diff options
author | jhb <jhb@FreeBSD.org> | 2016-12-05 20:43:25 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2016-12-05 20:43:25 +0000 |
commit | 14b8e70534d9788f03d27c16ff5957513ea67edc (patch) | |
tree | e4c4064dca3e307af30217c487806cabed81cdc7 /sys/dev/cxgbe/t4_main.c | |
parent | 2d64e2dd58e247189656af25ac3b78211bd989f9 (diff) | |
download | FreeBSD-src-14b8e70534d9788f03d27c16ff5957513ea67edc.zip FreeBSD-src-14b8e70534d9788f03d27c16ff5957513ea67edc.tar.gz |
MFC 305695,305696,305699,305702,305703,305713,305715,305827,305852,305906,
305908,306062,306063,306137,306138,306206,306216,306273,306295,306301,
306465,309302:
Add support for adapters using the Terminator T6 ASIC.
305695:
cxgbe(4): Set up fl_starve_threshold2 accurately for T6.
305696:
cxgbe(4): Use correct macro for header length with T6 ASICs. This
affects the transmit of the VF driver only.
305699:
cxgbe(4): Update the pad_boundary calculation for T6, which has a
different range of boundaries.
305702:
cxgbe(4): Use smaller min/max bursts for fl descriptors with a T6.
305703:
cxgbe(4): Deal with the slightly different SGE_STAT_CFG in T6.
305713:
cxgbe(4): Add support for additional port types and link speeds.
305715:
cxgbe(4): Catch up with the rename of tlscaps -> cryptocaps. TLS is one
of the capabilities of the crypto engine in T6.
305827:
cxgbe(4): Use the interface's viid to calculate the PF/VF/VFValid fields
to use in tx work requests.
305852:
cxgbe(4): Attach to cards with the Terminator 6 ASIC. T6 cards will
come up as 't6nex' nexus devices with 'cc' ports hanging off them.
The T6 firmware and configuration files will be added as soon as they
are released. For now the driver will try to work with whatever
firmware and configuration is on the card's flash.
305906:
cxgbe/t4_tom: The SMAC entry for a VI is at a different location in the T6.
305908:
cxgbe/t4_tom: Update the active/passive open code to support T6. Data
path works as-is.
306062:
cxgbe(4): Show wcwr_stats for T6 cards.
306063:
cxgbe(4): Setup congestion response for T6 rx queues.
306137:
cxgbetool: Add T6 support to the SGE context decoder.
306138:
Fix typo.
306206:
cxgbe(4): Catch up with the different layout of WHOAMI in T6.
Note that the code moved below t4_prep_adapter() as part of this change
because now it needs a working chip_id().
306216:
cxgbe(4): Fix the output of the "tids" sysctl on T6.
306273:
cxgbe(4): Fix netmap with T6, which doesn't encapsulate SGE_EGR_UPDATE
message inside a FW_MSG. The base NIC already deals with updates in
either form.
306295:
cxgbe(4): Support SIOGIFXMEDIA so that ifconfig displays correct media
for 25Gbps and 100Gbps ports. This should have been part of r305713,
which is when the driver first started reporting extended media types.
306301:
cxgbe(4): Use the port's top speed to figure out whether it is "high
speed" or not (for the purpose of calculating the number of queues etc.)
This does the right thing for 25Gbps and 100Gbps ports.
306465:
cxgbe(4): Claim the T6 -DBG card.
309302:
cxgbe(4): Include firmware for T6 cards in the driver. Update all
firmwares to 1.16.12.0.
Sponsored by: Chelsio Communications
Diffstat (limited to 'sys/dev/cxgbe/t4_main.c')
-rw-r--r-- | sys/dev/cxgbe/t4_main.c | 284 |
1 files changed, 252 insertions, 32 deletions
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 898a515..7b2aede 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -166,6 +166,36 @@ static driver_t vcxl_driver = { sizeof(struct vi_info) }; +/* T6 bus driver interface */ +static int t6_probe(device_t); +static device_method_t t6_methods[] = { + DEVMETHOD(device_probe, t6_probe), + DEVMETHOD(device_attach, t4_attach), + DEVMETHOD(device_detach, t4_detach), + + DEVMETHOD_END +}; +static driver_t t6_driver = { + "t6nex", + t6_methods, + sizeof(struct adapter) +}; + + +/* T6 port (cc) interface */ +static driver_t cc_driver = { + "cc", + cxgbe_methods, + sizeof(struct port_info) +}; + +/* T6 VI (vcc) interface */ +static driver_t vcc_driver = { + "vcc", + vcxgbe_methods, + sizeof(struct vi_info) +}; + /* ifnet + media interface */ static void cxgbe_init(void *); static int cxgbe_ioctl(struct ifnet *, unsigned long, caddr_t); @@ -347,8 +377,8 @@ TUNABLE_INT("hw.cxgbe.toecaps_allowed", &t4_toecaps_allowed); static int t4_rdmacaps_allowed = -1; TUNABLE_INT("hw.cxgbe.rdmacaps_allowed", &t4_rdmacaps_allowed); -static int t4_tlscaps_allowed = 0; -TUNABLE_INT("hw.cxgbe.tlscaps_allowed", &t4_tlscaps_allowed); +static int t4_cryptocaps_allowed = 0; +TUNABLE_INT("hw.cxgbe.cryptocaps_allowed", &t4_cryptocaps_allowed); static int t4_iscsicaps_allowed = -1; TUNABLE_INT("hw.cxgbe.iscsicaps_allowed", &t4_iscsicaps_allowed); @@ -558,6 +588,14 @@ struct { {0x540f, "Chelsio Amsterdam"}, {0x5413, "Chelsio T580-CHR"}, #endif +}, t6_pciids[] = { + {0xc006, "Chelsio Terminator 6 FPGA"}, /* T6 PE10K6 FPGA (PF0) */ + {0x6401, "Chelsio T6225-CR"}, /* 2 x 10/25G */ + {0x6402, "Chelsio T6225-SO-CR"}, /* 2 x 10/25G, nomem */ + {0x6407, "Chelsio T62100-LP-CR"}, /* 2 x 40/50/100G */ + {0x6408, "Chelsio T62100-SO-CR"}, /* 2 x 40/50/100G, nomem */ + {0x640d, "Chelsio T62100-CR"}, /* 2 x 40/50/100G */ + {0x6410, "Chelsio T62100-DBG"}, /* 2 x 40/50/100G, debug */ }; #ifdef TCP_OFFLOAD @@ -620,6 +658,26 @@ t5_probe(device_t dev) return (ENXIO); } +static int +t6_probe(device_t dev) +{ + int i; + uint16_t v = pci_get_vendor(dev); + uint16_t d = pci_get_device(dev); + + if (v != PCI_VENDOR_ID_CHELSIO) + return (ENXIO); + + for (i = 0; i < nitems(t6_pciids); i++) { + if (d == t6_pciids[i].device) { + device_set_desc(dev, t6_pciids[i].desc); + return (BUS_PROBE_DEFAULT); + } + } + + return (ENXIO); +} + static void t5_attribute_workaround(device_t dev) { @@ -647,6 +705,45 @@ t5_attribute_workaround(device_t dev) device_get_nameunit(root_port)); } +static const struct devnames devnames[] = { + { + .nexus_name = "t4nex", + .ifnet_name = "cxgbe", + .vi_ifnet_name = "vcxgbe", + .pf03_drv_name = "t4iov", + .vf_nexus_name = "t4vf", + .vf_ifnet_name = "cxgbev" + }, { + .nexus_name = "t5nex", + .ifnet_name = "cxl", + .vi_ifnet_name = "vcxl", + .pf03_drv_name = "t5iov", + .vf_nexus_name = "t5vf", + .vf_ifnet_name = "cxlv" + }, { + .nexus_name = "t6nex", + .ifnet_name = "cc", + .vi_ifnet_name = "vcc", + .pf03_drv_name = "t6iov", + .vf_nexus_name = "t6vf", + .vf_ifnet_name = "ccv" + } +}; + +void +t4_init_devnames(struct adapter *sc) +{ + int id; + + id = chip_id(sc); + if (id >= CHELSIO_T4 && id - CHELSIO_T4 < nitems(devnames)) + sc->names = &devnames[id - CHELSIO_T4]; + else { + device_printf(sc->dev, "chip id %d is not supported.\n", id); + sc->names = NULL; + } +} + static int t4_attach(device_t dev) { @@ -704,15 +801,6 @@ t4_attach(device_t dev) if (rc != 0) goto done; /* error message displayed already */ - /* - * This is the real PF# to which we're attaching. Works from within PCI - * passthrough environments too, where pci_get_function() could return a - * different PF# depending on the passthrough configuration. We need to - * use the real PF# in all our communication with the firmware. - */ - sc->pf = G_SOURCEPF(t4_read_reg(sc, A_PL_WHOAMI)); - sc->mbox = sc->pf; - memset(sc->chan_map, 0xff, sizeof(sc->chan_map)); /* Prepare the adapter for operation. */ @@ -725,6 +813,22 @@ t4_attach(device_t dev) } /* + * This is the real PF# to which we're attaching. Works from within PCI + * passthrough environments too, where pci_get_function() could return a + * different PF# depending on the passthrough configuration. We need to + * use the real PF# in all our communication with the firmware. + */ + j = t4_read_reg(sc, A_PL_WHOAMI); + sc->pf = chip_id(sc) <= CHELSIO_T5 ? G_SOURCEPF(j) : G_T6_SOURCEPF(j); + sc->mbox = sc->pf; + + t4_init_devnames(sc); + if (sc->names == NULL) { + rc = ENOTSUP; + goto done; /* error message displayed already */ + } + + /* * Do this really early, with the memory windows set up even before the * character device. The userland tool's register i/o and mem read * will work even in "recovery mode". @@ -855,7 +959,7 @@ t4_attach(device_t dev) pi->tc = malloc(sizeof(struct tx_sched_class) * sc->chip_params->nsched_cls, M_CXGBE, M_ZERO | M_WAITOK); - if (is_10G_port(pi) || is_40G_port(pi)) { + if (port_top_speed(pi) >= 10) { n10g++; } else { n1g++; @@ -863,7 +967,7 @@ t4_attach(device_t dev) pi->linkdnrc = -1; - pi->dev = device_add_child(dev, is_t4(sc) ? "cxgbe" : "cxl", -1); + pi->dev = device_add_child(dev, sc->names->ifnet_name, -1); if (pi->dev == NULL) { device_printf(dev, "failed to add device for port %d.\n", i); @@ -971,7 +1075,7 @@ t4_attach(device_t dev) vi->first_rxq = rqidx; vi->first_txq = tqidx; - if (is_10G_port(pi) || is_40G_port(pi)) { + if (port_top_speed(pi) >= 10) { vi->tmr_idx = t4_tmr_idx_10g; vi->pktc_idx = t4_pktc_idx_10g; vi->flags |= iaq.intr_flags_10g & INTR_RXQ; @@ -995,7 +1099,7 @@ t4_attach(device_t dev) #ifdef TCP_OFFLOAD vi->first_ofld_rxq = ofld_rqidx; vi->first_ofld_txq = ofld_tqidx; - if (is_10G_port(pi) || is_40G_port(pi)) { + if (port_top_speed(pi) >= 10) { vi->flags |= iaq.intr_flags_10g & INTR_OFLD_RXQ; vi->nofldrxq = j == 0 ? iaq.nofldrxq10g : iaq.nofldrxq_vi; @@ -1284,6 +1388,7 @@ static int cxgbe_attach(device_t dev) { struct port_info *pi = device_get_softc(dev); + struct adapter *sc = pi->adapter; struct vi_info *vi; int i, rc; @@ -1296,8 +1401,7 @@ cxgbe_attach(device_t dev) for_each_vi(pi, i, vi) { if (i == 0) continue; - vi->dev = device_add_child(dev, is_t4(pi->adapter) ? - "vcxgbe" : "vcxl", -1); + vi->dev = device_add_child(dev, sc->names->vi_ifnet_name, -1); if (vi->dev == NULL) { device_printf(dev, "failed to add VI %d\n", i); continue; @@ -1560,6 +1664,7 @@ fail: case SIOCSIFMEDIA: case SIOCGIFMEDIA: + case SIOCGIFXMEDIA: ifmedia_ioctl(ifp, ifr, &vi->media, cmd); break; @@ -1739,6 +1844,10 @@ vcxgbe_attach(device_t dev) return (-rc); } vi->viid = rc; + if (chip_id(sc) <= CHELSIO_T5) + vi->smt_idx = (rc & 0x7f) << 1; + else + vi->smt_idx = (rc & 0x7f); param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_RSSINFO) | @@ -1841,11 +1950,11 @@ t4_map_bar_2(struct adapter *sc) } sc->udbs_base = rman_get_virtual(sc->udbs_res); - if (is_t5(sc)) { + if (chip_id(sc) >= CHELSIO_T5) { setbit(&sc->doorbells, DOORBELL_UDB); #if defined(__i386__) || defined(__amd64__) if (t5_write_combine) { - int rc; + int rc, mode; /* * Enable write combining on BAR2. This is the @@ -1868,8 +1977,9 @@ t4_map_bar_2(struct adapter *sc) rc); } + mode = is_t5(sc) ? V_STATMODE(0) : V_T6_STATMODE(0); t4_write_reg(sc, A_SGE_STAT_CFG, - V_STATSOURCE_T5(7) | V_STATMODE(0)); + V_STATSOURCE_T5(7) | mode); } #endif } @@ -2499,6 +2609,22 @@ struct fw_info { .intfver_fcoepdu = FW_INTFVER(T5, FCOEPDU), .intfver_fcoe = FW_INTFVER(T5, FCOE), }, + }, { + .chip = CHELSIO_T6, + .kld_name = "t6fw_cfg", + .fw_mod_name = "t6fw", + .fw_hdr = { + .chip = FW_HDR_CHIP_T6, + .fw_ver = htobe32_const(FW_VERSION(T6)), + .intfver_nic = FW_INTFVER(T6, NIC), + .intfver_vnic = FW_INTFVER(T6, VNIC), + .intfver_ofld = FW_INTFVER(T6, OFLD), + .intfver_ri = FW_INTFVER(T6, RI), + .intfver_iscsipdu = FW_INTFVER(T6, ISCSIPDU), + .intfver_iscsi = FW_INTFVER(T6, ISCSI), + .intfver_fcoepdu = FW_INTFVER(T6, FCOEPDU), + .intfver_fcoe = FW_INTFVER(T6, FCOE), + }, } }; @@ -2927,7 +3053,7 @@ use_config_on_flash: LIMIT_CAPS(niccaps); LIMIT_CAPS(toecaps); LIMIT_CAPS(rdmacaps); - LIMIT_CAPS(tlscaps); + LIMIT_CAPS(cryptocaps); LIMIT_CAPS(iscsicaps); LIMIT_CAPS(fcoecaps); #undef LIMIT_CAPS @@ -3064,7 +3190,7 @@ get_params__post_init(struct adapter *sc) READ_CAPS(niccaps); READ_CAPS(toecaps); READ_CAPS(rdmacaps); - READ_CAPS(tlscaps); + READ_CAPS(cryptocaps); READ_CAPS(iscsicaps); READ_CAPS(fcoecaps); @@ -3273,6 +3399,39 @@ build_medialist(struct port_info *pi, struct ifmedia *media) } break; + case FW_PORT_TYPE_CR_QSFP: + case FW_PORT_TYPE_CR_SFP28: + case FW_PORT_TYPE_SFP28: + case FW_PORT_TYPE_KR_SFP28: + switch (pi->mod_type) { + + case FW_PORT_MOD_TYPE_SR: + ifmedia_add(media, m | IFM_25G_SR, 0, NULL); + ifmedia_set(media, m | IFM_25G_SR); + break; + + case FW_PORT_MOD_TYPE_TWINAX_PASSIVE: + case FW_PORT_MOD_TYPE_TWINAX_ACTIVE: + ifmedia_add(media, m | IFM_25G_CR, 0, NULL); + ifmedia_set(media, m | IFM_25G_CR); + break; + + case FW_PORT_MOD_TYPE_NONE: + m &= ~IFM_FDX; + ifmedia_add(media, m | IFM_NONE, 0, NULL); + ifmedia_set(media, m | IFM_NONE); + break; + + default: + device_printf(pi->dev, + "unknown port_type (%d), mod_type (%d)\n", + pi->port_type, pi->mod_type); + ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL); + ifmedia_set(media, m | IFM_UNKNOWN); + break; + } + break; + case FW_PORT_TYPE_QSFP: switch (pi->mod_type) { @@ -3308,6 +3467,42 @@ build_medialist(struct port_info *pi, struct ifmedia *media) } break; + case FW_PORT_TYPE_KR4_100G: + case FW_PORT_TYPE_CR4_QSFP: + switch (pi->mod_type) { + + case FW_PORT_MOD_TYPE_LR: + ifmedia_add(media, m | IFM_100G_LR4, 0, NULL); + ifmedia_set(media, m | IFM_100G_LR4); + break; + + case FW_PORT_MOD_TYPE_SR: + ifmedia_add(media, m | IFM_100G_SR4, 0, NULL); + ifmedia_set(media, m | IFM_100G_SR4); + break; + + case FW_PORT_MOD_TYPE_TWINAX_PASSIVE: + case FW_PORT_MOD_TYPE_TWINAX_ACTIVE: + ifmedia_add(media, m | IFM_100G_CR4, 0, NULL); + ifmedia_set(media, m | IFM_100G_CR4); + break; + + case FW_PORT_MOD_TYPE_NONE: + m &= ~IFM_FDX; + ifmedia_add(media, m | IFM_NONE, 0, NULL); + ifmedia_set(media, m | IFM_NONE); + break; + + default: + device_printf(pi->dev, + "unknown port_type (%d), mod_type (%d)\n", + pi->port_type, pi->mod_type); + ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL); + ifmedia_set(media, m | IFM_UNKNOWN); + break; + } + break; + default: device_printf(pi->dev, "unknown port_type (%d), mod_type (%d)\n", pi->port_type, @@ -4041,7 +4236,7 @@ vi_full_init(struct vi_info *vi) F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN | F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN | F_FW_RSS_VI_CONFIG_CMD_UDPEN; #endif - rc = -t4_config_vi_rss(sc, sc->mbox, vi->viid, hashen, rss[0]); + rc = -t4_config_vi_rss(sc, sc->mbox, vi->viid, hashen, rss[0], 0, 0); if (rc != 0) { if_printf(ifp, "rss hash/defaultq config failed: %d\n", rc); goto done; @@ -4443,7 +4638,7 @@ static char *caps_decoder[] = { "\005INITIATOR_SSNOFLD\006TARGET_SSNOFLD" "\007T10DIF" "\010INITIATOR_CMDOFLD\011TARGET_CMDOFLD", - "\20\00KEYS", /* 7: TLS */ + "\20\001LOOKASIDE\002TLSKEYS", /* 7: Crypto */ "\20\001INITIATOR\002TARGET\003CTRL_OFLD" /* 8: FCoE */ "\004PO_INITIATOR\005PO_TARGET", }; @@ -4551,7 +4746,7 @@ t4_sysctls(struct adapter *sc) SYSCTL_CAP(toecaps, 4, "TCP offload"); SYSCTL_CAP(rdmacaps, 5, "RDMA"); SYSCTL_CAP(iscsicaps, 6, "iSCSI"); - SYSCTL_CAP(tlscaps, 7, "TLS"); + SYSCTL_CAP(cryptocaps, 7, "crypto"); SYSCTL_CAP(fcoecaps, 8, "FCoE"); #undef SYSCTL_CAP @@ -4727,7 +4922,7 @@ t4_sysctls(struct adapter *sc) CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_ulprx_la, "A", "ULPRX logic analyzer"); - if (is_t5(sc)) { + if (chip_id(sc) >= CHELSIO_T5) { SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "wcwr_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_wcwr_stats, "A", "write combined work requests"); @@ -6876,7 +7071,12 @@ sysctl_tids(SYSCTL_HANDLER_ARGS) if (t->ntids) { if (t4_read_reg(sc, A_LE_DB_CONFIG) & F_HASHEN) { - uint32_t b = t4_read_reg(sc, A_LE_DB_SERVER_INDEX) / 4; + uint32_t b; + + if (chip_id(sc) <= CHELSIO_T5) + b = t4_read_reg(sc, A_LE_DB_SERVER_INDEX) / 4; + else + b = t4_read_reg(sc, A_LE_DB_SRVR_START_INDEX); if (b) { sbuf_printf(sb, "TID range: 0-%u, %u-%u", b - 1, @@ -7331,6 +7531,8 @@ sysctl_wcwr_stats(SYSCTL_HANDLER_ARGS) struct sbuf *sb; int rc, v; + MPASS(chip_id(sc) >= CHELSIO_T5); + rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); @@ -7341,14 +7543,19 @@ sysctl_wcwr_stats(SYSCTL_HANDLER_ARGS) v = t4_read_reg(sc, A_SGE_STAT_CFG); if (G_STATSOURCE_T5(v) == 7) { - if (G_STATMODE(v) == 0) { + int mode; + + mode = is_t5(sc) ? G_STATMODE(v) : G_T6_STATMODE(v); + if (mode == 0) { sbuf_printf(sb, "total %d, incomplete %d", t4_read_reg(sc, A_SGE_STAT_TOTAL), t4_read_reg(sc, A_SGE_STAT_MATCH)); - } else if (G_STATMODE(v) == 1) { + } else if (mode == 1) { sbuf_printf(sb, "total %d, data overflow %d", t4_read_reg(sc, A_SGE_STAT_TOTAL), t4_read_reg(sc, A_SGE_STAT_MATCH)); + } else { + sbuf_printf(sb, "unknown mode %d", mode); } } rc = sbuf_finish(sb); @@ -9414,9 +9621,9 @@ done_unload: return (rc); } -static devclass_t t4_devclass, t5_devclass; -static devclass_t cxgbe_devclass, cxl_devclass; -static devclass_t vcxgbe_devclass, vcxl_devclass; +static devclass_t t4_devclass, t5_devclass, t6_devclass; +static devclass_t cxgbe_devclass, cxl_devclass, cc_devclass; +static devclass_t vcxgbe_devclass, vcxl_devclass, vcc_devclass; DRIVER_MODULE(t4nex, pci, t4_driver, t4_devclass, mod_event, 0); MODULE_VERSION(t4nex, 1); @@ -9426,14 +9633,27 @@ DRIVER_MODULE(t5nex, pci, t5_driver, t5_devclass, mod_event, 0); MODULE_VERSION(t5nex, 1); MODULE_DEPEND(t5nex, firmware, 1, 1, 1); +DRIVER_MODULE(t6nex, pci, t6_driver, t6_devclass, mod_event, 0); +MODULE_VERSION(t6nex, 1); +MODULE_DEPEND(t6nex, firmware, 1, 1, 1); +#ifdef DEV_NETMAP +MODULE_DEPEND(t6nex, netmap, 1, 1, 1); +#endif /* DEV_NETMAP */ + DRIVER_MODULE(cxgbe, t4nex, cxgbe_driver, cxgbe_devclass, 0, 0); MODULE_VERSION(cxgbe, 1); DRIVER_MODULE(cxl, t5nex, cxl_driver, cxl_devclass, 0, 0); MODULE_VERSION(cxl, 1); +DRIVER_MODULE(cc, t6nex, cc_driver, cc_devclass, 0, 0); +MODULE_VERSION(cc, 1); + DRIVER_MODULE(vcxgbe, cxgbe, vcxgbe_driver, vcxgbe_devclass, 0, 0); MODULE_VERSION(vcxgbe, 1); DRIVER_MODULE(vcxl, cxl, vcxl_driver, vcxl_devclass, 0, 0); MODULE_VERSION(vcxl, 1); + +DRIVER_MODULE(vcc, cc, vcc_driver, vcc_devclass, 0, 0); +MODULE_VERSION(vcc, 1); |