summaryrefslogtreecommitdiffstats
path: root/sys/dev/cxgbe/t4_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/cxgbe/t4_main.c')
-rw-r--r--sys/dev/cxgbe/t4_main.c284
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);
OpenPOWER on IntegriCloud