Blame view
drivers/net/sungem_phy.c
29.8 KB
09c434b8a treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c Linux-2.6.12-rc2 |
2 3 |
/* * PHY drivers for the sungem ethernet driver. |
6aa20a223 drivers/net: Trim... |
4 |
* |
1da177e4c Linux-2.6.12-rc2 |
5 |
* This file could be shared with other drivers. |
6aa20a223 drivers/net: Trim... |
6 |
* |
63ea998a2 [SUNGEM]: PHY upd... |
7 |
* (c) 2002-2007, Benjamin Herrenscmidt (benh@kernel.crashing.org) |
1da177e4c Linux-2.6.12-rc2 |
8 9 |
* * TODO: |
1da177e4c Linux-2.6.12-rc2 |
10 11 12 13 14 15 16 17 18 19 20 |
* - Add support for PHYs that provide an IRQ line * - Eventually moved the entire polling state machine in * there (out of the eth driver), so that it can easily be * skipped on PHYs that implement it in hardware. * - On LXT971 & BCM5201, Apple uses some chip specific regs * to read the link status. Figure out why and if it makes * sense to do the same (magic aneg ?) * - Apple has some additional power management code for some * Broadcom PHYs that they "hide" from the OpenSource version * of darwin, still need to reverse engineer that */ |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 24 |
#include <linux/module.h> #include <linux/kernel.h> |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 28 29 30 |
#include <linux/types.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/mii.h> #include <linux/ethtool.h> #include <linux/delay.h> |
3c326fe9c [PATCH] ppc64: Ad... |
31 32 33 |
#ifdef CONFIG_PPC_PMAC #include <asm/prom.h> #endif |
ef37d38a1 sungem: sungem_ph... |
34 |
#include <linux/sungem_phy.h> |
1da177e4c Linux-2.6.12-rc2 |
35 36 |
/* Link modes of the BCM5400 PHY */ |
f71e13096 Massive net drive... |
37 |
static const int phy_BCM5400_link_table[8][3] = { |
1da177e4c Linux-2.6.12-rc2 |
38 39 40 41 42 43 44 45 46 |
{ 0, 0, 0 }, /* No link */ { 0, 0, 0 }, /* 10BT Half Duplex */ { 1, 0, 0 }, /* 10BT Full Duplex */ { 0, 1, 0 }, /* 100BT Half Duplex */ { 0, 1, 0 }, /* 100BT Half Duplex */ { 1, 1, 0 }, /* 100BT Full Duplex*/ { 1, 0, 1 }, /* 1000BT */ { 1, 0, 1 }, /* 1000BT */ }; |
abc4da450 sungem: Fix globa... |
47 |
static inline int __sungem_phy_read(struct mii_phy* phy, int id, int reg) |
1da177e4c Linux-2.6.12-rc2 |
48 49 50 |
{ return phy->mdio_read(phy->dev, id, reg); } |
abc4da450 sungem: Fix globa... |
51 |
static inline void __sungem_phy_write(struct mii_phy* phy, int id, int reg, int val) |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 |
{ phy->mdio_write(phy->dev, id, reg, val); } |
abc4da450 sungem: Fix globa... |
55 |
static inline int sungem_phy_read(struct mii_phy* phy, int reg) |
1da177e4c Linux-2.6.12-rc2 |
56 57 58 |
{ return phy->mdio_read(phy->dev, phy->mii_id, reg); } |
abc4da450 sungem: Fix globa... |
59 |
static inline void sungem_phy_write(struct mii_phy* phy, int reg, int val) |
1da177e4c Linux-2.6.12-rc2 |
60 61 62 63 64 65 66 67 |
{ phy->mdio_write(phy->dev, phy->mii_id, reg, val); } static int reset_one_mii_phy(struct mii_phy* phy, int phy_id) { u16 val; int limit = 10000; |
6aa20a223 drivers/net: Trim... |
68 |
|
abc4da450 sungem: Fix globa... |
69 |
val = __sungem_phy_read(phy, phy_id, MII_BMCR); |
1da177e4c Linux-2.6.12-rc2 |
70 71 |
val &= ~(BMCR_ISOLATE | BMCR_PDOWN); val |= BMCR_RESET; |
abc4da450 sungem: Fix globa... |
72 |
__sungem_phy_write(phy, phy_id, MII_BMCR, val); |
1da177e4c Linux-2.6.12-rc2 |
73 74 |
udelay(100); |
ff01b9163 cassini/sungem: l... |
75 |
while (--limit) { |
abc4da450 sungem: Fix globa... |
76 |
val = __sungem_phy_read(phy, phy_id, MII_BMCR); |
1da177e4c Linux-2.6.12-rc2 |
77 78 79 80 81 |
if ((val & BMCR_RESET) == 0) break; udelay(10); } if ((val & BMCR_ISOLATE) && limit > 0) |
abc4da450 sungem: Fix globa... |
82 |
__sungem_phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE); |
6aa20a223 drivers/net: Trim... |
83 |
|
807540baa drivers/net: retu... |
84 |
return limit <= 0; |
1da177e4c Linux-2.6.12-rc2 |
85 86 87 88 89 |
} static int bcm5201_init(struct mii_phy* phy) { u16 data; |
abc4da450 sungem: Fix globa... |
90 |
data = sungem_phy_read(phy, MII_BCM5201_MULTIPHY); |
1da177e4c Linux-2.6.12-rc2 |
91 |
data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE; |
abc4da450 sungem: Fix globa... |
92 |
sungem_phy_write(phy, MII_BCM5201_MULTIPHY, data); |
1da177e4c Linux-2.6.12-rc2 |
93 |
|
abc4da450 sungem: Fix globa... |
94 |
sungem_phy_write(phy, MII_BCM5201_INTERRUPT, 0); |
1da177e4c Linux-2.6.12-rc2 |
95 96 97 98 99 100 |
return 0; } static int bcm5201_suspend(struct mii_phy* phy) { |
abc4da450 sungem: Fix globa... |
101 102 |
sungem_phy_write(phy, MII_BCM5201_INTERRUPT, 0); sungem_phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE); |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 106 107 108 109 |
return 0; } static int bcm5221_init(struct mii_phy* phy) { u16 data; |
abc4da450 sungem: Fix globa... |
110 111 |
data = sungem_phy_read(phy, MII_BCM5221_TEST); sungem_phy_write(phy, MII_BCM5221_TEST, |
1da177e4c Linux-2.6.12-rc2 |
112 |
data | MII_BCM5221_TEST_ENABLE_SHADOWS); |
abc4da450 sungem: Fix globa... |
113 114 |
data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2); sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2, |
1da177e4c Linux-2.6.12-rc2 |
115 |
data | MII_BCM5221_SHDOW_AUX_STAT2_APD); |
abc4da450 sungem: Fix globa... |
116 117 |
data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, |
1da177e4c Linux-2.6.12-rc2 |
118 |
data | MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR); |
abc4da450 sungem: Fix globa... |
119 120 |
data = sungem_phy_read(phy, MII_BCM5221_TEST); sungem_phy_write(phy, MII_BCM5221_TEST, |
1da177e4c Linux-2.6.12-rc2 |
121 122 123 124 125 126 127 128 |
data & ~MII_BCM5221_TEST_ENABLE_SHADOWS); return 0; } static int bcm5221_suspend(struct mii_phy* phy) { u16 data; |
abc4da450 sungem: Fix globa... |
129 130 |
data = sungem_phy_read(phy, MII_BCM5221_TEST); sungem_phy_write(phy, MII_BCM5221_TEST, |
1da177e4c Linux-2.6.12-rc2 |
131 |
data | MII_BCM5221_TEST_ENABLE_SHADOWS); |
abc4da450 sungem: Fix globa... |
132 133 |
data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, |
1da177e4c Linux-2.6.12-rc2 |
134 135 136 137 |
data | MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE); return 0; } |
63ea998a2 [SUNGEM]: PHY upd... |
138 139 140 |
static int bcm5241_init(struct mii_phy* phy) { u16 data; |
abc4da450 sungem: Fix globa... |
141 142 |
data = sungem_phy_read(phy, MII_BCM5221_TEST); sungem_phy_write(phy, MII_BCM5221_TEST, |
63ea998a2 [SUNGEM]: PHY upd... |
143 |
data | MII_BCM5221_TEST_ENABLE_SHADOWS); |
abc4da450 sungem: Fix globa... |
144 145 |
data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2); sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2, |
63ea998a2 [SUNGEM]: PHY upd... |
146 |
data | MII_BCM5221_SHDOW_AUX_STAT2_APD); |
abc4da450 sungem: Fix globa... |
147 148 |
data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, |
63ea998a2 [SUNGEM]: PHY upd... |
149 |
data & ~MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR); |
abc4da450 sungem: Fix globa... |
150 151 |
data = sungem_phy_read(phy, MII_BCM5221_TEST); sungem_phy_write(phy, MII_BCM5221_TEST, |
63ea998a2 [SUNGEM]: PHY upd... |
152 153 154 155 156 157 158 159 |
data & ~MII_BCM5221_TEST_ENABLE_SHADOWS); return 0; } static int bcm5241_suspend(struct mii_phy* phy) { u16 data; |
abc4da450 sungem: Fix globa... |
160 161 |
data = sungem_phy_read(phy, MII_BCM5221_TEST); sungem_phy_write(phy, MII_BCM5221_TEST, |
63ea998a2 [SUNGEM]: PHY upd... |
162 |
data | MII_BCM5221_TEST_ENABLE_SHADOWS); |
abc4da450 sungem: Fix globa... |
163 164 |
data = sungem_phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4); sungem_phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4, |
63ea998a2 [SUNGEM]: PHY upd... |
165 166 167 168 |
data | MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
169 170 171 172 173 |
static int bcm5400_init(struct mii_phy* phy) { u16 data; /* Configure for gigabit full duplex */ |
abc4da450 sungem: Fix globa... |
174 |
data = sungem_phy_read(phy, MII_BCM5400_AUXCONTROL); |
1da177e4c Linux-2.6.12-rc2 |
175 |
data |= MII_BCM5400_AUXCONTROL_PWR10BASET; |
abc4da450 sungem: Fix globa... |
176 |
sungem_phy_write(phy, MII_BCM5400_AUXCONTROL, data); |
6aa20a223 drivers/net: Trim... |
177 |
|
abc4da450 sungem: Fix globa... |
178 |
data = sungem_phy_read(phy, MII_BCM5400_GB_CONTROL); |
1da177e4c Linux-2.6.12-rc2 |
179 |
data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; |
abc4da450 sungem: Fix globa... |
180 |
sungem_phy_write(phy, MII_BCM5400_GB_CONTROL, data); |
6aa20a223 drivers/net: Trim... |
181 |
|
1da177e4c Linux-2.6.12-rc2 |
182 183 184 185 |
udelay(100); /* Reset and configure cascaded 10/100 PHY */ (void)reset_one_mii_phy(phy, 0x1f); |
6aa20a223 drivers/net: Trim... |
186 |
|
abc4da450 sungem: Fix globa... |
187 |
data = __sungem_phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY); |
1da177e4c Linux-2.6.12-rc2 |
188 |
data |= MII_BCM5201_MULTIPHY_SERIALMODE; |
abc4da450 sungem: Fix globa... |
189 |
__sungem_phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data); |
1da177e4c Linux-2.6.12-rc2 |
190 |
|
abc4da450 sungem: Fix globa... |
191 |
data = sungem_phy_read(phy, MII_BCM5400_AUXCONTROL); |
1da177e4c Linux-2.6.12-rc2 |
192 |
data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET; |
abc4da450 sungem: Fix globa... |
193 |
sungem_phy_write(phy, MII_BCM5400_AUXCONTROL, data); |
1da177e4c Linux-2.6.12-rc2 |
194 195 196 197 198 199 200 |
return 0; } static int bcm5400_suspend(struct mii_phy* phy) { #if 0 /* Commented out in Darwin... someone has those dawn docs ? */ |
abc4da450 sungem: Fix globa... |
201 |
sungem_phy_write(phy, MII_BMCR, BMCR_PDOWN); |
1da177e4c Linux-2.6.12-rc2 |
202 203 204 205 206 207 208 209 |
#endif return 0; } static int bcm5401_init(struct mii_phy* phy) { u16 data; int rev; |
abc4da450 sungem: Fix globa... |
210 |
rev = sungem_phy_read(phy, MII_PHYSID2) & 0x000f; |
1da177e4c Linux-2.6.12-rc2 |
211 212 213 214 |
if (rev == 0 || rev == 3) { /* Some revisions of 5401 appear to need this * initialisation sequence to disable, according * to OF, "tap power management" |
6aa20a223 drivers/net: Trim... |
215 |
* |
1da177e4c Linux-2.6.12-rc2 |
216 217 218 219 220 221 222 |
* WARNING ! OF and Darwin don't agree on the * register addresses. OF seem to interpret the * register numbers below as decimal * * Note: This should (and does) match tg3_init_5401phy_dsp * in the tg3.c driver. -DaveM */ |
abc4da450 sungem: Fix globa... |
223 224 225 226 227 228 229 230 231 232 233 |
sungem_phy_write(phy, 0x18, 0x0c20); sungem_phy_write(phy, 0x17, 0x0012); sungem_phy_write(phy, 0x15, 0x1804); sungem_phy_write(phy, 0x17, 0x0013); sungem_phy_write(phy, 0x15, 0x1204); sungem_phy_write(phy, 0x17, 0x8006); sungem_phy_write(phy, 0x15, 0x0132); sungem_phy_write(phy, 0x17, 0x8006); sungem_phy_write(phy, 0x15, 0x0232); sungem_phy_write(phy, 0x17, 0x201f); sungem_phy_write(phy, 0x15, 0x0a20); |
1da177e4c Linux-2.6.12-rc2 |
234 |
} |
6aa20a223 drivers/net: Trim... |
235 |
|
1da177e4c Linux-2.6.12-rc2 |
236 |
/* Configure for gigabit full duplex */ |
abc4da450 sungem: Fix globa... |
237 |
data = sungem_phy_read(phy, MII_BCM5400_GB_CONTROL); |
1da177e4c Linux-2.6.12-rc2 |
238 |
data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; |
abc4da450 sungem: Fix globa... |
239 |
sungem_phy_write(phy, MII_BCM5400_GB_CONTROL, data); |
1da177e4c Linux-2.6.12-rc2 |
240 241 242 243 244 |
udelay(10); /* Reset and configure cascaded 10/100 PHY */ (void)reset_one_mii_phy(phy, 0x1f); |
6aa20a223 drivers/net: Trim... |
245 |
|
abc4da450 sungem: Fix globa... |
246 |
data = __sungem_phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY); |
1da177e4c Linux-2.6.12-rc2 |
247 |
data |= MII_BCM5201_MULTIPHY_SERIALMODE; |
abc4da450 sungem: Fix globa... |
248 |
__sungem_phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data); |
1da177e4c Linux-2.6.12-rc2 |
249 250 251 252 253 254 255 |
return 0; } static int bcm5401_suspend(struct mii_phy* phy) { #if 0 /* Commented out in Darwin... someone has those dawn docs ? */ |
abc4da450 sungem: Fix globa... |
256 |
sungem_phy_write(phy, MII_BMCR, BMCR_PDOWN); |
1da177e4c Linux-2.6.12-rc2 |
257 258 259 260 261 262 263 264 265 266 267 |
#endif return 0; } static int bcm5411_init(struct mii_phy* phy) { u16 data; /* Here's some more Apple black magic to setup * some voltage stuffs. */ |
abc4da450 sungem: Fix globa... |
268 269 270 |
sungem_phy_write(phy, 0x1c, 0x8c23); sungem_phy_write(phy, 0x1c, 0x8ca3); sungem_phy_write(phy, 0x1c, 0x8c23); |
1da177e4c Linux-2.6.12-rc2 |
271 272 273 274 |
/* Here, Apple seems to want to reset it, do * it as well */ |
abc4da450 sungem: Fix globa... |
275 276 |
sungem_phy_write(phy, MII_BMCR, BMCR_RESET); sungem_phy_write(phy, MII_BMCR, 0x1340); |
1da177e4c Linux-2.6.12-rc2 |
277 |
|
abc4da450 sungem: Fix globa... |
278 |
data = sungem_phy_read(phy, MII_BCM5400_GB_CONTROL); |
1da177e4c Linux-2.6.12-rc2 |
279 |
data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP; |
abc4da450 sungem: Fix globa... |
280 |
sungem_phy_write(phy, MII_BCM5400_GB_CONTROL, data); |
1da177e4c Linux-2.6.12-rc2 |
281 282 283 284 285 |
udelay(10); /* Reset and configure cascaded 10/100 PHY */ (void)reset_one_mii_phy(phy, 0x1f); |
6aa20a223 drivers/net: Trim... |
286 |
|
1da177e4c Linux-2.6.12-rc2 |
287 288 |
return 0; } |
eb5b5b2ff sungem_phy: suppo... |
289 290 291 292 293 294 295 296 297 298 299 |
static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise) { u16 ctl, adv; phy->autoneg = 1; phy->speed = SPEED_10; phy->duplex = DUPLEX_HALF; phy->pause = 0; phy->advertising = advertise; /* Setup standard advertise */ |
abc4da450 sungem: Fix globa... |
300 |
adv = sungem_phy_read(phy, MII_ADVERTISE); |
eb5b5b2ff sungem_phy: suppo... |
301 302 303 304 305 306 307 308 309 |
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); if (advertise & ADVERTISED_10baseT_Half) adv |= ADVERTISE_10HALF; if (advertise & ADVERTISED_10baseT_Full) adv |= ADVERTISE_10FULL; if (advertise & ADVERTISED_100baseT_Half) adv |= ADVERTISE_100HALF; if (advertise & ADVERTISED_100baseT_Full) adv |= ADVERTISE_100FULL; |
abc4da450 sungem: Fix globa... |
310 |
sungem_phy_write(phy, MII_ADVERTISE, adv); |
eb5b5b2ff sungem_phy: suppo... |
311 312 |
/* Start/Restart aneg */ |
abc4da450 sungem: Fix globa... |
313 |
ctl = sungem_phy_read(phy, MII_BMCR); |
eb5b5b2ff sungem_phy: suppo... |
314 |
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); |
abc4da450 sungem: Fix globa... |
315 |
sungem_phy_write(phy, MII_BMCR, ctl); |
eb5b5b2ff sungem_phy: suppo... |
316 317 318 319 320 321 322 323 324 325 326 327 |
return 0; } static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd) { u16 ctl; phy->autoneg = 0; phy->speed = speed; phy->duplex = fd; phy->pause = 0; |
abc4da450 sungem: Fix globa... |
328 |
ctl = sungem_phy_read(phy, MII_BMCR); |
eb5b5b2ff sungem_phy: suppo... |
329 330 331 |
ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE); /* First reset the PHY */ |
abc4da450 sungem: Fix globa... |
332 |
sungem_phy_write(phy, MII_BMCR, ctl | BMCR_RESET); |
eb5b5b2ff sungem_phy: suppo... |
333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
/* Select speed & duplex */ switch(speed) { case SPEED_10: break; case SPEED_100: ctl |= BMCR_SPEED100; break; case SPEED_1000: default: return -EINVAL; } if (fd == DUPLEX_FULL) ctl |= BMCR_FULLDPLX; |
abc4da450 sungem: Fix globa... |
347 |
sungem_phy_write(phy, MII_BMCR, ctl); |
eb5b5b2ff sungem_phy: suppo... |
348 349 350 351 352 353 354 |
return 0; } static int genmii_poll_link(struct mii_phy *phy) { u16 status; |
abc4da450 sungem: Fix globa... |
355 356 |
(void)sungem_phy_read(phy, MII_BMSR); status = sungem_phy_read(phy, MII_BMSR); |
eb5b5b2ff sungem_phy: suppo... |
357 358 359 360 361 362 363 364 365 366 367 368 |
if ((status & BMSR_LSTATUS) == 0) return 0; if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE)) return 0; return 1; } static int genmii_read_link(struct mii_phy *phy) { u16 lpa; if (phy->autoneg) { |
abc4da450 sungem: Fix globa... |
369 |
lpa = sungem_phy_read(phy, MII_LPA); |
eb5b5b2ff sungem_phy: suppo... |
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
if (lpa & (LPA_10FULL | LPA_100FULL)) phy->duplex = DUPLEX_FULL; else phy->duplex = DUPLEX_HALF; if (lpa & (LPA_100FULL | LPA_100HALF)) phy->speed = SPEED_100; else phy->speed = SPEED_10; phy->pause = 0; } /* On non-aneg, we assume what we put in BMCR is the speed, * though magic-aneg shouldn't prevent this case from occurring */ return 0; } |
d47f3640f [SUNGEM]: Marvell... |
387 |
static int generic_suspend(struct mii_phy* phy) |
1da177e4c Linux-2.6.12-rc2 |
388 |
{ |
abc4da450 sungem: Fix globa... |
389 |
sungem_phy_write(phy, MII_BMCR, BMCR_PDOWN); |
1da177e4c Linux-2.6.12-rc2 |
390 391 392 393 394 395 396 |
return 0; } static int bcm5421_init(struct mii_phy* phy) { u16 data; |
3c326fe9c [PATCH] ppc64: Ad... |
397 |
unsigned int id; |
1da177e4c Linux-2.6.12-rc2 |
398 |
|
abc4da450 sungem: Fix globa... |
399 |
id = (sungem_phy_read(phy, MII_PHYSID1) << 16 | sungem_phy_read(phy, MII_PHYSID2)); |
3c326fe9c [PATCH] ppc64: Ad... |
400 401 402 |
/* Revision 0 of 5421 needs some fixups */ if (id == 0x002060e0) { |
1da177e4c Linux-2.6.12-rc2 |
403 404 |
/* This is borrowed from MacOS */ |
abc4da450 sungem: Fix globa... |
405 406 407 408 409 410 411 412 413 |
sungem_phy_write(phy, 0x18, 0x1007); data = sungem_phy_read(phy, 0x18); sungem_phy_write(phy, 0x18, data | 0x0400); sungem_phy_write(phy, 0x18, 0x0007); data = sungem_phy_read(phy, 0x18); sungem_phy_write(phy, 0x18, data | 0x0800); sungem_phy_write(phy, 0x17, 0x000a); data = sungem_phy_read(phy, 0x15); sungem_phy_write(phy, 0x15, data | 0x0200); |
1da177e4c Linux-2.6.12-rc2 |
414 |
} |
1da177e4c Linux-2.6.12-rc2 |
415 |
|
3c326fe9c [PATCH] ppc64: Ad... |
416 417 |
/* Pick up some init code from OF for K2 version */ if ((id & 0xfffffff0) == 0x002062e0) { |
abc4da450 sungem: Fix globa... |
418 419 |
sungem_phy_write(phy, 4, 0x01e1); sungem_phy_write(phy, 9, 0x0300); |
3c326fe9c [PATCH] ppc64: Ad... |
420 421 422 423 424 425 426 |
} /* Check if we can enable automatic low power */ #ifdef CONFIG_PPC_PMAC if (phy->platform_data) { struct device_node *np = of_get_parent(phy->platform_data); int can_low_power = 1; |
40cd3a456 [POWERPC] Rename ... |
427 |
if (np == NULL || of_get_property(np, "no-autolowpower", NULL)) |
3c326fe9c [PATCH] ppc64: Ad... |
428 429 430 |
can_low_power = 0; if (can_low_power) { /* Enable automatic low-power */ |
abc4da450 sungem: Fix globa... |
431 432 433 |
sungem_phy_write(phy, 0x1c, 0x9002); sungem_phy_write(phy, 0x1c, 0xa821); sungem_phy_write(phy, 0x1c, 0x941d); |
3c326fe9c [PATCH] ppc64: Ad... |
434 435 436 |
} } #endif /* CONFIG_PPC_PMAC */ |
1da177e4c Linux-2.6.12-rc2 |
437 438 439 440 441 442 443 |
return 0; } static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise) { u16 ctl, adv; |
6aa20a223 drivers/net: Trim... |
444 |
|
1da177e4c Linux-2.6.12-rc2 |
445 446 447 448 449 450 451 |
phy->autoneg = 1; phy->speed = SPEED_10; phy->duplex = DUPLEX_HALF; phy->pause = 0; phy->advertising = advertise; /* Setup standard advertise */ |
abc4da450 sungem: Fix globa... |
452 |
adv = sungem_phy_read(phy, MII_ADVERTISE); |
1da177e4c Linux-2.6.12-rc2 |
453 454 455 456 457 458 459 460 461 |
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); if (advertise & ADVERTISED_10baseT_Half) adv |= ADVERTISE_10HALF; if (advertise & ADVERTISED_10baseT_Full) adv |= ADVERTISE_10FULL; if (advertise & ADVERTISED_100baseT_Half) adv |= ADVERTISE_100HALF; if (advertise & ADVERTISED_100baseT_Full) adv |= ADVERTISE_100FULL; |
63ea998a2 [SUNGEM]: PHY upd... |
462 463 464 465 |
if (advertise & ADVERTISED_Pause) adv |= ADVERTISE_PAUSE_CAP; if (advertise & ADVERTISED_Asym_Pause) adv |= ADVERTISE_PAUSE_ASYM; |
abc4da450 sungem: Fix globa... |
466 |
sungem_phy_write(phy, MII_ADVERTISE, adv); |
1da177e4c Linux-2.6.12-rc2 |
467 468 |
/* Setup 1000BT advertise */ |
abc4da450 sungem: Fix globa... |
469 |
adv = sungem_phy_read(phy, MII_1000BASETCONTROL); |
1da177e4c Linux-2.6.12-rc2 |
470 471 472 473 474 |
adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP|MII_1000BASETCONTROL_HALFDUPLEXCAP); if (advertise & SUPPORTED_1000baseT_Half) adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; if (advertise & SUPPORTED_1000baseT_Full) adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; |
abc4da450 sungem: Fix globa... |
475 |
sungem_phy_write(phy, MII_1000BASETCONTROL, adv); |
1da177e4c Linux-2.6.12-rc2 |
476 477 |
/* Start/Restart aneg */ |
abc4da450 sungem: Fix globa... |
478 |
ctl = sungem_phy_read(phy, MII_BMCR); |
1da177e4c Linux-2.6.12-rc2 |
479 |
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); |
abc4da450 sungem: Fix globa... |
480 |
sungem_phy_write(phy, MII_BMCR, ctl); |
1da177e4c Linux-2.6.12-rc2 |
481 482 483 484 485 486 487 |
return 0; } static int bcm54xx_setup_forced(struct mii_phy *phy, int speed, int fd) { u16 ctl; |
6aa20a223 drivers/net: Trim... |
488 |
|
1da177e4c Linux-2.6.12-rc2 |
489 490 491 492 |
phy->autoneg = 0; phy->speed = speed; phy->duplex = fd; phy->pause = 0; |
abc4da450 sungem: Fix globa... |
493 |
ctl = sungem_phy_read(phy, MII_BMCR); |
1da177e4c Linux-2.6.12-rc2 |
494 495 496 |
ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE); /* First reset the PHY */ |
abc4da450 sungem: Fix globa... |
497 |
sungem_phy_write(phy, MII_BMCR, ctl | BMCR_RESET); |
1da177e4c Linux-2.6.12-rc2 |
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
/* Select speed & duplex */ switch(speed) { case SPEED_10: break; case SPEED_100: ctl |= BMCR_SPEED100; break; case SPEED_1000: ctl |= BMCR_SPD2; } if (fd == DUPLEX_FULL) ctl |= BMCR_FULLDPLX; // XXX Should we set the sungem to GII now on 1000BT ? |
6aa20a223 drivers/net: Trim... |
513 |
|
abc4da450 sungem: Fix globa... |
514 |
sungem_phy_write(phy, MII_BMCR, ctl); |
1da177e4c Linux-2.6.12-rc2 |
515 516 517 518 519 520 |
return 0; } static int bcm54xx_read_link(struct mii_phy *phy) { |
6aa20a223 drivers/net: Trim... |
521 |
int link_mode; |
1da177e4c Linux-2.6.12-rc2 |
522 |
u16 val; |
6aa20a223 drivers/net: Trim... |
523 |
|
1da177e4c Linux-2.6.12-rc2 |
524 |
if (phy->autoneg) { |
abc4da450 sungem: Fix globa... |
525 |
val = sungem_phy_read(phy, MII_BCM5400_AUXSTATUS); |
1da177e4c Linux-2.6.12-rc2 |
526 527 |
link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >> MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT); |
63ea998a2 [SUNGEM]: PHY upd... |
528 529 |
phy->duplex = phy_BCM5400_link_table[link_mode][0] ? DUPLEX_FULL : DUPLEX_HALF; |
1da177e4c Linux-2.6.12-rc2 |
530 531 |
phy->speed = phy_BCM5400_link_table[link_mode][2] ? SPEED_1000 : |
63ea998a2 [SUNGEM]: PHY upd... |
532 533 |
(phy_BCM5400_link_table[link_mode][1] ? SPEED_100 : SPEED_10); |
abc4da450 sungem: Fix globa... |
534 |
val = sungem_phy_read(phy, MII_LPA); |
63ea998a2 [SUNGEM]: PHY upd... |
535 536 |
phy->pause = (phy->duplex == DUPLEX_FULL) && ((val & LPA_PAUSE) != 0); |
1da177e4c Linux-2.6.12-rc2 |
537 538 539 540 541 542 543 |
} /* On non-aneg, we assume what we put in BMCR is the speed, * though magic-aneg shouldn't prevent this case from occurring */ return 0; } |
63ea998a2 [SUNGEM]: PHY upd... |
544 545 546 547 548 |
static int marvell88e1111_init(struct mii_phy* phy) { u16 rev; /* magic init sequence for rev 0 */ |
abc4da450 sungem: Fix globa... |
549 |
rev = sungem_phy_read(phy, MII_PHYSID2) & 0x000f; |
63ea998a2 [SUNGEM]: PHY upd... |
550 |
if (rev == 0) { |
abc4da450 sungem: Fix globa... |
551 552 |
sungem_phy_write(phy, 0x1d, 0x000a); sungem_phy_write(phy, 0x1e, 0x0821); |
63ea998a2 [SUNGEM]: PHY upd... |
553 |
|
abc4da450 sungem: Fix globa... |
554 555 |
sungem_phy_write(phy, 0x1d, 0x0006); sungem_phy_write(phy, 0x1e, 0x8600); |
63ea998a2 [SUNGEM]: PHY upd... |
556 |
|
abc4da450 sungem: Fix globa... |
557 558 |
sungem_phy_write(phy, 0x1d, 0x000b); sungem_phy_write(phy, 0x1e, 0x0100); |
63ea998a2 [SUNGEM]: PHY upd... |
559 |
|
abc4da450 sungem: Fix globa... |
560 561 |
sungem_phy_write(phy, 0x1d, 0x0004); sungem_phy_write(phy, 0x1e, 0x4850); |
63ea998a2 [SUNGEM]: PHY upd... |
562 563 564 |
} return 0; } |
eb5b5b2ff sungem_phy: suppo... |
565 566 567 568 569 570 571 572 |
#define BCM5421_MODE_MASK (1 << 5) static int bcm5421_poll_link(struct mii_phy* phy) { u32 phy_reg; int mode; /* find out in what mode we are */ |
abc4da450 sungem: Fix globa... |
573 574 |
sungem_phy_write(phy, MII_NCONFIG, 0x1000); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
575 576 577 578 579 |
mode = (phy_reg & BCM5421_MODE_MASK) >> 5; if ( mode == BCM54XX_COPPER) return genmii_poll_link(phy); |
48fc7f7e7 Fix misspellings ... |
580 |
/* try to find out whether we have a link */ |
abc4da450 sungem: Fix globa... |
581 582 |
sungem_phy_write(phy, MII_NCONFIG, 0x2000); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
583 584 585 586 587 588 589 590 591 592 593 594 595 |
if (phy_reg & 0x0020) return 0; else return 1; } static int bcm5421_read_link(struct mii_phy* phy) { u32 phy_reg; int mode; /* find out in what mode we are */ |
abc4da450 sungem: Fix globa... |
596 597 |
sungem_phy_write(phy, MII_NCONFIG, 0x1000); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
598 599 600 601 602 603 604 |
mode = (phy_reg & BCM5421_MODE_MASK ) >> 5; if ( mode == BCM54XX_COPPER) return bcm54xx_read_link(phy); phy->speed = SPEED_1000; |
48fc7f7e7 Fix misspellings ... |
605 |
/* find out whether we are running half- or full duplex */ |
abc4da450 sungem: Fix globa... |
606 607 |
sungem_phy_write(phy, MII_NCONFIG, 0x2000); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
608 609 610 611 612 613 614 615 616 617 618 619 |
if ( (phy_reg & 0x0080) >> 7) phy->duplex |= DUPLEX_HALF; else phy->duplex |= DUPLEX_FULL; return 0; } static int bcm5421_enable_fiber(struct mii_phy* phy, int autoneg) { /* enable fiber mode */ |
abc4da450 sungem: Fix globa... |
620 |
sungem_phy_write(phy, MII_NCONFIG, 0x9020); |
eb5b5b2ff sungem_phy: suppo... |
621 |
/* LEDs active in both modes, autosense prio = fiber */ |
abc4da450 sungem: Fix globa... |
622 |
sungem_phy_write(phy, MII_NCONFIG, 0x945f); |
eb5b5b2ff sungem_phy: suppo... |
623 624 625 |
if (!autoneg) { /* switch off fibre autoneg */ |
abc4da450 sungem: Fix globa... |
626 627 |
sungem_phy_write(phy, MII_NCONFIG, 0xfc01); sungem_phy_write(phy, 0x0b, 0x0004); |
eb5b5b2ff sungem_phy: suppo... |
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 |
} phy->autoneg = autoneg; return 0; } #define BCM5461_FIBER_LINK (1 << 2) #define BCM5461_MODE_MASK (3 << 1) static int bcm5461_poll_link(struct mii_phy* phy) { u32 phy_reg; int mode; /* find out in what mode we are */ |
abc4da450 sungem: Fix globa... |
644 645 |
sungem_phy_write(phy, MII_NCONFIG, 0x7c00); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
646 647 648 649 650 |
mode = (phy_reg & BCM5461_MODE_MASK ) >> 1; if ( mode == BCM54XX_COPPER) return genmii_poll_link(phy); |
48fc7f7e7 Fix misspellings ... |
651 |
/* find out whether we have a link */ |
abc4da450 sungem: Fix globa... |
652 653 |
sungem_phy_write(phy, MII_NCONFIG, 0x7000); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 |
if (phy_reg & BCM5461_FIBER_LINK) return 1; else return 0; } #define BCM5461_FIBER_DUPLEX (1 << 3) static int bcm5461_read_link(struct mii_phy* phy) { u32 phy_reg; int mode; /* find out in what mode we are */ |
abc4da450 sungem: Fix globa... |
669 670 |
sungem_phy_write(phy, MII_NCONFIG, 0x7c00); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
671 672 673 674 675 676 677 678 |
mode = (phy_reg & BCM5461_MODE_MASK ) >> 1; if ( mode == BCM54XX_COPPER) { return bcm54xx_read_link(phy); } phy->speed = SPEED_1000; |
48fc7f7e7 Fix misspellings ... |
679 |
/* find out whether we are running half- or full duplex */ |
abc4da450 sungem: Fix globa... |
680 681 |
sungem_phy_write(phy, MII_NCONFIG, 0x7000); phy_reg = sungem_phy_read(phy, MII_NCONFIG); |
eb5b5b2ff sungem_phy: suppo... |
682 683 684 685 686 687 688 689 690 691 692 693 |
if (phy_reg & BCM5461_FIBER_DUPLEX) phy->duplex |= DUPLEX_FULL; else phy->duplex |= DUPLEX_HALF; return 0; } static int bcm5461_enable_fiber(struct mii_phy* phy, int autoneg) { /* select fiber mode, enable 1000 base-X registers */ |
abc4da450 sungem: Fix globa... |
694 |
sungem_phy_write(phy, MII_NCONFIG, 0xfc0b); |
eb5b5b2ff sungem_phy: suppo... |
695 696 697 |
if (autoneg) { /* enable fiber with no autonegotiation */ |
abc4da450 sungem: Fix globa... |
698 699 |
sungem_phy_write(phy, MII_ADVERTISE, 0x01e0); sungem_phy_write(phy, MII_BMCR, 0x1140); |
eb5b5b2ff sungem_phy: suppo... |
700 701 |
} else { /* enable fiber with autonegotiation */ |
abc4da450 sungem: Fix globa... |
702 |
sungem_phy_write(phy, MII_BMCR, 0x0140); |
eb5b5b2ff sungem_phy: suppo... |
703 704 705 706 707 708 |
} phy->autoneg = autoneg; return 0; } |
1da177e4c Linux-2.6.12-rc2 |
709 710 711 |
static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise) { u16 ctl, adv; |
6aa20a223 drivers/net: Trim... |
712 |
|
1da177e4c Linux-2.6.12-rc2 |
713 714 715 716 717 718 719 |
phy->autoneg = 1; phy->speed = SPEED_10; phy->duplex = DUPLEX_HALF; phy->pause = 0; phy->advertising = advertise; /* Setup standard advertise */ |
abc4da450 sungem: Fix globa... |
720 |
adv = sungem_phy_read(phy, MII_ADVERTISE); |
1da177e4c Linux-2.6.12-rc2 |
721 722 723 724 725 726 727 728 729 |
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); if (advertise & ADVERTISED_10baseT_Half) adv |= ADVERTISE_10HALF; if (advertise & ADVERTISED_10baseT_Full) adv |= ADVERTISE_10FULL; if (advertise & ADVERTISED_100baseT_Half) adv |= ADVERTISE_100HALF; if (advertise & ADVERTISED_100baseT_Full) adv |= ADVERTISE_100FULL; |
63ea998a2 [SUNGEM]: PHY upd... |
730 731 732 733 |
if (advertise & ADVERTISED_Pause) adv |= ADVERTISE_PAUSE_CAP; if (advertise & ADVERTISED_Asym_Pause) adv |= ADVERTISE_PAUSE_ASYM; |
abc4da450 sungem: Fix globa... |
734 |
sungem_phy_write(phy, MII_ADVERTISE, adv); |
1da177e4c Linux-2.6.12-rc2 |
735 736 737 738 739 740 741 |
/* Setup 1000BT advertise & enable crossover detect * XXX How do we advertise 1000BT ? Darwin source is * confusing here, they read from specific control and * write to control... Someone has specs for those * beasts ? */ |
abc4da450 sungem: Fix globa... |
742 |
adv = sungem_phy_read(phy, MII_M1011_PHY_SPEC_CONTROL); |
1da177e4c Linux-2.6.12-rc2 |
743 744 745 746 747 748 749 |
adv |= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX; adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | MII_1000BASETCONTROL_HALFDUPLEXCAP); if (advertise & SUPPORTED_1000baseT_Half) adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; if (advertise & SUPPORTED_1000baseT_Full) adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; |
abc4da450 sungem: Fix globa... |
750 |
sungem_phy_write(phy, MII_1000BASETCONTROL, adv); |
1da177e4c Linux-2.6.12-rc2 |
751 752 |
/* Start/Restart aneg */ |
abc4da450 sungem: Fix globa... |
753 |
ctl = sungem_phy_read(phy, MII_BMCR); |
1da177e4c Linux-2.6.12-rc2 |
754 |
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); |
abc4da450 sungem: Fix globa... |
755 |
sungem_phy_write(phy, MII_BMCR, ctl); |
1da177e4c Linux-2.6.12-rc2 |
756 757 758 759 760 761 762 |
return 0; } static int marvell_setup_forced(struct mii_phy *phy, int speed, int fd) { u16 ctl, ctl2; |
6aa20a223 drivers/net: Trim... |
763 |
|
1da177e4c Linux-2.6.12-rc2 |
764 765 766 767 |
phy->autoneg = 0; phy->speed = speed; phy->duplex = fd; phy->pause = 0; |
abc4da450 sungem: Fix globa... |
768 |
ctl = sungem_phy_read(phy, MII_BMCR); |
1da177e4c Linux-2.6.12-rc2 |
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE); ctl |= BMCR_RESET; /* Select speed & duplex */ switch(speed) { case SPEED_10: break; case SPEED_100: ctl |= BMCR_SPEED100; break; /* I'm not sure about the one below, again, Darwin source is * quite confusing and I lack chip specs */ case SPEED_1000: ctl |= BMCR_SPD2; } if (fd == DUPLEX_FULL) ctl |= BMCR_FULLDPLX; /* Disable crossover. Again, the way Apple does it is strange, * though I don't assume they are wrong ;) */ |
abc4da450 sungem: Fix globa... |
791 |
ctl2 = sungem_phy_read(phy, MII_M1011_PHY_SPEC_CONTROL); |
1da177e4c Linux-2.6.12-rc2 |
792 793 794 795 796 797 798 799 |
ctl2 &= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX | MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX | MII_1000BASETCONTROL_FULLDUPLEXCAP | MII_1000BASETCONTROL_HALFDUPLEXCAP); if (speed == SPEED_1000) ctl2 |= (fd == DUPLEX_FULL) ? MII_1000BASETCONTROL_FULLDUPLEXCAP : MII_1000BASETCONTROL_HALFDUPLEXCAP; |
abc4da450 sungem: Fix globa... |
800 |
sungem_phy_write(phy, MII_1000BASETCONTROL, ctl2); |
1da177e4c Linux-2.6.12-rc2 |
801 802 |
// XXX Should we set the sungem to GII now on 1000BT ? |
6aa20a223 drivers/net: Trim... |
803 |
|
abc4da450 sungem: Fix globa... |
804 |
sungem_phy_write(phy, MII_BMCR, ctl); |
1da177e4c Linux-2.6.12-rc2 |
805 806 807 808 809 810 |
return 0; } static int marvell_read_link(struct mii_phy *phy) { |
63ea998a2 [SUNGEM]: PHY upd... |
811 |
u16 status, pmask; |
1da177e4c Linux-2.6.12-rc2 |
812 813 |
if (phy->autoneg) { |
abc4da450 sungem: Fix globa... |
814 |
status = sungem_phy_read(phy, MII_M1011_PHY_SPEC_STATUS); |
1da177e4c Linux-2.6.12-rc2 |
815 816 817 818 819 820 821 822 823 824 825 826 |
if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0) return -EAGAIN; if (status & MII_M1011_PHY_SPEC_STATUS_1000) phy->speed = SPEED_1000; else if (status & MII_M1011_PHY_SPEC_STATUS_100) phy->speed = SPEED_100; else phy->speed = SPEED_10; if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) phy->duplex = DUPLEX_FULL; else phy->duplex = DUPLEX_HALF; |
63ea998a2 [SUNGEM]: PHY upd... |
827 828 829 |
pmask = MII_M1011_PHY_SPEC_STATUS_TX_PAUSE | MII_M1011_PHY_SPEC_STATUS_RX_PAUSE; phy->pause = (status & pmask) == pmask; |
1da177e4c Linux-2.6.12-rc2 |
830 831 832 833 834 835 836 |
} /* On non-aneg, we assume what we put in BMCR is the speed, * though magic-aneg shouldn't prevent this case from occurring */ return 0; } |
63ea998a2 [SUNGEM]: PHY upd... |
837 838 839 840 841 842 843 844 845 846 847 848 849 |
#define MII_BASIC_FEATURES \ (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | \ SUPPORTED_Pause) /* On gigabit capable PHYs, we advertise Pause support but not asym pause * support for now as I'm not sure it's supported and Darwin doesn't do * it neither. --BenH. */ #define MII_GBIT_FEATURES \ (MII_BASIC_FEATURES | \ SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full) |
1da177e4c Linux-2.6.12-rc2 |
850 851 |
/* Broadcom BCM 5201 */ |
7cb6e01de drivers/net/sunge... |
852 |
static const struct mii_phy_ops bcm5201_phy_ops = { |
1da177e4c Linux-2.6.12-rc2 |
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 |
.init = bcm5201_init, .suspend = bcm5201_suspend, .setup_aneg = genmii_setup_aneg, .setup_forced = genmii_setup_forced, .poll_link = genmii_poll_link, .read_link = genmii_read_link, }; static struct mii_phy_def bcm5201_phy_def = { .phy_id = 0x00406210, .phy_id_mask = 0xfffffff0, .name = "BCM5201", .features = MII_BASIC_FEATURES, .magic_aneg = 1, .ops = &bcm5201_phy_ops }; /* Broadcom BCM 5221 */ |
7cb6e01de drivers/net/sunge... |
871 |
static const struct mii_phy_ops bcm5221_phy_ops = { |
1da177e4c Linux-2.6.12-rc2 |
872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 |
.suspend = bcm5221_suspend, .init = bcm5221_init, .setup_aneg = genmii_setup_aneg, .setup_forced = genmii_setup_forced, .poll_link = genmii_poll_link, .read_link = genmii_read_link, }; static struct mii_phy_def bcm5221_phy_def = { .phy_id = 0x004061e0, .phy_id_mask = 0xfffffff0, .name = "BCM5221", .features = MII_BASIC_FEATURES, .magic_aneg = 1, .ops = &bcm5221_phy_ops }; |
63ea998a2 [SUNGEM]: PHY upd... |
888 |
/* Broadcom BCM 5241 */ |
7cb6e01de drivers/net/sunge... |
889 |
static const struct mii_phy_ops bcm5241_phy_ops = { |
63ea998a2 [SUNGEM]: PHY upd... |
890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 |
.suspend = bcm5241_suspend, .init = bcm5241_init, .setup_aneg = genmii_setup_aneg, .setup_forced = genmii_setup_forced, .poll_link = genmii_poll_link, .read_link = genmii_read_link, }; static struct mii_phy_def bcm5241_phy_def = { .phy_id = 0x0143bc30, .phy_id_mask = 0xfffffff0, .name = "BCM5241", .features = MII_BASIC_FEATURES, .magic_aneg = 1, .ops = &bcm5241_phy_ops }; |
1da177e4c Linux-2.6.12-rc2 |
905 |
/* Broadcom BCM 5400 */ |
7cb6e01de drivers/net/sunge... |
906 |
static const struct mii_phy_ops bcm5400_phy_ops = { |
1da177e4c Linux-2.6.12-rc2 |
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 |
.init = bcm5400_init, .suspend = bcm5400_suspend, .setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5400_phy_def = { .phy_id = 0x00206040, .phy_id_mask = 0xfffffff0, .name = "BCM5400", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &bcm5400_phy_ops }; /* Broadcom BCM 5401 */ |
7cb6e01de drivers/net/sunge... |
925 |
static const struct mii_phy_ops bcm5401_phy_ops = { |
1da177e4c Linux-2.6.12-rc2 |
926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 |
.init = bcm5401_init, .suspend = bcm5401_suspend, .setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5401_phy_def = { .phy_id = 0x00206050, .phy_id_mask = 0xfffffff0, .name = "BCM5401", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &bcm5401_phy_ops }; /* Broadcom BCM 5411 */ |
7cb6e01de drivers/net/sunge... |
944 |
static const struct mii_phy_ops bcm5411_phy_ops = { |
1da177e4c Linux-2.6.12-rc2 |
945 |
.init = bcm5411_init, |
d47f3640f [SUNGEM]: Marvell... |
946 |
.suspend = generic_suspend, |
1da177e4c Linux-2.6.12-rc2 |
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 |
.setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5411_phy_def = { .phy_id = 0x00206070, .phy_id_mask = 0xfffffff0, .name = "BCM5411", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &bcm5411_phy_ops }; /* Broadcom BCM 5421 */ |
7cb6e01de drivers/net/sunge... |
963 |
static const struct mii_phy_ops bcm5421_phy_ops = { |
1da177e4c Linux-2.6.12-rc2 |
964 |
.init = bcm5421_init, |
d47f3640f [SUNGEM]: Marvell... |
965 |
.suspend = generic_suspend, |
1da177e4c Linux-2.6.12-rc2 |
966 967 |
.setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, |
eb5b5b2ff sungem_phy: suppo... |
968 969 |
.poll_link = bcm5421_poll_link, .read_link = bcm5421_read_link, |
8ec934596 spidernet: enable... |
970 |
.enable_fiber = bcm5421_enable_fiber, |
1da177e4c Linux-2.6.12-rc2 |
971 972 973 974 975 976 977 978 979 980 981 982 |
}; static struct mii_phy_def bcm5421_phy_def = { .phy_id = 0x002060e0, .phy_id_mask = 0xfffffff0, .name = "BCM5421", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &bcm5421_phy_ops }; /* Broadcom BCM 5421 built-in K2 */ |
7cb6e01de drivers/net/sunge... |
983 |
static const struct mii_phy_ops bcm5421k2_phy_ops = { |
3c326fe9c [PATCH] ppc64: Ad... |
984 |
.init = bcm5421_init, |
d47f3640f [SUNGEM]: Marvell... |
985 |
.suspend = generic_suspend, |
1da177e4c Linux-2.6.12-rc2 |
986 987 988 989 990 991 992 993 994 995 996 997 998 999 |
.setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5421k2_phy_def = { .phy_id = 0x002062e0, .phy_id_mask = 0xfffffff0, .name = "BCM5421-K2", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &bcm5421k2_phy_ops }; |
7cb6e01de drivers/net/sunge... |
1000 |
static const struct mii_phy_ops bcm5461_phy_ops = { |
8ec934596 spidernet: enable... |
1001 1002 1003 1004 |
.init = bcm5421_init, .suspend = generic_suspend, .setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, |
eb5b5b2ff sungem_phy: suppo... |
1005 1006 |
.poll_link = bcm5461_poll_link, .read_link = bcm5461_read_link, |
8ec934596 spidernet: enable... |
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 |
.enable_fiber = bcm5461_enable_fiber, }; static struct mii_phy_def bcm5461_phy_def = { .phy_id = 0x002060c0, .phy_id_mask = 0xfffffff0, .name = "BCM5461", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &bcm5461_phy_ops }; |
3c326fe9c [PATCH] ppc64: Ad... |
1018 |
/* Broadcom BCM 5462 built-in Vesta */ |
7cb6e01de drivers/net/sunge... |
1019 |
static const struct mii_phy_ops bcm5462V_phy_ops = { |
3c326fe9c [PATCH] ppc64: Ad... |
1020 |
.init = bcm5421_init, |
d47f3640f [SUNGEM]: Marvell... |
1021 |
.suspend = generic_suspend, |
3c326fe9c [PATCH] ppc64: Ad... |
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 |
.setup_aneg = bcm54xx_setup_aneg, .setup_forced = bcm54xx_setup_forced, .poll_link = genmii_poll_link, .read_link = bcm54xx_read_link, }; static struct mii_phy_def bcm5462V_phy_def = { .phy_id = 0x002060d0, .phy_id_mask = 0xfffffff0, .name = "BCM5462-Vesta", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &bcm5462V_phy_ops }; |
63ea998a2 [SUNGEM]: PHY upd... |
1036 |
/* Marvell 88E1101 amd 88E1111 */ |
7cb6e01de drivers/net/sunge... |
1037 |
static const struct mii_phy_ops marvell88e1101_phy_ops = { |
d47f3640f [SUNGEM]: Marvell... |
1038 |
.suspend = generic_suspend, |
1da177e4c Linux-2.6.12-rc2 |
1039 1040 1041 1042 1043 |
.setup_aneg = marvell_setup_aneg, .setup_forced = marvell_setup_forced, .poll_link = genmii_poll_link, .read_link = marvell_read_link }; |
7cb6e01de drivers/net/sunge... |
1044 |
static const struct mii_phy_ops marvell88e1111_phy_ops = { |
63ea998a2 [SUNGEM]: PHY upd... |
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 |
.init = marvell88e1111_init, .suspend = generic_suspend, .setup_aneg = marvell_setup_aneg, .setup_forced = marvell_setup_forced, .poll_link = genmii_poll_link, .read_link = marvell_read_link }; /* two revs in darwin for the 88e1101 ... I could use a datasheet * to get the proper names... */ static struct mii_phy_def marvell88e1101v1_phy_def = { .phy_id = 0x01410c20, .phy_id_mask = 0xfffffff0, .name = "Marvell 88E1101v1", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &marvell88e1101_phy_ops }; static struct mii_phy_def marvell88e1101v2_phy_def = { .phy_id = 0x01410c60, .phy_id_mask = 0xfffffff0, .name = "Marvell 88E1101v2", .features = MII_GBIT_FEATURES, .magic_aneg = 1, .ops = &marvell88e1101_phy_ops }; static struct mii_phy_def marvell88e1111_phy_def = { .phy_id = 0x01410cc0, .phy_id_mask = 0xfffffff0, .name = "Marvell 88E1111", |
1da177e4c Linux-2.6.12-rc2 |
1076 1077 |
.features = MII_GBIT_FEATURES, .magic_aneg = 1, |
63ea998a2 [SUNGEM]: PHY upd... |
1078 |
.ops = &marvell88e1111_phy_ops |
1da177e4c Linux-2.6.12-rc2 |
1079 1080 1081 |
}; /* Generic implementation for most 10/100 PHYs */ |
7cb6e01de drivers/net/sunge... |
1082 |
static const struct mii_phy_ops generic_phy_ops = { |
1da177e4c Linux-2.6.12-rc2 |
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 |
.setup_aneg = genmii_setup_aneg, .setup_forced = genmii_setup_forced, .poll_link = genmii_poll_link, .read_link = genmii_read_link }; static struct mii_phy_def genmii_phy_def = { .phy_id = 0x00000000, .phy_id_mask = 0x00000000, .name = "Generic MII", .features = MII_BASIC_FEATURES, .magic_aneg = 0, .ops = &generic_phy_ops }; static struct mii_phy_def* mii_phy_table[] = { &bcm5201_phy_def, &bcm5221_phy_def, |
63ea998a2 [SUNGEM]: PHY upd... |
1101 |
&bcm5241_phy_def, |
1da177e4c Linux-2.6.12-rc2 |
1102 1103 1104 1105 1106 |
&bcm5400_phy_def, &bcm5401_phy_def, &bcm5411_phy_def, &bcm5421_phy_def, &bcm5421k2_phy_def, |
8ec934596 spidernet: enable... |
1107 |
&bcm5461_phy_def, |
3c326fe9c [PATCH] ppc64: Ad... |
1108 |
&bcm5462V_phy_def, |
63ea998a2 [SUNGEM]: PHY upd... |
1109 1110 1111 |
&marvell88e1101v1_phy_def, &marvell88e1101v2_phy_def, &marvell88e1111_phy_def, |
1da177e4c Linux-2.6.12-rc2 |
1112 1113 1114 |
&genmii_phy_def, NULL }; |
19e2f6fe9 net: Fix sungem_p... |
1115 |
int sungem_phy_probe(struct mii_phy *phy, int mii_id) |
1da177e4c Linux-2.6.12-rc2 |
1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 |
{ int rc; u32 id; struct mii_phy_def* def; int i; /* We do not reset the mii_phy structure as the driver * may re-probe the PHY regulary */ phy->mii_id = mii_id; |
6aa20a223 drivers/net: Trim... |
1126 |
|
1da177e4c Linux-2.6.12-rc2 |
1127 1128 1129 1130 |
/* Take PHY out of isloate mode and reset it. */ rc = reset_one_mii_phy(phy, mii_id); if (rc) goto fail; |
6aa20a223 drivers/net: Trim... |
1131 |
/* Read ID and find matching entry */ |
abc4da450 sungem: Fix globa... |
1132 |
id = (sungem_phy_read(phy, MII_PHYSID1) << 16 | sungem_phy_read(phy, MII_PHYSID2)); |
c6c759884 drivers/net/sunge... |
1133 1134 1135 |
printk(KERN_DEBUG KBUILD_MODNAME ": " "PHY ID: %x, addr: %x ", id, mii_id); |
1da177e4c Linux-2.6.12-rc2 |
1136 1137 1138 1139 1140 1141 1142 1143 |
for (i=0; (def = mii_phy_table[i]) != NULL; i++) if ((id & def->phy_id_mask) == def->phy_id) break; /* Should never be NULL (we have a generic entry), but... */ if (def == NULL) goto fail; phy->def = def; |
6aa20a223 drivers/net: Trim... |
1144 |
|
1da177e4c Linux-2.6.12-rc2 |
1145 1146 1147 1148 1149 1150 1151 1152 |
return 0; fail: phy->speed = 0; phy->duplex = 0; phy->pause = 0; phy->advertising = 0; return -ENODEV; } |
19e2f6fe9 net: Fix sungem_p... |
1153 |
EXPORT_SYMBOL(sungem_phy_probe); |
1da177e4c Linux-2.6.12-rc2 |
1154 |
MODULE_LICENSE("GPL"); |