1 /* mac89x0.c: A Crystal Semiconductor CS89[02]0 driver for linux. */
2 /*
3 	Written 1996 by Russell Nelson, with reference to skeleton.c
4 	written 1993-1994 by Donald Becker.
5 
6 	This software may be used and distributed according to the terms
7 	of the GNU General Public License, incorporated herein by reference.
8 
9 	The author may be reached at nelson@crynwr.com, Crynwr
10 	Software, 11 Grant St., Potsdam, NY 13676
11 
12   Changelog:
13 
14   Mike Cruse        : mcruse@cti-ltd.com
15                     : Changes for Linux 2.0 compatibility.
16                     : Added dev_id parameter in net_interrupt(),
17                     : request_irq() and free_irq(). Just NULL for now.
18 
19   Mike Cruse        : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros
20                     : in net_open() and net_close() so kerneld would know
21                     : that the module is in use and wouldn't eject the
22                     : driver prematurely.
23 
24   Mike Cruse        : Rewrote init_module() and cleanup_module using 8390.c
25                     : as an example. Disabled autoprobing in init_module(),
26                     : not a good thing to do to other devices while Linux
27                     : is running from all accounts.
28 
29   Alan Cox          : Removed 1.2 support, added 2.1 extra counters.
30 
31   David Huggins-Daines <dhd@debian.org>
32 
33   Split this off into mac89x0.c, and gutted it of all parts which are
34   not relevant to the existing CS8900 cards on the Macintosh
35   (i.e. basically the Daynaport CS and LC cards).  To be precise:
36 
37     * Removed all the media-detection stuff, because these cards are
38     TP-only.
39 
40     * Lobotomized the ISA interrupt bogosity, because these cards use
41     a hardwired NuBus interrupt and a magic ISAIRQ value in the card.
42 
43     * Basically eliminated everything not relevant to getting the
44     cards minimally functioning on the Macintosh.
45 
46   I might add that these cards are badly designed even from the Mac
47   standpoint, in that Dayna, in their infinite wisdom, used NuBus slot
48   I/O space and NuBus interrupts for these cards, but neglected to
49   provide anything even remotely resembling a NuBus ROM.  Therefore we
50   have to probe for them in a brain-damaged ISA-like fashion.
51 
52   Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 11/01/2001
53   check kmalloc and release the allocated memory on failure in
54   mac89x0_probe and in init_module
55   use local_irq_{save,restore}(flags) in net_get_stat, not just
56   local_irq_{dis,en}able()
57 */
58 
59 static const char version[] =
60 "cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>\n";
61 
62 /* ======================= configure the driver here ======================= */
63 
64 /* use 0 for production, 1 for verification, >2 for debug */
65 #ifndef NET_DEBUG
66 #define NET_DEBUG 0
67 #endif
68 
69 /* ======================= end of configuration ======================= */
70 
71 
72 /* Always include 'config.h' first in case the user wants to turn on
73    or override something. */
74 #include <linux/module.h>
75 
76 /*
77   Sources:
78 
79 	Crynwr packet driver epktisa.
80 
81 	Crystal Semiconductor data sheets.
82 
83 */
84 
85 #include <linux/kernel.h>
86 #include <linux/types.h>
87 #include <linux/fcntl.h>
88 #include <linux/interrupt.h>
89 #include <linux/ioport.h>
90 #include <linux/in.h>
91 #include <linux/string.h>
92 #include <linux/nubus.h>
93 #include <linux/errno.h>
94 #include <linux/init.h>
95 #include <linux/netdevice.h>
96 #include <linux/etherdevice.h>
97 #include <linux/skbuff.h>
98 #include <linux/delay.h>
99 #include <linux/bitops.h>
100 #include <linux/gfp.h>
101 
102 #include <asm/io.h>
103 #include <asm/hwtest.h>
104 #include <asm/macints.h>
105 
106 #include "cs89x0.h"
107 
108 static unsigned int net_debug = NET_DEBUG;
109 
110 /* Information that need to be kept for each board. */
111 struct net_local {
112 	int chip_type;		/* one of: CS8900, CS8920, CS8920M */
113 	char chip_revision;	/* revision letter of the chip ('A'...) */
114 	int send_cmd;		/* the propercommand used to send a packet. */
115 	int rx_mode;
116 	int curr_rx_cfg;
117         int send_underrun;      /* keep track of how many underruns in a row we get */
118 	struct sk_buff *skb;
119 };
120 
121 /* Index to functions, as function prototypes. */
122 
123 #if 0
124 extern void reset_chip(struct net_device *dev);
125 #endif
126 static int net_open(struct net_device *dev);
127 static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
128 static irqreturn_t net_interrupt(int irq, void *dev_id);
129 static void set_multicast_list(struct net_device *dev);
130 static void net_rx(struct net_device *dev);
131 static int net_close(struct net_device *dev);
132 static struct net_device_stats *net_get_stats(struct net_device *dev);
133 static int set_mac_address(struct net_device *dev, void *addr);
134 
135 
136 /* Example routines you must write ;->. */
137 #define tx_done(dev) 1
138 
139 /* For reading/writing registers ISA-style */
140 static inline int
141 readreg_io(struct net_device *dev, int portno)
142 {
143 	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
144 	return swab16(nubus_readw(dev->base_addr + DATA_PORT));
145 }
146 
147 static inline void
148 writereg_io(struct net_device *dev, int portno, int value)
149 {
150 	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
151 	nubus_writew(swab16(value), dev->base_addr + DATA_PORT);
152 }
153 
154 /* These are for reading/writing registers in shared memory */
155 static inline int
156 readreg(struct net_device *dev, int portno)
157 {
158 	return swab16(nubus_readw(dev->mem_start + portno));
159 }
160 
161 static inline void
162 writereg(struct net_device *dev, int portno, int value)
163 {
164 	nubus_writew(swab16(value), dev->mem_start + portno);
165 }
166 
167 static const struct net_device_ops mac89x0_netdev_ops = {
168 	.ndo_open		= net_open,
169 	.ndo_stop		= net_close,
170 	.ndo_start_xmit		= net_send_packet,
171 	.ndo_get_stats		= net_get_stats,
172 	.ndo_set_rx_mode	= set_multicast_list,
173 	.ndo_set_mac_address	= set_mac_address,
174 	.ndo_validate_addr	= eth_validate_addr,
175 };
176 
177 /* Probe for the CS8900 card in slot E.  We won't bother looking
178    anywhere else until we have a really good reason to do so. */
179 struct net_device * __init mac89x0_probe(int unit)
180 {
181 	struct net_device *dev;
182 	static int once_is_enough;
183 	struct net_local *lp;
184 	static unsigned version_printed;
185 	int i, slot;
186 	unsigned rev_type = 0;
187 	unsigned long ioaddr;
188 	unsigned short sig;
189 	int err = -ENODEV;
190 	struct nubus_rsrc *fres;
191 
192 	if (!MACH_IS_MAC)
193 		return ERR_PTR(-ENODEV);
194 
195 	dev = alloc_etherdev(sizeof(struct net_local));
196 	if (!dev)
197 		return ERR_PTR(-ENOMEM);
198 
199 	if (unit >= 0) {
200 		sprintf(dev->name, "eth%d", unit);
201 		netdev_boot_setup_check(dev);
202 	}
203 
204 	if (once_is_enough)
205 		goto out;
206 	once_is_enough = 1;
207 
208 	/* We might have to parameterize this later */
209 	slot = 0xE;
210 	/* Get out now if there's a real NuBus card in slot E */
211 	for_each_func_rsrc(fres)
212 		if (fres->board->slot == slot)
213 			goto out;
214 
215 	/* The pseudo-ISA bits always live at offset 0x300 (gee,
216            wonder why...) */
217 	ioaddr = (unsigned long)
218 		nubus_slot_addr(slot) | (((slot&0xf) << 20) + DEFAULTIOBASE);
219 	{
220 		int card_present;
221 
222 		card_present = (hwreg_present((void *)ioaddr + 4) &&
223 				hwreg_present((void *)ioaddr + DATA_PORT));
224 		if (!card_present)
225 			goto out;
226 	}
227 
228 	nubus_writew(0, ioaddr + ADD_PORT);
229 	sig = nubus_readw(ioaddr + DATA_PORT);
230 	if (sig != swab16(CHIP_EISA_ID_SIG))
231 		goto out;
232 
233 	/* Initialize the net_device structure. */
234 	lp = netdev_priv(dev);
235 
236 	/* Fill in the 'dev' fields. */
237 	dev->base_addr = ioaddr;
238 	dev->mem_start = (unsigned long)
239 		nubus_slot_addr(slot) | (((slot&0xf) << 20) + MMIOBASE);
240 	dev->mem_end = dev->mem_start + 0x1000;
241 
242 	/* Turn on shared memory */
243 	writereg_io(dev, PP_BusCTL, MEMORY_ON);
244 
245 	/* get the chip type */
246 	rev_type = readreg(dev, PRODUCT_ID_ADD);
247 	lp->chip_type = rev_type &~ REVISON_BITS;
248 	lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
249 
250 	/* Check the chip type and revision in order to set the correct send command
251 	CS8920 revision C and CS8900 revision F can use the faster send. */
252 	lp->send_cmd = TX_AFTER_381;
253 	if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
254 		lp->send_cmd = TX_NOW;
255 	if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
256 		lp->send_cmd = TX_NOW;
257 
258 	if (net_debug && version_printed++ == 0)
259 		printk(version);
260 
261 	printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#8lx",
262 	       dev->name,
263 	       lp->chip_type==CS8900?'0':'2',
264 	       lp->chip_type==CS8920M?"M":"",
265 	       lp->chip_revision,
266 	       dev->base_addr);
267 
268 	/* Try to read the MAC address */
269 	if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
270 		printk("\nmac89x0: No EEPROM, giving up now.\n");
271 		goto out1;
272         } else {
273                 for (i = 0; i < ETH_ALEN; i += 2) {
274 			/* Big-endian (why??!) */
275 			unsigned short s = readreg(dev, PP_IA + i);
276                         dev->dev_addr[i] = s >> 8;
277                         dev->dev_addr[i+1] = s & 0xff;
278                 }
279         }
280 
281 	dev->irq = SLOT2IRQ(slot);
282 
283 	/* print the IRQ and ethernet address. */
284 
285 	printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr);
286 
287 	dev->netdev_ops		= &mac89x0_netdev_ops;
288 
289 	err = register_netdev(dev);
290 	if (err)
291 		goto out1;
292 	return NULL;
293 out1:
294 	nubus_writew(0, dev->base_addr + ADD_PORT);
295 out:
296 	free_netdev(dev);
297 	return ERR_PTR(err);
298 }
299 
300 #if 0
301 /* This is useful for something, but I don't know what yet. */
302 void __init reset_chip(struct net_device *dev)
303 {
304 	int reset_start_time;
305 
306 	writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
307 
308 	/* wait 30 ms */
309 	msleep_interruptible(30);
310 
311 	/* Wait until the chip is reset */
312 	reset_start_time = jiffies;
313 	while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
314 		;
315 }
316 #endif
317 
318 /* Open/initialize the board.  This is called (in the current kernel)
319    sometime after booting when the 'ifconfig' program is run.
320 
321    This routine should set everything up anew at each open, even
322    registers that "should" only need to be set once at boot, so that
323    there is non-reboot way to recover if something goes wrong.
324    */
325 static int
326 net_open(struct net_device *dev)
327 {
328 	struct net_local *lp = netdev_priv(dev);
329 	int i;
330 
331 	/* Disable the interrupt for now */
332 	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
333 
334 	/* Grab the interrupt */
335 	if (request_irq(dev->irq, net_interrupt, 0, "cs89x0", dev))
336 		return -EAGAIN;
337 
338 	/* Set up the IRQ - Apparently magic */
339 	if (lp->chip_type == CS8900)
340 		writereg(dev, PP_CS8900_ISAINT, 0);
341 	else
342 		writereg(dev, PP_CS8920_ISAINT, 0);
343 
344 	/* set the Ethernet address */
345 	for (i=0; i < ETH_ALEN/2; i++)
346 		writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
347 
348 	/* Turn on both receive and transmit operations */
349 	writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
350 
351 	/* Receive only error free packets addressed to this card */
352 	lp->rx_mode = 0;
353 	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
354 
355 	lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
356 
357 	writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
358 
359 	writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
360 	       TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
361 
362 	writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
363 		 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
364 
365 	/* now that we've got our act together, enable everything */
366 	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
367 	netif_start_queue(dev);
368 	return 0;
369 }
370 
371 static int
372 net_send_packet(struct sk_buff *skb, struct net_device *dev)
373 {
374 	struct net_local *lp = netdev_priv(dev);
375 	unsigned long flags;
376 
377 	if (net_debug > 3)
378 		printk("%s: sent %d byte packet of type %x\n",
379 		       dev->name, skb->len,
380 		       (skb->data[ETH_ALEN+ETH_ALEN] << 8)
381 		       | skb->data[ETH_ALEN+ETH_ALEN+1]);
382 
383 	/* keep the upload from being interrupted, since we
384 	   ask the chip to start transmitting before the
385 	   whole packet has been completely uploaded. */
386 	local_irq_save(flags);
387 	netif_stop_queue(dev);
388 
389 	/* initiate a transmit sequence */
390 	writereg(dev, PP_TxCMD, lp->send_cmd);
391 	writereg(dev, PP_TxLength, skb->len);
392 
393 	/* Test to see if the chip has allocated memory for the packet */
394 	if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
395 		/* Gasp!  It hasn't.  But that shouldn't happen since
396 		   we're waiting for TxOk, so return 1 and requeue this packet. */
397 		local_irq_restore(flags);
398 		return NETDEV_TX_BUSY;
399 	}
400 
401 	/* Write the contents of the packet */
402 	skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame),
403 				  skb->len+1);
404 
405 	local_irq_restore(flags);
406 	dev_kfree_skb (skb);
407 
408 	return NETDEV_TX_OK;
409 }
410 
411 /* The typical workload of the driver:
412    Handle the network interface interrupts. */
413 static irqreturn_t net_interrupt(int irq, void *dev_id)
414 {
415 	struct net_device *dev = dev_id;
416 	struct net_local *lp;
417 	int ioaddr, status;
418 
419 	if (dev == NULL) {
420 		printk ("net_interrupt(): irq %d for unknown device.\n", irq);
421 		return IRQ_NONE;
422 	}
423 
424 	ioaddr = dev->base_addr;
425 	lp = netdev_priv(dev);
426 
427 	/* we MUST read all the events out of the ISQ, otherwise we'll never
428            get interrupted again.  As a consequence, we can't have any limit
429            on the number of times we loop in the interrupt handler.  The
430            hardware guarantees that eventually we'll run out of events.  Of
431            course, if you're on a slow machine, and packets are arriving
432            faster than you can read them off, you're screwed.  Hasta la
433            vista, baby!  */
434 	while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
435 		if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
436 		switch(status & ISQ_EVENT_MASK) {
437 		case ISQ_RECEIVER_EVENT:
438 			/* Got a packet(s). */
439 			net_rx(dev);
440 			break;
441 		case ISQ_TRANSMITTER_EVENT:
442 			dev->stats.tx_packets++;
443 			netif_wake_queue(dev);
444 			if ((status & TX_OK) == 0)
445 				dev->stats.tx_errors++;
446 			if (status & TX_LOST_CRS)
447 				dev->stats.tx_carrier_errors++;
448 			if (status & TX_SQE_ERROR)
449 				dev->stats.tx_heartbeat_errors++;
450 			if (status & TX_LATE_COL)
451 				dev->stats.tx_window_errors++;
452 			if (status & TX_16_COL)
453 				dev->stats.tx_aborted_errors++;
454 			break;
455 		case ISQ_BUFFER_EVENT:
456 			if (status & READY_FOR_TX) {
457 				/* we tried to transmit a packet earlier,
458                                    but inexplicably ran out of buffers.
459                                    That shouldn't happen since we only ever
460                                    load one packet.  Shrug.  Do the right
461                                    thing anyway. */
462 				netif_wake_queue(dev);
463 			}
464 			if (status & TX_UNDERRUN) {
465 				if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
466                                 lp->send_underrun++;
467                                 if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
468                                 else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
469                         }
470 			break;
471 		case ISQ_RX_MISS_EVENT:
472 			dev->stats.rx_missed_errors += (status >> 6);
473 			break;
474 		case ISQ_TX_COL_EVENT:
475 			dev->stats.collisions += (status >> 6);
476 			break;
477 		}
478 	}
479 	return IRQ_HANDLED;
480 }
481 
482 /* We have a good packet(s), get it/them out of the buffers. */
483 static void
484 net_rx(struct net_device *dev)
485 {
486 	struct sk_buff *skb;
487 	int status, length;
488 
489 	status = readreg(dev, PP_RxStatus);
490 	if ((status & RX_OK) == 0) {
491 		dev->stats.rx_errors++;
492 		if (status & RX_RUNT)
493 				dev->stats.rx_length_errors++;
494 		if (status & RX_EXTRA_DATA)
495 				dev->stats.rx_length_errors++;
496 		if ((status & RX_CRC_ERROR) &&
497 		    !(status & (RX_EXTRA_DATA|RX_RUNT)))
498 			/* per str 172 */
499 			dev->stats.rx_crc_errors++;
500 		if (status & RX_DRIBBLE)
501 				dev->stats.rx_frame_errors++;
502 		return;
503 	}
504 
505 	length = readreg(dev, PP_RxLength);
506 	/* Malloc up new buffer. */
507 	skb = alloc_skb(length, GFP_ATOMIC);
508 	if (skb == NULL) {
509 		printk("%s: Memory squeeze, dropping packet.\n", dev->name);
510 		dev->stats.rx_dropped++;
511 		return;
512 	}
513 	skb_put(skb, length);
514 
515 	skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
516 				length);
517 
518 	if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
519                                  dev->name, length,
520                                  (skb->data[ETH_ALEN+ETH_ALEN] << 8)
521 				 | skb->data[ETH_ALEN+ETH_ALEN+1]);
522 
523         skb->protocol=eth_type_trans(skb,dev);
524 	netif_rx(skb);
525 	dev->stats.rx_packets++;
526 	dev->stats.rx_bytes += length;
527 }
528 
529 /* The inverse routine to net_open(). */
530 static int
531 net_close(struct net_device *dev)
532 {
533 
534 	writereg(dev, PP_RxCFG, 0);
535 	writereg(dev, PP_TxCFG, 0);
536 	writereg(dev, PP_BufCFG, 0);
537 	writereg(dev, PP_BusCTL, 0);
538 
539 	netif_stop_queue(dev);
540 
541 	free_irq(dev->irq, dev);
542 
543 	/* Update the statistics here. */
544 
545 	return 0;
546 
547 }
548 
549 /* Get the current statistics.	This may be called with the card open or
550    closed. */
551 static struct net_device_stats *
552 net_get_stats(struct net_device *dev)
553 {
554 	unsigned long flags;
555 
556 	local_irq_save(flags);
557 	/* Update the statistics from the device registers. */
558 	dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
559 	dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
560 	local_irq_restore(flags);
561 
562 	return &dev->stats;
563 }
564 
565 static void set_multicast_list(struct net_device *dev)
566 {
567 	struct net_local *lp = netdev_priv(dev);
568 
569 	if(dev->flags&IFF_PROMISC)
570 	{
571 		lp->rx_mode = RX_ALL_ACCEPT;
572 	} else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
573 		/* The multicast-accept list is initialized to accept-all, and we
574 		   rely on higher-level filtering for now. */
575 		lp->rx_mode = RX_MULTCAST_ACCEPT;
576 	}
577 	else
578 		lp->rx_mode = 0;
579 
580 	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
581 
582 	/* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
583 	writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
584 	     (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
585 }
586 
587 
588 static int set_mac_address(struct net_device *dev, void *addr)
589 {
590 	struct sockaddr *saddr = addr;
591 	int i;
592 
593 	if (!is_valid_ether_addr(saddr->sa_data))
594 		return -EADDRNOTAVAIL;
595 
596 	memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
597 	printk("%s: Setting MAC address to %pM\n", dev->name, dev->dev_addr);
598 
599 	/* set the Ethernet address */
600 	for (i=0; i < ETH_ALEN/2; i++)
601 		writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
602 
603 	return 0;
604 }
605 
606 #ifdef MODULE
607 
608 static struct net_device *dev_cs89x0;
609 static int debug;
610 
611 module_param(debug, int, 0);
612 MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
613 MODULE_LICENSE("GPL");
614 
615 int __init
616 init_module(void)
617 {
618 	net_debug = debug;
619         dev_cs89x0 = mac89x0_probe(-1);
620 	if (IS_ERR(dev_cs89x0)) {
621                 printk(KERN_WARNING "mac89x0.c: No card found\n");
622 		return PTR_ERR(dev_cs89x0);
623 	}
624 	return 0;
625 }
626 
627 void
628 cleanup_module(void)
629 {
630 	unregister_netdev(dev_cs89x0);
631 	nubus_writew(0, dev_cs89x0->base_addr + ADD_PORT);
632 	free_netdev(dev_cs89x0);
633 }
634 #endif /* MODULE */
635