From owner-svn-src-stable-9@freebsd.org Mon Oct 29 12:13:06 2018 Return-Path: Delivered-To: svn-src-stable-9@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2F5CE10D651B; Mon, 29 Oct 2018 12:13:06 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D7DBB6E8DB; Mon, 29 Oct 2018 12:13:05 +0000 (UTC) (envelope-from hselasky@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B41AD64DE; Mon, 29 Oct 2018 12:13:05 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w9TCD5BH069721; Mon, 29 Oct 2018 12:13:05 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w9TCD5Pt069720; Mon, 29 Oct 2018 12:13:05 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201810291213.w9TCD5Pt069720@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Mon, 29 Oct 2018 12:13:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r339854 - stable/9/sys/dev/usb/serial X-SVN-Group: stable-9 X-SVN-Commit-Author: hselasky X-SVN-Commit-Paths: stable/9/sys/dev/usb/serial X-SVN-Commit-Revision: 339854 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 Oct 2018 12:13:06 -0000 Author: hselasky Date: Mon Oct 29 12:13:05 2018 New Revision: 339854 URL: https://svnweb.freebsd.org/changeset/base/339854 Log: MFC r339587: Added support for formula-based arbitrary baud rates, in contrast to the current fixed values, which enables use of rates above 1 Mbps. Improved the detection of HXD chips, and the status flag handling as well. Submitted by: Gabor Simon PR: 225932 Differential revision: https://reviews.freebsd.org/D16639 Sponsored by: Mellanox Technologies Modified: stable/9/sys/dev/usb/serial/uplcom.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/dev/usb/serial/uplcom.c ============================================================================== --- stable/9/sys/dev/usb/serial/uplcom.c Mon Oct 29 12:11:27 2018 (r339853) +++ stable/9/sys/dev/usb/serial/uplcom.c Mon Oct 29 12:13:05 2018 (r339854) @@ -132,12 +132,20 @@ SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RW #define UPLCOM_SET_CRTSCTS 0x41 #define UPLCOM_SET_CRTSCTS_PL2303X 0x61 #define RSAQ_STATUS_CTS 0x80 +#define RSAQ_STATUS_OVERRUN_ERROR 0x40 +#define RSAQ_STATUS_PARITY_ERROR 0x20 +#define RSAQ_STATUS_FRAME_ERROR 0x10 +#define RSAQ_STATUS_RING 0x08 +#define RSAQ_STATUS_BREAK_ERROR 0x04 #define RSAQ_STATUS_DSR 0x02 #define RSAQ_STATUS_DCD 0x01 #define TYPE_PL2303 0 #define TYPE_PL2303HX 1 +#define TYPE_PL2303HXD 2 +#define UPLCOM_STATE_INDEX 8 + enum { UPLCOM_BULK_DT_WR, UPLCOM_BULK_DT_RD, @@ -366,18 +374,49 @@ uplcom_attach(device_t dev) sc->sc_udev = uaa->device; - /* Determine the chip type. This algorithm is taken from Linux. */ dd = usbd_get_device_descriptor(sc->sc_udev); - if (dd->bDeviceClass == 0x02) - sc->sc_chiptype = TYPE_PL2303; - else if (dd->bMaxPacketSize == 0x40) + + switch (UGETW(dd->bcdDevice)) { + case 0x0300: sc->sc_chiptype = TYPE_PL2303HX; - else - sc->sc_chiptype = TYPE_PL2303; + /* or TA, that is HX with external crystal */ + break; + case 0x0400: + sc->sc_chiptype = TYPE_PL2303HXD; + /* or EA, that is HXD with ESD protection */ + /* or RA, that has internal voltage level converter that works only up to 1Mbaud (!) */ + break; + case 0x0500: + sc->sc_chiptype = TYPE_PL2303HXD; + /* in fact it's TB, that is HXD with external crystal */ + break; + default: + /* NOTE: I have no info about the bcdDevice for the base PL2303 (up to 1.2Mbaud, + only fixed rates) and for PL2303SA (8-pin chip, up to 115200 baud */ + /* Determine the chip type. This algorithm is taken from Linux. */ + if (dd->bDeviceClass == 0x02) + sc->sc_chiptype = TYPE_PL2303; + else if (dd->bMaxPacketSize == 0x40) + sc->sc_chiptype = TYPE_PL2303HX; + else + sc->sc_chiptype = TYPE_PL2303; + break; + } - DPRINTF("chiptype: %s\n", - (sc->sc_chiptype == TYPE_PL2303HX) ? - "2303X" : "2303"); + switch (sc->sc_chiptype) { + case TYPE_PL2303: + DPRINTF("chiptype: 2303\n"); + break; + case TYPE_PL2303HX: + DPRINTF("chiptype: 2303HX/TA\n"); + break; + case TYPE_PL2303HXD: + DPRINTF("chiptype: 2303HXD/TB/RA/EA\n"); + break; + default: + DPRINTF("chiptype: unknown %d\n", sc->sc_chiptype); + break; + } /* * USB-RSAQ1 has two interface @@ -426,13 +465,14 @@ uplcom_attach(device_t dev) goto detach; } - if (sc->sc_chiptype != TYPE_PL2303HX) { + if (sc->sc_chiptype == TYPE_PL2303) { /* HX variants seem to lock up after a clear stall request. */ mtx_lock(&sc->sc_mtx); usbd_xfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_WR]); usbd_xfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_RD]); mtx_unlock(&sc->sc_mtx); } else { + /* reset upstream data pipes */ if (uplcom_pl2303_do(sc->sc_udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 8, 0, 0) || uplcom_pl2303_do(sc->sc_udev, UT_WRITE_VENDOR_DEVICE, @@ -551,7 +591,7 @@ uplcom_pl2303_init(struct usb_device *udev, uint8_t ch || uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 1, 0, 0)) return (EIO); - if (chiptype == TYPE_PL2303HX) + if (chiptype != TYPE_PL2303) err = uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 2, 0x44, 0); else err = uplcom_pl2303_do(udev, UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 2, 0x24, 0); @@ -631,23 +671,52 @@ uplcom_cfg_set_break(struct ucom_softc *ucom, uint8_t &req, NULL, 0, 1000); } +/* + * NOTE: These baud rates are officially supported, they can be written + * directly into dwDTERate register. + * + * Free baudrate setting is not supported by the base PL2303, and on + * other models it requires writing a divisor value to dwDTERate instead + * of the raw baudrate. The formula for divisor calculation is not published + * by the vendor, so it is speculative, though the official product homepage + * refers to the Linux module source as a reference implementation. + */ static const uint32_t uplcom_rates[] = { - 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400, - 19200, 28800, 38400, 57600, 115200, /* - * Higher speeds are probably possible. PL2303X supports up to - * 6Mb and can set any rate + * Basic 'standard' speed rates, supported by all models + * NOTE: 900 and 56000 actually works as well */ - 230400, 460800, 614400, 921600, 1228800 + 75, 150, 300, 600, 900, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400, + 19200, 28800, 38400, 56000, 57600, 115200, + /* + * Advanced speed rates up to 6Mbs, supported by HX/TA and HXD/TB/EA/RA + * NOTE: regardless of the spec, 256000 does not work + */ + 128000, 134400, 161280, 201600, 230400, 268800, 403200, 460800, 614400, + 806400, 921600, 1228800, 2457600, 3000000, 6000000, + /* + * Advanced speed rates up to 12, supported by HXD/TB/EA/RA + */ + 12000000 }; #define N_UPLCOM_RATES (sizeof(uplcom_rates)/sizeof(uplcom_rates[0])) static int +uplcom_baud_supported(unsigned int speed) +{ + int i; + for (i = 0; i < N_UPLCOM_RATES; i++) { + if (uplcom_rates[i] == speed) + return 1; + } + return 0; +} + +static int uplcom_pre_param(struct ucom_softc *ucom, struct termios *t) { struct uplcom_softc *sc = ucom->sc_parent; - uint8_t i; DPRINTF("\n"); @@ -655,26 +724,75 @@ uplcom_pre_param(struct ucom_softc *ucom, struct termi * Check requested baud rate. * * The PL2303 can only set specific baud rates, up to 1228800 baud. - * The PL2303X can set any baud rate up to 6Mb. + * The PL2303HX can set any baud rate up to 6Mb. * The PL2303HX rev. D can set any baud rate up to 12Mb. * - * XXX: We currently cannot identify the PL2303HX rev. D, so treat - * it the same as the PL2303X. */ - if (sc->sc_chiptype != TYPE_PL2303HX) { - for (i = 0; i < N_UPLCOM_RATES; i++) { - if (uplcom_rates[i] == t->c_ospeed) + + /* accept raw divisor data, if someone wants to do the math in user domain */ + if (t->c_ospeed & 0x80000000) + return 0; + switch (sc->sc_chiptype) { + case TYPE_PL2303HXD: + if (t->c_ospeed <= 12000000) return (0); - } - } else { - if (t->c_ospeed <= 6000000) - return (0); + break; + case TYPE_PL2303HX: + if (t->c_ospeed <= 6000000) + return (0); + break; + default: + if (uplcom_baud_supported(t->c_ospeed)) + return (0); + break; } DPRINTF("uplcom_param: bad baud rate (%d)\n", t->c_ospeed); return (EIO); } +static unsigned int +uplcom_encode_baud_rate_divisor(uint8_t *buf, unsigned int baud) +{ + unsigned int baseline, mantissa, exponent; + + /* Determine the baud rate divisor. This algorithm is taken from Linux. */ + /* + * Apparently the formula is: + * baudrate = baseline / (mantissa * 4^exponent) + * where + * mantissa = buf[8:0] + * exponent = buf[11:9] + */ + if (baud == 0) + baud = 1; + baseline = 383385600; + mantissa = baseline / baud; + if (mantissa == 0) + mantissa = 1; + exponent = 0; + while (mantissa >= 512) { + if (exponent < 7) { + mantissa >>= 2; /* divide by 4 */ + exponent++; + } else { + /* Exponent is maxed. Trim mantissa and leave. This gives approx. 45.8 baud */ + mantissa = 511; + break; + } + } + + buf[3] = 0x80; + buf[2] = 0; + buf[1] = exponent << 1 | mantissa >> 8; + buf[0] = mantissa & 0xff; + + /* Calculate and return the exact baud rate. */ + baud = (baseline / mantissa) >> (exponent << 1); + DPRINTF("real baud rate will be %u\n", baud); + + return baud; +} static void uplcom_cfg_param(struct ucom_softc *ucom, struct termios *t) { @@ -686,10 +804,24 @@ uplcom_cfg_param(struct ucom_softc *ucom, struct termi memset(&ls, 0, sizeof(ls)); - USETDW(ls.dwDTERate, t->c_ospeed); + /* + * NOTE: If unsupported baud rates are set directly, the PL2303* uses 9600 baud. + */ + if ((t->c_ospeed & 0x80000000) || uplcom_baud_supported(t->c_ospeed)) + USETDW(ls.dwDTERate, t->c_ospeed); + else + t->c_ospeed = uplcom_encode_baud_rate_divisor((uint8_t*)&ls.dwDTERate, t->c_ospeed); if (t->c_cflag & CSTOPB) { - ls.bCharFormat = UCDC_STOP_BIT_2; + if ((t->c_cflag & CSIZE) == CS5) { + /* + * NOTE: Comply with "real" UARTs / RS232: + * use 1.5 instead of 2 stop bits with 5 data bits + */ + ls.bCharFormat = UCDC_STOP_BIT_1_5; + } else { + ls.bCharFormat = UCDC_STOP_BIT_2; + } } else { ls.bCharFormat = UCDC_STOP_BIT_1; } @@ -719,7 +851,7 @@ uplcom_cfg_param(struct ucom_softc *ucom, struct termi break; } - DPRINTF("rate=%d fmt=%d parity=%d bits=%d\n", + DPRINTF("rate=0x%08x fmt=%d parity=%d bits=%d\n", UGETDW(ls.dwDTERate), ls.bCharFormat, ls.bParityType, ls.bDataBits); @@ -740,7 +872,7 @@ uplcom_cfg_param(struct ucom_softc *ucom, struct termi req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = UPLCOM_SET_REQUEST; USETW(req.wValue, 0); - if (sc->sc_chiptype == TYPE_PL2303HX) + if (sc->sc_chiptype != TYPE_PL2303) USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303X); else USETW(req.wIndex, UPLCOM_SET_CRTSCTS); @@ -830,18 +962,33 @@ uplcom_intr_callback(struct usb_xfer *xfer, usb_error_ pc = usbd_xfer_get_frame(xfer, 0); usbd_copy_out(pc, 0, buf, sizeof(buf)); - DPRINTF("status = 0x%02x\n", buf[8]); + DPRINTF("status = 0x%02x\n", buf[UPLCOM_STATE_INDEX]); sc->sc_lsr = 0; sc->sc_msr = 0; - if (buf[8] & RSAQ_STATUS_CTS) { + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_CTS) { sc->sc_msr |= SER_CTS; } - if (buf[8] & RSAQ_STATUS_DSR) { + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_OVERRUN_ERROR) { + sc->sc_lsr |= ULSR_OE; + } + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_PARITY_ERROR) { + sc->sc_lsr |= ULSR_PE; + } + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_FRAME_ERROR) { + sc->sc_lsr |= ULSR_FE; + } + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_RING) { + sc->sc_msr |= SER_RI; + } + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_BREAK_ERROR) { + sc->sc_lsr |= ULSR_BI; + } + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_DSR) { sc->sc_msr |= SER_DSR; } - if (buf[8] & RSAQ_STATUS_DCD) { + if (buf[UPLCOM_STATE_INDEX] & RSAQ_STATUS_DCD) { sc->sc_msr |= SER_DCD; } ucom_status_change(&sc->sc_ucom); From owner-svn-src-stable-9@freebsd.org Mon Oct 29 21:36:11 2018 Return-Path: Delivered-To: svn-src-stable-9@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BAE8710EACE7; Mon, 29 Oct 2018 21:36:11 +0000 (UTC) (envelope-from davidcs@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 6820A84828; Mon, 29 Oct 2018 21:36:11 +0000 (UTC) (envelope-from davidcs@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3CB251400D; Mon, 29 Oct 2018 21:36:11 +0000 (UTC) (envelope-from davidcs@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w9TLaBOZ057564; Mon, 29 Oct 2018 21:36:11 GMT (envelope-from davidcs@FreeBSD.org) Received: (from davidcs@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w9TLaAtc057563; Mon, 29 Oct 2018 21:36:10 GMT (envelope-from davidcs@FreeBSD.org) Message-Id: <201810292136.w9TLaAtc057563@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: davidcs set sender to davidcs@FreeBSD.org using -f From: David C Somayajulu Date: Mon, 29 Oct 2018 21:36:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r339885 - stable/9/sys/dev/bxe X-SVN-Group: stable-9 X-SVN-Commit-Author: davidcs X-SVN-Commit-Paths: stable/9/sys/dev/bxe X-SVN-Commit-Revision: 339885 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 Oct 2018 21:36:11 -0000 Author: davidcs Date: Mon Oct 29 21:36:10 2018 New Revision: 339885 URL: https://svnweb.freebsd.org/changeset/base/339885 Log: MFC r338734 Fixed isses: State check before enqueuing transmit task in bxe_link_attn() routine. State check before invoking bxe_nic_unload in bxe_shutdown(). Submitted by:Vaishali.Kulkarni@cavium.com Modified: stable/9/sys/dev/bxe/bxe.c Directory Properties: stable/9/ (props changed) stable/9/sys/ (props changed) Modified: stable/9/sys/dev/bxe/bxe.c ============================================================================== --- stable/9/sys/dev/bxe/bxe.c Mon Oct 29 21:31:23 2018 (r339884) +++ stable/9/sys/dev/bxe/bxe.c Mon Oct 29 21:36:10 2018 (r339885) @@ -7081,13 +7081,13 @@ bxe_link_attn(struct bxe_softc *sc) if (sc->state == BXE_STATE_OPEN) { bxe_stats_handle(sc, STATS_EVENT_LINK_UP); + /* Restart tx when the link comes back. */ + FOR_EACH_ETH_QUEUE(sc, i) { + fp = &sc->fp[i]; + taskqueue_enqueue(fp->tq, &fp->tx_task); + } } - /* Restart tx when the link comes back. */ - FOR_EACH_ETH_QUEUE(sc, i) { - fp = &sc->fp[i]; - taskqueue_enqueue(fp->tq, &fp->tx_task); - } } if (sc->link_vars.link_up && sc->link_vars.line_speed) { @@ -16284,9 +16284,11 @@ bxe_shutdown(device_t dev) /* stop the periodic callout */ bxe_periodic_stop(sc); - BXE_CORE_LOCK(sc); - bxe_nic_unload(sc, UNLOAD_NORMAL, FALSE); - BXE_CORE_UNLOCK(sc); + if (sc->state != BXE_STATE_CLOSED) { + BXE_CORE_LOCK(sc); + bxe_nic_unload(sc, UNLOAD_NORMAL, FALSE); + BXE_CORE_UNLOCK(sc); + } return (0); } From owner-svn-src-stable-9@freebsd.org Mon Oct 29 21:46:16 2018 Return-Path: Delivered-To: svn-src-stable-9@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E685110EB1D2; Mon, 29 Oct 2018 21:46:15 +0000 (UTC) (envelope-from davidcs@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 9675084ECF; Mon, 29 Oct 2018 21:46:15 +0000 (UTC) (envelope-from davidcs@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AFAF6141AE; Mon, 29 Oct 2018 21:46:13 +0000 (UTC) (envelope-from davidcs@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w9TLkD2l062658; Mon, 29 Oct 2018 21:46:13 GMT (envelope-from davidcs@FreeBSD.org) Received: (from davidcs@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w9TLkDX4062655; Mon, 29 Oct 2018 21:46:13 GMT (envelope-from davidcs@FreeBSD.org) Message-Id: <201810292146.w9TLkDX4062655@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: davidcs set sender to davidcs@FreeBSD.org using -f From: David C Somayajulu Date: Mon, 29 Oct 2018 21:46:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r339887 - stable/9/sys/dev/bxe X-SVN-Group: stable-9 X-SVN-Commit-Author: davidcs X-SVN-Commit-Paths: stable/9/sys/dev/bxe X-SVN-Commit-Revision: 339887 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 Oct 2018 21:46:16 -0000 Author: davidcs Date: Mon Oct 29 21:46:12 2018 New Revision: 339887 URL: https://svnweb.freebsd.org/changeset/base/339887 Log: MFC r339366 Add support for Error Recovery Submitted by:Vaishali.Kulkarni@cavium.com Modified: stable/9/sys/dev/bxe/bxe.c stable/9/sys/dev/bxe/bxe.h stable/9/sys/dev/bxe/bxe_stats.c Directory Properties: stable/9/ (props changed) stable/9/sys/ (props changed) Modified: stable/9/sys/dev/bxe/bxe.c ============================================================================== --- stable/9/sys/dev/bxe/bxe.c Mon Oct 29 21:46:05 2018 (r339886) +++ stable/9/sys/dev/bxe/bxe.c Mon Oct 29 21:46:12 2018 (r339887) @@ -188,6 +188,7 @@ static int bxe_attach(device_t); static int bxe_detach(device_t); static int bxe_shutdown(device_t); + /* * FreeBSD KLD module/device interface event handler method. */ @@ -700,6 +701,9 @@ static void bxe_interrupt_detach(struct bxe_softc * static void bxe_set_rx_mode(struct bxe_softc *sc); static int bxe_init_locked(struct bxe_softc *sc); static int bxe_stop_locked(struct bxe_softc *sc); +static void bxe_sp_err_timeout_task(void *arg, int pending); +void bxe_parity_recover(struct bxe_softc *sc); +void bxe_handle_error(struct bxe_softc *sc); static __noinline int bxe_nic_load(struct bxe_softc *sc, int load_mode); static __noinline int bxe_nic_unload(struct bxe_softc *sc, @@ -3488,16 +3492,12 @@ bxe_watchdog(struct bxe_softc *sc, } BLOGE(sc, "TX watchdog timeout on fp[%02d], resetting!\n", fp->index); - if(sc->trigger_grcdump) { - /* taking grcdump */ - bxe_grc_dump(sc); - } BXE_FP_TX_UNLOCK(fp); + BXE_SET_ERROR_BIT(sc, BXE_ERR_TXQ_STUCK); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); - atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_REINIT); - taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task); - return (-1); } @@ -4252,6 +4252,7 @@ bxe_nic_unload(struct bxe_softc *sc, struct bxe_fastpath *fp; fp = &sc->fp[i]; + fp->watchdog_timer = 0; BXE_FP_TX_LOCK(fp); BXE_FP_TX_UNLOCK(fp); } @@ -4267,20 +4268,22 @@ bxe_nic_unload(struct bxe_softc *sc, if (IS_PF(sc) && sc->recovery_state != BXE_RECOVERY_DONE && (sc->state == BXE_STATE_CLOSED || sc->state == BXE_STATE_ERROR)) { - /* - * We can get here if the driver has been unloaded - * during parity error recovery and is either waiting for a - * leader to complete or for other functions to unload and - * then ifconfig down has been issued. In this case we want to - * unload and let other functions to complete a recovery - * process. - */ - sc->recovery_state = BXE_RECOVERY_DONE; - sc->is_leader = 0; - bxe_release_leader_lock(sc); - mb(); - BLOGD(sc, DBG_LOAD, "Releasing a leadership...\n"); + if(CHIP_PORT_MODE(sc) == CHIP_4_PORT_MODE) { + /* + * We can get here if the driver has been unloaded + * during parity error recovery and is either waiting for a + * leader to complete or for other functions to unload and + * then ifconfig down has been issued. In this case we want to + * unload and let other functions to complete a recovery + * process. + */ + sc->recovery_state = BXE_RECOVERY_DONE; + sc->is_leader = 0; + bxe_release_leader_lock(sc); + mb(); + BLOGD(sc, DBG_LOAD, "Releasing a leadership...\n"); + } BLOGE(sc, "Can't unload in closed or error state recover_state 0x%x" " state = 0x%x\n", sc->recovery_state, sc->state); return (-1); @@ -7575,6 +7578,10 @@ bxe_parity_attn(struct bxe_softc *sc, if (print) BLOGI(sc, "\n"); + if( *global == TRUE ) { + BXE_SET_ERROR_BIT(sc, BXE_ERR_GLOBAL); + } + return (TRUE); } @@ -7589,6 +7596,9 @@ bxe_chk_parity_attn(struct bxe_softc *sc, struct attn_route attn = { {0} }; int port = SC_PORT(sc); + if(sc->state != BXE_STATE_OPEN) + return FALSE; + attn.sig[0] = REG_RD(sc, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4); attn.sig[1] = REG_RD(sc, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); attn.sig[2] = REG_RD(sc, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4); @@ -7615,10 +7625,12 @@ bxe_attn_int_deasserted4(struct bxe_softc *sc, uint32_t attn) { uint32_t val; + boolean_t err_flg = FALSE; if (attn & AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT) { val = REG_RD(sc, PGLUE_B_REG_PGLUE_B_INT_STS_CLR); BLOGE(sc, "PGLUE hw attention 0x%08x\n", val); + err_flg = TRUE; if (val & PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR) BLOGE(sc, "PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR\n"); if (val & PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR) @@ -7642,6 +7654,7 @@ bxe_attn_int_deasserted4(struct bxe_softc *sc, if (attn & AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT) { val = REG_RD(sc, ATC_REG_ATC_INT_STS_CLR); BLOGE(sc, "ATC hw attention 0x%08x\n", val); + err_flg = TRUE; if (val & ATC_ATC_INT_STS_REG_ADDRESS_ERROR) BLOGE(sc, "ATC_ATC_INT_STS_REG_ADDRESS_ERROR\n"); if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND) @@ -7661,7 +7674,14 @@ bxe_attn_int_deasserted4(struct bxe_softc *sc, BLOGE(sc, "FATAL parity attention set4 0x%08x\n", (uint32_t)(attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR))); + err_flg = TRUE; } + if (err_flg) { + BXE_SET_ERROR_BIT(sc, BXE_ERR_MISC); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + } + } static void @@ -8016,14 +8036,21 @@ bxe_attn_int_deasserted3(struct bxe_softc *sc, REG_WR(sc, MISC_REG_AEU_GENERAL_ATTN_9, 0); REG_WR(sc, MISC_REG_AEU_GENERAL_ATTN_8, 0); REG_WR(sc, MISC_REG_AEU_GENERAL_ATTN_7, 0); - bxe_panic(sc, ("MC assert!\n")); - + bxe_int_disable(sc); + BXE_SET_ERROR_BIT(sc, BXE_ERR_MC_ASSERT); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + } else if (attn & BXE_MCP_ASSERT) { BLOGE(sc, "MCP assert!\n"); REG_WR(sc, MISC_REG_AEU_GENERAL_ATTN_11, 0); - // XXX bxe_fw_dump(sc); + BXE_SET_ERROR_BIT(sc, BXE_ERR_MCP_ASSERT); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + bxe_int_disable(sc); /*avoid repetive assert alert */ + } else { BLOGE(sc, "Unknown HW assert! (attn 0x%08x)\n", attn); } @@ -8051,6 +8078,7 @@ bxe_attn_int_deasserted2(struct bxe_softc *sc, int reg_offset; uint32_t val0, mask0, val1, mask1; uint32_t val; + boolean_t err_flg = FALSE; if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { val = REG_RD(sc, CFC_REG_CFC_INT_STS_CLR); @@ -8058,6 +8086,7 @@ bxe_attn_int_deasserted2(struct bxe_softc *sc, /* CFC error attention */ if (val & 0x2) { BLOGE(sc, "FATAL error from CFC\n"); + err_flg = TRUE; } } @@ -8067,11 +8096,13 @@ bxe_attn_int_deasserted2(struct bxe_softc *sc, /* RQ_USDMDP_FIFO_OVERFLOW */ if (val & 0x18000) { BLOGE(sc, "FATAL error from PXP\n"); + err_flg = TRUE; } if (!CHIP_IS_E1x(sc)) { val = REG_RD(sc, PXP_REG_PXP_INT_STS_CLR_1); BLOGE(sc, "PXP hw attention-1 0x%08x\n", val); + err_flg = TRUE; } } @@ -8108,6 +8139,7 @@ bxe_attn_int_deasserted2(struct bxe_softc *sc, */ if (val0 & PXP2_EOP_ERROR_BIT) { BLOGE(sc, "PXP2_WR_PGLUE_EOP_ERROR\n"); + err_flg = TRUE; /* * if only PXP2_PXP2_INT_STS_0_REG_WR_PGLUE_EOP_ERROR is @@ -8130,8 +8162,15 @@ bxe_attn_int_deasserted2(struct bxe_softc *sc, BLOGE(sc, "FATAL HW block attention set2 0x%x\n", (uint32_t)(attn & HW_INTERRUT_ASSERT_SET_2)); + err_flg = TRUE; bxe_panic(sc, ("HW block attention set2\n")); } + if(err_flg) { + BXE_SET_ERROR_BIT(sc, BXE_ERR_GLOBAL); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + } + } static void @@ -8141,6 +8180,7 @@ bxe_attn_int_deasserted1(struct bxe_softc *sc, int port = SC_PORT(sc); int reg_offset; uint32_t val; + boolean_t err_flg = FALSE; if (attn & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) { val = REG_RD(sc, DORQ_REG_DORQ_INT_STS_CLR); @@ -8148,6 +8188,7 @@ bxe_attn_int_deasserted1(struct bxe_softc *sc, /* DORQ discard attention */ if (val & 0x2) { BLOGE(sc, "FATAL error from DORQ\n"); + err_flg = TRUE; } } @@ -8161,8 +8202,15 @@ bxe_attn_int_deasserted1(struct bxe_softc *sc, BLOGE(sc, "FATAL HW block attention set1 0x%08x\n", (uint32_t)(attn & HW_INTERRUT_ASSERT_SET_1)); + err_flg = TRUE; bxe_panic(sc, ("HW block attention set1\n")); } + if(err_flg) { + BXE_SET_ERROR_BIT(sc, BXE_ERR_MISC); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + } + } static void @@ -8199,6 +8247,11 @@ bxe_attn_int_deasserted0(struct bxe_softc *sc, val &= ~(attn & HW_INTERRUT_ASSERT_SET_0); REG_WR(sc, reg_offset, val); + + BXE_SET_ERROR_BIT(sc, BXE_ERR_MISC); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + bxe_panic(sc, ("FATAL HW block attention set0 0x%lx\n", (attn & HW_INTERRUT_ASSERT_SET_0))); } @@ -8228,10 +8281,12 @@ bxe_attn_int_deasserted(struct bxe_softc *sc, * In case of parity errors don't handle attentions so that * other function would "see" parity errors. */ - sc->recovery_state = BXE_RECOVERY_INIT; // XXX schedule a recovery task... /* disable HW interrupts */ bxe_int_disable(sc); + BXE_SET_ERROR_BIT(sc, BXE_ERR_PARITY); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); bxe_release_alr(sc); return; } @@ -12363,6 +12418,259 @@ bxe_periodic_stop(struct bxe_softc *sc) callout_drain(&sc->periodic_callout); } +void +bxe_parity_recover(struct bxe_softc *sc) +{ + uint8_t global = FALSE; + uint32_t error_recovered, error_unrecovered; + bool is_parity; + + + if ((sc->recovery_state == BXE_RECOVERY_FAILED) && + (sc->state == BXE_STATE_ERROR)) { + BLOGE(sc, "RECOVERY failed, " + "stack notified driver is NOT running! " + "Please reboot/power cycle the system.\n"); + return; + } + + while (1) { + BLOGD(sc, DBG_SP, + "%s sc=%p state=0x%x rec_state=0x%x error_status=%x\n", + __func__, sc, sc->state, sc->recovery_state, sc->error_status); + + switch(sc->recovery_state) { + + case BXE_RECOVERY_INIT: + is_parity = bxe_chk_parity_attn(sc, &global, FALSE); + + if ((CHIP_PORT_MODE(sc) == CHIP_4_PORT_MODE) || + (sc->error_status & BXE_ERR_MCP_ASSERT) || + (sc->error_status & BXE_ERR_GLOBAL)) { + + BXE_CORE_LOCK(sc); + if (sc->ifnet->if_drv_flags & IFF_DRV_RUNNING) { + bxe_periodic_stop(sc); + } + bxe_nic_unload(sc, UNLOAD_RECOVERY, false); + sc->state = BXE_STATE_ERROR; + sc->recovery_state = BXE_RECOVERY_FAILED; + BLOGE(sc, " No Recovery tried for error 0x%x" + " stack notified driver is NOT running!" + " Please reboot/power cycle the system.\n", + sc->error_status); + BXE_CORE_UNLOCK(sc); + return; + } + + + /* Try to get a LEADER_LOCK HW lock */ + if (bxe_trylock_leader_lock(sc)) { + + bxe_set_reset_in_progress(sc); + /* + * Check if there is a global attention and if + * there was a global attention, set the global + * reset bit. + */ + if (global) { + bxe_set_reset_global(sc); + } + sc->is_leader = 1; + } + + /* If interface has been removed - break */ + + if (sc->ifnet->if_drv_flags & IFF_DRV_RUNNING) { + bxe_periodic_stop(sc); + } + + BXE_CORE_LOCK(sc); + bxe_nic_unload(sc,UNLOAD_RECOVERY, false); + sc->recovery_state = BXE_RECOVERY_WAIT; + BXE_CORE_UNLOCK(sc); + + /* + * Ensure "is_leader", MCP command sequence and + * "recovery_state" update values are seen on other + * CPUs. + */ + mb(); + break; + case BXE_RECOVERY_WAIT: + + if (sc->is_leader) { + int other_engine = SC_PATH(sc) ? 0 : 1; + bool other_load_status = + bxe_get_load_status(sc, other_engine); + bool load_status = + bxe_get_load_status(sc, SC_PATH(sc)); + global = bxe_reset_is_global(sc); + + /* + * In case of a parity in a global block, let + * the first leader that performs a + * leader_reset() reset the global blocks in + * order to clear global attentions. Otherwise + * the gates will remain closed for that + * engine. + */ + if (load_status || + (global && other_load_status)) { + /* + * Wait until all other functions get + * down. + */ + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + return; + } else { + /* + * If all other functions got down + * try to bring the chip back to + * normal. In any case it's an exit + * point for a leader. + */ + if (bxe_leader_reset(sc)) { + BLOGE(sc, "RECOVERY failed, " + "stack notified driver is NOT running!\n"); + sc->recovery_state = BXE_RECOVERY_FAILED; + sc->state = BXE_STATE_ERROR; + mb(); + return; + } + + /* + * If we are here, means that the + * leader has succeeded and doesn't + * want to be a leader any more. Try + * to continue as a none-leader. + */ + break; + } + + } else { /* non-leader */ + if (!bxe_reset_is_done(sc, SC_PATH(sc))) { + /* + * Try to get a LEADER_LOCK HW lock as + * long as a former leader may have + * been unloaded by the user or + * released a leadership by another + * reason. + */ + if (bxe_trylock_leader_lock(sc)) { + /* + * I'm a leader now! Restart a + * switch case. + */ + sc->is_leader = 1; + break; + } + + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + return; + + } else { + /* + * If there was a global attention, wait + * for it to be cleared. + */ + if (bxe_reset_is_global(sc)) { + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); + return; + } + + error_recovered = + sc->eth_stats.recoverable_error; + error_unrecovered = + sc->eth_stats.unrecoverable_error; + BXE_CORE_LOCK(sc); + sc->recovery_state = + BXE_RECOVERY_NIC_LOADING; + if (bxe_nic_load(sc, LOAD_NORMAL)) { + error_unrecovered++; + sc->recovery_state = BXE_RECOVERY_FAILED; + sc->state = BXE_STATE_ERROR; + BLOGE(sc, "Recovery is NOT successfull, " + " state=0x%x recovery_state=0x%x error=%x\n", + sc->state, sc->recovery_state, sc->error_status); + sc->error_status = 0; + } else { + sc->recovery_state = + BXE_RECOVERY_DONE; + error_recovered++; + BLOGI(sc, "Recovery is successfull from errors %x," + " state=0x%x" + " recovery_state=0x%x \n", sc->error_status, + sc->state, sc->recovery_state); + mb(); + } + sc->error_status = 0; + BXE_CORE_UNLOCK(sc); + sc->eth_stats.recoverable_error = + error_recovered; + sc->eth_stats.unrecoverable_error = + error_unrecovered; + + return; + } + } + default: + return; + } + } +} +void +bxe_handle_error(struct bxe_softc * sc) +{ + + if(sc->recovery_state == BXE_RECOVERY_WAIT) { + return; + } + if(sc->error_status) { + if (sc->state == BXE_STATE_OPEN) { + bxe_int_disable(sc); + } + if (sc->link_vars.link_up) { + if_link_state_change(sc->ifnet, LINK_STATE_DOWN); + } + sc->recovery_state = BXE_RECOVERY_INIT; + BLOGI(sc, "bxe%d: Recovery started errors 0x%x recovery state 0x%x\n", + sc->unit, sc->error_status, sc->recovery_state); + bxe_parity_recover(sc); + } +} + +static void +bxe_sp_err_timeout_task(void *arg, int pending) +{ + + struct bxe_softc *sc = (struct bxe_softc *)arg; + + BLOGD(sc, DBG_SP, + "%s state = 0x%x rec state=0x%x error_status=%x\n", + __func__, sc->state, sc->recovery_state, sc->error_status); + + if((sc->recovery_state == BXE_RECOVERY_FAILED) && + (sc->state == BXE_STATE_ERROR)) { + return; + } + /* if can be taken */ + if ((sc->error_status) && (sc->trigger_grcdump)) { + bxe_grc_dump(sc); + } + if (sc->recovery_state != BXE_RECOVERY_DONE) { + bxe_handle_error(sc); + bxe_parity_recover(sc); + } else if (sc->error_status) { + bxe_handle_error(sc); + } + + return; +} + /* start the controller */ static __noinline int bxe_nic_load(struct bxe_softc *sc, @@ -12644,6 +12952,15 @@ bxe_init_locked(struct bxe_softc *sc) return (0); } + if((sc->state == BXE_STATE_ERROR) && + (sc->recovery_state == BXE_RECOVERY_FAILED)) { + BLOGE(sc, "Initialization not done, " + "as previous recovery failed." + "Reboot/Power-cycle the system\n" ); + return (ENXIO); + } + + bxe_set_power_state(sc, PCI_PM_D0); /* @@ -16042,6 +16359,10 @@ bxe_attach(device_t dev) taskqueue_start_threads(&sc->chip_tq, 1, PWAIT, /* lower priority */ "%s", sc->chip_tq_name); + TIMEOUT_TASK_INIT(taskqueue_thread, + &sc->sp_err_timeout_task, 0, bxe_sp_err_timeout_task, sc); + + /* get device info and set params */ if (bxe_get_device_info(sc) != 0) { BLOGE(sc, "getting device info\n"); @@ -16217,6 +16538,8 @@ bxe_detach(device_t dev) taskqueue_drain(sc->chip_tq, &sc->chip_tq_task); taskqueue_free(sc->chip_tq); sc->chip_tq = NULL; + taskqueue_drain_timeout(taskqueue_thread, + &sc->sp_err_timeout_task); } /* stop and reset the controller if it was open */ Modified: stable/9/sys/dev/bxe/bxe.h ============================================================================== --- stable/9/sys/dev/bxe/bxe.h Mon Oct 29 21:46:05 2018 (r339886) +++ stable/9/sys/dev/bxe/bxe.h Mon Oct 29 21:46:12 2018 (r339887) @@ -474,6 +474,10 @@ struct bxe_device_type #define BXE_FW_RX_ALIGN_END (1 << BXE_RX_ALIGN_SHIFT) #define BXE_PXP_DRAM_ALIGN (BXE_RX_ALIGN_SHIFT - 5) /* XXX ??? */ +#define BXE_SET_ERROR_BIT(sc, error) \ +{ \ + (sc)->error_status |= (error); \ +} struct bxe_bar { struct resource *resource; @@ -1387,6 +1391,8 @@ struct bxe_softc { struct taskqueue *chip_tq; char chip_tq_name[32]; + struct timeout_task sp_err_timeout_task; + /* slowpath interrupt taskqueue */ struct task sp_tq_task; struct taskqueue *sp_tq; @@ -1540,6 +1546,16 @@ struct bxe_softc { #define BXE_RECOVERY_WAIT 3 #define BXE_RECOVERY_FAILED 4 #define BXE_RECOVERY_NIC_LOADING 5 + +#define BXE_ERR_TXQ_STUCK 0x1 /* Tx queue stuck detected by driver. */ +#define BXE_ERR_MISC 0x2 /* MISC ERR */ +#define BXE_ERR_PARITY 0x4 /* Parity error detected. */ +#define BXE_ERR_STATS_TO 0x8 /* Statistics timeout detected. */ +#define BXE_ERR_MC_ASSERT 0x10 /* MC assert attention received. */ +#define BXE_ERR_PANIC 0x20 /* Driver asserted. */ +#define BXE_ERR_MCP_ASSERT 0x40 /* MCP assert attention received. No Recovery*/ +#define BXE_ERR_GLOBAL 0x80 /* PCIe/PXP/IGU/MISC/NIG device blocks error- needs PCIe/Fundamental reset */ + uint32_t error_status; uint32_t rx_mode; #define BXE_RX_MODE_NONE 0 Modified: stable/9/sys/dev/bxe/bxe_stats.c ============================================================================== --- stable/9/sys/dev/bxe/bxe_stats.c Mon Oct 29 21:46:05 2018 (r339886) +++ stable/9/sys/dev/bxe/bxe_stats.c Mon Oct 29 21:46:12 2018 (r339887) @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$"); #define BITS_PER_LONG 64 #endif -extern int bxe_grc_dump(struct bxe_softc *sc); static inline long bxe_hilo(uint32_t *hiref) @@ -236,11 +235,11 @@ bxe_stats_comp(struct bxe_softc *sc) while (*stats_comp != DMAE_COMP_VAL) { if (!cnt) { BLOGE(sc, "Timeout waiting for stats finished\n"); - if(sc->trigger_grcdump) { - /* taking grcdump */ - bxe_grc_dump(sc); - } + BXE_SET_ERROR_BIT(sc, BXE_ERR_STATS_TO); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); break; + } cnt--; @@ -923,6 +922,7 @@ bxe_hw_stats_update(struct bxe_softc *sc) nig_timer_max = SHMEM_RD(sc, port_mb[SC_PORT(sc)].stat_nig_timer); if (nig_timer_max != estats->nig_timer_max) { estats->nig_timer_max = nig_timer_max; + /*NOTE: not setting error bit */ BLOGE(sc, "invalid NIG timer max (%u)\n", estats->nig_timer_max); } @@ -1316,12 +1316,10 @@ bxe_stats_update(struct bxe_softc *sc) if (bxe_storm_stats_update(sc)) { if (sc->stats_pending++ == 3) { if (sc->ifnet->if_drv_flags & IFF_DRV_RUNNING) { - if(sc->trigger_grcdump) { - /* taking grcdump */ - bxe_grc_dump(sc); - } - atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_REINIT); - taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task); + BLOGE(sc, "Storm stats not updated for 3 times, resetting\n"); + BXE_SET_ERROR_BIT(sc, BXE_ERR_STATS_TO); + taskqueue_enqueue_timeout(taskqueue_thread, + &sc->sp_err_timeout_task, hz/10); } } return;