blob: 6e5b2c79340ff8bab79e428b7c6680bfe1cf88fc [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* cs89x0.c: A Crystal Semiconductor (Now Cirrus Logic) CS89[02]0
Joe Perches204a38a2012-05-18 12:56:27 +00002 * driver for linux.
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, 521 Pleasant Valley Rd., Potsdam, NY 13676
11 *
12 * Other contributors:
13 * Mike Cruse : mcruse@cti-ltd.com
14 * Russ Nelson
15 * Melody Lee : ethernet@crystal.cirrus.com
16 * Alan Cox
17 * Andrew Morton
18 * Oskar Schirmer : oskar@scara.com
19 * Deepak Saxena : dsaxena@plexity.net
20 * Dmitry Pervushin : dpervushin@ru.mvista.com
21 * Deepak Saxena : dsaxena@plexity.net
22 * Domenico Andreoli : cavokz@gmail.com
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 */
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025
26/*
27 * Set this to zero to disable DMA code
28 *
29 * Note that even if DMA is turned off we still support the 'dma' and 'use_dma'
30 * module options so we don't break any startup scripts.
31 */
Lennert Buytenhek91e1c462006-01-11 12:17:34 -080032#ifndef CONFIG_ISA_DMA_API
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#define ALLOW_DMA 0
34#else
35#define ALLOW_DMA 1
36#endif
37
38/*
39 * Set this to zero to remove all the debug statements via
40 * dead code elimination
41 */
42#define DEBUGGING 1
43
Joe Perches204a38a2012-05-18 12:56:27 +000044/* Sources:
45 * Crynwr packet driver epktisa.
46 * Crystal Semiconductor data sheets.
47 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Joe Perchesdd92b9a2012-05-18 12:56:28 +000049#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
50
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010051#include <linux/module.h>
52#include <linux/printk.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#include <linux/errno.h>
54#include <linux/netdevice.h>
55#include <linux/etherdevice.h>
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010056#include <linux/platform_device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070057#include <linux/kernel.h>
58#include <linux/types.h>
59#include <linux/fcntl.h>
60#include <linux/interrupt.h>
61#include <linux/ioport.h>
62#include <linux/in.h>
63#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070064#include <linux/spinlock.h>
65#include <linux/string.h>
66#include <linux/init.h>
67#include <linux/bitops.h>
68#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090069#include <linux/gfp.h>
Joe Perchesca034bc2012-05-18 12:56:29 +000070#include <linux/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070071
Al Viro7625d482005-09-26 05:25:59 +010072#include <asm/irq.h>
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010073#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#if ALLOW_DMA
75#include <asm/dma.h>
76#endif
77
78#include "cs89x0.h"
79
80static char version[] __initdata =
Joe Perchesca034bc2012-05-18 12:56:29 +000081 "v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
83#define DRV_NAME "cs89x0"
84
85/* First, a few definitions that the brave might change.
Joe Perches204a38a2012-05-18 12:56:27 +000086 * A zero-terminated list of I/O addresses to be probed. Some special flags..
87 * Addr & 1 = Read back the address port, look for signature and reset
88 * the page window before probing
89 * Addr & 3 = Reset the page window and probe
90 * The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,
91 * but it is possible that a Cirrus board could be plugged into the ISA
92 * slots.
93 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -040094/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
Joe Perches204a38a2012-05-18 12:56:27 +000095 * them to system IRQ numbers. This mapping is card specific and is set to
96 * the configuration of the Cirrus Eval board for this chip.
97 */
Christoph Eggeref3cf9f2010-07-14 13:40:36 -070098#if defined(CONFIG_MACH_IXDP2351)
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010099#define CS89x0_NONISA_IRQ
Joe Perchesca034bc2012-05-18 12:56:29 +0000100static unsigned int netcard_portlist[] __used __initdata = {
101 IXDP2351_VIRT_CS8900_BASE, 0
102};
103static unsigned int cs8900_irq_map[] = {
104 IRQ_IXDP2351_CS8900, 0, 0, 0
105};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106#elif defined(CONFIG_ARCH_IXDP2X01)
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100107#define CS89x0_NONISA_IRQ
Joe Perchesca034bc2012-05-18 12:56:29 +0000108static unsigned int netcard_portlist[] __used __initdata = {
109 IXDP2X01_CS8900_VIRT_BASE, 0
110};
111static unsigned int cs8900_irq_map[] = {
112 IRQ_IXDP2X01_CS8900, 0, 0, 0
113};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114#else
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100115#ifndef CONFIG_CS89x0_PLATFORM
Joe Perchesca034bc2012-05-18 12:56:29 +0000116static unsigned int netcard_portlist[] __used __initdata = {
117 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240,
118 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0
119};
120static unsigned int cs8900_irq_map[] = {
121 10, 11, 12, 5
122};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123#endif
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100124#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
126#if DEBUGGING
127static unsigned int net_debug = DEBUGGING;
128#else
129#define net_debug 0 /* gcc will remove all the debug code for us */
130#endif
131
132/* The number of low I/O ports used by the ethercard. */
133#define NETCARD_IO_EXTENT 16
134
135/* we allow the user to override various values normally set in the EEPROM */
136#define FORCE_RJ45 0x0001 /* pick one of these three */
137#define FORCE_AUI 0x0002
138#define FORCE_BNC 0x0004
139
140#define FORCE_AUTO 0x0010 /* pick one of these three */
141#define FORCE_HALF 0x0020
142#define FORCE_FULL 0x0030
143
144/* Information that need to be kept for each board. */
145struct net_local {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 int chip_type; /* one of: CS8900, CS8920, CS8920M */
147 char chip_revision; /* revision letter of the chip ('A'...) */
148 int send_cmd; /* the proper send command: TX_NOW, TX_AFTER_381, or TX_AFTER_ALL */
149 int auto_neg_cnf; /* auto-negotiation word from EEPROM */
150 int adapter_cnf; /* adapter configuration from EEPROM */
151 int isa_config; /* ISA configuration from EEPROM */
152 int irq_map; /* IRQ map from EEPROM */
153 int rx_mode; /* what mode are we in? 0, RX_MULTCAST_ACCEPT, or RX_ALL_ACCEPT */
154 int curr_rx_cfg; /* a copy of PP_RxCFG */
155 int linectl; /* either 0 or LOW_RX_SQUELCH, depending on configuration. */
156 int send_underrun; /* keep track of how many underruns in a row we get */
157 int force; /* force various values; see FORCE* above. */
158 spinlock_t lock;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000159 void __iomem *virt_addr;/* CS89x0 virtual address. */
160 unsigned long size; /* Length of CS89x0 memory region. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161#if ALLOW_DMA
162 int use_dma; /* Flag: we're using dma */
163 int dma; /* DMA channel */
164 int dmasize; /* 16 or 64 */
165 unsigned char *dma_buff; /* points to the beginning of the buffer */
166 unsigned char *end_dma_buff; /* points to the end of the buffer */
167 unsigned char *rx_dma_ptr; /* points to the next packet */
168#endif
169};
170
171/* Index to functions, as function prototypes. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172static int net_open(struct net_device *dev);
Stephen Hemminger613573252009-08-31 19:50:58 +0000173static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
David Howells7d12e782006-10-05 14:55:46 +0100174static irqreturn_t net_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175static void set_multicast_list(struct net_device *dev);
176static void net_timeout(struct net_device *dev);
177static void net_rx(struct net_device *dev);
178static int net_close(struct net_device *dev);
179static struct net_device_stats *net_get_stats(struct net_device *dev);
180static void reset_chip(struct net_device *dev);
181static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer);
182static int get_eeprom_cksum(int off, int len, int *buffer);
183static int set_mac_address(struct net_device *dev, void *addr);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000184static void count_rx_errors(int status, struct net_device *dev);
Deepak Saxena6f519162005-09-09 13:02:07 -0700185#ifdef CONFIG_NET_POLL_CONTROLLER
186static void net_poll_controller(struct net_device *dev);
187#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188#if ALLOW_DMA
189static void get_dma_channel(struct net_device *dev);
190static void release_dma_buff(struct net_local *lp);
191#endif
192
193/* Example routines you must write ;->. */
194#define tx_done(dev) 1
195
196/*
197 * Permit 'cs89x0_dma=N' in the kernel boot environment
198 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000199#if !defined(MODULE)
200#if ALLOW_DMA
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201static int g_cs89x0_dma;
202
203static int __init dma_fn(char *str)
204{
Joe Perches204a38a2012-05-18 12:56:27 +0000205 g_cs89x0_dma = simple_strtol(str, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 return 1;
207}
208
209__setup("cs89x0_dma=", dma_fn);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000210#endif /* ALLOW_DMA */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212static int g_cs89x0_media__force;
213
214static int __init media_fn(char *str)
215{
Joe Perchesca034bc2012-05-18 12:56:29 +0000216 if (!strcmp(str, "rj45"))
217 g_cs89x0_media__force = FORCE_RJ45;
218 else if (!strcmp(str, "aui"))
219 g_cs89x0_media__force = FORCE_AUI;
220 else if (!strcmp(str, "bnc"))
221 g_cs89x0_media__force = FORCE_BNC;
222
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 return 1;
224}
225
226__setup("cs89x0_media=", media_fn);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100227#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
Deepak Saxena9c878962006-01-14 13:21:18 -0800229#if defined(CONFIG_MACH_IXDP2351)
230static u16
231readword(unsigned long base_addr, int portno)
232{
233 return __raw_readw(base_addr + (portno << 1));
234}
235
236static void
237writeword(unsigned long base_addr, int portno, u16 value)
238{
239 __raw_writew(value, base_addr + (portno << 1));
240}
241#elif defined(CONFIG_ARCH_IXDP2X01)
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800242static u16
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800243readword(unsigned long base_addr, int portno)
244{
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800245 return __raw_readl(base_addr + (portno << 1));
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800246}
247
248static void
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800249writeword(unsigned long base_addr, int portno, u16 value)
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800250{
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800251 __raw_writel(value, base_addr + (portno << 1));
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800252}
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800253#endif
Lennert Buytenhek0d5affc2006-01-08 01:01:09 -0800254
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000255static void readwords(struct net_local *lp, int portno, void *buf, int length)
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800256{
257 u8 *buf8 = (u8 *)buf;
258
259 do {
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800260 u16 tmp16;
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800261
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000262 tmp16 = ioread16(lp->virt_addr + portno);
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800263 *buf8++ = (u8)tmp16;
264 *buf8++ = (u8)(tmp16 >> 8);
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800265 } while (--length);
266}
267
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000268static void writewords(struct net_local *lp, int portno, void *buf, int length)
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800269{
270 u8 *buf8 = (u8 *)buf;
271
272 do {
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800273 u16 tmp16;
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800274
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800275 tmp16 = *buf8++;
276 tmp16 |= (*buf8++) << 8;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000277 iowrite16(tmp16, lp->virt_addr + portno);
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800278 } while (--length);
279}
280
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800281static u16
282readreg(struct net_device *dev, u16 regno)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000284 struct net_local *lp = netdev_priv(dev);
285
286 iowrite16(regno, lp->virt_addr + ADD_PORT);
287 return ioread16(lp->virt_addr + DATA_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288}
289
290static void
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800291writereg(struct net_device *dev, u16 regno, u16 value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000293 struct net_local *lp = netdev_priv(dev);
294
295 iowrite16(regno, lp->virt_addr + ADD_PORT);
296 iowrite16(value, lp->virt_addr + DATA_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297}
298
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299static int __init
300wait_eeprom_ready(struct net_device *dev)
301{
302 int timeout = jiffies;
Joe Perches204a38a2012-05-18 12:56:27 +0000303 /* check to see if the EEPROM is ready,
304 * a timeout is used just in case EEPROM is ready when
305 * SI_BUSY in the PP_SelfST is clear
306 */
307 while (readreg(dev, PP_SelfST) & SI_BUSY)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 if (jiffies - timeout >= 40)
309 return -1;
310 return 0;
311}
312
313static int __init
314get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
315{
316 int i;
317
Joe Perchesca034bc2012-05-18 12:56:29 +0000318 if (net_debug > 3)
319 printk("EEPROM data from %x for %x:\n", off, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 for (i = 0; i < len; i++) {
Joe Perchesca034bc2012-05-18 12:56:29 +0000321 if (wait_eeprom_ready(dev) < 0)
322 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 /* Now send the EEPROM read command and EEPROM location to read */
324 writereg(dev, PP_EECMD, (off + i) | EEPROM_READ_CMD);
Joe Perchesca034bc2012-05-18 12:56:29 +0000325 if (wait_eeprom_ready(dev) < 0)
326 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 buffer[i] = readreg(dev, PP_EEData);
Joe Perchesca034bc2012-05-18 12:56:29 +0000328 if (net_debug > 3)
329 printk("%04x ", buffer[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 }
Joe Perchesca034bc2012-05-18 12:56:29 +0000331 if (net_debug > 3)
332 printk("\n");
Joe Perches204a38a2012-05-18 12:56:27 +0000333 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334}
335
336static int __init
337get_eeprom_cksum(int off, int len, int *buffer)
338{
339 int i, cksum;
340
341 cksum = 0;
342 for (i = 0; i < len; i++)
343 cksum += buffer[i];
344 cksum &= 0xffff;
345 if (cksum == 0)
346 return 0;
347 return -1;
348}
349
Deepak Saxena6f519162005-09-09 13:02:07 -0700350#ifdef CONFIG_NET_POLL_CONTROLLER
351/*
352 * Polling receive - used by netconsole and other diagnostic tools
353 * to allow network i/o with interrupts disabled.
354 */
355static void net_poll_controller(struct net_device *dev)
356{
357 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100358 net_interrupt(dev->irq, dev);
Deepak Saxena6f519162005-09-09 13:02:07 -0700359 enable_irq(dev->irq);
360}
361#endif
362
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000363static const struct net_device_ops net_ops = {
364 .ndo_open = net_open,
365 .ndo_stop = net_close,
366 .ndo_tx_timeout = net_timeout,
Joe Perches204a38a2012-05-18 12:56:27 +0000367 .ndo_start_xmit = net_send_packet,
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000368 .ndo_get_stats = net_get_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000369 .ndo_set_rx_mode = set_multicast_list,
Joe Perches204a38a2012-05-18 12:56:27 +0000370 .ndo_set_mac_address = set_mac_address,
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000371#ifdef CONFIG_NET_POLL_CONTROLLER
372 .ndo_poll_controller = net_poll_controller,
373#endif
374 .ndo_change_mtu = eth_change_mtu,
375 .ndo_validate_addr = eth_validate_addr,
376};
377
Joe Perches204a38a2012-05-18 12:56:27 +0000378/* This is the real probe routine.
379 * Linux has a history of friendly device probes on the ISA bus.
380 * A good device probes avoids doing writes, and
381 * verifies that the correct device exists and functions.
382 * Return 0 on success.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384static int __init
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000385cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386{
387 struct net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 int i;
Denis Vlasenko01bdc032005-07-31 22:34:50 -0700389 int tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 unsigned rev_type = 0;
391 int eeprom_buff[CHKSUM_LEN];
392 int retval;
393
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 /* Initialize the device structure. */
395 if (!modular) {
396 memset(lp, 0, sizeof(*lp));
397 spin_lock_init(&lp->lock);
398#ifndef MODULE
399#if ALLOW_DMA
400 if (g_cs89x0_dma) {
401 lp->use_dma = 1;
402 lp->dma = g_cs89x0_dma;
403 lp->dmasize = 16; /* Could make this an option... */
404 }
405#endif
406 lp->force = g_cs89x0_media__force;
407#endif
Joe Perches204a38a2012-05-18 12:56:27 +0000408 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000410 pr_debug("PP_addr at %p[%x]: 0x%x\n",
411 ioaddr, ADD_PORT, ioread16(ioaddr + ADD_PORT));
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000412 iowrite16(PP_ChipID, ioaddr + ADD_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000414 tmp = ioread16(ioaddr + DATA_PORT);
Denis Vlasenko01bdc032005-07-31 22:34:50 -0700415 if (tmp != CHIP_EISA_ID_SIG) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000416 pr_debug("%s: incorrect signature at %p[%x]: 0x%x!="
417 CHIP_EISA_ID_SIG_STR "\n",
418 dev->name, ioaddr, DATA_PORT, tmp);
Joe Perches204a38a2012-05-18 12:56:27 +0000419 retval = -ENODEV;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000420 goto out1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 }
422
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000423 lp->virt_addr = ioaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
425 /* get the chip type */
426 rev_type = readreg(dev, PRODUCT_ID_ADD);
Joe Perches204a38a2012-05-18 12:56:27 +0000427 lp->chip_type = rev_type & ~REVISON_BITS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
429
430 /* Check the chip type and revision in order to set the correct send command
Joe Perches204a38a2012-05-18 12:56:27 +0000431 CS8920 revision C and CS8900 revision F can use the faster send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 lp->send_cmd = TX_AFTER_381;
433 if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
434 lp->send_cmd = TX_NOW;
435 if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
436 lp->send_cmd = TX_NOW;
437
Joe Perchesca034bc2012-05-18 12:56:29 +0000438 if (net_debug)
439 printk_once(version);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000441 pr_info("%s: cs89%c0%s rev %c found at %p ",
442 dev->name,
443 lp->chip_type == CS8900 ? '0' : '2',
444 lp->chip_type == CS8920M ? "M" : "",
445 lp->chip_revision,
446 lp->virt_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447
448 reset_chip(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400449
Joe Perches204a38a2012-05-18 12:56:27 +0000450 /* Here we read the current configuration of the chip.
451 * If there is no Extended EEPROM then the idea is to not disturb
452 * the chip configuration, it should have been correctly setup by
453 * automatic EEPROM read on reset. So, if the chip says it read
454 * the EEPROM the driver will always do *something* instead of
455 * complain that adapter_cnf is 0.
456 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457
Joe Perches204a38a2012-05-18 12:56:27 +0000458 if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
Joe Perchesca034bc2012-05-18 12:56:29 +0000459 (EEPROM_OK | EEPROM_PRESENT)) {
Joe Perches204a38a2012-05-18 12:56:27 +0000460 /* Load the MAC. */
461 for (i = 0; i < ETH_ALEN / 2; i++) {
462 unsigned int Addr;
463 Addr = readreg(dev, PP_IA + i * 2);
464 dev->dev_addr[i * 2] = Addr & 0xFF;
465 dev->dev_addr[i * 2 + 1] = Addr >> 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400467
Joe Perches204a38a2012-05-18 12:56:27 +0000468 /* Load the Adapter Configuration.
469 * Note: Barring any more specific information from some
470 * other source (ie EEPROM+Schematics), we would not know
471 * how to operate a 10Base2 interface on the AUI port.
472 * However, since we do read the status of HCB1 and use
473 * settings that always result in calls to control_dc_dc(dev,0)
474 * a BNC interface should work if the enable pin
475 * (dc/dc converter) is on HCB1.
476 * It will be called AUI however.
477 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400478
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 lp->adapter_cnf = 0;
480 i = readreg(dev, PP_LineCTL);
481 /* Preserve the setting of the HCB1 pin. */
Joe Perches204a38a2012-05-18 12:56:27 +0000482 if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 lp->adapter_cnf |= A_CNF_DC_DC_POLARITY;
484 /* Save the sqelch bit */
485 if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH)
486 lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH;
487 /* Check if the card is in 10Base-t only mode */
488 if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0)
489 lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T;
490 /* Check if the card is in AUI only mode */
491 if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY)
492 lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI;
493 /* Check if the card is in Auto mode. */
494 if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET)
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400495 lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T |
Joe Perches204a38a2012-05-18 12:56:27 +0000496 A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 if (net_debug > 1)
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000499 pr_info("%s: PP_LineCTL=0x%x, adapter_cnf=0x%x\n",
500 dev->name, i, lp->adapter_cnf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501
502 /* IRQ. Other chips already probe, see below. */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400503 if (lp->chip_type == CS8900)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400505
Joe Perches204a38a2012-05-18 12:56:27 +0000506 printk("[Cirrus EEPROM] ");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 }
508
Joe Perches204a38a2012-05-18 12:56:27 +0000509 printk("\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 /* First check to see if an EEPROM is attached. */
Christoph Eggeref3cf9f2010-07-14 13:40:36 -0700512
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000514 pr_warn("No EEPROM, relying on command line....\n");
Joe Perches204a38a2012-05-18 12:56:27 +0000515 else if (get_eeprom_data(dev, START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000516 pr_warn("EEPROM read failed, relying on command line\n");
Joe Perches204a38a2012-05-18 12:56:27 +0000517 } else if (get_eeprom_cksum(START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 /* Check if the chip was able to read its own configuration starting
519 at 0 in the EEPROM*/
520 if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) !=
Joe Perches204a38a2012-05-18 12:56:27 +0000521 (EEPROM_OK | EEPROM_PRESENT))
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000522 pr_warn("Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400523
Joe Perches204a38a2012-05-18 12:56:27 +0000524 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 /* This reads an extended EEPROM that is not documented
Joe Perches204a38a2012-05-18 12:56:27 +0000526 * in the CS8900 datasheet.
527 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400528
Joe Perches204a38a2012-05-18 12:56:27 +0000529 /* get transmission control word but keep the autonegotiation bits */
Joe Perchesca034bc2012-05-18 12:56:29 +0000530 if (!lp->auto_neg_cnf)
531 lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET / 2];
Joe Perches204a38a2012-05-18 12:56:27 +0000532 /* Store adapter configuration */
Joe Perchesca034bc2012-05-18 12:56:29 +0000533 if (!lp->adapter_cnf)
534 lp->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET / 2];
Joe Perches204a38a2012-05-18 12:56:27 +0000535 /* Store ISA configuration */
Joe Perchesca034bc2012-05-18 12:56:29 +0000536 lp->isa_config = eeprom_buff[ISA_CNF_OFFSET / 2];
537 dev->mem_start = eeprom_buff[PACKET_PAGE_OFFSET / 2] << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538
Joe Perches204a38a2012-05-18 12:56:27 +0000539 /* eeprom_buff has 32-bit ints, so we can't just memcpy it */
540 /* store the initial memory base address */
541 for (i = 0; i < ETH_ALEN / 2; i++) {
542 dev->dev_addr[i * 2] = eeprom_buff[i];
543 dev->dev_addr[i * 2 + 1] = eeprom_buff[i] >> 8;
544 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 if (net_debug > 1)
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000546 pr_debug("%s: new adapter_cnf: 0x%x\n",
547 dev->name, lp->adapter_cnf);
Joe Perches204a38a2012-05-18 12:56:27 +0000548 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Joe Perches204a38a2012-05-18 12:56:27 +0000550 /* allow them to force multiple transceivers. If they force multiple, autosense */
551 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 int count = 0;
Joe Perchesca034bc2012-05-18 12:56:29 +0000553 if (lp->force & FORCE_RJ45) {
554 lp->adapter_cnf |= A_CNF_10B_T;
555 count++;
556 }
557 if (lp->force & FORCE_AUI) {
558 lp->adapter_cnf |= A_CNF_AUI;
559 count++;
560 }
561 if (lp->force & FORCE_BNC) {
562 lp->adapter_cnf |= A_CNF_10B_2;
563 count++;
564 }
565 if (count > 1)
566 lp->adapter_cnf |= A_CNF_MEDIA_AUTO;
567 else if (lp->force & FORCE_RJ45)
568 lp->adapter_cnf |= A_CNF_MEDIA_10B_T;
569 else if (lp->force & FORCE_AUI)
570 lp->adapter_cnf |= A_CNF_MEDIA_AUI;
571 else if (lp->force & FORCE_BNC)
572 lp->adapter_cnf |= A_CNF_MEDIA_10B_2;
Joe Perches204a38a2012-05-18 12:56:27 +0000573 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
575 if (net_debug > 1)
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000576 pr_debug("%s: after force 0x%x, adapter_cnf=0x%x\n",
577 dev->name, lp->force, lp->adapter_cnf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578
Joe Perches204a38a2012-05-18 12:56:27 +0000579 /* FIXME: We don't let you set dc-dc polarity or low RX squelch from the command line: add it here */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580
Joe Perches204a38a2012-05-18 12:56:27 +0000581 /* FIXME: We don't let you set the IMM bit from the command line: add it to lp->auto_neg_cnf here */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
Joe Perches204a38a2012-05-18 12:56:27 +0000583 /* FIXME: we don't set the Ethernet address on the command line. Use
584 * ifconfig IFACE hw ether AABBCCDDEEFF
585 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000587 pr_info("media %s%s%s",
588 (lp->adapter_cnf & A_CNF_10B_T) ? "RJ-45," : "",
589 (lp->adapter_cnf & A_CNF_AUI) ? "AUI," : "",
590 (lp->adapter_cnf & A_CNF_10B_2) ? "BNC," : "");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
592 lp->irq_map = 0xffff;
593
594 /* If this is a CS8900 then no pnp soft */
595 if (lp->chip_type != CS8900 &&
596 /* Check if the ISA IRQ has been set */
Joe Perches204a38a2012-05-18 12:56:27 +0000597 (i = readreg(dev, PP_CS8920_ISAINT) & 0xff,
598 (i != 0 && i < CS8920_NO_INTS))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 if (!dev->irq)
600 dev->irq = i;
601 } else {
602 i = lp->isa_config & INT_NO_MASK;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100603#ifndef CONFIG_CS89x0_PLATFORM
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 if (lp->chip_type == CS8900) {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100605#ifdef CS89x0_NONISA_IRQ
Joe Perches204a38a2012-05-18 12:56:27 +0000606 i = cs8900_irq_map[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607#else
608 /* Translate the IRQ using the IRQ mapping table. */
Denis Chengff8ac602007-09-02 18:30:18 +0800609 if (i >= ARRAY_SIZE(cs8900_irq_map))
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000610 pr_err("invalid ISA interrupt number %d\n", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 else
612 i = cs8900_irq_map[i];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */
615 } else {
616 int irq_map_buff[IRQ_MAP_LEN/2];
617
618 if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA,
Joe Perches204a38a2012-05-18 12:56:27 +0000619 IRQ_MAP_LEN / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 irq_map_buff) >= 0) {
621 if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT)
Joe Perchesca034bc2012-05-18 12:56:29 +0000622 lp->irq_map = ((irq_map_buff[0] >> 8) |
623 (irq_map_buff[1] << 8));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 }
625#endif
626 }
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100627#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 if (!dev->irq)
629 dev->irq = i;
630 }
631
632 printk(" IRQ %d", dev->irq);
633
634#if ALLOW_DMA
635 if (lp->use_dma) {
636 get_dma_channel(dev);
637 printk(", DMA %d", dev->dma);
Joe Perchesca034bc2012-05-18 12:56:29 +0000638 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 printk(", programmed I/O");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
642 /* print the ethernet address. */
Joe Perchesca034bc2012-05-18 12:56:29 +0000643 printk(", MAC %pM\n", dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000645 dev->netdev_ops = &net_ops;
646 dev->watchdog_timeo = HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 if (net_debug)
649 printk("cs89x0_probe1() successful\n");
b1fc5502005-05-12 20:11:55 -0400650
651 retval = register_netdev(dev);
652 if (retval)
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000653 goto out2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 return 0;
655out2:
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000656 iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657out1:
658 return retval;
659}
660
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000661#ifndef CONFIG_CS89x0_PLATFORM
662/*
663 * This function converts the I/O port addres used by the cs89x0_probe() and
664 * init_module() functions to the I/O memory address used by the
665 * cs89x0_probe1() function.
666 */
667static int __init
668cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular)
669{
670 struct net_local *lp = netdev_priv(dev);
671 int ret;
672 void __iomem *io_mem;
673
674 if (!lp)
675 return -ENOMEM;
676
677 dev->base_addr = ioport;
678
679 if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) {
680 ret = -EBUSY;
681 goto out;
682 }
683
684 io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT);
685 if (!io_mem) {
686 ret = -ENOMEM;
687 goto release;
688 }
689
690 /* if they give us an odd I/O address, then do ONE write to
Joe Perches204a38a2012-05-18 12:56:27 +0000691 * the address port, to get it back to address zero, where we
692 * expect to find the EISA signature word. An IO with a base of 0x3
693 * will skip the test for the ADD_PORT.
694 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000695 if (ioport & 1) {
696 if (net_debug > 1)
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000697 pr_info("%s: odd ioaddr 0x%lx\n", dev->name, ioport);
Joe Perchesca034bc2012-05-18 12:56:29 +0000698 if ((ioport & 2) != 2) {
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000699 if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) !=
700 ADD_SIG) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000701 pr_err("%s: bad signature 0x%x\n",
702 dev->name, ioread16(io_mem + ADD_PORT));
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000703 ret = -ENODEV;
704 goto unmap;
705 }
Joe Perchesca034bc2012-05-18 12:56:29 +0000706 }
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000707 }
708
709 ret = cs89x0_probe1(dev, io_mem, modular);
710 if (!ret)
711 goto out;
712unmap:
713 ioport_unmap(io_mem);
714release:
715 release_region(ioport, NETCARD_IO_EXTENT);
716out:
717 return ret;
718}
719
720#ifndef MODULE
721/* Check for a network adaptor of this type, and return '0' iff one exists.
Joe Perches204a38a2012-05-18 12:56:27 +0000722 * If dev->base_addr == 0, probe all likely locations.
723 * If dev->base_addr == 1, always return failure.
724 * If dev->base_addr == 2, allocate space for the device and return success
725 * (detachable devices only).
726 * Return 0 on success.
727 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000728
729struct net_device * __init cs89x0_probe(int unit)
730{
731 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
732 unsigned *port;
733 int err = 0;
734 int irq;
735 int io;
736
737 if (!dev)
738 return ERR_PTR(-ENODEV);
739
740 sprintf(dev->name, "eth%d", unit);
741 netdev_boot_setup_check(dev);
742 io = dev->base_addr;
743 irq = dev->irq;
744
745 if (net_debug)
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000746 pr_info("cs89x0_probe(0x%x)\n", io);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000747
748 if (io > 0x1ff) { /* Check a single specified location. */
749 err = cs89x0_ioport_probe(dev, io, 0);
750 } else if (io != 0) { /* Don't probe at all. */
751 err = -ENXIO;
752 } else {
753 for (port = netcard_portlist; *port; port++) {
754 if (cs89x0_ioport_probe(dev, *port, 0) == 0)
755 break;
756 dev->irq = irq;
757 }
758 if (!*port)
759 err = -ENODEV;
760 }
761 if (err)
762 goto out;
763 return dev;
764out:
765 free_netdev(dev);
Joe Perchesdd92b9a2012-05-18 12:56:28 +0000766 pr_warn("no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000767 return ERR_PTR(err);
768}
769#endif
770#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400771
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772/*********************************
773 * This page contains DMA routines
Joe Perches204a38a2012-05-18 12:56:27 +0000774 *********************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
776#if ALLOW_DMA
777
Joe Perchesca034bc2012-05-18 12:56:29 +0000778#define dma_page_eq(ptr1, ptr2) ((long)(ptr1) >> 17 == (long)(ptr2) >> 17)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779
780static void
781get_dma_channel(struct net_device *dev)
782{
783 struct net_local *lp = netdev_priv(dev);
784
785 if (lp->dma) {
786 dev->dma = lp->dma;
787 lp->isa_config |= ISA_RxDMA;
788 } else {
789 if ((lp->isa_config & ANY_ISA_DMA) == 0)
790 return;
791 dev->dma = lp->isa_config & DMA_NO_MASK;
792 if (lp->chip_type == CS8900)
793 dev->dma += 5;
794 if (dev->dma < 5 || dev->dma > 7) {
795 lp->isa_config &= ~ANY_ISA_DMA;
796 return;
797 }
798 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799}
800
801static void
802write_dma(struct net_device *dev, int chip_type, int dma)
803{
804 struct net_local *lp = netdev_priv(dev);
805 if ((lp->isa_config & ANY_ISA_DMA) == 0)
806 return;
Joe Perchesca034bc2012-05-18 12:56:29 +0000807 if (chip_type == CS8900)
808 writereg(dev, PP_CS8900_ISADMA, dma - 5);
809 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 writereg(dev, PP_CS8920_ISADMA, dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811}
812
813static void
814set_dma_cfg(struct net_device *dev)
815{
816 struct net_local *lp = netdev_priv(dev);
817
818 if (lp->use_dma) {
819 if ((lp->isa_config & ANY_ISA_DMA) == 0) {
820 if (net_debug > 3)
821 printk("set_dma_cfg(): no DMA\n");
822 return;
823 }
824 if (lp->isa_config & ISA_RxDMA) {
825 lp->curr_rx_cfg |= RX_DMA_ONLY;
826 if (net_debug > 3)
827 printk("set_dma_cfg(): RX_DMA_ONLY\n");
828 } else {
829 lp->curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */
830 if (net_debug > 3)
831 printk("set_dma_cfg(): AUTO_RX_DMA\n");
832 }
833 }
834}
835
836static int
837dma_bufcfg(struct net_device *dev)
838{
839 struct net_local *lp = netdev_priv(dev);
840 if (lp->use_dma)
Joe Perches204a38a2012-05-18 12:56:27 +0000841 return (lp->isa_config & ANY_ISA_DMA) ? RX_DMA_ENBL : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 else
843 return 0;
844}
845
846static int
847dma_busctl(struct net_device *dev)
848{
849 int retval = 0;
850 struct net_local *lp = netdev_priv(dev);
851 if (lp->use_dma) {
852 if (lp->isa_config & ANY_ISA_DMA)
853 retval |= RESET_RX_DMA; /* Reset the DMA pointer */
854 if (lp->isa_config & DMA_BURST)
855 retval |= DMA_BURST_MODE; /* Does ISA config specify DMA burst ? */
856 if (lp->dmasize == 64)
857 retval |= RX_DMA_SIZE_64K; /* did they ask for 64K? */
858 retval |= MEMORY_ON; /* we need memory enabled to use DMA. */
859 }
860 return retval;
861}
862
863static void
864dma_rx(struct net_device *dev)
865{
866 struct net_local *lp = netdev_priv(dev);
867 struct sk_buff *skb;
868 int status, length;
869 unsigned char *bp = lp->rx_dma_ptr;
870
Joe Perchesca034bc2012-05-18 12:56:29 +0000871 status = bp[0] + (bp[1] << 8);
872 length = bp[2] + (bp[3] << 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 bp += 4;
874 if (net_debug > 5) {
Joe Perches204a38a2012-05-18 12:56:27 +0000875 printk("%s: receiving DMA packet at %lx, status %x, length %x\n",
876 dev->name, (unsigned long)bp, status, length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 }
878 if ((status & RX_OK) == 0) {
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000879 count_rx_errors(status, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 goto skip_this_frame;
881 }
882
883 /* Malloc up new buffer. */
Pradeep A Dalvi21a4e462012-02-05 02:50:10 +0000884 skb = netdev_alloc_skb(dev, length + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 if (skb == NULL) {
886 if (net_debug) /* I don't think we want to do this to a stressed system */
Joe Perchesca034bc2012-05-18 12:56:29 +0000887 printk("%s: Memory squeeze, dropping packet\n",
888 dev->name);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000889 dev->stats.rx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890
891 /* AKPM: advance bp to the next frame */
892skip_this_frame:
893 bp += (length + 3) & ~3;
Joe Perchesca034bc2012-05-18 12:56:29 +0000894 if (bp >= lp->end_dma_buff)
895 bp -= lp->dmasize * 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 lp->rx_dma_ptr = bp;
897 return;
898 }
899 skb_reserve(skb, 2); /* longword align L3 header */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900
901 if (bp + length > lp->end_dma_buff) {
902 int semi_cnt = lp->end_dma_buff - bp;
Joe Perches204a38a2012-05-18 12:56:27 +0000903 memcpy(skb_put(skb, semi_cnt), bp, semi_cnt);
904 memcpy(skb_put(skb, length - semi_cnt), lp->dma_buff,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 length - semi_cnt);
906 } else {
Joe Perches204a38a2012-05-18 12:56:27 +0000907 memcpy(skb_put(skb, length), bp, length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 }
909 bp += (length + 3) & ~3;
Joe Perchesca034bc2012-05-18 12:56:29 +0000910 if (bp >= lp->end_dma_buff)
911 bp -= lp->dmasize*1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 lp->rx_dma_ptr = bp;
913
914 if (net_debug > 3) {
Joe Perches204a38a2012-05-18 12:56:27 +0000915 printk("%s: received %d byte DMA packet of type %x\n",
916 dev->name, length,
Joe Perchesca034bc2012-05-18 12:56:29 +0000917 ((skb->data[ETH_ALEN + ETH_ALEN] << 8) |
918 skb->data[ETH_ALEN + ETH_ALEN + 1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 }
Joe Perches204a38a2012-05-18 12:56:27 +0000920 skb->protocol = eth_type_trans(skb, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 netif_rx(skb);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000922 dev->stats.rx_packets++;
923 dev->stats.rx_bytes += length;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924}
925
926#endif /* ALLOW_DMA */
927
Hannes Ederdac499f2008-12-25 23:56:45 -0800928static void __init reset_chip(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929{
Gilles Chanteperdrix0ac4ed92008-09-26 15:44:43 +0100930#if !defined(CONFIG_MACH_MX31ADS)
Domenico Andreolid181a612011-03-14 03:46:53 +0000931#if !defined(CS89x0_NONISA_IRQ)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 struct net_local *lp = netdev_priv(dev);
Domenico Andreolid181a612011-03-14 03:46:53 +0000933#endif /* CS89x0_NONISA_IRQ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 int reset_start_time;
935
936 writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
937
938 /* wait 30 ms */
939 msleep(30);
940
Domenico Andreolid181a612011-03-14 03:46:53 +0000941#if !defined(CS89x0_NONISA_IRQ)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 if (lp->chip_type != CS8900) {
943 /* Hardware problem requires PNP registers to be reconfigured after a reset */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000944 iowrite16(PP_CS8920_ISAINT, lp->virt_addr + ADD_PORT);
945 iowrite8(dev->irq, lp->virt_addr + DATA_PORT);
946 iowrite8(0, lp->virt_addr + DATA_PORT + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000948 iowrite16(PP_CS8920_ISAMemB, lp->virt_addr + ADD_PORT);
949 iowrite8((dev->mem_start >> 16) & 0xff,
950 lp->virt_addr + DATA_PORT);
951 iowrite8((dev->mem_start >> 8) & 0xff,
952 lp->virt_addr + DATA_PORT + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 }
Domenico Andreolid181a612011-03-14 03:46:53 +0000954#endif /* CS89x0_NONISA_IRQ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
956 /* Wait until the chip is reset */
957 reset_start_time = jiffies;
Joe Perchesca034bc2012-05-18 12:56:29 +0000958 while ((readreg(dev, PP_SelfST) & INIT_DONE) == 0 &&
959 jiffies - reset_start_time < 2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 ;
Gilles Chanteperdrix0ac4ed92008-09-26 15:44:43 +0100961#endif /* !CONFIG_MACH_MX31ADS */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962}
963
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400964
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965static void
966control_dc_dc(struct net_device *dev, int on_not_off)
967{
968 struct net_local *lp = netdev_priv(dev);
969 unsigned int selfcontrol;
970 int timenow = jiffies;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400971 /* control the DC to DC convertor in the SelfControl register.
Joe Perchesca034bc2012-05-18 12:56:29 +0000972 * Note: This is hooked up to a general purpose pin, might not
973 * always be a DC to DC convertor.
974 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
976 selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
977 if (((lp->adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
978 selfcontrol |= HCB1;
979 else
980 selfcontrol &= ~HCB1;
981 writereg(dev, PP_SelfCTL, selfcontrol);
982
983 /* Wait for the DC/DC converter to power up - 500ms */
984 while (jiffies - timenow < HZ)
985 ;
986}
987
988#define DETECTED_NONE 0
989#define DETECTED_RJ45H 1
990#define DETECTED_RJ45F 2
991#define DETECTED_AUI 3
992#define DETECTED_BNC 4
993
994static int
995detect_tp(struct net_device *dev)
996{
997 struct net_local *lp = netdev_priv(dev);
998 int timenow = jiffies;
999 int fdx;
1000
Joe Perchesca034bc2012-05-18 12:56:29 +00001001 if (net_debug > 1)
1002 printk("%s: Attempting TP\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
Joe Perchesca034bc2012-05-18 12:56:29 +00001004 /* If connected to another full duplex capable 10-Base-T card
1005 * the link pulses seem to be lost when the auto detect bit in
1006 * the LineCTL is set. To overcome this the auto detect bit will
1007 * be cleared whilst testing the 10-Base-T interface. This would
1008 * not be necessary for the sparrow chip but is simpler to do it
1009 * anyway.
1010 */
Joe Perches204a38a2012-05-18 12:56:27 +00001011 writereg(dev, PP_LineCTL, lp->linectl & ~AUI_ONLY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 control_dc_dc(dev, 0);
1013
Joe Perchesca034bc2012-05-18 12:56:29 +00001014 /* Delay for the hardware to work out if the TP cable is present
1015 * - 150ms
1016 */
1017 for (timenow = jiffies; jiffies - timenow < 15;)
Joe Perches204a38a2012-05-18 12:56:27 +00001018 ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 if ((readreg(dev, PP_LineST) & LINK_OK) == 0)
1020 return DETECTED_NONE;
1021
1022 if (lp->chip_type == CS8900) {
Joe Perches204a38a2012-05-18 12:56:27 +00001023 switch (lp->force & 0xf0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024#if 0
Joe Perches204a38a2012-05-18 12:56:27 +00001025 case FORCE_AUTO:
1026 printk("%s: cs8900 doesn't autonegotiate\n", dev->name);
1027 return DETECTED_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028#endif
Joe Perches204a38a2012-05-18 12:56:27 +00001029 /* CS8900 doesn't support AUTO, change to HALF*/
1030 case FORCE_AUTO:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 lp->force &= ~FORCE_AUTO;
Joe Perches204a38a2012-05-18 12:56:27 +00001032 lp->force |= FORCE_HALF;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 break;
1034 case FORCE_HALF:
1035 break;
Joe Perches204a38a2012-05-18 12:56:27 +00001036 case FORCE_FULL:
Joe Perchesca034bc2012-05-18 12:56:29 +00001037 writereg(dev, PP_TestCTL,
1038 readreg(dev, PP_TestCTL) | FDX_8900);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 break;
Joe Perches204a38a2012-05-18 12:56:27 +00001040 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 fdx = readreg(dev, PP_TestCTL) & FDX_8900;
1042 } else {
1043 switch (lp->force & 0xf0) {
1044 case FORCE_AUTO:
1045 lp->auto_neg_cnf = AUTO_NEG_ENABLE;
1046 break;
1047 case FORCE_HALF:
1048 lp->auto_neg_cnf = 0;
1049 break;
1050 case FORCE_FULL:
1051 lp->auto_neg_cnf = RE_NEG_NOW | ALLOW_FDX;
1052 break;
Joe Perches204a38a2012-05-18 12:56:27 +00001053 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
1055 writereg(dev, PP_AutoNegCTL, lp->auto_neg_cnf & AUTO_NEG_MASK);
1056
1057 if ((lp->auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001058 pr_info("%s: negotiating duplex...\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 while (readreg(dev, PP_AutoNegST) & AUTO_NEG_BUSY) {
1060 if (jiffies - timenow > 4000) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001061 pr_err("**** Full / half duplex auto-negotiation timed out ****\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 break;
1063 }
1064 }
1065 }
1066 fdx = readreg(dev, PP_AutoNegST) & FDX_ACTIVE;
1067 }
1068 if (fdx)
1069 return DETECTED_RJ45F;
1070 else
1071 return DETECTED_RJ45H;
1072}
1073
1074/* send a test packet - return true if carrier bits are ok */
1075static int
1076send_test_pkt(struct net_device *dev)
1077{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001078 struct net_local *lp = netdev_priv(dev);
Joe Perchesca034bc2012-05-18 12:56:29 +00001079 char test_packet[] = {
1080 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1081 0, 46, /* A 46 in network order */
1082 0, 0, /* DSAP=0 & SSAP=0 fields */
1083 0xf3, 0 /* Control (Test Req + P bit set) */
1084 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 long timenow = jiffies;
1086
1087 writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);
1088
Joe Perches204a38a2012-05-18 12:56:27 +00001089 memcpy(test_packet, dev->dev_addr, ETH_ALEN);
1090 memcpy(test_packet + ETH_ALEN, dev->dev_addr, ETH_ALEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001092 iowrite16(TX_AFTER_ALL, lp->virt_addr + TX_CMD_PORT);
1093 iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
1095 /* Test to see if the chip has allocated memory for the packet */
1096 while (jiffies - timenow < 5)
1097 if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW)
1098 break;
1099 if (jiffies - timenow >= 5)
1100 return 0; /* this shouldn't happen */
1101
1102 /* Write the contents of the packet */
Joe Perchesca034bc2012-05-18 12:56:29 +00001103 writewords(lp, TX_FRAME_PORT, test_packet, (ETH_ZLEN + 1) >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
Joe Perchesca034bc2012-05-18 12:56:29 +00001105 if (net_debug > 1)
1106 printk("Sending test packet ");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 /* wait a couple of jiffies for packet to be received */
Joe Perchesca034bc2012-05-18 12:56:29 +00001108 for (timenow = jiffies; jiffies - timenow < 3;)
Joe Perches204a38a2012-05-18 12:56:27 +00001109 ;
1110 if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001111 if (net_debug > 1)
1112 printk("succeeded\n");
Joe Perches204a38a2012-05-18 12:56:27 +00001113 return 1;
1114 }
Joe Perchesca034bc2012-05-18 12:56:29 +00001115 if (net_debug > 1)
1116 printk("failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 return 0;
1118}
1119
1120
1121static int
1122detect_aui(struct net_device *dev)
1123{
1124 struct net_local *lp = netdev_priv(dev);
1125
Joe Perchesca034bc2012-05-18 12:56:29 +00001126 if (net_debug > 1)
1127 printk("%s: Attempting AUI\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 control_dc_dc(dev, 0);
1129
Joe Perches204a38a2012-05-18 12:56:27 +00001130 writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
1132 if (send_test_pkt(dev))
1133 return DETECTED_AUI;
1134 else
1135 return DETECTED_NONE;
1136}
1137
1138static int
1139detect_bnc(struct net_device *dev)
1140{
1141 struct net_local *lp = netdev_priv(dev);
1142
Joe Perchesca034bc2012-05-18 12:56:29 +00001143 if (net_debug > 1)
1144 printk("%s: Attempting BNC\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 control_dc_dc(dev, 1);
1146
Joe Perches204a38a2012-05-18 12:56:27 +00001147 writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
1149 if (send_test_pkt(dev))
1150 return DETECTED_BNC;
1151 else
1152 return DETECTED_NONE;
1153}
1154
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001155
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156static void
1157write_irq(struct net_device *dev, int chip_type, int irq)
1158{
1159 int i;
1160
1161 if (chip_type == CS8900) {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001162#ifndef CONFIG_CS89x0_PLATFORM
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 /* Search the mapping table for the corresponding IRQ pin. */
Denis Chengff8ac602007-09-02 18:30:18 +08001164 for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 if (cs8900_irq_map[i] == irq)
1166 break;
1167 /* Not found */
Denis Chengff8ac602007-09-02 18:30:18 +08001168 if (i == ARRAY_SIZE(cs8900_irq_map))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 i = 3;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001170#else
1171 /* INTRQ0 pin is used for interrupt generation. */
1172 i = 0;
1173#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 writereg(dev, PP_CS8900_ISAINT, i);
1175 } else {
1176 writereg(dev, PP_CS8920_ISAINT, irq);
1177 }
1178}
1179
1180/* Open/initialize the board. This is called (in the current kernel)
1181 sometime after booting when the 'ifconfig' program is run.
1182
1183 This routine should set everything up anew at each open, even
1184 registers that "should" only need to be set once at boot, so that
1185 there is non-reboot way to recover if something goes wrong.
Joe Perches204a38a2012-05-18 12:56:27 +00001186*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
1188/* AKPM: do we need to do any locking here? */
1189
1190static int
1191net_open(struct net_device *dev)
1192{
1193 struct net_local *lp = netdev_priv(dev);
1194 int result = 0;
1195 int i;
1196 int ret;
1197
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 if (dev->irq < 2) {
1199 /* Allow interrupts to be generated by the chip */
1200/* Cirrus' release had this: */
1201#if 0
Joe Perches204a38a2012-05-18 12:56:27 +00001202 writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203#endif
1204/* And 2.3.47 had this: */
1205 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
1206
1207 for (i = 2; i < CS8920_NO_INTS; i++) {
1208 if ((1 << i) & lp->irq_map) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001209 if (request_irq(i, net_interrupt, 0, dev->name,
1210 dev) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 dev->irq = i;
1212 write_irq(dev, lp->chip_type, i);
1213 /* writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); */
1214 break;
1215 }
1216 }
1217 }
1218
1219 if (i >= CS8920_NO_INTS) {
1220 writereg(dev, PP_BusCTL, 0); /* disable interrupts. */
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001221 pr_err("can't get an interrupt\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 ret = -EAGAIN;
1223 goto bad_out;
1224 }
Joe Perchesca034bc2012-05-18 12:56:29 +00001225 } else {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001226#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 if (((1 << dev->irq) & lp->irq_map) == 0) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001228 pr_err("%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
Joe Perches204a38a2012-05-18 12:56:27 +00001229 dev->name, dev->irq, lp->irq_map);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 ret = -EAGAIN;
1231 goto bad_out;
1232 }
1233#endif
1234/* FIXME: Cirrus' release had this: */
Joe Perches204a38a2012-05-18 12:56:27 +00001235 writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236/* And 2.3.47 had this: */
1237#if 0
1238 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
1239#endif
1240 write_irq(dev, lp->chip_type, dev->irq);
Joe Perchesa0607fd2009-11-18 23:29:17 -08001241 ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 if (ret) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001243 pr_err("request_irq(%d) failed\n", dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 goto bad_out;
1245 }
1246 }
1247
1248#if ALLOW_DMA
Joe Perchesca034bc2012-05-18 12:56:29 +00001249 if (lp->use_dma && (lp->isa_config & ANY_ISA_DMA)) {
1250 unsigned long flags;
1251 lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,
1252 get_order(lp->dmasize * 1024));
1253 if (!lp->dma_buff) {
1254 pr_err("%s: cannot get %dK memory for DMA\n",
1255 dev->name, lp->dmasize);
1256 goto release_irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257 }
Joe Perchesca034bc2012-05-18 12:56:29 +00001258 if (net_debug > 1) {
1259 printk("%s: dma %lx %lx\n",
1260 dev->name,
1261 (unsigned long)lp->dma_buff,
1262 (unsigned long)isa_virt_to_bus(lp->dma_buff));
1263 }
1264 if ((unsigned long)lp->dma_buff >= MAX_DMA_ADDRESS ||
1265 !dma_page_eq(lp->dma_buff,
1266 lp->dma_buff + lp->dmasize * 1024 - 1)) {
1267 pr_err("%s: not usable as DMA buffer\n", dev->name);
1268 goto release_irq;
1269 }
1270 memset(lp->dma_buff, 0, lp->dmasize * 1024); /* Why? */
1271 if (request_dma(dev->dma, dev->name)) {
1272 pr_err("%s: cannot get dma channel %d\n",
1273 dev->name, dev->dma);
1274 goto release_irq;
1275 }
1276 write_dma(dev, lp->chip_type, dev->dma);
1277 lp->rx_dma_ptr = lp->dma_buff;
1278 lp->end_dma_buff = lp->dma_buff + lp->dmasize * 1024;
1279 spin_lock_irqsave(&lp->lock, flags);
1280 disable_dma(dev->dma);
1281 clear_dma_ff(dev->dma);
1282 set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */
1283 set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
1284 set_dma_count(dev->dma, lp->dmasize * 1024);
1285 enable_dma(dev->dma);
1286 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 }
1288#endif /* ALLOW_DMA */
1289
1290 /* set the Ethernet address */
Joe Perches204a38a2012-05-18 12:56:27 +00001291 for (i = 0; i < ETH_ALEN / 2; i++)
Joe Perchesca034bc2012-05-18 12:56:29 +00001292 writereg(dev, PP_IA + i * 2,
1293 (dev->dev_addr[i * 2] |
1294 (dev->dev_addr[i * 2 + 1] << 8)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295
1296 /* while we're testing the interface, leave interrupts disabled */
1297 writereg(dev, PP_BusCTL, MEMORY_ON);
1298
1299 /* Set the LineCTL quintuplet based on adapter configuration read from EEPROM */
Joe Perchesca034bc2012-05-18 12:56:29 +00001300 if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) &&
1301 (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH))
Joe Perches204a38a2012-05-18 12:56:27 +00001302 lp->linectl = LOW_RX_SQUELCH;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303 else
Joe Perches204a38a2012-05-18 12:56:27 +00001304 lp->linectl = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
Joe Perches204a38a2012-05-18 12:56:27 +00001306 /* check to make sure that they have the "right" hardware available */
1307 switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001308 case A_CNF_MEDIA_10B_T:
1309 result = lp->adapter_cnf & A_CNF_10B_T;
1310 break;
1311 case A_CNF_MEDIA_AUI:
1312 result = lp->adapter_cnf & A_CNF_AUI;
1313 break;
1314 case A_CNF_MEDIA_10B_2:
1315 result = lp->adapter_cnf & A_CNF_10B_2;
1316 break;
1317 default:
1318 result = lp->adapter_cnf & (A_CNF_10B_T |
1319 A_CNF_AUI |
1320 A_CNF_10B_2);
Joe Perches204a38a2012-05-18 12:56:27 +00001321 }
1322 if (!result) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001323 pr_err("%s: EEPROM is configured for unavailable media\n",
1324 dev->name);
Wang Chen17a94402008-05-30 11:18:55 +08001325release_dma:
1326#if ALLOW_DMA
1327 free_dma(dev->dma);
Wang Chen17a94402008-05-30 11:18:55 +08001328release_irq:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 release_dma_buff(lp);
1330#endif
Joe Perchesca034bc2012-05-18 12:56:29 +00001331 writereg(dev, PP_LineCTL,
1332 readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
Joe Perches204a38a2012-05-18 12:56:27 +00001333 free_irq(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 ret = -EAGAIN;
1335 goto bad_out;
1336 }
1337
Joe Perches204a38a2012-05-18 12:56:27 +00001338 /* set the hardware to the configured choice */
1339 switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 case A_CNF_MEDIA_10B_T:
Joe Perches204a38a2012-05-18 12:56:27 +00001341 result = detect_tp(dev);
1342 if (result == DETECTED_NONE) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001343 pr_warn("%s: 10Base-T (RJ-45) has no cable\n",
1344 dev->name);
Joe Perches204a38a2012-05-18 12:56:27 +00001345 if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
1346 result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */
1347 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 break;
1349 case A_CNF_MEDIA_AUI:
Joe Perches204a38a2012-05-18 12:56:27 +00001350 result = detect_aui(dev);
1351 if (result == DETECTED_NONE) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001352 pr_warn("%s: 10Base-5 (AUI) has no cable\n", dev->name);
Joe Perches204a38a2012-05-18 12:56:27 +00001353 if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
1354 result = DETECTED_AUI; /* Yes! I don't care if I see a carrrier */
1355 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 break;
1357 case A_CNF_MEDIA_10B_2:
Joe Perches204a38a2012-05-18 12:56:27 +00001358 result = detect_bnc(dev);
1359 if (result == DETECTED_NONE) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001360 pr_warn("%s: 10Base-2 (BNC) has no cable\n", dev->name);
Joe Perches204a38a2012-05-18 12:56:27 +00001361 if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
1362 result = DETECTED_BNC; /* Yes! I don't care if I can xmit a packet */
1363 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 break;
1365 case A_CNF_MEDIA_AUTO:
1366 writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET);
Joe Perchesca034bc2012-05-18 12:56:29 +00001367 if (lp->adapter_cnf & A_CNF_10B_T) {
1368 result = detect_tp(dev);
1369 if (result != DETECTED_NONE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 break;
Joe Perchesca034bc2012-05-18 12:56:29 +00001371 }
1372 if (lp->adapter_cnf & A_CNF_AUI) {
1373 result = detect_aui(dev);
1374 if (result != DETECTED_NONE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 break;
Joe Perchesca034bc2012-05-18 12:56:29 +00001376 }
1377 if (lp->adapter_cnf & A_CNF_10B_2) {
1378 result = detect_bnc(dev);
1379 if (result != DETECTED_NONE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 break;
Joe Perchesca034bc2012-05-18 12:56:29 +00001381 }
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001382 pr_err("%s: no media detected\n", dev->name);
Wang Chen17a94402008-05-30 11:18:55 +08001383 goto release_dma;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 }
Joe Perches204a38a2012-05-18 12:56:27 +00001385 switch (result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 case DETECTED_NONE:
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001387 pr_err("%s: no network cable attached to configured media\n",
1388 dev->name);
Wang Chen17a94402008-05-30 11:18:55 +08001389 goto release_dma;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 case DETECTED_RJ45H:
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001391 pr_info("%s: using half-duplex 10Base-T (RJ-45)\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 break;
1393 case DETECTED_RJ45F:
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001394 pr_info("%s: using full-duplex 10Base-T (RJ-45)\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 break;
1396 case DETECTED_AUI:
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001397 pr_info("%s: using 10Base-5 (AUI)\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 break;
1399 case DETECTED_BNC:
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001400 pr_info("%s: using 10Base-2 (BNC)\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 break;
1402 }
1403
1404 /* Turn on both receive and transmit operations */
Joe Perchesca034bc2012-05-18 12:56:29 +00001405 writereg(dev, PP_LineCTL,
1406 readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
1408 /* Receive only error free packets addressed to this card */
1409 lp->rx_mode = 0;
1410 writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
1411
1412 lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
1413
1414 if (lp->isa_config & STREAM_TRANSFER)
1415 lp->curr_rx_cfg |= RX_STREAM_ENBL;
1416#if ALLOW_DMA
1417 set_dma_cfg(dev);
1418#endif
1419 writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
1420
Joe Perchesca034bc2012-05-18 12:56:29 +00001421 writereg(dev, PP_TxCFG, (TX_LOST_CRS_ENBL |
1422 TX_SQE_ERROR_ENBL |
1423 TX_OK_ENBL |
1424 TX_LATE_COL_ENBL |
1425 TX_JBR_ENBL |
1426 TX_ANY_COL_ENBL |
1427 TX_16_COL_ENBL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
Joe Perchesca034bc2012-05-18 12:56:29 +00001429 writereg(dev, PP_BufCFG, (READY_FOR_TX_ENBL |
1430 RX_MISS_COUNT_OVRFLOW_ENBL |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431#if ALLOW_DMA
Joe Perchesca034bc2012-05-18 12:56:29 +00001432 dma_bufcfg(dev) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433#endif
Joe Perchesca034bc2012-05-18 12:56:29 +00001434 TX_COL_COUNT_OVRFLOW_ENBL |
1435 TX_UNDERRUN_ENBL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
1437 /* now that we've got our act together, enable everything */
Joe Perchesca034bc2012-05-18 12:56:29 +00001438 writereg(dev, PP_BusCTL, (ENABLE_IRQ
1439 | (dev->mem_start ? MEMORY_ON : 0) /* turn memory on */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440#if ALLOW_DMA
Joe Perchesca034bc2012-05-18 12:56:29 +00001441 | dma_busctl(dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442#endif
Joe Perchesca034bc2012-05-18 12:56:29 +00001443 ));
Joe Perches204a38a2012-05-18 12:56:27 +00001444 netif_start_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 if (net_debug > 1)
1446 printk("cs89x0: net_open() succeeded\n");
1447 return 0;
1448bad_out:
1449 return ret;
1450}
1451
1452static void net_timeout(struct net_device *dev)
1453{
1454 /* If we get here, some higher level has decided we are broken.
1455 There should really be a "kick me" function call instead. */
Joe Perchesca034bc2012-05-18 12:56:29 +00001456 if (net_debug > 0)
1457 printk("%s: transmit timed out, %s?\n",
1458 dev->name,
1459 tx_done(dev) ? "IRQ conflict" : "network cable problem");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 /* Try to restart the adaptor. */
1461 netif_wake_queue(dev);
1462}
1463
Joe Perches204a38a2012-05-18 12:56:27 +00001464static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465{
1466 struct net_local *lp = netdev_priv(dev);
Dongdong Deng79fbe132009-07-12 20:27:06 +00001467 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
1469 if (net_debug > 3) {
1470 printk("%s: sent %d byte packet of type %x\n",
Joe Perches204a38a2012-05-18 12:56:27 +00001471 dev->name, skb->len,
Joe Perchesca034bc2012-05-18 12:56:29 +00001472 ((skb->data[ETH_ALEN + ETH_ALEN] << 8) |
1473 skb->data[ETH_ALEN + ETH_ALEN + 1]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 }
1475
1476 /* keep the upload from being interrupted, since we
Joe Perchesca034bc2012-05-18 12:56:29 +00001477 * ask the chip to start transmitting before the
1478 * whole packet has been completely uploaded.
1479 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
Dongdong Deng79fbe132009-07-12 20:27:06 +00001481 spin_lock_irqsave(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 netif_stop_queue(dev);
1483
1484 /* initiate a transmit sequence */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001485 iowrite16(lp->send_cmd, lp->virt_addr + TX_CMD_PORT);
1486 iowrite16(skb->len, lp->virt_addr + TX_LEN_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487
1488 /* Test to see if the chip has allocated memory for the packet */
1489 if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
Joe Perches204a38a2012-05-18 12:56:27 +00001490 /* Gasp! It hasn't. But that shouldn't happen since
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 * we're waiting for TxOk, so return 1 and requeue this packet.
1492 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001493
Dongdong Deng79fbe132009-07-12 20:27:06 +00001494 spin_unlock_irqrestore(&lp->lock, flags);
Joe Perchesca034bc2012-05-18 12:56:29 +00001495 if (net_debug)
1496 printk("cs89x0: Tx buffer not free!\n");
Patrick McHardy5b548142009-06-12 06:22:29 +00001497 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 }
1499 /* Write the contents of the packet */
Joe Perchesca034bc2012-05-18 12:56:29 +00001500 writewords(lp, TX_FRAME_PORT, skb->data, (skb->len + 1) >> 1);
Dongdong Deng79fbe132009-07-12 20:27:06 +00001501 spin_unlock_irqrestore(&lp->lock, flags);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001502 dev->stats.tx_bytes += skb->len;
Joe Perches204a38a2012-05-18 12:56:27 +00001503 dev_kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Joe Perches204a38a2012-05-18 12:56:27 +00001505 /* We DO NOT call netif_wake_queue() here.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 * We also DO NOT call netif_start_queue().
1507 *
1508 * Either of these would cause another bottom half run through
Joe Perchesca034bc2012-05-18 12:56:29 +00001509 * net_send_packet() before this packet has fully gone out.
1510 * That causes us to hit the "Gasp!" above and the send is rescheduled.
1511 * it runs like a dog. We just return and wait for the Tx completion
1512 * interrupt handler to restart the netdevice layer
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 */
1514
Patrick McHardy6ed10652009-06-23 06:03:08 +00001515 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516}
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001517
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518/* The typical workload of the driver:
Joe Perches204a38a2012-05-18 12:56:27 +00001519 * Handle the network interface interrupts.
1520 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001521
David Howells7d12e782006-10-05 14:55:46 +01001522static irqreturn_t net_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523{
1524 struct net_device *dev = dev_id;
1525 struct net_local *lp;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001526 int status;
Joe Perches204a38a2012-05-18 12:56:27 +00001527 int handled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 lp = netdev_priv(dev);
1530
1531 /* we MUST read all the events out of the ISQ, otherwise we'll never
Joe Perches204a38a2012-05-18 12:56:27 +00001532 * get interrupted again. As a consequence, we can't have any limit
1533 * on the number of times we loop in the interrupt handler. The
1534 * hardware guarantees that eventually we'll run out of events. Of
1535 * course, if you're on a slow machine, and packets are arriving
1536 * faster than you can read them off, you're screwed. Hasta la
1537 * vista, baby!
1538 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001539 while ((status = ioread16(lp->virt_addr + ISQ_PORT))) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001540 if (net_debug > 4)
1541 printk("%s: event=%04x\n", dev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 handled = 1;
Joe Perches204a38a2012-05-18 12:56:27 +00001543 switch (status & ISQ_EVENT_MASK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 case ISQ_RECEIVER_EVENT:
1545 /* Got a packet(s). */
1546 net_rx(dev);
1547 break;
1548 case ISQ_TRANSMITTER_EVENT:
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001549 dev->stats.tx_packets++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 netif_wake_queue(dev); /* Inform upper layers. */
Joe Perches204a38a2012-05-18 12:56:27 +00001551 if ((status & (TX_OK |
1552 TX_LOST_CRS |
1553 TX_SQE_ERROR |
1554 TX_LATE_COL |
1555 TX_16_COL)) != TX_OK) {
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001556 if ((status & TX_OK) == 0)
1557 dev->stats.tx_errors++;
1558 if (status & TX_LOST_CRS)
1559 dev->stats.tx_carrier_errors++;
1560 if (status & TX_SQE_ERROR)
1561 dev->stats.tx_heartbeat_errors++;
1562 if (status & TX_LATE_COL)
1563 dev->stats.tx_window_errors++;
1564 if (status & TX_16_COL)
1565 dev->stats.tx_aborted_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 }
1567 break;
1568 case ISQ_BUFFER_EVENT:
1569 if (status & READY_FOR_TX) {
1570 /* we tried to transmit a packet earlier,
Joe Perches204a38a2012-05-18 12:56:27 +00001571 * but inexplicably ran out of buffers.
1572 * That shouldn't happen since we only ever
1573 * load one packet. Shrug. Do the right
1574 * thing anyway.
1575 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 netif_wake_queue(dev); /* Inform upper layers. */
1577 }
1578 if (status & TX_UNDERRUN) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001579 if (net_debug > 0)
1580 printk("%s: transmit underrun\n",
1581 dev->name);
Joe Perches204a38a2012-05-18 12:56:27 +00001582 lp->send_underrun++;
Joe Perchesca034bc2012-05-18 12:56:29 +00001583 if (lp->send_underrun == 3)
1584 lp->send_cmd = TX_AFTER_381;
1585 else if (lp->send_underrun == 6)
1586 lp->send_cmd = TX_AFTER_ALL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 /* transmit cycle is done, although
Joe Perches204a38a2012-05-18 12:56:27 +00001588 * frame wasn't transmitted - this
1589 * avoids having to wait for the upper
1590 * layers to timeout on us, in the
1591 * event of a tx underrun
1592 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 netif_wake_queue(dev); /* Inform upper layers. */
Joe Perches204a38a2012-05-18 12:56:27 +00001594 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595#if ALLOW_DMA
1596 if (lp->use_dma && (status & RX_DMA)) {
1597 int count = readreg(dev, PP_DmaFrameCnt);
Joe Perches204a38a2012-05-18 12:56:27 +00001598 while (count) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 if (net_debug > 5)
Joe Perchesca034bc2012-05-18 12:56:29 +00001600 printk("%s: receiving %d DMA frames\n",
1601 dev->name, count);
Joe Perches204a38a2012-05-18 12:56:27 +00001602 if (net_debug > 2 && count > 1)
Joe Perchesca034bc2012-05-18 12:56:29 +00001603 printk("%s: receiving %d DMA frames\n",
1604 dev->name, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 dma_rx(dev);
1606 if (--count == 0)
1607 count = readreg(dev, PP_DmaFrameCnt);
1608 if (net_debug > 2 && count > 0)
Joe Perchesca034bc2012-05-18 12:56:29 +00001609 printk("%s: continuing with %d DMA frames\n",
1610 dev->name, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 }
1612 }
1613#endif
1614 break;
1615 case ISQ_RX_MISS_EVENT:
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001616 dev->stats.rx_missed_errors += (status >> 6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 break;
1618 case ISQ_TX_COL_EVENT:
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001619 dev->stats.collisions += (status >> 6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 break;
1621 }
1622 }
1623 return IRQ_RETVAL(handled);
1624}
1625
1626static void
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001627count_rx_errors(int status, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628{
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001629 dev->stats.rx_errors++;
1630 if (status & RX_RUNT)
1631 dev->stats.rx_length_errors++;
1632 if (status & RX_EXTRA_DATA)
1633 dev->stats.rx_length_errors++;
Joe Perchesca034bc2012-05-18 12:56:29 +00001634 if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA | RX_RUNT)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 /* per str 172 */
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001636 dev->stats.rx_crc_errors++;
1637 if (status & RX_DRIBBLE)
1638 dev->stats.rx_frame_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639}
1640
1641/* We have a good packet(s), get it/them out of the buffers. */
1642static void
1643net_rx(struct net_device *dev)
1644{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001645 struct net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646 struct sk_buff *skb;
1647 int status, length;
1648
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001649 status = ioread16(lp->virt_addr + RX_FRAME_PORT);
1650 length = ioread16(lp->virt_addr + RX_FRAME_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
1652 if ((status & RX_OK) == 0) {
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001653 count_rx_errors(status, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 return;
1655 }
1656
1657 /* Malloc up new buffer. */
Pradeep A Dalvi21a4e462012-02-05 02:50:10 +00001658 skb = netdev_alloc_skb(dev, length + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 if (skb == NULL) {
1660#if 0 /* Again, this seems a cruel thing to do */
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001661 pr_warn("%s: Memory squeeze, dropping packet\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662#endif
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001663 dev->stats.rx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 return;
1665 }
1666 skb_reserve(skb, 2); /* longword align L3 header */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001668 readwords(lp, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 if (length & 1)
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001670 skb->data[length-1] = ioread16(lp->virt_addr + RX_FRAME_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
1672 if (net_debug > 3) {
Joe Perches204a38a2012-05-18 12:56:27 +00001673 printk("%s: received %d byte packet of type %x\n",
1674 dev->name, length,
Joe Perchesca034bc2012-05-18 12:56:29 +00001675 (skb->data[ETH_ALEN + ETH_ALEN] << 8) |
1676 skb->data[ETH_ALEN + ETH_ALEN + 1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 }
1678
Joe Perches204a38a2012-05-18 12:56:27 +00001679 skb->protocol = eth_type_trans(skb, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 netif_rx(skb);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001681 dev->stats.rx_packets++;
1682 dev->stats.rx_bytes += length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683}
1684
1685#if ALLOW_DMA
1686static void release_dma_buff(struct net_local *lp)
1687{
1688 if (lp->dma_buff) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001689 free_pages((unsigned long)(lp->dma_buff),
1690 get_order(lp->dmasize * 1024));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 lp->dma_buff = NULL;
1692 }
1693}
1694#endif
1695
1696/* The inverse routine to net_open(). */
1697static int
1698net_close(struct net_device *dev)
1699{
1700#if ALLOW_DMA
1701 struct net_local *lp = netdev_priv(dev);
1702#endif
1703
1704 netif_stop_queue(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001705
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 writereg(dev, PP_RxCFG, 0);
1707 writereg(dev, PP_TxCFG, 0);
1708 writereg(dev, PP_BufCFG, 0);
1709 writereg(dev, PP_BusCTL, 0);
1710
1711 free_irq(dev->irq, dev);
1712
1713#if ALLOW_DMA
1714 if (lp->use_dma && lp->dma) {
1715 free_dma(dev->dma);
1716 release_dma_buff(lp);
1717 }
1718#endif
1719
1720 /* Update the statistics here. */
1721 return 0;
1722}
1723
Joe Perches204a38a2012-05-18 12:56:27 +00001724/* Get the current statistics.
1725 * This may be called with the card open or closed.
1726 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727static struct net_device_stats *
1728net_get_stats(struct net_device *dev)
1729{
1730 struct net_local *lp = netdev_priv(dev);
1731 unsigned long flags;
1732
1733 spin_lock_irqsave(&lp->lock, flags);
1734 /* Update the statistics from the device registers. */
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001735 dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
1736 dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 spin_unlock_irqrestore(&lp->lock, flags);
1738
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001739 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740}
1741
1742static void set_multicast_list(struct net_device *dev)
1743{
1744 struct net_local *lp = netdev_priv(dev);
1745 unsigned long flags;
1746
1747 spin_lock_irqsave(&lp->lock, flags);
Joe Perchesca034bc2012-05-18 12:56:29 +00001748 if (dev->flags & IFF_PROMISC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 lp->rx_mode = RX_ALL_ACCEPT;
Jiri Pirkoe1d44472010-02-17 11:09:31 +00001750 else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
Joe Perchesca034bc2012-05-18 12:56:29 +00001751 /* The multicast-accept list is initialized to accept-all,
1752 * and we rely on higher-level filtering for now.
1753 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 lp->rx_mode = RX_MULTCAST_ACCEPT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 else
1756 lp->rx_mode = 0;
1757
1758 writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
1759
Joe Perchesca034bc2012-05-18 12:56:29 +00001760 /* in promiscuous mode, we accept errored packets,
1761 * so we have to enable interrupts on them also
1762 */
1763 writereg(dev, PP_RxCFG,
1764 (lp->curr_rx_cfg |
1765 (lp->rx_mode == RX_ALL_ACCEPT)
1766 ? (RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL)
1767 : 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 spin_unlock_irqrestore(&lp->lock, flags);
1769}
1770
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771static int set_mac_address(struct net_device *dev, void *p)
1772{
1773 int i;
1774 struct sockaddr *addr = p;
1775
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 if (netif_running(dev))
1777 return -EBUSY;
1778
1779 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1780
Johannes Berge1749612008-10-27 15:59:26 -07001781 if (net_debug)
Joe Perchesca034bc2012-05-18 12:56:29 +00001782 printk("%s: Setting MAC address to %pM\n",
Johannes Berge1749612008-10-27 15:59:26 -07001783 dev->name, dev->dev_addr);
1784
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 /* set the Ethernet address */
Joe Perches204a38a2012-05-18 12:56:27 +00001786 for (i = 0; i < ETH_ALEN / 2; i++)
Joe Perchesca034bc2012-05-18 12:56:29 +00001787 writereg(dev, PP_IA + i * 2,
1788 (dev->dev_addr[i * 2] |
1789 (dev->dev_addr[i * 2 + 1] << 8)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790
1791 return 0;
1792}
1793
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001794#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
1796static struct net_device *dev_cs89x0;
1797
Joe Perches204a38a2012-05-18 12:56:27 +00001798/* Support the 'debug' module parm even if we're compiled for non-debug to
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001799 * avoid breaking someone's startup scripts
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 */
1801
1802static int io;
1803static int irq;
1804static int debug;
1805static char media[8];
Joe Perches204a38a2012-05-18 12:56:27 +00001806static int duplex = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
1808static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */
1809static int dma;
Joe Perches204a38a2012-05-18 12:56:27 +00001810static int dmasize = 16; /* or 64 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
1812module_param(io, int, 0);
1813module_param(irq, int, 0);
1814module_param(debug, int, 0);
1815module_param_string(media, media, sizeof(media), 0);
1816module_param(duplex, int, 0);
1817module_param(dma , int, 0);
1818module_param(dmasize , int, 0);
1819module_param(use_dma , int, 0);
1820MODULE_PARM_DESC(io, "cs89x0 I/O base address");
1821MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
1822#if DEBUGGING
1823MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
1824#else
1825MODULE_PARM_DESC(debug, "(ignored)");
1826#endif
1827MODULE_PARM_DESC(media, "Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)");
1828/* No other value than -1 for duplex seems to be currently interpreted */
1829MODULE_PARM_DESC(duplex, "(ignored)");
1830#if ALLOW_DMA
1831MODULE_PARM_DESC(dma , "cs89x0 ISA DMA channel; ignored if use_dma=0");
1832MODULE_PARM_DESC(dmasize , "cs89x0 DMA size in kB (16,64); ignored if use_dma=0");
1833MODULE_PARM_DESC(use_dma , "cs89x0 using DMA (0-1)");
1834#else
1835MODULE_PARM_DESC(dma , "(ignored)");
1836MODULE_PARM_DESC(dmasize , "(ignored)");
1837MODULE_PARM_DESC(use_dma , "(ignored)");
1838#endif
1839
Francois Camie1f8e872008-10-15 22:01:59 -07001840MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841MODULE_LICENSE("GPL");
1842
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843/*
Joe Perches204a38a2012-05-18 12:56:27 +00001844 * media=t - specify media type
1845 * or media=2
1846 * or media=aui
1847 * or medai=auto
1848 * duplex=0 - specify forced half/full/autonegotiate duplex
1849 * debug=# - debug level
1850 *
1851 * Default Chip Configuration:
1852 * DMA Burst = enabled
1853 * IOCHRDY Enabled = enabled
1854 * UseSA = enabled
1855 * CS8900 defaults to half-duplex if not specified on command-line
1856 * CS8920 defaults to autoneg if not specified on command-line
1857 * Use reset defaults for other config parameters
1858 *
1859 * Assumptions:
1860 * media type specified is supported (circuitry is present)
1861 * if memory address is > 1MB, then required mem decode hw is present
1862 * if 10B-2, then agent other than driver will enable DC/DC converter
1863 * (hw or software util)
1864 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
Andrew Mortone26c1292006-08-14 22:59:59 -07001866int __init init_module(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867{
1868 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
1869 struct net_local *lp;
1870 int ret = 0;
1871
1872#if DEBUGGING
1873 net_debug = debug;
1874#else
1875 debug = 0;
1876#endif
1877 if (!dev)
1878 return -ENOMEM;
1879
1880 dev->irq = irq;
1881 dev->base_addr = io;
1882 lp = netdev_priv(dev);
1883
1884#if ALLOW_DMA
1885 if (use_dma) {
1886 lp->use_dma = use_dma;
1887 lp->dma = dma;
1888 lp->dmasize = dmasize;
1889 }
1890#endif
1891
1892 spin_lock_init(&lp->lock);
1893
Joe Perches204a38a2012-05-18 12:56:27 +00001894 /* boy, they'd better get these right */
1895 if (!strcmp(media, "rj45"))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
1897 else if (!strcmp(media, "aui"))
1898 lp->adapter_cnf = A_CNF_MEDIA_AUI | A_CNF_AUI;
1899 else if (!strcmp(media, "bnc"))
1900 lp->adapter_cnf = A_CNF_MEDIA_10B_2 | A_CNF_10B_2;
1901 else
1902 lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
1903
Joe Perches204a38a2012-05-18 12:56:27 +00001904 if (duplex == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 lp->auto_neg_cnf = AUTO_NEG_ENABLE;
1906
Joe Perches204a38a2012-05-18 12:56:27 +00001907 if (io == 0) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001908 pr_err("Module autoprobing not allowed\n");
1909 pr_err("Append io=0xNNN\n");
Joe Perches204a38a2012-05-18 12:56:27 +00001910 ret = -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 goto out;
Joe Perches204a38a2012-05-18 12:56:27 +00001912 } else if (io <= 0x1ff) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 ret = -ENXIO;
1914 goto out;
1915 }
1916
1917#if ALLOW_DMA
1918 if (use_dma && dmasize != 16 && dmasize != 64) {
Joe Perchesdd92b9a2012-05-18 12:56:28 +00001919 pr_err("dma size must be either 16K or 64K, not %dK\n",
1920 dmasize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 ret = -EPERM;
1922 goto out;
1923 }
1924#endif
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001925 ret = cs89x0_ioport_probe(dev, io, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 if (ret)
1927 goto out;
1928
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 dev_cs89x0 = dev;
1930 return 0;
1931out:
1932 free_netdev(dev);
1933 return ret;
1934}
1935
Al Viroafc8eb42006-06-14 18:50:53 -04001936void __exit
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937cleanup_module(void)
1938{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001939 struct net_local *lp = netdev_priv(dev_cs89x0);
1940
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 unregister_netdev(dev_cs89x0);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001942 iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
1943 ioport_unmap(lp->virt_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
1945 free_netdev(dev_cs89x0);
1946}
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001947#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
1948
1949#ifdef CONFIG_CS89x0_PLATFORM
1950static int __init cs89x0_platform_probe(struct platform_device *pdev)
1951{
1952 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
1953 struct net_local *lp;
1954 struct resource *mem_res;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001955 void __iomem *virt_addr;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001956 int err;
1957
1958 if (!dev)
1959 return -ENOMEM;
1960
1961 lp = netdev_priv(dev);
1962
1963 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1964 dev->irq = platform_get_irq(pdev, 0);
1965 if (mem_res == NULL || dev->irq <= 0) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001966 dev_warn(&dev->dev, "memory/interrupt resource missing\n");
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001967 err = -ENXIO;
1968 goto free;
1969 }
1970
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001971 lp->size = resource_size(mem_res);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001972 if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001973 dev_warn(&dev->dev, "request_mem_region() failed\n");
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001974 err = -EBUSY;
1975 goto free;
1976 }
1977
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001978 virt_addr = ioremap(mem_res->start, lp->size);
1979 if (!virt_addr) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001980 dev_warn(&dev->dev, "ioremap() failed\n");
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001981 err = -ENOMEM;
1982 goto release;
1983 }
1984
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001985 err = cs89x0_probe1(dev, virt_addr, 0);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001986 if (err) {
Joe Perchesca034bc2012-05-18 12:56:29 +00001987 dev_warn(&dev->dev, "no cs8900 or cs8920 detected\n");
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001988 goto unmap;
1989 }
1990
1991 platform_set_drvdata(pdev, dev);
1992 return 0;
1993
1994unmap:
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001995 iounmap(virt_addr);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001996release:
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001997 release_mem_region(mem_res->start, lp->size);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001998free:
1999 free_netdev(dev);
2000 return err;
2001}
2002
2003static int cs89x0_platform_remove(struct platform_device *pdev)
2004{
2005 struct net_device *dev = platform_get_drvdata(pdev);
2006 struct net_local *lp = netdev_priv(dev);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00002007 struct resource *mem_res;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01002008
Joe Perches204a38a2012-05-18 12:56:27 +00002009 /* This platform_get_resource() call will not return NULL, because
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00002010 * the same call in cs89x0_platform_probe() has returned a non NULL
2011 * value.
2012 */
2013 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01002014 unregister_netdev(dev);
2015 iounmap(lp->virt_addr);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00002016 release_mem_region(mem_res->start, lp->size);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01002017 free_netdev(dev);
2018 return 0;
2019}
2020
2021static struct platform_driver cs89x0_driver = {
2022 .driver = {
2023 .name = DRV_NAME,
2024 .owner = THIS_MODULE,
2025 },
2026 .remove = cs89x0_platform_remove,
2027};
2028
2029static int __init cs89x0_init(void)
2030{
2031 return platform_driver_probe(&cs89x0_driver, cs89x0_platform_probe);
2032}
2033
2034module_init(cs89x0_init);
2035
2036static void __exit cs89x0_cleanup(void)
2037{
2038 platform_driver_unregister(&cs89x0_driver);
2039}
2040
2041module_exit(cs89x0_cleanup);
2042
2043#endif /* CONFIG_CS89x0_PLATFORM */