static int rlphy_attach(device_t dev) { /* * The RealTek PHY can never be isolated. */ mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, &rlphy_funcs, 1); return (0); }
static int e1000phy_attach(device_t dev) { struct mii_softc *sc; struct ifnet *ifp; sc = device_get_softc(dev); mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &e1000phy_funcs, 0); ifp = sc->mii_pdata->mii_ifp; if (strcmp(ifp->if_dname, "msk") == 0 && (sc->mii_flags & MIIF_MACPRIV0) != 0) sc->mii_flags |= MIIF_PHYPRIV0; switch (sc->mii_mpd_model) { case MII_MODEL_xxMARVELL_E1011: case MII_MODEL_xxMARVELL_E1112: if (PHY_READ(sc, E1000_ESSR) & E1000_ESSR_FIBER_LINK) sc->mii_flags |= MIIF_HAVEFIBER; break; case MII_MODEL_xxMARVELL_E1149: case MII_MODEL_xxMARVELL_E1149R: /* * Some 88E1149 PHY's page select is initialized to * point to other bank instead of copper/fiber bank * which in turn resulted in wrong registers were * accessed during PHY operation. It is believed that * page 0 should be used for copper PHY so reinitialize * E1000_EADR to select default copper PHY. If parent * device know the type of PHY(either copper or fiber), * that information should be used to select default * type of PHY. */ PHY_WRITE(sc, E1000_EADR, 0); break; } PHY_RESET(sc); sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) { sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) sc->mii_flags |= MIIF_HAVE_GTCR; } device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }
static int ukphy_attach(device_t dev) { struct mii_softc *sc; sc = device_get_softc(dev); mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &ukphy_funcs, 1); mii_phy_setmedia(sc); return (0); }
static int jmphy_attach(device_t dev) { u_int flags; flags = 0; if (mii_dev_mac_match(dev, "jme") && (miibus_get_flags(dev) & MIIF_MACPRIV0) != 0) flags |= MIIF_PHYPRIV0; mii_phy_dev_attach(dev, flags, &jmphy_funcs, 1); return (0); }
static int smscphy_attach(device_t dev) { struct mii_softc *sc; const struct mii_phy_funcs *mpf; sc = device_get_softc(dev); mpf = &smscphy_funcs; mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, mpf, 1); mii_phy_setmedia(sc); return (0); }
static int jmphy_attach(device_t dev) { struct mii_attach_args *ma; u_int flags; ma = device_get_ivars(dev); flags = 0; if (strcmp(ma->mii_data->mii_ifp->if_dname, "jme") == 0 && (miibus_get_flags(dev) & MIIF_MACPRIV0) != 0) flags |= MIIF_PHYPRIV0; mii_phy_dev_attach(dev, flags, &jmphy_funcs, 1); return (0); }
static int nsphy_attach(device_t dev) { u_int flags; flags = MIIF_NOMANPAUSE; /* * Am79C971 wedge when isolating all of their external PHYs. */ if (mii_dev_mac_match(dev,"pcn")) flags |= MIIF_NOISOLATE; mii_phy_dev_attach(dev, flags, &nsphy_funcs, 1); return (0); }
static int ip1000phy_attach(device_t dev) { struct mii_attach_args *ma; u_int flags; ma = device_get_ivars(dev); flags = MIIF_NOISOLATE | MIIF_NOMANPAUSE; if (MII_MODEL(ma->mii_id2) == MII_MODEL_xxICPLUS_IP1000A && mii_dev_mac_match(dev, "stge") && (miibus_get_flags(dev) & MIIF_MACPRIV0) != 0) flags |= MIIF_PHYPRIV0; mii_phy_dev_attach(dev, flags, &ip1000phy_funcs, 1); return (0); }
static int nsphy_attach(device_t dev) { const char *nic; u_int flags; nic = device_get_name(device_get_parent(device_get_parent(dev))); flags = MIIF_NOMANPAUSE; /* * Am79C971 wedge when isolating all of their external PHYs. */ if (strcmp(nic, "pcn") == 0) flags |= MIIF_NOISOLATE; mii_phy_dev_attach(dev, flags, &nsphy_funcs, 1); return (0); }
static int smcphy_attach(device_t dev) { struct mii_softc *sc; struct mii_attach_args *ma; const struct mii_phy_funcs *mpf; sc = device_get_softc(dev); ma = device_get_ivars(dev); if (MII_MODEL(ma->mii_id2) == MII_MODEL_SEEQ_80220) mpf = &smcphy80220_funcs; else mpf = &smcphy_funcs; mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, mpf, 1); mii_phy_setmedia(sc); return (0); }
static int dcphy_attach(device_t dev) { struct mii_softc *sc; struct dc_softc *dc_sc; device_t brdev; sc = device_get_softc(dev); mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, &dcphy_funcs, 0); /*PHY_RESET(sc);*/ dc_sc = sc->mii_pdata->mii_ifp->if_softc; CSR_WRITE_4(dc_sc, DC_10BTSTAT, 0); CSR_WRITE_4(dc_sc, DC_10BTCTRL, 0); brdev = device_get_parent(sc->mii_dev); switch (pci_get_subdevice(brdev) << 16 | pci_get_subvendor(brdev)) { case COMPAQ_PRESARIO_ID: /* Example of how to only allow 10Mbps modes. */ sc->mii_capabilities = BMSR_ANEG | BMSR_10TFDX | BMSR_10THDX; break; default: if (dc_sc->dc_pmode == DC_PMODE_SIA) sc->mii_capabilities = BMSR_ANEG | BMSR_10TFDX | BMSR_10THDX; else sc->mii_capabilities = BMSR_ANEG | BMSR_100TXFDX | BMSR_100TXHDX | BMSR_10TFDX | BMSR_10THDX; break; } sc->mii_capabilities &= sc->mii_capmask; device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }
static int pnphy_attach(device_t dev) { struct mii_softc *sc; sc = device_get_softc(dev); mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, &pnphy_funcs, 0); sc->mii_capabilities = BMSR_100TXFDX | BMSR_100TXHDX | BMSR_10TFDX | BMSR_10THDX; sc->mii_capabilities &= sc->mii_capmask; device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }
/* Attach the PHY to the MII bus */ static int brgphy_attach(device_t dev) { struct brgphy_softc *bsc; struct bge_softc *bge_sc = NULL; struct bce_softc *bce_sc = NULL; struct mii_softc *sc; struct ifnet *ifp; bsc = device_get_softc(dev); sc = &bsc->mii_sc; mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, &brgphy_funcs, 0); bsc->serdes_flags = 0; ifp = sc->mii_pdata->mii_ifp; /* Find the MAC driver associated with this PHY. */ if (strcmp(ifp->if_dname, "bge") == 0) bge_sc = ifp->if_softc; else if (strcmp(ifp->if_dname, "bce") == 0) bce_sc = ifp->if_softc; /* Handle any special cases based on the PHY ID */ switch (sc->mii_mpd_oui) { case MII_OUI_BROADCOM: switch (sc->mii_mpd_model) { case MII_MODEL_BROADCOM_BCM5706: case MII_MODEL_BROADCOM_BCM5714: /* * The 5464 PHY used in the 5706 supports both copper * and fiber interfaces over GMII. Need to check the * shadow registers to see which mode is actually * in effect, and therefore whether we have 5706C or * 5706S. */ PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, BRGPHY_SHADOW_1C_MODE_CTRL); if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) & BRGPHY_SHADOW_1C_ENA_1000X) { bsc->serdes_flags |= BRGPHY_5706S; sc->mii_flags |= MIIF_HAVEFIBER; } break; } break; case MII_OUI_BROADCOM2: switch (sc->mii_mpd_model) { case MII_MODEL_BROADCOM2_BCM5708S: bsc->serdes_flags |= BRGPHY_5708S; sc->mii_flags |= MIIF_HAVEFIBER; break; case MII_MODEL_BROADCOM2_BCM5709S: /* * XXX * 5720S and 5709S shares the same PHY id. * Assume 5720S PHY if parent device is bge(4). */ if (bge_sc != NULL) bsc->serdes_flags |= BRGPHY_5708S; else bsc->serdes_flags |= BRGPHY_5709S; sc->mii_flags |= MIIF_HAVEFIBER; break; } break; } PHY_RESET(sc); /* Read the PHY's capabilities. */ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); #define ADD(m, c) ifmedia_add(&sc->mii_pdata->mii_media, (m), (c), NULL) /* Add the supported media types */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { mii_phy_add_media(sc); printf("\n"); } else { sc->mii_anegticks = MII_ANEGTICKS_GIGE; ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), BRGPHY_S1000 | BRGPHY_BMCR_FDX); printf("1000baseSX-FDX, "); /* 2.5G support is a software enabled feature on the 5708S and 5709S. */ if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0); printf("2500baseSX-FDX, "); } else if ((bsc->serdes_flags & BRGPHY_5708S) && bce_sc && (detect_hs21(bce_sc) != 0)) { /* * There appears to be certain silicon revision * in IBM HS21 blades that is having issues with * this driver wating for the auto-negotiation to * complete. This happens with a specific chip id * only and when the 1000baseSX-FDX is the only * mode. Workaround this issue since it's unlikely * to be ever addressed. */ printf("auto-neg workaround, "); bsc->serdes_flags |= BRGPHY_NOANWAIT; } ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); printf("auto\n"); } #undef ADD MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }
static int tlphy_attach(device_t dev) { device_t *devlist; struct mii_softc *other, *sc_mii; const char *sep = ""; int capmask, devs, i; sc_mii = device_get_softc(dev); mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &tlphy_funcs, 0); /* * Note that if we're on a device that also supports 100baseTX, * we are not going to want to use the built-in 10baseT port, * since there will be another PHY on the MII wired up to the * UTP connector. */ capmask = BMSR_DEFCAPMASK; if (sc_mii->mii_inst && device_get_children(sc_mii->mii_dev, &devlist, &devs) == 0) { for (i = 0; i < devs; i++) { if (devlist[i] != dev) { other = device_get_softc(devlist[i]); capmask &= ~other->mii_capabilities; break; } } free(devlist, M_TEMP); } PHY_RESET(sc_mii); sc_mii->mii_capabilities = PHY_READ(sc_mii, MII_BMSR) & capmask; #define ADD(m, c) \ ifmedia_add(&sc_mii->mii_pdata->mii_media, (m), (c), NULL) #define PRINT(s) printf("%s%s", sep, s); sep = ", " if ((sc_mii->mii_flags & (MIIF_MACPRIV0 | MIIF_MACPRIV1)) != 0 && (sc_mii->mii_capabilities & BMSR_MEDIAMASK) != 0) device_printf(dev, " "); if ((sc_mii->mii_flags & MIIF_MACPRIV0) != 0) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_2, 0, sc_mii->mii_inst), 0); PRINT("10base2/BNC"); } if ((sc_mii->mii_flags & MIIF_MACPRIV1) != 0) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_5, 0, sc_mii->mii_inst), 0); PRINT("10base5/AUI"); } if ((sc_mii->mii_capabilities & BMSR_MEDIAMASK) != 0) { printf("%s", sep); mii_phy_add_media(sc_mii); } if ((sc_mii->mii_flags & (MIIF_MACPRIV0 | MIIF_MACPRIV1)) != 0 && (sc_mii->mii_capabilities & BMSR_MEDIAMASK) != 0) printf("\n"); #undef ADD #undef PRINT MIIBUS_MEDIAINIT(sc_mii->mii_dev); return (0); }
static int rlswitch_attach(device_t dev) { struct mii_softc *sc; sc = device_get_softc(dev); /* * We handle all pseudo PHYs in a single instance. */ mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, &rlswitch_funcs, 0); sc->mii_capabilities = BMSR_100TXFDX & sc->mii_capmask; device_printf(dev, " "); mii_phy_add_media(sc); printf("\n"); #ifdef RL_DEBUG rlswitch_phydump(dev); #endif #ifdef RL_VLAN int val; /* Global Control 0 */ val = 0; val |= 0 << 10; /* enable 802.1q VLAN Tag support */ val |= 0 << 9; /* enable VLAN ingress filtering */ val |= 1 << 8; /* disable VLAN tag admit control */ val |= 1 << 6; /* internal use */ val |= 1 << 5; /* internal use */ val |= 1 << 4; /* internal use */ val |= 1 << 3; /* internal use */ val |= 1 << 1; /* reserved */ MIIBUS_WRITEREG(sc->mii_dev, 0, 16, val); /* Global Control 2 */ val = 0; val |= 1 << 15; /* reserved */ val |= 0 << 14; /* enable 1552 Bytes support */ val |= 1 << 13; /* enable broadcast input drop */ val |= 1 << 12; /* forward reserved control frames */ val |= 1 << 11; /* disable forwarding unicast frames to other VLAN's */ val |= 1 << 10; /* disable forwarding ARP broadcasts to other VLAN's */ val |= 1 << 9; /* enable 48 pass 1 */ val |= 0 << 8; /* enable VLAN */ val |= 1 << 7; /* reserved */ val |= 1 << 6; /* enable defer */ val |= 1 << 5; /* 43ms LED blink time */ val |= 3 << 3; /* 16:1 queue weight */ val |= 1 << 2; /* disable broadcast storm control */ val |= 1 << 1; /* enable power-on LED blinking */ val |= 1 << 0; /* reserved */ MIIBUS_WRITEREG(sc->mii_dev, 0, 18, val); /* Port 0 Control Register 0 */ val = 0; val |= 1 << 15; /* reserved */ val |= 1 << 11; /* drop received packets with wrong VLAN tag */ val |= 1 << 10; /* disable 802.1p priority classification */ val |= 1 << 9; /* disable diffserv priority classification */ val |= 1 << 6; /* internal use */ val |= 3 << 4; /* internal use */ val |= 1 << 3; /* internal use */ val |= 1 << 2; /* internal use */ val |= 1 << 0; /* remove VLAN tags on output */ MIIBUS_WRITEREG(sc->mii_dev, 0, 22, val); /* Port 1 Control Register 0 */ val = 0; val |= 1 << 15; /* reserved */ val |= 1 << 11; /* drop received packets with wrong VLAN tag */ val |= 1 << 10; /* disable 802.1p priority classification */ val |= 1 << 9; /* disable diffserv priority classification */ val |= 1 << 6; /* internal use */ val |= 3 << 4; /* internal use */ val |= 1 << 3; /* internal use */ val |= 1 << 2; /* internal use */ val |= 1 << 0; /* remove VLAN tags on output */ MIIBUS_WRITEREG(sc->mii_dev, 1, 22, val); /* Port 2 Control Register 0 */ val = 0; val |= 1 << 15; /* reserved */ val |= 1 << 11; /* drop received packets with wrong VLAN tag */ val |= 1 << 10; /* disable 802.1p priority classification */ val |= 1 << 9; /* disable diffserv priority classification */ val |= 1 << 6; /* internal use */ val |= 3 << 4; /* internal use */ val |= 1 << 3; /* internal use */ val |= 1 << 2; /* internal use */ val |= 1 << 0; /* remove VLAN tags on output */ MIIBUS_WRITEREG(sc->mii_dev, 2, 22, val); /* Port 3 Control Register 0 */ val = 0; val |= 1 << 15; /* reserved */ val |= 1 << 11; /* drop received packets with wrong VLAN tag */ val |= 1 << 10; /* disable 802.1p priority classification */ val |= 1 << 9; /* disable diffserv priority classification */ val |= 1 << 6; /* internal use */ val |= 3 << 4; /* internal use */ val |= 1 << 3; /* internal use */ val |= 1 << 2; /* internal use */ val |= 1 << 0; /* remove VLAN tags on output */ MIIBUS_WRITEREG(sc->mii_dev, 3, 22, val); /* Port 4 (system port) Control Register 0 */ val = 0; val |= 1 << 15; /* reserved */ val |= 0 << 11; /* don't drop received packets with wrong VLAN tag */ val |= 1 << 10; /* disable 802.1p priority classification */ val |= 1 << 9; /* disable diffserv priority classification */ val |= 1 << 6; /* internal use */ val |= 3 << 4; /* internal use */ val |= 1 << 3; /* internal use */ val |= 1 << 2; /* internal use */ val |= 2 << 0; /* add VLAN tags for untagged packets on output */ MIIBUS_WRITEREG(sc->mii_dev, 4, 22, val); /* Port 0 Control Register 1 and VLAN A */ val = 0; val |= 0x0 << 12; /* Port 0 VLAN Index */ val |= 1 << 11; /* internal use */ val |= 1 << 10; /* internal use */ val |= 1 << 9; /* internal use */ val |= 1 << 7; /* internal use */ val |= 1 << 6; /* internal use */ val |= 0x11 << 0; /* VLAN A membership */ MIIBUS_WRITEREG(sc->mii_dev, 0, 24, val); /* Port 0 Control Register 2 and VLAN A */ val = 0; val |= 1 << 15; /* internal use */ val |= 1 << 14; /* internal use */ val |= 1 << 13; /* internal use */ val |= 1 << 12; /* internal use */ val |= 0x100 << 0; /* VLAN A ID */ MIIBUS_WRITEREG(sc->mii_dev, 0, 25, val); /* Port 1 Control Register 1 and VLAN B */ val = 0; val |= 0x1 << 12; /* Port 1 VLAN Index */ val |= 1 << 11; /* internal use */ val |= 1 << 10; /* internal use */ val |= 1 << 9; /* internal use */ val |= 1 << 7; /* internal use */ val |= 1 << 6; /* internal use */ val |= 0x12 << 0; /* VLAN B membership */ MIIBUS_WRITEREG(sc->mii_dev, 1, 24, val); /* Port 1 Control Register 2 and VLAN B */ val = 0; val |= 1 << 15; /* internal use */ val |= 1 << 14; /* internal use */ val |= 1 << 13; /* internal use */ val |= 1 << 12; /* internal use */ val |= 0x101 << 0; /* VLAN B ID */ MIIBUS_WRITEREG(sc->mii_dev, 1, 25, val); /* Port 2 Control Register 1 and VLAN C */ val = 0; val |= 0x2 << 12; /* Port 2 VLAN Index */ val |= 1 << 11; /* internal use */ val |= 1 << 10; /* internal use */ val |= 1 << 9; /* internal use */ val |= 1 << 7; /* internal use */ val |= 1 << 6; /* internal use */ val |= 0x14 << 0; /* VLAN C membership */ MIIBUS_WRITEREG(sc->mii_dev, 2, 24, val); /* Port 2 Control Register 2 and VLAN C */ val = 0; val |= 1 << 15; /* internal use */ val |= 1 << 14; /* internal use */ val |= 1 << 13; /* internal use */ val |= 1 << 12; /* internal use */ val |= 0x102 << 0; /* VLAN C ID */ MIIBUS_WRITEREG(sc->mii_dev, 2, 25, val); /* Port 3 Control Register 1 and VLAN D */ val = 0; val |= 0x3 << 12; /* Port 3 VLAN Index */ val |= 1 << 11; /* internal use */ val |= 1 << 10; /* internal use */ val |= 1 << 9; /* internal use */ val |= 1 << 7; /* internal use */ val |= 1 << 6; /* internal use */ val |= 0x18 << 0; /* VLAN D membership */ MIIBUS_WRITEREG(sc->mii_dev, 3, 24, val); /* Port 3 Control Register 2 and VLAN D */ val = 0; val |= 1 << 15; /* internal use */ val |= 1 << 14; /* internal use */ val |= 1 << 13; /* internal use */ val |= 1 << 12; /* internal use */ val |= 0x103 << 0; /* VLAN D ID */ MIIBUS_WRITEREG(sc->mii_dev, 3, 25, val); /* Port 4 Control Register 1 and VLAN E */ val = 0; val |= 0x0 << 12; /* Port 4 VLAN Index */ val |= 1 << 11; /* internal use */ val |= 1 << 10; /* internal use */ val |= 1 << 9; /* internal use */ val |= 1 << 7; /* internal use */ val |= 1 << 6; /* internal use */ val |= 0 << 0; /* VLAN E membership */ MIIBUS_WRITEREG(sc->mii_dev, 4, 24, val); /* Port 4 Control Register 2 and VLAN E */ val = 0; val |= 1 << 15; /* internal use */ val |= 1 << 14; /* internal use */ val |= 1 << 13; /* internal use */ val |= 1 << 12; /* internal use */ val |= 0x104 << 0; /* VLAN E ID */ MIIBUS_WRITEREG(sc->mii_dev, 4, 25, val); #endif #ifdef RL_DEBUG rlswitch_phydump(dev); #endif MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }