Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci - Remove extra cast (from OpenBSD rev. 1.95)



details:   https://anonhg.NetBSD.org/src/rev/dcce9da35fa3
branches:  trunk
changeset: 449895:dcce9da35fa3
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Thu Mar 28 02:50:27 2019 +0000

description:
- Remove extra cast (from OpenBSD rev. 1.95)
- Add support flow control (from OpenBSD rev. 1.97 and 1.100).
  The main difference between NetBSD and other *BSDs is that the flow control
  does really works. The lower 8bit of BNX_L2CTX_CTX_TYPE should be 0xff
  (from Linux). Note that I have NetXtremeII-PG203-R.pdf and it says the field
  is reserved and should be 0.

diffstat:

 sys/dev/pci/if_bnx.c    |  113 ++++++++++++++++++++++++++++++++++++++---------
 sys/dev/pci/if_bnxvar.h |    2 +
 2 files changed, 93 insertions(+), 22 deletions(-)

diffs (216 lines):

diff -r 3b8ff04013b7 -r dcce9da35fa3 sys/dev/pci/if_bnx.c
--- a/sys/dev/pci/if_bnx.c      Wed Mar 27 22:00:33 2019 +0000
+++ b/sys/dev/pci/if_bnx.c      Thu Mar 28 02:50:27 2019 +0000
@@ -1,5 +1,5 @@
-/*     $NetBSD: if_bnx.c,v 1.71 2019/03/27 03:37:32 msaitoh Exp $      */
-/*     $OpenBSD: if_bnx.c,v 1.94 2011/04/18 04:27:31 dlg Exp $ */
+/*     $NetBSD: if_bnx.c,v 1.72 2019/03/28 02:50:27 msaitoh Exp $      */
+/*     $OpenBSD: if_bnx.c,v 1.100 2013/01/13 05:45:10 brad Exp $ */
 
 /*-
  * Copyright (c) 2006-2010 Broadcom Corporation
@@ -35,7 +35,7 @@
 #if 0
 __FBSDID("$FreeBSD: src/sys/dev/bce/if_bce.c,v 1.3 2006/04/13 14:12:26 ru Exp $");
 #endif
-__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.71 2019/03/27 03:37:32 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.72 2019/03/28 02:50:27 msaitoh Exp $");
 
 /*
  * The following controllers are supported by this driver:
@@ -380,6 +380,7 @@
 void   bnx_start(struct ifnet *);
 int    bnx_ioctl(struct ifnet *, u_long, void *);
 void   bnx_watchdog(struct ifnet *);
+void   bnx_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 int    bnx_init(struct ifnet *);
 
 void   bnx_init_context(struct bnx_softc *);
@@ -819,7 +820,7 @@
 
        sc->bnx_ec.ec_mii = &sc->bnx_mii;
        ifmedia_init(&sc->bnx_mii.mii_media, 0, ether_mediachange,
-           ether_mediastatus);
+           bnx_ifmedia_sts);
 
        /* set phyflags and chipid before mii_attach() */
        dict = device_properties(self);
@@ -831,6 +832,7 @@
        /* Print some useful adapter info */
        bnx_print_adapter_info(sc);
 
+       mii_flags |= MIIF_DOPAUSE;
        if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG)
                mii_flags |= MIIF_HAVEFIBER;
        mii_attach(self, &sc->bnx_mii, 0xffffffff,
@@ -1188,6 +1190,7 @@
 {
        struct bnx_softc        *sc = ifp->if_softc;
        struct mii_data         *mii = &sc->bnx_mii;
+       uint32_t                rx_mode = sc->rx_mode;
        int                     val;
 
        val = REG_RD(sc, BNX_EMAC_MODE);
@@ -1195,6 +1198,15 @@
            BNX_EMAC_MODE_MAC_LOOP | BNX_EMAC_MODE_FORCE_LINK |
            BNX_EMAC_MODE_25G);
 
+       /*
+        * Get flow control negotiation result.
+        */
+       if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
+           (mii->mii_media_active & IFM_ETH_FMASK) != sc->bnx_flowflags) {
+               sc->bnx_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
+               mii->mii_media_active &= ~IFM_ETH_FMASK;
+       }
+
        /* Set MII or GMII interface based on the speed
         * negotiated by the PHY.
         */
@@ -1235,6 +1247,36 @@
        }
 
        REG_WR(sc, BNX_EMAC_MODE, val);
+
+       /*
+        * 802.3x flow control
+        */
+       if (sc->bnx_flowflags & IFM_ETH_RXPAUSE) {
+               DBPRINT(sc, BNX_INFO, "Enabling RX mode flow control.\n");
+               rx_mode |= BNX_EMAC_RX_MODE_FLOW_EN;
+       } else {
+               DBPRINT(sc, BNX_INFO, "Disabling RX mode flow control.\n");
+               rx_mode &= ~BNX_EMAC_RX_MODE_FLOW_EN;
+       }
+
+       if (sc->bnx_flowflags & IFM_ETH_TXPAUSE) {
+               DBPRINT(sc, BNX_INFO, "Enabling TX mode flow control.\n");
+               BNX_SETBIT(sc, BNX_EMAC_TX_MODE, BNX_EMAC_TX_MODE_FLOW_EN);
+       } else {
+               DBPRINT(sc, BNX_INFO, "Disabling TX mode flow control.\n");
+               BNX_CLRBIT(sc, BNX_EMAC_TX_MODE, BNX_EMAC_TX_MODE_FLOW_EN);
+       }
+
+       /* Only make changes if the recive mode has actually changed. */
+       if (rx_mode != sc->rx_mode) {
+               DBPRINT(sc, BNX_VERBOSE, "Enabling new receive mode: 0x%08X\n",
+                   rx_mode);
+
+               sc->rx_mode = rx_mode;
+               REG_WR(sc, BNX_EMAC_RX_MODE, rx_mode);
+
+               bnx_init_rx_context(sc);
+       }
 }
 
 /****************************************************************************/
@@ -4147,7 +4189,7 @@
 
        /* Clear each TX chain page. */
        for (i = 0; i < TX_PAGES; i++) {
-               memset((char *)sc->tx_bd_chain[i], 0, BNX_TX_CHAIN_PAGE_SZ);
+               memset(sc->tx_bd_chain[i], 0, BNX_TX_CHAIN_PAGE_SZ);
                bus_dmamap_sync(sc->bnx_dmatag, sc->tx_bd_chain_map[i], 0,
                    BNX_TX_CHAIN_PAGE_SZ, BUS_DMASYNC_PREWRITE);
        }
@@ -4178,22 +4220,8 @@
        val = BNX_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
                BNX_L2CTX_CTX_TYPE_SIZE_L2 | (0x02 << 8);
 
-       if (BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5709) {
-               uint32_t lo_water, hi_water;
-
-               lo_water = BNX_L2CTX_RX_LO_WATER_MARK_DEFAULT;
-               hi_water = USABLE_RX_BD / 4;
-
-               lo_water /= BNX_L2CTX_RX_LO_WATER_MARK_SCALE;
-               hi_water /= BNX_L2CTX_RX_HI_WATER_MARK_SCALE;
-
-               if (hi_water > 0xf)
-                       hi_water = 0xf;
-               else if (hi_water == 0)
-                       lo_water = 0;
-               val |= lo_water |
-                   (hi_water << BNX_L2CTX_RX_HI_WATER_MARK_SHIFT);
-       }
+       if (sc->bnx_flowflags & IFM_ETH_TXPAUSE)
+               val |= 0x000000ff;
 
        CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_CTX_TYPE, val);
 
@@ -4319,7 +4347,7 @@
 
        /* Clear each RX chain page. */
        for (i = 0; i < RX_PAGES; i++)
-               memset((char *)sc->rx_bd_chain[i], 0, BNX_RX_CHAIN_PAGE_SZ);
+               memset(sc->rx_bd_chain[i], 0, BNX_RX_CHAIN_PAGE_SZ);
 
        sc->free_rx_bd = sc->max_rx_bd;
 
@@ -4333,6 +4361,33 @@
 }
 
 /****************************************************************************/
+/* Reports current media status.                                            */
+/*                                                                          */
+/* Returns:                                                                 */
+/*   Nothing.                                                               */
+/****************************************************************************/
+void
+bnx_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+       struct bnx_softc        *sc;
+       struct mii_data         *mii;
+       int                     s;
+
+       sc = ifp->if_softc;
+
+       s = splnet();
+
+       mii = &sc->bnx_mii;
+
+       mii_pollstat(mii);
+       ifmr->ifm_status = mii->mii_media_status;
+       ifmr->ifm_active = (mii->mii_media_active & ~IFM_ETH_FMASK) |
+           sc->bnx_flowflags;
+
+       splx(s);
+}
+
+/****************************************************************************/
 /* Handles PHY generated interrupt events.                                  */
 /*                                                                          */
 /* Returns:                                                                 */
@@ -5200,6 +5255,20 @@
                break;
 
        case SIOCSIFMEDIA:
+               /* Flow control requires full-duplex mode. */
+               if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
+                   (ifr->ifr_media & IFM_FDX) == 0)
+                       ifr->ifr_media &= ~IFM_ETH_FMASK;
+
+               if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
+                       if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
+                               /* We can do both TXPAUSE and RXPAUSE. */
+                               ifr->ifr_media |=
+                                   IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE;
+                       }
+                       sc->bnx_flowflags = ifr->ifr_media & IFM_ETH_FMASK;
+               }
+               /* FALLTHROUGH */
        case SIOCGIFMEDIA:
                DBPRINT(sc, BNX_VERBOSE, "bnx_phy_flags = 0x%08X\n",
                    sc->bnx_phy_flags);
diff -r 3b8ff04013b7 -r dcce9da35fa3 sys/dev/pci/if_bnxvar.h
--- a/sys/dev/pci/if_bnxvar.h   Wed Mar 27 22:00:33 2019 +0000
+++ b/sys/dev/pci/if_bnxvar.h   Thu Mar 28 02:50:27 2019 +0000
@@ -149,6 +149,8 @@
        uint32_t                bnx_shared_hw_cfg;
        uint32_t                bnx_port_hw_cfg;
 
+       int                     bnx_flowflags;
+       
        uint16_t                bus_speed_mhz;          /* PCI bus speed */
        uint16_t                link_width;             /* PCIe link width */
        uint16_t                link_speed;             /* PCIe link speed */



Home | Main Index | Thread Index | Old Index