2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-20 19:23:57 +08:00

Merge branch 'cxgb4-T6-update'

Hariprasad Shenai says:

====================
Update support for T6 adapters

This patch changes updates the various code changes related to
register, stats and hardware related changes for T6 family of
adapters.

This patch series has been created against net-next tree and includes
patches on cxgb4 and cxgb4vf driver.

We have included all the maintainers of respective drivers. Kindly review
the change and let us know in case of any review comments.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2015-12-23 22:34:45 -05:00
commit 6a29a42bb4
12 changed files with 338 additions and 73 deletions

View File

@ -301,6 +301,8 @@ struct devlog_params {
/* Stores chip specific parameters */ /* Stores chip specific parameters */
struct arch_specific_params { struct arch_specific_params {
u8 nchan; u8 nchan;
u8 pm_stats_cnt;
u8 cng_ch_bits_log; /* congestion channel map bits width */
u16 mps_rplc_size; u16 mps_rplc_size;
u16 vfcount; u16 vfcount;
u32 sge_fl_db; 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_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op);
int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
const u8 *fw_data, unsigned int size, int force); 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); unsigned int t4_flash_cfg_addr(struct adapter *adapter);
int t4_check_fw_version(struct adapter *adap); int t4_check_fw_version(struct adapter *adap);
int t4_get_fw_version(struct adapter *adapter, u32 *vers); int t4_get_fw_version(struct adapter *adapter, u32 *vers);

View File

@ -757,8 +757,8 @@ static int pm_stats_show(struct seq_file *seq, void *v)
}; };
int i; int i;
u32 tx_cnt[PM_NSTATS], rx_cnt[PM_NSTATS]; u32 tx_cnt[T6_PM_NSTATS], rx_cnt[T6_PM_NSTATS];
u64 tx_cyc[PM_NSTATS], rx_cyc[PM_NSTATS]; u64 tx_cyc[T6_PM_NSTATS], rx_cyc[T6_PM_NSTATS];
struct adapter *adap = seq->private; struct adapter *adap = seq->private;
t4_pmtx_get_stats(adap, tx_cnt, tx_cyc); 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++) for (i = 0; i < PM_NSTATS - 1; i++)
seq_printf(seq, "%-13s %10u %20llu\n", seq_printf(seq, "%-13s %10u %20llu\n",
rx_pm_stats[i], rx_cnt[i], rx_cyc[i]); 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; return 0;
} }
@ -1559,8 +1585,15 @@ static int mps_tcam_show(struct seq_file *seq, void *v)
{ {
struct adapter *adap = seq->private; struct adapter *adap = seq->private;
unsigned int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip); unsigned int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
if (v == SEQ_START_TOKEN) { if (v == SEQ_START_TOKEN) {
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 {
if (adap->params.arch.mps_rplc_size > 128) if (adap->params.arch.mps_rplc_size > 128)
seq_puts(seq, "Idx Ethernet address Mask " seq_puts(seq, "Idx Ethernet address Mask "
"Vld Ports PF VF " "Vld Ports PF VF "
@ -1570,14 +1603,17 @@ static int mps_tcam_show(struct seq_file *seq, void *v)
seq_puts(seq, "Idx Ethernet address Mask " seq_puts(seq, "Idx Ethernet address Mask "
"Vld Ports PF VF Replication" "Vld Ports PF VF Replication"
" P0 P1 P2 P3 ML\n"); " P0 P1 P2 P3 ML\n");
}
} else { } else {
u64 mask; u64 mask;
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
bool replicate; bool replicate, dip_hit = false, vlan_vld = false;
unsigned int idx = (uintptr_t)v - 2; unsigned int idx = (uintptr_t)v - 2;
u64 tcamy, tcamx, val; 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}; u32 rplc[8] = {0};
u8 lookup_type = 0, port_num = 0;
u16 ivlan = 0;
if (chip_ver > CHELSIO_T5) { if (chip_ver > CHELSIO_T5) {
/* CtlCmdType - 0: Read, 1: Write /* 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); val = t4_read_reg(adap, MPS_CLS_TCAM_DATA1_A);
tcamy = DMACH_G(val) << 32; tcamy = DMACH_G(val) << 32;
tcamy |= t4_read_reg(adap, MPS_CLS_TCAM_DATA0_A); 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 */ /* Read tcamx. Change the control param */
ctl |= CTLXYBITSEL_V(1); 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); val = t4_read_reg(adap, MPS_CLS_TCAM_DATA1_A);
tcamx = DMACH_G(val) << 32; tcamx = DMACH_G(val) << 32;
tcamx |= t4_read_reg(adap, MPS_CLS_TCAM_DATA0_A); 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 { } else {
tcamy = t4_read_reg64(adap, MPS_CLS_TCAM_Y_L(idx)); tcamy = t4_read_reg64(adap, MPS_CLS_TCAM_Y_L(idx));
tcamx = t4_read_reg64(adap, MPS_CLS_TCAM_X_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); tcamxy2valmask(tcamx, tcamy, addr, &mask);
if (chip_ver > CHELSIO_T5) if (chip_ver > CHELSIO_T5) {
seq_printf(seq, "%3u %02x:%02x:%02x:%02x:%02x:%02x " /* Inner header lookup */
"%012llx%3c %#x%4u%4d", if (lookup_type && (lookup_type != DATALKPTYPE_M)) {
idx, addr[0], addr[1], addr[2], addr[3], seq_printf(seq,
addr[4], addr[5], (unsigned long long)mask, "%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', (cls_lo & T6_SRAM_VLD_F) ? 'Y' : 'N',
PORTMAP_G(cls_hi), PORTMAP_G(cls_hi),
T6_PF_G(cls_lo), T6_PF_G(cls_lo),
(cls_lo & T6_VF_VALID_F) ? (cls_lo & T6_VF_VALID_F) ?
T6_VF_G(cls_lo) : -1); 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 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 " seq_printf(seq, "%3u %02x:%02x:%02x:%02x:%02x:%02x "
"%012llx%3c %#x%4u%4d", "%012llx%3c %#x%4u%4d",
idx, addr[0], addr[1], addr[2], addr[3], idx, addr[0], addr[1], addr[2], addr[3],

View File

@ -686,7 +686,7 @@ static int set_pauseparam(struct net_device *dev,
if (epause->tx_pause) if (epause->tx_pause)
lc->requested_fc |= PAUSE_TX; lc->requested_fc |= PAUSE_TX;
if (netif_running(dev)) 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); lc);
return 0; return 0;
} }

View File

@ -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 */ /* configure SGE_STAT_CFG_A to read WC stats */
if (!is_t4(adapter->params.chip)) if (!is_t4(adapter->params.chip))
t4_write_reg(adapter, SGE_STAT_CFG_A, t4_write_reg(adapter, SGE_STAT_CFG_A, STATSOURCE_T5_V(7) |
STATSOURCE_T5_V(7) | STATMODE_V(0)); (is_t5(adapter->params.chip) ? STATMODE_V(0) :
T6_STATMODE_V(0)));
for_each_port(adapter, i) { for_each_port(adapter, i) {
struct net_device *netdev; struct net_device *netdev;

View File

@ -2670,8 +2670,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
* simple (and hopefully less wrong). * simple (and hopefully less wrong).
*/ */
if (!is_t4(adap->params.chip) && cong >= 0) { if (!is_t4(adap->params.chip) && cong >= 0) {
u32 param, val; u32 param, val, ch_map = 0;
int i; int i;
u16 cng_ch_bits_log = adap->params.arch.cng_ch_bits_log;
param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) | param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) |
FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) | 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); CONMCTXT_CNGTPMODE_V(CONMCTXT_CNGTPMODE_CHANNEL_X);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (cong & (1 << i)) if (cong & (1 << i))
val |= ch_map |= 1 << (i << cng_ch_bits_log);
CONMCTXT_CNGCHMAP_V(1 << (i << 2));
} }
val |= CONMCTXT_CNGCHMAP_V(ch_map);
} }
ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1, ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1,
&param, &val); &param, &val);
@ -3173,8 +3174,7 @@ static int t4_sge_init_soft(struct adapter *adap)
int t4_sge_init(struct adapter *adap) int t4_sge_init(struct adapter *adap)
{ {
struct sge *s = &adap->sge; struct sge *s = &adap->sge;
u32 sge_control, sge_control2, sge_conm_ctrl; u32 sge_control, sge_conm_ctrl;
unsigned int ingpadboundary, ingpackboundary;
int ret, egress_threshold; int ret, egress_threshold;
/* /*
@ -3185,35 +3185,7 @@ int t4_sge_init(struct adapter *adap)
s->pktshift = PKTSHIFT_G(sge_control); s->pktshift = PKTSHIFT_G(sge_control);
s->stat_len = (sge_control & EGRSTATUSPAGESIZE_F) ? 128 : 64; s->stat_len = (sge_control & EGRSTATUSPAGESIZE_F) ? 128 : 64;
/* T4 uses a single control field to specify both the PCIe Padding and s->fl_align = t4_fl_pkt_align(adap);
* 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);
}
ret = t4_sge_init_soft(adap); ret = t4_sge_init_soft(adap);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -3231,10 +3203,21 @@ int t4_sge_init(struct adapter *adap)
* buffers. * buffers.
*/ */
sge_conm_ctrl = t4_read_reg(adap, SGE_CONM_CTRL_A); 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); egress_threshold = EGRTHRESHOLD_G(sge_conm_ctrl);
else break;
case CHELSIO_T5:
egress_threshold = EGRTHRESHOLDPACKING_G(sge_conm_ctrl); 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; s->fl_starve_thres = 2*egress_threshold + 1;
t4_idma_monitor_init(adap, &s->idma_monitor); t4_idma_monitor_init(adap, &s->idma_monitor);

View File

@ -1942,8 +1942,12 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
0x1190, 0x1194, 0x1190, 0x1194,
0x11a0, 0x11a4, 0x11a0, 0x11a4,
0x11b0, 0x11b4, 0x11b0, 0x11b4,
0x11fc, 0x1254, 0x11fc, 0x1258,
0x1280, 0x133c, 0x1280, 0x12d4,
0x12d9, 0x12d9,
0x12de, 0x12de,
0x12e3, 0x12e3,
0x12e8, 0x133c,
0x1800, 0x18fc, 0x1800, 0x18fc,
0x3000, 0x302c, 0x3000, 0x302c,
0x3060, 0x30b0, 0x3060, 0x30b0,
@ -1973,7 +1977,7 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
0x5e50, 0x5e94, 0x5e50, 0x5e94,
0x5ea0, 0x5eb0, 0x5ea0, 0x5eb0,
0x5ec0, 0x5ec0, 0x5ec0, 0x5ec0,
0x5ec8, 0x5ecc, 0x5ec8, 0x5ed0,
0x6000, 0x6020, 0x6000, 0x6020,
0x6028, 0x6040, 0x6028, 0x6040,
0x6058, 0x609c, 0x6058, 0x609c,
@ -2048,7 +2052,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
0x19150, 0x19194, 0x19150, 0x19194,
0x1919c, 0x191b0, 0x1919c, 0x191b0,
0x191d0, 0x191e8, 0x191d0, 0x191e8,
0x19238, 0x192b0, 0x19238, 0x19290,
0x192a4, 0x192b0,
0x192bc, 0x192bc, 0x192bc, 0x192bc,
0x19348, 0x1934c, 0x19348, 0x1934c,
0x193f8, 0x19418, 0x193f8, 0x19418,
@ -2442,7 +2447,8 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
0x40280, 0x40280, 0x40280, 0x40280,
0x40304, 0x40304, 0x40304, 0x40304,
0x40330, 0x4033c, 0x40330, 0x4033c,
0x41304, 0x413c8, 0x41304, 0x413b8,
0x413c0, 0x413c8,
0x413d0, 0x413dc, 0x413d0, 0x413dc,
0x413f0, 0x413f0, 0x413f0, 0x413f0,
0x41400, 0x4140c, 0x41400, 0x4140c,
@ -5254,7 +5260,7 @@ void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
int i; int i;
u32 data[2]; 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); t4_write_reg(adap, PM_TX_STAT_CONFIG_A, i + 1);
cnt[i] = t4_read_reg(adap, PM_TX_STAT_COUNT_A); cnt[i] = t4_read_reg(adap, PM_TX_STAT_COUNT_A);
if (is_t4(adap->params.chip)) { if (is_t4(adap->params.chip)) {
@ -5281,7 +5287,7 @@ void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
int i; int i;
u32 data[2]; 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); t4_write_reg(adap, PM_RX_STAT_CONFIG_A, i + 1);
cnt[i] = t4_read_reg(adap, PM_RX_STAT_COUNT_A); cnt[i] = t4_read_reg(adap, PM_RX_STAT_COUNT_A);
if (is_t4(adap->params.chip)) { 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) if (n == 0)
return idx == 0 ? 0xf : 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 idx < 2 ? (3 << (2 * idx)) : 0;
return 1 << idx; 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_PADDING",
"IDMA_FL_SEND_COMPLETION_TO_IMSG", "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[] = { static const u32 sge_regs[] = {
SGE_DEBUG_DATA_LOW_INDEX_2_A, SGE_DEBUG_DATA_LOW_INDEX_2_A,
SGE_DEBUG_DATA_LOW_INDEX_3_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; const char **sge_idma_decode;
int sge_idma_decode_nstates; int sge_idma_decode_nstates;
int i; 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)) { if (is_t4(adapter->params.chip)) {
sge_idma_decode = (const char **)t4_decode; sge_idma_decode = (const char **)t4_decode;
@ -6096,6 +6168,59 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
return t4_fw_restart(adap, mbox, reset); 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 * t4_fixup_host_params - fix up host-dependent parameters
* @adap: the adapter * @adap: the adapter
@ -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 stat_len = cache_line_size > 64 ? 128 : 64;
unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size; unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size;
unsigned int fl_align_log = fls(fl_align) - 1; unsigned int fl_align_log = fls(fl_align) - 1;
unsigned int ingpad;
t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A, t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A,
HOSTPAGESIZEPF0_V(sge_hps) | 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 = 64;
fl_align_log = 6; 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, t4_set_reg_field(adap, SGE_CONTROL_A,
INGPADBOUNDARY_V(INGPADBOUNDARY_M) | INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
EGRSTATUSPAGESIZE_F, EGRSTATUSPAGESIZE_F,
INGPADBOUNDARY_V(INGPCIEBOUNDARY_32B_X) | INGPADBOUNDARY_V(ingpad) |
EGRSTATUSPAGESIZE_V(stat_len != 64)); EGRSTATUSPAGESIZE_V(stat_len != 64));
t4_set_reg_field(adap, SGE_CONTROL2_A, t4_set_reg_field(adap, SGE_CONTROL2_A,
INGPACKBOUNDARY_V(INGPACKBOUNDARY_M), INGPACKBOUNDARY_V(INGPACKBOUNDARY_M),
@ -7060,7 +7192,12 @@ int t4_prep_adapter(struct adapter *adapter)
NUM_MPS_CLS_SRAM_L_INSTANCES; NUM_MPS_CLS_SRAM_L_INSTANCES;
adapter->params.arch.mps_rplc_size = 128; adapter->params.arch.mps_rplc_size = 128;
adapter->params.arch.nchan = NCHAN; adapter->params.arch.nchan = NCHAN;
adapter->params.arch.pm_stats_cnt = PM_NSTATS;
adapter->params.arch.vfcount = 128; 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; break;
case CHELSIO_T5: case CHELSIO_T5:
adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev); 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; NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
adapter->params.arch.mps_rplc_size = 128; adapter->params.arch.mps_rplc_size = 128;
adapter->params.arch.nchan = NCHAN; adapter->params.arch.nchan = NCHAN;
adapter->params.arch.pm_stats_cnt = PM_NSTATS;
adapter->params.arch.vfcount = 128; adapter->params.arch.vfcount = 128;
adapter->params.arch.cng_ch_bits_log = 2;
break; break;
case CHELSIO_T6: case CHELSIO_T6:
adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev); 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; NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
adapter->params.arch.mps_rplc_size = 256; adapter->params.arch.mps_rplc_size = 256;
adapter->params.arch.nchan = 2; adapter->params.arch.nchan = 2;
adapter->params.arch.pm_stats_cnt = T6_PM_NSTATS;
adapter->params.arch.vfcount = 256; 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; break;
default: default:
dev_err(adapter->pdev_dev, "Device %d is not supported\n", dev_err(adapter->pdev_dev, "Device %d is not supported\n",

View File

@ -48,6 +48,7 @@ enum {
NMTUS = 16, /* size of MTU table */ NMTUS = 16, /* size of MTU table */
NCCTRL_WIN = 32, /* # of congestion control windows */ NCCTRL_WIN = 32, /* # of congestion control windows */
PM_NSTATS = 5, /* # of PM stats */ PM_NSTATS = 5, /* # of PM stats */
T6_PM_NSTATS = 7, /* # of PM stats in T6 */
MBOX_LEN = 64, /* mailbox size in bytes */ MBOX_LEN = 64, /* mailbox size in bytes */
TRACE_LEN = 112, /* length of trace data and mask */ TRACE_LEN = 112, /* length of trace data and mask */
FILTER_OPT_LEN = 36, /* filter tuple width for optional components */ FILTER_OPT_LEN = 36, /* filter tuple width for optional components */

View File

@ -492,6 +492,9 @@
#define STATSOURCE_T5_V(x) ((x) << STATSOURCE_T5_S) #define STATSOURCE_T5_V(x) ((x) << STATSOURCE_T5_S)
#define STATSOURCE_T5_G(x) (((x) >> STATSOURCE_T5_S) & STATSOURCE_T5_M) #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 SGE_DBFIFO_STATUS2_A 0x1118
#define HP_INT_THRESH_T5_S 10 #define HP_INT_THRESH_T5_S 10
@ -2395,6 +2398,30 @@
#define MPS_CLS_TCAM_DATA0_A 0xf000 #define MPS_CLS_TCAM_DATA0_A 0xf000
#define MPS_CLS_TCAM_DATA1_A 0xf004 #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_S 16
#define USED_M 0x7ffU #define USED_M 0x7ffU
#define USED_G(x) (((x) >> USED_S) & USED_M) #define USED_G(x) (((x) >> USED_S) & USED_M)

View File

@ -53,6 +53,9 @@
#define INGPADBOUNDARY_SHIFT_X 5 #define INGPADBOUNDARY_SHIFT_X 5
#define T6_INGPADBOUNDARY_SHIFT_X 3
#define T6_INGPADBOUNDARY_32B_X 2
/* CONTROL2 register */ /* CONTROL2 register */
#define INGPACKBOUNDARY_SHIFT_X 5 #define INGPACKBOUNDARY_SHIFT_X 5
#define INGPACKBOUNDARY_16B_X 0 #define INGPACKBOUNDARY_16B_X 0

View File

@ -2607,7 +2607,7 @@ int t4vf_sge_init(struct adapter *adapter)
u32 fl0 = sge_params->sge_fl_buffer_size[0]; u32 fl0 = sge_params->sge_fl_buffer_size[0];
u32 fl1 = sge_params->sge_fl_buffer_size[1]; u32 fl1 = sge_params->sge_fl_buffer_size[1];
struct sge *s = &adapter->sge; 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 * 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 * 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 * end doing this because it would initialize the Padding Boundary and
* leave the Packing Boundary initialized to 0 (16 bytes).) * 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 = 1 << (INGPADBOUNDARY_G(sge_params->sge_control) +
INGPADBOUNDARY_SHIFT_X); ingpad_shift);
if (is_t4(adapter->params.chip)) { if (is_t4(adapter->params.chip)) {
s->fl_align = ingpadboundary; s->fl_align = ingpadboundary;
} else { } else {

View File

@ -54,6 +54,7 @@
#define T4VF_MPS_BASE_ADDR 0x0100 #define T4VF_MPS_BASE_ADDR 0x0100
#define T4VF_PL_BASE_ADDR 0x0200 #define T4VF_PL_BASE_ADDR 0x0200
#define T4VF_MBDATA_BASE_ADDR 0x0240 #define T4VF_MBDATA_BASE_ADDR 0x0240
#define T6VF_MBDATA_BASE_ADDR 0x0280
#define T4VF_CIM_BASE_ADDR 0x0300 #define T4VF_CIM_BASE_ADDR 0x0300
#define T4VF_REGMAP_START 0x0000 #define T4VF_REGMAP_START 0x0000

View File

@ -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 1, 1, 3, 5, 10, 10, 20, 50, 100
}; };
u32 v; u32 v, mbox_data;
int i, ms, delay_idx; int i, ms, delay_idx;
const __be64 *p; const __be64 *p;
u32 mbox_data = T4VF_MBDATA_BASE_ADDR;
u32 mbox_ctl = T4VF_CIM_BASE_ADDR + CIM_VF_EXT_MAILBOX_CTRL; 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 * Commands must be multiples of 16 bytes in length and may not be
* larger than the size of the Mailbox Data register array. * larger than the size of the Mailbox Data register array.