--- zzzz-none-000/linux-3.10.107/drivers/net/wireless/ath/ath9k/hif_usb.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/net/wireless/ath/ath9k/hif_usb.c 2021-02-04 17:41:59.000000000 +0000 @@ -17,12 +17,8 @@ #include #include "htc.h" -/* identify firmware images */ -#define FIRMWARE_AR7010_1_1 "htc_7010.fw" -#define FIRMWARE_AR9271 "htc_9271.fw" - -MODULE_FIRMWARE(FIRMWARE_AR7010_1_1); -MODULE_FIRMWARE(FIRMWARE_AR9271); +MODULE_FIRMWARE(HTC_7010_MODULE_FW); +MODULE_FIRMWARE(HTC_9271_MODULE_FW); static struct usb_device_id ath9k_hif_usb_ids[] = { { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */ @@ -40,6 +36,7 @@ { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */ { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ + { USB_DEVICE(0x0471, 0x209e) }, /* Philips (or NXP) PTA01 */ { USB_DEVICE(0x0cf3, 0x7015), .driver_info = AR9287_USB }, /* Atheros */ @@ -54,6 +51,8 @@ .driver_info = AR9280_USB }, /* SMC Networks */ { USB_DEVICE(0x0411, 0x017f), .driver_info = AR9280_USB }, /* Sony UWA-BR100 */ + { USB_DEVICE(0x0411, 0x0197), + .driver_info = AR9280_USB }, /* Buffalo WLI-UV-AG300P */ { USB_DEVICE(0x04da, 0x3904), .driver_info = AR9280_USB }, @@ -115,10 +114,10 @@ cmd->skb = skb; cmd->hif_dev = hif_dev; - usb_fill_bulk_urb(urb, hif_dev->udev, - usb_sndbulkpipe(hif_dev->udev, USB_REG_OUT_PIPE), + usb_fill_int_urb(urb, hif_dev->udev, + usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE), skb->data, skb->len, - hif_usb_regout_cb, cmd); + hif_usb_regout_cb, cmd, 1); usb_anchor_urb(urb, &hif_dev->regout_submitted); ret = usb_submit_urb(urb, GFP_KERNEL); @@ -234,10 +233,15 @@ struct sk_buff *skb; while ((skb = __skb_dequeue(queue)) != NULL) { +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + int ln = skb->len; +#endif ath9k_htc_txcompletion_cb(hif_dev->htc_handle, skb, txok); - if (txok) + if (txok) { TX_STAT_INC(skb_success); + TX_STAT_ADD(skb_success_bytes, ln); + } else TX_STAT_INC(skb_failed); } @@ -620,6 +624,7 @@ err: for (i = 0; i < pool_index; i++) { + RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len); ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], skb_pool[i]->len, USB_WLAN_RX_PIPE); RX_STAT_INC(skb_completed); @@ -717,11 +722,11 @@ return; } - usb_fill_bulk_urb(urb, hif_dev->udev, - usb_rcvbulkpipe(hif_dev->udev, + usb_fill_int_urb(urb, hif_dev->udev, + usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, nskb); + ath9k_hif_usb_reg_in_cb, nskb, 1); } resubmit: @@ -903,11 +908,11 @@ goto err_skb; } - usb_fill_bulk_urb(urb, hif_dev->udev, - usb_rcvbulkpipe(hif_dev->udev, + usb_fill_int_urb(urb, hif_dev->udev, + usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb); + ath9k_hif_usb_reg_in_cb, skb, 1); /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->reg_in_submitted); @@ -1025,9 +1030,7 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { - struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; - struct usb_endpoint_descriptor *endp; - int ret, idx; + int ret; ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { @@ -1037,20 +1040,6 @@ return ret; } - /* On downloading the firmware to the target, the USB descriptor of EP4 - * is 'patched' to change the type of the endpoint to Bulk. This will - * bring down CPU usage during the scan period. - */ - for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) { - endp = &alt->endpoint[idx].desc; - if ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_INT) { - endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK; - endp->bmAttributes |= USB_ENDPOINT_XFER_BULK; - endp->bInterval = 0; - } - } - /* Alloc URBs */ ret = ath9k_hif_usb_alloc_urbs(hif_dev); if (ret) { @@ -1076,7 +1065,7 @@ struct device *dev = &hif_dev->udev->dev; struct device *parent = dev->parent; - complete(&hif_dev->fw_done); + complete_all(&hif_dev->fw_done); if (parent) device_lock(parent); @@ -1087,12 +1076,88 @@ device_unlock(parent); } +static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context); + +/* taken from iwlwifi */ +static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev, + bool first) +{ + char index[8], *chip; + int ret; + + if (first) { + if (htc_use_dev_fw) { + hif_dev->fw_minor_index = FIRMWARE_MINOR_IDX_MAX + 1; + sprintf(index, "%s", "dev"); + } else { + hif_dev->fw_minor_index = FIRMWARE_MINOR_IDX_MAX; + sprintf(index, "%d", hif_dev->fw_minor_index); + } + } else { + hif_dev->fw_minor_index--; + sprintf(index, "%d", hif_dev->fw_minor_index); + } + + /* test for FW 1.3 */ + if (MAJOR_VERSION_REQ == 1 && hif_dev->fw_minor_index == 3) { + const char *filename; + + if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info)) + filename = FIRMWARE_AR7010_1_1; + else + filename = FIRMWARE_AR9271; + + /* expected fw locations: + * - htc_9271.fw (stable version 1.3, depricated) + */ + snprintf(hif_dev->fw_name, sizeof(hif_dev->fw_name), + "%s", filename); + + } else if (hif_dev->fw_minor_index < FIRMWARE_MINOR_IDX_MIN) { + dev_err(&hif_dev->udev->dev, "no suitable firmware found!\n"); + + return -ENOENT; + } else { + if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info)) + chip = "7010"; + else + chip = "9271"; + + /* expected fw locations: + * - ath9k_htc/htc_9271-1.dev.0.fw (development version) + * - ath9k_htc/htc_9271-1.4.0.fw (stable version) + */ + snprintf(hif_dev->fw_name, sizeof(hif_dev->fw_name), + "%s/htc_%s-%d.%s.0.fw", HTC_FW_PATH, + chip, MAJOR_VERSION_REQ, index); + } + + ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, + &hif_dev->udev->dev, GFP_KERNEL, + hif_dev, ath9k_hif_usb_firmware_cb); + if (ret) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Async request for firmware %s failed\n", + hif_dev->fw_name); + return ret; + } + + dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", + hif_dev->fw_name); + + return ret; +} + static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) { struct hif_device_usb *hif_dev = context; int ret; if (!fw) { + ret = ath9k_hif_request_firmware(hif_dev, false); + if (!ret) + return; + dev_err(&hif_dev->udev->dev, "ath9k_htc: Failed to get firmware %s\n", hif_dev->fw_name); @@ -1125,7 +1190,7 @@ release_firmware(fw); hif_dev->flags |= HIF_USB_READY; - complete(&hif_dev->fw_done); + complete_all(&hif_dev->fw_done); return; @@ -1222,27 +1287,11 @@ init_completion(&hif_dev->fw_done); - /* Find out which firmware to load */ - - if (IS_AR7010_DEVICE(id->driver_info)) - hif_dev->fw_name = FIRMWARE_AR7010_1_1; - else - hif_dev->fw_name = FIRMWARE_AR9271; - - ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, - &hif_dev->udev->dev, GFP_KERNEL, - hif_dev, ath9k_hif_usb_firmware_cb); - if (ret) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: Async request for firmware %s failed\n", - hif_dev->fw_name); + ret = ath9k_hif_request_firmware(hif_dev, true); + if (ret) goto err_fw_req; - } - dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", - hif_dev->fw_name); - - return 0; + return ret; err_fw_req: usb_set_intfdata(interface, NULL); @@ -1262,7 +1311,7 @@ if (!buf) return; - ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE), + ret = usb_interrupt_msg(udev, usb_sndintpipe(udev, USB_REG_OUT_PIPE), buf, 4, NULL, HZ); if (ret) dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n"); @@ -1312,7 +1361,10 @@ if (!(hif_dev->flags & HIF_USB_START)) ath9k_htc_suspend(hif_dev->htc_handle); - ath9k_hif_usb_dealloc_urbs(hif_dev); + wait_for_completion(&hif_dev->fw_done); + + if (hif_dev->flags & HIF_USB_READY) + ath9k_hif_usb_dealloc_urbs(hif_dev); return 0; }