diff options
Diffstat (limited to 'drivers/net/wireless/p54/p54usb.c')
-rw-r--r-- | drivers/net/wireless/p54/p54usb.c | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 5de2ebfb28c7..9539ddcf379f 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -424,9 +424,46 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep, | |||
424 | data, len, &alen, 2000); | 424 | data, len, &alen, 2000); |
425 | } | 425 | } |
426 | 426 | ||
427 | static const char p54u_romboot_3887[] = "~~~~"; | ||
428 | static const char p54u_firmware_upload_3887[] = "<\r"; | ||
429 | |||
430 | static int p54u_device_reset_3887(struct ieee80211_hw *dev) | ||
431 | { | ||
432 | struct p54u_priv *priv = dev->priv; | ||
433 | int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING); | ||
434 | u8 buf[4]; | ||
435 | |||
436 | if (lock) { | ||
437 | ret = usb_lock_device_for_reset(priv->udev, priv->intf); | ||
438 | if (ret < 0) { | ||
439 | dev_err(&priv->udev->dev, "(p54usb) unable to lock " | ||
440 | " device for reset: %d\n", ret); | ||
441 | return ret; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | ret = usb_reset_device(priv->udev); | ||
446 | if (lock) | ||
447 | usb_unlock_device(priv->udev); | ||
448 | |||
449 | if (ret) { | ||
450 | dev_err(&priv->udev->dev, "(p54usb) unable to reset " | ||
451 | "device: %d\n", ret); | ||
452 | return ret; | ||
453 | } | ||
454 | |||
455 | memcpy(&buf, p54u_romboot_3887, sizeof(buf)); | ||
456 | ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, | ||
457 | buf, sizeof(buf)); | ||
458 | if (ret) | ||
459 | dev_err(&priv->udev->dev, "(p54usb) unable to jump to " | ||
460 | "boot ROM: %d\n", ret); | ||
461 | |||
462 | return ret; | ||
463 | } | ||
464 | |||
427 | static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | 465 | static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) |
428 | { | 466 | { |
429 | static char start_string[] = "~~~~<\r"; | ||
430 | struct p54u_priv *priv = dev->priv; | 467 | struct p54u_priv *priv = dev->priv; |
431 | const struct firmware *fw_entry = NULL; | 468 | const struct firmware *fw_entry = NULL; |
432 | int err, alen; | 469 | int err, alen; |
@@ -445,12 +482,9 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
445 | goto err_bufalloc; | 482 | goto err_bufalloc; |
446 | } | 483 | } |
447 | 484 | ||
448 | memcpy(buf, start_string, 4); | 485 | err = p54u_device_reset_3887(dev); |
449 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4); | 486 | if (err) |
450 | if (err) { | ||
451 | dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err); | ||
452 | goto err_reset; | 487 | goto err_reset; |
453 | } | ||
454 | 488 | ||
455 | err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); | 489 | err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); |
456 | if (err) { | 490 | if (err) { |
@@ -466,15 +500,22 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
466 | if (err) | 500 | if (err) |
467 | goto err_upload_failed; | 501 | goto err_upload_failed; |
468 | 502 | ||
503 | if (priv->common.fw_interface != FW_LM87) { | ||
504 | dev_err(&priv->udev->dev, "wrong firmware, " | ||
505 | "please get a LM87 firmware and try again.\n"); | ||
506 | err = -EINVAL; | ||
507 | goto err_upload_failed; | ||
508 | } | ||
509 | |||
469 | left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); | 510 | left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); |
470 | strcpy(buf, start_string); | 511 | strcpy(buf, p54u_firmware_upload_3887); |
471 | left -= strlen(start_string); | 512 | left -= strlen(p54u_firmware_upload_3887); |
472 | tmp += strlen(start_string); | 513 | tmp += strlen(p54u_firmware_upload_3887); |
473 | 514 | ||
474 | data = fw_entry->data; | 515 | data = fw_entry->data; |
475 | remains = fw_entry->size; | 516 | remains = fw_entry->size; |
476 | 517 | ||
477 | hdr = (struct x2_header *)(buf + strlen(start_string)); | 518 | hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887)); |
478 | memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE); | 519 | memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE); |
479 | hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR); | 520 | hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR); |
480 | hdr->fw_length = cpu_to_le32(fw_entry->size); | 521 | hdr->fw_length = cpu_to_le32(fw_entry->size); |
@@ -616,6 +657,14 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) | |||
616 | return err; | 657 | return err; |
617 | } | 658 | } |
618 | 659 | ||
660 | if (priv->common.fw_interface != FW_LM86) { | ||
661 | dev_err(&priv->udev->dev, "wrong firmware, " | ||
662 | "please get a LM86(USB) firmware and try again.\n"); | ||
663 | kfree(buf); | ||
664 | release_firmware(fw_entry); | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | |||
619 | #define P54U_WRITE(type, addr, data) \ | 668 | #define P54U_WRITE(type, addr, data) \ |
620 | do {\ | 669 | do {\ |
621 | err = p54u_write(priv, buf, type,\ | 670 | err = p54u_write(priv, buf, type,\ |
@@ -876,6 +925,9 @@ static int __devinit p54u_probe(struct usb_interface *intf, | |||
876 | SET_IEEE80211_DEV(dev, &intf->dev); | 925 | SET_IEEE80211_DEV(dev, &intf->dev); |
877 | usb_set_intfdata(intf, dev); | 926 | usb_set_intfdata(intf, dev); |
878 | priv->udev = udev; | 927 | priv->udev = udev; |
928 | priv->intf = intf; | ||
929 | skb_queue_head_init(&priv->rx_queue); | ||
930 | init_usb_anchor(&priv->submitted); | ||
879 | 931 | ||
880 | usb_get_dev(udev); | 932 | usb_get_dev(udev); |
881 | 933 | ||
@@ -918,9 +970,6 @@ static int __devinit p54u_probe(struct usb_interface *intf, | |||
918 | if (err) | 970 | if (err) |
919 | goto err_free_dev; | 971 | goto err_free_dev; |
920 | 972 | ||
921 | skb_queue_head_init(&priv->rx_queue); | ||
922 | init_usb_anchor(&priv->submitted); | ||
923 | |||
924 | p54u_open(dev); | 973 | p54u_open(dev); |
925 | err = p54_read_eeprom(dev); | 974 | err = p54_read_eeprom(dev); |
926 | p54u_stop(dev); | 975 | p54u_stop(dev); |
@@ -958,11 +1007,23 @@ static void __devexit p54u_disconnect(struct usb_interface *intf) | |||
958 | ieee80211_free_hw(dev); | 1007 | ieee80211_free_hw(dev); |
959 | } | 1008 | } |
960 | 1009 | ||
1010 | static int p54u_pre_reset(struct usb_interface *intf) | ||
1011 | { | ||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int p54u_post_reset(struct usb_interface *intf) | ||
1016 | { | ||
1017 | return 0; | ||
1018 | } | ||
1019 | |||
961 | static struct usb_driver p54u_driver = { | 1020 | static struct usb_driver p54u_driver = { |
962 | .name = "p54usb", | 1021 | .name = "p54usb", |
963 | .id_table = p54u_table, | 1022 | .id_table = p54u_table, |
964 | .probe = p54u_probe, | 1023 | .probe = p54u_probe, |
965 | .disconnect = p54u_disconnect, | 1024 | .disconnect = p54u_disconnect, |
1025 | .pre_reset = p54u_pre_reset, | ||
1026 | .post_reset = p54u_post_reset, | ||
966 | }; | 1027 | }; |
967 | 1028 | ||
968 | static int __init p54u_init(void) | 1029 | static int __init p54u_init(void) |