Loading drivers/net/wireless/p54/p54usb.c +165 −91 Original line number Diff line number Diff line Loading @@ -81,6 +81,29 @@ static struct usb_device_id p54u_table[] __devinitdata = { MODULE_DEVICE_TABLE(usb, p54u_table); static const struct { u32 intf; enum p54u_hw_type type; char fw[FIRMWARE_NAME_MAX]; char fw_legacy[FIRMWARE_NAME_MAX]; char hw[20]; } p54u_fwlist[__NUM_P54U_HWTYPES] = { { .type = P54U_NET2280, .intf = FW_LM86, .fw = "isl3886usb", .fw_legacy = "isl3890usb", .hw = "ISL3886 + net2280", }, { .type = P54U_3887, .intf = FW_LM87, .fw = "isl3887usb", .fw_legacy = "isl3887usb_bare", .hw = "ISL3887", }, }; static void p54u_rx_cb(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *) urb->context; Loading Loading @@ -125,12 +148,8 @@ static void p54u_rx_cb(struct urb *urb) } skb_reset_tail_pointer(skb); skb_trim(skb, 0); if (urb->transfer_buffer != skb_tail_pointer(skb)) { /* this should not happen */ WARN_ON(1); urb->transfer_buffer = skb_tail_pointer(skb); } } skb_queue_tail(&priv->rx_queue, skb); usb_anchor_urb(urb, &priv->submitted); if (usb_submit_urb(urb, GFP_ATOMIC)) { Loading Loading @@ -378,20 +397,16 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep, data, len, &alen, 2000); } static const char p54u_romboot_3887[] = "~~~~"; static const char p54u_firmware_upload_3887[] = "<\r"; static int p54u_device_reset_3887(struct ieee80211_hw *dev) static int p54u_device_reset(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING); u8 buf[4]; if (lock) { ret = usb_lock_device_for_reset(priv->udev, priv->intf); if (ret < 0) { dev_err(&priv->udev->dev, "(p54usb) unable to lock " " device for reset: %d\n", ret); "device for reset (%d)!\n", ret); return ret; } } Loading @@ -400,26 +415,34 @@ static int p54u_device_reset_3887(struct ieee80211_hw *dev) if (lock) usb_unlock_device(priv->udev); if (ret) { if (ret) dev_err(&priv->udev->dev, "(p54usb) unable to reset " "device: %d\n", ret); "device (%d)!\n", ret); return ret; } static const char p54u_romboot_3887[] = "~~~~"; static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; u8 buf[4]; int ret; memcpy(&buf, p54u_romboot_3887, sizeof(buf)); ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(buf)); if (ret) dev_err(&priv->udev->dev, "(p54usb) unable to jump to " "boot ROM: %d\n", ret); "boot ROM (%d)!\n", ret); return ret; } static const char p54u_firmware_upload_3887[] = "<\r"; static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; const struct firmware *fw_entry = NULL; int err, alen; u8 carry = 0; u8 *buf, *tmp; Loading @@ -428,51 +451,29 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) struct x2_header *hdr; unsigned long timeout; err = p54u_firmware_reset_3887(dev); if (err) return err; tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL); if (!buf) { dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware" "upload buffer!\n"); err = -ENOMEM; goto err_bufalloc; } err = p54u_device_reset_3887(dev); if (err) goto err_reset; err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); if (err) { dev_err(&priv->udev->dev, "p54usb: cannot find firmware " "(isl3887usb)\n"); err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev); if (err) goto err_req_fw_failed; } err = p54_parse_firmware(dev, fw_entry); if (err) goto err_upload_failed; if (priv->common.fw_interface != FW_LM87) { dev_err(&priv->udev->dev, "wrong firmware, " "please get a LM87 firmware and try again.\n"); err = -EINVAL; goto err_upload_failed; return -ENOMEM; } left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size); strcpy(buf, p54u_firmware_upload_3887); left -= strlen(p54u_firmware_upload_3887); tmp += strlen(p54u_firmware_upload_3887); data = fw_entry->data; remains = fw_entry->size; data = priv->fw->data; remains = priv->fw->size; hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887)); memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE); hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR); hdr->fw_length = cpu_to_le32(fw_entry->size); hdr->fw_length = cpu_to_le32(priv->fw->size); hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr, sizeof(u32)*2)); left -= sizeof(*hdr); Loading Loading @@ -514,7 +515,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) left = block_size = min((unsigned int)P54U_FW_BLOCK, remains); } *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size)); *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data, priv->fw->size)); err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32)); if (err) { dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n"); Loading Loading @@ -566,18 +568,13 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) goto err_upload_failed; err_upload_failed: release_firmware(fw_entry); err_req_fw_failed: err_reset: kfree(buf); err_bufalloc: return err; } static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; const struct firmware *fw_entry = NULL; const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE; int err, alen; void *buf; Loading @@ -592,33 +589,6 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) return -ENOMEM; } err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev); if (err) { dev_err(&priv->udev->dev, "(p54usb) cannot find firmware " "(isl3886usb)\n"); err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev); if (err) { kfree(buf); return err; } } err = p54_parse_firmware(dev, fw_entry); if (err) { kfree(buf); release_firmware(fw_entry); return err; } if (priv->common.fw_interface != FW_LM86) { dev_err(&priv->udev->dev, "wrong firmware, " "please get a LM86(USB) firmware and try again.\n"); kfree(buf); release_firmware(fw_entry); return -EINVAL; } #define P54U_WRITE(type, addr, data) \ do {\ err = p54u_write(priv, buf, type,\ Loading Loading @@ -718,8 +688,8 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg); /* finally, we can upload firmware now! */ remains = fw_entry->size; data = fw_entry->data; remains = priv->fw->size; data = priv->fw->data; offset = ISL38XX_DEV_FIRMWARE_ADDR; while (remains) { Loading Loading @@ -829,11 +799,53 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) #undef P54U_READ fail: release_firmware(fw_entry); kfree(buf); return err; } static int p54u_load_firmware(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; int err, i; BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES); for (i = 0; i < __NUM_P54U_HWTYPES; i++) if (p54u_fwlist[i].type == priv->hw_type) break; if (i == __NUM_P54U_HWTYPES) return -EOPNOTSUPP; err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev); if (err) { dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " "(%d)!\n", p54u_fwlist[i].fw, err); err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy, &priv->udev->dev); if (err) return err; } err = p54_parse_firmware(dev, priv->fw); if (err) goto out; if (priv->common.fw_interface != p54u_fwlist[i].intf) { dev_err(&priv->udev->dev, "wrong firmware, please get " "a firmware for \"%s\" and try again.\n", p54u_fwlist[i].hw); err = -EINVAL; } out: if (err) release_firmware(priv->fw); return err; } static int p54u_open(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; Loading Loading @@ -875,6 +887,7 @@ static int __devinit p54u_probe(struct usb_interface *intf, } priv = dev->priv; priv->hw_type = P54U_INVALID_HW; SET_IEEE80211_DEV(dev, &intf->dev); usb_set_intfdata(intf, dev); Loading Loading @@ -906,33 +919,45 @@ static int __devinit p54u_probe(struct usb_interface *intf, priv->common.open = p54u_open; priv->common.stop = p54u_stop; if (recognized_pipes < P54U_PIPE_NUMBER) { /* ISL3887 needs a full reset on resume */ udev->reset_resume = 1; err = p54u_device_reset(dev); priv->hw_type = P54U_3887; dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr); priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr); priv->common.tx = p54u_tx_lm87; err = p54u_upload_firmware_3887(dev); priv->upload_fw = p54u_upload_firmware_3887; } else { priv->hw_type = P54U_NET2280; dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr); priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr); priv->common.tx = p54u_tx_net2280; err = p54u_upload_firmware_net2280(dev); priv->upload_fw = p54u_upload_firmware_net2280; } err = p54u_load_firmware(dev); if (err) goto err_free_dev; err = priv->upload_fw(dev); if (err) goto err_free_fw; p54u_open(dev); err = p54_read_eeprom(dev); p54u_stop(dev); if (err) goto err_free_dev; goto err_free_fw; err = p54_register_common(dev, &udev->dev); if (err) goto err_free_dev; goto err_free_fw; return 0; err_free_fw: release_firmware(priv->fw); err_free_dev: ieee80211_free_hw(dev); usb_set_intfdata(intf, NULL); Loading @@ -952,20 +977,64 @@ static void __devexit p54u_disconnect(struct usb_interface *intf) priv = dev->priv; usb_put_dev(interface_to_usbdev(intf)); release_firmware(priv->fw); p54_free_common(dev); ieee80211_free_hw(dev); } static int p54u_pre_reset(struct usb_interface *intf) { struct ieee80211_hw *dev = usb_get_intfdata(intf); if (!dev) return -ENODEV; p54u_stop(dev); return 0; } static int p54u_resume(struct usb_interface *intf) { struct ieee80211_hw *dev = usb_get_intfdata(intf); struct p54u_priv *priv; if (!dev) return -ENODEV; priv = dev->priv; if (unlikely(!(priv->upload_fw && priv->fw))) return 0; return priv->upload_fw(dev); } static int p54u_post_reset(struct usb_interface *intf) { struct ieee80211_hw *dev = usb_get_intfdata(intf); struct p54u_priv *priv; int err; err = p54u_resume(intf); if (err) return err; /* reinitialize old device state */ priv = dev->priv; if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) ieee80211_restart_hw(dev); return 0; } #ifdef CONFIG_PM static int p54u_suspend(struct usb_interface *intf, pm_message_t message) { return p54u_pre_reset(intf); } #endif /* CONFIG_PM */ static struct usb_driver p54u_driver = { .name = "p54usb", .id_table = p54u_table, Loading @@ -973,6 +1042,11 @@ static struct usb_driver p54u_driver = { .disconnect = p54u_disconnect, .pre_reset = p54u_pre_reset, .post_reset = p54u_post_reset, #ifdef CONFIG_PM .suspend = p54u_suspend, .resume = p54u_resume, .reset_resume = p54u_resume, #endif /* CONFIG_PM */ .soft_unbind = 1, }; Loading drivers/net/wireless/p54/p54usb.h +12 −4 Original line number Diff line number Diff line Loading @@ -123,18 +123,26 @@ struct p54u_rx_info { struct ieee80211_hw *dev; }; enum p54u_hw_type { P54U_INVALID_HW, P54U_NET2280, P54U_3887, /* keep last */ __NUM_P54U_HWTYPES, }; struct p54u_priv { struct p54_common common; struct usb_device *udev; struct usb_interface *intf; enum { P54U_NET2280 = 0, P54U_3887 } hw_type; int (*upload_fw)(struct ieee80211_hw *dev); enum p54u_hw_type hw_type; spinlock_t lock; struct sk_buff_head rx_queue; struct usb_anchor submitted; const struct firmware *fw; }; #endif /* P54USB_H */ Loading
drivers/net/wireless/p54/p54usb.c +165 −91 Original line number Diff line number Diff line Loading @@ -81,6 +81,29 @@ static struct usb_device_id p54u_table[] __devinitdata = { MODULE_DEVICE_TABLE(usb, p54u_table); static const struct { u32 intf; enum p54u_hw_type type; char fw[FIRMWARE_NAME_MAX]; char fw_legacy[FIRMWARE_NAME_MAX]; char hw[20]; } p54u_fwlist[__NUM_P54U_HWTYPES] = { { .type = P54U_NET2280, .intf = FW_LM86, .fw = "isl3886usb", .fw_legacy = "isl3890usb", .hw = "ISL3886 + net2280", }, { .type = P54U_3887, .intf = FW_LM87, .fw = "isl3887usb", .fw_legacy = "isl3887usb_bare", .hw = "ISL3887", }, }; static void p54u_rx_cb(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *) urb->context; Loading Loading @@ -125,12 +148,8 @@ static void p54u_rx_cb(struct urb *urb) } skb_reset_tail_pointer(skb); skb_trim(skb, 0); if (urb->transfer_buffer != skb_tail_pointer(skb)) { /* this should not happen */ WARN_ON(1); urb->transfer_buffer = skb_tail_pointer(skb); } } skb_queue_tail(&priv->rx_queue, skb); usb_anchor_urb(urb, &priv->submitted); if (usb_submit_urb(urb, GFP_ATOMIC)) { Loading Loading @@ -378,20 +397,16 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep, data, len, &alen, 2000); } static const char p54u_romboot_3887[] = "~~~~"; static const char p54u_firmware_upload_3887[] = "<\r"; static int p54u_device_reset_3887(struct ieee80211_hw *dev) static int p54u_device_reset(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING); u8 buf[4]; if (lock) { ret = usb_lock_device_for_reset(priv->udev, priv->intf); if (ret < 0) { dev_err(&priv->udev->dev, "(p54usb) unable to lock " " device for reset: %d\n", ret); "device for reset (%d)!\n", ret); return ret; } } Loading @@ -400,26 +415,34 @@ static int p54u_device_reset_3887(struct ieee80211_hw *dev) if (lock) usb_unlock_device(priv->udev); if (ret) { if (ret) dev_err(&priv->udev->dev, "(p54usb) unable to reset " "device: %d\n", ret); "device (%d)!\n", ret); return ret; } static const char p54u_romboot_3887[] = "~~~~"; static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; u8 buf[4]; int ret; memcpy(&buf, p54u_romboot_3887, sizeof(buf)); ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(buf)); if (ret) dev_err(&priv->udev->dev, "(p54usb) unable to jump to " "boot ROM: %d\n", ret); "boot ROM (%d)!\n", ret); return ret; } static const char p54u_firmware_upload_3887[] = "<\r"; static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; const struct firmware *fw_entry = NULL; int err, alen; u8 carry = 0; u8 *buf, *tmp; Loading @@ -428,51 +451,29 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) struct x2_header *hdr; unsigned long timeout; err = p54u_firmware_reset_3887(dev); if (err) return err; tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL); if (!buf) { dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware" "upload buffer!\n"); err = -ENOMEM; goto err_bufalloc; } err = p54u_device_reset_3887(dev); if (err) goto err_reset; err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); if (err) { dev_err(&priv->udev->dev, "p54usb: cannot find firmware " "(isl3887usb)\n"); err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev); if (err) goto err_req_fw_failed; } err = p54_parse_firmware(dev, fw_entry); if (err) goto err_upload_failed; if (priv->common.fw_interface != FW_LM87) { dev_err(&priv->udev->dev, "wrong firmware, " "please get a LM87 firmware and try again.\n"); err = -EINVAL; goto err_upload_failed; return -ENOMEM; } left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size); strcpy(buf, p54u_firmware_upload_3887); left -= strlen(p54u_firmware_upload_3887); tmp += strlen(p54u_firmware_upload_3887); data = fw_entry->data; remains = fw_entry->size; data = priv->fw->data; remains = priv->fw->size; hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887)); memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE); hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR); hdr->fw_length = cpu_to_le32(fw_entry->size); hdr->fw_length = cpu_to_le32(priv->fw->size); hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr, sizeof(u32)*2)); left -= sizeof(*hdr); Loading Loading @@ -514,7 +515,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) left = block_size = min((unsigned int)P54U_FW_BLOCK, remains); } *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size)); *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data, priv->fw->size)); err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32)); if (err) { dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n"); Loading Loading @@ -566,18 +568,13 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) goto err_upload_failed; err_upload_failed: release_firmware(fw_entry); err_req_fw_failed: err_reset: kfree(buf); err_bufalloc: return err; } static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; const struct firmware *fw_entry = NULL; const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE; int err, alen; void *buf; Loading @@ -592,33 +589,6 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) return -ENOMEM; } err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev); if (err) { dev_err(&priv->udev->dev, "(p54usb) cannot find firmware " "(isl3886usb)\n"); err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev); if (err) { kfree(buf); return err; } } err = p54_parse_firmware(dev, fw_entry); if (err) { kfree(buf); release_firmware(fw_entry); return err; } if (priv->common.fw_interface != FW_LM86) { dev_err(&priv->udev->dev, "wrong firmware, " "please get a LM86(USB) firmware and try again.\n"); kfree(buf); release_firmware(fw_entry); return -EINVAL; } #define P54U_WRITE(type, addr, data) \ do {\ err = p54u_write(priv, buf, type,\ Loading Loading @@ -718,8 +688,8 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg); /* finally, we can upload firmware now! */ remains = fw_entry->size; data = fw_entry->data; remains = priv->fw->size; data = priv->fw->data; offset = ISL38XX_DEV_FIRMWARE_ADDR; while (remains) { Loading Loading @@ -829,11 +799,53 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) #undef P54U_READ fail: release_firmware(fw_entry); kfree(buf); return err; } static int p54u_load_firmware(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; int err, i; BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES); for (i = 0; i < __NUM_P54U_HWTYPES; i++) if (p54u_fwlist[i].type == priv->hw_type) break; if (i == __NUM_P54U_HWTYPES) return -EOPNOTSUPP; err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev); if (err) { dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " "(%d)!\n", p54u_fwlist[i].fw, err); err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy, &priv->udev->dev); if (err) return err; } err = p54_parse_firmware(dev, priv->fw); if (err) goto out; if (priv->common.fw_interface != p54u_fwlist[i].intf) { dev_err(&priv->udev->dev, "wrong firmware, please get " "a firmware for \"%s\" and try again.\n", p54u_fwlist[i].hw); err = -EINVAL; } out: if (err) release_firmware(priv->fw); return err; } static int p54u_open(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; Loading Loading @@ -875,6 +887,7 @@ static int __devinit p54u_probe(struct usb_interface *intf, } priv = dev->priv; priv->hw_type = P54U_INVALID_HW; SET_IEEE80211_DEV(dev, &intf->dev); usb_set_intfdata(intf, dev); Loading Loading @@ -906,33 +919,45 @@ static int __devinit p54u_probe(struct usb_interface *intf, priv->common.open = p54u_open; priv->common.stop = p54u_stop; if (recognized_pipes < P54U_PIPE_NUMBER) { /* ISL3887 needs a full reset on resume */ udev->reset_resume = 1; err = p54u_device_reset(dev); priv->hw_type = P54U_3887; dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr); priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr); priv->common.tx = p54u_tx_lm87; err = p54u_upload_firmware_3887(dev); priv->upload_fw = p54u_upload_firmware_3887; } else { priv->hw_type = P54U_NET2280; dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr); priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr); priv->common.tx = p54u_tx_net2280; err = p54u_upload_firmware_net2280(dev); priv->upload_fw = p54u_upload_firmware_net2280; } err = p54u_load_firmware(dev); if (err) goto err_free_dev; err = priv->upload_fw(dev); if (err) goto err_free_fw; p54u_open(dev); err = p54_read_eeprom(dev); p54u_stop(dev); if (err) goto err_free_dev; goto err_free_fw; err = p54_register_common(dev, &udev->dev); if (err) goto err_free_dev; goto err_free_fw; return 0; err_free_fw: release_firmware(priv->fw); err_free_dev: ieee80211_free_hw(dev); usb_set_intfdata(intf, NULL); Loading @@ -952,20 +977,64 @@ static void __devexit p54u_disconnect(struct usb_interface *intf) priv = dev->priv; usb_put_dev(interface_to_usbdev(intf)); release_firmware(priv->fw); p54_free_common(dev); ieee80211_free_hw(dev); } static int p54u_pre_reset(struct usb_interface *intf) { struct ieee80211_hw *dev = usb_get_intfdata(intf); if (!dev) return -ENODEV; p54u_stop(dev); return 0; } static int p54u_resume(struct usb_interface *intf) { struct ieee80211_hw *dev = usb_get_intfdata(intf); struct p54u_priv *priv; if (!dev) return -ENODEV; priv = dev->priv; if (unlikely(!(priv->upload_fw && priv->fw))) return 0; return priv->upload_fw(dev); } static int p54u_post_reset(struct usb_interface *intf) { struct ieee80211_hw *dev = usb_get_intfdata(intf); struct p54u_priv *priv; int err; err = p54u_resume(intf); if (err) return err; /* reinitialize old device state */ priv = dev->priv; if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) ieee80211_restart_hw(dev); return 0; } #ifdef CONFIG_PM static int p54u_suspend(struct usb_interface *intf, pm_message_t message) { return p54u_pre_reset(intf); } #endif /* CONFIG_PM */ static struct usb_driver p54u_driver = { .name = "p54usb", .id_table = p54u_table, Loading @@ -973,6 +1042,11 @@ static struct usb_driver p54u_driver = { .disconnect = p54u_disconnect, .pre_reset = p54u_pre_reset, .post_reset = p54u_post_reset, #ifdef CONFIG_PM .suspend = p54u_suspend, .resume = p54u_resume, .reset_resume = p54u_resume, #endif /* CONFIG_PM */ .soft_unbind = 1, }; Loading
drivers/net/wireless/p54/p54usb.h +12 −4 Original line number Diff line number Diff line Loading @@ -123,18 +123,26 @@ struct p54u_rx_info { struct ieee80211_hw *dev; }; enum p54u_hw_type { P54U_INVALID_HW, P54U_NET2280, P54U_3887, /* keep last */ __NUM_P54U_HWTYPES, }; struct p54u_priv { struct p54_common common; struct usb_device *udev; struct usb_interface *intf; enum { P54U_NET2280 = 0, P54U_3887 } hw_type; int (*upload_fw)(struct ieee80211_hw *dev); enum p54u_hw_type hw_type; spinlock_t lock; struct sk_buff_head rx_queue; struct usb_anchor submitted; const struct firmware *fw; }; #endif /* P54USB_H */