[coldfire]: switch to 2.6.38
[openwrt.git] / target / linux / coldfire / patches / 006-Add-FEC-driver-support-for-MCF5445x-MCF5441x-MCF547x.patch
1 From 9be336132025e7670790cdc9c24a81c23e893484 Mon Sep 17 00:00:00 2001
2 From: Alison Wang <b18965@freescale.com>
3 Date: Thu, 4 Aug 2011 09:59:40 +0800
4 Subject: [PATCH 06/52] Add FEC driver support for MCF5445x/MCF5441x/MCF547x/MCF548x
5
6 Add FEC driver support for MCF5445x/MCF5441x/MCF547x/MCF548x.
7
8 Signed-off-by: Alison Wang <b18965@freescale.com>
9 ---
10  arch/m68k/coldfire/m5441x/fec.c |  172 +++++
11  arch/m68k/coldfire/m5445x/fec.c |  143 ++++
12  drivers/net/Kconfig             |   33 +-
13  drivers/net/Makefile            |    1 +
14  drivers/net/fec.c               |   27 +-
15  drivers/net/fec.h               |    7 +-
16  drivers/net/fec_m547x.c         | 1551 +++++++++++++++++++++++++++++++++++++++
17  drivers/net/fec_m547x.h         |  241 ++++++
18  drivers/net/phy/Kconfig         |   15 +
19  drivers/net/phy/Makefile        |    3 +
20  drivers/net/phy/broadcom522x.c  |  170 +++++
21  drivers/net/phy/national836x.c  |  104 +++
22  drivers/net/phy/national8384x.c |  110 +++
23  13 files changed, 2566 insertions(+), 11 deletions(-)
24  create mode 100644 arch/m68k/coldfire/m5441x/fec.c
25  create mode 100644 arch/m68k/coldfire/m5445x/fec.c
26  create mode 100644 drivers/net/fec_m547x.c
27  create mode 100644 drivers/net/fec_m547x.h
28  create mode 100644 drivers/net/phy/broadcom522x.c
29  create mode 100644 drivers/net/phy/national836x.c
30  create mode 100644 drivers/net/phy/national8384x.c
31
32 --- /dev/null
33 +++ b/arch/m68k/coldfire/m5441x/fec.c
34 @@ -0,0 +1,172 @@
35 +/*
36 + * fec.c on m5441x platform
37 + *
38 + * Sub-architcture dependant initialization code for the Freescale
39 + * 5441X FEC module.
40 + *
41 + * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
42 + * ShrekWu B16972@freescale.com
43 + * Alison Wang b18965@freescale.com
44 + *
45 + *
46 + * This program is free software; you can redistribute  it and/or modify it
47 + * under  the terms of  the GNU General  Public License as published by the
48 + * Free Software Foundation;  either version 2 of the  License, or (at your
49 + * option) any later version.
50 + *
51 + * This program is distributed in the hope that it will be useful,
52 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
53 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54 + * GNU General Public License for more details.
55 + *
56 + * You should have received a copy of the GNU General Public License
57 + * along with this program; if not, write to the Free Software
58 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
59 + */
60 +#include <linux/kernel.h>
61 +#include <linux/sched.h>
62 +#include <linux/param.h>
63 +#include <linux/init.h>
64 +#include <linux/interrupt.h>
65 +#include <linux/device.h>
66 +#include <linux/netdevice.h>
67 +#include <linux/etherdevice.h>
68 +#include <linux/skbuff.h>
69 +#include <linux/spinlock.h>
70 +#include <linux/workqueue.h>
71 +#include <linux/platform_device.h>
72 +#include <linux/fec.h>
73 +#include <linux/io.h>
74 +
75 +#include <asm/pgtable.h>
76 +#include <asm/traps.h>
77 +#include <asm/machdep.h>
78 +#include <asm/coldfire.h>
79 +#include <asm/mcfsim.h>
80 +#include <asm/mcf5441x_dtim.h>
81 +
82 +static struct resource fec0_resources[] = {
83 +       [0] = {
84 +               .start  = MCF_MBAR + 0xfc0d4000,
85 +               .end    = MCF_MBAR + 0xfc0d42ff,
86 +               .flags  = IORESOURCE_MEM,
87 +       },
88 +       [1] = {
89 +               .start  = (64 + 36),
90 +               .end    = (64 + 36),
91 +               .flags  = IORESOURCE_IRQ,
92 +       },
93 +       [2] = {
94 +               .start  = (64 + 40),
95 +               .end    = (64 + 40),
96 +               .flags  = IORESOURCE_IRQ,
97 +       },
98 +       [3] = {
99 +               .start  = (64 + 42),
100 +               .end    = (64 + 42),
101 +               .flags  = IORESOURCE_IRQ,
102 +       },
103 +};
104 +
105 +#if defined(CONFIG_FEC2)
106 +static struct resource fec1_resources[] = {
107 +       [0] = {
108 +               .start  = MCF_MBAR + 0xfc0d8000,
109 +               .end    = MCF_MBAR + 0xfc0d82ff,
110 +               .flags  = IORESOURCE_MEM,
111 +       },
112 +       [1] = {
113 +               .start  = (64 + 13 + 36),
114 +               .end    = (64 + 13 + 36),
115 +               .flags  = IORESOURCE_IRQ,
116 +       },
117 +       [2] = {
118 +               .start  = (64 + 13 + 40),
119 +               .end    = (64 + 13 + 40),
120 +               .flags  = IORESOURCE_IRQ,
121 +       },
122 +       [3] = {
123 +               .start  = (64 + 13 + 42),
124 +               .end    = (64 + 13 + 42),
125 +               .flags  = IORESOURCE_IRQ,
126 +       },
127 +};
128 +#endif
129 +
130 +static struct fec_platform_data m54418_fec_pdata = {
131 +       .phy = PHY_INTERFACE_MODE_RMII,
132 +};
133 +
134 +static struct platform_device fec0_coldfire_device = {
135 +       .name = "m54418-fec",
136 +       .id = 0,
137 +       .resource = fec0_resources,
138 +       .num_resources = ARRAY_SIZE(fec0_resources),
139 +       .dev = {
140 +               .platform_data = &m54418_fec_pdata,
141 +       }
142 +};
143 +
144 +#if defined(CONFIG_FEC2)
145 +static struct platform_device fec1_coldfire_device = {
146 +       .name = "m54418-fec",
147 +       .id = 1,
148 +       .resource = fec1_resources,
149 +       .num_resources = ARRAY_SIZE(fec1_resources),
150 +       .dev = {
151 +               .platform_data = &m54418_fec_pdata,
152 +       }
153 +};
154 +#endif
155 +
156 +static struct platform_device *fec_device[] = {
157 +       &fec0_coldfire_device,
158 +#if defined(CONFIG_FEC2)
159 +       &fec1_coldfire_device,
160 +#endif
161 +};
162 +
163 +static int __init mcf5441x_fec_dev_init(void)
164 +{
165 +       int retval = 0;
166 +
167 +       MCF_GPIO_PAR_FEC =
168 +               (MCF_GPIO_PAR_FEC &
169 +               MCF_GPIO_PAR_FEC_FEC_MASK) |
170 +               MCF_GPIO_PAR_FEC_FEC_RMII0FUL_ULPI;
171 +
172 +       MCF_GPIO_SRCR_FEC = 0x0C;
173 +
174 +#if defined(CONFIG_FEC2)
175 +       MCF_GPIO_PAR_FEC =
176 +               (MCF_GPIO_PAR_FEC &
177 +               MCF_GPIO_PAR_FEC_FEC_MASK) |
178 +               MCF_GPIO_PAR_FEC_FEC_RMII0FUL_1FUL;
179 +
180 +       MCF_GPIO_SRCR_FEC |= 0x03;
181 +
182 +       MCF_GPIO_PAR_SIMP0H =
183 +               (MCF_GPIO_PAR_SIMP0H &
184 +               MCF_GPIO_PAR_SIMP0H_DAT_MASK) |
185 +               MCF_GPIO_PAR_SIMP0H_DAT_GPIO;
186 +
187 +       MCF_GPIO_PDDR_G =
188 +               (MCF_GPIO_PDDR_G &
189 +               MCF_GPIO_PDDR_G4_MASK) |
190 +               MCF_GPIO_PDDR_G4_OUTPUT;
191 +
192 +       MCF_GPIO_PODR_G =
193 +               (MCF_GPIO_PODR_G &
194 +               MCF_GPIO_PODR_G4_MASK);
195 +#endif
196 +
197 +       retval = platform_add_devices(fec_device, ARRAY_SIZE(fec_device));
198 +       if (retval < 0) {
199 +               printk(KERN_ERR "MCF5441x FEC: platform_device_register failed"
200 +                               "with code=%d\n", retval);
201 +       }
202 +
203 +       return retval;
204 +}
205 +
206 +arch_initcall(mcf5441x_fec_dev_init);
207 --- /dev/null
208 +++ b/arch/m68k/coldfire/m5445x/fec.c
209 @@ -0,0 +1,143 @@
210 +/*
211 + * fec-mcf5445x.c
212 + *
213 + * Sub-architcture dependant initialization code for the Freescale
214 + * 5445X FEC module.
215 + *
216 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
217 + * Shrek Wu B16972@freescale.com
218 + *
219 + * This program is free software; you can redistribute  it and/or modify it
220 + * under  the terms of  the GNU General  Public License as published by the
221 + * Free Software Foundation;  either version 2 of the  License, or (at your
222 + * option) any later version.
223 + *
224 + * This program is distributed in the hope that it will be useful,
225 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
226 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
227 + * GNU General Public License for more details.
228 + *
229 + * You should have received a copy of the GNU General Public License
230 + * along with this program; if not, write to the Free Software
231 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
232 + */
233 +#include <linux/kernel.h>
234 +#include <linux/sched.h>
235 +#include <linux/param.h>
236 +#include <linux/init.h>
237 +#include <linux/interrupt.h>
238 +#include <linux/device.h>
239 +#include <linux/platform_device.h>
240 +#include <linux/fsl_devices.h>
241 +#include <linux/netdevice.h>
242 +#include <linux/etherdevice.h>
243 +#include <linux/skbuff.h>
244 +#include <linux/spinlock.h>
245 +#include <linux/workqueue.h>
246 +#include <asm/pgtable.h>
247 +
248 +#include <asm/traps.h>
249 +#include <asm/machdep.h>
250 +#include <asm/coldfire.h>
251 +#include <asm/mcfsim.h>
252 +
253 +static struct resource fec0_resources[] = {
254 +       [0] = {
255 +               .start  = MCF_MBAR + 0xfc030000,
256 +               .end    = MCF_MBAR + 0xfc0302ff,
257 +               .flags  = IORESOURCE_MEM,
258 +       },
259 +       [1] = {
260 +               .start  = (64 + 36),
261 +               .end    = (64 + 36),
262 +               .flags  = IORESOURCE_IRQ,
263 +       },
264 +       [2] = {
265 +               .start  = (64 + 40),
266 +               .end    = (64 + 40),
267 +               .flags  = IORESOURCE_IRQ,
268 +       },
269 +       [3] = {
270 +               .start  = (64 + 42),
271 +               .end    = (64 + 42),
272 +               .flags  = IORESOURCE_IRQ,
273 +       },
274 +};
275 +
276 +#if defined(CONFIG_FEC2)
277 +static struct resource fec1_resources[] = {
278 +       [0] = {
279 +               .start  = MCF_MBAR + 0xfc034000,
280 +               .end    = MCF_MBAR + 0xfc0342ff,
281 +               .flags  = IORESOURCE_MEM,
282 +       },
283 +       [1] = {
284 +               .start  = (64 + 13 + 36),
285 +               .end    = (64 + 13 + 36),
286 +               .flags  = IORESOURCE_IRQ,
287 +       },
288 +       [2] = {
289 +               .start  = (64 + 13 + 40),
290 +               .end    = (64 + 13 + 40),
291 +               .flags  = IORESOURCE_IRQ,
292 +       },
293 +       [3] = {
294 +               .start  = (64 + 13 + 42),
295 +               .end    = (64 + 13 + 42),
296 +               .flags  = IORESOURCE_IRQ,
297 +       },
298 +};
299 +#endif
300 +
301 +static struct platform_device fec0_coldfire_device = {
302 +       .name = "fec",
303 +       .id = 0,
304 +       .resource = fec0_resources,
305 +       .num_resources = ARRAY_SIZE(fec0_resources),
306 +};
307 +
308 +#if defined(CONFIG_FEC2)
309 +static struct platform_device fec1_coldfire_device = {
310 +       .name = "fec",
311 +       .id = 1,
312 +       .resource = fec1_resources,
313 +       .num_resources = ARRAY_SIZE(fec1_resources),
314 +};
315 +#endif
316 +
317 +static struct platform_device *fec_device[] = {
318 +       &fec0_coldfire_device,
319 +#if defined(CONFIG_FEC2)
320 +       &fec1_coldfire_device,
321 +#endif
322 +};
323 +
324 +static int __init mcf5445x_fec_dev_init(void)
325 +{
326 +       int retval = 0;
327 +
328 +       MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
329 +                       MCF_GPIO_PAR_FEC_FEC0_MASK) |
330 +                       MCF_GPIO_PAR_FEC_FEC0_RMII_GPIO;
331 +
332 +       MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
333 +               MCF_GPIO_PAR_FEC_FEC1_MASK) |
334 +               MCF_GPIO_PAR_FEC_FEC1_RMII_GPIO;
335 +
336 +       MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_MDIO0_MDIO0 |
337 +                       MCF_GPIO_PAR_FECI2C_MDC0_MDC0);
338 +
339 +       MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_MDIO1_MDIO1 |
340 +                       MCF_GPIO_PAR_FECI2C_MDC1_MDC1);
341 +
342 +       retval = platform_add_devices(fec_device, ARRAY_SIZE(fec_device));
343 +       if (retval < 0) {
344 +               printk(KERN_ERR "MCF5445x FEC: platform_device_register failed"
345 +                               "with code=%d\n",
346 +                       retval);
347 +       }
348 +
349 +       return retval;
350 +}
351 +
352 +arch_initcall(mcf5445x_fec_dev_init);
353 --- a/drivers/net/Kconfig
354 +++ b/drivers/net/Kconfig
355 @@ -1943,13 +1943,44 @@ config 68360_ENET
356  
357  config FEC
358         bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
359 -       depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
360 +       depends on M523x || M527x || M5272 || M528x || M520x || M532x || M5445X || M5441X || \
361                 MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
362         select PHYLIB
363         help
364           Say Y here if you want to use the built-in 10/100 Fast ethernet
365           controller on some Motorola ColdFire and Freescale i.MX processors.
366  
367 +
368 +config FEC2
369 +       bool "Second FEC ethernet controller (on some ColdFire CPUs)"
370 +       depends on FEC && (M54455 || M5441X)
371 +       help
372 +         Say Y here if you want to use the second built-in 10/100 Fast
373 +         ethernet controller on some Motorola ColdFire processors.
374 +
375 +config FEC_548x
376 +       tristate "MCF547x/MCF548x Fast Ethernet Controller support"
377 +       depends on M547X_8X
378 +       help
379 +         The MCF547x and MCF548x have a built-in Fast Ethernet Controller.
380 +         Saying Y here will include support for this device in the kernel.
381 +
382 +         To compile this driver as a module, choose M here: the module
383 +         will be called fecm.
384 +
385 +config FEC_548x_ENABLE_FEC2
386 +       bool "Enable the second FEC"
387 +       depends on FEC_548x
388 +       help
389 +         This enables the second FEC on the 547x/548x. If you want to use
390 +         it, say Y.
391 +
392 +config FEC_548x_SHARED_PHY
393 +       bool "Shared PHY interface(on some ColdFire designs)"
394 +       depends on FEC_548x_ENABLE_FEC2
395 +       help
396 +         Say Y here if both PHYs are controlled via a single channel.
397 +
398  config FEC_MPC52xx
399         tristate "MPC52xx FEC driver"
400         depends on PPC_MPC52xx && PPC_BESTCOMM
401 --- a/drivers/net/Makefile
402 +++ b/drivers/net/Makefile
403 @@ -123,6 +123,7 @@ obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
404  obj-$(CONFIG_HP100) += hp100.o
405  obj-$(CONFIG_SMC9194) += smc9194.o
406  obj-$(CONFIG_FEC) += fec.o
407 +obj-$(CONFIG_FEC_548x) += fec_m547x.o
408  obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
409  ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
410         obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
411 --- a/drivers/net/fec.c
412 +++ b/drivers/net/fec.c
413 @@ -18,7 +18,7 @@
414   * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
415   * Copyright (c) 2004-2006 Macq Electronique SA.
416   *
417 - * Copyright (C) 2010 Freescale Semiconductor, Inc.
418 + * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
419   */
420  
421  #include <linux/module.h>
422 @@ -74,6 +74,9 @@ static struct platform_device_id fec_dev
423         }, {
424                 .name = "imx28-fec",
425                 .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
426 +       }, {
427 +               .name = "m54418-fec",
428 +               .driver_data = FEC_QUIRK_ENET_MAC,
429         },
430         { }
431  };
432 @@ -148,8 +151,9 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet
433   * account when setting it.
434   */
435  #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
436 -    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
437 -    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
438 +       defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
439 +       defined(CONFIG_M5445X) || defined(CONFIG_M5441X) || \
440 +       defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
441  #define        OPT_FRAME_SIZE  (PKT_MAXBUF_SIZE << 16)
442  #else
443  #define        OPT_FRAME_SIZE  0
444 @@ -400,7 +404,8 @@ fec_enet_tx(struct net_device *dev)
445                 if (bdp == fep->cur_tx && fep->tx_full == 0)
446                         break;
447  
448 -               dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
449 +/*             dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, \
450 +                       FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);*/
451                 bdp->cbd_bufaddr = 0;
452  
453                 skb = fep->tx_skbuff[fep->skb_dirty];
454 @@ -527,8 +532,8 @@ fec_enet_rx(struct net_device *dev)
455                 dev->stats.rx_bytes += pkt_len;
456                 data = (__u8*)__va(bdp->cbd_bufaddr);
457  
458 -               dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
459 -                               DMA_FROM_DEVICE);
460 +/*             dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
461 +                       DMA_FROM_DEVICE);*/
462  
463                 if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
464                         swap_buffer(data, pkt_len);
465 @@ -552,8 +557,8 @@ fec_enet_rx(struct net_device *dev)
466                         netif_rx(skb);
467                 }
468  
469 -               bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
470 -                       DMA_FROM_DEVICE);
471 +/*             bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
472 +               DMA_FROM_DEVICE);*/
473  rx_processing_done:
474                 /* Clear the status flags for this buffer */
475                 status &= ~BD_ENET_RX_STATS;
476 @@ -632,6 +637,8 @@ static void __inline__ fec_get_mac(struc
477  static void fec_enet_adjust_link(struct net_device *dev)
478  {
479         struct fec_enet_private *fep = netdev_priv(dev);
480 +       const struct platform_device_id *id_entry =
481 +                               platform_get_device_id(fep->pdev);
482         struct phy_device *phy_dev = fep->phy_dev;
483         unsigned long flags;
484  
485 @@ -660,6 +667,10 @@ static void fec_enet_adjust_link(struct
486                         fec_restart(dev, phy_dev->duplex);
487                 else
488                         fec_stop(dev);
489 +
490 +               if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
491 +                       writel(2, fep->hwp + FEC_ECNTRL);
492 +
493                 status_change = 1;
494         }
495  
496 --- a/drivers/net/fec.h
497 +++ b/drivers/net/fec.h
498 @@ -4,6 +4,7 @@
499   *     fec.h  --  Fast Ethernet Controller for Motorola ColdFire SoC
500   *                processors.
501   *
502 + *      Copyright (C) 2011 Freescale Semiconductor,Inc. All Rights Reserved.
503   *     (C) Copyright 2000-2005, Greg Ungerer (gerg@snapgear.com)
504   *     (C) Copyright 2000-2001, Lineo (www.lineo.com)
505   */
506 @@ -14,8 +15,10 @@
507  /****************************************************************************/
508  
509  #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
510 -    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
511 -    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
512 +       defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
513 +       defined(CONFIG_M537x) || defined(CONFIG_M5301x) || \
514 +       defined(CONFIG_M5445X) || defined(CONFIG_M5441X) || \
515 +       defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
516  /*
517   *     Just figures, Motorola would have to change the offsets for
518   *     registers in the same peripheral device on different models
519 --- /dev/null
520 +++ b/drivers/net/fec_m547x.c
521 @@ -0,0 +1,1551 @@
522 +/*
523 + * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
524 + * Author: Kurt Mahan, kmahan@freescale.com
525 + *
526 + * This program is free software; you can redistribute it and/or modify
527 + * it under the terms of the GNU General Public License as published by
528 + * the Free Software Foundation; either version 2 of the License, or
529 + * (at your option) any later version.
530 + */
531 +#include <linux/module.h>
532 +#include <linux/kernel.h>
533 +#include <linux/string.h>
534 +#include <linux/ptrace.h>
535 +#include <linux/errno.h>
536 +#include <linux/ioport.h>
537 +#include <linux/slab.h>
538 +#include <linux/interrupt.h>
539 +#include <linux/pci.h>
540 +#include <linux/init.h>
541 +#include <linux/phy.h>
542 +#include <linux/delay.h>
543 +#include <linux/netdevice.h>
544 +#include <linux/etherdevice.h>
545 +#include <linux/skbuff.h>
546 +#include <linux/spinlock.h>
547 +#include <linux/workqueue.h>
548 +#include <linux/bitops.h>
549 +
550 +#include <asm/coldfire.h>
551 +#include <asm/mcfsim.h>
552 +
553 +#include <asm/dma.h>
554 +#include <asm/MCD_dma.h>
555 +#include <asm/m5485sram.h>
556 +#include <asm/virtconvert.h>
557 +#include <asm/irq.h>
558 +
559 +#include "fec_m547x.h"
560 +
561 +#ifdef CONFIG_FEC_548x_ENABLE_FEC2
562 +#define        FEC_MAX_PORTS   2
563 +#define        FEC_2
564 +#else
565 +#define        FEC_MAX_PORTS   1
566 +#undef FEC_2
567 +#endif
568 +
569 +#define VERSION "0.20"
570 +MODULE_DESCRIPTION("DMA Fast Ethernet Controller driver ver " VERSION);
571 +
572 +/* fec private */
573 +struct fec_priv {
574 +       struct net_device *netdev;              /* owning net device */
575 +       void *fecpriv_txbuf[FEC_TX_BUF_NUMBER]; /* tx buffer ptrs */
576 +       MCD_bufDescFec *fecpriv_txdesc;         /* tx descriptor ptrs */
577 +       volatile unsigned int fecpriv_current_tx; /* current tx desc index */
578 +       volatile unsigned int fecpriv_next_tx;  /* next tx desc index */
579 +       unsigned int fecpriv_current_rx;        /* current rx desc index */
580 +       MCD_bufDescFec *fecpriv_rxdesc;         /* rx descriptor ptrs */
581 +       struct sk_buff *askb_rx[FEC_RX_BUF_NUMBER]; /* rx SKB ptrs */
582 +       unsigned int fecpriv_initiator_rx;      /* rx dma initiator */
583 +       unsigned int fecpriv_initiator_tx;      /* tx dma initiator */
584 +       int fecpriv_fec_rx_channel;             /* rx dma channel */
585 +       int fecpriv_fec_tx_channel;             /* tx dma channel */
586 +       int fecpriv_rx_requestor;               /* rx dma requestor */
587 +       int fecpriv_tx_requestor;               /* tx dma requestor */
588 +       void *fecpriv_interrupt_fec_rx_handler; /* dma rx handler */
589 +       void *fecpriv_interrupt_fec_tx_handler; /* dma tx handler */
590 +       unsigned char *fecpriv_mac_addr;        /* private fec mac addr */
591 +       struct net_device_stats fecpriv_stat;   /* stats ptr */
592 +       spinlock_t fecpriv_lock;
593 +       int fecpriv_rxflag;
594 +       struct tasklet_struct fecpriv_tasklet_reinit;
595 +       int index;                              /* fec hw number */
596 +       struct phy_device *phydev;
597 +       struct mii_bus *mdio_bus;
598 +       int  duplex;
599 +       int  link;
600 +       int  speed;
601 +};
602 +
603 +struct net_device *fec_dev[FEC_MAX_PORTS];
604 +
605 +/* FEC functions */
606 +static int __init fec_init(void);
607 +/*
608 +static struct net_device_stats *fec_get_stat(struct net_device *dev);
609 +static int fec_open(struct net_device *dev);
610 +static int fec_close(struct net_device *nd);
611 +static int fec_tx(struct sk_buff *skb, struct net_device *dev);
612 +static void fec_set_multicast_list(struct net_device *nd);
613 +static int fec_set_mac_address(struct net_device *dev, void *p);
614 +static void fec_tx_timeout(struct net_device *dev);
615 +*/
616 +static void fec_interrupt_fec_tx_handler(struct net_device *dev);
617 +static void fec_interrupt_fec_rx_handler(struct net_device *dev);
618 +static irqreturn_t fec_interrupt_handler(int irq, void *dev_id);
619 +static void fec_interrupt_fec_tx_handler_fec0(void);
620 +static void fec_interrupt_fec_rx_handler_fec0(void);
621 +static void fec_interrupt_fec_reinit(unsigned long data);
622 +
623 +/* default fec0 address */
624 +unsigned char fec_mac_addr_fec0[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x50 };
625 +
626 +#ifdef FEC_2
627 +/* default fec1 address */
628 +unsigned char fec_mac_addr_fec1[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x51 };
629 +#endif
630 +
631 +extern unsigned char uboot_enet0[];
632 +extern unsigned char uboot_enet1[];
633 +
634 +#ifndef MODULE
635 +int fec_str_to_mac(char *str_mac, unsigned char* addr);
636 +int __init fec_mac_setup0(char *s);
637 +#endif
638 +
639 +
640 +#ifdef FEC_2
641 +void fec_interrupt_fec_tx_handler_fec1(void);
642 +void fec_interrupt_fec_rx_handler_fec1(void);
643 +#endif
644 +
645 +#ifndef MODULE
646 +int __init fec_mac_setup1(char *s);
647 +#endif
648 +
649 +module_init(fec_init);
650 +/* module_exit(fec_cleanup); */
651 +
652 +__setup("mac0=", fec_mac_setup0);
653 +
654 +#ifdef FEC_2
655 +__setup("mac1=", fec_mac_setup1);
656 +#endif
657 +
658 +#define mk_mii_read(REG)        (0x60020000 | ((REG & 0x1f) << 18))
659 +#define mk_mii_write(REG, VAL)  (0x50020000 | ((REG & 0x1f) << 18) | \
660 +               (VAL & 0xffff))
661 +/* ----------------------------------------------------------- */
662 +static int coldfire_fec_mdio_read(struct mii_bus *bus,
663 +       int phy_id, int reg)
664 +{
665 +       int ret;
666 +#ifdef CONFIG_FEC_548x_SHARED_PHY
667 +       unsigned long base_addr = (unsigned long)FEC_BASE_ADDR_FEC0;
668 +#else
669 +       unsigned long base_addr = (unsigned long) dev->base_addr;
670 +#endif
671 +       int tries = 100;
672 +
673 +       /* Clear the MII interrupt bit */
674 +       FEC_EIR(base_addr) = FEC_EIR_MII;
675 +
676 +       /* Write to the MII management frame register */
677 +       FEC_MMFR(base_addr) = mk_mii_read(reg) | (phy_id << 23);
678 +
679 +       /* Wait for the reading */
680 +       while (!(FEC_EIR(base_addr) & FEC_EIR_MII)) {
681 +               udelay(10);
682 +
683 +               if (!tries) {
684 +                       printk(KERN_ERR "%s timeout\n", __func__);
685 +                       return -ETIMEDOUT;
686 +               }
687 +               tries--;
688 +       }
689 +
690 +       /* Clear the MII interrupt bit */
691 +       FEC_EIR(base_addr) = FEC_EIR_MII;
692 +       ret = FEC_MMFR(base_addr) & 0x0000FFFF;
693 +       return ret;
694 +}
695 +
696 +static int coldfire_fec_mdio_write(struct mii_bus *bus,
697 +       int phy_id, int reg, u16 data)
698 +{
699 +       int ret;
700 +#ifdef CONFIG_FEC_548x_SHARED_PHY
701 +       unsigned long base_addr = (unsigned long)FEC_BASE_ADDR_FEC0;
702 +#else
703 +       unsigned long base_addr = (unsigned long) dev->base_addr;
704 +#endif
705 +       int tries = 100;
706 +
707 +       printk(KERN_ERR "%s base_addr %lx, phy_id %x, reg %x, data %x\n",
708 +               __func__, base_addr, phy_id, reg, data);
709 +       /* Clear the MII interrupt bit */
710 +       FEC_EIR(base_addr) = FEC_EIR_MII;
711 +
712 +       /*  Write to the MII management frame register */
713 +       FEC_MMFR(base_addr) = mk_mii_write(reg, data) | (phy_id << 23);
714 +
715 +       /* Wait for the writing */
716 +       while (!(FEC_EIR(base_addr) & FEC_EIR_MII)) {
717 +               udelay(10);
718 +               if (!tries) {
719 +                       printk(KERN_ERR "%s timeout\n", __func__);
720 +                       return -ETIMEDOUT;
721 +               }
722 +               tries--;
723 +       }
724 +       /* Clear the MII interrupt bit */
725 +       FEC_EIR(base_addr) = FEC_EIR_MII;
726 +       ret = FEC_MMFR(base_addr) & 0x0000FFFF;
727 +
728 +       return ret;
729 +}
730 +
731 +static void fec_adjust_link(struct net_device *dev)
732 +{
733 +       struct fec_priv *priv = netdev_priv(dev);
734 +       struct phy_device *phydev = priv->phydev;
735 +       int new_state = 0;
736 +
737 +       if (phydev->link != PHY_DOWN) {
738 +               if (phydev->duplex != priv->duplex) {
739 +                       new_state = 1;
740 +                       priv->duplex = phydev->duplex;
741 +               }
742 +
743 +               if (phydev->speed != priv->speed) {
744 +                       new_state = 1;
745 +                       priv->speed = phydev->speed;
746 +               }
747 +
748 +               if (priv->link == PHY_DOWN) {
749 +                       new_state = 1;
750 +                       priv->link = phydev->link;
751 +               }
752 +       } else if (priv->link) {
753 +               new_state = 1;
754 +               priv->link = PHY_DOWN;
755 +               priv->speed = 0;
756 +               priv->duplex = -1;
757 +       }
758 +
759 +       if (new_state)
760 +               phy_print_status(phydev);
761 +}
762 +
763 +static int coldfire_fec_init_phy(struct net_device *dev)
764 +{
765 +       struct fec_priv *priv = netdev_priv(dev);
766 +       struct phy_device *phydev = NULL;
767 +       int i;
768 +       int startnode;
769 +
770 +#ifdef CONFIG_FEC_548x_SHARED_PHY
771 +       if (priv->index == 0)
772 +               startnode = 0;
773 +       else if (priv->index == 1) {
774 +               struct fec_priv *priv0 = netdev_priv(fec_dev[0]);
775 +               startnode = priv0->phydev->addr + 1;
776 +       } else
777 +               startnode = 0;
778 +#else
779 +       startnode = 0;
780 +#endif
781 +#ifdef FEC_DEBUG
782 +       printk(KERN_ERR "%s priv->index %x, startnode %x\n",
783 +               __func__, priv->index, startnode);
784 +#endif
785 +       /* search for connect PHY device */
786 +       for (i = startnode; i < PHY_MAX_ADDR; i++) {
787 +               struct phy_device *const tmp_phydev =
788 +                       priv->mdio_bus->phy_map[i];
789 +
790 +               if (!tmp_phydev) {
791 +#ifdef FEC_DEBUG
792 +                       printk(KERN_INFO "%s no PHY here at"
793 +                               "mii_bus->phy_map[%d]\n",
794 +                               __func__, i);
795 +#endif
796 +                       continue; /* no PHY here... */
797 +               }
798 +               phydev = tmp_phydev;
799 +#ifdef FEC_DEBUG
800 +               printk(KERN_INFO "%s find PHY here at"
801 +                               "mii_bus->phy_map[%d]\n",
802 +                               __func__, i);
803 +#endif
804 +               break; /* found it */
805 +       }
806 +
807 +       /* now we are supposed to have a proper phydev, to attach to... */
808 +       if (!phydev) {
809 +               printk(KERN_INFO "%s: Don't found any phy device at all\n",
810 +                       dev->name);
811 +               return -ENODEV;
812 +       }
813 +
814 +       priv->link = 0;
815 +       priv->speed = 0;
816 +       priv->duplex = 0;
817 +#ifdef FEC_DEBUG
818 +       printk(KERN_INFO "%s phydev_busid %s\n", __func__, phydev->dev.bus_id);
819 +#endif
820 +       phydev = phy_connect(dev, dev_name(&phydev->dev),
821 +                       &fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
822 +       if (IS_ERR(phydev)) {
823 +               printk(KERN_ERR " %s phy_connect failed\n", __func__);
824 +               return PTR_ERR(phydev);
825 +       }
826 +
827 +       printk(KERN_INFO "attached phy %i to driver %s\n",
828 +       phydev->addr, phydev->drv->name);
829 +       priv->phydev = phydev;
830 +       return 0;
831 +}
832 +
833 +static int fec_mdio_register(struct net_device *dev,
834 +       int slot)
835 +{
836 +       int err = 0;
837 +       struct fec_priv *fp = netdev_priv(dev);
838 +
839 +       fp->mdio_bus = mdiobus_alloc();
840 +       if (!fp->mdio_bus) {
841 +               printk(KERN_ERR "ethernet mdiobus_alloc fail\n");
842 +               return -ENOMEM;
843 +       }
844 +
845 +       if (slot == 0) {
846 +               fp->mdio_bus->name = "Coldfire FEC MII 0 Bus";
847 +               strcpy(fp->mdio_bus->id, "0");
848 +       } else if (slot == 1) {
849 +               fp->mdio_bus->name = "Coldfire FEC MII 1 Bus";
850 +               strcpy(fp->mdio_bus->id, "1");
851 +       } else {
852 +               printk(KERN_ERR "Now coldfire can not"
853 +                       "support more than 2 mii bus\n");
854 +       }
855 +
856 +       fp->mdio_bus->read = &coldfire_fec_mdio_read;
857 +       fp->mdio_bus->write = &coldfire_fec_mdio_write;
858 +       fp->mdio_bus->priv = dev;
859 +       err = mdiobus_register(fp->mdio_bus);
860 +       if (err) {
861 +               mdiobus_free(fp->mdio_bus);
862 +               printk(KERN_ERR "%s: ethernet mdiobus_register fail %d\n",
863 +                       dev->name, err);
864 +               return -EIO;
865 +       }
866 +
867 +       printk(KERN_INFO "mdiobus_register %s ok\n",
868 +               fp->mdio_bus->name);
869 +       return err;
870 +}
871 +
872 +/************************************************************************
873 +* NAME: mcf547x_fec_open
874 +*
875 +* DESCRIPTION: This function performs the initialization of
876 +*                              of FEC and corresponding KS8721 transiver
877 +*
878 +* RETURNS: If no error occurs, this function returns zero.
879 +*************************************************************************/
880 +static int mcf547x_fec_open(struct net_device *dev)
881 +{
882 +       struct fec_priv *fp = netdev_priv(dev);
883 +       unsigned long base_addr = (unsigned long) dev->base_addr;
884 +       int fduplex;
885 +       int i;
886 +       int channel;
887 +       int error_code = -EBUSY;
888 +
889 +       fp->link = 0;
890 +       fp->duplex = 0;
891 +       fp->speed = 0;
892 +       coldfire_fec_init_phy(dev);
893 +       phy_start(fp->phydev);
894 +
895 +       /* Receive the DMA channels */
896 +       channel = dma_set_channel_fec(fp->fecpriv_rx_requestor);
897 +
898 +       if (channel == -1) {
899 +               printk(KERN_ERR "Dma channel cannot be reserved\n");
900 +               goto ERRORS;
901 +       }
902 +
903 +       fp->fecpriv_fec_rx_channel = channel;
904 +
905 +       dma_connect(channel, (int) fp->fecpriv_interrupt_fec_rx_handler);
906 +
907 +       channel = dma_set_channel_fec(fp->fecpriv_tx_requestor);
908 +
909 +       if (channel == -1) {
910 +               printk(KERN_ERR "Dma channel cannot be reserved\n");
911 +               goto ERRORS;
912 +       }
913 +
914 +       fp->fecpriv_fec_tx_channel = channel;
915 +
916 +       dma_connect(channel, (int) fp->fecpriv_interrupt_fec_tx_handler);
917 +
918 +       /* init tasklet for controller reinitialization */
919 +       tasklet_init(&fp->fecpriv_tasklet_reinit,
920 +               fec_interrupt_fec_reinit, (unsigned long) dev);
921 +
922 +       /* Reset FIFOs */
923 +       FEC_FECFRST(base_addr) |= FEC_SW_RST | FEC_RST_CTL;
924 +       FEC_FECFRST(base_addr) &= ~FEC_SW_RST;
925 +
926 +       /* Reset and disable FEC */
927 +       FEC_ECR(base_addr) = FEC_ECR_RESET;
928 +
929 +       udelay(10);
930 +
931 +       /* Clear all events */
932 +       FEC_EIR(base_addr) = FEC_EIR_CLEAR;
933 +
934 +       /* Reset FIFO status */
935 +       FEC_FECTFSR(base_addr) = FEC_FECTFSR_MSK;
936 +       FEC_FECRFSR(base_addr) = FEC_FECRFSR_MSK;
937 +
938 +       /* Set the default address */
939 +       FEC_PALR(base_addr) = (fp->fecpriv_mac_addr[0] << 24) |
940 +                             (fp->fecpriv_mac_addr[1] << 16) |
941 +                             (fp->fecpriv_mac_addr[2] << 8) |
942 +                             fp->fecpriv_mac_addr[3];
943 +       FEC_PAUR(base_addr) = (fp->fecpriv_mac_addr[4] << 24) |
944 +                             (fp->fecpriv_mac_addr[5] << 16) | 0x8808;
945 +
946 +       /* Reset the group address descriptor */
947 +       FEC_GALR(base_addr) = 0x00000000;
948 +       FEC_GAUR(base_addr) = 0x00000000;
949 +
950 +       /* Reset the individual address descriptor */
951 +       FEC_IALR(base_addr) = 0x00000000;
952 +       FEC_IAUR(base_addr) = 0x00000000;
953 +
954 +       /* Set the receive control register */
955 +       FEC_RCR(base_addr) = FEC_RCR_MAX_FRM_SIZE | FEC_RCR_MII;
956 +
957 +       /* Set the receive FIFO control register */
958 +       /*FEC_FECRFCR(base_addr) =
959 +       * FEC_FECRFCR_FRM | FEC_FECRFCR_GR | FEC_FECRFCR_MSK;*/
960 +       FEC_FECRFCR(base_addr) = FEC_FECRFCR_FRM | FEC_FECRFCR_GR
961 +                       | (FEC_FECRFCR_MSK
962 +                       /* disable all but ...*/
963 +                       & ~FEC_FECRFCR_FAE
964 +                       /* enable frame accept error*/
965 +                       & ~FEC_FECRFCR_RXW
966 +                       /* enable receive wait condition*/
967 +                       /*& ~FEC_FECRFCR_UF*/
968 +                       /* enable FIFO underflow*/
969 +                               );
970 +
971 +       /* Set the receive FIFO alarm register */
972 +       FEC_FECRFAR(base_addr) = FEC_FECRFAR_ALARM;
973 +
974 +       /* Set the transmit FIFO control register */
975 +       /*FEC_FECTFCR(base_addr) =
976 +       FEC_FECTFCR_FRM | FEC_FECTFCR_GR | FEC_FECTFCR_MSK;*/
977 +       FEC_FECTFCR(base_addr) = FEC_FECTFCR_FRM | FEC_FECTFCR_GR
978 +                       | (FEC_FECTFCR_MSK
979 +                       /* disable all but ... */
980 +                       & ~FEC_FECTFCR_FAE
981 +                       /* enable frame accept error */
982 +                       /* & ~FEC_FECTFCR_TXW */
983 +                       /*enable transmit wait condition*/
984 +                       /*& ~FEC_FECTFCR_UF*/
985 +                       /*enable FIFO underflow*/
986 +                       & ~FEC_FECTFCR_OF);
987 +                       /* enable FIFO overflow */
988 +
989 +       /* Set the transmit FIFO alarm register */
990 +       FEC_FECTFAR(base_addr) = FEC_FECTFAR_ALARM;
991 +
992 +       /* Set the Tx FIFO watermark */
993 +       FEC_FECTFWR(base_addr) = FEC_FECTFWR_XWMRK;
994 +
995 +       /* Enable the transmitter to append the CRC */
996 +       FEC_CTCWR(base_addr) = FEC_CTCWR_TFCW_CRC;
997 +
998 +       /* Enable the ethernet interrupts */
999 +       /*FEC_EIMR(base_addr) = FEC_EIMR_MASK;*/
1000 +       FEC_EIMR(base_addr) = FEC_EIMR_DISABLE
1001 +                       | FEC_EIR_LC
1002 +                       | FEC_EIR_RL
1003 +                       | FEC_EIR_HBERR
1004 +                       | FEC_EIR_XFUN
1005 +                       | FEC_EIR_XFERR
1006 +                       | FEC_EIR_RFERR;
1007 +
1008 +#if 0
1009 +       error_code = init_transceiver(base_addr, &fduplex);
1010 +       if (error_code != 0) {
1011 +               printk(KERN_ERR "Initialization of the "
1012 +                       "transceiver is failed\n");
1013 +               goto ERRORS;
1014 +       }
1015 +#else
1016 +       fduplex = 1;
1017 +#endif
1018 +       if (fduplex)
1019 +               /* Enable the full duplex mode */
1020 +               FEC_TCR(base_addr) = FEC_TCR_FDEN | FEC_TCR_HBC;
1021 +       else
1022 +               /* Disable reception of frames while transmitting */
1023 +               FEC_RCR(base_addr) |= FEC_RCR_DRT;
1024 +
1025 +       /* Enable MIB */
1026 +       FEC_MIBC(base_addr) = FEC_MIBC_ENABLE;
1027 +
1028 +       /* Enable FEC */
1029 +       FEC_ECR(base_addr) |= FEC_ECR_ETHEREN;
1030 +       FEC_MSCR(dev->base_addr) = FEC_MII_SPEED;
1031 +       /* Initialize tx descriptors and start DMA for the transmission */
1032 +       for (i = 0; i < FEC_TX_BUF_NUMBER; i++)
1033 +               fp->fecpriv_txdesc[i].statCtrl = MCD_FEC_INTERRUPT;
1034 +
1035 +       fp->fecpriv_txdesc[i - 1].statCtrl |= MCD_FEC_WRAP;
1036 +
1037 +       fp->fecpriv_current_tx = fp->fecpriv_next_tx = 0;
1038 +
1039 +       MCD_startDma(fp->fecpriv_fec_tx_channel, (char *) fp->fecpriv_txdesc, 0,
1040 +                    (unsigned char *) &(FEC_FECTFDR(base_addr)), 0,
1041 +                    FEC_MAX_FRM_SIZE, 0, fp->fecpriv_initiator_tx,
1042 +                    FEC_TX_DMA_PRI, MCD_FECTX_DMA | MCD_INTERRUPT,
1043 +                    MCD_NO_CSUM | MCD_NO_BYTE_SWAP);
1044 +
1045 +       /* Initialize rx descriptors and start DMA for the reception */
1046 +       for (i = 0; i < FEC_RX_BUF_NUMBER; i++) {
1047 +               fp->askb_rx[i] = alloc_skb(FEC_MAXBUF_SIZE + 16, GFP_DMA);
1048 +               if (!fp->askb_rx[i]) {
1049 +                       fp->fecpriv_rxdesc[i].dataPointer = 0;
1050 +                       fp->fecpriv_rxdesc[i].statCtrl = 0;
1051 +                       fp->fecpriv_rxdesc[i].length = 0;
1052 +               } else {
1053 +                       skb_reserve(fp->askb_rx[i], 16);
1054 +                       fp->askb_rx[i]->dev = dev;
1055 +                       fp->fecpriv_rxdesc[i].dataPointer =
1056 +                       (unsigned int)virt_to_phys(fp->askb_rx[i]->tail);
1057 +                       fp->fecpriv_rxdesc[i].statCtrl =
1058 +                               MCD_FEC_BUF_READY | MCD_FEC_INTERRUPT;
1059 +                       fp->fecpriv_rxdesc[i].length = FEC_MAXBUF_SIZE;
1060 +               }
1061 +       }
1062 +
1063 +       fp->fecpriv_rxdesc[i - 1].statCtrl |= MCD_FEC_WRAP;
1064 +       fp->fecpriv_current_rx = 0;
1065 +
1066 +       MCD_startDma(fp->fecpriv_fec_rx_channel, (char *) fp->fecpriv_rxdesc, 0,
1067 +                    (unsigned char *) &(FEC_FECRFDR(base_addr)), 0,
1068 +                    FEC_MAX_FRM_SIZE, 0, fp->fecpriv_initiator_rx,
1069 +                    FEC_RX_DMA_PRI, MCD_FECRX_DMA | MCD_INTERRUPT,
1070 +                    MCD_NO_CSUM | MCD_NO_BYTE_SWAP);
1071 +
1072 +       netif_start_queue(dev);
1073 +       return 0;
1074 +
1075 +ERRORS:
1076 +
1077 +       /* Remove the channels and return with the error code */
1078 +       if (fp->fecpriv_fec_rx_channel != -1) {
1079 +               dma_disconnect(fp->fecpriv_fec_rx_channel);
1080 +               dma_remove_channel_by_number(fp->fecpriv_fec_rx_channel);
1081 +               fp->fecpriv_fec_rx_channel = -1;
1082 +       }
1083 +
1084 +       if (fp->fecpriv_fec_tx_channel != -1) {
1085 +               dma_disconnect(fp->fecpriv_fec_tx_channel);
1086 +               dma_remove_channel_by_number(fp->fecpriv_fec_tx_channel);
1087 +               fp->fecpriv_fec_tx_channel = -1;
1088 +       }
1089 +
1090 +       return error_code;
1091 +}
1092 +
1093 +/************************************************************************
1094 +* NAME: mcf547x_fec_close
1095 +*
1096 +* DESCRIPTION: This function performs the graceful stop of the
1097 +*                              transmission and disables FEC
1098 +*
1099 +* RETURNS: This function always returns zero.
1100 +*************************************************************************/
1101 +static int mcf547x_fec_close(struct net_device *dev)
1102 +{
1103 +       struct fec_priv *fp = netdev_priv(dev);
1104 +       unsigned long base_addr = (unsigned long) dev->base_addr;
1105 +       unsigned long time;
1106 +       int i;
1107 +
1108 +       netif_stop_queue(dev);
1109 +       phy_disconnect(fp->phydev);
1110 +       phy_stop(fp->phydev);
1111 +       /* Perform the graceful stop */
1112 +       FEC_TCR(base_addr) |= FEC_TCR_GTS;
1113 +
1114 +       time = jiffies;
1115 +
1116 +       /* Wait for the graceful stop */
1117 +       while (!(FEC_EIR(base_addr) & FEC_EIR_GRA) && jiffies - time <
1118 +                       (FEC_GR_TIMEOUT * HZ))
1119 +               schedule();
1120 +
1121 +       /* Disable FEC */
1122 +       FEC_ECR(base_addr) = FEC_ECR_DISABLE;
1123 +
1124 +       /* Reset the DMA channels */
1125 +       spin_lock_irq(&fp->fecpriv_lock);
1126 +       MCD_killDma(fp->fecpriv_fec_tx_channel);
1127 +       spin_unlock_irq(&fp->fecpriv_lock);
1128 +       dma_remove_channel_by_number(fp->fecpriv_fec_tx_channel);
1129 +       dma_disconnect(fp->fecpriv_fec_tx_channel);
1130 +       fp->fecpriv_fec_tx_channel = -1;
1131 +
1132 +       for (i = 0; i < FEC_TX_BUF_NUMBER; i++) {
1133 +               kfree(fp->fecpriv_txbuf[i]);
1134 +               fp->fecpriv_txbuf[i] = NULL;
1135 +       }
1136 +
1137 +       spin_lock_irq(&fp->fecpriv_lock);
1138 +       MCD_killDma(fp->fecpriv_fec_rx_channel);
1139 +       spin_unlock_irq(&fp->fecpriv_lock);
1140 +
1141 +       dma_remove_channel_by_number(fp->fecpriv_fec_rx_channel);
1142 +       dma_disconnect(fp->fecpriv_fec_rx_channel);
1143 +       fp->fecpriv_fec_rx_channel = -1;
1144 +
1145 +       for (i = 0; i < FEC_RX_BUF_NUMBER; i++) {
1146 +               if (fp->askb_rx[i]) {
1147 +                       kfree_skb(fp->askb_rx[i]);
1148 +                       fp->askb_rx[i] = NULL;
1149 +               }
1150 +       }
1151 +
1152 +       return 0;
1153 +}
1154 +
1155 +/************************************************************************
1156 +* +NAME: mcf547x_fec_get_stat
1157 +*
1158 +* RETURNS: This function returns the statistical information.
1159 +*************************************************************************/
1160 +static struct net_device_stats *mcf547x_fec_get_stats(struct net_device *dev)
1161 +{
1162 +       struct fec_priv *fp = netdev_priv(dev);
1163 +       unsigned long base_addr = dev->base_addr;
1164 +
1165 +       /* Receive the statistical information */
1166 +       fp->fecpriv_stat.rx_packets = FECSTAT_RMON_R_PACKETS(base_addr);
1167 +       fp->fecpriv_stat.tx_packets = FECSTAT_RMON_T_PACKETS(base_addr);
1168 +       fp->fecpriv_stat.rx_bytes = FECSTAT_RMON_R_OCTETS(base_addr);
1169 +       fp->fecpriv_stat.tx_bytes = FECSTAT_RMON_T_OCTETS(base_addr);
1170 +
1171 +       fp->fecpriv_stat.multicast = FECSTAT_RMON_R_MC_PKT(base_addr);
1172 +       fp->fecpriv_stat.collisions = FECSTAT_RMON_T_COL(base_addr);
1173 +
1174 +       fp->fecpriv_stat.rx_length_errors =
1175 +               FECSTAT_RMON_R_UNDERSIZE(base_addr) +
1176 +               FECSTAT_RMON_R_OVERSIZE(base_addr) +
1177 +               FECSTAT_RMON_R_FRAG(base_addr) +
1178 +               FECSTAT_RMON_R_JAB(base_addr);
1179 +       fp->fecpriv_stat.rx_crc_errors = FECSTAT_IEEE_R_CRC(base_addr);
1180 +       fp->fecpriv_stat.rx_frame_errors = FECSTAT_IEEE_R_ALIGN(base_addr);
1181 +       fp->fecpriv_stat.rx_over_errors = FECSTAT_IEEE_R_MACERR(base_addr);
1182 +
1183 +       fp->fecpriv_stat.tx_carrier_errors = FECSTAT_IEEE_T_CSERR(base_addr);
1184 +       fp->fecpriv_stat.tx_fifo_errors = FECSTAT_IEEE_T_MACERR(base_addr);
1185 +       fp->fecpriv_stat.tx_window_errors = FECSTAT_IEEE_T_LCOL(base_addr);
1186 +
1187 +       /* I hope that one frame doesn't have more than one error */
1188 +       fp->fecpriv_stat.rx_errors = fp->fecpriv_stat.rx_length_errors +
1189 +               fp->fecpriv_stat.rx_crc_errors +
1190 +               fp->fecpriv_stat.rx_frame_errors +
1191 +               fp->fecpriv_stat.rx_over_errors +
1192 +               fp->fecpriv_stat.rx_dropped;
1193 +       fp->fecpriv_stat.tx_errors = fp->fecpriv_stat.tx_carrier_errors +
1194 +               fp->fecpriv_stat.tx_fifo_errors +
1195 +               fp->fecpriv_stat.tx_window_errors +
1196 +               fp->fecpriv_stat.tx_aborted_errors +
1197 +               fp->fecpriv_stat.tx_heartbeat_errors +
1198 +               fp->fecpriv_stat.tx_dropped;
1199 +
1200 +       return &fp->fecpriv_stat;
1201 +}
1202 +
1203 +/************************************************************************
1204 +* NAME: mcf547x_fec_set_multicast_list
1205 +*
1206 +* DESCRIPTION: This function sets the frame filtering parameters
1207 +*************************************************************************/
1208 +static void mcf547x_fec_set_multicast_list(struct net_device *dev)
1209 +{
1210 +       unsigned int crc, data;
1211 +       int j, k;
1212 +       unsigned long base_addr = (unsigned long) dev->base_addr;
1213 +       struct netdev_hw_addr *ha;
1214 +
1215 +       if (dev->flags & IFF_PROMISC || dev->flags & IFF_ALLMULTI) {
1216 +               /* Allow all incoming frames */
1217 +               FEC_GALR(base_addr) = 0xFFFFFFFF;
1218 +               FEC_GAUR(base_addr) = 0xFFFFFFFF;
1219 +               return;
1220 +       }
1221 +
1222 +       /* Reset the group address register */
1223 +       FEC_GALR(base_addr) = 0x00000000;
1224 +       FEC_GAUR(base_addr) = 0x00000000;
1225 +
1226 +       /* Process all addresses */
1227 +       netdev_for_each_mc_addr(ha, dev) {
1228 +               /* Processing must be only for the group addresses */
1229 +               if (!(ha->addr[0] & 1))
1230 +                       continue;
1231 +
1232 +               /* Calculate crc value for the current address */
1233 +               crc = 0xFFFFFFFF;
1234 +               for (j = 0; j < dev->addr_len; j++) {
1235 +                       data = ha->addr[j];
1236 +                       for (k = 0; k < 8; k++, data >>= 1) {
1237 +                               if ((crc ^ data) & 1)
1238 +                                       crc = (crc >> 1) ^ FEC_CRCPOL;
1239 +                               else
1240 +                                       crc >>= 1;
1241 +                       }
1242 +               }
1243 +
1244 +               /* Add this value */
1245 +               crc >>= 26;
1246 +               crc &= 0x3F;
1247 +               if (crc > 31)
1248 +                       FEC_GAUR(base_addr) |= 0x1 << (crc - 32);
1249 +               else
1250 +                       FEC_GALR(base_addr) |= 0x1 << crc;
1251 +       }
1252 +}
1253 +
1254 +/************************************************************************
1255 +* NAME: mcf547x_fec_set_mac_address
1256 +*
1257 +* DESCRIPTION: This function sets the MAC address
1258 +*************************************************************************/
1259 +static int mcf547x_fec_set_mac_address(struct net_device *dev, void *p)
1260 +{
1261 +       struct fec_priv *fp = netdev_priv(dev);
1262 +       unsigned long base_addr = (unsigned long) dev->base_addr;
1263 +       struct sockaddr *addr = p;
1264 +
1265 +       if (netif_running(dev))
1266 +               return -EBUSY;
1267 +
1268 +       /* Copy a new address to the device structure */
1269 +       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1270 +
1271 +       /* Copy a new address to the private structure */
1272 +       memcpy(fp->fecpriv_mac_addr, addr->sa_data, 6);
1273 +
1274 +       /* Set the address to the registers */
1275 +       FEC_PALR(base_addr) = (fp->fecpriv_mac_addr[0] << 24) |
1276 +               (fp->fecpriv_mac_addr[1] << 16) |
1277 +               (fp->fecpriv_mac_addr[2] << 8) |
1278 +               fp->fecpriv_mac_addr[3];
1279 +       FEC_PAUR(base_addr) = (fp->fecpriv_mac_addr[4] << 24) |
1280 +               (fp->fecpriv_mac_addr[5] << 16) |
1281 +               0x8808;
1282 +
1283 +       return 0;
1284 +}
1285 +
1286 +/************************************************************************
1287 +* NAME: mcf547x_fec_start_xmit
1288 +*
1289 +* DESCRIPTION: This function starts transmission of the frame using DMA
1290 +*
1291 +* RETURNS: This function always returns zero.
1292 +*************************************************************************/
1293 +static int mcf547x_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
1294 +{
1295 +       struct fec_priv *fp = netdev_priv(dev);
1296 +       void *data, *data_aligned;
1297 +       int offset;
1298 +
1299 +       data = kmalloc(skb->len + 15, GFP_DMA | GFP_ATOMIC);
1300 +
1301 +       if (!data) {
1302 +               fp->fecpriv_stat.tx_dropped++;
1303 +               dev_kfree_skb(skb);
1304 +               return 0;
1305 +       }
1306 +
1307 +       offset = (((unsigned long)virt_to_phys(data) + 15) & 0xFFFFFFF0) -
1308 +               (unsigned long)virt_to_phys(data);
1309 +       data_aligned = (void *)((unsigned long)data + offset);
1310 +       memcpy(data_aligned, skb->data, skb->len);
1311 +
1312 +       /* flush data cache before initializing
1313 +        * the descriptor and starting DMA */
1314 +
1315 +       spin_lock_irq(&fp->fecpriv_lock);
1316 +
1317 +       /* Initialize the descriptor */
1318 +       fp->fecpriv_txbuf[fp->fecpriv_next_tx] = data;
1319 +       fp->fecpriv_txdesc[fp->fecpriv_next_tx].dataPointer
1320 +               = (unsigned int) virt_to_phys(data_aligned);
1321 +       fp->fecpriv_txdesc[fp->fecpriv_next_tx].length = skb->len;
1322 +       fp->fecpriv_txdesc[fp->fecpriv_next_tx].statCtrl
1323 +               |= (MCD_FEC_END_FRAME | MCD_FEC_BUF_READY);
1324 +       fp->fecpriv_next_tx = (fp->fecpriv_next_tx + 1) & FEC_TX_INDEX_MASK;
1325 +
1326 +       if (fp->fecpriv_txbuf[fp->fecpriv_current_tx]
1327 +               && fp->fecpriv_current_tx == fp->fecpriv_next_tx)
1328 +               netif_stop_queue(dev);
1329 +
1330 +       spin_unlock_irq(&fp->fecpriv_lock);
1331 +
1332 +       /* Tell the DMA to continue the transmission */
1333 +       MCD_continDma(fp->fecpriv_fec_tx_channel);
1334 +
1335 +       dev_kfree_skb(skb);
1336 +
1337 +       dev->trans_start = jiffies;
1338 +
1339 +       return 0;
1340 +}
1341 +
1342 +/************************************************************************
1343 +* NAME: mcf547x_fec_tx_timeout
1344 +*
1345 +* DESCRIPTION: If the interrupt processing of received frames was lost
1346 +*              and DMA stopped the reception, this function clears
1347 +*              the transmission descriptors and starts DMA
1348 +*
1349 +*************************************************************************/
1350 +static void mcf547x_fec_tx_timeout(struct net_device *dev)
1351 +{
1352 +       int i;
1353 +       struct fec_priv *fp = netdev_priv(dev);
1354 +       unsigned long base_addr = (unsigned long) dev->base_addr;
1355 +
1356 +       spin_lock_irq(&fp->fecpriv_lock);
1357 +       MCD_killDma(fp->fecpriv_fec_tx_channel);
1358 +       for (i = 0; i < FEC_TX_BUF_NUMBER; i++) {
1359 +               kfree(fp->fecpriv_txbuf[i]);
1360 +               fp->fecpriv_txbuf[i] = NULL;
1361 +               fp->fecpriv_txdesc[i].statCtrl = MCD_FEC_INTERRUPT;
1362 +       }
1363 +       fp->fecpriv_txdesc[i - 1].statCtrl |= MCD_FEC_WRAP;
1364 +
1365 +       fp->fecpriv_current_tx = fp->fecpriv_next_tx = 0;
1366 +
1367 +       /* Reset FIFOs */
1368 +       FEC_FECFRST(base_addr) |= FEC_SW_RST;
1369 +       FEC_FECFRST(base_addr) &= ~FEC_SW_RST;
1370 +
1371 +       /* Reset and disable FEC */
1372 +       /* FEC_ECR(base_addr) = FEC_ECR_RESET; */
1373 +
1374 +       /* Enable FEC */
1375 +       FEC_ECR(base_addr) |= FEC_ECR_ETHEREN;
1376 +
1377 +       MCD_startDma(fp->fecpriv_fec_tx_channel, (char *) fp->fecpriv_txdesc, 0,
1378 +                    (unsigned char *) &(FEC_FECTFDR(base_addr)), 0,
1379 +                    FEC_MAX_FRM_SIZE, 0, fp->fecpriv_initiator_tx,
1380 +                    FEC_TX_DMA_PRI, MCD_FECTX_DMA | MCD_INTERRUPT,
1381 +                    MCD_NO_CSUM | MCD_NO_BYTE_SWAP);
1382 +
1383 +       spin_unlock_irq(&fp->fecpriv_lock);
1384 +
1385 +       netif_wake_queue(dev);
1386 +
1387 +}
1388 +
1389 +static const struct net_device_ops mcf547x_fec_netdev_ops = {
1390 +       .ndo_open = mcf547x_fec_open,
1391 +       .ndo_stop = mcf547x_fec_close,
1392 +       .ndo_start_xmit = mcf547x_fec_start_xmit,
1393 +       .ndo_set_multicast_list = mcf547x_fec_set_multicast_list,
1394 +       .ndo_set_mac_address = mcf547x_fec_set_mac_address,
1395 +       .ndo_tx_timeout = mcf547x_fec_tx_timeout,
1396 +       .ndo_get_stats = mcf547x_fec_get_stats,
1397 +};
1398 +
1399 +/*
1400 + * Initialize a FEC device
1401 + */
1402 +int fec_enet_init(struct net_device *dev, int slot)
1403 +{
1404 +       struct fec_priv *fp = netdev_priv(dev);
1405 +       int i;
1406 +
1407 +       fp->index = slot;
1408 +       fp->netdev = dev;
1409 +       fec_dev[slot] = dev;
1410 +
1411 +       if (slot == 0) {
1412 +               /* disable fec0 */
1413 +               FEC_ECR(FEC_BASE_ADDR_FEC0) = FEC_ECR_DISABLE;
1414 +
1415 +               /* setup the interrupt handler */
1416 +               dev->irq = 64 + ISC_FEC0;
1417 +
1418 +               if (request_irq(dev->irq, fec_interrupt_handler,
1419 +                       IRQF_DISABLED, "ColdFire FEC 0", dev)) {
1420 +                       dev->irq = 0;
1421 +                       printk(KERN_ERR "Cannot allocate FEC0 IRQ\n");
1422 +               } else {
1423 +                       /* interrupt priority and level */
1424 +                       MCF_ICR(ISC_FEC0) = ILP_FEC0;
1425 +               }
1426 +
1427 +               /* fec base address */
1428 +               dev->base_addr = FEC_BASE_ADDR_FEC0;
1429 +
1430 +               /* requestor numbers */
1431 +               fp->fecpriv_rx_requestor = DMA_FEC0_RX;
1432 +               fp->fecpriv_tx_requestor = DMA_FEC0_TX;
1433 +
1434 +               /* fec0 handlers */
1435 +               fp->fecpriv_interrupt_fec_rx_handler =
1436 +                       fec_interrupt_fec_rx_handler_fec0;
1437 +               fp->fecpriv_interrupt_fec_tx_handler =
1438 +                       fec_interrupt_fec_tx_handler_fec0;
1439 +
1440 +               /* tx descriptors */
1441 +               fp->fecpriv_txdesc = (void *)FEC_TX_DESC_FEC0;
1442 +
1443 +               /* rx descriptors */
1444 +               fp->fecpriv_rxdesc = (void *)FEC_RX_DESC_FEC0;
1445 +
1446 +               /* mac addr
1447 +               if (uboot_enet0[0] || uboot_enet0[1] || uboot_enet0[2] ||
1448 +                   uboot_enet0[3] || uboot_enet0[4] || uboot_enet0[5]) {
1449 +                        use uboot enet 0 addr
1450 +                       memcpy(fec_mac_addr_fec0, uboot_enet0, 6);
1451 +               }*/
1452 +               fec_mac_addr_fec0[0] =
1453 +                       (FEC_PALR(FEC_BASE_ADDR_FEC0) >> 24) & 0xFF;
1454 +               fec_mac_addr_fec0[1] =
1455 +                       (FEC_PALR(FEC_BASE_ADDR_FEC0) >> 16) & 0xFF;
1456 +               fec_mac_addr_fec0[2] =
1457 +                       (FEC_PALR(FEC_BASE_ADDR_FEC0) >> 8) & 0xFF;
1458 +               fec_mac_addr_fec0[3] =
1459 +                       (FEC_PALR(FEC_BASE_ADDR_FEC0)) & 0xFF;
1460 +               fec_mac_addr_fec0[4] =
1461 +                       (FEC_PAUR(FEC_BASE_ADDR_FEC0) >> 24) & 0xFF;
1462 +               fec_mac_addr_fec0[5] =
1463 +                       (FEC_PAUR(FEC_BASE_ADDR_FEC0) >> 16) & 0xFF;
1464 +
1465 +               fp->fecpriv_mac_addr = fec_mac_addr_fec0;
1466 +       } else {
1467 +               /* disable fec1 */
1468 +               FEC_ECR(FEC_BASE_ADDR_FEC1) = FEC_ECR_DISABLE;
1469 +#ifdef FEC_2
1470 +               /* setup the interrupt handler */
1471 +               dev->irq = 64 + ISC_FEC1;
1472 +
1473 +               if (request_irq(dev->irq, fec_interrupt_handler,
1474 +                       IRQF_DISABLED, "ColdFire FEC 1", dev)) {
1475 +                       dev->irq = 0;
1476 +                       printk(KERN_ERR "Cannot allocate FEC1 IRQ\n");
1477 +               } else {
1478 +                       /* interrupt priority and level */
1479 +                       MCF_ICR(ISC_FEC1) = ILP_FEC1;
1480 +               }
1481 +
1482 +               /* fec base address */
1483 +               dev->base_addr = FEC_BASE_ADDR_FEC1;
1484 +
1485 +               /* requestor numbers */
1486 +               fp->fecpriv_rx_requestor = DMA_FEC1_RX;
1487 +               fp->fecpriv_tx_requestor = DMA_FEC1_TX;
1488 +
1489 +               /* fec1 handlers */
1490 +               fp->fecpriv_interrupt_fec_rx_handler =
1491 +                       fec_interrupt_fec_rx_handler_fec1;
1492 +               fp->fecpriv_interrupt_fec_tx_handler =
1493 +                       fec_interrupt_fec_tx_handler_fec1;
1494 +
1495 +               /* tx descriptors */
1496 +               fp->fecpriv_txdesc = (void *)FEC_TX_DESC_FEC1;
1497 +
1498 +               /* rx descriptors */
1499 +               fp->fecpriv_rxdesc = (void *)FEC_RX_DESC_FEC1;
1500 +
1501 +               /* mac addr
1502 +               if (uboot_enet1[0] || uboot_enet1[1] || uboot_enet1[2] ||
1503 +                   uboot_enet1[3] || uboot_enet1[4] || uboot_enet1[5]) {
1504 +                       use uboot enet 1 addr
1505 +                       memcpy(fec_mac_addr_fec1, uboot_enet1, 6);
1506 +               }*/
1507 +               fec_mac_addr_fec1[0] =
1508 +                       (FEC_PALR(FEC_BASE_ADDR_FEC1) >> 24) & 0xFF;
1509 +               fec_mac_addr_fec1[1] =
1510 +                       (FEC_PALR(FEC_BASE_ADDR_FEC1) >> 16) & 0xFF;
1511 +               fec_mac_addr_fec1[2] =
1512 +                       (FEC_PALR(FEC_BASE_ADDR_FEC1) >> 8) & 0xFF;
1513 +               fec_mac_addr_fec1[3] =
1514 +                       (FEC_PALR(FEC_BASE_ADDR_FEC1)) & 0xFF;
1515 +               fec_mac_addr_fec1[4] =
1516 +                       (FEC_PAUR(FEC_BASE_ADDR_FEC1) >> 24) & 0xFF;
1517 +               fec_mac_addr_fec1[5] =
1518 +                       (FEC_PAUR(FEC_BASE_ADDR_FEC1) >> 16) & 0xFF;
1519 +
1520 +               fp->fecpriv_mac_addr = fec_mac_addr_fec1;
1521 +#endif
1522 +       }
1523 +
1524 +       /* clear MIB */
1525 +       memset((void *) (dev->base_addr + 0x200), 0, FEC_MIB_LEN);
1526 +
1527 +       /* clear the statistics structure */
1528 +       memset((void *) &(fp->fecpriv_stat), 0,
1529 +              sizeof(struct net_device_stats));
1530 +
1531 +       /* grab the FEC initiators */
1532 +       dma_set_initiator(fp->fecpriv_tx_requestor);
1533 +       fp->fecpriv_initiator_tx = dma_get_initiator(fp->fecpriv_tx_requestor);
1534 +       dma_set_initiator(fp->fecpriv_rx_requestor);
1535 +       fp->fecpriv_initiator_rx = dma_get_initiator(fp->fecpriv_rx_requestor);
1536 +
1537 +       /* reset the DMA channels */
1538 +       fp->fecpriv_fec_rx_channel = -1;
1539 +       fp->fecpriv_fec_tx_channel = -1;
1540 +
1541 +       for (i = 0; i < FEC_RX_BUF_NUMBER; i++)
1542 +               fp->askb_rx[i] = NULL;
1543 +
1544 +       /* initialize the pointers to the socket buffers */
1545 +       for (i = 0; i < FEC_TX_BUF_NUMBER; i++)
1546 +               fp->fecpriv_txbuf[i] = NULL;
1547 +
1548 +       ether_setup(dev);
1549 +
1550 +       dev->netdev_ops = &mcf547x_fec_netdev_ops;
1551 +       dev->watchdog_timeo = FEC_TX_TIMEOUT * HZ;
1552 +
1553 +       memcpy(dev->dev_addr, fp->fecpriv_mac_addr, ETH_ALEN);
1554 +
1555 +       spin_lock_init(&fp->fecpriv_lock);
1556 +
1557 +       /* Initialize FEC/I2C/IRQ Pin Assignment Register*/
1558 +       FEC_GPIO_PAR_FECI2CIRQ &= 0xF;
1559 +       FEC_GPIO_PAR_FECI2CIRQ |= FEC_FECI2CIRQ;
1560 +
1561 +       return 0;
1562 +}
1563 +
1564 +/*
1565 + * Module Initialization
1566 + */
1567 +int __init fec_init(void)
1568 +{
1569 +       struct net_device *dev;
1570 +       int i;
1571 +       int err;
1572 +       struct fec_priv *fep;
1573 +
1574 +       printk(KERN_INFO "FEC ENET (DMA) Version %s\n", VERSION);
1575 +
1576 +       for (i = 0; i < FEC_MAX_PORTS; i++) {
1577 +               dev = alloc_etherdev(sizeof(struct fec_priv));
1578 +               if (!dev)
1579 +                       return -ENOMEM;
1580 +               err = fec_enet_init(dev, i);
1581 +               if (err) {
1582 +                       free_netdev(dev);
1583 +                       continue;
1584 +               }
1585 +
1586 +               fep = netdev_priv(dev);
1587 +               FEC_MSCR(dev->base_addr) = FEC_MII_SPEED;
1588 +#ifdef CONFIG_FEC_548x_SHARED_PHY
1589 +               if (i == 0)
1590 +                       err = fec_mdio_register(dev, i);
1591 +               else {
1592 +                       struct fec_priv *priv0 = netdev_priv(fec_dev[0]);
1593 +                       fep->mdio_bus = priv0->mdio_bus;
1594 +                       printk(KERN_INFO "FEC%d SHARED the %s ok\n",
1595 +                               i, fep->mdio_bus->name);
1596 +               }
1597 +#else
1598 +               err = fec_mdio_register(dev, i);
1599 +#endif
1600 +               if (err) {
1601 +                       printk(KERN_ERR "%s: ethernet fec_mdio_register\n",
1602 +                               dev->name);
1603 +                       free_netdev(dev);
1604 +                       return -ENOMEM;
1605 +               }
1606 +
1607 +               if (register_netdev(dev) != 0) {
1608 +                       free_netdev(dev);
1609 +                       return -EIO;
1610 +               }
1611 +
1612 +               printk(KERN_INFO "%s: ethernet %s\n",
1613 +                               dev->name, dev->dev_addr);
1614 +       }
1615 +       return 0;
1616 +}
1617 +
1618 +/*
1619 + * Stop a device
1620 + */
1621 +void fec_stop(struct net_device *dev)
1622 +{
1623 +       struct fec_priv *fp = netdev_priv(dev);
1624 +
1625 +       dma_remove_initiator(fp->fecpriv_initiator_tx);
1626 +       dma_remove_initiator(fp->fecpriv_initiator_rx);
1627 +
1628 +       if (dev->irq)
1629 +               free_irq(dev->irq, dev);
1630 +}
1631 +
1632 +/************************************************************************
1633 +* NAME: fec_interrupt_tx_handler
1634 +*
1635 +* DESCRIPTION: This function is called when the data
1636 +*              transmission from the buffer to the FEC is completed.
1637 +*
1638 +*************************************************************************/
1639 +void fec_interrupt_fec_tx_handler(struct net_device *dev)
1640 +{
1641 +       struct fec_priv *fp = netdev_priv(dev);
1642 +
1643 +       /* Release the socket buffer */
1644 +       kfree(fp->fecpriv_txbuf[fp->fecpriv_current_tx]);
1645 +       fp->fecpriv_txbuf[fp->fecpriv_current_tx] = NULL;
1646 +
1647 +       fp->fecpriv_current_tx =
1648 +               (fp->fecpriv_current_tx + 1) & FEC_TX_INDEX_MASK;
1649 +
1650 +       if (MCD_dmaStatus(fp->fecpriv_fec_tx_channel) == MCD_DONE) {
1651 +               for (; fp->fecpriv_current_tx != fp->fecpriv_next_tx;
1652 +                       fp->fecpriv_current_tx =
1653 +                       (fp->fecpriv_current_tx + 1)
1654 +                       & FEC_TX_INDEX_MASK) {
1655 +                       if (fp->fecpriv_txbuf[fp->fecpriv_current_tx]) {
1656 +                               kfree(fp->fecpriv_txbuf[
1657 +                                       fp->fecpriv_current_tx]);
1658 +                               fp->fecpriv_txbuf[fp->fecpriv_current_tx]
1659 +                                       = NULL;
1660 +                       }
1661 +               }
1662 +       }
1663 +
1664 +       if (netif_queue_stopped(dev))
1665 +               netif_wake_queue(dev);
1666 +}
1667 +
1668 +/************************************************************************
1669 +* NAME: fec_interrupt_rx_handler
1670 +*
1671 +* DESCRIPTION: This function is called when the data
1672 +*              reception from the FEC to the reception buffer is completed.
1673 +*
1674 +*************************************************************************/
1675 +void fec_interrupt_fec_rx_handler(struct net_device *dev)
1676 +{
1677 +       struct fec_priv *fp = netdev_priv(dev);
1678 +       struct sk_buff *skb;
1679 +       int i;
1680 +
1681 +       fp->fecpriv_rxflag = 1;
1682 +       /* Some buffers can be missed */
1683 +       if (!(fp->fecpriv_rxdesc[fp->fecpriv_current_rx].statCtrl
1684 +                       & MCD_FEC_END_FRAME)) {
1685 +               /* Find a valid index */
1686 +               for (i = 0; ((i < FEC_RX_BUF_NUMBER) &&
1687 +                       !(fp->fecpriv_rxdesc[
1688 +                       fp->fecpriv_current_rx].statCtrl
1689 +                       & MCD_FEC_END_FRAME)); i++,
1690 +                       (fp->fecpriv_current_rx =
1691 +                       (fp->fecpriv_current_rx + 1)
1692 +                       & FEC_RX_INDEX_MASK))
1693 +                       ;
1694 +
1695 +               if (i == FEC_RX_BUF_NUMBER) {
1696 +                       /* There are no data to process */
1697 +                       /* Tell the DMA to continue the reception */
1698 +                       MCD_continDma(fp->fecpriv_fec_rx_channel);
1699 +
1700 +                       fp->fecpriv_rxflag = 0;
1701 +
1702 +                       return;
1703 +               }
1704 +       }
1705 +
1706 +       for (; fp->fecpriv_rxdesc[fp->fecpriv_current_rx].statCtrl
1707 +                       & MCD_FEC_END_FRAME;
1708 +               fp->fecpriv_current_rx = (fp->fecpriv_current_rx + 1)
1709 +                                               & FEC_RX_INDEX_MASK) {
1710 +               if ((fp->fecpriv_rxdesc[fp->fecpriv_current_rx].length
1711 +                       <= FEC_MAXBUF_SIZE) &&
1712 +                       (fp->fecpriv_rxdesc[fp->fecpriv_current_rx].length
1713 +                               > 4)) {
1714 +                       /* --tym-- */
1715 +                       skb = fp->askb_rx[fp->fecpriv_current_rx];
1716 +                       if (!skb)
1717 +                               fp->fecpriv_stat.rx_dropped++;
1718 +                       else {
1719 +                       /*
1720 +                       * flush data cache before initializing
1721 +                       * the descriptor and starting DMA
1722 +                       */
1723 +                               skb_put(skb,
1724 +                                       (fp->fecpriv_rxdesc[
1725 +                                        fp->fecpriv_current_rx].length - 4));
1726 +                               skb->protocol = eth_type_trans(skb, dev);
1727 +                               netif_rx(skb);
1728 +                       }
1729 +                       fp->fecpriv_rxdesc[fp->fecpriv_current_rx].statCtrl &=
1730 +                               ~MCD_FEC_END_FRAME;
1731 +                       /* allocate new skbuff */
1732 +                       fp->askb_rx[fp->fecpriv_current_rx] =
1733 +                               alloc_skb(FEC_MAXBUF_SIZE + 16,
1734 +                                       /*GFP_ATOMIC |*/ GFP_DMA);
1735 +                       if (!fp->askb_rx[fp->fecpriv_current_rx]) {
1736 +                               fp->fecpriv_rxdesc[
1737 +                               fp->fecpriv_current_rx].dataPointer
1738 +                                       = 0;
1739 +                               fp->fecpriv_rxdesc[
1740 +                                       fp->fecpriv_current_rx].length = 0;
1741 +                               fp->fecpriv_stat.rx_dropped++;
1742 +                       } else {
1743 +                               skb_reserve(
1744 +                               fp->askb_rx[fp->fecpriv_current_rx], 16);
1745 +                               fp->askb_rx[fp->fecpriv_current_rx]->dev = dev;
1746 +
1747 +                               /*
1748 +                                * flush data cache before initializing
1749 +                                * the descriptor and starting DMA
1750 +                                */
1751 +
1752 +                               fp->fecpriv_rxdesc[
1753 +                                       fp->fecpriv_current_rx].dataPointer =
1754 +                                       (unsigned int) virt_to_phys(
1755 +                                       fp->askb_rx[
1756 +                                               fp->fecpriv_current_rx]->tail);
1757 +                               fp->fecpriv_rxdesc[
1758 +                                       fp->fecpriv_current_rx].length =
1759 +                                       FEC_MAXBUF_SIZE;
1760 +                               fp->fecpriv_rxdesc[
1761 +                                       fp->fecpriv_current_rx].statCtrl |=
1762 +                                       MCD_FEC_BUF_READY;
1763 +
1764 +                               /*
1765 +                                * flush data cache before initializing
1766 +                                * the descriptor and starting DMA
1767 +                                */
1768 +                       }
1769 +               }
1770 +
1771 +       }
1772 +
1773 +       /* Tell the DMA to continue the reception */
1774 +       MCD_continDma(fp->fecpriv_fec_rx_channel);
1775 +
1776 +       fp->fecpriv_rxflag = 0;
1777 +}
1778 +
1779 +/************************************************************************
1780 +* NAME: fec_interrupt_handler
1781 +*
1782 +* DESCRIPTION: This function is called when some special errors occur
1783 +*
1784 +*************************************************************************/
1785 +irqreturn_t fec_interrupt_handler(int irq, void *dev_id)
1786 +{
1787 +
1788 +       struct net_device *dev = (struct net_device *)dev_id;
1789 +       struct fec_priv *fp = netdev_priv(dev);
1790 +       unsigned long base_addr = (unsigned long) dev->base_addr;
1791 +       unsigned long events;
1792 +
1793 +       /* Read and clear the events */
1794 +       events = FEC_EIR(base_addr) & FEC_EIMR(base_addr);
1795 +
1796 +       if (events & FEC_EIR_HBERR) {
1797 +               fp->fecpriv_stat.tx_heartbeat_errors++;
1798 +               FEC_EIR(base_addr) = FEC_EIR_HBERR;
1799 +       }
1800 +
1801 +       /* receive/transmit FIFO error */
1802 +       if (((events & FEC_EIR_RFERR) != 0)
1803 +               || ((events & FEC_EIR_XFERR) != 0)) {
1804 +               /* kill DMA receive channel */
1805 +               MCD_killDma(fp->fecpriv_fec_rx_channel);
1806 +
1807 +               /* kill running transmission by DMA */
1808 +               MCD_killDma(fp->fecpriv_fec_tx_channel);
1809 +
1810 +               /* Reset FIFOs */
1811 +               FEC_FECFRST(base_addr) |= FEC_SW_RST;
1812 +               FEC_FECFRST(base_addr) &= ~FEC_SW_RST;
1813 +
1814 +               /* reset receive FIFO status register */
1815 +               FEC_FECRFSR(base_addr) = FEC_FECRFSR_FAE |
1816 +                                        FEC_FECRFSR_RXW |
1817 +                                        FEC_FECRFSR_UF;
1818 +
1819 +               /* reset transmit FIFO status register */
1820 +               FEC_FECTFSR(base_addr) = FEC_FECTFSR_FAE |
1821 +                                        FEC_FECTFSR_TXW |
1822 +                                        FEC_FECTFSR_UF |
1823 +                                        FEC_FECTFSR_OF;
1824 +
1825 +               /* reset RFERR and XFERR event */
1826 +               FEC_EIR(base_addr) = FEC_EIR_RFERR | FEC_EIR_XFERR;
1827 +
1828 +               /* stop queue */
1829 +               netif_stop_queue(dev);
1830 +
1831 +               /* execute reinitialization as tasklet */
1832 +               tasklet_schedule(&fp->fecpriv_tasklet_reinit);
1833 +
1834 +               fp->fecpriv_stat.rx_dropped++;
1835 +       }
1836 +
1837 +       /* transmit FIFO underrun */
1838 +       if ((events & FEC_EIR_XFUN) != 0) {
1839 +               /* reset XFUN event */
1840 +               FEC_EIR(base_addr) = FEC_EIR_XFUN;
1841 +               fp->fecpriv_stat.tx_aborted_errors++;
1842 +       }
1843 +
1844 +       /* late collision */
1845 +       if ((events & FEC_EIR_LC) != 0) {
1846 +               /* reset LC event */
1847 +               FEC_EIR(base_addr) = FEC_EIR_LC;
1848 +               fp->fecpriv_stat.tx_aborted_errors++;
1849 +       }
1850 +
1851 +       /* collision retry limit */
1852 +       if ((events & FEC_EIR_RL) != 0) {
1853 +               /* reset RL event */
1854 +               FEC_EIR(base_addr) = FEC_EIR_RL;
1855 +               fp->fecpriv_stat.tx_aborted_errors++;
1856 +       }
1857 +       return 0;
1858 +}
1859 +
1860 +/************************************************************************
1861 +* NAME: fec_interrupt_reinit
1862 +*
1863 +* DESCRIPTION: This function is called from interrupt handler
1864 +*              when controller must be reinitialized.
1865 +*
1866 +*************************************************************************/
1867 +void fec_interrupt_fec_reinit(unsigned long data)
1868 +{
1869 +       int i;
1870 +       struct net_device *dev = (struct net_device *)data;
1871 +       struct fec_priv *fp = netdev_priv(dev);
1872 +       unsigned long base_addr = (unsigned long) dev->base_addr;
1873 +
1874 +       /* Initialize reception descriptors and start DMA for the reception */
1875 +       for (i = 0; i < FEC_RX_BUF_NUMBER; i++) {
1876 +               if (!fp->askb_rx[i]) {
1877 +                       fp->askb_rx[i] = alloc_skb(FEC_MAXBUF_SIZE + 16,
1878 +                                       GFP_ATOMIC | GFP_DMA);
1879 +                       if (!fp->askb_rx[i]) {
1880 +                               fp->fecpriv_rxdesc[i].dataPointer = 0;
1881 +                               fp->fecpriv_rxdesc[i].statCtrl = 0;
1882 +                               fp->fecpriv_rxdesc[i].length = 0;
1883 +                               continue;
1884 +                       }
1885 +                       fp->askb_rx[i]->dev = dev;
1886 +                       skb_reserve(fp->askb_rx[i], 16);
1887 +               }
1888 +               fp->fecpriv_rxdesc[i].dataPointer =
1889 +                       (unsigned int) virt_to_phys(fp->askb_rx[i]->tail);
1890 +               fp->fecpriv_rxdesc[i].statCtrl =
1891 +                       MCD_FEC_BUF_READY | MCD_FEC_INTERRUPT;
1892 +               fp->fecpriv_rxdesc[i].length = FEC_MAXBUF_SIZE;
1893 +       }
1894 +
1895 +       fp->fecpriv_rxdesc[i - 1].statCtrl |= MCD_FEC_WRAP;
1896 +       fp->fecpriv_current_rx = 0;
1897 +
1898 +       /* restart frame transmission */
1899 +       for (i = 0; i < FEC_TX_BUF_NUMBER; i++) {
1900 +               kfree(fp->fecpriv_txbuf[i]);
1901 +               fp->fecpriv_txbuf[i] = NULL;
1902 +               fp->fecpriv_stat.tx_dropped++;
1903 +               fp->fecpriv_txdesc[i].statCtrl = MCD_FEC_INTERRUPT;
1904 +       }
1905 +       fp->fecpriv_txdesc[i - 1].statCtrl |= MCD_FEC_WRAP;
1906 +       fp->fecpriv_current_tx = fp->fecpriv_next_tx = 0;
1907 +
1908 +       /* flush entire data cache before restarting the DMA */
1909 +
1910 +       /* restart DMA from beginning */
1911 +       MCD_startDma(fp->fecpriv_fec_rx_channel,
1912 +                    (char *) fp->fecpriv_rxdesc, 0,
1913 +                    (unsigned char *) &(FEC_FECRFDR(base_addr)), 0,
1914 +                    FEC_MAX_FRM_SIZE, 0, fp->fecpriv_initiator_rx,
1915 +                    FEC_RX_DMA_PRI, MCD_FECRX_DMA | MCD_INTERRUPT,
1916 +                    MCD_NO_CSUM | MCD_NO_BYTE_SWAP);
1917 +
1918 +       MCD_startDma(fp->fecpriv_fec_tx_channel, (char *) fp->fecpriv_txdesc, 0,
1919 +                    (unsigned char *) &(FEC_FECTFDR(base_addr)), 0,
1920 +                    FEC_MAX_FRM_SIZE, 0, fp->fecpriv_initiator_tx,
1921 +                    FEC_TX_DMA_PRI, MCD_FECTX_DMA | MCD_INTERRUPT,
1922 +                    MCD_NO_CSUM | MCD_NO_BYTE_SWAP);
1923 +
1924 +       /* Enable FEC */
1925 +       FEC_ECR(base_addr) |= FEC_ECR_ETHEREN;
1926 +
1927 +       netif_wake_queue(dev);
1928 +}
1929 +
1930 +/************************************************************************
1931 +* NAME: fec_interrupt_tx_handler_fec0
1932 +*
1933 +* DESCRIPTION: This is the DMA interrupt handler using  for FEC0
1934 +*              transmission.
1935 +*
1936 +*************************************************************************/
1937 +void fec_interrupt_fec_tx_handler_fec0(void)
1938 +{
1939 +       fec_interrupt_fec_tx_handler(fec_dev[0]);
1940 +}
1941 +
1942 +#ifdef FEC_2
1943 +/************************************************************************
1944 +* NAME: fec_interrupt_tx_handler_fec1
1945 +*
1946 +* DESCRIPTION: This is the DMA interrupt handler using for the FEC1
1947 +*              transmission.
1948 +*
1949 +*************************************************************************/
1950 +void fec_interrupt_fec_tx_handler_fec1(void)
1951 +{
1952 +       fec_interrupt_fec_tx_handler(fec_dev[1]);
1953 +}
1954 +#endif
1955 +
1956 +/************************************************************************
1957 +* NAME: fec_interrupt_rx_handler_fec0
1958 +*
1959 +* DESCRIPTION: This is the DMA interrupt handler using for the FEC0
1960 +*              reception.
1961 +*
1962 +*************************************************************************/
1963 +void fec_interrupt_fec_rx_handler_fec0(void)
1964 +{
1965 +       fec_interrupt_fec_rx_handler(fec_dev[0]);
1966 +}
1967 +
1968 +#ifdef FEC_2
1969 +/************************************************************************
1970 +* NAME: fec_interrupt_rx_handler_fec1
1971 +*
1972 +* DESCRIPTION: This is the DMA interrupt handler using for the FEC1
1973 +*              reception.
1974 +*
1975 +*************************************************************************/
1976 +void fec_interrupt_fec_rx_handler_fec1(void)
1977 +{
1978 +       fec_interrupt_fec_rx_handler(fec_dev[1]);
1979 +}
1980 +
1981 +#endif
1982 +
1983 +#ifndef MODULE
1984 +/************************************************************************
1985 +* NAME: fec_mac_setup0
1986 +*
1987 +* DESCRIPTION: This function sets the MAC address of FEC0 from command line
1988 +*
1989 +*************************************************************************/
1990 +int __init fec_mac_setup0(char *s)
1991 +{
1992 +       if (!s || !*s)
1993 +               return 1;
1994 +
1995 +       if (fec_str_to_mac(s, fec_mac_addr_fec0))
1996 +               printk(KERN_ERR "The MAC address of FEC0 "
1997 +                       "cannot be set from command line");
1998 +       return 1;
1999 +}
2000 +
2001 +#ifdef FEC_2
2002 +
2003 +/************************************************************************
2004 +* NAME: fec_mac_setup1
2005 +*
2006 +* DESCRIPTION: This function sets the MAC address of FEC1 from command line
2007 +*
2008 +*************************************************************************/
2009 +int __init fec_mac_setup1(char *s)
2010 +{
2011 +       if (!s || !*s)
2012 +               return 1;
2013 +
2014 +       if (fec_str_to_mac(s, fec_mac_addr_fec1))
2015 +               printk(KERN_ERR "The MAC address of FEC1 "
2016 +                       "cannot be set from command line\n");
2017 +       return 1;
2018 +}
2019 +#endif
2020 +
2021 +/************************************************************************
2022 +* NAME: fec_str_to_mac
2023 +*
2024 +* DESCRIPTION: This function interprets the character string into MAC addr
2025 +*
2026 +*************************************************************************/
2027 +int fec_str_to_mac(char *str_mac, unsigned char* addr)
2028 +{
2029 +       unsigned long val;
2030 +       char c;
2031 +       unsigned long octet[6], *octetptr = octet;
2032 +       int i;
2033 +
2034 +again:
2035 +       val = 0;
2036 +       while ((c = *str_mac) != '\0') {
2037 +               if ((c >= '0') && (c <= '9')) {
2038 +                       val = (val * 16) + (c - '0');
2039 +                       str_mac++;
2040 +                       continue;
2041 +               } else if (((c >= 'a') && (c <= 'f'))
2042 +                       || ((c >= 'A') && (c <= 'F'))) {
2043 +                       val = (val << 4) +
2044 +                               (c + 10 -
2045 +                               (((c >= 'a') && (c <= 'f')) ? 'a' : 'A'));
2046 +                       str_mac++;
2047 +                       continue;
2048 +               }
2049 +               break;
2050 +       }
2051 +       if (*str_mac == ':') {
2052 +               *octetptr++ = val, str_mac++;
2053 +               if (octetptr >= octet + 6)
2054 +                       return 1;
2055 +               goto again;
2056 +       }
2057 +
2058 +       /* Check for trailing characters */
2059 +       if (*str_mac && !(*str_mac == ' '))
2060 +               return 1;
2061 +
2062 +       *octetptr++ = val;
2063 +
2064 +       if ((octetptr - octet) == 6) {
2065 +               for (i = 0; i <= 6; i++)
2066 +                       addr[i] = octet[i];
2067 +       } else
2068 +               return 1;
2069 +
2070 +       return 0;
2071 +}
2072 +#endif
2073 --- /dev/null
2074 +++ b/drivers/net/fec_m547x.h
2075 @@ -0,0 +1,241 @@
2076 +#ifndef FEC_M547X_H
2077 +#define        FEC_M547X_H
2078 +/*
2079 + * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
2080 + *
2081 + * This program is free software; you can redistribute it and/or modify
2082 + * it under the terms of the GNU General Public License as published by
2083 + * the Free Software Foundation; either version 2 of the License, or
2084 + * (at your option) any later version.
2085 + */
2086 +
2087 +#define   FEC_BASE_ADDR_FEC0                ((unsigned int)MCF_MBAR + 0x9000)
2088 +#define   FEC_BASE_ADDR_FEC1                ((unsigned int)MCF_MBAR + 0x9800)
2089 +
2090 +#define   FEC_FECI2CIRQ                     (0xFFC0)
2091 +#define   FEC_GPIO_PAR_FECI2CIRQ            \
2092 +       (*(volatile unsigned short *)((unsigned int)MCF_MBAR + 0xA44))
2093 +
2094 +#define   FEC_ECR_DISABLE                   (0x00000000)
2095 +
2096 +#define   FEC_ECR(x)                        \
2097 +       (*(volatile unsigned int *)(x + 0x024))
2098 +#define   FEC_EIR(x)                        \
2099 +       (*(volatile unsigned int *)(x + 0x004))
2100 +#define   FEC_PALR(x)                       \
2101 +       (*(volatile unsigned int *)(x + 0x0E4))
2102 +#define   FEC_PAUR(x)                       \
2103 +       (*(volatile unsigned int *)(x + 0x0E8))
2104 +#define   FEC_IALR(x)                       \
2105 +       (*(volatile unsigned int *)(x + 0x11C))
2106 +#define   FEC_IAUR(x)                       \
2107 +       (*(volatile unsigned int *)(x + 0x118))
2108 +#define   FEC_GALR(x)                       \
2109 +       (*(volatile unsigned int *)(x + 0x124))
2110 +#define   FEC_GAUR(x)                       \
2111 +       (*(volatile unsigned int *)(x + 0x120))
2112 +#define   FEC_RCR(x)                        \
2113 +       (*(volatile unsigned int *)(x + 0x084))
2114 +#define   FEC_FECRFCR(x)                    \
2115 +       (*(volatile unsigned int *)(x + 0x18C))
2116 +#define   FEC_FECRFAR(x)                    \
2117 +       (*(volatile unsigned int *)(x + 0x198))
2118 +#define   FEC_FECTFCR(x)                    \
2119 +       (*(volatile unsigned int *)(x + 0x1AC))
2120 +#define   FEC_FECTFAR(x)                    \
2121 +       (*(volatile unsigned int *)(x + 0x1B8))
2122 +#define   FEC_FECTFWR(x)                    \
2123 +       (*(volatile unsigned int *)(x + 0x144))
2124 +#define   FEC_CTCWR(x)                      \
2125 +       (*(volatile unsigned int *)(x + 0x1C8))
2126 +#define   FEC_EIMR(x)                       \
2127 +       (*(volatile unsigned int *)(x + 0x008))
2128 +#define   FEC_TCR(x)                        \
2129 +       (*(volatile unsigned int *)(x + 0x0C4))
2130 +#define   FEC_MIBC(x)                       \
2131 +       (*(volatile unsigned int *)(x + 0x064))
2132 +#define   FEC_MSCR(x)                       \
2133 +       (*(volatile unsigned int *)(x + 0x044))
2134 +#define   FEC_FECTFDR(x)                    \
2135 +       (*(volatile unsigned int *)(x + 0x1A4))
2136 +#define   FEC_FECRFDR(x)                    \
2137 +       (*(volatile unsigned int *)(x + 0x184))
2138 +#define   FEC_FECTFSR(x)                    \
2139 +       (*(volatile unsigned int *)(x + 0x1A8))
2140 +#define   FEC_FECRFSR(x)                   \
2141 +       (*(volatile unsigned int *)(x + 0x188))
2142 +#define   FECSTAT_RMON_R_PACKETS(x)         \
2143 +       (*(volatile unsigned int *)(x + 0x284))
2144 +#define   FECSTAT_RMON_T_PACKETS(x)         \
2145 +       (*(volatile unsigned int *)(x + 0x204))
2146 +#define   FECSTAT_RMON_R_OCTETS(x)          \
2147 +       (*(volatile unsigned int *)(x + 0x2C4))
2148 +#define   FECSTAT_RMON_T_OCTETS(x)          \
2149 +       (*(volatile unsigned int *)(x + 0x244))
2150 +#define   FECSTAT_RMON_R_UNDERSIZE(x)       \
2151 +       (*(volatile unsigned int *)(x + 0x294))
2152 +#define   FECSTAT_RMON_R_OVERSIZE(x)        \
2153 +       (*(volatile unsigned int *)(x + 0x298))
2154 +#define   FECSTAT_RMON_R_FRAG(x)            \
2155 +       (*(volatile unsigned int *)(x + 0x29C))
2156 +#define   FECSTAT_RMON_R_JAB(x)             \
2157 +       (*(volatile unsigned int *)(x + 0x2A0))
2158 +#define   FECSTAT_RMON_R_MC_PKT(x)          \
2159 +       (*(volatile unsigned int *)(x + 0x28C))
2160 +#define   FECSTAT_RMON_T_COL(x)             \
2161 +       (*(volatile unsigned int *)(x + 0x224))
2162 +#define   FECSTAT_IEEE_R_ALIGN(x)           \
2163 +       (*(volatile unsigned int *)(x + 0x2D4))
2164 +#define   FECSTAT_IEEE_R_CRC(x)             \
2165 +       (*(volatile unsigned int *)(x + 0x2D0))
2166 +#define   FECSTAT_IEEE_R_MACERR(x)          \
2167 +       (*(volatile unsigned int *)(x + 0x2D8))
2168 +#define   FECSTAT_IEEE_T_CSERR(x)           \
2169 +       (*(volatile unsigned int *)(x + 0x268))
2170 +#define   FECSTAT_IEEE_T_MACERR(x)          \
2171 +       (*(volatile unsigned int *)(x + 0x264))
2172 +#define   FECSTAT_IEEE_T_LCOL(x)            \
2173 +       (*(volatile unsigned int *)(x + 0x25C))
2174 +#define   FECSTAT_IEEE_R_OCTETS_OK(x)       \
2175 +       (*(volatile unsigned int *)(x + 0x2E0))
2176 +#define   FECSTAT_IEEE_T_OCTETS_OK(x)       \
2177 +       (*(volatile unsigned int *)(x + 0x274))
2178 +#define   FECSTAT_IEEE_R_DROP(x)            \
2179 +       (*(volatile unsigned int *)(x + 0x2C8))
2180 +#define   FECSTAT_IEEE_T_DROP(x)            \
2181 +       (*(volatile unsigned int *)(x + 0x248))
2182 +#define   FECSTAT_IEEE_R_FRAME_OK(x)        \
2183 +       (*(volatile unsigned int *)(x + 0x2CC))
2184 +#define   FECSTAT_IEEE_T_FRAME_OK(x)        \
2185 +       (*(volatile unsigned int *)(x + 0x24C))
2186 +#define   FEC_MMFR(x)                       \
2187 +       (*(volatile unsigned int *)(x + 0x040))
2188 +#define   FEC_FECFRST(x)                    \
2189 +       (*(volatile unsigned int *)(x + 0x1C4))
2190 +
2191 +#define   FEC_MAX_FRM_SIZE                  (1518)
2192 +#define   FEC_MAXBUF_SIZE                   (1520)
2193 +
2194 +/* Register values */
2195 +#define   FEC_ECR_RESET                     (0x00000001)
2196 +#define   FEC_EIR_CLEAR                     (0xFFFFFFFF)
2197 +#define   FEC_EIR_RL                        (0x00100000)
2198 +#define   FEC_EIR_HBERR                     (0x80000000)
2199 +#define   FEC_EIR_BABR                     (0x40000000)
2200 +/* babbling receive error */
2201 +#define   FEC_EIR_BABT                     (0x20000000)
2202 +/* babbling transmit error */
2203 +#define   FEC_EIR_TXF                      (0x08000000)
2204 +/* transmit frame interrupt */
2205 +#define   FEC_EIR_MII                      (0x00800000)
2206 +/* MII interrupt */
2207 +#define   FEC_EIR_LC                       (0x00200000)
2208 +/* late collision */
2209 +#define   FEC_EIR_XFUN                     (0x00080000)
2210 +/* transmit FIFO underrun */
2211 +#define   FEC_EIR_XFERR                            (0x00040000)
2212 +/* transmit FIFO error */
2213 +#define   FEC_EIR_RFERR                            (0x00020000)
2214 +/* receive FIFO error */
2215 +#define   FEC_RCR_MAX_FRM_SIZE              (FEC_MAX_FRM_SIZE << 16)
2216 +#define   FEC_RCR_MII                       (0x00000004)
2217 +#define   FEC_FECRFCR_FAE                  (0x00400000)
2218 +/* frame accept error */
2219 +#define   FEC_FECRFCR_RXW                  (0x00200000)
2220 +/* receive wait condition */
2221 +#define   FEC_FECRFCR_UF                   (0x00100000)
2222 +/* receive FIFO underflow */
2223 +#define   FEC_FECRFCR_FRM                   (0x08000000)
2224 +#define   FEC_FECRFCR_GR                    (0x7 << 24)
2225 +
2226 +#define   FEC_EIMR_DISABLE                 (0x00000000)
2227 +
2228 +#define   FEC_FECRFAR_ALARM                 (0x300)
2229 +#define   FEC_FECTFCR_FRM                   (0x08000000)
2230 +#define   FEC_FECTFCR_GR                    (0x7 << 24)
2231 +#define   FEC_FECTFCR_FAE                  (0x00400000)
2232 +/* frame accept error */
2233 +#define   FEC_FECTFCR_TXW                  (0x00040000)
2234 +/* transmit wait condition */
2235 +#define   FEC_FECTFCR_UF                   (0x00100000)
2236 +/* transmit FIFO underflow */
2237 +#define   FEC_FECTFCR_OF                   (0x00080000)
2238 +/* transmit FIFO overflow */
2239 +
2240 +#define   FEC_FECTFAR_ALARM                 (0x100)
2241 +#define   FEC_FECTFWR_XWMRK                 (0x00000000)
2242 +
2243 +#define   FEC_FECTFSR_MSK                   (0xC0B00000)
2244 +#define   FEC_FECTFSR_TXW                   (0x40000000)
2245 +/* transmit wait condition */
2246 +#define   FEC_FECTFSR_FAE                   (0x00800000)
2247 +/* frame accept error */
2248 +#define   FEC_FECTFSR_UF                    (0x00200000)
2249 +/* transmit FIFO underflow */
2250 +#define   FEC_FECTFSR_OF                    (0x00100000)
2251 +/* transmit FIFO overflow */
2252 +
2253 +#define   FEC_FECRFSR_MSK                   (0x80F00000)
2254 +#define   FEC_FECRFSR_FAE                   (0x00800000)
2255 +/* frame accept error */
2256 +#define   FEC_FECRFSR_RXW                   (0x00400000)
2257 +/* receive wait condition */
2258 +#define   FEC_FECRFSR_UF                    (0x00200000)
2259 +/* receive FIFO underflow */
2260 +
2261 +#define   FEC_CTCWR_TFCW_CRC                (0x03000000)
2262 +#define   FEC_TCR_FDEN                      (0x00000004)
2263 +#define   FEC_TCR_HBC                       (0x00000002)
2264 +#define   FEC_RCR_DRT                       (0x00000002)
2265 +#define   FEC_EIMR_MASK                     (FEC_EIR_RL | FEC_EIR_HBERR)
2266 +#define   FEC_ECR_ETHEREN                   (0x00000002)
2267 +#define   FEC_FECTFCR_MSK                   (0x00FC0000)
2268 +#define   FEC_FECRFCR_MSK                   (0x00F80000)
2269 +#define   FEC_EIR_GRA                       (0x10000000)
2270 +#define   FEC_TCR_GTS                       (0x00000001)
2271 +#define   FEC_MIBC_ENABLE                   (0x00000000)
2272 +#define   FEC_MIB_LEN                       (228)
2273 +#define   FEC_PHY_ADDR                      (0x01)
2274 +
2275 +#define FEC_RX_DMA_PRI                      (6)
2276 +#define FEC_TX_DMA_PRI                      (6)
2277 +
2278 +#define   FEC_TX_BUF_NUMBER                 (8)
2279 +#define   FEC_RX_BUF_NUMBER                 (64)
2280 +
2281 +#define   FEC_TX_INDEX_MASK                 (0x7)
2282 +#define   FEC_RX_INDEX_MASK                 (0x3f)
2283 +
2284 +#define   FEC_RX_DESC_FEC0                  SYS_SRAM_FEC_START
2285 +#define   FEC_TX_DESC_FEC0                  \
2286 +       (FEC_RX_DESC_FEC0 + FEC_RX_BUF_NUMBER * sizeof(MCD_bufDescFec))
2287 +
2288 +#define   FEC_RX_DESC_FEC1                  \
2289 +       (SYS_SRAM_FEC_START + SYS_SRAM_FEC_SIZE/2)
2290 +#define   FEC_TX_DESC_FEC1                  \
2291 +       (FEC_RX_DESC_FEC1 + FEC_RX_BUF_NUMBER * sizeof(MCD_bufDescFec))
2292 +
2293 +#define   FEC_EIR_MII                       (0x00800000)
2294 +#define   FEC_MMFR_READ                     (0x60020000)
2295 +#define   FEC_MMFR_WRITE                    (0x50020000)
2296 +
2297 +#define   FEC_FLAGS_RX                      (0x00000001)
2298 +
2299 +#define   FEC_CRCPOL                        (0xEDB88320)
2300 +
2301 +#define   FEC_MII_TIMEOUT                   (2)
2302 +#define   FEC_GR_TIMEOUT                    (1)
2303 +#define   FEC_TX_TIMEOUT                    (1)
2304 +#define   FEC_RX_TIMEOUT                    (1)
2305 +
2306 +#define   FEC_SW_RST                        0x2000000
2307 +#define   FEC_RST_CTL                       0x1000000
2308 +
2309 +int fec_read_mii(unsigned int base_addr, unsigned int pa, unsigned int ra,
2310 +                unsigned int *data);
2311 +int fec_write_mii(unsigned int base_addr, unsigned int pa, unsigned int ra,
2312 +                 unsigned int data);
2313 +
2314 +#define FEC_MII_SPEED                   \
2315 +       ((MCF_CLK / 2) / ((2500000 / 2) * 2))
2316 +#endif
2317 --- a/drivers/net/phy/Kconfig
2318 +++ b/drivers/net/phy/Kconfig
2319 @@ -62,6 +62,11 @@ config BROADCOM_PHY
2320           Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481
2321           and BCM5482 PHYs.
2322  
2323 +config BROADCOM5222_PHY
2324 +       tristate "Drivers for Broadcom5222 PHY"
2325 +       ---help---
2326 +         Currently supports the BCM5222 PHYs.
2327 +
2328  config BCM63XX_PHY
2329         tristate "Drivers for Broadcom 63xx SOCs internal PHY"
2330         ---help---
2331 @@ -82,6 +87,16 @@ config NATIONAL_PHY
2332         ---help---
2333           Currently supports the DP83865 PHY.
2334  
2335 +config NATIONAL8364x_PHY
2336 +       tristate "Drivers for National Semiconductor dp83640 PHYs"
2337 +       ---help---
2338 +         Currently supports the DP83640 PHY.
2339 +
2340 +config NATIONAL8384x_PHY
2341 +       tristate "Drivers for National Semiconductor dp83848 dp83849 PHYs"
2342 +       ---help---
2343 +         Currently supports the DP83848 PHY.
2344 +
2345  config STE10XP
2346         depends on PHYLIB
2347         tristate "Driver for STMicroelectronics STe10Xp PHYs"
2348 --- a/drivers/net/phy/Makefile
2349 +++ b/drivers/net/phy/Makefile
2350 @@ -12,6 +12,7 @@ obj-$(CONFIG_QSEMI_PHY)               += qsemi.o
2351  obj-$(CONFIG_SMSC_PHY)         += smsc.o
2352  obj-$(CONFIG_VITESSE_PHY)      += vitesse.o
2353  obj-$(CONFIG_BROADCOM_PHY)     += broadcom.o
2354 +obj-$(CONFIG_BROADCOM5222_PHY)  += broadcom522x.o
2355  obj-$(CONFIG_BCM63XX_PHY)      += bcm63xx.o
2356  obj-$(CONFIG_ICPLUS_PHY)       += icplus.o
2357  obj-$(CONFIG_ADM6996_PHY)      += adm6996.o
2358 @@ -28,6 +29,8 @@ obj-$(CONFIG_FIXED_PHY)               += fixed.o
2359  obj-$(CONFIG_MDIO_BITBANG)     += mdio-bitbang.o
2360  obj-$(CONFIG_MDIO_GPIO)                += mdio-gpio.o
2361  obj-$(CONFIG_NATIONAL_PHY)     += national.o
2362 +obj-$(CONFIG_NATIONAL8364x_PHY) +=national836x.o
2363 +obj-$(CONFIG_NATIONAL8384x_PHY) +=national8384x.o
2364  obj-$(CONFIG_STE10XP)          += ste10Xp.o
2365  obj-$(CONFIG_MICREL_PHY)       += micrel.o
2366  obj-$(CONFIG_MDIO_OCTEON)      += mdio-octeon.o
2367 --- /dev/null
2368 +++ b/drivers/net/phy/broadcom522x.c
2369 @@ -0,0 +1,170 @@
2370 +/*
2371 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
2372 + *     Chenghu Wu <b16972@freescale.com>
2373 + *
2374 + * Driver for broadcom PHYs 522x
2375 + *
2376 + * This program is free software; you can redistribute  it and/or modify it
2377 + * under  the terms of  the GNU General  Public License as published by the
2378 + * Free Software Foundation;  either version 2 of the  License, or (at your
2379 + * option) any later version.
2380 + *
2381 + */
2382 +
2383 +#include <linux/kernel.h>
2384 +#include <linux/module.h>
2385 +#include <linux/mii.h>
2386 +#include <linux/ethtool.h>
2387 +#include <linux/phy.h>
2388 +#include <linux/netdevice.h>
2389 +
2390 +/* DP83865 phy identifier values */
2391 +#define BCM5222_PHY_ID 0x00406320
2392 +
2393 +/* PHY Register */
2394 +#define BCM5222_TIMEOUT                 0x100
2395 +
2396 +/* MII Registers */
2397 +#define BCM5222_CTRL                    0x00
2398 +#define BCM5222_STATUS                  0x01
2399 +#define BCM5222_ID_HIGH                 0x02
2400 +#define BCM5222_ID_LOW                  0x03
2401 +#define BCM5222_AN_ADV                  0x04
2402 +#define BCM5222_AN_LP                   0x05
2403 +#define BCM5222_AN_EXP                  0x06
2404 +#define BCM5222_AN_NEXTPG               0x07
2405 +#define BCM5222_AN_LP_NPTX              0x08
2406 +#define BCM5222_AUX_CS                  0x18
2407 +#define BCM5222_AUX_STATUS              0x19
2408 +
2409 +/* CONTROL Bits */
2410 +#define BCM5222_CTRL_RESET              0x8000
2411 +#define BCM5222_CTRL_LOOPBACK           0x4000
2412 +#define BCM5222_CTRL_FORCE              0x2000
2413 +#define BCM5222_CTRL_AUTOEN             0x1000
2414 +#define BCM5222_CTRL_PWRDN              0x0800
2415 +#define BCM5222_CTRL_ISOLATE            0x0400
2416 +#define BCM5222_CTRL_RESTART            0x0200
2417 +#define BCM5222_CTRL_DUPLEX             0x0100
2418 +#define BCM5222_CTRL_COLLEN             0x0080
2419 +
2420 +/* STATUS Bits */
2421 +#define BCM5222_STATUS_100T4            0x8000
2422 +#define BCM5222_STATUS_100TXFDX         0x4000
2423 +#define BCM5222_STATUS_100TX            0x2000
2424 +#define BCM5222_STATUS_10FDX            0x1000
2425 +#define BCM5222_STATUS_10               0x0800
2426 +#define BCM5222_STATUS_MF_PREAMBLE      0x0040
2427 +#define BCM5222_STATUS_AN_COMPLETE      0x0020
2428 +#define BCM5222_STATUS_REMOTE_FAULT     0x0010
2429 +#define BCM5222_STATUS_AN_CAPABLE       0x0008
2430 +#define BCM5222_STATUS_LINK             0x0004
2431 +#define BCM5222_STATUS_JABBER           0x0002
2432 +#define BCM5222_STATUS_EXT_CAP          0x0001
2433 +
2434 +/* ID Values */
2435 +#define BCM5222_ID_HIGH_VAL             0x0040
2436 +#define BCM5222_ID_LOW_VAL              0x6320
2437 +
2438 +/* Advertise Bits */
2439 +#define BCM5222_AN_ADV_NEXTPG           0x8000
2440 +#define BCM5222_AN_ADV_REMOTE_FAULT     0x2000
2441 +#define BCM5222_AN_ADV_PAUSE            0x0400
2442 +#define BCM5222_AN_ADV_100T4            0x0200
2443 +#define BCM5222_AN_ADV_100TXFDX         0x0100
2444 +#define BCM5222_AN_ADV_100TX            0x0080
2445 +#define BCM5222_AN_ADV_10FDX            0x0040
2446 +#define BCM5222_AN_ADV_10               0x0020
2447 +#define BCM5222_AN_ADV_8023             0x0001
2448 +#define BCM5222_AN_ADV_ALL              \
2449 +       (BCM5222_AN_ADV_100TXFDX | \
2450 +       BCM5222_AN_ADV_100TXFDX | \
2451 +       BCM5222_AN_ADV_100TX | \
2452 +       BCM5222_AN_ADV_10FDX | \
2453 +       BCM5222_AN_ADV_10 |    \
2454 +       BCM5222_AN_ADV_8023)
2455 +
2456 +/* AUX CTRL/STATUS Bits */
2457 +#define BCM5222_AUX_CS_JABBER_DIS       0x8000
2458 +#define BCM5222_AUX_CS_FORCE_LINK       0x4000
2459 +#define BCM5222_AUX_CS_10M_TX_PWR       0x0100
2460 +#define BCM5222_AUX_CS_HSQ_LSQ_MASK     0x00c0
2461 +#define BCM5222_AUX_CS_EDGE_RATE_MASK   0x0030
2462 +#define BCM5222_AUX_CS_AN_IND           0x0008
2463 +#define BCM5222_AUX_CS_SPEED_FORCE      0x0004
2464 +#define BCM5222_AUX_CS_SPEED            0x0002
2465 +#define BCM5222_AUX_CS_DUPLEX           0x0001
2466 +
2467 +/* AUX STATUS Bits */
2468 +#define BCM5222_AUX_STATUS_AN_COMP      0x8000
2469 +#define BCM5222_AUX_STATUS_AN_COMPACK   0x4000
2470 +#define BCM5222_AUX_STATUS_AN_ACKDET    0x2000
2471 +#define BCM5222_AUX_STATUS_AN_ABDET     0x1000
2472 +#define BCM5222_AUX_STATUS_AN_PAUSE     0x0800
2473 +#define BCM5222_AUX_STATUS_AN_HCDMASK   0x0700
2474 +#define BCM5222_AUX_STATUS_AN_PDFAULT   0x0080
2475 +#define BCM5222_AUX_STATUS_LP_RMTFAULT  0x0040
2476 +#define BCM5222_AUX_STATUS_LP_PGRX      0x0020
2477 +#define BCM5222_AUX_STATUS_LP_NEGABLE   0x0010
2478 +#define BCM5222_AUX_STATUS_SPEED        0x0008
2479 +#define BCM5222_AUX_STATUS_LINK         0x0004
2480 +#define BCM5222_AUX_STATUS_AN_EN        0x0002
2481 +#define BCM5222_AUX_STATUS_JABBER       0x0001
2482 +
2483 +static int bcm5222_config_intr(struct phy_device *phydev)
2484 +{
2485 +       int err = 0;
2486 +       printk(KERN_INFO "%s PHY_INTERRUPT %x\n",
2487 +                       __func__, phydev->interrupts);
2488 +
2489 +       return err;
2490 +}
2491 +
2492 +static int bcm5222_ack_interrupt(struct phy_device *phydev)
2493 +{
2494 +       return 0;
2495 +}
2496 +
2497 +static int bcm5222_config_init(struct phy_device *phydev)
2498 +{
2499 +       return  bcm5222_ack_interrupt(phydev);
2500 +}
2501 +
2502 +static struct phy_driver bcm5222_driver = {
2503 +       .phy_id = BCM5222_PHY_ID,
2504 +       .phy_id_mask = 0xfffffff0,
2505 +       .name = "Broadcom BCM5222",
2506 +       .features = PHY_BASIC_FEATURES,
2507 +       .flags = PHY_HAS_INTERRUPT,
2508 +       .config_init = bcm5222_config_init,
2509 +       .config_aneg = genphy_config_aneg,
2510 +       .read_status = genphy_read_status,
2511 +       .ack_interrupt = bcm5222_ack_interrupt,
2512 +       .config_intr = bcm5222_config_intr,
2513 +       .driver = {.owner = THIS_MODULE,}
2514 +};
2515 +
2516 +static int __init bcm5222_init(void)
2517 +{
2518 +       int ret;
2519 +
2520 +       ret = phy_driver_register(&bcm5222_driver);
2521 +       if (ret)
2522 +               goto err1;
2523 +
2524 +       return 0;
2525 +err1:
2526 +       printk(KERN_INFO "register bcm5222 PHY driver fail\n");
2527 +       return ret;
2528 +}
2529 +
2530 +static void __exit bcm5222_exit(void)
2531 +{
2532 +       phy_driver_unregister(&bcm5222_driver);
2533 +}
2534 +
2535 +MODULE_DESCRIPTION("Broadcom PHY driver");
2536 +MODULE_LICENSE("GPL v2");
2537 +
2538 +module_init(bcm5222_init);
2539 +module_exit(bcm5222_exit);
2540 --- /dev/null
2541 +++ b/drivers/net/phy/national836x.c
2542 @@ -0,0 +1,104 @@
2543 +/*
2544 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
2545 + *     Chenghu Wu <b16972@freescale.com>
2546 + *
2547 + * Driver for National Semiconductor PHYs 83640
2548 + *
2549 + * This program is free software; you can redistribute  it and/or modify it
2550 + * under  the terms of  the GNU General  Public License as published by the
2551 + * Free Software Foundation;  either version 2 of the  License, or (at your
2552 + * option) any later version.
2553 + *
2554 + */
2555 +
2556 +#include <linux/kernel.h>
2557 +#include <linux/module.h>
2558 +#include <linux/mii.h>
2559 +#include <linux/ethtool.h>
2560 +#include <linux/phy.h>
2561 +#include <linux/netdevice.h>
2562 +
2563 +/* DP83640 phy identifier values */
2564 +#define DP83640_PHY_ID 0x20005ce0
2565 +
2566 +/* PHY Status Register */
2567 +#define MII_DP83640_PHYSTST            16
2568 +/* Interrupt Control Register */
2569 +#define MII_DP83640_ICR                17
2570 +/* Interrupt Status and Interrupt EVEN Enable Register */
2571 +#define MII_DP83640_ISR                18
2572 +
2573 +#define MII_DP83640_ICR_IRQEVEN_EN      0x0001
2574 +#define MII_DP83640_ICR_IRQOUTPUT_EN    0x0002
2575 +#define MII_DP83640_ISR_ENERGY_EVEN     0x0040
2576 +#define MII_DP83640_ISR_LINKSTATUS_EVEN 0x0020
2577 +
2578 +static int ns_config_intr(struct phy_device *phydev)
2579 +{
2580 +       int err;
2581 +
2582 +       if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
2583 +               err = phy_write(phydev, MII_DP83640_ICR,
2584 +                               MII_DP83640_ICR_IRQEVEN_EN |
2585 +                               MII_DP83640_ICR_IRQOUTPUT_EN);
2586 +               err = phy_write(phydev, MII_DP83640_ICR,
2587 +                               MII_DP83640_ISR_ENERGY_EVEN |
2588 +                               MII_DP83640_ISR_LINKSTATUS_EVEN);
2589 +       } else {
2590 +               err = phy_write(phydev, MII_DP83640_ICR, 0);
2591 +       }
2592 +       return err;
2593 +}
2594 +
2595 +static int ns83640_ack_interrupt(struct phy_device *phydev)
2596 +{
2597 +       int ret = phy_read(phydev, MII_DP83640_ISR);
2598 +       if (ret < 0) {
2599 +               printk(KERN_INFO "%s MII_DP83640_ISR %x\n",
2600 +                       __func__, ret);
2601 +               return ret;
2602 +       }
2603 +       return 0;
2604 +}
2605 +
2606 +static int ns83640_config_init(struct phy_device *phydev)
2607 +{
2608 +       int ret = phy_read(phydev, MII_DP83640_PHYSTST);
2609 +       if (ret < 0) {
2610 +               printk(KERN_INFO "%s MII_DP83640_ISR %x\n",
2611 +                       __func__, ret);
2612 +       }
2613 +
2614 +       return ns83640_ack_interrupt(phydev);
2615 +}
2616 +
2617 +static struct phy_driver dp83640_driver = {
2618 +       .phy_id = DP83640_PHY_ID,
2619 +       .phy_id_mask = 0xfffffff0,
2620 +       .name = "NatSemi DP83640",
2621 +       .features = PHY_BASIC_FEATURES,
2622 +       .flags = PHY_HAS_INTERRUPT,
2623 +       .config_init = ns83640_config_init,
2624 +       .config_aneg = genphy_config_aneg,
2625 +       .read_status = genphy_read_status,
2626 +       .ack_interrupt = ns83640_ack_interrupt,
2627 +       .config_intr = ns_config_intr,
2628 +       .driver = {.owner = THIS_MODULE,}
2629 +};
2630 +
2631 +static int __init ns83640_init(void)
2632 +{
2633 +       return phy_driver_register(&dp83640_driver);
2634 +}
2635 +
2636 +static void __exit ns83640_exit(void)
2637 +{
2638 +       phy_driver_unregister(&dp83640_driver);
2639 +}
2640 +
2641 +MODULE_DESCRIPTION("NatSemi PHY driver");
2642 +MODULE_AUTHOR("Chenghu Wu <b16972@freescale.com>");
2643 +MODULE_LICENSE("GPL v2");
2644 +
2645 +module_init(ns83640_init);
2646 +module_exit(ns83640_exit);
2647 --- /dev/null
2648 +++ b/drivers/net/phy/national8384x.c
2649 @@ -0,0 +1,110 @@
2650 +/*
2651 + * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
2652 + *     Chenghu Wu <b16972@freescale.com>
2653 + *
2654 + * Driver for National Semiconductor PHYs 8384x
2655 + *
2656 + * This program is free software; you can redistribute  it and/or modify it
2657 + * under  the terms of  the GNU General  Public License as published by the
2658 + * Free Software Foundation;  either version 2 of the  License, or (at your
2659 + * option) any later version.
2660 + *
2661 + */
2662 +
2663 +#include <linux/kernel.h>
2664 +#include <linux/module.h>
2665 +#include <linux/mii.h>
2666 +#include <linux/ethtool.h>
2667 +#include <linux/phy.h>
2668 +#include <linux/netdevice.h>
2669 +
2670 +/* DP8384x phy identifier values */
2671 +#define DP83848_PHY_ID 0x20005c90
2672 +#define DP83849_PHY_ID  0x20005ca0
2673 +/* PHY Status Register */
2674 +#define MII_DP8384X_PHYSTST            16
2675 +
2676 +static int ns8384x_config_intr(struct phy_device *phydev)
2677 +{
2678 +       int err = 0;
2679 +
2680 +       return err;
2681 +}
2682 +
2683 +static int ns8384x_ack_interrupt(struct phy_device *phydev)
2684 +{
2685 +       return 0;
2686 +}
2687 +
2688 +static int ns8384x_config_init(struct phy_device *phydev)
2689 +{
2690 +       int ret = phy_read(phydev, MII_DP8384X_PHYSTST);
2691 +       if (ret < 0) {
2692 +               printk(KERN_INFO "%s MII_DP83640_ISR %x\n",
2693 +                       __func__, ret);
2694 +       }
2695 +
2696 +       return ns8384x_ack_interrupt(phydev);
2697 +}
2698 +
2699 +static struct phy_driver dp83848_driver = {
2700 +       .phy_id = DP83848_PHY_ID,
2701 +       .phy_id_mask = 0xfffffff0,
2702 +       .name = "NatSemi DP83848",
2703 +       .features = PHY_BASIC_FEATURES,
2704 +       .flags = PHY_HAS_INTERRUPT,
2705 +       .config_init = ns8384x_config_init,
2706 +       .config_aneg = genphy_config_aneg,
2707 +       .read_status = genphy_read_status,
2708 +       .ack_interrupt = ns8384x_ack_interrupt,
2709 +       .config_intr = ns8384x_config_intr,
2710 +       .driver = {.owner = THIS_MODULE,}
2711 +};
2712 +
2713 +static struct phy_driver dp83849_driver = {
2714 +       .phy_id = DP83849_PHY_ID,
2715 +       .phy_id_mask = 0xfffffff0,
2716 +       .name = "NatSemi DP83849",
2717 +       .features = PHY_BASIC_FEATURES,
2718 +       .flags = PHY_HAS_INTERRUPT,
2719 +       .config_init = ns8384x_config_init,
2720 +       .config_aneg = genphy_config_aneg,
2721 +       .read_status = genphy_read_status,
2722 +       .ack_interrupt = ns8384x_ack_interrupt,
2723 +       .config_intr = ns8384x_config_intr,
2724 +       .driver = {.owner = THIS_MODULE,}
2725 +};
2726 +
2727 +static int __init ns8384x_init(void)
2728 +{
2729 +       int ret;
2730 +
2731 +       ret = phy_driver_register(&dp83848_driver);
2732 +       if (ret)
2733 +               goto err1;
2734 +
2735 +       ret = phy_driver_register(&dp83849_driver);
2736 +       if (ret)
2737 +               goto err2;
2738 +
2739 +       return 0;
2740 +err2:
2741 +       printk(KERN_INFO "register dp83849 PHY driver fail\n");
2742 +       phy_driver_unregister(&dp83848_driver);
2743 +err1:
2744 +       printk(KERN_INFO "register dp83848 PHY driver fail\n");
2745 +       return ret;
2746 +}
2747 +
2748 +static void __exit ns8384x_exit(void)
2749 +{
2750 +       phy_driver_unregister(&dp83848_driver);
2751 +       phy_driver_unregister(&dp83849_driver);
2752 +}
2753 +
2754 +MODULE_DESCRIPTION("NatSemi PHY driver");
2755 +MODULE_AUTHOR("Chenghu Wu <b16972@freescale.com>");
2756 +MODULE_LICENSE("GPL v2");
2757 +
2758 +module_init(ns8384x_init);
2759 +module_exit(ns8384x_exit);