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
295295 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
296296 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) },
297297 { 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) },
298299 { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_FOXCONN, 0xe092) },
299300 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) },
300301 { 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
326326 [ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
327327 [ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",
328328 [ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war",
329+ [ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST] = "allows-mesh-bcast",
329330 };
330331
331332 static 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
15361537 switch (ar->state) {
15371538 case ATH10K_STATE_ON:
15381539 ar->state = ATH10K_STATE_RESTARTING;
1539− ath10k_hif_stop(ar);
1540+ ath10k_halt(ar);
15401541 ath10k_scan_finish(ar);
15411542 ieee80211_restart_hw(ar->hw);
15421543 break;
@@ -1857,7 +1858,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, · 314 unmodified lines
18571858 goto err_wmi_detach;
18581859 }
18591860
1860− status = ath10k_htt_tx_alloc(&ar->htt);
1861+ status = ath10k_htt_tx_start(&ar->htt);
18611862 if (status) {
18621863 ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
18631864 goto err_wmi_detach;
@@ -2052,7 +2053,7 @@ void ath10k_core_stop(struct ath10k *ar) · 188 unmodified lines
20522053 ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
20532054
20542055 ath10k_hif_stop(ar);
2055− ath10k_htt_tx_free(&ar->htt);
2056+ ath10k_htt_tx_stop(&ar->htt);
20562057 ath10k_htt_rx_free(&ar->htt);
20572058 ath10k_wmi_detach(ar);
20582059 }
@@ -2385,6 +2386,7 @@ void ath10k_core_destroy(struct ath10k *ar) · 326 unmodified lines
23852386 destroy_workqueue(ar->workqueue_aux);
23862387
23872388 ath10k_debug_destroy(ar);
2389+ ath10k_htt_tx_destroy(&ar->htt);
23882390 ath10k_wmi_free_host_mem(ar);
23892391 ath10k_mac_destroy(ar);
23902392 }
drivers/net/wireless/ath/ath10k/core.h+24−0
@@ -337,6 +337,7 @@ struct ath10k_sta { · 336 unmodified lines
337337 u32 nss;
338338 u32 smps;
339339 u16 peer_id;
340+ struct rate_info txrate;
340341
341342 struct work_struct update_wk;
342343
@@ -562,6 +563,13 @@ enum ath10k_fw_features { · 219 unmodified lines
562563 */
563564 ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR = 15,
564565
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+
565573 /* keep last */
566574 ATH10K_FW_FEATURE_COUNT,
567575 };
@@ -693,6 +701,21 @@ struct ath10k_fw_components { · 125 unmodified lines
693701 struct ath10k_fw_file fw_file;
694702 };
695703
704+struct 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+
696719 struct ath10k {
697720 struct ath_common ath_common;
698721 struct ieee80211_hw *hw;
@@ -906,6 +929,7 @@ struct ath10k { · 207 unmodified lines
906929
907930 struct ath10k_thermal thermal;
908931 struct ath10k_wow wow;
932+ struct ath10k_per_peer_tx_stats peer_tx_stats;
909933
910934 /* NAPI */
911935 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
7777
7878 sinfo->rx_duration = arsta->rx_duration;
7979 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;
8093 }
8194
8295 static 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
137137 HTT_T2H_MSG_TYPE_STATS_NOUPLOAD,
138138 [HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND] =
139139 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
140+ [HTT_10_4_T2H_MSG_TYPE_PEER_STATS] =
141+ HTT_T2H_MSG_TYPE_PEER_STATS,
140142 };
141143
142144 int 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
419419 HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD = 0x18,
420420 /* 0x19 to 0x2f are reserved */
421421 HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND = 0x30,
422+ HTT_10_4_T2H_MSG_TYPE_PEER_STATS = 0x31,
422423 /* keep this last */
423424 HTT_10_4_T2H_NUM_MSGS
424425 };
@@ -453,6 +454,7 @@ enum htt_t2h_msg_type { · 28 unmodified lines
453454 HTT_T2H_MSG_TYPE_TX_FETCH_IND,
454455 HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM,
455456 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
457+ HTT_T2H_MSG_TYPE_PEER_STATS,
456458 /* keep this last */
457459 HTT_T2H_NUM_MSGS
458460 };
@@ -1470,6 +1472,28 @@ struct htt_channel_change { · 1011 unmodified lines
14701472 __le32 phymode;
14711473 } __packed;
14721474
1475+struct 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+
1490+struct htt_peer_tx_stats {
1491+ u8 num_ppdu;
1492+ u8 ppdu_len;
1493+ u8 version;
1494+ u8 payload[0];
1495+} __packed;
1496+
14731497 union htt_rx_pn_t {
14741498 /* WEP: 24-bit PN */
14751499 u32 pn24;
@@ -1521,6 +1545,7 @@ struct htt_resp { · 45 unmodified lines
15211545 struct htt_tx_fetch_confirm tx_fetch_confirm;
15221546 struct htt_tx_mode_switch_ind tx_mode_switch_ind;
15231547 struct htt_channel_change chan_change;
1548+ struct htt_peer_tx_stats peer_tx_stats;
15241549 };
15251550 } __packed;
15261551
@@ -1692,6 +1717,8 @@ struct ath10k_htt { · 165 unmodified lines
16921717 enum htt_tx_mode_switch_mode mode;
16931718 enum htt_q_depth_type type;
16941719 } tx_q_state;
1720+
1721+ bool tx_mem_allocated;
16951722 };
16961723
16971724 #define RX_HTT_HDR_STATUS_LEN 64
@@ -1754,7 +1781,9 @@ int ath10k_htt_connect(struct ath10k_htt *htt); · 56 unmodified lines
17541781 int ath10k_htt_init(struct ath10k *ar);
17551782 int ath10k_htt_setup(struct ath10k_htt *htt);
17561783
1757−int ath10k_htt_tx_alloc(struct ath10k_htt *htt);
1784+int ath10k_htt_tx_start(struct ath10k_htt *htt);
1785+void ath10k_htt_tx_stop(struct ath10k_htt *htt);
1786+void ath10k_htt_tx_destroy(struct ath10k_htt *htt);
17581787 void ath10k_htt_tx_free(struct ath10k_htt *htt);
17591788
17601789 int 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
21942194 dev_kfree_skb_any(skb);
21952195 }
21962196
2197+static 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+
2211+static void
2212+ath10k_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+
2264+static 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+
2314+out:
2315+ spin_unlock_bh(&ar->data_lock);
2316+ rcu_read_unlock();
2317+}
2318+
21972319 bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
21982320 {
21992321 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
23542476 case HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND:
23552477 ath10k_htt_rx_tx_mode_switch_ind(ar, skb);
23562478 break;
2479+ case HTT_T2H_MSG_TYPE_PEER_STATS:
2480+ ath10k_htt_fetch_peer_stats(ar, skb);
2481+ break;
23572482 case HTT_T2H_MSG_TYPE_EN_STATS:
23582483 default:
23592484 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
350350 return ret;
351351 }
352352
353−int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
353+static int ath10k_htt_tx_alloc_buf(struct ath10k_htt *htt)
354354 {
355355 struct ath10k *ar = htt->ar;
356356 int ret;
357357
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−
364358 ret = ath10k_htt_tx_alloc_cont_txbuf(htt);
365359 if (ret) {
366360 ath10k_err(ar, "failed to alloc cont tx buffer: %d\n", ret);
367− goto free_idr_pending_tx;
361+ return ret;
368362 }
369363
370364 ret = ath10k_htt_tx_alloc_cont_frag_desc(htt);
@@ -396,6 +390,31 @@ free_frag_desc: · 25 unmodified lines
396390 free_txbuf:
397391 ath10k_htt_tx_free_cont_txbuf(htt);
398392
393+ return ret;
394+}
395+
396+int 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+
399418 free_idr_pending_tx:
400419 idr_destroy(&htt->pending_tx);
401420
@@ -418,15 +437,28 @@ static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx) · 16 unmodified lines
418437 return 0;
419438 }
420439
421−void ath10k_htt_tx_free(struct ath10k_htt *htt)
440+void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
422441 {
423− idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
424− idr_destroy(&htt->pending_tx);
442+ if (!htt->tx_mem_allocated)
443+ return;
425444
426445 ath10k_htt_tx_free_cont_txbuf(htt);
427446 ath10k_htt_tx_free_txq(htt);
428447 ath10k_htt_tx_free_cont_frag_desc(htt);
429448 ath10k_htt_tx_free_txdone_fifo(htt);
449+ htt->tx_mem_allocated = false;
450+}
451+
452+void 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+
458+void ath10k_htt_tx_free(struct ath10k_htt *htt)
459+{
460+ ath10k_htt_tx_stop(htt);
461+ ath10k_htt_tx_destroy(htt);
430462 }
431463
432464 void 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
11671167 return false;
11681168
11691169 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)) ||
11711173 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
11721174 }
11731175
@@ -4449,7 +4451,6 @@ static int ath10k_start(struct ieee80211_hw *hw) · 3275 unmodified lines
44494451 ar->state = ATH10K_STATE_ON;
44504452 break;
44514453 case ATH10K_STATE_RESTARTING:
4452− ath10k_halt(ar);
44534454 ar->state = ATH10K_STATE_RESTARTED;
44544455 break;
44554456 case ATH10K_STATE_ON:
@@ -6976,40 +6977,28 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw, · 2520 unmodified lines
69766977 ieee80211_queue_work(hw, &arsta->update_wk);
69776978 }
69786979
6979−static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6980−{
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−
6989−static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6990− u64 tsf)
6980+static void ath10k_offset_tsf(struct ieee80211_hw *hw,
6981+ struct ieee80211_vif *vif, s64 tsf_offset)
69916982 {
69926983 struct ath10k *ar = hw->priv;
69936984 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;
69956986 int ret;
69966987
6997− /* Workaround:
6998− *
6999− * Given tsf argument is entire TSF value, but firmware accepts
7000− * only TSF offset to current TSF.
7001− *
7002− * get_tsf function is used to get offset value, however since
7003− * ath10k_get_tsf is not implemented properly, it will return 0 always.
7004− * Luckily all the caller functions to set_tsf, as of now, also rely on
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);
6988+ if (tsf_offset < 0) {
6989+ vdev_param = ar->wmi.vdev_param->dec_tsf;
6990+ offset = -tsf_offset;
6991+ } else {
6992+ vdev_param = ar->wmi.vdev_param->inc_tsf;
6993+ offset = tsf_offset;
6994+ }
6995+
70096996 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
7010− vdev_param, tsf_offset);
6997+ vdev_param, offset);
6998+
70116999 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);
70137002 }
70147003
70157004 static int ath10k_ampdu_action(struct ieee80211_hw *hw,
@@ -7474,8 +7463,7 @@ static const struct ieee80211_ops ath10k_ops = { · 458 unmodified lines
74747463 .get_survey = ath10k_get_survey,
74757464 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
74767465 .sta_rc_update = ath10k_sta_rc_update,
7477− .get_tsf = ath10k_get_tsf,
7478− .set_tsf = ath10k_set_tsf,
7466+ .offset_tsf = ath10k_offset_tsf,
74797467 .ampdu_action = ath10k_ampdu_action,
74807468 .get_et_sset_count = ath10k_debug_get_et_sset_count,
74817469 .get_et_stats = ath10k_debug_get_et_stats,
@@ -8006,6 +7994,7 @@ int ath10k_mac_register(struct ath10k *ar) · 524 unmodified lines
80067994 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
80077995 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
80087996 ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
7997+ ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
80097998
80107999 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
80118000 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
660660 struct sk_buff *skb;
661661 u32 cmd_id;
662662
663+ if (!ar->wmi.ops->gen_vdev_spectral_conf)
664+ return -EOPNOTSUPP;
665+
663666 skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg);
664667 if (IS_ERR(skb))
665668 return PTR_ERR(skb);
@@ -675,6 +678,9 @@ ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, · 9 unmodified lines
675678 struct sk_buff *skb;
676679 u32 cmd_id;
677680
681+ if (!ar->wmi.ops->gen_vdev_spectral_enable)
682+ return -EOPNOTSUPP;
683+
678684 skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger,
679685 enable);
680686 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
13131313 cmd->regd = __cpu_to_le32(rd);
13141314 cmd->regd_2ghz = __cpu_to_le32(rd2g);
13151315 cmd->regd_5ghz = __cpu_to_le32(rd5g);
1316− cmd->conform_limit_2ghz = __cpu_to_le32(rd2g);
1317− cmd->conform_limit_5ghz = __cpu_to_le32(rd5g);
1316+ cmd->conform_limit_2ghz = __cpu_to_le32(ctl2g);
1317+ cmd->conform_limit_5ghz = __cpu_to_le32(ctl5g);
13181318
13191319 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
13201320 return skb;
@@ -3136,6 +3136,76 @@ ath10k_wmi_tlv_op_gen_echo(struct ath10k *ar, u32 value) · 1815 unmodified lines
31363136 return skb;
31373137 }
31383138
3139+static struct sk_buff *
3140+ath10k_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+
3182+static struct sk_buff *
3183+ath10k_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+
31393209 /****************/
31403210 /* TLV mappings */
31413211 /****************/
@@ -3464,7 +3534,6 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { · 322 unmodified lines
34643534 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
34653535 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
34663536 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
3467− .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
34683537 };
34693538
34703539 static const struct wmi_ops wmi_tlv_ops = {
@@ -3542,6 +3611,8 @@ static const struct wmi_ops wmi_tlv_ops = { · 71 unmodified lines
35423611 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
35433612 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
35443613 .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,
35453616 };
35463617
35473618 static 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
785785 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
786786 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
787787 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
788− .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
789788 };
790789
791790 /* 10.X WMI VDEV param map */
@@ -861,7 +860,6 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = { · 69 unmodified lines
861860 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
862861 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
863862 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
864− .set_tsf = WMI_VDEV_PARAM_UNSUPPORTED,
865863 };
866864
867865 static 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
936934 .meru_vc = WMI_VDEV_PARAM_UNSUPPORTED,
937935 .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
938936 .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
939− .set_tsf = WMI_10X_VDEV_PARAM_TSF_INCREMENT,
940937 };
941938
942939 static 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
10121009 .meru_vc = WMI_10_4_VDEV_PARAM_MERU_VC,
10131010 .rx_decap_type = WMI_10_4_VDEV_PARAM_RX_DECAP_TYPE,
10141011 .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,
10161014 };
10171015
10181016 static 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
44894487 if (!num_units)
44904488 return -ENOMEM;
44914489
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);
44934491 if (dma_mapping_error(ar->dev, paddr)) {
44944492 kfree(vaddr);
44954493 return -ENOMEM;
drivers/net/wireless/ath/ath10k/wmi.h+16−2
@@ -4603,9 +4603,17 @@ enum wmi_rate_preamble { · 4602 unmodified lines
46034603
46044604 #define ATH10K_HW_NSS(rate) (1 + (((rate) >> 4) & 0x3))
46054605 #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) \
46074611 (((preamble) << 6) | ((nss) << 4) | (rate))
46084612
4613+#define VHT_MCS_NUM 10
4614+#define VHT_BW_NUM 4
4615+#define VHT_NSS_NUM 4
4616+
46094617 /* Value to disable fixed rate setting */
46104618 #define WMI_FIXED_RATE_NONE (0xff)
46114619
@@ -4676,7 +4684,8 @@ struct wmi_vdev_param_map { · 64 unmodified lines
46764684 u32 meru_vc;
46774685 u32 rx_decap_type;
46784686 u32 bw_nss_ratemask;
4679− u32 set_tsf;
4687+ u32 inc_tsf;
4688+ u32 dec_tsf;
46804689 };
46814690
46824691 #define WMI_VDEV_PARAM_UNSUPPORTED 0
@@ -5009,6 +5018,11 @@ enum wmi_10_4_vdev_param { · 326 unmodified lines
50095018 WMI_10_4_VDEV_PARAM_STA_KICKOUT,
50105019 WMI_10_4_VDEV_PARAM_CAPABILITIES,
50115020 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,
50125026 };
50135027
50145028 #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
6666
6767 #include <linux/seq_file.h>
6868 #include <linux/list.h>
69−#include <linux/vmalloc.h>
7069 #include "debug.h"
7170 #include "ath5k.h"
7271 #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
6262 return false;
6363 }
6464
65−static struct ath_bus_ops ath_ahb_bus_ops = {
65+static const struct ath_bus_ops ath_ahb_bus_ops = {
6666 .ath_bus_type = ATH_AHB,
6767 .read_cachesize = ath_ahb_read_cachesize,
6868 .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
528528 if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
529529 return 0;
530530
531+ if (!spec_priv->rfs_chan_spec_scan)
532+ return 1;
533+
531534 /* Output buffers are full, no need to process anything
532535 * since there is no space to put the result anyway
533536 */
@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = { · 538 unmodified lines
10721075
10731076 void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
10741077 {
1075− if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS)) {
1078+ if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
10761079 relay_close(spec_priv->rfs_chan_spec_scan);
10771080 spec_priv->rfs_chan_spec_scan = NULL;
10781081 }
@@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, · 7 unmodified lines
10861089 debugfs_phy,
10871090 1024, 256, &rfs_spec_scan_cb,
10881091 NULL);
1092+ if (!spec_priv->rfs_chan_spec_scan)
1093+ return;
1094+
10891095 debugfs_create_file("spectral_scan_ctl",
10901096 S_IRUSR | S_IWUSR,
10911097 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
997997 err = usb_control_msg(hif_dev->udev,
998998 usb_sndctrlpipe(hif_dev->udev, 0),
999999 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
1000− addr >> 8, 0, buf, transfer, HZ);
1000+ addr >> 8, 0, buf, transfer,
1001+ USB_MSG_TIMEOUT);
10011002 if (err < 0) {
10021003 kfree(buf);
10031004 return err;
@@ -1020,7 +1021,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) · 16 unmodified lines
10201021 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
10211022 FIRMWARE_DOWNLOAD_COMP,
10221023 0x40 | USB_DIR_OUT,
1023− firm_offset >> 8, 0, NULL, 0, HZ);
1024+ firm_offset >> 8, 0, NULL, 0, USB_MSG_TIMEOUT);
10241025 if (err)
10251026 return -EIO;
10261027
@@ -1249,7 +1250,7 @@ static int send_eject_command(struct usb_interface *interface) · 222 unmodified lines
12491250
12501251 dev_info(&udev->dev, "Ejecting storage device...\n");
12511252 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
1252− cmd, 31, NULL, 2000);
1253+ cmd, 31, NULL, 2 * USB_MSG_TIMEOUT);
12531254 kfree(cmd);
12541255 if (r)
12551256 return r;
@@ -1314,7 +1315,7 @@ static void ath9k_hif_usb_reboot(struct usb_device *udev) · 58 unmodified lines
13141315 return;
13151316
13161317 ret = usb_interrupt_msg(udev, usb_sndintpipe(udev, USB_REG_OUT_PIPE),
1317− buf, 4, NULL, HZ);
1318+ buf, 4, NULL, USB_MSG_TIMEOUT);
13181319 if (ret)
13191320 dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n");
13201321
drivers/net/wireless/ath/ath9k/hif_usb.h+2−0
@@ -71,6 +71,8 @@ extern int htc_use_dev_fw; · 70 unmodified lines
7171 #define USB_REG_IN_PIPE 3
7272 #define USB_REG_OUT_PIPE 4
7373
74+#define USB_MSG_TIMEOUT 1000 /* (ms) */
75+
7476 #define HIF_USB_MAX_RXPIPES 2
7577 #define HIF_USB_MAX_TXPIPES 4
7678
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
27922792 WARN_ON(1);
27932793 }
27942794
2795− return val;
2795+ return !!val;
27962796 }
27972797 EXPORT_SYMBOL(ath9k_hw_gpio_get);
27982798
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
867867 * can be dropped.
868868 */
869869 if (rx_stats->rs_status & ATH9K_RXERR_PHY) {
870− ath9k_dfs_process_phyerr(sc, hdr, rx_stats, rx_status->mactime);
871− if (ath_cmn_process_fft(&sc->spec_priv, hdr, rx_stats, rx_status->mactime))
870+ /*
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)) {
872883 RX_STAT_INC(rx_spectral);
873−
884+ }
874885 return -EINVAL;
875886 }
876887
drivers/net/wireless/ath/wil6210/cfg80211.c+104−25
@@ -354,14 +354,6 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, · 353 unmodified lines
354354 wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
355355 __func__, wdev, wdev->iftype);
356356
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−
365357 /* check we are client side */
366358 switch (wdev->iftype) {
367359 case NL80211_IFTYPE_STATION:
@@ -378,12 +370,24 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, · 10 unmodified lines
378370 return -EBUSY;
379371 }
380372
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+
381384 /* social scan on P2P_DEVICE is handled as p2p search */
382385 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
383386 wil_p2p_is_social_scan(request)) {
384387 if (!wil->p2p.p2p_dev_started) {
385388 wil_err(wil, "P2P search requested on stopped P2P device\n");
386− return -EIO;
389+ rc = -EIO;
390+ goto out;
387391 }
388392 wil->scan_request = request;
389393 wil->radio_wdev = wdev;
@@ -392,7 +396,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, · 2 unmodified lines
392396 wil->radio_wdev = wil_to_wdev(wil);
393397 wil->scan_request = NULL;
394398 }
395− return rc;
399+ goto out;
396400 }
397401
398402 (void)wil_p2p_stop_discovery(wil);
@@ -415,7 +419,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, · 16 unmodified lines
415419
416420 if (rc) {
417421 wil_err(wil, "set SSID for scan request failed: %d\n", rc);
418− return rc;
422+ goto out;
419423 }
420424
421425 wil->scan_request = request;
@@ -448,7 +452,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, · 26 unmodified lines
448452
449453 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie);
450454 if (rc)
451− goto out;
455+ goto out_restore;
452456
453457 if (wil->discovery_mode && cmd.cmd.scan_type == WMI_ACTIVE_SCAN) {
454458 cmd.cmd.discovery_mode = 1;
@@ -459,16 +463,45 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, · 4 unmodified lines
459463 rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
460464 cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
461465
462−out:
466+out_restore:
463467 if (rc) {
464468 del_timer_sync(&wil->scan_timer);
465469 wil->radio_wdev = wil_to_wdev(wil);
466470 wil->scan_request = NULL;
467471 }
468−
472+out:
473+ mutex_unlock(&wil->mutex);
469474 return rc;
470475 }
471476
477+static 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+
500+out:
501+ mutex_unlock(&wil->p2p_wdev_mutex);
502+ mutex_unlock(&wil->mutex);
503+}
504+
472505 static void wil_print_crypto(struct wil6210_priv *wil,
473506 struct cfg80211_crypto_settings *c)
474507 {
@@ -674,6 +707,26 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy, · 199 unmodified lines
674707 return rc;
675708 }
676709
710+static 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+
677730 int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
678731 struct cfg80211_mgmt_tx_params *params,
679732 u64 *cookie)
@@ -940,16 +993,8 @@ static int wil_remain_on_channel(struct wiphy *wiphy, · 260 unmodified lines
940993 wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n",
941994 __func__, chan->center_freq, duration, wdev->iftype);
942995
943− rc = wil_p2p_listen(wil, duration, chan, cookie);
944− if (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;
996+ rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
997+ return rc;
953998 }
954999
9551000 static 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
14191464
14201465 wil_dbg_misc(wil, "%s: entered\n", __func__);
14211466 mutex_lock(&wil->mutex);
1467+ mutex_lock(&wil->p2p_wdev_mutex);
14221468 wil_p2p_stop_radio_operations(wil);
14231469 p2p->p2p_dev_started = 0;
1470+ mutex_unlock(&wil->p2p_wdev_mutex);
14241471 mutex_unlock(&wil->mutex);
14251472 }
14261473
1474+static 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+
14271502 static struct cfg80211_ops wil_cfg80211_ops = {
14281503 .add_virtual_intf = wil_cfg80211_add_iface,
14291504 .del_virtual_intf = wil_cfg80211_del_iface,
14301505 .scan = wil_cfg80211_scan,
1506+ .abort_scan = wil_cfg80211_abort_scan,
14311507 .connect = wil_cfg80211_connect,
14321508 .disconnect = wil_cfg80211_disconnect,
1509+ .set_wiphy_params = wil_cfg80211_set_wiphy_params,
14331510 .change_virtual_intf = wil_cfg80211_change_iface,
14341511 .get_station = wil_cfg80211_get_station,
14351512 .dump_station = wil_cfg80211_dump_station,
@@ -1450,6 +1527,7 @@ static struct cfg80211_ops wil_cfg80211_ops = { · 14 unmodified lines
14501527 /* P2P device */
14511528 .start_p2p_device = wil_cfg80211_start_p2p_device,
14521529 .stop_p2p_device = wil_cfg80211_stop_p2p_device,
1530+ .set_power_mgmt = wil_cfg80211_set_power_mgmt,
14531531 };
14541532
14551533 static void wil_wiphy_init(struct wiphy *wiphy)
@@ -1466,7 +1544,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) · 10 unmodified lines
14661544 BIT(NL80211_IFTYPE_MONITOR);
14671545 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
14681546 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;
14701549 dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
14711550 __func__, wiphy->flags);
14721551 wiphy->probe_resp_offload =
drivers/net/wireless/ath/wil6210/main.c+66−34
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include "boot_loader.h"
2525
2626 #define WAIT_FOR_HALP_VOTE_MS 100
27+#define WAIT_FOR_SCAN_ABORT_MS 1000
2728
2829 bool debug_fw; /* = false; */
2930 module_param(debug_fw, bool, S_IRUGO);
@@ -213,7 +214,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) · 183 unmodified lines
213214 memset(&sta->stats, 0, sizeof(sta->stats));
214215 }
215216
216−static bool wil_ap_is_connected(struct wil6210_priv *wil)
217+static bool wil_is_connected(struct wil6210_priv *wil)
217218 {
218219 int i;
219220
@@ -267,7 +268,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, · 47 unmodified lines
267268 case NL80211_IFTYPE_STATION:
268269 case NL80211_IFTYPE_P2P_CLIENT:
269270 wil_bcast_fini(wil);
270− netif_tx_stop_all_queues(ndev);
271+ wil_update_net_queues_bh(wil, NULL, true);
271272 netif_carrier_off(ndev);
272273
273274 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
283284 break;
284285 case NL80211_IFTYPE_AP:
285286 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);
287289 clear_bit(wil_status_fwconnected, wil->status);
290+ } else {
291+ wil_update_net_queues_bh(wil, NULL, false);
292+ }
288293 break;
289294 default:
290295 break;
@@ -384,18 +389,19 @@ static void wil_fw_error_worker(struct work_struct *work) · 93 unmodified lines
384389
385390 wil->last_fw_recovery = jiffies;
386391
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+
387399 mutex_lock(&wil->mutex);
388400 switch (wdev->iftype) {
389401 case NL80211_IFTYPE_STATION:
390402 case NL80211_IFTYPE_P2P_CLIENT:
391403 case NL80211_IFTYPE_MONITOR:
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 (0 != wil_wait_for_recovery(wil))
397− break;
398−
404+ /* silent recovery, upper layers will see disconnect */
399405 __wil_down(wil);
400406 __wil_up(wil);
401407 break;
@@ -512,10 +518,13 @@ int wil_priv_init(struct wil6210_priv *wil) · 110 unmodified lines
512518 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
513519 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker);
514520 INIT_WORK(&wil->probe_client_worker, wil_probe_client_worker);
521+ INIT_WORK(&wil->p2p.delayed_listen_work, wil_p2p_delayed_listen_work);
515522
516523 INIT_LIST_HEAD(&wil->pending_wmi_ev);
517524 INIT_LIST_HEAD(&wil->probe_client_pending);
518525 spin_lock_init(&wil->wmi_ev_lock);
526+ spin_lock_init(&wil->net_queue_lock);
527+ wil->net_queue_stopped = 1;
519528 init_waitqueue_head(&wil->wq);
520529
521530 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
@@ -571,6 +580,7 @@ void wil_priv_deinit(struct wil6210_priv *wil) · 49 unmodified lines
571580 cancel_work_sync(&wil->disconnect_worker);
572581 cancel_work_sync(&wil->fw_error_worker);
573582 cancel_work_sync(&wil->p2p.discovery_expired_work);
583+ cancel_work_sync(&wil->p2p.delayed_listen_work);
574584 mutex_lock(&wil->mutex);
575585 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
576586 mutex_unlock(&wil->mutex);
@@ -685,6 +695,19 @@ static int wil_target_reset(struct wil6210_priv *wil) · 108 unmodified lines
685695 return 0;
686696 }
687697
698+static 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+
688711 void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
689712 {
690713 le32_to_cpus(&r->base);
@@ -801,6 +824,34 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil) · 110 unmodified lines
801824 return 0;
802825 }
803826
827+void 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+
804855 /*
805856 * We reset all the structures, and we reset the UMAC.
806857 * 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
853904 mutex_unlock(&wil->wmi_mutex);
854905
855906 mutex_lock(&wil->p2p_wdev_mutex);
856− if (wil->scan_request) {
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− }
907+ wil_abort_scan(wil, false);
867908 mutex_unlock(&wil->p2p_wdev_mutex);
868909
869910 wil_mask_irq(wil);
@@ -940,6 +981,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) · 70 unmodified lines
940981 return rc;
941982 }
942983
984+ wil_collect_fw_info(wil);
985+
943986 if (wil->platform_ops.notify) {
944987 rc = wil->platform_ops.notify(wil->platform_handle,
945988 WIL_PLATFORM_EVT_FW_RDY);
@@ -1056,20 +1099,9 @@ int __wil_down(struct wil6210_priv *wil) · 110 unmodified lines
10561099 }
10571100 wil_enable_irq(wil);
10581101
1059− wil_p2p_stop_radio_operations(wil);
1060−
10611102 mutex_lock(&wil->p2p_wdev_mutex);
1062− if (wil->scan_request) {
1063− struct cfg80211_scan_info info = {
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− }
1103+ wil_p2p_stop_radio_operations(wil);
1104+ wil_abort_scan(wil, false);
10731105 mutex_unlock(&wil->p2p_wdev_mutex);
10741106
10751107 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
214214 netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
215215 WIL6210_NAPI_BUDGET);
216216
217− netif_tx_stop_all_queues(ndev);
217+ wil_update_net_queues_bh(wil, NULL, true);
218218
219219 rc = register_netdev(ndev);
220220 if (rc < 0) {
drivers/net/wireless/ath/wil6210/p2p.c+118−42
@@ -22,6 +22,43 @@ · 21 unmodified lines
2222 #define P2P_SEARCH_DURATION_MS 500
2323 #define P2P_DEFAULT_BI 100
2424
25+static 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));
54+out_stop:
55+ if (rc)
56+ wmi_stop_discovery(wil);
57+
58+out:
59+ return rc;
60+}
61+
2562 bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request)
2663 {
2764 return (request->n_channels == 1) &&
@@ -46,7 +83,7 @@ int wil_p2p_search(struct wil6210_priv *wil, · 18 unmodified lines
4683 wil_dbg_misc(wil, "%s: channel %d\n",
4784 __func__, P2P_DMG_SOCIAL_CHANNEL);
4885
49− mutex_lock(&wil->mutex);
86+ lockdep_assert_held(&wil->mutex);
5087
5188 if (p2p->discovery_started) {
5289 wil_err(wil, "%s: search failed. discovery already ongoing\n",
@@ -103,22 +140,19 @@ out_stop: · 50 unmodified lines
103140 wmi_stop_discovery(wil);
104141
105142 out:
106− mutex_unlock(&wil->mutex);
107143 return rc;
108144 }
109145
110−int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
111− struct ieee80211_channel *chan, u64 *cookie)
146+int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
147+ unsigned int duration, struct ieee80211_channel *chan,
148+ u64 *cookie)
112149 {
113150 struct wil_p2p_info *p2p = &wil->p2p;
114− u8 channel = P2P_DMG_SOCIAL_CHANNEL;
115151 int rc;
116152
117153 if (!chan)
118154 return -EINVAL;
119155
120− channel = chan->hw_value;
121−
122156 wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration);
123157
124158 mutex_lock(&wil->mutex);
@@ -129,35 +163,30 @@ int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration, · 4 unmodified lines
129163 goto out;
130164 }
131165
132− rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI);
133− if (rc) {
134− wil_err(wil, "%s: wmi_p2p_cfg failed\n", __func__);
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− }
166+ memcpy(&p2p->listen_chan, chan, sizeof(*chan));
167+ *cookie = ++p2p->cookie;
168+ p2p->listen_duration = duration;
143169
144− rc = wmi_start_listen(wil);
145− if (rc) {
146− wil_err(wil, "%s: wmi_start_listen failed\n", __func__);
147− goto out_stop;
170+ mutex_lock(&wil->p2p_wdev_mutex);
171+ if (wil->scan_request) {
172+ wil_dbg_misc(wil, "Delaying p2p listen until scan done\n");
173+ p2p->pending_listen_wdev = wdev;
174+ p2p->discovery_started = 1;
175+ rc = 0;
176+ mutex_unlock(&wil->p2p_wdev_mutex);
177+ goto out;
148178 }
179+ mutex_unlock(&wil->p2p_wdev_mutex);
149180
150− memcpy(&p2p->listen_chan, chan, sizeof(*chan));
151− *cookie = ++p2p->cookie;
181+ rc = wil_p2p_start_listen(wil);
182+ if (rc)
183+ goto out;
152184
153185 p2p->discovery_started = 1;
154− INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired);
155− mod_timer(&p2p->discovery_timer,
156− jiffies + msecs_to_jiffies(duration));
186+ wil->radio_wdev = wdev;
157187
158−out_stop:
159− if (rc)
160− wmi_stop_discovery(wil);
188+ cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
189+ GFP_KERNEL);
161190
162191 out:
163192 mutex_unlock(&wil->mutex);
@@ -170,9 +199,14 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) · 6 unmodified lines
170199 u8 started = p2p->discovery_started;
171200
172201 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+ }
174209 p2p->discovery_started = 0;
175− wmi_stop_discovery(wil);
176210 }
177211
178212 return started;
@@ -257,13 +291,59 @@ void wil_p2p_search_expired(struct work_struct *work) · 78 unmodified lines
257291 };
258292
259293 mutex_lock(&wil->p2p_wdev_mutex);
260− cfg80211_scan_done(wil->scan_request, &info);
261− wil->scan_request = NULL;
262− wil->radio_wdev = wil->wdev;
294+ if (wil->scan_request) {
295+ cfg80211_scan_done(wil->scan_request, &info);
296+ wil->scan_request = NULL;
297+ wil->radio_wdev = wil->wdev;
298+ }
263299 mutex_unlock(&wil->p2p_wdev_mutex);
264300 }
265301 }
266302
303+void 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+
343+out:
344+ mutex_unlock(&wil->mutex);
345+}
346+
267347 void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
268348 {
269349 struct wil_p2p_info *p2p = &wil->p2p;
@@ -272,8 +352,7 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) · 2 unmodified lines
272352 };
273353
274354 lockdep_assert_held(&wil->mutex);
275−
276− mutex_lock(&wil->p2p_wdev_mutex);
355+ lockdep_assert_held(&wil->p2p_wdev_mutex);
277356
278357 if (wil->radio_wdev != wil->p2p_wdev)
279358 goto out;
@@ -281,10 +360,8 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) · 1 unmodified line
281360 if (!p2p->discovery_started) {
282361 /* Regular scan on the p2p device */
283362 if (wil->scan_request &&
284− wil->scan_request->wdev == wil->p2p_wdev) {
285− cfg80211_scan_done(wil->scan_request, &info);
286− wil->scan_request = NULL;
287− }
363+ wil->scan_request->wdev == wil->p2p_wdev)
364+ wil_abort_scan(wil, true);
288365 goto out;
289366 }
290367
@@ -307,5 +384,4 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) · 16 unmodified lines
307384
308385 out:
309386 wil->radio_wdev = wil->wdev;
310− mutex_unlock(&wil->p2p_wdev_mutex);
311387 }
drivers/net/wireless/ath/wil6210/pmc.c+49−6
@@ -54,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil, · 53 unmodified lines
5454 struct pmc_ctx *pmc = &wil->pmc;
5555 struct device *dev = wil_to_dev(wil);
5656 struct wmi_pmc_cmd pmc_cmd = {0};
57+ int last_cmd_err = -ENOMEM;
5758
5859 mutex_lock(&pmc->lock);
5960
@@ -62,6 +63,29 @@ void wil_pmc_alloc(struct wil6210_priv *wil, · 2 unmodified lines
6263 wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__);
6364 goto no_release_err;
6465 }
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+ }
6589
6690 pmc->num_descriptors = num_descriptors;
6791 pmc->descriptor_size = descriptor_size;
@@ -189,7 +213,7 @@ release_pmc_skb_list: · 121 unmodified lines
189213 pmc->descriptors = NULL;
190214
191215 no_release_err:
192− pmc->last_cmd_status = -ENOMEM;
216+ pmc->last_cmd_status = last_cmd_err;
193217 mutex_unlock(&pmc->lock);
194218 }
195219
@@ -295,7 +319,7 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count, · 99 unmodified lines
295319 size_t retval = 0;
296320 unsigned long long idx;
297321 loff_t offset;
298− size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors;
322+ size_t pmc_size;
299323
300324 mutex_lock(&pmc->lock);
301325
@@ -306,6 +330,8 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count, · 4 unmodified lines
306330 return -EPERM;
307331 }
308332
333+ pmc_size = pmc->descriptor_size * pmc->num_descriptors;
334+
309335 wil_dbg_misc(wil,
310336 "%s: size %u, pos %lld\n",
311337 __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
345371 loff_t newpos;
346372 struct wil6210_priv *wil = filp->private_data;
347373 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;
349386
350387 switch (whence) {
351388 case 0: /* SEEK_SET */
@@ -361,15 +398,21 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence) · 9 unmodified lines
361398 break;
362399
363400 default: /* can't happen */
364− return -EINVAL;
401+ newpos = -EINVAL;
402+ goto out;
365403 }
366404
367− if (newpos < 0)
368− return -EINVAL;
405+ if (newpos < 0) {
406+ newpos = -EINVAL;
407+ goto out;
408+ }
369409 if (newpos > pmc_size)
370410 newpos = pmc_size;
371411
372412 filp->f_pos = newpos;
373413
414+out:
415+ mutex_unlock(&pmc->lock);
416+
374417 return newpos;
375418 }
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
8888 return vring->size/4;
8989 }
9090
91+/* returns true if num avail descriptors is lower than wmark_low */
92+static 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 */
98+static inline int wil_vring_avail_high(struct vring *vring)
99+{
100+ return wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring);
101+}
102+
91103 /* wil_val_in_range - check if value in [min,max) */
92104 static inline bool wil_val_in_range(int val, int min, int max)
93105 {
@@ -1780,6 +1792,89 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, · 1686 unmodified lines
17801792 return rc;
17811793 }
17821794
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+ */
1811+static 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+
1862+void 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+
1870+void 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+
17831878 netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
17841879 {
17851880 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
18221917 /* set up vring entry */
18231918 rc = wil_tx_vring(wil, vring, skb);
18241919
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−
18311920 switch (rc) {
18321921 case 0:
1922+ /* shall we stop net queues? */
1923+ wil_update_net_queues_bh(wil, vring, true);
18331924 /* statistics will be updated on the tx_complete */
18341925 dev_kfree_skb_any(skb);
18351926 return NETDEV_TX_OK;
@@ -1978,10 +2069,9 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid) · 142 unmodified lines
19782069 txdata->last_idle = get_cycles();
19792070 }
19802071
1981− if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring)) {
1982− wil_dbg_txrx(wil, "netif_tx_wake : ring not full\n");
1983− netif_tx_wake_all_queues(wil_to_ndev(wil));
1984− }
2072+ /* shall we wake net queues? */
2073+ if (done)
2074+ wil_update_net_queues(wil, vring, false);
19852075
19862076 return done;
19872077 }
drivers/net/wireless/ath/wil6210/wil6210.h+22−3
@@ -276,10 +276,11 @@ struct fw_map { · 275 unmodified lines
276276 u32 to; /* linker address - to, exclusive */
277277 u32 host; /* PCI/Host address - BAR0 + 0x880000 */
278278 const char *name; /* for debugfs */
279+ bool fw; /* true if FW mapping, false if UCODE mapping */
279280 };
280281
281282 /* array size should be in sync with actual definition in the wmi.c */
282−extern const struct fw_map fw_mapping[8];
283+extern const struct fw_map fw_mapping[10];
283284
284285 /**
285286 * mk_cidxtid - construct @cidxtid field
@@ -461,8 +462,11 @@ struct wil_p2p_info { · 175 unmodified lines
461462 u8 discovery_started;
462463 u8 p2p_dev_started;
463464 u64 cookie;
465+ struct wireless_dev *pending_listen_wdev;
466+ unsigned int listen_duration;
464467 struct timer_list discovery_timer; /* listen/search duration */
465468 struct work_struct discovery_expired_work; /* listen/search expire */
469+ struct work_struct delayed_listen_work; /* listen after scan done */
466470 };
467471
468472 enum wil_sta_status {
@@ -624,6 +628,8 @@ struct wil6210_priv { · 155 unmodified lines
624628 * - consumed in thread by wmi_event_worker
625629 */
626630 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 */
627633 struct napi_struct napi_rx;
628634 struct napi_struct napi_tx;
629635 /* keep alive */
@@ -817,6 +823,10 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason); · 187 unmodified lines
817823 int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
818824 int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
819825 u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
826+int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
827+ enum wmi_ps_profile_type ps_profile);
828+int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
829+int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
820830 int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
821831 u8 dialog_token, __le16 ba_param_set,
822832 __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
837847 void wil_p2p_discovery_timer_fn(ulong x);
838848 int wil_p2p_search(struct wil6210_priv *wil,
839849 struct cfg80211_scan_request *request);
840−int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
841− struct ieee80211_channel *chan, u64 *cookie);
850+int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
851+ unsigned int duration, struct ieee80211_channel *chan,
852+ u64 *cookie);
842853 u8 wil_p2p_stop_discovery(struct wil6210_priv *wil);
843854 int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie);
844855 void wil_p2p_listen_expired(struct work_struct *work);
845856 void wil_p2p_search_expired(struct work_struct *work);
846857 void wil_p2p_stop_radio_operations(struct wil6210_priv *wil);
858+void wil_p2p_delayed_listen_work(struct work_struct *work);
847859
848860 /* WMI for P2P */
849861 int 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
869881 u8 chan, u8 hidden_ssid, u8 is_go);
870882 int wmi_pcp_stop(struct wil6210_priv *wil);
871883 int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
884+int wmi_abort_scan(struct wil6210_priv *wil);
885+void wil_abort_scan(struct wil6210_priv *wil, bool sync);
886+
872887 void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
873888 u16 reason_code, bool from_event);
874889 void 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
886901 int wil_bcast_init(struct wil6210_priv *wil);
887902 void wil_bcast_fini(struct wil6210_priv *wil);
888903
904+void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring,
905+ bool should_stop);
906+void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring,
907+ bool check_stop);
889908 netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
890909 int wil_tx_complete(struct wil6210_priv *wil, int ringid);
891910 void 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
3636 for (i = 1; i < ARRAY_SIZE(fw_mapping); i++) {
3737 map = &fw_mapping[i];
3838
39+ if (!map->fw)
40+ continue;
41+
3942 if (map->host < host_min)
4043 host_min = map->host;
4144
@@ -73,6 +76,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) · 31 unmodified lines
7376 for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
7477 map = &fw_mapping[i];
7578
79+ if (!map->fw)
80+ continue;
81+
7682 data = (void * __force)wil->csr + HOSTADDR(map->host);
7783 len = map->to - map->from;
7884 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
8484 * array size should be in sync with the declaration in the wil6210.h
8585 */
8686 const struct fw_map fw_mapping[] = {
87− {0x000000, 0x040000, 0x8c0000, "fw_code"}, /* FW code RAM 256k */
88− {0x800000, 0x808000, 0x900000, "fw_data"}, /* FW data RAM 32k */
89− {0x840000, 0x860000, 0x908000, "fw_peri"}, /* periph. data RAM 128k */
90− {0x880000, 0x88a000, 0x880000, "rgf"}, /* various RGF 40k */
91− {0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table 4k */
92− {0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf 4k */
93− {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext"}, /* mac_ext_rgf 512b */
94− {0x8c0000, 0x949000, 0x8c0000, "upper"}, /* upper area 548k */
95− /*
96− * 920000..930000 ucode code RAM
97− * 930000..932000 ucode data RAM
98− * 932000..949000 back-door debug data
87+ /* FW code RAM 256k */
88+ {0x000000, 0x040000, 0x8c0000, "fw_code", true},
89+ /* FW data RAM 32k */
90+ {0x800000, 0x808000, 0x900000, "fw_data", true},
91+ /* periph data 128k */
92+ {0x840000, 0x860000, 0x908000, "fw_peri", true},
93+ /* various RGF 40k */
94+ {0x880000, 0x88a000, 0x880000, "rgf", true},
95+ /* AGC table 4k */
96+ {0x88a000, 0x88b000, 0x88a000, "AGC_tbl", true},
97+ /* Pcie_ext_rgf 4k */
98+ {0x88b000, 0x88c000, 0x88b000, "rgf_ext", true},
99+ /* mac_ext_rgf 512b */
100+ {0x88c000, 0x88c200, 0x88c000, "mac_rgf_ext", true},
101+ /* upper area 548k */
102+ {0x8c0000, 0x949000, 0x8c0000, "upper", true},
103+ /* UCODE areas - accessible by debugfs blobs but not by
104+ * wmi_addr_remap. UCODE areas MUST be added AFTER FW areas!
99105 */
106+ /* ucode code RAM 128k */
107+ {0x000000, 0x020000, 0x920000, "uc_code", false},
108+ /* ucode data RAM 16k */
109+ {0x800000, 0x804000, 0x940000, "uc_data", false},
100110 };
101111
102112 struct blink_on_off_time led_blink_time[] = {
@@ -108,7 +118,7 @@ struct blink_on_off_time led_blink_time[] = { · 5 unmodified lines
108118 u8 led_polarity = LED_POLARITY_LOW_ACTIVE;
109119
110120 /**
111− * return AHB address for given firmware/ucode internal (linker) address
121+ * return AHB address for given firmware internal (linker) address
112122 * @x - internal address
113123 * If address have no valid AHB mapping, return 0
114124 */
@@ -117,7 +127,8 @@ static u32 wmi_addr_remap(u32 x) · 2 unmodified lines
117127 uint i;
118128
119129 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)))
121132 return x + fw_mapping[i].host - fw_mapping[i].from;
122133 }
123134
@@ -427,18 +438,24 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, · 303 unmodified lines
427438 mutex_lock(&wil->p2p_wdev_mutex);
428439 if (wil->scan_request) {
429440 struct wmi_scan_complete_event *data = d;
441+ int status = le32_to_cpu(data->status);
430442 struct cfg80211_scan_info info = {
431− .aborted = (data->status != WMI_SCAN_SUCCESS),
443+ .aborted = ((status != WMI_SCAN_SUCCESS) &&
444+ (status != WMI_SCAN_ABORT_REJECTED)),
432445 };
433446
434− wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
447+ wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status);
435448 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
436449 wil->scan_request, info.aborted);
437−
438450 del_timer_sync(&wil->scan_timer);
439451 cfg80211_scan_done(wil->scan_request, &info);
440452 wil->radio_wdev = wil->wdev;
441453 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+ }
442459 } else {
443460 wil_err(wil, "SCAN_COMPLETE while not scanning\n");
444461 }
@@ -548,7 +565,6 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) · 103 unmodified lines
548565 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
549566 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
550567 if (rc) {
551− netif_tx_stop_all_queues(ndev);
552568 netif_carrier_off(ndev);
553569 wil_err(wil,
554570 "%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
588604
589605 wil->sta[evt->cid].status = wil_sta_connected;
590606 set_bit(wil_status_fwconnected, wil->status);
591− netif_tx_wake_all_queues(ndev);
607+ wil_update_net_queues_bh(wil, NULL, false);
592608
593609 out:
594610 if (rc)
@@ -1564,6 +1580,112 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, · 969 unmodified lines
15641580 return rc;
15651581 }
15661582
1583+int 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+
1617+int 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+
1650+int 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+
1676+int 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+
15671689 void wmi_event_flush(struct wil6210_priv *wil)
15681690 {
15691691 struct pending_wmi_event *evt, *t;
drivers/net/wireless/ath/wil6210/wmi.h+463−123
@@ -35,6 +35,7 @@ · 34 unmodified lines
3535 #define WMI_MAC_LEN (6)
3636 #define WMI_PROX_RANGE_NUM (3)
3737 #define WMI_MAX_LOSS_DMG_BEACONS (20)
38+#define MAX_NUM_OF_SECTORS (128)
3839
3940 /* Mailbox interface
4041 * used for commands and events
@@ -51,8 +52,10 @@ enum wmi_mid { · 10 unmodified lines
5152 * the host
5253 */
5354 enum wmi_fw_capability {
54− WMI_FW_CAPABILITY_FTM = 0,
55− WMI_FW_CAPABILITY_PS_CONFIG = 1,
55+ WMI_FW_CAPABILITY_FTM = 0,
56+ WMI_FW_CAPABILITY_PS_CONFIG = 1,
57+ WMI_FW_CAPABILITY_RF_SECTORS = 2,
58+ WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT = 3,
5659 WMI_FW_CAPABILITY_MAX,
5760 };
5861
@@ -66,137 +69,149 @@ struct wmi_cmd_hdr { · 7 unmodified lines
6669
6770 /* List of Commands */
6871 enum wmi_command_id {
69− WMI_CONNECT_CMDID = 0x01,
70− WMI_DISCONNECT_CMDID = 0x03,
71− WMI_DISCONNECT_STA_CMDID = 0x04,
72− WMI_START_SCAN_CMDID = 0x07,
73− WMI_SET_BSS_FILTER_CMDID = 0x09,
74− WMI_SET_PROBED_SSID_CMDID = 0x0A,
75− WMI_SET_LISTEN_INT_CMDID = 0x0B,
76− WMI_BCON_CTRL_CMDID = 0x0F,
77− WMI_ADD_CIPHER_KEY_CMDID = 0x16,
78− WMI_DELETE_CIPHER_KEY_CMDID = 0x17,
79− WMI_PCP_CONF_CMDID = 0x18,
80− WMI_SET_APPIE_CMDID = 0x3F,
81− WMI_SET_WSC_STATUS_CMDID = 0x41,
82− WMI_PXMT_RANGE_CFG_CMDID = 0x42,
83− WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x43,
84− WMI_MEM_READ_CMDID = 0x800,
85− WMI_MEM_WR_CMDID = 0x801,
86− WMI_ECHO_CMDID = 0x803,
87− WMI_DEEP_ECHO_CMDID = 0x804,
88− WMI_CONFIG_MAC_CMDID = 0x805,
89− WMI_CONFIG_PHY_DEBUG_CMDID = 0x806,
90− WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x808,
91− WMI_PHY_GET_STATISTICS_CMDID = 0x809,
92− WMI_FS_TUNE_CMDID = 0x80A,
93− WMI_CORR_MEASURE_CMDID = 0x80B,
94− WMI_READ_RSSI_CMDID = 0x80C,
95− WMI_TEMP_SENSE_CMDID = 0x80E,
96− WMI_DC_CALIB_CMDID = 0x80F,
97− WMI_SEND_TONE_CMDID = 0x810,
98− WMI_IQ_TX_CALIB_CMDID = 0x811,
99− WMI_IQ_RX_CALIB_CMDID = 0x812,
100− WMI_SET_UCODE_IDLE_CMDID = 0x813,
101− WMI_SET_WORK_MODE_CMDID = 0x815,
102− WMI_LO_LEAKAGE_CALIB_CMDID = 0x816,
103− WMI_MARLON_R_READ_CMDID = 0x818,
104− WMI_MARLON_R_WRITE_CMDID = 0x819,
105− WMI_MARLON_R_TXRX_SEL_CMDID = 0x81A,
106− MAC_IO_STATIC_PARAMS_CMDID = 0x81B,
107− MAC_IO_DYNAMIC_PARAMS_CMDID = 0x81C,
108− WMI_SILENT_RSSI_CALIB_CMDID = 0x81D,
109− WMI_RF_RX_TEST_CMDID = 0x81E,
110− WMI_CFG_RX_CHAIN_CMDID = 0x820,
111− WMI_VRING_CFG_CMDID = 0x821,
112− WMI_BCAST_VRING_CFG_CMDID = 0x822,
113− WMI_VRING_BA_EN_CMDID = 0x823,
114− WMI_VRING_BA_DIS_CMDID = 0x824,
115− WMI_RCP_ADDBA_RESP_CMDID = 0x825,
116− WMI_RCP_DELBA_CMDID = 0x826,
117− WMI_SET_SSID_CMDID = 0x827,
118− WMI_GET_SSID_CMDID = 0x828,
119− WMI_SET_PCP_CHANNEL_CMDID = 0x829,
120− WMI_GET_PCP_CHANNEL_CMDID = 0x82A,
121− WMI_SW_TX_REQ_CMDID = 0x82B,
122− WMI_READ_MAC_RXQ_CMDID = 0x830,
123− WMI_READ_MAC_TXQ_CMDID = 0x831,
124− WMI_WRITE_MAC_RXQ_CMDID = 0x832,
125− WMI_WRITE_MAC_TXQ_CMDID = 0x833,
126− WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x834,
127− WMI_MLME_PUSH_CMDID = 0x835,
128− WMI_BEAMFORMING_MGMT_CMDID = 0x836,
129− WMI_BF_TXSS_MGMT_CMDID = 0x837,
130− WMI_BF_SM_MGMT_CMDID = 0x838,
131− WMI_BF_RXSS_MGMT_CMDID = 0x839,
132− WMI_BF_TRIG_CMDID = 0x83A,
133− WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842,
134− WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843,
135− WMI_SET_SECTORS_CMDID = 0x849,
136− WMI_MAINTAIN_PAUSE_CMDID = 0x850,
137− WMI_MAINTAIN_RESUME_CMDID = 0x851,
138− WMI_RS_MGMT_CMDID = 0x852,
139− WMI_RF_MGMT_CMDID = 0x853,
140− WMI_THERMAL_THROTTLING_CTRL_CMDID = 0x854,
141− WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x855,
142− WMI_OTP_READ_CMDID = 0x856,
143− WMI_OTP_WRITE_CMDID = 0x857,
144− WMI_LED_CFG_CMDID = 0x858,
72+ WMI_CONNECT_CMDID = 0x01,
73+ WMI_DISCONNECT_CMDID = 0x03,
74+ WMI_DISCONNECT_STA_CMDID = 0x04,
75+ WMI_START_SCAN_CMDID = 0x07,
76+ WMI_SET_BSS_FILTER_CMDID = 0x09,
77+ WMI_SET_PROBED_SSID_CMDID = 0x0A,
78+ WMI_SET_LISTEN_INT_CMDID = 0x0B,
79+ WMI_BCON_CTRL_CMDID = 0x0F,
80+ WMI_ADD_CIPHER_KEY_CMDID = 0x16,
81+ WMI_DELETE_CIPHER_KEY_CMDID = 0x17,
82+ WMI_PCP_CONF_CMDID = 0x18,
83+ WMI_SET_APPIE_CMDID = 0x3F,
84+ WMI_SET_WSC_STATUS_CMDID = 0x41,
85+ WMI_PXMT_RANGE_CFG_CMDID = 0x42,
86+ WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x43,
87+ WMI_MEM_READ_CMDID = 0x800,
88+ WMI_MEM_WR_CMDID = 0x801,
89+ WMI_ECHO_CMDID = 0x803,
90+ WMI_DEEP_ECHO_CMDID = 0x804,
91+ WMI_CONFIG_MAC_CMDID = 0x805,
92+ WMI_CONFIG_PHY_DEBUG_CMDID = 0x806,
93+ WMI_ADD_DEBUG_TX_PCKT_CMDID = 0x808,
94+ WMI_PHY_GET_STATISTICS_CMDID = 0x809,
95+ WMI_FS_TUNE_CMDID = 0x80A,
96+ WMI_CORR_MEASURE_CMDID = 0x80B,
97+ WMI_READ_RSSI_CMDID = 0x80C,
98+ WMI_TEMP_SENSE_CMDID = 0x80E,
99+ WMI_DC_CALIB_CMDID = 0x80F,
100+ WMI_SEND_TONE_CMDID = 0x810,
101+ WMI_IQ_TX_CALIB_CMDID = 0x811,
102+ WMI_IQ_RX_CALIB_CMDID = 0x812,
103+ WMI_SET_UCODE_IDLE_CMDID = 0x813,
104+ WMI_SET_WORK_MODE_CMDID = 0x815,
105+ WMI_LO_LEAKAGE_CALIB_CMDID = 0x816,
106+ WMI_MARLON_R_READ_CMDID = 0x818,
107+ WMI_MARLON_R_WRITE_CMDID = 0x819,
108+ WMI_MARLON_R_TXRX_SEL_CMDID = 0x81A,
109+ MAC_IO_STATIC_PARAMS_CMDID = 0x81B,
110+ MAC_IO_DYNAMIC_PARAMS_CMDID = 0x81C,
111+ WMI_SILENT_RSSI_CALIB_CMDID = 0x81D,
112+ WMI_RF_RX_TEST_CMDID = 0x81E,
113+ WMI_CFG_RX_CHAIN_CMDID = 0x820,
114+ WMI_VRING_CFG_CMDID = 0x821,
115+ WMI_BCAST_VRING_CFG_CMDID = 0x822,
116+ WMI_VRING_BA_EN_CMDID = 0x823,
117+ WMI_VRING_BA_DIS_CMDID = 0x824,
118+ WMI_RCP_ADDBA_RESP_CMDID = 0x825,
119+ WMI_RCP_DELBA_CMDID = 0x826,
120+ WMI_SET_SSID_CMDID = 0x827,
121+ WMI_GET_SSID_CMDID = 0x828,
122+ WMI_SET_PCP_CHANNEL_CMDID = 0x829,
123+ WMI_GET_PCP_CHANNEL_CMDID = 0x82A,
124+ WMI_SW_TX_REQ_CMDID = 0x82B,
125+ WMI_READ_MAC_RXQ_CMDID = 0x830,
126+ WMI_READ_MAC_TXQ_CMDID = 0x831,
127+ WMI_WRITE_MAC_RXQ_CMDID = 0x832,
128+ WMI_WRITE_MAC_TXQ_CMDID = 0x833,
129+ WMI_WRITE_MAC_XQ_FIELD_CMDID = 0x834,
130+ WMI_MLME_PUSH_CMDID = 0x835,
131+ WMI_BEAMFORMING_MGMT_CMDID = 0x836,
132+ WMI_BF_TXSS_MGMT_CMDID = 0x837,
133+ WMI_BF_SM_MGMT_CMDID = 0x838,
134+ WMI_BF_RXSS_MGMT_CMDID = 0x839,
135+ WMI_BF_TRIG_CMDID = 0x83A,
136+ WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842,
137+ WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843,
138+ WMI_SET_SECTORS_CMDID = 0x849,
139+ WMI_MAINTAIN_PAUSE_CMDID = 0x850,
140+ WMI_MAINTAIN_RESUME_CMDID = 0x851,
141+ WMI_RS_MGMT_CMDID = 0x852,
142+ WMI_RF_MGMT_CMDID = 0x853,
143+ WMI_THERMAL_THROTTLING_CTRL_CMDID = 0x854,
144+ WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x855,
145+ WMI_OTP_READ_CMDID = 0x856,
146+ WMI_OTP_WRITE_CMDID = 0x857,
147+ WMI_LED_CFG_CMDID = 0x858,
145148 /* Performance monitoring commands */
146− WMI_BF_CTRL_CMDID = 0x862,
147− WMI_NOTIFY_REQ_CMDID = 0x863,
148− WMI_GET_STATUS_CMDID = 0x864,
149− WMI_GET_RF_STATUS_CMDID = 0x866,
150− WMI_GET_BASEBAND_TYPE_CMDID = 0x867,
151− WMI_UNIT_TEST_CMDID = 0x900,
152− WMI_HICCUP_CMDID = 0x901,
153− WMI_FLASH_READ_CMDID = 0x902,
154− WMI_FLASH_WRITE_CMDID = 0x903,
149+ WMI_BF_CTRL_CMDID = 0x862,
150+ WMI_NOTIFY_REQ_CMDID = 0x863,
151+ WMI_GET_STATUS_CMDID = 0x864,
152+ WMI_GET_RF_STATUS_CMDID = 0x866,
153+ WMI_GET_BASEBAND_TYPE_CMDID = 0x867,
154+ WMI_UNIT_TEST_CMDID = 0x900,
155+ WMI_HICCUP_CMDID = 0x901,
156+ WMI_FLASH_READ_CMDID = 0x902,
157+ WMI_FLASH_WRITE_CMDID = 0x903,
155158 /* Power management */
156− WMI_TRAFFIC_DEFERRAL_CMDID = 0x904,
157− WMI_TRAFFIC_RESUME_CMDID = 0x905,
159+ WMI_TRAFFIC_DEFERRAL_CMDID = 0x904,
160+ WMI_TRAFFIC_RESUME_CMDID = 0x905,
158161 /* P2P */
159− WMI_P2P_CFG_CMDID = 0x910,
160− WMI_PORT_ALLOCATE_CMDID = 0x911,
161− WMI_PORT_DELETE_CMDID = 0x912,
162− WMI_POWER_MGMT_CFG_CMDID = 0x913,
163− WMI_START_LISTEN_CMDID = 0x914,
164− WMI_START_SEARCH_CMDID = 0x915,
165− WMI_DISCOVERY_START_CMDID = 0x916,
166− WMI_DISCOVERY_STOP_CMDID = 0x917,
167− WMI_PCP_START_CMDID = 0x918,
168− WMI_PCP_STOP_CMDID = 0x919,
169− WMI_GET_PCP_FACTOR_CMDID = 0x91B,
162+ WMI_P2P_CFG_CMDID = 0x910,
163+ WMI_PORT_ALLOCATE_CMDID = 0x911,
164+ WMI_PORT_DELETE_CMDID = 0x912,
165+ WMI_POWER_MGMT_CFG_CMDID = 0x913,
166+ WMI_START_LISTEN_CMDID = 0x914,
167+ WMI_START_SEARCH_CMDID = 0x915,
168+ WMI_DISCOVERY_START_CMDID = 0x916,
169+ WMI_DISCOVERY_STOP_CMDID = 0x917,
170+ WMI_PCP_START_CMDID = 0x918,
171+ WMI_PCP_STOP_CMDID = 0x919,
172+ WMI_GET_PCP_FACTOR_CMDID = 0x91B,
170173 /* Power Save Configuration Commands */
171− WMI_PS_DEV_PROFILE_CFG_CMDID = 0x91C,
174+ WMI_PS_DEV_PROFILE_CFG_CMDID = 0x91C,
172175 /* Not supported yet */
173− WMI_PS_DEV_CFG_CMDID = 0x91D,
176+ WMI_PS_DEV_CFG_CMDID = 0x91D,
174177 /* Not supported yet */
175− WMI_PS_DEV_CFG_READ_CMDID = 0x91E,
178+ WMI_PS_DEV_CFG_READ_CMDID = 0x91E,
176179 /* Per MAC Power Save Configuration commands
177180 * Not supported yet
178181 */
179− WMI_PS_MID_CFG_CMDID = 0x91F,
182+ WMI_PS_MID_CFG_CMDID = 0x91F,
180183 /* Not supported yet */
181− WMI_PS_MID_CFG_READ_CMDID = 0x920,
182− WMI_RS_CFG_CMDID = 0x921,
183− WMI_GET_DETAILED_RS_RES_CMDID = 0x922,
184− WMI_AOA_MEAS_CMDID = 0x923,
185− WMI_TOF_SESSION_START_CMDID = 0x991,
186− WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
187− WMI_TOF_SET_LCR_CMDID = 0x993,
188− WMI_TOF_SET_LCI_CMDID = 0x994,
189− WMI_TOF_CHANNEL_INFO_CMDID = 0x995,
190− WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
191− WMI_ABORT_SCAN_CMDID = 0xF007,
192− WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
193− WMI_GET_PMK_CMDID = 0xF048,
194− WMI_SET_PASSPHRASE_CMDID = 0xF049,
195− WMI_SEND_ASSOC_RES_CMDID = 0xF04A,
196− WMI_SET_ASSOC_REQ_RELAY_CMDID = 0xF04B,
197− WMI_MAC_ADDR_REQ_CMDID = 0xF04D,
198− WMI_FW_VER_CMDID = 0xF04E,
199− WMI_PMC_CMDID = 0xF04F,
184+ WMI_PS_MID_CFG_READ_CMDID = 0x920,
185+ WMI_RS_CFG_CMDID = 0x921,
186+ WMI_GET_DETAILED_RS_RES_CMDID = 0x922,
187+ WMI_AOA_MEAS_CMDID = 0x923,
188+ WMI_SET_MGMT_RETRY_LIMIT_CMDID = 0x930,
189+ WMI_GET_MGMT_RETRY_LIMIT_CMDID = 0x931,
190+ WMI_TOF_SESSION_START_CMDID = 0x991,
191+ WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
192+ WMI_TOF_SET_LCR_CMDID = 0x993,
193+ WMI_TOF_SET_LCI_CMDID = 0x994,
194+ WMI_TOF_CHANNEL_INFO_CMDID = 0x995,
195+ WMI_TOF_SET_TX_RX_OFFSET_CMDID = 0x997,
196+ WMI_TOF_GET_TX_RX_OFFSET_CMDID = 0x998,
197+ WMI_GET_RF_SECTOR_PARAMS_CMDID = 0x9A0,
198+ WMI_SET_RF_SECTOR_PARAMS_CMDID = 0x9A1,
199+ WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID = 0x9A2,
200+ WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID = 0x9A3,
201+ WMI_SET_RF_SECTOR_ON_CMDID = 0x9A4,
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,
200215 };
201216
202217 /* WMI_CONNECT_CMDID */
@@ -879,6 +894,14 @@ struct wmi_aoa_meas_cmd { · 676 unmodified lines
879894 __le32 meas_rf_mask;
880895 } __packed;
881896
897+/* WMI_SET_MGMT_RETRY_LIMIT_CMDID */
898+struct 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+
882905 enum wmi_tof_burst_duration {
883906 WMI_TOF_BURST_DURATION_250_USEC = 2,
884907 WMI_TOF_BURST_DURATION_500_USEC = 3,
@@ -942,6 +965,15 @@ struct wmi_tof_channel_info_cmd { · 57 unmodified lines
942965 __le32 channel_info_report_request;
943966 } __packed;
944967
968+/* WMI_TOF_SET_TX_RX_OFFSET_CMDID */
969+struct 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+
945977 /* WMI Events
946978 * List of Events (target to host)
947979 */
@@ -1035,12 +1067,24 @@ enum wmi_event_id { · 87 unmodified lines
10351067 WMI_RS_CFG_DONE_EVENTID = 0x1921,
10361068 WMI_GET_DETAILED_RS_RES_EVENTID = 0x1922,
10371069 WMI_AOA_MEAS_EVENTID = 0x1923,
1070+ WMI_SET_MGMT_RETRY_LIMIT_EVENTID = 0x1930,
1071+ WMI_GET_MGMT_RETRY_LIMIT_EVENTID = 0x1931,
10381072 WMI_TOF_SESSION_END_EVENTID = 0x1991,
10391073 WMI_TOF_GET_CAPABILITIES_EVENTID = 0x1992,
10401074 WMI_TOF_SET_LCR_EVENTID = 0x1993,
10411075 WMI_TOF_SET_LCI_EVENTID = 0x1994,
10421076 WMI_TOF_FTM_PER_DEST_RES_EVENTID = 0x1995,
10431077 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,
10441088 WMI_SET_CHANNEL_EVENTID = 0x9000,
10451089 WMI_ASSOC_REQ_EVENTID = 0x9001,
10461090 WMI_EAPOL_RX_EVENTID = 0x9002,
@@ -1166,6 +1210,7 @@ enum baseband_type { · 119 unmodified lines
11661210 BASEBAND_SPARROW_M_B0 = 0x05,
11671211 BASEBAND_SPARROW_M_C0 = 0x06,
11681212 BASEBAND_SPARROW_M_D0 = 0x07,
1213+ BASEBAND_TALYN_M_A0 = 0x08,
11691214 };
11701215
11711216 /* WMI_GET_BASEBAND_TYPE_EVENTID */
@@ -2070,6 +2115,22 @@ struct wmi_aoa_meas_event { · 898 unmodified lines
20702115 u8 meas_data[WMI_AOA_MAX_DATA_SIZE];
20712116 } __packed;
20722117
2118+/* WMI_SET_MGMT_RETRY_LIMIT_EVENTID */
2119+struct 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 */
2127+struct 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+
20732134 /* WMI_TOF_GET_CAPABILITIES_EVENTID */
20742135 struct wmi_tof_get_capabilities_event {
20752136 u8 ftm_capability;
@@ -2184,4 +2245,283 @@ struct wmi_tof_channel_info_event { · 108 unmodified lines
21842245 u8 report[0];
21852246 } __packed;
21862247
2248+/* WMI_TOF_SET_TX_RX_OFFSET_EVENTID */
2249+struct 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 */
2256+struct 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 */
2268+enum 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) */
2276+enum 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) */
2282+struct 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 */
2309+struct 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 */
2319+struct 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 */
2333+struct 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 */
2345+struct 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+ */
2355+struct 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+ */
2367+struct 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+ */
2386+struct 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+ */
2398+struct 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+ */
2410+struct 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+ */
2422+struct 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+
2431+enum 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+ */
2445+struct 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 */
2457+enum 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 */
2465+struct 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+
2472+struct 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+ */
2488+struct 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 */
2495+struct 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+ */
2510+struct 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 */
2520+struct 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+
21872527 #endif /* __WILOCITY_WMI_H__ */
drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile+2−1
@@ -35,7 +35,8 @@ brcmfmac-objs += \ · 34 unmodified lines
3535 firmware.o \
3636 feature.o \
3737 btcoex.o \
38− vendor.o
38+ vendor.o \
39+ pno.o
3940 brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \
4041 bcdc.o
4142 brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h+8−2
@@ -22,10 +22,12 @@ · 21 unmodified lines
2222 /* IDs of the 6 default common rings of msgbuf protocol */
2323 #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0
2424 #define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 1
25+#define BRCMF_H2D_MSGRING_FLOWRING_IDSTART 2
2526 #define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 2
2627 #define BRCMF_D2H_MSGRING_TX_COMPLETE 3
2728 #define BRCMF_D2H_MSGRING_RX_COMPLETE 4
2829
30+
2931 #define BRCMF_NROF_H2D_COMMON_MSGRINGS 2
3032 #define BRCMF_NROF_D2H_COMMON_MSGRINGS 3
3133 #define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \
@@ -95,14 +97,18 @@ struct brcmf_bus_ops { · 63 unmodified lines
9597 * @flowrings: commonrings which are dynamically created and destroyed for data.
9698 * @rx_dataoffset: if set then all rx data has this this offset.
9799 * @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.
99103 */
100104 struct brcmf_bus_msgbuf {
101105 struct brcmf_commonring *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
102106 struct brcmf_commonring **flowrings;
103107 u32 rx_dataoffset;
104108 u32 max_rxbufpost;
105− u32 nrof_flowrings;
109+ u16 max_flowrings;
110+ u16 max_submissionrings;
111+ u16 max_completionrings;
106112 };
107113
108114
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c+145−236
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 #include "fwil_types.h"
3333 #include "p2p.h"
3434 #include "btcoex.h"
35+#include "pno.h"
3536 #include "cfg80211.h"
3637 #include "feature.h"
3738 #include "fwil.h"
@@ -41,16 +42,6 @@ · 3 unmodified lines
4142 #include "common.h"
4243
4344 #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
5445
5546 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
5647 #define WPA_OUI_TYPE 1
@@ -768,12 +759,12 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, · 711 unmodified lines
768759 brcmf_scan_config_mpc(ifp, 1);
769760
770761 /*
771− * e-scan can be initiated by scheduled scan
762+ * e-scan can be initiated internally
772763 * which takes precedence.
773764 */
774− if (cfg->sched_escan) {
765+ if (cfg->internal_escan) {
775766 brcmf_dbg(SCAN, "scheduled scan completed\n");
776− cfg->sched_escan = false;
767+ cfg->internal_escan = false;
777768 if (!aborted)
778769 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
779770 } else if (scan_request) {
@@ -1091,9 +1082,9 @@ exit: · 311 unmodified lines
10911082 }
10921083
10931084 static s32
1094−brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1095− struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1085+brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
10961086 {
1087+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
10971088 s32 err;
10981089 u32 passive_scan;
10991090 struct brcmf_scan_results *results;
@@ -1101,7 +1092,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy, · 1 unmodified line
11011092
11021093 brcmf_dbg(SCAN, "Enter\n");
11031094 escan->ifp = ifp;
1104− escan->wiphy = wiphy;
1095+ escan->wiphy = cfg->wiphy;
11051096 escan->escan_state = WL_ESCAN_STATE_SCANNING;
11061097 passive_scan = cfg->active_scan ? 0 : 1;
11071098 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
11811172 if (err)
11821173 goto scan_out;
11831174
1184− err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1175+ err = brcmf_do_escan(vif->ifp, request);
11851176 if (err)
11861177 goto scan_out;
11871178 } else {
@@ -3024,7 +3015,7 @@ void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) · 1836 unmodified lines
30243015 struct escan_info *escan = &cfg->escan_info;
30253016
30263017 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3027− if (cfg->scan_request) {
3018+ if (cfg->internal_escan || cfg->scan_request) {
30283019 escan->escan_state = WL_ESCAN_STATE_IDLE;
30293020 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
30303021 }
@@ -3047,7 +3038,7 @@ static void brcmf_escan_timeout(unsigned long data) · 16 unmodified lines
30473038 struct brcmf_cfg80211_info *cfg =
30483039 (struct brcmf_cfg80211_info *)data;
30493040
3050− if (cfg->scan_request) {
3041+ if (cfg->internal_escan || cfg->scan_request) {
30513042 brcmf_err("timer expired\n");
30523043 schedule_work(&cfg->escan_timeout_work);
30533044 }
@@ -3130,7 +3121,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, · 76 unmodified lines
31303121 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
31313122 goto exit;
31323123
3133− if (!cfg->scan_request) {
3124+ if (!cfg->internal_escan && !cfg->scan_request) {
31343125 brcmf_dbg(SCAN, "result without cfg80211 request\n");
31353126 goto exit;
31363127 }
@@ -3176,7 +3167,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, · 39 unmodified lines
31763167 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
31773168 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
31783169 goto exit;
3179− if (cfg->scan_request) {
3170+ if (cfg->internal_escan || cfg->scan_request) {
31803171 brcmf_inform_bss(cfg);
31813172 aborted = status != BRCMF_E_STATUS_SUCCESS;
31823173 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
32013192 brcmf_cfg80211_escan_timeout_worker);
32023193 }
32033194
3195+static struct cfg80211_scan_request *
3196+brcmf_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+
3213+static 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+
3240+static 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+
3262+static struct brcmf_pno_net_info_le *
3263+brcmf_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+
32043284 /* PFN result doesn't have all the info which are required by the supplicant
32053285 * (For e.g IEs) Do a target Escan so that sched scan results are reported
32063286 * 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
32143294 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
32153295 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
32163296 struct cfg80211_scan_request *request = NULL;
3217− struct cfg80211_ssid *ssid = NULL;
3218− struct ieee80211_channel *channel = NULL;
32193297 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3220− int err = 0;
3221− int channel_req = 0;
3222− int band = 0;
3298+ int i, err = 0;
32233299 struct brcmf_pno_scanresults_le *pfn_result;
32243300 u32 result_count;
32253301 u32 status;
@@ -3245,254 +3321,86 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, · 19 unmodified lines
32453321 */
32463322 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
32473323 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3248− if (result_count > 0) {
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 {
3324+ if (!result_count) {
33113325 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
33123326 goto out_err;
33133327 }
3314−
3315− kfree(ssid);
3316− kfree(channel);
3317− kfree(request);
3318− return 0;
3319−
3320−out_err:
3321− kfree(ssid);
3322− kfree(channel);
3323− kfree(request);
3324− cfg80211_sched_scan_stopped(wiphy);
3325− return err;
3326−}
3327−
3328−static 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−
3345−static 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;
3328+ request = brcmf_alloc_internal_escan_request(wiphy,
3329+ result_count);
3330+ if (!request) {
3331+ err = -ENOMEM;
3332+ goto out_err;
33703333 }
33713334
3372− /* Find out if mac randomization should be turned on */
3373− if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
3374− return 0;
3335+ data += sizeof(struct brcmf_pno_scanresults_le);
3336+ netinfo_start = brcmf_get_netinfo_array(pfn_result);
33753337
3376− pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
3377− pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
3338+ for (i = 0; i < result_count; i++) {
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+ }
33783346
3379− memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
3380− mac_mask = request->mac_addr_mask;
3381− for (i = 0; i < ETH_ALEN; i++) {
3382− pfn_mac.mac[i] &= mac_mask[i];
3383− pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
3347+ brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3348+ netinfo->SSID, netinfo->channel);
3349+ err = brcmf_internal_escan_add_info(request,
3350+ netinfo->SSID,
3351+ netinfo->SSID_len,
3352+ netinfo->channel);
3353+ if (err)
3354+ goto out_err;
33843355 }
3385− /* Clear multi bit */
3386− pfn_mac.mac[0] &= 0xFE;
3387− /* Set locally administered */
3388− pfn_mac.mac[0] |= 0x02;
33893356
3390− err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
3391− sizeof(pfn_mac));
3392− if (err)
3393− brcmf_err("pfn_macaddr failed, err=%d\n", err);
3357+ err = brcmf_start_internal_escan(ifp, request);
3358+ if (!err)
3359+ goto free_req;
33943360
3361+out_err:
3362+ cfg80211_sched_scan_stopped(wiphy);
3363+free_req:
3364+ kfree(request);
33953365 return err;
33963366 }
33973367
33983368 static int
33993369 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
34003370 struct net_device *ndev,
3401− struct cfg80211_sched_scan_request *request)
3371+ struct cfg80211_sched_scan_request *req)
34023372 {
34033373 struct brcmf_if *ifp = netdev_priv(ndev);
34043374 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3405− struct brcmf_pno_net_param_le pfn;
3406− int i;
3407− int ret = 0;
34083375
34093376 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3410− request->n_match_sets, request->n_ssids);
3411− if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3412− brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3413− return -EAGAIN;
3414− }
3377+ req->n_match_sets, req->n_ssids);
3378+
34153379 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
34163380 brcmf_err("Scanning suppressed: status (%lu)\n",
34173381 cfg->scan_status);
34183382 return -EAGAIN;
34193383 }
34203384
3421− if (!request->n_ssids || !request->n_match_sets) {
3422− brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3423− request->n_ssids);
3385+ if (req->n_match_sets <= 0) {
3386+ brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3387+ req->n_match_sets);
34243388 return -EINVAL;
34253389 }
34263390
3427− if (request->n_ssids > 0) {
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;
3391+ return brcmf_pno_start_sched_scan(ifp, req);
34853392 }
34863393
34873394 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
34883395 struct net_device *ndev)
34893396 {
34903397 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3398+ struct brcmf_if *ifp = netdev_priv(ndev);
34913399
34923400 brcmf_dbg(SCAN, "enter\n");
3493− brcmf_dev_pno_clean(ndev);
3494− if (cfg->sched_escan)
3495− brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3401+ brcmf_pno_clean(ifp);
3402+ if (cfg->internal_escan)
3403+ brcmf_notify_escan_complete(cfg, ifp, true, true);
34963404 return 0;
34973405 }
34983406
@@ -6428,6 +6336,7 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy) · 2929 unmodified lines
64286336 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
64296337 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
64306338 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6339+ wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
64316340 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
64326341 }
64336342
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h+2−2
@@ -271,7 +271,7 @@ struct brcmf_cfg80211_wowl { · 270 unmodified lines
271271 * @pub: common driver information.
272272 * @channel: current channel.
273273 * @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.
275275 * @ibss_starter: indicates this sta is ibss starter.
276276 * @pwr_save: indicate whether dongle to support power save mode.
277277 * @dongle_up: indicate whether dongle up or not.
@@ -303,7 +303,7 @@ struct brcmf_cfg80211_info { · 25 unmodified lines
303303 struct brcmf_pub *pub;
304304 u32 channel;
305305 bool active_scan;
306− bool sched_escan;
306+ bool internal_escan;
307307 bool ibss_starter;
308308 bool pwr_save;
309309 bool dongle_up;
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h+23−0
@@ -131,6 +131,7 @@ · 130 unmodified lines
131131 #define BRCMF_TXBF_MU_BFR_CAP BIT(1)
132132
133133 #define BRCMF_MAXPMKID 16 /* max # PMKID cache entries */
134+#define BRCMF_NUMCHANNELS 64
134135
135136 #define BRCMF_PFN_MACADDR_CFG_VER 1
136137 #define BRCMF_PFN_MAC_OUI_ONLY BIT(0)
@@ -718,6 +719,21 @@ struct brcmf_pno_param_le { · 581 unmodified lines
718719 __le32 slow_freq;
719720 };
720721
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+ */
730+struct brcmf_pno_config_le {
731+ __le32 reporttype;
732+ __le32 channel_num;
733+ __le16 channel_list[BRCMF_NUMCHANNELS];
734+ __le32 flags;
735+};
736+
721737 /**
722738 * struct brcmf_pno_net_param_le - scan parameters per preferred network.
723739 *
@@ -769,6 +785,13 @@ struct brcmf_pno_scanresults_le { · 45 unmodified lines
769785 __le32 count;
770786 };
771787
788+struct brcmf_pno_scanresults_v2_le {
789+ __le32 version;
790+ __le32 status;
791+ __le32 count;
792+ __le32 scan_ch_bucket;
793+};
794+
772795 /**
773796 * struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization.
774797 *
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c+18−20
@@ -87,11 +87,6 @@ struct msgbuf_common_hdr { · 86 unmodified lines
8787 __le32 request_id;
8888 };
8989
90−struct msgbuf_buf_addr {
91− __le32 low_addr;
92− __le32 high_addr;
93−};
94−
9590 struct msgbuf_ioctl_req_hdr {
9691 struct msgbuf_common_hdr msg;
9792 __le32 cmd;
@@ -227,7 +222,10 @@ struct brcmf_msgbuf { · 129 unmodified lines
227222 struct brcmf_commonring **commonrings;
228223 struct brcmf_commonring **flowrings;
229224 dma_addr_t *flowring_dma_handle;
230− u16 nrof_flowrings;
225+
226+ u16 max_flowrings;
227+ u16 max_submissionrings;
228+ u16 max_completionrings;
231229
232230 u16 rx_dataoffset;
233231 u32 max_rxbufpost;
@@ -610,7 +608,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf, · 376 unmodified lines
610608 create->msg.request_id = 0;
611609 create->tid = brcmf_flowring_tid(msgbuf->flow, flowid);
612610 create->flow_ring_id = cpu_to_le16(flowid +
613− BRCMF_NROF_H2D_COMMON_MSGRINGS);
611+ BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
614612 memcpy(create->sa, work->sa, ETH_ALEN);
615613 memcpy(create->da, work->da, ETH_ALEN);
616614 address = (u64)msgbuf->flowring_dma_handle[flowid];
@@ -760,7 +758,7 @@ static void brcmf_msgbuf_txflow_worker(struct work_struct *worker) · 143 unmodified lines
760758 u32 flowid;
761759
762760 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) {
764762 clear_bit(flowid, msgbuf->flow_map);
765763 brcmf_msgbuf_txflow(msgbuf, flowid);
766764 }
@@ -866,7 +864,7 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf) · 99 unmodified lines
866864 tx_status = (struct msgbuf_tx_status *)buf;
867865 idx = le32_to_cpu(tx_status->msg.request_id);
868866 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;
870868 skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
871869 msgbuf->tx_pktids, idx);
872870 if (!skb)
@@ -1174,7 +1172,7 @@ brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf, · 301 unmodified lines
11741172 flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf;
11751173
11761174 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;
11781176 status = le16_to_cpu(flowring_create_resp->compl_hdr.status);
11791177
11801178 if (status) {
@@ -1202,7 +1200,7 @@ brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf, · 21 unmodified lines
12021200 flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf;
12031201
12041202 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;
12061204 status = le16_to_cpu(flowring_delete_resp->compl_hdr.status);
12071205
12081206 if (status) {
@@ -1307,7 +1305,7 @@ int brcmf_proto_msgbuf_rx_trigger(struct device *dev) · 98 unmodified lines
13071305 brcmf_msgbuf_process_rx(msgbuf, buf);
13081306
13091307 for_each_set_bit(flowid, msgbuf->txstatus_done_map,
1310− msgbuf->nrof_flowrings) {
1308+ msgbuf->max_flowrings) {
13111309 clear_bit(flowid, msgbuf->txstatus_done_map);
13121310 commonring = msgbuf->flowrings[flowid];
13131311 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
13491347 delete->msg.request_id = 0;
13501348
13511349 delete->flow_ring_id = cpu_to_le16(flowid +
1352− BRCMF_NROF_H2D_COMMON_MSGRINGS);
1350+ BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
13531351 delete->reason = 0;
13541352
13551353 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
14271425
14281426 if_msgbuf = drvr->bus_if->msgbuf;
14291427
1430− if (if_msgbuf->nrof_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
1428+ if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
14311429 brcmf_err("driver not configured for this many flowrings %d\n",
1432− if_msgbuf->nrof_flowrings);
1433− if_msgbuf->nrof_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
1430+ if_msgbuf->max_flowrings);
1431+ if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
14341432 }
14351433
14361434 msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL);
@@ -1443,7 +1441,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) · 6 unmodified lines
14431441 goto fail;
14441442 }
14451443 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);
14471445 count = count * sizeof(unsigned long);
14481446 msgbuf->flow_map = kzalloc(count, GFP_KERNEL);
14491447 if (!msgbuf->flow_map)
@@ -1479,8 +1477,8 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) · 29 unmodified lines
14791477 msgbuf->commonrings =
14801478 (struct brcmf_commonring **)if_msgbuf->commonrings;
14811479 msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings;
1482− msgbuf->nrof_flowrings = if_msgbuf->nrof_flowrings;
1483− msgbuf->flowring_dma_handle = kzalloc(msgbuf->nrof_flowrings *
1480+ msgbuf->max_flowrings = if_msgbuf->max_flowrings;
1481+ msgbuf->flowring_dma_handle = kzalloc(msgbuf->max_flowrings *
14841482 sizeof(*msgbuf->flowring_dma_handle), GFP_KERNEL);
14851483 if (!msgbuf->flowring_dma_handle)
14861484 goto fail;
@@ -1501,7 +1499,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) · 14 unmodified lines
15011499 goto fail;
15021500
15031501 msgbuf->flow = brcmf_flowring_attach(drvr->bus_if->dev,
1504− if_msgbuf->nrof_flowrings);
1502+ if_msgbuf->max_flowrings);
15051503 if (!msgbuf->flow)
15061504 goto fail;
15071505
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h+4−0
@@ -31,6 +31,10 @@ · 30 unmodified lines
3131 #define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 32
3232 #define BRCMF_H2D_TXFLOWRING_ITEMSIZE 48
3333
34+struct msgbuf_buf_addr {
35+ __le32 low_addr;
36+ __le32 high_addr;
37+};
3438
3539 int brcmf_proto_msgbuf_rx_trigger(struct device *dev);
3640 void 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
135135 BRCMF_PCIE_MB_INT_D2H3_DB1)
136136
137137 #define BRCMF_PCIE_MIN_SHARED_VERSION 5
138−#define BRCMF_PCIE_MAX_SHARED_VERSION 5
138+#define BRCMF_PCIE_MAX_SHARED_VERSION 6
139139 #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF
140140 #define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000
141141 #define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000
@@ -166,17 +166,6 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { · 24 unmodified lines
166166 #define BRCMF_RING_MEM_SZ 16
167167 #define BRCMF_RING_STATE_SZ 8
168168
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−
180169 #define BRCMF_DEF_MAX_RXBUFPOST 255
181170
182171 #define BRCMF_CONSOLE_BUFADDR_OFFSET 8
@@ -231,7 +220,9 @@ struct brcmf_pcie_shared_info { · 48 unmodified lines
231220 struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
232221 struct brcmf_pcie_ringbuf *flowrings;
233222 u16 max_rxbufpost;
234− u32 nrof_flowrings;
223+ u16 max_flowrings;
224+ u16 max_submissionrings;
225+ u16 max_completionrings;
235226 u32 rx_dataoffset;
236227 u32 htod_mb_data_addr;
237228 u32 dtoh_mb_data_addr;
@@ -241,6 +232,7 @@ struct brcmf_pcie_shared_info { · 3 unmodified lines
241232 dma_addr_t scratch_dmahandle;
242233 void *ringupd;
243234 dma_addr_t ringupd_dmahandle;
235+ u8 version;
244236 };
245237
246238 struct brcmf_pcie_core_info {
@@ -284,6 +276,36 @@ struct brcmf_pcie_ringbuf { · 37 unmodified lines
284276 u8 id;
285277 };
286278
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+ */
295+struct 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+};
287309
288310 static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = {
289311 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
10541076 {
10551077 struct brcmf_pcie_ringbuf *ring;
10561078 struct brcmf_pcie_ringbuf *rings;
1057− u32 ring_addr;
10581079 u32 d2h_w_idx_ptr;
10591080 u32 d2h_r_idx_ptr;
10601081 u32 h2d_w_idx_ptr;
10611082 u32 h2d_r_idx_ptr;
1062− u32 addr;
10631083 u32 ring_mem_ptr;
10641084 u32 i;
10651085 u64 address;
10661086 u32 bufsz;
1067− u16 max_sub_queues;
10681087 u8 idx_offset;
1069−
1070− ring_addr = devinfo->shared.ring_info_addr;
1071− brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr);
1072− addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES;
1073− max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr);
1088+ struct brcmf_pcie_dhi_ringinfo ringinfo;
1089+ u16 max_flowrings;
1090+ u16 max_submissionrings;
1091+ u16 max_completionrings;
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+ }
10741105
10751106 if (devinfo->dma_idx_sz != 0) {
1076− bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) *
1107+ bufsz = (max_submissionrings + max_completionrings) *
10771108 devinfo->dma_idx_sz * 2;
10781109 devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz,
10791110 &devinfo->idxbuf_dmahandle,
@@ -1083,14 +1114,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) · 3 unmodified lines
10831114 }
10841115
10851116 if (devinfo->dma_idx_sz == 0) {
1086− addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET;
1087− d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
1088− addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET;
1089− d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
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);
1117+ d2h_w_idx_ptr = le32_to_cpu(ringinfo.d2h_w_idx_ptr);
1118+ d2h_r_idx_ptr = le32_to_cpu(ringinfo.d2h_r_idx_ptr);
1119+ h2d_w_idx_ptr = le32_to_cpu(ringinfo.h2d_w_idx_ptr);
1120+ h2d_r_idx_ptr = le32_to_cpu(ringinfo.h2d_r_idx_ptr);
10941121 idx_offset = sizeof(u32);
10951122 devinfo->write_ptr = brcmf_pcie_write_tcm16;
10961123 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
11031130 devinfo->read_ptr = brcmf_pcie_read_idx;
11041131
11051132 h2d_w_idx_ptr = 0;
1106− addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET;
11071133 address = (u64)devinfo->idxbuf_dmahandle;
1108− brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
1109− brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
1110−
1111− h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset;
1112− addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET;
1113− address += max_sub_queues * idx_offset;
1114− brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
1115− brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
1116−
1117− d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset;
1118− addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET;
1119− address += max_sub_queues * idx_offset;
1120− brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
1121− brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
1134+ ringinfo.h2d_w_idx_hostaddr.low_addr =
1135+ cpu_to_le32(address & 0xffffffff);
1136+ ringinfo.h2d_w_idx_hostaddr.high_addr =
1137+ cpu_to_le32(address >> 32);
1138+
1139+ h2d_r_idx_ptr = h2d_w_idx_ptr +
1140+ max_submissionrings * idx_offset;
1141+ address += max_submissionrings * idx_offset;
1142+ ringinfo.h2d_r_idx_hostaddr.low_addr =
1143+ cpu_to_le32(address & 0xffffffff);
1144+ ringinfo.h2d_r_idx_hostaddr.high_addr =
1145+ cpu_to_le32(address >> 32);
1146+
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);
11221154
11231155 d2h_r_idx_ptr = d2h_w_idx_ptr +
1124− BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
1125− addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET;
1126− address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
1127− brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
1128− brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
1156+ max_completionrings * idx_offset;
1157+ address += max_completionrings * idx_offset;
1158+ ringinfo.d2h_r_idx_hostaddr.low_addr =
1159+ cpu_to_le32(address & 0xffffffff);
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));
11291165 brcmf_dbg(PCIE, "Using host memory indices\n");
11301166 }
11311167
1132− addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET;
1133− ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
1168+ ring_mem_ptr = le32_to_cpu(ringinfo.ringmem);
11341169
11351170 for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) {
11361171 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
11611196 ring_mem_ptr += BRCMF_RING_MEM_SZ;
11621197 }
11631198
1164− devinfo->shared.nrof_flowrings =
1165− max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS;
1166− rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring),
1167− GFP_KERNEL);
1199+ devinfo->shared.max_flowrings = max_flowrings;
1200+ devinfo->shared.max_submissionrings = max_submissionrings;
1201+ devinfo->shared.max_completionrings = max_completionrings;
1202+ rings = kcalloc(max_flowrings, sizeof(*ring), GFP_KERNEL);
11681203 if (!rings)
11691204 goto fail;
11701205
1171− brcmf_dbg(PCIE, "Nr of flowrings is %d\n",
1172− devinfo->shared.nrof_flowrings);
1206+ brcmf_dbg(PCIE, "Nr of flowrings is %d\n", max_flowrings);
11731207
1174− for (i = 0; i < devinfo->shared.nrof_flowrings; i++) {
1208+ for (i = 0; i < max_flowrings; i++) {
11751209 ring = &rings[i];
11761210 ring->devinfo = devinfo;
1177− ring->id = i + BRCMF_NROF_COMMON_MSGRINGS;
1211+ ring->id = i + BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
11781212 brcmf_commonring_register_cb(&ring->commonring,
11791213 brcmf_pcie_ring_mb_ring_bell,
11801214 brcmf_pcie_ring_mb_update_rptr,
@@ -1357,17 +1391,16 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, · 176 unmodified lines
13571391 {
13581392 struct brcmf_pcie_shared_info *shared;
13591393 u32 addr;
1360− u32 version;
13611394
13621395 shared = &devinfo->shared;
13631396 shared->tcm_base_address = sharedram_addr;
13641397
13651398 shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr);
1366− version = shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK;
1367− brcmf_dbg(PCIE, "PCIe protocol version %d\n", version);
1368− if ((version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
1369− (version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
1370− brcmf_err("Unsupported PCIE version %d\n", version);
1399+ shared->version = (u8)(shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK);
1400+ brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version);
1401+ if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
1402+ (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
1403+ brcmf_err("Unsupported PCIE version %d\n", shared->version);
13711404 return -EINVAL;
13721405 }
13731406
@@ -1661,18 +1694,18 @@ static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw, · 287 unmodified lines
16611694 bus->msgbuf->commonrings[i] =
16621695 &devinfo->shared.commonrings[i]->commonring;
16631696
1664− flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings),
1697+ flowrings = kcalloc(devinfo->shared.max_flowrings, sizeof(*flowrings),
16651698 GFP_KERNEL);
16661699 if (!flowrings)
16671700 goto fail;
16681701
1669− for (i = 0; i < devinfo->shared.nrof_flowrings; i++)
1702+ for (i = 0; i < devinfo->shared.max_flowrings; i++)
16701703 flowrings[i] = &devinfo->shared.flowrings[i].commonring;
16711704 bus->msgbuf->flowrings = flowrings;
16721705
16731706 bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset;
16741707 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;
16761709
16771710 init_waitqueue_head(&devinfo->mbdata_resp_wait);
16781711
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+
38+static 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+
47+static 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+
100+exit:
101+ return err;
102+}
103+
104+static 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+
131+static 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+
147+static 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+
165+int 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+
181+int 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+ */
29+int 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+ */
37+int 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
621621 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330),
622622 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334),
623623 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340),
624+ BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340),
624625 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335),
625626 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
626627 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
179179 return u16extraSignBits;
180180 }
181181
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 */
183183 static const s16 log_table[] = {
184184 0,
185185 1455,
@@ -212,7 +212,8 @@ static const s16 log_table[] = { · 26 unmodified lines
212212 29717,
213213 30498,
214214 31267,
215− 32024
215+ 32024,
216+ 32768
216217 };
217218
218219 #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
3636 #define BRCM_CC_4330_CHIP_ID 0x4330
3737 #define BRCM_CC_4334_CHIP_ID 0x4334
3838 #define BRCM_CC_43340_CHIP_ID 43340
39+#define BRCM_CC_43341_CHIP_ID 43341
3940 #define BRCM_CC_43362_CHIP_ID 43362
4041 #define BRCM_CC_4335_CHIP_ID 0x4335
4142 #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
21432143 ret = mwifiex_set_encode(priv, NULL, NULL, 0, 0, NULL, 1);
21442144
21452145 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+
21462156 /* "privacy" is set only for ad-hoc mode */
21472157 if (privacy) {
21482158 /*
@@ -3980,13 +3990,11 @@ static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, · 1831 unmodified lines
39803990 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
39813991 struct mwifiex_ds_misc_cmd *hostcmd;
39823992 struct nlattr *tb[MWIFIEX_TM_ATTR_MAX + 1];
3983− struct mwifiex_adapter *adapter;
39843993 struct sk_buff *skb;
39853994 int err;
39863995
39873996 if (!priv)
39883997 return -EINVAL;
3989− adapter = priv->adapter;
39903998
39913999 err = nla_parse(tb, MWIFIEX_TM_ATTR_MAX, data, len,
39924000 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
219219 #define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14))
220220 #define ISSUPP_DRCS_ENABLED(FwCapInfo) (FwCapInfo & BIT(15))
221221 #define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16))
222+#define ISSUPP_ADHOC_ENABLED(FwCapInfo) (FwCapInfo & BIT(25))
222223
223224 #define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
224225 (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
518518 {
519519 int ret;
520520 char fmt[64];
521− struct mwifiex_private *priv;
522521 struct mwifiex_adapter *adapter = context;
523522 struct mwifiex_fw_image fw;
524523 bool init_failed = false;
@@ -576,8 +575,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) · 51 unmodified lines
576575 goto err_init_fw;
577576 }
578577
579− priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
580−
581578 if (!adapter->wiphy) {
582579 if (mwifiex_register_cfg80211(adapter)) {
583580 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
14241424 {
14251425 if (adapter->irq_wakeup >= 0) {
14261426 disable_irq_wake(adapter->irq_wakeup);
1427− if (!adapter->wake_by_wifi)
1428− disable_irq(adapter->irq_wakeup);
1427+ 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+
14291434 }
14301435 }
14311436
drivers/net/wireless/marvell/mwifiex/pcie.c+14−3
@@ -135,6 +135,7 @@ static int mwifiex_pcie_suspend(struct device *dev) · 134 unmodified lines
135135 mwifiex_dbg(adapter, ERROR,
136136 "cmd: failed to suspend\n");
137137 adapter->hs_enabling = false;
138+ mwifiex_disable_wake(adapter);
138139 return -EFAULT;
139140 }
140141
@@ -2050,7 +2051,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, · 1909 unmodified lines
20502051 }
20512052
20522053 /* Wait for the command done interrupt */
2053− do {
2054+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
20542055 if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
20552056 &ireg_intr)) {
20562057 mwifiex_dbg(adapter, ERROR,
@@ -2062,8 +2063,18 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, · 5 unmodified lines
20622063 ret = -1;
20632064 goto done;
20642065 }
2065− } while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
2066− CPU_INTR_DOOR_BELL);
2066+ if (!(ireg_intr & 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+ }
20672078
20682079 mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
20692080
drivers/net/wireless/marvell/mwifiex/scan.c+3−5
@@ -827,7 +827,6 @@ mwifiex_config_scan(struct mwifiex_private *priv, · 826 unmodified lines
827827 u32 num_probes;
828828 u32 ssid_len;
829829 u32 chan_idx;
830− u32 chan_num;
831830 u32 scan_type;
832831 u16 scan_dur;
833832 u8 channel;
@@ -1105,13 +1104,12 @@ mwifiex_config_scan(struct mwifiex_private *priv, · 271 unmodified lines
11051104 mwifiex_dbg(adapter, INFO,
11061105 "info: Scan: Scanning current channel only\n");
11071106 }
1108− chan_num = chan_idx;
11091107 } else {
11101108 mwifiex_dbg(adapter, INFO,
11111109 "info: Scan: Creating full region channel list\n");
1112− chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in,
1113− scan_chan_list,
1114− *filtered_scan);
1110+ mwifiex_scan_create_channel_list(priv, user_scan_in,
1111+ scan_chan_list,
1112+ *filtered_scan);
11151113 }
11161114
11171115 }
drivers/net/wireless/marvell/mwifiex/sdio.c+1−5
@@ -186,9 +186,7 @@ static int mwifiex_sdio_resume(struct device *dev) · 185 unmodified lines
186186 struct sdio_func *func = dev_to_sdio_func(dev);
187187 struct sdio_mmc_card *card;
188188 struct mwifiex_adapter *adapter;
189− mmc_pm_flag_t pm_flag = 0;
190189
191− pm_flag = sdio_get_host_pm_caps(func);
192190 card = sdio_get_drvdata(func);
193191 if (!card || !card->adapter) {
194192 dev_err(dev, "resume: invalid card or adapter\n");
@@ -298,6 +296,7 @@ static int mwifiex_sdio_suspend(struct device *dev) · 103 unmodified lines
298296 mwifiex_dbg(adapter, ERROR,
299297 "cmd: failed to suspend\n");
300298 adapter->hs_enabling = false;
299+ mwifiex_disable_wake(adapter);
301300 return -EFAULT;
302301 }
303302
@@ -1136,7 +1135,6 @@ static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter, · 832 unmodified lines
11361135 {
11371136 u32 total_pkt_len, pkt_len;
11381137 struct sk_buff *skb_deaggr;
1139− u32 pkt_type;
11401138 u16 blk_size;
11411139 u8 blk_num;
11421140 u8 *data;
@@ -1157,8 +1155,6 @@ static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter, · 14 unmodified lines
11571155 break;
11581156 }
11591157 pkt_len = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET));
1160− pkt_type = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET +
1161− 2));
11621158 if ((pkt_len + SDIO_HEADER_OFFSET) > blk_size) {
11631159 mwifiex_dbg(adapter, ERROR,
11641160 "%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
17461746 {
17471747 struct host_cmd_ds_tdls_oper *tdls_oper = &cmd->params.tdls_oper;
17481748 struct mwifiex_ds_tdls_oper *oper = data_buf;
1749− struct mwifiex_sta_node *sta_ptr;
17501749 struct host_cmd_tlv_rates *tlv_rates;
17511750 struct mwifiex_ie_types_htcap *ht_capab;
17521751 struct mwifiex_ie_types_qos_info *wmm_qos_info;
@@ -1764,7 +1763,6 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv, · 11 unmodified lines
17641763
17651764 tdls_oper->reason = 0;
17661765 memcpy(tdls_oper->peer_mac, oper->peer_mac, ETH_ALEN);
1767− sta_ptr = mwifiex_get_sta_entry(priv, oper->peer_mac);
17681766
17691767 pos = (u8 *)tdls_oper + sizeof(struct host_cmd_ds_tdls_oper);
17701768
@@ -1902,6 +1900,24 @@ static int mwifiex_cmd_get_wakeup_reason(struct mwifiex_private *priv, · 131 unmodified lines
19021900 return 0;
19031901 }
19041902
1903+/* This function check if the command is supported by firmware */
1904+static 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+
19051921 /*
19061922 * This function prepares the commands before sending them to the firmware.
19071923 *
@@ -1915,6 +1931,13 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, · 7 unmodified lines
19151931 struct host_cmd_ds_command *cmd_ptr = cmd_buf;
19161932 int ret = 0;
19171933
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+
19181941 /* Prepare command */
19191942 switch (cmd_no) {
19201943 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
22082231 {
22092232 struct mwifiex_adapter *adapter = priv->adapter;
22102233 int ret;
2211− u16 enable = true;
22122234 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
22132235 struct mwifiex_ds_auto_ds auto_ds;
22142236 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
23212343 if (ret)
23222344 return -1;
23232345
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−
23342346 memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
23352347 amsdu_aggr_ctrl.enable = true;
23362348 /* 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
379379 struct usb_endpoint_descriptor *epd;
380380 int ret, i;
381381 struct usb_card_rec *card;
382− u16 id_vendor, id_product, bcd_device, bcd_usb;
382+ u16 id_vendor, id_product, bcd_device;
383383
384384 card = devm_kzalloc(&intf->dev, sizeof(*card), GFP_KERNEL);
385385 if (!card)
@@ -390,7 +390,6 @@ static int mwifiex_usb_probe(struct usb_interface *intf, · 4 unmodified lines
390390 id_vendor = le16_to_cpu(udev->descriptor.idVendor);
391391 id_product = le16_to_cpu(udev->descriptor.idProduct);
392392 bcd_device = le16_to_cpu(udev->descriptor.bcdDevice);
393− bcd_usb = le16_to_cpu(udev->descriptor.bcdUSB);
394393 pr_debug("info: VID/PID = %X/%X, Boot2 version = %X\n",
395394 id_vendor, id_product, bcd_device);
396395
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
293293 ok = 0;
294294 i = 200;
295295 while (i--) {
296− if ((mt76_rr(dev, 0x0430) & 0x00ff0000) ||
297− (mt76_rr(dev, 0x0a30) & 0xffffffff) ||
298− (mt76_rr(dev, 0x0a34) & 0xffffffff))
299− ok++;
300− if (ok > 6)
301− break;
302−
296+ if (!(mt76_rr(dev, MT_RXQ_STA) & 0x00ff0000) &&
297+ !mt76_rr(dev, 0x0a30) &&
298+ !mt76_rr(dev, 0x0a34)) {
299+ if (ok++ > 5)
300+ break;
301+ continue;
302+ }
303303 msleep(1);
304304 }
305305
drivers/net/wireless/mediatek/mt7601u/regs.h+3−0
@@ -192,6 +192,9 @@ · 191 unmodified lines
192192 #define MT_BCN_OFFSET_BASE 0x041c
193193 #define MT_BCN_OFFSET(_n) (MT_BCN_OFFSET_BASE + ((_n) << 2))
194194
195+#define MT_RXQ_STA 0x0430
196+#define MT_TXQ_STA 0x0434
197+
195198 #define MT_RF_CSR_CFG 0x0500
196199 #define MT_RF_CSR_CFG_DATA GENMASK(7, 0)
197200 #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
13371337 u32 ramask, int sgi);
13381338 void (*report_connect) (struct rtl8xxxu_priv *priv,
13391339 u8 macid, bool connect);
1340− void (*fill_txdesc) (struct ieee80211_hdr *hdr,
1341− struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
1342− u16 rate_flag, bool sgi, bool short_preamble,
1343− bool ampdu_enable);
1340+ void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
1341+ struct ieee80211_tx_info *tx_info,
1342+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
1343+ bool short_preamble, bool ampdu_enable,
1344+ u32 rts_rate);
13441345 int writeN_block_size;
13451346 int rx_agg_buf_size;
13461347 char tx_desc_size;
@@ -1434,14 +1435,16 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb); · 87 unmodified lines
14341435 int rtl8xxxu_gen2_channel_to_group(int channel);
14351436 bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv,
14361437 int result[][8], int c1, int c2);
1437−void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
1438− struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
1439− u16 rate_flag, bool sgi, bool short_preamble,
1440− bool ampdu_enable);
1441−void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr,
1442− struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate,
1443− u16 rate_flag, bool sgi, bool short_preamble,
1444− bool ampdu_enable);
1438+void rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
1439+ struct ieee80211_tx_info *tx_info,
1440+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
1441+ bool short_preamble, bool ampdu_enable,
1442+ u32 rts_rate);
1443+void rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
1444+ struct ieee80211_tx_info *tx_info,
1445+ struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
1446+ bool short_preamble, bool ampdu_enable,
1447+ u32 rts_rate);
14451448
14461449 extern struct rtl8xxxu_fileops rtl8192cu_fops;
14471450 extern struct rtl8xxxu_fileops rtl8192eu_fops;
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c+1−1
@@ -1556,7 +1556,7 @@ exit: · 1555 unmodified lines
15561556 return ret;
15571557 }
15581558
1559−void rtl8192eu_power_off(struct rtl8xxxu_priv *priv)
1559+static void rtl8192eu_power_off(struct rtl8xxxu_priv *priv)
15601560 {
15611561 u8 val8;
15621562 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
43724372 void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
43734373 u8 macid, bool connect)
43744374 {
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+ */
43754382 struct h2c_cmd h2c;
43764383
43774384 memset(&h2c, 0, sizeof(struct h2c_cmd));
@@ -4383,6 +4390,7 @@ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, · 5 unmodified lines
43834390 h2c.media_status_rpt.parm &= ~BIT(0);
43844391
43854392 rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt));
4393+#endif
43864394 }
43874395
43884396 void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
@@ -4759,13 +4767,28 @@ static void rtl8xxxu_dump_action(struct device *dev, · 370 unmodified lines
47594767 * This format is used on 8188cu/8192cu/8723au
47604768 */
47614769 void
4762−rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr,
4763− struct rtl8xxxu_txdesc32 *tx_desc, u32 rate,
4764− u16 rate_flag, bool sgi, bool short_preamble,
4765− bool ampdu_enable)
4770+rtl8xxxu_fill_txdesc_v1(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
4771+ struct ieee80211_tx_info *tx_info,
4772+ struct rtl8xxxu_txdesc32 *tx_desc, bool sgi,
4773+ bool short_preamble, bool ampdu_enable, u32 rts_rate)
47664774 {
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;
47674780 u16 seq_number;
47684781
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+
47694792 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
47704793
47714794 tx_desc->txdw5 = cpu_to_le32(rate);
@@ -4796,15 +4819,16 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, · 24 unmodified lines
47964819 if (sgi)
47974820 tx_desc->txdw5 |= cpu_to_le32(TXDESC32_SHORT_GI);
47984821
4799− if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
4800− /*
4801− * Use RTS rate 24M - does the mac80211 tell
4802− * us which to use?
4803− */
4804− tx_desc->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
4805− TXDESC32_RTS_RATE_SHIFT);
4822+ /*
4823+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
4824+ */
4825+ tx_desc->txdw4 |= cpu_to_le32(rts_rate << TXDESC32_RTS_RATE_SHIFT);
4826+ if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
48064827 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_RTS_CTS_ENABLE);
48074828 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);
48084832 }
48094833 }
48104834
@@ -4813,16 +4837,31 @@ rtl8xxxu_fill_txdesc_v1(struct ieee80211_hdr *hdr, · 2 unmodified lines
48134837 * This format is used on 8192eu/8723bu
48144838 */
48154839 void
4816−rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr,
4817− struct rtl8xxxu_txdesc32 *tx_desc32, u32 rate,
4818− u16 rate_flag, bool sgi, bool short_preamble,
4819− bool ampdu_enable)
4840+rtl8xxxu_fill_txdesc_v2(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
4841+ struct ieee80211_tx_info *tx_info,
4842+ struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi,
4843+ bool short_preamble, bool ampdu_enable, u32 rts_rate)
48204844 {
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;
48214848 struct rtl8xxxu_txdesc40 *tx_desc40;
4849+ u32 rate;
4850+ u16 rate_flags = tx_info->control.rates[0].flags;
48224851 u16 seq_number;
48234852
48244853 tx_desc40 = (struct rtl8xxxu_txdesc40 *)tx_desc32;
48254854
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+
48264865 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
48274866
48284867 tx_desc40->txdw4 = cpu_to_le32(rate);
@@ -4849,15 +4888,19 @@ rtl8xxxu_fill_txdesc_v2(struct ieee80211_hdr *hdr, · 20 unmodified lines
48494888 if (short_preamble)
48504889 tx_desc40->txdw5 |= cpu_to_le32(TXDESC40_SHORT_PREAMBLE);
48514890
4852− if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
4853− /*
4854− * Use RTS rate 24M - does the mac80211 tell
4855− * us which to use?
4856− */
4857− tx_desc40->txdw4 |= cpu_to_le32(DESC_RATE_24M <<
4858− TXDESC40_RTS_RATE_SHIFT);
4891+ tx_desc40->txdw4 |= cpu_to_le32(rts_rate << TXDESC40_RTS_RATE_SHIFT);
4892+ /*
4893+ * rts_rate is zero if RTS/CTS or CTS to SELF are not enabled
4894+ */
4895+ if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
48594896 tx_desc40->txdw3 |= cpu_to_le32(TXDESC40_RTS_CTS_ENABLE);
48604897 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);
48614904 }
48624905 }
48634906
@@ -4867,14 +4910,13 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, · 3 unmodified lines
48674910 {
48684911 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
48694912 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
4870− struct ieee80211_rate *tx_rate = ieee80211_get_tx_rate(hw, tx_info);
48714913 struct rtl8xxxu_priv *priv = hw->priv;
48724914 struct rtl8xxxu_txdesc32 *tx_desc;
48734915 struct rtl8xxxu_tx_urb *tx_urb;
48744916 struct ieee80211_sta *sta = NULL;
48754917 struct ieee80211_vif *vif = tx_info->control.vif;
48764918 struct device *dev = &priv->udev->dev;
4877− u32 queue, rate;
4919+ u32 queue, rts_rate;
48784920 u16 pktlen = skb->len;
48794921 u16 seq_number;
48804922 u16 rate_flag = tx_info->control.rates[0].flags;
@@ -4901,10 +4943,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, · 20 unmodified lines
49014943 goto error;
49024944 }
49034945
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−
49084946 if (ieee80211_is_action(hdr->frame_control))
49094947 rtl8xxxu_dump_action(dev, hdr);
49104948
@@ -4958,12 +4996,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, · 47 unmodified lines
49584996 }
49594997 }
49604998
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−
49674999 if (rate_flag & IEEE80211_TX_RC_SHORT_GI ||
49685000 (ieee80211_is_data_qos(hdr->frame_control) &&
49695001 sta && sta->ht_cap.cap &
@@ -4974,10 +5006,17 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw, · 4 unmodified lines
49745006 (sta && vif && vif->bss_conf.use_short_preamble))
49755007 short_preamble = true;
49765008
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+
49775016 seq_number = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
49785017
4979− priv->fops->fill_txdesc(hdr, tx_desc, rate, rate_flag,
4980− sgi, short_preamble, ampdu_enable);
5018+ priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble,
5019+ ampdu_enable, rts_rate);
49815020
49825021 rtl8xxxu_calc_tx_desc_csum(tx_desc);
49835022
drivers/net/wireless/realtek/rtlwifi/base.c+4−4
@@ -1303,12 +1303,13 @@ EXPORT_SYMBOL_GPL(rtl_action_proc); · 1302 unmodified lines
13031303
13041304 static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc)
13051305 {
1306+ struct ieee80211_hw *hw = rtlpriv->hw;
1307+
13061308 rtlpriv->ra.is_special_data = true;
13071309 if (rtlpriv->cfg->ops->get_btc_status())
13081310 rtlpriv->btcoexist.btc_ops->btc_special_packet_notify(
13091311 rtlpriv, 1);
1310− rtlpriv->enter_ps = false;
1311− schedule_work(&rtlpriv->works.lps_change_work);
1312+ rtl_lps_leave(hw);
13121313 ppsc->last_delaylps_stamp_jiffies = jiffies;
13131314 }
13141315
@@ -1381,8 +1382,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx, · 66 unmodified lines
13811382
13821383 if (is_tx) {
13831384 rtlpriv->ra.is_special_data = true;
1384− rtlpriv->enter_ps = false;
1385− schedule_work(&rtlpriv->works.lps_change_work);
1385+ rtl_lps_leave(hw);
13861386 ppsc->last_delaylps_stamp_jiffies = jiffies;
13871387 }
13881388
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
11501150 } else {
11511151 mstatus = RT_MEDIA_DISCONNECT;
11521152
1153− if (mac->link_state == MAC80211_LINKED) {
1154− rtlpriv->enter_ps = false;
1155− schedule_work(&rtlpriv->works.lps_change_work);
1156− }
1153+ if (mac->link_state == MAC80211_LINKED)
1154+ rtl_lps_leave(hw);
11571155 if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
11581156 rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
11591157 mac->link_state = MAC80211_NOLINK;
@@ -1431,8 +1429,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw, · 271 unmodified lines
14311429 }
14321430
14331431 if (mac->link_state == MAC80211_LINKED) {
1434− rtlpriv->enter_ps = false;
1435− schedule_work(&rtlpriv->works.lps_change_work);
1432+ rtl_lps_leave(hw);
14361433 mac->link_state = MAC80211_LINKED_SCANNING;
14371434 } else {
14381435 rtl_ips_nic_on(hw);
drivers/net/wireless/realtek/rtlwifi/pci.c+5−9
@@ -659,11 +659,9 @@ tx_status_ok: · 658 unmodified lines
659659 }
660660
661661 if (((rtlpriv->link_info.num_rx_inperiod +
662− rtlpriv->link_info.num_tx_inperiod) > 8) ||
663− (rtlpriv->link_info.num_rx_inperiod > 2)) {
664− rtlpriv->enter_ps = false;
665− schedule_work(&rtlpriv->works.lps_change_work);
666− }
662+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
663+ (rtlpriv->link_info.num_rx_inperiod > 2))
664+ rtl_lps_leave(hw);
667665 }
668666
669667 static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
@@ -914,10 +912,8 @@ new_trx_end: · 244 unmodified lines
914912 }
915913 if (((rtlpriv->link_info.num_rx_inperiod +
916914 rtlpriv->link_info.num_tx_inperiod) > 8) ||
917− (rtlpriv->link_info.num_rx_inperiod > 2)) {
918− rtlpriv->enter_ps = false;
919− schedule_work(&rtlpriv->works.lps_change_work);
920− }
915+ (rtlpriv->link_info.num_rx_inperiod > 2))
916+ rtl_lps_leave(hw);
921917 skb = new_skb;
922918 no_new:
923919 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
407407 }
408408 }
409409
410−/*Enter the leisure power save mode.*/
411−void rtl_lps_enter(struct ieee80211_hw *hw)
410+/* Interrupt safe routine to enter the leisure power save mode.*/
411+static void rtl_lps_enter_core(struct ieee80211_hw *hw)
412412 {
413413 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
414414 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
444444
445445 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
446446 }
447−EXPORT_SYMBOL(rtl_lps_enter);
448447
449−/*Leave the leisure power save mode.*/
450−void rtl_lps_leave(struct ieee80211_hw *hw)
448+/* Interrupt safe routine to leave the leisure power save mode.*/
449+static void rtl_lps_leave_core(struct ieee80211_hw *hw)
451450 {
452451 struct rtl_priv *rtlpriv = rtl_priv(hw);
453452 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
477476 }
478477 spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
479478 }
480−EXPORT_SYMBOL(rtl_lps_leave);
481479
482480 /* For sw LPS*/
483481 void 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
670668 struct rtl_priv *rtlpriv = rtl_priv(hw);
671669
672670 if (rtlpriv->enter_ps)
673− rtl_lps_enter(hw);
671+ rtl_lps_enter_core(hw);
674672 else
675− rtl_lps_leave(hw);
673+ rtl_lps_leave_core(hw);
676674 }
677675 EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback);
678676
677+void 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+}
686+EXPORT_SYMBOL_GPL(rtl_lps_enter);
687+
688+void 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+}
697+EXPORT_SYMBOL_GPL(rtl_lps_leave);
698+
679699 void rtl_swlps_wq_callback(void *data)
680700 {
681701 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
275275 common->iface_down = false;
276276 mutex_unlock(&common->mutex);
277277
278+ rsi_send_rx_filter_frame(common, 0);
279+
278280 return 0;
279281 }
280282
@@ -388,7 +390,7 @@ static int rsi_channel_change(struct ieee80211_hw *hw) · 107 unmodified lines
388390
389391 status = rsi_band_check(common);
390392 if (!status)
391− status = rsi_set_channel(adapter->priv, channel);
393+ status = rsi_set_channel(adapter->priv, curchan);
392394
393395 if (bss->assoc) {
394396 if (common->hw_data_qs_blocked &&
@@ -408,6 +410,34 @@ static int rsi_channel_change(struct ieee80211_hw *hw) · 13 unmodified lines
408410 return status;
409411 }
410412
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+ */
419+static 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+
411441 /**
412442 * rsi_mac80211_config() - This function is a handler for configuration
413443 * requests. The stack calls this function to
@@ -429,6 +459,12 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw, · 15 unmodified lines
429459 if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
430460 status = rsi_channel_change(hw);
431461
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+
432468 mutex_unlock(&common->mutex);
433469
434470 return status;
@@ -471,11 +507,19 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, · 36 unmodified lines
471507 {
472508 struct rsi_hw *adapter = hw->priv;
473509 struct rsi_common *common = adapter->priv;
510+ u16 rx_filter_word = 0;
474511
475512 mutex_lock(&common->mutex);
476513 if (changed & BSS_CHANGED_ASSOC) {
477514 rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n",
478515 __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+ }
479523 rsi_inform_bss_status(common,
480524 bss_conf->assoc,
481525 bss_conf->bssid,
@@ -1013,6 +1057,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, · 531 unmodified lines
10131057 struct rsi_common *common = adapter->priv;
10141058
10151059 mutex_lock(&common->mutex);
1060+
10161061 /* Resetting all the fields to default values */
10171062 common->bitrate_mask[NL80211_BAND_2GHZ] = 0;
10181063 common->bitrate_mask[NL80211_BAND_5GHZ] = 0;
@@ -1022,9 +1067,114 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, · 3 unmodified lines
10221067 common->vif_info[0].seq_start = 0;
10231068 common->secinfo.ptk_cipher = 0;
10241069 common->secinfo.gtk_cipher = 0;
1070+
1071+ rsi_send_rx_filter_frame(common, 0);
1072+
10251073 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+ */
1087+static 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;
10261093
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+
10271120 return 0;
1121+
1122+fail_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+ */
1138+static 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+
1154+static 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;
10281178 }
10291179
10301180 static struct ieee80211_ops mac80211_ops = {
@@ -1043,6 +1193,8 @@ static struct ieee80211_ops mac80211_ops = { · 12 unmodified lines
10431193 .ampdu_action = rsi_mac80211_ampdu_action,
10441194 .sta_add = rsi_mac80211_sta_add,
10451195 .sta_remove = rsi_mac80211_sta_remove,
1196+ .set_antenna = rsi_mac80211_set_antenna,
1197+ .get_antenna = rsi_mac80211_get_antenna,
10461198 };
10471199
10481200 /**
@@ -1107,6 +1259,8 @@ int rsi_mac80211_attach(struct rsi_common *common) · 58 unmodified lines
11071259 wiphy->bands[NL80211_BAND_5GHZ] =
11081260 &adapter->sbands[NL80211_BAND_5GHZ];
11091261
1262+ wiphy->reg_notifier = rsi_reg_notify;
1263+
11101264 status = ieee80211_register_hw(hw);
11111265 if (status)
11121266 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
913913 *
914914 * Return: 0 on success, corresponding error code on failure.
915915 */
916−int rsi_set_channel(struct rsi_common *common, u16 channel)
916+int rsi_set_channel(struct rsi_common *common,
917+ struct ieee80211_channel *channel)
917918 {
918919 struct sk_buff *skb = NULL;
919920 struct rsi_mac_frame *mgmt_frame;
@@ -928,24 +929,76 @@ int rsi_set_channel(struct rsi_common *common, u16 channel) · 8 unmodified lines
928929 return -ENOMEM;
929930 }
930931
932+ if (!channel) {
933+ dev_kfree_skb(skb);
934+ return 0;
935+ }
931936 memset(skb->data, 0, FRAME_DESC_SZ);
932937 mgmt_frame = (struct rsi_mac_frame *)skb->data;
933938
934939 mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
935940 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));
937947
938948 mgmt_frame->desc_word[7] = cpu_to_le16(PUT_BBP_RESET |
939949 BBP_REG_WRITE |
940950 (RSI_RF_TYPE << 4));
941951
942− mgmt_frame->desc_word[5] = cpu_to_le16(0x01);
943− mgmt_frame->desc_word[6] = cpu_to_le16(0x12);
952+ if (!(channel->flags & IEEE80211_CHAN_NO_IR) &&
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);
944960
945961 if (common->channel_width == BW_40MHZ)
946962 mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8);
947963
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+ */
979+int 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);
9491002
9501003 skb_put(skb, FRAME_DESC_SZ);
9511004
@@ -1243,6 +1296,72 @@ int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event) · 291 unmodified lines
12431296
12441297 }
12451298
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+ */
1307+int 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+ */
1342+int 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+}
12461365
12471366 /**
12481367 * 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
204204 struct cqm_info cqm_info;
205205
206206 bool hw_data_qs_blocked;
207+
208+ int tx_power;
209+ u8 ant_in_use;
207210 };
208211
209212 struct rsi_hw {
@@ -220,6 +223,7 @@ struct rsi_hw { · 10 unmodified lines
220223 struct rsi_debugfs *dfsentry;
221224 u8 num_debugfs_entries;
222225 #endif
226+ u8 dfs_region;
223227 void *rsi_dev;
224228 int (*host_intf_read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
225229 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
140140
141141 #define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\
142142 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+
143156 enum opmode {
144157 STA_OPMODE = 1,
145158 AP_OPMODE = 2
@@ -190,7 +203,9 @@ enum cmd_frame_type { · 44 unmodified lines
190203 BG_SCAN_PARAMS,
191204 BG_SCAN_PROBE_REQ,
192205 CW_MODE_REQ,
193− PER_CMD_PKT
206+ PER_CMD_PKT,
207+ ANT_SEL_FRAME = 0x20,
208+ RADIO_PARAMS_UPDATE = 0x29
194209 };
195210
196211 struct rsi_mac_frame {
@@ -299,7 +314,8 @@ int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid, · 102 unmodified lines
299314 u16 ssn, u8 buf_size, u8 event);
300315 int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len,
301316 u8 key_type, u8 key_id, u32 cipher);
302−int rsi_set_channel(struct rsi_common *common, u16 chno);
317+int rsi_set_channel(struct rsi_common *common,
318+ struct ieee80211_channel *channel);
303319 int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
304320 void rsi_inform_bss_status(struct rsi_common *common, u8 status,
305321 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
313329 int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb);
314330 int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
315331 int rsi_band_check(struct rsi_common *common);
332+int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word);
333+int rsi_send_radio_params_update(struct rsi_common *common);
334+int rsi_set_antenna(struct rsi_common *common, u8 antenna);
316335 #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