> 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.

Reply via email to