diff options
author | Herbert Valerio Riedel <hvr@gnu.org> | 2006-06-01 03:41:04 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-06-11 23:19:00 -0400 |
commit | 0638dec01e89059c853515ab71c55fd13ba5a8ea (patch) | |
tree | 7743a5714b03ef408b3147475cfe61127d580ed3 /drivers/net/au1000_eth.c | |
parent | 96e672c79fb114ec38a868dc864e743205c24332 (diff) |
[PATCH] net: au1000_eth: PHY framework conversion
convert au1000_eth driver to use PHY framework and garbage collected
functions and identifiers that became unused/obsolete in the process
Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/au1000_eth.c')
-rw-r--r-- | drivers/net/au1000_eth.c | 1602 |
1 files changed, 368 insertions, 1234 deletions
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index e1fe960d71b3..038d5fcb15e6 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -9,6 +9,9 @@ | |||
9 | * Update: 2004 Bjoern Riemer, riemer@fokus.fraunhofer.de | 9 | * Update: 2004 Bjoern Riemer, riemer@fokus.fraunhofer.de |
10 | * or riemer@riemer-nt.de: fixed the link beat detection with | 10 | * or riemer@riemer-nt.de: fixed the link beat detection with |
11 | * ioctls (SIOCGMIIPHY) | 11 | * ioctls (SIOCGMIIPHY) |
12 | * Copyright 2006 Herbert Valerio Riedel <hvr@gnu.org> | ||
13 | * converted to use linux-2.6.x's PHY framework | ||
14 | * | ||
12 | * Author: MontaVista Software, Inc. | 15 | * Author: MontaVista Software, Inc. |
13 | * ppopov@mvista.com or source@mvista.com | 16 | * ppopov@mvista.com or source@mvista.com |
14 | * | 17 | * |
@@ -53,6 +56,7 @@ | |||
53 | #include <linux/skbuff.h> | 56 | #include <linux/skbuff.h> |
54 | #include <linux/delay.h> | 57 | #include <linux/delay.h> |
55 | #include <linux/crc32.h> | 58 | #include <linux/crc32.h> |
59 | #include <linux/phy.h> | ||
56 | #include <asm/mipsregs.h> | 60 | #include <asm/mipsregs.h> |
57 | #include <asm/irq.h> | 61 | #include <asm/irq.h> |
58 | #include <asm/io.h> | 62 | #include <asm/io.h> |
@@ -88,17 +92,15 @@ static int au1000_tx(struct sk_buff *, struct net_device *); | |||
88 | static int au1000_rx(struct net_device *); | 92 | static int au1000_rx(struct net_device *); |
89 | static irqreturn_t au1000_interrupt(int, void *, struct pt_regs *); | 93 | static irqreturn_t au1000_interrupt(int, void *, struct pt_regs *); |
90 | static void au1000_tx_timeout(struct net_device *); | 94 | static void au1000_tx_timeout(struct net_device *); |
91 | static int au1000_set_config(struct net_device *dev, struct ifmap *map); | ||
92 | static void set_rx_mode(struct net_device *); | 95 | static void set_rx_mode(struct net_device *); |
93 | static struct net_device_stats *au1000_get_stats(struct net_device *); | 96 | static struct net_device_stats *au1000_get_stats(struct net_device *); |
94 | static void au1000_timer(unsigned long); | ||
95 | static int au1000_ioctl(struct net_device *, struct ifreq *, int); | 97 | static int au1000_ioctl(struct net_device *, struct ifreq *, int); |
96 | static int mdio_read(struct net_device *, int, int); | 98 | static int mdio_read(struct net_device *, int, int); |
97 | static void mdio_write(struct net_device *, int, int, u16); | 99 | static void mdio_write(struct net_device *, int, int, u16); |
98 | static void dump_mii(struct net_device *dev, int phy_id); | 100 | static void au1000_adjust_link(struct net_device *); |
101 | static void enable_mac(struct net_device *, int); | ||
99 | 102 | ||
100 | // externs | 103 | // externs |
101 | extern void ack_rise_edge_irq(unsigned int); | ||
102 | extern int get_ethernet_addr(char *ethernet_addr); | 104 | extern int get_ethernet_addr(char *ethernet_addr); |
103 | extern void str2eaddr(unsigned char *ea, unsigned char *str); | 105 | extern void str2eaddr(unsigned char *ea, unsigned char *str); |
104 | extern char * __init prom_getcmdline(void); | 106 | extern char * __init prom_getcmdline(void); |
@@ -126,705 +128,83 @@ static unsigned char au1000_mac_addr[6] __devinitdata = { | |||
126 | 0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00 | 128 | 0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00 |
127 | }; | 129 | }; |
128 | 130 | ||
129 | #define nibswap(x) ((((x) >> 4) & 0x0f) | (((x) << 4) & 0xf0)) | ||
130 | #define RUN_AT(x) (jiffies + (x)) | ||
131 | |||
132 | // For reading/writing 32-bit words from/to DMA memory | ||
133 | #define cpu_to_dma32 cpu_to_be32 | ||
134 | #define dma32_to_cpu be32_to_cpu | ||
135 | |||
136 | struct au1000_private *au_macs[NUM_ETH_INTERFACES]; | 131 | struct au1000_private *au_macs[NUM_ETH_INTERFACES]; |
137 | 132 | ||
138 | /* FIXME | 133 | /* |
139 | * All of the PHY code really should be detached from the MAC | 134 | * board-specific configurations |
140 | * code. | 135 | * |
136 | * PHY detection algorithm | ||
137 | * | ||
138 | * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is | ||
139 | * autodetected: | ||
140 | * | ||
141 | * mii_probe() first searches the current MAC's MII bus for a PHY, | ||
142 | * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is | ||
143 | * defined) PHY address not already claimed by another netdev. | ||
144 | * | ||
145 | * If nothing was found that way when searching for the 2nd ethernet | ||
146 | * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then | ||
147 | * the first MII bus is searched as well for an unclaimed PHY; this is | ||
148 | * needed in case of a dual-PHY accessible only through the MAC0's MII | ||
149 | * bus. | ||
150 | * | ||
151 | * Finally, if no PHY is found, then the corresponding ethernet | ||
152 | * controller is not registered to the network subsystem. | ||
141 | */ | 153 | */ |
142 | 154 | ||
143 | /* Default advertise */ | 155 | /* autodetection defaults */ |
144 | #define GENMII_DEFAULT_ADVERTISE \ | 156 | #undef AU1XXX_PHY_SEARCH_HIGHEST_ADDR |
145 | ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ | 157 | #define AU1XXX_PHY1_SEARCH_ON_MAC0 |
146 | ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ | ||
147 | ADVERTISED_Autoneg | ||
148 | |||
149 | #define GENMII_DEFAULT_FEATURES \ | ||
150 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ | ||
151 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ | ||
152 | SUPPORTED_Autoneg | ||
153 | |||
154 | int bcm_5201_init(struct net_device *dev, int phy_addr) | ||
155 | { | ||
156 | s16 data; | ||
157 | |||
158 | /* Stop auto-negotiation */ | ||
159 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
160 | mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); | ||
161 | |||
162 | /* Set advertisement to 10/100 and Half/Full duplex | ||
163 | * (full capabilities) */ | ||
164 | data = mdio_read(dev, phy_addr, MII_ANADV); | ||
165 | data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; | ||
166 | mdio_write(dev, phy_addr, MII_ANADV, data); | ||
167 | |||
168 | /* Restart auto-negotiation */ | ||
169 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
170 | data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; | ||
171 | mdio_write(dev, phy_addr, MII_CONTROL, data); | ||
172 | |||
173 | if (au1000_debug > 4) | ||
174 | dump_mii(dev, phy_addr); | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | int bcm_5201_reset(struct net_device *dev, int phy_addr) | ||
179 | { | ||
180 | s16 mii_control, timeout; | ||
181 | |||
182 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
183 | mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); | ||
184 | mdelay(1); | ||
185 | for (timeout = 100; timeout > 0; --timeout) { | ||
186 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
187 | if ((mii_control & MII_CNTL_RESET) == 0) | ||
188 | break; | ||
189 | mdelay(1); | ||
190 | } | ||
191 | if (mii_control & MII_CNTL_RESET) { | ||
192 | printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); | ||
193 | return -1; | ||
194 | } | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | int | ||
199 | bcm_5201_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
200 | { | ||
201 | u16 mii_data; | ||
202 | struct au1000_private *aup; | ||
203 | |||
204 | if (!dev) { | ||
205 | printk(KERN_ERR "bcm_5201_status error: NULL dev\n"); | ||
206 | return -1; | ||
207 | } | ||
208 | aup = (struct au1000_private *) dev->priv; | ||
209 | |||
210 | mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); | ||
211 | if (mii_data & MII_STAT_LINK) { | ||
212 | *link = 1; | ||
213 | mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL); | ||
214 | if (mii_data & MII_AUX_100) { | ||
215 | if (mii_data & MII_AUX_FDX) { | ||
216 | *speed = IF_PORT_100BASEFX; | ||
217 | dev->if_port = IF_PORT_100BASEFX; | ||
218 | } | ||
219 | else { | ||
220 | *speed = IF_PORT_100BASETX; | ||
221 | dev->if_port = IF_PORT_100BASETX; | ||
222 | } | ||
223 | } | ||
224 | else { | ||
225 | *speed = IF_PORT_10BASET; | ||
226 | dev->if_port = IF_PORT_10BASET; | ||
227 | } | ||
228 | |||
229 | } | ||
230 | else { | ||
231 | *link = 0; | ||
232 | *speed = 0; | ||
233 | dev->if_port = IF_PORT_UNKNOWN; | ||
234 | } | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | int lsi_80227_init(struct net_device *dev, int phy_addr) | ||
239 | { | ||
240 | if (au1000_debug > 4) | ||
241 | printk("lsi_80227_init\n"); | ||
242 | |||
243 | /* restart auto-negotiation */ | ||
244 | mdio_write(dev, phy_addr, MII_CONTROL, | ||
245 | MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO); // | MII_CNTL_FDX); | ||
246 | mdelay(1); | ||
247 | |||
248 | /* set up LEDs to correct display */ | ||
249 | #ifdef CONFIG_MIPS_MTX1 | ||
250 | mdio_write(dev, phy_addr, 17, 0xff80); | ||
251 | #else | ||
252 | mdio_write(dev, phy_addr, 17, 0xffc0); | ||
253 | #endif | ||
254 | |||
255 | if (au1000_debug > 4) | ||
256 | dump_mii(dev, phy_addr); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | int lsi_80227_reset(struct net_device *dev, int phy_addr) | ||
261 | { | ||
262 | s16 mii_control, timeout; | ||
263 | |||
264 | if (au1000_debug > 4) { | ||
265 | printk("lsi_80227_reset\n"); | ||
266 | dump_mii(dev, phy_addr); | ||
267 | } | ||
268 | |||
269 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
270 | mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); | ||
271 | mdelay(1); | ||
272 | for (timeout = 100; timeout > 0; --timeout) { | ||
273 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
274 | if ((mii_control & MII_CNTL_RESET) == 0) | ||
275 | break; | ||
276 | mdelay(1); | ||
277 | } | ||
278 | if (mii_control & MII_CNTL_RESET) { | ||
279 | printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); | ||
280 | return -1; | ||
281 | } | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | int | ||
286 | lsi_80227_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
287 | { | ||
288 | u16 mii_data; | ||
289 | struct au1000_private *aup; | ||
290 | |||
291 | if (!dev) { | ||
292 | printk(KERN_ERR "lsi_80227_status error: NULL dev\n"); | ||
293 | return -1; | ||
294 | } | ||
295 | aup = (struct au1000_private *) dev->priv; | ||
296 | |||
297 | mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); | ||
298 | if (mii_data & MII_STAT_LINK) { | ||
299 | *link = 1; | ||
300 | mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_PHY_STAT); | ||
301 | if (mii_data & MII_LSI_PHY_STAT_SPD) { | ||
302 | if (mii_data & MII_LSI_PHY_STAT_FDX) { | ||
303 | *speed = IF_PORT_100BASEFX; | ||
304 | dev->if_port = IF_PORT_100BASEFX; | ||
305 | } | ||
306 | else { | ||
307 | *speed = IF_PORT_100BASETX; | ||
308 | dev->if_port = IF_PORT_100BASETX; | ||
309 | } | ||
310 | } | ||
311 | else { | ||
312 | *speed = IF_PORT_10BASET; | ||
313 | dev->if_port = IF_PORT_10BASET; | ||
314 | } | ||
315 | |||
316 | } | ||
317 | else { | ||
318 | *link = 0; | ||
319 | *speed = 0; | ||
320 | dev->if_port = IF_PORT_UNKNOWN; | ||
321 | } | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | int am79c901_init(struct net_device *dev, int phy_addr) | ||
326 | { | ||
327 | printk("am79c901_init\n"); | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | int am79c901_reset(struct net_device *dev, int phy_addr) | ||
332 | { | ||
333 | printk("am79c901_reset\n"); | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | int | ||
338 | am79c901_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
339 | { | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | int am79c874_init(struct net_device *dev, int phy_addr) | ||
344 | { | ||
345 | s16 data; | ||
346 | |||
347 | /* 79c874 has quit resembled bit assignments to BCM5201 */ | ||
348 | if (au1000_debug > 4) | ||
349 | printk("am79c847_init\n"); | ||
350 | |||
351 | /* Stop auto-negotiation */ | ||
352 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
353 | mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); | ||
354 | |||
355 | /* Set advertisement to 10/100 and Half/Full duplex | ||
356 | * (full capabilities) */ | ||
357 | data = mdio_read(dev, phy_addr, MII_ANADV); | ||
358 | data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; | ||
359 | mdio_write(dev, phy_addr, MII_ANADV, data); | ||
360 | |||
361 | /* Restart auto-negotiation */ | ||
362 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
363 | data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; | ||
364 | |||
365 | mdio_write(dev, phy_addr, MII_CONTROL, data); | ||
366 | |||
367 | if (au1000_debug > 4) dump_mii(dev, phy_addr); | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | int am79c874_reset(struct net_device *dev, int phy_addr) | ||
372 | { | ||
373 | s16 mii_control, timeout; | ||
374 | |||
375 | if (au1000_debug > 4) | ||
376 | printk("am79c874_reset\n"); | ||
377 | |||
378 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
379 | mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); | ||
380 | mdelay(1); | ||
381 | for (timeout = 100; timeout > 0; --timeout) { | ||
382 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
383 | if ((mii_control & MII_CNTL_RESET) == 0) | ||
384 | break; | ||
385 | mdelay(1); | ||
386 | } | ||
387 | if (mii_control & MII_CNTL_RESET) { | ||
388 | printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); | ||
389 | return -1; | ||
390 | } | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | int | ||
395 | am79c874_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
396 | { | ||
397 | u16 mii_data; | ||
398 | struct au1000_private *aup; | ||
399 | |||
400 | // printk("am79c874_status\n"); | ||
401 | if (!dev) { | ||
402 | printk(KERN_ERR "am79c874_status error: NULL dev\n"); | ||
403 | return -1; | ||
404 | } | ||
405 | |||
406 | aup = (struct au1000_private *) dev->priv; | ||
407 | mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); | ||
408 | 158 | ||
409 | if (mii_data & MII_STAT_LINK) { | 159 | /* static PHY setup |
410 | *link = 1; | 160 | * |
411 | mii_data = mdio_read(dev, aup->phy_addr, MII_AMD_PHY_STAT); | 161 | * most boards PHY setup should be detectable properly with the |
412 | if (mii_data & MII_AMD_PHY_STAT_SPD) { | 162 | * autodetection algorithm in mii_probe(), but in some cases (e.g. if |
413 | if (mii_data & MII_AMD_PHY_STAT_FDX) { | 163 | * you have a switch attached, or want to use the PHY's interrupt |
414 | *speed = IF_PORT_100BASEFX; | 164 | * notification capabilities) you can provide a static PHY |
415 | dev->if_port = IF_PORT_100BASEFX; | 165 | * configuration here |
416 | } | 166 | * |
417 | else { | 167 | * IRQs may only be set, if a PHY address was configured |
418 | *speed = IF_PORT_100BASETX; | 168 | * If a PHY address is given, also a bus id is required to be set |
419 | dev->if_port = IF_PORT_100BASETX; | 169 | * |
420 | } | 170 | * ps: make sure the used irqs are configured properly in the board |
421 | } | 171 | * specific irq-map |
422 | else { | 172 | */ |
423 | *speed = IF_PORT_10BASET; | ||
424 | dev->if_port = IF_PORT_10BASET; | ||
425 | } | ||
426 | |||
427 | } | ||
428 | else { | ||
429 | *link = 0; | ||
430 | *speed = 0; | ||
431 | dev->if_port = IF_PORT_UNKNOWN; | ||
432 | } | ||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | int lxt971a_init(struct net_device *dev, int phy_addr) | ||
437 | { | ||
438 | if (au1000_debug > 4) | ||
439 | printk("lxt971a_init\n"); | ||
440 | |||
441 | /* restart auto-negotiation */ | ||
442 | mdio_write(dev, phy_addr, MII_CONTROL, | ||
443 | MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO | MII_CNTL_FDX); | ||
444 | |||
445 | /* set up LEDs to correct display */ | ||
446 | mdio_write(dev, phy_addr, 20, 0x0422); | ||
447 | |||
448 | if (au1000_debug > 4) | ||
449 | dump_mii(dev, phy_addr); | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | int lxt971a_reset(struct net_device *dev, int phy_addr) | ||
454 | { | ||
455 | s16 mii_control, timeout; | ||
456 | |||
457 | if (au1000_debug > 4) { | ||
458 | printk("lxt971a_reset\n"); | ||
459 | dump_mii(dev, phy_addr); | ||
460 | } | ||
461 | |||
462 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
463 | mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); | ||
464 | mdelay(1); | ||
465 | for (timeout = 100; timeout > 0; --timeout) { | ||
466 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
467 | if ((mii_control & MII_CNTL_RESET) == 0) | ||
468 | break; | ||
469 | mdelay(1); | ||
470 | } | ||
471 | if (mii_control & MII_CNTL_RESET) { | ||
472 | printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); | ||
473 | return -1; | ||
474 | } | ||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | int | ||
479 | lxt971a_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
480 | { | ||
481 | u16 mii_data; | ||
482 | struct au1000_private *aup; | ||
483 | |||
484 | if (!dev) { | ||
485 | printk(KERN_ERR "lxt971a_status error: NULL dev\n"); | ||
486 | return -1; | ||
487 | } | ||
488 | aup = (struct au1000_private *) dev->priv; | ||
489 | |||
490 | mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); | ||
491 | if (mii_data & MII_STAT_LINK) { | ||
492 | *link = 1; | ||
493 | mii_data = mdio_read(dev, aup->phy_addr, MII_INTEL_PHY_STAT); | ||
494 | if (mii_data & MII_INTEL_PHY_STAT_SPD) { | ||
495 | if (mii_data & MII_INTEL_PHY_STAT_FDX) { | ||
496 | *speed = IF_PORT_100BASEFX; | ||
497 | dev->if_port = IF_PORT_100BASEFX; | ||
498 | } | ||
499 | else { | ||
500 | *speed = IF_PORT_100BASETX; | ||
501 | dev->if_port = IF_PORT_100BASETX; | ||
502 | } | ||
503 | } | ||
504 | else { | ||
505 | *speed = IF_PORT_10BASET; | ||
506 | dev->if_port = IF_PORT_10BASET; | ||
507 | } | ||
508 | |||
509 | } | ||
510 | else { | ||
511 | *link = 0; | ||
512 | *speed = 0; | ||
513 | dev->if_port = IF_PORT_UNKNOWN; | ||
514 | } | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | int ks8995m_init(struct net_device *dev, int phy_addr) | ||
519 | { | ||
520 | s16 data; | ||
521 | |||
522 | // printk("ks8995m_init\n"); | ||
523 | /* Stop auto-negotiation */ | ||
524 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
525 | mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); | ||
526 | |||
527 | /* Set advertisement to 10/100 and Half/Full duplex | ||
528 | * (full capabilities) */ | ||
529 | data = mdio_read(dev, phy_addr, MII_ANADV); | ||
530 | data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; | ||
531 | mdio_write(dev, phy_addr, MII_ANADV, data); | ||
532 | |||
533 | /* Restart auto-negotiation */ | ||
534 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
535 | data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; | ||
536 | mdio_write(dev, phy_addr, MII_CONTROL, data); | ||
537 | |||
538 | if (au1000_debug > 4) dump_mii(dev, phy_addr); | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | int ks8995m_reset(struct net_device *dev, int phy_addr) | ||
544 | { | ||
545 | s16 mii_control, timeout; | ||
546 | |||
547 | // printk("ks8995m_reset\n"); | ||
548 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
549 | mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); | ||
550 | mdelay(1); | ||
551 | for (timeout = 100; timeout > 0; --timeout) { | ||
552 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
553 | if ((mii_control & MII_CNTL_RESET) == 0) | ||
554 | break; | ||
555 | mdelay(1); | ||
556 | } | ||
557 | if (mii_control & MII_CNTL_RESET) { | ||
558 | printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); | ||
559 | return -1; | ||
560 | } | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | int ks8995m_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
565 | { | ||
566 | u16 mii_data; | ||
567 | struct au1000_private *aup; | ||
568 | |||
569 | if (!dev) { | ||
570 | printk(KERN_ERR "ks8995m_status error: NULL dev\n"); | ||
571 | return -1; | ||
572 | } | ||
573 | aup = (struct au1000_private *) dev->priv; | ||
574 | |||
575 | mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); | ||
576 | if (mii_data & MII_STAT_LINK) { | ||
577 | *link = 1; | ||
578 | mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL); | ||
579 | if (mii_data & MII_AUX_100) { | ||
580 | if (mii_data & MII_AUX_FDX) { | ||
581 | *speed = IF_PORT_100BASEFX; | ||
582 | dev->if_port = IF_PORT_100BASEFX; | ||
583 | } | ||
584 | else { | ||
585 | *speed = IF_PORT_100BASETX; | ||
586 | dev->if_port = IF_PORT_100BASETX; | ||
587 | } | ||
588 | } | ||
589 | else { | ||
590 | *speed = IF_PORT_10BASET; | ||
591 | dev->if_port = IF_PORT_10BASET; | ||
592 | } | ||
593 | |||
594 | } | ||
595 | else { | ||
596 | *link = 0; | ||
597 | *speed = 0; | ||
598 | dev->if_port = IF_PORT_UNKNOWN; | ||
599 | } | ||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | int | ||
604 | smsc_83C185_init (struct net_device *dev, int phy_addr) | ||
605 | { | ||
606 | s16 data; | ||
607 | |||
608 | if (au1000_debug > 4) | ||
609 | printk("smsc_83C185_init\n"); | ||
610 | |||
611 | /* Stop auto-negotiation */ | ||
612 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
613 | mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO); | ||
614 | |||
615 | /* Set advertisement to 10/100 and Half/Full duplex | ||
616 | * (full capabilities) */ | ||
617 | data = mdio_read(dev, phy_addr, MII_ANADV); | ||
618 | data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T; | ||
619 | mdio_write(dev, phy_addr, MII_ANADV, data); | ||
620 | |||
621 | /* Restart auto-negotiation */ | ||
622 | data = mdio_read(dev, phy_addr, MII_CONTROL); | ||
623 | data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO; | ||
624 | |||
625 | mdio_write(dev, phy_addr, MII_CONTROL, data); | ||
626 | |||
627 | if (au1000_debug > 4) dump_mii(dev, phy_addr); | ||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | int | ||
632 | smsc_83C185_reset (struct net_device *dev, int phy_addr) | ||
633 | { | ||
634 | s16 mii_control, timeout; | ||
635 | |||
636 | if (au1000_debug > 4) | ||
637 | printk("smsc_83C185_reset\n"); | ||
638 | |||
639 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
640 | mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET); | ||
641 | mdelay(1); | ||
642 | for (timeout = 100; timeout > 0; --timeout) { | ||
643 | mii_control = mdio_read(dev, phy_addr, MII_CONTROL); | ||
644 | if ((mii_control & MII_CNTL_RESET) == 0) | ||
645 | break; | ||
646 | mdelay(1); | ||
647 | } | ||
648 | if (mii_control & MII_CNTL_RESET) { | ||
649 | printk(KERN_ERR "%s PHY reset timeout !\n", dev->name); | ||
650 | return -1; | ||
651 | } | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | int | ||
656 | smsc_83C185_status (struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
657 | { | ||
658 | u16 mii_data; | ||
659 | struct au1000_private *aup; | ||
660 | |||
661 | if (!dev) { | ||
662 | printk(KERN_ERR "smsc_83C185_status error: NULL dev\n"); | ||
663 | return -1; | ||
664 | } | ||
665 | |||
666 | aup = (struct au1000_private *) dev->priv; | ||
667 | mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS); | ||
668 | |||
669 | if (mii_data & MII_STAT_LINK) { | ||
670 | *link = 1; | ||
671 | mii_data = mdio_read(dev, aup->phy_addr, 0x1f); | ||
672 | if (mii_data & (1<<3)) { | ||
673 | if (mii_data & (1<<4)) { | ||
674 | *speed = IF_PORT_100BASEFX; | ||
675 | dev->if_port = IF_PORT_100BASEFX; | ||
676 | } | ||
677 | else { | ||
678 | *speed = IF_PORT_100BASETX; | ||
679 | dev->if_port = IF_PORT_100BASETX; | ||
680 | } | ||
681 | } | ||
682 | else { | ||
683 | *speed = IF_PORT_10BASET; | ||
684 | dev->if_port = IF_PORT_10BASET; | ||
685 | } | ||
686 | } | ||
687 | else { | ||
688 | *link = 0; | ||
689 | *speed = 0; | ||
690 | dev->if_port = IF_PORT_UNKNOWN; | ||
691 | } | ||
692 | return 0; | ||
693 | } | ||
694 | |||
695 | |||
696 | #ifdef CONFIG_MIPS_BOSPORUS | ||
697 | int stub_init(struct net_device *dev, int phy_addr) | ||
698 | { | ||
699 | //printk("PHY stub_init\n"); | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | int stub_reset(struct net_device *dev, int phy_addr) | ||
704 | { | ||
705 | //printk("PHY stub_reset\n"); | ||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | int | ||
710 | stub_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed) | ||
711 | { | ||
712 | //printk("PHY stub_status\n"); | ||
713 | *link = 1; | ||
714 | /* hmmm, revisit */ | ||
715 | *speed = IF_PORT_100BASEFX; | ||
716 | dev->if_port = IF_PORT_100BASEFX; | ||
717 | return 0; | ||
718 | } | ||
719 | #endif | ||
720 | |||
721 | struct phy_ops bcm_5201_ops = { | ||
722 | bcm_5201_init, | ||
723 | bcm_5201_reset, | ||
724 | bcm_5201_status, | ||
725 | }; | ||
726 | |||
727 | struct phy_ops am79c874_ops = { | ||
728 | am79c874_init, | ||
729 | am79c874_reset, | ||
730 | am79c874_status, | ||
731 | }; | ||
732 | |||
733 | struct phy_ops am79c901_ops = { | ||
734 | am79c901_init, | ||
735 | am79c901_reset, | ||
736 | am79c901_status, | ||
737 | }; | ||
738 | |||
739 | struct phy_ops lsi_80227_ops = { | ||
740 | lsi_80227_init, | ||
741 | lsi_80227_reset, | ||
742 | lsi_80227_status, | ||
743 | }; | ||
744 | |||
745 | struct phy_ops lxt971a_ops = { | ||
746 | lxt971a_init, | ||
747 | lxt971a_reset, | ||
748 | lxt971a_status, | ||
749 | }; | ||
750 | 173 | ||
751 | struct phy_ops ks8995m_ops = { | 174 | #if defined(CONFIG_MIPS_BOSPORUS) |
752 | ks8995m_init, | 175 | /* |
753 | ks8995m_reset, | 176 | * Micrel/Kendin 5 port switch attached to MAC0, |
754 | ks8995m_status, | 177 | * MAC0 is associated with PHY address 5 (== WAN port) |
755 | }; | 178 | * MAC1 is not associated with any PHY, since it's connected directly |
179 | * to the switch. | ||
180 | * no interrupts are used | ||
181 | */ | ||
182 | # define AU1XXX_PHY_STATIC_CONFIG | ||
756 | 183 | ||
757 | struct phy_ops smsc_83C185_ops = { | 184 | # define AU1XXX_PHY0_ADDR 5 |
758 | smsc_83C185_init, | 185 | # define AU1XXX_PHY0_BUSID 0 |
759 | smsc_83C185_reset, | 186 | # undef AU1XXX_PHY0_IRQ |
760 | smsc_83C185_status, | ||
761 | }; | ||
762 | 187 | ||
763 | #ifdef CONFIG_MIPS_BOSPORUS | 188 | # undef AU1XXX_PHY1_ADDR |
764 | struct phy_ops stub_ops = { | 189 | # undef AU1XXX_PHY1_BUSID |
765 | stub_init, | 190 | # undef AU1XXX_PHY1_IRQ |
766 | stub_reset, | ||
767 | stub_status, | ||
768 | }; | ||
769 | #endif | 191 | #endif |
770 | 192 | ||
771 | static struct mii_chip_info { | 193 | #if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0) |
772 | const char * name; | 194 | # error MAC0-associated PHY attached 2nd MACs MII bus not supported yet |
773 | u16 phy_id0; | ||
774 | u16 phy_id1; | ||
775 | struct phy_ops *phy_ops; | ||
776 | int dual_phy; | ||
777 | } mii_chip_table[] = { | ||
778 | {"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0}, | ||
779 | {"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0}, | ||
780 | {"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1}, | ||
781 | {"NS DP83847 PHY", 0x2000, 0x5c30, &bcm_5201_ops ,0}, | ||
782 | {"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0}, | ||
783 | {"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0}, | ||
784 | {"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0}, | ||
785 | {"Intel LXT971A Dual Speed PHY",0x0013,0x78e2, &lxt971a_ops,0}, | ||
786 | {"Kendin KS8995M 10/100 BaseT PHY",0x0022,0x1450, &ks8995m_ops,0}, | ||
787 | {"SMSC LAN83C185 10/100 BaseT PHY",0x0007,0xc0a3, &smsc_83C185_ops,0}, | ||
788 | #ifdef CONFIG_MIPS_BOSPORUS | ||
789 | {"Stub", 0x1234, 0x5678, &stub_ops }, | ||
790 | #endif | 195 | #endif |
791 | {0,}, | ||
792 | }; | ||
793 | 196 | ||
794 | static int mdio_read(struct net_device *dev, int phy_id, int reg) | 197 | /* |
198 | * MII operations | ||
199 | */ | ||
200 | static int mdio_read(struct net_device *dev, int phy_addr, int reg) | ||
795 | { | 201 | { |
796 | struct au1000_private *aup = (struct au1000_private *) dev->priv; | 202 | struct au1000_private *aup = (struct au1000_private *) dev->priv; |
797 | volatile u32 *mii_control_reg; | 203 | volatile u32 *const mii_control_reg = &aup->mac->mii_control; |
798 | volatile u32 *mii_data_reg; | 204 | volatile u32 *const mii_data_reg = &aup->mac->mii_data; |
799 | u32 timedout = 20; | 205 | u32 timedout = 20; |
800 | u32 mii_control; | 206 | u32 mii_control; |
801 | 207 | ||
802 | #ifdef CONFIG_BCM5222_DUAL_PHY | ||
803 | /* First time we probe, it's for the mac0 phy. | ||
804 | * Since we haven't determined yet that we have a dual phy, | ||
805 | * aup->mii->mii_control_reg won't be setup and we'll | ||
806 | * default to the else statement. | ||
807 | * By the time we probe for the mac1 phy, the mii_control_reg | ||
808 | * will be setup to be the address of the mac0 phy control since | ||
809 | * both phys are controlled through mac0. | ||
810 | */ | ||
811 | if (aup->mii && aup->mii->mii_control_reg) { | ||
812 | mii_control_reg = aup->mii->mii_control_reg; | ||
813 | mii_data_reg = aup->mii->mii_data_reg; | ||
814 | } | ||
815 | else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { | ||
816 | /* assume both phys are controlled through mac0 */ | ||
817 | mii_control_reg = au_macs[0]->mii->mii_control_reg; | ||
818 | mii_data_reg = au_macs[0]->mii->mii_data_reg; | ||
819 | } | ||
820 | else | ||
821 | #endif | ||
822 | { | ||
823 | /* default control and data reg addresses */ | ||
824 | mii_control_reg = &aup->mac->mii_control; | ||
825 | mii_data_reg = &aup->mac->mii_data; | ||
826 | } | ||
827 | |||
828 | while (*mii_control_reg & MAC_MII_BUSY) { | 208 | while (*mii_control_reg & MAC_MII_BUSY) { |
829 | mdelay(1); | 209 | mdelay(1); |
830 | if (--timedout == 0) { | 210 | if (--timedout == 0) { |
@@ -835,7 +215,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg) | |||
835 | } | 215 | } |
836 | 216 | ||
837 | mii_control = MAC_SET_MII_SELECT_REG(reg) | | 217 | mii_control = MAC_SET_MII_SELECT_REG(reg) | |
838 | MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_READ; | 218 | MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ; |
839 | 219 | ||
840 | *mii_control_reg = mii_control; | 220 | *mii_control_reg = mii_control; |
841 | 221 | ||
@@ -851,32 +231,14 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg) | |||
851 | return (int)*mii_data_reg; | 231 | return (int)*mii_data_reg; |
852 | } | 232 | } |
853 | 233 | ||
854 | static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value) | 234 | static void mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value) |
855 | { | 235 | { |
856 | struct au1000_private *aup = (struct au1000_private *) dev->priv; | 236 | struct au1000_private *aup = (struct au1000_private *) dev->priv; |
857 | volatile u32 *mii_control_reg; | 237 | volatile u32 *const mii_control_reg = &aup->mac->mii_control; |
858 | volatile u32 *mii_data_reg; | 238 | volatile u32 *const mii_data_reg = &aup->mac->mii_data; |
859 | u32 timedout = 20; | 239 | u32 timedout = 20; |
860 | u32 mii_control; | 240 | u32 mii_control; |
861 | 241 | ||
862 | #ifdef CONFIG_BCM5222_DUAL_PHY | ||
863 | if (aup->mii && aup->mii->mii_control_reg) { | ||
864 | mii_control_reg = aup->mii->mii_control_reg; | ||
865 | mii_data_reg = aup->mii->mii_data_reg; | ||
866 | } | ||
867 | else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { | ||
868 | /* assume both phys are controlled through mac0 */ | ||
869 | mii_control_reg = au_macs[0]->mii->mii_control_reg; | ||
870 | mii_data_reg = au_macs[0]->mii->mii_data_reg; | ||
871 | } | ||
872 | else | ||
873 | #endif | ||
874 | { | ||
875 | /* default control and data reg addresses */ | ||
876 | mii_control_reg = &aup->mac->mii_control; | ||
877 | mii_data_reg = &aup->mac->mii_data; | ||
878 | } | ||
879 | |||
880 | while (*mii_control_reg & MAC_MII_BUSY) { | 242 | while (*mii_control_reg & MAC_MII_BUSY) { |
881 | mdelay(1); | 243 | mdelay(1); |
882 | if (--timedout == 0) { | 244 | if (--timedout == 0) { |
@@ -887,165 +249,145 @@ static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value) | |||
887 | } | 249 | } |
888 | 250 | ||
889 | mii_control = MAC_SET_MII_SELECT_REG(reg) | | 251 | mii_control = MAC_SET_MII_SELECT_REG(reg) | |
890 | MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_WRITE; | 252 | MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE; |
891 | 253 | ||
892 | *mii_data_reg = value; | 254 | *mii_data_reg = value; |
893 | *mii_control_reg = mii_control; | 255 | *mii_control_reg = mii_control; |
894 | } | 256 | } |
895 | 257 | ||
258 | static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) | ||
259 | { | ||
260 | /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does | ||
261 | * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */ | ||
262 | struct net_device *const dev = bus->priv; | ||
263 | |||
264 | enable_mac(dev, 0); /* make sure the MAC associated with this | ||
265 | * mii_bus is enabled */ | ||
266 | return mdio_read(dev, phy_addr, regnum); | ||
267 | } | ||
896 | 268 | ||
897 | static void dump_mii(struct net_device *dev, int phy_id) | 269 | static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, |
270 | u16 value) | ||
898 | { | 271 | { |
899 | int i, val; | 272 | struct net_device *const dev = bus->priv; |
900 | 273 | ||
901 | for (i = 0; i < 7; i++) { | 274 | enable_mac(dev, 0); /* make sure the MAC associated with this |
902 | if ((val = mdio_read(dev, phy_id, i)) >= 0) | 275 | * mii_bus is enabled */ |
903 | printk("%s: MII Reg %d=%x\n", dev->name, i, val); | 276 | mdio_write(dev, phy_addr, regnum, value); |
904 | } | 277 | return 0; |
905 | for (i = 16; i < 25; i++) { | ||
906 | if ((val = mdio_read(dev, phy_id, i)) >= 0) | ||
907 | printk("%s: MII Reg %d=%x\n", dev->name, i, val); | ||
908 | } | ||
909 | } | 278 | } |
910 | 279 | ||
911 | static int mii_probe (struct net_device * dev) | 280 | static int mdiobus_reset(struct mii_bus *bus) |
912 | { | 281 | { |
913 | struct au1000_private *aup = (struct au1000_private *) dev->priv; | 282 | struct net_device *const dev = bus->priv; |
914 | int phy_addr; | ||
915 | #ifdef CONFIG_MIPS_BOSPORUS | ||
916 | int phy_found=0; | ||
917 | #endif | ||
918 | 283 | ||
919 | /* search for total of 32 possible mii phy addresses */ | 284 | enable_mac(dev, 0); /* make sure the MAC associated with this |
920 | for (phy_addr = 0; phy_addr < 32; phy_addr++) { | 285 | * mii_bus is enabled */ |
921 | u16 mii_status; | 286 | return 0; |
922 | u16 phy_id0, phy_id1; | 287 | } |
923 | int i; | ||
924 | 288 | ||
925 | #ifdef CONFIG_BCM5222_DUAL_PHY | 289 | static int mii_probe (struct net_device *dev) |
926 | /* Mask the already found phy, try next one */ | 290 | { |
927 | if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) { | 291 | struct au1000_private *const aup = (struct au1000_private *) dev->priv; |
928 | if (au_macs[0]->phy_addr == phy_addr) | 292 | struct phy_device *phydev = NULL; |
929 | continue; | 293 | |
930 | } | 294 | #if defined(AU1XXX_PHY_STATIC_CONFIG) |
931 | #endif | 295 | BUG_ON(aup->mac_id < 0 || aup->mac_id > 1); |
932 | 296 | ||
933 | mii_status = mdio_read(dev, phy_addr, MII_STATUS); | 297 | if(aup->mac_id == 0) { /* get PHY0 */ |
934 | if (mii_status == 0xffff || mii_status == 0x0000) | 298 | # if defined(AU1XXX_PHY0_ADDR) |
935 | /* the mii is not accessable, try next one */ | 299 | phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus.phy_map[AU1XXX_PHY0_ADDR]; |
936 | continue; | 300 | # else |
937 | 301 | printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", | |
938 | phy_id0 = mdio_read(dev, phy_addr, MII_PHY_ID0); | 302 | dev->name); |
939 | phy_id1 = mdio_read(dev, phy_addr, MII_PHY_ID1); | 303 | return 0; |
940 | 304 | # endif /* defined(AU1XXX_PHY0_ADDR) */ | |
941 | /* search our mii table for the current mii */ | 305 | } else if (aup->mac_id == 1) { /* get PHY1 */ |
942 | for (i = 0; mii_chip_table[i].phy_id1; i++) { | 306 | # if defined(AU1XXX_PHY1_ADDR) |
943 | if (phy_id0 == mii_chip_table[i].phy_id0 && | 307 | phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus.phy_map[AU1XXX_PHY1_ADDR]; |
944 | phy_id1 == mii_chip_table[i].phy_id1) { | 308 | # else |
945 | struct mii_phy * mii_phy = aup->mii; | 309 | printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", |
946 | 310 | dev->name); | |
947 | printk(KERN_INFO "%s: %s at phy address %d\n", | 311 | return 0; |
948 | dev->name, mii_chip_table[i].name, | 312 | # endif /* defined(AU1XXX_PHY1_ADDR) */ |
949 | phy_addr); | 313 | } |
950 | #ifdef CONFIG_MIPS_BOSPORUS | 314 | |
951 | phy_found = 1; | 315 | #else /* defined(AU1XXX_PHY_STATIC_CONFIG) */ |
952 | #endif | 316 | int phy_addr; |
953 | mii_phy->chip_info = mii_chip_table+i; | 317 | |
954 | aup->phy_addr = phy_addr; | 318 | /* find the first (lowest address) PHY on the current MAC's MII bus */ |
955 | aup->want_autoneg = 1; | 319 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) |
956 | aup->phy_ops = mii_chip_table[i].phy_ops; | 320 | if (aup->mii_bus.phy_map[phy_addr]) { |
957 | aup->phy_ops->phy_init(dev,phy_addr); | 321 | phydev = aup->mii_bus.phy_map[phy_addr]; |
958 | 322 | # if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR) | |
959 | // Check for dual-phy and then store required | 323 | break; /* break out with first one found */ |
960 | // values and set indicators. We need to do | 324 | # endif |
961 | // this now since mdio_{read,write} need the | ||
962 | // control and data register addresses. | ||
963 | #ifdef CONFIG_BCM5222_DUAL_PHY | ||
964 | if ( mii_chip_table[i].dual_phy) { | ||
965 | |||
966 | /* assume both phys are controlled | ||
967 | * through MAC0. Board specific? */ | ||
968 | |||
969 | /* sanity check */ | ||
970 | if (!au_macs[0] || !au_macs[0]->mii) | ||
971 | return -1; | ||
972 | aup->mii->mii_control_reg = (u32 *) | ||
973 | &au_macs[0]->mac->mii_control; | ||
974 | aup->mii->mii_data_reg = (u32 *) | ||
975 | &au_macs[0]->mac->mii_data; | ||
976 | } | ||
977 | #endif | ||
978 | goto found; | ||
979 | } | ||
980 | } | 325 | } |
981 | } | ||
982 | found: | ||
983 | |||
984 | #ifdef CONFIG_MIPS_BOSPORUS | ||
985 | /* This is a workaround for the Micrel/Kendin 5 port switch | ||
986 | The second MAC doesn't see a PHY connected... so we need to | ||
987 | trick it into thinking we have one. | ||
988 | |||
989 | If this kernel is run on another Au1500 development board | ||
990 | the stub will be found as well as the actual PHY. However, | ||
991 | the last found PHY will be used... usually at Addr 31 (Db1500). | ||
992 | */ | ||
993 | if ( (!phy_found) ) | ||
994 | { | ||
995 | u16 phy_id0, phy_id1; | ||
996 | int i; | ||
997 | 326 | ||
998 | phy_id0 = 0x1234; | 327 | # if defined(AU1XXX_PHY1_SEARCH_ON_MAC0) |
999 | phy_id1 = 0x5678; | 328 | /* try harder to find a PHY */ |
1000 | 329 | if (!phydev && (aup->mac_id == 1)) { | |
1001 | /* search our mii table for the current mii */ | 330 | /* no PHY found, maybe we have a dual PHY? */ |
1002 | for (i = 0; mii_chip_table[i].phy_id1; i++) { | 331 | printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, " |
1003 | if (phy_id0 == mii_chip_table[i].phy_id0 && | 332 | "let's see if it's attached to MAC0...\n"); |
1004 | phy_id1 == mii_chip_table[i].phy_id1) { | 333 | |
1005 | struct mii_phy * mii_phy; | 334 | BUG_ON(!au_macs[0]); |
1006 | 335 | ||
1007 | printk(KERN_INFO "%s: %s at phy address %d\n", | 336 | /* find the first (lowest address) non-attached PHY on |
1008 | dev->name, mii_chip_table[i].name, | 337 | * the MAC0 MII bus */ |
1009 | phy_addr); | 338 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { |
1010 | mii_phy = kmalloc(sizeof(struct mii_phy), | 339 | struct phy_device *const tmp_phydev = |
1011 | GFP_KERNEL); | 340 | au_macs[0]->mii_bus.phy_map[phy_addr]; |
1012 | if (mii_phy) { | 341 | |
1013 | mii_phy->chip_info = mii_chip_table+i; | 342 | if (!tmp_phydev) |
1014 | aup->phy_addr = phy_addr; | 343 | continue; /* no PHY here... */ |
1015 | mii_phy->next = aup->mii; | 344 | |
1016 | aup->phy_ops = | 345 | if (tmp_phydev->attached_dev) |
1017 | mii_chip_table[i].phy_ops; | 346 | continue; /* already claimed by MAC0 */ |
1018 | aup->mii = mii_phy; | 347 | |
1019 | aup->phy_ops->phy_init(dev,phy_addr); | 348 | phydev = tmp_phydev; |
1020 | } else { | 349 | break; /* found it */ |
1021 | printk(KERN_ERR "%s: out of memory\n", | ||
1022 | dev->name); | ||
1023 | return -1; | ||
1024 | } | ||
1025 | mii_phy->chip_info = mii_chip_table+i; | ||
1026 | aup->phy_addr = phy_addr; | ||
1027 | aup->phy_ops = mii_chip_table[i].phy_ops; | ||
1028 | aup->phy_ops->phy_init(dev,phy_addr); | ||
1029 | break; | ||
1030 | } | ||
1031 | } | 350 | } |
1032 | } | 351 | } |
1033 | if (aup->mac_id == 0) { | 352 | # endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */ |
1034 | /* the Bosporus phy responds to addresses 0-5 but | ||
1035 | * 5 is the correct one. | ||
1036 | */ | ||
1037 | aup->phy_addr = 5; | ||
1038 | } | ||
1039 | #endif | ||
1040 | 353 | ||
1041 | if (aup->mii->chip_info == NULL) { | 354 | #endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */ |
1042 | printk(KERN_ERR "%s: Au1x No known MII transceivers found!\n", | 355 | if (!phydev) { |
1043 | dev->name); | 356 | printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name); |
1044 | return -1; | 357 | return -1; |
1045 | } | 358 | } |
1046 | 359 | ||
1047 | printk(KERN_INFO "%s: Using %s as default\n", | 360 | /* now we are supposed to have a proper phydev, to attach to... */ |
1048 | dev->name, aup->mii->chip_info->name); | 361 | BUG_ON(!phydev); |
362 | BUG_ON(phydev->attached_dev); | ||
363 | |||
364 | phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0); | ||
365 | |||
366 | if (IS_ERR(phydev)) { | ||
367 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | ||
368 | return PTR_ERR(phydev); | ||
369 | } | ||
370 | |||
371 | /* mask with MAC supported features */ | ||
372 | phydev->supported &= (SUPPORTED_10baseT_Half | ||
373 | | SUPPORTED_10baseT_Full | ||
374 | | SUPPORTED_100baseT_Half | ||
375 | | SUPPORTED_100baseT_Full | ||
376 | | SUPPORTED_Autoneg | ||
377 | /* | SUPPORTED_Pause | SUPPORTED_Asym_Pause */ | ||
378 | | SUPPORTED_MII | ||
379 | | SUPPORTED_TP); | ||
380 | |||
381 | phydev->advertising = phydev->supported; | ||
382 | |||
383 | aup->old_link = 0; | ||
384 | aup->old_speed = 0; | ||
385 | aup->old_duplex = -1; | ||
386 | aup->phy_dev = phydev; | ||
387 | |||
388 | printk(KERN_INFO "%s: attached PHY driver [%s] " | ||
389 | "(mii_bus:phy_addr=%s, irq=%d)\n", | ||
390 | dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq); | ||
1049 | 391 | ||
1050 | return 0; | 392 | return 0; |
1051 | } | 393 | } |
@@ -1097,35 +439,38 @@ static void hard_stop(struct net_device *dev) | |||
1097 | au_sync_delay(10); | 439 | au_sync_delay(10); |
1098 | } | 440 | } |
1099 | 441 | ||
1100 | 442 | static void enable_mac(struct net_device *dev, int force_reset) | |
1101 | static void reset_mac(struct net_device *dev) | ||
1102 | { | 443 | { |
1103 | int i; | 444 | unsigned long flags; |
1104 | u32 flags; | ||
1105 | struct au1000_private *aup = (struct au1000_private *) dev->priv; | 445 | struct au1000_private *aup = (struct au1000_private *) dev->priv; |
1106 | 446 | ||
1107 | if (au1000_debug > 4) | ||
1108 | printk(KERN_INFO "%s: reset mac, aup %x\n", | ||
1109 | dev->name, (unsigned)aup); | ||
1110 | |||
1111 | spin_lock_irqsave(&aup->lock, flags); | 447 | spin_lock_irqsave(&aup->lock, flags); |
1112 | if (aup->timer.function == &au1000_timer) {/* check if timer initted */ | ||
1113 | del_timer(&aup->timer); | ||
1114 | } | ||
1115 | 448 | ||
1116 | hard_stop(dev); | 449 | if(force_reset || (!aup->mac_enabled)) { |
1117 | #ifdef CONFIG_BCM5222_DUAL_PHY | ||
1118 | if (aup->mac_id != 0) { | ||
1119 | #endif | ||
1120 | /* If BCM5222, we can't leave MAC0 in reset because then | ||
1121 | * we can't access the dual phy for ETH1 */ | ||
1122 | *aup->enable = MAC_EN_CLOCK_ENABLE; | 450 | *aup->enable = MAC_EN_CLOCK_ENABLE; |
1123 | au_sync_delay(2); | 451 | au_sync_delay(2); |
1124 | *aup->enable = 0; | 452 | *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
453 | | MAC_EN_CLOCK_ENABLE); | ||
1125 | au_sync_delay(2); | 454 | au_sync_delay(2); |
1126 | #ifdef CONFIG_BCM5222_DUAL_PHY | 455 | |
456 | aup->mac_enabled = 1; | ||
1127 | } | 457 | } |
1128 | #endif | 458 | |
459 | spin_unlock_irqrestore(&aup->lock, flags); | ||
460 | } | ||
461 | |||
462 | static void reset_mac_unlocked(struct net_device *dev) | ||
463 | { | ||
464 | struct au1000_private *const aup = (struct au1000_private *) dev->priv; | ||
465 | int i; | ||
466 | |||
467 | hard_stop(dev); | ||
468 | |||
469 | *aup->enable = MAC_EN_CLOCK_ENABLE; | ||
470 | au_sync_delay(2); | ||
471 | *aup->enable = 0; | ||
472 | au_sync_delay(2); | ||
473 | |||
1129 | aup->tx_full = 0; | 474 | aup->tx_full = 0; |
1130 | for (i = 0; i < NUM_RX_DMA; i++) { | 475 | for (i = 0; i < NUM_RX_DMA; i++) { |
1131 | /* reset control bits */ | 476 | /* reset control bits */ |
@@ -1135,9 +480,26 @@ static void reset_mac(struct net_device *dev) | |||
1135 | /* reset control bits */ | 480 | /* reset control bits */ |
1136 | aup->tx_dma_ring[i]->buff_stat &= ~0xf; | 481 | aup->tx_dma_ring[i]->buff_stat &= ~0xf; |
1137 | } | 482 | } |
1138 | spin_unlock_irqrestore(&aup->lock, flags); | 483 | |
484 | aup->mac_enabled = 0; | ||
485 | |||
1139 | } | 486 | } |
1140 | 487 | ||
488 | static void reset_mac(struct net_device *dev) | ||
489 | { | ||
490 | struct au1000_private *const aup = (struct au1000_private *) dev->priv; | ||
491 | unsigned long flags; | ||
492 | |||
493 | if (au1000_debug > 4) | ||
494 | printk(KERN_INFO "%s: reset mac, aup %x\n", | ||
495 | dev->name, (unsigned)aup); | ||
496 | |||
497 | spin_lock_irqsave(&aup->lock, flags); | ||
498 | |||
499 | reset_mac_unlocked (dev); | ||
500 | |||
501 | spin_unlock_irqrestore(&aup->lock, flags); | ||
502 | } | ||
1141 | 503 | ||
1142 | /* | 504 | /* |
1143 | * Setup the receive and transmit "rings". These pointers are the addresses | 505 | * Setup the receive and transmit "rings". These pointers are the addresses |
@@ -1208,178 +570,31 @@ static int __init au1000_init_module(void) | |||
1208 | return 0; | 570 | return 0; |
1209 | } | 571 | } |
1210 | 572 | ||
1211 | static int au1000_setup_aneg(struct net_device *dev, u32 advertise) | 573 | /* |
1212 | { | 574 | * ethtool operations |
1213 | struct au1000_private *aup = (struct au1000_private *)dev->priv; | 575 | */ |
1214 | u16 ctl, adv; | ||
1215 | |||
1216 | /* Setup standard advertise */ | ||
1217 | adv = mdio_read(dev, aup->phy_addr, MII_ADVERTISE); | ||
1218 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); | ||
1219 | if (advertise & ADVERTISED_10baseT_Half) | ||
1220 | adv |= ADVERTISE_10HALF; | ||
1221 | if (advertise & ADVERTISED_10baseT_Full) | ||
1222 | adv |= ADVERTISE_10FULL; | ||
1223 | if (advertise & ADVERTISED_100baseT_Half) | ||
1224 | adv |= ADVERTISE_100HALF; | ||
1225 | if (advertise & ADVERTISED_100baseT_Full) | ||
1226 | adv |= ADVERTISE_100FULL; | ||
1227 | mdio_write(dev, aup->phy_addr, MII_ADVERTISE, adv); | ||
1228 | |||
1229 | /* Start/Restart aneg */ | ||
1230 | ctl = mdio_read(dev, aup->phy_addr, MII_BMCR); | ||
1231 | ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
1232 | mdio_write(dev, aup->phy_addr, MII_BMCR, ctl); | ||
1233 | |||
1234 | return 0; | ||
1235 | } | ||
1236 | 576 | ||
1237 | static int au1000_setup_forced(struct net_device *dev, int speed, int fd) | 577 | static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
1238 | { | 578 | { |
1239 | struct au1000_private *aup = (struct au1000_private *)dev->priv; | 579 | struct au1000_private *aup = (struct au1000_private *)dev->priv; |
1240 | u16 ctl; | ||
1241 | |||
1242 | ctl = mdio_read(dev, aup->phy_addr, MII_BMCR); | ||
1243 | ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE); | ||
1244 | |||
1245 | /* First reset the PHY */ | ||
1246 | mdio_write(dev, aup->phy_addr, MII_BMCR, ctl | BMCR_RESET); | ||
1247 | |||
1248 | /* Select speed & duplex */ | ||
1249 | switch (speed) { | ||
1250 | case SPEED_10: | ||
1251 | break; | ||
1252 | case SPEED_100: | ||
1253 | ctl |= BMCR_SPEED100; | ||
1254 | break; | ||
1255 | case SPEED_1000: | ||
1256 | default: | ||
1257 | return -EINVAL; | ||
1258 | } | ||
1259 | if (fd == DUPLEX_FULL) | ||
1260 | ctl |= BMCR_FULLDPLX; | ||
1261 | mdio_write(dev, aup->phy_addr, MII_BMCR, ctl); | ||
1262 | |||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | 580 | ||
1267 | static void | 581 | if (aup->phy_dev) |
1268 | au1000_start_link(struct net_device *dev, struct ethtool_cmd *cmd) | 582 | return phy_ethtool_gset(aup->phy_dev, cmd); |
1269 | { | ||
1270 | struct au1000_private *aup = (struct au1000_private *)dev->priv; | ||
1271 | u32 advertise; | ||
1272 | int autoneg; | ||
1273 | int forced_speed; | ||
1274 | int forced_duplex; | ||
1275 | |||
1276 | /* Default advertise */ | ||
1277 | advertise = GENMII_DEFAULT_ADVERTISE; | ||
1278 | autoneg = aup->want_autoneg; | ||
1279 | forced_speed = SPEED_100; | ||
1280 | forced_duplex = DUPLEX_FULL; | ||
1281 | |||
1282 | /* Setup link parameters */ | ||
1283 | if (cmd) { | ||
1284 | if (cmd->autoneg == AUTONEG_ENABLE) { | ||
1285 | advertise = cmd->advertising; | ||
1286 | autoneg = 1; | ||
1287 | } else { | ||
1288 | autoneg = 0; | ||
1289 | |||
1290 | forced_speed = cmd->speed; | ||
1291 | forced_duplex = cmd->duplex; | ||
1292 | } | ||
1293 | } | ||
1294 | 583 | ||
1295 | /* Configure PHY & start aneg */ | 584 | return -EINVAL; |
1296 | aup->want_autoneg = autoneg; | ||
1297 | if (autoneg) | ||
1298 | au1000_setup_aneg(dev, advertise); | ||
1299 | else | ||
1300 | au1000_setup_forced(dev, forced_speed, forced_duplex); | ||
1301 | mod_timer(&aup->timer, jiffies + HZ); | ||
1302 | } | 585 | } |
1303 | 586 | ||
1304 | static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 587 | static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
1305 | { | 588 | { |
1306 | struct au1000_private *aup = (struct au1000_private *)dev->priv; | 589 | struct au1000_private *aup = (struct au1000_private *)dev->priv; |
1307 | u16 link, speed; | ||
1308 | |||
1309 | cmd->supported = GENMII_DEFAULT_FEATURES; | ||
1310 | cmd->advertising = GENMII_DEFAULT_ADVERTISE; | ||
1311 | cmd->port = PORT_MII; | ||
1312 | cmd->transceiver = XCVR_EXTERNAL; | ||
1313 | cmd->phy_address = aup->phy_addr; | ||
1314 | spin_lock_irq(&aup->lock); | ||
1315 | cmd->autoneg = aup->want_autoneg; | ||
1316 | aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed); | ||
1317 | if ((speed == IF_PORT_100BASETX) || (speed == IF_PORT_100BASEFX)) | ||
1318 | cmd->speed = SPEED_100; | ||
1319 | else if (speed == IF_PORT_10BASET) | ||
1320 | cmd->speed = SPEED_10; | ||
1321 | if (link && (dev->if_port == IF_PORT_100BASEFX)) | ||
1322 | cmd->duplex = DUPLEX_FULL; | ||
1323 | else | ||
1324 | cmd->duplex = DUPLEX_HALF; | ||
1325 | spin_unlock_irq(&aup->lock); | ||
1326 | return 0; | ||
1327 | } | ||
1328 | 590 | ||
1329 | static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 591 | if (!capable(CAP_NET_ADMIN)) |
1330 | { | 592 | return -EPERM; |
1331 | struct au1000_private *aup = (struct au1000_private *)dev->priv; | ||
1332 | unsigned long features = GENMII_DEFAULT_FEATURES; | ||
1333 | |||
1334 | if (!capable(CAP_NET_ADMIN)) | ||
1335 | return -EPERM; | ||
1336 | |||
1337 | if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) | ||
1338 | return -EINVAL; | ||
1339 | if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0) | ||
1340 | return -EINVAL; | ||
1341 | if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) | ||
1342 | return -EINVAL; | ||
1343 | if (cmd->autoneg == AUTONEG_DISABLE) | ||
1344 | switch (cmd->speed) { | ||
1345 | case SPEED_10: | ||
1346 | if (cmd->duplex == DUPLEX_HALF && | ||
1347 | (features & SUPPORTED_10baseT_Half) == 0) | ||
1348 | return -EINVAL; | ||
1349 | if (cmd->duplex == DUPLEX_FULL && | ||
1350 | (features & SUPPORTED_10baseT_Full) == 0) | ||
1351 | return -EINVAL; | ||
1352 | break; | ||
1353 | case SPEED_100: | ||
1354 | if (cmd->duplex == DUPLEX_HALF && | ||
1355 | (features & SUPPORTED_100baseT_Half) == 0) | ||
1356 | return -EINVAL; | ||
1357 | if (cmd->duplex == DUPLEX_FULL && | ||
1358 | (features & SUPPORTED_100baseT_Full) == 0) | ||
1359 | return -EINVAL; | ||
1360 | break; | ||
1361 | default: | ||
1362 | return -EINVAL; | ||
1363 | } | ||
1364 | else if ((features & SUPPORTED_Autoneg) == 0) | ||
1365 | return -EINVAL; | ||
1366 | |||
1367 | spin_lock_irq(&aup->lock); | ||
1368 | au1000_start_link(dev, cmd); | ||
1369 | spin_unlock_irq(&aup->lock); | ||
1370 | return 0; | ||
1371 | } | ||
1372 | 593 | ||
1373 | static int au1000_nway_reset(struct net_device *dev) | 594 | if (aup->phy_dev) |
1374 | { | 595 | return phy_ethtool_sset(aup->phy_dev, cmd); |
1375 | struct au1000_private *aup = (struct au1000_private *)dev->priv; | ||
1376 | 596 | ||
1377 | if (!aup->want_autoneg) | 597 | return -EINVAL; |
1378 | return -EINVAL; | ||
1379 | spin_lock_irq(&aup->lock); | ||
1380 | au1000_start_link(dev, NULL); | ||
1381 | spin_unlock_irq(&aup->lock); | ||
1382 | return 0; | ||
1383 | } | 598 | } |
1384 | 599 | ||
1385 | static void | 600 | static void |
@@ -1394,17 +609,11 @@ au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1394 | info->regdump_len = 0; | 609 | info->regdump_len = 0; |
1395 | } | 610 | } |
1396 | 611 | ||
1397 | static u32 au1000_get_link(struct net_device *dev) | ||
1398 | { | ||
1399 | return netif_carrier_ok(dev); | ||
1400 | } | ||
1401 | |||
1402 | static struct ethtool_ops au1000_ethtool_ops = { | 612 | static struct ethtool_ops au1000_ethtool_ops = { |
1403 | .get_settings = au1000_get_settings, | 613 | .get_settings = au1000_get_settings, |
1404 | .set_settings = au1000_set_settings, | 614 | .set_settings = au1000_set_settings, |
1405 | .get_drvinfo = au1000_get_drvinfo, | 615 | .get_drvinfo = au1000_get_drvinfo, |
1406 | .nway_reset = au1000_nway_reset, | 616 | .get_link = ethtool_op_get_link, |
1407 | .get_link = au1000_get_link | ||
1408 | }; | 617 | }; |
1409 | 618 | ||
1410 | static struct net_device * au1000_probe(int port_num) | 619 | static struct net_device * au1000_probe(int port_num) |
@@ -1499,23 +708,31 @@ static struct net_device * au1000_probe(int port_num) | |||
1499 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | 708 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); |
1500 | dev->dev_addr[5] += port_num; | 709 | dev->dev_addr[5] += port_num; |
1501 | 710 | ||
1502 | /* Bring the device out of reset, otherwise probing the MII will hang */ | 711 | *aup->enable = 0; |
1503 | *aup->enable = MAC_EN_CLOCK_ENABLE; | 712 | aup->mac_enabled = 0; |
1504 | au_sync_delay(2); | 713 | |
1505 | *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | | 714 | aup->mii_bus.priv = dev; |
1506 | MAC_EN_CLOCK_ENABLE; | 715 | aup->mii_bus.read = mdiobus_read; |
1507 | au_sync_delay(2); | 716 | aup->mii_bus.write = mdiobus_write; |
1508 | 717 | aup->mii_bus.reset = mdiobus_reset; | |
1509 | aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL); | 718 | aup->mii_bus.name = "au1000_eth_mii"; |
1510 | if (!aup->mii) { | 719 | aup->mii_bus.id = aup->mac_id; |
1511 | printk(KERN_ERR "%s: out of memory\n", dev->name); | 720 | aup->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
1512 | goto err_out; | 721 | for(i = 0; i < PHY_MAX_ADDR; ++i) |
1513 | } | 722 | aup->mii_bus.irq[i] = PHY_POLL; |
1514 | aup->mii->next = NULL; | 723 | |
1515 | aup->mii->chip_info = NULL; | 724 | /* if known, set corresponding PHY IRQs */ |
1516 | aup->mii->status = 0; | 725 | #if defined(AU1XXX_PHY_STATIC_CONFIG) |
1517 | aup->mii->mii_control_reg = 0; | 726 | # if defined(AU1XXX_PHY0_IRQ) |
1518 | aup->mii->mii_data_reg = 0; | 727 | if (AU1XXX_PHY0_BUSID == aup->mii_bus.id) |
728 | aup->mii_bus.irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ; | ||
729 | # endif | ||
730 | # if defined(AU1XXX_PHY1_IRQ) | ||
731 | if (AU1XXX_PHY1_BUSID == aup->mii_bus.id) | ||
732 | aup->mii_bus.irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ; | ||
733 | # endif | ||
734 | #endif | ||
735 | mdiobus_register(&aup->mii_bus); | ||
1519 | 736 | ||
1520 | if (mii_probe(dev) != 0) { | 737 | if (mii_probe(dev) != 0) { |
1521 | goto err_out; | 738 | goto err_out; |
@@ -1561,7 +778,6 @@ static struct net_device * au1000_probe(int port_num) | |||
1561 | dev->set_multicast_list = &set_rx_mode; | 778 | dev->set_multicast_list = &set_rx_mode; |
1562 | dev->do_ioctl = &au1000_ioctl; | 779 | dev->do_ioctl = &au1000_ioctl; |
1563 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | 780 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); |
1564 | dev->set_config = &au1000_set_config; | ||
1565 | dev->tx_timeout = au1000_tx_timeout; | 781 | dev->tx_timeout = au1000_tx_timeout; |
1566 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | 782 | dev->watchdog_timeo = ETH_TX_TIMEOUT; |
1567 | 783 | ||
@@ -1577,7 +793,7 @@ err_out: | |||
1577 | /* here we should have a valid dev plus aup-> register addresses | 793 | /* here we should have a valid dev plus aup-> register addresses |
1578 | * so we can reset the mac properly.*/ | 794 | * so we can reset the mac properly.*/ |
1579 | reset_mac(dev); | 795 | reset_mac(dev); |
1580 | kfree(aup->mii); | 796 | |
1581 | for (i = 0; i < NUM_RX_DMA; i++) { | 797 | for (i = 0; i < NUM_RX_DMA; i++) { |
1582 | if (aup->rx_db_inuse[i]) | 798 | if (aup->rx_db_inuse[i]) |
1583 | ReleaseDB(aup, aup->rx_db_inuse[i]); | 799 | ReleaseDB(aup, aup->rx_db_inuse[i]); |
@@ -1610,19 +826,14 @@ static int au1000_init(struct net_device *dev) | |||
1610 | u32 flags; | 826 | u32 flags; |
1611 | int i; | 827 | int i; |
1612 | u32 control; | 828 | u32 control; |
1613 | u16 link, speed; | ||
1614 | 829 | ||
1615 | if (au1000_debug > 4) | 830 | if (au1000_debug > 4) |
1616 | printk("%s: au1000_init\n", dev->name); | 831 | printk("%s: au1000_init\n", dev->name); |
1617 | 832 | ||
1618 | spin_lock_irqsave(&aup->lock, flags); | ||
1619 | |||
1620 | /* bring the device out of reset */ | 833 | /* bring the device out of reset */ |
1621 | *aup->enable = MAC_EN_CLOCK_ENABLE; | 834 | enable_mac(dev, 1); |
1622 | au_sync_delay(2); | 835 | |
1623 | *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | | 836 | spin_lock_irqsave(&aup->lock, flags); |
1624 | MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE; | ||
1625 | au_sync_delay(20); | ||
1626 | 837 | ||
1627 | aup->mac->control = 0; | 838 | aup->mac->control = 0; |
1628 | aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2; | 839 | aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2; |
@@ -1638,12 +849,16 @@ static int au1000_init(struct net_device *dev) | |||
1638 | } | 849 | } |
1639 | au_sync(); | 850 | au_sync(); |
1640 | 851 | ||
1641 | aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed); | 852 | control = MAC_RX_ENABLE | MAC_TX_ENABLE; |
1642 | control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE; | ||
1643 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | 853 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
1644 | control |= MAC_BIG_ENDIAN; | 854 | control |= MAC_BIG_ENDIAN; |
1645 | #endif | 855 | #endif |
1646 | if (link && (dev->if_port == IF_PORT_100BASEFX)) { | 856 | if (aup->phy_dev) { |
857 | if (aup->phy_dev->link && (DUPLEX_FULL == aup->phy_dev->duplex)) | ||
858 | control |= MAC_FULL_DUPLEX; | ||
859 | else | ||
860 | control |= MAC_DISABLE_RX_OWN; | ||
861 | } else { /* PHY-less op, assume full-duplex */ | ||
1647 | control |= MAC_FULL_DUPLEX; | 862 | control |= MAC_FULL_DUPLEX; |
1648 | } | 863 | } |
1649 | 864 | ||
@@ -1655,57 +870,84 @@ static int au1000_init(struct net_device *dev) | |||
1655 | return 0; | 870 | return 0; |
1656 | } | 871 | } |
1657 | 872 | ||
1658 | static void au1000_timer(unsigned long data) | 873 | static void |
874 | au1000_adjust_link(struct net_device *dev) | ||
1659 | { | 875 | { |
1660 | struct net_device *dev = (struct net_device *)data; | ||
1661 | struct au1000_private *aup = (struct au1000_private *) dev->priv; | 876 | struct au1000_private *aup = (struct au1000_private *) dev->priv; |
1662 | unsigned char if_port; | 877 | struct phy_device *phydev = aup->phy_dev; |
1663 | u16 link, speed; | 878 | unsigned long flags; |
1664 | 879 | ||
1665 | if (!dev) { | 880 | int status_change = 0; |
1666 | /* fatal error, don't restart the timer */ | ||
1667 | printk(KERN_ERR "au1000_timer error: NULL dev\n"); | ||
1668 | return; | ||
1669 | } | ||
1670 | 881 | ||
1671 | if_port = dev->if_port; | 882 | BUG_ON(!aup->phy_dev); |
1672 | if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) { | 883 | |
1673 | if (link) { | 884 | spin_lock_irqsave(&aup->lock, flags); |
1674 | if (!netif_carrier_ok(dev)) { | 885 | |
1675 | netif_carrier_on(dev); | 886 | if (phydev->link && (aup->old_speed != phydev->speed)) { |
1676 | printk(KERN_INFO "%s: link up\n", dev->name); | 887 | // speed changed |
1677 | } | 888 | |
1678 | } | 889 | switch(phydev->speed) { |
1679 | else { | 890 | case SPEED_10: |
1680 | if (netif_carrier_ok(dev)) { | 891 | case SPEED_100: |
1681 | netif_carrier_off(dev); | 892 | break; |
1682 | dev->if_port = 0; | 893 | default: |
1683 | printk(KERN_INFO "%s: link down\n", dev->name); | 894 | printk(KERN_WARNING |
1684 | } | 895 | "%s: Speed (%d) is not 10/100 ???\n", |
896 | dev->name, phydev->speed); | ||
897 | break; | ||
1685 | } | 898 | } |
899 | |||
900 | aup->old_speed = phydev->speed; | ||
901 | |||
902 | status_change = 1; | ||
1686 | } | 903 | } |
1687 | 904 | ||
1688 | if (link && (dev->if_port != if_port) && | 905 | if (phydev->link && (aup->old_duplex != phydev->duplex)) { |
1689 | (dev->if_port != IF_PORT_UNKNOWN)) { | 906 | // duplex mode changed |
907 | |||
908 | /* switching duplex mode requires to disable rx and tx! */ | ||
1690 | hard_stop(dev); | 909 | hard_stop(dev); |
1691 | if (dev->if_port == IF_PORT_100BASEFX) { | 910 | |
1692 | printk(KERN_INFO "%s: going to full duplex\n", | 911 | if (DUPLEX_FULL == phydev->duplex) |
1693 | dev->name); | 912 | aup->mac->control = ((aup->mac->control |
1694 | aup->mac->control |= MAC_FULL_DUPLEX; | 913 | | MAC_FULL_DUPLEX) |
1695 | au_sync_delay(1); | 914 | & ~MAC_DISABLE_RX_OWN); |
1696 | } | 915 | else |
1697 | else { | 916 | aup->mac->control = ((aup->mac->control |
1698 | aup->mac->control &= ~MAC_FULL_DUPLEX; | 917 | & ~MAC_FULL_DUPLEX) |
1699 | au_sync_delay(1); | 918 | | MAC_DISABLE_RX_OWN); |
1700 | } | 919 | au_sync_delay(1); |
920 | |||
1701 | enable_rx_tx(dev); | 921 | enable_rx_tx(dev); |
922 | aup->old_duplex = phydev->duplex; | ||
923 | |||
924 | status_change = 1; | ||
925 | } | ||
926 | |||
927 | if(phydev->link != aup->old_link) { | ||
928 | // link state changed | ||
929 | |||
930 | if (phydev->link) // link went up | ||
931 | netif_schedule(dev); | ||
932 | else { // link went down | ||
933 | aup->old_speed = 0; | ||
934 | aup->old_duplex = -1; | ||
935 | } | ||
936 | |||
937 | aup->old_link = phydev->link; | ||
938 | status_change = 1; | ||
1702 | } | 939 | } |
1703 | 940 | ||
1704 | aup->timer.expires = RUN_AT((1*HZ)); | 941 | spin_unlock_irqrestore(&aup->lock, flags); |
1705 | aup->timer.data = (unsigned long)dev; | ||
1706 | aup->timer.function = &au1000_timer; /* timer handler */ | ||
1707 | add_timer(&aup->timer); | ||
1708 | 942 | ||
943 | if (status_change) { | ||
944 | if (phydev->link) | ||
945 | printk(KERN_INFO "%s: link up (%d/%s)\n", | ||
946 | dev->name, phydev->speed, | ||
947 | DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); | ||
948 | else | ||
949 | printk(KERN_INFO "%s: link down\n", dev->name); | ||
950 | } | ||
1709 | } | 951 | } |
1710 | 952 | ||
1711 | static int au1000_open(struct net_device *dev) | 953 | static int au1000_open(struct net_device *dev) |
@@ -1716,25 +958,26 @@ static int au1000_open(struct net_device *dev) | |||
1716 | if (au1000_debug > 4) | 958 | if (au1000_debug > 4) |
1717 | printk("%s: open: dev=%p\n", dev->name, dev); | 959 | printk("%s: open: dev=%p\n", dev->name, dev); |
1718 | 960 | ||
961 | if ((retval = request_irq(dev->irq, &au1000_interrupt, 0, | ||
962 | dev->name, dev))) { | ||
963 | printk(KERN_ERR "%s: unable to get IRQ %d\n", | ||
964 | dev->name, dev->irq); | ||
965 | return retval; | ||
966 | } | ||
967 | |||
1719 | if ((retval = au1000_init(dev))) { | 968 | if ((retval = au1000_init(dev))) { |
1720 | printk(KERN_ERR "%s: error in au1000_init\n", dev->name); | 969 | printk(KERN_ERR "%s: error in au1000_init\n", dev->name); |
1721 | free_irq(dev->irq, dev); | 970 | free_irq(dev->irq, dev); |
1722 | return retval; | 971 | return retval; |
1723 | } | 972 | } |
1724 | netif_start_queue(dev); | ||
1725 | 973 | ||
1726 | if ((retval = request_irq(dev->irq, &au1000_interrupt, 0, | 974 | if (aup->phy_dev) { |
1727 | dev->name, dev))) { | 975 | /* cause the PHY state machine to schedule a link state check */ |
1728 | printk(KERN_ERR "%s: unable to get IRQ %d\n", | 976 | aup->phy_dev->state = PHY_CHANGELINK; |
1729 | dev->name, dev->irq); | 977 | phy_start(aup->phy_dev); |
1730 | return retval; | ||
1731 | } | 978 | } |
1732 | 979 | ||
1733 | init_timer(&aup->timer); /* used in ioctl() */ | 980 | netif_start_queue(dev); |
1734 | aup->timer.expires = RUN_AT((3*HZ)); | ||
1735 | aup->timer.data = (unsigned long)dev; | ||
1736 | aup->timer.function = &au1000_timer; /* timer handler */ | ||
1737 | add_timer(&aup->timer); | ||
1738 | 981 | ||
1739 | if (au1000_debug > 4) | 982 | if (au1000_debug > 4) |
1740 | printk("%s: open: Initialization done.\n", dev->name); | 983 | printk("%s: open: Initialization done.\n", dev->name); |
@@ -1744,16 +987,19 @@ static int au1000_open(struct net_device *dev) | |||
1744 | 987 | ||
1745 | static int au1000_close(struct net_device *dev) | 988 | static int au1000_close(struct net_device *dev) |
1746 | { | 989 | { |
1747 | u32 flags; | 990 | unsigned long flags; |
1748 | struct au1000_private *aup = (struct au1000_private *) dev->priv; | 991 | struct au1000_private *const aup = (struct au1000_private *) dev->priv; |
1749 | 992 | ||
1750 | if (au1000_debug > 4) | 993 | if (au1000_debug > 4) |
1751 | printk("%s: close: dev=%p\n", dev->name, dev); | 994 | printk("%s: close: dev=%p\n", dev->name, dev); |
1752 | 995 | ||
1753 | reset_mac(dev); | 996 | if (aup->phy_dev) |
997 | phy_stop(aup->phy_dev); | ||
1754 | 998 | ||
1755 | spin_lock_irqsave(&aup->lock, flags); | 999 | spin_lock_irqsave(&aup->lock, flags); |
1756 | 1000 | ||
1001 | reset_mac_unlocked (dev); | ||
1002 | |||
1757 | /* stop the device */ | 1003 | /* stop the device */ |
1758 | netif_stop_queue(dev); | 1004 | netif_stop_queue(dev); |
1759 | 1005 | ||
@@ -1775,7 +1021,6 @@ static void __exit au1000_cleanup_module(void) | |||
1775 | if (dev) { | 1021 | if (dev) { |
1776 | aup = (struct au1000_private *) dev->priv; | 1022 | aup = (struct au1000_private *) dev->priv; |
1777 | unregister_netdev(dev); | 1023 | unregister_netdev(dev); |
1778 | kfree(aup->mii); | ||
1779 | for (j = 0; j < NUM_RX_DMA; j++) | 1024 | for (j = 0; j < NUM_RX_DMA; j++) |
1780 | if (aup->rx_db_inuse[j]) | 1025 | if (aup->rx_db_inuse[j]) |
1781 | ReleaseDB(aup, aup->rx_db_inuse[j]); | 1026 | ReleaseDB(aup, aup->rx_db_inuse[j]); |
@@ -1798,7 +1043,7 @@ static void update_tx_stats(struct net_device *dev, u32 status) | |||
1798 | struct net_device_stats *ps = &aup->stats; | 1043 | struct net_device_stats *ps = &aup->stats; |
1799 | 1044 | ||
1800 | if (status & TX_FRAME_ABORTED) { | 1045 | if (status & TX_FRAME_ABORTED) { |
1801 | if (dev->if_port == IF_PORT_100BASEFX) { | 1046 | if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) { |
1802 | if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { | 1047 | if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { |
1803 | /* any other tx errors are only valid | 1048 | /* any other tx errors are only valid |
1804 | * in half duplex mode */ | 1049 | * in half duplex mode */ |
@@ -2072,126 +1317,15 @@ static void set_rx_mode(struct net_device *dev) | |||
2072 | } | 1317 | } |
2073 | } | 1318 | } |
2074 | 1319 | ||
2075 | |||
2076 | static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 1320 | static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
2077 | { | 1321 | { |
2078 | struct au1000_private *aup = (struct au1000_private *)dev->priv; | 1322 | struct au1000_private *aup = (struct au1000_private *)dev->priv; |
2079 | u16 *data = (u16 *)&rq->ifr_ifru; | ||
2080 | |||
2081 | switch(cmd) { | ||
2082 | case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ | ||
2083 | case SIOCGMIIPHY: | ||
2084 | if (!netif_running(dev)) return -EINVAL; | ||
2085 | data[0] = aup->phy_addr; | ||
2086 | case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ | ||
2087 | case SIOCGMIIREG: | ||
2088 | data[3] = mdio_read(dev, data[0], data[1]); | ||
2089 | return 0; | ||
2090 | case SIOCDEVPRIVATE+2: /* Write the specified MII register */ | ||
2091 | case SIOCSMIIREG: | ||
2092 | if (!capable(CAP_NET_ADMIN)) | ||
2093 | return -EPERM; | ||
2094 | mdio_write(dev, data[0], data[1],data[2]); | ||
2095 | return 0; | ||
2096 | default: | ||
2097 | return -EOPNOTSUPP; | ||
2098 | } | ||
2099 | |||
2100 | } | ||
2101 | |||
2102 | |||
2103 | static int au1000_set_config(struct net_device *dev, struct ifmap *map) | ||
2104 | { | ||
2105 | struct au1000_private *aup = (struct au1000_private *) dev->priv; | ||
2106 | u16 control; | ||
2107 | 1323 | ||
2108 | if (au1000_debug > 4) { | 1324 | if (!netif_running(dev)) return -EINVAL; |
2109 | printk("%s: set_config called: dev->if_port %d map->port %x\n", | ||
2110 | dev->name, dev->if_port, map->port); | ||
2111 | } | ||
2112 | 1325 | ||
2113 | switch(map->port){ | 1326 | if (!aup->phy_dev) return -EINVAL; // PHY not controllable |
2114 | case IF_PORT_UNKNOWN: /* use auto here */ | ||
2115 | printk(KERN_INFO "%s: config phy for aneg\n", | ||
2116 | dev->name); | ||
2117 | dev->if_port = map->port; | ||
2118 | /* Link Down: the timer will bring it up */ | ||
2119 | netif_carrier_off(dev); | ||
2120 | |||
2121 | /* read current control */ | ||
2122 | control = mdio_read(dev, aup->phy_addr, MII_CONTROL); | ||
2123 | control &= ~(MII_CNTL_FDX | MII_CNTL_F100); | ||
2124 | |||
2125 | /* enable auto negotiation and reset the negotiation */ | ||
2126 | mdio_write(dev, aup->phy_addr, MII_CONTROL, | ||
2127 | control | MII_CNTL_AUTO | | ||
2128 | MII_CNTL_RST_AUTO); | ||
2129 | 1327 | ||
2130 | break; | 1328 | return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); |
2131 | |||
2132 | case IF_PORT_10BASET: /* 10BaseT */ | ||
2133 | printk(KERN_INFO "%s: config phy for 10BaseT\n", | ||
2134 | dev->name); | ||
2135 | dev->if_port = map->port; | ||
2136 | |||
2137 | /* Link Down: the timer will bring it up */ | ||
2138 | netif_carrier_off(dev); | ||
2139 | |||
2140 | /* set Speed to 10Mbps, Half Duplex */ | ||
2141 | control = mdio_read(dev, aup->phy_addr, MII_CONTROL); | ||
2142 | control &= ~(MII_CNTL_F100 | MII_CNTL_AUTO | | ||
2143 | MII_CNTL_FDX); | ||
2144 | |||
2145 | /* disable auto negotiation and force 10M/HD mode*/ | ||
2146 | mdio_write(dev, aup->phy_addr, MII_CONTROL, control); | ||
2147 | break; | ||
2148 | |||
2149 | case IF_PORT_100BASET: /* 100BaseT */ | ||
2150 | case IF_PORT_100BASETX: /* 100BaseTx */ | ||
2151 | printk(KERN_INFO "%s: config phy for 100BaseTX\n", | ||
2152 | dev->name); | ||
2153 | dev->if_port = map->port; | ||
2154 | |||
2155 | /* Link Down: the timer will bring it up */ | ||
2156 | netif_carrier_off(dev); | ||
2157 | |||
2158 | /* set Speed to 100Mbps, Half Duplex */ | ||
2159 | /* disable auto negotiation and enable 100MBit Mode */ | ||
2160 | control = mdio_read(dev, aup->phy_addr, MII_CONTROL); | ||
2161 | control &= ~(MII_CNTL_AUTO | MII_CNTL_FDX); | ||
2162 | control |= MII_CNTL_F100; | ||
2163 | mdio_write(dev, aup->phy_addr, MII_CONTROL, control); | ||
2164 | break; | ||
2165 | |||
2166 | case IF_PORT_100BASEFX: /* 100BaseFx */ | ||
2167 | printk(KERN_INFO "%s: config phy for 100BaseFX\n", | ||
2168 | dev->name); | ||
2169 | dev->if_port = map->port; | ||
2170 | |||
2171 | /* Link Down: the timer will bring it up */ | ||
2172 | netif_carrier_off(dev); | ||
2173 | |||
2174 | /* set Speed to 100Mbps, Full Duplex */ | ||
2175 | /* disable auto negotiation and enable 100MBit Mode */ | ||
2176 | control = mdio_read(dev, aup->phy_addr, MII_CONTROL); | ||
2177 | control &= ~MII_CNTL_AUTO; | ||
2178 | control |= MII_CNTL_F100 | MII_CNTL_FDX; | ||
2179 | mdio_write(dev, aup->phy_addr, MII_CONTROL, control); | ||
2180 | break; | ||
2181 | case IF_PORT_10BASE2: /* 10Base2 */ | ||
2182 | case IF_PORT_AUI: /* AUI */ | ||
2183 | /* These Modes are not supported (are they?)*/ | ||
2184 | printk(KERN_ERR "%s: 10Base2/AUI not supported", | ||
2185 | dev->name); | ||
2186 | return -EOPNOTSUPP; | ||
2187 | break; | ||
2188 | |||
2189 | default: | ||
2190 | printk(KERN_ERR "%s: Invalid media selected", | ||
2191 | dev->name); | ||
2192 | return -EINVAL; | ||
2193 | } | ||
2194 | return 0; | ||
2195 | } | 1329 | } |
2196 | 1330 | ||
2197 | static struct net_device_stats *au1000_get_stats(struct net_device *dev) | 1331 | static struct net_device_stats *au1000_get_stats(struct net_device *dev) |