summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/cxgbe
diff options
context:
space:
mode:
authorJohn Levon <john.levon@joyent.com>2020-05-26 13:57:13 +0000
committerJohn Levon <john.levon@joyent.com>2020-05-26 13:57:13 +0000
commit5b2acc0949194447bba6e45a0fa44d0b5f42f208 (patch)
tree7ea9eb87bc68fee386dd39035ce715e87a0e673c /usr/src/uts/common/io/cxgbe
parent8ca018083101bf1cb175869679bc123187fb1bab (diff)
parent2a1277d3064386cd5c4e372301007aa330bf1d5e (diff)
downloadillumos-joyent-gcc9.tar.gz
mergegcc9
Diffstat (limited to 'usr/src/uts/common/io/cxgbe')
-rw-r--r--usr/src/uts/common/io/cxgbe/common/common.h17
-rw-r--r--usr/src/uts/common/io/cxgbe/common/t4_hw.c85
-rw-r--r--usr/src/uts/common/io/cxgbe/firmware/t4fw_interface.h20
-rw-r--r--usr/src/uts/common/io/cxgbe/shared/shared.c6
-rw-r--r--usr/src/uts/common/io/cxgbe/shared/shared.h2
-rw-r--r--usr/src/uts/common/io/cxgbe/t4nex/cudbg.h2
-rw-r--r--usr/src/uts/common/io/cxgbe/t4nex/t4_ioctl.c2
-rw-r--r--usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c112
8 files changed, 218 insertions, 28 deletions
diff --git a/usr/src/uts/common/io/cxgbe/common/common.h b/usr/src/uts/common/io/cxgbe/common/common.h
index c7de2c4ebf..b8d77ebda3 100644
--- a/usr/src/uts/common/io/cxgbe/common/common.h
+++ b/usr/src/uts/common/io/cxgbe/common/common.h
@@ -20,6 +20,10 @@
* release for licensing terms and conditions.
*/
+/*
+ * Copyright 2020 RackTop Systems, Inc.
+ */
+
#ifndef __CHELSIO_COMMON_H
#define __CHELSIO_COMMON_H
@@ -103,9 +107,16 @@ enum {
typedef unsigned char cc_pause_t;
enum {
- FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */
- FEC_RS = 1 << 1, /* Reed-Solomon */
- FEC_BASER_RS = 1 << 2, /* BaseR/Reed-Solomon */
+ FEC_RS = 1 << 0, /* Reed-Solomon */
+ FEC_BASER_RS = 1 << 1, /* Base-R, aka Firecode */
+ FEC_NONE = 1 << 2, /* no FEC */
+
+ /*
+ * Pseudo FECs that translate to real FECs. The firmware knows nothing
+ * about these and they start at M_FW_PORT_CAP32_FEC + 1. AUTO should
+ * be set all by itself.
+ */
+ FEC_AUTO = 1 << 5,
};
typedef unsigned char cc_fec_t;
diff --git a/usr/src/uts/common/io/cxgbe/common/t4_hw.c b/usr/src/uts/common/io/cxgbe/common/t4_hw.c
index ae88f36f15..4bb48f1b3a 100644
--- a/usr/src/uts/common/io/cxgbe/common/t4_hw.c
+++ b/usr/src/uts/common/io/cxgbe/common/t4_hw.c
@@ -20,6 +20,10 @@
* release for licensing terms and conditions.
*/
+/*
+ * Copyright 2020 RackTop Systems, Inc.
+ */
+
#include "common.h"
#include "t4_regs.h"
#include "t4_regs_values.h"
@@ -4645,20 +4649,57 @@ static inline cc_fec_t fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
cc_fec |= FEC_BASER_RS;
- return cc_fec;
+ if (cc_fec == 0)
+ cc_fec = FEC_NONE;
+
+ return (cc_fec);
}
/* Translate Common Code Forward Error Correction specification to Firmware */
-static inline fw_port_cap32_t cc_to_fwcap_fec(cc_fec_t cc_fec)
+static inline boolean_t
+cc_to_fwcap_fec(fw_port_cap32_t *fw_fecp, cc_fec_t cc_fec,
+ struct link_config *lc)
{
fw_port_cap32_t fw_fec = 0;
- if (cc_fec & FEC_RS)
+ if ((cc_fec & FEC_AUTO) != 0) {
+ if ((lc->pcaps & FW_PORT_CAP32_SPEED_100G) == 0)
+ fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
+
+ if ((lc->pcaps & FW_PORT_CAP32_FORCE_FEC) != 0)
+ fw_fec |= FW_PORT_CAP32_FEC_NO_FEC;
+
+ fw_fec |= FW_PORT_CAP32_FEC_RS;
+
+ *fw_fecp = fw_fec;
+ return (B_TRUE);
+ }
+
+ if ((cc_fec & FEC_RS) != 0)
fw_fec |= FW_PORT_CAP32_FEC_RS;
- if (cc_fec & FEC_BASER_RS)
+
+ if ((cc_fec & FEC_BASER_RS) != 0 &&
+ (lc->pcaps & FW_PORT_CAP32_SPEED_100G) == 0)
fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
- return fw_fec;
+ if ((cc_fec & FEC_NONE) != 0) {
+ if ((lc->pcaps & FW_PORT_CAP32_FORCE_FEC) != 0) {
+ fw_fec |= FW_PORT_CAP32_FORCE_FEC;
+ fw_fec |= FW_PORT_CAP32_FEC_NO_FEC;
+ }
+
+ *fw_fecp = fw_fec;
+ return (B_TRUE);
+ }
+
+ if (fw_fec == 0)
+ return (B_FALSE);
+
+ if ((lc->pcaps & FW_PORT_CAP32_FORCE_FEC) != 0)
+ fw_fec |= FW_PORT_CAP32_FORCE_FEC;
+
+ *fw_fecp = fw_fec;
+ return (B_TRUE);
}
/**
@@ -4692,11 +4733,18 @@ fw_port_cap32_t t4_link_acaps(struct adapter *adapter, unsigned int port,
* the Transceiver Module EPROM FEC parameters. Otherwise we
* use whatever is in the current Requested FEC settings.
*/
- if (lc->requested_fec & FEC_AUTO)
- cc_fec = fwcap_to_cc_fec(lc->def_acaps);
- else
- cc_fec = lc->requested_fec;
- fw_fec = cc_to_fwcap_fec(cc_fec);
+ if (fec_supported(lc->pcaps)) {
+ if (lc->requested_fec & FEC_AUTO)
+ cc_fec = fwcap_to_cc_fec(lc->def_acaps);
+ else
+ cc_fec = lc->requested_fec;
+
+ if (!cc_to_fwcap_fec(&fw_fec, cc_fec, lc))
+ return (0);
+ } else {
+ fw_fec = 0;
+ cc_fec = FEC_NONE;
+ }
/* Figure out what our Requested Port Capabilities are going to be.
* Note parallel structure in t4_handle_get_port_info() and
@@ -9641,12 +9689,17 @@ static void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
lc->speed = 0;
lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
- /*
- * For Forward Error Control, we default to whatever the Firmware
- * tells us the Link is currently advertising.
- */
- lc->requested_fec = FEC_AUTO;
- lc->fec = fwcap_to_cc_fec(lc->def_acaps);
+ if (fec_supported(pcaps)) {
+ /*
+ * For Forward Error Control, we default to whatever the Firmware
+ * tells us the Link is currently advertising.
+ */
+ lc->requested_fec = FEC_AUTO;
+ lc->fec = fwcap_to_cc_fec(lc->def_acaps);
+ } else {
+ lc->requested_fec = FEC_NONE;
+ lc->fec = FEC_NONE;
+ }
/* If the Port is capable of Auto-Negtotiation, initialize it as
* "enabled" and copy over all of the Physical Port Capabilities
diff --git a/usr/src/uts/common/io/cxgbe/firmware/t4fw_interface.h b/usr/src/uts/common/io/cxgbe/firmware/t4fw_interface.h
index d705c73891..b998e85bae 100644
--- a/usr/src/uts/common/io/cxgbe/firmware/t4fw_interface.h
+++ b/usr/src/uts/common/io/cxgbe/firmware/t4fw_interface.h
@@ -11,6 +11,10 @@
* release for licensing terms and conditions.
*/
+/*
+ * Copyright 2020 RackTop Systems, Inc.
+ */
+
#ifndef _T4FW_INTERFACE_H_
#define _T4FW_INTERFACE_H_
@@ -7204,11 +7208,12 @@ enum fw_port_mdi {
#define FW_PORT_CAP32_MDISTRAIGHT 0x00400000UL
#define FW_PORT_CAP32_FEC_RS 0x00800000UL
#define FW_PORT_CAP32_FEC_BASER_RS 0x01000000UL
-#define FW_PORT_CAP32_FEC_RESERVED1 0x02000000UL
+#define FW_PORT_CAP32_FEC_NO_FEC 0x02000000UL
#define FW_PORT_CAP32_FEC_RESERVED2 0x04000000UL
#define FW_PORT_CAP32_FEC_RESERVED3 0x08000000UL
#define FW_PORT_CAP32_FORCE_PAUSE 0x10000000UL
-#define FW_PORT_CAP32_RESERVED2 0xe0000000UL
+#define FW_PORT_CAP32_FORCE_FEC 0x20000000UL
+#define FW_PORT_CAP32_RESERVED2 0xc0000000UL
#define S_FW_PORT_CAP32_SPEED 0
#define M_FW_PORT_CAP32_SPEED 0xfff
@@ -7254,7 +7259,7 @@ enum fw_port_mdi32 {
(((x) >> S_FW_PORT_CAP32_MDI) & M_FW_PORT_CAP32_MDI)
#define S_FW_PORT_CAP32_FEC 23
-#define M_FW_PORT_CAP32_FEC 0x1f
+#define M_FW_PORT_CAP32_FEC 0x5f
#define V_FW_PORT_CAP32_FEC(x) ((x) << S_FW_PORT_CAP32_FEC)
#define G_FW_PORT_CAP32_FEC(x) \
(((x) >> S_FW_PORT_CAP32_FEC) & M_FW_PORT_CAP32_FEC)
@@ -7269,6 +7274,15 @@ enum fw_port_mdi32 {
#define CAP32_FC(__cap32) \
(V_FW_PORT_CAP32_FC(M_FW_PORT_CAP32_FC) & __cap32)
+#ifdef _KERNEL
+static inline boolean_t
+fec_supported(uint32_t caps)
+{
+ return ((caps & (FW_PORT_CAP32_SPEED_25G | FW_PORT_CAP32_SPEED_50G |
+ FW_PORT_CAP32_SPEED_100G)) != 0);
+}
+#endif
+
enum fw_port_action {
FW_PORT_ACTION_L1_CFG = 0x0001,
FW_PORT_ACTION_L2_CFG = 0x0002,
diff --git a/usr/src/uts/common/io/cxgbe/shared/shared.c b/usr/src/uts/common/io/cxgbe/shared/shared.c
index 07dd78f189..e86272134a 100644
--- a/usr/src/uts/common/io/cxgbe/shared/shared.c
+++ b/usr/src/uts/common/io/cxgbe/shared/shared.c
@@ -32,17 +32,19 @@
static int rxbuf_ctor(void *, void *, int);
static void rxbuf_dtor(void *, void *);
-void
+int
cxgb_printf(dev_info_t *dip, int level, char *f, ...)
{
va_list list;
char fmt[128];
+ int rv;
- (void) snprintf(fmt, sizeof (fmt), "%s%d: %s", ddi_driver_name(dip),
+ rv = snprintf(fmt, sizeof (fmt), "%s%d: %s", ddi_driver_name(dip),
ddi_get_instance(dip), f);
va_start(list, f);
vcmn_err(level, fmt, list);
va_end(list);
+ return (rv);
}
kmem_cache_t *
diff --git a/usr/src/uts/common/io/cxgbe/shared/shared.h b/usr/src/uts/common/io/cxgbe/shared/shared.h
index 5838416838..d3171c224b 100644
--- a/usr/src/uts/common/io/cxgbe/shared/shared.h
+++ b/usr/src/uts/common/io/cxgbe/shared/shared.h
@@ -66,7 +66,7 @@ struct rxbuf_cache_params {
size_t buf_size;
};
-void cxgb_printf(dev_info_t *dip, int level, char *f, ...);
+int cxgb_printf(dev_info_t *dip, int level, char *f, ...);
kmem_cache_t *rxbuf_cache_create(struct rxbuf_cache_params *p);
void rxbuf_cache_destroy(kmem_cache_t *cache);
struct rxbuf *rxbuf_alloc(kmem_cache_t *cache, int kmflags, uint_t ref_cnt);
diff --git a/usr/src/uts/common/io/cxgbe/t4nex/cudbg.h b/usr/src/uts/common/io/cxgbe/t4nex/cudbg.h
index cb21451e5c..e86de21085 100644
--- a/usr/src/uts/common/io/cxgbe/t4nex/cudbg.h
+++ b/usr/src/uts/common/io/cxgbe/t4nex/cudbg.h
@@ -318,7 +318,7 @@ static struct el ATTRIBUTE_UNUSED entity_list[] = {
};
#ifdef _KERNEL
-typedef int (*cudbg_print_cb) (dev_info_t *dip, ...);
+typedef int (*cudbg_print_cb) (dev_info_t *dip, int, char *, ...);
#else
typedef int (*cudbg_print_cb) (char *, ...);
#endif
diff --git a/usr/src/uts/common/io/cxgbe/t4nex/t4_ioctl.c b/usr/src/uts/common/io/cxgbe/t4nex/t4_ioctl.c
index ee28c8a2ba..85d79e6201 100644
--- a/usr/src/uts/common/io/cxgbe/t4nex/t4_ioctl.c
+++ b/usr/src/uts/common/io/cxgbe/t4nex/t4_ioctl.c
@@ -1706,7 +1706,7 @@ get_cudbg(struct adapter *sc, void *data, int flags)
cudbg = cudbg_get_init(handle);
cudbg->adap = sc;
- cudbg->print = (cudbg_print_cb)(uintptr_t)cxgb_printf;
+ cudbg->print = cxgb_printf;
memcpy(cudbg->dbg_bitmap, dump.bitmap, sizeof(cudbg->dbg_bitmap));
diff --git a/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c b/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c
index 59c0ddde8d..9b4ffd8325 100644
--- a/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c
+++ b/usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c
@@ -20,6 +20,10 @@
* release for licensing terms and conditions.
*/
+/*
+ * Copyright 2020 RackTop Systems, Inc.
+ */
+
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/dlpi.h>
@@ -930,6 +934,62 @@ t4_mc_getcapab(void *arg, mac_capab_t cap, void *data)
return (status);
}
+static link_fec_t
+fec_to_link_fec(cc_fec_t cc_fec)
+{
+ link_fec_t link_fec = 0;
+
+ if ((cc_fec & (FEC_RS | FEC_BASER_RS)) == (FEC_RS | FEC_BASER_RS))
+ return (LINK_FEC_AUTO);
+
+ if ((cc_fec & FEC_NONE) != 0)
+ link_fec |= LINK_FEC_NONE;
+
+ if ((cc_fec & FEC_AUTO) != 0)
+ link_fec |= LINK_FEC_AUTO;
+
+ if ((cc_fec & FEC_RS) != 0)
+ link_fec |= LINK_FEC_RS;
+
+ if ((cc_fec & FEC_BASER_RS) != 0)
+ link_fec |= LINK_FEC_BASE_R;
+
+ return (link_fec);
+}
+
+static int
+link_fec_to_fec(int v)
+{
+ int fec = 0;
+
+ if ((v & LINK_FEC_AUTO) != 0) {
+ fec = FEC_AUTO;
+ v &= ~LINK_FEC_AUTO;
+ } else {
+ if ((v & LINK_FEC_NONE) != 0) {
+ fec = FEC_NONE;
+ v &= ~LINK_FEC_NONE;
+ }
+
+ if ((v & LINK_FEC_RS) != 0) {
+ fec |= FEC_RS;
+ v &= ~LINK_FEC_RS;
+ }
+
+ if ((v & LINK_FEC_BASE_R) != 0) {
+ fec |= FEC_BASER_RS;
+ v &= ~LINK_FEC_BASE_R;
+ }
+ }
+
+ if (v != 0)
+ return (-1);
+
+ ASSERT3S(fec, !=, 0);
+
+ return (fec);
+}
+
/* ARGSUSED */
static int
t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
@@ -941,7 +1001,9 @@ t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
uint8_t v8 = *(uint8_t *)val;
uint32_t v32 = *(uint32_t *)val;
int old, new = 0, relink = 0, rx_mode = 0, rc = 0;
+ boolean_t down_link = B_TRUE;
link_flowctrl_t fc;
+ link_fec_t fec;
/*
* Save a copy of link_config. This can be used to restore link_config
@@ -1009,6 +1071,30 @@ t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
}
break;
+ case MAC_PROP_EN_FEC_CAP:
+ if (!fec_supported(lc->pcaps)) {
+ rc = ENOTSUP;
+ break;
+ }
+
+ fec = *(link_fec_t *)val;
+ new = link_fec_to_fec(fec);
+ if (new < 0) {
+ rc = EINVAL;
+ } else if (new != lc->requested_fec) {
+ lc->requested_fec = new;
+ relink = 1;
+ /*
+ * For fec, do not preemptively force the link
+ * down. If changing fec causes the link state
+ * to transition, then appropriate asynchronous
+ * events are generated which correctly reflect
+ * the link state.
+ */
+ down_link = B_FALSE;
+ }
+ break;
+
case MAC_PROP_EN_10GFDX_CAP:
if (lc->pcaps & FW_PORT_CAP32_ANEG && is_10G_port(pi)) {
old = lc->acaps & FW_PORT_CAP32_SPEED_10G;
@@ -1062,7 +1148,8 @@ t4_mc_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
if (isset(&sc->open_device_map, pi->port_id) != 0) {
if (relink != 0) {
- t4_os_link_changed(pi->adapter, pi->port_id, 0);
+ if (down_link)
+ t4_os_link_changed(pi->adapter, pi->port_id, 0);
rc = begin_synchronized_op(pi, 1, 1);
if (rc != 0)
return (rc);
@@ -1143,6 +1230,20 @@ t4_mc_getprop(void *arg, const char *name, mac_prop_id_t id, uint_t size,
*(link_flowctrl_t *)val = LINK_FLOWCTRL_NONE;
break;
+ case MAC_PROP_ADV_FEC_CAP:
+ if (!fec_supported(lc->pcaps))
+ return (ENOTSUP);
+
+ *(link_fec_t *)val = fec_to_link_fec(lc->fec);
+ break;
+
+ case MAC_PROP_EN_FEC_CAP:
+ if (!fec_supported(lc->pcaps))
+ return (ENOTSUP);
+
+ *(link_fec_t *)val = fec_to_link_fec(lc->requested_fec);
+ break;
+
case MAC_PROP_ADV_100GFDX_CAP:
case MAC_PROP_EN_100GFDX_CAP:
*u = !!(lc->acaps & FW_PORT_CAP32_SPEED_100G);
@@ -1212,6 +1313,15 @@ t4_mc_propinfo(void *arg, const char *name, mac_prop_id_t id,
mac_prop_info_set_default_link_flowctrl(ph, LINK_FLOWCTRL_BI);
break;
+ case MAC_PROP_EN_FEC_CAP:
+ mac_prop_info_set_default_fec(ph, LINK_FEC_AUTO);
+ break;
+
+ case MAC_PROP_ADV_FEC_CAP:
+ mac_prop_info_set_perm(ph, MAC_PROP_PERM_READ);
+ mac_prop_info_set_default_fec(ph, LINK_FEC_AUTO);
+ break;
+
case MAC_PROP_EN_10GFDX_CAP:
if (lc->pcaps & FW_PORT_CAP32_ANEG &&
lc->pcaps & FW_PORT_CAP32_SPEED_10G)