summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c130
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c5
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sge.c55
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c162
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h27
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_values.h3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/sge.c11
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c11
12 files changed, 338 insertions, 73 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 3b59bc4038a6..ec6e849676c1 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -301,6 +301,8 @@ struct devlog_params {
/* Stores chip specific parameters */
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;
@@ -1255,6 +1257,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/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 62a343fc9c1a..1bab34f923e7 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;
}
@@ -1559,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
@@ -1596,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);
@@ -1603,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));
@@ -1662,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/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;
}
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 5e3ffa73ee13..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,
&param, &val);
@@ -3173,8 +3174,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 +3185,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;
@@ -3231,10 +3203,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 cf61a5869c6e..636b4691f252 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,
@@ -5254,7 +5260,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 +5287,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)) {
@@ -5310,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;
}
@@ -5689,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,
@@ -5697,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;
@@ -6097,6 +6169,59 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
}
/**
+ * 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
* @page_size: the host's Base Page Size
@@ -6114,6 +6239,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 +6287,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),
@@ -7060,7 +7192,12 @@ 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;
+ /* 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);
@@ -7069,7 +7206,9 @@ 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;
+ adapter->params.arch.cng_ch_bits_log = 2;
break;
case CHELSIO_T6:
adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev);
@@ -7078,7 +7217,12 @@ 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;
+ /* 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",
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 */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 91b52a21a2e7..9fea255c7e87 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
@@ -2395,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)
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 {
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.