aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben@fluff.org>2007-07-03 11:53:09 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-10 12:41:08 -0400
commit825a2ff1896ec3ead94bebef60c71f57254da58a (patch)
treecc88b2a7666df7377819e8265298f974e388294e
parentf49343a54864b98333b98706accba66aa75a0c16 (diff)
AX88796 network driver
Support for the Asix AX88796 network controller, an NE2000 compatible 10/100 ethernet device with internal PHY. The driver supports PHY settings via either ioctl() or the ethtool driver ops. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/8390.h11
-rw-r--r--drivers/net/Kconfig8
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/ax88796.c952
-rw-r--r--include/net/ax88796.h27
5 files changed, 999 insertions, 0 deletions
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 414de5bd228f..04ddec0f4c61 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -73,6 +73,9 @@ struct ei_device {
73 u32 *reg_offset; /* Register mapping table */ 73 u32 *reg_offset; /* Register mapping table */
74 spinlock_t page_lock; /* Page register locks */ 74 spinlock_t page_lock; /* Page register locks */
75 unsigned long priv; /* Private field to store bus IDs etc. */ 75 unsigned long priv; /* Private field to store bus IDs etc. */
76#ifdef AX88796_PLATFORM
77 unsigned char rxcr_base; /* default value for RXCR */
78#endif
76}; 79};
77 80
78/* The maximum number of 8390 interrupt service routines called per IRQ. */ 81/* The maximum number of 8390 interrupt service routines called per IRQ. */
@@ -86,11 +89,19 @@ struct ei_device {
86/* Some generic ethernet register configurations. */ 89/* Some generic ethernet register configurations. */
87#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ 90#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */
88#define E8390_RX_IRQ_MASK 0x5 91#define E8390_RX_IRQ_MASK 0x5
92
93#ifdef AX88796_PLATFORM
94#define E8390_RXCONFIG (ei_status.rxcr_base | 0x04)
95#define E8390_RXOFF (ei_status.rxcr_base | 0x20)
96#else
89#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ 97#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
90#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ 98#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
99#endif
100
91#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ 101#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
92#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ 102#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
93 103
104
94/* Register accessed at EN_CMD, the 8390 base addr. */ 105/* Register accessed at EN_CMD, the 8390 base addr. */
95#define E8390_STOP 0x01 /* Stop and reset the chip */ 106#define E8390_STOP 0x01 /* Stop and reset the chip */
96#define E8390_START 0x02 /* Start the chip, clear reset */ 107#define E8390_START 0x02 /* Start the chip, clear reset */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4f23ad7b13c1..09c68984c887 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -197,6 +197,14 @@ config MACB
197 197
198source "drivers/net/arm/Kconfig" 198source "drivers/net/arm/Kconfig"
199 199
200config AX88796
201 tristate "ASIX AX88796 NE2000 clone support"
202 select CRC32
203 select MII
204 help
205 AX88796 driver, using platform bus to provide
206 chip detection and resources
207
200config MACE 208config MACE
201 tristate "MACE (Power Mac ethernet) support" 209 tristate "MACE (Power Mac ethernet) support"
202 depends on PPC_PMAC && PPC32 210 depends on PPC_PMAC && PPC32
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index eb62fb48e4b7..515ca660b936 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -107,6 +107,7 @@ obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
107obj-$(CONFIG_B44) += b44.o 107obj-$(CONFIG_B44) += b44.o
108obj-$(CONFIG_FORCEDETH) += forcedeth.o 108obj-$(CONFIG_FORCEDETH) += forcedeth.o
109obj-$(CONFIG_NE_H8300) += ne-h8300.o 109obj-$(CONFIG_NE_H8300) += ne-h8300.o
110obj-$(CONFIG_AX88796) += ax88796.o
110 111
111obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o 112obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
112obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o 113obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
new file mode 100644
index 000000000000..d19874bf0706
--- /dev/null
+++ b/drivers/net/ax88796.c
@@ -0,0 +1,952 @@
1/* drivers/net/ax88796.c
2 *
3 * Copyright 2005,2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Asix AX88796 10/100 Ethernet controller support
7 * Based on ne.c, by Donald Becker, et-al.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/isapnp.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/delay.h>
22#include <linux/timer.h>
23#include <linux/netdevice.h>
24#include <linux/etherdevice.h>
25#include <linux/ethtool.h>
26#include <linux/mii.h>
27
28#include <net/ax88796.h>
29
30#include <asm/system.h>
31#include <asm/io.h>
32
33static int phy_debug = 0;
34
35/* Rename the lib8390.c functions to show that they are in this driver */
36#define __ei_open ax_ei_open
37#define __ei_close ax_ei_close
38#define __ei_poll ax_ei_poll
39#define __ei_tx_timeout ax_ei_tx_timeout
40#define __ei_interrupt ax_ei_interrupt
41#define ____alloc_ei_netdev ax__alloc_ei_netdev
42#define __NS8390_init ax_NS8390_init
43
44/* force unsigned long back to 'void __iomem *' */
45#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
46
47#define ei_inb(_a) readb(ax_convert_addr(_a))
48#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))
49
50#define ei_inb_p(_a) ei_inb(_a)
51#define ei_outb_p(_v, _a) ei_outb(_v, _a)
52
53/* define EI_SHIFT() to take into account our register offsets */
54#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
55
56/* Ensure we have our RCR base value */
57#define AX88796_PLATFORM
58
59static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
60
61#include "lib8390.c"
62
63#define DRV_NAME "ax88796"
64#define DRV_VERSION "1.00"
65
66/* from ne.c */
67#define NE_CMD EI_SHIFT(0x00)
68#define NE_RESET EI_SHIFT(0x1f)
69#define NE_DATAPORT EI_SHIFT(0x10)
70
71#define NE1SM_START_PG 0x20 /* First page of TX buffer */
72#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
73#define NESM_START_PG 0x40 /* First page of TX buffer */
74#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
75
76/* device private data */
77
78struct ax_device {
79 struct timer_list mii_timer;
80 spinlock_t mii_lock;
81 struct mii_if_info mii;
82
83 u32 msg_enable;
84 void __iomem *map2;
85 struct platform_device *dev;
86 struct resource *mem;
87 struct resource *mem2;
88 struct ax_plat_data *plat;
89
90 unsigned char running;
91 unsigned char resume_open;
92
93 u32 reg_offsets[0x20];
94};
95
96static inline struct ax_device *to_ax_dev(struct net_device *dev)
97{
98 struct ei_device *ei_local = netdev_priv(dev);
99 return (struct ax_device *)(ei_local+1);
100}
101
102/* ax_initial_check
103 *
104 * do an initial probe for the card to check wether it exists
105 * and is functional
106 */
107
108static int ax_initial_check(struct net_device *dev)
109{
110 struct ei_device *ei_local = netdev_priv(dev);
111 void __iomem *ioaddr = ei_local->mem;
112 int reg0;
113 int regd;
114
115 reg0 = ei_inb(ioaddr);
116 if (reg0 == 0xFF)
117 return -ENODEV;
118
119 ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
120 regd = ei_inb(ioaddr + 0x0d);
121 ei_outb(0xff, ioaddr + 0x0d);
122 ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
123 ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
124 if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
125 ei_outb(reg0, ioaddr);
126 ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */
127 return -ENODEV;
128 }
129
130 return 0;
131}
132
133/* Hard reset the card. This used to pause for the same period that a
134 8390 reset command required, but that shouldn't be necessary. */
135
136static void ax_reset_8390(struct net_device *dev)
137{
138 struct ei_device *ei_local = netdev_priv(dev);
139 unsigned long reset_start_time = jiffies;
140 void __iomem *addr = (void __iomem *)dev->base_addr;
141
142 if (ei_debug > 1)
143 printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
144
145 ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
146
147 ei_status.txing = 0;
148 ei_status.dmaing = 0;
149
150 /* This check _should_not_ be necessary, omit eventually. */
151 while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
152 if (jiffies - reset_start_time > 2*HZ/100) {
153 printk(KERN_WARNING "%s: %s did not complete.\n",
154 __FUNCTION__, dev->name);
155 break;
156 }
157 }
158
159 ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */
160}
161
162
163static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
164 int ring_page)
165{
166 struct ei_device *ei_local = netdev_priv(dev);
167 void __iomem *nic_base = ei_local->mem;
168
169 /* This *shouldn't* happen. If it does, it's the last thing you'll see */
170 if (ei_status.dmaing) {
171 printk(KERN_EMERG "%s: DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n",
172 dev->name, __FUNCTION__,
173 ei_status.dmaing, ei_status.irqlock);
174 return;
175 }
176
177 ei_status.dmaing |= 0x01;
178 ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
179 ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
180 ei_outb(0, nic_base + EN0_RCNTHI);
181 ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */
182 ei_outb(ring_page, nic_base + EN0_RSARHI);
183 ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
184
185 if (ei_status.word16)
186 readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
187 else
188 readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
189
190 ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
191 ei_status.dmaing &= ~0x01;
192
193 le16_to_cpus(&hdr->count);
194}
195
196
197/* Block input and output, similar to the Crynwr packet driver. If you
198 are porting to a new ethercard, look at the packet driver source for hints.
199 The NEx000 doesn't share the on-board packet memory -- you have to put
200 the packet out through the "remote DMA" dataport using ei_outb. */
201
202static void ax_block_input(struct net_device *dev, int count,
203 struct sk_buff *skb, int ring_offset)
204{
205 struct ei_device *ei_local = netdev_priv(dev);
206 void __iomem *nic_base = ei_local->mem;
207 char *buf = skb->data;
208
209 if (ei_status.dmaing) {
210 printk(KERN_EMERG "%s: DMAing conflict in ax_block_input "
211 "[DMAstat:%d][irqlock:%d].\n",
212 dev->name, ei_status.dmaing, ei_status.irqlock);
213 return;
214 }
215
216 ei_status.dmaing |= 0x01;
217
218 ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
219 ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
220 ei_outb(count >> 8, nic_base + EN0_RCNTHI);
221 ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
222 ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
223 ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
224
225 if (ei_status.word16) {
226 readsw(nic_base + NE_DATAPORT, buf, count >> 1);
227 if (count & 0x01)
228 buf[count-1] = ei_inb(nic_base + NE_DATAPORT);
229
230 } else {
231 readsb(nic_base + NE_DATAPORT, buf, count);
232 }
233
234 ei_status.dmaing &= ~1;
235}
236
237static void ax_block_output(struct net_device *dev, int count,
238 const unsigned char *buf, const int start_page)
239{
240 struct ei_device *ei_local = netdev_priv(dev);
241 void __iomem *nic_base = ei_local->mem;
242 unsigned long dma_start;
243
244 /* Round the count up for word writes. Do we need to do this?
245 What effect will an odd byte count have on the 8390?
246 I should check someday. */
247
248 if (ei_status.word16 && (count & 0x01))
249 count++;
250
251 /* This *shouldn't* happen. If it does, it's the last thing you'll see */
252 if (ei_status.dmaing) {
253 printk(KERN_EMERG "%s: DMAing conflict in %s."
254 "[DMAstat:%d][irqlock:%d]\n",
255 dev->name, __FUNCTION__,
256 ei_status.dmaing, ei_status.irqlock);
257 return;
258 }
259
260 ei_status.dmaing |= 0x01;
261 /* We should already be in page 0, but to be safe... */
262 ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
263
264 ei_outb(ENISR_RDC, nic_base + EN0_ISR);
265
266 /* Now the normal output. */
267 ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
268 ei_outb(count >> 8, nic_base + EN0_RCNTHI);
269 ei_outb(0x00, nic_base + EN0_RSARLO);
270 ei_outb(start_page, nic_base + EN0_RSARHI);
271
272 ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
273 if (ei_status.word16) {
274 writesw(nic_base + NE_DATAPORT, buf, count>>1);
275 } else {
276 writesb(nic_base + NE_DATAPORT, buf, count);
277 }
278
279 dma_start = jiffies;
280
281 while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
282 if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
283 printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
284 ax_reset_8390(dev);
285 ax_NS8390_init(dev,1);
286 break;
287 }
288 }
289
290 ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
291 ei_status.dmaing &= ~0x01;
292 return;
293}
294
295/* definitions for accessing MII/EEPROM interface */
296
297#define AX_MEMR EI_SHIFT(0x14)
298#define AX_MEMR_MDC (1<<0)
299#define AX_MEMR_MDIR (1<<1)
300#define AX_MEMR_MDI (1<<2)
301#define AX_MEMR_MDO (1<<3)
302#define AX_MEMR_EECS (1<<4)
303#define AX_MEMR_EEI (1<<5)
304#define AX_MEMR_EEO (1<<6)
305#define AX_MEMR_EECLK (1<<7)
306
307/* ax_mii_ei_outbits
308 *
309 * write the specified set of bits to the phy
310*/
311
312static void
313ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
314{
315 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
316 void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
317 unsigned int memr;
318
319 /* clock low, data to output mode */
320 memr = ei_inb(memr_addr);
321 memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR);
322 ei_outb(memr, memr_addr);
323
324 for (len--; len >= 0; len--) {
325 if (bits & (1 << len))
326 memr |= AX_MEMR_MDO;
327 else
328 memr &= ~AX_MEMR_MDO;
329
330 ei_outb(memr, memr_addr);
331
332 /* clock high */
333
334 ei_outb(memr | AX_MEMR_MDC, memr_addr);
335 udelay(1);
336
337 /* clock low */
338 ei_outb(memr, memr_addr);
339 }
340
341 /* leaves the clock line low, mdir input */
342 memr |= AX_MEMR_MDIR;
343 ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR);
344}
345
346/* ax_phy_ei_inbits
347 *
348 * read a specified number of bits from the phy
349*/
350
351static unsigned int
352ax_phy_ei_inbits(struct net_device *dev, int no)
353{
354 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
355 void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
356 unsigned int memr;
357 unsigned int result = 0;
358
359 /* clock low, data to input mode */
360 memr = ei_inb(memr_addr);
361 memr &= ~AX_MEMR_MDC;
362 memr |= AX_MEMR_MDIR;
363 ei_outb(memr, memr_addr);
364
365 for (no--; no >= 0; no--) {
366 ei_outb(memr | AX_MEMR_MDC, memr_addr);
367
368 udelay(1);
369
370 if (ei_inb(memr_addr) & AX_MEMR_MDI)
371 result |= (1<<no);
372
373 ei_outb(memr, memr_addr);
374 }
375
376 return result;
377}
378
379/* ax_phy_issueaddr
380 *
381 * use the low level bit shifting routines to send the address
382 * and command to the specified phy
383*/
384
385static void
386ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
387{
388 if (phy_debug)
389 pr_debug("%s: dev %p, %04x, %04x, %d\n",
390 __FUNCTION__, dev, phy_addr, reg, opc);
391
392 ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */
393 ax_mii_ei_outbits(dev, 1, 2); /* frame-start */
394 ax_mii_ei_outbits(dev, opc, 2); /* op code */
395 ax_mii_ei_outbits(dev, phy_addr, 5); /* phy address */
396 ax_mii_ei_outbits(dev, reg, 5); /* reg address */
397}
398
399static int
400ax_phy_read(struct net_device *dev, int phy_addr, int reg)
401{
402 struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
403 unsigned long flags;
404 unsigned int result;
405
406 spin_lock_irqsave(&ei_local->page_lock, flags);
407
408 ax_phy_issueaddr(dev, phy_addr, reg, 2);
409
410 result = ax_phy_ei_inbits(dev, 17);
411 result &= ~(3<<16);
412
413 spin_unlock_irqrestore(&ei_local->page_lock, flags);
414
415 if (phy_debug)
416 pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
417 phy_addr, reg, result);
418
419 return result;
420}
421
422static void
423ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
424{
425 struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
426 unsigned long flags;
427
428 printk(KERN_DEBUG "%s: %p, %04x, %04x %04x\n",
429 __FUNCTION__, dev, phy_addr, reg, value);
430
431 spin_lock_irqsave(&ei->page_lock, flags);
432
433 ax_phy_issueaddr(dev, phy_addr, reg, 1);
434 ax_mii_ei_outbits(dev, 2, 2); /* send TA */
435 ax_mii_ei_outbits(dev, value, 16);
436
437 spin_unlock_irqrestore(&ei->page_lock, flags);
438}
439
440static void ax_mii_expiry(unsigned long data)
441{
442 struct net_device *dev = (struct net_device *)data;
443 struct ax_device *ax = to_ax_dev(dev);
444 unsigned long flags;
445
446 spin_lock_irqsave(&ax->mii_lock, flags);
447 mii_check_media(&ax->mii, netif_msg_link(ax), 0);
448 spin_unlock_irqrestore(&ax->mii_lock, flags);
449
450 if (ax->running) {
451 ax->mii_timer.expires = jiffies + HZ*2;
452 add_timer(&ax->mii_timer);
453 }
454}
455
456static int ax_open(struct net_device *dev)
457{
458 struct ax_device *ax = to_ax_dev(dev);
459 struct ei_device *ei_local = netdev_priv(dev);
460 int ret;
461
462 dev_dbg(ax->dev, "%s: open\n", dev->name);
463
464 ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
465 if (ret)
466 return ret;
467
468 ret = ax_ei_open(dev);
469 if (ret)
470 return ret;
471
472 /* turn the phy on (if turned off) */
473
474 ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17));
475 ax->running = 1;
476
477 /* start the MII timer */
478
479 init_timer(&ax->mii_timer);
480
481 ax->mii_timer.expires = jiffies+1;
482 ax->mii_timer.data = (unsigned long) dev;
483 ax->mii_timer.function = ax_mii_expiry;
484
485 add_timer(&ax->mii_timer);
486
487 return 0;
488}
489
490static int ax_close(struct net_device *dev)
491{
492 struct ax_device *ax = to_ax_dev(dev);
493 struct ei_device *ei_local = netdev_priv(dev);
494
495 dev_dbg(ax->dev, "%s: close\n", dev->name);
496
497 /* turn the phy off */
498
499 ei_outb(ax->plat->gpoc_val | (1<<6),
500 ei_local->mem + EI_SHIFT(0x17));
501
502 ax->running = 0;
503 wmb();
504
505 del_timer_sync(&ax->mii_timer);
506 ax_ei_close(dev);
507
508 free_irq(dev->irq, dev);
509 return 0;
510}
511
512static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
513{
514 struct ax_device *ax = to_ax_dev(dev);
515 unsigned long flags;
516 int rc;
517
518 if (!netif_running(dev))
519 return -EINVAL;
520
521 spin_lock_irqsave(&ax->mii_lock, flags);
522 rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL);
523 spin_unlock_irqrestore(&ax->mii_lock, flags);
524
525 return rc;
526}
527
528/* ethtool ops */
529
530static void ax_get_drvinfo(struct net_device *dev,
531 struct ethtool_drvinfo *info)
532{
533 struct ax_device *ax = to_ax_dev(dev);
534
535 strcpy(info->driver, DRV_NAME);
536 strcpy(info->version, DRV_VERSION);
537 strcpy(info->bus_info, ax->dev->name);
538}
539
540static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
541{
542 struct ax_device *ax = to_ax_dev(dev);
543 unsigned long flags;
544
545 spin_lock_irqsave(&ax->mii_lock, flags);
546 mii_ethtool_gset(&ax->mii, cmd);
547 spin_lock_irqsave(&ax->mii_lock, flags);
548
549 return 0;
550}
551
552static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
553{
554 struct ax_device *ax = to_ax_dev(dev);
555 unsigned long flags;
556 int rc;
557
558 spin_lock_irqsave(&ax->mii_lock, flags);
559 rc = mii_ethtool_sset(&ax->mii, cmd);
560 spin_lock_irqsave(&ax->mii_lock, flags);
561
562 return rc;
563}
564
565static int ax_nway_reset(struct net_device *dev)
566{
567 struct ax_device *ax = to_ax_dev(dev);
568 return mii_nway_restart(&ax->mii);
569}
570
571static u32 ax_get_link(struct net_device *dev)
572{
573 struct ax_device *ax = to_ax_dev(dev);
574 return mii_link_ok(&ax->mii);
575}
576
577static const struct ethtool_ops ax_ethtool_ops = {
578 .get_drvinfo = ax_get_drvinfo,
579 .get_settings = ax_get_settings,
580 .set_settings = ax_set_settings,
581 .nway_reset = ax_nway_reset,
582 .get_link = ax_get_link,
583 .get_perm_addr = ethtool_op_get_perm_addr,
584};
585
586/* setup code */
587
588static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
589{
590 void __iomem *ioaddr = ei_local->mem;
591 struct ax_device *ax = to_ax_dev(dev);
592
593 /* Select page 0*/
594 ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD);
595
596 /* set to byte access */
597 ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
598 ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
599}
600
601/* ax_init_dev
602 *
603 * initialise the specified device, taking care to note the MAC
604 * address it may already have (if configured), ensure
605 * the device is ready to be used by lib8390.c and registerd with
606 * the network layer.
607 */
608
609static int ax_init_dev(struct net_device *dev, int first_init)
610{
611 struct ei_device *ei_local = netdev_priv(dev);
612 struct ax_device *ax = to_ax_dev(dev);
613 void __iomem *ioaddr = ei_local->mem;
614 unsigned int start_page;
615 unsigned int stop_page;
616 int ret;
617 int i;
618
619 ret = ax_initial_check(dev);
620 if (ret)
621 goto err_out;
622
623 /* setup goes here */
624
625 ax_initial_setup(dev, ei_local);
626
627 /* read the mac from the card prom if we need it */
628
629 if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) {
630 unsigned char SA_prom[32];
631
632 for(i = 0; i < sizeof(SA_prom); i+=2) {
633 SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
634 SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT);
635 }
636
637 if (ax->plat->wordlength == 2)
638 for (i = 0; i < 16; i++)
639 SA_prom[i] = SA_prom[i+i];
640
641 memcpy(dev->dev_addr, SA_prom, 6);
642 }
643
644 if (ax->plat->wordlength == 2) {
645 /* We must set the 8390 for word mode. */
646 ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
647 start_page = NESM_START_PG;
648 stop_page = NESM_STOP_PG;
649 } else {
650 start_page = NE1SM_START_PG;
651 stop_page = NE1SM_STOP_PG;
652 }
653
654 /* load the mac-address from the device if this is the
655 * first time we've initialised */
656
657 if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
658 ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
659 ei_local->mem + E8390_CMD); /* 0x61 */
660
661 for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
662 dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
663 }
664
665 ax_reset_8390(dev);
666
667 ei_status.name = "AX88796";
668 ei_status.tx_start_page = start_page;
669 ei_status.stop_page = stop_page;
670 ei_status.word16 = (ax->plat->wordlength == 2);
671 ei_status.rx_start_page = start_page + TX_PAGES;
672
673#ifdef PACKETBUF_MEMSIZE
674 /* Allow the packet buffer size to be overridden by know-it-alls. */
675 ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
676#endif
677
678 ei_status.reset_8390 = &ax_reset_8390;
679 ei_status.block_input = &ax_block_input;
680 ei_status.block_output = &ax_block_output;
681 ei_status.get_8390_hdr = &ax_get_8390_hdr;
682 ei_status.priv = 0;
683
684 dev->open = ax_open;
685 dev->stop = ax_close;
686 dev->do_ioctl = ax_ioctl;
687 dev->ethtool_ops = &ax_ethtool_ops;
688
689 ax->msg_enable = NETIF_MSG_LINK;
690 ax->mii.phy_id_mask = 0x1f;
691 ax->mii.reg_num_mask = 0x1f;
692 ax->mii.phy_id = 0x10; /* onboard phy */
693 ax->mii.force_media = 0;
694 ax->mii.full_duplex = 0;
695 ax->mii.mdio_read = ax_phy_read;
696 ax->mii.mdio_write = ax_phy_write;
697 ax->mii.dev = dev;
698
699#ifdef CONFIG_NET_POLL_CONTROLLER
700 dev->poll_controller = ax_ei_poll;
701#endif
702 ax_NS8390_init(dev, 0);
703
704 if (first_init) {
705 printk("AX88796: %dbit, irq %d, %lx, MAC: ",
706 ei_status.word16 ? 16:8, dev->irq, dev->base_addr);
707
708 for (i = 0; i < ETHER_ADDR_LEN; i++)
709 printk("%2.2x%c", dev->dev_addr[i],
710 (i < (ETHER_ADDR_LEN-1) ? ':' : ' '));
711
712 printk("\n");
713 }
714
715 ret = register_netdev(dev);
716 if (ret)
717 goto out_irq;
718
719 return 0;
720
721 out_irq:
722 /* cleanup irq */
723 free_irq(dev->irq, dev);
724 err_out:
725 return ret;
726}
727
728static int ax_remove(struct platform_device *_dev)
729{
730 struct net_device *dev = platform_get_drvdata(_dev);
731 struct ax_device *ax;
732
733 ax = to_ax_dev(dev);
734
735 unregister_netdev(dev);
736 free_irq(dev->irq, dev);
737
738 iounmap(ei_status.mem);
739 release_resource(ax->mem);
740 kfree(ax->mem);
741
742 if (ax->map2) {
743 iounmap(ax->map2);
744 release_resource(ax->mem2);
745 kfree(ax->mem2);
746 }
747
748 free_netdev(dev);
749
750 return 0;
751}
752
753/* ax_probe
754 *
755 * This is the entry point when the platform device system uses to
756 * notify us of a new device to attach to. Allocate memory, find
757 * the resources and information passed, and map the necessary registers.
758*/
759
760static int ax_probe(struct platform_device *pdev)
761{
762 struct net_device *dev;
763 struct ax_device *ax;
764 struct resource *res;
765 size_t size;
766 int ret;
767
768 dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
769 if (dev == NULL)
770 return -ENOMEM;
771
772 /* ok, let's setup our device */
773 ax = to_ax_dev(dev);
774
775 memset(ax, 0, sizeof(struct ax_device));
776
777 spin_lock_init(&ax->mii_lock);
778
779 ax->dev = pdev;
780 ax->plat = pdev->dev.platform_data;
781 platform_set_drvdata(pdev, dev);
782
783 ei_status.rxcr_base = ax->plat->rcr_val;
784
785 /* find the platform resources */
786
787 dev->irq = platform_get_irq(pdev, 0);
788 if (dev->irq < 0) {
789 dev_err(&pdev->dev, "no IRQ specified\n");
790 ret = -ENXIO;
791 goto exit_mem;
792 }
793
794 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
795 if (res == NULL) {
796 dev_err(&pdev->dev, "no MEM specified\n");
797 ret = -ENXIO;
798 goto exit_mem;
799 }
800
801 size = (res->end - res->start) + 1;
802
803 /* setup the register offsets from either the platform data
804 * or by using the size of the resource provided */
805
806 if (ax->plat->reg_offsets)
807 ei_status.reg_offset = ax->plat->reg_offsets;
808 else {
809 ei_status.reg_offset = ax->reg_offsets;
810 for (ret = 0; ret < 0x18; ret++)
811 ax->reg_offsets[ret] = (size / 0x18) * ret;
812 }
813
814 ax->mem = request_mem_region(res->start, size, pdev->name);
815 if (ax->mem == NULL) {
816 dev_err(&pdev->dev, "cannot reserve registers\n");
817 ret = -ENXIO;
818 goto exit_mem;
819 }
820
821 ei_status.mem = ioremap(res->start, size);
822 dev->base_addr = (long)ei_status.mem;
823
824 if (ei_status.mem == NULL) {
825 dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
826 res->start, res->end);
827
828 ret = -ENXIO;
829 goto exit_req;
830 }
831
832 /* look for reset area */
833
834 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
835 if (res == NULL) {
836 if (!ax->plat->reg_offsets) {
837 for (ret = 0; ret < 0x20; ret++)
838 ax->reg_offsets[ret] = (size / 0x20) * ret;
839 }
840
841 ax->map2 = NULL;
842 } else {
843 size = (res->end - res->start) + 1;
844
845 ax->mem2 = request_mem_region(res->start, size, pdev->name);
846 if (ax->mem == NULL) {
847 dev_err(&pdev->dev, "cannot reserve registers\n");
848 ret = -ENXIO;
849 goto exit_mem1;
850 }
851
852 ax->map2 = ioremap(res->start, size);
853 if (ax->map2 == NULL) {
854 dev_err(&pdev->dev, "cannot map reset register");
855 ret = -ENXIO;
856 goto exit_mem2;
857 }
858
859 ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
860 }
861
862 /* got resources, now initialise and register device */
863
864 ret = ax_init_dev(dev, 1);
865 if (!ret)
866 return 0;
867
868 if (ax->map2 == NULL)
869 goto exit_mem1;
870
871 iounmap(ax->map2);
872
873 exit_mem2:
874 release_resource(ax->mem2);
875 kfree(ax->mem2);
876
877 exit_mem1:
878 iounmap(ei_status.mem);
879
880 exit_req:
881 release_resource(ax->mem);
882 kfree(ax->mem);
883
884 exit_mem:
885 free_netdev(dev);
886
887 return ret;
888}
889
890/* suspend and resume */
891
892#ifdef CONFIG_PM
893static int ax_suspend(struct platform_device *dev, pm_message_t state)
894{
895 struct net_device *ndev = platform_get_drvdata(dev);
896 struct ax_device *ax = to_ax_dev(ndev);
897
898 ax->resume_open = ax->running;
899
900 netif_device_detach(ndev);
901 ax_close(ndev);
902
903 return 0;
904}
905
906static int ax_resume(struct platform_device *pdev)
907{
908 struct net_device *ndev = platform_get_drvdata(pdev);
909 struct ax_device *ax = to_ax_dev(ndev);
910
911 ax_initial_setup(ndev, netdev_priv(ndev));
912 ax_NS8390_init(ndev, ax->resume_open);
913 netif_device_attach(ndev);
914
915 if (ax->resume_open)
916 ax_open(ndev);
917
918 return 0;
919}
920
921#else
922#define ax_suspend NULL
923#define ax_resume NULL
924#endif
925
926static struct platform_driver axdrv = {
927 .driver = {
928 .name = "ax88796",
929 .owner = THIS_MODULE,
930 },
931 .probe = ax_probe,
932 .remove = ax_remove,
933 .suspend = ax_suspend,
934 .resume = ax_resume,
935};
936
937static int __init axdrv_init(void)
938{
939 return platform_driver_register(&axdrv);
940}
941
942static void __exit axdrv_exit(void)
943{
944 platform_driver_unregister(&axdrv);
945}
946
947module_init(axdrv_init);
948module_exit(axdrv_exit);
949
950MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
951MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
952MODULE_LICENSE("GPL v2");
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
new file mode 100644
index 000000000000..ee786a043b3d
--- /dev/null
+++ b/include/net/ax88796.h
@@ -0,0 +1,27 @@
1/* include/net/ax88796.h
2 *
3 * Copyright 2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10*/
11
12#ifndef __NET_AX88796_PLAT_H
13#define __NET_AX88796_PLAT_H
14
15#define AXFLG_HAS_EEPROM (1<<0)
16#define AXFLG_MAC_FROMDEV (1<<1) /* device already has MAC */
17
18struct ax_plat_data {
19 unsigned int flags;
20 unsigned char wordlength; /* 1 or 2 */
21 unsigned char dcr_val; /* default value for DCR */
22 unsigned char rcr_val; /* default value for RCR */
23 unsigned char gpoc_val; /* default value for GPOC */
24 u32 *reg_offsets; /* register offsets */
25};
26
27#endif /* __NET_AX88796_PLAT_H */