aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/p54/p54usb.c')
-rw-r--r--drivers/net/wireless/p54/p54usb.c87
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
427static const char p54u_romboot_3887[] = "~~~~";
428static const char p54u_firmware_upload_3887[] = "<\r";
429
430static 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
427static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) 465static 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
1010static int p54u_pre_reset(struct usb_interface *intf)
1011{
1012 return 0;
1013}
1014
1015static int p54u_post_reset(struct usb_interface *intf)
1016{
1017 return 0;
1018}
1019
961static struct usb_driver p54u_driver = { 1020static 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
968static int __init p54u_init(void) 1029static int __init p54u_init(void)