aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/arm/ether3.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/net/arm/ether3.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/net/arm/ether3.c')
-rw-r--r--drivers/net/arm/ether3.c918
1 files changed, 918 insertions, 0 deletions
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
new file mode 100644
index 00000000000..44a8746f401
--- /dev/null
+++ b/drivers/net/arm/ether3.c
@@ -0,0 +1,918 @@
1/*
2 * linux/drivers/acorn/net/ether3.c
3 *
4 * Copyright (C) 1995-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * SEEQ nq8005 ethernet driver for Acorn/ANT Ether3 card
11 * for Acorn machines
12 *
13 * By Russell King, with some suggestions from borris@ant.co.uk
14 *
15 * Changelog:
16 * 1.04 RMK 29/02/1996 Won't pass packets that are from our ethernet
17 * address up to the higher levels - they're
18 * silently ignored. I/F can now be put into
19 * multicast mode. Receiver routine optimised.
20 * 1.05 RMK 30/02/1996 Now claims interrupt at open when part of
21 * the kernel rather than when a module.
22 * 1.06 RMK 02/03/1996 Various code cleanups
23 * 1.07 RMK 13/10/1996 Optimised interrupt routine and transmit
24 * routines.
25 * 1.08 RMK 14/10/1996 Fixed problem with too many packets,
26 * prevented the kernel message about dropped
27 * packets appearing too many times a second.
28 * Now does not disable all IRQs, only the IRQ
29 * used by this card.
30 * 1.09 RMK 10/11/1996 Only enables TX irq when buffer space is low,
31 * but we still service the TX queue if we get a
32 * RX interrupt.
33 * 1.10 RMK 15/07/1997 Fixed autoprobing of NQ8004.
34 * 1.11 RMK 16/11/1997 Fixed autoprobing of NQ8005A.
35 * 1.12 RMK 31/12/1997 Removed reference to dev_tint for Linux 2.1.
36 * RMK 27/06/1998 Changed asm/delay.h to linux/delay.h.
37 * 1.13 RMK 29/06/1998 Fixed problem with transmission of packets.
38 * Chip seems to have a bug in, whereby if the
39 * packet starts two bytes from the end of the
40 * buffer, it corrupts the receiver chain, and
41 * never updates the transmit status correctly.
42 * 1.14 RMK 07/01/1998 Added initial code for ETHERB addressing.
43 * 1.15 RMK 30/04/1999 More fixes to the transmit routine for buggy
44 * hardware.
45 * 1.16 RMK 10/02/2000 Updated for 2.3.43
46 * 1.17 RMK 13/05/2000 Updated for 2.3.99-pre8
47 */
48
49#include <linux/module.h>
50#include <linux/kernel.h>
51#include <linux/types.h>
52#include <linux/fcntl.h>
53#include <linux/interrupt.h>
54#include <linux/ioport.h>
55#include <linux/in.h>
56#include <linux/slab.h>
57#include <linux/string.h>
58#include <linux/errno.h>
59#include <linux/netdevice.h>
60#include <linux/etherdevice.h>
61#include <linux/skbuff.h>
62#include <linux/device.h>
63#include <linux/init.h>
64#include <linux/delay.h>
65#include <linux/bitops.h>
66
67#include <asm/system.h>
68#include <asm/ecard.h>
69#include <asm/io.h>
70
71static char version[] __devinitdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
72
73#include "ether3.h"
74
75static unsigned int net_debug = NET_DEBUG;
76
77static void ether3_setmulticastlist(struct net_device *dev);
78static int ether3_rx(struct net_device *dev, unsigned int maxcnt);
79static void ether3_tx(struct net_device *dev);
80static int ether3_open (struct net_device *dev);
81static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
82static irqreturn_t ether3_interrupt (int irq, void *dev_id);
83static int ether3_close (struct net_device *dev);
84static void ether3_setmulticastlist (struct net_device *dev);
85static void ether3_timeout(struct net_device *dev);
86
87#define BUS_16 2
88#define BUS_8 1
89#define BUS_UNKNOWN 0
90
91/* --------------------------------------------------------------------------- */
92
93typedef enum {
94 buffer_write,
95 buffer_read
96} buffer_rw_t;
97
98/*
99 * ether3 read/write. Slow things down a bit...
100 * The SEEQ8005 doesn't like us writing to its registers
101 * too quickly.
102 */
103static inline void ether3_outb(int v, const void __iomem *r)
104{
105 writeb(v, r);
106 udelay(1);
107}
108
109static inline void ether3_outw(int v, const void __iomem *r)
110{
111 writew(v, r);
112 udelay(1);
113}
114#define ether3_inb(r) ({ unsigned int __v = readb((r)); udelay(1); __v; })
115#define ether3_inw(r) ({ unsigned int __v = readw((r)); udelay(1); __v; })
116
117static int
118ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start)
119{
120 int timeout = 1000;
121
122 ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1);
123 ether3_outw(priv(dev)->regs.command | CMD_FIFOWRITE, REG_COMMAND);
124
125 while ((ether3_inw(REG_STATUS) & STAT_FIFOEMPTY) == 0) {
126 if (!timeout--) {
127 printk("%s: setbuffer broken\n", dev->name);
128 priv(dev)->broken = 1;
129 return 1;
130 }
131 udelay(1);
132 }
133
134 if (read == buffer_read) {
135 ether3_outw(start, REG_DMAADDR);
136 ether3_outw(priv(dev)->regs.command | CMD_FIFOREAD, REG_COMMAND);
137 } else {
138 ether3_outw(priv(dev)->regs.command | CMD_FIFOWRITE, REG_COMMAND);
139 ether3_outw(start, REG_DMAADDR);
140 }
141 return 0;
142}
143
144/*
145 * write data to the buffer memory
146 */
147#define ether3_writebuffer(dev,data,length) \
148 writesw(REG_BUFWIN, (data), (length) >> 1)
149
150#define ether3_writeword(dev,data) \
151 writew((data), REG_BUFWIN)
152
153#define ether3_writelong(dev,data) { \
154 void __iomem *reg_bufwin = REG_BUFWIN; \
155 writew((data), reg_bufwin); \
156 writew((data) >> 16, reg_bufwin); \
157}
158
159/*
160 * read data from the buffer memory
161 */
162#define ether3_readbuffer(dev,data,length) \
163 readsw(REG_BUFWIN, (data), (length) >> 1)
164
165#define ether3_readword(dev) \
166 readw(REG_BUFWIN)
167
168#define ether3_readlong(dev) \
169 readw(REG_BUFWIN) | (readw(REG_BUFWIN) << 16)
170
171/*
172 * Switch LED off...
173 */
174static void ether3_ledoff(unsigned long data)
175{
176 struct net_device *dev = (struct net_device *)data;
177 ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2);
178}
179
180/*
181 * switch LED on...
182 */
183static inline void ether3_ledon(struct net_device *dev)
184{
185 del_timer(&priv(dev)->timer);
186 priv(dev)->timer.expires = jiffies + HZ / 50; /* leave on for 1/50th second */
187 priv(dev)->timer.data = (unsigned long)dev;
188 priv(dev)->timer.function = ether3_ledoff;
189 add_timer(&priv(dev)->timer);
190 if (priv(dev)->regs.config2 & CFG2_CTRLO)
191 ether3_outw(priv(dev)->regs.config2 &= ~CFG2_CTRLO, REG_CONFIG2);
192}
193
194/*
195 * Read the ethernet address string from the on board rom.
196 * This is an ascii string!!!
197 */
198static int __devinit
199ether3_addr(char *addr, struct expansion_card *ec)
200{
201 struct in_chunk_dir cd;
202 char *s;
203
204 if (ecard_readchunk(&cd, ec, 0xf5, 0) && (s = strchr(cd.d.string, '('))) {
205 int i;
206 for (i = 0; i<6; i++) {
207 addr[i] = simple_strtoul(s + 1, &s, 0x10);
208 if (*s != (i==5?')' : ':' ))
209 break;
210 }
211 if (i == 6)
212 return 0;
213 }