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