diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/Kconfig | 29 | ||||
-rw-r--r-- | drivers/net/usb/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/usb/asix.c | 168 | ||||
-rw-r--r-- | drivers/net/usb/catc.c | 15 | ||||
-rw-r--r-- | drivers/net/usb/cdc-phonet.c | 9 | ||||
-rw-r--r-- | drivers/net/usb/cdc_eem.c | 15 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ether.c | 105 | ||||
-rw-r--r-- | drivers/net/usb/dm9601.c | 64 | ||||
-rw-r--r-- | drivers/net/usb/gl620a.c | 1 | ||||
-rw-r--r-- | drivers/net/usb/hso.c | 142 | ||||
-rw-r--r-- | drivers/net/usb/int51x1.c | 18 | ||||
-rw-r--r-- | drivers/net/usb/ipheth.c | 569 | ||||
-rw-r--r-- | drivers/net/usb/kaweth.c | 18 | ||||
-rw-r--r-- | drivers/net/usb/mcs7830.c | 259 | ||||
-rw-r--r-- | drivers/net/usb/net1080.c | 110 | ||||
-rw-r--r-- | drivers/net/usb/pegasus.c | 172 | ||||
-rw-r--r-- | drivers/net/usb/pegasus.h | 6 | ||||
-rw-r--r-- | drivers/net/usb/rndis_host.c | 35 | ||||
-rw-r--r-- | drivers/net/usb/rtl8150.c | 15 | ||||
-rw-r--r-- | drivers/net/usb/sierra_net.c | 1004 | ||||
-rw-r--r-- | drivers/net/usb/smsc75xx.c | 1289 | ||||
-rw-r--r-- | drivers/net/usb/smsc75xx.h | 421 | ||||
-rw-r--r-- | drivers/net/usb/smsc95xx.c | 279 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 449 | ||||
-rw-r--r-- | drivers/net/usb/zaurus.c | 4 |
25 files changed, 4388 insertions, 811 deletions
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 32d93564a74d..d7b7018a1de1 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -204,6 +204,14 @@ config USB_NET_DM9601 | |||
204 | This option adds support for Davicom DM9601 based USB 1.1 | 204 | This option adds support for Davicom DM9601 based USB 1.1 |
205 | 10/100 Ethernet adapters. | 205 | 10/100 Ethernet adapters. |
206 | 206 | ||
207 | config USB_NET_SMSC75XX | ||
208 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" | ||
209 | depends on USB_USBNET | ||
210 | select CRC32 | ||
211 | help | ||
212 | This option adds support for SMSC LAN95XX based USB 2.0 | ||
213 | Gigabit Ethernet adapters. | ||
214 | |||
207 | config USB_NET_SMSC95XX | 215 | config USB_NET_SMSC95XX |
208 | tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices" | 216 | tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices" |
209 | depends on USB_USBNET | 217 | depends on USB_USBNET |
@@ -377,4 +385,25 @@ config USB_CDC_PHONET | |||
377 | cellular modem, as found on most Nokia handsets with the | 385 | cellular modem, as found on most Nokia handsets with the |
378 | "PC suite" USB profile. | 386 | "PC suite" USB profile. |
379 | 387 | ||
388 | config USB_IPHETH | ||
389 | tristate "Apple iPhone USB Ethernet driver" | ||
390 | default n | ||
391 | ---help--- | ||
392 | Module used to share Internet connection (tethering) from your | ||
393 | iPhone (Original, 3G and 3GS) to your system. | ||
394 | Note that you need userspace libraries and programs that are needed | ||
395 | to pair your device with your system and that understand the iPhone | ||
396 | protocol. | ||
397 | |||
398 | For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver | ||
399 | |||
400 | config USB_SIERRA_NET | ||
401 | tristate "USB-to-WWAN Driver for Sierra Wireless modems" | ||
402 | depends on USB_USBNET | ||
403 | help | ||
404 | Choose this option if you have a Sierra Wireless USB-to-WWAN device. | ||
405 | |||
406 | To compile this driver as a module, choose M here: the | ||
407 | module will be called sierra_net. | ||
408 | |||
380 | endmenu | 409 | endmenu |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index e17afb78f372..b13a279663ba 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_USB_NET_AX8817X) += asix.o | |||
11 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o | 11 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o |
12 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o | 12 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o |
13 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o | 13 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o |
14 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o | ||
14 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o | 15 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o |
15 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o | 16 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o |
16 | obj-$(CONFIG_USB_NET_NET1080) += net1080.o | 17 | obj-$(CONFIG_USB_NET_NET1080) += net1080.o |
@@ -22,4 +23,6 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o | |||
22 | obj-$(CONFIG_USB_USBNET) += usbnet.o | 23 | obj-$(CONFIG_USB_USBNET) += usbnet.o |
23 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o | 24 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o |
24 | obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o | 25 | obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o |
26 | obj-$(CONFIG_USB_IPHETH) += ipheth.o | ||
27 | obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o | ||
25 | 28 | ||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6ce7f775bb74..35f56fc82803 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include <linux/crc32.h> | 35 | #include <linux/crc32.h> |
36 | #include <linux/usb/usbnet.h> | 36 | #include <linux/usb/usbnet.h> |
37 | #include <linux/slab.h> | ||
37 | 38 | ||
38 | #define DRIVER_VERSION "14-Jun-2006" | 39 | #define DRIVER_VERSION "14-Jun-2006" |
39 | static const char driver_name [] = "asix"; | 40 | static const char driver_name [] = "asix"; |
@@ -54,6 +55,7 @@ static const char driver_name [] = "asix"; | |||
54 | #define AX_CMD_WRITE_IPG0 0x12 | 55 | #define AX_CMD_WRITE_IPG0 0x12 |
55 | #define AX_CMD_WRITE_IPG1 0x13 | 56 | #define AX_CMD_WRITE_IPG1 0x13 |
56 | #define AX_CMD_READ_NODE_ID 0x13 | 57 | #define AX_CMD_READ_NODE_ID 0x13 |
58 | #define AX_CMD_WRITE_NODE_ID 0x14 | ||
57 | #define AX_CMD_WRITE_IPG2 0x14 | 59 | #define AX_CMD_WRITE_IPG2 0x14 |
58 | #define AX_CMD_WRITE_MULTI_FILTER 0x16 | 60 | #define AX_CMD_WRITE_MULTI_FILTER 0x16 |
59 | #define AX88172_CMD_READ_NODE_ID 0x17 | 61 | #define AX88172_CMD_READ_NODE_ID 0x17 |
@@ -165,6 +167,7 @@ static const char driver_name [] = "asix"; | |||
165 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ | 167 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ |
166 | struct asix_data { | 168 | struct asix_data { |
167 | u8 multi_filter[AX_MCAST_FILTER_SIZE]; | 169 | u8 multi_filter[AX_MCAST_FILTER_SIZE]; |
170 | u8 mac_addr[ETH_ALEN]; | ||
168 | u8 phymode; | 171 | u8 phymode; |
169 | u8 ledmode; | 172 | u8 ledmode; |
170 | u8 eeprom_len; | 173 | u8 eeprom_len; |
@@ -184,8 +187,8 @@ static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
184 | void *buf; | 187 | void *buf; |
185 | int err = -ENOMEM; | 188 | int err = -ENOMEM; |
186 | 189 | ||
187 | devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", | 190 | netdev_dbg(dev->net, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", |
188 | cmd, value, index, size); | 191 | cmd, value, index, size); |
189 | 192 | ||
190 | buf = kmalloc(size, GFP_KERNEL); | 193 | buf = kmalloc(size, GFP_KERNEL); |
191 | if (!buf) | 194 | if (!buf) |
@@ -217,8 +220,8 @@ static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
217 | void *buf = NULL; | 220 | void *buf = NULL; |
218 | int err = -ENOMEM; | 221 | int err = -ENOMEM; |
219 | 222 | ||
220 | devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", | 223 | netdev_dbg(dev->net, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", |
221 | cmd, value, index, size); | 224 | cmd, value, index, size); |
222 | 225 | ||
223 | if (data) { | 226 | if (data) { |
224 | buf = kmalloc(size, GFP_KERNEL); | 227 | buf = kmalloc(size, GFP_KERNEL); |
@@ -264,15 +267,15 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
264 | int status; | 267 | int status; |
265 | struct urb *urb; | 268 | struct urb *urb; |
266 | 269 | ||
267 | devdbg(dev,"asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d", | 270 | netdev_dbg(dev->net, "asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n", |
268 | cmd, value, index, size); | 271 | cmd, value, index, size); |
269 | if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) { | 272 | if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) { |
270 | deverr(dev, "Error allocating URB in write_cmd_async!"); | 273 | netdev_err(dev->net, "Error allocating URB in write_cmd_async!\n"); |
271 | return; | 274 | return; |
272 | } | 275 | } |
273 | 276 | ||
274 | if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) { | 277 | if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) { |
275 | deverr(dev, "Failed to allocate memory for control request"); | 278 | netdev_err(dev->net, "Failed to allocate memory for control request\n"); |
276 | usb_free_urb(urb); | 279 | usb_free_urb(urb); |
277 | return; | 280 | return; |
278 | } | 281 | } |
@@ -289,8 +292,8 @@ asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | |||
289 | asix_async_cmd_callback, req); | 292 | asix_async_cmd_callback, req); |
290 | 293 | ||
291 | if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { | 294 | if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { |
292 | deverr(dev, "Error submitting the control message: status=%d", | 295 | netdev_err(dev->net, "Error submitting the control message: status=%d\n", |
293 | status); | 296 | status); |
294 | kfree(req); | 297 | kfree(req); |
295 | usb_free_urb(urb); | 298 | usb_free_urb(urb); |
296 | } | 299 | } |
@@ -314,7 +317,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
314 | while (skb->len > 0) { | 317 | while (skb->len > 0) { |
315 | if ((short)(header & 0x0000ffff) != | 318 | if ((short)(header & 0x0000ffff) != |
316 | ~((short)((header & 0xffff0000) >> 16))) { | 319 | ~((short)((header & 0xffff0000) >> 16))) { |
317 | deverr(dev,"asix_rx_fixup() Bad Header Length"); | 320 | netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n"); |
318 | } | 321 | } |
319 | /* get the packet length */ | 322 | /* get the packet length */ |
320 | size = (u16) (header & 0x0000ffff); | 323 | size = (u16) (header & 0x0000ffff); |
@@ -322,7 +325,8 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
322 | if ((skb->len) - ((size + 1) & 0xfffe) == 0) | 325 | if ((skb->len) - ((size + 1) & 0xfffe) == 0) |
323 | return 2; | 326 | return 2; |
324 | if (size > ETH_FRAME_LEN) { | 327 | if (size > ETH_FRAME_LEN) { |
325 | deverr(dev,"asix_rx_fixup() Bad RX Length %d", size); | 328 | netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n", |
329 | size); | ||
326 | return 0; | 330 | return 0; |
327 | } | 331 | } |
328 | ax_skb = skb_clone(skb, GFP_ATOMIC); | 332 | ax_skb = skb_clone(skb, GFP_ATOMIC); |
@@ -348,7 +352,8 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
348 | } | 352 | } |
349 | 353 | ||
350 | if (skb->len < 0) { | 354 | if (skb->len < 0) { |
351 | deverr(dev,"asix_rx_fixup() Bad SKB Length %d", skb->len); | 355 | netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n", |
356 | skb->len); | ||
352 | return 0; | 357 | return 0; |
353 | } | 358 | } |
354 | return 1; | 359 | return 1; |
@@ -365,8 +370,8 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
365 | 370 | ||
366 | padlen = ((skb->len + 4) % 512) ? 0 : 4; | 371 | padlen = ((skb->len + 4) % 512) ? 0 : 4; |
367 | 372 | ||
368 | if ((!skb_cloned(skb)) | 373 | if ((!skb_cloned(skb)) && |
369 | && ((headroom + tailroom) >= (4 + padlen))) { | 374 | ((headroom + tailroom) >= (4 + padlen))) { |
370 | if ((headroom < 4) || (tailroom < padlen)) { | 375 | if ((headroom < 4) || (tailroom < padlen)) { |
371 | skb->data = memmove(skb->head + 4, skb->data, skb->len); | 376 | skb->data = memmove(skb->head + 4, skb->data, skb->len); |
372 | skb_set_tail_pointer(skb, skb->len); | 377 | skb_set_tail_pointer(skb, skb->len); |
@@ -409,7 +414,7 @@ static void asix_status(struct usbnet *dev, struct urb *urb) | |||
409 | usbnet_defer_kevent (dev, EVENT_LINK_RESET ); | 414 | usbnet_defer_kevent (dev, EVENT_LINK_RESET ); |
410 | } else | 415 | } else |
411 | netif_carrier_off(dev->net); | 416 | netif_carrier_off(dev->net); |
412 | devdbg(dev, "Link Status is: %d", link); | 417 | netdev_dbg(dev->net, "Link Status is: %d\n", link); |
413 | } | 418 | } |
414 | } | 419 | } |
415 | 420 | ||
@@ -418,7 +423,7 @@ static inline int asix_set_sw_mii(struct usbnet *dev) | |||
418 | int ret; | 423 | int ret; |
419 | ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); | 424 | ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); |
420 | if (ret < 0) | 425 | if (ret < 0) |
421 | deverr(dev, "Failed to enable software MII access"); | 426 | netdev_err(dev->net, "Failed to enable software MII access\n"); |
422 | return ret; | 427 | return ret; |
423 | } | 428 | } |
424 | 429 | ||
@@ -427,7 +432,7 @@ static inline int asix_set_hw_mii(struct usbnet *dev) | |||
427 | int ret; | 432 | int ret; |
428 | ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); | 433 | ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); |
429 | if (ret < 0) | 434 | if (ret < 0) |
430 | deverr(dev, "Failed to enable hardware MII access"); | 435 | netdev_err(dev->net, "Failed to enable hardware MII access\n"); |
431 | return ret; | 436 | return ret; |
432 | } | 437 | } |
433 | 438 | ||
@@ -436,13 +441,14 @@ static inline int asix_get_phy_addr(struct usbnet *dev) | |||
436 | u8 buf[2]; | 441 | u8 buf[2]; |
437 | int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); | 442 | int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); |
438 | 443 | ||
439 | devdbg(dev, "asix_get_phy_addr()"); | 444 | netdev_dbg(dev->net, "asix_get_phy_addr()\n"); |
440 | 445 | ||
441 | if (ret < 0) { | 446 | if (ret < 0) { |
442 | deverr(dev, "Error reading PHYID register: %02x", ret); | 447 | netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret); |
443 | goto out; | 448 | goto out; |
444 | } | 449 | } |
445 | devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((__le16 *)buf)); | 450 | netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n", |
451 | *((__le16 *)buf)); | ||
446 | ret = buf[1]; | 452 | ret = buf[1]; |
447 | 453 | ||
448 | out: | 454 | out: |
@@ -455,7 +461,7 @@ static int asix_sw_reset(struct usbnet *dev, u8 flags) | |||
455 | 461 | ||
456 | ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); | 462 | ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL); |
457 | if (ret < 0) | 463 | if (ret < 0) |
458 | deverr(dev,"Failed to send software reset: %02x", ret); | 464 | netdev_err(dev->net, "Failed to send software reset: %02x\n", ret); |
459 | 465 | ||
460 | return ret; | 466 | return ret; |
461 | } | 467 | } |
@@ -466,7 +472,7 @@ static u16 asix_read_rx_ctl(struct usbnet *dev) | |||
466 | int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); | 472 | int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); |
467 | 473 | ||
468 | if (ret < 0) { | 474 | if (ret < 0) { |
469 | deverr(dev, "Error reading RX_CTL register: %02x", ret); | 475 | netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret); |
470 | goto out; | 476 | goto out; |
471 | } | 477 | } |
472 | ret = le16_to_cpu(v); | 478 | ret = le16_to_cpu(v); |
@@ -478,11 +484,11 @@ static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) | |||
478 | { | 484 | { |
479 | int ret; | 485 | int ret; |
480 | 486 | ||
481 | devdbg(dev,"asix_write_rx_ctl() - mode = 0x%04x", mode); | 487 | netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode); |
482 | ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); | 488 | ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); |
483 | if (ret < 0) | 489 | if (ret < 0) |
484 | deverr(dev, "Failed to write RX_CTL mode to 0x%04x: %02x", | 490 | netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n", |
485 | mode, ret); | 491 | mode, ret); |
486 | 492 | ||
487 | return ret; | 493 | return ret; |
488 | } | 494 | } |
@@ -493,7 +499,8 @@ static u16 asix_read_medium_status(struct usbnet *dev) | |||
493 | int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); | 499 | int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); |
494 | 500 | ||
495 | if (ret < 0) { | 501 | if (ret < 0) { |
496 | deverr(dev, "Error reading Medium Status register: %02x", ret); | 502 | netdev_err(dev->net, "Error reading Medium Status register: %02x\n", |
503 | ret); | ||
497 | goto out; | 504 | goto out; |
498 | } | 505 | } |
499 | ret = le16_to_cpu(v); | 506 | ret = le16_to_cpu(v); |
@@ -505,11 +512,11 @@ static int asix_write_medium_mode(struct usbnet *dev, u16 mode) | |||
505 | { | 512 | { |
506 | int ret; | 513 | int ret; |
507 | 514 | ||
508 | devdbg(dev,"asix_write_medium_mode() - mode = 0x%04x", mode); | 515 | netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode); |
509 | ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); | 516 | ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); |
510 | if (ret < 0) | 517 | if (ret < 0) |
511 | deverr(dev, "Failed to write Medium Mode mode to 0x%04x: %02x", | 518 | netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n", |
512 | mode, ret); | 519 | mode, ret); |
513 | 520 | ||
514 | return ret; | 521 | return ret; |
515 | } | 522 | } |
@@ -518,11 +525,11 @@ static int asix_write_gpio(struct usbnet *dev, u16 value, int sleep) | |||
518 | { | 525 | { |
519 | int ret; | 526 | int ret; |
520 | 527 | ||
521 | devdbg(dev,"asix_write_gpio() - value = 0x%04x", value); | 528 | netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value); |
522 | ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL); | 529 | ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL); |
523 | if (ret < 0) | 530 | if (ret < 0) |
524 | deverr(dev, "Failed to write GPIO value 0x%04x: %02x", | 531 | netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n", |
525 | value, ret); | 532 | value, ret); |
526 | 533 | ||
527 | if (sleep) | 534 | if (sleep) |
528 | msleep(sleep); | 535 | msleep(sleep); |
@@ -541,30 +548,28 @@ static void asix_set_multicast(struct net_device *net) | |||
541 | 548 | ||
542 | if (net->flags & IFF_PROMISC) { | 549 | if (net->flags & IFF_PROMISC) { |
543 | rx_ctl |= AX_RX_CTL_PRO; | 550 | rx_ctl |= AX_RX_CTL_PRO; |
544 | } else if (net->flags & IFF_ALLMULTI | 551 | } else if (net->flags & IFF_ALLMULTI || |
545 | || net->mc_count > AX_MAX_MCAST) { | 552 | netdev_mc_count(net) > AX_MAX_MCAST) { |
546 | rx_ctl |= AX_RX_CTL_AMALL; | 553 | rx_ctl |= AX_RX_CTL_AMALL; |
547 | } else if (net->mc_count == 0) { | 554 | } else if (netdev_mc_empty(net)) { |
548 | /* just broadcast and directed */ | 555 | /* just broadcast and directed */ |
549 | } else { | 556 | } else { |
550 | /* We use the 20 byte dev->data | 557 | /* We use the 20 byte dev->data |
551 | * for our 8 byte filter buffer | 558 | * for our 8 byte filter buffer |
552 | * to avoid allocating memory that | 559 | * to avoid allocating memory that |
553 | * is tricky to free later */ | 560 | * is tricky to free later */ |
554 | struct dev_mc_list *mc_list = net->mc_list; | 561 | struct dev_mc_list *mc_list; |
555 | u32 crc_bits; | 562 | u32 crc_bits; |
556 | int i; | ||
557 | 563 | ||
558 | memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); | 564 | memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); |
559 | 565 | ||
560 | /* Build the multicast hash filter. */ | 566 | /* Build the multicast hash filter. */ |
561 | for (i = 0; i < net->mc_count; i++) { | 567 | netdev_for_each_mc_addr(mc_list, net) { |
562 | crc_bits = | 568 | crc_bits = |
563 | ether_crc(ETH_ALEN, | 569 | ether_crc(ETH_ALEN, |
564 | mc_list->dmi_addr) >> 26; | 570 | mc_list->dmi_addr) >> 26; |
565 | data->multi_filter[crc_bits >> 3] |= | 571 | data->multi_filter[crc_bits >> 3] |= |
566 | 1 << (crc_bits & 7); | 572 | 1 << (crc_bits & 7); |
567 | mc_list = mc_list->next; | ||
568 | } | 573 | } |
569 | 574 | ||
570 | asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, | 575 | asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, |
@@ -588,7 +593,8 @@ static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) | |||
588 | asix_set_hw_mii(dev); | 593 | asix_set_hw_mii(dev); |
589 | mutex_unlock(&dev->phy_mutex); | 594 | mutex_unlock(&dev->phy_mutex); |
590 | 595 | ||
591 | devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res)); | 596 | netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", |
597 | phy_id, loc, le16_to_cpu(res)); | ||
592 | 598 | ||
593 | return le16_to_cpu(res); | 599 | return le16_to_cpu(res); |
594 | } | 600 | } |
@@ -599,7 +605,8 @@ asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) | |||
599 | struct usbnet *dev = netdev_priv(netdev); | 605 | struct usbnet *dev = netdev_priv(netdev); |
600 | __le16 res = cpu_to_le16(val); | 606 | __le16 res = cpu_to_le16(val); |
601 | 607 | ||
602 | devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); | 608 | netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", |
609 | phy_id, loc, val); | ||
603 | mutex_lock(&dev->phy_mutex); | 610 | mutex_lock(&dev->phy_mutex); |
604 | asix_set_sw_mii(dev); | 611 | asix_set_sw_mii(dev); |
605 | asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); | 612 | asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); |
@@ -728,6 +735,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) | |||
728 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | 735 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); |
729 | } | 736 | } |
730 | 737 | ||
738 | static int asix_set_mac_address(struct net_device *net, void *p) | ||
739 | { | ||
740 | struct usbnet *dev = netdev_priv(net); | ||
741 | struct asix_data *data = (struct asix_data *)&dev->data; | ||
742 | struct sockaddr *addr = p; | ||
743 | |||
744 | if (netif_running(net)) | ||
745 | return -EBUSY; | ||
746 | if (!is_valid_ether_addr(addr->sa_data)) | ||
747 | return -EADDRNOTAVAIL; | ||
748 | |||
749 | memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); | ||
750 | |||
751 | /* We use the 20 byte dev->data | ||
752 | * for our 6 byte mac buffer | ||
753 | * to avoid allocating memory that | ||
754 | * is tricky to free later */ | ||
755 | memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); | ||
756 | asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
757 | data->mac_addr); | ||
758 | |||
759 | return 0; | ||
760 | } | ||
761 | |||
731 | /* We need to override some ethtool_ops so we require our | 762 | /* We need to override some ethtool_ops so we require our |
732 | own structure so we don't interfere with other usbnet | 763 | own structure so we don't interfere with other usbnet |
733 | devices that may be connected at the same time. */ | 764 | devices that may be connected at the same time. */ |
@@ -753,30 +784,28 @@ static void ax88172_set_multicast(struct net_device *net) | |||
753 | 784 | ||
754 | if (net->flags & IFF_PROMISC) { | 785 | if (net->flags & IFF_PROMISC) { |
755 | rx_ctl |= 0x01; | 786 | rx_ctl |= 0x01; |
756 | } else if (net->flags & IFF_ALLMULTI | 787 | } else if (net->flags & IFF_ALLMULTI || |
757 | || net->mc_count > AX_MAX_MCAST) { | 788 | netdev_mc_count(net) > AX_MAX_MCAST) { |
758 | rx_ctl |= 0x02; | 789 | rx_ctl |= 0x02; |
759 | } else if (net->mc_count == 0) { | 790 | } else if (netdev_mc_empty(net)) { |
760 | /* just broadcast and directed */ | 791 | /* just broadcast and directed */ |
761 | } else { | 792 | } else { |
762 | /* We use the 20 byte dev->data | 793 | /* We use the 20 byte dev->data |
763 | * for our 8 byte filter buffer | 794 | * for our 8 byte filter buffer |
764 | * to avoid allocating memory that | 795 | * to avoid allocating memory that |
765 | * is tricky to free later */ | 796 | * is tricky to free later */ |
766 | struct dev_mc_list *mc_list = net->mc_list; | 797 | struct dev_mc_list *mc_list; |
767 | u32 crc_bits; | 798 | u32 crc_bits; |
768 | int i; | ||
769 | 799 | ||
770 | memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); | 800 | memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); |
771 | 801 | ||
772 | /* Build the multicast hash filter. */ | 802 | /* Build the multicast hash filter. */ |
773 | for (i = 0; i < net->mc_count; i++) { | 803 | netdev_for_each_mc_addr(mc_list, net) { |
774 | crc_bits = | 804 | crc_bits = |
775 | ether_crc(ETH_ALEN, | 805 | ether_crc(ETH_ALEN, |
776 | mc_list->dmi_addr) >> 26; | 806 | mc_list->dmi_addr) >> 26; |
777 | data->multi_filter[crc_bits >> 3] |= | 807 | data->multi_filter[crc_bits >> 3] |= |
778 | 1 << (crc_bits & 7); | 808 | 1 << (crc_bits & 7); |
779 | mc_list = mc_list->next; | ||
780 | } | 809 | } |
781 | 810 | ||
782 | asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, | 811 | asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, |
@@ -800,7 +829,8 @@ static int ax88172_link_reset(struct usbnet *dev) | |||
800 | if (ecmd.duplex != DUPLEX_FULL) | 829 | if (ecmd.duplex != DUPLEX_FULL) |
801 | mode |= ~AX88172_MEDIUM_FD; | 830 | mode |= ~AX88172_MEDIUM_FD; |
802 | 831 | ||
803 | devdbg(dev, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode); | 832 | netdev_dbg(dev->net, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n", |
833 | ecmd.speed, ecmd.duplex, mode); | ||
804 | 834 | ||
805 | asix_write_medium_mode(dev, mode); | 835 | asix_write_medium_mode(dev, mode); |
806 | 836 | ||
@@ -902,7 +932,8 @@ static int ax88772_link_reset(struct usbnet *dev) | |||
902 | if (ecmd.duplex != DUPLEX_FULL) | 932 | if (ecmd.duplex != DUPLEX_FULL) |
903 | mode &= ~AX_MEDIUM_FD; | 933 | mode &= ~AX_MEDIUM_FD; |
904 | 934 | ||
905 | devdbg(dev, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode); | 935 | netdev_dbg(dev->net, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n", |
936 | ecmd.speed, ecmd.duplex, mode); | ||
906 | 937 | ||
907 | asix_write_medium_mode(dev, mode); | 938 | asix_write_medium_mode(dev, mode); |
908 | 939 | ||
@@ -915,7 +946,7 @@ static const struct net_device_ops ax88772_netdev_ops = { | |||
915 | .ndo_start_xmit = usbnet_start_xmit, | 946 | .ndo_start_xmit = usbnet_start_xmit, |
916 | .ndo_tx_timeout = usbnet_tx_timeout, | 947 | .ndo_tx_timeout = usbnet_tx_timeout, |
917 | .ndo_change_mtu = usbnet_change_mtu, | 948 | .ndo_change_mtu = usbnet_change_mtu, |
918 | .ndo_set_mac_address = eth_mac_addr, | 949 | .ndo_set_mac_address = asix_set_mac_address, |
919 | .ndo_validate_addr = eth_validate_addr, | 950 | .ndo_validate_addr = eth_validate_addr, |
920 | .ndo_do_ioctl = asix_ioctl, | 951 | .ndo_do_ioctl = asix_ioctl, |
921 | .ndo_set_multicast_list = asix_set_multicast, | 952 | .ndo_set_multicast_list = asix_set_multicast, |
@@ -1059,10 +1090,10 @@ static int marvell_phy_init(struct usbnet *dev) | |||
1059 | struct asix_data *data = (struct asix_data *)&dev->data; | 1090 | struct asix_data *data = (struct asix_data *)&dev->data; |
1060 | u16 reg; | 1091 | u16 reg; |
1061 | 1092 | ||
1062 | devdbg(dev,"marvell_phy_init()"); | 1093 | netdev_dbg(dev->net, "marvell_phy_init()\n"); |
1063 | 1094 | ||
1064 | reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_MARVELL_STATUS); | 1095 | reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_MARVELL_STATUS); |
1065 | devdbg(dev,"MII_MARVELL_STATUS = 0x%04x", reg); | 1096 | netdev_dbg(dev->net, "MII_MARVELL_STATUS = 0x%04x\n", reg); |
1066 | 1097 | ||
1067 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_MARVELL_CTRL, | 1098 | asix_mdio_write(dev->net, dev->mii.phy_id, MII_MARVELL_CTRL, |
1068 | MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY); | 1099 | MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY); |
@@ -1070,7 +1101,7 @@ static int marvell_phy_init(struct usbnet *dev) | |||
1070 | if (data->ledmode) { | 1101 | if (data->ledmode) { |
1071 | reg = asix_mdio_read(dev->net, dev->mii.phy_id, | 1102 | reg = asix_mdio_read(dev->net, dev->mii.phy_id, |
1072 | MII_MARVELL_LED_CTRL); | 1103 | MII_MARVELL_LED_CTRL); |
1073 | devdbg(dev,"MII_MARVELL_LED_CTRL (1) = 0x%04x", reg); | 1104 | netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (1) = 0x%04x\n", reg); |
1074 | 1105 | ||
1075 | reg &= 0xf8ff; | 1106 | reg &= 0xf8ff; |
1076 | reg |= (1 + 0x0100); | 1107 | reg |= (1 + 0x0100); |
@@ -1079,7 +1110,7 @@ static int marvell_phy_init(struct usbnet *dev) | |||
1079 | 1110 | ||
1080 | reg = asix_mdio_read(dev->net, dev->mii.phy_id, | 1111 | reg = asix_mdio_read(dev->net, dev->mii.phy_id, |
1081 | MII_MARVELL_LED_CTRL); | 1112 | MII_MARVELL_LED_CTRL); |
1082 | devdbg(dev,"MII_MARVELL_LED_CTRL (2) = 0x%04x", reg); | 1113 | netdev_dbg(dev->net, "MII_MARVELL_LED_CTRL (2) = 0x%04x\n", reg); |
1083 | reg &= 0xfc0f; | 1114 | reg &= 0xfc0f; |
1084 | } | 1115 | } |
1085 | 1116 | ||
@@ -1090,7 +1121,7 @@ static int marvell_led_status(struct usbnet *dev, u16 speed) | |||
1090 | { | 1121 | { |
1091 | u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL); | 1122 | u16 reg = asix_mdio_read(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL); |
1092 | 1123 | ||
1093 | devdbg(dev, "marvell_led_status() read 0x%04x", reg); | 1124 | netdev_dbg(dev->net, "marvell_led_status() read 0x%04x\n", reg); |
1094 | 1125 | ||
1095 | /* Clear out the center LED bits - 0x03F0 */ | 1126 | /* Clear out the center LED bits - 0x03F0 */ |
1096 | reg &= 0xfc0f; | 1127 | reg &= 0xfc0f; |
@@ -1106,7 +1137,7 @@ static int marvell_led_status(struct usbnet *dev, u16 speed) | |||
1106 | reg |= 0x02f0; | 1137 | reg |= 0x02f0; |
1107 | } | 1138 | } |
1108 | 1139 | ||
1109 | devdbg(dev, "marvell_led_status() writing 0x%04x", reg); | 1140 | netdev_dbg(dev->net, "marvell_led_status() writing 0x%04x\n", reg); |
1110 | asix_mdio_write(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL, reg); | 1141 | asix_mdio_write(dev->net, dev->mii.phy_id, MARVELL_LED_MANUAL, reg); |
1111 | 1142 | ||
1112 | return 0; | 1143 | return 0; |
@@ -1118,7 +1149,7 @@ static int ax88178_link_reset(struct usbnet *dev) | |||
1118 | struct ethtool_cmd ecmd; | 1149 | struct ethtool_cmd ecmd; |
1119 | struct asix_data *data = (struct asix_data *)&dev->data; | 1150 | struct asix_data *data = (struct asix_data *)&dev->data; |
1120 | 1151 | ||
1121 | devdbg(dev,"ax88178_link_reset()"); | 1152 | netdev_dbg(dev->net, "ax88178_link_reset()\n"); |
1122 | 1153 | ||
1123 | mii_check_media(&dev->mii, 1, 1); | 1154 | mii_check_media(&dev->mii, 1, 1); |
1124 | mii_ethtool_gset(&dev->mii, &ecmd); | 1155 | mii_ethtool_gset(&dev->mii, &ecmd); |
@@ -1138,7 +1169,8 @@ static int ax88178_link_reset(struct usbnet *dev) | |||
1138 | else | 1169 | else |
1139 | mode &= ~AX_MEDIUM_FD; | 1170 | mode &= ~AX_MEDIUM_FD; |
1140 | 1171 | ||
1141 | devdbg(dev, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x", ecmd.speed, ecmd.duplex, mode); | 1172 | netdev_dbg(dev->net, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n", |
1173 | ecmd.speed, ecmd.duplex, mode); | ||
1142 | 1174 | ||
1143 | asix_write_medium_mode(dev, mode); | 1175 | asix_write_medium_mode(dev, mode); |
1144 | 1176 | ||
@@ -1188,7 +1220,7 @@ static int ax88178_change_mtu(struct net_device *net, int new_mtu) | |||
1188 | struct usbnet *dev = netdev_priv(net); | 1220 | struct usbnet *dev = netdev_priv(net); |
1189 | int ll_mtu = new_mtu + net->hard_header_len + 4; | 1221 | int ll_mtu = new_mtu + net->hard_header_len + 4; |
1190 | 1222 | ||
1191 | devdbg(dev, "ax88178_change_mtu() new_mtu=%d", new_mtu); | 1223 | netdev_dbg(dev->net, "ax88178_change_mtu() new_mtu=%d\n", new_mtu); |
1192 | 1224 | ||
1193 | if (new_mtu <= 0 || ll_mtu > 16384) | 1225 | if (new_mtu <= 0 || ll_mtu > 16384) |
1194 | return -EINVAL; | 1226 | return -EINVAL; |
@@ -1208,7 +1240,7 @@ static const struct net_device_ops ax88178_netdev_ops = { | |||
1208 | .ndo_stop = usbnet_stop, | 1240 | .ndo_stop = usbnet_stop, |
1209 | .ndo_start_xmit = usbnet_start_xmit, | 1241 | .ndo_start_xmit = usbnet_start_xmit, |
1210 | .ndo_tx_timeout = usbnet_tx_timeout, | 1242 | .ndo_tx_timeout = usbnet_tx_timeout, |
1211 | .ndo_set_mac_address = eth_mac_addr, | 1243 | .ndo_set_mac_address = asix_set_mac_address, |
1212 | .ndo_validate_addr = eth_validate_addr, | 1244 | .ndo_validate_addr = eth_validate_addr, |
1213 | .ndo_set_multicast_list = asix_set_multicast, | 1245 | .ndo_set_multicast_list = asix_set_multicast, |
1214 | .ndo_do_ioctl = asix_ioctl, | 1246 | .ndo_do_ioctl = asix_ioctl, |
@@ -1327,7 +1359,7 @@ static const struct driver_info ax8817x_info = { | |||
1327 | .status = asix_status, | 1359 | .status = asix_status, |
1328 | .link_reset = ax88172_link_reset, | 1360 | .link_reset = ax88172_link_reset, |
1329 | .reset = ax88172_link_reset, | 1361 | .reset = ax88172_link_reset, |
1330 | .flags = FLAG_ETHER, | 1362 | .flags = FLAG_ETHER | FLAG_LINK_INTR, |
1331 | .data = 0x00130103, | 1363 | .data = 0x00130103, |
1332 | }; | 1364 | }; |
1333 | 1365 | ||
@@ -1337,7 +1369,7 @@ static const struct driver_info dlink_dub_e100_info = { | |||
1337 | .status = asix_status, | 1369 | .status = asix_status, |
1338 | .link_reset = ax88172_link_reset, | 1370 | .link_reset = ax88172_link_reset, |
1339 | .reset = ax88172_link_reset, | 1371 | .reset = ax88172_link_reset, |
1340 | .flags = FLAG_ETHER, | 1372 | .flags = FLAG_ETHER | FLAG_LINK_INTR, |
1341 | .data = 0x009f9d9f, | 1373 | .data = 0x009f9d9f, |
1342 | }; | 1374 | }; |
1343 | 1375 | ||
@@ -1347,7 +1379,7 @@ static const struct driver_info netgear_fa120_info = { | |||
1347 | .status = asix_status, | 1379 | .status = asix_status, |
1348 | .link_reset = ax88172_link_reset, | 1380 | .link_reset = ax88172_link_reset, |
1349 | .reset = ax88172_link_reset, | 1381 | .reset = ax88172_link_reset, |
1350 | .flags = FLAG_ETHER, | 1382 | .flags = FLAG_ETHER | FLAG_LINK_INTR, |
1351 | .data = 0x00130103, | 1383 | .data = 0x00130103, |
1352 | }; | 1384 | }; |
1353 | 1385 | ||
@@ -1357,7 +1389,7 @@ static const struct driver_info hawking_uf200_info = { | |||
1357 | .status = asix_status, | 1389 | .status = asix_status, |
1358 | .link_reset = ax88172_link_reset, | 1390 | .link_reset = ax88172_link_reset, |
1359 | .reset = ax88172_link_reset, | 1391 | .reset = ax88172_link_reset, |
1360 | .flags = FLAG_ETHER, | 1392 | .flags = FLAG_ETHER | FLAG_LINK_INTR, |
1361 | .data = 0x001f1d1f, | 1393 | .data = 0x001f1d1f, |
1362 | }; | 1394 | }; |
1363 | 1395 | ||
@@ -1367,7 +1399,7 @@ static const struct driver_info ax88772_info = { | |||
1367 | .status = asix_status, | 1399 | .status = asix_status, |
1368 | .link_reset = ax88772_link_reset, | 1400 | .link_reset = ax88772_link_reset, |
1369 | .reset = ax88772_link_reset, | 1401 | .reset = ax88772_link_reset, |
1370 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1402 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, |
1371 | .rx_fixup = asix_rx_fixup, | 1403 | .rx_fixup = asix_rx_fixup, |
1372 | .tx_fixup = asix_tx_fixup, | 1404 | .tx_fixup = asix_tx_fixup, |
1373 | }; | 1405 | }; |
@@ -1378,7 +1410,7 @@ static const struct driver_info ax88178_info = { | |||
1378 | .status = asix_status, | 1410 | .status = asix_status, |
1379 | .link_reset = ax88178_link_reset, | 1411 | .link_reset = ax88178_link_reset, |
1380 | .reset = ax88178_link_reset, | 1412 | .reset = ax88178_link_reset, |
1381 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | 1413 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, |
1382 | .rx_fixup = asix_rx_fixup, | 1414 | .rx_fixup = asix_rx_fixup, |
1383 | .tx_fixup = asix_tx_fixup, | 1415 | .tx_fixup = asix_tx_fixup, |
1384 | }; | 1416 | }; |
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 2bed6b087d16..602e123b2741 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/string.h> | 38 | #include <linux/string.h> |
39 | #include <linux/slab.h> | ||
40 | #include <linux/netdevice.h> | 39 | #include <linux/netdevice.h> |
41 | #include <linux/etherdevice.h> | 40 | #include <linux/etherdevice.h> |
42 | #include <linux/skbuff.h> | 41 | #include <linux/skbuff.h> |
@@ -44,6 +43,7 @@ | |||
44 | #include <linux/ethtool.h> | 43 | #include <linux/ethtool.h> |
45 | #include <linux/crc32.h> | 44 | #include <linux/crc32.h> |
46 | #include <linux/bitops.h> | 45 | #include <linux/bitops.h> |
46 | #include <linux/gfp.h> | ||
47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
48 | 48 | ||
49 | #undef DEBUG | 49 | #undef DEBUG |
@@ -436,8 +436,8 @@ static netdev_tx_t catc_start_xmit(struct sk_buff *skb, | |||
436 | clear_bit(TX_RUNNING, &catc->flags); | 436 | clear_bit(TX_RUNNING, &catc->flags); |
437 | } | 437 | } |
438 | 438 | ||
439 | if ((catc->is_f5u011 && catc->tx_ptr) | 439 | if ((catc->is_f5u011 && catc->tx_ptr) || |
440 | || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) | 440 | (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) |
441 | netif_stop_queue(netdev); | 441 | netif_stop_queue(netdev); |
442 | 442 | ||
443 | spin_unlock_irqrestore(&catc->tx_lock, flags); | 443 | spin_unlock_irqrestore(&catc->tx_lock, flags); |
@@ -632,7 +632,6 @@ static void catc_set_multicast_list(struct net_device *netdev) | |||
632 | struct dev_mc_list *mc; | 632 | struct dev_mc_list *mc; |
633 | u8 broadcast[6]; | 633 | u8 broadcast[6]; |
634 | u8 rx = RxEnable | RxPolarity | RxMultiCast; | 634 | u8 rx = RxEnable | RxPolarity | RxMultiCast; |
635 | int i; | ||
636 | 635 | ||
637 | memset(broadcast, 0xff, 6); | 636 | memset(broadcast, 0xff, 6); |
638 | memset(catc->multicast, 0, 64); | 637 | memset(catc->multicast, 0, 64); |
@@ -648,7 +647,7 @@ static void catc_set_multicast_list(struct net_device *netdev) | |||
648 | if (netdev->flags & IFF_ALLMULTI) { | 647 | if (netdev->flags & IFF_ALLMULTI) { |
649 | memset(catc->multicast, 0xff, 64); | 648 | memset(catc->multicast, 0xff, 64); |
650 | } else { | 649 | } else { |
651 | for (i = 0, mc = netdev->mc_list; mc && i < netdev->mc_count; i++, mc = mc->next) { | 650 | netdev_for_each_mc_addr(mc, netdev) { |
652 | u32 crc = ether_crc_le(6, mc->dmi_addr); | 651 | u32 crc = ether_crc_le(6, mc->dmi_addr); |
653 | if (!catc->is_f5u011) { | 652 | if (!catc->is_f5u011) { |
654 | catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7); | 653 | catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7); |
@@ -897,11 +896,9 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
897 | f5u011_rxmode(catc, catc->rxmode); | 896 | f5u011_rxmode(catc, catc->rxmode); |
898 | } | 897 | } |
899 | dbg("Init done."); | 898 | dbg("Init done."); |
900 | printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, ", | 899 | printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, %pM.\n", |
901 | netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate", | 900 | netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate", |
902 | usbdev->bus->bus_name, usbdev->devpath); | 901 | usbdev->bus->bus_name, usbdev->devpath, netdev->dev_addr); |
903 | for (i = 0; i < 5; i++) printk("%2.2x:", netdev->dev_addr[i]); | ||
904 | printk("%2.2x.\n", netdev->dev_addr[i]); | ||
905 | usb_set_intfdata(intf, catc); | 902 | usb_set_intfdata(intf, catc); |
906 | 903 | ||
907 | SET_NETDEV_DEV(netdev, &intf->dev); | 904 | SET_NETDEV_DEV(netdev, &intf->dev); |
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 33d5c579c5ad..dc9444525b49 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/gfp.h> | ||
25 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
26 | #include <linux/usb/cdc.h> | 27 | #include <linux/usb/cdc.h> |
27 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
@@ -372,12 +373,12 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
372 | /* Data interface has one inactive and one active setting */ | 373 | /* Data interface has one inactive and one active setting */ |
373 | if (data_intf->num_altsetting != 2) | 374 | if (data_intf->num_altsetting != 2) |
374 | return -EINVAL; | 375 | return -EINVAL; |
375 | if (data_intf->altsetting[0].desc.bNumEndpoints == 0 | 376 | if (data_intf->altsetting[0].desc.bNumEndpoints == 0 && |
376 | && data_intf->altsetting[1].desc.bNumEndpoints == 2) | 377 | data_intf->altsetting[1].desc.bNumEndpoints == 2) |
377 | data_desc = data_intf->altsetting + 1; | 378 | data_desc = data_intf->altsetting + 1; |
378 | else | 379 | else |
379 | if (data_intf->altsetting[0].desc.bNumEndpoints == 2 | 380 | if (data_intf->altsetting[0].desc.bNumEndpoints == 2 && |
380 | && data_intf->altsetting[1].desc.bNumEndpoints == 0) | 381 | data_intf->altsetting[1].desc.bNumEndpoints == 0) |
381 | data_desc = data_intf->altsetting; | 382 | data_desc = data_intf->altsetting; |
382 | else | 383 | else |
383 | return -EINVAL; | 384 | return -EINVAL; |
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 23300656c266..5f3b97668e63 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/crc32.h> | 30 | #include <linux/crc32.h> |
31 | #include <linux/usb/cdc.h> | 31 | #include <linux/usb/cdc.h> |
32 | #include <linux/usb/usbnet.h> | 32 | #include <linux/usb/usbnet.h> |
33 | #include <linux/gfp.h> | ||
33 | 34 | ||
34 | 35 | ||
35 | /* | 36 | /* |
@@ -73,7 +74,7 @@ static void eem_linkcmd(struct usbnet *dev, struct sk_buff *skb) | |||
73 | usb_free_urb(urb); | 74 | usb_free_urb(urb); |
74 | fail: | 75 | fail: |
75 | dev_kfree_skb(skb); | 76 | dev_kfree_skb(skb); |
76 | devwarn(dev, "link cmd failure\n"); | 77 | netdev_warn(dev->net, "link cmd failure\n"); |
77 | return; | 78 | return; |
78 | } | 79 | } |
79 | } | 80 | } |
@@ -121,8 +122,8 @@ static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
121 | int headroom = skb_headroom(skb); | 122 | int headroom = skb_headroom(skb); |
122 | int tailroom = skb_tailroom(skb); | 123 | int tailroom = skb_tailroom(skb); |
123 | 124 | ||
124 | if ((tailroom >= ETH_FCS_LEN + padlen) | 125 | if ((tailroom >= ETH_FCS_LEN + padlen) && |
125 | && (headroom >= EEM_HEAD)) | 126 | (headroom >= EEM_HEAD)) |
126 | goto done; | 127 | goto done; |
127 | 128 | ||
128 | if ((headroom + tailroom) | 129 | if ((headroom + tailroom) |
@@ -212,7 +213,8 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
212 | * b15: 1 (EEM command) | 213 | * b15: 1 (EEM command) |
213 | */ | 214 | */ |
214 | if (header & BIT(14)) { | 215 | if (header & BIT(14)) { |
215 | devdbg(dev, "reserved command %04x\n", header); | 216 | netdev_dbg(dev->net, "reserved command %04x\n", |
217 | header); | ||
216 | continue; | 218 | continue; |
217 | } | 219 | } |
218 | 220 | ||
@@ -255,8 +257,9 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
255 | case 1: /* Echo response */ | 257 | case 1: /* Echo response */ |
256 | case 5: /* Tickle */ | 258 | case 5: /* Tickle */ |
257 | default: /* reserved */ | 259 | default: /* reserved */ |
258 | devwarn(dev, "unexpected link command %d\n", | 260 | netdev_warn(dev->net, |
259 | bmEEMCmd); | 261 | "unexpected link command %d\n", |
262 | bmEEMCmd); | ||
260 | continue; | 263 | continue; |
261 | } | 264 | } |
262 | 265 | ||
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 21e1ba160008..3547cf13d219 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -37,23 +37,23 @@ | |||
37 | 37 | ||
38 | static int is_rndis(struct usb_interface_descriptor *desc) | 38 | static int is_rndis(struct usb_interface_descriptor *desc) |
39 | { | 39 | { |
40 | return desc->bInterfaceClass == USB_CLASS_COMM | 40 | return (desc->bInterfaceClass == USB_CLASS_COMM && |
41 | && desc->bInterfaceSubClass == 2 | 41 | desc->bInterfaceSubClass == 2 && |
42 | && desc->bInterfaceProtocol == 0xff; | 42 | desc->bInterfaceProtocol == 0xff); |
43 | } | 43 | } |
44 | 44 | ||
45 | static int is_activesync(struct usb_interface_descriptor *desc) | 45 | static int is_activesync(struct usb_interface_descriptor *desc) |
46 | { | 46 | { |
47 | return desc->bInterfaceClass == USB_CLASS_MISC | 47 | return (desc->bInterfaceClass == USB_CLASS_MISC && |
48 | && desc->bInterfaceSubClass == 1 | 48 | desc->bInterfaceSubClass == 1 && |
49 | && desc->bInterfaceProtocol == 1; | 49 | desc->bInterfaceProtocol == 1); |
50 | } | 50 | } |
51 | 51 | ||
52 | static int is_wireless_rndis(struct usb_interface_descriptor *desc) | 52 | static int is_wireless_rndis(struct usb_interface_descriptor *desc) |
53 | { | 53 | { |
54 | return desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER | 54 | return (desc->bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER && |
55 | && desc->bInterfaceSubClass == 1 | 55 | desc->bInterfaceSubClass == 1 && |
56 | && desc->bInterfaceProtocol == 3; | 56 | desc->bInterfaceProtocol == 3); |
57 | } | 57 | } |
58 | 58 | ||
59 | #else | 59 | #else |
@@ -116,9 +116,9 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) | |||
116 | /* this assumes that if there's a non-RNDIS vendor variant | 116 | /* this assumes that if there's a non-RNDIS vendor variant |
117 | * of cdc-acm, it'll fail RNDIS requests cleanly. | 117 | * of cdc-acm, it'll fail RNDIS requests cleanly. |
118 | */ | 118 | */ |
119 | rndis = is_rndis(&intf->cur_altsetting->desc) | 119 | rndis = (is_rndis(&intf->cur_altsetting->desc) || |
120 | || is_activesync(&intf->cur_altsetting->desc) | 120 | is_activesync(&intf->cur_altsetting->desc) || |
121 | || is_wireless_rndis(&intf->cur_altsetting->desc); | 121 | is_wireless_rndis(&intf->cur_altsetting->desc)); |
122 | 122 | ||
123 | memset(info, 0, sizeof *info); | 123 | memset(info, 0, sizeof *info); |
124 | info->control = intf; | 124 | info->control = intf; |
@@ -279,10 +279,10 @@ next_desc: | |||
279 | 279 | ||
280 | dev->status = &info->control->cur_altsetting->endpoint [0]; | 280 | dev->status = &info->control->cur_altsetting->endpoint [0]; |
281 | desc = &dev->status->desc; | 281 | desc = &dev->status->desc; |
282 | if (!usb_endpoint_is_int_in(desc) | 282 | if (!usb_endpoint_is_int_in(desc) || |
283 | || (le16_to_cpu(desc->wMaxPacketSize) | 283 | (le16_to_cpu(desc->wMaxPacketSize) |
284 | < sizeof(struct usb_cdc_notification)) | 284 | < sizeof(struct usb_cdc_notification)) || |
285 | || !desc->bInterval) { | 285 | !desc->bInterval) { |
286 | dev_dbg(&intf->dev, "bad notification endpoint\n"); | 286 | dev_dbg(&intf->dev, "bad notification endpoint\n"); |
287 | dev->status = NULL; | 287 | dev->status = NULL; |
288 | } | 288 | } |
@@ -339,10 +339,10 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind); | |||
339 | 339 | ||
340 | static void dumpspeed(struct usbnet *dev, __le32 *speeds) | 340 | static void dumpspeed(struct usbnet *dev, __le32 *speeds) |
341 | { | 341 | { |
342 | if (netif_msg_timer(dev)) | 342 | netif_info(dev, timer, dev->net, |
343 | devinfo(dev, "link speeds: %u kbps up, %u kbps down", | 343 | "link speeds: %u kbps up, %u kbps down\n", |
344 | __le32_to_cpu(speeds[0]) / 1000, | 344 | __le32_to_cpu(speeds[0]) / 1000, |
345 | __le32_to_cpu(speeds[1]) / 1000); | 345 | __le32_to_cpu(speeds[1]) / 1000); |
346 | } | 346 | } |
347 | 347 | ||
348 | static void cdc_status(struct usbnet *dev, struct urb *urb) | 348 | static void cdc_status(struct usbnet *dev, struct urb *urb) |
@@ -361,18 +361,16 @@ static void cdc_status(struct usbnet *dev, struct urb *urb) | |||
361 | event = urb->transfer_buffer; | 361 | event = urb->transfer_buffer; |
362 | switch (event->bNotificationType) { | 362 | switch (event->bNotificationType) { |
363 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | 363 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: |
364 | if (netif_msg_timer(dev)) | 364 | netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n", |
365 | devdbg(dev, "CDC: carrier %s", | 365 | event->wValue ? "on" : "off"); |
366 | event->wValue ? "on" : "off"); | ||
367 | if (event->wValue) | 366 | if (event->wValue) |
368 | netif_carrier_on(dev->net); | 367 | netif_carrier_on(dev->net); |
369 | else | 368 | else |
370 | netif_carrier_off(dev->net); | 369 | netif_carrier_off(dev->net); |
371 | break; | 370 | break; |
372 | case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */ | 371 | case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */ |
373 | if (netif_msg_timer(dev)) | 372 | netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n", |
374 | devdbg(dev, "CDC: speed change (len %d)", | 373 | urb->actual_length); |
375 | urb->actual_length); | ||
376 | if (urb->actual_length != (sizeof *event + 8)) | 374 | if (urb->actual_length != (sizeof *event + 8)) |
377 | set_bit(EVENT_STS_SPLIT, &dev->flags); | 375 | set_bit(EVENT_STS_SPLIT, &dev->flags); |
378 | else | 376 | else |
@@ -382,8 +380,8 @@ static void cdc_status(struct usbnet *dev, struct urb *urb) | |||
382 | * but there are no standard formats for the response data. | 380 | * but there are no standard formats for the response data. |
383 | */ | 381 | */ |
384 | default: | 382 | default: |
385 | deverr(dev, "CDC: unexpected notification %02x!", | 383 | netdev_err(dev->net, "CDC: unexpected notification %02x!\n", |
386 | event->bNotificationType); | 384 | event->bNotificationType); |
387 | break; | 385 | break; |
388 | } | 386 | } |
389 | } | 387 | } |
@@ -411,6 +409,12 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) | |||
411 | return 0; | 409 | return 0; |
412 | } | 410 | } |
413 | 411 | ||
412 | static int cdc_manage_power(struct usbnet *dev, int on) | ||
413 | { | ||
414 | dev->intf->needs_remote_wakeup = on; | ||
415 | return 0; | ||
416 | } | ||
417 | |||
414 | static const struct driver_info cdc_info = { | 418 | static const struct driver_info cdc_info = { |
415 | .description = "CDC Ethernet Device", | 419 | .description = "CDC Ethernet Device", |
416 | .flags = FLAG_ETHER, | 420 | .flags = FLAG_ETHER, |
@@ -418,6 +422,16 @@ static const struct driver_info cdc_info = { | |||
418 | .bind = cdc_bind, | 422 | .bind = cdc_bind, |
419 | .unbind = usbnet_cdc_unbind, | 423 | .unbind = usbnet_cdc_unbind, |
420 | .status = cdc_status, | 424 | .status = cdc_status, |
425 | .manage_power = cdc_manage_power, | ||
426 | }; | ||
427 | |||
428 | static const struct driver_info mbm_info = { | ||
429 | .description = "Mobile Broadband Network Device", | ||
430 | .flags = FLAG_WWAN, | ||
431 | .bind = cdc_bind, | ||
432 | .unbind = usbnet_cdc_unbind, | ||
433 | .status = cdc_status, | ||
434 | .manage_power = cdc_manage_power, | ||
421 | }; | 435 | }; |
422 | 436 | ||
423 | /*-------------------------------------------------------------------------*/ | 437 | /*-------------------------------------------------------------------------*/ |
@@ -532,72 +546,77 @@ static const struct usb_device_id products [] = { | |||
532 | /* Ericsson F3507g */ | 546 | /* Ericsson F3507g */ |
533 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM, | 547 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM, |
534 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 548 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
535 | .driver_info = (unsigned long) &cdc_info, | 549 | .driver_info = (unsigned long) &mbm_info, |
536 | }, { | 550 | }, { |
537 | /* Ericsson F3507g ver. 2 */ | 551 | /* Ericsson F3507g ver. 2 */ |
538 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM, | 552 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1902, USB_CLASS_COMM, |
539 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 553 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
540 | .driver_info = (unsigned long) &cdc_info, | 554 | .driver_info = (unsigned long) &mbm_info, |
541 | }, { | 555 | }, { |
542 | /* Ericsson F3607gw */ | 556 | /* Ericsson F3607gw */ |
543 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM, | 557 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1904, USB_CLASS_COMM, |
544 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 558 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
545 | .driver_info = (unsigned long) &cdc_info, | 559 | .driver_info = (unsigned long) &mbm_info, |
546 | }, { | 560 | }, { |
547 | /* Ericsson F3607gw ver 2 */ | 561 | /* Ericsson F3607gw ver 2 */ |
548 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM, | 562 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1905, USB_CLASS_COMM, |
549 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 563 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
550 | .driver_info = (unsigned long) &cdc_info, | 564 | .driver_info = (unsigned long) &mbm_info, |
551 | }, { | 565 | }, { |
552 | /* Ericsson F3607gw ver 3 */ | 566 | /* Ericsson F3607gw ver 3 */ |
553 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM, | 567 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1906, USB_CLASS_COMM, |
554 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 568 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
555 | .driver_info = (unsigned long) &cdc_info, | 569 | .driver_info = (unsigned long) &mbm_info, |
556 | }, { | 570 | }, { |
557 | /* Ericsson F3307 */ | 571 | /* Ericsson F3307 */ |
558 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM, | 572 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190a, USB_CLASS_COMM, |
559 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 573 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
560 | .driver_info = (unsigned long) &cdc_info, | 574 | .driver_info = (unsigned long) &mbm_info, |
561 | }, { | 575 | }, { |
562 | /* Ericsson F3307 ver 2 */ | 576 | /* Ericsson F3307 ver 2 */ |
563 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM, | 577 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1909, USB_CLASS_COMM, |
564 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 578 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
565 | .driver_info = (unsigned long) &cdc_info, | 579 | .driver_info = (unsigned long) &mbm_info, |
566 | }, { | 580 | }, { |
567 | /* Ericsson C3607w */ | 581 | /* Ericsson C3607w */ |
568 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM, | 582 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM, |
569 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 583 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
570 | .driver_info = (unsigned long) &cdc_info, | 584 | .driver_info = (unsigned long) &mbm_info, |
585 | }, { | ||
586 | /* Ericsson C3607w ver 2 */ | ||
587 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM, | ||
588 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
589 | .driver_info = (unsigned long) &mbm_info, | ||
571 | }, { | 590 | }, { |
572 | /* Toshiba F3507g */ | 591 | /* Toshiba F3507g */ |
573 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, | 592 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, |
574 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 593 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
575 | .driver_info = (unsigned long) &cdc_info, | 594 | .driver_info = (unsigned long) &mbm_info, |
576 | }, { | 595 | }, { |
577 | /* Toshiba F3607gw */ | 596 | /* Toshiba F3607gw */ |
578 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM, | 597 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130c, USB_CLASS_COMM, |
579 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 598 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
580 | .driver_info = (unsigned long) &cdc_info, | 599 | .driver_info = (unsigned long) &mbm_info, |
581 | }, { | 600 | }, { |
582 | /* Toshiba F3607gw ver 2 */ | 601 | /* Toshiba F3607gw ver 2 */ |
583 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM, | 602 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x1311, USB_CLASS_COMM, |
584 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 603 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
585 | .driver_info = (unsigned long) &cdc_info, | 604 | .driver_info = (unsigned long) &mbm_info, |
586 | }, { | 605 | }, { |
587 | /* Dell F3507g */ | 606 | /* Dell F3507g */ |
588 | USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM, | 607 | USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8147, USB_CLASS_COMM, |
589 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 608 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
590 | .driver_info = (unsigned long) &cdc_info, | 609 | .driver_info = (unsigned long) &mbm_info, |
591 | }, { | 610 | }, { |
592 | /* Dell F3607gw */ | 611 | /* Dell F3607gw */ |
593 | USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM, | 612 | USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8183, USB_CLASS_COMM, |
594 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 613 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
595 | .driver_info = (unsigned long) &cdc_info, | 614 | .driver_info = (unsigned long) &mbm_info, |
596 | }, { | 615 | }, { |
597 | /* Dell F3607gw ver 2 */ | 616 | /* Dell F3607gw ver 2 */ |
598 | USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM, | 617 | USB_DEVICE_AND_INTERFACE_INFO(0x413c, 0x8184, USB_CLASS_COMM, |
599 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 618 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
600 | .driver_info = (unsigned long) &cdc_info, | 619 | .driver_info = (unsigned long) &mbm_info, |
601 | }, | 620 | }, |
602 | { }, // END | 621 | { }, // END |
603 | }; | 622 | }; |
@@ -610,6 +629,8 @@ static struct usb_driver cdc_driver = { | |||
610 | .disconnect = usbnet_disconnect, | 629 | .disconnect = usbnet_disconnect, |
611 | .suspend = usbnet_suspend, | 630 | .suspend = usbnet_suspend, |
612 | .resume = usbnet_resume, | 631 | .resume = usbnet_resume, |
632 | .reset_resume = usbnet_resume, | ||
633 | .supports_autosuspend = 1, | ||
613 | }; | 634 | }; |
614 | 635 | ||
615 | 636 | ||
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index a2b30a10064f..5dfed9297b22 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/usb/usbnet.h> | 23 | #include <linux/usb/usbnet.h> |
24 | #include <linux/slab.h> | ||
24 | 25 | ||
25 | /* datasheet: | 26 | /* datasheet: |
26 | http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf | 27 | http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf |
@@ -58,7 +59,7 @@ static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data) | |||
58 | void *buf; | 59 | void *buf; |
59 | int err = -ENOMEM; | 60 | int err = -ENOMEM; |
60 | 61 | ||
61 | devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length); | 62 | netdev_dbg(dev->net, "dm_read() reg=0x%02x length=%d\n", reg, length); |
62 | 63 | ||
63 | buf = kmalloc(length, GFP_KERNEL); | 64 | buf = kmalloc(length, GFP_KERNEL); |
64 | if (!buf) | 65 | if (!buf) |
@@ -89,7 +90,7 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data) | |||
89 | void *buf = NULL; | 90 | void *buf = NULL; |
90 | int err = -ENOMEM; | 91 | int err = -ENOMEM; |
91 | 92 | ||
92 | devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length); | 93 | netdev_dbg(dev->net, "dm_write() reg=0x%02x, length=%d\n", reg, length); |
93 | 94 | ||
94 | if (data) { | 95 | if (data) { |
95 | buf = kmalloc(length, GFP_KERNEL); | 96 | buf = kmalloc(length, GFP_KERNEL); |
@@ -112,7 +113,8 @@ static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data) | |||
112 | 113 | ||
113 | static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) | 114 | static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value) |
114 | { | 115 | { |
115 | devdbg(dev, "dm_write_reg() reg=0x%02x, value=0x%02x", reg, value); | 116 | netdev_dbg(dev->net, "dm_write_reg() reg=0x%02x, value=0x%02x\n", |
117 | reg, value); | ||
116 | return usb_control_msg(dev->udev, | 118 | return usb_control_msg(dev->udev, |
117 | usb_sndctrlpipe(dev->udev, 0), | 119 | usb_sndctrlpipe(dev->udev, 0), |
118 | DM_WRITE_REG, | 120 | DM_WRITE_REG, |
@@ -142,13 +144,13 @@ static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, | |||
142 | 144 | ||
143 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 145 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
144 | if (!urb) { | 146 | if (!urb) { |
145 | deverr(dev, "Error allocating URB in dm_write_async_helper!"); | 147 | netdev_err(dev->net, "Error allocating URB in dm_write_async_helper!\n"); |
146 | return; | 148 | return; |
147 | } | 149 | } |
148 | 150 | ||
149 | req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); | 151 | req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); |
150 | if (!req) { | 152 | if (!req) { |
151 | deverr(dev, "Failed to allocate memory for control request"); | 153 | netdev_err(dev->net, "Failed to allocate memory for control request\n"); |
152 | usb_free_urb(urb); | 154 | usb_free_urb(urb); |
153 | return; | 155 | return; |
154 | } | 156 | } |
@@ -166,8 +168,8 @@ static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, | |||
166 | 168 | ||
167 | status = usb_submit_urb(urb, GFP_ATOMIC); | 169 | status = usb_submit_urb(urb, GFP_ATOMIC); |
168 | if (status < 0) { | 170 | if (status < 0) { |
169 | deverr(dev, "Error submitting the control message: status=%d", | 171 | netdev_err(dev->net, "Error submitting the control message: status=%d\n", |
170 | status); | 172 | status); |
171 | kfree(req); | 173 | kfree(req); |
172 | usb_free_urb(urb); | 174 | usb_free_urb(urb); |
173 | } | 175 | } |
@@ -175,15 +177,15 @@ static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, | |||
175 | 177 | ||
176 | static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) | 178 | static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) |
177 | { | 179 | { |
178 | devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length); | 180 | netdev_dbg(dev->net, "dm_write_async() reg=0x%02x length=%d\n", reg, length); |
179 | 181 | ||
180 | dm_write_async_helper(dev, reg, 0, length, data); | 182 | dm_write_async_helper(dev, reg, 0, length, data); |
181 | } | 183 | } |
182 | 184 | ||
183 | static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value) | 185 | static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value) |
184 | { | 186 | { |
185 | devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x", | 187 | netdev_dbg(dev->net, "dm_write_reg_async() reg=0x%02x value=0x%02x\n", |
186 | reg, value); | 188 | reg, value); |
187 | 189 | ||
188 | dm_write_async_helper(dev, reg, value, 0, NULL); | 190 | dm_write_async_helper(dev, reg, value, 0, NULL); |
189 | } | 191 | } |
@@ -211,7 +213,7 @@ static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *valu | |||
211 | } | 213 | } |
212 | 214 | ||
213 | if (i == DM_TIMEOUT) { | 215 | if (i == DM_TIMEOUT) { |
214 | deverr(dev, "%s read timed out!", phy ? "phy" : "eeprom"); | 216 | netdev_err(dev->net, "%s read timed out!\n", phy ? "phy" : "eeprom"); |
215 | ret = -EIO; | 217 | ret = -EIO; |
216 | goto out; | 218 | goto out; |
217 | } | 219 | } |
@@ -219,8 +221,8 @@ static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 *valu | |||
219 | dm_write_reg(dev, DM_SHARED_CTRL, 0x0); | 221 | dm_write_reg(dev, DM_SHARED_CTRL, 0x0); |
220 | ret = dm_read(dev, DM_SHARED_DATA, 2, value); | 222 | ret = dm_read(dev, DM_SHARED_DATA, 2, value); |
221 | 223 | ||
222 | devdbg(dev, "read shared %d 0x%02x returned 0x%04x, %d", | 224 | netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n", |
223 | phy, reg, *value, ret); | 225 | phy, reg, *value, ret); |
224 | 226 | ||
225 | out: | 227 | out: |
226 | mutex_unlock(&dev->phy_mutex); | 228 | mutex_unlock(&dev->phy_mutex); |
@@ -238,7 +240,7 @@ static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 valu | |||
238 | goto out; | 240 | goto out; |
239 | 241 | ||
240 | dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg); | 242 | dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg); |
241 | dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14); | 243 | dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12); |
242 | 244 | ||
243 | for (i = 0; i < DM_TIMEOUT; i++) { | 245 | for (i = 0; i < DM_TIMEOUT; i++) { |
244 | u8 tmp; | 246 | u8 tmp; |
@@ -254,7 +256,7 @@ static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 valu | |||
254 | } | 256 | } |
255 | 257 | ||
256 | if (i == DM_TIMEOUT) { | 258 | if (i == DM_TIMEOUT) { |
257 | deverr(dev, "%s write timed out!", phy ? "phy" : "eeprom"); | 259 | netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom"); |
258 | ret = -EIO; | 260 | ret = -EIO; |
259 | goto out; | 261 | goto out; |
260 | } | 262 | } |
@@ -304,15 +306,15 @@ static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc) | |||
304 | __le16 res; | 306 | __le16 res; |
305 | 307 | ||
306 | if (phy_id) { | 308 | if (phy_id) { |
307 | devdbg(dev, "Only internal phy supported"); | 309 | netdev_dbg(dev->net, "Only internal phy supported\n"); |
308 | return 0; | 310 | return 0; |
309 | } | 311 | } |
310 | 312 | ||
311 | dm_read_shared_word(dev, 1, loc, &res); | 313 | dm_read_shared_word(dev, 1, loc, &res); |
312 | 314 | ||
313 | devdbg(dev, | 315 | netdev_dbg(dev->net, |
314 | "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", | 316 | "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", |
315 | phy_id, loc, le16_to_cpu(res)); | 317 | phy_id, loc, le16_to_cpu(res)); |
316 | 318 | ||
317 | return le16_to_cpu(res); | 319 | return le16_to_cpu(res); |
318 | } | 320 | } |
@@ -324,12 +326,12 @@ static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc, | |||
324 | __le16 res = cpu_to_le16(val); | 326 | __le16 res = cpu_to_le16(val); |
325 | 327 | ||
326 | if (phy_id) { | 328 | if (phy_id) { |
327 | devdbg(dev, "Only internal phy supported"); | 329 | netdev_dbg(dev->net, "Only internal phy supported\n"); |
328 | return; | 330 | return; |
329 | } | 331 | } |
330 | 332 | ||
331 | devdbg(dev,"dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", | 333 | netdev_dbg(dev->net, "dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", |
332 | phy_id, loc, val); | 334 | phy_id, loc, val); |
333 | 335 | ||
334 | dm_write_shared_word(dev, 1, loc, res); | 336 | dm_write_shared_word(dev, 1, loc, res); |
335 | } | 337 | } |
@@ -381,13 +383,13 @@ static void dm9601_set_multicast(struct net_device *net) | |||
381 | 383 | ||
382 | if (net->flags & IFF_PROMISC) { | 384 | if (net->flags & IFF_PROMISC) { |
383 | rx_ctl |= 0x02; | 385 | rx_ctl |= 0x02; |
384 | } else if (net->flags & IFF_ALLMULTI || net->mc_count > DM_MAX_MCAST) { | 386 | } else if (net->flags & IFF_ALLMULTI || |
387 | netdev_mc_count(net) > DM_MAX_MCAST) { | ||
385 | rx_ctl |= 0x04; | 388 | rx_ctl |= 0x04; |
386 | } else if (net->mc_count) { | 389 | } else if (!netdev_mc_empty(net)) { |
387 | struct dev_mc_list *mc_list = net->mc_list; | 390 | struct dev_mc_list *mc_list; |
388 | int i; | ||
389 | 391 | ||
390 | for (i = 0; i < net->mc_count; i++, mc_list = mc_list->next) { | 392 | netdev_for_each_mc_addr(mc_list, net) { |
391 | u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; | 393 | u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; |
392 | hashes[crc >> 3] |= 1 << (crc & 0x7); | 394 | hashes[crc >> 3] |= 1 << (crc & 0x7); |
393 | } | 395 | } |
@@ -592,7 +594,7 @@ static void dm9601_status(struct usbnet *dev, struct urb *urb) | |||
592 | } | 594 | } |
593 | else | 595 | else |
594 | netif_carrier_off(dev->net); | 596 | netif_carrier_off(dev->net); |
595 | devdbg(dev, "Link Status is: %d", link); | 597 | netdev_dbg(dev->net, "Link Status is: %d\n", link); |
596 | } | 598 | } |
597 | } | 599 | } |
598 | 600 | ||
@@ -603,15 +605,15 @@ static int dm9601_link_reset(struct usbnet *dev) | |||
603 | mii_check_media(&dev->mii, 1, 1); | 605 | mii_check_media(&dev->mii, 1, 1); |
604 | mii_ethtool_gset(&dev->mii, &ecmd); | 606 | mii_ethtool_gset(&dev->mii, &ecmd); |
605 | 607 | ||
606 | devdbg(dev, "link_reset() speed: %d duplex: %d", | 608 | netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n", |
607 | ecmd.speed, ecmd.duplex); | 609 | ecmd.speed, ecmd.duplex); |
608 | 610 | ||
609 | return 0; | 611 | return 0; |
610 | } | 612 | } |
611 | 613 | ||
612 | static const struct driver_info dm9601_info = { | 614 | static const struct driver_info dm9601_info = { |
613 | .description = "Davicom DM9601 USB Ethernet", | 615 | .description = "Davicom DM9601 USB Ethernet", |
614 | .flags = FLAG_ETHER, | 616 | .flags = FLAG_ETHER | FLAG_LINK_INTR, |
615 | .bind = dm9601_bind, | 617 | .bind = dm9601_bind, |
616 | .rx_fixup = dm9601_rx_fixup, | 618 | .rx_fixup = dm9601_rx_fixup, |
617 | .tx_fixup = dm9601_tx_fixup, | 619 | .tx_fixup = dm9601_tx_fixup, |
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index f7ccfad9384e..dcd57c37ef73 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mii.h> | 30 | #include <linux/mii.h> |
31 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
32 | #include <linux/usb/usbnet.h> | 32 | #include <linux/usb/usbnet.h> |
33 | #include <linux/gfp.h> | ||
33 | 34 | ||
34 | 35 | ||
35 | /* | 36 | /* |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 43bc3fcc0d85..be0cc99e881a 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -286,6 +286,7 @@ struct hso_device { | |||
286 | u8 usb_gone; | 286 | u8 usb_gone; |
287 | struct work_struct async_get_intf; | 287 | struct work_struct async_get_intf; |
288 | struct work_struct async_put_intf; | 288 | struct work_struct async_put_intf; |
289 | struct work_struct reset_device; | ||
289 | 290 | ||
290 | struct usb_device *usb; | 291 | struct usb_device *usb; |
291 | struct usb_interface *interface; | 292 | struct usb_interface *interface; |
@@ -332,7 +333,8 @@ static void hso_kick_transmit(struct hso_serial *serial); | |||
332 | /* Helper functions */ | 333 | /* Helper functions */ |
333 | static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, | 334 | static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, |
334 | struct usb_device *usb, gfp_t gfp); | 335 | struct usb_device *usb, gfp_t gfp); |
335 | static void log_usb_status(int status, const char *function); | 336 | static void handle_usb_error(int status, const char *function, |
337 | struct hso_device *hso_dev); | ||
336 | static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, | 338 | static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, |
337 | int type, int dir); | 339 | int type, int dir); |
338 | static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); | 340 | static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); |
@@ -350,6 +352,7 @@ static void async_put_intf(struct work_struct *data); | |||
350 | static int hso_put_activity(struct hso_device *hso_dev); | 352 | static int hso_put_activity(struct hso_device *hso_dev); |
351 | static int hso_get_activity(struct hso_device *hso_dev); | 353 | static int hso_get_activity(struct hso_device *hso_dev); |
352 | static void tiocmget_intr_callback(struct urb *urb); | 354 | static void tiocmget_intr_callback(struct urb *urb); |
355 | static void reset_device(struct work_struct *data); | ||
353 | /*****************************************************************************/ | 356 | /*****************************************************************************/ |
354 | /* Helping functions */ | 357 | /* Helping functions */ |
355 | /*****************************************************************************/ | 358 | /*****************************************************************************/ |
@@ -461,10 +464,17 @@ static const struct usb_device_id hso_ids[] = { | |||
461 | {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ | 464 | {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ |
462 | {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ | 465 | {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ |
463 | {USB_DEVICE(0x0af0, 0x7701)}, | 466 | {USB_DEVICE(0x0af0, 0x7701)}, |
467 | {USB_DEVICE(0x0af0, 0x7706)}, | ||
464 | {USB_DEVICE(0x0af0, 0x7801)}, | 468 | {USB_DEVICE(0x0af0, 0x7801)}, |
465 | {USB_DEVICE(0x0af0, 0x7901)}, | 469 | {USB_DEVICE(0x0af0, 0x7901)}, |
470 | {USB_DEVICE(0x0af0, 0x7A01)}, | ||
471 | {USB_DEVICE(0x0af0, 0x7A05)}, | ||
466 | {USB_DEVICE(0x0af0, 0x8200)}, | 472 | {USB_DEVICE(0x0af0, 0x8200)}, |
467 | {USB_DEVICE(0x0af0, 0x8201)}, | 473 | {USB_DEVICE(0x0af0, 0x8201)}, |
474 | {USB_DEVICE(0x0af0, 0x8300)}, | ||
475 | {USB_DEVICE(0x0af0, 0x8302)}, | ||
476 | {USB_DEVICE(0x0af0, 0x8304)}, | ||
477 | {USB_DEVICE(0x0af0, 0x8400)}, | ||
468 | {USB_DEVICE(0x0af0, 0xd035)}, | 478 | {USB_DEVICE(0x0af0, 0xd035)}, |
469 | {USB_DEVICE(0x0af0, 0xd055)}, | 479 | {USB_DEVICE(0x0af0, 0xd055)}, |
470 | {USB_DEVICE(0x0af0, 0xd155)}, | 480 | {USB_DEVICE(0x0af0, 0xd155)}, |
@@ -473,6 +483,8 @@ static const struct usb_device_id hso_ids[] = { | |||
473 | {USB_DEVICE(0x0af0, 0xd157)}, | 483 | {USB_DEVICE(0x0af0, 0xd157)}, |
474 | {USB_DEVICE(0x0af0, 0xd257)}, | 484 | {USB_DEVICE(0x0af0, 0xd257)}, |
475 | {USB_DEVICE(0x0af0, 0xd357)}, | 485 | {USB_DEVICE(0x0af0, 0xd357)}, |
486 | {USB_DEVICE(0x0af0, 0xd058)}, | ||
487 | {USB_DEVICE(0x0af0, 0xc100)}, | ||
476 | {} | 488 | {} |
477 | }; | 489 | }; |
478 | MODULE_DEVICE_TABLE(usb, hso_ids); | 490 | MODULE_DEVICE_TABLE(usb, hso_ids); |
@@ -602,9 +614,9 @@ static struct hso_serial *get_serial_by_shared_int_and_type( | |||
602 | port = hso_mux_to_port(mux); | 614 | port = hso_mux_to_port(mux); |
603 | 615 | ||
604 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { | 616 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { |
605 | if (serial_table[i] | 617 | if (serial_table[i] && |
606 | && (dev2ser(serial_table[i])->shared_int == shared_int) | 618 | (dev2ser(serial_table[i])->shared_int == shared_int) && |
607 | && ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) { | 619 | ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) { |
608 | return dev2ser(serial_table[i]); | 620 | return dev2ser(serial_table[i]); |
609 | } | 621 | } |
610 | } | 622 | } |
@@ -655,8 +667,8 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial) | |||
655 | spin_unlock_irqrestore(&serial_table_lock, flags); | 667 | spin_unlock_irqrestore(&serial_table_lock, flags); |
656 | } | 668 | } |
657 | 669 | ||
658 | /* log a meaningful explanation of an USB status */ | 670 | static void handle_usb_error(int status, const char *function, |
659 | static void log_usb_status(int status, const char *function) | 671 | struct hso_device *hso_dev) |
660 | { | 672 | { |
661 | char *explanation; | 673 | char *explanation; |
662 | 674 | ||
@@ -685,10 +697,20 @@ static void log_usb_status(int status, const char *function) | |||
685 | case -EMSGSIZE: | 697 | case -EMSGSIZE: |
686 | explanation = "internal error"; | 698 | explanation = "internal error"; |
687 | break; | 699 | break; |
700 | case -EILSEQ: | ||
701 | case -EPROTO: | ||
702 | case -ETIME: | ||
703 | case -ETIMEDOUT: | ||
704 | explanation = "protocol error"; | ||
705 | if (hso_dev) | ||
706 | schedule_work(&hso_dev->reset_device); | ||
707 | break; | ||
688 | default: | 708 | default: |
689 | explanation = "unknown status"; | 709 | explanation = "unknown status"; |
690 | break; | 710 | break; |
691 | } | 711 | } |
712 | |||
713 | /* log a meaningful explanation of an USB status */ | ||
692 | D1("%s: received USB status - %s (%d)", function, explanation, status); | 714 | D1("%s: received USB status - %s (%d)", function, explanation, status); |
693 | } | 715 | } |
694 | 716 | ||
@@ -762,7 +784,7 @@ static void write_bulk_callback(struct urb *urb) | |||
762 | /* log status, but don't act on it, we don't need to resubmit anything | 784 | /* log status, but don't act on it, we don't need to resubmit anything |
763 | * anyhow */ | 785 | * anyhow */ |
764 | if (status) | 786 | if (status) |
765 | log_usb_status(status, __func__); | 787 | handle_usb_error(status, __func__, odev->parent); |
766 | 788 | ||
767 | hso_put_activity(odev->parent); | 789 | hso_put_activity(odev->parent); |
768 | 790 | ||
@@ -806,7 +828,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, | |||
806 | result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); | 828 | result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); |
807 | if (result) { | 829 | if (result) { |
808 | dev_warn(&odev->parent->interface->dev, | 830 | dev_warn(&odev->parent->interface->dev, |
809 | "failed mux_bulk_tx_urb %d", result); | 831 | "failed mux_bulk_tx_urb %d\n", result); |
810 | net->stats.tx_errors++; | 832 | net->stats.tx_errors++; |
811 | netif_start_queue(net); | 833 | netif_start_queue(net); |
812 | } else { | 834 | } else { |
@@ -846,8 +868,8 @@ static void hso_net_tx_timeout(struct net_device *net) | |||
846 | dev_warn(&net->dev, "Tx timed out.\n"); | 868 | dev_warn(&net->dev, "Tx timed out.\n"); |
847 | 869 | ||
848 | /* Tear the waiting frame off the list */ | 870 | /* Tear the waiting frame off the list */ |
849 | if (odev->mux_bulk_tx_urb | 871 | if (odev->mux_bulk_tx_urb && |
850 | && (odev->mux_bulk_tx_urb->status == -EINPROGRESS)) | 872 | (odev->mux_bulk_tx_urb->status == -EINPROGRESS)) |
851 | usb_unlink_urb(odev->mux_bulk_tx_urb); | 873 | usb_unlink_urb(odev->mux_bulk_tx_urb); |
852 | 874 | ||
853 | /* Update statistics */ | 875 | /* Update statistics */ |
@@ -998,7 +1020,7 @@ static void read_bulk_callback(struct urb *urb) | |||
998 | 1020 | ||
999 | /* is al ok? (Filip: Who's Al ?) */ | 1021 | /* is al ok? (Filip: Who's Al ?) */ |
1000 | if (status) { | 1022 | if (status) { |
1001 | log_usb_status(status, __func__); | 1023 | handle_usb_error(status, __func__, odev->parent); |
1002 | return; | 1024 | return; |
1003 | } | 1025 | } |
1004 | 1026 | ||
@@ -1019,10 +1041,11 @@ static void read_bulk_callback(struct urb *urb) | |||
1019 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { | 1041 | if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { |
1020 | u32 rest; | 1042 | u32 rest; |
1021 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | 1043 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; |
1022 | rest = urb->actual_length % odev->in_endp->wMaxPacketSize; | 1044 | rest = urb->actual_length % |
1023 | if (((rest == 5) || (rest == 6)) | 1045 | le16_to_cpu(odev->in_endp->wMaxPacketSize); |
1024 | && !memcmp(((u8 *) urb->transfer_buffer) + | 1046 | if (((rest == 5) || (rest == 6)) && |
1025 | urb->actual_length - 4, crc_check, 4)) { | 1047 | !memcmp(((u8 *) urb->transfer_buffer) + |
1048 | urb->actual_length - 4, crc_check, 4)) { | ||
1026 | urb->actual_length -= 4; | 1049 | urb->actual_length -= 4; |
1027 | } | 1050 | } |
1028 | } | 1051 | } |
@@ -1053,7 +1076,7 @@ static void read_bulk_callback(struct urb *urb) | |||
1053 | result = usb_submit_urb(urb, GFP_ATOMIC); | 1076 | result = usb_submit_urb(urb, GFP_ATOMIC); |
1054 | if (result) | 1077 | if (result) |
1055 | dev_warn(&odev->parent->interface->dev, | 1078 | dev_warn(&odev->parent->interface->dev, |
1056 | "%s failed submit mux_bulk_rx_urb %d", __func__, | 1079 | "%s failed submit mux_bulk_rx_urb %d\n", __func__, |
1057 | result); | 1080 | result); |
1058 | } | 1081 | } |
1059 | 1082 | ||
@@ -1132,9 +1155,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty, | |||
1132 | static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) | 1155 | static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) |
1133 | { | 1156 | { |
1134 | int result; | 1157 | int result; |
1135 | #ifdef CONFIG_HSO_AUTOPM | ||
1136 | usb_mark_last_busy(urb->dev); | ||
1137 | #endif | ||
1138 | /* We are done with this URB, resubmit it. Prep the USB to wait for | 1158 | /* We are done with this URB, resubmit it. Prep the USB to wait for |
1139 | * another frame */ | 1159 | * another frame */ |
1140 | usb_fill_bulk_urb(urb, serial->parent->usb, | 1160 | usb_fill_bulk_urb(urb, serial->parent->usb, |
@@ -1207,7 +1227,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1207 | D1("serial == NULL"); | 1227 | D1("serial == NULL"); |
1208 | return; | 1228 | return; |
1209 | } else if (status) { | 1229 | } else if (status) { |
1210 | log_usb_status(status, __func__); | 1230 | handle_usb_error(status, __func__, serial->parent); |
1211 | return; | 1231 | return; |
1212 | } | 1232 | } |
1213 | 1233 | ||
@@ -1225,10 +1245,10 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1225 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; | 1245 | u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; |
1226 | rest = | 1246 | rest = |
1227 | urb->actual_length % | 1247 | urb->actual_length % |
1228 | serial->in_endp->wMaxPacketSize; | 1248 | le16_to_cpu(serial->in_endp->wMaxPacketSize); |
1229 | if (((rest == 5) || (rest == 6)) | 1249 | if (((rest == 5) || (rest == 6)) && |
1230 | && !memcmp(((u8 *) urb->transfer_buffer) + | 1250 | !memcmp(((u8 *) urb->transfer_buffer) + |
1231 | urb->actual_length - 4, crc_check, 4)) { | 1251 | urb->actual_length - 4, crc_check, 4)) { |
1232 | urb->actual_length -= 4; | 1252 | urb->actual_length -= 4; |
1233 | } | 1253 | } |
1234 | } | 1254 | } |
@@ -1513,7 +1533,7 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
1513 | if (!serial) | 1533 | if (!serial) |
1514 | return; | 1534 | return; |
1515 | if (status) { | 1535 | if (status) { |
1516 | log_usb_status(status, __func__); | 1536 | handle_usb_error(status, __func__, serial->parent); |
1517 | return; | 1537 | return; |
1518 | } | 1538 | } |
1519 | tiocmget = serial->tiocmget; | 1539 | tiocmget = serial->tiocmget; |
@@ -1700,6 +1720,10 @@ static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, | |||
1700 | D1("no tty structures"); | 1720 | D1("no tty structures"); |
1701 | return -EINVAL; | 1721 | return -EINVAL; |
1702 | } | 1722 | } |
1723 | |||
1724 | if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM) | ||
1725 | return -EINVAL; | ||
1726 | |||
1703 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; | 1727 | if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; |
1704 | 1728 | ||
1705 | spin_lock_irqsave(&serial->serial_lock, flags); | 1729 | spin_lock_irqsave(&serial->serial_lock, flags); |
@@ -1838,7 +1862,7 @@ static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, | |||
1838 | result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); | 1862 | result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); |
1839 | if (result) { | 1863 | if (result) { |
1840 | dev_err(&ctrl_urb->dev->dev, | 1864 | dev_err(&ctrl_urb->dev->dev, |
1841 | "%s failed submit ctrl_urb %d type %d", __func__, | 1865 | "%s failed submit ctrl_urb %d type %d\n", __func__, |
1842 | result, type); | 1866 | result, type); |
1843 | return result; | 1867 | return result; |
1844 | } | 1868 | } |
@@ -1888,7 +1912,7 @@ static void intr_callback(struct urb *urb) | |||
1888 | 1912 | ||
1889 | /* status check */ | 1913 | /* status check */ |
1890 | if (status) { | 1914 | if (status) { |
1891 | log_usb_status(status, __func__); | 1915 | handle_usb_error(status, __func__, NULL); |
1892 | return; | 1916 | return; |
1893 | } | 1917 | } |
1894 | D4("\n--- Got intr callback 0x%02X ---", status); | 1918 | D4("\n--- Got intr callback 0x%02X ---", status); |
@@ -1905,18 +1929,18 @@ static void intr_callback(struct urb *urb) | |||
1905 | if (serial != NULL) { | 1929 | if (serial != NULL) { |
1906 | D1("Pending read interrupt on port %d\n", i); | 1930 | D1("Pending read interrupt on port %d\n", i); |
1907 | spin_lock(&serial->serial_lock); | 1931 | spin_lock(&serial->serial_lock); |
1908 | if (serial->rx_state == RX_IDLE) { | 1932 | if (serial->rx_state == RX_IDLE && |
1933 | serial->open_count > 0) { | ||
1909 | /* Setup and send a ctrl req read on | 1934 | /* Setup and send a ctrl req read on |
1910 | * port i */ | 1935 | * port i */ |
1911 | if (!serial->rx_urb_filled[0]) { | 1936 | if (!serial->rx_urb_filled[0]) { |
1912 | serial->rx_state = RX_SENT; | 1937 | serial->rx_state = RX_SENT; |
1913 | hso_mux_serial_read(serial); | 1938 | hso_mux_serial_read(serial); |
1914 | } else | 1939 | } else |
1915 | serial->rx_state = RX_PENDING; | 1940 | serial->rx_state = RX_PENDING; |
1916 | |||
1917 | } else { | 1941 | } else { |
1918 | D1("Already pending a read on " | 1942 | D1("Already a read pending on " |
1919 | "port %d\n", i); | 1943 | "port %d or port not open\n", i); |
1920 | } | 1944 | } |
1921 | spin_unlock(&serial->serial_lock); | 1945 | spin_unlock(&serial->serial_lock); |
1922 | } | 1946 | } |
@@ -1958,7 +1982,7 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb) | |||
1958 | tty = tty_kref_get(serial->tty); | 1982 | tty = tty_kref_get(serial->tty); |
1959 | spin_unlock(&serial->serial_lock); | 1983 | spin_unlock(&serial->serial_lock); |
1960 | if (status) { | 1984 | if (status) { |
1961 | log_usb_status(status, __func__); | 1985 | handle_usb_error(status, __func__, serial->parent); |
1962 | tty_kref_put(tty); | 1986 | tty_kref_put(tty); |
1963 | return; | 1987 | return; |
1964 | } | 1988 | } |
@@ -2014,7 +2038,7 @@ static void ctrl_callback(struct urb *urb) | |||
2014 | tty = tty_kref_get(serial->tty); | 2038 | tty = tty_kref_get(serial->tty); |
2015 | spin_unlock(&serial->serial_lock); | 2039 | spin_unlock(&serial->serial_lock); |
2016 | if (status) { | 2040 | if (status) { |
2017 | log_usb_status(status, __func__); | 2041 | handle_usb_error(status, __func__, serial->parent); |
2018 | tty_kref_put(tty); | 2042 | tty_kref_put(tty); |
2019 | return; | 2043 | return; |
2020 | } | 2044 | } |
@@ -2358,12 +2382,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
2358 | serial->tx_data_length = tx_size; | 2382 | serial->tx_data_length = tx_size; |
2359 | serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); | 2383 | serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); |
2360 | if (!serial->tx_data) { | 2384 | if (!serial->tx_data) { |
2361 | dev_err(dev, "%s - Out of memory", __func__); | 2385 | dev_err(dev, "%s - Out of memory\n", __func__); |
2362 | goto exit; | 2386 | goto exit; |
2363 | } | 2387 | } |
2364 | serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); | 2388 | serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); |
2365 | if (!serial->tx_buffer) { | 2389 | if (!serial->tx_buffer) { |
2366 | dev_err(dev, "%s - Out of memory", __func__); | 2390 | dev_err(dev, "%s - Out of memory\n", __func__); |
2367 | goto exit; | 2391 | goto exit; |
2368 | } | 2392 | } |
2369 | 2393 | ||
@@ -2391,6 +2415,7 @@ static struct hso_device *hso_create_device(struct usb_interface *intf, | |||
2391 | 2415 | ||
2392 | INIT_WORK(&hso_dev->async_get_intf, async_get_intf); | 2416 | INIT_WORK(&hso_dev->async_get_intf, async_get_intf); |
2393 | INIT_WORK(&hso_dev->async_put_intf, async_put_intf); | 2417 | INIT_WORK(&hso_dev->async_put_intf, async_put_intf); |
2418 | INIT_WORK(&hso_dev->reset_device, reset_device); | ||
2394 | 2419 | ||
2395 | return hso_dev; | 2420 | return hso_dev; |
2396 | } | 2421 | } |
@@ -2831,13 +2856,14 @@ struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) | |||
2831 | 2856 | ||
2832 | mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); | 2857 | mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); |
2833 | if (!mux->shared_intr_urb) { | 2858 | if (!mux->shared_intr_urb) { |
2834 | dev_err(&interface->dev, "Could not allocate intr urb?"); | 2859 | dev_err(&interface->dev, "Could not allocate intr urb?\n"); |
2835 | goto exit; | 2860 | goto exit; |
2836 | } | 2861 | } |
2837 | mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize, | 2862 | mux->shared_intr_buf = |
2838 | GFP_KERNEL); | 2863 | kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize), |
2864 | GFP_KERNEL); | ||
2839 | if (!mux->shared_intr_buf) { | 2865 | if (!mux->shared_intr_buf) { |
2840 | dev_err(&interface->dev, "Could not allocate intr buf?"); | 2866 | dev_err(&interface->dev, "Could not allocate intr buf?\n"); |
2841 | goto exit; | 2867 | goto exit; |
2842 | } | 2868 | } |
2843 | 2869 | ||
@@ -2982,8 +3008,8 @@ static int hso_probe(struct usb_interface *interface, | |||
2982 | 3008 | ||
2983 | case HSO_INTF_BULK: | 3009 | case HSO_INTF_BULK: |
2984 | /* It's a regular bulk interface */ | 3010 | /* It's a regular bulk interface */ |
2985 | if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) | 3011 | if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) && |
2986 | && !disable_net) | 3012 | !disable_net) |
2987 | hso_dev = hso_create_net_device(interface, port_spec); | 3013 | hso_dev = hso_create_net_device(interface, port_spec); |
2988 | else | 3014 | else |
2989 | hso_dev = | 3015 | hso_dev = |
@@ -3132,6 +3158,26 @@ out: | |||
3132 | return result; | 3158 | return result; |
3133 | } | 3159 | } |
3134 | 3160 | ||
3161 | static void reset_device(struct work_struct *data) | ||
3162 | { | ||
3163 | struct hso_device *hso_dev = | ||
3164 | container_of(data, struct hso_device, reset_device); | ||
3165 | struct usb_device *usb = hso_dev->usb; | ||
3166 | int result; | ||
3167 | |||
3168 | if (hso_dev->usb_gone) { | ||
3169 | D1("No reset during disconnect\n"); | ||
3170 | } else { | ||
3171 | result = usb_lock_device_for_reset(usb, hso_dev->interface); | ||
3172 | if (result < 0) | ||
3173 | D1("unable to lock device for reset: %d\n", result); | ||
3174 | else { | ||
3175 | usb_reset_device(usb); | ||
3176 | usb_unlock_device(usb); | ||
3177 | } | ||
3178 | } | ||
3179 | } | ||
3180 | |||
3135 | static void hso_serial_ref_free(struct kref *ref) | 3181 | static void hso_serial_ref_free(struct kref *ref) |
3136 | { | 3182 | { |
3137 | struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); | 3183 | struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); |
@@ -3146,8 +3192,8 @@ static void hso_free_interface(struct usb_interface *interface) | |||
3146 | int i; | 3192 | int i; |
3147 | 3193 | ||
3148 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { | 3194 | for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { |
3149 | if (serial_table[i] | 3195 | if (serial_table[i] && |
3150 | && (serial_table[i]->interface == interface)) { | 3196 | (serial_table[i]->interface == interface)) { |
3151 | hso_dev = dev2ser(serial_table[i]); | 3197 | hso_dev = dev2ser(serial_table[i]); |
3152 | spin_lock_irq(&hso_dev->serial_lock); | 3198 | spin_lock_irq(&hso_dev->serial_lock); |
3153 | tty = tty_kref_get(hso_dev->tty); | 3199 | tty = tty_kref_get(hso_dev->tty); |
@@ -3163,8 +3209,8 @@ static void hso_free_interface(struct usb_interface *interface) | |||
3163 | } | 3209 | } |
3164 | 3210 | ||
3165 | for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { | 3211 | for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { |
3166 | if (network_table[i] | 3212 | if (network_table[i] && |
3167 | && (network_table[i]->interface == interface)) { | 3213 | (network_table[i]->interface == interface)) { |
3168 | struct rfkill *rfk = dev2net(network_table[i])->rfkill; | 3214 | struct rfkill *rfk = dev2net(network_table[i])->rfkill; |
3169 | /* hso_stop_net_device doesn't stop the net queue since | 3215 | /* hso_stop_net_device doesn't stop the net queue since |
3170 | * traffic needs to start it again when suspended */ | 3216 | * traffic needs to start it again when suspended */ |
@@ -3232,13 +3278,13 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, | |||
3232 | usb_rcvintpipe(usb, | 3278 | usb_rcvintpipe(usb, |
3233 | shared_int->intr_endp->bEndpointAddress & 0x7F), | 3279 | shared_int->intr_endp->bEndpointAddress & 0x7F), |
3234 | shared_int->shared_intr_buf, | 3280 | shared_int->shared_intr_buf, |
3235 | shared_int->intr_endp->wMaxPacketSize, | 3281 | 1, |
3236 | intr_callback, shared_int, | 3282 | intr_callback, shared_int, |
3237 | shared_int->intr_endp->bInterval); | 3283 | shared_int->intr_endp->bInterval); |
3238 | 3284 | ||
3239 | result = usb_submit_urb(shared_int->shared_intr_urb, gfp); | 3285 | result = usb_submit_urb(shared_int->shared_intr_urb, gfp); |
3240 | if (result) | 3286 | if (result) |
3241 | dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__, | 3287 | dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__, |
3242 | result); | 3288 | result); |
3243 | 3289 | ||
3244 | return result; | 3290 | return result; |
diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c index 55cf7081de10..be02a25da71a 100644 --- a/drivers/net/usb/int51x1.c +++ b/drivers/net/usb/int51x1.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <linux/ethtool.h> | 31 | #include <linux/ethtool.h> |
32 | #include <linux/slab.h> | ||
32 | #include <linux/mii.h> | 33 | #include <linux/mii.h> |
33 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
34 | #include <linux/usb/usbnet.h> | 35 | #include <linux/usb/usbnet.h> |
@@ -51,7 +52,7 @@ static int int51x1_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
51 | int len; | 52 | int len; |
52 | 53 | ||
53 | if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) { | 54 | if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) { |
54 | deverr(dev, "unexpected tiny rx frame"); | 55 | netdev_err(dev->net, "unexpected tiny rx frame\n"); |
55 | return 0; | 56 | return 0; |
56 | } | 57 | } |
57 | 58 | ||
@@ -138,25 +139,25 @@ static void int51x1_set_multicast(struct net_device *netdev) | |||
138 | if (netdev->flags & IFF_PROMISC) { | 139 | if (netdev->flags & IFF_PROMISC) { |
139 | /* do not expect to see traffic of other PLCs */ | 140 | /* do not expect to see traffic of other PLCs */ |
140 | filter |= PACKET_TYPE_PROMISCUOUS; | 141 | filter |= PACKET_TYPE_PROMISCUOUS; |
141 | devinfo(dev, "promiscuous mode enabled"); | 142 | netdev_info(dev->net, "promiscuous mode enabled\n"); |
142 | } else if (netdev->mc_count || | 143 | } else if (!netdev_mc_empty(netdev) || |
143 | (netdev->flags & IFF_ALLMULTI)) { | 144 | (netdev->flags & IFF_ALLMULTI)) { |
144 | filter |= PACKET_TYPE_ALL_MULTICAST; | 145 | filter |= PACKET_TYPE_ALL_MULTICAST; |
145 | devdbg(dev, "receive all multicast enabled"); | 146 | netdev_dbg(dev->net, "receive all multicast enabled\n"); |
146 | } else { | 147 | } else { |
147 | /* ~PROMISCUOUS, ~MULTICAST */ | 148 | /* ~PROMISCUOUS, ~MULTICAST */ |
148 | devdbg(dev, "receive own packets only"); | 149 | netdev_dbg(dev->net, "receive own packets only\n"); |
149 | } | 150 | } |
150 | 151 | ||
151 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 152 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
152 | if (!urb) { | 153 | if (!urb) { |
153 | devwarn(dev, "Error allocating URB"); | 154 | netdev_warn(dev->net, "Error allocating URB\n"); |
154 | return; | 155 | return; |
155 | } | 156 | } |
156 | 157 | ||
157 | req = kmalloc(sizeof(*req), GFP_ATOMIC); | 158 | req = kmalloc(sizeof(*req), GFP_ATOMIC); |
158 | if (!req) { | 159 | if (!req) { |
159 | devwarn(dev, "Error allocating control msg"); | 160 | netdev_warn(dev->net, "Error allocating control msg\n"); |
160 | goto out; | 161 | goto out; |
161 | } | 162 | } |
162 | 163 | ||
@@ -173,7 +174,8 @@ static void int51x1_set_multicast(struct net_device *netdev) | |||
173 | 174 | ||
174 | status = usb_submit_urb(urb, GFP_ATOMIC); | 175 | status = usb_submit_urb(urb, GFP_ATOMIC); |
175 | if (status < 0) { | 176 | if (status < 0) { |
176 | devwarn(dev, "Error submitting control msg, sts=%d", status); | 177 | netdev_warn(dev->net, "Error submitting control msg, sts=%d\n", |
178 | status); | ||
177 | goto out1; | 179 | goto out1; |
178 | } | 180 | } |
179 | return; | 181 | return; |
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c new file mode 100644 index 000000000000..418825d26f90 --- /dev/null +++ b/drivers/net/usb/ipheth.c | |||
@@ -0,0 +1,569 @@ | |||
1 | /* | ||
2 | * ipheth.c - Apple iPhone USB Ethernet driver | ||
3 | * | ||
4 | * Copyright (c) 2009 Diego Giagio <diego@giagio.com> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of GIAGIO.COM nor the names of its contributors | ||
16 | * may be used to endorse or promote products derived from this software | ||
17 | * without specific prior written permission. | ||
18 | * | ||
19 | * Alternatively, provided that this notice is retained in full, this | ||
20 | * software may be distributed under the terms of the GNU General | ||
21 | * Public License ("GPL") version 2, in which case the provisions of the | ||
22 | * GPL apply INSTEAD OF those given above. | ||
23 | * | ||
24 | * The provided data structures and external interfaces from this code | ||
25 | * are not restricted to be used by modules with a GPL compatible license. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
30 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
31 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
32 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
33 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
34 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
35 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
36 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
37 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
38 | * DAMAGE. | ||
39 | * | ||
40 | * | ||
41 | * Attention: iPhone device must be paired, otherwise it won't respond to our | ||
42 | * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver | ||
43 | * | ||
44 | */ | ||
45 | |||
46 | #include <linux/kernel.h> | ||
47 | #include <linux/errno.h> | ||
48 | #include <linux/init.h> | ||
49 | #include <linux/slab.h> | ||
50 | #include <linux/module.h> | ||
51 | #include <linux/netdevice.h> | ||
52 | #include <linux/etherdevice.h> | ||
53 | #include <linux/ethtool.h> | ||
54 | #include <linux/usb.h> | ||
55 | #include <linux/workqueue.h> | ||
56 | |||
57 | #define USB_VENDOR_APPLE 0x05ac | ||
58 | #define USB_PRODUCT_IPHONE 0x1290 | ||
59 | #define USB_PRODUCT_IPHONE_3G 0x1292 | ||
60 | #define USB_PRODUCT_IPHONE_3GS 0x1294 | ||
61 | |||
62 | #define IPHETH_USBINTF_CLASS 255 | ||
63 | #define IPHETH_USBINTF_SUBCLASS 253 | ||
64 | #define IPHETH_USBINTF_PROTO 1 | ||
65 | |||
66 | #define IPHETH_BUF_SIZE 1516 | ||
67 | #define IPHETH_TX_TIMEOUT (5 * HZ) | ||
68 | |||
69 | #define IPHETH_INTFNUM 2 | ||
70 | #define IPHETH_ALT_INTFNUM 1 | ||
71 | |||
72 | #define IPHETH_CTRL_ENDP 0x00 | ||
73 | #define IPHETH_CTRL_BUF_SIZE 0x40 | ||
74 | #define IPHETH_CTRL_TIMEOUT (5 * HZ) | ||
75 | |||
76 | #define IPHETH_CMD_GET_MACADDR 0x00 | ||
77 | #define IPHETH_CMD_CARRIER_CHECK 0x45 | ||
78 | |||
79 | #define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ) | ||
80 | #define IPHETH_CARRIER_ON 0x04 | ||
81 | |||
82 | static struct usb_device_id ipheth_table[] = { | ||
83 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
84 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE, | ||
85 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
86 | IPHETH_USBINTF_PROTO) }, | ||
87 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
88 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G, | ||
89 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
90 | IPHETH_USBINTF_PROTO) }, | ||
91 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
92 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, | ||
93 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
94 | IPHETH_USBINTF_PROTO) }, | ||
95 | { } | ||
96 | }; | ||
97 | MODULE_DEVICE_TABLE(usb, ipheth_table); | ||
98 | |||
99 | struct ipheth_device { | ||
100 | struct usb_device *udev; | ||
101 | struct usb_interface *intf; | ||
102 | struct net_device *net; | ||
103 | struct sk_buff *tx_skb; | ||
104 | struct urb *tx_urb; | ||
105 | struct urb *rx_urb; | ||
106 | unsigned char *tx_buf; | ||
107 | unsigned char *rx_buf; | ||
108 | unsigned char *ctrl_buf; | ||
109 | u8 bulk_in; | ||
110 | u8 bulk_out; | ||
111 | struct delayed_work carrier_work; | ||
112 | }; | ||
113 | |||
114 | static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags); | ||
115 | |||
116 | static int ipheth_alloc_urbs(struct ipheth_device *iphone) | ||
117 | { | ||
118 | struct urb *tx_urb = NULL; | ||
119 | struct urb *rx_urb = NULL; | ||
120 | u8 *tx_buf = NULL; | ||
121 | u8 *rx_buf = NULL; | ||
122 | |||
123 | tx_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
124 | if (tx_urb == NULL) | ||
125 | goto error_nomem; | ||
126 | |||
127 | rx_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
128 | if (rx_urb == NULL) | ||
129 | goto free_tx_urb; | ||
130 | |||
131 | tx_buf = usb_buffer_alloc(iphone->udev, | ||
132 | IPHETH_BUF_SIZE, | ||
133 | GFP_KERNEL, | ||
134 | &tx_urb->transfer_dma); | ||
135 | if (tx_buf == NULL) | ||
136 | goto free_rx_urb; | ||
137 | |||
138 | rx_buf = usb_buffer_alloc(iphone->udev, | ||
139 | IPHETH_BUF_SIZE, | ||
140 | GFP_KERNEL, | ||
141 | &rx_urb->transfer_dma); | ||
142 | if (rx_buf == NULL) | ||
143 | goto free_tx_buf; | ||
144 | |||
145 | |||
146 | iphone->tx_urb = tx_urb; | ||
147 | iphone->rx_urb = rx_urb; | ||
148 | iphone->tx_buf = tx_buf; | ||
149 | iphone->rx_buf = rx_buf; | ||
150 | return 0; | ||
151 | |||
152 | free_tx_buf: | ||
153 | usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, tx_buf, | ||
154 | tx_urb->transfer_dma); | ||
155 | free_rx_urb: | ||
156 | usb_free_urb(rx_urb); | ||
157 | free_tx_urb: | ||
158 | usb_free_urb(tx_urb); | ||
159 | error_nomem: | ||
160 | return -ENOMEM; | ||
161 | } | ||
162 | |||
163 | static void ipheth_free_urbs(struct ipheth_device *iphone) | ||
164 | { | ||
165 | usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf, | ||
166 | iphone->rx_urb->transfer_dma); | ||
167 | usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, | ||
168 | iphone->tx_urb->transfer_dma); | ||
169 | usb_free_urb(iphone->rx_urb); | ||
170 | usb_free_urb(iphone->tx_urb); | ||
171 | } | ||
172 | |||
173 | static void ipheth_kill_urbs(struct ipheth_device *dev) | ||
174 | { | ||
175 | usb_kill_urb(dev->tx_urb); | ||
176 | usb_kill_urb(dev->rx_urb); | ||
177 | } | ||
178 | |||
179 | static void ipheth_rcvbulk_callback(struct urb *urb) | ||
180 | { | ||
181 | struct ipheth_device *dev; | ||
182 | struct sk_buff *skb; | ||
183 | int status; | ||
184 | char *buf; | ||
185 | int len; | ||
186 | |||
187 | dev = urb->context; | ||
188 | if (dev == NULL) | ||
189 | return; | ||
190 | |||
191 | status = urb->status; | ||
192 | switch (status) { | ||
193 | case -ENOENT: | ||
194 | case -ECONNRESET: | ||
195 | case -ESHUTDOWN: | ||
196 | return; | ||
197 | case 0: | ||
198 | break; | ||
199 | default: | ||
200 | err("%s: urb status: %d", __func__, urb->status); | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | len = urb->actual_length; | ||
205 | buf = urb->transfer_buffer; | ||
206 | |||
207 | skb = dev_alloc_skb(NET_IP_ALIGN + len); | ||
208 | if (!skb) { | ||
209 | err("%s: dev_alloc_skb: -ENOMEM", __func__); | ||
210 | dev->net->stats.rx_dropped++; | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | skb_reserve(skb, NET_IP_ALIGN); | ||
215 | memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN); | ||
216 | skb->dev = dev->net; | ||
217 | skb->protocol = eth_type_trans(skb, dev->net); | ||
218 | |||
219 | dev->net->stats.rx_packets++; | ||
220 | dev->net->stats.rx_bytes += len; | ||
221 | |||
222 | netif_rx(skb); | ||
223 | ipheth_rx_submit(dev, GFP_ATOMIC); | ||
224 | } | ||
225 | |||
226 | static void ipheth_sndbulk_callback(struct urb *urb) | ||
227 | { | ||
228 | struct ipheth_device *dev; | ||
229 | |||
230 | dev = urb->context; | ||
231 | if (dev == NULL) | ||
232 | return; | ||
233 | |||
234 | if (urb->status != 0 && | ||
235 | urb->status != -ENOENT && | ||
236 | urb->status != -ECONNRESET && | ||
237 | urb->status != -ESHUTDOWN) | ||
238 | err("%s: urb status: %d", __func__, urb->status); | ||
239 | |||
240 | dev_kfree_skb_irq(dev->tx_skb); | ||
241 | netif_wake_queue(dev->net); | ||
242 | } | ||
243 | |||
244 | static int ipheth_carrier_set(struct ipheth_device *dev) | ||
245 | { | ||
246 | struct usb_device *udev = dev->udev; | ||
247 | int retval; | ||
248 | |||
249 | retval = usb_control_msg(udev, | ||
250 | usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), | ||
251 | IPHETH_CMD_CARRIER_CHECK, /* request */ | ||
252 | 0xc0, /* request type */ | ||
253 | 0x00, /* value */ | ||
254 | 0x02, /* index */ | ||
255 | dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE, | ||
256 | IPHETH_CTRL_TIMEOUT); | ||
257 | if (retval < 0) { | ||
258 | err("%s: usb_control_msg: %d", __func__, retval); | ||
259 | return retval; | ||
260 | } | ||
261 | |||
262 | if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) | ||
263 | netif_carrier_on(dev->net); | ||
264 | else | ||
265 | netif_carrier_off(dev->net); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static void ipheth_carrier_check_work(struct work_struct *work) | ||
271 | { | ||
272 | struct ipheth_device *dev = container_of(work, struct ipheth_device, | ||
273 | carrier_work.work); | ||
274 | |||
275 | ipheth_carrier_set(dev); | ||
276 | schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); | ||
277 | } | ||
278 | |||
279 | static int ipheth_get_macaddr(struct ipheth_device *dev) | ||
280 | { | ||
281 | struct usb_device *udev = dev->udev; | ||
282 | struct net_device *net = dev->net; | ||
283 | int retval; | ||
284 | |||
285 | retval = usb_control_msg(udev, | ||
286 | usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP), | ||
287 | IPHETH_CMD_GET_MACADDR, /* request */ | ||
288 | 0xc0, /* request type */ | ||
289 | 0x00, /* value */ | ||
290 | 0x02, /* index */ | ||
291 | dev->ctrl_buf, | ||
292 | IPHETH_CTRL_BUF_SIZE, | ||
293 | IPHETH_CTRL_TIMEOUT); | ||
294 | if (retval < 0) { | ||
295 | err("%s: usb_control_msg: %d", __func__, retval); | ||
296 | } else if (retval < ETH_ALEN) { | ||
297 | err("%s: usb_control_msg: short packet: %d bytes", | ||
298 | __func__, retval); | ||
299 | retval = -EINVAL; | ||
300 | } else { | ||
301 | memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN); | ||
302 | retval = 0; | ||
303 | } | ||
304 | |||
305 | return retval; | ||
306 | } | ||
307 | |||
308 | static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) | ||
309 | { | ||
310 | struct usb_device *udev = dev->udev; | ||
311 | int retval; | ||
312 | |||
313 | usb_fill_bulk_urb(dev->rx_urb, udev, | ||
314 | usb_rcvbulkpipe(udev, dev->bulk_in), | ||
315 | dev->rx_buf, IPHETH_BUF_SIZE, | ||
316 | ipheth_rcvbulk_callback, | ||
317 | dev); | ||
318 | dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
319 | |||
320 | retval = usb_submit_urb(dev->rx_urb, mem_flags); | ||
321 | if (retval) | ||
322 | err("%s: usb_submit_urb: %d", __func__, retval); | ||
323 | return retval; | ||
324 | } | ||
325 | |||
326 | static int ipheth_open(struct net_device *net) | ||
327 | { | ||
328 | struct ipheth_device *dev = netdev_priv(net); | ||
329 | struct usb_device *udev = dev->udev; | ||
330 | int retval = 0; | ||
331 | |||
332 | usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM); | ||
333 | |||
334 | retval = ipheth_carrier_set(dev); | ||
335 | if (retval) | ||
336 | return retval; | ||
337 | |||
338 | retval = ipheth_rx_submit(dev, GFP_KERNEL); | ||
339 | if (retval) | ||
340 | return retval; | ||
341 | |||
342 | schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT); | ||
343 | netif_start_queue(net); | ||
344 | return retval; | ||
345 | } | ||
346 | |||
347 | static int ipheth_close(struct net_device *net) | ||
348 | { | ||
349 | struct ipheth_device *dev = netdev_priv(net); | ||
350 | |||
351 | cancel_delayed_work_sync(&dev->carrier_work); | ||
352 | netif_stop_queue(net); | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int ipheth_tx(struct sk_buff *skb, struct net_device *net) | ||
357 | { | ||
358 | struct ipheth_device *dev = netdev_priv(net); | ||
359 | struct usb_device *udev = dev->udev; | ||
360 | int retval; | ||
361 | |||
362 | /* Paranoid */ | ||
363 | if (skb->len > IPHETH_BUF_SIZE) { | ||
364 | WARN(1, "%s: skb too large: %d bytes", __func__, skb->len); | ||
365 | dev->net->stats.tx_dropped++; | ||
366 | dev_kfree_skb_irq(skb); | ||
367 | return NETDEV_TX_OK; | ||
368 | } | ||
369 | |||
370 | memcpy(dev->tx_buf, skb->data, skb->len); | ||
371 | if (skb->len < IPHETH_BUF_SIZE) | ||
372 | memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len); | ||
373 | |||
374 | usb_fill_bulk_urb(dev->tx_urb, udev, | ||
375 | usb_sndbulkpipe(udev, dev->bulk_out), | ||
376 | dev->tx_buf, IPHETH_BUF_SIZE, | ||
377 | ipheth_sndbulk_callback, | ||
378 | dev); | ||
379 | dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
380 | |||
381 | retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC); | ||
382 | if (retval) { | ||
383 | err("%s: usb_submit_urb: %d", __func__, retval); | ||
384 | dev->net->stats.tx_errors++; | ||
385 | dev_kfree_skb_irq(skb); | ||
386 | } else { | ||
387 | dev->tx_skb = skb; | ||
388 | |||
389 | dev->net->stats.tx_packets++; | ||
390 | dev->net->stats.tx_bytes += skb->len; | ||
391 | netif_stop_queue(net); | ||
392 | } | ||
393 | |||
394 | return NETDEV_TX_OK; | ||
395 | } | ||
396 | |||
397 | static void ipheth_tx_timeout(struct net_device *net) | ||
398 | { | ||
399 | struct ipheth_device *dev = netdev_priv(net); | ||
400 | |||
401 | err("%s: TX timeout", __func__); | ||
402 | dev->net->stats.tx_errors++; | ||
403 | usb_unlink_urb(dev->tx_urb); | ||
404 | } | ||
405 | |||
406 | static struct net_device_stats *ipheth_stats(struct net_device *net) | ||
407 | { | ||
408 | struct ipheth_device *dev = netdev_priv(net); | ||
409 | return &dev->net->stats; | ||
410 | } | ||
411 | |||
412 | static u32 ipheth_ethtool_op_get_link(struct net_device *net) | ||
413 | { | ||
414 | struct ipheth_device *dev = netdev_priv(net); | ||
415 | return netif_carrier_ok(dev->net); | ||
416 | } | ||
417 | |||
418 | static struct ethtool_ops ops = { | ||
419 | .get_link = ipheth_ethtool_op_get_link | ||
420 | }; | ||
421 | |||
422 | static const struct net_device_ops ipheth_netdev_ops = { | ||
423 | .ndo_open = &ipheth_open, | ||
424 | .ndo_stop = &ipheth_close, | ||
425 | .ndo_start_xmit = &ipheth_tx, | ||
426 | .ndo_tx_timeout = &ipheth_tx_timeout, | ||
427 | .ndo_get_stats = &ipheth_stats, | ||
428 | }; | ||
429 | |||
430 | static struct device_type ipheth_type = { | ||
431 | .name = "wwan", | ||
432 | }; | ||
433 | |||
434 | static int ipheth_probe(struct usb_interface *intf, | ||
435 | const struct usb_device_id *id) | ||
436 | { | ||
437 | struct usb_device *udev = interface_to_usbdev(intf); | ||
438 | struct usb_host_interface *hintf; | ||
439 | struct usb_endpoint_descriptor *endp; | ||
440 | struct ipheth_device *dev; | ||
441 | struct net_device *netdev; | ||
442 | int i; | ||
443 | int retval; | ||
444 | |||
445 | netdev = alloc_etherdev(sizeof(struct ipheth_device)); | ||
446 | if (!netdev) | ||
447 | return -ENOMEM; | ||
448 | |||
449 | netdev->netdev_ops = &ipheth_netdev_ops; | ||
450 | netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; | ||
451 | strcpy(netdev->name, "wwan%d"); | ||
452 | |||
453 | dev = netdev_priv(netdev); | ||
454 | dev->udev = udev; | ||
455 | dev->net = netdev; | ||
456 | dev->intf = intf; | ||
457 | |||
458 | /* Set up endpoints */ | ||
459 | hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); | ||
460 | if (hintf == NULL) { | ||
461 | retval = -ENODEV; | ||
462 | err("Unable to find alternate settings interface"); | ||
463 | goto err_endpoints; | ||
464 | } | ||
465 | |||
466 | for (i = 0; i < hintf->desc.bNumEndpoints; i++) { | ||
467 | endp = &hintf->endpoint[i].desc; | ||
468 | if (usb_endpoint_is_bulk_in(endp)) | ||
469 | dev->bulk_in = endp->bEndpointAddress; | ||
470 | else if (usb_endpoint_is_bulk_out(endp)) | ||
471 | dev->bulk_out = endp->bEndpointAddress; | ||
472 | } | ||
473 | if (!(dev->bulk_in && dev->bulk_out)) { | ||
474 | retval = -ENODEV; | ||
475 | err("Unable to find endpoints"); | ||
476 | goto err_endpoints; | ||
477 | } | ||
478 | |||
479 | dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL); | ||
480 | if (dev->ctrl_buf == NULL) { | ||
481 | retval = -ENOMEM; | ||
482 | goto err_alloc_ctrl_buf; | ||
483 | } | ||
484 | |||
485 | retval = ipheth_get_macaddr(dev); | ||
486 | if (retval) | ||
487 | goto err_get_macaddr; | ||
488 | |||
489 | INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work); | ||
490 | |||
491 | retval = ipheth_alloc_urbs(dev); | ||
492 | if (retval) { | ||
493 | err("error allocating urbs: %d", retval); | ||
494 | goto err_alloc_urbs; | ||
495 | } | ||
496 | |||
497 | usb_set_intfdata(intf, dev); | ||
498 | |||
499 | SET_NETDEV_DEV(netdev, &intf->dev); | ||
500 | SET_ETHTOOL_OPS(netdev, &ops); | ||
501 | SET_NETDEV_DEVTYPE(netdev, &ipheth_type); | ||
502 | |||
503 | retval = register_netdev(netdev); | ||
504 | if (retval) { | ||
505 | err("error registering netdev: %d", retval); | ||
506 | retval = -EIO; | ||
507 | goto err_register_netdev; | ||
508 | } | ||
509 | |||
510 | dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n"); | ||
511 | return 0; | ||
512 | |||
513 | err_register_netdev: | ||
514 | ipheth_free_urbs(dev); | ||
515 | err_alloc_urbs: | ||
516 | err_get_macaddr: | ||
517 | err_alloc_ctrl_buf: | ||
518 | kfree(dev->ctrl_buf); | ||
519 | err_endpoints: | ||
520 | free_netdev(netdev); | ||
521 | return retval; | ||
522 | } | ||
523 | |||
524 | static void ipheth_disconnect(struct usb_interface *intf) | ||
525 | { | ||
526 | struct ipheth_device *dev; | ||
527 | |||
528 | dev = usb_get_intfdata(intf); | ||
529 | if (dev != NULL) { | ||
530 | unregister_netdev(dev->net); | ||
531 | ipheth_kill_urbs(dev); | ||
532 | ipheth_free_urbs(dev); | ||
533 | kfree(dev->ctrl_buf); | ||
534 | free_netdev(dev->net); | ||
535 | } | ||
536 | usb_set_intfdata(intf, NULL); | ||
537 | dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n"); | ||
538 | } | ||
539 | |||
540 | static struct usb_driver ipheth_driver = { | ||
541 | .name = "ipheth", | ||
542 | .probe = ipheth_probe, | ||
543 | .disconnect = ipheth_disconnect, | ||
544 | .id_table = ipheth_table, | ||
545 | }; | ||
546 | |||
547 | static int __init ipheth_init(void) | ||
548 | { | ||
549 | int retval; | ||
550 | |||
551 | retval = usb_register(&ipheth_driver); | ||
552 | if (retval) { | ||
553 | err("usb_register failed: %d", retval); | ||
554 | return retval; | ||
555 | } | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static void __exit ipheth_exit(void) | ||
560 | { | ||
561 | usb_deregister(&ipheth_driver); | ||
562 | } | ||
563 | |||
564 | module_init(ipheth_init); | ||
565 | module_exit(ipheth_exit); | ||
566 | |||
567 | MODULE_AUTHOR("Diego Giagio <diego@giagio.com>"); | ||
568 | MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver"); | ||
569 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index e391ef969c28..c4c334d9770f 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -145,6 +145,7 @@ static struct usb_device_id usb_klsi_table[] = { | |||
145 | { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */ | 145 | { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */ |
146 | { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */ | 146 | { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */ |
147 | { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */ | 147 | { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */ |
148 | { USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */ | ||
148 | { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */ | 149 | { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */ |
149 | { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */ | 150 | { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */ |
150 | { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */ | 151 | { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */ |
@@ -471,16 +472,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) | |||
471 | int result; | 472 | int result; |
472 | 473 | ||
473 | dbg("kaweth_reset(%p)", kaweth); | 474 | dbg("kaweth_reset(%p)", kaweth); |
474 | result = kaweth_control(kaweth, | 475 | result = usb_reset_configuration(kaweth->dev); |
475 | usb_sndctrlpipe(kaweth->dev, 0), | ||
476 | USB_REQ_SET_CONFIGURATION, | ||
477 | 0, | ||
478 | kaweth->dev->config[0].desc.bConfigurationValue, | ||
479 | 0, | ||
480 | NULL, | ||
481 | 0, | ||
482 | KAWETH_CONTROL_TIMEOUT); | ||
483 | |||
484 | mdelay(10); | 476 | mdelay(10); |
485 | 477 | ||
486 | dbg("kaweth_reset() returns %d.",result); | 478 | dbg("kaweth_reset() returns %d.",result); |
@@ -725,7 +717,7 @@ static int kaweth_open(struct net_device *net) | |||
725 | return 0; | 717 | return 0; |
726 | 718 | ||
727 | err_out: | 719 | err_out: |
728 | usb_autopm_enable(kaweth->intf); | 720 | usb_autopm_put_interface(kaweth->intf); |
729 | return -EIO; | 721 | return -EIO; |
730 | } | 722 | } |
731 | 723 | ||
@@ -762,7 +754,7 @@ static int kaweth_close(struct net_device *net) | |||
762 | 754 | ||
763 | kaweth->status &= ~KAWETH_STATUS_CLOSING; | 755 | kaweth->status &= ~KAWETH_STATUS_CLOSING; |
764 | 756 | ||
765 | usb_autopm_enable(kaweth->intf); | 757 | usb_autopm_put_interface(kaweth->intf); |
766 | 758 | ||
767 | return 0; | 759 | return 0; |
768 | } | 760 | } |
@@ -890,7 +882,7 @@ static void kaweth_set_rx_mode(struct net_device *net) | |||
890 | if (net->flags & IFF_PROMISC) { | 882 | if (net->flags & IFF_PROMISC) { |
891 | packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS; | 883 | packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS; |
892 | } | 884 | } |
893 | else if ((net->mc_count) || (net->flags & IFF_ALLMULTI)) { | 885 | else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) { |
894 | packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST; | 886 | packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST; |
895 | } | 887 | } |
896 | 888 | ||
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 10873d96b2da..9f24e3f871e1 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
@@ -1,13 +1,27 @@ | |||
1 | /* | 1 | /* |
2 | * MosChips MCS7830 based USB 2.0 Ethernet Devices | 2 | * MOSCHIP MCS7830 based USB 2.0 Ethernet Devices |
3 | * | 3 | * |
4 | * based on usbnet.c, asix.c and the vendor provided mcs7830 driver | 4 | * based on usbnet.c, asix.c and the vendor provided mcs7830 driver |
5 | * | 5 | * |
6 | * Copyright (C) 2010 Andreas Mohr <andi@lisas.de> | ||
6 | * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de> | 7 | * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de> |
7 | * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> | 8 | * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> |
8 | * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net> | 9 | * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net> |
9 | * Copyright (c) 2002-2003 TiVo Inc. | 10 | * Copyright (c) 2002-2003 TiVo Inc. |
10 | * | 11 | * |
12 | * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!). | ||
13 | * | ||
14 | * TODO: | ||
15 | * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?) | ||
16 | * - implement ethtool_ops get_pauseparam/set_pauseparam | ||
17 | * via HIF_REG_PAUSE_THRESHOLD (>= revision C only!) | ||
18 | * - implement get_eeprom/[set_eeprom] | ||
19 | * - switch PHY on/off on ifup/ifdown (perhaps in usbnet.c, via MII) | ||
20 | * - mcs7830_get_regs() handling is weird: for rev 2 we return 32 regs, | ||
21 | * can access only ~ 24, remaining user buffer is uninitialized garbage | ||
22 | * - anything else? | ||
23 | * | ||
24 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 25 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 26 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 27 | * the Free Software Foundation; either version 2 of the License, or |
@@ -30,6 +44,7 @@ | |||
30 | #include <linux/mii.h> | 44 | #include <linux/mii.h> |
31 | #include <linux/module.h> | 45 | #include <linux/module.h> |
32 | #include <linux/netdevice.h> | 46 | #include <linux/netdevice.h> |
47 | #include <linux/slab.h> | ||
33 | #include <linux/usb.h> | 48 | #include <linux/usb.h> |
34 | #include <linux/usb/usbnet.h> | 49 | #include <linux/usb/usbnet.h> |
35 | 50 | ||
@@ -55,7 +70,7 @@ | |||
55 | ADVERTISE_100HALF | ADVERTISE_10FULL | \ | 70 | ADVERTISE_100HALF | ADVERTISE_10FULL | \ |
56 | ADVERTISE_10HALF | ADVERTISE_CSMA) | 71 | ADVERTISE_10HALF | ADVERTISE_CSMA) |
57 | 72 | ||
58 | /* HIF_REG_XX coressponding index value */ | 73 | /* HIF_REG_XX corresponding index value */ |
59 | enum { | 74 | enum { |
60 | HIF_REG_MULTICAST_HASH = 0x00, | 75 | HIF_REG_MULTICAST_HASH = 0x00, |
61 | HIF_REG_PACKET_GAP1 = 0x08, | 76 | HIF_REG_PACKET_GAP1 = 0x08, |
@@ -69,6 +84,7 @@ enum { | |||
69 | HIF_REG_PHY_CMD2_PEND_FLAG_BIT = 0x80, | 84 | HIF_REG_PHY_CMD2_PEND_FLAG_BIT = 0x80, |
70 | HIF_REG_PHY_CMD2_READY_FLAG_BIT = 0x40, | 85 | HIF_REG_PHY_CMD2_READY_FLAG_BIT = 0x40, |
71 | HIF_REG_CONFIG = 0x0e, | 86 | HIF_REG_CONFIG = 0x0e, |
87 | /* hmm, spec sez: "R/W", "Except bit 3" (likely TXENABLE). */ | ||
72 | HIF_REG_CONFIG_CFG = 0x80, | 88 | HIF_REG_CONFIG_CFG = 0x80, |
73 | HIF_REG_CONFIG_SPEED100 = 0x40, | 89 | HIF_REG_CONFIG_SPEED100 = 0x40, |
74 | HIF_REG_CONFIG_FULLDUPLEX_ENABLE = 0x20, | 90 | HIF_REG_CONFIG_FULLDUPLEX_ENABLE = 0x20, |
@@ -76,13 +92,24 @@ enum { | |||
76 | HIF_REG_CONFIG_TXENABLE = 0x08, | 92 | HIF_REG_CONFIG_TXENABLE = 0x08, |
77 | HIF_REG_CONFIG_SLEEPMODE = 0x04, | 93 | HIF_REG_CONFIG_SLEEPMODE = 0x04, |
78 | HIF_REG_CONFIG_ALLMULTICAST = 0x02, | 94 | HIF_REG_CONFIG_ALLMULTICAST = 0x02, |
79 | HIF_REG_CONFIG_PROMISCIOUS = 0x01, | 95 | HIF_REG_CONFIG_PROMISCUOUS = 0x01, |
80 | HIF_REG_ETHERNET_ADDR = 0x0f, | 96 | HIF_REG_ETHERNET_ADDR = 0x0f, |
81 | HIF_REG_22 = 0x15, | 97 | HIF_REG_FRAME_DROP_COUNTER = 0x15, /* 0..ff; reset: 0 */ |
82 | HIF_REG_PAUSE_THRESHOLD = 0x16, | 98 | HIF_REG_PAUSE_THRESHOLD = 0x16, |
83 | HIF_REG_PAUSE_THRESHOLD_DEFAULT = 0, | 99 | HIF_REG_PAUSE_THRESHOLD_DEFAULT = 0, |
84 | }; | 100 | }; |
85 | 101 | ||
102 | /* Trailing status byte in Ethernet Rx frame */ | ||
103 | enum { | ||
104 | MCS7830_RX_SHORT_FRAME = 0x01, /* < 64 bytes */ | ||
105 | MCS7830_RX_LENGTH_ERROR = 0x02, /* framelen != Ethernet length field */ | ||
106 | MCS7830_RX_ALIGNMENT_ERROR = 0x04, /* non-even number of nibbles */ | ||
107 | MCS7830_RX_CRC_ERROR = 0x08, | ||
108 | MCS7830_RX_LARGE_FRAME = 0x10, /* > 1518 bytes */ | ||
109 | MCS7830_RX_FRAME_CORRECT = 0x20, /* frame is correct */ | ||
110 | /* [7:6] reserved */ | ||
111 | }; | ||
112 | |||
86 | struct mcs7830_data { | 113 | struct mcs7830_data { |
87 | u8 multi_filter[8]; | 114 | u8 multi_filter[8]; |
88 | u8 config; | 115 | u8 config; |
@@ -109,7 +136,7 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) | |||
109 | return ret; | 136 | return ret; |
110 | } | 137 | } |
111 | 138 | ||
112 | static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data) | 139 | static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data) |
113 | { | 140 | { |
114 | struct usb_device *xdev = dev->udev; | 141 | struct usb_device *xdev = dev->udev; |
115 | int ret; | 142 | int ret; |
@@ -183,13 +210,43 @@ out: | |||
183 | usb_free_urb(urb); | 210 | usb_free_urb(urb); |
184 | } | 211 | } |
185 | 212 | ||
186 | static int mcs7830_get_address(struct usbnet *dev) | 213 | static int mcs7830_hif_get_mac_address(struct usbnet *dev, unsigned char *addr) |
214 | { | ||
215 | int ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr); | ||
216 | if (ret < 0) | ||
217 | return ret; | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int mcs7830_hif_set_mac_address(struct usbnet *dev, unsigned char *addr) | ||
222 | { | ||
223 | int ret = mcs7830_set_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, addr); | ||
224 | |||
225 | if (ret < 0) | ||
226 | return ret; | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int mcs7830_set_mac_address(struct net_device *netdev, void *p) | ||
187 | { | 231 | { |
188 | int ret; | 232 | int ret; |
189 | ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, | 233 | struct usbnet *dev = netdev_priv(netdev); |
190 | dev->net->dev_addr); | 234 | struct sockaddr *addr = p; |
235 | |||
236 | if (netif_running(netdev)) | ||
237 | return -EBUSY; | ||
238 | |||
239 | if (!is_valid_ether_addr(addr->sa_data)) | ||
240 | return -EINVAL; | ||
241 | |||
242 | ret = mcs7830_hif_set_mac_address(dev, addr->sa_data); | ||
243 | |||
191 | if (ret < 0) | 244 | if (ret < 0) |
192 | return ret; | 245 | return ret; |
246 | |||
247 | /* it worked --> adopt it on netdev side */ | ||
248 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | ||
249 | |||
193 | return 0; | 250 | return 0; |
194 | } | 251 | } |
195 | 252 | ||
@@ -307,7 +364,7 @@ static int mcs7830_get_rev(struct usbnet *dev) | |||
307 | { | 364 | { |
308 | u8 dummy[2]; | 365 | u8 dummy[2]; |
309 | int ret; | 366 | int ret; |
310 | ret = mcs7830_get_reg(dev, HIF_REG_22, 2, dummy); | 367 | ret = mcs7830_get_reg(dev, HIF_REG_FRAME_DROP_COUNTER, 2, dummy); |
311 | if (ret > 0) | 368 | if (ret > 0) |
312 | return 2; /* Rev C or later */ | 369 | return 2; /* Rev C or later */ |
313 | return 1; /* earlier revision */ | 370 | return 1; /* earlier revision */ |
@@ -331,33 +388,6 @@ static void mcs7830_rev_C_fixup(struct usbnet *dev) | |||
331 | } | 388 | } |
332 | } | 389 | } |
333 | 390 | ||
334 | static int mcs7830_init_dev(struct usbnet *dev) | ||
335 | { | ||
336 | int ret; | ||
337 | int retry; | ||
338 | |||
339 | /* Read MAC address from EEPROM */ | ||
340 | ret = -EINVAL; | ||
341 | for (retry = 0; retry < 5 && ret; retry++) | ||
342 | ret = mcs7830_get_address(dev); | ||
343 | if (ret) { | ||
344 | dev_warn(&dev->udev->dev, "Cannot read MAC address\n"); | ||
345 | goto out; | ||
346 | } | ||
347 | |||
348 | /* Set up PHY */ | ||
349 | ret = mcs7830_set_autoneg(dev, 0); | ||
350 | if (ret) { | ||
351 | dev_info(&dev->udev->dev, "Cannot set autoneg\n"); | ||
352 | goto out; | ||
353 | } | ||
354 | |||
355 | mcs7830_rev_C_fixup(dev); | ||
356 | ret = 0; | ||
357 | out: | ||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | static int mcs7830_mdio_read(struct net_device *netdev, int phy_id, | 391 | static int mcs7830_mdio_read(struct net_device *netdev, int phy_id, |
362 | int location) | 392 | int location) |
363 | { | 393 | { |
@@ -378,11 +408,33 @@ static int mcs7830_ioctl(struct net_device *net, struct ifreq *rq, int cmd) | |||
378 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | 408 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); |
379 | } | 409 | } |
380 | 410 | ||
381 | /* credits go to asix_set_multicast */ | 411 | static inline struct mcs7830_data *mcs7830_get_data(struct usbnet *dev) |
382 | static void mcs7830_set_multicast(struct net_device *net) | 412 | { |
413 | return (struct mcs7830_data *)&dev->data; | ||
414 | } | ||
415 | |||
416 | static void mcs7830_hif_update_multicast_hash(struct usbnet *dev) | ||
417 | { | ||
418 | struct mcs7830_data *data = mcs7830_get_data(dev); | ||
419 | mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH, | ||
420 | sizeof data->multi_filter, | ||
421 | data->multi_filter); | ||
422 | } | ||
423 | |||
424 | static void mcs7830_hif_update_config(struct usbnet *dev) | ||
425 | { | ||
426 | /* implementation specific to data->config | ||
427 | (argument needs to be heap-based anyway - USB DMA!) */ | ||
428 | struct mcs7830_data *data = mcs7830_get_data(dev); | ||
429 | mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config); | ||
430 | } | ||
431 | |||
432 | static void mcs7830_data_set_multicast(struct net_device *net) | ||
383 | { | 433 | { |
384 | struct usbnet *dev = netdev_priv(net); | 434 | struct usbnet *dev = netdev_priv(net); |
385 | struct mcs7830_data *data = (struct mcs7830_data *)&dev->data; | 435 | struct mcs7830_data *data = mcs7830_get_data(dev); |
436 | |||
437 | memset(data->multi_filter, 0, sizeof data->multi_filter); | ||
386 | 438 | ||
387 | data->config = HIF_REG_CONFIG_TXENABLE; | 439 | data->config = HIF_REG_CONFIG_TXENABLE; |
388 | 440 | ||
@@ -390,36 +442,64 @@ static void mcs7830_set_multicast(struct net_device *net) | |||
390 | data->config |= HIF_REG_CONFIG_ALLMULTICAST; | 442 | data->config |= HIF_REG_CONFIG_ALLMULTICAST; |
391 | 443 | ||
392 | if (net->flags & IFF_PROMISC) { | 444 | if (net->flags & IFF_PROMISC) { |
393 | data->config |= HIF_REG_CONFIG_PROMISCIOUS; | 445 | data->config |= HIF_REG_CONFIG_PROMISCUOUS; |
394 | } else if (net->flags & IFF_ALLMULTI | 446 | } else if (net->flags & IFF_ALLMULTI || |
395 | || net->mc_count > MCS7830_MAX_MCAST) { | 447 | netdev_mc_count(net) > MCS7830_MAX_MCAST) { |
396 | data->config |= HIF_REG_CONFIG_ALLMULTICAST; | 448 | data->config |= HIF_REG_CONFIG_ALLMULTICAST; |
397 | } else if (net->mc_count == 0) { | 449 | } else if (netdev_mc_empty(net)) { |
398 | /* just broadcast and directed */ | 450 | /* just broadcast and directed */ |
399 | } else { | 451 | } else { |
400 | /* We use the 20 byte dev->data | 452 | /* We use the 20 byte dev->data |
401 | * for our 8 byte filter buffer | 453 | * for our 8 byte filter buffer |
402 | * to avoid allocating memory that | 454 | * to avoid allocating memory that |
403 | * is tricky to free later */ | 455 | * is tricky to free later */ |
404 | struct dev_mc_list *mc_list = net->mc_list; | 456 | struct dev_mc_list *mc_list; |
405 | u32 crc_bits; | 457 | u32 crc_bits; |
406 | int i; | ||
407 | |||
408 | memset(data->multi_filter, 0, sizeof data->multi_filter); | ||
409 | 458 | ||
410 | /* Build the multicast hash filter. */ | 459 | /* Build the multicast hash filter. */ |
411 | for (i = 0; i < net->mc_count; i++) { | 460 | netdev_for_each_mc_addr(mc_list, net) { |
412 | crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; | 461 | crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; |
413 | data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); | 462 | data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7); |
414 | mc_list = mc_list->next; | ||
415 | } | 463 | } |
464 | } | ||
465 | } | ||
416 | 466 | ||
417 | mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH, | 467 | static int mcs7830_apply_base_config(struct usbnet *dev) |
418 | sizeof data->multi_filter, | 468 | { |
419 | data->multi_filter); | 469 | int ret; |
470 | |||
471 | /* re-configure known MAC (suspend case etc.) */ | ||
472 | ret = mcs7830_hif_set_mac_address(dev, dev->net->dev_addr); | ||
473 | if (ret) { | ||
474 | dev_info(&dev->udev->dev, "Cannot set MAC address\n"); | ||
475 | goto out; | ||
420 | } | 476 | } |
421 | 477 | ||
422 | mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config); | 478 | /* Set up PHY */ |
479 | ret = mcs7830_set_autoneg(dev, 0); | ||
480 | if (ret) { | ||
481 | dev_info(&dev->udev->dev, "Cannot set autoneg\n"); | ||
482 | goto out; | ||
483 | } | ||
484 | |||
485 | mcs7830_hif_update_multicast_hash(dev); | ||
486 | mcs7830_hif_update_config(dev); | ||
487 | |||
488 | mcs7830_rev_C_fixup(dev); | ||
489 | ret = 0; | ||
490 | out: | ||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | /* credits go to asix_set_multicast */ | ||
495 | static void mcs7830_set_multicast(struct net_device *net) | ||
496 | { | ||
497 | struct usbnet *dev = netdev_priv(net); | ||
498 | |||
499 | mcs7830_data_set_multicast(net); | ||
500 | |||
501 | mcs7830_hif_update_multicast_hash(dev); | ||
502 | mcs7830_hif_update_config(dev); | ||
423 | } | 503 | } |
424 | 504 | ||
425 | static int mcs7830_get_regs_len(struct net_device *net) | 505 | static int mcs7830_get_regs_len(struct net_device *net) |
@@ -463,29 +543,6 @@ static const struct ethtool_ops mcs7830_ethtool_ops = { | |||
463 | .nway_reset = usbnet_nway_reset, | 543 | .nway_reset = usbnet_nway_reset, |
464 | }; | 544 | }; |
465 | 545 | ||
466 | static int mcs7830_set_mac_address(struct net_device *netdev, void *p) | ||
467 | { | ||
468 | int ret; | ||
469 | struct usbnet *dev = netdev_priv(netdev); | ||
470 | struct sockaddr *addr = p; | ||
471 | |||
472 | if (netif_running(netdev)) | ||
473 | return -EBUSY; | ||
474 | |||
475 | if (!is_valid_ether_addr(addr->sa_data)) | ||
476 | return -EINVAL; | ||
477 | |||
478 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | ||
479 | |||
480 | ret = mcs7830_set_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN, | ||
481 | netdev->dev_addr); | ||
482 | |||
483 | if (ret < 0) | ||
484 | return ret; | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | static const struct net_device_ops mcs7830_netdev_ops = { | 546 | static const struct net_device_ops mcs7830_netdev_ops = { |
490 | .ndo_open = usbnet_open, | 547 | .ndo_open = usbnet_open, |
491 | .ndo_stop = usbnet_stop, | 548 | .ndo_stop = usbnet_stop, |
@@ -495,21 +552,32 @@ static const struct net_device_ops mcs7830_netdev_ops = { | |||
495 | .ndo_validate_addr = eth_validate_addr, | 552 | .ndo_validate_addr = eth_validate_addr, |
496 | .ndo_do_ioctl = mcs7830_ioctl, | 553 | .ndo_do_ioctl = mcs7830_ioctl, |
497 | .ndo_set_multicast_list = mcs7830_set_multicast, | 554 | .ndo_set_multicast_list = mcs7830_set_multicast, |
498 | .ndo_set_mac_address = mcs7830_set_mac_address, | 555 | .ndo_set_mac_address = mcs7830_set_mac_address, |
499 | }; | 556 | }; |
500 | 557 | ||
501 | static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) | 558 | static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) |
502 | { | 559 | { |
503 | struct net_device *net = dev->net; | 560 | struct net_device *net = dev->net; |
504 | int ret; | 561 | int ret; |
562 | int retry; | ||
505 | 563 | ||
506 | ret = mcs7830_init_dev(dev); | 564 | /* Initial startup: Gather MAC address setting from EEPROM */ |
565 | ret = -EINVAL; | ||
566 | for (retry = 0; retry < 5 && ret; retry++) | ||
567 | ret = mcs7830_hif_get_mac_address(dev, net->dev_addr); | ||
568 | if (ret) { | ||
569 | dev_warn(&dev->udev->dev, "Cannot read MAC address\n"); | ||
570 | goto out; | ||
571 | } | ||
572 | |||
573 | mcs7830_data_set_multicast(net); | ||
574 | |||
575 | ret = mcs7830_apply_base_config(dev); | ||
507 | if (ret) | 576 | if (ret) |
508 | goto out; | 577 | goto out; |
509 | 578 | ||
510 | net->ethtool_ops = &mcs7830_ethtool_ops; | 579 | net->ethtool_ops = &mcs7830_ethtool_ops; |
511 | net->netdev_ops = &mcs7830_netdev_ops; | 580 | net->netdev_ops = &mcs7830_netdev_ops; |
512 | mcs7830_set_multicast(net); | ||
513 | 581 | ||
514 | /* reserve space for the status byte on rx */ | 582 | /* reserve space for the status byte on rx */ |
515 | dev->rx_urb_size = ETH_FRAME_LEN + 1; | 583 | dev->rx_urb_size = ETH_FRAME_LEN + 1; |
@@ -526,7 +594,7 @@ out: | |||
526 | return ret; | 594 | return ret; |
527 | } | 595 | } |
528 | 596 | ||
529 | /* The chip always appends a status bytes that we need to strip */ | 597 | /* The chip always appends a status byte that we need to strip */ |
530 | static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 598 | static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
531 | { | 599 | { |
532 | u8 status; | 600 | u8 status; |
@@ -539,9 +607,23 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
539 | skb_trim(skb, skb->len - 1); | 607 | skb_trim(skb, skb->len - 1); |
540 | status = skb->data[skb->len]; | 608 | status = skb->data[skb->len]; |
541 | 609 | ||
542 | if (status != 0x20) | 610 | if (status != MCS7830_RX_FRAME_CORRECT) { |
543 | dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status); | 611 | dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status); |
544 | 612 | ||
613 | /* hmm, perhaps usbnet.c already sees a globally visible | ||
614 | frame error and increments rx_errors on its own already? */ | ||
615 | dev->net->stats.rx_errors++; | ||
616 | |||
617 | if (status & (MCS7830_RX_SHORT_FRAME | ||
618 | |MCS7830_RX_LENGTH_ERROR | ||
619 | |MCS7830_RX_LARGE_FRAME)) | ||
620 | dev->net->stats.rx_length_errors++; | ||
621 | if (status & MCS7830_RX_ALIGNMENT_ERROR) | ||
622 | dev->net->stats.rx_frame_errors++; | ||
623 | if (status & MCS7830_RX_CRC_ERROR) | ||
624 | dev->net->stats.rx_crc_errors++; | ||
625 | } | ||
626 | |||
545 | return skb->len > 0; | 627 | return skb->len > 0; |
546 | } | 628 | } |
547 | 629 | ||
@@ -580,6 +662,20 @@ static const struct usb_device_id products[] = { | |||
580 | }; | 662 | }; |
581 | MODULE_DEVICE_TABLE(usb, products); | 663 | MODULE_DEVICE_TABLE(usb, products); |
582 | 664 | ||
665 | static int mcs7830_reset_resume (struct usb_interface *intf) | ||
666 | { | ||
667 | /* YES, this function is successful enough that ethtool -d | ||
668 | does show same output pre-/post-suspend */ | ||
669 | |||
670 | struct usbnet *dev = usb_get_intfdata(intf); | ||
671 | |||
672 | mcs7830_apply_base_config(dev); | ||
673 | |||
674 | usbnet_resume(intf); | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
583 | static struct usb_driver mcs7830_driver = { | 679 | static struct usb_driver mcs7830_driver = { |
584 | .name = driver_name, | 680 | .name = driver_name, |
585 | .id_table = products, | 681 | .id_table = products, |
@@ -587,6 +683,7 @@ static struct usb_driver mcs7830_driver = { | |||
587 | .disconnect = usbnet_disconnect, | 683 | .disconnect = usbnet_disconnect, |
588 | .suspend = usbnet_suspend, | 684 | .suspend = usbnet_suspend, |
589 | .resume = usbnet_resume, | 685 | .resume = usbnet_resume, |
686 | .reset_resume = mcs7830_reset_resume, | ||
590 | }; | 687 | }; |
591 | 688 | ||
592 | static int __init mcs7830_init(void) | 689 | static int __init mcs7830_init(void) |
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index aeb1ab03a9ee..961a8ed38d8f 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mii.h> | 29 | #include <linux/mii.h> |
30 | #include <linux/usb.h> | 30 | #include <linux/usb.h> |
31 | #include <linux/usb/usbnet.h> | 31 | #include <linux/usb/usbnet.h> |
32 | #include <linux/slab.h> | ||
32 | 33 | ||
33 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
34 | 35 | ||
@@ -203,25 +204,23 @@ static void nc_dump_registers(struct usbnet *dev) | |||
203 | 204 | ||
204 | static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl) | 205 | static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl) |
205 | { | 206 | { |
206 | if (!netif_msg_link(dev)) | 207 | netif_dbg(dev, link, dev->net, |
207 | return; | 208 | "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s; this%s%s; other%s%s; r/o 0x%x\n", |
208 | devdbg(dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;" | 209 | dev->udev->bus->bus_name, dev->udev->devpath, |
209 | " this%s%s;" | 210 | usbctl, |
210 | " other%s%s; r/o 0x%x", | 211 | (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "", |
211 | dev->udev->bus->bus_name, dev->udev->devpath, | 212 | (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "", |
212 | usbctl, | 213 | (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "", |
213 | (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "", | 214 | (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "", |
214 | (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "", | 215 | (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "", |
215 | (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "", | 216 | |
216 | (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "", | 217 | (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "", |
217 | (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "", | 218 | (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "", |
218 | 219 | ||
219 | (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "", | 220 | (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "", |
220 | (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "", | 221 | (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "", |
221 | (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "", | 222 | |
222 | (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "", | 223 | usbctl & ~USBCTL_WRITABLE_MASK); |
223 | usbctl & ~USBCTL_WRITABLE_MASK | ||
224 | ); | ||
225 | } | 224 | } |
226 | 225 | ||
227 | /*-------------------------------------------------------------------------*/ | 226 | /*-------------------------------------------------------------------------*/ |
@@ -248,30 +247,26 @@ static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl) | |||
248 | 247 | ||
249 | static inline void nc_dump_status(struct usbnet *dev, u16 status) | 248 | static inline void nc_dump_status(struct usbnet *dev, u16 status) |
250 | { | 249 | { |
251 | if (!netif_msg_link(dev)) | 250 | netif_dbg(dev, link, dev->net, |
252 | return; | 251 | "net1080 %s-%s status 0x%x: this (%c) PKT=%d%s%s%s; other PKT=%d%s%s%s; unspec 0x%x\n", |
253 | devdbg(dev, "net1080 %s-%s status 0x%x:" | 252 | dev->udev->bus->bus_name, dev->udev->devpath, |
254 | " this (%c) PKT=%d%s%s%s;" | 253 | status, |
255 | " other PKT=%d%s%s%s; unspec 0x%x", | 254 | |
256 | dev->udev->bus->bus_name, dev->udev->devpath, | 255 | // XXX the packet counts don't seem right |
257 | status, | 256 | // (1 at reset, not 0); maybe UNSPEC too |
258 | 257 | ||
259 | // XXX the packet counts don't seem right | 258 | (status & STATUS_PORT_A) ? 'A' : 'B', |
260 | // (1 at reset, not 0); maybe UNSPEC too | 259 | STATUS_PACKETS_THIS(status), |
261 | 260 | (status & STATUS_CONN_THIS) ? " CON" : "", | |
262 | (status & STATUS_PORT_A) ? 'A' : 'B', | 261 | (status & STATUS_SUSPEND_THIS) ? " SUS" : "", |
263 | STATUS_PACKETS_THIS(status), | 262 | (status & STATUS_MAILBOX_THIS) ? " MBOX" : "", |
264 | (status & STATUS_CONN_THIS) ? " CON" : "", | 263 | |
265 | (status & STATUS_SUSPEND_THIS) ? " SUS" : "", | 264 | STATUS_PACKETS_OTHER(status), |
266 | (status & STATUS_MAILBOX_THIS) ? " MBOX" : "", | 265 | (status & STATUS_CONN_OTHER) ? " CON" : "", |
267 | 266 | (status & STATUS_SUSPEND_OTHER) ? " SUS" : "", | |
268 | STATUS_PACKETS_OTHER(status), | 267 | (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "", |
269 | (status & STATUS_CONN_OTHER) ? " CON" : "", | 268 | |
270 | (status & STATUS_SUSPEND_OTHER) ? " SUS" : "", | 269 | status & STATUS_UNSPEC_MASK); |
271 | (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "", | ||
272 | |||
273 | status & STATUS_UNSPEC_MASK | ||
274 | ); | ||
275 | } | 270 | } |
276 | 271 | ||
277 | /*-------------------------------------------------------------------------*/ | 272 | /*-------------------------------------------------------------------------*/ |
@@ -286,10 +281,9 @@ static inline void nc_dump_status(struct usbnet *dev, u16 status) | |||
286 | 281 | ||
287 | static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl) | 282 | static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl) |
288 | { | 283 | { |
289 | if (netif_msg_link(dev)) | 284 | netif_dbg(dev, link, dev->net, "net1080 %s-%s ttl 0x%x this = %d, other = %d\n", |
290 | devdbg(dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d", | 285 | dev->udev->bus->bus_name, dev->udev->devpath, |
291 | dev->udev->bus->bus_name, dev->udev->devpath, | 286 | ttl, TTL_THIS(ttl), TTL_OTHER(ttl)); |
292 | ttl, TTL_THIS(ttl), TTL_OTHER(ttl)); | ||
293 | } | 287 | } |
294 | 288 | ||
295 | /*-------------------------------------------------------------------------*/ | 289 | /*-------------------------------------------------------------------------*/ |
@@ -334,11 +328,9 @@ static int net1080_reset(struct usbnet *dev) | |||
334 | MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) ); | 328 | MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) ); |
335 | dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS); | 329 | dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS); |
336 | 330 | ||
337 | if (netif_msg_link(dev)) | 331 | netif_info(dev, link, dev->net, "port %c, peer %sconnected\n", |
338 | devinfo(dev, "port %c, peer %sconnected", | 332 | (status & STATUS_PORT_A) ? 'A' : 'B', |
339 | (status & STATUS_PORT_A) ? 'A' : 'B', | 333 | (status & STATUS_CONN_OTHER) ? "" : "dis"); |
340 | (status & STATUS_CONN_OTHER) ? "" : "dis" | ||
341 | ); | ||
342 | retval = 0; | 334 | retval = 0; |
343 | 335 | ||
344 | done: | 336 | done: |
@@ -415,8 +407,8 @@ static void nc_ensure_sync(struct usbnet *dev) | |||
415 | return; | 407 | return; |
416 | } | 408 | } |
417 | 409 | ||
418 | if (netif_msg_rx_err(dev)) | 410 | netif_dbg(dev, rx_err, dev->net, |
419 | devdbg(dev, "flush net1080; too many framing errors"); | 411 | "flush net1080; too many framing errors\n"); |
420 | dev->frame_errors = 0; | 412 | dev->frame_errors = 0; |
421 | } | 413 | } |
422 | } | 414 | } |
@@ -486,8 +478,8 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
486 | return 0; | 478 | return 0; |
487 | } | 479 | } |
488 | #if 0 | 480 | #if 0 |
489 | devdbg(dev, "frame <rx h %d p %d id %d", header->hdr_len, | 481 | netdev_dbg(dev->net, "frame <rx h %d p %d id %d\n", header->hdr_len, |
490 | header->packet_len, header->packet_id); | 482 | header->packet_len, header->packet_id); |
491 | #endif | 483 | #endif |
492 | dev->frame_errors = 0; | 484 | dev->frame_errors = 0; |
493 | return 1; | 485 | return 1; |
@@ -547,9 +539,9 @@ encapsulate: | |||
547 | trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer); | 539 | trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer); |
548 | put_unaligned(header->packet_id, &trailer->packet_id); | 540 | put_unaligned(header->packet_id, &trailer->packet_id); |
549 | #if 0 | 541 | #if 0 |
550 | devdbg(dev, "frame >tx h %d p %d id %d", | 542 | netdev_dbg(dev->net, "frame >tx h %d p %d id %d\n", |
551 | header->hdr_len, header->packet_len, | 543 | header->hdr_len, header->packet_len, |
552 | header->packet_id); | 544 | header->packet_id); |
553 | #endif | 545 | #endif |
554 | return skb; | 546 | return skb; |
555 | } | 547 | } |
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index ed4a508ef262..41838773b568 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
@@ -132,9 +132,10 @@ static void ctrl_callback(struct urb *urb) | |||
132 | case -ENOENT: | 132 | case -ENOENT: |
133 | break; | 133 | break; |
134 | default: | 134 | default: |
135 | if (netif_msg_drv(pegasus) && printk_ratelimit()) | 135 | if (net_ratelimit()) |
136 | dev_dbg(&pegasus->intf->dev, "%s, status %d\n", | 136 | netif_dbg(pegasus, drv, pegasus->net, |
137 | __func__, status); | 137 | "%s, status %d\n", __func__, status); |
138 | break; | ||
138 | } | 139 | } |
139 | pegasus->flags &= ~ETH_REGS_CHANGED; | 140 | pegasus->flags &= ~ETH_REGS_CHANGED; |
140 | wake_up(&pegasus->ctrl_wait); | 141 | wake_up(&pegasus->ctrl_wait); |
@@ -149,9 +150,8 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
149 | 150 | ||
150 | buffer = kmalloc(size, GFP_KERNEL); | 151 | buffer = kmalloc(size, GFP_KERNEL); |
151 | if (!buffer) { | 152 | if (!buffer) { |
152 | if (netif_msg_drv(pegasus)) | 153 | netif_warn(pegasus, drv, pegasus->net, |
153 | dev_warn(&pegasus->intf->dev, "out of memory in %s\n", | 154 | "out of memory in %s\n", __func__); |
154 | __func__); | ||
155 | return -ENOMEM; | 155 | return -ENOMEM; |
156 | } | 156 | } |
157 | add_wait_queue(&pegasus->ctrl_wait, &wait); | 157 | add_wait_queue(&pegasus->ctrl_wait, &wait); |
@@ -181,9 +181,9 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
181 | set_current_state(TASK_RUNNING); | 181 | set_current_state(TASK_RUNNING); |
182 | if (ret == -ENODEV) | 182 | if (ret == -ENODEV) |
183 | netif_device_detach(pegasus->net); | 183 | netif_device_detach(pegasus->net); |
184 | if (netif_msg_drv(pegasus) && printk_ratelimit()) | 184 | if (net_ratelimit()) |
185 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 185 | netif_err(pegasus, drv, pegasus->net, |
186 | __func__, ret); | 186 | "%s, status %d\n", __func__, ret); |
187 | goto out; | 187 | goto out; |
188 | } | 188 | } |
189 | 189 | ||
@@ -205,9 +205,8 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
205 | 205 | ||
206 | buffer = kmalloc(size, GFP_KERNEL); | 206 | buffer = kmalloc(size, GFP_KERNEL); |
207 | if (!buffer) { | 207 | if (!buffer) { |
208 | if (netif_msg_drv(pegasus)) | 208 | netif_warn(pegasus, drv, pegasus->net, |
209 | dev_warn(&pegasus->intf->dev, "out of memory in %s\n", | 209 | "out of memory in %s\n", __func__); |
210 | __func__); | ||
211 | return -ENOMEM; | 210 | return -ENOMEM; |
212 | } | 211 | } |
213 | memcpy(buffer, data, size); | 212 | memcpy(buffer, data, size); |
@@ -237,9 +236,8 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
237 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { | 236 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { |
238 | if (ret == -ENODEV) | 237 | if (ret == -ENODEV) |
239 | netif_device_detach(pegasus->net); | 238 | netif_device_detach(pegasus->net); |
240 | if (netif_msg_drv(pegasus)) | 239 | netif_err(pegasus, drv, pegasus->net, |
241 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 240 | "%s, status %d\n", __func__, ret); |
242 | __func__, ret); | ||
243 | goto out; | 241 | goto out; |
244 | } | 242 | } |
245 | 243 | ||
@@ -259,9 +257,8 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) | |||
259 | 257 | ||
260 | tmp = kmalloc(1, GFP_KERNEL); | 258 | tmp = kmalloc(1, GFP_KERNEL); |
261 | if (!tmp) { | 259 | if (!tmp) { |
262 | if (netif_msg_drv(pegasus)) | 260 | netif_warn(pegasus, drv, pegasus->net, |
263 | dev_warn(&pegasus->intf->dev, "out of memory in %s\n", | 261 | "out of memory in %s\n", __func__); |
264 | __func__); | ||
265 | return -ENOMEM; | 262 | return -ENOMEM; |
266 | } | 263 | } |
267 | memcpy(tmp, &data, 1); | 264 | memcpy(tmp, &data, 1); |
@@ -290,9 +287,9 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) | |||
290 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { | 287 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { |
291 | if (ret == -ENODEV) | 288 | if (ret == -ENODEV) |
292 | netif_device_detach(pegasus->net); | 289 | netif_device_detach(pegasus->net); |
293 | if (netif_msg_drv(pegasus) && printk_ratelimit()) | 290 | if (net_ratelimit()) |
294 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 291 | netif_err(pegasus, drv, pegasus->net, |
295 | __func__, ret); | 292 | "%s, status %d\n", __func__, ret); |
296 | goto out; | 293 | goto out; |
297 | } | 294 | } |
298 | 295 | ||
@@ -323,9 +320,8 @@ static int update_eth_regs_async(pegasus_t * pegasus) | |||
323 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { | 320 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { |
324 | if (ret == -ENODEV) | 321 | if (ret == -ENODEV) |
325 | netif_device_detach(pegasus->net); | 322 | netif_device_detach(pegasus->net); |
326 | if (netif_msg_drv(pegasus)) | 323 | netif_err(pegasus, drv, pegasus->net, |
327 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 324 | "%s, status %d\n", __func__, ret); |
328 | __func__, ret); | ||
329 | } | 325 | } |
330 | 326 | ||
331 | return ret; | 327 | return ret; |
@@ -349,14 +345,16 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) | |||
349 | if (data[0] & PHY_DONE) | 345 | if (data[0] & PHY_DONE) |
350 | break; | 346 | break; |
351 | } | 347 | } |
352 | if (i < REG_TIMEOUT) { | 348 | |
353 | ret = get_registers(pegasus, PhyData, 2, ®di); | 349 | if (i >= REG_TIMEOUT) |
354 | *regd = le16_to_cpu(regdi); | 350 | goto fail; |
355 | return ret; | 351 | |
356 | } | 352 | ret = get_registers(pegasus, PhyData, 2, ®di); |
353 | *regd = le16_to_cpu(regdi); | ||
354 | return ret; | ||
355 | |||
357 | fail: | 356 | fail: |
358 | if (netif_msg_drv(pegasus)) | 357 | netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
359 | dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); | ||
360 | 358 | ||
361 | return ret; | 359 | return ret; |
362 | } | 360 | } |
@@ -388,12 +386,14 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) | |||
388 | if (data[0] & PHY_DONE) | 386 | if (data[0] & PHY_DONE) |
389 | break; | 387 | break; |
390 | } | 388 | } |
391 | if (i < REG_TIMEOUT) | 389 | |
392 | return ret; | 390 | if (i >= REG_TIMEOUT) |
391 | goto fail; | ||
392 | |||
393 | return ret; | ||
393 | 394 | ||
394 | fail: | 395 | fail: |
395 | if (netif_msg_drv(pegasus)) | 396 | netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
396 | dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); | ||
397 | return -ETIMEDOUT; | 397 | return -ETIMEDOUT; |
398 | } | 398 | } |
399 | 399 | ||
@@ -422,15 +422,15 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) | |||
422 | if (ret == -ESHUTDOWN) | 422 | if (ret == -ESHUTDOWN) |
423 | goto fail; | 423 | goto fail; |
424 | } | 424 | } |
425 | if (i < REG_TIMEOUT) { | 425 | if (i >= REG_TIMEOUT) |
426 | ret = get_registers(pegasus, EpromData, 2, &retdatai); | 426 | goto fail; |
427 | *retdata = le16_to_cpu(retdatai); | 427 | |
428 | return ret; | 428 | ret = get_registers(pegasus, EpromData, 2, &retdatai); |
429 | } | 429 | *retdata = le16_to_cpu(retdatai); |
430 | return ret; | ||
430 | 431 | ||
431 | fail: | 432 | fail: |
432 | if (netif_msg_drv(pegasus)) | 433 | netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
433 | dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); | ||
434 | return -ETIMEDOUT; | 434 | return -ETIMEDOUT; |
435 | } | 435 | } |
436 | 436 | ||
@@ -475,11 +475,13 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) | |||
475 | break; | 475 | break; |
476 | } | 476 | } |
477 | disable_eprom_write(pegasus); | 477 | disable_eprom_write(pegasus); |
478 | if (i < REG_TIMEOUT) | 478 | if (i >= REG_TIMEOUT) |
479 | return ret; | 479 | goto fail; |
480 | |||
481 | return ret; | ||
482 | |||
480 | fail: | 483 | fail: |
481 | if (netif_msg_drv(pegasus)) | 484 | netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
482 | dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); | ||
483 | return -ETIMEDOUT; | 485 | return -ETIMEDOUT; |
484 | } | 486 | } |
485 | #endif /* PEGASUS_WRITE_EEPROM */ | 487 | #endif /* PEGASUS_WRITE_EEPROM */ |
@@ -642,25 +644,20 @@ static void read_bulk_callback(struct urb *urb) | |||
642 | case 0: | 644 | case 0: |
643 | break; | 645 | break; |
644 | case -ETIME: | 646 | case -ETIME: |
645 | if (netif_msg_rx_err(pegasus)) | 647 | netif_dbg(pegasus, rx_err, net, "reset MAC\n"); |
646 | pr_debug("%s: reset MAC\n", net->name); | ||
647 | pegasus->flags &= ~PEGASUS_RX_BUSY; | 648 | pegasus->flags &= ~PEGASUS_RX_BUSY; |
648 | break; | 649 | break; |
649 | case -EPIPE: /* stall, or disconnect from TT */ | 650 | case -EPIPE: /* stall, or disconnect from TT */ |
650 | /* FIXME schedule work to clear the halt */ | 651 | /* FIXME schedule work to clear the halt */ |
651 | if (netif_msg_rx_err(pegasus)) | 652 | netif_warn(pegasus, rx_err, net, "no rx stall recovery\n"); |
652 | printk(KERN_WARNING "%s: no rx stall recovery\n", | ||
653 | net->name); | ||
654 | return; | 653 | return; |
655 | case -ENOENT: | 654 | case -ENOENT: |
656 | case -ECONNRESET: | 655 | case -ECONNRESET: |
657 | case -ESHUTDOWN: | 656 | case -ESHUTDOWN: |
658 | if (netif_msg_ifdown(pegasus)) | 657 | netif_dbg(pegasus, ifdown, net, "rx unlink, %d\n", status); |
659 | pr_debug("%s: rx unlink, %d\n", net->name, status); | ||
660 | return; | 658 | return; |
661 | default: | 659 | default: |
662 | if (netif_msg_rx_err(pegasus)) | 660 | netif_dbg(pegasus, rx_err, net, "RX status %d\n", status); |
663 | pr_debug("%s: RX status %d\n", net->name, status); | ||
664 | goto goon; | 661 | goto goon; |
665 | } | 662 | } |
666 | 663 | ||
@@ -669,9 +666,8 @@ static void read_bulk_callback(struct urb *urb) | |||
669 | 666 | ||
670 | rx_status = buf[count - 2]; | 667 | rx_status = buf[count - 2]; |
671 | if (rx_status & 0x1e) { | 668 | if (rx_status & 0x1e) { |
672 | if (netif_msg_rx_err(pegasus)) | 669 | netif_dbg(pegasus, rx_err, net, |
673 | pr_debug("%s: RX packet error %x\n", | 670 | "RX packet error %x\n", rx_status); |
674 | net->name, rx_status); | ||
675 | pegasus->stats.rx_errors++; | 671 | pegasus->stats.rx_errors++; |
676 | if (rx_status & 0x06) // long or runt | 672 | if (rx_status & 0x06) // long or runt |
677 | pegasus->stats.rx_length_errors++; | 673 | pegasus->stats.rx_length_errors++; |
@@ -758,9 +754,7 @@ static void rx_fixup(unsigned long data) | |||
758 | pegasus->rx_skb = pull_skb(pegasus); | 754 | pegasus->rx_skb = pull_skb(pegasus); |
759 | } | 755 | } |
760 | if (pegasus->rx_skb == NULL) { | 756 | if (pegasus->rx_skb == NULL) { |
761 | if (netif_msg_rx_err(pegasus)) | 757 | netif_warn(pegasus, rx_err, pegasus->net, "low on memory\n"); |
762 | printk(KERN_WARNING "%s: low on memory\n", | ||
763 | pegasus->net->name); | ||
764 | tasklet_schedule(&pegasus->rx_tl); | 758 | tasklet_schedule(&pegasus->rx_tl); |
765 | goto done; | 759 | goto done; |
766 | } | 760 | } |
@@ -800,19 +794,15 @@ static void write_bulk_callback(struct urb *urb) | |||
800 | case -EPIPE: | 794 | case -EPIPE: |
801 | /* FIXME schedule_work() to clear the tx halt */ | 795 | /* FIXME schedule_work() to clear the tx halt */ |
802 | netif_stop_queue(net); | 796 | netif_stop_queue(net); |
803 | if (netif_msg_tx_err(pegasus)) | 797 | netif_warn(pegasus, tx_err, net, "no tx stall recovery\n"); |
804 | printk(KERN_WARNING "%s: no tx stall recovery\n", | ||
805 | net->name); | ||
806 | return; | 798 | return; |
807 | case -ENOENT: | 799 | case -ENOENT: |
808 | case -ECONNRESET: | 800 | case -ECONNRESET: |
809 | case -ESHUTDOWN: | 801 | case -ESHUTDOWN: |
810 | if (netif_msg_ifdown(pegasus)) | 802 | netif_dbg(pegasus, ifdown, net, "tx unlink, %d\n", status); |
811 | pr_debug("%s: tx unlink, %d\n", net->name, status); | ||
812 | return; | 803 | return; |
813 | default: | 804 | default: |
814 | if (netif_msg_tx_err(pegasus)) | 805 | netif_info(pegasus, tx_err, net, "TX status %d\n", status); |
815 | pr_info("%s: TX status %d\n", net->name, status); | ||
816 | /* FALL THROUGH */ | 806 | /* FALL THROUGH */ |
817 | case 0: | 807 | case 0: |
818 | break; | 808 | break; |
@@ -843,9 +833,7 @@ static void intr_callback(struct urb *urb) | |||
843 | /* some Pegasus-I products report LOTS of data | 833 | /* some Pegasus-I products report LOTS of data |
844 | * toggle errors... avoid log spamming | 834 | * toggle errors... avoid log spamming |
845 | */ | 835 | */ |
846 | if (netif_msg_timer(pegasus)) | 836 | netif_dbg(pegasus, timer, net, "intr status %d\n", status); |
847 | pr_debug("%s: intr status %d\n", net->name, | ||
848 | status); | ||
849 | } | 837 | } |
850 | 838 | ||
851 | if (urb->actual_length >= 6) { | 839 | if (urb->actual_length >= 6) { |
@@ -875,16 +863,15 @@ static void intr_callback(struct urb *urb) | |||
875 | res = usb_submit_urb(urb, GFP_ATOMIC); | 863 | res = usb_submit_urb(urb, GFP_ATOMIC); |
876 | if (res == -ENODEV) | 864 | if (res == -ENODEV) |
877 | netif_device_detach(pegasus->net); | 865 | netif_device_detach(pegasus->net); |
878 | if (res && netif_msg_timer(pegasus)) | 866 | if (res) |
879 | printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n", | 867 | netif_err(pegasus, timer, net, |
880 | net->name, res); | 868 | "can't resubmit interrupt urb, %d\n", res); |
881 | } | 869 | } |
882 | 870 | ||
883 | static void pegasus_tx_timeout(struct net_device *net) | 871 | static void pegasus_tx_timeout(struct net_device *net) |
884 | { | 872 | { |
885 | pegasus_t *pegasus = netdev_priv(net); | 873 | pegasus_t *pegasus = netdev_priv(net); |
886 | if (netif_msg_timer(pegasus)) | 874 | netif_warn(pegasus, timer, net, "tx timeout\n"); |
887 | printk(KERN_WARNING "%s: tx timeout\n", net->name); | ||
888 | usb_unlink_urb(pegasus->tx_urb); | 875 | usb_unlink_urb(pegasus->tx_urb); |
889 | pegasus->stats.tx_errors++; | 876 | pegasus->stats.tx_errors++; |
890 | } | 877 | } |
@@ -906,9 +893,7 @@ static netdev_tx_t pegasus_start_xmit(struct sk_buff *skb, | |||
906 | pegasus->tx_buff, count, | 893 | pegasus->tx_buff, count, |
907 | write_bulk_callback, pegasus); | 894 | write_bulk_callback, pegasus); |
908 | if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { | 895 | if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { |
909 | if (netif_msg_tx_err(pegasus)) | 896 | netif_warn(pegasus, tx_err, net, "fail tx, %d\n", res); |
910 | printk(KERN_WARNING "%s: fail tx, %d\n", | ||
911 | net->name, res); | ||
912 | switch (res) { | 897 | switch (res) { |
913 | case -EPIPE: /* stall, or disconnect from TT */ | 898 | case -EPIPE: /* stall, or disconnect from TT */ |
914 | /* cleanup should already have been scheduled */ | 899 | /* cleanup should already have been scheduled */ |
@@ -952,10 +937,9 @@ static inline void get_interrupt_interval(pegasus_t * pegasus) | |||
952 | interval = data >> 8; | 937 | interval = data >> 8; |
953 | if (pegasus->usb->speed != USB_SPEED_HIGH) { | 938 | if (pegasus->usb->speed != USB_SPEED_HIGH) { |
954 | if (interval < 0x80) { | 939 | if (interval < 0x80) { |
955 | if (netif_msg_timer(pegasus)) | 940 | netif_info(pegasus, timer, pegasus->net, |
956 | dev_info(&pegasus->intf->dev, "intr interval " | 941 | "intr interval changed from %ums to %ums\n", |
957 | "changed from %ums to %ums\n", | 942 | interval, 0x80); |
958 | interval, 0x80); | ||
959 | interval = 0x80; | 943 | interval = 0x80; |
960 | data = (data & 0x00FF) | ((u16)interval << 8); | 944 | data = (data & 0x00FF) | ((u16)interval << 8); |
961 | #ifdef PEGASUS_WRITE_EEPROM | 945 | #ifdef PEGASUS_WRITE_EEPROM |
@@ -1046,8 +1030,7 @@ static int pegasus_open(struct net_device *net) | |||
1046 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { | 1030 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { |
1047 | if (res == -ENODEV) | 1031 | if (res == -ENODEV) |
1048 | netif_device_detach(pegasus->net); | 1032 | netif_device_detach(pegasus->net); |
1049 | if (netif_msg_ifup(pegasus)) | 1033 | netif_dbg(pegasus, ifup, net, "failed rx_urb, %d\n", res); |
1050 | pr_debug("%s: failed rx_urb, %d", net->name, res); | ||
1051 | goto exit; | 1034 | goto exit; |
1052 | } | 1035 | } |
1053 | 1036 | ||
@@ -1058,15 +1041,13 @@ static int pegasus_open(struct net_device *net) | |||
1058 | if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { | 1041 | if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { |
1059 | if (res == -ENODEV) | 1042 | if (res == -ENODEV) |
1060 | netif_device_detach(pegasus->net); | 1043 | netif_device_detach(pegasus->net); |
1061 | if (netif_msg_ifup(pegasus)) | 1044 | netif_dbg(pegasus, ifup, net, "failed intr_urb, %d\n", res); |
1062 | pr_debug("%s: failed intr_urb, %d\n", net->name, res); | ||
1063 | usb_kill_urb(pegasus->rx_urb); | 1045 | usb_kill_urb(pegasus->rx_urb); |
1064 | goto exit; | 1046 | goto exit; |
1065 | } | 1047 | } |
1066 | if ((res = enable_net_traffic(net, pegasus->usb))) { | 1048 | if ((res = enable_net_traffic(net, pegasus->usb))) { |
1067 | if (netif_msg_ifup(pegasus)) | 1049 | netif_dbg(pegasus, ifup, net, |
1068 | pr_debug("%s: can't enable_net_traffic() - %d\n", | 1050 | "can't enable_net_traffic() - %d\n", res); |
1069 | net->name, res); | ||
1070 | res = -EIO; | 1051 | res = -EIO; |
1071 | usb_kill_urb(pegasus->rx_urb); | 1052 | usb_kill_urb(pegasus->rx_urb); |
1072 | usb_kill_urb(pegasus->intr_urb); | 1053 | usb_kill_urb(pegasus->intr_urb); |
@@ -1075,8 +1056,7 @@ static int pegasus_open(struct net_device *net) | |||
1075 | } | 1056 | } |
1076 | set_carrier(net); | 1057 | set_carrier(net); |
1077 | netif_start_queue(net); | 1058 | netif_start_queue(net); |
1078 | if (netif_msg_ifup(pegasus)) | 1059 | netif_dbg(pegasus, ifup, net, "open\n"); |
1079 | pr_debug("%s: open\n", net->name); | ||
1080 | res = 0; | 1060 | res = 0; |
1081 | exit: | 1061 | exit: |
1082 | return res; | 1062 | return res; |
@@ -1230,13 +1210,11 @@ static void pegasus_set_multicast(struct net_device *net) | |||
1230 | 1210 | ||
1231 | if (net->flags & IFF_PROMISC) { | 1211 | if (net->flags & IFF_PROMISC) { |
1232 | pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS; | 1212 | pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS; |
1233 | if (netif_msg_link(pegasus)) | 1213 | netif_info(pegasus, link, net, "Promiscuous mode enabled\n"); |
1234 | pr_info("%s: Promiscuous mode enabled.\n", net->name); | 1214 | } else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) { |
1235 | } else if (net->mc_count || (net->flags & IFF_ALLMULTI)) { | ||
1236 | pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST; | 1215 | pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST; |
1237 | pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; | 1216 | pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; |
1238 | if (netif_msg_link(pegasus)) | 1217 | netif_dbg(pegasus, link, net, "set allmulti\n"); |
1239 | pr_debug("%s: set allmulti\n", net->name); | ||
1240 | } else { | 1218 | } else { |
1241 | pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST; | 1219 | pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST; |
1242 | pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; | 1220 | pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; |
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h index 5d02f0200737..b90d8766ab74 100644 --- a/drivers/net/usb/pegasus.h +++ b/drivers/net/usb/pegasus.h | |||
@@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c, | |||
177 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, | 177 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, |
178 | DEFAULT_GPIO_RESET ) | 178 | DEFAULT_GPIO_RESET ) |
179 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, | 179 | PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, |
180 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 180 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
181 | PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, | 181 | PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, |
182 | DEFAULT_GPIO_RESET ) | 182 | DEFAULT_GPIO_RESET ) |
183 | PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, | 183 | PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, |
@@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, | |||
208 | */ | 208 | */ |
209 | PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, | 209 | PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, |
210 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 210 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
211 | PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122, | ||
212 | DEFAULT_GPIO_RESET | PEGASUS_II ) | ||
211 | PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, | 213 | PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, |
212 | DEFAULT_GPIO_RESET ) | 214 | DEFAULT_GPIO_RESET ) |
213 | PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, | 215 | PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, |
@@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002, | |||
249 | PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, | 251 | PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, |
250 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 252 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
251 | PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c, | 253 | PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c, |
252 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 254 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
253 | PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, | 255 | PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, |
254 | DEFAULT_GPIO_RESET ) | 256 | DEFAULT_GPIO_RESET ) |
255 | PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, | 257 | PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, |
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index f56dec6119c3..dd8a4adf48ca 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/etherdevice.h> | 22 | #include <linux/etherdevice.h> |
23 | #include <linux/ethtool.h> | 23 | #include <linux/ethtool.h> |
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/slab.h> | ||
25 | #include <linux/mii.h> | 26 | #include <linux/mii.h> |
26 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
27 | #include <linux/usb/cdc.h> | 28 | #include <linux/usb/cdc.h> |
@@ -57,8 +58,8 @@ | |||
57 | */ | 58 | */ |
58 | void rndis_status(struct usbnet *dev, struct urb *urb) | 59 | void rndis_status(struct usbnet *dev, struct urb *urb) |
59 | { | 60 | { |
60 | devdbg(dev, "rndis status urb, len %d stat %d", | 61 | netdev_dbg(dev->net, "rndis status urb, len %d stat %d\n", |
61 | urb->actual_length, urb->status); | 62 | urb->actual_length, urb->status); |
62 | // FIXME for keepalives, respond immediately (asynchronously) | 63 | // FIXME for keepalives, respond immediately (asynchronously) |
63 | // if not an RNDIS status, do like cdc_status(dev,urb) does | 64 | // if not an RNDIS status, do like cdc_status(dev,urb) does |
64 | } | 65 | } |
@@ -114,8 +115,8 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen) | |||
114 | */ | 115 | */ |
115 | 116 | ||
116 | /* Issue the request; xid is unique, don't bother byteswapping it */ | 117 | /* Issue the request; xid is unique, don't bother byteswapping it */ |
117 | if (likely(buf->msg_type != RNDIS_MSG_HALT | 118 | if (likely(buf->msg_type != RNDIS_MSG_HALT && |
118 | && buf->msg_type != RNDIS_MSG_RESET)) { | 119 | buf->msg_type != RNDIS_MSG_RESET)) { |
119 | xid = dev->xid++; | 120 | xid = dev->xid++; |
120 | if (!xid) | 121 | if (!xid) |
121 | xid = dev->xid++; | 122 | xid = dev->xid++; |
@@ -335,8 +336,8 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | |||
335 | 336 | ||
336 | dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); | 337 | dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); |
337 | if (dev->maxpacket == 0) { | 338 | if (dev->maxpacket == 0) { |
338 | if (netif_msg_probe(dev)) | 339 | netif_dbg(dev, probe, dev->net, |
339 | dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n"); | 340 | "dev->maxpacket can't be 0\n"); |
340 | retval = -EINVAL; | 341 | retval = -EINVAL; |
341 | goto fail_and_release; | 342 | goto fail_and_release; |
342 | } | 343 | } |
@@ -394,17 +395,15 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) | |||
394 | } | 395 | } |
395 | if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && | 396 | if ((flags & FLAG_RNDIS_PHYM_WIRELESS) && |
396 | *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { | 397 | *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { |
397 | if (netif_msg_probe(dev)) | 398 | netif_dbg(dev, probe, dev->net, |
398 | dev_dbg(&intf->dev, "driver requires wireless " | 399 | "driver requires wireless physical medium, but device is not\n"); |
399 | "physical medium, but device is not.\n"); | ||
400 | retval = -ENODEV; | 400 | retval = -ENODEV; |
401 | goto halt_fail_and_release; | 401 | goto halt_fail_and_release; |
402 | } | 402 | } |
403 | if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && | 403 | if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) && |
404 | *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { | 404 | *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) { |
405 | if (netif_msg_probe(dev)) | 405 | netif_dbg(dev, probe, dev->net, |
406 | dev_dbg(&intf->dev, "driver requires non-wireless " | 406 | "driver requires non-wireless physical medium, but device is wireless.\n"); |
407 | "physical medium, but device is wireless.\n"); | ||
408 | retval = -ENODEV; | 407 | retval = -ENODEV; |
409 | goto halt_fail_and_release; | 408 | goto halt_fail_and_release; |
410 | } | 409 | } |
@@ -493,13 +492,13 @@ int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
493 | data_len = le32_to_cpu(hdr->data_len); | 492 | data_len = le32_to_cpu(hdr->data_len); |
494 | 493 | ||
495 | /* don't choke if we see oob, per-packet data, etc */ | 494 | /* don't choke if we see oob, per-packet data, etc */ |
496 | if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET | 495 | if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET || |
497 | || skb->len < msg_len | 496 | skb->len < msg_len || |
498 | || (data_offset + data_len + 8) > msg_len)) { | 497 | (data_offset + data_len + 8) > msg_len)) { |
499 | dev->net->stats.rx_frame_errors++; | 498 | dev->net->stats.rx_frame_errors++; |
500 | devdbg(dev, "bad rndis message %d/%d/%d/%d, len %d", | 499 | netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n", |
501 | le32_to_cpu(hdr->msg_type), | 500 | le32_to_cpu(hdr->msg_type), |
502 | msg_len, data_offset, data_len, skb->len); | 501 | msg_len, data_offset, data_len, skb->len); |
503 | return 0; | 502 | return 0; |
504 | } | 503 | } |
505 | skb_pull(skb, 8 + data_offset); | 504 | skb_pull(skb, 8 + data_offset); |
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index b091e20ca167..e85c89c6706d 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c | |||
@@ -270,7 +270,7 @@ static int read_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 * reg) | |||
270 | get_registers(dev, PHYCNT, 1, data); | 270 | get_registers(dev, PHYCNT, 1, data); |
271 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); | 271 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); |
272 | 272 | ||
273 | if (i < MII_TIMEOUT) { | 273 | if (i <= MII_TIMEOUT) { |
274 | get_registers(dev, PHYDAT, 2, data); | 274 | get_registers(dev, PHYDAT, 2, data); |
275 | *reg = data[0] | (data[1] << 8); | 275 | *reg = data[0] | (data[1] << 8); |
276 | return 0; | 276 | return 0; |
@@ -295,7 +295,7 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) | |||
295 | get_registers(dev, PHYCNT, 1, data); | 295 | get_registers(dev, PHYCNT, 1, data); |
296 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); | 296 | } while ((data[0] & PHY_GO) && (i++ < MII_TIMEOUT)); |
297 | 297 | ||
298 | if (i < MII_TIMEOUT) | 298 | if (i <= MII_TIMEOUT) |
299 | return 0; | 299 | return 0; |
300 | else | 300 | else |
301 | return 1; | 301 | return 1; |
@@ -313,20 +313,17 @@ static int rtl8150_set_mac_address(struct net_device *netdev, void *p) | |||
313 | { | 313 | { |
314 | struct sockaddr *addr = p; | 314 | struct sockaddr *addr = p; |
315 | rtl8150_t *dev = netdev_priv(netdev); | 315 | rtl8150_t *dev = netdev_priv(netdev); |
316 | int i; | ||
317 | 316 | ||
318 | if (netif_running(netdev)) | 317 | if (netif_running(netdev)) |
319 | return -EBUSY; | 318 | return -EBUSY; |
320 | 319 | ||
321 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 320 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
322 | dbg("%s: Setting MAC address to ", netdev->name); | 321 | dbg("%s: Setting MAC address to %pM\n", netdev->name, netdev->dev_addr); |
323 | for (i = 0; i < 5; i++) | ||
324 | dbg("%02X:", netdev->dev_addr[i]); | ||
325 | dbg("%02X\n", netdev->dev_addr[i]); | ||
326 | /* Set the IDR registers. */ | 322 | /* Set the IDR registers. */ |
327 | set_registers(dev, IDR, sizeof(netdev->dev_addr), netdev->dev_addr); | 323 | set_registers(dev, IDR, netdev->addr_len, netdev->dev_addr); |
328 | #ifdef EEPROM_WRITE | 324 | #ifdef EEPROM_WRITE |
329 | { | 325 | { |
326 | int i; | ||
330 | u8 cr; | 327 | u8 cr; |
331 | /* Get the CR contents. */ | 328 | /* Get the CR contents. */ |
332 | get_registers(dev, CR, 1, &cr); | 329 | get_registers(dev, CR, 1, &cr); |
@@ -714,7 +711,7 @@ static void rtl8150_set_multicast(struct net_device *netdev) | |||
714 | if (netdev->flags & IFF_PROMISC) { | 711 | if (netdev->flags & IFF_PROMISC) { |
715 | dev->rx_creg |= cpu_to_le16(0x0001); | 712 | dev->rx_creg |= cpu_to_le16(0x0001); |
716 | dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); | 713 | dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name); |
717 | } else if (netdev->mc_count || | 714 | } else if (!netdev_mc_empty(netdev) || |
718 | (netdev->flags & IFF_ALLMULTI)) { | 715 | (netdev->flags & IFF_ALLMULTI)) { |
719 | dev->rx_creg &= cpu_to_le16(0xfffe); | 716 | dev->rx_creg &= cpu_to_le16(0xfffe); |
720 | dev->rx_creg |= cpu_to_le16(0x0002); | 717 | dev->rx_creg |= cpu_to_le16(0x0002); |
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c new file mode 100644 index 000000000000..f1942d69a0d5 --- /dev/null +++ b/drivers/net/usb/sierra_net.c | |||
@@ -0,0 +1,1004 @@ | |||
1 | /* | ||
2 | * USB-to-WWAN Driver for Sierra Wireless modems | ||
3 | * | ||
4 | * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer | ||
5 | * <linux@sierrawireless.com> | ||
6 | * | ||
7 | * Portions of this based on the cdc_ether driver by David Brownell (2003-2005) | ||
8 | * and Ole Andre Vadla Ravnas (ActiveSync) (2006). | ||
9 | * | ||
10 | * IMPORTANT DISCLAIMER: This driver is not commercially supported by | ||
11 | * Sierra Wireless. Use at your own risk. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
26 | */ | ||
27 | |||
28 | #define DRIVER_VERSION "v.2.0" | ||
29 | #define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer" | ||
30 | #define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems" | ||
31 | static const char driver_name[] = "sierra_net"; | ||
32 | |||
33 | /* if defined debug messages enabled */ | ||
34 | /*#define DEBUG*/ | ||
35 | |||
36 | #include <linux/module.h> | ||
37 | #include <linux/etherdevice.h> | ||
38 | #include <linux/ethtool.h> | ||
39 | #include <linux/mii.h> | ||
40 | #include <linux/sched.h> | ||
41 | #include <linux/timer.h> | ||
42 | #include <linux/usb.h> | ||
43 | #include <linux/usb/cdc.h> | ||
44 | #include <net/ip.h> | ||
45 | #include <net/udp.h> | ||
46 | #include <asm/unaligned.h> | ||
47 | #include <linux/usb/usbnet.h> | ||
48 | |||
49 | #define SWI_USB_REQUEST_GET_FW_ATTR 0x06 | ||
50 | #define SWI_GET_FW_ATTR_MASK 0x08 | ||
51 | |||
52 | /* atomic counter partially included in MAC address to make sure 2 devices | ||
53 | * do not end up with the same MAC - concept breaks in case of > 255 ifaces | ||
54 | */ | ||
55 | static atomic_t iface_counter = ATOMIC_INIT(0); | ||
56 | |||
57 | /* | ||
58 | * SYNC Timer Delay definition used to set the expiry time | ||
59 | */ | ||
60 | #define SIERRA_NET_SYNCDELAY (2*HZ) | ||
61 | |||
62 | /* Max. MTU supported. The modem buffers are limited to 1500 */ | ||
63 | #define SIERRA_NET_MAX_SUPPORTED_MTU 1500 | ||
64 | |||
65 | /* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control | ||
66 | * message reception ... and thus the max. received packet. | ||
67 | * (May be the cause for parse_hip returning -EINVAL) | ||
68 | */ | ||
69 | #define SIERRA_NET_USBCTL_BUF_LEN 1024 | ||
70 | |||
71 | /* list of interface numbers - used for constructing interface lists */ | ||
72 | struct sierra_net_iface_info { | ||
73 | const u32 infolen; /* number of interface numbers on list */ | ||
74 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | ||
75 | }; | ||
76 | |||
77 | struct sierra_net_info_data { | ||
78 | u16 rx_urb_size; | ||
79 | struct sierra_net_iface_info whitelist; | ||
80 | }; | ||
81 | |||
82 | /* Private data structure */ | ||
83 | struct sierra_net_data { | ||
84 | |||
85 | u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */ | ||
86 | |||
87 | u16 link_up; /* air link up or down */ | ||
88 | u8 tx_hdr_template[4]; /* part of HIP hdr for tx'd packets */ | ||
89 | |||
90 | u8 sync_msg[4]; /* SYNC message */ | ||
91 | u8 shdwn_msg[4]; /* Shutdown message */ | ||
92 | |||
93 | /* Backpointer to the container */ | ||
94 | struct usbnet *usbnet; | ||
95 | |||
96 | u8 ifnum; /* interface number */ | ||
97 | |||
98 | /* Bit masks, must be a power of 2 */ | ||
99 | #define SIERRA_NET_EVENT_RESP_AVAIL 0x01 | ||
100 | #define SIERRA_NET_TIMER_EXPIRY 0x02 | ||
101 | unsigned long kevent_flags; | ||
102 | struct work_struct sierra_net_kevent; | ||
103 | struct timer_list sync_timer; /* For retrying SYNC sequence */ | ||
104 | }; | ||
105 | |||
106 | struct param { | ||
107 | int is_present; | ||
108 | union { | ||
109 | void *ptr; | ||
110 | u32 dword; | ||
111 | u16 word; | ||
112 | u8 byte; | ||
113 | }; | ||
114 | }; | ||
115 | |||
116 | /* HIP message type */ | ||
117 | #define SIERRA_NET_HIP_EXTENDEDID 0x7F | ||
118 | #define SIERRA_NET_HIP_HSYNC_ID 0x60 /* Modem -> host */ | ||
119 | #define SIERRA_NET_HIP_RESTART_ID 0x62 /* Modem -> host */ | ||
120 | #define SIERRA_NET_HIP_MSYNC_ID 0x20 /* Host -> modem */ | ||
121 | #define SIERRA_NET_HIP_SHUTD_ID 0x26 /* Host -> modem */ | ||
122 | |||
123 | #define SIERRA_NET_HIP_EXT_IP_IN_ID 0x0202 | ||
124 | #define SIERRA_NET_HIP_EXT_IP_OUT_ID 0x0002 | ||
125 | |||
126 | /* 3G UMTS Link Sense Indication definitions */ | ||
127 | #define SIERRA_NET_HIP_LSI_UMTSID 0x78 | ||
128 | |||
129 | /* Reverse Channel Grant Indication HIP message */ | ||
130 | #define SIERRA_NET_HIP_RCGI 0x64 | ||
131 | |||
132 | /* LSI Protocol types */ | ||
133 | #define SIERRA_NET_PROTOCOL_UMTS 0x01 | ||
134 | /* LSI Coverage */ | ||
135 | #define SIERRA_NET_COVERAGE_NONE 0x00 | ||
136 | #define SIERRA_NET_COVERAGE_NOPACKET 0x01 | ||
137 | |||
138 | /* LSI Session */ | ||
139 | #define SIERRA_NET_SESSION_IDLE 0x00 | ||
140 | /* LSI Link types */ | ||
141 | #define SIERRA_NET_AS_LINK_TYPE_IPv4 0x00 | ||
142 | |||
143 | struct lsi_umts { | ||
144 | u8 protocol; | ||
145 | u8 unused1; | ||
146 | __be16 length; | ||
147 | /* eventually use a union for the rest - assume umts for now */ | ||
148 | u8 coverage; | ||
149 | u8 unused2[41]; | ||
150 | u8 session_state; | ||
151 | u8 unused3[33]; | ||
152 | u8 link_type; | ||
153 | u8 pdp_addr_len; /* NW-supplied PDP address len */ | ||
154 | u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */ | ||
155 | u8 unused4[23]; | ||
156 | u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */ | ||
157 | u8 dns1_addr[16]; /* NW-supplied 1st DNS address */ | ||
158 | u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */ | ||
159 | u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/ | ||
160 | u8 wins1_addr_len; /* NW-supplied 1st Wins address len */ | ||
161 | u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/ | ||
162 | u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */ | ||
163 | u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */ | ||
164 | u8 unused5[4]; | ||
165 | u8 gw_addr_len; /* NW-supplied GW address len */ | ||
166 | u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */ | ||
167 | u8 reserved[8]; | ||
168 | } __attribute__ ((packed)); | ||
169 | |||
170 | #define SIERRA_NET_LSI_COMMON_LEN 4 | ||
171 | #define SIERRA_NET_LSI_UMTS_LEN (sizeof(struct lsi_umts)) | ||
172 | #define SIERRA_NET_LSI_UMTS_STATUS_LEN \ | ||
173 | (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN) | ||
174 | |||
175 | /* Forward definitions */ | ||
176 | static void sierra_sync_timer(unsigned long syncdata); | ||
177 | static int sierra_net_change_mtu(struct net_device *net, int new_mtu); | ||
178 | |||
179 | /* Our own net device operations structure */ | ||
180 | static const struct net_device_ops sierra_net_device_ops = { | ||
181 | .ndo_open = usbnet_open, | ||
182 | .ndo_stop = usbnet_stop, | ||
183 | .ndo_start_xmit = usbnet_start_xmit, | ||
184 | .ndo_tx_timeout = usbnet_tx_timeout, | ||
185 | .ndo_change_mtu = sierra_net_change_mtu, | ||
186 | .ndo_set_mac_address = eth_mac_addr, | ||
187 | .ndo_validate_addr = eth_validate_addr, | ||
188 | }; | ||
189 | |||
190 | /* get private data associated with passed in usbnet device */ | ||
191 | static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev) | ||
192 | { | ||
193 | return (struct sierra_net_data *)dev->data[0]; | ||
194 | } | ||
195 | |||
196 | /* set private data associated with passed in usbnet device */ | ||
197 | static inline void sierra_net_set_private(struct usbnet *dev, | ||
198 | struct sierra_net_data *priv) | ||
199 | { | ||
200 | dev->data[0] = (unsigned long)priv; | ||
201 | } | ||
202 | |||
203 | /* is packet IPv4 */ | ||
204 | static inline int is_ip(struct sk_buff *skb) | ||
205 | { | ||
206 | return (skb->protocol == cpu_to_be16(ETH_P_IP)); | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * check passed in packet and make sure that: | ||
211 | * - it is linear (no scatter/gather) | ||
212 | * - it is ethernet (mac_header properly set) | ||
213 | */ | ||
214 | static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev) | ||
215 | { | ||
216 | skb_reset_mac_header(skb); /* ethernet header */ | ||
217 | |||
218 | if (skb_is_nonlinear(skb)) { | ||
219 | netdev_err(dev->net, "Non linear buffer-dropping\n"); | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | if (!pskb_may_pull(skb, ETH_HLEN)) | ||
224 | return 0; | ||
225 | skb->protocol = eth_hdr(skb)->h_proto; | ||
226 | |||
227 | return 1; | ||
228 | } | ||
229 | |||
230 | static const u8 *save16bit(struct param *p, const u8 *datap) | ||
231 | { | ||
232 | p->is_present = 1; | ||
233 | p->word = get_unaligned_be16(datap); | ||
234 | return datap + sizeof(p->word); | ||
235 | } | ||
236 | |||
237 | static const u8 *save8bit(struct param *p, const u8 *datap) | ||
238 | { | ||
239 | p->is_present = 1; | ||
240 | p->byte = *datap; | ||
241 | return datap + sizeof(p->byte); | ||
242 | } | ||
243 | |||
244 | /*----------------------------------------------------------------------------* | ||
245 | * BEGIN HIP * | ||
246 | *----------------------------------------------------------------------------*/ | ||
247 | /* HIP header */ | ||
248 | #define SIERRA_NET_HIP_HDR_LEN 4 | ||
249 | /* Extended HIP header */ | ||
250 | #define SIERRA_NET_HIP_EXT_HDR_LEN 6 | ||
251 | |||
252 | struct hip_hdr { | ||
253 | int hdrlen; | ||
254 | struct param payload_len; | ||
255 | struct param msgid; | ||
256 | struct param msgspecific; | ||
257 | struct param extmsgid; | ||
258 | }; | ||
259 | |||
260 | static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh) | ||
261 | { | ||
262 | const u8 *curp = buf; | ||
263 | int padded; | ||
264 | |||
265 | if (buflen < SIERRA_NET_HIP_HDR_LEN) | ||
266 | return -EPROTO; | ||
267 | |||
268 | curp = save16bit(&hh->payload_len, curp); | ||
269 | curp = save8bit(&hh->msgid, curp); | ||
270 | curp = save8bit(&hh->msgspecific, curp); | ||
271 | |||
272 | padded = hh->msgid.byte & 0x80; | ||
273 | hh->msgid.byte &= 0x7F; /* 7 bits */ | ||
274 | |||
275 | hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID); | ||
276 | if (hh->extmsgid.is_present) { | ||
277 | if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN) | ||
278 | return -EPROTO; | ||
279 | |||
280 | hh->payload_len.word &= 0x3FFF; /* 14 bits */ | ||
281 | |||
282 | curp = save16bit(&hh->extmsgid, curp); | ||
283 | hh->extmsgid.word &= 0x03FF; /* 10 bits */ | ||
284 | |||
285 | hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN; | ||
286 | } else { | ||
287 | hh->payload_len.word &= 0x07FF; /* 11 bits */ | ||
288 | hh->hdrlen = SIERRA_NET_HIP_HDR_LEN; | ||
289 | } | ||
290 | |||
291 | if (padded) { | ||
292 | hh->hdrlen++; | ||
293 | hh->payload_len.word--; | ||
294 | } | ||
295 | |||
296 | /* if real packet shorter than the claimed length */ | ||
297 | if (buflen < (hh->hdrlen + hh->payload_len.word)) | ||
298 | return -EINVAL; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static void build_hip(u8 *buf, const u16 payloadlen, | ||
304 | struct sierra_net_data *priv) | ||
305 | { | ||
306 | /* the following doesn't have the full functionality. We | ||
307 | * currently build only one kind of header, so it is faster this way | ||
308 | */ | ||
309 | put_unaligned_be16(payloadlen, buf); | ||
310 | memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template)); | ||
311 | } | ||
312 | /*----------------------------------------------------------------------------* | ||
313 | * END HIP * | ||
314 | *----------------------------------------------------------------------------*/ | ||
315 | |||
316 | static int sierra_net_send_cmd(struct usbnet *dev, | ||
317 | u8 *cmd, int cmdlen, const char * cmd_name) | ||
318 | { | ||
319 | struct sierra_net_data *priv = sierra_net_get_private(dev); | ||
320 | int status; | ||
321 | |||
322 | status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | ||
323 | USB_CDC_SEND_ENCAPSULATED_COMMAND, | ||
324 | USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0, | ||
325 | priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT); | ||
326 | |||
327 | if (status != cmdlen && status != -ENODEV) | ||
328 | netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status); | ||
329 | |||
330 | return status; | ||
331 | } | ||
332 | |||
333 | static int sierra_net_send_sync(struct usbnet *dev) | ||
334 | { | ||
335 | int status; | ||
336 | struct sierra_net_data *priv = sierra_net_get_private(dev); | ||
337 | |||
338 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
339 | |||
340 | status = sierra_net_send_cmd(dev, priv->sync_msg, | ||
341 | sizeof(priv->sync_msg), "SYNC"); | ||
342 | |||
343 | return status; | ||
344 | } | ||
345 | |||
346 | static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix) | ||
347 | { | ||
348 | dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix); | ||
349 | priv->tx_hdr_template[0] = 0x3F; | ||
350 | priv->tx_hdr_template[1] = ctx_ix; | ||
351 | *((u16 *)&priv->tx_hdr_template[2]) = | ||
352 | cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID); | ||
353 | } | ||
354 | |||
355 | static inline int sierra_net_is_valid_addrlen(u8 len) | ||
356 | { | ||
357 | return (len == sizeof(struct in_addr)); | ||
358 | } | ||
359 | |||
360 | static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen) | ||
361 | { | ||
362 | struct lsi_umts *lsi = (struct lsi_umts *)data; | ||
363 | |||
364 | if (datalen < sizeof(struct lsi_umts)) { | ||
365 | netdev_err(dev->net, "%s: Data length %d, exp %Zu\n", | ||
366 | __func__, datalen, | ||
367 | sizeof(struct lsi_umts)); | ||
368 | return -1; | ||
369 | } | ||
370 | |||
371 | if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) { | ||
372 | netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n", | ||
373 | __func__, be16_to_cpu(lsi->length), | ||
374 | (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN); | ||
375 | return -1; | ||
376 | } | ||
377 | |||
378 | /* Validate the protocol - only support UMTS for now */ | ||
379 | if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) { | ||
380 | netdev_err(dev->net, "Protocol unsupported, 0x%02x\n", | ||
381 | lsi->protocol); | ||
382 | return -1; | ||
383 | } | ||
384 | |||
385 | /* Validate the link type */ | ||
386 | if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) { | ||
387 | netdev_err(dev->net, "Link type unsupported: 0x%02x\n", | ||
388 | lsi->link_type); | ||
389 | return -1; | ||
390 | } | ||
391 | |||
392 | /* Validate the coverage */ | ||
393 | if (lsi->coverage == SIERRA_NET_COVERAGE_NONE | ||
394 | || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) { | ||
395 | netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | /* Validate the session state */ | ||
400 | if (lsi->session_state == SIERRA_NET_SESSION_IDLE) { | ||
401 | netdev_err(dev->net, "Session idle, 0x%02x\n", | ||
402 | lsi->session_state); | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | /* Set link_sense true */ | ||
407 | return 1; | ||
408 | } | ||
409 | |||
410 | static void sierra_net_handle_lsi(struct usbnet *dev, char *data, | ||
411 | struct hip_hdr *hh) | ||
412 | { | ||
413 | struct sierra_net_data *priv = sierra_net_get_private(dev); | ||
414 | int link_up; | ||
415 | |||
416 | link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen, | ||
417 | hh->payload_len.word); | ||
418 | if (link_up < 0) { | ||
419 | netdev_err(dev->net, "Invalid LSI\n"); | ||
420 | return; | ||
421 | } | ||
422 | if (link_up) { | ||
423 | sierra_net_set_ctx_index(priv, hh->msgspecific.byte); | ||
424 | priv->link_up = 1; | ||
425 | netif_carrier_on(dev->net); | ||
426 | } else { | ||
427 | priv->link_up = 0; | ||
428 | netif_carrier_off(dev->net); | ||
429 | } | ||
430 | } | ||
431 | |||
432 | static void sierra_net_dosync(struct usbnet *dev) | ||
433 | { | ||
434 | int status; | ||
435 | struct sierra_net_data *priv = sierra_net_get_private(dev); | ||
436 | |||
437 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
438 | |||
439 | /* tell modem we are ready */ | ||
440 | status = sierra_net_send_sync(dev); | ||
441 | if (status < 0) | ||
442 | netdev_err(dev->net, | ||
443 | "Send SYNC failed, status %d\n", status); | ||
444 | status = sierra_net_send_sync(dev); | ||
445 | if (status < 0) | ||
446 | netdev_err(dev->net, | ||
447 | "Send SYNC failed, status %d\n", status); | ||
448 | |||
449 | /* Now, start a timer and make sure we get the Restart Indication */ | ||
450 | priv->sync_timer.function = sierra_sync_timer; | ||
451 | priv->sync_timer.data = (unsigned long) dev; | ||
452 | priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY; | ||
453 | add_timer(&priv->sync_timer); | ||
454 | } | ||
455 | |||
456 | static void sierra_net_kevent(struct work_struct *work) | ||
457 | { | ||
458 | struct sierra_net_data *priv = | ||
459 | container_of(work, struct sierra_net_data, sierra_net_kevent); | ||
460 | struct usbnet *dev = priv->usbnet; | ||
461 | int len; | ||
462 | int err; | ||
463 | u8 *buf; | ||
464 | u8 ifnum; | ||
465 | |||
466 | if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) { | ||
467 | clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags); | ||
468 | |||
469 | /* Query the modem for the LSI message */ | ||
470 | buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL); | ||
471 | if (!buf) { | ||
472 | netdev_err(dev->net, | ||
473 | "failed to allocate buf for LS msg\n"); | ||
474 | return; | ||
475 | } | ||
476 | ifnum = priv->ifnum; | ||
477 | len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | ||
478 | USB_CDC_GET_ENCAPSULATED_RESPONSE, | ||
479 | USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE, | ||
480 | 0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN, | ||
481 | USB_CTRL_SET_TIMEOUT); | ||
482 | |||
483 | if (len < 0) { | ||
484 | netdev_err(dev->net, | ||
485 | "usb_control_msg failed, status %d\n", len); | ||
486 | } else { | ||
487 | struct hip_hdr hh; | ||
488 | |||
489 | dev_dbg(&dev->udev->dev, "%s: Received status message," | ||
490 | " %04x bytes", __func__, len); | ||
491 | |||
492 | err = parse_hip(buf, len, &hh); | ||
493 | if (err) { | ||
494 | netdev_err(dev->net, "%s: Bad packet," | ||
495 | " parse result %d\n", __func__, err); | ||
496 | kfree(buf); | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | /* Validate packet length */ | ||
501 | if (len != hh.hdrlen + hh.payload_len.word) { | ||
502 | netdev_err(dev->net, "%s: Bad packet, received" | ||
503 | " %d, expected %d\n", __func__, len, | ||
504 | hh.hdrlen + hh.payload_len.word); | ||
505 | kfree(buf); | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | /* Switch on received message types */ | ||
510 | switch (hh.msgid.byte) { | ||
511 | case SIERRA_NET_HIP_LSI_UMTSID: | ||
512 | dev_dbg(&dev->udev->dev, "LSI for ctx:%d", | ||
513 | hh.msgspecific.byte); | ||
514 | sierra_net_handle_lsi(dev, buf, &hh); | ||
515 | break; | ||
516 | case SIERRA_NET_HIP_RESTART_ID: | ||
517 | dev_dbg(&dev->udev->dev, "Restart reported: %d," | ||
518 | " stopping sync timer", | ||
519 | hh.msgspecific.byte); | ||
520 | /* Got sync resp - stop timer & clear mask */ | ||
521 | del_timer_sync(&priv->sync_timer); | ||
522 | clear_bit(SIERRA_NET_TIMER_EXPIRY, | ||
523 | &priv->kevent_flags); | ||
524 | break; | ||
525 | case SIERRA_NET_HIP_HSYNC_ID: | ||
526 | dev_dbg(&dev->udev->dev, "SYNC received"); | ||
527 | err = sierra_net_send_sync(dev); | ||
528 | if (err < 0) | ||
529 | netdev_err(dev->net, | ||
530 | "Send SYNC failed %d\n", err); | ||
531 | break; | ||
532 | case SIERRA_NET_HIP_EXTENDEDID: | ||
533 | netdev_err(dev->net, "Unrecognized HIP msg, " | ||
534 | "extmsgid 0x%04x\n", hh.extmsgid.word); | ||
535 | break; | ||
536 | case SIERRA_NET_HIP_RCGI: | ||
537 | /* Ignored */ | ||
538 | break; | ||
539 | default: | ||
540 | netdev_err(dev->net, "Unrecognized HIP msg, " | ||
541 | "msgid 0x%02x\n", hh.msgid.byte); | ||
542 | break; | ||
543 | } | ||
544 | } | ||
545 | kfree(buf); | ||
546 | } | ||
547 | /* The sync timer bit might be set */ | ||
548 | if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) { | ||
549 | clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags); | ||
550 | dev_dbg(&dev->udev->dev, "Deferred sync timer expiry"); | ||
551 | sierra_net_dosync(priv->usbnet); | ||
552 | } | ||
553 | |||
554 | if (priv->kevent_flags) | ||
555 | dev_dbg(&dev->udev->dev, "sierra_net_kevent done, " | ||
556 | "kevent_flags = 0x%lx", priv->kevent_flags); | ||
557 | } | ||
558 | |||
559 | static void sierra_net_defer_kevent(struct usbnet *dev, int work) | ||
560 | { | ||
561 | struct sierra_net_data *priv = sierra_net_get_private(dev); | ||
562 | |||
563 | set_bit(work, &priv->kevent_flags); | ||
564 | schedule_work(&priv->sierra_net_kevent); | ||
565 | } | ||
566 | |||
567 | /* | ||
568 | * Sync Retransmit Timer Handler. On expiry, kick the work queue | ||
569 | */ | ||
570 | void sierra_sync_timer(unsigned long syncdata) | ||
571 | { | ||
572 | struct usbnet *dev = (struct usbnet *)syncdata; | ||
573 | |||
574 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
575 | /* Kick the tasklet */ | ||
576 | sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY); | ||
577 | } | ||
578 | |||
579 | static void sierra_net_status(struct usbnet *dev, struct urb *urb) | ||
580 | { | ||
581 | struct usb_cdc_notification *event; | ||
582 | |||
583 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
584 | |||
585 | if (urb->actual_length < sizeof *event) | ||
586 | return; | ||
587 | |||
588 | /* Add cases to handle other standard notifications. */ | ||
589 | event = urb->transfer_buffer; | ||
590 | switch (event->bNotificationType) { | ||
591 | case USB_CDC_NOTIFY_NETWORK_CONNECTION: | ||
592 | case USB_CDC_NOTIFY_SPEED_CHANGE: | ||
593 | /* USB 305 sends those */ | ||
594 | break; | ||
595 | case USB_CDC_NOTIFY_RESPONSE_AVAILABLE: | ||
596 | sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL); | ||
597 | break; | ||
598 | default: | ||
599 | netdev_err(dev->net, ": unexpected notification %02x!\n", | ||
600 | event->bNotificationType); | ||
601 | break; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static void sierra_net_get_drvinfo(struct net_device *net, | ||
606 | struct ethtool_drvinfo *info) | ||
607 | { | ||
608 | /* Inherit standard device info */ | ||
609 | usbnet_get_drvinfo(net, info); | ||
610 | strncpy(info->driver, driver_name, sizeof info->driver); | ||
611 | strncpy(info->version, DRIVER_VERSION, sizeof info->version); | ||
612 | } | ||
613 | |||
614 | static u32 sierra_net_get_link(struct net_device *net) | ||
615 | { | ||
616 | struct usbnet *dev = netdev_priv(net); | ||
617 | /* Report link is down whenever the interface is down */ | ||
618 | return sierra_net_get_private(dev)->link_up && netif_running(net); | ||
619 | } | ||
620 | |||
621 | static struct ethtool_ops sierra_net_ethtool_ops = { | ||
622 | .get_drvinfo = sierra_net_get_drvinfo, | ||
623 | .get_link = sierra_net_get_link, | ||
624 | .get_msglevel = usbnet_get_msglevel, | ||
625 | .set_msglevel = usbnet_set_msglevel, | ||
626 | .get_settings = usbnet_get_settings, | ||
627 | .set_settings = usbnet_set_settings, | ||
628 | .nway_reset = usbnet_nway_reset, | ||
629 | }; | ||
630 | |||
631 | /* MTU can not be more than 1500 bytes, enforce it. */ | ||
632 | static int sierra_net_change_mtu(struct net_device *net, int new_mtu) | ||
633 | { | ||
634 | if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU) | ||
635 | return -EINVAL; | ||
636 | |||
637 | return usbnet_change_mtu(net, new_mtu); | ||
638 | } | ||
639 | |||
640 | static int is_whitelisted(const u8 ifnum, | ||
641 | const struct sierra_net_iface_info *whitelist) | ||
642 | { | ||
643 | if (whitelist) { | ||
644 | const u8 *list = whitelist->ifaceinfo; | ||
645 | int i; | ||
646 | |||
647 | for (i = 0; i < whitelist->infolen; i++) { | ||
648 | if (list[i] == ifnum) | ||
649 | return 1; | ||
650 | } | ||
651 | } | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | ||
656 | { | ||
657 | int result = 0; | ||
658 | u16 *attrdata; | ||
659 | |||
660 | attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL); | ||
661 | if (!attrdata) | ||
662 | return -ENOMEM; | ||
663 | |||
664 | result = usb_control_msg( | ||
665 | dev->udev, | ||
666 | usb_rcvctrlpipe(dev->udev, 0), | ||
667 | /* _u8 vendor specific request */ | ||
668 | SWI_USB_REQUEST_GET_FW_ATTR, | ||
669 | USB_DIR_IN | USB_TYPE_VENDOR, /* __u8 request type */ | ||
670 | 0x0000, /* __u16 value not used */ | ||
671 | 0x0000, /* __u16 index not used */ | ||
672 | attrdata, /* char *data */ | ||
673 | sizeof(*attrdata), /* __u16 size */ | ||
674 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | ||
675 | |||
676 | if (result < 0) { | ||
677 | kfree(attrdata); | ||
678 | return -EIO; | ||
679 | } | ||
680 | |||
681 | *datap = *attrdata; | ||
682 | |||
683 | kfree(attrdata); | ||
684 | return result; | ||
685 | } | ||
686 | |||
687 | /* | ||
688 | * collects the bulk endpoints, the status endpoint. | ||
689 | */ | ||
690 | static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) | ||
691 | { | ||
692 | u8 ifacenum; | ||
693 | u8 numendpoints; | ||
694 | u16 fwattr = 0; | ||
695 | int status; | ||
696 | struct ethhdr *eth; | ||
697 | struct sierra_net_data *priv; | ||
698 | static const u8 sync_tmplate[sizeof(priv->sync_msg)] = { | ||
699 | 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00}; | ||
700 | static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = { | ||
701 | 0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00}; | ||
702 | |||
703 | struct sierra_net_info_data *data = | ||
704 | (struct sierra_net_info_data *)dev->driver_info->data; | ||
705 | |||
706 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
707 | |||
708 | ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; | ||
709 | /* We only accept certain interfaces */ | ||
710 | if (!is_whitelisted(ifacenum, &data->whitelist)) { | ||
711 | dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum); | ||
712 | return -ENODEV; | ||
713 | } | ||
714 | numendpoints = intf->cur_altsetting->desc.bNumEndpoints; | ||
715 | /* We have three endpoints, bulk in and out, and a status */ | ||
716 | if (numendpoints != 3) { | ||
717 | dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d", | ||
718 | numendpoints); | ||
719 | return -ENODEV; | ||
720 | } | ||
721 | /* Status endpoint set in usbnet_get_endpoints() */ | ||
722 | dev->status = NULL; | ||
723 | status = usbnet_get_endpoints(dev, intf); | ||
724 | if (status < 0) { | ||
725 | dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)", | ||
726 | status); | ||
727 | return -ENODEV; | ||
728 | } | ||
729 | /* Initialize sierra private data */ | ||
730 | priv = kzalloc(sizeof *priv, GFP_KERNEL); | ||
731 | if (!priv) { | ||
732 | dev_err(&dev->udev->dev, "No memory"); | ||
733 | return -ENOMEM; | ||
734 | } | ||
735 | |||
736 | priv->usbnet = dev; | ||
737 | priv->ifnum = ifacenum; | ||
738 | dev->net->netdev_ops = &sierra_net_device_ops; | ||
739 | |||
740 | /* change MAC addr to include, ifacenum, and to be unique */ | ||
741 | dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter); | ||
742 | dev->net->dev_addr[ETH_ALEN-1] = ifacenum; | ||
743 | |||
744 | /* we will have to manufacture ethernet headers, prepare template */ | ||
745 | eth = (struct ethhdr *)priv->ethr_hdr_tmpl; | ||
746 | memcpy(ð->h_dest, dev->net->dev_addr, ETH_ALEN); | ||
747 | eth->h_proto = cpu_to_be16(ETH_P_IP); | ||
748 | |||
749 | /* prepare shutdown message template */ | ||
750 | memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg)); | ||
751 | /* set context index initially to 0 - prepares tx hdr template */ | ||
752 | sierra_net_set_ctx_index(priv, 0); | ||
753 | |||
754 | /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */ | ||
755 | dev->rx_urb_size = data->rx_urb_size; | ||
756 | if (dev->udev->speed != USB_SPEED_HIGH) | ||
757 | dev->rx_urb_size = min_t(size_t, 4096, data->rx_urb_size); | ||
758 | |||
759 | dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN; | ||
760 | dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; | ||
761 | |||
762 | /* Set up the netdev */ | ||
763 | dev->net->flags |= IFF_NOARP; | ||
764 | dev->net->ethtool_ops = &sierra_net_ethtool_ops; | ||
765 | netif_carrier_off(dev->net); | ||
766 | |||
767 | sierra_net_set_private(dev, priv); | ||
768 | |||
769 | priv->kevent_flags = 0; | ||
770 | |||
771 | /* Use the shared workqueue */ | ||
772 | INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent); | ||
773 | |||
774 | /* Only need to do this once */ | ||
775 | init_timer(&priv->sync_timer); | ||
776 | |||
777 | /* verify fw attributes */ | ||
778 | status = sierra_net_get_fw_attr(dev, &fwattr); | ||
779 | dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr); | ||
780 | |||
781 | /* test whether firmware supports DHCP */ | ||
782 | if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) { | ||
783 | /* found incompatible firmware version */ | ||
784 | dev_err(&dev->udev->dev, "Incompatible driver and firmware" | ||
785 | " versions\n"); | ||
786 | kfree(priv); | ||
787 | return -ENODEV; | ||
788 | } | ||
789 | /* prepare sync message from template */ | ||
790 | memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg)); | ||
791 | |||
792 | /* initiate the sync sequence */ | ||
793 | sierra_net_dosync(dev); | ||
794 | |||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf) | ||
799 | { | ||
800 | int status; | ||
801 | struct sierra_net_data *priv = sierra_net_get_private(dev); | ||
802 | |||
803 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
804 | |||
805 | /* Kill the timer then flush the work queue */ | ||
806 | del_timer_sync(&priv->sync_timer); | ||
807 | |||
808 | flush_scheduled_work(); | ||
809 | |||
810 | /* tell modem we are going away */ | ||
811 | status = sierra_net_send_cmd(dev, priv->shdwn_msg, | ||
812 | sizeof(priv->shdwn_msg), "Shutdown"); | ||
813 | if (status < 0) | ||
814 | netdev_err(dev->net, | ||
815 | "usb_control_msg failed, status %d\n", status); | ||
816 | |||
817 | sierra_net_set_private(dev, NULL); | ||
818 | |||
819 | kfree(priv); | ||
820 | } | ||
821 | |||
822 | static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev, | ||
823 | struct sk_buff *skb, int len) | ||
824 | { | ||
825 | struct sk_buff *new_skb; | ||
826 | |||
827 | /* clone skb */ | ||
828 | new_skb = skb_clone(skb, GFP_ATOMIC); | ||
829 | |||
830 | /* remove len bytes from original */ | ||
831 | skb_pull(skb, len); | ||
832 | |||
833 | /* trim next packet to it's length */ | ||
834 | if (new_skb) { | ||
835 | skb_trim(new_skb, len); | ||
836 | } else { | ||
837 | if (netif_msg_rx_err(dev)) | ||
838 | netdev_err(dev->net, "failed to get skb\n"); | ||
839 | dev->net->stats.rx_dropped++; | ||
840 | } | ||
841 | |||
842 | return new_skb; | ||
843 | } | ||
844 | |||
845 | /* ---------------------------- Receive data path ----------------------*/ | ||
846 | static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
847 | { | ||
848 | int err; | ||
849 | struct hip_hdr hh; | ||
850 | struct sk_buff *new_skb; | ||
851 | |||
852 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
853 | |||
854 | /* could contain multiple packets */ | ||
855 | while (likely(skb->len)) { | ||
856 | err = parse_hip(skb->data, skb->len, &hh); | ||
857 | if (err) { | ||
858 | if (netif_msg_rx_err(dev)) | ||
859 | netdev_err(dev->net, "Invalid HIP header %d\n", | ||
860 | err); | ||
861 | /* dev->net->stats.rx_errors incremented by caller */ | ||
862 | dev->net->stats.rx_length_errors++; | ||
863 | return 0; | ||
864 | } | ||
865 | |||
866 | /* Validate Extended HIP header */ | ||
867 | if (!hh.extmsgid.is_present | ||
868 | || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) { | ||
869 | if (netif_msg_rx_err(dev)) | ||
870 | netdev_err(dev->net, "HIP/ETH: Invalid pkt\n"); | ||
871 | |||
872 | dev->net->stats.rx_frame_errors++; | ||
873 | /* dev->net->stats.rx_errors incremented by caller */; | ||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | skb_pull(skb, hh.hdrlen); | ||
878 | |||
879 | /* We are going to accept this packet, prepare it */ | ||
880 | memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl, | ||
881 | ETH_HLEN); | ||
882 | |||
883 | /* Last packet in batch handled by usbnet */ | ||
884 | if (hh.payload_len.word == skb->len) | ||
885 | return 1; | ||
886 | |||
887 | new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word); | ||
888 | if (new_skb) | ||
889 | usbnet_skb_return(dev, new_skb); | ||
890 | |||
891 | } /* while */ | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | /* ---------------------------- Transmit data path ----------------------*/ | ||
897 | struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | ||
898 | gfp_t flags) | ||
899 | { | ||
900 | struct sierra_net_data *priv = sierra_net_get_private(dev); | ||
901 | u16 len; | ||
902 | bool need_tail; | ||
903 | |||
904 | dev_dbg(&dev->udev->dev, "%s", __func__); | ||
905 | if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) { | ||
906 | /* enough head room as is? */ | ||
907 | if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) { | ||
908 | /* Save the Eth/IP length and set up HIP hdr */ | ||
909 | len = skb->len; | ||
910 | skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN); | ||
911 | /* Handle ZLP issue */ | ||
912 | need_tail = ((len + SIERRA_NET_HIP_EXT_HDR_LEN) | ||
913 | % dev->maxpacket == 0); | ||
914 | if (need_tail) { | ||
915 | if (unlikely(skb_tailroom(skb) == 0)) { | ||
916 | netdev_err(dev->net, "tx_fixup:" | ||
917 | "no room for packet\n"); | ||
918 | dev_kfree_skb_any(skb); | ||
919 | return NULL; | ||
920 | } else { | ||
921 | skb->data[skb->len] = 0; | ||
922 | __skb_put(skb, 1); | ||
923 | len = len + 1; | ||
924 | } | ||
925 | } | ||
926 | build_hip(skb->data, len, priv); | ||
927 | return skb; | ||
928 | } else { | ||
929 | /* | ||
930 | * compensate in the future if necessary | ||
931 | */ | ||
932 | netdev_err(dev->net, "tx_fixup: no room for HIP\n"); | ||
933 | } /* headroom */ | ||
934 | } | ||
935 | |||
936 | if (!priv->link_up) | ||
937 | dev->net->stats.tx_carrier_errors++; | ||
938 | |||
939 | /* tx_dropped incremented by usbnet */ | ||
940 | |||
941 | /* filter the packet out, release it */ | ||
942 | dev_kfree_skb_any(skb); | ||
943 | return NULL; | ||
944 | } | ||
945 | |||
946 | static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; | ||
947 | static const struct sierra_net_info_data sierra_net_info_data_68A3 = { | ||
948 | .rx_urb_size = 8 * 1024, | ||
949 | .whitelist = { | ||
950 | .infolen = ARRAY_SIZE(sierra_net_ifnum_list), | ||
951 | .ifaceinfo = sierra_net_ifnum_list | ||
952 | } | ||
953 | }; | ||
954 | |||
955 | static const struct driver_info sierra_net_info_68A3 = { | ||
956 | .description = "Sierra Wireless USB-to-WWAN Modem", | ||
957 | .flags = FLAG_WWAN | FLAG_SEND_ZLP, | ||
958 | .bind = sierra_net_bind, | ||
959 | .unbind = sierra_net_unbind, | ||
960 | .status = sierra_net_status, | ||
961 | .rx_fixup = sierra_net_rx_fixup, | ||
962 | .tx_fixup = sierra_net_tx_fixup, | ||
963 | .data = (unsigned long)&sierra_net_info_data_68A3, | ||
964 | }; | ||
965 | |||
966 | static const struct usb_device_id products[] = { | ||
967 | {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ | ||
968 | .driver_info = (unsigned long) &sierra_net_info_68A3}, | ||
969 | |||
970 | {}, /* last item */ | ||
971 | }; | ||
972 | MODULE_DEVICE_TABLE(usb, products); | ||
973 | |||
974 | /* We are based on usbnet, so let it handle the USB driver specifics */ | ||
975 | static struct usb_driver sierra_net_driver = { | ||
976 | .name = "sierra_net", | ||
977 | .id_table = products, | ||
978 | .probe = usbnet_probe, | ||
979 | .disconnect = usbnet_disconnect, | ||
980 | .suspend = usbnet_suspend, | ||
981 | .resume = usbnet_resume, | ||
982 | .no_dynamic_id = 1, | ||
983 | }; | ||
984 | |||
985 | static int __init sierra_net_init(void) | ||
986 | { | ||
987 | BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data) | ||
988 | < sizeof(struct cdc_state)); | ||
989 | |||
990 | return usb_register(&sierra_net_driver); | ||
991 | } | ||
992 | |||
993 | static void __exit sierra_net_exit(void) | ||
994 | { | ||
995 | usb_deregister(&sierra_net_driver); | ||
996 | } | ||
997 | |||
998 | module_exit(sierra_net_exit); | ||
999 | module_init(sierra_net_init); | ||
1000 | |||
1001 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
1002 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1003 | MODULE_VERSION(DRIVER_VERSION); | ||
1004 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c new file mode 100644 index 000000000000..35b98b1b79e4 --- /dev/null +++ b/drivers/net/usb/smsc75xx.c | |||
@@ -0,0 +1,1289 @@ | |||
1 | /*************************************************************************** | ||
2 | * | ||
3 | * Copyright (C) 2007-2010 SMSC | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | * | ||
19 | *****************************************************************************/ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/kmod.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/etherdevice.h> | ||
26 | #include <linux/ethtool.h> | ||
27 | #include <linux/mii.h> | ||
28 | #include <linux/usb.h> | ||
29 | #include <linux/crc32.h> | ||
30 | #include <linux/usb/usbnet.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include "smsc75xx.h" | ||
33 | |||
34 | #define SMSC_CHIPNAME "smsc75xx" | ||
35 | #define SMSC_DRIVER_VERSION "1.0.0" | ||
36 | #define HS_USB_PKT_SIZE (512) | ||
37 | #define FS_USB_PKT_SIZE (64) | ||
38 | #define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE) | ||
39 | #define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE) | ||
40 | #define DEFAULT_BULK_IN_DELAY (0x00002000) | ||
41 | #define MAX_SINGLE_PACKET_SIZE (9000) | ||
42 | #define LAN75XX_EEPROM_MAGIC (0x7500) | ||
43 | #define EEPROM_MAC_OFFSET (0x01) | ||
44 | #define DEFAULT_TX_CSUM_ENABLE (true) | ||
45 | #define DEFAULT_RX_CSUM_ENABLE (true) | ||
46 | #define DEFAULT_TSO_ENABLE (true) | ||
47 | #define SMSC75XX_INTERNAL_PHY_ID (1) | ||
48 | #define SMSC75XX_TX_OVERHEAD (8) | ||
49 | #define MAX_RX_FIFO_SIZE (20 * 1024) | ||
50 | #define MAX_TX_FIFO_SIZE (12 * 1024) | ||
51 | #define USB_VENDOR_ID_SMSC (0x0424) | ||
52 | #define USB_PRODUCT_ID_LAN7500 (0x7500) | ||
53 | #define USB_PRODUCT_ID_LAN7505 (0x7505) | ||
54 | |||
55 | #define check_warn(ret, fmt, args...) \ | ||
56 | ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) | ||
57 | |||
58 | #define check_warn_return(ret, fmt, args...) \ | ||
59 | ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } }) | ||
60 | |||
61 | #define check_warn_goto_done(ret, fmt, args...) \ | ||
62 | ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } }) | ||
63 | |||
64 | struct smsc75xx_priv { | ||
65 | struct usbnet *dev; | ||
66 | u32 rfe_ctl; | ||
67 | u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN]; | ||
68 | bool use_rx_csum; | ||
69 | struct mutex dataport_mutex; | ||
70 | spinlock_t rfe_ctl_lock; | ||
71 | struct work_struct set_multicast; | ||
72 | }; | ||
73 | |||
74 | struct usb_context { | ||
75 | struct usb_ctrlrequest req; | ||
76 | struct usbnet *dev; | ||
77 | }; | ||
78 | |||
79 | static int turbo_mode = true; | ||
80 | module_param(turbo_mode, bool, 0644); | ||
81 | MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); | ||
82 | |||
83 | static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, | ||
84 | u32 *data) | ||
85 | { | ||
86 | u32 *buf = kmalloc(4, GFP_KERNEL); | ||
87 | int ret; | ||
88 | |||
89 | BUG_ON(!dev); | ||
90 | |||
91 | if (!buf) | ||
92 | return -ENOMEM; | ||
93 | |||
94 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | ||
95 | USB_VENDOR_REQUEST_READ_REGISTER, | ||
96 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
97 | 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); | ||
98 | |||
99 | if (unlikely(ret < 0)) | ||
100 | netdev_warn(dev->net, | ||
101 | "Failed to read register index 0x%08x", index); | ||
102 | |||
103 | le32_to_cpus(buf); | ||
104 | *data = *buf; | ||
105 | kfree(buf); | ||
106 | |||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, | ||
111 | u32 data) | ||
112 | { | ||
113 | u32 *buf = kmalloc(4, GFP_KERNEL); | ||
114 | int ret; | ||
115 | |||
116 | BUG_ON(!dev); | ||
117 | |||
118 | if (!buf) | ||
119 | return -ENOMEM; | ||
120 | |||
121 | *buf = data; | ||
122 | cpu_to_le32s(buf); | ||
123 | |||
124 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | ||
125 | USB_VENDOR_REQUEST_WRITE_REGISTER, | ||
126 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
127 | 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); | ||
128 | |||
129 | if (unlikely(ret < 0)) | ||
130 | netdev_warn(dev->net, | ||
131 | "Failed to write register index 0x%08x", index); | ||
132 | |||
133 | kfree(buf); | ||
134 | |||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | /* Loop until the read is completed with timeout | ||
139 | * called with phy_mutex held */ | ||
140 | static int smsc75xx_phy_wait_not_busy(struct usbnet *dev) | ||
141 | { | ||
142 | unsigned long start_time = jiffies; | ||
143 | u32 val; | ||
144 | int ret; | ||
145 | |||
146 | do { | ||
147 | ret = smsc75xx_read_reg(dev, MII_ACCESS, &val); | ||
148 | check_warn_return(ret, "Error reading MII_ACCESS"); | ||
149 | |||
150 | if (!(val & MII_ACCESS_BUSY)) | ||
151 | return 0; | ||
152 | } while (!time_after(jiffies, start_time + HZ)); | ||
153 | |||
154 | return -EIO; | ||
155 | } | ||
156 | |||
157 | static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx) | ||
158 | { | ||
159 | struct usbnet *dev = netdev_priv(netdev); | ||
160 | u32 val, addr; | ||
161 | int ret; | ||
162 | |||
163 | mutex_lock(&dev->phy_mutex); | ||
164 | |||
165 | /* confirm MII not busy */ | ||
166 | ret = smsc75xx_phy_wait_not_busy(dev); | ||
167 | check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read"); | ||
168 | |||
169 | /* set the address, index & direction (read from PHY) */ | ||
170 | phy_id &= dev->mii.phy_id_mask; | ||
171 | idx &= dev->mii.reg_num_mask; | ||
172 | addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) | ||
173 | | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) | ||
174 | | MII_ACCESS_READ; | ||
175 | ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); | ||
176 | check_warn_goto_done(ret, "Error writing MII_ACCESS"); | ||
177 | |||
178 | ret = smsc75xx_phy_wait_not_busy(dev); | ||
179 | check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx); | ||
180 | |||
181 | ret = smsc75xx_read_reg(dev, MII_DATA, &val); | ||
182 | check_warn_goto_done(ret, "Error reading MII_DATA"); | ||
183 | |||
184 | ret = (u16)(val & 0xFFFF); | ||
185 | |||
186 | done: | ||
187 | mutex_unlock(&dev->phy_mutex); | ||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx, | ||
192 | int regval) | ||
193 | { | ||
194 | struct usbnet *dev = netdev_priv(netdev); | ||
195 | u32 val, addr; | ||
196 | int ret; | ||
197 | |||
198 | mutex_lock(&dev->phy_mutex); | ||
199 | |||
200 | /* confirm MII not busy */ | ||
201 | ret = smsc75xx_phy_wait_not_busy(dev); | ||
202 | check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write"); | ||
203 | |||
204 | val = regval; | ||
205 | ret = smsc75xx_write_reg(dev, MII_DATA, val); | ||
206 | check_warn_goto_done(ret, "Error writing MII_DATA"); | ||
207 | |||
208 | /* set the address, index & direction (write to PHY) */ | ||
209 | phy_id &= dev->mii.phy_id_mask; | ||
210 | idx &= dev->mii.reg_num_mask; | ||
211 | addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) | ||
212 | | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) | ||
213 | | MII_ACCESS_WRITE; | ||
214 | ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); | ||
215 | check_warn_goto_done(ret, "Error writing MII_ACCESS"); | ||
216 | |||
217 | ret = smsc75xx_phy_wait_not_busy(dev); | ||
218 | check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx); | ||
219 | |||
220 | done: | ||
221 | mutex_unlock(&dev->phy_mutex); | ||
222 | } | ||
223 | |||
224 | static int smsc75xx_wait_eeprom(struct usbnet *dev) | ||
225 | { | ||
226 | unsigned long start_time = jiffies; | ||
227 | u32 val; | ||
228 | int ret; | ||
229 | |||
230 | do { | ||
231 | ret = smsc75xx_read_reg(dev, E2P_CMD, &val); | ||
232 | check_warn_return(ret, "Error reading E2P_CMD"); | ||
233 | |||
234 | if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT)) | ||
235 | break; | ||
236 | udelay(40); | ||
237 | } while (!time_after(jiffies, start_time + HZ)); | ||
238 | |||
239 | if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) { | ||
240 | netdev_warn(dev->net, "EEPROM read operation timeout"); | ||
241 | return -EIO; | ||
242 | } | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev) | ||
248 | { | ||
249 | unsigned long start_time = jiffies; | ||
250 | u32 val; | ||
251 | int ret; | ||
252 | |||
253 | do { | ||
254 | ret = smsc75xx_read_reg(dev, E2P_CMD, &val); | ||
255 | check_warn_return(ret, "Error reading E2P_CMD"); | ||
256 | |||
257 | if (!(val & E2P_CMD_BUSY)) | ||
258 | return 0; | ||
259 | |||
260 | udelay(40); | ||
261 | } while (!time_after(jiffies, start_time + HZ)); | ||
262 | |||
263 | netdev_warn(dev->net, "EEPROM is busy"); | ||
264 | return -EIO; | ||
265 | } | ||
266 | |||
267 | static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length, | ||
268 | u8 *data) | ||
269 | { | ||
270 | u32 val; | ||
271 | int i, ret; | ||
272 | |||
273 | BUG_ON(!dev); | ||
274 | BUG_ON(!data); | ||
275 | |||
276 | ret = smsc75xx_eeprom_confirm_not_busy(dev); | ||
277 | if (ret) | ||
278 | return ret; | ||
279 | |||
280 | for (i = 0; i < length; i++) { | ||
281 | val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR); | ||
282 | ret = smsc75xx_write_reg(dev, E2P_CMD, val); | ||
283 | check_warn_return(ret, "Error writing E2P_CMD"); | ||
284 | |||
285 | ret = smsc75xx_wait_eeprom(dev); | ||
286 | if (ret < 0) | ||
287 | return ret; | ||
288 | |||
289 | ret = smsc75xx_read_reg(dev, E2P_DATA, &val); | ||
290 | check_warn_return(ret, "Error reading E2P_DATA"); | ||
291 | |||
292 | data[i] = val & 0xFF; | ||
293 | offset++; | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length, | ||
300 | u8 *data) | ||
301 | { | ||
302 | u32 val; | ||
303 | int i, ret; | ||
304 | |||
305 | BUG_ON(!dev); | ||
306 | BUG_ON(!data); | ||
307 | |||
308 | ret = smsc75xx_eeprom_confirm_not_busy(dev); | ||
309 | if (ret) | ||
310 | return ret; | ||
311 | |||
312 | /* Issue write/erase enable command */ | ||
313 | val = E2P_CMD_BUSY | E2P_CMD_EWEN; | ||
314 | ret = smsc75xx_write_reg(dev, E2P_CMD, val); | ||
315 | check_warn_return(ret, "Error writing E2P_CMD"); | ||
316 | |||
317 | ret = smsc75xx_wait_eeprom(dev); | ||
318 | if (ret < 0) | ||
319 | return ret; | ||
320 | |||
321 | for (i = 0; i < length; i++) { | ||
322 | |||
323 | /* Fill data register */ | ||
324 | val = data[i]; | ||
325 | ret = smsc75xx_write_reg(dev, E2P_DATA, val); | ||
326 | check_warn_return(ret, "Error writing E2P_DATA"); | ||
327 | |||
328 | /* Send "write" command */ | ||
329 | val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR); | ||
330 | ret = smsc75xx_write_reg(dev, E2P_CMD, val); | ||
331 | check_warn_return(ret, "Error writing E2P_CMD"); | ||
332 | |||
333 | ret = smsc75xx_wait_eeprom(dev); | ||
334 | if (ret < 0) | ||
335 | return ret; | ||
336 | |||
337 | offset++; | ||
338 | } | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev) | ||
344 | { | ||
345 | int i, ret; | ||
346 | |||
347 | for (i = 0; i < 100; i++) { | ||
348 | u32 dp_sel; | ||
349 | ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); | ||
350 | check_warn_return(ret, "Error reading DP_SEL"); | ||
351 | |||
352 | if (dp_sel & DP_SEL_DPRDY) | ||
353 | return 0; | ||
354 | |||
355 | udelay(40); | ||
356 | } | ||
357 | |||
358 | netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out"); | ||
359 | |||
360 | return -EIO; | ||
361 | } | ||
362 | |||
363 | static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr, | ||
364 | u32 length, u32 *buf) | ||
365 | { | ||
366 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
367 | u32 dp_sel; | ||
368 | int i, ret; | ||
369 | |||
370 | mutex_lock(&pdata->dataport_mutex); | ||
371 | |||
372 | ret = smsc75xx_dataport_wait_not_busy(dev); | ||
373 | check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry"); | ||
374 | |||
375 | ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); | ||
376 | check_warn_goto_done(ret, "Error reading DP_SEL"); | ||
377 | |||
378 | dp_sel &= ~DP_SEL_RSEL; | ||
379 | dp_sel |= ram_select; | ||
380 | ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel); | ||
381 | check_warn_goto_done(ret, "Error writing DP_SEL"); | ||
382 | |||
383 | for (i = 0; i < length; i++) { | ||
384 | ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i); | ||
385 | check_warn_goto_done(ret, "Error writing DP_ADDR"); | ||
386 | |||
387 | ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]); | ||
388 | check_warn_goto_done(ret, "Error writing DP_DATA"); | ||
389 | |||
390 | ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE); | ||
391 | check_warn_goto_done(ret, "Error writing DP_CMD"); | ||
392 | |||
393 | ret = smsc75xx_dataport_wait_not_busy(dev); | ||
394 | check_warn_goto_done(ret, "smsc75xx_dataport_write timeout"); | ||
395 | } | ||
396 | |||
397 | done: | ||
398 | mutex_unlock(&pdata->dataport_mutex); | ||
399 | return ret; | ||
400 | } | ||
401 | |||
402 | /* returns hash bit number for given MAC address */ | ||
403 | static u32 smsc75xx_hash(char addr[ETH_ALEN]) | ||
404 | { | ||
405 | return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff; | ||
406 | } | ||
407 | |||
408 | static void smsc75xx_deferred_multicast_write(struct work_struct *param) | ||
409 | { | ||
410 | struct smsc75xx_priv *pdata = | ||
411 | container_of(param, struct smsc75xx_priv, set_multicast); | ||
412 | struct usbnet *dev = pdata->dev; | ||
413 | int ret; | ||
414 | |||
415 | netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x", | ||
416 | pdata->rfe_ctl); | ||
417 | |||
418 | smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN, | ||
419 | DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table); | ||
420 | |||
421 | ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); | ||
422 | check_warn(ret, "Error writing RFE_CRL"); | ||
423 | } | ||
424 | |||
425 | static void smsc75xx_set_multicast(struct net_device *netdev) | ||
426 | { | ||
427 | struct usbnet *dev = netdev_priv(netdev); | ||
428 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
429 | unsigned long flags; | ||
430 | int i; | ||
431 | |||
432 | spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); | ||
433 | |||
434 | pdata->rfe_ctl &= | ||
435 | ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF); | ||
436 | pdata->rfe_ctl |= RFE_CTL_AB; | ||
437 | |||
438 | for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++) | ||
439 | pdata->multicast_hash_table[i] = 0; | ||
440 | |||
441 | if (dev->net->flags & IFF_PROMISC) { | ||
442 | netif_dbg(dev, drv, dev->net, "promiscuous mode enabled"); | ||
443 | pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU; | ||
444 | } else if (dev->net->flags & IFF_ALLMULTI) { | ||
445 | netif_dbg(dev, drv, dev->net, "receive all multicast enabled"); | ||
446 | pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF; | ||
447 | } else if (!netdev_mc_empty(dev->net)) { | ||
448 | struct dev_mc_list *mc_list; | ||
449 | |||
450 | netif_dbg(dev, drv, dev->net, "receive multicast hash filter"); | ||
451 | |||
452 | pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF; | ||
453 | |||
454 | netdev_for_each_mc_addr(mc_list, netdev) { | ||
455 | u32 bitnum = smsc75xx_hash(mc_list->dmi_addr); | ||
456 | pdata->multicast_hash_table[bitnum / 32] |= | ||
457 | (1 << (bitnum % 32)); | ||
458 | } | ||
459 | } else { | ||
460 | netif_dbg(dev, drv, dev->net, "receive own packets only"); | ||
461 | pdata->rfe_ctl |= RFE_CTL_DPF; | ||
462 | } | ||
463 | |||
464 | spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); | ||
465 | |||
466 | /* defer register writes to a sleepable context */ | ||
467 | schedule_work(&pdata->set_multicast); | ||
468 | } | ||
469 | |||
470 | static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex, | ||
471 | u16 lcladv, u16 rmtadv) | ||
472 | { | ||
473 | u32 flow = 0, fct_flow = 0; | ||
474 | int ret; | ||
475 | |||
476 | if (duplex == DUPLEX_FULL) { | ||
477 | u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); | ||
478 | |||
479 | if (cap & FLOW_CTRL_TX) { | ||
480 | flow = (FLOW_TX_FCEN | 0xFFFF); | ||
481 | /* set fct_flow thresholds to 20% and 80% */ | ||
482 | fct_flow = (8 << 8) | 32; | ||
483 | } | ||
484 | |||
485 | if (cap & FLOW_CTRL_RX) | ||
486 | flow |= FLOW_RX_FCEN; | ||
487 | |||
488 | netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s", | ||
489 | (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), | ||
490 | (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); | ||
491 | } else { | ||
492 | netif_dbg(dev, link, dev->net, "half duplex"); | ||
493 | } | ||
494 | |||
495 | ret = smsc75xx_write_reg(dev, FLOW, flow); | ||
496 | check_warn_return(ret, "Error writing FLOW"); | ||
497 | |||
498 | ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow); | ||
499 | check_warn_return(ret, "Error writing FCT_FLOW"); | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static int smsc75xx_link_reset(struct usbnet *dev) | ||
505 | { | ||
506 | struct mii_if_info *mii = &dev->mii; | ||
507 | struct ethtool_cmd ecmd; | ||
508 | u16 lcladv, rmtadv; | ||
509 | int ret; | ||
510 | |||
511 | /* clear interrupt status */ | ||
512 | ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); | ||
513 | check_warn_return(ret, "Error reading PHY_INT_SRC"); | ||
514 | |||
515 | ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); | ||
516 | check_warn_return(ret, "Error writing INT_STS"); | ||
517 | |||
518 | mii_check_media(mii, 1, 1); | ||
519 | mii_ethtool_gset(&dev->mii, &ecmd); | ||
520 | lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); | ||
521 | rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA); | ||
522 | |||
523 | netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x" | ||
524 | " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv); | ||
525 | |||
526 | return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv); | ||
527 | } | ||
528 | |||
529 | static void smsc75xx_status(struct usbnet *dev, struct urb *urb) | ||
530 | { | ||
531 | u32 intdata; | ||
532 | |||
533 | if (urb->actual_length != 4) { | ||
534 | netdev_warn(dev->net, | ||
535 | "unexpected urb length %d", urb->actual_length); | ||
536 | return; | ||
537 | } | ||
538 | |||
539 | memcpy(&intdata, urb->transfer_buffer, 4); | ||
540 | le32_to_cpus(&intdata); | ||
541 | |||
542 | netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata); | ||
543 | |||
544 | if (intdata & INT_ENP_PHY_INT) | ||
545 | usbnet_defer_kevent(dev, EVENT_LINK_RESET); | ||
546 | else | ||
547 | netdev_warn(dev->net, | ||
548 | "unexpected interrupt, intdata=0x%08X", intdata); | ||
549 | } | ||
550 | |||
551 | /* Enable or disable Rx checksum offload engine */ | ||
552 | static int smsc75xx_set_rx_csum_offload(struct usbnet *dev) | ||
553 | { | ||
554 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
555 | unsigned long flags; | ||
556 | int ret; | ||
557 | |||
558 | spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); | ||
559 | |||
560 | if (pdata->use_rx_csum) | ||
561 | pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM; | ||
562 | else | ||
563 | pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM); | ||
564 | |||
565 | spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); | ||
566 | |||
567 | ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); | ||
568 | check_warn_return(ret, "Error writing RFE_CTL"); | ||
569 | |||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net) | ||
574 | { | ||
575 | return MAX_EEPROM_SIZE; | ||
576 | } | ||
577 | |||
578 | static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev, | ||
579 | struct ethtool_eeprom *ee, u8 *data) | ||
580 | { | ||
581 | struct usbnet *dev = netdev_priv(netdev); | ||
582 | |||
583 | ee->magic = LAN75XX_EEPROM_MAGIC; | ||
584 | |||
585 | return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data); | ||
586 | } | ||
587 | |||
588 | static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev, | ||
589 | struct ethtool_eeprom *ee, u8 *data) | ||
590 | { | ||
591 | struct usbnet *dev = netdev_priv(netdev); | ||
592 | |||
593 | if (ee->magic != LAN75XX_EEPROM_MAGIC) { | ||
594 | netdev_warn(dev->net, | ||
595 | "EEPROM: magic value mismatch: 0x%x", ee->magic); | ||
596 | return -EINVAL; | ||
597 | } | ||
598 | |||
599 | return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data); | ||
600 | } | ||
601 | |||
602 | static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev) | ||
603 | { | ||
604 | struct usbnet *dev = netdev_priv(netdev); | ||
605 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
606 | |||
607 | return pdata->use_rx_csum; | ||
608 | } | ||
609 | |||
610 | static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val) | ||
611 | { | ||
612 | struct usbnet *dev = netdev_priv(netdev); | ||
613 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
614 | |||
615 | pdata->use_rx_csum = !!val; | ||
616 | |||
617 | return smsc75xx_set_rx_csum_offload(dev); | ||
618 | } | ||
619 | |||
620 | static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data) | ||
621 | { | ||
622 | if (data) | ||
623 | netdev->features |= NETIF_F_TSO | NETIF_F_TSO6; | ||
624 | else | ||
625 | netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
626 | |||
627 | return 0; | ||
628 | } | ||
629 | |||
630 | static const struct ethtool_ops smsc75xx_ethtool_ops = { | ||
631 | .get_link = usbnet_get_link, | ||
632 | .nway_reset = usbnet_nway_reset, | ||
633 | .get_drvinfo = usbnet_get_drvinfo, | ||
634 | .get_msglevel = usbnet_get_msglevel, | ||
635 | .set_msglevel = usbnet_set_msglevel, | ||
636 | .get_settings = usbnet_get_settings, | ||
637 | .set_settings = usbnet_set_settings, | ||
638 | .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len, | ||
639 | .get_eeprom = smsc75xx_ethtool_get_eeprom, | ||
640 | .set_eeprom = smsc75xx_ethtool_set_eeprom, | ||
641 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
642 | .set_tx_csum = ethtool_op_set_tx_hw_csum, | ||
643 | .get_rx_csum = smsc75xx_ethtool_get_rx_csum, | ||
644 | .set_rx_csum = smsc75xx_ethtool_set_rx_csum, | ||
645 | .get_tso = ethtool_op_get_tso, | ||
646 | .set_tso = smsc75xx_ethtool_set_tso, | ||
647 | }; | ||
648 | |||
649 | static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | ||
650 | { | ||
651 | struct usbnet *dev = netdev_priv(netdev); | ||
652 | |||
653 | if (!netif_running(netdev)) | ||
654 | return -EINVAL; | ||
655 | |||
656 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | ||
657 | } | ||
658 | |||
659 | static void smsc75xx_init_mac_address(struct usbnet *dev) | ||
660 | { | ||
661 | /* try reading mac address from EEPROM */ | ||
662 | if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, | ||
663 | dev->net->dev_addr) == 0) { | ||
664 | if (is_valid_ether_addr(dev->net->dev_addr)) { | ||
665 | /* eeprom values are valid so use them */ | ||
666 | netif_dbg(dev, ifup, dev->net, | ||
667 | "MAC address read from EEPROM"); | ||
668 | return; | ||
669 | } | ||
670 | } | ||
671 | |||
672 | /* no eeprom, or eeprom values are invalid. generate random MAC */ | ||
673 | random_ether_addr(dev->net->dev_addr); | ||
674 | netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr"); | ||
675 | } | ||
676 | |||
677 | static int smsc75xx_set_mac_address(struct usbnet *dev) | ||
678 | { | ||
679 | u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | | ||
680 | dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; | ||
681 | u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; | ||
682 | |||
683 | int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi); | ||
684 | check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret); | ||
685 | |||
686 | ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo); | ||
687 | check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret); | ||
688 | |||
689 | addr_hi |= ADDR_FILTX_FB_VALID; | ||
690 | ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi); | ||
691 | check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret); | ||
692 | |||
693 | ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo); | ||
694 | check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret); | ||
695 | |||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static int smsc75xx_phy_initialize(struct usbnet *dev) | ||
700 | { | ||
701 | int bmcr, timeout = 0; | ||
702 | |||
703 | /* Initialize MII structure */ | ||
704 | dev->mii.dev = dev->net; | ||
705 | dev->mii.mdio_read = smsc75xx_mdio_read; | ||
706 | dev->mii.mdio_write = smsc75xx_mdio_write; | ||
707 | dev->mii.phy_id_mask = 0x1f; | ||
708 | dev->mii.reg_num_mask = 0x1f; | ||
709 | dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID; | ||
710 | |||
711 | /* reset phy and wait for reset to complete */ | ||
712 | smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | ||
713 | |||
714 | do { | ||
715 | msleep(10); | ||
716 | bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); | ||
717 | check_warn_return(bmcr, "Error reading MII_BMCR"); | ||
718 | timeout++; | ||
719 | } while ((bmcr & MII_BMCR) && (timeout < 100)); | ||
720 | |||
721 | if (timeout >= 100) { | ||
722 | netdev_warn(dev->net, "timeout on PHY Reset"); | ||
723 | return -EIO; | ||
724 | } | ||
725 | |||
726 | smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | ||
727 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | | ||
728 | ADVERTISE_PAUSE_ASYM); | ||
729 | |||
730 | /* read to clear */ | ||
731 | smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); | ||
732 | check_warn_return(bmcr, "Error reading PHY_INT_SRC"); | ||
733 | |||
734 | smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, | ||
735 | PHY_INT_MASK_DEFAULT); | ||
736 | mii_nway_restart(&dev->mii); | ||
737 | |||
738 | netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); | ||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) | ||
743 | { | ||
744 | int ret = 0; | ||
745 | u32 buf; | ||
746 | bool rxenabled; | ||
747 | |||
748 | ret = smsc75xx_read_reg(dev, MAC_RX, &buf); | ||
749 | check_warn_return(ret, "Failed to read MAC_RX: %d", ret); | ||
750 | |||
751 | rxenabled = ((buf & MAC_RX_RXEN) != 0); | ||
752 | |||
753 | if (rxenabled) { | ||
754 | buf &= ~MAC_RX_RXEN; | ||
755 | ret = smsc75xx_write_reg(dev, MAC_RX, buf); | ||
756 | check_warn_return(ret, "Failed to write MAC_RX: %d", ret); | ||
757 | } | ||
758 | |||
759 | /* add 4 to size for FCS */ | ||
760 | buf &= ~MAC_RX_MAX_SIZE; | ||
761 | buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE); | ||
762 | |||
763 | ret = smsc75xx_write_reg(dev, MAC_RX, buf); | ||
764 | check_warn_return(ret, "Failed to write MAC_RX: %d", ret); | ||
765 | |||
766 | if (rxenabled) { | ||
767 | buf |= MAC_RX_RXEN; | ||
768 | ret = smsc75xx_write_reg(dev, MAC_RX, buf); | ||
769 | check_warn_return(ret, "Failed to write MAC_RX: %d", ret); | ||
770 | } | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) | ||
776 | { | ||
777 | struct usbnet *dev = netdev_priv(netdev); | ||
778 | |||
779 | int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); | ||
780 | check_warn_return(ret, "Failed to set mac rx frame length"); | ||
781 | |||
782 | return usbnet_change_mtu(netdev, new_mtu); | ||
783 | } | ||
784 | |||
785 | static int smsc75xx_reset(struct usbnet *dev) | ||
786 | { | ||
787 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
788 | u32 buf; | ||
789 | int ret = 0, timeout; | ||
790 | |||
791 | netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset"); | ||
792 | |||
793 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); | ||
794 | check_warn_return(ret, "Failed to read HW_CFG: %d", ret); | ||
795 | |||
796 | buf |= HW_CFG_LRST; | ||
797 | |||
798 | ret = smsc75xx_write_reg(dev, HW_CFG, buf); | ||
799 | check_warn_return(ret, "Failed to write HW_CFG: %d", ret); | ||
800 | |||
801 | timeout = 0; | ||
802 | do { | ||
803 | msleep(10); | ||
804 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); | ||
805 | check_warn_return(ret, "Failed to read HW_CFG: %d", ret); | ||
806 | timeout++; | ||
807 | } while ((buf & HW_CFG_LRST) && (timeout < 100)); | ||
808 | |||
809 | if (timeout >= 100) { | ||
810 | netdev_warn(dev->net, "timeout on completion of Lite Reset"); | ||
811 | return -EIO; | ||
812 | } | ||
813 | |||
814 | netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY"); | ||
815 | |||
816 | ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); | ||
817 | check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); | ||
818 | |||
819 | buf |= PMT_CTL_PHY_RST; | ||
820 | |||
821 | ret = smsc75xx_write_reg(dev, PMT_CTL, buf); | ||
822 | check_warn_return(ret, "Failed to write PMT_CTL: %d", ret); | ||
823 | |||
824 | timeout = 0; | ||
825 | do { | ||
826 | msleep(10); | ||
827 | ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); | ||
828 | check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); | ||
829 | timeout++; | ||
830 | } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100)); | ||
831 | |||
832 | if (timeout >= 100) { | ||
833 | netdev_warn(dev->net, "timeout waiting for PHY Reset"); | ||
834 | return -EIO; | ||
835 | } | ||
836 | |||
837 | netif_dbg(dev, ifup, dev->net, "PHY reset complete"); | ||
838 | |||
839 | smsc75xx_init_mac_address(dev); | ||
840 | |||
841 | ret = smsc75xx_set_mac_address(dev); | ||
842 | check_warn_return(ret, "Failed to set mac address"); | ||
843 | |||
844 | netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr); | ||
845 | |||
846 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); | ||
847 | check_warn_return(ret, "Failed to read HW_CFG: %d", ret); | ||
848 | |||
849 | netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf); | ||
850 | |||
851 | buf |= HW_CFG_BIR; | ||
852 | |||
853 | ret = smsc75xx_write_reg(dev, HW_CFG, buf); | ||
854 | check_warn_return(ret, "Failed to write HW_CFG: %d", ret); | ||
855 | |||
856 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); | ||
857 | check_warn_return(ret, "Failed to read HW_CFG: %d", ret); | ||
858 | |||
859 | netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after " | ||
860 | "writing HW_CFG_BIR: 0x%08x", buf); | ||
861 | |||
862 | if (!turbo_mode) { | ||
863 | buf = 0; | ||
864 | dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; | ||
865 | } else if (dev->udev->speed == USB_SPEED_HIGH) { | ||
866 | buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; | ||
867 | dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; | ||
868 | } else { | ||
869 | buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; | ||
870 | dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; | ||
871 | } | ||
872 | |||
873 | netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld", | ||
874 | (ulong)dev->rx_urb_size); | ||
875 | |||
876 | ret = smsc75xx_write_reg(dev, BURST_CAP, buf); | ||
877 | check_warn_return(ret, "Failed to write BURST_CAP: %d", ret); | ||
878 | |||
879 | ret = smsc75xx_read_reg(dev, BURST_CAP, &buf); | ||
880 | check_warn_return(ret, "Failed to read BURST_CAP: %d", ret); | ||
881 | |||
882 | netif_dbg(dev, ifup, dev->net, | ||
883 | "Read Value from BURST_CAP after writing: 0x%08x", buf); | ||
884 | |||
885 | ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); | ||
886 | check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret); | ||
887 | |||
888 | ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf); | ||
889 | check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret); | ||
890 | |||
891 | netif_dbg(dev, ifup, dev->net, | ||
892 | "Read Value from BULK_IN_DLY after writing: 0x%08x", buf); | ||
893 | |||
894 | if (turbo_mode) { | ||
895 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); | ||
896 | check_warn_return(ret, "Failed to read HW_CFG: %d", ret); | ||
897 | |||
898 | netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf); | ||
899 | |||
900 | buf |= (HW_CFG_MEF | HW_CFG_BCE); | ||
901 | |||
902 | ret = smsc75xx_write_reg(dev, HW_CFG, buf); | ||
903 | check_warn_return(ret, "Failed to write HW_CFG: %d", ret); | ||
904 | |||
905 | ret = smsc75xx_read_reg(dev, HW_CFG, &buf); | ||
906 | check_warn_return(ret, "Failed to read HW_CFG: %d", ret); | ||
907 | |||
908 | netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf); | ||
909 | } | ||
910 | |||
911 | /* set FIFO sizes */ | ||
912 | buf = (MAX_RX_FIFO_SIZE - 512) / 512; | ||
913 | ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf); | ||
914 | check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret); | ||
915 | |||
916 | netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf); | ||
917 | |||
918 | buf = (MAX_TX_FIFO_SIZE - 512) / 512; | ||
919 | ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf); | ||
920 | check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret); | ||
921 | |||
922 | netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf); | ||
923 | |||
924 | ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); | ||
925 | check_warn_return(ret, "Failed to write INT_STS: %d", ret); | ||
926 | |||
927 | ret = smsc75xx_read_reg(dev, ID_REV, &buf); | ||
928 | check_warn_return(ret, "Failed to read ID_REV: %d", ret); | ||
929 | |||
930 | netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf); | ||
931 | |||
932 | /* Configure GPIO pins as LED outputs */ | ||
933 | ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf); | ||
934 | check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret); | ||
935 | |||
936 | buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL); | ||
937 | buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL; | ||
938 | |||
939 | ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf); | ||
940 | check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret); | ||
941 | |||
942 | ret = smsc75xx_write_reg(dev, FLOW, 0); | ||
943 | check_warn_return(ret, "Failed to write FLOW: %d", ret); | ||
944 | |||
945 | ret = smsc75xx_write_reg(dev, FCT_FLOW, 0); | ||
946 | check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret); | ||
947 | |||
948 | /* Don't need rfe_ctl_lock during initialisation */ | ||
949 | ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); | ||
950 | check_warn_return(ret, "Failed to read RFE_CTL: %d", ret); | ||
951 | |||
952 | pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF; | ||
953 | |||
954 | ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); | ||
955 | check_warn_return(ret, "Failed to write RFE_CTL: %d", ret); | ||
956 | |||
957 | ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); | ||
958 | check_warn_return(ret, "Failed to read RFE_CTL: %d", ret); | ||
959 | |||
960 | netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl); | ||
961 | |||
962 | /* Enable or disable checksum offload engines */ | ||
963 | ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE); | ||
964 | ret = smsc75xx_set_rx_csum_offload(dev); | ||
965 | check_warn_return(ret, "Failed to set rx csum offload: %d", ret); | ||
966 | |||
967 | smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE); | ||
968 | |||
969 | smsc75xx_set_multicast(dev->net); | ||
970 | |||
971 | ret = smsc75xx_phy_initialize(dev); | ||
972 | check_warn_return(ret, "Failed to initialize PHY: %d", ret); | ||
973 | |||
974 | ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf); | ||
975 | check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret); | ||
976 | |||
977 | /* enable PHY interrupts */ | ||
978 | buf |= INT_ENP_PHY_INT; | ||
979 | |||
980 | ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf); | ||
981 | check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); | ||
982 | |||
983 | ret = smsc75xx_read_reg(dev, MAC_TX, &buf); | ||
984 | check_warn_return(ret, "Failed to read MAC_TX: %d", ret); | ||
985 | |||
986 | buf |= MAC_TX_TXEN; | ||
987 | |||
988 | ret = smsc75xx_write_reg(dev, MAC_TX, buf); | ||
989 | check_warn_return(ret, "Failed to write MAC_TX: %d", ret); | ||
990 | |||
991 | netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf); | ||
992 | |||
993 | ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf); | ||
994 | check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret); | ||
995 | |||
996 | buf |= FCT_TX_CTL_EN; | ||
997 | |||
998 | ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf); | ||
999 | check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret); | ||
1000 | |||
1001 | netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf); | ||
1002 | |||
1003 | ret = smsc75xx_set_rx_max_frame_length(dev, 1514); | ||
1004 | check_warn_return(ret, "Failed to set max rx frame length"); | ||
1005 | |||
1006 | ret = smsc75xx_read_reg(dev, MAC_RX, &buf); | ||
1007 | check_warn_return(ret, "Failed to read MAC_RX: %d", ret); | ||
1008 | |||
1009 | buf |= MAC_RX_RXEN; | ||
1010 | |||
1011 | ret = smsc75xx_write_reg(dev, MAC_RX, buf); | ||
1012 | check_warn_return(ret, "Failed to write MAC_RX: %d", ret); | ||
1013 | |||
1014 | netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf); | ||
1015 | |||
1016 | ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf); | ||
1017 | check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret); | ||
1018 | |||
1019 | buf |= FCT_RX_CTL_EN; | ||
1020 | |||
1021 | ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf); | ||
1022 | check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret); | ||
1023 | |||
1024 | netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf); | ||
1025 | |||
1026 | netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0"); | ||
1027 | return 0; | ||
1028 | } | ||
1029 | |||
1030 | static const struct net_device_ops smsc75xx_netdev_ops = { | ||
1031 | .ndo_open = usbnet_open, | ||
1032 | .ndo_stop = usbnet_stop, | ||
1033 | .ndo_start_xmit = usbnet_start_xmit, | ||
1034 | .ndo_tx_timeout = usbnet_tx_timeout, | ||
1035 | .ndo_change_mtu = smsc75xx_change_mtu, | ||
1036 | .ndo_set_mac_address = eth_mac_addr, | ||
1037 | .ndo_validate_addr = eth_validate_addr, | ||
1038 | .ndo_do_ioctl = smsc75xx_ioctl, | ||
1039 | .ndo_set_multicast_list = smsc75xx_set_multicast, | ||
1040 | }; | ||
1041 | |||
1042 | static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) | ||
1043 | { | ||
1044 | struct smsc75xx_priv *pdata = NULL; | ||
1045 | int ret; | ||
1046 | |||
1047 | printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); | ||
1048 | |||
1049 | ret = usbnet_get_endpoints(dev, intf); | ||
1050 | check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret); | ||
1051 | |||
1052 | dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv), | ||
1053 | GFP_KERNEL); | ||
1054 | |||
1055 | pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
1056 | if (!pdata) { | ||
1057 | netdev_warn(dev->net, "Unable to allocate smsc75xx_priv"); | ||
1058 | return -ENOMEM; | ||
1059 | } | ||
1060 | |||
1061 | pdata->dev = dev; | ||
1062 | |||
1063 | spin_lock_init(&pdata->rfe_ctl_lock); | ||
1064 | mutex_init(&pdata->dataport_mutex); | ||
1065 | |||
1066 | INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); | ||
1067 | |||
1068 | pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE; | ||
1069 | |||
1070 | /* We have to advertise SG otherwise TSO cannot be enabled */ | ||
1071 | dev->net->features |= NETIF_F_SG; | ||
1072 | |||
1073 | /* Init all registers */ | ||
1074 | ret = smsc75xx_reset(dev); | ||
1075 | |||
1076 | dev->net->netdev_ops = &smsc75xx_netdev_ops; | ||
1077 | dev->net->ethtool_ops = &smsc75xx_ethtool_ops; | ||
1078 | dev->net->flags |= IFF_MULTICAST; | ||
1079 | dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; | ||
1080 | return 0; | ||
1081 | } | ||
1082 | |||
1083 | static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) | ||
1084 | { | ||
1085 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
1086 | if (pdata) { | ||
1087 | netif_dbg(dev, ifdown, dev->net, "free pdata"); | ||
1088 | kfree(pdata); | ||
1089 | pdata = NULL; | ||
1090 | dev->data[0] = 0; | ||
1091 | } | ||
1092 | } | ||
1093 | |||
1094 | static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a, | ||
1095 | u32 rx_cmd_b) | ||
1096 | { | ||
1097 | if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) { | ||
1098 | skb->ip_summed = CHECKSUM_NONE; | ||
1099 | } else { | ||
1100 | skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT)); | ||
1101 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
1106 | { | ||
1107 | struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); | ||
1108 | |||
1109 | while (skb->len > 0) { | ||
1110 | u32 rx_cmd_a, rx_cmd_b, align_count, size; | ||
1111 | struct sk_buff *ax_skb; | ||
1112 | unsigned char *packet; | ||
1113 | |||
1114 | memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a)); | ||
1115 | le32_to_cpus(&rx_cmd_a); | ||
1116 | skb_pull(skb, 4); | ||
1117 | |||
1118 | memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b)); | ||
1119 | le32_to_cpus(&rx_cmd_b); | ||
1120 | skb_pull(skb, 4 + NET_IP_ALIGN); | ||
1121 | |||
1122 | packet = skb->data; | ||
1123 | |||
1124 | /* get the packet length */ | ||
1125 | size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN; | ||
1126 | align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; | ||
1127 | |||
1128 | if (unlikely(rx_cmd_a & RX_CMD_A_RED)) { | ||
1129 | netif_dbg(dev, rx_err, dev->net, | ||
1130 | "Error rx_cmd_a=0x%08x", rx_cmd_a); | ||
1131 | dev->net->stats.rx_errors++; | ||
1132 | dev->net->stats.rx_dropped++; | ||
1133 | |||
1134 | if (rx_cmd_a & RX_CMD_A_FCS) | ||
1135 | dev->net->stats.rx_crc_errors++; | ||
1136 | else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) | ||
1137 | dev->net->stats.rx_frame_errors++; | ||
1138 | } else { | ||
1139 | /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ | ||
1140 | if (unlikely(size > (ETH_FRAME_LEN + 12))) { | ||
1141 | netif_dbg(dev, rx_err, dev->net, | ||
1142 | "size err rx_cmd_a=0x%08x", rx_cmd_a); | ||
1143 | return 0; | ||
1144 | } | ||
1145 | |||
1146 | /* last frame in this batch */ | ||
1147 | if (skb->len == size) { | ||
1148 | if (pdata->use_rx_csum) | ||
1149 | smsc75xx_rx_csum_offload(skb, rx_cmd_a, | ||
1150 | rx_cmd_b); | ||
1151 | else | ||
1152 | skb->ip_summed = CHECKSUM_NONE; | ||
1153 | |||
1154 | skb_trim(skb, skb->len - 4); /* remove fcs */ | ||
1155 | skb->truesize = size + sizeof(struct sk_buff); | ||
1156 | |||
1157 | return 1; | ||
1158 | } | ||
1159 | |||
1160 | ax_skb = skb_clone(skb, GFP_ATOMIC); | ||
1161 | if (unlikely(!ax_skb)) { | ||
1162 | netdev_warn(dev->net, "Error allocating skb"); | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | ax_skb->len = size; | ||
1167 | ax_skb->data = packet; | ||
1168 | skb_set_tail_pointer(ax_skb, size); | ||
1169 | |||
1170 | if (pdata->use_rx_csum) | ||
1171 | smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a, | ||
1172 | rx_cmd_b); | ||
1173 | else | ||
1174 | ax_skb->ip_summed = CHECKSUM_NONE; | ||
1175 | |||
1176 | skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ | ||
1177 | ax_skb->truesize = size + sizeof(struct sk_buff); | ||
1178 | |||
1179 | usbnet_skb_return(dev, ax_skb); | ||
1180 | } | ||
1181 | |||
1182 | skb_pull(skb, size); | ||
1183 | |||
1184 | /* padding bytes before the next frame starts */ | ||
1185 | if (skb->len) | ||
1186 | skb_pull(skb, align_count); | ||
1187 | } | ||
1188 | |||
1189 | if (unlikely(skb->len < 0)) { | ||
1190 | netdev_warn(dev->net, "invalid rx length<0 %d", skb->len); | ||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1194 | return 1; | ||
1195 | } | ||
1196 | |||
1197 | static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev, | ||
1198 | struct sk_buff *skb, gfp_t flags) | ||
1199 | { | ||
1200 | u32 tx_cmd_a, tx_cmd_b; | ||
1201 | |||
1202 | skb_linearize(skb); | ||
1203 | |||
1204 | if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) { | ||
1205 | struct sk_buff *skb2 = | ||
1206 | skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags); | ||
1207 | dev_kfree_skb_any(skb); | ||
1208 | skb = skb2; | ||
1209 | if (!skb) | ||
1210 | return NULL; | ||
1211 | } | ||
1212 | |||
1213 | tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS; | ||
1214 | |||
1215 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
1216 | tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE; | ||
1217 | |||
1218 | if (skb_is_gso(skb)) { | ||
1219 | u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN); | ||
1220 | tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS; | ||
1221 | |||
1222 | tx_cmd_a |= TX_CMD_A_LSO; | ||
1223 | } else { | ||
1224 | tx_cmd_b = 0; | ||
1225 | } | ||
1226 | |||
1227 | skb_push(skb, 4); | ||
1228 | cpu_to_le32s(&tx_cmd_b); | ||
1229 | memcpy(skb->data, &tx_cmd_b, 4); | ||
1230 | |||
1231 | skb_push(skb, 4); | ||
1232 | cpu_to_le32s(&tx_cmd_a); | ||
1233 | memcpy(skb->data, &tx_cmd_a, 4); | ||
1234 | |||
1235 | return skb; | ||
1236 | } | ||
1237 | |||
1238 | static const struct driver_info smsc75xx_info = { | ||
1239 | .description = "smsc75xx USB 2.0 Gigabit Ethernet", | ||
1240 | .bind = smsc75xx_bind, | ||
1241 | .unbind = smsc75xx_unbind, | ||
1242 | .link_reset = smsc75xx_link_reset, | ||
1243 | .reset = smsc75xx_reset, | ||
1244 | .rx_fixup = smsc75xx_rx_fixup, | ||
1245 | .tx_fixup = smsc75xx_tx_fixup, | ||
1246 | .status = smsc75xx_status, | ||
1247 | .flags = FLAG_ETHER | FLAG_SEND_ZLP, | ||
1248 | }; | ||
1249 | |||
1250 | static const struct usb_device_id products[] = { | ||
1251 | { | ||
1252 | /* SMSC7500 USB Gigabit Ethernet Device */ | ||
1253 | USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500), | ||
1254 | .driver_info = (unsigned long) &smsc75xx_info, | ||
1255 | }, | ||
1256 | { | ||
1257 | /* SMSC7500 USB Gigabit Ethernet Device */ | ||
1258 | USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505), | ||
1259 | .driver_info = (unsigned long) &smsc75xx_info, | ||
1260 | }, | ||
1261 | { }, /* END */ | ||
1262 | }; | ||
1263 | MODULE_DEVICE_TABLE(usb, products); | ||
1264 | |||
1265 | static struct usb_driver smsc75xx_driver = { | ||
1266 | .name = SMSC_CHIPNAME, | ||
1267 | .id_table = products, | ||
1268 | .probe = usbnet_probe, | ||
1269 | .suspend = usbnet_suspend, | ||
1270 | .resume = usbnet_resume, | ||
1271 | .disconnect = usbnet_disconnect, | ||
1272 | }; | ||
1273 | |||
1274 | static int __init smsc75xx_init(void) | ||
1275 | { | ||
1276 | return usb_register(&smsc75xx_driver); | ||
1277 | } | ||
1278 | module_init(smsc75xx_init); | ||
1279 | |||
1280 | static void __exit smsc75xx_exit(void) | ||
1281 | { | ||
1282 | usb_deregister(&smsc75xx_driver); | ||
1283 | } | ||
1284 | module_exit(smsc75xx_exit); | ||
1285 | |||
1286 | MODULE_AUTHOR("Nancy Lin"); | ||
1287 | MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>"); | ||
1288 | MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices"); | ||
1289 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/smsc75xx.h b/drivers/net/usb/smsc75xx.h new file mode 100644 index 000000000000..16e98c778344 --- /dev/null +++ b/drivers/net/usb/smsc75xx.h | |||
@@ -0,0 +1,421 @@ | |||
1 | /*************************************************************************** | ||
2 | * | ||
3 | * Copyright (C) 2007-2010 SMSC | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | * | ||
19 | *****************************************************************************/ | ||
20 | |||
21 | #ifndef _SMSC75XX_H | ||
22 | #define _SMSC75XX_H | ||
23 | |||
24 | /* Tx command words */ | ||
25 | #define TX_CMD_A_LSO (0x08000000) | ||
26 | #define TX_CMD_A_IPE (0x04000000) | ||
27 | #define TX_CMD_A_TPE (0x02000000) | ||
28 | #define TX_CMD_A_IVTG (0x01000000) | ||
29 | #define TX_CMD_A_RVTG (0x00800000) | ||
30 | #define TX_CMD_A_FCS (0x00400000) | ||
31 | #define TX_CMD_A_LEN (0x000FFFFF) | ||
32 | |||
33 | #define TX_CMD_B_MSS (0x3FFF0000) | ||
34 | #define TX_CMD_B_MSS_SHIFT (16) | ||
35 | #define TX_MSS_MIN ((u16)8) | ||
36 | #define TX_CMD_B_VTAG (0x0000FFFF) | ||
37 | |||
38 | /* Rx command words */ | ||
39 | #define RX_CMD_A_ICE (0x80000000) | ||
40 | #define RX_CMD_A_TCE (0x40000000) | ||
41 | #define RX_CMD_A_IPV (0x20000000) | ||
42 | #define RX_CMD_A_PID (0x18000000) | ||
43 | #define RX_CMD_A_PID_NIP (0x00000000) | ||
44 | #define RX_CMD_A_PID_TCP (0x08000000) | ||
45 | #define RX_CMD_A_PID_UDP (0x10000000) | ||
46 | #define RX_CMD_A_PID_PP (0x18000000) | ||
47 | #define RX_CMD_A_PFF (0x04000000) | ||
48 | #define RX_CMD_A_BAM (0x02000000) | ||
49 | #define RX_CMD_A_MAM (0x01000000) | ||
50 | #define RX_CMD_A_FVTG (0x00800000) | ||
51 | #define RX_CMD_A_RED (0x00400000) | ||
52 | #define RX_CMD_A_RWT (0x00200000) | ||
53 | #define RX_CMD_A_RUNT (0x00100000) | ||
54 | #define RX_CMD_A_LONG (0x00080000) | ||
55 | #define RX_CMD_A_RXE (0x00040000) | ||
56 | #define RX_CMD_A_DRB (0x00020000) | ||
57 | #define RX_CMD_A_FCS (0x00010000) | ||
58 | #define RX_CMD_A_UAM (0x00008000) | ||
59 | #define RX_CMD_A_LCSM (0x00004000) | ||
60 | #define RX_CMD_A_LEN (0x00003FFF) | ||
61 | |||
62 | #define RX_CMD_B_CSUM (0xFFFF0000) | ||
63 | #define RX_CMD_B_CSUM_SHIFT (16) | ||
64 | #define RX_CMD_B_VTAG (0x0000FFFF) | ||
65 | |||
66 | /* SCSRs */ | ||
67 | #define ID_REV (0x0000) | ||
68 | |||
69 | #define FPGA_REV (0x0004) | ||
70 | |||
71 | #define BOND_CTL (0x0008) | ||
72 | |||
73 | #define INT_STS (0x000C) | ||
74 | #define INT_STS_RDFO_INT (0x00400000) | ||
75 | #define INT_STS_TXE_INT (0x00200000) | ||
76 | #define INT_STS_MACRTO_INT (0x00100000) | ||
77 | #define INT_STS_TX_DIS_INT (0x00080000) | ||
78 | #define INT_STS_RX_DIS_INT (0x00040000) | ||
79 | #define INT_STS_PHY_INT_ (0x00020000) | ||
80 | #define INT_STS_MAC_ERR_INT (0x00008000) | ||
81 | #define INT_STS_TDFU (0x00004000) | ||
82 | #define INT_STS_TDFO (0x00002000) | ||
83 | #define INT_STS_GPIOS (0x00000FFF) | ||
84 | #define INT_STS_CLEAR_ALL (0xFFFFFFFF) | ||
85 | |||
86 | #define HW_CFG (0x0010) | ||
87 | #define HW_CFG_SMDET_STS (0x00008000) | ||
88 | #define HW_CFG_SMDET_EN (0x00004000) | ||
89 | #define HW_CFG_EEM (0x00002000) | ||
90 | #define HW_CFG_RST_PROTECT (0x00001000) | ||
91 | #define HW_CFG_PORT_SWAP (0x00000800) | ||
92 | #define HW_CFG_PHY_BOOST (0x00000600) | ||
93 | #define HW_CFG_PHY_BOOST_NORMAL (0x00000000) | ||
94 | #define HW_CFG_PHY_BOOST_4 (0x00002000) | ||
95 | #define HW_CFG_PHY_BOOST_8 (0x00004000) | ||
96 | #define HW_CFG_PHY_BOOST_12 (0x00006000) | ||
97 | #define HW_CFG_LEDB (0x00000100) | ||
98 | #define HW_CFG_BIR (0x00000080) | ||
99 | #define HW_CFG_SBP (0x00000040) | ||
100 | #define HW_CFG_IME (0x00000020) | ||
101 | #define HW_CFG_MEF (0x00000010) | ||
102 | #define HW_CFG_ETC (0x00000008) | ||
103 | #define HW_CFG_BCE (0x00000004) | ||
104 | #define HW_CFG_LRST (0x00000002) | ||
105 | #define HW_CFG_SRST (0x00000001) | ||
106 | |||
107 | #define PMT_CTL (0x0014) | ||
108 | #define PMT_CTL_PHY_PWRUP (0x00000400) | ||
109 | #define PMT_CTL_RES_CLR_WKP_EN (0x00000100) | ||
110 | #define PMT_CTL_DEV_RDY (0x00000080) | ||
111 | #define PMT_CTL_SUS_MODE (0x00000060) | ||
112 | #define PMT_CTL_SUS_MODE_0 (0x00000000) | ||
113 | #define PMT_CTL_SUS_MODE_1 (0x00000020) | ||
114 | #define PMT_CTL_SUS_MODE_2 (0x00000040) | ||
115 | #define PMT_CTL_SUS_MODE_3 (0x00000060) | ||
116 | #define PMT_CTL_PHY_RST (0x00000010) | ||
117 | #define PMT_CTL_WOL_EN (0x00000008) | ||
118 | #define PMT_CTL_ED_EN (0x00000004) | ||
119 | #define PMT_CTL_WUPS (0x00000003) | ||
120 | #define PMT_CTL_WUPS_NO (0x00000000) | ||
121 | #define PMT_CTL_WUPS_ED (0x00000001) | ||
122 | #define PMT_CTL_WUPS_WOL (0x00000002) | ||
123 | #define PMT_CTL_WUPS_MULTI (0x00000003) | ||
124 | |||
125 | #define LED_GPIO_CFG (0x0018) | ||
126 | #define LED_GPIO_CFG_LED2_FUN_SEL (0x80000000) | ||
127 | #define LED_GPIO_CFG_LED10_FUN_SEL (0x40000000) | ||
128 | #define LED_GPIO_CFG_LEDGPIO_EN (0x0000F000) | ||
129 | #define LED_GPIO_CFG_LEDGPIO_EN_0 (0x00001000) | ||
130 | #define LED_GPIO_CFG_LEDGPIO_EN_1 (0x00002000) | ||
131 | #define LED_GPIO_CFG_LEDGPIO_EN_2 (0x00004000) | ||
132 | #define LED_GPIO_CFG_LEDGPIO_EN_3 (0x00008000) | ||
133 | #define LED_GPIO_CFG_GPBUF (0x00000F00) | ||
134 | #define LED_GPIO_CFG_GPBUF_0 (0x00000100) | ||
135 | #define LED_GPIO_CFG_GPBUF_1 (0x00000200) | ||
136 | #define LED_GPIO_CFG_GPBUF_2 (0x00000400) | ||
137 | #define LED_GPIO_CFG_GPBUF_3 (0x00000800) | ||
138 | #define LED_GPIO_CFG_GPDIR (0x000000F0) | ||
139 | #define LED_GPIO_CFG_GPDIR_0 (0x00000010) | ||
140 | #define LED_GPIO_CFG_GPDIR_1 (0x00000020) | ||
141 | #define LED_GPIO_CFG_GPDIR_2 (0x00000040) | ||
142 | #define LED_GPIO_CFG_GPDIR_3 (0x00000080) | ||
143 | #define LED_GPIO_CFG_GPDATA (0x0000000F) | ||
144 | #define LED_GPIO_CFG_GPDATA_0 (0x00000001) | ||
145 | #define LED_GPIO_CFG_GPDATA_1 (0x00000002) | ||
146 | #define LED_GPIO_CFG_GPDATA_2 (0x00000004) | ||
147 | #define LED_GPIO_CFG_GPDATA_3 (0x00000008) | ||
148 | |||
149 | #define GPIO_CFG (0x001C) | ||
150 | #define GPIO_CFG_SHIFT (24) | ||
151 | #define GPIO_CFG_GPEN (0xFF000000) | ||
152 | #define GPIO_CFG_GPBUF (0x00FF0000) | ||
153 | #define GPIO_CFG_GPDIR (0x0000FF00) | ||
154 | #define GPIO_CFG_GPDATA (0x000000FF) | ||
155 | |||
156 | #define GPIO_WAKE (0x0020) | ||
157 | #define GPIO_WAKE_PHY_LINKUP_EN (0x80000000) | ||
158 | #define GPIO_WAKE_POL (0x0FFF0000) | ||
159 | #define GPIO_WAKE_POL_SHIFT (16) | ||
160 | #define GPIO_WAKE_WK (0x00000FFF) | ||
161 | |||
162 | #define DP_SEL (0x0024) | ||
163 | #define DP_SEL_DPRDY (0x80000000) | ||
164 | #define DP_SEL_RSEL (0x0000000F) | ||
165 | #define DP_SEL_URX (0x00000000) | ||
166 | #define DP_SEL_VHF (0x00000001) | ||
167 | #define DP_SEL_VHF_HASH_LEN (16) | ||
168 | #define DP_SEL_VHF_VLAN_LEN (128) | ||
169 | #define DP_SEL_LSO_HEAD (0x00000002) | ||
170 | #define DP_SEL_FCT_RX (0x00000003) | ||
171 | #define DP_SEL_FCT_TX (0x00000004) | ||
172 | #define DP_SEL_DESCRIPTOR (0x00000005) | ||
173 | #define DP_SEL_WOL (0x00000006) | ||
174 | |||
175 | #define DP_CMD (0x0028) | ||
176 | #define DP_CMD_WRITE (0x01) | ||
177 | #define DP_CMD_READ (0x00) | ||
178 | |||
179 | #define DP_ADDR (0x002C) | ||
180 | |||
181 | #define DP_DATA (0x0030) | ||
182 | |||
183 | #define BURST_CAP (0x0034) | ||
184 | #define BURST_CAP_MASK (0x0000000F) | ||
185 | |||
186 | #define INT_EP_CTL (0x0038) | ||
187 | #define INT_EP_CTL_INTEP_ON (0x80000000) | ||
188 | #define INT_EP_CTL_RDFO_EN (0x00400000) | ||
189 | #define INT_EP_CTL_TXE_EN (0x00200000) | ||
190 | #define INT_EP_CTL_MACROTO_EN (0x00100000) | ||
191 | #define INT_EP_CTL_TX_DIS_EN (0x00080000) | ||
192 | #define INT_EP_CTL_RX_DIS_EN (0x00040000) | ||
193 | #define INT_EP_CTL_PHY_EN_ (0x00020000) | ||
194 | #define INT_EP_CTL_MAC_ERR_EN (0x00008000) | ||
195 | #define INT_EP_CTL_TDFU_EN (0x00004000) | ||
196 | #define INT_EP_CTL_TDFO_EN (0x00002000) | ||
197 | #define INT_EP_CTL_RX_FIFO_EN (0x00001000) | ||
198 | #define INT_EP_CTL_GPIOX_EN (0x00000FFF) | ||
199 | |||
200 | #define BULK_IN_DLY (0x003C) | ||
201 | #define BULK_IN_DLY_MASK (0xFFFF) | ||
202 | |||
203 | #define E2P_CMD (0x0040) | ||
204 | #define E2P_CMD_BUSY (0x80000000) | ||
205 | #define E2P_CMD_MASK (0x70000000) | ||
206 | #define E2P_CMD_READ (0x00000000) | ||
207 | #define E2P_CMD_EWDS (0x10000000) | ||
208 | #define E2P_CMD_EWEN (0x20000000) | ||
209 | #define E2P_CMD_WRITE (0x30000000) | ||
210 | #define E2P_CMD_WRAL (0x40000000) | ||
211 | #define E2P_CMD_ERASE (0x50000000) | ||
212 | #define E2P_CMD_ERAL (0x60000000) | ||
213 | #define E2P_CMD_RELOAD (0x70000000) | ||
214 | #define E2P_CMD_TIMEOUT (0x00000400) | ||
215 | #define E2P_CMD_LOADED (0x00000200) | ||
216 | #define E2P_CMD_ADDR (0x000001FF) | ||
217 | |||
218 | #define MAX_EEPROM_SIZE (512) | ||
219 | |||
220 | #define E2P_DATA (0x0044) | ||
221 | #define E2P_DATA_MASK_ (0x000000FF) | ||
222 | |||
223 | #define RFE_CTL (0x0060) | ||
224 | #define RFE_CTL_TCPUDP_CKM (0x00001000) | ||
225 | #define RFE_CTL_IP_CKM (0x00000800) | ||
226 | #define RFE_CTL_AB (0x00000400) | ||
227 | #define RFE_CTL_AM (0x00000200) | ||
228 | #define RFE_CTL_AU (0x00000100) | ||
229 | #define RFE_CTL_VS (0x00000080) | ||
230 | #define RFE_CTL_UF (0x00000040) | ||
231 | #define RFE_CTL_VF (0x00000020) | ||
232 | #define RFE_CTL_SPF (0x00000010) | ||
233 | #define RFE_CTL_MHF (0x00000008) | ||
234 | #define RFE_CTL_DHF (0x00000004) | ||
235 | #define RFE_CTL_DPF (0x00000002) | ||
236 | #define RFE_CTL_RST_RF (0x00000001) | ||
237 | |||
238 | #define VLAN_TYPE (0x0064) | ||
239 | #define VLAN_TYPE_MASK (0x0000FFFF) | ||
240 | |||
241 | #define FCT_RX_CTL (0x0090) | ||
242 | #define FCT_RX_CTL_EN (0x80000000) | ||
243 | #define FCT_RX_CTL_RST (0x40000000) | ||
244 | #define FCT_RX_CTL_SBF (0x02000000) | ||
245 | #define FCT_RX_CTL_OVERFLOW (0x01000000) | ||
246 | #define FCT_RX_CTL_FRM_DROP (0x00800000) | ||
247 | #define FCT_RX_CTL_RX_NOT_EMPTY (0x00400000) | ||
248 | #define FCT_RX_CTL_RX_EMPTY (0x00200000) | ||
249 | #define FCT_RX_CTL_RX_DISABLED (0x00100000) | ||
250 | #define FCT_RX_CTL_RXUSED (0x0000FFFF) | ||
251 | |||
252 | #define FCT_TX_CTL (0x0094) | ||
253 | #define FCT_TX_CTL_EN (0x80000000) | ||
254 | #define FCT_TX_CTL_RST (0x40000000) | ||
255 | #define FCT_TX_CTL_TX_NOT_EMPTY (0x00400000) | ||
256 | #define FCT_TX_CTL_TX_EMPTY (0x00200000) | ||
257 | #define FCT_TX_CTL_TX_DISABLED (0x00100000) | ||
258 | #define FCT_TX_CTL_TXUSED (0x0000FFFF) | ||
259 | |||
260 | #define FCT_RX_FIFO_END (0x0098) | ||
261 | #define FCT_RX_FIFO_END_MASK (0x0000007F) | ||
262 | |||
263 | #define FCT_TX_FIFO_END (0x009C) | ||
264 | #define FCT_TX_FIFO_END_MASK (0x0000003F) | ||
265 | |||
266 | #define FCT_FLOW (0x00A0) | ||
267 | #define FCT_FLOW_THRESHOLD_OFF (0x00007F00) | ||
268 | #define FCT_FLOW_THRESHOLD_OFF_SHIFT (8) | ||
269 | #define FCT_FLOW_THRESHOLD_ON (0x0000007F) | ||
270 | |||
271 | /* MAC CSRs */ | ||
272 | #define MAC_CR (0x100) | ||
273 | #define MAC_CR_ADP (0x00002000) | ||
274 | #define MAC_CR_ADD (0x00001000) | ||
275 | #define MAC_CR_ASD (0x00000800) | ||
276 | #define MAC_CR_INT_LOOP (0x00000400) | ||
277 | #define MAC_CR_BOLMT (0x000000C0) | ||
278 | #define MAC_CR_FDPX (0x00000008) | ||
279 | #define MAC_CR_CFG (0x00000006) | ||
280 | #define MAC_CR_CFG_10 (0x00000000) | ||
281 | #define MAC_CR_CFG_100 (0x00000002) | ||
282 | #define MAC_CR_CFG_1000 (0x00000004) | ||
283 | #define MAC_CR_RST (0x00000001) | ||
284 | |||
285 | #define MAC_RX (0x104) | ||
286 | #define MAC_RX_MAX_SIZE (0x3FFF0000) | ||
287 | #define MAC_RX_MAX_SIZE_SHIFT (16) | ||
288 | #define MAC_RX_FCS_STRIP (0x00000010) | ||
289 | #define MAC_RX_FSE (0x00000004) | ||
290 | #define MAC_RX_RXD (0x00000002) | ||
291 | #define MAC_RX_RXEN (0x00000001) | ||
292 | |||
293 | #define MAC_TX (0x108) | ||
294 | #define MAC_TX_BFCS (0x00000004) | ||
295 | #define MAC_TX_TXD (0x00000002) | ||
296 | #define MAC_TX_TXEN (0x00000001) | ||
297 | |||
298 | #define FLOW (0x10C) | ||
299 | #define FLOW_FORCE_FC (0x80000000) | ||
300 | #define FLOW_TX_FCEN (0x40000000) | ||
301 | #define FLOW_RX_FCEN (0x20000000) | ||
302 | #define FLOW_FPF (0x10000000) | ||
303 | #define FLOW_PAUSE_TIME (0x0000FFFF) | ||
304 | |||
305 | #define RAND_SEED (0x110) | ||
306 | #define RAND_SEED_MASK (0x0000FFFF) | ||
307 | |||
308 | #define ERR_STS (0x114) | ||
309 | #define ERR_STS_FCS_ERR (0x00000100) | ||
310 | #define ERR_STS_LFRM_ERR (0x00000080) | ||
311 | #define ERR_STS_RUNT_ERR (0x00000040) | ||
312 | #define ERR_STS_COLLISION_ERR (0x00000010) | ||
313 | #define ERR_STS_ALIGN_ERR (0x00000008) | ||
314 | #define ERR_STS_URUN_ERR (0x00000004) | ||
315 | |||
316 | #define RX_ADDRH (0x118) | ||
317 | #define RX_ADDRH_MASK (0x0000FFFF) | ||
318 | |||
319 | #define RX_ADDRL (0x11C) | ||
320 | |||
321 | #define MII_ACCESS (0x120) | ||
322 | #define MII_ACCESS_PHY_ADDR (0x0000F800) | ||
323 | #define MII_ACCESS_PHY_ADDR_SHIFT (11) | ||
324 | #define MII_ACCESS_REG_ADDR (0x000007C0) | ||
325 | #define MII_ACCESS_REG_ADDR_SHIFT (6) | ||
326 | #define MII_ACCESS_READ (0x00000000) | ||
327 | #define MII_ACCESS_WRITE (0x00000002) | ||
328 | #define MII_ACCESS_BUSY (0x00000001) | ||
329 | |||
330 | #define MII_DATA (0x124) | ||
331 | #define MII_DATA_MASK (0x0000FFFF) | ||
332 | |||
333 | #define WUCSR (0x140) | ||
334 | #define WUCSR_PFDA_FR (0x00000080) | ||
335 | #define WUCSR_WUFR (0x00000040) | ||
336 | #define WUCSR_MPR (0x00000020) | ||
337 | #define WUCSR_BCAST_FR (0x00000010) | ||
338 | #define WUCSR_PFDA_EN (0x00000008) | ||
339 | #define WUCSR_WUEN (0x00000004) | ||
340 | #define WUCSR_MPEN (0x00000002) | ||
341 | #define WUCSR_BCST_EN (0x00000001) | ||
342 | |||
343 | #define WUF_CFGX (0x144) | ||
344 | #define WUF_CFGX_EN (0x80000000) | ||
345 | #define WUF_CFGX_ATYPE (0x03000000) | ||
346 | #define WUF_CFGX_ATYPE_UNICAST (0x00000000) | ||
347 | #define WUF_CFGX_ATYPE_MULTICAST (0x02000000) | ||
348 | #define WUF_CFGX_ATYPE_ALL (0x03000000) | ||
349 | #define WUF_CFGX_PATTERN_OFFSET (0x007F0000) | ||
350 | #define WUF_CFGX_PATTERN_OFFSET_SHIFT (16) | ||
351 | #define WUF_CFGX_CRC16 (0x0000FFFF) | ||
352 | #define WUF_NUM (8) | ||
353 | |||
354 | #define WUF_MASKX (0x170) | ||
355 | #define WUF_MASKX_AVALID (0x80000000) | ||
356 | #define WUF_MASKX_ATYPE (0x40000000) | ||
357 | |||
358 | #define ADDR_FILTX (0x300) | ||
359 | #define ADDR_FILTX_FB_VALID (0x80000000) | ||
360 | #define ADDR_FILTX_FB_TYPE (0x40000000) | ||
361 | #define ADDR_FILTX_FB_ADDRHI (0x0000FFFF) | ||
362 | #define ADDR_FILTX_SB_ADDRLO (0xFFFFFFFF) | ||
363 | |||
364 | #define WUCSR2 (0x500) | ||
365 | #define WUCSR2_NS_RCD (0x00000040) | ||
366 | #define WUCSR2_ARP_RCD (0x00000020) | ||
367 | #define WUCSR2_TCPSYN_RCD (0x00000010) | ||
368 | #define WUCSR2_NS_OFFLOAD (0x00000004) | ||
369 | #define WUCSR2_ARP_OFFLOAD (0x00000002) | ||
370 | #define WUCSR2_TCPSYN_OFFLOAD (0x00000001) | ||
371 | |||
372 | #define WOL_FIFO_STS (0x504) | ||
373 | |||
374 | #define IPV6_ADDRX (0x510) | ||
375 | |||
376 | #define IPV4_ADDRX (0x590) | ||
377 | |||
378 | |||
379 | /* Vendor-specific PHY Definitions */ | ||
380 | |||
381 | /* Mode Control/Status Register */ | ||
382 | #define PHY_MODE_CTRL_STS (17) | ||
383 | #define MODE_CTRL_STS_EDPWRDOWN ((u16)0x2000) | ||
384 | #define MODE_CTRL_STS_ENERGYON ((u16)0x0002) | ||
385 | |||
386 | #define PHY_INT_SRC (29) | ||
387 | #define PHY_INT_SRC_ENERGY_ON ((u16)0x0080) | ||
388 | #define PHY_INT_SRC_ANEG_COMP ((u16)0x0040) | ||
389 | #define PHY_INT_SRC_REMOTE_FAULT ((u16)0x0020) | ||
390 | #define PHY_INT_SRC_LINK_DOWN ((u16)0x0010) | ||
391 | |||
392 | #define PHY_INT_MASK (30) | ||
393 | #define PHY_INT_MASK_ENERGY_ON ((u16)0x0080) | ||
394 | #define PHY_INT_MASK_ANEG_COMP ((u16)0x0040) | ||
395 | #define PHY_INT_MASK_REMOTE_FAULT ((u16)0x0020) | ||
396 | #define PHY_INT_MASK_LINK_DOWN ((u16)0x0010) | ||
397 | #define PHY_INT_MASK_DEFAULT (PHY_INT_MASK_ANEG_COMP | \ | ||
398 | PHY_INT_MASK_LINK_DOWN) | ||
399 | |||
400 | #define PHY_SPECIAL (31) | ||
401 | #define PHY_SPECIAL_SPD ((u16)0x001C) | ||
402 | #define PHY_SPECIAL_SPD_10HALF ((u16)0x0004) | ||
403 | #define PHY_SPECIAL_SPD_10FULL ((u16)0x0014) | ||
404 | #define PHY_SPECIAL_SPD_100HALF ((u16)0x0008) | ||
405 | #define PHY_SPECIAL_SPD_100FULL ((u16)0x0018) | ||
406 | |||
407 | /* USB Vendor Requests */ | ||
408 | #define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0 | ||
409 | #define USB_VENDOR_REQUEST_READ_REGISTER 0xA1 | ||
410 | #define USB_VENDOR_REQUEST_GET_STATS 0xA2 | ||
411 | |||
412 | /* Interrupt Endpoint status word bitfields */ | ||
413 | #define INT_ENP_RDFO_INT ((u32)BIT(22)) | ||
414 | #define INT_ENP_TXE_INT ((u32)BIT(21)) | ||
415 | #define INT_ENP_TX_DIS_INT ((u32)BIT(19)) | ||
416 | #define INT_ENP_RX_DIS_INT ((u32)BIT(18)) | ||
417 | #define INT_ENP_PHY_INT ((u32)BIT(17)) | ||
418 | #define INT_ENP_MAC_ERR_INT ((u32)BIT(15)) | ||
419 | #define INT_ENP_RX_FIFO_DATA_INT ((u32)BIT(12)) | ||
420 | |||
421 | #endif /* _SMSC75XX_H */ | ||
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index c6c922247d05..3135af63d378 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
29 | #include <linux/crc32.h> | 29 | #include <linux/crc32.h> |
30 | #include <linux/usb/usbnet.h> | 30 | #include <linux/usb/usbnet.h> |
31 | #include <linux/slab.h> | ||
31 | #include "smsc95xx.h" | 32 | #include "smsc95xx.h" |
32 | 33 | ||
33 | #define SMSC_CHIPNAME "smsc95xx" | 34 | #define SMSC_CHIPNAME "smsc95xx" |
@@ -78,7 +79,7 @@ static int smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data) | |||
78 | 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); | 79 | 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); |
79 | 80 | ||
80 | if (unlikely(ret < 0)) | 81 | if (unlikely(ret < 0)) |
81 | devwarn(dev, "Failed to read register index 0x%08x", index); | 82 | netdev_warn(dev->net, "Failed to read register index 0x%08x\n", index); |
82 | 83 | ||
83 | le32_to_cpus(buf); | 84 | le32_to_cpus(buf); |
84 | *data = *buf; | 85 | *data = *buf; |
@@ -106,7 +107,7 @@ static int smsc95xx_write_reg(struct usbnet *dev, u32 index, u32 data) | |||
106 | 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); | 107 | 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); |
107 | 108 | ||
108 | if (unlikely(ret < 0)) | 109 | if (unlikely(ret < 0)) |
109 | devwarn(dev, "Failed to write register index 0x%08x", index); | 110 | netdev_warn(dev->net, "Failed to write register index 0x%08x\n", index); |
110 | 111 | ||
111 | kfree(buf); | 112 | kfree(buf); |
112 | 113 | ||
@@ -138,7 +139,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) | |||
138 | 139 | ||
139 | /* confirm MII not busy */ | 140 | /* confirm MII not busy */ |
140 | if (smsc95xx_phy_wait_not_busy(dev)) { | 141 | if (smsc95xx_phy_wait_not_busy(dev)) { |
141 | devwarn(dev, "MII is busy in smsc95xx_mdio_read"); | 142 | netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_read\n"); |
142 | mutex_unlock(&dev->phy_mutex); | 143 | mutex_unlock(&dev->phy_mutex); |
143 | return -EIO; | 144 | return -EIO; |
144 | } | 145 | } |
@@ -150,7 +151,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) | |||
150 | smsc95xx_write_reg(dev, MII_ADDR, addr); | 151 | smsc95xx_write_reg(dev, MII_ADDR, addr); |
151 | 152 | ||
152 | if (smsc95xx_phy_wait_not_busy(dev)) { | 153 | if (smsc95xx_phy_wait_not_busy(dev)) { |
153 | devwarn(dev, "Timed out reading MII reg %02X", idx); | 154 | netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx); |
154 | mutex_unlock(&dev->phy_mutex); | 155 | mutex_unlock(&dev->phy_mutex); |
155 | return -EIO; | 156 | return -EIO; |
156 | } | 157 | } |
@@ -172,7 +173,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, | |||
172 | 173 | ||
173 | /* confirm MII not busy */ | 174 | /* confirm MII not busy */ |
174 | if (smsc95xx_phy_wait_not_busy(dev)) { | 175 | if (smsc95xx_phy_wait_not_busy(dev)) { |
175 | devwarn(dev, "MII is busy in smsc95xx_mdio_write"); | 176 | netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_write\n"); |
176 | mutex_unlock(&dev->phy_mutex); | 177 | mutex_unlock(&dev->phy_mutex); |
177 | return; | 178 | return; |
178 | } | 179 | } |
@@ -187,7 +188,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, | |||
187 | smsc95xx_write_reg(dev, MII_ADDR, addr); | 188 | smsc95xx_write_reg(dev, MII_ADDR, addr); |
188 | 189 | ||
189 | if (smsc95xx_phy_wait_not_busy(dev)) | 190 | if (smsc95xx_phy_wait_not_busy(dev)) |
190 | devwarn(dev, "Timed out writing MII reg %02X", idx); | 191 | netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx); |
191 | 192 | ||
192 | mutex_unlock(&dev->phy_mutex); | 193 | mutex_unlock(&dev->phy_mutex); |
193 | } | 194 | } |
@@ -205,7 +206,7 @@ static int smsc95xx_wait_eeprom(struct usbnet *dev) | |||
205 | } while (!time_after(jiffies, start_time + HZ)); | 206 | } while (!time_after(jiffies, start_time + HZ)); |
206 | 207 | ||
207 | if (val & (E2P_CMD_TIMEOUT_ | E2P_CMD_BUSY_)) { | 208 | if (val & (E2P_CMD_TIMEOUT_ | E2P_CMD_BUSY_)) { |
208 | devwarn(dev, "EEPROM read operation timeout"); | 209 | netdev_warn(dev->net, "EEPROM read operation timeout\n"); |
209 | return -EIO; | 210 | return -EIO; |
210 | } | 211 | } |
211 | 212 | ||
@@ -226,7 +227,7 @@ static int smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev) | |||
226 | udelay(40); | 227 | udelay(40); |
227 | } while (!time_after(jiffies, start_time + HZ)); | 228 | } while (!time_after(jiffies, start_time + HZ)); |
228 | 229 | ||
229 | devwarn(dev, "EEPROM is busy"); | 230 | netdev_warn(dev->net, "EEPROM is busy\n"); |
230 | return -EIO; | 231 | return -EIO; |
231 | } | 232 | } |
232 | 233 | ||
@@ -308,7 +309,7 @@ static void smsc95xx_async_cmd_callback(struct urb *urb) | |||
308 | int status = urb->status; | 309 | int status = urb->status; |
309 | 310 | ||
310 | if (status < 0) | 311 | if (status < 0) |
311 | devwarn(dev, "async callback failed with %d", status); | 312 | netdev_warn(dev->net, "async callback failed with %d\n", status); |
312 | 313 | ||
313 | kfree(usb_context); | 314 | kfree(usb_context); |
314 | usb_free_urb(urb); | 315 | usb_free_urb(urb); |
@@ -323,13 +324,13 @@ static int smsc95xx_write_reg_async(struct usbnet *dev, u16 index, u32 *data) | |||
323 | 324 | ||
324 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 325 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
325 | if (!urb) { | 326 | if (!urb) { |
326 | devwarn(dev, "Error allocating URB"); | 327 | netdev_warn(dev->net, "Error allocating URB\n"); |
327 | return -ENOMEM; | 328 | return -ENOMEM; |
328 | } | 329 | } |
329 | 330 | ||
330 | usb_context = kmalloc(sizeof(struct usb_context), GFP_ATOMIC); | 331 | usb_context = kmalloc(sizeof(struct usb_context), GFP_ATOMIC); |
331 | if (usb_context == NULL) { | 332 | if (usb_context == NULL) { |
332 | devwarn(dev, "Error allocating control msg"); | 333 | netdev_warn(dev->net, "Error allocating control msg\n"); |
333 | usb_free_urb(urb); | 334 | usb_free_urb(urb); |
334 | return -ENOMEM; | 335 | return -ENOMEM; |
335 | } | 336 | } |
@@ -348,7 +349,8 @@ static int smsc95xx_write_reg_async(struct usbnet *dev, u16 index, u32 *data) | |||
348 | 349 | ||
349 | status = usb_submit_urb(urb, GFP_ATOMIC); | 350 | status = usb_submit_urb(urb, GFP_ATOMIC); |
350 | if (status < 0) { | 351 | if (status < 0) { |
351 | devwarn(dev, "Error submitting control msg, sts=%d", status); | 352 | netdev_warn(dev->net, "Error submitting control msg, sts=%d\n", |
353 | status); | ||
352 | kfree(usb_context); | 354 | kfree(usb_context); |
353 | usb_free_urb(urb); | 355 | usb_free_urb(urb); |
354 | } | 356 | } |
@@ -375,46 +377,32 @@ static void smsc95xx_set_multicast(struct net_device *netdev) | |||
375 | spin_lock_irqsave(&pdata->mac_cr_lock, flags); | 377 | spin_lock_irqsave(&pdata->mac_cr_lock, flags); |
376 | 378 | ||
377 | if (dev->net->flags & IFF_PROMISC) { | 379 | if (dev->net->flags & IFF_PROMISC) { |
378 | if (netif_msg_drv(dev)) | 380 | netif_dbg(dev, drv, dev->net, "promiscuous mode enabled\n"); |
379 | devdbg(dev, "promiscuous mode enabled"); | ||
380 | pdata->mac_cr |= MAC_CR_PRMS_; | 381 | pdata->mac_cr |= MAC_CR_PRMS_; |
381 | pdata->mac_cr &= ~(MAC_CR_MCPAS_ | MAC_CR_HPFILT_); | 382 | pdata->mac_cr &= ~(MAC_CR_MCPAS_ | MAC_CR_HPFILT_); |
382 | } else if (dev->net->flags & IFF_ALLMULTI) { | 383 | } else if (dev->net->flags & IFF_ALLMULTI) { |
383 | if (netif_msg_drv(dev)) | 384 | netif_dbg(dev, drv, dev->net, "receive all multicast enabled\n"); |
384 | devdbg(dev, "receive all multicast enabled"); | ||
385 | pdata->mac_cr |= MAC_CR_MCPAS_; | 385 | pdata->mac_cr |= MAC_CR_MCPAS_; |
386 | pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_HPFILT_); | 386 | pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_HPFILT_); |
387 | } else if (dev->net->mc_count > 0) { | 387 | } else if (!netdev_mc_empty(dev->net)) { |
388 | struct dev_mc_list *mc_list = dev->net->mc_list; | 388 | struct dev_mc_list *mc_list; |
389 | int count = 0; | ||
390 | 389 | ||
391 | pdata->mac_cr |= MAC_CR_HPFILT_; | 390 | pdata->mac_cr |= MAC_CR_HPFILT_; |
392 | pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_); | 391 | pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_); |
393 | 392 | ||
394 | while (mc_list) { | 393 | netdev_for_each_mc_addr(mc_list, netdev) { |
395 | count++; | 394 | u32 bitnum = smsc95xx_hash(mc_list->dmi_addr); |
396 | if (mc_list->dmi_addrlen == ETH_ALEN) { | 395 | u32 mask = 0x01 << (bitnum & 0x1F); |
397 | u32 bitnum = smsc95xx_hash(mc_list->dmi_addr); | 396 | if (bitnum & 0x20) |
398 | u32 mask = 0x01 << (bitnum & 0x1F); | 397 | hash_hi |= mask; |
399 | if (bitnum & 0x20) | 398 | else |
400 | hash_hi |= mask; | 399 | hash_lo |= mask; |
401 | else | ||
402 | hash_lo |= mask; | ||
403 | } else { | ||
404 | devwarn(dev, "dmi_addrlen != 6"); | ||
405 | } | ||
406 | mc_list = mc_list->next; | ||
407 | } | 400 | } |
408 | 401 | ||
409 | if (count != ((u32)dev->net->mc_count)) | 402 | netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n", |
410 | devwarn(dev, "mc_count != dev->mc_count"); | 403 | hash_hi, hash_lo); |
411 | |||
412 | if (netif_msg_drv(dev)) | ||
413 | devdbg(dev, "HASHH=0x%08X, HASHL=0x%08X", hash_hi, | ||
414 | hash_lo); | ||
415 | } else { | 404 | } else { |
416 | if (netif_msg_drv(dev)) | 405 | netif_dbg(dev, drv, dev->net, "receive own packets only\n"); |
417 | devdbg(dev, "receive own packets only"); | ||
418 | pdata->mac_cr &= | 406 | pdata->mac_cr &= |
419 | ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); | 407 | ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); |
420 | } | 408 | } |
@@ -434,7 +422,7 @@ static void smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex, | |||
434 | 422 | ||
435 | int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg); | 423 | int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg); |
436 | if (ret < 0) { | 424 | if (ret < 0) { |
437 | devwarn(dev, "error reading AFC_CFG"); | 425 | netdev_warn(dev->net, "error reading AFC_CFG\n"); |
438 | return; | 426 | return; |
439 | } | 427 | } |
440 | 428 | ||
@@ -451,13 +439,11 @@ static void smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex, | |||
451 | else | 439 | else |
452 | afc_cfg &= ~0xF; | 440 | afc_cfg &= ~0xF; |
453 | 441 | ||
454 | if (netif_msg_link(dev)) | 442 | netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s\n", |
455 | devdbg(dev, "rx pause %s, tx pause %s", | 443 | cap & FLOW_CTRL_RX ? "enabled" : "disabled", |
456 | (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), | 444 | cap & FLOW_CTRL_TX ? "enabled" : "disabled"); |
457 | (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); | ||
458 | } else { | 445 | } else { |
459 | if (netif_msg_link(dev)) | 446 | netif_dbg(dev, link, dev->net, "half duplex\n"); |
460 | devdbg(dev, "half duplex"); | ||
461 | flow = 0; | 447 | flow = 0; |
462 | afc_cfg |= 0xF; | 448 | afc_cfg |= 0xF; |
463 | } | 449 | } |
@@ -485,9 +471,8 @@ static int smsc95xx_link_reset(struct usbnet *dev) | |||
485 | lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); | 471 | lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); |
486 | rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA); | 472 | rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA); |
487 | 473 | ||
488 | if (netif_msg_link(dev)) | 474 | netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x\n", |
489 | devdbg(dev, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x", | 475 | ecmd.speed, ecmd.duplex, lcladv, rmtadv); |
490 | ecmd.speed, ecmd.duplex, lcladv, rmtadv); | ||
491 | 476 | ||
492 | spin_lock_irqsave(&pdata->mac_cr_lock, flags); | 477 | spin_lock_irqsave(&pdata->mac_cr_lock, flags); |
493 | if (ecmd.duplex != DUPLEX_FULL) { | 478 | if (ecmd.duplex != DUPLEX_FULL) { |
@@ -511,20 +496,21 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb) | |||
511 | u32 intdata; | 496 | u32 intdata; |
512 | 497 | ||
513 | if (urb->actual_length != 4) { | 498 | if (urb->actual_length != 4) { |
514 | devwarn(dev, "unexpected urb length %d", urb->actual_length); | 499 | netdev_warn(dev->net, "unexpected urb length %d\n", |
500 | urb->actual_length); | ||
515 | return; | 501 | return; |
516 | } | 502 | } |
517 | 503 | ||
518 | memcpy(&intdata, urb->transfer_buffer, 4); | 504 | memcpy(&intdata, urb->transfer_buffer, 4); |
519 | le32_to_cpus(&intdata); | 505 | le32_to_cpus(&intdata); |
520 | 506 | ||
521 | if (netif_msg_link(dev)) | 507 | netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); |
522 | devdbg(dev, "intdata: 0x%08X", intdata); | ||
523 | 508 | ||
524 | if (intdata & INT_ENP_PHY_INT_) | 509 | if (intdata & INT_ENP_PHY_INT_) |
525 | usbnet_defer_kevent(dev, EVENT_LINK_RESET); | 510 | usbnet_defer_kevent(dev, EVENT_LINK_RESET); |
526 | else | 511 | else |
527 | devwarn(dev, "unexpected interrupt, intdata=0x%08X", intdata); | 512 | netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", |
513 | intdata); | ||
528 | } | 514 | } |
529 | 515 | ||
530 | /* Enable or disable Tx & Rx checksum offload engines */ | 516 | /* Enable or disable Tx & Rx checksum offload engines */ |
@@ -534,7 +520,7 @@ static int smsc95xx_set_csums(struct usbnet *dev) | |||
534 | u32 read_buf; | 520 | u32 read_buf; |
535 | int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf); | 521 | int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf); |
536 | if (ret < 0) { | 522 | if (ret < 0) { |
537 | devwarn(dev, "Failed to read COE_CR: %d", ret); | 523 | netdev_warn(dev->net, "Failed to read COE_CR: %d\n", ret); |
538 | return ret; | 524 | return ret; |
539 | } | 525 | } |
540 | 526 | ||
@@ -550,12 +536,11 @@ static int smsc95xx_set_csums(struct usbnet *dev) | |||
550 | 536 | ||
551 | ret = smsc95xx_write_reg(dev, COE_CR, read_buf); | 537 | ret = smsc95xx_write_reg(dev, COE_CR, read_buf); |
552 | if (ret < 0) { | 538 | if (ret < 0) { |
553 | devwarn(dev, "Failed to write COE_CR: %d", ret); | 539 | netdev_warn(dev->net, "Failed to write COE_CR: %d\n", ret); |
554 | return ret; | 540 | return ret; |
555 | } | 541 | } |
556 | 542 | ||
557 | if (netif_msg_hw(dev)) | 543 | netif_dbg(dev, hw, dev->net, "COE_CR = 0x%08x\n", read_buf); |
558 | devdbg(dev, "COE_CR = 0x%08x", read_buf); | ||
559 | return 0; | 544 | return 0; |
560 | } | 545 | } |
561 | 546 | ||
@@ -580,8 +565,8 @@ static int smsc95xx_ethtool_set_eeprom(struct net_device *netdev, | |||
580 | struct usbnet *dev = netdev_priv(netdev); | 565 | struct usbnet *dev = netdev_priv(netdev); |
581 | 566 | ||
582 | if (ee->magic != LAN95XX_EEPROM_MAGIC) { | 567 | if (ee->magic != LAN95XX_EEPROM_MAGIC) { |
583 | devwarn(dev, "EEPROM: magic value mismatch, magic = 0x%x", | 568 | netdev_warn(dev->net, "EEPROM: magic value mismatch, magic = 0x%x\n", |
584 | ee->magic); | 569 | ee->magic); |
585 | return -EINVAL; | 570 | return -EINVAL; |
586 | } | 571 | } |
587 | 572 | ||
@@ -659,16 +644,14 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) | |||
659 | dev->net->dev_addr) == 0) { | 644 | dev->net->dev_addr) == 0) { |
660 | if (is_valid_ether_addr(dev->net->dev_addr)) { | 645 | if (is_valid_ether_addr(dev->net->dev_addr)) { |
661 | /* eeprom values are valid so use them */ | 646 | /* eeprom values are valid so use them */ |
662 | if (netif_msg_ifup(dev)) | 647 | netif_dbg(dev, ifup, dev->net, "MAC address read from EEPROM\n"); |
663 | devdbg(dev, "MAC address read from EEPROM"); | ||
664 | return; | 648 | return; |
665 | } | 649 | } |
666 | } | 650 | } |
667 | 651 | ||
668 | /* no eeprom, or eeprom values are invalid. generate random MAC */ | 652 | /* no eeprom, or eeprom values are invalid. generate random MAC */ |
669 | random_ether_addr(dev->net->dev_addr); | 653 | random_ether_addr(dev->net->dev_addr); |
670 | if (netif_msg_ifup(dev)) | 654 | netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr\n"); |
671 | devdbg(dev, "MAC address set to random_ether_addr"); | ||
672 | } | 655 | } |
673 | 656 | ||
674 | static int smsc95xx_set_mac_address(struct usbnet *dev) | 657 | static int smsc95xx_set_mac_address(struct usbnet *dev) |
@@ -680,13 +663,13 @@ static int smsc95xx_set_mac_address(struct usbnet *dev) | |||
680 | 663 | ||
681 | ret = smsc95xx_write_reg(dev, ADDRL, addr_lo); | 664 | ret = smsc95xx_write_reg(dev, ADDRL, addr_lo); |
682 | if (ret < 0) { | 665 | if (ret < 0) { |
683 | devwarn(dev, "Failed to write ADDRL: %d", ret); | 666 | netdev_warn(dev->net, "Failed to write ADDRL: %d\n", ret); |
684 | return ret; | 667 | return ret; |
685 | } | 668 | } |
686 | 669 | ||
687 | ret = smsc95xx_write_reg(dev, ADDRH, addr_hi); | 670 | ret = smsc95xx_write_reg(dev, ADDRH, addr_hi); |
688 | if (ret < 0) { | 671 | if (ret < 0) { |
689 | devwarn(dev, "Failed to write ADDRH: %d", ret); | 672 | netdev_warn(dev->net, "Failed to write ADDRH: %d\n", ret); |
690 | return ret; | 673 | return ret; |
691 | } | 674 | } |
692 | 675 | ||
@@ -727,6 +710,8 @@ static void smsc95xx_start_rx_path(struct usbnet *dev) | |||
727 | 710 | ||
728 | static int smsc95xx_phy_initialize(struct usbnet *dev) | 711 | static int smsc95xx_phy_initialize(struct usbnet *dev) |
729 | { | 712 | { |
713 | int bmcr, timeout = 0; | ||
714 | |||
730 | /* Initialize MII structure */ | 715 | /* Initialize MII structure */ |
731 | dev->mii.dev = dev->net; | 716 | dev->mii.dev = dev->net; |
732 | dev->mii.mdio_read = smsc95xx_mdio_read; | 717 | dev->mii.mdio_read = smsc95xx_mdio_read; |
@@ -735,7 +720,20 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) | |||
735 | dev->mii.reg_num_mask = 0x1f; | 720 | dev->mii.reg_num_mask = 0x1f; |
736 | dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID; | 721 | dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID; |
737 | 722 | ||
723 | /* reset phy and wait for reset to complete */ | ||
738 | smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | 724 | smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); |
725 | |||
726 | do { | ||
727 | msleep(10); | ||
728 | bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); | ||
729 | timeout++; | ||
730 | } while ((bmcr & MII_BMCR) && (timeout < 100)); | ||
731 | |||
732 | if (timeout >= 100) { | ||
733 | netdev_warn(dev->net, "timeout on PHY Reset"); | ||
734 | return -EIO; | ||
735 | } | ||
736 | |||
739 | smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | 737 | smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, |
740 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | | 738 | ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | |
741 | ADVERTISE_PAUSE_ASYM); | 739 | ADVERTISE_PAUSE_ASYM); |
@@ -747,8 +745,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) | |||
747 | PHY_INT_MASK_DEFAULT_); | 745 | PHY_INT_MASK_DEFAULT_); |
748 | mii_nway_restart(&dev->mii); | 746 | mii_nway_restart(&dev->mii); |
749 | 747 | ||
750 | if (netif_msg_ifup(dev)) | 748 | netif_dbg(dev, ifup, dev->net, "phy initialised successfully\n"); |
751 | devdbg(dev, "phy initialised succesfully"); | ||
752 | return 0; | 749 | return 0; |
753 | } | 750 | } |
754 | 751 | ||
@@ -759,14 +756,13 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
759 | u32 read_buf, write_buf, burst_cap; | 756 | u32 read_buf, write_buf, burst_cap; |
760 | int ret = 0, timeout; | 757 | int ret = 0, timeout; |
761 | 758 | ||
762 | if (netif_msg_ifup(dev)) | 759 | netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n"); |
763 | devdbg(dev, "entering smsc95xx_reset"); | ||
764 | 760 | ||
765 | write_buf = HW_CFG_LRST_; | 761 | write_buf = HW_CFG_LRST_; |
766 | ret = smsc95xx_write_reg(dev, HW_CFG, write_buf); | 762 | ret = smsc95xx_write_reg(dev, HW_CFG, write_buf); |
767 | if (ret < 0) { | 763 | if (ret < 0) { |
768 | devwarn(dev, "Failed to write HW_CFG_LRST_ bit in HW_CFG " | 764 | netdev_warn(dev->net, "Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d\n", |
769 | "register, ret = %d", ret); | 765 | ret); |
770 | return ret; | 766 | return ret; |
771 | } | 767 | } |
772 | 768 | ||
@@ -774,7 +770,7 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
774 | do { | 770 | do { |
775 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); | 771 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); |
776 | if (ret < 0) { | 772 | if (ret < 0) { |
777 | devwarn(dev, "Failed to read HW_CFG: %d", ret); | 773 | netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); |
778 | return ret; | 774 | return ret; |
779 | } | 775 | } |
780 | msleep(10); | 776 | msleep(10); |
@@ -782,14 +778,14 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
782 | } while ((read_buf & HW_CFG_LRST_) && (timeout < 100)); | 778 | } while ((read_buf & HW_CFG_LRST_) && (timeout < 100)); |
783 | 779 | ||
784 | if (timeout >= 100) { | 780 | if (timeout >= 100) { |
785 | devwarn(dev, "timeout waiting for completion of Lite Reset"); | 781 | netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n"); |
786 | return ret; | 782 | return ret; |
787 | } | 783 | } |
788 | 784 | ||
789 | write_buf = PM_CTL_PHY_RST_; | 785 | write_buf = PM_CTL_PHY_RST_; |
790 | ret = smsc95xx_write_reg(dev, PM_CTRL, write_buf); | 786 | ret = smsc95xx_write_reg(dev, PM_CTRL, write_buf); |
791 | if (ret < 0) { | 787 | if (ret < 0) { |
792 | devwarn(dev, "Failed to write PM_CTRL: %d", ret); | 788 | netdev_warn(dev->net, "Failed to write PM_CTRL: %d\n", ret); |
793 | return ret; | 789 | return ret; |
794 | } | 790 | } |
795 | 791 | ||
@@ -797,7 +793,7 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
797 | do { | 793 | do { |
798 | ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf); | 794 | ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf); |
799 | if (ret < 0) { | 795 | if (ret < 0) { |
800 | devwarn(dev, "Failed to read PM_CTRL: %d", ret); | 796 | netdev_warn(dev->net, "Failed to read PM_CTRL: %d\n", ret); |
801 | return ret; | 797 | return ret; |
802 | } | 798 | } |
803 | msleep(10); | 799 | msleep(10); |
@@ -805,7 +801,7 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
805 | } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100)); | 801 | } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100)); |
806 | 802 | ||
807 | if (timeout >= 100) { | 803 | if (timeout >= 100) { |
808 | devwarn(dev, "timeout waiting for PHY Reset"); | 804 | netdev_warn(dev->net, "timeout waiting for PHY Reset\n"); |
809 | return ret; | 805 | return ret; |
810 | } | 806 | } |
811 | 807 | ||
@@ -815,35 +811,35 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
815 | if (ret < 0) | 811 | if (ret < 0) |
816 | return ret; | 812 | return ret; |
817 | 813 | ||
818 | if (netif_msg_ifup(dev)) | 814 | netif_dbg(dev, ifup, dev->net, |
819 | devdbg(dev, "MAC Address: %pM", dev->net->dev_addr); | 815 | "MAC Address: %pM\n", dev->net->dev_addr); |
820 | 816 | ||
821 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); | 817 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); |
822 | if (ret < 0) { | 818 | if (ret < 0) { |
823 | devwarn(dev, "Failed to read HW_CFG: %d", ret); | 819 | netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); |
824 | return ret; | 820 | return ret; |
825 | } | 821 | } |
826 | 822 | ||
827 | if (netif_msg_ifup(dev)) | 823 | netif_dbg(dev, ifup, dev->net, |
828 | devdbg(dev, "Read Value from HW_CFG : 0x%08x", read_buf); | 824 | "Read Value from HW_CFG : 0x%08x\n", read_buf); |
829 | 825 | ||
830 | read_buf |= HW_CFG_BIR_; | 826 | read_buf |= HW_CFG_BIR_; |
831 | 827 | ||
832 | ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); | 828 | ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); |
833 | if (ret < 0) { | 829 | if (ret < 0) { |
834 | devwarn(dev, "Failed to write HW_CFG_BIR_ bit in HW_CFG " | 830 | netdev_warn(dev->net, "Failed to write HW_CFG_BIR_ bit in HW_CFG register, ret = %d\n", |
835 | "register, ret = %d", ret); | 831 | ret); |
836 | return ret; | 832 | return ret; |
837 | } | 833 | } |
838 | 834 | ||
839 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); | 835 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); |
840 | if (ret < 0) { | 836 | if (ret < 0) { |
841 | devwarn(dev, "Failed to read HW_CFG: %d", ret); | 837 | netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); |
842 | return ret; | 838 | return ret; |
843 | } | 839 | } |
844 | if (netif_msg_ifup(dev)) | 840 | netif_dbg(dev, ifup, dev->net, |
845 | devdbg(dev, "Read Value from HW_CFG after writing " | 841 | "Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n", |
846 | "HW_CFG_BIR_: 0x%08x", read_buf); | 842 | read_buf); |
847 | 843 | ||
848 | if (!turbo_mode) { | 844 | if (!turbo_mode) { |
849 | burst_cap = 0; | 845 | burst_cap = 0; |
@@ -856,47 +852,47 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
856 | dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; | 852 | dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; |
857 | } | 853 | } |
858 | 854 | ||
859 | if (netif_msg_ifup(dev)) | 855 | netif_dbg(dev, ifup, dev->net, |
860 | devdbg(dev, "rx_urb_size=%ld", (ulong)dev->rx_urb_size); | 856 | "rx_urb_size=%ld\n", (ulong)dev->rx_urb_size); |
861 | 857 | ||
862 | ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap); | 858 | ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap); |
863 | if (ret < 0) { | 859 | if (ret < 0) { |
864 | devwarn(dev, "Failed to write BURST_CAP: %d", ret); | 860 | netdev_warn(dev->net, "Failed to write BURST_CAP: %d\n", ret); |
865 | return ret; | 861 | return ret; |
866 | } | 862 | } |
867 | 863 | ||
868 | ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf); | 864 | ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf); |
869 | if (ret < 0) { | 865 | if (ret < 0) { |
870 | devwarn(dev, "Failed to read BURST_CAP: %d", ret); | 866 | netdev_warn(dev->net, "Failed to read BURST_CAP: %d\n", ret); |
871 | return ret; | 867 | return ret; |
872 | } | 868 | } |
873 | if (netif_msg_ifup(dev)) | 869 | netif_dbg(dev, ifup, dev->net, |
874 | devdbg(dev, "Read Value from BURST_CAP after writing: 0x%08x", | 870 | "Read Value from BURST_CAP after writing: 0x%08x\n", |
875 | read_buf); | 871 | read_buf); |
876 | 872 | ||
877 | read_buf = DEFAULT_BULK_IN_DELAY; | 873 | read_buf = DEFAULT_BULK_IN_DELAY; |
878 | ret = smsc95xx_write_reg(dev, BULK_IN_DLY, read_buf); | 874 | ret = smsc95xx_write_reg(dev, BULK_IN_DLY, read_buf); |
879 | if (ret < 0) { | 875 | if (ret < 0) { |
880 | devwarn(dev, "ret = %d", ret); | 876 | netdev_warn(dev->net, "ret = %d\n", ret); |
881 | return ret; | 877 | return ret; |
882 | } | 878 | } |
883 | 879 | ||
884 | ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf); | 880 | ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf); |
885 | if (ret < 0) { | 881 | if (ret < 0) { |
886 | devwarn(dev, "Failed to read BULK_IN_DLY: %d", ret); | 882 | netdev_warn(dev->net, "Failed to read BULK_IN_DLY: %d\n", ret); |
887 | return ret; | 883 | return ret; |
888 | } | 884 | } |
889 | if (netif_msg_ifup(dev)) | 885 | netif_dbg(dev, ifup, dev->net, |
890 | devdbg(dev, "Read Value from BULK_IN_DLY after writing: " | 886 | "Read Value from BULK_IN_DLY after writing: 0x%08x\n", |
891 | "0x%08x", read_buf); | 887 | read_buf); |
892 | 888 | ||
893 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); | 889 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); |
894 | if (ret < 0) { | 890 | if (ret < 0) { |
895 | devwarn(dev, "Failed to read HW_CFG: %d", ret); | 891 | netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); |
896 | return ret; | 892 | return ret; |
897 | } | 893 | } |
898 | if (netif_msg_ifup(dev)) | 894 | netif_dbg(dev, ifup, dev->net, |
899 | devdbg(dev, "Read Value from HW_CFG: 0x%08x", read_buf); | 895 | "Read Value from HW_CFG: 0x%08x\n", read_buf); |
900 | 896 | ||
901 | if (turbo_mode) | 897 | if (turbo_mode) |
902 | read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_); | 898 | read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_); |
@@ -908,41 +904,41 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
908 | 904 | ||
909 | ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); | 905 | ret = smsc95xx_write_reg(dev, HW_CFG, read_buf); |
910 | if (ret < 0) { | 906 | if (ret < 0) { |
911 | devwarn(dev, "Failed to write HW_CFG register, ret=%d", ret); | 907 | netdev_warn(dev->net, "Failed to write HW_CFG register, ret=%d\n", |
908 | ret); | ||
912 | return ret; | 909 | return ret; |
913 | } | 910 | } |
914 | 911 | ||
915 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); | 912 | ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf); |
916 | if (ret < 0) { | 913 | if (ret < 0) { |
917 | devwarn(dev, "Failed to read HW_CFG: %d", ret); | 914 | netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret); |
918 | return ret; | 915 | return ret; |
919 | } | 916 | } |
920 | if (netif_msg_ifup(dev)) | 917 | netif_dbg(dev, ifup, dev->net, |
921 | devdbg(dev, "Read Value from HW_CFG after writing: 0x%08x", | 918 | "Read Value from HW_CFG after writing: 0x%08x\n", read_buf); |
922 | read_buf); | ||
923 | 919 | ||
924 | write_buf = 0xFFFFFFFF; | 920 | write_buf = 0xFFFFFFFF; |
925 | ret = smsc95xx_write_reg(dev, INT_STS, write_buf); | 921 | ret = smsc95xx_write_reg(dev, INT_STS, write_buf); |
926 | if (ret < 0) { | 922 | if (ret < 0) { |
927 | devwarn(dev, "Failed to write INT_STS register, ret=%d", ret); | 923 | netdev_warn(dev->net, "Failed to write INT_STS register, ret=%d\n", |
924 | ret); | ||
928 | return ret; | 925 | return ret; |
929 | } | 926 | } |
930 | 927 | ||
931 | ret = smsc95xx_read_reg(dev, ID_REV, &read_buf); | 928 | ret = smsc95xx_read_reg(dev, ID_REV, &read_buf); |
932 | if (ret < 0) { | 929 | if (ret < 0) { |
933 | devwarn(dev, "Failed to read ID_REV: %d", ret); | 930 | netdev_warn(dev->net, "Failed to read ID_REV: %d\n", ret); |
934 | return ret; | 931 | return ret; |
935 | } | 932 | } |
936 | if (netif_msg_ifup(dev)) | 933 | netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf); |
937 | devdbg(dev, "ID_REV = 0x%08x", read_buf); | ||
938 | 934 | ||
939 | /* Configure GPIO pins as LED outputs */ | 935 | /* Configure GPIO pins as LED outputs */ |
940 | write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | | 936 | write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | |
941 | LED_GPIO_CFG_FDX_LED; | 937 | LED_GPIO_CFG_FDX_LED; |
942 | ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf); | 938 | ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf); |
943 | if (ret < 0) { | 939 | if (ret < 0) { |
944 | devwarn(dev, "Failed to write LED_GPIO_CFG register, ret=%d", | 940 | netdev_warn(dev->net, "Failed to write LED_GPIO_CFG register, ret=%d\n", |
945 | ret); | 941 | ret); |
946 | return ret; | 942 | return ret; |
947 | } | 943 | } |
948 | 944 | ||
@@ -950,21 +946,21 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
950 | write_buf = 0; | 946 | write_buf = 0; |
951 | ret = smsc95xx_write_reg(dev, FLOW, write_buf); | 947 | ret = smsc95xx_write_reg(dev, FLOW, write_buf); |
952 | if (ret < 0) { | 948 | if (ret < 0) { |
953 | devwarn(dev, "Failed to write FLOW: %d", ret); | 949 | netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret); |
954 | return ret; | 950 | return ret; |
955 | } | 951 | } |
956 | 952 | ||
957 | read_buf = AFC_CFG_DEFAULT; | 953 | read_buf = AFC_CFG_DEFAULT; |
958 | ret = smsc95xx_write_reg(dev, AFC_CFG, read_buf); | 954 | ret = smsc95xx_write_reg(dev, AFC_CFG, read_buf); |
959 | if (ret < 0) { | 955 | if (ret < 0) { |
960 | devwarn(dev, "Failed to write AFC_CFG: %d", ret); | 956 | netdev_warn(dev->net, "Failed to write AFC_CFG: %d\n", ret); |
961 | return ret; | 957 | return ret; |
962 | } | 958 | } |
963 | 959 | ||
964 | /* Don't need mac_cr_lock during initialisation */ | 960 | /* Don't need mac_cr_lock during initialisation */ |
965 | ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr); | 961 | ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr); |
966 | if (ret < 0) { | 962 | if (ret < 0) { |
967 | devwarn(dev, "Failed to read MAC_CR: %d", ret); | 963 | netdev_warn(dev->net, "Failed to read MAC_CR: %d\n", ret); |
968 | return ret; | 964 | return ret; |
969 | } | 965 | } |
970 | 966 | ||
@@ -973,7 +969,7 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
973 | write_buf = (u32)ETH_P_8021Q; | 969 | write_buf = (u32)ETH_P_8021Q; |
974 | ret = smsc95xx_write_reg(dev, VLAN1, write_buf); | 970 | ret = smsc95xx_write_reg(dev, VLAN1, write_buf); |
975 | if (ret < 0) { | 971 | if (ret < 0) { |
976 | devwarn(dev, "Failed to write VAN1: %d", ret); | 972 | netdev_warn(dev->net, "Failed to write VAN1: %d\n", ret); |
977 | return ret; | 973 | return ret; |
978 | } | 974 | } |
979 | 975 | ||
@@ -981,7 +977,7 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
981 | ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum); | 977 | ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum); |
982 | ret = smsc95xx_set_csums(dev); | 978 | ret = smsc95xx_set_csums(dev); |
983 | if (ret < 0) { | 979 | if (ret < 0) { |
984 | devwarn(dev, "Failed to set csum offload: %d", ret); | 980 | netdev_warn(dev->net, "Failed to set csum offload: %d\n", ret); |
985 | return ret; | 981 | return ret; |
986 | } | 982 | } |
987 | 983 | ||
@@ -992,7 +988,7 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
992 | 988 | ||
993 | ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf); | 989 | ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf); |
994 | if (ret < 0) { | 990 | if (ret < 0) { |
995 | devwarn(dev, "Failed to read INT_EP_CTL: %d", ret); | 991 | netdev_warn(dev->net, "Failed to read INT_EP_CTL: %d\n", ret); |
996 | return ret; | 992 | return ret; |
997 | } | 993 | } |
998 | 994 | ||
@@ -1001,15 +997,14 @@ static int smsc95xx_reset(struct usbnet *dev) | |||
1001 | 997 | ||
1002 | ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf); | 998 | ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf); |
1003 | if (ret < 0) { | 999 | if (ret < 0) { |
1004 | devwarn(dev, "Failed to write INT_EP_CTL: %d", ret); | 1000 | netdev_warn(dev->net, "Failed to write INT_EP_CTL: %d\n", ret); |
1005 | return ret; | 1001 | return ret; |
1006 | } | 1002 | } |
1007 | 1003 | ||
1008 | smsc95xx_start_tx_path(dev); | 1004 | smsc95xx_start_tx_path(dev); |
1009 | smsc95xx_start_rx_path(dev); | 1005 | smsc95xx_start_rx_path(dev); |
1010 | 1006 | ||
1011 | if (netif_msg_ifup(dev)) | 1007 | netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n"); |
1012 | devdbg(dev, "smsc95xx_reset, return 0"); | ||
1013 | return 0; | 1008 | return 0; |
1014 | } | 1009 | } |
1015 | 1010 | ||
@@ -1034,7 +1029,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1034 | 1029 | ||
1035 | ret = usbnet_get_endpoints(dev, intf); | 1030 | ret = usbnet_get_endpoints(dev, intf); |
1036 | if (ret < 0) { | 1031 | if (ret < 0) { |
1037 | devwarn(dev, "usbnet_get_endpoints failed: %d", ret); | 1032 | netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret); |
1038 | return ret; | 1033 | return ret; |
1039 | } | 1034 | } |
1040 | 1035 | ||
@@ -1043,7 +1038,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1043 | 1038 | ||
1044 | pdata = (struct smsc95xx_priv *)(dev->data[0]); | 1039 | pdata = (struct smsc95xx_priv *)(dev->data[0]); |
1045 | if (!pdata) { | 1040 | if (!pdata) { |
1046 | devwarn(dev, "Unable to allocate struct smsc95xx_priv"); | 1041 | netdev_warn(dev->net, "Unable to allocate struct smsc95xx_priv\n"); |
1047 | return -ENOMEM; | 1042 | return -ENOMEM; |
1048 | } | 1043 | } |
1049 | 1044 | ||
@@ -1066,8 +1061,7 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
1066 | { | 1061 | { |
1067 | struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); | 1062 | struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); |
1068 | if (pdata) { | 1063 | if (pdata) { |
1069 | if (netif_msg_ifdown(dev)) | 1064 | netif_dbg(dev, ifdown, dev->net, "free pdata\n"); |
1070 | devdbg(dev, "free pdata"); | ||
1071 | kfree(pdata); | 1065 | kfree(pdata); |
1072 | pdata = NULL; | 1066 | pdata = NULL; |
1073 | dev->data[0] = 0; | 1067 | dev->data[0] = 0; |
@@ -1101,8 +1095,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1101 | align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; | 1095 | align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; |
1102 | 1096 | ||
1103 | if (unlikely(header & RX_STS_ES_)) { | 1097 | if (unlikely(header & RX_STS_ES_)) { |
1104 | if (netif_msg_rx_err(dev)) | 1098 | netif_dbg(dev, rx_err, dev->net, |
1105 | devdbg(dev, "Error header=0x%08x", header); | 1099 | "Error header=0x%08x\n", header); |
1106 | dev->net->stats.rx_errors++; | 1100 | dev->net->stats.rx_errors++; |
1107 | dev->net->stats.rx_dropped++; | 1101 | dev->net->stats.rx_dropped++; |
1108 | 1102 | ||
@@ -1119,9 +1113,8 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1119 | } else { | 1113 | } else { |
1120 | /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ | 1114 | /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ |
1121 | if (unlikely(size > (ETH_FRAME_LEN + 12))) { | 1115 | if (unlikely(size > (ETH_FRAME_LEN + 12))) { |
1122 | if (netif_msg_rx_err(dev)) | 1116 | netif_dbg(dev, rx_err, dev->net, |
1123 | devdbg(dev, "size err header=0x%08x", | 1117 | "size err header=0x%08x\n", header); |
1124 | header); | ||
1125 | return 0; | 1118 | return 0; |
1126 | } | 1119 | } |
1127 | 1120 | ||
@@ -1137,7 +1130,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1137 | 1130 | ||
1138 | ax_skb = skb_clone(skb, GFP_ATOMIC); | 1131 | ax_skb = skb_clone(skb, GFP_ATOMIC); |
1139 | if (unlikely(!ax_skb)) { | 1132 | if (unlikely(!ax_skb)) { |
1140 | devwarn(dev, "Error allocating skb"); | 1133 | netdev_warn(dev->net, "Error allocating skb\n"); |
1141 | return 0; | 1134 | return 0; |
1142 | } | 1135 | } |
1143 | 1136 | ||
@@ -1161,7 +1154,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1161 | } | 1154 | } |
1162 | 1155 | ||
1163 | if (unlikely(skb->len < 0)) { | 1156 | if (unlikely(skb->len < 0)) { |
1164 | devwarn(dev, "invalid rx length<0 %d", skb->len); | 1157 | netdev_warn(dev->net, "invalid rx length<0 %d\n", skb->len); |
1165 | return 0; | 1158 | return 0; |
1166 | } | 1159 | } |
1167 | 1160 | ||
@@ -1197,9 +1190,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, | |||
1197 | } | 1190 | } |
1198 | 1191 | ||
1199 | if (csum) { | 1192 | if (csum) { |
1200 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); | 1193 | if (skb->len <= 45) { |
1201 | skb_push(skb, 4); | 1194 | /* workaround - hardware tx checksum does not work |
1202 | memcpy(skb->data, &csum_preamble, 4); | 1195 | * properly with extremely small packets */ |
1196 | long csstart = skb->csum_start - skb_headroom(skb); | ||
1197 | __wsum calc = csum_partial(skb->data + csstart, | ||
1198 | skb->len - csstart, 0); | ||
1199 | *((__sum16 *)(skb->data + csstart | ||
1200 | + skb->csum_offset)) = csum_fold(calc); | ||
1201 | |||
1202 | csum = false; | ||
1203 | } else { | ||
1204 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); | ||
1205 | skb_push(skb, 4); | ||
1206 | memcpy(skb->data, &csum_preamble, 4); | ||
1207 | } | ||
1203 | } | 1208 | } |
1204 | 1209 | ||
1205 | skb_push(skb, 4); | 1210 | skb_push(skb, 4); |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ca5ca5ae061d..7177abc78dc6 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/mii.h> | 43 | #include <linux/mii.h> |
44 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
45 | #include <linux/usb/usbnet.h> | 45 | #include <linux/usb/usbnet.h> |
46 | #include <linux/slab.h> | ||
46 | 47 | ||
47 | #define DRIVER_VERSION "22-Aug-2005" | 48 | #define DRIVER_VERSION "22-Aug-2005" |
48 | 49 | ||
@@ -140,8 +141,8 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) | |||
140 | if (!alt || !in || !out) | 141 | if (!alt || !in || !out) |
141 | return -EINVAL; | 142 | return -EINVAL; |
142 | 143 | ||
143 | if (alt->desc.bAlternateSetting != 0 | 144 | if (alt->desc.bAlternateSetting != 0 || |
144 | || !(dev->driver_info->flags & FLAG_NO_SETINT)) { | 145 | !(dev->driver_info->flags & FLAG_NO_SETINT)) { |
145 | tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, | 146 | tmp = usb_set_interface (dev->udev, alt->desc.bInterfaceNumber, |
146 | alt->desc.bAlternateSetting); | 147 | alt->desc.bAlternateSetting); |
147 | if (tmp < 0) | 148 | if (tmp < 0) |
@@ -242,13 +243,13 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) | |||
242 | dev->net->stats.rx_packets++; | 243 | dev->net->stats.rx_packets++; |
243 | dev->net->stats.rx_bytes += skb->len; | 244 | dev->net->stats.rx_bytes += skb->len; |
244 | 245 | ||
245 | if (netif_msg_rx_status (dev)) | 246 | netif_dbg(dev, rx_status, dev->net, "< rx, len %zu, type 0x%x\n", |
246 | devdbg (dev, "< rx, len %zu, type 0x%x", | 247 | skb->len + sizeof (struct ethhdr), skb->protocol); |
247 | skb->len + sizeof (struct ethhdr), skb->protocol); | ||
248 | memset (skb->cb, 0, sizeof (struct skb_data)); | 248 | memset (skb->cb, 0, sizeof (struct skb_data)); |
249 | status = netif_rx (skb); | 249 | status = netif_rx (skb); |
250 | if (status != NET_RX_SUCCESS && netif_msg_rx_err (dev)) | 250 | if (status != NET_RX_SUCCESS) |
251 | devdbg (dev, "netif_rx status %d", status); | 251 | netif_dbg(dev, rx_err, dev->net, |
252 | "netif_rx status %d\n", status); | ||
252 | } | 253 | } |
253 | EXPORT_SYMBOL_GPL(usbnet_skb_return); | 254 | EXPORT_SYMBOL_GPL(usbnet_skb_return); |
254 | 255 | ||
@@ -313,9 +314,9 @@ void usbnet_defer_kevent (struct usbnet *dev, int work) | |||
313 | { | 314 | { |
314 | set_bit (work, &dev->flags); | 315 | set_bit (work, &dev->flags); |
315 | if (!schedule_work (&dev->kevent)) | 316 | if (!schedule_work (&dev->kevent)) |
316 | deverr (dev, "kevent %d may have been dropped", work); | 317 | netdev_err(dev->net, "kevent %d may have been dropped\n", work); |
317 | else | 318 | else |
318 | devdbg (dev, "kevent %d scheduled", work); | 319 | netdev_dbg(dev->net, "kevent %d scheduled\n", work); |
319 | } | 320 | } |
320 | EXPORT_SYMBOL_GPL(usbnet_defer_kevent); | 321 | EXPORT_SYMBOL_GPL(usbnet_defer_kevent); |
321 | 322 | ||
@@ -332,8 +333,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
332 | size_t size = dev->rx_urb_size; | 333 | size_t size = dev->rx_urb_size; |
333 | 334 | ||
334 | if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { | 335 | if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { |
335 | if (netif_msg_rx_err (dev)) | 336 | netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); |
336 | devdbg (dev, "no rx skb"); | ||
337 | usbnet_defer_kevent (dev, EVENT_RX_MEMORY); | 337 | usbnet_defer_kevent (dev, EVENT_RX_MEMORY); |
338 | usb_free_urb (urb); | 338 | usb_free_urb (urb); |
339 | return; | 339 | return; |
@@ -351,9 +351,10 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
351 | 351 | ||
352 | spin_lock_irqsave (&dev->rxq.lock, lockflags); | 352 | spin_lock_irqsave (&dev->rxq.lock, lockflags); |
353 | 353 | ||
354 | if (netif_running (dev->net) | 354 | if (netif_running (dev->net) && |
355 | && netif_device_present (dev->net) | 355 | netif_device_present (dev->net) && |
356 | && !test_bit (EVENT_RX_HALT, &dev->flags)) { | 356 | !test_bit (EVENT_RX_HALT, &dev->flags) && |
357 | !test_bit (EVENT_DEV_ASLEEP, &dev->flags)) { | ||
357 | switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { | 358 | switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) { |
358 | case -EPIPE: | 359 | case -EPIPE: |
359 | usbnet_defer_kevent (dev, EVENT_RX_HALT); | 360 | usbnet_defer_kevent (dev, EVENT_RX_HALT); |
@@ -362,21 +363,19 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
362 | usbnet_defer_kevent (dev, EVENT_RX_MEMORY); | 363 | usbnet_defer_kevent (dev, EVENT_RX_MEMORY); |
363 | break; | 364 | break; |
364 | case -ENODEV: | 365 | case -ENODEV: |
365 | if (netif_msg_ifdown (dev)) | 366 | netif_dbg(dev, ifdown, dev->net, "device gone\n"); |
366 | devdbg (dev, "device gone"); | ||
367 | netif_device_detach (dev->net); | 367 | netif_device_detach (dev->net); |
368 | break; | 368 | break; |
369 | default: | 369 | default: |
370 | if (netif_msg_rx_err (dev)) | 370 | netif_dbg(dev, rx_err, dev->net, |
371 | devdbg (dev, "rx submit, %d", retval); | 371 | "rx submit, %d\n", retval); |
372 | tasklet_schedule (&dev->bh); | 372 | tasklet_schedule (&dev->bh); |
373 | break; | 373 | break; |
374 | case 0: | 374 | case 0: |
375 | __skb_queue_tail (&dev->rxq, skb); | 375 | __skb_queue_tail (&dev->rxq, skb); |
376 | } | 376 | } |
377 | } else { | 377 | } else { |
378 | if (netif_msg_ifdown (dev)) | 378 | netif_dbg(dev, ifdown, dev->net, "rx: stopped\n"); |
379 | devdbg (dev, "rx: stopped"); | ||
380 | retval = -ENOLINK; | 379 | retval = -ENOLINK; |
381 | } | 380 | } |
382 | spin_unlock_irqrestore (&dev->rxq.lock, lockflags); | 381 | spin_unlock_irqrestore (&dev->rxq.lock, lockflags); |
@@ -391,16 +390,15 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
391 | 390 | ||
392 | static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | 391 | static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) |
393 | { | 392 | { |
394 | if (dev->driver_info->rx_fixup | 393 | if (dev->driver_info->rx_fixup && |
395 | && !dev->driver_info->rx_fixup (dev, skb)) | 394 | !dev->driver_info->rx_fixup (dev, skb)) |
396 | goto error; | 395 | goto error; |
397 | // else network stack removes extra byte if we forced a short packet | 396 | // else network stack removes extra byte if we forced a short packet |
398 | 397 | ||
399 | if (skb->len) | 398 | if (skb->len) |
400 | usbnet_skb_return (dev, skb); | 399 | usbnet_skb_return (dev, skb); |
401 | else { | 400 | else { |
402 | if (netif_msg_rx_err (dev)) | 401 | netif_dbg(dev, rx_err, dev->net, "drop\n"); |
403 | devdbg (dev, "drop"); | ||
404 | error: | 402 | error: |
405 | dev->net->stats.rx_errors++; | 403 | dev->net->stats.rx_errors++; |
406 | skb_queue_tail (&dev->done, skb); | 404 | skb_queue_tail (&dev->done, skb); |
@@ -427,8 +425,8 @@ static void rx_complete (struct urb *urb) | |||
427 | entry->state = rx_cleanup; | 425 | entry->state = rx_cleanup; |
428 | dev->net->stats.rx_errors++; | 426 | dev->net->stats.rx_errors++; |
429 | dev->net->stats.rx_length_errors++; | 427 | dev->net->stats.rx_length_errors++; |
430 | if (netif_msg_rx_err (dev)) | 428 | netif_dbg(dev, rx_err, dev->net, |
431 | devdbg (dev, "rx length %d", skb->len); | 429 | "rx length %d\n", skb->len); |
432 | } | 430 | } |
433 | break; | 431 | break; |
434 | 432 | ||
@@ -445,8 +443,8 @@ static void rx_complete (struct urb *urb) | |||
445 | /* software-driven interface shutdown */ | 443 | /* software-driven interface shutdown */ |
446 | case -ECONNRESET: /* async unlink */ | 444 | case -ECONNRESET: /* async unlink */ |
447 | case -ESHUTDOWN: /* hardware gone */ | 445 | case -ESHUTDOWN: /* hardware gone */ |
448 | if (netif_msg_ifdown (dev)) | 446 | netif_dbg(dev, ifdown, dev->net, |
449 | devdbg (dev, "rx shutdown, code %d", urb_status); | 447 | "rx shutdown, code %d\n", urb_status); |
450 | goto block; | 448 | goto block; |
451 | 449 | ||
452 | /* we get controller i/o faults during khubd disconnect() delays. | 450 | /* we get controller i/o faults during khubd disconnect() delays. |
@@ -459,8 +457,8 @@ static void rx_complete (struct urb *urb) | |||
459 | dev->net->stats.rx_errors++; | 457 | dev->net->stats.rx_errors++; |
460 | if (!timer_pending (&dev->delay)) { | 458 | if (!timer_pending (&dev->delay)) { |
461 | mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); | 459 | mod_timer (&dev->delay, jiffies + THROTTLE_JIFFIES); |
462 | if (netif_msg_link (dev)) | 460 | netif_dbg(dev, link, dev->net, |
463 | devdbg (dev, "rx throttle %d", urb_status); | 461 | "rx throttle %d\n", urb_status); |
464 | } | 462 | } |
465 | block: | 463 | block: |
466 | entry->state = rx_cleanup; | 464 | entry->state = rx_cleanup; |
@@ -476,23 +474,21 @@ block: | |||
476 | default: | 474 | default: |
477 | entry->state = rx_cleanup; | 475 | entry->state = rx_cleanup; |
478 | dev->net->stats.rx_errors++; | 476 | dev->net->stats.rx_errors++; |
479 | if (netif_msg_rx_err (dev)) | 477 | netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status); |
480 | devdbg (dev, "rx status %d", urb_status); | ||
481 | break; | 478 | break; |
482 | } | 479 | } |
483 | 480 | ||
484 | defer_bh(dev, skb, &dev->rxq); | 481 | defer_bh(dev, skb, &dev->rxq); |
485 | 482 | ||
486 | if (urb) { | 483 | if (urb) { |
487 | if (netif_running (dev->net) | 484 | if (netif_running (dev->net) && |
488 | && !test_bit (EVENT_RX_HALT, &dev->flags)) { | 485 | !test_bit (EVENT_RX_HALT, &dev->flags)) { |
489 | rx_submit (dev, urb, GFP_ATOMIC); | 486 | rx_submit (dev, urb, GFP_ATOMIC); |
490 | return; | 487 | return; |
491 | } | 488 | } |
492 | usb_free_urb (urb); | 489 | usb_free_urb (urb); |
493 | } | 490 | } |
494 | if (netif_msg_rx_err (dev)) | 491 | netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n"); |
495 | devdbg (dev, "no read resubmitted"); | ||
496 | } | 492 | } |
497 | 493 | ||
498 | static void intr_complete (struct urb *urb) | 494 | static void intr_complete (struct urb *urb) |
@@ -509,15 +505,15 @@ static void intr_complete (struct urb *urb) | |||
509 | /* software-driven interface shutdown */ | 505 | /* software-driven interface shutdown */ |
510 | case -ENOENT: /* urb killed */ | 506 | case -ENOENT: /* urb killed */ |
511 | case -ESHUTDOWN: /* hardware gone */ | 507 | case -ESHUTDOWN: /* hardware gone */ |
512 | if (netif_msg_ifdown (dev)) | 508 | netif_dbg(dev, ifdown, dev->net, |
513 | devdbg (dev, "intr shutdown, code %d", status); | 509 | "intr shutdown, code %d\n", status); |
514 | return; | 510 | return; |
515 | 511 | ||
516 | /* NOTE: not throttling like RX/TX, since this endpoint | 512 | /* NOTE: not throttling like RX/TX, since this endpoint |
517 | * already polls infrequently | 513 | * already polls infrequently |
518 | */ | 514 | */ |
519 | default: | 515 | default: |
520 | devdbg (dev, "intr status %d", status); | 516 | netdev_dbg(dev->net, "intr status %d\n", status); |
521 | break; | 517 | break; |
522 | } | 518 | } |
523 | 519 | ||
@@ -526,8 +522,9 @@ static void intr_complete (struct urb *urb) | |||
526 | 522 | ||
527 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); | 523 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); |
528 | status = usb_submit_urb (urb, GFP_ATOMIC); | 524 | status = usb_submit_urb (urb, GFP_ATOMIC); |
529 | if (status != 0 && netif_msg_timer (dev)) | 525 | if (status != 0) |
530 | deverr(dev, "intr resubmit --> %d", status); | 526 | netif_err(dev, timer, dev->net, |
527 | "intr resubmit --> %d\n", status); | ||
531 | } | 528 | } |
532 | 529 | ||
533 | /*-------------------------------------------------------------------------*/ | 530 | /*-------------------------------------------------------------------------*/ |
@@ -535,8 +532,7 @@ void usbnet_pause_rx(struct usbnet *dev) | |||
535 | { | 532 | { |
536 | set_bit(EVENT_RX_PAUSED, &dev->flags); | 533 | set_bit(EVENT_RX_PAUSED, &dev->flags); |
537 | 534 | ||
538 | if (netif_msg_rx_status(dev)) | 535 | netif_dbg(dev, rx_status, dev->net, "paused rx queue enabled\n"); |
539 | devdbg(dev, "paused rx queue enabled"); | ||
540 | } | 536 | } |
541 | EXPORT_SYMBOL_GPL(usbnet_pause_rx); | 537 | EXPORT_SYMBOL_GPL(usbnet_pause_rx); |
542 | 538 | ||
@@ -554,8 +550,8 @@ void usbnet_resume_rx(struct usbnet *dev) | |||
554 | 550 | ||
555 | tasklet_schedule(&dev->bh); | 551 | tasklet_schedule(&dev->bh); |
556 | 552 | ||
557 | if (netif_msg_rx_status(dev)) | 553 | netif_dbg(dev, rx_status, dev->net, |
558 | devdbg(dev, "paused rx queue disabled, %d skbs requeued", num); | 554 | "paused rx queue disabled, %d skbs requeued\n", num); |
559 | } | 555 | } |
560 | EXPORT_SYMBOL_GPL(usbnet_resume_rx); | 556 | EXPORT_SYMBOL_GPL(usbnet_resume_rx); |
561 | 557 | ||
@@ -588,7 +584,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) | |||
588 | // these (async) unlinks complete immediately | 584 | // these (async) unlinks complete immediately |
589 | retval = usb_unlink_urb (urb); | 585 | retval = usb_unlink_urb (urb); |
590 | if (retval != -EINPROGRESS && retval != 0) | 586 | if (retval != -EINPROGRESS && retval != 0) |
591 | devdbg (dev, "unlink urb err, %d", retval); | 587 | netdev_dbg(dev->net, "unlink urb err, %d\n", retval); |
592 | else | 588 | else |
593 | count++; | 589 | count++; |
594 | } | 590 | } |
@@ -611,55 +607,60 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs); | |||
611 | /*-------------------------------------------------------------------------*/ | 607 | /*-------------------------------------------------------------------------*/ |
612 | 608 | ||
613 | // precondition: never called in_interrupt | 609 | // precondition: never called in_interrupt |
610 | static void usbnet_terminate_urbs(struct usbnet *dev) | ||
611 | { | ||
612 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); | ||
613 | DECLARE_WAITQUEUE(wait, current); | ||
614 | int temp; | ||
615 | |||
616 | /* ensure there are no more active urbs */ | ||
617 | add_wait_queue(&unlink_wakeup, &wait); | ||
618 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
619 | dev->wait = &unlink_wakeup; | ||
620 | temp = unlink_urbs(dev, &dev->txq) + | ||
621 | unlink_urbs(dev, &dev->rxq); | ||
622 | |||
623 | /* maybe wait for deletions to finish. */ | ||
624 | while (!skb_queue_empty(&dev->rxq) | ||
625 | && !skb_queue_empty(&dev->txq) | ||
626 | && !skb_queue_empty(&dev->done)) { | ||
627 | schedule_timeout(UNLINK_TIMEOUT_MS); | ||
628 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
629 | netif_dbg(dev, ifdown, dev->net, | ||
630 | "waited for %d urb completions\n", temp); | ||
631 | } | ||
632 | set_current_state(TASK_RUNNING); | ||
633 | dev->wait = NULL; | ||
634 | remove_wait_queue(&unlink_wakeup, &wait); | ||
635 | } | ||
614 | 636 | ||
615 | int usbnet_stop (struct net_device *net) | 637 | int usbnet_stop (struct net_device *net) |
616 | { | 638 | { |
617 | struct usbnet *dev = netdev_priv(net); | 639 | struct usbnet *dev = netdev_priv(net); |
618 | struct driver_info *info = dev->driver_info; | 640 | struct driver_info *info = dev->driver_info; |
619 | int temp; | ||
620 | int retval; | 641 | int retval; |
621 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup); | ||
622 | DECLARE_WAITQUEUE (wait, current); | ||
623 | 642 | ||
624 | netif_stop_queue (net); | 643 | netif_stop_queue (net); |
625 | 644 | ||
626 | if (netif_msg_ifdown (dev)) | 645 | netif_info(dev, ifdown, dev->net, |
627 | devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld", | 646 | "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", |
628 | net->stats.rx_packets, net->stats.tx_packets, | 647 | net->stats.rx_packets, net->stats.tx_packets, |
629 | net->stats.rx_errors, net->stats.tx_errors | 648 | net->stats.rx_errors, net->stats.tx_errors); |
630 | ); | ||
631 | 649 | ||
632 | /* allow minidriver to stop correctly (wireless devices to turn off | 650 | /* allow minidriver to stop correctly (wireless devices to turn off |
633 | * radio etc) */ | 651 | * radio etc) */ |
634 | if (info->stop) { | 652 | if (info->stop) { |
635 | retval = info->stop(dev); | 653 | retval = info->stop(dev); |
636 | if (retval < 0 && netif_msg_ifdown(dev)) | 654 | if (retval < 0) |
637 | devinfo(dev, | 655 | netif_info(dev, ifdown, dev->net, |
638 | "stop fail (%d) usbnet usb-%s-%s, %s", | 656 | "stop fail (%d) usbnet usb-%s-%s, %s\n", |
639 | retval, | 657 | retval, |
640 | dev->udev->bus->bus_name, dev->udev->devpath, | 658 | dev->udev->bus->bus_name, dev->udev->devpath, |
641 | info->description); | 659 | info->description); |
642 | } | 660 | } |
643 | 661 | ||
644 | if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) { | 662 | if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) |
645 | /* ensure there are no more active urbs */ | 663 | usbnet_terminate_urbs(dev); |
646 | add_wait_queue(&unlink_wakeup, &wait); | ||
647 | dev->wait = &unlink_wakeup; | ||
648 | temp = unlink_urbs(dev, &dev->txq) + | ||
649 | unlink_urbs(dev, &dev->rxq); | ||
650 | |||
651 | /* maybe wait for deletions to finish. */ | ||
652 | while (!skb_queue_empty(&dev->rxq) | ||
653 | && !skb_queue_empty(&dev->txq) | ||
654 | && !skb_queue_empty(&dev->done)) { | ||
655 | msleep(UNLINK_TIMEOUT_MS); | ||
656 | if (netif_msg_ifdown(dev)) | ||
657 | devdbg(dev, "waited for %d urb completions", | ||
658 | temp); | ||
659 | } | ||
660 | dev->wait = NULL; | ||
661 | remove_wait_queue(&unlink_wakeup, &wait); | ||
662 | } | ||
663 | 664 | ||
664 | usb_kill_urb(dev->interrupt); | 665 | usb_kill_urb(dev->interrupt); |
665 | 666 | ||
@@ -672,7 +673,10 @@ int usbnet_stop (struct net_device *net) | |||
672 | dev->flags = 0; | 673 | dev->flags = 0; |
673 | del_timer_sync (&dev->delay); | 674 | del_timer_sync (&dev->delay); |
674 | tasklet_kill (&dev->bh); | 675 | tasklet_kill (&dev->bh); |
675 | usb_autopm_put_interface(dev->intf); | 676 | if (info->manage_power) |
677 | info->manage_power(dev, 0); | ||
678 | else | ||
679 | usb_autopm_put_interface(dev->intf); | ||
676 | 680 | ||
677 | return 0; | 681 | return 0; |
678 | } | 682 | } |
@@ -691,30 +695,29 @@ int usbnet_open (struct net_device *net) | |||
691 | struct driver_info *info = dev->driver_info; | 695 | struct driver_info *info = dev->driver_info; |
692 | 696 | ||
693 | if ((retval = usb_autopm_get_interface(dev->intf)) < 0) { | 697 | if ((retval = usb_autopm_get_interface(dev->intf)) < 0) { |
694 | if (netif_msg_ifup (dev)) | 698 | netif_info(dev, ifup, dev->net, |
695 | devinfo (dev, | 699 | "resumption fail (%d) usbnet usb-%s-%s, %s\n", |
696 | "resumption fail (%d) usbnet usb-%s-%s, %s", | 700 | retval, |
697 | retval, | 701 | dev->udev->bus->bus_name, |
698 | dev->udev->bus->bus_name, dev->udev->devpath, | 702 | dev->udev->devpath, |
699 | info->description); | 703 | info->description); |
700 | goto done_nopm; | 704 | goto done_nopm; |
701 | } | 705 | } |
702 | 706 | ||
703 | // put into "known safe" state | 707 | // put into "known safe" state |
704 | if (info->reset && (retval = info->reset (dev)) < 0) { | 708 | if (info->reset && (retval = info->reset (dev)) < 0) { |
705 | if (netif_msg_ifup (dev)) | 709 | netif_info(dev, ifup, dev->net, |
706 | devinfo (dev, | 710 | "open reset fail (%d) usbnet usb-%s-%s, %s\n", |
707 | "open reset fail (%d) usbnet usb-%s-%s, %s", | 711 | retval, |
708 | retval, | 712 | dev->udev->bus->bus_name, |
709 | dev->udev->bus->bus_name, dev->udev->devpath, | 713 | dev->udev->devpath, |
710 | info->description); | 714 | info->description); |
711 | goto done; | 715 | goto done; |
712 | } | 716 | } |
713 | 717 | ||
714 | // insist peer be connected | 718 | // insist peer be connected |
715 | if (info->check_connect && (retval = info->check_connect (dev)) < 0) { | 719 | if (info->check_connect && (retval = info->check_connect (dev)) < 0) { |
716 | if (netif_msg_ifup (dev)) | 720 | netif_dbg(dev, ifup, dev->net, "can't open; %d\n", retval); |
717 | devdbg (dev, "can't open; %d", retval); | ||
718 | goto done; | 721 | goto done; |
719 | } | 722 | } |
720 | 723 | ||
@@ -722,38 +725,34 @@ int usbnet_open (struct net_device *net) | |||
722 | if (dev->interrupt) { | 725 | if (dev->interrupt) { |
723 | retval = usb_submit_urb (dev->interrupt, GFP_KERNEL); | 726 | retval = usb_submit_urb (dev->interrupt, GFP_KERNEL); |
724 | if (retval < 0) { | 727 | if (retval < 0) { |
725 | if (netif_msg_ifup (dev)) | 728 | netif_err(dev, ifup, dev->net, |
726 | deverr (dev, "intr submit %d", retval); | 729 | "intr submit %d\n", retval); |
727 | goto done; | 730 | goto done; |
728 | } | 731 | } |
729 | } | 732 | } |
730 | 733 | ||
731 | netif_start_queue (net); | 734 | netif_start_queue (net); |
732 | if (netif_msg_ifup (dev)) { | 735 | netif_info(dev, ifup, dev->net, |
733 | char *framing; | 736 | "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n", |
734 | 737 | (int)RX_QLEN(dev), (int)TX_QLEN(dev), | |
735 | if (dev->driver_info->flags & FLAG_FRAMING_NC) | 738 | dev->net->mtu, |
736 | framing = "NetChip"; | 739 | (dev->driver_info->flags & FLAG_FRAMING_NC) ? "NetChip" : |
737 | else if (dev->driver_info->flags & FLAG_FRAMING_GL) | 740 | (dev->driver_info->flags & FLAG_FRAMING_GL) ? "GeneSys" : |
738 | framing = "GeneSys"; | 741 | (dev->driver_info->flags & FLAG_FRAMING_Z) ? "Zaurus" : |
739 | else if (dev->driver_info->flags & FLAG_FRAMING_Z) | 742 | (dev->driver_info->flags & FLAG_FRAMING_RN) ? "RNDIS" : |
740 | framing = "Zaurus"; | 743 | (dev->driver_info->flags & FLAG_FRAMING_AX) ? "ASIX" : |
741 | else if (dev->driver_info->flags & FLAG_FRAMING_RN) | 744 | "simple"); |
742 | framing = "RNDIS"; | ||
743 | else if (dev->driver_info->flags & FLAG_FRAMING_AX) | ||
744 | framing = "ASIX"; | ||
745 | else | ||
746 | framing = "simple"; | ||
747 | |||
748 | devinfo (dev, "open: enable queueing " | ||
749 | "(rx %d, tx %d) mtu %d %s framing", | ||
750 | (int)RX_QLEN (dev), (int)TX_QLEN (dev), dev->net->mtu, | ||
751 | framing); | ||
752 | } | ||
753 | 745 | ||
754 | // delay posting reads until we're fully open | 746 | // delay posting reads until we're fully open |
755 | tasklet_schedule (&dev->bh); | 747 | tasklet_schedule (&dev->bh); |
748 | if (info->manage_power) { | ||
749 | retval = info->manage_power(dev, 1); | ||
750 | if (retval < 0) | ||
751 | goto done; | ||
752 | usb_autopm_put_interface(dev->intf); | ||
753 | } | ||
756 | return retval; | 754 | return retval; |
755 | |||
757 | done: | 756 | done: |
758 | usb_autopm_put_interface(dev->intf); | 757 | usb_autopm_put_interface(dev->intf); |
759 | done_nopm: | 758 | done_nopm: |
@@ -881,13 +880,18 @@ kevent (struct work_struct *work) | |||
881 | /* usb_clear_halt() needs a thread context */ | 880 | /* usb_clear_halt() needs a thread context */ |
882 | if (test_bit (EVENT_TX_HALT, &dev->flags)) { | 881 | if (test_bit (EVENT_TX_HALT, &dev->flags)) { |
883 | unlink_urbs (dev, &dev->txq); | 882 | unlink_urbs (dev, &dev->txq); |
883 | status = usb_autopm_get_interface(dev->intf); | ||
884 | if (status < 0) | ||
885 | goto fail_pipe; | ||
884 | status = usb_clear_halt (dev->udev, dev->out); | 886 | status = usb_clear_halt (dev->udev, dev->out); |
885 | if (status < 0 | 887 | usb_autopm_put_interface(dev->intf); |
886 | && status != -EPIPE | 888 | if (status < 0 && |
887 | && status != -ESHUTDOWN) { | 889 | status != -EPIPE && |
890 | status != -ESHUTDOWN) { | ||
888 | if (netif_msg_tx_err (dev)) | 891 | if (netif_msg_tx_err (dev)) |
889 | deverr (dev, "can't clear tx halt, status %d", | 892 | fail_pipe: |
890 | status); | 893 | netdev_err(dev->net, "can't clear tx halt, status %d\n", |
894 | status); | ||
891 | } else { | 895 | } else { |
892 | clear_bit (EVENT_TX_HALT, &dev->flags); | 896 | clear_bit (EVENT_TX_HALT, &dev->flags); |
893 | if (status != -ESHUTDOWN) | 897 | if (status != -ESHUTDOWN) |
@@ -896,13 +900,18 @@ kevent (struct work_struct *work) | |||
896 | } | 900 | } |
897 | if (test_bit (EVENT_RX_HALT, &dev->flags)) { | 901 | if (test_bit (EVENT_RX_HALT, &dev->flags)) { |
898 | unlink_urbs (dev, &dev->rxq); | 902 | unlink_urbs (dev, &dev->rxq); |
903 | status = usb_autopm_get_interface(dev->intf); | ||
904 | if (status < 0) | ||
905 | goto fail_halt; | ||
899 | status = usb_clear_halt (dev->udev, dev->in); | 906 | status = usb_clear_halt (dev->udev, dev->in); |
900 | if (status < 0 | 907 | usb_autopm_put_interface(dev->intf); |
901 | && status != -EPIPE | 908 | if (status < 0 && |
902 | && status != -ESHUTDOWN) { | 909 | status != -EPIPE && |
910 | status != -ESHUTDOWN) { | ||
903 | if (netif_msg_rx_err (dev)) | 911 | if (netif_msg_rx_err (dev)) |
904 | deverr (dev, "can't clear rx halt, status %d", | 912 | fail_halt: |
905 | status); | 913 | netdev_err(dev->net, "can't clear rx halt, status %d\n", |
914 | status); | ||
906 | } else { | 915 | } else { |
907 | clear_bit (EVENT_RX_HALT, &dev->flags); | 916 | clear_bit (EVENT_RX_HALT, &dev->flags); |
908 | tasklet_schedule (&dev->bh); | 917 | tasklet_schedule (&dev->bh); |
@@ -919,7 +928,12 @@ kevent (struct work_struct *work) | |||
919 | clear_bit (EVENT_RX_MEMORY, &dev->flags); | 928 | clear_bit (EVENT_RX_MEMORY, &dev->flags); |
920 | if (urb != NULL) { | 929 | if (urb != NULL) { |
921 | clear_bit (EVENT_RX_MEMORY, &dev->flags); | 930 | clear_bit (EVENT_RX_MEMORY, &dev->flags); |
931 | status = usb_autopm_get_interface(dev->intf); | ||
932 | if (status < 0) | ||
933 | goto fail_lowmem; | ||
922 | rx_submit (dev, urb, GFP_KERNEL); | 934 | rx_submit (dev, urb, GFP_KERNEL); |
935 | usb_autopm_put_interface(dev->intf); | ||
936 | fail_lowmem: | ||
923 | tasklet_schedule (&dev->bh); | 937 | tasklet_schedule (&dev->bh); |
924 | } | 938 | } |
925 | } | 939 | } |
@@ -929,17 +943,24 @@ kevent (struct work_struct *work) | |||
929 | int retval = 0; | 943 | int retval = 0; |
930 | 944 | ||
931 | clear_bit (EVENT_LINK_RESET, &dev->flags); | 945 | clear_bit (EVENT_LINK_RESET, &dev->flags); |
946 | status = usb_autopm_get_interface(dev->intf); | ||
947 | if (status < 0) | ||
948 | goto skip_reset; | ||
932 | if(info->link_reset && (retval = info->link_reset(dev)) < 0) { | 949 | if(info->link_reset && (retval = info->link_reset(dev)) < 0) { |
933 | devinfo(dev, "link reset failed (%d) usbnet usb-%s-%s, %s", | 950 | usb_autopm_put_interface(dev->intf); |
934 | retval, | 951 | skip_reset: |
935 | dev->udev->bus->bus_name, dev->udev->devpath, | 952 | netdev_info(dev->net, "link reset failed (%d) usbnet usb-%s-%s, %s\n", |
936 | info->description); | 953 | retval, |
954 | dev->udev->bus->bus_name, | ||
955 | dev->udev->devpath, | ||
956 | info->description); | ||
957 | } else { | ||
958 | usb_autopm_put_interface(dev->intf); | ||
937 | } | 959 | } |
938 | } | 960 | } |
939 | 961 | ||
940 | if (dev->flags) | 962 | if (dev->flags) |
941 | devdbg (dev, "kevent done, flags = 0x%lx", | 963 | netdev_dbg(dev->net, "kevent done, flags = 0x%lx\n", dev->flags); |
942 | dev->flags); | ||
943 | } | 964 | } |
944 | 965 | ||
945 | /*-------------------------------------------------------------------------*/ | 966 | /*-------------------------------------------------------------------------*/ |
@@ -971,22 +992,23 @@ static void tx_complete (struct urb *urb) | |||
971 | case -EPROTO: | 992 | case -EPROTO: |
972 | case -ETIME: | 993 | case -ETIME: |
973 | case -EILSEQ: | 994 | case -EILSEQ: |
995 | usb_mark_last_busy(dev->udev); | ||
974 | if (!timer_pending (&dev->delay)) { | 996 | if (!timer_pending (&dev->delay)) { |
975 | mod_timer (&dev->delay, | 997 | mod_timer (&dev->delay, |
976 | jiffies + THROTTLE_JIFFIES); | 998 | jiffies + THROTTLE_JIFFIES); |
977 | if (netif_msg_link (dev)) | 999 | netif_dbg(dev, link, dev->net, |
978 | devdbg (dev, "tx throttle %d", | 1000 | "tx throttle %d\n", urb->status); |
979 | urb->status); | ||
980 | } | 1001 | } |
981 | netif_stop_queue (dev->net); | 1002 | netif_stop_queue (dev->net); |
982 | break; | 1003 | break; |
983 | default: | 1004 | default: |
984 | if (netif_msg_tx_err (dev)) | 1005 | netif_dbg(dev, tx_err, dev->net, |
985 | devdbg (dev, "tx err %d", entry->urb->status); | 1006 | "tx err %d\n", entry->urb->status); |
986 | break; | 1007 | break; |
987 | } | 1008 | } |
988 | } | 1009 | } |
989 | 1010 | ||
1011 | usb_autopm_put_interface_async(dev->intf); | ||
990 | urb->dev = NULL; | 1012 | urb->dev = NULL; |
991 | entry->state = tx_done; | 1013 | entry->state = tx_done; |
992 | defer_bh(dev, skb, &dev->txq); | 1014 | defer_bh(dev, skb, &dev->txq); |
@@ -1023,16 +1045,14 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1023 | if (info->tx_fixup) { | 1045 | if (info->tx_fixup) { |
1024 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); | 1046 | skb = info->tx_fixup (dev, skb, GFP_ATOMIC); |
1025 | if (!skb) { | 1047 | if (!skb) { |
1026 | if (netif_msg_tx_err (dev)) | 1048 | netif_dbg(dev, tx_err, dev->net, "can't tx_fixup skb\n"); |
1027 | devdbg (dev, "can't tx_fixup skb"); | ||
1028 | goto drop; | 1049 | goto drop; |
1029 | } | 1050 | } |
1030 | } | 1051 | } |
1031 | length = skb->len; | 1052 | length = skb->len; |
1032 | 1053 | ||
1033 | if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) { | 1054 | if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) { |
1034 | if (netif_msg_tx_err (dev)) | 1055 | netif_dbg(dev, tx_err, dev->net, "no urb\n"); |
1035 | devdbg (dev, "no urb"); | ||
1036 | goto drop; | 1056 | goto drop; |
1037 | } | 1057 | } |
1038 | 1058 | ||
@@ -1057,16 +1077,36 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1057 | } | 1077 | } |
1058 | } | 1078 | } |
1059 | 1079 | ||
1060 | spin_lock_irqsave (&dev->txq.lock, flags); | 1080 | spin_lock_irqsave(&dev->txq.lock, flags); |
1081 | retval = usb_autopm_get_interface_async(dev->intf); | ||
1082 | if (retval < 0) { | ||
1083 | spin_unlock_irqrestore(&dev->txq.lock, flags); | ||
1084 | goto drop; | ||
1085 | } | ||
1086 | |||
1087 | #ifdef CONFIG_PM | ||
1088 | /* if this triggers the device is still a sleep */ | ||
1089 | if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) { | ||
1090 | /* transmission will be done in resume */ | ||
1091 | usb_anchor_urb(urb, &dev->deferred); | ||
1092 | /* no use to process more packets */ | ||
1093 | netif_stop_queue(net); | ||
1094 | spin_unlock_irqrestore(&dev->txq.lock, flags); | ||
1095 | netdev_dbg(dev->net, "Delaying transmission for resumption\n"); | ||
1096 | goto deferred; | ||
1097 | } | ||
1098 | #endif | ||
1061 | 1099 | ||
1062 | switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { | 1100 | switch ((retval = usb_submit_urb (urb, GFP_ATOMIC))) { |
1063 | case -EPIPE: | 1101 | case -EPIPE: |
1064 | netif_stop_queue (net); | 1102 | netif_stop_queue (net); |
1065 | usbnet_defer_kevent (dev, EVENT_TX_HALT); | 1103 | usbnet_defer_kevent (dev, EVENT_TX_HALT); |
1104 | usb_autopm_put_interface_async(dev->intf); | ||
1066 | break; | 1105 | break; |
1067 | default: | 1106 | default: |
1068 | if (netif_msg_tx_err (dev)) | 1107 | usb_autopm_put_interface_async(dev->intf); |
1069 | devdbg (dev, "tx: submit urb err %d", retval); | 1108 | netif_dbg(dev, tx_err, dev->net, |
1109 | "tx: submit urb err %d\n", retval); | ||
1070 | break; | 1110 | break; |
1071 | case 0: | 1111 | case 0: |
1072 | net->trans_start = jiffies; | 1112 | net->trans_start = jiffies; |
@@ -1077,17 +1117,18 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb, | |||
1077 | spin_unlock_irqrestore (&dev->txq.lock, flags); | 1117 | spin_unlock_irqrestore (&dev->txq.lock, flags); |
1078 | 1118 | ||
1079 | if (retval) { | 1119 | if (retval) { |
1080 | if (netif_msg_tx_err (dev)) | 1120 | netif_dbg(dev, tx_err, dev->net, "drop, code %d\n", retval); |
1081 | devdbg (dev, "drop, code %d", retval); | ||
1082 | drop: | 1121 | drop: |
1083 | dev->net->stats.tx_dropped++; | 1122 | dev->net->stats.tx_dropped++; |
1084 | if (skb) | 1123 | if (skb) |
1085 | dev_kfree_skb_any (skb); | 1124 | dev_kfree_skb_any (skb); |
1086 | usb_free_urb (urb); | 1125 | usb_free_urb (urb); |
1087 | } else if (netif_msg_tx_queued (dev)) { | 1126 | } else |
1088 | devdbg (dev, "> tx, len %d, type 0x%x", | 1127 | netif_dbg(dev, tx_queued, dev->net, |
1089 | length, skb->protocol); | 1128 | "> tx, len %d, type 0x%x\n", length, skb->protocol); |
1090 | } | 1129 | #ifdef CONFIG_PM |
1130 | deferred: | ||
1131 | #endif | ||
1091 | return NETDEV_TX_OK; | 1132 | return NETDEV_TX_OK; |
1092 | } | 1133 | } |
1093 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); | 1134 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); |
@@ -1115,7 +1156,7 @@ static void usbnet_bh (unsigned long param) | |||
1115 | dev_kfree_skb (skb); | 1156 | dev_kfree_skb (skb); |
1116 | continue; | 1157 | continue; |
1117 | default: | 1158 | default: |
1118 | devdbg (dev, "bogus skb state %d", entry->state); | 1159 | netdev_dbg(dev->net, "bogus skb state %d\n", entry->state); |
1119 | } | 1160 | } |
1120 | } | 1161 | } |
1121 | 1162 | ||
@@ -1126,10 +1167,10 @@ static void usbnet_bh (unsigned long param) | |||
1126 | } | 1167 | } |
1127 | 1168 | ||
1128 | // or are we maybe short a few urbs? | 1169 | // or are we maybe short a few urbs? |
1129 | } else if (netif_running (dev->net) | 1170 | } else if (netif_running (dev->net) && |
1130 | && netif_device_present (dev->net) | 1171 | netif_device_present (dev->net) && |
1131 | && !timer_pending (&dev->delay) | 1172 | !timer_pending (&dev->delay) && |
1132 | && !test_bit (EVENT_RX_HALT, &dev->flags)) { | 1173 | !test_bit (EVENT_RX_HALT, &dev->flags)) { |
1133 | int temp = dev->rxq.qlen; | 1174 | int temp = dev->rxq.qlen; |
1134 | int qlen = RX_QLEN (dev); | 1175 | int qlen = RX_QLEN (dev); |
1135 | 1176 | ||
@@ -1143,9 +1184,10 @@ static void usbnet_bh (unsigned long param) | |||
1143 | if (urb != NULL) | 1184 | if (urb != NULL) |
1144 | rx_submit (dev, urb, GFP_ATOMIC); | 1185 | rx_submit (dev, urb, GFP_ATOMIC); |
1145 | } | 1186 | } |
1146 | if (temp != dev->rxq.qlen && netif_msg_link (dev)) | 1187 | if (temp != dev->rxq.qlen) |
1147 | devdbg (dev, "rxqlen %d --> %d", | 1188 | netif_dbg(dev, link, dev->net, |
1148 | temp, dev->rxq.qlen); | 1189 | "rxqlen %d --> %d\n", |
1190 | temp, dev->rxq.qlen); | ||
1149 | if (dev->rxq.qlen < qlen) | 1191 | if (dev->rxq.qlen < qlen) |
1150 | tasklet_schedule (&dev->bh); | 1192 | tasklet_schedule (&dev->bh); |
1151 | } | 1193 | } |
@@ -1176,11 +1218,10 @@ void usbnet_disconnect (struct usb_interface *intf) | |||
1176 | 1218 | ||
1177 | xdev = interface_to_usbdev (intf); | 1219 | xdev = interface_to_usbdev (intf); |
1178 | 1220 | ||
1179 | if (netif_msg_probe (dev)) | 1221 | netif_info(dev, probe, dev->net, "unregister '%s' usb-%s-%s, %s\n", |
1180 | devinfo (dev, "unregister '%s' usb-%s-%s, %s", | 1222 | intf->dev.driver->name, |
1181 | intf->dev.driver->name, | 1223 | xdev->bus->bus_name, xdev->devpath, |
1182 | xdev->bus->bus_name, xdev->devpath, | 1224 | dev->driver_info->description); |
1183 | dev->driver_info->description); | ||
1184 | 1225 | ||
1185 | net = dev->net; | 1226 | net = dev->net; |
1186 | unregister_netdev (net); | 1227 | unregister_netdev (net); |
@@ -1210,6 +1251,14 @@ static const struct net_device_ops usbnet_netdev_ops = { | |||
1210 | 1251 | ||
1211 | // precondition: never called in_interrupt | 1252 | // precondition: never called in_interrupt |
1212 | 1253 | ||
1254 | static struct device_type wlan_type = { | ||
1255 | .name = "wlan", | ||
1256 | }; | ||
1257 | |||
1258 | static struct device_type wwan_type = { | ||
1259 | .name = "wwan", | ||
1260 | }; | ||
1261 | |||
1213 | int | 1262 | int |
1214 | usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | 1263 | usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) |
1215 | { | 1264 | { |
@@ -1255,6 +1304,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1255 | dev->bh.func = usbnet_bh; | 1304 | dev->bh.func = usbnet_bh; |
1256 | dev->bh.data = (unsigned long) dev; | 1305 | dev->bh.data = (unsigned long) dev; |
1257 | INIT_WORK (&dev->kevent, kevent); | 1306 | INIT_WORK (&dev->kevent, kevent); |
1307 | init_usb_anchor(&dev->deferred); | ||
1258 | dev->delay.function = usbnet_bh; | 1308 | dev->delay.function = usbnet_bh; |
1259 | dev->delay.data = (unsigned long) dev; | 1309 | dev->delay.data = (unsigned long) dev; |
1260 | init_timer (&dev->delay); | 1310 | init_timer (&dev->delay); |
@@ -1289,12 +1339,15 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1289 | // heuristic: "usb%d" for links we know are two-host, | 1339 | // heuristic: "usb%d" for links we know are two-host, |
1290 | // else "eth%d" when there's reasonable doubt. userspace | 1340 | // else "eth%d" when there's reasonable doubt. userspace |
1291 | // can rename the link if it knows better. | 1341 | // can rename the link if it knows better. |
1292 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 | 1342 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && |
1293 | && (net->dev_addr [0] & 0x02) == 0) | 1343 | (net->dev_addr [0] & 0x02) == 0) |
1294 | strcpy (net->name, "eth%d"); | 1344 | strcpy (net->name, "eth%d"); |
1295 | /* WLAN devices should always be named "wlan%d" */ | 1345 | /* WLAN devices should always be named "wlan%d" */ |
1296 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) | 1346 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) |
1297 | strcpy(net->name, "wlan%d"); | 1347 | strcpy(net->name, "wlan%d"); |
1348 | /* WWAN devices should always be named "wwan%d" */ | ||
1349 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) | ||
1350 | strcpy(net->name, "wwan%d"); | ||
1298 | 1351 | ||
1299 | /* maybe the remote can't receive an Ethernet MTU */ | 1352 | /* maybe the remote can't receive an Ethernet MTU */ |
1300 | if (net->mtu > (dev->hard_mtu - net->hard_header_len)) | 1353 | if (net->mtu > (dev->hard_mtu - net->hard_header_len)) |
@@ -1322,22 +1375,30 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1322 | dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); | 1375 | dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); |
1323 | 1376 | ||
1324 | SET_NETDEV_DEV(net, &udev->dev); | 1377 | SET_NETDEV_DEV(net, &udev->dev); |
1378 | |||
1379 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) | ||
1380 | SET_NETDEV_DEVTYPE(net, &wlan_type); | ||
1381 | if ((dev->driver_info->flags & FLAG_WWAN) != 0) | ||
1382 | SET_NETDEV_DEVTYPE(net, &wwan_type); | ||
1383 | |||
1325 | status = register_netdev (net); | 1384 | status = register_netdev (net); |
1326 | if (status) | 1385 | if (status) |
1327 | goto out3; | 1386 | goto out3; |
1328 | if (netif_msg_probe (dev)) | 1387 | netif_info(dev, probe, dev->net, |
1329 | devinfo (dev, "register '%s' at usb-%s-%s, %s, %pM", | 1388 | "register '%s' at usb-%s-%s, %s, %pM\n", |
1330 | udev->dev.driver->name, | 1389 | udev->dev.driver->name, |
1331 | xdev->bus->bus_name, xdev->devpath, | 1390 | xdev->bus->bus_name, xdev->devpath, |
1332 | dev->driver_info->description, | 1391 | dev->driver_info->description, |
1333 | net->dev_addr); | 1392 | net->dev_addr); |
1334 | 1393 | ||
1335 | // ok, it's ready to go. | 1394 | // ok, it's ready to go. |
1336 | usb_set_intfdata (udev, dev); | 1395 | usb_set_intfdata (udev, dev); |
1337 | 1396 | ||
1338 | // start as if the link is up | ||
1339 | netif_device_attach (net); | 1397 | netif_device_attach (net); |
1340 | 1398 | ||
1399 | if (dev->driver_info->flags & FLAG_LINK_INTR) | ||
1400 | netif_carrier_off(net); | ||
1401 | |||
1341 | return 0; | 1402 | return 0; |
1342 | 1403 | ||
1343 | out3: | 1404 | out3: |
@@ -1363,13 +1424,23 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) | |||
1363 | struct usbnet *dev = usb_get_intfdata(intf); | 1424 | struct usbnet *dev = usb_get_intfdata(intf); |
1364 | 1425 | ||
1365 | if (!dev->suspend_count++) { | 1426 | if (!dev->suspend_count++) { |
1427 | spin_lock_irq(&dev->txq.lock); | ||
1428 | /* don't autosuspend while transmitting */ | ||
1429 | if (dev->txq.qlen && (message.event & PM_EVENT_AUTO)) { | ||
1430 | spin_unlock_irq(&dev->txq.lock); | ||
1431 | return -EBUSY; | ||
1432 | } else { | ||
1433 | set_bit(EVENT_DEV_ASLEEP, &dev->flags); | ||
1434 | spin_unlock_irq(&dev->txq.lock); | ||
1435 | } | ||
1366 | /* | 1436 | /* |
1367 | * accelerate emptying of the rx and queues, to avoid | 1437 | * accelerate emptying of the rx and queues, to avoid |
1368 | * having everything error out. | 1438 | * having everything error out. |
1369 | */ | 1439 | */ |
1370 | netif_device_detach (dev->net); | 1440 | netif_device_detach (dev->net); |
1371 | (void) unlink_urbs (dev, &dev->rxq); | 1441 | usbnet_terminate_urbs(dev); |
1372 | (void) unlink_urbs (dev, &dev->txq); | 1442 | usb_kill_urb(dev->interrupt); |
1443 | |||
1373 | /* | 1444 | /* |
1374 | * reattach so runtime management can use and | 1445 | * reattach so runtime management can use and |
1375 | * wake the device | 1446 | * wake the device |
@@ -1383,10 +1454,34 @@ EXPORT_SYMBOL_GPL(usbnet_suspend); | |||
1383 | int usbnet_resume (struct usb_interface *intf) | 1454 | int usbnet_resume (struct usb_interface *intf) |
1384 | { | 1455 | { |
1385 | struct usbnet *dev = usb_get_intfdata(intf); | 1456 | struct usbnet *dev = usb_get_intfdata(intf); |
1457 | struct sk_buff *skb; | ||
1458 | struct urb *res; | ||
1459 | int retval; | ||
1460 | |||
1461 | if (!--dev->suspend_count) { | ||
1462 | spin_lock_irq(&dev->txq.lock); | ||
1463 | while ((res = usb_get_from_anchor(&dev->deferred))) { | ||
1464 | |||
1465 | printk(KERN_INFO"%s has delayed data\n", __func__); | ||
1466 | skb = (struct sk_buff *)res->context; | ||
1467 | retval = usb_submit_urb(res, GFP_ATOMIC); | ||
1468 | if (retval < 0) { | ||
1469 | dev_kfree_skb_any(skb); | ||
1470 | usb_free_urb(res); | ||
1471 | usb_autopm_put_interface_async(dev->intf); | ||
1472 | } else { | ||
1473 | dev->net->trans_start = jiffies; | ||
1474 | __skb_queue_tail(&dev->txq, skb); | ||
1475 | } | ||
1476 | } | ||
1386 | 1477 | ||
1387 | if (!--dev->suspend_count) | 1478 | smp_mb(); |
1479 | clear_bit(EVENT_DEV_ASLEEP, &dev->flags); | ||
1480 | spin_unlock_irq(&dev->txq.lock); | ||
1481 | if (!(dev->txq.qlen >= TX_QLEN(dev))) | ||
1482 | netif_start_queue(dev->net); | ||
1388 | tasklet_schedule (&dev->bh); | 1483 | tasklet_schedule (&dev->bh); |
1389 | 1484 | } | |
1390 | return 0; | 1485 | return 0; |
1391 | } | 1486 | } |
1392 | EXPORT_SYMBOL_GPL(usbnet_resume); | 1487 | EXPORT_SYMBOL_GPL(usbnet_resume); |
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index 04882c8f9bf1..3eb0b167b5b4 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c | |||
@@ -174,8 +174,8 @@ static int blan_mdlm_bind(struct usbnet *dev, struct usb_interface *intf) | |||
174 | goto bad_desc; | 174 | goto bad_desc; |
175 | } | 175 | } |
176 | /* expect bcdVersion 1.0, ignore */ | 176 | /* expect bcdVersion 1.0, ignore */ |
177 | if (memcmp(&desc->bGUID, blan_guid, 16) | 177 | if (memcmp(&desc->bGUID, blan_guid, 16) && |
178 | && memcmp(&desc->bGUID, safe_guid, 16) ) { | 178 | memcmp(&desc->bGUID, safe_guid, 16)) { |
179 | /* hey, this one might _really_ be MDLM! */ | 179 | /* hey, this one might _really_ be MDLM! */ |
180 | dev_dbg(&intf->dev, "MDLM guid\n"); | 180 | dev_dbg(&intf->dev, "MDLM guid\n"); |
181 | goto bad_desc; | 181 | goto bad_desc; |