1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/fcntl.h>
20#include <linux/interrupt.h>
21#include <linux/ioport.h>
22#include <linux/in.h>
23#include <linux/slab.h>
24#include <linux/string.h>
25#include <linux/delay.h>
26#include <linux/init.h>
27#include <linux/ethtool.h>
28#include <linux/mii.h>
29#include <linux/crc32.h>
30#include <linux/random.h>
31#include <linux/errno.h>
32#include <linux/netdevice.h>
33#include <linux/etherdevice.h>
34#include <linux/skbuff.h>
35#include <linux/mm.h>
36#include <linux/bitops.h>
37#include <linux/dma-mapping.h>
38
39#include <asm/io.h>
40#include <asm/dma.h>
41#include <asm/byteorder.h>
42
43#ifdef CONFIG_SPARC
44#include <linux/of.h>
45#include <linux/of_device.h>
46#include <asm/idprom.h>
47#include <asm/openprom.h>
48#include <asm/oplib.h>
49#include <asm/prom.h>
50#include <asm/auxio.h>
51#endif
52#include <asm/uaccess.h>
53
54#include <asm/pgtable.h>
55#include <asm/irq.h>
56
57#ifdef CONFIG_PCI
58#include <linux/pci.h>
59#endif
60
61#include "sunhme.h"
62
63#define DRV_NAME "sunhme"
64#define DRV_VERSION "3.10"
65#define DRV_RELDATE "August 26, 2008"
66#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"
67
68static char version[] =
69 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
70
71MODULE_VERSION(DRV_VERSION);
72MODULE_AUTHOR(DRV_AUTHOR);
73MODULE_DESCRIPTION("Sun HappyMealEthernet(HME) 10/100baseT ethernet driver");
74MODULE_LICENSE("GPL");
75
76static int macaddr[6];
77
78
79module_param_array(macaddr, int, NULL, 0);
80MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
81
82#ifdef CONFIG_SBUS
83static struct quattro *qfe_sbus_list;
84#endif
85
86#ifdef CONFIG_PCI
87static struct quattro *qfe_pci_list;
88#endif
89
90#undef HMEDEBUG
91#undef SXDEBUG
92#undef RXDEBUG
93#undef TXDEBUG
94#undef TXLOGGING
95
96#ifdef TXLOGGING
97struct hme_tx_logent {
98 unsigned int tstamp;
99 int tx_new, tx_old;
100 unsigned int action;
101#define TXLOG_ACTION_IRQ 0x01
102#define TXLOG_ACTION_TXMIT 0x02
103#define TXLOG_ACTION_TBUSY 0x04
104#define TXLOG_ACTION_NBUFS 0x08
105 unsigned int status;
106};
107#define TX_LOG_LEN 128
108static struct hme_tx_logent tx_log[TX_LOG_LEN];
109static int txlog_cur_entry;
110static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigned int s)
111{
112 struct hme_tx_logent *tlp;
113 unsigned long flags;
114
115 local_irq_save(flags);
116 tlp = &tx_log[txlog_cur_entry];
117 tlp->tstamp = (unsigned int)jiffies;
118 tlp->tx_new = hp->tx_new;
119 tlp->tx_old = hp->tx_old;
120 tlp->action = a;
121 tlp->status = s;
122 txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1);
123 local_irq_restore(flags);
124}
125static __inline__ void tx_dump_log(void)
126{
127 int i, this;
128
129 this = txlog_cur_entry;
130 for (i = 0; i < TX_LOG_LEN; i++) {
131 printk("TXLOG[%d]: j[%08x] tx[N(%d)O(%d)] action[%08x] stat[%08x]\n", i,
132 tx_log[this].tstamp,
133 tx_log[this].tx_new, tx_log[this].tx_old,
134 tx_log[this].action, tx_log[this].status);
135 this = (this + 1) & (TX_LOG_LEN - 1);
136 }
137}
138static __inline__ void tx_dump_ring(struct happy_meal *hp)
139{
140 struct hmeal_init_block *hb = hp->happy_block;
141 struct happy_meal_txd *tp = &hb->happy_meal_txd[0];
142 int i;
143
144 for (i = 0; i < TX_RING_SIZE; i+=4) {
145 printk("TXD[%d..%d]: [%08x:%08x] [%08x:%08x] [%08x:%08x] [%08x:%08x]\n",
146 i, i + 4,
147 le32_to_cpu(tp[i].tx_flags), le32_to_cpu(tp[i].tx_addr),
148 le32_to_cpu(tp[i + 1].tx_flags), le32_to_cpu(tp[i + 1].tx_addr),
149 le32_to_cpu(tp[i + 2].tx_flags), le32_to_cpu(tp[i + 2].tx_addr),
150 le32_to_cpu(tp[i + 3].tx_flags), le32_to_cpu(tp[i + 3].tx_addr));
151 }
152}
153#else
154#define tx_add_log(hp, a, s) do { } while(0)
155#define tx_dump_log() do { } while(0)
156#define tx_dump_ring(hp) do { } while(0)
157#endif
158
159#ifdef HMEDEBUG
160#define HMD(x) printk x
161#else
162#define HMD(x)
163#endif
164
165
166
167#ifdef AUTO_SWITCH_DEBUG
168#define ASD(x) printk x
169#else
170#define ASD(x)
171#endif
172
173#define DEFAULT_IPG0 16
174#define DEFAULT_IPG1 8
175#define DEFAULT_IPG2 4
176#define DEFAULT_JAMSIZE 4
177
178
179
180
181
182
183
184
185#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
186static void sbus_hme_write32(void __iomem *reg, u32 val)
187{
188 sbus_writel(val, reg);
189}
190
191static u32 sbus_hme_read32(void __iomem *reg)
192{
193 return sbus_readl(reg);
194}
195
196static void sbus_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr)
197{
198 rxd->rx_addr = (__force hme32)addr;
199 wmb();
200 rxd->rx_flags = (__force hme32)flags;
201}
202
203static void sbus_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr)
204{
205 txd->tx_addr = (__force hme32)addr;
206 wmb();
207 txd->tx_flags = (__force hme32)flags;
208}
209
210static u32 sbus_hme_read_desc32(hme32 *p)
211{
212 return (__force u32)*p;
213}
214
215static void pci_hme_write32(void __iomem *reg, u32 val)
216{
217 writel(val, reg);
218}
219
220static u32 pci_hme_read32(void __iomem *reg)
221{
222 return readl(reg);
223}
224
225static void pci_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr)
226{
227 rxd->rx_addr = (__force hme32)cpu_to_le32(addr);
228 wmb();
229 rxd->rx_flags = (__force hme32)cpu_to_le32(flags);
230}
231
232static void pci_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr)
233{
234 txd->tx_addr = (__force hme32)cpu_to_le32(addr);
235 wmb();
236 txd->tx_flags = (__force hme32)cpu_to_le32(flags);
237}
238
239static u32 pci_hme_read_desc32(hme32 *p)
240{
241 return le32_to_cpup((__le32 *)p);
242}
243
244#define hme_write32(__hp, __reg, __val) \
245 ((__hp)->write32((__reg), (__val)))
246#define hme_read32(__hp, __reg) \
247 ((__hp)->read32(__reg))
248#define hme_write_rxd(__hp, __rxd, __flags, __addr) \
249 ((__hp)->write_rxd((__rxd), (__flags), (__addr)))
250#define hme_write_txd(__hp, __txd, __flags, __addr) \
251 ((__hp)->write_txd((__txd), (__flags), (__addr)))
252#define hme_read_desc32(__hp, __p) \
253 ((__hp)->read_desc32(__p))
254#define hme_dma_map(__hp, __ptr, __size, __dir) \
255 ((__hp)->dma_map((__hp)->dma_dev, (__ptr), (__size), (__dir)))
256#define hme_dma_unmap(__hp, __addr, __size, __dir) \
257 ((__hp)->dma_unmap((__hp)->dma_dev, (__addr), (__size), (__dir)))
258#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
259 ((__hp)->dma_sync_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir)))
260#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
261 ((__hp)->dma_sync_for_device((__hp)->dma_dev, (__addr), (__size), (__dir)))
262#else
263#ifdef CONFIG_SBUS
264
265#define hme_write32(__hp, __reg, __val) \
266 sbus_writel((__val), (__reg))
267#define hme_read32(__hp, __reg) \
268 sbus_readl(__reg)
269#define hme_write_rxd(__hp, __rxd, __flags, __addr) \
270do { (__rxd)->rx_addr = (__force hme32)(u32)(__addr); \
271 wmb(); \
272 (__rxd)->rx_flags = (__force hme32)(u32)(__flags); \
273} while(0)
274#define hme_write_txd(__hp, __txd, __flags, __addr) \
275do { (__txd)->tx_addr = (__force hme32)(u32)(__addr); \
276 wmb(); \
277 (__txd)->tx_flags = (__force hme32)(u32)(__flags); \
278} while(0)
279#define hme_read_desc32(__hp, __p) ((__force u32)(hme32)*(__p))
280#define hme_dma_map(__hp, __ptr, __size, __dir) \
281 dma_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir))
282#define hme_dma_unmap(__hp, __addr, __size, __dir) \
283 dma_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir))
284#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
285 dma_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir))
286#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
287 dma_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir))
288#else
289
290#define hme_write32(__hp, __reg, __val) \
291 writel((__val), (__reg))
292#define hme_read32(__hp, __reg) \
293 readl(__reg)
294#define hme_write_rxd(__hp, __rxd, __flags, __addr) \
295do { (__rxd)->rx_addr = (__force hme32)cpu_to_le32(__addr); \
296 wmb(); \
297 (__rxd)->rx_flags = (__force hme32)cpu_to_le32(__flags); \
298} while(0)
299#define hme_write_txd(__hp, __txd, __flags, __addr) \
300do { (__txd)->tx_addr = (__force hme32)cpu_to_le32(__addr); \
301 wmb(); \
302 (__txd)->tx_flags = (__force hme32)cpu_to_le32(__flags); \
303} while(0)
304static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p)
305{
306 return le32_to_cpup((__le32 *)p);
307}
308#define hme_dma_map(__hp, __ptr, __size, __dir) \
309 pci_map_single((__hp)->dma_dev, (__ptr), (__size), (__dir))
310#define hme_dma_unmap(__hp, __addr, __size, __dir) \
311 pci_unmap_single((__hp)->dma_dev, (__addr), (__size), (__dir))
312#define hme_dma_sync_for_cpu(__hp, __addr, __size, __dir) \
313 pci_dma_sync_single_for_cpu((__hp)->dma_dev, (__addr), (__size), (__dir))
314#define hme_dma_sync_for_device(__hp, __addr, __size, __dir) \
315 pci_dma_sync_single_for_device((__hp)->dma_dev, (__addr), (__size), (__dir))
316#endif
317#endif
318
319
320
321static void BB_PUT_BIT(struct happy_meal *hp, void __iomem *tregs, int bit)
322{
323 hme_write32(hp, tregs + TCVR_BBDATA, bit);
324 hme_write32(hp, tregs + TCVR_BBCLOCK, 0);
325 hme_write32(hp, tregs + TCVR_BBCLOCK, 1);
326}
327
328#if 0
329static u32 BB_GET_BIT(struct happy_meal *hp, void __iomem *tregs, int internal)
330{
331 u32 ret;
332
333 hme_write32(hp, tregs + TCVR_BBCLOCK, 0);
334 hme_write32(hp, tregs + TCVR_BBCLOCK, 1);
335 ret = hme_read32(hp, tregs + TCVR_CFG);
336 if (internal)
337 ret &= TCV_CFG_MDIO0;
338 else
339 ret &= TCV_CFG_MDIO1;
340
341 return ret;
342}
343#endif
344
345static u32 BB_GET_BIT2(struct happy_meal *hp, void __iomem *tregs, int internal)
346{
347 u32 retval;
348
349 hme_write32(hp, tregs + TCVR_BBCLOCK, 0);
350 udelay(1);
351 retval = hme_read32(hp, tregs + TCVR_CFG);
352 if (internal)
353 retval &= TCV_CFG_MDIO0;
354 else
355 retval &= TCV_CFG_MDIO1;
356 hme_write32(hp, tregs + TCVR_BBCLOCK, 1);
357
358 return retval;
359}
360
361#define TCVR_FAILURE 0x80000000
362
363static int happy_meal_bb_read(struct happy_meal *hp,
364 void __iomem *tregs, int reg)
365{
366 u32 tmp;
367 int retval = 0;
368 int i;
369
370 ASD(("happy_meal_bb_read: reg=%d ", reg));
371
372
373 hme_write32(hp, tregs + TCVR_BBOENAB, 1);
374
375
376 for (i = 0; i < 32; i++)
377 BB_PUT_BIT(hp, tregs, 1);
378
379
380 BB_PUT_BIT(hp, tregs, 0);
381 BB_PUT_BIT(hp, tregs, 1);
382 BB_PUT_BIT(hp, tregs, 1);
383 BB_PUT_BIT(hp, tregs, 0);
384
385
386 tmp = hp->paddr & 0xff;
387 for (i = 4; i >= 0; i--)
388 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
389
390
391 tmp = (reg & 0xff);
392 for (i = 4; i >= 0; i--)
393 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
394
395
396 hme_write32(hp, tregs + TCVR_BBOENAB, 0);
397
398
399 (void) BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
400 for (i = 15; i >= 0; i--)
401 retval |= BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
402 (void) BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
403 (void) BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
404 (void) BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
405 ASD(("value=%x\n", retval));
406 return retval;
407}
408
409static void happy_meal_bb_write(struct happy_meal *hp,
410 void __iomem *tregs, int reg,
411 unsigned short value)
412{
413 u32 tmp;
414 int i;
415
416 ASD(("happy_meal_bb_write: reg=%d value=%x\n", reg, value));
417
418
419 hme_write32(hp, tregs + TCVR_BBOENAB, 1);
420
421
422 for (i = 0; i < 32; i++)
423 BB_PUT_BIT(hp, tregs, 1);
424
425
426 BB_PUT_BIT(hp, tregs, 0);
427 BB_PUT_BIT(hp, tregs, 1);
428 BB_PUT_BIT(hp, tregs, 0);
429 BB_PUT_BIT(hp, tregs, 1);
430
431
432 tmp = (hp->paddr & 0xff);
433 for (i = 4; i >= 0; i--)
434 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
435
436
437 tmp = (reg & 0xff);
438 for (i = 4; i >= 0; i--)
439 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
440
441
442 BB_PUT_BIT(hp, tregs, 1);
443 BB_PUT_BIT(hp, tregs, 0);
444
445 for (i = 15; i >= 0; i--)
446 BB_PUT_BIT(hp, tregs, ((value >> i) & 1));
447
448
449 hme_write32(hp, tregs + TCVR_BBOENAB, 0);
450}
451
452#define TCVR_READ_TRIES 16
453
454static int happy_meal_tcvr_read(struct happy_meal *hp,
455 void __iomem *tregs, int reg)
456{
457 int tries = TCVR_READ_TRIES;
458 int retval;
459
460 ASD(("happy_meal_tcvr_read: reg=0x%02x ", reg));
461 if (hp->tcvr_type == none) {
462 ASD(("no transceiver, value=TCVR_FAILURE\n"));
463 return TCVR_FAILURE;
464 }
465
466 if (!(hp->happy_flags & HFLAG_FENABLE)) {
467 ASD(("doing bit bang\n"));
468 return happy_meal_bb_read(hp, tregs, reg);
469 }
470
471 hme_write32(hp, tregs + TCVR_FRAME,
472 (FRAME_READ | (hp->paddr << 23) | ((reg & 0xff) << 18)));
473 while (!(hme_read32(hp, tregs + TCVR_FRAME) & 0x10000) && --tries)
474 udelay(20);
475 if (!tries) {
476 printk(KERN_ERR "happy meal: Aieee, transceiver MIF read bolixed\n");
477 return TCVR_FAILURE;
478 }
479 retval = hme_read32(hp, tregs + TCVR_FRAME) & 0xffff;
480 ASD(("value=%04x\n", retval));
481 return retval;
482}
483
484#define TCVR_WRITE_TRIES 16
485
486static void happy_meal_tcvr_write(struct happy_meal *hp,
487 void __iomem *tregs, int reg,
488 unsigned short value)
489{
490 int tries = TCVR_WRITE_TRIES;
491
492 ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value));
493
494
495 if (!(hp->happy_flags & HFLAG_FENABLE)) {
496 happy_meal_bb_write(hp, tregs, reg, value);
497 return;
498 }
499
500
501 hme_write32(hp, tregs + TCVR_FRAME,
502 (FRAME_WRITE | (hp->paddr << 23) |
503 ((reg & 0xff) << 18) | (value & 0xffff)));
504 while (!(hme_read32(hp, tregs + TCVR_FRAME) & 0x10000) && --tries)
505 udelay(20);
506
507
508 if (!tries)
509 printk(KERN_ERR "happy meal: Aieee, transceiver MIF write bolixed\n");
510
511
512}
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546static int try_next_permutation(struct happy_meal *hp, void __iomem *tregs)
547{
548 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
549
550
551
552
553 if (hp->sw_bmcr & BMCR_FULLDPLX) {
554 hp->sw_bmcr &= ~(BMCR_FULLDPLX);
555 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
556 return 0;
557 }
558
559
560 if (hp->sw_bmcr & BMCR_SPEED100) {
561 hp->sw_bmcr &= ~(BMCR_SPEED100);
562 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
563 return 0;
564 }
565
566
567 return -1;
568}
569
570static void display_link_mode(struct happy_meal *hp, void __iomem *tregs)
571{
572 printk(KERN_INFO "%s: Link is up using ", hp->dev->name);
573 if (hp->tcvr_type == external)
574 printk("external ");
575 else
576 printk("internal ");
577 printk("transceiver at ");
578 hp->sw_lpa = happy_meal_tcvr_read(hp, tregs, MII_LPA);
579 if (hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) {
580 if (hp->sw_lpa & LPA_100FULL)
581 printk("100Mb/s, Full Duplex.\n");
582 else
583 printk("100Mb/s, Half Duplex.\n");
584 } else {
585 if (hp->sw_lpa & LPA_10FULL)
586 printk("10Mb/s, Full Duplex.\n");
587 else
588 printk("10Mb/s, Half Duplex.\n");
589 }
590}
591
592static void display_forced_link_mode(struct happy_meal *hp, void __iomem *tregs)
593{
594 printk(KERN_INFO "%s: Link has been forced up using ", hp->dev->name);
595 if (hp->tcvr_type == external)
596 printk("external ");
597 else
598 printk("internal ");
599 printk("transceiver at ");
600 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
601 if (hp->sw_bmcr & BMCR_SPEED100)
602 printk("100Mb/s, ");
603 else
604 printk("10Mb/s, ");
605 if (hp->sw_bmcr & BMCR_FULLDPLX)
606 printk("Full Duplex.\n");
607 else
608 printk("Half Duplex.\n");
609}
610
611static int set_happy_link_modes(struct happy_meal *hp, void __iomem *tregs)
612{
613 int full;
614
615
616
617
618 if (hp->timer_state == arbwait) {
619 hp->sw_lpa = happy_meal_tcvr_read(hp, tregs, MII_LPA);
620 if (!(hp->sw_lpa & (LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL)))
621 goto no_response;
622 if (hp->sw_lpa & LPA_100FULL)
623 full = 1;
624 else if (hp->sw_lpa & LPA_100HALF)
625 full = 0;
626 else if (hp->sw_lpa & LPA_10FULL)
627 full = 1;
628 else
629 full = 0;
630 } else {
631
632 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
633 if (hp->sw_bmcr & BMCR_FULLDPLX)
634 full = 1;
635 else
636 full = 0;
637 }
638
639
640
641
642
643
644
645
646
647 hme_write32(hp, hp->bigmacregs + BMAC_TXCFG,
648 hme_read32(hp, hp->bigmacregs + BMAC_TXCFG) &
649 ~(BIGMAC_TXCFG_ENABLE));
650 while (hme_read32(hp, hp->bigmacregs + BMAC_TXCFG) & BIGMAC_TXCFG_ENABLE)
651 barrier();
652 if (full) {
653 hp->happy_flags |= HFLAG_FULL;
654 hme_write32(hp, hp->bigmacregs + BMAC_TXCFG,
655 hme_read32(hp, hp->bigmacregs + BMAC_TXCFG) |
656 BIGMAC_TXCFG_FULLDPLX);
657 } else {
658 hp->happy_flags &= ~(HFLAG_FULL);
659 hme_write32(hp, hp->bigmacregs + BMAC_TXCFG,
660 hme_read32(hp, hp->bigmacregs + BMAC_TXCFG) &
661 ~(BIGMAC_TXCFG_FULLDPLX));
662 }
663 hme_write32(hp, hp->bigmacregs + BMAC_TXCFG,
664 hme_read32(hp, hp->bigmacregs + BMAC_TXCFG) |
665 BIGMAC_TXCFG_ENABLE);
666 return 0;
667no_response:
668 return 1;
669}
670
671static int happy_meal_init(struct happy_meal *hp);
672
673static int is_lucent_phy(struct happy_meal *hp)
674{
675 void __iomem *tregs = hp->tcvregs;
676 unsigned short mr2, mr3;
677 int ret = 0;
678
679 mr2 = happy_meal_tcvr_read(hp, tregs, 2);
680 mr3 = happy_meal_tcvr_read(hp, tregs, 3);
681 if ((mr2 & 0xffff) == 0x0180 &&
682 ((mr3 & 0xffff) >> 10) == 0x1d)
683 ret = 1;
684
685 return ret;
686}
687
688static void happy_meal_timer(unsigned long data)
689{
690 struct happy_meal *hp = (struct happy_meal *) data;
691 void __iomem *tregs = hp->tcvregs;
692 int restart_timer = 0;
693
694 spin_lock_irq(&hp->happy_lock);
695
696 hp->timer_ticks++;
697 switch(hp->timer_state) {
698 case arbwait:
699
700
701
702 if (hp->timer_ticks >= 10) {
703
704 do_force_mode:
705 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
706 printk(KERN_NOTICE "%s: Auto-Negotiation unsuccessful, trying force link mode\n",
707 hp->dev->name);
708 hp->sw_bmcr = BMCR_SPEED100;
709 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
710
711 if (!is_lucent_phy(hp)) {
712
713
714
715
716 hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs, DP83840_CSCONFIG);
717 hp->sw_csconfig &= ~(CSCONFIG_TCVDISAB);
718 happy_meal_tcvr_write(hp, tregs, DP83840_CSCONFIG, hp->sw_csconfig);
719 }
720 hp->timer_state = ltrywait;
721 hp->timer_ticks = 0;
722 restart_timer = 1;
723 } else {
724
725 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, MII_BMSR);
726 if (hp->sw_bmsr & BMSR_ANEGCOMPLETE) {
727 int ret;
728
729
730 ret = set_happy_link_modes(hp, tregs);
731 if (ret) {
732
733
734
735
736
737
738 goto do_force_mode;
739 }
740
741
742 hp->timer_state = lupwait;
743 restart_timer = 1;
744 } else {
745 restart_timer = 1;
746 }
747 }
748 break;
749
750 case lupwait:
751
752
753
754
755
756 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, MII_BMSR);
757 if (hp->sw_bmsr & BMSR_LSTATUS) {
758
759
760
761 display_link_mode(hp, tregs);
762 hp->timer_state = asleep;
763 restart_timer = 0;
764 } else {
765 if (hp->timer_ticks >= 10) {
766 printk(KERN_NOTICE "%s: Auto negotiation successful, link still "
767 "not completely up.\n", hp->dev->name);
768 hp->timer_ticks = 0;
769 restart_timer = 1;
770 } else {
771 restart_timer = 1;
772 }
773 }
774 break;
775
776 case ltrywait:
777
778
779
780
781
782 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, MII_BMSR);
783 hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs, DP83840_CSCONFIG);
784 if (hp->timer_ticks == 1) {
785 if (!is_lucent_phy(hp)) {
786
787
788
789 hp->sw_csconfig |= CSCONFIG_TCVDISAB;
790 happy_meal_tcvr_write(hp, tregs,
791 DP83840_CSCONFIG, hp->sw_csconfig);
792 }
793 restart_timer = 1;
794 break;
795 }
796 if (hp->timer_ticks == 2) {
797 if (!is_lucent_phy(hp)) {
798 hp->sw_csconfig &= ~(CSCONFIG_TCVDISAB);
799 happy_meal_tcvr_write(hp, tregs,
800 DP83840_CSCONFIG, hp->sw_csconfig);
801 }
802 restart_timer = 1;
803 break;
804 }
805 if (hp->sw_bmsr & BMSR_LSTATUS) {
806
807 display_forced_link_mode(hp, tregs);
808 set_happy_link_modes(hp, tregs);
809 hp->timer_state = asleep;
810 restart_timer = 0;
811 } else {
812 if (hp->timer_ticks >= 4) {
813 int ret;
814
815 ret = try_next_permutation(hp, tregs);
816 if (ret == -1) {
817
818
819
820
821
822 printk(KERN_NOTICE "%s: Link down, cable problem?\n",
823 hp->dev->name);
824
825 ret = happy_meal_init(hp);
826 if (ret) {
827
828 printk(KERN_ERR "%s: Error, cannot re-init the "
829 "Happy Meal.\n", hp->dev->name);
830 }
831 goto out;
832 }
833 if (!is_lucent_phy(hp)) {
834 hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs,
835 DP83840_CSCONFIG);
836 hp->sw_csconfig |= CSCONFIG_TCVDISAB;
837 happy_meal_tcvr_write(hp, tregs,
838 DP83840_CSCONFIG, hp->sw_csconfig);
839 }
840 hp->timer_ticks = 0;
841 restart_timer = 1;
842 } else {
843 restart_timer = 1;
844 }
845 }
846 break;
847
848 case asleep:
849 default:
850
851 printk(KERN_ERR "%s: Aieee, link timer is asleep but we got one anyways!\n",
852 hp->dev->name);
853 restart_timer = 0;
854 hp->timer_ticks = 0;
855 hp->timer_state = asleep;
856 break;
857 }
858
859 if (restart_timer) {
860 hp->happy_timer.expires = jiffies + ((12 * HZ)/10);
861 add_timer(&hp->happy_timer);
862 }
863
864out:
865 spin_unlock_irq(&hp->happy_lock);
866}
867
868#define TX_RESET_TRIES 32
869#define RX_RESET_TRIES 32
870
871
872static void happy_meal_tx_reset(struct happy_meal *hp, void __iomem *bregs)
873{
874 int tries = TX_RESET_TRIES;
875
876 HMD(("happy_meal_tx_reset: reset, "));
877
878
879 hme_write32(hp, bregs + BMAC_TXSWRESET, 0);
880 while ((hme_read32(hp, bregs + BMAC_TXSWRESET) & 1) && --tries)
881 udelay(20);
882
883
884 if (!tries)
885 printk(KERN_ERR "happy meal: Transceiver BigMac ATTACK!");
886
887
888 HMD(("done\n"));
889}
890
891
892static void happy_meal_rx_reset(struct happy_meal *hp, void __iomem *bregs)
893{
894 int tries = RX_RESET_TRIES;
895
896 HMD(("happy_meal_rx_reset: reset, "));
897
898
899 hme_write32(hp, bregs + BMAC_RXSWRESET, 0);
900 while ((hme_read32(hp, bregs + BMAC_RXSWRESET) & 1) && --tries)
901 udelay(20);
902
903
904 if (!tries)
905 printk(KERN_ERR "happy meal: Receiver BigMac ATTACK!");
906
907
908 HMD(("done\n"));
909}
910
911#define STOP_TRIES 16
912
913
914static void happy_meal_stop(struct happy_meal *hp, void __iomem *gregs)
915{
916 int tries = STOP_TRIES;
917
918 HMD(("happy_meal_stop: reset, "));
919
920
921 hme_write32(hp, gregs + GREG_SWRESET, GREG_RESET_ALL);
922 while (hme_read32(hp, gregs + GREG_SWRESET) && --tries)
923 udelay(20);
924
925
926 if (!tries)
927 printk(KERN_ERR "happy meal: Fry guys.");
928
929
930 HMD(("done\n"));
931}
932
933
934static void happy_meal_get_counters(struct happy_meal *hp, void __iomem *bregs)
935{
936 struct net_device_stats *stats = &hp->net_stats;
937
938 stats->rx_crc_errors += hme_read32(hp, bregs + BMAC_RCRCECTR);
939 hme_write32(hp, bregs + BMAC_RCRCECTR, 0);
940
941 stats->rx_frame_errors += hme_read32(hp, bregs + BMAC_UNALECTR);
942 hme_write32(hp, bregs + BMAC_UNALECTR, 0);
943
944 stats->rx_length_errors += hme_read32(hp, bregs + BMAC_GLECTR);
945 hme_write32(hp, bregs + BMAC_GLECTR, 0);
946
947 stats->tx_aborted_errors += hme_read32(hp, bregs + BMAC_EXCTR);
948
949 stats->collisions +=
950 (hme_read32(hp, bregs + BMAC_EXCTR) +
951 hme_read32(hp, bregs + BMAC_LTCTR));
952 hme_write32(hp, bregs + BMAC_EXCTR, 0);
953 hme_write32(hp, bregs + BMAC_LTCTR, 0);
954}
955
956
957static void happy_meal_poll_stop(struct happy_meal *hp, void __iomem *tregs)
958{
959 ASD(("happy_meal_poll_stop: "));
960
961
962 if ((hp->happy_flags & (HFLAG_POLLENABLE | HFLAG_POLL)) !=
963 (HFLAG_POLLENABLE | HFLAG_POLL)) {
964 HMD(("not polling, return\n"));
965 return;
966 }
967
968
969 ASD(("were polling, mif ints off, "));
970 hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
971
972
973 ASD(("polling off, "));
974 hme_write32(hp, tregs + TCVR_CFG,
975 hme_read32(hp, tregs + TCVR_CFG) & ~(TCV_CFG_PENABLE));
976
977
978 hp->happy_flags &= ~(HFLAG_POLL);
979
980
981 udelay(200);
982 ASD(("done\n"));
983}
984
985
986
987
988#define TCVR_RESET_TRIES 16
989#define TCVR_UNISOLATE_TRIES 32
990
991
992static int happy_meal_tcvr_reset(struct happy_meal *hp, void __iomem *tregs)
993{
994 u32 tconfig;
995 int result, tries = TCVR_RESET_TRIES;
996
997 tconfig = hme_read32(hp, tregs + TCVR_CFG);
998 ASD(("happy_meal_tcvr_reset: tcfg<%08lx> ", tconfig));
999 if (hp->tcvr_type == external) {
1000 ASD(("external<"));
1001 hme_write32(hp, tregs + TCVR_CFG, tconfig & ~(TCV_CFG_PSELECT));
1002 hp->tcvr_type = internal;
1003 hp->paddr = TCV_PADDR_ITX;
1004 ASD(("ISOLATE,"));
1005 happy_meal_tcvr_write(hp, tregs, MII_BMCR,
1006 (BMCR_LOOPBACK|BMCR_PDOWN|BMCR_ISOLATE));
1007 result = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
1008 if (result == TCVR_FAILURE) {
1009 ASD(("phyread_fail>\n"));
1010 return -1;
1011 }
1012 ASD(("phyread_ok,PSELECT>"));
1013 hme_write32(hp, tregs + TCVR_CFG, tconfig | TCV_CFG_PSELECT);
1014 hp->tcvr_type = external;
1015 hp->paddr = TCV_PADDR_ETX;
1016 } else {
1017 if (tconfig & TCV_CFG_MDIO1) {
1018 ASD(("internal<PSELECT,"));
1019 hme_write32(hp, tregs + TCVR_CFG, (tconfig | TCV_CFG_PSELECT));
1020 ASD(("ISOLATE,"));
1021 happy_meal_tcvr_write(hp, tregs, MII_BMCR,
1022 (BMCR_LOOPBACK|BMCR_PDOWN|BMCR_ISOLATE));
1023 result = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
1024 if (result == TCVR_FAILURE) {
1025 ASD(("phyread_fail>\n"));
1026 return -1;
1027 }
1028 ASD(("phyread_ok,~PSELECT>"));
1029 hme_write32(hp, tregs + TCVR_CFG, (tconfig & ~(TCV_CFG_PSELECT)));
1030 hp->tcvr_type = internal;
1031 hp->paddr = TCV_PADDR_ITX;
1032 }
1033 }
1034
1035 ASD(("BMCR_RESET "));
1036 happy_meal_tcvr_write(hp, tregs, MII_BMCR, BMCR_RESET);
1037
1038 while (--tries) {
1039 result = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
1040 if (result == TCVR_FAILURE)
1041 return -1;
1042 hp->sw_bmcr = result;
1043 if (!(result & BMCR_RESET))
1044 break;
1045 udelay(20);
1046 }
1047 if (!tries) {
1048 ASD(("BMCR RESET FAILED!\n"));
1049 return -1;
1050 }
1051 ASD(("RESET_OK\n"));
1052
1053
1054 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, MII_BMSR);
1055 hp->sw_physid1 = happy_meal_tcvr_read(hp, tregs, MII_PHYSID1);
1056 hp->sw_physid2 = happy_meal_tcvr_read(hp, tregs, MII_PHYSID2);
1057 hp->sw_advertise = happy_meal_tcvr_read(hp, tregs, MII_ADVERTISE);
1058
1059 ASD(("UNISOLATE"));
1060 hp->sw_bmcr &= ~(BMCR_ISOLATE);
1061 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
1062
1063 tries = TCVR_UNISOLATE_TRIES;
1064 while (--tries) {
1065 result = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
1066 if (result == TCVR_FAILURE)
1067 return -1;
1068 if (!(result & BMCR_ISOLATE))
1069 break;
1070 udelay(20);
1071 }
1072 if (!tries) {
1073 ASD((" FAILED!\n"));
1074 return -1;
1075 }
1076 ASD((" SUCCESS and CSCONFIG_DFBYPASS\n"));
1077 if (!is_lucent_phy(hp)) {
1078 result = happy_meal_tcvr_read(hp, tregs,
1079 DP83840_CSCONFIG);
1080 happy_meal_tcvr_write(hp, tregs,
1081 DP83840_CSCONFIG, (result | CSCONFIG_DFBYPASS));
1082 }
1083 return 0;
1084}
1085
1086
1087
1088
1089
1090static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tregs)
1091{
1092 unsigned long tconfig = hme_read32(hp, tregs + TCVR_CFG);
1093
1094 ASD(("happy_meal_transceiver_check: tcfg=%08lx ", tconfig));
1095 if (hp->happy_flags & HFLAG_POLL) {
1096
1097 ASD(("<polling> "));
1098 if (hp->tcvr_type == internal) {
1099 if (tconfig & TCV_CFG_MDIO1) {
1100 ASD(("<internal> <poll stop> "));
1101 happy_meal_poll_stop(hp, tregs);
1102 hp->paddr = TCV_PADDR_ETX;
1103 hp->tcvr_type = external;
1104 ASD(("<external>\n"));
1105 tconfig &= ~(TCV_CFG_PENABLE);
1106 tconfig |= TCV_CFG_PSELECT;
1107 hme_write32(hp, tregs + TCVR_CFG, tconfig);
1108 }
1109 } else {
1110 if (hp->tcvr_type == external) {
1111 ASD(("<external> "));
1112 if (!(hme_read32(hp, tregs + TCVR_STATUS) >> 16)) {
1113 ASD(("<poll stop> "));
1114 happy_meal_poll_stop(hp, tregs);
1115 hp->paddr = TCV_PADDR_ITX;
1116 hp->tcvr_type = internal;
1117 ASD(("<internal>\n"));
1118 hme_write32(hp, tregs + TCVR_CFG,
1119 hme_read32(hp, tregs + TCVR_CFG) &
1120 ~(TCV_CFG_PSELECT));
1121 }
1122 ASD(("\n"));
1123 } else {
1124 ASD(("<none>\n"));
1125 }
1126 }
1127 } else {
1128 u32 reread = hme_read32(hp, tregs + TCVR_CFG);
1129
1130
1131 ASD(("<not polling> "));
1132 if (reread & TCV_CFG_MDIO1) {
1133 hme_write32(hp, tregs + TCVR_CFG, tconfig | TCV_CFG_PSELECT);
1134 hp->paddr = TCV_PADDR_ETX;
1135 hp->tcvr_type = external;
1136 ASD(("<external>\n"));
1137 } else {
1138 if (reread & TCV_CFG_MDIO0) {
1139 hme_write32(hp, tregs + TCVR_CFG,
1140 tconfig & ~(TCV_CFG_PSELECT));
1141 hp->paddr = TCV_PADDR_ITX;
1142 hp->tcvr_type = internal;
1143 ASD(("<internal>\n"));
1144 } else {
1145 printk(KERN_ERR "happy meal: Transceiver and a coke please.");
1146 hp->tcvr_type = none;
1147 ASD(("<none>\n"));
1148 }
1149 }
1150 }
1151}
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197static void happy_meal_clean_rings(struct happy_meal *hp)
1198{
1199 int i;
1200
1201 for (i = 0; i < RX_RING_SIZE; i++) {
1202 if (hp->rx_skbs[i] != NULL) {
1203 struct sk_buff *skb = hp->rx_skbs[i];
1204 struct happy_meal_rxd *rxd;
1205 u32 dma_addr;
1206
1207 rxd = &hp->happy_block->happy_meal_rxd[i];
1208 dma_addr = hme_read_desc32(hp, &rxd->rx_addr);
1209 dma_unmap_single(hp->dma_dev, dma_addr,
1210 RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
1211 dev_kfree_skb_any(skb);
1212 hp->rx_skbs[i] = NULL;
1213 }
1214 }
1215
1216 for (i = 0; i < TX_RING_SIZE; i++) {
1217 if (hp->tx_skbs[i] != NULL) {
1218 struct sk_buff *skb = hp->tx_skbs[i];
1219 struct happy_meal_txd *txd;
1220 u32 dma_addr;
1221 int frag;
1222
1223 hp->tx_skbs[i] = NULL;
1224
1225 for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
1226 txd = &hp->happy_block->happy_meal_txd[i];
1227 dma_addr = hme_read_desc32(hp, &txd->tx_addr);
1228 if (!frag)
1229 dma_unmap_single(hp->dma_dev, dma_addr,
1230 (hme_read_desc32(hp, &txd->tx_flags)
1231 & TXFLAG_SIZE),
1232 DMA_TO_DEVICE);
1233 else
1234 dma_unmap_page(hp->dma_dev, dma_addr,
1235 (hme_read_desc32(hp, &txd->tx_flags)
1236 & TXFLAG_SIZE),
1237 DMA_TO_DEVICE);
1238
1239 if (frag != skb_shinfo(skb)->nr_frags)
1240 i++;
1241 }
1242
1243 dev_kfree_skb_any(skb);
1244 }
1245 }
1246}
1247
1248
1249static void happy_meal_init_rings(struct happy_meal *hp)
1250{
1251 struct hmeal_init_block *hb = hp->happy_block;
1252 struct net_device *dev = hp->dev;
1253 int i;
1254
1255 HMD(("happy_meal_init_rings: counters to zero, "));
1256 hp->rx_new = hp->rx_old = hp->tx_new = hp->tx_old = 0;
1257
1258
1259 HMD(("clean, "));
1260 happy_meal_clean_rings(hp);
1261
1262
1263 HMD(("init rxring, "));
1264 for (i = 0; i < RX_RING_SIZE; i++) {
1265 struct sk_buff *skb;
1266
1267 skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
1268 if (!skb) {
1269 hme_write_rxd(hp, &hb->happy_meal_rxd[i], 0, 0);
1270 continue;
1271 }
1272 hp->rx_skbs[i] = skb;
1273 skb->dev = dev;
1274
1275
1276 skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
1277 hme_write_rxd(hp, &hb->happy_meal_rxd[i],
1278 (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16)),
1279 dma_map_single(hp->dma_dev, skb->data, RX_BUF_ALLOC_SIZE,
1280 DMA_FROM_DEVICE));
1281 skb_reserve(skb, RX_OFFSET);
1282 }
1283
1284 HMD(("init txring, "));
1285 for (i = 0; i < TX_RING_SIZE; i++)
1286 hme_write_txd(hp, &hb->happy_meal_txd[i], 0, 0);
1287
1288 HMD(("done\n"));
1289}
1290
1291
1292static void happy_meal_begin_auto_negotiation(struct happy_meal *hp,
1293 void __iomem *tregs,
1294 struct ethtool_cmd *ep)
1295{
1296 int timeout;
1297
1298
1299 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, MII_BMSR);
1300 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
1301 hp->sw_physid1 = happy_meal_tcvr_read(hp, tregs, MII_PHYSID1);
1302 hp->sw_physid2 = happy_meal_tcvr_read(hp, tregs, MII_PHYSID2);
1303
1304
1305
1306 hp->sw_advertise = happy_meal_tcvr_read(hp, tregs, MII_ADVERTISE);
1307 if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) {
1308
1309 if (hp->sw_bmsr & BMSR_10HALF)
1310 hp->sw_advertise |= (ADVERTISE_10HALF);
1311 else
1312 hp->sw_advertise &= ~(ADVERTISE_10HALF);
1313
1314 if (hp->sw_bmsr & BMSR_10FULL)
1315 hp->sw_advertise |= (ADVERTISE_10FULL);
1316 else
1317 hp->sw_advertise &= ~(ADVERTISE_10FULL);
1318 if (hp->sw_bmsr & BMSR_100HALF)
1319 hp->sw_advertise |= (ADVERTISE_100HALF);
1320 else
1321 hp->sw_advertise &= ~(ADVERTISE_100HALF);
1322 if (hp->sw_bmsr & BMSR_100FULL)
1323 hp->sw_advertise |= (ADVERTISE_100FULL);
1324 else
1325 hp->sw_advertise &= ~(ADVERTISE_100FULL);
1326 happy_meal_tcvr_write(hp, tregs, MII_ADVERTISE, hp->sw_advertise);
1327
1328
1329
1330
1331
1332
1333
1334#ifdef AUTO_SWITCH_DEBUG
1335 ASD(("%s: Advertising [ ", hp->dev->name));
1336 if (hp->sw_advertise & ADVERTISE_10HALF)
1337 ASD(("10H "));
1338 if (hp->sw_advertise & ADVERTISE_10FULL)
1339 ASD(("10F "));
1340 if (hp->sw_advertise & ADVERTISE_100HALF)
1341 ASD(("100H "));
1342 if (hp->sw_advertise & ADVERTISE_100FULL)
1343 ASD(("100F "));
1344#endif
1345
1346
1347 hp->sw_bmcr |= BMCR_ANENABLE;
1348 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
1349
1350
1351 hp->sw_bmcr |= BMCR_ANRESTART;
1352 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
1353
1354
1355
1356 timeout = 64;
1357 while (--timeout) {
1358 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
1359 if (!(hp->sw_bmcr & BMCR_ANRESTART))
1360 break;
1361 udelay(10);
1362 }
1363 if (!timeout) {
1364 printk(KERN_ERR "%s: Happy Meal would not start auto negotiation "
1365 "BMCR=0x%04x\n", hp->dev->name, hp->sw_bmcr);
1366 printk(KERN_NOTICE "%s: Performing force link detection.\n",
1367 hp->dev->name);
1368 goto force_link;
1369 } else {
1370 hp->timer_state = arbwait;
1371 }
1372 } else {
1373force_link:
1374
1375
1376
1377
1378
1379
1380
1381
1382 if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) {
1383 hp->sw_bmcr = BMCR_SPEED100;
1384 } else {
1385 if (ethtool_cmd_speed(ep) == SPEED_100)
1386 hp->sw_bmcr = BMCR_SPEED100;
1387 else
1388 hp->sw_bmcr = 0;
1389 if (ep->duplex == DUPLEX_FULL)
1390 hp->sw_bmcr |= BMCR_FULLDPLX;
1391 }
1392 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
1393
1394 if (!is_lucent_phy(hp)) {
1395
1396
1397
1398
1399 hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs,
1400 DP83840_CSCONFIG);
1401 hp->sw_csconfig &= ~(CSCONFIG_TCVDISAB);
1402 happy_meal_tcvr_write(hp, tregs, DP83840_CSCONFIG,
1403 hp->sw_csconfig);
1404 }
1405 hp->timer_state = ltrywait;
1406 }
1407
1408 hp->timer_ticks = 0;
1409 hp->happy_timer.expires = jiffies + (12 * HZ)/10;
1410 hp->happy_timer.data = (unsigned long) hp;
1411 hp->happy_timer.function = happy_meal_timer;
1412 add_timer(&hp->happy_timer);
1413}
1414
1415
1416static int happy_meal_init(struct happy_meal *hp)
1417{
1418 void __iomem *gregs = hp->gregs;
1419 void __iomem *etxregs = hp->etxregs;
1420 void __iomem *erxregs = hp->erxregs;
1421 void __iomem *bregs = hp->bigmacregs;
1422 void __iomem *tregs = hp->tcvregs;
1423 u32 regtmp, rxcfg;
1424 unsigned char *e = &hp->dev->dev_addr[0];
1425
1426
1427 del_timer(&hp->happy_timer);
1428
1429 HMD(("happy_meal_init: happy_flags[%08x] ",
1430 hp->happy_flags));
1431 if (!(hp->happy_flags & HFLAG_INIT)) {
1432 HMD(("set HFLAG_INIT, "));
1433 hp->happy_flags |= HFLAG_INIT;
1434 happy_meal_get_counters(hp, bregs);
1435 }
1436
1437
1438 HMD(("to happy_meal_poll_stop\n"));
1439 happy_meal_poll_stop(hp, tregs);
1440
1441
1442 HMD(("happy_meal_init: to happy_meal_stop\n"));
1443 happy_meal_stop(hp, gregs);
1444
1445
1446 HMD(("happy_meal_init: to happy_meal_init_rings\n"));
1447 happy_meal_init_rings(hp);
1448
1449
1450 HMD(("happy_meal_init: Disable all MIF irqs (old[%08x]), ",
1451 hme_read32(hp, tregs + TCVR_IMASK)));
1452 hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
1453
1454
1455 if (hp->happy_flags & HFLAG_FENABLE) {
1456 HMD(("use frame old[%08x], ",
1457 hme_read32(hp, tregs + TCVR_CFG)));
1458 hme_write32(hp, tregs + TCVR_CFG,
1459 hme_read32(hp, tregs + TCVR_CFG) & ~(TCV_CFG_BENABLE));
1460 } else {
1461 HMD(("use bitbang old[%08x], ",
1462 hme_read32(hp, tregs + TCVR_CFG)));
1463 hme_write32(hp, tregs + TCVR_CFG,
1464 hme_read32(hp, tregs + TCVR_CFG) | TCV_CFG_BENABLE);
1465 }
1466
1467
1468 HMD(("to happy_meal_transceiver_check\n"));
1469 happy_meal_transceiver_check(hp, tregs);
1470
1471
1472 HMD(("happy_meal_init: "));
1473 switch(hp->tcvr_type) {
1474 case none:
1475
1476 HMD(("AAIEEE no transceiver type, EAGAIN"));
1477 return -EAGAIN;
1478
1479 case internal:
1480
1481 HMD(("internal, using MII, "));
1482 hme_write32(hp, bregs + BMAC_XIFCFG, 0);
1483 break;
1484
1485 case external:
1486
1487 HMD(("external, disable MII, "));
1488 hme_write32(hp, bregs + BMAC_XIFCFG, BIGMAC_XCFG_MIIDISAB);
1489 break;
1490 }
1491
1492 if (happy_meal_tcvr_reset(hp, tregs))
1493 return -EAGAIN;
1494
1495
1496 HMD(("tx/rx reset, "));
1497 happy_meal_tx_reset(hp, bregs);
1498 happy_meal_rx_reset(hp, bregs);
1499
1500
1501 HMD(("jsize/ipg1/ipg2, "));
1502 hme_write32(hp, bregs + BMAC_JSIZE, DEFAULT_JAMSIZE);
1503 hme_write32(hp, bregs + BMAC_IGAP1, DEFAULT_IPG1);
1504 hme_write32(hp, bregs + BMAC_IGAP2, DEFAULT_IPG2);
1505
1506
1507 HMD(("rseed/macaddr, "));
1508
1509
1510 hme_write32(hp, bregs + BMAC_RSEED, ((e[5] | e[4]<<8)&0x3ff));
1511
1512 hme_write32(hp, bregs + BMAC_MACADDR2, ((e[4] << 8) | e[5]));
1513 hme_write32(hp, bregs + BMAC_MACADDR1, ((e[2] << 8) | e[3]));
1514 hme_write32(hp, bregs + BMAC_MACADDR0, ((e[0] << 8) | e[1]));
1515
1516 HMD(("htable, "));
1517 if ((hp->dev->flags & IFF_ALLMULTI) ||
1518 (netdev_mc_count(hp->dev) > 64)) {
1519 hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff);
1520 hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff);
1521 hme_write32(hp, bregs + BMAC_HTABLE2, 0xffff);
1522 hme_write32(hp, bregs + BMAC_HTABLE3, 0xffff);
1523 } else if ((hp->dev->flags & IFF_PROMISC) == 0) {
1524 u16 hash_table[4];
1525 struct netdev_hw_addr *ha;
1526 u32 crc;
1527
1528 memset(hash_table, 0, sizeof(hash_table));
1529 netdev_for_each_mc_addr(ha, hp->dev) {
1530 crc = ether_crc_le(6, ha->addr);
1531 crc >>= 26;
1532 hash_table[crc >> 4] |= 1 << (crc & 0xf);
1533 }
1534 hme_write32(hp, bregs + BMAC_HTABLE0, hash_table[0]);
1535 hme_write32(hp, bregs + BMAC_HTABLE1, hash_table[1]);
1536 hme_write32(hp, bregs + BMAC_HTABLE2, hash_table[2]);
1537 hme_write32(hp, bregs + BMAC_HTABLE3, hash_table[3]);
1538 } else {
1539 hme_write32(hp, bregs + BMAC_HTABLE3, 0);
1540 hme_write32(hp, bregs + BMAC_HTABLE2, 0);
1541 hme_write32(hp, bregs + BMAC_HTABLE1, 0);
1542 hme_write32(hp, bregs + BMAC_HTABLE0, 0);
1543 }
1544
1545
1546 HMD(("ring ptrs rxr[%08x] txr[%08x]\n",
1547 ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)),
1548 ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0))));
1549 hme_write32(hp, erxregs + ERX_RING,
1550 ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)));
1551 hme_write32(hp, etxregs + ETX_RING,
1552 ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0)));
1553
1554
1555
1556
1557
1558
1559 if (hme_read32(hp, erxregs + ERX_RING) !=
1560 ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)))
1561 hme_write32(hp, erxregs + ERX_RING,
1562 ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0))
1563 | 0x4);
1564
1565
1566 HMD(("happy_meal_init: old[%08x] bursts<",
1567 hme_read32(hp, gregs + GREG_CFG)));
1568
1569#ifndef CONFIG_SPARC
1570
1571 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64);
1572#else
1573 if ((hp->happy_bursts & DMA_BURST64) &&
1574 ((hp->happy_flags & HFLAG_PCI) != 0
1575#ifdef CONFIG_SBUS
1576 || sbus_can_burst64()
1577#endif
1578 || 0)) {
1579 u32 gcfg = GREG_CFG_BURST64;
1580
1581
1582
1583
1584
1585#ifdef CONFIG_SBUS
1586 if ((hp->happy_flags & HFLAG_PCI) == 0) {
1587 struct platform_device *op = hp->happy_dev;
1588 if (sbus_can_dma_64bit()) {
1589 sbus_set_sbus64(&op->dev,
1590 hp->happy_bursts);
1591 gcfg |= GREG_CFG_64BIT;
1592 }
1593 }
1594#endif
1595
1596 HMD(("64>"));
1597 hme_write32(hp, gregs + GREG_CFG, gcfg);
1598 } else if (hp->happy_bursts & DMA_BURST32) {
1599 HMD(("32>"));
1600 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST32);
1601 } else if (hp->happy_bursts & DMA_BURST16) {
1602 HMD(("16>"));
1603 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST16);
1604 } else {
1605 HMD(("XXX>"));
1606 hme_write32(hp, gregs + GREG_CFG, 0);
1607 }
1608#endif
1609
1610
1611 HMD((", enable global interrupts, "));
1612 hme_write32(hp, gregs + GREG_IMASK,
1613 (GREG_IMASK_GOTFRAME | GREG_IMASK_RCNTEXP |
1614 GREG_IMASK_SENTFRAME | GREG_IMASK_TXPERR));
1615
1616
1617 HMD(("tx rsize=%d oreg[%08x], ", (int)TX_RING_SIZE,
1618 hme_read32(hp, etxregs + ETX_RSIZE)));
1619 hme_write32(hp, etxregs + ETX_RSIZE, (TX_RING_SIZE >> ETX_RSIZE_SHIFT) - 1);
1620
1621
1622 HMD(("tx dma enable old[%08x], ",
1623 hme_read32(hp, etxregs + ETX_CFG)));
1624 hme_write32(hp, etxregs + ETX_CFG,
1625 hme_read32(hp, etxregs + ETX_CFG) | ETX_CFG_DMAENABLE);
1626
1627
1628
1629
1630
1631
1632 HMD(("erx regs bug old[%08x]\n",
1633 hme_read32(hp, erxregs + ERX_CFG)));
1634 hme_write32(hp, erxregs + ERX_CFG, ERX_CFG_DEFAULT(RX_OFFSET));
1635 regtmp = hme_read32(hp, erxregs + ERX_CFG);
1636 hme_write32(hp, erxregs + ERX_CFG, ERX_CFG_DEFAULT(RX_OFFSET));
1637 if (hme_read32(hp, erxregs + ERX_CFG) != ERX_CFG_DEFAULT(RX_OFFSET)) {
1638 printk(KERN_ERR "happy meal: Eieee, rx config register gets greasy fries.\n");
1639 printk(KERN_ERR "happy meal: Trying to set %08x, reread gives %08x\n",
1640 ERX_CFG_DEFAULT(RX_OFFSET), regtmp);
1641
1642 }
1643
1644
1645 HMD(("happy_meal_init: enable hash rx_cfg_old[%08x], ",
1646 hme_read32(hp, bregs + BMAC_RXCFG)));
1647 rxcfg = BIGMAC_RXCFG_HENABLE | BIGMAC_RXCFG_REJME;
1648 if (hp->dev->flags & IFF_PROMISC)
1649 rxcfg |= BIGMAC_RXCFG_PMISC;
1650 hme_write32(hp, bregs + BMAC_RXCFG, rxcfg);
1651
1652
1653 udelay(10);
1654
1655
1656 HMD(("BIGMAC init, "));
1657 regtmp = 0;
1658 if (hp->happy_flags & HFLAG_FULL)
1659 regtmp |= BIGMAC_TXCFG_FULLDPLX;
1660
1661
1662
1663
1664 hme_write32(hp, bregs + BMAC_TXCFG, regtmp );
1665
1666
1667 hme_write32(hp, bregs + BMAC_ALIMIT, 16);
1668
1669
1670 regtmp = BIGMAC_XCFG_ODENABLE;
1671
1672
1673 if (hp->happy_flags & HFLAG_LANCE)
1674 regtmp |= (DEFAULT_IPG0 << 5) | BIGMAC_XCFG_LANCE;
1675
1676
1677 if (hp->tcvr_type == external)
1678 regtmp |= BIGMAC_XCFG_MIIDISAB;
1679
1680 HMD(("XIF config old[%08x], ",
1681 hme_read32(hp, bregs + BMAC_XIFCFG)));
1682 hme_write32(hp, bregs + BMAC_XIFCFG, regtmp);
1683
1684
1685 HMD(("tx old[%08x] and rx [%08x] ON!\n",
1686 hme_read32(hp, bregs + BMAC_TXCFG),
1687 hme_read32(hp, bregs + BMAC_RXCFG)));
1688
1689
1690 hme_write32(hp, bregs + BMAC_TXMAX, ETH_FRAME_LEN + 8);
1691 hme_write32(hp, bregs + BMAC_RXMAX, ETH_FRAME_LEN + 8);
1692
1693 hme_write32(hp, bregs + BMAC_TXCFG,
1694 hme_read32(hp, bregs + BMAC_TXCFG) | BIGMAC_TXCFG_ENABLE);
1695 hme_write32(hp, bregs + BMAC_RXCFG,
1696 hme_read32(hp, bregs + BMAC_RXCFG) | BIGMAC_RXCFG_ENABLE);
1697
1698
1699 happy_meal_begin_auto_negotiation(hp, tregs, NULL);
1700
1701
1702 return 0;
1703}
1704
1705
1706static void happy_meal_set_initial_advertisement(struct happy_meal *hp)
1707{
1708 void __iomem *tregs = hp->tcvregs;
1709 void __iomem *bregs = hp->bigmacregs;
1710 void __iomem *gregs = hp->gregs;
1711
1712 happy_meal_stop(hp, gregs);
1713 hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
1714 if (hp->happy_flags & HFLAG_FENABLE)
1715 hme_write32(hp, tregs + TCVR_CFG,
1716 hme_read32(hp, tregs + TCVR_CFG) & ~(TCV_CFG_BENABLE));
1717 else
1718 hme_write32(hp, tregs + TCVR_CFG,
1719 hme_read32(hp, tregs + TCVR_CFG) | TCV_CFG_BENABLE);
1720 happy_meal_transceiver_check(hp, tregs);
1721 switch(hp->tcvr_type) {
1722 case none:
1723 return;
1724 case internal:
1725 hme_write32(hp, bregs + BMAC_XIFCFG, 0);
1726 break;
1727 case external:
1728 hme_write32(hp, bregs + BMAC_XIFCFG, BIGMAC_XCFG_MIIDISAB);
1729 break;
1730 }
1731 if (happy_meal_tcvr_reset(hp, tregs))
1732 return;
1733
1734
1735 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, MII_BMSR);
1736 hp->sw_advertise = happy_meal_tcvr_read(hp, tregs, MII_ADVERTISE);
1737
1738
1739 if (hp->sw_bmsr & BMSR_10HALF)
1740 hp->sw_advertise |= (ADVERTISE_10HALF);
1741 else
1742 hp->sw_advertise &= ~(ADVERTISE_10HALF);
1743
1744 if (hp->sw_bmsr & BMSR_10FULL)
1745 hp->sw_advertise |= (ADVERTISE_10FULL);
1746 else
1747 hp->sw_advertise &= ~(ADVERTISE_10FULL);
1748 if (hp->sw_bmsr & BMSR_100HALF)
1749 hp->sw_advertise |= (ADVERTISE_100HALF);
1750 else
1751 hp->sw_advertise &= ~(ADVERTISE_100HALF);
1752 if (hp->sw_bmsr & BMSR_100FULL)
1753 hp->sw_advertise |= (ADVERTISE_100FULL);
1754 else
1755 hp->sw_advertise &= ~(ADVERTISE_100FULL);
1756
1757
1758 happy_meal_tcvr_write(hp, tregs, MII_ADVERTISE, hp->sw_advertise);
1759}
1760
1761
1762
1763
1764
1765
1766static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status)
1767{
1768 int reset = 0;
1769
1770
1771 if (status & (GREG_STAT_STSTERR | GREG_STAT_TFIFO_UND |
1772 GREG_STAT_MAXPKTERR | GREG_STAT_RXERR |
1773 GREG_STAT_RXPERR | GREG_STAT_RXTERR | GREG_STAT_EOPERR |
1774 GREG_STAT_MIFIRQ | GREG_STAT_TXEACK | GREG_STAT_TXLERR |
1775 GREG_STAT_TXPERR | GREG_STAT_TXTERR | GREG_STAT_SLVERR |
1776 GREG_STAT_SLVPERR))
1777 printk(KERN_ERR "%s: Error interrupt for happy meal, status = %08x\n",
1778 hp->dev->name, status);
1779
1780 if (status & GREG_STAT_RFIFOVF) {
1781
1782
1783 printk(KERN_DEBUG "%s: Happy Meal receive FIFO overflow.\n", hp->dev->name);
1784 }
1785
1786 if (status & GREG_STAT_STSTERR) {
1787
1788 printk(KERN_ERR "%s: Happy Meal BigMAC SQE test failed.\n", hp->dev->name);
1789 reset = 1;
1790 }
1791
1792 if (status & GREG_STAT_TFIFO_UND) {
1793
1794 printk(KERN_ERR "%s: Happy Meal transmitter FIFO underrun, DMA error.\n",
1795 hp->dev->name);
1796 reset = 1;
1797 }
1798
1799 if (status & GREG_STAT_MAXPKTERR) {
1800
1801
1802
1803 printk(KERN_ERR "%s: Happy Meal MAX Packet size error.\n", hp->dev->name);
1804 reset = 1;
1805 }
1806
1807 if (status & GREG_STAT_NORXD) {
1808
1809
1810
1811
1812
1813 printk(KERN_INFO "%s: Happy Meal out of receive "
1814 "descriptors, packet dropped.\n",
1815 hp->dev->name);
1816 }
1817
1818 if (status & (GREG_STAT_RXERR|GREG_STAT_RXPERR|GREG_STAT_RXTERR)) {
1819
1820 printk(KERN_ERR "%s: Happy Meal rx DMA errors [ ", hp->dev->name);
1821 if (status & GREG_STAT_RXERR)
1822 printk("GenericError ");
1823 if (status & GREG_STAT_RXPERR)
1824 printk("ParityError ");
1825 if (status & GREG_STAT_RXTERR)
1826 printk("RxTagBotch ");
1827 printk("]\n");
1828 reset = 1;
1829 }
1830
1831 if (status & GREG_STAT_EOPERR) {
1832
1833
1834
1835 printk(KERN_ERR "%s: EOP not set in happy meal transmit descriptor!\n",
1836 hp->dev->name);
1837 reset = 1;
1838 }
1839
1840 if (status & GREG_STAT_MIFIRQ) {
1841
1842 printk(KERN_ERR "%s: Happy Meal MIF interrupt.\n", hp->dev->name);
1843 }
1844
1845 if (status &
1846 (GREG_STAT_TXEACK|GREG_STAT_TXLERR|GREG_STAT_TXPERR|GREG_STAT_TXTERR)) {
1847
1848 printk(KERN_ERR "%s: Happy Meal tx DMA errors [ ", hp->dev->name);
1849 if (status & GREG_STAT_TXEACK)
1850 printk("GenericError ");
1851 if (status & GREG_STAT_TXLERR)
1852 printk("LateError ");
1853 if (status & GREG_STAT_TXPERR)
1854 printk("ParityErro ");
1855 if (status & GREG_STAT_TXTERR)
1856 printk("TagBotch ");
1857 printk("]\n");
1858 reset = 1;
1859 }
1860
1861 if (status & (GREG_STAT_SLVERR|GREG_STAT_SLVPERR)) {
1862
1863
1864
1865 printk(KERN_ERR "%s: Happy Meal register access SBUS slave (%s) error.\n",
1866 hp->dev->name,
1867 (status & GREG_STAT_SLVPERR) ? "parity" : "generic");
1868 reset = 1;
1869 }
1870
1871 if (reset) {
1872 printk(KERN_NOTICE "%s: Resetting...\n", hp->dev->name);
1873 happy_meal_init(hp);
1874 return 1;
1875 }
1876 return 0;
1877}
1878
1879
1880static void happy_meal_mif_interrupt(struct happy_meal *hp)
1881{
1882 void __iomem *tregs = hp->tcvregs;
1883
1884 printk(KERN_INFO "%s: Link status change.\n", hp->dev->name);
1885 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
1886 hp->sw_lpa = happy_meal_tcvr_read(hp, tregs, MII_LPA);
1887
1888
1889 if (hp->sw_lpa & LPA_100FULL) {
1890 printk(KERN_INFO "%s: Switching to 100Mbps at full duplex.", hp->dev->name);
1891 hp->sw_bmcr |= (BMCR_FULLDPLX | BMCR_SPEED100);
1892 } else if (hp->sw_lpa & LPA_100HALF) {
1893 printk(KERN_INFO "%s: Switching to 100MBps at half duplex.", hp->dev->name);
1894 hp->sw_bmcr |= BMCR_SPEED100;
1895 } else if (hp->sw_lpa & LPA_10FULL) {
1896 printk(KERN_INFO "%s: Switching to 10MBps at full duplex.", hp->dev->name);
1897 hp->sw_bmcr |= BMCR_FULLDPLX;
1898 } else {
1899 printk(KERN_INFO "%s: Using 10Mbps at half duplex.", hp->dev->name);
1900 }
1901 happy_meal_tcvr_write(hp, tregs, MII_BMCR, hp->sw_bmcr);
1902
1903
1904 happy_meal_poll_stop(hp, tregs);
1905}
1906
1907#ifdef TXDEBUG
1908#define TXD(x) printk x
1909#else
1910#define TXD(x)
1911#endif
1912
1913
1914static void happy_meal_tx(struct happy_meal *hp)
1915{
1916 struct happy_meal_txd *txbase = &hp->happy_block->happy_meal_txd[0];
1917 struct happy_meal_txd *this;
1918 struct net_device *dev = hp->dev;
1919 int elem;
1920
1921 elem = hp->tx_old;
1922 TXD(("TX<"));
1923 while (elem != hp->tx_new) {
1924 struct sk_buff *skb;
1925 u32 flags, dma_addr, dma_len;
1926 int frag;
1927
1928 TXD(("[%d]", elem));
1929 this = &txbase[elem];
1930 flags = hme_read_desc32(hp, &this->tx_flags);
1931 if (flags & TXFLAG_OWN)
1932 break;
1933 skb = hp->tx_skbs[elem];
1934 if (skb_shinfo(skb)->nr_frags) {
1935 int last;
1936
1937 last = elem + skb_shinfo(skb)->nr_frags;
1938 last &= (TX_RING_SIZE - 1);
1939 flags = hme_read_desc32(hp, &txbase[last].tx_flags);
1940 if (flags & TXFLAG_OWN)
1941 break;
1942 }
1943 hp->tx_skbs[elem] = NULL;
1944 hp->net_stats.tx_bytes += skb->len;
1945
1946 for (frag = 0; frag <= skb_shinfo(skb)->nr_frags; frag++) {
1947 dma_addr = hme_read_desc32(hp, &this->tx_addr);
1948 dma_len = hme_read_desc32(hp, &this->tx_flags);
1949
1950 dma_len &= TXFLAG_SIZE;
1951 if (!frag)
1952 dma_unmap_single(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE);
1953 else
1954 dma_unmap_page(hp->dma_dev, dma_addr, dma_len, DMA_TO_DEVICE);
1955
1956 elem = NEXT_TX(elem);
1957 this = &txbase[elem];
1958 }
1959
1960 dev_kfree_skb_irq(skb);
1961 hp->net_stats.tx_packets++;
1962 }
1963 hp->tx_old = elem;
1964 TXD((">"));
1965
1966 if (netif_queue_stopped(dev) &&
1967 TX_BUFFS_AVAIL(hp) > (MAX_SKB_FRAGS + 1))
1968 netif_wake_queue(dev);
1969}
1970
1971#ifdef RXDEBUG
1972#define RXD(x) printk x
1973#else
1974#define RXD(x)
1975#endif
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
1987{
1988 struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0];
1989 struct happy_meal_rxd *this;
1990 int elem = hp->rx_new, drops = 0;
1991 u32 flags;
1992
1993 RXD(("RX<"));
1994 this = &rxbase[elem];
1995 while (!((flags = hme_read_desc32(hp, &this->rx_flags)) & RXFLAG_OWN)) {
1996 struct sk_buff *skb;
1997 int len = flags >> 16;
1998 u16 csum = flags & RXFLAG_CSUM;
1999 u32 dma_addr = hme_read_desc32(hp, &this->rx_addr);
2000
2001 RXD(("[%d ", elem));
2002
2003
2004 if ((len < ETH_ZLEN) || (flags & RXFLAG_OVERFLOW)) {
2005 RXD(("ERR(%08x)]", flags));
2006 hp->net_stats.rx_errors++;
2007 if (len < ETH_ZLEN)
2008 hp->net_stats.rx_length_errors++;
2009 if (len & (RXFLAG_OVERFLOW >> 16)) {
2010 hp->net_stats.rx_over_errors++;
2011 hp->net_stats.rx_fifo_errors++;
2012 }
2013
2014
2015 drop_it:
2016 hp->net_stats.rx_dropped++;
2017 hme_write_rxd(hp, this,
2018 (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
2019 dma_addr);
2020 goto next;
2021 }
2022 skb = hp->rx_skbs[elem];
2023 if (len > RX_COPY_THRESHOLD) {
2024 struct sk_buff *new_skb;
2025
2026
2027 new_skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
2028 if (new_skb == NULL) {
2029 drops++;
2030 goto drop_it;
2031 }
2032 dma_unmap_single(hp->dma_dev, dma_addr, RX_BUF_ALLOC_SIZE, DMA_FROM_DEVICE);
2033 hp->rx_skbs[elem] = new_skb;
2034 new_skb->dev = dev;
2035 skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET + 4));
2036 hme_write_rxd(hp, this,
2037 (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
2038 dma_map_single(hp->dma_dev, new_skb->data, RX_BUF_ALLOC_SIZE,
2039 DMA_FROM_DEVICE));
2040 skb_reserve(new_skb, RX_OFFSET);
2041
2042
2043 skb_trim(skb, len);
2044 } else {
2045 struct sk_buff *copy_skb = netdev_alloc_skb(dev, len + 2);
2046
2047 if (copy_skb == NULL) {
2048 drops++;
2049 goto drop_it;
2050 }
2051
2052 skb_reserve(copy_skb, 2);
2053 skb_put(copy_skb, len);
2054 dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
2055 skb_copy_from_linear_data(skb, copy_skb->data, len);
2056 dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE);
2057
2058 hme_write_rxd(hp, this,
2059 (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
2060 dma_addr);
2061
2062 skb = copy_skb;
2063 }
2064
2065
2066 skb->csum = csum_unfold(~(__force __sum16)htons(csum));
2067 skb->ip_summed = CHECKSUM_COMPLETE;
2068
2069 RXD(("len=%d csum=%4x]", len, csum));
2070 skb->protocol = eth_type_trans(skb, dev);
2071 netif_rx(skb);
2072
2073 hp->net_stats.rx_packets++;
2074 hp->net_stats.rx_bytes += len;
2075 next:
2076 elem = NEXT_RX(elem);
2077 this = &rxbase[elem];
2078 }
2079 hp->rx_new = elem;
2080 if (drops)
2081 printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", hp->dev->name);
2082 RXD((">"));
2083}
2084
2085static irqreturn_t happy_meal_interrupt(int irq, void *dev_id)
2086{
2087 struct net_device *dev = dev_id;
2088 struct happy_meal *hp = netdev_priv(dev);
2089 u32 happy_status = hme_read32(hp, hp->gregs + GREG_STAT);
2090
2091 HMD(("happy_meal_interrupt: status=%08x ", happy_status));
2092
2093 spin_lock(&hp->happy_lock);
2094
2095 if (happy_status & GREG_STAT_ERRORS) {
2096 HMD(("ERRORS "));
2097 if (happy_meal_is_not_so_happy(hp, happy_status))
2098 goto out;
2099 }
2100
2101 if (happy_status & GREG_STAT_MIFIRQ) {
2102 HMD(("MIFIRQ "));
2103 happy_meal_mif_interrupt(hp);
2104 }
2105
2106 if (happy_status & GREG_STAT_TXALL) {
2107 HMD(("TXALL "));
2108 happy_meal_tx(hp);
2109 }
2110
2111 if (happy_status & GREG_STAT_RXTOHOST) {
2112 HMD(("RXTOHOST "));
2113 happy_meal_rx(hp, dev);
2114 }
2115
2116 HMD(("done\n"));
2117out:
2118 spin_unlock(&hp->happy_lock);
2119
2120 return IRQ_HANDLED;
2121}
2122
2123#ifdef CONFIG_SBUS
2124static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie)
2125{
2126 struct quattro *qp = (struct quattro *) cookie;
2127 int i;
2128
2129 for (i = 0; i < 4; i++) {
2130 struct net_device *dev = qp->happy_meals[i];
2131 struct happy_meal *hp = netdev_priv(dev);
2132 u32 happy_status = hme_read32(hp, hp->gregs + GREG_STAT);
2133
2134 HMD(("quattro_interrupt: status=%08x ", happy_status));
2135
2136 if (!(happy_status & (GREG_STAT_ERRORS |
2137 GREG_STAT_MIFIRQ |
2138 GREG_STAT_TXALL |
2139 GREG_STAT_RXTOHOST)))
2140 continue;
2141
2142 spin_lock(&hp->happy_lock);
2143
2144 if (happy_status & GREG_STAT_ERRORS) {
2145 HMD(("ERRORS "));
2146 if (happy_meal_is_not_so_happy(hp, happy_status))
2147 goto next;
2148 }
2149
2150 if (happy_status & GREG_STAT_MIFIRQ) {
2151 HMD(("MIFIRQ "));
2152 happy_meal_mif_interrupt(hp);
2153 }
2154
2155 if (happy_status & GREG_STAT_TXALL) {
2156 HMD(("TXALL "));
2157 happy_meal_tx(hp);
2158 }
2159
2160 if (happy_status & GREG_STAT_RXTOHOST) {
2161 HMD(("RXTOHOST "));
2162 happy_meal_rx(hp, dev);
2163 }
2164
2165 next:
2166 spin_unlock(&hp->happy_lock);
2167 }
2168 HMD(("done\n"));
2169
2170 return IRQ_HANDLED;
2171}
2172#endif
2173
2174static int happy_meal_open(struct net_device *dev)
2175{
2176 struct happy_meal *hp = netdev_priv(dev);
2177 int res;
2178
2179 HMD(("happy_meal_open: "));
2180
2181
2182
2183
2184 if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) {
2185 if (request_irq(dev->irq, happy_meal_interrupt,
2186 IRQF_SHARED, dev->name, (void *)dev)) {
2187 HMD(("EAGAIN\n"));
2188 printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n",
2189 dev->irq);
2190
2191 return -EAGAIN;
2192 }
2193 }
2194
2195 HMD(("to happy_meal_init\n"));
2196
2197 spin_lock_irq(&hp->happy_lock);
2198 res = happy_meal_init(hp);
2199 spin_unlock_irq(&hp->happy_lock);
2200
2201 if (res && ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO))
2202 free_irq(dev->irq, dev);
2203 return res;
2204}
2205
2206static int happy_meal_close(struct net_device *dev)
2207{
2208 struct happy_meal *hp = netdev_priv(dev);
2209
2210 spin_lock_irq(&hp->happy_lock);
2211 happy_meal_stop(hp, hp->gregs);
2212 happy_meal_clean_rings(hp);
2213
2214
2215 del_timer(&hp->happy_timer);
2216
2217 spin_unlock_irq(&hp->happy_lock);
2218
2219
2220
2221
2222
2223 if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO)
2224 free_irq(dev->irq, dev);
2225
2226 return 0;
2227}
2228
2229#ifdef SXDEBUG
2230#define SXD(x) printk x
2231#else
2232#define SXD(x)
2233#endif
2234
2235static void happy_meal_tx_timeout(struct net_device *dev)
2236{
2237 struct happy_meal *hp = netdev_priv(dev);
2238
2239 printk (KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
2240 tx_dump_log();
2241 printk (KERN_ERR "%s: Happy Status %08x TX[%08x:%08x]\n", dev->name,
2242 hme_read32(hp, hp->gregs + GREG_STAT),
2243 hme_read32(hp, hp->etxregs + ETX_CFG),
2244 hme_read32(hp, hp->bigmacregs + BMAC_TXCFG));
2245
2246 spin_lock_irq(&hp->happy_lock);
2247 happy_meal_init(hp);
2248 spin_unlock_irq(&hp->happy_lock);
2249
2250 netif_wake_queue(dev);
2251}
2252
2253static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
2254 struct net_device *dev)
2255{
2256 struct happy_meal *hp = netdev_priv(dev);
2257 int entry;
2258 u32 tx_flags;
2259
2260 tx_flags = TXFLAG_OWN;
2261 if (skb->ip_summed == CHECKSUM_PARTIAL) {
2262 const u32 csum_start_off = skb_checksum_start_offset(skb);
2263 const u32 csum_stuff_off = csum_start_off + skb->csum_offset;
2264
2265 tx_flags = (TXFLAG_OWN | TXFLAG_CSENABLE |
2266 ((csum_start_off << 14) & TXFLAG_CSBUFBEGIN) |
2267 ((csum_stuff_off << 20) & TXFLAG_CSLOCATION));
2268 }
2269
2270 spin_lock_irq(&hp->happy_lock);
2271
2272 if (TX_BUFFS_AVAIL(hp) <= (skb_shinfo(skb)->nr_frags + 1)) {
2273 netif_stop_queue(dev);
2274 spin_unlock_irq(&hp->happy_lock);
2275 printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
2276 dev->name);
2277 return NETDEV_TX_BUSY;
2278 }
2279
2280 entry = hp->tx_new;
2281 SXD(("SX<l[%d]e[%d]>", len, entry));
2282 hp->tx_skbs[entry] = skb;
2283
2284 if (skb_shinfo(skb)->nr_frags == 0) {
2285 u32 mapping, len;
2286
2287 len = skb->len;
2288 mapping = dma_map_single(hp->dma_dev, skb->data, len, DMA_TO_DEVICE);
2289 tx_flags |= (TXFLAG_SOP | TXFLAG_EOP);
2290 hme_write_txd(hp, &hp->happy_block->happy_meal_txd[entry],
2291 (tx_flags | (len & TXFLAG_SIZE)),
2292 mapping);
2293 entry = NEXT_TX(entry);
2294 } else {
2295 u32 first_len, first_mapping;
2296 int frag, first_entry = entry;
2297
2298
2299
2300
2301 first_len = skb_headlen(skb);
2302 first_mapping = dma_map_single(hp->dma_dev, skb->data, first_len,
2303 DMA_TO_DEVICE);
2304 entry = NEXT_TX(entry);
2305
2306 for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
2307 const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
2308 u32 len, mapping, this_txflags;
2309
2310 len = skb_frag_size(this_frag);
2311 mapping = skb_frag_dma_map(hp->dma_dev, this_frag,
2312 0, len, DMA_TO_DEVICE);
2313 this_txflags = tx_flags;
2314 if (frag == skb_shinfo(skb)->nr_frags - 1)
2315 this_txflags |= TXFLAG_EOP;
2316 hme_write_txd(hp, &hp->happy_block->happy_meal_txd[entry],
2317 (this_txflags | (len & TXFLAG_SIZE)),
2318 mapping);
2319 entry = NEXT_TX(entry);
2320 }
2321 hme_write_txd(hp, &hp->happy_block->happy_meal_txd[first_entry],
2322 (tx_flags | TXFLAG_SOP | (first_len & TXFLAG_SIZE)),
2323 first_mapping);
2324 }
2325
2326 hp->tx_new = entry;
2327
2328 if (TX_BUFFS_AVAIL(hp) <= (MAX_SKB_FRAGS + 1))
2329 netif_stop_queue(dev);
2330
2331
2332 hme_write32(hp, hp->etxregs + ETX_PENDING, ETX_TP_DMAWAKEUP);
2333
2334 spin_unlock_irq(&hp->happy_lock);
2335
2336 tx_add_log(hp, TXLOG_ACTION_TXMIT, 0);
2337 return NETDEV_TX_OK;
2338}
2339
2340static struct net_device_stats *happy_meal_get_stats(struct net_device *dev)
2341{
2342 struct happy_meal *hp = netdev_priv(dev);
2343
2344 spin_lock_irq(&hp->happy_lock);
2345 happy_meal_get_counters(hp, hp->bigmacregs);
2346 spin_unlock_irq(&hp->happy_lock);
2347
2348 return &hp->net_stats;
2349}
2350
2351static void happy_meal_set_multicast(struct net_device *dev)
2352{
2353 struct happy_meal *hp = netdev_priv(dev);
2354 void __iomem *bregs = hp->bigmacregs;
2355 struct netdev_hw_addr *ha;
2356 u32 crc;
2357
2358 spin_lock_irq(&hp->happy_lock);
2359
2360 if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
2361 hme_write32(hp, bregs + BMAC_HTABLE0, 0xffff);
2362 hme_write32(hp, bregs + BMAC_HTABLE1, 0xffff);
2363 hme_write32(hp, bregs + BMAC_HTABLE2, 0xffff);
2364 hme_write32(hp, bregs + BMAC_HTABLE3, 0xffff);
2365 } else if (dev->flags & IFF_PROMISC) {
2366 hme_write32(hp, bregs + BMAC_RXCFG,
2367 hme_read32(hp, bregs + BMAC_RXCFG) | BIGMAC_RXCFG_PMISC);
2368 } else {
2369 u16 hash_table[4];
2370
2371 memset(hash_table, 0, sizeof(hash_table));
2372 netdev_for_each_mc_addr(ha, dev) {
2373 crc = ether_crc_le(6, ha->addr);
2374 crc >>= 26;
2375 hash_table[crc >> 4] |= 1 << (crc & 0xf);
2376 }
2377 hme_write32(hp, bregs + BMAC_HTABLE0, hash_table[0]);
2378 hme_write32(hp, bregs + BMAC_HTABLE1, hash_table[1]);
2379 hme_write32(hp, bregs + BMAC_HTABLE2, hash_table[2]);
2380 hme_write32(hp, bregs + BMAC_HTABLE3, hash_table[3]);
2381 }
2382
2383 spin_unlock_irq(&hp->happy_lock);
2384}
2385
2386
2387static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2388{
2389 struct happy_meal *hp = netdev_priv(dev);
2390 u32 speed;
2391
2392 cmd->supported =
2393 (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
2394 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
2395 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
2396
2397
2398 cmd->port = PORT_TP;
2399 cmd->transceiver = XCVR_INTERNAL;
2400 cmd->phy_address = 0;
2401
2402
2403 spin_lock_irq(&hp->happy_lock);
2404 hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
2405 hp->sw_lpa = happy_meal_tcvr_read(hp, hp->tcvregs, MII_LPA);
2406 spin_unlock_irq(&hp->happy_lock);
2407
2408 if (hp->sw_bmcr & BMCR_ANENABLE) {
2409 cmd->autoneg = AUTONEG_ENABLE;
2410 speed = ((hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
2411 SPEED_100 : SPEED_10);
2412 if (speed == SPEED_100)
2413 cmd->duplex =
2414 (hp->sw_lpa & (LPA_100FULL)) ?
2415 DUPLEX_FULL : DUPLEX_HALF;
2416 else
2417 cmd->duplex =
2418 (hp->sw_lpa & (LPA_10FULL)) ?
2419 DUPLEX_FULL : DUPLEX_HALF;
2420 } else {
2421 cmd->autoneg = AUTONEG_DISABLE;
2422 speed = (hp->sw_bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
2423 cmd->duplex =
2424 (hp->sw_bmcr & BMCR_FULLDPLX) ?
2425 DUPLEX_FULL : DUPLEX_HALF;
2426 }
2427 ethtool_cmd_speed_set(cmd, speed);
2428 return 0;
2429}
2430
2431static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2432{
2433 struct happy_meal *hp = netdev_priv(dev);
2434
2435
2436 if (cmd->autoneg != AUTONEG_ENABLE &&
2437 cmd->autoneg != AUTONEG_DISABLE)
2438 return -EINVAL;
2439 if (cmd->autoneg == AUTONEG_DISABLE &&
2440 ((ethtool_cmd_speed(cmd) != SPEED_100 &&
2441 ethtool_cmd_speed(cmd) != SPEED_10) ||
2442 (cmd->duplex != DUPLEX_HALF &&
2443 cmd->duplex != DUPLEX_FULL)))
2444 return -EINVAL;
2445
2446
2447 spin_lock_irq(&hp->happy_lock);
2448 del_timer(&hp->happy_timer);
2449 happy_meal_begin_auto_negotiation(hp, hp->tcvregs, cmd);
2450 spin_unlock_irq(&hp->happy_lock);
2451
2452 return 0;
2453}
2454
2455static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
2456{
2457 struct happy_meal *hp = netdev_priv(dev);
2458
2459 strlcpy(info->driver, "sunhme", sizeof(info->driver));
2460 strlcpy(info->version, "2.02", sizeof(info->version));
2461 if (hp->happy_flags & HFLAG_PCI) {
2462 struct pci_dev *pdev = hp->happy_dev;
2463 strlcpy(info->bus_info, pci_name(pdev), sizeof(info->bus_info));
2464 }
2465#ifdef CONFIG_SBUS
2466 else {
2467 const struct linux_prom_registers *regs;
2468 struct platform_device *op = hp->happy_dev;
2469 regs = of_get_property(op->dev.of_node, "regs", NULL);
2470 if (regs)
2471 snprintf(info->bus_info, sizeof(info->bus_info),
2472 "SBUS:%d",
2473 regs->which_io);
2474 }
2475#endif
2476}
2477
2478static u32 hme_get_link(struct net_device *dev)
2479{
2480 struct happy_meal *hp = netdev_priv(dev);
2481
2482 spin_lock_irq(&hp->happy_lock);
2483 hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
2484 spin_unlock_irq(&hp->happy_lock);
2485
2486 return hp->sw_bmsr & BMSR_LSTATUS;
2487}
2488
2489static const struct ethtool_ops hme_ethtool_ops = {
2490 .get_settings = hme_get_settings,
2491 .set_settings = hme_set_settings,
2492 .get_drvinfo = hme_get_drvinfo,
2493 .get_link = hme_get_link,
2494};
2495
2496static int hme_version_printed;
2497
2498#ifdef CONFIG_SBUS
2499
2500
2501
2502
2503
2504static struct quattro * __devinit quattro_sbus_find(struct platform_device *child)
2505{
2506 struct device *parent = child->dev.parent;
2507 struct platform_device *op;
2508 struct quattro *qp;
2509
2510 op = to_platform_device(parent);
2511 qp = dev_get_drvdata(&op->dev);
2512 if (qp)
2513 return qp;
2514
2515 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL);
2516 if (qp != NULL) {
2517 int i;
2518
2519 for (i = 0; i < 4; i++)
2520 qp->happy_meals[i] = NULL;
2521
2522 qp->quattro_dev = child;
2523 qp->next = qfe_sbus_list;
2524 qfe_sbus_list = qp;
2525
2526 dev_set_drvdata(&op->dev, qp);
2527 }
2528 return qp;
2529}
2530
2531
2532
2533
2534
2535static int __init quattro_sbus_register_irqs(void)
2536{
2537 struct quattro *qp;
2538
2539 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2540 struct platform_device *op = qp->quattro_dev;
2541 int err, qfe_slot, skip = 0;
2542
2543 for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
2544 if (!qp->happy_meals[qfe_slot])
2545 skip = 1;
2546 }
2547 if (skip)
2548 continue;
2549
2550 err = request_irq(op->archdata.irqs[0],
2551 quattro_sbus_interrupt,
2552 IRQF_SHARED, "Quattro",
2553 qp);
2554 if (err != 0) {
2555 printk(KERN_ERR "Quattro HME: IRQ registration "
2556 "error %d.\n", err);
2557 return err;
2558 }
2559 }
2560
2561 return 0;
2562}
2563
2564static void quattro_sbus_free_irqs(void)
2565{
2566 struct quattro *qp;
2567
2568 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2569 struct platform_device *op = qp->quattro_dev;
2570 int qfe_slot, skip = 0;
2571
2572 for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) {
2573 if (!qp->happy_meals[qfe_slot])
2574 skip = 1;
2575 }
2576 if (skip)
2577 continue;
2578
2579 free_irq(op->archdata.irqs[0], qp);
2580 }
2581}
2582#endif
2583
2584#ifdef CONFIG_PCI
2585static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev)
2586{
2587 struct pci_dev *bdev = pdev->bus->self;
2588 struct quattro *qp;
2589
2590 if (!bdev) return NULL;
2591 for (qp = qfe_pci_list; qp != NULL; qp = qp->next) {
2592 struct pci_dev *qpdev = qp->quattro_dev;
2593
2594 if (qpdev == bdev)
2595 return qp;
2596 }
2597 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL);
2598 if (qp != NULL) {
2599 int i;
2600
2601 for (i = 0; i < 4; i++)
2602 qp->happy_meals[i] = NULL;
2603
2604 qp->quattro_dev = bdev;
2605 qp->next = qfe_pci_list;
2606 qfe_pci_list = qp;
2607
2608
2609 qp->nranges = 0;
2610 }
2611 return qp;
2612}
2613#endif
2614
2615static const struct net_device_ops hme_netdev_ops = {
2616 .ndo_open = happy_meal_open,
2617 .ndo_stop = happy_meal_close,
2618 .ndo_start_xmit = happy_meal_start_xmit,
2619 .ndo_tx_timeout = happy_meal_tx_timeout,
2620 .ndo_get_stats = happy_meal_get_stats,
2621 .ndo_set_rx_mode = happy_meal_set_multicast,
2622 .ndo_change_mtu = eth_change_mtu,
2623 .ndo_set_mac_address = eth_mac_addr,
2624 .ndo_validate_addr = eth_validate_addr,
2625};
2626
2627#ifdef CONFIG_SBUS
2628static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int is_qfe)
2629{
2630 struct device_node *dp = op->dev.of_node, *sbus_dp;
2631 struct quattro *qp = NULL;
2632 struct happy_meal *hp;
2633 struct net_device *dev;
2634 int i, qfe_slot = -1;
2635 int err = -ENODEV;
2636
2637 sbus_dp = op->dev.parent->of_node;
2638
2639
2640 if (strcmp(sbus_dp->name, "sbus") && strcmp(sbus_dp->name, "sbi"))
2641 return err;
2642
2643 if (is_qfe) {
2644 qp = quattro_sbus_find(op);
2645 if (qp == NULL)
2646 goto err_out;
2647 for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
2648 if (qp->happy_meals[qfe_slot] == NULL)
2649 break;
2650 if (qfe_slot == 4)
2651 goto err_out;
2652 }
2653
2654 err = -ENOMEM;
2655 dev = alloc_etherdev(sizeof(struct happy_meal));
2656 if (!dev)
2657 goto err_out;
2658 SET_NETDEV_DEV(dev, &op->dev);
2659
2660 if (hme_version_printed++ == 0)
2661 printk(KERN_INFO "%s", version);
2662
2663
2664
2665
2666 for (i = 0; i < 6; i++) {
2667 if (macaddr[i] != 0)
2668 break;
2669 }
2670 if (i < 6) {
2671 for (i = 0; i < 6; i++)
2672 dev->dev_addr[i] = macaddr[i];
2673 macaddr[5]++;
2674 } else {
2675 const unsigned char *addr;
2676 int len;
2677
2678 addr = of_get_property(dp, "local-mac-address", &len);
2679
2680 if (qfe_slot != -1 && addr && len == 6)
2681 memcpy(dev->dev_addr, addr, 6);
2682 else
2683 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2684 }
2685
2686 hp = netdev_priv(dev);
2687
2688 hp->happy_dev = op;
2689 hp->dma_dev = &op->dev;
2690
2691 spin_lock_init(&hp->happy_lock);
2692
2693 err = -ENODEV;
2694 if (qp != NULL) {
2695 hp->qfe_parent = qp;
2696 hp->qfe_ent = qfe_slot;
2697 qp->happy_meals[qfe_slot] = dev;
2698 }
2699
2700 hp->gregs = of_ioremap(&op->resource[0], 0,
2701 GREG_REG_SIZE, "HME Global Regs");
2702 if (!hp->gregs) {
2703 printk(KERN_ERR "happymeal: Cannot map global registers.\n");
2704 goto err_out_free_netdev;
2705 }
2706
2707 hp->etxregs = of_ioremap(&op->resource[1], 0,
2708 ETX_REG_SIZE, "HME TX Regs");
2709 if (!hp->etxregs) {
2710 printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n");
2711 goto err_out_iounmap;
2712 }
2713
2714 hp->erxregs = of_ioremap(&op->resource[2], 0,
2715 ERX_REG_SIZE, "HME RX Regs");
2716 if (!hp->erxregs) {
2717 printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n");
2718 goto err_out_iounmap;
2719 }
2720
2721 hp->bigmacregs = of_ioremap(&op->resource[3], 0,
2722 BMAC_REG_SIZE, "HME BIGMAC Regs");
2723 if (!hp->bigmacregs) {
2724 printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n");
2725 goto err_out_iounmap;
2726 }
2727
2728 hp->tcvregs = of_ioremap(&op->resource[4], 0,
2729 TCVR_REG_SIZE, "HME Tranceiver Regs");
2730 if (!hp->tcvregs) {
2731 printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n");
2732 goto err_out_iounmap;
2733 }
2734
2735 hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
2736 if (hp->hm_revision == 0xff)
2737 hp->hm_revision = 0xa0;
2738
2739
2740 if (hp->hm_revision == 0x20 || hp->hm_revision == 0x21)
2741 hp->happy_flags = HFLAG_20_21;
2742 else if (hp->hm_revision != 0xa0)
2743 hp->happy_flags = HFLAG_NOT_A0;
2744
2745 if (qp != NULL)
2746 hp->happy_flags |= HFLAG_QUATTRO;
2747
2748
2749 hp->happy_bursts = of_getintprop_default(sbus_dp,
2750 "burst-sizes", 0x00);
2751
2752 hp->happy_block = dma_alloc_coherent(hp->dma_dev,
2753 PAGE_SIZE,
2754 &hp->hblock_dvma,
2755 GFP_ATOMIC);
2756 err = -ENOMEM;
2757 if (!hp->happy_block) {
2758 printk(KERN_ERR "happymeal: Cannot allocate descriptors.\n");
2759 goto err_out_iounmap;
2760 }
2761
2762
2763 hp->linkcheck = 0;
2764
2765
2766 hp->timer_state = asleep;
2767 hp->timer_ticks = 0;
2768
2769 init_timer(&hp->happy_timer);
2770
2771 hp->dev = dev;
2772 dev->netdev_ops = &hme_netdev_ops;
2773 dev->watchdog_timeo = 5*HZ;
2774 dev->ethtool_ops = &hme_ethtool_ops;
2775
2776
2777 dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
2778 dev->features |= dev->hw_features | NETIF_F_RXCSUM;
2779
2780 dev->irq = op->archdata.irqs[0];
2781
2782#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
2783
2784 hp->read_desc32 = sbus_hme_read_desc32;
2785 hp->write_txd = sbus_hme_write_txd;
2786 hp->write_rxd = sbus_hme_write_rxd;
2787 hp->read32 = sbus_hme_read32;
2788 hp->write32 = sbus_hme_write32;
2789#endif
2790
2791
2792
2793
2794 spin_lock_irq(&hp->happy_lock);
2795 happy_meal_set_initial_advertisement(hp);
2796 spin_unlock_irq(&hp->happy_lock);
2797
2798 err = register_netdev(hp->dev);
2799 if (err) {
2800 printk(KERN_ERR "happymeal: Cannot register net device, "
2801 "aborting.\n");
2802 goto err_out_free_coherent;
2803 }
2804
2805 dev_set_drvdata(&op->dev, hp);
2806
2807 if (qfe_slot != -1)
2808 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
2809 dev->name, qfe_slot);
2810 else
2811 printk(KERN_INFO "%s: HAPPY MEAL (SBUS) 10/100baseT Ethernet ",
2812 dev->name);
2813
2814 printk("%pM\n", dev->dev_addr);
2815
2816 return 0;
2817
2818err_out_free_coherent:
2819 dma_free_coherent(hp->dma_dev,
2820 PAGE_SIZE,
2821 hp->happy_block,
2822 hp->hblock_dvma);
2823
2824err_out_iounmap:
2825 if (hp->gregs)
2826 of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
2827 if (hp->etxregs)
2828 of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
2829 if (hp->erxregs)
2830 of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
2831 if (hp->bigmacregs)
2832 of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
2833 if (hp->tcvregs)
2834 of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
2835
2836 if (qp)
2837 qp->happy_meals[qfe_slot] = NULL;
2838
2839err_out_free_netdev:
2840 free_netdev(dev);
2841
2842err_out:
2843 return err;
2844}
2845#endif
2846
2847#ifdef CONFIG_PCI
2848#ifndef CONFIG_SPARC
2849static int is_quattro_p(struct pci_dev *pdev)
2850{
2851 struct pci_dev *busdev = pdev->bus->self;
2852 struct pci_dev *this_pdev;
2853 int n_hmes;
2854
2855 if (busdev == NULL ||
2856 busdev->vendor != PCI_VENDOR_ID_DEC ||
2857 busdev->device != PCI_DEVICE_ID_DEC_21153)
2858 return 0;
2859
2860 n_hmes = 0;
2861 list_for_each_entry(this_pdev, &pdev->bus->devices, bus_list) {
2862 if (this_pdev->vendor == PCI_VENDOR_ID_SUN &&
2863 this_pdev->device == PCI_DEVICE_ID_SUN_HAPPYMEAL)
2864 n_hmes++;
2865 }
2866
2867 if (n_hmes != 4)
2868 return 0;
2869
2870 return 1;
2871}
2872
2873
2874static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
2875{
2876 int this_offset;
2877
2878 for (this_offset = 0x20; this_offset < len; this_offset++) {
2879 void __iomem *p = rom_base + this_offset;
2880
2881 if (readb(p + 0) != 0x90 ||
2882 readb(p + 1) != 0x00 ||
2883 readb(p + 2) != 0x09 ||
2884 readb(p + 3) != 0x4e ||
2885 readb(p + 4) != 0x41 ||
2886 readb(p + 5) != 0x06)
2887 continue;
2888
2889 this_offset += 6;
2890 p += 6;
2891
2892 if (index == 0) {
2893 int i;
2894
2895 for (i = 0; i < 6; i++)
2896 dev_addr[i] = readb(p + i);
2897 return 1;
2898 }
2899 index--;
2900 }
2901 return 0;
2902}
2903
2904static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
2905{
2906 size_t size;
2907 void __iomem *p = pci_map_rom(pdev, &size);
2908
2909 if (p) {
2910 int index = 0;
2911 int found;
2912
2913 if (is_quattro_p(pdev))
2914 index = PCI_SLOT(pdev->devfn);
2915
2916 found = readb(p) == 0x55 &&
2917 readb(p + 1) == 0xaa &&
2918 find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
2919 pci_unmap_rom(pdev, p);
2920 if (found)
2921 return;
2922 }
2923
2924
2925 dev_addr[0] = 0x08;
2926 dev_addr[1] = 0x00;
2927 dev_addr[2] = 0x20;
2928 get_random_bytes(&dev_addr[3], 3);
2929}
2930#endif
2931
2932static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
2933 const struct pci_device_id *ent)
2934{
2935 struct quattro *qp = NULL;
2936#ifdef CONFIG_SPARC
2937 struct device_node *dp;
2938#endif
2939 struct happy_meal *hp;
2940 struct net_device *dev;
2941 void __iomem *hpreg_base;
2942 unsigned long hpreg_res;
2943 int i, qfe_slot = -1;
2944 char prom_name[64];
2945 int err;
2946
2947
2948#ifdef CONFIG_SPARC
2949 dp = pci_device_to_OF_node(pdev);
2950 strcpy(prom_name, dp->name);
2951#else
2952 if (is_quattro_p(pdev))
2953 strcpy(prom_name, "SUNW,qfe");
2954 else
2955 strcpy(prom_name, "SUNW,hme");
2956#endif
2957
2958 err = -ENODEV;
2959
2960 if (pci_enable_device(pdev))
2961 goto err_out;
2962 pci_set_master(pdev);
2963
2964 if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
2965 qp = quattro_pci_find(pdev);
2966 if (qp == NULL)
2967 goto err_out;
2968 for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
2969 if (qp->happy_meals[qfe_slot] == NULL)
2970 break;
2971 if (qfe_slot == 4)
2972 goto err_out;
2973 }
2974
2975 dev = alloc_etherdev(sizeof(struct happy_meal));
2976 err = -ENOMEM;
2977 if (!dev)
2978 goto err_out;
2979 SET_NETDEV_DEV(dev, &pdev->dev);
2980
2981 if (hme_version_printed++ == 0)
2982 printk(KERN_INFO "%s", version);
2983
2984 dev->base_addr = (long) pdev;
2985
2986 hp = netdev_priv(dev);
2987
2988 hp->happy_dev = pdev;
2989 hp->dma_dev = &pdev->dev;
2990
2991 spin_lock_init(&hp->happy_lock);
2992
2993 if (qp != NULL) {
2994 hp->qfe_parent = qp;
2995 hp->qfe_ent = qfe_slot;
2996 qp->happy_meals[qfe_slot] = dev;
2997 }
2998
2999 hpreg_res = pci_resource_start(pdev, 0);
3000 err = -ENODEV;
3001 if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
3002 printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n");
3003 goto err_out_clear_quattro;
3004 }
3005 if (pci_request_regions(pdev, DRV_NAME)) {
3006 printk(KERN_ERR "happymeal(PCI): Cannot obtain PCI resources, "
3007 "aborting.\n");
3008 goto err_out_clear_quattro;
3009 }
3010
3011 if ((hpreg_base = ioremap(hpreg_res, 0x8000)) == NULL) {
3012 printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n");
3013 goto err_out_free_res;
3014 }
3015
3016 for (i = 0; i < 6; i++) {
3017 if (macaddr[i] != 0)
3018 break;
3019 }
3020 if (i < 6) {
3021 for (i = 0; i < 6; i++)
3022 dev->dev_addr[i] = macaddr[i];
3023 macaddr[5]++;
3024 } else {
3025#ifdef CONFIG_SPARC
3026 const unsigned char *addr;
3027 int len;
3028
3029 if (qfe_slot != -1 &&
3030 (addr = of_get_property(dp, "local-mac-address", &len))
3031 != NULL &&
3032 len == 6) {
3033 memcpy(dev->dev_addr, addr, 6);
3034 } else {
3035 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
3036 }
3037#else
3038 get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]);
3039#endif
3040 }
3041
3042
3043 hp->gregs = (hpreg_base + 0x0000UL);
3044 hp->etxregs = (hpreg_base + 0x2000UL);
3045 hp->erxregs = (hpreg_base + 0x4000UL);
3046 hp->bigmacregs = (hpreg_base + 0x6000UL);
3047 hp->tcvregs = (hpreg_base + 0x7000UL);
3048
3049#ifdef CONFIG_SPARC
3050 hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
3051 if (hp->hm_revision == 0xff)
3052 hp->hm_revision = 0xc0 | (pdev->revision & 0x0f);
3053#else
3054
3055 hp->hm_revision = 0x20;
3056#endif
3057
3058
3059 if (hp->hm_revision == 0x20 || hp->hm_revision == 0x21)
3060 hp->happy_flags = HFLAG_20_21;
3061 else if (hp->hm_revision != 0xa0 && hp->hm_revision != 0xc0)
3062 hp->happy_flags = HFLAG_NOT_A0;
3063
3064 if (qp != NULL)
3065 hp->happy_flags |= HFLAG_QUATTRO;
3066
3067
3068 hp->happy_flags |= HFLAG_PCI;
3069
3070#ifdef CONFIG_SPARC
3071
3072 hp->happy_bursts = DMA_BURSTBITS;
3073#endif
3074
3075 hp->happy_block = (struct hmeal_init_block *)
3076 dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &hp->hblock_dvma, GFP_KERNEL);
3077
3078 err = -ENODEV;
3079 if (!hp->happy_block) {
3080 printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n");
3081 goto err_out_iounmap;
3082 }
3083
3084 hp->linkcheck = 0;
3085 hp->timer_state = asleep;
3086 hp->timer_ticks = 0;
3087
3088 init_timer(&hp->happy_timer);
3089
3090 hp->dev = dev;
3091 dev->netdev_ops = &hme_netdev_ops;
3092 dev->watchdog_timeo = 5*HZ;
3093 dev->ethtool_ops = &hme_ethtool_ops;
3094 dev->irq = pdev->irq;
3095 dev->dma = 0;
3096
3097
3098 dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
3099 dev->features |= dev->hw_features | NETIF_F_RXCSUM;
3100
3101#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
3102
3103 hp->read_desc32 = pci_hme_read_desc32;
3104 hp->write_txd = pci_hme_write_txd;
3105 hp->write_rxd = pci_hme_write_rxd;
3106 hp->read32 = pci_hme_read32;
3107 hp->write32 = pci_hme_write32;
3108#endif
3109
3110
3111
3112
3113 spin_lock_irq(&hp->happy_lock);
3114 happy_meal_set_initial_advertisement(hp);
3115 spin_unlock_irq(&hp->happy_lock);
3116
3117 err = register_netdev(hp->dev);
3118 if (err) {
3119 printk(KERN_ERR "happymeal(PCI): Cannot register net device, "
3120 "aborting.\n");
3121 goto err_out_iounmap;
3122 }
3123
3124 dev_set_drvdata(&pdev->dev, hp);
3125
3126 if (!qfe_slot) {
3127 struct pci_dev *qpdev = qp->quattro_dev;
3128
3129 prom_name[0] = 0;
3130 if (!strncmp(dev->name, "eth", 3)) {
3131 int i = simple_strtoul(dev->name + 3, NULL, 10);
3132 sprintf(prom_name, "-%d", i + 3);
3133 }
3134 printk(KERN_INFO "%s%s: Quattro HME (PCI/CheerIO) 10/100baseT Ethernet ", dev->name, prom_name);
3135 if (qpdev->vendor == PCI_VENDOR_ID_DEC &&
3136 qpdev->device == PCI_DEVICE_ID_DEC_21153)
3137 printk("DEC 21153 PCI Bridge\n");
3138 else
3139 printk("unknown bridge %04x.%04x\n",
3140 qpdev->vendor, qpdev->device);
3141 }
3142
3143 if (qfe_slot != -1)
3144 printk(KERN_INFO "%s: Quattro HME slot %d (PCI/CheerIO) 10/100baseT Ethernet ",
3145 dev->name, qfe_slot);
3146 else
3147 printk(KERN_INFO "%s: HAPPY MEAL (PCI/CheerIO) 10/100BaseT Ethernet ",
3148 dev->name);
3149
3150 printk("%pM\n", dev->dev_addr);
3151
3152 return 0;
3153
3154err_out_iounmap:
3155 iounmap(hp->gregs);
3156
3157err_out_free_res:
3158 pci_release_regions(pdev);
3159
3160err_out_clear_quattro:
3161 if (qp != NULL)
3162 qp->happy_meals[qfe_slot] = NULL;
3163
3164 free_netdev(dev);
3165
3166err_out:
3167 return err;
3168}
3169
3170static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
3171{
3172 struct happy_meal *hp = dev_get_drvdata(&pdev->dev);
3173 struct net_device *net_dev = hp->dev;
3174
3175 unregister_netdev(net_dev);
3176
3177 dma_free_coherent(hp->dma_dev, PAGE_SIZE,
3178 hp->happy_block, hp->hblock_dvma);
3179 iounmap(hp->gregs);
3180 pci_release_regions(hp->happy_dev);
3181
3182 free_netdev(net_dev);
3183
3184 dev_set_drvdata(&pdev->dev, NULL);
3185}
3186
3187static DEFINE_PCI_DEVICE_TABLE(happymeal_pci_ids) = {
3188 { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) },
3189 { }
3190};
3191
3192MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
3193
3194static struct pci_driver hme_pci_driver = {
3195 .name = "hme",
3196 .id_table = happymeal_pci_ids,
3197 .probe = happy_meal_pci_probe,
3198 .remove = __devexit_p(happy_meal_pci_remove),
3199};
3200
3201static int __init happy_meal_pci_init(void)
3202{
3203 return pci_register_driver(&hme_pci_driver);
3204}
3205
3206static void happy_meal_pci_exit(void)
3207{
3208 pci_unregister_driver(&hme_pci_driver);
3209
3210 while (qfe_pci_list) {
3211 struct quattro *qfe = qfe_pci_list;
3212 struct quattro *next = qfe->next;
3213
3214 kfree(qfe);
3215
3216 qfe_pci_list = next;
3217 }
3218}
3219
3220#endif
3221
3222#ifdef CONFIG_SBUS
3223static const struct of_device_id hme_sbus_match[];
3224static int __devinit hme_sbus_probe(struct platform_device *op)
3225{
3226 const struct of_device_id *match;
3227 struct device_node *dp = op->dev.of_node;
3228 const char *model = of_get_property(dp, "model", NULL);
3229 int is_qfe;
3230
3231 match = of_match_device(hme_sbus_match, &op->dev);
3232 if (!match)
3233 return -EINVAL;
3234 is_qfe = (match->data != NULL);
3235
3236 if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe"))
3237 is_qfe = 1;
3238
3239 return happy_meal_sbus_probe_one(op, is_qfe);
3240}
3241
3242static int __devexit hme_sbus_remove(struct platform_device *op)
3243{
3244 struct happy_meal *hp = dev_get_drvdata(&op->dev);
3245 struct net_device *net_dev = hp->dev;
3246
3247 unregister_netdev(net_dev);
3248
3249
3250
3251 of_iounmap(&op->resource[0], hp->gregs, GREG_REG_SIZE);
3252 of_iounmap(&op->resource[1], hp->etxregs, ETX_REG_SIZE);
3253 of_iounmap(&op->resource[2], hp->erxregs, ERX_REG_SIZE);
3254 of_iounmap(&op->resource[3], hp->bigmacregs, BMAC_REG_SIZE);
3255 of_iounmap(&op->resource[4], hp->tcvregs, TCVR_REG_SIZE);
3256 dma_free_coherent(hp->dma_dev,
3257 PAGE_SIZE,
3258 hp->happy_block,
3259 hp->hblock_dvma);
3260
3261 free_netdev(net_dev);
3262
3263 dev_set_drvdata(&op->dev, NULL);
3264
3265 return 0;
3266}
3267
3268static const struct of_device_id hme_sbus_match[] = {
3269 {
3270 .name = "SUNW,hme",
3271 },
3272 {
3273 .name = "SUNW,qfe",
3274 .data = (void *) 1,
3275 },
3276 {
3277 .name = "qfe",
3278 .data = (void *) 1,
3279 },
3280 {},
3281};
3282
3283MODULE_DEVICE_TABLE(of, hme_sbus_match);
3284
3285static struct platform_driver hme_sbus_driver = {
3286 .driver = {
3287 .name = "hme",
3288 .owner = THIS_MODULE,
3289 .of_match_table = hme_sbus_match,
3290 },
3291 .probe = hme_sbus_probe,
3292 .remove = __devexit_p(hme_sbus_remove),
3293};
3294
3295static int __init happy_meal_sbus_init(void)
3296{
3297 int err;
3298
3299 err = platform_driver_register(&hme_sbus_driver);
3300 if (!err)
3301 err = quattro_sbus_register_irqs();
3302
3303 return err;
3304}
3305
3306static void happy_meal_sbus_exit(void)
3307{
3308 platform_driver_unregister(&hme_sbus_driver);
3309 quattro_sbus_free_irqs();
3310
3311 while (qfe_sbus_list) {
3312 struct quattro *qfe = qfe_sbus_list;
3313 struct quattro *next = qfe->next;
3314
3315 kfree(qfe);
3316
3317 qfe_sbus_list = next;
3318 }
3319}
3320#endif
3321
3322static int __init happy_meal_probe(void)
3323{
3324 int err = 0;
3325
3326#ifdef CONFIG_SBUS
3327 err = happy_meal_sbus_init();
3328#endif
3329#ifdef CONFIG_PCI
3330 if (!err) {
3331 err = happy_meal_pci_init();
3332#ifdef CONFIG_SBUS
3333 if (err)
3334 happy_meal_sbus_exit();
3335#endif
3336 }
3337#endif
3338
3339 return err;
3340}
3341
3342
3343static void __exit happy_meal_exit(void)
3344{
3345#ifdef CONFIG_SBUS
3346 happy_meal_sbus_exit();
3347#endif
3348#ifdef CONFIG_PCI
3349 happy_meal_pci_exit();
3350#endif
3351}
3352
3353module_init(happy_meal_probe);
3354module_exit(happy_meal_exit);
3355