diff options
author | John Levon <john.levon@joyent.com> | 2020-05-26 13:57:13 +0000 |
---|---|---|
committer | John Levon <john.levon@joyent.com> | 2020-05-26 13:57:13 +0000 |
commit | 5b2acc0949194447bba6e45a0fa44d0b5f42f208 (patch) | |
tree | 7ea9eb87bc68fee386dd39035ce715e87a0e673c /usr/src/uts/common/io/cxgbe | |
parent | 8ca018083101bf1cb175869679bc123187fb1bab (diff) | |
parent | 2a1277d3064386cd5c4e372301007aa330bf1d5e (diff) | |
download | illumos-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.h | 17 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/common/t4_hw.c | 85 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/firmware/t4fw_interface.h | 20 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/shared/shared.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/shared/shared.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/t4nex/cudbg.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/t4nex/t4_ioctl.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/io/cxgbe/t4nex/t4_mac.c | 112 |
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) |