aboutsummaryrefslogtreecommitdiff
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.c187
1 files changed, 120 insertions, 67 deletions
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 22d2f504c257..5e02b47da8d9 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -57,9 +57,7 @@
#include <net/if_types.h>
#include <net/if_dl.h>
#include <net/if_vlan_var.h>
-#ifdef RSS
#include <net/rss_config.h>
-#endif
#include <netinet/in.h>
#include <netinet/ip.h>
#ifdef KERN_TLS
@@ -611,7 +609,7 @@ static int t4_switchcaps_allowed = FW_CAPS_CONFIG_SWITCH_INGRESS |
SYSCTL_INT(_hw_cxgbe, OID_AUTO, switchcaps_allowed, CTLFLAG_RDTUN,
&t4_switchcaps_allowed, 0, "Default switch capabilities");
-static int t4_nvmecaps_allowed = 0;
+static int t4_nvmecaps_allowed = -1;
SYSCTL_INT(_hw_cxgbe, OID_AUTO, nvmecaps_allowed, CTLFLAG_RDTUN,
&t4_nvmecaps_allowed, 0, "Default NVMe capabilities");
@@ -1327,6 +1325,8 @@ t4_attach(device_t dev)
sc->dev = dev;
sysctl_ctx_init(&sc->ctx);
TUNABLE_INT_FETCH("hw.cxgbe.dflags", &sc->debug_flags);
+ if (TUNABLE_INT_FETCH("hw.cxgbe.iflags", &sc->intr_flags) == 0)
+ sc->intr_flags = IHF_INTR_CLEAR_ON_INIT | IHF_CLR_ALL_UNIGNORED;
if ((pci_get_device(dev) & 0xff00) == 0x5400)
t5_attribute_workaround(dev);
@@ -2817,7 +2817,7 @@ cxgbe_probe(device_t dev)
#define T4_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \
IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \
IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWCSUM_IPV6 | IFCAP_HWSTATS | \
- IFCAP_HWRXTSTMP | IFCAP_MEXTPG)
+ IFCAP_HWRXTSTMP | IFCAP_MEXTPG | IFCAP_NV)
#define T4_CAP_ENABLE (T4_CAP)
static void
@@ -3065,7 +3065,7 @@ cxgbe_ioctl(if_t ifp, unsigned long cmd, caddr_t data)
struct port_info *pi = vi->pi;
struct adapter *sc = pi->adapter;
struct ifreq *ifr = (struct ifreq *)data;
- uint32_t mask;
+ uint32_t mask, mask2;
switch (cmd) {
case SIOCSIFMTU:
@@ -3124,12 +3124,24 @@ cxgbe_ioctl(if_t ifp, unsigned long cmd, caddr_t data)
end_synchronized_op(sc, 0);
break;
+ case SIOCGIFCAPNV:
+ break;
+ case SIOCSIFCAPNV:
case SIOCSIFCAP:
rc = begin_synchronized_op(sc, vi, SLEEP_OK | INTR_OK, "t4cap");
if (rc)
return (rc);
- mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
+ if (cmd == SIOCSIFCAPNV) {
+ const struct siocsifcapnv_driver_data *ifr_nv =
+ (struct siocsifcapnv_driver_data *)data;
+
+ mask = ifr_nv->reqcap ^ if_getcapenable(ifp);
+ mask2 = ifr_nv->reqcap2 ^ if_getcapenable2(ifp);
+ } else {
+ mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
+ mask2 = 0;
+ }
if (mask & IFCAP_TXCSUM) {
if_togglecapenable(ifp, IFCAP_TXCSUM);
if_togglehwassist(ifp, CSUM_TCP | CSUM_UDP | CSUM_IP);
@@ -3264,6 +3276,9 @@ cxgbe_ioctl(if_t ifp, unsigned long cmd, caddr_t data)
CSUM_INNER_IP_TSO);
}
+ MPASS(mask2 == 0);
+ (void)mask2;
+
#ifdef VLAN_CAPABILITIES
VLAN_CAPABILITIES(ifp);
#endif
@@ -3652,6 +3667,7 @@ port_mword(struct port_info *pi, uint32_t speed)
case FW_PORT_TYPE_SFP28:
case FW_PORT_TYPE_SFP56:
case FW_PORT_TYPE_QSFP56:
+ case FW_PORT_TYPE_QSFPDD:
/* Pluggable transceiver */
switch (pi->mod_type) {
case FW_PORT_MOD_TYPE_LR:
@@ -3671,6 +3687,8 @@ port_mword(struct port_info *pi, uint32_t speed)
return (IFM_100G_LR4);
case FW_PORT_CAP32_SPEED_200G:
return (IFM_200G_LR4);
+ case FW_PORT_CAP32_SPEED_400G:
+ return (IFM_400G_LR8);
}
break;
case FW_PORT_MOD_TYPE_SR:
@@ -3689,6 +3707,8 @@ port_mword(struct port_info *pi, uint32_t speed)
return (IFM_100G_SR4);
case FW_PORT_CAP32_SPEED_200G:
return (IFM_200G_SR4);
+ case FW_PORT_CAP32_SPEED_400G:
+ return (IFM_400G_SR8);
}
break;
case FW_PORT_MOD_TYPE_ER:
@@ -3712,6 +3732,8 @@ port_mword(struct port_info *pi, uint32_t speed)
return (IFM_100G_CR4);
case FW_PORT_CAP32_SPEED_200G:
return (IFM_200G_CR4_PAM4);
+ case FW_PORT_CAP32_SPEED_400G:
+ return (IFM_400G_CR8);
}
break;
case FW_PORT_MOD_TYPE_LRM:
@@ -3723,10 +3745,12 @@ port_mword(struct port_info *pi, uint32_t speed)
return (IFM_100G_DR);
if (speed == FW_PORT_CAP32_SPEED_200G)
return (IFM_200G_DR4);
+ if (speed == FW_PORT_CAP32_SPEED_400G)
+ return (IFM_400G_DR4);
break;
case FW_PORT_MOD_TYPE_NA:
MPASS(0); /* Not pluggable? */
- /* fall throough */
+ /* fall through */
case FW_PORT_MOD_TYPE_ERROR:
case FW_PORT_MOD_TYPE_UNKNOWN:
case FW_PORT_MOD_TYPE_NOTSUPPORTED:
@@ -3735,6 +3759,10 @@ port_mword(struct port_info *pi, uint32_t speed)
return (IFM_NONE);
}
break;
+ case M_FW_PORT_CMD_PTYPE: /* FW_PORT_TYPE_NONE for old firmware */
+ if (chip_id(pi->adapter) >= CHELSIO_T7)
+ return (IFM_UNKNOWN);
+ /* fall through */
case FW_PORT_TYPE_NONE:
return (IFM_NONE);
}
@@ -3930,8 +3958,6 @@ fatal_error_task(void *arg, int pending)
void
t4_fatal_err(struct adapter *sc, bool fw_error)
{
- const bool verbose = (sc->debug_flags & DF_VERBOSE_SLOWINTR) != 0;
-
stop_adapter(sc);
if (atomic_testandset_int(&sc->error_flags, ilog2(ADAP_FATAL_ERR)))
return;
@@ -3944,7 +3970,7 @@ t4_fatal_err(struct adapter *sc, bool fw_error)
* main INT_CAUSE registers here to make sure we haven't missed
* anything interesting.
*/
- t4_slow_intr_handler(sc, verbose);
+ t4_slow_intr_handler(sc, sc->intr_flags);
atomic_set_int(&sc->error_flags, ADAP_CIM_ERR);
}
t4_report_fw_error(sc);
@@ -5408,6 +5434,7 @@ apply_cfg_and_initialize(struct adapter *sc, char *cfg_file,
caps.toecaps = 0;
caps.rdmacaps = 0;
caps.iscsicaps = 0;
+ caps.nvmecaps = 0;
}
caps.op_to_write = htobe32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
@@ -5881,61 +5908,63 @@ get_params__post_init(struct adapter *sc)
* that will never be used.
*/
sc->iscsicaps = 0;
+ sc->nvmecaps = 0;
sc->rdmacaps = 0;
}
- if (sc->rdmacaps) {
+ if (sc->nvmecaps || sc->rdmacaps) {
param[0] = FW_PARAM_PFVF(STAG_START);
param[1] = FW_PARAM_PFVF(STAG_END);
- param[2] = FW_PARAM_PFVF(RQ_START);
- param[3] = FW_PARAM_PFVF(RQ_END);
- param[4] = FW_PARAM_PFVF(PBL_START);
- param[5] = FW_PARAM_PFVF(PBL_END);
- rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val);
+ param[2] = FW_PARAM_PFVF(PBL_START);
+ param[3] = FW_PARAM_PFVF(PBL_END);
+ rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 4, param, val);
if (rc != 0) {
device_printf(sc->dev,
- "failed to query RDMA parameters(1): %d.\n", rc);
+ "failed to query NVMe/RDMA parameters: %d.\n", rc);
return (rc);
}
sc->vres.stag.start = val[0];
sc->vres.stag.size = val[1] - val[0] + 1;
- sc->vres.rq.start = val[2];
- sc->vres.rq.size = val[3] - val[2] + 1;
- sc->vres.pbl.start = val[4];
- sc->vres.pbl.size = val[5] - val[4] + 1;
-
- param[0] = FW_PARAM_PFVF(SQRQ_START);
- param[1] = FW_PARAM_PFVF(SQRQ_END);
- param[2] = FW_PARAM_PFVF(CQ_START);
- param[3] = FW_PARAM_PFVF(CQ_END);
- param[4] = FW_PARAM_PFVF(OCQ_START);
- param[5] = FW_PARAM_PFVF(OCQ_END);
+ sc->vres.pbl.start = val[2];
+ sc->vres.pbl.size = val[3] - val[2] + 1;
+ }
+ if (sc->rdmacaps) {
+ param[0] = FW_PARAM_PFVF(RQ_START);
+ param[1] = FW_PARAM_PFVF(RQ_END);
+ param[2] = FW_PARAM_PFVF(SQRQ_START);
+ param[3] = FW_PARAM_PFVF(SQRQ_END);
+ param[4] = FW_PARAM_PFVF(CQ_START);
+ param[5] = FW_PARAM_PFVF(CQ_END);
rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val);
if (rc != 0) {
device_printf(sc->dev,
- "failed to query RDMA parameters(2): %d.\n", rc);
+ "failed to query RDMA parameters(1): %d.\n", rc);
return (rc);
}
- sc->vres.qp.start = val[0];
- sc->vres.qp.size = val[1] - val[0] + 1;
- sc->vres.cq.start = val[2];
- sc->vres.cq.size = val[3] - val[2] + 1;
- sc->vres.ocq.start = val[4];
- sc->vres.ocq.size = val[5] - val[4] + 1;
-
- param[0] = FW_PARAM_PFVF(SRQ_START);
- param[1] = FW_PARAM_PFVF(SRQ_END);
- param[2] = FW_PARAM_DEV(MAXORDIRD_QP);
- param[3] = FW_PARAM_DEV(MAXIRD_ADAPTER);
- rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 4, param, val);
+ sc->vres.rq.start = val[0];
+ sc->vres.rq.size = val[1] - val[0] + 1;
+ sc->vres.qp.start = val[2];
+ sc->vres.qp.size = val[3] - val[2] + 1;
+ sc->vres.cq.start = val[4];
+ sc->vres.cq.size = val[5] - val[4] + 1;
+
+ param[0] = FW_PARAM_PFVF(OCQ_START);
+ param[1] = FW_PARAM_PFVF(OCQ_END);
+ param[2] = FW_PARAM_PFVF(SRQ_START);
+ param[3] = FW_PARAM_PFVF(SRQ_END);
+ param[4] = FW_PARAM_DEV(MAXORDIRD_QP);
+ param[5] = FW_PARAM_DEV(MAXIRD_ADAPTER);
+ rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val);
if (rc != 0) {
device_printf(sc->dev,
- "failed to query RDMA parameters(3): %d.\n", rc);
+ "failed to query RDMA parameters(2): %d.\n", rc);
return (rc);
}
- sc->vres.srq.start = val[0];
- sc->vres.srq.size = val[1] - val[0] + 1;
- sc->params.max_ordird_qp = val[2];
- sc->params.max_ird_adapter = val[3];
+ sc->vres.ocq.start = val[0];
+ sc->vres.ocq.size = val[1] - val[0] + 1;
+ sc->vres.srq.start = val[2];
+ sc->vres.srq.size = val[3] - val[2] + 1;
+ sc->params.max_ordird_qp = val[4];
+ sc->params.max_ird_adapter = val[5];
}
if (sc->iscsicaps) {
param[0] = FW_PARAM_PFVF(ISCSI_START);
@@ -7019,7 +7048,6 @@ t4_setup_intr_handlers(struct adapter *sc)
static void
write_global_rss_key(struct adapter *sc)
{
-#ifdef RSS
int i;
uint32_t raw_rss_key[RSS_KEYSIZE / sizeof(uint32_t)];
uint32_t rss_key[RSS_KEYSIZE / sizeof(uint32_t)];
@@ -7031,7 +7059,6 @@ write_global_rss_key(struct adapter *sc)
rss_key[i] = htobe32(raw_rss_key[nitems(rss_key) - 1 - i]);
}
t4_write_rss_key(sc, &rss_key[0], -1, 1);
-#endif
}
/*
@@ -7111,7 +7138,6 @@ adapter_full_uninit(struct adapter *sc)
sc->flags &= ~FULL_INIT_DONE;
}
-#ifdef RSS
#define SUPPORTED_RSS_HASHTYPES (RSS_HASHTYPE_RSS_IPV4 | \
RSS_HASHTYPE_RSS_TCP_IPV4 | RSS_HASHTYPE_RSS_IPV6 | \
RSS_HASHTYPE_RSS_TCP_IPV6 | RSS_HASHTYPE_RSS_UDP_IPV4 | \
@@ -7174,7 +7200,6 @@ hashen_to_hashconfig(int hashen)
return (hashconfig);
}
-#endif
/*
* Idempotent.
@@ -7184,11 +7209,10 @@ vi_full_init(struct vi_info *vi)
{
struct adapter *sc = vi->adapter;
struct sge_rxq *rxq;
- int rc, i, j;
+ int rc, i, j, extra;
+ int hashconfig = rss_gethashconfig();
#ifdef RSS
int nbuckets = rss_getnumbuckets();
- int hashconfig = rss_gethashconfig();
- int extra;
#endif
ASSERT_SYNCHRONIZED_OP(sc);
@@ -7243,7 +7267,6 @@ vi_full_init(struct vi_info *vi)
return (rc);
}
-#ifdef RSS
vi->hashen = hashconfig_to_hashen(hashconfig);
/*
@@ -7279,12 +7302,7 @@ vi_full_init(struct vi_info *vi)
CH_ALERT(vi, "UDP/IPv4 4-tuple hashing forced on.\n");
if (extra & RSS_HASHTYPE_RSS_UDP_IPV6)
CH_ALERT(vi, "UDP/IPv6 4-tuple hashing forced on.\n");
-#else
- vi->hashen = F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
- F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN |
- 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, vi->hashen, vi->rss[0],
0, 0);
if (rc != 0) {
@@ -7892,6 +7910,9 @@ t4_sysctls(struct adapter *sc)
SYSCTL_ADD_INT(ctx, children, OID_AUTO, "dflags", CTLFLAG_RW,
&sc->debug_flags, 0, "flags to enable runtime debugging");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO, "iflags", CTLFLAG_RW,
+ &sc->intr_flags, 0, "flags for the slow interrupt handler");
+
SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "tp_version",
CTLFLAG_RD, sc->tp_version, 0, "TP microcode version");
@@ -8988,7 +9009,7 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS)
struct adapter *sc = pi->adapter;
struct link_config *lc = &pi->link_cfg;
int rc;
- int8_t old;
+ int8_t old = lc->requested_fec;
if (req->newptr == NULL) {
struct sbuf *sb;
@@ -8997,16 +9018,15 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS)
if (sb == NULL)
return (ENOMEM);
- sbuf_printf(sb, "%b", lc->requested_fec, t4_fec_bits);
+ sbuf_printf(sb, "%b", old, t4_fec_bits);
rc = sbuf_finish(sb);
sbuf_delete(sb);
} else {
char s[8];
int n;
- snprintf(s, sizeof(s), "%d",
- lc->requested_fec == FEC_AUTO ? -1 :
- lc->requested_fec & (M_FW_PORT_CAP32_FEC | FEC_MODULE));
+ snprintf(s, sizeof(s), "%d", old == FEC_AUTO ? -1 :
+ old & (M_FW_PORT_CAP32_FEC | FEC_MODULE));
rc = sysctl_handle_string(oidp, s, sizeof(s), req);
if (rc != 0)
@@ -9023,7 +9043,10 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS)
if (rc)
return (rc);
PORT_LOCK(pi);
- old = lc->requested_fec;
+ if (lc->requested_fec != old) {
+ rc = EBUSY;
+ goto done;
+ }
if (n == FEC_AUTO)
lc->requested_fec = FEC_AUTO;
else if (n == 0 || n == FEC_NONE)
@@ -12984,6 +13007,9 @@ clear_stats(struct adapter *sc, u_int port_id)
counter_u64_zero(ofld_txq->tx_iscsi_pdus);
counter_u64_zero(ofld_txq->tx_iscsi_octets);
counter_u64_zero(ofld_txq->tx_iscsi_iso_wrs);
+ counter_u64_zero(ofld_txq->tx_nvme_pdus);
+ counter_u64_zero(ofld_txq->tx_nvme_octets);
+ counter_u64_zero(ofld_txq->tx_nvme_iso_wrs);
counter_u64_zero(ofld_txq->tx_aio_jobs);
counter_u64_zero(ofld_txq->tx_aio_octets);
counter_u64_zero(ofld_txq->tx_toe_tls_records);
@@ -13003,6 +13029,22 @@ clear_stats(struct adapter *sc, u_int port_id)
ofld_rxq->rx_iscsi_ddp_octets = 0;
ofld_rxq->rx_iscsi_fl_pdus = 0;
ofld_rxq->rx_iscsi_fl_octets = 0;
+ counter_u64_zero(
+ ofld_rxq->rx_nvme_ddp_setup_ok);
+ counter_u64_zero(
+ ofld_rxq->rx_nvme_ddp_setup_no_stag);
+ counter_u64_zero(
+ ofld_rxq->rx_nvme_ddp_setup_error);
+ counter_u64_zero(ofld_rxq->rx_nvme_ddp_pdus);
+ counter_u64_zero(ofld_rxq->rx_nvme_ddp_octets);
+ counter_u64_zero(ofld_rxq->rx_nvme_fl_pdus);
+ counter_u64_zero(ofld_rxq->rx_nvme_fl_octets);
+ counter_u64_zero(
+ ofld_rxq->rx_nvme_invalid_headers);
+ counter_u64_zero(
+ ofld_rxq->rx_nvme_header_digest_errors);
+ counter_u64_zero(
+ ofld_rxq->rx_nvme_data_digest_errors);
ofld_rxq->rx_aio_ddp_jobs = 0;
ofld_rxq->rx_aio_ddp_octets = 0;
ofld_rxq->rx_toe_tls_records = 0;
@@ -13409,11 +13451,16 @@ toe_capability(struct vi_info *vi, bool enable)
("%s: TOM activated but flag not set", __func__));
}
- /* Activate iWARP and iSCSI too, if the modules are loaded. */
+ /*
+ * Activate iWARP, iSCSI, and NVMe too, if the modules
+ * are loaded.
+ */
if (!uld_active(sc, ULD_IWARP))
(void) t4_activate_uld(sc, ULD_IWARP);
if (!uld_active(sc, ULD_ISCSI))
(void) t4_activate_uld(sc, ULD_ISCSI);
+ if (!uld_active(sc, ULD_NVME))
+ (void) t4_activate_uld(sc, ULD_NVME);
if (pi->uld_vis++ == 0)
setbit(&sc->offload_map, pi->port_id);
@@ -13694,6 +13741,9 @@ tweak_tunables(void)
FW_CAPS_CONFIG_ISCSI_T10DIF;
}
+ if (t4_nvmecaps_allowed == -1)
+ t4_nvmecaps_allowed = FW_CAPS_CONFIG_NVME_TCP;
+
if (t4_tmr_idx_ofld < 0 || t4_tmr_idx_ofld >= SGE_NTIMERS)
t4_tmr_idx_ofld = TMR_IDX_OFLD;
@@ -13705,6 +13755,9 @@ tweak_tunables(void)
if (t4_iscsicaps_allowed == -1)
t4_iscsicaps_allowed = 0;
+
+ if (t4_nvmecaps_allowed == -1)
+ t4_nvmecaps_allowed = 0;
#endif
#ifdef DEV_NETMAP