Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  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
 59static 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/system.h>
103#include <asm/io.h>
104#include <asm/hwtest.h>
105#include <asm/macints.h>
106
107#include "cs89x0.h"
108
109static unsigned int net_debug = NET_DEBUG;
110
111/* Information that need to be kept for each board. */
112struct net_local {
113	int chip_type;		/* one of: CS8900, CS8920, CS8920M */
114	char chip_revision;	/* revision letter of the chip ('A'...) */
115	int send_cmd;		/* the propercommand used to send a packet. */
116	int rx_mode;
117	int curr_rx_cfg;
118        int send_underrun;      /* keep track of how many underruns in a row we get */
119	struct sk_buff *skb;
120};
121
122/* Index to functions, as function prototypes. */
123
124#if 0
125extern void reset_chip(struct net_device *dev);
126#endif
127static int net_open(struct net_device *dev);
128static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
129static irqreturn_t net_interrupt(int irq, void *dev_id);
130static void set_multicast_list(struct net_device *dev);
131static void net_rx(struct net_device *dev);
132static int net_close(struct net_device *dev);
133static struct net_device_stats *net_get_stats(struct net_device *dev);
134static int set_mac_address(struct net_device *dev, void *addr);
135
136
137/* Example routines you must write ;->. */
138#define tx_done(dev) 1
139
140/* For reading/writing registers ISA-style */
141static inline int
142readreg_io(struct net_device *dev, int portno)
143{
144	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
145	return swab16(nubus_readw(dev->base_addr + DATA_PORT));
146}
147
148static inline void
149writereg_io(struct net_device *dev, int portno, int value)
150{
151	nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
152	nubus_writew(swab16(value), dev->base_addr + DATA_PORT);
153}
154
155/* These are for reading/writing registers in shared memory */
156static inline int
157readreg(struct net_device *dev, int portno)
158{
159	return swab16(nubus_readw(dev->mem_start + portno));
160}
161
162static inline void
163writereg(struct net_device *dev, int portno, int value)
164{
165	nubus_writew(swab16(value), dev->mem_start + portno);
166}
167
168static const struct net_device_ops mac89x0_netdev_ops = {
169	.ndo_open		= net_open,
170	.ndo_stop		= net_close,
171	.ndo_start_xmit		= net_send_packet,
172	.ndo_get_stats		= net_get_stats,
173	.ndo_set_multicast_list	= set_multicast_list,
174	.ndo_set_mac_address	= set_mac_address,
175	.ndo_validate_addr	= eth_validate_addr,
176	.ndo_change_mtu		= eth_change_mtu,
177};
178
179/* Probe for the CS8900 card in slot E.  We won't bother looking
180   anywhere else until we have a really good reason to do so. */
181struct net_device * __init mac89x0_probe(int unit)
182{
183	struct net_device *dev;
184	static int once_is_enough;
185	struct net_local *lp;
186	static unsigned version_printed;
187	int i, slot;
188	unsigned rev_type = 0;
189	unsigned long ioaddr;
190	unsigned short sig;
191	int err = -ENODEV;
192
193	if (!MACH_IS_MAC)
194		return ERR_PTR(-ENODEV);
195
196	dev = alloc_etherdev(sizeof(struct net_local));
197	if (!dev)
198		return ERR_PTR(-ENOMEM);
199
200	if (unit >= 0) {
201		sprintf(dev->name, "eth%d", unit);
202		netdev_boot_setup_check(dev);
203	}
204
205	if (once_is_enough)
206		goto out;
207	once_is_enough = 1;
208
209	/* We might have to parameterize this later */
210	slot = 0xE;
211	/* Get out now if there's a real NuBus card in slot E */
212	if (nubus_find_slot(slot, NULL) != NULL)
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		unsigned long flags;
221		int card_present;
222
223		local_irq_save(flags);
224		card_present = (hwreg_present((void*) ioaddr+4) &&
225				hwreg_present((void*) ioaddr + DATA_PORT));
226		local_irq_restore(flags);
227
228		if (!card_present)
229			goto out;
230	}
231
232	nubus_writew(0, ioaddr + ADD_PORT);
233	sig = nubus_readw(ioaddr + DATA_PORT);
234	if (sig != swab16(CHIP_EISA_ID_SIG))
235		goto out;
236
237	/* Initialize the net_device structure. */
238	lp = netdev_priv(dev);
239
240	/* Fill in the 'dev' fields. */
241	dev->base_addr = ioaddr;
242	dev->mem_start = (unsigned long)
243		nubus_slot_addr(slot) | (((slot&0xf) << 20) + MMIOBASE);
244	dev->mem_end = dev->mem_start + 0x1000;
245
246	/* Turn on shared memory */
247	writereg_io(dev, PP_BusCTL, MEMORY_ON);
248
249	/* get the chip type */
250	rev_type = readreg(dev, PRODUCT_ID_ADD);
251	lp->chip_type = rev_type &~ REVISON_BITS;
252	lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
253
254	/* Check the chip type and revision in order to set the correct send command
255	CS8920 revision C and CS8900 revision F can use the faster send. */
256	lp->send_cmd = TX_AFTER_381;
257	if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
258		lp->send_cmd = TX_NOW;
259	if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
260		lp->send_cmd = TX_NOW;
261
262	if (net_debug && version_printed++ == 0)
263		printk(version);
264
265	printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#8lx",
266	       dev->name,
267	       lp->chip_type==CS8900?'0':'2',
268	       lp->chip_type==CS8920M?"M":"",
269	       lp->chip_revision,
270	       dev->base_addr);
271
272	/* Try to read the MAC address */
273	if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
274		printk("\nmac89x0: No EEPROM, giving up now.\n");
275		goto out1;
276        } else {
277                for (i = 0; i < ETH_ALEN; i += 2) {
278			/* Big-endian (why??!) */
279			unsigned short s = readreg(dev, PP_IA + i);
280                        dev->dev_addr[i] = s >> 8;
281                        dev->dev_addr[i+1] = s & 0xff;
282                }
283        }
284
285	dev->irq = SLOT2IRQ(slot);
286
287	/* print the IRQ and ethernet address. */
288
289	printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr);
290
291	dev->netdev_ops		= &mac89x0_netdev_ops;
292
293	err = register_netdev(dev);
294	if (err)
295		goto out1;
296	return NULL;
297out1:
298	nubus_writew(0, dev->base_addr + ADD_PORT);
299out:
300	free_netdev(dev);
301	return ERR_PTR(err);
302}
303
304#if 0
305/* This is useful for something, but I don't know what yet. */
306void __init reset_chip(struct net_device *dev)
307{
308	int reset_start_time;
309
310	writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
311
312	/* wait 30 ms */
313	msleep_interruptible(30);
314
315	/* Wait until the chip is reset */
316	reset_start_time = jiffies;
317	while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
318		;
319}
320#endif
321
322/* Open/initialize the board.  This is called (in the current kernel)
323   sometime after booting when the 'ifconfig' program is run.
324
325   This routine should set everything up anew at each open, even
326   registers that "should" only need to be set once at boot, so that
327   there is non-reboot way to recover if something goes wrong.
328   */
329static int
330net_open(struct net_device *dev)
331{
332	struct net_local *lp = netdev_priv(dev);
333	int i;
334
335	/* Disable the interrupt for now */
336	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
337
338	/* Grab the interrupt */
339	if (request_irq(dev->irq, net_interrupt, 0, "cs89x0", dev))
340		return -EAGAIN;
341
342	/* Set up the IRQ - Apparently magic */
343	if (lp->chip_type == CS8900)
344		writereg(dev, PP_CS8900_ISAINT, 0);
345	else
346		writereg(dev, PP_CS8920_ISAINT, 0);
347
348	/* set the Ethernet address */
349	for (i=0; i < ETH_ALEN/2; i++)
350		writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
351
352	/* Turn on both receive and transmit operations */
353	writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
354
355	/* Receive only error free packets addressed to this card */
356	lp->rx_mode = 0;
357	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
358
359	lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
360
361	writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
362
363	writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
364	       TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
365
366	writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
367		 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
368
369	/* now that we've got our act together, enable everything */
370	writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
371	netif_start_queue(dev);
372	return 0;
373}
374
375static int
376net_send_packet(struct sk_buff *skb, struct net_device *dev)
377{
378	struct net_local *lp = netdev_priv(dev);
379	unsigned long flags;
380
381	if (net_debug > 3)
382		printk("%s: sent %d byte packet of type %x\n",
383		       dev->name, skb->len,
384		       (skb->data[ETH_ALEN+ETH_ALEN] << 8)
385		       | skb->data[ETH_ALEN+ETH_ALEN+1]);
386
387	/* keep the upload from being interrupted, since we
388	   ask the chip to start transmitting before the
389	   whole packet has been completely uploaded. */
390	local_irq_save(flags);
391	netif_stop_queue(dev);
392
393	/* initiate a transmit sequence */
394	writereg(dev, PP_TxCMD, lp->send_cmd);
395	writereg(dev, PP_TxLength, skb->len);
396
397	/* Test to see if the chip has allocated memory for the packet */
398	if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
399		/* Gasp!  It hasn't.  But that shouldn't happen since
400		   we're waiting for TxOk, so return 1 and requeue this packet. */
401		local_irq_restore(flags);
402		return NETDEV_TX_BUSY;
403	}
404
405	/* Write the contents of the packet */
406	skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame),
407				  skb->len+1);
408
409	local_irq_restore(flags);
410	dev_kfree_skb (skb);
411
412	return NETDEV_TX_OK;
413}
414
415/* The typical workload of the driver:
416   Handle the network interface interrupts. */
417static irqreturn_t net_interrupt(int irq, void *dev_id)
418{
419	struct net_device *dev = dev_id;
420	struct net_local *lp;
421	int ioaddr, status;
422
423	if (dev == NULL) {
424		printk ("net_interrupt(): irq %d for unknown device.\n", irq);
425		return IRQ_NONE;
426	}
427
428	ioaddr = dev->base_addr;
429	lp = netdev_priv(dev);
430
431	/* we MUST read all the events out of the ISQ, otherwise we'll never
432           get interrupted again.  As a consequence, we can't have any limit
433           on the number of times we loop in the interrupt handler.  The
434           hardware guarantees that eventually we'll run out of events.  Of
435           course, if you're on a slow machine, and packets are arriving
436           faster than you can read them off, you're screwed.  Hasta la
437           vista, baby!  */
438	while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
439		if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
440		switch(status & ISQ_EVENT_MASK) {
441		case ISQ_RECEIVER_EVENT:
442			/* Got a packet(s). */
443			net_rx(dev);
444			break;
445		case ISQ_TRANSMITTER_EVENT:
446			dev->stats.tx_packets++;
447			netif_wake_queue(dev);
448			if ((status & TX_OK) == 0)
449				dev->stats.tx_errors++;
450			if (status & TX_LOST_CRS)
451				dev->stats.tx_carrier_errors++;
452			if (status & TX_SQE_ERROR)
453				dev->stats.tx_heartbeat_errors++;
454			if (status & TX_LATE_COL)
455				dev->stats.tx_window_errors++;
456			if (status & TX_16_COL)
457				dev->stats.tx_aborted_errors++;
458			break;
459		case ISQ_BUFFER_EVENT:
460			if (status & READY_FOR_TX) {
461				/* we tried to transmit a packet earlier,
462                                   but inexplicably ran out of buffers.
463                                   That shouldn't happen since we only ever
464                                   load one packet.  Shrug.  Do the right
465                                   thing anyway. */
466				netif_wake_queue(dev);
467			}
468			if (status & TX_UNDERRUN) {
469				if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
470                                lp->send_underrun++;
471                                if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
472                                else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
473                        }
474			break;
475		case ISQ_RX_MISS_EVENT:
476			dev->stats.rx_missed_errors += (status >> 6);
477			break;
478		case ISQ_TX_COL_EVENT:
479			dev->stats.collisions += (status >> 6);
480			break;
481		}
482	}
483	return IRQ_HANDLED;
484}
485
486/* We have a good packet(s), get it/them out of the buffers. */
487static void
488net_rx(struct net_device *dev)
489{
490	struct sk_buff *skb;
491	int status, length;
492
493	status = readreg(dev, PP_RxStatus);
494	if ((status & RX_OK) == 0) {
495		dev->stats.rx_errors++;
496		if (status & RX_RUNT)
497				dev->stats.rx_length_errors++;
498		if (status & RX_EXTRA_DATA)
499				dev->stats.rx_length_errors++;
500		if ((status & RX_CRC_ERROR) &&
501		    !(status & (RX_EXTRA_DATA|RX_RUNT)))
502			/* per str 172 */
503			dev->stats.rx_crc_errors++;
504		if (status & RX_DRIBBLE)
505				dev->stats.rx_frame_errors++;
506		return;
507	}
508
509	length = readreg(dev, PP_RxLength);
510	/* Malloc up new buffer. */
511	skb = alloc_skb(length, GFP_ATOMIC);
512	if (skb == NULL) {
513		printk("%s: Memory squeeze, dropping packet.\n", dev->name);
514		dev->stats.rx_dropped++;
515		return;
516	}
517	skb_put(skb, length);
518
519	skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
520				length);
521
522	if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
523                                 dev->name, length,
524                                 (skb->data[ETH_ALEN+ETH_ALEN] << 8)
525				 | skb->data[ETH_ALEN+ETH_ALEN+1]);
526
527        skb->protocol=eth_type_trans(skb,dev);
528	netif_rx(skb);
529	dev->stats.rx_packets++;
530	dev->stats.rx_bytes += length;
531}
532
533/* The inverse routine to net_open(). */
534static int
535net_close(struct net_device *dev)
536{
537
538	writereg(dev, PP_RxCFG, 0);
539	writereg(dev, PP_TxCFG, 0);
540	writereg(dev, PP_BufCFG, 0);
541	writereg(dev, PP_BusCTL, 0);
542
543	netif_stop_queue(dev);
544
545	free_irq(dev->irq, dev);
546
547	/* Update the statistics here. */
548
549	return 0;
550
551}
552
553/* Get the current statistics.	This may be called with the card open or
554   closed. */
555static struct net_device_stats *
556net_get_stats(struct net_device *dev)
557{
558	unsigned long flags;
559
560	local_irq_save(flags);
561	/* Update the statistics from the device registers. */
562	dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
563	dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
564	local_irq_restore(flags);
565
566	return &dev->stats;
567}
568
569static void set_multicast_list(struct net_device *dev)
570{
571	struct net_local *lp = netdev_priv(dev);
572
573	if(dev->flags&IFF_PROMISC)
574	{
575		lp->rx_mode = RX_ALL_ACCEPT;
576	} else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
577		/* The multicast-accept list is initialized to accept-all, and we
578		   rely on higher-level filtering for now. */
579		lp->rx_mode = RX_MULTCAST_ACCEPT;
580	}
581	else
582		lp->rx_mode = 0;
583
584	writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
585
586	/* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
587	writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
588	     (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
589}
590
591
592static int set_mac_address(struct net_device *dev, void *addr)
593{
594	int i;
595	printk("%s: Setting MAC address to ", dev->name);
596	for (i = 0; i < 6; i++)
597		printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
598	printk(".\n");
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
608static struct net_device *dev_cs89x0;
609static int debug;
610
611module_param(debug, int, 0);
612MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
613MODULE_LICENSE("GPL");
614
615int __init
616init_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
627void
628cleanup_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 */