From e894d720a5c501c4a2a01ae64f732046d1f48b76 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:11 +0530 Subject: [PATCH 1/9] cxgb4: Pass correct argument to t4_link_l1cfg() Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c index 2a61a42ab033..7a0b92b2f73c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c @@ -686,7 +686,7 @@ static int set_pauseparam(struct net_device *dev, if (epause->tx_pause) lc->requested_fc |= PAUSE_TX; if (netif_running(dev)) - return t4_link_l1cfg(p->adapter, p->adapter->pf, p->tx_chan, + return t4_link_l1cfg(p->adapter, p->adapter->mbox, p->tx_chan, lc); return 0; } From 44588560d95c105cc9dfa82180a6f542adea9ac9 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:12 +0530 Subject: [PATCH 2/9] cxgb4: Update pm_stats for T6 adapter family Updated pm_stats code to display input FIFO wait (index 5) and read latency (index 7) counters for T6 adapters Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + .../ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 30 +++++++++++++++++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 7 +++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 1 + 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 3b59bc4038a6..eab57cf29aa1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -301,6 +301,7 @@ struct devlog_params { /* Stores chip specific parameters */ struct arch_specific_params { u8 nchan; + u8 pm_stats_cnt; u16 mps_rplc_size; u16 vfcount; u32 sge_fl_db; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index 62a343fc9c1a..c6e92cc0aa09 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -757,8 +757,8 @@ static int pm_stats_show(struct seq_file *seq, void *v) }; int i; - u32 tx_cnt[PM_NSTATS], rx_cnt[PM_NSTATS]; - u64 tx_cyc[PM_NSTATS], rx_cyc[PM_NSTATS]; + u32 tx_cnt[T6_PM_NSTATS], rx_cnt[T6_PM_NSTATS]; + u64 tx_cyc[T6_PM_NSTATS], rx_cyc[T6_PM_NSTATS]; struct adapter *adap = seq->private; t4_pmtx_get_stats(adap, tx_cnt, tx_cyc); @@ -773,6 +773,32 @@ static int pm_stats_show(struct seq_file *seq, void *v) for (i = 0; i < PM_NSTATS - 1; i++) seq_printf(seq, "%-13s %10u %20llu\n", rx_pm_stats[i], rx_cnt[i], rx_cyc[i]); + + if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) { + /* In T5 the granularity of the total wait is too fine. + * It is not useful as it reaches the max value too fast. + * Hence display this Input FIFO wait for T6 onwards. + */ + seq_printf(seq, "%13s %10s %20s\n", + " ", "Total wait", "Total Occupancy"); + seq_printf(seq, "Tx FIFO wait %10u %20llu\n", + tx_cnt[i], tx_cyc[i]); + seq_printf(seq, "Rx FIFO wait %10u %20llu\n", + rx_cnt[i], rx_cyc[i]); + + /* Skip index 6 as there is nothing useful ihere */ + i += 2; + + /* At index 7, a new stat for read latency (count, total wait) + * is added. + */ + seq_printf(seq, "%13s %10s %20s\n", + " ", "Reads", "Total wait"); + seq_printf(seq, "Tx latency %10u %20llu\n", + tx_cnt[i], tx_cyc[i]); + seq_printf(seq, "Rx latency %10u %20llu\n", + rx_cnt[i], rx_cyc[i]); + } return 0; } diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index cf61a5869c6e..5266011e530b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -5254,7 +5254,7 @@ void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) int i; u32 data[2]; - for (i = 0; i < PM_NSTATS; i++) { + for (i = 0; i < adap->params.arch.pm_stats_cnt; i++) { t4_write_reg(adap, PM_TX_STAT_CONFIG_A, i + 1); cnt[i] = t4_read_reg(adap, PM_TX_STAT_COUNT_A); if (is_t4(adap->params.chip)) { @@ -5281,7 +5281,7 @@ void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]) int i; u32 data[2]; - for (i = 0; i < PM_NSTATS; i++) { + for (i = 0; i < adap->params.arch.pm_stats_cnt; i++) { t4_write_reg(adap, PM_RX_STAT_CONFIG_A, i + 1); cnt[i] = t4_read_reg(adap, PM_RX_STAT_COUNT_A); if (is_t4(adap->params.chip)) { @@ -7060,6 +7060,7 @@ int t4_prep_adapter(struct adapter *adapter) NUM_MPS_CLS_SRAM_L_INSTANCES; adapter->params.arch.mps_rplc_size = 128; adapter->params.arch.nchan = NCHAN; + adapter->params.arch.pm_stats_cnt = PM_NSTATS; adapter->params.arch.vfcount = 128; break; case CHELSIO_T5: @@ -7069,6 +7070,7 @@ int t4_prep_adapter(struct adapter *adapter) NUM_MPS_T5_CLS_SRAM_L_INSTANCES; adapter->params.arch.mps_rplc_size = 128; adapter->params.arch.nchan = NCHAN; + adapter->params.arch.pm_stats_cnt = PM_NSTATS; adapter->params.arch.vfcount = 128; break; case CHELSIO_T6: @@ -7078,6 +7080,7 @@ int t4_prep_adapter(struct adapter *adapter) NUM_MPS_T5_CLS_SRAM_L_INSTANCES; adapter->params.arch.mps_rplc_size = 256; adapter->params.arch.nchan = 2; + adapter->params.arch.pm_stats_cnt = T6_PM_NSTATS; adapter->params.arch.vfcount = 256; break; default: diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h index 13708fde1668..2fc60e83a7a1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h @@ -48,6 +48,7 @@ enum { NMTUS = 16, /* size of MTU table */ NCCTRL_WIN = 32, /* # of congestion control windows */ PM_NSTATS = 5, /* # of PM stats */ + T6_PM_NSTATS = 7, /* # of PM stats in T6 */ MBOX_LEN = 64, /* mailbox size in bytes */ TRACE_LEN = 112, /* length of trace data and mask */ FILTER_OPT_LEN = 36, /* filter tuple width for optional components */ From acac596286bcadda964d0e15dbbd8bdebedcaa41 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:13 +0530 Subject: [PATCH 3/9] cxgb4/cxgb4vf: Update Ingress padding boundary values for T6 adapter Ingress padding boundary values got changed for T6. T5: 0=32B 1=64B 2=128B 3=256B 4=512B 5=1024B 6=2048B 7=4096B T6: 0=8B 1=16B 2=32B 3=64B 4=128B 5=128B 6=256B 7=512B Updating the driver to set the correct boundary values in SGE_CONTROL to 32B. Also, need to take care of this fl alignment change when calculating the next packet offset. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + drivers/net/ethernet/chelsio/cxgb4/sge.c | 33 +--------- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 62 ++++++++++++++++++- .../net/ethernet/chelsio/cxgb4/t4_values.h | 3 + drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 11 +++- 5 files changed, 76 insertions(+), 34 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index eab57cf29aa1..5c193a5f564e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -1256,6 +1256,7 @@ int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver); int t4_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op); int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, const u8 *fw_data, unsigned int size, int force); +int t4_fl_pkt_align(struct adapter *adap); unsigned int t4_flash_cfg_addr(struct adapter *adapter); int t4_check_fw_version(struct adapter *adap); int t4_get_fw_version(struct adapter *adapter, u32 *vers); diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 5e3ffa73ee13..099b946f017f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -3173,8 +3173,7 @@ static int t4_sge_init_soft(struct adapter *adap) int t4_sge_init(struct adapter *adap) { struct sge *s = &adap->sge; - u32 sge_control, sge_control2, sge_conm_ctrl; - unsigned int ingpadboundary, ingpackboundary; + u32 sge_control, sge_conm_ctrl; int ret, egress_threshold; /* @@ -3185,35 +3184,7 @@ int t4_sge_init(struct adapter *adap) s->pktshift = PKTSHIFT_G(sge_control); s->stat_len = (sge_control & EGRSTATUSPAGESIZE_F) ? 128 : 64; - /* T4 uses a single control field to specify both the PCIe Padding and - * Packing Boundary. T5 introduced the ability to specify these - * separately. The actual Ingress Packet Data alignment boundary - * within Packed Buffer Mode is the maximum of these two - * specifications. (Note that it makes no real practical sense to - * have the Pading Boudary be larger than the Packing Boundary but you - * could set the chip up that way and, in fact, legacy T4 code would - * end doing this because it would initialize the Padding Boundary and - * leave the Packing Boundary initialized to 0 (16 bytes).) - */ - ingpadboundary = 1 << (INGPADBOUNDARY_G(sge_control) + - INGPADBOUNDARY_SHIFT_X); - if (is_t4(adap->params.chip)) { - s->fl_align = ingpadboundary; - } else { - /* T5 has a different interpretation of one of the PCIe Packing - * Boundary values. - */ - sge_control2 = t4_read_reg(adap, SGE_CONTROL2_A); - ingpackboundary = INGPACKBOUNDARY_G(sge_control2); - if (ingpackboundary == INGPACKBOUNDARY_16B_X) - ingpackboundary = 16; - else - ingpackboundary = 1 << (ingpackboundary + - INGPACKBOUNDARY_SHIFT_X); - - s->fl_align = max(ingpadboundary, ingpackboundary); - } - + s->fl_align = t4_fl_pkt_align(adap); ret = t4_sge_init_soft(adap); if (ret < 0) return ret; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 5266011e530b..42754c06b7d8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -6096,6 +6096,59 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, return t4_fw_restart(adap, mbox, reset); } +/** + * t4_fl_pkt_align - return the fl packet alignment + * @adap: the adapter + * + * T4 has a single field to specify the packing and padding boundary. + * T5 onwards has separate fields for this and hence the alignment for + * next packet offset is maximum of these two. + * + */ +int t4_fl_pkt_align(struct adapter *adap) +{ + u32 sge_control, sge_control2; + unsigned int ingpadboundary, ingpackboundary, fl_align, ingpad_shift; + + sge_control = t4_read_reg(adap, SGE_CONTROL_A); + + /* T4 uses a single control field to specify both the PCIe Padding and + * Packing Boundary. T5 introduced the ability to specify these + * separately. The actual Ingress Packet Data alignment boundary + * within Packed Buffer Mode is the maximum of these two + * specifications. (Note that it makes no real practical sense to + * have the Pading Boudary be larger than the Packing Boundary but you + * could set the chip up that way and, in fact, legacy T4 code would + * end doing this because it would initialize the Padding Boundary and + * leave the Packing Boundary initialized to 0 (16 bytes).) + * Padding Boundary values in T6 starts from 8B, + * where as it is 32B for T4 and T5. + */ + if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5) + ingpad_shift = INGPADBOUNDARY_SHIFT_X; + else + ingpad_shift = T6_INGPADBOUNDARY_SHIFT_X; + + ingpadboundary = 1 << (INGPADBOUNDARY_G(sge_control) + ingpad_shift); + + fl_align = ingpadboundary; + if (!is_t4(adap->params.chip)) { + /* T5 has a weird interpretation of one of the PCIe Packing + * Boundary values. No idea why ... + */ + sge_control2 = t4_read_reg(adap, SGE_CONTROL2_A); + ingpackboundary = INGPACKBOUNDARY_G(sge_control2); + if (ingpackboundary == INGPACKBOUNDARY_16B_X) + ingpackboundary = 16; + else + ingpackboundary = 1 << (ingpackboundary + + INGPACKBOUNDARY_SHIFT_X); + + fl_align = max(ingpadboundary, ingpackboundary); + } + return fl_align; +} + /** * t4_fixup_host_params - fix up host-dependent parameters * @adap: the adapter @@ -6114,6 +6167,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, unsigned int stat_len = cache_line_size > 64 ? 128 : 64; unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size; unsigned int fl_align_log = fls(fl_align) - 1; + unsigned int ingpad; t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A, HOSTPAGESIZEPF0_V(sge_hps) | @@ -6161,10 +6215,16 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, fl_align = 64; fl_align_log = 6; } + + if (is_t5(adap->params.chip)) + ingpad = INGPCIEBOUNDARY_32B_X; + else + ingpad = T6_INGPADBOUNDARY_32B_X; + t4_set_reg_field(adap, SGE_CONTROL_A, INGPADBOUNDARY_V(INGPADBOUNDARY_M) | EGRSTATUSPAGESIZE_F, - INGPADBOUNDARY_V(INGPCIEBOUNDARY_32B_X) | + INGPADBOUNDARY_V(ingpad) | EGRSTATUSPAGESIZE_V(stat_len != 64)); t4_set_reg_field(adap, SGE_CONTROL2_A, INGPACKBOUNDARY_V(INGPACKBOUNDARY_M), diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_values.h b/drivers/net/ethernet/chelsio/cxgb4/t4_values.h index 7bdee3bf75ec..a5231fa771db 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_values.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_values.h @@ -53,6 +53,9 @@ #define INGPADBOUNDARY_SHIFT_X 5 +#define T6_INGPADBOUNDARY_SHIFT_X 3 +#define T6_INGPADBOUNDARY_32B_X 2 + /* CONTROL2 register */ #define INGPACKBOUNDARY_SHIFT_X 5 #define INGPACKBOUNDARY_16B_X 0 diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index fa3786a9d30e..6528231d8a59 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -2607,7 +2607,7 @@ int t4vf_sge_init(struct adapter *adapter) u32 fl0 = sge_params->sge_fl_buffer_size[0]; u32 fl1 = sge_params->sge_fl_buffer_size[1]; struct sge *s = &adapter->sge; - unsigned int ingpadboundary, ingpackboundary; + unsigned int ingpadboundary, ingpackboundary, ingpad_shift; /* * Start by vetting the basic SGE parameters which have been set up by @@ -2642,9 +2642,16 @@ int t4vf_sge_init(struct adapter *adapter) * could set the chip up that way and, in fact, legacy T4 code would * end doing this because it would initialize the Padding Boundary and * leave the Packing Boundary initialized to 0 (16 bytes).) + * Padding Boundary values in T6 starts from 8B, + * where as it is 32B for T4 and T5. */ + if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) + ingpad_shift = INGPADBOUNDARY_SHIFT_X; + else + ingpad_shift = T6_INGPADBOUNDARY_SHIFT_X; + ingpadboundary = 1 << (INGPADBOUNDARY_G(sge_params->sge_control) + - INGPADBOUNDARY_SHIFT_X); + ingpad_shift); if (is_t4(adapter->params.chip)) { s->fl_align = ingpadboundary; } else { From 676d6a753066e9b5ae6c0a6ce8ec8cf9dabc4352 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:14 +0530 Subject: [PATCH 4/9] cxgb4: Update register range and SGE registers for T6 adapter Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 5 +++-- drivers/net/ethernet/chelsio/cxgb4/sge.c | 15 +++++++++++++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 16 +++++++++++----- drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 3 +++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 2642593289d9..c0dd533eeafb 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -4855,8 +4855,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* configure SGE_STAT_CFG_A to read WC stats */ if (!is_t4(adapter->params.chip)) - t4_write_reg(adapter, SGE_STAT_CFG_A, - STATSOURCE_T5_V(7) | STATMODE_V(0)); + t4_write_reg(adapter, SGE_STAT_CFG_A, STATSOURCE_T5_V(7) | + (is_t5(adapter->params.chip) ? STATMODE_V(0) : + T6_STATMODE_V(0))); for_each_port(adapter, i) { struct net_device *netdev; diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 099b946f017f..5829c9caa1fa 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -3202,10 +3202,21 @@ int t4_sge_init(struct adapter *adap) * buffers. */ sge_conm_ctrl = t4_read_reg(adap, SGE_CONM_CTRL_A); - if (is_t4(adap->params.chip)) + switch (CHELSIO_CHIP_VERSION(adap->params.chip)) { + case CHELSIO_T4: egress_threshold = EGRTHRESHOLD_G(sge_conm_ctrl); - else + break; + case CHELSIO_T5: egress_threshold = EGRTHRESHOLDPACKING_G(sge_conm_ctrl); + break; + case CHELSIO_T6: + egress_threshold = T6_EGRTHRESHOLDPACKING_G(sge_conm_ctrl); + break; + default: + dev_err(adap->pdev_dev, "Unsupported Chip version %d\n", + CHELSIO_CHIP_VERSION(adap->params.chip)); + return -EINVAL; + } s->fl_starve_thres = 2*egress_threshold + 1; t4_idma_monitor_init(adap, &s->idma_monitor); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 42754c06b7d8..c613bd6a6091 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -1942,8 +1942,12 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0x1190, 0x1194, 0x11a0, 0x11a4, 0x11b0, 0x11b4, - 0x11fc, 0x1254, - 0x1280, 0x133c, + 0x11fc, 0x1258, + 0x1280, 0x12d4, + 0x12d9, 0x12d9, + 0x12de, 0x12de, + 0x12e3, 0x12e3, + 0x12e8, 0x133c, 0x1800, 0x18fc, 0x3000, 0x302c, 0x3060, 0x30b0, @@ -1973,7 +1977,7 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0x5e50, 0x5e94, 0x5ea0, 0x5eb0, 0x5ec0, 0x5ec0, - 0x5ec8, 0x5ecc, + 0x5ec8, 0x5ed0, 0x6000, 0x6020, 0x6028, 0x6040, 0x6058, 0x609c, @@ -2048,7 +2052,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0x19150, 0x19194, 0x1919c, 0x191b0, 0x191d0, 0x191e8, - 0x19238, 0x192b0, + 0x19238, 0x19290, + 0x192a4, 0x192b0, 0x192bc, 0x192bc, 0x19348, 0x1934c, 0x193f8, 0x19418, @@ -2442,7 +2447,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size) 0x40280, 0x40280, 0x40304, 0x40304, 0x40330, 0x4033c, - 0x41304, 0x413c8, + 0x41304, 0x413b8, + 0x413c0, 0x413c8, 0x413d0, 0x413dc, 0x413f0, 0x413f0, 0x41400, 0x4140c, diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 91b52a21a2e7..0971cc41c747 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -492,6 +492,9 @@ #define STATSOURCE_T5_V(x) ((x) << STATSOURCE_T5_S) #define STATSOURCE_T5_G(x) (((x) >> STATSOURCE_T5_S) & STATSOURCE_T5_M) +#define T6_STATMODE_S 0 +#define T6_STATMODE_V(x) ((x) << T6_STATMODE_S) + #define SGE_DBFIFO_STATUS2_A 0x1118 #define HP_INT_THRESH_T5_S 10 From e9faeab8d48fc8962e4a244a6097048acebde47b Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:15 +0530 Subject: [PATCH 5/9] cxgb4: Update Congestion Channel map for T6 adapter Updating Congestion Channel/Priority Map in Congestion Manager Context for T6. In T6 port 0 is mapped to channel 0 and port 1 is mapped to channel 1. For 2 port T4/T5 adapter, port 0 is mapped to channel 0,1 and port 1 is mapped to channel 2,3 Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index c613bd6a6091..2f8c73630410 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -5316,7 +5316,14 @@ unsigned int t4_get_mps_bg_map(struct adapter *adap, int idx) if (n == 0) return idx == 0 ? 0xf : 0; - if (n == 1) + /* In T6 (which is a 2 port card), + * port 0 is mapped to channel 0 and port 1 is mapped to channel 1. + * For 2 port T4/T5 adapter, + * port 0 is mapped to channel 0 and 1, + * port 1 is mapped to channel 2 and 3. + */ + if ((n == 1) && + (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5)) return idx < 2 ? (3 << (2 * idx)) : 0; return 1 << idx; } From 6df397539cb0200b237e9b7b1665d26d5e01d01a Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:16 +0530 Subject: [PATCH 6/9] cxgb4: Update correct encoding of SGE Ingress DMA States for T6 adapter Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 2f8c73630410..0132b6492611 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -5702,6 +5702,39 @@ void t4_sge_decode_idma_state(struct adapter *adapter, int state) "IDMA_FL_SEND_PADDING", "IDMA_FL_SEND_COMPLETION_TO_IMSG", }; + static const char * const t6_decode[] = { + "IDMA_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_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_A, SGE_DEBUG_DATA_LOW_INDEX_3_A, @@ -5710,6 +5743,32 @@ void t4_sge_decode_idma_state(struct adapter *adapter, int state) const char **sge_idma_decode; int sge_idma_decode_nstates; int i; + unsigned int chip_version = CHELSIO_CHIP_VERSION(adapter->params.chip); + + /* Select the right set of decode strings to dump depending on the + * adapter chip type. + */ + switch (chip_version) { + case CHELSIO_T4: + sge_idma_decode = (const char **)t4_decode; + sge_idma_decode_nstates = ARRAY_SIZE(t4_decode); + break; + + case CHELSIO_T5: + sge_idma_decode = (const char **)t5_decode; + sge_idma_decode_nstates = ARRAY_SIZE(t5_decode); + break; + + case CHELSIO_T6: + sge_idma_decode = (const char **)t6_decode; + sge_idma_decode_nstates = ARRAY_SIZE(t6_decode); + break; + + default: + dev_err(adapter->pdev_dev, + "Unsupported chip version %d\n", chip_version); + return; + } if (is_t4(adapter->params.chip)) { sge_idma_decode = (const char **)t4_decode; From 115b56af88b538147cf241d0f75a370a73009ed9 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:17 +0530 Subject: [PATCH 7/9] cxgb4: Update mps_tcam output to include T6 fields In T6, MPS classification has a 512 deep TCAM to do the match lookup. Each entry has 80x2b sets containing 48 bit MAC address, port number, VLAN Valid/ID, VNI, lookup type (outer or inner packet header). [71:48] bit locations are overloaded for outer vs. inner lookup types. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- .../ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 100 ++++++++++++++---- drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 24 +++++ 2 files changed, 105 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index c6e92cc0aa09..1bab34f923e7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -1585,25 +1585,35 @@ static int mps_tcam_show(struct seq_file *seq, void *v) { struct adapter *adap = seq->private; unsigned int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip); - if (v == SEQ_START_TOKEN) { - if (adap->params.arch.mps_rplc_size > 128) + if (chip_ver > CHELSIO_T5) { seq_puts(seq, "Idx Ethernet address Mask " + " VNI Mask IVLAN Vld " + "DIP_Hit Lookup Port " "Vld Ports PF VF " "Replication " " P0 P1 P2 P3 ML\n"); - else - seq_puts(seq, "Idx Ethernet address Mask " - "Vld Ports PF VF Replication" - " P0 P1 P2 P3 ML\n"); + } else { + if (adap->params.arch.mps_rplc_size > 128) + seq_puts(seq, "Idx Ethernet address Mask " + "Vld Ports PF VF " + "Replication " + " P0 P1 P2 P3 ML\n"); + else + seq_puts(seq, "Idx Ethernet address Mask " + "Vld Ports PF VF Replication" + " P0 P1 P2 P3 ML\n"); + } } else { u64 mask; u8 addr[ETH_ALEN]; - bool replicate; + bool replicate, dip_hit = false, vlan_vld = false; unsigned int idx = (uintptr_t)v - 2; u64 tcamy, tcamx, val; - u32 cls_lo, cls_hi, ctl; + u32 cls_lo, cls_hi, ctl, data2, vnix = 0, vniy = 0; u32 rplc[8] = {0}; + u8 lookup_type = 0, port_num = 0; + u16 ivlan = 0; if (chip_ver > CHELSIO_T5) { /* CtlCmdType - 0: Read, 1: Write @@ -1622,6 +1632,22 @@ static int mps_tcam_show(struct seq_file *seq, void *v) val = t4_read_reg(adap, MPS_CLS_TCAM_DATA1_A); tcamy = DMACH_G(val) << 32; tcamy |= t4_read_reg(adap, MPS_CLS_TCAM_DATA0_A); + data2 = t4_read_reg(adap, MPS_CLS_TCAM_DATA2_CTL_A); + lookup_type = DATALKPTYPE_G(data2); + /* 0 - Outer header, 1 - Inner header + * [71:48] bit locations are overloaded for + * outer vs. inner lookup types. + */ + if (lookup_type && (lookup_type != DATALKPTYPE_M)) { + /* Inner header VNI */ + vniy = ((data2 & DATAVIDH2_F) << 23) | + (DATAVIDH1_G(data2) << 16) | VIDL_G(val); + dip_hit = data2 & DATADIPHIT_F; + } else { + vlan_vld = data2 & DATAVIDH2_F; + ivlan = VIDL_G(val); + } + port_num = DATAPORTNUM_G(data2); /* Read tcamx. Change the control param */ ctl |= CTLXYBITSEL_V(1); @@ -1629,6 +1655,12 @@ static int mps_tcam_show(struct seq_file *seq, void *v) val = t4_read_reg(adap, MPS_CLS_TCAM_DATA1_A); tcamx = DMACH_G(val) << 32; tcamx |= t4_read_reg(adap, MPS_CLS_TCAM_DATA0_A); + data2 = t4_read_reg(adap, MPS_CLS_TCAM_DATA2_CTL_A); + if (lookup_type && (lookup_type != DATALKPTYPE_M)) { + /* Inner header VNI mask */ + vnix = ((data2 & DATAVIDH2_F) << 23) | + (DATAVIDH1_G(data2) << 16) | VIDL_G(val); + } } else { tcamy = t4_read_reg64(adap, MPS_CLS_TCAM_Y_L(idx)); tcamx = t4_read_reg64(adap, MPS_CLS_TCAM_X_L(idx)); @@ -1688,17 +1720,47 @@ static int mps_tcam_show(struct seq_file *seq, void *v) } tcamxy2valmask(tcamx, tcamy, addr, &mask); - if (chip_ver > CHELSIO_T5) - seq_printf(seq, "%3u %02x:%02x:%02x:%02x:%02x:%02x " - "%012llx%3c %#x%4u%4d", - idx, addr[0], addr[1], addr[2], addr[3], - addr[4], addr[5], (unsigned long long)mask, - (cls_lo & T6_SRAM_VLD_F) ? 'Y' : 'N', - PORTMAP_G(cls_hi), - T6_PF_G(cls_lo), - (cls_lo & T6_VF_VALID_F) ? - T6_VF_G(cls_lo) : -1); - else + if (chip_ver > CHELSIO_T5) { + /* Inner header lookup */ + if (lookup_type && (lookup_type != DATALKPTYPE_M)) { + seq_printf(seq, + "%3u %02x:%02x:%02x:%02x:%02x:%02x " + "%012llx %06x %06x - - %3c" + " %3c %4x " + "%3c %#x%4u%4d", idx, addr[0], + addr[1], addr[2], addr[3], + addr[4], addr[5], + (unsigned long long)mask, + vniy, vnix, dip_hit ? 'Y' : 'N', + lookup_type ? 'I' : 'O', port_num, + (cls_lo & T6_SRAM_VLD_F) ? 'Y' : 'N', + PORTMAP_G(cls_hi), + T6_PF_G(cls_lo), + (cls_lo & T6_VF_VALID_F) ? + T6_VF_G(cls_lo) : -1); + } else { + seq_printf(seq, + "%3u %02x:%02x:%02x:%02x:%02x:%02x " + "%012llx - - ", + idx, addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5], + (unsigned long long)mask); + + if (vlan_vld) + seq_printf(seq, "%4u Y ", ivlan); + else + seq_puts(seq, " - N "); + + seq_printf(seq, + "- %3c %4x %3c %#x%4u%4d", + lookup_type ? 'I' : 'O', port_num, + (cls_lo & T6_SRAM_VLD_F) ? 'Y' : 'N', + PORTMAP_G(cls_hi), + T6_PF_G(cls_lo), + (cls_lo & T6_VF_VALID_F) ? + T6_VF_G(cls_lo) : -1); + } + } else seq_printf(seq, "%3u %02x:%02x:%02x:%02x:%02x:%02x " "%012llx%3c %#x%4u%4d", idx, addr[0], addr[1], addr[2], addr[3], diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index 0971cc41c747..9fea255c7e87 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -2398,6 +2398,30 @@ #define MPS_CLS_TCAM_DATA0_A 0xf000 #define MPS_CLS_TCAM_DATA1_A 0xf004 +#define VIDL_S 16 +#define VIDL_M 0xffffU +#define VIDL_G(x) (((x) >> VIDL_S) & VIDL_M) + +#define DATALKPTYPE_S 10 +#define DATALKPTYPE_M 0x3U +#define DATALKPTYPE_G(x) (((x) >> DATALKPTYPE_S) & DATALKPTYPE_M) + +#define DATAPORTNUM_S 12 +#define DATAPORTNUM_M 0xfU +#define DATAPORTNUM_G(x) (((x) >> DATAPORTNUM_S) & DATAPORTNUM_M) + +#define DATADIPHIT_S 8 +#define DATADIPHIT_V(x) ((x) << DATADIPHIT_S) +#define DATADIPHIT_F DATADIPHIT_V(1U) + +#define DATAVIDH2_S 7 +#define DATAVIDH2_V(x) ((x) << DATAVIDH2_S) +#define DATAVIDH2_F DATAVIDH2_V(1U) + +#define DATAVIDH1_S 0 +#define DATAVIDH1_M 0x7fU +#define DATAVIDH1_G(x) (((x) >> DATAVIDH1_S) & DATAVIDH1_M) + #define USED_S 16 #define USED_M 0x7ffU #define USED_G(x) (((x) >> USED_S) & USED_M) From 2216d01432cb1589d1bfbd2722f2ec05cb26ea51 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:18 +0530 Subject: [PATCH 8/9] cxgb4: Update SGE context congestion map change for T6 adapter SGE context congestion map changed from 4 to 8 priority per port in T6 as there are only 2 channels. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 + drivers/net/ethernet/chelsio/cxgb4/sge.c | 7 ++++--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 9 +++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 5c193a5f564e..ec6e849676c1 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -302,6 +302,7 @@ struct devlog_params { struct arch_specific_params { u8 nchan; u8 pm_stats_cnt; + u8 cng_ch_bits_log; /* congestion channel map bits width */ u16 mps_rplc_size; u16 vfcount; u32 sge_fl_db; diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index 5829c9caa1fa..b4eb4680a27c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -2670,8 +2670,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, * simple (and hopefully less wrong). */ if (!is_t4(adap->params.chip) && cong >= 0) { - u32 param, val; + u32 param, val, ch_map = 0; int i; + u16 cng_ch_bits_log = adap->params.arch.cng_ch_bits_log; param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) | FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) | @@ -2683,9 +2684,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, CONMCTXT_CNGTPMODE_V(CONMCTXT_CNGTPMODE_CHANNEL_X); for (i = 0; i < 4; i++) { if (cong & (1 << i)) - val |= - CONMCTXT_CNGCHMAP_V(1 << (i << 2)); + ch_map |= 1 << (i << cng_ch_bits_log); } + val |= CONMCTXT_CNGCHMAP_V(ch_map); } ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 0132b6492611..636b4691f252 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -7194,6 +7194,10 @@ int t4_prep_adapter(struct adapter *adapter) adapter->params.arch.nchan = NCHAN; adapter->params.arch.pm_stats_cnt = PM_NSTATS; adapter->params.arch.vfcount = 128; + /* Congestion map is for 4 channels so that + * MPS can have 4 priority per port. + */ + adapter->params.arch.cng_ch_bits_log = 2; break; case CHELSIO_T5: adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev); @@ -7204,6 +7208,7 @@ int t4_prep_adapter(struct adapter *adapter) adapter->params.arch.nchan = NCHAN; adapter->params.arch.pm_stats_cnt = PM_NSTATS; adapter->params.arch.vfcount = 128; + adapter->params.arch.cng_ch_bits_log = 2; break; case CHELSIO_T6: adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev); @@ -7214,6 +7219,10 @@ int t4_prep_adapter(struct adapter *adapter) adapter->params.arch.nchan = 2; adapter->params.arch.pm_stats_cnt = T6_PM_NSTATS; adapter->params.arch.vfcount = 256; + /* Congestion map will be for 2 channels so that + * MPS can have 8 priority per port. + */ + adapter->params.arch.cng_ch_bits_log = 3; break; default: dev_err(adapter->pdev_dev, "Device %d is not supported\n", From 10aa3b78e9446b6d31262671dc1faed8d950d090 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 23 Dec 2015 22:47:19 +0530 Subject: [PATCH 9/9] cxgb4vf: Update to 128 byte mailbox size for T6 adapter Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h | 1 + drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h index b516b12b1884..f859db3d254c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h @@ -54,6 +54,7 @@ #define T4VF_MPS_BASE_ADDR 0x0100 #define T4VF_PL_BASE_ADDR 0x0200 #define T4VF_MBDATA_BASE_ADDR 0x0240 +#define T6VF_MBDATA_BASE_ADDR 0x0280 #define T4VF_CIM_BASE_ADDR 0x0300 #define T4VF_REGMAP_START 0x0000 diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 63dd5fdac5b9..b6fa74aafe47 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -120,12 +120,19 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, 1, 1, 3, 5, 10, 10, 20, 50, 100 }; - u32 v; + u32 v, mbox_data; int i, ms, delay_idx; const __be64 *p; - u32 mbox_data = T4VF_MBDATA_BASE_ADDR; u32 mbox_ctl = T4VF_CIM_BASE_ADDR + CIM_VF_EXT_MAILBOX_CTRL; + /* In T6, mailbox size is changed to 128 bytes to avoid + * invalidating the entire prefetch buffer. + */ + if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) + mbox_data = T4VF_MBDATA_BASE_ADDR; + else + mbox_data = T6VF_MBDATA_BASE_ADDR; + /* * Commands must be multiples of 16 bytes in length and may not be * larger than the size of the Mailbox Data register array.