An oldie, but I dug it up from the archives to test on my R210 II.
Diff applies (slightly offset) and works just fine. ifconfig bnx now
shows:
media: Ethernet autoselect (1000baseT full-duplex,rxpause,txpause)
For the record, this is a Broadcom BCM5716 (see dmesg posted to misc@
yesterday):
bnx1 at pci1 dev 0 function 1 "Broadcom BCM5716" rev 0x20: apic 0 int 17
Paul 'WEiRD' de Weerd
On Mon, Jun 28, 2010 at 03:34:23PM -0400, Brad wrote:
| Here is an older diff I had to add flow control support to bnx(4)
| which I have dug out and updated to -current src. I have tested
| it with the following adapters and could use some testing with a
| BCM5709 chipset. This supports flow control on all copper adapters
| and BCM5706 with fiber, but not BCM5708/BCM5709 with fiber yet.
|
| bnx0 at pci1 dev 7 function 0 "Broadcom BCM5706" rev 0x02: apic 2 int 16 (irq
12)
| bnx0: address 00:10:18:15:f8:8a
| brgphy1 at bnx0 phy 1: BCM5706 10/100/1000baseT/SX PHY, rev. 2
|
| bnx1 at pci5 dev 0 function 0 "Broadcom BCM5708" rev 0x11: apic 2 int 16 (irq
12)
| bnx1: address 00:10:18:15:fa:3e
| brgphy2 at bnx1 phy 1: BCM5708C 10/100/1000baseT PHY, rev. 5
|
| Please test with any bnx(4) chipsets and provide a dmesg.
|
|
| Index: if_bnx.c
| ===================================================================
| RCS file: /cvs/src/sys/dev/pci/if_bnx.c,v
| retrieving revision 1.88
| diff -u -p -r1.88 if_bnx.c
| --- if_bnx.c 24 May 2010 21:23:23 -0000 1.88
| +++ if_bnx.c 28 Jun 2010 19:15:52 -0000
| @@ -913,6 +913,9 @@ bnx_attachhook(void *xsc)
| /* Look for our PHY. */
| ifmedia_init(&sc->bnx_mii.mii_media, 0, bnx_ifmedia_upd,
| bnx_ifmedia_sts);
| + if (BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5706 ||
| + (!(sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG)))
| + mii_flags |= MIIF_DOPAUSE;
| if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG)
| mii_flags |= MIIF_HAVEFIBER;
| mii_attach(&sc->bnx_dev, &sc->bnx_mii, 0xffffffff,
| @@ -1279,6 +1282,7 @@ bnx_miibus_statchg(struct device *dev)
| {
| struct bnx_softc *sc = (struct bnx_softc *)dev;
| struct mii_data *mii = &sc->bnx_mii;
| + u_int32_t rx_mode = sc->rx_mode;
| int val;
|
| val = REG_RD(sc, BNX_EMAC_MODE);
| @@ -1286,6 +1290,15 @@ bnx_miibus_statchg(struct device *dev)
| 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.
| */
| @@ -1325,6 +1338,34 @@ bnx_miibus_statchg(struct device *dev)
| DBPRINT(sc, BNX_INFO, "Setting Full-Duplex interface.\n");
|
| 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);
| + }
| }
|
|
/****************************************************************************/
| @@ -3954,6 +3995,13 @@ 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);
|
| + /*
| + * Set the level for generating pause frames
| + * when the number of available rx_bd's gets
| + * too low (the low watermark) and the level
| + * when pause frames can be stopped (the high
| + * watermark).
| + */
| if (BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5709) {
| u_int32_t lo_water, hi_water;
|
| @@ -3967,7 +4015,8 @@ bnx_init_rx_context(struct bnx_softc *sc
| hi_water = 0xf;
| else if (hi_water == 0)
| lo_water = 0;
| - val |= lo_water |
| +
| + val |= (lo_water << BNX_L2CTX_RX_LO_WATER_MARK_SHIFT) |
| (hi_water << BNX_L2CTX_RX_HI_WATER_MARK_SHIFT);
| }
|
| @@ -4202,8 +4251,9 @@ bnx_ifmedia_sts(struct ifnet *ifp, struc
| mii = &sc->bnx_mii;
|
| mii_pollstat(mii);
| - ifmr->ifm_active = mii->mii_media_active;
| ifmr->ifm_status = mii->mii_media_status;
| + ifmr->ifm_active = (mii->mii_media_active & ~IFM_ETH_FMASK) |
| + sc->bnx_flowflags;
|
| splx(s);
| }
| @@ -5091,6 +5141,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: if_bnxreg.h
| ===================================================================
| RCS file: /cvs/src/sys/dev/pci/if_bnxreg.h,v
| retrieving revision 1.35
| diff -u -p -r1.35 if_bnxreg.h
| --- if_bnxreg.h 24 May 2010 21:23:23 -0000 1.35
| +++ if_bnxreg.h 28 Jun 2010 19:15:55 -0000
| @@ -4809,6 +4809,8 @@ struct bnx_softc {
| u_int32_t bnx_shared_hw_cfg;
| u_int32_t bnx_port_hw_cfg;
|
| + int bnx_flowflags;
| +
| u_int16_t bus_speed_mhz; /* PCI bus speed */
| struct flash_spec *bnx_flash_info; /* Flash NVRAM settings
*/
| u_int32_t bnx_flash_size; /* Flash NVRAM size */
|
| --
| This message has been scanned for viruses and
| dangerous content by MailScanner, and is
| believed to be clean.
|
--
>++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+
+++++++++++>-]<.>++[<------------>-]<+.--------------.[-]
http://www.weirdnet.nl/