diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/8390/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/Kconfig | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/Kconfig | 82 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/Makefile | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/ibmlana.c | 1075 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/ibmlana.h | 278 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/jazzsonic.c | 308 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/macsonic.c | 666 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/natsemi.c | 3370 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/ns83820.c | 2312 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/sonic.c | 742 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/sonic.h | 450 | ||||
-rw-r--r-- | drivers/net/ethernet/natsemi/xtsonic.c | 333 |
14 files changed, 9633 insertions, 4 deletions
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig index f1b9bddc1550..5d2169809b19 100644 --- a/drivers/net/ethernet/8390/Kconfig +++ b/drivers/net/ethernet/8390/Kconfig | |||
@@ -4,9 +4,10 @@ | |||
4 | 4 | ||
5 | config NET_VENDOR_8390 | 5 | config NET_VENDOR_8390 |
6 | bool "National Semi-conductor 8390 devices" | 6 | bool "National Semi-conductor 8390 devices" |
7 | depends on AMIGA_PCMCIA || PCI || SUPERH || ISA || MCA || EISA || \ | 7 | depends on NET_VENDOR_NATSEMI && (AMIGA_PCMCIA || PCI || SUPERH || \ |
8 | MAC || M32R || MACH_TX49XX || MCA_LEGACY || H8300 || \ | 8 | ISA || MCA || EISA || MAC || M32R || MACH_TX49XX || \ |
9 | ARM || MIPS || ZORRO || PCMCIA || EXPERIMENTAL | 9 | MCA_LEGACY || H8300 || ARM || MIPS || ZORRO || PCMCIA || \ |
10 | EXPERIMENTAL) | ||
10 | ---help--- | 11 | ---help--- |
11 | If you have a network (Ethernet) card belonging to this class, say Y | 12 | If you have a network (Ethernet) card belonging to this class, say Y |
12 | and read the Ethernet-HOWTO, available from | 13 | and read the Ethernet-HOWTO, available from |
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index c3c415d853b7..efc36651a2b9 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig | |||
@@ -12,7 +12,6 @@ menuconfig ETHERNET | |||
12 | if ETHERNET | 12 | if ETHERNET |
13 | 13 | ||
14 | source "drivers/net/ethernet/3com/Kconfig" | 14 | source "drivers/net/ethernet/3com/Kconfig" |
15 | source "drivers/net/ethernet/8390/Kconfig" | ||
16 | source "drivers/net/ethernet/amd/Kconfig" | 15 | source "drivers/net/ethernet/amd/Kconfig" |
17 | source "drivers/net/ethernet/apple/Kconfig" | 16 | source "drivers/net/ethernet/apple/Kconfig" |
18 | source "drivers/net/ethernet/broadcom/Kconfig" | 17 | source "drivers/net/ethernet/broadcom/Kconfig" |
@@ -26,6 +25,8 @@ source "drivers/net/ethernet/intel/Kconfig" | |||
26 | source "drivers/net/ethernet/i825xx/Kconfig" | 25 | source "drivers/net/ethernet/i825xx/Kconfig" |
27 | source "drivers/net/ethernet/mellanox/Kconfig" | 26 | source "drivers/net/ethernet/mellanox/Kconfig" |
28 | source "drivers/net/ethernet/myricom/Kconfig" | 27 | source "drivers/net/ethernet/myricom/Kconfig" |
28 | source "drivers/net/ethernet/natsemi/Kconfig" | ||
29 | source "drivers/net/ethernet/8390/Kconfig" | ||
29 | source "drivers/net/ethernet/pasemi/Kconfig" | 30 | source "drivers/net/ethernet/pasemi/Kconfig" |
30 | source "drivers/net/ethernet/qlogic/Kconfig" | 31 | source "drivers/net/ethernet/qlogic/Kconfig" |
31 | source "drivers/net/ethernet/racal/Kconfig" | 32 | source "drivers/net/ethernet/racal/Kconfig" |
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index b67b88d5afd9..668ca92b4863 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile | |||
@@ -17,6 +17,7 @@ obj-$(CONFIG_NET_VENDOR_INTEL) += intel/ | |||
17 | obj-$(CONFIG_NET_VENDOR_I825XX) += i825xx/ | 17 | obj-$(CONFIG_NET_VENDOR_I825XX) += i825xx/ |
18 | obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/ | 18 | obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/ |
19 | obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/ | 19 | obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/ |
20 | obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/ | ||
20 | obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ | 21 | obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ |
21 | obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ | 22 | obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ |
22 | obj-$(CONFIG_NET_VENDOR_RACAL) += racal/ | 23 | obj-$(CONFIG_NET_VENDOR_RACAL) += racal/ |
diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig new file mode 100644 index 000000000000..1e5c1e1ec79a --- /dev/null +++ b/drivers/net/ethernet/natsemi/Kconfig | |||
@@ -0,0 +1,82 @@ | |||
1 | # | ||
2 | # National Semi-conductor device configuration | ||
3 | # | ||
4 | |||
5 | config NET_VENDOR_NATSEMI | ||
6 | bool "National Semi-conductor devices" | ||
7 | depends on MCA || MAC || MACH_JAZZ || PCI || XTENSA_PLATFORM_XT2000 | ||
8 | ---help--- | ||
9 | If you have a network (Ethernet) card belonging to this class, say Y | ||
10 | and read the Ethernet-HOWTO, available from | ||
11 | <http://www.tldp.org/docs.html#howto>. | ||
12 | |||
13 | Note that the answer to this question doesn't directly affect the | ||
14 | kernel: saying N will just cause the configurator to skip all | ||
15 | the questions about National Semi-conductor devices. If you say Y, | ||
16 | you will be asked for your specific card in the following questions. | ||
17 | |||
18 | if NET_VENDOR_NATSEMI | ||
19 | |||
20 | config IBMLANA | ||
21 | tristate "IBM LAN Adapter/A support" | ||
22 | depends on MCA | ||
23 | ---help--- | ||
24 | This is a Micro Channel Ethernet adapter. You need to set | ||
25 | CONFIG_MCA to use this driver. It is both available as an in-kernel | ||
26 | driver and as a module. | ||
27 | |||
28 | To compile this driver as a module, choose M here. The only | ||
29 | currently supported card is the IBM LAN Adapter/A for Ethernet. It | ||
30 | will both support 16K and 32K memory windows, however a 32K window | ||
31 | gives a better security against packet losses. Usage of multiple | ||
32 | boards with this driver should be possible, but has not been tested | ||
33 | up to now due to lack of hardware. | ||
34 | |||
35 | config MACSONIC | ||
36 | tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)" | ||
37 | depends on MAC | ||
38 | ---help--- | ||
39 | Support for NatSemi SONIC based Ethernet devices. This includes | ||
40 | the onboard Ethernet in many Quadras as well as some LC-PDS, | ||
41 | a few Nubus and all known Comm Slot Ethernet cards. If you have | ||
42 | one of these say Y and read the Ethernet-HOWTO, available from | ||
43 | <http://www.tldp.org/docs.html#howto>. | ||
44 | |||
45 | To compile this driver as a module, choose M here. This module will | ||
46 | be called macsonic. | ||
47 | |||
48 | config MIPS_JAZZ_SONIC | ||
49 | tristate "MIPS JAZZ onboard SONIC Ethernet support" | ||
50 | depends on MACH_JAZZ | ||
51 | ---help--- | ||
52 | This is the driver for the onboard card of MIPS Magnum 4000, | ||
53 | Acer PICA, Olivetti M700-10 and a few other identical OEM systems. | ||
54 | |||
55 | config NATSEMI | ||
56 | tristate "National Semiconductor DP8381x series PCI Ethernet support" | ||
57 | depends on PCI | ||
58 | select CRC32 | ||
59 | ---help--- | ||
60 | This driver is for the National Semiconductor DP83810 series, | ||
61 | which is used in cards from PureData, NetGear, Linksys | ||
62 | and others, including the 83815 chip. | ||
63 | More specific information and updates are available from | ||
64 | <http://www.scyld.com/network/natsemi.html>. | ||
65 | |||
66 | config NS83820 | ||
67 | tristate "National Semiconductor DP83820 support" | ||
68 | depends on PCI | ||
69 | ---help--- | ||
70 | This is a driver for the National Semiconductor DP83820 series | ||
71 | of gigabit ethernet MACs. Cards using this chipset include | ||
72 | the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX, | ||
73 | SOHO-GA2000T, SOHO-GA2500T. The driver supports the use of | ||
74 | zero copy. | ||
75 | |||
76 | config XTENSA_XT2000_SONIC | ||
77 | tristate "Xtensa XT2000 onboard SONIC Ethernet support" | ||
78 | depends on XTENSA_PLATFORM_XT2000 | ||
79 | ---help--- | ||
80 | This is the driver for the onboard card of the Xtensa XT2000 board. | ||
81 | |||
82 | endif # NET_VENDOR_NATSEMI | ||
diff --git a/drivers/net/ethernet/natsemi/Makefile b/drivers/net/ethernet/natsemi/Makefile new file mode 100644 index 000000000000..9aa5dea52b3e --- /dev/null +++ b/drivers/net/ethernet/natsemi/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for the National Semi-conductor Sonic devices. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_IBMLANA) += ibmlana.o | ||
6 | obj-$(CONFIG_MACSONIC) += macsonic.o | ||
7 | obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o | ||
8 | obj-$(CONFIG_NATSEMI) += natsemi.o | ||
9 | obj-$(CONFIG_NS83820) += ns83820.o | ||
10 | obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o | ||
diff --git a/drivers/net/ethernet/natsemi/ibmlana.c b/drivers/net/ethernet/natsemi/ibmlana.c new file mode 100644 index 000000000000..a7d6cad32953 --- /dev/null +++ b/drivers/net/ethernet/natsemi/ibmlana.c | |||
@@ -0,0 +1,1075 @@ | |||
1 | /* | ||
2 | net-3-driver for the IBM LAN Adapter/A | ||
3 | |||
4 | This is an extension to the Linux operating system, and is covered by the | ||
5 | same GNU General Public License that covers that work. | ||
6 | |||
7 | Copyright 1999 by Alfred Arnold (alfred@ccac.rwth-aachen.de, | ||
8 | alfred.arnold@lancom.de) | ||
9 | |||
10 | This driver is based both on the SK_MCA driver, which is itself based on the | ||
11 | SK_G16 and 3C523 driver. | ||
12 | |||
13 | paper sources: | ||
14 | 'PC Hardware: Aufbau, Funktionsweise, Programmierung' by | ||
15 | Hans-Peter Messmer for the basic Microchannel stuff | ||
16 | |||
17 | 'Linux Geraetetreiber' by Allesandro Rubini, Kalle Dalheimer | ||
18 | for help on Ethernet driver programming | ||
19 | |||
20 | 'DP83934CVUL-20/25 MHz SONIC-T Ethernet Controller Datasheet' by National | ||
21 | Semiconductor for info on the MAC chip | ||
22 | |||
23 | 'LAN Technical Reference Ethernet Adapter Interface Version 1 Release 1.0 | ||
24 | Document Number SC30-3661-00' by IBM for info on the adapter itself | ||
25 | |||
26 | Also see http://www.national.com/analog | ||
27 | |||
28 | special acknowledgements to: | ||
29 | - Bob Eager for helping me out with documentation from IBM | ||
30 | - Jim Shorney for his endless patience with me while I was using | ||
31 | him as a beta tester to trace down the address filter bug ;-) | ||
32 | |||
33 | Missing things: | ||
34 | |||
35 | -> set debug level via ioctl instead of compile-time switches | ||
36 | -> I didn't follow the development of the 2.1.x kernels, so my | ||
37 | assumptions about which things changed with which kernel version | ||
38 | are probably nonsense | ||
39 | |||
40 | History: | ||
41 | Nov 6th, 1999 | ||
42 | startup from SK_MCA driver | ||
43 | Dec 6th, 1999 | ||
44 | finally got docs about the card. A big thank you to Bob Eager! | ||
45 | Dec 12th, 1999 | ||
46 | first packet received | ||
47 | Dec 13th, 1999 | ||
48 | recv queue done, tcpdump works | ||
49 | Dec 15th, 1999 | ||
50 | transmission part works | ||
51 | Dec 28th, 1999 | ||
52 | added usage of the isa_functions for Linux 2.3 . Things should | ||
53 | still work with 2.0.x.... | ||
54 | Jan 28th, 2000 | ||
55 | in Linux 2.2.13, the version.h file mysteriously didn't get | ||
56 | included. Added a workaround for this. Furthermore, it now | ||
57 | not only compiles as a modules ;-) | ||
58 | Jan 30th, 2000 | ||
59 | newer kernels automatically probe more than one board, so the | ||
60 | 'startslot' as a variable is also needed here | ||
61 | Apr 12th, 2000 | ||
62 | the interrupt mask register is not set 'hard' instead of individually | ||
63 | setting registers, since this seems to set bits that shouldn't be | ||
64 | set | ||
65 | May 21st, 2000 | ||
66 | reset interrupt status immediately after CAM load | ||
67 | add a recovery delay after releasing the chip's reset line | ||
68 | May 24th, 2000 | ||
69 | finally found the bug in the address filter setup - damned signed | ||
70 | chars! | ||
71 | June 1st, 2000 | ||
72 | corrected version codes, added support for the latest 2.3 changes | ||
73 | Oct 28th, 2002 | ||
74 | cleaned up for the 2.5 tree <alan@lxorguk.ukuu.org.uk> | ||
75 | |||
76 | *************************************************************************/ | ||
77 | |||
78 | #include <linux/kernel.h> | ||
79 | #include <linux/string.h> | ||
80 | #include <linux/errno.h> | ||
81 | #include <linux/ioport.h> | ||
82 | #include <linux/interrupt.h> | ||
83 | #include <linux/delay.h> | ||
84 | #include <linux/time.h> | ||
85 | #include <linux/mca.h> | ||
86 | #include <linux/module.h> | ||
87 | #include <linux/netdevice.h> | ||
88 | #include <linux/etherdevice.h> | ||
89 | #include <linux/if_ether.h> | ||
90 | #include <linux/skbuff.h> | ||
91 | #include <linux/bitops.h> | ||
92 | |||
93 | #include <asm/processor.h> | ||
94 | #include <asm/io.h> | ||
95 | |||
96 | #define _IBM_LANA_DRIVER_ | ||
97 | #include "ibmlana.h" | ||
98 | |||
99 | #undef DEBUG | ||
100 | |||
101 | #define DRV_NAME "ibmlana" | ||
102 | |||
103 | /* ------------------------------------------------------------------------ | ||
104 | * global static data - not more since we can handle multiple boards and | ||
105 | * have to pack all state info into the device struct! | ||
106 | * ------------------------------------------------------------------------ */ | ||
107 | |||
108 | static char *MediaNames[Media_Count] = { | ||
109 | "10BaseT", "10Base5", "Unknown", "10Base2" | ||
110 | }; | ||
111 | |||
112 | /* ------------------------------------------------------------------------ | ||
113 | * private subfunctions | ||
114 | * ------------------------------------------------------------------------ */ | ||
115 | |||
116 | #ifdef DEBUG | ||
117 | /* dump all registers */ | ||
118 | |||
119 | static void dumpregs(struct net_device *dev) | ||
120 | { | ||
121 | int z; | ||
122 | |||
123 | for (z = 0; z < 160; z += 2) { | ||
124 | if (!(z & 15)) | ||
125 | printk("REGS: %04x:", z); | ||
126 | printk(" %04x", inw(dev->base_addr + z)); | ||
127 | if ((z & 15) == 14) | ||
128 | printk("\n"); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* dump parts of shared memory - only needed during debugging */ | ||
133 | |||
134 | static void dumpmem(struct net_device *dev, u32 start, u32 len) | ||
135 | { | ||
136 | ibmlana_priv *priv = netdev_priv(dev); | ||
137 | int z; | ||
138 | |||
139 | printk("Address %04x:\n", start); | ||
140 | for (z = 0; z < len; z++) { | ||
141 | if ((z & 15) == 0) | ||
142 | printk("%04x:", z); | ||
143 | printk(" %02x", readb(priv->base + start + z)); | ||
144 | if ((z & 15) == 15) | ||
145 | printk("\n"); | ||
146 | } | ||
147 | if ((z & 15) != 0) | ||
148 | printk("\n"); | ||
149 | } | ||
150 | |||
151 | /* print exact time - ditto */ | ||
152 | |||
153 | static void PrTime(void) | ||
154 | { | ||
155 | struct timeval tv; | ||
156 | |||
157 | do_gettimeofday(&tv); | ||
158 | printk("%9d:%06d: ", (int) tv.tv_sec, (int) tv.tv_usec); | ||
159 | } | ||
160 | #endif /* DEBUG */ | ||
161 | |||
162 | /* deduce resources out of POS registers */ | ||
163 | |||
164 | static void getaddrs(struct mca_device *mdev, int *base, int *memlen, | ||
165 | int *iobase, int *irq, ibmlana_medium *medium) | ||
166 | { | ||
167 | u_char pos0, pos1; | ||
168 | |||
169 | pos0 = mca_device_read_stored_pos(mdev, 2); | ||
170 | pos1 = mca_device_read_stored_pos(mdev, 3); | ||
171 | |||
172 | *base = 0xc0000 + ((pos1 & 0xf0) << 9); | ||
173 | *memlen = (pos1 & 0x01) ? 0x8000 : 0x4000; | ||
174 | *iobase = (pos0 & 0xe0) << 7; | ||
175 | switch (pos0 & 0x06) { | ||
176 | case 0: | ||
177 | *irq = 5; | ||
178 | break; | ||
179 | case 2: | ||
180 | *irq = 15; | ||
181 | break; | ||
182 | case 4: | ||
183 | *irq = 10; | ||
184 | break; | ||
185 | case 6: | ||
186 | *irq = 11; | ||
187 | break; | ||
188 | } | ||
189 | *medium = (pos0 & 0x18) >> 3; | ||
190 | } | ||
191 | |||
192 | /* wait on register value with mask and timeout */ | ||
193 | |||
194 | static int wait_timeout(struct net_device *dev, int regoffs, u16 mask, | ||
195 | u16 value, int timeout) | ||
196 | { | ||
197 | unsigned long fin = jiffies + timeout; | ||
198 | |||
199 | while (time_before(jiffies,fin)) | ||
200 | if ((inw(dev->base_addr + regoffs) & mask) == value) | ||
201 | return 1; | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | |||
207 | /* reset the whole board */ | ||
208 | |||
209 | static void ResetBoard(struct net_device *dev) | ||
210 | { | ||
211 | unsigned char bcmval; | ||
212 | |||
213 | /* read original board control value */ | ||
214 | |||
215 | bcmval = inb(dev->base_addr + BCMREG); | ||
216 | |||
217 | /* set reset bit for a while */ | ||
218 | |||
219 | bcmval |= BCMREG_RESET; | ||
220 | outb(bcmval, dev->base_addr + BCMREG); | ||
221 | udelay(10); | ||
222 | bcmval &= ~BCMREG_RESET; | ||
223 | outb(bcmval, dev->base_addr + BCMREG); | ||
224 | |||
225 | /* switch over to RAM again */ | ||
226 | |||
227 | bcmval |= BCMREG_RAMEN | BCMREG_RAMWIN; | ||
228 | outb(bcmval, dev->base_addr + BCMREG); | ||
229 | } | ||
230 | |||
231 | /* calculate RAM layout & set up descriptors in RAM */ | ||
232 | |||
233 | static void InitDscrs(struct net_device *dev) | ||
234 | { | ||
235 | ibmlana_priv *priv = netdev_priv(dev); | ||
236 | u32 addr, baddr, raddr; | ||
237 | int z; | ||
238 | tda_t tda; | ||
239 | rda_t rda; | ||
240 | rra_t rra; | ||
241 | |||
242 | /* initialize RAM */ | ||
243 | |||
244 | memset_io(priv->base, 0xaa, | ||
245 | dev->mem_start - dev->mem_start); /* XXX: typo? */ | ||
246 | |||
247 | /* setup n TX descriptors - independent of RAM size */ | ||
248 | |||
249 | priv->tdastart = addr = 0; | ||
250 | priv->txbufstart = baddr = sizeof(tda_t) * TXBUFCNT; | ||
251 | for (z = 0; z < TXBUFCNT; z++) { | ||
252 | tda.status = 0; | ||
253 | tda.config = 0; | ||
254 | tda.length = 0; | ||
255 | tda.fragcount = 1; | ||
256 | tda.startlo = baddr; | ||
257 | tda.starthi = 0; | ||
258 | tda.fraglength = 0; | ||
259 | if (z == TXBUFCNT - 1) | ||
260 | tda.link = priv->tdastart; | ||
261 | else | ||
262 | tda.link = addr + sizeof(tda_t); | ||
263 | tda.link |= 1; | ||
264 | memcpy_toio(priv->base + addr, &tda, sizeof(tda_t)); | ||
265 | addr += sizeof(tda_t); | ||
266 | baddr += PKTSIZE; | ||
267 | } | ||
268 | |||
269 | /* calculate how many receive buffers fit into remaining memory */ | ||
270 | |||
271 | priv->rxbufcnt = (dev->mem_end - dev->mem_start - baddr) / (sizeof(rra_t) + sizeof(rda_t) + PKTSIZE); | ||
272 | |||
273 | /* calculate receive addresses */ | ||
274 | |||
275 | priv->rrastart = raddr = priv->txbufstart + (TXBUFCNT * PKTSIZE); | ||
276 | priv->rdastart = addr = priv->rrastart + (priv->rxbufcnt * sizeof(rra_t)); | ||
277 | priv->rxbufstart = baddr = priv->rdastart + (priv->rxbufcnt * sizeof(rda_t)); | ||
278 | |||
279 | for (z = 0; z < priv->rxbufcnt; z++) { | ||
280 | rra.startlo = baddr; | ||
281 | rra.starthi = 0; | ||
282 | rra.cntlo = PKTSIZE >> 1; | ||
283 | rra.cnthi = 0; | ||
284 | memcpy_toio(priv->base + raddr, &rra, sizeof(rra_t)); | ||
285 | |||
286 | rda.status = 0; | ||
287 | rda.length = 0; | ||
288 | rda.startlo = 0; | ||
289 | rda.starthi = 0; | ||
290 | rda.seqno = 0; | ||
291 | if (z < priv->rxbufcnt - 1) | ||
292 | rda.link = addr + sizeof(rda_t); | ||
293 | else | ||
294 | rda.link = 1; | ||
295 | rda.inuse = 1; | ||
296 | memcpy_toio(priv->base + addr, &rda, sizeof(rda_t)); | ||
297 | |||
298 | baddr += PKTSIZE; | ||
299 | raddr += sizeof(rra_t); | ||
300 | addr += sizeof(rda_t); | ||
301 | } | ||
302 | |||
303 | /* initialize current pointers */ | ||
304 | |||
305 | priv->nextrxdescr = 0; | ||
306 | priv->lastrxdescr = priv->rxbufcnt - 1; | ||
307 | priv->nexttxdescr = 0; | ||
308 | priv->currtxdescr = 0; | ||
309 | priv->txusedcnt = 0; | ||
310 | memset(priv->txused, 0, sizeof(priv->txused)); | ||
311 | } | ||
312 | |||
313 | /* set up Rx + Tx descriptors in SONIC */ | ||
314 | |||
315 | static int InitSONIC(struct net_device *dev) | ||
316 | { | ||
317 | ibmlana_priv *priv = netdev_priv(dev); | ||
318 | |||
319 | /* set up start & end of resource area */ | ||
320 | |||
321 | outw(0, SONIC_URRA); | ||
322 | outw(priv->rrastart, dev->base_addr + SONIC_RSA); | ||
323 | outw(priv->rrastart + (priv->rxbufcnt * sizeof(rra_t)), dev->base_addr + SONIC_REA); | ||
324 | outw(priv->rrastart, dev->base_addr + SONIC_RRP); | ||
325 | outw(priv->rrastart, dev->base_addr + SONIC_RWP); | ||
326 | |||
327 | /* set EOBC so that only one packet goes into one buffer */ | ||
328 | |||
329 | outw((PKTSIZE - 4) >> 1, dev->base_addr + SONIC_EOBC); | ||
330 | |||
331 | /* let SONIC read the first RRA descriptor */ | ||
332 | |||
333 | outw(CMDREG_RRRA, dev->base_addr + SONIC_CMDREG); | ||
334 | if (!wait_timeout(dev, SONIC_CMDREG, CMDREG_RRRA, 0, 2)) { | ||
335 | printk(KERN_ERR "%s: SONIC did not respond on RRRA command - giving up.", dev->name); | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | /* point SONIC to the first RDA */ | ||
340 | |||
341 | outw(0, dev->base_addr + SONIC_URDA); | ||
342 | outw(priv->rdastart, dev->base_addr + SONIC_CRDA); | ||
343 | |||
344 | /* set upper half of TDA address */ | ||
345 | |||
346 | outw(0, dev->base_addr + SONIC_UTDA); | ||
347 | |||
348 | return 1; | ||
349 | } | ||
350 | |||
351 | /* stop SONIC so we can reinitialize it */ | ||
352 | |||
353 | static void StopSONIC(struct net_device *dev) | ||
354 | { | ||
355 | /* disable interrupts */ | ||
356 | |||
357 | outb(inb(dev->base_addr + BCMREG) & (~BCMREG_IEN), dev->base_addr + BCMREG); | ||
358 | outb(0, dev->base_addr + SONIC_IMREG); | ||
359 | |||
360 | /* reset the SONIC */ | ||
361 | |||
362 | outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG); | ||
363 | udelay(10); | ||
364 | outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG); | ||
365 | } | ||
366 | |||
367 | /* initialize card and SONIC for proper operation */ | ||
368 | |||
369 | static void putcam(camentry_t * cams, int *camcnt, char *addr) | ||
370 | { | ||
371 | camentry_t *pcam = cams + (*camcnt); | ||
372 | u8 *uaddr = (u8 *) addr; | ||
373 | |||
374 | pcam->index = *camcnt; | ||
375 | pcam->addr0 = (((u16) uaddr[1]) << 8) | uaddr[0]; | ||
376 | pcam->addr1 = (((u16) uaddr[3]) << 8) | uaddr[2]; | ||
377 | pcam->addr2 = (((u16) uaddr[5]) << 8) | uaddr[4]; | ||
378 | (*camcnt)++; | ||
379 | } | ||
380 | |||
381 | static void InitBoard(struct net_device *dev) | ||
382 | { | ||
383 | ibmlana_priv *priv = netdev_priv(dev); | ||
384 | int camcnt; | ||
385 | camentry_t cams[16]; | ||
386 | u32 cammask; | ||
387 | struct netdev_hw_addr *ha; | ||
388 | u16 rcrval; | ||
389 | |||
390 | /* reset the SONIC */ | ||
391 | |||
392 | outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG); | ||
393 | udelay(10); | ||
394 | |||
395 | /* clear all spurious interrupts */ | ||
396 | |||
397 | outw(inw(dev->base_addr + SONIC_ISREG), dev->base_addr + SONIC_ISREG); | ||
398 | |||
399 | /* set up the SONIC's bus interface - constant for this adapter - | ||
400 | must be done while the SONIC is in reset */ | ||
401 | |||
402 | outw(DCREG_USR1 | DCREG_USR0 | DCREG_WC1 | DCREG_DW32, dev->base_addr + SONIC_DCREG); | ||
403 | outw(0, dev->base_addr + SONIC_DCREG2); | ||
404 | |||
405 | /* remove reset form the SONIC */ | ||
406 | |||
407 | outw(0, dev->base_addr + SONIC_CMDREG); | ||
408 | udelay(10); | ||
409 | |||
410 | /* data sheet requires URRA to be programmed before setting up the CAM contents */ | ||
411 | |||
412 | outw(0, dev->base_addr + SONIC_URRA); | ||
413 | |||
414 | /* program the CAM entry 0 to the device address */ | ||
415 | |||
416 | camcnt = 0; | ||
417 | putcam(cams, &camcnt, dev->dev_addr); | ||
418 | |||
419 | /* start putting the multicast addresses into the CAM list. Stop if | ||
420 | it is full. */ | ||
421 | |||
422 | netdev_for_each_mc_addr(ha, dev) { | ||
423 | putcam(cams, &camcnt, ha->addr); | ||
424 | if (camcnt == 16) | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | /* calculate CAM mask */ | ||
429 | |||
430 | cammask = (1 << camcnt) - 1; | ||
431 | |||
432 | /* feed CDA into SONIC, initialize RCR value (always get broadcasts) */ | ||
433 | |||
434 | memcpy_toio(priv->base, cams, sizeof(camentry_t) * camcnt); | ||
435 | memcpy_toio(priv->base + (sizeof(camentry_t) * camcnt), &cammask, sizeof(cammask)); | ||
436 | |||
437 | #ifdef DEBUG | ||
438 | printk("CAM setup:\n"); | ||
439 | dumpmem(dev, 0, sizeof(camentry_t) * camcnt + sizeof(cammask)); | ||
440 | #endif | ||
441 | |||
442 | outw(0, dev->base_addr + SONIC_CAMPTR); | ||
443 | outw(camcnt, dev->base_addr + SONIC_CAMCNT); | ||
444 | outw(CMDREG_LCAM, dev->base_addr + SONIC_CMDREG); | ||
445 | if (!wait_timeout(dev, SONIC_CMDREG, CMDREG_LCAM, 0, 2)) { | ||
446 | printk(KERN_ERR "%s:SONIC did not respond on LCAM command - giving up.", dev->name); | ||
447 | return; | ||
448 | } else { | ||
449 | /* clear interrupt condition */ | ||
450 | |||
451 | outw(ISREG_LCD, dev->base_addr + SONIC_ISREG); | ||
452 | |||
453 | #ifdef DEBUG | ||
454 | printk("Loading CAM done, address pointers %04x:%04x\n", | ||
455 | inw(dev->base_addr + SONIC_URRA), | ||
456 | inw(dev->base_addr + SONIC_CAMPTR)); | ||
457 | { | ||
458 | int z; | ||
459 | |||
460 | printk("\n-->CAM: PTR %04x CNT %04x\n", | ||
461 | inw(dev->base_addr + SONIC_CAMPTR), | ||
462 | inw(dev->base_addr + SONIC_CAMCNT)); | ||
463 | outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG); | ||
464 | for (z = 0; z < camcnt; z++) { | ||
465 | outw(z, dev->base_addr + SONIC_CAMEPTR); | ||
466 | printk("Entry %d: %04x %04x %04x\n", z, | ||
467 | inw(dev->base_addr + SONIC_CAMADDR0), | ||
468 | inw(dev->base_addr + SONIC_CAMADDR1), | ||
469 | inw(dev->base_addr + SONIC_CAMADDR2)); | ||
470 | } | ||
471 | outw(0, dev->base_addr + SONIC_CMDREG); | ||
472 | } | ||
473 | #endif | ||
474 | } | ||
475 | |||
476 | rcrval = RCREG_BRD | RCREG_LB_NONE; | ||
477 | |||
478 | /* if still multicast addresses left or ALLMULTI is set, set the multicast | ||
479 | enable bit */ | ||
480 | |||
481 | if ((dev->flags & IFF_ALLMULTI) || netdev_mc_count(dev) > camcnt) | ||
482 | rcrval |= RCREG_AMC; | ||
483 | |||
484 | /* promiscuous mode ? */ | ||
485 | |||
486 | if (dev->flags & IFF_PROMISC) | ||
487 | rcrval |= RCREG_PRO; | ||
488 | |||
489 | /* program receive mode */ | ||
490 | |||
491 | outw(rcrval, dev->base_addr + SONIC_RCREG); | ||
492 | #ifdef DEBUG | ||
493 | printk("\nRCRVAL: %04x\n", rcrval); | ||
494 | #endif | ||
495 | |||
496 | /* set up descriptors in shared memory + feed them into SONIC registers */ | ||
497 | |||
498 | InitDscrs(dev); | ||
499 | if (!InitSONIC(dev)) | ||
500 | return; | ||
501 | |||
502 | /* reset all pending interrupts */ | ||
503 | |||
504 | outw(0xffff, dev->base_addr + SONIC_ISREG); | ||
505 | |||
506 | /* enable transmitter + receiver interrupts */ | ||
507 | |||
508 | outw(CMDREG_RXEN, dev->base_addr + SONIC_CMDREG); | ||
509 | outw(IMREG_PRXEN | IMREG_RBEEN | IMREG_PTXEN | IMREG_TXEREN, dev->base_addr + SONIC_IMREG); | ||
510 | |||
511 | /* turn on card interrupts */ | ||
512 | |||
513 | outb(inb(dev->base_addr + BCMREG) | BCMREG_IEN, dev->base_addr + BCMREG); | ||
514 | |||
515 | #ifdef DEBUG | ||
516 | printk("Register dump after initialization:\n"); | ||
517 | dumpregs(dev); | ||
518 | #endif | ||
519 | } | ||
520 | |||
521 | /* start transmission of a descriptor */ | ||
522 | |||
523 | static void StartTx(struct net_device *dev, int descr) | ||
524 | { | ||
525 | ibmlana_priv *priv = netdev_priv(dev); | ||
526 | int addr; | ||
527 | |||
528 | addr = priv->tdastart + (descr * sizeof(tda_t)); | ||
529 | |||
530 | /* put descriptor address into SONIC */ | ||
531 | |||
532 | outw(addr, dev->base_addr + SONIC_CTDA); | ||
533 | |||
534 | /* trigger transmitter */ | ||
535 | |||
536 | priv->currtxdescr = descr; | ||
537 | outw(CMDREG_TXP, dev->base_addr + SONIC_CMDREG); | ||
538 | } | ||
539 | |||
540 | /* ------------------------------------------------------------------------ | ||
541 | * interrupt handler(s) | ||
542 | * ------------------------------------------------------------------------ */ | ||
543 | |||
544 | /* receive buffer area exhausted */ | ||
545 | |||
546 | static void irqrbe_handler(struct net_device *dev) | ||
547 | { | ||
548 | ibmlana_priv *priv = netdev_priv(dev); | ||
549 | |||
550 | /* point the SONIC back to the RRA start */ | ||
551 | |||
552 | outw(priv->rrastart, dev->base_addr + SONIC_RRP); | ||
553 | outw(priv->rrastart, dev->base_addr + SONIC_RWP); | ||
554 | } | ||
555 | |||
556 | /* receive interrupt */ | ||
557 | |||
558 | static void irqrx_handler(struct net_device *dev) | ||
559 | { | ||
560 | ibmlana_priv *priv = netdev_priv(dev); | ||
561 | rda_t rda; | ||
562 | u32 rdaaddr, lrdaaddr; | ||
563 | |||
564 | /* loop until ... */ | ||
565 | |||
566 | while (1) { | ||
567 | /* read descriptor that was next to be filled by SONIC */ | ||
568 | |||
569 | rdaaddr = priv->rdastart + (priv->nextrxdescr * sizeof(rda_t)); | ||
570 | lrdaaddr = priv->rdastart + (priv->lastrxdescr * sizeof(rda_t)); | ||
571 | memcpy_fromio(&rda, priv->base + rdaaddr, sizeof(rda_t)); | ||
572 | |||
573 | /* iron out upper word halves of fields we use - SONIC will duplicate | ||
574 | bits 0..15 to 16..31 */ | ||
575 | |||
576 | rda.status &= 0xffff; | ||
577 | rda.length &= 0xffff; | ||
578 | rda.startlo &= 0xffff; | ||
579 | |||
580 | /* stop if the SONIC still owns it, i.e. there is no data for us */ | ||
581 | |||
582 | if (rda.inuse) | ||
583 | break; | ||
584 | |||
585 | /* good packet? */ | ||
586 | |||
587 | else if (rda.status & RCREG_PRX) { | ||
588 | struct sk_buff *skb; | ||
589 | |||
590 | /* fetch buffer */ | ||
591 | |||
592 | skb = dev_alloc_skb(rda.length + 2); | ||
593 | if (skb == NULL) | ||
594 | dev->stats.rx_dropped++; | ||
595 | else { | ||
596 | /* copy out data */ | ||
597 | |||
598 | memcpy_fromio(skb_put(skb, rda.length), | ||
599 | priv->base + | ||
600 | rda.startlo, rda.length); | ||
601 | |||
602 | /* set up skb fields */ | ||
603 | |||
604 | skb->protocol = eth_type_trans(skb, dev); | ||
605 | skb_checksum_none_assert(skb); | ||
606 | |||
607 | /* bookkeeping */ | ||
608 | dev->stats.rx_packets++; | ||
609 | dev->stats.rx_bytes += rda.length; | ||
610 | |||
611 | /* pass to the upper layers */ | ||
612 | netif_rx(skb); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | /* otherwise check error status bits and increase statistics */ | ||
617 | |||
618 | else { | ||
619 | dev->stats.rx_errors++; | ||
620 | if (rda.status & RCREG_FAER) | ||
621 | dev->stats.rx_frame_errors++; | ||
622 | if (rda.status & RCREG_CRCR) | ||
623 | dev->stats.rx_crc_errors++; | ||
624 | } | ||
625 | |||
626 | /* descriptor processed, will become new last descriptor in queue */ | ||
627 | |||
628 | rda.link = 1; | ||
629 | rda.inuse = 1; | ||
630 | memcpy_toio(priv->base + rdaaddr, &rda, | ||
631 | sizeof(rda_t)); | ||
632 | |||
633 | /* set up link and EOL = 0 in currently last descriptor. Only write | ||
634 | the link field since the SONIC may currently already access the | ||
635 | other fields. */ | ||
636 | |||
637 | memcpy_toio(priv->base + lrdaaddr + 20, &rdaaddr, 4); | ||
638 | |||
639 | /* advance indices */ | ||
640 | |||
641 | priv->lastrxdescr = priv->nextrxdescr; | ||
642 | if ((++priv->nextrxdescr) >= priv->rxbufcnt) | ||
643 | priv->nextrxdescr = 0; | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /* transmit interrupt */ | ||
648 | |||
649 | static void irqtx_handler(struct net_device *dev) | ||
650 | { | ||
651 | ibmlana_priv *priv = netdev_priv(dev); | ||
652 | tda_t tda; | ||
653 | |||
654 | /* fetch descriptor (we forgot the size ;-) */ | ||
655 | memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t)); | ||
656 | |||
657 | /* update statistics */ | ||
658 | dev->stats.tx_packets++; | ||
659 | dev->stats.tx_bytes += tda.length; | ||
660 | |||
661 | /* update our pointers */ | ||
662 | priv->txused[priv->currtxdescr] = 0; | ||
663 | priv->txusedcnt--; | ||
664 | |||
665 | /* if there are more descriptors present in RAM, start them */ | ||
666 | if (priv->txusedcnt > 0) | ||
667 | StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT); | ||
668 | |||
669 | /* tell the upper layer we can go on transmitting */ | ||
670 | netif_wake_queue(dev); | ||
671 | } | ||
672 | |||
673 | static void irqtxerr_handler(struct net_device *dev) | ||
674 | { | ||
675 | ibmlana_priv *priv = netdev_priv(dev); | ||
676 | tda_t tda; | ||
677 | |||
678 | /* fetch descriptor to check status */ | ||
679 | memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t)); | ||
680 | |||
681 | /* update statistics */ | ||
682 | dev->stats.tx_errors++; | ||
683 | if (tda.status & (TCREG_NCRS | TCREG_CRSL)) | ||
684 | dev->stats.tx_carrier_errors++; | ||
685 | if (tda.status & TCREG_EXC) | ||
686 | dev->stats.tx_aborted_errors++; | ||
687 | if (tda.status & TCREG_OWC) | ||
688 | dev->stats.tx_window_errors++; | ||
689 | if (tda.status & TCREG_FU) | ||
690 | dev->stats.tx_fifo_errors++; | ||
691 | |||
692 | /* update our pointers */ | ||
693 | priv->txused[priv->currtxdescr] = 0; | ||
694 | priv->txusedcnt--; | ||
695 | |||
696 | /* if there are more descriptors present in RAM, start them */ | ||
697 | if (priv->txusedcnt > 0) | ||
698 | StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT); | ||
699 | |||
700 | /* tell the upper layer we can go on transmitting */ | ||
701 | netif_wake_queue(dev); | ||
702 | } | ||
703 | |||
704 | /* general interrupt entry */ | ||
705 | |||
706 | static irqreturn_t irq_handler(int dummy, void *device) | ||
707 | { | ||
708 | struct net_device *dev = device; | ||
709 | u16 ival; | ||
710 | |||
711 | /* in case we're not meant... */ | ||
712 | if (!(inb(dev->base_addr + BCMREG) & BCMREG_IPEND)) | ||
713 | return IRQ_NONE; | ||
714 | |||
715 | /* loop through the interrupt bits until everything is clear */ | ||
716 | while (1) { | ||
717 | ival = inw(dev->base_addr + SONIC_ISREG); | ||
718 | |||
719 | if (ival & ISREG_RBE) { | ||
720 | irqrbe_handler(dev); | ||
721 | outw(ISREG_RBE, dev->base_addr + SONIC_ISREG); | ||
722 | } | ||
723 | if (ival & ISREG_PKTRX) { | ||
724 | irqrx_handler(dev); | ||
725 | outw(ISREG_PKTRX, dev->base_addr + SONIC_ISREG); | ||
726 | } | ||
727 | if (ival & ISREG_TXDN) { | ||
728 | irqtx_handler(dev); | ||
729 | outw(ISREG_TXDN, dev->base_addr + SONIC_ISREG); | ||
730 | } | ||
731 | if (ival & ISREG_TXER) { | ||
732 | irqtxerr_handler(dev); | ||
733 | outw(ISREG_TXER, dev->base_addr + SONIC_ISREG); | ||
734 | } | ||
735 | break; | ||
736 | } | ||
737 | return IRQ_HANDLED; | ||
738 | } | ||
739 | |||
740 | /* ------------------------------------------------------------------------ | ||
741 | * driver methods | ||
742 | * ------------------------------------------------------------------------ */ | ||
743 | |||
744 | /* MCA info */ | ||
745 | |||
746 | #if 0 /* info available elsewhere, but this is kept for reference */ | ||
747 | static int ibmlana_getinfo(char *buf, int slot, void *d) | ||
748 | { | ||
749 | int len = 0, i; | ||
750 | struct net_device *dev = (struct net_device *) d; | ||
751 | ibmlana_priv *priv; | ||
752 | |||
753 | /* can't say anything about an uninitialized device... */ | ||
754 | |||
755 | if (dev == NULL) | ||
756 | return len; | ||
757 | priv = netdev_priv(dev); | ||
758 | |||
759 | /* print info */ | ||
760 | |||
761 | len += sprintf(buf + len, "IRQ: %d\n", priv->realirq); | ||
762 | len += sprintf(buf + len, "I/O: %#lx\n", dev->base_addr); | ||
763 | len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start, dev->mem_end - 1); | ||
764 | len += sprintf(buf + len, "Transceiver: %s\n", MediaNames[priv->medium]); | ||
765 | len += sprintf(buf + len, "Device: %s\n", dev->name); | ||
766 | len += sprintf(buf + len, "MAC address:"); | ||
767 | for (i = 0; i < 6; i++) | ||
768 | len += sprintf(buf + len, " %02x", dev->dev_addr[i]); | ||
769 | buf[len++] = '\n'; | ||
770 | buf[len] = 0; | ||
771 | |||
772 | return len; | ||
773 | } | ||
774 | #endif | ||
775 | |||
776 | /* open driver. Means also initialization and start of LANCE */ | ||
777 | |||
778 | static int ibmlana_open(struct net_device *dev) | ||
779 | { | ||
780 | int result; | ||
781 | ibmlana_priv *priv = netdev_priv(dev); | ||
782 | |||
783 | /* register resources - only necessary for IRQ */ | ||
784 | |||
785 | result = request_irq(priv->realirq, irq_handler, IRQF_SHARED, | ||
786 | dev->name, dev); | ||
787 | if (result != 0) { | ||
788 | printk(KERN_ERR "%s: failed to register irq %d\n", dev->name, dev->irq); | ||
789 | return result; | ||
790 | } | ||
791 | dev->irq = priv->realirq; | ||
792 | |||
793 | /* set up the card and SONIC */ | ||
794 | InitBoard(dev); | ||
795 | |||
796 | /* initialize operational flags */ | ||
797 | netif_start_queue(dev); | ||
798 | return 0; | ||
799 | } | ||
800 | |||
801 | /* close driver. Shut down board and free allocated resources */ | ||
802 | |||
803 | static int ibmlana_close(struct net_device *dev) | ||
804 | { | ||
805 | /* turn off board */ | ||
806 | |||
807 | /* release resources */ | ||
808 | if (dev->irq != 0) | ||
809 | free_irq(dev->irq, dev); | ||
810 | dev->irq = 0; | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | /* transmit a block. */ | ||
815 | |||
816 | static netdev_tx_t ibmlana_tx(struct sk_buff *skb, struct net_device *dev) | ||
817 | { | ||
818 | ibmlana_priv *priv = netdev_priv(dev); | ||
819 | int tmplen, addr; | ||
820 | unsigned long flags; | ||
821 | tda_t tda; | ||
822 | int baddr; | ||
823 | |||
824 | /* find out if there are free slots for a frame to transmit. If not, | ||
825 | the upper layer is in deep desperation and we simply ignore the frame. */ | ||
826 | |||
827 | if (priv->txusedcnt >= TXBUFCNT) { | ||
828 | dev->stats.tx_dropped++; | ||
829 | goto tx_done; | ||
830 | } | ||
831 | |||
832 | /* copy the frame data into the next free transmit buffer - fillup missing */ | ||
833 | tmplen = skb->len; | ||
834 | if (tmplen < 60) | ||
835 | tmplen = 60; | ||
836 | baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE); | ||
837 | memcpy_toio(priv->base + baddr, skb->data, skb->len); | ||
838 | |||
839 | /* copy filler into RAM - in case we're filling up... | ||
840 | we're filling a bit more than necessary, but that doesn't harm | ||
841 | since the buffer is far larger... | ||
842 | Sorry Linus for the filler string but I couldn't resist ;-) */ | ||
843 | |||
844 | if (tmplen > skb->len) { | ||
845 | char *fill = "NetBSD is a nice OS too! "; | ||
846 | unsigned int destoffs = skb->len, l = strlen(fill); | ||
847 | |||
848 | while (destoffs < tmplen) { | ||
849 | memcpy_toio(priv->base + baddr + destoffs, fill, l); | ||
850 | destoffs += l; | ||
851 | } | ||
852 | } | ||
853 | |||
854 | /* set up the new frame descriptor */ | ||
855 | addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t)); | ||
856 | memcpy_fromio(&tda, priv->base + addr, sizeof(tda_t)); | ||
857 | tda.length = tda.fraglength = tmplen; | ||
858 | memcpy_toio(priv->base + addr, &tda, sizeof(tda_t)); | ||
859 | |||
860 | /* if there were no active descriptors, trigger the SONIC */ | ||
861 | spin_lock_irqsave(&priv->lock, flags); | ||
862 | |||
863 | priv->txusedcnt++; | ||
864 | priv->txused[priv->nexttxdescr] = 1; | ||
865 | |||
866 | /* are all transmission slots used up ? */ | ||
867 | if (priv->txusedcnt >= TXBUFCNT) | ||
868 | netif_stop_queue(dev); | ||
869 | |||
870 | if (priv->txusedcnt == 1) | ||
871 | StartTx(dev, priv->nexttxdescr); | ||
872 | priv->nexttxdescr = (priv->nexttxdescr + 1) % TXBUFCNT; | ||
873 | |||
874 | spin_unlock_irqrestore(&priv->lock, flags); | ||
875 | tx_done: | ||
876 | dev_kfree_skb(skb); | ||
877 | return NETDEV_TX_OK; | ||
878 | } | ||
879 | |||
880 | /* switch receiver mode. */ | ||
881 | |||
882 | static void ibmlana_set_multicast_list(struct net_device *dev) | ||
883 | { | ||
884 | /* first stop the SONIC... */ | ||
885 | StopSONIC(dev); | ||
886 | /* ...then reinit it with the new flags */ | ||
887 | InitBoard(dev); | ||
888 | } | ||
889 | |||
890 | /* ------------------------------------------------------------------------ | ||
891 | * hardware check | ||
892 | * ------------------------------------------------------------------------ */ | ||
893 | |||
894 | static int ibmlana_irq; | ||
895 | static int ibmlana_io; | ||
896 | static int startslot; /* counts through slots when probing multiple devices */ | ||
897 | |||
898 | static short ibmlana_adapter_ids[] __initdata = { | ||
899 | IBM_LANA_ID, | ||
900 | 0x0000 | ||
901 | }; | ||
902 | |||
903 | static char *ibmlana_adapter_names[] __devinitdata = { | ||
904 | "IBM LAN Adapter/A", | ||
905 | NULL | ||
906 | }; | ||
907 | |||
908 | |||
909 | static const struct net_device_ops ibmlana_netdev_ops = { | ||
910 | .ndo_open = ibmlana_open, | ||
911 | .ndo_stop = ibmlana_close, | ||
912 | .ndo_start_xmit = ibmlana_tx, | ||
913 | .ndo_set_multicast_list = ibmlana_set_multicast_list, | ||
914 | .ndo_change_mtu = eth_change_mtu, | ||
915 | .ndo_set_mac_address = eth_mac_addr, | ||
916 | .ndo_validate_addr = eth_validate_addr, | ||
917 | }; | ||
918 | |||
919 | static int __devinit ibmlana_init_one(struct device *kdev) | ||
920 | { | ||
921 | struct mca_device *mdev = to_mca_device(kdev); | ||
922 | struct net_device *dev; | ||
923 | int slot = mdev->slot, z, rc; | ||
924 | int base = 0, irq = 0, iobase = 0, memlen = 0; | ||
925 | ibmlana_priv *priv; | ||
926 | ibmlana_medium medium; | ||
927 | |||
928 | dev = alloc_etherdev(sizeof(ibmlana_priv)); | ||
929 | if (!dev) | ||
930 | return -ENOMEM; | ||
931 | |||
932 | dev->irq = ibmlana_irq; | ||
933 | dev->base_addr = ibmlana_io; | ||
934 | |||
935 | base = dev->mem_start; | ||
936 | irq = dev->irq; | ||
937 | |||
938 | /* deduce card addresses */ | ||
939 | getaddrs(mdev, &base, &memlen, &iobase, &irq, &medium); | ||
940 | |||
941 | /* were we looking for something different ? */ | ||
942 | if (dev->irq && dev->irq != irq) { | ||
943 | rc = -ENODEV; | ||
944 | goto err_out; | ||
945 | } | ||
946 | if (dev->mem_start && dev->mem_start != base) { | ||
947 | rc = -ENODEV; | ||
948 | goto err_out; | ||
949 | } | ||
950 | |||
951 | /* announce success */ | ||
952 | printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1); | ||
953 | |||
954 | /* try to obtain I/O range */ | ||
955 | if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) { | ||
956 | printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase); | ||
957 | startslot = slot + 1; | ||
958 | rc = -EBUSY; | ||
959 | goto err_out; | ||
960 | } | ||
961 | |||
962 | priv = netdev_priv(dev); | ||
963 | priv->slot = slot; | ||
964 | priv->realirq = mca_device_transform_irq(mdev, irq); | ||
965 | priv->medium = medium; | ||
966 | spin_lock_init(&priv->lock); | ||
967 | |||
968 | /* set base + irq for this device (irq not allocated so far) */ | ||
969 | |||
970 | dev->irq = 0; | ||
971 | dev->mem_start = base; | ||
972 | dev->mem_end = base + memlen; | ||
973 | dev->base_addr = iobase; | ||
974 | |||
975 | priv->base = ioremap(base, memlen); | ||
976 | if (!priv->base) { | ||
977 | printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME); | ||
978 | startslot = slot + 1; | ||
979 | rc = -EBUSY; | ||
980 | goto err_out_reg; | ||
981 | } | ||
982 | |||
983 | mca_device_set_name(mdev, ibmlana_adapter_names[mdev->index]); | ||
984 | mca_device_set_claim(mdev, 1); | ||
985 | |||
986 | /* set methods */ | ||
987 | dev->netdev_ops = &ibmlana_netdev_ops; | ||
988 | dev->flags |= IFF_MULTICAST; | ||
989 | |||
990 | /* copy out MAC address */ | ||
991 | |||
992 | for (z = 0; z < ETH_ALEN; z++) | ||
993 | dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z); | ||
994 | |||
995 | /* print config */ | ||
996 | |||
997 | printk(KERN_INFO "%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, " | ||
998 | "MAC address %pM.\n", | ||
999 | dev->name, priv->realirq, dev->base_addr, | ||
1000 | dev->mem_start, dev->mem_end - 1, | ||
1001 | dev->dev_addr); | ||
1002 | printk(KERN_INFO "%s: %s medium\n", dev->name, MediaNames[priv->medium]); | ||
1003 | |||
1004 | /* reset board */ | ||
1005 | |||
1006 | ResetBoard(dev); | ||
1007 | |||
1008 | /* next probe will start at next slot */ | ||
1009 | |||
1010 | startslot = slot + 1; | ||
1011 | |||
1012 | rc = register_netdev(dev); | ||
1013 | if (rc) | ||
1014 | goto err_out_claimed; | ||
1015 | |||
1016 | dev_set_drvdata(kdev, dev); | ||
1017 | return 0; | ||
1018 | |||
1019 | err_out_claimed: | ||
1020 | mca_device_set_claim(mdev, 0); | ||
1021 | iounmap(priv->base); | ||
1022 | err_out_reg: | ||
1023 | release_region(iobase, IBM_LANA_IORANGE); | ||
1024 | err_out: | ||
1025 | free_netdev(dev); | ||
1026 | return rc; | ||
1027 | } | ||
1028 | |||
1029 | static int ibmlana_remove_one(struct device *kdev) | ||
1030 | { | ||
1031 | struct mca_device *mdev = to_mca_device(kdev); | ||
1032 | struct net_device *dev = dev_get_drvdata(kdev); | ||
1033 | ibmlana_priv *priv = netdev_priv(dev); | ||
1034 | |||
1035 | unregister_netdev(dev); | ||
1036 | /*DeinitBoard(dev); */ | ||
1037 | release_region(dev->base_addr, IBM_LANA_IORANGE); | ||
1038 | mca_device_set_claim(mdev, 0); | ||
1039 | iounmap(priv->base); | ||
1040 | free_netdev(dev); | ||
1041 | return 0; | ||
1042 | } | ||
1043 | |||
1044 | /* ------------------------------------------------------------------------ | ||
1045 | * modularization support | ||
1046 | * ------------------------------------------------------------------------ */ | ||
1047 | |||
1048 | module_param_named(irq, ibmlana_irq, int, 0); | ||
1049 | module_param_named(io, ibmlana_io, int, 0); | ||
1050 | MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number"); | ||
1051 | MODULE_PARM_DESC(io, "IBM LAN/A I/O base address"); | ||
1052 | MODULE_LICENSE("GPL"); | ||
1053 | |||
1054 | static struct mca_driver ibmlana_driver = { | ||
1055 | .id_table = ibmlana_adapter_ids, | ||
1056 | .driver = { | ||
1057 | .name = "ibmlana", | ||
1058 | .bus = &mca_bus_type, | ||
1059 | .probe = ibmlana_init_one, | ||
1060 | .remove = ibmlana_remove_one, | ||
1061 | }, | ||
1062 | }; | ||
1063 | |||
1064 | static int __init ibmlana_init_module(void) | ||
1065 | { | ||
1066 | return mca_register_driver(&ibmlana_driver); | ||
1067 | } | ||
1068 | |||
1069 | static void __exit ibmlana_cleanup_module(void) | ||
1070 | { | ||
1071 | mca_unregister_driver(&ibmlana_driver); | ||
1072 | } | ||
1073 | |||
1074 | module_init(ibmlana_init_module); | ||
1075 | module_exit(ibmlana_cleanup_module); | ||
diff --git a/drivers/net/ethernet/natsemi/ibmlana.h b/drivers/net/ethernet/natsemi/ibmlana.h new file mode 100644 index 000000000000..accd5efc9c8a --- /dev/null +++ b/drivers/net/ethernet/natsemi/ibmlana.h | |||
@@ -0,0 +1,278 @@ | |||
1 | #ifndef _IBM_LANA_INCLUDE_ | ||
2 | #define _IBM_LANA_INCLUDE_ | ||
3 | |||
4 | #ifdef _IBM_LANA_DRIVER_ | ||
5 | |||
6 | /* maximum packet size */ | ||
7 | |||
8 | #define PKTSIZE 1524 | ||
9 | |||
10 | /* number of transmit buffers */ | ||
11 | |||
12 | #define TXBUFCNT 4 | ||
13 | |||
14 | /* Adapter ID's */ | ||
15 | #define IBM_LANA_ID 0xffe0 | ||
16 | |||
17 | /* media enumeration - defined in a way that it fits onto the LAN/A's | ||
18 | POS registers... */ | ||
19 | |||
20 | typedef enum { | ||
21 | Media_10BaseT, Media_10Base5, | ||
22 | Media_Unknown, Media_10Base2, Media_Count | ||
23 | } ibmlana_medium; | ||
24 | |||
25 | /* private structure */ | ||
26 | |||
27 | typedef struct { | ||
28 | unsigned int slot; /* MCA-Slot-# */ | ||
29 | int realirq; /* memorizes actual IRQ, even when | ||
30 | currently not allocated */ | ||
31 | ibmlana_medium medium; /* physical cannector */ | ||
32 | u32 tdastart, txbufstart, /* addresses */ | ||
33 | rrastart, rxbufstart, rdastart, rxbufcnt, txusedcnt; | ||
34 | int nextrxdescr, /* next rx descriptor to be used */ | ||
35 | lastrxdescr, /* last free rx descriptor */ | ||
36 | nexttxdescr, /* last tx descriptor to be used */ | ||
37 | currtxdescr, /* tx descriptor currently tx'ed */ | ||
38 | txused[TXBUFCNT]; /* busy flags */ | ||
39 | void __iomem *base; | ||
40 | spinlock_t lock; | ||
41 | } ibmlana_priv; | ||
42 | |||
43 | /* this card uses quite a lot of I/O ports...luckily the MCA bus decodes | ||
44 | a full 64K I/O range... */ | ||
45 | |||
46 | #define IBM_LANA_IORANGE 0xa0 | ||
47 | |||
48 | /* Command Register: */ | ||
49 | |||
50 | #define SONIC_CMDREG 0x00 | ||
51 | #define CMDREG_HTX 0x0001 /* halt transmission */ | ||
52 | #define CMDREG_TXP 0x0002 /* start transmission */ | ||
53 | #define CMDREG_RXDIS 0x0004 /* disable receiver */ | ||
54 | #define CMDREG_RXEN 0x0008 /* enable receiver */ | ||
55 | #define CMDREG_STP 0x0010 /* stop timer */ | ||
56 | #define CMDREG_ST 0x0020 /* start timer */ | ||
57 | #define CMDREG_RST 0x0080 /* software reset */ | ||
58 | #define CMDREG_RRRA 0x0100 /* force SONIC to read first RRA */ | ||
59 | #define CMDREG_LCAM 0x0200 /* force SONIC to read CAM descrs */ | ||
60 | |||
61 | /* Data Configuration Register */ | ||
62 | |||
63 | #define SONIC_DCREG 0x02 | ||
64 | #define DCREG_EXBUS 0x8000 /* Extended Bus Mode */ | ||
65 | #define DCREG_LBR 0x2000 /* Latched Bus Retry */ | ||
66 | #define DCREG_PO1 0x1000 /* Programmable Outputs */ | ||
67 | #define DCREG_PO0 0x0800 | ||
68 | #define DCREG_SBUS 0x0400 /* Synchronous Bus Mode */ | ||
69 | #define DCREG_USR1 0x0200 /* User Definable Pins */ | ||
70 | #define DCREG_USR0 0x0100 | ||
71 | #define DCREG_WC0 0x0000 /* 0..3 Wait States */ | ||
72 | #define DCREG_WC1 0x0040 | ||
73 | #define DCREG_WC2 0x0080 | ||
74 | #define DCREG_WC3 0x00c0 | ||
75 | #define DCREG_DW16 0x0000 /* 16 bit Bus Mode */ | ||
76 | #define DCREG_DW32 0x0020 /* 32 bit Bus Mode */ | ||
77 | #define DCREG_BMS 0x0010 /* Block Mode Select */ | ||
78 | #define DCREG_RFT4 0x0000 /* 4/8/16/24 bytes RX Threshold */ | ||
79 | #define DCREG_RFT8 0x0004 | ||
80 | #define DCREG_RFT16 0x0008 | ||
81 | #define DCREG_RFT24 0x000c | ||
82 | #define DCREG_TFT8 0x0000 /* 8/16/24/28 bytes TX Threshold */ | ||
83 | #define DCREG_TFT16 0x0001 | ||
84 | #define DCREG_TFT24 0x0002 | ||
85 | #define DCREG_TFT28 0x0003 | ||
86 | |||
87 | /* Receive Control Register */ | ||
88 | |||
89 | #define SONIC_RCREG 0x04 | ||
90 | #define RCREG_ERR 0x8000 /* accept damaged and collided pkts */ | ||
91 | #define RCREG_RNT 0x4000 /* accept packets that are < 64 */ | ||
92 | #define RCREG_BRD 0x2000 /* accept broadcasts */ | ||
93 | #define RCREG_PRO 0x1000 /* promiscuous mode */ | ||
94 | #define RCREG_AMC 0x0800 /* accept all multicasts */ | ||
95 | #define RCREG_LB_NONE 0x0000 /* no loopback */ | ||
96 | #define RCREG_LB_MAC 0x0200 /* MAC loopback */ | ||
97 | #define RCREG_LB_ENDEC 0x0400 /* ENDEC loopback */ | ||
98 | #define RCREG_LB_XVR 0x0600 /* Transceiver loopback */ | ||
99 | #define RCREG_MC 0x0100 /* Multicast received */ | ||
100 | #define RCREG_BC 0x0080 /* Broadcast received */ | ||
101 | #define RCREG_LPKT 0x0040 /* last packet in RBA */ | ||
102 | #define RCREG_CRS 0x0020 /* carrier sense present */ | ||
103 | #define RCREG_COL 0x0010 /* recv'd packet with collision */ | ||
104 | #define RCREG_CRCR 0x0008 /* recv'd packet with CRC error */ | ||
105 | #define RCREG_FAER 0x0004 /* recv'd packet with inv. framing */ | ||
106 | #define RCREG_LBK 0x0002 /* recv'd loopback packet */ | ||
107 | #define RCREG_PRX 0x0001 /* recv'd packet is OK */ | ||
108 | |||
109 | /* Transmit Control Register */ | ||
110 | |||
111 | #define SONIC_TCREG 0x06 | ||
112 | #define TCREG_PINT 0x8000 /* generate interrupt after TDA read */ | ||
113 | #define TCREG_POWC 0x4000 /* timer start out of window detect */ | ||
114 | #define TCREG_CRCI 0x2000 /* inhibit CRC generation */ | ||
115 | #define TCREG_EXDIS 0x1000 /* disable excessive deferral timer */ | ||
116 | #define TCREG_EXD 0x0400 /* excessive deferral occurred */ | ||
117 | #define TCREG_DEF 0x0200 /* single deferral occurred */ | ||
118 | #define TCREG_NCRS 0x0100 /* no carrier detected */ | ||
119 | #define TCREG_CRSL 0x0080 /* carrier lost */ | ||
120 | #define TCREG_EXC 0x0040 /* excessive collisions occurred */ | ||
121 | #define TCREG_OWC 0x0020 /* out of window collision occurred */ | ||
122 | #define TCREG_PMB 0x0008 /* packet monitored bad */ | ||
123 | #define TCREG_FU 0x0004 /* FIFO underrun */ | ||
124 | #define TCREG_BCM 0x0002 /* byte count mismatch of fragments */ | ||
125 | #define TCREG_PTX 0x0001 /* packet transmitted OK */ | ||
126 | |||
127 | /* Interrupt Mask Register */ | ||
128 | |||
129 | #define SONIC_IMREG 0x08 | ||
130 | #define IMREG_BREN 0x4000 /* interrupt when bus retry occurred */ | ||
131 | #define IMREG_HBLEN 0x2000 /* interrupt when heartbeat lost */ | ||
132 | #define IMREG_LCDEN 0x1000 /* interrupt when CAM loaded */ | ||
133 | #define IMREG_PINTEN 0x0800 /* interrupt when PINT in TDA set */ | ||
134 | #define IMREG_PRXEN 0x0400 /* interrupt when packet received */ | ||
135 | #define IMREG_PTXEN 0x0200 /* interrupt when packet was sent */ | ||
136 | #define IMREG_TXEREN 0x0100 /* interrupt when send failed */ | ||
137 | #define IMREG_TCEN 0x0080 /* interrupt when timer completed */ | ||
138 | #define IMREG_RDEEN 0x0040 /* interrupt when RDA exhausted */ | ||
139 | #define IMREG_RBEEN 0x0020 /* interrupt when RBA exhausted */ | ||
140 | #define IMREG_RBAEEN 0x0010 /* interrupt when RBA too short */ | ||
141 | #define IMREG_CRCEN 0x0008 /* interrupt when CRC counter rolls */ | ||
142 | #define IMREG_FAEEN 0x0004 /* interrupt when FAE counter rolls */ | ||
143 | #define IMREG_MPEN 0x0002 /* interrupt when MP counter rolls */ | ||
144 | #define IMREG_RFOEN 0x0001 /* interrupt when Rx FIFO overflows */ | ||
145 | |||
146 | /* Interrupt Status Register */ | ||
147 | |||
148 | #define SONIC_ISREG 0x0a | ||
149 | #define ISREG_BR 0x4000 /* bus retry occurred */ | ||
150 | #define ISREG_HBL 0x2000 /* heartbeat lost */ | ||
151 | #define ISREG_LCD 0x1000 /* CAM loaded */ | ||
152 | #define ISREG_PINT 0x0800 /* PINT in TDA set */ | ||
153 | #define ISREG_PKTRX 0x0400 /* packet received */ | ||
154 | #define ISREG_TXDN 0x0200 /* packet was sent */ | ||
155 | #define ISREG_TXER 0x0100 /* send failed */ | ||
156 | #define ISREG_TC 0x0080 /* timer completed */ | ||
157 | #define ISREG_RDE 0x0040 /* RDA exhausted */ | ||
158 | #define ISREG_RBE 0x0020 /* RBA exhausted */ | ||
159 | #define ISREG_RBAE 0x0010 /* RBA too short for received frame */ | ||
160 | #define ISREG_CRC 0x0008 /* CRC counter rolls over */ | ||
161 | #define ISREG_FAE 0x0004 /* FAE counter rolls over */ | ||
162 | #define ISREG_MP 0x0002 /* MP counter rolls over */ | ||
163 | #define ISREG_RFO 0x0001 /* Rx FIFO overflows */ | ||
164 | |||
165 | #define SONIC_UTDA 0x0c /* current transmit descr address */ | ||
166 | #define SONIC_CTDA 0x0e | ||
167 | |||
168 | #define SONIC_URDA 0x1a /* current receive descr address */ | ||
169 | #define SONIC_CRDA 0x1c | ||
170 | |||
171 | #define SONIC_CRBA0 0x1e /* current receive buffer address */ | ||
172 | #define SONIC_CRBA1 0x20 | ||
173 | |||
174 | #define SONIC_RBWC0 0x22 /* word count in receive buffer */ | ||
175 | #define SONIC_RBWC1 0x24 | ||
176 | |||
177 | #define SONIC_EOBC 0x26 /* minimum space to be free in RBA */ | ||
178 | |||
179 | #define SONIC_URRA 0x28 /* upper address of CDA & Recv Area */ | ||
180 | |||
181 | #define SONIC_RSA 0x2a /* start of receive resource area */ | ||
182 | |||
183 | #define SONIC_REA 0x2c /* end of receive resource area */ | ||
184 | |||
185 | #define SONIC_RRP 0x2e /* resource read pointer */ | ||
186 | |||
187 | #define SONIC_RWP 0x30 /* resource write pointer */ | ||
188 | |||
189 | #define SONIC_CAMEPTR 0x42 /* CAM entry pointer */ | ||
190 | |||
191 | #define SONIC_CAMADDR2 0x44 /* CAM address ports */ | ||
192 | #define SONIC_CAMADDR1 0x46 | ||
193 | #define SONIC_CAMADDR0 0x48 | ||
194 | |||
195 | #define SONIC_CAMPTR 0x4c /* lower address of CDA */ | ||
196 | |||
197 | #define SONIC_CAMCNT 0x4e /* # of CAM descriptors to load */ | ||
198 | |||
199 | /* Data Configuration Register 2 */ | ||
200 | |||
201 | #define SONIC_DCREG2 0x7e | ||
202 | #define DCREG2_EXPO3 0x8000 /* extended programmable outputs */ | ||
203 | #define DCREG2_EXPO2 0x4000 | ||
204 | #define DCREG2_EXPO1 0x2000 | ||
205 | #define DCREG2_EXPO0 0x1000 | ||
206 | #define DCREG2_HD 0x0800 /* heartbeat disable */ | ||
207 | #define DCREG2_JD 0x0200 /* jabber timer disable */ | ||
208 | #define DCREG2_AUTO 0x0100 /* enable AUI/TP auto selection */ | ||
209 | #define DCREG2_XWRAP 0x0040 /* TP transceiver loopback */ | ||
210 | #define DCREG2_PH 0x0010 /* HOLD request timing */ | ||
211 | #define DCREG2_PCM 0x0004 /* packet compress when matched */ | ||
212 | #define DCREG2_PCNM 0x0002 /* packet compress when not matched */ | ||
213 | #define DCREG2_RJCM 0x0001 /* inverse packet match via CAM */ | ||
214 | |||
215 | /* Board Control Register: Enable RAM, Interrupts... */ | ||
216 | |||
217 | #define BCMREG 0x80 | ||
218 | #define BCMREG_RAMEN 0x80 /* switch over to RAM */ | ||
219 | #define BCMREG_IPEND 0x40 /* interrupt pending ? */ | ||
220 | #define BCMREG_RESET 0x08 /* reset board */ | ||
221 | #define BCMREG_16BIT 0x04 /* adapter in 16-bit slot */ | ||
222 | #define BCMREG_RAMWIN 0x02 /* enable RAM window */ | ||
223 | #define BCMREG_IEN 0x01 /* interrupt enable */ | ||
224 | |||
225 | /* MAC Address PROM */ | ||
226 | |||
227 | #define MACADDRPROM 0x92 | ||
228 | |||
229 | /* structure of a CAM entry */ | ||
230 | |||
231 | typedef struct { | ||
232 | u32 index; /* pointer into CAM area */ | ||
233 | u32 addr0; /* address part (bits 0..15 used) */ | ||
234 | u32 addr1; | ||
235 | u32 addr2; | ||
236 | } camentry_t; | ||
237 | |||
238 | /* structure of a receive resource */ | ||
239 | |||
240 | typedef struct { | ||
241 | u32 startlo; /* start address (bits 0..15 used) */ | ||
242 | u32 starthi; | ||
243 | u32 cntlo; /* size in 16-bit quantities */ | ||
244 | u32 cnthi; | ||
245 | } rra_t; | ||
246 | |||
247 | /* structure of a receive descriptor */ | ||
248 | |||
249 | typedef struct { | ||
250 | u32 status; /* packet status */ | ||
251 | u32 length; /* length in bytes */ | ||
252 | u32 startlo; /* start address */ | ||
253 | u32 starthi; | ||
254 | u32 seqno; /* frame sequence */ | ||
255 | u32 link; /* pointer to next descriptor */ | ||
256 | /* bit 0 = EOL */ | ||
257 | u32 inuse; /* !=0 --> free for SONIC to write */ | ||
258 | } rda_t; | ||
259 | |||
260 | /* structure of a transmit descriptor */ | ||
261 | |||
262 | typedef struct { | ||
263 | u32 status; /* transmit status */ | ||
264 | u32 config; /* value for TCR */ | ||
265 | u32 length; /* total length */ | ||
266 | u32 fragcount; /* number of fragments */ | ||
267 | u32 startlo; /* start address of fragment */ | ||
268 | u32 starthi; | ||
269 | u32 fraglength; /* length of this fragment */ | ||
270 | /* more address/length triplets may */ | ||
271 | /* follow here */ | ||
272 | u32 link; /* pointer to next descriptor */ | ||
273 | /* bit 0 = EOL */ | ||
274 | } tda_t; | ||
275 | |||
276 | #endif /* _IBM_LANA_DRIVER_ */ | ||
277 | |||
278 | #endif /* _IBM_LANA_INCLUDE_ */ | ||
diff --git a/drivers/net/ethernet/natsemi/jazzsonic.c b/drivers/net/ethernet/natsemi/jazzsonic.c new file mode 100644 index 000000000000..949c1f933644 --- /dev/null +++ b/drivers/net/ethernet/natsemi/jazzsonic.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /* | ||
2 | * jazzsonic.c | ||
3 | * | ||
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, and (from the mac68k project) introduced | ||
7 | * dhd's support for 16-bit cards. | ||
8 | * | ||
9 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
10 | * | ||
11 | * This driver is based on work from Andreas Busse, but most of | ||
12 | * the code is rewritten. | ||
13 | * | ||
14 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) | ||
15 | * | ||
16 | * A driver for the onboard Sonic ethernet controller on Mips Jazz | ||
17 | * systems (Acer Pica-61, Mips Magnum 4000, Olivetti M700 and | ||
18 | * perhaps others, too) | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/fcntl.h> | ||
25 | #include <linux/gfp.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/ioport.h> | ||
29 | #include <linux/in.h> | ||
30 | #include <linux/string.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/netdevice.h> | ||
34 | #include <linux/etherdevice.h> | ||
35 | #include <linux/skbuff.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/dma-mapping.h> | ||
38 | #include <linux/slab.h> | ||
39 | |||
40 | #include <asm/bootinfo.h> | ||
41 | #include <asm/system.h> | ||
42 | #include <asm/pgtable.h> | ||
43 | #include <asm/io.h> | ||
44 | #include <asm/dma.h> | ||
45 | #include <asm/jazz.h> | ||
46 | #include <asm/jazzdma.h> | ||
47 | |||
48 | static char jazz_sonic_string[] = "jazzsonic"; | ||
49 | |||
50 | #define SONIC_MEM_SIZE 0x100 | ||
51 | |||
52 | #include "sonic.h" | ||
53 | |||
54 | /* | ||
55 | * Macros to access SONIC registers | ||
56 | */ | ||
57 | #define SONIC_READ(reg) (*((volatile unsigned int *)dev->base_addr+reg)) | ||
58 | |||
59 | #define SONIC_WRITE(reg,val) \ | ||
60 | do { \ | ||
61 | *((volatile unsigned int *)dev->base_addr+(reg)) = (val); \ | ||
62 | } while (0) | ||
63 | |||
64 | |||
65 | /* use 0 for production, 1 for verification, >1 for debug */ | ||
66 | #ifdef SONIC_DEBUG | ||
67 | static unsigned int sonic_debug = SONIC_DEBUG; | ||
68 | #else | ||
69 | static unsigned int sonic_debug = 1; | ||
70 | #endif | ||
71 | |||
72 | /* | ||
73 | * We cannot use station (ethernet) address prefixes to detect the | ||
74 | * sonic controller since these are board manufacturer depended. | ||
75 | * So we check for known Silicon Revision IDs instead. | ||
76 | */ | ||
77 | static unsigned short known_revisions[] = | ||
78 | { | ||
79 | 0x04, /* Mips Magnum 4000 */ | ||
80 | 0xffff /* end of list */ | ||
81 | }; | ||
82 | |||
83 | static int jazzsonic_open(struct net_device* dev) | ||
84 | { | ||
85 | int retval; | ||
86 | |||
87 | retval = request_irq(dev->irq, sonic_interrupt, IRQF_DISABLED, | ||
88 | "sonic", dev); | ||
89 | if (retval) { | ||
90 | printk(KERN_ERR "%s: unable to get IRQ %d.\n", | ||
91 | dev->name, dev->irq); | ||
92 | return retval; | ||
93 | } | ||
94 | |||
95 | retval = sonic_open(dev); | ||
96 | if (retval) | ||
97 | free_irq(dev->irq, dev); | ||
98 | return retval; | ||
99 | } | ||
100 | |||
101 | static int jazzsonic_close(struct net_device* dev) | ||
102 | { | ||
103 | int err; | ||
104 | err = sonic_close(dev); | ||
105 | free_irq(dev->irq, dev); | ||
106 | return err; | ||
107 | } | ||
108 | |||
109 | static const struct net_device_ops sonic_netdev_ops = { | ||
110 | .ndo_open = jazzsonic_open, | ||
111 | .ndo_stop = jazzsonic_close, | ||
112 | .ndo_start_xmit = sonic_send_packet, | ||
113 | .ndo_get_stats = sonic_get_stats, | ||
114 | .ndo_set_multicast_list = sonic_multicast_list, | ||
115 | .ndo_tx_timeout = sonic_tx_timeout, | ||
116 | .ndo_change_mtu = eth_change_mtu, | ||
117 | .ndo_validate_addr = eth_validate_addr, | ||
118 | .ndo_set_mac_address = eth_mac_addr, | ||
119 | }; | ||
120 | |||
121 | static int __devinit sonic_probe1(struct net_device *dev) | ||
122 | { | ||
123 | static unsigned version_printed; | ||
124 | unsigned int silicon_revision; | ||
125 | unsigned int val; | ||
126 | struct sonic_local *lp = netdev_priv(dev); | ||
127 | int err = -ENODEV; | ||
128 | int i; | ||
129 | |||
130 | if (!request_mem_region(dev->base_addr, SONIC_MEM_SIZE, jazz_sonic_string)) | ||
131 | return -EBUSY; | ||
132 | |||
133 | /* | ||
134 | * get the Silicon Revision ID. If this is one of the known | ||
135 | * one assume that we found a SONIC ethernet controller at | ||
136 | * the expected location. | ||
137 | */ | ||
138 | silicon_revision = SONIC_READ(SONIC_SR); | ||
139 | if (sonic_debug > 1) | ||
140 | printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision); | ||
141 | |||
142 | i = 0; | ||
143 | while (known_revisions[i] != 0xffff && | ||
144 | known_revisions[i] != silicon_revision) | ||
145 | i++; | ||
146 | |||
147 | if (known_revisions[i] == 0xffff) { | ||
148 | printk("SONIC ethernet controller not found (0x%4x)\n", | ||
149 | silicon_revision); | ||
150 | goto out; | ||
151 | } | ||
152 | |||
153 | if (sonic_debug && version_printed++ == 0) | ||
154 | printk(version); | ||
155 | |||
156 | printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", | ||
157 | dev_name(lp->device), dev->base_addr); | ||
158 | |||
159 | /* | ||
160 | * Put the sonic into software reset, then | ||
161 | * retrieve and print the ethernet address. | ||
162 | */ | ||
163 | SONIC_WRITE(SONIC_CMD,SONIC_CR_RST); | ||
164 | SONIC_WRITE(SONIC_CEP,0); | ||
165 | for (i=0; i<3; i++) { | ||
166 | val = SONIC_READ(SONIC_CAP0-i); | ||
167 | dev->dev_addr[i*2] = val; | ||
168 | dev->dev_addr[i*2+1] = val >> 8; | ||
169 | } | ||
170 | |||
171 | err = -ENOMEM; | ||
172 | |||
173 | /* Initialize the device structure. */ | ||
174 | |||
175 | lp->dma_bitmode = SONIC_BITMODE32; | ||
176 | |||
177 | /* Allocate the entire chunk of memory for the descriptors. | ||
178 | Note that this cannot cross a 64K boundary. */ | ||
179 | if ((lp->descriptors = dma_alloc_coherent(lp->device, | ||
180 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
181 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { | ||
182 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", | ||
183 | dev_name(lp->device)); | ||
184 | goto out; | ||
185 | } | ||
186 | |||
187 | /* Now set up the pointers to point to the appropriate places */ | ||
188 | lp->cda = lp->descriptors; | ||
189 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA | ||
190 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
191 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
192 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
193 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
194 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
195 | |||
196 | lp->cda_laddr = lp->descriptors_laddr; | ||
197 | lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA | ||
198 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
199 | lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
200 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
201 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
202 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
203 | |||
204 | dev->netdev_ops = &sonic_netdev_ops; | ||
205 | dev->watchdog_timeo = TX_TIMEOUT; | ||
206 | |||
207 | /* | ||
208 | * clear tally counter | ||
209 | */ | ||
210 | SONIC_WRITE(SONIC_CRCT,0xffff); | ||
211 | SONIC_WRITE(SONIC_FAET,0xffff); | ||
212 | SONIC_WRITE(SONIC_MPT,0xffff); | ||
213 | |||
214 | return 0; | ||
215 | out: | ||
216 | release_mem_region(dev->base_addr, SONIC_MEM_SIZE); | ||
217 | return err; | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * Probe for a SONIC ethernet controller on a Mips Jazz board. | ||
222 | * Actually probing is superfluous but we're paranoid. | ||
223 | */ | ||
224 | static int __devinit jazz_sonic_probe(struct platform_device *pdev) | ||
225 | { | ||
226 | struct net_device *dev; | ||
227 | struct sonic_local *lp; | ||
228 | struct resource *res; | ||
229 | int err = 0; | ||
230 | |||
231 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
232 | if (!res) | ||
233 | return -ENODEV; | ||
234 | |||
235 | dev = alloc_etherdev(sizeof(struct sonic_local)); | ||
236 | if (!dev) | ||
237 | return -ENOMEM; | ||
238 | |||
239 | lp = netdev_priv(dev); | ||
240 | lp->device = &pdev->dev; | ||
241 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
242 | platform_set_drvdata(pdev, dev); | ||
243 | |||
244 | netdev_boot_setup_check(dev); | ||
245 | |||
246 | dev->base_addr = res->start; | ||
247 | dev->irq = platform_get_irq(pdev, 0); | ||
248 | err = sonic_probe1(dev); | ||
249 | if (err) | ||
250 | goto out; | ||
251 | err = register_netdev(dev); | ||
252 | if (err) | ||
253 | goto out1; | ||
254 | |||
255 | printk("%s: MAC %pM IRQ %d\n", dev->name, dev->dev_addr, dev->irq); | ||
256 | |||
257 | return 0; | ||
258 | |||
259 | out1: | ||
260 | release_mem_region(dev->base_addr, SONIC_MEM_SIZE); | ||
261 | out: | ||
262 | free_netdev(dev); | ||
263 | |||
264 | return err; | ||
265 | } | ||
266 | |||
267 | MODULE_DESCRIPTION("Jazz SONIC ethernet driver"); | ||
268 | module_param(sonic_debug, int, 0); | ||
269 | MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)"); | ||
270 | MODULE_ALIAS("platform:jazzsonic"); | ||
271 | |||
272 | #include "sonic.c" | ||
273 | |||
274 | static int __devexit jazz_sonic_device_remove (struct platform_device *pdev) | ||
275 | { | ||
276 | struct net_device *dev = platform_get_drvdata(pdev); | ||
277 | struct sonic_local* lp = netdev_priv(dev); | ||
278 | |||
279 | unregister_netdev(dev); | ||
280 | dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
281 | lp->descriptors, lp->descriptors_laddr); | ||
282 | release_mem_region(dev->base_addr, SONIC_MEM_SIZE); | ||
283 | free_netdev(dev); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static struct platform_driver jazz_sonic_driver = { | ||
289 | .probe = jazz_sonic_probe, | ||
290 | .remove = __devexit_p(jazz_sonic_device_remove), | ||
291 | .driver = { | ||
292 | .name = jazz_sonic_string, | ||
293 | .owner = THIS_MODULE, | ||
294 | }, | ||
295 | }; | ||
296 | |||
297 | static int __init jazz_sonic_init_module(void) | ||
298 | { | ||
299 | return platform_driver_register(&jazz_sonic_driver); | ||
300 | } | ||
301 | |||
302 | static void __exit jazz_sonic_cleanup_module(void) | ||
303 | { | ||
304 | platform_driver_unregister(&jazz_sonic_driver); | ||
305 | } | ||
306 | |||
307 | module_init(jazz_sonic_init_module); | ||
308 | module_exit(jazz_sonic_cleanup_module); | ||
diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c new file mode 100644 index 000000000000..c93679ee6994 --- /dev/null +++ b/drivers/net/ethernet/natsemi/macsonic.c | |||
@@ -0,0 +1,666 @@ | |||
1 | /* | ||
2 | * macsonic.c | ||
3 | * | ||
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, converted to unified driver model, made it work as | ||
7 | * a module again, and from the mac68k project, introduced more 32-bit cards | ||
8 | * and dhd's support for 16-bit cards. | ||
9 | * | ||
10 | * (C) 1998 Alan Cox | ||
11 | * | ||
12 | * Debugging Andreas Ehliar, Michael Schmitz | ||
13 | * | ||
14 | * Based on code | ||
15 | * (C) 1996 by Thomas Bogendoerfer (tsbogend@bigbug.franken.de) | ||
16 | * | ||
17 | * This driver is based on work from Andreas Busse, but most of | ||
18 | * the code is rewritten. | ||
19 | * | ||
20 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) | ||
21 | * | ||
22 | * A driver for the Mac onboard Sonic ethernet chip. | ||
23 | * | ||
24 | * 98/12/21 MSch: judged from tests on Q800, it's basically working, | ||
25 | * but eating up both receive and transmit resources | ||
26 | * and duplicating packets. Needs more testing. | ||
27 | * | ||
28 | * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed. | ||
29 | * | ||
30 | * 00/10/31 sammy@oh.verio.com: Updated driver for 2.4 kernels, fixed problems | ||
31 | * on centris. | ||
32 | */ | ||
33 | |||
34 | #include <linux/kernel.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/types.h> | ||
37 | #include <linux/fcntl.h> | ||
38 | #include <linux/gfp.h> | ||
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/ioport.h> | ||
42 | #include <linux/in.h> | ||
43 | #include <linux/string.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/nubus.h> | ||
46 | #include <linux/errno.h> | ||
47 | #include <linux/netdevice.h> | ||
48 | #include <linux/etherdevice.h> | ||
49 | #include <linux/skbuff.h> | ||
50 | #include <linux/platform_device.h> | ||
51 | #include <linux/dma-mapping.h> | ||
52 | #include <linux/bitrev.h> | ||
53 | #include <linux/slab.h> | ||
54 | |||
55 | #include <asm/bootinfo.h> | ||
56 | #include <asm/system.h> | ||
57 | #include <asm/pgtable.h> | ||
58 | #include <asm/io.h> | ||
59 | #include <asm/hwtest.h> | ||
60 | #include <asm/dma.h> | ||
61 | #include <asm/macintosh.h> | ||
62 | #include <asm/macints.h> | ||
63 | #include <asm/mac_via.h> | ||
64 | |||
65 | static char mac_sonic_string[] = "macsonic"; | ||
66 | |||
67 | #include "sonic.h" | ||
68 | |||
69 | /* These should basically be bus-size and endian independent (since | ||
70 | the SONIC is at least smart enough that it uses the same endianness | ||
71 | as the host, unlike certain less enlightened Macintosh NICs) */ | ||
72 | #define SONIC_READ(reg) (nubus_readw(dev->base_addr + (reg * 4) \ | ||
73 | + lp->reg_offset)) | ||
74 | #define SONIC_WRITE(reg,val) (nubus_writew(val, dev->base_addr + (reg * 4) \ | ||
75 | + lp->reg_offset)) | ||
76 | |||
77 | /* use 0 for production, 1 for verification, >1 for debug */ | ||
78 | #ifdef SONIC_DEBUG | ||
79 | static unsigned int sonic_debug = SONIC_DEBUG; | ||
80 | #else | ||
81 | static unsigned int sonic_debug = 1; | ||
82 | #endif | ||
83 | |||
84 | static int sonic_version_printed; | ||
85 | |||
86 | /* For onboard SONIC */ | ||
87 | #define ONBOARD_SONIC_REGISTERS 0x50F0A000 | ||
88 | #define ONBOARD_SONIC_PROM_BASE 0x50f08000 | ||
89 | |||
90 | enum macsonic_type { | ||
91 | MACSONIC_DUODOCK, | ||
92 | MACSONIC_APPLE, | ||
93 | MACSONIC_APPLE16, | ||
94 | MACSONIC_DAYNA, | ||
95 | MACSONIC_DAYNALINK | ||
96 | }; | ||
97 | |||
98 | /* For the built-in SONIC in the Duo Dock */ | ||
99 | #define DUODOCK_SONIC_REGISTERS 0xe10000 | ||
100 | #define DUODOCK_SONIC_PROM_BASE 0xe12000 | ||
101 | |||
102 | /* For Apple-style NuBus SONIC */ | ||
103 | #define APPLE_SONIC_REGISTERS 0 | ||
104 | #define APPLE_SONIC_PROM_BASE 0x40000 | ||
105 | |||
106 | /* Daynalink LC SONIC */ | ||
107 | #define DAYNALINK_PROM_BASE 0x400000 | ||
108 | |||
109 | /* For Dayna-style NuBus SONIC (haven't seen one yet) */ | ||
110 | #define DAYNA_SONIC_REGISTERS 0x180000 | ||
111 | /* This is what OpenBSD says. However, this is definitely in NuBus | ||
112 | ROM space so we should be able to get it by walking the NuBus | ||
113 | resource directories */ | ||
114 | #define DAYNA_SONIC_MAC_ADDR 0xffe004 | ||
115 | |||
116 | #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr) | ||
117 | |||
118 | /* | ||
119 | * For reversing the PROM address | ||
120 | */ | ||
121 | |||
122 | static inline void bit_reverse_addr(unsigned char addr[6]) | ||
123 | { | ||
124 | int i; | ||
125 | |||
126 | for(i = 0; i < 6; i++) | ||
127 | addr[i] = bitrev8(addr[i]); | ||
128 | } | ||
129 | |||
130 | static irqreturn_t macsonic_interrupt(int irq, void *dev_id) | ||
131 | { | ||
132 | irqreturn_t result; | ||
133 | unsigned long flags; | ||
134 | |||
135 | local_irq_save(flags); | ||
136 | result = sonic_interrupt(irq, dev_id); | ||
137 | local_irq_restore(flags); | ||
138 | return result; | ||
139 | } | ||
140 | |||
141 | static int macsonic_open(struct net_device* dev) | ||
142 | { | ||
143 | int retval; | ||
144 | |||
145 | retval = request_irq(dev->irq, sonic_interrupt, IRQ_FLG_FAST, | ||
146 | "sonic", dev); | ||
147 | if (retval) { | ||
148 | printk(KERN_ERR "%s: unable to get IRQ %d.\n", | ||
149 | dev->name, dev->irq); | ||
150 | goto err; | ||
151 | } | ||
152 | /* Under the A/UX interrupt scheme, the onboard SONIC interrupt comes | ||
153 | * in at priority level 3. However, we sometimes get the level 2 inter- | ||
154 | * rupt as well, which must prevent re-entrance of the sonic handler. | ||
155 | */ | ||
156 | if (dev->irq == IRQ_AUTO_3) { | ||
157 | retval = request_irq(IRQ_NUBUS_9, macsonic_interrupt, | ||
158 | IRQ_FLG_FAST, "sonic", dev); | ||
159 | if (retval) { | ||
160 | printk(KERN_ERR "%s: unable to get IRQ %d.\n", | ||
161 | dev->name, IRQ_NUBUS_9); | ||
162 | goto err_irq; | ||
163 | } | ||
164 | } | ||
165 | retval = sonic_open(dev); | ||
166 | if (retval) | ||
167 | goto err_irq_nubus; | ||
168 | return 0; | ||
169 | |||
170 | err_irq_nubus: | ||
171 | if (dev->irq == IRQ_AUTO_3) | ||
172 | free_irq(IRQ_NUBUS_9, dev); | ||
173 | err_irq: | ||
174 | free_irq(dev->irq, dev); | ||
175 | err: | ||
176 | return retval; | ||
177 | } | ||
178 | |||
179 | static int macsonic_close(struct net_device* dev) | ||
180 | { | ||
181 | int err; | ||
182 | err = sonic_close(dev); | ||
183 | free_irq(dev->irq, dev); | ||
184 | if (dev->irq == IRQ_AUTO_3) | ||
185 | free_irq(IRQ_NUBUS_9, dev); | ||
186 | return err; | ||
187 | } | ||
188 | |||
189 | static const struct net_device_ops macsonic_netdev_ops = { | ||
190 | .ndo_open = macsonic_open, | ||
191 | .ndo_stop = macsonic_close, | ||
192 | .ndo_start_xmit = sonic_send_packet, | ||
193 | .ndo_set_multicast_list = sonic_multicast_list, | ||
194 | .ndo_tx_timeout = sonic_tx_timeout, | ||
195 | .ndo_get_stats = sonic_get_stats, | ||
196 | .ndo_validate_addr = eth_validate_addr, | ||
197 | .ndo_change_mtu = eth_change_mtu, | ||
198 | .ndo_set_mac_address = eth_mac_addr, | ||
199 | }; | ||
200 | |||
201 | static int __devinit macsonic_init(struct net_device *dev) | ||
202 | { | ||
203 | struct sonic_local* lp = netdev_priv(dev); | ||
204 | |||
205 | /* Allocate the entire chunk of memory for the descriptors. | ||
206 | Note that this cannot cross a 64K boundary. */ | ||
207 | if ((lp->descriptors = dma_alloc_coherent(lp->device, | ||
208 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
209 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { | ||
210 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", | ||
211 | dev_name(lp->device)); | ||
212 | return -ENOMEM; | ||
213 | } | ||
214 | |||
215 | /* Now set up the pointers to point to the appropriate places */ | ||
216 | lp->cda = lp->descriptors; | ||
217 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA | ||
218 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
219 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
220 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
221 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
222 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
223 | |||
224 | lp->cda_laddr = lp->descriptors_laddr; | ||
225 | lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA | ||
226 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
227 | lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
228 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
229 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
230 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
231 | |||
232 | dev->netdev_ops = &macsonic_netdev_ops; | ||
233 | dev->watchdog_timeo = TX_TIMEOUT; | ||
234 | |||
235 | /* | ||
236 | * clear tally counter | ||
237 | */ | ||
238 | SONIC_WRITE(SONIC_CRCT, 0xffff); | ||
239 | SONIC_WRITE(SONIC_FAET, 0xffff); | ||
240 | SONIC_WRITE(SONIC_MPT, 0xffff); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | #define INVALID_MAC(mac) (memcmp(mac, "\x08\x00\x07", 3) && \ | ||
246 | memcmp(mac, "\x00\xA0\x40", 3) && \ | ||
247 | memcmp(mac, "\x00\x80\x19", 3) && \ | ||
248 | memcmp(mac, "\x00\x05\x02", 3)) | ||
249 | |||
250 | static void __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev) | ||
251 | { | ||
252 | struct sonic_local *lp = netdev_priv(dev); | ||
253 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; | ||
254 | unsigned short val; | ||
255 | |||
256 | /* | ||
257 | * On NuBus boards we can sometimes look in the ROM resources. | ||
258 | * No such luck for comm-slot/onboard. | ||
259 | * On the PowerBook 520, the PROM base address is a mystery. | ||
260 | */ | ||
261 | if (hwreg_present((void *)prom_addr)) { | ||
262 | int i; | ||
263 | |||
264 | for (i = 0; i < 6; i++) | ||
265 | dev->dev_addr[i] = SONIC_READ_PROM(i); | ||
266 | if (!INVALID_MAC(dev->dev_addr)) | ||
267 | return; | ||
268 | |||
269 | /* | ||
270 | * Most of the time, the address is bit-reversed. The NetBSD | ||
271 | * source has a rather long and detailed historical account of | ||
272 | * why this is so. | ||
273 | */ | ||
274 | bit_reverse_addr(dev->dev_addr); | ||
275 | if (!INVALID_MAC(dev->dev_addr)) | ||
276 | return; | ||
277 | |||
278 | /* | ||
279 | * If we still have what seems to be a bogus address, we'll | ||
280 | * look in the CAM. The top entry should be ours. | ||
281 | */ | ||
282 | printk(KERN_WARNING "macsonic: MAC address in PROM seems " | ||
283 | "to be invalid, trying CAM\n"); | ||
284 | } else { | ||
285 | printk(KERN_WARNING "macsonic: cannot read MAC address from " | ||
286 | "PROM, trying CAM\n"); | ||
287 | } | ||
288 | |||
289 | /* This only works if MacOS has already initialized the card. */ | ||
290 | |||
291 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | ||
292 | SONIC_WRITE(SONIC_CEP, 15); | ||
293 | |||
294 | val = SONIC_READ(SONIC_CAP2); | ||
295 | dev->dev_addr[5] = val >> 8; | ||
296 | dev->dev_addr[4] = val & 0xff; | ||
297 | val = SONIC_READ(SONIC_CAP1); | ||
298 | dev->dev_addr[3] = val >> 8; | ||
299 | dev->dev_addr[2] = val & 0xff; | ||
300 | val = SONIC_READ(SONIC_CAP0); | ||
301 | dev->dev_addr[1] = val >> 8; | ||
302 | dev->dev_addr[0] = val & 0xff; | ||
303 | |||
304 | if (!INVALID_MAC(dev->dev_addr)) | ||
305 | return; | ||
306 | |||
307 | /* Still nonsense ... messed up someplace! */ | ||
308 | |||
309 | printk(KERN_WARNING "macsonic: MAC address in CAM entry 15 " | ||
310 | "seems invalid, will use a random MAC\n"); | ||
311 | random_ether_addr(dev->dev_addr); | ||
312 | } | ||
313 | |||
314 | static int __devinit mac_onboard_sonic_probe(struct net_device *dev) | ||
315 | { | ||
316 | /* Bwahahaha */ | ||
317 | static int once_is_more_than_enough; | ||
318 | struct sonic_local* lp = netdev_priv(dev); | ||
319 | int sr; | ||
320 | int commslot = 0; | ||
321 | |||
322 | if (once_is_more_than_enough) | ||
323 | return -ENODEV; | ||
324 | once_is_more_than_enough = 1; | ||
325 | |||
326 | if (!MACH_IS_MAC) | ||
327 | return -ENODEV; | ||
328 | |||
329 | if (macintosh_config->ether_type != MAC_ETHER_SONIC) | ||
330 | return -ENODEV; | ||
331 | |||
332 | printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. "); | ||
333 | |||
334 | /* Bogus probing, on the models which may or may not have | ||
335 | Ethernet (BTW, the Ethernet *is* always at the same | ||
336 | address, and nothing else lives there, at least if Apple's | ||
337 | documentation is to be believed) */ | ||
338 | if (macintosh_config->ident == MAC_MODEL_Q630 || | ||
339 | macintosh_config->ident == MAC_MODEL_P588 || | ||
340 | macintosh_config->ident == MAC_MODEL_P575 || | ||
341 | macintosh_config->ident == MAC_MODEL_C610) { | ||
342 | unsigned long flags; | ||
343 | int card_present; | ||
344 | |||
345 | local_irq_save(flags); | ||
346 | card_present = hwreg_present((void*)ONBOARD_SONIC_REGISTERS); | ||
347 | local_irq_restore(flags); | ||
348 | |||
349 | if (!card_present) { | ||
350 | printk("none.\n"); | ||
351 | return -ENODEV; | ||
352 | } | ||
353 | commslot = 1; | ||
354 | } | ||
355 | |||
356 | printk("yes\n"); | ||
357 | |||
358 | /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset | ||
359 | * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */ | ||
360 | dev->base_addr = ONBOARD_SONIC_REGISTERS; | ||
361 | if (via_alt_mapping) | ||
362 | dev->irq = IRQ_AUTO_3; | ||
363 | else | ||
364 | dev->irq = IRQ_NUBUS_9; | ||
365 | |||
366 | if (!sonic_version_printed) { | ||
367 | printk(KERN_INFO "%s", version); | ||
368 | sonic_version_printed = 1; | ||
369 | } | ||
370 | printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n", | ||
371 | dev_name(lp->device), dev->base_addr); | ||
372 | |||
373 | /* The PowerBook's SONIC is 16 bit always. */ | ||
374 | if (macintosh_config->ident == MAC_MODEL_PB520) { | ||
375 | lp->reg_offset = 0; | ||
376 | lp->dma_bitmode = SONIC_BITMODE16; | ||
377 | sr = SONIC_READ(SONIC_SR); | ||
378 | } else if (commslot) { | ||
379 | /* Some of the comm-slot cards are 16 bit. But some | ||
380 | of them are not. The 32-bit cards use offset 2 and | ||
381 | have known revisions, we try reading the revision | ||
382 | register at offset 2, if we don't get a known revision | ||
383 | we assume 16 bit at offset 0. */ | ||
384 | lp->reg_offset = 2; | ||
385 | lp->dma_bitmode = SONIC_BITMODE16; | ||
386 | |||
387 | sr = SONIC_READ(SONIC_SR); | ||
388 | if (sr == 0x0004 || sr == 0x0006 || sr == 0x0100 || sr == 0x0101) | ||
389 | /* 83932 is 0x0004 or 0x0006, 83934 is 0x0100 or 0x0101 */ | ||
390 | lp->dma_bitmode = SONIC_BITMODE32; | ||
391 | else { | ||
392 | lp->dma_bitmode = SONIC_BITMODE16; | ||
393 | lp->reg_offset = 0; | ||
394 | sr = SONIC_READ(SONIC_SR); | ||
395 | } | ||
396 | } else { | ||
397 | /* All onboard cards are at offset 2 with 32 bit DMA. */ | ||
398 | lp->reg_offset = 2; | ||
399 | lp->dma_bitmode = SONIC_BITMODE32; | ||
400 | sr = SONIC_READ(SONIC_SR); | ||
401 | } | ||
402 | printk(KERN_INFO | ||
403 | "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | ||
404 | dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset); | ||
405 | |||
406 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ | ||
407 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device), | ||
408 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); | ||
409 | #endif | ||
410 | |||
411 | /* Software reset, then initialize control registers. */ | ||
412 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | ||
413 | |||
414 | SONIC_WRITE(SONIC_DCR, SONIC_DCR_EXBUS | SONIC_DCR_BMS | | ||
415 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | | ||
416 | (lp->dma_bitmode ? SONIC_DCR_DW : 0)); | ||
417 | |||
418 | /* This *must* be written back to in order to restore the | ||
419 | * extended programmable output bits, as it may not have been | ||
420 | * initialised since the hardware reset. */ | ||
421 | SONIC_WRITE(SONIC_DCR2, 0); | ||
422 | |||
423 | /* Clear *and* disable interrupts to be on the safe side */ | ||
424 | SONIC_WRITE(SONIC_IMR, 0); | ||
425 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
426 | |||
427 | /* Now look for the MAC address. */ | ||
428 | mac_onboard_sonic_ethernet_addr(dev); | ||
429 | |||
430 | /* Shared init code */ | ||
431 | return macsonic_init(dev); | ||
432 | } | ||
433 | |||
434 | static int __devinit mac_nubus_sonic_ethernet_addr(struct net_device *dev, | ||
435 | unsigned long prom_addr, | ||
436 | int id) | ||
437 | { | ||
438 | int i; | ||
439 | for(i = 0; i < 6; i++) | ||
440 | dev->dev_addr[i] = SONIC_READ_PROM(i); | ||
441 | |||
442 | /* Some of the addresses are bit-reversed */ | ||
443 | if (id != MACSONIC_DAYNA) | ||
444 | bit_reverse_addr(dev->dev_addr); | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int __devinit macsonic_ident(struct nubus_dev *ndev) | ||
450 | { | ||
451 | if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC && | ||
452 | ndev->dr_sw == NUBUS_DRSW_SONIC_LC) | ||
453 | return MACSONIC_DAYNALINK; | ||
454 | if (ndev->dr_hw == NUBUS_DRHW_SONIC && | ||
455 | ndev->dr_sw == NUBUS_DRSW_APPLE) { | ||
456 | /* There has to be a better way to do this... */ | ||
457 | if (strstr(ndev->board->name, "DuoDock")) | ||
458 | return MACSONIC_DUODOCK; | ||
459 | else | ||
460 | return MACSONIC_APPLE; | ||
461 | } | ||
462 | |||
463 | if (ndev->dr_hw == NUBUS_DRHW_SMC9194 && | ||
464 | ndev->dr_sw == NUBUS_DRSW_DAYNA) | ||
465 | return MACSONIC_DAYNA; | ||
466 | |||
467 | if (ndev->dr_hw == NUBUS_DRHW_APPLE_SONIC_LC && | ||
468 | ndev->dr_sw == 0) { /* huh? */ | ||
469 | return MACSONIC_APPLE16; | ||
470 | } | ||
471 | return -1; | ||
472 | } | ||
473 | |||
474 | static int __devinit mac_nubus_sonic_probe(struct net_device *dev) | ||
475 | { | ||
476 | static int slots; | ||
477 | struct nubus_dev* ndev = NULL; | ||
478 | struct sonic_local* lp = netdev_priv(dev); | ||
479 | unsigned long base_addr, prom_addr; | ||
480 | u16 sonic_dcr; | ||
481 | int id = -1; | ||
482 | int reg_offset, dma_bitmode; | ||
483 | |||
484 | /* Find the first SONIC that hasn't been initialized already */ | ||
485 | while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, | ||
486 | NUBUS_TYPE_ETHERNET, ndev)) != NULL) | ||
487 | { | ||
488 | /* Have we seen it already? */ | ||
489 | if (slots & (1<<ndev->board->slot)) | ||
490 | continue; | ||
491 | slots |= 1<<ndev->board->slot; | ||
492 | |||
493 | /* Is it one of ours? */ | ||
494 | if ((id = macsonic_ident(ndev)) != -1) | ||
495 | break; | ||
496 | } | ||
497 | |||
498 | if (ndev == NULL) | ||
499 | return -ENODEV; | ||
500 | |||
501 | switch (id) { | ||
502 | case MACSONIC_DUODOCK: | ||
503 | base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS; | ||
504 | prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE; | ||
505 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 | | ||
506 | SONIC_DCR_TFT0; | ||
507 | reg_offset = 2; | ||
508 | dma_bitmode = SONIC_BITMODE32; | ||
509 | break; | ||
510 | case MACSONIC_APPLE: | ||
511 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | ||
512 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; | ||
513 | sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0; | ||
514 | reg_offset = 0; | ||
515 | dma_bitmode = SONIC_BITMODE32; | ||
516 | break; | ||
517 | case MACSONIC_APPLE16: | ||
518 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | ||
519 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; | ||
520 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | | ||
521 | SONIC_DCR_PO1 | SONIC_DCR_BMS; | ||
522 | reg_offset = 0; | ||
523 | dma_bitmode = SONIC_BITMODE16; | ||
524 | break; | ||
525 | case MACSONIC_DAYNALINK: | ||
526 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | ||
527 | prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE; | ||
528 | sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | | ||
529 | SONIC_DCR_PO1 | SONIC_DCR_BMS; | ||
530 | reg_offset = 0; | ||
531 | dma_bitmode = SONIC_BITMODE16; | ||
532 | break; | ||
533 | case MACSONIC_DAYNA: | ||
534 | base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS; | ||
535 | prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR; | ||
536 | sonic_dcr = SONIC_DCR_BMS | | ||
537 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1; | ||
538 | reg_offset = 0; | ||
539 | dma_bitmode = SONIC_BITMODE16; | ||
540 | break; | ||
541 | default: | ||
542 | printk(KERN_ERR "macsonic: WTF, id is %d\n", id); | ||
543 | return -ENODEV; | ||
544 | } | ||
545 | |||
546 | /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset | ||
547 | * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */ | ||
548 | dev->base_addr = base_addr; | ||
549 | lp->reg_offset = reg_offset; | ||
550 | lp->dma_bitmode = dma_bitmode; | ||
551 | dev->irq = SLOT2IRQ(ndev->board->slot); | ||
552 | |||
553 | if (!sonic_version_printed) { | ||
554 | printk(KERN_INFO "%s", version); | ||
555 | sonic_version_printed = 1; | ||
556 | } | ||
557 | printk(KERN_INFO "%s: %s in slot %X\n", | ||
558 | dev_name(lp->device), ndev->board->name, ndev->board->slot); | ||
559 | printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | ||
560 | dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset); | ||
561 | |||
562 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ | ||
563 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device), | ||
564 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); | ||
565 | #endif | ||
566 | |||
567 | /* Software reset, then initialize control registers. */ | ||
568 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | ||
569 | SONIC_WRITE(SONIC_DCR, sonic_dcr | (dma_bitmode ? SONIC_DCR_DW : 0)); | ||
570 | /* This *must* be written back to in order to restore the | ||
571 | * extended programmable output bits, since it may not have been | ||
572 | * initialised since the hardware reset. */ | ||
573 | SONIC_WRITE(SONIC_DCR2, 0); | ||
574 | |||
575 | /* Clear *and* disable interrupts to be on the safe side */ | ||
576 | SONIC_WRITE(SONIC_IMR, 0); | ||
577 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
578 | |||
579 | /* Now look for the MAC address. */ | ||
580 | if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0) | ||
581 | return -ENODEV; | ||
582 | |||
583 | /* Shared init code */ | ||
584 | return macsonic_init(dev); | ||
585 | } | ||
586 | |||
587 | static int __devinit mac_sonic_probe(struct platform_device *pdev) | ||
588 | { | ||
589 | struct net_device *dev; | ||
590 | struct sonic_local *lp; | ||
591 | int err; | ||
592 | |||
593 | dev = alloc_etherdev(sizeof(struct sonic_local)); | ||
594 | if (!dev) | ||
595 | return -ENOMEM; | ||
596 | |||
597 | lp = netdev_priv(dev); | ||
598 | lp->device = &pdev->dev; | ||
599 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
600 | platform_set_drvdata(pdev, dev); | ||
601 | |||
602 | /* This will catch fatal stuff like -ENOMEM as well as success */ | ||
603 | err = mac_onboard_sonic_probe(dev); | ||
604 | if (err == 0) | ||
605 | goto found; | ||
606 | if (err != -ENODEV) | ||
607 | goto out; | ||
608 | err = mac_nubus_sonic_probe(dev); | ||
609 | if (err) | ||
610 | goto out; | ||
611 | found: | ||
612 | err = register_netdev(dev); | ||
613 | if (err) | ||
614 | goto out; | ||
615 | |||
616 | printk("%s: MAC %pM IRQ %d\n", dev->name, dev->dev_addr, dev->irq); | ||
617 | |||
618 | return 0; | ||
619 | |||
620 | out: | ||
621 | free_netdev(dev); | ||
622 | |||
623 | return err; | ||
624 | } | ||
625 | |||
626 | MODULE_DESCRIPTION("Macintosh SONIC ethernet driver"); | ||
627 | module_param(sonic_debug, int, 0); | ||
628 | MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); | ||
629 | MODULE_ALIAS("platform:macsonic"); | ||
630 | |||
631 | #include "sonic.c" | ||
632 | |||
633 | static int __devexit mac_sonic_device_remove (struct platform_device *pdev) | ||
634 | { | ||
635 | struct net_device *dev = platform_get_drvdata(pdev); | ||
636 | struct sonic_local* lp = netdev_priv(dev); | ||
637 | |||
638 | unregister_netdev(dev); | ||
639 | dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
640 | lp->descriptors, lp->descriptors_laddr); | ||
641 | free_netdev(dev); | ||
642 | |||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static struct platform_driver mac_sonic_driver = { | ||
647 | .probe = mac_sonic_probe, | ||
648 | .remove = __devexit_p(mac_sonic_device_remove), | ||
649 | .driver = { | ||
650 | .name = mac_sonic_string, | ||
651 | .owner = THIS_MODULE, | ||
652 | }, | ||
653 | }; | ||
654 | |||
655 | static int __init mac_sonic_init_module(void) | ||
656 | { | ||
657 | return platform_driver_register(&mac_sonic_driver); | ||
658 | } | ||
659 | |||
660 | static void __exit mac_sonic_cleanup_module(void) | ||
661 | { | ||
662 | platform_driver_unregister(&mac_sonic_driver); | ||
663 | } | ||
664 | |||
665 | module_init(mac_sonic_init_module); | ||
666 | module_exit(mac_sonic_cleanup_module); | ||
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c new file mode 100644 index 000000000000..2962cc695ce3 --- /dev/null +++ b/drivers/net/ethernet/natsemi/natsemi.c | |||
@@ -0,0 +1,3370 @@ | |||
1 | /* natsemi.c: A Linux PCI Ethernet driver for the NatSemi DP8381x series. */ | ||
2 | /* | ||
3 | Written/copyright 1999-2001 by Donald Becker. | ||
4 | Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com) | ||
5 | Portions copyright 2001,2002 Manfred Spraul (manfred@colorfullife.com) | ||
6 | Portions copyright 2004 Harald Welte <laforge@gnumonks.org> | ||
7 | |||
8 | This software may be used and distributed according to the terms of | ||
9 | the GNU General Public License (GPL), incorporated herein by reference. | ||
10 | Drivers based on or derived from this code fall under the GPL and must | ||
11 | retain the authorship, copyright and license notice. This file is not | ||
12 | a complete program and may only be used when the entire operating | ||
13 | system is licensed under the GPL. License for under other terms may be | ||
14 | available. Contact the original author for details. | ||
15 | |||
16 | The original author may be reached as becker@scyld.com, or at | ||
17 | Scyld Computing Corporation | ||
18 | 410 Severn Ave., Suite 210 | ||
19 | Annapolis MD 21403 | ||
20 | |||
21 | Support information and updates available at | ||
22 | http://www.scyld.com/network/netsemi.html | ||
23 | [link no longer provides useful info -jgarzik] | ||
24 | |||
25 | |||
26 | TODO: | ||
27 | * big endian support with CFG:BEM instead of cpu_to_le32 | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/ioport.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/interrupt.h> | ||
38 | #include <linux/pci.h> | ||
39 | #include <linux/netdevice.h> | ||
40 | #include <linux/etherdevice.h> | ||
41 | #include <linux/skbuff.h> | ||
42 | #include <linux/init.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | #include <linux/ethtool.h> | ||
45 | #include <linux/delay.h> | ||
46 | #include <linux/rtnetlink.h> | ||
47 | #include <linux/mii.h> | ||
48 | #include <linux/crc32.h> | ||
49 | #include <linux/bitops.h> | ||
50 | #include <linux/prefetch.h> | ||
51 | #include <asm/processor.h> /* Processor type for cache alignment. */ | ||
52 | #include <asm/io.h> | ||
53 | #include <asm/irq.h> | ||
54 | #include <asm/uaccess.h> | ||
55 | |||
56 | #define DRV_NAME "natsemi" | ||
57 | #define DRV_VERSION "2.1" | ||
58 | #define DRV_RELDATE "Sept 11, 2006" | ||
59 | |||
60 | #define RX_OFFSET 2 | ||
61 | |||
62 | /* Updated to recommendations in pci-skeleton v2.03. */ | ||
63 | |||
64 | /* The user-configurable values. | ||
65 | These may be modified when a driver module is loaded.*/ | ||
66 | |||
67 | #define NATSEMI_DEF_MSG (NETIF_MSG_DRV | \ | ||
68 | NETIF_MSG_LINK | \ | ||
69 | NETIF_MSG_WOL | \ | ||
70 | NETIF_MSG_RX_ERR | \ | ||
71 | NETIF_MSG_TX_ERR) | ||
72 | static int debug = -1; | ||
73 | |||
74 | static int mtu; | ||
75 | |||
76 | /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). | ||
77 | This chip uses a 512 element hash table based on the Ethernet CRC. */ | ||
78 | static const int multicast_filter_limit = 100; | ||
79 | |||
80 | /* Set the copy breakpoint for the copy-only-tiny-frames scheme. | ||
81 | Setting to > 1518 effectively disables this feature. */ | ||
82 | static int rx_copybreak; | ||
83 | |||
84 | static int dspcfg_workaround = 1; | ||
85 | |||
86 | /* Used to pass the media type, etc. | ||
87 | Both 'options[]' and 'full_duplex[]' should exist for driver | ||
88 | interoperability. | ||
89 | The media type is usually passed in 'options[]'. | ||
90 | */ | ||
91 | #define MAX_UNITS 8 /* More are supported, limit only on options */ | ||
92 | static int options[MAX_UNITS]; | ||
93 | static int full_duplex[MAX_UNITS]; | ||
94 | |||
95 | /* Operational parameters that are set at compile time. */ | ||
96 | |||
97 | /* Keep the ring sizes a power of two for compile efficiency. | ||
98 | The compiler will convert <unsigned>'%'<2^N> into a bit mask. | ||
99 | Making the Tx ring too large decreases the effectiveness of channel | ||
100 | bonding and packet priority. | ||
101 | There are no ill effects from too-large receive rings. */ | ||
102 | #define TX_RING_SIZE 16 | ||
103 | #define TX_QUEUE_LEN 10 /* Limit ring entries actually used, min 4. */ | ||
104 | #define RX_RING_SIZE 32 | ||
105 | |||
106 | /* Operational parameters that usually are not changed. */ | ||
107 | /* Time in jiffies before concluding the transmitter is hung. */ | ||
108 | #define TX_TIMEOUT (2*HZ) | ||
109 | |||
110 | #define NATSEMI_HW_TIMEOUT 400 | ||
111 | #define NATSEMI_TIMER_FREQ 5*HZ | ||
112 | #define NATSEMI_PG0_NREGS 64 | ||
113 | #define NATSEMI_RFDR_NREGS 8 | ||
114 | #define NATSEMI_PG1_NREGS 4 | ||
115 | #define NATSEMI_NREGS (NATSEMI_PG0_NREGS + NATSEMI_RFDR_NREGS + \ | ||
116 | NATSEMI_PG1_NREGS) | ||
117 | #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ | ||
118 | #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) | ||
119 | |||
120 | /* Buffer sizes: | ||
121 | * The nic writes 32-bit values, even if the upper bytes of | ||
122 | * a 32-bit value are beyond the end of the buffer. | ||
123 | */ | ||
124 | #define NATSEMI_HEADERS 22 /* 2*mac,type,vlan,crc */ | ||
125 | #define NATSEMI_PADDING 16 /* 2 bytes should be sufficient */ | ||
126 | #define NATSEMI_LONGPKT 1518 /* limit for normal packets */ | ||
127 | #define NATSEMI_RX_LIMIT 2046 /* maximum supported by hardware */ | ||
128 | |||
129 | /* These identify the driver base version and may not be removed. */ | ||
130 | static const char version[] __devinitconst = | ||
131 | KERN_INFO DRV_NAME " dp8381x driver, version " | ||
132 | DRV_VERSION ", " DRV_RELDATE "\n" | ||
133 | " originally by Donald Becker <becker@scyld.com>\n" | ||
134 | " 2.4.x kernel port by Jeff Garzik, Tjeerd Mulder\n"; | ||
135 | |||
136 | MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); | ||
137 | MODULE_DESCRIPTION("National Semiconductor DP8381x series PCI Ethernet driver"); | ||
138 | MODULE_LICENSE("GPL"); | ||
139 | |||
140 | module_param(mtu, int, 0); | ||
141 | module_param(debug, int, 0); | ||
142 | module_param(rx_copybreak, int, 0); | ||
143 | module_param(dspcfg_workaround, int, 0); | ||
144 | module_param_array(options, int, NULL, 0); | ||
145 | module_param_array(full_duplex, int, NULL, 0); | ||
146 | MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); | ||
147 | MODULE_PARM_DESC(debug, "DP8381x default debug level"); | ||
148 | MODULE_PARM_DESC(rx_copybreak, | ||
149 | "DP8381x copy breakpoint for copy-only-tiny-frames"); | ||
150 | MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround"); | ||
151 | MODULE_PARM_DESC(options, | ||
152 | "DP8381x: Bits 0-3: media type, bit 17: full duplex"); | ||
153 | MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)"); | ||
154 | |||
155 | /* | ||
156 | Theory of Operation | ||
157 | |||
158 | I. Board Compatibility | ||
159 | |||
160 | This driver is designed for National Semiconductor DP83815 PCI Ethernet NIC. | ||
161 | It also works with other chips in in the DP83810 series. | ||
162 | |||
163 | II. Board-specific settings | ||
164 | |||
165 | This driver requires the PCI interrupt line to be valid. | ||
166 | It honors the EEPROM-set values. | ||
167 | |||
168 | III. Driver operation | ||
169 | |||
170 | IIIa. Ring buffers | ||
171 | |||
172 | This driver uses two statically allocated fixed-size descriptor lists | ||
173 | formed into rings by a branch from the final descriptor to the beginning of | ||
174 | the list. The ring sizes are set at compile time by RX/TX_RING_SIZE. | ||
175 | The NatSemi design uses a 'next descriptor' pointer that the driver forms | ||
176 | into a list. | ||
177 | |||
178 | IIIb/c. Transmit/Receive Structure | ||
179 | |||
180 | This driver uses a zero-copy receive and transmit scheme. | ||
181 | The driver allocates full frame size skbuffs for the Rx ring buffers at | ||
182 | open() time and passes the skb->data field to the chip as receive data | ||
183 | buffers. When an incoming frame is less than RX_COPYBREAK bytes long, | ||
184 | a fresh skbuff is allocated and the frame is copied to the new skbuff. | ||
185 | When the incoming frame is larger, the skbuff is passed directly up the | ||
186 | protocol stack. Buffers consumed this way are replaced by newly allocated | ||
187 | skbuffs in a later phase of receives. | ||
188 | |||
189 | The RX_COPYBREAK value is chosen to trade-off the memory wasted by | ||
190 | using a full-sized skbuff for small frames vs. the copying costs of larger | ||
191 | frames. New boards are typically used in generously configured machines | ||
192 | and the underfilled buffers have negligible impact compared to the benefit of | ||
193 | a single allocation size, so the default value of zero results in never | ||
194 | copying packets. When copying is done, the cost is usually mitigated by using | ||
195 | a combined copy/checksum routine. Copying also preloads the cache, which is | ||
196 | most useful with small frames. | ||
197 | |||
198 | A subtle aspect of the operation is that unaligned buffers are not permitted | ||
199 | by the hardware. Thus the IP header at offset 14 in an ethernet frame isn't | ||
200 | longword aligned for further processing. On copies frames are put into the | ||
201 | skbuff at an offset of "+2", 16-byte aligning the IP header. | ||
202 | |||
203 | IIId. Synchronization | ||
204 | |||
205 | Most operations are synchronized on the np->lock irq spinlock, except the | ||
206 | receive and transmit paths which are synchronised using a combination of | ||
207 | hardware descriptor ownership, disabling interrupts and NAPI poll scheduling. | ||
208 | |||
209 | IVb. References | ||
210 | |||
211 | http://www.scyld.com/expert/100mbps.html | ||
212 | http://www.scyld.com/expert/NWay.html | ||
213 | Datasheet is available from: | ||
214 | http://www.national.com/pf/DP/DP83815.html | ||
215 | |||
216 | IVc. Errata | ||
217 | |||
218 | None characterised. | ||
219 | */ | ||
220 | |||
221 | |||
222 | |||
223 | /* | ||
224 | * Support for fibre connections on Am79C874: | ||
225 | * This phy needs a special setup when connected to a fibre cable. | ||
226 | * http://www.amd.com/files/connectivitysolutions/networking/archivednetworking/22235.pdf | ||
227 | */ | ||
228 | #define PHYID_AM79C874 0x0022561b | ||
229 | |||
230 | enum { | ||
231 | MII_MCTRL = 0x15, /* mode control register */ | ||
232 | MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */ | ||
233 | MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */ | ||
234 | }; | ||
235 | |||
236 | enum { | ||
237 | NATSEMI_FLAG_IGNORE_PHY = 0x1, | ||
238 | }; | ||
239 | |||
240 | /* array of board data directly indexed by pci_tbl[x].driver_data */ | ||
241 | static struct { | ||
242 | const char *name; | ||
243 | unsigned long flags; | ||
244 | unsigned int eeprom_size; | ||
245 | } natsemi_pci_info[] __devinitdata = { | ||
246 | { "Aculab E1/T1 PMXc cPCI carrier card", NATSEMI_FLAG_IGNORE_PHY, 128 }, | ||
247 | { "NatSemi DP8381[56]", 0, 24 }, | ||
248 | }; | ||
249 | |||
250 | static DEFINE_PCI_DEVICE_TABLE(natsemi_pci_tbl) = { | ||
251 | { PCI_VENDOR_ID_NS, 0x0020, 0x12d9, 0x000c, 0, 0, 0 }, | ||
252 | { PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, | ||
253 | { } /* terminate list */ | ||
254 | }; | ||
255 | MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl); | ||
256 | |||
257 | /* Offsets to the device registers. | ||
258 | Unlike software-only systems, device drivers interact with complex hardware. | ||
259 | It's not useful to define symbolic names for every register bit in the | ||
260 | device. | ||
261 | */ | ||
262 | enum register_offsets { | ||
263 | ChipCmd = 0x00, | ||
264 | ChipConfig = 0x04, | ||
265 | EECtrl = 0x08, | ||
266 | PCIBusCfg = 0x0C, | ||
267 | IntrStatus = 0x10, | ||
268 | IntrMask = 0x14, | ||
269 | IntrEnable = 0x18, | ||
270 | IntrHoldoff = 0x1C, /* DP83816 only */ | ||
271 | TxRingPtr = 0x20, | ||
272 | TxConfig = 0x24, | ||
273 | RxRingPtr = 0x30, | ||
274 | RxConfig = 0x34, | ||
275 | ClkRun = 0x3C, | ||
276 | WOLCmd = 0x40, | ||
277 | PauseCmd = 0x44, | ||
278 | RxFilterAddr = 0x48, | ||
279 | RxFilterData = 0x4C, | ||
280 | BootRomAddr = 0x50, | ||
281 | BootRomData = 0x54, | ||
282 | SiliconRev = 0x58, | ||
283 | StatsCtrl = 0x5C, | ||
284 | StatsData = 0x60, | ||
285 | RxPktErrs = 0x60, | ||
286 | RxMissed = 0x68, | ||
287 | RxCRCErrs = 0x64, | ||
288 | BasicControl = 0x80, | ||
289 | BasicStatus = 0x84, | ||
290 | AnegAdv = 0x90, | ||
291 | AnegPeer = 0x94, | ||
292 | PhyStatus = 0xC0, | ||
293 | MIntrCtrl = 0xC4, | ||
294 | MIntrStatus = 0xC8, | ||
295 | PhyCtrl = 0xE4, | ||
296 | |||
297 | /* These are from the spec, around page 78... on a separate table. | ||
298 | * The meaning of these registers depend on the value of PGSEL. */ | ||
299 | PGSEL = 0xCC, | ||
300 | PMDCSR = 0xE4, | ||
301 | TSTDAT = 0xFC, | ||
302 | DSPCFG = 0xF4, | ||
303 | SDCFG = 0xF8 | ||
304 | }; | ||
305 | /* the values for the 'magic' registers above (PGSEL=1) */ | ||
306 | #define PMDCSR_VAL 0x189c /* enable preferred adaptation circuitry */ | ||
307 | #define TSTDAT_VAL 0x0 | ||
308 | #define DSPCFG_VAL 0x5040 | ||
309 | #define SDCFG_VAL 0x008c /* set voltage thresholds for Signal Detect */ | ||
310 | #define DSPCFG_LOCK 0x20 /* coefficient lock bit in DSPCFG */ | ||
311 | #define DSPCFG_COEF 0x1000 /* see coefficient (in TSTDAT) bit in DSPCFG */ | ||
312 | #define TSTDAT_FIXED 0xe8 /* magic number for bad coefficients */ | ||
313 | |||
314 | /* misc PCI space registers */ | ||
315 | enum pci_register_offsets { | ||
316 | PCIPM = 0x44, | ||
317 | }; | ||
318 | |||
319 | enum ChipCmd_bits { | ||
320 | ChipReset = 0x100, | ||
321 | RxReset = 0x20, | ||
322 | TxReset = 0x10, | ||
323 | RxOff = 0x08, | ||
324 | RxOn = 0x04, | ||
325 | TxOff = 0x02, | ||
326 | TxOn = 0x01, | ||
327 | }; | ||
328 | |||
329 | enum ChipConfig_bits { | ||
330 | CfgPhyDis = 0x200, | ||
331 | CfgPhyRst = 0x400, | ||
332 | CfgExtPhy = 0x1000, | ||
333 | CfgAnegEnable = 0x2000, | ||
334 | CfgAneg100 = 0x4000, | ||
335 | CfgAnegFull = 0x8000, | ||
336 | CfgAnegDone = 0x8000000, | ||
337 | CfgFullDuplex = 0x20000000, | ||
338 | CfgSpeed100 = 0x40000000, | ||
339 | CfgLink = 0x80000000, | ||
340 | }; | ||
341 | |||
342 | enum EECtrl_bits { | ||
343 | EE_ShiftClk = 0x04, | ||
344 | EE_DataIn = 0x01, | ||
345 | EE_ChipSelect = 0x08, | ||
346 | EE_DataOut = 0x02, | ||
347 | MII_Data = 0x10, | ||
348 | MII_Write = 0x20, | ||
349 | MII_ShiftClk = 0x40, | ||
350 | }; | ||
351 | |||
352 | enum PCIBusCfg_bits { | ||
353 | EepromReload = 0x4, | ||
354 | }; | ||
355 | |||
356 | /* Bits in the interrupt status/mask registers. */ | ||
357 | enum IntrStatus_bits { | ||
358 | IntrRxDone = 0x0001, | ||
359 | IntrRxIntr = 0x0002, | ||
360 | IntrRxErr = 0x0004, | ||
361 | IntrRxEarly = 0x0008, | ||
362 | IntrRxIdle = 0x0010, | ||
363 | IntrRxOverrun = 0x0020, | ||
364 | IntrTxDone = 0x0040, | ||
365 | IntrTxIntr = 0x0080, | ||
366 | IntrTxErr = 0x0100, | ||
367 | IntrTxIdle = 0x0200, | ||
368 | IntrTxUnderrun = 0x0400, | ||
369 | StatsMax = 0x0800, | ||
370 | SWInt = 0x1000, | ||
371 | WOLPkt = 0x2000, | ||
372 | LinkChange = 0x4000, | ||
373 | IntrHighBits = 0x8000, | ||
374 | RxStatusFIFOOver = 0x10000, | ||
375 | IntrPCIErr = 0xf00000, | ||
376 | RxResetDone = 0x1000000, | ||
377 | TxResetDone = 0x2000000, | ||
378 | IntrAbnormalSummary = 0xCD20, | ||
379 | }; | ||
380 | |||
381 | /* | ||
382 | * Default Interrupts: | ||
383 | * Rx OK, Rx Packet Error, Rx Overrun, | ||
384 | * Tx OK, Tx Packet Error, Tx Underrun, | ||
385 | * MIB Service, Phy Interrupt, High Bits, | ||
386 | * Rx Status FIFO overrun, | ||
387 | * Received Target Abort, Received Master Abort, | ||
388 | * Signalled System Error, Received Parity Error | ||
389 | */ | ||
390 | #define DEFAULT_INTR 0x00f1cd65 | ||
391 | |||
392 | enum TxConfig_bits { | ||
393 | TxDrthMask = 0x3f, | ||
394 | TxFlthMask = 0x3f00, | ||
395 | TxMxdmaMask = 0x700000, | ||
396 | TxMxdma_512 = 0x0, | ||
397 | TxMxdma_4 = 0x100000, | ||
398 | TxMxdma_8 = 0x200000, | ||
399 | TxMxdma_16 = 0x300000, | ||
400 | TxMxdma_32 = 0x400000, | ||
401 | TxMxdma_64 = 0x500000, | ||
402 | TxMxdma_128 = 0x600000, | ||
403 | TxMxdma_256 = 0x700000, | ||
404 | TxCollRetry = 0x800000, | ||
405 | TxAutoPad = 0x10000000, | ||
406 | TxMacLoop = 0x20000000, | ||
407 | TxHeartIgn = 0x40000000, | ||
408 | TxCarrierIgn = 0x80000000 | ||
409 | }; | ||
410 | |||
411 | /* | ||
412 | * Tx Configuration: | ||
413 | * - 256 byte DMA burst length | ||
414 | * - fill threshold 512 bytes (i.e. restart DMA when 512 bytes are free) | ||
415 | * - 64 bytes initial drain threshold (i.e. begin actual transmission | ||
416 | * when 64 byte are in the fifo) | ||
417 | * - on tx underruns, increase drain threshold by 64. | ||
418 | * - at most use a drain threshold of 1472 bytes: The sum of the fill | ||
419 | * threshold and the drain threshold must be less than 2016 bytes. | ||
420 | * | ||
421 | */ | ||
422 | #define TX_FLTH_VAL ((512/32) << 8) | ||
423 | #define TX_DRTH_VAL_START (64/32) | ||
424 | #define TX_DRTH_VAL_INC 2 | ||
425 | #define TX_DRTH_VAL_LIMIT (1472/32) | ||
426 | |||
427 | enum RxConfig_bits { | ||
428 | RxDrthMask = 0x3e, | ||
429 | RxMxdmaMask = 0x700000, | ||
430 | RxMxdma_512 = 0x0, | ||
431 | RxMxdma_4 = 0x100000, | ||
432 | RxMxdma_8 = 0x200000, | ||
433 | RxMxdma_16 = 0x300000, | ||
434 | RxMxdma_32 = 0x400000, | ||
435 | RxMxdma_64 = 0x500000, | ||
436 | RxMxdma_128 = 0x600000, | ||
437 | RxMxdma_256 = 0x700000, | ||
438 | RxAcceptLong = 0x8000000, | ||
439 | RxAcceptTx = 0x10000000, | ||
440 | RxAcceptRunt = 0x40000000, | ||
441 | RxAcceptErr = 0x80000000 | ||
442 | }; | ||
443 | #define RX_DRTH_VAL (128/8) | ||
444 | |||
445 | enum ClkRun_bits { | ||
446 | PMEEnable = 0x100, | ||
447 | PMEStatus = 0x8000, | ||
448 | }; | ||
449 | |||
450 | enum WolCmd_bits { | ||
451 | WakePhy = 0x1, | ||
452 | WakeUnicast = 0x2, | ||
453 | WakeMulticast = 0x4, | ||
454 | WakeBroadcast = 0x8, | ||
455 | WakeArp = 0x10, | ||
456 | WakePMatch0 = 0x20, | ||
457 | WakePMatch1 = 0x40, | ||
458 | WakePMatch2 = 0x80, | ||
459 | WakePMatch3 = 0x100, | ||
460 | WakeMagic = 0x200, | ||
461 | WakeMagicSecure = 0x400, | ||
462 | SecureHack = 0x100000, | ||
463 | WokePhy = 0x400000, | ||
464 | WokeUnicast = 0x800000, | ||
465 | WokeMulticast = 0x1000000, | ||
466 | WokeBroadcast = 0x2000000, | ||
467 | WokeArp = 0x4000000, | ||
468 | WokePMatch0 = 0x8000000, | ||
469 | WokePMatch1 = 0x10000000, | ||
470 | WokePMatch2 = 0x20000000, | ||
471 | WokePMatch3 = 0x40000000, | ||
472 | WokeMagic = 0x80000000, | ||
473 | WakeOptsSummary = 0x7ff | ||
474 | }; | ||
475 | |||
476 | enum RxFilterAddr_bits { | ||
477 | RFCRAddressMask = 0x3ff, | ||
478 | AcceptMulticast = 0x00200000, | ||
479 | AcceptMyPhys = 0x08000000, | ||
480 | AcceptAllPhys = 0x10000000, | ||
481 | AcceptAllMulticast = 0x20000000, | ||
482 | AcceptBroadcast = 0x40000000, | ||
483 | RxFilterEnable = 0x80000000 | ||
484 | }; | ||
485 | |||
486 | enum StatsCtrl_bits { | ||
487 | StatsWarn = 0x1, | ||
488 | StatsFreeze = 0x2, | ||
489 | StatsClear = 0x4, | ||
490 | StatsStrobe = 0x8, | ||
491 | }; | ||
492 | |||
493 | enum MIntrCtrl_bits { | ||
494 | MICRIntEn = 0x2, | ||
495 | }; | ||
496 | |||
497 | enum PhyCtrl_bits { | ||
498 | PhyAddrMask = 0x1f, | ||
499 | }; | ||
500 | |||
501 | #define PHY_ADDR_NONE 32 | ||
502 | #define PHY_ADDR_INTERNAL 1 | ||
503 | |||
504 | /* values we might find in the silicon revision register */ | ||
505 | #define SRR_DP83815_C 0x0302 | ||
506 | #define SRR_DP83815_D 0x0403 | ||
507 | #define SRR_DP83816_A4 0x0504 | ||
508 | #define SRR_DP83816_A5 0x0505 | ||
509 | |||
510 | /* The Rx and Tx buffer descriptors. */ | ||
511 | /* Note that using only 32 bit fields simplifies conversion to big-endian | ||
512 | architectures. */ | ||
513 | struct netdev_desc { | ||
514 | __le32 next_desc; | ||
515 | __le32 cmd_status; | ||
516 | __le32 addr; | ||
517 | __le32 software_use; | ||
518 | }; | ||
519 | |||
520 | /* Bits in network_desc.status */ | ||
521 | enum desc_status_bits { | ||
522 | DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000, | ||
523 | DescNoCRC=0x10000000, DescPktOK=0x08000000, | ||
524 | DescSizeMask=0xfff, | ||
525 | |||
526 | DescTxAbort=0x04000000, DescTxFIFO=0x02000000, | ||
527 | DescTxCarrier=0x01000000, DescTxDefer=0x00800000, | ||
528 | DescTxExcDefer=0x00400000, DescTxOOWCol=0x00200000, | ||
529 | DescTxExcColl=0x00100000, DescTxCollCount=0x000f0000, | ||
530 | |||
531 | DescRxAbort=0x04000000, DescRxOver=0x02000000, | ||
532 | DescRxDest=0x01800000, DescRxLong=0x00400000, | ||
533 | DescRxRunt=0x00200000, DescRxInvalid=0x00100000, | ||
534 | DescRxCRC=0x00080000, DescRxAlign=0x00040000, | ||
535 | DescRxLoop=0x00020000, DesRxColl=0x00010000, | ||
536 | }; | ||
537 | |||
538 | struct netdev_private { | ||
539 | /* Descriptor rings first for alignment */ | ||
540 | dma_addr_t ring_dma; | ||
541 | struct netdev_desc *rx_ring; | ||
542 | struct netdev_desc *tx_ring; | ||
543 | /* The addresses of receive-in-place skbuffs */ | ||
544 | struct sk_buff *rx_skbuff[RX_RING_SIZE]; | ||
545 | dma_addr_t rx_dma[RX_RING_SIZE]; | ||
546 | /* address of a sent-in-place packet/buffer, for later free() */ | ||
547 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; | ||
548 | dma_addr_t tx_dma[TX_RING_SIZE]; | ||
549 | struct net_device *dev; | ||
550 | struct napi_struct napi; | ||
551 | /* Media monitoring timer */ | ||
552 | struct timer_list timer; | ||
553 | /* Frequently used values: keep some adjacent for cache effect */ | ||
554 | struct pci_dev *pci_dev; | ||
555 | struct netdev_desc *rx_head_desc; | ||
556 | /* Producer/consumer ring indices */ | ||
557 | unsigned int cur_rx, dirty_rx; | ||
558 | unsigned int cur_tx, dirty_tx; | ||
559 | /* Based on MTU+slack. */ | ||
560 | unsigned int rx_buf_sz; | ||
561 | int oom; | ||
562 | /* Interrupt status */ | ||
563 | u32 intr_status; | ||
564 | /* Do not touch the nic registers */ | ||
565 | int hands_off; | ||
566 | /* Don't pay attention to the reported link state. */ | ||
567 | int ignore_phy; | ||
568 | /* external phy that is used: only valid if dev->if_port != PORT_TP */ | ||
569 | int mii; | ||
570 | int phy_addr_external; | ||
571 | unsigned int full_duplex; | ||
572 | /* Rx filter */ | ||
573 | u32 cur_rx_mode; | ||
574 | u32 rx_filter[16]; | ||
575 | /* FIFO and PCI burst thresholds */ | ||
576 | u32 tx_config, rx_config; | ||
577 | /* original contents of ClkRun register */ | ||
578 | u32 SavedClkRun; | ||
579 | /* silicon revision */ | ||
580 | u32 srr; | ||
581 | /* expected DSPCFG value */ | ||
582 | u16 dspcfg; | ||
583 | int dspcfg_workaround; | ||
584 | /* parms saved in ethtool format */ | ||
585 | u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ | ||
586 | u8 duplex; /* Duplex, half or full */ | ||
587 | u8 autoneg; /* Autonegotiation enabled */ | ||
588 | /* MII transceiver section */ | ||
589 | u16 advertising; | ||
590 | unsigned int iosize; | ||
591 | spinlock_t lock; | ||
592 | u32 msg_enable; | ||
593 | /* EEPROM data */ | ||
594 | int eeprom_size; | ||
595 | }; | ||
596 | |||
597 | static void move_int_phy(struct net_device *dev, int addr); | ||
598 | static int eeprom_read(void __iomem *ioaddr, int location); | ||
599 | static int mdio_read(struct net_device *dev, int reg); | ||
600 | static void mdio_write(struct net_device *dev, int reg, u16 data); | ||
601 | static void init_phy_fixup(struct net_device *dev); | ||
602 | static int miiport_read(struct net_device *dev, int phy_id, int reg); | ||
603 | static void miiport_write(struct net_device *dev, int phy_id, int reg, u16 data); | ||
604 | static int find_mii(struct net_device *dev); | ||
605 | static void natsemi_reset(struct net_device *dev); | ||
606 | static void natsemi_reload_eeprom(struct net_device *dev); | ||
607 | static void natsemi_stop_rxtx(struct net_device *dev); | ||
608 | static int netdev_open(struct net_device *dev); | ||
609 | static void do_cable_magic(struct net_device *dev); | ||
610 | static void undo_cable_magic(struct net_device *dev); | ||
611 | static void check_link(struct net_device *dev); | ||
612 | static void netdev_timer(unsigned long data); | ||
613 | static void dump_ring(struct net_device *dev); | ||
614 | static void ns_tx_timeout(struct net_device *dev); | ||
615 | static int alloc_ring(struct net_device *dev); | ||
616 | static void refill_rx(struct net_device *dev); | ||
617 | static void init_ring(struct net_device *dev); | ||
618 | static void drain_tx(struct net_device *dev); | ||
619 | static void drain_ring(struct net_device *dev); | ||
620 | static void free_ring(struct net_device *dev); | ||
621 | static void reinit_ring(struct net_device *dev); | ||
622 | static void init_registers(struct net_device *dev); | ||
623 | static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev); | ||
624 | static irqreturn_t intr_handler(int irq, void *dev_instance); | ||
625 | static void netdev_error(struct net_device *dev, int intr_status); | ||
626 | static int natsemi_poll(struct napi_struct *napi, int budget); | ||
627 | static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do); | ||
628 | static void netdev_tx_done(struct net_device *dev); | ||
629 | static int natsemi_change_mtu(struct net_device *dev, int new_mtu); | ||
630 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
631 | static void natsemi_poll_controller(struct net_device *dev); | ||
632 | #endif | ||
633 | static void __set_rx_mode(struct net_device *dev); | ||
634 | static void set_rx_mode(struct net_device *dev); | ||
635 | static void __get_stats(struct net_device *dev); | ||
636 | static struct net_device_stats *get_stats(struct net_device *dev); | ||
637 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | ||
638 | static int netdev_set_wol(struct net_device *dev, u32 newval); | ||
639 | static int netdev_get_wol(struct net_device *dev, u32 *supported, u32 *cur); | ||
640 | static int netdev_set_sopass(struct net_device *dev, u8 *newval); | ||
641 | static int netdev_get_sopass(struct net_device *dev, u8 *data); | ||
642 | static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd); | ||
643 | static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd); | ||
644 | static void enable_wol_mode(struct net_device *dev, int enable_intr); | ||
645 | static int netdev_close(struct net_device *dev); | ||
646 | static int netdev_get_regs(struct net_device *dev, u8 *buf); | ||
647 | static int netdev_get_eeprom(struct net_device *dev, u8 *buf); | ||
648 | static const struct ethtool_ops ethtool_ops; | ||
649 | |||
650 | #define NATSEMI_ATTR(_name) \ | ||
651 | static ssize_t natsemi_show_##_name(struct device *dev, \ | ||
652 | struct device_attribute *attr, char *buf); \ | ||
653 | static ssize_t natsemi_set_##_name(struct device *dev, \ | ||
654 | struct device_attribute *attr, \ | ||
655 | const char *buf, size_t count); \ | ||
656 | static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name) | ||
657 | |||
658 | #define NATSEMI_CREATE_FILE(_dev, _name) \ | ||
659 | device_create_file(&_dev->dev, &dev_attr_##_name) | ||
660 | #define NATSEMI_REMOVE_FILE(_dev, _name) \ | ||
661 | device_remove_file(&_dev->dev, &dev_attr_##_name) | ||
662 | |||
663 | NATSEMI_ATTR(dspcfg_workaround); | ||
664 | |||
665 | static ssize_t natsemi_show_dspcfg_workaround(struct device *dev, | ||
666 | struct device_attribute *attr, | ||
667 | char *buf) | ||
668 | { | ||
669 | struct netdev_private *np = netdev_priv(to_net_dev(dev)); | ||
670 | |||
671 | return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off"); | ||
672 | } | ||
673 | |||
674 | static ssize_t natsemi_set_dspcfg_workaround(struct device *dev, | ||
675 | struct device_attribute *attr, | ||
676 | const char *buf, size_t count) | ||
677 | { | ||
678 | struct netdev_private *np = netdev_priv(to_net_dev(dev)); | ||
679 | int new_setting; | ||
680 | unsigned long flags; | ||
681 | |||
682 | /* Find out the new setting */ | ||
683 | if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) | ||
684 | new_setting = 1; | ||
685 | else if (!strncmp("off", buf, count - 1) || | ||
686 | !strncmp("0", buf, count - 1)) | ||
687 | new_setting = 0; | ||
688 | else | ||
689 | return count; | ||
690 | |||
691 | spin_lock_irqsave(&np->lock, flags); | ||
692 | |||
693 | np->dspcfg_workaround = new_setting; | ||
694 | |||
695 | spin_unlock_irqrestore(&np->lock, flags); | ||
696 | |||
697 | return count; | ||
698 | } | ||
699 | |||
700 | static inline void __iomem *ns_ioaddr(struct net_device *dev) | ||
701 | { | ||
702 | return (void __iomem *) dev->base_addr; | ||
703 | } | ||
704 | |||
705 | static inline void natsemi_irq_enable(struct net_device *dev) | ||
706 | { | ||
707 | writel(1, ns_ioaddr(dev) + IntrEnable); | ||
708 | readl(ns_ioaddr(dev) + IntrEnable); | ||
709 | } | ||
710 | |||
711 | static inline void natsemi_irq_disable(struct net_device *dev) | ||
712 | { | ||
713 | writel(0, ns_ioaddr(dev) + IntrEnable); | ||
714 | readl(ns_ioaddr(dev) + IntrEnable); | ||
715 | } | ||
716 | |||
717 | static void move_int_phy(struct net_device *dev, int addr) | ||
718 | { | ||
719 | struct netdev_private *np = netdev_priv(dev); | ||
720 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
721 | int target = 31; | ||
722 | |||
723 | /* | ||
724 | * The internal phy is visible on the external mii bus. Therefore we must | ||
725 | * move it away before we can send commands to an external phy. | ||
726 | * There are two addresses we must avoid: | ||
727 | * - the address on the external phy that is used for transmission. | ||
728 | * - the address that we want to access. User space can access phys | ||
729 | * on the mii bus with SIOCGMIIREG/SIOCSMIIREG, independent from the | ||
730 | * phy that is used for transmission. | ||
731 | */ | ||
732 | |||
733 | if (target == addr) | ||
734 | target--; | ||
735 | if (target == np->phy_addr_external) | ||
736 | target--; | ||
737 | writew(target, ioaddr + PhyCtrl); | ||
738 | readw(ioaddr + PhyCtrl); | ||
739 | udelay(1); | ||
740 | } | ||
741 | |||
742 | static void __devinit natsemi_init_media (struct net_device *dev) | ||
743 | { | ||
744 | struct netdev_private *np = netdev_priv(dev); | ||
745 | u32 tmp; | ||
746 | |||
747 | if (np->ignore_phy) | ||
748 | netif_carrier_on(dev); | ||
749 | else | ||
750 | netif_carrier_off(dev); | ||
751 | |||
752 | /* get the initial settings from hardware */ | ||
753 | tmp = mdio_read(dev, MII_BMCR); | ||
754 | np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; | ||
755 | np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; | ||
756 | np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; | ||
757 | np->advertising= mdio_read(dev, MII_ADVERTISE); | ||
758 | |||
759 | if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL && | ||
760 | netif_msg_probe(np)) { | ||
761 | printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s " | ||
762 | "10%s %s duplex.\n", | ||
763 | pci_name(np->pci_dev), | ||
764 | (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)? | ||
765 | "enabled, advertise" : "disabled, force", | ||
766 | (np->advertising & | ||
767 | (ADVERTISE_100FULL|ADVERTISE_100HALF))? | ||
768 | "0" : "", | ||
769 | (np->advertising & | ||
770 | (ADVERTISE_100FULL|ADVERTISE_10FULL))? | ||
771 | "full" : "half"); | ||
772 | } | ||
773 | if (netif_msg_probe(np)) | ||
774 | printk(KERN_INFO | ||
775 | "natsemi %s: Transceiver status %#04x advertising %#04x.\n", | ||
776 | pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), | ||
777 | np->advertising); | ||
778 | |||
779 | } | ||
780 | |||
781 | static const struct net_device_ops natsemi_netdev_ops = { | ||
782 | .ndo_open = netdev_open, | ||
783 | .ndo_stop = netdev_close, | ||
784 | .ndo_start_xmit = start_tx, | ||
785 | .ndo_get_stats = get_stats, | ||
786 | .ndo_set_multicast_list = set_rx_mode, | ||
787 | .ndo_change_mtu = natsemi_change_mtu, | ||
788 | .ndo_do_ioctl = netdev_ioctl, | ||
789 | .ndo_tx_timeout = ns_tx_timeout, | ||
790 | .ndo_set_mac_address = eth_mac_addr, | ||
791 | .ndo_validate_addr = eth_validate_addr, | ||
792 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
793 | .ndo_poll_controller = natsemi_poll_controller, | ||
794 | #endif | ||
795 | }; | ||
796 | |||
797 | static int __devinit natsemi_probe1 (struct pci_dev *pdev, | ||
798 | const struct pci_device_id *ent) | ||
799 | { | ||
800 | struct net_device *dev; | ||
801 | struct netdev_private *np; | ||
802 | int i, option, irq, chip_idx = ent->driver_data; | ||
803 | static int find_cnt = -1; | ||
804 | resource_size_t iostart; | ||
805 | unsigned long iosize; | ||
806 | void __iomem *ioaddr; | ||
807 | const int pcibar = 1; /* PCI base address register */ | ||
808 | int prev_eedata; | ||
809 | u32 tmp; | ||
810 | |||
811 | /* when built into the kernel, we only print version if device is found */ | ||
812 | #ifndef MODULE | ||
813 | static int printed_version; | ||
814 | if (!printed_version++) | ||
815 | printk(version); | ||
816 | #endif | ||
817 | |||
818 | i = pci_enable_device(pdev); | ||
819 | if (i) return i; | ||
820 | |||
821 | /* natsemi has a non-standard PM control register | ||
822 | * in PCI config space. Some boards apparently need | ||
823 | * to be brought to D0 in this manner. | ||
824 | */ | ||
825 | pci_read_config_dword(pdev, PCIPM, &tmp); | ||
826 | if (tmp & PCI_PM_CTRL_STATE_MASK) { | ||
827 | /* D0 state, disable PME assertion */ | ||
828 | u32 newtmp = tmp & ~PCI_PM_CTRL_STATE_MASK; | ||
829 | pci_write_config_dword(pdev, PCIPM, newtmp); | ||
830 | } | ||
831 | |||
832 | find_cnt++; | ||
833 | iostart = pci_resource_start(pdev, pcibar); | ||
834 | iosize = pci_resource_len(pdev, pcibar); | ||
835 | irq = pdev->irq; | ||
836 | |||
837 | pci_set_master(pdev); | ||
838 | |||
839 | dev = alloc_etherdev(sizeof (struct netdev_private)); | ||
840 | if (!dev) | ||
841 | return -ENOMEM; | ||
842 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
843 | |||
844 | i = pci_request_regions(pdev, DRV_NAME); | ||
845 | if (i) | ||
846 | goto err_pci_request_regions; | ||
847 | |||
848 | ioaddr = ioremap(iostart, iosize); | ||
849 | if (!ioaddr) { | ||
850 | i = -ENOMEM; | ||
851 | goto err_ioremap; | ||
852 | } | ||
853 | |||
854 | /* Work around the dropped serial bit. */ | ||
855 | prev_eedata = eeprom_read(ioaddr, 6); | ||
856 | for (i = 0; i < 3; i++) { | ||
857 | int eedata = eeprom_read(ioaddr, i + 7); | ||
858 | dev->dev_addr[i*2] = (eedata << 1) + (prev_eedata >> 15); | ||
859 | dev->dev_addr[i*2+1] = eedata >> 7; | ||
860 | prev_eedata = eedata; | ||
861 | } | ||
862 | |||
863 | /* Store MAC Address in perm_addr */ | ||
864 | memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); | ||
865 | |||
866 | dev->base_addr = (unsigned long __force) ioaddr; | ||
867 | dev->irq = irq; | ||
868 | |||
869 | np = netdev_priv(dev); | ||
870 | netif_napi_add(dev, &np->napi, natsemi_poll, 64); | ||
871 | np->dev = dev; | ||
872 | |||
873 | np->pci_dev = pdev; | ||
874 | pci_set_drvdata(pdev, dev); | ||
875 | np->iosize = iosize; | ||
876 | spin_lock_init(&np->lock); | ||
877 | np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; | ||
878 | np->hands_off = 0; | ||
879 | np->intr_status = 0; | ||
880 | np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size; | ||
881 | if (natsemi_pci_info[chip_idx].flags & NATSEMI_FLAG_IGNORE_PHY) | ||
882 | np->ignore_phy = 1; | ||
883 | else | ||
884 | np->ignore_phy = 0; | ||
885 | np->dspcfg_workaround = dspcfg_workaround; | ||
886 | |||
887 | /* Initial port: | ||
888 | * - If configured to ignore the PHY set up for external. | ||
889 | * - If the nic was configured to use an external phy and if find_mii | ||
890 | * finds a phy: use external port, first phy that replies. | ||
891 | * - Otherwise: internal port. | ||
892 | * Note that the phy address for the internal phy doesn't matter: | ||
893 | * The address would be used to access a phy over the mii bus, but | ||
894 | * the internal phy is accessed through mapped registers. | ||
895 | */ | ||
896 | if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy) | ||
897 | dev->if_port = PORT_MII; | ||
898 | else | ||
899 | dev->if_port = PORT_TP; | ||
900 | /* Reset the chip to erase previous misconfiguration. */ | ||
901 | natsemi_reload_eeprom(dev); | ||
902 | natsemi_reset(dev); | ||
903 | |||
904 | if (dev->if_port != PORT_TP) { | ||
905 | np->phy_addr_external = find_mii(dev); | ||
906 | /* If we're ignoring the PHY it doesn't matter if we can't | ||
907 | * find one. */ | ||
908 | if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) { | ||
909 | dev->if_port = PORT_TP; | ||
910 | np->phy_addr_external = PHY_ADDR_INTERNAL; | ||
911 | } | ||
912 | } else { | ||
913 | np->phy_addr_external = PHY_ADDR_INTERNAL; | ||
914 | } | ||
915 | |||
916 | option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; | ||
917 | if (dev->mem_start) | ||
918 | option = dev->mem_start; | ||
919 | |||
920 | /* The lower four bits are the media type. */ | ||
921 | if (option) { | ||
922 | if (option & 0x200) | ||
923 | np->full_duplex = 1; | ||
924 | if (option & 15) | ||
925 | printk(KERN_INFO | ||
926 | "natsemi %s: ignoring user supplied media type %d", | ||
927 | pci_name(np->pci_dev), option & 15); | ||
928 | } | ||
929 | if (find_cnt < MAX_UNITS && full_duplex[find_cnt]) | ||
930 | np->full_duplex = 1; | ||
931 | |||
932 | dev->netdev_ops = &natsemi_netdev_ops; | ||
933 | dev->watchdog_timeo = TX_TIMEOUT; | ||
934 | |||
935 | SET_ETHTOOL_OPS(dev, ðtool_ops); | ||
936 | |||
937 | if (mtu) | ||
938 | dev->mtu = mtu; | ||
939 | |||
940 | natsemi_init_media(dev); | ||
941 | |||
942 | /* save the silicon revision for later querying */ | ||
943 | np->srr = readl(ioaddr + SiliconRev); | ||
944 | if (netif_msg_hw(np)) | ||
945 | printk(KERN_INFO "natsemi %s: silicon revision %#04x.\n", | ||
946 | pci_name(np->pci_dev), np->srr); | ||
947 | |||
948 | i = register_netdev(dev); | ||
949 | if (i) | ||
950 | goto err_register_netdev; | ||
951 | |||
952 | if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround)) | ||
953 | goto err_create_file; | ||
954 | |||
955 | if (netif_msg_drv(np)) { | ||
956 | printk(KERN_INFO "natsemi %s: %s at %#08llx " | ||
957 | "(%s), %pM, IRQ %d", | ||
958 | dev->name, natsemi_pci_info[chip_idx].name, | ||
959 | (unsigned long long)iostart, pci_name(np->pci_dev), | ||
960 | dev->dev_addr, irq); | ||
961 | if (dev->if_port == PORT_TP) | ||
962 | printk(", port TP.\n"); | ||
963 | else if (np->ignore_phy) | ||
964 | printk(", port MII, ignoring PHY\n"); | ||
965 | else | ||
966 | printk(", port MII, phy ad %d.\n", np->phy_addr_external); | ||
967 | } | ||
968 | return 0; | ||
969 | |||
970 | err_create_file: | ||
971 | unregister_netdev(dev); | ||
972 | |||
973 | err_register_netdev: | ||
974 | iounmap(ioaddr); | ||
975 | |||
976 | err_ioremap: | ||
977 | pci_release_regions(pdev); | ||
978 | pci_set_drvdata(pdev, NULL); | ||
979 | |||
980 | err_pci_request_regions: | ||
981 | free_netdev(dev); | ||
982 | return i; | ||
983 | } | ||
984 | |||
985 | |||
986 | /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. | ||
987 | The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */ | ||
988 | |||
989 | /* Delay between EEPROM clock transitions. | ||
990 | No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need | ||
991 | a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that | ||
992 | made udelay() unreliable. | ||
993 | The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is | ||
994 | deprecated. | ||
995 | */ | ||
996 | #define eeprom_delay(ee_addr) readl(ee_addr) | ||
997 | |||
998 | #define EE_Write0 (EE_ChipSelect) | ||
999 | #define EE_Write1 (EE_ChipSelect | EE_DataIn) | ||
1000 | |||
1001 | /* The EEPROM commands include the alway-set leading bit. */ | ||
1002 | enum EEPROM_Cmds { | ||
1003 | EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6), | ||
1004 | }; | ||
1005 | |||
1006 | static int eeprom_read(void __iomem *addr, int location) | ||
1007 | { | ||
1008 | int i; | ||
1009 | int retval = 0; | ||
1010 | void __iomem *ee_addr = addr + EECtrl; | ||
1011 | int read_cmd = location | EE_ReadCmd; | ||
1012 | |||
1013 | writel(EE_Write0, ee_addr); | ||
1014 | |||
1015 | /* Shift the read command bits out. */ | ||
1016 | for (i = 10; i >= 0; i--) { | ||
1017 | short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0; | ||
1018 | writel(dataval, ee_addr); | ||
1019 | eeprom_delay(ee_addr); | ||
1020 | writel(dataval | EE_ShiftClk, ee_addr); | ||
1021 | eeprom_delay(ee_addr); | ||
1022 | } | ||
1023 | writel(EE_ChipSelect, ee_addr); | ||
1024 | eeprom_delay(ee_addr); | ||
1025 | |||
1026 | for (i = 0; i < 16; i++) { | ||
1027 | writel(EE_ChipSelect | EE_ShiftClk, ee_addr); | ||
1028 | eeprom_delay(ee_addr); | ||
1029 | retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0; | ||
1030 | writel(EE_ChipSelect, ee_addr); | ||
1031 | eeprom_delay(ee_addr); | ||
1032 | } | ||
1033 | |||
1034 | /* Terminate the EEPROM access. */ | ||
1035 | writel(EE_Write0, ee_addr); | ||
1036 | writel(0, ee_addr); | ||
1037 | return retval; | ||
1038 | } | ||
1039 | |||
1040 | /* MII transceiver control section. | ||
1041 | * The 83815 series has an internal transceiver, and we present the | ||
1042 | * internal management registers as if they were MII connected. | ||
1043 | * External Phy registers are referenced through the MII interface. | ||
1044 | */ | ||
1045 | |||
1046 | /* clock transitions >= 20ns (25MHz) | ||
1047 | * One readl should be good to PCI @ 100MHz | ||
1048 | */ | ||
1049 | #define mii_delay(ioaddr) readl(ioaddr + EECtrl) | ||
1050 | |||
1051 | static int mii_getbit (struct net_device *dev) | ||
1052 | { | ||
1053 | int data; | ||
1054 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1055 | |||
1056 | writel(MII_ShiftClk, ioaddr + EECtrl); | ||
1057 | data = readl(ioaddr + EECtrl); | ||
1058 | writel(0, ioaddr + EECtrl); | ||
1059 | mii_delay(ioaddr); | ||
1060 | return (data & MII_Data)? 1 : 0; | ||
1061 | } | ||
1062 | |||
1063 | static void mii_send_bits (struct net_device *dev, u32 data, int len) | ||
1064 | { | ||
1065 | u32 i; | ||
1066 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1067 | |||
1068 | for (i = (1 << (len-1)); i; i >>= 1) | ||
1069 | { | ||
1070 | u32 mdio_val = MII_Write | ((data & i)? MII_Data : 0); | ||
1071 | writel(mdio_val, ioaddr + EECtrl); | ||
1072 | mii_delay(ioaddr); | ||
1073 | writel(mdio_val | MII_ShiftClk, ioaddr + EECtrl); | ||
1074 | mii_delay(ioaddr); | ||
1075 | } | ||
1076 | writel(0, ioaddr + EECtrl); | ||
1077 | mii_delay(ioaddr); | ||
1078 | } | ||
1079 | |||
1080 | static int miiport_read(struct net_device *dev, int phy_id, int reg) | ||
1081 | { | ||
1082 | u32 cmd; | ||
1083 | int i; | ||
1084 | u32 retval = 0; | ||
1085 | |||
1086 | /* Ensure sync */ | ||
1087 | mii_send_bits (dev, 0xffffffff, 32); | ||
1088 | /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */ | ||
1089 | /* ST,OP = 0110'b for read operation */ | ||
1090 | cmd = (0x06 << 10) | (phy_id << 5) | reg; | ||
1091 | mii_send_bits (dev, cmd, 14); | ||
1092 | /* Turnaround */ | ||
1093 | if (mii_getbit (dev)) | ||
1094 | return 0; | ||
1095 | /* Read data */ | ||
1096 | for (i = 0; i < 16; i++) { | ||
1097 | retval <<= 1; | ||
1098 | retval |= mii_getbit (dev); | ||
1099 | } | ||
1100 | /* End cycle */ | ||
1101 | mii_getbit (dev); | ||
1102 | return retval; | ||
1103 | } | ||
1104 | |||
1105 | static void miiport_write(struct net_device *dev, int phy_id, int reg, u16 data) | ||
1106 | { | ||
1107 | u32 cmd; | ||
1108 | |||
1109 | /* Ensure sync */ | ||
1110 | mii_send_bits (dev, 0xffffffff, 32); | ||
1111 | /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */ | ||
1112 | /* ST,OP,AAAAA,RRRRR,TA = 0101xxxxxxxxxx10'b = 0x5002 for write */ | ||
1113 | cmd = (0x5002 << 16) | (phy_id << 23) | (reg << 18) | data; | ||
1114 | mii_send_bits (dev, cmd, 32); | ||
1115 | /* End cycle */ | ||
1116 | mii_getbit (dev); | ||
1117 | } | ||
1118 | |||
1119 | static int mdio_read(struct net_device *dev, int reg) | ||
1120 | { | ||
1121 | struct netdev_private *np = netdev_priv(dev); | ||
1122 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1123 | |||
1124 | /* The 83815 series has two ports: | ||
1125 | * - an internal transceiver | ||
1126 | * - an external mii bus | ||
1127 | */ | ||
1128 | if (dev->if_port == PORT_TP) | ||
1129 | return readw(ioaddr+BasicControl+(reg<<2)); | ||
1130 | else | ||
1131 | return miiport_read(dev, np->phy_addr_external, reg); | ||
1132 | } | ||
1133 | |||
1134 | static void mdio_write(struct net_device *dev, int reg, u16 data) | ||
1135 | { | ||
1136 | struct netdev_private *np = netdev_priv(dev); | ||
1137 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1138 | |||
1139 | /* The 83815 series has an internal transceiver; handle separately */ | ||
1140 | if (dev->if_port == PORT_TP) | ||
1141 | writew(data, ioaddr+BasicControl+(reg<<2)); | ||
1142 | else | ||
1143 | miiport_write(dev, np->phy_addr_external, reg, data); | ||
1144 | } | ||
1145 | |||
1146 | static void init_phy_fixup(struct net_device *dev) | ||
1147 | { | ||
1148 | struct netdev_private *np = netdev_priv(dev); | ||
1149 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1150 | int i; | ||
1151 | u32 cfg; | ||
1152 | u16 tmp; | ||
1153 | |||
1154 | /* restore stuff lost when power was out */ | ||
1155 | tmp = mdio_read(dev, MII_BMCR); | ||
1156 | if (np->autoneg == AUTONEG_ENABLE) { | ||
1157 | /* renegotiate if something changed */ | ||
1158 | if ((tmp & BMCR_ANENABLE) == 0 || | ||
1159 | np->advertising != mdio_read(dev, MII_ADVERTISE)) | ||
1160 | { | ||
1161 | /* turn on autonegotiation and force negotiation */ | ||
1162 | tmp |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
1163 | mdio_write(dev, MII_ADVERTISE, np->advertising); | ||
1164 | } | ||
1165 | } else { | ||
1166 | /* turn off auto negotiation, set speed and duplexity */ | ||
1167 | tmp &= ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX); | ||
1168 | if (np->speed == SPEED_100) | ||
1169 | tmp |= BMCR_SPEED100; | ||
1170 | if (np->duplex == DUPLEX_FULL) | ||
1171 | tmp |= BMCR_FULLDPLX; | ||
1172 | /* | ||
1173 | * Note: there is no good way to inform the link partner | ||
1174 | * that our capabilities changed. The user has to unplug | ||
1175 | * and replug the network cable after some changes, e.g. | ||
1176 | * after switching from 10HD, autoneg off to 100 HD, | ||
1177 | * autoneg off. | ||
1178 | */ | ||
1179 | } | ||
1180 | mdio_write(dev, MII_BMCR, tmp); | ||
1181 | readl(ioaddr + ChipConfig); | ||
1182 | udelay(1); | ||
1183 | |||
1184 | /* find out what phy this is */ | ||
1185 | np->mii = (mdio_read(dev, MII_PHYSID1) << 16) | ||
1186 | + mdio_read(dev, MII_PHYSID2); | ||
1187 | |||
1188 | /* handle external phys here */ | ||
1189 | switch (np->mii) { | ||
1190 | case PHYID_AM79C874: | ||
1191 | /* phy specific configuration for fibre/tp operation */ | ||
1192 | tmp = mdio_read(dev, MII_MCTRL); | ||
1193 | tmp &= ~(MII_FX_SEL | MII_EN_SCRM); | ||
1194 | if (dev->if_port == PORT_FIBRE) | ||
1195 | tmp |= MII_FX_SEL; | ||
1196 | else | ||
1197 | tmp |= MII_EN_SCRM; | ||
1198 | mdio_write(dev, MII_MCTRL, tmp); | ||
1199 | break; | ||
1200 | default: | ||
1201 | break; | ||
1202 | } | ||
1203 | cfg = readl(ioaddr + ChipConfig); | ||
1204 | if (cfg & CfgExtPhy) | ||
1205 | return; | ||
1206 | |||
1207 | /* On page 78 of the spec, they recommend some settings for "optimum | ||
1208 | performance" to be done in sequence. These settings optimize some | ||
1209 | of the 100Mbit autodetection circuitry. They say we only want to | ||
1210 | do this for rev C of the chip, but engineers at NSC (Bradley | ||
1211 | Kennedy) recommends always setting them. If you don't, you get | ||
1212 | errors on some autonegotiations that make the device unusable. | ||
1213 | |||
1214 | It seems that the DSP needs a few usec to reinitialize after | ||
1215 | the start of the phy. Just retry writing these values until they | ||
1216 | stick. | ||
1217 | */ | ||
1218 | for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { | ||
1219 | |||
1220 | int dspcfg; | ||
1221 | writew(1, ioaddr + PGSEL); | ||
1222 | writew(PMDCSR_VAL, ioaddr + PMDCSR); | ||
1223 | writew(TSTDAT_VAL, ioaddr + TSTDAT); | ||
1224 | np->dspcfg = (np->srr <= SRR_DP83815_C)? | ||
1225 | DSPCFG_VAL : (DSPCFG_COEF | readw(ioaddr + DSPCFG)); | ||
1226 | writew(np->dspcfg, ioaddr + DSPCFG); | ||
1227 | writew(SDCFG_VAL, ioaddr + SDCFG); | ||
1228 | writew(0, ioaddr + PGSEL); | ||
1229 | readl(ioaddr + ChipConfig); | ||
1230 | udelay(10); | ||
1231 | |||
1232 | writew(1, ioaddr + PGSEL); | ||
1233 | dspcfg = readw(ioaddr + DSPCFG); | ||
1234 | writew(0, ioaddr + PGSEL); | ||
1235 | if (np->dspcfg == dspcfg) | ||
1236 | break; | ||
1237 | } | ||
1238 | |||
1239 | if (netif_msg_link(np)) { | ||
1240 | if (i==NATSEMI_HW_TIMEOUT) { | ||
1241 | printk(KERN_INFO | ||
1242 | "%s: DSPCFG mismatch after retrying for %d usec.\n", | ||
1243 | dev->name, i*10); | ||
1244 | } else { | ||
1245 | printk(KERN_INFO | ||
1246 | "%s: DSPCFG accepted after %d usec.\n", | ||
1247 | dev->name, i*10); | ||
1248 | } | ||
1249 | } | ||
1250 | /* | ||
1251 | * Enable PHY Specific event based interrupts. Link state change | ||
1252 | * and Auto-Negotiation Completion are among the affected. | ||
1253 | * Read the intr status to clear it (needed for wake events). | ||
1254 | */ | ||
1255 | readw(ioaddr + MIntrStatus); | ||
1256 | writew(MICRIntEn, ioaddr + MIntrCtrl); | ||
1257 | } | ||
1258 | |||
1259 | static int switch_port_external(struct net_device *dev) | ||
1260 | { | ||
1261 | struct netdev_private *np = netdev_priv(dev); | ||
1262 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1263 | u32 cfg; | ||
1264 | |||
1265 | cfg = readl(ioaddr + ChipConfig); | ||
1266 | if (cfg & CfgExtPhy) | ||
1267 | return 0; | ||
1268 | |||
1269 | if (netif_msg_link(np)) { | ||
1270 | printk(KERN_INFO "%s: switching to external transceiver.\n", | ||
1271 | dev->name); | ||
1272 | } | ||
1273 | |||
1274 | /* 1) switch back to external phy */ | ||
1275 | writel(cfg | (CfgExtPhy | CfgPhyDis), ioaddr + ChipConfig); | ||
1276 | readl(ioaddr + ChipConfig); | ||
1277 | udelay(1); | ||
1278 | |||
1279 | /* 2) reset the external phy: */ | ||
1280 | /* resetting the external PHY has been known to cause a hub supplying | ||
1281 | * power over Ethernet to kill the power. We don't want to kill | ||
1282 | * power to this computer, so we avoid resetting the phy. | ||
1283 | */ | ||
1284 | |||
1285 | /* 3) reinit the phy fixup, it got lost during power down. */ | ||
1286 | move_int_phy(dev, np->phy_addr_external); | ||
1287 | init_phy_fixup(dev); | ||
1288 | |||
1289 | return 1; | ||
1290 | } | ||
1291 | |||
1292 | static int switch_port_internal(struct net_device *dev) | ||
1293 | { | ||
1294 | struct netdev_private *np = netdev_priv(dev); | ||
1295 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1296 | int i; | ||
1297 | u32 cfg; | ||
1298 | u16 bmcr; | ||
1299 | |||
1300 | cfg = readl(ioaddr + ChipConfig); | ||
1301 | if (!(cfg &CfgExtPhy)) | ||
1302 | return 0; | ||
1303 | |||
1304 | if (netif_msg_link(np)) { | ||
1305 | printk(KERN_INFO "%s: switching to internal transceiver.\n", | ||
1306 | dev->name); | ||
1307 | } | ||
1308 | /* 1) switch back to internal phy: */ | ||
1309 | cfg = cfg & ~(CfgExtPhy | CfgPhyDis); | ||
1310 | writel(cfg, ioaddr + ChipConfig); | ||
1311 | readl(ioaddr + ChipConfig); | ||
1312 | udelay(1); | ||
1313 | |||
1314 | /* 2) reset the internal phy: */ | ||
1315 | bmcr = readw(ioaddr+BasicControl+(MII_BMCR<<2)); | ||
1316 | writel(bmcr | BMCR_RESET, ioaddr+BasicControl+(MII_BMCR<<2)); | ||
1317 | readl(ioaddr + ChipConfig); | ||
1318 | udelay(10); | ||
1319 | for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { | ||
1320 | bmcr = readw(ioaddr+BasicControl+(MII_BMCR<<2)); | ||
1321 | if (!(bmcr & BMCR_RESET)) | ||
1322 | break; | ||
1323 | udelay(10); | ||
1324 | } | ||
1325 | if (i==NATSEMI_HW_TIMEOUT && netif_msg_link(np)) { | ||
1326 | printk(KERN_INFO | ||
1327 | "%s: phy reset did not complete in %d usec.\n", | ||
1328 | dev->name, i*10); | ||
1329 | } | ||
1330 | /* 3) reinit the phy fixup, it got lost during power down. */ | ||
1331 | init_phy_fixup(dev); | ||
1332 | |||
1333 | return 1; | ||
1334 | } | ||
1335 | |||
1336 | /* Scan for a PHY on the external mii bus. | ||
1337 | * There are two tricky points: | ||
1338 | * - Do not scan while the internal phy is enabled. The internal phy will | ||
1339 | * crash: e.g. reads from the DSPCFG register will return odd values and | ||
1340 | * the nasty random phy reset code will reset the nic every few seconds. | ||
1341 | * - The internal phy must be moved around, an external phy could | ||
1342 | * have the same address as the internal phy. | ||
1343 | */ | ||
1344 | static int find_mii(struct net_device *dev) | ||
1345 | { | ||
1346 | struct netdev_private *np = netdev_priv(dev); | ||
1347 | int tmp; | ||
1348 | int i; | ||
1349 | int did_switch; | ||
1350 | |||
1351 | /* Switch to external phy */ | ||
1352 | did_switch = switch_port_external(dev); | ||
1353 | |||
1354 | /* Scan the possible phy addresses: | ||
1355 | * | ||
1356 | * PHY address 0 means that the phy is in isolate mode. Not yet | ||
1357 | * supported due to lack of test hardware. User space should | ||
1358 | * handle it through ethtool. | ||
1359 | */ | ||
1360 | for (i = 1; i <= 31; i++) { | ||
1361 | move_int_phy(dev, i); | ||
1362 | tmp = miiport_read(dev, i, MII_BMSR); | ||
1363 | if (tmp != 0xffff && tmp != 0x0000) { | ||
1364 | /* found something! */ | ||
1365 | np->mii = (mdio_read(dev, MII_PHYSID1) << 16) | ||
1366 | + mdio_read(dev, MII_PHYSID2); | ||
1367 | if (netif_msg_probe(np)) { | ||
1368 | printk(KERN_INFO "natsemi %s: found external phy %08x at address %d.\n", | ||
1369 | pci_name(np->pci_dev), np->mii, i); | ||
1370 | } | ||
1371 | break; | ||
1372 | } | ||
1373 | } | ||
1374 | /* And switch back to internal phy: */ | ||
1375 | if (did_switch) | ||
1376 | switch_port_internal(dev); | ||
1377 | return i; | ||
1378 | } | ||
1379 | |||
1380 | /* CFG bits [13:16] [18:23] */ | ||
1381 | #define CFG_RESET_SAVE 0xfde000 | ||
1382 | /* WCSR bits [0:4] [9:10] */ | ||
1383 | #define WCSR_RESET_SAVE 0x61f | ||
1384 | /* RFCR bits [20] [22] [27:31] */ | ||
1385 | #define RFCR_RESET_SAVE 0xf8500000 | ||
1386 | |||
1387 | static void natsemi_reset(struct net_device *dev) | ||
1388 | { | ||
1389 | int i; | ||
1390 | u32 cfg; | ||
1391 | u32 wcsr; | ||
1392 | u32 rfcr; | ||
1393 | u16 pmatch[3]; | ||
1394 | u16 sopass[3]; | ||
1395 | struct netdev_private *np = netdev_priv(dev); | ||
1396 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1397 | |||
1398 | /* | ||
1399 | * Resetting the chip causes some registers to be lost. | ||
1400 | * Natsemi suggests NOT reloading the EEPROM while live, so instead | ||
1401 | * we save the state that would have been loaded from EEPROM | ||
1402 | * on a normal power-up (see the spec EEPROM map). This assumes | ||
1403 | * whoever calls this will follow up with init_registers() eventually. | ||
1404 | */ | ||
1405 | |||
1406 | /* CFG */ | ||
1407 | cfg = readl(ioaddr + ChipConfig) & CFG_RESET_SAVE; | ||
1408 | /* WCSR */ | ||
1409 | wcsr = readl(ioaddr + WOLCmd) & WCSR_RESET_SAVE; | ||
1410 | /* RFCR */ | ||
1411 | rfcr = readl(ioaddr + RxFilterAddr) & RFCR_RESET_SAVE; | ||
1412 | /* PMATCH */ | ||
1413 | for (i = 0; i < 3; i++) { | ||
1414 | writel(i*2, ioaddr + RxFilterAddr); | ||
1415 | pmatch[i] = readw(ioaddr + RxFilterData); | ||
1416 | } | ||
1417 | /* SOPAS */ | ||
1418 | for (i = 0; i < 3; i++) { | ||
1419 | writel(0xa+(i*2), ioaddr + RxFilterAddr); | ||
1420 | sopass[i] = readw(ioaddr + RxFilterData); | ||
1421 | } | ||
1422 | |||
1423 | /* now whack the chip */ | ||
1424 | writel(ChipReset, ioaddr + ChipCmd); | ||
1425 | for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { | ||
1426 | if (!(readl(ioaddr + ChipCmd) & ChipReset)) | ||
1427 | break; | ||
1428 | udelay(5); | ||
1429 | } | ||
1430 | if (i==NATSEMI_HW_TIMEOUT) { | ||
1431 | printk(KERN_WARNING "%s: reset did not complete in %d usec.\n", | ||
1432 | dev->name, i*5); | ||
1433 | } else if (netif_msg_hw(np)) { | ||
1434 | printk(KERN_DEBUG "%s: reset completed in %d usec.\n", | ||
1435 | dev->name, i*5); | ||
1436 | } | ||
1437 | |||
1438 | /* restore CFG */ | ||
1439 | cfg |= readl(ioaddr + ChipConfig) & ~CFG_RESET_SAVE; | ||
1440 | /* turn on external phy if it was selected */ | ||
1441 | if (dev->if_port == PORT_TP) | ||
1442 | cfg &= ~(CfgExtPhy | CfgPhyDis); | ||
1443 | else | ||
1444 | cfg |= (CfgExtPhy | CfgPhyDis); | ||
1445 | writel(cfg, ioaddr + ChipConfig); | ||
1446 | /* restore WCSR */ | ||
1447 | wcsr |= readl(ioaddr + WOLCmd) & ~WCSR_RESET_SAVE; | ||
1448 | writel(wcsr, ioaddr + WOLCmd); | ||
1449 | /* read RFCR */ | ||
1450 | rfcr |= readl(ioaddr + RxFilterAddr) & ~RFCR_RESET_SAVE; | ||
1451 | /* restore PMATCH */ | ||
1452 | for (i = 0; i < 3; i++) { | ||
1453 | writel(i*2, ioaddr + RxFilterAddr); | ||
1454 | writew(pmatch[i], ioaddr + RxFilterData); | ||
1455 | } | ||
1456 | for (i = 0; i < 3; i++) { | ||
1457 | writel(0xa+(i*2), ioaddr + RxFilterAddr); | ||
1458 | writew(sopass[i], ioaddr + RxFilterData); | ||
1459 | } | ||
1460 | /* restore RFCR */ | ||
1461 | writel(rfcr, ioaddr + RxFilterAddr); | ||
1462 | } | ||
1463 | |||
1464 | static void reset_rx(struct net_device *dev) | ||
1465 | { | ||
1466 | int i; | ||
1467 | struct netdev_private *np = netdev_priv(dev); | ||
1468 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1469 | |||
1470 | np->intr_status &= ~RxResetDone; | ||
1471 | |||
1472 | writel(RxReset, ioaddr + ChipCmd); | ||
1473 | |||
1474 | for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { | ||
1475 | np->intr_status |= readl(ioaddr + IntrStatus); | ||
1476 | if (np->intr_status & RxResetDone) | ||
1477 | break; | ||
1478 | udelay(15); | ||
1479 | } | ||
1480 | if (i==NATSEMI_HW_TIMEOUT) { | ||
1481 | printk(KERN_WARNING "%s: RX reset did not complete in %d usec.\n", | ||
1482 | dev->name, i*15); | ||
1483 | } else if (netif_msg_hw(np)) { | ||
1484 | printk(KERN_WARNING "%s: RX reset took %d usec.\n", | ||
1485 | dev->name, i*15); | ||
1486 | } | ||
1487 | } | ||
1488 | |||
1489 | static void natsemi_reload_eeprom(struct net_device *dev) | ||
1490 | { | ||
1491 | struct netdev_private *np = netdev_priv(dev); | ||
1492 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1493 | int i; | ||
1494 | |||
1495 | writel(EepromReload, ioaddr + PCIBusCfg); | ||
1496 | for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { | ||
1497 | udelay(50); | ||
1498 | if (!(readl(ioaddr + PCIBusCfg) & EepromReload)) | ||
1499 | break; | ||
1500 | } | ||
1501 | if (i==NATSEMI_HW_TIMEOUT) { | ||
1502 | printk(KERN_WARNING "natsemi %s: EEPROM did not reload in %d usec.\n", | ||
1503 | pci_name(np->pci_dev), i*50); | ||
1504 | } else if (netif_msg_hw(np)) { | ||
1505 | printk(KERN_DEBUG "natsemi %s: EEPROM reloaded in %d usec.\n", | ||
1506 | pci_name(np->pci_dev), i*50); | ||
1507 | } | ||
1508 | } | ||
1509 | |||
1510 | static void natsemi_stop_rxtx(struct net_device *dev) | ||
1511 | { | ||
1512 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
1513 | struct netdev_private *np = netdev_priv(dev); | ||
1514 | int i; | ||
1515 | |||
1516 | writel(RxOff | TxOff, ioaddr + ChipCmd); | ||
1517 | for(i=0;i< NATSEMI_HW_TIMEOUT;i++) { | ||
1518 | if ((readl(ioaddr + ChipCmd) & (TxOn|RxOn)) == 0) | ||
1519 | break; | ||
1520 | udelay(5); | ||
1521 | } | ||
1522 | if (i==NATSEMI_HW_TIMEOUT) { | ||
1523 | printk(KERN_WARNING "%s: Tx/Rx process did not stop in %d usec.\n", | ||
1524 | dev->name, i*5); | ||
1525 | } else if (netif_msg_hw(np)) { | ||
1526 | printk(KERN_DEBUG "%s: Tx/Rx process stopped in %d usec.\n", | ||
1527 | dev->name, i*5); | ||
1528 | } | ||
1529 | } | ||
1530 | |||
1531 | static int netdev_open(struct net_device *dev) | ||
1532 | { | ||
1533 | struct netdev_private *np = netdev_priv(dev); | ||
1534 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
1535 | int i; | ||
1536 | |||
1537 | /* Reset the chip, just in case. */ | ||
1538 | natsemi_reset(dev); | ||
1539 | |||
1540 | i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev); | ||
1541 | if (i) return i; | ||
1542 | |||
1543 | if (netif_msg_ifup(np)) | ||
1544 | printk(KERN_DEBUG "%s: netdev_open() irq %d.\n", | ||
1545 | dev->name, dev->irq); | ||
1546 | i = alloc_ring(dev); | ||
1547 | if (i < 0) { | ||
1548 | free_irq(dev->irq, dev); | ||
1549 | return i; | ||
1550 | } | ||
1551 | napi_enable(&np->napi); | ||
1552 | |||
1553 | init_ring(dev); | ||
1554 | spin_lock_irq(&np->lock); | ||
1555 | init_registers(dev); | ||
1556 | /* now set the MAC address according to dev->dev_addr */ | ||
1557 | for (i = 0; i < 3; i++) { | ||
1558 | u16 mac = (dev->dev_addr[2*i+1]<<8) + dev->dev_addr[2*i]; | ||
1559 | |||
1560 | writel(i*2, ioaddr + RxFilterAddr); | ||
1561 | writew(mac, ioaddr + RxFilterData); | ||
1562 | } | ||
1563 | writel(np->cur_rx_mode, ioaddr + RxFilterAddr); | ||
1564 | spin_unlock_irq(&np->lock); | ||
1565 | |||
1566 | netif_start_queue(dev); | ||
1567 | |||
1568 | if (netif_msg_ifup(np)) | ||
1569 | printk(KERN_DEBUG "%s: Done netdev_open(), status: %#08x.\n", | ||
1570 | dev->name, (int)readl(ioaddr + ChipCmd)); | ||
1571 | |||
1572 | /* Set the timer to check for link beat. */ | ||
1573 | init_timer(&np->timer); | ||
1574 | np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ); | ||
1575 | np->timer.data = (unsigned long)dev; | ||
1576 | np->timer.function = netdev_timer; /* timer handler */ | ||
1577 | add_timer(&np->timer); | ||
1578 | |||
1579 | return 0; | ||
1580 | } | ||
1581 | |||
1582 | static void do_cable_magic(struct net_device *dev) | ||
1583 | { | ||
1584 | struct netdev_private *np = netdev_priv(dev); | ||
1585 | void __iomem *ioaddr = ns_ioaddr(dev); | ||
1586 | |||
1587 | if (dev->if_port != PORT_TP) | ||
1588 | return; | ||
1589 | |||
1590 | if (np->srr >= SRR_DP83816_A5) | ||
1591 | return; | ||
1592 | |||
1593 | /* | ||
1594 | * 100 MBit links with short cables can trip an issue with the chip. | ||
1595 | * The problem manifests as lots of CRC errors and/or flickering | ||
1596 | * activity LED while idle. This process is based on instructions | ||
1597 | * from engineers at National. | ||
1598 | */ | ||
1599 | if (readl(ioaddr + ChipConfig) & CfgSpeed100) { | ||
1600 | u16 data; | ||
1601 | |||
1602 | writew(1, ioaddr + PGSEL); | ||
1603 | /* | ||
1604 | * coefficient visibility should already be enabled via | ||
1605 | * DSPCFG | 0x1000 | ||
1606 | */ | ||
1607 | data = readw(ioaddr + TSTDAT) & 0xff; | ||
1608 | /* | ||
1609 | * the value must be negative, and within certain values | ||
1610 | * (these values all come from National) | ||
1611 | */ | ||
1612 | if (!(data & 0x80) || ((data >= 0xd8) && (data <= 0xff))) { | ||
1613 | np = netdev_priv(dev); | ||
1614 | |||
1615 | /* the bug has been triggered - fix the coefficient */ | ||
1616 | writew(TSTDAT_FIXED, ioaddr + TSTDAT); | ||
1617 | /* lock the value */ | ||
1618 | data = readw(ioaddr + DSPCFG); | ||
1619 | np->dspcfg = data | DSPCFG_LOCK; | ||
1620 | writew(np->dspcfg, ioaddr + DSPCFG); | ||
1621 | } | ||
1622 | writew(0, ioaddr + PGSEL); | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | static void undo_cable_magic(struct net_device *dev) | ||
1627 | { | ||
1628 | u16 data; | ||
1629 | struct netdev_private *np = netdev_priv(dev); | ||
1630 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
1631 | |||
1632 | if (dev->if_port != PORT_TP) | ||
1633 | return; | ||
1634 | |||
1635 | if (np->srr >= SRR_DP83816_A5) | ||
1636 | return; | ||
1637 | |||
1638 | writew(1, ioaddr + PGSEL); | ||
1639 | /* make sure the lock bit is clear */ | ||
1640 | data = readw(ioaddr + DSPCFG); | ||
1641 | np->dspcfg = data & ~DSPCFG_LOCK; | ||
1642 | writew(np->dspcfg, ioaddr + DSPCFG); | ||
1643 | writew(0, ioaddr + PGSEL); | ||
1644 | } | ||
1645 | |||
1646 | static void check_link(struct net_device *dev) | ||
1647 | { | ||
1648 | struct netdev_private *np = netdev_priv(dev); | ||
1649 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
1650 | int duplex = np->duplex; | ||
1651 | u16 bmsr; | ||
1652 | |||
1653 | /* If we are ignoring the PHY then don't try reading it. */ | ||
1654 | if (np->ignore_phy) | ||
1655 | goto propagate_state; | ||
1656 | |||
1657 | /* The link status field is latched: it remains low after a temporary | ||
1658 | * link failure until it's read. We need the current link status, | ||
1659 | * thus read twice. | ||
1660 | */ | ||
1661 | mdio_read(dev, MII_BMSR); | ||
1662 | bmsr = mdio_read(dev, MII_BMSR); | ||
1663 | |||
1664 | if (!(bmsr & BMSR_LSTATUS)) { | ||
1665 | if (netif_carrier_ok(dev)) { | ||
1666 | if (netif_msg_link(np)) | ||
1667 | printk(KERN_NOTICE "%s: link down.\n", | ||
1668 | dev->name); | ||
1669 | netif_carrier_off(dev); | ||
1670 | undo_cable_magic(dev); | ||
1671 | } | ||
1672 | return; | ||
1673 | } | ||
1674 | if (!netif_carrier_ok(dev)) { | ||
1675 | if (netif_msg_link(np)) | ||
1676 | printk(KERN_NOTICE "%s: link up.\n", dev->name); | ||
1677 | netif_carrier_on(dev); | ||
1678 | do_cable_magic(dev); | ||
1679 | } | ||
1680 | |||
1681 | duplex = np->full_duplex; | ||
1682 | if (!duplex) { | ||
1683 | if (bmsr & BMSR_ANEGCOMPLETE) { | ||
1684 | int tmp = mii_nway_result( | ||
1685 | np->advertising & mdio_read(dev, MII_LPA)); | ||
1686 | if (tmp == LPA_100FULL || tmp == LPA_10FULL) | ||
1687 | duplex = 1; | ||
1688 | } else if (mdio_read(dev, MII_BMCR) & BMCR_FULLDPLX) | ||
1689 | duplex = 1; | ||
1690 | } | ||
1691 | |||
1692 | propagate_state: | ||
1693 | /* if duplex is set then bit 28 must be set, too */ | ||
1694 | if (duplex ^ !!(np->rx_config & RxAcceptTx)) { | ||
1695 | if (netif_msg_link(np)) | ||
1696 | printk(KERN_INFO | ||
1697 | "%s: Setting %s-duplex based on negotiated " | ||
1698 | "link capability.\n", dev->name, | ||
1699 | duplex ? "full" : "half"); | ||
1700 | if (duplex) { | ||
1701 | np->rx_config |= RxAcceptTx; | ||
1702 | np->tx_config |= TxCarrierIgn | TxHeartIgn; | ||
1703 | } else { | ||
1704 | np->rx_config &= ~RxAcceptTx; | ||
1705 | np->tx_config &= ~(TxCarrierIgn | TxHeartIgn); | ||
1706 | } | ||
1707 | writel(np->tx_config, ioaddr + TxConfig); | ||
1708 | writel(np->rx_config, ioaddr + RxConfig); | ||
1709 | } | ||
1710 | } | ||
1711 | |||
1712 | static void init_registers(struct net_device *dev) | ||
1713 | { | ||
1714 | struct netdev_private *np = netdev_priv(dev); | ||
1715 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
1716 | |||
1717 | init_phy_fixup(dev); | ||
1718 | |||
1719 | /* clear any interrupts that are pending, such as wake events */ | ||
1720 | readl(ioaddr + IntrStatus); | ||
1721 | |||
1722 | writel(np->ring_dma, ioaddr + RxRingPtr); | ||
1723 | writel(np->ring_dma + RX_RING_SIZE * sizeof(struct netdev_desc), | ||
1724 | ioaddr + TxRingPtr); | ||
1725 | |||
1726 | /* Initialize other registers. | ||
1727 | * Configure the PCI bus bursts and FIFO thresholds. | ||
1728 | * Configure for standard, in-spec Ethernet. | ||
1729 | * Start with half-duplex. check_link will update | ||
1730 | * to the correct settings. | ||
1731 | */ | ||
1732 | |||
1733 | /* DRTH: 2: start tx if 64 bytes are in the fifo | ||
1734 | * FLTH: 0x10: refill with next packet if 512 bytes are free | ||
1735 | * MXDMA: 0: up to 256 byte bursts. | ||
1736 | * MXDMA must be <= FLTH | ||
1737 | * ECRETRY=1 | ||
1738 | * ATP=1 | ||
1739 | */ | ||
1740 | np->tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | | ||
1741 | TX_FLTH_VAL | TX_DRTH_VAL_START; | ||
1742 | writel(np->tx_config, ioaddr + TxConfig); | ||
1743 | |||
1744 | /* DRTH 0x10: start copying to memory if 128 bytes are in the fifo | ||
1745 | * MXDMA 0: up to 256 byte bursts | ||
1746 | */ | ||
1747 | np->rx_config = RxMxdma_256 | RX_DRTH_VAL; | ||
1748 | /* if receive ring now has bigger buffers than normal, enable jumbo */ | ||
1749 | if (np->rx_buf_sz > NATSEMI_LONGPKT) | ||
1750 | np->rx_config |= RxAcceptLong; | ||
1751 | |||
1752 | writel(np->rx_config, ioaddr + RxConfig); | ||
1753 | |||
1754 | /* Disable PME: | ||
1755 | * The PME bit is initialized from the EEPROM contents. | ||
1756 | * PCI cards probably have PME disabled, but motherboard | ||
1757 | * implementations may have PME set to enable WakeOnLan. | ||
1758 | * With PME set the chip will scan incoming packets but | ||
1759 | * nothing will be written to memory. */ | ||
1760 | np->SavedClkRun = readl(ioaddr + ClkRun); | ||
1761 | writel(np->SavedClkRun & ~PMEEnable, ioaddr + ClkRun); | ||
1762 | if (np->SavedClkRun & PMEStatus && netif_msg_wol(np)) { | ||
1763 | printk(KERN_NOTICE "%s: Wake-up event %#08x\n", | ||
1764 | dev->name, readl(ioaddr + WOLCmd)); | ||
1765 | } | ||
1766 | |||
1767 | check_link(dev); | ||
1768 | __set_rx_mode(dev); | ||
1769 | |||
1770 | /* Enable interrupts by setting the interrupt mask. */ | ||
1771 | writel(DEFAULT_INTR, ioaddr + IntrMask); | ||
1772 | natsemi_irq_enable(dev); | ||
1773 | |||
1774 | writel(RxOn | TxOn, ioaddr + ChipCmd); | ||
1775 | writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */ | ||
1776 | } | ||
1777 | |||
1778 | /* | ||
1779 | * netdev_timer: | ||
1780 | * Purpose: | ||
1781 | * 1) check for link changes. Usually they are handled by the MII interrupt | ||
1782 | * but it doesn't hurt to check twice. | ||
1783 | * 2) check for sudden death of the NIC: | ||
1784 | * It seems that a reference set for this chip went out with incorrect info, | ||
1785 | * and there exist boards that aren't quite right. An unexpected voltage | ||
1786 | * drop can cause the PHY to get itself in a weird state (basically reset). | ||
1787 | * NOTE: this only seems to affect revC chips. The user can disable | ||
1788 | * this check via dspcfg_workaround sysfs option. | ||
1789 | * 3) check of death of the RX path due to OOM | ||
1790 | */ | ||
1791 | static void netdev_timer(unsigned long data) | ||
1792 | { | ||
1793 | struct net_device *dev = (struct net_device *)data; | ||
1794 | struct netdev_private *np = netdev_priv(dev); | ||
1795 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
1796 | int next_tick = NATSEMI_TIMER_FREQ; | ||
1797 | |||
1798 | if (netif_msg_timer(np)) { | ||
1799 | /* DO NOT read the IntrStatus register, | ||
1800 | * a read clears any pending interrupts. | ||
1801 | */ | ||
1802 | printk(KERN_DEBUG "%s: Media selection timer tick.\n", | ||
1803 | dev->name); | ||
1804 | } | ||
1805 | |||
1806 | if (dev->if_port == PORT_TP) { | ||
1807 | u16 dspcfg; | ||
1808 | |||
1809 | spin_lock_irq(&np->lock); | ||
1810 | /* check for a nasty random phy-reset - use dspcfg as a flag */ | ||
1811 | writew(1, ioaddr+PGSEL); | ||
1812 | dspcfg = readw(ioaddr+DSPCFG); | ||
1813 | writew(0, ioaddr+PGSEL); | ||
1814 | if (np->dspcfg_workaround && dspcfg != np->dspcfg) { | ||
1815 | if (!netif_queue_stopped(dev)) { | ||
1816 | spin_unlock_irq(&np->lock); | ||
1817 | if (netif_msg_drv(np)) | ||
1818 | printk(KERN_NOTICE "%s: possible phy reset: " | ||
1819 | "re-initializing\n", dev->name); | ||
1820 | disable_irq(dev->irq); | ||
1821 | spin_lock_irq(&np->lock); | ||
1822 | natsemi_stop_rxtx(dev); | ||
1823 | dump_ring(dev); | ||
1824 | reinit_ring(dev); | ||
1825 | init_registers(dev); | ||
1826 | spin_unlock_irq(&np->lock); | ||
1827 | enable_irq(dev->irq); | ||
1828 | } else { | ||
1829 | /* hurry back */ | ||
1830 | next_tick = HZ; | ||
1831 | spin_unlock_irq(&np->lock); | ||
1832 | } | ||
1833 | } else { | ||
1834 | /* init_registers() calls check_link() for the above case */ | ||
1835 | check_link(dev); | ||
1836 | spin_unlock_irq(&np->lock); | ||
1837 | } | ||
1838 | } else { | ||
1839 | spin_lock_irq(&np->lock); | ||
1840 | check_link(dev); | ||
1841 | spin_unlock_irq(&np->lock); | ||
1842 | } | ||
1843 | if (np->oom) { | ||
1844 | disable_irq(dev->irq); | ||
1845 | np->oom = 0; | ||
1846 | refill_rx(dev); | ||
1847 | enable_irq(dev->irq); | ||
1848 | if (!np->oom) { | ||
1849 | writel(RxOn, ioaddr + ChipCmd); | ||
1850 | } else { | ||
1851 | next_tick = 1; | ||
1852 | } | ||
1853 | } | ||
1854 | |||
1855 | if (next_tick > 1) | ||
1856 | mod_timer(&np->timer, round_jiffies(jiffies + next_tick)); | ||
1857 | else | ||
1858 | mod_timer(&np->timer, jiffies + next_tick); | ||
1859 | } | ||
1860 | |||
1861 | static void dump_ring(struct net_device *dev) | ||
1862 | { | ||
1863 | struct netdev_private *np = netdev_priv(dev); | ||
1864 | |||
1865 | if (netif_msg_pktdata(np)) { | ||
1866 | int i; | ||
1867 | printk(KERN_DEBUG " Tx ring at %p:\n", np->tx_ring); | ||
1868 | for (i = 0; i < TX_RING_SIZE; i++) { | ||
1869 | printk(KERN_DEBUG " #%d desc. %#08x %#08x %#08x.\n", | ||
1870 | i, np->tx_ring[i].next_desc, | ||
1871 | np->tx_ring[i].cmd_status, | ||
1872 | np->tx_ring[i].addr); | ||
1873 | } | ||
1874 | printk(KERN_DEBUG " Rx ring %p:\n", np->rx_ring); | ||
1875 | for (i = 0; i < RX_RING_SIZE; i++) { | ||
1876 | printk(KERN_DEBUG " #%d desc. %#08x %#08x %#08x.\n", | ||
1877 | i, np->rx_ring[i].next_desc, | ||
1878 | np->rx_ring[i].cmd_status, | ||
1879 | np->rx_ring[i].addr); | ||
1880 | } | ||
1881 | } | ||
1882 | } | ||
1883 | |||
1884 | static void ns_tx_timeout(struct net_device *dev) | ||
1885 | { | ||
1886 | struct netdev_private *np = netdev_priv(dev); | ||
1887 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
1888 | |||
1889 | disable_irq(dev->irq); | ||
1890 | spin_lock_irq(&np->lock); | ||
1891 | if (!np->hands_off) { | ||
1892 | if (netif_msg_tx_err(np)) | ||
1893 | printk(KERN_WARNING | ||
1894 | "%s: Transmit timed out, status %#08x," | ||
1895 | " resetting...\n", | ||
1896 | dev->name, readl(ioaddr + IntrStatus)); | ||
1897 | dump_ring(dev); | ||
1898 | |||
1899 | natsemi_reset(dev); | ||
1900 | reinit_ring(dev); | ||
1901 | init_registers(dev); | ||
1902 | } else { | ||
1903 | printk(KERN_WARNING | ||
1904 | "%s: tx_timeout while in hands_off state?\n", | ||
1905 | dev->name); | ||
1906 | } | ||
1907 | spin_unlock_irq(&np->lock); | ||
1908 | enable_irq(dev->irq); | ||
1909 | |||
1910 | dev->trans_start = jiffies; /* prevent tx timeout */ | ||
1911 | dev->stats.tx_errors++; | ||
1912 | netif_wake_queue(dev); | ||
1913 | } | ||
1914 | |||
1915 | static int alloc_ring(struct net_device *dev) | ||
1916 | { | ||
1917 | struct netdev_private *np = netdev_priv(dev); | ||
1918 | np->rx_ring = pci_alloc_consistent(np->pci_dev, | ||
1919 | sizeof(struct netdev_desc) * (RX_RING_SIZE+TX_RING_SIZE), | ||
1920 | &np->ring_dma); | ||
1921 | if (!np->rx_ring) | ||
1922 | return -ENOMEM; | ||
1923 | np->tx_ring = &np->rx_ring[RX_RING_SIZE]; | ||
1924 | return 0; | ||
1925 | } | ||
1926 | |||
1927 | static void refill_rx(struct net_device *dev) | ||
1928 | { | ||
1929 | struct netdev_private *np = netdev_priv(dev); | ||
1930 | |||
1931 | /* Refill the Rx ring buffers. */ | ||
1932 | for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) { | ||
1933 | struct sk_buff *skb; | ||
1934 | int entry = np->dirty_rx % RX_RING_SIZE; | ||
1935 | if (np->rx_skbuff[entry] == NULL) { | ||
1936 | unsigned int buflen = np->rx_buf_sz+NATSEMI_PADDING; | ||
1937 | skb = dev_alloc_skb(buflen); | ||
1938 | np->rx_skbuff[entry] = skb; | ||
1939 | if (skb == NULL) | ||
1940 | break; /* Better luck next round. */ | ||
1941 | skb->dev = dev; /* Mark as being used by this device. */ | ||
1942 | np->rx_dma[entry] = pci_map_single(np->pci_dev, | ||
1943 | skb->data, buflen, PCI_DMA_FROMDEVICE); | ||
1944 | np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); | ||
1945 | } | ||
1946 | np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); | ||
1947 | } | ||
1948 | if (np->cur_rx - np->dirty_rx == RX_RING_SIZE) { | ||
1949 | if (netif_msg_rx_err(np)) | ||
1950 | printk(KERN_WARNING "%s: going OOM.\n", dev->name); | ||
1951 | np->oom = 1; | ||
1952 | } | ||
1953 | } | ||
1954 | |||
1955 | static void set_bufsize(struct net_device *dev) | ||
1956 | { | ||
1957 | struct netdev_private *np = netdev_priv(dev); | ||
1958 | if (dev->mtu <= ETH_DATA_LEN) | ||
1959 | np->rx_buf_sz = ETH_DATA_LEN + NATSEMI_HEADERS; | ||
1960 | else | ||
1961 | np->rx_buf_sz = dev->mtu + NATSEMI_HEADERS; | ||
1962 | } | ||
1963 | |||
1964 | /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ | ||
1965 | static void init_ring(struct net_device *dev) | ||
1966 | { | ||
1967 | struct netdev_private *np = netdev_priv(dev); | ||
1968 | int i; | ||
1969 | |||
1970 | /* 1) TX ring */ | ||
1971 | np->dirty_tx = np->cur_tx = 0; | ||
1972 | for (i = 0; i < TX_RING_SIZE; i++) { | ||
1973 | np->tx_skbuff[i] = NULL; | ||
1974 | np->tx_ring[i].next_desc = cpu_to_le32(np->ring_dma | ||
1975 | +sizeof(struct netdev_desc) | ||
1976 | *((i+1)%TX_RING_SIZE+RX_RING_SIZE)); | ||
1977 | np->tx_ring[i].cmd_status = 0; | ||
1978 | } | ||
1979 | |||
1980 | /* 2) RX ring */ | ||
1981 | np->dirty_rx = 0; | ||
1982 | np->cur_rx = RX_RING_SIZE; | ||
1983 | np->oom = 0; | ||
1984 | set_bufsize(dev); | ||
1985 | |||
1986 | np->rx_head_desc = &np->rx_ring[0]; | ||
1987 | |||
1988 | /* Please be careful before changing this loop - at least gcc-2.95.1 | ||
1989 | * miscompiles it otherwise. | ||
1990 | */ | ||
1991 | /* Initialize all Rx descriptors. */ | ||
1992 | for (i = 0; i < RX_RING_SIZE; i++) { | ||
1993 | np->rx_ring[i].next_desc = cpu_to_le32(np->ring_dma | ||
1994 | +sizeof(struct netdev_desc) | ||
1995 | *((i+1)%RX_RING_SIZE)); | ||
1996 | np->rx_ring[i].cmd_status = cpu_to_le32(DescOwn); | ||
1997 | np->rx_skbuff[i] = NULL; | ||
1998 | } | ||
1999 | refill_rx(dev); | ||
2000 | dump_ring(dev); | ||
2001 | } | ||
2002 | |||
2003 | static void drain_tx(struct net_device *dev) | ||
2004 | { | ||
2005 | struct netdev_private *np = netdev_priv(dev); | ||
2006 | int i; | ||
2007 | |||
2008 | for (i = 0; i < TX_RING_SIZE; i++) { | ||
2009 | if (np->tx_skbuff[i]) { | ||
2010 | pci_unmap_single(np->pci_dev, | ||
2011 | np->tx_dma[i], np->tx_skbuff[i]->len, | ||
2012 | PCI_DMA_TODEVICE); | ||
2013 | dev_kfree_skb(np->tx_skbuff[i]); | ||
2014 | dev->stats.tx_dropped++; | ||
2015 | } | ||
2016 | np->tx_skbuff[i] = NULL; | ||
2017 | } | ||
2018 | } | ||
2019 | |||
2020 | static void drain_rx(struct net_device *dev) | ||
2021 | { | ||
2022 | struct netdev_private *np = netdev_priv(dev); | ||
2023 | unsigned int buflen = np->rx_buf_sz; | ||
2024 | int i; | ||
2025 | |||
2026 | /* Free all the skbuffs in the Rx queue. */ | ||
2027 | for (i = 0; i < RX_RING_SIZE; i++) { | ||
2028 | np->rx_ring[i].cmd_status = 0; | ||
2029 | np->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ | ||
2030 | if (np->rx_skbuff[i]) { | ||
2031 | pci_unmap_single(np->pci_dev, np->rx_dma[i], | ||
2032 | buflen + NATSEMI_PADDING, | ||
2033 | PCI_DMA_FROMDEVICE); | ||
2034 | dev_kfree_skb(np->rx_skbuff[i]); | ||
2035 | } | ||
2036 | np->rx_skbuff[i] = NULL; | ||
2037 | } | ||
2038 | } | ||
2039 | |||
2040 | static void drain_ring(struct net_device *dev) | ||
2041 | { | ||
2042 | drain_rx(dev); | ||
2043 | drain_tx(dev); | ||
2044 | } | ||
2045 | |||
2046 | static void free_ring(struct net_device *dev) | ||
2047 | { | ||
2048 | struct netdev_private *np = netdev_priv(dev); | ||
2049 | pci_free_consistent(np->pci_dev, | ||
2050 | sizeof(struct netdev_desc) * (RX_RING_SIZE+TX_RING_SIZE), | ||
2051 | np->rx_ring, np->ring_dma); | ||
2052 | } | ||
2053 | |||
2054 | static void reinit_rx(struct net_device *dev) | ||
2055 | { | ||
2056 | struct netdev_private *np = netdev_priv(dev); | ||
2057 | int i; | ||
2058 | |||
2059 | /* RX Ring */ | ||
2060 | np->dirty_rx = 0; | ||
2061 | np->cur_rx = RX_RING_SIZE; | ||
2062 | np->rx_head_desc = &np->rx_ring[0]; | ||
2063 | /* Initialize all Rx descriptors. */ | ||
2064 | for (i = 0; i < RX_RING_SIZE; i++) | ||
2065 | np->rx_ring[i].cmd_status = cpu_to_le32(DescOwn); | ||
2066 | |||
2067 | refill_rx(dev); | ||
2068 | } | ||
2069 | |||
2070 | static void reinit_ring(struct net_device *dev) | ||
2071 | { | ||
2072 | struct netdev_private *np = netdev_priv(dev); | ||
2073 | int i; | ||
2074 | |||
2075 | /* drain TX ring */ | ||
2076 | drain_tx(dev); | ||
2077 | np->dirty_tx = np->cur_tx = 0; | ||
2078 | for (i=0;i<TX_RING_SIZE;i++) | ||
2079 | np->tx_ring[i].cmd_status = 0; | ||
2080 | |||
2081 | reinit_rx(dev); | ||
2082 | } | ||
2083 | |||
2084 | static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) | ||
2085 | { | ||
2086 | struct netdev_private *np = netdev_priv(dev); | ||
2087 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2088 | unsigned entry; | ||
2089 | unsigned long flags; | ||
2090 | |||
2091 | /* Note: Ordering is important here, set the field with the | ||
2092 | "ownership" bit last, and only then increment cur_tx. */ | ||
2093 | |||
2094 | /* Calculate the next Tx descriptor entry. */ | ||
2095 | entry = np->cur_tx % TX_RING_SIZE; | ||
2096 | |||
2097 | np->tx_skbuff[entry] = skb; | ||
2098 | np->tx_dma[entry] = pci_map_single(np->pci_dev, | ||
2099 | skb->data,skb->len, PCI_DMA_TODEVICE); | ||
2100 | |||
2101 | np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]); | ||
2102 | |||
2103 | spin_lock_irqsave(&np->lock, flags); | ||
2104 | |||
2105 | if (!np->hands_off) { | ||
2106 | np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | skb->len); | ||
2107 | /* StrongARM: Explicitly cache flush np->tx_ring and | ||
2108 | * skb->data,skb->len. */ | ||
2109 | wmb(); | ||
2110 | np->cur_tx++; | ||
2111 | if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) { | ||
2112 | netdev_tx_done(dev); | ||
2113 | if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) | ||
2114 | netif_stop_queue(dev); | ||
2115 | } | ||
2116 | /* Wake the potentially-idle transmit channel. */ | ||
2117 | writel(TxOn, ioaddr + ChipCmd); | ||
2118 | } else { | ||
2119 | dev_kfree_skb_irq(skb); | ||
2120 | dev->stats.tx_dropped++; | ||
2121 | } | ||
2122 | spin_unlock_irqrestore(&np->lock, flags); | ||
2123 | |||
2124 | if (netif_msg_tx_queued(np)) { | ||
2125 | printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n", | ||
2126 | dev->name, np->cur_tx, entry); | ||
2127 | } | ||
2128 | return NETDEV_TX_OK; | ||
2129 | } | ||
2130 | |||
2131 | static void netdev_tx_done(struct net_device *dev) | ||
2132 | { | ||
2133 | struct netdev_private *np = netdev_priv(dev); | ||
2134 | |||
2135 | for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) { | ||
2136 | int entry = np->dirty_tx % TX_RING_SIZE; | ||
2137 | if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescOwn)) | ||
2138 | break; | ||
2139 | if (netif_msg_tx_done(np)) | ||
2140 | printk(KERN_DEBUG | ||
2141 | "%s: tx frame #%d finished, status %#08x.\n", | ||
2142 | dev->name, np->dirty_tx, | ||
2143 | le32_to_cpu(np->tx_ring[entry].cmd_status)); | ||
2144 | if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescPktOK)) { | ||
2145 | dev->stats.tx_packets++; | ||
2146 | dev->stats.tx_bytes += np->tx_skbuff[entry]->len; | ||
2147 | } else { /* Various Tx errors */ | ||
2148 | int tx_status = | ||
2149 | le32_to_cpu(np->tx_ring[entry].cmd_status); | ||
2150 | if (tx_status & (DescTxAbort|DescTxExcColl)) | ||
2151 | dev->stats.tx_aborted_errors++; | ||
2152 | if (tx_status & DescTxFIFO) | ||
2153 | dev->stats.tx_fifo_errors++; | ||
2154 | if (tx_status & DescTxCarrier) | ||
2155 | dev->stats.tx_carrier_errors++; | ||
2156 | if (tx_status & DescTxOOWCol) | ||
2157 | dev->stats.tx_window_errors++; | ||
2158 | dev->stats.tx_errors++; | ||
2159 | } | ||
2160 | pci_unmap_single(np->pci_dev,np->tx_dma[entry], | ||
2161 | np->tx_skbuff[entry]->len, | ||
2162 | PCI_DMA_TODEVICE); | ||
2163 | /* Free the original skb. */ | ||
2164 | dev_kfree_skb_irq(np->tx_skbuff[entry]); | ||
2165 | np->tx_skbuff[entry] = NULL; | ||
2166 | } | ||
2167 | if (netif_queue_stopped(dev) && | ||
2168 | np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) { | ||
2169 | /* The ring is no longer full, wake queue. */ | ||
2170 | netif_wake_queue(dev); | ||
2171 | } | ||
2172 | } | ||
2173 | |||
2174 | /* The interrupt handler doesn't actually handle interrupts itself, it | ||
2175 | * schedules a NAPI poll if there is anything to do. */ | ||
2176 | static irqreturn_t intr_handler(int irq, void *dev_instance) | ||
2177 | { | ||
2178 | struct net_device *dev = dev_instance; | ||
2179 | struct netdev_private *np = netdev_priv(dev); | ||
2180 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2181 | |||
2182 | /* Reading IntrStatus automatically acknowledges so don't do | ||
2183 | * that while interrupts are disabled, (for example, while a | ||
2184 | * poll is scheduled). */ | ||
2185 | if (np->hands_off || !readl(ioaddr + IntrEnable)) | ||
2186 | return IRQ_NONE; | ||
2187 | |||
2188 | np->intr_status = readl(ioaddr + IntrStatus); | ||
2189 | |||
2190 | if (!np->intr_status) | ||
2191 | return IRQ_NONE; | ||
2192 | |||
2193 | if (netif_msg_intr(np)) | ||
2194 | printk(KERN_DEBUG | ||
2195 | "%s: Interrupt, status %#08x, mask %#08x.\n", | ||
2196 | dev->name, np->intr_status, | ||
2197 | readl(ioaddr + IntrMask)); | ||
2198 | |||
2199 | prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); | ||
2200 | |||
2201 | if (napi_schedule_prep(&np->napi)) { | ||
2202 | /* Disable interrupts and register for poll */ | ||
2203 | natsemi_irq_disable(dev); | ||
2204 | __napi_schedule(&np->napi); | ||
2205 | } else | ||
2206 | printk(KERN_WARNING | ||
2207 | "%s: Ignoring interrupt, status %#08x, mask %#08x.\n", | ||
2208 | dev->name, np->intr_status, | ||
2209 | readl(ioaddr + IntrMask)); | ||
2210 | |||
2211 | return IRQ_HANDLED; | ||
2212 | } | ||
2213 | |||
2214 | /* This is the NAPI poll routine. As well as the standard RX handling | ||
2215 | * it also handles all other interrupts that the chip might raise. | ||
2216 | */ | ||
2217 | static int natsemi_poll(struct napi_struct *napi, int budget) | ||
2218 | { | ||
2219 | struct netdev_private *np = container_of(napi, struct netdev_private, napi); | ||
2220 | struct net_device *dev = np->dev; | ||
2221 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2222 | int work_done = 0; | ||
2223 | |||
2224 | do { | ||
2225 | if (netif_msg_intr(np)) | ||
2226 | printk(KERN_DEBUG | ||
2227 | "%s: Poll, status %#08x, mask %#08x.\n", | ||
2228 | dev->name, np->intr_status, | ||
2229 | readl(ioaddr + IntrMask)); | ||
2230 | |||
2231 | /* netdev_rx() may read IntrStatus again if the RX state | ||
2232 | * machine falls over so do it first. */ | ||
2233 | if (np->intr_status & | ||
2234 | (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | | ||
2235 | IntrRxErr | IntrRxOverrun)) { | ||
2236 | netdev_rx(dev, &work_done, budget); | ||
2237 | } | ||
2238 | |||
2239 | if (np->intr_status & | ||
2240 | (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) { | ||
2241 | spin_lock(&np->lock); | ||
2242 | netdev_tx_done(dev); | ||
2243 | spin_unlock(&np->lock); | ||
2244 | } | ||
2245 | |||
2246 | /* Abnormal error summary/uncommon events handlers. */ | ||
2247 | if (np->intr_status & IntrAbnormalSummary) | ||
2248 | netdev_error(dev, np->intr_status); | ||
2249 | |||
2250 | if (work_done >= budget) | ||
2251 | return work_done; | ||
2252 | |||
2253 | np->intr_status = readl(ioaddr + IntrStatus); | ||
2254 | } while (np->intr_status); | ||
2255 | |||
2256 | napi_complete(napi); | ||
2257 | |||
2258 | /* Reenable interrupts providing nothing is trying to shut | ||
2259 | * the chip down. */ | ||
2260 | spin_lock(&np->lock); | ||
2261 | if (!np->hands_off) | ||
2262 | natsemi_irq_enable(dev); | ||
2263 | spin_unlock(&np->lock); | ||
2264 | |||
2265 | return work_done; | ||
2266 | } | ||
2267 | |||
2268 | /* This routine is logically part of the interrupt handler, but separated | ||
2269 | for clarity and better register allocation. */ | ||
2270 | static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) | ||
2271 | { | ||
2272 | struct netdev_private *np = netdev_priv(dev); | ||
2273 | int entry = np->cur_rx % RX_RING_SIZE; | ||
2274 | int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx; | ||
2275 | s32 desc_status = le32_to_cpu(np->rx_head_desc->cmd_status); | ||
2276 | unsigned int buflen = np->rx_buf_sz; | ||
2277 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2278 | |||
2279 | /* If the driver owns the next entry it's a new packet. Send it up. */ | ||
2280 | while (desc_status < 0) { /* e.g. & DescOwn */ | ||
2281 | int pkt_len; | ||
2282 | if (netif_msg_rx_status(np)) | ||
2283 | printk(KERN_DEBUG | ||
2284 | " netdev_rx() entry %d status was %#08x.\n", | ||
2285 | entry, desc_status); | ||
2286 | if (--boguscnt < 0) | ||
2287 | break; | ||
2288 | |||
2289 | if (*work_done >= work_to_do) | ||
2290 | break; | ||
2291 | |||
2292 | (*work_done)++; | ||
2293 | |||
2294 | pkt_len = (desc_status & DescSizeMask) - 4; | ||
2295 | if ((desc_status&(DescMore|DescPktOK|DescRxLong)) != DescPktOK){ | ||
2296 | if (desc_status & DescMore) { | ||
2297 | unsigned long flags; | ||
2298 | |||
2299 | if (netif_msg_rx_err(np)) | ||
2300 | printk(KERN_WARNING | ||
2301 | "%s: Oversized(?) Ethernet " | ||
2302 | "frame spanned multiple " | ||
2303 | "buffers, entry %#08x " | ||
2304 | "status %#08x.\n", dev->name, | ||
2305 | np->cur_rx, desc_status); | ||
2306 | dev->stats.rx_length_errors++; | ||
2307 | |||
2308 | /* The RX state machine has probably | ||
2309 | * locked up beneath us. Follow the | ||
2310 | * reset procedure documented in | ||
2311 | * AN-1287. */ | ||
2312 | |||
2313 | spin_lock_irqsave(&np->lock, flags); | ||
2314 | reset_rx(dev); | ||
2315 | reinit_rx(dev); | ||
2316 | writel(np->ring_dma, ioaddr + RxRingPtr); | ||
2317 | check_link(dev); | ||
2318 | spin_unlock_irqrestore(&np->lock, flags); | ||
2319 | |||
2320 | /* We'll enable RX on exit from this | ||
2321 | * function. */ | ||
2322 | break; | ||
2323 | |||
2324 | } else { | ||
2325 | /* There was an error. */ | ||
2326 | dev->stats.rx_errors++; | ||
2327 | if (desc_status & (DescRxAbort|DescRxOver)) | ||
2328 | dev->stats.rx_over_errors++; | ||
2329 | if (desc_status & (DescRxLong|DescRxRunt)) | ||
2330 | dev->stats.rx_length_errors++; | ||
2331 | if (desc_status & (DescRxInvalid|DescRxAlign)) | ||
2332 | dev->stats.rx_frame_errors++; | ||
2333 | if (desc_status & DescRxCRC) | ||
2334 | dev->stats.rx_crc_errors++; | ||
2335 | } | ||
2336 | } else if (pkt_len > np->rx_buf_sz) { | ||
2337 | /* if this is the tail of a double buffer | ||
2338 | * packet, we've already counted the error | ||
2339 | * on the first part. Ignore the second half. | ||
2340 | */ | ||
2341 | } else { | ||
2342 | struct sk_buff *skb; | ||
2343 | /* Omit CRC size. */ | ||
2344 | /* Check if the packet is long enough to accept | ||
2345 | * without copying to a minimally-sized skbuff. */ | ||
2346 | if (pkt_len < rx_copybreak && | ||
2347 | (skb = dev_alloc_skb(pkt_len + RX_OFFSET)) != NULL) { | ||
2348 | /* 16 byte align the IP header */ | ||
2349 | skb_reserve(skb, RX_OFFSET); | ||
2350 | pci_dma_sync_single_for_cpu(np->pci_dev, | ||
2351 | np->rx_dma[entry], | ||
2352 | buflen, | ||
2353 | PCI_DMA_FROMDEVICE); | ||
2354 | skb_copy_to_linear_data(skb, | ||
2355 | np->rx_skbuff[entry]->data, pkt_len); | ||
2356 | skb_put(skb, pkt_len); | ||
2357 | pci_dma_sync_single_for_device(np->pci_dev, | ||
2358 | np->rx_dma[entry], | ||
2359 | buflen, | ||
2360 | PCI_DMA_FROMDEVICE); | ||
2361 | } else { | ||
2362 | pci_unmap_single(np->pci_dev, np->rx_dma[entry], | ||
2363 | buflen + NATSEMI_PADDING, | ||
2364 | PCI_DMA_FROMDEVICE); | ||
2365 | skb_put(skb = np->rx_skbuff[entry], pkt_len); | ||
2366 | np->rx_skbuff[entry] = NULL; | ||
2367 | } | ||
2368 | skb->protocol = eth_type_trans(skb, dev); | ||
2369 | netif_receive_skb(skb); | ||
2370 | dev->stats.rx_packets++; | ||
2371 | dev->stats.rx_bytes += pkt_len; | ||
2372 | } | ||
2373 | entry = (++np->cur_rx) % RX_RING_SIZE; | ||
2374 | np->rx_head_desc = &np->rx_ring[entry]; | ||
2375 | desc_status = le32_to_cpu(np->rx_head_desc->cmd_status); | ||
2376 | } | ||
2377 | refill_rx(dev); | ||
2378 | |||
2379 | /* Restart Rx engine if stopped. */ | ||
2380 | if (np->oom) | ||
2381 | mod_timer(&np->timer, jiffies + 1); | ||
2382 | else | ||
2383 | writel(RxOn, ioaddr + ChipCmd); | ||
2384 | } | ||
2385 | |||
2386 | static void netdev_error(struct net_device *dev, int intr_status) | ||
2387 | { | ||
2388 | struct netdev_private *np = netdev_priv(dev); | ||
2389 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2390 | |||
2391 | spin_lock(&np->lock); | ||
2392 | if (intr_status & LinkChange) { | ||
2393 | u16 lpa = mdio_read(dev, MII_LPA); | ||
2394 | if (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE && | ||
2395 | netif_msg_link(np)) { | ||
2396 | printk(KERN_INFO | ||
2397 | "%s: Autonegotiation advertising" | ||
2398 | " %#04x partner %#04x.\n", dev->name, | ||
2399 | np->advertising, lpa); | ||
2400 | } | ||
2401 | |||
2402 | /* read MII int status to clear the flag */ | ||
2403 | readw(ioaddr + MIntrStatus); | ||
2404 | check_link(dev); | ||
2405 | } | ||
2406 | if (intr_status & StatsMax) { | ||
2407 | __get_stats(dev); | ||
2408 | } | ||
2409 | if (intr_status & IntrTxUnderrun) { | ||
2410 | if ((np->tx_config & TxDrthMask) < TX_DRTH_VAL_LIMIT) { | ||
2411 | np->tx_config += TX_DRTH_VAL_INC; | ||
2412 | if (netif_msg_tx_err(np)) | ||
2413 | printk(KERN_NOTICE | ||
2414 | "%s: increased tx threshold, txcfg %#08x.\n", | ||
2415 | dev->name, np->tx_config); | ||
2416 | } else { | ||
2417 | if (netif_msg_tx_err(np)) | ||
2418 | printk(KERN_NOTICE | ||
2419 | "%s: tx underrun with maximum tx threshold, txcfg %#08x.\n", | ||
2420 | dev->name, np->tx_config); | ||
2421 | } | ||
2422 | writel(np->tx_config, ioaddr + TxConfig); | ||
2423 | } | ||
2424 | if (intr_status & WOLPkt && netif_msg_wol(np)) { | ||
2425 | int wol_status = readl(ioaddr + WOLCmd); | ||
2426 | printk(KERN_NOTICE "%s: Link wake-up event %#08x\n", | ||
2427 | dev->name, wol_status); | ||
2428 | } | ||
2429 | if (intr_status & RxStatusFIFOOver) { | ||
2430 | if (netif_msg_rx_err(np) && netif_msg_intr(np)) { | ||
2431 | printk(KERN_NOTICE "%s: Rx status FIFO overrun\n", | ||
2432 | dev->name); | ||
2433 | } | ||
2434 | dev->stats.rx_fifo_errors++; | ||
2435 | dev->stats.rx_errors++; | ||
2436 | } | ||
2437 | /* Hmmmmm, it's not clear how to recover from PCI faults. */ | ||
2438 | if (intr_status & IntrPCIErr) { | ||
2439 | printk(KERN_NOTICE "%s: PCI error %#08x\n", dev->name, | ||
2440 | intr_status & IntrPCIErr); | ||
2441 | dev->stats.tx_fifo_errors++; | ||
2442 | dev->stats.tx_errors++; | ||
2443 | dev->stats.rx_fifo_errors++; | ||
2444 | dev->stats.rx_errors++; | ||
2445 | } | ||
2446 | spin_unlock(&np->lock); | ||
2447 | } | ||
2448 | |||
2449 | static void __get_stats(struct net_device *dev) | ||
2450 | { | ||
2451 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2452 | |||
2453 | /* The chip only need report frame silently dropped. */ | ||
2454 | dev->stats.rx_crc_errors += readl(ioaddr + RxCRCErrs); | ||
2455 | dev->stats.rx_missed_errors += readl(ioaddr + RxMissed); | ||
2456 | } | ||
2457 | |||
2458 | static struct net_device_stats *get_stats(struct net_device *dev) | ||
2459 | { | ||
2460 | struct netdev_private *np = netdev_priv(dev); | ||
2461 | |||
2462 | /* The chip only need report frame silently dropped. */ | ||
2463 | spin_lock_irq(&np->lock); | ||
2464 | if (netif_running(dev) && !np->hands_off) | ||
2465 | __get_stats(dev); | ||
2466 | spin_unlock_irq(&np->lock); | ||
2467 | |||
2468 | return &dev->stats; | ||
2469 | } | ||
2470 | |||
2471 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2472 | static void natsemi_poll_controller(struct net_device *dev) | ||
2473 | { | ||
2474 | disable_irq(dev->irq); | ||
2475 | intr_handler(dev->irq, dev); | ||
2476 | enable_irq(dev->irq); | ||
2477 | } | ||
2478 | #endif | ||
2479 | |||
2480 | #define HASH_TABLE 0x200 | ||
2481 | static void __set_rx_mode(struct net_device *dev) | ||
2482 | { | ||
2483 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2484 | struct netdev_private *np = netdev_priv(dev); | ||
2485 | u8 mc_filter[64]; /* Multicast hash filter */ | ||
2486 | u32 rx_mode; | ||
2487 | |||
2488 | if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ | ||
2489 | rx_mode = RxFilterEnable | AcceptBroadcast | ||
2490 | | AcceptAllMulticast | AcceptAllPhys | AcceptMyPhys; | ||
2491 | } else if ((netdev_mc_count(dev) > multicast_filter_limit) || | ||
2492 | (dev->flags & IFF_ALLMULTI)) { | ||
2493 | rx_mode = RxFilterEnable | AcceptBroadcast | ||
2494 | | AcceptAllMulticast | AcceptMyPhys; | ||
2495 | } else { | ||
2496 | struct netdev_hw_addr *ha; | ||
2497 | int i; | ||
2498 | |||
2499 | memset(mc_filter, 0, sizeof(mc_filter)); | ||
2500 | netdev_for_each_mc_addr(ha, dev) { | ||
2501 | int b = (ether_crc(ETH_ALEN, ha->addr) >> 23) & 0x1ff; | ||
2502 | mc_filter[b/8] |= (1 << (b & 0x07)); | ||
2503 | } | ||
2504 | rx_mode = RxFilterEnable | AcceptBroadcast | ||
2505 | | AcceptMulticast | AcceptMyPhys; | ||
2506 | for (i = 0; i < 64; i += 2) { | ||
2507 | writel(HASH_TABLE + i, ioaddr + RxFilterAddr); | ||
2508 | writel((mc_filter[i + 1] << 8) + mc_filter[i], | ||
2509 | ioaddr + RxFilterData); | ||
2510 | } | ||
2511 | } | ||
2512 | writel(rx_mode, ioaddr + RxFilterAddr); | ||
2513 | np->cur_rx_mode = rx_mode; | ||
2514 | } | ||
2515 | |||
2516 | static int natsemi_change_mtu(struct net_device *dev, int new_mtu) | ||
2517 | { | ||
2518 | if (new_mtu < 64 || new_mtu > NATSEMI_RX_LIMIT-NATSEMI_HEADERS) | ||
2519 | return -EINVAL; | ||
2520 | |||
2521 | dev->mtu = new_mtu; | ||
2522 | |||
2523 | /* synchronized against open : rtnl_lock() held by caller */ | ||
2524 | if (netif_running(dev)) { | ||
2525 | struct netdev_private *np = netdev_priv(dev); | ||
2526 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2527 | |||
2528 | disable_irq(dev->irq); | ||
2529 | spin_lock(&np->lock); | ||
2530 | /* stop engines */ | ||
2531 | natsemi_stop_rxtx(dev); | ||
2532 | /* drain rx queue */ | ||
2533 | drain_rx(dev); | ||
2534 | /* change buffers */ | ||
2535 | set_bufsize(dev); | ||
2536 | reinit_rx(dev); | ||
2537 | writel(np->ring_dma, ioaddr + RxRingPtr); | ||
2538 | /* restart engines */ | ||
2539 | writel(RxOn | TxOn, ioaddr + ChipCmd); | ||
2540 | spin_unlock(&np->lock); | ||
2541 | enable_irq(dev->irq); | ||
2542 | } | ||
2543 | return 0; | ||
2544 | } | ||
2545 | |||
2546 | static void set_rx_mode(struct net_device *dev) | ||
2547 | { | ||
2548 | struct netdev_private *np = netdev_priv(dev); | ||
2549 | spin_lock_irq(&np->lock); | ||
2550 | if (!np->hands_off) | ||
2551 | __set_rx_mode(dev); | ||
2552 | spin_unlock_irq(&np->lock); | ||
2553 | } | ||
2554 | |||
2555 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
2556 | { | ||
2557 | struct netdev_private *np = netdev_priv(dev); | ||
2558 | strncpy(info->driver, DRV_NAME, ETHTOOL_BUSINFO_LEN); | ||
2559 | strncpy(info->version, DRV_VERSION, ETHTOOL_BUSINFO_LEN); | ||
2560 | strncpy(info->bus_info, pci_name(np->pci_dev), ETHTOOL_BUSINFO_LEN); | ||
2561 | } | ||
2562 | |||
2563 | static int get_regs_len(struct net_device *dev) | ||
2564 | { | ||
2565 | return NATSEMI_REGS_SIZE; | ||
2566 | } | ||
2567 | |||
2568 | static int get_eeprom_len(struct net_device *dev) | ||
2569 | { | ||
2570 | struct netdev_private *np = netdev_priv(dev); | ||
2571 | return np->eeprom_size; | ||
2572 | } | ||
2573 | |||
2574 | static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | ||
2575 | { | ||
2576 | struct netdev_private *np = netdev_priv(dev); | ||
2577 | spin_lock_irq(&np->lock); | ||
2578 | netdev_get_ecmd(dev, ecmd); | ||
2579 | spin_unlock_irq(&np->lock); | ||
2580 | return 0; | ||
2581 | } | ||
2582 | |||
2583 | static int set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | ||
2584 | { | ||
2585 | struct netdev_private *np = netdev_priv(dev); | ||
2586 | int res; | ||
2587 | spin_lock_irq(&np->lock); | ||
2588 | res = netdev_set_ecmd(dev, ecmd); | ||
2589 | spin_unlock_irq(&np->lock); | ||
2590 | return res; | ||
2591 | } | ||
2592 | |||
2593 | static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
2594 | { | ||
2595 | struct netdev_private *np = netdev_priv(dev); | ||
2596 | spin_lock_irq(&np->lock); | ||
2597 | netdev_get_wol(dev, &wol->supported, &wol->wolopts); | ||
2598 | netdev_get_sopass(dev, wol->sopass); | ||
2599 | spin_unlock_irq(&np->lock); | ||
2600 | } | ||
2601 | |||
2602 | static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
2603 | { | ||
2604 | struct netdev_private *np = netdev_priv(dev); | ||
2605 | int res; | ||
2606 | spin_lock_irq(&np->lock); | ||
2607 | netdev_set_wol(dev, wol->wolopts); | ||
2608 | res = netdev_set_sopass(dev, wol->sopass); | ||
2609 | spin_unlock_irq(&np->lock); | ||
2610 | return res; | ||
2611 | } | ||
2612 | |||
2613 | static void get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) | ||
2614 | { | ||
2615 | struct netdev_private *np = netdev_priv(dev); | ||
2616 | regs->version = NATSEMI_REGS_VER; | ||
2617 | spin_lock_irq(&np->lock); | ||
2618 | netdev_get_regs(dev, buf); | ||
2619 | spin_unlock_irq(&np->lock); | ||
2620 | } | ||
2621 | |||
2622 | static u32 get_msglevel(struct net_device *dev) | ||
2623 | { | ||
2624 | struct netdev_private *np = netdev_priv(dev); | ||
2625 | return np->msg_enable; | ||
2626 | } | ||
2627 | |||
2628 | static void set_msglevel(struct net_device *dev, u32 val) | ||
2629 | { | ||
2630 | struct netdev_private *np = netdev_priv(dev); | ||
2631 | np->msg_enable = val; | ||
2632 | } | ||
2633 | |||
2634 | static int nway_reset(struct net_device *dev) | ||
2635 | { | ||
2636 | int tmp; | ||
2637 | int r = -EINVAL; | ||
2638 | /* if autoneg is off, it's an error */ | ||
2639 | tmp = mdio_read(dev, MII_BMCR); | ||
2640 | if (tmp & BMCR_ANENABLE) { | ||
2641 | tmp |= (BMCR_ANRESTART); | ||
2642 | mdio_write(dev, MII_BMCR, tmp); | ||
2643 | r = 0; | ||
2644 | } | ||
2645 | return r; | ||
2646 | } | ||
2647 | |||
2648 | static u32 get_link(struct net_device *dev) | ||
2649 | { | ||
2650 | /* LSTATUS is latched low until a read - so read twice */ | ||
2651 | mdio_read(dev, MII_BMSR); | ||
2652 | return (mdio_read(dev, MII_BMSR)&BMSR_LSTATUS) ? 1:0; | ||
2653 | } | ||
2654 | |||
2655 | static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) | ||
2656 | { | ||
2657 | struct netdev_private *np = netdev_priv(dev); | ||
2658 | u8 *eebuf; | ||
2659 | int res; | ||
2660 | |||
2661 | eebuf = kmalloc(np->eeprom_size, GFP_KERNEL); | ||
2662 | if (!eebuf) | ||
2663 | return -ENOMEM; | ||
2664 | |||
2665 | eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16); | ||
2666 | spin_lock_irq(&np->lock); | ||
2667 | res = netdev_get_eeprom(dev, eebuf); | ||
2668 | spin_unlock_irq(&np->lock); | ||
2669 | if (!res) | ||
2670 | memcpy(data, eebuf+eeprom->offset, eeprom->len); | ||
2671 | kfree(eebuf); | ||
2672 | return res; | ||
2673 | } | ||
2674 | |||
2675 | static const struct ethtool_ops ethtool_ops = { | ||
2676 | .get_drvinfo = get_drvinfo, | ||
2677 | .get_regs_len = get_regs_len, | ||
2678 | .get_eeprom_len = get_eeprom_len, | ||
2679 | .get_settings = get_settings, | ||
2680 | .set_settings = set_settings, | ||
2681 | .get_wol = get_wol, | ||
2682 | .set_wol = set_wol, | ||
2683 | .get_regs = get_regs, | ||
2684 | .get_msglevel = get_msglevel, | ||
2685 | .set_msglevel = set_msglevel, | ||
2686 | .nway_reset = nway_reset, | ||
2687 | .get_link = get_link, | ||
2688 | .get_eeprom = get_eeprom, | ||
2689 | }; | ||
2690 | |||
2691 | static int netdev_set_wol(struct net_device *dev, u32 newval) | ||
2692 | { | ||
2693 | struct netdev_private *np = netdev_priv(dev); | ||
2694 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2695 | u32 data = readl(ioaddr + WOLCmd) & ~WakeOptsSummary; | ||
2696 | |||
2697 | /* translate to bitmasks this chip understands */ | ||
2698 | if (newval & WAKE_PHY) | ||
2699 | data |= WakePhy; | ||
2700 | if (newval & WAKE_UCAST) | ||
2701 | data |= WakeUnicast; | ||
2702 | if (newval & WAKE_MCAST) | ||
2703 | data |= WakeMulticast; | ||
2704 | if (newval & WAKE_BCAST) | ||
2705 | data |= WakeBroadcast; | ||
2706 | if (newval & WAKE_ARP) | ||
2707 | data |= WakeArp; | ||
2708 | if (newval & WAKE_MAGIC) | ||
2709 | data |= WakeMagic; | ||
2710 | if (np->srr >= SRR_DP83815_D) { | ||
2711 | if (newval & WAKE_MAGICSECURE) { | ||
2712 | data |= WakeMagicSecure; | ||
2713 | } | ||
2714 | } | ||
2715 | |||
2716 | writel(data, ioaddr + WOLCmd); | ||
2717 | |||
2718 | return 0; | ||
2719 | } | ||
2720 | |||
2721 | static int netdev_get_wol(struct net_device *dev, u32 *supported, u32 *cur) | ||
2722 | { | ||
2723 | struct netdev_private *np = netdev_priv(dev); | ||
2724 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2725 | u32 regval = readl(ioaddr + WOLCmd); | ||
2726 | |||
2727 | *supported = (WAKE_PHY | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | ||
2728 | | WAKE_ARP | WAKE_MAGIC); | ||
2729 | |||
2730 | if (np->srr >= SRR_DP83815_D) { | ||
2731 | /* SOPASS works on revD and higher */ | ||
2732 | *supported |= WAKE_MAGICSECURE; | ||
2733 | } | ||
2734 | *cur = 0; | ||
2735 | |||
2736 | /* translate from chip bitmasks */ | ||
2737 | if (regval & WakePhy) | ||
2738 | *cur |= WAKE_PHY; | ||
2739 | if (regval & WakeUnicast) | ||
2740 | *cur |= WAKE_UCAST; | ||
2741 | if (regval & WakeMulticast) | ||
2742 | *cur |= WAKE_MCAST; | ||
2743 | if (regval & WakeBroadcast) | ||
2744 | *cur |= WAKE_BCAST; | ||
2745 | if (regval & WakeArp) | ||
2746 | *cur |= WAKE_ARP; | ||
2747 | if (regval & WakeMagic) | ||
2748 | *cur |= WAKE_MAGIC; | ||
2749 | if (regval & WakeMagicSecure) { | ||
2750 | /* this can be on in revC, but it's broken */ | ||
2751 | *cur |= WAKE_MAGICSECURE; | ||
2752 | } | ||
2753 | |||
2754 | return 0; | ||
2755 | } | ||
2756 | |||
2757 | static int netdev_set_sopass(struct net_device *dev, u8 *newval) | ||
2758 | { | ||
2759 | struct netdev_private *np = netdev_priv(dev); | ||
2760 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2761 | u16 *sval = (u16 *)newval; | ||
2762 | u32 addr; | ||
2763 | |||
2764 | if (np->srr < SRR_DP83815_D) { | ||
2765 | return 0; | ||
2766 | } | ||
2767 | |||
2768 | /* enable writing to these registers by disabling the RX filter */ | ||
2769 | addr = readl(ioaddr + RxFilterAddr) & ~RFCRAddressMask; | ||
2770 | addr &= ~RxFilterEnable; | ||
2771 | writel(addr, ioaddr + RxFilterAddr); | ||
2772 | |||
2773 | /* write the three words to (undocumented) RFCR vals 0xa, 0xc, 0xe */ | ||
2774 | writel(addr | 0xa, ioaddr + RxFilterAddr); | ||
2775 | writew(sval[0], ioaddr + RxFilterData); | ||
2776 | |||
2777 | writel(addr | 0xc, ioaddr + RxFilterAddr); | ||
2778 | writew(sval[1], ioaddr + RxFilterData); | ||
2779 | |||
2780 | writel(addr | 0xe, ioaddr + RxFilterAddr); | ||
2781 | writew(sval[2], ioaddr + RxFilterData); | ||
2782 | |||
2783 | /* re-enable the RX filter */ | ||
2784 | writel(addr | RxFilterEnable, ioaddr + RxFilterAddr); | ||
2785 | |||
2786 | return 0; | ||
2787 | } | ||
2788 | |||
2789 | static int netdev_get_sopass(struct net_device *dev, u8 *data) | ||
2790 | { | ||
2791 | struct netdev_private *np = netdev_priv(dev); | ||
2792 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2793 | u16 *sval = (u16 *)data; | ||
2794 | u32 addr; | ||
2795 | |||
2796 | if (np->srr < SRR_DP83815_D) { | ||
2797 | sval[0] = sval[1] = sval[2] = 0; | ||
2798 | return 0; | ||
2799 | } | ||
2800 | |||
2801 | /* read the three words from (undocumented) RFCR vals 0xa, 0xc, 0xe */ | ||
2802 | addr = readl(ioaddr + RxFilterAddr) & ~RFCRAddressMask; | ||
2803 | |||
2804 | writel(addr | 0xa, ioaddr + RxFilterAddr); | ||
2805 | sval[0] = readw(ioaddr + RxFilterData); | ||
2806 | |||
2807 | writel(addr | 0xc, ioaddr + RxFilterAddr); | ||
2808 | sval[1] = readw(ioaddr + RxFilterData); | ||
2809 | |||
2810 | writel(addr | 0xe, ioaddr + RxFilterAddr); | ||
2811 | sval[2] = readw(ioaddr + RxFilterData); | ||
2812 | |||
2813 | writel(addr, ioaddr + RxFilterAddr); | ||
2814 | |||
2815 | return 0; | ||
2816 | } | ||
2817 | |||
2818 | static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) | ||
2819 | { | ||
2820 | struct netdev_private *np = netdev_priv(dev); | ||
2821 | u32 tmp; | ||
2822 | |||
2823 | ecmd->port = dev->if_port; | ||
2824 | ethtool_cmd_speed_set(ecmd, np->speed); | ||
2825 | ecmd->duplex = np->duplex; | ||
2826 | ecmd->autoneg = np->autoneg; | ||
2827 | ecmd->advertising = 0; | ||
2828 | if (np->advertising & ADVERTISE_10HALF) | ||
2829 | ecmd->advertising |= ADVERTISED_10baseT_Half; | ||
2830 | if (np->advertising & ADVERTISE_10FULL) | ||
2831 | ecmd->advertising |= ADVERTISED_10baseT_Full; | ||
2832 | if (np->advertising & ADVERTISE_100HALF) | ||
2833 | ecmd->advertising |= ADVERTISED_100baseT_Half; | ||
2834 | if (np->advertising & ADVERTISE_100FULL) | ||
2835 | ecmd->advertising |= ADVERTISED_100baseT_Full; | ||
2836 | ecmd->supported = (SUPPORTED_Autoneg | | ||
2837 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | | ||
2838 | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | | ||
2839 | SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_FIBRE); | ||
2840 | ecmd->phy_address = np->phy_addr_external; | ||
2841 | /* | ||
2842 | * We intentionally report the phy address of the external | ||
2843 | * phy, even if the internal phy is used. This is necessary | ||
2844 | * to work around a deficiency of the ethtool interface: | ||
2845 | * It's only possible to query the settings of the active | ||
2846 | * port. Therefore | ||
2847 | * # ethtool -s ethX port mii | ||
2848 | * actually sends an ioctl to switch to port mii with the | ||
2849 | * settings that are used for the current active port. | ||
2850 | * If we would report a different phy address in this | ||
2851 | * command, then | ||
2852 | * # ethtool -s ethX port tp;ethtool -s ethX port mii | ||
2853 | * would unintentionally change the phy address. | ||
2854 | * | ||
2855 | * Fortunately the phy address doesn't matter with the | ||
2856 | * internal phy... | ||
2857 | */ | ||
2858 | |||
2859 | /* set information based on active port type */ | ||
2860 | switch (ecmd->port) { | ||
2861 | default: | ||
2862 | case PORT_TP: | ||
2863 | ecmd->advertising |= ADVERTISED_TP; | ||
2864 | ecmd->transceiver = XCVR_INTERNAL; | ||
2865 | break; | ||
2866 | case PORT_MII: | ||
2867 | ecmd->advertising |= ADVERTISED_MII; | ||
2868 | ecmd->transceiver = XCVR_EXTERNAL; | ||
2869 | break; | ||
2870 | case PORT_FIBRE: | ||
2871 | ecmd->advertising |= ADVERTISED_FIBRE; | ||
2872 | ecmd->transceiver = XCVR_EXTERNAL; | ||
2873 | break; | ||
2874 | } | ||
2875 | |||
2876 | /* if autonegotiation is on, try to return the active speed/duplex */ | ||
2877 | if (ecmd->autoneg == AUTONEG_ENABLE) { | ||
2878 | ecmd->advertising |= ADVERTISED_Autoneg; | ||
2879 | tmp = mii_nway_result( | ||
2880 | np->advertising & mdio_read(dev, MII_LPA)); | ||
2881 | if (tmp == LPA_100FULL || tmp == LPA_100HALF) | ||
2882 | ethtool_cmd_speed_set(ecmd, SPEED_100); | ||
2883 | else | ||
2884 | ethtool_cmd_speed_set(ecmd, SPEED_10); | ||
2885 | if (tmp == LPA_100FULL || tmp == LPA_10FULL) | ||
2886 | ecmd->duplex = DUPLEX_FULL; | ||
2887 | else | ||
2888 | ecmd->duplex = DUPLEX_HALF; | ||
2889 | } | ||
2890 | |||
2891 | /* ignore maxtxpkt, maxrxpkt for now */ | ||
2892 | |||
2893 | return 0; | ||
2894 | } | ||
2895 | |||
2896 | static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) | ||
2897 | { | ||
2898 | struct netdev_private *np = netdev_priv(dev); | ||
2899 | |||
2900 | if (ecmd->port != PORT_TP && ecmd->port != PORT_MII && ecmd->port != PORT_FIBRE) | ||
2901 | return -EINVAL; | ||
2902 | if (ecmd->transceiver != XCVR_INTERNAL && ecmd->transceiver != XCVR_EXTERNAL) | ||
2903 | return -EINVAL; | ||
2904 | if (ecmd->autoneg == AUTONEG_ENABLE) { | ||
2905 | if ((ecmd->advertising & (ADVERTISED_10baseT_Half | | ||
2906 | ADVERTISED_10baseT_Full | | ||
2907 | ADVERTISED_100baseT_Half | | ||
2908 | ADVERTISED_100baseT_Full)) == 0) { | ||
2909 | return -EINVAL; | ||
2910 | } | ||
2911 | } else if (ecmd->autoneg == AUTONEG_DISABLE) { | ||
2912 | u32 speed = ethtool_cmd_speed(ecmd); | ||
2913 | if (speed != SPEED_10 && speed != SPEED_100) | ||
2914 | return -EINVAL; | ||
2915 | if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) | ||
2916 | return -EINVAL; | ||
2917 | } else { | ||
2918 | return -EINVAL; | ||
2919 | } | ||
2920 | |||
2921 | /* | ||
2922 | * If we're ignoring the PHY then autoneg and the internal | ||
2923 | * transceiver are really not going to work so don't let the | ||
2924 | * user select them. | ||
2925 | */ | ||
2926 | if (np->ignore_phy && (ecmd->autoneg == AUTONEG_ENABLE || | ||
2927 | ecmd->port == PORT_TP)) | ||
2928 | return -EINVAL; | ||
2929 | |||
2930 | /* | ||
2931 | * maxtxpkt, maxrxpkt: ignored for now. | ||
2932 | * | ||
2933 | * transceiver: | ||
2934 | * PORT_TP is always XCVR_INTERNAL, PORT_MII and PORT_FIBRE are always | ||
2935 | * XCVR_EXTERNAL. The implementation thus ignores ecmd->transceiver and | ||
2936 | * selects based on ecmd->port. | ||
2937 | * | ||
2938 | * Actually PORT_FIBRE is nearly identical to PORT_MII: it's for fibre | ||
2939 | * phys that are connected to the mii bus. It's used to apply fibre | ||
2940 | * specific updates. | ||
2941 | */ | ||
2942 | |||
2943 | /* WHEW! now lets bang some bits */ | ||
2944 | |||
2945 | /* save the parms */ | ||
2946 | dev->if_port = ecmd->port; | ||
2947 | np->autoneg = ecmd->autoneg; | ||
2948 | np->phy_addr_external = ecmd->phy_address & PhyAddrMask; | ||
2949 | if (np->autoneg == AUTONEG_ENABLE) { | ||
2950 | /* advertise only what has been requested */ | ||
2951 | np->advertising &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); | ||
2952 | if (ecmd->advertising & ADVERTISED_10baseT_Half) | ||
2953 | np->advertising |= ADVERTISE_10HALF; | ||
2954 | if (ecmd->advertising & ADVERTISED_10baseT_Full) | ||
2955 | np->advertising |= ADVERTISE_10FULL; | ||
2956 | if (ecmd->advertising & ADVERTISED_100baseT_Half) | ||
2957 | np->advertising |= ADVERTISE_100HALF; | ||
2958 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | ||
2959 | np->advertising |= ADVERTISE_100FULL; | ||
2960 | } else { | ||
2961 | np->speed = ethtool_cmd_speed(ecmd); | ||
2962 | np->duplex = ecmd->duplex; | ||
2963 | /* user overriding the initial full duplex parm? */ | ||
2964 | if (np->duplex == DUPLEX_HALF) | ||
2965 | np->full_duplex = 0; | ||
2966 | } | ||
2967 | |||
2968 | /* get the right phy enabled */ | ||
2969 | if (ecmd->port == PORT_TP) | ||
2970 | switch_port_internal(dev); | ||
2971 | else | ||
2972 | switch_port_external(dev); | ||
2973 | |||
2974 | /* set parms and see how this affected our link status */ | ||
2975 | init_phy_fixup(dev); | ||
2976 | check_link(dev); | ||
2977 | return 0; | ||
2978 | } | ||
2979 | |||
2980 | static int netdev_get_regs(struct net_device *dev, u8 *buf) | ||
2981 | { | ||
2982 | int i; | ||
2983 | int j; | ||
2984 | u32 rfcr; | ||
2985 | u32 *rbuf = (u32 *)buf; | ||
2986 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
2987 | |||
2988 | /* read non-mii page 0 of registers */ | ||
2989 | for (i = 0; i < NATSEMI_PG0_NREGS/2; i++) { | ||
2990 | rbuf[i] = readl(ioaddr + i*4); | ||
2991 | } | ||
2992 | |||
2993 | /* read current mii registers */ | ||
2994 | for (i = NATSEMI_PG0_NREGS/2; i < NATSEMI_PG0_NREGS; i++) | ||
2995 | rbuf[i] = mdio_read(dev, i & 0x1f); | ||
2996 | |||
2997 | /* read only the 'magic' registers from page 1 */ | ||
2998 | writew(1, ioaddr + PGSEL); | ||
2999 | rbuf[i++] = readw(ioaddr + PMDCSR); | ||
3000 | rbuf[i++] = readw(ioaddr + TSTDAT); | ||
3001 | rbuf[i++] = readw(ioaddr + DSPCFG); | ||
3002 | rbuf[i++] = readw(ioaddr + SDCFG); | ||
3003 | writew(0, ioaddr + PGSEL); | ||
3004 | |||
3005 | /* read RFCR indexed registers */ | ||
3006 | rfcr = readl(ioaddr + RxFilterAddr); | ||
3007 | for (j = 0; j < NATSEMI_RFDR_NREGS; j++) { | ||
3008 | writel(j*2, ioaddr + RxFilterAddr); | ||
3009 | rbuf[i++] = readw(ioaddr + RxFilterData); | ||
3010 | } | ||
3011 | writel(rfcr, ioaddr + RxFilterAddr); | ||
3012 | |||
3013 | /* the interrupt status is clear-on-read - see if we missed any */ | ||
3014 | if (rbuf[4] & rbuf[5]) { | ||
3015 | printk(KERN_WARNING | ||
3016 | "%s: shoot, we dropped an interrupt (%#08x)\n", | ||
3017 | dev->name, rbuf[4] & rbuf[5]); | ||
3018 | } | ||
3019 | |||
3020 | return 0; | ||
3021 | } | ||
3022 | |||
3023 | #define SWAP_BITS(x) ( (((x) & 0x0001) << 15) | (((x) & 0x0002) << 13) \ | ||
3024 | | (((x) & 0x0004) << 11) | (((x) & 0x0008) << 9) \ | ||
3025 | | (((x) & 0x0010) << 7) | (((x) & 0x0020) << 5) \ | ||
3026 | | (((x) & 0x0040) << 3) | (((x) & 0x0080) << 1) \ | ||
3027 | | (((x) & 0x0100) >> 1) | (((x) & 0x0200) >> 3) \ | ||
3028 | | (((x) & 0x0400) >> 5) | (((x) & 0x0800) >> 7) \ | ||
3029 | | (((x) & 0x1000) >> 9) | (((x) & 0x2000) >> 11) \ | ||
3030 | | (((x) & 0x4000) >> 13) | (((x) & 0x8000) >> 15) ) | ||
3031 | |||
3032 | static int netdev_get_eeprom(struct net_device *dev, u8 *buf) | ||
3033 | { | ||
3034 | int i; | ||
3035 | u16 *ebuf = (u16 *)buf; | ||
3036 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
3037 | struct netdev_private *np = netdev_priv(dev); | ||
3038 | |||
3039 | /* eeprom_read reads 16 bits, and indexes by 16 bits */ | ||
3040 | for (i = 0; i < np->eeprom_size/2; i++) { | ||
3041 | ebuf[i] = eeprom_read(ioaddr, i); | ||
3042 | /* The EEPROM itself stores data bit-swapped, but eeprom_read | ||
3043 | * reads it back "sanely". So we swap it back here in order to | ||
3044 | * present it to userland as it is stored. */ | ||
3045 | ebuf[i] = SWAP_BITS(ebuf[i]); | ||
3046 | } | ||
3047 | return 0; | ||
3048 | } | ||
3049 | |||
3050 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
3051 | { | ||
3052 | struct mii_ioctl_data *data = if_mii(rq); | ||
3053 | struct netdev_private *np = netdev_priv(dev); | ||
3054 | |||
3055 | switch(cmd) { | ||
3056 | case SIOCGMIIPHY: /* Get address of MII PHY in use. */ | ||
3057 | data->phy_id = np->phy_addr_external; | ||
3058 | /* Fall Through */ | ||
3059 | |||
3060 | case SIOCGMIIREG: /* Read MII PHY register. */ | ||
3061 | /* The phy_id is not enough to uniquely identify | ||
3062 | * the intended target. Therefore the command is sent to | ||
3063 | * the given mii on the current port. | ||
3064 | */ | ||
3065 | if (dev->if_port == PORT_TP) { | ||
3066 | if ((data->phy_id & 0x1f) == np->phy_addr_external) | ||
3067 | data->val_out = mdio_read(dev, | ||
3068 | data->reg_num & 0x1f); | ||
3069 | else | ||
3070 | data->val_out = 0; | ||
3071 | } else { | ||
3072 | move_int_phy(dev, data->phy_id & 0x1f); | ||
3073 | data->val_out = miiport_read(dev, data->phy_id & 0x1f, | ||
3074 | data->reg_num & 0x1f); | ||
3075 | } | ||
3076 | return 0; | ||
3077 | |||
3078 | case SIOCSMIIREG: /* Write MII PHY register. */ | ||
3079 | if (dev->if_port == PORT_TP) { | ||
3080 | if ((data->phy_id & 0x1f) == np->phy_addr_external) { | ||
3081 | if ((data->reg_num & 0x1f) == MII_ADVERTISE) | ||
3082 | np->advertising = data->val_in; | ||
3083 | mdio_write(dev, data->reg_num & 0x1f, | ||
3084 | data->val_in); | ||
3085 | } | ||
3086 | } else { | ||
3087 | if ((data->phy_id & 0x1f) == np->phy_addr_external) { | ||
3088 | if ((data->reg_num & 0x1f) == MII_ADVERTISE) | ||
3089 | np->advertising = data->val_in; | ||
3090 | } | ||
3091 | move_int_phy(dev, data->phy_id & 0x1f); | ||
3092 | miiport_write(dev, data->phy_id & 0x1f, | ||
3093 | data->reg_num & 0x1f, | ||
3094 | data->val_in); | ||
3095 | } | ||
3096 | return 0; | ||
3097 | default: | ||
3098 | return -EOPNOTSUPP; | ||
3099 | } | ||
3100 | } | ||
3101 | |||
3102 | static void enable_wol_mode(struct net_device *dev, int enable_intr) | ||
3103 | { | ||
3104 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
3105 | struct netdev_private *np = netdev_priv(dev); | ||
3106 | |||
3107 | if (netif_msg_wol(np)) | ||
3108 | printk(KERN_INFO "%s: remaining active for wake-on-lan\n", | ||
3109 | dev->name); | ||
3110 | |||
3111 | /* For WOL we must restart the rx process in silent mode. | ||
3112 | * Write NULL to the RxRingPtr. Only possible if | ||
3113 | * rx process is stopped | ||
3114 | */ | ||
3115 | writel(0, ioaddr + RxRingPtr); | ||
3116 | |||
3117 | /* read WoL status to clear */ | ||
3118 | readl(ioaddr + WOLCmd); | ||
3119 | |||
3120 | /* PME on, clear status */ | ||
3121 | writel(np->SavedClkRun | PMEEnable | PMEStatus, ioaddr + ClkRun); | ||
3122 | |||
3123 | /* and restart the rx process */ | ||
3124 | writel(RxOn, ioaddr + ChipCmd); | ||
3125 | |||
3126 | if (enable_intr) { | ||
3127 | /* enable the WOL interrupt. | ||
3128 | * Could be used to send a netlink message. | ||
3129 | */ | ||
3130 | writel(WOLPkt | LinkChange, ioaddr + IntrMask); | ||
3131 | natsemi_irq_enable(dev); | ||
3132 | } | ||
3133 | } | ||
3134 | |||
3135 | static int netdev_close(struct net_device *dev) | ||
3136 | { | ||
3137 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
3138 | struct netdev_private *np = netdev_priv(dev); | ||
3139 | |||
3140 | if (netif_msg_ifdown(np)) | ||
3141 | printk(KERN_DEBUG | ||
3142 | "%s: Shutting down ethercard, status was %#04x.\n", | ||
3143 | dev->name, (int)readl(ioaddr + ChipCmd)); | ||
3144 | if (netif_msg_pktdata(np)) | ||
3145 | printk(KERN_DEBUG | ||
3146 | "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", | ||
3147 | dev->name, np->cur_tx, np->dirty_tx, | ||
3148 | np->cur_rx, np->dirty_rx); | ||
3149 | |||
3150 | napi_disable(&np->napi); | ||
3151 | |||
3152 | /* | ||
3153 | * FIXME: what if someone tries to close a device | ||
3154 | * that is suspended? | ||
3155 | * Should we reenable the nic to switch to | ||
3156 | * the final WOL settings? | ||
3157 | */ | ||
3158 | |||
3159 | del_timer_sync(&np->timer); | ||
3160 | disable_irq(dev->irq); | ||
3161 | spin_lock_irq(&np->lock); | ||
3162 | natsemi_irq_disable(dev); | ||
3163 | np->hands_off = 1; | ||
3164 | spin_unlock_irq(&np->lock); | ||
3165 | enable_irq(dev->irq); | ||
3166 | |||
3167 | free_irq(dev->irq, dev); | ||
3168 | |||
3169 | /* Interrupt disabled, interrupt handler released, | ||
3170 | * queue stopped, timer deleted, rtnl_lock held | ||
3171 | * All async codepaths that access the driver are disabled. | ||
3172 | */ | ||
3173 | spin_lock_irq(&np->lock); | ||
3174 | np->hands_off = 0; | ||
3175 | readl(ioaddr + IntrMask); | ||
3176 | readw(ioaddr + MIntrStatus); | ||
3177 | |||
3178 | /* Freeze Stats */ | ||
3179 | writel(StatsFreeze, ioaddr + StatsCtrl); | ||
3180 | |||
3181 | /* Stop the chip's Tx and Rx processes. */ | ||
3182 | natsemi_stop_rxtx(dev); | ||
3183 | |||
3184 | __get_stats(dev); | ||
3185 | spin_unlock_irq(&np->lock); | ||
3186 | |||
3187 | /* clear the carrier last - an interrupt could reenable it otherwise */ | ||
3188 | netif_carrier_off(dev); | ||
3189 | netif_stop_queue(dev); | ||
3190 | |||
3191 | dump_ring(dev); | ||
3192 | drain_ring(dev); | ||
3193 | free_ring(dev); | ||
3194 | |||
3195 | { | ||
3196 | u32 wol = readl(ioaddr + WOLCmd) & WakeOptsSummary; | ||
3197 | if (wol) { | ||
3198 | /* restart the NIC in WOL mode. | ||
3199 | * The nic must be stopped for this. | ||
3200 | */ | ||
3201 | enable_wol_mode(dev, 0); | ||
3202 | } else { | ||
3203 | /* Restore PME enable bit unmolested */ | ||
3204 | writel(np->SavedClkRun, ioaddr + ClkRun); | ||
3205 | } | ||
3206 | } | ||
3207 | return 0; | ||
3208 | } | ||
3209 | |||
3210 | |||
3211 | static void __devexit natsemi_remove1 (struct pci_dev *pdev) | ||
3212 | { | ||
3213 | struct net_device *dev = pci_get_drvdata(pdev); | ||
3214 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
3215 | |||
3216 | NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); | ||
3217 | unregister_netdev (dev); | ||
3218 | pci_release_regions (pdev); | ||
3219 | iounmap(ioaddr); | ||
3220 | free_netdev (dev); | ||
3221 | pci_set_drvdata(pdev, NULL); | ||
3222 | } | ||
3223 | |||
3224 | #ifdef CONFIG_PM | ||
3225 | |||
3226 | /* | ||
3227 | * The ns83815 chip doesn't have explicit RxStop bits. | ||
3228 | * Kicking the Rx or Tx process for a new packet reenables the Rx process | ||
3229 | * of the nic, thus this function must be very careful: | ||
3230 | * | ||
3231 | * suspend/resume synchronization: | ||
3232 | * entry points: | ||
3233 | * netdev_open, netdev_close, netdev_ioctl, set_rx_mode, intr_handler, | ||
3234 | * start_tx, ns_tx_timeout | ||
3235 | * | ||
3236 | * No function accesses the hardware without checking np->hands_off. | ||
3237 | * the check occurs under spin_lock_irq(&np->lock); | ||
3238 | * exceptions: | ||
3239 | * * netdev_ioctl: noncritical access. | ||
3240 | * * netdev_open: cannot happen due to the device_detach | ||
3241 | * * netdev_close: doesn't hurt. | ||
3242 | * * netdev_timer: timer stopped by natsemi_suspend. | ||
3243 | * * intr_handler: doesn't acquire the spinlock. suspend calls | ||
3244 | * disable_irq() to enforce synchronization. | ||
3245 | * * natsemi_poll: checks before reenabling interrupts. suspend | ||
3246 | * sets hands_off, disables interrupts and then waits with | ||
3247 | * napi_disable(). | ||
3248 | * | ||
3249 | * Interrupts must be disabled, otherwise hands_off can cause irq storms. | ||
3250 | */ | ||
3251 | |||
3252 | static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state) | ||
3253 | { | ||
3254 | struct net_device *dev = pci_get_drvdata (pdev); | ||
3255 | struct netdev_private *np = netdev_priv(dev); | ||
3256 | void __iomem * ioaddr = ns_ioaddr(dev); | ||
3257 | |||
3258 | rtnl_lock(); | ||
3259 | if (netif_running (dev)) { | ||
3260 | del_timer_sync(&np->timer); | ||
3261 | |||
3262 | disable_irq(dev->irq); | ||
3263 | spin_lock_irq(&np->lock); | ||
3264 | |||
3265 | natsemi_irq_disable(dev); | ||
3266 | np->hands_off = 1; | ||
3267 | natsemi_stop_rxtx(dev); | ||
3268 | netif_stop_queue(dev); | ||
3269 | |||
3270 | spin_unlock_irq(&np->lock); | ||
3271 | enable_irq(dev->irq); | ||
3272 | |||
3273 | napi_disable(&np->napi); | ||
3274 | |||
3275 | /* Update the error counts. */ | ||
3276 | __get_stats(dev); | ||
3277 | |||
3278 | /* pci_power_off(pdev, -1); */ | ||
3279 | drain_ring(dev); | ||
3280 | { | ||
3281 | u32 wol = readl(ioaddr + WOLCmd) & WakeOptsSummary; | ||
3282 | /* Restore PME enable bit */ | ||
3283 | if (wol) { | ||
3284 | /* restart the NIC in WOL mode. | ||
3285 | * The nic must be stopped for this. | ||
3286 | * FIXME: use the WOL interrupt | ||
3287 | */ | ||
3288 | enable_wol_mode(dev, 0); | ||
3289 | } else { | ||
3290 | /* Restore PME enable bit unmolested */ | ||
3291 | writel(np->SavedClkRun, ioaddr + ClkRun); | ||
3292 | } | ||
3293 | } | ||
3294 | } | ||
3295 | netif_device_detach(dev); | ||
3296 | rtnl_unlock(); | ||
3297 | return 0; | ||
3298 | } | ||
3299 | |||
3300 | |||
3301 | static int natsemi_resume (struct pci_dev *pdev) | ||
3302 | { | ||
3303 | struct net_device *dev = pci_get_drvdata (pdev); | ||
3304 | struct netdev_private *np = netdev_priv(dev); | ||
3305 | int ret = 0; | ||
3306 | |||
3307 | rtnl_lock(); | ||
3308 | if (netif_device_present(dev)) | ||
3309 | goto out; | ||
3310 | if (netif_running(dev)) { | ||
3311 | BUG_ON(!np->hands_off); | ||
3312 | ret = pci_enable_device(pdev); | ||
3313 | if (ret < 0) { | ||
3314 | dev_err(&pdev->dev, | ||
3315 | "pci_enable_device() failed: %d\n", ret); | ||
3316 | goto out; | ||
3317 | } | ||
3318 | /* pci_power_on(pdev); */ | ||
3319 | |||
3320 | napi_enable(&np->napi); | ||
3321 | |||
3322 | natsemi_reset(dev); | ||
3323 | init_ring(dev); | ||
3324 | disable_irq(dev->irq); | ||
3325 | spin_lock_irq(&np->lock); | ||
3326 | np->hands_off = 0; | ||
3327 | init_registers(dev); | ||
3328 | netif_device_attach(dev); | ||
3329 | spin_unlock_irq(&np->lock); | ||
3330 | enable_irq(dev->irq); | ||
3331 | |||
3332 | mod_timer(&np->timer, round_jiffies(jiffies + 1*HZ)); | ||
3333 | } | ||
3334 | netif_device_attach(dev); | ||
3335 | out: | ||
3336 | rtnl_unlock(); | ||
3337 | return ret; | ||
3338 | } | ||
3339 | |||
3340 | #endif /* CONFIG_PM */ | ||
3341 | |||
3342 | static struct pci_driver natsemi_driver = { | ||
3343 | .name = DRV_NAME, | ||
3344 | .id_table = natsemi_pci_tbl, | ||
3345 | .probe = natsemi_probe1, | ||
3346 | .remove = __devexit_p(natsemi_remove1), | ||
3347 | #ifdef CONFIG_PM | ||
3348 | .suspend = natsemi_suspend, | ||
3349 | .resume = natsemi_resume, | ||
3350 | #endif | ||
3351 | }; | ||
3352 | |||
3353 | static int __init natsemi_init_mod (void) | ||
3354 | { | ||
3355 | /* when a module, this is printed whether or not devices are found in probe */ | ||
3356 | #ifdef MODULE | ||
3357 | printk(version); | ||
3358 | #endif | ||
3359 | |||
3360 | return pci_register_driver(&natsemi_driver); | ||
3361 | } | ||
3362 | |||
3363 | static void __exit natsemi_exit_mod (void) | ||
3364 | { | ||
3365 | pci_unregister_driver (&natsemi_driver); | ||
3366 | } | ||
3367 | |||
3368 | module_init(natsemi_init_mod); | ||
3369 | module_exit(natsemi_exit_mod); | ||
3370 | |||
diff --git a/drivers/net/ethernet/natsemi/ns83820.c b/drivers/net/ethernet/natsemi/ns83820.c new file mode 100644 index 000000000000..e736aec588fc --- /dev/null +++ b/drivers/net/ethernet/natsemi/ns83820.c | |||
@@ -0,0 +1,2312 @@ | |||
1 | #define VERSION "0.23" | ||
2 | /* ns83820.c by Benjamin LaHaise with contributions. | ||
3 | * | ||
4 | * Questions/comments/discussion to linux-ns83820@kvack.org. | ||
5 | * | ||
6 | * $Revision: 1.34.2.23 $ | ||
7 | * | ||
8 | * Copyright 2001 Benjamin LaHaise. | ||
9 | * Copyright 2001, 2002 Red Hat. | ||
10 | * | ||
11 | * Mmmm, chocolate vanilla mocha... | ||
12 | * | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | * | ||
28 | * | ||
29 | * ChangeLog | ||
30 | * ========= | ||
31 | * 20010414 0.1 - created | ||
32 | * 20010622 0.2 - basic rx and tx. | ||
33 | * 20010711 0.3 - added duplex and link state detection support. | ||
34 | * 20010713 0.4 - zero copy, no hangs. | ||
35 | * 0.5 - 64 bit dma support (davem will hate me for this) | ||
36 | * - disable jumbo frames to avoid tx hangs | ||
37 | * - work around tx deadlocks on my 1.02 card via | ||
38 | * fiddling with TXCFG | ||
39 | * 20010810 0.6 - use pci dma api for ringbuffers, work on ia64 | ||
40 | * 20010816 0.7 - misc cleanups | ||
41 | * 20010826 0.8 - fix critical zero copy bugs | ||
42 | * 0.9 - internal experiment | ||
43 | * 20010827 0.10 - fix ia64 unaligned access. | ||
44 | * 20010906 0.11 - accept all packets with checksum errors as | ||
45 | * otherwise fragments get lost | ||
46 | * - fix >> 32 bugs | ||
47 | * 0.12 - add statistics counters | ||
48 | * - add allmulti/promisc support | ||
49 | * 20011009 0.13 - hotplug support, other smaller pci api cleanups | ||
50 | * 20011204 0.13a - optical transceiver support added | ||
51 | * by Michael Clark <michael@metaparadigm.com> | ||
52 | * 20011205 0.13b - call register_netdev earlier in initialization | ||
53 | * suppress duplicate link status messages | ||
54 | * 20011117 0.14 - ethtool GDRVINFO, GLINK support from jgarzik | ||
55 | * 20011204 0.15 get ppc (big endian) working | ||
56 | * 20011218 0.16 various cleanups | ||
57 | * 20020310 0.17 speedups | ||
58 | * 20020610 0.18 - actually use the pci dma api for highmem | ||
59 | * - remove pci latency register fiddling | ||
60 | * 0.19 - better bist support | ||
61 | * - add ihr and reset_phy parameters | ||
62 | * - gmii bus probing | ||
63 | * - fix missed txok introduced during performance | ||
64 | * tuning | ||
65 | * 0.20 - fix stupid RFEN thinko. i am such a smurf. | ||
66 | * 20040828 0.21 - add hardware vlan accleration | ||
67 | * by Neil Horman <nhorman@redhat.com> | ||
68 | * 20050406 0.22 - improved DAC ifdefs from Andi Kleen | ||
69 | * - removal of dead code from Adrian Bunk | ||
70 | * - fix half duplex collision behaviour | ||
71 | * Driver Overview | ||
72 | * =============== | ||
73 | * | ||
74 | * This driver was originally written for the National Semiconductor | ||
75 | * 83820 chip, a 10/100/1000 Mbps 64 bit PCI ethernet NIC. Hopefully | ||
76 | * this code will turn out to be a) clean, b) correct, and c) fast. | ||
77 | * With that in mind, I'm aiming to split the code up as much as | ||
78 | * reasonably possible. At present there are X major sections that | ||
79 | * break down into a) packet receive, b) packet transmit, c) link | ||
80 | * management, d) initialization and configuration. Where possible, | ||
81 | * these code paths are designed to run in parallel. | ||
82 | * | ||
83 | * This driver has been tested and found to work with the following | ||
84 | * cards (in no particular order): | ||
85 | * | ||
86 | * Cameo SOHO-GA2000T SOHO-GA2500T | ||
87 | * D-Link DGE-500T | ||
88 | * PureData PDP8023Z-TG | ||
89 | * SMC SMC9452TX SMC9462TX | ||
90 | * Netgear GA621 | ||
91 | * | ||
92 | * Special thanks to SMC for providing hardware to test this driver on. | ||
93 | * | ||
94 | * Reports of success or failure would be greatly appreciated. | ||
95 | */ | ||
96 | //#define dprintk printk | ||
97 | #define dprintk(x...) do { } while (0) | ||
98 | |||
99 | #include <linux/module.h> | ||
100 | #include <linux/moduleparam.h> | ||
101 | #include <linux/types.h> | ||
102 | #include <linux/pci.h> | ||
103 | #include <linux/dma-mapping.h> | ||
104 | #include <linux/netdevice.h> | ||
105 | #include <linux/etherdevice.h> | ||
106 | #include <linux/delay.h> | ||
107 | #include <linux/workqueue.h> | ||
108 | #include <linux/init.h> | ||
109 | #include <linux/interrupt.h> | ||
110 | #include <linux/ip.h> /* for iph */ | ||
111 | #include <linux/in.h> /* for IPPROTO_... */ | ||
112 | #include <linux/compiler.h> | ||
113 | #include <linux/prefetch.h> | ||
114 | #include <linux/ethtool.h> | ||
115 | #include <linux/sched.h> | ||
116 | #include <linux/timer.h> | ||
117 | #include <linux/if_vlan.h> | ||
118 | #include <linux/rtnetlink.h> | ||
119 | #include <linux/jiffies.h> | ||
120 | #include <linux/slab.h> | ||
121 | |||
122 | #include <asm/io.h> | ||
123 | #include <asm/uaccess.h> | ||
124 | #include <asm/system.h> | ||
125 | |||
126 | #define DRV_NAME "ns83820" | ||
127 | |||
128 | /* Global parameters. See module_param near the bottom. */ | ||
129 | static int ihr = 2; | ||
130 | static int reset_phy = 0; | ||
131 | static int lnksts = 0; /* CFG_LNKSTS bit polarity */ | ||
132 | |||
133 | /* Dprintk is used for more interesting debug events */ | ||
134 | #undef Dprintk | ||
135 | #define Dprintk dprintk | ||
136 | |||
137 | /* tunables */ | ||
138 | #define RX_BUF_SIZE 1500 /* 8192 */ | ||
139 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
140 | #define NS83820_VLAN_ACCEL_SUPPORT | ||
141 | #endif | ||
142 | |||
143 | /* Must not exceed ~65000. */ | ||
144 | #define NR_RX_DESC 64 | ||
145 | #define NR_TX_DESC 128 | ||
146 | |||
147 | /* not tunable */ | ||
148 | #define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14) /* rx/tx mac addr + type */ | ||
149 | |||
150 | #define MIN_TX_DESC_FREE 8 | ||
151 | |||
152 | /* register defines */ | ||
153 | #define CFGCS 0x04 | ||
154 | |||
155 | #define CR_TXE 0x00000001 | ||
156 | #define CR_TXD 0x00000002 | ||
157 | /* Ramit : Here's a tip, don't do a RXD immediately followed by an RXE | ||
158 | * The Receive engine skips one descriptor and moves | ||
159 | * onto the next one!! */ | ||
160 | #define CR_RXE 0x00000004 | ||
161 | #define CR_RXD 0x00000008 | ||
162 | #define CR_TXR 0x00000010 | ||
163 | #define CR_RXR 0x00000020 | ||
164 | #define CR_SWI 0x00000080 | ||
165 | #define CR_RST 0x00000100 | ||
166 | |||
167 | #define PTSCR_EEBIST_FAIL 0x00000001 | ||
168 | #define PTSCR_EEBIST_EN 0x00000002 | ||
169 | #define PTSCR_EELOAD_EN 0x00000004 | ||
170 | #define PTSCR_RBIST_FAIL 0x000001b8 | ||
171 | #define PTSCR_RBIST_DONE 0x00000200 | ||
172 | #define PTSCR_RBIST_EN 0x00000400 | ||
173 | #define PTSCR_RBIST_RST 0x00002000 | ||
174 | |||
175 | #define MEAR_EEDI 0x00000001 | ||
176 | #define MEAR_EEDO 0x00000002 | ||
177 | #define MEAR_EECLK 0x00000004 | ||
178 | #define MEAR_EESEL 0x00000008 | ||
179 | #define MEAR_MDIO 0x00000010 | ||
180 | #define MEAR_MDDIR 0x00000020 | ||
181 | #define MEAR_MDC 0x00000040 | ||
182 | |||
183 | #define ISR_TXDESC3 0x40000000 | ||
184 | #define ISR_TXDESC2 0x20000000 | ||
185 | #define ISR_TXDESC1 0x10000000 | ||
186 | #define ISR_TXDESC0 0x08000000 | ||
187 | #define ISR_RXDESC3 0x04000000 | ||
188 | #define ISR_RXDESC2 0x02000000 | ||
189 | #define ISR_RXDESC1 0x01000000 | ||
190 | #define ISR_RXDESC0 0x00800000 | ||
191 | #define ISR_TXRCMP 0x00400000 | ||
192 | #define ISR_RXRCMP 0x00200000 | ||
193 | #define ISR_DPERR 0x00100000 | ||
194 | #define ISR_SSERR 0x00080000 | ||
195 | #define ISR_RMABT 0x00040000 | ||
196 | #define ISR_RTABT 0x00020000 | ||
197 | #define ISR_RXSOVR 0x00010000 | ||
198 | #define ISR_HIBINT 0x00008000 | ||
199 | #define ISR_PHY 0x00004000 | ||
200 | #define ISR_PME 0x00002000 | ||
201 | #define ISR_SWI 0x00001000 | ||
202 | #define ISR_MIB 0x00000800 | ||
203 | #define ISR_TXURN 0x00000400 | ||
204 | #define ISR_TXIDLE 0x00000200 | ||
205 | #define ISR_TXERR 0x00000100 | ||
206 | #define ISR_TXDESC 0x00000080 | ||
207 | #define ISR_TXOK 0x00000040 | ||
208 | #define ISR_RXORN 0x00000020 | ||
209 | #define ISR_RXIDLE 0x00000010 | ||
210 | #define ISR_RXEARLY 0x00000008 | ||
211 | #define ISR_RXERR 0x00000004 | ||
212 | #define ISR_RXDESC 0x00000002 | ||
213 | #define ISR_RXOK 0x00000001 | ||
214 | |||
215 | #define TXCFG_CSI 0x80000000 | ||
216 | #define TXCFG_HBI 0x40000000 | ||
217 | #define TXCFG_MLB 0x20000000 | ||
218 | #define TXCFG_ATP 0x10000000 | ||
219 | #define TXCFG_ECRETRY 0x00800000 | ||
220 | #define TXCFG_BRST_DIS 0x00080000 | ||
221 | #define TXCFG_MXDMA1024 0x00000000 | ||
222 | #define TXCFG_MXDMA512 0x00700000 | ||
223 | #define TXCFG_MXDMA256 0x00600000 | ||
224 | #define TXCFG_MXDMA128 0x00500000 | ||
225 | #define TXCFG_MXDMA64 0x00400000 | ||
226 | #define TXCFG_MXDMA32 0x00300000 | ||
227 | #define TXCFG_MXDMA16 0x00200000 | ||
228 | #define TXCFG_MXDMA8 0x00100000 | ||
229 | |||
230 | #define CFG_LNKSTS 0x80000000 | ||
231 | #define CFG_SPDSTS 0x60000000 | ||
232 | #define CFG_SPDSTS1 0x40000000 | ||
233 | #define CFG_SPDSTS0 0x20000000 | ||
234 | #define CFG_DUPSTS 0x10000000 | ||
235 | #define CFG_TBI_EN 0x01000000 | ||
236 | #define CFG_MODE_1000 0x00400000 | ||
237 | /* Ramit : Dont' ever use AUTO_1000, it never works and is buggy. | ||
238 | * Read the Phy response and then configure the MAC accordingly */ | ||
239 | #define CFG_AUTO_1000 0x00200000 | ||
240 | #define CFG_PINT_CTL 0x001c0000 | ||
241 | #define CFG_PINT_DUPSTS 0x00100000 | ||
242 | #define CFG_PINT_LNKSTS 0x00080000 | ||
243 | #define CFG_PINT_SPDSTS 0x00040000 | ||
244 | #define CFG_TMRTEST 0x00020000 | ||
245 | #define CFG_MRM_DIS 0x00010000 | ||
246 | #define CFG_MWI_DIS 0x00008000 | ||
247 | #define CFG_T64ADDR 0x00004000 | ||
248 | #define CFG_PCI64_DET 0x00002000 | ||
249 | #define CFG_DATA64_EN 0x00001000 | ||
250 | #define CFG_M64ADDR 0x00000800 | ||
251 | #define CFG_PHY_RST 0x00000400 | ||
252 | #define CFG_PHY_DIS 0x00000200 | ||
253 | #define CFG_EXTSTS_EN 0x00000100 | ||
254 | #define CFG_REQALG 0x00000080 | ||
255 | #define CFG_SB 0x00000040 | ||
256 | #define CFG_POW 0x00000020 | ||
257 | #define CFG_EXD 0x00000010 | ||
258 | #define CFG_PESEL 0x00000008 | ||
259 | #define CFG_BROM_DIS 0x00000004 | ||
260 | #define CFG_EXT_125 0x00000002 | ||
261 | #define CFG_BEM 0x00000001 | ||
262 | |||
263 | #define EXTSTS_UDPPKT 0x00200000 | ||
264 | #define EXTSTS_TCPPKT 0x00080000 | ||
265 | #define EXTSTS_IPPKT 0x00020000 | ||
266 | #define EXTSTS_VPKT 0x00010000 | ||
267 | #define EXTSTS_VTG_MASK 0x0000ffff | ||
268 | |||
269 | #define SPDSTS_POLARITY (CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS | (lnksts ? CFG_LNKSTS : 0)) | ||
270 | |||
271 | #define MIBC_MIBS 0x00000008 | ||
272 | #define MIBC_ACLR 0x00000004 | ||
273 | #define MIBC_FRZ 0x00000002 | ||
274 | #define MIBC_WRN 0x00000001 | ||
275 | |||
276 | #define PCR_PSEN (1 << 31) | ||
277 | #define PCR_PS_MCAST (1 << 30) | ||
278 | #define PCR_PS_DA (1 << 29) | ||
279 | #define PCR_STHI_8 (3 << 23) | ||
280 | #define PCR_STLO_4 (1 << 23) | ||
281 | #define PCR_FFHI_8K (3 << 21) | ||
282 | #define PCR_FFLO_4K (1 << 21) | ||
283 | #define PCR_PAUSE_CNT 0xFFFE | ||
284 | |||
285 | #define RXCFG_AEP 0x80000000 | ||
286 | #define RXCFG_ARP 0x40000000 | ||
287 | #define RXCFG_STRIPCRC 0x20000000 | ||
288 | #define RXCFG_RX_FD 0x10000000 | ||
289 | #define RXCFG_ALP 0x08000000 | ||
290 | #define RXCFG_AIRL 0x04000000 | ||
291 | #define RXCFG_MXDMA512 0x00700000 | ||
292 | #define RXCFG_DRTH 0x0000003e | ||
293 | #define RXCFG_DRTH0 0x00000002 | ||
294 | |||
295 | #define RFCR_RFEN 0x80000000 | ||
296 | #define RFCR_AAB 0x40000000 | ||
297 | #define RFCR_AAM 0x20000000 | ||
298 | #define RFCR_AAU 0x10000000 | ||
299 | #define RFCR_APM 0x08000000 | ||
300 | #define RFCR_APAT 0x07800000 | ||
301 | #define RFCR_APAT3 0x04000000 | ||
302 | #define RFCR_APAT2 0x02000000 | ||
303 | #define RFCR_APAT1 0x01000000 | ||
304 | #define RFCR_APAT0 0x00800000 | ||
305 | #define RFCR_AARP 0x00400000 | ||
306 | #define RFCR_MHEN 0x00200000 | ||
307 | #define RFCR_UHEN 0x00100000 | ||
308 | #define RFCR_ULM 0x00080000 | ||
309 | |||
310 | #define VRCR_RUDPE 0x00000080 | ||
311 | #define VRCR_RTCPE 0x00000040 | ||
312 | #define VRCR_RIPE 0x00000020 | ||
313 | #define VRCR_IPEN 0x00000010 | ||
314 | #define VRCR_DUTF 0x00000008 | ||
315 | #define VRCR_DVTF 0x00000004 | ||
316 | #define VRCR_VTREN 0x00000002 | ||
317 | #define VRCR_VTDEN 0x00000001 | ||
318 | |||
319 | #define VTCR_PPCHK 0x00000008 | ||
320 | #define VTCR_GCHK 0x00000004 | ||
321 | #define VTCR_VPPTI 0x00000002 | ||
322 | #define VTCR_VGTI 0x00000001 | ||
323 | |||
324 | #define CR 0x00 | ||
325 | #define CFG 0x04 | ||
326 | #define MEAR 0x08 | ||
327 | #define PTSCR 0x0c | ||
328 | #define ISR 0x10 | ||
329 | #define IMR 0x14 | ||
330 | #define IER 0x18 | ||
331 | #define IHR 0x1c | ||
332 | #define TXDP 0x20 | ||
333 | #define TXDP_HI 0x24 | ||
334 | #define TXCFG 0x28 | ||
335 | #define GPIOR 0x2c | ||
336 | #define RXDP 0x30 | ||
337 | #define RXDP_HI 0x34 | ||
338 | #define RXCFG 0x38 | ||
339 | #define PQCR 0x3c | ||
340 | #define WCSR 0x40 | ||
341 | #define PCR 0x44 | ||
342 | #define RFCR 0x48 | ||
343 | #define RFDR 0x4c | ||
344 | |||
345 | #define SRR 0x58 | ||
346 | |||
347 | #define VRCR 0xbc | ||
348 | #define VTCR 0xc0 | ||
349 | #define VDR 0xc4 | ||
350 | #define CCSR 0xcc | ||
351 | |||
352 | #define TBICR 0xe0 | ||
353 | #define TBISR 0xe4 | ||
354 | #define TANAR 0xe8 | ||
355 | #define TANLPAR 0xec | ||
356 | #define TANER 0xf0 | ||
357 | #define TESR 0xf4 | ||
358 | |||
359 | #define TBICR_MR_AN_ENABLE 0x00001000 | ||
360 | #define TBICR_MR_RESTART_AN 0x00000200 | ||
361 | |||
362 | #define TBISR_MR_LINK_STATUS 0x00000020 | ||
363 | #define TBISR_MR_AN_COMPLETE 0x00000004 | ||
364 | |||
365 | #define TANAR_PS2 0x00000100 | ||
366 | #define TANAR_PS1 0x00000080 | ||
367 | #define TANAR_HALF_DUP 0x00000040 | ||
368 | #define TANAR_FULL_DUP 0x00000020 | ||
369 | |||
370 | #define GPIOR_GP5_OE 0x00000200 | ||
371 | #define GPIOR_GP4_OE 0x00000100 | ||
372 | #define GPIOR_GP3_OE 0x00000080 | ||
373 | #define GPIOR_GP2_OE 0x00000040 | ||
374 | #define GPIOR_GP1_OE 0x00000020 | ||
375 | #define GPIOR_GP3_OUT 0x00000004 | ||
376 | #define GPIOR_GP1_OUT 0x00000001 | ||
377 | |||
378 | #define LINK_AUTONEGOTIATE 0x01 | ||
379 | #define LINK_DOWN 0x02 | ||
380 | #define LINK_UP 0x04 | ||
381 | |||
382 | #define HW_ADDR_LEN sizeof(dma_addr_t) | ||
383 | #define desc_addr_set(desc, addr) \ | ||
384 | do { \ | ||
385 | ((desc)[0] = cpu_to_le32(addr)); \ | ||
386 | if (HW_ADDR_LEN == 8) \ | ||
387 | (desc)[1] = cpu_to_le32(((u64)addr) >> 32); \ | ||
388 | } while(0) | ||
389 | #define desc_addr_get(desc) \ | ||
390 | (le32_to_cpu((desc)[0]) | \ | ||
391 | (HW_ADDR_LEN == 8 ? ((dma_addr_t)le32_to_cpu((desc)[1]))<<32 : 0)) | ||
392 | |||
393 | #define DESC_LINK 0 | ||
394 | #define DESC_BUFPTR (DESC_LINK + HW_ADDR_LEN/4) | ||
395 | #define DESC_CMDSTS (DESC_BUFPTR + HW_ADDR_LEN/4) | ||
396 | #define DESC_EXTSTS (DESC_CMDSTS + 4/4) | ||
397 | |||
398 | #define CMDSTS_OWN 0x80000000 | ||
399 | #define CMDSTS_MORE 0x40000000 | ||
400 | #define CMDSTS_INTR 0x20000000 | ||
401 | #define CMDSTS_ERR 0x10000000 | ||
402 | #define CMDSTS_OK 0x08000000 | ||
403 | #define CMDSTS_RUNT 0x00200000 | ||
404 | #define CMDSTS_LEN_MASK 0x0000ffff | ||
405 | |||
406 | #define CMDSTS_DEST_MASK 0x01800000 | ||
407 | #define CMDSTS_DEST_SELF 0x00800000 | ||
408 | #define CMDSTS_DEST_MULTI 0x01000000 | ||
409 | |||
410 | #define DESC_SIZE 8 /* Should be cache line sized */ | ||
411 | |||
412 | struct rx_info { | ||
413 | spinlock_t lock; | ||
414 | int up; | ||
415 | unsigned long idle; | ||
416 | |||
417 | struct sk_buff *skbs[NR_RX_DESC]; | ||
418 | |||
419 | __le32 *next_rx_desc; | ||
420 | u16 next_rx, next_empty; | ||
421 | |||
422 | __le32 *descs; | ||
423 | dma_addr_t phy_descs; | ||
424 | }; | ||
425 | |||
426 | |||
427 | struct ns83820 { | ||
428 | u8 __iomem *base; | ||
429 | |||
430 | struct pci_dev *pci_dev; | ||
431 | struct net_device *ndev; | ||
432 | |||
433 | struct rx_info rx_info; | ||
434 | struct tasklet_struct rx_tasklet; | ||
435 | |||
436 | unsigned ihr; | ||
437 | struct work_struct tq_refill; | ||
438 | |||
439 | /* protects everything below. irqsave when using. */ | ||
440 | spinlock_t misc_lock; | ||
441 | |||
442 | u32 CFG_cache; | ||
443 | |||
444 | u32 MEAR_cache; | ||
445 | u32 IMR_cache; | ||
446 | |||
447 | unsigned linkstate; | ||
448 | |||
449 | spinlock_t tx_lock; | ||
450 | |||
451 | u16 tx_done_idx; | ||
452 | u16 tx_idx; | ||
453 | volatile u16 tx_free_idx; /* idx of free desc chain */ | ||
454 | u16 tx_intr_idx; | ||
455 | |||
456 | atomic_t nr_tx_skbs; | ||
457 | struct sk_buff *tx_skbs[NR_TX_DESC]; | ||
458 | |||
459 | char pad[16] __attribute__((aligned(16))); | ||
460 | __le32 *tx_descs; | ||
461 | dma_addr_t tx_phy_descs; | ||
462 | |||
463 | struct timer_list tx_watchdog; | ||
464 | }; | ||
465 | |||
466 | static inline struct ns83820 *PRIV(struct net_device *dev) | ||
467 | { | ||
468 | return netdev_priv(dev); | ||
469 | } | ||
470 | |||
471 | #define __kick_rx(dev) writel(CR_RXE, dev->base + CR) | ||
472 | |||
473 | static inline void kick_rx(struct net_device *ndev) | ||
474 | { | ||
475 | struct ns83820 *dev = PRIV(ndev); | ||
476 | dprintk("kick_rx: maybe kicking\n"); | ||
477 | if (test_and_clear_bit(0, &dev->rx_info.idle)) { | ||
478 | dprintk("actually kicking\n"); | ||
479 | writel(dev->rx_info.phy_descs + | ||
480 | (4 * DESC_SIZE * dev->rx_info.next_rx), | ||
481 | dev->base + RXDP); | ||
482 | if (dev->rx_info.next_rx == dev->rx_info.next_empty) | ||
483 | printk(KERN_DEBUG "%s: uh-oh: next_rx == next_empty???\n", | ||
484 | ndev->name); | ||
485 | __kick_rx(dev); | ||
486 | } | ||
487 | } | ||
488 | |||
489 | //free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC | ||
490 | #define start_tx_okay(dev) \ | ||
491 | (((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE) | ||
492 | |||
493 | /* Packet Receiver | ||
494 | * | ||
495 | * The hardware supports linked lists of receive descriptors for | ||
496 | * which ownership is transferred back and forth by means of an | ||
497 | * ownership bit. While the hardware does support the use of a | ||
498 | * ring for receive descriptors, we only make use of a chain in | ||
499 | * an attempt to reduce bus traffic under heavy load scenarios. | ||
500 | * This will also make bugs a bit more obvious. The current code | ||
501 | * only makes use of a single rx chain; I hope to implement | ||
502 | * priority based rx for version 1.0. Goal: even under overload | ||
503 | * conditions, still route realtime traffic with as low jitter as | ||
504 | * possible. | ||
505 | */ | ||
506 | static inline void build_rx_desc(struct ns83820 *dev, __le32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts) | ||
507 | { | ||
508 | desc_addr_set(desc + DESC_LINK, link); | ||
509 | desc_addr_set(desc + DESC_BUFPTR, buf); | ||
510 | desc[DESC_EXTSTS] = cpu_to_le32(extsts); | ||
511 | mb(); | ||
512 | desc[DESC_CMDSTS] = cpu_to_le32(cmdsts); | ||
513 | } | ||
514 | |||
515 | #define nr_rx_empty(dev) ((NR_RX_DESC-2 + dev->rx_info.next_rx - dev->rx_info.next_empty) % NR_RX_DESC) | ||
516 | static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) | ||
517 | { | ||
518 | unsigned next_empty; | ||
519 | u32 cmdsts; | ||
520 | __le32 *sg; | ||
521 | dma_addr_t buf; | ||
522 | |||
523 | next_empty = dev->rx_info.next_empty; | ||
524 | |||
525 | /* don't overrun last rx marker */ | ||
526 | if (unlikely(nr_rx_empty(dev) <= 2)) { | ||
527 | kfree_skb(skb); | ||
528 | return 1; | ||
529 | } | ||
530 | |||
531 | #if 0 | ||
532 | dprintk("next_empty[%d] nr_used[%d] next_rx[%d]\n", | ||
533 | dev->rx_info.next_empty, | ||
534 | dev->rx_info.nr_used, | ||
535 | dev->rx_info.next_rx | ||
536 | ); | ||
537 | #endif | ||
538 | |||
539 | sg = dev->rx_info.descs + (next_empty * DESC_SIZE); | ||
540 | BUG_ON(NULL != dev->rx_info.skbs[next_empty]); | ||
541 | dev->rx_info.skbs[next_empty] = skb; | ||
542 | |||
543 | dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; | ||
544 | cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR; | ||
545 | buf = pci_map_single(dev->pci_dev, skb->data, | ||
546 | REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | ||
547 | build_rx_desc(dev, sg, 0, buf, cmdsts, 0); | ||
548 | /* update link of previous rx */ | ||
549 | if (likely(next_empty != dev->rx_info.next_rx)) | ||
550 | dev->rx_info.descs[((NR_RX_DESC + next_empty - 1) % NR_RX_DESC) * DESC_SIZE] = cpu_to_le32(dev->rx_info.phy_descs + (next_empty * DESC_SIZE * 4)); | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static inline int rx_refill(struct net_device *ndev, gfp_t gfp) | ||
556 | { | ||
557 | struct ns83820 *dev = PRIV(ndev); | ||
558 | unsigned i; | ||
559 | unsigned long flags = 0; | ||
560 | |||
561 | if (unlikely(nr_rx_empty(dev) <= 2)) | ||
562 | return 0; | ||
563 | |||
564 | dprintk("rx_refill(%p)\n", ndev); | ||
565 | if (gfp == GFP_ATOMIC) | ||
566 | spin_lock_irqsave(&dev->rx_info.lock, flags); | ||
567 | for (i=0; i<NR_RX_DESC; i++) { | ||
568 | struct sk_buff *skb; | ||
569 | long res; | ||
570 | |||
571 | /* extra 16 bytes for alignment */ | ||
572 | skb = __netdev_alloc_skb(ndev, REAL_RX_BUF_SIZE+16, gfp); | ||
573 | if (unlikely(!skb)) | ||
574 | break; | ||
575 | |||
576 | skb_reserve(skb, skb->data - PTR_ALIGN(skb->data, 16)); | ||
577 | if (gfp != GFP_ATOMIC) | ||
578 | spin_lock_irqsave(&dev->rx_info.lock, flags); | ||
579 | res = ns83820_add_rx_skb(dev, skb); | ||
580 | if (gfp != GFP_ATOMIC) | ||
581 | spin_unlock_irqrestore(&dev->rx_info.lock, flags); | ||
582 | if (res) { | ||
583 | i = 1; | ||
584 | break; | ||
585 | } | ||
586 | } | ||
587 | if (gfp == GFP_ATOMIC) | ||
588 | spin_unlock_irqrestore(&dev->rx_info.lock, flags); | ||
589 | |||
590 | return i ? 0 : -ENOMEM; | ||
591 | } | ||
592 | |||
593 | static void rx_refill_atomic(struct net_device *ndev) | ||
594 | { | ||
595 | rx_refill(ndev, GFP_ATOMIC); | ||
596 | } | ||
597 | |||
598 | /* REFILL */ | ||
599 | static inline void queue_refill(struct work_struct *work) | ||
600 | { | ||
601 | struct ns83820 *dev = container_of(work, struct ns83820, tq_refill); | ||
602 | struct net_device *ndev = dev->ndev; | ||
603 | |||
604 | rx_refill(ndev, GFP_KERNEL); | ||
605 | if (dev->rx_info.up) | ||
606 | kick_rx(ndev); | ||
607 | } | ||
608 | |||
609 | static inline void clear_rx_desc(struct ns83820 *dev, unsigned i) | ||
610 | { | ||
611 | build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0); | ||
612 | } | ||
613 | |||
614 | static void phy_intr(struct net_device *ndev) | ||
615 | { | ||
616 | struct ns83820 *dev = PRIV(ndev); | ||
617 | static const char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" }; | ||
618 | u32 cfg, new_cfg; | ||
619 | u32 tbisr, tanar, tanlpar; | ||
620 | int speed, fullduplex, newlinkstate; | ||
621 | |||
622 | cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; | ||
623 | |||
624 | if (dev->CFG_cache & CFG_TBI_EN) { | ||
625 | /* we have an optical transceiver */ | ||
626 | tbisr = readl(dev->base + TBISR); | ||
627 | tanar = readl(dev->base + TANAR); | ||
628 | tanlpar = readl(dev->base + TANLPAR); | ||
629 | dprintk("phy_intr: tbisr=%08x, tanar=%08x, tanlpar=%08x\n", | ||
630 | tbisr, tanar, tanlpar); | ||
631 | |||
632 | if ( (fullduplex = (tanlpar & TANAR_FULL_DUP) && | ||
633 | (tanar & TANAR_FULL_DUP)) ) { | ||
634 | |||
635 | /* both of us are full duplex */ | ||
636 | writel(readl(dev->base + TXCFG) | ||
637 | | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP, | ||
638 | dev->base + TXCFG); | ||
639 | writel(readl(dev->base + RXCFG) | RXCFG_RX_FD, | ||
640 | dev->base + RXCFG); | ||
641 | /* Light up full duplex LED */ | ||
642 | writel(readl(dev->base + GPIOR) | GPIOR_GP1_OUT, | ||
643 | dev->base + GPIOR); | ||
644 | |||
645 | } else if (((tanlpar & TANAR_HALF_DUP) && | ||
646 | (tanar & TANAR_HALF_DUP)) || | ||
647 | ((tanlpar & TANAR_FULL_DUP) && | ||
648 | (tanar & TANAR_HALF_DUP)) || | ||
649 | ((tanlpar & TANAR_HALF_DUP) && | ||
650 | (tanar & TANAR_FULL_DUP))) { | ||
651 | |||
652 | /* one or both of us are half duplex */ | ||
653 | writel((readl(dev->base + TXCFG) | ||
654 | & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP, | ||
655 | dev->base + TXCFG); | ||
656 | writel(readl(dev->base + RXCFG) & ~RXCFG_RX_FD, | ||
657 | dev->base + RXCFG); | ||
658 | /* Turn off full duplex LED */ | ||
659 | writel(readl(dev->base + GPIOR) & ~GPIOR_GP1_OUT, | ||
660 | dev->base + GPIOR); | ||
661 | } | ||
662 | |||
663 | speed = 4; /* 1000F */ | ||
664 | |||
665 | } else { | ||
666 | /* we have a copper transceiver */ | ||
667 | new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS); | ||
668 | |||
669 | if (cfg & CFG_SPDSTS1) | ||
670 | new_cfg |= CFG_MODE_1000; | ||
671 | else | ||
672 | new_cfg &= ~CFG_MODE_1000; | ||
673 | |||
674 | speed = ((cfg / CFG_SPDSTS0) & 3); | ||
675 | fullduplex = (cfg & CFG_DUPSTS); | ||
676 | |||
677 | if (fullduplex) { | ||
678 | new_cfg |= CFG_SB; | ||
679 | writel(readl(dev->base + TXCFG) | ||
680 | | TXCFG_CSI | TXCFG_HBI, | ||
681 | dev->base + TXCFG); | ||
682 | writel(readl(dev->base + RXCFG) | RXCFG_RX_FD, | ||
683 | dev->base + RXCFG); | ||
684 | } else { | ||
685 | writel(readl(dev->base + TXCFG) | ||
686 | & ~(TXCFG_CSI | TXCFG_HBI), | ||
687 | dev->base + TXCFG); | ||
688 | writel(readl(dev->base + RXCFG) & ~(RXCFG_RX_FD), | ||
689 | dev->base + RXCFG); | ||
690 | } | ||
691 | |||
692 | if ((cfg & CFG_LNKSTS) && | ||
693 | ((new_cfg ^ dev->CFG_cache) != 0)) { | ||
694 | writel(new_cfg, dev->base + CFG); | ||
695 | dev->CFG_cache = new_cfg; | ||
696 | } | ||
697 | |||
698 | dev->CFG_cache &= ~CFG_SPDSTS; | ||
699 | dev->CFG_cache |= cfg & CFG_SPDSTS; | ||
700 | } | ||
701 | |||
702 | newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN; | ||
703 | |||
704 | if (newlinkstate & LINK_UP && | ||
705 | dev->linkstate != newlinkstate) { | ||
706 | netif_start_queue(ndev); | ||
707 | netif_wake_queue(ndev); | ||
708 | printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n", | ||
709 | ndev->name, | ||
710 | speeds[speed], | ||
711 | fullduplex ? "full" : "half"); | ||
712 | } else if (newlinkstate & LINK_DOWN && | ||
713 | dev->linkstate != newlinkstate) { | ||
714 | netif_stop_queue(ndev); | ||
715 | printk(KERN_INFO "%s: link now down.\n", ndev->name); | ||
716 | } | ||
717 | |||
718 | dev->linkstate = newlinkstate; | ||
719 | } | ||
720 | |||
721 | static int ns83820_setup_rx(struct net_device *ndev) | ||
722 | { | ||
723 | struct ns83820 *dev = PRIV(ndev); | ||
724 | unsigned i; | ||
725 | int ret; | ||
726 | |||
727 | dprintk("ns83820_setup_rx(%p)\n", ndev); | ||
728 | |||
729 | dev->rx_info.idle = 1; | ||
730 | dev->rx_info.next_rx = 0; | ||
731 | dev->rx_info.next_rx_desc = dev->rx_info.descs; | ||
732 | dev->rx_info.next_empty = 0; | ||
733 | |||
734 | for (i=0; i<NR_RX_DESC; i++) | ||
735 | clear_rx_desc(dev, i); | ||
736 | |||
737 | writel(0, dev->base + RXDP_HI); | ||
738 | writel(dev->rx_info.phy_descs, dev->base + RXDP); | ||
739 | |||
740 | ret = rx_refill(ndev, GFP_KERNEL); | ||
741 | if (!ret) { | ||
742 | dprintk("starting receiver\n"); | ||
743 | /* prevent the interrupt handler from stomping on us */ | ||
744 | spin_lock_irq(&dev->rx_info.lock); | ||
745 | |||
746 | writel(0x0001, dev->base + CCSR); | ||
747 | writel(0, dev->base + RFCR); | ||
748 | writel(0x7fc00000, dev->base + RFCR); | ||
749 | writel(0xffc00000, dev->base + RFCR); | ||
750 | |||
751 | dev->rx_info.up = 1; | ||
752 | |||
753 | phy_intr(ndev); | ||
754 | |||
755 | /* Okay, let it rip */ | ||
756 | spin_lock(&dev->misc_lock); | ||
757 | dev->IMR_cache |= ISR_PHY; | ||
758 | dev->IMR_cache |= ISR_RXRCMP; | ||
759 | //dev->IMR_cache |= ISR_RXERR; | ||
760 | //dev->IMR_cache |= ISR_RXOK; | ||
761 | dev->IMR_cache |= ISR_RXORN; | ||
762 | dev->IMR_cache |= ISR_RXSOVR; | ||
763 | dev->IMR_cache |= ISR_RXDESC; | ||
764 | dev->IMR_cache |= ISR_RXIDLE; | ||
765 | dev->IMR_cache |= ISR_TXDESC; | ||
766 | dev->IMR_cache |= ISR_TXIDLE; | ||
767 | |||
768 | writel(dev->IMR_cache, dev->base + IMR); | ||
769 | writel(1, dev->base + IER); | ||
770 | spin_unlock(&dev->misc_lock); | ||
771 | |||
772 | kick_rx(ndev); | ||
773 | |||
774 | spin_unlock_irq(&dev->rx_info.lock); | ||
775 | } | ||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | static void ns83820_cleanup_rx(struct ns83820 *dev) | ||
780 | { | ||
781 | unsigned i; | ||
782 | unsigned long flags; | ||
783 | |||
784 | dprintk("ns83820_cleanup_rx(%p)\n", dev); | ||
785 | |||
786 | /* disable receive interrupts */ | ||
787 | spin_lock_irqsave(&dev->misc_lock, flags); | ||
788 | dev->IMR_cache &= ~(ISR_RXOK | ISR_RXDESC | ISR_RXERR | ISR_RXEARLY | ISR_RXIDLE); | ||
789 | writel(dev->IMR_cache, dev->base + IMR); | ||
790 | spin_unlock_irqrestore(&dev->misc_lock, flags); | ||
791 | |||
792 | /* synchronize with the interrupt handler and kill it */ | ||
793 | dev->rx_info.up = 0; | ||
794 | synchronize_irq(dev->pci_dev->irq); | ||
795 | |||
796 | /* touch the pci bus... */ | ||
797 | readl(dev->base + IMR); | ||
798 | |||
799 | /* assumes the transmitter is already disabled and reset */ | ||
800 | writel(0, dev->base + RXDP_HI); | ||
801 | writel(0, dev->base + RXDP); | ||
802 | |||
803 | for (i=0; i<NR_RX_DESC; i++) { | ||
804 | struct sk_buff *skb = dev->rx_info.skbs[i]; | ||
805 | dev->rx_info.skbs[i] = NULL; | ||
806 | clear_rx_desc(dev, i); | ||
807 | kfree_skb(skb); | ||
808 | } | ||
809 | } | ||
810 | |||
811 | static void ns83820_rx_kick(struct net_device *ndev) | ||
812 | { | ||
813 | struct ns83820 *dev = PRIV(ndev); | ||
814 | /*if (nr_rx_empty(dev) >= NR_RX_DESC/4)*/ { | ||
815 | if (dev->rx_info.up) { | ||
816 | rx_refill_atomic(ndev); | ||
817 | kick_rx(ndev); | ||
818 | } | ||
819 | } | ||
820 | |||
821 | if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4) | ||
822 | schedule_work(&dev->tq_refill); | ||
823 | else | ||
824 | kick_rx(ndev); | ||
825 | if (dev->rx_info.idle) | ||
826 | printk(KERN_DEBUG "%s: BAD\n", ndev->name); | ||
827 | } | ||
828 | |||
829 | /* rx_irq | ||
830 | * | ||
831 | */ | ||
832 | static void rx_irq(struct net_device *ndev) | ||
833 | { | ||
834 | struct ns83820 *dev = PRIV(ndev); | ||
835 | struct rx_info *info = &dev->rx_info; | ||
836 | unsigned next_rx; | ||
837 | int rx_rc, len; | ||
838 | u32 cmdsts; | ||
839 | __le32 *desc; | ||
840 | unsigned long flags; | ||
841 | int nr = 0; | ||
842 | |||
843 | dprintk("rx_irq(%p)\n", ndev); | ||
844 | dprintk("rxdp: %08x, descs: %08lx next_rx[%d]: %p next_empty[%d]: %p\n", | ||
845 | readl(dev->base + RXDP), | ||
846 | (long)(dev->rx_info.phy_descs), | ||
847 | (int)dev->rx_info.next_rx, | ||
848 | (dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_rx)), | ||
849 | (int)dev->rx_info.next_empty, | ||
850 | (dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_empty)) | ||
851 | ); | ||
852 | |||
853 | spin_lock_irqsave(&info->lock, flags); | ||
854 | if (!info->up) | ||
855 | goto out; | ||
856 | |||
857 | dprintk("walking descs\n"); | ||
858 | next_rx = info->next_rx; | ||
859 | desc = info->next_rx_desc; | ||
860 | while ((CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[DESC_CMDSTS]))) && | ||
861 | (cmdsts != CMDSTS_OWN)) { | ||
862 | struct sk_buff *skb; | ||
863 | u32 extsts = le32_to_cpu(desc[DESC_EXTSTS]); | ||
864 | dma_addr_t bufptr = desc_addr_get(desc + DESC_BUFPTR); | ||
865 | |||
866 | dprintk("cmdsts: %08x\n", cmdsts); | ||
867 | dprintk("link: %08x\n", cpu_to_le32(desc[DESC_LINK])); | ||
868 | dprintk("extsts: %08x\n", extsts); | ||
869 | |||
870 | skb = info->skbs[next_rx]; | ||
871 | info->skbs[next_rx] = NULL; | ||
872 | info->next_rx = (next_rx + 1) % NR_RX_DESC; | ||
873 | |||
874 | mb(); | ||
875 | clear_rx_desc(dev, next_rx); | ||
876 | |||
877 | pci_unmap_single(dev->pci_dev, bufptr, | ||
878 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | ||
879 | len = cmdsts & CMDSTS_LEN_MASK; | ||
880 | #ifdef NS83820_VLAN_ACCEL_SUPPORT | ||
881 | /* NH: As was mentioned below, this chip is kinda | ||
882 | * brain dead about vlan tag stripping. Frames | ||
883 | * that are 64 bytes with a vlan header appended | ||
884 | * like arp frames, or pings, are flagged as Runts | ||
885 | * when the tag is stripped and hardware. This | ||
886 | * also means that the OK bit in the descriptor | ||
887 | * is cleared when the frame comes in so we have | ||
888 | * to do a specific length check here to make sure | ||
889 | * the frame would have been ok, had we not stripped | ||
890 | * the tag. | ||
891 | */ | ||
892 | if (likely((CMDSTS_OK & cmdsts) || | ||
893 | ((cmdsts & CMDSTS_RUNT) && len >= 56))) { | ||
894 | #else | ||
895 | if (likely(CMDSTS_OK & cmdsts)) { | ||
896 | #endif | ||
897 | skb_put(skb, len); | ||
898 | if (unlikely(!skb)) | ||
899 | goto netdev_mangle_me_harder_failed; | ||
900 | if (cmdsts & CMDSTS_DEST_MULTI) | ||
901 | ndev->stats.multicast++; | ||
902 | ndev->stats.rx_packets++; | ||
903 | ndev->stats.rx_bytes += len; | ||
904 | if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) { | ||
905 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
906 | } else { | ||
907 | skb_checksum_none_assert(skb); | ||
908 | } | ||
909 | skb->protocol = eth_type_trans(skb, ndev); | ||
910 | #ifdef NS83820_VLAN_ACCEL_SUPPORT | ||
911 | if(extsts & EXTSTS_VPKT) { | ||
912 | unsigned short tag; | ||
913 | |||
914 | tag = ntohs(extsts & EXTSTS_VTG_MASK); | ||
915 | __vlan_hwaccel_put_tag(skb, tag); | ||
916 | } | ||
917 | #endif | ||
918 | rx_rc = netif_rx(skb); | ||
919 | if (NET_RX_DROP == rx_rc) { | ||
920 | netdev_mangle_me_harder_failed: | ||
921 | ndev->stats.rx_dropped++; | ||
922 | } | ||
923 | } else { | ||
924 | kfree_skb(skb); | ||
925 | } | ||
926 | |||
927 | nr++; | ||
928 | next_rx = info->next_rx; | ||
929 | desc = info->descs + (DESC_SIZE * next_rx); | ||
930 | } | ||
931 | info->next_rx = next_rx; | ||
932 | info->next_rx_desc = info->descs + (DESC_SIZE * next_rx); | ||
933 | |||
934 | out: | ||
935 | if (0 && !nr) { | ||
936 | Dprintk("dazed: cmdsts_f: %08x\n", cmdsts); | ||
937 | } | ||
938 | |||
939 | spin_unlock_irqrestore(&info->lock, flags); | ||
940 | } | ||
941 | |||
942 | static void rx_action(unsigned long _dev) | ||
943 | { | ||
944 | struct net_device *ndev = (void *)_dev; | ||
945 | struct ns83820 *dev = PRIV(ndev); | ||
946 | rx_irq(ndev); | ||
947 | writel(ihr, dev->base + IHR); | ||
948 | |||
949 | spin_lock_irq(&dev->misc_lock); | ||
950 | dev->IMR_cache |= ISR_RXDESC; | ||
951 | writel(dev->IMR_cache, dev->base + IMR); | ||
952 | spin_unlock_irq(&dev->misc_lock); | ||
953 | |||
954 | rx_irq(ndev); | ||
955 | ns83820_rx_kick(ndev); | ||
956 | } | ||
957 | |||
958 | /* Packet Transmit code | ||
959 | */ | ||
960 | static inline void kick_tx(struct ns83820 *dev) | ||
961 | { | ||
962 | dprintk("kick_tx(%p): tx_idx=%d free_idx=%d\n", | ||
963 | dev, dev->tx_idx, dev->tx_free_idx); | ||
964 | writel(CR_TXE, dev->base + CR); | ||
965 | } | ||
966 | |||
967 | /* No spinlock needed on the transmit irq path as the interrupt handler is | ||
968 | * serialized. | ||
969 | */ | ||
970 | static void do_tx_done(struct net_device *ndev) | ||
971 | { | ||
972 | struct ns83820 *dev = PRIV(ndev); | ||
973 | u32 cmdsts, tx_done_idx; | ||
974 | __le32 *desc; | ||
975 | |||
976 | dprintk("do_tx_done(%p)\n", ndev); | ||
977 | tx_done_idx = dev->tx_done_idx; | ||
978 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); | ||
979 | |||
980 | dprintk("tx_done_idx=%d free_idx=%d cmdsts=%08x\n", | ||
981 | tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS])); | ||
982 | while ((tx_done_idx != dev->tx_free_idx) && | ||
983 | !(CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[DESC_CMDSTS]))) ) { | ||
984 | struct sk_buff *skb; | ||
985 | unsigned len; | ||
986 | dma_addr_t addr; | ||
987 | |||
988 | if (cmdsts & CMDSTS_ERR) | ||
989 | ndev->stats.tx_errors++; | ||
990 | if (cmdsts & CMDSTS_OK) | ||
991 | ndev->stats.tx_packets++; | ||
992 | if (cmdsts & CMDSTS_OK) | ||
993 | ndev->stats.tx_bytes += cmdsts & 0xffff; | ||
994 | |||
995 | dprintk("tx_done_idx=%d free_idx=%d cmdsts=%08x\n", | ||
996 | tx_done_idx, dev->tx_free_idx, cmdsts); | ||
997 | skb = dev->tx_skbs[tx_done_idx]; | ||
998 | dev->tx_skbs[tx_done_idx] = NULL; | ||
999 | dprintk("done(%p)\n", skb); | ||
1000 | |||
1001 | len = cmdsts & CMDSTS_LEN_MASK; | ||
1002 | addr = desc_addr_get(desc + DESC_BUFPTR); | ||
1003 | if (skb) { | ||
1004 | pci_unmap_single(dev->pci_dev, | ||
1005 | addr, | ||
1006 | len, | ||
1007 | PCI_DMA_TODEVICE); | ||
1008 | dev_kfree_skb_irq(skb); | ||
1009 | atomic_dec(&dev->nr_tx_skbs); | ||
1010 | } else | ||
1011 | pci_unmap_page(dev->pci_dev, | ||
1012 | addr, | ||
1013 | len, | ||
1014 | PCI_DMA_TODEVICE); | ||
1015 | |||
1016 | tx_done_idx = (tx_done_idx + 1) % NR_TX_DESC; | ||
1017 | dev->tx_done_idx = tx_done_idx; | ||
1018 | desc[DESC_CMDSTS] = cpu_to_le32(0); | ||
1019 | mb(); | ||
1020 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); | ||
1021 | } | ||
1022 | |||
1023 | /* Allow network stack to resume queueing packets after we've | ||
1024 | * finished transmitting at least 1/4 of the packets in the queue. | ||
1025 | */ | ||
1026 | if (netif_queue_stopped(ndev) && start_tx_okay(dev)) { | ||
1027 | dprintk("start_queue(%p)\n", ndev); | ||
1028 | netif_start_queue(ndev); | ||
1029 | netif_wake_queue(ndev); | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | static void ns83820_cleanup_tx(struct ns83820 *dev) | ||
1034 | { | ||
1035 | unsigned i; | ||
1036 | |||
1037 | for (i=0; i<NR_TX_DESC; i++) { | ||
1038 | struct sk_buff *skb = dev->tx_skbs[i]; | ||
1039 | dev->tx_skbs[i] = NULL; | ||
1040 | if (skb) { | ||
1041 | __le32 *desc = dev->tx_descs + (i * DESC_SIZE); | ||
1042 | pci_unmap_single(dev->pci_dev, | ||
1043 | desc_addr_get(desc + DESC_BUFPTR), | ||
1044 | le32_to_cpu(desc[DESC_CMDSTS]) & CMDSTS_LEN_MASK, | ||
1045 | PCI_DMA_TODEVICE); | ||
1046 | dev_kfree_skb_irq(skb); | ||
1047 | atomic_dec(&dev->nr_tx_skbs); | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | memset(dev->tx_descs, 0, NR_TX_DESC * DESC_SIZE * 4); | ||
1052 | } | ||
1053 | |||
1054 | /* transmit routine. This code relies on the network layer serializing | ||
1055 | * its calls in, but will run happily in parallel with the interrupt | ||
1056 | * handler. This code currently has provisions for fragmenting tx buffers | ||
1057 | * while trying to track down a bug in either the zero copy code or | ||
1058 | * the tx fifo (hence the MAX_FRAG_LEN). | ||
1059 | */ | ||
1060 | static netdev_tx_t ns83820_hard_start_xmit(struct sk_buff *skb, | ||
1061 | struct net_device *ndev) | ||
1062 | { | ||
1063 | struct ns83820 *dev = PRIV(ndev); | ||
1064 | u32 free_idx, cmdsts, extsts; | ||
1065 | int nr_free, nr_frags; | ||
1066 | unsigned tx_done_idx, last_idx; | ||
1067 | dma_addr_t buf; | ||
1068 | unsigned len; | ||
1069 | skb_frag_t *frag; | ||
1070 | int stopped = 0; | ||
1071 | int do_intr = 0; | ||
1072 | volatile __le32 *first_desc; | ||
1073 | |||
1074 | dprintk("ns83820_hard_start_xmit\n"); | ||
1075 | |||
1076 | nr_frags = skb_shinfo(skb)->nr_frags; | ||
1077 | again: | ||
1078 | if (unlikely(dev->CFG_cache & CFG_LNKSTS)) { | ||
1079 | netif_stop_queue(ndev); | ||
1080 | if (unlikely(dev->CFG_cache & CFG_LNKSTS)) | ||
1081 | return NETDEV_TX_BUSY; | ||
1082 | netif_start_queue(ndev); | ||
1083 | } | ||
1084 | |||
1085 | last_idx = free_idx = dev->tx_free_idx; | ||
1086 | tx_done_idx = dev->tx_done_idx; | ||
1087 | nr_free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC; | ||
1088 | nr_free -= 1; | ||
1089 | if (nr_free <= nr_frags) { | ||
1090 | dprintk("stop_queue - not enough(%p)\n", ndev); | ||
1091 | netif_stop_queue(ndev); | ||
1092 | |||
1093 | /* Check again: we may have raced with a tx done irq */ | ||
1094 | if (dev->tx_done_idx != tx_done_idx) { | ||
1095 | dprintk("restart queue(%p)\n", ndev); | ||
1096 | netif_start_queue(ndev); | ||
1097 | goto again; | ||
1098 | } | ||
1099 | return NETDEV_TX_BUSY; | ||
1100 | } | ||
1101 | |||
1102 | if (free_idx == dev->tx_intr_idx) { | ||
1103 | do_intr = 1; | ||
1104 | dev->tx_intr_idx = (dev->tx_intr_idx + NR_TX_DESC/4) % NR_TX_DESC; | ||
1105 | } | ||
1106 | |||
1107 | nr_free -= nr_frags; | ||
1108 | if (nr_free < MIN_TX_DESC_FREE) { | ||
1109 | dprintk("stop_queue - last entry(%p)\n", ndev); | ||
1110 | netif_stop_queue(ndev); | ||
1111 | stopped = 1; | ||
1112 | } | ||
1113 | |||
1114 | frag = skb_shinfo(skb)->frags; | ||
1115 | if (!nr_frags) | ||
1116 | frag = NULL; | ||
1117 | extsts = 0; | ||
1118 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
1119 | extsts |= EXTSTS_IPPKT; | ||
1120 | if (IPPROTO_TCP == ip_hdr(skb)->protocol) | ||
1121 | extsts |= EXTSTS_TCPPKT; | ||
1122 | else if (IPPROTO_UDP == ip_hdr(skb)->protocol) | ||
1123 | extsts |= EXTSTS_UDPPKT; | ||
1124 | } | ||
1125 | |||
1126 | #ifdef NS83820_VLAN_ACCEL_SUPPORT | ||
1127 | if(vlan_tx_tag_present(skb)) { | ||
1128 | /* fetch the vlan tag info out of the | ||
1129 | * ancillary data if the vlan code | ||
1130 | * is using hw vlan acceleration | ||
1131 | */ | ||
1132 | short tag = vlan_tx_tag_get(skb); | ||
1133 | extsts |= (EXTSTS_VPKT | htons(tag)); | ||
1134 | } | ||
1135 | #endif | ||
1136 | |||
1137 | len = skb->len; | ||
1138 | if (nr_frags) | ||
1139 | len -= skb->data_len; | ||
1140 | buf = pci_map_single(dev->pci_dev, skb->data, len, PCI_DMA_TODEVICE); | ||
1141 | |||
1142 | first_desc = dev->tx_descs + (free_idx * DESC_SIZE); | ||
1143 | |||
1144 | for (;;) { | ||
1145 | volatile __le32 *desc = dev->tx_descs + (free_idx * DESC_SIZE); | ||
1146 | |||
1147 | dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len, | ||
1148 | (unsigned long long)buf); | ||
1149 | last_idx = free_idx; | ||
1150 | free_idx = (free_idx + 1) % NR_TX_DESC; | ||
1151 | desc[DESC_LINK] = cpu_to_le32(dev->tx_phy_descs + (free_idx * DESC_SIZE * 4)); | ||
1152 | desc_addr_set(desc + DESC_BUFPTR, buf); | ||
1153 | desc[DESC_EXTSTS] = cpu_to_le32(extsts); | ||
1154 | |||
1155 | cmdsts = ((nr_frags) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0); | ||
1156 | cmdsts |= (desc == first_desc) ? 0 : CMDSTS_OWN; | ||
1157 | cmdsts |= len; | ||
1158 | desc[DESC_CMDSTS] = cpu_to_le32(cmdsts); | ||
1159 | |||
1160 | if (!nr_frags) | ||
1161 | break; | ||
1162 | |||
1163 | buf = pci_map_page(dev->pci_dev, frag->page, | ||
1164 | frag->page_offset, | ||
1165 | frag->size, PCI_DMA_TODEVICE); | ||
1166 | dprintk("frag: buf=%08Lx page=%08lx offset=%08lx\n", | ||
1167 | (long long)buf, (long) page_to_pfn(frag->page), | ||
1168 | frag->page_offset); | ||
1169 | len = frag->size; | ||
1170 | frag++; | ||
1171 | nr_frags--; | ||
1172 | } | ||
1173 | dprintk("done pkt\n"); | ||
1174 | |||
1175 | spin_lock_irq(&dev->tx_lock); | ||
1176 | dev->tx_skbs[last_idx] = skb; | ||
1177 | first_desc[DESC_CMDSTS] |= cpu_to_le32(CMDSTS_OWN); | ||
1178 | dev->tx_free_idx = free_idx; | ||
1179 | atomic_inc(&dev->nr_tx_skbs); | ||
1180 | spin_unlock_irq(&dev->tx_lock); | ||
1181 | |||
1182 | kick_tx(dev); | ||
1183 | |||
1184 | /* Check again: we may have raced with a tx done irq */ | ||
1185 | if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev)) | ||
1186 | netif_start_queue(ndev); | ||
1187 | |||
1188 | return NETDEV_TX_OK; | ||
1189 | } | ||
1190 | |||
1191 | static void ns83820_update_stats(struct ns83820 *dev) | ||
1192 | { | ||
1193 | struct net_device *ndev = dev->ndev; | ||
1194 | u8 __iomem *base = dev->base; | ||
1195 | |||
1196 | /* the DP83820 will freeze counters, so we need to read all of them */ | ||
1197 | ndev->stats.rx_errors += readl(base + 0x60) & 0xffff; | ||
1198 | ndev->stats.rx_crc_errors += readl(base + 0x64) & 0xffff; | ||
1199 | ndev->stats.rx_missed_errors += readl(base + 0x68) & 0xffff; | ||
1200 | ndev->stats.rx_frame_errors += readl(base + 0x6c) & 0xffff; | ||
1201 | /*ndev->stats.rx_symbol_errors +=*/ readl(base + 0x70); | ||
1202 | ndev->stats.rx_length_errors += readl(base + 0x74) & 0xffff; | ||
1203 | ndev->stats.rx_length_errors += readl(base + 0x78) & 0xffff; | ||
1204 | /*ndev->stats.rx_badopcode_errors += */ readl(base + 0x7c); | ||
1205 | /*ndev->stats.rx_pause_count += */ readl(base + 0x80); | ||
1206 | /*ndev->stats.tx_pause_count += */ readl(base + 0x84); | ||
1207 | ndev->stats.tx_carrier_errors += readl(base + 0x88) & 0xff; | ||
1208 | } | ||
1209 | |||
1210 | static struct net_device_stats *ns83820_get_stats(struct net_device *ndev) | ||
1211 | { | ||
1212 | struct ns83820 *dev = PRIV(ndev); | ||
1213 | |||
1214 | /* somewhat overkill */ | ||
1215 | spin_lock_irq(&dev->misc_lock); | ||
1216 | ns83820_update_stats(dev); | ||
1217 | spin_unlock_irq(&dev->misc_lock); | ||
1218 | |||
1219 | return &ndev->stats; | ||
1220 | } | ||
1221 | |||
1222 | /* Let ethtool retrieve info */ | ||
1223 | static int ns83820_get_settings(struct net_device *ndev, | ||
1224 | struct ethtool_cmd *cmd) | ||
1225 | { | ||
1226 | struct ns83820 *dev = PRIV(ndev); | ||
1227 | u32 cfg, tanar, tbicr; | ||
1228 | int fullduplex = 0; | ||
1229 | |||
1230 | /* | ||
1231 | * Here's the list of available ethtool commands from other drivers: | ||
1232 | * cmd->advertising = | ||
1233 | * ethtool_cmd_speed_set(cmd, ...) | ||
1234 | * cmd->duplex = | ||
1235 | * cmd->port = 0; | ||
1236 | * cmd->phy_address = | ||
1237 | * cmd->transceiver = 0; | ||
1238 | * cmd->autoneg = | ||
1239 | * cmd->maxtxpkt = 0; | ||
1240 | * cmd->maxrxpkt = 0; | ||
1241 | */ | ||
1242 | |||
1243 | /* read current configuration */ | ||
1244 | cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; | ||
1245 | tanar = readl(dev->base + TANAR); | ||
1246 | tbicr = readl(dev->base + TBICR); | ||
1247 | |||
1248 | fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; | ||
1249 | |||
1250 | cmd->supported = SUPPORTED_Autoneg; | ||
1251 | |||
1252 | if (dev->CFG_cache & CFG_TBI_EN) { | ||
1253 | /* we have optical interface */ | ||
1254 | cmd->supported |= SUPPORTED_1000baseT_Half | | ||
1255 | SUPPORTED_1000baseT_Full | | ||
1256 | SUPPORTED_FIBRE; | ||
1257 | cmd->port = PORT_FIBRE; | ||
1258 | } else { | ||
1259 | /* we have copper */ | ||
1260 | cmd->supported |= SUPPORTED_10baseT_Half | | ||
1261 | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | | ||
1262 | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | | ||
1263 | SUPPORTED_1000baseT_Full | | ||
1264 | SUPPORTED_MII; | ||
1265 | cmd->port = PORT_MII; | ||
1266 | } | ||
1267 | |||
1268 | cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF; | ||
1269 | switch (cfg / CFG_SPDSTS0 & 3) { | ||
1270 | case 2: | ||
1271 | ethtool_cmd_speed_set(cmd, SPEED_1000); | ||
1272 | break; | ||
1273 | case 1: | ||
1274 | ethtool_cmd_speed_set(cmd, SPEED_100); | ||
1275 | break; | ||
1276 | default: | ||
1277 | ethtool_cmd_speed_set(cmd, SPEED_10); | ||
1278 | break; | ||
1279 | } | ||
1280 | cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) | ||
1281 | ? AUTONEG_ENABLE : AUTONEG_DISABLE; | ||
1282 | return 0; | ||
1283 | } | ||
1284 | |||
1285 | /* Let ethool change settings*/ | ||
1286 | static int ns83820_set_settings(struct net_device *ndev, | ||
1287 | struct ethtool_cmd *cmd) | ||
1288 | { | ||
1289 | struct ns83820 *dev = PRIV(ndev); | ||
1290 | u32 cfg, tanar; | ||
1291 | int have_optical = 0; | ||
1292 | int fullduplex = 0; | ||
1293 | |||
1294 | /* read current configuration */ | ||
1295 | cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; | ||
1296 | tanar = readl(dev->base + TANAR); | ||
1297 | |||
1298 | if (dev->CFG_cache & CFG_TBI_EN) { | ||
1299 | /* we have optical */ | ||
1300 | have_optical = 1; | ||
1301 | fullduplex = (tanar & TANAR_FULL_DUP); | ||
1302 | |||
1303 | } else { | ||
1304 | /* we have copper */ | ||
1305 | fullduplex = cfg & CFG_DUPSTS; | ||
1306 | } | ||
1307 | |||
1308 | spin_lock_irq(&dev->misc_lock); | ||
1309 | spin_lock(&dev->tx_lock); | ||
1310 | |||
1311 | /* Set duplex */ | ||
1312 | if (cmd->duplex != fullduplex) { | ||
1313 | if (have_optical) { | ||
1314 | /*set full duplex*/ | ||
1315 | if (cmd->duplex == DUPLEX_FULL) { | ||
1316 | /* force full duplex */ | ||
1317 | writel(readl(dev->base + TXCFG) | ||
1318 | | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP, | ||
1319 | dev->base + TXCFG); | ||
1320 | writel(readl(dev->base + RXCFG) | RXCFG_RX_FD, | ||
1321 | dev->base + RXCFG); | ||
1322 | /* Light up full duplex LED */ | ||
1323 | writel(readl(dev->base + GPIOR) | GPIOR_GP1_OUT, | ||
1324 | dev->base + GPIOR); | ||
1325 | } else { | ||
1326 | /*TODO: set half duplex */ | ||
1327 | } | ||
1328 | |||
1329 | } else { | ||
1330 | /*we have copper*/ | ||
1331 | /* TODO: Set duplex for copper cards */ | ||
1332 | } | ||
1333 | printk(KERN_INFO "%s: Duplex set via ethtool\n", | ||
1334 | ndev->name); | ||
1335 | } | ||
1336 | |||
1337 | /* Set autonegotiation */ | ||
1338 | if (1) { | ||
1339 | if (cmd->autoneg == AUTONEG_ENABLE) { | ||
1340 | /* restart auto negotiation */ | ||
1341 | writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN, | ||
1342 | dev->base + TBICR); | ||
1343 | writel(TBICR_MR_AN_ENABLE, dev->base + TBICR); | ||
1344 | dev->linkstate = LINK_AUTONEGOTIATE; | ||
1345 | |||
1346 | printk(KERN_INFO "%s: autoneg enabled via ethtool\n", | ||
1347 | ndev->name); | ||
1348 | } else { | ||
1349 | /* disable auto negotiation */ | ||
1350 | writel(0x00000000, dev->base + TBICR); | ||
1351 | } | ||
1352 | |||
1353 | printk(KERN_INFO "%s: autoneg %s via ethtool\n", ndev->name, | ||
1354 | cmd->autoneg ? "ENABLED" : "DISABLED"); | ||
1355 | } | ||
1356 | |||
1357 | phy_intr(ndev); | ||
1358 | spin_unlock(&dev->tx_lock); | ||
1359 | spin_unlock_irq(&dev->misc_lock); | ||
1360 | |||
1361 | return 0; | ||
1362 | } | ||
1363 | /* end ethtool get/set support -df */ | ||
1364 | |||
1365 | static void ns83820_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) | ||
1366 | { | ||
1367 | struct ns83820 *dev = PRIV(ndev); | ||
1368 | strcpy(info->driver, "ns83820"); | ||
1369 | strcpy(info->version, VERSION); | ||
1370 | strcpy(info->bus_info, pci_name(dev->pci_dev)); | ||
1371 | } | ||
1372 | |||
1373 | static u32 ns83820_get_link(struct net_device *ndev) | ||
1374 | { | ||
1375 | struct ns83820 *dev = PRIV(ndev); | ||
1376 | u32 cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY; | ||
1377 | return cfg & CFG_LNKSTS ? 1 : 0; | ||
1378 | } | ||
1379 | |||
1380 | static const struct ethtool_ops ops = { | ||
1381 | .get_settings = ns83820_get_settings, | ||
1382 | .set_settings = ns83820_set_settings, | ||
1383 | .get_drvinfo = ns83820_get_drvinfo, | ||
1384 | .get_link = ns83820_get_link | ||
1385 | }; | ||
1386 | |||
1387 | static inline void ns83820_disable_interrupts(struct ns83820 *dev) | ||
1388 | { | ||
1389 | writel(0, dev->base + IMR); | ||
1390 | writel(0, dev->base + IER); | ||
1391 | readl(dev->base + IER); | ||
1392 | } | ||
1393 | |||
1394 | /* this function is called in irq context from the ISR */ | ||
1395 | static void ns83820_mib_isr(struct ns83820 *dev) | ||
1396 | { | ||
1397 | unsigned long flags; | ||
1398 | spin_lock_irqsave(&dev->misc_lock, flags); | ||
1399 | ns83820_update_stats(dev); | ||
1400 | spin_unlock_irqrestore(&dev->misc_lock, flags); | ||
1401 | } | ||
1402 | |||
1403 | static void ns83820_do_isr(struct net_device *ndev, u32 isr); | ||
1404 | static irqreturn_t ns83820_irq(int foo, void *data) | ||
1405 | { | ||
1406 | struct net_device *ndev = data; | ||
1407 | struct ns83820 *dev = PRIV(ndev); | ||
1408 | u32 isr; | ||
1409 | dprintk("ns83820_irq(%p)\n", ndev); | ||
1410 | |||
1411 | dev->ihr = 0; | ||
1412 | |||
1413 | isr = readl(dev->base + ISR); | ||
1414 | dprintk("irq: %08x\n", isr); | ||
1415 | ns83820_do_isr(ndev, isr); | ||
1416 | return IRQ_HANDLED; | ||
1417 | } | ||
1418 | |||
1419 | static void ns83820_do_isr(struct net_device *ndev, u32 isr) | ||
1420 | { | ||
1421 | struct ns83820 *dev = PRIV(ndev); | ||
1422 | unsigned long flags; | ||
1423 | |||
1424 | #ifdef DEBUG | ||
1425 | if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC)) | ||
1426 | Dprintk("odd isr? 0x%08x\n", isr); | ||
1427 | #endif | ||
1428 | |||
1429 | if (ISR_RXIDLE & isr) { | ||
1430 | dev->rx_info.idle = 1; | ||
1431 | Dprintk("oh dear, we are idle\n"); | ||
1432 | ns83820_rx_kick(ndev); | ||
1433 | } | ||
1434 | |||
1435 | if ((ISR_RXDESC | ISR_RXOK) & isr) { | ||
1436 | prefetch(dev->rx_info.next_rx_desc); | ||
1437 | |||
1438 | spin_lock_irqsave(&dev->misc_lock, flags); | ||
1439 | dev->IMR_cache &= ~(ISR_RXDESC | ISR_RXOK); | ||
1440 | writel(dev->IMR_cache, dev->base + IMR); | ||
1441 | spin_unlock_irqrestore(&dev->misc_lock, flags); | ||
1442 | |||
1443 | tasklet_schedule(&dev->rx_tasklet); | ||
1444 | //rx_irq(ndev); | ||
1445 | //writel(4, dev->base + IHR); | ||
1446 | } | ||
1447 | |||
1448 | if ((ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr) | ||
1449 | ns83820_rx_kick(ndev); | ||
1450 | |||
1451 | if (unlikely(ISR_RXSOVR & isr)) { | ||
1452 | //printk("overrun: rxsovr\n"); | ||
1453 | ndev->stats.rx_fifo_errors++; | ||
1454 | } | ||
1455 | |||
1456 | if (unlikely(ISR_RXORN & isr)) { | ||
1457 | //printk("overrun: rxorn\n"); | ||
1458 | ndev->stats.rx_fifo_errors++; | ||
1459 | } | ||
1460 | |||
1461 | if ((ISR_RXRCMP & isr) && dev->rx_info.up) | ||
1462 | writel(CR_RXE, dev->base + CR); | ||
1463 | |||
1464 | if (ISR_TXIDLE & isr) { | ||
1465 | u32 txdp; | ||
1466 | txdp = readl(dev->base + TXDP); | ||
1467 | dprintk("txdp: %08x\n", txdp); | ||
1468 | txdp -= dev->tx_phy_descs; | ||
1469 | dev->tx_idx = txdp / (DESC_SIZE * 4); | ||
1470 | if (dev->tx_idx >= NR_TX_DESC) { | ||
1471 | printk(KERN_ALERT "%s: BUG -- txdp out of range\n", ndev->name); | ||
1472 | dev->tx_idx = 0; | ||
1473 | } | ||
1474 | /* The may have been a race between a pci originated read | ||
1475 | * and the descriptor update from the cpu. Just in case, | ||
1476 | * kick the transmitter if the hardware thinks it is on a | ||
1477 | * different descriptor than we are. | ||
1478 | */ | ||
1479 | if (dev->tx_idx != dev->tx_free_idx) | ||
1480 | kick_tx(dev); | ||
1481 | } | ||
1482 | |||
1483 | /* Defer tx ring processing until more than a minimum amount of | ||
1484 | * work has accumulated | ||
1485 | */ | ||
1486 | if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) { | ||
1487 | spin_lock_irqsave(&dev->tx_lock, flags); | ||
1488 | do_tx_done(ndev); | ||
1489 | spin_unlock_irqrestore(&dev->tx_lock, flags); | ||
1490 | |||
1491 | /* Disable TxOk if there are no outstanding tx packets. | ||
1492 | */ | ||
1493 | if ((dev->tx_done_idx == dev->tx_free_idx) && | ||
1494 | (dev->IMR_cache & ISR_TXOK)) { | ||
1495 | spin_lock_irqsave(&dev->misc_lock, flags); | ||
1496 | dev->IMR_cache &= ~ISR_TXOK; | ||
1497 | writel(dev->IMR_cache, dev->base + IMR); | ||
1498 | spin_unlock_irqrestore(&dev->misc_lock, flags); | ||
1499 | } | ||
1500 | } | ||
1501 | |||
1502 | /* The TxIdle interrupt can come in before the transmit has | ||
1503 | * completed. Normally we reap packets off of the combination | ||
1504 | * of TxDesc and TxIdle and leave TxOk disabled (since it | ||
1505 | * occurs on every packet), but when no further irqs of this | ||
1506 | * nature are expected, we must enable TxOk. | ||
1507 | */ | ||
1508 | if ((ISR_TXIDLE & isr) && (dev->tx_done_idx != dev->tx_free_idx)) { | ||
1509 | spin_lock_irqsave(&dev->misc_lock, flags); | ||
1510 | dev->IMR_cache |= ISR_TXOK; | ||
1511 | writel(dev->IMR_cache, dev->base + IMR); | ||
1512 | spin_unlock_irqrestore(&dev->misc_lock, flags); | ||
1513 | } | ||
1514 | |||
1515 | /* MIB interrupt: one of the statistics counters is about to overflow */ | ||
1516 | if (unlikely(ISR_MIB & isr)) | ||
1517 | ns83820_mib_isr(dev); | ||
1518 | |||
1519 | /* PHY: Link up/down/negotiation state change */ | ||
1520 | if (unlikely(ISR_PHY & isr)) | ||
1521 | phy_intr(ndev); | ||
1522 | |||
1523 | #if 0 /* Still working on the interrupt mitigation strategy */ | ||
1524 | if (dev->ihr) | ||
1525 | writel(dev->ihr, dev->base + IHR); | ||
1526 | #endif | ||
1527 | } | ||
1528 | |||
1529 | static void ns83820_do_reset(struct ns83820 *dev, u32 which) | ||
1530 | { | ||
1531 | Dprintk("resetting chip...\n"); | ||
1532 | writel(which, dev->base + CR); | ||
1533 | do { | ||
1534 | schedule(); | ||
1535 | } while (readl(dev->base + CR) & which); | ||
1536 | Dprintk("okay!\n"); | ||
1537 | } | ||
1538 | |||
1539 | static int ns83820_stop(struct net_device *ndev) | ||
1540 | { | ||
1541 | struct ns83820 *dev = PRIV(ndev); | ||
1542 | |||
1543 | /* FIXME: protect against interrupt handler? */ | ||
1544 | del_timer_sync(&dev->tx_watchdog); | ||
1545 | |||
1546 | ns83820_disable_interrupts(dev); | ||
1547 | |||
1548 | dev->rx_info.up = 0; | ||
1549 | synchronize_irq(dev->pci_dev->irq); | ||
1550 | |||
1551 | ns83820_do_reset(dev, CR_RST); | ||
1552 | |||
1553 | synchronize_irq(dev->pci_dev->irq); | ||
1554 | |||
1555 | spin_lock_irq(&dev->misc_lock); | ||
1556 | dev->IMR_cache &= ~(ISR_TXURN | ISR_TXIDLE | ISR_TXERR | ISR_TXDESC | ISR_TXOK); | ||
1557 | spin_unlock_irq(&dev->misc_lock); | ||
1558 | |||
1559 | ns83820_cleanup_rx(dev); | ||
1560 | ns83820_cleanup_tx(dev); | ||
1561 | |||
1562 | return 0; | ||
1563 | } | ||
1564 | |||
1565 | static void ns83820_tx_timeout(struct net_device *ndev) | ||
1566 | { | ||
1567 | struct ns83820 *dev = PRIV(ndev); | ||
1568 | u32 tx_done_idx; | ||
1569 | __le32 *desc; | ||
1570 | unsigned long flags; | ||
1571 | |||
1572 | spin_lock_irqsave(&dev->tx_lock, flags); | ||
1573 | |||
1574 | tx_done_idx = dev->tx_done_idx; | ||
1575 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); | ||
1576 | |||
1577 | printk(KERN_INFO "%s: tx_timeout: tx_done_idx=%d free_idx=%d cmdsts=%08x\n", | ||
1578 | ndev->name, | ||
1579 | tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS])); | ||
1580 | |||
1581 | #if defined(DEBUG) | ||
1582 | { | ||
1583 | u32 isr; | ||
1584 | isr = readl(dev->base + ISR); | ||
1585 | printk("irq: %08x imr: %08x\n", isr, dev->IMR_cache); | ||
1586 | ns83820_do_isr(ndev, isr); | ||
1587 | } | ||
1588 | #endif | ||
1589 | |||
1590 | do_tx_done(ndev); | ||
1591 | |||
1592 | tx_done_idx = dev->tx_done_idx; | ||
1593 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); | ||
1594 | |||
1595 | printk(KERN_INFO "%s: after: tx_done_idx=%d free_idx=%d cmdsts=%08x\n", | ||
1596 | ndev->name, | ||
1597 | tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS])); | ||
1598 | |||
1599 | spin_unlock_irqrestore(&dev->tx_lock, flags); | ||
1600 | } | ||
1601 | |||
1602 | static void ns83820_tx_watch(unsigned long data) | ||
1603 | { | ||
1604 | struct net_device *ndev = (void *)data; | ||
1605 | struct ns83820 *dev = PRIV(ndev); | ||
1606 | |||
1607 | #if defined(DEBUG) | ||
1608 | printk("ns83820_tx_watch: %u %u %d\n", | ||
1609 | dev->tx_done_idx, dev->tx_free_idx, atomic_read(&dev->nr_tx_skbs) | ||
1610 | ); | ||
1611 | #endif | ||
1612 | |||
1613 | if (time_after(jiffies, dev_trans_start(ndev) + 1*HZ) && | ||
1614 | dev->tx_done_idx != dev->tx_free_idx) { | ||
1615 | printk(KERN_DEBUG "%s: ns83820_tx_watch: %u %u %d\n", | ||
1616 | ndev->name, | ||
1617 | dev->tx_done_idx, dev->tx_free_idx, | ||
1618 | atomic_read(&dev->nr_tx_skbs)); | ||
1619 | ns83820_tx_timeout(ndev); | ||
1620 | } | ||
1621 | |||
1622 | mod_timer(&dev->tx_watchdog, jiffies + 2*HZ); | ||
1623 | } | ||
1624 | |||
1625 | static int ns83820_open(struct net_device *ndev) | ||
1626 | { | ||
1627 | struct ns83820 *dev = PRIV(ndev); | ||
1628 | unsigned i; | ||
1629 | u32 desc; | ||
1630 | int ret; | ||
1631 | |||
1632 | dprintk("ns83820_open\n"); | ||
1633 | |||
1634 | writel(0, dev->base + PQCR); | ||
1635 | |||
1636 | ret = ns83820_setup_rx(ndev); | ||
1637 | if (ret) | ||
1638 | goto failed; | ||
1639 | |||
1640 | memset(dev->tx_descs, 0, 4 * NR_TX_DESC * DESC_SIZE); | ||
1641 | for (i=0; i<NR_TX_DESC; i++) { | ||
1642 | dev->tx_descs[(i * DESC_SIZE) + DESC_LINK] | ||
1643 | = cpu_to_le32( | ||
1644 | dev->tx_phy_descs | ||
1645 | + ((i+1) % NR_TX_DESC) * DESC_SIZE * 4); | ||
1646 | } | ||
1647 | |||
1648 | dev->tx_idx = 0; | ||
1649 | dev->tx_done_idx = 0; | ||
1650 | desc = dev->tx_phy_descs; | ||
1651 | writel(0, dev->base + TXDP_HI); | ||
1652 | writel(desc, dev->base + TXDP); | ||
1653 | |||
1654 | init_timer(&dev->tx_watchdog); | ||
1655 | dev->tx_watchdog.data = (unsigned long)ndev; | ||
1656 | dev->tx_watchdog.function = ns83820_tx_watch; | ||
1657 | mod_timer(&dev->tx_watchdog, jiffies + 2*HZ); | ||
1658 | |||
1659 | netif_start_queue(ndev); /* FIXME: wait for phy to come up */ | ||
1660 | |||
1661 | return 0; | ||
1662 | |||
1663 | failed: | ||
1664 | ns83820_stop(ndev); | ||
1665 | return ret; | ||
1666 | } | ||
1667 | |||
1668 | static void ns83820_getmac(struct ns83820 *dev, u8 *mac) | ||
1669 | { | ||
1670 | unsigned i; | ||
1671 | for (i=0; i<3; i++) { | ||
1672 | u32 data; | ||
1673 | |||
1674 | /* Read from the perfect match memory: this is loaded by | ||
1675 | * the chip from the EEPROM via the EELOAD self test. | ||
1676 | */ | ||
1677 | writel(i*2, dev->base + RFCR); | ||
1678 | data = readl(dev->base + RFDR); | ||
1679 | |||
1680 | *mac++ = data; | ||
1681 | *mac++ = data >> 8; | ||
1682 | } | ||
1683 | } | ||
1684 | |||
1685 | static int ns83820_change_mtu(struct net_device *ndev, int new_mtu) | ||
1686 | { | ||
1687 | if (new_mtu > RX_BUF_SIZE) | ||
1688 | return -EINVAL; | ||
1689 | ndev->mtu = new_mtu; | ||
1690 | return 0; | ||
1691 | } | ||
1692 | |||
1693 | static void ns83820_set_multicast(struct net_device *ndev) | ||
1694 | { | ||
1695 | struct ns83820 *dev = PRIV(ndev); | ||
1696 | u8 __iomem *rfcr = dev->base + RFCR; | ||
1697 | u32 and_mask = 0xffffffff; | ||
1698 | u32 or_mask = 0; | ||
1699 | u32 val; | ||
1700 | |||
1701 | if (ndev->flags & IFF_PROMISC) | ||
1702 | or_mask |= RFCR_AAU | RFCR_AAM; | ||
1703 | else | ||
1704 | and_mask &= ~(RFCR_AAU | RFCR_AAM); | ||
1705 | |||
1706 | if (ndev->flags & IFF_ALLMULTI || netdev_mc_count(ndev)) | ||
1707 | or_mask |= RFCR_AAM; | ||
1708 | else | ||
1709 | and_mask &= ~RFCR_AAM; | ||
1710 | |||
1711 | spin_lock_irq(&dev->misc_lock); | ||
1712 | val = (readl(rfcr) & and_mask) | or_mask; | ||
1713 | /* Ramit : RFCR Write Fix doc says RFEN must be 0 modify other bits */ | ||
1714 | writel(val & ~RFCR_RFEN, rfcr); | ||
1715 | writel(val, rfcr); | ||
1716 | spin_unlock_irq(&dev->misc_lock); | ||
1717 | } | ||
1718 | |||
1719 | static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enable, u32 done, u32 fail) | ||
1720 | { | ||
1721 | struct ns83820 *dev = PRIV(ndev); | ||
1722 | int timed_out = 0; | ||
1723 | unsigned long start; | ||
1724 | u32 status; | ||
1725 | int loops = 0; | ||
1726 | |||
1727 | dprintk("%s: start %s\n", ndev->name, name); | ||
1728 | |||
1729 | start = jiffies; | ||
1730 | |||
1731 | writel(enable, dev->base + PTSCR); | ||
1732 | for (;;) { | ||
1733 | loops++; | ||
1734 | status = readl(dev->base + PTSCR); | ||
1735 | if (!(status & enable)) | ||
1736 | break; | ||
1737 | if (status & done) | ||
1738 | break; | ||
1739 | if (status & fail) | ||
1740 | break; | ||
1741 | if (time_after_eq(jiffies, start + HZ)) { | ||
1742 | timed_out = 1; | ||
1743 | break; | ||
1744 | } | ||
1745 | schedule_timeout_uninterruptible(1); | ||
1746 | } | ||
1747 | |||
1748 | if (status & fail) | ||
1749 | printk(KERN_INFO "%s: %s failed! (0x%08x & 0x%08x)\n", | ||
1750 | ndev->name, name, status, fail); | ||
1751 | else if (timed_out) | ||
1752 | printk(KERN_INFO "%s: run_bist %s timed out! (%08x)\n", | ||
1753 | ndev->name, name, status); | ||
1754 | |||
1755 | dprintk("%s: done %s in %d loops\n", ndev->name, name, loops); | ||
1756 | } | ||
1757 | |||
1758 | #ifdef PHY_CODE_IS_FINISHED | ||
1759 | static void ns83820_mii_write_bit(struct ns83820 *dev, int bit) | ||
1760 | { | ||
1761 | /* drive MDC low */ | ||
1762 | dev->MEAR_cache &= ~MEAR_MDC; | ||
1763 | writel(dev->MEAR_cache, dev->base + MEAR); | ||
1764 | readl(dev->base + MEAR); | ||
1765 | |||
1766 | /* enable output, set bit */ | ||
1767 | dev->MEAR_cache |= MEAR_MDDIR; | ||
1768 | if (bit) | ||
1769 | dev->MEAR_cache |= MEAR_MDIO; | ||
1770 | else | ||
1771 | dev->MEAR_cache &= ~MEAR_MDIO; | ||
1772 | |||
1773 | /* set the output bit */ | ||
1774 | writel(dev->MEAR_cache, dev->base + MEAR); | ||
1775 | readl(dev->base + MEAR); | ||
1776 | |||
1777 | /* Wait. Max clock rate is 2.5MHz, this way we come in under 1MHz */ | ||
1778 | udelay(1); | ||
1779 | |||
1780 | /* drive MDC high causing the data bit to be latched */ | ||
1781 | dev->MEAR_cache |= MEAR_MDC; | ||
1782 | writel(dev->MEAR_cache, dev->base + MEAR); | ||
1783 | readl(dev->base + MEAR); | ||
1784 | |||
1785 | /* Wait again... */ | ||
1786 | udelay(1); | ||
1787 | } | ||
1788 | |||
1789 | static int ns83820_mii_read_bit(struct ns83820 *dev) | ||
1790 | { | ||
1791 | int bit; | ||
1792 | |||
1793 | /* drive MDC low, disable output */ | ||
1794 | dev->MEAR_cache &= ~MEAR_MDC; | ||
1795 | dev->MEAR_cache &= ~MEAR_MDDIR; | ||
1796 | writel(dev->MEAR_cache, dev->base + MEAR); | ||
1797 | readl(dev->base + MEAR); | ||
1798 | |||
1799 | /* Wait. Max clock rate is 2.5MHz, this way we come in under 1MHz */ | ||
1800 | udelay(1); | ||
1801 | |||
1802 | /* drive MDC high causing the data bit to be latched */ | ||
1803 | bit = (readl(dev->base + MEAR) & MEAR_MDIO) ? 1 : 0; | ||
1804 | dev->MEAR_cache |= MEAR_MDC; | ||
1805 | writel(dev->MEAR_cache, dev->base + MEAR); | ||
1806 | |||
1807 | /* Wait again... */ | ||
1808 | udelay(1); | ||
1809 | |||
1810 | return bit; | ||
1811 | } | ||
1812 | |||
1813 | static unsigned ns83820_mii_read_reg(struct ns83820 *dev, unsigned phy, unsigned reg) | ||
1814 | { | ||
1815 | unsigned data = 0; | ||
1816 | int i; | ||
1817 | |||
1818 | /* read some garbage so that we eventually sync up */ | ||
1819 | for (i=0; i<64; i++) | ||
1820 | ns83820_mii_read_bit(dev); | ||
1821 | |||
1822 | ns83820_mii_write_bit(dev, 0); /* start */ | ||
1823 | ns83820_mii_write_bit(dev, 1); | ||
1824 | ns83820_mii_write_bit(dev, 1); /* opcode read */ | ||
1825 | ns83820_mii_write_bit(dev, 0); | ||
1826 | |||
1827 | /* write out the phy address: 5 bits, msb first */ | ||
1828 | for (i=0; i<5; i++) | ||
1829 | ns83820_mii_write_bit(dev, phy & (0x10 >> i)); | ||
1830 | |||
1831 | /* write out the register address, 5 bits, msb first */ | ||
1832 | for (i=0; i<5; i++) | ||
1833 | ns83820_mii_write_bit(dev, reg & (0x10 >> i)); | ||
1834 | |||
1835 | ns83820_mii_read_bit(dev); /* turn around cycles */ | ||
1836 | ns83820_mii_read_bit(dev); | ||
1837 | |||
1838 | /* read in the register data, 16 bits msb first */ | ||
1839 | for (i=0; i<16; i++) { | ||
1840 | data <<= 1; | ||
1841 | data |= ns83820_mii_read_bit(dev); | ||
1842 | } | ||
1843 | |||
1844 | return data; | ||
1845 | } | ||
1846 | |||
1847 | static unsigned ns83820_mii_write_reg(struct ns83820 *dev, unsigned phy, unsigned reg, unsigned data) | ||
1848 | { | ||
1849 | int i; | ||
1850 | |||
1851 | /* read some garbage so that we eventually sync up */ | ||
1852 | for (i=0; i<64; i++) | ||
1853 | ns83820_mii_read_bit(dev); | ||
1854 | |||
1855 | ns83820_mii_write_bit(dev, 0); /* start */ | ||
1856 | ns83820_mii_write_bit(dev, 1); | ||
1857 | ns83820_mii_write_bit(dev, 0); /* opcode read */ | ||
1858 | ns83820_mii_write_bit(dev, 1); | ||
1859 | |||
1860 | /* write out the phy address: 5 bits, msb first */ | ||
1861 | for (i=0; i<5; i++) | ||
1862 | ns83820_mii_write_bit(dev, phy & (0x10 >> i)); | ||
1863 | |||
1864 | /* write out the register address, 5 bits, msb first */ | ||
1865 | for (i=0; i<5; i++) | ||
1866 | ns83820_mii_write_bit(dev, reg & (0x10 >> i)); | ||
1867 | |||
1868 | ns83820_mii_read_bit(dev); /* turn around cycles */ | ||
1869 | ns83820_mii_read_bit(dev); | ||
1870 | |||
1871 | /* read in the register data, 16 bits msb first */ | ||
1872 | for (i=0; i<16; i++) | ||
1873 | ns83820_mii_write_bit(dev, (data >> (15 - i)) & 1); | ||
1874 | |||
1875 | return data; | ||
1876 | } | ||
1877 | |||
1878 | static void ns83820_probe_phy(struct net_device *ndev) | ||
1879 | { | ||
1880 | struct ns83820 *dev = PRIV(ndev); | ||
1881 | static int first; | ||
1882 | int i; | ||
1883 | #define MII_PHYIDR1 0x02 | ||
1884 | #define MII_PHYIDR2 0x03 | ||
1885 | |||
1886 | #if 0 | ||
1887 | if (!first) { | ||
1888 | unsigned tmp; | ||
1889 | ns83820_mii_read_reg(dev, 1, 0x09); | ||
1890 | ns83820_mii_write_reg(dev, 1, 0x10, 0x0d3e); | ||
1891 | |||
1892 | tmp = ns83820_mii_read_reg(dev, 1, 0x00); | ||
1893 | ns83820_mii_write_reg(dev, 1, 0x00, tmp | 0x8000); | ||
1894 | udelay(1300); | ||
1895 | ns83820_mii_read_reg(dev, 1, 0x09); | ||
1896 | } | ||
1897 | #endif | ||
1898 | first = 1; | ||
1899 | |||
1900 | for (i=1; i<2; i++) { | ||
1901 | int j; | ||
1902 | unsigned a, b; | ||
1903 | a = ns83820_mii_read_reg(dev, i, MII_PHYIDR1); | ||
1904 | b = ns83820_mii_read_reg(dev, i, MII_PHYIDR2); | ||
1905 | |||
1906 | //printk("%s: phy %d: 0x%04x 0x%04x\n", | ||
1907 | // ndev->name, i, a, b); | ||
1908 | |||
1909 | for (j=0; j<0x16; j+=4) { | ||
1910 | dprintk("%s: [0x%02x] %04x %04x %04x %04x\n", | ||
1911 | ndev->name, j, | ||
1912 | ns83820_mii_read_reg(dev, i, 0 + j), | ||
1913 | ns83820_mii_read_reg(dev, i, 1 + j), | ||
1914 | ns83820_mii_read_reg(dev, i, 2 + j), | ||
1915 | ns83820_mii_read_reg(dev, i, 3 + j) | ||
1916 | ); | ||
1917 | } | ||
1918 | } | ||
1919 | { | ||
1920 | unsigned a, b; | ||
1921 | /* read firmware version: memory addr is 0x8402 and 0x8403 */ | ||
1922 | ns83820_mii_write_reg(dev, 1, 0x16, 0x000d); | ||
1923 | ns83820_mii_write_reg(dev, 1, 0x1e, 0x810e); | ||
1924 | a = ns83820_mii_read_reg(dev, 1, 0x1d); | ||
1925 | |||
1926 | ns83820_mii_write_reg(dev, 1, 0x16, 0x000d); | ||
1927 | ns83820_mii_write_reg(dev, 1, 0x1e, 0x810e); | ||
1928 | b = ns83820_mii_read_reg(dev, 1, 0x1d); | ||
1929 | dprintk("version: 0x%04x 0x%04x\n", a, b); | ||
1930 | } | ||
1931 | } | ||
1932 | #endif | ||
1933 | |||
1934 | static const struct net_device_ops netdev_ops = { | ||
1935 | .ndo_open = ns83820_open, | ||
1936 | .ndo_stop = ns83820_stop, | ||
1937 | .ndo_start_xmit = ns83820_hard_start_xmit, | ||
1938 | .ndo_get_stats = ns83820_get_stats, | ||
1939 | .ndo_change_mtu = ns83820_change_mtu, | ||
1940 | .ndo_set_multicast_list = ns83820_set_multicast, | ||
1941 | .ndo_validate_addr = eth_validate_addr, | ||
1942 | .ndo_set_mac_address = eth_mac_addr, | ||
1943 | .ndo_tx_timeout = ns83820_tx_timeout, | ||
1944 | }; | ||
1945 | |||
1946 | static int __devinit ns83820_init_one(struct pci_dev *pci_dev, | ||
1947 | const struct pci_device_id *id) | ||
1948 | { | ||
1949 | struct net_device *ndev; | ||
1950 | struct ns83820 *dev; | ||
1951 | long addr; | ||
1952 | int err; | ||
1953 | int using_dac = 0; | ||
1954 | |||
1955 | /* See if we can set the dma mask early on; failure is fatal. */ | ||
1956 | if (sizeof(dma_addr_t) == 8 && | ||
1957 | !pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) { | ||
1958 | using_dac = 1; | ||
1959 | } else if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) { | ||
1960 | using_dac = 0; | ||
1961 | } else { | ||
1962 | dev_warn(&pci_dev->dev, "pci_set_dma_mask failed!\n"); | ||
1963 | return -ENODEV; | ||
1964 | } | ||
1965 | |||
1966 | ndev = alloc_etherdev(sizeof(struct ns83820)); | ||
1967 | err = -ENOMEM; | ||
1968 | if (!ndev) | ||
1969 | goto out; | ||
1970 | |||
1971 | dev = PRIV(ndev); | ||
1972 | dev->ndev = ndev; | ||
1973 | |||
1974 | spin_lock_init(&dev->rx_info.lock); | ||
1975 | spin_lock_init(&dev->tx_lock); | ||
1976 | spin_lock_init(&dev->misc_lock); | ||
1977 | dev->pci_dev = pci_dev; | ||
1978 | |||
1979 | SET_NETDEV_DEV(ndev, &pci_dev->dev); | ||
1980 | |||
1981 | INIT_WORK(&dev->tq_refill, queue_refill); | ||
1982 | tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)ndev); | ||
1983 | |||
1984 | err = pci_enable_device(pci_dev); | ||
1985 | if (err) { | ||
1986 | dev_info(&pci_dev->dev, "pci_enable_dev failed: %d\n", err); | ||
1987 | goto out_free; | ||
1988 | } | ||
1989 | |||
1990 | pci_set_master(pci_dev); | ||
1991 | addr = pci_resource_start(pci_dev, 1); | ||
1992 | dev->base = ioremap_nocache(addr, PAGE_SIZE); | ||
1993 | dev->tx_descs = pci_alloc_consistent(pci_dev, | ||
1994 | 4 * DESC_SIZE * NR_TX_DESC, &dev->tx_phy_descs); | ||
1995 | dev->rx_info.descs = pci_alloc_consistent(pci_dev, | ||
1996 | 4 * DESC_SIZE * NR_RX_DESC, &dev->rx_info.phy_descs); | ||
1997 | err = -ENOMEM; | ||
1998 | if (!dev->base || !dev->tx_descs || !dev->rx_info.descs) | ||
1999 | goto out_disable; | ||
2000 | |||
2001 | dprintk("%p: %08lx %p: %08lx\n", | ||
2002 | dev->tx_descs, (long)dev->tx_phy_descs, | ||
2003 | dev->rx_info.descs, (long)dev->rx_info.phy_descs); | ||
2004 | |||
2005 | ns83820_disable_interrupts(dev); | ||
2006 | |||
2007 | dev->IMR_cache = 0; | ||
2008 | |||
2009 | err = request_irq(pci_dev->irq, ns83820_irq, IRQF_SHARED, | ||
2010 | DRV_NAME, ndev); | ||
2011 | if (err) { | ||
2012 | dev_info(&pci_dev->dev, "unable to register irq %d, err %d\n", | ||
2013 | pci_dev->irq, err); | ||
2014 | goto out_disable; | ||
2015 | } | ||
2016 | |||
2017 | /* | ||
2018 | * FIXME: we are holding rtnl_lock() over obscenely long area only | ||
2019 | * because some of the setup code uses dev->name. It's Wrong(tm) - | ||
2020 | * we should be using driver-specific names for all that stuff. | ||
2021 | * For now that will do, but we really need to come back and kill | ||
2022 | * most of the dev_alloc_name() users later. | ||
2023 | */ | ||
2024 | rtnl_lock(); | ||
2025 | err = dev_alloc_name(ndev, ndev->name); | ||
2026 | if (err < 0) { | ||
2027 | dev_info(&pci_dev->dev, "unable to get netdev name: %d\n", err); | ||
2028 | goto out_free_irq; | ||
2029 | } | ||
2030 | |||
2031 | printk("%s: ns83820.c: 0x22c: %08x, subsystem: %04x:%04x\n", | ||
2032 | ndev->name, le32_to_cpu(readl(dev->base + 0x22c)), | ||
2033 | pci_dev->subsystem_vendor, pci_dev->subsystem_device); | ||
2034 | |||
2035 | ndev->netdev_ops = &netdev_ops; | ||
2036 | SET_ETHTOOL_OPS(ndev, &ops); | ||
2037 | ndev->watchdog_timeo = 5 * HZ; | ||
2038 | pci_set_drvdata(pci_dev, ndev); | ||
2039 | |||
2040 | ns83820_do_reset(dev, CR_RST); | ||
2041 | |||
2042 | /* Must reset the ram bist before running it */ | ||
2043 | writel(PTSCR_RBIST_RST, dev->base + PTSCR); | ||
2044 | ns83820_run_bist(ndev, "sram bist", PTSCR_RBIST_EN, | ||
2045 | PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL); | ||
2046 | ns83820_run_bist(ndev, "eeprom bist", PTSCR_EEBIST_EN, 0, | ||
2047 | PTSCR_EEBIST_FAIL); | ||
2048 | ns83820_run_bist(ndev, "eeprom load", PTSCR_EELOAD_EN, 0, 0); | ||
2049 | |||
2050 | /* I love config registers */ | ||
2051 | dev->CFG_cache = readl(dev->base + CFG); | ||
2052 | |||
2053 | if ((dev->CFG_cache & CFG_PCI64_DET)) { | ||
2054 | printk(KERN_INFO "%s: detected 64 bit PCI data bus.\n", | ||
2055 | ndev->name); | ||
2056 | /*dev->CFG_cache |= CFG_DATA64_EN;*/ | ||
2057 | if (!(dev->CFG_cache & CFG_DATA64_EN)) | ||
2058 | printk(KERN_INFO "%s: EEPROM did not enable 64 bit bus. Disabled.\n", | ||
2059 | ndev->name); | ||
2060 | } else | ||
2061 | dev->CFG_cache &= ~(CFG_DATA64_EN); | ||
2062 | |||
2063 | dev->CFG_cache &= (CFG_TBI_EN | CFG_MRM_DIS | CFG_MWI_DIS | | ||
2064 | CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 | | ||
2065 | CFG_M64ADDR); | ||
2066 | dev->CFG_cache |= CFG_PINT_DUPSTS | CFG_PINT_LNKSTS | CFG_PINT_SPDSTS | | ||
2067 | CFG_EXTSTS_EN | CFG_EXD | CFG_PESEL; | ||
2068 | dev->CFG_cache |= CFG_REQALG; | ||
2069 | dev->CFG_cache |= CFG_POW; | ||
2070 | dev->CFG_cache |= CFG_TMRTEST; | ||
2071 | |||
2072 | /* When compiled with 64 bit addressing, we must always enable | ||
2073 | * the 64 bit descriptor format. | ||
2074 | */ | ||
2075 | if (sizeof(dma_addr_t) == 8) | ||
2076 | dev->CFG_cache |= CFG_M64ADDR; | ||
2077 | if (using_dac) | ||
2078 | dev->CFG_cache |= CFG_T64ADDR; | ||
2079 | |||
2080 | /* Big endian mode does not seem to do what the docs suggest */ | ||
2081 | dev->CFG_cache &= ~CFG_BEM; | ||
2082 | |||
2083 | /* setup optical transceiver if we have one */ | ||
2084 | if (dev->CFG_cache & CFG_TBI_EN) { | ||
2085 | printk(KERN_INFO "%s: enabling optical transceiver\n", | ||
2086 | ndev->name); | ||
2087 | writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR); | ||
2088 | |||
2089 | /* setup auto negotiation feature advertisement */ | ||
2090 | writel(readl(dev->base + TANAR) | ||
2091 | | TANAR_HALF_DUP | TANAR_FULL_DUP, | ||
2092 | dev->base + TANAR); | ||
2093 | |||
2094 | /* start auto negotiation */ | ||
2095 | writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN, | ||
2096 | dev->base + TBICR); | ||
2097 | writel(TBICR_MR_AN_ENABLE, dev->base + TBICR); | ||
2098 | dev->linkstate = LINK_AUTONEGOTIATE; | ||
2099 | |||
2100 | dev->CFG_cache |= CFG_MODE_1000; | ||
2101 | } | ||
2102 | |||
2103 | writel(dev->CFG_cache, dev->base + CFG); | ||
2104 | dprintk("CFG: %08x\n", dev->CFG_cache); | ||
2105 | |||
2106 | if (reset_phy) { | ||
2107 | printk(KERN_INFO "%s: resetting phy\n", ndev->name); | ||
2108 | writel(dev->CFG_cache | CFG_PHY_RST, dev->base + CFG); | ||
2109 | msleep(10); | ||
2110 | writel(dev->CFG_cache, dev->base + CFG); | ||
2111 | } | ||
2112 | |||
2113 | #if 0 /* Huh? This sets the PCI latency register. Should be done via | ||
2114 | * the PCI layer. FIXME. | ||
2115 | */ | ||
2116 | if (readl(dev->base + SRR)) | ||
2117 | writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c); | ||
2118 | #endif | ||
2119 | |||
2120 | /* Note! The DMA burst size interacts with packet | ||
2121 | * transmission, such that the largest packet that | ||
2122 | * can be transmitted is 8192 - FLTH - burst size. | ||
2123 | * If only the transmit fifo was larger... | ||
2124 | */ | ||
2125 | /* Ramit : 1024 DMA is not a good idea, it ends up banging | ||
2126 | * some DELL and COMPAQ SMP systems */ | ||
2127 | writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA512 | ||
2128 | | ((1600 / 32) * 0x100), | ||
2129 | dev->base + TXCFG); | ||
2130 | |||
2131 | /* Flush the interrupt holdoff timer */ | ||
2132 | writel(0x000, dev->base + IHR); | ||
2133 | writel(0x100, dev->base + IHR); | ||
2134 | writel(0x000, dev->base + IHR); | ||
2135 | |||
2136 | /* Set Rx to full duplex, don't accept runt, errored, long or length | ||
2137 | * range errored packets. Use 512 byte DMA. | ||
2138 | */ | ||
2139 | /* Ramit : 1024 DMA is not a good idea, it ends up banging | ||
2140 | * some DELL and COMPAQ SMP systems | ||
2141 | * Turn on ALP, only we are accpeting Jumbo Packets */ | ||
2142 | writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD | ||
2143 | | RXCFG_STRIPCRC | ||
2144 | //| RXCFG_ALP | ||
2145 | | (RXCFG_MXDMA512) | 0, dev->base + RXCFG); | ||
2146 | |||
2147 | /* Disable priority queueing */ | ||
2148 | writel(0, dev->base + PQCR); | ||
2149 | |||
2150 | /* Enable IP checksum validation and detetion of VLAN headers. | ||
2151 | * Note: do not set the reject options as at least the 0x102 | ||
2152 | * revision of the chip does not properly accept IP fragments | ||
2153 | * at least for UDP. | ||
2154 | */ | ||
2155 | /* Ramit : Be sure to turn on RXCFG_ARP if VLAN's are enabled, since | ||
2156 | * the MAC it calculates the packetsize AFTER stripping the VLAN | ||
2157 | * header, and if a VLAN Tagged packet of 64 bytes is received (like | ||
2158 | * a ping with a VLAN header) then the card, strips the 4 byte VLAN | ||
2159 | * tag and then checks the packet size, so if RXCFG_ARP is not enabled, | ||
2160 | * it discrards it!. These guys...... | ||
2161 | * also turn on tag stripping if hardware acceleration is enabled | ||
2162 | */ | ||
2163 | #ifdef NS83820_VLAN_ACCEL_SUPPORT | ||
2164 | #define VRCR_INIT_VALUE (VRCR_IPEN|VRCR_VTDEN|VRCR_VTREN) | ||
2165 | #else | ||
2166 | #define VRCR_INIT_VALUE (VRCR_IPEN|VRCR_VTDEN) | ||
2167 | #endif | ||
2168 | writel(VRCR_INIT_VALUE, dev->base + VRCR); | ||
2169 | |||
2170 | /* Enable per-packet TCP/UDP/IP checksumming | ||
2171 | * and per packet vlan tag insertion if | ||
2172 | * vlan hardware acceleration is enabled | ||
2173 | */ | ||
2174 | #ifdef NS83820_VLAN_ACCEL_SUPPORT | ||
2175 | #define VTCR_INIT_VALUE (VTCR_PPCHK|VTCR_VPPTI) | ||
2176 | #else | ||
2177 | #define VTCR_INIT_VALUE VTCR_PPCHK | ||
2178 | #endif | ||
2179 | writel(VTCR_INIT_VALUE, dev->base + VTCR); | ||
2180 | |||
2181 | /* Ramit : Enable async and sync pause frames */ | ||
2182 | /* writel(0, dev->base + PCR); */ | ||
2183 | writel((PCR_PS_MCAST | PCR_PS_DA | PCR_PSEN | PCR_FFLO_4K | | ||
2184 | PCR_FFHI_8K | PCR_STLO_4 | PCR_STHI_8 | PCR_PAUSE_CNT), | ||
2185 | dev->base + PCR); | ||
2186 | |||
2187 | /* Disable Wake On Lan */ | ||
2188 | writel(0, dev->base + WCSR); | ||
2189 | |||
2190 | ns83820_getmac(dev, ndev->dev_addr); | ||
2191 | |||
2192 | /* Yes, we support dumb IP checksum on transmit */ | ||
2193 | ndev->features |= NETIF_F_SG; | ||
2194 | ndev->features |= NETIF_F_IP_CSUM; | ||
2195 | |||
2196 | #ifdef NS83820_VLAN_ACCEL_SUPPORT | ||
2197 | /* We also support hardware vlan acceleration */ | ||
2198 | ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
2199 | #endif | ||
2200 | |||
2201 | if (using_dac) { | ||
2202 | printk(KERN_INFO "%s: using 64 bit addressing.\n", | ||
2203 | ndev->name); | ||
2204 | ndev->features |= NETIF_F_HIGHDMA; | ||
2205 | } | ||
2206 | |||
2207 | printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %pM io=0x%08lx irq=%d f=%s\n", | ||
2208 | ndev->name, | ||
2209 | (unsigned)readl(dev->base + SRR) >> 8, | ||
2210 | (unsigned)readl(dev->base + SRR) & 0xff, | ||
2211 | ndev->dev_addr, addr, pci_dev->irq, | ||
2212 | (ndev->features & NETIF_F_HIGHDMA) ? "h,sg" : "sg" | ||
2213 | ); | ||
2214 | |||
2215 | #ifdef PHY_CODE_IS_FINISHED | ||
2216 | ns83820_probe_phy(ndev); | ||
2217 | #endif | ||
2218 | |||
2219 | err = register_netdevice(ndev); | ||
2220 | if (err) { | ||
2221 | printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err); | ||
2222 | goto out_cleanup; | ||
2223 | } | ||
2224 | rtnl_unlock(); | ||
2225 | |||
2226 | return 0; | ||
2227 | |||
2228 | out_cleanup: | ||
2229 | ns83820_disable_interrupts(dev); /* paranoia */ | ||
2230 | out_free_irq: | ||
2231 | rtnl_unlock(); | ||
2232 | free_irq(pci_dev->irq, ndev); | ||
2233 | out_disable: | ||
2234 | if (dev->base) | ||
2235 | iounmap(dev->base); | ||
2236 | pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_TX_DESC, dev->tx_descs, dev->tx_phy_descs); | ||
2237 | pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_RX_DESC, dev->rx_info.descs, dev->rx_info.phy_descs); | ||
2238 | pci_disable_device(pci_dev); | ||
2239 | out_free: | ||
2240 | free_netdev(ndev); | ||
2241 | pci_set_drvdata(pci_dev, NULL); | ||
2242 | out: | ||
2243 | return err; | ||
2244 | } | ||
2245 | |||
2246 | static void __devexit ns83820_remove_one(struct pci_dev *pci_dev) | ||
2247 | { | ||
2248 | struct net_device *ndev = pci_get_drvdata(pci_dev); | ||
2249 | struct ns83820 *dev = PRIV(ndev); /* ok even if NULL */ | ||
2250 | |||
2251 | if (!ndev) /* paranoia */ | ||
2252 | return; | ||
2253 | |||
2254 | ns83820_disable_interrupts(dev); /* paranoia */ | ||
2255 | |||
2256 | unregister_netdev(ndev); | ||
2257 | free_irq(dev->pci_dev->irq, ndev); | ||
2258 | iounmap(dev->base); | ||
2259 | pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_TX_DESC, | ||
2260 | dev->tx_descs, dev->tx_phy_descs); | ||
2261 | pci_free_consistent(dev->pci_dev, 4 * DESC_SIZE * NR_RX_DESC, | ||
2262 | dev->rx_info.descs, dev->rx_info.phy_descs); | ||
2263 | pci_disable_device(dev->pci_dev); | ||
2264 | free_netdev(ndev); | ||
2265 | pci_set_drvdata(pci_dev, NULL); | ||
2266 | } | ||
2267 | |||
2268 | static DEFINE_PCI_DEVICE_TABLE(ns83820_pci_tbl) = { | ||
2269 | { 0x100b, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, .driver_data = 0, }, | ||
2270 | { 0, }, | ||
2271 | }; | ||
2272 | |||
2273 | static struct pci_driver driver = { | ||
2274 | .name = "ns83820", | ||
2275 | .id_table = ns83820_pci_tbl, | ||
2276 | .probe = ns83820_init_one, | ||
2277 | .remove = __devexit_p(ns83820_remove_one), | ||
2278 | #if 0 /* FIXME: implement */ | ||
2279 | .suspend = , | ||
2280 | .resume = , | ||
2281 | #endif | ||
2282 | }; | ||
2283 | |||
2284 | |||
2285 | static int __init ns83820_init(void) | ||
2286 | { | ||
2287 | printk(KERN_INFO "ns83820.c: National Semiconductor DP83820 10/100/1000 driver.\n"); | ||
2288 | return pci_register_driver(&driver); | ||
2289 | } | ||
2290 | |||
2291 | static void __exit ns83820_exit(void) | ||
2292 | { | ||
2293 | pci_unregister_driver(&driver); | ||
2294 | } | ||
2295 | |||
2296 | MODULE_AUTHOR("Benjamin LaHaise <bcrl@kvack.org>"); | ||
2297 | MODULE_DESCRIPTION("National Semiconductor DP83820 10/100/1000 driver"); | ||
2298 | MODULE_LICENSE("GPL"); | ||
2299 | |||
2300 | MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl); | ||
2301 | |||
2302 | module_param(lnksts, int, 0); | ||
2303 | MODULE_PARM_DESC(lnksts, "Polarity of LNKSTS bit"); | ||
2304 | |||
2305 | module_param(ihr, int, 0); | ||
2306 | MODULE_PARM_DESC(ihr, "Time in 100 us increments to delay interrupts (range 0-127)"); | ||
2307 | |||
2308 | module_param(reset_phy, int, 0); | ||
2309 | MODULE_PARM_DESC(reset_phy, "Set to 1 to reset the PHY on startup"); | ||
2310 | |||
2311 | module_init(ns83820_init); | ||
2312 | module_exit(ns83820_exit); | ||
diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c new file mode 100644 index 000000000000..26e25d7f5829 --- /dev/null +++ b/drivers/net/ethernet/natsemi/sonic.c | |||
@@ -0,0 +1,742 @@ | |||
1 | /* | ||
2 | * sonic.c | ||
3 | * | ||
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, added zero-copy buffer handling, and | ||
7 | * (from the mac68k project) introduced dhd's support for 16-bit cards. | ||
8 | * | ||
9 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
10 | * | ||
11 | * This driver is based on work from Andreas Busse, but most of | ||
12 | * the code is rewritten. | ||
13 | * | ||
14 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) | ||
15 | * | ||
16 | * Core code included by system sonic drivers | ||
17 | * | ||
18 | * And... partially rewritten again by David Huggins-Daines in order | ||
19 | * to cope with screwed up Macintosh NICs that may or may not use | ||
20 | * 16-bit DMA. | ||
21 | * | ||
22 | * (C) 1999 David Huggins-Daines <dhd@debian.org> | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook, | ||
28 | * National Semiconductors data sheet for the DP83932B Sonic Ethernet | ||
29 | * controller, and the files "8390.c" and "skeleton.c" in this directory. | ||
30 | * | ||
31 | * Additional sources: Nat Semi data sheet for the DP83932C and Nat Semi | ||
32 | * Application Note AN-746, the files "lance.c" and "ibmlana.c". See also | ||
33 | * the NetBSD file "sys/arch/mac68k/dev/if_sn.c". | ||
34 | */ | ||
35 | |||
36 | |||
37 | |||
38 | /* | ||
39 | * Open/initialize the SONIC controller. | ||
40 | * | ||
41 | * This routine should set everything up anew at each open, even | ||
42 | * registers that "should" only need to be set once at boot, so that | ||
43 | * there is non-reboot way to recover if something goes wrong. | ||
44 | */ | ||
45 | static int sonic_open(struct net_device *dev) | ||
46 | { | ||
47 | struct sonic_local *lp = netdev_priv(dev); | ||
48 | int i; | ||
49 | |||
50 | if (sonic_debug > 2) | ||
51 | printk("sonic_open: initializing sonic driver.\n"); | ||
52 | |||
53 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
54 | struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2); | ||
55 | if (skb == NULL) { | ||
56 | while(i > 0) { /* free any that were allocated successfully */ | ||
57 | i--; | ||
58 | dev_kfree_skb(lp->rx_skb[i]); | ||
59 | lp->rx_skb[i] = NULL; | ||
60 | } | ||
61 | printk(KERN_ERR "%s: couldn't allocate receive buffers\n", | ||
62 | dev->name); | ||
63 | return -ENOMEM; | ||
64 | } | ||
65 | /* align IP header unless DMA requires otherwise */ | ||
66 | if (SONIC_BUS_SCALE(lp->dma_bitmode) == 2) | ||
67 | skb_reserve(skb, 2); | ||
68 | lp->rx_skb[i] = skb; | ||
69 | } | ||
70 | |||
71 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
72 | dma_addr_t laddr = dma_map_single(lp->device, skb_put(lp->rx_skb[i], SONIC_RBSIZE), | ||
73 | SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
74 | if (!laddr) { | ||
75 | while(i > 0) { /* free any that were mapped successfully */ | ||
76 | i--; | ||
77 | dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
78 | lp->rx_laddr[i] = (dma_addr_t)0; | ||
79 | } | ||
80 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
81 | dev_kfree_skb(lp->rx_skb[i]); | ||
82 | lp->rx_skb[i] = NULL; | ||
83 | } | ||
84 | printk(KERN_ERR "%s: couldn't map rx DMA buffers\n", | ||
85 | dev->name); | ||
86 | return -ENOMEM; | ||
87 | } | ||
88 | lp->rx_laddr[i] = laddr; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * Initialize the SONIC | ||
93 | */ | ||
94 | sonic_init(dev); | ||
95 | |||
96 | netif_start_queue(dev); | ||
97 | |||
98 | if (sonic_debug > 2) | ||
99 | printk("sonic_open: Initialization done.\n"); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | |||
105 | /* | ||
106 | * Close the SONIC device | ||
107 | */ | ||
108 | static int sonic_close(struct net_device *dev) | ||
109 | { | ||
110 | struct sonic_local *lp = netdev_priv(dev); | ||
111 | int i; | ||
112 | |||
113 | if (sonic_debug > 2) | ||
114 | printk("sonic_close\n"); | ||
115 | |||
116 | netif_stop_queue(dev); | ||
117 | |||
118 | /* | ||
119 | * stop the SONIC, disable interrupts | ||
120 | */ | ||
121 | SONIC_WRITE(SONIC_IMR, 0); | ||
122 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
123 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | ||
124 | |||
125 | /* unmap and free skbs that haven't been transmitted */ | ||
126 | for (i = 0; i < SONIC_NUM_TDS; i++) { | ||
127 | if(lp->tx_laddr[i]) { | ||
128 | dma_unmap_single(lp->device, lp->tx_laddr[i], lp->tx_len[i], DMA_TO_DEVICE); | ||
129 | lp->tx_laddr[i] = (dma_addr_t)0; | ||
130 | } | ||
131 | if(lp->tx_skb[i]) { | ||
132 | dev_kfree_skb(lp->tx_skb[i]); | ||
133 | lp->tx_skb[i] = NULL; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /* unmap and free the receive buffers */ | ||
138 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
139 | if(lp->rx_laddr[i]) { | ||
140 | dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
141 | lp->rx_laddr[i] = (dma_addr_t)0; | ||
142 | } | ||
143 | if(lp->rx_skb[i]) { | ||
144 | dev_kfree_skb(lp->rx_skb[i]); | ||
145 | lp->rx_skb[i] = NULL; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static void sonic_tx_timeout(struct net_device *dev) | ||
153 | { | ||
154 | struct sonic_local *lp = netdev_priv(dev); | ||
155 | int i; | ||
156 | /* | ||
157 | * put the Sonic into software-reset mode and | ||
158 | * disable all interrupts before releasing DMA buffers | ||
159 | */ | ||
160 | SONIC_WRITE(SONIC_IMR, 0); | ||
161 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
162 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | ||
163 | /* We could resend the original skbs. Easier to re-initialise. */ | ||
164 | for (i = 0; i < SONIC_NUM_TDS; i++) { | ||
165 | if(lp->tx_laddr[i]) { | ||
166 | dma_unmap_single(lp->device, lp->tx_laddr[i], lp->tx_len[i], DMA_TO_DEVICE); | ||
167 | lp->tx_laddr[i] = (dma_addr_t)0; | ||
168 | } | ||
169 | if(lp->tx_skb[i]) { | ||
170 | dev_kfree_skb(lp->tx_skb[i]); | ||
171 | lp->tx_skb[i] = NULL; | ||
172 | } | ||
173 | } | ||
174 | /* Try to restart the adaptor. */ | ||
175 | sonic_init(dev); | ||
176 | lp->stats.tx_errors++; | ||
177 | dev->trans_start = jiffies; /* prevent tx timeout */ | ||
178 | netif_wake_queue(dev); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * transmit packet | ||
183 | * | ||
184 | * Appends new TD during transmission thus avoiding any TX interrupts | ||
185 | * until we run out of TDs. | ||
186 | * This routine interacts closely with the ISR in that it may, | ||
187 | * set tx_skb[i] | ||
188 | * reset the status flags of the new TD | ||
189 | * set and reset EOL flags | ||
190 | * stop the tx queue | ||
191 | * The ISR interacts with this routine in various ways. It may, | ||
192 | * reset tx_skb[i] | ||
193 | * test the EOL and status flags of the TDs | ||
194 | * wake the tx queue | ||
195 | * Concurrently with all of this, the SONIC is potentially writing to | ||
196 | * the status flags of the TDs. | ||
197 | * Until some mutual exclusion is added, this code will not work with SMP. However, | ||
198 | * MIPS Jazz machines and m68k Macs were all uni-processor machines. | ||
199 | */ | ||
200 | |||
201 | static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) | ||
202 | { | ||
203 | struct sonic_local *lp = netdev_priv(dev); | ||
204 | dma_addr_t laddr; | ||
205 | int length; | ||
206 | int entry = lp->next_tx; | ||
207 | |||
208 | if (sonic_debug > 2) | ||
209 | printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev); | ||
210 | |||
211 | length = skb->len; | ||
212 | if (length < ETH_ZLEN) { | ||
213 | if (skb_padto(skb, ETH_ZLEN)) | ||
214 | return NETDEV_TX_OK; | ||
215 | length = ETH_ZLEN; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Map the packet data into the logical DMA address space | ||
220 | */ | ||
221 | |||
222 | laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE); | ||
223 | if (!laddr) { | ||
224 | printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name); | ||
225 | dev_kfree_skb(skb); | ||
226 | return NETDEV_TX_BUSY; | ||
227 | } | ||
228 | |||
229 | sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */ | ||
230 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_COUNT, 1); /* single fragment */ | ||
231 | sonic_tda_put(dev, entry, SONIC_TD_PKTSIZE, length); /* length of packet */ | ||
232 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_PTR_L, laddr & 0xffff); | ||
233 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_PTR_H, laddr >> 16); | ||
234 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_SIZE, length); | ||
235 | sonic_tda_put(dev, entry, SONIC_TD_LINK, | ||
236 | sonic_tda_get(dev, entry, SONIC_TD_LINK) | SONIC_EOL); | ||
237 | |||
238 | /* | ||
239 | * Must set tx_skb[entry] only after clearing status, and | ||
240 | * before clearing EOL and before stopping queue | ||
241 | */ | ||
242 | wmb(); | ||
243 | lp->tx_len[entry] = length; | ||
244 | lp->tx_laddr[entry] = laddr; | ||
245 | lp->tx_skb[entry] = skb; | ||
246 | |||
247 | wmb(); | ||
248 | sonic_tda_put(dev, lp->eol_tx, SONIC_TD_LINK, | ||
249 | sonic_tda_get(dev, lp->eol_tx, SONIC_TD_LINK) & ~SONIC_EOL); | ||
250 | lp->eol_tx = entry; | ||
251 | |||
252 | lp->next_tx = (entry + 1) & SONIC_TDS_MASK; | ||
253 | if (lp->tx_skb[lp->next_tx] != NULL) { | ||
254 | /* The ring is full, the ISR has yet to process the next TD. */ | ||
255 | if (sonic_debug > 3) | ||
256 | printk("%s: stopping queue\n", dev->name); | ||
257 | netif_stop_queue(dev); | ||
258 | /* after this packet, wait for ISR to free up some TDAs */ | ||
259 | } else netif_start_queue(dev); | ||
260 | |||
261 | if (sonic_debug > 2) | ||
262 | printk("sonic_send_packet: issuing Tx command\n"); | ||
263 | |||
264 | SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); | ||
265 | |||
266 | return NETDEV_TX_OK; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * The typical workload of the driver: | ||
271 | * Handle the network interface interrupts. | ||
272 | */ | ||
273 | static irqreturn_t sonic_interrupt(int irq, void *dev_id) | ||
274 | { | ||
275 | struct net_device *dev = dev_id; | ||
276 | struct sonic_local *lp = netdev_priv(dev); | ||
277 | int status; | ||
278 | |||
279 | if (!(status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)) | ||
280 | return IRQ_NONE; | ||
281 | |||
282 | do { | ||
283 | if (status & SONIC_INT_PKTRX) { | ||
284 | if (sonic_debug > 2) | ||
285 | printk("%s: packet rx\n", dev->name); | ||
286 | sonic_rx(dev); /* got packet(s) */ | ||
287 | SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */ | ||
288 | } | ||
289 | |||
290 | if (status & SONIC_INT_TXDN) { | ||
291 | int entry = lp->cur_tx; | ||
292 | int td_status; | ||
293 | int freed_some = 0; | ||
294 | |||
295 | /* At this point, cur_tx is the index of a TD that is one of: | ||
296 | * unallocated/freed (status set & tx_skb[entry] clear) | ||
297 | * allocated and sent (status set & tx_skb[entry] set ) | ||
298 | * allocated and not yet sent (status clear & tx_skb[entry] set ) | ||
299 | * still being allocated by sonic_send_packet (status clear & tx_skb[entry] clear) | ||
300 | */ | ||
301 | |||
302 | if (sonic_debug > 2) | ||
303 | printk("%s: tx done\n", dev->name); | ||
304 | |||
305 | while (lp->tx_skb[entry] != NULL) { | ||
306 | if ((td_status = sonic_tda_get(dev, entry, SONIC_TD_STATUS)) == 0) | ||
307 | break; | ||
308 | |||
309 | if (td_status & 0x0001) { | ||
310 | lp->stats.tx_packets++; | ||
311 | lp->stats.tx_bytes += sonic_tda_get(dev, entry, SONIC_TD_PKTSIZE); | ||
312 | } else { | ||
313 | lp->stats.tx_errors++; | ||
314 | if (td_status & 0x0642) | ||
315 | lp->stats.tx_aborted_errors++; | ||
316 | if (td_status & 0x0180) | ||
317 | lp->stats.tx_carrier_errors++; | ||
318 | if (td_status & 0x0020) | ||
319 | lp->stats.tx_window_errors++; | ||
320 | if (td_status & 0x0004) | ||
321 | lp->stats.tx_fifo_errors++; | ||
322 | } | ||
323 | |||
324 | /* We must free the original skb */ | ||
325 | dev_kfree_skb_irq(lp->tx_skb[entry]); | ||
326 | lp->tx_skb[entry] = NULL; | ||
327 | /* and unmap DMA buffer */ | ||
328 | dma_unmap_single(lp->device, lp->tx_laddr[entry], lp->tx_len[entry], DMA_TO_DEVICE); | ||
329 | lp->tx_laddr[entry] = (dma_addr_t)0; | ||
330 | freed_some = 1; | ||
331 | |||
332 | if (sonic_tda_get(dev, entry, SONIC_TD_LINK) & SONIC_EOL) { | ||
333 | entry = (entry + 1) & SONIC_TDS_MASK; | ||
334 | break; | ||
335 | } | ||
336 | entry = (entry + 1) & SONIC_TDS_MASK; | ||
337 | } | ||
338 | |||
339 | if (freed_some || lp->tx_skb[entry] == NULL) | ||
340 | netif_wake_queue(dev); /* The ring is no longer full */ | ||
341 | lp->cur_tx = entry; | ||
342 | SONIC_WRITE(SONIC_ISR, SONIC_INT_TXDN); /* clear the interrupt */ | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * check error conditions | ||
347 | */ | ||
348 | if (status & SONIC_INT_RFO) { | ||
349 | if (sonic_debug > 1) | ||
350 | printk("%s: rx fifo overrun\n", dev->name); | ||
351 | lp->stats.rx_fifo_errors++; | ||
352 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */ | ||
353 | } | ||
354 | if (status & SONIC_INT_RDE) { | ||
355 | if (sonic_debug > 1) | ||
356 | printk("%s: rx descriptors exhausted\n", dev->name); | ||
357 | lp->stats.rx_dropped++; | ||
358 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */ | ||
359 | } | ||
360 | if (status & SONIC_INT_RBAE) { | ||
361 | if (sonic_debug > 1) | ||
362 | printk("%s: rx buffer area exceeded\n", dev->name); | ||
363 | lp->stats.rx_dropped++; | ||
364 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */ | ||
365 | } | ||
366 | |||
367 | /* counter overruns; all counters are 16bit wide */ | ||
368 | if (status & SONIC_INT_FAE) { | ||
369 | lp->stats.rx_frame_errors += 65536; | ||
370 | SONIC_WRITE(SONIC_ISR, SONIC_INT_FAE); /* clear the interrupt */ | ||
371 | } | ||
372 | if (status & SONIC_INT_CRC) { | ||
373 | lp->stats.rx_crc_errors += 65536; | ||
374 | SONIC_WRITE(SONIC_ISR, SONIC_INT_CRC); /* clear the interrupt */ | ||
375 | } | ||
376 | if (status & SONIC_INT_MP) { | ||
377 | lp->stats.rx_missed_errors += 65536; | ||
378 | SONIC_WRITE(SONIC_ISR, SONIC_INT_MP); /* clear the interrupt */ | ||
379 | } | ||
380 | |||
381 | /* transmit error */ | ||
382 | if (status & SONIC_INT_TXER) { | ||
383 | if ((SONIC_READ(SONIC_TCR) & SONIC_TCR_FU) && (sonic_debug > 2)) | ||
384 | printk(KERN_ERR "%s: tx fifo underrun\n", dev->name); | ||
385 | SONIC_WRITE(SONIC_ISR, SONIC_INT_TXER); /* clear the interrupt */ | ||
386 | } | ||
387 | |||
388 | /* bus retry */ | ||
389 | if (status & SONIC_INT_BR) { | ||
390 | printk(KERN_ERR "%s: Bus retry occurred! Device interrupt disabled.\n", | ||
391 | dev->name); | ||
392 | /* ... to help debug DMA problems causing endless interrupts. */ | ||
393 | /* Bounce the eth interface to turn on the interrupt again. */ | ||
394 | SONIC_WRITE(SONIC_IMR, 0); | ||
395 | SONIC_WRITE(SONIC_ISR, SONIC_INT_BR); /* clear the interrupt */ | ||
396 | } | ||
397 | |||
398 | /* load CAM done */ | ||
399 | if (status & SONIC_INT_LCD) | ||
400 | SONIC_WRITE(SONIC_ISR, SONIC_INT_LCD); /* clear the interrupt */ | ||
401 | } while((status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)); | ||
402 | return IRQ_HANDLED; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * We have a good packet(s), pass it/them up the network stack. | ||
407 | */ | ||
408 | static void sonic_rx(struct net_device *dev) | ||
409 | { | ||
410 | struct sonic_local *lp = netdev_priv(dev); | ||
411 | int status; | ||
412 | int entry = lp->cur_rx; | ||
413 | |||
414 | while (sonic_rda_get(dev, entry, SONIC_RD_IN_USE) == 0) { | ||
415 | struct sk_buff *used_skb; | ||
416 | struct sk_buff *new_skb; | ||
417 | dma_addr_t new_laddr; | ||
418 | u16 bufadr_l; | ||
419 | u16 bufadr_h; | ||
420 | int pkt_len; | ||
421 | |||
422 | status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); | ||
423 | if (status & SONIC_RCR_PRX) { | ||
424 | /* Malloc up new buffer. */ | ||
425 | new_skb = dev_alloc_skb(SONIC_RBSIZE + 2); | ||
426 | if (new_skb == NULL) { | ||
427 | printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); | ||
428 | lp->stats.rx_dropped++; | ||
429 | break; | ||
430 | } | ||
431 | /* provide 16 byte IP header alignment unless DMA requires otherwise */ | ||
432 | if(SONIC_BUS_SCALE(lp->dma_bitmode) == 2) | ||
433 | skb_reserve(new_skb, 2); | ||
434 | |||
435 | new_laddr = dma_map_single(lp->device, skb_put(new_skb, SONIC_RBSIZE), | ||
436 | SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
437 | if (!new_laddr) { | ||
438 | dev_kfree_skb(new_skb); | ||
439 | printk(KERN_ERR "%s: Failed to map rx buffer, dropping packet.\n", dev->name); | ||
440 | lp->stats.rx_dropped++; | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | /* now we have a new skb to replace it, pass the used one up the stack */ | ||
445 | dma_unmap_single(lp->device, lp->rx_laddr[entry], SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
446 | used_skb = lp->rx_skb[entry]; | ||
447 | pkt_len = sonic_rda_get(dev, entry, SONIC_RD_PKTLEN); | ||
448 | skb_trim(used_skb, pkt_len); | ||
449 | used_skb->protocol = eth_type_trans(used_skb, dev); | ||
450 | netif_rx(used_skb); | ||
451 | lp->stats.rx_packets++; | ||
452 | lp->stats.rx_bytes += pkt_len; | ||
453 | |||
454 | /* and insert the new skb */ | ||
455 | lp->rx_laddr[entry] = new_laddr; | ||
456 | lp->rx_skb[entry] = new_skb; | ||
457 | |||
458 | bufadr_l = (unsigned long)new_laddr & 0xffff; | ||
459 | bufadr_h = (unsigned long)new_laddr >> 16; | ||
460 | sonic_rra_put(dev, entry, SONIC_RR_BUFADR_L, bufadr_l); | ||
461 | sonic_rra_put(dev, entry, SONIC_RR_BUFADR_H, bufadr_h); | ||
462 | } else { | ||
463 | /* This should only happen, if we enable accepting broken packets. */ | ||
464 | lp->stats.rx_errors++; | ||
465 | if (status & SONIC_RCR_FAER) | ||
466 | lp->stats.rx_frame_errors++; | ||
467 | if (status & SONIC_RCR_CRCR) | ||
468 | lp->stats.rx_crc_errors++; | ||
469 | } | ||
470 | if (status & SONIC_RCR_LPKT) { | ||
471 | /* | ||
472 | * this was the last packet out of the current receive buffer | ||
473 | * give the buffer back to the SONIC | ||
474 | */ | ||
475 | lp->cur_rwp += SIZEOF_SONIC_RR * SONIC_BUS_SCALE(lp->dma_bitmode); | ||
476 | if (lp->cur_rwp >= lp->rra_end) lp->cur_rwp = lp->rra_laddr & 0xffff; | ||
477 | SONIC_WRITE(SONIC_RWP, lp->cur_rwp); | ||
478 | if (SONIC_READ(SONIC_ISR) & SONIC_INT_RBE) { | ||
479 | if (sonic_debug > 2) | ||
480 | printk("%s: rx buffer exhausted\n", dev->name); | ||
481 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); /* clear the flag */ | ||
482 | } | ||
483 | } else | ||
484 | printk(KERN_ERR "%s: rx desc without RCR_LPKT. Shouldn't happen !?\n", | ||
485 | dev->name); | ||
486 | /* | ||
487 | * give back the descriptor | ||
488 | */ | ||
489 | sonic_rda_put(dev, entry, SONIC_RD_LINK, | ||
490 | sonic_rda_get(dev, entry, SONIC_RD_LINK) | SONIC_EOL); | ||
491 | sonic_rda_put(dev, entry, SONIC_RD_IN_USE, 1); | ||
492 | sonic_rda_put(dev, lp->eol_rx, SONIC_RD_LINK, | ||
493 | sonic_rda_get(dev, lp->eol_rx, SONIC_RD_LINK) & ~SONIC_EOL); | ||
494 | lp->eol_rx = entry; | ||
495 | lp->cur_rx = entry = (entry + 1) & SONIC_RDS_MASK; | ||
496 | } | ||
497 | /* | ||
498 | * If any worth-while packets have been received, netif_rx() | ||
499 | * has done a mark_bh(NET_BH) for us and will work on them | ||
500 | * when we get to the bottom-half routine. | ||
501 | */ | ||
502 | } | ||
503 | |||
504 | |||
505 | /* | ||
506 | * Get the current statistics. | ||
507 | * This may be called with the device open or closed. | ||
508 | */ | ||
509 | static struct net_device_stats *sonic_get_stats(struct net_device *dev) | ||
510 | { | ||
511 | struct sonic_local *lp = netdev_priv(dev); | ||
512 | |||
513 | /* read the tally counter from the SONIC and reset them */ | ||
514 | lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT); | ||
515 | SONIC_WRITE(SONIC_CRCT, 0xffff); | ||
516 | lp->stats.rx_frame_errors += SONIC_READ(SONIC_FAET); | ||
517 | SONIC_WRITE(SONIC_FAET, 0xffff); | ||
518 | lp->stats.rx_missed_errors += SONIC_READ(SONIC_MPT); | ||
519 | SONIC_WRITE(SONIC_MPT, 0xffff); | ||
520 | |||
521 | return &lp->stats; | ||
522 | } | ||
523 | |||
524 | |||
525 | /* | ||
526 | * Set or clear the multicast filter for this adaptor. | ||
527 | */ | ||
528 | static void sonic_multicast_list(struct net_device *dev) | ||
529 | { | ||
530 | struct sonic_local *lp = netdev_priv(dev); | ||
531 | unsigned int rcr; | ||
532 | struct netdev_hw_addr *ha; | ||
533 | unsigned char *addr; | ||
534 | int i; | ||
535 | |||
536 | rcr = SONIC_READ(SONIC_RCR) & ~(SONIC_RCR_PRO | SONIC_RCR_AMC); | ||
537 | rcr |= SONIC_RCR_BRD; /* accept broadcast packets */ | ||
538 | |||
539 | if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */ | ||
540 | rcr |= SONIC_RCR_PRO; | ||
541 | } else { | ||
542 | if ((dev->flags & IFF_ALLMULTI) || | ||
543 | (netdev_mc_count(dev) > 15)) { | ||
544 | rcr |= SONIC_RCR_AMC; | ||
545 | } else { | ||
546 | if (sonic_debug > 2) | ||
547 | printk("sonic_multicast_list: mc_count %d\n", | ||
548 | netdev_mc_count(dev)); | ||
549 | sonic_set_cam_enable(dev, 1); /* always enable our own address */ | ||
550 | i = 1; | ||
551 | netdev_for_each_mc_addr(ha, dev) { | ||
552 | addr = ha->addr; | ||
553 | sonic_cda_put(dev, i, SONIC_CD_CAP0, addr[1] << 8 | addr[0]); | ||
554 | sonic_cda_put(dev, i, SONIC_CD_CAP1, addr[3] << 8 | addr[2]); | ||
555 | sonic_cda_put(dev, i, SONIC_CD_CAP2, addr[5] << 8 | addr[4]); | ||
556 | sonic_set_cam_enable(dev, sonic_get_cam_enable(dev) | (1 << i)); | ||
557 | i++; | ||
558 | } | ||
559 | SONIC_WRITE(SONIC_CDC, 16); | ||
560 | /* issue Load CAM command */ | ||
561 | SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff); | ||
562 | SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM); | ||
563 | } | ||
564 | } | ||
565 | |||
566 | if (sonic_debug > 2) | ||
567 | printk("sonic_multicast_list: setting RCR=%x\n", rcr); | ||
568 | |||
569 | SONIC_WRITE(SONIC_RCR, rcr); | ||
570 | } | ||
571 | |||
572 | |||
573 | /* | ||
574 | * Initialize the SONIC ethernet controller. | ||
575 | */ | ||
576 | static int sonic_init(struct net_device *dev) | ||
577 | { | ||
578 | unsigned int cmd; | ||
579 | struct sonic_local *lp = netdev_priv(dev); | ||
580 | int i; | ||
581 | |||
582 | /* | ||
583 | * put the Sonic into software-reset mode and | ||
584 | * disable all interrupts | ||
585 | */ | ||
586 | SONIC_WRITE(SONIC_IMR, 0); | ||
587 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
588 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | ||
589 | |||
590 | /* | ||
591 | * clear software reset flag, disable receiver, clear and | ||
592 | * enable interrupts, then completely initialize the SONIC | ||
593 | */ | ||
594 | SONIC_WRITE(SONIC_CMD, 0); | ||
595 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS); | ||
596 | |||
597 | /* | ||
598 | * initialize the receive resource area | ||
599 | */ | ||
600 | if (sonic_debug > 2) | ||
601 | printk("sonic_init: initialize receive resource area\n"); | ||
602 | |||
603 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
604 | u16 bufadr_l = (unsigned long)lp->rx_laddr[i] & 0xffff; | ||
605 | u16 bufadr_h = (unsigned long)lp->rx_laddr[i] >> 16; | ||
606 | sonic_rra_put(dev, i, SONIC_RR_BUFADR_L, bufadr_l); | ||
607 | sonic_rra_put(dev, i, SONIC_RR_BUFADR_H, bufadr_h); | ||
608 | sonic_rra_put(dev, i, SONIC_RR_BUFSIZE_L, SONIC_RBSIZE >> 1); | ||
609 | sonic_rra_put(dev, i, SONIC_RR_BUFSIZE_H, 0); | ||
610 | } | ||
611 | |||
612 | /* initialize all RRA registers */ | ||
613 | lp->rra_end = (lp->rra_laddr + SONIC_NUM_RRS * SIZEOF_SONIC_RR * | ||
614 | SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; | ||
615 | lp->cur_rwp = (lp->rra_laddr + (SONIC_NUM_RRS - 1) * SIZEOF_SONIC_RR * | ||
616 | SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; | ||
617 | |||
618 | SONIC_WRITE(SONIC_RSA, lp->rra_laddr & 0xffff); | ||
619 | SONIC_WRITE(SONIC_REA, lp->rra_end); | ||
620 | SONIC_WRITE(SONIC_RRP, lp->rra_laddr & 0xffff); | ||
621 | SONIC_WRITE(SONIC_RWP, lp->cur_rwp); | ||
622 | SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16); | ||
623 | SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE >> 1) - (lp->dma_bitmode ? 2 : 1)); | ||
624 | |||
625 | /* load the resource pointers */ | ||
626 | if (sonic_debug > 3) | ||
627 | printk("sonic_init: issuing RRRA command\n"); | ||
628 | |||
629 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); | ||
630 | i = 0; | ||
631 | while (i++ < 100) { | ||
632 | if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA) | ||
633 | break; | ||
634 | } | ||
635 | |||
636 | if (sonic_debug > 2) | ||
637 | printk("sonic_init: status=%x i=%d\n", SONIC_READ(SONIC_CMD), i); | ||
638 | |||
639 | /* | ||
640 | * Initialize the receive descriptors so that they | ||
641 | * become a circular linked list, ie. let the last | ||
642 | * descriptor point to the first again. | ||
643 | */ | ||
644 | if (sonic_debug > 2) | ||
645 | printk("sonic_init: initialize receive descriptors\n"); | ||
646 | for (i=0; i<SONIC_NUM_RDS; i++) { | ||
647 | sonic_rda_put(dev, i, SONIC_RD_STATUS, 0); | ||
648 | sonic_rda_put(dev, i, SONIC_RD_PKTLEN, 0); | ||
649 | sonic_rda_put(dev, i, SONIC_RD_PKTPTR_L, 0); | ||
650 | sonic_rda_put(dev, i, SONIC_RD_PKTPTR_H, 0); | ||
651 | sonic_rda_put(dev, i, SONIC_RD_SEQNO, 0); | ||
652 | sonic_rda_put(dev, i, SONIC_RD_IN_USE, 1); | ||
653 | sonic_rda_put(dev, i, SONIC_RD_LINK, | ||
654 | lp->rda_laddr + | ||
655 | ((i+1) * SIZEOF_SONIC_RD * SONIC_BUS_SCALE(lp->dma_bitmode))); | ||
656 | } | ||
657 | /* fix last descriptor */ | ||
658 | sonic_rda_put(dev, SONIC_NUM_RDS - 1, SONIC_RD_LINK, | ||
659 | (lp->rda_laddr & 0xffff) | SONIC_EOL); | ||
660 | lp->eol_rx = SONIC_NUM_RDS - 1; | ||
661 | lp->cur_rx = 0; | ||
662 | SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16); | ||
663 | SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff); | ||
664 | |||
665 | /* | ||
666 | * initialize transmit descriptors | ||
667 | */ | ||
668 | if (sonic_debug > 2) | ||
669 | printk("sonic_init: initialize transmit descriptors\n"); | ||
670 | for (i = 0; i < SONIC_NUM_TDS; i++) { | ||
671 | sonic_tda_put(dev, i, SONIC_TD_STATUS, 0); | ||
672 | sonic_tda_put(dev, i, SONIC_TD_CONFIG, 0); | ||
673 | sonic_tda_put(dev, i, SONIC_TD_PKTSIZE, 0); | ||
674 | sonic_tda_put(dev, i, SONIC_TD_FRAG_COUNT, 0); | ||
675 | sonic_tda_put(dev, i, SONIC_TD_LINK, | ||
676 | (lp->tda_laddr & 0xffff) + | ||
677 | (i + 1) * SIZEOF_SONIC_TD * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
678 | lp->tx_skb[i] = NULL; | ||
679 | } | ||
680 | /* fix last descriptor */ | ||
681 | sonic_tda_put(dev, SONIC_NUM_TDS - 1, SONIC_TD_LINK, | ||
682 | (lp->tda_laddr & 0xffff)); | ||
683 | |||
684 | SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16); | ||
685 | SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff); | ||
686 | lp->cur_tx = lp->next_tx = 0; | ||
687 | lp->eol_tx = SONIC_NUM_TDS - 1; | ||
688 | |||
689 | /* | ||
690 | * put our own address to CAM desc[0] | ||
691 | */ | ||
692 | sonic_cda_put(dev, 0, SONIC_CD_CAP0, dev->dev_addr[1] << 8 | dev->dev_addr[0]); | ||
693 | sonic_cda_put(dev, 0, SONIC_CD_CAP1, dev->dev_addr[3] << 8 | dev->dev_addr[2]); | ||
694 | sonic_cda_put(dev, 0, SONIC_CD_CAP2, dev->dev_addr[5] << 8 | dev->dev_addr[4]); | ||
695 | sonic_set_cam_enable(dev, 1); | ||
696 | |||
697 | for (i = 0; i < 16; i++) | ||
698 | sonic_cda_put(dev, i, SONIC_CD_ENTRY_POINTER, i); | ||
699 | |||
700 | /* | ||
701 | * initialize CAM registers | ||
702 | */ | ||
703 | SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff); | ||
704 | SONIC_WRITE(SONIC_CDC, 16); | ||
705 | |||
706 | /* | ||
707 | * load the CAM | ||
708 | */ | ||
709 | SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM); | ||
710 | |||
711 | i = 0; | ||
712 | while (i++ < 100) { | ||
713 | if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD) | ||
714 | break; | ||
715 | } | ||
716 | if (sonic_debug > 2) { | ||
717 | printk("sonic_init: CMD=%x, ISR=%x\n, i=%d", | ||
718 | SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR), i); | ||
719 | } | ||
720 | |||
721 | /* | ||
722 | * enable receiver, disable loopback | ||
723 | * and enable all interrupts | ||
724 | */ | ||
725 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RXEN | SONIC_CR_STP); | ||
726 | SONIC_WRITE(SONIC_RCR, SONIC_RCR_DEFAULT); | ||
727 | SONIC_WRITE(SONIC_TCR, SONIC_TCR_DEFAULT); | ||
728 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
729 | SONIC_WRITE(SONIC_IMR, SONIC_IMR_DEFAULT); | ||
730 | |||
731 | cmd = SONIC_READ(SONIC_CMD); | ||
732 | if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) | ||
733 | printk(KERN_ERR "sonic_init: failed, status=%x\n", cmd); | ||
734 | |||
735 | if (sonic_debug > 2) | ||
736 | printk("sonic_init: new status=%x\n", | ||
737 | SONIC_READ(SONIC_CMD)); | ||
738 | |||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/natsemi/sonic.h b/drivers/net/ethernet/natsemi/sonic.h new file mode 100644 index 000000000000..07091dd27e5d --- /dev/null +++ b/drivers/net/ethernet/natsemi/sonic.h | |||
@@ -0,0 +1,450 @@ | |||
1 | /* | ||
2 | * Header file for sonic.c | ||
3 | * | ||
4 | * (C) Waldorf Electronics, Germany | ||
5 | * Written by Andreas Busse | ||
6 | * | ||
7 | * NOTE: most of the structure definitions here are endian dependent. | ||
8 | * If you want to use this driver on big endian machines, the data | ||
9 | * and pad structure members must be exchanged. Also, the structures | ||
10 | * need to be changed accordingly to the bus size. | ||
11 | * | ||
12 | * 981229 MSch: did just that for the 68k Mac port (32 bit, big endian) | ||
13 | * | ||
14 | * 990611 David Huggins-Daines <dhd@debian.org>: This machine abstraction | ||
15 | * does not cope with 16-bit bus sizes very well. Therefore I have | ||
16 | * rewritten it with ugly macros and evil inlines. | ||
17 | * | ||
18 | * 050625 Finn Thain: introduced more 32-bit cards and dhd's support | ||
19 | * for 16-bit cards (from the mac68k project). | ||
20 | */ | ||
21 | |||
22 | #ifndef SONIC_H | ||
23 | #define SONIC_H | ||
24 | |||
25 | |||
26 | /* | ||
27 | * SONIC register offsets | ||
28 | */ | ||
29 | |||
30 | #define SONIC_CMD 0x00 | ||
31 | #define SONIC_DCR 0x01 | ||
32 | #define SONIC_RCR 0x02 | ||
33 | #define SONIC_TCR 0x03 | ||
34 | #define SONIC_IMR 0x04 | ||
35 | #define SONIC_ISR 0x05 | ||
36 | |||
37 | #define SONIC_UTDA 0x06 | ||
38 | #define SONIC_CTDA 0x07 | ||
39 | |||
40 | #define SONIC_URDA 0x0d | ||
41 | #define SONIC_CRDA 0x0e | ||
42 | #define SONIC_EOBC 0x13 | ||
43 | #define SONIC_URRA 0x14 | ||
44 | #define SONIC_RSA 0x15 | ||
45 | #define SONIC_REA 0x16 | ||
46 | #define SONIC_RRP 0x17 | ||
47 | #define SONIC_RWP 0x18 | ||
48 | #define SONIC_RSC 0x2b | ||
49 | |||
50 | #define SONIC_CEP 0x21 | ||
51 | #define SONIC_CAP2 0x22 | ||
52 | #define SONIC_CAP1 0x23 | ||
53 | #define SONIC_CAP0 0x24 | ||
54 | #define SONIC_CE 0x25 | ||
55 | #define SONIC_CDP 0x26 | ||
56 | #define SONIC_CDC 0x27 | ||
57 | |||
58 | #define SONIC_WT0 0x29 | ||
59 | #define SONIC_WT1 0x2a | ||
60 | |||
61 | #define SONIC_SR 0x28 | ||
62 | |||
63 | |||
64 | /* test-only registers */ | ||
65 | |||
66 | #define SONIC_TPS 0x08 | ||
67 | #define SONIC_TFC 0x09 | ||
68 | #define SONIC_TSA0 0x0a | ||
69 | #define SONIC_TSA1 0x0b | ||
70 | #define SONIC_TFS 0x0c | ||
71 | |||
72 | #define SONIC_CRBA0 0x0f | ||
73 | #define SONIC_CRBA1 0x10 | ||
74 | #define SONIC_RBWC0 0x11 | ||
75 | #define SONIC_RBWC1 0x12 | ||
76 | #define SONIC_TTDA 0x20 | ||
77 | #define SONIC_MDT 0x2f | ||
78 | |||
79 | #define SONIC_TRBA0 0x19 | ||
80 | #define SONIC_TRBA1 0x1a | ||
81 | #define SONIC_TBWC0 0x1b | ||
82 | #define SONIC_TBWC1 0x1c | ||
83 | #define SONIC_LLFA 0x1f | ||
84 | |||
85 | #define SONIC_ADDR0 0x1d | ||
86 | #define SONIC_ADDR1 0x1e | ||
87 | |||
88 | /* | ||
89 | * Error counters | ||
90 | */ | ||
91 | |||
92 | #define SONIC_CRCT 0x2c | ||
93 | #define SONIC_FAET 0x2d | ||
94 | #define SONIC_MPT 0x2e | ||
95 | |||
96 | #define SONIC_DCR2 0x3f | ||
97 | |||
98 | /* | ||
99 | * SONIC command bits | ||
100 | */ | ||
101 | |||
102 | #define SONIC_CR_LCAM 0x0200 | ||
103 | #define SONIC_CR_RRRA 0x0100 | ||
104 | #define SONIC_CR_RST 0x0080 | ||
105 | #define SONIC_CR_ST 0x0020 | ||
106 | #define SONIC_CR_STP 0x0010 | ||
107 | #define SONIC_CR_RXEN 0x0008 | ||
108 | #define SONIC_CR_RXDIS 0x0004 | ||
109 | #define SONIC_CR_TXP 0x0002 | ||
110 | #define SONIC_CR_HTX 0x0001 | ||
111 | |||
112 | /* | ||
113 | * SONIC data configuration bits | ||
114 | */ | ||
115 | |||
116 | #define SONIC_DCR_EXBUS 0x8000 | ||
117 | #define SONIC_DCR_LBR 0x2000 | ||
118 | #define SONIC_DCR_PO1 0x1000 | ||
119 | #define SONIC_DCR_PO0 0x0800 | ||
120 | #define SONIC_DCR_SBUS 0x0400 | ||
121 | #define SONIC_DCR_USR1 0x0200 | ||
122 | #define SONIC_DCR_USR0 0x0100 | ||
123 | #define SONIC_DCR_WC1 0x0080 | ||
124 | #define SONIC_DCR_WC0 0x0040 | ||
125 | #define SONIC_DCR_DW 0x0020 | ||
126 | #define SONIC_DCR_BMS 0x0010 | ||
127 | #define SONIC_DCR_RFT1 0x0008 | ||
128 | #define SONIC_DCR_RFT0 0x0004 | ||
129 | #define SONIC_DCR_TFT1 0x0002 | ||
130 | #define SONIC_DCR_TFT0 0x0001 | ||
131 | |||
132 | /* | ||
133 | * Constants for the SONIC receive control register. | ||
134 | */ | ||
135 | |||
136 | #define SONIC_RCR_ERR 0x8000 | ||
137 | #define SONIC_RCR_RNT 0x4000 | ||
138 | #define SONIC_RCR_BRD 0x2000 | ||
139 | #define SONIC_RCR_PRO 0x1000 | ||
140 | #define SONIC_RCR_AMC 0x0800 | ||
141 | #define SONIC_RCR_LB1 0x0400 | ||
142 | #define SONIC_RCR_LB0 0x0200 | ||
143 | |||
144 | #define SONIC_RCR_MC 0x0100 | ||
145 | #define SONIC_RCR_BC 0x0080 | ||
146 | #define SONIC_RCR_LPKT 0x0040 | ||
147 | #define SONIC_RCR_CRS 0x0020 | ||
148 | #define SONIC_RCR_COL 0x0010 | ||
149 | #define SONIC_RCR_CRCR 0x0008 | ||
150 | #define SONIC_RCR_FAER 0x0004 | ||
151 | #define SONIC_RCR_LBK 0x0002 | ||
152 | #define SONIC_RCR_PRX 0x0001 | ||
153 | |||
154 | #define SONIC_RCR_LB_OFF 0 | ||
155 | #define SONIC_RCR_LB_MAC SONIC_RCR_LB0 | ||
156 | #define SONIC_RCR_LB_ENDEC SONIC_RCR_LB1 | ||
157 | #define SONIC_RCR_LB_TRANS (SONIC_RCR_LB0 | SONIC_RCR_LB1) | ||
158 | |||
159 | /* default RCR setup */ | ||
160 | |||
161 | #define SONIC_RCR_DEFAULT (SONIC_RCR_BRD) | ||
162 | |||
163 | |||
164 | /* | ||
165 | * SONIC Transmit Control register bits | ||
166 | */ | ||
167 | |||
168 | #define SONIC_TCR_PINTR 0x8000 | ||
169 | #define SONIC_TCR_POWC 0x4000 | ||
170 | #define SONIC_TCR_CRCI 0x2000 | ||
171 | #define SONIC_TCR_EXDIS 0x1000 | ||
172 | #define SONIC_TCR_EXD 0x0400 | ||
173 | #define SONIC_TCR_DEF 0x0200 | ||
174 | #define SONIC_TCR_NCRS 0x0100 | ||
175 | #define SONIC_TCR_CRLS 0x0080 | ||
176 | #define SONIC_TCR_EXC 0x0040 | ||
177 | #define SONIC_TCR_PMB 0x0008 | ||
178 | #define SONIC_TCR_FU 0x0004 | ||
179 | #define SONIC_TCR_BCM 0x0002 | ||
180 | #define SONIC_TCR_PTX 0x0001 | ||
181 | |||
182 | #define SONIC_TCR_DEFAULT 0x0000 | ||
183 | |||
184 | /* | ||
185 | * Constants for the SONIC_INTERRUPT_MASK and | ||
186 | * SONIC_INTERRUPT_STATUS registers. | ||
187 | */ | ||
188 | |||
189 | #define SONIC_INT_BR 0x4000 | ||
190 | #define SONIC_INT_HBL 0x2000 | ||
191 | #define SONIC_INT_LCD 0x1000 | ||
192 | #define SONIC_INT_PINT 0x0800 | ||
193 | #define SONIC_INT_PKTRX 0x0400 | ||
194 | #define SONIC_INT_TXDN 0x0200 | ||
195 | #define SONIC_INT_TXER 0x0100 | ||
196 | #define SONIC_INT_TC 0x0080 | ||
197 | #define SONIC_INT_RDE 0x0040 | ||
198 | #define SONIC_INT_RBE 0x0020 | ||
199 | #define SONIC_INT_RBAE 0x0010 | ||
200 | #define SONIC_INT_CRC 0x0008 | ||
201 | #define SONIC_INT_FAE 0x0004 | ||
202 | #define SONIC_INT_MP 0x0002 | ||
203 | #define SONIC_INT_RFO 0x0001 | ||
204 | |||
205 | |||
206 | /* | ||
207 | * The interrupts we allow. | ||
208 | */ | ||
209 | |||
210 | #define SONIC_IMR_DEFAULT ( SONIC_INT_BR | \ | ||
211 | SONIC_INT_LCD | \ | ||
212 | SONIC_INT_RFO | \ | ||
213 | SONIC_INT_PKTRX | \ | ||
214 | SONIC_INT_TXDN | \ | ||
215 | SONIC_INT_TXER | \ | ||
216 | SONIC_INT_RDE | \ | ||
217 | SONIC_INT_RBAE | \ | ||
218 | SONIC_INT_CRC | \ | ||
219 | SONIC_INT_FAE | \ | ||
220 | SONIC_INT_MP) | ||
221 | |||
222 | |||
223 | #define SONIC_EOL 0x0001 | ||
224 | #define CAM_DESCRIPTORS 16 | ||
225 | |||
226 | /* Offsets in the various DMA buffers accessed by the SONIC */ | ||
227 | |||
228 | #define SONIC_BITMODE16 0 | ||
229 | #define SONIC_BITMODE32 1 | ||
230 | #define SONIC_BUS_SCALE(bitmode) ((bitmode) ? 4 : 2) | ||
231 | /* Note! These are all measured in bus-size units, so use SONIC_BUS_SCALE */ | ||
232 | #define SIZEOF_SONIC_RR 4 | ||
233 | #define SONIC_RR_BUFADR_L 0 | ||
234 | #define SONIC_RR_BUFADR_H 1 | ||
235 | #define SONIC_RR_BUFSIZE_L 2 | ||
236 | #define SONIC_RR_BUFSIZE_H 3 | ||
237 | |||
238 | #define SIZEOF_SONIC_RD 7 | ||
239 | #define SONIC_RD_STATUS 0 | ||
240 | #define SONIC_RD_PKTLEN 1 | ||
241 | #define SONIC_RD_PKTPTR_L 2 | ||
242 | #define SONIC_RD_PKTPTR_H 3 | ||
243 | #define SONIC_RD_SEQNO 4 | ||
244 | #define SONIC_RD_LINK 5 | ||
245 | #define SONIC_RD_IN_USE 6 | ||
246 | |||
247 | #define SIZEOF_SONIC_TD 8 | ||
248 | #define SONIC_TD_STATUS 0 | ||
249 | #define SONIC_TD_CONFIG 1 | ||
250 | #define SONIC_TD_PKTSIZE 2 | ||
251 | #define SONIC_TD_FRAG_COUNT 3 | ||
252 | #define SONIC_TD_FRAG_PTR_L 4 | ||
253 | #define SONIC_TD_FRAG_PTR_H 5 | ||
254 | #define SONIC_TD_FRAG_SIZE 6 | ||
255 | #define SONIC_TD_LINK 7 | ||
256 | |||
257 | #define SIZEOF_SONIC_CD 4 | ||
258 | #define SONIC_CD_ENTRY_POINTER 0 | ||
259 | #define SONIC_CD_CAP0 1 | ||
260 | #define SONIC_CD_CAP1 2 | ||
261 | #define SONIC_CD_CAP2 3 | ||
262 | |||
263 | #define SIZEOF_SONIC_CDA ((CAM_DESCRIPTORS * SIZEOF_SONIC_CD) + 1) | ||
264 | #define SONIC_CDA_CAM_ENABLE (CAM_DESCRIPTORS * SIZEOF_SONIC_CD) | ||
265 | |||
266 | /* | ||
267 | * Some tunables for the buffer areas. Power of 2 is required | ||
268 | * the current driver uses one receive buffer for each descriptor. | ||
269 | * | ||
270 | * MSch: use more buffer space for the slow m68k Macs! | ||
271 | */ | ||
272 | #define SONIC_NUM_RRS 16 /* number of receive resources */ | ||
273 | #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ | ||
274 | #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ | ||
275 | |||
276 | #define SONIC_RDS_MASK (SONIC_NUM_RDS-1) | ||
277 | #define SONIC_TDS_MASK (SONIC_NUM_TDS-1) | ||
278 | |||
279 | #define SONIC_RBSIZE 1520 /* size of one resource buffer */ | ||
280 | |||
281 | /* Again, measured in bus size units! */ | ||
282 | #define SIZEOF_SONIC_DESC (SIZEOF_SONIC_CDA \ | ||
283 | + (SIZEOF_SONIC_TD * SONIC_NUM_TDS) \ | ||
284 | + (SIZEOF_SONIC_RD * SONIC_NUM_RDS) \ | ||
285 | + (SIZEOF_SONIC_RR * SONIC_NUM_RRS)) | ||
286 | |||
287 | /* Information that need to be kept for each board. */ | ||
288 | struct sonic_local { | ||
289 | /* Bus size. 0 == 16 bits, 1 == 32 bits. */ | ||
290 | int dma_bitmode; | ||
291 | /* Register offset within the longword (independent of endianness, | ||
292 | and varies from one type of Macintosh SONIC to another | ||
293 | (Aarrgh)) */ | ||
294 | int reg_offset; | ||
295 | void *descriptors; | ||
296 | /* Crud. These areas have to be within the same 64K. Therefore | ||
297 | we allocate a desriptors page, and point these to places within it. */ | ||
298 | void *cda; /* CAM descriptor area */ | ||
299 | void *tda; /* Transmit descriptor area */ | ||
300 | void *rra; /* Receive resource area */ | ||
301 | void *rda; /* Receive descriptor area */ | ||
302 | struct sk_buff* volatile rx_skb[SONIC_NUM_RRS]; /* packets to be received */ | ||
303 | struct sk_buff* volatile tx_skb[SONIC_NUM_TDS]; /* packets to be transmitted */ | ||
304 | unsigned int tx_len[SONIC_NUM_TDS]; /* lengths of tx DMA mappings */ | ||
305 | /* Logical DMA addresses on MIPS, bus addresses on m68k | ||
306 | * (so "laddr" is a bit misleading) */ | ||
307 | dma_addr_t descriptors_laddr; | ||
308 | u32 cda_laddr; /* logical DMA address of CDA */ | ||
309 | u32 tda_laddr; /* logical DMA address of TDA */ | ||
310 | u32 rra_laddr; /* logical DMA address of RRA */ | ||
311 | u32 rda_laddr; /* logical DMA address of RDA */ | ||
312 | dma_addr_t rx_laddr[SONIC_NUM_RRS]; /* logical DMA addresses of rx skbuffs */ | ||
313 | dma_addr_t tx_laddr[SONIC_NUM_TDS]; /* logical DMA addresses of tx skbuffs */ | ||
314 | unsigned int rra_end; | ||
315 | unsigned int cur_rwp; | ||
316 | unsigned int cur_rx; | ||
317 | unsigned int cur_tx; /* first unacked transmit packet */ | ||
318 | unsigned int eol_rx; | ||
319 | unsigned int eol_tx; /* last unacked transmit packet */ | ||
320 | unsigned int next_tx; /* next free TD */ | ||
321 | struct device *device; /* generic device */ | ||
322 | struct net_device_stats stats; | ||
323 | }; | ||
324 | |||
325 | #define TX_TIMEOUT (3 * HZ) | ||
326 | |||
327 | /* Index to functions, as function prototypes. */ | ||
328 | |||
329 | static int sonic_open(struct net_device *dev); | ||
330 | static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev); | ||
331 | static irqreturn_t sonic_interrupt(int irq, void *dev_id); | ||
332 | static void sonic_rx(struct net_device *dev); | ||
333 | static int sonic_close(struct net_device *dev); | ||
334 | static struct net_device_stats *sonic_get_stats(struct net_device *dev); | ||
335 | static void sonic_multicast_list(struct net_device *dev); | ||
336 | static int sonic_init(struct net_device *dev); | ||
337 | static void sonic_tx_timeout(struct net_device *dev); | ||
338 | |||
339 | /* Internal inlines for reading/writing DMA buffers. Note that bus | ||
340 | size and endianness matter here, whereas they don't for registers, | ||
341 | as far as we can tell. */ | ||
342 | /* OpenBSD calls this "SWO". I'd like to think that sonic_buf_put() | ||
343 | is a much better name. */ | ||
344 | static inline void sonic_buf_put(void* base, int bitmode, | ||
345 | int offset, __u16 val) | ||
346 | { | ||
347 | if (bitmode) | ||
348 | #ifdef __BIG_ENDIAN | ||
349 | ((__u16 *) base + (offset*2))[1] = val; | ||
350 | #else | ||
351 | ((__u16 *) base + (offset*2))[0] = val; | ||
352 | #endif | ||
353 | else | ||
354 | ((__u16 *) base)[offset] = val; | ||
355 | } | ||
356 | |||
357 | static inline __u16 sonic_buf_get(void* base, int bitmode, | ||
358 | int offset) | ||
359 | { | ||
360 | if (bitmode) | ||
361 | #ifdef __BIG_ENDIAN | ||
362 | return ((volatile __u16 *) base + (offset*2))[1]; | ||
363 | #else | ||
364 | return ((volatile __u16 *) base + (offset*2))[0]; | ||
365 | #endif | ||
366 | else | ||
367 | return ((volatile __u16 *) base)[offset]; | ||
368 | } | ||
369 | |||
370 | /* Inlines that you should actually use for reading/writing DMA buffers */ | ||
371 | static inline void sonic_cda_put(struct net_device* dev, int entry, | ||
372 | int offset, __u16 val) | ||
373 | { | ||
374 | struct sonic_local *lp = netdev_priv(dev); | ||
375 | sonic_buf_put(lp->cda, lp->dma_bitmode, | ||
376 | (entry * SIZEOF_SONIC_CD) + offset, val); | ||
377 | } | ||
378 | |||
379 | static inline __u16 sonic_cda_get(struct net_device* dev, int entry, | ||
380 | int offset) | ||
381 | { | ||
382 | struct sonic_local *lp = netdev_priv(dev); | ||
383 | return sonic_buf_get(lp->cda, lp->dma_bitmode, | ||
384 | (entry * SIZEOF_SONIC_CD) + offset); | ||
385 | } | ||
386 | |||
387 | static inline void sonic_set_cam_enable(struct net_device* dev, __u16 val) | ||
388 | { | ||
389 | struct sonic_local *lp = netdev_priv(dev); | ||
390 | sonic_buf_put(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE, val); | ||
391 | } | ||
392 | |||
393 | static inline __u16 sonic_get_cam_enable(struct net_device* dev) | ||
394 | { | ||
395 | struct sonic_local *lp = netdev_priv(dev); | ||
396 | return sonic_buf_get(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE); | ||
397 | } | ||
398 | |||
399 | static inline void sonic_tda_put(struct net_device* dev, int entry, | ||
400 | int offset, __u16 val) | ||
401 | { | ||
402 | struct sonic_local *lp = netdev_priv(dev); | ||
403 | sonic_buf_put(lp->tda, lp->dma_bitmode, | ||
404 | (entry * SIZEOF_SONIC_TD) + offset, val); | ||
405 | } | ||
406 | |||
407 | static inline __u16 sonic_tda_get(struct net_device* dev, int entry, | ||
408 | int offset) | ||
409 | { | ||
410 | struct sonic_local *lp = netdev_priv(dev); | ||
411 | return sonic_buf_get(lp->tda, lp->dma_bitmode, | ||
412 | (entry * SIZEOF_SONIC_TD) + offset); | ||
413 | } | ||
414 | |||
415 | static inline void sonic_rda_put(struct net_device* dev, int entry, | ||
416 | int offset, __u16 val) | ||
417 | { | ||
418 | struct sonic_local *lp = netdev_priv(dev); | ||
419 | sonic_buf_put(lp->rda, lp->dma_bitmode, | ||
420 | (entry * SIZEOF_SONIC_RD) + offset, val); | ||
421 | } | ||
422 | |||
423 | static inline __u16 sonic_rda_get(struct net_device* dev, int entry, | ||
424 | int offset) | ||
425 | { | ||
426 | struct sonic_local *lp = netdev_priv(dev); | ||
427 | return sonic_buf_get(lp->rda, lp->dma_bitmode, | ||
428 | (entry * SIZEOF_SONIC_RD) + offset); | ||
429 | } | ||
430 | |||
431 | static inline void sonic_rra_put(struct net_device* dev, int entry, | ||
432 | int offset, __u16 val) | ||
433 | { | ||
434 | struct sonic_local *lp = netdev_priv(dev); | ||
435 | sonic_buf_put(lp->rra, lp->dma_bitmode, | ||
436 | (entry * SIZEOF_SONIC_RR) + offset, val); | ||
437 | } | ||
438 | |||
439 | static inline __u16 sonic_rra_get(struct net_device* dev, int entry, | ||
440 | int offset) | ||
441 | { | ||
442 | struct sonic_local *lp = netdev_priv(dev); | ||
443 | return sonic_buf_get(lp->rra, lp->dma_bitmode, | ||
444 | (entry * SIZEOF_SONIC_RR) + offset); | ||
445 | } | ||
446 | |||
447 | static const char *version = | ||
448 | "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; | ||
449 | |||
450 | #endif /* SONIC_H */ | ||
diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c new file mode 100644 index 000000000000..9f12026d98e7 --- /dev/null +++ b/drivers/net/ethernet/natsemi/xtsonic.c | |||
@@ -0,0 +1,333 @@ | |||
1 | /* | ||
2 | * xtsonic.c | ||
3 | * | ||
4 | * (C) 2001 - 2007 Tensilica Inc. | ||
5 | * Kevin Chea <kchea@yahoo.com> | ||
6 | * Marc Gauthier <marc@linux-xtensa.org> | ||
7 | * Chris Zankel <chris@zankel.net> | ||
8 | * | ||
9 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
10 | * | ||
11 | * This driver is based on work from Andreas Busse, but most of | ||
12 | * the code is rewritten. | ||
13 | * | ||
14 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) | ||
15 | * | ||
16 | * A driver for the onboard Sonic ethernet controller on the XT2000. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/fcntl.h> | ||
23 | #include <linux/gfp.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/ioport.h> | ||
27 | #include <linux/in.h> | ||
28 | #include <linux/string.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/netdevice.h> | ||
32 | #include <linux/etherdevice.h> | ||
33 | #include <linux/skbuff.h> | ||
34 | #include <linux/platform_device.h> | ||
35 | #include <linux/dma-mapping.h> | ||
36 | #include <linux/slab.h> | ||
37 | |||
38 | #include <asm/io.h> | ||
39 | #include <asm/pgtable.h> | ||
40 | #include <asm/dma.h> | ||
41 | |||
42 | static char xtsonic_string[] = "xtsonic"; | ||
43 | |||
44 | extern unsigned xtboard_nvram_valid(void); | ||
45 | extern void xtboard_get_ether_addr(unsigned char *buf); | ||
46 | |||
47 | #include "sonic.h" | ||
48 | |||
49 | /* | ||
50 | * According to the documentation for the Sonic ethernet controller, | ||
51 | * EOBC should be 760 words (1520 bytes) for 32-bit applications, and, | ||
52 | * as such, 2 words less than the buffer size. The value for RBSIZE | ||
53 | * defined in sonic.h, however is only 1520. | ||
54 | * | ||
55 | * (Note that in 16-bit configurations, EOBC is 759 words (1518 bytes) and | ||
56 | * RBSIZE 1520 bytes) | ||
57 | */ | ||
58 | #undef SONIC_RBSIZE | ||
59 | #define SONIC_RBSIZE 1524 | ||
60 | |||
61 | /* | ||
62 | * The chip provides 256 byte register space. | ||
63 | */ | ||
64 | #define SONIC_MEM_SIZE 0x100 | ||
65 | |||
66 | /* | ||
67 | * Macros to access SONIC registers | ||
68 | */ | ||
69 | #define SONIC_READ(reg) \ | ||
70 | (0xffff & *((volatile unsigned int *)dev->base_addr+reg)) | ||
71 | |||
72 | #define SONIC_WRITE(reg,val) \ | ||
73 | *((volatile unsigned int *)dev->base_addr+reg) = val | ||
74 | |||
75 | |||
76 | /* Use 0 for production, 1 for verification, and >2 for debug */ | ||
77 | #ifdef SONIC_DEBUG | ||
78 | static unsigned int sonic_debug = SONIC_DEBUG; | ||
79 | #else | ||
80 | static unsigned int sonic_debug = 1; | ||
81 | #endif | ||
82 | |||
83 | /* | ||
84 | * We cannot use station (ethernet) address prefixes to detect the | ||
85 | * sonic controller since these are board manufacturer depended. | ||
86 | * So we check for known Silicon Revision IDs instead. | ||
87 | */ | ||
88 | static unsigned short known_revisions[] = | ||
89 | { | ||
90 | 0x101, /* SONIC 83934 */ | ||
91 | 0xffff /* end of list */ | ||
92 | }; | ||
93 | |||
94 | static int xtsonic_open(struct net_device *dev) | ||
95 | { | ||
96 | int retval; | ||
97 | |||
98 | retval = request_irq(dev->irq, sonic_interrupt, IRQF_DISABLED, | ||
99 | "sonic", dev); | ||
100 | if (retval) { | ||
101 | printk(KERN_ERR "%s: unable to get IRQ %d.\n", | ||
102 | dev->name, dev->irq); | ||
103 | return -EAGAIN; | ||
104 | } | ||
105 | |||
106 | retval = sonic_open(dev); | ||
107 | if (retval) | ||
108 | free_irq(dev->irq, dev); | ||
109 | return retval; | ||
110 | } | ||
111 | |||
112 | static int xtsonic_close(struct net_device *dev) | ||
113 | { | ||
114 | int err; | ||
115 | err = sonic_close(dev); | ||
116 | free_irq(dev->irq, dev); | ||
117 | return err; | ||
118 | } | ||
119 | |||
120 | static const struct net_device_ops xtsonic_netdev_ops = { | ||
121 | .ndo_open = xtsonic_open, | ||
122 | .ndo_stop = xtsonic_close, | ||
123 | .ndo_start_xmit = sonic_send_packet, | ||
124 | .ndo_get_stats = sonic_get_stats, | ||
125 | .ndo_set_multicast_list = sonic_multicast_list, | ||
126 | .ndo_tx_timeout = sonic_tx_timeout, | ||
127 | .ndo_validate_addr = eth_validate_addr, | ||
128 | .ndo_change_mtu = eth_change_mtu, | ||
129 | .ndo_set_mac_address = eth_mac_addr, | ||
130 | }; | ||
131 | |||
132 | static int __init sonic_probe1(struct net_device *dev) | ||
133 | { | ||
134 | static unsigned version_printed = 0; | ||
135 | unsigned int silicon_revision; | ||
136 | struct sonic_local *lp = netdev_priv(dev); | ||
137 | unsigned int base_addr = dev->base_addr; | ||
138 | int i; | ||
139 | int err = 0; | ||
140 | |||
141 | if (!request_mem_region(base_addr, 0x100, xtsonic_string)) | ||
142 | return -EBUSY; | ||
143 | |||
144 | /* | ||
145 | * get the Silicon Revision ID. If this is one of the known | ||
146 | * one assume that we found a SONIC ethernet controller at | ||
147 | * the expected location. | ||
148 | */ | ||
149 | silicon_revision = SONIC_READ(SONIC_SR); | ||
150 | if (sonic_debug > 1) | ||
151 | printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision); | ||
152 | |||
153 | i = 0; | ||
154 | while ((known_revisions[i] != 0xffff) && | ||
155 | (known_revisions[i] != silicon_revision)) | ||
156 | i++; | ||
157 | |||
158 | if (known_revisions[i] == 0xffff) { | ||
159 | printk("SONIC ethernet controller not found (0x%4x)\n", | ||
160 | silicon_revision); | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | |||
164 | if (sonic_debug && version_printed++ == 0) | ||
165 | printk(version); | ||
166 | |||
167 | /* | ||
168 | * Put the sonic into software reset, then retrieve ethernet address. | ||
169 | * Note: we are assuming that the boot-loader has initialized the cam. | ||
170 | */ | ||
171 | SONIC_WRITE(SONIC_CMD,SONIC_CR_RST); | ||
172 | SONIC_WRITE(SONIC_DCR, | ||
173 | SONIC_DCR_WC0|SONIC_DCR_DW|SONIC_DCR_LBR|SONIC_DCR_SBUS); | ||
174 | SONIC_WRITE(SONIC_CEP,0); | ||
175 | SONIC_WRITE(SONIC_IMR,0); | ||
176 | |||
177 | SONIC_WRITE(SONIC_CMD,SONIC_CR_RST); | ||
178 | SONIC_WRITE(SONIC_CEP,0); | ||
179 | |||
180 | for (i=0; i<3; i++) { | ||
181 | unsigned int val = SONIC_READ(SONIC_CAP0-i); | ||
182 | dev->dev_addr[i*2] = val; | ||
183 | dev->dev_addr[i*2+1] = val >> 8; | ||
184 | } | ||
185 | |||
186 | /* Initialize the device structure. */ | ||
187 | |||
188 | lp->dma_bitmode = SONIC_BITMODE32; | ||
189 | |||
190 | /* | ||
191 | * Allocate local private descriptor areas in uncached space. | ||
192 | * The entire structure must be located within the same 64kb segment. | ||
193 | * A simple way to ensure this is to allocate twice the | ||
194 | * size of the structure -- given that the structure is | ||
195 | * much less than 64 kB, at least one of the halves of | ||
196 | * the allocated area will be contained entirely in 64 kB. | ||
197 | * We also allocate extra space for a pointer to allow freeing | ||
198 | * this structure later on (in xtsonic_cleanup_module()). | ||
199 | */ | ||
200 | lp->descriptors = | ||
201 | dma_alloc_coherent(lp->device, | ||
202 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
203 | &lp->descriptors_laddr, GFP_KERNEL); | ||
204 | |||
205 | if (lp->descriptors == NULL) { | ||
206 | printk(KERN_ERR "%s: couldn't alloc DMA memory for " | ||
207 | " descriptors.\n", dev_name(lp->device)); | ||
208 | goto out; | ||
209 | } | ||
210 | |||
211 | lp->cda = lp->descriptors; | ||
212 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA | ||
213 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
214 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
215 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
216 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
217 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
218 | |||
219 | /* get the virtual dma address */ | ||
220 | |||
221 | lp->cda_laddr = lp->descriptors_laddr; | ||
222 | lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA | ||
223 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
224 | lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
225 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
226 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
227 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
228 | |||
229 | dev->netdev_ops = &xtsonic_netdev_ops; | ||
230 | dev->watchdog_timeo = TX_TIMEOUT; | ||
231 | |||
232 | /* | ||
233 | * clear tally counter | ||
234 | */ | ||
235 | SONIC_WRITE(SONIC_CRCT,0xffff); | ||
236 | SONIC_WRITE(SONIC_FAET,0xffff); | ||
237 | SONIC_WRITE(SONIC_MPT,0xffff); | ||
238 | |||
239 | return 0; | ||
240 | out: | ||
241 | release_region(dev->base_addr, SONIC_MEM_SIZE); | ||
242 | return err; | ||
243 | } | ||
244 | |||
245 | |||
246 | /* | ||
247 | * Probe for a SONIC ethernet controller on an XT2000 board. | ||
248 | * Actually probing is superfluous but we're paranoid. | ||
249 | */ | ||
250 | |||
251 | int __devinit xtsonic_probe(struct platform_device *pdev) | ||
252 | { | ||
253 | struct net_device *dev; | ||
254 | struct sonic_local *lp; | ||
255 | struct resource *resmem, *resirq; | ||
256 | int err = 0; | ||
257 | |||
258 | if ((resmem = platform_get_resource(pdev, IORESOURCE_MEM, 0)) == NULL) | ||
259 | return -ENODEV; | ||
260 | |||
261 | if ((resirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0)) == NULL) | ||
262 | return -ENODEV; | ||
263 | |||
264 | if ((dev = alloc_etherdev(sizeof(struct sonic_local))) == NULL) | ||
265 | return -ENOMEM; | ||
266 | |||
267 | lp = netdev_priv(dev); | ||
268 | lp->device = &pdev->dev; | ||
269 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
270 | netdev_boot_setup_check(dev); | ||
271 | |||
272 | dev->base_addr = resmem->start; | ||
273 | dev->irq = resirq->start; | ||
274 | |||
275 | if ((err = sonic_probe1(dev))) | ||
276 | goto out; | ||
277 | if ((err = register_netdev(dev))) | ||
278 | goto out1; | ||
279 | |||
280 | printk("%s: SONIC ethernet @%08lx, MAC %pM, IRQ %d\n", dev->name, | ||
281 | dev->base_addr, dev->dev_addr, dev->irq); | ||
282 | |||
283 | return 0; | ||
284 | |||
285 | out1: | ||
286 | release_region(dev->base_addr, SONIC_MEM_SIZE); | ||
287 | out: | ||
288 | free_netdev(dev); | ||
289 | |||
290 | return err; | ||
291 | } | ||
292 | |||
293 | MODULE_DESCRIPTION("Xtensa XT2000 SONIC ethernet driver"); | ||
294 | module_param(sonic_debug, int, 0); | ||
295 | MODULE_PARM_DESC(sonic_debug, "xtsonic debug level (1-4)"); | ||
296 | |||
297 | #include "sonic.c" | ||
298 | |||
299 | static int __devexit xtsonic_device_remove (struct platform_device *pdev) | ||
300 | { | ||
301 | struct net_device *dev = platform_get_drvdata(pdev); | ||
302 | struct sonic_local *lp = netdev_priv(dev); | ||
303 | |||
304 | unregister_netdev(dev); | ||
305 | dma_free_coherent(lp->device, | ||
306 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
307 | lp->descriptors, lp->descriptors_laddr); | ||
308 | release_region (dev->base_addr, SONIC_MEM_SIZE); | ||
309 | free_netdev(dev); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static struct platform_driver xtsonic_driver = { | ||
315 | .probe = xtsonic_probe, | ||
316 | .remove = __devexit_p(xtsonic_device_remove), | ||
317 | .driver = { | ||
318 | .name = xtsonic_string, | ||
319 | }, | ||
320 | }; | ||
321 | |||
322 | static int __init xtsonic_init(void) | ||
323 | { | ||
324 | return platform_driver_register(&xtsonic_driver); | ||
325 | } | ||
326 | |||
327 | static void __exit xtsonic_cleanup(void) | ||
328 | { | ||
329 | platform_driver_unregister(&xtsonic_driver); | ||
330 | } | ||
331 | |||
332 | module_init(xtsonic_init); | ||
333 | module_exit(xtsonic_cleanup); | ||