aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c11
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c12
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c73
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h13
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c46
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c11
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c6
-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
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/spectral.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c34
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c58
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c42
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c22
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h26
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c21
32 files changed, 552 insertions, 151 deletions
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index d185dc0cd12b..4333107ecf37 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -603,16 +603,19 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
603 if (ret) 603 if (ret)
604 return ret; 604 return ret;
605 605
606 src_ring->hw_index = 606 read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
607 ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); 607 if (read_index == 0xffffffff)
608 src_ring->hw_index &= nentries_mask; 608 return -ENODEV;
609
610 read_index &= nentries_mask;
611 src_ring->hw_index = read_index;
609 612
610 ath10k_pci_sleep(ar); 613 ath10k_pci_sleep(ar);
611 } 614 }
612 615
613 read_index = src_ring->hw_index; 616 read_index = src_ring->hw_index;
614 617
615 if ((read_index == sw_index) || (read_index == 0xffffffff)) 618 if (read_index == sw_index)
616 return -EIO; 619 return -EIO;
617 620
618 sbase = src_ring->shadow_base; 621 sbase = src_ring->shadow_base;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index e6c56c5bb0f6..93adb8c58969 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -802,7 +802,7 @@ int ath10k_core_start(struct ath10k *ar)
802 802
803 INIT_LIST_HEAD(&ar->arvifs); 803 INIT_LIST_HEAD(&ar->arvifs);
804 804
805 if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) 805 if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) {
806 ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n", 806 ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
807 ar->hw_params.name, 807 ar->hw_params.name,
808 ar->target_version, 808 ar->target_version,
@@ -811,6 +811,12 @@ int ath10k_core_start(struct ath10k *ar)
811 ar->fw_api, 811 ar->fw_api,
812 ar->htt.target_version_major, 812 ar->htt.target_version_major,
813 ar->htt.target_version_minor); 813 ar->htt.target_version_minor);
814 ath10k_info("debug %d debugfs %d tracing %d dfs %d\n",
815 config_enabled(CONFIG_ATH10K_DEBUG),
816 config_enabled(CONFIG_ATH10K_DEBUGFS),
817 config_enabled(CONFIG_ATH10K_TRACING),
818 config_enabled(CONFIG_ATH10K_DFS_CERTIFIED));
819 }
814 820
815 __set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags); 821 __set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags);
816 822
@@ -988,7 +994,9 @@ err_unregister_mac:
988err_release_fw: 994err_release_fw:
989 ath10k_core_free_firmware_files(ar); 995 ath10k_core_free_firmware_files(ar);
990err: 996err:
991 device_release_driver(ar->dev); 997 /* TODO: It's probably a good idea to release device from the driver
998 * but calling device_release_driver() here will cause a deadlock.
999 */
992 return; 1000 return;
993} 1001}
994 1002
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 68ceef61933d..83a5fa91531d 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -290,6 +290,9 @@ struct ath10k_debug {
290 struct ath_dfs_pool_stats dfs_pool_stats; 290 struct ath_dfs_pool_stats dfs_pool_stats;
291 291
292 u32 fw_dbglog_mask; 292 u32 fw_dbglog_mask;
293
294 u8 htt_max_amsdu;
295 u8 htt_max_ampdu;
293}; 296};
294 297
295enum ath10k_state { 298enum ath10k_state {
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 1b7ff4ba122c..3030158c478e 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -671,6 +671,72 @@ static const struct file_operations fops_htt_stats_mask = {
671 .llseek = default_llseek, 671 .llseek = default_llseek,
672}; 672};
673 673
674static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
675 char __user *user_buf,
676 size_t count, loff_t *ppos)
677{
678 struct ath10k *ar = file->private_data;
679 char buf[64];
680 u8 amsdu = 3, ampdu = 64;
681 unsigned int len;
682
683 mutex_lock(&ar->conf_mutex);
684
685 if (ar->debug.htt_max_amsdu)
686 amsdu = ar->debug.htt_max_amsdu;
687
688 if (ar->debug.htt_max_ampdu)
689 ampdu = ar->debug.htt_max_ampdu;
690
691 mutex_unlock(&ar->conf_mutex);
692
693 len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
694
695 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
696}
697
698static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
699 const char __user *user_buf,
700 size_t count, loff_t *ppos)
701{
702 struct ath10k *ar = file->private_data;
703 int res;
704 char buf[64];
705 unsigned int amsdu, ampdu;
706
707 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
708
709 /* make sure that buf is null terminated */
710 buf[sizeof(buf) - 1] = 0;
711
712 res = sscanf(buf, "%u %u", &amsdu, &ampdu);
713
714 if (res != 2)
715 return -EINVAL;
716
717 mutex_lock(&ar->conf_mutex);
718
719 res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
720 if (res)
721 goto out;
722
723 res = count;
724 ar->debug.htt_max_amsdu = amsdu;
725 ar->debug.htt_max_ampdu = ampdu;
726
727out:
728 mutex_unlock(&ar->conf_mutex);
729 return res;
730}
731
732static const struct file_operations fops_htt_max_amsdu_ampdu = {
733 .read = ath10k_read_htt_max_amsdu_ampdu,
734 .write = ath10k_write_htt_max_amsdu_ampdu,
735 .open = simple_open,
736 .owner = THIS_MODULE,
737 .llseek = default_llseek,
738};
739
674static ssize_t ath10k_read_fw_dbglog(struct file *file, 740static ssize_t ath10k_read_fw_dbglog(struct file *file,
675 char __user *user_buf, 741 char __user *user_buf,
676 size_t count, loff_t *ppos) 742 size_t count, loff_t *ppos)
@@ -757,6 +823,9 @@ void ath10k_debug_stop(struct ath10k *ar)
757 * warning from del_timer(). */ 823 * warning from del_timer(). */
758 if (ar->debug.htt_stats_mask != 0) 824 if (ar->debug.htt_stats_mask != 0)
759 cancel_delayed_work(&ar->debug.htt_stats_dwork); 825 cancel_delayed_work(&ar->debug.htt_stats_dwork);
826
827 ar->debug.htt_max_amsdu = 0;
828 ar->debug.htt_max_ampdu = 0;
760} 829}
761 830
762static ssize_t ath10k_write_simulate_radar(struct file *file, 831static ssize_t ath10k_write_simulate_radar(struct file *file,
@@ -867,6 +936,10 @@ int ath10k_debug_create(struct ath10k *ar)
867 debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, 936 debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
868 ar, &fops_htt_stats_mask); 937 ar, &fops_htt_stats_mask);
869 938
939 debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
940 ar->debug.debugfs_phy, ar,
941 &fops_htt_max_amsdu_ampdu);
942
870 debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy, 943 debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
871 ar, &fops_fw_dbglog); 944 ar, &fops_fw_dbglog);
872 945
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 9a263462c793..6c93f3885ee5 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -240,16 +240,10 @@ struct htt_oob_sync_req {
240 __le16 rsvd0; 240 __le16 rsvd0;
241} __packed; 241} __packed;
242 242
243#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F
244#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB 0
245
246struct htt_aggr_conf { 243struct htt_aggr_conf {
247 u8 max_num_ampdu_subframes; 244 u8 max_num_ampdu_subframes;
248 union { 245 /* amsdu_subframes is limited by 0x1F mask */
249 /* dont use bitfields; undefined behaviour */ 246 u8 max_num_amsdu_subframes;
250 u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */
251 u8 max_num_amsdu_subframes:5;
252 } __packed;
253} __packed; 247} __packed;
254 248
255#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32 249#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
@@ -1343,6 +1337,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
1343int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); 1337int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
1344int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); 1338int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
1345int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt); 1339int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
1340int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
1341 u8 max_subfrms_ampdu,
1342 u8 max_subfrms_amsdu);
1346 1343
1347void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt); 1344void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
1348int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt); 1345int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 7064354d1f4f..accb6b4f6faf 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -307,6 +307,52 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
307 return 0; 307 return 0;
308} 308}
309 309
310int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
311 u8 max_subfrms_ampdu,
312 u8 max_subfrms_amsdu)
313{
314 struct htt_aggr_conf *aggr_conf;
315 struct sk_buff *skb;
316 struct htt_cmd *cmd;
317 int len;
318 int ret;
319
320 /* Firmware defaults are: amsdu = 3 and ampdu = 64 */
321
322 if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
323 return -EINVAL;
324
325 if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
326 return -EINVAL;
327
328 len = sizeof(cmd->hdr);
329 len += sizeof(cmd->aggr_conf);
330
331 skb = ath10k_htc_alloc_skb(len);
332 if (!skb)
333 return -ENOMEM;
334
335 skb_put(skb, len);
336 cmd = (struct htt_cmd *)skb->data;
337 cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
338
339 aggr_conf = &cmd->aggr_conf;
340 aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
341 aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
342
343 ath10k_dbg(ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
344 aggr_conf->max_num_amsdu_subframes,
345 aggr_conf->max_num_ampdu_subframes);
346
347 ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
348 if (ret) {
349 dev_kfree_skb_any(skb);
350 return ret;
351 }
352
353 return 0;
354}
355
310int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) 356int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
311{ 357{
312 struct device *dev = htt->ar->dev; 358 struct device *dev = htt->ar->dev;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index d0004d59c97e..06840d101c45 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1362,8 +1362,6 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
1362 ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr); 1362 ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr);
1363 } 1363 }
1364 1364
1365 init_completion(&xfer.done);
1366
1367 ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0); 1365 ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0);
1368 if (ret) 1366 if (ret)
1369 goto err_resp; 1367 goto err_resp;
@@ -1414,10 +1412,7 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state)
1414 &nbytes, &transfer_id)) 1412 &nbytes, &transfer_id))
1415 return; 1413 return;
1416 1414
1417 if (xfer->wait_for_resp) 1415 xfer->tx_done = true;
1418 return;
1419
1420 complete(&xfer->done);
1421} 1416}
1422 1417
1423static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) 1418static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
@@ -1438,7 +1433,7 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
1438 } 1433 }
1439 1434
1440 xfer->resp_len = nbytes; 1435 xfer->resp_len = nbytes;
1441 complete(&xfer->done); 1436 xfer->rx_done = true;
1442} 1437}
1443 1438
1444static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe, 1439static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
@@ -1451,7 +1446,7 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
1451 ath10k_pci_bmi_send_done(tx_pipe); 1446 ath10k_pci_bmi_send_done(tx_pipe);
1452 ath10k_pci_bmi_recv_data(rx_pipe); 1447 ath10k_pci_bmi_recv_data(rx_pipe);
1453 1448
1454 if (completion_done(&xfer->done)) 1449 if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp))
1455 return 0; 1450 return 0;
1456 1451
1457 schedule(); 1452 schedule();
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index dfdebb4157aa..940129209990 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -38,7 +38,8 @@
38#define DIAG_TRANSFER_LIMIT 2048 38#define DIAG_TRANSFER_LIMIT 2048
39 39
40struct bmi_xfer { 40struct bmi_xfer {
41 struct completion done; 41 bool tx_done;
42 bool rx_done;
42 bool wait_for_resp; 43 bool wait_for_resp;
43 u32 resp_len; 44 u32 resp_len;
44}; 45};
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 4b7782a529ac..6f83cae57655 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2106,7 +2106,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
2106{ 2106{
2107 struct wmi_cmd_hdr *cmd_hdr; 2107 struct wmi_cmd_hdr *cmd_hdr;
2108 enum wmi_event_id id; 2108 enum wmi_event_id id;
2109 u16 len;
2110 2109
2111 cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 2110 cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
2112 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 2111 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -2114,8 +2113,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
2114 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 2113 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
2115 return; 2114 return;
2116 2115
2117 len = skb->len;
2118
2119 trace_ath10k_wmi_event(id, skb->data, skb->len); 2116 trace_ath10k_wmi_event(id, skb->data, skb->len);
2120 2117
2121 switch (id) { 2118 switch (id) {
@@ -2225,7 +2222,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
2225{ 2222{
2226 struct wmi_cmd_hdr *cmd_hdr; 2223 struct wmi_cmd_hdr *cmd_hdr;
2227 enum wmi_10x_event_id id; 2224 enum wmi_10x_event_id id;
2228 u16 len;
2229 2225
2230 cmd_hdr = (struct wmi_cmd_hdr *)skb->data; 2226 cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
2231 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 2227 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -2233,8 +2229,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
2233 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 2229 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
2234 return; 2230 return;
2235 2231
2236 len = skb->len;
2237
2238 trace_ath10k_wmi_event(id, skb->data, skb->len); 2232 trace_ath10k_wmi_event(id, skb->data, skb->len);
2239 2233
2240 switch (id) { 2234 switch (id) {
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 1c4ce8e3eebe..e535807c3d89 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 8ee7097f0b25..fffd52355123 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) {
@@ -1229,7 +1268,13 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
1229 } 1268 }
1230 1269
1231 /* record the fact that Board Data IS initialized */ 1270 /* record the fact that Board Data IS initialized */
1232 ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1); 1271 if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
1272 (ar->version.target_ver == AR6004_HW_3_0_VERSION))
1273 param = board_data_size;
1274 else
1275 param = 1;
1276
1277 ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
1233 1278
1234 return ret; 1279 return ret;
1235} 1280}
@@ -1360,7 +1405,11 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
1360 } 1405 }
1361 1406
1362 ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address); 1407 ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
1363 ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096); 1408
1409 if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
1410 (ar->version.target_ver != AR6004_HW_3_0_VERSION))
1411 ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
1412
1364 ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1); 1413 ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
1365 1414
1366 return 0; 1415 return 0;
@@ -1566,6 +1615,11 @@ static const struct fw_capa_str_map {
1566 { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" }, 1615 { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
1567 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" }, 1616 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
1568 { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" }, 1617 { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
1618 { ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
1619 { ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
1620 { ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
1621 { ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
1622 { ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
1569}; 1623};
1570 1624
1571static const char *ath6kl_init_get_fw_capa_name(unsigned int id) 1625static 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);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 741b38ddcb37..59af9f9712da 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -281,7 +281,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
281 281
282 ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen) 282 ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
283 | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) 283 | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
284 | SM(i->txpower, AR_XmitPower) 284 | SM(i->txpower, AR_XmitPower0)
285 | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) 285 | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
286 | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) 286 | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
287 | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) 287 | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
@@ -306,6 +306,10 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
306 | set11nRateFlags(i->rates, 2) 306 | set11nRateFlags(i->rates, 2)
307 | set11nRateFlags(i->rates, 3) 307 | set11nRateFlags(i->rates, 3)
308 | SM(i->rtscts_rate, AR_RTSCTSRate); 308 | SM(i->rtscts_rate, AR_RTSCTSRate);
309
310 ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower, AR_XmitPower1);
311 ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower, AR_XmitPower2);
312 ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower, AR_XmitPower3);
309} 313}
310 314
311static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, 315static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 729ffbf07343..71e38e85aa99 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -101,7 +101,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
101 101
102 ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen) 102 ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
103 | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) 103 | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
104 | SM(i->txpower, AR_XmitPower) 104 | SM(i->txpower, AR_XmitPower0)
105 | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) 105 | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
106 | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) 106 | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
107 | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0) 107 | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
@@ -151,6 +151,10 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
151 | SM(i->rtscts_rate, AR_RTSCTSRate); 151 | SM(i->rtscts_rate, AR_RTSCTSRate);
152 152
153 ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding; 153 ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
154
155 ACCESS_ONCE(ads->ctl20) = SM(i->txpower, AR_XmitPower1);
156 ACCESS_ONCE(ads->ctl21) = SM(i->txpower, AR_XmitPower2);
157 ACCESS_ONCE(ads->ctl22) = SM(i->txpower, AR_XmitPower3);
154} 158}
155 159
156static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads) 160static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 11b5e4dd6294..7fc13a8da675 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -182,7 +182,8 @@ struct ath_atx_ac {
182 182
183struct ath_frame_info { 183struct ath_frame_info {
184 struct ath_buf *bf; 184 struct ath_buf *bf;
185 int framelen; 185 u16 framelen;
186 s8 txq;
186 enum ath9k_key_type keytype; 187 enum ath9k_key_type keytype;
187 u8 keyix; 188 u8 keyix;
188 u8 rtscts_rate; 189 u8 rtscts_rate;
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index ce073e995dfe..d2279365be6f 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -202,7 +202,7 @@ static ssize_t write_file_ani(struct file *file,
202 if (kstrtoul(buf, 0, &ani)) 202 if (kstrtoul(buf, 0, &ani))
203 return -EINVAL; 203 return -EINVAL;
204 204
205 if (ani < 0 || ani > 1) 205 if (ani > 1)
206 return -EINVAL; 206 return -EINVAL;
207 207
208 common->disable_ani = !ani; 208 common->disable_ani = !ani;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index da7686757535..6c56cafa5ca4 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -346,8 +346,14 @@ struct ar5416_desc {
346#define AR_FrameLen 0x00000fff 346#define AR_FrameLen 0x00000fff
347#define AR_VirtMoreFrag 0x00001000 347#define AR_VirtMoreFrag 0x00001000
348#define AR_TxCtlRsvd00 0x0000e000 348#define AR_TxCtlRsvd00 0x0000e000
349#define AR_XmitPower 0x003f0000 349#define AR_XmitPower0 0x003f0000
350#define AR_XmitPower_S 16 350#define AR_XmitPower0_S 16
351#define AR_XmitPower1 0x3f000000
352#define AR_XmitPower1_S 24
353#define AR_XmitPower2 0x3f000000
354#define AR_XmitPower2_S 24
355#define AR_XmitPower3 0x3f000000
356#define AR_XmitPower3_S 24
351#define AR_RTSEnable 0x00400000 357#define AR_RTSEnable 0x00400000
352#define AR_VEOL 0x00800000 358#define AR_VEOL 0x00800000
353#define AR_ClrDestMask 0x01000000 359#define AR_ClrDestMask 0x01000000
diff --git a/drivers/net/wireless/ath/ath9k/spectral.c b/drivers/net/wireless/ath/ath9k/spectral.c
index 99f4de95c264..5fe29b9f8fa2 100644
--- a/drivers/net/wireless/ath/ath9k/spectral.c
+++ b/drivers/net/wireless/ath/ath9k/spectral.c
@@ -313,7 +313,7 @@ static ssize_t write_file_spectral_short_repeat(struct file *file,
313 if (kstrtoul(buf, 0, &val)) 313 if (kstrtoul(buf, 0, &val))
314 return -EINVAL; 314 return -EINVAL;
315 315
316 if (val < 0 || val > 1) 316 if (val > 1)
317 return -EINVAL; 317 return -EINVAL;
318 318
319 sc->spec_config.short_repeat = val; 319 sc->spec_config.short_repeat = val;
@@ -361,7 +361,7 @@ static ssize_t write_file_spectral_count(struct file *file,
361 if (kstrtoul(buf, 0, &val)) 361 if (kstrtoul(buf, 0, &val))
362 return -EINVAL; 362 return -EINVAL;
363 363
364 if (val < 0 || val > 255) 364 if (val > 255)
365 return -EINVAL; 365 return -EINVAL;
366 366
367 sc->spec_config.count = val; 367 sc->spec_config.count = val;
@@ -409,7 +409,7 @@ static ssize_t write_file_spectral_period(struct file *file,
409 if (kstrtoul(buf, 0, &val)) 409 if (kstrtoul(buf, 0, &val))
410 return -EINVAL; 410 return -EINVAL;
411 411
412 if (val < 0 || val > 255) 412 if (val > 255)
413 return -EINVAL; 413 return -EINVAL;
414 414
415 sc->spec_config.period = val; 415 sc->spec_config.period = val;
@@ -457,7 +457,7 @@ static ssize_t write_file_spectral_fft_period(struct file *file,
457 if (kstrtoul(buf, 0, &val)) 457 if (kstrtoul(buf, 0, &val))
458 return -EINVAL; 458 return -EINVAL;
459 459
460 if (val < 0 || val > 15) 460 if (val > 15)
461 return -EINVAL; 461 return -EINVAL;
462 462
463 sc->spec_config.fft_period = val; 463 sc->spec_config.fft_period = val;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index d4927c9a6bae..704fcbcbe20b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -157,15 +157,14 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
157 struct sk_buff *skb) 157 struct sk_buff *skb)
158{ 158{
159 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 159 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
160 int q, hw_queue; 160 struct ath_frame_info *fi = get_frame_info(skb);
161 161 int hw_queue;
162 q = skb_get_queue_mapping(skb); 162 int q = fi->txq;
163 if (txq == sc->tx.uapsdq)
164 txq = sc->tx.txq_map[q];
165 163
166 if (txq != sc->tx.txq_map[q]) 164 if (q < 0)
167 return; 165 return;
168 166
167 txq = sc->tx.txq_map[q];
169 if (WARN_ON(--txq->pending_frames < 0)) 168 if (WARN_ON(--txq->pending_frames < 0))
170 txq->pending_frames = 0; 169 txq->pending_frames = 0;
171 170
@@ -898,6 +897,15 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
898 897
899 tx_info = IEEE80211_SKB_CB(skb); 898 tx_info = IEEE80211_SKB_CB(skb);
900 tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; 899 tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
900
901 /*
902 * No aggregation session is running, but there may be frames
903 * from a previous session or a failed attempt in the queue.
904 * Send them out as normal data frames
905 */
906 if (!tid->active)
907 tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
908
901 if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { 909 if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
902 bf->bf_state.bf_type = 0; 910 bf->bf_state.bf_type = 0;
903 return bf; 911 return bf;
@@ -2036,6 +2044,7 @@ static void setup_frame_info(struct ieee80211_hw *hw,
2036 an = (struct ath_node *) sta->drv_priv; 2044 an = (struct ath_node *) sta->drv_priv;
2037 2045
2038 memset(fi, 0, sizeof(*fi)); 2046 memset(fi, 0, sizeof(*fi));
2047 fi->txq = -1;
2039 if (hw_key) 2048 if (hw_key)
2040 fi->keyix = hw_key->hw_key_idx; 2049 fi->keyix = hw_key->hw_key_idx;
2041 else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) 2050 else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
@@ -2187,6 +2196,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2187 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2196 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2188 struct ieee80211_sta *sta = txctl->sta; 2197 struct ieee80211_sta *sta = txctl->sta;
2189 struct ieee80211_vif *vif = info->control.vif; 2198 struct ieee80211_vif *vif = info->control.vif;
2199 struct ath_frame_info *fi = get_frame_info(skb);
2190 struct ath_vif *avp = NULL; 2200 struct ath_vif *avp = NULL;
2191 struct ath_softc *sc = hw->priv; 2201 struct ath_softc *sc = hw->priv;
2192 struct ath_txq *txq = txctl->txq; 2202 struct ath_txq *txq = txctl->txq;
@@ -2216,11 +2226,13 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2216 hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue; 2226 hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
2217 2227
2218 ath_txq_lock(sc, txq); 2228 ath_txq_lock(sc, txq);
2219 if (txq == sc->tx.txq_map[q] && 2229 if (txq == sc->tx.txq_map[q]) {
2220 ++txq->pending_frames > sc->tx.txq_max_pending[q] && 2230 fi->txq = q;
2221 !txq->stopped) { 2231 if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
2222 ieee80211_stop_queue(sc->hw, hw_queue); 2232 !txq->stopped) {
2223 txq->stopped = true; 2233 ieee80211_stop_queue(sc->hw, hw_queue);
2234 txq->stopped = true;
2235 }
2224 } 2236 }
2225 2237
2226 queue = ieee80211_is_data_present(hdr->frame_control); 2238 queue = ieee80211_is_data_present(hdr->frame_control);
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index a868c5eebe37..8f66186adb8c 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -448,8 +448,10 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
448 char *kbuf = kmalloc(len + 1, GFP_KERNEL); 448 char *kbuf = kmalloc(len + 1, GFP_KERNEL);
449 if (!kbuf) 449 if (!kbuf)
450 return -ENOMEM; 450 return -ENOMEM;
451 if (copy_from_user(kbuf, buf, len)) 451 if (copy_from_user(kbuf, buf, len)) {
452 kfree(kbuf);
452 return -EIO; 453 return -EIO;
454 }
453 455
454 kbuf[len] = '\0'; 456 kbuf[len] = '\0';
455 rc = kstrtol(kbuf, 0, &channel); 457 rc = kstrtol(kbuf, 0, &channel);
@@ -963,6 +965,26 @@ static const struct file_operations fops_sta = {
963}; 965};
964 966
965/*----------------*/ 967/*----------------*/
968static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
969 struct dentry *dbg)
970{
971 int i;
972 char name[32];
973
974 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
975 struct debugfs_blob_wrapper *blob = &wil->blobs[i];
976 const struct fw_map *map = &fw_mapping[i];
977
978 if (!map->name)
979 continue;
980
981 blob->data = (void * __force)wil->csr + HOSTADDR(map->host);
982 blob->size = map->to - map->from;
983 snprintf(name, sizeof(name), "blob_%s", map->name);
984 wil_debugfs_create_ioblob(name, S_IRUGO, dbg, blob);
985 }
986}
987
966int wil6210_debugfs_init(struct wil6210_priv *wil) 988int wil6210_debugfs_init(struct wil6210_priv *wil)
967{ 989{
968 struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME, 990 struct dentry *dbg = wil->debug = debugfs_create_dir(WIL_NAME,
@@ -986,6 +1008,8 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
986 &wil->secure_pcp); 1008 &wil->secure_pcp);
987 wil_debugfs_create_ulong("status", S_IRUGO | S_IWUSR, dbg, 1009 wil_debugfs_create_ulong("status", S_IRUGO | S_IWUSR, dbg,
988 &wil->status); 1010 &wil->status);
1011 debugfs_create_u32("fw_version", S_IRUGO, dbg, &wil->fw_version);
1012 debugfs_create_x32("hw_version", S_IRUGO, dbg, &wil->hw_version);
989 1013
990 wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg, 1014 wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg,
991 HOSTADDR(RGF_USER_USER_ICR)); 1015 HOSTADDR(RGF_USER_USER_ICR));
@@ -998,6 +1022,9 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
998 wil6210_debugfs_create_pseudo_ISR(wil, dbg); 1022 wil6210_debugfs_create_pseudo_ISR(wil, dbg);
999 wil6210_debugfs_create_ITR_CNT(wil, dbg); 1023 wil6210_debugfs_create_ITR_CNT(wil, dbg);
1000 1024
1025 wil_debugfs_create_iomem_x32("RGF_USER_USAGE_1", S_IRUGO, dbg,
1026 wil->csr +
1027 HOSTADDR(RGF_USER_USAGE_1));
1001 debugfs_create_u32("mem_addr", S_IRUGO | S_IWUSR, dbg, &mem_addr); 1028 debugfs_create_u32("mem_addr", S_IRUGO | S_IWUSR, dbg, &mem_addr);
1002 debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread); 1029 debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
1003 1030
@@ -1010,34 +1037,7 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
1010 debugfs_create_file("link", S_IRUGO, dbg, wil, &fops_link); 1037 debugfs_create_file("link", S_IRUGO, dbg, wil, &fops_link);
1011 debugfs_create_file("info", S_IRUGO, dbg, wil, &fops_info); 1038 debugfs_create_file("info", S_IRUGO, dbg, wil, &fops_info);
1012 1039
1013 wil->rgf_blob.data = (void * __force)wil->csr + 0; 1040 wil6210_debugfs_init_blobs(wil, dbg);
1014 wil->rgf_blob.size = 0xa000;
1015 wil_debugfs_create_ioblob("blob_rgf", S_IRUGO, dbg, &wil->rgf_blob);
1016
1017 wil->fw_code_blob.data = (void * __force)wil->csr + 0x40000;
1018 wil->fw_code_blob.size = 0x40000;
1019 wil_debugfs_create_ioblob("blob_fw_code", S_IRUGO, dbg,
1020 &wil->fw_code_blob);
1021
1022 wil->fw_data_blob.data = (void * __force)wil->csr + 0x80000;
1023 wil->fw_data_blob.size = 0x8000;
1024 wil_debugfs_create_ioblob("blob_fw_data", S_IRUGO, dbg,
1025 &wil->fw_data_blob);
1026
1027 wil->fw_peri_blob.data = (void * __force)wil->csr + 0x88000;
1028 wil->fw_peri_blob.size = 0x18000;
1029 wil_debugfs_create_ioblob("blob_fw_peri", S_IRUGO, dbg,
1030 &wil->fw_peri_blob);
1031
1032 wil->uc_code_blob.data = (void * __force)wil->csr + 0xa0000;
1033 wil->uc_code_blob.size = 0x10000;
1034 wil_debugfs_create_ioblob("blob_uc_code", S_IRUGO, dbg,
1035 &wil->uc_code_blob);
1036
1037 wil->uc_data_blob.data = (void * __force)wil->csr + 0xb0000;
1038 wil->uc_data_blob.size = 0x4000;
1039 wil_debugfs_create_ioblob("blob_uc_data", S_IRUGO, dbg,
1040 &wil->uc_data_blob);
1041 1041
1042 return 0; 1042 return 0;
1043} 1043}
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 53a689ed7c7d..3704d2a434f3 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -314,8 +314,9 @@ static void wil_target_reset(struct wil6210_priv *wil)
314 int delay = 0; 314 int delay = 0;
315 u32 hw_state; 315 u32 hw_state;
316 u32 rev_id; 316 u32 rev_id;
317 bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW);
317 318
318 wil_dbg_misc(wil, "Resetting...\n"); 319 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name);
319 320
320 /* register read */ 321 /* register read */
321#define R(a) ioread32(wil->csr + HOSTADDR(a)) 322#define R(a) ioread32(wil->csr + HOSTADDR(a))
@@ -328,35 +329,59 @@ static void wil_target_reset(struct wil6210_priv *wil)
328 329
329 wil->hw_version = R(RGF_USER_FW_REV_ID); 330 wil->hw_version = R(RGF_USER_FW_REV_ID);
330 rev_id = wil->hw_version & 0xff; 331 rev_id = wil->hw_version & 0xff;
332
333 /* Clear MAC link up */
334 S(RGF_HP_CTRL, BIT(15));
331 /* hpal_perst_from_pad_src_n_mask */ 335 /* hpal_perst_from_pad_src_n_mask */
332 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6)); 336 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6));
333 /* car_perst_rst_src_n_mask */ 337 /* car_perst_rst_src_n_mask */
334 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7)); 338 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7));
335 wmb(); /* order is important here */ 339 wmb(); /* order is important here */
336 340
341 if (is_sparrow) {
342 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
343 wmb(); /* order is important here */
344 }
345
337 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ 346 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
338 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ 347 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
339 wmb(); /* order is important here */ 348 wmb(); /* order is important here */
340 349
341 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 350 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
342 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 351 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
343 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); 352 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000B0 : 0x00000170);
344 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); 353 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
345 wmb(); /* order is important here */ 354 wmb(); /* order is important here */
346 355
356 if (is_sparrow) {
357 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
358 wmb(); /* order is important here */
359 }
360
347 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 361 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
348 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 362 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
349 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 363 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
350 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 364 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
351 wmb(); /* order is important here */ 365 wmb(); /* order is important here */
352 366
353 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); 367 if (is_sparrow) {
354 if (rev_id == 1) { 368 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
355 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); 369 /* reset A2 PCIE AHB */
356 } else {
357 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
358 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 370 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
371
372 } else {
373 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
374 if (rev_id == 1) {
375 /* reset A1 BOTH PCIE AHB & PCIE RGF */
376 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
377 } else {
378 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
379 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
380 }
381
359 } 382 }
383
384 /* TODO: check order here!!! Erez code is different */
360 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 385 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
361 wmb(); /* order is important here */ 386 wmb(); /* order is important here */
362 387
@@ -371,7 +396,8 @@ static void wil_target_reset(struct wil6210_priv *wil)
371 } 396 }
372 } while (hw_state != HW_MACHINE_BOOT_DONE); 397 } while (hw_state != HW_MACHINE_BOOT_DONE);
373 398
374 if (rev_id == 2) 399 /* TODO: Erez check rev_id != 1 */
400 if (!is_sparrow && (rev_id != 1))
375 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); 401 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
376 402
377 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 403 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 77b6272d93fb..d3fbfa28db62 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -122,10 +122,12 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
122 struct wil6210_priv *wil; 122 struct wil6210_priv *wil;
123 struct device *dev = &pdev->dev; 123 struct device *dev = &pdev->dev;
124 void __iomem *csr; 124 void __iomem *csr;
125 struct wil_board *board = (struct wil_board *)id->driver_data;
125 int rc; 126 int rc;
126 127
127 /* check HW */ 128 /* check HW */
128 dev_info(&pdev->dev, WIL_NAME " device found [%04x:%04x] (rev %x)\n", 129 dev_info(&pdev->dev, WIL_NAME
130 " \"%s\" device found [%04x:%04x] (rev %x)\n", board->name,
129 (int)pdev->vendor, (int)pdev->device, (int)pdev->revision); 131 (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
130 132
131 if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) { 133 if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) {
@@ -175,6 +177,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
175 177
176 pci_set_drvdata(pdev, wil); 178 pci_set_drvdata(pdev, wil);
177 wil->pdev = pdev; 179 wil->pdev = pdev;
180 wil->board = board;
178 181
179 wil6210_clear_irq(wil); 182 wil6210_clear_irq(wil);
180 /* FW should raise IRQ when ready */ 183 /* FW should raise IRQ when ready */
@@ -225,8 +228,21 @@ static void wil_pcie_remove(struct pci_dev *pdev)
225 pci_disable_device(pdev); 228 pci_disable_device(pdev);
226} 229}
227 230
228static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = { 231static const struct wil_board wil_board_marlon = {
229 { PCI_DEVICE(0x1ae9, 0x0301) }, 232 .board = WIL_BOARD_MARLON,
233 .name = "marlon",
234};
235
236static const struct wil_board wil_board_sparrow = {
237 .board = WIL_BOARD_SPARROW,
238 .name = "sparrow",
239};
240
241static const struct pci_device_id wil6210_pcie_ids[] = {
242 { PCI_DEVICE(0x1ae9, 0x0301),
243 .driver_data = (kernel_ulong_t)&wil_board_marlon },
244 { PCI_DEVICE(0x1ae9, 0x0310),
245 .driver_data = (kernel_ulong_t)&wil_board_sparrow },
230 { /* end: all zeroes */ }, 246 { /* end: all zeroes */ },
231}; 247};
232MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids); 248MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index af4b93e4beb5..d3467943d39d 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -1108,8 +1108,10 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1108 while (vring->swtail != new_swtail) { 1108 while (vring->swtail != new_swtail) {
1109 struct vring_tx_desc dd, *d = &dd; 1109 struct vring_tx_desc dd, *d = &dd;
1110 u16 dmalen; 1110 u16 dmalen;
1111 struct wil_ctx *ctx = &vring->ctx[vring->swtail]; 1111 struct sk_buff *skb;
1112 struct sk_buff *skb = ctx->skb; 1112
1113 ctx = &vring->ctx[vring->swtail];
1114 skb = ctx->skb;
1113 _d = &vring->va[vring->swtail].tx; 1115 _d = &vring->va[vring->swtail].tx;
1114 1116
1115 *d = *_d; 1117 *d = *_d;
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 424906635f05..67e9624f7111 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -24,6 +24,13 @@
24 24
25#define WIL_NAME "wil6210" 25#define WIL_NAME "wil6210"
26 26
27struct wil_board {
28 int board;
29#define WIL_BOARD_MARLON (1)
30#define WIL_BOARD_SPARROW (2)
31 const char * const name;
32};
33
27/** 34/**
28 * extract bits [@b0:@b1] (inclusive) from the value @x 35 * extract bits [@b0:@b1] (inclusive) from the value @x
29 * it should be @b0 <= @b1, or result is incorrect 36 * it should be @b0 <= @b1, or result is incorrect
@@ -78,6 +85,7 @@ struct RGF_ICR {
78} __packed; 85} __packed;
79 86
80/* registers - FW addresses */ 87/* registers - FW addresses */
88#define RGF_USER_USAGE_1 (0x880004)
81#define RGF_USER_HW_MACHINE_STATE (0x8801dc) 89#define RGF_USER_HW_MACHINE_STATE (0x8801dc)
82 #define HW_MACHINE_BOOT_DONE (0x3fffffd) 90 #define HW_MACHINE_BOOT_DONE (0x3fffffd)
83#define RGF_USER_USER_CPU_0 (0x8801e0) 91#define RGF_USER_USER_CPU_0 (0x8801e0)
@@ -93,6 +101,7 @@ struct RGF_ICR {
93#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14) 101#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14)
94#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */ 102#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */
95 #define BIT_USER_USER_ICR_SW_INT_2 BIT(18) 103 #define BIT_USER_USER_ICR_SW_INT_2 BIT(18)
104#define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18)
96 105
97#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */ 106#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */
98 #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0) 107 #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0)
@@ -121,6 +130,7 @@ struct RGF_ICR {
121 #define BIT_DMA_PSEUDO_CAUSE_TX BIT(1) 130 #define BIT_DMA_PSEUDO_CAUSE_TX BIT(1)
122 #define BIT_DMA_PSEUDO_CAUSE_MISC BIT(2) 131 #define BIT_DMA_PSEUDO_CAUSE_MISC BIT(2)
123 132
133#define RGF_HP_CTRL (0x88265c)
124#define RGF_PCIE_LOS_COUNTER_CTL (0x882dc4) 134#define RGF_PCIE_LOS_COUNTER_CTL (0x882dc4)
125 135
126/* popular locations */ 136/* popular locations */
@@ -135,6 +145,14 @@ struct RGF_ICR {
135#define ISR_MISC_FW_ERROR BIT_DMA_EP_MISC_ICR_FW_INT(3) 145#define ISR_MISC_FW_ERROR BIT_DMA_EP_MISC_ICR_FW_INT(3)
136 146
137/* Hardware definitions end */ 147/* Hardware definitions end */
148struct fw_map {
149 u32 from; /* linker address - from, inclusive */
150 u32 to; /* linker address - to, exclusive */
151 u32 host; /* PCI/Host address - BAR0 + 0x880000 */
152 const char *name; /* for debugfs */
153};
154/* array size should be in sync with actual definition in the wmi.c */
155extern const struct fw_map fw_mapping[7];
138 156
139/** 157/**
140 * mk_cidxtid - construct @cidxtid field 158 * mk_cidxtid - construct @cidxtid field
@@ -365,6 +383,7 @@ struct wil6210_priv {
365 ulong status; 383 ulong status;
366 u32 fw_version; 384 u32 fw_version;
367 u32 hw_version; 385 u32 hw_version;
386 struct wil_board *board;
368 u8 n_mids; /* number of additional MIDs as reported by FW */ 387 u8 n_mids; /* number of additional MIDs as reported by FW */
369 int recovery_count; /* num of FW recovery attempts in a short time */ 388 int recovery_count; /* num of FW recovery attempts in a short time */
370 unsigned long last_fw_recovery; /* jiffies of last fw recovery */ 389 unsigned long last_fw_recovery; /* jiffies of last fw recovery */
@@ -415,12 +434,7 @@ struct wil6210_priv {
415 atomic_t isr_count_rx, isr_count_tx; 434 atomic_t isr_count_rx, isr_count_tx;
416 /* debugfs */ 435 /* debugfs */
417 struct dentry *debug; 436 struct dentry *debug;
418 struct debugfs_blob_wrapper fw_code_blob; 437 struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)];
419 struct debugfs_blob_wrapper fw_data_blob;
420 struct debugfs_blob_wrapper fw_peri_blob;
421 struct debugfs_blob_wrapper uc_code_blob;
422 struct debugfs_blob_wrapper uc_data_blob;
423 struct debugfs_blob_wrapper rgf_blob;
424}; 438};
425 439
426#define wil_to_wiphy(i) (i->wdev->wiphy) 440#define wil_to_wiphy(i) (i->wdev->wiphy)
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index a136dab560e2..1d1d0afdd2e1 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -65,18 +65,17 @@
65 65
66/** 66/**
67 * @fw_mapping provides memory remapping table 67 * @fw_mapping provides memory remapping table
68 *
69 * array size should be in sync with the declaration in the wil6210.h
68 */ 70 */
69static const struct { 71const struct fw_map fw_mapping[] = {
70 u32 from; /* linker address - from, inclusive */ 72 {0x000000, 0x040000, 0x8c0000, "fw_code"}, /* FW code RAM 256k */
71 u32 to; /* linker address - to, exclusive */ 73 {0x800000, 0x808000, 0x900000, "fw_data"}, /* FW data RAM 32k */
72 u32 host; /* PCI/Host address - BAR0 + 0x880000 */ 74 {0x840000, 0x860000, 0x908000, "fw_peri"}, /* periph. data RAM 128k */
73} fw_mapping[] = { 75 {0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */
74 {0x000000, 0x040000, 0x8c0000}, /* FW code RAM 256k */ 76 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */
75 {0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */ 77 {0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */
76 {0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */ 78 {0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */
77 {0x880000, 0x88a000, 0x880000}, /* various RGF */
78 {0x88b000, 0x88c000, 0x88b000}, /* Pcie_ext_rgf */
79 {0x8c0000, 0x949000, 0x8c0000}, /* trivial mapping for upper area */
80 /* 79 /*
81 * 920000..930000 ucode code RAM 80 * 920000..930000 ucode code RAM
82 * 930000..932000 ucode data RAM 81 * 930000..932000 ucode data RAM