|
@@ -17,12 +17,8 @@
|
|
#include <asm/unaligned.h>
|
|
#include <asm/unaligned.h>
|
|
#include "htc.h"
|
|
#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[] = {
|
|
static struct usb_device_id ath9k_hif_usb_ids[] = {
|
|
{ USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
|
|
{ USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
|
|
@@ -1080,12 +1076,88 @@ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev)
|
|
device_unlock(parent);
|
|
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)
|
|
static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
|
|
{
|
|
{
|
|
struct hif_device_usb *hif_dev = context;
|
|
struct hif_device_usb *hif_dev = context;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
if (!fw) {
|
|
if (!fw) {
|
|
|
|
+ ret = ath9k_hif_request_firmware(hif_dev, false);
|
|
|
|
+ if (!ret)
|
|
|
|
+ return;
|
|
|
|
+
|
|
dev_err(&hif_dev->udev->dev,
|
|
dev_err(&hif_dev->udev->dev,
|
|
"ath9k_htc: Failed to get firmware %s\n",
|
|
"ath9k_htc: Failed to get firmware %s\n",
|
|
hif_dev->fw_name);
|
|
hif_dev->fw_name);
|
|
@@ -1215,27 +1287,11 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
|
|
|
|
|
|
init_completion(&hif_dev->fw_done);
|
|
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;
|
|
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:
|
|
err_fw_req:
|
|
usb_set_intfdata(interface, NULL);
|
|
usb_set_intfdata(interface, NULL);
|