4 * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de)
6 * This driver is based on work from Andreas Busse, but most of
7 * the code is rewritten.
9 * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
11 * Core code included by system sonic drivers
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.
23 * Open/initialize the SONIC controller.
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.
29 static int sonic_open(struct device
*dev
)
32 printk("sonic_open: initializing sonic driver.\n");
35 * We don't need to deal with auto-irq stuff since we
36 * hardwire the sonic interrupt.
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.
44 // if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) {
45 if (sonic_request_irq(dev
->irq
, &sonic_interrupt
, SA_INTERRUPT
, "sonic", dev
)) {
46 printk ("\n%s: unable to get IRQ %d .\n", dev
->name
, dev
->irq
);
51 * Initialize the SONIC
60 printk("sonic_open: Initialization done.\n");
67 * Close the SONIC device
70 sonic_close(struct device
*dev
)
72 unsigned int base_addr
= dev
->base_addr
;
75 printk ("sonic_close\n");
81 * stop the SONIC, disable interrupts
83 SONIC_WRITE(SONIC_ISR
,0x7fff);
84 SONIC_WRITE(SONIC_IMR
,0);
85 SONIC_WRITE(SONIC_CMD
,SONIC_CR_RST
);
87 sonic_free_irq(dev
->irq
, dev
); /* release the IRQ */
96 static int sonic_send_packet(struct sk_buff
*skb
, struct device
*dev
)
98 struct sonic_local
*lp
= (struct sonic_local
*)dev
->priv
;
99 unsigned int base_addr
= dev
->base_addr
;
104 printk("sonic_send_packet: skb=%p, dev=%p\n",skb
,dev
);
107 int tickssofar
= jiffies
- dev
->trans_start
;
109 /* If we get here, some higher level has decided we are broken.
110 There should really be a "kick me" function call instead. */
113 printk("sonic_send_packet: called with dev->tbusy = 1 !\n");
118 printk("%s: transmit timed out.\n", dev
->name
);
120 /* Try to restart the adaptor. */
123 dev
->trans_start
= jiffies
;
127 * Block a timer-based transmit from overlapping. This could better be
128 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
130 if (test_and_set_bit(0, (void*)&dev
->tbusy
) != 0) {
131 printk("%s: Transmitter access conflict.\n", dev
->name
);
136 * Map the packet data into the logical DMA address space
138 if ((laddr
= vdma_alloc(PHYSADDR(skb
->data
),skb
->len
)) == ~0UL) {
139 printk("%s: no VDMA entry for transmit available.\n",dev
->name
);
144 entry
= lp
->cur_tx
& SONIC_TDS_MASK
;
145 lp
->tx_laddr
[entry
] = laddr
;
146 lp
->tx_skb
[entry
] = skb
;
148 length
= (skb
->len
< ETH_ZLEN
) ? ETH_ZLEN
: skb
->len
;
152 * Setup the transmit descriptor and issue the transmit command.
154 lp
->tda
[entry
].tx_status
= 0; /* clear status */
155 lp
->tda
[entry
].tx_frag_count
= 1; /* single fragment */
156 lp
->tda
[entry
].tx_pktsize
= length
; /* length of packet */
157 lp
->tda
[entry
].tx_frag_ptr_l
= laddr
& 0xffff;
158 lp
->tda
[entry
].tx_frag_ptr_h
= laddr
>> 16;
159 lp
->tda
[entry
].tx_frag_size
= length
;
161 lp
->stats
.tx_bytes
+= length
;
164 printk("sonic_send_packet: issueing Tx command\n");
166 SONIC_WRITE(SONIC_CMD
,SONIC_CR_TXP
);
168 dev
->trans_start
= jiffies
;
170 if (lp
->cur_tx
< lp
->dirty_tx
+ SONIC_NUM_TDS
)
180 * The typical workload of the driver:
181 * Handle the network interface interrupts.
184 sonic_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
)
186 struct device
*dev
= (struct device
*)dev_id
;
187 unsigned int base_addr
= dev
->base_addr
;
188 struct sonic_local
*lp
;
192 printk ("sonic_interrupt: irq %d for unknown device.\n", irq
);
196 lp
= (struct sonic_local
*)dev
->priv
;
198 status
= SONIC_READ(SONIC_ISR
);
199 SONIC_WRITE(SONIC_ISR
,0x7fff); /* clear all bits */
202 printk("sonic_interrupt: ISR=%x\n",status
);
204 if (status
& SONIC_INT_PKTRX
) {
205 sonic_rx(dev
); /* got packet(s) */
208 if (status
& SONIC_INT_TXDN
) {
209 int dirty_tx
= lp
->dirty_tx
;
211 while (dirty_tx
< lp
->cur_tx
) {
212 int entry
= dirty_tx
& SONIC_TDS_MASK
;
213 int status
= lp
->tda
[entry
].tx_status
;
216 printk ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n",
217 status
,lp
->cur_tx
,lp
->dirty_tx
);
220 /* It still hasn't been Txed, kick the sonic again */
221 SONIC_WRITE(SONIC_CMD
,SONIC_CR_TXP
);
225 /* put back EOL and free descriptor */
226 lp
->tda
[entry
].tx_frag_count
= 0;
227 lp
->tda
[entry
].tx_status
= 0;
230 lp
->stats
.tx_packets
++;
232 lp
->stats
.tx_errors
++;
233 if (status
& 0x0642) lp
->stats
.tx_aborted_errors
++;
234 if (status
& 0x0180) lp
->stats
.tx_carrier_errors
++;
235 if (status
& 0x0020) lp
->stats
.tx_window_errors
++;
236 if (status
& 0x0004) lp
->stats
.tx_fifo_errors
++;
239 /* We must free the original skb */
240 if (lp
->tx_skb
[entry
]) {
241 dev_kfree_skb(lp
->tx_skb
[entry
]);
242 lp
->tx_skb
[entry
] = 0;
244 /* and the VDMA address */
245 vdma_free(lp
->tx_laddr
[entry
]);
249 if (lp
->tx_full
&& dev
->tbusy
250 && dirty_tx
+ SONIC_NUM_TDS
> lp
->cur_tx
+ 2) {
251 /* The ring is no longer full, clear tbusy. */
257 lp
->dirty_tx
= dirty_tx
;
261 * check error conditions
263 if (status
& SONIC_INT_RFO
) {
264 printk ("%s: receive fifo underrun\n",dev
->name
);
265 lp
->stats
.rx_fifo_errors
++;
267 if (status
& SONIC_INT_RDE
) {
268 printk ("%s: receive descriptors exhausted\n",dev
->name
);
269 lp
->stats
.rx_dropped
++;
271 if (status
& SONIC_INT_RBE
) {
272 printk ("%s: receive buffer exhausted\n",dev
->name
);
273 lp
->stats
.rx_dropped
++;
275 if (status
& SONIC_INT_RBAE
) {
276 printk ("%s: receive buffer area exhausted\n",dev
->name
);
277 lp
->stats
.rx_dropped
++;
280 /* counter overruns; all counters are 16bit wide */
281 if (status
& SONIC_INT_FAE
)
282 lp
->stats
.rx_frame_errors
+= 65536;
283 if (status
& SONIC_INT_CRC
)
284 lp
->stats
.rx_crc_errors
+= 65536;
285 if (status
& SONIC_INT_MP
)
286 lp
->stats
.rx_missed_errors
+= 65536;
289 if (status
& SONIC_INT_TXER
)
290 lp
->stats
.tx_errors
++;
293 * clear interrupt bits and return
295 SONIC_WRITE(SONIC_ISR
,status
);
301 * We have a good packet(s), get it/them out of the buffers.
304 sonic_rx(struct device
*dev
)
306 unsigned int base_addr
= dev
->base_addr
;
307 struct sonic_local
*lp
= (struct sonic_local
*)dev
->priv
;
308 sonic_rd_t
*rd
= &lp
->rda
[lp
->cur_rx
& SONIC_RDS_MASK
];
311 while (rd
->in_use
== 0) {
314 unsigned char *pkt_ptr
;
316 status
= rd
->rx_status
;
318 printk ("status %x, cur_rx %d, cur_rra %x\n",status
,lp
->cur_rx
,lp
->cur_rra
);
319 if (status
& SONIC_RCR_PRX
) {
320 pkt_len
= rd
->rx_pktlen
;
321 pkt_ptr
= (char *)sonic_chiptomem((rd
->rx_pktptr_h
<< 16) +
325 printk ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n", pkt_ptr
,lp
->rba
,
326 rd
->rx_pktptr_h
,rd
->rx_pktptr_l
,
327 SONIC_READ(SONIC_RBWC1
),SONIC_READ(SONIC_RBWC0
));
329 /* Malloc up new buffer. */
330 skb
= dev_alloc_skb(pkt_len
+2);
332 printk("%s: Memory squeeze, dropping packet.\n", dev
->name
);
333 lp
->stats
.rx_dropped
++;
337 skb_reserve(skb
,2); /* 16 byte align */
338 skb_put(skb
,pkt_len
); /* Make room */
339 eth_copy_and_sum(skb
, pkt_ptr
, pkt_len
, 0);
340 skb
->protocol
=eth_type_trans(skb
,dev
);
341 netif_rx(skb
); /* pass the packet to upper layers */
342 lp
->stats
.rx_packets
++;
343 lp
->stats
.rx_bytes
+= pkt_len
;
346 /* This should only happen, if we enable accepting broken packets. */
347 lp
->stats
.rx_errors
++;
348 if (status
& SONIC_RCR_FAER
) lp
->stats
.rx_frame_errors
++;
349 if (status
& SONIC_RCR_CRCR
) lp
->stats
.rx_crc_errors
++;
353 rd
= &lp
->rda
[(++lp
->cur_rx
) & SONIC_RDS_MASK
];
354 /* now give back the buffer to the receive buffer area */
355 if (status
& SONIC_RCR_LPKT
) {
357 * this was the last packet out of the current receice buffer
358 * give the buffer back to the SONIC
360 lp
->cur_rra
+= sizeof(sonic_rr_t
);
361 if (lp
->cur_rra
> (lp
->rra_laddr
+ (SONIC_NUM_RRS
-1) * sizeof(sonic_rr_t
)))
362 lp
->cur_rra
= lp
->rra_laddr
;
363 SONIC_WRITE(SONIC_RWP
, lp
->cur_rra
& 0xffff);
365 printk ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n",dev
->name
);
368 * If any worth-while packets have been received, dev_rint()
369 * has done a mark_bh(NET_BH) for us and will work on them
370 * when we get to the bottom-half routine.
377 * Get the current statistics.
378 * This may be called with the device open or closed.
380 static struct enet_statistics
*
381 sonic_get_stats(struct device
*dev
)
383 struct sonic_local
*lp
= (struct sonic_local
*)dev
->priv
;
384 unsigned int base_addr
= dev
->base_addr
;
386 /* read the tally counter from the SONIC and reset them */
387 lp
->stats
.rx_crc_errors
+= SONIC_READ(SONIC_CRCT
);
388 SONIC_WRITE(SONIC_CRCT
,0xffff);
389 lp
->stats
.rx_frame_errors
+= SONIC_READ(SONIC_FAET
);
390 SONIC_WRITE(SONIC_FAET
,0xffff);
391 lp
->stats
.rx_missed_errors
+= SONIC_READ(SONIC_MPT
);
392 SONIC_WRITE(SONIC_MPT
,0xffff);
399 * Set or clear the multicast filter for this adaptor.
402 sonic_multicast_list(struct device
*dev
)
404 struct sonic_local
*lp
= (struct sonic_local
*)dev
->priv
;
405 unsigned int base_addr
= dev
->base_addr
;
407 struct dev_mc_list
*dmi
= dev
->mc_list
;
411 rcr
= SONIC_READ(SONIC_RCR
) & ~(SONIC_RCR_PRO
| SONIC_RCR_AMC
);
412 rcr
|= SONIC_RCR_BRD
; /* accept broadcast packets */
414 if (dev
->flags
& IFF_PROMISC
) { /* set promiscuous mode */
415 rcr
|= SONIC_RCR_PRO
;
417 if ((dev
->flags
& IFF_ALLMULTI
) || (dev
->mc_count
> 15)) {
418 rcr
|= SONIC_RCR_AMC
;
421 printk ("sonic_multicast_list: mc_count %d\n",dev
->mc_count
);
422 lp
->cda
.cam_enable
= 1; /* always enable our own address */
423 for (i
= 1; i
<= dev
->mc_count
; i
++) {
424 addr
= dmi
->dmi_addr
;
426 lp
->cda
.cam_desc
[i
].cam_cap0
= addr
[1] << 8 | addr
[0];
427 lp
->cda
.cam_desc
[i
].cam_cap1
= addr
[3] << 8 | addr
[2];
428 lp
->cda
.cam_desc
[i
].cam_cap2
= addr
[5] << 8 | addr
[4];
429 lp
->cda
.cam_enable
|= (1 << i
);
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
);
439 printk("sonic_multicast_list: setting RCR=%x\n",rcr
);
441 SONIC_WRITE(SONIC_RCR
,rcr
);
446 * Initialize the SONIC ethernet controller.
448 static int sonic_init(struct device
*dev
)
450 unsigned int base_addr
= dev
->base_addr
;
452 struct sonic_local
*lp
= (struct sonic_local
*)dev
->priv
;
453 unsigned int rra_start
;
454 unsigned int rra_end
;
458 * put the Sonic into software-reset mode and
459 * disable all interrupts
461 SONIC_WRITE(SONIC_ISR
,0x7fff);
462 SONIC_WRITE(SONIC_IMR
,0);
463 SONIC_WRITE(SONIC_CMD
,SONIC_CR_RST
);
466 * clear software reset flag, disable receiver, clear and
467 * enable interrupts, then completely initialize the SONIC
469 SONIC_WRITE(SONIC_CMD
,0);
470 SONIC_WRITE(SONIC_CMD
,SONIC_CR_RXDIS
);
473 * initialize the receive resource area
476 printk ("sonic_init: initialize receive resource area\n");
478 rra_start
= lp
->rra_laddr
& 0xffff;
479 rra_end
= (rra_start
+ (SONIC_NUM_RRS
* sizeof(sonic_rr_t
))) & 0xffff;
481 for (i
= 0; i
< SONIC_NUM_RRS
; i
++) {
482 lp
->rra
[i
].rx_bufadr_l
= (lp
->rba_laddr
+ i
* SONIC_RBSIZE
) & 0xffff;
483 lp
->rra
[i
].rx_bufadr_h
= (lp
->rba_laddr
+ i
* SONIC_RBSIZE
) >> 16;
484 lp
->rra
[i
].rx_bufsize_l
= SONIC_RBSIZE
>> 1;
485 lp
->rra
[i
].rx_bufsize_h
= 0;
488 /* initialize all RRA registers */
489 SONIC_WRITE(SONIC_RSA
,rra_start
);
490 SONIC_WRITE(SONIC_REA
,rra_end
);
491 SONIC_WRITE(SONIC_RRP
,rra_start
);
492 SONIC_WRITE(SONIC_RWP
,rra_end
);
493 SONIC_WRITE(SONIC_URRA
,lp
->rra_laddr
>> 16);
494 SONIC_WRITE(SONIC_EOBC
,(SONIC_RBSIZE
-2) >> 1);
496 lp
->cur_rra
= lp
->rra_laddr
+ (SONIC_NUM_RRS
-1) * sizeof(sonic_rr_t
);
498 /* load the resource pointers */
500 printk("sonic_init: issueing RRRA command\n");
502 SONIC_WRITE(SONIC_CMD
,SONIC_CR_RRRA
);
505 if (SONIC_READ(SONIC_CMD
) & SONIC_CR_RRRA
)
510 printk("sonic_init: status=%x\n",SONIC_READ(SONIC_CMD
));
513 * Initialize the receive descriptors so that they
514 * become a circular linked list, ie. let the last
515 * descriptor point to the first again.
518 printk ("sonic_init: initialize receive descriptors\n");
519 for (i
=0; i
<SONIC_NUM_RDS
; i
++) {
520 lp
->rda
[i
].rx_status
= 0;
521 lp
->rda
[i
].rx_pktlen
= 0;
522 lp
->rda
[i
].rx_pktptr_l
= 0;
523 lp
->rda
[i
].rx_pktptr_h
= 0;
524 lp
->rda
[i
].rx_seqno
= 0;
525 lp
->rda
[i
].in_use
= 1;
526 lp
->rda
[i
].link
= lp
->rda_laddr
+ (i
+1) * sizeof (sonic_rd_t
);
528 /* fix last descriptor */
529 lp
->rda
[SONIC_NUM_RDS
-1].link
= lp
->rda_laddr
;
531 SONIC_WRITE(SONIC_URDA
,lp
->rda_laddr
>> 16);
532 SONIC_WRITE(SONIC_CRDA
,lp
->rda_laddr
& 0xffff);
535 * initialize transmit descriptors
538 printk ("sonic_init: initialize transmit descriptors\n");
539 for (i
= 0; i
< SONIC_NUM_TDS
; i
++) {
540 lp
->tda
[i
].tx_status
= 0;
541 lp
->tda
[i
].tx_config
= 0;
542 lp
->tda
[i
].tx_pktsize
= 0;
543 lp
->tda
[i
].tx_frag_count
= 0;
544 lp
->tda
[i
].link
= (lp
->tda_laddr
+ (i
+1) * sizeof (sonic_td_t
)) | SONIC_END_OF_LINKS
;
546 lp
->tda
[SONIC_NUM_TDS
-1].link
= (lp
->tda_laddr
& 0xffff) | SONIC_END_OF_LINKS
;
548 SONIC_WRITE(SONIC_UTDA
,lp
->tda_laddr
>> 16);
549 SONIC_WRITE(SONIC_CTDA
,lp
->tda_laddr
& 0xffff);
550 lp
->cur_tx
= lp
->dirty_tx
= 0;
553 * put our own address to CAM desc[0]
555 lp
->cda
.cam_desc
[0].cam_cap0
= dev
->dev_addr
[1] << 8 | dev
->dev_addr
[0];
556 lp
->cda
.cam_desc
[0].cam_cap1
= dev
->dev_addr
[3] << 8 | dev
->dev_addr
[2];
557 lp
->cda
.cam_desc
[0].cam_cap2
= dev
->dev_addr
[5] << 8 | dev
->dev_addr
[4];
558 lp
->cda
.cam_enable
= 1;
560 for (i
=0; i
< 16; i
++)
561 lp
->cda
.cam_desc
[i
].cam_entry_pointer
= i
;
564 * initialize CAM registers
566 SONIC_WRITE(SONIC_CDP
, lp
->cda_laddr
& 0xffff);
567 SONIC_WRITE(SONIC_CDC
,16);
572 SONIC_WRITE(SONIC_CMD
,SONIC_CR_LCAM
);
576 if (SONIC_READ(SONIC_ISR
) & SONIC_INT_LCD
)
579 if (sonic_debug
> 2) {
580 printk("sonic_init: CMD=%x, ISR=%x\n",
581 SONIC_READ(SONIC_CMD
),
582 SONIC_READ(SONIC_ISR
));
586 * enable receiver, disable loopback
587 * and enable all interrupts
589 SONIC_WRITE(SONIC_CMD
,SONIC_CR_RXEN
| SONIC_CR_STP
);
590 SONIC_WRITE(SONIC_RCR
,SONIC_RCR_DEFAULT
);
591 SONIC_WRITE(SONIC_TCR
,SONIC_TCR_DEFAULT
);
592 SONIC_WRITE(SONIC_ISR
,0x7fff);
593 SONIC_WRITE(SONIC_IMR
,SONIC_IMR_DEFAULT
);
595 cmd
= SONIC_READ(SONIC_CMD
);
596 if ((cmd
& SONIC_CR_RXEN
) == 0 ||
597 (cmd
& SONIC_CR_STP
) == 0)
598 printk("sonic_init: failed, status=%x\n",cmd
);
601 printk("sonic_init: new status=%x\n",SONIC_READ(SONIC_CMD
));
609 * compile-command: "mipsel-linux-gcc -D__KERNEL__ -D__mips64 -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -mcpu=r4000 -c sonic.c"
611 * kept-new-versions: 5