diff options
Diffstat (limited to 'drivers/net/wireless/ath')
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: | |||
988 | err_release_fw: | 994 | err_release_fw: |
989 | ath10k_core_free_firmware_files(ar); | 995 | ath10k_core_free_firmware_files(ar); |
990 | err: | 996 | err: |
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 | ||
295 | enum ath10k_state { | 298 | enum 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 | ||
674 | static 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 | |||
698 | static 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, &du); | ||
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 | |||
727 | out: | ||
728 | mutex_unlock(&ar->conf_mutex); | ||
729 | return res; | ||
730 | } | ||
731 | |||
732 | static 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 | |||
674 | static ssize_t ath10k_read_fw_dbglog(struct file *file, | 740 | static 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 | ||
762 | static ssize_t ath10k_write_simulate_radar(struct file *file, | 831 | static 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 | |||
246 | struct htt_aggr_conf { | 243 | struct 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); | |||
1343 | int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); | 1337 | int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); |
1344 | int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); | 1338 | int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); |
1345 | int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt); | 1339 | int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt); |
1340 | int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, | ||
1341 | u8 max_subfrms_ampdu, | ||
1342 | u8 max_subfrms_amsdu); | ||
1346 | 1343 | ||
1347 | void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt); | 1344 | void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt); |
1348 | int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt); | 1345 | int 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 | ||
310 | int 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 | |||
310 | int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) | 356 | int 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 | ||
1423 | static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) | 1418 | static 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 | ||
1444 | static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe, | 1439 | static 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 | ||
40 | struct bmi_xfer { | 40 | struct 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 | ||
151 | enum ath6kl_hw_flags { | 166 | enum 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) | |||
1170 | static void htc_rxctrl_complete(struct htc_target *context, | 1170 | static 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 | ||
1679 | static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target) | 1683 | static 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 | ||
1684 | static int ath6kl_htc_pipe_credit_setup(struct htc_target *target, | 1710 | static 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 | ||
1571 | static const char *ath6kl_init_get_fw_capa_name(unsigned int id) | 1625 | static 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 | ||
1291 | void init_netdev(struct net_device *dev) | 1294 | void 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 */ |
1210 | static struct usb_device_id ath6kl_usb_ids[] = { | 1212 | static 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 | ||
62 | static 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 */ |
63 | static const u8 up_to_ac[] = { | 112 | static 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 | ||
3282 | s32 ath6kl_wmi_get_rate(s8 rate_index) | 3332 | s32 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 | ||
3301 | static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, | 3363 | static 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); |
2633 | int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); | 2633 | int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); |
2634 | 2634 | ||
2635 | s32 ath6kl_wmi_get_rate(s8 rate_index); | 2635 | s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index); |
2636 | 2636 | ||
2637 | int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, | 2637 | int 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 | ||
311 | static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, | 315 | static 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 | ||
156 | static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads) | 160 | static 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 | ||
183 | struct ath_frame_info { | 183 | struct 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 | /*----------------*/ |
968 | static 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 | |||
966 | int wil6210_debugfs_init(struct wil6210_priv *wil) | 988 | int 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 | ||
228 | static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = { | 231 | static const struct wil_board wil_board_marlon = { |
229 | { PCI_DEVICE(0x1ae9, 0x0301) }, | 232 | .board = WIL_BOARD_MARLON, |
233 | .name = "marlon", | ||
234 | }; | ||
235 | |||
236 | static const struct wil_board wil_board_sparrow = { | ||
237 | .board = WIL_BOARD_SPARROW, | ||
238 | .name = "sparrow", | ||
239 | }; | ||
240 | |||
241 | static 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 | }; |
232 | MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids); | 248 | MODULE_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 = ⅆ | 1109 | struct vring_tx_desc dd, *d = ⅆ |
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 | ||
27 | struct 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 */ |
148 | struct 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 */ | ||
155 | extern 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 | */ |
69 | static const struct { | 71 | const 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 |