mii_physubr.c (95724) | mii_physubr.c (96026) |
---|---|
1/* $NetBSD: mii_physubr.c,v 1.5 1999/08/03 19:41:49 drochner Exp $ */ 2 3/*- 4 * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, --- 46 unchanged lines hidden (view full) --- 55 56#include <dev/mii/mii.h> 57#include <dev/mii/miivar.h> 58 59#include "miibus_if.h" 60 61#if !defined(lint) 62static const char rcsid[] = | 1/* $NetBSD: mii_physubr.c,v 1.5 1999/08/03 19:41:49 drochner Exp $ */ 2 3/*- 4 * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, --- 46 unchanged lines hidden (view full) --- 55 56#include <dev/mii/mii.h> 57#include <dev/mii/miivar.h> 58 59#include "miibus_if.h" 60 61#if !defined(lint) 62static const char rcsid[] = |
63 "$FreeBSD: head/sys/dev/mii/mii_physubr.c 95724 2002-04-29 14:09:10Z phk $"; | 63 "$FreeBSD: head/sys/dev/mii/mii_physubr.c 96026 2002-05-04 11:00:30Z phk $"; |
64#endif 65 66/* 67 * Media to register setting conversion table. Order matters. 68 */ 69const struct mii_media mii_media_table[MII_NMEDIA] = { 70 /* None */ 71 { BMCR_ISO, ANAR_CSMA, --- 31 unchanged lines hidden (view full) --- 103 { BMCR_S1000, ANAR_CSMA, 104 GTCR_ADV_1000THDX }, 105 106 /* 1000baseT-FDX */ 107 { BMCR_S1000, ANAR_CSMA, 108 GTCR_ADV_1000TFDX }, 109}; 110 | 64#endif 65 66/* 67 * Media to register setting conversion table. Order matters. 68 */ 69const struct mii_media mii_media_table[MII_NMEDIA] = { 70 /* None */ 71 { BMCR_ISO, ANAR_CSMA, --- 31 unchanged lines hidden (view full) --- 103 { BMCR_S1000, ANAR_CSMA, 104 GTCR_ADV_1000THDX }, 105 106 /* 1000baseT-FDX */ 107 { BMCR_S1000, ANAR_CSMA, 108 GTCR_ADV_1000TFDX }, 109}; 110 |
111void mii_phy_auto_timeout(void *); 112 | |
113void 114mii_phy_setmedia(struct mii_softc *sc) 115{ 116 struct mii_data *mii = sc->mii_pdata; 117 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 118 int bmcr, anar, gtcr; 119 120 if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { 121 if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0) | 111void 112mii_phy_setmedia(struct mii_softc *sc) 113{ 114 struct mii_data *mii = sc->mii_pdata; 115 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 116 int bmcr, anar, gtcr; 117 118 if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { 119 if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0) |
122 (void) mii_phy_auto(sc, 1); | 120 (void) mii_phy_auto(sc); |
123 return; 124 } 125 126 /* 127 * Table index is stored in the media entry. 128 */ 129 130 KASSERT(ife->ifm_data >=0 && ife->ifm_data < MII_NMEDIA, --- 20 unchanged lines hidden (view full) --- 151 152 PHY_WRITE(sc, MII_ANAR, anar); 153 PHY_WRITE(sc, MII_BMCR, bmcr); 154 if (sc->mii_flags & MIIF_HAVE_GTCR) 155 PHY_WRITE(sc, MII_100T2CR, gtcr); 156} 157 158int | 121 return; 122 } 123 124 /* 125 * Table index is stored in the media entry. 126 */ 127 128 KASSERT(ife->ifm_data >=0 && ife->ifm_data < MII_NMEDIA, --- 20 unchanged lines hidden (view full) --- 149 150 PHY_WRITE(sc, MII_ANAR, anar); 151 PHY_WRITE(sc, MII_BMCR, bmcr); 152 if (sc->mii_flags & MIIF_HAVE_GTCR) 153 PHY_WRITE(sc, MII_100T2CR, gtcr); 154} 155 156int |
159mii_phy_auto(struct mii_softc *sc, int waitfor) | 157mii_phy_auto(struct mii_softc *sc) |
160{ | 158{ |
161 int bmsr, i; | |
162 | 159 |
163 if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { 164 /* 165 * Check for 1000BASE-X. Autonegotiation is a bit 166 * different on such devices. 167 */ 168 if (sc->mii_flags & MIIF_IS_1000X) { 169 uint16_t anar = 0; | 160 /* 161 * Check for 1000BASE-X. Autonegotiation is a bit 162 * different on such devices. 163 */ 164 if (sc->mii_flags & MIIF_IS_1000X) { 165 uint16_t anar = 0; |
170 | 166 |
171 if (sc->mii_extcapabilities & EXTSR_1000XFDX) 172 anar |= ANAR_X_FD; 173 if (sc->mii_extcapabilities & EXTSR_1000XHDX) 174 anar |= ANAR_X_HD; | 167 if (sc->mii_extcapabilities & EXTSR_1000XFDX) 168 anar |= ANAR_X_FD; 169 if (sc->mii_extcapabilities & EXTSR_1000XHDX) 170 anar |= ANAR_X_HD; |
175 | 171 |
176 if (sc->mii_flags & MIIF_DOPAUSE) { 177 /* XXX Asymmetric vs. symmetric? */ 178 anar |= ANLPAR_X_PAUSE_TOWARDS; 179 } | 172 if (sc->mii_flags & MIIF_DOPAUSE) { 173 /* XXX Asymmetric vs. symmetric? */ 174 anar |= ANLPAR_X_PAUSE_TOWARDS; 175 } |
180 | 176 |
181 PHY_WRITE(sc, MII_ANAR, anar); 182 } else { 183 uint16_t anar; | 177 PHY_WRITE(sc, MII_ANAR, anar); 178 } else { 179 uint16_t anar; |
184 | 180 |
185 anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | 186 ANAR_CSMA; 187 if (sc->mii_flags & MIIF_DOPAUSE) 188 anar |= ANAR_FC; 189 PHY_WRITE(sc, MII_ANAR, anar); 190 if (sc->mii_flags & MIIF_HAVE_GTCR) { 191 uint16_t gtcr = 0; | 181 anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | 182 ANAR_CSMA; 183 if (sc->mii_flags & MIIF_DOPAUSE) 184 anar |= ANAR_FC; 185 PHY_WRITE(sc, MII_ANAR, anar); 186 if (sc->mii_flags & MIIF_HAVE_GTCR) { 187 uint16_t gtcr = 0; |
192 | 188 |
193 if (sc->mii_extcapabilities & EXTSR_1000TFDX) 194 gtcr |= GTCR_ADV_1000TFDX; 195 if (sc->mii_extcapabilities & EXTSR_1000THDX) 196 gtcr |= GTCR_ADV_1000THDX; | 189 if (sc->mii_extcapabilities & EXTSR_1000TFDX) 190 gtcr |= GTCR_ADV_1000TFDX; 191 if (sc->mii_extcapabilities & EXTSR_1000THDX) 192 gtcr |= GTCR_ADV_1000THDX; |
197 | 193 |
198 PHY_WRITE(sc, MII_100T2CR, gtcr); 199 } | 194 PHY_WRITE(sc, MII_100T2CR, gtcr); |
200 } | 195 } |
201 PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); | |
202 } | 196 } |
203 204 if (waitfor) { 205 /* Wait 500ms for it to complete. */ 206 for (i = 0; i < 500; i++) { 207 if ((bmsr = PHY_READ(sc, MII_BMSR)) & BMSR_ACOMP) 208 return (0); 209 DELAY(1000); 210 } 211 212 /* 213 * Don't need to worry about clearing MIIF_DOINGAUTO. 214 * If that's set, a timeout is pending, and it will 215 * clear the flag. 216 */ 217 return (EIO); 218 } 219 220 /* 221 * Just let it finish asynchronously. This is for the benefit of 222 * the tick handler driving autonegotiation. Don't want 500ms 223 * delays all the time while the system is running! 224 */ 225 if ((sc->mii_flags & MIIF_DOINGAUTO) == 0) { 226 sc->mii_flags |= MIIF_DOINGAUTO; 227 sc->mii_auto_ch = timeout(mii_phy_auto_timeout, sc, hz >> 1); 228 } | 197 PHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG); |
229 return (EJUSTRETURN); 230} 231 | 198 return (EJUSTRETURN); 199} 200 |
232void 233mii_phy_auto_timeout(void *arg) 234{ 235 struct mii_softc *sc = arg; 236 int s, bmsr; 237 238#if 0 239 if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0) 240 return; 241#endif 242 243 s = splnet(); 244 sc->mii_flags &= ~MIIF_DOINGAUTO; 245 bmsr = PHY_READ(sc, MII_BMSR); 246 247 /* Update the media status. */ 248 (void) (*sc->mii_service)(sc, sc->mii_pdata, MII_POLLSTAT); 249 splx(s); 250} 251 | |
252int 253mii_phy_tick(struct mii_softc *sc) 254{ 255 struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur; 256 struct ifnet *ifp = sc->mii_pdata->mii_ifp; 257 int reg; 258 259 /* Just bail now if the interface is down. */ --- 23 unchanged lines hidden (view full) --- 283 */ 284 if (sc->mii_anegticks == 0) 285 sc->mii_anegticks = 5; 286 if (++sc->mii_ticks != sc->mii_anegticks) 287 return (EJUSTRETURN); 288 289 sc->mii_ticks = 0; 290 mii_phy_reset(sc); | 201int 202mii_phy_tick(struct mii_softc *sc) 203{ 204 struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur; 205 struct ifnet *ifp = sc->mii_pdata->mii_ifp; 206 int reg; 207 208 /* Just bail now if the interface is down. */ --- 23 unchanged lines hidden (view full) --- 232 */ 233 if (sc->mii_anegticks == 0) 234 sc->mii_anegticks = 5; 235 if (++sc->mii_ticks != sc->mii_anegticks) 236 return (EJUSTRETURN); 237 238 sc->mii_ticks = 0; 239 mii_phy_reset(sc); |
291 if (mii_phy_auto(sc, 0) == EJUSTRETURN) 292 return (EJUSTRETURN); 293 294 /* 295 * Might need to generate a status message if autonegotiation 296 * failed. 297 */ | 240 mii_phy_auto(sc); |
298 return (0); 299} 300 301void 302mii_phy_reset(struct mii_softc *sc) 303{ 304 int reg, i; 305 --- 14 unchanged lines hidden (view full) --- 320 if (sc->mii_inst != 0 && ((sc->mii_flags & MIIF_NOISOLATE) == 0)) 321 PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 322} 323 324void 325mii_phy_down(struct mii_softc *sc) 326{ 327 | 241 return (0); 242} 243 244void 245mii_phy_reset(struct mii_softc *sc) 246{ 247 int reg, i; 248 --- 14 unchanged lines hidden (view full) --- 263 if (sc->mii_inst != 0 && ((sc->mii_flags & MIIF_NOISOLATE) == 0)) 264 PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 265} 266 267void 268mii_phy_down(struct mii_softc *sc) 269{ 270 |
328 if (sc->mii_flags & MIIF_DOINGAUTO) { 329 sc->mii_flags &= ~MIIF_DOINGAUTO; 330 untimeout(mii_phy_auto_timeout, sc, sc->mii_auto_ch); 331 } | |
332} 333 334void 335mii_phy_update(struct mii_softc *sc, int cmd) 336{ 337 struct mii_data *mii = sc->mii_pdata; 338 339 if (sc->mii_media_active != mii->mii_media_active || --- 268 unchanged lines hidden --- | 271} 272 273void 274mii_phy_update(struct mii_softc *sc, int cmd) 275{ 276 struct mii_data *mii = sc->mii_pdata; 277 278 if (sc->mii_media_active != mii->mii_media_active || --- 268 unchanged lines hidden --- |