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  */
sonic_open(struct net_device * dev)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  */
sonic_close(struct net_device * dev)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 
sonic_tx_timeout(struct net_device * dev)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  */
sonic_send_packet(struct sk_buff * skb,struct net_device * dev)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(PHYSADDR(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  */
sonic_interrupt(int irq,void * dev_id,struct pt_regs * regs)164 static void 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;
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 }
281 
282 /*
283  * We have a good packet(s), get it/them out of the buffers.
284  */
sonic_rx(struct net_device * dev)285 static void sonic_rx(struct net_device *dev)
286 {
287 	unsigned int base_addr = dev->base_addr;
288 	struct sonic_local *lp = (struct sonic_local *) dev->priv;
289 	sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK];
290 	int status;
291 
292 	while (rd->in_use == 0) {
293 		struct sk_buff *skb;
294 		int pkt_len;
295 		unsigned char *pkt_ptr;
296 
297 		status = rd->rx_status;
298 		if (sonic_debug > 3)
299 			printk("status %x, cur_rx %d, cur_rra %x\n",
300 			       status, lp->cur_rx, lp->cur_rra);
301 		if (status & SONIC_RCR_PRX) {
302 			pkt_len = rd->rx_pktlen;
303 			pkt_ptr =
304 			    (char *)
305 			    sonic_chiptomem((rd->rx_pktptr_h << 16) +
306 					    rd->rx_pktptr_l);
307 
308 			if (sonic_debug > 3)
309 				printk
310 				    ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n",
311 				     pkt_ptr, lp->rba, rd->rx_pktptr_h,
312 				     rd->rx_pktptr_l,
313 				     SONIC_READ(SONIC_RBWC1),
314 				     SONIC_READ(SONIC_RBWC0));
315 
316 			/* Malloc up new buffer. */
317 			skb = dev_alloc_skb(pkt_len + 2);
318 			if (skb == NULL) {
319 				printk
320 				    ("%s: Memory squeeze, dropping packet.\n",
321 				     dev->name);
322 				lp->stats.rx_dropped++;
323 				break;
324 			}
325 			skb->dev = dev;
326 			skb_reserve(skb, 2);	/* 16 byte align */
327 			skb_put(skb, pkt_len);	/* Make room */
328 			eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0);
329 			skb->protocol = eth_type_trans(skb, dev);
330 			netif_rx(skb);	/* pass the packet to upper layers */
331 			dev->last_rx = jiffies;
332 			lp->stats.rx_packets++;
333 			lp->stats.rx_bytes += pkt_len;
334 
335 		} else {
336 			/* This should only happen, if we enable accepting broken packets. */
337 			lp->stats.rx_errors++;
338 			if (status & SONIC_RCR_FAER)
339 				lp->stats.rx_frame_errors++;
340 			if (status & SONIC_RCR_CRCR)
341 				lp->stats.rx_crc_errors++;
342 		}
343 
344 		rd->in_use = 1;
345 		rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK];
346 		/* now give back the buffer to the receive buffer area */
347 		if (status & SONIC_RCR_LPKT) {
348 			/*
349 			 * this was the last packet out of the current receice buffer
350 			 * give the buffer back to the SONIC
351 			 */
352 			lp->cur_rra += sizeof(sonic_rr_t);
353 			if (lp->cur_rra >
354 			    (lp->rra_laddr +
355 			     (SONIC_NUM_RRS -
356 			      1) * sizeof(sonic_rr_t))) lp->cur_rra =
357 				    lp->rra_laddr;
358 			SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff);
359 		} else
360 			printk
361 			    ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n",
362 			     dev->name);
363 	}
364 	/*
365 	 * If any worth-while packets have been received, dev_rint()
366 	 * has done a mark_bh(NET_BH) for us and will work on them
367 	 * when we get to the bottom-half routine.
368 	 */
369 }
370 
371 
372 /*
373  * Get the current statistics.
374  * This may be called with the device open or closed.
375  */
sonic_get_stats(struct net_device * dev)376 static struct net_device_stats *sonic_get_stats(struct net_device *dev)
377 {
378 	struct sonic_local *lp = (struct sonic_local *) dev->priv;
379 	unsigned int base_addr = dev->base_addr;
380 
381 	/* read the tally counter from the SONIC and reset them */
382 	lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT);
383 	SONIC_WRITE(SONIC_CRCT, 0xffff);
384 	lp->stats.rx_frame_errors += SONIC_READ(SONIC_FAET);
385 	SONIC_WRITE(SONIC_FAET, 0xffff);
386 	lp->stats.rx_missed_errors += SONIC_READ(SONIC_MPT);
387 	SONIC_WRITE(SONIC_MPT, 0xffff);
388 
389 	return &lp->stats;
390 }
391 
392 
393 /*
394  * Set or clear the multicast filter for this adaptor.
395  */
sonic_multicast_list(struct net_device * dev)396 static void sonic_multicast_list(struct net_device *dev)
397 {
398 	struct sonic_local *lp = (struct sonic_local *) dev->priv;
399 	unsigned int base_addr = dev->base_addr;
400 	unsigned int rcr;
401 	struct dev_mc_list *dmi = dev->mc_list;
402 	unsigned char *addr;
403 	int i;
404 
405 	rcr = SONIC_READ(SONIC_RCR) & ~(SONIC_RCR_PRO | SONIC_RCR_AMC);
406 	rcr |= SONIC_RCR_BRD;	/* accept broadcast packets */
407 
408 	if (dev->flags & IFF_PROMISC) {	/* set promiscuous mode */
409 		rcr |= SONIC_RCR_PRO;
410 	} else {
411 		if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {
412 			rcr |= SONIC_RCR_AMC;
413 		} else {
414 			if (sonic_debug > 2)
415 				printk
416 				    ("sonic_multicast_list: mc_count %d\n",
417 				     dev->mc_count);
418 			lp->cda.cam_enable = 1;	/* always enable our own address */
419 			for (i = 1; i <= dev->mc_count; i++) {
420 				addr = dmi->dmi_addr;
421 				dmi = dmi->next;
422 				lp->cda.cam_desc[i].cam_cap0 =
423 				    addr[1] << 8 | addr[0];
424 				lp->cda.cam_desc[i].cam_cap1 =
425 				    addr[3] << 8 | addr[2];
426 				lp->cda.cam_desc[i].cam_cap2 =
427 				    addr[5] << 8 | addr[4];
428 				lp->cda.cam_enable |= (1 << i);
429 			}
430 			SONIC_WRITE(SONIC_CDC, 16);
431 			/* issue Load CAM command */
432 			SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
433 			SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM);
434 		}
435 	}
436 
437 	if (sonic_debug > 2)
438 		printk("sonic_multicast_list: setting RCR=%x\n", rcr);
439 
440 	SONIC_WRITE(SONIC_RCR, rcr);
441 }
442 
443 
444 /*
445  * Initialize the SONIC ethernet controller.
446  */
sonic_init(struct net_device * dev)447 static int sonic_init(struct net_device *dev)
448 {
449 	unsigned int base_addr = dev->base_addr;
450 	unsigned int cmd;
451 	struct sonic_local *lp = (struct sonic_local *) dev->priv;
452 	unsigned int rra_start;
453 	unsigned int rra_end;
454 	int i;
455 
456 	/*
457 	 * put the Sonic into software-reset mode and
458 	 * disable all interrupts
459 	 */
460 	SONIC_WRITE(SONIC_ISR, 0x7fff);
461 	SONIC_WRITE(SONIC_IMR, 0);
462 	SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
463 
464 	/*
465 	 * clear software reset flag, disable receiver, clear and
466 	 * enable interrupts, then completely initialize the SONIC
467 	 */
468 	SONIC_WRITE(SONIC_CMD, 0);
469 	SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
470 
471 	/*
472 	 * initialize the receive resource area
473 	 */
474 	if (sonic_debug > 2)
475 		printk("sonic_init: initialize receive resource area\n");
476 
477 	rra_start = lp->rra_laddr & 0xffff;
478 	rra_end =
479 	    (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff;
480 
481 	for (i = 0; i < SONIC_NUM_RRS; i++) {
482 		lp->rra[i].rx_bufadr_l =
483 		    (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff;
484 		lp->rra[i].rx_bufadr_h =
485 		    (lp->rba_laddr + i * SONIC_RBSIZE) >> 16;
486 		lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1;
487 		lp->rra[i].rx_bufsize_h = 0;
488 	}
489 
490 	/* initialize all RRA registers */
491 	SONIC_WRITE(SONIC_RSA, rra_start);
492 	SONIC_WRITE(SONIC_REA, rra_end);
493 	SONIC_WRITE(SONIC_RRP, rra_start);
494 	SONIC_WRITE(SONIC_RWP, rra_end);
495 	SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16);
496 	SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE - 2) >> 1);
497 
498 	lp->cur_rra =
499 	    lp->rra_laddr + (SONIC_NUM_RRS - 1) * sizeof(sonic_rr_t);
500 
501 	/* load the resource pointers */
502 	if (sonic_debug > 3)
503 		printk("sonic_init: issueing RRRA command\n");
504 
505 	SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA);
506 	i = 0;
507 	while (i++ < 100) {
508 		if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA)
509 			break;
510 	}
511 
512 	if (sonic_debug > 2)
513 		printk("sonic_init: status=%x\n", SONIC_READ(SONIC_CMD));
514 
515 	/*
516 	 * Initialize the receive descriptors so that they
517 	 * become a circular linked list, ie. let the last
518 	 * descriptor point to the first again.
519 	 */
520 	if (sonic_debug > 2)
521 		printk("sonic_init: initialize receive descriptors\n");
522 	for (i = 0; i < SONIC_NUM_RDS; i++) {
523 		lp->rda[i].rx_status = 0;
524 		lp->rda[i].rx_pktlen = 0;
525 		lp->rda[i].rx_pktptr_l = 0;
526 		lp->rda[i].rx_pktptr_h = 0;
527 		lp->rda[i].rx_seqno = 0;
528 		lp->rda[i].in_use = 1;
529 		lp->rda[i].link =
530 		    lp->rda_laddr + (i + 1) * sizeof(sonic_rd_t);
531 	}
532 	/* fix last descriptor */
533 	lp->rda[SONIC_NUM_RDS - 1].link = lp->rda_laddr;
534 	lp->cur_rx = 0;
535 	SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16);
536 	SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff);
537 
538 	/*
539 	 * initialize transmit descriptors
540 	 */
541 	if (sonic_debug > 2)
542 		printk("sonic_init: initialize transmit descriptors\n");
543 	for (i = 0; i < SONIC_NUM_TDS; i++) {
544 		lp->tda[i].tx_status = 0;
545 		lp->tda[i].tx_config = 0;
546 		lp->tda[i].tx_pktsize = 0;
547 		lp->tda[i].tx_frag_count = 0;
548 		lp->tda[i].link =
549 		    (lp->tda_laddr +
550 		     (i + 1) * sizeof(sonic_td_t)) | SONIC_END_OF_LINKS;
551 	}
552 	lp->tda[SONIC_NUM_TDS - 1].link =
553 	    (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS;
554 
555 	SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16);
556 	SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff);
557 	lp->cur_tx = lp->dirty_tx = 0;
558 
559 	/*
560 	 * put our own address to CAM desc[0]
561 	 */
562 	lp->cda.cam_desc[0].cam_cap0 =
563 	    dev->dev_addr[1] << 8 | dev->dev_addr[0];
564 	lp->cda.cam_desc[0].cam_cap1 =
565 	    dev->dev_addr[3] << 8 | dev->dev_addr[2];
566 	lp->cda.cam_desc[0].cam_cap2 =
567 	    dev->dev_addr[5] << 8 | dev->dev_addr[4];
568 	lp->cda.cam_enable = 1;
569 
570 	for (i = 0; i < 16; i++)
571 		lp->cda.cam_desc[i].cam_entry_pointer = i;
572 
573 	/*
574 	 * initialize CAM registers
575 	 */
576 	SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);
577 	SONIC_WRITE(SONIC_CDC, 16);
578 
579 	/*
580 	 * load the CAM
581 	 */
582 	SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM);
583 
584 	i = 0;
585 	while (i++ < 100) {
586 		if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)
587 			break;
588 	}
589 	if (sonic_debug > 2) {
590 		printk("sonic_init: CMD=%x, ISR=%x\n",
591 		       SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR));
592 	}
593 
594 	/*
595 	 * enable receiver, disable loopback
596 	 * and enable all interrupts
597 	 */
598 	SONIC_WRITE(SONIC_CMD, SONIC_CR_RXEN | SONIC_CR_STP);
599 	SONIC_WRITE(SONIC_RCR, SONIC_RCR_DEFAULT);
600 	SONIC_WRITE(SONIC_TCR, SONIC_TCR_DEFAULT);
601 	SONIC_WRITE(SONIC_ISR, 0x7fff);
602 	SONIC_WRITE(SONIC_IMR, SONIC_IMR_DEFAULT);
603 
604 	cmd = SONIC_READ(SONIC_CMD);
605 	if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0)
606 		printk("sonic_init: failed, status=%x\n", cmd);
607 
608 	if (sonic_debug > 2)
609 		printk("sonic_init: new status=%x\n",
610 		       SONIC_READ(SONIC_CMD));
611 
612 	return 0;
613 }
614 
615 MODULE_LICENSE("GPL");
616