^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Written 1993-2000 by Donald Becker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) Copyright 1994-2000 by Donald Becker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) Copyright 1993 United States Government as represented by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) Director, National Security Agency. This software may be used and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) distributed according to the terms of the GNU General Public License,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) incorporated herein by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) This driver is for the 3Com EtherLinkIII series.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) The author may be reached as becker@scyld.com, or C/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) Scyld Computing Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 410 Severn Ave., Suite 210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) Annapolis MD 21403
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) Known limitations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) Because of the way 3c509 ISA detection works it's difficult to predict
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) a priori which of several ISA-mode cards will be detected first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) This driver does not use predictive interrupt mode, resulting in higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) packet latency but lower overhead. If interrupts are disabled for an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unusually long time it could also result in missed packets, but in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) practice this rarely happens.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) FIXES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) Alan Cox: Removed the 'Unexpected interrupt' bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) Michael Meskes: Upgraded to Donald Becker's version 1.07.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) Alan Cox: Increased the eeprom delay. Regardless of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) what the docs say some people definitely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) get problems with lower (but in card spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) delays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) v1.10 4/21/97 Fixed module code so that multiple cards may be detected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) other cleanups. -djb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) Andrea Arcangeli: Upgraded to Donald Becker's version 1.12.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) Rick Payne: Fixed SMP race condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) v1.13 9/8/97 Made 'max_interrupt_work' an insmod-settable variable -djb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) v1.15 1/31/98 Faster recovery for Tx errors. -djb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) v1.18 12Mar2001 Andrew Morton
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) - Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) - Reviewed against 1.18 from scyld.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) - ethtool support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) v1.18b 1Mar2002 Zwane Mwaikambo <zwane@commfireservices.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) - Power Management support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) v1.18c 1Mar2002 David Ruggiero <jdr@farfalle.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) - Full duplex support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) v1.19 16Oct2002 Zwane Mwaikambo <zwane@linuxpower.ca>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) - Additional ethtool features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) - Increase *read_eeprom udelay to workaround oops with 2 cards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) - Introduce driver model for EISA cards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) v1.20 04Feb2008 Ondrej Zary <linux@rainbow-software.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) - convert to isa_driver and pnp_driver and some cleanups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DRV_NAME "3c509"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* A few values that may be tweaked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Time in jiffies before concluding the transmitter is hung. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define TX_TIMEOUT (400*HZ/1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <linux/isa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #include <linux/delay.h> /* for udelay() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #include <linux/eisa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #ifdef EL3_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int el3_debug = EL3_DEBUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int el3_debug = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* Used to do a global count of all the cards in the system. Must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * a global variable so that the eisa probe routines can increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int el3_cards = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define EL3_MAX_CARDS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* To minimize the size of the driver source I only define operating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) constants if they are used several times. You'll need the manual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) anyway if you want to understand driver details. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Offsets from base I/O address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define EL3_DATA 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define EL3_CMD 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define EL3_STATUS 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define EEPROM_READ 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define EL3_IO_EXTENT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* The top five bits written to EL3_CMD are a command, the lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 11 bits are the parameter, if applicable. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) enum c509cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) StatsDisable = 22<<11, StopCoax = 23<<11, PowerUp = 27<<11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) PowerDown = 28<<11, PowerAuto = 29<<11};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) enum c509status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* The SetRxFilter command accepts the following classes: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) enum RxFilter {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* Register window 1 offsets, the window used in normal operation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define TX_FIFO 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define RX_FIFO 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define RX_STATUS 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define TX_STATUS 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define WN0_CONF_CTRL 0x04 /* Window 0: Configuration control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define WN0_ADDR_CONF 0x06 /* Window 0: Address configuration register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define WN0_IRQ 0x08 /* Window 0: Set IRQ line in bits 12-15. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define WN4_MEDIA 0x0A /* Window 4: Various transcvr/media bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define WN4_NETDIAG 0x06 /* Window 4: Net diagnostic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define FD_ENABLE 0x8000 /* Enable full-duplex ("external loopback") */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * Must be a power of two (we use a binary and in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * circular queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define SKB_QUEUE_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_EISA };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct el3_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* skb send-queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int head, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct sk_buff *queue[SKB_QUEUE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) enum el3_cardtype type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int id_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static int current_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static struct net_device *el3_devs[EL3_MAX_CARDS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* Parameters that may be passed into the module. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int debug = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int max_interrupt_work = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int nopnp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int el3_common_init(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void el3_common_remove(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static ushort id_read_eeprom(int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static ushort read_eeprom(int ioaddr, int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int el3_open(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static netdev_tx_t el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static irqreturn_t el3_interrupt(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void update_stats(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static struct net_device_stats *el3_get_stats(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int el3_rx(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int el3_close(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void set_multicast_list(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static void el3_tx_timeout (struct net_device *dev, unsigned int txqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static void el3_down(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static void el3_up(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static const struct ethtool_ops ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int el3_suspend(struct device *, pm_message_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int el3_resume(struct device *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define el3_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define el3_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* generic device remove for all device types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int el3_device_remove (struct device *device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void el3_poll_controller(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Return 0 on success, 1 on error, 2 when found already detected PnP card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static int el3_isa_id_sequence(__be16 *phys_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) short lrs_state = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* ISA boards are detected by sending the ID sequence to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ID_PORT. We find cards past the first by setting the 'current_tag'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) on cards as they are found. Cards with their tag set will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) respond to subsequent ID sequences. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) outb(0x00, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) outb(0x00, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) for (i = 0; i < 255; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) outb(lrs_state, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) lrs_state <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* For the first probe, clear all board's tag registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (current_tag == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) outb(0xd0, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) else /* Otherwise kill off already-found boards. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) outb(0xd8, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (id_read_eeprom(7) != 0x6d50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* Read in EEPROM data, which does contention-select.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) Only the lowest address board will stay "on-line".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 3Com got the byte order backwards. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) phys_addr[i] = htons(id_read_eeprom(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!nopnp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* The ISA PnP 3c509 cards respond to the ID sequence too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) This check is needed in order not to register them twice. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) for (i = 0; i < el3_cards; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct el3_private *lp = netdev_priv(el3_devs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (lp->type == EL3_PNP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ether_addr_equal((u8 *)phys_addr, el3_devs[i]->dev_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (el3_debug > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) phys_addr[0] & 0xff, phys_addr[0] >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) phys_addr[1] & 0xff, phys_addr[1] >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) phys_addr[2] & 0xff, phys_addr[2] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Set the adaptor tag so that the next card can be found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) outb(0xd0 + ++current_tag, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static void el3_dev_fill(struct net_device *dev, __be16 *phys_addr, int ioaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int irq, int if_port, enum el3_cardtype type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) memcpy(dev->dev_addr, phys_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dev->base_addr = ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) dev->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev->if_port = if_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) lp->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int el3_isa_match(struct device *pdev, unsigned int ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int ioaddr, isa_irq, if_port, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) unsigned int iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) __be16 phys_addr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) while ((err = el3_isa_id_sequence(phys_addr)) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ; /* Skip to next card when PnP card found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (err == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) iobase = id_read_eeprom(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if_port = iobase >> 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ioaddr = 0x200 + ((iobase & 0x1f) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (irq[el3_cards] > 1 && irq[el3_cards] < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) isa_irq = irq[el3_cards];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) isa_irq = id_read_eeprom(9) >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dev = alloc_etherdev(sizeof(struct el3_private));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) SET_NETDEV_DEV(dev, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) netdev_boot_setup_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* Set the adaptor tag so that the next card can be found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) outb(0xd0 + ++current_tag, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Activate the adaptor at the EEPROM location. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) outb((ioaddr >> 4) | 0xe0, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (inw(ioaddr) != 0x6d50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Free the interrupt so that some other card can use it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) outw(0x0f00, ioaddr + WN0_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) el3_dev_fill(dev, phys_addr, ioaddr, isa_irq, if_port, EL3_ISA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) dev_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (el3_common_init(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) el3_devs[el3_cards++] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int el3_isa_remove(struct device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) unsigned int ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) el3_device_remove(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dev_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int el3_isa_suspend(struct device *dev, unsigned int n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) current_tag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return el3_suspend(dev, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int el3_isa_resume(struct device *dev, unsigned int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct net_device *ndev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int ioaddr = ndev->base_addr, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) __be16 phys_addr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) while ((err = el3_isa_id_sequence(phys_addr)) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ; /* Skip to next card when PnP card found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (err == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Set the adaptor tag so that the next card can be found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) outb(0xd0 + ++current_tag, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Enable the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) outb((ioaddr >> 4) | 0xe0, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (inw(ioaddr) != 0x6d50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Free the interrupt so that some other card can use it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) outw(0x0f00, ioaddr + WN0_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return el3_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static struct isa_driver el3_isa_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .match = el3_isa_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .remove = el3_isa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .suspend = el3_isa_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .resume = el3_isa_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .name = "3c509"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static int isa_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static const struct pnp_device_id el3_pnp_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) { .id = "TCM5091" }, /* 3Com Etherlink III */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) { .id = "TCM5095" }, /* 3Com Etherlink III (TPO) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) { .id = "TCM5098" }, /* 3Com Etherlink III (TPC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) { .id = "PNP80f7" }, /* 3Com Etherlink III compatible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) { .id = "PNP80f8" }, /* 3Com Etherlink III compatible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) { .id = "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) MODULE_DEVICE_TABLE(pnp, el3_pnp_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int el3_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) short i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ioaddr, irq, if_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) __be16 phys_addr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct net_device *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ioaddr = pnp_port_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-pnp"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) irq = pnp_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) phys_addr[i] = htons(read_eeprom(ioaddr, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if_port = read_eeprom(ioaddr, 8) >> 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dev = alloc_etherdev(sizeof(struct el3_private));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) release_region(ioaddr, EL3_IO_EXTENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) SET_NETDEV_DEV(dev, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) netdev_boot_setup_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_PNP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) pnp_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) err = el3_common_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) pnp_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) el3_devs[el3_cards++] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static void el3_pnp_remove(struct pnp_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) el3_common_remove(pnp_get_drvdata(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pnp_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int el3_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return el3_suspend(&pdev->dev, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int el3_pnp_resume(struct pnp_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return el3_resume(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static struct pnp_driver el3_pnp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .name = "3c509",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .id_table = el3_pnp_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .probe = el3_pnp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .remove = el3_pnp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .suspend = el3_pnp_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .resume = el3_pnp_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static int pnp_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static const struct eisa_device_id el3_eisa_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) { "TCM5090" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) { "TCM5091" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) { "TCM5092" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) { "TCM5093" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) { "TCM5094" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) { "TCM5095" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) { "TCM5098" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) { "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) MODULE_DEVICE_TABLE(eisa, el3_eisa_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int el3_eisa_probe (struct device *device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static struct eisa_driver el3_eisa_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .id_table = el3_eisa_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .name = "3c579",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .probe = el3_eisa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .remove = el3_device_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .suspend = el3_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .resume = el3_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int eisa_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static const struct net_device_ops netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .ndo_open = el3_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .ndo_stop = el3_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .ndo_start_xmit = el3_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .ndo_get_stats = el3_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .ndo_set_rx_mode = set_multicast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .ndo_tx_timeout = el3_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .ndo_poll_controller = el3_poll_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int el3_common_init(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) spin_lock_init(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) dev->if_port = (dev->mem_start & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) } else { /* xcvr codes 0/8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* use eeprom value, but save user's full-duplex selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dev->if_port |= (dev->mem_start & 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* The EL3-specific entries in the device structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dev->netdev_ops = &netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dev->watchdog_timeo = TX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dev->ethtool_ops = ðtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) dev->base_addr, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) release_region(dev->base_addr, EL3_IO_EXTENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) dev->dev_addr, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static void el3_common_remove (struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) unregister_netdev (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) release_region(dev->base_addr, EL3_IO_EXTENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) free_netdev (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int el3_eisa_probe(struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) short i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int ioaddr, irq, if_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) __be16 phys_addr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct net_device *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct eisa_device *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* Yeepee, The driver framework is calling us ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) edev = to_eisa_device (device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ioaddr = edev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!request_region(ioaddr, EL3_IO_EXTENT, "3c579-eisa"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* Change the register set to the configuration window 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) irq = inw(ioaddr + WN0_IRQ) >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if_port = inw(ioaddr + 6)>>14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) phys_addr[i] = htons(read_eeprom(ioaddr, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* Restore the "Product ID" to the EEPROM read register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) read_eeprom(ioaddr, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) dev = alloc_etherdev(sizeof (struct el3_private));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) release_region(ioaddr, EL3_IO_EXTENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) SET_NETDEV_DEV(dev, device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) netdev_boot_setup_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) eisa_set_drvdata (edev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) err = el3_common_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) eisa_set_drvdata (edev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) el3_devs[el3_cards++] = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* This remove works for all device types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * The net dev must be stored in the driver data field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static int el3_device_remove(struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) dev = dev_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) el3_common_remove (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* Read a word from the EEPROM using the regular EEPROM access register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) Assume that we are in register window zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static ushort read_eeprom(int ioaddr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) outw(EEPROM_READ + index, ioaddr + 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* Pause for at least 162 us. for the read to take place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) Some chips seem to require much longer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) mdelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return inw(ioaddr + 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* Read a word from the EEPROM when in the ISA ID probe state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static ushort id_read_eeprom(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int bit, word = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* Issue read command, and pause for at least 162 us. for it to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) Assume extra-fast 16Mhz bus. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) outb(EEPROM_READ + index, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* Pause for at least 162 us. for the read to take place. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /* Some chips seem to require much longer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) mdelay(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) for (bit = 15; bit >= 0; bit--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) word = (word << 1) + (inb(id_port) & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (el3_debug > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) pr_debug(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) el3_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) outw(TxReset, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) outw(RxReset, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) i = request_irq(dev->irq, el3_interrupt, 0, dev->name, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (el3_debug > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) pr_debug("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) el3_up(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (el3_debug > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pr_debug("%s: Opened 3c509 IRQ %d status %4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) el3_tx_timeout (struct net_device *dev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* Transmitter timeout, serious problems. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) pr_warn("%s: transmit timed out, Tx_status %2.2x status %4.4x Tx FIFO room %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) inw(ioaddr + TX_FREE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) netif_trans_update(dev); /* prevent tx timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* Issue TX_RESET and TX_START commands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) outw(TxReset, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) outw(TxEnable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static netdev_tx_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) netif_stop_queue (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) dev->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (el3_debug > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) dev->name, skb->len, inw(ioaddr + EL3_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * We lock the driver against other processors. Note
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * we don't need to lock versus the IRQ as we suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * that. This means that we lose the ability to take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * an RX during a TX upload. That sucks a bit with SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * on an original 3c509 (2K buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * Using disable_irq stops us crapping on other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * time sensitive devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) spin_lock_irqsave(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* Put out the doubleword header... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) outw(skb->len, ioaddr + TX_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) outw(0x00, ioaddr + TX_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* ... and the packet rounded to a doubleword. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (inw(ioaddr + TX_FREE) > 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Interrupt us when the FIFO has room for max-sized packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) spin_unlock_irqrestore(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) dev_consume_skb_any (skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* Clear the Tx status stack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) short tx_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int i = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) while (--i > 0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* The EL3 interrupt handler. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) el3_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct net_device *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct el3_private *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int ioaddr, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) int i = max_interrupt_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) spin_lock(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (el3_debug > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) status = inw(ioaddr + EL3_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) while ((status = inw(ioaddr + EL3_STATUS)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) (IntLatch | RxComplete | StatsFull)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (status & RxComplete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) el3_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (status & TxAvailable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (el3_debug > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) pr_debug(" TX room bit was handled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /* There's room in the FIFO for a full-sized packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) netif_wake_queue (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (status & (AdapterFailure | RxEarly | StatsFull | TxComplete)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* Handle all uncommon interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (status & StatsFull) /* Empty statistics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) update_stats(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (status & RxEarly) { /* Rx early is unused. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) el3_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (status & TxComplete) { /* Really Tx error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) short tx_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int i = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (status & AdapterFailure) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* Adapter failure requires Rx reset and reinit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) outw(RxReset, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* Set the Rx filter to the current state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) outw(SetRxFilter | RxStation | RxBroadcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) | (dev->flags & IFF_PROMISC ? RxProm : 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (--i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) pr_err("%s: Infinite loop in interrupt, status %4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) dev->name, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Clear all interrupts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* Acknowledge the IRQ. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); /* Ack IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (el3_debug > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) inw(ioaddr + EL3_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) spin_unlock(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * Polling receive - used by netconsole and other diagnostic tools
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * to allow network i/o with interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) static void el3_poll_controller(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) disable_irq(dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) el3_interrupt(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) enable_irq(dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static struct net_device_stats *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) el3_get_stats(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * This is fast enough not to bother with disable IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * stuff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) spin_lock_irqsave(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) update_stats(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) spin_unlock_irqrestore(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return &dev->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* Update statistics. We change to register window 6, so this should be run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) single-threaded if the device is active. This is expected to be a rare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) operation, and it's simpler for the rest of the driver to assume that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) window 1 is always valid rather than use a special window-state variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static void update_stats(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (el3_debug > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) pr_debug(" Updating the statistics.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* Turn off statistics updates while reading. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) outw(StatsDisable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /* Switch to the stats window, and read everything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) EL3WINDOW(6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) dev->stats.tx_carrier_errors += inb(ioaddr + 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /* Multiple collisions. */ inb(ioaddr + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) dev->stats.collisions += inb(ioaddr + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) dev->stats.tx_window_errors += inb(ioaddr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) dev->stats.rx_fifo_errors += inb(ioaddr + 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) dev->stats.tx_packets += inb(ioaddr + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* Rx packets */ inb(ioaddr + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* Tx deferrals */ inb(ioaddr + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) inw(ioaddr + 10); /* Total Rx and Tx octets. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) inw(ioaddr + 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /* Back to window 1, and turn statistics back on. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) EL3WINDOW(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) outw(StatsEnable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) el3_rx(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) short rx_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (el3_debug > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (rx_status & 0x4000) { /* Error, update stats. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) short error = rx_status & 0x3800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) outw(RxDiscard, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) case 0x0000: dev->stats.rx_over_errors++; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) case 0x0800: dev->stats.rx_length_errors++; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) case 0x1000: dev->stats.rx_frame_errors++; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) case 0x1800: dev->stats.rx_length_errors++; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) case 0x2000: dev->stats.rx_frame_errors++; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) case 0x2800: dev->stats.rx_crc_errors++; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) short pkt_len = rx_status & 0x7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) skb = netdev_alloc_skb(dev, pkt_len + 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (el3_debug > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) pr_debug("Receiving packet size %d status %4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) pkt_len, rx_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (skb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) skb_reserve(skb, 2); /* Align IP on 16 byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /* 'skb->data' points to the start of sk_buff data area. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) (pkt_len + 3) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) skb->protocol = eth_type_trans(skb,dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) dev->stats.rx_bytes += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) outw(RxDiscard, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (el3_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dev->name, pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) inw(ioaddr + EL3_STATUS); /* Delay. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) while (inw(ioaddr + EL3_STATUS) & 0x1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) pr_debug(" Waiting for 3c509 to discard packet, status %x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) inw(ioaddr + EL3_STATUS) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * Set or clear the multicast filter for this adaptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) set_multicast_list(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int mc_count = netdev_mc_count(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (el3_debug > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static int old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (old != mc_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) old = mc_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) pr_debug("%s: Setting Rx mode to %d addresses.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) dev->name, mc_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) spin_lock_irqsave(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (dev->flags&IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) else if (mc_count || (dev->flags&IFF_ALLMULTI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) spin_unlock_irqrestore(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) el3_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (el3_debug > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) pr_debug("%s: Shutting down ethercard.\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) el3_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) free_irq(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* Switching back to window 0 disables the IRQ. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (lp->type != EL3_EISA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* But we explicitly zero the IRQ line select anyway. Don't do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * it on EISA cards, it prevents the module from getting an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * IRQ after unload+reload... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) outw(0x0f00, ioaddr + WN0_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) el3_link_ok(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) u16 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) EL3WINDOW(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) tmp = inw(ioaddr + WN4_MEDIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) EL3WINDOW(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) return tmp & (1<<11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) u16 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) u32 supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /* obtain current transceiver via WN4_MEDIA? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) tmp = inw(ioaddr + WN0_ADDR_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) switch (tmp >> 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) cmd->base.port = PORT_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) cmd->base.port = PORT_AUI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) cmd->base.port = PORT_BNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) cmd->base.duplex = DUPLEX_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) tmp = inw(ioaddr + WN0_CONF_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (tmp & (1<<13))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) supported |= SUPPORTED_AUI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (tmp & (1<<12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) supported |= SUPPORTED_BNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (tmp & (1<<9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) supported |= SUPPORTED_TP | SUPPORTED_10baseT_Half |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) SUPPORTED_10baseT_Full; /* hmm... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) EL3WINDOW(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) tmp = inw(ioaddr + WN4_NETDIAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (tmp & FD_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) cmd->base.duplex = DUPLEX_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) cmd->base.speed = SPEED_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) EL3WINDOW(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) el3_netdev_set_ecmd(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) const struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) u16 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (cmd->base.speed != SPEED_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if ((cmd->base.duplex != DUPLEX_HALF) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) (cmd->base.duplex != DUPLEX_FULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /* change XCVR type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) tmp = inw(ioaddr + WN0_ADDR_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) switch (cmd->base.port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) case PORT_TP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) tmp &= ~(3<<14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) dev->if_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) case PORT_AUI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) tmp |= (1<<14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) dev->if_port = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) case PORT_BNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) tmp |= (3<<14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) dev->if_port = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) outw(tmp, ioaddr + WN0_ADDR_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (dev->if_port == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /* fire up the DC-DC convertor if BNC gets enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) tmp = inw(ioaddr + WN0_ADDR_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (tmp & (3 << 14)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) outw(StartCoax, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) udelay(800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) EL3WINDOW(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) tmp = inw(ioaddr + WN4_NETDIAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (cmd->base.duplex == DUPLEX_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) tmp |= FD_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) tmp &= ~FD_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) outw(tmp, ioaddr + WN4_NETDIAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) EL3WINDOW(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static void el3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int el3_get_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) spin_lock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) el3_netdev_get_ecmd(dev, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) spin_unlock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static int el3_set_link_ksettings(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) const struct ethtool_link_ksettings *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) spin_lock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ret = el3_netdev_set_ecmd(dev, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) spin_unlock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static u32 el3_get_link(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct el3_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) u32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) spin_lock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ret = el3_link_ok(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) spin_unlock_irq(&lp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static u32 el3_get_msglevel(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return el3_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) static void el3_set_msglevel(struct net_device *dev, u32 v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) el3_debug = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static const struct ethtool_ops ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) .get_drvinfo = el3_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) .get_link = el3_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) .get_msglevel = el3_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) .set_msglevel = el3_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) .get_link_ksettings = el3_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) .set_link_ksettings = el3_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) el3_down(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* Turn off statistics ASAP. We update lp->stats below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) outw(StatsDisable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* Disable the receiver and transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) outw(RxDisable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) outw(TxDisable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (dev->if_port == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* Turn off thinnet power. Green! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) outw(StopCoax, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) else if (dev->if_port == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /* Disable link beat and jabber, if_port may change here next open(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) EL3WINDOW(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) update_stats(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) el3_up(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) int i, sw_info, net_diag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) int ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /* Activating the board required and does no harm otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) outw(0x0001, ioaddr + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) /* Set the IRQ line. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) /* Set the station address in window 2 each time opened. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) EL3WINDOW(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) for (i = 0; i < 6; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) outb(dev->dev_addr[i], ioaddr + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if ((dev->if_port & 0x03) == 3) /* BNC interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) /* Start the thinnet transceiver. We should really wait 50ms...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) outw(StartCoax, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) else if ((dev->if_port & 0x03) == 0) { /* 10baseT interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) /* Combine secondary sw_info word (the adapter level) and primary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) sw_info word (duplex setting plus other useless bits) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) (read_eeprom(ioaddr, 0x0d) & 0xBff0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) EL3WINDOW(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) net_diag = inw(ioaddr + WN4_NETDIAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) pr_info("%s: ", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) switch (dev->if_port & 0x0c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) /* force full-duplex mode if 3c5x9b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (sw_info & 0x000f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) pr_cont("Forcing 3c5x9b full-duplex mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /* set full-duplex mode based on eeprom config setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) /* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) pr_cont("Setting 3c5x9/3c5x9B half-duplex mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) outw(net_diag, ioaddr + WN4_NETDIAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (el3_debug > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* Enable link beat and jabber check. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) /* Switch to the stats window, and clear all stats by reading. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) outw(StatsDisable, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) EL3WINDOW(6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) for (i = 0; i < 9; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) inb(ioaddr + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) inw(ioaddr + 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) inw(ioaddr + 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /* Switch to register set 1 for normal use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) EL3WINDOW(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) /* Accept b-case and phys addr only. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /* Allow status bits to be seen. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /* Ack all pending events, and set active indicator mask. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /* Power Management support functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) el3_suspend(struct device *pdev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) struct el3_private *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) int ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) dev = dev_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) spin_lock_irqsave(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) netif_device_detach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) el3_down(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) outw(PowerDown, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) spin_unlock_irqrestore(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) el3_resume(struct device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct el3_private *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) int ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) dev = dev_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) ioaddr = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) spin_lock_irqsave(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) outw(PowerUp, ioaddr + EL3_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) EL3WINDOW(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) el3_up(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) netif_device_attach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) spin_unlock_irqrestore(&lp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) module_param(debug,int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) module_param_hw_array(irq, int, irq, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) module_param(max_interrupt_work, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) MODULE_PARM_DESC(debug, "debug level (0-6)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) module_param(nopnp, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) #endif /* CONFIG_PNP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B, 3c529, 3c579) ethernet driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static int __init el3_init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (debug >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) el3_debug = debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (!nopnp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) ret = pnp_register_driver(&el3_pnp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) pnp_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /* Select an open I/O location at 0x1*0 to do ISA contention select. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) /* Start with 0x110 to avoid some sound cards.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) for (id_port = 0x110 ; id_port < 0x200; id_port += 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (!request_region(id_port, 1, "3c509-control"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) outb(0x00, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) outb(0xff, id_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (inb(id_port) & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) release_region(id_port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (id_port >= 0x200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) id_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) pr_err("No I/O port available for 3c509 activation.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) isa_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) ret = eisa_driver_register(&el3_eisa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) eisa_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (pnp_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (isa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (eisa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static void __exit el3_cleanup_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (pnp_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) pnp_unregister_driver(&el3_pnp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (isa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) isa_unregister_driver(&el3_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (id_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) release_region(id_port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (eisa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) eisa_driver_unregister(&el3_eisa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) module_init (el3_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) module_exit (el3_cleanup_module);