diff options
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); |