ixgb: Increment version to 1.0.109-k4
[pandora-kernel.git] / drivers / net / fs_enet / fs_enet-mii.c
1 /*
2  * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
3  *
4  * Copyright (c) 2003 Intracom S.A. 
5  *  by Pantelis Antoniou <panto@intracom.gr>
6  * 
7  * 2005 (c) MontaVista Software, Inc. 
8  * Vitaly Bordug <vbordug@ru.mvista.com>
9  *
10  * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
11  * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
12  *
13  * This file is licensed under the terms of the GNU General Public License 
14  * version 2. This program is licensed "as is" without any warranty of any 
15  * kind, whether express or implied.
16  */
17
18
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/string.h>
24 #include <linux/ptrace.h>
25 #include <linux/errno.h>
26 #include <linux/ioport.h>
27 #include <linux/slab.h>
28 #include <linux/interrupt.h>
29 #include <linux/pci.h>
30 #include <linux/init.h>
31 #include <linux/delay.h>
32 #include <linux/netdevice.h>
33 #include <linux/etherdevice.h>
34 #include <linux/skbuff.h>
35 #include <linux/spinlock.h>
36 #include <linux/mii.h>
37 #include <linux/ethtool.h>
38 #include <linux/bitops.h>
39
40 #include <asm/pgtable.h>
41 #include <asm/irq.h>
42 #include <asm/uaccess.h>
43
44 #include "fs_enet.h"
45
46 /*************************************************/
47
48 /*
49  * Generic PHY support.
50  * Should work for all PHYs, but link change is detected by polling
51  */
52
53 static void generic_timer_callback(unsigned long data)
54 {
55         struct net_device *dev = (struct net_device *)data;
56         struct fs_enet_private *fep = netdev_priv(dev);
57
58         fep->phy_timer_list.expires = jiffies + HZ / 2;
59
60         add_timer(&fep->phy_timer_list);
61
62         fs_mii_link_status_change_check(dev, 0);
63 }
64
65 static void generic_startup(struct net_device *dev)
66 {
67         struct fs_enet_private *fep = netdev_priv(dev);
68
69         fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */
70         fep->phy_timer_list.data = (unsigned long)dev;
71         fep->phy_timer_list.function = generic_timer_callback;
72         add_timer(&fep->phy_timer_list);
73 }
74
75 static void generic_shutdown(struct net_device *dev)
76 {
77         struct fs_enet_private *fep = netdev_priv(dev);
78
79         del_timer_sync(&fep->phy_timer_list);
80 }
81
82 /* ------------------------------------------------------------------------- */
83 /* The Davicom DM9161 is used on the NETTA board                             */
84
85 /* register definitions */
86
87 #define MII_DM9161_ANAR         4       /* Aux. Config Register         */
88 #define MII_DM9161_ACR          16      /* Aux. Config Register         */
89 #define MII_DM9161_ACSR         17      /* Aux. Config/Status Register  */
90 #define MII_DM9161_10TCSR       18      /* 10BaseT Config/Status Reg.   */
91 #define MII_DM9161_INTR         21      /* Interrupt Register           */
92 #define MII_DM9161_RECR         22      /* Receive Error Counter Reg.   */
93 #define MII_DM9161_DISCR        23      /* Disconnect Counter Register  */
94
95 static void dm9161_startup(struct net_device *dev)
96 {
97         struct fs_enet_private *fep = netdev_priv(dev);
98
99         fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000);
100         /* Start autonegotiation */
101         fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200);
102
103         set_current_state(TASK_UNINTERRUPTIBLE);
104         schedule_timeout(HZ*8);
105 }
106
107 static void dm9161_ack_int(struct net_device *dev)
108 {
109         struct fs_enet_private *fep = netdev_priv(dev);
110
111         fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR);
112 }
113
114 static void dm9161_shutdown(struct net_device *dev)
115 {
116         struct fs_enet_private *fep = netdev_priv(dev);
117
118         fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00);
119 }
120
121 /**********************************************************************************/
122
123 static const struct phy_info phy_info[] = {
124         {
125                 .id = 0x00181b88,
126                 .name = "DM9161",
127                 .startup = dm9161_startup,
128                 .ack_int = dm9161_ack_int,
129                 .shutdown = dm9161_shutdown,
130         }, {
131                 .id = 0,
132                 .name = "GENERIC",
133                 .startup = generic_startup,
134                 .shutdown = generic_shutdown,
135         },
136 };
137
138 /**********************************************************************************/
139
140 static int phy_id_detect(struct net_device *dev)
141 {
142         struct fs_enet_private *fep = netdev_priv(dev);
143         const struct fs_platform_info *fpi = fep->fpi;
144         struct fs_enet_mii_bus *bus = fep->mii_bus;
145         int i, r, start, end, phytype, physubtype;
146         const struct phy_info *phy;
147         int phy_hwid, phy_id;
148
149         phy_hwid = -1;
150         fep->phy = NULL;
151
152         /* auto-detect? */
153         if (fpi->phy_addr == -1) {
154                 start = 1;
155                 end = 32;
156         } else {                /* direct */
157                 start = fpi->phy_addr;
158                 end = start + 1;
159         }
160
161         for (phy_id = start; phy_id < end; phy_id++) {
162                 /* skip already used phy addresses on this bus */ 
163                 if (bus->usage_map & (1 << phy_id))
164                         continue;
165                 r = fs_mii_read(dev, phy_id, MII_PHYSID1);
166                 if (r == -1 || (phytype = (r & 0xffff)) == 0xffff)
167                         continue;
168                 r = fs_mii_read(dev, phy_id, MII_PHYSID2);
169                 if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff)
170                         continue;
171                 phy_hwid = (phytype << 16) | physubtype;
172                 if (phy_hwid != -1)
173                         break;
174         }
175
176         if (phy_hwid == -1) {
177                 printk(KERN_ERR DRV_MODULE_NAME
178                        ": %s No PHY detected! range=0x%02x-0x%02x\n",
179                         dev->name, start, end);
180                 return -1;
181         }
182
183         for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++)
184                 if (phy->id == (phy_hwid >> 4) || phy->id == 0)
185                         break;
186
187         if (i >= ARRAY_SIZE(phy_info)) {
188                 printk(KERN_ERR DRV_MODULE_NAME
189                        ": %s PHY id 0x%08x is not supported!\n",
190                        dev->name, phy_hwid);
191                 return -1;
192         }
193
194         fep->phy = phy;
195
196         /* mark this address as used */
197         bus->usage_map |= (1 << phy_id);
198
199         printk(KERN_INFO DRV_MODULE_NAME
200                ": %s Phy @ 0x%x, type %s (0x%08x)%s\n",
201                dev->name, phy_id, fep->phy->name, phy_hwid,
202                fpi->phy_addr == -1 ? " (auto-detected)" : "");
203
204         return phy_id;
205 }
206
207 void fs_mii_startup(struct net_device *dev)
208 {
209         struct fs_enet_private *fep = netdev_priv(dev);
210
211         if (fep->phy->startup)
212                 (*fep->phy->startup) (dev);
213 }
214
215 void fs_mii_shutdown(struct net_device *dev)
216 {
217         struct fs_enet_private *fep = netdev_priv(dev);
218
219         if (fep->phy->shutdown)
220                 (*fep->phy->shutdown) (dev);
221 }
222
223 void fs_mii_ack_int(struct net_device *dev)
224 {
225         struct fs_enet_private *fep = netdev_priv(dev);
226
227         if (fep->phy->ack_int)
228                 (*fep->phy->ack_int) (dev);
229 }
230
231 #define MII_LINK        0x0001
232 #define MII_HALF        0x0002
233 #define MII_FULL        0x0004
234 #define MII_BASE4       0x0008
235 #define MII_10M         0x0010
236 #define MII_100M        0x0020
237 #define MII_1G          0x0040
238 #define MII_10G         0x0080
239
240 /* return full mii info at one gulp, with a usable form */
241 static unsigned int mii_full_status(struct mii_if_info *mii)
242 {
243         unsigned int status;
244         int bmsr, adv, lpa, neg;
245         struct fs_enet_private* fep = netdev_priv(mii->dev);
246         
247         /* first, a dummy read, needed to latch some MII phys */
248         (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
249         bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
250
251         /* no link */
252         if ((bmsr & BMSR_LSTATUS) == 0)
253                 return 0;
254
255         status = MII_LINK;
256         
257         /* Lets look what ANEG says if it's supported - otherwize we shall
258            take the right values from the platform info*/
259         if(!mii->force_media) {
260                 /* autoneg not completed; don't bother */
261                 if ((bmsr & BMSR_ANEGCOMPLETE) == 0)
262                         return 0;
263
264                 adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE);
265                 lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA);
266
267                 neg = lpa & adv;
268         } else {
269                 neg = fep->fpi->bus_info->lpa;
270         }
271
272         if (neg & LPA_100FULL)
273                 status |= MII_FULL | MII_100M;
274         else if (neg & LPA_100BASE4)
275                 status |= MII_FULL | MII_BASE4 | MII_100M;
276         else if (neg & LPA_100HALF)
277                 status |= MII_HALF | MII_100M;
278         else if (neg & LPA_10FULL)
279                 status |= MII_FULL | MII_10M;
280         else
281                 status |= MII_HALF | MII_10M;
282         
283         return status;
284 }
285
286 void fs_mii_link_status_change_check(struct net_device *dev, int init_media)
287 {
288         struct fs_enet_private *fep = netdev_priv(dev);
289         struct mii_if_info *mii = &fep->mii_if;
290         unsigned int mii_status;
291         int ok_to_print, link, duplex, speed;
292         unsigned long flags;
293
294         ok_to_print = netif_msg_link(fep);
295
296         mii_status = mii_full_status(mii);
297
298         if (!init_media && mii_status == fep->last_mii_status)
299                 return;
300
301         fep->last_mii_status = mii_status;
302
303         link = !!(mii_status & MII_LINK);
304         duplex = !!(mii_status & MII_FULL);
305         speed = (mii_status & MII_100M) ? 100 : 10;
306
307         if (link == 0) {
308                 netif_carrier_off(mii->dev);
309                 netif_stop_queue(dev);
310                 if (!init_media) {
311                         spin_lock_irqsave(&fep->lock, flags);
312                         (*fep->ops->stop)(dev);
313                         spin_unlock_irqrestore(&fep->lock, flags);
314                 }
315
316                 if (ok_to_print)
317                         printk(KERN_INFO "%s: link down\n", mii->dev->name);
318
319         } else {
320
321                 mii->full_duplex = duplex;
322
323                 netif_carrier_on(mii->dev);
324
325                 spin_lock_irqsave(&fep->lock, flags);
326                 fep->duplex = duplex;
327                 fep->speed = speed;
328                 (*fep->ops->restart)(dev);
329                 spin_unlock_irqrestore(&fep->lock, flags);
330
331                 netif_start_queue(dev);
332
333                 if (ok_to_print)
334                         printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n",
335                                dev->name, speed, duplex ? "full" : "half");
336         }
337 }
338
339 /**********************************************************************************/
340
341 int fs_mii_read(struct net_device *dev, int phy_id, int location)
342 {
343         struct fs_enet_private *fep = netdev_priv(dev);
344         struct fs_enet_mii_bus *bus = fep->mii_bus;
345
346         unsigned long flags;
347         int ret;
348
349         spin_lock_irqsave(&bus->mii_lock, flags);
350         ret = (*bus->mii_read)(bus, phy_id, location);
351         spin_unlock_irqrestore(&bus->mii_lock, flags);
352
353         return ret;
354 }
355
356 void fs_mii_write(struct net_device *dev, int phy_id, int location, int value)
357 {
358         struct fs_enet_private *fep = netdev_priv(dev);
359         struct fs_enet_mii_bus *bus = fep->mii_bus;
360         unsigned long flags;
361
362         spin_lock_irqsave(&bus->mii_lock, flags);
363         (*bus->mii_write)(bus, phy_id, location, value);
364         spin_unlock_irqrestore(&bus->mii_lock, flags);
365 }
366
367 /*****************************************************************************/
368
369 /* list of all registered mii buses */
370 static LIST_HEAD(fs_mii_bus_list);
371
372 static struct fs_enet_mii_bus *lookup_bus(int method, int id)
373 {
374         struct list_head *ptr;
375         struct fs_enet_mii_bus *bus;
376
377         list_for_each(ptr, &fs_mii_bus_list) {
378                 bus = list_entry(ptr, struct fs_enet_mii_bus, list);
379                 if (bus->bus_info->method == method &&
380                         bus->bus_info->id == id)
381                         return bus;
382         }
383         return NULL;
384 }
385
386 static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi)
387 {
388         struct fs_enet_mii_bus *bus;
389         int ret = 0;
390
391         bus = kmalloc(sizeof(*bus), GFP_KERNEL);
392         if (bus == NULL) {
393                 ret = -ENOMEM;
394                 goto err;
395         }
396         memset(bus, 0, sizeof(*bus));
397         spin_lock_init(&bus->mii_lock);
398         bus->bus_info = bi;
399         bus->refs = 0;
400         bus->usage_map = 0;
401
402         /* perform initialization */
403         switch (bi->method) {
404
405                 case fsmii_fixed:
406                         ret = fs_mii_fixed_init(bus);
407                         if (ret != 0)
408                                 goto err;
409                         break;
410
411                 case fsmii_bitbang:
412                         ret = fs_mii_bitbang_init(bus);
413                         if (ret != 0)
414                                 goto err;
415                         break;
416 #ifdef CONFIG_FS_ENET_HAS_FEC
417                 case fsmii_fec:
418                         ret = fs_mii_fec_init(bus);
419                         if (ret != 0)
420                                 goto err;
421                         break;
422 #endif
423                 default:
424                         ret = -EINVAL;
425                         goto err;
426         }
427
428         list_add(&bus->list, &fs_mii_bus_list);
429
430         return bus;
431
432 err:
433         kfree(bus);
434         return ERR_PTR(ret);
435 }
436
437 static void destroy_bus(struct fs_enet_mii_bus *bus)
438 {
439         /* remove from bus list */
440         list_del(&bus->list);
441
442         /* nothing more needed */
443         kfree(bus);
444 }
445
446 int fs_mii_connect(struct net_device *dev)
447 {
448         struct fs_enet_private *fep = netdev_priv(dev);
449         const struct fs_platform_info *fpi = fep->fpi;
450         struct fs_enet_mii_bus *bus = NULL;
451
452         /* check method validity */
453         switch (fpi->bus_info->method) {
454                 case fsmii_fixed:
455                 case fsmii_bitbang:
456                         break;
457 #ifdef CONFIG_FS_ENET_HAS_FEC
458                 case fsmii_fec:
459                         break;
460 #endif
461                 default:
462                         printk(KERN_ERR DRV_MODULE_NAME
463                                ": %s Unknown MII bus method (%d)!\n",
464                                dev->name, fpi->bus_info->method);
465                         return -EINVAL; 
466         }
467
468         bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id);
469
470         /* if not found create new bus */
471         if (bus == NULL) {
472                 bus = create_bus(fpi->bus_info);
473                 if (IS_ERR(bus)) {
474                         printk(KERN_ERR DRV_MODULE_NAME
475                                ": %s MII bus creation failure!\n", dev->name);
476                         return PTR_ERR(bus);
477                 }
478         }
479
480         bus->refs++;
481
482         fep->mii_bus = bus;
483
484         fep->mii_if.dev = dev;
485         fep->mii_if.phy_id_mask = 0x1f;
486         fep->mii_if.reg_num_mask = 0x1f;
487         fep->mii_if.mdio_read = fs_mii_read;
488         fep->mii_if.mdio_write = fs_mii_write;
489         fep->mii_if.force_media = fpi->bus_info->disable_aneg;
490         fep->mii_if.phy_id = phy_id_detect(dev);
491
492         return 0;
493 }
494
495 void fs_mii_disconnect(struct net_device *dev)
496 {
497         struct fs_enet_private *fep = netdev_priv(dev);
498         struct fs_enet_mii_bus *bus = NULL;
499
500         bus = fep->mii_bus;
501         fep->mii_bus = NULL;
502
503         if (--bus->refs <= 0)
504                 destroy_bus(bus);
505 }