Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

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