1
2
3
4
5
6
7
8
9
10
11#include <linux/module.h>
12#include <linux/init.h>
13
14#include <linux/sched.h>
15#include <linux/kernel.h>
16#include <linux/delay.h>
17#include <linux/slab.h>
18#include <linux/errno.h>
19#include <linux/types.h>
20#include <linux/interrupt.h>
21#include <linux/pci.h>
22
23#include <linux/in.h>
24#include <linux/netdevice.h>
25#include <linux/etherdevice.h>
26#include <linux/ip.h>
27#include <linux/tcp.h>
28#include <linux/skbuff.h>
29#include <linux/mii.h>
30
31#include <asm/ip32/crime.h>
32#include <asm/ip32/mace.h>
33#include <asm/ip32/ip32_ints.h>
34
35#include "meth.h"
36
37#include <linux/in6.h>
38#include <asm/checksum.h>
39
40#ifndef MFE_DEBUG
41#define MFE_DEBUG 0
42#endif
43
44#if MFE_DEBUG>=1
45#define DPRINTK(str,args...) printk (KERN_DEBUG "meth(%ld): %s: " str, jiffies, __FUNCTION__ , ## args)
46#define MFE_RX_DEBUG 2
47#else
48#define DPRINTK(str,args...)
49#define MFE_RX_DEBUG 0
50#endif
51
52
53static const char *version="meth.c: Ilya Volynets (ilya@theIlya.com)";
54static const char *meth_str="SGI O2 Fast Ethernet";
55MODULE_AUTHOR("Ilya Volynets");
56MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
57
58
59
60
61
62#define HAVE_TX_TIMEOUT
63
64#define TX_TIMEOUT (400*HZ/1000)
65
66#ifdef HAVE_TX_TIMEOUT
67static int timeout = TX_TIMEOUT;
68MODULE_PARM(timeout, "i");
69#endif
70
71int meth_eth;
72
73
74
75
76
77
78typedef struct meth_private {
79 struct net_device_stats stats;
80 volatile struct meth_regs *regs;
81 u64 mode;
82 int phy_addr;
83 tx_packet *tx_ring;
84 dma_addr_t tx_ring_dma;
85 int free_space;
86 struct sk_buff *tx_skbs[TX_RING_ENTRIES];
87 dma_addr_t tx_skb_dmas[TX_RING_ENTRIES];
88 int tx_read,tx_write;
89 int tx_count;
90
91 rx_packet *rx_ring[RX_RING_ENTRIES];
92 dma_addr_t rx_ring_dmas[RX_RING_ENTRIES];
93 int rx_write;
94
95 spinlock_t meth_lock;
96} meth_private;
97
98extern struct net_device meth_devs[];
99void meth_tx_timeout (struct net_device *dev);
100void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs);
101
102
103char o2meth_eaddr[8]={0,0,0,0,0,0,0,0};
104
105static inline void load_eaddr(struct net_device *dev,
106 volatile struct meth_regs *regs)
107{
108 int i;
109 DPRINTK("Loading MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
110 (int)o2meth_eaddr[0]&0xFF,(int)o2meth_eaddr[1]&0xFF,(int)o2meth_eaddr[2]&0xFF,
111 (int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF);
112
113 for (i=0; i<6; i++)
114 dev->dev_addr[i]=o2meth_eaddr[i];
115 regs->mac_addr=
116
117
118 (*(u64*)o2meth_eaddr)>>16;
119 DPRINTK("MAC, finally is %0lx\n",regs->mac_addr);
120}
121
122
123
124
125#define WAIT_FOR_PHY(___regs, ___rval) \
126 while((___rval=___regs->phy_data)&MDIO_BUSY){ \
127 udelay(25); \
128 }
129
130static int mdio_read(meth_private *priv,int phyreg)
131{
132 volatile meth_regs* regs=priv->regs;
133 volatile u32 rval;
134 WAIT_FOR_PHY(regs,rval)
135 regs->phy_registers=(priv->phy_addr<<5)|(phyreg&0x1f);
136 udelay(25);
137 regs->phy_trans_go=1;
138 udelay(25);
139 WAIT_FOR_PHY(regs,rval)
140 return rval&MDIO_DATA_MASK;
141}
142
143
144static void mdio_write(meth_private* priv,int pfyreg,int val)
145{
146 volatile meth_regs* regs=priv->regs;
147 int rval;
148
149 spin_lock_irq(&priv->meth_lock);
150 WAIT_FOR_PHY(regs,rval)
151 regs->phy_registers=(priv->phy_addr<<5)|(pfyreg&0x1f);
152 regs->phy_data=val;
153 udelay(25);
154 WAIT_FOR_PHY(regs,rval)
155 spin_unlock_irq(&priv->meth_lock);
156}
157
158
159static void mdio_update(meth_private* priv,int phyreg, int val, int mask)
160{
161 int rval;
162 DPRINTK("RMW value %i to PHY register %i with mask %i\n",val,phyreg,mask);
163 rval=mdio_read(priv,phyreg);
164 rval=(rval&~mask)|(val&mask);
165 mdio_write(priv,phyreg,rval);
166}
167
168
169
170
171
172
173static int mdio_probe(meth_private *priv)
174{
175 int i, p2, p3;
176 DPRINTK("Detecting PHY kind\n");
177
178 if(priv->phy_addr>=0&&priv->phy_addr<32)
179 return 0;
180 spin_lock_irq(&priv->meth_lock);
181 for (i=0;i<32;++i){
182 priv->phy_addr=(char)i;
183 p2=mdio_read(priv,2);
184#ifdef MFE_DEBUG
185 p3=mdio_read(priv,3);
186 switch ((p2<<12)|(p3>>4)){
187 case PHY_QS6612X:
188 DPRINTK("PHY is QS6612X\n");
189 break;
190 case PHY_ICS1889:
191 DPRINTK("PHY is ICS1889\n");
192 break;
193 case PHY_ICS1890:
194 DPRINTK("PHY is ICS1890\n");
195 break;
196 case PHY_DP83840:
197 DPRINTK("PHY is DP83840\n");
198 break;
199 }
200#endif
201 if(p2!=0xffff&&p2!=0x0000){
202 DPRINTK("PHY code: %x\n",(p2<<12)|(p3>>4));
203 break;
204 }
205 }
206 spin_unlock_irq(&priv->meth_lock);
207 if(priv->phy_addr<32) {
208 return 0;
209 }
210 DPRINTK("Oopsie! PHY is not known!\n");
211 priv->phy_addr=-1;
212 return -ENODEV;
213}
214
215static void meth_check_link(struct net_device *dev)
216{
217 struct meth_private *priv = (struct meth_private *) dev->priv;
218 int mii_partner = mdio_read(priv, 5);
219 int mii_advertising = mdio_read(priv, 4);
220 int negotiated = mii_advertising & mii_partner;
221 int duplex, speed;
222
223 if (mii_partner == 0xffff)
224 return;
225
226 duplex = ((negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040)?METH_PHY_FDX:0;
227 speed = (negotiated & 0x0380)?METH_100MBIT:0;
228
229 if ((priv->mode & METH_PHY_FDX) ^ duplex)
230 {
231 DPRINTK("Setting %s-duplex\n", duplex ? "full" : "half");
232 if (duplex)
233 priv->mode |= METH_PHY_FDX;
234 else
235 priv->mode &= ~METH_PHY_FDX;
236 priv->regs->mac_ctrl = priv->mode;
237 }
238
239 if ((priv->mode & METH_100MBIT) ^ speed)
240 {
241 DPRINTK("Setting %dMbs mode\n", speed ? 100 : 10);
242 if (duplex)
243 priv->mode |= METH_100MBIT;
244 else
245 priv->mode &= ~METH_100MBIT;
246 priv->regs->mac_ctrl = priv->mode;
247 }
248}
249
250
251static int meth_init_tx_ring(meth_private *priv)
252{
253
254 DPRINTK("Initializing TX ring\n");
255 priv->tx_ring = (tx_packet *) pci_alloc_consistent(NULL,TX_RING_BUFFER_SIZE,&(priv->tx_ring_dma));
256 if(!priv->tx_ring)
257 return -ENOMEM;
258 memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE);
259 priv->tx_count = priv->tx_read = priv->tx_write = 0;
260 priv->regs->tx_ring_base = priv->tx_ring_dma;
261 priv->free_space = TX_RING_ENTRIES;
262
263 memset(priv->tx_skbs,0,sizeof(priv->tx_skbs));
264 memset(priv->tx_skb_dmas,0,sizeof(priv->tx_skb_dmas));
265 DPRINTK("Done with TX ring init\n");
266 return 0;
267}
268
269static int meth_init_rx_ring(meth_private *priv)
270{
271 int i;
272 DPRINTK("Initializing RX ring\n");
273 for(i=0;i<RX_RING_ENTRIES;i++){
274 DPRINTK("\t1:\t%i\t",i);
275
276
277
278 priv->rx_ring[i]=(rx_packet*)pci_alloc_consistent(NULL,METH_RX_BUFF_SIZE,&(priv->rx_ring_dmas[i]));
279
280 DPRINTK("\t%p\n",priv->rx_ring[i]);
281 priv->regs->rx_fifo=priv->rx_ring_dmas[i];
282 }
283 priv->rx_write = 0;
284 DPRINTK("Done with RX ring\n");
285 return 0;
286}
287static void meth_free_tx_ring(meth_private *priv)
288{
289 int i;
290
291
292 for (i = 0; i < TX_RING_ENTRIES; i++) {
293 if (priv->tx_skbs[i])
294 dev_kfree_skb(priv->tx_skbs[i]);
295 priv->tx_skbs[i] = NULL;
296 }
297 pci_free_consistent(NULL,
298 TX_RING_BUFFER_SIZE,
299 priv->tx_ring,
300 priv->tx_ring_dma);
301}
302static void meth_free_rx_ring(meth_private *priv)
303{
304 int i;
305
306 for(i=0;i<RX_RING_ENTRIES;i++)
307 pci_free_consistent(NULL,
308 METH_RX_BUFF_SIZE,
309 priv->rx_ring[i],
310 priv->rx_ring_dmas[i]);
311}
312
313int meth_reset(struct net_device *dev)
314{
315 struct meth_private *priv = (struct meth_private *) dev->priv;
316
317
318 priv->regs->mac_ctrl = SGI_MAC_RESET;
319 priv->regs->mac_ctrl = 0;
320 udelay(25);
321 DPRINTK("MAC control after reset: %016lx\n", priv->regs->mac_ctrl);
322
323
324 load_eaddr(dev, priv->regs);
325
326
327
328 if(mdio_probe(priv) < 0) {
329 DPRINTK("Unable to find PHY\n");
330 return -ENODEV;
331 }
332
333
334 priv->mode=METH_ACCEPT_MCAST|METH_DEFAULT_IPG;
335 if(dev->flags | IFF_PROMISC)
336 priv->mode |= METH_PROMISC;
337 priv->regs->mac_ctrl = priv->mode;
338
339
340 meth_check_link(dev);
341
342
343 priv->regs->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) |
344 (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
345
346 return(0);
347}
348
349
350
351
352
353
354
355int meth_open(struct net_device *dev)
356{
357 meth_private *priv=dev->priv;
358 volatile meth_regs *regs=priv->regs;
359
360 MOD_INC_USE_COUNT;
361
362
363 regs->dma_ctrl|=
364 METH_DMA_TX_EN|
365 METH_DMA_RX_EN|METH_DMA_RX_INT_EN;
366
367 if(request_irq(dev->irq,meth_interrupt,SA_SHIRQ,meth_str,dev)){
368 printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq);
369 return -EAGAIN;
370 }
371 netif_start_queue(dev);
372 DPRINTK("Opened... DMA control=0x%08lx\n", regs->dma_ctrl);
373 return 0;
374}
375
376int meth_release(struct net_device *dev)
377{
378 netif_stop_queue(dev);
379
380 ((meth_private*)(dev->priv))->regs->dma_ctrl&=
381 ~(METH_DMA_TX_EN|METH_DMA_TX_INT_EN|
382 METH_DMA_RX_EN|METH_DMA_RX_INT_EN);
383 free_irq(dev->irq, dev);
384 MOD_DEC_USE_COUNT;
385 return 0;
386}
387
388
389
390
391int meth_config(struct net_device *dev, struct ifmap *map)
392{
393 if (dev->flags & IFF_UP)
394 return -EBUSY;
395
396
397 if (map->base_addr != dev->base_addr) {
398 printk(KERN_WARNING "meth: Can't change I/O address\n");
399 return -EOPNOTSUPP;
400 }
401
402
403 if (map->irq != dev->irq) {
404 printk(KERN_WARNING "meth: Can't change IRQ\n");
405 return -EOPNOTSUPP;
406 }
407 DPRINTK("Configured\n");
408
409
410 return 0;
411}
412
413
414
415
416void meth_rx(struct net_device* dev)
417{
418 struct sk_buff *skb;
419 struct meth_private *priv = (struct meth_private *) dev->priv;
420 rx_packet *rxb;
421 DPRINTK("RX...\n");
422
423 while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){
424 int len=rxb->status.parsed.rx_len - 4;
425 DPRINTK("(%i)\n",priv->rx_write);
426
427 if(len < 60 || len > 1518) {
428 printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x.\n",
429 dev->name, priv->rx_write, rxb->status.raw);
430 priv->stats.rx_errors++;
431 priv->stats.rx_length_errors++;
432 }
433 if(!(rxb->status.raw&METH_RX_STATUS_ERRORS)){
434 skb=alloc_skb(len+2,GFP_ATOMIC);
435 if(!skb){
436
437 DPRINTK("!!!>>>Ouch! Not enough Memory for RX buffer!\n");
438 priv->stats.rx_dropped++;
439 } else {
440 skb_reserve(skb, 2);
441 memcpy(skb_put(skb, len), rxb->buf, len);
442
443 skb->dev = dev;
444 skb->protocol = eth_type_trans(skb, dev);
445
446
447 DPRINTK("passing packet\n");
448 DPRINTK("len = %d rxb->status = %x\n",
449 len, rxb->status.raw);
450 netif_rx(skb);
451 dev->last_rx = jiffies;
452 priv->stats.rx_packets++;
453 priv->stats.rx_bytes+=len;
454 DPRINTK("There we go... Whew...\n");
455 }
456 }
457 priv->regs->rx_fifo=priv->rx_ring_dmas[priv->rx_write];
458 rxb->status.raw=0;
459 priv->rx_write=(priv->rx_write+1)&(RX_RING_ENTRIES-1);
460 }
461}
462
463static int meth_tx_full(struct net_device *dev)
464{
465 struct meth_private *priv = (struct meth_private *) dev->priv;
466
467 return(priv->tx_count >= TX_RING_ENTRIES-1);
468}
469
470void meth_tx_cleanup(struct net_device* dev, int rptr)
471{
472 meth_private *priv=dev->priv;
473 tx_packet* status;
474 struct sk_buff *skb;
475
476 spin_lock(&priv->meth_lock);
477
478
479 priv->regs->dma_ctrl &= ~(METH_DMA_TX_INT_EN);
480
481 while(priv->tx_read != rptr){
482 skb = priv->tx_skbs[priv->tx_read];
483 status = &priv->tx_ring[priv->tx_read];
484 if(!status->header.res.sent)
485 break;
486 if(status->header.raw & METH_TX_STATUS_DONE) {
487 priv->stats.tx_packets++;
488 priv->stats.tx_bytes += skb->len;
489 }
490 dev_kfree_skb_irq(skb);
491 priv->tx_skbs[priv->tx_read] = NULL;
492 status->header.raw = 0;
493 priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1);
494 priv->tx_count --;
495 }
496
497
498 if (netif_queue_stopped(dev) && ! meth_tx_full(dev)) {
499 netif_wake_queue(dev);
500 }
501
502 spin_unlock(priv->meth_lock);
503}
504
505
506
507
508void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs)
509{
510 struct meth_private *priv;
511 union {
512 u32 reg;
513 struct {
514 u32 : 2,
515 rx_seq : 5,
516 tx_read : 9,
517
518 rx_read : 8,
519 int_mask: 8;
520 } parsed;
521 } status;
522
523
524
525
526 struct net_device *dev = (struct net_device *)dev_id;
527
528
529 if (!dev ) return;
530
531
532 priv = (struct meth_private *) dev->priv;
533
534 status.reg = priv->regs->int_flags;
535
536 DPRINTK("Interrupt, status %08x...\n",status.reg);
537 if (status.parsed.int_mask & METH_INT_RX_THRESHOLD) {
538
539 meth_rx(dev);
540 }
541
542 if (status.parsed.int_mask & (METH_INT_TX_EMPTY|METH_INT_TX_PKT)) {
543
544 meth_tx_cleanup(dev, status.parsed.tx_read);
545 }
546
547 if (status.parsed.int_mask & (METH_INT_TX_LINK_FAIL))
548 printk(KERN_WARNING "meth: link failure\n");
549 if (status.parsed.int_mask & (METH_INT_MEM_ERROR))
550 printk(KERN_WARNING "meth: memory error\n");
551 if (status.parsed.int_mask & (METH_INT_TX_ABORT))
552 printk(KERN_WARNING "meth: aborted\n");
553 DPRINTK("Interrupt handling done...\n");
554
555 priv->regs->int_flags=status.reg&0xff;
556}
557
558
559
560
561static void meth_tx_short_prepare(meth_private* priv, struct sk_buff* skb)
562{
563 tx_packet *desc=&priv->tx_ring[priv->tx_write];
564 int len = (skb->len<ETH_ZLEN)?ETH_ZLEN:skb->len;
565
566 DPRINTK("preparing short packet\n");
567
568 memcpy(desc->data.dt+(120-len),skb->data,skb->len);
569 if(skb->len < len)
570 memset(desc->data.dt+120-len+skb->len,0,len-skb->len);
571 desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16);
572 DPRINTK("desc=%016lx\n",desc->header.raw);
573}
574#define TX_CATBUF1 BIT(25)
575static void meth_tx_1page_prepare(meth_private* priv, struct sk_buff* skb)
576{
577 tx_packet *desc=&priv->tx_ring[priv->tx_write];
578 void *buffer_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL));
579 int unaligned_len = (int)((u64)buffer_data - (u64)skb->data);
580 int buffer_len = skb->len - unaligned_len;
581 dma_addr_t catbuf;
582
583 DPRINTK("preparing 1 page...\n");
584 DPRINTK("length=%d data=%p\n", skb->len, skb->data);
585 DPRINTK("unaligned_len=%d\n", unaligned_len);
586 DPRINTK("buffer_data=%p buffer_len=%d\n",
587 buffer_data,
588 buffer_len);
589
590 desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1);
591
592
593 if(unaligned_len){
594 memcpy(desc->data.dt+(120-unaligned_len),
595 skb->data, unaligned_len);
596 desc->header.raw |= (128-unaligned_len) << 16;
597 }
598
599
600 catbuf = pci_map_single(NULL,
601 buffer_data,
602 buffer_len,
603 PCI_DMA_TODEVICE);
604 DPRINTK("catbuf=%x\n", catbuf);
605 desc->data.cat_buf[0].form.start_addr = catbuf >> 3;
606 desc->data.cat_buf[0].form.len = buffer_len-1;
607 DPRINTK("desc=%016lx\n",desc->header.raw);
608 DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw);
609}
610#define TX_CATBUF2 BIT(26)
611static void meth_tx_2page_prepare(meth_private* priv, struct sk_buff* skb)
612{
613 tx_packet *desc=&priv->tx_ring[priv->tx_write];
614 void *buffer1_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL));
615 void *buffer2_data = (void *)PAGE_ALIGN((u64)skb->data);
616 int unaligned_len = (int)((u64)buffer1_data - (u64)skb->data);
617 int buffer1_len = (int)((u64)buffer2_data - (u64)buffer1_data);
618 int buffer2_len = skb->len - buffer1_len - unaligned_len;
619 dma_addr_t catbuf1, catbuf2;
620
621 DPRINTK("preparing 2 pages... \n");
622 DPRINTK("length=%d data=%p\n", skb->len, skb->data);
623 DPRINTK("unaligned_len=%d\n", unaligned_len);
624 DPRINTK("buffer1_data=%p buffer1_len=%d\n",
625 buffer1_data,
626 buffer1_len);
627 DPRINTK("buffer2_data=%p buffer2_len=%d\n",
628 buffer2_data,
629 buffer2_len);
630
631 desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1);
632
633 if(unaligned_len){
634 memcpy(desc->data.dt+(120-unaligned_len),
635 skb->data, unaligned_len);
636 desc->header.raw |= (128-unaligned_len) << 16;
637 }
638
639
640 catbuf1 = pci_map_single(NULL,
641 buffer1_data,
642 buffer1_len,
643 PCI_DMA_TODEVICE);
644 DPRINTK("catbuf1=%x\n", catbuf1);
645 desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3;
646 desc->data.cat_buf[0].form.len = buffer1_len-1;
647
648 catbuf2 = pci_map_single(NULL,
649 buffer2_data,
650 buffer2_len,
651 PCI_DMA_TODEVICE);
652 DPRINTK("catbuf2=%x\n", catbuf2);
653 desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3;
654 desc->data.cat_buf[1].form.len = buffer2_len-1;
655 DPRINTK("desc=%016lx\n",desc->header.raw);
656 DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw);
657 DPRINTK("cat_buf[1].raw=%016lx\n",desc->data.cat_buf[1].raw);
658}
659
660
661void meth_add_to_tx_ring(meth_private *priv, struct sk_buff* skb)
662{
663 DPRINTK("Transmitting data...\n");
664 if(skb->len <= 120) {
665
666 meth_tx_short_prepare(priv,skb);
667 } else if(PAGE_ALIGN((u64)skb->data) !=
668 PAGE_ALIGN((u64)skb->data+skb->len-1)) {
669
670 meth_tx_2page_prepare(priv,skb);
671 } else {
672
673 meth_tx_1page_prepare(priv,skb);
674 }
675
676
677 priv->tx_skbs[priv->tx_write] = skb;
678 priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1);
679 priv->regs->tx_info.wptr = priv->tx_write;
680 priv->tx_count ++;
681
682 priv->regs->dma_ctrl |= METH_DMA_TX_INT_EN;
683}
684
685
686
687
688int meth_tx(struct sk_buff *skb, struct net_device *dev)
689{
690 struct meth_private *priv = (struct meth_private *) dev->priv;
691
692 spin_lock_irq(&priv->meth_lock);
693
694 meth_add_to_tx_ring(priv, skb);
695 dev->trans_start = jiffies;
696
697
698 if (meth_tx_full(dev)) {
699 DPRINTK("TX full: stopping\n");
700 netif_stop_queue(dev);
701 }
702
703 spin_unlock_irq(&priv->meth_lock);
704
705 return 0;
706}
707
708
709
710
711
712void meth_tx_timeout (struct net_device *dev)
713{
714 struct meth_private *priv = (struct meth_private *) dev->priv;
715
716 printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
717
718
719 spin_lock_irq(&priv->meth_lock);
720
721
722 meth_reset(dev);
723
724 priv->stats.tx_errors++;
725
726
727 meth_free_tx_ring(priv);
728 meth_free_rx_ring(priv);
729 meth_init_tx_ring(priv);
730 meth_init_rx_ring(priv);
731
732
733 priv->regs->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN;
734
735
736 spin_unlock_irq(&priv->meth_lock);
737
738 dev->trans_start = jiffies;
739 netif_wake_queue(dev);
740
741 return;
742}
743
744
745
746
747int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
748{
749
750 DPRINTK("ioctl\n");
751 return 0;
752}
753
754
755
756
757struct net_device_stats *meth_stats(struct net_device *dev)
758{
759 struct meth_private *priv = (struct meth_private *) dev->priv;
760 return &priv->stats;
761}
762
763
764
765
766
767int meth_init(struct net_device *dev)
768{
769 meth_private *priv;
770 int ret;
771
772
773
774
775 ether_setup(dev);
776
777 dev->open = meth_open;
778 dev->stop = meth_release;
779 dev->set_config = meth_config;
780 dev->hard_start_xmit = meth_tx;
781 dev->do_ioctl = meth_ioctl;
782 dev->get_stats = meth_stats;
783#ifdef HAVE_TX_TIMEOUT
784 dev->tx_timeout = meth_tx_timeout;
785 dev->watchdog_timeo = timeout;
786#endif
787 dev->irq = MACE_ETHERNET_IRQ;
788 SET_MODULE_OWNER(dev);
789
790
791
792
793
794 priv = kmalloc(sizeof(struct meth_private), GFP_KERNEL);
795 if (priv == NULL)
796 return -ENOMEM;
797 dev->priv=priv;
798 memset(priv, 0, sizeof(struct meth_private));
799 spin_lock_init(&((struct meth_private *) dev->priv)->meth_lock);
800
801
802
803
804
805 priv->regs=(meth_regs*)SGI_MFE;
806 dev->base_addr=SGI_MFE;
807 priv->phy_addr = -1;
808
809
810 if((ret=meth_reset(dev)) < 0)
811 return ret;
812
813
814 if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){
815 meth_free_tx_ring(priv);
816 meth_free_rx_ring(priv);
817 return ret;
818 }
819
820 printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29);
821
822 return 0;
823}
824
825
826
827
828
829struct net_device meth_devs[1] = {
830 { init: meth_init, }
831};
832
833
834
835
836
837int meth_init_module(void)
838{
839 int result, device_present = 0;
840
841 strcpy(meth_devs[0].name, "eth%d");
842
843 if ( (result = register_netdev(meth_devs)) )
844 printk("meth: error %i registering device \"%s\"\n",
845 result, meth_devs->name);
846 else device_present++;
847
848 return device_present ? 0 : -ENODEV;
849}
850
851void meth_cleanup(void)
852{
853 kfree(meth_devs->priv);
854 unregister_netdev(meth_devs);
855 return;
856}
857
858module_init(meth_init_module);
859module_exit(meth_cleanup);
860