Module Name:    src
Committed By:   msaitoh
Date:           Thu Mar 28 02:50:27 UTC 2019

Modified Files:
        src/sys/dev/pci: if_bnx.c if_bnxvar.h

Log Message:
- 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.


To generate a diff of this commit:
cvs rdiff -u -r1.71 -r1.72 src/sys/dev/pci/if_bnx.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/pci/if_bnxvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_bnx.c
diff -u src/sys/dev/pci/if_bnx.c:1.71 src/sys/dev/pci/if_bnx.c:1.72
--- src/sys/dev/pci/if_bnx.c:1.71	Wed Mar 27 03:37:32 2019
+++ src/sys/dev/pci/if_bnx.c	Thu Mar 28 02:50:27 2019
@@ -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 @@ int	bnx_tx_encap(struct bnx_softc *, str
 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 @@ bnx_attach(device_t parent, device_t sel
 
 	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 @@ bnx_attach(device_t parent, device_t sel
 	/* 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 @@ bnx_miibus_statchg(struct ifnet *ifp)
 {
 	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_miibus_statchg(struct ifnet *ifp)
 	    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 @@ bnx_miibus_statchg(struct ifnet *ifp)
 	}
 
 	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 @@ bnx_free_tx_chain(struct bnx_softc *sc)
 
 	/* 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 @@ bnx_init_rx_context(struct bnx_softc *sc
 	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 @@ bnx_free_rx_chain(struct bnx_softc *sc)
 
 	/* 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 @@ bnx_free_rx_chain(struct bnx_softc *sc)
 }
 
 /****************************************************************************/
+/* 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 @@ bnx_ioctl(struct ifnet *ifp, u_long comm
 		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);

Index: src/sys/dev/pci/if_bnxvar.h
diff -u src/sys/dev/pci/if_bnxvar.h:1.7 src/sys/dev/pci/if_bnxvar.h:1.8
--- src/sys/dev/pci/if_bnxvar.h:1.7	Tue May  8 04:11:09 2018
+++ src/sys/dev/pci/if_bnxvar.h	Thu Mar 28 02:50:27 2019
@@ -149,6 +149,8 @@ struct bnx_softc
 	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 */

Reply via email to