1ae150435SJeff Kirsher /*======================================================================
2ae150435SJeff Kirsher
3ae150435SJeff Kirsher A PCMCIA ethernet driver for SMC91c92-based cards.
4ae150435SJeff Kirsher
5ae150435SJeff Kirsher This driver supports Megahertz PCMCIA ethernet cards; and
6ae150435SJeff Kirsher Megahertz, Motorola, Ositech, and Psion Dacom ethernet/modem
7ae150435SJeff Kirsher multifunction cards.
8ae150435SJeff Kirsher
9ae150435SJeff Kirsher Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
10ae150435SJeff Kirsher
11ae150435SJeff Kirsher smc91c92_cs.c 1.122 2002/10/25 06:26:39
12ae150435SJeff Kirsher
13ae150435SJeff Kirsher This driver contains code written by Donald Becker
14ae150435SJeff Kirsher (becker@scyld.com), Rowan Hughes (x-csrdh@jcu.edu.au),
15ae150435SJeff Kirsher David Hinds (dahinds@users.sourceforge.net), and Erik Stahlman
16ae150435SJeff Kirsher (erik@vt.edu). Donald wrote the SMC 91c92 code using parts of
17ae150435SJeff Kirsher Erik's SMC 91c94 driver. Rowan wrote a similar driver, and I've
18ae150435SJeff Kirsher incorporated some parts of his driver here. I (Dave) wrote most
19ae150435SJeff Kirsher of the PCMCIA glue code, and the Ositech support code. Kelly
20ae150435SJeff Kirsher Stephens (kstephen@holli.com) added support for the Motorola
21ae150435SJeff Kirsher Mariner, with help from Allen Brost.
22ae150435SJeff Kirsher
23ae150435SJeff Kirsher This software may be used and distributed according to the terms of
24ae150435SJeff Kirsher the GNU General Public License, incorporated herein by reference.
25ae150435SJeff Kirsher
26ae150435SJeff Kirsher ======================================================================*/
27ae150435SJeff Kirsher
28ae150435SJeff Kirsher #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29ae150435SJeff Kirsher
30ae150435SJeff Kirsher #include <linux/module.h>
31ae150435SJeff Kirsher #include <linux/kernel.h>
32ae150435SJeff Kirsher #include <linux/slab.h>
33ae150435SJeff Kirsher #include <linux/string.h>
34ae150435SJeff Kirsher #include <linux/timer.h>
35ae150435SJeff Kirsher #include <linux/interrupt.h>
36ae150435SJeff Kirsher #include <linux/delay.h>
37ae150435SJeff Kirsher #include <linux/crc32.h>
38ae150435SJeff Kirsher #include <linux/netdevice.h>
39ae150435SJeff Kirsher #include <linux/etherdevice.h>
40ae150435SJeff Kirsher #include <linux/skbuff.h>
41ae150435SJeff Kirsher #include <linux/if_arp.h>
42ae150435SJeff Kirsher #include <linux/ioport.h>
43ae150435SJeff Kirsher #include <linux/ethtool.h>
44ae150435SJeff Kirsher #include <linux/mii.h>
45ae150435SJeff Kirsher #include <linux/jiffies.h>
46ae150435SJeff Kirsher #include <linux/firmware.h>
47ae150435SJeff Kirsher
48ae150435SJeff Kirsher #include <pcmcia/cistpl.h>
49ae150435SJeff Kirsher #include <pcmcia/cisreg.h>
50ae150435SJeff Kirsher #include <pcmcia/ciscode.h>
51ae150435SJeff Kirsher #include <pcmcia/ds.h>
52ae150435SJeff Kirsher #include <pcmcia/ss.h>
53ae150435SJeff Kirsher
54ae150435SJeff Kirsher #include <asm/io.h>
557c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
56ae150435SJeff Kirsher
57ae150435SJeff Kirsher /*====================================================================*/
58ae150435SJeff Kirsher
59ae150435SJeff Kirsher static const char *if_names[] = { "auto", "10baseT", "10base2"};
60ae150435SJeff Kirsher
61ae150435SJeff Kirsher /* Firmware name */
62ae150435SJeff Kirsher #define FIRMWARE_NAME "ositech/Xilinx7OD.bin"
63ae150435SJeff Kirsher
64ae150435SJeff Kirsher /* Module parameters */
65ae150435SJeff Kirsher
66ae150435SJeff Kirsher MODULE_DESCRIPTION("SMC 91c92 series PCMCIA ethernet driver");
67ae150435SJeff Kirsher MODULE_LICENSE("GPL");
68ae150435SJeff Kirsher MODULE_FIRMWARE(FIRMWARE_NAME);
69ae150435SJeff Kirsher
70ae150435SJeff Kirsher #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
71ae150435SJeff Kirsher
72ae150435SJeff Kirsher /*
73ae150435SJeff Kirsher Transceiver/media type.
74ae150435SJeff Kirsher 0 = auto
75ae150435SJeff Kirsher 1 = 10baseT (and autoselect if #define AUTOSELECT),
76ae150435SJeff Kirsher 2 = AUI/10base2,
77ae150435SJeff Kirsher */
78ae150435SJeff Kirsher INT_MODULE_PARM(if_port, 0);
79ae150435SJeff Kirsher
80ae150435SJeff Kirsher
81ae150435SJeff Kirsher #define DRV_NAME "smc91c92_cs"
82ae150435SJeff Kirsher #define DRV_VERSION "1.123"
83ae150435SJeff Kirsher
84ae150435SJeff Kirsher /*====================================================================*/
85ae150435SJeff Kirsher
86ae150435SJeff Kirsher /* Operational parameter that usually are not changed. */
87ae150435SJeff Kirsher
88ae150435SJeff Kirsher /* Time in jiffies before concluding Tx hung */
89ae150435SJeff Kirsher #define TX_TIMEOUT ((400*HZ)/1000)
90ae150435SJeff Kirsher
91ae150435SJeff Kirsher /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
92ae150435SJeff Kirsher #define INTR_WORK 4
93ae150435SJeff Kirsher
94ae150435SJeff Kirsher /* Times to check the check the chip before concluding that it doesn't
95ae150435SJeff Kirsher currently have room for another Tx packet. */
96ae150435SJeff Kirsher #define MEMORY_WAIT_TIME 8
97ae150435SJeff Kirsher
98ae150435SJeff Kirsher struct smc_private {
99ae150435SJeff Kirsher struct pcmcia_device *p_dev;
100ae150435SJeff Kirsher spinlock_t lock;
101ae150435SJeff Kirsher u_short manfid;
102ae150435SJeff Kirsher u_short cardid;
103ae150435SJeff Kirsher
104ae150435SJeff Kirsher struct sk_buff *saved_skb;
105ae150435SJeff Kirsher int packets_waiting;
106ae150435SJeff Kirsher void __iomem *base;
107ae150435SJeff Kirsher u_short cfg;
108ae150435SJeff Kirsher struct timer_list media;
109ae150435SJeff Kirsher int watchdog, tx_err;
110ae150435SJeff Kirsher u_short media_status;
111ae150435SJeff Kirsher u_short fast_poll;
112ae150435SJeff Kirsher u_short link_status;
113ae150435SJeff Kirsher struct mii_if_info mii_if;
114ae150435SJeff Kirsher int duplex;
115ae150435SJeff Kirsher int rx_ovrn;
1164a7c9726STobias Klauser unsigned long last_rx;
117ae150435SJeff Kirsher };
118ae150435SJeff Kirsher
119ae150435SJeff Kirsher /* Special definitions for Megahertz multifunction cards */
120ae150435SJeff Kirsher #define MEGAHERTZ_ISR 0x0380
121ae150435SJeff Kirsher
122ae150435SJeff Kirsher /* Special function registers for Motorola Mariner */
123ae150435SJeff Kirsher #define MOT_LAN 0x0000
124ae150435SJeff Kirsher #define MOT_UART 0x0020
125ae150435SJeff Kirsher #define MOT_EEPROM 0x20
126ae150435SJeff Kirsher
127ae150435SJeff Kirsher #define MOT_NORMAL \
128ae150435SJeff Kirsher (COR_LEVEL_REQ | COR_FUNC_ENA | COR_ADDR_DECODE | COR_IREQ_ENA)
129ae150435SJeff Kirsher
130ae150435SJeff Kirsher /* Special function registers for Ositech cards */
131ae150435SJeff Kirsher #define OSITECH_AUI_CTL 0x0c
132ae150435SJeff Kirsher #define OSITECH_PWRDOWN 0x0d
133ae150435SJeff Kirsher #define OSITECH_RESET 0x0e
134ae150435SJeff Kirsher #define OSITECH_ISR 0x0f
135ae150435SJeff Kirsher #define OSITECH_AUI_PWR 0x0c
136ae150435SJeff Kirsher #define OSITECH_RESET_ISR 0x0e
137ae150435SJeff Kirsher
138ae150435SJeff Kirsher #define OSI_AUI_PWR 0x40
139ae150435SJeff Kirsher #define OSI_LAN_PWRDOWN 0x02
140ae150435SJeff Kirsher #define OSI_MODEM_PWRDOWN 0x01
141ae150435SJeff Kirsher #define OSI_LAN_RESET 0x02
142ae150435SJeff Kirsher #define OSI_MODEM_RESET 0x01
143ae150435SJeff Kirsher
144ae150435SJeff Kirsher /* Symbolic constants for the SMC91c9* series chips, from Erik Stahlman. */
145ae150435SJeff Kirsher #define BANK_SELECT 14 /* Window select register. */
146ae150435SJeff Kirsher #define SMC_SELECT_BANK(x) { outw(x, ioaddr + BANK_SELECT); }
147ae150435SJeff Kirsher
148ae150435SJeff Kirsher /* Bank 0 registers. */
149ae150435SJeff Kirsher #define TCR 0 /* transmit control register */
150ae150435SJeff Kirsher #define TCR_CLEAR 0 /* do NOTHING */
151ae150435SJeff Kirsher #define TCR_ENABLE 0x0001 /* if this is 1, we can transmit */
152ae150435SJeff Kirsher #define TCR_PAD_EN 0x0080 /* pads short packets to 64 bytes */
153ae150435SJeff Kirsher #define TCR_MONCSN 0x0400 /* Monitor Carrier. */
154ae150435SJeff Kirsher #define TCR_FDUPLX 0x0800 /* Full duplex mode. */
155ae150435SJeff Kirsher #define TCR_NORMAL TCR_ENABLE | TCR_PAD_EN
156ae150435SJeff Kirsher
157ae150435SJeff Kirsher #define EPH 2 /* Ethernet Protocol Handler report. */
158ae150435SJeff Kirsher #define EPH_TX_SUC 0x0001
159ae150435SJeff Kirsher #define EPH_SNGLCOL 0x0002
160ae150435SJeff Kirsher #define EPH_MULCOL 0x0004
161ae150435SJeff Kirsher #define EPH_LTX_MULT 0x0008
162ae150435SJeff Kirsher #define EPH_16COL 0x0010
163ae150435SJeff Kirsher #define EPH_SQET 0x0020
164ae150435SJeff Kirsher #define EPH_LTX_BRD 0x0040
165ae150435SJeff Kirsher #define EPH_TX_DEFR 0x0080
166ae150435SJeff Kirsher #define EPH_LAT_COL 0x0200
167ae150435SJeff Kirsher #define EPH_LOST_CAR 0x0400
168ae150435SJeff Kirsher #define EPH_EXC_DEF 0x0800
169ae150435SJeff Kirsher #define EPH_CTR_ROL 0x1000
170ae150435SJeff Kirsher #define EPH_RX_OVRN 0x2000
171ae150435SJeff Kirsher #define EPH_LINK_OK 0x4000
172ae150435SJeff Kirsher #define EPH_TX_UNRN 0x8000
173ae150435SJeff Kirsher #define MEMINFO 8 /* Memory Information Register */
174ae150435SJeff Kirsher #define MEMCFG 10 /* Memory Configuration Register */
175ae150435SJeff Kirsher
176ae150435SJeff Kirsher /* Bank 1 registers. */
177ae150435SJeff Kirsher #define CONFIG 0
178ae150435SJeff Kirsher #define CFG_MII_SELECT 0x8000 /* 91C100 only */
179ae150435SJeff Kirsher #define CFG_NO_WAIT 0x1000
180ae150435SJeff Kirsher #define CFG_FULL_STEP 0x0400
181ae150435SJeff Kirsher #define CFG_SET_SQLCH 0x0200
182ae150435SJeff Kirsher #define CFG_AUI_SELECT 0x0100
183ae150435SJeff Kirsher #define CFG_16BIT 0x0080
184ae150435SJeff Kirsher #define CFG_DIS_LINK 0x0040
185ae150435SJeff Kirsher #define CFG_STATIC 0x0030
186ae150435SJeff Kirsher #define CFG_IRQ_SEL_1 0x0004
187ae150435SJeff Kirsher #define CFG_IRQ_SEL_0 0x0002
188ae150435SJeff Kirsher #define BASE_ADDR 2
189ae150435SJeff Kirsher #define ADDR0 4
190ae150435SJeff Kirsher #define GENERAL 10
191ae150435SJeff Kirsher #define CONTROL 12
192ae150435SJeff Kirsher #define CTL_STORE 0x0001
193ae150435SJeff Kirsher #define CTL_RELOAD 0x0002
194ae150435SJeff Kirsher #define CTL_EE_SELECT 0x0004
195ae150435SJeff Kirsher #define CTL_TE_ENABLE 0x0020
196ae150435SJeff Kirsher #define CTL_CR_ENABLE 0x0040
197ae150435SJeff Kirsher #define CTL_LE_ENABLE 0x0080
198ae150435SJeff Kirsher #define CTL_AUTO_RELEASE 0x0800
199ae150435SJeff Kirsher #define CTL_POWERDOWN 0x2000
200ae150435SJeff Kirsher
201ae150435SJeff Kirsher /* Bank 2 registers. */
202ae150435SJeff Kirsher #define MMU_CMD 0
203ae150435SJeff Kirsher #define MC_ALLOC 0x20 /* or with number of 256 byte packets */
204ae150435SJeff Kirsher #define MC_RESET 0x40
205ae150435SJeff Kirsher #define MC_RELEASE 0x80 /* remove and release the current rx packet */
206ae150435SJeff Kirsher #define MC_FREEPKT 0xA0 /* Release packet in PNR register */
207ae150435SJeff Kirsher #define MC_ENQUEUE 0xC0 /* Enqueue the packet for transmit */
208ae150435SJeff Kirsher #define PNR_ARR 2
209ae150435SJeff Kirsher #define FIFO_PORTS 4
210ae150435SJeff Kirsher #define FP_RXEMPTY 0x8000
211ae150435SJeff Kirsher #define POINTER 6
212ae150435SJeff Kirsher #define PTR_AUTO_INC 0x0040
213ae150435SJeff Kirsher #define PTR_READ 0x2000
214ae150435SJeff Kirsher #define PTR_AUTOINC 0x4000
215ae150435SJeff Kirsher #define PTR_RCV 0x8000
216ae150435SJeff Kirsher #define DATA_1 8
217ae150435SJeff Kirsher #define INTERRUPT 12
218ae150435SJeff Kirsher #define IM_RCV_INT 0x1
219ae150435SJeff Kirsher #define IM_TX_INT 0x2
220ae150435SJeff Kirsher #define IM_TX_EMPTY_INT 0x4
221ae150435SJeff Kirsher #define IM_ALLOC_INT 0x8
222ae150435SJeff Kirsher #define IM_RX_OVRN_INT 0x10
223ae150435SJeff Kirsher #define IM_EPH_INT 0x20
224ae150435SJeff Kirsher
225ae150435SJeff Kirsher #define RCR 4
226ae150435SJeff Kirsher enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
227ae150435SJeff Kirsher RxEnable = 0x0100, RxStripCRC = 0x0200};
228ae150435SJeff Kirsher #define RCR_SOFTRESET 0x8000 /* resets the chip */
229ae150435SJeff Kirsher #define RCR_STRIP_CRC 0x200 /* strips CRC */
230ae150435SJeff Kirsher #define RCR_ENABLE 0x100 /* IFF this is set, we can receive packets */
231ae150435SJeff Kirsher #define RCR_ALMUL 0x4 /* receive all multicast packets */
232ae150435SJeff Kirsher #define RCR_PROMISC 0x2 /* enable promiscuous mode */
233ae150435SJeff Kirsher
234ae150435SJeff Kirsher /* the normal settings for the RCR register : */
235ae150435SJeff Kirsher #define RCR_NORMAL (RCR_STRIP_CRC | RCR_ENABLE)
236ae150435SJeff Kirsher #define RCR_CLEAR 0x0 /* set it to a base state */
237ae150435SJeff Kirsher #define COUNTER 6
238ae150435SJeff Kirsher
239ae150435SJeff Kirsher /* BANK 3 -- not the same values as in smc9194! */
240ae150435SJeff Kirsher #define MULTICAST0 0
241ae150435SJeff Kirsher #define MULTICAST2 2
242ae150435SJeff Kirsher #define MULTICAST4 4
243ae150435SJeff Kirsher #define MULTICAST6 6
244ae150435SJeff Kirsher #define MGMT 8
245ae150435SJeff Kirsher #define REVISION 0x0a
246ae150435SJeff Kirsher
247ae150435SJeff Kirsher /* Transmit status bits. */
248ae150435SJeff Kirsher #define TS_SUCCESS 0x0001
249ae150435SJeff Kirsher #define TS_16COL 0x0010
250ae150435SJeff Kirsher #define TS_LATCOL 0x0200
251ae150435SJeff Kirsher #define TS_LOSTCAR 0x0400
252ae150435SJeff Kirsher
253ae150435SJeff Kirsher /* Receive status bits. */
254ae150435SJeff Kirsher #define RS_ALGNERR 0x8000
255ae150435SJeff Kirsher #define RS_BADCRC 0x2000
256ae150435SJeff Kirsher #define RS_ODDFRAME 0x1000
257ae150435SJeff Kirsher #define RS_TOOLONG 0x0800
258ae150435SJeff Kirsher #define RS_TOOSHORT 0x0400
259ae150435SJeff Kirsher #define RS_MULTICAST 0x0001
260ae150435SJeff Kirsher #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
261ae150435SJeff Kirsher
262ae150435SJeff Kirsher #define set_bits(v, p) outw(inw(p)|(v), (p))
263ae150435SJeff Kirsher #define mask_bits(v, p) outw(inw(p)&(v), (p))
264ae150435SJeff Kirsher
265ae150435SJeff Kirsher /*====================================================================*/
266ae150435SJeff Kirsher
267ae150435SJeff Kirsher static void smc91c92_detach(struct pcmcia_device *p_dev);
268ae150435SJeff Kirsher static int smc91c92_config(struct pcmcia_device *link);
269ae150435SJeff Kirsher static void smc91c92_release(struct pcmcia_device *link);
270ae150435SJeff Kirsher
271ae150435SJeff Kirsher static int smc_open(struct net_device *dev);
272ae150435SJeff Kirsher static int smc_close(struct net_device *dev);
273ae150435SJeff Kirsher static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
2740290bd29SMichael S. Tsirkin static void smc_tx_timeout(struct net_device *dev, unsigned int txqueue);
275ae150435SJeff Kirsher static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
276ae150435SJeff Kirsher struct net_device *dev);
277ae150435SJeff Kirsher static irqreturn_t smc_interrupt(int irq, void *dev_id);
278ae150435SJeff Kirsher static void smc_rx(struct net_device *dev);
279ae150435SJeff Kirsher static void set_rx_mode(struct net_device *dev);
280ae150435SJeff Kirsher static int s9k_config(struct net_device *dev, struct ifmap *map);
281ae150435SJeff Kirsher static void smc_set_xcvr(struct net_device *dev, int if_port);
282ae150435SJeff Kirsher static void smc_reset(struct net_device *dev);
283267146d4SKees Cook static void media_check(struct timer_list *t);
284ae150435SJeff Kirsher static void mdio_sync(unsigned int addr);
285ae150435SJeff Kirsher static int mdio_read(struct net_device *dev, int phy_id, int loc);
286ae150435SJeff Kirsher static void mdio_write(struct net_device *dev, int phy_id, int loc, int value);
287ae150435SJeff Kirsher static int smc_link_ok(struct net_device *dev);
288ae150435SJeff Kirsher static const struct ethtool_ops ethtool_ops;
289ae150435SJeff Kirsher
290ae150435SJeff Kirsher static const struct net_device_ops smc_netdev_ops = {
291ae150435SJeff Kirsher .ndo_open = smc_open,
292ae150435SJeff Kirsher .ndo_stop = smc_close,
293ae150435SJeff Kirsher .ndo_start_xmit = smc_start_xmit,
294ae150435SJeff Kirsher .ndo_tx_timeout = smc_tx_timeout,
295ae150435SJeff Kirsher .ndo_set_config = s9k_config,
296afc4b13dSJiri Pirko .ndo_set_rx_mode = set_rx_mode,
297a7605370SArnd Bergmann .ndo_eth_ioctl = smc_ioctl,
298ae150435SJeff Kirsher .ndo_set_mac_address = eth_mac_addr,
299ae150435SJeff Kirsher .ndo_validate_addr = eth_validate_addr,
300ae150435SJeff Kirsher };
301ae150435SJeff Kirsher
smc91c92_probe(struct pcmcia_device * link)302ae150435SJeff Kirsher static int smc91c92_probe(struct pcmcia_device *link)
303ae150435SJeff Kirsher {
304ae150435SJeff Kirsher struct smc_private *smc;
305ae150435SJeff Kirsher struct net_device *dev;
306ae150435SJeff Kirsher
307ae150435SJeff Kirsher dev_dbg(&link->dev, "smc91c92_attach()\n");
308ae150435SJeff Kirsher
309ae150435SJeff Kirsher /* Create new ethernet device */
310ae150435SJeff Kirsher dev = alloc_etherdev(sizeof(struct smc_private));
311ae150435SJeff Kirsher if (!dev)
312ae150435SJeff Kirsher return -ENOMEM;
313ae150435SJeff Kirsher smc = netdev_priv(dev);
314ae150435SJeff Kirsher smc->p_dev = link;
315ae150435SJeff Kirsher link->priv = dev;
316ae150435SJeff Kirsher
317ae150435SJeff Kirsher spin_lock_init(&smc->lock);
318ae150435SJeff Kirsher
319ae150435SJeff Kirsher /* The SMC91c92-specific entries in the device structure. */
320ae150435SJeff Kirsher dev->netdev_ops = &smc_netdev_ops;
3217ad24ea4SWilfried Klaebe dev->ethtool_ops = ðtool_ops;
322ae150435SJeff Kirsher dev->watchdog_timeo = TX_TIMEOUT;
323ae150435SJeff Kirsher
324ae150435SJeff Kirsher smc->mii_if.dev = dev;
325ae150435SJeff Kirsher smc->mii_if.mdio_read = mdio_read;
326ae150435SJeff Kirsher smc->mii_if.mdio_write = mdio_write;
327ae150435SJeff Kirsher smc->mii_if.phy_id_mask = 0x1f;
328ae150435SJeff Kirsher smc->mii_if.reg_num_mask = 0x1f;
329ae150435SJeff Kirsher
330ae150435SJeff Kirsher return smc91c92_config(link);
331ae150435SJeff Kirsher } /* smc91c92_attach */
332ae150435SJeff Kirsher
smc91c92_detach(struct pcmcia_device * link)333ae150435SJeff Kirsher static void smc91c92_detach(struct pcmcia_device *link)
334ae150435SJeff Kirsher {
335ae150435SJeff Kirsher struct net_device *dev = link->priv;
336ae150435SJeff Kirsher
337ae150435SJeff Kirsher dev_dbg(&link->dev, "smc91c92_detach\n");
338ae150435SJeff Kirsher
339ae150435SJeff Kirsher unregister_netdev(dev);
340ae150435SJeff Kirsher
341ae150435SJeff Kirsher smc91c92_release(link);
342ae150435SJeff Kirsher
343ae150435SJeff Kirsher free_netdev(dev);
344ae150435SJeff Kirsher } /* smc91c92_detach */
345ae150435SJeff Kirsher
346ae150435SJeff Kirsher /*====================================================================*/
347ae150435SJeff Kirsher
cvt_ascii_address(struct net_device * dev,char * s)348ae150435SJeff Kirsher static int cvt_ascii_address(struct net_device *dev, char *s)
349ae150435SJeff Kirsher {
3504abd7cffSJakub Kicinski u8 mac[ETH_ALEN];
351ae150435SJeff Kirsher int i, j, da, c;
352ae150435SJeff Kirsher
353ae150435SJeff Kirsher if (strlen(s) != 12)
354ae150435SJeff Kirsher return -1;
355ae150435SJeff Kirsher for (i = 0; i < 6; i++) {
356ae150435SJeff Kirsher da = 0;
357ae150435SJeff Kirsher for (j = 0; j < 2; j++) {
358ae150435SJeff Kirsher c = *s++;
359ae150435SJeff Kirsher da <<= 4;
360ae150435SJeff Kirsher da += ((c >= '0') && (c <= '9')) ?
361ae150435SJeff Kirsher (c - '0') : ((c & 0x0f) + 9);
362ae150435SJeff Kirsher }
3634abd7cffSJakub Kicinski mac[i] = da;
364ae150435SJeff Kirsher }
3654abd7cffSJakub Kicinski eth_hw_addr_set(dev, mac);
366ae150435SJeff Kirsher return 0;
367ae150435SJeff Kirsher }
368ae150435SJeff Kirsher
369ae150435SJeff Kirsher /*====================================================================
370ae150435SJeff Kirsher
371ae150435SJeff Kirsher Configuration stuff for Megahertz cards
372ae150435SJeff Kirsher
373ae150435SJeff Kirsher mhz_3288_power() is used to power up a 3288's ethernet chip.
374ae150435SJeff Kirsher mhz_mfc_config() handles socket setup for multifunction (1144
375ae150435SJeff Kirsher and 3288) cards. mhz_setup() gets a card's hardware ethernet
376ae150435SJeff Kirsher address.
377ae150435SJeff Kirsher
378ae150435SJeff Kirsher ======================================================================*/
379ae150435SJeff Kirsher
mhz_3288_power(struct pcmcia_device * link)380ae150435SJeff Kirsher static int mhz_3288_power(struct pcmcia_device *link)
381ae150435SJeff Kirsher {
382ae150435SJeff Kirsher struct net_device *dev = link->priv;
383ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
384ae150435SJeff Kirsher u_char tmp;
385ae150435SJeff Kirsher
386ae150435SJeff Kirsher /* Read the ISR twice... */
387ae150435SJeff Kirsher readb(smc->base+MEGAHERTZ_ISR);
388ae150435SJeff Kirsher udelay(5);
389ae150435SJeff Kirsher readb(smc->base+MEGAHERTZ_ISR);
390ae150435SJeff Kirsher
391ae150435SJeff Kirsher /* Pause 200ms... */
392ae150435SJeff Kirsher mdelay(200);
393ae150435SJeff Kirsher
394ae150435SJeff Kirsher /* Now read and write the COR... */
395ae150435SJeff Kirsher tmp = readb(smc->base + link->config_base + CISREG_COR);
396ae150435SJeff Kirsher udelay(5);
397ae150435SJeff Kirsher writeb(tmp, smc->base + link->config_base + CISREG_COR);
398ae150435SJeff Kirsher
399ae150435SJeff Kirsher return 0;
400ae150435SJeff Kirsher }
401ae150435SJeff Kirsher
mhz_mfc_config_check(struct pcmcia_device * p_dev,void * priv_data)402ae150435SJeff Kirsher static int mhz_mfc_config_check(struct pcmcia_device *p_dev, void *priv_data)
403ae150435SJeff Kirsher {
404ae150435SJeff Kirsher int k;
405ae150435SJeff Kirsher p_dev->io_lines = 16;
406ae150435SJeff Kirsher p_dev->resource[1]->start = p_dev->resource[0]->start;
407ae150435SJeff Kirsher p_dev->resource[1]->end = 8;
408ae150435SJeff Kirsher p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
409ae150435SJeff Kirsher p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
410ae150435SJeff Kirsher p_dev->resource[0]->end = 16;
411ae150435SJeff Kirsher p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
412ae150435SJeff Kirsher p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
413ae150435SJeff Kirsher for (k = 0; k < 0x400; k += 0x10) {
414ae150435SJeff Kirsher if (k & 0x80)
415ae150435SJeff Kirsher continue;
416ae150435SJeff Kirsher p_dev->resource[0]->start = k ^ 0x300;
417ae150435SJeff Kirsher if (!pcmcia_request_io(p_dev))
418ae150435SJeff Kirsher return 0;
419ae150435SJeff Kirsher }
420ae150435SJeff Kirsher return -ENODEV;
421ae150435SJeff Kirsher }
422ae150435SJeff Kirsher
mhz_mfc_config(struct pcmcia_device * link)423ae150435SJeff Kirsher static int mhz_mfc_config(struct pcmcia_device *link)
424ae150435SJeff Kirsher {
425ae150435SJeff Kirsher struct net_device *dev = link->priv;
426ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
427ae150435SJeff Kirsher unsigned int offset;
428ae150435SJeff Kirsher int i;
429ae150435SJeff Kirsher
430ae150435SJeff Kirsher link->config_flags |= CONF_ENABLE_SPKR | CONF_ENABLE_IRQ |
431ae150435SJeff Kirsher CONF_AUTO_SET_IO;
432ae150435SJeff Kirsher
433ae150435SJeff Kirsher /* The Megahertz combo cards have modem-like CIS entries, so
434ae150435SJeff Kirsher we have to explicitly try a bunch of port combinations. */
435ae150435SJeff Kirsher if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
436ae150435SJeff Kirsher return -ENODEV;
437ae150435SJeff Kirsher
438ae150435SJeff Kirsher dev->base_addr = link->resource[0]->start;
439ae150435SJeff Kirsher
440ae150435SJeff Kirsher /* Allocate a memory window, for accessing the ISR */
441ae150435SJeff Kirsher link->resource[2]->flags = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
442ae150435SJeff Kirsher link->resource[2]->start = link->resource[2]->end = 0;
443ae150435SJeff Kirsher i = pcmcia_request_window(link, link->resource[2], 0);
444ae150435SJeff Kirsher if (i != 0)
445ae150435SJeff Kirsher return -ENODEV;
446ae150435SJeff Kirsher
447ae150435SJeff Kirsher smc->base = ioremap(link->resource[2]->start,
448ae150435SJeff Kirsher resource_size(link->resource[2]));
449ae150435SJeff Kirsher offset = (smc->manfid == MANFID_MOTOROLA) ? link->config_base : 0;
450ae150435SJeff Kirsher i = pcmcia_map_mem_page(link, link->resource[2], offset);
451ae150435SJeff Kirsher if ((i == 0) &&
452ae150435SJeff Kirsher (smc->manfid == MANFID_MEGAHERTZ) &&
453ae150435SJeff Kirsher (smc->cardid == PRODID_MEGAHERTZ_EM3288))
454ae150435SJeff Kirsher mhz_3288_power(link);
455ae150435SJeff Kirsher
456ae150435SJeff Kirsher return 0;
457ae150435SJeff Kirsher }
458ae150435SJeff Kirsher
pcmcia_get_versmac(struct pcmcia_device * p_dev,tuple_t * tuple,void * priv)459ae150435SJeff Kirsher static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
460ae150435SJeff Kirsher tuple_t *tuple,
461ae150435SJeff Kirsher void *priv)
462ae150435SJeff Kirsher {
463ae150435SJeff Kirsher struct net_device *dev = priv;
464ae150435SJeff Kirsher cisparse_t parse;
465ae150435SJeff Kirsher u8 *buf;
466ae150435SJeff Kirsher
467ae150435SJeff Kirsher if (pcmcia_parse_tuple(tuple, &parse))
468ae150435SJeff Kirsher return -EINVAL;
469ae150435SJeff Kirsher
470ae150435SJeff Kirsher buf = parse.version_1.str + parse.version_1.ofs[3];
471ae150435SJeff Kirsher
472ae150435SJeff Kirsher if ((parse.version_1.ns > 3) && (cvt_ascii_address(dev, buf) == 0))
473ae150435SJeff Kirsher return 0;
474ae150435SJeff Kirsher
475ae150435SJeff Kirsher return -EINVAL;
476ae150435SJeff Kirsher };
477ae150435SJeff Kirsher
mhz_setup(struct pcmcia_device * link)478ae150435SJeff Kirsher static int mhz_setup(struct pcmcia_device *link)
479ae150435SJeff Kirsher {
480ae150435SJeff Kirsher struct net_device *dev = link->priv;
481ae150435SJeff Kirsher size_t len;
482ae150435SJeff Kirsher u8 *buf;
483ae150435SJeff Kirsher int rc;
484ae150435SJeff Kirsher
485ae150435SJeff Kirsher /* Read the station address from the CIS. It is stored as the last
486ae150435SJeff Kirsher (fourth) string in the Version 1 Version/ID tuple. */
487ae150435SJeff Kirsher if ((link->prod_id[3]) &&
488ae150435SJeff Kirsher (cvt_ascii_address(dev, link->prod_id[3]) == 0))
489ae150435SJeff Kirsher return 0;
490ae150435SJeff Kirsher
491ae150435SJeff Kirsher /* Workarounds for broken cards start here. */
492ae150435SJeff Kirsher /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
493ae150435SJeff Kirsher if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
494ae150435SJeff Kirsher return 0;
495ae150435SJeff Kirsher
496ae150435SJeff Kirsher /* Another possibility: for the EM3288, in a special tuple */
497ae150435SJeff Kirsher rc = -1;
498ae150435SJeff Kirsher len = pcmcia_get_tuple(link, 0x81, &buf);
499ae150435SJeff Kirsher if (buf && len >= 13) {
500ae150435SJeff Kirsher buf[12] = '\0';
501ae150435SJeff Kirsher if (cvt_ascii_address(dev, buf) == 0)
502ae150435SJeff Kirsher rc = 0;
503ae150435SJeff Kirsher }
504ae150435SJeff Kirsher kfree(buf);
505ae150435SJeff Kirsher
506ae150435SJeff Kirsher return rc;
507ae150435SJeff Kirsher };
508ae150435SJeff Kirsher
509ae150435SJeff Kirsher /*======================================================================
510ae150435SJeff Kirsher
511ae150435SJeff Kirsher Configuration stuff for the Motorola Mariner
512ae150435SJeff Kirsher
513ae150435SJeff Kirsher mot_config() writes directly to the Mariner configuration
514ae150435SJeff Kirsher registers because the CIS is just bogus.
515ae150435SJeff Kirsher
516ae150435SJeff Kirsher ======================================================================*/
517ae150435SJeff Kirsher
mot_config(struct pcmcia_device * link)518ae150435SJeff Kirsher static void mot_config(struct pcmcia_device *link)
519ae150435SJeff Kirsher {
520ae150435SJeff Kirsher struct net_device *dev = link->priv;
521ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
522ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
523ae150435SJeff Kirsher unsigned int iouart = link->resource[1]->start;
524ae150435SJeff Kirsher
525ae150435SJeff Kirsher /* Set UART base address and force map with COR bit 1 */
526ae150435SJeff Kirsher writeb(iouart & 0xff, smc->base + MOT_UART + CISREG_IOBASE_0);
527ae150435SJeff Kirsher writeb((iouart >> 8) & 0xff, smc->base + MOT_UART + CISREG_IOBASE_1);
528ae150435SJeff Kirsher writeb(MOT_NORMAL, smc->base + MOT_UART + CISREG_COR);
529ae150435SJeff Kirsher
530ae150435SJeff Kirsher /* Set SMC base address and force map with COR bit 1 */
531ae150435SJeff Kirsher writeb(ioaddr & 0xff, smc->base + MOT_LAN + CISREG_IOBASE_0);
532ae150435SJeff Kirsher writeb((ioaddr >> 8) & 0xff, smc->base + MOT_LAN + CISREG_IOBASE_1);
533ae150435SJeff Kirsher writeb(MOT_NORMAL, smc->base + MOT_LAN + CISREG_COR);
534ae150435SJeff Kirsher
535ae150435SJeff Kirsher /* Wait for things to settle down */
536ae150435SJeff Kirsher mdelay(100);
537ae150435SJeff Kirsher }
538ae150435SJeff Kirsher
mot_setup(struct pcmcia_device * link)539ae150435SJeff Kirsher static int mot_setup(struct pcmcia_device *link)
540ae150435SJeff Kirsher {
541ae150435SJeff Kirsher struct net_device *dev = link->priv;
542ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
543ae150435SJeff Kirsher int i, wait, loop;
5444abd7cffSJakub Kicinski u8 mac[ETH_ALEN];
545ae150435SJeff Kirsher u_int addr;
546ae150435SJeff Kirsher
547ae150435SJeff Kirsher /* Read Ethernet address from Serial EEPROM */
548ae150435SJeff Kirsher
549ae150435SJeff Kirsher for (i = 0; i < 3; i++) {
550ae150435SJeff Kirsher SMC_SELECT_BANK(2);
551ae150435SJeff Kirsher outw(MOT_EEPROM + i, ioaddr + POINTER);
552ae150435SJeff Kirsher SMC_SELECT_BANK(1);
553ae150435SJeff Kirsher outw((CTL_RELOAD | CTL_EE_SELECT), ioaddr + CONTROL);
554ae150435SJeff Kirsher
555ae150435SJeff Kirsher for (loop = wait = 0; loop < 200; loop++) {
556ae150435SJeff Kirsher udelay(10);
557ae150435SJeff Kirsher wait = ((CTL_RELOAD | CTL_STORE) & inw(ioaddr + CONTROL));
558ae150435SJeff Kirsher if (wait == 0) break;
559ae150435SJeff Kirsher }
560ae150435SJeff Kirsher
561ae150435SJeff Kirsher if (wait)
562ae150435SJeff Kirsher return -1;
563ae150435SJeff Kirsher
564ae150435SJeff Kirsher addr = inw(ioaddr + GENERAL);
5654abd7cffSJakub Kicinski mac[2*i] = addr & 0xff;
5664abd7cffSJakub Kicinski mac[2*i+1] = (addr >> 8) & 0xff;
567ae150435SJeff Kirsher }
5684abd7cffSJakub Kicinski eth_hw_addr_set(dev, mac);
569ae150435SJeff Kirsher
570ae150435SJeff Kirsher return 0;
571ae150435SJeff Kirsher }
572ae150435SJeff Kirsher
573ae150435SJeff Kirsher /*====================================================================*/
574ae150435SJeff Kirsher
smc_configcheck(struct pcmcia_device * p_dev,void * priv_data)575ae150435SJeff Kirsher static int smc_configcheck(struct pcmcia_device *p_dev, void *priv_data)
576ae150435SJeff Kirsher {
577ae150435SJeff Kirsher p_dev->resource[0]->end = 16;
578ae150435SJeff Kirsher p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
579ae150435SJeff Kirsher p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
580ae150435SJeff Kirsher
581ae150435SJeff Kirsher return pcmcia_request_io(p_dev);
582ae150435SJeff Kirsher }
583ae150435SJeff Kirsher
smc_config(struct pcmcia_device * link)584ae150435SJeff Kirsher static int smc_config(struct pcmcia_device *link)
585ae150435SJeff Kirsher {
586ae150435SJeff Kirsher struct net_device *dev = link->priv;
587ae150435SJeff Kirsher int i;
588ae150435SJeff Kirsher
589ae150435SJeff Kirsher link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
590ae150435SJeff Kirsher
591ae150435SJeff Kirsher i = pcmcia_loop_config(link, smc_configcheck, NULL);
592ae150435SJeff Kirsher if (!i)
593ae150435SJeff Kirsher dev->base_addr = link->resource[0]->start;
594ae150435SJeff Kirsher
595ae150435SJeff Kirsher return i;
596ae150435SJeff Kirsher }
597ae150435SJeff Kirsher
598ae150435SJeff Kirsher
smc_setup(struct pcmcia_device * link)599ae150435SJeff Kirsher static int smc_setup(struct pcmcia_device *link)
600ae150435SJeff Kirsher {
601ae150435SJeff Kirsher struct net_device *dev = link->priv;
602ae150435SJeff Kirsher
603ae150435SJeff Kirsher /* Check for a LAN function extension tuple */
604ae150435SJeff Kirsher if (!pcmcia_get_mac_from_cis(link, dev))
605ae150435SJeff Kirsher return 0;
606ae150435SJeff Kirsher
607ae150435SJeff Kirsher /* Try the third string in the Version 1 Version/ID tuple. */
608ae150435SJeff Kirsher if (link->prod_id[2]) {
609ae150435SJeff Kirsher if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
610ae150435SJeff Kirsher return 0;
611ae150435SJeff Kirsher }
612ae150435SJeff Kirsher return -1;
613ae150435SJeff Kirsher }
614ae150435SJeff Kirsher
615ae150435SJeff Kirsher /*====================================================================*/
616ae150435SJeff Kirsher
osi_config(struct pcmcia_device * link)617ae150435SJeff Kirsher static int osi_config(struct pcmcia_device *link)
618ae150435SJeff Kirsher {
619ae150435SJeff Kirsher struct net_device *dev = link->priv;
620ae150435SJeff Kirsher static const unsigned int com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
621ae150435SJeff Kirsher int i, j;
622ae150435SJeff Kirsher
623ae150435SJeff Kirsher link->config_flags |= CONF_ENABLE_SPKR | CONF_ENABLE_IRQ;
624ae150435SJeff Kirsher link->resource[0]->end = 64;
625ae150435SJeff Kirsher link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
626ae150435SJeff Kirsher link->resource[1]->end = 8;
627ae150435SJeff Kirsher
628ae150435SJeff Kirsher /* Enable Hard Decode, LAN, Modem */
629ae150435SJeff Kirsher link->io_lines = 16;
630ae150435SJeff Kirsher link->config_index = 0x23;
631ae150435SJeff Kirsher
632ae150435SJeff Kirsher for (i = j = 0; j < 4; j++) {
633ae150435SJeff Kirsher link->resource[1]->start = com[j];
634ae150435SJeff Kirsher i = pcmcia_request_io(link);
635ae150435SJeff Kirsher if (i == 0)
636ae150435SJeff Kirsher break;
637ae150435SJeff Kirsher }
638ae150435SJeff Kirsher if (i != 0) {
639ae150435SJeff Kirsher /* Fallback: turn off hard decode */
640ae150435SJeff Kirsher link->config_index = 0x03;
641ae150435SJeff Kirsher link->resource[1]->end = 0;
642ae150435SJeff Kirsher i = pcmcia_request_io(link);
643ae150435SJeff Kirsher }
644ae150435SJeff Kirsher dev->base_addr = link->resource[0]->start + 0x10;
645ae150435SJeff Kirsher return i;
646ae150435SJeff Kirsher }
647ae150435SJeff Kirsher
osi_load_firmware(struct pcmcia_device * link)648ae150435SJeff Kirsher static int osi_load_firmware(struct pcmcia_device *link)
649ae150435SJeff Kirsher {
650ae150435SJeff Kirsher const struct firmware *fw;
651ae150435SJeff Kirsher int i, err;
652ae150435SJeff Kirsher
653ae150435SJeff Kirsher err = request_firmware(&fw, FIRMWARE_NAME, &link->dev);
654ae150435SJeff Kirsher if (err) {
655ae150435SJeff Kirsher pr_err("Failed to load firmware \"%s\"\n", FIRMWARE_NAME);
656ae150435SJeff Kirsher return err;
657ae150435SJeff Kirsher }
658ae150435SJeff Kirsher
659ae150435SJeff Kirsher /* Download the Seven of Diamonds firmware */
660ae150435SJeff Kirsher for (i = 0; i < fw->size; i++) {
661ae150435SJeff Kirsher outb(fw->data[i], link->resource[0]->start + 2);
662ae150435SJeff Kirsher udelay(50);
663ae150435SJeff Kirsher }
664ae150435SJeff Kirsher release_firmware(fw);
665ae150435SJeff Kirsher return err;
666ae150435SJeff Kirsher }
667ae150435SJeff Kirsher
pcmcia_osi_mac(struct pcmcia_device * p_dev,tuple_t * tuple,void * priv)668ae150435SJeff Kirsher static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
669ae150435SJeff Kirsher tuple_t *tuple,
670ae150435SJeff Kirsher void *priv)
671ae150435SJeff Kirsher {
672ae150435SJeff Kirsher struct net_device *dev = priv;
673ae150435SJeff Kirsher
674ae150435SJeff Kirsher if (tuple->TupleDataLen < 8)
675ae150435SJeff Kirsher return -EINVAL;
676ae150435SJeff Kirsher if (tuple->TupleData[0] != 0x04)
677ae150435SJeff Kirsher return -EINVAL;
678562ef98aSJakub Kicinski
679562ef98aSJakub Kicinski eth_hw_addr_set(dev, &tuple->TupleData[2]);
680ae150435SJeff Kirsher return 0;
681ae150435SJeff Kirsher };
682ae150435SJeff Kirsher
683ae150435SJeff Kirsher
osi_setup(struct pcmcia_device * link,u_short manfid,u_short cardid)684ae150435SJeff Kirsher static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
685ae150435SJeff Kirsher {
686ae150435SJeff Kirsher struct net_device *dev = link->priv;
687ae150435SJeff Kirsher int rc;
688ae150435SJeff Kirsher
689ae150435SJeff Kirsher /* Read the station address from tuple 0x90, subtuple 0x04 */
690ae150435SJeff Kirsher if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
691ae150435SJeff Kirsher return -1;
692ae150435SJeff Kirsher
693ae150435SJeff Kirsher if (((manfid == MANFID_OSITECH) &&
694ae150435SJeff Kirsher (cardid == PRODID_OSITECH_SEVEN)) ||
695ae150435SJeff Kirsher ((manfid == MANFID_PSION) &&
696ae150435SJeff Kirsher (cardid == PRODID_PSION_NET100))) {
697ae150435SJeff Kirsher rc = osi_load_firmware(link);
698ae150435SJeff Kirsher if (rc)
699ae150435SJeff Kirsher return rc;
700ae150435SJeff Kirsher } else if (manfid == MANFID_OSITECH) {
701ae150435SJeff Kirsher /* Make sure both functions are powered up */
702ae150435SJeff Kirsher set_bits(0x300, link->resource[0]->start + OSITECH_AUI_PWR);
703ae150435SJeff Kirsher /* Now, turn on the interrupt for both card functions */
704ae150435SJeff Kirsher set_bits(0x300, link->resource[0]->start + OSITECH_RESET_ISR);
705ae150435SJeff Kirsher dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
706ae150435SJeff Kirsher inw(link->resource[0]->start + OSITECH_AUI_PWR),
707ae150435SJeff Kirsher inw(link->resource[0]->start + OSITECH_RESET_ISR));
708ae150435SJeff Kirsher }
709ae150435SJeff Kirsher return 0;
710ae150435SJeff Kirsher }
711ae150435SJeff Kirsher
smc91c92_suspend(struct pcmcia_device * link)712ae150435SJeff Kirsher static int smc91c92_suspend(struct pcmcia_device *link)
713ae150435SJeff Kirsher {
714ae150435SJeff Kirsher struct net_device *dev = link->priv;
715ae150435SJeff Kirsher
716ae150435SJeff Kirsher if (link->open)
717ae150435SJeff Kirsher netif_device_detach(dev);
718ae150435SJeff Kirsher
719ae150435SJeff Kirsher return 0;
720ae150435SJeff Kirsher }
721ae150435SJeff Kirsher
smc91c92_resume(struct pcmcia_device * link)722ae150435SJeff Kirsher static int smc91c92_resume(struct pcmcia_device *link)
723ae150435SJeff Kirsher {
724ae150435SJeff Kirsher struct net_device *dev = link->priv;
725ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
726ae150435SJeff Kirsher int i;
727ae150435SJeff Kirsher
728ae150435SJeff Kirsher if ((smc->manfid == MANFID_MEGAHERTZ) &&
729ae150435SJeff Kirsher (smc->cardid == PRODID_MEGAHERTZ_EM3288))
730ae150435SJeff Kirsher mhz_3288_power(link);
731ae150435SJeff Kirsher if (smc->manfid == MANFID_MOTOROLA)
732ae150435SJeff Kirsher mot_config(link);
733ae150435SJeff Kirsher if ((smc->manfid == MANFID_OSITECH) &&
734ae150435SJeff Kirsher (smc->cardid != PRODID_OSITECH_SEVEN)) {
735ae150435SJeff Kirsher /* Power up the card and enable interrupts */
736ae150435SJeff Kirsher set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
737ae150435SJeff Kirsher set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
738ae150435SJeff Kirsher }
739ae150435SJeff Kirsher if (((smc->manfid == MANFID_OSITECH) &&
740ae150435SJeff Kirsher (smc->cardid == PRODID_OSITECH_SEVEN)) ||
741ae150435SJeff Kirsher ((smc->manfid == MANFID_PSION) &&
742ae150435SJeff Kirsher (smc->cardid == PRODID_PSION_NET100))) {
743ae150435SJeff Kirsher i = osi_load_firmware(link);
744ae150435SJeff Kirsher if (i) {
745c501b1f5SBen Boeckel netdev_err(dev, "Failed to load firmware\n");
746ae150435SJeff Kirsher return i;
747ae150435SJeff Kirsher }
748ae150435SJeff Kirsher }
749ae150435SJeff Kirsher if (link->open) {
750ae150435SJeff Kirsher smc_reset(dev);
751ae150435SJeff Kirsher netif_device_attach(dev);
752ae150435SJeff Kirsher }
753ae150435SJeff Kirsher
754ae150435SJeff Kirsher return 0;
755ae150435SJeff Kirsher }
756ae150435SJeff Kirsher
757ae150435SJeff Kirsher
758ae150435SJeff Kirsher /*======================================================================
759ae150435SJeff Kirsher
760ae150435SJeff Kirsher This verifies that the chip is some SMC91cXX variant, and returns
761ae150435SJeff Kirsher the revision code if successful. Otherwise, it returns -ENODEV.
762ae150435SJeff Kirsher
763ae150435SJeff Kirsher ======================================================================*/
764ae150435SJeff Kirsher
check_sig(struct pcmcia_device * link)765ae150435SJeff Kirsher static int check_sig(struct pcmcia_device *link)
766ae150435SJeff Kirsher {
767ae150435SJeff Kirsher struct net_device *dev = link->priv;
768ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
769ae150435SJeff Kirsher int width;
770ae150435SJeff Kirsher u_short s;
771ae150435SJeff Kirsher
772ae150435SJeff Kirsher SMC_SELECT_BANK(1);
773ae150435SJeff Kirsher if (inw(ioaddr + BANK_SELECT) >> 8 != 0x33) {
774ae150435SJeff Kirsher /* Try powering up the chip */
775ae150435SJeff Kirsher outw(0, ioaddr + CONTROL);
776ae150435SJeff Kirsher mdelay(55);
777ae150435SJeff Kirsher }
778ae150435SJeff Kirsher
779ae150435SJeff Kirsher /* Try setting bus width */
780ae150435SJeff Kirsher width = (link->resource[0]->flags == IO_DATA_PATH_WIDTH_AUTO);
781ae150435SJeff Kirsher s = inb(ioaddr + CONFIG);
782ae150435SJeff Kirsher if (width)
783ae150435SJeff Kirsher s |= CFG_16BIT;
784ae150435SJeff Kirsher else
785ae150435SJeff Kirsher s &= ~CFG_16BIT;
786ae150435SJeff Kirsher outb(s, ioaddr + CONFIG);
787ae150435SJeff Kirsher
788ae150435SJeff Kirsher /* Check Base Address Register to make sure bus width is OK */
789ae150435SJeff Kirsher s = inw(ioaddr + BASE_ADDR);
790ae150435SJeff Kirsher if ((inw(ioaddr + BANK_SELECT) >> 8 == 0x33) &&
791ae150435SJeff Kirsher ((s >> 8) != (s & 0xff))) {
792ae150435SJeff Kirsher SMC_SELECT_BANK(3);
793ae150435SJeff Kirsher s = inw(ioaddr + REVISION);
794ae150435SJeff Kirsher return s & 0xff;
795ae150435SJeff Kirsher }
796ae150435SJeff Kirsher
797ae150435SJeff Kirsher if (width) {
798c501b1f5SBen Boeckel netdev_info(dev, "using 8-bit IO window\n");
799ae150435SJeff Kirsher
800ae150435SJeff Kirsher smc91c92_suspend(link);
801ae150435SJeff Kirsher pcmcia_fixup_iowidth(link);
802ae150435SJeff Kirsher smc91c92_resume(link);
803ae150435SJeff Kirsher return check_sig(link);
804ae150435SJeff Kirsher }
805ae150435SJeff Kirsher return -ENODEV;
806ae150435SJeff Kirsher }
807ae150435SJeff Kirsher
smc91c92_config(struct pcmcia_device * link)808ae150435SJeff Kirsher static int smc91c92_config(struct pcmcia_device *link)
809ae150435SJeff Kirsher {
810ae150435SJeff Kirsher struct net_device *dev = link->priv;
811ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
812ae150435SJeff Kirsher char *name;
813ae150435SJeff Kirsher int i, rev, j = 0;
814ae150435SJeff Kirsher unsigned int ioaddr;
815ae150435SJeff Kirsher u_long mir;
816ae150435SJeff Kirsher
817ae150435SJeff Kirsher dev_dbg(&link->dev, "smc91c92_config\n");
818ae150435SJeff Kirsher
819ae150435SJeff Kirsher smc->manfid = link->manf_id;
820ae150435SJeff Kirsher smc->cardid = link->card_id;
821ae150435SJeff Kirsher
822ae150435SJeff Kirsher if ((smc->manfid == MANFID_OSITECH) &&
823ae150435SJeff Kirsher (smc->cardid != PRODID_OSITECH_SEVEN)) {
824ae150435SJeff Kirsher i = osi_config(link);
825ae150435SJeff Kirsher } else if ((smc->manfid == MANFID_MOTOROLA) ||
826ae150435SJeff Kirsher ((smc->manfid == MANFID_MEGAHERTZ) &&
827ae150435SJeff Kirsher ((smc->cardid == PRODID_MEGAHERTZ_VARIOUS) ||
828ae150435SJeff Kirsher (smc->cardid == PRODID_MEGAHERTZ_EM3288)))) {
829ae150435SJeff Kirsher i = mhz_mfc_config(link);
830ae150435SJeff Kirsher } else {
831ae150435SJeff Kirsher i = smc_config(link);
832ae150435SJeff Kirsher }
833ae150435SJeff Kirsher if (i)
834ae150435SJeff Kirsher goto config_failed;
835ae150435SJeff Kirsher
836ae150435SJeff Kirsher i = pcmcia_request_irq(link, smc_interrupt);
837ae150435SJeff Kirsher if (i)
838ae150435SJeff Kirsher goto config_failed;
839ae150435SJeff Kirsher i = pcmcia_enable_device(link);
840ae150435SJeff Kirsher if (i)
841ae150435SJeff Kirsher goto config_failed;
842ae150435SJeff Kirsher
843ae150435SJeff Kirsher if (smc->manfid == MANFID_MOTOROLA)
844ae150435SJeff Kirsher mot_config(link);
845ae150435SJeff Kirsher
846ae150435SJeff Kirsher dev->irq = link->irq;
847ae150435SJeff Kirsher
848ae150435SJeff Kirsher if ((if_port >= 0) && (if_port <= 2))
849ae150435SJeff Kirsher dev->if_port = if_port;
850ae150435SJeff Kirsher else
851ae150435SJeff Kirsher dev_notice(&link->dev, "invalid if_port requested\n");
852ae150435SJeff Kirsher
853ae150435SJeff Kirsher switch (smc->manfid) {
854ae150435SJeff Kirsher case MANFID_OSITECH:
855ae150435SJeff Kirsher case MANFID_PSION:
856ae150435SJeff Kirsher i = osi_setup(link, smc->manfid, smc->cardid); break;
857ae150435SJeff Kirsher case MANFID_SMC:
858ae150435SJeff Kirsher case MANFID_NEW_MEDIA:
859ae150435SJeff Kirsher i = smc_setup(link); break;
860ae150435SJeff Kirsher case 0x128: /* For broken Megahertz cards */
861ae150435SJeff Kirsher case MANFID_MEGAHERTZ:
862ae150435SJeff Kirsher i = mhz_setup(link); break;
863ae150435SJeff Kirsher case MANFID_MOTOROLA:
864ae150435SJeff Kirsher default: /* get the hw address from EEPROM */
865ae150435SJeff Kirsher i = mot_setup(link); break;
866ae150435SJeff Kirsher }
867ae150435SJeff Kirsher
868ae150435SJeff Kirsher if (i != 0) {
869ae150435SJeff Kirsher dev_notice(&link->dev, "Unable to find hardware address.\n");
870ae150435SJeff Kirsher goto config_failed;
871ae150435SJeff Kirsher }
872ae150435SJeff Kirsher
873ae150435SJeff Kirsher smc->duplex = 0;
874ae150435SJeff Kirsher smc->rx_ovrn = 0;
875ae150435SJeff Kirsher
876ae150435SJeff Kirsher rev = check_sig(link);
877ae150435SJeff Kirsher name = "???";
878ae150435SJeff Kirsher if (rev > 0)
879ae150435SJeff Kirsher switch (rev >> 4) {
880ae150435SJeff Kirsher case 3: name = "92"; break;
881ae150435SJeff Kirsher case 4: name = ((rev & 15) >= 6) ? "96" : "94"; break;
882ae150435SJeff Kirsher case 5: name = "95"; break;
883ae150435SJeff Kirsher case 7: name = "100"; break;
884ae150435SJeff Kirsher case 8: name = "100-FD"; break;
885ae150435SJeff Kirsher case 9: name = "110"; break;
886ae150435SJeff Kirsher }
887ae150435SJeff Kirsher
888ae150435SJeff Kirsher ioaddr = dev->base_addr;
889ae150435SJeff Kirsher if (rev > 0) {
890ae150435SJeff Kirsher u_long mcr;
891ae150435SJeff Kirsher SMC_SELECT_BANK(0);
892ae150435SJeff Kirsher mir = inw(ioaddr + MEMINFO) & 0xff;
893ae150435SJeff Kirsher if (mir == 0xff) mir++;
894ae150435SJeff Kirsher /* Get scale factor for memory size */
895ae150435SJeff Kirsher mcr = ((rev >> 4) > 3) ? inw(ioaddr + MEMCFG) : 0x0200;
896ae150435SJeff Kirsher mir *= 128 * (1<<((mcr >> 9) & 7));
897ae150435SJeff Kirsher SMC_SELECT_BANK(1);
898ae150435SJeff Kirsher smc->cfg = inw(ioaddr + CONFIG) & ~CFG_AUI_SELECT;
899ae150435SJeff Kirsher smc->cfg |= CFG_NO_WAIT | CFG_16BIT | CFG_STATIC;
900ae150435SJeff Kirsher if (smc->manfid == MANFID_OSITECH)
901ae150435SJeff Kirsher smc->cfg |= CFG_IRQ_SEL_1 | CFG_IRQ_SEL_0;
902ae150435SJeff Kirsher if ((rev >> 4) >= 7)
903ae150435SJeff Kirsher smc->cfg |= CFG_MII_SELECT;
904ae150435SJeff Kirsher } else
905ae150435SJeff Kirsher mir = 0;
906ae150435SJeff Kirsher
907ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT) {
908ae150435SJeff Kirsher SMC_SELECT_BANK(3);
909ae150435SJeff Kirsher
910ae150435SJeff Kirsher for (i = 0; i < 32; i++) {
911ae150435SJeff Kirsher j = mdio_read(dev, i, 1);
912ae150435SJeff Kirsher if ((j != 0) && (j != 0xffff)) break;
913ae150435SJeff Kirsher }
914ae150435SJeff Kirsher smc->mii_if.phy_id = (i < 32) ? i : -1;
915ae150435SJeff Kirsher
916ae150435SJeff Kirsher SMC_SELECT_BANK(0);
917ae150435SJeff Kirsher }
918ae150435SJeff Kirsher
919ae150435SJeff Kirsher SET_NETDEV_DEV(dev, &link->dev);
920ae150435SJeff Kirsher
921ae150435SJeff Kirsher if (register_netdev(dev) != 0) {
922ae150435SJeff Kirsher dev_err(&link->dev, "register_netdev() failed\n");
923ae150435SJeff Kirsher goto config_undo;
924ae150435SJeff Kirsher }
925ae150435SJeff Kirsher
926ae150435SJeff Kirsher netdev_info(dev, "smc91c%s rev %d: io %#3lx, irq %d, hw_addr %pM\n",
927ae150435SJeff Kirsher name, (rev & 0x0f), dev->base_addr, dev->irq, dev->dev_addr);
928ae150435SJeff Kirsher
929ae150435SJeff Kirsher if (rev > 0) {
930ae150435SJeff Kirsher if (mir & 0x3ff)
931ae150435SJeff Kirsher netdev_info(dev, " %lu byte", mir);
932ae150435SJeff Kirsher else
933ae150435SJeff Kirsher netdev_info(dev, " %lu kb", mir>>10);
934ae150435SJeff Kirsher pr_cont(" buffer, %s xcvr\n",
935ae150435SJeff Kirsher (smc->cfg & CFG_MII_SELECT) ? "MII" : if_names[dev->if_port]);
936ae150435SJeff Kirsher }
937ae150435SJeff Kirsher
938ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT) {
939ae150435SJeff Kirsher if (smc->mii_if.phy_id != -1) {
940ae150435SJeff Kirsher netdev_dbg(dev, " MII transceiver at index %d, status %x\n",
941ae150435SJeff Kirsher smc->mii_if.phy_id, j);
942ae150435SJeff Kirsher } else {
943ae150435SJeff Kirsher netdev_notice(dev, " No MII transceivers found!\n");
944ae150435SJeff Kirsher }
945ae150435SJeff Kirsher }
946ae150435SJeff Kirsher return 0;
947ae150435SJeff Kirsher
948ae150435SJeff Kirsher config_undo:
949ae150435SJeff Kirsher unregister_netdev(dev);
950ae150435SJeff Kirsher config_failed:
951ae150435SJeff Kirsher smc91c92_release(link);
952ae150435SJeff Kirsher free_netdev(dev);
953ae150435SJeff Kirsher return -ENODEV;
954ae150435SJeff Kirsher } /* smc91c92_config */
955ae150435SJeff Kirsher
smc91c92_release(struct pcmcia_device * link)956ae150435SJeff Kirsher static void smc91c92_release(struct pcmcia_device *link)
957ae150435SJeff Kirsher {
958ae150435SJeff Kirsher dev_dbg(&link->dev, "smc91c92_release\n");
959ae150435SJeff Kirsher if (link->resource[2]->end) {
960ae150435SJeff Kirsher struct net_device *dev = link->priv;
961ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
962ae150435SJeff Kirsher iounmap(smc->base);
963ae150435SJeff Kirsher }
964ae150435SJeff Kirsher pcmcia_disable_device(link);
965ae150435SJeff Kirsher }
966ae150435SJeff Kirsher
967ae150435SJeff Kirsher /*======================================================================
968ae150435SJeff Kirsher
969ae150435SJeff Kirsher MII interface support for SMC91cXX based cards
970ae150435SJeff Kirsher ======================================================================*/
971ae150435SJeff Kirsher
972ae150435SJeff Kirsher #define MDIO_SHIFT_CLK 0x04
973ae150435SJeff Kirsher #define MDIO_DATA_OUT 0x01
974ae150435SJeff Kirsher #define MDIO_DIR_WRITE 0x08
975ae150435SJeff Kirsher #define MDIO_DATA_WRITE0 (MDIO_DIR_WRITE)
976ae150435SJeff Kirsher #define MDIO_DATA_WRITE1 (MDIO_DIR_WRITE | MDIO_DATA_OUT)
977ae150435SJeff Kirsher #define MDIO_DATA_READ 0x02
978ae150435SJeff Kirsher
mdio_sync(unsigned int addr)979ae150435SJeff Kirsher static void mdio_sync(unsigned int addr)
980ae150435SJeff Kirsher {
981ae150435SJeff Kirsher int bits;
982ae150435SJeff Kirsher for (bits = 0; bits < 32; bits++) {
983ae150435SJeff Kirsher outb(MDIO_DATA_WRITE1, addr);
984ae150435SJeff Kirsher outb(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr);
985ae150435SJeff Kirsher }
986ae150435SJeff Kirsher }
987ae150435SJeff Kirsher
mdio_read(struct net_device * dev,int phy_id,int loc)988ae150435SJeff Kirsher static int mdio_read(struct net_device *dev, int phy_id, int loc)
989ae150435SJeff Kirsher {
990ae150435SJeff Kirsher unsigned int addr = dev->base_addr + MGMT;
991ae150435SJeff Kirsher u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
992ae150435SJeff Kirsher int i, retval = 0;
993ae150435SJeff Kirsher
994ae150435SJeff Kirsher mdio_sync(addr);
995ae150435SJeff Kirsher for (i = 13; i >= 0; i--) {
996ae150435SJeff Kirsher int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
997ae150435SJeff Kirsher outb(dat, addr);
998ae150435SJeff Kirsher outb(dat | MDIO_SHIFT_CLK, addr);
999ae150435SJeff Kirsher }
1000ae150435SJeff Kirsher for (i = 19; i > 0; i--) {
1001ae150435SJeff Kirsher outb(0, addr);
1002ae150435SJeff Kirsher retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0);
1003ae150435SJeff Kirsher outb(MDIO_SHIFT_CLK, addr);
1004ae150435SJeff Kirsher }
1005ae150435SJeff Kirsher return (retval>>1) & 0xffff;
1006ae150435SJeff Kirsher }
1007ae150435SJeff Kirsher
mdio_write(struct net_device * dev,int phy_id,int loc,int value)1008ae150435SJeff Kirsher static void mdio_write(struct net_device *dev, int phy_id, int loc, int value)
1009ae150435SJeff Kirsher {
1010ae150435SJeff Kirsher unsigned int addr = dev->base_addr + MGMT;
1011ae150435SJeff Kirsher u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
1012ae150435SJeff Kirsher int i;
1013ae150435SJeff Kirsher
1014ae150435SJeff Kirsher mdio_sync(addr);
1015ae150435SJeff Kirsher for (i = 31; i >= 0; i--) {
1016ae150435SJeff Kirsher int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
1017ae150435SJeff Kirsher outb(dat, addr);
1018ae150435SJeff Kirsher outb(dat | MDIO_SHIFT_CLK, addr);
1019ae150435SJeff Kirsher }
1020ae150435SJeff Kirsher for (i = 1; i >= 0; i--) {
1021ae150435SJeff Kirsher outb(0, addr);
1022ae150435SJeff Kirsher outb(MDIO_SHIFT_CLK, addr);
1023ae150435SJeff Kirsher }
1024ae150435SJeff Kirsher }
1025ae150435SJeff Kirsher
1026ae150435SJeff Kirsher /*======================================================================
1027ae150435SJeff Kirsher
1028ae150435SJeff Kirsher The driver core code, most of which should be common with a
1029ae150435SJeff Kirsher non-PCMCIA implementation.
1030ae150435SJeff Kirsher
1031ae150435SJeff Kirsher ======================================================================*/
1032ae150435SJeff Kirsher
1033ae150435SJeff Kirsher #ifdef PCMCIA_DEBUG
smc_dump(struct net_device * dev)1034ae150435SJeff Kirsher static void smc_dump(struct net_device *dev)
1035ae150435SJeff Kirsher {
1036ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1037ae150435SJeff Kirsher u_short i, w, save;
1038ae150435SJeff Kirsher save = inw(ioaddr + BANK_SELECT);
1039ae150435SJeff Kirsher for (w = 0; w < 4; w++) {
1040ae150435SJeff Kirsher SMC_SELECT_BANK(w);
1041c501b1f5SBen Boeckel netdev_dbg(dev, "bank %d: ", w);
1042ae150435SJeff Kirsher for (i = 0; i < 14; i += 2)
1043ae150435SJeff Kirsher pr_cont(" %04x", inw(ioaddr + i));
1044ae150435SJeff Kirsher pr_cont("\n");
1045ae150435SJeff Kirsher }
1046ae150435SJeff Kirsher outw(save, ioaddr + BANK_SELECT);
1047ae150435SJeff Kirsher }
1048ae150435SJeff Kirsher #endif
1049ae150435SJeff Kirsher
smc_open(struct net_device * dev)1050ae150435SJeff Kirsher static int smc_open(struct net_device *dev)
1051ae150435SJeff Kirsher {
1052ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1053ae150435SJeff Kirsher struct pcmcia_device *link = smc->p_dev;
1054ae150435SJeff Kirsher
1055ae150435SJeff Kirsher dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n",
1056ae150435SJeff Kirsher dev->name, dev, inw(dev->base_addr + BANK_SELECT));
1057ae150435SJeff Kirsher #ifdef PCMCIA_DEBUG
1058ae150435SJeff Kirsher smc_dump(dev);
1059ae150435SJeff Kirsher #endif
1060ae150435SJeff Kirsher
1061ae150435SJeff Kirsher /* Check that the PCMCIA card is still here. */
1062ae150435SJeff Kirsher if (!pcmcia_dev_present(link))
1063ae150435SJeff Kirsher return -ENODEV;
1064ae150435SJeff Kirsher /* Physical device present signature. */
1065ae150435SJeff Kirsher if (check_sig(link) < 0) {
1066ae150435SJeff Kirsher netdev_info(dev, "Yikes! Bad chip signature!\n");
1067ae150435SJeff Kirsher return -ENODEV;
1068ae150435SJeff Kirsher }
1069ae150435SJeff Kirsher link->open++;
1070ae150435SJeff Kirsher
1071ae150435SJeff Kirsher netif_start_queue(dev);
1072ae150435SJeff Kirsher smc->saved_skb = NULL;
1073ae150435SJeff Kirsher smc->packets_waiting = 0;
1074ae150435SJeff Kirsher
1075ae150435SJeff Kirsher smc_reset(dev);
1076267146d4SKees Cook timer_setup(&smc->media, media_check, 0);
1077b8b01344SVaishali Thakkar mod_timer(&smc->media, jiffies + HZ);
1078ae150435SJeff Kirsher
1079ae150435SJeff Kirsher return 0;
1080ae150435SJeff Kirsher } /* smc_open */
1081ae150435SJeff Kirsher
1082ae150435SJeff Kirsher /*====================================================================*/
1083ae150435SJeff Kirsher
smc_close(struct net_device * dev)1084ae150435SJeff Kirsher static int smc_close(struct net_device *dev)
1085ae150435SJeff Kirsher {
1086ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1087ae150435SJeff Kirsher struct pcmcia_device *link = smc->p_dev;
1088ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1089ae150435SJeff Kirsher
1090ae150435SJeff Kirsher dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n",
1091ae150435SJeff Kirsher dev->name, inw(ioaddr + BANK_SELECT));
1092ae150435SJeff Kirsher
1093ae150435SJeff Kirsher netif_stop_queue(dev);
1094ae150435SJeff Kirsher
1095ae150435SJeff Kirsher /* Shut off all interrupts, and turn off the Tx and Rx sections.
1096ae150435SJeff Kirsher Don't bother to check for chip present. */
1097ae150435SJeff Kirsher SMC_SELECT_BANK(2); /* Nominally paranoia, but do no assume... */
1098ae150435SJeff Kirsher outw(0, ioaddr + INTERRUPT);
1099ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1100ae150435SJeff Kirsher mask_bits(0xff00, ioaddr + RCR);
1101ae150435SJeff Kirsher mask_bits(0xff00, ioaddr + TCR);
1102ae150435SJeff Kirsher
1103ae150435SJeff Kirsher /* Put the chip into power-down mode. */
1104ae150435SJeff Kirsher SMC_SELECT_BANK(1);
1105ae150435SJeff Kirsher outw(CTL_POWERDOWN, ioaddr + CONTROL );
1106ae150435SJeff Kirsher
1107ae150435SJeff Kirsher link->open--;
1108ae150435SJeff Kirsher del_timer_sync(&smc->media);
1109ae150435SJeff Kirsher
1110ae150435SJeff Kirsher return 0;
1111ae150435SJeff Kirsher } /* smc_close */
1112ae150435SJeff Kirsher
1113ae150435SJeff Kirsher /*======================================================================
1114ae150435SJeff Kirsher
1115ae150435SJeff Kirsher Transfer a packet to the hardware and trigger the packet send.
1116ae150435SJeff Kirsher This may be called at either from either the Tx queue code
1117ae150435SJeff Kirsher or the interrupt handler.
1118ae150435SJeff Kirsher
1119ae150435SJeff Kirsher ======================================================================*/
1120ae150435SJeff Kirsher
smc_hardware_send_packet(struct net_device * dev)1121ae150435SJeff Kirsher static void smc_hardware_send_packet(struct net_device * dev)
1122ae150435SJeff Kirsher {
1123ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1124ae150435SJeff Kirsher struct sk_buff *skb = smc->saved_skb;
1125ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1126ae150435SJeff Kirsher u_char packet_no;
1127ae150435SJeff Kirsher
1128ae150435SJeff Kirsher if (!skb) {
1129ae150435SJeff Kirsher netdev_err(dev, "In XMIT with no packet to send\n");
1130ae150435SJeff Kirsher return;
1131ae150435SJeff Kirsher }
1132ae150435SJeff Kirsher
1133ae150435SJeff Kirsher /* There should be a packet slot waiting. */
1134ae150435SJeff Kirsher packet_no = inw(ioaddr + PNR_ARR) >> 8;
1135ae150435SJeff Kirsher if (packet_no & 0x80) {
1136ae150435SJeff Kirsher /* If not, there is a hardware problem! Likely an ejected card. */
1137ae150435SJeff Kirsher netdev_warn(dev, "hardware Tx buffer allocation failed, status %#2.2x\n",
1138ae150435SJeff Kirsher packet_no);
1139ae150435SJeff Kirsher dev_kfree_skb_irq(skb);
1140ae150435SJeff Kirsher smc->saved_skb = NULL;
1141ae150435SJeff Kirsher netif_start_queue(dev);
1142ae150435SJeff Kirsher return;
1143ae150435SJeff Kirsher }
1144ae150435SJeff Kirsher
1145ae150435SJeff Kirsher dev->stats.tx_bytes += skb->len;
1146ae150435SJeff Kirsher /* The card should use the just-allocated buffer. */
1147ae150435SJeff Kirsher outw(packet_no, ioaddr + PNR_ARR);
1148ae150435SJeff Kirsher /* point to the beginning of the packet */
1149ae150435SJeff Kirsher outw(PTR_AUTOINC , ioaddr + POINTER);
1150ae150435SJeff Kirsher
1151ae150435SJeff Kirsher /* Send the packet length (+6 for status, length and ctl byte)
1152ae150435SJeff Kirsher and the status word (set to zeros). */
1153ae150435SJeff Kirsher {
1154ae150435SJeff Kirsher u_char *buf = skb->data;
1155ae150435SJeff Kirsher u_int length = skb->len; /* The chip will pad to ethernet min. */
1156ae150435SJeff Kirsher
1157ae150435SJeff Kirsher netdev_dbg(dev, "Trying to xmit packet of length %d\n", length);
1158ae150435SJeff Kirsher
1159ae150435SJeff Kirsher /* send the packet length: +6 for status word, length, and ctl */
1160ae150435SJeff Kirsher outw(0, ioaddr + DATA_1);
1161ae150435SJeff Kirsher outw(length + 6, ioaddr + DATA_1);
1162ae150435SJeff Kirsher outsw(ioaddr + DATA_1, buf, length >> 1);
1163ae150435SJeff Kirsher
1164ae150435SJeff Kirsher /* The odd last byte, if there is one, goes in the control word. */
1165ae150435SJeff Kirsher outw((length & 1) ? 0x2000 | buf[length-1] : 0, ioaddr + DATA_1);
1166ae150435SJeff Kirsher }
1167ae150435SJeff Kirsher
1168ae150435SJeff Kirsher /* Enable the Tx interrupts, both Tx (TxErr) and TxEmpty. */
1169ae150435SJeff Kirsher outw(((IM_TX_INT|IM_TX_EMPTY_INT)<<8) |
1170ae150435SJeff Kirsher (inw(ioaddr + INTERRUPT) & 0xff00),
1171ae150435SJeff Kirsher ioaddr + INTERRUPT);
1172ae150435SJeff Kirsher
1173ae150435SJeff Kirsher /* The chip does the rest of the work. */
1174ae150435SJeff Kirsher outw(MC_ENQUEUE , ioaddr + MMU_CMD);
1175ae150435SJeff Kirsher
1176ae150435SJeff Kirsher smc->saved_skb = NULL;
1177ae150435SJeff Kirsher dev_kfree_skb_irq(skb);
1178860e9538SFlorian Westphal netif_trans_update(dev);
1179ae150435SJeff Kirsher netif_start_queue(dev);
1180ae150435SJeff Kirsher }
1181ae150435SJeff Kirsher
1182ae150435SJeff Kirsher /*====================================================================*/
1183ae150435SJeff Kirsher
smc_tx_timeout(struct net_device * dev,unsigned int txqueue)11840290bd29SMichael S. Tsirkin static void smc_tx_timeout(struct net_device *dev, unsigned int txqueue)
1185ae150435SJeff Kirsher {
1186ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1187ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1188ae150435SJeff Kirsher
1189ae150435SJeff Kirsher netdev_notice(dev, "transmit timed out, Tx_status %2.2x status %4.4x.\n",
1190ae150435SJeff Kirsher inw(ioaddr)&0xff, inw(ioaddr + 2));
1191ae150435SJeff Kirsher dev->stats.tx_errors++;
1192ae150435SJeff Kirsher smc_reset(dev);
1193860e9538SFlorian Westphal netif_trans_update(dev); /* prevent tx timeout */
1194ae150435SJeff Kirsher smc->saved_skb = NULL;
1195ae150435SJeff Kirsher netif_wake_queue(dev);
1196ae150435SJeff Kirsher }
1197ae150435SJeff Kirsher
smc_start_xmit(struct sk_buff * skb,struct net_device * dev)1198ae150435SJeff Kirsher static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
1199ae150435SJeff Kirsher struct net_device *dev)
1200ae150435SJeff Kirsher {
1201ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1202ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1203ae150435SJeff Kirsher u_short num_pages;
1204ae150435SJeff Kirsher short time_out, ir;
1205ae150435SJeff Kirsher unsigned long flags;
1206ae150435SJeff Kirsher
1207ae150435SJeff Kirsher netif_stop_queue(dev);
1208ae150435SJeff Kirsher
1209ae150435SJeff Kirsher netdev_dbg(dev, "smc_start_xmit(length = %d) called, status %04x\n",
1210ae150435SJeff Kirsher skb->len, inw(ioaddr + 2));
1211ae150435SJeff Kirsher
1212ae150435SJeff Kirsher if (smc->saved_skb) {
1213ae150435SJeff Kirsher /* THIS SHOULD NEVER HAPPEN. */
1214ae150435SJeff Kirsher dev->stats.tx_aborted_errors++;
1215c501b1f5SBen Boeckel netdev_dbg(dev, "Internal error -- sent packet while busy\n");
1216ae150435SJeff Kirsher return NETDEV_TX_BUSY;
1217ae150435SJeff Kirsher }
1218ae150435SJeff Kirsher smc->saved_skb = skb;
1219ae150435SJeff Kirsher
1220ae150435SJeff Kirsher num_pages = skb->len >> 8;
1221ae150435SJeff Kirsher
1222ae150435SJeff Kirsher if (num_pages > 7) {
1223ae150435SJeff Kirsher netdev_err(dev, "Far too big packet error: %d pages\n", num_pages);
1224ae150435SJeff Kirsher dev_kfree_skb (skb);
1225ae150435SJeff Kirsher smc->saved_skb = NULL;
1226ae150435SJeff Kirsher dev->stats.tx_dropped++;
1227ae150435SJeff Kirsher return NETDEV_TX_OK; /* Do not re-queue this packet. */
1228ae150435SJeff Kirsher }
1229ae150435SJeff Kirsher /* A packet is now waiting. */
1230ae150435SJeff Kirsher smc->packets_waiting++;
1231ae150435SJeff Kirsher
1232ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
1233ae150435SJeff Kirsher SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */
1234ae150435SJeff Kirsher
1235ae150435SJeff Kirsher /* need MC_RESET to keep the memory consistent. errata? */
1236ae150435SJeff Kirsher if (smc->rx_ovrn) {
1237ae150435SJeff Kirsher outw(MC_RESET, ioaddr + MMU_CMD);
1238ae150435SJeff Kirsher smc->rx_ovrn = 0;
1239ae150435SJeff Kirsher }
1240ae150435SJeff Kirsher
1241ae150435SJeff Kirsher /* Allocate the memory; send the packet now if we win. */
1242ae150435SJeff Kirsher outw(MC_ALLOC | num_pages, ioaddr + MMU_CMD);
1243ae150435SJeff Kirsher for (time_out = MEMORY_WAIT_TIME; time_out >= 0; time_out--) {
1244ae150435SJeff Kirsher ir = inw(ioaddr+INTERRUPT);
1245ae150435SJeff Kirsher if (ir & IM_ALLOC_INT) {
1246ae150435SJeff Kirsher /* Acknowledge the interrupt, send the packet. */
1247ae150435SJeff Kirsher outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT);
1248ae150435SJeff Kirsher smc_hardware_send_packet(dev); /* Send the packet now.. */
1249ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
1250ae150435SJeff Kirsher return NETDEV_TX_OK;
1251ae150435SJeff Kirsher }
1252ae150435SJeff Kirsher }
1253ae150435SJeff Kirsher
1254ae150435SJeff Kirsher /* Otherwise defer until the Tx-space-allocated interrupt. */
1255c501b1f5SBen Boeckel netdev_dbg(dev, "memory allocation deferred.\n");
1256ae150435SJeff Kirsher outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
1257ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
1258ae150435SJeff Kirsher
1259ae150435SJeff Kirsher return NETDEV_TX_OK;
1260ae150435SJeff Kirsher }
1261ae150435SJeff Kirsher
1262ae150435SJeff Kirsher /*======================================================================
1263ae150435SJeff Kirsher
1264ae150435SJeff Kirsher Handle a Tx anomalous event. Entered while in Window 2.
1265ae150435SJeff Kirsher
1266ae150435SJeff Kirsher ======================================================================*/
1267ae150435SJeff Kirsher
smc_tx_err(struct net_device * dev)1268ae150435SJeff Kirsher static void smc_tx_err(struct net_device * dev)
1269ae150435SJeff Kirsher {
1270ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1271ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1272ae150435SJeff Kirsher int saved_packet = inw(ioaddr + PNR_ARR) & 0xff;
1273ae150435SJeff Kirsher int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f;
1274ae150435SJeff Kirsher int tx_status;
1275ae150435SJeff Kirsher
1276ae150435SJeff Kirsher /* select this as the packet to read from */
1277ae150435SJeff Kirsher outw(packet_no, ioaddr + PNR_ARR);
1278ae150435SJeff Kirsher
1279ae150435SJeff Kirsher /* read the first word from this packet */
1280ae150435SJeff Kirsher outw(PTR_AUTOINC | PTR_READ | 0, ioaddr + POINTER);
1281ae150435SJeff Kirsher
1282ae150435SJeff Kirsher tx_status = inw(ioaddr + DATA_1);
1283ae150435SJeff Kirsher
1284ae150435SJeff Kirsher dev->stats.tx_errors++;
1285ae150435SJeff Kirsher if (tx_status & TS_LOSTCAR) dev->stats.tx_carrier_errors++;
1286ae150435SJeff Kirsher if (tx_status & TS_LATCOL) dev->stats.tx_window_errors++;
1287ae150435SJeff Kirsher if (tx_status & TS_16COL) {
1288ae150435SJeff Kirsher dev->stats.tx_aborted_errors++;
1289ae150435SJeff Kirsher smc->tx_err++;
1290ae150435SJeff Kirsher }
1291ae150435SJeff Kirsher
1292ae150435SJeff Kirsher if (tx_status & TS_SUCCESS) {
1293ae150435SJeff Kirsher netdev_notice(dev, "Successful packet caused error interrupt?\n");
1294ae150435SJeff Kirsher }
1295ae150435SJeff Kirsher /* re-enable transmit */
1296ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1297ae150435SJeff Kirsher outw(inw(ioaddr + TCR) | TCR_ENABLE | smc->duplex, ioaddr + TCR);
1298ae150435SJeff Kirsher SMC_SELECT_BANK(2);
1299ae150435SJeff Kirsher
1300ae150435SJeff Kirsher outw(MC_FREEPKT, ioaddr + MMU_CMD); /* Free the packet memory. */
1301ae150435SJeff Kirsher
1302ae150435SJeff Kirsher /* one less packet waiting for me */
1303ae150435SJeff Kirsher smc->packets_waiting--;
1304ae150435SJeff Kirsher
1305ae150435SJeff Kirsher outw(saved_packet, ioaddr + PNR_ARR);
1306ae150435SJeff Kirsher }
1307ae150435SJeff Kirsher
1308ae150435SJeff Kirsher /*====================================================================*/
1309ae150435SJeff Kirsher
smc_eph_irq(struct net_device * dev)1310ae150435SJeff Kirsher static void smc_eph_irq(struct net_device *dev)
1311ae150435SJeff Kirsher {
1312ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1313ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1314ae150435SJeff Kirsher u_short card_stats, ephs;
1315ae150435SJeff Kirsher
1316ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1317ae150435SJeff Kirsher ephs = inw(ioaddr + EPH);
1318c501b1f5SBen Boeckel netdev_dbg(dev, "Ethernet protocol handler interrupt, status %4.4x.\n",
1319c501b1f5SBen Boeckel ephs);
1320ae150435SJeff Kirsher /* Could be a counter roll-over warning: update stats. */
1321ae150435SJeff Kirsher card_stats = inw(ioaddr + COUNTER);
1322ae150435SJeff Kirsher /* single collisions */
1323ae150435SJeff Kirsher dev->stats.collisions += card_stats & 0xF;
1324ae150435SJeff Kirsher card_stats >>= 4;
1325ae150435SJeff Kirsher /* multiple collisions */
1326ae150435SJeff Kirsher dev->stats.collisions += card_stats & 0xF;
1327ae150435SJeff Kirsher #if 0 /* These are for when linux supports these statistics */
1328ae150435SJeff Kirsher card_stats >>= 4; /* deferred */
1329ae150435SJeff Kirsher card_stats >>= 4; /* excess deferred */
1330ae150435SJeff Kirsher #endif
1331ae150435SJeff Kirsher /* If we had a transmit error we must re-enable the transmitter. */
1332ae150435SJeff Kirsher outw(inw(ioaddr + TCR) | TCR_ENABLE | smc->duplex, ioaddr + TCR);
1333ae150435SJeff Kirsher
1334ae150435SJeff Kirsher /* Clear a link error interrupt. */
1335ae150435SJeff Kirsher SMC_SELECT_BANK(1);
1336ae150435SJeff Kirsher outw(CTL_AUTO_RELEASE | 0x0000, ioaddr + CONTROL);
1337ae150435SJeff Kirsher outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE,
1338ae150435SJeff Kirsher ioaddr + CONTROL);
1339ae150435SJeff Kirsher SMC_SELECT_BANK(2);
1340ae150435SJeff Kirsher }
1341ae150435SJeff Kirsher
1342ae150435SJeff Kirsher /*====================================================================*/
1343ae150435SJeff Kirsher
smc_interrupt(int irq,void * dev_id)1344ae150435SJeff Kirsher static irqreturn_t smc_interrupt(int irq, void *dev_id)
1345ae150435SJeff Kirsher {
1346ae150435SJeff Kirsher struct net_device *dev = dev_id;
1347ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1348ae150435SJeff Kirsher unsigned int ioaddr;
1349ae150435SJeff Kirsher u_short saved_bank, saved_pointer, mask, status;
1350ae150435SJeff Kirsher unsigned int handled = 1;
1351ae150435SJeff Kirsher char bogus_cnt = INTR_WORK; /* Work we are willing to do. */
1352ae150435SJeff Kirsher
1353ae150435SJeff Kirsher if (!netif_device_present(dev))
1354ae150435SJeff Kirsher return IRQ_NONE;
1355ae150435SJeff Kirsher
1356ae150435SJeff Kirsher ioaddr = dev->base_addr;
1357ae150435SJeff Kirsher
1358c501b1f5SBen Boeckel netdev_dbg(dev, "SMC91c92 interrupt %d at %#x.\n",
1359ae150435SJeff Kirsher irq, ioaddr);
1360ae150435SJeff Kirsher
1361ae150435SJeff Kirsher spin_lock(&smc->lock);
1362ae150435SJeff Kirsher smc->watchdog = 0;
1363ae150435SJeff Kirsher saved_bank = inw(ioaddr + BANK_SELECT);
1364ae150435SJeff Kirsher if ((saved_bank & 0xff00) != 0x3300) {
1365ae150435SJeff Kirsher /* The device does not exist -- the card could be off-line, or
1366ae150435SJeff Kirsher maybe it has been ejected. */
1367c501b1f5SBen Boeckel netdev_dbg(dev, "SMC91c92 interrupt %d for non-existent/ejected device.\n",
1368c501b1f5SBen Boeckel irq);
1369ae150435SJeff Kirsher handled = 0;
1370ae150435SJeff Kirsher goto irq_done;
1371ae150435SJeff Kirsher }
1372ae150435SJeff Kirsher
1373ae150435SJeff Kirsher SMC_SELECT_BANK(2);
1374ae150435SJeff Kirsher saved_pointer = inw(ioaddr + POINTER);
1375ae150435SJeff Kirsher mask = inw(ioaddr + INTERRUPT) >> 8;
1376ae150435SJeff Kirsher /* clear all interrupts */
1377ae150435SJeff Kirsher outw(0, ioaddr + INTERRUPT);
1378ae150435SJeff Kirsher
1379ae150435SJeff Kirsher do { /* read the status flag, and mask it */
1380ae150435SJeff Kirsher status = inw(ioaddr + INTERRUPT) & 0xff;
1381c501b1f5SBen Boeckel netdev_dbg(dev, "Status is %#2.2x (mask %#2.2x).\n",
1382ae150435SJeff Kirsher status, mask);
1383ae150435SJeff Kirsher if ((status & mask) == 0) {
1384ae150435SJeff Kirsher if (bogus_cnt == INTR_WORK)
1385ae150435SJeff Kirsher handled = 0;
1386ae150435SJeff Kirsher break;
1387ae150435SJeff Kirsher }
1388ae150435SJeff Kirsher if (status & IM_RCV_INT) {
1389ae150435SJeff Kirsher /* Got a packet(s). */
1390ae150435SJeff Kirsher smc_rx(dev);
1391ae150435SJeff Kirsher }
1392ae150435SJeff Kirsher if (status & IM_TX_INT) {
1393ae150435SJeff Kirsher smc_tx_err(dev);
1394ae150435SJeff Kirsher outw(IM_TX_INT, ioaddr + INTERRUPT);
1395ae150435SJeff Kirsher }
1396ae150435SJeff Kirsher status &= mask;
1397ae150435SJeff Kirsher if (status & IM_TX_EMPTY_INT) {
1398ae150435SJeff Kirsher outw(IM_TX_EMPTY_INT, ioaddr + INTERRUPT);
1399ae150435SJeff Kirsher mask &= ~IM_TX_EMPTY_INT;
1400ae150435SJeff Kirsher dev->stats.tx_packets += smc->packets_waiting;
1401ae150435SJeff Kirsher smc->packets_waiting = 0;
1402ae150435SJeff Kirsher }
1403ae150435SJeff Kirsher if (status & IM_ALLOC_INT) {
1404ae150435SJeff Kirsher /* Clear this interrupt so it doesn't happen again */
1405ae150435SJeff Kirsher mask &= ~IM_ALLOC_INT;
1406ae150435SJeff Kirsher
1407ae150435SJeff Kirsher smc_hardware_send_packet(dev);
1408ae150435SJeff Kirsher
1409ae150435SJeff Kirsher /* enable xmit interrupts based on this */
1410ae150435SJeff Kirsher mask |= (IM_TX_EMPTY_INT | IM_TX_INT);
1411ae150435SJeff Kirsher
1412ae150435SJeff Kirsher /* and let the card send more packets to me */
1413ae150435SJeff Kirsher netif_wake_queue(dev);
1414ae150435SJeff Kirsher }
1415ae150435SJeff Kirsher if (status & IM_RX_OVRN_INT) {
1416ae150435SJeff Kirsher dev->stats.rx_errors++;
1417ae150435SJeff Kirsher dev->stats.rx_fifo_errors++;
1418ae150435SJeff Kirsher if (smc->duplex)
1419ae150435SJeff Kirsher smc->rx_ovrn = 1; /* need MC_RESET outside smc_interrupt */
1420ae150435SJeff Kirsher outw(IM_RX_OVRN_INT, ioaddr + INTERRUPT);
1421ae150435SJeff Kirsher }
1422ae150435SJeff Kirsher if (status & IM_EPH_INT)
1423ae150435SJeff Kirsher smc_eph_irq(dev);
1424ae150435SJeff Kirsher } while (--bogus_cnt);
1425ae150435SJeff Kirsher
1426c501b1f5SBen Boeckel netdev_dbg(dev, " Restoring saved registers mask %2.2x bank %4.4x pointer %4.4x.\n",
1427c501b1f5SBen Boeckel mask, saved_bank, saved_pointer);
1428ae150435SJeff Kirsher
1429ae150435SJeff Kirsher /* restore state register */
1430ae150435SJeff Kirsher outw((mask<<8), ioaddr + INTERRUPT);
1431ae150435SJeff Kirsher outw(saved_pointer, ioaddr + POINTER);
1432ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1433ae150435SJeff Kirsher
1434c501b1f5SBen Boeckel netdev_dbg(dev, "Exiting interrupt IRQ%d.\n", irq);
1435ae150435SJeff Kirsher
1436ae150435SJeff Kirsher irq_done:
1437ae150435SJeff Kirsher
1438ae150435SJeff Kirsher if ((smc->manfid == MANFID_OSITECH) &&
1439ae150435SJeff Kirsher (smc->cardid != PRODID_OSITECH_SEVEN)) {
1440ae150435SJeff Kirsher /* Retrigger interrupt if needed */
1441ae150435SJeff Kirsher mask_bits(0x00ff, ioaddr-0x10+OSITECH_RESET_ISR);
1442ae150435SJeff Kirsher set_bits(0x0300, ioaddr-0x10+OSITECH_RESET_ISR);
1443ae150435SJeff Kirsher }
1444ae150435SJeff Kirsher if (smc->manfid == MANFID_MOTOROLA) {
1445ae150435SJeff Kirsher u_char cor;
1446ae150435SJeff Kirsher cor = readb(smc->base + MOT_UART + CISREG_COR);
1447ae150435SJeff Kirsher writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_UART + CISREG_COR);
1448ae150435SJeff Kirsher writeb(cor, smc->base + MOT_UART + CISREG_COR);
1449ae150435SJeff Kirsher cor = readb(smc->base + MOT_LAN + CISREG_COR);
1450ae150435SJeff Kirsher writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_LAN + CISREG_COR);
1451ae150435SJeff Kirsher writeb(cor, smc->base + MOT_LAN + CISREG_COR);
1452ae150435SJeff Kirsher }
1453ae150435SJeff Kirsher
1454ae150435SJeff Kirsher if ((smc->base != NULL) && /* Megahertz MFC's */
1455ae150435SJeff Kirsher (smc->manfid == MANFID_MEGAHERTZ) &&
1456ae150435SJeff Kirsher (smc->cardid == PRODID_MEGAHERTZ_EM3288)) {
1457ae150435SJeff Kirsher
1458ae150435SJeff Kirsher u_char tmp;
1459ae150435SJeff Kirsher tmp = readb(smc->base+MEGAHERTZ_ISR);
1460ae150435SJeff Kirsher tmp = readb(smc->base+MEGAHERTZ_ISR);
1461ae150435SJeff Kirsher
1462ae150435SJeff Kirsher /* Retrigger interrupt if needed */
1463ae150435SJeff Kirsher writeb(tmp, smc->base + MEGAHERTZ_ISR);
1464ae150435SJeff Kirsher writeb(tmp, smc->base + MEGAHERTZ_ISR);
1465ae150435SJeff Kirsher }
1466ae150435SJeff Kirsher
1467ae150435SJeff Kirsher spin_unlock(&smc->lock);
1468ae150435SJeff Kirsher return IRQ_RETVAL(handled);
1469ae150435SJeff Kirsher }
1470ae150435SJeff Kirsher
1471ae150435SJeff Kirsher /*====================================================================*/
1472ae150435SJeff Kirsher
smc_rx(struct net_device * dev)1473ae150435SJeff Kirsher static void smc_rx(struct net_device *dev)
1474ae150435SJeff Kirsher {
1475ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1476ae150435SJeff Kirsher int rx_status;
1477ae150435SJeff Kirsher int packet_length; /* Caution: not frame length, rather words
1478ae150435SJeff Kirsher to transfer from the chip. */
1479ae150435SJeff Kirsher
1480ae150435SJeff Kirsher /* Assertion: we are in Window 2. */
1481ae150435SJeff Kirsher
1482ae150435SJeff Kirsher if (inw(ioaddr + FIFO_PORTS) & FP_RXEMPTY) {
1483ae150435SJeff Kirsher netdev_err(dev, "smc_rx() with nothing on Rx FIFO\n");
1484ae150435SJeff Kirsher return;
1485ae150435SJeff Kirsher }
1486ae150435SJeff Kirsher
1487ae150435SJeff Kirsher /* Reset the read pointer, and read the status and packet length. */
1488ae150435SJeff Kirsher outw(PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + POINTER);
1489ae150435SJeff Kirsher rx_status = inw(ioaddr + DATA_1);
1490ae150435SJeff Kirsher packet_length = inw(ioaddr + DATA_1) & 0x07ff;
1491ae150435SJeff Kirsher
1492c501b1f5SBen Boeckel netdev_dbg(dev, "Receive status %4.4x length %d.\n",
1493c501b1f5SBen Boeckel rx_status, packet_length);
1494ae150435SJeff Kirsher
1495ae150435SJeff Kirsher if (!(rx_status & RS_ERRORS)) {
1496ae150435SJeff Kirsher /* do stuff to make a new packet */
1497ae150435SJeff Kirsher struct sk_buff *skb;
14984a7c9726STobias Klauser struct smc_private *smc = netdev_priv(dev);
1499ae150435SJeff Kirsher
1500ae150435SJeff Kirsher /* Note: packet_length adds 5 or 6 extra bytes here! */
1501dae2e9f4SPradeep A. Dalvi skb = netdev_alloc_skb(dev, packet_length+2);
1502ae150435SJeff Kirsher
1503ae150435SJeff Kirsher if (skb == NULL) {
1504c501b1f5SBen Boeckel netdev_dbg(dev, "Low memory, packet dropped.\n");
1505ae150435SJeff Kirsher dev->stats.rx_dropped++;
1506ae150435SJeff Kirsher outw(MC_RELEASE, ioaddr + MMU_CMD);
1507ae150435SJeff Kirsher return;
1508ae150435SJeff Kirsher }
1509ae150435SJeff Kirsher
1510ae150435SJeff Kirsher packet_length -= (rx_status & RS_ODDFRAME ? 5 : 6);
1511ae150435SJeff Kirsher skb_reserve(skb, 2);
1512ae150435SJeff Kirsher insw(ioaddr+DATA_1, skb_put(skb, packet_length),
1513ae150435SJeff Kirsher (packet_length+1)>>1);
1514ae150435SJeff Kirsher skb->protocol = eth_type_trans(skb, dev);
1515ae150435SJeff Kirsher
1516ae150435SJeff Kirsher netif_rx(skb);
15174a7c9726STobias Klauser smc->last_rx = jiffies;
1518ae150435SJeff Kirsher dev->stats.rx_packets++;
1519ae150435SJeff Kirsher dev->stats.rx_bytes += packet_length;
1520ae150435SJeff Kirsher if (rx_status & RS_MULTICAST)
1521ae150435SJeff Kirsher dev->stats.multicast++;
1522ae150435SJeff Kirsher } else {
1523ae150435SJeff Kirsher /* error ... */
1524ae150435SJeff Kirsher dev->stats.rx_errors++;
1525ae150435SJeff Kirsher
1526ae150435SJeff Kirsher if (rx_status & RS_ALGNERR) dev->stats.rx_frame_errors++;
1527ae150435SJeff Kirsher if (rx_status & (RS_TOOSHORT | RS_TOOLONG))
1528ae150435SJeff Kirsher dev->stats.rx_length_errors++;
1529ae150435SJeff Kirsher if (rx_status & RS_BADCRC) dev->stats.rx_crc_errors++;
1530ae150435SJeff Kirsher }
1531ae150435SJeff Kirsher /* Let the MMU free the memory of this packet. */
1532ae150435SJeff Kirsher outw(MC_RELEASE, ioaddr + MMU_CMD);
1533ae150435SJeff Kirsher }
1534ae150435SJeff Kirsher
1535ae150435SJeff Kirsher /*======================================================================
1536ae150435SJeff Kirsher
1537ae150435SJeff Kirsher Set the receive mode.
1538ae150435SJeff Kirsher
1539ae150435SJeff Kirsher This routine is used by both the protocol level to notify us of
1540ae150435SJeff Kirsher promiscuous/multicast mode changes, and by the open/reset code to
1541ae150435SJeff Kirsher initialize the Rx registers. We always set the multicast list and
1542ae150435SJeff Kirsher leave the receiver running.
1543ae150435SJeff Kirsher
1544ae150435SJeff Kirsher ======================================================================*/
1545ae150435SJeff Kirsher
set_rx_mode(struct net_device * dev)1546ae150435SJeff Kirsher static void set_rx_mode(struct net_device *dev)
1547ae150435SJeff Kirsher {
1548ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1549ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1550ae150435SJeff Kirsher unsigned char multicast_table[8];
1551ae150435SJeff Kirsher unsigned long flags;
1552ae150435SJeff Kirsher u_short rx_cfg_setting;
1553ae150435SJeff Kirsher int i;
1554ae150435SJeff Kirsher
1555ae150435SJeff Kirsher memset(multicast_table, 0, sizeof(multicast_table));
1556ae150435SJeff Kirsher
1557ae150435SJeff Kirsher if (dev->flags & IFF_PROMISC) {
1558ae150435SJeff Kirsher rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
1559ae150435SJeff Kirsher } else if (dev->flags & IFF_ALLMULTI)
1560ae150435SJeff Kirsher rx_cfg_setting = RxStripCRC | RxEnable | RxAllMulti;
1561ae150435SJeff Kirsher else {
1562ae150435SJeff Kirsher if (!netdev_mc_empty(dev)) {
1563ae150435SJeff Kirsher struct netdev_hw_addr *ha;
1564ae150435SJeff Kirsher
1565ae150435SJeff Kirsher netdev_for_each_mc_addr(ha, dev) {
1566ae150435SJeff Kirsher u_int position = ether_crc(6, ha->addr);
1567ae150435SJeff Kirsher multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
1568ae150435SJeff Kirsher }
1569ae150435SJeff Kirsher }
1570ae150435SJeff Kirsher rx_cfg_setting = RxStripCRC | RxEnable;
1571ae150435SJeff Kirsher }
1572ae150435SJeff Kirsher
1573ae150435SJeff Kirsher /* Load MC table and Rx setting into the chip without interrupts. */
1574ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
1575ae150435SJeff Kirsher SMC_SELECT_BANK(3);
1576ae150435SJeff Kirsher for (i = 0; i < 8; i++)
1577ae150435SJeff Kirsher outb(multicast_table[i], ioaddr + MULTICAST0 + i);
1578ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1579ae150435SJeff Kirsher outw(rx_cfg_setting, ioaddr + RCR);
1580ae150435SJeff Kirsher SMC_SELECT_BANK(2);
1581ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
1582ae150435SJeff Kirsher }
1583ae150435SJeff Kirsher
1584ae150435SJeff Kirsher /*======================================================================
1585ae150435SJeff Kirsher
1586ae150435SJeff Kirsher Senses when a card's config changes. Here, it's coax or TP.
1587ae150435SJeff Kirsher
1588ae150435SJeff Kirsher ======================================================================*/
1589ae150435SJeff Kirsher
s9k_config(struct net_device * dev,struct ifmap * map)1590ae150435SJeff Kirsher static int s9k_config(struct net_device *dev, struct ifmap *map)
1591ae150435SJeff Kirsher {
1592ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1593ae150435SJeff Kirsher if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
1594ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT)
1595ae150435SJeff Kirsher return -EOPNOTSUPP;
1596ae150435SJeff Kirsher else if (map->port > 2)
1597ae150435SJeff Kirsher return -EINVAL;
1598ae150435SJeff Kirsher dev->if_port = map->port;
1599ae150435SJeff Kirsher netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
1600ae150435SJeff Kirsher smc_reset(dev);
1601ae150435SJeff Kirsher }
1602ae150435SJeff Kirsher return 0;
1603ae150435SJeff Kirsher }
1604ae150435SJeff Kirsher
1605ae150435SJeff Kirsher /*======================================================================
1606ae150435SJeff Kirsher
1607ae150435SJeff Kirsher Reset the chip, reloading every register that might be corrupted.
1608ae150435SJeff Kirsher
1609ae150435SJeff Kirsher ======================================================================*/
1610ae150435SJeff Kirsher
1611ae150435SJeff Kirsher /*
1612ae150435SJeff Kirsher Set transceiver type, perhaps to something other than what the user
1613ae150435SJeff Kirsher specified in dev->if_port.
1614ae150435SJeff Kirsher */
smc_set_xcvr(struct net_device * dev,int if_port)1615ae150435SJeff Kirsher static void smc_set_xcvr(struct net_device *dev, int if_port)
1616ae150435SJeff Kirsher {
1617ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1618ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1619ae150435SJeff Kirsher u_short saved_bank;
1620ae150435SJeff Kirsher
1621ae150435SJeff Kirsher saved_bank = inw(ioaddr + BANK_SELECT);
1622ae150435SJeff Kirsher SMC_SELECT_BANK(1);
1623ae150435SJeff Kirsher if (if_port == 2) {
1624ae150435SJeff Kirsher outw(smc->cfg | CFG_AUI_SELECT, ioaddr + CONFIG);
1625ae150435SJeff Kirsher if ((smc->manfid == MANFID_OSITECH) &&
1626ae150435SJeff Kirsher (smc->cardid != PRODID_OSITECH_SEVEN))
1627ae150435SJeff Kirsher set_bits(OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR);
1628ae150435SJeff Kirsher smc->media_status = ((dev->if_port == 0) ? 0x0001 : 0x0002);
1629ae150435SJeff Kirsher } else {
1630ae150435SJeff Kirsher outw(smc->cfg, ioaddr + CONFIG);
1631ae150435SJeff Kirsher if ((smc->manfid == MANFID_OSITECH) &&
1632ae150435SJeff Kirsher (smc->cardid != PRODID_OSITECH_SEVEN))
1633ae150435SJeff Kirsher mask_bits(~OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR);
1634ae150435SJeff Kirsher smc->media_status = ((dev->if_port == 0) ? 0x0012 : 0x4001);
1635ae150435SJeff Kirsher }
1636ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1637ae150435SJeff Kirsher }
1638ae150435SJeff Kirsher
smc_reset(struct net_device * dev)1639ae150435SJeff Kirsher static void smc_reset(struct net_device *dev)
1640ae150435SJeff Kirsher {
1641ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1642ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1643ae150435SJeff Kirsher int i;
1644ae150435SJeff Kirsher
1645c501b1f5SBen Boeckel netdev_dbg(dev, "smc91c92 reset called.\n");
1646ae150435SJeff Kirsher
1647ae150435SJeff Kirsher /* The first interaction must be a write to bring the chip out
1648ae150435SJeff Kirsher of sleep mode. */
1649ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1650ae150435SJeff Kirsher /* Reset the chip. */
1651ae150435SJeff Kirsher outw(RCR_SOFTRESET, ioaddr + RCR);
1652ae150435SJeff Kirsher udelay(10);
1653ae150435SJeff Kirsher
1654ae150435SJeff Kirsher /* Clear the transmit and receive configuration registers. */
1655ae150435SJeff Kirsher outw(RCR_CLEAR, ioaddr + RCR);
1656ae150435SJeff Kirsher outw(TCR_CLEAR, ioaddr + TCR);
1657ae150435SJeff Kirsher
1658ae150435SJeff Kirsher /* Set the Window 1 control, configuration and station addr registers.
1659ae150435SJeff Kirsher No point in writing the I/O base register ;-> */
1660ae150435SJeff Kirsher SMC_SELECT_BANK(1);
1661ae150435SJeff Kirsher /* Automatically release successfully transmitted packets,
1662ae150435SJeff Kirsher Accept link errors, counter and Tx error interrupts. */
1663ae150435SJeff Kirsher outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE,
1664ae150435SJeff Kirsher ioaddr + CONTROL);
1665ae150435SJeff Kirsher smc_set_xcvr(dev, dev->if_port);
1666ae150435SJeff Kirsher if ((smc->manfid == MANFID_OSITECH) &&
1667ae150435SJeff Kirsher (smc->cardid != PRODID_OSITECH_SEVEN))
1668ae150435SJeff Kirsher outw((dev->if_port == 2 ? OSI_AUI_PWR : 0) |
1669ae150435SJeff Kirsher (inw(ioaddr-0x10+OSITECH_AUI_PWR) & 0xff00),
1670ae150435SJeff Kirsher ioaddr - 0x10 + OSITECH_AUI_PWR);
1671ae150435SJeff Kirsher
1672ae150435SJeff Kirsher /* Fill in the physical address. The databook is wrong about the order! */
1673ae150435SJeff Kirsher for (i = 0; i < 6; i += 2)
1674ae150435SJeff Kirsher outw((dev->dev_addr[i+1]<<8)+dev->dev_addr[i],
1675ae150435SJeff Kirsher ioaddr + ADDR0 + i);
1676ae150435SJeff Kirsher
1677ae150435SJeff Kirsher /* Reset the MMU */
1678ae150435SJeff Kirsher SMC_SELECT_BANK(2);
1679ae150435SJeff Kirsher outw(MC_RESET, ioaddr + MMU_CMD);
1680ae150435SJeff Kirsher outw(0, ioaddr + INTERRUPT);
1681ae150435SJeff Kirsher
1682ae150435SJeff Kirsher /* Re-enable the chip. */
1683ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1684ae150435SJeff Kirsher outw(((smc->cfg & CFG_MII_SELECT) ? 0 : TCR_MONCSN) |
1685ae150435SJeff Kirsher TCR_ENABLE | TCR_PAD_EN | smc->duplex, ioaddr + TCR);
1686ae150435SJeff Kirsher set_rx_mode(dev);
1687ae150435SJeff Kirsher
1688ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT) {
1689ae150435SJeff Kirsher SMC_SELECT_BANK(3);
1690ae150435SJeff Kirsher
1691ae150435SJeff Kirsher /* Reset MII */
1692ae150435SJeff Kirsher mdio_write(dev, smc->mii_if.phy_id, 0, 0x8000);
1693ae150435SJeff Kirsher
1694ae150435SJeff Kirsher /* Advertise 100F, 100H, 10F, 10H */
1695ae150435SJeff Kirsher mdio_write(dev, smc->mii_if.phy_id, 4, 0x01e1);
1696ae150435SJeff Kirsher
1697ae150435SJeff Kirsher /* Restart MII autonegotiation */
1698ae150435SJeff Kirsher mdio_write(dev, smc->mii_if.phy_id, 0, 0x0000);
1699ae150435SJeff Kirsher mdio_write(dev, smc->mii_if.phy_id, 0, 0x1200);
1700ae150435SJeff Kirsher }
1701ae150435SJeff Kirsher
1702ae150435SJeff Kirsher /* Enable interrupts. */
1703ae150435SJeff Kirsher SMC_SELECT_BANK(2);
1704ae150435SJeff Kirsher outw((IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT) << 8,
1705ae150435SJeff Kirsher ioaddr + INTERRUPT);
1706ae150435SJeff Kirsher }
1707ae150435SJeff Kirsher
1708ae150435SJeff Kirsher /*======================================================================
1709ae150435SJeff Kirsher
1710ae150435SJeff Kirsher Media selection timer routine
1711ae150435SJeff Kirsher
1712ae150435SJeff Kirsher ======================================================================*/
1713ae150435SJeff Kirsher
media_check(struct timer_list * t)1714267146d4SKees Cook static void media_check(struct timer_list *t)
1715ae150435SJeff Kirsher {
1716267146d4SKees Cook struct smc_private *smc = from_timer(smc, t, media);
1717267146d4SKees Cook struct net_device *dev = smc->mii_if.dev;
1718ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1719ae150435SJeff Kirsher u_short i, media, saved_bank;
1720ae150435SJeff Kirsher u_short link;
1721ae150435SJeff Kirsher unsigned long flags;
1722ae150435SJeff Kirsher
1723ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
1724ae150435SJeff Kirsher
1725ae150435SJeff Kirsher saved_bank = inw(ioaddr + BANK_SELECT);
1726ae150435SJeff Kirsher
1727ae150435SJeff Kirsher if (!netif_device_present(dev))
1728ae150435SJeff Kirsher goto reschedule;
1729ae150435SJeff Kirsher
1730ae150435SJeff Kirsher SMC_SELECT_BANK(2);
1731ae150435SJeff Kirsher
1732ae150435SJeff Kirsher /* need MC_RESET to keep the memory consistent. errata? */
1733ae150435SJeff Kirsher if (smc->rx_ovrn) {
1734ae150435SJeff Kirsher outw(MC_RESET, ioaddr + MMU_CMD);
1735ae150435SJeff Kirsher smc->rx_ovrn = 0;
1736ae150435SJeff Kirsher }
1737ae150435SJeff Kirsher i = inw(ioaddr + INTERRUPT);
1738ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1739ae150435SJeff Kirsher media = inw(ioaddr + EPH) & EPH_LINK_OK;
1740ae150435SJeff Kirsher SMC_SELECT_BANK(1);
1741ae150435SJeff Kirsher media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
1742ae150435SJeff Kirsher
1743ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1744ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
1745ae150435SJeff Kirsher
1746ae150435SJeff Kirsher /* Check for pending interrupt with watchdog flag set: with
1747ae150435SJeff Kirsher this, we can limp along even if the interrupt is blocked */
1748ae150435SJeff Kirsher if (smc->watchdog++ && ((i>>8) & i)) {
1749ae150435SJeff Kirsher if (!smc->fast_poll)
1750ae150435SJeff Kirsher netdev_info(dev, "interrupt(s) dropped!\n");
1751ae150435SJeff Kirsher local_irq_save(flags);
1752ae150435SJeff Kirsher smc_interrupt(dev->irq, dev);
1753ae150435SJeff Kirsher local_irq_restore(flags);
1754ae150435SJeff Kirsher smc->fast_poll = HZ;
1755ae150435SJeff Kirsher }
1756ae150435SJeff Kirsher if (smc->fast_poll) {
1757ae150435SJeff Kirsher smc->fast_poll--;
1758ae150435SJeff Kirsher smc->media.expires = jiffies + HZ/100;
1759ae150435SJeff Kirsher add_timer(&smc->media);
1760ae150435SJeff Kirsher return;
1761ae150435SJeff Kirsher }
1762ae150435SJeff Kirsher
1763ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
1764ae150435SJeff Kirsher
1765ae150435SJeff Kirsher saved_bank = inw(ioaddr + BANK_SELECT);
1766ae150435SJeff Kirsher
1767ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT) {
1768ae150435SJeff Kirsher if (smc->mii_if.phy_id < 0)
1769ae150435SJeff Kirsher goto reschedule;
1770ae150435SJeff Kirsher
1771ae150435SJeff Kirsher SMC_SELECT_BANK(3);
1772ae150435SJeff Kirsher link = mdio_read(dev, smc->mii_if.phy_id, 1);
1773ae150435SJeff Kirsher if (!link || (link == 0xffff)) {
1774ae150435SJeff Kirsher netdev_info(dev, "MII is missing!\n");
1775ae150435SJeff Kirsher smc->mii_if.phy_id = -1;
1776ae150435SJeff Kirsher goto reschedule;
1777ae150435SJeff Kirsher }
1778ae150435SJeff Kirsher
1779ae150435SJeff Kirsher link &= 0x0004;
1780ae150435SJeff Kirsher if (link != smc->link_status) {
1781ae150435SJeff Kirsher u_short p = mdio_read(dev, smc->mii_if.phy_id, 5);
1782ae150435SJeff Kirsher netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
1783ae150435SJeff Kirsher smc->duplex = (((p & 0x0100) || ((p & 0x1c0) == 0x40))
1784ae150435SJeff Kirsher ? TCR_FDUPLX : 0);
1785ae150435SJeff Kirsher if (link) {
1786ae150435SJeff Kirsher netdev_info(dev, "autonegotiation complete: "
1787ae150435SJeff Kirsher "%dbaseT-%cD selected\n",
1788ae150435SJeff Kirsher (p & 0x0180) ? 100 : 10, smc->duplex ? 'F' : 'H');
1789ae150435SJeff Kirsher }
1790ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1791ae150435SJeff Kirsher outw(inw(ioaddr + TCR) | smc->duplex, ioaddr + TCR);
1792ae150435SJeff Kirsher smc->link_status = link;
1793ae150435SJeff Kirsher }
1794ae150435SJeff Kirsher goto reschedule;
1795ae150435SJeff Kirsher }
1796ae150435SJeff Kirsher
1797ae150435SJeff Kirsher /* Ignore collisions unless we've had no rx's recently */
17984a7c9726STobias Klauser if (time_after(jiffies, smc->last_rx + HZ)) {
1799ae150435SJeff Kirsher if (smc->tx_err || (smc->media_status & EPH_16COL))
1800ae150435SJeff Kirsher media |= EPH_16COL;
1801ae150435SJeff Kirsher }
1802ae150435SJeff Kirsher smc->tx_err = 0;
1803ae150435SJeff Kirsher
1804ae150435SJeff Kirsher if (media != smc->media_status) {
1805ae150435SJeff Kirsher if ((media & smc->media_status & 1) &&
1806ae150435SJeff Kirsher ((smc->media_status ^ media) & EPH_LINK_OK))
1807ae150435SJeff Kirsher netdev_info(dev, "%s link beat\n",
1808ae150435SJeff Kirsher smc->media_status & EPH_LINK_OK ? "lost" : "found");
1809ae150435SJeff Kirsher else if ((media & smc->media_status & 2) &&
1810ae150435SJeff Kirsher ((smc->media_status ^ media) & EPH_16COL))
1811ae150435SJeff Kirsher netdev_info(dev, "coax cable %s\n",
1812ae150435SJeff Kirsher media & EPH_16COL ? "problem" : "ok");
1813ae150435SJeff Kirsher if (dev->if_port == 0) {
1814ae150435SJeff Kirsher if (media & 1) {
1815ae150435SJeff Kirsher if (media & EPH_LINK_OK)
1816ae150435SJeff Kirsher netdev_info(dev, "flipped to 10baseT\n");
1817ae150435SJeff Kirsher else
1818ae150435SJeff Kirsher smc_set_xcvr(dev, 2);
1819ae150435SJeff Kirsher } else {
1820ae150435SJeff Kirsher if (media & EPH_16COL)
1821ae150435SJeff Kirsher smc_set_xcvr(dev, 1);
1822ae150435SJeff Kirsher else
1823ae150435SJeff Kirsher netdev_info(dev, "flipped to 10base2\n");
1824ae150435SJeff Kirsher }
1825ae150435SJeff Kirsher }
1826ae150435SJeff Kirsher smc->media_status = media;
1827ae150435SJeff Kirsher }
1828ae150435SJeff Kirsher
1829ae150435SJeff Kirsher reschedule:
1830ae150435SJeff Kirsher smc->media.expires = jiffies + HZ;
1831ae150435SJeff Kirsher add_timer(&smc->media);
1832ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1833ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
1834ae150435SJeff Kirsher }
1835ae150435SJeff Kirsher
smc_link_ok(struct net_device * dev)1836ae150435SJeff Kirsher static int smc_link_ok(struct net_device *dev)
1837ae150435SJeff Kirsher {
1838ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1839ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1840ae150435SJeff Kirsher
1841ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT) {
1842ae150435SJeff Kirsher return mii_link_ok(&smc->mii_if);
1843ae150435SJeff Kirsher } else {
1844ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1845ae150435SJeff Kirsher return inw(ioaddr + EPH) & EPH_LINK_OK;
1846ae150435SJeff Kirsher }
1847ae150435SJeff Kirsher }
1848ae150435SJeff Kirsher
smc_netdev_get_ecmd(struct net_device * dev,struct ethtool_link_ksettings * ecmd)184982c01a84Syuval.shaia@oracle.com static void smc_netdev_get_ecmd(struct net_device *dev,
185088da73a3SPhilippe Reynes struct ethtool_link_ksettings *ecmd)
1851ae150435SJeff Kirsher {
1852ae150435SJeff Kirsher u16 tmp;
1853ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
185488da73a3SPhilippe Reynes u32 supported;
1855ae150435SJeff Kirsher
185688da73a3SPhilippe Reynes supported = (SUPPORTED_TP | SUPPORTED_AUI |
1857ae150435SJeff Kirsher SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full);
1858ae150435SJeff Kirsher
1859ae150435SJeff Kirsher SMC_SELECT_BANK(1);
1860ae150435SJeff Kirsher tmp = inw(ioaddr + CONFIG);
186188da73a3SPhilippe Reynes ecmd->base.port = (tmp & CFG_AUI_SELECT) ? PORT_AUI : PORT_TP;
186288da73a3SPhilippe Reynes ecmd->base.speed = SPEED_10;
186388da73a3SPhilippe Reynes ecmd->base.phy_address = ioaddr + MGMT;
1864ae150435SJeff Kirsher
1865ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1866ae150435SJeff Kirsher tmp = inw(ioaddr + TCR);
186788da73a3SPhilippe Reynes ecmd->base.duplex = (tmp & TCR_FDUPLX) ? DUPLEX_FULL : DUPLEX_HALF;
186888da73a3SPhilippe Reynes
186988da73a3SPhilippe Reynes ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
187088da73a3SPhilippe Reynes supported);
1871ae150435SJeff Kirsher }
1872ae150435SJeff Kirsher
smc_netdev_set_ecmd(struct net_device * dev,const struct ethtool_link_ksettings * ecmd)187388da73a3SPhilippe Reynes static int smc_netdev_set_ecmd(struct net_device *dev,
187488da73a3SPhilippe Reynes const struct ethtool_link_ksettings *ecmd)
1875ae150435SJeff Kirsher {
1876ae150435SJeff Kirsher u16 tmp;
1877ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1878ae150435SJeff Kirsher
187988da73a3SPhilippe Reynes if (ecmd->base.speed != SPEED_10)
1880ae150435SJeff Kirsher return -EINVAL;
188188da73a3SPhilippe Reynes if (ecmd->base.duplex != DUPLEX_HALF &&
188288da73a3SPhilippe Reynes ecmd->base.duplex != DUPLEX_FULL)
1883ae150435SJeff Kirsher return -EINVAL;
188488da73a3SPhilippe Reynes if (ecmd->base.port != PORT_TP && ecmd->base.port != PORT_AUI)
1885ae150435SJeff Kirsher return -EINVAL;
1886ae150435SJeff Kirsher
188788da73a3SPhilippe Reynes if (ecmd->base.port == PORT_AUI)
1888ae150435SJeff Kirsher smc_set_xcvr(dev, 1);
1889ae150435SJeff Kirsher else
1890ae150435SJeff Kirsher smc_set_xcvr(dev, 0);
1891ae150435SJeff Kirsher
1892ae150435SJeff Kirsher SMC_SELECT_BANK(0);
1893ae150435SJeff Kirsher tmp = inw(ioaddr + TCR);
189488da73a3SPhilippe Reynes if (ecmd->base.duplex == DUPLEX_FULL)
1895ae150435SJeff Kirsher tmp |= TCR_FDUPLX;
1896ae150435SJeff Kirsher else
1897ae150435SJeff Kirsher tmp &= ~TCR_FDUPLX;
1898ae150435SJeff Kirsher outw(tmp, ioaddr + TCR);
1899ae150435SJeff Kirsher
1900ae150435SJeff Kirsher return 0;
1901ae150435SJeff Kirsher }
1902ae150435SJeff Kirsher
check_if_running(struct net_device * dev)1903ae150435SJeff Kirsher static int check_if_running(struct net_device *dev)
1904ae150435SJeff Kirsher {
1905ae150435SJeff Kirsher if (!netif_running(dev))
1906ae150435SJeff Kirsher return -EINVAL;
1907ae150435SJeff Kirsher return 0;
1908ae150435SJeff Kirsher }
1909ae150435SJeff Kirsher
smc_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * info)1910ae150435SJeff Kirsher static void smc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1911ae150435SJeff Kirsher {
1912*f029c781SWolfram Sang strscpy(info->driver, DRV_NAME, sizeof(info->driver));
1913*f029c781SWolfram Sang strscpy(info->version, DRV_VERSION, sizeof(info->version));
1914ae150435SJeff Kirsher }
1915ae150435SJeff Kirsher
smc_get_link_ksettings(struct net_device * dev,struct ethtool_link_ksettings * ecmd)191688da73a3SPhilippe Reynes static int smc_get_link_ksettings(struct net_device *dev,
191788da73a3SPhilippe Reynes struct ethtool_link_ksettings *ecmd)
1918ae150435SJeff Kirsher {
1919ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1920ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1921ae150435SJeff Kirsher u16 saved_bank = inw(ioaddr + BANK_SELECT);
1922ae150435SJeff Kirsher unsigned long flags;
1923ae150435SJeff Kirsher
1924ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
1925ae150435SJeff Kirsher SMC_SELECT_BANK(3);
1926ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT)
192782c01a84Syuval.shaia@oracle.com mii_ethtool_get_link_ksettings(&smc->mii_if, ecmd);
1928ae150435SJeff Kirsher else
192982c01a84Syuval.shaia@oracle.com smc_netdev_get_ecmd(dev, ecmd);
1930ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1931ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
193282c01a84Syuval.shaia@oracle.com return 0;
1933ae150435SJeff Kirsher }
1934ae150435SJeff Kirsher
smc_set_link_ksettings(struct net_device * dev,const struct ethtool_link_ksettings * ecmd)193588da73a3SPhilippe Reynes static int smc_set_link_ksettings(struct net_device *dev,
193688da73a3SPhilippe Reynes const struct ethtool_link_ksettings *ecmd)
1937ae150435SJeff Kirsher {
1938ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1939ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1940ae150435SJeff Kirsher u16 saved_bank = inw(ioaddr + BANK_SELECT);
1941ae150435SJeff Kirsher int ret;
1942ae150435SJeff Kirsher unsigned long flags;
1943ae150435SJeff Kirsher
1944ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
1945ae150435SJeff Kirsher SMC_SELECT_BANK(3);
1946ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT)
194788da73a3SPhilippe Reynes ret = mii_ethtool_set_link_ksettings(&smc->mii_if, ecmd);
1948ae150435SJeff Kirsher else
1949ae150435SJeff Kirsher ret = smc_netdev_set_ecmd(dev, ecmd);
1950ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1951ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
1952ae150435SJeff Kirsher return ret;
1953ae150435SJeff Kirsher }
1954ae150435SJeff Kirsher
smc_get_link(struct net_device * dev)1955ae150435SJeff Kirsher static u32 smc_get_link(struct net_device *dev)
1956ae150435SJeff Kirsher {
1957ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1958ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1959ae150435SJeff Kirsher u16 saved_bank = inw(ioaddr + BANK_SELECT);
1960ae150435SJeff Kirsher u32 ret;
1961ae150435SJeff Kirsher unsigned long flags;
1962ae150435SJeff Kirsher
1963ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
1964ae150435SJeff Kirsher SMC_SELECT_BANK(3);
1965ae150435SJeff Kirsher ret = smc_link_ok(dev);
1966ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1967ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
1968ae150435SJeff Kirsher return ret;
1969ae150435SJeff Kirsher }
1970ae150435SJeff Kirsher
smc_nway_reset(struct net_device * dev)1971ae150435SJeff Kirsher static int smc_nway_reset(struct net_device *dev)
1972ae150435SJeff Kirsher {
1973ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
1974ae150435SJeff Kirsher if (smc->cfg & CFG_MII_SELECT) {
1975ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
1976ae150435SJeff Kirsher u16 saved_bank = inw(ioaddr + BANK_SELECT);
1977ae150435SJeff Kirsher int res;
1978ae150435SJeff Kirsher
1979ae150435SJeff Kirsher SMC_SELECT_BANK(3);
1980ae150435SJeff Kirsher res = mii_nway_restart(&smc->mii_if);
1981ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
1982ae150435SJeff Kirsher
1983ae150435SJeff Kirsher return res;
1984ae150435SJeff Kirsher } else
1985ae150435SJeff Kirsher return -EOPNOTSUPP;
1986ae150435SJeff Kirsher }
1987ae150435SJeff Kirsher
1988ae150435SJeff Kirsher static const struct ethtool_ops ethtool_ops = {
1989ae150435SJeff Kirsher .begin = check_if_running,
1990ae150435SJeff Kirsher .get_drvinfo = smc_get_drvinfo,
1991ae150435SJeff Kirsher .get_link = smc_get_link,
1992ae150435SJeff Kirsher .nway_reset = smc_nway_reset,
199388da73a3SPhilippe Reynes .get_link_ksettings = smc_get_link_ksettings,
199488da73a3SPhilippe Reynes .set_link_ksettings = smc_set_link_ksettings,
1995ae150435SJeff Kirsher };
1996ae150435SJeff Kirsher
smc_ioctl(struct net_device * dev,struct ifreq * rq,int cmd)1997ae150435SJeff Kirsher static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1998ae150435SJeff Kirsher {
1999ae150435SJeff Kirsher struct smc_private *smc = netdev_priv(dev);
2000ae150435SJeff Kirsher struct mii_ioctl_data *mii = if_mii(rq);
2001ae150435SJeff Kirsher int rc = 0;
2002ae150435SJeff Kirsher u16 saved_bank;
2003ae150435SJeff Kirsher unsigned int ioaddr = dev->base_addr;
2004ae150435SJeff Kirsher unsigned long flags;
2005ae150435SJeff Kirsher
2006ae150435SJeff Kirsher if (!netif_running(dev))
2007ae150435SJeff Kirsher return -EINVAL;
2008ae150435SJeff Kirsher
2009ae150435SJeff Kirsher spin_lock_irqsave(&smc->lock, flags);
2010ae150435SJeff Kirsher saved_bank = inw(ioaddr + BANK_SELECT);
2011ae150435SJeff Kirsher SMC_SELECT_BANK(3);
2012ae150435SJeff Kirsher rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL);
2013ae150435SJeff Kirsher SMC_SELECT_BANK(saved_bank);
2014ae150435SJeff Kirsher spin_unlock_irqrestore(&smc->lock, flags);
2015ae150435SJeff Kirsher return rc;
2016ae150435SJeff Kirsher }
2017ae150435SJeff Kirsher
2018ae150435SJeff Kirsher static const struct pcmcia_device_id smc91c92_ids[] = {
2019ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0109, 0x0501),
2020ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0140, 0x000a),
2021ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
2022ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
2023ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
2024ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
2025ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID12(0, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
2026ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID12(0, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
2027ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
2028ae150435SJeff Kirsher PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
2029ae150435SJeff Kirsher PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x016c, 0x0020),
2030ae150435SJeff Kirsher PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0023),
2031ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID123("BASICS by New Media Corporation", "Ethernet", "SMC91C94", 0x23c78a9d, 0x00b2e941, 0xcef397fb),
2032ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("ARGOSY", "Fast Ethernet PCCard", 0x78f308dc, 0xdcea68bc),
2033ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("dit Co., Ltd.", "PC Card-10/100BTX", 0xe59365c8, 0x6a2161d1),
2034ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L100C", 0x6a26d1cf, 0xc16ce9c5),
2035ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("Farallon", "Farallon Enet", 0x58d93fc4, 0x244734e9),
2036ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("Megahertz", "CC10BT/2", 0x33234748, 0x3c95b953),
2037ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("MELCO/SMC", "LPC-TX", 0xa2cd8e6d, 0x42da662a),
2038ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Four of Diamonds Ethernet", 0xc2f80cd, 0xb3466314),
2039ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Seven of Diamonds Ethernet", 0xc2f80cd, 0x194b650a),
2040ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast Ethernet PCCard", 0x281f1c5d, 0xdcea68bc),
2041ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("Psion", "10Mb Ethernet", 0x4ef00b21, 0x844be9e9),
2042ae150435SJeff Kirsher PCMCIA_DEVICE_PROD_ID12("SMC", "EtherEZ Ethernet 8020", 0xc4f8b18b, 0x4a0eeb2d),
2043ae150435SJeff Kirsher /* These conflict with other cards! */
2044ae150435SJeff Kirsher /* PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0100), */
2045ae150435SJeff Kirsher /* PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), */
2046ae150435SJeff Kirsher PCMCIA_DEVICE_NULL,
2047ae150435SJeff Kirsher };
2048ae150435SJeff Kirsher MODULE_DEVICE_TABLE(pcmcia, smc91c92_ids);
2049ae150435SJeff Kirsher
2050ae150435SJeff Kirsher static struct pcmcia_driver smc91c92_cs_driver = {
2051ae150435SJeff Kirsher .owner = THIS_MODULE,
2052ae150435SJeff Kirsher .name = "smc91c92_cs",
2053ae150435SJeff Kirsher .probe = smc91c92_probe,
2054ae150435SJeff Kirsher .remove = smc91c92_detach,
2055ae150435SJeff Kirsher .id_table = smc91c92_ids,
2056ae150435SJeff Kirsher .suspend = smc91c92_suspend,
2057ae150435SJeff Kirsher .resume = smc91c92_resume,
2058ae150435SJeff Kirsher };
2059fdd3f29eSH Hartley Sweeten module_pcmcia_driver(smc91c92_cs_driver);
2060