From 173bb18e67a4a6ff542dd7d178896b797b2364c1 Mon Sep 17 00:00:00 2001 From: Kumar Sanghvi Date: Mon, 17 Mar 2014 13:40:25 +0530 Subject: [PATCH] linux-next-cherry-picks: Bring upstream fixes on cxgb4 This patch brings in below fixes on cxgb4 from linux-next: ca71de6 (cxgb4: Calculate len properly for LSO path) c2b955e (cxgb4: Updates for T5 SGE's Egress Congestion Threshold) 0f4d201 (cxgb4: Rectify emitting messages about SGE Ingress DMA channels being potentially stuck) 68bce192 (cxgb4: Add code to dump SGE registers when hitting idma hangs) 92ddcc7 (cxgb4: Fix some small bugs in t4_sge_init_soft() when our Page Size is 64KB) Signed-off-by: Kumar Sanghvi --- ...-some-small-bugs-in-t4_sge_init_soft.patch | 26 +++ ...cxgb4-Add-code-to-dump-SGE-registers.patch | 159 +++++++++++++++++ ...-emitting-messages-about-SGE-Ingress.patch | 160 ++++++++++++++++++ ...r-T5-SGE-s-Egress-Congestion-Thresho.patch | 71 ++++++++ ...-Calculate-len-properly-for-LSO-path.patch | 40 +++++ 5 files changed, 456 insertions(+) create mode 100644 linux-next-cherry-picks/0053-cxgb4-Fix-some-small-bugs-in-t4_sge_init_soft.patch create mode 100644 linux-next-cherry-picks/0054-cxgb4-Add-code-to-dump-SGE-registers.patch create mode 100644 linux-next-cherry-picks/0055-cxgb4-Rectify-emitting-messages-about-SGE-Ingress.patch create mode 100644 linux-next-cherry-picks/0056-cxgb4-Updates-for-T5-SGE-s-Egress-Congestion-Thresho.patch create mode 100644 linux-next-cherry-picks/0057-cxgb4-Calculate-len-properly-for-LSO-path.patch diff --git a/linux-next-cherry-picks/0053-cxgb4-Fix-some-small-bugs-in-t4_sge_init_soft.patch b/linux-next-cherry-picks/0053-cxgb4-Fix-some-small-bugs-in-t4_sge_init_soft.patch new file mode 100644 index 0000000..43ca637 --- /dev/null +++ b/linux-next-cherry-picks/0053-cxgb4-Fix-some-small-bugs-in-t4_sge_init_soft.patch @@ -0,0 +1,26 @@ +diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c +index 3cf8f69..530b090 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -2702,11 +2702,19 @@ static int t4_sge_init_soft(struct adapter *adap) + fl_small_mtu = READ_FL_BUF(RX_SMALL_MTU_BUF); + fl_large_mtu = READ_FL_BUF(RX_LARGE_MTU_BUF); + ++ /* We only bother using the Large Page logic if the Large Page Buffer ++ * is larger than our Page Size Buffer. ++ */ ++ if (fl_large_pg <= fl_small_pg) ++ fl_large_pg = 0; ++ + #undef READ_FL_BUF + ++ /* The Page Size Buffer must be exactly equal to our Page Size and the ++ * Large Page Size Buffer should be 0 (per above) or a power of 2. ++ */ + if (fl_small_pg != PAGE_SIZE || +- (fl_large_pg != 0 && (fl_large_pg <= fl_small_pg || +- (fl_large_pg & (fl_large_pg-1)) != 0))) { ++ (fl_large_pg & (fl_large_pg-1)) != 0) { + dev_err(adap->pdev_dev, "bad SGE FL page buffer sizes [%d, %d]\n", + fl_small_pg, fl_large_pg); + return -EINVAL; diff --git a/linux-next-cherry-picks/0054-cxgb4-Add-code-to-dump-SGE-registers.patch b/linux-next-cherry-picks/0054-cxgb4-Add-code-to-dump-SGE-registers.patch new file mode 100644 index 0000000..97074ad --- /dev/null +++ b/linux-next-cherry-picks/0054-cxgb4-Add-code-to-dump-SGE-registers.patch @@ -0,0 +1,159 @@ +From 68bce1922fa95e307f605cf43eac65e42c9076a6 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Thu, 13 Mar 2014 20:50:47 +0530 +Subject: [PATCH] cxgb4: Add code to dump SGE registers when hitting idma hangs + +Based on original work by Casey Leedom + +Signed-off-by: Kumar Sanghvi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + + drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 106 +++++++++++++++++++++++++++ + drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 3 + + 3 files changed, 110 insertions(+) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +index 944f2cb..509c976 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +@@ -1032,4 +1032,5 @@ void t4_db_dropped(struct adapter *adapter); + int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len); + int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, + u32 addr, u32 val); ++void t4_sge_decode_idma_state(struct adapter *adapter, int state); + #endif /* __CXGB4_H__ */ +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +index d3c2a51..fb2fe65 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +@@ -2597,6 +2597,112 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, + } + + /** ++ * t4_sge_decode_idma_state - decode the idma state ++ * @adap: the adapter ++ * @state: the state idma is stuck in ++ */ ++void t4_sge_decode_idma_state(struct adapter *adapter, int state) ++{ ++ static const char * const t4_decode[] = { ++ "IDMA_IDLE", ++ "IDMA_PUSH_MORE_CPL_FIFO", ++ "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO", ++ "Not used", ++ "IDMA_PHYSADDR_SEND_PCIEHDR", ++ "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST", ++ "IDMA_PHYSADDR_SEND_PAYLOAD", ++ "IDMA_SEND_FIFO_TO_IMSG", ++ "IDMA_FL_REQ_DATA_FL_PREP", ++ "IDMA_FL_REQ_DATA_FL", ++ "IDMA_FL_DROP", ++ "IDMA_FL_H_REQ_HEADER_FL", ++ "IDMA_FL_H_SEND_PCIEHDR", ++ "IDMA_FL_H_PUSH_CPL_FIFO", ++ "IDMA_FL_H_SEND_CPL", ++ "IDMA_FL_H_SEND_IP_HDR_FIRST", ++ "IDMA_FL_H_SEND_IP_HDR", ++ "IDMA_FL_H_REQ_NEXT_HEADER_FL", ++ "IDMA_FL_H_SEND_NEXT_PCIEHDR", ++ "IDMA_FL_H_SEND_IP_HDR_PADDING", ++ "IDMA_FL_D_SEND_PCIEHDR", ++ "IDMA_FL_D_SEND_CPL_AND_IP_HDR", ++ "IDMA_FL_D_REQ_NEXT_DATA_FL", ++ "IDMA_FL_SEND_PCIEHDR", ++ "IDMA_FL_PUSH_CPL_FIFO", ++ "IDMA_FL_SEND_CPL", ++ "IDMA_FL_SEND_PAYLOAD_FIRST", ++ "IDMA_FL_SEND_PAYLOAD", ++ "IDMA_FL_REQ_NEXT_DATA_FL", ++ "IDMA_FL_SEND_NEXT_PCIEHDR", ++ "IDMA_FL_SEND_PADDING", ++ "IDMA_FL_SEND_COMPLETION_TO_IMSG", ++ "IDMA_FL_SEND_FIFO_TO_IMSG", ++ "IDMA_FL_REQ_DATAFL_DONE", ++ "IDMA_FL_REQ_HEADERFL_DONE", ++ }; ++ static const char * const t5_decode[] = { ++ "IDMA_IDLE", ++ "IDMA_ALMOST_IDLE", ++ "IDMA_PUSH_MORE_CPL_FIFO", ++ "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO", ++ "IDMA_SGEFLRFLUSH_SEND_PCIEHDR", ++ "IDMA_PHYSADDR_SEND_PCIEHDR", ++ "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST", ++ "IDMA_PHYSADDR_SEND_PAYLOAD", ++ "IDMA_SEND_FIFO_TO_IMSG", ++ "IDMA_FL_REQ_DATA_FL", ++ "IDMA_FL_DROP", ++ "IDMA_FL_DROP_SEND_INC", ++ "IDMA_FL_H_REQ_HEADER_FL", ++ "IDMA_FL_H_SEND_PCIEHDR", ++ "IDMA_FL_H_PUSH_CPL_FIFO", ++ "IDMA_FL_H_SEND_CPL", ++ "IDMA_FL_H_SEND_IP_HDR_FIRST", ++ "IDMA_FL_H_SEND_IP_HDR", ++ "IDMA_FL_H_REQ_NEXT_HEADER_FL", ++ "IDMA_FL_H_SEND_NEXT_PCIEHDR", ++ "IDMA_FL_H_SEND_IP_HDR_PADDING", ++ "IDMA_FL_D_SEND_PCIEHDR", ++ "IDMA_FL_D_SEND_CPL_AND_IP_HDR", ++ "IDMA_FL_D_REQ_NEXT_DATA_FL", ++ "IDMA_FL_SEND_PCIEHDR", ++ "IDMA_FL_PUSH_CPL_FIFO", ++ "IDMA_FL_SEND_CPL", ++ "IDMA_FL_SEND_PAYLOAD_FIRST", ++ "IDMA_FL_SEND_PAYLOAD", ++ "IDMA_FL_REQ_NEXT_DATA_FL", ++ "IDMA_FL_SEND_NEXT_PCIEHDR", ++ "IDMA_FL_SEND_PADDING", ++ "IDMA_FL_SEND_COMPLETION_TO_IMSG", ++ }; ++ static const u32 sge_regs[] = { ++ SGE_DEBUG_DATA_LOW_INDEX_2, ++ SGE_DEBUG_DATA_LOW_INDEX_3, ++ SGE_DEBUG_DATA_HIGH_INDEX_10, ++ }; ++ const char **sge_idma_decode; ++ int sge_idma_decode_nstates; ++ int i; ++ ++ if (is_t4(adapter->params.chip)) { ++ sge_idma_decode = (const char **)t4_decode; ++ sge_idma_decode_nstates = ARRAY_SIZE(t4_decode); ++ } else { ++ sge_idma_decode = (const char **)t5_decode; ++ sge_idma_decode_nstates = ARRAY_SIZE(t5_decode); ++ } ++ ++ if (state < sge_idma_decode_nstates) ++ CH_WARN(adapter, "idma state %s\n", sge_idma_decode[state]); ++ else ++ CH_WARN(adapter, "idma state %d unknown\n", state); ++ ++ for (i = 0; i < ARRAY_SIZE(sge_regs); i++) ++ CH_WARN(adapter, "SGE register %#x value %#x\n", ++ sge_regs[i], t4_read_reg(adapter, sge_regs[i])); ++} ++ ++/** + * t4_fw_hello - establish communication with FW + * @adap: the adapter + * @mbox: mailbox to use for the FW command +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +index 4082522..33cf9ef 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +@@ -278,6 +278,9 @@ + #define SGE_DEBUG_INDEX 0x10cc + #define SGE_DEBUG_DATA_HIGH 0x10d0 + #define SGE_DEBUG_DATA_LOW 0x10d4 ++#define SGE_DEBUG_DATA_LOW_INDEX_2 0x12c8 ++#define SGE_DEBUG_DATA_LOW_INDEX_3 0x12cc ++#define SGE_DEBUG_DATA_HIGH_INDEX_10 0x12a8 + #define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4 + + #define S_HP_INT_THRESH 28 +-- +1.8.4 + diff --git a/linux-next-cherry-picks/0055-cxgb4-Rectify-emitting-messages-about-SGE-Ingress.patch b/linux-next-cherry-picks/0055-cxgb4-Rectify-emitting-messages-about-SGE-Ingress.patch new file mode 100644 index 0000000..8a4a83e --- /dev/null +++ b/linux-next-cherry-picks/0055-cxgb4-Rectify-emitting-messages-about-SGE-Ingress.patch @@ -0,0 +1,160 @@ +From 0f4d201f74f0d4f1f88c367185591195c8151e9c Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Thu, 13 Mar 2014 20:50:48 +0530 +Subject: [PATCH] cxgb4: Rectify emitting messages about SGE Ingress DMA + channels being potentially stuck + +Based on original work by Casey Leedom + +Signed-off-by: Kumar Sanghvi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 9 ++- + drivers/net/ethernet/chelsio/cxgb4/sge.c | 90 ++++++++++++++++++++++++------ + 2 files changed, 79 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +index 509c976..50abe1d 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +@@ -556,8 +556,13 @@ struct sge { + u32 pktshift; /* padding between CPL & packet data */ + u32 fl_align; /* response queue message alignment */ + u32 fl_starve_thres; /* Free List starvation threshold */ +- unsigned int starve_thres; +- u8 idma_state[2]; ++ ++ /* State variables for detecting an SGE Ingress DMA hang */ ++ unsigned int idma_1s_thresh;/* SGE same State Counter 1s threshold */ ++ unsigned int idma_stalled[2];/* SGE synthesized stalled timers in HZ */ ++ unsigned int idma_state[2]; /* SGE IDMA Hang detect state */ ++ unsigned int idma_qid[2]; /* SGE IDMA Hung Ingress Queue ID */ ++ + unsigned int egr_start; + unsigned int ingr_start; + void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */ +diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c +index 3a2ecd8..054bb03 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -93,6 +93,16 @@ + */ + #define TX_QCHECK_PERIOD (HZ / 2) + ++/* SGE Hung Ingress DMA Threshold Warning time (in Hz) and Warning Repeat Rate ++ * (in RX_QCHECK_PERIOD multiples). If we find one of the SGE Ingress DMA ++ * State Machines in the same state for this amount of time (in HZ) then we'll ++ * issue a warning about a potential hang. We'll repeat the warning as the ++ * SGE Ingress DMA Channel appears to be hung every N RX_QCHECK_PERIODs till ++ * the situation clears. If the situation clears, we'll note that as well. ++ */ ++#define SGE_IDMA_WARN_THRESH (1 * HZ) ++#define SGE_IDMA_WARN_REPEAT (20 * RX_QCHECK_PERIOD) ++ + /* + * Max number of Tx descriptors to be reclaimed by the Tx timer. + */ +@@ -2008,7 +2018,7 @@ irq_handler_t t4_intr_handler(struct adapter *adap) + static void sge_rx_timer_cb(unsigned long data) + { + unsigned long m; +- unsigned int i, cnt[2]; ++ unsigned int i, idma_same_state_cnt[2]; + struct adapter *adap = (struct adapter *)data; + struct sge *s = &adap->sge; + +@@ -2031,21 +2041,64 @@ static void sge_rx_timer_cb(unsigned long data) + } + + t4_write_reg(adap, SGE_DEBUG_INDEX, 13); +- cnt[0] = t4_read_reg(adap, SGE_DEBUG_DATA_HIGH); +- cnt[1] = t4_read_reg(adap, SGE_DEBUG_DATA_LOW); +- +- for (i = 0; i < 2; i++) +- if (cnt[i] >= s->starve_thres) { +- if (s->idma_state[i] || cnt[i] == 0xffffffff) +- continue; +- s->idma_state[i] = 1; +- t4_write_reg(adap, SGE_DEBUG_INDEX, 11); +- m = t4_read_reg(adap, SGE_DEBUG_DATA_LOW) >> (i * 16); +- dev_warn(adap->pdev_dev, +- "SGE idma%u starvation detected for " +- "queue %lu\n", i, m & 0xffff); +- } else if (s->idma_state[i]) +- s->idma_state[i] = 0; ++ idma_same_state_cnt[0] = t4_read_reg(adap, SGE_DEBUG_DATA_HIGH); ++ idma_same_state_cnt[1] = t4_read_reg(adap, SGE_DEBUG_DATA_LOW); ++ ++ for (i = 0; i < 2; i++) { ++ u32 debug0, debug11; ++ ++ /* If the Ingress DMA Same State Counter ("timer") is less ++ * than 1s, then we can reset our synthesized Stall Timer and ++ * continue. If we have previously emitted warnings about a ++ * potential stalled Ingress Queue, issue a note indicating ++ * that the Ingress Queue has resumed forward progress. ++ */ ++ if (idma_same_state_cnt[i] < s->idma_1s_thresh) { ++ if (s->idma_stalled[i] >= SGE_IDMA_WARN_THRESH) ++ CH_WARN(adap, "SGE idma%d, queue%u,resumed after %d sec\n", ++ i, s->idma_qid[i], ++ s->idma_stalled[i]/HZ); ++ s->idma_stalled[i] = 0; ++ continue; ++ } ++ ++ /* Synthesize an SGE Ingress DMA Same State Timer in the Hz ++ * domain. The first time we get here it'll be because we ++ * passed the 1s Threshold; each additional time it'll be ++ * because the RX Timer Callback is being fired on its regular ++ * schedule. ++ * ++ * If the stall is below our Potential Hung Ingress Queue ++ * Warning Threshold, continue. ++ */ ++ if (s->idma_stalled[i] == 0) ++ s->idma_stalled[i] = HZ; ++ else ++ s->idma_stalled[i] += RX_QCHECK_PERIOD; ++ ++ if (s->idma_stalled[i] < SGE_IDMA_WARN_THRESH) ++ continue; ++ ++ /* We'll issue a warning every SGE_IDMA_WARN_REPEAT Hz */ ++ if (((s->idma_stalled[i] - HZ) % SGE_IDMA_WARN_REPEAT) != 0) ++ continue; ++ ++ /* Read and save the SGE IDMA State and Queue ID information. ++ * We do this every time in case it changes across time ... ++ */ ++ t4_write_reg(adap, SGE_DEBUG_INDEX, 0); ++ debug0 = t4_read_reg(adap, SGE_DEBUG_DATA_LOW); ++ s->idma_state[i] = (debug0 >> (i * 9)) & 0x3f; ++ ++ t4_write_reg(adap, SGE_DEBUG_INDEX, 11); ++ debug11 = t4_read_reg(adap, SGE_DEBUG_DATA_LOW); ++ s->idma_qid[i] = (debug11 >> (i * 16)) & 0xffff; ++ ++ CH_WARN(adap, "SGE idma%u, queue%u, maybe stuck state%u %dsecs (debug0=%#x, debug11=%#x)\n", ++ i, s->idma_qid[i], s->idma_state[i], ++ s->idma_stalled[i]/HZ, debug0, debug11); ++ t4_sge_decode_idma_state(adap, s->idma_state[i]); ++ } + + mod_timer(&s->rx_timer, jiffies + RX_QCHECK_PERIOD); + } +@@ -2756,8 +2809,9 @@ int t4_sge_init(struct adapter *adap) + + setup_timer(&s->rx_timer, sge_rx_timer_cb, (unsigned long)adap); + setup_timer(&s->tx_timer, sge_tx_timer_cb, (unsigned long)adap); +- s->starve_thres = core_ticks_per_usec(adap) * 1000000; /* 1 s */ +- s->idma_state[0] = s->idma_state[1] = 0; ++ s->idma_1s_thresh = core_ticks_per_usec(adap) * 1000000; /* 1 s */ ++ s->idma_stalled[0] = 0; ++ s->idma_stalled[1] = 0; + spin_lock_init(&s->intrq_lock); + + return 0; +-- +1.8.4 + diff --git a/linux-next-cherry-picks/0056-cxgb4-Updates-for-T5-SGE-s-Egress-Congestion-Thresho.patch b/linux-next-cherry-picks/0056-cxgb4-Updates-for-T5-SGE-s-Egress-Congestion-Thresho.patch new file mode 100644 index 0000000..10277e1 --- /dev/null +++ b/linux-next-cherry-picks/0056-cxgb4-Updates-for-T5-SGE-s-Egress-Congestion-Thresho.patch @@ -0,0 +1,71 @@ +From c2b955e0063411826d2c4540c96a8f2c4e1c2cb0 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Thu, 13 Mar 2014 20:50:49 +0530 +Subject: [PATCH] cxgb4: Updates for T5 SGE's Egress Congestion Threshold + +Based on original work by Casey Leedom + +Signed-off-by: Kumar Sanghvi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/sge.c | 18 +++++++++++++----- + drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 6 ++++++ + 2 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c +index 054bb03..a7c56b3 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -2776,8 +2776,8 @@ static int t4_sge_init_hard(struct adapter *adap) + int t4_sge_init(struct adapter *adap) + { + struct sge *s = &adap->sge; +- u32 sge_control; +- int ret; ++ u32 sge_control, sge_conm_ctrl; ++ int ret, egress_threshold; + + /* + * Ingress Padding Boundary and Egress Status Page Size are set up by +@@ -2802,10 +2802,18 @@ int t4_sge_init(struct adapter *adap) + * SGE's Egress Congestion Threshold. If it isn't, then we can get + * stuck waiting for new packets while the SGE is waiting for us to + * give it more Free List entries. (Note that the SGE's Egress +- * Congestion Threshold is in units of 2 Free List pointers.) ++ * Congestion Threshold is in units of 2 Free List pointers.) For T4, ++ * there was only a single field to control this. For T5 there's the ++ * original field which now only applies to Unpacked Mode Free List ++ * buffers and a new field which only applies to Packed Mode Free List ++ * buffers. + */ +- s->fl_starve_thres +- = EGRTHRESHOLD_GET(t4_read_reg(adap, SGE_CONM_CTRL))*2 + 1; ++ sge_conm_ctrl = t4_read_reg(adap, SGE_CONM_CTRL); ++ if (is_t4(adap->params.chip)) ++ egress_threshold = EGRTHRESHOLD_GET(sge_conm_ctrl); ++ else ++ egress_threshold = EGRTHRESHOLDPACKING_GET(sge_conm_ctrl); ++ s->fl_starve_thres = 2*egress_threshold + 1; + + setup_timer(&s->rx_timer, sge_rx_timer_cb, (unsigned long)adap); + setup_timer(&s->tx_timer, sge_tx_timer_cb, (unsigned long)adap); +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +index 33cf9ef..225ad8a 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +@@ -230,6 +230,12 @@ + #define EGRTHRESHOLD(x) ((x) << EGRTHRESHOLDshift) + #define EGRTHRESHOLD_GET(x) (((x) & EGRTHRESHOLD_MASK) >> EGRTHRESHOLDshift) + ++#define EGRTHRESHOLDPACKING_MASK 0x3fU ++#define EGRTHRESHOLDPACKING_SHIFT 14 ++#define EGRTHRESHOLDPACKING(x) ((x) << EGRTHRESHOLDPACKING_SHIFT) ++#define EGRTHRESHOLDPACKING_GET(x) (((x) >> EGRTHRESHOLDPACKING_SHIFT) & \ ++ EGRTHRESHOLDPACKING_MASK) ++ + #define SGE_DBFIFO_STATUS 0x10a4 + #define HP_INT_THRESH_SHIFT 28 + #define HP_INT_THRESH_MASK 0xfU +-- +1.8.4 + diff --git a/linux-next-cherry-picks/0057-cxgb4-Calculate-len-properly-for-LSO-path.patch b/linux-next-cherry-picks/0057-cxgb4-Calculate-len-properly-for-LSO-path.patch new file mode 100644 index 0000000..df845fa --- /dev/null +++ b/linux-next-cherry-picks/0057-cxgb4-Calculate-len-properly-for-LSO-path.patch @@ -0,0 +1,40 @@ +From ca71de6ba7c18a3a1576e04f7ed8d8508ceba4c9 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Thu, 13 Mar 2014 20:50:50 +0530 +Subject: [PATCH] cxgb4: Calculate len properly for LSO path + +Commit 0034b29 ("cxgb4: Don't assume LSO only uses SGL path in t4_eth_xmit()") +introduced a regression where-in length was calculated wrongly for LSO path, +causing chip hangs. +So, correct the calculation of len. + +Fixes: 0034b29 ("cxgb4: Don't assume LSO only uses SGL path in t4_eth_xmit()") +Signed-off-by: Kumar Sanghvi +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/chelsio/cxgb4/sge.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c +index a7c56b3..46429f9 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -1051,7 +1051,6 @@ out_free: dev_kfree_skb(skb); + end = (u64 *)wr + flits; + + len = immediate ? skb->len : 0; +- len += sizeof(*cpl); + ssi = skb_shinfo(skb); + if (ssi->gso_size) { + struct cpl_tx_pkt_lso *lso = (void *)wr; +@@ -1079,6 +1078,7 @@ out_free: dev_kfree_skb(skb); + q->tso++; + q->tx_cso += ssi->gso_segs; + } else { ++ len += sizeof(*cpl); + wr->op_immdlen = htonl(FW_WR_OP(FW_ETH_TX_PKT_WR) | + FW_WR_IMMDLEN(len)); + cpl = (void *)(wr + 1); +-- +1.8.4 + -- 2.46.0