aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-07-18 13:44:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-07-18 13:44:50 -0400
commit5235cd21212ca3701b678d7e93682999a772c995 (patch)
treeb45a81a0bf30cff43e7b6e9fc40606f7129a2ee3 /drivers/net/wireless/ath/ath6kl
parentfd29d2cdd5866fd64f2704663535274f5fcaf0af (diff)
parent993619443774f7ef4df3b98655df4c3bf298548c (diff)
Merge tag 'for-linville-20140717' of git://github.com/kvalo/ath
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl')
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.h3
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c6
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c16
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h36
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_pipe.c32
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c90
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c17
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c7
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c72
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h2
10 files changed, 239 insertions, 42 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
index 18fdd69e1f71..397a52f2628b 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.h
+++ b/drivers/net/wireless/ath/ath6kl/bmi.h
@@ -242,7 +242,8 @@ struct ath6kl_bmi_target_info {
242 (void) (check_type == val); \ 242 (void) (check_type == val); \
243 addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ 243 addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \
244 ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \ 244 ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \
245 *val = le32_to_cpu(tmp); \ 245 if (!ret) \
246 *val = le32_to_cpu(tmp); \
246 ret; \ 247 ret; \
247 }) 248 })
248 249
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 0e26f4a34fda..d139f2a7160a 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -2899,7 +2899,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2899 if (info->inactivity_timeout) { 2899 if (info->inactivity_timeout) {
2900 inactivity_timeout = info->inactivity_timeout; 2900 inactivity_timeout = info->inactivity_timeout;
2901 2901
2902 if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS) 2902 if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
2903 ar->fw_capabilities))
2903 inactivity_timeout = DIV_ROUND_UP(inactivity_timeout, 2904 inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2904 60); 2905 60);
2905 2906
@@ -3782,7 +3783,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
3782 ath6kl_band_5ghz.ht_cap.ht_supported = false; 3783 ath6kl_band_5ghz.ht_cap.ht_supported = false;
3783 } 3784 }
3784 3785
3785 if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) { 3786 if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3787 ar->fw_capabilities)) {
3786 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; 3788 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3787 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; 3789 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3788 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; 3790 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index b0b652042760..0df74b245af4 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -123,6 +123,22 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
123 123
124 /* FIXME: we should free all firmwares in the error cases below */ 124 /* FIXME: we should free all firmwares in the error cases below */
125 125
126 /*
127 * Backwards compatibility support for older ar6004 firmware images
128 * which do not set these feature flags.
129 */
130 if (ar->target_type == TARGET_TYPE_AR6004 &&
131 ar->fw_api <= 4) {
132 __set_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
133 ar->fw_capabilities);
134 __set_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
135 ar->fw_capabilities);
136
137 if (ar->hw.id == AR6004_HW_1_3_VERSION)
138 __set_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
139 ar->fw_capabilities);
140 }
141
126 /* Indicate that WMI is enabled (although not ready yet) */ 142 /* Indicate that WMI is enabled (although not ready yet) */
127 set_bit(WMI_ENABLED, &ar->flag); 143 set_bit(WMI_ENABLED, &ar->flag);
128 ar->wmi = ath6kl_wmi_init(ar); 144 ar->wmi = ath6kl_wmi_init(ar);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 26b0f92424e1..2b78c863d030 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -136,6 +136,21 @@ enum ath6kl_fw_capability {
136 */ 136 */
137 ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, 137 ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
138 138
139 /* WMI_SET_TX_SELECT_RATES_CMDID uses 64 bit size rate table */
140 ATH6KL_FW_CAPABILITY_64BIT_RATES,
141
142 /* WMI_AP_CONN_INACT_CMDID uses minutes as units */
143 ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
144
145 /* use low priority endpoint for all data */
146 ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
147
148 /* ratetable is the 2 stream version (max MCS15) */
149 ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
150
151 /* firmare doesn't support IP checksumming */
152 ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
153
139 /* this needs to be last */ 154 /* this needs to be last */
140 ATH6KL_FW_CAPABILITY_MAX, 155 ATH6KL_FW_CAPABILITY_MAX,
141}; 156};
@@ -149,15 +164,13 @@ struct ath6kl_fw_ie {
149}; 164};
150 165
151enum ath6kl_hw_flags { 166enum ath6kl_hw_flags {
152 ATH6KL_HW_64BIT_RATES = BIT(0),
153 ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1),
154 ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2),
155 ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3), 167 ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3),
156}; 168};
157 169
158#define ATH6KL_FW_API2_FILE "fw-2.bin" 170#define ATH6KL_FW_API2_FILE "fw-2.bin"
159#define ATH6KL_FW_API3_FILE "fw-3.bin" 171#define ATH6KL_FW_API3_FILE "fw-3.bin"
160#define ATH6KL_FW_API4_FILE "fw-4.bin" 172#define ATH6KL_FW_API4_FILE "fw-4.bin"
173#define ATH6KL_FW_API5_FILE "fw-5.bin"
161 174
162/* AR6003 1.0 definitions */ 175/* AR6003 1.0 definitions */
163#define AR6003_HW_1_0_VERSION 0x300002ba 176#define AR6003_HW_1_0_VERSION 0x300002ba
@@ -215,8 +228,21 @@ enum ath6kl_hw_flags {
215#define AR6004_HW_1_3_VERSION 0x31c8088a 228#define AR6004_HW_1_3_VERSION 0x31c8088a
216#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3" 229#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3"
217#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin" 230#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin"
218#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" 231#define AR6004_HW_1_3_TCMD_FIRMWARE_FILE "utf.bin"
219#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" 232#define AR6004_HW_1_3_UTF_FIRMWARE_FILE "utf.bin"
233#define AR6004_HW_1_3_TESTSCRIPT_FILE "nullTestFlow.bin"
234#define AR6004_HW_1_3_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
235#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
236
237/* AR6004 3.0 definitions */
238#define AR6004_HW_3_0_VERSION 0x31C809F8
239#define AR6004_HW_3_0_FW_DIR "ath6k/AR6004/hw3.0"
240#define AR6004_HW_3_0_FIRMWARE_FILE "fw.ram.bin"
241#define AR6004_HW_3_0_TCMD_FIRMWARE_FILE "utf.bin"
242#define AR6004_HW_3_0_UTF_FIRMWARE_FILE "utf.bin"
243#define AR6004_HW_3_0_TESTSCRIPT_FILE "nullTestFlow.bin"
244#define AR6004_HW_3_0_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
245#define AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
220 246
221/* Per STA data, used in AP mode */ 247/* Per STA data, used in AP mode */
222#define STA_PS_AWAKE BIT(0) 248#define STA_PS_AWAKE BIT(0)
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
index 756fe52a12c8..ca1a18c86c0d 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -1170,8 +1170,12 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
1170static void htc_rxctrl_complete(struct htc_target *context, 1170static void htc_rxctrl_complete(struct htc_target *context,
1171 struct htc_packet *packet) 1171 struct htc_packet *packet)
1172{ 1172{
1173 /* TODO, can't really receive HTC control messages yet.... */ 1173 struct sk_buff *skb = packet->skb;
1174 ath6kl_dbg(ATH6KL_DBG_HTC, "%s: invalid call function\n", __func__); 1174
1175 if (packet->endpoint == ENDPOINT_0 &&
1176 packet->status == -ECANCELED &&
1177 skb != NULL)
1178 dev_kfree_skb(skb);
1175} 1179}
1176 1180
1177/* htc pipe initialization */ 1181/* htc pipe initialization */
@@ -1678,7 +1682,29 @@ static void ath6kl_htc_pipe_activity_changed(struct htc_target *target,
1678 1682
1679static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target) 1683static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target)
1680{ 1684{
1681 /* TODO */ 1685 struct htc_endpoint *endpoint;
1686 struct htc_packet *packet, *tmp_pkt;
1687 int i;
1688
1689 for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
1690 endpoint = &target->endpoint[i];
1691
1692 spin_lock_bh(&target->rx_lock);
1693
1694 list_for_each_entry_safe(packet, tmp_pkt,
1695 &endpoint->rx_bufq, list) {
1696 list_del(&packet->list);
1697 spin_unlock_bh(&target->rx_lock);
1698 ath6kl_dbg(ATH6KL_DBG_HTC,
1699 "htc rx flush pkt 0x%p len %d ep %d\n",
1700 packet, packet->buf_len,
1701 packet->endpoint);
1702 dev_kfree_skb(packet->pkt_cntxt);
1703 spin_lock_bh(&target->rx_lock);
1704 }
1705
1706 spin_unlock_bh(&target->rx_lock);
1707 }
1682} 1708}
1683 1709
1684static int ath6kl_htc_pipe_credit_setup(struct htc_target *target, 1710static int ath6kl_htc_pipe_credit_setup(struct htc_target *target,
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index d5ef211f261c..a61118484de6 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
93 .board_addr = 0x433900, 93 .board_addr = 0x433900,
94 .refclk_hz = 26000000, 94 .refclk_hz = 26000000,
95 .uarttx_pin = 11, 95 .uarttx_pin = 11,
96 .flags = ATH6KL_HW_64BIT_RATES | 96 .flags = 0,
97 ATH6KL_HW_AP_INACTIVITY_MINS,
98 97
99 .fw = { 98 .fw = {
100 .dir = AR6004_HW_1_0_FW_DIR, 99 .dir = AR6004_HW_1_0_FW_DIR,
@@ -114,8 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
114 .board_addr = 0x43d400, 113 .board_addr = 0x43d400,
115 .refclk_hz = 40000000, 114 .refclk_hz = 40000000,
116 .uarttx_pin = 11, 115 .uarttx_pin = 11,
117 .flags = ATH6KL_HW_64BIT_RATES | 116 .flags = 0,
118 ATH6KL_HW_AP_INACTIVITY_MINS,
119 .fw = { 117 .fw = {
120 .dir = AR6004_HW_1_1_FW_DIR, 118 .dir = AR6004_HW_1_1_FW_DIR,
121 .fw = AR6004_HW_1_1_FIRMWARE_FILE, 119 .fw = AR6004_HW_1_1_FIRMWARE_FILE,
@@ -134,8 +132,7 @@ static const struct ath6kl_hw hw_list[] = {
134 .board_addr = 0x435c00, 132 .board_addr = 0x435c00,
135 .refclk_hz = 40000000, 133 .refclk_hz = 40000000,
136 .uarttx_pin = 11, 134 .uarttx_pin = 11,
137 .flags = ATH6KL_HW_64BIT_RATES | 135 .flags = 0,
138 ATH6KL_HW_AP_INACTIVITY_MINS,
139 136
140 .fw = { 137 .fw = {
141 .dir = AR6004_HW_1_2_FW_DIR, 138 .dir = AR6004_HW_1_2_FW_DIR,
@@ -152,20 +149,43 @@ static const struct ath6kl_hw hw_list[] = {
152 .board_ext_data_addr = 0x437000, 149 .board_ext_data_addr = 0x437000,
153 .reserved_ram_size = 7168, 150 .reserved_ram_size = 7168,
154 .board_addr = 0x436400, 151 .board_addr = 0x436400,
155 .refclk_hz = 40000000, 152 .refclk_hz = 0,
156 .uarttx_pin = 11, 153 .uarttx_pin = 11,
157 .flags = ATH6KL_HW_64BIT_RATES | 154 .flags = 0,
158 ATH6KL_HW_AP_INACTIVITY_MINS |
159 ATH6KL_HW_MAP_LP_ENDPOINT,
160 155
161 .fw = { 156 .fw = {
162 .dir = AR6004_HW_1_3_FW_DIR, 157 .dir = AR6004_HW_1_3_FW_DIR,
163 .fw = AR6004_HW_1_3_FIRMWARE_FILE, 158 .fw = AR6004_HW_1_3_FIRMWARE_FILE,
159 .tcmd = AR6004_HW_1_3_TCMD_FIRMWARE_FILE,
160 .utf = AR6004_HW_1_3_UTF_FIRMWARE_FILE,
161 .testscript = AR6004_HW_1_3_TESTSCRIPT_FILE,
164 }, 162 },
165 163
166 .fw_board = AR6004_HW_1_3_BOARD_DATA_FILE, 164 .fw_board = AR6004_HW_1_3_BOARD_DATA_FILE,
167 .fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE, 165 .fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
168 }, 166 },
167 {
168 .id = AR6004_HW_3_0_VERSION,
169 .name = "ar6004 hw 3.0",
170 .dataset_patch_addr = 0,
171 .app_load_addr = 0x1234,
172 .board_ext_data_addr = 0,
173 .reserved_ram_size = 7168,
174 .board_addr = 0x436400,
175 .testscript_addr = 0,
176 .flags = 0,
177
178 .fw = {
179 .dir = AR6004_HW_3_0_FW_DIR,
180 .fw = AR6004_HW_3_0_FIRMWARE_FILE,
181 .tcmd = AR6004_HW_3_0_TCMD_FIRMWARE_FILE,
182 .utf = AR6004_HW_3_0_UTF_FIRMWARE_FILE,
183 .testscript = AR6004_HW_3_0_TESTSCRIPT_FILE,
184 },
185
186 .fw_board = AR6004_HW_3_0_BOARD_DATA_FILE,
187 .fw_default_board = AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE,
188 },
169}; 189};
170 190
171/* 191/*
@@ -601,7 +621,9 @@ int ath6kl_configure_target(struct ath6kl *ar)
601 * but possible in theory. 621 * but possible in theory.
602 */ 622 */
603 623
604 if (ar->target_type == TARGET_TYPE_AR6003) { 624 if ((ar->target_type == TARGET_TYPE_AR6003) ||
625 (ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
626 (ar->version.target_ver == AR6004_HW_3_0_VERSION)) {
605 param = ar->hw.board_ext_data_addr; 627 param = ar->hw.board_ext_data_addr;
606 ram_reserved_size = ar->hw.reserved_ram_size; 628 ram_reserved_size = ar->hw.reserved_ram_size;
607 629
@@ -629,9 +651,12 @@ int ath6kl_configure_target(struct ath6kl *ar)
629 return status; 651 return status;
630 652
631 /* Configure target refclk_hz */ 653 /* Configure target refclk_hz */
632 status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz); 654 if (ar->hw.refclk_hz != 0) {
633 if (status) 655 status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz,
634 return status; 656 ar->hw.refclk_hz);
657 if (status)
658 return status;
659 }
635 660
636 return 0; 661 return 0;
637} 662}
@@ -1112,6 +1137,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
1112 if (ret) 1137 if (ret)
1113 return ret; 1138 return ret;
1114 1139
1140 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API5_FILE);
1141 if (ret == 0) {
1142 ar->fw_api = 5;
1143 goto out;
1144 }
1145
1115 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE); 1146 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
1116 if (ret == 0) { 1147 if (ret == 0) {
1117 ar->fw_api = 4; 1148 ar->fw_api = 4;
@@ -1161,11 +1192,19 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
1161 ath6kl_bmi_write_hi32(ar, hi_board_data, 1192 ath6kl_bmi_write_hi32(ar, hi_board_data,
1162 board_address); 1193 board_address);
1163 } else { 1194 } else {
1164 ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address); 1195 ret = ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
1196 if (ret) {
1197 ath6kl_err("Failed to get board file target address.\n");
1198 return ret;
1199 }
1165 } 1200 }
1166 1201
1167 /* determine where in target ram to write extended board data */ 1202 /* determine where in target ram to write extended board data */
1168 ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address); 1203 ret = ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
1204 if (ret) {
1205 ath6kl_err("Failed to get extended board file target address.\n");
1206 return ret;
1207 }
1169 1208
1170 if (ar->target_type == TARGET_TYPE_AR6003 && 1209 if (ar->target_type == TARGET_TYPE_AR6003 &&
1171 board_ext_address == 0) { 1210 board_ext_address == 0) {
@@ -1230,7 +1269,13 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
1230 } 1269 }
1231 1270
1232 /* record the fact that Board Data IS initialized */ 1271 /* record the fact that Board Data IS initialized */
1233 ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1); 1272 if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
1273 (ar->version.target_ver == AR6004_HW_3_0_VERSION))
1274 param = board_data_size;
1275 else
1276 param = 1;
1277
1278 ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
1234 1279
1235 return ret; 1280 return ret;
1236} 1281}
@@ -1361,7 +1406,11 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
1361 } 1406 }
1362 1407
1363 ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address); 1408 ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
1364 ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096); 1409
1410 if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
1411 (ar->version.target_ver != AR6004_HW_3_0_VERSION))
1412 ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
1413
1365 ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1); 1414 ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
1366 1415
1367 return 0; 1416 return 0;
@@ -1567,6 +1616,11 @@ static const struct fw_capa_str_map {
1567 { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" }, 1616 { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
1568 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" }, 1617 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
1569 { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" }, 1618 { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
1619 { ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
1620 { ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
1621 { ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
1622 { ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
1623 { ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
1570}; 1624};
1571 1625
1572static const char *ath6kl_init_get_fw_capa_name(unsigned int id) 1626static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index d56554674da4..21516bc65785 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -702,6 +702,7 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
702 struct ath6kl *ar = vif->ar; 702 struct ath6kl *ar = vif->ar;
703 struct target_stats *stats = &vif->target_stats; 703 struct target_stats *stats = &vif->target_stats;
704 struct tkip_ccmp_stats *ccmp_stats; 704 struct tkip_ccmp_stats *ccmp_stats;
705 s32 rate;
705 u8 ac; 706 u8 ac;
706 707
707 if (len < sizeof(*tgt_stats)) 708 if (len < sizeof(*tgt_stats))
@@ -731,8 +732,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
731 le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt); 732 le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
732 stats->tx_rts_fail_cnt += 733 stats->tx_rts_fail_cnt +=
733 le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt); 734 le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
734 stats->tx_ucast_rate = 735
735 ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate)); 736 rate = a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate);
737 stats->tx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
736 738
737 stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt); 739 stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
738 stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte); 740 stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
@@ -749,8 +751,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
749 le32_to_cpu(tgt_stats->stats.rx.key_cache_miss); 751 le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
750 stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err); 752 stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
751 stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame); 753 stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
752 stats->rx_ucast_rate = 754
753 ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate)); 755 rate = a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate);
756 stats->rx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
754 757
755 ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats; 758 ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
756 759
@@ -1290,6 +1293,8 @@ static const struct net_device_ops ath6kl_netdev_ops = {
1290 1293
1291void init_netdev(struct net_device *dev) 1294void init_netdev(struct net_device *dev)
1292{ 1295{
1296 struct ath6kl *ar = ath6kl_priv(dev);
1297
1293 dev->netdev_ops = &ath6kl_netdev_ops; 1298 dev->netdev_ops = &ath6kl_netdev_ops;
1294 dev->destructor = free_netdev; 1299 dev->destructor = free_netdev;
1295 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT; 1300 dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
@@ -1301,7 +1306,9 @@ void init_netdev(struct net_device *dev)
1301 WMI_MAX_TX_META_SZ + 1306 WMI_MAX_TX_META_SZ +
1302 ATH6KL_HTC_ALIGN_BYTES, 4); 1307 ATH6KL_HTC_ALIGN_BYTES, 4);
1303 1308
1304 dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; 1309 if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
1310 ar->fw_capabilities))
1311 dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
1305 1312
1306 return; 1313 return;
1307} 1314}
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 3afc5a463d06..c44325856b81 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -802,7 +802,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
802 break; 802 break;
803 case WMI_DATA_VI_SVC: 803 case WMI_DATA_VI_SVC:
804 804
805 if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) 805 if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
806 ar->fw_capabilities))
806 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; 807 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
807 else 808 else
808 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; 809 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
@@ -814,7 +815,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
814 break; 815 break;
815 case WMI_DATA_VO_SVC: 816 case WMI_DATA_VO_SVC:
816 817
817 if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) 818 if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
819 ar->fw_capabilities))
818 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; 820 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
819 else 821 else
820 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; 822 *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
@@ -1208,6 +1210,7 @@ static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf)
1208 1210
1209/* table of devices that work with this driver */ 1211/* table of devices that work with this driver */
1210static struct usb_device_id ath6kl_usb_ids[] = { 1212static struct usb_device_id ath6kl_usb_ids[] = {
1213 {USB_DEVICE(0x0cf3, 0x9375)},
1211 {USB_DEVICE(0x0cf3, 0x9374)}, 1214 {USB_DEVICE(0x0cf3, 0x9374)},
1212 { /* Terminating entry */ }, 1215 { /* Terminating entry */ },
1213}; 1216};
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 4d7f9e4712e9..94df345d08c2 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -59,6 +59,55 @@ static const s32 wmi_rate_tbl[][2] = {
59 {0, 0} 59 {0, 0}
60}; 60};
61 61
62static const s32 wmi_rate_tbl_mcs15[][2] = {
63 /* {W/O SGI, with SGI} */
64 {1000, 1000},
65 {2000, 2000},
66 {5500, 5500},
67 {11000, 11000},
68 {6000, 6000},
69 {9000, 9000},
70 {12000, 12000},
71 {18000, 18000},
72 {24000, 24000},
73 {36000, 36000},
74 {48000, 48000},
75 {54000, 54000},
76 {6500, 7200}, /* HT 20, MCS 0 */
77 {13000, 14400},
78 {19500, 21700},
79 {26000, 28900},
80 {39000, 43300},
81 {52000, 57800},
82 {58500, 65000},
83 {65000, 72200},
84 {13000, 14400}, /* HT 20, MCS 8 */
85 {26000, 28900},
86 {39000, 43300},
87 {52000, 57800},
88 {78000, 86700},
89 {104000, 115600},
90 {117000, 130000},
91 {130000, 144400}, /* HT 20, MCS 15 */
92 {13500, 15000}, /*HT 40, MCS 0 */
93 {27000, 30000},
94 {40500, 45000},
95 {54000, 60000},
96 {81000, 90000},
97 {108000, 120000},
98 {121500, 135000},
99 {135000, 150000},
100 {27000, 30000}, /*HT 40, MCS 8 */
101 {54000, 60000},
102 {81000, 90000},
103 {108000, 120000},
104 {162000, 180000},
105 {216000, 240000},
106 {243000, 270000},
107 {270000, 300000}, /*HT 40, MCS 15 */
108 {0, 0}
109};
110
62/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */ 111/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
63static const u8 up_to_ac[] = { 112static const u8 up_to_ac[] = {
64 WMM_AC_BE, 113 WMM_AC_BE,
@@ -2838,7 +2887,8 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
2838{ 2887{
2839 struct ath6kl *ar = wmi->parent_dev; 2888 struct ath6kl *ar = wmi->parent_dev;
2840 2889
2841 if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) 2890 if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
2891 ar->fw_capabilities))
2842 return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); 2892 return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
2843 else 2893 else
2844 return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); 2894 return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
@@ -3279,9 +3329,11 @@ int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
3279 NO_SYNC_WMIFLAG); 3329 NO_SYNC_WMIFLAG);
3280} 3330}
3281 3331
3282s32 ath6kl_wmi_get_rate(s8 rate_index) 3332s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index)
3283{ 3333{
3334 struct ath6kl *ar = wmi->parent_dev;
3284 u8 sgi = 0; 3335 u8 sgi = 0;
3336 s32 ret;
3285 3337
3286 if (rate_index == RATE_AUTO) 3338 if (rate_index == RATE_AUTO)
3287 return 0; 3339 return 0;
@@ -3292,10 +3344,20 @@ s32 ath6kl_wmi_get_rate(s8 rate_index)
3292 sgi = 1; 3344 sgi = 1;
3293 } 3345 }
3294 3346
3295 if (WARN_ON(rate_index > RATE_MCS_7_40)) 3347 if (test_bit(ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
3296 rate_index = RATE_MCS_7_40; 3348 ar->fw_capabilities)) {
3349 if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl_mcs15)))
3350 return 0;
3351
3352 ret = wmi_rate_tbl_mcs15[(u32) rate_index][sgi];
3353 } else {
3354 if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl)))
3355 return 0;
3297 3356
3298 return wmi_rate_tbl[(u32) rate_index][sgi]; 3357 ret = wmi_rate_tbl[(u32) rate_index][sgi];
3358 }
3359
3360 return ret;
3299} 3361}
3300 3362
3301static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, 3363static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index bb23fc00111d..19f88b4a24fb 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2632,7 +2632,7 @@ int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
2632 struct ath6kl_htcap *htcap); 2632 struct ath6kl_htcap *htcap);
2633int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); 2633int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
2634 2634
2635s32 ath6kl_wmi_get_rate(s8 rate_index); 2635s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index);
2636 2636
2637int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, 2637int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
2638 __be32 ips0, __be32 ips1); 2638 __be32 ips0, __be32 ips1);