From owner-svn-src-stable@freebsd.org Wed Jan 4 06:54:07 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A9E38C9E25A; Wed, 4 Jan 2017 06:54:07 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 784721BCE; Wed, 4 Jan 2017 06:54:07 +0000 (UTC) (envelope-from np@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v046s6FV042133; Wed, 4 Jan 2017 06:54:06 GMT (envelope-from np@FreeBSD.org) Received: (from np@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v046s5a1042124; Wed, 4 Jan 2017 06:54:05 GMT (envelope-from np@FreeBSD.org) Message-Id: <201701040654.v046s5a1042124@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: np set sender to np@FreeBSD.org using -f From: Navdeep Parhar Date: Wed, 4 Jan 2017 06:54:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r311260 - in stable/11: share/man/man4 sys/dev/cxgbe sys/dev/cxgbe/common X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Jan 2017 06:54:07 -0000 Author: np Date: Wed Jan 4 06:54:05 2017 New Revision: 311260 URL: https://svnweb.freebsd.org/changeset/base/311260 Log: MFC r309666, r310033, r310049, r310100, r310152, and r310807. r309666: cxgbe(4): unsigned short isn't large enough to store link speed (which is in Mbps) for 100Gbps links. r310033: cxgbe(4): Retire t4_bus_space_read_8 and t4_bus_space_write_8. r310049: cxgbe(4): Fix the tid range shown for T6 cards in misc.tids. r310100: cxgbe(4): Deal with compressed error vectors. r310152: cxgbe(4): Fix typo in an unused macro. r310807: cxgbe(4): Updates to link configuration. - Update struct link_settings and associated shared code. - Add tunables to control FEC and autonegotiation. All ports inherit these values as their initial settings. hw.cxgbe.fec hw.cxgbe.autoneg - Add per-port sysctls to control FEC and autonegotiation. These can be modified at any time. dev...fec dev...autoneg Modified: stable/11/share/man/man4/cxgbe.4 stable/11/sys/dev/cxgbe/adapter.h stable/11/sys/dev/cxgbe/common/common.h stable/11/sys/dev/cxgbe/common/t4_hw.c stable/11/sys/dev/cxgbe/common/t4_msg.h stable/11/sys/dev/cxgbe/t4_main.c stable/11/sys/dev/cxgbe/t4_sge.c stable/11/sys/dev/cxgbe/t4_vf.c Directory Properties: stable/11/ (props changed) Modified: stable/11/share/man/man4/cxgbe.4 ============================================================================== --- stable/11/share/man/man4/cxgbe.4 Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/share/man/man4/cxgbe.4 Wed Jan 4 06:54:05 2017 (r311260) @@ -289,6 +289,24 @@ The default is 3 (both rx_pause and tx_p This tunable establishes the default PAUSE settings for all ports. Settings can be displayed and controlled on a per-port basis via the dev..X.pause_settings sysctl. +.It Va hw.cxgbe.fec +FEC (Forward Error Correction) settings. +0 diables FEC. +Bit 0 enables RS FEC, bit 1 enables BASE-R RS, bit 3 is reserved. +The default is -1 which lets the driver pick a value. +This tunable establishes the default FEC settings for all ports. +Settings can be displayed and controlled on a per-port basis via the +dev..X.fec sysctl. +.It Va hw.cxgbe.autoneg +Link autonegotiation settings. +This tunable establishes the default autonegotiation settings for all ports. +Settings can be displayed and controlled on a per-port basis via the +dev..X.autoneg sysctl. +0 disables autonegotiation. +1 enables autonegotiation. +The default is -1 which lets the driver pick a value. +dev..X.autoneg is -1 for port and module combinations that do not support +autonegotiation. .It Va hw.cxgbe.buffer_packing Allow the hardware to deliver multiple frames in the same receive buffer opportunistically. Modified: stable/11/sys/dev/cxgbe/adapter.h ============================================================================== --- stable/11/sys/dev/cxgbe/adapter.h Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/sys/dev/cxgbe/adapter.h Wed Jan 4 06:54:05 2017 (r311260) @@ -84,45 +84,6 @@ prefetch(void *x) #define SBUF_DRAIN 1 #endif -#ifdef __amd64__ -/* XXX: need systemwide bus_space_read_8/bus_space_write_8 */ -static __inline uint64_t -t4_bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - KASSERT(tag == X86_BUS_SPACE_MEM, - ("%s: can only handle mem space", __func__)); - - return (*(volatile uint64_t *)(handle + offset)); -} - -static __inline void -t4_bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, uint64_t value) -{ - KASSERT(tag == X86_BUS_SPACE_MEM, - ("%s: can only handle mem space", __func__)); - - *(volatile uint64_t *)(bsh + offset) = value; -} -#else -static __inline uint64_t -t4_bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - return (uint64_t)bus_space_read_4(tag, handle, offset) + - ((uint64_t)bus_space_read_4(tag, handle, offset + 4) << 32); -} - -static __inline void -t4_bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t bsh, - bus_size_t offset, uint64_t value) -{ - bus_space_write_4(tag, bsh, offset, value); - bus_space_write_4(tag, bsh, offset + 4, value >> 32); -} -#endif - struct adapter; typedef struct adapter adapter_t; @@ -304,7 +265,6 @@ struct port_info { uint8_t tx_chan; uint8_t rx_chan_map; /* rx MPS channel bitmap */ - int linkdnrc; struct link_config link_cfg; struct timeval last_refreshed; @@ -977,14 +937,25 @@ static inline uint64_t t4_read_reg64(struct adapter *sc, uint32_t reg) { - return t4_bus_space_read_8(sc->bt, sc->bh, reg); +#ifdef __LP64__ + return bus_space_read_8(sc->bt, sc->bh, reg); +#else + return (uint64_t)bus_space_read_4(sc->bt, sc->bh, reg) + + ((uint64_t)bus_space_read_4(sc->bt, sc->bh, reg + 4) << 32); + +#endif } static inline void t4_write_reg64(struct adapter *sc, uint32_t reg, uint64_t val) { - t4_bus_space_write_8(sc->bt, sc->bh, reg, val); +#ifdef __LP64__ + bus_space_write_8(sc->bt, sc->bh, reg, val); +#else + bus_space_write_4(sc->bt, sc->bh, reg, val); + bus_space_write_4(sc->bt, sc->bh, reg + 4, val>> 32); +#endif } static inline void @@ -1126,7 +1097,7 @@ int t4_os_find_pci_capability(struct ada int t4_os_pci_save_state(struct adapter *); int t4_os_pci_restore_state(struct adapter *); void t4_os_portmod_changed(const struct adapter *, int); -void t4_os_link_changed(struct adapter *, int, int, int); +void t4_os_link_changed(struct adapter *, int, int); void t4_iterate(void (*)(struct adapter *, void *), void *); void t4_init_devnames(struct adapter *); void t4_add_adapter(struct adapter *); Modified: stable/11/sys/dev/cxgbe/common/common.h ============================================================================== --- stable/11/sys/dev/cxgbe/common/common.h Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/sys/dev/cxgbe/common/common.h Wed Jan 4 06:54:05 2017 (r311260) @@ -62,6 +62,12 @@ enum { PAUSE_AUTONEG = 1 << 2 }; +enum { + FEC_RS = 1 << 0, + FEC_BASER_RS = 1 << 1, + FEC_RESERVED = 1 << 2, +}; + struct port_stats { u64 tx_octets; /* total # of octets in good frames */ u64 tx_frames; /* all good frames */ @@ -227,7 +233,7 @@ struct tp_params { uint32_t vlan_pri_map; uint32_t ingress_config; - uint32_t rx_pkt_encap; + __be16 err_vec_mask; int8_t fcoe_shift; int8_t port_shift; @@ -392,12 +398,16 @@ struct trace_params { struct link_config { unsigned short supported; /* link capabilities */ unsigned short advertising; /* advertised capabilities */ - unsigned short requested_speed; /* speed user has requested */ - unsigned short speed; /* actual link speed */ + unsigned short lp_advertising; /* peer advertised capabilities */ + unsigned int requested_speed; /* speed user has requested */ + unsigned int speed; /* actual link speed */ unsigned char requested_fc; /* flow control user has requested */ unsigned char fc; /* actual link flow control */ + unsigned char requested_fec; /* FEC user has requested */ + unsigned char fec; /* actual FEC */ unsigned char autoneg; /* autonegotiating? */ unsigned char link_ok; /* link up? */ + unsigned char link_down_rc; /* link down reason */ }; #include "adapter.h" Modified: stable/11/sys/dev/cxgbe/common/t4_hw.c ============================================================================== --- stable/11/sys/dev/cxgbe/common/t4_hw.c Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/sys/dev/cxgbe/common/t4_hw.c Wed Jan 4 06:54:05 2017 (r311260) @@ -3683,9 +3683,7 @@ void t4_ulprx_read_la(struct adapter *ad } } -#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ - FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_25G | \ - FW_PORT_CAP_SPEED_40G | FW_PORT_CAP_SPEED_100G | \ +#define ADVERT_MASK (V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED) | \ FW_PORT_CAP_ANEG) /** @@ -3705,14 +3703,23 @@ int t4_link_l1cfg(struct adapter *adap, struct link_config *lc) { struct fw_port_cmd c; - unsigned int fc = 0, mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO); + unsigned int mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO); + unsigned int fc, fec; - lc->link_ok = 0; + fc = 0; if (lc->requested_fc & PAUSE_RX) fc |= FW_PORT_CAP_FC_RX; if (lc->requested_fc & PAUSE_TX) fc |= FW_PORT_CAP_FC_TX; + fec = 0; + if (lc->requested_fec & FEC_RS) + fec |= FW_PORT_CAP_FEC_RS; + if (lc->requested_fec & FEC_BASER_RS) + fec |= FW_PORT_CAP_FEC_BASER_RS; + if (lc->requested_fec & FEC_RESERVED) + fec |= FW_PORT_CAP_FEC_RESERVED; + memset(&c, 0, sizeof(c)); c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_EXEC | @@ -3723,13 +3730,16 @@ int t4_link_l1cfg(struct adapter *adap, if (!(lc->supported & FW_PORT_CAP_ANEG)) { c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) | - fc); - lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); + fc | fec); + lc->fc = lc->requested_fc & ~PAUSE_AUTONEG; + lc->fec = lc->requested_fec; } else if (lc->autoneg == AUTONEG_DISABLE) { - c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fc | mdi); - lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); + c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | + fc | fec | mdi); + lc->fc = lc->requested_fc & ~PAUSE_AUTONEG; + lc->fec = lc->requested_fec; } else - c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fc | mdi); + c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fc | fec | mdi); return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } @@ -7517,18 +7527,14 @@ int t4_handle_fw_rpl(struct adapter *ada } if (link_ok != lc->link_ok || speed != lc->speed || fc != lc->fc) { /* something changed */ - int reason; - if (!link_ok && lc->link_ok) - reason = G_FW_PORT_CMD_LINKDNRC(stat); - else - reason = -1; - + lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); lc->link_ok = link_ok; lc->speed = speed; lc->fc = fc; lc->supported = be16_to_cpu(p->u.info.pcap); - t4_os_link_changed(adap, i, link_ok, reason); + lc->lp_advertising = be16_to_cpu(p->u.info.lpacap); + t4_os_link_changed(adap, i, link_ok); } } else { CH_WARN_RATELIMIT(adap, "Unknown firmware reply %d\n", opcode); @@ -7562,17 +7568,34 @@ static void get_pci_mode(struct adapter /** * init_link_config - initialize a link's SW state * @lc: structure holding the link state - * @caps: link capabilities + * @pcaps: supported link capabilities + * @acaps: advertised link capabilities * * Initializes the SW state maintained for each link, including the link's * capabilities and default speed/flow-control/autonegotiation settings. */ -static void init_link_config(struct link_config *lc, unsigned int caps) +static void init_link_config(struct link_config *lc, unsigned int pcaps, + unsigned int acaps) { - lc->supported = caps; + unsigned int fec; + + lc->supported = pcaps; + lc->lp_advertising = 0; lc->requested_speed = 0; lc->speed = 0; lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; + lc->link_ok = 0; + lc->link_down_rc = 255; + + fec = 0; + if (acaps & FW_PORT_CAP_FEC_RS) + fec |= FEC_RS; + if (acaps & FW_PORT_CAP_FEC_BASER_RS) + fec |= FEC_BASER_RS; + if (acaps & FW_PORT_CAP_FEC_RESERVED) + fec |= FEC_RESERVED; + lc->requested_fec = lc->fec = fec; + if (lc->supported & FW_PORT_CAP_ANEG) { lc->advertising = lc->supported & ADVERT_MASK; lc->autoneg = AUTONEG_ENABLE; @@ -8020,12 +8043,17 @@ int t4_init_tp_params(struct adapter *ad read_filter_mode_and_ingress_config(adap); /* - * For T6, cache the adapter's compressed error vector - * and passing outer header info for encapsulated packets. + * Cache a mask of the bits that represent the error vector portion of + * rx_pkt.err_vec. T6+ can use a compressed error vector to make room + * for information about outer encapsulation (GENEVE/VXLAN/NVGRE). */ + tpp->err_vec_mask = htobe16(0xffff); if (chip_id(adap) > CHELSIO_T5) { v = t4_read_reg(adap, A_TP_OUT_CONFIG); - tpp->rx_pkt_encap = (v & F_CRXPKTENC) ? 1 : 0; + if (v & F_CRXPKTENC) { + tpp->err_vec_mask = + htobe16(V_T6_COMPR_RXERR_VEC(M_T6_COMPR_RXERR_VEC)); + } } return 0; @@ -8121,7 +8149,8 @@ int t4_port_init(struct adapter *adap, i p->port_type = G_FW_PORT_CMD_PTYPE(ret); p->mod_type = G_FW_PORT_CMD_MODTYPE(ret); - init_link_config(&p->link_cfg, be16_to_cpu(c.u.info.pcap)); + init_link_config(&p->link_cfg, be16_to_cpu(c.u.info.pcap), + be16_to_cpu(c.u.info.acap)); } ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size); Modified: stable/11/sys/dev/cxgbe/common/t4_msg.h ============================================================================== --- stable/11/sys/dev/cxgbe/common/t4_msg.h Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/sys/dev/cxgbe/common/t4_msg.h Wed Jan 4 06:54:05 2017 (r311260) @@ -2014,7 +2014,7 @@ struct cpl_rx_pkt { #define S_T6_COMPR_RXERR_VEC 0 #define M_T6_COMPR_RXERR_VEC 0x3F -#define V_T6_COMPR_RXERR_VEC(x) ((x) << S_T6_COMPR_RXERR_LEN) +#define V_T6_COMPR_RXERR_VEC(x) ((x) << S_T6_COMPR_RXERR_VEC) #define G_T6_COMPR_RXERR_VEC(x) \ (((x) >> S_T6_COMPR_RXERR_VEC) & M_T6_COMPR_RXERR_VEC) @@ -2026,7 +2026,7 @@ struct cpl_rx_pkt { * RX_ERROR_IP_HDR_LEN, RX_ERROR_ETH_HDR_LEN */ #define S_T6_COMPR_RXERR_LEN 1 -#define V_T6_COMPR_RXERR_LEN(x) ((x) << S_COMPR_T6_RXERR_LEN) +#define V_T6_COMPR_RXERR_LEN(x) ((x) << S_T6_COMPR_RXERR_LEN) #define F_T6_COMPR_RXERR_LEN V_COMPR_T6_RXERR_LEN(1U) #define S_T6_COMPR_RXERR_TCP_OPT 2 Modified: stable/11/sys/dev/cxgbe/t4_main.c ============================================================================== --- stable/11/sys/dev/cxgbe/t4_main.c Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/sys/dev/cxgbe/t4_main.c Wed Jan 4 06:54:05 2017 (r311260) @@ -359,6 +359,24 @@ static int t4_pause_settings = PAUSE_TX TUNABLE_INT("hw.cxgbe.pause_settings", &t4_pause_settings); /* + * Forward Error Correction settings (bit 0, 1, 2 = FEC_RS, FEC_BASER_RS, + * FEC_RESERVED respectively). + * -1 to run with the firmware default. + * 0 to disable FEC. + */ +static int t4_fec = -1; +TUNABLE_INT("hw.cxgbe.fec", &t4_fec); + +/* + * Link autonegotiation. + * -1 to run with the firmware default. + * 0 to disable. + * 1 to enable. + */ +static int t4_autoneg = -1; +TUNABLE_INT("hw.cxgbe.autoneg", &t4_autoneg); + +/* * Firmware auto-install by driver during attach (0, 1, 2 = prohibited, allowed, * encouraged respectively). */ @@ -493,6 +511,8 @@ static int sysctl_holdoff_pktc_idx(SYSCT static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS); static int sysctl_qsize_txq(SYSCTL_HANDLER_ARGS); static int sysctl_pause_settings(SYSCTL_HANDLER_ARGS); +static int sysctl_fec(SYSCTL_HANDLER_ARGS); +static int sysctl_autoneg(SYSCTL_HANDLER_ARGS); static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS); static int sysctl_temperature(SYSCTL_HANDLER_ARGS); #ifdef SBUF_DRAIN @@ -922,6 +942,7 @@ t4_attach(device_t dev) n10g = n1g = 0; for_each_port(sc, i) { struct port_info *pi; + struct link_config *lc; pi = malloc(sizeof(*pi), M_CXGBE, M_ZERO | M_WAITOK); sc->port[i] = pi; @@ -950,12 +971,19 @@ t4_attach(device_t dev) goto done; } - pi->link_cfg.requested_fc &= ~(PAUSE_TX | PAUSE_RX); - pi->link_cfg.requested_fc |= t4_pause_settings; - pi->link_cfg.fc &= ~(PAUSE_TX | PAUSE_RX); - pi->link_cfg.fc |= t4_pause_settings; + lc = &pi->link_cfg; + lc->requested_fc &= ~(PAUSE_TX | PAUSE_RX); + lc->requested_fc |= t4_pause_settings; + if (t4_fec != -1) { + lc->requested_fec = t4_fec & + G_FW_PORT_CAP_FEC(lc->supported); + } + if (lc->supported & FW_PORT_CAP_ANEG && t4_autoneg != -1) { + lc->autoneg = t4_autoneg ? AUTONEG_ENABLE : + AUTONEG_DISABLE; + } - rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, &pi->link_cfg); + rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc != 0) { device_printf(dev, "port %d l1cfg failed: %d\n", i, rc); free(pi->vi, M_CXGBE); @@ -978,8 +1006,6 @@ t4_attach(device_t dev) n1g++; } - pi->linkdnrc = -1; - pi->dev = device_add_child(dev, sc->names->ifnet_name, -1); if (pi->dev == NULL) { device_printf(dev, @@ -4056,8 +4082,8 @@ cxgbe_uninit_synchronized(struct vi_info pi->link_cfg.link_ok = 0; pi->link_cfg.speed = 0; - pi->linkdnrc = -1; - t4_os_link_changed(sc, pi->port_id, 0, -1); + pi->link_cfg.link_down_rc = 255; + t4_os_link_changed(sc, pi->port_id, 0); return (0); } @@ -5270,8 +5296,14 @@ cxgbe_sysctls(struct port_info *pi) } SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "pause_settings", - CTLTYPE_STRING | CTLFLAG_RW, pi, PAUSE_TX, sysctl_pause_settings, - "A", "PAUSE settings (bit 0 = rx_pause, bit 1 = tx_pause)"); + CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_pause_settings, "A", + "PAUSE settings (bit 0 = rx_pause, bit 1 = tx_pause)"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fec", + CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_fec, "A", + "Forward Error Correction (bit 0 = RS, bit 1 = BASER_RS)"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "autoneg", + CTLTYPE_INT | CTLFLAG_RW, pi, 0, sysctl_autoneg, "I", + "autonegotiation (-1 = not supported)"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "max_speed", CTLFLAG_RD, NULL, port_top_speed(pi), "max speed (in Gbps)"); @@ -5731,12 +5763,9 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARG if (rc) return (rc); if ((lc->requested_fc & (PAUSE_TX | PAUSE_RX)) != n) { - int link_ok = lc->link_ok; - lc->requested_fc &= ~(PAUSE_TX | PAUSE_RX); lc->requested_fc |= n; rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); - lc->link_ok = link_ok; /* restore */ } end_synchronized_op(sc, 0); } @@ -5745,6 +5774,97 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARG } static int +sysctl_fec(SYSCTL_HANDLER_ARGS) +{ + struct port_info *pi = arg1; + struct adapter *sc = pi->adapter; + struct link_config *lc = &pi->link_cfg; + int rc; + + if (req->newptr == NULL) { + struct sbuf *sb; + static char *bits = "\20\1RS\2BASER_RS\3RESERVED"; + + rc = sysctl_wire_old_buffer(req, 0); + if (rc != 0) + return(rc); + + sb = sbuf_new_for_sysctl(NULL, NULL, 128, req); + if (sb == NULL) + return (ENOMEM); + + sbuf_printf(sb, "%b", lc->fec & M_FW_PORT_CAP_FEC, bits); + rc = sbuf_finish(sb); + sbuf_delete(sb); + } else { + char s[2]; + int n; + + s[0] = '0' + (lc->requested_fec & M_FW_PORT_CAP_FEC); + s[1] = 0; + + rc = sysctl_handle_string(oidp, s, sizeof(s), req); + if (rc != 0) + return(rc); + + if (s[1] != 0) + return (EINVAL); + if (s[0] < '0' || s[0] > '9') + return (EINVAL); /* not a number */ + n = s[0] - '0'; + if (n & ~M_FW_PORT_CAP_FEC) + return (EINVAL); /* some other bit is set too */ + + rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, + "t4fec"); + if (rc) + return (rc); + if ((lc->requested_fec & M_FW_PORT_CAP_FEC) != n) { + lc->requested_fec = n & + G_FW_PORT_CAP_FEC(lc->supported); + rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); + } + end_synchronized_op(sc, 0); + } + + return (rc); +} + +static int +sysctl_autoneg(SYSCTL_HANDLER_ARGS) +{ + struct port_info *pi = arg1; + struct adapter *sc = pi->adapter; + struct link_config *lc = &pi->link_cfg; + int rc, val, old; + + if (lc->supported & FW_PORT_CAP_ANEG) + val = lc->autoneg == AUTONEG_ENABLE ? 1 : 0; + else + val = -1; + rc = sysctl_handle_int(oidp, &val, 0, req); + if (rc != 0 || req->newptr == NULL) + return (rc); + if ((lc->supported & FW_PORT_CAP_ANEG) == 0) + return (ENOTSUP); + + val = val ? AUTONEG_ENABLE : AUTONEG_DISABLE; + if (lc->autoneg == val) + return (0); /* no change */ + + rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, + "t4aneg"); + if (rc) + return (rc); + old = lc->autoneg; + lc->autoneg = val; + rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); + if (rc != 0) + lc->autoneg = old; + return (rc); +} + +static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; @@ -6489,6 +6609,7 @@ sysctl_linkdnrc(SYSCTL_HANDLER_ARGS) { int rc = 0; struct port_info *pi = arg1; + struct link_config *lc = &pi->link_cfg; struct sbuf *sb; rc = sysctl_wire_old_buffer(req, 0); @@ -6498,10 +6619,10 @@ sysctl_linkdnrc(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - if (pi->linkdnrc < 0) + if (lc->link_ok || lc->link_down_rc == 255) sbuf_printf(sb, "n/a"); else - sbuf_printf(sb, "%s", t4_link_down_rc_str(pi->linkdnrc)); + sbuf_printf(sb, "%s", t4_link_down_rc_str(lc->link_down_rc)); rc = sbuf_finish(sb); sbuf_delete(sb); @@ -7215,25 +7336,23 @@ sysctl_tids(SYSCTL_HANDLER_ARGS) } if (t->ntids) { + sbuf_printf(sb, "TID range: "); if (t4_read_reg(sc, A_LE_DB_CONFIG) & F_HASHEN) { - uint32_t b; + uint32_t b, hb; - if (chip_id(sc) <= CHELSIO_T5) + 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, - t4_read_reg(sc, A_LE_DB_TID_HASHBASE) / 4, - t->ntids - 1); + hb = t4_read_reg(sc, A_LE_DB_TID_HASHBASE) / 4; } else { - sbuf_printf(sb, "TID range: %u-%u", - t4_read_reg(sc, A_LE_DB_TID_HASHBASE) / 4, - t->ntids - 1); + b = t4_read_reg(sc, A_LE_DB_SRVR_START_INDEX); + hb = t4_read_reg(sc, A_T6_LE_DB_HASH_TID_BASE); } + + if (b) + sbuf_printf(sb, "0-%u, ", b - 1); + sbuf_printf(sb, "%u-%u", hb, t->ntids - 1); } else - sbuf_printf(sb, "TID range: 0-%u", t->ntids - 1); + sbuf_printf(sb, "0-%u", t->ntids - 1); sbuf_printf(sb, ", in use: %u\n", atomic_load_acq_int(&t->tids_in_use)); } @@ -8971,19 +9090,13 @@ t4_os_portmod_changed(const struct adapt } void -t4_os_link_changed(struct adapter *sc, int idx, int link_stat, int reason) +t4_os_link_changed(struct adapter *sc, int idx, int link_stat) { struct port_info *pi = sc->port[idx]; struct vi_info *vi; struct ifnet *ifp; int v; - if (link_stat) - pi->linkdnrc = -1; - else { - if (reason >= 0) - pi->linkdnrc = reason; - } for_each_vi(pi, v, vi) { ifp = vi->ifp; if (ifp == NULL) Modified: stable/11/sys/dev/cxgbe/t4_sge.c ============================================================================== --- stable/11/sys/dev/cxgbe/t4_sge.c Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/sys/dev/cxgbe/t4_sge.c Wed Jan 4 06:54:05 2017 (r311260) @@ -1799,7 +1799,7 @@ t4_eth_rx(struct sge_iq *iq, const struc M_HASHTYPE_SET(m0, sw_hashtype[rss->hash_type][rss->ipv6]); m0->m_pkthdr.flowid = be32toh(rss->hash_val); - if (cpl->csum_calc && !cpl->err_vec) { + if (cpl->csum_calc && !(cpl->err_vec & sc->params.tp.err_vec_mask)) { if (ifp->if_capenable & IFCAP_RXCSUM && cpl->l2info & htobe32(F_RXF_IP)) { m0->m_pkthdr.csum_flags = (CSUM_IP_CHECKED | Modified: stable/11/sys/dev/cxgbe/t4_vf.c ============================================================================== --- stable/11/sys/dev/cxgbe/t4_vf.c Wed Jan 4 06:53:00 2017 (r311259) +++ stable/11/sys/dev/cxgbe/t4_vf.c Wed Jan 4 06:54:05 2017 (r311260) @@ -668,8 +668,6 @@ t4vf_attach(device_t dev) n1g++; } - pi->linkdnrc = -1; - pi->dev = device_add_child(dev, sc->names->vf_ifnet_name, -1); if (pi->dev == NULL) { device_printf(dev,