Re: bnx(4) flow control support.
So we have been running with this diff in the office, and it is working well for us. bnx0 at pci7 dev 0 function 0 Broadcom BCM5709 rev 0x20: apic 0 int 6 bnx0: address 1c:c1:de:e4:5e:b0 brgphy0 at bnx0 phy 1: BCM5709 10/100/1000baseT PHY, rev. 8 As a side note, having TXPAUSE and RXPAUSE enabled, with a seperate interrupt colascing diff makes a significant speed improvement. On 2011 Sep 22 (Thu) at 22:00:22 +0200 (+0200), Paul de Weerd wrote: :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 - 1.88 :| +++ if_bnx.c 28 Jun 2010 19:15:52 - :| @@ -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, 0x, :| @@ -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); :| :| +/* :|
Re: bnx(4) flow control support.
On Thu, Jun 28, 2012 at 16:07 +0200, Peter Hessler wrote: So we have been running with this diff in the office, and it is working well for us. bnx0 at pci7 dev 0 function 0 Broadcom BCM5709 rev 0x20: apic 0 int 6 bnx0: address 1c:c1:de:e4:5e:b0 brgphy0 at bnx0 phy 1: BCM5709 10/100/1000baseT PHY, rev. 8 As a side note, having TXPAUSE and RXPAUSE enabled, with a seperate interrupt colascing diff makes a significant speed improvement. the diff makes sense to me, ok mikeb On 2011 Sep 22 (Thu) at 22:00:22 +0200 (+0200), Paul de Weerd wrote: :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 - 1.88 :| +++ if_bnx.c 28 Jun 2010 19:15:52 - :| @@ -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, 0x, :| @@ -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 :|
Re: bnx(4) flow control support.
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 - 1.88 | +++ if_bnx.c 28 Jun 2010 19:15:52 - | @@ -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, 0x, | @@ -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) |
bnx(4) flow control support.
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.c24 May 2010 21:23:23 - 1.88 +++ if_bnx.c28 Jun 2010 19:15:52 - @@ -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, 0x, @@ -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;