> Please test the following diff if you have a system utilizing the > BCM5709S chipset. This diff adds support for the fiber PHY coupled > with the BCM5709S controller.
This is wrong. Test if you have *any* bnx. When a diff of this nasty complexity and size goes by, noone could give a rats ass if it helps support the new chip. Everyone cares that it doesn't break an existing chipset. If you have a bnx, test it. Report all failures to brad. He might care to hear that it helps new chips, but what he really needs to hear is that it breaks other chips, that people have. Always approach all big diffs like that. We don't care as much if they help new chips people don't have. We care that they don't break things people have lots of. When they break things people have, that is embarrasing because it so preventable. And honestly.. this is a simple diff compared to the others recently floating around. > Index: pci/if_bnx.c > =================================================================== > RCS file: /cvs/src/sys/dev/pci/if_bnx.c,v > retrieving revision 1.86 > diff -u -p -r1.86 if_bnx.c > --- pci/if_bnx.c 23 Nov 2009 10:54:43 -0000 1.86 > +++ pci/if_bnx.c 28 Mar 2010 21:45:11 -0000 > @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD: src/sys/dev/bce/if_b > * BCM5708C B1, B2 > * BCM5708S B1, B2 > * BCM5709C A1, C0 > + * BCM5709S A1, C0 > * BCM5716 C0 > * > * The following controllers are not supported by this driver: > @@ -50,7 +51,7 @@ __FBSDID("$FreeBSD: src/sys/dev/bce/if_b > * BCM5708C A0, B0 > * BCM5708S A0, B0 > * BCM5709C A0 B0, B1, B2 (pre-production) > - * BCM5709S A0, A1, B0, B1, B2, C0 (pre-production) > + * BCM5709S A0, B0, B1, B2 (pre-production) > */ > > #include <dev/pci/if_bnxreg.h> > @@ -340,6 +341,7 @@ int bnx_nvram_write(struct bnx_softc *, > /* > */ > > /****************************************************************************/ > void bnx_get_media(struct bnx_softc *); > +void bnx_init_media(struct bnx_softc *); > int bnx_dma_alloc(struct bnx_softc *); > void bnx_dma_free(struct bnx_softc *); > void bnx_release_resources(struct bnx_softc *); > @@ -905,6 +907,9 @@ bnx_attachhook(void *xsc) > sc->bnx_mii.mii_writereg = bnx_miibus_write_reg; > sc->bnx_mii.mii_statchg = bnx_miibus_statchg; > > + /* Handle any special PHY initialization for SerDes PHYs. */ > + bnx_init_media(sc); > + > /* Look for our PHY. */ > ifmedia_init(&sc->bnx_mii.mii_media, 0, bnx_ifmedia_upd, > bnx_ifmedia_sts); > @@ -1120,6 +1125,16 @@ bnx_miibus_read_reg(struct device *dev, > return(0); > } > > + /* > + * The BCM5709S PHY is an IEEE Clause 45 PHY > + * with special mappings to work with IEEE > + * Clause 22 register accesses. > + */ > + if ((sc->bnx_phy_flags & BNX_PHY_IEEE_CLAUSE_45_FLAG) != 0) { > + if (reg >= MII_BMCR && reg <= MII_ANLPRNP) > + reg += 0x10; > + } > + > if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) { > val = REG_RD(sc, BNX_EMAC_MDIO_MODE); > val &= ~BNX_EMAC_MDIO_MODE_AUTO_POLL; > @@ -1199,6 +1214,16 @@ bnx_miibus_write_reg(struct device *dev, > "val = 0x%04X\n", __FUNCTION__, > phy, (u_int16_t) reg & 0xffff, (u_int16_t) val & 0xffff); > > + /* > + * The BCM5709S PHY is an IEEE Clause 45 PHY > + * with special mappings to work with IEEE > + * Clause 22 register accesses. > + */ > + if ((sc->bnx_phy_flags & BNX_PHY_IEEE_CLAUSE_45_FLAG) != 0) { > + if (reg >= MII_BMCR && reg <= MII_ANLPRNP) > + reg += 0x10; > + } > + > if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) { > val1 = REG_RD(sc, BNX_EMAC_MDIO_MODE); > val1 &= ~BNX_EMAC_MDIO_MODE_AUTO_POLL; > @@ -2179,6 +2204,7 @@ bnx_get_media(struct bnx_softc *sc) > DBPRINT(sc, BNX_INFO_LOAD, > "BCM5709 s/w configured for SerDes.\n"); > sc->bnx_phy_flags |= BNX_PHY_SERDES_FLAG; > + break; > default: > DBPRINT(sc, BNX_INFO_LOAD, > "BCM5709 s/w configured for Copper.\n"); > @@ -2191,6 +2217,7 @@ bnx_get_media(struct bnx_softc *sc) > DBPRINT(sc, BNX_INFO_LOAD, > "BCM5709 s/w configured for SerDes.\n"); > sc->bnx_phy_flags |= BNX_PHY_SERDES_FLAG; > + break; > default: > DBPRINT(sc, BNX_INFO_LOAD, > "BCM5709 s/w configured for Copper.\n"); > @@ -2202,6 +2229,14 @@ bnx_get_media(struct bnx_softc *sc) > > if (sc->bnx_phy_flags && BNX_PHY_SERDES_FLAG) { > sc->bnx_flags |= BNX_NO_WOL_FLAG; > + > + if (BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5709) > + sc->bnx_phy_flags |= BNX_PHY_IEEE_CLAUSE_45_FLAG; > + > + /* > + * The BCM5708S, BCM5709S, and BCM5716S controllers use a > + * separate PHY for SerDes. > + */ > if (BNX_CHIP_NUM(sc) != BNX_CHIP_NUM_5706) { > sc->bnx_phy_addr = 2; > val = REG_RD_IND(sc, sc->bnx_shmem_base + > @@ -2219,6 +2254,36 @@ bnx_get_media(struct bnx_softc *sc) > bnx_get_media_exit: > DBPRINT(sc, (BNX_INFO_LOAD | BNX_INFO_PHY), > "Using PHY address %d.\n", sc->bnx_phy_addr); > +} > + > +/****************************************************************************/ > +/* Performs PHY initialization required before MII drivers access the > */ > +/* device. > */ > +/* > */ > +/* Returns: > */ > +/* Nothing. > */ > +/****************************************************************************/ > +void > +bnx_init_media(struct bnx_softc *sc) > +{ > + if (sc->bnx_phy_flags & BNX_PHY_IEEE_CLAUSE_45_FLAG) { > + /* > + * Configure the BCM5709S / BCM5716S PHYs to use traditional > + * IEEE Clause 22 method. Otherwise we have no way to attach > + * the PHY to the mii(4) layer. PHY specific configuration > + * is done by the mii(4) layer. > + */ > + > + /* Select auto-negotiation MMD of the PHY. */ > + bnx_miibus_write_reg(&sc->bnx_dev, sc->bnx_phy_addr, > + BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT); > + > + bnx_miibus_write_reg(&sc->bnx_dev, sc->bnx_phy_addr, > + BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD); > + > + bnx_miibus_write_reg(&sc->bnx_dev, sc->bnx_phy_addr, > + BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0); > + } > } > > > /****************************************************************************/ > Index: pci/if_bnxreg.h > =================================================================== > RCS file: /cvs/src/sys/dev/pci/if_bnxreg.h,v > retrieving revision 1.34 > diff -u -p -r1.34 if_bnxreg.h > --- pci/if_bnxreg.h 23 Nov 2009 10:54:43 -0000 1.34 > +++ pci/if_bnxreg.h 28 Mar 2010 23:59:31 -0000 > @@ -4803,6 +4803,7 @@ struct bnx_softc { > #define BNX_PHY_INT_MODE_MASK_FLAG 0x300 > #define BNX_PHY_INT_MODE_AUTO_POLLING_FLAG 0x100 > #define BNX_PHY_INT_MODE_LINK_READY_FLAG 0x200 > +#define BNX_PHY_IEEE_CLAUSE_45_FLAG 0x400 > > /* Values that need to be shared with the PHY driver. */ > u_int32_t bnx_shared_hw_cfg; > Index: mii/brgphy.c > =================================================================== > RCS file: /cvs/src/sys/dev/mii/brgphy.c,v > retrieving revision 1.91 > diff -u -p -r1.91 brgphy.c > --- mii/brgphy.c 6 Apr 2010 20:20:52 -0000 1.91 > +++ mii/brgphy.c 7 Apr 2010 00:18:21 -0000 > @@ -81,6 +81,7 @@ int brgphy_service(struct mii_softc *, s > void brgphy_copper_status(struct mii_softc *); > void brgphy_fiber_status(struct mii_softc *); > void brgphy_5708s_status(struct mii_softc *); > +void brgphy_5709s_status(struct mii_softc *); > int brgphy_mii_phy_auto(struct mii_softc *); > void brgphy_loop(struct mii_softc *); > void brgphy_reset(struct mii_softc *); > @@ -108,6 +109,10 @@ const struct mii_phy_funcs brgphy_5708s_ > brgphy_service, brgphy_5708s_status, brgphy_reset, > }; > > +const struct mii_phy_funcs brgphy_5709s_funcs = { > + brgphy_service, brgphy_5709s_status, brgphy_reset, > +}; > + > static const struct mii_phydesc brgphys[] = { > { MII_OUI_xxBROADCOM, MII_MODEL_xxBROADCOM_BCM5400, > MII_STR_xxBROADCOM_BCM5400 }, > @@ -161,6 +166,8 @@ static const struct mii_phydesc brgphys[ > MII_STR_xxBROADCOM2_BCM5708S }, > { MII_OUI_xxBROADCOM2, MII_MODEL_xxBROADCOM2_BCM5709C, > MII_STR_xxBROADCOM2_BCM5709C }, > + { MII_OUI_xxBROADCOM2, MII_MODEL_xxBROADCOM2_BCM5709S, > + MII_STR_xxBROADCOM2_BCM5709S }, > { MII_OUI_xxBROADCOM2, MII_MODEL_xxBROADCOM2_BCM5709CAX, > MII_STR_xxBROADCOM2_BCM5709CAX }, > { MII_OUI_xxBROADCOM3, MII_MODEL_xxBROADCOM3_BCM57780, > @@ -219,6 +226,8 @@ brgphy_attach(struct device *parent, str > if (strcmp(devname, "bnx") == 0) { > if (BNX_CHIP_NUM(bnx_sc) == BNX_CHIP_NUM_5708) > sc->mii_funcs = &brgphy_5708s_funcs; > + else if (BNX_CHIP_NUM(bnx_sc) == BNX_CHIP_NUM_5709) > + sc->mii_funcs = &brgphy_5709s_funcs; > else > sc->mii_funcs = &brgphy_fiber_funcs; > } else > @@ -609,6 +618,64 @@ brgphy_5708s_status(struct mii_softc *sc > mii->mii_media_active = ife->ifm_media; > } > > +void > +brgphy_5709s_status(struct mii_softc *sc) > +{ > + struct mii_data *mii = sc->mii_pdata; > + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; > + int bmcr, bmsr; > + > + mii->mii_media_status = IFM_AVALID; > + mii->mii_media_active = IFM_ETHER; > + > + bmsr = PHY_READ(sc, BRGPHY_MII_BMSR) | PHY_READ(sc, BRGPHY_MII_BMSR); > + if (bmsr & BRGPHY_BMSR_LINK) > + mii->mii_media_status |= IFM_ACTIVE; > + > + bmcr = PHY_READ(sc, BRGPHY_MII_BMCR); > + if (bmcr & BRGPHY_BMCR_LOOP) > + mii->mii_media_active |= IFM_LOOP; > + > + if (bmcr & BRGPHY_BMCR_AUTOEN) { > + int xstat; > + > + if ((bmsr & BRGPHY_BMSR_ACOMP) == 0) { > + /* Erg, still trying, I guess... */ > + mii->mii_media_active |= IFM_NONE; > + return; > + } > + > + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, > + BRGPHY_BLOCK_ADDR_GP_STATUS); > + > + xstat = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS); > + > + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, > + BRGPHY_BLOCK_ADDR_COMBO_IEEE0); > + > + switch (xstat & BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK) { > + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10: > + mii->mii_media_active |= IFM_10_FL; > + break; > + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100: > + mii->mii_media_active |= IFM_100_FX; > + break; > + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G: > + mii->mii_media_active |= IFM_1000_SX; > + break; > + case BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G: > + mii->mii_media_active |= IFM_2500_SX; > + break; > + } > + > + if (xstat & BRGPHY_GP_STATUS_TOP_ANEG_FDX) > + mii->mii_media_active |= IFM_FDX; > + else > + mii->mii_media_active |= IFM_HDX; > + } else > + mii->mii_media_active = ife->ifm_media; > +} > + > int > brgphy_mii_phy_auto(struct mii_softc *sc) > { > @@ -792,6 +859,56 @@ brgphy_reset(struct mii_softc *sc) > PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, > BRGPHY_5708S_DIG_PG0); > } > + } else if (BNX_CHIP_NUM(bnx_sc) == BNX_CHIP_NUM_5709 && > + sc->mii_flags & MIIF_HAVEFIBER) { > + /* Select the SerDes Digital block of the AN MMD. */ > + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, > + BRGPHY_BLOCK_ADDR_SERDES_DIG); > + > + PHY_WRITE(sc, BRGPHY_SERDES_DIG_1000X_CTL1, > + (PHY_READ(sc, BRGPHY_SERDES_DIG_1000X_CTL1) & > + ~BRGPHY_SD_DIG_1000X_CTL1_AUTODET) | > + BRGPHY_SD_DIG_1000X_CTL1_FIBER); > + > + if (bnx_sc->bnx_phy_flags & BNX_PHY_2_5G_CAPABLE_FLAG) { > + /* Select the Over 1G block of the AN MMD. */ > + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, > + BRGPHY_BLOCK_ADDR_OVER_1G); > + > + /* > + * Enable autoneg "Next Page" to advertise > + * 2.5G support. > + */ > + PHY_WRITE(sc, BRGPHY_OVER_1G_UNFORMAT_PG1, > + PHY_READ(sc, BRGPHY_OVER_1G_UNFORMAT_PG1) | > + BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G); > + } > + > + /* > + * Select the Multi-Rate Backplane Ethernet block of > + * the AN MMD. > + */ > + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, > + BRGPHY_BLOCK_ADDR_MRBE); > + > + /* Enable MRBE speed autoneg. */ > + PHY_WRITE(sc, BRGPHY_MRBE_MSG_PG5_NP, > + PHY_READ(sc, BRGPHY_MRBE_MSG_PG5_NP) | > + BRGPHY_MRBE_MSG_PG5_NP_MBRE | > + BRGPHY_MRBE_MSG_PG5_NP_T2); > + > + /* Select the Clause 73 User B0 block of the AN MMD. > */ > + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, > + BRGPHY_BLOCK_ADDR_CL73_USER_B0); > + > + /* Enable MRBE speed autoneg. */ > + PHY_WRITE(sc, BRGPHY_CL73_USER_B0_MBRE_CTL1, > + BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP | > + BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR | > + BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG); > + > + PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, > + BRGPHY_BLOCK_ADDR_COMBO_IEEE0); > } else if (BNX_CHIP_NUM(bnx_sc) == BNX_CHIP_NUM_5709) { > if (BNX_CHIP_REV(bnx_sc) == BNX_CHIP_REV_Ax || > BNX_CHIP_REV(bnx_sc) == BNX_CHIP_REV_Bx) > Index: mii/brgphyreg.h > =================================================================== > RCS file: /cvs/src/sys/dev/mii/brgphyreg.h,v > retrieving revision 1.13 > diff -u -p -r1.13 brgphyreg.h > --- mii/brgphyreg.h 8 Nov 2008 03:03:50 -0000 1.13 > +++ mii/brgphyreg.h 30 Mar 2010 00:16:57 -0000 > @@ -369,6 +369,61 @@ > /* End: PHY register values for the 5708S SerDes PHY */ > /*******************************************************/ > > +/*******************************************************/ > +/* Begin: PHY register values for the 5709S SerDes PHY */ > +/*******************************************************/ > + > +/* 5709S SerDes "General Purpose Status" Registers */ > +#define BRGPHY_BLOCK_ADDR_GP_STATUS 0x8120 > +#define BRGPHY_GP_STATUS_TOP_ANEG_STATUS 0x1B > +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_MASK 0x3F00 > +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_10 0x0000 > +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_100 0x0100 > +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1G 0x0200 > +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_25G 0x0300 > +#define BRGPHY_GP_STATUS_TOP_ANEG_SPEED_1GKX 0x0D00 > +#define BRGPHY_GP_STATUS_TOP_ANEG_FDX 0x0008 > +#define BRGPHY_GP_STATUS_TOP_ANEG_LINK_UP 0x0004 > +#define BRGPHY_GP_STATUS_TOP_ANEG_CL73_COMP 0x0001 > + > +/* 5709S SerDes "SerDes Digital" Registers */ > +#define BRGPHY_BLOCK_ADDR_SERDES_DIG 0x8300 > +#define BRGPHY_SERDES_DIG_1000X_CTL1 0x0010 > +#define BRGPHY_SD_DIG_1000X_CTL1_AUTODET 0x0010 > +#define BRGPHY_SD_DIG_1000X_CTL1_FIBER 0x0001 > + > +/* 5709S SerDes "Over 1G" Registers */ > +#define BRGPHY_BLOCK_ADDR_OVER_1G 0x8320 > +#define BRGPHY_OVER_1G_UNFORMAT_PG1 0x19 > + > +/* 5709S SerDes "Multi-Rate Backplane Ethernet" Registers */ > +#define BRGPHY_BLOCK_ADDR_MRBE 0x8350 > +#define BRGPHY_MRBE_MSG_PG5_NP 0x10 > +#define BRGPHY_MRBE_MSG_PG5_NP_MBRE 0x0001 > +#define BRGPHY_MRBE_MSG_PG5_NP_T2 0x0001 > + > +/* 5709S SerDes "IEEE Clause 73 User B0" Registers */ > +#define BRGPHY_BLOCK_ADDR_CL73_USER_B0 0x8370 > +#define BRGPHY_CL73_USER_B0_MBRE_CTL1 0x12 > +#define BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP 0x2000 > +#define BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR 0x4000 > +#define BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG 0x8000 > + > +/* 5709S SerDes "IEEE Clause 73 User B0" Registers */ > +#define BRGPHY_BLOCK_ADDR_ADDR_EXT 0xFFD0 > + > +/* 5709S SerDes "Combo IEEE 0" Registers */ > +#define BRGPHY_BLOCK_ADDR_COMBO_IEEE0 0xFFE0 > + > +#define BRGPHY_ADDR_EXT 0x1E > +#define BRGPHY_BLOCK_ADDR 0x1F > + > +#define BRGPHY_ADDR_EXT_AN_MMD 0x3800 > + > +/*******************************************************/ > +/* End: PHY register values for the 5709S SerDes PHY */ > +/*******************************************************/ > + > #define BRGPHY_INTRS \ > ~(BRGPHY_IMR_LNK_CHG|BRGPHY_IMR_LSP_CHG|BRGPHY_IMR_DUP_CHG) > > > -- > This message has been scanned for viruses and > dangerous content by MailScanner, and is > believed to be clean.