tlan.c 85.7 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*******************************************************************************
 *
 *  Linux ThunderLAN Driver
 *
 *  tlan.c
 *  by James Banks
 *
 *  (C) 1997-1998 Caldera, Inc.
 *  (C) 1998 James Banks
 *  (C) 1999-2001 Torben Mathiasen
 *  (C) 2002 Samuel Chessman
 *
 *  This software may be used and distributed according to the terms
 *  of the GNU General Public License, incorporated herein by reference.
 *
 ** Useful (if not required) reading:
 *
 *		Texas Instruments, ThunderLAN Programmer's Guide,
 *			TI Literature Number SPWU013A
 *			available in PDF format from www.ti.com
 *		Level One, LXT901 and LXT970 Data Sheets
 *			available in PDF format from www.level1.com
 *		National Semiconductor, DP83840A Data Sheet
 *			available in PDF format from www.national.com
 *		Microchip Technology, 24C01A/02A/04A Data Sheet
 *			available in PDF format from www.microchip.com
 *
28
 ******************************************************************************/
Linus Torvalds's avatar
Linus Torvalds committed
29

30
31
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

32
#include <linux/hardirq.h>
Linus Torvalds's avatar
Linus Torvalds committed
33
34
#include <linux/module.h>
#include <linux/init.h>
35
#include <linux/interrupt.h>
Linus Torvalds's avatar
Linus Torvalds committed
36
37
38
#include <linux/ioport.h>
#include <linux/eisa.h>
#include <linux/pci.h>
39
#include <linux/dma-mapping.h>
Linus Torvalds's avatar
Linus Torvalds committed
40
41
42
43
44
45
46
47
48
49
50
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/mii.h>

#include "tlan.h"


/* For removing EISA devices */
51
static	struct net_device	*tlan_eisa_devices;
Linus Torvalds's avatar
Linus Torvalds committed
52

53
static	int		tlan_devices_installed;
Linus Torvalds's avatar
Linus Torvalds committed
54
55
56
57
58
59

/* Set speed, duplex and aui settings */
static  int aui[MAX_TLAN_BOARDS];
static  int duplex[MAX_TLAN_BOARDS];
static  int speed[MAX_TLAN_BOARDS];
static  int boards_found;
60
61
62
63
module_param_array(aui, int, NULL, 0);
module_param_array(duplex, int, NULL, 0);
module_param_array(speed, int, NULL, 0);
MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
64
65
MODULE_PARM_DESC(duplex,
		 "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
66
MODULE_PARM_DESC(speed, "ThunderLAN port speed setting(s) (0,10,100)");
Linus Torvalds's avatar
Linus Torvalds committed
67
68
69
70
71

MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
MODULE_LICENSE("GPL");

72
73
74
/* Turn on debugging.
 * See Documentation/networking/device_drivers/ti/tlan.txt for details
 */
Linus Torvalds's avatar
Linus Torvalds committed
75
static  int		debug;
76
77
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
Linus Torvalds's avatar
Linus Torvalds committed
78

79
static	const char tlan_signature[] = "TLAN";
80
static  const char tlan_banner[] = "ThunderLAN driver v1.17\n";
Linus Torvalds's avatar
Linus Torvalds committed
81
82
83
static  int tlan_have_pci;
static  int tlan_have_eisa;

84
85
86
static const char * const media[] = {
	"10BaseT-HD", "10BaseT-FD", "100baseTx-HD",
	"100BaseTx-FD", "100BaseT4", NULL
Linus Torvalds's avatar
Linus Torvalds committed
87
88
89
};

static struct board {
90
91
92
	const char	*device_label;
	u32		flags;
	u16		addr_ofs;
Linus Torvalds's avatar
Linus Torvalds committed
93
94
} board_info[] = {
	{ "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
95
96
	{ "Compaq Netelligent 10/100 TX PCI UTP",
	  TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Linus Torvalds's avatar
Linus Torvalds committed
97
	{ "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemminger's avatar
Stephen Hemminger committed
98
99
	{ "Compaq NetFlex-3/P",
	  TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Linus Torvalds's avatar
Linus Torvalds committed
100
	{ "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemminger's avatar
Stephen Hemminger committed
101
102
	{ "Compaq Netelligent Integrated 10/100 TX UTP",
	  TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
103
104
105
106
	{ "Compaq Netelligent Dual 10/100 TX PCI UTP",
	  TLAN_ADAPTER_NONE, 0x83 },
	{ "Compaq Netelligent 10/100 TX Embedded UTP",
	  TLAN_ADAPTER_NONE, 0x83 },
Linus Torvalds's avatar
Linus Torvalds committed
107
	{ "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
108
109
110
111
	{ "Olicom OC-2325", TLAN_ADAPTER_ACTIVITY_LED |
	  TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
	{ "Olicom OC-2326", TLAN_ADAPTER_ACTIVITY_LED |
	  TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
Linus Torvalds's avatar
Linus Torvalds committed
112
	{ "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
113
	{ "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemminger's avatar
Stephen Hemminger committed
114
	{ "Compaq NetFlex-3/E",
115
	  TLAN_ADAPTER_ACTIVITY_LED |	/* EISA card */
Stephen Hemminger's avatar
Stephen Hemminger committed
116
	  TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
117
118
	{ "Compaq NetFlex-3/E",
	  TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
Linus Torvalds's avatar
Linus Torvalds committed
119
120
};

121
static const struct pci_device_id tlan_pci_tbl[] = {
Linus Torvalds's avatar
Linus Torvalds committed
122
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
123
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
Linus Torvalds's avatar
Linus Torvalds committed
124
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
125
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
Linus Torvalds's avatar
Linus Torvalds committed
126
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
127
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
Linus Torvalds's avatar
Linus Torvalds committed
128
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
129
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
Linus Torvalds's avatar
Linus Torvalds committed
130
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
131
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
Linus Torvalds's avatar
Linus Torvalds committed
132
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
133
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
Linus Torvalds's avatar
Linus Torvalds committed
134
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
135
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
Linus Torvalds's avatar
Linus Torvalds committed
136
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
137
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
Linus Torvalds's avatar
Linus Torvalds committed
138
	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
139
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
Linus Torvalds's avatar
Linus Torvalds committed
140
	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
141
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
Linus Torvalds's avatar
Linus Torvalds committed
142
	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
143
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
Linus Torvalds's avatar
Linus Torvalds committed
144
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
145
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
Linus Torvalds's avatar
Linus Torvalds committed
146
	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
147
	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
Linus Torvalds's avatar
Linus Torvalds committed
148
149
	{ 0,}
};
150
MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
Linus Torvalds's avatar
Linus Torvalds committed
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
static void	tlan_eisa_probe(void);
static void	tlan_eisa_cleanup(void);
static int      tlan_init(struct net_device *);
static int	tlan_open(struct net_device *dev);
static netdev_tx_t tlan_start_tx(struct sk_buff *, struct net_device *);
static irqreturn_t tlan_handle_interrupt(int, void *);
static int	tlan_close(struct net_device *);
static struct	net_device_stats *tlan_get_stats(struct net_device *);
static void	tlan_set_multicast_list(struct net_device *);
static int	tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int      tlan_probe1(struct pci_dev *pdev, long ioaddr,
			    int irq, int rev, const struct pci_device_id *ent);
static void	tlan_tx_timeout(struct net_device *dev);
static void	tlan_tx_timeout_work(struct work_struct *work);
static int	tlan_init_one(struct pci_dev *pdev,
			      const struct pci_device_id *ent);

static u32	tlan_handle_tx_eof(struct net_device *, u16);
static u32	tlan_handle_stat_overflow(struct net_device *, u16);
static u32	tlan_handle_rx_eof(struct net_device *, u16);
static u32	tlan_handle_dummy(struct net_device *, u16);
static u32	tlan_handle_tx_eoc(struct net_device *, u16);
static u32	tlan_handle_status_check(struct net_device *, u16);
static u32	tlan_handle_rx_eoc(struct net_device *, u16);

177
178
static void	tlan_timer(struct timer_list *t);
static void	tlan_phy_monitor(struct timer_list *t);
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

static void	tlan_reset_lists(struct net_device *);
static void	tlan_free_lists(struct net_device *);
static void	tlan_print_dio(u16);
static void	tlan_print_list(struct tlan_list *, char *, int);
static void	tlan_read_and_clear_stats(struct net_device *, int);
static void	tlan_reset_adapter(struct net_device *);
static void	tlan_finish_reset(struct net_device *);
static void	tlan_set_mac(struct net_device *, int areg, char *mac);

static void	tlan_phy_print(struct net_device *);
static void	tlan_phy_detect(struct net_device *);
static void	tlan_phy_power_down(struct net_device *);
static void	tlan_phy_power_up(struct net_device *);
static void	tlan_phy_reset(struct net_device *);
static void	tlan_phy_start_link(struct net_device *);
static void	tlan_phy_finish_auto_neg(struct net_device *);
Linus Torvalds's avatar
Linus Torvalds committed
196
197

/*
198
199
200
201
  static int	tlan_phy_nop(struct net_device *);
  static int	tlan_phy_internal_check(struct net_device *);
  static int	tlan_phy_internal_service(struct net_device *);
  static int	tlan_phy_dp83840a_check(struct net_device *);
Linus Torvalds's avatar
Linus Torvalds committed
202
203
*/

204
205
206
207
static bool	tlan_mii_read_reg(struct net_device *, u16, u16, u16 *);
static void	tlan_mii_send_data(u16, u32, unsigned);
static void	tlan_mii_sync(u16);
static void	tlan_mii_write_reg(struct net_device *, u16, u16, u16);
Linus Torvalds's avatar
Linus Torvalds committed
208

209
210
211
212
static void	tlan_ee_send_start(u16);
static int	tlan_ee_send_byte(u16, u8, int);
static void	tlan_ee_receive_byte(u16, u8 *, int);
static int	tlan_ee_read_byte(struct net_device *, u8, u8 *);
Linus Torvalds's avatar
Linus Torvalds committed
213
214


Stephen Hemminger's avatar
Stephen Hemminger committed
215
static inline void
216
tlan_store_skb(struct tlan_list *tag, struct sk_buff *skb)
Linus Torvalds's avatar
Linus Torvalds committed
217
218
{
	unsigned long addr = (unsigned long)skb;
Stephen Hemminger's avatar
Stephen Hemminger committed
219
220
	tag->buffer[9].address = addr;
	tag->buffer[8].address = upper_32_bits(addr);
Linus Torvalds's avatar
Linus Torvalds committed
221
222
}

Stephen Hemminger's avatar
Stephen Hemminger committed
223
static inline struct sk_buff *
224
tlan_get_skb(const struct tlan_list *tag)
Linus Torvalds's avatar
Linus Torvalds committed
225
{
Stephen Hemminger's avatar
Stephen Hemminger committed
226
227
	unsigned long addr;

228
	addr = tag->buffer[9].address;
229
	addr |= ((unsigned long) tag->buffer[8].address << 16) << 16;
Linus Torvalds's avatar
Linus Torvalds committed
230
231
232
	return (struct sk_buff *) addr;
}

233
234
static u32
(*tlan_int_vector[TLAN_INT_NUMBER_OF_INTS])(struct net_device *, u16) = {
235
	NULL,
236
237
238
239
240
241
242
	tlan_handle_tx_eof,
	tlan_handle_stat_overflow,
	tlan_handle_rx_eof,
	tlan_handle_dummy,
	tlan_handle_tx_eoc,
	tlan_handle_status_check,
	tlan_handle_rx_eoc
Linus Torvalds's avatar
Linus Torvalds committed
243
244
245
};

static inline void
246
tlan_set_timer(struct net_device *dev, u32 ticks, u32 type)
Linus Torvalds's avatar
Linus Torvalds committed
247
{
248
	struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds's avatar
Linus Torvalds committed
249
	unsigned long flags = 0;
250

Linus Torvalds's avatar
Linus Torvalds committed
251
252
	if (!in_irq())
		spin_lock_irqsave(&priv->lock, flags);
253
254
	if (priv->timer.function != NULL &&
	    priv->timer_type != TLAN_TIMER_ACTIVITY) {
Linus Torvalds's avatar
Linus Torvalds committed
255
256
257
258
		if (!in_irq())
			spin_unlock_irqrestore(&priv->lock, flags);
		return;
	}
259
	priv->timer.function = tlan_timer;
Linus Torvalds's avatar
Linus Torvalds committed
260
261
262
	if (!in_irq())
		spin_unlock_irqrestore(&priv->lock, flags);

263
264
	priv->timer_set_at = jiffies;
	priv->timer_type = type;
Linus Torvalds's avatar
Linus Torvalds committed
265
	mod_timer(&priv->timer, jiffies + ticks);
266

267
}
Linus Torvalds's avatar
Linus Torvalds committed
268
269
270
271
272


/*****************************************************************************
******************************************************************************

273
ThunderLAN driver primary functions
Linus Torvalds's avatar
Linus Torvalds committed
274

275
these functions are more or less common to all linux network drivers.
Linus Torvalds's avatar
Linus Torvalds committed
276
277
278
279
280
281
282
283

******************************************************************************
*****************************************************************************/





284
285
286
287
288
289
290
291
292
293
294
295
296
297
/***************************************************************
 *	tlan_remove_one
 *
 *	Returns:
 *		Nothing
 *	Parms:
 *		None
 *
 *	Goes through the TLanDevices list and frees the device
 *	structs and memory associated with each device (lists
 *	and buffers).  It also ureserves the IO port regions
 *	associated with this device.
 *
 **************************************************************/
Linus Torvalds's avatar
Linus Torvalds committed
298
299


300
static void tlan_remove_one(struct pci_dev *pdev)
Linus Torvalds's avatar
Linus Torvalds committed
301
{
302
303
	struct net_device *dev = pci_get_drvdata(pdev);
	struct tlan_priv	*priv = netdev_priv(dev);
304

305
	unregister_netdev(dev);
Linus Torvalds's avatar
Linus Torvalds committed
306

307
308
309
310
	if (priv->dma_storage) {
		pci_free_consistent(priv->pci_dev,
				    priv->dma_size, priv->dma_storage,
				    priv->dma_storage_dma);
Linus Torvalds's avatar
Linus Torvalds committed
311
312
313
314
315
	}

#ifdef CONFIG_PCI
	pci_release_regions(pdev);
#endif
316

317
	free_netdev(dev);
318

319
	cancel_work_sync(&priv->tlan_tqueue);
320
}
Linus Torvalds's avatar
Linus Torvalds committed
321

322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
static void tlan_start(struct net_device *dev)
{
	tlan_reset_lists(dev);
	/* NOTE: It might not be necessary to read the stats before a
	   reset if you don't care what the values are.
	*/
	tlan_read_and_clear_stats(dev, TLAN_IGNORE);
	tlan_reset_adapter(dev);
	netif_wake_queue(dev);
}

static void tlan_stop(struct net_device *dev)
{
	struct tlan_priv *priv = netdev_priv(dev);

Ondrej Zary's avatar
Ondrej Zary committed
337
	del_timer_sync(&priv->media_timer);
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
	tlan_read_and_clear_stats(dev, TLAN_RECORD);
	outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
	/* Reset and power down phy */
	tlan_reset_adapter(dev);
	if (priv->timer.function != NULL) {
		del_timer_sync(&priv->timer);
		priv->timer.function = NULL;
	}
}

#ifdef CONFIG_PM

static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct net_device *dev = pci_get_drvdata(pdev);

	if (netif_running(dev))
		tlan_stop(dev);

	netif_device_detach(dev);
	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_wake_from_d3(pdev, false);
	pci_set_power_state(pdev, PCI_D3hot);

	return 0;
}

static int tlan_resume(struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata(pdev);
Ondrej Zary's avatar
Ondrej Zary committed
369
	int rc = pci_enable_device(pdev);
370

Ondrej Zary's avatar
Ondrej Zary committed
371
372
	if (rc)
		return rc;
373
	pci_restore_state(pdev);
374
	pci_enable_wake(pdev, PCI_D0, 0);
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
	netif_device_attach(dev);

	if (netif_running(dev))
		tlan_start(dev);

	return 0;
}

#else /* CONFIG_PM */

#define tlan_suspend   NULL
#define tlan_resume    NULL

#endif /* CONFIG_PM */


Linus Torvalds's avatar
Linus Torvalds committed
391
392
393
394
static struct pci_driver tlan_driver = {
	.name		= "tlan",
	.id_table	= tlan_pci_tbl,
	.probe		= tlan_init_one,
395
	.remove		= tlan_remove_one,
396
397
	.suspend	= tlan_suspend,
	.resume		= tlan_resume,
Linus Torvalds's avatar
Linus Torvalds committed
398
399
400
401
};

static int __init tlan_probe(void)
{
402
	int rc = -ENODEV;
403

404
	pr_info("%s", tlan_banner);
405

Linus Torvalds's avatar
Linus Torvalds committed
406
	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
407

Linus Torvalds's avatar
Linus Torvalds committed
408
409
	/* Use new style PCI probing. Now the kernel will
	   do most of this for us */
410
411
412
	rc = pci_register_driver(&tlan_driver);

	if (rc != 0) {
413
		pr_err("Could not register pci driver\n");
414
415
		goto err_out_pci_free;
	}
Linus Torvalds's avatar
Linus Torvalds committed
416
417

	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
418
	tlan_eisa_probe();
419

420
421
422
	pr_info("%d device%s installed, PCI: %d  EISA: %d\n",
		tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s",
		tlan_have_pci, tlan_have_eisa);
Linus Torvalds's avatar
Linus Torvalds committed
423

424
	if (tlan_devices_installed == 0) {
425
426
		rc = -ENODEV;
		goto  err_out_pci_unreg;
Linus Torvalds's avatar
Linus Torvalds committed
427
428
	}
	return 0;
429
430
431
432
433

err_out_pci_unreg:
	pci_unregister_driver(&tlan_driver);
err_out_pci_free:
	return rc;
Linus Torvalds's avatar
Linus Torvalds committed
434
}
435

Linus Torvalds's avatar
Linus Torvalds committed
436

437
static int tlan_init_one(struct pci_dev *pdev,
438
				   const struct pci_device_id *ent)
Linus Torvalds's avatar
Linus Torvalds committed
439
{
440
	return tlan_probe1(pdev, -1, -1, 0, ent);
Linus Torvalds's avatar
Linus Torvalds committed
441
442
443
444
}


/*
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
***************************************************************
*	tlan_probe1
*
*	Returns:
*		0 on success, error code on error
*	Parms:
*		none
*
*	The name is lower case to fit in with all the rest of
*	the netcard_probe names.  This function looks for
*	another TLan based adapter, setting it up with the
*	allocated device struct if one is found.
*	tlan_probe has been ported to the new net API and
*	now allocates its own device structure. This function
*	is also used by modules.
*
**************************************************************/

463
464
static int tlan_probe1(struct pci_dev *pdev, long ioaddr, int irq, int rev,
		       const struct pci_device_id *ent)
Linus Torvalds's avatar
Linus Torvalds committed
465
466
467
{

	struct net_device  *dev;
468
	struct tlan_priv  *priv;
Linus Torvalds's avatar
Linus Torvalds committed
469
470
471
	u16		   device_id;
	int		   reg, rc = -ENODEV;

472
#ifdef CONFIG_PCI
Linus Torvalds's avatar
Linus Torvalds committed
473
474
475
476
477
	if (pdev) {
		rc = pci_enable_device(pdev);
		if (rc)
			return rc;

478
		rc = pci_request_regions(pdev, tlan_signature);
Linus Torvalds's avatar
Linus Torvalds committed
479
		if (rc) {
480
			pr_err("Could not reserve IO regions\n");
Linus Torvalds's avatar
Linus Torvalds committed
481
482
483
			goto err_out;
		}
	}
484
#endif  /*  CONFIG_PCI  */
Linus Torvalds's avatar
Linus Torvalds committed
485

486
	dev = alloc_etherdev(sizeof(struct tlan_priv));
Linus Torvalds's avatar
Linus Torvalds committed
487
488
489
490
491
	if (dev == NULL) {
		rc = -ENOMEM;
		goto err_out_regions;
	}
	SET_NETDEV_DEV(dev, &pdev->dev);
492

Linus Torvalds's avatar
Linus Torvalds committed
493
494
	priv = netdev_priv(dev);

495
	priv->pci_dev = pdev;
David Howells's avatar
David Howells committed
496
	priv->dev = dev;
497

Linus Torvalds's avatar
Linus Torvalds committed
498
499
	/* Is this a PCI device? */
	if (pdev) {
500
		u32		   pci_io_base = 0;
Linus Torvalds's avatar
Linus Torvalds committed
501
502
503

		priv->adapter = &board_info[ent->driver_data];

504
		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds's avatar
Linus Torvalds committed
505
		if (rc) {
506
			pr_err("No suitable PCI mapping available\n");
Linus Torvalds's avatar
Linus Torvalds committed
507
508
509
			goto err_out_free_dev;
		}

510
		for (reg = 0; reg <= 5; reg++) {
Linus Torvalds's avatar
Linus Torvalds committed
511
512
			if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
				pci_io_base = pci_resource_start(pdev, reg);
513
514
515
				TLAN_DBG(TLAN_DEBUG_GNRL,
					 "IO mapping is available at %x.\n",
					 pci_io_base);
Linus Torvalds's avatar
Linus Torvalds committed
516
517
518
519
				break;
			}
		}
		if (!pci_io_base) {
520
			pr_err("No IO mappings available\n");
Linus Torvalds's avatar
Linus Torvalds committed
521
522
523
			rc = -EIO;
			goto err_out_free_dev;
		}
524

Linus Torvalds's avatar
Linus Torvalds committed
525
526
		dev->base_addr = pci_io_base;
		dev->irq = pdev->irq;
527
		priv->adapter_rev = pdev->revision;
Linus Torvalds's avatar
Linus Torvalds committed
528
529
530
531
532
533
534
535
		pci_set_master(pdev);
		pci_set_drvdata(pdev, dev);

	} else	{     /* EISA card */
		/* This is a hack. We need to know which board structure
		 * is suited for this adapter */
		device_id = inw(ioaddr + EISA_ID2);
		if (device_id == 0x20F1) {
536
537
			priv->adapter = &board_info[13]; /* NetFlex-3/E */
			priv->adapter_rev = 23;		/* TLAN 2.3 */
Linus Torvalds's avatar
Linus Torvalds committed
538
539
		} else {
			priv->adapter = &board_info[14];
540
			priv->adapter_rev = 10;		/* TLAN 1.0 */
Linus Torvalds's avatar
Linus Torvalds committed
541
542
543
544
545
546
547
548
		}
		dev->base_addr = ioaddr;
		dev->irq = irq;
	}

	/* Kernel parameters */
	if (dev->mem_start) {
		priv->aui    = dev->mem_start & 0x01;
Stephen Hemminger's avatar
Stephen Hemminger committed
549
550
551
552
		priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
			: (dev->mem_start & 0x06) >> 1;
		priv->speed  = ((dev->mem_start & 0x18) == 0x18) ? 0
			: (dev->mem_start & 0x18) >> 3;
553

554
		if (priv->speed == 0x1)
Linus Torvalds's avatar
Linus Torvalds committed
555
			priv->speed = TLAN_SPEED_10;
556
		else if (priv->speed == 0x2)
Linus Torvalds's avatar
Linus Torvalds committed
557
			priv->speed = TLAN_SPEED_100;
558

Linus Torvalds's avatar
Linus Torvalds committed
559
560
561
562
563
564
565
		debug = priv->debug = dev->mem_end;
	} else {
		priv->aui    = aui[boards_found];
		priv->speed  = speed[boards_found];
		priv->duplex = duplex[boards_found];
		priv->debug = debug;
	}
566

Linus Torvalds's avatar
Linus Torvalds committed
567
568
	/* This will be used when we get an adapter error from
	 * within our irq handler */
569
	INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work);
Linus Torvalds's avatar
Linus Torvalds committed
570
571

	spin_lock_init(&priv->lock);
572

573
	rc = tlan_init(dev);
Linus Torvalds's avatar
Linus Torvalds committed
574
	if (rc) {
575
		pr_err("Could not set up device\n");
Linus Torvalds's avatar
Linus Torvalds committed
576
577
578
579
580
		goto err_out_free_dev;
	}

	rc = register_netdev(dev);
	if (rc) {
581
		pr_err("Could not register device\n");
Linus Torvalds's avatar
Linus Torvalds committed
582
583
584
		goto err_out_uninit;
	}

585

586
	tlan_devices_installed++;
Linus Torvalds's avatar
Linus Torvalds committed
587
	boards_found++;
588

Linus Torvalds's avatar
Linus Torvalds committed
589
590
591
592
	/* pdev is NULL if this is an EISA device */
	if (pdev)
		tlan_have_pci++;
	else {
593
594
		priv->next_device = tlan_eisa_devices;
		tlan_eisa_devices = dev;
Linus Torvalds's avatar
Linus Torvalds committed
595
596
		tlan_have_eisa++;
	}
597

598
599
600
601
602
	netdev_info(dev, "irq=%2d, io=%04x, %s, Rev. %d\n",
		    (int)dev->irq,
		    (int)dev->base_addr,
		    priv->adapter->device_label,
		    priv->adapter_rev);
Linus Torvalds's avatar
Linus Torvalds committed
603
604
605
	return 0;

err_out_uninit:
606
607
	pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage,
			    priv->dma_storage_dma);
Linus Torvalds's avatar
Linus Torvalds committed
608
609
610
611
612
613
614
err_out_free_dev:
	free_netdev(dev);
err_out_regions:
#ifdef CONFIG_PCI
	if (pdev)
		pci_release_regions(pdev);
err_out:
615
#endif
Linus Torvalds's avatar
Linus Torvalds committed
616
617
618
619
620
621
	if (pdev)
		pci_disable_device(pdev);
	return rc;
}


622
static void tlan_eisa_cleanup(void)
Linus Torvalds's avatar
Linus Torvalds committed
623
624
{
	struct net_device *dev;
625
	struct tlan_priv *priv;
626

627
628
	while (tlan_have_eisa) {
		dev = tlan_eisa_devices;
Linus Torvalds's avatar
Linus Torvalds committed
629
		priv = netdev_priv(dev);
630
631
632
633
		if (priv->dma_storage) {
			pci_free_consistent(priv->pci_dev, priv->dma_size,
					    priv->dma_storage,
					    priv->dma_storage_dma);
Linus Torvalds's avatar
Linus Torvalds committed
634
		}
635
636
637
638
		release_region(dev->base_addr, 0x10);
		unregister_netdev(dev);
		tlan_eisa_devices = priv->next_device;
		free_netdev(dev);
Linus Torvalds's avatar
Linus Torvalds committed
639
640
641
		tlan_have_eisa--;
	}
}
642
643


Linus Torvalds's avatar
Linus Torvalds committed
644
645
646
647
648
static void __exit tlan_exit(void)
{
	pci_unregister_driver(&tlan_driver);

	if (tlan_have_eisa)
649
		tlan_eisa_cleanup();
Linus Torvalds's avatar
Linus Torvalds committed
650
651
652
653
654
655
656
657
658
659

}


/* Module loading/unloading */
module_init(tlan_probe);
module_exit(tlan_exit);



660
661
662
663
664
665
666
667
668
669
670
671
/**************************************************************
 *	tlan_eisa_probe
 *
 *	Returns: 0 on success, 1 otherwise
 *
 *	Parms:	 None
 *
 *
 *	This functions probes for EISA devices and calls
 *	TLan_probe1 when one is found.
 *
 *************************************************************/
Linus Torvalds's avatar
Linus Torvalds committed
672

673
static void  __init tlan_eisa_probe(void)
Linus Torvalds's avatar
Linus Torvalds committed
674
{
675
676
677
	long	ioaddr;
	int	rc = -ENODEV;
	int	irq;
Linus Torvalds's avatar
Linus Torvalds committed
678
679
	u16	device_id;

680
	if (!EISA_bus) {
Linus Torvalds's avatar
Linus Torvalds committed
681
682
683
		TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
		return;
	}
684

Linus Torvalds's avatar
Linus Torvalds committed
685
686
	/* Loop through all slots of the EISA bus */
	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
687

688
689
690
691
		TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
			 (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID));
		TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
			 (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2));
Linus Torvalds's avatar
Linus Torvalds committed
692
693


694
695
696
697
		TLAN_DBG(TLAN_DEBUG_PROBE,
			 "Probing for EISA adapter at IO: 0x%4x : ",
			 (int) ioaddr);
		if (request_region(ioaddr, 0x10, tlan_signature) == NULL)
Linus Torvalds's avatar
Linus Torvalds committed
698
699
			goto out;

700
		if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds's avatar
Linus Torvalds committed
701
702
703
			release_region(ioaddr, 0x10);
			goto out;
		}
704

Linus Torvalds's avatar
Linus Torvalds committed
705
		device_id = inw(ioaddr + EISA_ID2);
706
		if (device_id !=  0x20F1 && device_id != 0x40F1) {
707
			release_region(ioaddr, 0x10);
Linus Torvalds's avatar
Linus Torvalds committed
708
709
			goto out;
		}
710

711
712
713
		/* check if adapter is enabled */
		if (inb(ioaddr + EISA_CR) != 0x1) {
			release_region(ioaddr, 0x10);
Linus Torvalds's avatar
Linus Torvalds committed
714
715
			goto out2;
		}
716
717

		if (debug == 0x10)
718
			pr_info("Found one\n");
Linus Torvalds's avatar
Linus Torvalds committed
719
720
721


		/* Get irq from board */
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
		switch (inb(ioaddr + 0xcc0)) {
		case(0x10):
			irq = 5;
			break;
		case(0x20):
			irq = 9;
			break;
		case(0x40):
			irq = 10;
			break;
		case(0x80):
			irq = 11;
			break;
		default:
			goto out;
737
738
739
		}


Linus Torvalds's avatar
Linus Torvalds committed
740
		/* Setup the newly found eisa adapter */
741
742
		rc = tlan_probe1(NULL, ioaddr, irq,
				 12, NULL);
Linus Torvalds's avatar
Linus Torvalds committed
743
		continue;
744

745
746
out:
		if (debug == 0x10)
747
			pr_info("None found\n");
748
		continue;
Linus Torvalds's avatar
Linus Torvalds committed
749

750
751
out2:
		if (debug == 0x10)
752
			pr_info("Card found but it is not enabled, skipping\n");
753
		continue;
754

Linus Torvalds's avatar
Linus Torvalds committed
755
756
	}

757
}
Linus Torvalds's avatar
Linus Torvalds committed
758
759

#ifdef CONFIG_NET_POLL_CONTROLLER
760
static void tlan_poll(struct net_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
761
762
{
	disable_irq(dev->irq);
763
	tlan_handle_interrupt(dev->irq, dev);
Linus Torvalds's avatar
Linus Torvalds committed
764
765
766
767
	enable_irq(dev->irq);
}
#endif

768
769
770
771
772
773
static const struct net_device_ops tlan_netdev_ops = {
	.ndo_open		= tlan_open,
	.ndo_stop		= tlan_close,
	.ndo_start_xmit		= tlan_start_tx,
	.ndo_tx_timeout		= tlan_tx_timeout,
	.ndo_get_stats		= tlan_get_stats,
774
	.ndo_set_rx_mode	= tlan_set_multicast_list,
775
776
	.ndo_do_ioctl		= tlan_ioctl,
	.ndo_set_mac_address	= eth_mac_addr,
777
778
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
779
	.ndo_poll_controller	 = tlan_poll,
780
781
#endif
};
782

Ondrej Zary's avatar
Ondrej Zary committed
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
static void tlan_get_drvinfo(struct net_device *dev,
			     struct ethtool_drvinfo *info)
{
	struct tlan_priv *priv = netdev_priv(dev);

	strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
	if (priv->pci_dev)
		strlcpy(info->bus_info, pci_name(priv->pci_dev),
			sizeof(info->bus_info));
	else
		strlcpy(info->bus_info, "EISA",	sizeof(info->bus_info));
}

static int tlan_get_eeprom_len(struct net_device *dev)
{
	return TLAN_EEPROM_SIZE;
}
Linus Torvalds's avatar
Linus Torvalds committed
800

Ondrej Zary's avatar
Ondrej Zary committed
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
static int tlan_get_eeprom(struct net_device *dev,
			   struct ethtool_eeprom *eeprom, u8 *data)
{
	int i;

	for (i = 0; i < TLAN_EEPROM_SIZE; i++)
		if (tlan_ee_read_byte(dev, i, &data[i]))
			return -EIO;

	return 0;
}

static const struct ethtool_ops tlan_ethtool_ops = {
	.get_drvinfo	= tlan_get_drvinfo,
	.get_link	= ethtool_op_get_link,
	.get_eeprom_len	= tlan_get_eeprom_len,
	.get_eeprom	= tlan_get_eeprom,
};
Linus Torvalds's avatar
Linus Torvalds committed
819

820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
/***************************************************************
 *	tlan_init
 *
 *	Returns:
 *		0 on success, error code otherwise.
 *	Parms:
 *		dev	The structure of the device to be
 *			init'ed.
 *
 *	This function completes the initialization of the
 *	device structure and driver.  It reserves the IO
 *	addresses, allocates memory for the lists and bounce
 *	buffers, retrieves the MAC address from the eeprom
 *	and assignes the device's methods.
 *
 **************************************************************/

static int tlan_init(struct net_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
838
839
{
	int		dma_size;
840
	int		err;
Linus Torvalds's avatar
Linus Torvalds committed
841
	int		i;
842
	struct tlan_priv	*priv;
Linus Torvalds's avatar
Linus Torvalds committed
843
844

	priv = netdev_priv(dev);
845

846
847
848
849
850
851
852
853
	dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS)
		* (sizeof(struct tlan_list));
	priv->dma_storage = pci_alloc_consistent(priv->pci_dev,
						 dma_size,
						 &priv->dma_storage_dma);
	priv->dma_size = dma_size;

	if (priv->dma_storage == NULL) {
854
		pr_err("Could not allocate lists and buffers for %s\n",
855
		       dev->name);
Linus Torvalds's avatar
Linus Torvalds committed
856
857
		return -ENOMEM;
	}
858
859
860
861
862
863
864
	memset(priv->dma_storage, 0, dma_size);
	priv->rx_list = (struct tlan_list *)
		ALIGN((unsigned long)priv->dma_storage, 8);
	priv->rx_list_dma = ALIGN(priv->dma_storage_dma, 8);
	priv->tx_list = priv->rx_list + TLAN_NUM_RX_LISTS;
	priv->tx_list_dma =
		priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
Stephen Hemminger's avatar
Stephen Hemminger committed
865

Linus Torvalds's avatar
Linus Torvalds committed
866
	err = 0;
867
	for (i = 0; i < ETH_ALEN; i++)
868
869
870
871
		err |= tlan_ee_read_byte(dev,
					 (u8) priv->adapter->addr_ofs + i,
					 (u8 *) &dev->dev_addr[i]);
	if (err) {
872
873
		pr_err("%s: Error reading MAC from eeprom: %d\n",
		       dev->name, err);
Linus Torvalds's avatar
Linus Torvalds committed
874
	}
875
876
877
878
879
880
881
882
	/* Olicom OC-2325/OC-2326 have the address byte-swapped */
	if (priv->adapter->addr_ofs == 0xf8) {
		for (i = 0; i < ETH_ALEN; i += 2) {
			char tmp = dev->dev_addr[i];
			dev->dev_addr[i] = dev->dev_addr[i + 1];
			dev->dev_addr[i + 1] = tmp;
		}
	}
Linus Torvalds's avatar
Linus Torvalds committed
883
884
885
886

	netif_carrier_off(dev);

	/* Device methods */
887
	dev->netdev_ops = &tlan_netdev_ops;
Ondrej Zary's avatar
Ondrej Zary committed
888
	dev->ethtool_ops = &tlan_ethtool_ops;
Linus Torvalds's avatar
Linus Torvalds committed
889
890
891
892
	dev->watchdog_timeo = TX_TIMEOUT;

	return 0;

893
}
Linus Torvalds's avatar
Linus Torvalds committed
894
895
896
897




898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
/***************************************************************
 *	tlan_open
 *
 *	Returns:
 *		0 on success, error code otherwise.
 *	Parms:
 *		dev	Structure of device to be opened.
 *
 *	This routine puts the driver and TLAN adapter in a
 *	state where it is ready to send and receive packets.
 *	It allocates the IRQ, resets and brings the adapter
 *	out of reset, and allows interrupts.  It also delays
 *	the startup for autonegotiation or sends a Rx GO
 *	command to the adapter, as appropriate.
 *
 **************************************************************/
Linus Torvalds's avatar
Linus Torvalds committed
914

915
static int tlan_open(struct net_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
916
{
917
	struct tlan_priv	*priv = netdev_priv(dev);
Linus Torvalds's avatar
Linus Torvalds committed
918
	int		err;
919

920
921
922
	priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION);
	err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED,
			  dev->name, dev);
923

924
	if (err) {
925
926
		netdev_err(dev, "Cannot open because IRQ %d is already in use\n",
			   dev->irq);
Linus Torvalds's avatar
Linus Torvalds committed
927
928
		return err;
	}
929

930
931
	timer_setup(&priv->timer, NULL, 0);
	timer_setup(&priv->media_timer, tlan_phy_monitor, 0);
932

933
	tlan_start(dev);
Linus Torvalds's avatar
Linus Torvalds committed
934

935
936
	TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened.  TLAN Chip Rev: %x\n",
		 dev->name, priv->tlan_rev);
Linus Torvalds's avatar
Linus Torvalds committed
937
938
939

	return 0;

940
}
Linus Torvalds's avatar
Linus Torvalds committed
941
942
943



944
945
946
947
948
949
950
951
952
953
954
955
956
957
/**************************************************************
 *	tlan_ioctl
 *
 *	Returns:
 *		0 on success, error code otherwise
 *	Params:
 *		dev	structure of device to receive ioctl.
 *
 *		rq	ifreq structure to hold userspace data.
 *
 *		cmd	ioctl command.
 *
 *
 *************************************************************/
Linus Torvalds's avatar
Linus Torvalds committed
958

959
static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
Linus Torvalds's avatar
Linus Torvalds committed
960
{
961
	struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds's avatar
Linus Torvalds committed
962
	struct mii_ioctl_data *data = if_mii(rq);
963
	u32 phy   = priv->phy[priv->phy_num];
964

965
	if (!priv->phy_online)
Linus Torvalds's avatar
Linus Torvalds committed
966
967
		return -EAGAIN;

968
969
970
	switch (cmd) {
	case SIOCGMIIPHY:		/* get address of MII PHY in use. */
		data->phy_id = phy;
971
		/* fall through */
Linus Torvalds's avatar
Linus Torvalds committed
972
973


974
975
976
977
	case SIOCGMIIREG:		/* read MII PHY register. */
		tlan_mii_read_reg(dev, data->phy_id & 0x1f,
				  data->reg_num & 0x1f, &data->val_out);
		return 0;
978

Linus Torvalds's avatar
Linus Torvalds committed
979

980
981
982
983
984
985
	case SIOCSMIIREG:		/* write MII PHY register. */
		tlan_mii_write_reg(dev, data->phy_id & 0x1f,
				   data->reg_num & 0x1f, data->val_in);
		return 0;
	default:
		return -EOPNOTSUPP;
Linus Torvalds's avatar
Linus Torvalds committed
986
	}
987
}
Linus Torvalds's avatar
Linus Torvalds committed
988
989


990
991
992
993
994
995
996
997
998
999
/***************************************************************
 *	tlan_tx_timeout
 *
 *	Returns: nothing
 *
 *	Params:
 *		dev	structure of device which timed out
 *			during transmit.
 *
 **************************************************************/
Linus Torvalds's avatar
Linus Torvalds committed
1000