vserver 2.0 rc7
[linux-2.6.git] / drivers / net / sonic.c
1 /*
2  * sonic.c
3  *
4  * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de)
5  * 
6  * This driver is based on work from Andreas Busse, but most of
7  * the code is rewritten.
8  * 
9  * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
10  *
11  *    Core code included by system sonic drivers
12  */
13
14 /*
15  * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook,
16  * National Semiconductors data sheet for the DP83932B Sonic Ethernet
17  * controller, and the files "8390.c" and "skeleton.c" in this directory.
18  */
19
20
21
22 /*
23  * Open/initialize the SONIC controller.
24  *
25  * This routine should set everything up anew at each open, even
26  *  registers that "should" only need to be set once at boot, so that
27  *  there is non-reboot way to recover if something goes wrong.
28  */
29 static int sonic_open(struct net_device *dev)
30 {
31         if (sonic_debug > 2)
32                 printk("sonic_open: initializing sonic driver.\n");
33
34         /*
35          * We don't need to deal with auto-irq stuff since we
36          * hardwire the sonic interrupt.
37          */
38 /*
39  * XXX Horrible work around:  We install sonic_interrupt as fast interrupt.
40  * This means that during execution of the handler interrupt are disabled
41  * covering another bug otherwise corrupting data.  This doesn't mean
42  * this glue works ok under all situations.
43  */
44 //    if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) {
45         if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT,
46                               "sonic", dev)) {
47                 printk("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq);
48                 return -EAGAIN;
49         }
50
51         /*
52          * Initialize the SONIC
53          */
54         sonic_init(dev);
55
56         netif_start_queue(dev);
57
58         if (sonic_debug > 2)
59                 printk("sonic_open: Initialization done.\n");
60
61         return 0;
62 }
63
64
65 /*
66  * Close the SONIC device
67  */
68 static int sonic_close(struct net_device *dev)
69 {
70         unsigned int base_addr = dev->base_addr;
71
72         if (sonic_debug > 2)
73                 printk("sonic_close\n");
74
75         netif_stop_queue(dev);
76
77         /*
78          * stop the SONIC, disable interrupts
79          */
80         SONIC_WRITE(SONIC_ISR, 0x7fff);
81         SONIC_WRITE(SONIC_IMR, 0);
82         SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
83
84         sonic_free_irq(dev->irq, dev);  /* release the IRQ */
85
86         return 0;
87 }
88
89 static void sonic_tx_timeout(struct net_device *dev)
90 {
91         struct sonic_local *lp = (struct sonic_local *) dev->priv;
92         printk("%s: transmit timed out.\n", dev->name);
93
94         /* Try to restart the adaptor. */
95         sonic_init(dev);
96         lp->stats.tx_errors++;
97         dev->trans_start = jiffies;
98         netif_wake_queue(dev);
99 }
100
101 /*
102  * transmit packet
103  */
104 static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
105 {
106         struct sonic_local *lp = (struct sonic_local *) dev->priv;
107         unsigned int base_addr = dev->base_addr;
108         unsigned int laddr;
109         int entry, length;
110
111         netif_stop_queue(dev);
112
113         if (sonic_debug > 2)
114                 printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev);
115
116         /*
117          * Map the packet data into the logical DMA address space
118          */
119         if ((laddr = vdma_alloc(CPHYSADDR(skb->data), skb->len)) == ~0UL) {
120                 printk("%s: no VDMA entry for transmit available.\n",
121                        dev->name);
122                 dev_kfree_skb(skb);
123                 netif_start_queue(dev);
124                 return 1;
125         }
126         entry = lp->cur_tx & SONIC_TDS_MASK;
127         lp->tx_laddr[entry] = laddr;
128         lp->tx_skb[entry] = skb;
129
130         length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
131         flush_cache_all();
132
133         /*
134          * Setup the transmit descriptor and issue the transmit command.
135          */
136         lp->tda[entry].tx_status = 0;   /* clear status */
137         lp->tda[entry].tx_frag_count = 1;       /* single fragment */
138         lp->tda[entry].tx_pktsize = length;     /* length of packet */
139         lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff;
140         lp->tda[entry].tx_frag_ptr_h = laddr >> 16;
141         lp->tda[entry].tx_frag_size = length;
142         lp->cur_tx++;
143         lp->stats.tx_bytes += length;
144
145         if (sonic_debug > 2)
146                 printk("sonic_send_packet: issueing Tx command\n");
147
148         SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP);
149
150         dev->trans_start = jiffies;
151
152         if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS)
153                 netif_start_queue(dev);
154         else
155                 lp->tx_full = 1;
156
157         return 0;
158 }
159
160 /*
161  * The typical workload of the driver:
162  * Handle the network interface interrupts.
163  */
164 static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs)
165 {
166         struct net_device *dev = (struct net_device *) dev_id;
167         unsigned int base_addr = dev->base_addr;
168         struct sonic_local *lp;
169         int status;
170
171         if (dev == NULL) {
172                 printk("sonic_interrupt: irq %d for unknown device.\n", irq);
173                 return IRQ_NONE;
174         }
175
176         lp = (struct sonic_local *) dev->priv;
177
178         status = SONIC_READ(SONIC_ISR);
179         SONIC_WRITE(SONIC_ISR, 0x7fff); /* clear all bits */
180
181         if (sonic_debug > 2)
182                 printk("sonic_interrupt: ISR=%x\n", status);
183
184         if (status & SONIC_INT_PKTRX) {
185                 sonic_rx(dev);  /* got packet(s) */
186         }
187
188         if (status & SONIC_INT_TXDN) {
189                 int dirty_tx = lp->dirty_tx;
190
191                 while (dirty_tx < lp->cur_tx) {
192                         int entry = dirty_tx & SONIC_TDS_MASK;
193                         int status = lp->tda[entry].tx_status;
194
195                         if (sonic_debug > 3)
196                                 printk
197                                     ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n",
198                                      status, lp->cur_tx, lp->dirty_tx);
199
200                         if (status == 0) {
201                                 /* It still hasn't been Txed, kick the sonic again */
202                                 SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP);
203                                 break;
204                         }
205
206                         /* put back EOL and free descriptor */
207                         lp->tda[entry].tx_frag_count = 0;
208                         lp->tda[entry].tx_status = 0;
209
210                         if (status & 0x0001)
211                                 lp->stats.tx_packets++;
212                         else {
213                                 lp->stats.tx_errors++;
214                                 if (status & 0x0642)
215                                         lp->stats.tx_aborted_errors++;
216                                 if (status & 0x0180)
217                                         lp->stats.tx_carrier_errors++;
218                                 if (status & 0x0020)
219                                         lp->stats.tx_window_errors++;
220                                 if (status & 0x0004)
221                                         lp->stats.tx_fifo_errors++;
222                         }
223
224                         /* We must free the original skb */
225                         if (lp->tx_skb[entry]) {
226                                 dev_kfree_skb_irq(lp->tx_skb[entry]);
227                                 lp->tx_skb[entry] = 0;
228                         }
229                         /* and the VDMA address */
230                         vdma_free(lp->tx_laddr[entry]);
231                         dirty_tx++;
232                 }
233
234                 if (lp->tx_full
235                     && dirty_tx + SONIC_NUM_TDS > lp->cur_tx + 2) {
236                         /* The ring is no longer full, clear tbusy. */
237                         lp->tx_full = 0;
238                         netif_wake_queue(dev);
239                 }
240
241                 lp->dirty_tx = dirty_tx;
242         }
243
244         /*
245          * check error conditions
246          */
247         if (status & SONIC_INT_RFO) {
248                 printk("%s: receive fifo underrun\n", dev->name);
249                 lp->stats.rx_fifo_errors++;
250         }
251         if (status & SONIC_INT_RDE) {
252                 printk("%s: receive descriptors exhausted\n", dev->name);
253                 lp->stats.rx_dropped++;
254         }
255         if (status & SONIC_INT_RBE) {
256                 printk("%s: receive buffer exhausted\n", dev->name);
257                 lp->stats.rx_dropped++;
258         }
259         if (status & SONIC_INT_RBAE) {
260                 printk("%s: receive buffer area exhausted\n", dev->name);
261                 lp->stats.rx_dropped++;
262         }
263
264         /* counter overruns; all counters are 16bit wide */
265         if (status & SONIC_INT_FAE)
266                 lp->stats.rx_frame_errors += 65536;
267         if (status & SONIC_INT_CRC)
268                 lp->stats.rx_crc_errors += 65536;
269         if (status & SONIC_INT_MP)
270                 lp->stats.rx_missed_errors += 65536;
271
272         /* transmit error */
273         if (status & SONIC_INT_TXER)
274                 lp->stats.tx_errors++;
275
276         /*
277          * clear interrupt bits and return
278          */
279         SONIC_WRITE(SONIC_ISR, status);
280         return IRQ_HANDLED;
281 }
282
283 /*
284  * We have a good packet(s), get it/them out of the buffers.
285  */
286 static void sonic_rx(struct net_device *dev)
287 {
288         unsigned int base_addr = dev->base_addr;
289         struct sonic_local *lp = (struct sonic_local *) dev->priv;
290         sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK];
291         int status;
292
293         while (rd->in_use == 0) {
294                 struct sk_buff *skb;
295                 int pkt_len;
296                 unsigned char *pkt_ptr;
297
298                 status = rd->rx_status;
299                 if (sonic_debug > 3)
300                         printk("status %x, cur_rx %d, cur_rra %x\n",
301                                status, lp->cur_rx, lp->cur_rra);
302                 if (status & SONIC_RCR_PRX) {
303                         pkt_len = rd->rx_pktlen;
304                         pkt_ptr =
305                             (char *)
306                             sonic_chiptomem((rd->rx_pktptr_h << 16) +
307                                             rd->rx_pktptr_l);
308
309                         if (sonic_debug > 3)
310                                 printk
311                                     ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n",
312                                      pkt_ptr, lp->rba, rd->rx_pktptr_h,
313                                      rd->rx_pktptr_l,
314                                      SONIC_READ(SONIC_RBWC1),
315                                      SONIC_READ(SONIC_RBWC0));
316
317                         /* Malloc up new buffer. */
318                         skb = dev_alloc_skb(pkt_len + 2);
319                         if (skb == NULL) {
320                                 printk
321                                     ("%s: Memory squeeze, dropping packet.\n",
322                                      dev->name);
323                                 lp->stats.rx_dropped++;
324                                 break;
325                         }
326                         skb->dev = dev;
327                         skb_reserve(skb, 2);    /* 16 byte align */
328                         skb_put(skb, pkt_len);  /* Make room */
329                         eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0);
330                         skb->protocol = eth_type_trans(skb, dev);
331                         netif_rx(skb);  /* pass the packet to upper layers */
332                         dev->last_rx = jiffies;
333                         lp->stats.rx_packets++;
334                         lp->stats.rx_bytes += pkt_len;
335
336                 } else {
337                         /* This should only happen, if we enable accepting broken packets. */
338                         lp->stats.rx_errors++;
339                         if (status & SONIC_RCR_FAER)
340                                 lp->stats.rx_frame_errors++;
341                         if (status & SONIC_RCR_CRCR)
342                                 lp->stats.rx_crc_errors++;
343                 }
344
345                 rd->in_use = 1;
346                 rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK];
347                 /* now give back the buffer to the receive buffer area */
348                 if (status & SONIC_RCR_LPKT) {
349                         /*
350                          * this was the last packet out of the current receice buffer
351                          * give the buffer back to the SONIC
352                          */
353                         lp->cur_rra += sizeof(sonic_rr_t);
354                         if (lp->cur_rra >
355                             (lp->rra_laddr +
356                              (SONIC_NUM_RRS -
357                               1) * sizeof(sonic_rr_t))) lp->cur_rra =
358                                     lp->rra_laddr;
359                         SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff);
360                 } else
361                         printk
362                             ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n",
363                              dev->name);
364         }
365         /*
366          * If any worth-while packets have been received, dev_rint()
367          * has done a mark_bh(NET_BH) for us and will work on them
368          * when we get to the bottom-half routine.
369          */
370 }
371
372
373 /*
374  * Get the current statistics.
375  * This may be called with the device open or closed.
376  */
377 static struct net_device_stats *sonic_get_stats(struct net_device *dev)
378 {
379         struct sonic_local *lp = (struct sonic_local *) dev->priv;
380         unsigned int base_addr = dev->base_addr;
381
382         /* read the tally counter from the SONIC and reset them */
383         lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT);
384         SONIC_WRITE(SONIC_CRCT, 0xffff);
385         lp->stats.rx_frame_errors += SONIC_READ(SONIC_FAET);
386         SONIC_WRITE(SONIC_FAET, 0xffff);
387         lp->stats.rx_missed_errors += SONIC_READ(SONIC_MPT);
388         SONIC_WRITE(SONIC_MPT, 0xffff);
389
390         return &lp->stats;
391 }
392
393
394 /*
395  * Set or clear the multicast filter for this adaptor.
396  */
397 static void sonic_multicast_list(struct net_device *dev)
398 {
399         struct sonic_local *lp = (struct sonic_local *) dev->priv;
400         unsigned int base_addr = dev->base_addr;
401         unsigned int rcr;
402         struct dev_mc_list *dmi = dev->mc_list;
403         unsigned char *addr;
404         int i;
405
406         rcr = SONIC_READ(SONIC_RCR) & ~(SONIC_RCR_PRO | SONIC_RCR_AMC);
407         rcr |= SONIC_RCR_BRD;   /* accept broadcast packets */
408
409         if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
410                 rcr |= SONIC_RCR_PRO;
411         } else {
412                 if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
413                         rcr |= SONIC_RCR_AMC;
414                 } else {
415                         if (sonic_debug > 2)
416                                 printk
417                                     ("sonic_multicast_list: mc_count %d\n",
418                                      dev->mc_count);
419                         lp->cda.cam_enable = 1; /* always enable our own address */
420                         for (i = 1; i <= dev->mc_count; i++) {
421                                 addr = dmi->dmi_addr;
422                                 dmi = dmi->next;
423                                 lp->cda.cam_desc[i].cam_cap0 =
424                                     addr[1] << 8 | addr[0];
425                                 lp->cda.cam_desc[i].cam_cap1 =
426                                     addr[3] << 8 | addr[2];
427                                 lp->cda.cam_desc[i].cam_cap2 =
428                                     addr[5] << 8 | addr[4];
429                                 lp->cda.cam_enable |= (1 << i);
430                         }
431                         SONIC_WRITE(SONIC_CDC, 16);
432                         /* issue Load CAM command */
433                         SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
434                         SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM);
435                 }
436         }
437
438         if (sonic_debug > 2)
439                 printk("sonic_multicast_list: setting RCR=%x\n", rcr);
440
441         SONIC_WRITE(SONIC_RCR, rcr);
442 }
443
444
445 /*
446  * Initialize the SONIC ethernet controller.
447  */
448 static int sonic_init(struct net_device *dev)
449 {
450         unsigned int base_addr = dev->base_addr;
451         unsigned int cmd;
452         struct sonic_local *lp = (struct sonic_local *) dev->priv;
453         unsigned int rra_start;
454         unsigned int rra_end;
455         int i;
456
457         /*
458          * put the Sonic into software-reset mode and
459          * disable all interrupts
460          */
461         SONIC_WRITE(SONIC_ISR, 0x7fff);
462         SONIC_WRITE(SONIC_IMR, 0);
463         SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
464
465         /*
466          * clear software reset flag, disable receiver, clear and
467          * enable interrupts, then completely initialize the SONIC
468          */
469         SONIC_WRITE(SONIC_CMD, 0);
470         SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
471
472         /*
473          * initialize the receive resource area
474          */
475         if (sonic_debug > 2)
476                 printk("sonic_init: initialize receive resource area\n");
477
478         rra_start = lp->rra_laddr & 0xffff;
479         rra_end =
480             (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff;
481
482         for (i = 0; i < SONIC_NUM_RRS; i++) {
483                 lp->rra[i].rx_bufadr_l =
484                     (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff;
485                 lp->rra[i].rx_bufadr_h =
486                     (lp->rba_laddr + i * SONIC_RBSIZE) >> 16;
487                 lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1;
488                 lp->rra[i].rx_bufsize_h = 0;
489         }
490
491         /* initialize all RRA registers */
492         SONIC_WRITE(SONIC_RSA, rra_start);
493         SONIC_WRITE(SONIC_REA, rra_end);
494         SONIC_WRITE(SONIC_RRP, rra_start);
495         SONIC_WRITE(SONIC_RWP, rra_end);
496         SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16);
497         SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE - 2) >> 1);
498
499         lp->cur_rra =
500             lp->rra_laddr + (SONIC_NUM_RRS - 1) * sizeof(sonic_rr_t);
501
502         /* load the resource pointers */
503         if (sonic_debug > 3)
504                 printk("sonic_init: issueing RRRA command\n");
505
506         SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA);
507         i = 0;
508         while (i++ < 100) {
509                 if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA)
510                         break;
511         }
512
513         if (sonic_debug > 2)
514                 printk("sonic_init: status=%x\n", SONIC_READ(SONIC_CMD));
515
516         /*
517          * Initialize the receive descriptors so that they
518          * become a circular linked list, ie. let the last
519          * descriptor point to the first again.
520          */
521         if (sonic_debug > 2)
522                 printk("sonic_init: initialize receive descriptors\n");
523         for (i = 0; i < SONIC_NUM_RDS; i++) {
524                 lp->rda[i].rx_status = 0;
525                 lp->rda[i].rx_pktlen = 0;
526                 lp->rda[i].rx_pktptr_l = 0;
527                 lp->rda[i].rx_pktptr_h = 0;
528                 lp->rda[i].rx_seqno = 0;
529                 lp->rda[i].in_use = 1;
530                 lp->rda[i].link =
531                     lp->rda_laddr + (i + 1) * sizeof(sonic_rd_t);
532         }
533         /* fix last descriptor */
534         lp->rda[SONIC_NUM_RDS - 1].link = lp->rda_laddr;
535         lp->cur_rx = 0;
536         SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16);
537         SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff);
538
539         /* 
540          * initialize transmit descriptors
541          */
542         if (sonic_debug > 2)
543                 printk("sonic_init: initialize transmit descriptors\n");
544         for (i = 0; i < SONIC_NUM_TDS; i++) {
545                 lp->tda[i].tx_status = 0;
546                 lp->tda[i].tx_config = 0;
547                 lp->tda[i].tx_pktsize = 0;
548                 lp->tda[i].tx_frag_count = 0;
549                 lp->tda[i].link =
550                     (lp->tda_laddr +
551                      (i + 1) * sizeof(sonic_td_t)) | SONIC_END_OF_LINKS;
552         }
553         lp->tda[SONIC_NUM_TDS - 1].link =
554             (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS;
555
556         SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16);
557         SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff);
558         lp->cur_tx = lp->dirty_tx = 0;
559
560         /*
561          * put our own address to CAM desc[0]
562          */
563         lp->cda.cam_desc[0].cam_cap0 =
564             dev->dev_addr[1] << 8 | dev->dev_addr[0];
565         lp->cda.cam_desc[0].cam_cap1 =
566             dev->dev_addr[3] << 8 | dev->dev_addr[2];
567         lp->cda.cam_desc[0].cam_cap2 =
568             dev->dev_addr[5] << 8 | dev->dev_addr[4];
569         lp->cda.cam_enable = 1;
570
571         for (i = 0; i < 16; i++)
572                 lp->cda.cam_desc[i].cam_entry_pointer = i;
573
574         /*
575          * initialize CAM registers
576          */
577         SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
578         SONIC_WRITE(SONIC_CDC, 16);
579
580         /*
581          * load the CAM
582          */
583         SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM);
584
585         i = 0;
586         while (i++ < 100) {
587                 if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)
588                         break;
589         }
590         if (sonic_debug > 2) {
591                 printk("sonic_init: CMD=%x, ISR=%x\n",
592                        SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR));
593         }
594
595         /*
596          * enable receiver, disable loopback
597          * and enable all interrupts
598          */
599         SONIC_WRITE(SONIC_CMD, SONIC_CR_RXEN | SONIC_CR_STP);
600         SONIC_WRITE(SONIC_RCR, SONIC_RCR_DEFAULT);
601         SONIC_WRITE(SONIC_TCR, SONIC_TCR_DEFAULT);
602         SONIC_WRITE(SONIC_ISR, 0x7fff);
603         SONIC_WRITE(SONIC_IMR, SONIC_IMR_DEFAULT);
604
605         cmd = SONIC_READ(SONIC_CMD);
606         if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0)
607                 printk("sonic_init: failed, status=%x\n", cmd);
608
609         if (sonic_debug > 2)
610                 printk("sonic_init: new status=%x\n",
611                        SONIC_READ(SONIC_CMD));
612
613         return 0;
614 }
615
616 MODULE_LICENSE("GPL");