rtl8150.c 22.7 KB
Newer Older
Petko Manolov's avatar
USB  
Petko Manolov committed
1
/*
Petko Manolov's avatar
Petko Manolov committed
2
 *  Copyright (c) 2002 Petko Manolov (petkan@users.sourceforge.net)
Petko Manolov's avatar
USB  
Petko Manolov committed
3
 *
Petko Manolov's avatar
Petko Manolov committed
4 5 6
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
Petko Manolov's avatar
USB  
Petko Manolov committed
7 8 9 10
 */

#include <linux/config.h>
#include <linux/sched.h>
Petko Manolov's avatar
Petko Manolov committed
11
#include <linux/init.h>
Petko Manolov's avatar
USB  
Petko Manolov committed
12 13 14 15 16 17 18 19 20 21 22
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/usb.h>
#include <asm/uaccess.h>

/* Version Information */
Petko Manolov's avatar
Petko Manolov committed
23
#define DRIVER_VERSION "v0.6.1 (2004/03/13)"
Petko Manolov's avatar
USB  
Petko Manolov committed
24 25 26
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_DESC "rtl8150 based usb-ethernet driver"

Petko Manolov's avatar
Petko Manolov committed
27
#define	IDR			0x0120
Petko Manolov's avatar
USB  
Petko Manolov committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#define	MAR			0x0126
#define	CR			0x012e
#define	TCR			0x012f
#define	RCR			0x0130
#define	TSR			0x0132
#define	RSR			0x0133
#define	CON0			0x0135
#define	CON1			0x0136
#define	MSR			0x0137
#define	PHYADD			0x0138
#define	PHYDAT			0x0139
#define	PHYCNT			0x013b
#define	GPPC			0x013d
#define	BMCR			0x0140
#define	BMSR			0x0142
#define	ANAR			0x0144
#define	ANLP			0x0146
#define	AER			0x0148
Petko Manolov's avatar
Petko Manolov committed
46 47
#define CSCR			0x014C  /* This one has the link status */
#define CSCR_LINK_STATUS	(1 << 3)
Petko Manolov's avatar
USB  
Petko Manolov committed
48

Petko Manolov's avatar
Petko Manolov committed
49 50
#define	IDR_EEPROM		0x1202

Petko Manolov's avatar
USB  
Petko Manolov committed
51 52 53 54
#define	PHY_READ		0
#define	PHY_WRITE		0x20
#define	PHY_GO			0x40

Petko Manolov's avatar
Petko Manolov committed
55
#define	MII_TIMEOUT		10
56
#define	INTBUFSIZE		8
Petko Manolov's avatar
Petko Manolov committed
57

Petko Manolov's avatar
USB  
Petko Manolov committed
58 59 60 61 62
#define	RTL8150_REQT_READ	0xc0
#define	RTL8150_REQT_WRITE	0x40
#define	RTL8150_REQ_GET_REGS	0x05
#define	RTL8150_REQ_SET_REGS	0x05

Petko Manolov's avatar
Petko Manolov committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

/* Transmit status register errors */
#define TSR_ECOL		(1<<5)
#define TSR_LCOL		(1<<4)
#define TSR_LOSS_CRS		(1<<3)
#define TSR_JBR			(1<<2)
#define TSR_ERRORS		(TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR)
/* Receive status register errors */
#define RSR_CRC			(1<<2)
#define RSR_FAE			(1<<1)
#define RSR_ERRORS		(RSR_CRC | RSR_FAE)

/* Media status register definitions */
#define MSR_DUPLEX		(1<<4)
#define MSR_SPEED		(1<<3)
#define MSR_LINK		(1<<2)

/* Interrupt pipe data */
#define INT_TSR			0x00
#define INT_RSR			0x01
#define INT_MSR			0x02
#define INT_WAKSR		0x03
#define INT_TXOK_CNT		0x04
#define INT_RXLOST_CNT		0x05
#define INT_CRERR_CNT		0x06
#define INT_COL_CNT		0x07

/* Transmit status register errors */
#define TSR_ECOL		(1<<5)
#define TSR_LCOL		(1<<4)
#define TSR_LOSS_CRS		(1<<3)
#define TSR_JBR			(1<<2)
#define TSR_ERRORS		(TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR)
/* Receive status register errors */
#define RSR_CRC			(1<<2)
#define RSR_FAE			(1<<1)
#define RSR_ERRORS		(RSR_CRC | RSR_FAE)

/* Media status register definitions */
#define MSR_DUPLEX		(1<<4)
#define MSR_SPEED		(1<<3)
#define MSR_LINK		(1<<2)

/* Interrupt pipe data */
#define INT_TSR			0x00
#define INT_RSR			0x01
#define INT_MSR			0x02
#define INT_WAKSR		0x03
#define INT_TXOK_CNT		0x04
#define INT_RXLOST_CNT		0x05
#define INT_CRERR_CNT		0x06
#define INT_COL_CNT		0x07


Petko Manolov's avatar
Petko Manolov committed
117
#define	RTL8150_MTU		1540
Petko Manolov's avatar
USB  
Petko Manolov committed
118
#define	RTL8150_TX_TIMEOUT	(HZ)
Petko Manolov's avatar
Petko Manolov committed
119
#define	RX_SKB_POOL_SIZE	4
Petko Manolov's avatar
USB  
Petko Manolov committed
120 121

/* rtl8150 flags */
Petko Manolov's avatar
Petko Manolov committed
122
#define	RTL8150_HW_CRC		0
Petko Manolov's avatar
USB  
Petko Manolov committed
123
#define	RX_REG_SET		1
Petko Manolov's avatar
Petko Manolov committed
124
#define	RTL8150_UNPLUG		2
125
#define	RX_URB_FAIL		3
Petko Manolov's avatar
USB  
Petko Manolov committed
126 127 128

/* Define these values to match your device */
#define VENDOR_ID_REALTEK		0x0bda
Petko Manolov's avatar
Petko Manolov committed
129
#define	VENDOR_ID_MELCO			0x0411
Petko Manolov's avatar
Petko Manolov committed
130 131
#define VENDOR_ID_MICRONET		0x3980
#define	VENDOR_ID_LONGSHINE		0x07b8
Petko Manolov's avatar
Petko Manolov committed
132

Petko Manolov's avatar
USB  
Petko Manolov committed
133
#define PRODUCT_ID_RTL8150		0x8150
Petko Manolov's avatar
Petko Manolov committed
134
#define	PRODUCT_ID_LUAKTX		0x0012
Petko Manolov's avatar
Petko Manolov committed
135 136
#define	PRODUCT_ID_LCS8138TX		0x401a
#define PRODUCT_ID_SP128AR		0x0003
Petko Manolov's avatar
USB  
Petko Manolov committed
137

Petko Manolov's avatar
Petko Manolov committed
138 139
#undef	EEPROM_WRITE

Petko Manolov's avatar
USB  
Petko Manolov committed
140
/* table of devices that work with this driver */
Petko Manolov's avatar
Petko Manolov committed
141 142
static struct usb_device_id rtl8150_table[] = {
	{USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8150)},
Petko Manolov's avatar
Petko Manolov committed
143
	{USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},
Petko Manolov's avatar
Petko Manolov committed
144 145
	{USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)},
	{USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)},
Petko Manolov's avatar
Petko Manolov committed
146
	{}
Petko Manolov's avatar
USB  
Petko Manolov committed
147 148
};

Petko Manolov's avatar
Petko Manolov committed
149
MODULE_DEVICE_TABLE(usb, rtl8150_table);
Petko Manolov's avatar
USB  
Petko Manolov committed
150 151

struct rtl8150 {
Petko Manolov's avatar
Petko Manolov committed
152 153 154 155 156 157 158 159 160 161 162 163
	unsigned long flags;
	struct usb_device *udev;
	struct tasklet_struct tl;
	struct net_device_stats stats;
	struct net_device *netdev;
	struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
	struct sk_buff *tx_skb, *rx_skb;
	struct sk_buff *rx_skb_pool[RX_SKB_POOL_SIZE];
	spinlock_t rx_pool_lock;
	struct usb_ctrlrequest dr;
	int intr_interval;
	u16 rx_creg;
164
	u8 *intr_buff;
Petko Manolov's avatar
Petko Manolov committed
165
	u8 phy;
Petko Manolov's avatar
USB  
Petko Manolov committed
166 167
};

Petko Manolov's avatar
Petko Manolov committed
168
typedef struct rtl8150 rtl8150_t;
Petko Manolov's avatar
USB  
Petko Manolov committed
169

170
static unsigned long multicast_filter_limit = 32;
Petko Manolov's avatar
USB  
Petko Manolov committed
171

Petko Manolov's avatar
Petko Manolov committed
172 173
static void fill_skb_pool(rtl8150_t *);
static void free_skb_pool(rtl8150_t *);
Petko Manolov's avatar
Petko Manolov committed
174
static inline struct sk_buff *pull_skb(rtl8150_t *);
175 176
static void rtl8150_disconnect(struct usb_interface *intf);
static int rtl8150_probe(struct usb_interface *intf,
Petko Manolov's avatar
Petko Manolov committed
177
			   const struct usb_device_id *id);
Petko Manolov's avatar
USB  
Petko Manolov committed
178

179 180
static const char driver_name [] = "rtl8150";

Petko Manolov's avatar
USB  
Petko Manolov committed
181
static struct usb_driver rtl8150_driver = {
182
	.owner =	THIS_MODULE,
183
	.name =		driver_name,
184 185 186
	.probe =	rtl8150_probe,
	.disconnect =	rtl8150_disconnect,
	.id_table =	rtl8150_table,
Petko Manolov's avatar
USB  
Petko Manolov committed
187 188 189 190 191 192 193
};

/*
**
**	device related part of the code
**
*/
Petko Manolov's avatar
Petko Manolov committed
194
static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
Petko Manolov's avatar
USB  
Petko Manolov committed
195
{
Petko Manolov's avatar
Petko Manolov committed
196 197 198
	return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
			       RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
			       indx, 0, data, size, HZ / 2);
Petko Manolov's avatar
USB  
Petko Manolov committed
199 200
}

Petko Manolov's avatar
Petko Manolov committed
201
static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
Petko Manolov's avatar
USB  
Petko Manolov committed
202
{
Petko Manolov's avatar
Petko Manolov committed
203 204 205
	return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
			       RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
			       indx, 0, data, size, HZ / 2);
Petko Manolov's avatar
USB  
Petko Manolov committed
206 207
}

David S. Miller's avatar
David S. Miller committed
208
static void ctrl_callback(struct urb *urb, struct pt_regs *regs)
Petko Manolov's avatar
USB  
Petko Manolov committed
209
{
Petko Manolov's avatar
Petko Manolov committed
210 211
	rtl8150_t *dev;

Petko Manolov's avatar
USB  
Petko Manolov committed
212 213 214 215 216 217 218 219 220 221 222 223 224 225
	switch (urb->status) {
	case 0:
		break;
	case -EINPROGRESS:
		break;
	case -ENOENT:
		break;
	default:
		warn("ctrl urb status %d", urb->status);
	}
	dev = urb->context;
	clear_bit(RX_REG_SET, &dev->flags);
}

226
static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
Petko Manolov's avatar
USB  
Petko Manolov committed
227
{
Petko Manolov's avatar
Petko Manolov committed
228
	int ret;
Petko Manolov's avatar
USB  
Petko Manolov committed
229

Petko Manolov's avatar
Petko Manolov committed
230
	if (test_bit(RX_REG_SET, &dev->flags))
Petko Manolov's avatar
USB  
Petko Manolov committed
231
		return -EAGAIN;
Petko Manolov's avatar
Petko Manolov committed
232

Petko Manolov's avatar
USB  
Petko Manolov committed
233 234 235 236 237 238
	dev->dr.bRequestType = RTL8150_REQT_WRITE;
	dev->dr.bRequest = RTL8150_REQ_SET_REGS;
	dev->dr.wValue = cpu_to_le16(indx);
	dev->dr.wIndex = 0;
	dev->dr.wLength = cpu_to_le16(size);
	dev->ctrl_urb->transfer_buffer_length = size;
239
	usb_fill_control_urb(dev->ctrl_urb, dev->udev,
Petko Manolov's avatar
Petko Manolov committed
240 241
			 usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
			 &dev->rx_creg, size, ctrl_callback, dev);
Petko Manolov's avatar
USB  
Petko Manolov committed
242 243 244 245 246 247 248 249
	if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC)))
		err("control request submission failed: %d", ret);
	else
		set_bit(RX_REG_SET, &dev->flags);

	return ret;
}

Petko Manolov's avatar
Petko Manolov committed
250
static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg)
Petko Manolov's avatar
USB  
Petko Manolov committed
251
{
Petko Manolov's avatar
Petko Manolov committed
252 253
	int i;
	u8 data[3], tmp;
Petko Manolov's avatar
USB  
Petko Manolov committed
254 255 256 257 258 259 260 261 262 263

	data[0] = phy;
	data[1] = data[2] = 0;
	tmp = indx | PHY_READ | PHY_GO;
	i = 0;

	set_registers(dev, PHYADD, sizeof(data), data);
	set_registers(dev, PHYCNT, 1, &tmp);
	do {
		get_registers(dev, PHYCNT, 1, data);
Petko Manolov's avatar
Petko Manolov committed
264
	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
Petko Manolov's avatar
USB  
Petko Manolov committed
265

Petko Manolov's avatar
Petko Manolov committed
266
	if (i < MII_TIMEOUT) {
Petko Manolov's avatar
USB  
Petko Manolov committed
267 268 269 270 271 272 273
		get_registers(dev, PHYDAT, 2, data);
		*reg = le16_to_cpup(data);
		return 0;
	} else
		return 1;
}

Petko Manolov's avatar
Petko Manolov committed
274
static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg)
Petko Manolov's avatar
USB  
Petko Manolov committed
275
{
Petko Manolov's avatar
Petko Manolov committed
276 277
	int i;
	u8 data[3], tmp;
Petko Manolov's avatar
USB  
Petko Manolov committed
278 279 280 281 282 283 284 285 286 287

	data[0] = phy;
	*(data + 1) = cpu_to_le16p(&reg);
	tmp = indx | PHY_WRITE | PHY_GO;
	i = 0;

	set_registers(dev, PHYADD, sizeof(data), data);
	set_registers(dev, PHYCNT, 1, &tmp);
	do {
		get_registers(dev, PHYCNT, 1, data);
Petko Manolov's avatar
Petko Manolov committed
288
	} while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT));
Petko Manolov's avatar
USB  
Petko Manolov committed
289

Petko Manolov's avatar
Petko Manolov committed
290
	if (i < MII_TIMEOUT)
Petko Manolov's avatar
USB  
Petko Manolov committed
291 292 293 294 295
		return 0;
	else
		return 1;
}

Petko Manolov's avatar
Petko Manolov committed
296
static inline void set_ethernet_addr(rtl8150_t * dev)
Petko Manolov's avatar
USB  
Petko Manolov committed
297
{
Petko Manolov's avatar
Petko Manolov committed
298
	u8 node_id[6];
Petko Manolov's avatar
USB  
Petko Manolov committed
299

Petko Manolov's avatar
Petko Manolov committed
300
	get_registers(dev, IDR, sizeof(node_id), node_id);
Petko Manolov's avatar
USB  
Petko Manolov committed
301 302 303
	memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id));
}

Petko Manolov's avatar
Petko Manolov committed
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
static int rtl8150_set_mac_address(struct net_device *netdev, void *p)
{
	struct sockaddr *addr = p;
	rtl8150_t *dev;
	int i;

	if (netif_running(netdev))
		return -EBUSY;
	dev = netdev->priv;
	if (dev == NULL) {
		return -ENODEV;
	}
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
	dbg("%s: Setting MAC address to ", netdev->name);
	for (i = 0; i < 5; i++)
		dbg("%02X:", netdev->dev_addr[i]);
	dbg("%02X\n", netdev->dev_addr[i]);
	/* Set the IDR registers. */
	set_registers(dev, IDR, sizeof(netdev->dev_addr), netdev->dev_addr);
#ifdef EEPROM_WRITE
	{
	u8 cr;
	/* Get the CR contents. */
	get_registers(dev, CR, 1, &cr);
	/* Set the WEPROM bit (eeprom write enable). */
	cr |= 0x20;
	set_registers(dev, CR, 1, &cr);
	/* Write the MAC address into eeprom. Eeprom writes must be word-sized,
	   so we need to split them up. */
	for (i = 0; i * 2 < netdev->addr_len; i++) {
		set_registers(dev, IDR_EEPROM + (i * 2), 2, 
		netdev->dev_addr + (i * 2));
	}
	/* Clear the WEPROM bit (preventing accidental eeprom writes). */
	cr &= 0xdf;
	set_registers(dev, CR, 1, &cr);
	}
#endif
	return 0;
}

Petko Manolov's avatar
Petko Manolov committed
345
static int rtl8150_reset(rtl8150_t * dev)
Petko Manolov's avatar
USB  
Petko Manolov committed
346
{
Petko Manolov's avatar
Petko Manolov committed
347 348
	u8 data = 0x10;
	int i = HZ;
Petko Manolov's avatar
USB  
Petko Manolov committed
349 350 351 352 353 354

	set_registers(dev, CR, 1, &data);
	do {
		get_registers(dev, CR, 1, &data);
	} while ((data & 0x10) && --i);

Petko Manolov's avatar
Petko Manolov committed
355 356
	return (i > 0) ? 1 : 0;
}
Petko Manolov's avatar
USB  
Petko Manolov committed
357

Petko Manolov's avatar
Petko Manolov committed
358
static int alloc_all_urbs(rtl8150_t * dev)
Petko Manolov's avatar
USB  
Petko Manolov committed
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
{
	dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->rx_urb)
		return 0;
	dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->tx_urb) {
		usb_free_urb(dev->rx_urb);
		return 0;
	}
	dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->intr_urb) {
		usb_free_urb(dev->rx_urb);
		usb_free_urb(dev->tx_urb);
		return 0;
	}
	dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->intr_urb) {
		usb_free_urb(dev->rx_urb);
		usb_free_urb(dev->tx_urb);
		usb_free_urb(dev->intr_urb);
		return 0;
	}

	return 1;
}

Petko Manolov's avatar
Petko Manolov committed
385
static void free_all_urbs(rtl8150_t * dev)
Petko Manolov's avatar
USB  
Petko Manolov committed
386 387 388 389 390 391 392
{
	usb_free_urb(dev->rx_urb);
	usb_free_urb(dev->tx_urb);
	usb_free_urb(dev->intr_urb);
	usb_free_urb(dev->ctrl_urb);
}

Petko Manolov's avatar
Petko Manolov committed
393
static void unlink_all_urbs(rtl8150_t * dev)
Petko Manolov's avatar
USB  
Petko Manolov committed
394 395 396 397 398 399 400
{
	usb_unlink_urb(dev->rx_urb);
	usb_unlink_urb(dev->tx_urb);
	usb_unlink_urb(dev->intr_urb);
	usb_unlink_urb(dev->ctrl_urb);
}

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
static inline struct sk_buff *pull_skb(rtl8150_t *dev)
{
	struct sk_buff *skb;
	int i;

	for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
		if (dev->rx_skb_pool[i]) {
			skb = dev->rx_skb_pool[i];
			dev->rx_skb_pool[i] = NULL;
			return skb;
		}
	}
	return NULL;
}

David S. Miller's avatar
David S. Miller committed
416
static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
Petko Manolov's avatar
USB  
Petko Manolov committed
417
{
Petko Manolov's avatar
Petko Manolov committed
418 419 420
	rtl8150_t *dev;
	unsigned pkt_len, res;
	struct sk_buff *skb;
Petko Manolov's avatar
USB  
Petko Manolov committed
421
	struct net_device *netdev;
Petko Manolov's avatar
Petko Manolov committed
422
	u16 rx_stat;
Petko Manolov's avatar
USB  
Petko Manolov committed
423 424

	dev = urb->context;
425 426 427
	if (!dev)
		return;
	if (test_bit(RTL8150_UNPLUG, &dev->flags))
Petko Manolov's avatar
USB  
Petko Manolov committed
428 429
		return;
	netdev = dev->netdev;
430
	if (!netif_device_present(netdev))
Petko Manolov's avatar
USB  
Petko Manolov committed
431
		return;
432

Petko Manolov's avatar
USB  
Petko Manolov committed
433 434 435 436
	switch (urb->status) {
	case 0:
		break;
	case -ENOENT:
Petko Manolov's avatar
Petko Manolov committed
437
		return;	/* the urb is in unlink state */
Petko Manolov's avatar
USB  
Petko Manolov committed
438
	case -ETIMEDOUT:
Petko Manolov's avatar
Petko Manolov committed
439
		warn("may be reset is needed?..");
Petko Manolov's avatar
Petko Manolov committed
440
		goto goon;
Petko Manolov's avatar
USB  
Petko Manolov committed
441 442 443 444 445
	default:
		warn("Rx status %d", urb->status);
		goto goon;
	}

Petko Manolov's avatar
Petko Manolov committed
446 447
	if (!dev->rx_skb)
		goto resched;
Petko Manolov's avatar
Petko Manolov committed
448 449 450
	/* protect against short packets (tell me why we got some?!?) */
	if (urb->actual_length < 4)
		goto goon;
Petko Manolov's avatar
Petko Manolov committed
451

Petko Manolov's avatar
Petko Manolov committed
452
	res = urb->actual_length;
Petko Manolov's avatar
Petko Manolov committed
453
	rx_stat = le16_to_cpu(*(short *)(urb->transfer_buffer + res - 4));
Petko Manolov's avatar
Petko Manolov committed
454 455
	pkt_len = res - 4;

Petko Manolov's avatar
Petko Manolov committed
456 457 458
	skb_put(dev->rx_skb, pkt_len);
	dev->rx_skb->protocol = eth_type_trans(dev->rx_skb, netdev);
	netif_rx(dev->rx_skb);
Petko Manolov's avatar
USB  
Petko Manolov committed
459 460
	dev->stats.rx_packets++;
	dev->stats.rx_bytes += pkt_len;
Petko Manolov's avatar
Petko Manolov committed
461 462

	spin_lock(&dev->rx_pool_lock);
Petko Manolov's avatar
Petko Manolov committed
463
	skb = pull_skb(dev);
Petko Manolov's avatar
Petko Manolov committed
464
	spin_unlock(&dev->rx_pool_lock);
Petko Manolov's avatar
Petko Manolov committed
465 466
	if (!skb)
		goto resched;
Petko Manolov's avatar
Petko Manolov committed
467 468

	dev->rx_skb = skb;
Petko Manolov's avatar
USB  
Petko Manolov committed
469
goon:
470
	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
Petko Manolov's avatar
Petko Manolov committed
471
		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
Petko Manolov's avatar
Petko Manolov committed
472
	if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
473
		set_bit(RX_URB_FAIL, &dev->flags);
Petko Manolov's avatar
Petko Manolov committed
474 475
		goto resched;
	} else {
476
		clear_bit(RX_URB_FAIL, &dev->flags);
Petko Manolov's avatar
Petko Manolov committed
477 478 479 480 481
	}

	return;
resched:
	tasklet_schedule(&dev->tl);
Petko Manolov's avatar
USB  
Petko Manolov committed
482 483
}

Petko Manolov's avatar
Petko Manolov committed
484 485 486 487 488 489
static void rx_fixup(unsigned long data)
{
	rtl8150_t *dev;
	struct sk_buff *skb;

	dev = (rtl8150_t *)data;
490

Petko Manolov's avatar
Petko Manolov committed
491
	spin_lock_irq(&dev->rx_pool_lock);
Petko Manolov's avatar
Petko Manolov committed
492
	fill_skb_pool(dev);
Petko Manolov's avatar
Petko Manolov committed
493
	spin_unlock_irq(&dev->rx_pool_lock);
494
	if (test_bit(RX_URB_FAIL, &dev->flags))
Petko Manolov's avatar
Petko Manolov committed
495 496
		if (dev->rx_skb)
			goto try_again;
Petko Manolov's avatar
Petko Manolov committed
497 498 499 500
	spin_lock_irq(&dev->rx_pool_lock);
	skb = pull_skb(dev);
	spin_unlock_irq(&dev->rx_pool_lock);
	if (skb == NULL)
Petko Manolov's avatar
Petko Manolov committed
501
		goto tlsched;
Petko Manolov's avatar
Petko Manolov committed
502
	dev->rx_skb = skb;
503
	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
Petko Manolov's avatar
Petko Manolov committed
504
		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
505 506 507
try_again:
	if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) {
		set_bit(RX_URB_FAIL, &dev->flags);
Petko Manolov's avatar
Petko Manolov committed
508 509
		goto tlsched;
	 } else {
510
		clear_bit(RX_URB_FAIL, &dev->flags);
Petko Manolov's avatar
Petko Manolov committed
511 512 513 514 515
	}

	return;
tlsched:
	tasklet_schedule(&dev->tl);
Petko Manolov's avatar
Petko Manolov committed
516
}
Petko Manolov's avatar
USB  
Petko Manolov committed
517

David S. Miller's avatar
David S. Miller committed
518
static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
Petko Manolov's avatar
USB  
Petko Manolov committed
519
{
Petko Manolov's avatar
Petko Manolov committed
520
	rtl8150_t *dev;
Petko Manolov's avatar
USB  
Petko Manolov committed
521 522 523 524

	dev = urb->context;
	if (!dev)
		return;
Petko Manolov's avatar
Petko Manolov committed
525
	dev_kfree_skb_irq(dev->tx_skb);
Petko Manolov's avatar
USB  
Petko Manolov committed
526 527 528 529 530 531 532 533
	if (!netif_device_present(dev->netdev))
		return;
	if (urb->status)
		info("%s: Tx status %d", dev->netdev->name, urb->status);
	dev->netdev->trans_start = jiffies;
	netif_wake_queue(dev->netdev);
}

534
static void intr_callback(struct urb *urb, struct pt_regs *regs)
Petko Manolov's avatar
USB  
Petko Manolov committed
535
{
Petko Manolov's avatar
Petko Manolov committed
536
	rtl8150_t *dev;
Petko Manolov's avatar
Petko Manolov committed
537
	__u8 *d;
538
	int status;
Petko Manolov's avatar
USB  
Petko Manolov committed
539 540 541 542 543

	dev = urb->context;
	if (!dev)
		return;
	switch (urb->status) {
544
	case 0:			/* success */
Petko Manolov's avatar
Petko Manolov committed
545
		break;
546
	case -ECONNRESET:	/* unlink */
Petko Manolov's avatar
Petko Manolov committed
547
	case -ENOENT:
548
	case -ESHUTDOWN:
Petko Manolov's avatar
Petko Manolov committed
549
		return;
550
	/* -EPIPE:  should clear the halt */
Petko Manolov's avatar
Petko Manolov committed
551 552
	default:
		info("%s: intr status %d", dev->netdev->name, urb->status);
553
		goto resubmit;
Petko Manolov's avatar
USB  
Petko Manolov committed
554
	}
555

Petko Manolov's avatar
Petko Manolov committed
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
	d = urb->transfer_buffer;
	if (d[0] & TSR_ERRORS) {
		dev->stats.tx_errors++;
		if (d[INT_TSR] & (TSR_ECOL | TSR_JBR))
			dev->stats.tx_aborted_errors++;
		if (d[INT_TSR] & TSR_LCOL)
			dev->stats.tx_window_errors++;
		if (d[INT_TSR] & TSR_LOSS_CRS)
			dev->stats.tx_carrier_errors++;
	}
	/* Report link status changes to the network stack */
	if ((d[INT_MSR] & MSR_LINK) == 0) {
		if (netif_carrier_ok(dev->netdev)) {
			netif_carrier_off(dev->netdev);
			dbg("%s: LINK LOST\n", __func__);
		}
	} else {
		if (!netif_carrier_ok(dev->netdev)) {
			netif_carrier_on(dev->netdev);
			dbg("%s: LINK CAME BACK\n", __func__);
		}
	}
578 579 580 581 582 583 584

resubmit:
	status = usb_submit_urb (urb, SLAB_ATOMIC);
	if (status)
		err ("can't resubmit intr, %s-%s/input0, status %d",
				dev->udev->bus->bus_name,
				dev->udev->devpath, status);
Petko Manolov's avatar
USB  
Petko Manolov committed
585 586
}

Petko Manolov's avatar
Petko Manolov committed
587

Petko Manolov's avatar
USB  
Petko Manolov committed
588 589 590 591 592 593
/*
**
**	network related part of the code
**
*/

Petko Manolov's avatar
Petko Manolov committed
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
static void fill_skb_pool(rtl8150_t *dev)
{
	struct sk_buff *skb;
	int i;

	for (i = 0; i < RX_SKB_POOL_SIZE; i++) {
		if (dev->rx_skb_pool[i])
			continue;
		skb = dev_alloc_skb(RTL8150_MTU + 2);
		if (!skb) {
			return;
		}
		skb->dev = dev->netdev;
		skb_reserve(skb, 2);
		dev->rx_skb_pool[i] = skb;
	}
}

static void free_skb_pool(rtl8150_t *dev)
{
	int i;

	for (i = 0; i < RX_SKB_POOL_SIZE; i++)
		if (dev->rx_skb_pool[i])
			dev_kfree_skb(dev->rx_skb_pool[i]);
}

static int enable_net_traffic(rtl8150_t * dev)
Petko Manolov's avatar
USB  
Petko Manolov committed
622
{
Petko Manolov's avatar
Petko Manolov committed
623
	u8 cr, tcr, rcr, msr;
Petko Manolov's avatar
USB  
Petko Manolov committed
624

Petko Manolov's avatar
Petko Manolov committed
625
	if (!rtl8150_reset(dev)) {
Petko Manolov's avatar
USB  
Petko Manolov committed
626 627
		warn("%s - device reset failed", __FUNCTION__);
	}
Petko Manolov's avatar
Petko Manolov committed
628
	/* RCR bit7=1 attach Rx info at the end;  =0 HW CRC (which is broken) */
Petko Manolov's avatar
Petko Manolov committed
629
	rcr = 0x9e;
630
	dev->rx_creg = cpu_to_le16(rcr);
Petko Manolov's avatar
Petko Manolov committed
631
	tcr = 0xd8;
Petko Manolov's avatar
USB  
Petko Manolov committed
632
	cr = 0x0c;
Petko Manolov's avatar
Petko Manolov committed
633 634
	if (!(rcr & 0x80))
		set_bit(RTL8150_HW_CRC, &dev->flags);
Petko Manolov's avatar
USB  
Petko Manolov committed
635 636 637 638 639 640 641 642
	set_registers(dev, RCR, 1, &rcr);
	set_registers(dev, TCR, 1, &tcr);
	set_registers(dev, CR, 1, &cr);
	get_registers(dev, MSR, 1, &msr);

	return 0;
}

Petko Manolov's avatar
Petko Manolov committed
643
static void disable_net_traffic(rtl8150_t * dev)
Petko Manolov's avatar
USB  
Petko Manolov committed
644
{
Petko Manolov's avatar
Petko Manolov committed
645
	u8 cr;
Petko Manolov's avatar
USB  
Petko Manolov committed
646 647 648 649 650 651 652 653

	get_registers(dev, CR, 1, &cr);
	cr &= 0xf3;
	set_registers(dev, CR, 1, &cr);
}

static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
{
Petko Manolov's avatar
Petko Manolov committed
654
	return &((rtl8150_t *) dev->priv)->stats;
Petko Manolov's avatar
USB  
Petko Manolov committed
655 656 657 658
}

static void rtl8150_tx_timeout(struct net_device *netdev)
{
Petko Manolov's avatar
Petko Manolov committed
659
	rtl8150_t *dev;
Petko Manolov's avatar
USB  
Petko Manolov committed
660 661 662 663

	dev = netdev->priv;
	if (!dev)
		return;
Petko Manolov's avatar
Petko Manolov committed
664
	warn("%s: Tx timeout.", netdev->name);
665
	dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
Petko Manolov's avatar
USB  
Petko Manolov committed
666 667 668 669 670 671
	usb_unlink_urb(dev->tx_urb);
	dev->stats.tx_errors++;
}

static void rtl8150_set_multicast(struct net_device *netdev)
{
Petko Manolov's avatar
Petko Manolov committed
672
	rtl8150_t *dev;
Petko Manolov's avatar
USB  
Petko Manolov committed
673 674 675 676

	dev = netdev->priv;
	netif_stop_queue(netdev);
	if (netdev->flags & IFF_PROMISC) {
677
		dev->rx_creg |= cpu_to_le16(0x0001);
Petko Manolov's avatar
USB  
Petko Manolov committed
678 679
		info("%s: promiscuous mode", netdev->name);
	} else if ((netdev->mc_count > multicast_filter_limit) ||
Petko Manolov's avatar
Petko Manolov committed
680
		   (netdev->flags & IFF_ALLMULTI)) {
681 682
		dev->rx_creg &= cpu_to_le16(0xfffe);
		dev->rx_creg |= cpu_to_le16(0x0002);
Petko Manolov's avatar
USB  
Petko Manolov committed
683 684 685
		info("%s: allmulti set", netdev->name);
	} else {
		/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
686
		dev->rx_creg &= cpu_to_le16(0x00fc);
Petko Manolov's avatar
USB  
Petko Manolov committed
687
	}
688
	async_set_registers(dev, RCR, 2);
Petko Manolov's avatar
USB  
Petko Manolov committed
689 690 691 692 693
	netif_wake_queue(netdev);
}

static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
Petko Manolov's avatar
Petko Manolov committed
694 695
	rtl8150_t *dev;
	int count, res;
Petko Manolov's avatar
USB  
Petko Manolov committed
696 697 698

	netif_stop_queue(netdev);
	dev = netdev->priv;
Petko Manolov's avatar
Petko Manolov committed
699 700
	count = (skb->len < 60) ? 60 : skb->len;
	count = (count & 0x3f) ? count : count + 1;
Petko Manolov's avatar
Petko Manolov committed
701
	dev->tx_skb = skb;
702
	usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
Petko Manolov's avatar
Petko Manolov committed
703
		      skb->data, count, write_bulk_callback, dev);
704
	if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
Petko Manolov's avatar
USB  
Petko Manolov committed
705 706 707 708 709 710 711 712 713 714 715 716
		warn("failed tx_urb %d\n", res);
		dev->stats.tx_errors++;
		netif_start_queue(netdev);
	} else {
		dev->stats.tx_packets++;
		dev->stats.tx_bytes += skb->len;
		netdev->trans_start = jiffies;
	}

	return 0;
}

Petko Manolov's avatar
Petko Manolov committed
717 718 719 720 721 722 723 724 725 726 727 728 729

static void set_carrier(struct net_device *netdev)
{
	rtl8150_t *dev = netdev->priv;
	short tmp;

	get_registers(dev, CSCR, 2, &tmp);
	if (tmp & CSCR_LINK_STATUS)
		netif_carrier_on(netdev);
	else
		netif_carrier_off(netdev);
}

Petko Manolov's avatar
USB  
Petko Manolov committed
730 731
static int rtl8150_open(struct net_device *netdev)
{
Petko Manolov's avatar
Petko Manolov committed
732 733 734
	rtl8150_t *dev;
	int res;

Petko Manolov's avatar
USB  
Petko Manolov committed
735 736 737 738
	dev = netdev->priv;
	if (dev == NULL) {
		return -ENODEV;
	}
Petko Manolov's avatar
Petko Manolov committed
739 740
	if (dev->rx_skb == NULL)
		dev->rx_skb = pull_skb(dev);
Petko Manolov's avatar
Petko Manolov committed
741 742 743
	if (!dev->rx_skb)
		return -ENOMEM;

Petko Manolov's avatar
Petko Manolov committed
744 745
	set_registers(dev, IDR, 6, netdev->dev_addr);
	
746
	usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
Petko Manolov's avatar
Petko Manolov committed
747 748
		      dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
	if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL)))
Petko Manolov's avatar
USB  
Petko Manolov committed
749
		warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
750
	usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
751
		     dev->intr_buff, INTBUFSIZE, intr_callback,
Petko Manolov's avatar
Petko Manolov committed
752 753
		     dev, dev->intr_interval);
	if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL)))
Petko Manolov's avatar
USB  
Petko Manolov committed
754 755 756
		warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
	netif_start_queue(netdev);
	enable_net_traffic(dev);
Petko Manolov's avatar
Petko Manolov committed
757
	set_carrier(netdev);
Petko Manolov's avatar
USB  
Petko Manolov committed
758 759 760 761 762 763 764 765 766 767 768 769 770

	return res;
}

static int rtl8150_close(struct net_device *netdev)
{
	rtl8150_t *dev;
	int res = 0;

	dev = netdev->priv;
	if (!dev)
		return -ENODEV;

771
	netif_stop_queue(netdev);
Petko Manolov's avatar
Petko Manolov committed
772 773
	if (!test_bit(RTL8150_UNPLUG, &dev->flags))
		disable_net_traffic(dev);
Petko Manolov's avatar
USB  
Petko Manolov committed
774 775 776 777 778
	unlink_all_urbs(dev);

	return res;
}

779
static int rtl8150_ethtool_ioctl(struct net_device *netdev, void __user *uaddr)
Petko Manolov's avatar
USB  
Petko Manolov committed
780
{
Petko Manolov's avatar
Petko Manolov committed
781 782
	rtl8150_t *dev;
	int cmd;
Petko Manolov's avatar
USB  
Petko Manolov committed
783 784

	dev = netdev->priv;
785
	if (get_user(cmd, (int __user *) uaddr))
Petko Manolov's avatar
USB  
Petko Manolov committed
786 787 788
		return -EFAULT;

	switch (cmd) {
Petko Manolov's avatar
Petko Manolov committed
789 790 791
	case ETHTOOL_GDRVINFO:{
		struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };

792
		strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
Petko Manolov's avatar
USB  
Petko Manolov committed
793
		strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
Petko Manolov's avatar
Petko Manolov committed
794
		usb_make_path(dev->udev, info.bus_info, sizeof info.bus_info);
Petko Manolov's avatar
USB  
Petko Manolov committed
795 796 797
		if (copy_to_user(uaddr, &info, sizeof(info)))
			return -EFAULT;
		return 0;
Petko Manolov's avatar
Petko Manolov committed
798 799
		}
	case ETHTOOL_GSET:{
Petko Manolov's avatar
USB  
Petko Manolov committed
800
		struct ethtool_cmd ecmd;
Petko Manolov's avatar
Petko Manolov committed
801
		short lpa, bmcr;
Petko Manolov's avatar
USB  
Petko Manolov committed
802 803 804 805

		if (copy_from_user(&ecmd, uaddr, sizeof(ecmd)))
			return -EFAULT;
		ecmd.supported = (SUPPORTED_10baseT_Half |
Petko Manolov's avatar
Petko Manolov committed
806 807 808 809 810
				  SUPPORTED_10baseT_Full |
				  SUPPORTED_100baseT_Half |
				  SUPPORTED_100baseT_Full |
				  SUPPORTED_Autoneg |
				  SUPPORTED_TP | SUPPORTED_MII);
Petko Manolov's avatar
USB  
Petko Manolov committed
811 812 813 814 815 816 817 818 819 820 821
		ecmd.port = PORT_TP;
		ecmd.transceiver = XCVR_INTERNAL;
		ecmd.phy_address = dev->phy;
		get_registers(dev, BMCR, 2, &bmcr);
		get_registers(dev, ANLP, 2, &lpa);
		if (bmcr & BMCR_ANENABLE) {
			ecmd.autoneg = AUTONEG_ENABLE;
			ecmd.speed = (lpa & (LPA_100HALF | LPA_100FULL)) ?
			             SPEED_100 : SPEED_10;
			if (ecmd.speed == SPEED_100)
				ecmd.duplex = (lpa & LPA_100FULL) ?
Petko Manolov's avatar
Petko Manolov committed
822
				    DUPLEX_FULL : DUPLEX_HALF;
Petko Manolov's avatar
USB  
Petko Manolov committed
823 824
			else
				ecmd.duplex = (lpa & LPA_10FULL) ?
Petko Manolov's avatar
Petko Manolov committed
825
				    DUPLEX_FULL : DUPLEX_HALF;
Petko Manolov's avatar
USB  
Petko Manolov committed
826 827 828
		} else {
			ecmd.autoneg = AUTONEG_DISABLE;
			ecmd.speed = (bmcr & BMCR_SPEED100) ?
Petko Manolov's avatar
Petko Manolov committed
829
			    SPEED_100 : SPEED_10;
Petko Manolov's avatar
USB  
Petko Manolov committed
830
			ecmd.duplex = (bmcr & BMCR_FULLDPLX) ?
Petko Manolov's avatar
Petko Manolov committed
831
			    DUPLEX_FULL : DUPLEX_HALF;
Petko Manolov's avatar
USB  
Petko Manolov committed
832 833 834 835
		}
		if (copy_to_user(uaddr, &ecmd, sizeof(ecmd)))
			return -EFAULT;
		return 0;
Petko Manolov's avatar
Petko Manolov committed
836
		}
Petko Manolov's avatar
USB  
Petko Manolov committed
837 838
	case ETHTOOL_SSET:
		return -ENOTSUPP;
Petko Manolov's avatar
Petko Manolov committed
839 840
	case ETHTOOL_GLINK:{
		struct ethtool_value edata = { ETHTOOL_GLINK };
Petko Manolov's avatar
USB  
Petko Manolov committed
841 842 843 844 845

		edata.data = netif_carrier_ok(netdev);
		if (copy_to_user(uaddr, &edata, sizeof(edata)))
			return -EFAULT;
		return 0;
Petko Manolov's avatar
Petko Manolov committed
846
		}
Petko Manolov's avatar
USB  
Petko Manolov committed
847 848 849 850 851
	default:
		return -EOPNOTSUPP;
	}
}

Petko Manolov's avatar
Petko Manolov committed
852
static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
Petko Manolov's avatar
USB  
Petko Manolov committed
853 854
{
	rtl8150_t *dev;
Petko Manolov's avatar
Petko Manolov committed
855 856
	u16 *data;
	int res;
Petko Manolov's avatar
USB  
Petko Manolov committed
857 858

	dev = netdev->priv;
859
	data = (u16 *) & rq->ifr_ifru;
Petko Manolov's avatar
Petko Manolov committed
860
	res = 0;
Petko Manolov's avatar
USB  
Petko Manolov committed
861 862 863

	switch (cmd) {
	case SIOCETHTOOL:
Petko Manolov's avatar
Petko Manolov committed
864
		res = rtl8150_ethtool_ioctl(netdev, rq->ifr_data);
Petko Manolov's avatar
Petko Manolov committed
865
		break;
Petko Manolov's avatar
USB  
Petko Manolov committed
866 867
	case SIOCDEVPRIVATE:
		data[0] = dev->phy;
Petko Manolov's avatar
Petko Manolov committed
868
	case SIOCDEVPRIVATE + 1:
Petko Manolov's avatar
USB  
Petko Manolov committed
869
		read_mii_word(dev, dev->phy, (data[1] & 0x1f), &data[3]);
Petko Manolov's avatar
Petko Manolov committed
870
		break;
Petko Manolov's avatar
Petko Manolov committed
871
	case SIOCDEVPRIVATE + 2:
872
		if (!capable(CAP_NET_ADMIN))
Petko Manolov's avatar
USB  
Petko Manolov committed
873 874
			return -EPERM;
		write_mii_word(dev, dev->phy, (data[1] & 0x1f), data[2]);
Petko Manolov's avatar
Petko Manolov committed
875
		break;
Petko Manolov's avatar
USB  
Petko Manolov committed
876
	default:
Petko Manolov's avatar
Petko Manolov committed
877
		res = -EOPNOTSUPP;
Petko Manolov's avatar
USB  
Petko Manolov committed
878
	}
Petko Manolov's avatar
Petko Manolov committed
879

Petko Manolov's avatar
Petko Manolov committed
880
	return res;
Petko Manolov's avatar
USB  
Petko Manolov committed
881 882
}

883 884
static int rtl8150_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
Petko Manolov's avatar
USB  
Petko Manolov committed
885
{
886
	struct usb_device *udev = interface_to_usbdev(intf);
Petko Manolov's avatar
USB  
Petko Manolov committed
887 888 889 890 891
	rtl8150_t *dev;
	struct net_device *netdev;

	dev = kmalloc(sizeof(rtl8150_t), GFP_KERNEL);
	if (!dev) {
Petko Manolov's avatar
Petko Manolov committed
892
		err("Out of memory");
893
		return -ENOMEM;
Petko Manolov's avatar
USB  
Petko Manolov committed
894 895 896
	} else
		memset(dev, 0, sizeof(rtl8150_t));

897 898 899 900 901
	dev->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL);
	if (!dev->intr_buff) {
		kfree(dev);
		return -ENOMEM;
	}
902
	netdev = alloc_etherdev(0);
Petko Manolov's avatar
USB  
Petko Manolov committed
903
	if (!netdev) {
904
		kfree(dev->intr_buff);
Petko Manolov's avatar
USB  
Petko Manolov committed
905 906
		kfree(dev);
		err("Oh boy, out of memory again?!?");
907
		return -ENOMEM;
Petko Manolov's avatar
USB  
Petko Manolov committed
908
	}
Petko Manolov's avatar
Petko Manolov committed
909 910 911 912

	tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev);
	spin_lock_init(&dev->rx_pool_lock);
	
Petko Manolov's avatar
USB  
Petko Manolov committed
913 914 915 916 917 918 919 920 921 922 923
	dev->udev = udev;
	dev->netdev = netdev;
	SET_MODULE_OWNER(netdev);
	netdev->priv = dev;
	netdev->open = rtl8150_open;
	netdev->stop = rtl8150_close;
	netdev->do_ioctl = rtl8150_ioctl;
	netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
	netdev->tx_timeout = rtl8150_tx_timeout;
	netdev->hard_start_xmit = rtl8150_start_xmit;
	netdev->set_multicast_list = rtl8150_set_multicast;
Petko Manolov's avatar
Petko Manolov committed
924
	netdev->set_mac_address = rtl8150_set_mac_address;
Petko Manolov's avatar
USB  
Petko Manolov committed
925 926 927 928
	netdev->get_stats = rtl8150_netdev_stats;
	netdev->mtu = RTL8150_MTU;
	dev->intr_interval = 100;	/* 100ms */

Petko Manolov's avatar
Petko Manolov committed
929 930
	if (!alloc_all_urbs(dev)) {
		err("out of memory");
931
		goto out;
Petko Manolov's avatar
Petko Manolov committed
932 933
	}
	if (!rtl8150_reset(dev)) {
Petko Manolov's avatar
USB  
Petko Manolov committed
934
		err("couldn't reset the device");
935
		goto out1;
Petko Manolov's avatar
USB  
Petko Manolov committed
936
	}
Petko Manolov's avatar
Petko Manolov committed
937
	fill_skb_pool(dev);
Petko Manolov's avatar
USB  
Petko Manolov committed
938
	set_ethernet_addr(dev);
Petko Manolov's avatar
Petko Manolov committed
939
	info("%s: rtl8150 is detected", netdev->name);
Petko Manolov's avatar
Petko Manolov committed
940
	
941
	usb_set_intfdata(intf, dev);
942
	SET_NETDEV_DEV(netdev, &intf->dev);
943 944 945 946
	if (register_netdev(netdev) != 0) {
		err("couldn't register the device");
		goto out2;
	}
947
	return 0;
948 949 950 951 952 953 954

out2:
	usb_set_intfdata(intf, NULL);
	free_skb_pool(dev);
out1:
	free_all_urbs(dev);
out:
955
	kfree(dev->intr_buff);
956
	free_netdev(netdev);
Petko Manolov's avatar
Petko Manolov committed
957
	kfree(dev);
958
	return -EIO;
Petko Manolov's avatar
USB  
Petko Manolov committed
959 960
}

961
static void rtl8150_disconnect(struct usb_interface *intf)
Petko Manolov's avatar
USB  
Petko Manolov committed
962
{
963
	rtl8150_t *dev = usb_get_intfdata(intf);
964

965
	usb_set_intfdata(intf, NULL);
966 967 968 969 970 971 972 973
	if (dev) {
		set_bit(RTL8150_UNPLUG, &dev->flags);
		unregister_netdev(dev->netdev);
		unlink_all_urbs(dev);
		free_all_urbs(dev);
		free_skb_pool(dev);
		if (dev->rx_skb)
			dev_kfree_skb(dev->rx_skb);
974
		free_netdev(dev->netdev);
975
		kfree(dev->intr_buff);
976 977
		kfree(dev);
	}
Petko Manolov's avatar
USB  
Petko Manolov committed
978 979
}

980
static int __init usb_rtl8150_init(void)
Petko Manolov's avatar
USB  
Petko Manolov committed
981 982 983 984 985
{
	info(DRIVER_DESC " " DRIVER_VERSION);
	return usb_register(&rtl8150_driver);
}

986
static void __exit usb_rtl8150_exit(void)
Petko Manolov's avatar
USB  
Petko Manolov committed
987 988 989 990 991 992 993 994 995 996
{
	usb_deregister(&rtl8150_driver);
}

module_init(usb_rtl8150_init);
module_exit(usb_rtl8150_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");