aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleksij Rempel <linux@rempel-privat.de>2015-09-06 07:09:01 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-09-18 03:40:14 -0400
commite904cf6fe23022cde4e0ea9d41601411a315a3dc (patch)
tree6a2b0347c9dc27c8e06d3d8b114464ed7abca5df
parent47bbbb30b4331ec58a74a66a044341f0114b02b3 (diff)
ath9k_htc: introduce support for different fw versions
Current kernel support only one fw name with theoretically only one fw version located in “firmware/htc_[9271|7010].fw”. Which is ok so far we have only one fw version (1.3). After we realised new fw 1.4, we faced compatibility problem which was decided to solve by firmware name and location: - new firmware is located now in firmware/ath9k_htc/htc_[9271|7010]-1.4.0.fw - old version 1.3 should be on old place, so old kernel have no issues with it. - new kernels including this patch should be able to try different supported (min..max) fw version. - new kernel should be able to support old fw location too. At least for now. At same time this patch will add new module option which should allow user to play with development fw version without replacing stable one. If user will set “ath9k_htc use_dev_fw=1” module will try to find firmware/ath9k_htc/htc_[9271|7010]-1.dev.0.fw first and if it fails, use stable version: for example...1.4.0.fw. Signed-off-by: Oleksij Rempel <linux@rempel-privat.de> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c106
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h21
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c4
3 files changed, 105 insertions, 26 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 10c02f5cbc5e..165dd202c365 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -17,12 +17,8 @@
17#include <asm/unaligned.h> 17#include <asm/unaligned.h>
18#include "htc.h" 18#include "htc.h"
19 19
20/* identify firmware images */ 20MODULE_FIRMWARE(HTC_7010_MODULE_FW);
21#define FIRMWARE_AR7010_1_1 "htc_7010.fw" 21MODULE_FIRMWARE(HTC_9271_MODULE_FW);
22#define FIRMWARE_AR9271 "htc_9271.fw"
23
24MODULE_FIRMWARE(FIRMWARE_AR7010_1_1);
25MODULE_FIRMWARE(FIRMWARE_AR9271);
26 22
27static struct usb_device_id ath9k_hif_usb_ids[] = { 23static struct usb_device_id ath9k_hif_usb_ids[] = {
28 { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */ 24 { USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
@@ -1080,12 +1076,88 @@ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev)
1080 device_unlock(parent); 1076 device_unlock(parent);
1081} 1077}
1082 1078
1079static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context);
1080
1081/* taken from iwlwifi */
1082static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,
1083 bool first)
1084{
1085 char index[8], *chip;
1086 int ret;
1087
1088 if (first) {
1089 if (htc_use_dev_fw) {
1090 hif_dev->fw_minor_index = FIRMWARE_MINOR_IDX_MAX + 1;
1091 sprintf(index, "%s", "dev");
1092 } else {
1093 hif_dev->fw_minor_index = FIRMWARE_MINOR_IDX_MAX;
1094 sprintf(index, "%d", hif_dev->fw_minor_index);
1095 }
1096 } else {
1097 hif_dev->fw_minor_index--;
1098 sprintf(index, "%d", hif_dev->fw_minor_index);
1099 }
1100
1101 /* test for FW 1.3 */
1102 if (MAJOR_VERSION_REQ == 1 && hif_dev->fw_minor_index == 3) {
1103 const char *filename;
1104
1105 if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
1106 filename = FIRMWARE_AR7010_1_1;
1107 else
1108 filename = FIRMWARE_AR9271;
1109
1110 /* expected fw locations:
1111 * - htc_9271.fw (stable version 1.3, depricated)
1112 */
1113 snprintf(hif_dev->fw_name, sizeof(hif_dev->fw_name),
1114 "%s", filename);
1115
1116 } else if (hif_dev->fw_minor_index < FIRMWARE_MINOR_IDX_MIN) {
1117 dev_err(&hif_dev->udev->dev, "no suitable firmware found!\n");
1118
1119 return -ENOENT;
1120 } else {
1121 if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
1122 chip = "7010";
1123 else
1124 chip = "9271";
1125
1126 /* expected fw locations:
1127 * - ath9k_htc/htc_9271-1.dev.0.fw (development version)
1128 * - ath9k_htc/htc_9271-1.4.0.fw (stable version)
1129 */
1130 snprintf(hif_dev->fw_name, sizeof(hif_dev->fw_name),
1131 "%s/htc_%s-%d.%s.0.fw", HTC_FW_PATH,
1132 chip, MAJOR_VERSION_REQ, index);
1133 }
1134
1135 ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name,
1136 &hif_dev->udev->dev, GFP_KERNEL,
1137 hif_dev, ath9k_hif_usb_firmware_cb);
1138 if (ret) {
1139 dev_err(&hif_dev->udev->dev,
1140 "ath9k_htc: Async request for firmware %s failed\n",
1141 hif_dev->fw_name);
1142 return ret;
1143 }
1144
1145 dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n",
1146 hif_dev->fw_name);
1147
1148 return ret;
1149}
1150
1083static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) 1151static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
1084{ 1152{
1085 struct hif_device_usb *hif_dev = context; 1153 struct hif_device_usb *hif_dev = context;
1086 int ret; 1154 int ret;
1087 1155
1088 if (!fw) { 1156 if (!fw) {
1157 ret = ath9k_hif_request_firmware(hif_dev, false);
1158 if (!ret)
1159 return;
1160
1089 dev_err(&hif_dev->udev->dev, 1161 dev_err(&hif_dev->udev->dev,
1090 "ath9k_htc: Failed to get firmware %s\n", 1162 "ath9k_htc: Failed to get firmware %s\n",
1091 hif_dev->fw_name); 1163 hif_dev->fw_name);
@@ -1215,27 +1287,11 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
1215 1287
1216 init_completion(&hif_dev->fw_done); 1288 init_completion(&hif_dev->fw_done);
1217 1289
1218 /* Find out which firmware to load */ 1290 ret = ath9k_hif_request_firmware(hif_dev, true);
1219 1291 if (ret)
1220 if (IS_AR7010_DEVICE(id->driver_info))
1221 hif_dev->fw_name = FIRMWARE_AR7010_1_1;
1222 else
1223 hif_dev->fw_name = FIRMWARE_AR9271;
1224
1225 ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name,
1226 &hif_dev->udev->dev, GFP_KERNEL,
1227 hif_dev, ath9k_hif_usb_firmware_cb);
1228 if (ret) {
1229 dev_err(&hif_dev->udev->dev,
1230 "ath9k_htc: Async request for firmware %s failed\n",
1231 hif_dev->fw_name);
1232 goto err_fw_req; 1292 goto err_fw_req;
1233 }
1234 1293
1235 dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", 1294 return ret;
1236 hif_dev->fw_name);
1237
1238 return 0;
1239 1295
1240err_fw_req: 1296err_fw_req:
1241 usb_set_intfdata(interface, NULL); 1297 usb_set_intfdata(interface, NULL);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 51496e74b83e..7c2ef7ecd98b 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -17,8 +17,26 @@
17#ifndef HTC_USB_H 17#ifndef HTC_USB_H
18#define HTC_USB_H 18#define HTC_USB_H
19 19
20/* old firmware images */
21#define FIRMWARE_AR7010_1_1 "htc_7010.fw"
22#define FIRMWARE_AR9271 "htc_9271.fw"
23
24/* supported Major FW version */
20#define MAJOR_VERSION_REQ 1 25#define MAJOR_VERSION_REQ 1
21#define MINOR_VERSION_REQ 3 26#define MINOR_VERSION_REQ 3
27/* minimal and maximal supported Minor FW version. */
28#define FIRMWARE_MINOR_IDX_MAX 4
29#define FIRMWARE_MINOR_IDX_MIN 3
30#define HTC_FW_PATH "ath9k_htc"
31
32#define HTC_9271_MODULE_FW HTC_FW_PATH "/htc_9271-" \
33 __stringify(MAJOR_VERSION_REQ) \
34 "." __stringify(FIRMWARE_MINOR_IDX_MAX) ".0.fw"
35#define HTC_7010_MODULE_FW HTC_FW_PATH "/htc_7010-" \
36 __stringify(MAJOR_VERSION_REQ) \
37 "." __stringify(FIRMWARE_MINOR_IDX_MAX) ".0.fw"
38
39extern int htc_use_dev_fw;
22 40
23#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) 41#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
24 42
@@ -101,7 +119,8 @@ struct hif_device_usb {
101 struct usb_anchor reg_in_submitted; 119 struct usb_anchor reg_in_submitted;
102 struct usb_anchor mgmt_submitted; 120 struct usb_anchor mgmt_submitted;
103 struct sk_buff *remain_skb; 121 struct sk_buff *remain_skb;
104 const char *fw_name; 122 char fw_name[32];
123 int fw_minor_index;
105 int rx_remain_len; 124 int rx_remain_len;
106 int rx_pkt_len; 125 int rx_pkt_len;
107 int rx_transfer_len; 126 int rx_transfer_len;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 1e84882f8c5b..efe77db96570 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -38,6 +38,10 @@ static int ath9k_ps_enable;
38module_param_named(ps_enable, ath9k_ps_enable, int, 0444); 38module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
39MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); 39MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
40 40
41int htc_use_dev_fw = 0;
42module_param_named(use_dev_fw, htc_use_dev_fw, int, 0444);
43MODULE_PARM_DESC(use_dev_fw, "Use development FW version");
44
41#ifdef CONFIG_MAC80211_LEDS 45#ifdef CONFIG_MAC80211_LEDS
42int ath9k_htc_led_blink = 1; 46int ath9k_htc_led_blink = 1;
43module_param_named(blink, ath9k_htc_led_blink, int, 0444); 47module_param_named(blink, ath9k_htc_led_blink, int, 0444);