blob: 41c8ac92080bcf4d81bf20b3c24c8f469f1ceaf5 [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
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010049#include <linux/module.h>
50#include <linux/printk.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <linux/errno.h>
52#include <linux/netdevice.h>
53#include <linux/etherdevice.h>
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010054#include <linux/platform_device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055#include <linux/kernel.h>
56#include <linux/types.h>
57#include <linux/fcntl.h>
58#include <linux/interrupt.h>
59#include <linux/ioport.h>
60#include <linux/in.h>
61#include <linux/skbuff.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070062#include <linux/spinlock.h>
63#include <linux/string.h>
64#include <linux/init.h>
65#include <linux/bitops.h>
66#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090067#include <linux/gfp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#include <asm/io.h>
Al Viro7625d482005-09-26 05:25:59 +010070#include <asm/irq.h>
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010071#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070072#if ALLOW_DMA
73#include <asm/dma.h>
74#endif
75
76#include "cs89x0.h"
77
78static char version[] __initdata =
Joe Perches204a38a2012-05-18 12:56:27 +000079 "cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
81#define DRV_NAME "cs89x0"
82
83/* First, a few definitions that the brave might change.
Joe Perches204a38a2012-05-18 12:56:27 +000084 * A zero-terminated list of I/O addresses to be probed. Some special flags..
85 * Addr & 1 = Read back the address port, look for signature and reset
86 * the page window before probing
87 * Addr & 3 = Reset the page window and probe
88 * The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,
89 * but it is possible that a Cirrus board could be plugged into the ISA
90 * slots.
91 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -040092/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
Joe Perches204a38a2012-05-18 12:56:27 +000093 * them to system IRQ numbers. This mapping is card specific and is set to
94 * the configuration of the Cirrus Eval board for this chip.
95 */
Christoph Eggeref3cf9f2010-07-14 13:40:36 -070096#if defined(CONFIG_MACH_IXDP2351)
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +010097#define CS89x0_NONISA_IRQ
Leonardo Potenzaa80763c2008-02-17 18:23:15 +010098static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
Deepak Saxena9c878962006-01-14 13:21:18 -080099static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100#elif defined(CONFIG_ARCH_IXDP2X01)
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100101#define CS89x0_NONISA_IRQ
Leonardo Potenzaa80763c2008-02-17 18:23:15 +0100102static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
104#else
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100105#ifndef CONFIG_CS89x0_PLATFORM
Leonardo Potenzaa80763c2008-02-17 18:23:15 +0100106static unsigned int netcard_portlist[] __used __initdata =
Joe Perches204a38a2012-05-18 12:56:27 +0000107{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
108static unsigned int cs8900_irq_map[] = {10, 11, 12, 5};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109#endif
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100110#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112#if DEBUGGING
113static unsigned int net_debug = DEBUGGING;
114#else
115#define net_debug 0 /* gcc will remove all the debug code for us */
116#endif
117
118/* The number of low I/O ports used by the ethercard. */
119#define NETCARD_IO_EXTENT 16
120
121/* we allow the user to override various values normally set in the EEPROM */
122#define FORCE_RJ45 0x0001 /* pick one of these three */
123#define FORCE_AUI 0x0002
124#define FORCE_BNC 0x0004
125
126#define FORCE_AUTO 0x0010 /* pick one of these three */
127#define FORCE_HALF 0x0020
128#define FORCE_FULL 0x0030
129
130/* Information that need to be kept for each board. */
131struct net_local {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 int chip_type; /* one of: CS8900, CS8920, CS8920M */
133 char chip_revision; /* revision letter of the chip ('A'...) */
134 int send_cmd; /* the proper send command: TX_NOW, TX_AFTER_381, or TX_AFTER_ALL */
135 int auto_neg_cnf; /* auto-negotiation word from EEPROM */
136 int adapter_cnf; /* adapter configuration from EEPROM */
137 int isa_config; /* ISA configuration from EEPROM */
138 int irq_map; /* IRQ map from EEPROM */
139 int rx_mode; /* what mode are we in? 0, RX_MULTCAST_ACCEPT, or RX_ALL_ACCEPT */
140 int curr_rx_cfg; /* a copy of PP_RxCFG */
141 int linectl; /* either 0 or LOW_RX_SQUELCH, depending on configuration. */
142 int send_underrun; /* keep track of how many underruns in a row we get */
143 int force; /* force various values; see FORCE* above. */
144 spinlock_t lock;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000145 void __iomem *virt_addr;/* CS89x0 virtual address. */
146 unsigned long size; /* Length of CS89x0 memory region. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147#if ALLOW_DMA
148 int use_dma; /* Flag: we're using dma */
149 int dma; /* DMA channel */
150 int dmasize; /* 16 or 64 */
151 unsigned char *dma_buff; /* points to the beginning of the buffer */
152 unsigned char *end_dma_buff; /* points to the end of the buffer */
153 unsigned char *rx_dma_ptr; /* points to the next packet */
154#endif
155};
156
157/* Index to functions, as function prototypes. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158static int net_open(struct net_device *dev);
Stephen Hemminger613573252009-08-31 19:50:58 +0000159static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
David Howells7d12e782006-10-05 14:55:46 +0100160static irqreturn_t net_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161static void set_multicast_list(struct net_device *dev);
162static void net_timeout(struct net_device *dev);
163static void net_rx(struct net_device *dev);
164static int net_close(struct net_device *dev);
165static struct net_device_stats *net_get_stats(struct net_device *dev);
166static void reset_chip(struct net_device *dev);
167static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer);
168static int get_eeprom_cksum(int off, int len, int *buffer);
169static int set_mac_address(struct net_device *dev, void *addr);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000170static void count_rx_errors(int status, struct net_device *dev);
Deepak Saxena6f519162005-09-09 13:02:07 -0700171#ifdef CONFIG_NET_POLL_CONTROLLER
172static void net_poll_controller(struct net_device *dev);
173#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174#if ALLOW_DMA
175static void get_dma_channel(struct net_device *dev);
176static void release_dma_buff(struct net_local *lp);
177#endif
178
179/* Example routines you must write ;->. */
180#define tx_done(dev) 1
181
182/*
183 * Permit 'cs89x0_dma=N' in the kernel boot environment
184 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000185#if !defined(MODULE)
186#if ALLOW_DMA
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187static int g_cs89x0_dma;
188
189static int __init dma_fn(char *str)
190{
Joe Perches204a38a2012-05-18 12:56:27 +0000191 g_cs89x0_dma = simple_strtol(str, NULL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 return 1;
193}
194
195__setup("cs89x0_dma=", dma_fn);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000196#endif /* ALLOW_DMA */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198static int g_cs89x0_media__force;
199
200static int __init media_fn(char *str)
201{
202 if (!strcmp(str, "rj45")) g_cs89x0_media__force = FORCE_RJ45;
203 else if (!strcmp(str, "aui")) g_cs89x0_media__force = FORCE_AUI;
204 else if (!strcmp(str, "bnc")) g_cs89x0_media__force = FORCE_BNC;
205 return 1;
206}
207
208__setup("cs89x0_media=", media_fn);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100209#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
Deepak Saxena9c878962006-01-14 13:21:18 -0800211#if defined(CONFIG_MACH_IXDP2351)
212static u16
213readword(unsigned long base_addr, int portno)
214{
215 return __raw_readw(base_addr + (portno << 1));
216}
217
218static void
219writeword(unsigned long base_addr, int portno, u16 value)
220{
221 __raw_writew(value, base_addr + (portno << 1));
222}
223#elif defined(CONFIG_ARCH_IXDP2X01)
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800224static u16
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800225readword(unsigned long base_addr, int portno)
226{
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800227 return __raw_readl(base_addr + (portno << 1));
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800228}
229
230static void
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800231writeword(unsigned long base_addr, int portno, u16 value)
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800232{
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800233 __raw_writel(value, base_addr + (portno << 1));
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800234}
Lennert Buytenhek3b68d702006-01-08 01:01:11 -0800235#endif
Lennert Buytenhek0d5affc2006-01-08 01:01:09 -0800236
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000237static void readwords(struct net_local *lp, int portno, void *buf, int length)
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800238{
239 u8 *buf8 = (u8 *)buf;
240
241 do {
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800242 u16 tmp16;
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800243
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000244 tmp16 = ioread16(lp->virt_addr + portno);
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800245 *buf8++ = (u8)tmp16;
246 *buf8++ = (u8)(tmp16 >> 8);
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800247 } while (--length);
248}
249
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000250static void writewords(struct net_local *lp, int portno, void *buf, int length)
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800251{
252 u8 *buf8 = (u8 *)buf;
253
254 do {
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800255 u16 tmp16;
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800256
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800257 tmp16 = *buf8++;
258 tmp16 |= (*buf8++) << 8;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000259 iowrite16(tmp16, lp->virt_addr + portno);
Lennert Buytenhek084f7462006-01-08 01:01:12 -0800260 } while (--length);
261}
262
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800263static u16
264readreg(struct net_device *dev, u16 regno)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000266 struct net_local *lp = netdev_priv(dev);
267
268 iowrite16(regno, lp->virt_addr + ADD_PORT);
269 return ioread16(lp->virt_addr + DATA_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270}
271
272static void
Lennert Buytenheka07f0db2006-01-14 13:21:17 -0800273writereg(struct net_device *dev, u16 regno, u16 value)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000275 struct net_local *lp = netdev_priv(dev);
276
277 iowrite16(regno, lp->virt_addr + ADD_PORT);
278 iowrite16(value, lp->virt_addr + DATA_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279}
280
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281static int __init
282wait_eeprom_ready(struct net_device *dev)
283{
284 int timeout = jiffies;
Joe Perches204a38a2012-05-18 12:56:27 +0000285 /* check to see if the EEPROM is ready,
286 * a timeout is used just in case EEPROM is ready when
287 * SI_BUSY in the PP_SelfST is clear
288 */
289 while (readreg(dev, PP_SelfST) & SI_BUSY)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 if (jiffies - timeout >= 40)
291 return -1;
292 return 0;
293}
294
295static int __init
296get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
297{
298 int i;
299
Joe Perches204a38a2012-05-18 12:56:27 +0000300 if (net_debug > 3) printk("EEPROM data from %x for %x:\n", off, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 for (i = 0; i < len; i++) {
302 if (wait_eeprom_ready(dev) < 0) return -1;
303 /* Now send the EEPROM read command and EEPROM location to read */
304 writereg(dev, PP_EECMD, (off + i) | EEPROM_READ_CMD);
305 if (wait_eeprom_ready(dev) < 0) return -1;
306 buffer[i] = readreg(dev, PP_EEData);
307 if (net_debug > 3) printk("%04x ", buffer[i]);
308 }
309 if (net_debug > 3) printk("\n");
Joe Perches204a38a2012-05-18 12:56:27 +0000310 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311}
312
313static int __init
314get_eeprom_cksum(int off, int len, int *buffer)
315{
316 int i, cksum;
317
318 cksum = 0;
319 for (i = 0; i < len; i++)
320 cksum += buffer[i];
321 cksum &= 0xffff;
322 if (cksum == 0)
323 return 0;
324 return -1;
325}
326
Deepak Saxena6f519162005-09-09 13:02:07 -0700327#ifdef CONFIG_NET_POLL_CONTROLLER
328/*
329 * Polling receive - used by netconsole and other diagnostic tools
330 * to allow network i/o with interrupts disabled.
331 */
332static void net_poll_controller(struct net_device *dev)
333{
334 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100335 net_interrupt(dev->irq, dev);
Deepak Saxena6f519162005-09-09 13:02:07 -0700336 enable_irq(dev->irq);
337}
338#endif
339
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000340static const struct net_device_ops net_ops = {
341 .ndo_open = net_open,
342 .ndo_stop = net_close,
343 .ndo_tx_timeout = net_timeout,
Joe Perches204a38a2012-05-18 12:56:27 +0000344 .ndo_start_xmit = net_send_packet,
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000345 .ndo_get_stats = net_get_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000346 .ndo_set_rx_mode = set_multicast_list,
Joe Perches204a38a2012-05-18 12:56:27 +0000347 .ndo_set_mac_address = set_mac_address,
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000348#ifdef CONFIG_NET_POLL_CONTROLLER
349 .ndo_poll_controller = net_poll_controller,
350#endif
351 .ndo_change_mtu = eth_change_mtu,
352 .ndo_validate_addr = eth_validate_addr,
353};
354
Joe Perches204a38a2012-05-18 12:56:27 +0000355/* This is the real probe routine.
356 * Linux has a history of friendly device probes on the ISA bus.
357 * A good device probes avoids doing writes, and
358 * verifies that the correct device exists and functions.
359 * Return 0 on success.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361static int __init
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000362cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363{
364 struct net_local *lp = netdev_priv(dev);
365 static unsigned version_printed;
366 int i;
Denis Vlasenko01bdc032005-07-31 22:34:50 -0700367 int tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 unsigned rev_type = 0;
369 int eeprom_buff[CHKSUM_LEN];
370 int retval;
371
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 /* Initialize the device structure. */
373 if (!modular) {
374 memset(lp, 0, sizeof(*lp));
375 spin_lock_init(&lp->lock);
376#ifndef MODULE
377#if ALLOW_DMA
378 if (g_cs89x0_dma) {
379 lp->use_dma = 1;
380 lp->dma = g_cs89x0_dma;
381 lp->dmasize = 16; /* Could make this an option... */
382 }
383#endif
384 lp->force = g_cs89x0_media__force;
385#endif
Joe Perches204a38a2012-05-18 12:56:27 +0000386 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000388 printk(KERN_DEBUG "PP_addr at %p[%x]: 0x%x\n",
389 ioaddr, ADD_PORT, ioread16(ioaddr + ADD_PORT));
390 iowrite16(PP_ChipID, ioaddr + ADD_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000392 tmp = ioread16(ioaddr + DATA_PORT);
Denis Vlasenko01bdc032005-07-31 22:34:50 -0700393 if (tmp != CHIP_EISA_ID_SIG) {
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000394 printk(KERN_DEBUG "%s: incorrect signature at %p[%x]: 0x%x!="
Joe Perches204a38a2012-05-18 12:56:27 +0000395 CHIP_EISA_ID_SIG_STR "\n",
396 dev->name, ioaddr, DATA_PORT, tmp);
397 retval = -ENODEV;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000398 goto out1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 }
400
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000401 lp->virt_addr = ioaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
403 /* get the chip type */
404 rev_type = readreg(dev, PRODUCT_ID_ADD);
Joe Perches204a38a2012-05-18 12:56:27 +0000405 lp->chip_type = rev_type & ~REVISON_BITS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
407
408 /* Check the chip type and revision in order to set the correct send command
Joe Perches204a38a2012-05-18 12:56:27 +0000409 CS8920 revision C and CS8900 revision F can use the faster send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 lp->send_cmd = TX_AFTER_381;
411 if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
412 lp->send_cmd = TX_NOW;
413 if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
414 lp->send_cmd = TX_NOW;
415
416 if (net_debug && version_printed++ == 0)
417 printk(version);
418
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000419 printk(KERN_INFO "%s: cs89%c0%s rev %c found at %p ",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 dev->name,
Joe Perches204a38a2012-05-18 12:56:27 +0000421 lp->chip_type == CS8900 ? '0' : '2',
422 lp->chip_type == CS8920M ? "M" : "",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 lp->chip_revision,
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000424 lp->virt_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
426 reset_chip(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400427
Joe Perches204a38a2012-05-18 12:56:27 +0000428 /* Here we read the current configuration of the chip.
429 * If there is no Extended EEPROM then the idea is to not disturb
430 * the chip configuration, it should have been correctly setup by
431 * automatic EEPROM read on reset. So, if the chip says it read
432 * the EEPROM the driver will always do *something* instead of
433 * complain that adapter_cnf is 0.
434 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435
Joe Perches204a38a2012-05-18 12:56:27 +0000436 if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
437 (EEPROM_OK|EEPROM_PRESENT)) {
438 /* Load the MAC. */
439 for (i = 0; i < ETH_ALEN / 2; i++) {
440 unsigned int Addr;
441 Addr = readreg(dev, PP_IA + i * 2);
442 dev->dev_addr[i * 2] = Addr & 0xFF;
443 dev->dev_addr[i * 2 + 1] = Addr >> 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400445
Joe Perches204a38a2012-05-18 12:56:27 +0000446 /* Load the Adapter Configuration.
447 * Note: Barring any more specific information from some
448 * other source (ie EEPROM+Schematics), we would not know
449 * how to operate a 10Base2 interface on the AUI port.
450 * However, since we do read the status of HCB1 and use
451 * settings that always result in calls to control_dc_dc(dev,0)
452 * a BNC interface should work if the enable pin
453 * (dc/dc converter) is on HCB1.
454 * It will be called AUI however.
455 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400456
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 lp->adapter_cnf = 0;
458 i = readreg(dev, PP_LineCTL);
459 /* Preserve the setting of the HCB1 pin. */
Joe Perches204a38a2012-05-18 12:56:27 +0000460 if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 lp->adapter_cnf |= A_CNF_DC_DC_POLARITY;
462 /* Save the sqelch bit */
463 if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH)
464 lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH;
465 /* Check if the card is in 10Base-t only mode */
466 if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0)
467 lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T;
468 /* Check if the card is in AUI only mode */
469 if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY)
470 lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI;
471 /* Check if the card is in Auto mode. */
472 if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET)
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400473 lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T |
Joe Perches204a38a2012-05-18 12:56:27 +0000474 A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400475
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 if (net_debug > 1)
477 printk(KERN_INFO "%s: PP_LineCTL=0x%x, adapter_cnf=0x%x\n",
Joe Perches204a38a2012-05-18 12:56:27 +0000478 dev->name, i, lp->adapter_cnf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
480 /* IRQ. Other chips already probe, see below. */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400481 if (lp->chip_type == CS8900)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400483
Joe Perches204a38a2012-05-18 12:56:27 +0000484 printk("[Cirrus EEPROM] ");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 }
486
Joe Perches204a38a2012-05-18 12:56:27 +0000487 printk("\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400488
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 /* First check to see if an EEPROM is attached. */
Christoph Eggeref3cf9f2010-07-14 13:40:36 -0700490
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
492 printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
Joe Perches204a38a2012-05-18 12:56:27 +0000493 else if (get_eeprom_data(dev, START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 printk(KERN_WARNING "\ncs89x0: EEPROM read failed, relying on command line.\n");
Joe Perches204a38a2012-05-18 12:56:27 +0000495 } else if (get_eeprom_cksum(START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 /* Check if the chip was able to read its own configuration starting
497 at 0 in the EEPROM*/
498 if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) !=
Joe Perches204a38a2012-05-18 12:56:27 +0000499 (EEPROM_OK | EEPROM_PRESENT))
500 printk(KERN_WARNING "cs89x0: Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400501
Joe Perches204a38a2012-05-18 12:56:27 +0000502 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 /* This reads an extended EEPROM that is not documented
Joe Perches204a38a2012-05-18 12:56:27 +0000504 * in the CS8900 datasheet.
505 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400506
Joe Perches204a38a2012-05-18 12:56:27 +0000507 /* get transmission control word but keep the autonegotiation bits */
508 if (!lp->auto_neg_cnf) lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
509 /* Store adapter configuration */
510 if (!lp->adapter_cnf) lp->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
511 /* Store ISA configuration */
512 lp->isa_config = eeprom_buff[ISA_CNF_OFFSET/2];
513 dev->mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514
Joe Perches204a38a2012-05-18 12:56:27 +0000515 /* eeprom_buff has 32-bit ints, so we can't just memcpy it */
516 /* store the initial memory base address */
517 for (i = 0; i < ETH_ALEN / 2; i++) {
518 dev->dev_addr[i * 2] = eeprom_buff[i];
519 dev->dev_addr[i * 2 + 1] = eeprom_buff[i] >> 8;
520 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 if (net_debug > 1)
522 printk(KERN_DEBUG "%s: new adapter_cnf: 0x%x\n",
Joe Perches204a38a2012-05-18 12:56:27 +0000523 dev->name, lp->adapter_cnf);
524 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525
Joe Perches204a38a2012-05-18 12:56:27 +0000526 /* allow them to force multiple transceivers. If they force multiple, autosense */
527 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 int count = 0;
529 if (lp->force & FORCE_RJ45) {lp->adapter_cnf |= A_CNF_10B_T; count++; }
Joe Perches204a38a2012-05-18 12:56:27 +0000530 if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_AUI; count++; }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_10B_2; count++; }
532 if (count > 1) {lp->adapter_cnf |= A_CNF_MEDIA_AUTO; }
533 else if (lp->force & FORCE_RJ45){lp->adapter_cnf |= A_CNF_MEDIA_10B_T; }
534 else if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_MEDIA_AUI; }
535 else if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_MEDIA_10B_2; }
Joe Perches204a38a2012-05-18 12:56:27 +0000536 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
538 if (net_debug > 1)
539 printk(KERN_DEBUG "%s: after force 0x%x, adapter_cnf=0x%x\n",
Joe Perches204a38a2012-05-18 12:56:27 +0000540 dev->name, lp->force, lp->adapter_cnf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
Joe Perches204a38a2012-05-18 12:56:27 +0000542 /* 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 -0700543
Joe Perches204a38a2012-05-18 12:56:27 +0000544 /* 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 -0700545
Joe Perches204a38a2012-05-18 12:56:27 +0000546 /* FIXME: we don't set the Ethernet address on the command line. Use
547 * ifconfig IFACE hw ether AABBCCDDEEFF
548 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550 printk(KERN_INFO "cs89x0 media %s%s%s",
Joe Perches204a38a2012-05-18 12:56:27 +0000551 (lp->adapter_cnf & A_CNF_10B_T) ? "RJ-45," : "",
552 (lp->adapter_cnf & A_CNF_AUI) ? "AUI," : "",
553 (lp->adapter_cnf & A_CNF_10B_2) ? "BNC," : "");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554
555 lp->irq_map = 0xffff;
556
557 /* If this is a CS8900 then no pnp soft */
558 if (lp->chip_type != CS8900 &&
559 /* Check if the ISA IRQ has been set */
Joe Perches204a38a2012-05-18 12:56:27 +0000560 (i = readreg(dev, PP_CS8920_ISAINT) & 0xff,
561 (i != 0 && i < CS8920_NO_INTS))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 if (!dev->irq)
563 dev->irq = i;
564 } else {
565 i = lp->isa_config & INT_NO_MASK;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100566#ifndef CONFIG_CS89x0_PLATFORM
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 if (lp->chip_type == CS8900) {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100568#ifdef CS89x0_NONISA_IRQ
Joe Perches204a38a2012-05-18 12:56:27 +0000569 i = cs8900_irq_map[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570#else
571 /* Translate the IRQ using the IRQ mapping table. */
Denis Chengff8ac602007-09-02 18:30:18 +0800572 if (i >= ARRAY_SIZE(cs8900_irq_map))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 printk("\ncs89x0: invalid ISA interrupt number %d\n", i);
574 else
575 i = cs8900_irq_map[i];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */
578 } else {
579 int irq_map_buff[IRQ_MAP_LEN/2];
580
581 if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA,
Joe Perches204a38a2012-05-18 12:56:27 +0000582 IRQ_MAP_LEN / 2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 irq_map_buff) >= 0) {
584 if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT)
Joe Perches204a38a2012-05-18 12:56:27 +0000585 lp->irq_map = (irq_map_buff[0] >> 8) | (irq_map_buff[1] << 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 }
587#endif
588 }
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +0100589#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 if (!dev->irq)
591 dev->irq = i;
592 }
593
594 printk(" IRQ %d", dev->irq);
595
596#if ALLOW_DMA
597 if (lp->use_dma) {
598 get_dma_channel(dev);
599 printk(", DMA %d", dev->dma);
600 }
601 else
602#endif
603 {
604 printk(", programmed I/O");
605 }
606
607 /* print the ethernet address. */
Johannes Berge1749612008-10-27 15:59:26 -0700608 printk(", MAC %pM", dev->dev_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Stephen Hemminger15d23e72009-03-26 15:11:43 +0000610 dev->netdev_ops = &net_ops;
611 dev->watchdog_timeo = HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613 printk("\n");
614 if (net_debug)
615 printk("cs89x0_probe1() successful\n");
b1fc5502005-05-12 20:11:55 -0400616
617 retval = register_netdev(dev);
618 if (retval)
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000619 goto out2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 return 0;
621out2:
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000622 iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623out1:
624 return retval;
625}
626
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000627#ifndef CONFIG_CS89x0_PLATFORM
628/*
629 * This function converts the I/O port addres used by the cs89x0_probe() and
630 * init_module() functions to the I/O memory address used by the
631 * cs89x0_probe1() function.
632 */
633static int __init
634cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular)
635{
636 struct net_local *lp = netdev_priv(dev);
637 int ret;
638 void __iomem *io_mem;
639
640 if (!lp)
641 return -ENOMEM;
642
643 dev->base_addr = ioport;
644
645 if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) {
646 ret = -EBUSY;
647 goto out;
648 }
649
650 io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT);
651 if (!io_mem) {
652 ret = -ENOMEM;
653 goto release;
654 }
655
656 /* if they give us an odd I/O address, then do ONE write to
Joe Perches204a38a2012-05-18 12:56:27 +0000657 * the address port, to get it back to address zero, where we
658 * expect to find the EISA signature word. An IO with a base of 0x3
659 * will skip the test for the ADD_PORT.
660 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000661 if (ioport & 1) {
662 if (net_debug > 1)
663 printk(KERN_INFO "%s: odd ioaddr 0x%lx\n",
664 dev->name,
665 ioport);
666 if ((ioport & 2) != 2)
667 if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) !=
668 ADD_SIG) {
669 printk(KERN_ERR "%s: bad signature 0x%x\n",
Joe Perches204a38a2012-05-18 12:56:27 +0000670 dev->name,
671 ioread16(io_mem + ADD_PORT));
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000672 ret = -ENODEV;
673 goto unmap;
674 }
675 }
676
677 ret = cs89x0_probe1(dev, io_mem, modular);
678 if (!ret)
679 goto out;
680unmap:
681 ioport_unmap(io_mem);
682release:
683 release_region(ioport, NETCARD_IO_EXTENT);
684out:
685 return ret;
686}
687
688#ifndef MODULE
689/* Check for a network adaptor of this type, and return '0' iff one exists.
Joe Perches204a38a2012-05-18 12:56:27 +0000690 * If dev->base_addr == 0, probe all likely locations.
691 * If dev->base_addr == 1, always return failure.
692 * If dev->base_addr == 2, allocate space for the device and return success
693 * (detachable devices only).
694 * Return 0 on success.
695 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000696
697struct net_device * __init cs89x0_probe(int unit)
698{
699 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
700 unsigned *port;
701 int err = 0;
702 int irq;
703 int io;
704
705 if (!dev)
706 return ERR_PTR(-ENODEV);
707
708 sprintf(dev->name, "eth%d", unit);
709 netdev_boot_setup_check(dev);
710 io = dev->base_addr;
711 irq = dev->irq;
712
713 if (net_debug)
714 printk(KERN_INFO "cs89x0:cs89x0_probe(0x%x)\n", io);
715
716 if (io > 0x1ff) { /* Check a single specified location. */
717 err = cs89x0_ioport_probe(dev, io, 0);
718 } else if (io != 0) { /* Don't probe at all. */
719 err = -ENXIO;
720 } else {
721 for (port = netcard_portlist; *port; port++) {
722 if (cs89x0_ioport_probe(dev, *port, 0) == 0)
723 break;
724 dev->irq = irq;
725 }
726 if (!*port)
727 err = -ENODEV;
728 }
729 if (err)
730 goto out;
731 return dev;
732out:
733 free_netdev(dev);
734 printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
735 return ERR_PTR(err);
736}
737#endif
738#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400739
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740/*********************************
741 * This page contains DMA routines
Joe Perches204a38a2012-05-18 12:56:27 +0000742 *********************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743
744#if ALLOW_DMA
745
746#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
747
748static void
749get_dma_channel(struct net_device *dev)
750{
751 struct net_local *lp = netdev_priv(dev);
752
753 if (lp->dma) {
754 dev->dma = lp->dma;
755 lp->isa_config |= ISA_RxDMA;
756 } else {
757 if ((lp->isa_config & ANY_ISA_DMA) == 0)
758 return;
759 dev->dma = lp->isa_config & DMA_NO_MASK;
760 if (lp->chip_type == CS8900)
761 dev->dma += 5;
762 if (dev->dma < 5 || dev->dma > 7) {
763 lp->isa_config &= ~ANY_ISA_DMA;
764 return;
765 }
766 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767}
768
769static void
770write_dma(struct net_device *dev, int chip_type, int dma)
771{
772 struct net_local *lp = netdev_priv(dev);
773 if ((lp->isa_config & ANY_ISA_DMA) == 0)
774 return;
775 if (chip_type == CS8900) {
776 writereg(dev, PP_CS8900_ISADMA, dma-5);
777 } else {
778 writereg(dev, PP_CS8920_ISADMA, dma);
779 }
780}
781
782static void
783set_dma_cfg(struct net_device *dev)
784{
785 struct net_local *lp = netdev_priv(dev);
786
787 if (lp->use_dma) {
788 if ((lp->isa_config & ANY_ISA_DMA) == 0) {
789 if (net_debug > 3)
790 printk("set_dma_cfg(): no DMA\n");
791 return;
792 }
793 if (lp->isa_config & ISA_RxDMA) {
794 lp->curr_rx_cfg |= RX_DMA_ONLY;
795 if (net_debug > 3)
796 printk("set_dma_cfg(): RX_DMA_ONLY\n");
797 } else {
798 lp->curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */
799 if (net_debug > 3)
800 printk("set_dma_cfg(): AUTO_RX_DMA\n");
801 }
802 }
803}
804
805static int
806dma_bufcfg(struct net_device *dev)
807{
808 struct net_local *lp = netdev_priv(dev);
809 if (lp->use_dma)
Joe Perches204a38a2012-05-18 12:56:27 +0000810 return (lp->isa_config & ANY_ISA_DMA) ? RX_DMA_ENBL : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 else
812 return 0;
813}
814
815static int
816dma_busctl(struct net_device *dev)
817{
818 int retval = 0;
819 struct net_local *lp = netdev_priv(dev);
820 if (lp->use_dma) {
821 if (lp->isa_config & ANY_ISA_DMA)
822 retval |= RESET_RX_DMA; /* Reset the DMA pointer */
823 if (lp->isa_config & DMA_BURST)
824 retval |= DMA_BURST_MODE; /* Does ISA config specify DMA burst ? */
825 if (lp->dmasize == 64)
826 retval |= RX_DMA_SIZE_64K; /* did they ask for 64K? */
827 retval |= MEMORY_ON; /* we need memory enabled to use DMA. */
828 }
829 return retval;
830}
831
832static void
833dma_rx(struct net_device *dev)
834{
835 struct net_local *lp = netdev_priv(dev);
836 struct sk_buff *skb;
837 int status, length;
838 unsigned char *bp = lp->rx_dma_ptr;
839
840 status = bp[0] + (bp[1]<<8);
841 length = bp[2] + (bp[3]<<8);
842 bp += 4;
843 if (net_debug > 5) {
Joe Perches204a38a2012-05-18 12:56:27 +0000844 printk("%s: receiving DMA packet at %lx, status %x, length %x\n",
845 dev->name, (unsigned long)bp, status, length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 }
847 if ((status & RX_OK) == 0) {
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000848 count_rx_errors(status, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 goto skip_this_frame;
850 }
851
852 /* Malloc up new buffer. */
Pradeep A Dalvi21a4e462012-02-05 02:50:10 +0000853 skb = netdev_alloc_skb(dev, length + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 if (skb == NULL) {
855 if (net_debug) /* I don't think we want to do this to a stressed system */
856 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000857 dev->stats.rx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
859 /* AKPM: advance bp to the next frame */
860skip_this_frame:
861 bp += (length + 3) & ~3;
862 if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024;
863 lp->rx_dma_ptr = bp;
864 return;
865 }
866 skb_reserve(skb, 2); /* longword align L3 header */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867
868 if (bp + length > lp->end_dma_buff) {
869 int semi_cnt = lp->end_dma_buff - bp;
Joe Perches204a38a2012-05-18 12:56:27 +0000870 memcpy(skb_put(skb, semi_cnt), bp, semi_cnt);
871 memcpy(skb_put(skb, length - semi_cnt), lp->dma_buff,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 length - semi_cnt);
873 } else {
Joe Perches204a38a2012-05-18 12:56:27 +0000874 memcpy(skb_put(skb, length), bp, length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 }
876 bp += (length + 3) & ~3;
877 if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024;
878 lp->rx_dma_ptr = bp;
879
880 if (net_debug > 3) {
Joe Perches204a38a2012-05-18 12:56:27 +0000881 printk("%s: received %d byte DMA packet of type %x\n",
882 dev->name, length,
883 (skb->data[ETH_ALEN + ETH_ALEN] << 8) | skb->data[ETH_ALEN + ETH_ALEN + 1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 }
Joe Perches204a38a2012-05-18 12:56:27 +0000885 skb->protocol = eth_type_trans(skb, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 netif_rx(skb);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +0000887 dev->stats.rx_packets++;
888 dev->stats.rx_bytes += length;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889}
890
891#endif /* ALLOW_DMA */
892
Hannes Ederdac499f2008-12-25 23:56:45 -0800893static void __init reset_chip(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894{
Gilles Chanteperdrix0ac4ed92008-09-26 15:44:43 +0100895#if !defined(CONFIG_MACH_MX31ADS)
Domenico Andreolid181a612011-03-14 03:46:53 +0000896#if !defined(CS89x0_NONISA_IRQ)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 struct net_local *lp = netdev_priv(dev);
Domenico Andreolid181a612011-03-14 03:46:53 +0000898#endif /* CS89x0_NONISA_IRQ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 int reset_start_time;
900
901 writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
902
903 /* wait 30 ms */
904 msleep(30);
905
Domenico Andreolid181a612011-03-14 03:46:53 +0000906#if !defined(CS89x0_NONISA_IRQ)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 if (lp->chip_type != CS8900) {
908 /* Hardware problem requires PNP registers to be reconfigured after a reset */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000909 iowrite16(PP_CS8920_ISAINT, lp->virt_addr + ADD_PORT);
910 iowrite8(dev->irq, lp->virt_addr + DATA_PORT);
911 iowrite8(0, lp->virt_addr + DATA_PORT + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +0000913 iowrite16(PP_CS8920_ISAMemB, lp->virt_addr + ADD_PORT);
914 iowrite8((dev->mem_start >> 16) & 0xff,
915 lp->virt_addr + DATA_PORT);
916 iowrite8((dev->mem_start >> 8) & 0xff,
917 lp->virt_addr + DATA_PORT + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 }
Domenico Andreolid181a612011-03-14 03:46:53 +0000919#endif /* CS89x0_NONISA_IRQ */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920
921 /* Wait until the chip is reset */
922 reset_start_time = jiffies;
Joe Perches204a38a2012-05-18 12:56:27 +0000923 while ((readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 ;
Gilles Chanteperdrix0ac4ed92008-09-26 15:44:43 +0100925#endif /* !CONFIG_MACH_MX31ADS */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926}
927
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400928
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929static void
930control_dc_dc(struct net_device *dev, int on_not_off)
931{
932 struct net_local *lp = netdev_priv(dev);
933 unsigned int selfcontrol;
934 int timenow = jiffies;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400935 /* control the DC to DC convertor in the SelfControl register.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 Note: This is hooked up to a general purpose pin, might not
937 always be a DC to DC convertor. */
938
939 selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
940 if (((lp->adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
941 selfcontrol |= HCB1;
942 else
943 selfcontrol &= ~HCB1;
944 writereg(dev, PP_SelfCTL, selfcontrol);
945
946 /* Wait for the DC/DC converter to power up - 500ms */
947 while (jiffies - timenow < HZ)
948 ;
949}
950
951#define DETECTED_NONE 0
952#define DETECTED_RJ45H 1
953#define DETECTED_RJ45F 2
954#define DETECTED_AUI 3
955#define DETECTED_BNC 4
956
957static int
958detect_tp(struct net_device *dev)
959{
960 struct net_local *lp = netdev_priv(dev);
961 int timenow = jiffies;
962 int fdx;
963
964 if (net_debug > 1) printk("%s: Attempting TP\n", dev->name);
965
Joe Perches204a38a2012-05-18 12:56:27 +0000966 /* If connected to another full duplex capable 10-Base-T card the link pulses
967 seem to be lost when the auto detect bit in the LineCTL is set.
968 To overcome this the auto detect bit will be cleared whilst testing the
969 10-Base-T interface. This would not be necessary for the sparrow chip but
970 is simpler to do it anyway. */
971 writereg(dev, PP_LineCTL, lp->linectl & ~AUI_ONLY);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 control_dc_dc(dev, 0);
973
Joe Perches204a38a2012-05-18 12:56:27 +0000974 /* Delay for the hardware to work out if the TP cable is present - 150ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 for (timenow = jiffies; jiffies - timenow < 15; )
Joe Perches204a38a2012-05-18 12:56:27 +0000976 ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 if ((readreg(dev, PP_LineST) & LINK_OK) == 0)
978 return DETECTED_NONE;
979
980 if (lp->chip_type == CS8900) {
Joe Perches204a38a2012-05-18 12:56:27 +0000981 switch (lp->force & 0xf0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982#if 0
Joe Perches204a38a2012-05-18 12:56:27 +0000983 case FORCE_AUTO:
984 printk("%s: cs8900 doesn't autonegotiate\n", dev->name);
985 return DETECTED_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986#endif
Joe Perches204a38a2012-05-18 12:56:27 +0000987 /* CS8900 doesn't support AUTO, change to HALF*/
988 case FORCE_AUTO:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 lp->force &= ~FORCE_AUTO;
Joe Perches204a38a2012-05-18 12:56:27 +0000990 lp->force |= FORCE_HALF;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 break;
992 case FORCE_HALF:
993 break;
Joe Perches204a38a2012-05-18 12:56:27 +0000994 case FORCE_FULL:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 writereg(dev, PP_TestCTL, readreg(dev, PP_TestCTL) | FDX_8900);
996 break;
Joe Perches204a38a2012-05-18 12:56:27 +0000997 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 fdx = readreg(dev, PP_TestCTL) & FDX_8900;
999 } else {
1000 switch (lp->force & 0xf0) {
1001 case FORCE_AUTO:
1002 lp->auto_neg_cnf = AUTO_NEG_ENABLE;
1003 break;
1004 case FORCE_HALF:
1005 lp->auto_neg_cnf = 0;
1006 break;
1007 case FORCE_FULL:
1008 lp->auto_neg_cnf = RE_NEG_NOW | ALLOW_FDX;
1009 break;
Joe Perches204a38a2012-05-18 12:56:27 +00001010 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011
1012 writereg(dev, PP_AutoNegCTL, lp->auto_neg_cnf & AUTO_NEG_MASK);
1013
1014 if ((lp->auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
Joe Perches204a38a2012-05-18 12:56:27 +00001015 printk(KERN_INFO "%s: negotiating duplex...\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 while (readreg(dev, PP_AutoNegST) & AUTO_NEG_BUSY) {
1017 if (jiffies - timenow > 4000) {
1018 printk(KERN_ERR "**** Full / half duplex auto-negotiation timed out ****\n");
1019 break;
1020 }
1021 }
1022 }
1023 fdx = readreg(dev, PP_AutoNegST) & FDX_ACTIVE;
1024 }
1025 if (fdx)
1026 return DETECTED_RJ45F;
1027 else
1028 return DETECTED_RJ45H;
1029}
1030
1031/* send a test packet - return true if carrier bits are ok */
1032static int
1033send_test_pkt(struct net_device *dev)
1034{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001035 struct net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
Joe Perches204a38a2012-05-18 12:56:27 +00001037 0, 46, /* A 46 in network order */
1038 0, 0, /* DSAP=0 & SSAP=0 fields */
1039 0xf3, 0 /* Control (Test Req + P bit set) */ };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 long timenow = jiffies;
1041
1042 writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);
1043
Joe Perches204a38a2012-05-18 12:56:27 +00001044 memcpy(test_packet, dev->dev_addr, ETH_ALEN);
1045 memcpy(test_packet + ETH_ALEN, dev->dev_addr, ETH_ALEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001047 iowrite16(TX_AFTER_ALL, lp->virt_addr + TX_CMD_PORT);
1048 iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050 /* Test to see if the chip has allocated memory for the packet */
1051 while (jiffies - timenow < 5)
1052 if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW)
1053 break;
1054 if (jiffies - timenow >= 5)
1055 return 0; /* this shouldn't happen */
1056
1057 /* Write the contents of the packet */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001058 writewords(lp, TX_FRAME_PORT, test_packet, (ETH_ZLEN+1) >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060 if (net_debug > 1) printk("Sending test packet ");
1061 /* wait a couple of jiffies for packet to be received */
1062 for (timenow = jiffies; jiffies - timenow < 3; )
Joe Perches204a38a2012-05-18 12:56:27 +00001063 ;
1064 if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
1065 if (net_debug > 1) printk("succeeded\n");
1066 return 1;
1067 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 if (net_debug > 1) printk("failed\n");
1069 return 0;
1070}
1071
1072
1073static int
1074detect_aui(struct net_device *dev)
1075{
1076 struct net_local *lp = netdev_priv(dev);
1077
1078 if (net_debug > 1) printk("%s: Attempting AUI\n", dev->name);
1079 control_dc_dc(dev, 0);
1080
Joe Perches204a38a2012-05-18 12:56:27 +00001081 writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
1083 if (send_test_pkt(dev))
1084 return DETECTED_AUI;
1085 else
1086 return DETECTED_NONE;
1087}
1088
1089static int
1090detect_bnc(struct net_device *dev)
1091{
1092 struct net_local *lp = netdev_priv(dev);
1093
1094 if (net_debug > 1) printk("%s: Attempting BNC\n", dev->name);
1095 control_dc_dc(dev, 1);
1096
Joe Perches204a38a2012-05-18 12:56:27 +00001097 writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
1099 if (send_test_pkt(dev))
1100 return DETECTED_BNC;
1101 else
1102 return DETECTED_NONE;
1103}
1104
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001105
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106static void
1107write_irq(struct net_device *dev, int chip_type, int irq)
1108{
1109 int i;
1110
1111 if (chip_type == CS8900) {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001112#ifndef CONFIG_CS89x0_PLATFORM
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 /* Search the mapping table for the corresponding IRQ pin. */
Denis Chengff8ac602007-09-02 18:30:18 +08001114 for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 if (cs8900_irq_map[i] == irq)
1116 break;
1117 /* Not found */
Denis Chengff8ac602007-09-02 18:30:18 +08001118 if (i == ARRAY_SIZE(cs8900_irq_map))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 i = 3;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001120#else
1121 /* INTRQ0 pin is used for interrupt generation. */
1122 i = 0;
1123#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 writereg(dev, PP_CS8900_ISAINT, i);
1125 } else {
1126 writereg(dev, PP_CS8920_ISAINT, irq);
1127 }
1128}
1129
1130/* Open/initialize the board. This is called (in the current kernel)
1131 sometime after booting when the 'ifconfig' program is run.
1132
1133 This routine should set everything up anew at each open, even
1134 registers that "should" only need to be set once at boot, so that
1135 there is non-reboot way to recover if something goes wrong.
Joe Perches204a38a2012-05-18 12:56:27 +00001136*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
1138/* AKPM: do we need to do any locking here? */
1139
1140static int
1141net_open(struct net_device *dev)
1142{
1143 struct net_local *lp = netdev_priv(dev);
1144 int result = 0;
1145 int i;
1146 int ret;
1147
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 if (dev->irq < 2) {
1149 /* Allow interrupts to be generated by the chip */
1150/* Cirrus' release had this: */
1151#if 0
Joe Perches204a38a2012-05-18 12:56:27 +00001152 writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153#endif
1154/* And 2.3.47 had this: */
1155 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
1156
1157 for (i = 2; i < CS8920_NO_INTS; i++) {
1158 if ((1 << i) & lp->irq_map) {
1159 if (request_irq(i, net_interrupt, 0, dev->name, dev) == 0) {
1160 dev->irq = i;
1161 write_irq(dev, lp->chip_type, i);
1162 /* writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); */
1163 break;
1164 }
1165 }
1166 }
1167
1168 if (i >= CS8920_NO_INTS) {
1169 writereg(dev, PP_BusCTL, 0); /* disable interrupts. */
1170 printk(KERN_ERR "cs89x0: can't get an interrupt\n");
1171 ret = -EAGAIN;
1172 goto bad_out;
1173 }
1174 }
1175 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001177#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 if (((1 << dev->irq) & lp->irq_map) == 0) {
1179 printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
Joe Perches204a38a2012-05-18 12:56:27 +00001180 dev->name, dev->irq, lp->irq_map);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 ret = -EAGAIN;
1182 goto bad_out;
1183 }
1184#endif
1185/* FIXME: Cirrus' release had this: */
Joe Perches204a38a2012-05-18 12:56:27 +00001186 writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187/* And 2.3.47 had this: */
1188#if 0
1189 writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
1190#endif
1191 write_irq(dev, lp->chip_type, dev->irq);
Joe Perchesa0607fd2009-11-18 23:29:17 -08001192 ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 if (ret) {
Mark Brown569b7892010-01-07 00:53:05 -08001194 printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 goto bad_out;
1196 }
1197 }
1198
1199#if ALLOW_DMA
1200 if (lp->use_dma) {
1201 if (lp->isa_config & ANY_ISA_DMA) {
1202 unsigned long flags;
1203 lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,
Joe Perches204a38a2012-05-18 12:56:27 +00001204 get_order(lp->dmasize * 1024));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
1206 if (!lp->dma_buff) {
1207 printk(KERN_ERR "%s: cannot get %dK memory for DMA\n", dev->name, lp->dmasize);
1208 goto release_irq;
1209 }
1210 if (net_debug > 1) {
Joe Perches204a38a2012-05-18 12:56:27 +00001211 printk("%s: dma %lx %lx\n",
1212 dev->name,
1213 (unsigned long)lp->dma_buff,
1214 (unsigned long)isa_virt_to_bus(lp->dma_buff));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 }
1216 if ((unsigned long) lp->dma_buff >= MAX_DMA_ADDRESS ||
1217 !dma_page_eq(lp->dma_buff, lp->dma_buff+lp->dmasize*1024-1)) {
1218 printk(KERN_ERR "%s: not usable as DMA buffer\n", dev->name);
1219 goto release_irq;
1220 }
1221 memset(lp->dma_buff, 0, lp->dmasize * 1024); /* Why? */
1222 if (request_dma(dev->dma, dev->name)) {
1223 printk(KERN_ERR "%s: cannot get dma channel %d\n", dev->name, dev->dma);
1224 goto release_irq;
1225 }
1226 write_dma(dev, lp->chip_type, dev->dma);
1227 lp->rx_dma_ptr = lp->dma_buff;
1228 lp->end_dma_buff = lp->dma_buff + lp->dmasize*1024;
1229 spin_lock_irqsave(&lp->lock, flags);
1230 disable_dma(dev->dma);
1231 clear_dma_ff(dev->dma);
Julia Lawallef0657c2009-07-06 19:09:50 -07001232 set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
1234 set_dma_count(dev->dma, lp->dmasize*1024);
1235 enable_dma(dev->dma);
1236 spin_unlock_irqrestore(&lp->lock, flags);
1237 }
1238 }
1239#endif /* ALLOW_DMA */
1240
1241 /* set the Ethernet address */
Joe Perches204a38a2012-05-18 12:56:27 +00001242 for (i = 0; i < ETH_ALEN / 2; i++)
1243 writereg(dev, PP_IA + i * 2, dev->dev_addr[i * 2] | (dev->dev_addr[i * 2 + 1] << 8));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
1245 /* while we're testing the interface, leave interrupts disabled */
1246 writereg(dev, PP_BusCTL, MEMORY_ON);
1247
1248 /* Set the LineCTL quintuplet based on adapter configuration read from EEPROM */
1249 if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) && (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH))
Joe Perches204a38a2012-05-18 12:56:27 +00001250 lp->linectl = LOW_RX_SQUELCH;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 else
Joe Perches204a38a2012-05-18 12:56:27 +00001252 lp->linectl = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
Joe Perches204a38a2012-05-18 12:56:27 +00001254 /* check to make sure that they have the "right" hardware available */
1255 switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break;
1257 case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break;
1258 case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
Joe Perches204a38a2012-05-18 12:56:27 +00001259 default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
1260 }
1261 if (!result) {
1262 printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name);
Wang Chen17a94402008-05-30 11:18:55 +08001263release_dma:
1264#if ALLOW_DMA
1265 free_dma(dev->dma);
Wang Chen17a94402008-05-30 11:18:55 +08001266release_irq:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 release_dma_buff(lp);
1268#endif
Joe Perches204a38a2012-05-18 12:56:27 +00001269 writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
1270 free_irq(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 ret = -EAGAIN;
1272 goto bad_out;
1273 }
1274
Joe Perches204a38a2012-05-18 12:56:27 +00001275 /* set the hardware to the configured choice */
1276 switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 case A_CNF_MEDIA_10B_T:
Joe Perches204a38a2012-05-18 12:56:27 +00001278 result = detect_tp(dev);
1279 if (result == DETECTED_NONE) {
1280 printk(KERN_WARNING "%s: 10Base-T (RJ-45) has no cable\n", dev->name);
1281 if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
1282 result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */
1283 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 break;
1285 case A_CNF_MEDIA_AUI:
Joe Perches204a38a2012-05-18 12:56:27 +00001286 result = detect_aui(dev);
1287 if (result == DETECTED_NONE) {
1288 printk(KERN_WARNING "%s: 10Base-5 (AUI) has no cable\n", dev->name);
1289 if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
1290 result = DETECTED_AUI; /* Yes! I don't care if I see a carrrier */
1291 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 break;
1293 case A_CNF_MEDIA_10B_2:
Joe Perches204a38a2012-05-18 12:56:27 +00001294 result = detect_bnc(dev);
1295 if (result == DETECTED_NONE) {
1296 printk(KERN_WARNING "%s: 10Base-2 (BNC) has no cable\n", dev->name);
1297 if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
1298 result = DETECTED_BNC; /* Yes! I don't care if I can xmit a packet */
1299 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 break;
1301 case A_CNF_MEDIA_AUTO:
1302 writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET);
1303 if (lp->adapter_cnf & A_CNF_10B_T)
1304 if ((result = detect_tp(dev)) != DETECTED_NONE)
1305 break;
1306 if (lp->adapter_cnf & A_CNF_AUI)
1307 if ((result = detect_aui(dev)) != DETECTED_NONE)
1308 break;
1309 if (lp->adapter_cnf & A_CNF_10B_2)
1310 if ((result = detect_bnc(dev)) != DETECTED_NONE)
1311 break;
1312 printk(KERN_ERR "%s: no media detected\n", dev->name);
Wang Chen17a94402008-05-30 11:18:55 +08001313 goto release_dma;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 }
Joe Perches204a38a2012-05-18 12:56:27 +00001315 switch (result) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 case DETECTED_NONE:
1317 printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name);
Wang Chen17a94402008-05-30 11:18:55 +08001318 goto release_dma;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 case DETECTED_RJ45H:
1320 printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name);
1321 break;
1322 case DETECTED_RJ45F:
1323 printk(KERN_INFO "%s: using full-duplex 10Base-T (RJ-45)\n", dev->name);
1324 break;
1325 case DETECTED_AUI:
1326 printk(KERN_INFO "%s: using 10Base-5 (AUI)\n", dev->name);
1327 break;
1328 case DETECTED_BNC:
1329 printk(KERN_INFO "%s: using 10Base-2 (BNC)\n", dev->name);
1330 break;
1331 }
1332
1333 /* Turn on both receive and transmit operations */
1334 writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
1335
1336 /* Receive only error free packets addressed to this card */
1337 lp->rx_mode = 0;
1338 writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
1339
1340 lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
1341
1342 if (lp->isa_config & STREAM_TRANSFER)
1343 lp->curr_rx_cfg |= RX_STREAM_ENBL;
1344#if ALLOW_DMA
1345 set_dma_cfg(dev);
1346#endif
1347 writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
1348
1349 writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
Joe Perches204a38a2012-05-18 12:56:27 +00001350 TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351
1352 writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
1353#if ALLOW_DMA
Joe Perches204a38a2012-05-18 12:56:27 +00001354 dma_bufcfg(dev) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355#endif
Joe Perches204a38a2012-05-18 12:56:27 +00001356 TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
1358 /* now that we've got our act together, enable everything */
1359 writereg(dev, PP_BusCTL, ENABLE_IRQ
Joe Perches204a38a2012-05-18 12:56:27 +00001360 | (dev->mem_start ? MEMORY_ON : 0) /* turn memory on */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361#if ALLOW_DMA
1362 | dma_busctl(dev)
1363#endif
Joe Perches204a38a2012-05-18 12:56:27 +00001364 );
1365 netif_start_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 if (net_debug > 1)
1367 printk("cs89x0: net_open() succeeded\n");
1368 return 0;
1369bad_out:
1370 return ret;
1371}
1372
1373static void net_timeout(struct net_device *dev)
1374{
1375 /* If we get here, some higher level has decided we are broken.
1376 There should really be a "kick me" function call instead. */
1377 if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
Joe Perches204a38a2012-05-18 12:56:27 +00001378 tx_done(dev) ? "IRQ conflict ?" : "network cable problem");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 /* Try to restart the adaptor. */
1380 netif_wake_queue(dev);
1381}
1382
Joe Perches204a38a2012-05-18 12:56:27 +00001383static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384{
1385 struct net_local *lp = netdev_priv(dev);
Dongdong Deng79fbe132009-07-12 20:27:06 +00001386 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387
1388 if (net_debug > 3) {
1389 printk("%s: sent %d byte packet of type %x\n",
Joe Perches204a38a2012-05-18 12:56:27 +00001390 dev->name, skb->len,
1391 (skb->data[ETH_ALEN + ETH_ALEN] << 8) | skb->data[ETH_ALEN + ETH_ALEN + 1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 }
1393
1394 /* keep the upload from being interrupted, since we
Joe Perches204a38a2012-05-18 12:56:27 +00001395 ask the chip to start transmitting before the
1396 whole packet has been completely uploaded. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
Dongdong Deng79fbe132009-07-12 20:27:06 +00001398 spin_lock_irqsave(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 netif_stop_queue(dev);
1400
1401 /* initiate a transmit sequence */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001402 iowrite16(lp->send_cmd, lp->virt_addr + TX_CMD_PORT);
1403 iowrite16(skb->len, lp->virt_addr + TX_LEN_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405 /* Test to see if the chip has allocated memory for the packet */
1406 if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
Joe Perches204a38a2012-05-18 12:56:27 +00001407 /* Gasp! It hasn't. But that shouldn't happen since
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 * we're waiting for TxOk, so return 1 and requeue this packet.
1409 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001410
Dongdong Deng79fbe132009-07-12 20:27:06 +00001411 spin_unlock_irqrestore(&lp->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 if (net_debug) printk("cs89x0: Tx buffer not free!\n");
Patrick McHardy5b548142009-06-12 06:22:29 +00001413 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 }
1415 /* Write the contents of the packet */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001416 writewords(lp, TX_FRAME_PORT, skb->data, (skb->len+1) >> 1);
Dongdong Deng79fbe132009-07-12 20:27:06 +00001417 spin_unlock_irqrestore(&lp->lock, flags);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001418 dev->stats.tx_bytes += skb->len;
Joe Perches204a38a2012-05-18 12:56:27 +00001419 dev_kfree_skb(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420
Joe Perches204a38a2012-05-18 12:56:27 +00001421 /* We DO NOT call netif_wake_queue() here.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 * We also DO NOT call netif_start_queue().
1423 *
1424 * Either of these would cause another bottom half run through
1425 * net_send_packet() before this packet has fully gone out. That causes
1426 * us to hit the "Gasp!" above and the send is rescheduled. it runs like
1427 * a dog. We just return and wait for the Tx completion interrupt handler
1428 * to restart the netdevice layer
1429 */
1430
Patrick McHardy6ed10652009-06-23 06:03:08 +00001431 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432}
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001433
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434/* The typical workload of the driver:
Joe Perches204a38a2012-05-18 12:56:27 +00001435 * Handle the network interface interrupts.
1436 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001437
David Howells7d12e782006-10-05 14:55:46 +01001438static irqreturn_t net_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439{
1440 struct net_device *dev = dev_id;
1441 struct net_local *lp;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001442 int status;
Joe Perches204a38a2012-05-18 12:56:27 +00001443 int handled = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 lp = netdev_priv(dev);
1446
1447 /* we MUST read all the events out of the ISQ, otherwise we'll never
Joe Perches204a38a2012-05-18 12:56:27 +00001448 * get interrupted again. As a consequence, we can't have any limit
1449 * on the number of times we loop in the interrupt handler. The
1450 * hardware guarantees that eventually we'll run out of events. Of
1451 * course, if you're on a slow machine, and packets are arriving
1452 * faster than you can read them off, you're screwed. Hasta la
1453 * vista, baby!
1454 */
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001455 while ((status = ioread16(lp->virt_addr + ISQ_PORT))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
1457 handled = 1;
Joe Perches204a38a2012-05-18 12:56:27 +00001458 switch (status & ISQ_EVENT_MASK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 case ISQ_RECEIVER_EVENT:
1460 /* Got a packet(s). */
1461 net_rx(dev);
1462 break;
1463 case ISQ_TRANSMITTER_EVENT:
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001464 dev->stats.tx_packets++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 netif_wake_queue(dev); /* Inform upper layers. */
Joe Perches204a38a2012-05-18 12:56:27 +00001466 if ((status & (TX_OK |
1467 TX_LOST_CRS |
1468 TX_SQE_ERROR |
1469 TX_LATE_COL |
1470 TX_16_COL)) != TX_OK) {
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001471 if ((status & TX_OK) == 0)
1472 dev->stats.tx_errors++;
1473 if (status & TX_LOST_CRS)
1474 dev->stats.tx_carrier_errors++;
1475 if (status & TX_SQE_ERROR)
1476 dev->stats.tx_heartbeat_errors++;
1477 if (status & TX_LATE_COL)
1478 dev->stats.tx_window_errors++;
1479 if (status & TX_16_COL)
1480 dev->stats.tx_aborted_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 }
1482 break;
1483 case ISQ_BUFFER_EVENT:
1484 if (status & READY_FOR_TX) {
1485 /* we tried to transmit a packet earlier,
Joe Perches204a38a2012-05-18 12:56:27 +00001486 * but inexplicably ran out of buffers.
1487 * That shouldn't happen since we only ever
1488 * load one packet. Shrug. Do the right
1489 * thing anyway.
1490 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 netif_wake_queue(dev); /* Inform upper layers. */
1492 }
1493 if (status & TX_UNDERRUN) {
1494 if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
Joe Perches204a38a2012-05-18 12:56:27 +00001495 lp->send_underrun++;
1496 if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
1497 else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 /* transmit cycle is done, although
Joe Perches204a38a2012-05-18 12:56:27 +00001499 * frame wasn't transmitted - this
1500 * avoids having to wait for the upper
1501 * layers to timeout on us, in the
1502 * event of a tx underrun
1503 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 netif_wake_queue(dev); /* Inform upper layers. */
Joe Perches204a38a2012-05-18 12:56:27 +00001505 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506#if ALLOW_DMA
1507 if (lp->use_dma && (status & RX_DMA)) {
1508 int count = readreg(dev, PP_DmaFrameCnt);
Joe Perches204a38a2012-05-18 12:56:27 +00001509 while (count) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 if (net_debug > 5)
1511 printk("%s: receiving %d DMA frames\n", dev->name, count);
Joe Perches204a38a2012-05-18 12:56:27 +00001512 if (net_debug > 2 && count > 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 printk("%s: receiving %d DMA frames\n", dev->name, count);
1514 dma_rx(dev);
1515 if (--count == 0)
1516 count = readreg(dev, PP_DmaFrameCnt);
1517 if (net_debug > 2 && count > 0)
1518 printk("%s: continuing with %d DMA frames\n", dev->name, count);
1519 }
1520 }
1521#endif
1522 break;
1523 case ISQ_RX_MISS_EVENT:
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001524 dev->stats.rx_missed_errors += (status >> 6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 break;
1526 case ISQ_TX_COL_EVENT:
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001527 dev->stats.collisions += (status >> 6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 break;
1529 }
1530 }
1531 return IRQ_RETVAL(handled);
1532}
1533
1534static void
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001535count_rx_errors(int status, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536{
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001537 dev->stats.rx_errors++;
1538 if (status & RX_RUNT)
1539 dev->stats.rx_length_errors++;
1540 if (status & RX_EXTRA_DATA)
1541 dev->stats.rx_length_errors++;
1542 if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA|RX_RUNT)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 /* per str 172 */
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001544 dev->stats.rx_crc_errors++;
1545 if (status & RX_DRIBBLE)
1546 dev->stats.rx_frame_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547}
1548
1549/* We have a good packet(s), get it/them out of the buffers. */
1550static void
1551net_rx(struct net_device *dev)
1552{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001553 struct net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 struct sk_buff *skb;
1555 int status, length;
1556
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001557 status = ioread16(lp->virt_addr + RX_FRAME_PORT);
1558 length = ioread16(lp->virt_addr + RX_FRAME_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
1560 if ((status & RX_OK) == 0) {
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001561 count_rx_errors(status, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 return;
1563 }
1564
1565 /* Malloc up new buffer. */
Pradeep A Dalvi21a4e462012-02-05 02:50:10 +00001566 skb = netdev_alloc_skb(dev, length + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 if (skb == NULL) {
1568#if 0 /* Again, this seems a cruel thing to do */
1569 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
1570#endif
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001571 dev->stats.rx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572 return;
1573 }
1574 skb_reserve(skb, 2); /* longword align L3 header */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001576 readwords(lp, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 if (length & 1)
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001578 skb->data[length-1] = ioread16(lp->virt_addr + RX_FRAME_PORT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
1580 if (net_debug > 3) {
Joe Perches204a38a2012-05-18 12:56:27 +00001581 printk("%s: received %d byte packet of type %x\n",
1582 dev->name, length,
1583 (skb->data[ETH_ALEN + ETH_ALEN] << 8) | skb->data[ETH_ALEN + ETH_ALEN + 1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 }
1585
Joe Perches204a38a2012-05-18 12:56:27 +00001586 skb->protocol = eth_type_trans(skb, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 netif_rx(skb);
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001588 dev->stats.rx_packets++;
1589 dev->stats.rx_bytes += length;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590}
1591
1592#if ALLOW_DMA
1593static void release_dma_buff(struct net_local *lp)
1594{
1595 if (lp->dma_buff) {
1596 free_pages((unsigned long)(lp->dma_buff), get_order(lp->dmasize * 1024));
1597 lp->dma_buff = NULL;
1598 }
1599}
1600#endif
1601
1602/* The inverse routine to net_open(). */
1603static int
1604net_close(struct net_device *dev)
1605{
1606#if ALLOW_DMA
1607 struct net_local *lp = netdev_priv(dev);
1608#endif
1609
1610 netif_stop_queue(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001611
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 writereg(dev, PP_RxCFG, 0);
1613 writereg(dev, PP_TxCFG, 0);
1614 writereg(dev, PP_BufCFG, 0);
1615 writereg(dev, PP_BusCTL, 0);
1616
1617 free_irq(dev->irq, dev);
1618
1619#if ALLOW_DMA
1620 if (lp->use_dma && lp->dma) {
1621 free_dma(dev->dma);
1622 release_dma_buff(lp);
1623 }
1624#endif
1625
1626 /* Update the statistics here. */
1627 return 0;
1628}
1629
Joe Perches204a38a2012-05-18 12:56:27 +00001630/* Get the current statistics.
1631 * This may be called with the card open or closed.
1632 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633static struct net_device_stats *
1634net_get_stats(struct net_device *dev)
1635{
1636 struct net_local *lp = netdev_priv(dev);
1637 unsigned long flags;
1638
1639 spin_lock_irqsave(&lp->lock, flags);
1640 /* Update the statistics from the device registers. */
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001641 dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
1642 dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 spin_unlock_irqrestore(&lp->lock, flags);
1644
Kulikov Vasiliy661a16c2010-07-05 02:13:15 +00001645 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646}
1647
1648static void set_multicast_list(struct net_device *dev)
1649{
1650 struct net_local *lp = netdev_priv(dev);
1651 unsigned long flags;
1652
1653 spin_lock_irqsave(&lp->lock, flags);
Joe Perches204a38a2012-05-18 12:56:27 +00001654 if (dev->flags&IFF_PROMISC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 {
1656 lp->rx_mode = RX_ALL_ACCEPT;
1657 }
Jiri Pirkoe1d44472010-02-17 11:09:31 +00001658 else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 {
1660 /* The multicast-accept list is initialized to accept-all, and we
1661 rely on higher-level filtering for now. */
1662 lp->rx_mode = RX_MULTCAST_ACCEPT;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001663 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 else
1665 lp->rx_mode = 0;
1666
1667 writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
1668
1669 /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
1670 writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
Joe Perches204a38a2012-05-18 12:56:27 +00001671 (lp->rx_mode == RX_ALL_ACCEPT ? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 spin_unlock_irqrestore(&lp->lock, flags);
1673}
1674
1675
1676static int set_mac_address(struct net_device *dev, void *p)
1677{
1678 int i;
1679 struct sockaddr *addr = p;
1680
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 if (netif_running(dev))
1682 return -EBUSY;
1683
1684 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1685
Johannes Berge1749612008-10-27 15:59:26 -07001686 if (net_debug)
1687 printk("%s: Setting MAC address to %pM.\n",
1688 dev->name, dev->dev_addr);
1689
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 /* set the Ethernet address */
Joe Perches204a38a2012-05-18 12:56:27 +00001691 for (i = 0; i < ETH_ALEN / 2; i++)
1692 writereg(dev, PP_IA + i * 2, dev->dev_addr[i * 2] | (dev->dev_addr[i * 2 + 1] << 8));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
1694 return 0;
1695}
1696
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001697#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
1699static struct net_device *dev_cs89x0;
1700
Joe Perches204a38a2012-05-18 12:56:27 +00001701/* Support the 'debug' module parm even if we're compiled for non-debug to
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001702 * avoid breaking someone's startup scripts
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 */
1704
1705static int io;
1706static int irq;
1707static int debug;
1708static char media[8];
Joe Perches204a38a2012-05-18 12:56:27 +00001709static int duplex = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710
1711static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */
1712static int dma;
Joe Perches204a38a2012-05-18 12:56:27 +00001713static int dmasize = 16; /* or 64 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
1715module_param(io, int, 0);
1716module_param(irq, int, 0);
1717module_param(debug, int, 0);
1718module_param_string(media, media, sizeof(media), 0);
1719module_param(duplex, int, 0);
1720module_param(dma , int, 0);
1721module_param(dmasize , int, 0);
1722module_param(use_dma , int, 0);
1723MODULE_PARM_DESC(io, "cs89x0 I/O base address");
1724MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
1725#if DEBUGGING
1726MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
1727#else
1728MODULE_PARM_DESC(debug, "(ignored)");
1729#endif
1730MODULE_PARM_DESC(media, "Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)");
1731/* No other value than -1 for duplex seems to be currently interpreted */
1732MODULE_PARM_DESC(duplex, "(ignored)");
1733#if ALLOW_DMA
1734MODULE_PARM_DESC(dma , "cs89x0 ISA DMA channel; ignored if use_dma=0");
1735MODULE_PARM_DESC(dmasize , "cs89x0 DMA size in kB (16,64); ignored if use_dma=0");
1736MODULE_PARM_DESC(use_dma , "cs89x0 using DMA (0-1)");
1737#else
1738MODULE_PARM_DESC(dma , "(ignored)");
1739MODULE_PARM_DESC(dmasize , "(ignored)");
1740MODULE_PARM_DESC(use_dma , "(ignored)");
1741#endif
1742
Francois Camie1f8e872008-10-15 22:01:59 -07001743MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744MODULE_LICENSE("GPL");
1745
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746/*
Joe Perches204a38a2012-05-18 12:56:27 +00001747 * media=t - specify media type
1748 * or media=2
1749 * or media=aui
1750 * or medai=auto
1751 * duplex=0 - specify forced half/full/autonegotiate duplex
1752 * debug=# - debug level
1753 *
1754 * Default Chip Configuration:
1755 * DMA Burst = enabled
1756 * IOCHRDY Enabled = enabled
1757 * UseSA = enabled
1758 * CS8900 defaults to half-duplex if not specified on command-line
1759 * CS8920 defaults to autoneg if not specified on command-line
1760 * Use reset defaults for other config parameters
1761 *
1762 * Assumptions:
1763 * media type specified is supported (circuitry is present)
1764 * if memory address is > 1MB, then required mem decode hw is present
1765 * if 10B-2, then agent other than driver will enable DC/DC converter
1766 * (hw or software util)
1767 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
Andrew Mortone26c1292006-08-14 22:59:59 -07001769int __init init_module(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770{
1771 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
1772 struct net_local *lp;
1773 int ret = 0;
1774
1775#if DEBUGGING
1776 net_debug = debug;
1777#else
1778 debug = 0;
1779#endif
1780 if (!dev)
1781 return -ENOMEM;
1782
1783 dev->irq = irq;
1784 dev->base_addr = io;
1785 lp = netdev_priv(dev);
1786
1787#if ALLOW_DMA
1788 if (use_dma) {
1789 lp->use_dma = use_dma;
1790 lp->dma = dma;
1791 lp->dmasize = dmasize;
1792 }
1793#endif
1794
1795 spin_lock_init(&lp->lock);
1796
Joe Perches204a38a2012-05-18 12:56:27 +00001797 /* boy, they'd better get these right */
1798 if (!strcmp(media, "rj45"))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
1800 else if (!strcmp(media, "aui"))
1801 lp->adapter_cnf = A_CNF_MEDIA_AUI | A_CNF_AUI;
1802 else if (!strcmp(media, "bnc"))
1803 lp->adapter_cnf = A_CNF_MEDIA_10B_2 | A_CNF_10B_2;
1804 else
1805 lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
1806
Joe Perches204a38a2012-05-18 12:56:27 +00001807 if (duplex == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 lp->auto_neg_cnf = AUTO_NEG_ENABLE;
1809
Joe Perches204a38a2012-05-18 12:56:27 +00001810 if (io == 0) {
1811 printk(KERN_ERR "cs89x0.c: Module autoprobing not allowed.\n");
1812 printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n");
1813 ret = -EPERM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 goto out;
Joe Perches204a38a2012-05-18 12:56:27 +00001815 } else if (io <= 0x1ff) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 ret = -ENXIO;
1817 goto out;
1818 }
1819
1820#if ALLOW_DMA
1821 if (use_dma && dmasize != 16 && dmasize != 64) {
1822 printk(KERN_ERR "cs89x0.c: dma size must be either 16K or 64K, not %dK\n", dmasize);
1823 ret = -EPERM;
1824 goto out;
1825 }
1826#endif
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001827 ret = cs89x0_ioport_probe(dev, io, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 if (ret)
1829 goto out;
1830
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 dev_cs89x0 = dev;
1832 return 0;
1833out:
1834 free_netdev(dev);
1835 return ret;
1836}
1837
Al Viroafc8eb42006-06-14 18:50:53 -04001838void __exit
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839cleanup_module(void)
1840{
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001841 struct net_local *lp = netdev_priv(dev_cs89x0);
1842
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 unregister_netdev(dev_cs89x0);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001844 iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
1845 ioport_unmap(lp->virt_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
1847 free_netdev(dev_cs89x0);
1848}
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001849#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
1850
1851#ifdef CONFIG_CS89x0_PLATFORM
1852static int __init cs89x0_platform_probe(struct platform_device *pdev)
1853{
1854 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
1855 struct net_local *lp;
1856 struct resource *mem_res;
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001857 void __iomem *virt_addr;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001858 int err;
1859
1860 if (!dev)
1861 return -ENOMEM;
1862
1863 lp = netdev_priv(dev);
1864
1865 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1866 dev->irq = platform_get_irq(pdev, 0);
1867 if (mem_res == NULL || dev->irq <= 0) {
1868 dev_warn(&dev->dev, "memory/interrupt resource missing.\n");
1869 err = -ENXIO;
1870 goto free;
1871 }
1872
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001873 lp->size = resource_size(mem_res);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001874 if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001875 dev_warn(&dev->dev, "request_mem_region() failed.\n");
1876 err = -EBUSY;
1877 goto free;
1878 }
1879
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001880 virt_addr = ioremap(mem_res->start, lp->size);
1881 if (!virt_addr) {
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001882 dev_warn(&dev->dev, "ioremap() failed.\n");
1883 err = -ENOMEM;
1884 goto release;
1885 }
1886
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001887 err = cs89x0_probe1(dev, virt_addr, 0);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001888 if (err) {
1889 dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n");
1890 goto unmap;
1891 }
1892
1893 platform_set_drvdata(pdev, dev);
1894 return 0;
1895
1896unmap:
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001897 iounmap(virt_addr);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001898release:
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001899 release_mem_region(mem_res->start, lp->size);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001900free:
1901 free_netdev(dev);
1902 return err;
1903}
1904
1905static int cs89x0_platform_remove(struct platform_device *pdev)
1906{
1907 struct net_device *dev = platform_get_drvdata(pdev);
1908 struct net_local *lp = netdev_priv(dev);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001909 struct resource *mem_res;
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001910
Joe Perches204a38a2012-05-18 12:56:27 +00001911 /* This platform_get_resource() call will not return NULL, because
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001912 * the same call in cs89x0_platform_probe() has returned a non NULL
1913 * value.
1914 */
1915 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001916 unregister_netdev(dev);
1917 iounmap(lp->virt_addr);
Jaccon Bastiaansen09dcd602012-05-17 07:11:42 +00001918 release_mem_region(mem_res->start, lp->size);
Jaccon Bastiaansene9460a92012-01-26 21:46:15 +01001919 free_netdev(dev);
1920 return 0;
1921}
1922
1923static struct platform_driver cs89x0_driver = {
1924 .driver = {
1925 .name = DRV_NAME,
1926 .owner = THIS_MODULE,
1927 },
1928 .remove = cs89x0_platform_remove,
1929};
1930
1931static int __init cs89x0_init(void)
1932{
1933 return platform_driver_probe(&cs89x0_driver, cs89x0_platform_probe);
1934}
1935
1936module_init(cs89x0_init);
1937
1938static void __exit cs89x0_cleanup(void)
1939{
1940 platform_driver_unregister(&cs89x0_driver);
1941}
1942
1943module_exit(cs89x0_cleanup);
1944
1945#endif /* CONFIG_CS89x0_PLATFORM */