aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfrederic RODO <f.rodo@til-technologies.fr>2007-07-12 13:07:24 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-16 18:28:04 -0400
commit6c36a7074436e181fb3df41f66bbdaf53980951e (patch)
tree8be326aad4f8798059a3606aa29326d9dbad8043
parent54ab2927d38536f6d437bdd0d7454b99bf67a48c (diff)
macb: Use generic PHY layer
Convert the macb driver to use the generic PHY layer in drivers/net/phy. Signed-off-by: Frederic RODO <f.rodo@til-technologies.fr> Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/macb.c451
-rw-r--r--drivers/net/macb.h10
-rw-r--r--include/asm-arm/arch-at91/board.h1
-rw-r--r--include/asm-avr32/arch-at32ap/board.h1
5 files changed, 208 insertions, 257 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b941c74a06c4..4b9b7fe41ee0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -187,7 +187,7 @@ config MII
187config MACB 187config MACB
188 tristate "Atmel MACB support" 188 tristate "Atmel MACB support"
189 depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 189 depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263
190 select MII 190 select PHYLIB
191 help 191 help
192 The Atmel MACB ethernet interface is found on many AT32 and AT91 192 The Atmel MACB ethernet interface is found on many AT32 and AT91
193 parts. Say Y to include support for the MACB chip. 193 parts. Say Y to include support for the MACB chip.
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 0e04f7ac3f2e..83c35fd91e0f 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -17,13 +17,12 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/netdevice.h> 18#include <linux/netdevice.h>
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <linux/mii.h>
21#include <linux/mutex.h>
22#include <linux/dma-mapping.h> 20#include <linux/dma-mapping.h>
23#include <linux/ethtool.h>
24#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/phy.h>
25 23
26#include <asm/arch/board.h> 24#include <asm/arch/board.h>
25#include <asm/arch/cpu.h>
27 26
28#include "macb.h" 27#include "macb.h"
29 28
@@ -85,172 +84,202 @@ static void __init macb_get_hwaddr(struct macb *bp)
85 memcpy(bp->dev->dev_addr, addr, sizeof(addr)); 84 memcpy(bp->dev->dev_addr, addr, sizeof(addr));
86} 85}
87 86
88static void macb_enable_mdio(struct macb *bp) 87static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
89{ 88{
90 unsigned long flags; 89 struct macb *bp = bus->priv;
91 u32 reg;
92
93 spin_lock_irqsave(&bp->lock, flags);
94 reg = macb_readl(bp, NCR);
95 reg |= MACB_BIT(MPE);
96 macb_writel(bp, NCR, reg);
97 macb_writel(bp, IER, MACB_BIT(MFD));
98 spin_unlock_irqrestore(&bp->lock, flags);
99}
100
101static void macb_disable_mdio(struct macb *bp)
102{
103 unsigned long flags;
104 u32 reg;
105
106 spin_lock_irqsave(&bp->lock, flags);
107 reg = macb_readl(bp, NCR);
108 reg &= ~MACB_BIT(MPE);
109 macb_writel(bp, NCR, reg);
110 macb_writel(bp, IDR, MACB_BIT(MFD));
111 spin_unlock_irqrestore(&bp->lock, flags);
112}
113
114static int macb_mdio_read(struct net_device *dev, int phy_id, int location)
115{
116 struct macb *bp = netdev_priv(dev);
117 int value; 90 int value;
118 91
119 mutex_lock(&bp->mdio_mutex);
120
121 macb_enable_mdio(bp);
122 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) 92 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
123 | MACB_BF(RW, MACB_MAN_READ) 93 | MACB_BF(RW, MACB_MAN_READ)
124 | MACB_BF(PHYA, phy_id) 94 | MACB_BF(PHYA, mii_id)
125 | MACB_BF(REGA, location) 95 | MACB_BF(REGA, regnum)
126 | MACB_BF(CODE, MACB_MAN_CODE))); 96 | MACB_BF(CODE, MACB_MAN_CODE)));
127 97
128 wait_for_completion(&bp->mdio_complete); 98 /* wait for end of transfer */
99 while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
100 cpu_relax();
129 101
130 value = MACB_BFEXT(DATA, macb_readl(bp, MAN)); 102 value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
131 macb_disable_mdio(bp);
132 mutex_unlock(&bp->mdio_mutex);
133 103
134 return value; 104 return value;
135} 105}
136 106
137static void macb_mdio_write(struct net_device *dev, int phy_id, 107static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
138 int location, int val) 108 u16 value)
139{ 109{
140 struct macb *bp = netdev_priv(dev); 110 struct macb *bp = bus->priv;
141
142 dev_dbg(&bp->pdev->dev, "mdio_write %02x:%02x <- %04x\n",
143 phy_id, location, val);
144
145 mutex_lock(&bp->mdio_mutex);
146 macb_enable_mdio(bp);
147 111
148 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) 112 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
149 | MACB_BF(RW, MACB_MAN_WRITE) 113 | MACB_BF(RW, MACB_MAN_WRITE)
150 | MACB_BF(PHYA, phy_id) 114 | MACB_BF(PHYA, mii_id)
151 | MACB_BF(REGA, location) 115 | MACB_BF(REGA, regnum)
152 | MACB_BF(CODE, MACB_MAN_CODE) 116 | MACB_BF(CODE, MACB_MAN_CODE)
153 | MACB_BF(DATA, val))); 117 | MACB_BF(DATA, value)));
154 118
155 wait_for_completion(&bp->mdio_complete); 119 /* wait for end of transfer */
120 while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
121 cpu_relax();
122
123 return 0;
124}
156 125
157 macb_disable_mdio(bp); 126static int macb_mdio_reset(struct mii_bus *bus)
158 mutex_unlock(&bp->mdio_mutex); 127{
128 return 0;
159} 129}
160 130
161static int macb_phy_probe(struct macb *bp) 131static void macb_handle_link_change(struct net_device *dev)
162{ 132{
163 int phy_address; 133 struct macb *bp = netdev_priv(dev);
164 u16 phyid1, phyid2; 134 struct phy_device *phydev = bp->phy_dev;
135 unsigned long flags;
165 136
166 for (phy_address = 0; phy_address < 32; phy_address++) { 137 int status_change = 0;
167 phyid1 = macb_mdio_read(bp->dev, phy_address, MII_PHYSID1);
168 phyid2 = macb_mdio_read(bp->dev, phy_address, MII_PHYSID2);
169 138
170 if (phyid1 != 0xffff && phyid1 != 0x0000 139 spin_lock_irqsave(&bp->lock, flags);
171 && phyid2 != 0xffff && phyid2 != 0x0000) 140
172 break; 141 if (phydev->link) {
142 if ((bp->speed != phydev->speed) ||
143 (bp->duplex != phydev->duplex)) {
144 u32 reg;
145
146 reg = macb_readl(bp, NCFGR);
147 reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
148
149 if (phydev->duplex)
150 reg |= MACB_BIT(FD);
151 if (phydev->speed)
152 reg |= MACB_BIT(SPD);
153
154 macb_writel(bp, NCFGR, reg);
155
156 bp->speed = phydev->speed;
157 bp->duplex = phydev->duplex;
158 status_change = 1;
159 }
173 } 160 }
174 161
175 if (phy_address == 32) 162 if (phydev->link != bp->link) {
176 return -ENODEV; 163 if (phydev->link)
164 netif_schedule(dev);
165 else {
166 bp->speed = 0;
167 bp->duplex = -1;
168 }
169 bp->link = phydev->link;
177 170
178 dev_info(&bp->pdev->dev, 171 status_change = 1;
179 "detected PHY at address %d (ID %04x:%04x)\n", 172 }
180 phy_address, phyid1, phyid2);
181 173
182 bp->mii.phy_id = phy_address; 174 spin_unlock_irqrestore(&bp->lock, flags);
183 return 0; 175
176 if (status_change) {
177 if (phydev->link)
178 printk(KERN_INFO "%s: link up (%d/%s)\n",
179 dev->name, phydev->speed,
180 DUPLEX_FULL == phydev->duplex ? "Full":"Half");
181 else
182 printk(KERN_INFO "%s: link down\n", dev->name);
183 }
184} 184}
185 185
186static void macb_set_media(struct macb *bp, int media) 186/* based on au1000_eth. c*/
187static int macb_mii_probe(struct net_device *dev)
187{ 188{
188 u32 reg; 189 struct macb *bp = netdev_priv(dev);
190 struct phy_device *phydev = NULL;
191 struct eth_platform_data *pdata;
192 int phy_addr;
189 193
190 spin_lock_irq(&bp->lock); 194 /* find the first phy */
191 reg = macb_readl(bp, NCFGR); 195 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
192 reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); 196 if (bp->mii_bus.phy_map[phy_addr]) {
193 if (media & (ADVERTISE_100HALF | ADVERTISE_100FULL)) 197 phydev = bp->mii_bus.phy_map[phy_addr];
194 reg |= MACB_BIT(SPD); 198 break;
195 if (media & ADVERTISE_FULL) 199 }
196 reg |= MACB_BIT(FD); 200 }
197 macb_writel(bp, NCFGR, reg); 201
198 spin_unlock_irq(&bp->lock); 202 if (!phydev) {
203 printk (KERN_ERR "%s: no PHY found\n", dev->name);
204 return -1;
205 }
206
207 pdata = bp->pdev->dev.platform_data;
208 /* TODO : add pin_irq */
209
210 /* attach the mac to the phy */
211 if (pdata && pdata->is_rmii) {
212 phydev = phy_connect(dev, phydev->dev.bus_id,
213 &macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
214 } else {
215 phydev = phy_connect(dev, phydev->dev.bus_id,
216 &macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
217 }
218
219 if (IS_ERR(phydev)) {
220 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
221 return PTR_ERR(phydev);
222 }
223
224 /* mask with MAC supported features */
225 phydev->supported &= PHY_BASIC_FEATURES;
226
227 phydev->advertising = phydev->supported;
228
229 bp->link = 0;
230 bp->speed = 0;
231 bp->duplex = -1;
232 bp->phy_dev = phydev;
233
234 return 0;
199} 235}
200 236
201static void macb_check_media(struct macb *bp, int ok_to_print, int init_media) 237static int macb_mii_init(struct macb *bp)
202{ 238{
203 struct mii_if_info *mii = &bp->mii; 239 struct eth_platform_data *pdata;
204 unsigned int old_carrier, new_carrier; 240 int err = -ENXIO, i;
205 int advertise, lpa, media, duplex;
206 241
207 /* if forced media, go no further */ 242 /* Enable managment port */
208 if (mii->force_media) 243 macb_writel(bp, NCR, MACB_BIT(MPE));
209 return;
210 244
211 /* check current and old link status */ 245 bp->mii_bus.name = "MACB_mii_bus",
212 old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0; 246 bp->mii_bus.read = &macb_mdio_read,
213 new_carrier = (unsigned int) mii_link_ok(mii); 247 bp->mii_bus.write = &macb_mdio_write,
248 bp->mii_bus.reset = &macb_mdio_reset,
249 bp->mii_bus.id = bp->pdev->id,
250 bp->mii_bus.priv = bp,
251 bp->mii_bus.dev = &bp->dev->dev;
252 pdata = bp->pdev->dev.platform_data;
214 253
215 /* if carrier state did not change, assume nothing else did */ 254 if (pdata)
216 if (!init_media && old_carrier == new_carrier) 255 bp->mii_bus.phy_mask = pdata->phy_mask;
217 return;
218 256
219 /* no carrier, nothing much to do */ 257 bp->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
220 if (!new_carrier) { 258 if (!bp->mii_bus.irq) {
221 netif_carrier_off(mii->dev); 259 err = -ENOMEM;
222 printk(KERN_INFO "%s: link down\n", mii->dev->name); 260 goto err_out;
223 return;
224 } 261 }
225 262
226 /* 263 for (i = 0; i < PHY_MAX_ADDR; i++)
227 * we have carrier, see who's on the other end 264 bp->mii_bus.irq[i] = PHY_POLL;
228 */
229 netif_carrier_on(mii->dev);
230 265
231 /* get MII advertise and LPA values */ 266 platform_set_drvdata(bp->dev, &bp->mii_bus);
232 if (!init_media && mii->advertising) {
233 advertise = mii->advertising;
234 } else {
235 advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE);
236 mii->advertising = advertise;
237 }
238 lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
239 267
240 /* figure out media and duplex from advertise and LPA values */ 268 if (mdiobus_register(&bp->mii_bus))
241 media = mii_nway_result(lpa & advertise); 269 goto err_out_free_mdio_irq;
242 duplex = (media & ADVERTISE_FULL) ? 1 : 0;
243 270
244 if (ok_to_print) 271 if (macb_mii_probe(bp->dev) != 0) {
245 printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, lpa 0x%04X\n", 272 goto err_out_unregister_bus;
246 mii->dev->name, 273 }
247 media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? "100" : "10",
248 duplex ? "full" : "half", lpa);
249 274
250 mii->full_duplex = duplex; 275 return 0;
251 276
252 /* Let the MAC know about the new link state */ 277err_out_unregister_bus:
253 macb_set_media(bp, media); 278 mdiobus_unregister(&bp->mii_bus);
279err_out_free_mdio_irq:
280 kfree(bp->mii_bus.irq);
281err_out:
282 return err;
254} 283}
255 284
256static void macb_update_stats(struct macb *bp) 285static void macb_update_stats(struct macb *bp)
@@ -265,16 +294,6 @@ static void macb_update_stats(struct macb *bp)
265 *p += __raw_readl(reg); 294 *p += __raw_readl(reg);
266} 295}
267 296
268static void macb_periodic_task(struct work_struct *work)
269{
270 struct macb *bp = container_of(work, struct macb, periodic_task.work);
271
272 macb_update_stats(bp);
273 macb_check_media(bp, 1, 0);
274
275 schedule_delayed_work(&bp->periodic_task, HZ);
276}
277
278static void macb_tx(struct macb *bp) 297static void macb_tx(struct macb *bp)
279{ 298{
280 unsigned int tail; 299 unsigned int tail;
@@ -519,9 +538,6 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
519 spin_lock(&bp->lock); 538 spin_lock(&bp->lock);
520 539
521 while (status) { 540 while (status) {
522 if (status & MACB_BIT(MFD))
523 complete(&bp->mdio_complete);
524
525 /* close possible race with dev_close */ 541 /* close possible race with dev_close */
526 if (unlikely(!netif_running(dev))) { 542 if (unlikely(!netif_running(dev))) {
527 macb_writel(bp, IDR, ~0UL); 543 macb_writel(bp, IDR, ~0UL);
@@ -535,7 +551,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
535 * until we have processed the buffers 551 * until we have processed the buffers
536 */ 552 */
537 macb_writel(bp, IDR, MACB_RX_INT_FLAGS); 553 macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
538 dev_dbg(&bp->pdev->dev, "scheduling RX softirq\n"); 554 dev_dbg(&bp->pdev->dev,
555 "scheduling RX softirq\n");
539 __netif_rx_schedule(dev); 556 __netif_rx_schedule(dev);
540 } 557 }
541 } 558 }
@@ -765,7 +782,7 @@ static void macb_init_hw(struct macb *bp)
765 macb_writel(bp, TBQP, bp->tx_ring_dma); 782 macb_writel(bp, TBQP, bp->tx_ring_dma);
766 783
767 /* Enable TX and RX */ 784 /* Enable TX and RX */
768 macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE)); 785 macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
769 786
770 /* Enable interrupts */ 787 /* Enable interrupts */
771 macb_writel(bp, IER, (MACB_BIT(RCOMP) 788 macb_writel(bp, IER, (MACB_BIT(RCOMP)
@@ -776,18 +793,7 @@ static void macb_init_hw(struct macb *bp)
776 | MACB_BIT(TCOMP) 793 | MACB_BIT(TCOMP)
777 | MACB_BIT(ISR_ROVR) 794 | MACB_BIT(ISR_ROVR)
778 | MACB_BIT(HRESP))); 795 | MACB_BIT(HRESP)));
779}
780 796
781static void macb_init_phy(struct net_device *dev)
782{
783 struct macb *bp = netdev_priv(dev);
784
785 /* Set some reasonable default settings */
786 macb_mdio_write(dev, bp->mii.phy_id, MII_ADVERTISE,
787 ADVERTISE_CSMA | ADVERTISE_ALL);
788 macb_mdio_write(dev, bp->mii.phy_id, MII_BMCR,
789 (BMCR_SPEED100 | BMCR_ANENABLE
790 | BMCR_ANRESTART | BMCR_FULLDPLX));
791} 797}
792 798
793static int macb_open(struct net_device *dev) 799static int macb_open(struct net_device *dev)
@@ -797,6 +803,10 @@ static int macb_open(struct net_device *dev)
797 803
798 dev_dbg(&bp->pdev->dev, "open\n"); 804 dev_dbg(&bp->pdev->dev, "open\n");
799 805
806 /* if the phy is not yet register, retry later*/
807 if (!bp->phy_dev)
808 return -EAGAIN;
809
800 if (!is_valid_ether_addr(dev->dev_addr)) 810 if (!is_valid_ether_addr(dev->dev_addr))
801 return -EADDRNOTAVAIL; 811 return -EADDRNOTAVAIL;
802 812
@@ -810,12 +820,11 @@ static int macb_open(struct net_device *dev)
810 820
811 macb_init_rings(bp); 821 macb_init_rings(bp);
812 macb_init_hw(bp); 822 macb_init_hw(bp);
813 macb_init_phy(dev);
814 823
815 macb_check_media(bp, 1, 1); 824 /* schedule a link state check */
816 netif_start_queue(dev); 825 phy_start(bp->phy_dev);
817 826
818 schedule_delayed_work(&bp->periodic_task, HZ); 827 netif_start_queue(dev);
819 828
820 return 0; 829 return 0;
821} 830}
@@ -825,10 +834,11 @@ static int macb_close(struct net_device *dev)
825 struct macb *bp = netdev_priv(dev); 834 struct macb *bp = netdev_priv(dev);
826 unsigned long flags; 835 unsigned long flags;
827 836
828 cancel_rearming_delayed_work(&bp->periodic_task);
829
830 netif_stop_queue(dev); 837 netif_stop_queue(dev);
831 838
839 if (bp->phy_dev)
840 phy_stop(bp->phy_dev);
841
832 spin_lock_irqsave(&bp->lock, flags); 842 spin_lock_irqsave(&bp->lock, flags);
833 macb_reset_hw(bp); 843 macb_reset_hw(bp);
834 netif_carrier_off(dev); 844 netif_carrier_off(dev);
@@ -845,6 +855,9 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
845 struct net_device_stats *nstat = &bp->stats; 855 struct net_device_stats *nstat = &bp->stats;
846 struct macb_stats *hwstat = &bp->hw_stats; 856 struct macb_stats *hwstat = &bp->hw_stats;
847 857
858 /* read stats from hardware */
859 macb_update_stats(bp);
860
848 /* Convert HW stats into netdevice stats */ 861 /* Convert HW stats into netdevice stats */
849 nstat->rx_errors = (hwstat->rx_fcs_errors + 862 nstat->rx_errors = (hwstat->rx_fcs_errors +
850 hwstat->rx_align_errors + 863 hwstat->rx_align_errors +
@@ -882,18 +895,27 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
882static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 895static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
883{ 896{
884 struct macb *bp = netdev_priv(dev); 897 struct macb *bp = netdev_priv(dev);
898 struct phy_device *phydev = bp->phy_dev;
899
900 if (!phydev)
901 return -ENODEV;
885 902
886 return mii_ethtool_gset(&bp->mii, cmd); 903 return phy_ethtool_gset(phydev, cmd);
887} 904}
888 905
889static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 906static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
890{ 907{
891 struct macb *bp = netdev_priv(dev); 908 struct macb *bp = netdev_priv(dev);
909 struct phy_device *phydev = bp->phy_dev;
892 910
893 return mii_ethtool_sset(&bp->mii, cmd); 911 if (!phydev)
912 return -ENODEV;
913
914 return phy_ethtool_sset(phydev, cmd);
894} 915}
895 916
896static void macb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 917static void macb_get_drvinfo(struct net_device *dev,
918 struct ethtool_drvinfo *info)
897{ 919{
898 struct macb *bp = netdev_priv(dev); 920 struct macb *bp = netdev_priv(dev);
899 921
@@ -902,104 +924,34 @@ static void macb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *inf
902 strcpy(info->bus_info, bp->pdev->dev.bus_id); 924 strcpy(info->bus_info, bp->pdev->dev.bus_id);
903} 925}
904 926
905static int macb_nway_reset(struct net_device *dev)
906{
907 struct macb *bp = netdev_priv(dev);
908 return mii_nway_restart(&bp->mii);
909}
910
911static struct ethtool_ops macb_ethtool_ops = { 927static struct ethtool_ops macb_ethtool_ops = {
912 .get_settings = macb_get_settings, 928 .get_settings = macb_get_settings,
913 .set_settings = macb_set_settings, 929 .set_settings = macb_set_settings,
914 .get_drvinfo = macb_get_drvinfo, 930 .get_drvinfo = macb_get_drvinfo,
915 .nway_reset = macb_nway_reset,
916 .get_link = ethtool_op_get_link, 931 .get_link = ethtool_op_get_link,
917}; 932};
918 933
919static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 934static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
920{ 935{
921 struct macb *bp = netdev_priv(dev); 936 struct macb *bp = netdev_priv(dev);
937 struct phy_device *phydev = bp->phy_dev;
922 938
923 if (!netif_running(dev)) 939 if (!netif_running(dev))
924 return -EINVAL; 940 return -EINVAL;
925 941
926 return generic_mii_ioctl(&bp->mii, if_mii(rq), cmd, NULL); 942 if (!phydev)
927} 943 return -ENODEV;
928
929static ssize_t macb_mii_show(const struct device *_dev, char *buf,
930 unsigned long addr)
931{
932 struct net_device *dev = to_net_dev(_dev);
933 struct macb *bp = netdev_priv(dev);
934 ssize_t ret = -EINVAL;
935
936 if (netif_running(dev)) {
937 int value;
938 value = macb_mdio_read(dev, bp->mii.phy_id, addr);
939 ret = sprintf(buf, "0x%04x\n", (uint16_t)value);
940 }
941
942 return ret;
943}
944
945#define MII_ENTRY(name, addr) \
946static ssize_t show_##name(struct device *_dev, \
947 struct device_attribute *attr, \
948 char *buf) \
949{ \
950 return macb_mii_show(_dev, buf, addr); \
951} \
952static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
953
954MII_ENTRY(bmcr, MII_BMCR);
955MII_ENTRY(bmsr, MII_BMSR);
956MII_ENTRY(physid1, MII_PHYSID1);
957MII_ENTRY(physid2, MII_PHYSID2);
958MII_ENTRY(advertise, MII_ADVERTISE);
959MII_ENTRY(lpa, MII_LPA);
960MII_ENTRY(expansion, MII_EXPANSION);
961
962static struct attribute *macb_mii_attrs[] = {
963 &dev_attr_bmcr.attr,
964 &dev_attr_bmsr.attr,
965 &dev_attr_physid1.attr,
966 &dev_attr_physid2.attr,
967 &dev_attr_advertise.attr,
968 &dev_attr_lpa.attr,
969 &dev_attr_expansion.attr,
970 NULL,
971};
972
973static struct attribute_group macb_mii_group = {
974 .name = "mii",
975 .attrs = macb_mii_attrs,
976};
977
978static void macb_unregister_sysfs(struct net_device *net)
979{
980 struct device *_dev = &net->dev;
981 944
982 sysfs_remove_group(&_dev->kobj, &macb_mii_group); 945 return phy_mii_ioctl(phydev, if_mii(rq), cmd);
983} 946}
984 947
985static int macb_register_sysfs(struct net_device *net)
986{
987 struct device *_dev = &net->dev;
988 int ret;
989
990 ret = sysfs_create_group(&_dev->kobj, &macb_mii_group);
991 if (ret)
992 printk(KERN_WARNING
993 "%s: sysfs mii attribute registration failed: %d\n",
994 net->name, ret);
995 return ret;
996}
997static int __devinit macb_probe(struct platform_device *pdev) 948static int __devinit macb_probe(struct platform_device *pdev)
998{ 949{
999 struct eth_platform_data *pdata; 950 struct eth_platform_data *pdata;
1000 struct resource *regs; 951 struct resource *regs;
1001 struct net_device *dev; 952 struct net_device *dev;
1002 struct macb *bp; 953 struct macb *bp;
954 struct phy_device *phydev;
1003 unsigned long pclk_hz; 955 unsigned long pclk_hz;
1004 u32 config; 956 u32 config;
1005 int err = -ENXIO; 957 int err = -ENXIO;
@@ -1080,10 +1032,6 @@ static int __devinit macb_probe(struct platform_device *pdev)
1080 1032
1081 dev->base_addr = regs->start; 1033 dev->base_addr = regs->start;
1082 1034
1083 INIT_DELAYED_WORK(&bp->periodic_task, macb_periodic_task);
1084 mutex_init(&bp->mdio_mutex);
1085 init_completion(&bp->mdio_complete);
1086
1087 /* Set MII management clock divider */ 1035 /* Set MII management clock divider */
1088 pclk_hz = clk_get_rate(bp->pclk); 1036 pclk_hz = clk_get_rate(bp->pclk);
1089 if (pclk_hz <= 20000000) 1037 if (pclk_hz <= 20000000)
@@ -1096,20 +1044,9 @@ static int __devinit macb_probe(struct platform_device *pdev)
1096 config = MACB_BF(CLK, MACB_CLK_DIV64); 1044 config = MACB_BF(CLK, MACB_CLK_DIV64);
1097 macb_writel(bp, NCFGR, config); 1045 macb_writel(bp, NCFGR, config);
1098 1046
1099 bp->mii.dev = dev;
1100 bp->mii.mdio_read = macb_mdio_read;
1101 bp->mii.mdio_write = macb_mdio_write;
1102 bp->mii.phy_id_mask = 0x1f;
1103 bp->mii.reg_num_mask = 0x1f;
1104
1105 macb_get_hwaddr(bp); 1047 macb_get_hwaddr(bp);
1106 err = macb_phy_probe(bp);
1107 if (err) {
1108 dev_err(&pdev->dev, "Failed to detect PHY, aborting.\n");
1109 goto err_out_free_irq;
1110 }
1111
1112 pdata = pdev->dev.platform_data; 1048 pdata = pdev->dev.platform_data;
1049
1113 if (pdata && pdata->is_rmii) 1050 if (pdata && pdata->is_rmii)
1114#if defined(CONFIG_ARCH_AT91) 1051#if defined(CONFIG_ARCH_AT91)
1115 macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) ); 1052 macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) );
@@ -1131,9 +1068,11 @@ static int __devinit macb_probe(struct platform_device *pdev)
1131 goto err_out_free_irq; 1068 goto err_out_free_irq;
1132 } 1069 }
1133 1070
1134 platform_set_drvdata(pdev, dev); 1071 if (macb_mii_init(bp) != 0) {
1072 goto err_out_unregister_netdev;
1073 }
1135 1074
1136 macb_register_sysfs(dev); 1075 platform_set_drvdata(pdev, dev);
1137 1076
1138 printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d " 1077 printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d "
1139 "(%02x:%02x:%02x:%02x:%02x:%02x)\n", 1078 "(%02x:%02x:%02x:%02x:%02x:%02x)\n",
@@ -1141,8 +1080,15 @@ static int __devinit macb_probe(struct platform_device *pdev)
1141 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], 1080 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
1142 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); 1081 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
1143 1082
1083 phydev = bp->phy_dev;
1084 printk(KERN_INFO "%s: attached PHY driver [%s] "
1085 "(mii_bus:phy_addr=%s, irq=%d)\n",
1086 dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
1087
1144 return 0; 1088 return 0;
1145 1089
1090err_out_unregister_netdev:
1091 unregister_netdev(dev);
1146err_out_free_irq: 1092err_out_free_irq:
1147 free_irq(dev->irq, dev); 1093 free_irq(dev->irq, dev);
1148err_out_iounmap: 1094err_out_iounmap:
@@ -1153,7 +1099,9 @@ err_out_disable_clocks:
1153 clk_put(bp->hclk); 1099 clk_put(bp->hclk);
1154#endif 1100#endif
1155 clk_disable(bp->pclk); 1101 clk_disable(bp->pclk);
1102#ifndef CONFIG_ARCH_AT91
1156err_out_put_pclk: 1103err_out_put_pclk:
1104#endif
1157 clk_put(bp->pclk); 1105 clk_put(bp->pclk);
1158err_out_free_dev: 1106err_out_free_dev:
1159 free_netdev(dev); 1107 free_netdev(dev);
@@ -1171,7 +1119,8 @@ static int __devexit macb_remove(struct platform_device *pdev)
1171 1119
1172 if (dev) { 1120 if (dev) {
1173 bp = netdev_priv(dev); 1121 bp = netdev_priv(dev);
1174 macb_unregister_sysfs(dev); 1122 mdiobus_unregister(&bp->mii_bus);
1123 kfree(bp->mii_bus.irq);
1175 unregister_netdev(dev); 1124 unregister_netdev(dev);
1176 free_irq(dev->irq, dev); 1125 free_irq(dev->irq, dev);
1177 iounmap(bp->regs); 1126 iounmap(bp->regs);
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index b3bb2182edd1..4e3283ebd97c 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -383,11 +383,11 @@ struct macb {
383 383
384 unsigned int rx_pending, tx_pending; 384 unsigned int rx_pending, tx_pending;
385 385
386 struct delayed_work periodic_task; 386 struct mii_bus mii_bus;
387 387 struct phy_device *phy_dev;
388 struct mutex mdio_mutex; 388 unsigned int link;
389 struct completion mdio_complete; 389 unsigned int speed;
390 struct mii_if_info mii; 390 unsigned int duplex;
391}; 391};
392 392
393#endif /* _MACB_H */ 393#endif /* _MACB_H */
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h
index 0ce6ee98ed0b..d96b10fd449f 100644
--- a/include/asm-arm/arch-at91/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -64,6 +64,7 @@ extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
64 64
65 /* Ethernet (EMAC & MACB) */ 65 /* Ethernet (EMAC & MACB) */
66struct at91_eth_data { 66struct at91_eth_data {
67 u32 phy_mask;
67 u8 phy_irq_pin; /* PHY IRQ */ 68 u8 phy_irq_pin; /* PHY IRQ */
68 u8 is_rmii; /* using RMII interface? */ 69 u8 is_rmii; /* using RMII interface? */
69}; 70};
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h
index 9fd2e32f84b8..974480438849 100644
--- a/include/asm-avr32/arch-at32ap/board.h
+++ b/include/asm-avr32/arch-at32ap/board.h
@@ -21,6 +21,7 @@ void at32_map_usart(unsigned int hw_id, unsigned int line);
21struct platform_device *at32_add_device_usart(unsigned int id); 21struct platform_device *at32_add_device_usart(unsigned int id);
22 22
23struct eth_platform_data { 23struct eth_platform_data {
24 u32 phy_mask;
24 u8 is_rmii; 25 u8 is_rmii;
25}; 26};
26struct platform_device * 27struct platform_device *