diff options
| author | Bill Paul <wpaul@FreeBSD.org> | 2000-10-05 17:36:14 +0000 |
|---|---|---|
| committer | Bill Paul <wpaul@FreeBSD.org> | 2000-10-05 17:36:14 +0000 |
| commit | 5c1cfac46e47ae5f83346be09703ae711e47b4a4 (patch) | |
| tree | 4b47a08c23d6c1d8c369e0700170c125e8bc4f89 /sys/dev | |
| parent | b75e82a0e60b039d0eca71e903a01a8bdc76813f (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/dc/dcphy.c | 22 | ||||
| -rw-r--r-- | sys/dev/dc/if_dc.c | 278 | ||||
| -rw-r--r-- | sys/dev/dc/if_dcreg.h | 120 | ||||
| -rw-r--r-- | sys/dev/mii/dcphy.c | 22 |
4 files changed, 369 insertions, 73 deletions
diff --git a/sys/dev/dc/dcphy.c b/sys/dev/dc/dcphy.c index 73e241e8f5cc..ad2599c69583 100644 --- a/sys/dev/dc/dcphy.c +++ b/sys/dev/dc/dcphy.c @@ -179,12 +179,17 @@ static int dcphy_attach(dev) sc->mii_capabilities = BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX; break; default: - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, - sc->mii_inst), BMCR_LOOP|BMCR_S100); + if (dc_sc->dc_pmode == DC_PMODE_SIA) { + sc->mii_capabilities = + BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX; + } else { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, + sc->mii_inst), BMCR_LOOP|BMCR_S100); - sc->mii_capabilities = - BMSR_ANEG|BMSR_100TXFDX|BMSR_100TXHDX| - BMSR_10TFDX|BMSR_10THDX; + sc->mii_capabilities = + BMSR_ANEG|BMSR_100TXFDX|BMSR_100TXHDX| + BMSR_10TFDX|BMSR_10THDX; + } break; } @@ -429,10 +434,11 @@ dcphy_status(sc) } skip: - if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SCRAMBLER) - mii->mii_media_active |= IFM_100_TX; - else + + if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SPEEDSEL) mii->mii_media_active |= IFM_10_T; + else + mii->mii_media_active |= IFM_100_TX; if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_FULLDUPLEX) mii->mii_media_active |= IFM_FDX; diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index 039f83574243..695b019fec29 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -73,27 +73,6 @@ * combination with the internal NWAY support to create a 10/100 * autosensing configuration. * - * Knowing which media is available on a given card is tough: you're - * supposed to go slogging through the EEPROM looking for media - * description structures. Unfortunately, some card vendors that use - * the 21143 don't obey the DEC SROM spec correctly, which means that - * what you find in the EEPROM may not agree with reality. Fortunately, - * the 21143 provides us a way to get around this issue: lurking in - * PCI configuration space is the Configuration Wake-Up Command Register. - * This register is loaded with a value from the EEPROM when wake on LAN - * mode is enabled; this value tells us quite clearly what kind of media - * is attached to the NIC. The main purpose of this register is to tell - * the NIC what media to scan when in wake on LAN mode, however by - * forcibly enabling wake on LAN mode, we can use to learn what kind of - * media a given NIC has available and adapt ourselves accordingly. - * - * Of course, if the media description blocks in the EEPROM are bogus. - * what are the odds that the CWUC aren't bogus as well, right? Well, - * the CWUC value is more likely to be correct since wake on LAN mode - * won't work correctly without it, and wake on LAN is a big selling - * point these days. It's also harder to screw up a single byte than - * a whole media descriptor block. - * * Note that not all tulip workalikes are handled in this driver: we only * deal with those which are relatively well behaved. The Winbond is * handled separately due to its different register offsets and the @@ -140,6 +119,9 @@ #include <pci/pcivar.h> #define DC_USEIOSPACE +#ifdef __alpha__ +#define SRM_MEDIA +#endif #include <pci/if_dcreg.h> @@ -257,6 +239,15 @@ static void dc_reset __P((struct dc_softc *)); static int dc_list_rx_init __P((struct dc_softc *)); static int dc_list_tx_init __P((struct dc_softc *)); +static void dc_parse_21143_srom __P((struct dc_softc *)); +static void dc_decode_leaf_sia __P((struct dc_softc *, + struct dc_eblock_sia *)); +static void dc_decode_leaf_mii __P((struct dc_softc *, + struct dc_eblock_mii *)); +static void dc_decode_leaf_sym __P((struct dc_softc *, + struct dc_eblock_sym *)); +static void dc_apply_fixup __P((struct dc_softc *, int)); + #ifdef DC_USEIOSPACE #define DC_RES SYS_RES_IOPORT #define DC_RID DC_PCI_CFBIO @@ -691,7 +682,7 @@ static int dc_miibus_readreg(dev, phy, reg) if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR) return(0); - if (sc->dc_pmode == DC_PMODE_SYM) { + if (sc->dc_pmode != DC_PMODE_MII) { if (phy == (MII_NPHY - 1)) { switch(reg) { case MII_BMSR: @@ -860,6 +851,7 @@ static void dc_miibus_statchg(dev) sc = device_get_softc(dev); if (DC_IS_ADMTEK(sc)) return; + mii = device_get_softc(sc->dc_miibus); ifm = &mii->mii_media; if (DC_IS_DAVICOM(sc) && @@ -1248,6 +1240,10 @@ static void dc_setcfg(sc, media) DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL); DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PCS); DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_SCRAMBLER); + if (DC_IS_INTEL(sc)) + dc_apply_fixup(sc, + (media & IFM_GMASK) == IFM_FDX ? + IFM_100_TX|IFM_FDX : IFM_100_TX); } } @@ -1278,6 +1274,21 @@ static void dc_setcfg(sc, media) DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL); DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PCS); DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_SCRAMBLER); + if (DC_IS_INTEL(sc)) { + DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET); + DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF); + if ((media & IFM_GMASK) == IFM_FDX) + DC_SETBIT(sc, DC_10BTCTRL, 0x7F3D); + else + DC_SETBIT(sc, DC_10BTCTRL, 0x7F3F); + DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET); + DC_CLRBIT(sc, DC_10BTCTRL, + DC_TCTL_AUTONEGENBL); + dc_apply_fixup(sc, + (media & IFM_GMASK) == IFM_FDX ? + IFM_10_T|IFM_FDX : IFM_10_T); + DELAY(20000); + } } } @@ -1346,8 +1357,11 @@ static void dc_reset(sc) * into a state where it will never come out of reset * until we reset the whole chip again. */ - if (DC_IS_INTEL(sc)) + if (DC_IS_INTEL(sc)) { DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET); + CSR_WRITE_4(sc, DC_10BTCTRL, 0); + CSR_WRITE_4(sc, DC_WATCHDOG, 0); + } return; } @@ -1456,6 +1470,155 @@ static void dc_acpi(dev) return; } +static void dc_apply_fixup(sc, media) + struct dc_softc *sc; + int media; +{ + struct dc_mediainfo *m; + u_int8_t *p; + int i; + u_int8_t reg; + + m = sc->dc_mi; + + while (m != NULL) { + if (m->dc_media == media) + break; + m = m->dc_next; + } + + if (m == NULL) + return; + + for (i = 0, p = m->dc_reset_ptr; i < m->dc_reset_len; i++, p += 2) { + reg = (p[0] | (p[1] << 8)) << 16; + CSR_WRITE_4(sc, DC_WATCHDOG, reg); + } + + for (i = 0, p = m->dc_gp_ptr; i < m->dc_gp_len; i++, p += 2) { + reg = (p[0] | (p[1] << 8)) << 16; + CSR_WRITE_4(sc, DC_WATCHDOG, reg); + } + + return; +} + +static void dc_decode_leaf_sia(sc, l) + struct dc_softc *sc; + struct dc_eblock_sia *l; +{ + struct dc_mediainfo *m; + + m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT); + if (l->dc_sia_code == DC_SIA_CODE_10BT) + m->dc_media = IFM_10_T; + + if (l->dc_sia_code == DC_SIA_CODE_10BT_FDX) + m->dc_media = IFM_10_T|IFM_FDX; + + if (l->dc_sia_code == DC_SIA_CODE_10B2) + m->dc_media = IFM_10_2; + + if (l->dc_sia_code == DC_SIA_CODE_10B5) + m->dc_media = IFM_10_5; + + m->dc_gp_len = 2; + m->dc_gp_ptr = (u_int8_t *)&l->dc_sia_gpio_ctl; + + m->dc_next = sc->dc_mi; + sc->dc_mi = m; + + sc->dc_pmode = DC_PMODE_SIA; + + return; +} + +static void dc_decode_leaf_sym(sc, l) + struct dc_softc *sc; + struct dc_eblock_sym *l; +{ + struct dc_mediainfo *m; + + m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT); + if (l->dc_sym_code == DC_SYM_CODE_100BT) + m->dc_media = IFM_100_TX; + + if (l->dc_sym_code == DC_SYM_CODE_100BT_FDX) + m->dc_media = IFM_100_TX|IFM_FDX; + + m->dc_gp_len = 2; + m->dc_gp_ptr = (u_int8_t *)&l->dc_sym_gpio_ctl; + + m->dc_next = sc->dc_mi; + sc->dc_mi = m; + + sc->dc_pmode = DC_PMODE_SYM; + + return; +} + +static void dc_decode_leaf_mii(sc, l) + struct dc_softc *sc; + struct dc_eblock_mii *l; +{ + u_int8_t *p; + struct dc_mediainfo *m; + + m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT); + /* We abuse IFM_AUTO to represent MII. */ + m->dc_media = IFM_AUTO; + m->dc_gp_len = l->dc_gpr_len; + + p = (u_int8_t *)l; + p += sizeof(struct dc_eblock_mii); + m->dc_gp_ptr = p; + p += 2 * l->dc_gpr_len; + m->dc_reset_len = *p; + p++; + m->dc_reset_ptr = p; + + m->dc_next = sc->dc_mi; + sc->dc_mi = m; + + return; +} + +static void dc_parse_21143_srom(sc) + struct dc_softc *sc; +{ + struct dc_leaf_hdr *lhdr; + struct dc_eblock_hdr *hdr; + int i, loff; + char *ptr; + + loff = sc->dc_srom[27]; + lhdr = (struct dc_leaf_hdr *)&(sc->dc_srom[loff]); + + ptr = (char *)lhdr; + ptr += sizeof(struct dc_leaf_hdr) - 1; + for (i = 0; i < lhdr->dc_mcnt; i++) { + hdr = (struct dc_eblock_hdr *)ptr; + switch(hdr->dc_type) { + case DC_EBLOCK_MII: + dc_decode_leaf_mii(sc, (struct dc_eblock_mii *)hdr); + break; + case DC_EBLOCK_SIA: + dc_decode_leaf_sia(sc, (struct dc_eblock_sia *)hdr); + break; + case DC_EBLOCK_SYM: + dc_decode_leaf_sym(sc, (struct dc_eblock_sym *)hdr); + break; + default: + /* Don't care. Yet. */ + break; + } + ptr += (hdr->dc_len & 0x7F); + ptr++; + } + + return; +} + /* * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. @@ -1463,7 +1626,7 @@ static void dc_acpi(dev) static int dc_attach(dev) device_t dev; { - int s; + int s, tmp = 0; u_char eaddr[ETHER_ADDR_LEN]; u_int32_t command; struct dc_softc *sc; @@ -1548,12 +1711,14 @@ static int dc_attach(dev) sc->dc_type = DC_TYPE_21143; sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR; sc->dc_flags |= DC_REDUCED_MII_POLL; + /* Save EEPROM contents so we can parse them later. */ + dc_read_eeprom(sc, (caddr_t)&sc->dc_srom, 0, 512, 0); break; case DC_DEVICEID_DM9100: case DC_DEVICEID_DM9102: sc->dc_type = DC_TYPE_DM9102; sc->dc_flags |= DC_TX_COALESCE|DC_TX_USE_TX_INTR; - sc->dc_flags |= DC_REDUCED_MII_POLL; + sc->dc_flags |= DC_REDUCED_MII_POLL|DC_TX_ONE; sc->dc_pmode = DC_PMODE_MII; break; case DC_DEVICEID_AL981: @@ -1650,32 +1815,9 @@ static int dc_attach(dev) * The tricky ones are the Macronix/PNIC II and the * Intel 21143. */ - if (DC_IS_INTEL(sc)) { - u_int32_t media, cwuc; - cwuc = pci_read_config(dev, DC_PCI_CWUC, 4); - cwuc |= DC_CWUC_FORCE_WUL; - pci_write_config(dev, DC_PCI_CWUC, cwuc, 4); - DELAY(10000); - media = pci_read_config(dev, DC_PCI_CWUC, 4); - cwuc &= ~DC_CWUC_FORCE_WUL; - pci_write_config(dev, DC_PCI_CWUC, cwuc, 4); - DELAY(10000); - if (media & DC_CWUC_MII_ABILITY) - sc->dc_pmode = DC_PMODE_MII; - if (media & DC_CWUC_SYM_ABILITY) { - sc->dc_pmode = DC_PMODE_SYM; - sc->dc_flags |= DC_21143_NWAY; - } - /* - * If none of the bits are set, then this NIC - * isn't meant to support 'wake up LAN' mode. - * This is usually only the case on multiport - * cards, and these cards almost always have - * MII transceivers. - */ - if (media == 0) - sc->dc_pmode = DC_PMODE_MII; - } else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) { + if (DC_IS_INTEL(sc)) + dc_parse_21143_srom(sc); + else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) { if (sc->dc_type == DC_TYPE_98713) sc->dc_pmode = DC_PMODE_MII; else @@ -1749,13 +1891,25 @@ static int dc_attach(dev) ifp->if_snd.ifq_maxlen = DC_TX_LIST_CNT - 1; /* - * Do MII setup. + * Do MII setup. If this is a 21143, check for a PHY on the + * MII bus after applying any necessary fixups to twiddle the + * GPIO bits. If we don't end up finding a PHY, restore the + * old selection (SIA only or SIA/SYM) and attach the dcphy + * driver instead. */ + if (DC_IS_INTEL(sc)) { + dc_apply_fixup(sc, IFM_AUTO); + tmp = sc->dc_pmode; + sc->dc_pmode = DC_PMODE_MII; + } + error = mii_phy_probe(dev, &sc->dc_miibus, dc_ifmedia_upd, dc_ifmedia_sts); if (error && DC_IS_INTEL(sc)) { - sc->dc_pmode = DC_PMODE_SYM; + sc->dc_pmode = tmp; + if (sc->dc_pmode != DC_PMODE_SIA) + sc->dc_pmode = DC_PMODE_SYM; sc->dc_flags |= DC_21143_NWAY; mii_phy_probe(dev, &sc->dc_miibus, dc_ifmedia_upd, dc_ifmedia_sts); @@ -1786,7 +1940,7 @@ static int dc_attach(dev) ether_ifattach(ifp, ETHER_BPF_SUPPORTED); callout_handle_init(&sc->dc_stat_ch); -#ifdef __alpha__ +#ifdef SRM_MEDIA sc->dc_srm_media = 0; /* Remember the SRM console media setting */ @@ -1825,6 +1979,7 @@ static int dc_detach(dev) struct dc_softc *sc; struct ifnet *ifp; int s; + struct dc_mediainfo *m; s = splimp(); @@ -1845,6 +2000,12 @@ static int dc_detach(dev) if (sc->dc_pnic_rx_buf != NULL) free(sc->dc_pnic_rx_buf, M_DEVBUF); + while(sc->dc_mi != NULL) { + m = sc->dc_mi->dc_next; + free(sc->dc_mi, M_DEVBUF); + sc->dc_mi = m; + } + splx(s); return(0); @@ -2609,6 +2770,11 @@ static void dc_start(ifp) */ if (ifp->if_bpf) bpf_mtap(ifp, m_head); + + if (sc->dc_flags & DC_TX_ONE) { + ifp->if_flags |= IFF_OACTIVE; + break; + } } /* Transmit */ @@ -2775,7 +2941,7 @@ static void dc_init(xsc) sc->dc_stat_ch = timeout(dc_tick, sc, hz); } -#ifdef __alpha__ +#ifdef SRM_MEDIA if(sc->dc_srm_media) { struct ifreq ifr; @@ -2887,7 +3053,7 @@ static int dc_ioctl(ifp, command, data) case SIOCSIFMEDIA: mii = device_get_softc(sc->dc_miibus); error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); -#ifdef __alpha__ +#ifdef SRM_MEDIA if (sc->dc_srm_media) sc->dc_srm_media = 0; #endif diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h index a0a2444de88b..9c6cfc41bf43 100644 --- a/sys/dev/dc/if_dcreg.h +++ b/sys/dev/dc/if_dcreg.h @@ -96,6 +96,7 @@ /* MII/symbol mode port types */ #define DC_PMODE_MII 0x1 #define DC_PMODE_SYM 0x2 +#define DC_PMODE_SIA 0x3 /* * Bus control bits. @@ -445,6 +446,16 @@ struct dc_chain_data { int dc_rx_prod; }; +struct dc_mediainfo { + int dc_media; + u_int8_t *dc_gp_ptr; + u_int8_t dc_gp_len; + u_int8_t *dc_reset_ptr; + u_int8_t dc_reset_len; + struct dc_mediainfo *dc_next; +}; + + struct dc_type { u_int16_t dc_vid; u_int16_t dc_did; @@ -657,10 +668,12 @@ struct dc_softc { int dc_if_media; u_int32_t dc_flags; u_int32_t dc_txthresh; + u_int8_t dc_srom[1024]; + struct dc_mediainfo *dc_mi; struct dc_list_data *dc_ldata; struct dc_chain_data dc_cdata; struct callout_handle dc_stat_ch; -#ifdef __alpha__ +#ifdef SRM_MEDIA int dc_srm_media; #endif }; @@ -680,6 +693,7 @@ struct dc_softc { #define DC_128BIT_HASH 0x00001000 #define DC_64BIT_HASH 0x00002000 #define DC_TULIP_LEDS 0x00004000 +#define DC_TX_ONE 0x00008000 /* * register space access macros @@ -930,6 +944,110 @@ struct dc_softc { #define DC_CWUC_SYM_ABILITY 0x00000080 #define DC_CWUC_LOCK 0x00000100 +/* + * SROM nonsense. + */ + +#define DC_IB_CTLRCNT 0x13 +#define DC_IB_LEAF0_CNUM 0x1A +#define DC_IB_LEAF0_OFFSET 0x1B + +struct dc_info_leaf { + u_int16_t dc_conntype; + u_int8_t dc_blkcnt; + u_int8_t dc_rsvd; + u_int16_t dc_infoblk; +}; + +#define DC_CTYPE_10BT 0x0000 +#define DC_CTYPE_10BT_NWAY 0x0100 +#define DC_CTYPE_10BT_FDX 0x0204 +#define DC_CTYPE_10B2 0x0001 +#define DC_CTYPE_10B5 0x0002 +#define DC_CTYPE_100BT 0x0003 +#define DC_CTYPE_100BT_FDX 0x0205 +#define DC_CTYPE_100T4 0x0006 +#define DC_CTYPE_100FX 0x0007 +#define DC_CTYPE_100FX_FDX 0x0208 +#define DC_CTYPE_MII_10BT 0x0009 +#define DC_CTYPE_MII_10BT_FDX 0x020A +#define DC_CTYPE_MII_100BT 0x000D +#define DC_CTYPE_MII_100BT_FDX 0x020E +#define DC_CTYPE_MII_100T4 0x000F +#define DC_CTYPE_MII_100FX 0x0010 +#define DC_CTYPE_MII_100FX_FDX 0x0211 +#define DC_CTYPE_DYN_PUP_AUTOSENSE 0x0800 +#define DC_CTYPE_PUP_AUTOSENSe 0x8800 +#define DC_CTYPE_NOMEDIA 0xFFFF + +#define DC_EBLOCK_SIA 0x0002 +#define DC_EBLOCK_MII 0x0003 +#define DC_EBLOCK_SYM 0x0004 +#define DC_EBLOCK_RESET 0x0005 +#define DC_EBLOCK_PHY_SHUTDOWN 0x0006 + +struct dc_leaf_hdr { + u_int16_t dc_mtype; + u_int8_t dc_mcnt; + u_int8_t dc_rsvd; +}; + +struct dc_eblock_hdr { + u_int8_t dc_len; + u_int8_t dc_type; +}; + +struct dc_eblock_sia { + struct dc_eblock_hdr dc_sia_hdr; + u_int8_t dc_sia_code; + u_int8_t dc_sia_mediaspec[6]; /* CSR13, CSR14, CSR15 */ + u_int8_t dc_sia_gpio_ctl[2]; + u_int8_t dc_sia_gpio_dat[2]; +}; + +#define DC_SIA_CODE_10BT 0x00 +#define DC_SIA_CODE_10B2 0x01 +#define DC_SIA_CODE_10B5 0x02 +#define DC_SIA_CODE_10BT_FDX 0x04 +#define DC_SIA_CODE_EXT 0x40 + +/* + * Note that the first word in the gpr and reset + * sequences is always a control word. + */ +struct dc_eblock_mii { + struct dc_eblock_hdr dc_mii_hdr; + u_int8_t dc_mii_phynum; + u_int8_t dc_gpr_len; +/* u_int16_t dc_gpr_dat[n]; */ +/* u_int8_t dc_reset_len; */ +/* u_int16_t dc_reset_dat[n]; */ +/* There are other fields after these, but we don't + * care about them since they can be determined by looking + * at the PHY. + */ +}; + +struct dc_eblock_sym { + struct dc_eblock_hdr dc_sym_hdr; + u_int8_t dc_sym_code; + u_int8_t dc_sym_gpio_ctl[2]; + u_int8_t dc_sym_gpio_dat[2]; + u_int8_t dc_sym_cmd[2]; +}; + +#define DC_SYM_CODE_100BT 0x03 +#define DC_SYM_CODE_100BT_FDX 0x05 +#define DC_SYM_CODE_100T4 0x06 +#define DC_SYM_CODE_100FX 0x07 +#define DC_SYM_CODE_100FX_FDX 0x08 + +struct dc_eblock_reset { + struct dc_eblock_hdr dc_reset_hdr; + u_int8_t dc_reset_len; +/* u_int16_t dc_reset_dat[n]; */ +}; + #ifdef __alpha__ #undef vtophys #define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) diff --git a/sys/dev/mii/dcphy.c b/sys/dev/mii/dcphy.c index 73e241e8f5cc..ad2599c69583 100644 --- a/sys/dev/mii/dcphy.c +++ b/sys/dev/mii/dcphy.c @@ -179,12 +179,17 @@ static int dcphy_attach(dev) sc->mii_capabilities = BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX; break; default: - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, - sc->mii_inst), BMCR_LOOP|BMCR_S100); + if (dc_sc->dc_pmode == DC_PMODE_SIA) { + sc->mii_capabilities = + BMSR_ANEG|BMSR_10TFDX|BMSR_10THDX; + } else { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, + sc->mii_inst), BMCR_LOOP|BMCR_S100); - sc->mii_capabilities = - BMSR_ANEG|BMSR_100TXFDX|BMSR_100TXHDX| - BMSR_10TFDX|BMSR_10THDX; + sc->mii_capabilities = + BMSR_ANEG|BMSR_100TXFDX|BMSR_100TXHDX| + BMSR_10TFDX|BMSR_10THDX; + } break; } @@ -429,10 +434,11 @@ dcphy_status(sc) } skip: - if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SCRAMBLER) - mii->mii_media_active |= IFM_100_TX; - else + + if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SPEEDSEL) mii->mii_media_active |= IFM_10_T; + else + mii->mii_media_active |= IFM_100_TX; if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_FULLDUPLEX) mii->mii_media_active |= IFM_FDX; |
