tlan.c 85.9 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 72 73

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

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

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

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

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

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

150 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 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
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);

static void	tlan_timer(unsigned long);

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 *);
Ondrej Zary's avatar
Ondrej Zary committed
193
static void     tlan_phy_monitor(unsigned long);
Linus Torvalds's avatar
Linus Torvalds committed
194 195

/*
196 197 198 199
  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
200 201
*/

202 203 204 205
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
206

207 208 209 210
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
211 212


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

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

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

231 232
static u32
(*tlan_int_vector[TLAN_INT_NUMBER_OF_INTS])(struct net_device *, u16) = {
233
	NULL,
234 235 236 237 238 239 240
	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
241 242 243
};

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

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

	priv->timer.data = (unsigned long) dev;
262 263
	priv->timer_set_at = jiffies;
	priv->timer_type = type;
Linus Torvalds's avatar
Linus Torvalds committed
264
	mod_timer(&priv->timer, jiffies + ticks);
265

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


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

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

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

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





283 284 285 286 287 288 289 290 291 292 293 294 295 296
/***************************************************************
 *	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
297 298


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

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

306 307 308 309
	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
310 311 312 313 314
	}

#ifdef CONFIG_PCI
	pci_release_regions(pdev);
#endif
315

316
	free_netdev(dev);
317

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

321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
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
336
	del_timer_sync(&priv->media_timer);
337 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
	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
368
	int rc = pci_enable_device(pdev);
369

Ondrej Zary's avatar
Ondrej Zary committed
370 371
	if (rc)
		return rc;
372
	pci_restore_state(pdev);
373
	pci_enable_wake(pdev, PCI_D0, 0);
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
	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
390 391 392 393
static struct pci_driver tlan_driver = {
	.name		= "tlan",
	.id_table	= tlan_pci_tbl,
	.probe		= tlan_init_one,
394
	.remove		= tlan_remove_one,
395 396
	.suspend	= tlan_suspend,
	.resume		= tlan_resume,
Linus Torvalds's avatar
Linus Torvalds committed
397 398 399 400
};

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

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

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

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

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

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

419 420 421
	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
422

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

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

Linus Torvalds's avatar
Linus Torvalds committed
435

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


/*
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
***************************************************************
*	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.
*
**************************************************************/

462 463
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
464 465 466
{

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

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

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

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

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

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

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

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

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

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

Linus Torvalds's avatar
Linus Torvalds committed
524 525
		dev->base_addr = pci_io_base;
		dev->irq = pdev->irq;
526
		priv->adapter_rev = pdev->revision;
Linus Torvalds's avatar
Linus Torvalds committed
527 528 529 530 531 532 533 534
		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) {
535 536
			priv->adapter = &board_info[13]; /* NetFlex-3/E */
			priv->adapter_rev = 23;		/* TLAN 2.3 */
Linus Torvalds's avatar
Linus Torvalds committed
537 538
		} else {
			priv->adapter = &board_info[14];
539
			priv->adapter_rev = 10;		/* TLAN 1.0 */
Linus Torvalds's avatar
Linus Torvalds committed
540 541 542 543 544 545 546 547
		}
		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
548 549 550 551
		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;
552

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

Linus Torvalds's avatar
Linus Torvalds committed
558 559 560 561 562 563 564
		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;
	}
565

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

	spin_lock_init(&priv->lock);
571

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

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

584

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

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

597 598 599 600 601
	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
602 603 604
	return 0;

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


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

626 627
	while (tlan_have_eisa) {
		dev = tlan_eisa_devices;
Linus Torvalds's avatar
Linus Torvalds committed
628
		priv = netdev_priv(dev);
629 630 631 632
		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
633
		}
634 635 636 637
		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
638 639 640
		tlan_have_eisa--;
	}
}
641 642


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

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

}


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



659 660 661 662 663 664 665 666 667 668 669 670
/**************************************************************
 *	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
671

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

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

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

687 688 689 690
		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
691 692


693 694 695 696
		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
697 698
			goto out;

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

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

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

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


		/* Get irq from board */
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
		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;
736 737 738
		}


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

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

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

Linus Torvalds's avatar
Linus Torvalds committed
754 755
	}

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

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

767 768 769 770 771 772
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,
773
	.ndo_set_rx_mode	= tlan_set_multicast_list,
774
	.ndo_do_ioctl		= tlan_ioctl,
775
	.ndo_change_mtu		= eth_change_mtu,
776
	.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 800
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));
	info->eedump_len = TLAN_EEPROM_SIZE;
}

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

Ondrej Zary's avatar
Ondrej Zary committed
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
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
820

821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
/***************************************************************
 *	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
839 840
{
	int		dma_size;
841
	int		err;
Linus Torvalds's avatar
Linus Torvalds committed
842
	int		i;
843
	struct tlan_priv	*priv;
Linus Torvalds's avatar
Linus Torvalds committed
844 845

	priv = netdev_priv(dev);
846

847 848 849 850 851 852 853 854
	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) {
855
		pr_err("Could not allocate lists and buffers for %s\n",
856
		       dev->name);
Linus Torvalds's avatar
Linus Torvalds committed
857 858
		return -ENOMEM;
	}
859 860 861 862 863 864 865
	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
866

Linus Torvalds's avatar
Linus Torvalds committed
867
	err = 0;
868
	for (i = 0; i < ETH_ALEN; i++)
869 870 871 872
		err |= tlan_ee_read_byte(dev,
					 (u8) priv->adapter->addr_ofs + i,
					 (u8 *) &dev->dev_addr[i]);
	if (err) {
873 874
		pr_err("%s: Error reading MAC from eeprom: %d\n",
		       dev->name, err);
Linus Torvalds's avatar
Linus Torvalds committed
875
	}
876 877 878 879 880 881 882 883
	/* 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
884 885 886 887

	netif_carrier_off(dev);

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

	return 0;

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




899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914
/***************************************************************
 *	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
915

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

921 922 923
	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);
924

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

Linus Torvalds's avatar
Linus Torvalds committed
931
	init_timer(&priv->timer);
Ondrej Zary's avatar
Ondrej Zary committed
932
	init_timer(&priv->media_timer);
933

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

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

	return 0;

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



945 946 947 948 949 950 951 952 953 954 955 956 957 958
/**************************************************************
 *	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
959

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

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

969 970 971
	switch (cmd) {
	case SIOCGMIIPHY:		/* get address of MII PHY in use. */
		data->phy_id = phy;
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

1001
static void tlan_tx_timeout(struct net_device *dev)
Linus Torvalds's avatar
Linus Torvalds committed
1002
{
1003

1004
	TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
1005

Linus Torvalds's avatar
Linus Torvalds committed
1006
	/* Ok so we timed out, lets see what we can do about it...*/
1007 1008 1009 1010
	tlan_free_lists(dev);
	tlan_reset_lists(dev);
	tlan_read_and_clear_stats(dev, TLAN_IGNORE);
	tlan_reset_adapter(dev);
Eric Dumazet's avatar
Eric Dumazet committed
1011
	dev->trans_start = jiffies; /* prevent tx timeout */
1012
	netif_wake_queue(dev);
Linus Torvalds's avatar
Linus Torvalds committed
1013 1014

}