1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 29e13fbf7SJeff Kirsher /* 39e13fbf7SJeff Kirsher * linux/drivers/acorn/net/ether3.c 49e13fbf7SJeff Kirsher * 59e13fbf7SJeff Kirsher * Copyright (C) 1995-2000 Russell King 69e13fbf7SJeff Kirsher * 79e13fbf7SJeff Kirsher * SEEQ nq8005 ethernet driver for Acorn/ANT Ether3 card 89e13fbf7SJeff Kirsher * for Acorn machines 99e13fbf7SJeff Kirsher * 109e13fbf7SJeff Kirsher * By Russell King, with some suggestions from borris@ant.co.uk 119e13fbf7SJeff Kirsher * 129e13fbf7SJeff Kirsher * Changelog: 139e13fbf7SJeff Kirsher * 1.04 RMK 29/02/1996 Won't pass packets that are from our ethernet 149e13fbf7SJeff Kirsher * address up to the higher levels - they're 159e13fbf7SJeff Kirsher * silently ignored. I/F can now be put into 169e13fbf7SJeff Kirsher * multicast mode. Receiver routine optimised. 179e13fbf7SJeff Kirsher * 1.05 RMK 30/02/1996 Now claims interrupt at open when part of 189e13fbf7SJeff Kirsher * the kernel rather than when a module. 199e13fbf7SJeff Kirsher * 1.06 RMK 02/03/1996 Various code cleanups 209e13fbf7SJeff Kirsher * 1.07 RMK 13/10/1996 Optimised interrupt routine and transmit 219e13fbf7SJeff Kirsher * routines. 229e13fbf7SJeff Kirsher * 1.08 RMK 14/10/1996 Fixed problem with too many packets, 239e13fbf7SJeff Kirsher * prevented the kernel message about dropped 249e13fbf7SJeff Kirsher * packets appearing too many times a second. 259e13fbf7SJeff Kirsher * Now does not disable all IRQs, only the IRQ 269e13fbf7SJeff Kirsher * used by this card. 279e13fbf7SJeff Kirsher * 1.09 RMK 10/11/1996 Only enables TX irq when buffer space is low, 289e13fbf7SJeff Kirsher * but we still service the TX queue if we get a 299e13fbf7SJeff Kirsher * RX interrupt. 309e13fbf7SJeff Kirsher * 1.10 RMK 15/07/1997 Fixed autoprobing of NQ8004. 319e13fbf7SJeff Kirsher * 1.11 RMK 16/11/1997 Fixed autoprobing of NQ8005A. 329e13fbf7SJeff Kirsher * 1.12 RMK 31/12/1997 Removed reference to dev_tint for Linux 2.1. 339e13fbf7SJeff Kirsher * RMK 27/06/1998 Changed asm/delay.h to linux/delay.h. 349e13fbf7SJeff Kirsher * 1.13 RMK 29/06/1998 Fixed problem with transmission of packets. 359e13fbf7SJeff Kirsher * Chip seems to have a bug in, whereby if the 369e13fbf7SJeff Kirsher * packet starts two bytes from the end of the 379e13fbf7SJeff Kirsher * buffer, it corrupts the receiver chain, and 389e13fbf7SJeff Kirsher * never updates the transmit status correctly. 399e13fbf7SJeff Kirsher * 1.14 RMK 07/01/1998 Added initial code for ETHERB addressing. 409e13fbf7SJeff Kirsher * 1.15 RMK 30/04/1999 More fixes to the transmit routine for buggy 419e13fbf7SJeff Kirsher * hardware. 429e13fbf7SJeff Kirsher * 1.16 RMK 10/02/2000 Updated for 2.3.43 439e13fbf7SJeff Kirsher * 1.17 RMK 13/05/2000 Updated for 2.3.99-pre8 449e13fbf7SJeff Kirsher */ 459e13fbf7SJeff Kirsher 469e13fbf7SJeff Kirsher #include <linux/module.h> 479e13fbf7SJeff Kirsher #include <linux/kernel.h> 489e13fbf7SJeff Kirsher #include <linux/types.h> 499e13fbf7SJeff Kirsher #include <linux/fcntl.h> 509e13fbf7SJeff Kirsher #include <linux/interrupt.h> 519e13fbf7SJeff Kirsher #include <linux/ioport.h> 529e13fbf7SJeff Kirsher #include <linux/in.h> 539e13fbf7SJeff Kirsher #include <linux/slab.h> 549e13fbf7SJeff Kirsher #include <linux/string.h> 559e13fbf7SJeff Kirsher #include <linux/errno.h> 569e13fbf7SJeff Kirsher #include <linux/netdevice.h> 579e13fbf7SJeff Kirsher #include <linux/etherdevice.h> 589e13fbf7SJeff Kirsher #include <linux/skbuff.h> 599e13fbf7SJeff Kirsher #include <linux/device.h> 609e13fbf7SJeff Kirsher #include <linux/init.h> 619e13fbf7SJeff Kirsher #include <linux/delay.h> 629e13fbf7SJeff Kirsher #include <linux/bitops.h> 639e13fbf7SJeff Kirsher 649e13fbf7SJeff Kirsher #include <asm/ecard.h> 659e13fbf7SJeff Kirsher #include <asm/io.h> 669e13fbf7SJeff Kirsher 675911ce0dSBill Pemberton static char version[] = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n"; 689e13fbf7SJeff Kirsher 699e13fbf7SJeff Kirsher #include "ether3.h" 709e13fbf7SJeff Kirsher 719e13fbf7SJeff Kirsher static unsigned int net_debug = NET_DEBUG; 729e13fbf7SJeff Kirsher 739e13fbf7SJeff Kirsher static void ether3_setmulticastlist(struct net_device *dev); 749e13fbf7SJeff Kirsher static int ether3_rx(struct net_device *dev, unsigned int maxcnt); 759e13fbf7SJeff Kirsher static void ether3_tx(struct net_device *dev); 769e13fbf7SJeff Kirsher static int ether3_open (struct net_device *dev); 7772b46279SYueHaibing static netdev_tx_t ether3_sendpacket(struct sk_buff *skb, 7872b46279SYueHaibing struct net_device *dev); 799e13fbf7SJeff Kirsher static irqreturn_t ether3_interrupt (int irq, void *dev_id); 809e13fbf7SJeff Kirsher static int ether3_close (struct net_device *dev); 819e13fbf7SJeff Kirsher static void ether3_setmulticastlist (struct net_device *dev); 820290bd29SMichael S. Tsirkin static void ether3_timeout(struct net_device *dev, unsigned int txqueue); 839e13fbf7SJeff Kirsher 849e13fbf7SJeff Kirsher #define BUS_16 2 859e13fbf7SJeff Kirsher #define BUS_8 1 869e13fbf7SJeff Kirsher #define BUS_UNKNOWN 0 879e13fbf7SJeff Kirsher 889e13fbf7SJeff Kirsher /* --------------------------------------------------------------------------- */ 899e13fbf7SJeff Kirsher 909e13fbf7SJeff Kirsher typedef enum { 919e13fbf7SJeff Kirsher buffer_write, 929e13fbf7SJeff Kirsher buffer_read 939e13fbf7SJeff Kirsher } buffer_rw_t; 949e13fbf7SJeff Kirsher 959e13fbf7SJeff Kirsher /* 969e13fbf7SJeff Kirsher * ether3 read/write. Slow things down a bit... 979e13fbf7SJeff Kirsher * The SEEQ8005 doesn't like us writing to its registers 989e13fbf7SJeff Kirsher * too quickly. 999e13fbf7SJeff Kirsher */ 100a019c5e2SArnd Bergmann static inline void ether3_outb(int v, void __iomem *r) 1019e13fbf7SJeff Kirsher { 1029e13fbf7SJeff Kirsher writeb(v, r); 1039e13fbf7SJeff Kirsher udelay(1); 1049e13fbf7SJeff Kirsher } 1059e13fbf7SJeff Kirsher 106a019c5e2SArnd Bergmann static inline void ether3_outw(int v, void __iomem *r) 1079e13fbf7SJeff Kirsher { 1089e13fbf7SJeff Kirsher writew(v, r); 1099e13fbf7SJeff Kirsher udelay(1); 1109e13fbf7SJeff Kirsher } 1119e13fbf7SJeff Kirsher #define ether3_inb(r) ({ unsigned int __v = readb((r)); udelay(1); __v; }) 1129e13fbf7SJeff Kirsher #define ether3_inw(r) ({ unsigned int __v = readw((r)); udelay(1); __v; }) 1139e13fbf7SJeff Kirsher 1149e13fbf7SJeff Kirsher static int 1159e13fbf7SJeff Kirsher ether3_setbuffer(struct net_device *dev, buffer_rw_t read, int start) 1169e13fbf7SJeff Kirsher { 1179e13fbf7SJeff Kirsher int timeout = 1000; 1189e13fbf7SJeff Kirsher 1199e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); 1209e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.command | CMD_FIFOWRITE, REG_COMMAND); 1219e13fbf7SJeff Kirsher 1229e13fbf7SJeff Kirsher while ((ether3_inw(REG_STATUS) & STAT_FIFOEMPTY) == 0) { 1239e13fbf7SJeff Kirsher if (!timeout--) { 1249e13fbf7SJeff Kirsher printk("%s: setbuffer broken\n", dev->name); 1259e13fbf7SJeff Kirsher priv(dev)->broken = 1; 1269e13fbf7SJeff Kirsher return 1; 1279e13fbf7SJeff Kirsher } 1289e13fbf7SJeff Kirsher udelay(1); 1299e13fbf7SJeff Kirsher } 1309e13fbf7SJeff Kirsher 1319e13fbf7SJeff Kirsher if (read == buffer_read) { 1329e13fbf7SJeff Kirsher ether3_outw(start, REG_DMAADDR); 1339e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.command | CMD_FIFOREAD, REG_COMMAND); 1349e13fbf7SJeff Kirsher } else { 1359e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.command | CMD_FIFOWRITE, REG_COMMAND); 1369e13fbf7SJeff Kirsher ether3_outw(start, REG_DMAADDR); 1379e13fbf7SJeff Kirsher } 1389e13fbf7SJeff Kirsher return 0; 1399e13fbf7SJeff Kirsher } 1409e13fbf7SJeff Kirsher 1419e13fbf7SJeff Kirsher /* 1429e13fbf7SJeff Kirsher * write data to the buffer memory 1439e13fbf7SJeff Kirsher */ 1449e13fbf7SJeff Kirsher #define ether3_writebuffer(dev,data,length) \ 1459e13fbf7SJeff Kirsher writesw(REG_BUFWIN, (data), (length) >> 1) 1469e13fbf7SJeff Kirsher 1479e13fbf7SJeff Kirsher #define ether3_writeword(dev,data) \ 1489e13fbf7SJeff Kirsher writew((data), REG_BUFWIN) 1499e13fbf7SJeff Kirsher 1509e13fbf7SJeff Kirsher #define ether3_writelong(dev,data) { \ 1519e13fbf7SJeff Kirsher void __iomem *reg_bufwin = REG_BUFWIN; \ 1529e13fbf7SJeff Kirsher writew((data), reg_bufwin); \ 1539e13fbf7SJeff Kirsher writew((data) >> 16, reg_bufwin); \ 1549e13fbf7SJeff Kirsher } 1559e13fbf7SJeff Kirsher 1569e13fbf7SJeff Kirsher /* 1579e13fbf7SJeff Kirsher * read data from the buffer memory 1589e13fbf7SJeff Kirsher */ 1599e13fbf7SJeff Kirsher #define ether3_readbuffer(dev,data,length) \ 1609e13fbf7SJeff Kirsher readsw(REG_BUFWIN, (data), (length) >> 1) 1619e13fbf7SJeff Kirsher 1629e13fbf7SJeff Kirsher #define ether3_readword(dev) \ 1639e13fbf7SJeff Kirsher readw(REG_BUFWIN) 1649e13fbf7SJeff Kirsher 1659e13fbf7SJeff Kirsher #define ether3_readlong(dev) \ 1669e13fbf7SJeff Kirsher readw(REG_BUFWIN) | (readw(REG_BUFWIN) << 16) 1679e13fbf7SJeff Kirsher 1689e13fbf7SJeff Kirsher /* 1699e13fbf7SJeff Kirsher * Switch LED off... 1709e13fbf7SJeff Kirsher */ 1716fd9c53fSKees Cook static void ether3_ledoff(struct timer_list *t) 1729e13fbf7SJeff Kirsher { 1739691cea9SArnd Bergmann struct dev_priv *private = from_timer(private, t, timer); 1746fd9c53fSKees Cook struct net_device *dev = private->dev; 1756fd9c53fSKees Cook 1769e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2); 1779e13fbf7SJeff Kirsher } 1789e13fbf7SJeff Kirsher 1799e13fbf7SJeff Kirsher /* 1809e13fbf7SJeff Kirsher * switch LED on... 1819e13fbf7SJeff Kirsher */ 1829e13fbf7SJeff Kirsher static inline void ether3_ledon(struct net_device *dev) 1839e13fbf7SJeff Kirsher { 1849e13fbf7SJeff Kirsher del_timer(&priv(dev)->timer); 1859e13fbf7SJeff Kirsher priv(dev)->timer.expires = jiffies + HZ / 50; /* leave on for 1/50th second */ 1869e13fbf7SJeff Kirsher add_timer(&priv(dev)->timer); 1879e13fbf7SJeff Kirsher if (priv(dev)->regs.config2 & CFG2_CTRLO) 1889e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config2 &= ~CFG2_CTRLO, REG_CONFIG2); 1899e13fbf7SJeff Kirsher } 1909e13fbf7SJeff Kirsher 1919e13fbf7SJeff Kirsher /* 1929e13fbf7SJeff Kirsher * Read the ethernet address string from the on board rom. 1939e13fbf7SJeff Kirsher * This is an ascii string!!! 1949e13fbf7SJeff Kirsher */ 1955911ce0dSBill Pemberton static int 1969e13fbf7SJeff Kirsher ether3_addr(char *addr, struct expansion_card *ec) 1979e13fbf7SJeff Kirsher { 1989e13fbf7SJeff Kirsher struct in_chunk_dir cd; 1999e13fbf7SJeff Kirsher char *s; 2009e13fbf7SJeff Kirsher 2019e13fbf7SJeff Kirsher if (ecard_readchunk(&cd, ec, 0xf5, 0) && (s = strchr(cd.d.string, '('))) { 2029e13fbf7SJeff Kirsher int i; 2039e13fbf7SJeff Kirsher for (i = 0; i<6; i++) { 2049e13fbf7SJeff Kirsher addr[i] = simple_strtoul(s + 1, &s, 0x10); 2059e13fbf7SJeff Kirsher if (*s != (i==5?')' : ':' )) 2069e13fbf7SJeff Kirsher break; 2079e13fbf7SJeff Kirsher } 2089e13fbf7SJeff Kirsher if (i == 6) 2099e13fbf7SJeff Kirsher return 0; 2109e13fbf7SJeff Kirsher } 2119e13fbf7SJeff Kirsher /* I wonder if we should even let the user continue in this case 2129e13fbf7SJeff Kirsher * - no, it would be better to disable the device 2139e13fbf7SJeff Kirsher */ 2149e13fbf7SJeff Kirsher printk(KERN_ERR "ether3: Couldn't read a valid MAC address from card.\n"); 2159e13fbf7SJeff Kirsher return -ENODEV; 2169e13fbf7SJeff Kirsher } 2179e13fbf7SJeff Kirsher 2189e13fbf7SJeff Kirsher /* --------------------------------------------------------------------------- */ 2199e13fbf7SJeff Kirsher 2205911ce0dSBill Pemberton static int 2219e13fbf7SJeff Kirsher ether3_ramtest(struct net_device *dev, unsigned char byte) 2229e13fbf7SJeff Kirsher { 2239e13fbf7SJeff Kirsher unsigned char *buffer = kmalloc(RX_END, GFP_KERNEL); 2249e13fbf7SJeff Kirsher int i,ret = 0; 2259e13fbf7SJeff Kirsher int max_errors = 4; 2269e13fbf7SJeff Kirsher int bad = -1; 2279e13fbf7SJeff Kirsher 2289e13fbf7SJeff Kirsher if (!buffer) 2299e13fbf7SJeff Kirsher return 1; 2309e13fbf7SJeff Kirsher 2319e13fbf7SJeff Kirsher memset(buffer, byte, RX_END); 2329e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_write, 0); 2339e13fbf7SJeff Kirsher ether3_writebuffer(dev, buffer, TX_END); 2349e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_write, RX_START); 2359e13fbf7SJeff Kirsher ether3_writebuffer(dev, buffer + RX_START, RX_LEN); 2369e13fbf7SJeff Kirsher memset(buffer, byte ^ 0xff, RX_END); 2379e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_read, 0); 2389e13fbf7SJeff Kirsher ether3_readbuffer(dev, buffer, TX_END); 2399e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_read, RX_START); 2409e13fbf7SJeff Kirsher ether3_readbuffer(dev, buffer + RX_START, RX_LEN); 2419e13fbf7SJeff Kirsher 2429e13fbf7SJeff Kirsher for (i = 0; i < RX_END; i++) { 2439e13fbf7SJeff Kirsher if (buffer[i] != byte) { 2449e13fbf7SJeff Kirsher if (max_errors > 0 && bad != buffer[i]) { 2459e13fbf7SJeff Kirsher printk("%s: RAM failed with (%02X instead of %02X) at 0x%04X", 2469e13fbf7SJeff Kirsher dev->name, buffer[i], byte, i); 2479e13fbf7SJeff Kirsher ret = 2; 2489e13fbf7SJeff Kirsher max_errors--; 2499e13fbf7SJeff Kirsher bad = i; 2509e13fbf7SJeff Kirsher } 2519e13fbf7SJeff Kirsher } else { 2529e13fbf7SJeff Kirsher if (bad != -1) { 2539e13fbf7SJeff Kirsher if (bad != i - 1) 2549e13fbf7SJeff Kirsher printk(" - 0x%04X\n", i - 1); 2559e13fbf7SJeff Kirsher printk("\n"); 2569e13fbf7SJeff Kirsher bad = -1; 2579e13fbf7SJeff Kirsher } 2589e13fbf7SJeff Kirsher } 2599e13fbf7SJeff Kirsher } 2609e13fbf7SJeff Kirsher if (bad != -1) 2619e13fbf7SJeff Kirsher printk(" - 0xffff\n"); 2629e13fbf7SJeff Kirsher kfree(buffer); 2639e13fbf7SJeff Kirsher 2649e13fbf7SJeff Kirsher return ret; 2659e13fbf7SJeff Kirsher } 2669e13fbf7SJeff Kirsher 2679e13fbf7SJeff Kirsher /* ------------------------------------------------------------------------------- */ 2689e13fbf7SJeff Kirsher 2695911ce0dSBill Pemberton static int ether3_init_2(struct net_device *dev) 2709e13fbf7SJeff Kirsher { 2719e13fbf7SJeff Kirsher int i; 2729e13fbf7SJeff Kirsher 2739e13fbf7SJeff Kirsher priv(dev)->regs.config1 = CFG1_RECVCOMPSTAT0|CFG1_DMABURST8; 2749e13fbf7SJeff Kirsher priv(dev)->regs.config2 = CFG2_CTRLO|CFG2_RECVCRC|CFG2_ERRENCRC; 2759e13fbf7SJeff Kirsher priv(dev)->regs.command = 0; 2769e13fbf7SJeff Kirsher 2779e13fbf7SJeff Kirsher /* 2789e13fbf7SJeff Kirsher * Set up our hardware address 2799e13fbf7SJeff Kirsher */ 2809e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1); 2819e13fbf7SJeff Kirsher for (i = 0; i < 6; i++) 2829e13fbf7SJeff Kirsher ether3_outb(dev->dev_addr[i], REG_BUFWIN); 2839e13fbf7SJeff Kirsher 2849e13fbf7SJeff Kirsher if (dev->flags & IFF_PROMISC) 2859e13fbf7SJeff Kirsher priv(dev)->regs.config1 |= CFG1_RECVPROMISC; 2869e13fbf7SJeff Kirsher else if (dev->flags & IFF_MULTICAST) 2879e13fbf7SJeff Kirsher priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI; 2889e13fbf7SJeff Kirsher else 2899e13fbf7SJeff Kirsher priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD; 2909e13fbf7SJeff Kirsher 2919e13fbf7SJeff Kirsher /* 2929e13fbf7SJeff Kirsher * There is a problem with the NQ8005 in that it occasionally loses the 2939e13fbf7SJeff Kirsher * last two bytes. To get round this problem, we receive the CRC as 2949e13fbf7SJeff Kirsher * well. That way, if we do lose the last two, then it doesn't matter. 2959e13fbf7SJeff Kirsher */ 2969e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_TRANSEND, REG_CONFIG1); 2979e13fbf7SJeff Kirsher ether3_outw((TX_END>>8) - 1, REG_BUFWIN); 2989e13fbf7SJeff Kirsher ether3_outw(priv(dev)->rx_head, REG_RECVPTR); 2999e13fbf7SJeff Kirsher ether3_outw(0, REG_TRANSMITPTR); 3009e13fbf7SJeff Kirsher ether3_outw(priv(dev)->rx_head >> 8, REG_RECVEND); 3019e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config2, REG_CONFIG2); 3029e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); 3039e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.command, REG_COMMAND); 3049e13fbf7SJeff Kirsher 3059e13fbf7SJeff Kirsher i = ether3_ramtest(dev, 0x5A); 3069e13fbf7SJeff Kirsher if(i) 3079e13fbf7SJeff Kirsher return i; 3089e13fbf7SJeff Kirsher i = ether3_ramtest(dev, 0x1E); 3099e13fbf7SJeff Kirsher if(i) 3109e13fbf7SJeff Kirsher return i; 3119e13fbf7SJeff Kirsher 3129e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_write, 0); 3139e13fbf7SJeff Kirsher ether3_writelong(dev, 0); 3149e13fbf7SJeff Kirsher return 0; 3159e13fbf7SJeff Kirsher } 3169e13fbf7SJeff Kirsher 3179e13fbf7SJeff Kirsher static void 3189e13fbf7SJeff Kirsher ether3_init_for_open(struct net_device *dev) 3199e13fbf7SJeff Kirsher { 3209e13fbf7SJeff Kirsher int i; 3219e13fbf7SJeff Kirsher 3229e13fbf7SJeff Kirsher /* Reset the chip */ 3239e13fbf7SJeff Kirsher ether3_outw(CFG2_RESET, REG_CONFIG2); 3249e13fbf7SJeff Kirsher udelay(4); 3259e13fbf7SJeff Kirsher 3269e13fbf7SJeff Kirsher priv(dev)->regs.command = 0; 3279e13fbf7SJeff Kirsher ether3_outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND); 3289e13fbf7SJeff Kirsher while (ether3_inw(REG_STATUS) & (STAT_RXON|STAT_TXON)) 3299e13fbf7SJeff Kirsher barrier(); 3309e13fbf7SJeff Kirsher 3319e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1); 3329e13fbf7SJeff Kirsher for (i = 0; i < 6; i++) 3339e13fbf7SJeff Kirsher ether3_outb(dev->dev_addr[i], REG_BUFWIN); 3349e13fbf7SJeff Kirsher 3359e13fbf7SJeff Kirsher priv(dev)->tx_head = 0; 3369e13fbf7SJeff Kirsher priv(dev)->tx_tail = 0; 3379e13fbf7SJeff Kirsher priv(dev)->regs.config2 |= CFG2_CTRLO; 3389e13fbf7SJeff Kirsher priv(dev)->rx_head = RX_START; 3399e13fbf7SJeff Kirsher 3409e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_TRANSEND, REG_CONFIG1); 3419e13fbf7SJeff Kirsher ether3_outw((TX_END>>8) - 1, REG_BUFWIN); 3429e13fbf7SJeff Kirsher ether3_outw(priv(dev)->rx_head, REG_RECVPTR); 3439e13fbf7SJeff Kirsher ether3_outw(priv(dev)->rx_head >> 8, REG_RECVEND); 3449e13fbf7SJeff Kirsher ether3_outw(0, REG_TRANSMITPTR); 3459e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config2, REG_CONFIG2); 3469e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); 3479e13fbf7SJeff Kirsher 3489e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_write, 0); 3499e13fbf7SJeff Kirsher ether3_writelong(dev, 0); 3509e13fbf7SJeff Kirsher 3519e13fbf7SJeff Kirsher priv(dev)->regs.command = CMD_ENINTRX | CMD_ENINTTX; 3529e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND); 3539e13fbf7SJeff Kirsher } 3549e13fbf7SJeff Kirsher 3559e13fbf7SJeff Kirsher static inline int 3569e13fbf7SJeff Kirsher ether3_probe_bus_8(struct net_device *dev, int val) 3579e13fbf7SJeff Kirsher { 3589e13fbf7SJeff Kirsher int write_low, write_high, read_low, read_high; 3599e13fbf7SJeff Kirsher 3609e13fbf7SJeff Kirsher write_low = val & 255; 3619e13fbf7SJeff Kirsher write_high = val >> 8; 3629e13fbf7SJeff Kirsher 3639e13fbf7SJeff Kirsher printk(KERN_DEBUG "ether3_probe: write8 [%02X:%02X]", write_high, write_low); 3649e13fbf7SJeff Kirsher 3659e13fbf7SJeff Kirsher ether3_outb(write_low, REG_RECVPTR); 3669e13fbf7SJeff Kirsher ether3_outb(write_high, REG_RECVPTR + 4); 3679e13fbf7SJeff Kirsher 3689e13fbf7SJeff Kirsher read_low = ether3_inb(REG_RECVPTR); 3699e13fbf7SJeff Kirsher read_high = ether3_inb(REG_RECVPTR + 4); 3709e13fbf7SJeff Kirsher 3719e13fbf7SJeff Kirsher printk(", read8 [%02X:%02X]\n", read_high, read_low); 3729e13fbf7SJeff Kirsher 3739e13fbf7SJeff Kirsher return read_low == write_low && read_high == write_high; 3749e13fbf7SJeff Kirsher } 3759e13fbf7SJeff Kirsher 3769e13fbf7SJeff Kirsher static inline int 3779e13fbf7SJeff Kirsher ether3_probe_bus_16(struct net_device *dev, int val) 3789e13fbf7SJeff Kirsher { 3799e13fbf7SJeff Kirsher int read_val; 3809e13fbf7SJeff Kirsher 3819e13fbf7SJeff Kirsher ether3_outw(val, REG_RECVPTR); 3829e13fbf7SJeff Kirsher read_val = ether3_inw(REG_RECVPTR); 3839e13fbf7SJeff Kirsher 3849e13fbf7SJeff Kirsher printk(KERN_DEBUG "ether3_probe: write16 [%04X], read16 [%04X]\n", val, read_val); 3859e13fbf7SJeff Kirsher 3869e13fbf7SJeff Kirsher return read_val == val; 3879e13fbf7SJeff Kirsher } 3889e13fbf7SJeff Kirsher 3899e13fbf7SJeff Kirsher /* 3909e13fbf7SJeff Kirsher * Open/initialize the board. This is called (in the current kernel) 3919e13fbf7SJeff Kirsher * sometime after booting when the 'ifconfig' program is run. 3929e13fbf7SJeff Kirsher * 3939e13fbf7SJeff Kirsher * This routine should set everything up anew at each open, even 3949e13fbf7SJeff Kirsher * registers that "should" only need to be set once at boot, so that 3959e13fbf7SJeff Kirsher * there is non-reboot way to recover if something goes wrong. 3969e13fbf7SJeff Kirsher */ 3979e13fbf7SJeff Kirsher static int 3989e13fbf7SJeff Kirsher ether3_open(struct net_device *dev) 3999e13fbf7SJeff Kirsher { 4009e13fbf7SJeff Kirsher if (request_irq(dev->irq, ether3_interrupt, 0, "ether3", dev)) 4019e13fbf7SJeff Kirsher return -EAGAIN; 4029e13fbf7SJeff Kirsher 4039e13fbf7SJeff Kirsher ether3_init_for_open(dev); 4049e13fbf7SJeff Kirsher 4059e13fbf7SJeff Kirsher netif_start_queue(dev); 4069e13fbf7SJeff Kirsher 4079e13fbf7SJeff Kirsher return 0; 4089e13fbf7SJeff Kirsher } 4099e13fbf7SJeff Kirsher 4109e13fbf7SJeff Kirsher /* 4119e13fbf7SJeff Kirsher * The inverse routine to ether3_open(). 4129e13fbf7SJeff Kirsher */ 4139e13fbf7SJeff Kirsher static int 4149e13fbf7SJeff Kirsher ether3_close(struct net_device *dev) 4159e13fbf7SJeff Kirsher { 4169e13fbf7SJeff Kirsher netif_stop_queue(dev); 4179e13fbf7SJeff Kirsher 4189e13fbf7SJeff Kirsher disable_irq(dev->irq); 4199e13fbf7SJeff Kirsher 4209e13fbf7SJeff Kirsher ether3_outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND); 4219e13fbf7SJeff Kirsher priv(dev)->regs.command = 0; 4229e13fbf7SJeff Kirsher while (ether3_inw(REG_STATUS) & (STAT_RXON|STAT_TXON)) 4239e13fbf7SJeff Kirsher barrier(); 4249e13fbf7SJeff Kirsher ether3_outb(0x80, REG_CONFIG2 + 4); 4259e13fbf7SJeff Kirsher ether3_outw(0, REG_COMMAND); 4269e13fbf7SJeff Kirsher 4279e13fbf7SJeff Kirsher free_irq(dev->irq, dev); 4289e13fbf7SJeff Kirsher 4299e13fbf7SJeff Kirsher return 0; 4309e13fbf7SJeff Kirsher } 4319e13fbf7SJeff Kirsher 4329e13fbf7SJeff Kirsher /* 4339e13fbf7SJeff Kirsher * Set or clear promiscuous/multicast mode filter for this adaptor. 4349e13fbf7SJeff Kirsher * 4359e13fbf7SJeff Kirsher * We don't attempt any packet filtering. The card may have a SEEQ 8004 4369e13fbf7SJeff Kirsher * in which does not have the other ethernet address registers present... 4379e13fbf7SJeff Kirsher */ 4389e13fbf7SJeff Kirsher static void ether3_setmulticastlist(struct net_device *dev) 4399e13fbf7SJeff Kirsher { 4409e13fbf7SJeff Kirsher priv(dev)->regs.config1 &= ~CFG1_RECVPROMISC; 4419e13fbf7SJeff Kirsher 4429e13fbf7SJeff Kirsher if (dev->flags & IFF_PROMISC) { 4439e13fbf7SJeff Kirsher /* promiscuous mode */ 4449e13fbf7SJeff Kirsher priv(dev)->regs.config1 |= CFG1_RECVPROMISC; 4459e13fbf7SJeff Kirsher } else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) { 4469e13fbf7SJeff Kirsher priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI; 4479e13fbf7SJeff Kirsher } else 4489e13fbf7SJeff Kirsher priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD; 4499e13fbf7SJeff Kirsher 4509e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); 4519e13fbf7SJeff Kirsher } 4529e13fbf7SJeff Kirsher 4530290bd29SMichael S. Tsirkin static void ether3_timeout(struct net_device *dev, unsigned int txqueue) 4549e13fbf7SJeff Kirsher { 4559e13fbf7SJeff Kirsher unsigned long flags; 4569e13fbf7SJeff Kirsher 4579e13fbf7SJeff Kirsher del_timer(&priv(dev)->timer); 4589e13fbf7SJeff Kirsher 4599e13fbf7SJeff Kirsher local_irq_save(flags); 4609e13fbf7SJeff Kirsher printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name); 4619e13fbf7SJeff Kirsher printk(KERN_ERR "%s: state: { status=%04X cfg1=%04X cfg2=%04X }\n", dev->name, 4629e13fbf7SJeff Kirsher ether3_inw(REG_STATUS), ether3_inw(REG_CONFIG1), ether3_inw(REG_CONFIG2)); 4639e13fbf7SJeff Kirsher printk(KERN_ERR "%s: { rpr=%04X rea=%04X tpr=%04X }\n", dev->name, 4649e13fbf7SJeff Kirsher ether3_inw(REG_RECVPTR), ether3_inw(REG_RECVEND), ether3_inw(REG_TRANSMITPTR)); 4659e13fbf7SJeff Kirsher printk(KERN_ERR "%s: tx head=%X tx tail=%X\n", dev->name, 4669e13fbf7SJeff Kirsher priv(dev)->tx_head, priv(dev)->tx_tail); 4679e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_read, priv(dev)->tx_tail); 4689e13fbf7SJeff Kirsher printk(KERN_ERR "%s: packet status = %08X\n", dev->name, ether3_readlong(dev)); 4699e13fbf7SJeff Kirsher local_irq_restore(flags); 4709e13fbf7SJeff Kirsher 4719e13fbf7SJeff Kirsher priv(dev)->regs.config2 |= CFG2_CTRLO; 4729e13fbf7SJeff Kirsher dev->stats.tx_errors += 1; 4739e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.config2, REG_CONFIG2); 4749e13fbf7SJeff Kirsher priv(dev)->tx_head = priv(dev)->tx_tail = 0; 4759e13fbf7SJeff Kirsher 4769e13fbf7SJeff Kirsher netif_wake_queue(dev); 4779e13fbf7SJeff Kirsher } 4789e13fbf7SJeff Kirsher 4799e13fbf7SJeff Kirsher /* 4809e13fbf7SJeff Kirsher * Transmit a packet 4819e13fbf7SJeff Kirsher */ 48272b46279SYueHaibing static netdev_tx_t 4839e13fbf7SJeff Kirsher ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) 4849e13fbf7SJeff Kirsher { 4859e13fbf7SJeff Kirsher unsigned long flags; 4869e13fbf7SJeff Kirsher unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; 4879e13fbf7SJeff Kirsher unsigned int ptr, next_ptr; 4889e13fbf7SJeff Kirsher 4899e13fbf7SJeff Kirsher if (priv(dev)->broken) { 4909e13fbf7SJeff Kirsher dev_kfree_skb(skb); 4919e13fbf7SJeff Kirsher dev->stats.tx_dropped++; 4929e13fbf7SJeff Kirsher netif_start_queue(dev); 4939e13fbf7SJeff Kirsher return NETDEV_TX_OK; 4949e13fbf7SJeff Kirsher } 4959e13fbf7SJeff Kirsher 4969e13fbf7SJeff Kirsher length = (length + 1) & ~1; 4979e13fbf7SJeff Kirsher if (length != skb->len) { 4989e13fbf7SJeff Kirsher if (skb_padto(skb, length)) 4999e13fbf7SJeff Kirsher goto out; 5009e13fbf7SJeff Kirsher } 5019e13fbf7SJeff Kirsher 5029e13fbf7SJeff Kirsher next_ptr = (priv(dev)->tx_head + 1) & 15; 5039e13fbf7SJeff Kirsher 5049e13fbf7SJeff Kirsher local_irq_save(flags); 5059e13fbf7SJeff Kirsher 5069e13fbf7SJeff Kirsher if (priv(dev)->tx_tail == next_ptr) { 5079e13fbf7SJeff Kirsher local_irq_restore(flags); 5089e13fbf7SJeff Kirsher return NETDEV_TX_BUSY; /* unable to queue */ 5099e13fbf7SJeff Kirsher } 5109e13fbf7SJeff Kirsher 5119e13fbf7SJeff Kirsher ptr = 0x600 * priv(dev)->tx_head; 5129e13fbf7SJeff Kirsher priv(dev)->tx_head = next_ptr; 5139e13fbf7SJeff Kirsher next_ptr *= 0x600; 5149e13fbf7SJeff Kirsher 5159e13fbf7SJeff Kirsher #define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS) 5169e13fbf7SJeff Kirsher 5179e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_write, next_ptr); 5189e13fbf7SJeff Kirsher ether3_writelong(dev, 0); 5199e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_write, ptr); 5209e13fbf7SJeff Kirsher ether3_writelong(dev, 0); 5219e13fbf7SJeff Kirsher ether3_writebuffer(dev, skb->data, length); 5229e13fbf7SJeff Kirsher ether3_writeword(dev, htons(next_ptr)); 5239e13fbf7SJeff Kirsher ether3_writeword(dev, TXHDR_CHAINCONTINUE >> 16); 5249e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_write, ptr); 5259e13fbf7SJeff Kirsher ether3_writeword(dev, htons((ptr + length + 4))); 5269e13fbf7SJeff Kirsher ether3_writeword(dev, TXHDR_FLAGS >> 16); 5279e13fbf7SJeff Kirsher ether3_ledon(dev); 5289e13fbf7SJeff Kirsher 5299e13fbf7SJeff Kirsher if (!(ether3_inw(REG_STATUS) & STAT_TXON)) { 5309e13fbf7SJeff Kirsher ether3_outw(ptr, REG_TRANSMITPTR); 5319e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.command | CMD_TXON, REG_COMMAND); 5329e13fbf7SJeff Kirsher } 5339e13fbf7SJeff Kirsher 5349e13fbf7SJeff Kirsher next_ptr = (priv(dev)->tx_head + 1) & 15; 5359e13fbf7SJeff Kirsher local_irq_restore(flags); 5369e13fbf7SJeff Kirsher 5379e13fbf7SJeff Kirsher dev_kfree_skb(skb); 5389e13fbf7SJeff Kirsher 5399e13fbf7SJeff Kirsher if (priv(dev)->tx_tail == next_ptr) 5409e13fbf7SJeff Kirsher netif_stop_queue(dev); 5419e13fbf7SJeff Kirsher 5429e13fbf7SJeff Kirsher out: 5439e13fbf7SJeff Kirsher return NETDEV_TX_OK; 5449e13fbf7SJeff Kirsher } 5459e13fbf7SJeff Kirsher 5469e13fbf7SJeff Kirsher static irqreturn_t 5479e13fbf7SJeff Kirsher ether3_interrupt(int irq, void *dev_id) 5489e13fbf7SJeff Kirsher { 5499e13fbf7SJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 5509e13fbf7SJeff Kirsher unsigned int status, handled = IRQ_NONE; 5519e13fbf7SJeff Kirsher 5529e13fbf7SJeff Kirsher #if NET_DEBUG > 1 5539e13fbf7SJeff Kirsher if(net_debug & DEBUG_INT) 5549e13fbf7SJeff Kirsher printk("eth3irq: %d ", irq); 5559e13fbf7SJeff Kirsher #endif 5569e13fbf7SJeff Kirsher 5579e13fbf7SJeff Kirsher status = ether3_inw(REG_STATUS); 5589e13fbf7SJeff Kirsher 5599e13fbf7SJeff Kirsher if (status & STAT_INTRX) { 5609e13fbf7SJeff Kirsher ether3_outw(CMD_ACKINTRX | priv(dev)->regs.command, REG_COMMAND); 5619e13fbf7SJeff Kirsher ether3_rx(dev, 12); 5629e13fbf7SJeff Kirsher handled = IRQ_HANDLED; 5639e13fbf7SJeff Kirsher } 5649e13fbf7SJeff Kirsher 5659e13fbf7SJeff Kirsher if (status & STAT_INTTX) { 5669e13fbf7SJeff Kirsher ether3_outw(CMD_ACKINTTX | priv(dev)->regs.command, REG_COMMAND); 5679e13fbf7SJeff Kirsher ether3_tx(dev); 5689e13fbf7SJeff Kirsher handled = IRQ_HANDLED; 5699e13fbf7SJeff Kirsher } 5709e13fbf7SJeff Kirsher 5719e13fbf7SJeff Kirsher #if NET_DEBUG > 1 5729e13fbf7SJeff Kirsher if(net_debug & DEBUG_INT) 5739e13fbf7SJeff Kirsher printk("done\n"); 5749e13fbf7SJeff Kirsher #endif 5759e13fbf7SJeff Kirsher return handled; 5769e13fbf7SJeff Kirsher } 5779e13fbf7SJeff Kirsher 5789e13fbf7SJeff Kirsher /* 5799e13fbf7SJeff Kirsher * If we have a good packet(s), get it/them out of the buffers. 5809e13fbf7SJeff Kirsher */ 5819e13fbf7SJeff Kirsher static int ether3_rx(struct net_device *dev, unsigned int maxcnt) 5829e13fbf7SJeff Kirsher { 5839e13fbf7SJeff Kirsher unsigned int next_ptr = priv(dev)->rx_head, received = 0; 5849e13fbf7SJeff Kirsher 5859e13fbf7SJeff Kirsher ether3_ledon(dev); 5869e13fbf7SJeff Kirsher 5879e13fbf7SJeff Kirsher do { 5889e13fbf7SJeff Kirsher unsigned int this_ptr, status; 5899e13fbf7SJeff Kirsher unsigned char addrs[16]; 5909e13fbf7SJeff Kirsher 5919e13fbf7SJeff Kirsher /* 5929e13fbf7SJeff Kirsher * read the first 16 bytes from the buffer. 5939e13fbf7SJeff Kirsher * This contains the status bytes etc and ethernet addresses, 5949e13fbf7SJeff Kirsher * and we also check the source ethernet address to see if 5959e13fbf7SJeff Kirsher * it originated from us. 5969e13fbf7SJeff Kirsher */ 5979e13fbf7SJeff Kirsher { 5989e13fbf7SJeff Kirsher unsigned int temp_ptr; 5999e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_read, next_ptr); 6009e13fbf7SJeff Kirsher temp_ptr = ether3_readword(dev); 6019e13fbf7SJeff Kirsher status = ether3_readword(dev); 6029e13fbf7SJeff Kirsher if ((status & (RXSTAT_DONE | RXHDR_CHAINCONTINUE | RXHDR_RECEIVE)) != 6039e13fbf7SJeff Kirsher (RXSTAT_DONE | RXHDR_CHAINCONTINUE) || !temp_ptr) 6049e13fbf7SJeff Kirsher break; 6059e13fbf7SJeff Kirsher 6069e13fbf7SJeff Kirsher this_ptr = next_ptr + 4; 6079e13fbf7SJeff Kirsher next_ptr = ntohs(temp_ptr); 6089e13fbf7SJeff Kirsher } 6099e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_read, this_ptr); 6109e13fbf7SJeff Kirsher ether3_readbuffer(dev, addrs+2, 12); 6119e13fbf7SJeff Kirsher 6129e13fbf7SJeff Kirsher if (next_ptr < RX_START || next_ptr >= RX_END) { 6139e13fbf7SJeff Kirsher printk("%s: bad next pointer @%04X: ", dev->name, priv(dev)->rx_head); 6149e13fbf7SJeff Kirsher printk("%02X %02X %02X %02X ", next_ptr >> 8, next_ptr & 255, status & 255, status >> 8); 615*35e43c39SAndy Shevchenko printk("%pM %pM\n", addrs + 2, addrs + 8); 6169e13fbf7SJeff Kirsher next_ptr = priv(dev)->rx_head; 6179e13fbf7SJeff Kirsher break; 6189e13fbf7SJeff Kirsher } 6199e13fbf7SJeff Kirsher /* 6209e13fbf7SJeff Kirsher * ignore our own packets... 6219e13fbf7SJeff Kirsher */ 6229e13fbf7SJeff Kirsher if (!(*(unsigned long *)&dev->dev_addr[0] ^ *(unsigned long *)&addrs[2+6]) && 6239e13fbf7SJeff Kirsher !(*(unsigned short *)&dev->dev_addr[4] ^ *(unsigned short *)&addrs[2+10])) { 6249e13fbf7SJeff Kirsher maxcnt ++; /* compensate for loopedback packet */ 6259e13fbf7SJeff Kirsher ether3_outw(next_ptr >> 8, REG_RECVEND); 6269e13fbf7SJeff Kirsher } else 6279e13fbf7SJeff Kirsher if (!(status & (RXSTAT_OVERSIZE|RXSTAT_CRCERROR|RXSTAT_DRIBBLEERROR|RXSTAT_SHORTPACKET))) { 6289e13fbf7SJeff Kirsher unsigned int length = next_ptr - this_ptr; 6299e13fbf7SJeff Kirsher struct sk_buff *skb; 6309e13fbf7SJeff Kirsher 6319e13fbf7SJeff Kirsher if (next_ptr <= this_ptr) 6329e13fbf7SJeff Kirsher length += RX_END - RX_START; 6339e13fbf7SJeff Kirsher 634dae2e9f4SPradeep A. Dalvi skb = netdev_alloc_skb(dev, length + 2); 6359e13fbf7SJeff Kirsher if (skb) { 6369e13fbf7SJeff Kirsher unsigned char *buf; 6379e13fbf7SJeff Kirsher 6389e13fbf7SJeff Kirsher skb_reserve(skb, 2); 6399e13fbf7SJeff Kirsher buf = skb_put(skb, length); 6409e13fbf7SJeff Kirsher ether3_readbuffer(dev, buf + 12, length - 12); 6419e13fbf7SJeff Kirsher ether3_outw(next_ptr >> 8, REG_RECVEND); 6429e13fbf7SJeff Kirsher *(unsigned short *)(buf + 0) = *(unsigned short *)(addrs + 2); 6439e13fbf7SJeff Kirsher *(unsigned long *)(buf + 2) = *(unsigned long *)(addrs + 4); 6449e13fbf7SJeff Kirsher *(unsigned long *)(buf + 6) = *(unsigned long *)(addrs + 8); 6459e13fbf7SJeff Kirsher *(unsigned short *)(buf + 10) = *(unsigned short *)(addrs + 12); 6469e13fbf7SJeff Kirsher skb->protocol = eth_type_trans(skb, dev); 6479e13fbf7SJeff Kirsher netif_rx(skb); 6489e13fbf7SJeff Kirsher received ++; 649720a43efSJoe Perches } else { 650720a43efSJoe Perches ether3_outw(next_ptr >> 8, REG_RECVEND); 651720a43efSJoe Perches dev->stats.rx_dropped++; 652720a43efSJoe Perches goto done; 653720a43efSJoe Perches } 6549e13fbf7SJeff Kirsher } else { 6559e13fbf7SJeff Kirsher struct net_device_stats *stats = &dev->stats; 6569e13fbf7SJeff Kirsher ether3_outw(next_ptr >> 8, REG_RECVEND); 6579e13fbf7SJeff Kirsher if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++; 6589e13fbf7SJeff Kirsher if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++; 6599e13fbf7SJeff Kirsher if (status & RXSTAT_DRIBBLEERROR) stats->rx_fifo_errors ++; 6609e13fbf7SJeff Kirsher if (status & RXSTAT_SHORTPACKET) stats->rx_length_errors ++; 6619e13fbf7SJeff Kirsher stats->rx_errors++; 6629e13fbf7SJeff Kirsher } 6639e13fbf7SJeff Kirsher } 6649e13fbf7SJeff Kirsher while (-- maxcnt); 6659e13fbf7SJeff Kirsher 6669e13fbf7SJeff Kirsher done: 6679e13fbf7SJeff Kirsher dev->stats.rx_packets += received; 6689e13fbf7SJeff Kirsher priv(dev)->rx_head = next_ptr; 6699e13fbf7SJeff Kirsher /* 6709e13fbf7SJeff Kirsher * If rx went off line, then that means that the buffer may be full. We 6719e13fbf7SJeff Kirsher * have dropped at least one packet. 6729e13fbf7SJeff Kirsher */ 6739e13fbf7SJeff Kirsher if (!(ether3_inw(REG_STATUS) & STAT_RXON)) { 6749e13fbf7SJeff Kirsher dev->stats.rx_dropped++; 6759e13fbf7SJeff Kirsher ether3_outw(next_ptr, REG_RECVPTR); 6769e13fbf7SJeff Kirsher ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND); 6779e13fbf7SJeff Kirsher } 6789e13fbf7SJeff Kirsher 6799e13fbf7SJeff Kirsher return maxcnt; 6809e13fbf7SJeff Kirsher } 6819e13fbf7SJeff Kirsher 6829e13fbf7SJeff Kirsher /* 6839e13fbf7SJeff Kirsher * Update stats for the transmitted packet(s) 6849e13fbf7SJeff Kirsher */ 6859e13fbf7SJeff Kirsher static void ether3_tx(struct net_device *dev) 6869e13fbf7SJeff Kirsher { 6879e13fbf7SJeff Kirsher unsigned int tx_tail = priv(dev)->tx_tail; 6889e13fbf7SJeff Kirsher int max_work = 14; 6899e13fbf7SJeff Kirsher 6909e13fbf7SJeff Kirsher do { 6919e13fbf7SJeff Kirsher unsigned long status; 6929e13fbf7SJeff Kirsher 6939e13fbf7SJeff Kirsher /* 6949e13fbf7SJeff Kirsher * Read the packet header 6959e13fbf7SJeff Kirsher */ 6969e13fbf7SJeff Kirsher ether3_setbuffer(dev, buffer_read, tx_tail * 0x600); 6979e13fbf7SJeff Kirsher status = ether3_readlong(dev); 6989e13fbf7SJeff Kirsher 6999e13fbf7SJeff Kirsher /* 7009e13fbf7SJeff Kirsher * Check to see if this packet has been transmitted 7019e13fbf7SJeff Kirsher */ 7029e13fbf7SJeff Kirsher if ((status & (TXSTAT_DONE | TXHDR_TRANSMIT)) != 7039e13fbf7SJeff Kirsher (TXSTAT_DONE | TXHDR_TRANSMIT)) 7049e13fbf7SJeff Kirsher break; 7059e13fbf7SJeff Kirsher 7069e13fbf7SJeff Kirsher /* 7079e13fbf7SJeff Kirsher * Update errors 7089e13fbf7SJeff Kirsher */ 7099e13fbf7SJeff Kirsher if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS))) 7109e13fbf7SJeff Kirsher dev->stats.tx_packets++; 7119e13fbf7SJeff Kirsher else { 7129e13fbf7SJeff Kirsher dev->stats.tx_errors++; 7139e13fbf7SJeff Kirsher if (status & TXSTAT_16COLLISIONS) 7149e13fbf7SJeff Kirsher dev->stats.collisions += 16; 7159e13fbf7SJeff Kirsher if (status & TXSTAT_BABBLED) 7169e13fbf7SJeff Kirsher dev->stats.tx_fifo_errors++; 7179e13fbf7SJeff Kirsher } 7189e13fbf7SJeff Kirsher 7199e13fbf7SJeff Kirsher tx_tail = (tx_tail + 1) & 15; 7209e13fbf7SJeff Kirsher } while (--max_work); 7219e13fbf7SJeff Kirsher 7229e13fbf7SJeff Kirsher if (priv(dev)->tx_tail != tx_tail) { 7239e13fbf7SJeff Kirsher priv(dev)->tx_tail = tx_tail; 7249e13fbf7SJeff Kirsher netif_wake_queue(dev); 7259e13fbf7SJeff Kirsher } 7269e13fbf7SJeff Kirsher } 7279e13fbf7SJeff Kirsher 7285911ce0dSBill Pemberton static void ether3_banner(void) 7299e13fbf7SJeff Kirsher { 7309e13fbf7SJeff Kirsher static unsigned version_printed = 0; 7319e13fbf7SJeff Kirsher 7329e13fbf7SJeff Kirsher if (net_debug && version_printed++ == 0) 7339e13fbf7SJeff Kirsher printk(KERN_INFO "%s", version); 7349e13fbf7SJeff Kirsher } 7359e13fbf7SJeff Kirsher 7369e13fbf7SJeff Kirsher static const struct net_device_ops ether3_netdev_ops = { 7379e13fbf7SJeff Kirsher .ndo_open = ether3_open, 7389e13fbf7SJeff Kirsher .ndo_stop = ether3_close, 7399e13fbf7SJeff Kirsher .ndo_start_xmit = ether3_sendpacket, 740afc4b13dSJiri Pirko .ndo_set_rx_mode = ether3_setmulticastlist, 7419e13fbf7SJeff Kirsher .ndo_tx_timeout = ether3_timeout, 7429e13fbf7SJeff Kirsher .ndo_validate_addr = eth_validate_addr, 7439e13fbf7SJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 7449e13fbf7SJeff Kirsher }; 7459e13fbf7SJeff Kirsher 7465911ce0dSBill Pemberton static int 7479e13fbf7SJeff Kirsher ether3_probe(struct expansion_card *ec, const struct ecard_id *id) 7489e13fbf7SJeff Kirsher { 7499e13fbf7SJeff Kirsher const struct ether3_data *data = id->data; 7509e13fbf7SJeff Kirsher struct net_device *dev; 7519e13fbf7SJeff Kirsher int bus_type, ret; 7529e13fbf7SJeff Kirsher 7539e13fbf7SJeff Kirsher ether3_banner(); 7549e13fbf7SJeff Kirsher 7559e13fbf7SJeff Kirsher ret = ecard_request_resources(ec); 7569e13fbf7SJeff Kirsher if (ret) 7579e13fbf7SJeff Kirsher goto out; 7589e13fbf7SJeff Kirsher 7599e13fbf7SJeff Kirsher dev = alloc_etherdev(sizeof(struct dev_priv)); 7609e13fbf7SJeff Kirsher if (!dev) { 7619e13fbf7SJeff Kirsher ret = -ENOMEM; 7629e13fbf7SJeff Kirsher goto release; 7639e13fbf7SJeff Kirsher } 7649e13fbf7SJeff Kirsher 7659e13fbf7SJeff Kirsher SET_NETDEV_DEV(dev, &ec->dev); 7669e13fbf7SJeff Kirsher 7679e13fbf7SJeff Kirsher priv(dev)->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); 7689e13fbf7SJeff Kirsher if (!priv(dev)->base) { 7699e13fbf7SJeff Kirsher ret = -ENOMEM; 7709e13fbf7SJeff Kirsher goto free; 7719e13fbf7SJeff Kirsher } 7729e13fbf7SJeff Kirsher 7739e13fbf7SJeff Kirsher ec->irqaddr = priv(dev)->base + data->base_offset; 7749e13fbf7SJeff Kirsher ec->irqmask = 0xf0; 7759e13fbf7SJeff Kirsher 7769e13fbf7SJeff Kirsher priv(dev)->seeq = priv(dev)->base + data->base_offset; 7779e13fbf7SJeff Kirsher dev->irq = ec->irq; 7789e13fbf7SJeff Kirsher 7799e13fbf7SJeff Kirsher ether3_addr(dev->dev_addr, ec); 7809e13fbf7SJeff Kirsher 7816fd9c53fSKees Cook priv(dev)->dev = dev; 7826fd9c53fSKees Cook timer_setup(&priv(dev)->timer, ether3_ledoff, 0); 7839e13fbf7SJeff Kirsher 7849e13fbf7SJeff Kirsher /* Reset card... 7859e13fbf7SJeff Kirsher */ 7869e13fbf7SJeff Kirsher ether3_outb(0x80, REG_CONFIG2 + 4); 7879e13fbf7SJeff Kirsher bus_type = BUS_UNKNOWN; 7889e13fbf7SJeff Kirsher udelay(4); 7899e13fbf7SJeff Kirsher 7909e13fbf7SJeff Kirsher /* Test using Receive Pointer (16-bit register) to find out 7919e13fbf7SJeff Kirsher * how the ether3 is connected to the bus... 7929e13fbf7SJeff Kirsher */ 7939e13fbf7SJeff Kirsher if (ether3_probe_bus_8(dev, 0x100) && 7949e13fbf7SJeff Kirsher ether3_probe_bus_8(dev, 0x201)) 7959e13fbf7SJeff Kirsher bus_type = BUS_8; 7969e13fbf7SJeff Kirsher 7979e13fbf7SJeff Kirsher if (bus_type == BUS_UNKNOWN && 7989e13fbf7SJeff Kirsher ether3_probe_bus_16(dev, 0x101) && 7999e13fbf7SJeff Kirsher ether3_probe_bus_16(dev, 0x201)) 8009e13fbf7SJeff Kirsher bus_type = BUS_16; 8019e13fbf7SJeff Kirsher 8029e13fbf7SJeff Kirsher switch (bus_type) { 8039e13fbf7SJeff Kirsher case BUS_UNKNOWN: 8049e13fbf7SJeff Kirsher printk(KERN_ERR "%s: unable to identify bus width\n", dev->name); 8059e13fbf7SJeff Kirsher ret = -ENODEV; 8069e13fbf7SJeff Kirsher goto free; 8079e13fbf7SJeff Kirsher 8089e13fbf7SJeff Kirsher case BUS_8: 8099e13fbf7SJeff Kirsher printk(KERN_ERR "%s: %s found, but is an unsupported " 8109e13fbf7SJeff Kirsher "8-bit card\n", dev->name, data->name); 8119e13fbf7SJeff Kirsher ret = -ENODEV; 8129e13fbf7SJeff Kirsher goto free; 8139e13fbf7SJeff Kirsher 8149e13fbf7SJeff Kirsher default: 8159e13fbf7SJeff Kirsher break; 8169e13fbf7SJeff Kirsher } 8179e13fbf7SJeff Kirsher 8189e13fbf7SJeff Kirsher if (ether3_init_2(dev)) { 8199e13fbf7SJeff Kirsher ret = -ENODEV; 8209e13fbf7SJeff Kirsher goto free; 8219e13fbf7SJeff Kirsher } 8229e13fbf7SJeff Kirsher 8239e13fbf7SJeff Kirsher dev->netdev_ops = ðer3_netdev_ops; 8249e13fbf7SJeff Kirsher dev->watchdog_timeo = 5 * HZ / 100; 8259e13fbf7SJeff Kirsher 8269e13fbf7SJeff Kirsher ret = register_netdev(dev); 8279e13fbf7SJeff Kirsher if (ret) 8289e13fbf7SJeff Kirsher goto free; 8299e13fbf7SJeff Kirsher 8309e13fbf7SJeff Kirsher printk("%s: %s in slot %d, %pM\n", 8319e13fbf7SJeff Kirsher dev->name, data->name, ec->slot_no, dev->dev_addr); 8329e13fbf7SJeff Kirsher 8339e13fbf7SJeff Kirsher ecard_set_drvdata(ec, dev); 8349e13fbf7SJeff Kirsher return 0; 8359e13fbf7SJeff Kirsher 8369e13fbf7SJeff Kirsher free: 8379e13fbf7SJeff Kirsher free_netdev(dev); 8389e13fbf7SJeff Kirsher release: 8399e13fbf7SJeff Kirsher ecard_release_resources(ec); 8409e13fbf7SJeff Kirsher out: 8419e13fbf7SJeff Kirsher return ret; 8429e13fbf7SJeff Kirsher } 8439e13fbf7SJeff Kirsher 8445911ce0dSBill Pemberton static void ether3_remove(struct expansion_card *ec) 8459e13fbf7SJeff Kirsher { 8469e13fbf7SJeff Kirsher struct net_device *dev = ecard_get_drvdata(ec); 8479e13fbf7SJeff Kirsher 8489e13fbf7SJeff Kirsher ecard_set_drvdata(ec, NULL); 8499e13fbf7SJeff Kirsher 8509e13fbf7SJeff Kirsher unregister_netdev(dev); 8519e13fbf7SJeff Kirsher free_netdev(dev); 8529e13fbf7SJeff Kirsher ecard_release_resources(ec); 8539e13fbf7SJeff Kirsher } 8549e13fbf7SJeff Kirsher 8559e13fbf7SJeff Kirsher static struct ether3_data ether3 = { 8569e13fbf7SJeff Kirsher .name = "ether3", 8579e13fbf7SJeff Kirsher .base_offset = 0, 8589e13fbf7SJeff Kirsher }; 8599e13fbf7SJeff Kirsher 8609e13fbf7SJeff Kirsher static struct ether3_data etherb = { 8619e13fbf7SJeff Kirsher .name = "etherb", 8629e13fbf7SJeff Kirsher .base_offset = 0x800, 8639e13fbf7SJeff Kirsher }; 8649e13fbf7SJeff Kirsher 8659e13fbf7SJeff Kirsher static const struct ecard_id ether3_ids[] = { 8669e13fbf7SJeff Kirsher { MANU_ANT2, PROD_ANT_ETHER3, ðer3 }, 8679e13fbf7SJeff Kirsher { MANU_ANT, PROD_ANT_ETHER3, ðer3 }, 8689e13fbf7SJeff Kirsher { MANU_ANT, PROD_ANT_ETHERB, ðerb }, 8699e13fbf7SJeff Kirsher { 0xffff, 0xffff } 8709e13fbf7SJeff Kirsher }; 8719e13fbf7SJeff Kirsher 8729e13fbf7SJeff Kirsher static struct ecard_driver ether3_driver = { 8739e13fbf7SJeff Kirsher .probe = ether3_probe, 8745911ce0dSBill Pemberton .remove = ether3_remove, 8759e13fbf7SJeff Kirsher .id_table = ether3_ids, 8769e13fbf7SJeff Kirsher .drv = { 8779e13fbf7SJeff Kirsher .name = "ether3", 8789e13fbf7SJeff Kirsher }, 8799e13fbf7SJeff Kirsher }; 8809e13fbf7SJeff Kirsher 8819e13fbf7SJeff Kirsher static int __init ether3_init(void) 8829e13fbf7SJeff Kirsher { 8839e13fbf7SJeff Kirsher return ecard_register_driver(ðer3_driver); 8849e13fbf7SJeff Kirsher } 8859e13fbf7SJeff Kirsher 8869e13fbf7SJeff Kirsher static void __exit ether3_exit(void) 8879e13fbf7SJeff Kirsher { 8889e13fbf7SJeff Kirsher ecard_remove_driver(ðer3_driver); 8899e13fbf7SJeff Kirsher } 8909e13fbf7SJeff Kirsher 8919e13fbf7SJeff Kirsher module_init(ether3_init); 8929e13fbf7SJeff Kirsher module_exit(ether3_exit); 8939e13fbf7SJeff Kirsher 8949e13fbf7SJeff Kirsher MODULE_LICENSE("GPL"); 895