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.c132
1 files changed, 99 insertions, 33 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 712a606a080a..cb1f7b5bcf4c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -213,7 +213,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
213 .p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE, 213 .p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE,
214 .p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE, 214 .p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE,
215 .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, 215 .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED,
216 .ap_ps_peer_param_cmdid = WMI_CMD_UNSUPPORTED, 216 .ap_ps_peer_param_cmdid = WMI_10X_AP_PS_PEER_PARAM_CMDID,
217 .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, 217 .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED,
218 .peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID, 218 .peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID,
219 .wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID, 219 .wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID,
@@ -420,7 +420,6 @@ static struct wmi_pdev_param_map wmi_pdev_param_map = {
420 .bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 420 .bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
421 .pmf_qos = WMI_PDEV_PARAM_PMF_QOS, 421 .pmf_qos = WMI_PDEV_PARAM_PMF_QOS,
422 .arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, 422 .arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
423 .arpdhcp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED,
424 .dcs = WMI_PDEV_PARAM_DCS, 423 .dcs = WMI_PDEV_PARAM_DCS,
425 .ani_enable = WMI_PDEV_PARAM_ANI_ENABLE, 424 .ani_enable = WMI_PDEV_PARAM_ANI_ENABLE,
426 .ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD, 425 .ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD,
@@ -472,8 +471,7 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
472 .bcnflt_stats_update_period = 471 .bcnflt_stats_update_period =
473 WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, 472 WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
474 .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS, 473 .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
475 .arp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, 474 .arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
476 .arpdhcp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
477 .dcs = WMI_10X_PDEV_PARAM_DCS, 475 .dcs = WMI_10X_PDEV_PARAM_DCS,
478 .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE, 476 .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE,
479 .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, 477 .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD,
@@ -561,7 +559,6 @@ err_pull:
561 559
562static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) 560static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
563{ 561{
564 struct wmi_bcn_tx_arg arg = {0};
565 int ret; 562 int ret;
566 563
567 lockdep_assert_held(&arvif->ar->data_lock); 564 lockdep_assert_held(&arvif->ar->data_lock);
@@ -569,18 +566,16 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
569 if (arvif->beacon == NULL) 566 if (arvif->beacon == NULL)
570 return; 567 return;
571 568
572 arg.vdev_id = arvif->vdev_id; 569 if (arvif->beacon_sent)
573 arg.tx_rate = 0; 570 return;
574 arg.tx_power = 0;
575 arg.bcn = arvif->beacon->data;
576 arg.bcn_len = arvif->beacon->len;
577 571
578 ret = ath10k_wmi_beacon_send_nowait(arvif->ar, &arg); 572 ret = ath10k_wmi_beacon_send_ref_nowait(arvif);
579 if (ret) 573 if (ret)
580 return; 574 return;
581 575
582 dev_kfree_skb_any(arvif->beacon); 576 /* We need to retain the arvif->beacon reference for DMA unmapping and
583 arvif->beacon = NULL; 577 * freeing the skbuff later. */
578 arvif->beacon_sent = true;
584} 579}
585 580
586static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac, 581static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac,
@@ -1116,7 +1111,27 @@ static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar,
1116static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, 1111static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar,
1117 struct sk_buff *skb) 1112 struct sk_buff *skb)
1118{ 1113{
1119 ath10k_dbg(ATH10K_DBG_WMI, "WMI_PEER_STA_KICKOUT_EVENTID\n"); 1114 struct wmi_peer_sta_kickout_event *ev;
1115 struct ieee80211_sta *sta;
1116
1117 ev = (struct wmi_peer_sta_kickout_event *)skb->data;
1118
1119 ath10k_dbg(ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n",
1120 ev->peer_macaddr.addr);
1121
1122 rcu_read_lock();
1123
1124 sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL);
1125 if (!sta) {
1126 ath10k_warn("Spurious quick kickout for STA %pM\n",
1127 ev->peer_macaddr.addr);
1128 goto exit;
1129 }
1130
1131 ieee80211_report_low_ack(sta, 10);
1132
1133exit:
1134 rcu_read_unlock();
1120} 1135}
1121 1136
1122/* 1137/*
@@ -1217,6 +1232,13 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1217 tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast); 1232 tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast);
1218 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len); 1233 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);
1219 1234
1235 if (tim->dtim_count == 0) {
1236 ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
1237
1238 if (__le32_to_cpu(bcn_info->tim_info.tim_mcast) == 1)
1239 ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
1240 }
1241
1220 ath10k_dbg(ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n", 1242 ath10k_dbg(ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
1221 tim->dtim_count, tim->dtim_period, 1243 tim->dtim_count, tim->dtim_period,
1222 tim->bitmap_ctrl, pvm_len); 1244 tim->bitmap_ctrl, pvm_len);
@@ -1338,7 +1360,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1338 struct wmi_bcn_info *bcn_info; 1360 struct wmi_bcn_info *bcn_info;
1339 struct ath10k_vif *arvif; 1361 struct ath10k_vif *arvif;
1340 struct sk_buff *bcn; 1362 struct sk_buff *bcn;
1341 int vdev_id = 0; 1363 int ret, vdev_id = 0;
1342 1364
1343 ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n"); 1365 ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n");
1344 1366
@@ -1385,6 +1407,17 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1385 continue; 1407 continue;
1386 } 1408 }
1387 1409
1410 /* There are no completions for beacons so wait for next SWBA
1411 * before telling mac80211 to decrement CSA counter
1412 *
1413 * Once CSA counter is completed stop sending beacons until
1414 * actual channel switch is done */
1415 if (arvif->vif->csa_active &&
1416 ieee80211_csa_is_complete(arvif->vif)) {
1417 ieee80211_csa_finish(arvif->vif);
1418 continue;
1419 }
1420
1388 bcn = ieee80211_beacon_get(ar->hw, arvif->vif); 1421 bcn = ieee80211_beacon_get(ar->hw, arvif->vif);
1389 if (!bcn) { 1422 if (!bcn) {
1390 ath10k_warn("could not get mac80211 beacon\n"); 1423 ath10k_warn("could not get mac80211 beacon\n");
@@ -1396,15 +1429,33 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1396 ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info); 1429 ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info);
1397 1430
1398 spin_lock_bh(&ar->data_lock); 1431 spin_lock_bh(&ar->data_lock);
1432
1399 if (arvif->beacon) { 1433 if (arvif->beacon) {
1400 ath10k_warn("SWBA overrun on vdev %d\n", 1434 if (!arvif->beacon_sent)
1401 arvif->vdev_id); 1435 ath10k_warn("SWBA overrun on vdev %d\n",
1436 arvif->vdev_id);
1437
1438 dma_unmap_single(arvif->ar->dev,
1439 ATH10K_SKB_CB(arvif->beacon)->paddr,
1440 arvif->beacon->len, DMA_TO_DEVICE);
1402 dev_kfree_skb_any(arvif->beacon); 1441 dev_kfree_skb_any(arvif->beacon);
1403 } 1442 }
1404 1443
1444 ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev,
1445 bcn->data, bcn->len,
1446 DMA_TO_DEVICE);
1447 ret = dma_mapping_error(arvif->ar->dev,
1448 ATH10K_SKB_CB(bcn)->paddr);
1449 if (ret) {
1450 ath10k_warn("failed to map beacon: %d\n", ret);
1451 goto skip;
1452 }
1453
1405 arvif->beacon = bcn; 1454 arvif->beacon = bcn;
1455 arvif->beacon_sent = false;
1406 1456
1407 ath10k_wmi_tx_beacon_nowait(arvif); 1457 ath10k_wmi_tx_beacon_nowait(arvif);
1458skip:
1408 spin_unlock_bh(&ar->data_lock); 1459 spin_unlock_bh(&ar->data_lock);
1409 } 1460 }
1410} 1461}
@@ -2031,11 +2082,11 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
2031 memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN); 2082 memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN);
2032 2083
2033 ath10k_dbg(ATH10K_DBG_WMI, 2084 ath10k_dbg(ATH10K_DBG_WMI,
2034 "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d\n", 2085 "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n",
2035 __le32_to_cpu(ev->sw_version), 2086 __le32_to_cpu(ev->sw_version),
2036 __le32_to_cpu(ev->abi_version), 2087 __le32_to_cpu(ev->abi_version),
2037 ev->mac_addr.addr, 2088 ev->mac_addr.addr,
2038 __le32_to_cpu(ev->status)); 2089 __le32_to_cpu(ev->status), skb->len, sizeof(*ev));
2039 2090
2040 complete(&ar->wmi.unified_ready); 2091 complete(&ar->wmi.unified_ready);
2041 return 0; 2092 return 0;
@@ -2403,7 +2454,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
2403 ar->wmi.cmd->pdev_set_channel_cmdid); 2454 ar->wmi.cmd->pdev_set_channel_cmdid);
2404} 2455}
2405 2456
2406int ath10k_wmi_pdev_suspend_target(struct ath10k *ar) 2457int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
2407{ 2458{
2408 struct wmi_pdev_suspend_cmd *cmd; 2459 struct wmi_pdev_suspend_cmd *cmd;
2409 struct sk_buff *skb; 2460 struct sk_buff *skb;
@@ -2413,7 +2464,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar)
2413 return -ENOMEM; 2464 return -ENOMEM;
2414 2465
2415 cmd = (struct wmi_pdev_suspend_cmd *)skb->data; 2466 cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
2416 cmd->suspend_opt = WMI_PDEV_SUSPEND; 2467 cmd->suspend_opt = __cpu_to_le32(suspend_opt);
2417 2468
2418 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); 2469 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid);
2419} 2470}
@@ -3342,7 +3393,6 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
3342 ci->max_power = ch->max_power; 3393 ci->max_power = ch->max_power;
3343 ci->reg_power = ch->max_reg_power; 3394 ci->reg_power = ch->max_reg_power;
3344 ci->antenna_max = ch->max_antenna_gain; 3395 ci->antenna_max = ch->max_antenna_gain;
3345 ci->antenna_max = 0;
3346 3396
3347 /* mode & flags share storage */ 3397 /* mode & flags share storage */
3348 ci->mode = ch->mode; 3398 ci->mode = ch->mode;
@@ -3411,25 +3461,41 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
3411 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); 3461 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
3412} 3462}
3413 3463
3414int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, 3464/* This function assumes the beacon is already DMA mapped */
3415 const struct wmi_bcn_tx_arg *arg) 3465int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif)
3416{ 3466{
3417 struct wmi_bcn_tx_cmd *cmd; 3467 struct wmi_bcn_tx_ref_cmd *cmd;
3418 struct sk_buff *skb; 3468 struct sk_buff *skb;
3469 struct sk_buff *beacon = arvif->beacon;
3470 struct ath10k *ar = arvif->ar;
3471 struct ieee80211_hdr *hdr;
3419 int ret; 3472 int ret;
3473 u16 fc;
3420 3474
3421 skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->bcn_len); 3475 skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
3422 if (!skb) 3476 if (!skb)
3423 return -ENOMEM; 3477 return -ENOMEM;
3424 3478
3425 cmd = (struct wmi_bcn_tx_cmd *)skb->data; 3479 hdr = (struct ieee80211_hdr *)beacon->data;
3426 cmd->hdr.vdev_id = __cpu_to_le32(arg->vdev_id); 3480 fc = le16_to_cpu(hdr->frame_control);
3427 cmd->hdr.tx_rate = __cpu_to_le32(arg->tx_rate); 3481
3428 cmd->hdr.tx_power = __cpu_to_le32(arg->tx_power); 3482 cmd = (struct wmi_bcn_tx_ref_cmd *)skb->data;
3429 cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len); 3483 cmd->vdev_id = __cpu_to_le32(arvif->vdev_id);
3430 memcpy(cmd->bcn, arg->bcn, arg->bcn_len); 3484 cmd->data_len = __cpu_to_le32(beacon->len);
3485 cmd->data_ptr = __cpu_to_le32(ATH10K_SKB_CB(beacon)->paddr);
3486 cmd->msdu_id = 0;
3487 cmd->frame_control = __cpu_to_le32(fc);
3488 cmd->flags = 0;
3489
3490 if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero)
3491 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
3492
3493 if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab)
3494 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
3495
3496 ret = ath10k_wmi_cmd_send_nowait(ar, skb,
3497 ar->wmi.cmd->pdev_send_bcn_cmdid);
3431 3498
3432 ret = ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid);
3433 if (ret) 3499 if (ret)
3434 dev_kfree_skb(skb); 3500 dev_kfree_skb(skb);
3435 3501