aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/wmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c312
1 files changed, 135 insertions, 177 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index c7ea77edce24..6c046c244705 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -26,6 +26,8 @@
26#include "mac.h" 26#include "mac.h"
27#include "testmode.h" 27#include "testmode.h"
28#include "wmi-ops.h" 28#include "wmi-ops.h"
29#include "p2p.h"
30#include "hw.h"
29 31
30/* MAIN WMI cmd track */ 32/* MAIN WMI cmd track */
31static struct wmi_cmd_map wmi_cmd_map = { 33static struct wmi_cmd_map wmi_cmd_map = {
@@ -884,20 +886,24 @@ void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
884 886
885int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) 887int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
886{ 888{
887 int ret; 889 unsigned long time_left;
888 890
889 ret = wait_for_completion_timeout(&ar->wmi.service_ready, 891 time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
890 WMI_SERVICE_READY_TIMEOUT_HZ); 892 WMI_SERVICE_READY_TIMEOUT_HZ);
891 return ret; 893 if (!time_left)
894 return -ETIMEDOUT;
895 return 0;
892} 896}
893 897
894int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) 898int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar)
895{ 899{
896 int ret; 900 unsigned long time_left;
897 901
898 ret = wait_for_completion_timeout(&ar->wmi.unified_ready, 902 time_left = wait_for_completion_timeout(&ar->wmi.unified_ready,
899 WMI_UNIFIED_READY_TIMEOUT_HZ); 903 WMI_UNIFIED_READY_TIMEOUT_HZ);
900 return ret; 904 if (!time_left)
905 return -ETIMEDOUT;
906 return 0;
901} 907}
902 908
903struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len) 909struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len)
@@ -1351,63 +1357,6 @@ static inline enum ieee80211_band phy_mode_to_band(u32 phy_mode)
1351 return band; 1357 return band;
1352} 1358}
1353 1359
1354static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band)
1355{
1356 u8 rate_idx = 0;
1357
1358 /* rate in Kbps */
1359 switch (rate) {
1360 case 1000:
1361 rate_idx = 0;
1362 break;
1363 case 2000:
1364 rate_idx = 1;
1365 break;
1366 case 5500:
1367 rate_idx = 2;
1368 break;
1369 case 11000:
1370 rate_idx = 3;
1371 break;
1372 case 6000:
1373 rate_idx = 4;
1374 break;
1375 case 9000:
1376 rate_idx = 5;
1377 break;
1378 case 12000:
1379 rate_idx = 6;
1380 break;
1381 case 18000:
1382 rate_idx = 7;
1383 break;
1384 case 24000:
1385 rate_idx = 8;
1386 break;
1387 case 36000:
1388 rate_idx = 9;
1389 break;
1390 case 48000:
1391 rate_idx = 10;
1392 break;
1393 case 54000:
1394 rate_idx = 11;
1395 break;
1396 default:
1397 break;
1398 }
1399
1400 if (band == IEEE80211_BAND_5GHZ) {
1401 if (rate_idx > 3)
1402 /* Omit CCK rates */
1403 rate_idx -= 4;
1404 else
1405 rate_idx = 0;
1406 }
1407
1408 return rate_idx;
1409}
1410
1411/* If keys are configured, HW decrypts all frames 1360/* If keys are configured, HW decrypts all frames
1412 * with protected bit set. Mark such frames as decrypted. 1361 * with protected bit set. Mark such frames as decrypted.
1413 */ 1362 */
@@ -1489,6 +1438,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1489 struct wmi_mgmt_rx_ev_arg arg = {}; 1438 struct wmi_mgmt_rx_ev_arg arg = {};
1490 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 1439 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
1491 struct ieee80211_hdr *hdr; 1440 struct ieee80211_hdr *hdr;
1441 struct ieee80211_supported_band *sband;
1492 u32 rx_status; 1442 u32 rx_status;
1493 u32 channel; 1443 u32 channel;
1494 u32 phy_mode; 1444 u32 phy_mode;
@@ -1501,6 +1451,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1501 ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg); 1451 ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg);
1502 if (ret) { 1452 if (ret) {
1503 ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret); 1453 ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret);
1454 dev_kfree_skb(skb);
1504 return ret; 1455 return ret;
1505 } 1456 }
1506 1457
@@ -1559,9 +1510,11 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1559 if (phy_mode == MODE_11B && status->band == IEEE80211_BAND_5GHZ) 1510 if (phy_mode == MODE_11B && status->band == IEEE80211_BAND_5GHZ)
1560 ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); 1511 ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n");
1561 1512
1513 sband = &ar->mac.sbands[status->band];
1514
1562 status->freq = ieee80211_channel_to_frequency(channel, status->band); 1515 status->freq = ieee80211_channel_to_frequency(channel, status->band);
1563 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; 1516 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;
1564 status->rate_idx = get_rate_idx(rate, status->band); 1517 status->rate_idx = ath10k_mac_bitrate_to_idx(sband, rate / 100);
1565 1518
1566 hdr = (struct ieee80211_hdr *)skb->data; 1519 hdr = (struct ieee80211_hdr *)skb->data;
1567 fc = le16_to_cpu(hdr->frame_control); 1520 fc = le16_to_cpu(hdr->frame_control);
@@ -1585,6 +1538,9 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1585 } 1538 }
1586 } 1539 }
1587 1540
1541 if (ieee80211_is_beacon(hdr->frame_control))
1542 ath10k_mac_handle_beacon(ar, skb);
1543
1588 ath10k_dbg(ar, ATH10K_DBG_MGMT, 1544 ath10k_dbg(ar, ATH10K_DBG_MGMT,
1589 "event mgmt rx skb %p len %d ftype %02x stype %02x\n", 1545 "event mgmt rx skb %p len %d ftype %02x stype %02x\n",
1590 skb, skb->len, 1546 skb, skb->len,
@@ -1682,20 +1638,22 @@ void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
1682 } 1638 }
1683 1639
1684 if (cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) { 1640 if (cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) {
1685 /* During scanning chan info is reported twice for each 1641 if (ar->ch_info_can_report_survey) {
1686 * visited channel. The reported cycle count is global 1642 survey = &ar->survey[idx];
1687 * and per-channel cycle count must be calculated */ 1643 survey->noise = noise_floor;
1688 1644 survey->filled = SURVEY_INFO_NOISE_DBM;
1689 cycle_count -= ar->survey_last_cycle_count; 1645
1690 rx_clear_count -= ar->survey_last_rx_clear_count; 1646 ath10k_hw_fill_survey_time(ar,
1691 1647 survey,
1692 survey = &ar->survey[idx]; 1648 cycle_count,
1693 survey->time = WMI_CHAN_INFO_MSEC(cycle_count); 1649 rx_clear_count,
1694 survey->time_rx = WMI_CHAN_INFO_MSEC(rx_clear_count); 1650 ar->survey_last_cycle_count,
1695 survey->noise = noise_floor; 1651 ar->survey_last_rx_clear_count);
1696 survey->filled = SURVEY_INFO_TIME | 1652 }
1697 SURVEY_INFO_TIME_RX | 1653
1698 SURVEY_INFO_NOISE_DBM; 1654 ar->ch_info_can_report_survey = false;
1655 } else {
1656 ar->ch_info_can_report_survey = true;
1699 } 1657 }
1700 1658
1701 ar->survey_last_rx_clear_count = rx_clear_count; 1659 ar->survey_last_rx_clear_count = rx_clear_count;
@@ -2276,109 +2234,25 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
2276 tim->bitmap_ctrl, pvm_len); 2234 tim->bitmap_ctrl, pvm_len);
2277} 2235}
2278 2236
2279static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len,
2280 const struct wmi_p2p_noa_info *noa)
2281{
2282 struct ieee80211_p2p_noa_attr *noa_attr;
2283 u8 ctwindow_oppps = noa->ctwindow_oppps;
2284 u8 ctwindow = ctwindow_oppps >> WMI_P2P_OPPPS_CTWINDOW_OFFSET;
2285 bool oppps = !!(ctwindow_oppps & WMI_P2P_OPPPS_ENABLE_BIT);
2286 __le16 *noa_attr_len;
2287 u16 attr_len;
2288 u8 noa_descriptors = noa->num_descriptors;
2289 int i;
2290
2291 /* P2P IE */
2292 data[0] = WLAN_EID_VENDOR_SPECIFIC;
2293 data[1] = len - 2;
2294 data[2] = (WLAN_OUI_WFA >> 16) & 0xff;
2295 data[3] = (WLAN_OUI_WFA >> 8) & 0xff;
2296 data[4] = (WLAN_OUI_WFA >> 0) & 0xff;
2297 data[5] = WLAN_OUI_TYPE_WFA_P2P;
2298
2299 /* NOA ATTR */
2300 data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
2301 noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */
2302 noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9];
2303
2304 noa_attr->index = noa->index;
2305 noa_attr->oppps_ctwindow = ctwindow;
2306 if (oppps)
2307 noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT;
2308
2309 for (i = 0; i < noa_descriptors; i++) {
2310 noa_attr->desc[i].count =
2311 __le32_to_cpu(noa->descriptors[i].type_count);
2312 noa_attr->desc[i].duration = noa->descriptors[i].duration;
2313 noa_attr->desc[i].interval = noa->descriptors[i].interval;
2314 noa_attr->desc[i].start_time = noa->descriptors[i].start_time;
2315 }
2316
2317 attr_len = 2; /* index + oppps_ctwindow */
2318 attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
2319 *noa_attr_len = __cpu_to_le16(attr_len);
2320}
2321
2322static u32 ath10k_p2p_calc_noa_ie_len(const struct wmi_p2p_noa_info *noa)
2323{
2324 u32 len = 0;
2325 u8 noa_descriptors = noa->num_descriptors;
2326 u8 opp_ps_info = noa->ctwindow_oppps;
2327 bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT);
2328
2329 if (!noa_descriptors && !opps_enabled)
2330 return len;
2331
2332 len += 1 + 1 + 4; /* EID + len + OUI */
2333 len += 1 + 2; /* noa attr + attr len */
2334 len += 1 + 1; /* index + oppps_ctwindow */
2335 len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
2336
2337 return len;
2338}
2339
2340static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif, 2237static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
2341 struct sk_buff *bcn, 2238 struct sk_buff *bcn,
2342 const struct wmi_p2p_noa_info *noa) 2239 const struct wmi_p2p_noa_info *noa)
2343{ 2240{
2344 u8 *new_data, *old_data = arvif->u.ap.noa_data;
2345 u32 new_len;
2346
2347 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) 2241 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
2348 return; 2242 return;
2349 2243
2350 ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); 2244 ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed);
2351 if (noa->changed & WMI_P2P_NOA_CHANGED_BIT) {
2352 new_len = ath10k_p2p_calc_noa_ie_len(noa);
2353 if (!new_len)
2354 goto cleanup;
2355
2356 new_data = kmalloc(new_len, GFP_ATOMIC);
2357 if (!new_data)
2358 goto cleanup;
2359
2360 ath10k_p2p_fill_noa_ie(new_data, new_len, noa);
2361 2245
2362 spin_lock_bh(&ar->data_lock); 2246 if (noa->changed & WMI_P2P_NOA_CHANGED_BIT)
2363 arvif->u.ap.noa_data = new_data; 2247 ath10k_p2p_noa_update(arvif, noa);
2364 arvif->u.ap.noa_len = new_len;
2365 spin_unlock_bh(&ar->data_lock);
2366 kfree(old_data);
2367 }
2368 2248
2369 if (arvif->u.ap.noa_data) 2249 if (arvif->u.ap.noa_data)
2370 if (!pskb_expand_head(bcn, 0, arvif->u.ap.noa_len, GFP_ATOMIC)) 2250 if (!pskb_expand_head(bcn, 0, arvif->u.ap.noa_len, GFP_ATOMIC))
2371 memcpy(skb_put(bcn, arvif->u.ap.noa_len), 2251 memcpy(skb_put(bcn, arvif->u.ap.noa_len),
2372 arvif->u.ap.noa_data, 2252 arvif->u.ap.noa_data,
2373 arvif->u.ap.noa_len); 2253 arvif->u.ap.noa_len);
2374 return;
2375 2254
2376cleanup: 2255 return;
2377 spin_lock_bh(&ar->data_lock);
2378 arvif->u.ap.noa_data = NULL;
2379 arvif->u.ap.noa_len = 0;
2380 spin_unlock_bh(&ar->data_lock);
2381 kfree(old_data);
2382} 2256}
2383 2257
2384static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb, 2258static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb,
@@ -2555,6 +2429,7 @@ static void ath10k_dfs_radar_report(struct ath10k *ar,
2555 u64 tsf) 2429 u64 tsf)
2556{ 2430{
2557 u32 reg0, reg1, tsf32l; 2431 u32 reg0, reg1, tsf32l;
2432 struct ieee80211_channel *ch;
2558 struct pulse_event pe; 2433 struct pulse_event pe;
2559 u64 tsf64; 2434 u64 tsf64;
2560 u8 rssi, width; 2435 u8 rssi, width;
@@ -2583,6 +2458,15 @@ static void ath10k_dfs_radar_report(struct ath10k *ar,
2583 if (!ar->dfs_detector) 2458 if (!ar->dfs_detector)
2584 return; 2459 return;
2585 2460
2461 spin_lock_bh(&ar->data_lock);
2462 ch = ar->rx_channel;
2463 spin_unlock_bh(&ar->data_lock);
2464
2465 if (!ch) {
2466 ath10k_warn(ar, "failed to derive channel for radar pulse, treating as radar\n");
2467 goto radar_detected;
2468 }
2469
2586 /* report event to DFS pattern detector */ 2470 /* report event to DFS pattern detector */
2587 tsf32l = __le32_to_cpu(phyerr->tsf_timestamp); 2471 tsf32l = __le32_to_cpu(phyerr->tsf_timestamp);
2588 tsf64 = tsf & (~0xFFFFFFFFULL); 2472 tsf64 = tsf & (~0xFFFFFFFFULL);
@@ -2598,10 +2482,10 @@ static void ath10k_dfs_radar_report(struct ath10k *ar,
2598 rssi = 0; 2482 rssi = 0;
2599 2483
2600 pe.ts = tsf64; 2484 pe.ts = tsf64;
2601 pe.freq = ar->hw->conf.chandef.chan->center_freq; 2485 pe.freq = ch->center_freq;
2602 pe.width = width; 2486 pe.width = width;
2603 pe.rssi = rssi; 2487 pe.rssi = rssi;
2604 2488 pe.chirp = (MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP) != 0);
2605 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, 2489 ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
2606 "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n", 2490 "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n",
2607 pe.freq, pe.width, pe.rssi, pe.ts); 2491 pe.freq, pe.width, pe.rssi, pe.ts);
@@ -2614,6 +2498,7 @@ static void ath10k_dfs_radar_report(struct ath10k *ar,
2614 return; 2498 return;
2615 } 2499 }
2616 2500
2501radar_detected:
2617 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n"); 2502 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n");
2618 ATH10K_DFS_STAT_INC(ar, radar_detected); 2503 ATH10K_DFS_STAT_INC(ar, radar_detected);
2619 2504
@@ -2872,7 +2757,43 @@ void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
2872 2757
2873void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) 2758void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
2874{ 2759{
2875 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); 2760 struct wmi_roam_ev_arg arg = {};
2761 int ret;
2762 u32 vdev_id;
2763 u32 reason;
2764 s32 rssi;
2765
2766 ret = ath10k_wmi_pull_roam_ev(ar, skb, &arg);
2767 if (ret) {
2768 ath10k_warn(ar, "failed to parse roam event: %d\n", ret);
2769 return;
2770 }
2771
2772 vdev_id = __le32_to_cpu(arg.vdev_id);
2773 reason = __le32_to_cpu(arg.reason);
2774 rssi = __le32_to_cpu(arg.rssi);
2775 rssi += WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT;
2776
2777 ath10k_dbg(ar, ATH10K_DBG_WMI,
2778 "wmi roam event vdev %u reason 0x%08x rssi %d\n",
2779 vdev_id, reason, rssi);
2780
2781 if (reason >= WMI_ROAM_REASON_MAX)
2782 ath10k_warn(ar, "ignoring unknown roam event reason %d on vdev %i\n",
2783 reason, vdev_id);
2784
2785 switch (reason) {
2786 case WMI_ROAM_REASON_BEACON_MISS:
2787 ath10k_mac_handle_beacon_miss(ar, vdev_id);
2788 break;
2789 case WMI_ROAM_REASON_BETTER_AP:
2790 case WMI_ROAM_REASON_LOW_RSSI:
2791 case WMI_ROAM_REASON_SUITABLE_AP_FOUND:
2792 case WMI_ROAM_REASON_HO_FAILED:
2793 ath10k_warn(ar, "ignoring not implemented roam event reason %d on vdev %i\n",
2794 reason, vdev_id);
2795 break;
2796 }
2876} 2797}
2877 2798
2878void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb) 2799void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb)
@@ -2942,7 +2863,19 @@ void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb)
2942 2863
2943void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb) 2864void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb)
2944{ 2865{
2945 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); 2866 struct wmi_wow_ev_arg ev = {};
2867 int ret;
2868
2869 complete(&ar->wow.wakeup_completed);
2870
2871 ret = ath10k_wmi_pull_wow_event(ar, skb, &ev);
2872 if (ret) {
2873 ath10k_warn(ar, "failed to parse wow wakeup event: %d\n", ret);
2874 return;
2875 }
2876
2877 ath10k_dbg(ar, ATH10K_DBG_WMI, "wow wakeup host reason %s\n",
2878 wow_reason(ev.wake_reason));
2946} 2879}
2947 2880
2948void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb) 2881void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb)
@@ -3231,6 +3164,21 @@ static int ath10k_wmi_op_pull_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
3231 return 0; 3164 return 0;
3232} 3165}
3233 3166
3167static int ath10k_wmi_op_pull_roam_ev(struct ath10k *ar, struct sk_buff *skb,
3168 struct wmi_roam_ev_arg *arg)
3169{
3170 struct wmi_roam_ev *ev = (void *)skb->data;
3171
3172 if (skb->len < sizeof(*ev))
3173 return -EPROTO;
3174
3175 skb_pull(skb, sizeof(*ev));
3176 arg->vdev_id = ev->vdev_id;
3177 arg->reason = ev->reason;
3178
3179 return 0;
3180}
3181
3234int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) 3182int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
3235{ 3183{
3236 struct wmi_rdy_ev_arg arg = {}; 3184 struct wmi_rdy_ev_arg arg = {};
@@ -3275,7 +3223,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
3275 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 3223 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
3276 3224
3277 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 3225 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
3278 return; 3226 goto out;
3279 3227
3280 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 3228 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
3281 3229
@@ -3379,6 +3327,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
3379 break; 3327 break;
3380 } 3328 }
3381 3329
3330out:
3382 dev_kfree_skb(skb); 3331 dev_kfree_skb(skb);
3383} 3332}
3384 3333
@@ -3392,7 +3341,7 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb)
3392 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 3341 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
3393 3342
3394 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 3343 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
3395 return; 3344 goto out;
3396 3345
3397 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 3346 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
3398 3347
@@ -3515,7 +3464,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
3515 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); 3464 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
3516 3465
3517 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) 3466 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
3518 return; 3467 goto out;
3519 3468
3520 trace_ath10k_wmi_event(ar, id, skb->data, skb->len); 3469 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
3521 3470
@@ -3623,6 +3572,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
3623 break; 3572 break;
3624 } 3573 }
3625 3574
3575out:
3626 dev_kfree_skb(skb); 3576 dev_kfree_skb(skb);
3627} 3577}
3628 3578
@@ -3989,6 +3939,8 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
3989 cmd = (struct wmi_init_cmd_10_2 *)buf->data; 3939 cmd = (struct wmi_init_cmd_10_2 *)buf->data;
3990 3940
3991 features = WMI_10_2_RX_BATCH_MODE; 3941 features = WMI_10_2_RX_BATCH_MODE;
3942 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
3943 features |= WMI_10_2_COEX_GPIO;
3992 cmd->resource_config.feature_mask = __cpu_to_le32(features); 3944 cmd->resource_config.feature_mask = __cpu_to_le32(features);
3993 3945
3994 memcpy(&cmd->resource_config.common, &config, sizeof(config)); 3946 memcpy(&cmd->resource_config.common, &config, sizeof(config));
@@ -4315,8 +4267,6 @@ ath10k_wmi_op_gen_vdev_start(struct ath10k *ar,
4315 const char *cmdname; 4267 const char *cmdname;
4316 u32 flags = 0; 4268 u32 flags = 0;
4317 4269
4318 if (WARN_ON(arg->ssid && arg->ssid_len == 0))
4319 return ERR_PTR(-EINVAL);
4320 if (WARN_ON(arg->hidden_ssid && !arg->ssid)) 4270 if (WARN_ON(arg->hidden_ssid && !arg->ssid))
4321 return ERR_PTR(-EINVAL); 4271 return ERR_PTR(-EINVAL);
4322 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) 4272 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
@@ -4539,7 +4489,8 @@ ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
4539 4489
4540static struct sk_buff * 4490static struct sk_buff *
4541ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, 4491ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
4542 const u8 peer_addr[ETH_ALEN]) 4492 const u8 peer_addr[ETH_ALEN],
4493 enum wmi_peer_type peer_type)
4543{ 4494{
4544 struct wmi_peer_create_cmd *cmd; 4495 struct wmi_peer_create_cmd *cmd;
4545 struct sk_buff *skb; 4496 struct sk_buff *skb;
@@ -5223,6 +5174,7 @@ static const struct wmi_ops wmi_ops = {
5223 .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, 5174 .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
5224 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 5175 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5225 .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats, 5176 .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats,
5177 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
5226 5178
5227 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 5179 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5228 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 5180 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -5268,6 +5220,7 @@ static const struct wmi_ops wmi_ops = {
5268 /* .gen_bcn_tmpl not implemented */ 5220 /* .gen_bcn_tmpl not implemented */
5269 /* .gen_prb_tmpl not implemented */ 5221 /* .gen_prb_tmpl not implemented */
5270 /* .gen_p2p_go_bcn_ie not implemented */ 5222 /* .gen_p2p_go_bcn_ie not implemented */
5223 /* .gen_adaptive_qcs not implemented */
5271}; 5224};
5272 5225
5273static const struct wmi_ops wmi_10_1_ops = { 5226static const struct wmi_ops wmi_10_1_ops = {
@@ -5290,6 +5243,7 @@ static const struct wmi_ops wmi_10_1_ops = {
5290 .pull_swba = ath10k_wmi_op_pull_swba_ev, 5243 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5291 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 5244 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5292 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 5245 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5246 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
5293 5247
5294 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 5248 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5295 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 5249 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -5330,6 +5284,7 @@ static const struct wmi_ops wmi_10_1_ops = {
5330 /* .gen_bcn_tmpl not implemented */ 5284 /* .gen_bcn_tmpl not implemented */
5331 /* .gen_prb_tmpl not implemented */ 5285 /* .gen_prb_tmpl not implemented */
5332 /* .gen_p2p_go_bcn_ie not implemented */ 5286 /* .gen_p2p_go_bcn_ie not implemented */
5287 /* .gen_adaptive_qcs not implemented */
5333}; 5288};
5334 5289
5335static const struct wmi_ops wmi_10_2_ops = { 5290static const struct wmi_ops wmi_10_2_ops = {
@@ -5353,6 +5308,7 @@ static const struct wmi_ops wmi_10_2_ops = {
5353 .pull_swba = ath10k_wmi_op_pull_swba_ev, 5308 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5354 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 5309 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5355 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 5310 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5311 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
5356 5312
5357 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 5313 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5358 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 5314 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -5413,6 +5369,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
5413 .pull_swba = ath10k_wmi_op_pull_swba_ev, 5369 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5414 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 5370 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5415 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 5371 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5372 .pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
5416 5373
5417 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, 5374 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5418 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, 5375 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
@@ -5452,6 +5409,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
5452 /* .gen_bcn_tmpl not implemented */ 5409 /* .gen_bcn_tmpl not implemented */
5453 /* .gen_prb_tmpl not implemented */ 5410 /* .gen_prb_tmpl not implemented */
5454 /* .gen_p2p_go_bcn_ie not implemented */ 5411 /* .gen_p2p_go_bcn_ie not implemented */
5412 /* .gen_adaptive_qcs not implemented */
5455}; 5413};
5456 5414
5457int ath10k_wmi_attach(struct ath10k *ar) 5415int ath10k_wmi_attach(struct ath10k *ar)