svn commit: r235818 - stable/9/sys/dev/bce

YongHyeon PYUN pyunyh at gmail.com
Thu May 24 02:36:59 UTC 2012


On Wed, May 23, 2012 at 10:55:18AM -0700, Adrian Chadd wrote:
> Hi,
> 
> Have you looked at the MDIO bus support that I brought in from Stefan?
> 
> This almost feels like a poster child for that - you'd write an MDIO
> bus driver for this particular mailbox hardware interface and modify
> the driver to use that, then the MDIO bus will automatically probe
> whatever PHYs exist there
> 

I'm not familiar with that code but I don't want to write another
driver just to access a couple of mailbox registers.

> That way it could be reused for other MDIO bus consumers too, such as
> switch PHYs and other MDIO-but-not-quite-PHY devices.

Not sure how well it fits to brgphy(4).

> 
> Adrian
> 
> On 22 May 2012 19:02, Pyun YongHyeon <yongari at freebsd.org> wrote:
> > Author: yongari
> > Date: Wed May 23 02:02:29 2012
> > New Revision: 235818
> > URL: http://svn.freebsd.org/changeset/base/235818
> >
> > Log:
> > ?MFC r235151:
> > ? ?Implement basic remote PHY support. Remote PHY allows the
> > ? ?controller to perform MDIO type accesses to a remote transceiver
> > ? ?using message pages defined through MRBE(multirate backplane
> > ? ?ethernet). ?It's used in blade systems(e.g Dell Blade m610) which
> > ? ?are connected to pass-through blades rather than traditional
> > ? ?switches.
> > ? ?This change directly manipulates firmware's mailboxes to control
> > ? ?remote PHY such that it does not use mii(4). ?Alternatively, as
> > ? ?David said, it could be implemented in brgphy(4) by creating a fake
> > ? ?PHY and let brgphy(4) do necessary mii accesses and bce(4) can
> > ? ?implement mailbox accesses based on the type of brgphy(4)'s mii
> > ? ?accesses. Personally, I think it would make brgphy(4) hard to
> > ? ?maintain since it would have to access many bce(4) registers in
> > ? ?brgphy(4). Given that there are users who are suffering from lack
> > ? ?of remote PHY support, it would be better to get working system
> > ? ?rather than waiting for complete/perfect implementation.
> >
> > Modified:
> > ?stable/9/sys/dev/bce/if_bce.c
> > ?stable/9/sys/dev/bce/if_bcereg.h
> > Directory Properties:
> > ?stable/9/sys/ ? (props changed)
> > ?stable/9/sys/amd64/include/xen/ ? (props changed)
> > ?stable/9/sys/boot/ ? (props changed)
> > ?stable/9/sys/boot/i386/efi/ ? (props changed)
> > ?stable/9/sys/boot/ia64/efi/ ? (props changed)
> > ?stable/9/sys/boot/ia64/ski/ ? (props changed)
> > ?stable/9/sys/boot/powerpc/boot1.chrp/ ? (props changed)
> > ?stable/9/sys/boot/powerpc/ofw/ ? (props changed)
> > ?stable/9/sys/cddl/contrib/opensolaris/ ? (props changed)
> > ?stable/9/sys/conf/ ? (props changed)
> > ?stable/9/sys/contrib/dev/acpica/ ? (props changed)
> > ?stable/9/sys/contrib/octeon-sdk/ ? (props changed)
> > ?stable/9/sys/contrib/pf/ ? (props changed)
> > ?stable/9/sys/contrib/x86emu/ ? (props changed)
> > ?stable/9/sys/dev/ ? (props changed)
> > ?stable/9/sys/dev/e1000/ ? (props changed)
> > ?stable/9/sys/dev/ixgbe/ ? (props changed)
> > ?stable/9/sys/fs/ ? (props changed)
> > ?stable/9/sys/fs/ntfs/ ? (props changed)
> > ?stable/9/sys/modules/ ? (props changed)
> >
> > Modified: stable/9/sys/dev/bce/if_bce.c
> > ==============================================================================
> > --- stable/9/sys/dev/bce/if_bce.c ? ? ? Wed May 23 01:49:50 2012 ? ? ? ?(r235817)
> > +++ stable/9/sys/dev/bce/if_bce.c ? ? ? Wed May 23 02:02:29 2012 ? ? ? ?(r235818)
> > @@ -364,6 +364,7 @@ static int ?bce_nvram_write ? ? ? ? (struct bce
> > ?static void bce_get_rx_buffer_sizes(struct bce_softc *, int);
> > ?static void bce_get_media ? ? ? ? ? ? ? ? ? ? ?(struct bce_softc *);
> > ?static void bce_init_media ? ? ? ? ? ? ? ? ? ? (struct bce_softc *);
> > +static u32 bce_get_rphy_link ? ? ? ? ? (struct bce_softc *);
> > ?static void bce_dma_map_addr ? ? ? ? ? (void *, bus_dma_segment_t *, int, int);
> > ?static int ?bce_dma_alloc ? ? ? ? ? ? ? ? ? ? ?(device_t);
> > ?static void bce_dma_free ? ? ? ? ? ? ? ? ? ? ? (struct bce_softc *);
> > @@ -372,6 +373,7 @@ static void bce_release_resources ? (struc
> > ?/****************************************************************************/
> > ?/* BCE Firmware Synchronization and Load ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
> > ?/****************************************************************************/
> > +static void bce_fw_cap_init ? ? ? ? ? ? ? ? ? ?(struct bce_softc *);
> > ?static int ?bce_fw_sync ? ? ? ? ? ? ? ? ? ? ? ?(struct bce_softc *, u32);
> > ?static void bce_load_rv2p_fw ? ? ? ? ? (struct bce_softc *, u32 *, u32, u32);
> > ?static void bce_load_cpu_fw ? ? ? ? ? ?(struct bce_softc *,
> > @@ -418,6 +420,7 @@ static void bce_watchdog ? ? ? ? ? ? ? ? ? ?(struct bce_s
> > ?static int ?bce_ifmedia_upd ? ? ? ? ? ?(struct ifnet *);
> > ?static int ?bce_ifmedia_upd_locked ? ? (struct ifnet *);
> > ?static void bce_ifmedia_sts ? ? ? ? ? ?(struct ifnet *, struct ifmediareq *);
> > +static void bce_ifmedia_sts_rphy ? ? ? (struct bce_softc *, struct ifmediareq *);
> > ?static void bce_init_locked ? ? ? ? ? ?(struct bce_softc *);
> > ?static void bce_init ? ? ? ? ? ? ? ? ? ? ? ? ? (void *);
> > ?static void bce_mgmt_init_locked ? ? ? (struct bce_softc *sc);
> > @@ -757,6 +760,13 @@ bce_print_adapter_info(struct bce_softc
> > ? ? ? ? ? ? ? ? ? ? ? ?printf("2.5G"); i++;
> > ? ? ? ? ? ? ? ?}
> >
> > + ? ? ? ? ? ? ? if (sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) {
> > + ? ? ? ? ? ? ? ? ? ? ? if (i > 0) printf("|");
> > + ? ? ? ? ? ? ? ? ? ? ? printf("Remote PHY(%s)",
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG ?
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? "FIBER" : "TP"); i++;
> > + ? ? ? ? ? ? ? }
> > +
> > ? ? ? ? ? ? ? ?if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
> > ? ? ? ? ? ? ? ? ? ? ? ?if (i > 0) printf("|");
> > ? ? ? ? ? ? ? ? ? ? ? ?printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
> > @@ -1297,6 +1307,9 @@ bce_attach(device_t dev)
> > ? ? ? ?if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
> > ? ? ? ? ? ? ? ?sc->bce_flags |= BCE_PCI_32BIT_FLAG;
> >
> > + ? ? ? /* Find the media type for the adapter. */
> > + ? ? ? bce_get_media(sc);
> > +
> > ? ? ? ?/* Reset controller and announce to bootcode that driver is present. */
> > ? ? ? ?if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
> > ? ? ? ? ? ? ? ?BCE_PRINTF("%s(%d): Controller reset failed!\n",
> > @@ -1344,9 +1357,6 @@ bce_attach(device_t dev)
> > ? ? ? ?/* Update statistics once every second. */
> > ? ? ? ?sc->bce_stats_ticks = 1000000 & 0xffff00;
> >
> > - ? ? ? /* Find the media type for the adapter. */
> > - ? ? ? bce_get_media(sc);
> > -
> > ? ? ? ?/* Store data needed by PHY driver for backplane applications */
> > ? ? ? ?sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
> > ? ? ? ?sc->bce_port_hw_cfg ? = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
> > @@ -1386,6 +1396,15 @@ bce_attach(device_t dev)
> > ? ? ? ? ? ? ? ?ifp->if_capabilities = BCE_IF_CAPABILITIES;
> > ? ? ? ?}
> >
> > +#if __FreeBSD_version >= 800505
> > + ? ? ? /*
> > + ? ? ? ?* Introducing IFCAP_LINKSTATE didn't bump __FreeBSD_version
> > + ? ? ? ?* so it's approximate value.
> > + ? ? ? ?*/
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
> > + ? ? ? ? ? ? ? ifp->if_capabilities |= IFCAP_LINKSTATE;
> > +#endif
> > +
> > ? ? ? ?ifp->if_capenable = ifp->if_capabilities;
> >
> > ? ? ? ?/*
> > @@ -1409,14 +1428,52 @@ bce_attach(device_t dev)
> > ? ? ? ?/* Handle any special PHY initialization for SerDes PHYs. */
> > ? ? ? ?bce_init_media(sc);
> >
> > - ? ? ? /* MII child bus by attaching the PHY. */
> > - ? ? ? rc = mii_attach(dev, &sc->bce_miibus, ifp, bce_ifmedia_upd,
> > - ? ? ? ? ? bce_ifmedia_sts, BMSR_DEFCAPMASK, sc->bce_phy_addr,
> > - ? ? ? ? ? MII_OFFSET_ANY, MIIF_DOPAUSE);
> > - ? ? ? if (rc != 0) {
> > - ? ? ? ? ? ? ? BCE_PRINTF("%s(%d): attaching PHYs failed\n", __FILE__,
> > - ? ? ? ? ? ? ? ? ? __LINE__);
> > - ? ? ? ? ? ? ? goto bce_attach_fail;
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
> > + ? ? ? ? ? ? ? ifmedia_init(&sc->bce_ifmedia, IFM_IMASK, bce_ifmedia_upd,
> > + ? ? ? ? ? ? ? ? ? bce_ifmedia_sts);
> > + ? ? ? ? ? ? ? /*
> > + ? ? ? ? ? ? ? ?* We can't manually override remote PHY's link and assume
> > + ? ? ? ? ? ? ? ?* PHY port configuration(Fiber or TP) is not changed after
> > + ? ? ? ? ? ? ? ?* device attach. ?This may not be correct though.
> > + ? ? ? ? ? ? ? ?*/
> > + ? ? ? ? ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0) {
> > + ? ? ? ? ? ? ? ? ? ? ? if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_2500_SX, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_2500_SX | IFM_FDX, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? }
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_1000_SX, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_1000_SX | IFM_FDX, 0, NULL);
> > + ? ? ? ? ? ? ? } else {
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_10_T, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_100_TX, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_1000_T, 0, NULL);
> > + ? ? ? ? ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
> > + ? ? ? ? ? ? ? }
> > + ? ? ? ? ? ? ? ifmedia_add(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
> > + ? ? ? ? ? ? ? ifmedia_set(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO);
> > + ? ? ? ? ? ? ? sc->bce_ifmedia.ifm_media = sc->bce_ifmedia.ifm_cur->ifm_media;
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? /* MII child bus by attaching the PHY. */
> > + ? ? ? ? ? ? ? rc = mii_attach(dev, &sc->bce_miibus, ifp, bce_ifmedia_upd,
> > + ? ? ? ? ? ? ? ? ? bce_ifmedia_sts, BMSR_DEFCAPMASK, sc->bce_phy_addr,
> > + ? ? ? ? ? ? ? ? ? MII_OFFSET_ANY, MIIF_DOPAUSE);
> > + ? ? ? ? ? ? ? if (rc != 0) {
> > + ? ? ? ? ? ? ? ? ? ? ? BCE_PRINTF("%s(%d): attaching PHYs failed\n", __FILE__,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? __LINE__);
> > + ? ? ? ? ? ? ? ? ? ? ? goto bce_attach_fail;
> > + ? ? ? ? ? ? ? }
> > ? ? ? ?}
> >
> > ? ? ? ?/* Attach to the Ethernet interface list. */
> > @@ -1521,8 +1578,12 @@ bce_detach(device_t dev)
> > ? ? ? ?ether_ifdetach(ifp);
> >
> > ? ? ? ?/* If we have a child device on the MII bus remove it too. */
> > - ? ? ? bus_generic_detach(dev);
> > - ? ? ? device_delete_child(dev, sc->bce_miibus);
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
> > + ? ? ? ? ? ? ? ifmedia_removeall(&sc->bce_ifmedia);
> > + ? ? ? else {
> > + ? ? ? ? ? ? ? bus_generic_detach(dev);
> > + ? ? ? ? ? ? ? device_delete_child(dev, sc->bce_miibus);
> > + ? ? ? }
> >
> > ? ? ? ?/* Release all remaining resources. */
> > ? ? ? ?bce_release_resources(sc);
> > @@ -1983,13 +2044,23 @@ bce_miibus_statchg(device_t dev)
> > ?{
> > ? ? ? ?struct bce_softc *sc;
> > ? ? ? ?struct mii_data *mii;
> > - ? ? ? int val;
> > + ? ? ? struct ifmediareq ifmr;
> > + ? ? ? int media_active, media_status, val;
> >
> > ? ? ? ?sc = device_get_softc(dev);
> >
> > ? ? ? ?DBENTER(BCE_VERBOSE_PHY);
> >
> > - ? ? ? mii = device_get_softc(sc->bce_miibus);
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
> > + ? ? ? ? ? ? ? bzero(&ifmr, sizeof(ifmr));
> > + ? ? ? ? ? ? ? bce_ifmedia_sts_rphy(sc, &ifmr);
> > + ? ? ? ? ? ? ? media_active = ifmr.ifm_active;
> > + ? ? ? ? ? ? ? media_status = ifmr.ifm_status;
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? mii = device_get_softc(sc->bce_miibus);
> > + ? ? ? ? ? ? ? media_active = mii->mii_media_active;
> > + ? ? ? ? ? ? ? media_status = mii->mii_media_status;
> > + ? ? ? }
> >
> > ? ? ? ?val = REG_RD(sc, BCE_EMAC_MODE);
> > ? ? ? ?val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
> > @@ -1997,7 +2068,7 @@ bce_miibus_statchg(device_t dev)
> > ? ? ? ? ? ?BCE_EMAC_MODE_25G);
> >
> > ? ? ? ?/* Set MII or GMII interface based on the PHY speed. */
> > - ? ? ? switch (IFM_SUBTYPE(mii->mii_media_active)) {
> > + ? ? ? switch (IFM_SUBTYPE(media_active)) {
> > ? ? ? ?case IFM_10_T:
> > ? ? ? ? ? ? ? ?if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
> > ? ? ? ? ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_INFO_PHY,
> > @@ -2026,7 +2097,7 @@ bce_miibus_statchg(device_t dev)
> > ? ? ? ?}
> >
> > ? ? ? ?/* Set half or full duplex based on PHY settings. */
> > - ? ? ? if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) {
> > + ? ? ? if ((IFM_OPTIONS(media_active) & IFM_FDX) == 0) {
> > ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_INFO_PHY,
> > ? ? ? ? ? ? ? ? ? ?"Setting Half-Duplex interface.\n");
> > ? ? ? ? ? ? ? ?val |= BCE_EMAC_MODE_HALF_DUPLEX;
> > @@ -2036,7 +2107,7 @@ bce_miibus_statchg(device_t dev)
> >
> > ? ? ? ?REG_WR(sc, BCE_EMAC_MODE, val);
> >
> > - ? ? ? if ((mii->mii_media_active & IFM_ETH_RXPAUSE) != 0) {
> > + ? ? ? if ((IFM_OPTIONS(media_active) & IFM_ETH_RXPAUSE) != 0) {
> > ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_INFO_PHY,
> > ? ? ? ? ? ? ? ? ? ?"%s(): Enabling RX flow control.\n", __FUNCTION__);
> > ? ? ? ? ? ? ? ?BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
> > @@ -2046,7 +2117,7 @@ bce_miibus_statchg(device_t dev)
> > ? ? ? ? ? ? ? ?BCE_CLRBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
> > ? ? ? ?}
> >
> > - ? ? ? if ((mii->mii_media_active & IFM_ETH_TXPAUSE) != 0) {
> > + ? ? ? if ((IFM_OPTIONS(media_active) & IFM_ETH_TXPAUSE) != 0) {
> > ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_INFO_PHY,
> > ? ? ? ? ? ? ? ? ? ?"%s(): Enabling TX flow control.\n", __FUNCTION__);
> > ? ? ? ? ? ? ? ?BCE_SETBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
> > @@ -3130,7 +3201,8 @@ bce_get_media_exit:
> > ?static void
> > ?bce_init_media(struct bce_softc *sc)
> > ?{
> > - ? ? ? if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
> > + ? ? ? if ((sc->bce_phy_flags & (BCE_PHY_IEEE_CLAUSE_45_FLAG |
> > + ? ? ? ? ? BCE_PHY_REMOTE_CAP_FLAG)) == BCE_PHY_IEEE_CLAUSE_45_FLAG) {
> > ? ? ? ? ? ? ? ?/*
> > ? ? ? ? ? ? ? ? * Configure 5709S/5716S PHYs to use traditional IEEE
> > ? ? ? ? ? ? ? ? * Clause 22 method. Otherwise we have no way to attach
> > @@ -5018,6 +5090,8 @@ bce_reset(struct bce_softc *sc, u32 rese
> > ? ? ? ?if (rc)
> > ? ? ? ? ? ? ? ?BCE_PRINTF("%s(%d): Firmware did not complete "
> > ? ? ? ? ? ? ? ? ? ?"initialization!\n", __FILE__, __LINE__);
> > + ? ? ? /* Get firmware capabilities. */
> > + ? ? ? bce_fw_cap_init(sc);
> >
> > ?bce_reset_exit:
> > ? ? ? ?DBEXIT(BCE_VERBOSE_RESET);
> > @@ -6081,6 +6155,55 @@ bce_free_pg_chain(struct bce_softc *sc)
> > ?}
> >
> >
> > +static u32
> > +bce_get_rphy_link(struct bce_softc *sc)
> > +{
> > + ? ? ? u32 advertise, link;
> > + ? ? ? int fdpx;
> > +
> > + ? ? ? advertise = 0;
> > + ? ? ? fdpx = 0;
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0)
> > + ? ? ? ? ? ? ? link = bce_shmem_rd(sc, BCE_RPHY_SERDES_LINK);
> > + ? ? ? else
> > + ? ? ? ? ? ? ? link = bce_shmem_rd(sc, BCE_RPHY_COPPER_LINK);
> > + ? ? ? if (link & BCE_NETLINK_ANEG_ENB)
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_ANEG_ENB;
> > + ? ? ? if (link & BCE_NETLINK_SPEED_10HALF)
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_10HALF;
> > + ? ? ? if (link & BCE_NETLINK_SPEED_10FULL) {
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_10FULL;
> > + ? ? ? ? ? ? ? fdpx++;
> > + ? ? ? }
> > + ? ? ? if (link & BCE_NETLINK_SPEED_100HALF)
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_100HALF;
> > + ? ? ? if (link & BCE_NETLINK_SPEED_100FULL) {
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_100FULL;
> > + ? ? ? ? ? ? ? fdpx++;
> > + ? ? ? }
> > + ? ? ? if (link & BCE_NETLINK_SPEED_1000HALF)
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_1000HALF;
> > + ? ? ? if (link & BCE_NETLINK_SPEED_1000FULL) {
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_1000FULL;
> > + ? ? ? ? ? ? ? fdpx++;
> > + ? ? ? }
> > + ? ? ? if (link & BCE_NETLINK_SPEED_2500HALF)
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_2500HALF;
> > + ? ? ? if (link & BCE_NETLINK_SPEED_2500FULL) {
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_SPEED_2500FULL;
> > + ? ? ? ? ? ? ? fdpx++;
> > + ? ? ? }
> > + ? ? ? if (fdpx)
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_FC_PAUSE_SYM |
> > + ? ? ? ? ? ? ? ? ? BCE_NETLINK_FC_PAUSE_ASYM;
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
> > + ? ? ? ? ? ? ? advertise |= BCE_NETLINK_PHY_APP_REMOTE |
> > + ? ? ? ? ? ? ? ? ? BCE_NETLINK_ETH_AT_WIRESPEED;
> > +
> > + ? ? ? return (advertise);
> > +}
> > +
> > +
> > ?/****************************************************************************/
> > ?/* Set media options. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
> > ?/* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
> > @@ -6116,21 +6239,110 @@ bce_ifmedia_upd_locked(struct ifnet *ifp
> > ? ? ? ?struct bce_softc *sc = ifp->if_softc;
> > ? ? ? ?struct mii_data *mii;
> > ? ? ? ?struct mii_softc *miisc;
> > - ? ? ? int error;
> > + ? ? ? struct ifmedia *ifm;
> > + ? ? ? u32 link;
> > + ? ? ? int error, fdx;
> >
> > ? ? ? ?DBENTER(BCE_VERBOSE_PHY);
> >
> > ? ? ? ?error = 0;
> > ? ? ? ?BCE_LOCK_ASSERT(sc);
> >
> > - ? ? ? mii = device_get_softc(sc->bce_miibus);
> > + ? ? ? sc->bce_link_up = FALSE;
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
> > + ? ? ? ? ? ? ? ifm = &sc->bce_ifmedia;
> > + ? ? ? ? ? ? ? if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
> > + ? ? ? ? ? ? ? ? ? ? ? return (EINVAL);
> > + ? ? ? ? ? ? ? link = 0;
> > + ? ? ? ? ? ? ? fdx = IFM_OPTIONS(ifm->ifm_media) & IFM_FDX;
> > + ? ? ? ? ? ? ? switch(IFM_SUBTYPE(ifm->ifm_media)) {
> > + ? ? ? ? ? ? ? case IFM_AUTO:
> > + ? ? ? ? ? ? ? ? ? ? ? /*
> > + ? ? ? ? ? ? ? ? ? ? ? ?* Check advertised link of remote PHY by reading
> > + ? ? ? ? ? ? ? ? ? ? ? ?* BCE_RPHY_SERDES_LINK or BCE_RPHY_COPPER_LINK.
> > + ? ? ? ? ? ? ? ? ? ? ? ?* Always use the same link type of remote PHY.
> > + ? ? ? ? ? ? ? ? ? ? ? ?*/
> > + ? ? ? ? ? ? ? ? ? ? ? link = bce_get_rphy_link(sc);
> > + ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? case IFM_2500_SX:
> > + ? ? ? ? ? ? ? ? ? ? ? if ((sc->bce_phy_flags &
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? (BCE_PHY_REMOTE_PORT_FIBER_FLAG |
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? BCE_PHY_2_5G_CAPABLE_FLAG)) == 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return (EINVAL);
> > + ? ? ? ? ? ? ? ? ? ? ? /*
> > + ? ? ? ? ? ? ? ? ? ? ? ?* XXX
> > + ? ? ? ? ? ? ? ? ? ? ? ?* Have to enable forced 2.5Gbps configuration.
> > + ? ? ? ? ? ? ? ? ? ? ? ?*/
> > + ? ? ? ? ? ? ? ? ? ? ? if (fdx != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link |= BCE_NETLINK_SPEED_2500FULL;
> > + ? ? ? ? ? ? ? ? ? ? ? else
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link |= BCE_NETLINK_SPEED_2500HALF;
> > + ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? case IFM_1000_SX:
> > + ? ? ? ? ? ? ? ? ? ? ? if ((sc->bce_phy_flags &
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return (EINVAL);
> > + ? ? ? ? ? ? ? ? ? ? ? /*
> > + ? ? ? ? ? ? ? ? ? ? ? ?* XXX
> > + ? ? ? ? ? ? ? ? ? ? ? ?* Have to disable 2.5Gbps configuration.
> > + ? ? ? ? ? ? ? ? ? ? ? ?*/
> > + ? ? ? ? ? ? ? ? ? ? ? if (fdx != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_1000FULL;
> > + ? ? ? ? ? ? ? ? ? ? ? else
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_1000HALF;
> > + ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? case IFM_1000_T:
> > + ? ? ? ? ? ? ? ? ? ? ? if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return (EINVAL);
> > + ? ? ? ? ? ? ? ? ? ? ? if (fdx != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_1000FULL;
> > + ? ? ? ? ? ? ? ? ? ? ? else
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_1000HALF;
> > + ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? case IFM_100_TX:
> > + ? ? ? ? ? ? ? ? ? ? ? if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return (EINVAL);
> > + ? ? ? ? ? ? ? ? ? ? ? if (fdx != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_100FULL;
> > + ? ? ? ? ? ? ? ? ? ? ? else
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_100HALF;
> > + ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? case IFM_10_T:
> > + ? ? ? ? ? ? ? ? ? ? ? if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return (EINVAL);
> > + ? ? ? ? ? ? ? ? ? ? ? if (fdx != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_10FULL;
> > + ? ? ? ? ? ? ? ? ? ? ? else
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link = BCE_NETLINK_SPEED_10HALF;
> > + ? ? ? ? ? ? ? ? ? ? ? break;
> > + ? ? ? ? ? ? ? default:
> > + ? ? ? ? ? ? ? ? ? ? ? return (EINVAL);
> > + ? ? ? ? ? ? ? }
> > + ? ? ? ? ? ? ? if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO) {
> > + ? ? ? ? ? ? ? ? ? ? ? /*
> > + ? ? ? ? ? ? ? ? ? ? ? ?* XXX
> > + ? ? ? ? ? ? ? ? ? ? ? ?* Advertise pause capability for full-duplex media.
> > + ? ? ? ? ? ? ? ? ? ? ? ?*/
> > + ? ? ? ? ? ? ? ? ? ? ? if (fdx != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link |= BCE_NETLINK_FC_PAUSE_SYM |
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BCE_NETLINK_FC_PAUSE_ASYM;
> > + ? ? ? ? ? ? ? ? ? ? ? if ((sc->bce_phy_flags &
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? link |= BCE_NETLINK_PHY_APP_REMOTE |
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BCE_NETLINK_ETH_AT_WIRESPEED;
> > + ? ? ? ? ? ? ? }
> >
> > - ? ? ? /* Make sure the MII bus has been enumerated. */
> > - ? ? ? if (mii) {
> > - ? ? ? ? ? ? ? sc->bce_link_up = FALSE;
> > - ? ? ? ? ? ? ? LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
> > - ? ? ? ? ? ? ? ? ? PHY_RESET(miisc);
> > - ? ? ? ? ? ? ? error = mii_mediachg(mii);
> > + ? ? ? ? ? ? ? bce_shmem_wr(sc, BCE_MB_ARGS_0, link);
> > + ? ? ? ? ? ? ? error = bce_fw_sync(sc, BCE_DRV_MSG_CODE_CMD_SET_LINK);
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? mii = device_get_softc(sc->bce_miibus);
> > +
> > + ? ? ? ? ? ? ? /* Make sure the MII bus has been enumerated. */
> > + ? ? ? ? ? ? ? if (mii) {
> > + ? ? ? ? ? ? ? ? ? ? ? LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PHY_RESET(miisc);
> > + ? ? ? ? ? ? ? ? ? ? ? error = mii_mediachg(mii);
> > + ? ? ? ? ? ? ? }
> > ? ? ? ?}
> >
> > ? ? ? ?DBEXIT(BCE_VERBOSE_PHY);
> > @@ -6138,6 +6350,85 @@ bce_ifmedia_upd_locked(struct ifnet *ifp
> > ?}
> >
> >
> > +static void
> > +bce_ifmedia_sts_rphy(struct bce_softc *sc, struct ifmediareq *ifmr)
> > +{
> > + ? ? ? struct ifnet *ifp;
> > + ? ? ? u32 link;
> > +
> > + ? ? ? ifp = sc->bce_ifp;
> > + ? ? ? BCE_LOCK_ASSERT(sc);
> > +
> > + ? ? ? ifmr->ifm_status = IFM_AVALID;
> > + ? ? ? ifmr->ifm_active = IFM_ETHER;
> > + ? ? ? link = bce_shmem_rd(sc, BCE_LINK_STATUS);
> > + ? ? ? /* XXX Handle heart beat status? */
> > + ? ? ? if ((link & BCE_LINK_STATUS_LINK_UP) != 0)
> > + ? ? ? ? ? ? ? ifmr->ifm_status |= IFM_ACTIVE;
> > + ? ? ? else {
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_NONE;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = 0;
> > + ? ? ? ? ? ? ? return;
> > + ? ? ? }
> > + ? ? ? switch (link & BCE_LINK_STATUS_SPEED_MASK) {
> > + ? ? ? case BCE_LINK_STATUS_10HALF:
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_10_T | IFM_HDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(10UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? case BCE_LINK_STATUS_10FULL:
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_10_T | IFM_FDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(10UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? case BCE_LINK_STATUS_100HALF:
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_100_TX | IFM_HDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(100UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? case BCE_LINK_STATUS_100FULL:
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(100UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? case BCE_LINK_STATUS_1000HALF:
> > + ? ? ? ? ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_1000_T | IFM_HDX;
> > + ? ? ? ? ? ? ? else
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_1000_SX | IFM_HDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(1000UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? case BCE_LINK_STATUS_1000FULL:
> > + ? ? ? ? ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
> > + ? ? ? ? ? ? ? else
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(1000UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? case BCE_LINK_STATUS_2500HALF:
> > + ? ? ? ? ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_NONE;
> > + ? ? ? ? ? ? ? ? ? ? ? return;
> > + ? ? ? ? ? ? ? } else
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_2500_SX | IFM_HDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(2500UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? case BCE_LINK_STATUS_2500FULL:
> > + ? ? ? ? ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_NONE;
> > + ? ? ? ? ? ? ? ? ? ? ? return;
> > + ? ? ? ? ? ? ? } else
> > + ? ? ? ? ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_2500_SX | IFM_FDX;
> > + ? ? ? ? ? ? ? ifp->if_baudrate = IF_Mbps(2500UL);
> > + ? ? ? ? ? ? ? break;
> > + ? ? ? default:
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_NONE;
> > + ? ? ? ? ? ? ? return;
> > + ? ? ? }
> > +
> > + ? ? ? if ((link & BCE_LINK_STATUS_RX_FC_ENABLED) != 0)
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_ETH_RXPAUSE;
> > + ? ? ? if ((link & BCE_LINK_STATUS_TX_FC_ENABLED) != 0)
> > + ? ? ? ? ? ? ? ifmr->ifm_active |= IFM_ETH_TXPAUSE;
> > +}
> > +
> > +
> > ?/****************************************************************************/
> > ?/* Reports current media status. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
> > ?/* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
> > @@ -6158,11 +6449,15 @@ bce_ifmedia_sts(struct ifnet *ifp, struc
> > ? ? ? ? ? ? ? ?BCE_UNLOCK(sc);
> > ? ? ? ? ? ? ? ?return;
> > ? ? ? ?}
> > - ? ? ? mii = device_get_softc(sc->bce_miibus);
> >
> > - ? ? ? mii_pollstat(mii);
> > - ? ? ? ifmr->ifm_active = mii->mii_media_active;
> > - ? ? ? ifmr->ifm_status = mii->mii_media_status;
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
> > + ? ? ? ? ? ? ? bce_ifmedia_sts_rphy(sc, ifmr);
> > + ? ? ? else {
> > + ? ? ? ? ? ? ? mii = device_get_softc(sc->bce_miibus);
> > + ? ? ? ? ? ? ? mii_pollstat(mii);
> > + ? ? ? ? ? ? ? ifmr->ifm_active = mii->mii_media_active;
> > + ? ? ? ? ? ? ? ifmr->ifm_status = mii->mii_media_status;
> > + ? ? ? }
> >
> > ? ? ? ?BCE_UNLOCK(sc);
> >
> > @@ -6199,14 +6494,26 @@ bce_phy_intr(struct bce_softc *sc)
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ?STATUS_ATTN_BITS_LINK_STATE);
> > ? ? ? ? ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ?__FUNCTION__);
> > - ? ? ? ? ? ? ? }
> > - ? ? ? ? ? ? ? else {
> > + ? ? ? ? ? ? ? } else {
> > ? ? ? ? ? ? ? ? ? ? ? ?REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ?STATUS_ATTN_BITS_LINK_STATE);
> > ? ? ? ? ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ?__FUNCTION__);
> > ? ? ? ? ? ? ? ?}
> >
> > + ? ? ? ? ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
> > + ? ? ? ? ? ? ? ? ? ? ? if (new_link_state) {
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (bootverbose)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if_printf(sc->bce_ifp, "link UP\n");
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if_link_state_change(sc->bce_ifp,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LINK_STATE_UP);
> > + ? ? ? ? ? ? ? ? ? ? ? } else {
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (bootverbose)
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if_printf(sc->bce_ifp, "link DOWN\n");
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if_link_state_change(sc->bce_ifp,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LINK_STATE_DOWN);
> > + ? ? ? ? ? ? ? ? ? ? ? }
> > + ? ? ? ? ? ? ? }
> > ? ? ? ? ? ? ? ?/*
> > ? ? ? ? ? ? ? ? * Assume link is down and allow
> > ? ? ? ? ? ? ? ? * tick routine to update the state
> > @@ -7495,10 +7802,14 @@ bce_ioctl(struct ifnet *ifp, u_long comm
> > ? ? ? ?case SIOCGIFMEDIA:
> > ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_VERBOSE_MISC,
> > ? ? ? ? ? ? ? ? ? ?"Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
> > -
> > - ? ? ? ? ? ? ? mii = device_get_softc(sc->bce_miibus);
> > - ? ? ? ? ? ? ? error = ifmedia_ioctl(ifp, ifr,
> > - ? ? ? ? ? ? ? ? ? &mii->mii_media, command);
> > + ? ? ? ? ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? error = ifmedia_ioctl(ifp, ifr, &sc->bce_ifmedia,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? command);
> > + ? ? ? ? ? ? ? else {
> > + ? ? ? ? ? ? ? ? ? ? ? mii = device_get_softc(sc->bce_miibus);
> > + ? ? ? ? ? ? ? ? ? ? ? error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? command);
> > + ? ? ? ? ? ? ? }
> > ? ? ? ? ? ? ? ?break;
> >
> > ? ? ? ?/* Set interface capability */
> > @@ -8163,6 +8474,7 @@ bce_tick(void *xsc)
> > ? ? ? ?struct bce_softc *sc = xsc;
> > ? ? ? ?struct mii_data *mii;
> > ? ? ? ?struct ifnet *ifp;
> > + ? ? ? struct ifmediareq ifmr;
> >
> > ? ? ? ?ifp = sc->bce_ifp;
> >
> > @@ -8193,21 +8505,32 @@ bce_tick(void *xsc)
> > ? ? ? ? ? ? ? ?goto bce_tick_exit;
> >
> > ? ? ? ?/* Link is down. ?Check what the PHY's doing. */
> > - ? ? ? mii = device_get_softc(sc->bce_miibus);
> > - ? ? ? mii_tick(mii);
> > -
> > - ? ? ? /* Check if the link has come up. */
> > - ? ? ? if ((mii->mii_media_status & IFM_ACTIVE) &&
> > - ? ? ? ? ? (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
> > - ? ? ? ? ? ? ? DBPRINT(sc, BCE_VERBOSE_MISC,
> > - ? ? ? ? ? ? ? ? ? "%s(): Link up!\n", __FUNCTION__);
> > - ? ? ? ? ? ? ? sc->bce_link_up = TRUE;
> > - ? ? ? ? ? ? ? if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
> > - ? ? ? ? ? ? ? ? ? IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
> > - ? ? ? ? ? ? ? ? ? IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
> > - ? ? ? ? ? ? ? ? ? (bce_verbose || bootverbose))
> > - ? ? ? ? ? ? ? ? ? ? ? BCE_PRINTF("Gigabit link up!\n");
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
> > + ? ? ? ? ? ? ? bzero(&ifmr, sizeof(ifmr));
> > + ? ? ? ? ? ? ? bce_ifmedia_sts_rphy(sc, &ifmr);
> > + ? ? ? ? ? ? ? if ((ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) ==
> > + ? ? ? ? ? ? ? ? ? (IFM_ACTIVE | IFM_AVALID)) {
> > + ? ? ? ? ? ? ? ? ? ? ? sc->bce_link_up = TRUE;
> > + ? ? ? ? ? ? ? ? ? ? ? bce_miibus_statchg(sc->bce_dev);
> > + ? ? ? ? ? ? ? }
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? mii = device_get_softc(sc->bce_miibus);
> > + ? ? ? ? ? ? ? mii_tick(mii);
> > + ? ? ? ? ? ? ? /* Check if the link has come up. */
> > + ? ? ? ? ? ? ? if ((mii->mii_media_status & IFM_ACTIVE) &&
> > + ? ? ? ? ? ? ? ? ? (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
> > + ? ? ? ? ? ? ? ? ? ? ? DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n",
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? __FUNCTION__);
> > + ? ? ? ? ? ? ? ? ? ? ? sc->bce_link_up = TRUE;
> > + ? ? ? ? ? ? ? ? ? ? ? if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? (bce_verbose || bootverbose))
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BCE_PRINTF("Gigabit link up!\n");
> > + ? ? ? ? ? ? ? }
> >
> > + ? ? ? }
> > + ? ? ? if (sc->bce_link_up == TRUE) {
> > ? ? ? ? ? ? ? ?/* Now that link is up, handle any outstanding TX traffic. */
> > ? ? ? ? ? ? ? ?if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
> > ? ? ? ? ? ? ? ? ? ? ? ?DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
> > @@ -8221,6 +8544,36 @@ bce_tick_exit:
> > ? ? ? ?return;
> > ?}
> >
> > +static void
> > +bce_fw_cap_init(struct bce_softc *sc)
> > +{
> > + ? ? ? u32 ack, cap, link;
> > +
> > + ? ? ? ack = 0;
> > + ? ? ? cap = bce_shmem_rd(sc, BCE_FW_CAP_MB);
> > + ? ? ? if ((cap & BCE_FW_CAP_SIGNATURE_MAGIC_MASK) !=
> > + ? ? ? ? ? BCE_FW_CAP_SIGNATURE_MAGIC)
> > + ? ? ? ? ? ? ? return;
> > + ? ? ? if ((cap & (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN)) ==
> > + ? ? ? ? ? (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN))
> > + ? ? ? ? ? ? ? ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
> > + ? ? ? ? ? ? ? ? ? BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN;
> > + ? ? ? if ((sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) != 0 &&
> > + ? ? ? ? ? (cap & BCE_FW_CAP_REMOTE_PHY_CAP) != 0) {
> > + ? ? ? ? ? ? ? sc->bce_phy_flags &= ~BCE_PHY_REMOTE_PORT_FIBER_FLAG;
> > + ? ? ? ? ? ? ? sc->bce_phy_flags |= BCE_PHY_REMOTE_CAP_FLAG;
> > + ? ? ? ? ? ? ? link = bce_shmem_rd(sc, BCE_LINK_STATUS);
> > + ? ? ? ? ? ? ? if ((link & BCE_LINK_STATUS_SERDES_LINK) != 0)
> > + ? ? ? ? ? ? ? ? ? ? ? sc->bce_phy_flags |= BCE_PHY_REMOTE_PORT_FIBER_FLAG;
> > + ? ? ? ? ? ? ? ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
> > + ? ? ? ? ? ? ? ? ? BCE_FW_CAP_REMOTE_PHY_CAP;
> > + ? ? ? }
> > +
> > + ? ? ? if (ack != 0)
> > + ? ? ? ? ? ? ? bce_shmem_wr(sc, BCE_DRV_ACK_CAP_MB, ack);
> > +}
> > +
> > +
> > ?#ifdef BCE_DEBUG
> > ?/****************************************************************************/
> > ?/* Allows the driver state to be dumped through the sysctl interface. ? ? ? */
> >
> > Modified: stable/9/sys/dev/bce/if_bcereg.h
> > ==============================================================================
> > --- stable/9/sys/dev/bce/if_bcereg.h ? ?Wed May 23 01:49:50 2012 ? ? ? ?(r235817)
> > +++ stable/9/sys/dev/bce/if_bcereg.h ? ?Wed May 23 02:02:29 2012 ? ? ? ?(r235818)
> > @@ -814,6 +814,23 @@ struct flash_spec {
> > ?#define BCE_DRV_PULSE_SEQ_MASK ? ? ? ? ? ? ? ? ?0x00007fff
> >
> > ?#define BCE_MB_ARGS_0 ? ? ? ? ? ? ? ? ? ? ? ? ?0x00000014
> > +#define ? ? ? ?BCE_NETLINK_SPEED_10HALF ? ? ? ? ? ? ? ? (1<<0)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_10FULL ? ? ? ? ? ? ? ? (1<<1)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_100HALF ? ? ? ? ? ? ? ?(1<<2)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_100FULL ? ? ? ? ? ? ? ?(1<<3)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_1000HALF ? ? ? ? ? ? ? (1<<4)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_1000FULL ? ? ? ? ? ? ? (1<<5)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_2500HALF ? ? ? ? ? ? ? (1<<6)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_2500FULL ? ? ? ? ? ? ? (1<<7)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_10GHALF ? ? ? ? ? ? ? ?(1<<8)
> > +#define ? ? ? ?BCE_NETLINK_SPEED_10GFULL ? ? ? ? ? ? ? ?(1<<9)
> > +#define ? ? ? ?BCE_NETLINK_ANEG_ENB ? ? ? ? ? ? ? ? ? ? (1<<10)
> > +#define ? ? ? ?BCE_NETLINK_PHY_APP_REMOTE ? ? ? ? ? ? ? (1<<11)
> > +#define ? ? ? ?BCE_NETLINK_FC_PAUSE_SYM ? ? ? ? ? ? ? ? (1<<12)
> > +#define ? ? ? ?BCE_NETLINK_FC_PAUSE_ASYM ? ? ? ? ? ? ? ?(1<<13)
> > +#define ? ? ? ?BCE_NETLINK_ETH_AT_WIRESPEED ? ? ? ? ? ? (1<<14)
> > +#define ? ? ? ?BCE_NETLINK_PHY_RESET ? ? ? ? ? ? ? ? ? ?(1<<15)
> > +
> > ?#define BCE_MB_ARGS_1 ? ? ? ? ? ? ? ? ? ? ? ? ?0x00000018
> >
> > ?/* Indicate to the firmware not to go into the
> > @@ -1079,6 +1096,26 @@ struct flash_spec {
> > ?#define BCE_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK ?0xffff
> > ?#define BCE_BC_STATE_BC_DBG_CMD_LOOP_INFINITE ?0xffff
> >
> > +#define ? ? ? ?BCE_FW_EVT_CODE_MB ? ? ? ? ? ? ? ? ? ? ?0x00000354
> > +#define ? ? ? ?BCE_FW_EVT_CODE_SW_TIMER_EXPIRE_EVENT ? 0x00000000
> > +#define ? ? ? ?BCE_FW_EVT_CODE_LINK_EVENT ? ? ? ? ? ? ?0x00000001
> > +
> > +#define ? ? ? ?BCE_DRV_ACK_CAP_MB ? ? ? ? ? ? ? ? ? ? ?0x00000364
> > +#define ? ? ? ?BCE_DRV_ACK_CAP_SIGNATURE_MAGIC ? ? ? ? 0x35450000
> > +
> > +#define ? ? ? ?BCE_FW_CAP_MB ? ? ? ? ? ? ? ? ? ? ? ? ? 0x00000368
> > +#define ? ? ? ?BCE_FW_CAP_SIGNATURE_MAGIC ? ? ? ? ? ? ?0xaa550000
> > +#define ? ? ? ?BCE_FW_ACK_SIGNATURE_MAGIC ? ? ? ? ? ? ?0x52500000
> > +#define ? ? ? ?BCE_FW_CAP_SIGNATURE_MAGIC_MASK ? ? ? ? 0xffff0000
> > +#define ? ? ? ?BCE_FW_CAP_REMOTE_PHY_CAP ? ? ? ? ? ? ? 0x00000001
> > +#define ? ? ? ?BCE_FW_CAP_REMOTE_PHY_PRESENT ? ? ? ? ? 0x00000002
> > +#define ? ? ? ?BCE_FW_CAP_MFW_KEEP_VLAN ? ? ? ? ? ? ? ?0x00000008
> > +#define ? ? ? ?BCE_FW_CAP_BC_KEEP_VLAN ? ? ? ? ? ? ? ? 0x00000010
> > +
> > +#define ? ? ? ?BCE_RPHY_SERDES_LINK ? ? ? ? ? ? ? ? ? ?0x00000374
> > +
> > +#define ? ? ? ?BCE_RPHY_COPPER_LINK ? ? ? ? ? ? ? ? ? ?0x00000378
> > +
> > ?#define HOST_VIEW_SHMEM_BASE ? ? ? ? ? ? ? ? ? 0x167c00
> >
> > ?/*
> > @@ -6454,6 +6491,8 @@ struct bce_softc
> > ?#define BCE_PHY_INT_MODE_AUTO_POLLING_FLAG ? ? 0x00000100
> > ?#define BCE_PHY_INT_MODE_LINK_READY_FLAG ? ? ? 0x00000200
> > ?#define BCE_PHY_IEEE_CLAUSE_45_FLAG ? ? ? ? ? ?0x00000400
> > +#define ? ? ? ?BCE_PHY_REMOTE_CAP_FLAG ? ? ? ? ? ? ? ? 0x00000800
> > +#define ? ? ? ?BCE_PHY_REMOTE_PORT_FIBER_FLAG ? ? ? ? ?0x00001000
> >
> > ? ? ? ?/* Values that need to be shared with the PHY driver. */
> > ? ? ? ?u32 ? ? ? ? ? ? ? ? ? ? bce_shared_hw_cfg;
> 


More information about the svn-src-all mailing list