History

Merge tag 'wireless-drivers-next-for-davem-2016-12-01' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says: ==================== wireless-drivers-next patches for 4.10 Major changes: rsi * filter rx frames * configure tx power * make it possible to select antenna * support 802.11d brcmfmac * cleanup of scheduled scan code * support for bcm43341 chipset with different chip id * support rev6 of PCIe device interface ath10k * add spectral scan support for QCA6174 and QCA9377 families * show used tx bitrate with 10.4 firmware wil6210 * add power save mode support * add abort scan functionality * add support settings retry limit for short frames bcma * add Dell Inspiron 3148 ====================

David S. Miller committed 9 years ago

Commit ab17cb12 parents 4f4f907 d5fb3a165 files · +2560 −788Browse files

Unified · Split

65 files
  1. drivers/bcma/host_pci.c +1 −0
  2. drivers/net/wireless/ath/ath10k/core.c +5 −3
  3. drivers/net/wireless/ath/ath10k/core.h +24 −0
  4. drivers/net/wireless/ath/ath10k/debugfs_sta.c +13 −0
  5. drivers/net/wireless/ath/ath10k/htt.c +2 −0
  6. drivers/net/wireless/ath/ath10k/htt.h +30 −1
  7. drivers/net/wireless/ath/ath10k/htt_rx.c +125 −0
  8. drivers/net/wireless/ath/ath10k/htt_tx.c +43 −11
  9. drivers/net/wireless/ath/ath10k/mac.c +20 −31
  10. drivers/net/wireless/ath/ath10k/wmi-ops.h +6 −0
  11. drivers/net/wireless/ath/ath10k/wmi-tlv.c +74 −3
  12. drivers/net/wireless/ath/ath10k/wmi.c +3 −5
  13. drivers/net/wireless/ath/ath10k/wmi.h +16 −2
  14. drivers/net/wireless/ath/ath5k/debug.c +0 −1
  15. drivers/net/wireless/ath/ath9k/ahb.c +1 −1
  16. drivers/net/wireless/ath/ath9k/common-spectral.c +7 −1
  17. drivers/net/wireless/ath/ath9k/hif_usb.c +5 −4
  18. drivers/net/wireless/ath/ath9k/hif_usb.h +2 −0
  19. drivers/net/wireless/ath/ath9k/hw.c +1 −1
  20. drivers/net/wireless/ath/ath9k/recv.c +14 −3
  21. drivers/net/wireless/ath/wil6210/cfg80211.c +104 −25
  22. drivers/net/wireless/ath/wil6210/main.c +66 −34
  23. drivers/net/wireless/ath/wil6210/netdev.c +1 −1
  24. drivers/net/wireless/ath/wil6210/p2p.c +118 −42
  25. drivers/net/wireless/ath/wil6210/pmc.c +49 −6
  26. drivers/net/wireless/ath/wil6210/txrx.c +100 −10
  27. drivers/net/wireless/ath/wil6210/wil6210.h +22 −3
  28. drivers/net/wireless/ath/wil6210/wil_crash_dump.c +6 −0
  29. drivers/net/wireless/ath/wil6210/wmi.c +141 −19
  30. drivers/net/wireless/ath/wil6210/wmi.h +463 −123
  31. drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile +2 −1
  32. drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +8 −2
  33. drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +145 −236
  34. drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +2 −2
  35. drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +23 −0
  36. drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +18 −20
  37. drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h +4 −0
  38. drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +102 −69
  39. drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +242 −0
  40. drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h +40 −0
  41. drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +1 −0
  42. drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c +3 −2
  43. drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +1 −0
  44. drivers/net/wireless/marvell/mwifiex/cfg80211.c +10 −2
  45. drivers/net/wireless/marvell/mwifiex/fw.h +1 −0
  46. drivers/net/wireless/marvell/mwifiex/main.c +0 −3
  47. drivers/net/wireless/marvell/mwifiex/main.h +7 −2
  48. drivers/net/wireless/marvell/mwifiex/pcie.c +14 −3
  49. drivers/net/wireless/marvell/mwifiex/scan.c +3 −5
  50. drivers/net/wireless/marvell/mwifiex/sdio.c +1 −5
  51. drivers/net/wireless/marvell/mwifiex/sta_cmd.c +25 −13
  52. drivers/net/wireless/marvell/mwifiex/usb.c +1 −2
  53. drivers/net/wireless/mediatek/mt7601u/init.c +7 −7
  54. drivers/net/wireless/mediatek/mt7601u/regs.h +3 −0
  55. drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +15 −12
  56. drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +1 −1
  57. drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +75 −36
  58. drivers/net/wireless/realtek/rtlwifi/base.c +4 −4
  59. drivers/net/wireless/realtek/rtlwifi/core.c +3 −6
  60. drivers/net/wireless/realtek/rtlwifi/pci.c +5 −9
  61. drivers/net/wireless/realtek/rtlwifi/ps.c +28 −8
  62. drivers/net/wireless/rsi/rsi_91x_mac80211.c +155 −1
  63. drivers/net/wireless/rsi/rsi_91x_mgmt.c +124 −5
  64. drivers/net/wireless/rsi/rsi_main.h +4 −0
  65. drivers/net/wireless/rsi/rsi_mgmt.h +21 −2
drivers/bcma/host_pci.c+1−0
@@ -295,6 +295,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = { · 294 unmodified lines
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) },
drivers/net/wireless/ath/ath10k/core.c+5−3
@@ -326,6 +326,7 @@ static const char *const ath10k_core_fw_feature_str[] = { · 325 unmodified lines
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) · 1204 unmodified lines
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, · 314 unmodified lines
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) · 188 unmodified lines
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) · 326 unmodified lines
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}
drivers/net/wireless/ath/ath10k/core.h+24−0
@@ -337,6 +337,7 @@ struct ath10k_sta { · 336 unmodified lines
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 { · 219 unmodified lines
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 { · 125 unmodified lines
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 { · 207 unmodified lines
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;
drivers/net/wireless/ath/ath10k/debugfs_sta.c+13−0
@@ -77,6 +77,19 @@ void ath10k_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif, · 76 unmodified lines
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,
drivers/net/wireless/ath/ath10k/htt.c+2−0
@@ -137,6 +137,8 @@ static const enum htt_t2h_msg_type htt_10_4_t2h_msg_types[] = { · 136 unmodified lines
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)
drivers/net/wireless/ath/ath10k/htt.h+30−1
@@ -419,6 +419,7 @@ enum htt_10_4_t2h_msg_type { · 418 unmodified lines
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_MSGS424 HTT_10_4_T2H_NUM_MSGS
424};425};
@@ -453,6 +454,7 @@ enum htt_t2h_msg_type { · 28 unmodified lines
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_MSGS459 HTT_T2H_NUM_MSGS
458};460};
@@ -1470,6 +1472,28 @@ struct htt_channel_change { · 1011 unmodified lines
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 { · 45 unmodified lines
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 { · 165 unmodified lines
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 641724#define RX_HTT_HDR_STATUS_LEN 64
@@ -1754,7 +1781,9 @@ int ath10k_htt_connect(struct ath10k_htt *htt); · 56 unmodified lines
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);
drivers/net/wireless/ath/ath10k/htt_rx.c+125−0
@@ -2194,6 +2194,128 @@ void ath10k_htt_htc_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) · 2193 unmodified lines
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) · 154 unmodified lines
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",
drivers/net/wireless/ath/ath10k/htt_tx.c+43−11
@@ -350,21 +350,15 @@ static int ath10k_htt_tx_alloc_txdone_fifo(struct ath10k_htt *htt) · 349 unmodified lines
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: · 25 unmodified lines
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) · 16 unmodified lines
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)
drivers/net/wireless/ath/ath10k/mac.c+20−31
@@ -1167,7 +1167,9 @@ static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar) · 1166 unmodified lines
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) · 3275 unmodified lines
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, · 2520 unmodified lines
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 accepts6990 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 since6993 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 on6995
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 = { · 458 unmodified lines
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) · 524 unmodified lines
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);
drivers/net/wireless/ath/ath10k/wmi-ops.h+6−0
@@ -660,6 +660,9 @@ ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, · 659 unmodified lines
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, · 9 unmodified lines
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))
drivers/net/wireless/ath/ath10k/wmi-tlv.c+74−3
@@ -1313,8 +1313,8 @@ ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar, · 1312 unmodified lines
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) · 1815 unmodified lines
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 = { · 322 unmodified lines
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 = { · 71 unmodified lines
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 = {
drivers/net/wireless/ath/ath10k/wmi.c+3−5
@@ -785,7 +785,6 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = { · 784 unmodified lines
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 = { · 69 unmodified lines
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 = { · 68 unmodified lines
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 = { · 69 unmodified lines
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, · 3470 unmodified lines
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;
drivers/net/wireless/ath/ath10k/wmi.h+16−2
@@ -4603,9 +4603,17 @@ enum wmi_rate_preamble { · 4602 unmodified lines
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 { · 64 unmodified lines
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 04691#define WMI_VDEV_PARAM_UNSUPPORTED 0
@@ -5009,6 +5018,11 @@ enum wmi_10_4_vdev_param { · 326 unmodified lines
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)
drivers/net/wireless/ath/ath5k/debug.c+0−1
@@ -66,7 +66,6 @@ · 65 unmodified lines
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"
drivers/net/wireless/ath/ath9k/ahb.c+1−1
@@ -62,7 +62,7 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) · 61 unmodified lines
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,
drivers/net/wireless/ath/ath9k/common-spectral.c+7−1
@@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h · 527 unmodified lines
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 anything534 /* Output buffers are full, no need to process anything
532 * since there is no space to put the result anyway535 * since there is no space to put the result anyway
533 */536 */
@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = { · 538 unmodified lines
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, · 7 unmodified lines
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,
drivers/net/wireless/ath/ath9k/hif_usb.c+5−4
@@ -997,7 +997,8 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) · 996 unmodified lines
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) · 16 unmodified lines
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) · 222 unmodified lines
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) · 58 unmodified lines
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
drivers/net/wireless/ath/ath9k/hif_usb.h+2−0
@@ -71,6 +71,8 @@ extern int htc_use_dev_fw; · 70 unmodified lines
71#define USB_REG_IN_PIPE 371#define USB_REG_IN_PIPE 3
72#define USB_REG_OUT_PIPE 472#define USB_REG_OUT_PIPE 4
73 73
74#define USB_MSG_TIMEOUT 1000 /* (ms) */
75
74#define HIF_USB_MAX_RXPIPES 276#define HIF_USB_MAX_RXPIPES 2
75#define HIF_USB_MAX_TXPIPES 477#define HIF_USB_MAX_TXPIPES 4
76 78
drivers/net/wireless/ath/ath9k/hw.c+1−1
@@ -2792,7 +2792,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) · 2791 unmodified lines
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
drivers/net/wireless/ath/ath9k/recv.c+14−3
@@ -867,10 +867,21 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, · 866 unmodified lines
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
drivers/net/wireless/ath/wil6210/cfg80211.c+104−25
@@ -354,14 +354,6 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, · 353 unmodified lines
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, · 10 unmodified lines
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, · 2 unmodified lines
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, · 16 unmodified lines
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, · 26 unmodified lines
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, · 4 unmodified lines
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, · 199 unmodified lines
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, · 260 unmodified lines
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, · 463 unmodified lines
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 = { · 14 unmodified lines
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) · 10 unmodified lines
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 =
drivers/net/wireless/ath/wil6210/main.c+66−34
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include "boot_loader.h"24#include "boot_loader.h"
25 25
26#define WAIT_FOR_HALP_VOTE_MS 10026#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) · 183 unmodified lines
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, · 47 unmodified lines
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, · 9 unmodified lines
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) · 93 unmodified lines
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) · 110 unmodified lines
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) · 49 unmodified lines
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) · 108 unmodified lines
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) · 110 unmodified lines
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 reload857 * After calling this routine, you're expected to reload
@@ -853,17 +904,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) · 46 unmodified lines
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) · 70 unmodified lines
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) · 110 unmodified lines
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);
drivers/net/wireless/ath/wil6210/netdev.c+1−1
@@ -214,7 +214,7 @@ int wil_if_add(struct wil6210_priv *wil) · 213 unmodified lines
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) {
drivers/net/wireless/ath/wil6210/p2p.c+118−42
@@ -22,6 +22,43 @@ · 21 unmodified lines
22#define P2P_SEARCH_DURATION_MS 50022#define P2P_SEARCH_DURATION_MS 500
23#define P2P_DEFAULT_BI 10023#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, · 18 unmodified lines
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: · 50 unmodified lines
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, · 4 unmodified lines
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) · 6 unmodified lines
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) · 78 unmodified lines
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) · 2 unmodified lines
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) · 1 unmodified line
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) · 16 unmodified lines
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}
drivers/net/wireless/ath/wil6210/pmc.c+49−6
@@ -54,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil, · 53 unmodified lines
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, · 2 unmodified lines
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: · 121 unmodified lines
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, · 99 unmodified lines
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, · 4 unmodified lines
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) · 33 unmodified lines
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) · 9 unmodified lines
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}
drivers/net/wireless/ath/wil6210/txrx.c+100−10
@@ -88,6 +88,18 @@ static inline int wil_vring_wmark_high(struct vring *vring) · 87 unmodified lines
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, · 1686 unmodified lines
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) · 36 unmodified lines
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) · 142 unmodified lines
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}
drivers/net/wireless/ath/wil6210/wil6210.h+22−3
@@ -276,10 +276,11 @@ struct fw_map { · 275 unmodified lines
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 field286 * mk_cidxtid - construct @cidxtid field
@@ -461,8 +462,11 @@ struct wil_p2p_info { · 175 unmodified lines
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 { · 155 unmodified lines
624 * - consumed in thread by wmi_event_worker628 * - 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); · 187 unmodified lines
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); · 14 unmodified lines
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, · 19 unmodified lines
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); · 11 unmodified lines
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);
drivers/net/wireless/ath/wil6210/wil_crash_dump.c+6−0
@@ -36,6 +36,9 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil, · 35 unmodified lines
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) · 31 unmodified lines
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;
drivers/net/wireless/ath/wil6210/wmi.c+141−19
@@ -84,19 +84,29 @@ MODULE_PARM_DESC(led_id, · 83 unmodified lines
84 * array size should be in sync with the declaration in the wil6210.h84 * 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 RAM96 {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true},
97 * 930000..932000 ucode data RAM97 /* Pcie_ext_rgf 4k */
98 * 932000..949000 back-door debug data98 {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[] = { · 5 unmodified lines
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) address121 * return AHB address for given firmware internal (linker) address
112 * @x - internal address122 * @x - internal address
113 * If address have no valid AHB mapping, return 0123 * If address have no valid AHB mapping, return 0
114 */124 */
@@ -117,7 +127,8 @@ static u32 wmi_addr_remap(u32 x) · 2 unmodified lines
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, · 303 unmodified lines
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) · 103 unmodified lines
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) · 33 unmodified lines
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, · 969 unmodified lines
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;
drivers/net/wireless/ath/wil6210/wmi.h+463−123
@@ -35,6 +35,7 @@ · 34 unmodified lines
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 interface40/* Mailbox interface
40 * used for commands and events41 * used for commands and events
@@ -51,8 +52,10 @@ enum wmi_mid { · 10 unmodified lines
51 * the host52 * 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 { · 7 unmodified lines
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 commands179 /* Per MAC Power Save Configuration commands
177 * Not supported yet180 * 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 { · 676 unmodified lines
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 { · 57 unmodified lines
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 Events977/* 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 { · 87 unmodified lines
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 { · 119 unmodified lines
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 { · 898 unmodified lines
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 { · 108 unmodified lines
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__ */
drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile+2−1
@@ -35,7 +35,8 @@ brcmfmac-objs += \ · 34 unmodified lines
35 firmware.o \35 firmware.o \
36 feature.o \36 feature.o \
37 btcoex.o \37 btcoex.o \
38 vendor.o38 vendor.o \
39 pno.o
39brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \40brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \
40 bcdc.o41 bcdc.o
41brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \42brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h+8−2
@@ -22,10 +22,12 @@ · 21 unmodified lines
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 023#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
24#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 124#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 1
25#define BRCMF_H2D_MSGRING_FLOWRING_IDSTART 2
25#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 226#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 2
26#define BRCMF_D2H_MSGRING_TX_COMPLETE 327#define BRCMF_D2H_MSGRING_TX_COMPLETE 3
27#define BRCMF_D2H_MSGRING_RX_COMPLETE 428#define BRCMF_D2H_MSGRING_RX_COMPLETE 4
28 29
30
29#define BRCMF_NROF_H2D_COMMON_MSGRINGS 231#define BRCMF_NROF_H2D_COMMON_MSGRINGS 2
30#define BRCMF_NROF_D2H_COMMON_MSGRINGS 332#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 { · 63 unmodified lines
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
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c+145−236
@@ -32,6 +32,7 @@ · 31 unmodified lines
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 @@ · 3 unmodified lines
41#include "common.h"42#include "common.h"
42 43
43#define BRCMF_SCAN_IE_LEN_MAX 204844#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 147#define WPA_OUI_TYPE 1
@@ -768,12 +759,12 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, · 711 unmodified lines
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 scan762 * 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: · 311 unmodified lines
1091}1082}
1092 1083
1093static s321084static 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, · 1 unmodified line
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, · 73 unmodified lines
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) · 1836 unmodified lines
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) · 16 unmodified lines
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, · 76 unmodified lines
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, · 39 unmodified lines
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) · 18 unmodified lines
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 supplicant3284/* 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 reported3285 * (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 the3286 * 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, · 7 unmodified lines
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, · 19 unmodified lines
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 int3368static 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) · 2929 unmodified lines
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
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h+2−2
@@ -271,7 +271,7 @@ struct brcmf_cfg80211_wowl { · 270 unmodified lines
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 { · 25 unmodified lines
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;
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h+23−0
@@ -131,6 +131,7 @@ · 130 unmodified lines
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 1136#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)
@@ -718,6 +719,21 @@ struct brcmf_pno_param_le { · 581 unmodified lines
718 __le32 slow_freq;719 __le32 slow_freq;
719};720};
720 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
721/**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 *
@@ -769,6 +785,13 @@ struct brcmf_pno_scanresults_le { · 45 unmodified lines
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 *
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c+18−20
@@ -87,11 +87,6 @@ struct msgbuf_common_hdr { · 86 unmodified lines
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 { · 129 unmodified lines
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, · 376 unmodified lines
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) · 143 unmodified lines
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) · 99 unmodified lines
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, · 301 unmodified lines
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, · 21 unmodified lines
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) · 98 unmodified lines
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) · 35 unmodified lines
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) · 71 unmodified lines
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) · 6 unmodified lines
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) · 29 unmodified lines
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) · 14 unmodified lines
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
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h+4−0
@@ -31,6 +31,10 @@ · 30 unmodified lines
31#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 3231#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 32
32#define BRCMF_H2D_TXFLOWRING_ITEMSIZE 4832#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);
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c+102−69
@@ -135,7 +135,7 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { · 134 unmodified lines
135 BRCMF_PCIE_MB_INT_D2H3_DB1)135 BRCMF_PCIE_MB_INT_D2H3_DB1)
136 136
137#define BRCMF_PCIE_MIN_SHARED_VERSION 5137#define BRCMF_PCIE_MIN_SHARED_VERSION 5
138#define BRCMF_PCIE_MAX_SHARED_VERSION 5138#define BRCMF_PCIE_MAX_SHARED_VERSION 6
139#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF139#define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF
140#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000140#define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000
141#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000141#define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000
@@ -166,17 +166,6 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { · 24 unmodified lines
166#define BRCMF_RING_MEM_SZ 16166#define BRCMF_RING_MEM_SZ 16
167#define BRCMF_RING_STATE_SZ 8167#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 255169#define BRCMF_DEF_MAX_RXBUFPOST 255
181 170
182#define BRCMF_CONSOLE_BUFADDR_OFFSET 8171#define BRCMF_CONSOLE_BUFADDR_OFFSET 8
@@ -231,7 +220,9 @@ struct brcmf_pcie_shared_info { · 48 unmodified lines
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 { · 3 unmodified lines
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 { · 37 unmodified lines
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) · 764 unmodified lines
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) · 3 unmodified lines
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) · 6 unmodified lines
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) · 24 unmodified lines
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, · 176 unmodified lines
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, · 287 unmodified lines
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
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c+242−0
@@ -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
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h+40−0
@@ -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 */
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c+1−0
@@ -621,6 +621,7 @@ static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { · 620 unmodified lines
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),
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_qmath.c+3−2
@@ -179,7 +179,7 @@ s16 qm_norm32(s32 op) · 178 unmodified lines
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[] = { · 26 unmodified lines
212 29717,212 29717,
213 30498,213 30498,
214 31267,214 31267,
215 32024215 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 */
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h+1−0
@@ -36,6 +36,7 @@ · 35 unmodified lines
36#define BRCM_CC_4330_CHIP_ID 0x433036#define BRCM_CC_4330_CHIP_ID 0x4330
37#define BRCM_CC_4334_CHIP_ID 0x433437#define BRCM_CC_4334_CHIP_ID 0x4334
38#define BRCM_CC_43340_CHIP_ID 4334038#define BRCM_CC_43340_CHIP_ID 43340
39#define BRCM_CC_43341_CHIP_ID 43341
39#define BRCM_CC_43362_CHIP_ID 4336240#define BRCM_CC_43362_CHIP_ID 43362
40#define BRCM_CC_4335_CHIP_ID 0x433541#define BRCM_CC_4335_CHIP_ID 0x4335
41#define BRCM_CC_4339_CHIP_ID 0x433942#define BRCM_CC_4339_CHIP_ID 0x4339
drivers/net/wireless/marvell/mwifiex/cfg80211.c+10−2
@@ -2143,6 +2143,16 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, · 2142 unmodified lines
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, · 1831 unmodified lines
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);
drivers/net/wireless/marvell/mwifiex/fw.h+1−0
@@ -219,6 +219,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { · 218 unmodified lines
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) | \
drivers/net/wireless/marvell/mwifiex/main.c+0−3
@@ -518,7 +518,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) · 517 unmodified lines
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) · 51 unmodified lines
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,
drivers/net/wireless/marvell/mwifiex/main.h+7−2
@@ -1424,8 +1424,13 @@ static inline void mwifiex_disable_wake(struct mwifiex_adapter *adapter) · 1423 unmodified lines
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
drivers/net/wireless/marvell/mwifiex/pcie.c+14−3
@@ -135,6 +135,7 @@ static int mwifiex_pcie_suspend(struct device *dev) · 134 unmodified lines
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, · 1909 unmodified lines
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, · 5 unmodified lines
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
drivers/net/wireless/marvell/mwifiex/scan.c+3−5
@@ -827,7 +827,6 @@ mwifiex_config_scan(struct mwifiex_private *priv, · 826 unmodified lines
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, · 271 unmodified lines
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}
drivers/net/wireless/marvell/mwifiex/sdio.c+1−5
@@ -186,9 +186,7 @@ static int mwifiex_sdio_resume(struct device *dev) · 185 unmodified lines
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) · 103 unmodified lines
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, · 832 unmodified lines
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, · 14 unmodified lines
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"
drivers/net/wireless/marvell/mwifiex/sta_cmd.c+25−13
@@ -1746,7 +1746,6 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv, · 1745 unmodified lines
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, · 11 unmodified lines
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, · 131 unmodified lines
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, · 7 unmodified lines
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) · 287 unmodified lines
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) · 106 unmodified lines
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 */
drivers/net/wireless/marvell/mwifiex/usb.c+1−2
@@ -379,7 +379,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf, · 378 unmodified lines
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, · 4 unmodified lines
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
drivers/net/wireless/mediatek/mt7601u/init.c+7−7
@@ -293,13 +293,13 @@ static void mt7601u_mac_stop_hw(struct mt7601u_dev *dev) · 292 unmodified lines
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
drivers/net/wireless/mediatek/mt7601u/regs.h+3−0
@@ -192,6 +192,9 @@ · 191 unmodified lines
192#define MT_BCN_OFFSET_BASE 0x041c192#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 0x0500198#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)
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h+15−12
@@ -1337,10 +1337,11 @@ struct rtl8xxxu_fileops { · 1336 unmodified lines
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); · 87 unmodified lines
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;
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c+1−1
@@ -1556,7 +1556,7 @@ exit: · 1555 unmodified lines
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;
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c+75−36
@@ -4372,6 +4372,13 @@ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv, · 4371 unmodified lines
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, · 5 unmodified lines
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, · 370 unmodified lines
4759 * This format is used on 8188cu/8192cu/8723au4767 * This format is used on 8188cu/8192cu/8723au
4760 */4768 */
4761void4769void
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, · 24 unmodified lines
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 tell4824 */
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, · 2 unmodified lines
4813 * This format is used on 8192eu/8723bu4837 * This format is used on 8192eu/8723bu
4814 */4838 */
4815void4839void
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, · 20 unmodified lines
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 tell4893 * 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, · 3 unmodified lines
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, · 20 unmodified lines
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, · 47 unmodified lines
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, · 4 unmodified lines
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
drivers/net/wireless/realtek/rtlwifi/base.c+4−4
@@ -1303,12 +1303,13 @@ EXPORT_SYMBOL_GPL(rtl_action_proc); · 1302 unmodified lines
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, · 66 unmodified lines
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
drivers/net/wireless/realtek/rtlwifi/core.c+3−6
@@ -1150,10 +1150,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, · 1149 unmodified lines
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, · 271 unmodified lines
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);
drivers/net/wireless/realtek/rtlwifi/pci.c+5−9
@@ -659,11 +659,9 @@ tx_status_ok: · 658 unmodified lines
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: · 244 unmodified lines
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) {
drivers/net/wireless/realtek/rtlwifi/ps.c+28−8
@@ -407,8 +407,8 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) · 406 unmodified lines
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) · 29 unmodified lines
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) · 23 unmodified lines
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) · 186 unmodified lines
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 else672 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,
drivers/net/wireless/rsi/rsi_91x_mac80211.c+155−1
@@ -275,6 +275,8 @@ static int rsi_mac80211_start(struct ieee80211_hw *hw) · 274 unmodified lines
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) · 107 unmodified lines
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 &&
@@ -408,6 +410,34 @@ static int rsi_channel_change(struct ieee80211_hw *hw) · 13 unmodified lines
408 return status;410 return status;
409}411}
410 412
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
411/**441/**
412 * rsi_mac80211_config() - This function is a handler for configuration442 * rsi_mac80211_config() - This function is a handler for configuration
413 * requests. The stack calls this function to443 * requests. The stack calls this function to
@@ -429,6 +459,12 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw, · 15 unmodified lines
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, · 36 unmodified lines
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, · 531 unmodified lines
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, · 3 unmodified lines
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 = { · 12 unmodified lines
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) · 58 unmodified lines
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;
drivers/net/wireless/rsi/rsi_91x_mgmt.c+124−5
@@ -913,7 +913,8 @@ int rsi_band_check(struct rsi_common *common) · 912 unmodified lines
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) · 8 unmodified lines
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) · 291 unmodified lines
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.
drivers/net/wireless/rsi/rsi_main.h+4−0
@@ -204,6 +204,9 @@ struct rsi_common { · 203 unmodified lines
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 { · 10 unmodified lines
220 struct rsi_debugfs *dfsentry;223 struct rsi_debugfs *dfsentry;
221 u8 num_debugfs_entries;224 u8 num_debugfs_entries;
222#endif225#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);
drivers/net/wireless/rsi/rsi_mgmt.h+21−2
@@ -140,6 +140,19 @@ · 139 unmodified lines
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 = 2158 AP_OPMODE = 2
@@ -190,7 +203,9 @@ enum cmd_frame_type { · 44 unmodified lines
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_PKT206 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, · 102 unmodified lines
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); · 7 unmodified lines
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#endif335#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t