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