aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-28 20:36:25 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-28 20:36:25 -0400
commit3fd0202a0dfe07d255c5462d7d0e27673ca10430 (patch)
tree126483df9ff404e0d31cdcad18ad4280df06d89f /drivers/net/wireless/ath
parenta67eed571aa505f51a4d02cab765a9d4f6ef80c4 (diff)
parent9a244409d0b0cf3b1e46f1dc331f2c718597fae0 (diff)
Merge tag 'master-2014-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== pull request: wireless-next 2014-07-25 Please pull this batch of updates intended for the 3.17 stream! For the mac80211 bits, Johannes says: "We have a lot of TDLS patches, among them a fix that should make hwsim tests happy again. The rest, this time, is mostly small fixes." For the Bluetooth bits, Gustavo says: "Some more patches for 3.17. The most important change here is the move of the 6lowpan code to net/6lowpan. It has been agreed with Davem that this change will go through the bluetooth tree. The rest are mostly clean up and fixes." and, "Here follows some more patches for 3.17. These are mostly fixes to what we've sent to you before for next merge window." For the iwlwifi bits, Emmanuel says: "I have the usual amount of BT Coex stuff. Arik continues to work on TDLS and Ariej contributes a few things for HS2.0. I added a few more things to the firmware debugging infrastructure. Eran fixes a small bug - pretty normal content." And for the Atheros bits, Kalle says: "For ath6kl me and Jessica added support for ar6004 hw3.0, our latest version of ar6004. For ath10k Janusz added a printout so that it's easier to check what ath10k kconfig options are enabled. He also added a debugfs file to configure maximum amsdu and ampdu values. Also we had few fixes as usual." On top of that is the usual large batch of various driver updates -- brcmfmac, mwifiex, the TI drivers, and wil6210 all get some action. RafaƂ has also been very busy with b43 and related updates. Also, I pulled the wireless tree into this in order to resolve a merge conflict... P.S. The change to fs/compat_ioctl.c reflects a name change in a Bluetooth header file... ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
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