aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/bcma/host_pci.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c8
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h24
-rw-r--r--drivers/net/wireless/ath/ath10k/debugfs_sta.c13
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h31
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c125
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c54
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c51
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c77
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c8
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h18
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/common-spectral.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c17
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c129
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c100
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/p2p.c160
-rw-r--r--drivers/net/wireless/ath/wil6210/pmc.c55
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c110
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h25
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_crash_dump.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c160
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h586
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile3
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c381
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h23
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c38
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c171
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c242
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h40
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c1
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c5
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h1
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfg80211.c12
-rw-r--r--drivers/net/wireless/marvell/mwifiex/fw.h1
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.c3
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.h9
-rw-r--r--drivers/net/wireless/marvell/mwifiex/pcie.c17
-rw-r--r--drivers/net/wireless/marvell/mwifiex/scan.c8
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sdio.c6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_cmd.c38
-rw-r--r--drivers/net/wireless/marvell/mwifiex/usb.c3
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/init.c14
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/regs.h3
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h27
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c2
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c111
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/base.c8
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/core.c9
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.c14
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/ps.c36
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c156
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c129
-rw-r--r--drivers/net/wireless/rsi/rsi_main.h4
-rw-r--r--drivers/net/wireless/rsi/rsi_mgmt.h23
65 files changed, 2560 insertions, 788 deletions
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index bd46569e0e52..925842996986 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -295,6 +295,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = {
295 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, 295 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
296 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, 296 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) },
297 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) }, 297 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) },
298 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0018) },
298 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_FOXCONN, 0xe092) }, 299 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_FOXCONN, 0xe092) },
299 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, 300 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) },
300 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, 301 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 7005e2a98726..749e381edd38 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -326,6 +326,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
326 [ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl", 326 [ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
327 [ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param", 327 [ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",
328 [ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war", 328 [ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war",
329 [ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST] = "allows-mesh-bcast",
329}; 330};
330 331
331static unsigned int ath10k_core_get_fw_feature_str(char *buf, 332static unsigned int ath10k_core_get_fw_feature_str(char *buf,
@@ -1536,7 +1537,7 @@ static void ath10k_core_restart(struct work_struct *work)
1536 switch (ar->state) { 1537 switch (ar->state) {
1537 case ATH10K_STATE_ON: 1538 case ATH10K_STATE_ON:
1538 ar->state = ATH10K_STATE_RESTARTING; 1539 ar->state = ATH10K_STATE_RESTARTING;
1539 ath10k_hif_stop(ar); 1540 ath10k_halt(ar);
1540 ath10k_scan_finish(ar); 1541 ath10k_scan_finish(ar);
1541 ieee80211_restart_hw(ar->hw); 1542 ieee80211_restart_hw(ar->hw);
1542 break; 1543 break;
@@ -1857,7 +1858,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
1857 goto err_wmi_detach; 1858 goto err_wmi_detach;
1858 } 1859 }
1859 1860
1860 status = ath10k_htt_tx_alloc(&ar->htt); 1861 status = ath10k_htt_tx_start(&ar->htt);
1861 if (status) { 1862 if (status) {
1862 ath10k_err(ar, "failed to alloc htt tx: %d\n", status); 1863 ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
1863 goto err_wmi_detach; 1864 goto err_wmi_detach;
@@ -2052,7 +2053,7 @@ void ath10k_core_stop(struct ath10k *ar)
2052 ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); 2053 ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
2053 2054
2054 ath10k_hif_stop(ar); 2055 ath10k_hif_stop(ar);
2055 ath10k_htt_tx_free(&ar->htt); 2056 ath10k_htt_tx_stop(&ar->htt);
2056 ath10k_htt_rx_free(&ar->htt); 2057 ath10k_htt_rx_free(&ar->htt);
2057 ath10k_wmi_detach(ar); 2058 ath10k_wmi_detach(ar);
2058} 2059}
@@ -2385,6 +2386,7 @@ void ath10k_core_destroy(struct ath10k *ar)
2385 destroy_workqueue(ar->workqueue_aux); 2386 destroy_workqueue(ar->workqueue_aux);
2386 2387
2387 ath10k_debug_destroy(ar); 2388 ath10k_debug_destroy(ar);
2389 ath10k_htt_tx_destroy(&ar->htt);
2388 ath10k_wmi_free_host_mem(ar); 2390 ath10k_wmi_free_host_mem(ar);
2389 ath10k_mac_destroy(ar); 2391 ath10k_mac_destroy(ar);
2390} 2392}
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index e8decfaba5b6..09ff8b8a6441 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -337,6 +337,7 @@ struct ath10k_sta {
337 u32 nss; 337 u32 nss;
338 u32 smps; 338 u32 smps;
339 u16 peer_id; 339 u16 peer_id;
340 struct rate_info txrate;
340 341
341 struct work_struct update_wk; 342 struct work_struct update_wk;
342 343
@@ -562,6 +563,13 @@ enum ath10k_fw_features {
562 */ 563 */
563 ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15, 564 ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15,
564 565
566 /* Firmware allow other BSS mesh broadcast/multicast frames without
567 * creating monitor interface. Appropriate rxfilters are programmed for
568 * mesh vdev by firmware itself. This feature flags will be used for
569 * not creating monitor vdev while configuring mesh node.
570 */
571 ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST = 16,
572
565 /* keep last */ 573 /* keep last */
566 ATH10K_FW_FEATURE_COUNT, 574 ATH10K_FW_FEATURE_COUNT,
567}; 575};
@@ -693,6 +701,21 @@ struct ath10k_fw_components {
693 struct ath10k_fw_file fw_file; 701 struct ath10k_fw_file fw_file;
694}; 702};
695 703
704struct ath10k_per_peer_tx_stats {
705 u32 succ_bytes;
706 u32 retry_bytes;
707 u32 failed_bytes;
708 u8 ratecode;
709 u8 flags;
710 u16 peer_id;
711 u16 succ_pkts;
712 u16 retry_pkts;
713 u16 failed_pkts;
714 u16 duration;
715 u32 reserved1;
716 u32 reserved2;
717};
718
696struct ath10k { 719struct ath10k {
697 struct ath_common ath_common; 720 struct ath_common ath_common;
698 struct ieee80211_hw *hw; 721 struct ieee80211_hw *hw;
@@ -906,6 +929,7 @@ struct ath10k {
906 929
907 struct ath10k_thermal thermal; 930 struct ath10k_thermal thermal;
908 struct ath10k_wow wow; 931 struct ath10k_wow wow;
932 struct ath10k_per_peer_tx_stats peer_tx_stats;
909 933
910 /* NAPI */ 934 /* NAPI */
911 struct net_device napi_dev; 935 struct net_device napi_dev;
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
index 9955fea0802a..fce6f8137d33 100644
--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -77,6 +77,19 @@ void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
77 77
78 sinfo->rx_duration = arsta->rx_duration; 78 sinfo->rx_duration = arsta->rx_duration;
79 sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION; 79 sinfo->filled |= 1ULL << NL80211_STA_INFO_RX_DURATION;
80
81 if (!arsta->txrate.legacy && !arsta->txrate.nss)
82 return;
83
84 if (arsta->txrate.legacy) {
85 sinfo->txrate.legacy = arsta->txrate.legacy;
86 } else {
87 sinfo->txrate.mcs = arsta->txrate.mcs;
88 sinfo->txrate.nss = arsta->txrate.nss;
89 sinfo->txrate.bw = arsta->txrate.bw;
90 }
91 sinfo->txrate.flags = arsta->txrate.flags;
92 sinfo->filled |= 1ULL << NL80211_STA_INFO_TX_BITRATE;
80} 93}
81 94
82static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, 95static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
index 130cd9502021..cd160b16db1e 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -137,6 +137,8 @@ static const enum htt_t2h_msg_type htt_10_4_t2h_msg_types[] = {
137 HTT_T2H_MSG_TYPE_STATS_NOUPLOAD, 137 HTT_T2H_MSG_TYPE_STATS_NOUPLOAD,
138 [HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND] = 138 [HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND] =
139 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND, 139 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
140 [HTT_10_4_T2H_MSG_TYPE_PEER_STATS] =
141 HTT_T2H_MSG_TYPE_PEER_STATS,
140}; 142};
141 143
142int ath10k_htt_connect(struct ath10k_htt *htt) 144int ath10k_htt_connect(struct ath10k_htt *htt)
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 0d2ed09f202b..44b25cf00553 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -419,6 +419,7 @@ enum htt_10_4_t2h_msg_type {
419 HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD = 0x18, 419 HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD = 0x18,
420 /* 0x19 to 0x2f are reserved */ 420 /* 0x19 to 0x2f are reserved */
421 HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND = 0x30, 421 HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND = 0x30,
422 HTT_10_4_T2H_MSG_TYPE_PEER_STATS = 0x31,
422 /* keep this last */ 423 /* keep this last */
423 HTT_10_4_T2H_NUM_MSGS 424 HTT_10_4_T2H_NUM_MSGS
424}; 425};
@@ -453,6 +454,7 @@ enum htt_t2h_msg_type {
453 HTT_T2H_MSG_TYPE_TX_FETCH_IND, 454 HTT_T2H_MSG_TYPE_TX_FETCH_IND,
454 HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM, 455 HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM,
455 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND, 456 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
457 HTT_T2H_MSG_TYPE_PEER_STATS,
456 /* keep this last */ 458 /* keep this last */
457 HTT_T2H_NUM_MSGS 459 HTT_T2H_NUM_MSGS
458}; 460};
@@ -1470,6 +1472,28 @@ struct htt_channel_change {
1470 __le32 phymode; 1472 __le32 phymode;
1471} __packed; 1473} __packed;
1472 1474
1475struct htt_per_peer_tx_stats_ind {
1476 __le32 succ_bytes;
1477 __le32 retry_bytes;
1478 __le32 failed_bytes;
1479 u8 ratecode;
1480 u8 flags;
1481 __le16 peer_id;
1482 __le16 succ_pkts;
1483 __le16 retry_pkts;
1484 __le16 failed_pkts;
1485 __le16 tx_duration;
1486 __le32 reserved1;
1487 __le32 reserved2;
1488} __packed;
1489
1490struct htt_peer_tx_stats {
1491 u8 num_ppdu;
1492 u8 ppdu_len;
1493 u8 version;
1494 u8 payload[0];
1495} __packed;
1496
1473union htt_rx_pn_t { 1497union htt_rx_pn_t {
1474 /* WEP: 24-bit PN */ 1498 /* WEP: 24-bit PN */
1475 u32 pn24; 1499 u32 pn24;
@@ -1521,6 +1545,7 @@ struct htt_resp {
1521 struct htt_tx_fetch_confirm tx_fetch_confirm; 1545 struct htt_tx_fetch_confirm tx_fetch_confirm;
1522 struct htt_tx_mode_switch_ind tx_mode_switch_ind; 1546 struct htt_tx_mode_switch_ind tx_mode_switch_ind;
1523 struct htt_channel_change chan_change; 1547 struct htt_channel_change chan_change;
1548 struct htt_peer_tx_stats peer_tx_stats;
1524 }; 1549 };
1525} __packed; 1550} __packed;
1526 1551
@@ -1692,6 +1717,8 @@ struct ath10k_htt {
1692 enum htt_tx_mode_switch_mode mode; 1717 enum htt_tx_mode_switch_mode mode;
1693 enum htt_q_depth_type type; 1718 enum htt_q_depth_type type;
1694 } tx_q_state; 1719 } tx_q_state;
1720
1721 bool tx_mem_allocated;
1695}; 1722};
1696 1723
1697#define RX_HTT_HDR_STATUS_LEN 64 1724#define RX_HTT_HDR_STATUS_LEN 64
@@ -1754,7 +1781,9 @@ int ath10k_htt_connect(struct ath10k_htt *htt);
1754int ath10k_htt_init(struct ath10k *ar); 1781int ath10k_htt_init(struct ath10k *ar);
1755int ath10k_htt_setup(struct ath10k_htt *htt); 1782int ath10k_htt_setup(struct ath10k_htt *htt);
1756 1783
1757int ath10k_htt_tx_alloc(struct ath10k_htt *htt); 1784int ath10k_htt_tx_start(struct ath10k_htt *htt);
1785void ath10k_htt_tx_stop(struct ath10k_htt *htt);
1786void ath10k_htt_tx_destroy(struct ath10k_htt *htt);
1758void ath10k_htt_tx_free(struct ath10k_htt *htt); 1787void ath10k_htt_tx_free(struct ath10k_htt *htt);
1759 1788
1760int ath10k_htt_rx_alloc(struct ath10k_htt *htt); 1789int ath10k_htt_rx_alloc(struct ath10k_htt *htt);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 285b235268d7..86d082cf4eef 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2194,6 +2194,128 @@ void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2194 dev_kfree_skb_any(skb); 2194 dev_kfree_skb_any(skb);
2195} 2195}
2196 2196
2197static inline bool is_valid_legacy_rate(u8 rate)
2198{
2199 static const u8 legacy_rates[] = {1, 2, 5, 11, 6, 9, 12,
2200 18, 24, 36, 48, 54};
2201 int i;
2202
2203 for (i = 0; i < ARRAY_SIZE(legacy_rates); i++) {
2204 if (rate == legacy_rates[i])
2205 return true;
2206 }
2207
2208 return false;
2209}
2210
2211static void
2212ath10k_update_per_peer_tx_stats(struct ath10k *ar,
2213 struct ieee80211_sta *sta,
2214 struct ath10k_per_peer_tx_stats *peer_stats)
2215{
2216 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
2217 u8 rate = 0, sgi;
2218 struct rate_info txrate;
2219
2220 lockdep_assert_held(&ar->data_lock);
2221
2222 txrate.flags = ATH10K_HW_PREAMBLE(peer_stats->ratecode);
2223 txrate.bw = ATH10K_HW_BW(peer_stats->flags);
2224 txrate.nss = ATH10K_HW_NSS(peer_stats->ratecode);
2225 txrate.mcs = ATH10K_HW_MCS_RATE(peer_stats->ratecode);
2226 sgi = ATH10K_HW_GI(peer_stats->flags);
2227
2228 if (((txrate.flags == WMI_RATE_PREAMBLE_HT) ||
2229 (txrate.flags == WMI_RATE_PREAMBLE_VHT)) && txrate.mcs > 9) {
2230 ath10k_warn(ar, "Invalid mcs %hhd peer stats", txrate.mcs);
2231 return;
2232 }
2233
2234 if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
2235 txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
2236 rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
2237
2238 if (!is_valid_legacy_rate(rate)) {
2239 ath10k_warn(ar, "Invalid legacy rate %hhd peer stats",
2240 rate);
2241 return;
2242 }
2243
2244 /* This is hacky, FW sends CCK rate 5.5Mbps as 6 */
2245 rate *= 10;
2246 if (rate == 60 && txrate.flags == WMI_RATE_PREAMBLE_CCK)
2247 rate = rate - 5;
2248 arsta->txrate.legacy = rate * 10;
2249 } else if (txrate.flags == WMI_RATE_PREAMBLE_HT) {
2250 arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
2251 arsta->txrate.mcs = txrate.mcs;
2252 } else {
2253 arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
2254 arsta->txrate.mcs = txrate.mcs;
2255 }
2256
2257 if (sgi)
2258 arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
2259
2260 arsta->txrate.nss = txrate.nss;
2261 arsta->txrate.bw = txrate.bw + RATE_INFO_BW_20;
2262}
2263
2264static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
2265 struct sk_buff *skb)
2266{
2267 struct htt_resp *resp = (struct htt_resp *)skb->data;
2268 struct ath10k_per_peer_tx_stats *p_tx_stats = &ar->peer_tx_stats;
2269 struct htt_per_peer_tx_stats_ind *tx_stats;
2270 struct ieee80211_sta *sta;
2271 struct ath10k_peer *peer;
2272 int peer_id, i;
2273 u8 ppdu_len, num_ppdu;
2274
2275 num_ppdu = resp->peer_tx_stats.num_ppdu;
2276 ppdu_len = resp->peer_tx_stats.ppdu_len * sizeof(__le32);
2277
2278 if (skb->len < sizeof(struct htt_resp_hdr) + num_ppdu * ppdu_len) {
2279 ath10k_warn(ar, "Invalid peer stats buf length %d\n", skb->len);
2280 return;
2281 }
2282
2283 tx_stats = (struct htt_per_peer_tx_stats_ind *)
2284 (resp->peer_tx_stats.payload);
2285 peer_id = __le16_to_cpu(tx_stats->peer_id);
2286
2287 rcu_read_lock();
2288 spin_lock_bh(&ar->data_lock);
2289 peer = ath10k_peer_find_by_id(ar, peer_id);
2290 if (!peer) {
2291 ath10k_warn(ar, "Invalid peer id %d peer stats buffer\n",
2292 peer_id);
2293 goto out;
2294 }
2295
2296 sta = peer->sta;
2297 for (i = 0; i < num_ppdu; i++) {
2298 tx_stats = (struct htt_per_peer_tx_stats_ind *)
2299 (resp->peer_tx_stats.payload + i * ppdu_len);
2300
2301 p_tx_stats->succ_bytes = __le32_to_cpu(tx_stats->succ_bytes);
2302 p_tx_stats->retry_bytes = __le32_to_cpu(tx_stats->retry_bytes);
2303 p_tx_stats->failed_bytes =
2304 __le32_to_cpu(tx_stats->failed_bytes);
2305 p_tx_stats->ratecode = tx_stats->ratecode;
2306 p_tx_stats->flags = tx_stats->flags;
2307 p_tx_stats->succ_pkts = __le16_to_cpu(tx_stats->succ_pkts);
2308 p_tx_stats->retry_pkts = __le16_to_cpu(tx_stats->retry_pkts);
2309 p_tx_stats->failed_pkts = __le16_to_cpu(tx_stats->failed_pkts);
2310
2311 ath10k_update_per_peer_tx_stats(ar, sta, p_tx_stats);
2312 }
2313
2314out:
2315 spin_unlock_bh(&ar->data_lock);
2316 rcu_read_unlock();
2317}
2318
2197bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) 2319bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2198{ 2320{
2199 struct ath10k_htt *htt = &ar->htt; 2321 struct ath10k_htt *htt = &ar->htt;
@@ -2354,6 +2476,9 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2354 case HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND: 2476 case HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND:
2355 ath10k_htt_rx_tx_mode_switch_ind(ar, skb); 2477 ath10k_htt_rx_tx_mode_switch_ind(ar, skb);
2356 break; 2478 break;
2479 case HTT_T2H_MSG_TYPE_PEER_STATS:
2480 ath10k_htt_fetch_peer_stats(ar, skb);
2481 break;
2357 case HTT_T2H_MSG_TYPE_EN_STATS: 2482 case HTT_T2H_MSG_TYPE_EN_STATS:
2358 default: 2483 default:
2359 ath10k_warn(ar, "htt event (%d) not handled\n", 2484 ath10k_warn(ar, "htt event (%d) not handled\n",
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index ccbc8c03abc1..27e49db4287a 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -350,21 +350,15 @@ static int ath10k_htt_tx_alloc_txdone_fifo(struct ath10k_htt *htt)
350 return ret; 350 return ret;
351} 351}
352 352
353int ath10k_htt_tx_alloc(struct ath10k_htt *htt) 353static int ath10k_htt_tx_alloc_buf(struct ath10k_htt *htt)
354{ 354{
355 struct ath10k *ar = htt->ar; 355 struct ath10k *ar = htt->ar;
356 int ret; 356 int ret;
357 357
358 ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
359 htt->max_num_pending_tx);
360
361 spin_lock_init(&htt->tx_lock);
362 idr_init(&htt->pending_tx);
363
364 ret = ath10k_htt_tx_alloc_cont_txbuf(htt); 358 ret = ath10k_htt_tx_alloc_cont_txbuf(htt);
365 if (ret) { 359 if (ret) {
366 ath10k_err(ar, "failed to alloc cont tx buffer: %d\n", ret); 360 ath10k_err(ar, "failed to alloc cont tx buffer: %d\n", ret);
367 goto free_idr_pending_tx; 361 return ret;
368 } 362 }
369 363
370 ret = ath10k_htt_tx_alloc_cont_frag_desc(htt); 364 ret = ath10k_htt_tx_alloc_cont_frag_desc(htt);
@@ -396,6 +390,31 @@ free_frag_desc:
396free_txbuf: 390free_txbuf:
397 ath10k_htt_tx_free_cont_txbuf(htt); 391 ath10k_htt_tx_free_cont_txbuf(htt);
398 392
393 return ret;
394}
395
396int ath10k_htt_tx_start(struct ath10k_htt *htt)
397{
398 struct ath10k *ar = htt->ar;
399 int ret;
400
401 ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
402 htt->max_num_pending_tx);
403
404 spin_lock_init(&htt->tx_lock);
405 idr_init(&htt->pending_tx);
406
407 if (htt->tx_mem_allocated)
408 return 0;
409
410 ret = ath10k_htt_tx_alloc_buf(htt);
411 if (ret)
412 goto free_idr_pending_tx;
413
414 htt->tx_mem_allocated = true;
415
416 return 0;
417
399free_idr_pending_tx: 418free_idr_pending_tx:
400 idr_destroy(&htt->pending_tx); 419 idr_destroy(&htt->pending_tx);
401 420
@@ -418,15 +437,28 @@ static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)
418 return 0; 437 return 0;
419} 438}
420 439
421void ath10k_htt_tx_free(struct ath10k_htt *htt) 440void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
422{ 441{
423 idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); 442 if (!htt->tx_mem_allocated)
424 idr_destroy(&htt->pending_tx); 443 return;
425 444
426 ath10k_htt_tx_free_cont_txbuf(htt); 445 ath10k_htt_tx_free_cont_txbuf(htt);
427 ath10k_htt_tx_free_txq(htt); 446 ath10k_htt_tx_free_txq(htt);
428 ath10k_htt_tx_free_cont_frag_desc(htt); 447 ath10k_htt_tx_free_cont_frag_desc(htt);
429 ath10k_htt_tx_free_txdone_fifo(htt); 448 ath10k_htt_tx_free_txdone_fifo(htt);
449 htt->tx_mem_allocated = false;
450}
451
452void ath10k_htt_tx_stop(struct ath10k_htt *htt)
453{
454 idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
455 idr_destroy(&htt->pending_tx);
456}
457
458void ath10k_htt_tx_free(struct ath10k_htt *htt)
459{
460 ath10k_htt_tx_stop(htt);
461 ath10k_htt_tx_destroy(htt);
430} 462}
431 463
432void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) 464void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 717b2fad9a8a..aa545a1dbdc7 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1167,7 +1167,9 @@ static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1167 return false; 1167 return false;
1168 1168
1169 return ar->monitor || 1169 return ar->monitor ||
1170 ar->filter_flags & FIF_OTHER_BSS || 1170 (!test_bit(ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST,
1171 ar->running_fw->fw_file.fw_features) &&
1172 (ar->filter_flags & FIF_OTHER_BSS)) ||
1171 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); 1173 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1172} 1174}
1173 1175
@@ -4449,7 +4451,6 @@ static int ath10k_start(struct ieee80211_hw *hw)
4449 ar->state = ATH10K_STATE_ON; 4451 ar->state = ATH10K_STATE_ON;
4450 break; 4452 break;
4451 case ATH10K_STATE_RESTARTING: 4453 case ATH10K_STATE_RESTARTING:
4452 ath10k_halt(ar);
4453 ar->state = ATH10K_STATE_RESTARTED; 4454 ar->state = ATH10K_STATE_RESTARTED;
4454 break; 4455 break;
4455 case ATH10K_STATE_ON: 4456 case ATH10K_STATE_ON:
@@ -6976,40 +6977,28 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6976 ieee80211_queue_work(hw, &arsta->update_wk); 6977 ieee80211_queue_work(hw, &arsta->update_wk);
6977} 6978}
6978 6979
6979static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 6980static void ath10k_offset_tsf(struct ieee80211_hw *hw,
6980{ 6981 struct ieee80211_vif *vif, s64 tsf_offset)
6981 /*
6982 * FIXME: Return 0 for time being. Need to figure out whether FW
6983 * has the API to fetch 64-bit local TSF
6984 */
6985
6986 return 0;
6987}
6988
6989static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6990 u64 tsf)
6991{ 6982{
6992 struct ath10k *ar = hw->priv; 6983 struct ath10k *ar = hw->priv;
6993 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 6984 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6994 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf; 6985 u32 offset, vdev_param;
6995 int ret; 6986 int ret;
6996 6987
6997 /* Workaround: 6988 if (tsf_offset < 0) {
6998 * 6989 vdev_param = ar->wmi.vdev_param->dec_tsf;
6999 * Given tsf argument is entire TSF value, but firmware accepts 6990 offset = -tsf_offset;
7000 * only TSF offset to current TSF. 6991 } else {
7001 * 6992 vdev_param = ar->wmi.vdev_param->inc_tsf;
7002 * get_tsf function is used to get offset value, however since 6993 offset = tsf_offset;
7003 * ath10k_get_tsf is not implemented properly, it will return 0 always. 6994 }
7004 * Luckily all the caller functions to set_tsf, as of now, also rely on 6995
7005 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
7006 * final tsf offset value to firmware will be arithmetically correct.
7007 */
7008 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
7009 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, 6996 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
7010 vdev_param, tsf_offset); 6997 vdev_param, offset);
6998
7011 if (ret && ret != -EOPNOTSUPP) 6999 if (ret && ret != -EOPNOTSUPP)
7012 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret); 7000 ath10k_warn(ar, "failed to set tsf offset %d cmd %d: %d\n",
7001 offset, vdev_param, ret);
7013} 7002}
7014 7003
7015static int ath10k_ampdu_action(struct ieee80211_hw *hw, 7004static int ath10k_ampdu_action(struct ieee80211_hw *hw,
@@ -7474,8 +7463,7 @@ static const struct ieee80211_ops ath10k_ops = {
7474 .get_survey = ath10k_get_survey, 7463 .get_survey = ath10k_get_survey,
7475 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask, 7464 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
7476 .sta_rc_update = ath10k_sta_rc_update, 7465 .sta_rc_update = ath10k_sta_rc_update,
7477 .get_tsf = ath10k_get_tsf, 7466 .offset_tsf = ath10k_offset_tsf,
7478 .set_tsf = ath10k_set_tsf,
7479 .ampdu_action = ath10k_ampdu_action, 7467 .ampdu_action = ath10k_ampdu_action,
7480 .get_et_sset_count = ath10k_debug_get_et_sset_count, 7468 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7481 .get_et_stats = ath10k_debug_get_et_stats, 7469 .get_et_stats = ath10k_debug_get_et_stats,
@@ -8006,6 +7994,7 @@ int ath10k_mac_register(struct ath10k *ar)
8006 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA); 7994 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
8007 ieee80211_hw_set(ar->hw, QUEUE_CONTROL); 7995 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
8008 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); 7996 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
7997 ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
8009 7998
8010 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) 7999 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8011 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL); 8000 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index c9a8bb1186f2..c7956e181f80 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -660,6 +660,9 @@ ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
660 struct sk_buff *skb; 660 struct sk_buff *skb;
661 u32 cmd_id; 661 u32 cmd_id;
662 662
663 if (!ar->wmi.ops->gen_vdev_spectral_conf)
664 return -EOPNOTSUPP;
665
663 skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg); 666 skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg);
664 if (IS_ERR(skb)) 667 if (IS_ERR(skb))
665 return PTR_ERR(skb); 668 return PTR_ERR(skb);
@@ -675,6 +678,9 @@ ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger,
675 struct sk_buff *skb; 678 struct sk_buff *skb;
676 u32 cmd_id; 679 u32 cmd_id;
677 680
681 if (!ar->wmi.ops->gen_vdev_spectral_enable)
682 return -EOPNOTSUPP;
683
678 skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger, 684 skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger,
679 enable); 685 enable);
680 if (IS_ERR(skb)) 686 if (IS_ERR(skb))
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index e64f59300a7c..f304f6632c4f 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1313,8 +1313,8 @@ ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
1313 cmd->regd = __cpu_to_le32(rd); 1313 cmd->regd = __cpu_to_le32(rd);
1314 cmd->regd_2ghz = __cpu_to_le32(rd2g); 1314 cmd->regd_2ghz = __cpu_to_le32(rd2g);
1315 cmd->regd_5ghz = __cpu_to_le32(rd5g); 1315 cmd->regd_5ghz = __cpu_to_le32(rd5g);
1316 cmd->conform_limit_2ghz = __cpu_to_le32(rd2g); 1316 cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g);
1317 cmd->conform_limit_5ghz = __cpu_to_le32(rd5g); 1317 cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g);
1318 1318
1319 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n"); 1319 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
1320 return skb; 1320 return skb;
@@ -3136,6 +3136,76 @@ ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value)
3136 return skb; 3136 return skb;
3137} 3137}
3138 3138
3139static struct sk_buff *
3140ath10k_wmi_tlv_op_gen_vdev_spectral_conf(struct ath10k *ar,
3141 const struct wmi_vdev_spectral_conf_arg *arg)
3142{
3143 struct wmi_vdev_spectral_conf_cmd *cmd;
3144 struct sk_buff *skb;
3145 struct wmi_tlv *tlv;
3146 void *ptr;
3147 size_t len;
3148
3149 len = sizeof(*tlv) + sizeof(*cmd);
3150 skb = ath10k_wmi_alloc_skb(ar, len);
3151 if (!skb)
3152 return ERR_PTR(-ENOMEM);
3153
3154 ptr = (void *)skb->data;
3155 tlv = ptr;
3156 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD);
3157 tlv->len = __cpu_to_le16(sizeof(*cmd));
3158 cmd = (void *)tlv->value;
3159 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
3160 cmd->scan_count = __cpu_to_le32(arg->scan_count);
3161 cmd->scan_period = __cpu_to_le32(arg->scan_period);
3162 cmd->scan_priority = __cpu_to_le32(arg->scan_priority);
3163 cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size);
3164 cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena);
3165 cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena);
3166 cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref);
3167 cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay);
3168 cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr);
3169 cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr);
3170 cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode);
3171 cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode);
3172 cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr);
3173 cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format);
3174 cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode);
3175 cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale);
3176 cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
3177 cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
3178
3179 return skb;
3180}
3181
3182static struct sk_buff *
3183ath10k_wmi_tlv_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
3184 u32 trigger, u32 enable)
3185{
3186 struct wmi_vdev_spectral_enable_cmd *cmd;
3187 struct sk_buff *skb;
3188 struct wmi_tlv *tlv;
3189 void *ptr;
3190 size_t len;
3191
3192 len = sizeof(*tlv) + sizeof(*cmd);
3193 skb = ath10k_wmi_alloc_skb(ar, len);
3194 if (!skb)
3195 return ERR_PTR(-ENOMEM);
3196
3197 ptr = (void *)skb->data;
3198 tlv = ptr;
3199 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD);
3200 tlv->len = __cpu_to_le16(sizeof(*cmd));
3201 cmd = (void *)tlv->value;
3202 cmd->vdev_id = __cpu_to_le32(vdev_id);
3203 cmd->trigger_cmd = __cpu_to_le32(trigger);
3204 cmd->enable_cmd = __cpu_to_le32(enable);
3205
3206 return skb;
3207}
3208
3139/****************/ 3209/****************/
3140/* TLV mappings */ 3210/* TLV mappings */
3141/****************/ 3211/****************/
@@ -3464,7 +3534,6 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
3464 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, 3534 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
3465 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, 3535 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
3466 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 3536 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
3467 .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
3468}; 3537};
3469 3538
3470static const struct wmi_ops wmi_tlv_ops = { 3539static const struct wmi_ops wmi_tlv_ops = {
@@ -3542,6 +3611,8 @@ static const struct wmi_ops wmi_tlv_ops = {
3542 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 3611 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
3543 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, 3612 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
3544 .gen_echo = ath10k_wmi_tlv_op_gen_echo, 3613 .gen_echo = ath10k_wmi_tlv_op_gen_echo,
3614 .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
3615 .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
3545}; 3616};
3546 3617
3547static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { 3618static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 387c4eede388..c893314a191f 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -785,7 +785,6 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = {
785 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, 785 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
786 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, 786 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
787 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 787 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
788 .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
789}; 788};
790 789
791/* 10.X WMI VDEV param map */ 790/* 10.X WMI VDEV param map */
@@ -861,7 +860,6 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
861 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, 860 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
862 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, 861 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
863 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 862 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
864 .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
865}; 863};
866 864
867static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { 865static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
@@ -936,7 +934,6 @@ static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
936 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED, 934 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
937 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, 935 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
938 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, 936 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
939 .set_tsf = WMI_10X_VDEV_PARAM_TSF_INCREMENT,
940}; 937};
941 938
942static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = { 939static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
@@ -1012,7 +1009,8 @@ static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
1012 .meru_vc = WMI_10_4_VDEV_PARAM_MERU_VC, 1009 .meru_vc = WMI_10_4_VDEV_PARAM_MERU_VC,
1013 .rx_decap_type = WMI_10_4_VDEV_PARAM_RX_DECAP_TYPE, 1010 .rx_decap_type = WMI_10_4_VDEV_PARAM_RX_DECAP_TYPE,
1014 .bw_nss_ratemask = WMI_10_4_VDEV_PARAM_BW_NSS_RATEMASK, 1011 .bw_nss_ratemask = WMI_10_4_VDEV_PARAM_BW_NSS_RATEMASK,
1015 .set_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT, 1012 .inc_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
1013 .dec_tsf = WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
1016}; 1014};
1017 1015
1018static struct wmi_pdev_param_map wmi_pdev_param_map = { 1016static struct wmi_pdev_param_map wmi_pdev_param_map = {
@@ -4489,7 +4487,7 @@ static int ath10k_wmi_alloc_chunk(struct ath10k *ar, u32 req_id,
4489 if (!num_units) 4487 if (!num_units)
4490 return -ENOMEM; 4488 return -ENOMEM;
4491 4489
4492 paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_TO_DEVICE); 4490 paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_BIDIRECTIONAL);
4493 if (dma_mapping_error(ar->dev, paddr)) { 4491 if (dma_mapping_error(ar->dev, paddr)) {
4494 kfree(vaddr); 4492 kfree(vaddr);
4495 return -ENOMEM; 4493 return -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 1b243c899bef..5d3dff95b2e5 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4603,9 +4603,17 @@ enum wmi_rate_preamble {
4603 4603
4604#define ATH10K_HW_NSS(rate) (1 + (((rate) >> 4) & 0x3)) 4604#define ATH10K_HW_NSS(rate) (1 + (((rate) >> 4) & 0x3))
4605#define ATH10K_HW_PREAMBLE(rate) (((rate) >> 6) & 0x3) 4605#define ATH10K_HW_PREAMBLE(rate) (((rate) >> 6) & 0x3)
4606#define ATH10K_HW_RATECODE(rate, nss, preamble) \ 4606#define ATH10K_HW_MCS_RATE(rate) ((rate) & 0xf)
4607#define ATH10K_HW_LEGACY_RATE(rate) ((rate) & 0x3f)
4608#define ATH10K_HW_BW(flags) (((flags) >> 3) & 0x3)
4609#define ATH10K_HW_GI(flags) (((flags) >> 5) & 0x1)
4610#define ATH10K_HW_RATECODE(rate, nss, preamble) \
4607 (((preamble) << 6) | ((nss) << 4) | (rate)) 4611 (((preamble) << 6) | ((nss) << 4) | (rate))
4608 4612
4613#define VHT_MCS_NUM 10
4614#define VHT_BW_NUM 4
4615#define VHT_NSS_NUM 4
4616
4609/* Value to disable fixed rate setting */ 4617/* Value to disable fixed rate setting */
4610#define WMI_FIXED_RATE_NONE (0xff) 4618#define WMI_FIXED_RATE_NONE (0xff)
4611 4619
@@ -4676,7 +4684,8 @@ struct wmi_vdev_param_map {
4676 u32 meru_vc; 4684 u32 meru_vc;
4677 u32 rx_decap_type; 4685 u32 rx_decap_type;
4678 u32 bw_nss_ratemask; 4686 u32 bw_nss_ratemask;
4679 u32 set_tsf; 4687 u32 inc_tsf;
4688 u32 dec_tsf;
4680}; 4689};
4681 4690
4682#define WMI_VDEV_PARAM_UNSUPPORTED 0 4691#define WMI_VDEV_PARAM_UNSUPPORTED 0
@@ -5009,6 +5018,11 @@ enum wmi_10_4_vdev_param {
5009 WMI_10_4_VDEV_PARAM_STA_KICKOUT, 5018 WMI_10_4_VDEV_PARAM_STA_KICKOUT,
5010 WMI_10_4_VDEV_PARAM_CAPABILITIES, 5019 WMI_10_4_VDEV_PARAM_CAPABILITIES,
5011 WMI_10_4_VDEV_PARAM_TSF_INCREMENT, 5020 WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
5021 WMI_10_4_VDEV_PARAM_RX_FILTER,
5022 WMI_10_4_VDEV_PARAM_MGMT_TX_POWER,
5023 WMI_10_4_VDEV_PARAM_ATF_SSID_SCHED_POLICY,
5024 WMI_10_4_VDEV_PARAM_DISABLE_DYN_BW_RTS,
5025 WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
5012}; 5026};
5013 5027
5014#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0) 5028#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 4f8d9ed04f5e..d068df520e7a 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -66,7 +66,6 @@
66 66
67#include <linux/seq_file.h> 67#include <linux/seq_file.h>
68#include <linux/list.h> 68#include <linux/list.h>
69#include <linux/vmalloc.h>
70#include "debug.h" 69#include "debug.h"
71#include "ath5k.h" 70#include "ath5k.h"
72#include "reg.h" 71#include "reg.h"
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index bea6186f745a..2bd982c3a479 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -62,7 +62,7 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
62 return false; 62 return false;
63} 63}
64 64
65static struct ath_bus_ops ath_ahb_bus_ops = { 65static const struct ath_bus_ops ath_ahb_bus_ops = {
66 .ath_bus_type = ATH_AHB, 66 .ath_bus_type = ATH_AHB,
67 .read_cachesize = ath_ahb_read_cachesize, 67 .read_cachesize = ath_ahb_read_cachesize,
68 .eeprom_read = ath_ahb_eeprom_read, 68 .eeprom_read = ath_ahb_eeprom_read,
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index e2512d5bc0e1..eedf86b67cf5 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
@@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h
528 if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK)) 528 if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
529 return 0; 529 return 0;
530 530
531 if (!spec_priv->rfs_chan_spec_scan)
532 return 1;
533
531 /* Output buffers are full, no need to process anything 534 /* Output buffers are full, no need to process anything
532 * since there is no space to put the result anyway 535 * since there is no space to put the result anyway
533 */ 536 */
@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = {
1072 1075
1073void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) 1076void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
1074{ 1077{
1075 if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS)) { 1078 if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
1076 relay_close(spec_priv->rfs_chan_spec_scan); 1079 relay_close(spec_priv->rfs_chan_spec_scan);
1077 spec_priv->rfs_chan_spec_scan = NULL; 1080 spec_priv->rfs_chan_spec_scan = NULL;
1078 } 1081 }
@@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,
1086 debugfs_phy, 1089 debugfs_phy,
1087 1024, 256, &rfs_spec_scan_cb, 1090 1024, 256, &rfs_spec_scan_cb,
1088 NULL); 1091 NULL);
1092 if (!spec_priv->rfs_chan_spec_scan)
1093 return;
1094
1089 debugfs_create_file("spectral_scan_ctl", 1095 debugfs_create_file("spectral_scan_ctl",
1090 S_IRUSR | S_IWUSR, 1096 S_IRUSR | S_IWUSR,
1091 debugfs_phy, spec_priv, 1097 debugfs_phy, spec_priv,
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index e1c338cb9cb5..de2d212f39ec 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -997,7 +997,8 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
997 err = usb_control_msg(hif_dev->udev, 997 err = usb_control_msg(hif_dev->udev,
998 usb_sndctrlpipe(hif_dev->udev, 0), 998 usb_sndctrlpipe(hif_dev->udev, 0),
999 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT, 999 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
1000 addr >> 8, 0, buf, transfer, HZ); 1000 addr >> 8, 0, buf, transfer,
1001 USB_MSG_TIMEOUT);
1001 if (err < 0) { 1002 if (err < 0) {
1002 kfree(buf); 1003 kfree(buf);
1003 return err; 1004 return err;
@@ -1020,7 +1021,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
1020 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0), 1021 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
1021 FIRMWARE_DOWNLOAD_COMP, 1022 FIRMWARE_DOWNLOAD_COMP,
1022 0x40 | USB_DIR_OUT, 1023 0x40 | USB_DIR_OUT,
1023 firm_offset >> 8, 0, NULL, 0, HZ); 1024 firm_offset >> 8, 0, NULL, 0, USB_MSG_TIMEOUT);
1024 if (err) 1025 if (err)
1025 return -EIO; 1026 return -EIO;
1026 1027
@@ -1249,7 +1250,7 @@ static int send_eject_command(struct usb_interface *interface)
1249 1250
1250 dev_info(&udev->dev, "Ejecting storage device...\n"); 1251 dev_info(&udev->dev, "Ejecting storage device...\n");
1251 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep), 1252 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
1252 cmd, 31, NULL, 2000); 1253 cmd, 31, NULL, 2 * USB_MSG_TIMEOUT);
1253 kfree(cmd); 1254 kfree(cmd);
1254 if (r) 1255 if (r)
1255 return r; 1256 return r;
@@ -1314,7 +1315,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev)
1314 return; 1315 return;
1315 1316
1316 ret = usb_interrupt_msg(udev, usb_sndintpipe(udev, USB_REG_OUT_PIPE), 1317 ret = usb_interrupt_msg(udev, usb_sndintpipe(udev, USB_REG_OUT_PIPE),
1317 buf, 4, NULL, HZ); 1318 buf, 4, NULL, USB_MSG_TIMEOUT);
1318 if (ret) 1319 if (ret)
1319 dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n"); 1320 dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n");
1320 1321
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 7c2ef7ecd98b..7846916aa01d 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -71,6 +71,8 @@ extern int htc_use_dev_fw;
71#define USB_REG_IN_PIPE 3 71#define USB_REG_IN_PIPE 3
72#define USB_REG_OUT_PIPE 4 72#define USB_REG_OUT_PIPE 4
73 73
74#define USB_MSG_TIMEOUT 1000 /* (ms) */
75
74#define HIF_USB_MAX_RXPIPES 2 76#define HIF_USB_MAX_RXPIPES 2
75#define HIF_USB_MAX_TXPIPES 4 77#define HIF_USB_MAX_TXPIPES 4
76 78
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 14b13f07cd1f..a35f78be8dec 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2792,7 +2792,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
2792 WARN_ON(1); 2792 WARN_ON(1);
2793 } 2793 }
2794 2794
2795 return val; 2795 return !!val;
2796} 2796}
2797EXPORT_SYMBOL(ath9k_hw_gpio_get); 2797EXPORT_SYMBOL(ath9k_hw_gpio_get);
2798 2798
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 669734252664..fb4ba27d92b7 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -867,10 +867,21 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
867 * can be dropped. 867 * can be dropped.
868 */ 868 */
869 if (rx_stats->rs_status & ATH9K_RXERR_PHY) { 869 if (rx_stats->rs_status & ATH9K_RXERR_PHY) {
870 ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status->mactime); 870 /*
871 if (ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats, rx_status->mactime)) 871 * DFS and spectral are mutually exclusive
872 *
873 * Since some chips use PHYERR_RADAR as indication for both, we
874 * need to double check which feature is enabled to prevent
875 * feeding spectral or dfs-detector with wrong frames.
876 */
877 if (hw->conf.radar_enabled) {
878 ath9k_dfs_process_phyerr(sc, hdr, rx_stats,
879 rx_status->mactime);
880 } else if (sc->spec_priv.spectral_mode != SPECTRAL_DISABLED &&
881 ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats,
882 rx_status->mactime)) {
872 RX_STAT_INC(rx_spectral); 883 RX_STAT_INC(rx_spectral);
873 884 }
874 return -EINVAL; 885 return -EINVAL;
875 } 886 }
876 887
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index d117240d9a73..6aa3ff4240a9 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -354,14 +354,6 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
354 wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n", 354 wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
355 __func__, wdev, wdev->iftype); 355 __func__, wdev, wdev->iftype);
356 356
357 mutex_lock(&wil->p2p_wdev_mutex);
358 if (wil->scan_request) {
359 wil_err(wil, "Already scanning\n");
360 mutex_unlock(&wil->p2p_wdev_mutex);
361 return -EAGAIN;
362 }
363 mutex_unlock(&wil->p2p_wdev_mutex);
364
365 /* check we are client side */ 357 /* check we are client side */
366 switch (wdev->iftype) { 358 switch (wdev->iftype) {
367 case NL80211_IFTYPE_STATION: 359 case NL80211_IFTYPE_STATION:
@@ -378,12 +370,24 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
378 return -EBUSY; 370 return -EBUSY;
379 } 371 }
380 372
373 mutex_lock(&wil->mutex);
374
375 mutex_lock(&wil->p2p_wdev_mutex);
376 if (wil->scan_request || wil->p2p.discovery_started) {
377 wil_err(wil, "Already scanning\n");
378 mutex_unlock(&wil->p2p_wdev_mutex);
379 rc = -EAGAIN;
380 goto out;
381 }
382 mutex_unlock(&wil->p2p_wdev_mutex);
383
381 /* social scan on P2P_DEVICE is handled as p2p search */ 384 /* social scan on P2P_DEVICE is handled as p2p search */
382 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE && 385 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
383 wil_p2p_is_social_scan(request)) { 386 wil_p2p_is_social_scan(request)) {
384 if (!wil->p2p.p2p_dev_started) { 387 if (!wil->p2p.p2p_dev_started) {
385 wil_err(wil, "P2P search requested on stopped P2P device\n"); 388 wil_err(wil, "P2P search requested on stopped P2P device\n");
386 return -EIO; 389 rc = -EIO;
390 goto out;
387 } 391 }
388 wil->scan_request = request; 392 wil->scan_request = request;
389 wil->radio_wdev = wdev; 393 wil->radio_wdev = wdev;
@@ -392,7 +396,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
392 wil->radio_wdev = wil_to_wdev(wil); 396 wil->radio_wdev = wil_to_wdev(wil);
393 wil->scan_request = NULL; 397 wil->scan_request = NULL;
394 } 398 }
395 return rc; 399 goto out;
396 } 400 }
397 401
398 (void)wil_p2p_stop_discovery(wil); 402 (void)wil_p2p_stop_discovery(wil);
@@ -415,7 +419,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
415 419
416 if (rc) { 420 if (rc) {
417 wil_err(wil, "set SSID for scan request failed: %d\n", rc); 421 wil_err(wil, "set SSID for scan request failed: %d\n", rc);
418 return rc; 422 goto out;
419 } 423 }
420 424
421 wil->scan_request = request; 425 wil->scan_request = request;
@@ -448,7 +452,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
448 452
449 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie); 453 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie);
450 if (rc) 454 if (rc)
451 goto out; 455 goto out_restore;
452 456
453 if (wil->discovery_mode && cmd.cmd.scan_type == WMI_ACTIVE_SCAN) { 457 if (wil->discovery_mode && cmd.cmd.scan_type == WMI_ACTIVE_SCAN) {
454 cmd.cmd.discovery_mode = 1; 458 cmd.cmd.discovery_mode = 1;
@@ -459,16 +463,45 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
459 rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + 463 rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
460 cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); 464 cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
461 465
462out: 466out_restore:
463 if (rc) { 467 if (rc) {
464 del_timer_sync(&wil->scan_timer); 468 del_timer_sync(&wil->scan_timer);
465 wil->radio_wdev = wil_to_wdev(wil); 469 wil->radio_wdev = wil_to_wdev(wil);
466 wil->scan_request = NULL; 470 wil->scan_request = NULL;
467 } 471 }
468 472out:
473 mutex_unlock(&wil->mutex);
469 return rc; 474 return rc;
470} 475}
471 476
477static void wil_cfg80211_abort_scan(struct wiphy *wiphy,
478 struct wireless_dev *wdev)
479{
480 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
481
482 wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
483
484 mutex_lock(&wil->mutex);
485 mutex_lock(&wil->p2p_wdev_mutex);
486
487 if (!wil->scan_request)
488 goto out;
489
490 if (wdev != wil->scan_request->wdev) {
491 wil_dbg_misc(wil, "abort scan was called on the wrong iface\n");
492 goto out;
493 }
494
495 if (wil->radio_wdev == wil->p2p_wdev)
496 wil_p2p_stop_radio_operations(wil);
497 else
498 wil_abort_scan(wil, true);
499
500out:
501 mutex_unlock(&wil->p2p_wdev_mutex);
502 mutex_unlock(&wil->mutex);
503}
504
472static void wil_print_crypto(struct wil6210_priv *wil, 505static void wil_print_crypto(struct wil6210_priv *wil,
473 struct cfg80211_crypto_settings *c) 506 struct cfg80211_crypto_settings *c)
474{ 507{
@@ -674,6 +707,26 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
674 return rc; 707 return rc;
675} 708}
676 709
710static int wil_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
711{
712 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
713 int rc;
714
715 /* these parameters are explicitly not supported */
716 if (changed & (WIPHY_PARAM_RETRY_LONG |
717 WIPHY_PARAM_FRAG_THRESHOLD |
718 WIPHY_PARAM_RTS_THRESHOLD))
719 return -ENOTSUPP;
720
721 if (changed & WIPHY_PARAM_RETRY_SHORT) {
722 rc = wmi_set_mgmt_retry(wil, wiphy->retry_short);
723 if (rc)
724 return rc;
725 }
726
727 return 0;
728}
729
677int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 730int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
678 struct cfg80211_mgmt_tx_params *params, 731 struct cfg80211_mgmt_tx_params *params,
679 u64 *cookie) 732 u64 *cookie)
@@ -940,16 +993,8 @@ static int wil_remain_on_channel(struct wiphy *wiphy,
940 wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n", 993 wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n",
941 __func__, chan->center_freq, duration, wdev->iftype); 994 __func__, chan->center_freq, duration, wdev->iftype);
942 995
943 rc = wil_p2p_listen(wil, duration, chan, cookie); 996 rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
944 if (rc) 997 return rc;
945 return rc;
946
947 wil->radio_wdev = wdev;
948
949 cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
950 GFP_KERNEL);
951
952 return 0;
953} 998}
954 999
955static int wil_cancel_remain_on_channel(struct wiphy *wiphy, 1000static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
@@ -1419,17 +1464,49 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
1419 1464
1420 wil_dbg_misc(wil, "%s: entered\n", __func__); 1465 wil_dbg_misc(wil, "%s: entered\n", __func__);
1421 mutex_lock(&wil->mutex); 1466 mutex_lock(&wil->mutex);
1467 mutex_lock(&wil->p2p_wdev_mutex);
1422 wil_p2p_stop_radio_operations(wil); 1468 wil_p2p_stop_radio_operations(wil);
1423 p2p->p2p_dev_started = 0; 1469 p2p->p2p_dev_started = 0;
1470 mutex_unlock(&wil->p2p_wdev_mutex);
1424 mutex_unlock(&wil->mutex); 1471 mutex_unlock(&wil->mutex);
1425} 1472}
1426 1473
1474static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1475 struct net_device *dev,
1476 bool enabled, int timeout)
1477{
1478 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1479 enum wmi_ps_profile_type ps_profile;
1480 int rc;
1481
1482 if (!test_bit(WMI_FW_CAPABILITY_PS_CONFIG, wil->fw_capabilities)) {
1483 wil_err(wil, "set_power_mgmt not supported\n");
1484 return -EOPNOTSUPP;
1485 }
1486
1487 wil_dbg_misc(wil, "enabled=%d, timeout=%d\n",
1488 enabled, timeout);
1489
1490 if (enabled)
1491 ps_profile = WMI_PS_PROFILE_TYPE_DEFAULT;
1492 else
1493 ps_profile = WMI_PS_PROFILE_TYPE_PS_DISABLED;
1494
1495 rc = wmi_ps_dev_profile_cfg(wil, ps_profile);
1496 if (rc)
1497 wil_err(wil, "wmi_ps_dev_profile_cfg failed (%d)\n", rc);
1498
1499 return rc;
1500}
1501
1427static struct cfg80211_ops wil_cfg80211_ops = { 1502static struct cfg80211_ops wil_cfg80211_ops = {
1428 .add_virtual_intf = wil_cfg80211_add_iface, 1503 .add_virtual_intf = wil_cfg80211_add_iface,
1429 .del_virtual_intf = wil_cfg80211_del_iface, 1504 .del_virtual_intf = wil_cfg80211_del_iface,
1430 .scan = wil_cfg80211_scan, 1505 .scan = wil_cfg80211_scan,
1506 .abort_scan = wil_cfg80211_abort_scan,
1431 .connect = wil_cfg80211_connect, 1507 .connect = wil_cfg80211_connect,
1432 .disconnect = wil_cfg80211_disconnect, 1508 .disconnect = wil_cfg80211_disconnect,
1509 .set_wiphy_params = wil_cfg80211_set_wiphy_params,
1433 .change_virtual_intf = wil_cfg80211_change_iface, 1510 .change_virtual_intf = wil_cfg80211_change_iface,
1434 .get_station = wil_cfg80211_get_station, 1511 .get_station = wil_cfg80211_get_station,
1435 .dump_station = wil_cfg80211_dump_station, 1512 .dump_station = wil_cfg80211_dump_station,
@@ -1450,6 +1527,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
1450 /* P2P device */ 1527 /* P2P device */
1451 .start_p2p_device = wil_cfg80211_start_p2p_device, 1528 .start_p2p_device = wil_cfg80211_start_p2p_device,
1452 .stop_p2p_device = wil_cfg80211_stop_p2p_device, 1529 .stop_p2p_device = wil_cfg80211_stop_p2p_device,
1530 .set_power_mgmt = wil_cfg80211_set_power_mgmt,
1453}; 1531};
1454 1532
1455static void wil_wiphy_init(struct wiphy *wiphy) 1533static void wil_wiphy_init(struct wiphy *wiphy)
@@ -1466,7 +1544,8 @@ static void wil_wiphy_init(struct wiphy *wiphy)
1466 BIT(NL80211_IFTYPE_MONITOR); 1544 BIT(NL80211_IFTYPE_MONITOR);
1467 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 1545 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
1468 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 1546 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
1469 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; 1547 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
1548 WIPHY_FLAG_PS_ON_BY_DEFAULT;
1470 dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n", 1549 dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
1471 __func__, wiphy->flags); 1550 __func__, wiphy->flags);
1472 wiphy->probe_resp_offload = 1551 wiphy->probe_resp_offload =
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index e7130b54d1d8..e2e021bcaa03 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -24,6 +24,7 @@
24#include "boot_loader.h" 24#include "boot_loader.h"
25 25
26#define WAIT_FOR_HALP_VOTE_MS 100 26#define WAIT_FOR_HALP_VOTE_MS 100
27#define WAIT_FOR_SCAN_ABORT_MS 1000
27 28
28bool debug_fw; /* = false; */ 29bool debug_fw; /* = false; */
29module_param(debug_fw, bool, S_IRUGO); 30module_param(debug_fw, bool, S_IRUGO);
@@ -213,7 +214,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
213 memset(&sta->stats, 0, sizeof(sta->stats)); 214 memset(&sta->stats, 0, sizeof(sta->stats));
214} 215}
215 216
216static bool wil_ap_is_connected(struct wil6210_priv *wil) 217static bool wil_is_connected(struct wil6210_priv *wil)
217{ 218{
218 int i; 219 int i;
219 220
@@ -267,7 +268,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
267 case NL80211_IFTYPE_STATION: 268 case NL80211_IFTYPE_STATION:
268 case NL80211_IFTYPE_P2P_CLIENT: 269 case NL80211_IFTYPE_P2P_CLIENT:
269 wil_bcast_fini(wil); 270 wil_bcast_fini(wil);
270 netif_tx_stop_all_queues(ndev); 271 wil_update_net_queues_bh(wil, NULL, true);
271 netif_carrier_off(ndev); 272 netif_carrier_off(ndev);
272 273
273 if (test_bit(wil_status_fwconnected, wil->status)) { 274 if (test_bit(wil_status_fwconnected, wil->status)) {
@@ -283,8 +284,12 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
283 break; 284 break;
284 case NL80211_IFTYPE_AP: 285 case NL80211_IFTYPE_AP:
285 case NL80211_IFTYPE_P2P_GO: 286 case NL80211_IFTYPE_P2P_GO:
286 if (!wil_ap_is_connected(wil)) 287 if (!wil_is_connected(wil)) {
288 wil_update_net_queues_bh(wil, NULL, true);
287 clear_bit(wil_status_fwconnected, wil->status); 289 clear_bit(wil_status_fwconnected, wil->status);
290 } else {
291 wil_update_net_queues_bh(wil, NULL, false);
292 }
288 break; 293 break;
289 default: 294 default:
290 break; 295 break;
@@ -384,18 +389,19 @@ static void wil_fw_error_worker(struct work_struct *work)
384 389
385 wil->last_fw_recovery = jiffies; 390 wil->last_fw_recovery = jiffies;
386 391
392 wil_info(wil, "fw error recovery requested (try %d)...\n",
393 wil->recovery_count);
394 if (!no_fw_recovery)
395 wil->recovery_state = fw_recovery_running;
396 if (wil_wait_for_recovery(wil) != 0)
397 return;
398
387 mutex_lock(&wil->mutex); 399 mutex_lock(&wil->mutex);
388 switch (wdev->iftype) { 400 switch (wdev->iftype) {
389 case NL80211_IFTYPE_STATION: 401 case NL80211_IFTYPE_STATION:
390 case NL80211_IFTYPE_P2P_CLIENT: 402 case NL80211_IFTYPE_P2P_CLIENT:
391 case NL80211_IFTYPE_MONITOR: 403 case NL80211_IFTYPE_MONITOR:
392 wil_info(wil, "fw error recovery requested (try %d)...\n", 404 /* silent recovery, upper layers will see disconnect */
393 wil->recovery_count);
394 if (!no_fw_recovery)
395 wil->recovery_state = fw_recovery_running;
396 if (0 != wil_wait_for_recovery(wil))
397 break;
398
399 __wil_down(wil); 405 __wil_down(wil);
400 __wil_up(wil); 406 __wil_up(wil);
401 break; 407 break;
@@ -512,10 +518,13 @@ int wil_priv_init(struct wil6210_priv *wil)
512 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 518 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
513 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); 519 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker);
514 INIT_WORK(&wil->probe_client_worker, wil_probe_client_worker); 520 INIT_WORK(&wil->probe_client_worker, wil_probe_client_worker);
521 INIT_WORK(&wil->p2p.delayed_listen_work, wil_p2p_delayed_listen_work);
515 522
516 INIT_LIST_HEAD(&wil->pending_wmi_ev); 523 INIT_LIST_HEAD(&wil->pending_wmi_ev);
517 INIT_LIST_HEAD(&wil->probe_client_pending); 524 INIT_LIST_HEAD(&wil->probe_client_pending);
518 spin_lock_init(&wil->wmi_ev_lock); 525 spin_lock_init(&wil->wmi_ev_lock);
526 spin_lock_init(&wil->net_queue_lock);
527 wil->net_queue_stopped = 1;
519 init_waitqueue_head(&wil->wq); 528 init_waitqueue_head(&wil->wq);
520 529
521 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi"); 530 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
@@ -571,6 +580,7 @@ void wil_priv_deinit(struct wil6210_priv *wil)
571 cancel_work_sync(&wil->disconnect_worker); 580 cancel_work_sync(&wil->disconnect_worker);
572 cancel_work_sync(&wil->fw_error_worker); 581 cancel_work_sync(&wil->fw_error_worker);
573 cancel_work_sync(&wil->p2p.discovery_expired_work); 582 cancel_work_sync(&wil->p2p.discovery_expired_work);
583 cancel_work_sync(&wil->p2p.delayed_listen_work);
574 mutex_lock(&wil->mutex); 584 mutex_lock(&wil->mutex);
575 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 585 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
576 mutex_unlock(&wil->mutex); 586 mutex_unlock(&wil->mutex);
@@ -685,6 +695,19 @@ static int wil_target_reset(struct wil6210_priv *wil)
685 return 0; 695 return 0;
686} 696}
687 697
698static void wil_collect_fw_info(struct wil6210_priv *wil)
699{
700 struct wiphy *wiphy = wil_to_wiphy(wil);
701 u8 retry_short;
702 int rc;
703
704 rc = wmi_get_mgmt_retry(wil, &retry_short);
705 if (!rc) {
706 wiphy->retry_short = retry_short;
707 wil_dbg_misc(wil, "FW retry_short: %d\n", retry_short);
708 }
709}
710
688void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) 711void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
689{ 712{
690 le32_to_cpus(&r->base); 713 le32_to_cpus(&r->base);
@@ -801,6 +824,34 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
801 return 0; 824 return 0;
802} 825}
803 826
827void wil_abort_scan(struct wil6210_priv *wil, bool sync)
828{
829 int rc;
830 struct cfg80211_scan_info info = {
831 .aborted = true,
832 };
833
834 lockdep_assert_held(&wil->p2p_wdev_mutex);
835
836 if (!wil->scan_request)
837 return;
838
839 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", wil->scan_request);
840 del_timer_sync(&wil->scan_timer);
841 mutex_unlock(&wil->p2p_wdev_mutex);
842 rc = wmi_abort_scan(wil);
843 if (!rc && sync)
844 wait_event_interruptible_timeout(wil->wq, !wil->scan_request,
845 msecs_to_jiffies(
846 WAIT_FOR_SCAN_ABORT_MS));
847
848 mutex_lock(&wil->p2p_wdev_mutex);
849 if (wil->scan_request) {
850 cfg80211_scan_done(wil->scan_request, &info);
851 wil->scan_request = NULL;
852 }
853}
854
804/* 855/*
805 * We reset all the structures, and we reset the UMAC. 856 * We reset all the structures, and we reset the UMAC.
806 * After calling this routine, you're expected to reload 857 * After calling this routine, you're expected to reload
@@ -853,17 +904,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
853 mutex_unlock(&wil->wmi_mutex); 904 mutex_unlock(&wil->wmi_mutex);
854 905
855 mutex_lock(&wil->p2p_wdev_mutex); 906 mutex_lock(&wil->p2p_wdev_mutex);
856 if (wil->scan_request) { 907 wil_abort_scan(wil, false);
857 struct cfg80211_scan_info info = {
858 .aborted = true,
859 };
860
861 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
862 wil->scan_request);
863 del_timer_sync(&wil->scan_timer);
864 cfg80211_scan_done(wil->scan_request, &info);
865 wil->scan_request = NULL;
866 }
867 mutex_unlock(&wil->p2p_wdev_mutex); 908 mutex_unlock(&wil->p2p_wdev_mutex);
868 909
869 wil_mask_irq(wil); 910 wil_mask_irq(wil);
@@ -940,6 +981,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
940 return rc; 981 return rc;
941 } 982 }
942 983
984 wil_collect_fw_info(wil);
985
943 if (wil->platform_ops.notify) { 986 if (wil->platform_ops.notify) {
944 rc = wil->platform_ops.notify(wil->platform_handle, 987 rc = wil->platform_ops.notify(wil->platform_handle,
945 WIL_PLATFORM_EVT_FW_RDY); 988 WIL_PLATFORM_EVT_FW_RDY);
@@ -1056,20 +1099,9 @@ int __wil_down(struct wil6210_priv *wil)
1056 } 1099 }
1057 wil_enable_irq(wil); 1100 wil_enable_irq(wil);
1058 1101
1059 wil_p2p_stop_radio_operations(wil);
1060
1061 mutex_lock(&wil->p2p_wdev_mutex); 1102 mutex_lock(&wil->p2p_wdev_mutex);
1062 if (wil->scan_request) { 1103 wil_p2p_stop_radio_operations(wil);
1063 struct cfg80211_scan_info info = { 1104 wil_abort_scan(wil, false);
1064 .aborted = true,
1065 };
1066
1067 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
1068 wil->scan_request);
1069 del_timer_sync(&wil->scan_timer);
1070 cfg80211_scan_done(wil->scan_request, &info);
1071 wil->scan_request = NULL;
1072 }
1073 mutex_unlock(&wil->p2p_wdev_mutex); 1105 mutex_unlock(&wil->p2p_wdev_mutex);
1074 1106
1075 wil_reset(wil, false); 1107 wil_reset(wil, false);
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index d18372cdc8ca..6676001dcbca 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -214,7 +214,7 @@ int wil_if_add(struct wil6210_priv *wil)
214 netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx, 214 netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
215 WIL6210_NAPI_BUDGET); 215 WIL6210_NAPI_BUDGET);
216 216
217 netif_tx_stop_all_queues(ndev); 217 wil_update_net_queues_bh(wil, NULL, true);
218 218
219 rc = register_netdev(ndev); 219 rc = register_netdev(ndev);
220 if (rc < 0) { 220 if (rc < 0) {
diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c
index 4087785d3090..fbae99525e01 100644
--- a/drivers/net/wireless/ath/wil6210/p2p.c
+++ b/drivers/net/wireless/ath/wil6210/p2p.c
@@ -22,6 +22,43 @@
22#define P2P_SEARCH_DURATION_MS 500 22#define P2P_SEARCH_DURATION_MS 500
23#define P2P_DEFAULT_BI 100 23#define P2P_DEFAULT_BI 100
24 24
25static int wil_p2p_start_listen(struct wil6210_priv *wil)
26{
27 struct wil_p2p_info *p2p = &wil->p2p;
28 u8 channel = p2p->listen_chan.hw_value;
29 int rc;
30
31 lockdep_assert_held(&wil->mutex);
32
33 rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI);
34 if (rc) {
35 wil_err(wil, "wmi_p2p_cfg failed\n");
36 goto out;
37 }
38
39 rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
40 if (rc) {
41 wil_err(wil, "wmi_set_ssid failed\n");
42 goto out_stop;
43 }
44
45 rc = wmi_start_listen(wil);
46 if (rc) {
47 wil_err(wil, "wmi_start_listen failed\n");
48 goto out_stop;
49 }
50
51 INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired);
52 mod_timer(&p2p->discovery_timer,
53 jiffies + msecs_to_jiffies(p2p->listen_duration));
54out_stop:
55 if (rc)
56 wmi_stop_discovery(wil);
57
58out:
59 return rc;
60}
61
25bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request) 62bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request)
26{ 63{
27 return (request->n_channels == 1) && 64 return (request->n_channels == 1) &&
@@ -46,7 +83,7 @@ int wil_p2p_search(struct wil6210_priv *wil,
46 wil_dbg_misc(wil, "%s: channel %d\n", 83 wil_dbg_misc(wil, "%s: channel %d\n",
47 __func__, P2P_DMG_SOCIAL_CHANNEL); 84 __func__, P2P_DMG_SOCIAL_CHANNEL);
48 85
49 mutex_lock(&wil->mutex); 86 lockdep_assert_held(&wil->mutex);
50 87
51 if (p2p->discovery_started) { 88 if (p2p->discovery_started) {
52 wil_err(wil, "%s: search failed. discovery already ongoing\n", 89 wil_err(wil, "%s: search failed. discovery already ongoing\n",
@@ -103,22 +140,19 @@ out_stop:
103 wmi_stop_discovery(wil); 140 wmi_stop_discovery(wil);
104 141
105out: 142out:
106 mutex_unlock(&wil->mutex);
107 return rc; 143 return rc;
108} 144}
109 145
110int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration, 146int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
111 struct ieee80211_channel *chan, u64 *cookie) 147 unsigned int duration, struct ieee80211_channel *chan,
148 u64 *cookie)
112{ 149{
113 struct wil_p2p_info *p2p = &wil->p2p; 150 struct wil_p2p_info *p2p = &wil->p2p;
114 u8 channel = P2P_DMG_SOCIAL_CHANNEL;
115 int rc; 151 int rc;
116 152
117 if (!chan) 153 if (!chan)
118 return -EINVAL; 154 return -EINVAL;
119 155
120 channel = chan->hw_value;
121
122 wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration); 156 wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration);
123 157
124 mutex_lock(&wil->mutex); 158 mutex_lock(&wil->mutex);
@@ -129,35 +163,30 @@ int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
129 goto out; 163 goto out;
130 } 164 }
131 165
132 rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI); 166 memcpy(&p2p->listen_chan, chan, sizeof(*chan));
133 if (rc) { 167 *cookie = ++p2p->cookie;
134 wil_err(wil, "%s: wmi_p2p_cfg failed\n", __func__); 168 p2p->listen_duration = duration;
135 goto out;
136 }
137
138 rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
139 if (rc) {
140 wil_err(wil, "%s: wmi_set_ssid failed\n", __func__);
141 goto out_stop;
142 }
143 169
144 rc = wmi_start_listen(wil); 170 mutex_lock(&wil->p2p_wdev_mutex);
145 if (rc) { 171 if (wil->scan_request) {
146 wil_err(wil, "%s: wmi_start_listen failed\n", __func__); 172 wil_dbg_misc(wil, "Delaying p2p listen until scan done\n");
147 goto out_stop; 173 p2p->pending_listen_wdev = wdev;
174 p2p->discovery_started = 1;
175 rc = 0;
176 mutex_unlock(&wil->p2p_wdev_mutex);
177 goto out;
148 } 178 }
179 mutex_unlock(&wil->p2p_wdev_mutex);
149 180
150 memcpy(&p2p->listen_chan, chan, sizeof(*chan)); 181 rc = wil_p2p_start_listen(wil);
151 *cookie = ++p2p->cookie; 182 if (rc)
183 goto out;
152 184
153 p2p->discovery_started = 1; 185 p2p->discovery_started = 1;
154 INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired); 186 wil->radio_wdev = wdev;
155 mod_timer(&p2p->discovery_timer,
156 jiffies + msecs_to_jiffies(duration));
157 187
158out_stop: 188 cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
159 if (rc) 189 GFP_KERNEL);
160 wmi_stop_discovery(wil);
161 190
162out: 191out:
163 mutex_unlock(&wil->mutex); 192 mutex_unlock(&wil->mutex);
@@ -170,9 +199,14 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil)
170 u8 started = p2p->discovery_started; 199 u8 started = p2p->discovery_started;
171 200
172 if (p2p->discovery_started) { 201 if (p2p->discovery_started) {
173 del_timer_sync(&p2p->discovery_timer); 202 if (p2p->pending_listen_wdev) {
203 /* discovery not really started, only pending */
204 p2p->pending_listen_wdev = NULL;
205 } else {
206 del_timer_sync(&p2p->discovery_timer);
207 wmi_stop_discovery(wil);
208 }
174 p2p->discovery_started = 0; 209 p2p->discovery_started = 0;
175 wmi_stop_discovery(wil);
176 } 210 }
177 211
178 return started; 212 return started;
@@ -257,13 +291,59 @@ void wil_p2p_search_expired(struct work_struct *work)
257 }; 291 };
258 292
259 mutex_lock(&wil->p2p_wdev_mutex); 293 mutex_lock(&wil->p2p_wdev_mutex);
260 cfg80211_scan_done(wil->scan_request, &info); 294 if (wil->scan_request) {
261 wil->scan_request = NULL; 295 cfg80211_scan_done(wil->scan_request, &info);
262 wil->radio_wdev = wil->wdev; 296 wil->scan_request = NULL;
297 wil->radio_wdev = wil->wdev;
298 }
263 mutex_unlock(&wil->p2p_wdev_mutex); 299 mutex_unlock(&wil->p2p_wdev_mutex);
264 } 300 }
265} 301}
266 302
303void wil_p2p_delayed_listen_work(struct work_struct *work)
304{
305 struct wil_p2p_info *p2p = container_of(work,
306 struct wil_p2p_info, delayed_listen_work);
307 struct wil6210_priv *wil = container_of(p2p,
308 struct wil6210_priv, p2p);
309 int rc;
310
311 mutex_lock(&wil->mutex);
312
313 wil_dbg_misc(wil, "Checking delayed p2p listen\n");
314 if (!p2p->discovery_started || !p2p->pending_listen_wdev)
315 goto out;
316
317 mutex_lock(&wil->p2p_wdev_mutex);
318 if (wil->scan_request) {
319 /* another scan started, wait again... */
320 mutex_unlock(&wil->p2p_wdev_mutex);
321 goto out;
322 }
323 mutex_unlock(&wil->p2p_wdev_mutex);
324
325 rc = wil_p2p_start_listen(wil);
326
327 mutex_lock(&wil->p2p_wdev_mutex);
328 if (rc) {
329 cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev,
330 p2p->cookie,
331 &p2p->listen_chan,
332 GFP_KERNEL);
333 wil->radio_wdev = wil->wdev;
334 } else {
335 cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie,
336 &p2p->listen_chan,
337 p2p->listen_duration, GFP_KERNEL);
338 wil->radio_wdev = p2p->pending_listen_wdev;
339 }
340 p2p->pending_listen_wdev = NULL;
341 mutex_unlock(&wil->p2p_wdev_mutex);
342
343out:
344 mutex_unlock(&wil->mutex);
345}
346
267void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) 347void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
268{ 348{
269 struct wil_p2p_info *p2p = &wil->p2p; 349 struct wil_p2p_info *p2p = &wil->p2p;
@@ -272,8 +352,7 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
272 }; 352 };
273 353
274 lockdep_assert_held(&wil->mutex); 354 lockdep_assert_held(&wil->mutex);
275 355 lockdep_assert_held(&wil->p2p_wdev_mutex);
276 mutex_lock(&wil->p2p_wdev_mutex);
277 356
278 if (wil->radio_wdev != wil->p2p_wdev) 357 if (wil->radio_wdev != wil->p2p_wdev)
279 goto out; 358 goto out;
@@ -281,10 +360,8 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
281 if (!p2p->discovery_started) { 360 if (!p2p->discovery_started) {
282 /* Regular scan on the p2p device */ 361 /* Regular scan on the p2p device */
283 if (wil->scan_request && 362 if (wil->scan_request &&
284 wil->scan_request->wdev == wil->p2p_wdev) { 363 wil->scan_request->wdev == wil->p2p_wdev)
285 cfg80211_scan_done(wil->scan_request, &info); 364 wil_abort_scan(wil, true);
286 wil->scan_request = NULL;
287 }
288 goto out; 365 goto out;
289 } 366 }
290 367
@@ -307,5 +384,4 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
307 384
308out: 385out:
309 wil->radio_wdev = wil->wdev; 386 wil->radio_wdev = wil->wdev;
310 mutex_unlock(&wil->p2p_wdev_mutex);
311} 387}
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c
index 5ca0307a3274..b9faae0278c9 100644
--- a/drivers/net/wireless/ath/wil6210/pmc.c
+++ b/drivers/net/wireless/ath/wil6210/pmc.c
@@ -54,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
54 struct pmc_ctx *pmc = &wil->pmc; 54 struct pmc_ctx *pmc = &wil->pmc;
55 struct device *dev = wil_to_dev(wil); 55 struct device *dev = wil_to_dev(wil);
56 struct wmi_pmc_cmd pmc_cmd = {0}; 56 struct wmi_pmc_cmd pmc_cmd = {0};
57 int last_cmd_err = -ENOMEM;
57 58
58 mutex_lock(&pmc->lock); 59 mutex_lock(&pmc->lock);
59 60
@@ -62,6 +63,29 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
62 wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__); 63 wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__);
63 goto no_release_err; 64 goto no_release_err;
64 } 65 }
66 if ((num_descriptors <= 0) || (descriptor_size <= 0)) {
67 wil_err(wil,
68 "Invalid params num_descriptors(%d), descriptor_size(%d)\n",
69 num_descriptors, descriptor_size);
70 last_cmd_err = -EINVAL;
71 goto no_release_err;
72 }
73
74 if (num_descriptors > (1 << WIL_RING_SIZE_ORDER_MAX)) {
75 wil_err(wil,
76 "num_descriptors(%d) exceeds max ring size %d\n",
77 num_descriptors, 1 << WIL_RING_SIZE_ORDER_MAX);
78 last_cmd_err = -EINVAL;
79 goto no_release_err;
80 }
81
82 if (num_descriptors > INT_MAX / descriptor_size) {
83 wil_err(wil,
84 "Overflow in num_descriptors(%d)*descriptor_size(%d)\n",
85 num_descriptors, descriptor_size);
86 last_cmd_err = -EINVAL;
87 goto no_release_err;
88 }
65 89
66 pmc->num_descriptors = num_descriptors; 90 pmc->num_descriptors = num_descriptors;
67 pmc->descriptor_size = descriptor_size; 91 pmc->descriptor_size = descriptor_size;
@@ -189,7 +213,7 @@ release_pmc_skb_list:
189 pmc->descriptors = NULL; 213 pmc->descriptors = NULL;
190 214
191no_release_err: 215no_release_err:
192 pmc->last_cmd_status = -ENOMEM; 216 pmc->last_cmd_status = last_cmd_err;
193 mutex_unlock(&pmc->lock); 217 mutex_unlock(&pmc->lock);
194} 218}
195 219
@@ -295,7 +319,7 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
295 size_t retval = 0; 319 size_t retval = 0;
296 unsigned long long idx; 320 unsigned long long idx;
297 loff_t offset; 321 loff_t offset;
298 size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors; 322 size_t pmc_size;
299 323
300 mutex_lock(&pmc->lock); 324 mutex_lock(&pmc->lock);
301 325
@@ -306,6 +330,8 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
306 return -EPERM; 330 return -EPERM;
307 } 331 }
308 332
333 pmc_size = pmc->descriptor_size * pmc->num_descriptors;
334
309 wil_dbg_misc(wil, 335 wil_dbg_misc(wil,
310 "%s: size %u, pos %lld\n", 336 "%s: size %u, pos %lld\n",
311 __func__, (unsigned)count, *f_pos); 337 __func__, (unsigned)count, *f_pos);
@@ -345,7 +371,18 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
345 loff_t newpos; 371 loff_t newpos;
346 struct wil6210_priv *wil = filp->private_data; 372 struct wil6210_priv *wil = filp->private_data;
347 struct pmc_ctx *pmc = &wil->pmc; 373 struct pmc_ctx *pmc = &wil->pmc;
348 size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors; 374 size_t pmc_size;
375
376 mutex_lock(&pmc->lock);
377
378 if (!wil_is_pmc_allocated(pmc)) {
379 wil_err(wil, "error, pmc is not allocated!\n");
380 pmc->last_cmd_status = -EPERM;
381 mutex_unlock(&pmc->lock);
382 return -EPERM;
383 }
384
385 pmc_size = pmc->descriptor_size * pmc->num_descriptors;
349 386
350 switch (whence) { 387 switch (whence) {
351 case 0: /* SEEK_SET */ 388 case 0: /* SEEK_SET */
@@ -361,15 +398,21 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
361 break; 398 break;
362 399
363 default: /* can't happen */ 400 default: /* can't happen */
364 return -EINVAL; 401 newpos = -EINVAL;
402 goto out;
365 } 403 }
366 404
367 if (newpos < 0) 405 if (newpos < 0) {
368 return -EINVAL; 406 newpos = -EINVAL;
407 goto out;
408 }
369 if (newpos > pmc_size) 409 if (newpos > pmc_size)
370 newpos = pmc_size; 410 newpos = pmc_size;
371 411
372 filp->f_pos = newpos; 412 filp->f_pos = newpos;
373 413
414out:
415 mutex_unlock(&pmc->lock);
416
374 return newpos; 417 return newpos;
375} 418}
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 4c38520d4dd2..4ac9ba04afed 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -88,6 +88,18 @@ static inline int wil_vring_wmark_high(struct vring *vring)
88 return vring->size/4; 88 return vring->size/4;
89} 89}
90 90
91/* returns true if num avail descriptors is lower than wmark_low */
92static inline int wil_vring_avail_low(struct vring *vring)
93{
94 return wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring);
95}
96
97/* returns true if num avail descriptors is higher than wmark_high */
98static inline int wil_vring_avail_high(struct vring *vring)
99{
100 return wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring);
101}
102
91/* wil_val_in_range - check if value in [min,max) */ 103/* wil_val_in_range - check if value in [min,max) */
92static inline bool wil_val_in_range(int val, int min, int max) 104static inline bool wil_val_in_range(int val, int min, int max)
93{ 105{
@@ -1780,6 +1792,89 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1780 return rc; 1792 return rc;
1781} 1793}
1782 1794
1795/**
1796 * Check status of tx vrings and stop/wake net queues if needed
1797 *
1798 * This function does one of two checks:
1799 * In case check_stop is true, will check if net queues need to be stopped. If
1800 * the conditions for stopping are met, netif_tx_stop_all_queues() is called.
1801 * In case check_stop is false, will check if net queues need to be waked. If
1802 * the conditions for waking are met, netif_tx_wake_all_queues() is called.
1803 * vring is the vring which is currently being modified by either adding
1804 * descriptors (tx) into it or removing descriptors (tx complete) from it. Can
1805 * be null when irrelevant (e.g. connect/disconnect events).
1806 *
1807 * The implementation is to stop net queues if modified vring has low
1808 * descriptor availability. Wake if all vrings are not in low descriptor
1809 * availability and modified vring has high descriptor availability.
1810 */
1811static inline void __wil_update_net_queues(struct wil6210_priv *wil,
1812 struct vring *vring,
1813 bool check_stop)
1814{
1815 int i;
1816
1817 if (vring)
1818 wil_dbg_txrx(wil, "vring %d, check_stop=%d, stopped=%d",
1819 (int)(vring - wil->vring_tx), check_stop,
1820 wil->net_queue_stopped);
1821 else
1822 wil_dbg_txrx(wil, "check_stop=%d, stopped=%d",
1823 check_stop, wil->net_queue_stopped);
1824
1825 if (check_stop == wil->net_queue_stopped)
1826 /* net queues already in desired state */
1827 return;
1828
1829 if (check_stop) {
1830 if (!vring || unlikely(wil_vring_avail_low(vring))) {
1831 /* not enough room in the vring */
1832 netif_tx_stop_all_queues(wil_to_ndev(wil));
1833 wil->net_queue_stopped = true;
1834 wil_dbg_txrx(wil, "netif_tx_stop called\n");
1835 }
1836 return;
1837 }
1838
1839 /* check wake */
1840 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
1841 struct vring *cur_vring = &wil->vring_tx[i];
1842 struct vring_tx_data *txdata = &wil->vring_tx_data[i];
1843
1844 if (!cur_vring->va || !txdata->enabled || cur_vring == vring)
1845 continue;
1846
1847 if (wil_vring_avail_low(cur_vring)) {
1848 wil_dbg_txrx(wil, "vring %d full, can't wake\n",
1849 (int)(cur_vring - wil->vring_tx));
1850 return;
1851 }
1852 }
1853
1854 if (!vring || wil_vring_avail_high(vring)) {
1855 /* enough room in the vring */
1856 wil_dbg_txrx(wil, "calling netif_tx_wake\n");
1857 netif_tx_wake_all_queues(wil_to_ndev(wil));
1858 wil->net_queue_stopped = false;
1859 }
1860}
1861
1862void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring,
1863 bool check_stop)
1864{
1865 spin_lock(&wil->net_queue_lock);
1866 __wil_update_net_queues(wil, vring, check_stop);
1867 spin_unlock(&wil->net_queue_lock);
1868}
1869
1870void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring,
1871 bool check_stop)
1872{
1873 spin_lock_bh(&wil->net_queue_lock);
1874 __wil_update_net_queues(wil, vring, check_stop);
1875 spin_unlock_bh(&wil->net_queue_lock);
1876}
1877
1783netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) 1878netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1784{ 1879{
1785 struct wil6210_priv *wil = ndev_to_wil(ndev); 1880 struct wil6210_priv *wil = ndev_to_wil(ndev);
@@ -1822,14 +1917,10 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1822 /* set up vring entry */ 1917 /* set up vring entry */
1823 rc = wil_tx_vring(wil, vring, skb); 1918 rc = wil_tx_vring(wil, vring, skb);
1824 1919
1825 /* do we still have enough room in the vring? */
1826 if (unlikely(wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring))) {
1827 netif_tx_stop_all_queues(wil_to_ndev(wil));
1828 wil_dbg_txrx(wil, "netif_tx_stop : ring full\n");
1829 }
1830
1831 switch (rc) { 1920 switch (rc) {
1832 case 0: 1921 case 0:
1922 /* shall we stop net queues? */
1923 wil_update_net_queues_bh(wil, vring, true);
1833 /* statistics will be updated on the tx_complete */ 1924 /* statistics will be updated on the tx_complete */
1834 dev_kfree_skb_any(skb); 1925 dev_kfree_skb_any(skb);
1835 return NETDEV_TX_OK; 1926 return NETDEV_TX_OK;
@@ -1978,10 +2069,9 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1978 txdata->last_idle = get_cycles(); 2069 txdata->last_idle = get_cycles();
1979 } 2070 }
1980 2071
1981 if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring)) { 2072 /* shall we wake net queues? */
1982 wil_dbg_txrx(wil, "netif_tx_wake : ring not full\n"); 2073 if (done)
1983 netif_tx_wake_all_queues(wil_to_ndev(wil)); 2074 wil_update_net_queues(wil, vring, false);
1984 }
1985 2075
1986 return done; 2076 return done;
1987} 2077}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index a949cd62bc4e..237e1666df2d 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -276,10 +276,11 @@ struct fw_map {
276 u32 to; /* linker address - to, exclusive */ 276 u32 to; /* linker address - to, exclusive */
277 u32 host; /* PCI/Host address - BAR0 + 0x880000 */ 277 u32 host; /* PCI/Host address - BAR0 + 0x880000 */
278 const char *name; /* for debugfs */ 278 const char *name; /* for debugfs */
279 bool fw; /* true if FW mapping, false if UCODE mapping */
279}; 280};
280 281
281/* array size should be in sync with actual definition in the wmi.c */ 282/* array size should be in sync with actual definition in the wmi.c */
282extern const struct fw_map fw_mapping[8]; 283extern const struct fw_map fw_mapping[10];
283 284
284/** 285/**
285 * mk_cidxtid - construct @cidxtid field 286 * mk_cidxtid - construct @cidxtid field
@@ -461,8 +462,11 @@ struct wil_p2p_info {
461 u8 discovery_started; 462 u8 discovery_started;
462 u8 p2p_dev_started; 463 u8 p2p_dev_started;
463 u64 cookie; 464 u64 cookie;
465 struct wireless_dev *pending_listen_wdev;
466 unsigned int listen_duration;
464 struct timer_list discovery_timer; /* listen/search duration */ 467 struct timer_list discovery_timer; /* listen/search duration */
465 struct work_struct discovery_expired_work; /* listen/search expire */ 468 struct work_struct discovery_expired_work; /* listen/search expire */
469 struct work_struct delayed_listen_work; /* listen after scan done */
466}; 470};
467 471
468enum wil_sta_status { 472enum wil_sta_status {
@@ -624,6 +628,8 @@ struct wil6210_priv {
624 * - consumed in thread by wmi_event_worker 628 * - consumed in thread by wmi_event_worker
625 */ 629 */
626 spinlock_t wmi_ev_lock; 630 spinlock_t wmi_ev_lock;
631 spinlock_t net_queue_lock; /* guarding stop/wake netif queue */
632 int net_queue_stopped; /* netif_tx_stop_all_queues invoked */
627 struct napi_struct napi_rx; 633 struct napi_struct napi_rx;
628 struct napi_struct napi_tx; 634 struct napi_struct napi_tx;
629 /* keep alive */ 635 /* keep alive */
@@ -817,6 +823,10 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
817int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason); 823int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
818int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, 824int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
819 u16 status, bool amsdu, u16 agg_wsize, u16 timeout); 825 u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
826int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
827 enum wmi_ps_profile_type ps_profile);
828int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
829int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
820int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, 830int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
821 u8 dialog_token, __le16 ba_param_set, 831 u8 dialog_token, __le16 ba_param_set,
822 __le16 ba_timeout, __le16 ba_seq_ctrl); 832 __le16 ba_timeout, __le16 ba_seq_ctrl);
@@ -837,13 +847,15 @@ bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request);
837void wil_p2p_discovery_timer_fn(ulong x); 847void wil_p2p_discovery_timer_fn(ulong x);
838int wil_p2p_search(struct wil6210_priv *wil, 848int wil_p2p_search(struct wil6210_priv *wil,
839 struct cfg80211_scan_request *request); 849 struct cfg80211_scan_request *request);
840int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration, 850int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
841 struct ieee80211_channel *chan, u64 *cookie); 851 unsigned int duration, struct ieee80211_channel *chan,
852 u64 *cookie);
842u8 wil_p2p_stop_discovery(struct wil6210_priv *wil); 853u8 wil_p2p_stop_discovery(struct wil6210_priv *wil);
843int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie); 854int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie);
844void wil_p2p_listen_expired(struct work_struct *work); 855void wil_p2p_listen_expired(struct work_struct *work);
845void wil_p2p_search_expired(struct work_struct *work); 856void wil_p2p_search_expired(struct work_struct *work);
846void wil_p2p_stop_radio_operations(struct wil6210_priv *wil); 857void wil_p2p_stop_radio_operations(struct wil6210_priv *wil);
858void wil_p2p_delayed_listen_work(struct work_struct *work);
847 859
848/* WMI for P2P */ 860/* WMI for P2P */
849int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi); 861int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi);
@@ -869,6 +881,9 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
869 u8 chan, u8 hidden_ssid, u8 is_go); 881 u8 chan, u8 hidden_ssid, u8 is_go);
870int wmi_pcp_stop(struct wil6210_priv *wil); 882int wmi_pcp_stop(struct wil6210_priv *wil);
871int wmi_led_cfg(struct wil6210_priv *wil, bool enable); 883int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
884int wmi_abort_scan(struct wil6210_priv *wil);
885void wil_abort_scan(struct wil6210_priv *wil, bool sync);
886
872void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 887void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
873 u16 reason_code, bool from_event); 888 u16 reason_code, bool from_event);
874void wil_probe_client_flush(struct wil6210_priv *wil); 889void wil_probe_client_flush(struct wil6210_priv *wil);
@@ -886,6 +901,10 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size);
886int wil_bcast_init(struct wil6210_priv *wil); 901int wil_bcast_init(struct wil6210_priv *wil);
887void wil_bcast_fini(struct wil6210_priv *wil); 902void wil_bcast_fini(struct wil6210_priv *wil);
888 903
904void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring,
905 bool should_stop);
906void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring,
907 bool check_stop);
889netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 908netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
890int wil_tx_complete(struct wil6210_priv *wil, int ringid); 909int wil_tx_complete(struct wil6210_priv *wil, int ringid);
891void wil6210_unmask_irq_tx(struct wil6210_priv *wil); 910void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wil_crash_dump.c b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
index b57d280946e0..d051eea47a54 100644
--- a/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
+++ b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
@@ -36,6 +36,9 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil,
36 for (i = 1; i < ARRAY_SIZE(fw_mapping); i++) { 36 for (i = 1; i < ARRAY_SIZE(fw_mapping); i++) {
37 map = &fw_mapping[i]; 37 map = &fw_mapping[i];
38 38
39 if (!map->fw)
40 continue;
41
39 if (map->host < host_min) 42 if (map->host < host_min)
40 host_min = map->host; 43 host_min = map->host;
41 44
@@ -73,6 +76,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
73 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { 76 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
74 map = &fw_mapping[i]; 77 map = &fw_mapping[i];
75 78
79 if (!map->fw)
80 continue;
81
76 data = (void * __force)wil->csr + HOSTADDR(map->host); 82 data = (void * __force)wil->csr + HOSTADDR(map->host);
77 len = map->to - map->from; 83 len = map->to - map->from;
78 offset = map->host - host_min; 84 offset = map->host - host_min;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index fae4f1285d08..7585003bef67 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -84,19 +84,29 @@ MODULE_PARM_DESC(led_id,
84 * array size should be in sync with the declaration in the wil6210.h 84 * array size should be in sync with the declaration in the wil6210.h
85 */ 85 */
86const struct fw_map fw_mapping[] = { 86const struct fw_map fw_mapping[] = {
87 {0x000000, 0x040000, 0x8c0000, "fw_code"}, /* FW code RAM 256k */ 87 /* FW code RAM 256k */
88 {0x800000, 0x808000, 0x900000, "fw_data"}, /* FW data RAM 32k */ 88 {0x000000, 0x040000, 0x8c0000, "fw_code", true},
89 {0x840000, 0x860000, 0x908000, "fw_peri"}, /* periph. data RAM 128k */ 89 /* FW data RAM 32k */
90 {0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */ 90 {0x800000, 0x808000, 0x900000, "fw_data", true},
91 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */ 91 /* periph data 128k */
92 {0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */ 92 {0x840000, 0x860000, 0x908000, "fw_peri", true},
93 {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext"}, /* mac_ext_rgf 512b */ 93 /* various RGF 40k */
94 {0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */ 94 {0x880000, 0x88a000, 0x880000, "rgf", true},
95 /* 95 /* AGC table 4k */
96 * 920000..930000 ucode code RAM 96 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true},
97 * 930000..932000 ucode data RAM 97 /* Pcie_ext_rgf 4k */
98 * 932000..949000 back-door debug data 98 {0x88b000, 0x88c000, 0x88b000, "rgf_ext", true},
99 /* mac_ext_rgf 512b */
100 {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext", true},
101 /* upper area 548k */
102 {0x8c0000, 0x949000, 0x8c0000, "upper", true},
103 /* UCODE areas - accessible by debugfs blobs but not by
104 * wmi_addr_remap. UCODE areas MUST be added AFTER FW areas!
99 */ 105 */
106 /* ucode code RAM 128k */
107 {0x000000, 0x020000, 0x920000, "uc_code", false},
108 /* ucode data RAM 16k */
109 {0x800000, 0x804000, 0x940000, "uc_data", false},
100}; 110};
101 111
102struct blink_on_off_time led_blink_time[] = { 112struct blink_on_off_time led_blink_time[] = {
@@ -108,7 +118,7 @@ struct blink_on_off_time led_blink_time[] = {
108u8 led_polarity = LED_POLARITY_LOW_ACTIVE; 118u8 led_polarity = LED_POLARITY_LOW_ACTIVE;
109 119
110/** 120/**
111 * return AHB address for given firmware/ucode internal (linker) address 121 * return AHB address for given firmware internal (linker) address
112 * @x - internal address 122 * @x - internal address
113 * If address have no valid AHB mapping, return 0 123 * If address have no valid AHB mapping, return 0
114 */ 124 */
@@ -117,7 +127,8 @@ static u32 wmi_addr_remap(u32 x)
117 uint i; 127 uint i;
118 128
119 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { 129 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
120 if ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to)) 130 if (fw_mapping[i].fw &&
131 ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to)))
121 return x + fw_mapping[i].host - fw_mapping[i].from; 132 return x + fw_mapping[i].host - fw_mapping[i].from;
122 } 133 }
123 134
@@ -427,18 +438,24 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
427 mutex_lock(&wil->p2p_wdev_mutex); 438 mutex_lock(&wil->p2p_wdev_mutex);
428 if (wil->scan_request) { 439 if (wil->scan_request) {
429 struct wmi_scan_complete_event *data = d; 440 struct wmi_scan_complete_event *data = d;
441 int status = le32_to_cpu(data->status);
430 struct cfg80211_scan_info info = { 442 struct cfg80211_scan_info info = {
431 .aborted = (data->status != WMI_SCAN_SUCCESS), 443 .aborted = ((status != WMI_SCAN_SUCCESS) &&
444 (status != WMI_SCAN_ABORT_REJECTED)),
432 }; 445 };
433 446
434 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); 447 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status);
435 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", 448 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
436 wil->scan_request, info.aborted); 449 wil->scan_request, info.aborted);
437
438 del_timer_sync(&wil->scan_timer); 450 del_timer_sync(&wil->scan_timer);
439 cfg80211_scan_done(wil->scan_request, &info); 451 cfg80211_scan_done(wil->scan_request, &info);
440 wil->radio_wdev = wil->wdev; 452 wil->radio_wdev = wil->wdev;
441 wil->scan_request = NULL; 453 wil->scan_request = NULL;
454 wake_up_interruptible(&wil->wq);
455 if (wil->p2p.pending_listen_wdev) {
456 wil_dbg_misc(wil, "Scheduling delayed listen\n");
457 schedule_work(&wil->p2p.delayed_listen_work);
458 }
442 } else { 459 } else {
443 wil_err(wil, "SCAN_COMPLETE while not scanning\n"); 460 wil_err(wil, "SCAN_COMPLETE while not scanning\n");
444 } 461 }
@@ -548,7 +565,6 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
548 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 565 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
549 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 566 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
550 if (rc) { 567 if (rc) {
551 netif_tx_stop_all_queues(ndev);
552 netif_carrier_off(ndev); 568 netif_carrier_off(ndev);
553 wil_err(wil, 569 wil_err(wil,
554 "%s: cfg80211_connect_result with failure\n", 570 "%s: cfg80211_connect_result with failure\n",
@@ -588,7 +604,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
588 604
589 wil->sta[evt->cid].status = wil_sta_connected; 605 wil->sta[evt->cid].status = wil_sta_connected;
590 set_bit(wil_status_fwconnected, wil->status); 606 set_bit(wil_status_fwconnected, wil->status);
591 netif_tx_wake_all_queues(ndev); 607 wil_update_net_queues_bh(wil, NULL, false);
592 608
593out: 609out:
594 if (rc) 610 if (rc)
@@ -1564,6 +1580,112 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
1564 return rc; 1580 return rc;
1565} 1581}
1566 1582
1583int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
1584 enum wmi_ps_profile_type ps_profile)
1585{
1586 int rc;
1587 struct wmi_ps_dev_profile_cfg_cmd cmd = {
1588 .ps_profile = ps_profile,
1589 };
1590 struct {
1591 struct wmi_cmd_hdr wmi;
1592 struct wmi_ps_dev_profile_cfg_event evt;
1593 } __packed reply;
1594 u32 status;
1595
1596 wil_dbg_wmi(wil, "Setting ps dev profile %d\n", ps_profile);
1597
1598 reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR);
1599
1600 rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, &cmd, sizeof(cmd),
1601 WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply),
1602 100);
1603 if (rc)
1604 return rc;
1605
1606 status = le32_to_cpu(reply.evt.status);
1607
1608 if (status != WMI_PS_CFG_CMD_STATUS_SUCCESS) {
1609 wil_err(wil, "ps dev profile cfg failed with status %d\n",
1610 status);
1611 rc = -EINVAL;
1612 }
1613
1614 return rc;
1615}
1616
1617int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short)
1618{
1619 int rc;
1620 struct wmi_set_mgmt_retry_limit_cmd cmd = {
1621 .mgmt_retry_limit = retry_short,
1622 };
1623 struct {
1624 struct wmi_cmd_hdr wmi;
1625 struct wmi_set_mgmt_retry_limit_event evt;
1626 } __packed reply;
1627
1628 wil_dbg_wmi(wil, "Setting mgmt retry short %d\n", retry_short);
1629
1630 if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities))
1631 return -ENOTSUPP;
1632
1633 reply.evt.status = WMI_FW_STATUS_FAILURE;
1634
1635 rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, &cmd, sizeof(cmd),
1636 WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
1637 100);
1638 if (rc)
1639 return rc;
1640
1641 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) {
1642 wil_err(wil, "set mgmt retry limit failed with status %d\n",
1643 reply.evt.status);
1644 rc = -EINVAL;
1645 }
1646
1647 return rc;
1648}
1649
1650int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short)
1651{
1652 int rc;
1653 struct {
1654 struct wmi_cmd_hdr wmi;
1655 struct wmi_get_mgmt_retry_limit_event evt;
1656 } __packed reply;
1657
1658 wil_dbg_wmi(wil, "getting mgmt retry short\n");
1659
1660 if (!test_bit(WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT, wil->fw_capabilities))
1661 return -ENOTSUPP;
1662
1663 reply.evt.mgmt_retry_limit = 0;
1664 rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, NULL, 0,
1665 WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
1666 100);
1667 if (rc)
1668 return rc;
1669
1670 if (retry_short)
1671 *retry_short = reply.evt.mgmt_retry_limit;
1672
1673 return 0;
1674}
1675
1676int wmi_abort_scan(struct wil6210_priv *wil)
1677{
1678 int rc;
1679
1680 wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n");
1681
1682 rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, NULL, 0);
1683 if (rc)
1684 wil_err(wil, "Failed to abort scan (%d)\n", rc);
1685
1686 return rc;
1687}
1688
1567void wmi_event_flush(struct wil6210_priv *wil) 1689void wmi_event_flush(struct wil6210_priv *wil)
1568{ 1690{
1569 struct pending_wmi_event *evt, *t; 1691 struct pending_wmi_event *evt, *t;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index f430e8a80603..d93a4d490d24 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -35,6 +35,7 @@
35#define WMI_MAC_LEN (6) 35#define WMI_MAC_LEN (6)
36#define WMI_PROX_RANGE_NUM (3) 36#define WMI_PROX_RANGE_NUM (3)
37#define WMI_MAX_LOSS_DMG_BEACONS (20) 37#define WMI_MAX_LOSS_DMG_BEACONS (20)
38#define MAX_NUM_OF_SECTORS (128)
38 39
39/* Mailbox interface 40/* Mailbox interface
40 * used for commands and events 41 * used for commands and events
@@ -51,8 +52,10 @@ enum wmi_mid {
51 * the host 52 * the host
52 */ 53 */
53enum wmi_fw_capability { 54enum wmi_fw_capability {
54 WMI_FW_CAPABILITY_FTM = 0, 55 WMI_FW_CAPABILITY_FTM = 0,
55 WMI_FW_CAPABILITY_PS_CONFIG = 1, 56 WMI_FW_CAPABILITY_PS_CONFIG = 1,
57 WMI_FW_CAPABILITY_RF_SECTORS = 2,
58 WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT = 3,
56 WMI_FW_CAPABILITY_MAX, 59 WMI_FW_CAPABILITY_MAX,
57}; 60};
58 61
@@ -66,137 +69,149 @@ struct wmi_cmd_hdr {
66 69
67/* List of Commands */ 70/* List of Commands */
68enum wmi_command_id { 71enum wmi_command_id {
69 WMI_CONNECT_CMDID = 0x01, 72 WMI_CONNECT_CMDID = 0x01,
70 WMI_DISCONNECT_CMDID = 0x03, 73 WMI_DISCONNECT_CMDID = 0x03,
71 WMI_DISCONNECT_STA_CMDID = 0x04, 74 WMI_DISCONNECT_STA_CMDID = 0x04,
72 WMI_START_SCAN_CMDID = 0x07, 75 WMI_START_SCAN_CMDID = 0x07,
73 WMI_SET_BSS_FILTER_CMDID = 0x09, 76 WMI_SET_BSS_FILTER_CMDID = 0x09,
74 WMI_SET_PROBED_SSID_CMDID = 0x0A, 77 WMI_SET_PROBED_SSID_CMDID = 0x0A,
75 WMI_SET_LISTEN_INT_CMDID = 0x0B, 78 WMI_SET_LISTEN_INT_CMDID = 0x0B,
76 WMI_BCON_CTRL_CMDID = 0x0F, 79 WMI_BCON_CTRL_CMDID = 0x0F,
77 WMI_ADD_CIPHER_KEY_CMDID = 0x16, 80 WMI_ADD_CIPHER_KEY_CMDID = 0x16,
78 WMI_DELETE_CIPHER_KEY_CMDID = 0x17, 81 WMI_DELETE_CIPHER_KEY_CMDID = 0x17,
79 WMI_PCP_CONF_CMDID = 0x18, 82 WMI_PCP_CONF_CMDID = 0x18,
80 WMI_SET_APPIE_CMDID = 0x3F, 83 WMI_SET_APPIE_CMDID = 0x3F,
81 WMI_SET_WSC_STATUS_CMDID = 0x41, 84 WMI_SET_WSC_STATUS_CMDID = 0x41,
82 WMI_PXMT_RANGE_CFG_CMDID = 0x42, 85 WMI_PXMT_RANGE_CFG_CMDID = 0x42,
83 WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x43, 86 WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x43,
84 WMI_MEM_READ_CMDID = 0x800, 87 WMI_MEM_READ_CMDID = 0x800,
85 WMI_MEM_WR_CMDID = 0x801, 88 WMI_MEM_WR_CMDID = 0x801,
86 WMI_ECHO_CMDID = 0x803, 89 WMI_ECHO_CMDID = 0x803,
87 WMI_DEEP_ECHO_CMDID = 0x804, 90 WMI_DEEP_ECHO_CMDID = 0x804,
88 WMI_CONFIG_MAC_CMDID = 0x805, 91 WMI_CONFIG_MAC_CMDID = 0x805,
89 WMI_CONFIG_PHY_DEBUG_CMDID = 0x806, 92 WMI_CONFIG_PHY_DEBUG_CMDID = 0x806,
90 WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x808, 93 WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x808,
91 WMI_PHY_GET_STATISTICS_CMDID = 0x809, 94 WMI_PHY_GET_STATISTICS_CMDID = 0x809,
92 WMI_FS_TUNE_CMDID = 0x80A, 95 WMI_FS_TUNE_CMDID = 0x80A,
93 WMI_CORR_MEASURE_CMDID = 0x80B, 96 WMI_CORR_MEASURE_CMDID = 0x80B,
94 WMI_READ_RSSI_CMDID = 0x80C, 97 WMI_READ_RSSI_CMDID = 0x80C,
95 WMI_TEMP_SENSE_CMDID = 0x80E, 98 WMI_TEMP_SENSE_CMDID = 0x80E,
96 WMI_DC_CALIB_CMDID = 0x80F, 99 WMI_DC_CALIB_CMDID = 0x80F,
97 WMI_SEND_TONE_CMDID = 0x810, 100 WMI_SEND_TONE_CMDID = 0x810,
98 WMI_IQ_TX_CALIB_CMDID = 0x811, 101 WMI_IQ_TX_CALIB_CMDID = 0x811,
99 WMI_IQ_RX_CALIB_CMDID = 0x812, 102 WMI_IQ_RX_CALIB_CMDID = 0x812,
100 WMI_SET_UCODE_IDLE_CMDID = 0x813, 103 WMI_SET_UCODE_IDLE_CMDID = 0x813,
101 WMI_SET_WORK_MODE_CMDID = 0x815, 104 WMI_SET_WORK_MODE_CMDID = 0x815,
102 WMI_LO_LEAKAGE_CALIB_CMDID = 0x816, 105 WMI_LO_LEAKAGE_CALIB_CMDID = 0x816,
103 WMI_MARLON_R_READ_CMDID = 0x818, 106 WMI_MARLON_R_READ_CMDID = 0x818,
104 WMI_MARLON_R_WRITE_CMDID = 0x819, 107 WMI_MARLON_R_WRITE_CMDID = 0x819,
105 WMI_MARLON_R_TXRX_SEL_CMDID = 0x81A, 108 WMI_MARLON_R_TXRX_SEL_CMDID = 0x81A,
106 MAC_IO_STATIC_PARAMS_CMDID = 0x81B, 109 MAC_IO_STATIC_PARAMS_CMDID = 0x81B,
107 MAC_IO_DYNAMIC_PARAMS_CMDID = 0x81C, 110 MAC_IO_DYNAMIC_PARAMS_CMDID = 0x81C,
108 WMI_SILENT_RSSI_CALIB_CMDID = 0x81D, 111 WMI_SILENT_RSSI_CALIB_CMDID = 0x81D,
109 WMI_RF_RX_TEST_CMDID = 0x81E, 112 WMI_RF_RX_TEST_CMDID = 0x81E,
110 WMI_CFG_RX_CHAIN_CMDID = 0x820, 113 WMI_CFG_RX_CHAIN_CMDID = 0x820,
111 WMI_VRING_CFG_CMDID = 0x821, 114 WMI_VRING_CFG_CMDID = 0x821,
112 WMI_BCAST_VRING_CFG_CMDID = 0x822, 115 WMI_BCAST_VRING_CFG_CMDID = 0x822,
113 WMI_VRING_BA_EN_CMDID = 0x823, 116 WMI_VRING_BA_EN_CMDID = 0x823,
114 WMI_VRING_BA_DIS_CMDID = 0x824, 117 WMI_VRING_BA_DIS_CMDID = 0x824,
115 WMI_RCP_ADDBA_RESP_CMDID = 0x825, 118 WMI_RCP_ADDBA_RESP_CMDID = 0x825,
116 WMI_RCP_DELBA_CMDID = 0x826, 119 WMI_RCP_DELBA_CMDID = 0x826,
117 WMI_SET_SSID_CMDID = 0x827, 120 WMI_SET_SSID_CMDID = 0x827,
118 WMI_GET_SSID_CMDID = 0x828, 121 WMI_GET_SSID_CMDID = 0x828,
119 WMI_SET_PCP_CHANNEL_CMDID = 0x829, 122 WMI_SET_PCP_CHANNEL_CMDID = 0x829,
120 WMI_GET_PCP_CHANNEL_CMDID = 0x82A, 123 WMI_GET_PCP_CHANNEL_CMDID = 0x82A,
121 WMI_SW_TX_REQ_CMDID = 0x82B, 124 WMI_SW_TX_REQ_CMDID = 0x82B,
122 WMI_READ_MAC_RXQ_CMDID = 0x830, 125 WMI_READ_MAC_RXQ_CMDID = 0x830,
123 WMI_READ_MAC_TXQ_CMDID = 0x831, 126 WMI_READ_MAC_TXQ_CMDID = 0x831,
124 WMI_WRITE_MAC_RXQ_CMDID = 0x832, 127 WMI_WRITE_MAC_RXQ_CMDID = 0x832,
125 WMI_WRITE_MAC_TXQ_CMDID = 0x833, 128 WMI_WRITE_MAC_TXQ_CMDID = 0x833,
126 WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x834, 129 WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x834,
127 WMI_MLME_PUSH_CMDID = 0x835, 130 WMI_MLME_PUSH_CMDID = 0x835,
128 WMI_BEAMFORMING_MGMT_CMDID = 0x836, 131 WMI_BEAMFORMING_MGMT_CMDID = 0x836,
129 WMI_BF_TXSS_MGMT_CMDID = 0x837, 132 WMI_BF_TXSS_MGMT_CMDID = 0x837,
130 WMI_BF_SM_MGMT_CMDID = 0x838, 133 WMI_BF_SM_MGMT_CMDID = 0x838,
131 WMI_BF_RXSS_MGMT_CMDID = 0x839, 134 WMI_BF_RXSS_MGMT_CMDID = 0x839,
132 WMI_BF_TRIG_CMDID = 0x83A, 135 WMI_BF_TRIG_CMDID = 0x83A,
133 WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842, 136 WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842,
134 WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843, 137 WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843,
135 WMI_SET_SECTORS_CMDID = 0x849, 138 WMI_SET_SECTORS_CMDID = 0x849,
136 WMI_MAINTAIN_PAUSE_CMDID = 0x850, 139 WMI_MAINTAIN_PAUSE_CMDID = 0x850,
137 WMI_MAINTAIN_RESUME_CMDID = 0x851, 140 WMI_MAINTAIN_RESUME_CMDID = 0x851,
138 WMI_RS_MGMT_CMDID = 0x852, 141 WMI_RS_MGMT_CMDID = 0x852,
139 WMI_RF_MGMT_CMDID = 0x853, 142 WMI_RF_MGMT_CMDID = 0x853,
140 WMI_THERMAL_THROTTLING_CTRL_CMDID = 0x854, 143 WMI_THERMAL_THROTTLING_CTRL_CMDID = 0x854,
141 WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x855, 144 WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x855,
142 WMI_OTP_READ_CMDID = 0x856, 145 WMI_OTP_READ_CMDID = 0x856,
143 WMI_OTP_WRITE_CMDID = 0x857, 146 WMI_OTP_WRITE_CMDID = 0x857,
144 WMI_LED_CFG_CMDID = 0x858, 147 WMI_LED_CFG_CMDID = 0x858,
145 /* Performance monitoring commands */ 148 /* Performance monitoring commands */
146 WMI_BF_CTRL_CMDID = 0x862, 149 WMI_BF_CTRL_CMDID = 0x862,
147 WMI_NOTIFY_REQ_CMDID = 0x863, 150 WMI_NOTIFY_REQ_CMDID = 0x863,
148 WMI_GET_STATUS_CMDID = 0x864, 151 WMI_GET_STATUS_CMDID = 0x864,
149 WMI_GET_RF_STATUS_CMDID = 0x866, 152 WMI_GET_RF_STATUS_CMDID = 0x866,
150 WMI_GET_BASEBAND_TYPE_CMDID = 0x867, 153 WMI_GET_BASEBAND_TYPE_CMDID = 0x867,
151 WMI_UNIT_TEST_CMDID = 0x900, 154 WMI_UNIT_TEST_CMDID = 0x900,
152 WMI_HICCUP_CMDID = 0x901, 155 WMI_HICCUP_CMDID = 0x901,
153 WMI_FLASH_READ_CMDID = 0x902, 156 WMI_FLASH_READ_CMDID = 0x902,
154 WMI_FLASH_WRITE_CMDID = 0x903, 157 WMI_FLASH_WRITE_CMDID = 0x903,
155 /* Power management */ 158 /* Power management */
156 WMI_TRAFFIC_DEFERRAL_CMDID = 0x904, 159 WMI_TRAFFIC_DEFERRAL_CMDID = 0x904,
157 WMI_TRAFFIC_RESUME_CMDID = 0x905, 160 WMI_TRAFFIC_RESUME_CMDID = 0x905,
158 /* P2P */ 161 /* P2P */
159 WMI_P2P_CFG_CMDID = 0x910, 162 WMI_P2P_CFG_CMDID = 0x910,
160 WMI_PORT_ALLOCATE_CMDID = 0x911, 163 WMI_PORT_ALLOCATE_CMDID = 0x911,
161 WMI_PORT_DELETE_CMDID = 0x912, 164 WMI_PORT_DELETE_CMDID = 0x912,
162 WMI_POWER_MGMT_CFG_CMDID = 0x913, 165 WMI_POWER_MGMT_CFG_CMDID = 0x913,
163 WMI_START_LISTEN_CMDID = 0x914, 166 WMI_START_LISTEN_CMDID = 0x914,
164 WMI_START_SEARCH_CMDID = 0x915, 167 WMI_START_SEARCH_CMDID = 0x915,
165 WMI_DISCOVERY_START_CMDID = 0x916, 168 WMI_DISCOVERY_START_CMDID = 0x916,
166 WMI_DISCOVERY_STOP_CMDID = 0x917, 169 WMI_DISCOVERY_STOP_CMDID = 0x917,
167 WMI_PCP_START_CMDID = 0x918, 170 WMI_PCP_START_CMDID = 0x918,
168 WMI_PCP_STOP_CMDID = 0x919, 171 WMI_PCP_STOP_CMDID = 0x919,
169 WMI_GET_PCP_FACTOR_CMDID = 0x91B, 172 WMI_GET_PCP_FACTOR_CMDID = 0x91B,
170 /* Power Save Configuration Commands */ 173 /* Power Save Configuration Commands */
171 WMI_PS_DEV_PROFILE_CFG_CMDID = 0x91C, 174 WMI_PS_DEV_PROFILE_CFG_CMDID = 0x91C,
172 /* Not supported yet */ 175 /* Not supported yet */
173 WMI_PS_DEV_CFG_CMDID = 0x91D, 176 WMI_PS_DEV_CFG_CMDID = 0x91D,
174 /* Not supported yet */ 177 /* Not supported yet */
175 WMI_PS_DEV_CFG_READ_CMDID = 0x91E, 178 WMI_PS_DEV_CFG_READ_CMDID = 0x91E,
176 /* Per MAC Power Save Configuration commands 179 /* Per MAC Power Save Configuration commands
177 * Not supported yet 180 * Not supported yet
178 */ 181 */
179 WMI_PS_MID_CFG_CMDID = 0x91F, 182 WMI_PS_MID_CFG_CMDID = 0x91F,
180 /* Not supported yet */ 183 /* Not supported yet */
181 WMI_PS_MID_CFG_READ_CMDID = 0x920, 184 WMI_PS_MID_CFG_READ_CMDID = 0x920,
182 WMI_RS_CFG_CMDID = 0x921, 185 WMI_RS_CFG_CMDID = 0x921,
183 WMI_GET_DETAILED_RS_RES_CMDID = 0x922, 186 WMI_GET_DETAILED_RS_RES_CMDID = 0x922,
184 WMI_AOA_MEAS_CMDID = 0x923, 187 WMI_AOA_MEAS_CMDID = 0x923,
185 WMI_TOF_SESSION_START_CMDID = 0x991, 188 WMI_SET_MGMT_RETRY_LIMIT_CMDID = 0x930,
186 WMI_TOF_GET_CAPABILITIES_CMDID = 0x992, 189 WMI_GET_MGMT_RETRY_LIMIT_CMDID = 0x931,
187 WMI_TOF_SET_LCR_CMDID = 0x993, 190 WMI_TOF_SESSION_START_CMDID = 0x991,
188 WMI_TOF_SET_LCI_CMDID = 0x994, 191 WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
189 WMI_TOF_CHANNEL_INFO_CMDID = 0x995, 192 WMI_TOF_SET_LCR_CMDID = 0x993,
190 WMI_SET_MAC_ADDRESS_CMDID = 0xF003, 193 WMI_TOF_SET_LCI_CMDID = 0x994,
191 WMI_ABORT_SCAN_CMDID = 0xF007, 194 WMI_TOF_CHANNEL_INFO_CMDID = 0x995,
192 WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041, 195 WMI_TOF_SET_TX_RX_OFFSET_CMDID = 0x997,
193 WMI_GET_PMK_CMDID = 0xF048, 196 WMI_TOF_GET_TX_RX_OFFSET_CMDID = 0x998,
194 WMI_SET_PASSPHRASE_CMDID = 0xF049, 197 WMI_GET_RF_SECTOR_PARAMS_CMDID = 0x9A0,
195 WMI_SEND_ASSOC_RES_CMDID = 0xF04A, 198 WMI_SET_RF_SECTOR_PARAMS_CMDID = 0x9A1,
196 WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xF04B, 199 WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID = 0x9A2,
197 WMI_MAC_ADDR_REQ_CMDID = 0xF04D, 200 WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID = 0x9A3,
198 WMI_FW_VER_CMDID = 0xF04E, 201 WMI_SET_RF_SECTOR_ON_CMDID = 0x9A4,
199 WMI_PMC_CMDID = 0xF04F, 202 WMI_PRIO_TX_SECTORS_ORDER_CMDID = 0x9A5,
203 WMI_PRIO_TX_SECTORS_NUMBER_CMDID = 0x9A6,
204 WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_CMDID = 0x9A7,
205 WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
206 WMI_ABORT_SCAN_CMDID = 0xF007,
207 WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
208 WMI_GET_PMK_CMDID = 0xF048,
209 WMI_SET_PASSPHRASE_CMDID = 0xF049,
210 WMI_SEND_ASSOC_RES_CMDID = 0xF04A,
211 WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xF04B,
212 WMI_MAC_ADDR_REQ_CMDID = 0xF04D,
213 WMI_FW_VER_CMDID = 0xF04E,
214 WMI_PMC_CMDID = 0xF04F,
200}; 215};
201 216
202/* WMI_CONNECT_CMDID */ 217/* WMI_CONNECT_CMDID */
@@ -879,6 +894,14 @@ struct wmi_aoa_meas_cmd {
879 __le32 meas_rf_mask; 894 __le32 meas_rf_mask;
880} __packed; 895} __packed;
881 896
897/* WMI_SET_MGMT_RETRY_LIMIT_CMDID */
898struct wmi_set_mgmt_retry_limit_cmd {
899 /* MAC retransmit limit for mgmt frames */
900 u8 mgmt_retry_limit;
901 /* alignment to 32b */
902 u8 reserved[3];
903} __packed;
904
882enum wmi_tof_burst_duration { 905enum wmi_tof_burst_duration {
883 WMI_TOF_BURST_DURATION_250_USEC = 2, 906 WMI_TOF_BURST_DURATION_250_USEC = 2,
884 WMI_TOF_BURST_DURATION_500_USEC = 3, 907 WMI_TOF_BURST_DURATION_500_USEC = 3,
@@ -942,6 +965,15 @@ struct wmi_tof_channel_info_cmd {
942 __le32 channel_info_report_request; 965 __le32 channel_info_report_request;
943} __packed; 966} __packed;
944 967
968/* WMI_TOF_SET_TX_RX_OFFSET_CMDID */
969struct wmi_tof_set_tx_rx_offset_cmd {
970 /* TX delay offset */
971 __le32 tx_offset;
972 /* RX delay offset */
973 __le32 rx_offset;
974 __le32 reserved[2];
975} __packed;
976
945/* WMI Events 977/* WMI Events
946 * List of Events (target to host) 978 * List of Events (target to host)
947 */ 979 */
@@ -1035,12 +1067,24 @@ enum wmi_event_id {
1035 WMI_RS_CFG_DONE_EVENTID = 0x1921, 1067 WMI_RS_CFG_DONE_EVENTID = 0x1921,
1036 WMI_GET_DETAILED_RS_RES_EVENTID = 0x1922, 1068 WMI_GET_DETAILED_RS_RES_EVENTID = 0x1922,
1037 WMI_AOA_MEAS_EVENTID = 0x1923, 1069 WMI_AOA_MEAS_EVENTID = 0x1923,
1070 WMI_SET_MGMT_RETRY_LIMIT_EVENTID = 0x1930,
1071 WMI_GET_MGMT_RETRY_LIMIT_EVENTID = 0x1931,
1038 WMI_TOF_SESSION_END_EVENTID = 0x1991, 1072 WMI_TOF_SESSION_END_EVENTID = 0x1991,
1039 WMI_TOF_GET_CAPABILITIES_EVENTID = 0x1992, 1073 WMI_TOF_GET_CAPABILITIES_EVENTID = 0x1992,
1040 WMI_TOF_SET_LCR_EVENTID = 0x1993, 1074 WMI_TOF_SET_LCR_EVENTID = 0x1993,
1041 WMI_TOF_SET_LCI_EVENTID = 0x1994, 1075 WMI_TOF_SET_LCI_EVENTID = 0x1994,
1042 WMI_TOF_FTM_PER_DEST_RES_EVENTID = 0x1995, 1076 WMI_TOF_FTM_PER_DEST_RES_EVENTID = 0x1995,
1043 WMI_TOF_CHANNEL_INFO_EVENTID = 0x1996, 1077 WMI_TOF_CHANNEL_INFO_EVENTID = 0x1996,
1078 WMI_TOF_SET_TX_RX_OFFSET_EVENTID = 0x1997,
1079 WMI_TOF_GET_TX_RX_OFFSET_EVENTID = 0x1998,
1080 WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID = 0x19A0,
1081 WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID = 0x19A1,
1082 WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID = 0x19A2,
1083 WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID = 0x19A3,
1084 WMI_SET_RF_SECTOR_ON_DONE_EVENTID = 0x19A4,
1085 WMI_PRIO_TX_SECTORS_ORDER_EVENTID = 0x19A5,
1086 WMI_PRIO_TX_SECTORS_NUMBER_EVENTID = 0x19A6,
1087 WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_EVENTID = 0x19A7,
1044 WMI_SET_CHANNEL_EVENTID = 0x9000, 1088 WMI_SET_CHANNEL_EVENTID = 0x9000,
1045 WMI_ASSOC_REQ_EVENTID = 0x9001, 1089 WMI_ASSOC_REQ_EVENTID = 0x9001,
1046 WMI_EAPOL_RX_EVENTID = 0x9002, 1090 WMI_EAPOL_RX_EVENTID = 0x9002,
@@ -1166,6 +1210,7 @@ enum baseband_type {
1166 BASEBAND_SPARROW_M_B0 = 0x05, 1210 BASEBAND_SPARROW_M_B0 = 0x05,
1167 BASEBAND_SPARROW_M_C0 = 0x06, 1211 BASEBAND_SPARROW_M_C0 = 0x06,
1168 BASEBAND_SPARROW_M_D0 = 0x07, 1212 BASEBAND_SPARROW_M_D0 = 0x07,
1213 BASEBAND_TALYN_M_A0 = 0x08,
1169}; 1214};
1170 1215
1171/* WMI_GET_BASEBAND_TYPE_EVENTID */ 1216/* WMI_GET_BASEBAND_TYPE_EVENTID */
@@ -2070,6 +2115,22 @@ struct wmi_aoa_meas_event {
2070 u8 meas_data[WMI_AOA_MAX_DATA_SIZE]; 2115 u8 meas_data[WMI_AOA_MAX_DATA_SIZE];
2071} __packed; 2116} __packed;
2072 2117
2118/* WMI_SET_MGMT_RETRY_LIMIT_EVENTID */
2119struct wmi_set_mgmt_retry_limit_event {
2120 /* enum wmi_fw_status */
2121 u8 status;
2122 /* alignment to 32b */
2123 u8 reserved[3];
2124} __packed;
2125
2126/* WMI_GET_MGMT_RETRY_LIMIT_EVENTID */
2127struct wmi_get_mgmt_retry_limit_event {
2128 /* MAC retransmit limit for mgmt frames */
2129 u8 mgmt_retry_limit;
2130 /* alignment to 32b */
2131 u8 reserved[3];
2132} __packed;
2133
2073/* WMI_TOF_GET_CAPABILITIES_EVENTID */ 2134/* WMI_TOF_GET_CAPABILITIES_EVENTID */
2074struct wmi_tof_get_capabilities_event { 2135struct wmi_tof_get_capabilities_event {
2075 u8 ftm_capability; 2136 u8 ftm_capability;
@@ -2184,4 +2245,283 @@ struct wmi_tof_channel_info_event {
2184 u8 report[0]; 2245 u8 report[0];
2185} __packed; 2246} __packed;
2186 2247
2248/* WMI_TOF_SET_TX_RX_OFFSET_EVENTID */
2249struct wmi_tof_set_tx_rx_offset_event {
2250 /* enum wmi_fw_status */
2251 u8 status;
2252 u8 reserved[3];
2253} __packed;
2254
2255/* WMI_TOF_GET_TX_RX_OFFSET_EVENTID */
2256struct wmi_tof_get_tx_rx_offset_event {
2257 /* enum wmi_fw_status */
2258 u8 status;
2259 u8 reserved1[3];
2260 /* TX delay offset */
2261 __le32 tx_offset;
2262 /* RX delay offset */
2263 __le32 rx_offset;
2264 __le32 reserved2[2];
2265} __packed;
2266
2267/* Result status codes for WMI commands */
2268enum wmi_rf_sector_status {
2269 WMI_RF_SECTOR_STATUS_SUCCESS = 0x00,
2270 WMI_RF_SECTOR_STATUS_BAD_PARAMETERS_ERROR = 0x01,
2271 WMI_RF_SECTOR_STATUS_BUSY_ERROR = 0x02,
2272 WMI_RF_SECTOR_STATUS_NOT_SUPPORTED_ERROR = 0x03,
2273};
2274
2275/* Types of the RF sector (TX,RX) */
2276enum wmi_rf_sector_type {
2277 WMI_RF_SECTOR_TYPE_RX = 0x00,
2278 WMI_RF_SECTOR_TYPE_TX = 0x01,
2279};
2280
2281/* Content of RF Sector (six 32-bits registers) */
2282struct wmi_rf_sector_info {
2283 /* Phase values for RF Chains[15-0] (2bits per RF chain) */
2284 __le32 psh_hi;
2285 /* Phase values for RF Chains[31-16] (2bits per RF chain) */
2286 __le32 psh_lo;
2287 /* ETYPE Bit0 for all RF chains[31-0] - bit0 of Edge amplifier gain
2288 * index
2289 */
2290 __le32 etype0;
2291 /* ETYPE Bit1 for all RF chains[31-0] - bit1 of Edge amplifier gain
2292 * index
2293 */
2294 __le32 etype1;
2295 /* ETYPE Bit2 for all RF chains[31-0] - bit2 of Edge amplifier gain
2296 * index
2297 */
2298 __le32 etype2;
2299 /* D-Type values (3bits each) for 8 Distribution amplifiers + X16
2300 * switch bits
2301 */
2302 __le32 dtype_swch_off;
2303} __packed;
2304
2305#define WMI_INVALID_RF_SECTOR_INDEX (0xFFFF)
2306#define WMI_MAX_RF_MODULES_NUM (8)
2307
2308/* WMI_GET_RF_SECTOR_PARAMS_CMD */
2309struct wmi_get_rf_sector_params_cmd {
2310 /* Sector number to be retrieved */
2311 __le16 sector_idx;
2312 /* enum wmi_rf_sector_type - type of requested RF sector */
2313 u8 sector_type;
2314 /* bitmask vector specifying destination RF modules */
2315 u8 rf_modules_vec;
2316} __packed;
2317
2318/* \WMI_GET_RF_SECTOR_PARAMS_DONE_EVENT */
2319struct wmi_get_rf_sector_params_done_event {
2320 /* result status of WMI_GET_RF_SECTOR_PARAMS_CMD (enum
2321 * wmi_rf_sector_status)
2322 */
2323 u8 status;
2324 /* align next field to U64 boundary */
2325 u8 reserved[7];
2326 /* TSF timestamp when RF sectors where retrieved */
2327 __le64 tsf;
2328 /* Content of RF sector retrieved from each RF module */
2329 struct wmi_rf_sector_info sectors_info[WMI_MAX_RF_MODULES_NUM];
2330} __packed;
2331
2332/* WMI_SET_RF_SECTOR_PARAMS_CMD */
2333struct wmi_set_rf_sector_params_cmd {
2334 /* Sector number to be retrieved */
2335 __le16 sector_idx;
2336 /* enum wmi_rf_sector_type - type of requested RF sector */
2337 u8 sector_type;
2338 /* bitmask vector specifying destination RF modules */
2339 u8 rf_modules_vec;
2340 /* Content of RF sector to be written to each RF module */
2341 struct wmi_rf_sector_info sectors_info[WMI_MAX_RF_MODULES_NUM];
2342} __packed;
2343
2344/* \WMI_SET_RF_SECTOR_PARAMS_DONE_EVENT */
2345struct wmi_set_rf_sector_params_done_event {
2346 /* result status of WMI_SET_RF_SECTOR_PARAMS_CMD (enum
2347 * wmi_rf_sector_status)
2348 */
2349 u8 status;
2350} __packed;
2351
2352/* WMI_GET_SELECTED_RF_SECTOR_INDEX_CMD - Get RF sector index selected by
2353 * TXSS/BRP for communication with specified CID
2354 */
2355struct wmi_get_selected_rf_sector_index_cmd {
2356 /* Connection/Station ID in [0:7] range */
2357 u8 cid;
2358 /* type of requested RF sector (enum wmi_rf_sector_type) */
2359 u8 sector_type;
2360 /* align to U32 boundary */
2361 u8 reserved[2];
2362} __packed;
2363
2364/* \WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT - Returns retrieved RF sector
2365 * index selected by TXSS/BRP for communication with specified CID
2366 */
2367struct wmi_get_selected_rf_sector_index_done_event {
2368 /* Retrieved sector index selected in TXSS (for TX sector request) or
2369 * BRP (for RX sector request)
2370 */
2371 __le16 sector_idx;
2372 /* result status of WMI_GET_SELECTED_RF_SECTOR_INDEX_CMD (enum
2373 * wmi_rf_sector_status)
2374 */
2375 u8 status;
2376 /* align next field to U64 boundary */
2377 u8 reserved[5];
2378 /* TSF timestamp when result was retrieved */
2379 __le64 tsf;
2380} __packed;
2381
2382/* WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD - Force RF sector index for
2383 * communication with specified CID. Assumes that TXSS/BRP is disabled by
2384 * other command
2385 */
2386struct wmi_set_selected_rf_sector_index_cmd {
2387 /* Connection/Station ID in [0:7] range */
2388 u8 cid;
2389 /* type of requested RF sector (enum wmi_rf_sector_type) */
2390 u8 sector_type;
2391 /* Forced sector index */
2392 __le16 sector_idx;
2393} __packed;
2394
2395/* \WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENT - Success/Fail status for
2396 * WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD
2397 */
2398struct wmi_set_selected_rf_sector_index_done_event {
2399 /* result status of WMI_SET_SELECTED_RF_SECTOR_INDEX_CMD (enum
2400 * wmi_rf_sector_status)
2401 */
2402 u8 status;
2403 /* align to U32 boundary */
2404 u8 reserved[3];
2405} __packed;
2406
2407/* WMI_SET_RF_SECTOR_ON_CMD - Activates specified sector for specified rf
2408 * modules
2409 */
2410struct wmi_set_rf_sector_on_cmd {
2411 /* Sector index to be activated */
2412 __le16 sector_idx;
2413 /* type of requested RF sector (enum wmi_rf_sector_type) */
2414 u8 sector_type;
2415 /* bitmask vector specifying destination RF modules */
2416 u8 rf_modules_vec;
2417} __packed;
2418
2419/* \WMI_SET_RF_SECTOR_ON_DONE_EVENT - Success/Fail status for
2420 * WMI_SET_RF_SECTOR_ON_CMD
2421 */
2422struct wmi_set_rf_sector_on_done_event {
2423 /* result status of WMI_SET_RF_SECTOR_ON_CMD (enum
2424 * wmi_rf_sector_status)
2425 */
2426 u8 status;
2427 /* align to U32 boundary */
2428 u8 reserved[3];
2429} __packed;
2430
2431enum wmi_sector_sweep_type {
2432 WMI_SECTOR_SWEEP_TYPE_TXSS = 0x00,
2433 WMI_SECTOR_SWEEP_TYPE_BCON = 0x01,
2434 WMI_SECTOR_SWEEP_TYPE_TXSS_AND_BCON = 0x02,
2435 WMI_SECTOR_SWEEP_TYPE_NUM = 0x03,
2436};
2437
2438/* WMI_PRIO_TX_SECTORS_ORDER_CMDID
2439 *
2440 * Set the order of TX sectors in TXSS and/or Beacon(AP).
2441 *
2442 * Returned event:
2443 * - WMI_PRIO_TX_SECTORS_ORDER_EVENTID
2444 */
2445struct wmi_prio_tx_sectors_order_cmd {
2446 /* tx sectors order to be applied, 0xFF for end of array */
2447 u8 tx_sectors_priority_array[MAX_NUM_OF_SECTORS];
2448 /* enum wmi_sector_sweep_type, TXSS and/or Beacon */
2449 u8 sector_sweep_type;
2450 /* needed only for TXSS configuration */
2451 u8 cid;
2452 /* alignment to 32b */
2453 u8 reserved[2];
2454} __packed;
2455
2456/* completion status codes */
2457enum wmi_prio_tx_sectors_cmd_status {
2458 WMI_PRIO_TX_SECT_CMD_STATUS_SUCCESS = 0x00,
2459 WMI_PRIO_TX_SECT_CMD_STATUS_BAD_PARAM = 0x01,
2460 /* other error */
2461 WMI_PRIO_TX_SECT_CMD_STATUS_ERROR = 0x02,
2462};
2463
2464/* WMI_PRIO_TX_SECTORS_ORDER_EVENTID */
2465struct wmi_prio_tx_sectors_order_event {
2466 /* enum wmi_prio_tx_sectors_cmd_status */
2467 u8 status;
2468 /* alignment to 32b */
2469 u8 reserved[3];
2470} __packed;
2471
2472struct wmi_prio_tx_sectors_num_cmd {
2473 /* [0-128], 0 = No changes */
2474 u8 beacon_number_of_sectors;
2475 /* [0-128], 0 = No changes */
2476 u8 txss_number_of_sectors;
2477 /* [0-8] needed only for TXSS configuration */
2478 u8 cid;
2479} __packed;
2480
2481/* WMI_PRIO_TX_SECTORS_NUMBER_CMDID
2482 *
2483 * Set the number of active sectors in TXSS and/or Beacon.
2484 *
2485 * Returned event:
2486 * - WMI_PRIO_TX_SECTORS_NUMBER_EVENTID
2487 */
2488struct wmi_prio_tx_sectors_number_cmd {
2489 struct wmi_prio_tx_sectors_num_cmd active_sectors_num;
2490 /* alignment to 32b */
2491 u8 reserved;
2492} __packed;
2493
2494/* WMI_PRIO_TX_SECTORS_NUMBER_EVENTID */
2495struct wmi_prio_tx_sectors_number_event {
2496 /* enum wmi_prio_tx_sectors_cmd_status */
2497 u8 status;
2498 /* alignment to 32b */
2499 u8 reserved[3];
2500} __packed;
2501
2502/* WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_CMDID
2503 *
2504 * Set default sectors order and number (hard coded in board file)
2505 * in TXSS and/or Beacon.
2506 *
2507 * Returned event:
2508 * - WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_EVENTID
2509 */
2510struct wmi_prio_tx_sectors_set_default_cfg_cmd {
2511 /* enum wmi_sector_sweep_type, TXSS and/or Beacon */
2512 u8 sector_sweep_type;
2513 /* needed only for TXSS configuration */
2514 u8 cid;
2515 /* alignment to 32b */
2516 u8 reserved[2];
2517} __packed;
2518
2519/* WMI_PRIO_TX_SECTORS_SET_DEFAULT_CFG_EVENTID */
2520struct wmi_prio_tx_sectors_set_default_cfg_event {
2521 /* enum wmi_prio_tx_sectors_cmd_status */
2522 u8 status;
2523 /* alignment to 32b */
2524 u8 reserved[3];
2525} __packed;
2526
2187#endif /* __WILOCITY_WMI_H__ */ 2527#endif /* __WILOCITY_WMI_H__ */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
index 9e4b505ca593..d1568bed1ad1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
@@ -35,7 +35,8 @@ brcmfmac-objs += \
35 firmware.o \ 35 firmware.o \
36 feature.o \ 36 feature.o \
37 btcoex.o \ 37 btcoex.o \
38 vendor.o 38 vendor.o \
39 pno.o
39brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \ 40brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \
40 bcdc.o 41 bcdc.o
41brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \ 42brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 2b246545647a..e21f7600122b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -22,10 +22,12 @@
22/* IDs of the 6 default common rings of msgbuf protocol */ 22/* IDs of the 6 default common rings of msgbuf protocol */
23#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0 23#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
24#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 1 24#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 1
25#define BRCMF_H2D_MSGRING_FLOWRING_IDSTART 2
25#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 2 26#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 2
26#define BRCMF_D2H_MSGRING_TX_COMPLETE 3 27#define BRCMF_D2H_MSGRING_TX_COMPLETE 3
27#define BRCMF_D2H_MSGRING_RX_COMPLETE 4 28#define BRCMF_D2H_MSGRING_RX_COMPLETE 4
28 29
30
29#define BRCMF_NROF_H2D_COMMON_MSGRINGS 2 31#define BRCMF_NROF_H2D_COMMON_MSGRINGS 2
30#define BRCMF_NROF_D2H_COMMON_MSGRINGS 3 32#define BRCMF_NROF_D2H_COMMON_MSGRINGS 3
31#define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \ 33#define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \
@@ -95,14 +97,18 @@ struct brcmf_bus_ops {
95 * @flowrings: commonrings which are dynamically created and destroyed for data. 97 * @flowrings: commonrings which are dynamically created and destroyed for data.
96 * @rx_dataoffset: if set then all rx data has this this offset. 98 * @rx_dataoffset: if set then all rx data has this this offset.
97 * @max_rxbufpost: maximum number of buffers to post for rx. 99 * @max_rxbufpost: maximum number of buffers to post for rx.
98 * @nrof_flowrings: number of flowrings. 100 * @max_flowrings: maximum number of tx flow rings supported.
101 * @max_submissionrings: maximum number of submission rings(h2d) supported.
102 * @max_completionrings: maximum number of completion rings(d2h) supported.
99 */ 103 */
100struct brcmf_bus_msgbuf { 104struct brcmf_bus_msgbuf {
101 struct brcmf_commonring *commonrings[BRCMF_NROF_COMMON_MSGRINGS]; 105 struct brcmf_commonring *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
102 struct brcmf_commonring **flowrings; 106 struct brcmf_commonring **flowrings;
103 u32 rx_dataoffset; 107 u32 rx_dataoffset;
104 u32 max_rxbufpost; 108 u32 max_rxbufpost;
105 u32 nrof_flowrings; 109 u16 max_flowrings;
110 u16 max_submissionrings;
111 u16 max_completionrings;
106}; 112};
107 113
108 114
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 4e238c0bdaf3..ccae3bbe7db2 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -32,6 +32,7 @@
32#include "fwil_types.h" 32#include "fwil_types.h"
33#include "p2p.h" 33#include "p2p.h"
34#include "btcoex.h" 34#include "btcoex.h"
35#include "pno.h"
35#include "cfg80211.h" 36#include "cfg80211.h"
36#include "feature.h" 37#include "feature.h"
37#include "fwil.h" 38#include "fwil.h"
@@ -41,16 +42,6 @@
41#include "common.h" 42#include "common.h"
42 43
43#define BRCMF_SCAN_IE_LEN_MAX 2048 44#define BRCMF_SCAN_IE_LEN_MAX 2048
44#define BRCMF_PNO_VERSION 2
45#define BRCMF_PNO_TIME 30
46#define BRCMF_PNO_REPEAT 4
47#define BRCMF_PNO_FREQ_EXPO_MAX 3
48#define BRCMF_PNO_MAX_PFN_COUNT 16
49#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
50#define BRCMF_PNO_HIDDEN_BIT 2
51#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
52#define BRCMF_PNO_SCAN_COMPLETE 1
53#define BRCMF_PNO_SCAN_INCOMPLETE 0
54 45
55#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ 46#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56#define WPA_OUI_TYPE 1 47#define WPA_OUI_TYPE 1
@@ -768,12 +759,12 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
768 brcmf_scan_config_mpc(ifp, 1); 759 brcmf_scan_config_mpc(ifp, 1);
769 760
770 /* 761 /*
771 * e-scan can be initiated by scheduled scan 762 * e-scan can be initiated internally
772 * which takes precedence. 763 * which takes precedence.
773 */ 764 */
774 if (cfg->sched_escan) { 765 if (cfg->internal_escan) {
775 brcmf_dbg(SCAN, "scheduled scan completed\n"); 766 brcmf_dbg(SCAN, "scheduled scan completed\n");
776 cfg->sched_escan = false; 767 cfg->internal_escan = false;
777 if (!aborted) 768 if (!aborted)
778 cfg80211_sched_scan_results(cfg_to_wiphy(cfg)); 769 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
779 } else if (scan_request) { 770 } else if (scan_request) {
@@ -1091,9 +1082,9 @@ exit:
1091} 1082}
1092 1083
1093static s32 1084static s32
1094brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy, 1085brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1095 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1096{ 1086{
1087 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1097 s32 err; 1088 s32 err;
1098 u32 passive_scan; 1089 u32 passive_scan;
1099 struct brcmf_scan_results *results; 1090 struct brcmf_scan_results *results;
@@ -1101,7 +1092,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1101 1092
1102 brcmf_dbg(SCAN, "Enter\n"); 1093 brcmf_dbg(SCAN, "Enter\n");
1103 escan->ifp = ifp; 1094 escan->ifp = ifp;
1104 escan->wiphy = wiphy; 1095 escan->wiphy = cfg->wiphy;
1105 escan->escan_state = WL_ESCAN_STATE_SCANNING; 1096 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1106 passive_scan = cfg->active_scan ? 0 : 1; 1097 passive_scan = cfg->active_scan ? 0 : 1;
1107 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, 1098 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
@@ -1181,7 +1172,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1181 if (err) 1172 if (err)
1182 goto scan_out; 1173 goto scan_out;
1183 1174
1184 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request); 1175 err = brcmf_do_escan(vif->ifp, request);
1185 if (err) 1176 if (err)
1186 goto scan_out; 1177 goto scan_out;
1187 } else { 1178 } else {
@@ -3024,7 +3015,7 @@ void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
3024 struct escan_info *escan = &cfg->escan_info; 3015 struct escan_info *escan = &cfg->escan_info;
3025 3016
3026 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); 3017 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3027 if (cfg->scan_request) { 3018 if (cfg->internal_escan || cfg->scan_request) {
3028 escan->escan_state = WL_ESCAN_STATE_IDLE; 3019 escan->escan_state = WL_ESCAN_STATE_IDLE;
3029 brcmf_notify_escan_complete(cfg, escan->ifp, true, true); 3020 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
3030 } 3021 }
@@ -3047,7 +3038,7 @@ static void brcmf_escan_timeout(unsigned long data)
3047 struct brcmf_cfg80211_info *cfg = 3038 struct brcmf_cfg80211_info *cfg =
3048 (struct brcmf_cfg80211_info *)data; 3039 (struct brcmf_cfg80211_info *)data;
3049 3040
3050 if (cfg->scan_request) { 3041 if (cfg->internal_escan || cfg->scan_request) {
3051 brcmf_err("timer expired\n"); 3042 brcmf_err("timer expired\n");
3052 schedule_work(&cfg->escan_timeout_work); 3043 schedule_work(&cfg->escan_timeout_work);
3053 } 3044 }
@@ -3130,7 +3121,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3130 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le)) 3121 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3131 goto exit; 3122 goto exit;
3132 3123
3133 if (!cfg->scan_request) { 3124 if (!cfg->internal_escan && !cfg->scan_request) {
3134 brcmf_dbg(SCAN, "result without cfg80211 request\n"); 3125 brcmf_dbg(SCAN, "result without cfg80211 request\n");
3135 goto exit; 3126 goto exit;
3136 } 3127 }
@@ -3176,7 +3167,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3176 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; 3167 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3177 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL)) 3168 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3178 goto exit; 3169 goto exit;
3179 if (cfg->scan_request) { 3170 if (cfg->internal_escan || cfg->scan_request) {
3180 brcmf_inform_bss(cfg); 3171 brcmf_inform_bss(cfg);
3181 aborted = status != BRCMF_E_STATUS_SUCCESS; 3172 aborted = status != BRCMF_E_STATUS_SUCCESS;
3182 brcmf_notify_escan_complete(cfg, ifp, aborted, false); 3173 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
@@ -3201,6 +3192,95 @@ static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3201 brcmf_cfg80211_escan_timeout_worker); 3192 brcmf_cfg80211_escan_timeout_worker);
3202} 3193}
3203 3194
3195static struct cfg80211_scan_request *
3196brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3197 struct cfg80211_scan_request *req;
3198 size_t req_size;
3199
3200 req_size = sizeof(*req) +
3201 n_netinfo * sizeof(req->channels[0]) +
3202 n_netinfo * sizeof(*req->ssids);
3203
3204 req = kzalloc(req_size, GFP_KERNEL);
3205 if (req) {
3206 req->wiphy = wiphy;
3207 req->ssids = (void *)(&req->channels[0]) +
3208 n_netinfo * sizeof(req->channels[0]);
3209 }
3210 return req;
3211}
3212
3213static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
3214 u8 *ssid, u8 ssid_len, u8 channel)
3215{
3216 struct ieee80211_channel *chan;
3217 enum nl80211_band band;
3218 int freq;
3219
3220 if (channel <= CH_MAX_2G_CHANNEL)
3221 band = NL80211_BAND_2GHZ;
3222 else
3223 band = NL80211_BAND_5GHZ;
3224
3225 freq = ieee80211_channel_to_frequency(channel, band);
3226 if (!freq)
3227 return -EINVAL;
3228
3229 chan = ieee80211_get_channel(req->wiphy, freq);
3230 if (!chan)
3231 return -EINVAL;
3232
3233 req->channels[req->n_channels++] = chan;
3234 memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
3235 req->ssids[req->n_ssids++].ssid_len = ssid_len;
3236
3237 return 0;
3238}
3239
3240static int brcmf_start_internal_escan(struct brcmf_if *ifp,
3241 struct cfg80211_scan_request *request)
3242{
3243 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3244 int err;
3245
3246 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3247 /* Abort any on-going scan */
3248 brcmf_abort_scanning(cfg);
3249 }
3250
3251 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3252 cfg->escan_info.run = brcmf_run_escan;
3253 err = brcmf_do_escan(ifp, request);
3254 if (err) {
3255 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3256 return err;
3257 }
3258 cfg->internal_escan = true;
3259 return 0;
3260}
3261
3262static struct brcmf_pno_net_info_le *
3263brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
3264{
3265 struct brcmf_pno_scanresults_v2_le *pfn_v2;
3266 struct brcmf_pno_net_info_le *netinfo;
3267
3268 switch (pfn_v1->version) {
3269 default:
3270 WARN_ON(1);
3271 /* fall-thru */
3272 case cpu_to_le32(1):
3273 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
3274 break;
3275 case cpu_to_le32(2):
3276 pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
3277 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
3278 break;
3279 }
3280
3281 return netinfo;
3282}
3283
3204/* PFN result doesn't have all the info which are required by the supplicant 3284/* PFN result doesn't have all the info which are required by the supplicant
3205 * (For e.g IEs) Do a target Escan so that sched scan results are reported 3285 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3206 * via wl_inform_single_bss in the required format. Escan does require the 3286 * via wl_inform_single_bss in the required format. Escan does require the
@@ -3214,12 +3294,8 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3214 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 3294 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3215 struct brcmf_pno_net_info_le *netinfo, *netinfo_start; 3295 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3216 struct cfg80211_scan_request *request = NULL; 3296 struct cfg80211_scan_request *request = NULL;
3217 struct cfg80211_ssid *ssid = NULL;
3218 struct ieee80211_channel *channel = NULL;
3219 struct wiphy *wiphy = cfg_to_wiphy(cfg); 3297 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3220 int err = 0; 3298 int i, err = 0;
3221 int channel_req = 0;
3222 int band = 0;
3223 struct brcmf_pno_scanresults_le *pfn_result; 3299 struct brcmf_pno_scanresults_le *pfn_result;
3224 u32 result_count; 3300 u32 result_count;
3225 u32 status; 3301 u32 status;
@@ -3245,254 +3321,86 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3245 */ 3321 */
3246 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE); 3322 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3247 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count); 3323 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3248 if (result_count > 0) { 3324 if (!result_count) {
3249 int i;
3250
3251 request = kzalloc(sizeof(*request), GFP_KERNEL);
3252 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3253 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3254 if (!request || !ssid || !channel) {
3255 err = -ENOMEM;
3256 goto out_err;
3257 }
3258
3259 request->wiphy = wiphy;
3260 data += sizeof(struct brcmf_pno_scanresults_le);
3261 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3262
3263 for (i = 0; i < result_count; i++) {
3264 netinfo = &netinfo_start[i];
3265 if (!netinfo) {
3266 brcmf_err("Invalid netinfo ptr. index: %d\n",
3267 i);
3268 err = -EINVAL;
3269 goto out_err;
3270 }
3271
3272 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3273 netinfo->SSID, netinfo->channel);
3274 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3275 ssid[i].ssid_len = netinfo->SSID_len;
3276 request->n_ssids++;
3277
3278 channel_req = netinfo->channel;
3279 if (channel_req <= CH_MAX_2G_CHANNEL)
3280 band = NL80211_BAND_2GHZ;
3281 else
3282 band = NL80211_BAND_5GHZ;
3283 channel[i].center_freq =
3284 ieee80211_channel_to_frequency(channel_req,
3285 band);
3286 channel[i].band = band;
3287 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3288 request->channels[i] = &channel[i];
3289 request->n_channels++;
3290 }
3291
3292 /* assign parsed ssid array */
3293 if (request->n_ssids)
3294 request->ssids = &ssid[0];
3295
3296 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3297 /* Abort any on-going scan */
3298 brcmf_abort_scanning(cfg);
3299 }
3300
3301 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3302 cfg->escan_info.run = brcmf_run_escan;
3303 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3304 if (err) {
3305 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3306 goto out_err;
3307 }
3308 cfg->sched_escan = true;
3309 cfg->scan_request = request;
3310 } else {
3311 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n"); 3325 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3312 goto out_err; 3326 goto out_err;
3313 } 3327 }
3314 3328 request = brcmf_alloc_internal_escan_request(wiphy,
3315 kfree(ssid); 3329 result_count);
3316 kfree(channel); 3330 if (!request) {
3317 kfree(request); 3331 err = -ENOMEM;
3318 return 0; 3332 goto out_err;
3319
3320out_err:
3321 kfree(ssid);
3322 kfree(channel);
3323 kfree(request);
3324 cfg80211_sched_scan_stopped(wiphy);
3325 return err;
3326}
3327
3328static int brcmf_dev_pno_clean(struct net_device *ndev)
3329{
3330 int ret;
3331
3332 /* Disable pfn */
3333 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3334 if (ret == 0) {
3335 /* clear pfn */
3336 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3337 NULL, 0);
3338 }
3339 if (ret < 0)
3340 brcmf_err("failed code %d\n", ret);
3341
3342 return ret;
3343}
3344
3345static int brcmf_dev_pno_config(struct brcmf_if *ifp,
3346 struct cfg80211_sched_scan_request *request)
3347{
3348 struct brcmf_pno_param_le pfn_param;
3349 struct brcmf_pno_macaddr_le pfn_mac;
3350 s32 err;
3351 u8 *mac_mask;
3352 int i;
3353
3354 memset(&pfn_param, 0, sizeof(pfn_param));
3355 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3356
3357 /* set extra pno params */
3358 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3359 pfn_param.repeat = BRCMF_PNO_REPEAT;
3360 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3361
3362 /* set up pno scan fr */
3363 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3364
3365 err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
3366 sizeof(pfn_param));
3367 if (err) {
3368 brcmf_err("pfn_set failed, err=%d\n", err);
3369 return err;
3370 } 3333 }
3371 3334
3372 /* Find out if mac randomization should be turned on */ 3335 data += sizeof(struct brcmf_pno_scanresults_le);
3373 if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) 3336 netinfo_start = brcmf_get_netinfo_array(pfn_result);
3374 return 0;
3375 3337
3376 pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER; 3338 for (i = 0; i < result_count; i++) {
3377 pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC; 3339 netinfo = &netinfo_start[i];
3340 if (!netinfo) {
3341 brcmf_err("Invalid netinfo ptr. index: %d\n",
3342 i);
3343 err = -EINVAL;
3344 goto out_err;
3345 }
3378 3346
3379 memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN); 3347 brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3380 mac_mask = request->mac_addr_mask; 3348 netinfo->SSID, netinfo->channel);
3381 for (i = 0; i < ETH_ALEN; i++) { 3349 err = brcmf_internal_escan_add_info(request,
3382 pfn_mac.mac[i] &= mac_mask[i]; 3350 netinfo->SSID,
3383 pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]); 3351 netinfo->SSID_len,
3352 netinfo->channel);
3353 if (err)
3354 goto out_err;
3384 } 3355 }
3385 /* Clear multi bit */
3386 pfn_mac.mac[0] &= 0xFE;
3387 /* Set locally administered */
3388 pfn_mac.mac[0] |= 0x02;
3389 3356
3390 err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac, 3357 err = brcmf_start_internal_escan(ifp, request);
3391 sizeof(pfn_mac)); 3358 if (!err)
3392 if (err) 3359 goto free_req;
3393 brcmf_err("pfn_macaddr failed, err=%d\n", err);
3394 3360
3361out_err:
3362 cfg80211_sched_scan_stopped(wiphy);
3363free_req:
3364 kfree(request);
3395 return err; 3365 return err;
3396} 3366}
3397 3367
3398static int 3368static int
3399brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy, 3369brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3400 struct net_device *ndev, 3370 struct net_device *ndev,
3401 struct cfg80211_sched_scan_request *request) 3371 struct cfg80211_sched_scan_request *req)
3402{ 3372{
3403 struct brcmf_if *ifp = netdev_priv(ndev); 3373 struct brcmf_if *ifp = netdev_priv(ndev);
3404 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); 3374 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3405 struct brcmf_pno_net_param_le pfn;
3406 int i;
3407 int ret = 0;
3408 3375
3409 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n", 3376 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3410 request->n_match_sets, request->n_ssids); 3377 req->n_match_sets, req->n_ssids);
3411 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { 3378
3412 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3413 return -EAGAIN;
3414 }
3415 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { 3379 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3416 brcmf_err("Scanning suppressed: status (%lu)\n", 3380 brcmf_err("Scanning suppressed: status (%lu)\n",
3417 cfg->scan_status); 3381 cfg->scan_status);
3418 return -EAGAIN; 3382 return -EAGAIN;
3419 } 3383 }
3420 3384
3421 if (!request->n_ssids || !request->n_match_sets) { 3385 if (req->n_match_sets <= 0) {
3422 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n", 3386 brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3423 request->n_ssids); 3387 req->n_match_sets);
3424 return -EINVAL; 3388 return -EINVAL;
3425 } 3389 }
3426 3390
3427 if (request->n_ssids > 0) { 3391 return brcmf_pno_start_sched_scan(ifp, req);
3428 for (i = 0; i < request->n_ssids; i++) {
3429 /* Active scan req for ssids */
3430 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3431 request->ssids[i].ssid);
3432
3433 /* match_set ssids is a supert set of n_ssid list,
3434 * so we need not add these set separately.
3435 */
3436 }
3437 }
3438
3439 if (request->n_match_sets > 0) {
3440 /* clean up everything */
3441 ret = brcmf_dev_pno_clean(ndev);
3442 if (ret < 0) {
3443 brcmf_err("failed error=%d\n", ret);
3444 return ret;
3445 }
3446
3447 /* configure pno */
3448 if (brcmf_dev_pno_config(ifp, request))
3449 return -EINVAL;
3450
3451 /* configure each match set */
3452 for (i = 0; i < request->n_match_sets; i++) {
3453 struct cfg80211_ssid *ssid;
3454 u32 ssid_len;
3455
3456 ssid = &request->match_sets[i].ssid;
3457 ssid_len = ssid->ssid_len;
3458
3459 if (!ssid_len) {
3460 brcmf_err("skip broadcast ssid\n");
3461 continue;
3462 }
3463 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3464 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3465 pfn.wsec = cpu_to_le32(0);
3466 pfn.infra = cpu_to_le32(1);
3467 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3468 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3469 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3470 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3471 sizeof(pfn));
3472 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3473 ret == 0 ? "set" : "failed", ssid->ssid);
3474 }
3475 /* Enable the PNO */
3476 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3477 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3478 return -EINVAL;
3479 }
3480 } else {
3481 return -EINVAL;
3482 }
3483
3484 return 0;
3485} 3392}
3486 3393
3487static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, 3394static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3488 struct net_device *ndev) 3395 struct net_device *ndev)
3489{ 3396{
3490 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3397 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3398 struct brcmf_if *ifp = netdev_priv(ndev);
3491 3399
3492 brcmf_dbg(SCAN, "enter\n"); 3400 brcmf_dbg(SCAN, "enter\n");
3493 brcmf_dev_pno_clean(ndev); 3401 brcmf_pno_clean(ifp);
3494 if (cfg->sched_escan) 3402 if (cfg->internal_escan)
3495 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true); 3403 brcmf_notify_escan_complete(cfg, ifp, true, true);
3496 return 0; 3404 return 0;
3497} 3405}
3498 3406
@@ -6428,6 +6336,7 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
6428 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; 6336 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
6429 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; 6337 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
6430 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; 6338 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6339 wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
6431 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 6340 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6432} 6341}
6433 6342
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 8889832c17e0..0c9a7081fca9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -271,7 +271,7 @@ struct brcmf_cfg80211_wowl {
271 * @pub: common driver information. 271 * @pub: common driver information.
272 * @channel: current channel. 272 * @channel: current channel.
273 * @active_scan: current scan mode. 273 * @active_scan: current scan mode.
274 * @sched_escan: e-scan for scheduled scan support running. 274 * @internal_escan: indicates internally initiated e-scan is running.
275 * @ibss_starter: indicates this sta is ibss starter. 275 * @ibss_starter: indicates this sta is ibss starter.
276 * @pwr_save: indicate whether dongle to support power save mode. 276 * @pwr_save: indicate whether dongle to support power save mode.
277 * @dongle_up: indicate whether dongle up or not. 277 * @dongle_up: indicate whether dongle up or not.
@@ -303,7 +303,7 @@ struct brcmf_cfg80211_info {
303 struct brcmf_pub *pub; 303 struct brcmf_pub *pub;
304 u32 channel; 304 u32 channel;
305 bool active_scan; 305 bool active_scan;
306 bool sched_escan; 306 bool internal_escan;
307 bool ibss_starter; 307 bool ibss_starter;
308 bool pwr_save; 308 bool pwr_save;
309 bool dongle_up; 309 bool dongle_up;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index a4118c0ef6ca..9a1eb5ab6c4b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -131,6 +131,7 @@
131#define BRCMF_TXBF_MU_BFR_CAP BIT(1) 131#define BRCMF_TXBF_MU_BFR_CAP BIT(1)
132 132
133#define BRCMF_MAXPMKID 16 /* max # PMKID cache entries */ 133#define BRCMF_MAXPMKID 16 /* max # PMKID cache entries */
134#define BRCMF_NUMCHANNELS 64
134 135
135#define BRCMF_PFN_MACADDR_CFG_VER 1 136#define BRCMF_PFN_MACADDR_CFG_VER 1
136#define BRCMF_PFN_MAC_OUI_ONLY BIT(0) 137#define BRCMF_PFN_MAC_OUI_ONLY BIT(0)
@@ -719,6 +720,21 @@ struct brcmf_pno_param_le {
719}; 720};
720 721
721/** 722/**
723 * struct brcmf_pno_config_le - PNO channel configuration.
724 *
725 * @reporttype: determines what is reported.
726 * @channel_num: number of channels specified in @channel_list.
727 * @channel_list: channels to use in PNO scan.
728 * @flags: reserved.
729 */
730struct brcmf_pno_config_le {
731 __le32 reporttype;
732 __le32 channel_num;
733 __le16 channel_list[BRCMF_NUMCHANNELS];
734 __le32 flags;
735};
736
737/**
722 * struct brcmf_pno_net_param_le - scan parameters per preferred network. 738 * struct brcmf_pno_net_param_le - scan parameters per preferred network.
723 * 739 *
724 * @ssid: ssid name and its length. 740 * @ssid: ssid name and its length.
@@ -769,6 +785,13 @@ struct brcmf_pno_scanresults_le {
769 __le32 count; 785 __le32 count;
770}; 786};
771 787
788struct brcmf_pno_scanresults_v2_le {
789 __le32 version;
790 __le32 status;
791 __le32 count;
792 __le32 scan_ch_bucket;
793};
794
772/** 795/**
773 * struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization. 796 * struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization.
774 * 797 *
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 7cc8851c071e..d2c834c3b2fc 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -87,11 +87,6 @@ struct msgbuf_common_hdr {
87 __le32 request_id; 87 __le32 request_id;
88}; 88};
89 89
90struct msgbuf_buf_addr {
91 __le32 low_addr;
92 __le32 high_addr;
93};
94
95struct msgbuf_ioctl_req_hdr { 90struct msgbuf_ioctl_req_hdr {
96 struct msgbuf_common_hdr msg; 91 struct msgbuf_common_hdr msg;
97 __le32 cmd; 92 __le32 cmd;
@@ -227,7 +222,10 @@ struct brcmf_msgbuf {
227 struct brcmf_commonring **commonrings; 222 struct brcmf_commonring **commonrings;
228 struct brcmf_commonring **flowrings; 223 struct brcmf_commonring **flowrings;
229 dma_addr_t *flowring_dma_handle; 224 dma_addr_t *flowring_dma_handle;
230 u16 nrof_flowrings; 225
226 u16 max_flowrings;
227 u16 max_submissionrings;
228 u16 max_completionrings;
231 229
232 u16 rx_dataoffset; 230 u16 rx_dataoffset;
233 u32 max_rxbufpost; 231 u32 max_rxbufpost;
@@ -610,7 +608,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
610 create->msg.request_id = 0; 608 create->msg.request_id = 0;
611 create->tid = brcmf_flowring_tid(msgbuf->flow, flowid); 609 create->tid = brcmf_flowring_tid(msgbuf->flow, flowid);
612 create->flow_ring_id = cpu_to_le16(flowid + 610 create->flow_ring_id = cpu_to_le16(flowid +
613 BRCMF_NROF_H2D_COMMON_MSGRINGS); 611 BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
614 memcpy(create->sa, work->sa, ETH_ALEN); 612 memcpy(create->sa, work->sa, ETH_ALEN);
615 memcpy(create->da, work->da, ETH_ALEN); 613 memcpy(create->da, work->da, ETH_ALEN);
616 address = (u64)msgbuf->flowring_dma_handle[flowid]; 614 address = (u64)msgbuf->flowring_dma_handle[flowid];
@@ -760,7 +758,7 @@ static void brcmf_msgbuf_txflow_worker(struct work_struct *worker)
760 u32 flowid; 758 u32 flowid;
761 759
762 msgbuf = container_of(worker, struct brcmf_msgbuf, txflow_work); 760 msgbuf = container_of(worker, struct brcmf_msgbuf, txflow_work);
763 for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->nrof_flowrings) { 761 for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->max_flowrings) {
764 clear_bit(flowid, msgbuf->flow_map); 762 clear_bit(flowid, msgbuf->flow_map);
765 brcmf_msgbuf_txflow(msgbuf, flowid); 763 brcmf_msgbuf_txflow(msgbuf, flowid);
766 } 764 }
@@ -866,7 +864,7 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
866 tx_status = (struct msgbuf_tx_status *)buf; 864 tx_status = (struct msgbuf_tx_status *)buf;
867 idx = le32_to_cpu(tx_status->msg.request_id); 865 idx = le32_to_cpu(tx_status->msg.request_id);
868 flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id); 866 flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
869 flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; 867 flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
870 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, 868 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
871 msgbuf->tx_pktids, idx); 869 msgbuf->tx_pktids, idx);
872 if (!skb) 870 if (!skb)
@@ -1174,7 +1172,7 @@ brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
1174 flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf; 1172 flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf;
1175 1173
1176 flowid = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id); 1174 flowid = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id);
1177 flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; 1175 flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
1178 status = le16_to_cpu(flowring_create_resp->compl_hdr.status); 1176 status = le16_to_cpu(flowring_create_resp->compl_hdr.status);
1179 1177
1180 if (status) { 1178 if (status) {
@@ -1202,7 +1200,7 @@ brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
1202 flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf; 1200 flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf;
1203 1201
1204 flowid = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id); 1202 flowid = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id);
1205 flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; 1203 flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
1206 status = le16_to_cpu(flowring_delete_resp->compl_hdr.status); 1204 status = le16_to_cpu(flowring_delete_resp->compl_hdr.status);
1207 1205
1208 if (status) { 1206 if (status) {
@@ -1307,7 +1305,7 @@ int brcmf_proto_msgbuf_rx_trigger(struct device *dev)
1307 brcmf_msgbuf_process_rx(msgbuf, buf); 1305 brcmf_msgbuf_process_rx(msgbuf, buf);
1308 1306
1309 for_each_set_bit(flowid, msgbuf->txstatus_done_map, 1307 for_each_set_bit(flowid, msgbuf->txstatus_done_map,
1310 msgbuf->nrof_flowrings) { 1308 msgbuf->max_flowrings) {
1311 clear_bit(flowid, msgbuf->txstatus_done_map); 1309 clear_bit(flowid, msgbuf->txstatus_done_map);
1312 commonring = msgbuf->flowrings[flowid]; 1310 commonring = msgbuf->flowrings[flowid];
1313 qlen = brcmf_flowring_qlen(msgbuf->flow, flowid); 1311 qlen = brcmf_flowring_qlen(msgbuf->flow, flowid);
@@ -1349,7 +1347,7 @@ void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
1349 delete->msg.request_id = 0; 1347 delete->msg.request_id = 0;
1350 1348
1351 delete->flow_ring_id = cpu_to_le16(flowid + 1349 delete->flow_ring_id = cpu_to_le16(flowid +
1352 BRCMF_NROF_H2D_COMMON_MSGRINGS); 1350 BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
1353 delete->reason = 0; 1351 delete->reason = 0;
1354 1352
1355 brcmf_dbg(MSGBUF, "Send Flow Delete Req flow ID %d, ifindex %d\n", 1353 brcmf_dbg(MSGBUF, "Send Flow Delete Req flow ID %d, ifindex %d\n",
@@ -1427,10 +1425,10 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1427 1425
1428 if_msgbuf = drvr->bus_if->msgbuf; 1426 if_msgbuf = drvr->bus_if->msgbuf;
1429 1427
1430 if (if_msgbuf->nrof_flowrings >= BRCMF_FLOWRING_HASHSIZE) { 1428 if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
1431 brcmf_err("driver not configured for this many flowrings %d\n", 1429 brcmf_err("driver not configured for this many flowrings %d\n",
1432 if_msgbuf->nrof_flowrings); 1430 if_msgbuf->max_flowrings);
1433 if_msgbuf->nrof_flowrings = BRCMF_FLOWRING_HASHSIZE - 1; 1431 if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
1434 } 1432 }
1435 1433
1436 msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL); 1434 msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL);
@@ -1443,7 +1441,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1443 goto fail; 1441 goto fail;
1444 } 1442 }
1445 INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker); 1443 INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker);
1446 count = BITS_TO_LONGS(if_msgbuf->nrof_flowrings); 1444 count = BITS_TO_LONGS(if_msgbuf->max_flowrings);
1447 count = count * sizeof(unsigned long); 1445 count = count * sizeof(unsigned long);
1448 msgbuf->flow_map = kzalloc(count, GFP_KERNEL); 1446 msgbuf->flow_map = kzalloc(count, GFP_KERNEL);
1449 if (!msgbuf->flow_map) 1447 if (!msgbuf->flow_map)
@@ -1479,8 +1477,8 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1479 msgbuf->commonrings = 1477 msgbuf->commonrings =
1480 (struct brcmf_commonring **)if_msgbuf->commonrings; 1478 (struct brcmf_commonring **)if_msgbuf->commonrings;
1481 msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings; 1479 msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings;
1482 msgbuf->nrof_flowrings = if_msgbuf->nrof_flowrings; 1480 msgbuf->max_flowrings = if_msgbuf->max_flowrings;
1483 msgbuf->flowring_dma_handle = kzalloc(msgbuf->nrof_flowrings * 1481 msgbuf->flowring_dma_handle = kzalloc(msgbuf->max_flowrings *
1484 sizeof(*msgbuf->flowring_dma_handle), GFP_KERNEL); 1482 sizeof(*msgbuf->flowring_dma_handle), GFP_KERNEL);
1485 if (!msgbuf->flowring_dma_handle) 1483 if (!msgbuf->flowring_dma_handle)
1486 goto fail; 1484 goto fail;
@@ -1501,7 +1499,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1501 goto fail; 1499 goto fail;
1502 1500
1503 msgbuf->flow = brcmf_flowring_attach(drvr->bus_if->dev, 1501 msgbuf->flow = brcmf_flowring_attach(drvr->bus_if->dev,
1504 if_msgbuf->nrof_flowrings); 1502 if_msgbuf->max_flowrings);
1505 if (!msgbuf->flow) 1503 if (!msgbuf->flow)
1506 goto fail; 1504 goto fail;
1507 1505
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
index ee6906a3c3f6..f93ba6be1ef8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
@@ -31,6 +31,10 @@
31#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 32 31#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 32
32#define BRCMF_H2D_TXFLOWRING_ITEMSIZE 48 32#define BRCMF_H2D_TXFLOWRING_ITEMSIZE 48
33 33
34struct msgbuf_buf_addr {
35 __le32 low_addr;
36 __le32 high_addr;
37};
34 38
35int brcmf_proto_msgbuf_rx_trigger(struct device *dev); 39int brcmf_proto_msgbuf_rx_trigger(struct device *dev);
36void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid); 40void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index 3deba90c7eb5..048027f2085b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -135,7 +135,7 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
135 BRCMF_PCIE_MB_INT_D2H3_DB1) 135 BRCMF_PCIE_MB_INT_D2H3_DB1)
136 136
137#define BRCMF_PCIE_MIN_SHARED_VERSION 5 137#define BRCMF_PCIE_MIN_SHARED_VERSION 5
138#define BRCMF_PCIE_MAX_SHARED_VERSION 5 138#define BRCMF_PCIE_MAX_SHARED_VERSION 6
139#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF 139#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF
140#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000 140#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000
141#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000 141#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000
@@ -166,17 +166,6 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
166#define BRCMF_RING_MEM_SZ 16 166#define BRCMF_RING_MEM_SZ 16
167#define BRCMF_RING_STATE_SZ 8 167#define BRCMF_RING_STATE_SZ 8
168 168
169#define BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET 4
170#define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET 8
171#define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET 12
172#define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET 16
173#define BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET 20
174#define BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET 28
175#define BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET 36
176#define BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET 44
177#define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET 0
178#define BRCMF_SHARED_RING_MAX_SUB_QUEUES 52
179
180#define BRCMF_DEF_MAX_RXBUFPOST 255 169#define BRCMF_DEF_MAX_RXBUFPOST 255
181 170
182#define BRCMF_CONSOLE_BUFADDR_OFFSET 8 171#define BRCMF_CONSOLE_BUFADDR_OFFSET 8
@@ -231,7 +220,9 @@ struct brcmf_pcie_shared_info {
231 struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS]; 220 struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
232 struct brcmf_pcie_ringbuf *flowrings; 221 struct brcmf_pcie_ringbuf *flowrings;
233 u16 max_rxbufpost; 222 u16 max_rxbufpost;
234 u32 nrof_flowrings; 223 u16 max_flowrings;
224 u16 max_submissionrings;
225 u16 max_completionrings;
235 u32 rx_dataoffset; 226 u32 rx_dataoffset;
236 u32 htod_mb_data_addr; 227 u32 htod_mb_data_addr;
237 u32 dtoh_mb_data_addr; 228 u32 dtoh_mb_data_addr;
@@ -241,6 +232,7 @@ struct brcmf_pcie_shared_info {
241 dma_addr_t scratch_dmahandle; 232 dma_addr_t scratch_dmahandle;
242 void *ringupd; 233 void *ringupd;
243 dma_addr_t ringupd_dmahandle; 234 dma_addr_t ringupd_dmahandle;
235 u8 version;
244}; 236};
245 237
246struct brcmf_pcie_core_info { 238struct brcmf_pcie_core_info {
@@ -284,6 +276,36 @@ struct brcmf_pcie_ringbuf {
284 u8 id; 276 u8 id;
285}; 277};
286 278
279/**
280 * struct brcmf_pcie_dhi_ringinfo - dongle/host interface shared ring info
281 *
282 * @ringmem: dongle memory pointer to ring memory location
283 * @h2d_w_idx_ptr: h2d ring write indices dongle memory pointers
284 * @h2d_r_idx_ptr: h2d ring read indices dongle memory pointers
285 * @d2h_w_idx_ptr: d2h ring write indices dongle memory pointers
286 * @d2h_r_idx_ptr: d2h ring read indices dongle memory pointers
287 * @h2d_w_idx_hostaddr: h2d ring write indices host memory pointers
288 * @h2d_r_idx_hostaddr: h2d ring read indices host memory pointers
289 * @d2h_w_idx_hostaddr: d2h ring write indices host memory pointers
290 * @d2h_r_idx_hostaddr: d2h ring reaD indices host memory pointers
291 * @max_flowrings: maximum number of tx flow rings supported.
292 * @max_submissionrings: maximum number of submission rings(h2d) supported.
293 * @max_completionrings: maximum number of completion rings(d2h) supported.
294 */
295struct brcmf_pcie_dhi_ringinfo {
296 __le32 ringmem;
297 __le32 h2d_w_idx_ptr;
298 __le32 h2d_r_idx_ptr;
299 __le32 d2h_w_idx_ptr;
300 __le32 d2h_r_idx_ptr;
301 struct msgbuf_buf_addr h2d_w_idx_hostaddr;
302 struct msgbuf_buf_addr h2d_r_idx_hostaddr;
303 struct msgbuf_buf_addr d2h_w_idx_hostaddr;
304 struct msgbuf_buf_addr d2h_r_idx_hostaddr;
305 __le16 max_flowrings;
306 __le16 max_submissionrings;
307 __le16 max_completionrings;
308};
287 309
288static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = { 310static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = {
289 BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM, 311 BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM,
@@ -1054,26 +1076,35 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
1054{ 1076{
1055 struct brcmf_pcie_ringbuf *ring; 1077 struct brcmf_pcie_ringbuf *ring;
1056 struct brcmf_pcie_ringbuf *rings; 1078 struct brcmf_pcie_ringbuf *rings;
1057 u32 ring_addr;
1058 u32 d2h_w_idx_ptr; 1079 u32 d2h_w_idx_ptr;
1059 u32 d2h_r_idx_ptr; 1080 u32 d2h_r_idx_ptr;
1060 u32 h2d_w_idx_ptr; 1081 u32 h2d_w_idx_ptr;
1061 u32 h2d_r_idx_ptr; 1082 u32 h2d_r_idx_ptr;
1062 u32 addr;
1063 u32 ring_mem_ptr; 1083 u32 ring_mem_ptr;
1064 u32 i; 1084 u32 i;
1065 u64 address; 1085 u64 address;
1066 u32 bufsz; 1086 u32 bufsz;
1067 u16 max_sub_queues;
1068 u8 idx_offset; 1087 u8 idx_offset;
1069 1088 struct brcmf_pcie_dhi_ringinfo ringinfo;
1070 ring_addr = devinfo->shared.ring_info_addr; 1089 u16 max_flowrings;
1071 brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr); 1090 u16 max_submissionrings;
1072 addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES; 1091 u16 max_completionrings;
1073 max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr); 1092
1093 memcpy_fromio(&ringinfo, devinfo->tcm + devinfo->shared.ring_info_addr,
1094 sizeof(ringinfo));
1095 if (devinfo->shared.version >= 6) {
1096 max_submissionrings = le16_to_cpu(ringinfo.max_submissionrings);
1097 max_flowrings = le16_to_cpu(ringinfo.max_flowrings);
1098 max_completionrings = le16_to_cpu(ringinfo.max_completionrings);
1099 } else {
1100 max_submissionrings = le16_to_cpu(ringinfo.max_flowrings);
1101 max_flowrings = max_submissionrings -
1102 BRCMF_NROF_H2D_COMMON_MSGRINGS;
1103 max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
1104 }
1074 1105
1075 if (devinfo->dma_idx_sz != 0) { 1106 if (devinfo->dma_idx_sz != 0) {
1076 bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) * 1107 bufsz = (max_submissionrings + max_completionrings) *
1077 devinfo->dma_idx_sz * 2; 1108 devinfo->dma_idx_sz * 2;
1078 devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz, 1109 devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz,
1079 &devinfo->idxbuf_dmahandle, 1110 &devinfo->idxbuf_dmahandle,
@@ -1083,14 +1114,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
1083 } 1114 }
1084 1115
1085 if (devinfo->dma_idx_sz == 0) { 1116 if (devinfo->dma_idx_sz == 0) {
1086 addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET; 1117 d2h_w_idx_ptr = le32_to_cpu(ringinfo.d2h_w_idx_ptr);
1087 d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); 1118 d2h_r_idx_ptr = le32_to_cpu(ringinfo.d2h_r_idx_ptr);
1088 addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET; 1119 h2d_w_idx_ptr = le32_to_cpu(ringinfo.h2d_w_idx_ptr);
1089 d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr); 1120 h2d_r_idx_ptr = le32_to_cpu(ringinfo.h2d_r_idx_ptr);
1090 addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET;
1091 h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
1092 addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET;
1093 h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
1094 idx_offset = sizeof(u32); 1121 idx_offset = sizeof(u32);
1095 devinfo->write_ptr = brcmf_pcie_write_tcm16; 1122 devinfo->write_ptr = brcmf_pcie_write_tcm16;
1096 devinfo->read_ptr = brcmf_pcie_read_tcm16; 1123 devinfo->read_ptr = brcmf_pcie_read_tcm16;
@@ -1103,34 +1130,42 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
1103 devinfo->read_ptr = brcmf_pcie_read_idx; 1130 devinfo->read_ptr = brcmf_pcie_read_idx;
1104 1131
1105 h2d_w_idx_ptr = 0; 1132 h2d_w_idx_ptr = 0;
1106 addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET;
1107 address = (u64)devinfo->idxbuf_dmahandle; 1133 address = (u64)devinfo->idxbuf_dmahandle;
1108 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); 1134 ringinfo.h2d_w_idx_hostaddr.low_addr =
1109 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); 1135 cpu_to_le32(address & 0xffffffff);
1110 1136 ringinfo.h2d_w_idx_hostaddr.high_addr =
1111 h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset; 1137 cpu_to_le32(address >> 32);
1112 addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET; 1138
1113 address += max_sub_queues * idx_offset; 1139 h2d_r_idx_ptr = h2d_w_idx_ptr +
1114 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); 1140 max_submissionrings * idx_offset;
1115 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); 1141 address += max_submissionrings * idx_offset;
1116 1142 ringinfo.h2d_r_idx_hostaddr.low_addr =
1117 d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset; 1143 cpu_to_le32(address & 0xffffffff);
1118 addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET; 1144 ringinfo.h2d_r_idx_hostaddr.high_addr =
1119 address += max_sub_queues * idx_offset; 1145 cpu_to_le32(address >> 32);
1120 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); 1146
1121 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); 1147 d2h_w_idx_ptr = h2d_r_idx_ptr +
1148 max_submissionrings * idx_offset;
1149 address += max_submissionrings * idx_offset;
1150 ringinfo.d2h_w_idx_hostaddr.low_addr =
1151 cpu_to_le32(address & 0xffffffff);
1152 ringinfo.d2h_w_idx_hostaddr.high_addr =
1153 cpu_to_le32(address >> 32);
1122 1154
1123 d2h_r_idx_ptr = d2h_w_idx_ptr + 1155 d2h_r_idx_ptr = d2h_w_idx_ptr +
1124 BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; 1156 max_completionrings * idx_offset;
1125 addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET; 1157 address += max_completionrings * idx_offset;
1126 address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset; 1158 ringinfo.d2h_r_idx_hostaddr.low_addr =
1127 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); 1159 cpu_to_le32(address & 0xffffffff);
1128 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); 1160 ringinfo.d2h_r_idx_hostaddr.high_addr =
1161 cpu_to_le32(address >> 32);
1162
1163 memcpy_toio(devinfo->tcm + devinfo->shared.ring_info_addr,
1164 &ringinfo, sizeof(ringinfo));
1129 brcmf_dbg(PCIE, "Using host memory indices\n"); 1165 brcmf_dbg(PCIE, "Using host memory indices\n");
1130 } 1166 }
1131 1167
1132 addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET; 1168 ring_mem_ptr = le32_to_cpu(ringinfo.ringmem);
1133 ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
1134 1169
1135 for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) { 1170 for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) {
1136 ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr); 1171 ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr);
@@ -1161,20 +1196,19 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
1161 ring_mem_ptr += BRCMF_RING_MEM_SZ; 1196 ring_mem_ptr += BRCMF_RING_MEM_SZ;
1162 } 1197 }
1163 1198
1164 devinfo->shared.nrof_flowrings = 1199 devinfo->shared.max_flowrings = max_flowrings;
1165 max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS; 1200 devinfo->shared.max_submissionrings = max_submissionrings;
1166 rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring), 1201 devinfo->shared.max_completionrings = max_completionrings;
1167 GFP_KERNEL); 1202 rings = kcalloc(max_flowrings, sizeof(*ring), GFP_KERNEL);
1168 if (!rings) 1203 if (!rings)
1169 goto fail; 1204 goto fail;
1170 1205
1171 brcmf_dbg(PCIE, "Nr of flowrings is %d\n", 1206 brcmf_dbg(PCIE, "Nr of flowrings is %d\n", max_flowrings);
1172 devinfo->shared.nrof_flowrings);
1173 1207
1174 for (i = 0; i < devinfo->shared.nrof_flowrings; i++) { 1208 for (i = 0; i < max_flowrings; i++) {
1175 ring = &rings[i]; 1209 ring = &rings[i];
1176 ring->devinfo = devinfo; 1210 ring->devinfo = devinfo;
1177 ring->id = i + BRCMF_NROF_COMMON_MSGRINGS; 1211 ring->id = i + BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
1178 brcmf_commonring_register_cb(&ring->commonring, 1212 brcmf_commonring_register_cb(&ring->commonring,
1179 brcmf_pcie_ring_mb_ring_bell, 1213 brcmf_pcie_ring_mb_ring_bell,
1180 brcmf_pcie_ring_mb_update_rptr, 1214 brcmf_pcie_ring_mb_update_rptr,
@@ -1357,17 +1391,16 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
1357{ 1391{
1358 struct brcmf_pcie_shared_info *shared; 1392 struct brcmf_pcie_shared_info *shared;
1359 u32 addr; 1393 u32 addr;
1360 u32 version;
1361 1394
1362 shared = &devinfo->shared; 1395 shared = &devinfo->shared;
1363 shared->tcm_base_address = sharedram_addr; 1396 shared->tcm_base_address = sharedram_addr;
1364 1397
1365 shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr); 1398 shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr);
1366 version = shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK; 1399 shared->version = (u8)(shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK);
1367 brcmf_dbg(PCIE, "PCIe protocol version %d\n", version); 1400 brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version);
1368 if ((version > BRCMF_PCIE_MAX_SHARED_VERSION) || 1401 if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
1369 (version < BRCMF_PCIE_MIN_SHARED_VERSION)) { 1402 (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
1370 brcmf_err("Unsupported PCIE version %d\n", version); 1403 brcmf_err("Unsupported PCIE version %d\n", shared->version);
1371 return -EINVAL; 1404 return -EINVAL;
1372 } 1405 }
1373 1406
@@ -1661,18 +1694,18 @@ static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
1661 bus->msgbuf->commonrings[i] = 1694 bus->msgbuf->commonrings[i] =
1662 &devinfo->shared.commonrings[i]->commonring; 1695 &devinfo->shared.commonrings[i]->commonring;
1663 1696
1664 flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings), 1697 flowrings = kcalloc(devinfo->shared.max_flowrings, sizeof(*flowrings),
1665 GFP_KERNEL); 1698 GFP_KERNEL);
1666 if (!flowrings) 1699 if (!flowrings)
1667 goto fail; 1700 goto fail;
1668 1701
1669 for (i = 0; i < devinfo->shared.nrof_flowrings; i++) 1702 for (i = 0; i < devinfo->shared.max_flowrings; i++)
1670 flowrings[i] = &devinfo->shared.flowrings[i].commonring; 1703 flowrings[i] = &devinfo->shared.flowrings[i].commonring;
1671 bus->msgbuf->flowrings = flowrings; 1704 bus->msgbuf->flowrings = flowrings;
1672 1705
1673 bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset; 1706 bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset;
1674 bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost; 1707 bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost;
1675 bus->msgbuf->nrof_flowrings = devinfo->shared.nrof_flowrings; 1708 bus->msgbuf->max_flowrings = devinfo->shared.max_flowrings;
1676 1709
1677 init_waitqueue_head(&devinfo->mbdata_resp_wait); 1710 init_waitqueue_head(&devinfo->mbdata_resp_wait);
1678 1711
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
new file mode 100644
index 000000000000..f273cab0da10
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -0,0 +1,242 @@
1/*
2 * Copyright (c) 2016 Broadcom
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#include <linux/netdevice.h>
17#include <net/cfg80211.h>
18
19#include "core.h"
20#include "debug.h"
21#include "fwil.h"
22#include "fwil_types.h"
23#include "cfg80211.h"
24#include "pno.h"
25
26#define BRCMF_PNO_VERSION 2
27#define BRCMF_PNO_REPEAT 4
28#define BRCMF_PNO_FREQ_EXPO_MAX 3
29#define BRCMF_PNO_IMMEDIATE_SCAN_BIT 3
30#define BRCMF_PNO_ENABLE_BD_SCAN_BIT 5
31#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
32#define BRCMF_PNO_REPORT_SEPARATELY_BIT 11
33#define BRCMF_PNO_SCAN_INCOMPLETE 0
34#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
35#define BRCMF_PNO_HIDDEN_BIT 2
36#define BRCMF_PNO_SCHED_SCAN_PERIOD 30
37
38static int brcmf_pno_channel_config(struct brcmf_if *ifp,
39 struct brcmf_pno_config_le *cfg)
40{
41 cfg->reporttype = 0;
42 cfg->flags = 0;
43
44 return brcmf_fil_iovar_data_set(ifp, "pfn_cfg", cfg, sizeof(*cfg));
45}
46
47static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
48 u32 mscan, u32 bestn)
49{
50 struct brcmf_pno_param_le pfn_param;
51 u16 flags;
52 u32 pfnmem;
53 s32 err;
54
55 memset(&pfn_param, 0, sizeof(pfn_param));
56 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
57
58 /* set extra pno params */
59 flags = BIT(BRCMF_PNO_IMMEDIATE_SCAN_BIT) |
60 BIT(BRCMF_PNO_REPORT_SEPARATELY_BIT) |
61 BIT(BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
62 pfn_param.repeat = BRCMF_PNO_REPEAT;
63 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
64
65 /* set up pno scan fr */
66 if (scan_freq < BRCMF_PNO_SCHED_SCAN_MIN_PERIOD) {
67 brcmf_dbg(SCAN, "scan period too small, using minimum\n");
68 scan_freq = BRCMF_PNO_SCHED_SCAN_MIN_PERIOD;
69 }
70 pfn_param.scan_freq = cpu_to_le32(scan_freq);
71
72 if (mscan) {
73 pfnmem = bestn;
74
75 /* set bestn in firmware */
76 err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem);
77 if (err < 0) {
78 brcmf_err("failed to set pfnmem\n");
79 goto exit;
80 }
81 /* get max mscan which the firmware supports */
82 err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem);
83 if (err < 0) {
84 brcmf_err("failed to get pfnmem\n");
85 goto exit;
86 }
87 mscan = min_t(u32, mscan, pfnmem);
88 pfn_param.mscan = mscan;
89 pfn_param.bestn = bestn;
90 flags |= BIT(BRCMF_PNO_ENABLE_BD_SCAN_BIT);
91 brcmf_dbg(INFO, "mscan=%d, bestn=%d\n", mscan, bestn);
92 }
93
94 pfn_param.flags = cpu_to_le16(flags);
95 err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
96 sizeof(pfn_param));
97 if (err)
98 brcmf_err("pfn_set failed, err=%d\n", err);
99
100exit:
101 return err;
102}
103
104static int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr,
105 u8 *mac_mask)
106{
107 struct brcmf_pno_macaddr_le pfn_mac;
108 int err, i;
109
110 pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
111 pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
112
113 memcpy(pfn_mac.mac, mac_addr, ETH_ALEN);
114 for (i = 0; i < ETH_ALEN; i++) {
115 pfn_mac.mac[i] &= mac_mask[i];
116 pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
117 }
118 /* Clear multi bit */
119 pfn_mac.mac[0] &= 0xFE;
120 /* Set locally administered */
121 pfn_mac.mac[0] |= 0x02;
122
123 err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
124 sizeof(pfn_mac));
125 if (err)
126 brcmf_err("pfn_macaddr failed, err=%d\n", err);
127
128 return err;
129}
130
131static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
132 bool active)
133{
134 struct brcmf_pno_net_param_le pfn;
135
136 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
137 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
138 pfn.wsec = cpu_to_le32(0);
139 pfn.infra = cpu_to_le32(1);
140 if (active)
141 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
142 pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len);
143 memcpy(pfn.ssid.SSID, ssid->ssid, ssid->ssid_len);
144 return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
145}
146
147static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
148 struct cfg80211_sched_scan_request *req)
149{
150 int i;
151
152 if (!ssid || !req->ssids || !req->n_ssids)
153 return false;
154
155 for (i = 0; i < req->n_ssids; i++) {
156 if (ssid->ssid_len == req->ssids[i].ssid_len) {
157 if (!strncmp(ssid->ssid, req->ssids[i].ssid,
158 ssid->ssid_len))
159 return true;
160 }
161 }
162 return false;
163}
164
165int brcmf_pno_clean(struct brcmf_if *ifp)
166{
167 int ret;
168
169 /* Disable pfn */
170 ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0);
171 if (ret == 0) {
172 /* clear pfn */
173 ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0);
174 }
175 if (ret < 0)
176 brcmf_err("failed code %d\n", ret);
177
178 return ret;
179}
180
181int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
182 struct cfg80211_sched_scan_request *req)
183{
184 struct brcmu_d11inf *d11inf;
185 struct brcmf_pno_config_le pno_cfg;
186 struct cfg80211_ssid *ssid;
187 u16 chan;
188 int i, ret;
189
190 /* clean up everything */
191 ret = brcmf_pno_clean(ifp);
192 if (ret < 0) {
193 brcmf_err("failed error=%d\n", ret);
194 return ret;
195 }
196
197 /* configure pno */
198 ret = brcmf_pno_config(ifp, req->scan_plans[0].interval, 0, 0);
199 if (ret < 0)
200 return ret;
201
202 /* configure random mac */
203 if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
204 ret = brcmf_pno_set_random(ifp, req->mac_addr,
205 req->mac_addr_mask);
206 if (ret < 0)
207 return ret;
208 }
209
210 /* configure channels to use */
211 d11inf = &ifp->drvr->config->d11inf;
212 for (i = 0; i < req->n_channels; i++) {
213 chan = req->channels[i]->hw_value;
214 pno_cfg.channel_list[i] = cpu_to_le16(chan);
215 }
216 if (req->n_channels) {
217 pno_cfg.channel_num = cpu_to_le32(req->n_channels);
218 brcmf_pno_channel_config(ifp, &pno_cfg);
219 }
220
221 /* configure each match set */
222 for (i = 0; i < req->n_match_sets; i++) {
223 ssid = &req->match_sets[i].ssid;
224 if (!ssid->ssid_len) {
225 brcmf_err("skip broadcast ssid\n");
226 continue;
227 }
228
229 ret = brcmf_pno_add_ssid(ifp, ssid,
230 brcmf_is_ssid_active(ssid, req));
231 if (ret < 0)
232 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
233 ret == 0 ? "set" : "failed", ssid->ssid);
234 }
235 /* Enable the PNO */
236 ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1);
237 if (ret < 0)
238 brcmf_err("PNO enable failed!! ret=%d\n", ret);
239
240 return ret;
241}
242
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
new file mode 100644
index 000000000000..bae55b2af78c
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 2016 Broadcom
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef _BRCMF_PNO_H
17#define _BRCMF_PNO_H
18
19#define BRCMF_PNO_SCAN_COMPLETE 1
20#define BRCMF_PNO_MAX_PFN_COUNT 16
21#define BRCMF_PNO_SCHED_SCAN_MIN_PERIOD 10
22#define BRCMF_PNO_SCHED_SCAN_MAX_PERIOD 508
23
24/**
25 * brcmf_pno_clean - disable and clear pno in firmware.
26 *
27 * @ifp: interface object used.
28 */
29int brcmf_pno_clean(struct brcmf_if *ifp);
30
31/**
32 * brcmf_pno_start_sched_scan - initiate scheduled scan on device.
33 *
34 * @ifp: interface object used.
35 * @req: configuration parameters for scheduled scan.
36 */
37int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
38 struct cfg80211_sched_scan_request *req);
39
40#endif /* _BRCMF_PNO_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index b892dac70f4b..dfb0658713d9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -621,6 +621,7 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
621 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), 621 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330),
622 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), 622 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334),
623 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), 623 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340),
624 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340),
624 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), 625 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335),
625 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), 626 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
626 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), 627 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c
index faf1ebe76068..b9672da24a9d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c
@@ -179,7 +179,7 @@ s16 qm_norm32(s32 op)
179 return u16extraSignBits; 179 return u16extraSignBits;
180} 180}
181 181
182/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */ 182/* This table is log2(1+(i/32)) where i=[0:1:32], in q.15 format */
183static const s16 log_table[] = { 183static const s16 log_table[] = {
184 0, 184 0,
185 1455, 185 1455,
@@ -212,7 +212,8 @@ static const s16 log_table[] = {
212 29717, 212 29717,
213 30498, 213 30498,
214 31267, 214 31267,
215 32024 215 32024,
216 32768
216}; 217};
217 218
218#define LOG_TABLE_SIZE 32 /* log_table size */ 219#define LOG_TABLE_SIZE 32 /* log_table size */
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
index d0407d9ad782..f1fb8a3c7a32 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -36,6 +36,7 @@
36#define BRCM_CC_4330_CHIP_ID 0x4330 36#define BRCM_CC_4330_CHIP_ID 0x4330
37#define BRCM_CC_4334_CHIP_ID 0x4334 37#define BRCM_CC_4334_CHIP_ID 0x4334
38#define BRCM_CC_43340_CHIP_ID 43340 38#define BRCM_CC_43340_CHIP_ID 43340
39#define BRCM_CC_43341_CHIP_ID 43341
39#define BRCM_CC_43362_CHIP_ID 43362 40#define BRCM_CC_43362_CHIP_ID 43362
40#define BRCM_CC_4335_CHIP_ID 0x4335 41#define BRCM_CC_4335_CHIP_ID 0x4335
41#define BRCM_CC_4339_CHIP_ID 0x4339 42#define BRCM_CC_4339_CHIP_ID 0x4339
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index c26469a5a5f3..a7d359e9f378 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2143,6 +2143,16 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len,
2143 ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1); 2143 ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
2144 2144
2145 if (mode == NL80211_IFTYPE_ADHOC) { 2145 if (mode == NL80211_IFTYPE_ADHOC) {
2146 u16 enable = true;
2147
2148 /* set ibss coalescing_status */
2149 ret = mwifiex_send_cmd(
2150 priv,
2151 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
2152 HostCmd_ACT_GEN_SET, 0, &enable, true);
2153 if (ret)
2154 return ret;
2155
2146 /* "privacy" is set only for ad-hoc mode */ 2156 /* "privacy" is set only for ad-hoc mode */
2147 if (privacy) { 2157 if (privacy) {
2148 /* 2158 /*
@@ -3980,13 +3990,11 @@ static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
3980 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 3990 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
3981 struct mwifiex_ds_misc_cmd *hostcmd; 3991 struct mwifiex_ds_misc_cmd *hostcmd;
3982 struct nlattr *tb[MWIFIEX_TM_ATTR_MAX + 1]; 3992 struct nlattr *tb[MWIFIEX_TM_ATTR_MAX + 1];
3983 struct mwifiex_adapter *adapter;
3984 struct sk_buff *skb; 3993 struct sk_buff *skb;
3985 int err; 3994 int err;
3986 3995
3987 if (!priv) 3996 if (!priv)
3988 return -EINVAL; 3997 return -EINVAL;
3989 adapter = priv->adapter;
3990 3998
3991 err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len, 3999 err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len,
3992 mwifiex_tm_policy); 4000 mwifiex_tm_policy);
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 9b3cceadd707..ea455948a68a 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -219,6 +219,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
219#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14)) 219#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14))
220#define ISSUPP_DRCS_ENABLED(FwCapInfo) (FwCapInfo & BIT(15)) 220#define ISSUPP_DRCS_ENABLED(FwCapInfo) (FwCapInfo & BIT(15))
221#define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16)) 221#define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16))
222#define ISSUPP_ADHOC_ENABLED(FwCapInfo) (FwCapInfo & BIT(25))
222 223
223#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ 224#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
224 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \ 225 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
index eac44fe9c416..e5c3a8aa3929 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -518,7 +518,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
518{ 518{
519 int ret; 519 int ret;
520 char fmt[64]; 520 char fmt[64];
521 struct mwifiex_private *priv;
522 struct mwifiex_adapter *adapter = context; 521 struct mwifiex_adapter *adapter = context;
523 struct mwifiex_fw_image fw; 522 struct mwifiex_fw_image fw;
524 bool init_failed = false; 523 bool init_failed = false;
@@ -576,8 +575,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
576 goto err_init_fw; 575 goto err_init_fw;
577 } 576 }
578 577
579 priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
580
581 if (!adapter->wiphy) { 578 if (!adapter->wiphy) {
582 if (mwifiex_register_cfg80211(adapter)) { 579 if (mwifiex_register_cfg80211(adapter)) {
583 mwifiex_dbg(adapter, ERROR, 580 mwifiex_dbg(adapter, ERROR,
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index cf4c78080d94..5c9bd944b6ea 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -1424,8 +1424,13 @@ static inline void mwifiex_disable_wake(struct mwifiex_adapter *adapter)
1424{ 1424{
1425 if (adapter->irq_wakeup >= 0) { 1425 if (adapter->irq_wakeup >= 0) {
1426 disable_irq_wake(adapter->irq_wakeup); 1426 disable_irq_wake(adapter->irq_wakeup);
1427 if (!adapter->wake_by_wifi) 1427 disable_irq(adapter->irq_wakeup);
1428 disable_irq(adapter->irq_wakeup); 1428 if (adapter->wake_by_wifi)
1429 /* Undo our disable, since interrupt handler already
1430 * did this.
1431 */
1432 enable_irq(adapter->irq_wakeup);
1433
1429 } 1434 }
1430} 1435}
1431 1436
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 4b89f557d0b6..4db07da81d8d 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -135,6 +135,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
135 mwifiex_dbg(adapter, ERROR, 135 mwifiex_dbg(adapter, ERROR,
136 "cmd: failed to suspend\n"); 136 "cmd: failed to suspend\n");
137 adapter->hs_enabling = false; 137 adapter->hs_enabling = false;
138 mwifiex_disable_wake(adapter);
138 return -EFAULT; 139 return -EFAULT;
139 } 140 }
140 141
@@ -2050,7 +2051,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
2050 } 2051 }
2051 2052
2052 /* Wait for the command done interrupt */ 2053 /* Wait for the command done interrupt */
2053 do { 2054 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2054 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, 2055 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
2055 &ireg_intr)) { 2056 &ireg_intr)) {
2056 mwifiex_dbg(adapter, ERROR, 2057 mwifiex_dbg(adapter, ERROR,
@@ -2062,8 +2063,18 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
2062 ret = -1; 2063 ret = -1;
2063 goto done; 2064 goto done;
2064 } 2065 }
2065 } while ((ireg_intr & CPU_INTR_DOOR_BELL) == 2066 if (!(ireg_intr & CPU_INTR_DOOR_BELL))
2066 CPU_INTR_DOOR_BELL); 2067 break;
2068 usleep_range(10, 20);
2069 }
2070 if (ireg_intr & CPU_INTR_DOOR_BELL) {
2071 mwifiex_dbg(adapter, ERROR, "%s: Card failed to ACK download\n",
2072 __func__);
2073 mwifiex_unmap_pci_memory(adapter, skb,
2074 PCI_DMA_TODEVICE);
2075 ret = -1;
2076 goto done;
2077 }
2067 2078
2068 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); 2079 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
2069 2080
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 98ce07280ae8..181691684a08 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -827,7 +827,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
827 u32 num_probes; 827 u32 num_probes;
828 u32 ssid_len; 828 u32 ssid_len;
829 u32 chan_idx; 829 u32 chan_idx;
830 u32 chan_num;
831 u32 scan_type; 830 u32 scan_type;
832 u16 scan_dur; 831 u16 scan_dur;
833 u8 channel; 832 u8 channel;
@@ -1105,13 +1104,12 @@ mwifiex_config_scan(struct mwifiex_private *priv,
1105 mwifiex_dbg(adapter, INFO, 1104 mwifiex_dbg(adapter, INFO,
1106 "info: Scan: Scanning current channel only\n"); 1105 "info: Scan: Scanning current channel only\n");
1107 } 1106 }
1108 chan_num = chan_idx;
1109 } else { 1107 } else {
1110 mwifiex_dbg(adapter, INFO, 1108 mwifiex_dbg(adapter, INFO,
1111 "info: Scan: Creating full region channel list\n"); 1109 "info: Scan: Creating full region channel list\n");
1112 chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in, 1110 mwifiex_scan_create_channel_list(priv, user_scan_in,
1113 scan_chan_list, 1111 scan_chan_list,
1114 *filtered_scan); 1112 *filtered_scan);
1115 } 1113 }
1116 1114
1117} 1115}
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index 0d00db5142e6..740d79cd91fa 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -186,9 +186,7 @@ static int mwifiex_sdio_resume(struct device *dev)
186 struct sdio_func *func = dev_to_sdio_func(dev); 186 struct sdio_func *func = dev_to_sdio_func(dev);
187 struct sdio_mmc_card *card; 187 struct sdio_mmc_card *card;
188 struct mwifiex_adapter *adapter; 188 struct mwifiex_adapter *adapter;
189 mmc_pm_flag_t pm_flag = 0;
190 189
191 pm_flag = sdio_get_host_pm_caps(func);
192 card = sdio_get_drvdata(func); 190 card = sdio_get_drvdata(func);
193 if (!card || !card->adapter) { 191 if (!card || !card->adapter) {
194 dev_err(dev, "resume: invalid card or adapter\n"); 192 dev_err(dev, "resume: invalid card or adapter\n");
@@ -298,6 +296,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
298 mwifiex_dbg(adapter, ERROR, 296 mwifiex_dbg(adapter, ERROR,
299 "cmd: failed to suspend\n"); 297 "cmd: failed to suspend\n");
300 adapter->hs_enabling = false; 298 adapter->hs_enabling = false;
299 mwifiex_disable_wake(adapter);
301 return -EFAULT; 300 return -EFAULT;
302 } 301 }
303 302
@@ -1136,7 +1135,6 @@ static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter,
1136{ 1135{
1137 u32 total_pkt_len, pkt_len; 1136 u32 total_pkt_len, pkt_len;
1138 struct sk_buff *skb_deaggr; 1137 struct sk_buff *skb_deaggr;
1139 u32 pkt_type;
1140 u16 blk_size; 1138 u16 blk_size;
1141 u8 blk_num; 1139 u8 blk_num;
1142 u8 *data; 1140 u8 *data;
@@ -1157,8 +1155,6 @@ static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter,
1157 break; 1155 break;
1158 } 1156 }
1159 pkt_len = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET)); 1157 pkt_len = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET));
1160 pkt_type = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET +
1161 2));
1162 if ((pkt_len + SDIO_HEADER_OFFSET) > blk_size) { 1158 if ((pkt_len + SDIO_HEADER_OFFSET) > blk_size) {
1163 mwifiex_dbg(adapter, ERROR, 1159 mwifiex_dbg(adapter, ERROR,
1164 "%s: error in pkt_len,\t" 1160 "%s: error in pkt_len,\t"
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index bcd64081d4a8..125e448712dd 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -1746,7 +1746,6 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1746{ 1746{
1747 struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper; 1747 struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper;
1748 struct mwifiex_ds_tdls_oper *oper = data_buf; 1748 struct mwifiex_ds_tdls_oper *oper = data_buf;
1749 struct mwifiex_sta_node *sta_ptr;
1750 struct host_cmd_tlv_rates *tlv_rates; 1749 struct host_cmd_tlv_rates *tlv_rates;
1751 struct mwifiex_ie_types_htcap *ht_capab; 1750 struct mwifiex_ie_types_htcap *ht_capab;
1752 struct mwifiex_ie_types_qos_info *wmm_qos_info; 1751 struct mwifiex_ie_types_qos_info *wmm_qos_info;
@@ -1764,7 +1763,6 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1764 1763
1765 tdls_oper->reason = 0; 1764 tdls_oper->reason = 0;
1766 memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN); 1765 memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN);
1767 sta_ptr = mwifiex_get_sta_entry(priv, oper->peer_mac);
1768 1766
1769 pos = (u8 *)tdls_oper + sizeof(struct host_cmd_ds_tdls_oper); 1767 pos = (u8 *)tdls_oper + sizeof(struct host_cmd_ds_tdls_oper);
1770 1768
@@ -1902,6 +1900,24 @@ static int mwifiex_cmd_get_wakeup_reason(struct mwifiex_private *priv,
1902 return 0; 1900 return 0;
1903} 1901}
1904 1902
1903/* This function check if the command is supported by firmware */
1904static int mwifiex_is_cmd_supported(struct mwifiex_private *priv, u16 cmd_no)
1905{
1906 if (!ISSUPP_ADHOC_ENABLED(priv->adapter->fw_cap_info)) {
1907 switch (cmd_no) {
1908 case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
1909 case HostCmd_CMD_802_11_AD_HOC_START:
1910 case HostCmd_CMD_802_11_AD_HOC_JOIN:
1911 case HostCmd_CMD_802_11_AD_HOC_STOP:
1912 return -EOPNOTSUPP;
1913 default:
1914 break;
1915 }
1916 }
1917
1918 return 0;
1919}
1920
1905/* 1921/*
1906 * This function prepares the commands before sending them to the firmware. 1922 * This function prepares the commands before sending them to the firmware.
1907 * 1923 *
@@ -1915,6 +1931,13 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1915 struct host_cmd_ds_command *cmd_ptr = cmd_buf; 1931 struct host_cmd_ds_command *cmd_ptr = cmd_buf;
1916 int ret = 0; 1932 int ret = 0;
1917 1933
1934 if (mwifiex_is_cmd_supported(priv, cmd_no)) {
1935 mwifiex_dbg(priv->adapter, ERROR,
1936 "0x%x command not supported by firmware\n",
1937 cmd_no);
1938 return -EOPNOTSUPP;
1939 }
1940
1918 /* Prepare command */ 1941 /* Prepare command */
1919 switch (cmd_no) { 1942 switch (cmd_no) {
1920 case HostCmd_CMD_GET_HW_SPEC: 1943 case HostCmd_CMD_GET_HW_SPEC:
@@ -2208,7 +2231,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
2208{ 2231{
2209 struct mwifiex_adapter *adapter = priv->adapter; 2232 struct mwifiex_adapter *adapter = priv->adapter;
2210 int ret; 2233 int ret;
2211 u16 enable = true;
2212 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; 2234 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
2213 struct mwifiex_ds_auto_ds auto_ds; 2235 struct mwifiex_ds_auto_ds auto_ds;
2214 enum state_11d_t state_11d; 2236 enum state_11d_t state_11d;
@@ -2321,16 +2343,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
2321 if (ret) 2343 if (ret)
2322 return -1; 2344 return -1;
2323 2345
2324 if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
2325 /* set ibss coalescing_status */
2326 ret = mwifiex_send_cmd(
2327 priv,
2328 HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
2329 HostCmd_ACT_GEN_SET, 0, &enable, true);
2330 if (ret)
2331 return -1;
2332 }
2333
2334 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl)); 2346 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
2335 amsdu_aggr_ctrl.enable = true; 2347 amsdu_aggr_ctrl.enable = true;
2336 /* Send request to firmware */ 2348 /* Send request to firmware */
diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c
index c3f696a2e852..c563160b3b6b 100644
--- a/drivers/net/wireless/marvell/mwifiex/usb.c
+++ b/drivers/net/wireless/marvell/mwifiex/usb.c
@@ -379,7 +379,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
379 struct usb_endpoint_descriptor *epd; 379 struct usb_endpoint_descriptor *epd;
380 int ret, i; 380 int ret, i;
381 struct usb_card_rec *card; 381 struct usb_card_rec *card;
382 u16 id_vendor, id_product, bcd_device, bcd_usb; 382 u16 id_vendor, id_product, bcd_device;
383 383
384 card = devm_kzalloc(&intf->dev, sizeof(*card), GFP_KERNEL); 384 card = devm_kzalloc(&intf->dev, sizeof(*card), GFP_KERNEL);
385 if (!card) 385 if (!card)
@@ -390,7 +390,6 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
390 id_vendor = le16_to_cpu(udev->descriptor.idVendor); 390 id_vendor = le16_to_cpu(udev->descriptor.idVendor);
391 id_product = le16_to_cpu(udev->descriptor.idProduct); 391 id_product = le16_to_cpu(udev->descriptor.idProduct);
392 bcd_device = le16_to_cpu(udev->descriptor.bcdDevice); 392 bcd_device = le16_to_cpu(udev->descriptor.bcdDevice);
393 bcd_usb = le16_to_cpu(udev->descriptor.bcdUSB);
394 pr_debug("info: VID/PID = %X/%X, Boot2 version = %X\n", 393 pr_debug("info: VID/PID = %X/%X, Boot2 version = %X\n",
395 id_vendor, id_product, bcd_device); 394 id_vendor, id_product, bcd_device);
396 395
diff --git a/drivers/net/wireless/mediatek/mt7601u/init.c b/drivers/net/wireless/mediatek/mt7601u/init.c
index 44d46e25db80..a6e901766226 100644
--- a/drivers/net/wireless/mediatek/mt7601u/init.c
+++ b/drivers/net/wireless/mediatek/mt7601u/init.c
@@ -293,13 +293,13 @@ static void mt7601u_mac_stop_hw(struct mt7601u_dev *dev)
293 ok = 0; 293 ok = 0;
294 i = 200; 294 i = 200;
295 while (i--) { 295 while (i--) {
296 if ((mt76_rr(dev, 0x0430) & 0x00ff0000) || 296 if (!(mt76_rr(dev, MT_RXQ_STA) & 0x00ff0000) &&
297 (mt76_rr(dev, 0x0a30) & 0xffffffff) || 297 !mt76_rr(dev, 0x0a30) &&
298 (mt76_rr(dev, 0x0a34) & 0xffffffff)) 298 !mt76_rr(dev, 0x0a34)) {
299 ok++; 299 if (ok++ > 5)
300 if (ok > 6) 300 break;
301 break; 301 continue;
302 302 }
303 msleep(1); 303 msleep(1);
304 } 304 }
305 305
diff --git a/drivers/net/wireless/mediatek/mt7601u/regs.h b/drivers/net/wireless/mediatek/mt7601u/regs.h
index 27a429d90cec..2a8837002f00 100644
--- a/drivers/net/wireless/mediatek/mt7601u/regs.h
+++ b/drivers/net/wireless/mediatek/mt7601u/regs.h
@@ -192,6 +192,9 @@
192#define MT_BCN_OFFSET_BASE 0x041c 192#define MT_BCN_OFFSET_BASE 0x041c
193#define MT_BCN_OFFSET(_n) (MT_BCN_OFFSET_BASE + ((_n) << 2)) 193#define MT_BCN_OFFSET(_n) (MT_BCN_OFFSET_BASE + ((_n) << 2))
194 194
195#define MT_RXQ_STA 0x0430
196#define MT_TXQ_STA 0x0434
197
195#define MT_RF_CSR_CFG 0x0500 198#define MT_RF_CSR_CFG 0x0500
196#define MT_RF_CSR_CFG_DATA GENMASK(7, 0) 199#define MT_RF_CSR_CFG_DATA GENMASK(7, 0)
197#define MT_RF_CSR_CFG_REG_ID GENMASK(13, 8) 200#define MT_RF_CSR_CFG_REG_ID GENMASK(13, 8)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
index 08d587a342d3..df551b2b56eb 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -1337,10 +1337,11 @@ struct rtl8xxxu_fileops {
1337 u32 ramask, int sgi); 1337 u32 ramask, int sgi);
1338 void (*report_connect) (struct rtl8xxxu_priv *priv, 1338 void (*report_connect) (struct rtl8xxxu_priv *priv,
1339 u8 macid, bool connect); 1339 u8 macid, bool connect);
1340 void (*fill_txdesc) (struct ieee80211_hdr *hdr, 1340 void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
1341 struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, 1341 struct ieee80211_tx_info *tx_info,
1342 u16 rate_flag, bool sgi, bool short_preamble, 1342 struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
1343 bool ampdu_enable); 1343 bool short_preamble, bool ampdu_enable,
1344 u32 rts_rate);
1344 int writeN_block_size; 1345 int writeN_block_size;
1345 int rx_agg_buf_size; 1346 int rx_agg_buf_size;
1346 char tx_desc_size; 1347 char tx_desc_size;
@@ -1434,14 +1435,16 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
1434int rtl8xxxu_gen2_channel_to_group(int channel); 1435int rtl8xxxu_gen2_channel_to_group(int channel);
1435bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, 1436bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv,
1436 int result[][8], int c1, int c2); 1437 int result[][8], int c1, int c2);
1437void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, 1438void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
1438 struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, 1439 struct ieee80211_tx_info *tx_info,
1439 u16 rate_flag, bool sgi, bool short_preamble, 1440 struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
1440 bool ampdu_enable); 1441 bool short_preamble, bool ampdu_enable,
1441void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr, 1442 u32 rts_rate);
1442 struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate, 1443void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
1443 u16 rate_flag, bool sgi, bool short_preamble, 1444 struct ieee80211_tx_info *tx_info,
1444 bool ampdu_enable); 1445 struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
1446 bool short_preamble, bool ampdu_enable,
1447 u32 rts_rate);
1445 1448
1446extern struct rtl8xxxu_fileops rtl8192cu_fops; 1449extern struct rtl8xxxu_fileops rtl8192cu_fops;
1447extern struct rtl8xxxu_fileops rtl8192eu_fops; 1450extern struct rtl8xxxu_fileops rtl8192eu_fops;
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
index a793fedc3654..a1178c5d6ad8 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
@@ -1556,7 +1556,7 @@ exit:
1556 return ret; 1556 return ret;
1557} 1557}
1558 1558
1559void rtl8192eu_power_off(struct rtl8xxxu_priv *priv) 1559static void rtl8192eu_power_off(struct rtl8xxxu_priv *priv)
1560{ 1560{
1561 u8 val8; 1561 u8 val8;
1562 u16 val16; 1562 u16 val16;
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
index a5e6ec2152bf..3a86675020a2 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
@@ -4372,6 +4372,13 @@ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
4372void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, 4372void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
4373 u8 macid, bool connect) 4373 u8 macid, bool connect)
4374{ 4374{
4375#ifdef RTL8XXXU_GEN2_REPORT_CONNECT
4376 /*
4377 * Barry Day reports this causes issues with 8192eu and 8723bu
4378 * devices reconnecting. The reason for this is unclear, but
4379 * until it is better understood, leave the code in place but
4380 * disabled, so it is not lost.
4381 */
4375 struct h2c_cmd h2c; 4382 struct h2c_cmd h2c;
4376 4383
4377 memset(&h2c, 0, sizeof(struct h2c_cmd)); 4384 memset(&h2c, 0, sizeof(struct h2c_cmd));
@@ -4383,6 +4390,7 @@ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
4383 h2c.media_status_rpt.parm &= ~BIT(0); 4390 h2c.media_status_rpt.parm &= ~BIT(0);
4384 4391
4385 rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt)); 4392 rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt));
4393#endif
4386} 4394}
4387 4395
4388void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv) 4396void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
@@ -4759,13 +4767,28 @@ static void rtl8xxxu_dump_action(struct device *dev,
4759 * This format is used on 8188cu/8192cu/8723au 4767 * This format is used on 8188cu/8192cu/8723au
4760 */ 4768 */
4761void 4769void
4762rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, 4770rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
4763 struct rtl8xxxu_txdesc32 *tx_desc, u32 rate, 4771 struct ieee80211_tx_info *tx_info,
4764 u16 rate_flag, bool sgi, bool short_preamble, 4772 struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
4765 bool ampdu_enable) 4773 bool short_preamble, bool ampdu_enable, u32 rts_rate)
4766{ 4774{
4775 struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
4776 struct rtl8xxxu_priv *priv = hw->priv;
4777 struct device *dev = &priv->udev->dev;
4778 u32 rate;
4779 u16 rate_flags = tx_info->control.rates[0].flags;
4767 u16 seq_number; 4780 u16 seq_number;
4768 4781
4782 if (rate_flags & IEEE80211_TX_RC_MCS &&
4783 !ieee80211_is_mgmt(hdr->frame_control))
4784 rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
4785 else
4786 rate = tx_rate->hw_value;
4787
4788 if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
4789 dev_info(dev, "%s: TX rate: %d, pkt size %d\n",
4790 __func__, rate, cpu_to_le16(tx_desc->pkt_size));
4791
4769 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); 4792 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
4770 4793
4771 tx_desc->txdw5 = cpu_to_le32(rate); 4794 tx_desc->txdw5 = cpu_to_le32(rate);
@@ -4796,15 +4819,16 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
4796 if (sgi) 4819 if (sgi)
4797 tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI); 4820 tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI);
4798 4821
4799 if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { 4822 /*
4800 /* 4823 * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
4801 * Use RTS rate 24M - does the mac80211 tell 4824 */
4802 * us which to use? 4825 tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT);
4803 */ 4826 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
4804 tx_desc->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
4805 TXDESC32_RTS_RATE_SHIFT);
4806 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE); 4827 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE);
4807 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE); 4828 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
4829 } else if (rate_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
4830 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_CTS_SELF_ENABLE);
4831 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_HW_RTS_ENABLE);
4808 } 4832 }
4809} 4833}
4810 4834
@@ -4813,16 +4837,31 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
4813 * This format is used on 8192eu/8723bu 4837 * This format is used on 8192eu/8723bu
4814 */ 4838 */
4815void 4839void
4816rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr, 4840rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
4817 struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate, 4841 struct ieee80211_tx_info *tx_info,
4818 u16 rate_flag, bool sgi, bool short_preamble, 4842 struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
4819 bool ampdu_enable) 4843 bool short_preamble, bool ampdu_enable, u32 rts_rate)
4820{ 4844{
4845 struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
4846 struct rtl8xxxu_priv *priv = hw->priv;
4847 struct device *dev = &priv->udev->dev;
4821 struct rtl8xxxu_txdesc40 *tx_desc40; 4848 struct rtl8xxxu_txdesc40 *tx_desc40;
4849 u32 rate;
4850 u16 rate_flags = tx_info->control.rates[0].flags;
4822 u16 seq_number; 4851 u16 seq_number;
4823 4852
4824 tx_desc40 = (struct rtl8xxxu_txdesc40 *)tx_desc32; 4853 tx_desc40 = (struct rtl8xxxu_txdesc40 *)tx_desc32;
4825 4854
4855 if (rate_flags & IEEE80211_TX_RC_MCS &&
4856 !ieee80211_is_mgmt(hdr->frame_control))
4857 rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
4858 else
4859 rate = tx_rate->hw_value;
4860
4861 if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
4862 dev_info(dev, "%s: TX rate: %d, pkt size %d\n",
4863 __func__, rate, cpu_to_le16(tx_desc40->pkt_size));
4864
4826 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); 4865 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
4827 4866
4828 tx_desc40->txdw4 = cpu_to_le32(rate); 4867 tx_desc40->txdw4 = cpu_to_le32(rate);
@@ -4849,15 +4888,19 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr,
4849 if (short_preamble) 4888 if (short_preamble)
4850 tx_desc40->txdw5 |= cpu_to_le32(TXDESC40_SHORT_PREAMBLE); 4889 tx_desc40->txdw5 |= cpu_to_le32(TXDESC40_SHORT_PREAMBLE);
4851 4890
4852 if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { 4891 tx_desc40->txdw4 |= cpu_to_le32(rts_rate << TXDESC40_RTS_RATE_SHIFT);
4853 /* 4892 /*
4854 * Use RTS rate 24M - does the mac80211 tell 4893 * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
4855 * us which to use? 4894 */
4856 */ 4895 if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
4857 tx_desc40->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
4858 TXDESC40_RTS_RATE_SHIFT);
4859 tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE); 4896 tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE);
4860 tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_HW_RTS_ENABLE); 4897 tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_HW_RTS_ENABLE);
4898 } else if (rate_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
4899 /*
4900 * For some reason the vendor driver doesn't set
4901 * TXDESC40_HW_RTS_ENABLE for CTS to SELF
4902 */
4903 tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_CTS_SELF_ENABLE);
4861 } 4904 }
4862} 4905}
4863 4906
@@ -4867,14 +4910,13 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
4867{ 4910{
4868 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 4911 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
4869 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 4912 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
4870 struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
4871 struct rtl8xxxu_priv *priv = hw->priv; 4913 struct rtl8xxxu_priv *priv = hw->priv;
4872 struct rtl8xxxu_txdesc32 *tx_desc; 4914 struct rtl8xxxu_txdesc32 *tx_desc;
4873 struct rtl8xxxu_tx_urb *tx_urb; 4915 struct rtl8xxxu_tx_urb *tx_urb;
4874 struct ieee80211_sta *sta = NULL; 4916 struct ieee80211_sta *sta = NULL;
4875 struct ieee80211_vif *vif = tx_info->control.vif; 4917 struct ieee80211_vif *vif = tx_info->control.vif;
4876 struct device *dev = &priv->udev->dev; 4918 struct device *dev = &priv->udev->dev;
4877 u32 queue, rate; 4919 u32 queue, rts_rate;
4878 u16 pktlen = skb->len; 4920 u16 pktlen = skb->len;
4879 u16 seq_number; 4921 u16 seq_number;
4880 u16 rate_flag = tx_info->control.rates[0].flags; 4922 u16 rate_flag = tx_info->control.rates[0].flags;
@@ -4901,10 +4943,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
4901 goto error; 4943 goto error;
4902 } 4944 }
4903 4945
4904 if (rtl8xxxu_debug & RTL8XXXU_DEBUG_TX)
4905 dev_info(dev, "%s: TX rate: %d (%d), pkt size %d\n",
4906 __func__, tx_rate->bitrate, tx_rate->hw_value, pktlen);
4907
4908 if (ieee80211_is_action(hdr->frame_control)) 4946 if (ieee80211_is_action(hdr->frame_control))
4909 rtl8xxxu_dump_action(dev, hdr); 4947 rtl8xxxu_dump_action(dev, hdr);
4910 4948
@@ -4958,12 +4996,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
4958 } 4996 }
4959 } 4997 }
4960 4998
4961 if (rate_flag & IEEE80211_TX_RC_MCS &&
4962 !ieee80211_is_mgmt(hdr->frame_control))
4963 rate = tx_info->control.rates[0].idx + DESC_RATE_MCS0;
4964 else
4965 rate = tx_rate->hw_value;
4966
4967 if (rate_flag & IEEE80211_TX_RC_SHORT_GI || 4999 if (rate_flag & IEEE80211_TX_RC_SHORT_GI ||
4968 (ieee80211_is_data_qos(hdr->frame_control) && 5000 (ieee80211_is_data_qos(hdr->frame_control) &&
4969 sta && sta->ht_cap.cap & 5001 sta && sta->ht_cap.cap &
@@ -4974,10 +5006,17 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
4974 (sta && vif && vif->bss_conf.use_short_preamble)) 5006 (sta && vif && vif->bss_conf.use_short_preamble))
4975 short_preamble = true; 5007 short_preamble = true;
4976 5008
5009 if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS)
5010 rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value;
5011 else if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT)
5012 rts_rate = ieee80211_get_rts_cts_rate(hw, tx_info)->hw_value;
5013 else
5014 rts_rate = 0;
5015
4977 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); 5016 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
4978 5017
4979 priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag, 5018 priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble,
4980 sgi, short_preamble, ampdu_enable); 5019 ampdu_enable, rts_rate);
4981 5020
4982 rtl8xxxu_calc_tx_desc_csum(tx_desc); 5021 rtl8xxxu_calc_tx_desc_csum(tx_desc);
4983 5022
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
index 264466f59c57..4ac928bf1f8e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -1303,12 +1303,13 @@ EXPORT_SYMBOL_GPL(rtl_action_proc);
1303 1303
1304static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc) 1304static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc)
1305{ 1305{
1306 struct ieee80211_hw *hw = rtlpriv->hw;
1307
1306 rtlpriv->ra.is_special_data = true; 1308 rtlpriv->ra.is_special_data = true;
1307 if (rtlpriv->cfg->ops->get_btc_status()) 1309 if (rtlpriv->cfg->ops->get_btc_status())
1308 rtlpriv->btcoexist.btc_ops->btc_special_packet_notify( 1310 rtlpriv->btcoexist.btc_ops->btc_special_packet_notify(
1309 rtlpriv, 1); 1311 rtlpriv, 1);
1310 rtlpriv->enter_ps = false; 1312 rtl_lps_leave(hw);
1311 schedule_work(&rtlpriv->works.lps_change_work);
1312 ppsc->last_delaylps_stamp_jiffies = jiffies; 1313 ppsc->last_delaylps_stamp_jiffies = jiffies;
1313} 1314}
1314 1315
@@ -1381,8 +1382,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
1381 1382
1382 if (is_tx) { 1383 if (is_tx) {
1383 rtlpriv->ra.is_special_data = true; 1384 rtlpriv->ra.is_special_data = true;
1384 rtlpriv->enter_ps = false; 1385 rtl_lps_leave(hw);
1385 schedule_work(&rtlpriv->works.lps_change_work);
1386 ppsc->last_delaylps_stamp_jiffies = jiffies; 1386 ppsc->last_delaylps_stamp_jiffies = jiffies;
1387 } 1387 }
1388 1388
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
index e89681d2f83a..2caa4ad04dba 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -1150,10 +1150,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
1150 } else { 1150 } else {
1151 mstatus = RT_MEDIA_DISCONNECT; 1151 mstatus = RT_MEDIA_DISCONNECT;
1152 1152
1153 if (mac->link_state == MAC80211_LINKED) { 1153 if (mac->link_state == MAC80211_LINKED)
1154 rtlpriv->enter_ps = false; 1154 rtl_lps_leave(hw);
1155 schedule_work(&rtlpriv->works.lps_change_work);
1156 }
1157 if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE) 1155 if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
1158 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); 1156 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
1159 mac->link_state = MAC80211_NOLINK; 1157 mac->link_state = MAC80211_NOLINK;
@@ -1431,8 +1429,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw,
1431 } 1429 }
1432 1430
1433 if (mac->link_state == MAC80211_LINKED) { 1431 if (mac->link_state == MAC80211_LINKED) {
1434 rtlpriv->enter_ps = false; 1432 rtl_lps_leave(hw);
1435 schedule_work(&rtlpriv->works.lps_change_work);
1436 mac->link_state = MAC80211_LINKED_SCANNING; 1433 mac->link_state = MAC80211_LINKED_SCANNING;
1437 } else { 1434 } else {
1438 rtl_ips_nic_on(hw); 1435 rtl_ips_nic_on(hw);
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index d044b23a0d33..8bfe020edd3a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -659,11 +659,9 @@ tx_status_ok:
659 } 659 }
660 660
661 if (((rtlpriv->link_info.num_rx_inperiod + 661 if (((rtlpriv->link_info.num_rx_inperiod +
662 rtlpriv->link_info.num_tx_inperiod) > 8) || 662 rtlpriv->link_info.num_tx_inperiod) > 8) ||
663 (rtlpriv->link_info.num_rx_inperiod > 2)) { 663 (rtlpriv->link_info.num_rx_inperiod > 2))
664 rtlpriv->enter_ps = false; 664 rtl_lps_leave(hw);
665 schedule_work(&rtlpriv->works.lps_change_work);
666 }
667} 665}
668 666
669static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, 667static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
@@ -914,10 +912,8 @@ new_trx_end:
914 } 912 }
915 if (((rtlpriv->link_info.num_rx_inperiod + 913 if (((rtlpriv->link_info.num_rx_inperiod +
916 rtlpriv->link_info.num_tx_inperiod) > 8) || 914 rtlpriv->link_info.num_tx_inperiod) > 8) ||
917 (rtlpriv->link_info.num_rx_inperiod > 2)) { 915 (rtlpriv->link_info.num_rx_inperiod > 2))
918 rtlpriv->enter_ps = false; 916 rtl_lps_leave(hw);
919 schedule_work(&rtlpriv->works.lps_change_work);
920 }
921 skb = new_skb; 917 skb = new_skb;
922no_new: 918no_new:
923 if (rtlpriv->use_new_trx_flow) { 919 if (rtlpriv->use_new_trx_flow) {
diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c
index 18d979affc18..d0ffc4d508cf 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
@@ -407,8 +407,8 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
407 } 407 }
408} 408}
409 409
410/*Enter the leisure power save mode.*/ 410/* Interrupt safe routine to enter the leisure power save mode.*/
411void rtl_lps_enter(struct ieee80211_hw *hw) 411static void rtl_lps_enter_core(struct ieee80211_hw *hw)
412{ 412{
413 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 413 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
414 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 414 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
@@ -444,10 +444,9 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
444 444
445 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); 445 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
446} 446}
447EXPORT_SYMBOL(rtl_lps_enter);
448 447
449/*Leave the leisure power save mode.*/ 448/* Interrupt safe routine to leave the leisure power save mode.*/
450void rtl_lps_leave(struct ieee80211_hw *hw) 449static void rtl_lps_leave_core(struct ieee80211_hw *hw)
451{ 450{
452 struct rtl_priv *rtlpriv = rtl_priv(hw); 451 struct rtl_priv *rtlpriv = rtl_priv(hw);
453 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 452 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
@@ -477,7 +476,6 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
477 } 476 }
478 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); 477 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
479} 478}
480EXPORT_SYMBOL(rtl_lps_leave);
481 479
482/* For sw LPS*/ 480/* For sw LPS*/
483void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) 481void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
@@ -670,12 +668,34 @@ void rtl_lps_change_work_callback(struct work_struct *work)
670 struct rtl_priv *rtlpriv = rtl_priv(hw); 668 struct rtl_priv *rtlpriv = rtl_priv(hw);
671 669
672 if (rtlpriv->enter_ps) 670 if (rtlpriv->enter_ps)
673 rtl_lps_enter(hw); 671 rtl_lps_enter_core(hw);
674 else 672 else
675 rtl_lps_leave(hw); 673 rtl_lps_leave_core(hw);
676} 674}
677EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback); 675EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback);
678 676
677void rtl_lps_enter(struct ieee80211_hw *hw)
678{
679 struct rtl_priv *rtlpriv = rtl_priv(hw);
680
681 if (!in_interrupt())
682 return rtl_lps_enter_core(hw);
683 rtlpriv->enter_ps = true;
684 schedule_work(&rtlpriv->works.lps_change_work);
685}
686EXPORT_SYMBOL_GPL(rtl_lps_enter);
687
688void rtl_lps_leave(struct ieee80211_hw *hw)
689{
690 struct rtl_priv *rtlpriv = rtl_priv(hw);
691
692 if (!in_interrupt())
693 return rtl_lps_leave_core(hw);
694 rtlpriv->enter_ps = false;
695 schedule_work(&rtlpriv->works.lps_change_work);
696}
697EXPORT_SYMBOL_GPL(rtl_lps_leave);
698
679void rtl_swlps_wq_callback(void *data) 699void rtl_swlps_wq_callback(void *data)
680{ 700{
681 struct rtl_works *rtlworks = container_of_dwork_rtl(data, 701 struct rtl_works *rtlworks = container_of_dwork_rtl(data,
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index aaca25870bc1..dadaa73ab49d 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -275,6 +275,8 @@ static int rsi_mac80211_start(struct ieee80211_hw *hw)
275 common->iface_down = false; 275 common->iface_down = false;
276 mutex_unlock(&common->mutex); 276 mutex_unlock(&common->mutex);
277 277
278 rsi_send_rx_filter_frame(common, 0);
279
278 return 0; 280 return 0;
279} 281}
280 282
@@ -388,7 +390,7 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
388 390
389 status = rsi_band_check(common); 391 status = rsi_band_check(common);
390 if (!status) 392 if (!status)
391 status = rsi_set_channel(adapter->priv, channel); 393 status = rsi_set_channel(adapter->priv, curchan);
392 394
393 if (bss->assoc) { 395 if (bss->assoc) {
394 if (common->hw_data_qs_blocked && 396 if (common->hw_data_qs_blocked &&
@@ -409,6 +411,34 @@ static int rsi_channel_change(struct ieee80211_hw *hw)
409} 411}
410 412
411/** 413/**
414 * rsi_config_power() - This function configures tx power to device
415 * @hw: Pointer to the ieee80211_hw structure.
416 *
417 * Return: 0 on success, negative error code on failure.
418 */
419static int rsi_config_power(struct ieee80211_hw *hw)
420{
421 struct rsi_hw *adapter = hw->priv;
422 struct rsi_common *common = adapter->priv;
423 struct ieee80211_conf *conf = &hw->conf;
424
425 if (adapter->sc_nvifs <= 0) {
426 rsi_dbg(ERR_ZONE, "%s: No virtual interface found\n", __func__);
427 return -EINVAL;
428 }
429
430 rsi_dbg(INFO_ZONE,
431 "%s: Set tx power: %d dBM\n", __func__, conf->power_level);
432
433 if (conf->power_level == common->tx_power)
434 return 0;
435
436 common->tx_power = conf->power_level;
437
438 return rsi_send_radio_params_update(common);
439}
440
441/**
412 * rsi_mac80211_config() - This function is a handler for configuration 442 * rsi_mac80211_config() - This function is a handler for configuration
413 * requests. The stack calls this function to 443 * requests. The stack calls this function to
414 * change hardware configuration, e.g., channel. 444 * change hardware configuration, e.g., channel.
@@ -429,6 +459,12 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
429 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) 459 if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
430 status = rsi_channel_change(hw); 460 status = rsi_channel_change(hw);
431 461
462 /* tx power */
463 if (changed & IEEE80211_CONF_CHANGE_POWER) {
464 rsi_dbg(INFO_ZONE, "%s: Configuring Power\n", __func__);
465 status = rsi_config_power(hw);
466 }
467
432 mutex_unlock(&common->mutex); 468 mutex_unlock(&common->mutex);
433 469
434 return status; 470 return status;
@@ -471,11 +507,19 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
471{ 507{
472 struct rsi_hw *adapter = hw->priv; 508 struct rsi_hw *adapter = hw->priv;
473 struct rsi_common *common = adapter->priv; 509 struct rsi_common *common = adapter->priv;
510 u16 rx_filter_word = 0;
474 511
475 mutex_lock(&common->mutex); 512 mutex_lock(&common->mutex);
476 if (changed & BSS_CHANGED_ASSOC) { 513 if (changed & BSS_CHANGED_ASSOC) {
477 rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n", 514 rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n",
478 __func__, bss_conf->assoc); 515 __func__, bss_conf->assoc);
516 if (bss_conf->assoc) {
517 /* Send the RX filter frame */
518 rx_filter_word = (ALLOW_DATA_ASSOC_PEER |
519 ALLOW_CTRL_ASSOC_PEER |
520 ALLOW_MGMT_ASSOC_PEER);
521 rsi_send_rx_filter_frame(common, rx_filter_word);
522 }
479 rsi_inform_bss_status(common, 523 rsi_inform_bss_status(common,
480 bss_conf->assoc, 524 bss_conf->assoc,
481 bss_conf->bssid, 525 bss_conf->bssid,
@@ -1013,6 +1057,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
1013 struct rsi_common *common = adapter->priv; 1057 struct rsi_common *common = adapter->priv;
1014 1058
1015 mutex_lock(&common->mutex); 1059 mutex_lock(&common->mutex);
1060
1016 /* Resetting all the fields to default values */ 1061 /* Resetting all the fields to default values */
1017 common->bitrate_mask[NL80211_BAND_2GHZ] = 0; 1062 common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
1018 common->bitrate_mask[NL80211_BAND_5GHZ] = 0; 1063 common->bitrate_mask[NL80211_BAND_5GHZ] = 0;
@@ -1022,9 +1067,114 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
1022 common->vif_info[0].seq_start = 0; 1067 common->vif_info[0].seq_start = 0;
1023 common->secinfo.ptk_cipher = 0; 1068 common->secinfo.ptk_cipher = 0;
1024 common->secinfo.gtk_cipher = 0; 1069 common->secinfo.gtk_cipher = 0;
1070
1071 rsi_send_rx_filter_frame(common, 0);
1072
1025 mutex_unlock(&common->mutex); 1073 mutex_unlock(&common->mutex);
1074
1075 return 0;
1076}
1077
1078/**
1079 * rsi_mac80211_set_antenna() - This function is used to configure
1080 * tx and rx antennas.
1081 * @hw: Pointer to the ieee80211_hw structure.
1082 * @tx_ant: Bitmap for tx antenna
1083 * @rx_ant: Bitmap for rx antenna
1084 *
1085 * Return: 0 on success, Negative error code on failure.
1086 */
1087static int rsi_mac80211_set_antenna(struct ieee80211_hw *hw,
1088 u32 tx_ant, u32 rx_ant)
1089{
1090 struct rsi_hw *adapter = hw->priv;
1091 struct rsi_common *common = adapter->priv;
1092 u8 antenna = 0;
1026 1093
1094 if (tx_ant > 1 || rx_ant > 1) {
1095 rsi_dbg(ERR_ZONE,
1096 "Invalid antenna selection (tx: %d, rx:%d)\n",
1097 tx_ant, rx_ant);
1098 rsi_dbg(ERR_ZONE,
1099 "Use 0 for int_ant, 1 for ext_ant\n");
1100 return -EINVAL;
1101 }
1102
1103 rsi_dbg(INFO_ZONE, "%s: Antenna map Tx %x Rx %d\n",
1104 __func__, tx_ant, rx_ant);
1105
1106 mutex_lock(&common->mutex);
1107
1108 antenna = tx_ant ? ANTENNA_SEL_UFL : ANTENNA_SEL_INT;
1109 if (common->ant_in_use != antenna)
1110 if (rsi_set_antenna(common, antenna))
1111 goto fail_set_antenna;
1112
1113 rsi_dbg(INFO_ZONE, "(%s) Antenna path configured successfully\n",
1114 tx_ant ? "UFL" : "INT");
1115
1116 common->ant_in_use = antenna;
1117
1118 mutex_unlock(&common->mutex);
1119
1027 return 0; 1120 return 0;
1121
1122fail_set_antenna:
1123 rsi_dbg(ERR_ZONE, "%s: Failed.\n", __func__);
1124 mutex_unlock(&common->mutex);
1125 return -EINVAL;
1126}
1127
1128/**
1129 * rsi_mac80211_get_antenna() - This function is used to configure
1130 * tx and rx antennas.
1131 *
1132 * @hw: Pointer to the ieee80211_hw structure.
1133 * @tx_ant: Bitmap for tx antenna
1134 * @rx_ant: Bitmap for rx antenna
1135 *
1136 * Return: 0 on success, -1 on failure.
1137 */
1138static int rsi_mac80211_get_antenna(struct ieee80211_hw *hw,
1139 u32 *tx_ant, u32 *rx_ant)
1140{
1141 struct rsi_hw *adapter = hw->priv;
1142 struct rsi_common *common = adapter->priv;
1143
1144 mutex_lock(&common->mutex);
1145
1146 *tx_ant = (common->ant_in_use == ANTENNA_SEL_UFL) ? 1 : 0;
1147 *rx_ant = 0;
1148
1149 mutex_unlock(&common->mutex);
1150
1151 return 0;
1152}
1153
1154static void rsi_reg_notify(struct wiphy *wiphy,
1155 struct regulatory_request *request)
1156{
1157 struct ieee80211_supported_band *sband;
1158 struct ieee80211_channel *ch;
1159 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1160 struct rsi_hw * adapter = hw->priv;
1161 int i;
1162
1163 sband = wiphy->bands[NL80211_BAND_5GHZ];
1164
1165 for (i = 0; i < sband->n_channels; i++) {
1166 ch = &sband->channels[i];
1167 if (ch->flags & IEEE80211_CHAN_DISABLED)
1168 continue;
1169
1170 if (ch->flags & IEEE80211_CHAN_RADAR)
1171 ch->flags |= IEEE80211_CHAN_NO_IR;
1172 }
1173
1174 rsi_dbg(INFO_ZONE,
1175 "country = %s dfs_region = %d\n",
1176 request->alpha2, request->dfs_region);
1177 adapter->dfs_region = request->dfs_region;
1028} 1178}
1029 1179
1030static struct ieee80211_ops mac80211_ops = { 1180static struct ieee80211_ops mac80211_ops = {
@@ -1043,6 +1193,8 @@ static struct ieee80211_ops mac80211_ops = {
1043 .ampdu_action = rsi_mac80211_ampdu_action, 1193 .ampdu_action = rsi_mac80211_ampdu_action,
1044 .sta_add = rsi_mac80211_sta_add, 1194 .sta_add = rsi_mac80211_sta_add,
1045 .sta_remove = rsi_mac80211_sta_remove, 1195 .sta_remove = rsi_mac80211_sta_remove,
1196 .set_antenna = rsi_mac80211_set_antenna,
1197 .get_antenna = rsi_mac80211_get_antenna,
1046}; 1198};
1047 1199
1048/** 1200/**
@@ -1107,6 +1259,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
1107 wiphy->bands[NL80211_BAND_5GHZ] = 1259 wiphy->bands[NL80211_BAND_5GHZ] =
1108 &adapter->sbands[NL80211_BAND_5GHZ]; 1260 &adapter->sbands[NL80211_BAND_5GHZ];
1109 1261
1262 wiphy->reg_notifier = rsi_reg_notify;
1263
1110 status = ieee80211_register_hw(hw); 1264 status = ieee80211_register_hw(hw);
1111 if (status) 1265 if (status)
1112 return status; 1266 return status;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 30b9d44ff8f8..fac87c06357b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -913,7 +913,8 @@ int rsi_band_check(struct rsi_common *common)
913 * 913 *
914 * Return: 0 on success, corresponding error code on failure. 914 * Return: 0 on success, corresponding error code on failure.
915 */ 915 */
916int rsi_set_channel(struct rsi_common *common, u16 channel) 916int rsi_set_channel(struct rsi_common *common,
917 struct ieee80211_channel *channel)
917{ 918{
918 struct sk_buff *skb = NULL; 919 struct sk_buff *skb = NULL;
919 struct rsi_mac_frame *mgmt_frame; 920 struct rsi_mac_frame *mgmt_frame;
@@ -928,24 +929,76 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
928 return -ENOMEM; 929 return -ENOMEM;
929 } 930 }
930 931
932 if (!channel) {
933 dev_kfree_skb(skb);
934 return 0;
935 }
931 memset(skb->data, 0, FRAME_DESC_SZ); 936 memset(skb->data, 0, FRAME_DESC_SZ);
932 mgmt_frame = (struct rsi_mac_frame *)skb->data; 937 mgmt_frame = (struct rsi_mac_frame *)skb->data;
933 938
934 mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 939 mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
935 mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST); 940 mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST);
936 mgmt_frame->desc_word[4] = cpu_to_le16(channel); 941 mgmt_frame->desc_word[4] = cpu_to_le16(channel->hw_value);
942
943 mgmt_frame->desc_word[4] |=
944 cpu_to_le16(((char)(channel->max_antenna_gain)) << 8);
945 mgmt_frame->desc_word[5] =
946 cpu_to_le16((char)(channel->max_antenna_gain));
937 947
938 mgmt_frame->desc_word[7] = cpu_to_le16(PUT_BBP_RESET | 948 mgmt_frame->desc_word[7] = cpu_to_le16(PUT_BBP_RESET |
939 BBP_REG_WRITE | 949 BBP_REG_WRITE |
940 (RSI_RF_TYPE << 4)); 950 (RSI_RF_TYPE << 4));
941 951
942 mgmt_frame->desc_word[5] = cpu_to_le16(0x01); 952 if (!(channel->flags & IEEE80211_CHAN_NO_IR) &&
943 mgmt_frame->desc_word[6] = cpu_to_le16(0x12); 953 !(channel->flags & IEEE80211_CHAN_RADAR)) {
954 if (common->tx_power < channel->max_power)
955 mgmt_frame->desc_word[6] = cpu_to_le16(common->tx_power);
956 else
957 mgmt_frame->desc_word[6] = cpu_to_le16(channel->max_power);
958 }
959 mgmt_frame->desc_word[7] = cpu_to_le16(common->priv->dfs_region);
944 960
945 if (common->channel_width == BW_40MHZ) 961 if (common->channel_width == BW_40MHZ)
946 mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8); 962 mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8);
947 963
948 common->channel = channel; 964 common->channel = channel->hw_value;
965
966 skb_put(skb, FRAME_DESC_SZ);
967
968 return rsi_send_internal_mgmt_frame(common, skb);
969}
970
971/**
972 * rsi_send_radio_params_update() - This function sends the radio
973 * parameters update to device
974 * @common: Pointer to the driver private structure.
975 * @channel: Channel value to be set.
976 *
977 * Return: 0 on success, corresponding error code on failure.
978 */
979int rsi_send_radio_params_update(struct rsi_common *common)
980{
981 struct rsi_mac_frame *cmd_frame;
982 struct sk_buff *skb = NULL;
983
984 rsi_dbg(MGMT_TX_ZONE,
985 "%s: Sending Radio Params update frame\n", __func__);
986
987 skb = dev_alloc_skb(FRAME_DESC_SZ);
988 if (!skb) {
989 rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
990 __func__);
991 return -ENOMEM;
992 }
993
994 memset(skb->data, 0, FRAME_DESC_SZ);
995 cmd_frame = (struct rsi_mac_frame *)skb->data;
996
997 cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
998 cmd_frame->desc_word[1] = cpu_to_le16(RADIO_PARAMS_UPDATE);
999 cmd_frame->desc_word[3] = cpu_to_le16(BIT(0));
1000
1001 cmd_frame->desc_word[3] |= cpu_to_le16(common->tx_power << 8);
949 1002
950 skb_put(skb, FRAME_DESC_SZ); 1003 skb_put(skb, FRAME_DESC_SZ);
951 1004
@@ -1243,6 +1296,72 @@ int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event)
1243 1296
1244} 1297}
1245 1298
1299/**
1300 * rsi_send_rx_filter_frame() - Sends a frame to filter the RX packets
1301 *
1302 * @common: Pointer to the driver private structure.
1303 * @rx_filter_word: Flags of filter packets
1304 *
1305 * @Return: 0 on success, -1 on failure.
1306 */
1307int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word)
1308{
1309 struct rsi_mac_frame *cmd_frame;
1310 struct sk_buff *skb;
1311
1312 rsi_dbg(MGMT_TX_ZONE, "Sending RX filter frame\n");
1313
1314 skb = dev_alloc_skb(FRAME_DESC_SZ);
1315 if (!skb) {
1316 rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
1317 __func__);
1318 return -ENOMEM;
1319 }
1320
1321 memset(skb->data, 0, FRAME_DESC_SZ);
1322 cmd_frame = (struct rsi_mac_frame *)skb->data;
1323
1324 cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
1325 cmd_frame->desc_word[1] = cpu_to_le16(SET_RX_FILTER);
1326 cmd_frame->desc_word[4] = cpu_to_le16(rx_filter_word);
1327
1328 skb_put(skb, FRAME_DESC_SZ);
1329
1330 return rsi_send_internal_mgmt_frame(common, skb);
1331}
1332
1333/**
1334 * rsi_set_antenna() - This fuction send antenna configuration request
1335 * to device
1336 *
1337 * @common: Pointer to the driver private structure.
1338 * @antenna: bitmap for tx antenna selection
1339 *
1340 * Return: 0 on Success, negative error code on failure
1341 */
1342int rsi_set_antenna(struct rsi_common *common, u8 antenna)
1343{
1344 struct rsi_mac_frame *cmd_frame;
1345 struct sk_buff *skb;
1346
1347 skb = dev_alloc_skb(FRAME_DESC_SZ);
1348 if (!skb) {
1349 rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
1350 __func__);
1351 return -ENOMEM;
1352 }
1353
1354 memset(skb->data, 0, FRAME_DESC_SZ);
1355 cmd_frame = (struct rsi_mac_frame *)skb->data;
1356
1357 cmd_frame->desc_word[1] = cpu_to_le16(ANT_SEL_FRAME);
1358 cmd_frame->desc_word[3] = cpu_to_le16(antenna & 0x00ff);
1359 cmd_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
1360
1361 skb_put(skb, FRAME_DESC_SZ);
1362
1363 return rsi_send_internal_mgmt_frame(common, skb);
1364}
1246 1365
1247/** 1366/**
1248 * rsi_handle_ta_confirm_type() - This function handles the confirm frames. 1367 * rsi_handle_ta_confirm_type() - This function handles the confirm frames.
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index dcd095787166..1d5904bc2c74 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -204,6 +204,9 @@ struct rsi_common {
204 struct cqm_info cqm_info; 204 struct cqm_info cqm_info;
205 205
206 bool hw_data_qs_blocked; 206 bool hw_data_qs_blocked;
207
208 int tx_power;
209 u8 ant_in_use;
207}; 210};
208 211
209struct rsi_hw { 212struct rsi_hw {
@@ -220,6 +223,7 @@ struct rsi_hw {
220 struct rsi_debugfs *dfsentry; 223 struct rsi_debugfs *dfsentry;
221 u8 num_debugfs_entries; 224 u8 num_debugfs_entries;
222#endif 225#endif
226 u8 dfs_region;
223 void *rsi_dev; 227 void *rsi_dev;
224 int (*host_intf_read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len); 228 int (*host_intf_read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
225 int (*host_intf_write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len); 229 int (*host_intf_write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index d1553581e471..dfbf7a50269b 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -140,6 +140,19 @@
140 140
141#define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\ 141#define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\
142 FIF_BCN_PRBRESP_PROMISC) 142 FIF_BCN_PRBRESP_PROMISC)
143
144#define ANTENNA_SEL_INT 0x02 /* RF_OUT_2 / Integerated */
145#define ANTENNA_SEL_UFL 0x03 /* RF_OUT_1 / U.FL */
146
147/* Rx filter word definitions */
148#define PROMISCOUS_MODE BIT(0)
149#define ALLOW_DATA_ASSOC_PEER BIT(1)
150#define ALLOW_MGMT_ASSOC_PEER BIT(2)
151#define ALLOW_CTRL_ASSOC_PEER BIT(3)
152#define DISALLOW_BEACONS BIT(4)
153#define ALLOW_CONN_PEER_MGMT_WHILE_BUF_FULL BIT(5)
154#define DISALLOW_BROADCAST_DATA BIT(6)
155
143enum opmode { 156enum opmode {
144 STA_OPMODE = 1, 157 STA_OPMODE = 1,
145 AP_OPMODE = 2 158 AP_OPMODE = 2
@@ -190,7 +203,9 @@ enum cmd_frame_type {
190 BG_SCAN_PARAMS, 203 BG_SCAN_PARAMS,
191 BG_SCAN_PROBE_REQ, 204 BG_SCAN_PROBE_REQ,
192 CW_MODE_REQ, 205 CW_MODE_REQ,
193 PER_CMD_PKT 206 PER_CMD_PKT,
207 ANT_SEL_FRAME = 0x20,
208 RADIO_PARAMS_UPDATE = 0x29
194}; 209};
195 210
196struct rsi_mac_frame { 211struct rsi_mac_frame {
@@ -299,7 +314,8 @@ int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid,
299 u16 ssn, u8 buf_size, u8 event); 314 u16 ssn, u8 buf_size, u8 event);
300int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len, 315int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len,
301 u8 key_type, u8 key_id, u32 cipher); 316 u8 key_type, u8 key_id, u32 cipher);
302int rsi_set_channel(struct rsi_common *common, u16 chno); 317int rsi_set_channel(struct rsi_common *common,
318 struct ieee80211_channel *channel);
303int rsi_send_block_unblock_frame(struct rsi_common *common, bool event); 319int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
304void rsi_inform_bss_status(struct rsi_common *common, u8 status, 320void rsi_inform_bss_status(struct rsi_common *common, u8 status,
305 const u8 *bssid, u8 qos_enable, u16 aid); 321 const u8 *bssid, u8 qos_enable, u16 aid);
@@ -313,4 +329,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb);
313int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb); 329int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb);
314int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb); 330int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
315int rsi_band_check(struct rsi_common *common); 331int rsi_band_check(struct rsi_common *common);
332int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word);
333int rsi_send_radio_params_update(struct rsi_common *common);
334int rsi_set_antenna(struct rsi_common *common, u8 antenna);
316#endif 335#endif