ip1000phy.c (217412) | ip1000phy.c (221407) |
---|---|
1/*- 2 * Copyright (c) 2006, Pyun YongHyeon <yongari@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006, Pyun YongHyeon <yongari@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/dev/mii/ip1000phy.c 217412 2011-01-14 19:16:59Z marius $"); | 30__FBSDID("$FreeBSD: head/sys/dev/mii/ip1000phy.c 221407 2011-05-03 19:51:29Z marius $"); |
31 32/* 33 * Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY. 34 */ 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/kernel.h> --- 13 unchanged lines hidden (view full) --- 52#include "miibus_if.h" 53 54#include <machine/bus.h> 55#include <dev/stge/if_stgereg.h> 56 57static int ip1000phy_probe(device_t); 58static int ip1000phy_attach(device_t); 59 | 31 32/* 33 * Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY. 34 */ 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/kernel.h> --- 13 unchanged lines hidden (view full) --- 52#include "miibus_if.h" 53 54#include <machine/bus.h> 55#include <dev/stge/if_stgereg.h> 56 57static int ip1000phy_probe(device_t); 58static int ip1000phy_attach(device_t); 59 |
60struct ip1000phy_softc { 61 struct mii_softc mii_sc; 62 int model; 63 int revision; 64}; 65 | |
66static device_method_t ip1000phy_methods[] = { 67 /* device interface */ 68 DEVMETHOD(device_probe, ip1000phy_probe), 69 DEVMETHOD(device_attach, ip1000phy_attach), 70 DEVMETHOD(device_detach, mii_phy_detach), 71 DEVMETHOD(device_shutdown, bus_generic_shutdown), 72 { 0, 0 } 73}; --- 8 unchanged lines hidden (view full) --- 82DRIVER_MODULE(ip1000phy, miibus, ip1000phy_driver, ip1000phy_devclass, 0, 0); 83 84static int ip1000phy_service(struct mii_softc *, struct mii_data *, int); 85static void ip1000phy_status(struct mii_softc *); 86static void ip1000phy_reset(struct mii_softc *); 87static int ip1000phy_mii_phy_auto(struct mii_softc *, int); 88 89static const struct mii_phydesc ip1000phys[] = { | 60static device_method_t ip1000phy_methods[] = { 61 /* device interface */ 62 DEVMETHOD(device_probe, ip1000phy_probe), 63 DEVMETHOD(device_attach, ip1000phy_attach), 64 DEVMETHOD(device_detach, mii_phy_detach), 65 DEVMETHOD(device_shutdown, bus_generic_shutdown), 66 { 0, 0 } 67}; --- 8 unchanged lines hidden (view full) --- 76DRIVER_MODULE(ip1000phy, miibus, ip1000phy_driver, ip1000phy_devclass, 0, 0); 77 78static int ip1000phy_service(struct mii_softc *, struct mii_data *, int); 79static void ip1000phy_status(struct mii_softc *); 80static void ip1000phy_reset(struct mii_softc *); 81static int ip1000phy_mii_phy_auto(struct mii_softc *, int); 82 83static const struct mii_phydesc ip1000phys[] = { |
90 MII_PHY_DESC(ICPLUS, IP1000A), 91 MII_PHY_DESC(ICPLUS, IP1001), | 84 MII_PHY_DESC(xxICPLUS, IP1000A), 85 MII_PHY_DESC(xxICPLUS, IP1001), |
92 MII_PHY_END 93}; 94 | 86 MII_PHY_END 87}; 88 |
89static const struct mii_phy_funcs ip1000phy_funcs = { 90 ip1000phy_service, 91 ip1000phy_status, 92 ip1000phy_reset 93}; 94 |
|
95static int 96ip1000phy_probe(device_t dev) 97{ 98 99 return (mii_phy_dev_probe(dev, ip1000phys, BUS_PROBE_DEFAULT)); 100} 101 102static int 103ip1000phy_attach(device_t dev) 104{ | 95static int 96ip1000phy_probe(device_t dev) 97{ 98 99 return (mii_phy_dev_probe(dev, ip1000phys, BUS_PROBE_DEFAULT)); 100} 101 102static int 103ip1000phy_attach(device_t dev) 104{ |
105 struct ip1000phy_softc *isc; 106 struct mii_softc *sc; | |
107 struct mii_attach_args *ma; | 105 struct mii_attach_args *ma; |
108 struct mii_data *mii; | 106 u_int flags; |
109 | 107 |
110 isc = device_get_softc(dev); 111 sc = &isc->mii_sc; | |
112 ma = device_get_ivars(dev); | 108 ma = device_get_ivars(dev); |
113 sc->mii_dev = device_get_parent(dev); 114 mii = ma->mii_data; 115 LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); 116 117 sc->mii_flags = miibus_get_flags(dev); 118 sc->mii_inst = mii->mii_instance++; 119 sc->mii_phy = ma->mii_phyno; 120 sc->mii_service = ip1000phy_service; 121 sc->mii_pdata = mii; 122 123 sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOMANPAUSE; 124 125 isc->model = MII_MODEL(ma->mii_id2); 126 isc->revision = MII_REV(ma->mii_id2); 127 if (isc->model == MII_MODEL_ICPLUS_IP1000A && 128 strcmp(mii->mii_ifp->if_dname, "stge") == 0 && 129 (sc->mii_flags & MIIF_MACPRIV0) != 0) 130 sc->mii_flags |= MIIF_PHYPRIV0; 131 132 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; 133 if (sc->mii_capabilities & BMSR_EXTSTAT) 134 sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); 135 device_printf(dev, " "); 136 137 ip1000phy_reset(sc); 138 mii_phy_add_media(sc); 139 printf("\n"); 140 141 MIIBUS_MEDIAINIT(sc->mii_dev); | 109 flags = MIIF_NOISOLATE | MIIF_NOMANPAUSE; 110 if (MII_MODEL(ma->mii_id2) == MII_MODEL_xxICPLUS_IP1000A && 111 strcmp(ma->mii_data->mii_ifp->if_dname, "stge") == 0 && 112 (miibus_get_flags(dev) & MIIF_MACPRIV0) != 0) 113 flags |= MIIF_PHYPRIV0; 114 mii_phy_dev_attach(dev, flags, &ip1000phy_funcs, 0); |
142 return (0); 143} 144 145static int 146ip1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 147{ 148 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 149 uint32_t gig, reg, speed; --- 5 unchanged lines hidden (view full) --- 155 case MII_MEDIACHG: 156 /* 157 * If the interface is not up, don't do anything. 158 */ 159 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) { 160 break; 161 } 162 | 115 return (0); 116} 117 118static int 119ip1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 120{ 121 struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 122 uint32_t gig, reg, speed; --- 5 unchanged lines hidden (view full) --- 128 case MII_MEDIACHG: 129 /* 130 * If the interface is not up, don't do anything. 131 */ 132 if ((mii->mii_ifp->if_flags & IFF_UP) == 0) { 133 break; 134 } 135 |
163 ip1000phy_reset(sc); | 136 PHY_RESET(sc); |
164 switch (IFM_SUBTYPE(ife->ifm_media)) { 165 case IFM_AUTO: 166 (void)ip1000phy_mii_phy_auto(sc, ife->ifm_media); 167 goto done; 168 169 case IFM_1000_T: 170 /* 171 * XXX --- 68 unchanged lines hidden (view full) --- 240 break; 241 242 sc->mii_ticks = 0; 243 ip1000phy_mii_phy_auto(sc, ife->ifm_media); 244 break; 245 } 246 247 /* Update the media status. */ | 137 switch (IFM_SUBTYPE(ife->ifm_media)) { 138 case IFM_AUTO: 139 (void)ip1000phy_mii_phy_auto(sc, ife->ifm_media); 140 goto done; 141 142 case IFM_1000_T: 143 /* 144 * XXX --- 68 unchanged lines hidden (view full) --- 213 break; 214 215 sc->mii_ticks = 0; 216 ip1000phy_mii_phy_auto(sc, ife->ifm_media); 217 break; 218 } 219 220 /* Update the media status. */ |
248 ip1000phy_status(sc); | 221 PHY_STATUS(sc); |
249 250 /* Callback if something changed. */ 251 mii_phy_update(sc, cmd); 252 return (0); 253} 254 255static void 256ip1000phy_status(struct mii_softc *sc) 257{ | 222 223 /* Callback if something changed. */ 224 mii_phy_update(sc, cmd); 225 return (0); 226} 227 228static void 229ip1000phy_status(struct mii_softc *sc) 230{ |
258 struct ip1000phy_softc *isc; | |
259 struct mii_data *mii = sc->mii_pdata; 260 uint32_t bmsr, bmcr, stat; 261 | 231 struct mii_data *mii = sc->mii_pdata; 232 uint32_t bmsr, bmcr, stat; 233 |
262 isc = (struct ip1000phy_softc *)sc; 263 | |
264 mii->mii_media_status = IFM_AVALID; 265 mii->mii_media_active = IFM_ETHER; 266 267 bmsr = PHY_READ(sc, IP1000PHY_MII_BMSR) | 268 PHY_READ(sc, IP1000PHY_MII_BMSR); 269 if ((bmsr & IP1000PHY_BMSR_LINK) != 0) 270 mii->mii_media_status |= IFM_ACTIVE; 271 --- 4 unchanged lines hidden (view full) --- 276 if ((bmcr & IP1000PHY_BMCR_AUTOEN) != 0) { 277 if ((bmsr & IP1000PHY_BMSR_ANEGCOMP) == 0) { 278 /* Erg, still trying, I guess... */ 279 mii->mii_media_active |= IFM_NONE; 280 return; 281 } 282 } 283 | 234 mii->mii_media_status = IFM_AVALID; 235 mii->mii_media_active = IFM_ETHER; 236 237 bmsr = PHY_READ(sc, IP1000PHY_MII_BMSR) | 238 PHY_READ(sc, IP1000PHY_MII_BMSR); 239 if ((bmsr & IP1000PHY_BMSR_LINK) != 0) 240 mii->mii_media_status |= IFM_ACTIVE; 241 --- 4 unchanged lines hidden (view full) --- 246 if ((bmcr & IP1000PHY_BMCR_AUTOEN) != 0) { 247 if ((bmsr & IP1000PHY_BMSR_ANEGCOMP) == 0) { 248 /* Erg, still trying, I guess... */ 249 mii->mii_media_active |= IFM_NONE; 250 return; 251 } 252 } 253 |
284 if (isc->model == MII_MODEL_ICPLUS_IP1001) { | 254 if (sc->mii_mpd_model == MII_MODEL_xxICPLUS_IP1001) { |
285 stat = PHY_READ(sc, IP1000PHY_LSR); 286 switch (stat & IP1000PHY_LSR_SPEED_MASK) { 287 case IP1000PHY_LSR_SPEED_10: 288 mii->mii_media_active |= IFM_10_T; 289 break; 290 case IP1000PHY_LSR_SPEED_100: 291 mii->mii_media_active |= IFM_100_TX; 292 break; --- 41 unchanged lines hidden (view full) --- 334 if ((stat & IP1000PHY_1000SR_MASTER) != 0) 335 mii->mii_media_active |= IFM_ETH_MASTER; 336 } 337} 338 339static int 340ip1000phy_mii_phy_auto(struct mii_softc *sc, int media) 341{ | 255 stat = PHY_READ(sc, IP1000PHY_LSR); 256 switch (stat & IP1000PHY_LSR_SPEED_MASK) { 257 case IP1000PHY_LSR_SPEED_10: 258 mii->mii_media_active |= IFM_10_T; 259 break; 260 case IP1000PHY_LSR_SPEED_100: 261 mii->mii_media_active |= IFM_100_TX; 262 break; --- 41 unchanged lines hidden (view full) --- 304 if ((stat & IP1000PHY_1000SR_MASTER) != 0) 305 mii->mii_media_active |= IFM_ETH_MASTER; 306 } 307} 308 309static int 310ip1000phy_mii_phy_auto(struct mii_softc *sc, int media) 311{ |
342 struct ip1000phy_softc *isc; | |
343 uint32_t reg; 344 | 312 uint32_t reg; 313 |
345 isc = (struct ip1000phy_softc *)sc; | |
346 reg = 0; | 314 reg = 0; |
347 if (isc->model == MII_MODEL_ICPLUS_IP1001) { | 315 if (sc->mii_mpd_model == MII_MODEL_xxICPLUS_IP1001) { |
348 reg = PHY_READ(sc, IP1000PHY_MII_ANAR); 349 reg &= ~(IP1000PHY_ANAR_PAUSE | IP1000PHY_ANAR_APAUSE); 350 reg |= IP1000PHY_ANAR_NP; 351 } 352 reg |= IP1000PHY_ANAR_10T | IP1000PHY_ANAR_10T_FDX | 353 IP1000PHY_ANAR_100TX | IP1000PHY_ANAR_100TX_FDX; 354 if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) 355 reg |= IP1000PHY_ANAR_PAUSE | IP1000PHY_ANAR_APAUSE; --- 41 unchanged lines hidden --- | 316 reg = PHY_READ(sc, IP1000PHY_MII_ANAR); 317 reg &= ~(IP1000PHY_ANAR_PAUSE | IP1000PHY_ANAR_APAUSE); 318 reg |= IP1000PHY_ANAR_NP; 319 } 320 reg |= IP1000PHY_ANAR_10T | IP1000PHY_ANAR_10T_FDX | 321 IP1000PHY_ANAR_100TX | IP1000PHY_ANAR_100TX_FDX; 322 if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0) 323 reg |= IP1000PHY_ANAR_PAUSE | IP1000PHY_ANAR_APAUSE; --- 41 unchanged lines hidden --- |