2 * drivers/net/gianfar_phy.c
4 * Gianfar Ethernet Driver -- PHY handling
5 * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
6 * Based on 8260_io/fcc_enet.c
9 * Maintainer: Kumar Gala (kumar.gala@freescale.com)
11 * Copyright 2004 Freescale Semiconductor, Inc
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
20 #include <linux/config.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/string.h>
24 #include <linux/errno.h>
25 #include <linux/slab.h>
26 #include <linux/interrupt.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/netdevice.h>
30 #include <linux/etherdevice.h>
31 #include <linux/skbuff.h>
32 #include <linux/spinlock.h>
34 #include <linux/mii.h>
38 #include <asm/uaccess.h>
39 #include <linux/module.h>
40 #include <linux/version.h>
41 #include <linux/crc32.h>
44 #include "gianfar_phy.h"
46 /* Write value to the PHY for this device to the register at regnum, */
47 /* waiting until the write is done before it returns. All PHY */
48 /* configuration has to be done through the TSEC1 MIIM regs */
49 void write_phy_reg(struct net_device *dev, u16 regnum, u16 value)
51 struct gfar_private *priv = (struct gfar_private *) dev->priv;
52 struct gfar *regbase = priv->phyregs;
53 struct ocp_gfar_data *einfo = priv->einfo;
55 /* Set the PHY address and the register address we want to write */
56 gfar_write(®base->miimadd, ((einfo->phyid) << 8) | regnum);
58 /* Write out the value we want */
59 gfar_write(®base->miimcon, value);
61 /* Wait for the transaction to finish */
62 while (gfar_read(®base->miimind) & MIIMIND_BUSY)
66 /* Reads from register regnum in the PHY for device dev, */
67 /* returning the value. Clears miimcom first. All PHY */
68 /* configuration has to be done through the TSEC1 MIIM regs */
69 u16 read_phy_reg(struct net_device *dev, u16 regnum)
71 struct gfar_private *priv = (struct gfar_private *) dev->priv;
72 struct gfar *regbase = priv->phyregs;
73 struct ocp_gfar_data *einfo = priv->einfo;
76 /* Set the PHY address and the register address we want to read */
77 gfar_write(®base->miimadd, ((einfo->phyid) << 8) | regnum);
79 /* Clear miimcom, and then initiate a read */
80 gfar_write(®base->miimcom, 0);
81 gfar_write(®base->miimcom, MIIM_READ_COMMAND);
83 /* Wait for the transaction to finish */
84 while (gfar_read(®base->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
87 /* Grab the value of the register from miimstat */
88 value = gfar_read(®base->miimstat);
93 /* returns which value to write to the control register. */
94 /* For 10/100 the value is slightly different. */
95 u16 mii_cr_init(u16 mii_reg, struct net_device * dev)
97 struct gfar_private *priv = (struct gfar_private *) dev->priv;
98 struct ocp_gfar_data *einfo = priv->einfo;
100 if (einfo->flags & GFAR_HAS_GIGABIT)
101 return MIIM_CONTROL_INIT;
106 #define BRIEF_GFAR_ERRORS
107 /* Wait for auto-negotiation to complete */
108 u16 mii_parse_sr(u16 mii_reg, struct net_device * dev)
110 struct gfar_private *priv = (struct gfar_private *) dev->priv;
112 unsigned int timeout = GFAR_AN_TIMEOUT;
114 if (mii_reg & MIIM_STATUS_LINK)
119 /* Only auto-negotiate if the link has just gone up */
120 if (priv->link && !priv->oldlink) {
121 while ((!(mii_reg & MIIM_STATUS_AN_DONE)) && timeout--)
122 mii_reg = read_phy_reg(dev, MIIM_STATUS);
124 #if defined(BRIEF_GFAR_ERRORS)
125 if (mii_reg & MIIM_STATUS_AN_DONE)
126 printk(KERN_INFO "%s: Auto-negotiation done\n",
129 printk(KERN_INFO "%s: Auto-negotiation timed out\n",
137 /* Determine the speed and duplex which was negotiated */
138 u16 mii_parse_88E1011_psr(u16 mii_reg, struct net_device * dev)
140 struct gfar_private *priv = (struct gfar_private *) dev->priv;
144 if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX)
149 speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED);
152 case MIIM_88E1011_PHYSTAT_GBIT:
155 case MIIM_88E1011_PHYSTAT_100:
170 u16 mii_parse_cis8201(u16 mii_reg, struct net_device * dev)
172 struct gfar_private *priv = (struct gfar_private *) dev->priv;
176 if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX)
181 speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED;
184 case MIIM_CIS8201_AUXCONSTAT_GBIT:
187 case MIIM_CIS8201_AUXCONSTAT_100:
202 u16 mii_parse_dm9161_scsr(u16 mii_reg, struct net_device * dev)
204 struct gfar_private *priv = (struct gfar_private *) dev->priv;
206 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
211 if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
219 u16 dm9161_wait(u16 mii_reg, struct net_device *dev)
227 /* Davicom takes a bit to come up after a reset,
228 * so wait here for a bit */
229 set_current_state(TASK_UNINTERRUPTIBLE);
230 schedule_timeout(timeout);
232 temp = read_phy_reg(dev, MIIM_STATUS);
235 } while ((!(temp & MIIM_STATUS_AN_DONE)) && secondary);
241 * consult the BCM54xx auxilliary status register to find the link settings
243 u16 mii_parse_bcm54xx_sr(u16 mii_reg, struct net_device * dev)
245 struct gfar_private *priv = (struct gfar_private *) dev->priv;
247 /* Link modes of the BCM5400 PHY */
248 static const uint16_t link_table[8][3] = {
249 { 0, 0 }, /* No link */
250 { 0, 10 }, /* 10BT Half Duplex */
251 { 1, 10 }, /* 10BT Full Duplex */
252 { 0, 100 }, /* 100BT Half Duplex */
253 { 0, 100 }, /* 100BT Half Duplex */
254 { 1, 100 }, /* 100BT Full Duplex*/
255 { 1, 1000 }, /* 1000BT */
256 { 1, 1000 }, /* 1000BT */
261 link_mode = mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK;
262 link_mode >>= MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT;
264 priv->duplexity = link_table[link_mode][0];
265 priv->speed = link_table[link_mode][1];
270 static struct phy_info phy_info_M88E1011S = {
274 (const struct phy_cmd[]) { /* config */
275 /* Reset and configure the PHY */
276 {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init},
279 (const struct phy_cmd[]) { /* startup */
280 /* Status is read once to clear old link state */
281 {MIIM_STATUS, miim_read, NULL},
283 {MIIM_STATUS, miim_read, mii_parse_sr},
284 /* Read the status */
285 {MIIM_88E1011_PHY_STATUS, miim_read, mii_parse_88E1011_psr},
286 /* Clear the IEVENT register */
287 {MIIM_88E1011_IEVENT, miim_read, NULL},
288 /* Set up the mask */
289 {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_INIT, NULL},
292 (const struct phy_cmd[]) { /* ack_int */
293 /* Clear the interrupt */
294 {MIIM_88E1011_IEVENT, miim_read, NULL},
295 /* Disable interrupts */
296 {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_CLEAR, NULL},
299 (const struct phy_cmd[]) { /* handle_int */
300 /* Read the Status (2x to make sure link is right) */
301 {MIIM_STATUS, miim_read, NULL},
302 /* Check the status */
303 {MIIM_STATUS, miim_read, mii_parse_sr},
304 {MIIM_88E1011_PHY_STATUS, miim_read, mii_parse_88E1011_psr},
305 /* Enable Interrupts */
306 {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_INIT, NULL},
309 (const struct phy_cmd[]) { /* shutdown */
310 {MIIM_88E1011_IEVENT, miim_read, NULL},
311 {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_CLEAR, NULL},
317 static struct phy_info phy_info_cis8204 = {
321 (const struct phy_cmd[]) { /* config */
322 /* Override PHY config settings */
323 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
324 /* Set up the interface mode */
325 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
326 /* Configure some basic stuff */
327 {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init},
330 (const struct phy_cmd[]) { /* startup */
331 /* Read the Status (2x to make sure link is right) */
332 {MIIM_STATUS, miim_read, NULL},
334 {MIIM_STATUS, miim_read, mii_parse_sr},
335 /* Read the status */
336 {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201},
337 /* Clear the status register */
338 {MIIM_CIS8204_ISTAT, miim_read, NULL},
339 /* Enable interrupts */
340 {MIIM_CIS8204_IMASK, MIIM_CIS8204_IMASK_MASK, NULL},
343 (const struct phy_cmd[]) { /* ack_int */
344 /* Clear the status register */
345 {MIIM_CIS8204_ISTAT, miim_read, NULL},
346 /* Disable interrupts */
347 {MIIM_CIS8204_IMASK, 0x0, NULL},
350 (const struct phy_cmd[]) { /* handle_int */
351 /* Read the Status (2x to make sure link is right) */
352 {MIIM_STATUS, miim_read, NULL},
354 {MIIM_STATUS, miim_read, mii_parse_sr},
355 /* Read the status */
356 {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201},
357 /* Enable interrupts */
358 {MIIM_CIS8204_IMASK, MIIM_CIS8204_IMASK_MASK, NULL},
361 (const struct phy_cmd[]) { /* shutdown */
362 /* Clear the status register */
363 {MIIM_CIS8204_ISTAT, miim_read, NULL},
364 /* Disable interrupts */
365 {MIIM_CIS8204_IMASK, 0x0, NULL},
371 static struct phy_info phy_info_cis8201 = {
375 (const struct phy_cmd[]) { /* config */
376 /* Override PHY config settings */
377 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
378 /* Set up the interface mode */
379 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
380 /* Configure some basic stuff */
381 {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init},
384 (const struct phy_cmd[]) { /* startup */
385 /* Read the Status (2x to make sure link is right) */
386 {MIIM_STATUS, miim_read, NULL},
388 {MIIM_STATUS, miim_read, mii_parse_sr},
389 /* Read the status */
390 {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201},
393 (const struct phy_cmd[]) { /* ack_int */
396 (const struct phy_cmd[]) { /* handle_int */
399 (const struct phy_cmd[]) { /* shutdown */
404 static struct phy_info phy_info_dm9161 = {
408 (const struct phy_cmd[]) { /* config */
409 {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL},
410 /* Do not bypass the scrambler/descrambler */
411 {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL},
412 /* Clear 10BTCSR to default */
413 {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL},
414 /* Configure some basic stuff */
415 {MIIM_CONTROL, MIIM_CR_INIT, NULL},
418 (const struct phy_cmd[]) { /* startup */
419 /* Restart Auto Negotiation */
420 {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL},
421 /* Status is read once to clear old link state */
422 {MIIM_STATUS, miim_read, dm9161_wait},
424 {MIIM_STATUS, miim_read, mii_parse_sr},
425 /* Read the status */
426 {MIIM_DM9161_SCSR, miim_read, mii_parse_dm9161_scsr},
427 /* Clear any pending interrupts */
428 {MIIM_DM9161_INTR, miim_read, NULL},
431 (const struct phy_cmd[]) { /* ack_int */
432 {MIIM_DM9161_INTR, miim_read, NULL},
435 (const struct phy_cmd[]) { /* handle_int */
436 {MIIM_STATUS, miim_read, NULL},
437 {MIIM_STATUS, miim_read, mii_parse_sr},
438 {MIIM_DM9161_SCSR, miim_read, mii_parse_dm9161_scsr},
441 (const struct phy_cmd[]) { /* shutdown */
442 {MIIM_DM9161_INTR, miim_read, NULL},
447 /* Broadcom BCM5421S PHY */
448 static struct phy_info phy_info_bcm5421s = {
450 .name = "Broadcom BCM5421S",
452 .config = (const struct phy_cmd[]) {
453 /* Configure some basic stuff */
454 {MIIM_CONTROL, MIIM_CR_INIT, NULL},
455 #if 0 /* 5421 only */
456 miim_write(MII_BCM5400_AUXCONTROL, 0x1007),
457 miim_set_bits(MII_BCM5400_AUXCONTROL, 0x0400),
458 miim_write(MII_BCM5400_AUXCONTROL, 0x0007),
459 miim_set_bits(MII_BCM5400_AUXCONTROL, 0x0800),
460 miim_write(0x17, 0x000a),
461 miim_set_bits(MII_RERRCOUNTER, 0x0200),
463 #if 0 /* enable automatic low power */
464 miim_write(MII_NCONFIG, 0x9002),
465 miim_write(MII_NCONFIG, 0xa821),
466 miim_write(MII_NCONFIG, 0x941d),
470 .startup = (const struct phy_cmd[]) {
471 /* Restart Auto Negotiation */
472 miim_set_bits(MIIM_CONTROL, BMCR_ANENABLE | BMCR_ANRESTART),
474 /* Status is read once to clear old link state */
475 {MIIM_STATUS, miim_read, dm9161_wait},
478 {MIIM_STATUS, miim_read, mii_parse_sr},
480 /* Read the link status */
481 {MIIM_BCM54xx_AUXSTATUS, miim_read, mii_parse_bcm54xx_sr},
485 .ack_int = (const struct phy_cmd[]) {
488 .handle_int = (const struct phy_cmd[]) {
489 {MIIM_STATUS, miim_read, NULL},
490 {MIIM_STATUS, miim_read, mii_parse_sr},
493 .shutdown = (const struct phy_cmd[]) {
498 static struct phy_info *phy_info[] = {
507 /* Use the PHY ID registers to determine what type of PHY is attached
508 * to device dev. return a struct phy_info structure describing that PHY
510 struct phy_info * get_phy_info(struct net_device *dev)
515 struct phy_info *theInfo = NULL;
517 /* Grab the bits from PHYIR1, and put them in the upper half */
518 phy_reg = read_phy_reg(dev, MIIM_PHYIR1);
519 phy_ID = (phy_reg & 0xffff) << 16;
521 /* Grab the bits from PHYIR2, and put them in the lower half */
522 phy_reg = read_phy_reg(dev, MIIM_PHYIR2);
523 phy_ID |= (phy_reg & 0xffff);
525 /* loop through all the known PHY types, and find one that */
526 /* matches the ID we read from the PHY. */
527 for (i = 0; phy_info[i]; i++)
528 if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift))
529 theInfo = phy_info[i];
531 if (theInfo == NULL) {
532 printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
535 printk("%s: PHY is %s (%x)\n", dev->name, theInfo->name,
542 /* Take a list of struct phy_cmd, and, depending on the values, either */
543 /* read or write, using a helper function if provided */
544 /* It is assumed that all lists of struct phy_cmd will be terminated by */
546 void phy_run_commands(struct net_device *dev, const struct phy_cmd *cmd)
550 struct gfar_private *priv = (struct gfar_private *) dev->priv;
551 struct gfar *phyregs = priv->phyregs;
553 /* Reset the management interface */
554 gfar_write(&phyregs->miimcfg, MIIMCFG_RESET);
556 /* Setup the MII Mgmt clock speed */
557 gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
559 /* Wait until the bus is free */
560 while (gfar_read(&phyregs->miimind) & MIIMIND_BUSY)
563 for (i = 0; cmd->mii_reg != miim_end; i++) {
564 switch (cmd->mii_data >> 16) {
566 /* Otherwise, it's a write */
567 /* If a function was supplied, it will provide
568 * the value to write */
569 /* Otherwise, the value was supplied in cmd->mii_data */
570 if (cmd->funct != NULL)
571 result = (*(cmd->funct)) (0, dev);
573 result = cmd->mii_data;
575 write_phy_reg(dev, cmd->mii_reg, result);
579 /* Read the value of the PHY reg */
580 result = read_phy_reg(dev, cmd->mii_reg);
582 /* If a function was supplied, we need to let it process */
584 if (cmd->funct != NULL)
585 (*(cmd->funct)) (result, dev);
589 /* read the value, clear some bits and write it back */
592 result = read_phy_reg(dev, cmd->mii_reg);
593 result &= cmd->mii_data;
594 write_phy_reg(dev, cmd->mii_reg, result);
598 /* read the value, set some bits and write it back */
601 result = read_phy_reg(dev, cmd->mii_reg);
602 result &= cmd->mii_data;
603 write_phy_reg(dev, cmd->mii_reg, result);
607 /* read the value, flip some bits and write it back */
610 result = read_phy_reg(dev, cmd->mii_reg);
611 result &= cmd->mii_data;
612 write_phy_reg(dev, cmd->mii_reg, result);
616 printk("GIANFAR: Unknown MII command %08x\n",