Loading drivers/net/wireless/ath/ath10k/core.c +5 −0 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -538,6 +539,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .hw_ops = &wcn3990_ops, .decap_align_bytes = 1, .num_peers = TARGET_HL_10_TLV_NUM_PEERS, .n_cipher_suites = 11, .ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT, .num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES, .target_64bit = true, Loading Loading @@ -2100,6 +2102,7 @@ static void ath10k_core_restart(struct work_struct *work) complete(&ar->offchan_tx_completed); complete(&ar->install_key_done); complete(&ar->vdev_setup_done); complete(&ar->vdev_delete_done); complete(&ar->thermal.wmi_sync); complete(&ar->bss_survey_done); wake_up(&ar->htt.empty_tx_wq); Loading Loading @@ -3002,8 +3005,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); init_completion(&ar->vdev_delete_done); init_completion(&ar->thermal.wmi_sync); init_completion(&ar->bss_survey_done); init_completion(&ar->peer_delete_done); INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); Loading drivers/net/wireless/ath/ath10k/core.h +7 −1 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -375,6 +376,7 @@ struct ath10k_sta { }; #define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ) #define ATH10K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) enum ath10k_beacon_state { ATH10K_BEACON_SCHEDULED = 0, Loading Loading @@ -913,6 +915,7 @@ struct ath10k { int last_wmi_vdev_start_status; struct completion vdev_setup_done; struct completion vdev_delete_done; struct workqueue_struct *workqueue; /* Auxiliary workqueue */ Loading Loading @@ -1037,8 +1040,11 @@ struct ath10k { u32 ampdu_reference; const u8 *wmi_key_cipher; void *ce_priv; struct completion peer_delete_done; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; Loading drivers/net/wireless/ath/ath10k/mac.c +60 −8 Original line number Diff line number Diff line Loading @@ -231,24 +231,24 @@ static int ath10k_send_key(struct ath10k_vif *arvif, switch (key->cipher) { case WLAN_CIPHER_SUITE_CCMP: arg.key_cipher = WMI_CIPHER_AES_CCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM]; key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; break; case WLAN_CIPHER_SUITE_TKIP: arg.key_cipher = WMI_CIPHER_TKIP; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_TKIP]; arg.key_txmic_len = 8; arg.key_rxmic_len = 8; break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: arg.key_cipher = WMI_CIPHER_WEP; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_WEP]; break; case WLAN_CIPHER_SUITE_CCMP_256: arg.key_cipher = WMI_CIPHER_AES_CCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM]; break; case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP_256: arg.key_cipher = WMI_CIPHER_AES_GCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM]; break; case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_256: Loading @@ -265,7 +265,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (cmd == DISABLE_KEY) { arg.key_cipher = WMI_CIPHER_NONE; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_NONE]; arg.key_data = NULL; } Loading Loading @@ -685,6 +685,26 @@ ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw, *def = &conf->def; } static void ath10k_wait_for_peer_delete_done(struct ath10k *ar, u32 vdev_id, const u8 *addr) { unsigned long time_left; int ret; if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr); if (ret) { ath10k_warn(ar, "failed wait for peer deleted"); return; } time_left = wait_for_completion_timeout(&ar->peer_delete_done, 5 * HZ); if (!time_left) ath10k_warn(ar, "Timeout in receiving peer delete response\n"); } } static int ath10k_peer_create(struct ath10k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, Loading Loading @@ -729,7 +749,7 @@ static int ath10k_peer_create(struct ath10k *ar, spin_unlock_bh(&ar->data_lock); ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n", addr, vdev_id); ath10k_wmi_peer_delete(ar, vdev_id, addr); ath10k_wait_for_peer_delete_done(ar, vdev_id, addr); return -ENOENT; } Loading Loading @@ -811,6 +831,18 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) if (ret) return ret; if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { unsigned long time_left; time_left = wait_for_completion_timeout (&ar->peer_delete_done, 5 * HZ); if (!time_left) { ath10k_warn(ar, "Timeout in receiving peer delete response\n"); return -ETIMEDOUT; } } ar->num_peers--; return 0; Loading Loading @@ -1003,6 +1035,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_start(ar, &arg); if (ret) { Loading Loading @@ -1052,6 +1085,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar) ar->monitor_vdev_id, ret); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); if (ret) Loading Loading @@ -1393,6 +1427,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) lockdep_assert_held(&ar->conf_mutex); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); if (ret) { Loading Loading @@ -1429,6 +1464,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, lockdep_assert_held(&ar->conf_mutex); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); arg.vdev_id = arvif->vdev_id; arg.dtim_period = arvif->dtim_period; Loading Loading @@ -5244,8 +5280,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, err_peer_delete: if (arvif->vdev_type == WMI_VDEV_TYPE_AP || arvif->vdev_type == WMI_VDEV_TYPE_IBSS) arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr); ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, vif->addr); } err_vdev_delete: ath10k_wmi_vdev_delete(ar, arvif->vdev_id); Loading Loading @@ -5280,6 +5319,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = (void *)vif->drv_priv; struct ath10k_peer *peer; unsigned long time_left; int ret; int i; Loading Loading @@ -5310,6 +5350,8 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n", arvif->vdev_id, ret); ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, vif->addr); kfree(arvif->u.ap.noa_data); } Loading @@ -5321,6 +5363,15 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", arvif->vdev_id, ret); if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { time_left = wait_for_completion_timeout(&ar->vdev_delete_done, ATH10K_VDEV_DELETE_TIMEOUT_HZ); if (time_left == 0) { ath10k_warn(ar, "Timeout in receiving vdev delete response\n"); goto out; } } /* Some firmware revisions don't notify host about self-peer removal * until after associated vdev is deleted. */ Loading Loading @@ -5371,6 +5422,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_mac_txq_unref(ar, vif->txq); out: mutex_unlock(&ar->conf_mutex); } Loading drivers/net/wireless/ath/ath10k/wmi-tlv.c +60 −4 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -222,6 +223,13 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, return 0; } static void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar, struct sk_buff *skb) { ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n"); complete(&ar->vdev_delete_done); } static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar, struct sk_buff *skb) { Loading Loading @@ -412,6 +420,24 @@ static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, return 0; } static int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar, struct sk_buff *skb) { struct wmi_peer_delete_resp_ev_arg *arg; struct wmi_tlv *tlv_hdr; tlv_hdr = (struct wmi_tlv *)skb->data; arg = (struct wmi_peer_delete_resp_ev_arg *)tlv_hdr->value; ath10k_dbg(ar, ATH10K_DBG_WMI, "vdev id %d", arg->vdev_id); ath10k_dbg(ar, ATH10K_DBG_WMI, "peer mac addr %pM", &arg->peer_addr); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete response\n"); complete(&ar->peer_delete_done); return 0; } /***********/ /* TLV ops */ /***********/ Loading Loading @@ -468,6 +494,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_TLV_VDEV_STOPPED_EVENTID: ath10k_wmi_event_vdev_stopped(ar, skb); break; case WMI_TLV_VDEV_DELETE_RESP_EVENTID: ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb); break; case WMI_TLV_PEER_STA_KICKOUT_EVENTID: ath10k_wmi_event_peer_sta_kickout(ar, skb); break; Loading Loading @@ -555,6 +584,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_TLV_TX_PAUSE_EVENTID: ath10k_wmi_tlv_event_tx_pause(ar, skb); break; case WMI_TLV_PEER_DELETE_RESP_EVENTID: ath10k_wmi_tlv_event_peer_delete_resp(ar, skb); break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; Loading Loading @@ -1704,6 +1736,28 @@ ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar, return skb; } static int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar, enum wmi_vdev_subtype subtype) { switch (subtype) { case WMI_VDEV_SUBTYPE_NONE: return WMI_TLV_VDEV_SUBTYPE_NONE; case WMI_VDEV_SUBTYPE_P2P_DEVICE: return WMI_TLV_VDEV_SUBTYPE_P2P_DEV; case WMI_VDEV_SUBTYPE_P2P_CLIENT: return WMI_TLV_VDEV_SUBTYPE_P2P_CLI; case WMI_VDEV_SUBTYPE_P2P_GO: return WMI_TLV_VDEV_SUBTYPE_P2P_GO; case WMI_VDEV_SUBTYPE_PROXY_STA: return WMI_TLV_VDEV_SUBTYPE_PROXY_STA; case WMI_VDEV_SUBTYPE_MESH_11S: return WMI_TLV_VDEV_SUBTYPE_MESH_11S; case WMI_VDEV_SUBTYPE_MESH_NON_11S: return -ENOTSUPP; } return -ENOTSUPP; } static struct sk_buff * ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id, Loading Loading @@ -1932,9 +1986,11 @@ ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar, size_t len; void *ptr; if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] && arg->key_data) return ERR_PTR(-EINVAL); if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] && !arg->key_data) return ERR_PTR(-EINVAL); len = sizeof(*tlv) + sizeof(*cmd) + Loading Loading @@ -2611,7 +2667,7 @@ ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) ieee80211_is_deauth(hdr->frame_control) || ieee80211_is_disassoc(hdr->frame_control)) && ieee80211_has_protected(hdr->frame_control)) { len += IEEE80211_CCMP_MIC_LEN; skb_put(msdu, IEEE80211_CCMP_MIC_LEN); buf_len += IEEE80211_CCMP_MIC_LEN; } Loading Loading @@ -3826,7 +3882,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, .get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype, .gen_echo = ath10k_wmi_tlv_op_gen_echo, .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, Loading drivers/net/wireless/ath/ath10k/wmi-tlv.h +19 −0 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -309,11 +310,15 @@ enum wmi_tlv_event_id { WMI_TLV_VDEV_STOPPED_EVENTID, WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID, WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID, WMI_TLV_VDEV_TSF_REPORT_EVENTID, WMI_TLV_VDEV_DELETE_RESP_EVENTID, WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER), WMI_TLV_PEER_INFO_EVENTID, WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID, WMI_TLV_PEER_ESTIMATED_LINKSPEED_EVENTID, WMI_TLV_PEER_STATE_EVENTID, WMI_TLV_PEER_ASSOC_CONF_EVENTID, WMI_TLV_PEER_DELETE_RESP_EVENTID, WMI_TLV_MGMT_RX_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MGMT), WMI_TLV_HOST_SWBA_EVENTID, WMI_TLV_TBTTOFFSET_UPDATE_EVENTID, Loading Loading @@ -1554,6 +1559,10 @@ wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len) WMI_SERVICE_SAP_AUTH_OFFLOAD, len); SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI, WMI_SERVICE_MGMT_TX_WMI, len); SVCMAP(WMI_TLV_SERVICE_MESH_11S, WMI_SERVICE_MESH_11S, len); SVCMAP(WMI_TLV_SERVICE_SYNC_DELETE_CMDS, WMI_SERVICE_SYNC_DELETE_CMDS, len); } static inline void Loading Loading @@ -1721,6 +1730,16 @@ struct wmi_tlv_start_scan_cmd { struct wmi_mac_addr mac_mask; } __packed; enum wmi_tlv_vdev_subtype { WMI_TLV_VDEV_SUBTYPE_NONE = 0, WMI_TLV_VDEV_SUBTYPE_P2P_DEV = 1, WMI_TLV_VDEV_SUBTYPE_P2P_CLI = 2, WMI_TLV_VDEV_SUBTYPE_P2P_GO = 3, WMI_TLV_VDEV_SUBTYPE_PROXY_STA = 4, WMI_TLV_VDEV_SUBTYPE_MESH = 5, WMI_TLV_VDEV_SUBTYPE_MESH_11S = 6, }; struct wmi_tlv_vdev_start_cmd { __le32 vdev_id; __le32 requestor_id; Loading Loading
drivers/net/wireless/ath/ath10k/core.c +5 −0 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -538,6 +539,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { .hw_ops = &wcn3990_ops, .decap_align_bytes = 1, .num_peers = TARGET_HL_10_TLV_NUM_PEERS, .n_cipher_suites = 11, .ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT, .num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES, .target_64bit = true, Loading Loading @@ -2100,6 +2102,7 @@ static void ath10k_core_restart(struct work_struct *work) complete(&ar->offchan_tx_completed); complete(&ar->install_key_done); complete(&ar->vdev_setup_done); complete(&ar->vdev_delete_done); complete(&ar->thermal.wmi_sync); complete(&ar->bss_survey_done); wake_up(&ar->htt.empty_tx_wq); Loading Loading @@ -3002,8 +3005,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); init_completion(&ar->vdev_delete_done); init_completion(&ar->thermal.wmi_sync); init_completion(&ar->bss_survey_done); init_completion(&ar->peer_delete_done); INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); Loading
drivers/net/wireless/ath/ath10k/core.h +7 −1 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -375,6 +376,7 @@ struct ath10k_sta { }; #define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ) #define ATH10K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) enum ath10k_beacon_state { ATH10K_BEACON_SCHEDULED = 0, Loading Loading @@ -913,6 +915,7 @@ struct ath10k { int last_wmi_vdev_start_status; struct completion vdev_setup_done; struct completion vdev_delete_done; struct workqueue_struct *workqueue; /* Auxiliary workqueue */ Loading Loading @@ -1037,8 +1040,11 @@ struct ath10k { u32 ampdu_reference; const u8 *wmi_key_cipher; void *ce_priv; struct completion peer_delete_done; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; Loading
drivers/net/wireless/ath/ath10k/mac.c +60 −8 Original line number Diff line number Diff line Loading @@ -231,24 +231,24 @@ static int ath10k_send_key(struct ath10k_vif *arvif, switch (key->cipher) { case WLAN_CIPHER_SUITE_CCMP: arg.key_cipher = WMI_CIPHER_AES_CCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM]; key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; break; case WLAN_CIPHER_SUITE_TKIP: arg.key_cipher = WMI_CIPHER_TKIP; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_TKIP]; arg.key_txmic_len = 8; arg.key_rxmic_len = 8; break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: arg.key_cipher = WMI_CIPHER_WEP; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_WEP]; break; case WLAN_CIPHER_SUITE_CCMP_256: arg.key_cipher = WMI_CIPHER_AES_CCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM]; break; case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP_256: arg.key_cipher = WMI_CIPHER_AES_GCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM]; break; case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_256: Loading @@ -265,7 +265,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; if (cmd == DISABLE_KEY) { arg.key_cipher = WMI_CIPHER_NONE; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_NONE]; arg.key_data = NULL; } Loading Loading @@ -685,6 +685,26 @@ ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw, *def = &conf->def; } static void ath10k_wait_for_peer_delete_done(struct ath10k *ar, u32 vdev_id, const u8 *addr) { unsigned long time_left; int ret; if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr); if (ret) { ath10k_warn(ar, "failed wait for peer deleted"); return; } time_left = wait_for_completion_timeout(&ar->peer_delete_done, 5 * HZ); if (!time_left) ath10k_warn(ar, "Timeout in receiving peer delete response\n"); } } static int ath10k_peer_create(struct ath10k *ar, struct ieee80211_vif *vif, struct ieee80211_sta *sta, Loading Loading @@ -729,7 +749,7 @@ static int ath10k_peer_create(struct ath10k *ar, spin_unlock_bh(&ar->data_lock); ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n", addr, vdev_id); ath10k_wmi_peer_delete(ar, vdev_id, addr); ath10k_wait_for_peer_delete_done(ar, vdev_id, addr); return -ENOENT; } Loading Loading @@ -811,6 +831,18 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) if (ret) return ret; if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { unsigned long time_left; time_left = wait_for_completion_timeout (&ar->peer_delete_done, 5 * HZ); if (!time_left) { ath10k_warn(ar, "Timeout in receiving peer delete response\n"); return -ETIMEDOUT; } } ar->num_peers--; return 0; Loading Loading @@ -1003,6 +1035,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_start(ar, &arg); if (ret) { Loading Loading @@ -1052,6 +1085,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar) ar->monitor_vdev_id, ret); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); if (ret) Loading Loading @@ -1393,6 +1427,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) lockdep_assert_held(&ar->conf_mutex); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); if (ret) { Loading Loading @@ -1429,6 +1464,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, lockdep_assert_held(&ar->conf_mutex); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); arg.vdev_id = arvif->vdev_id; arg.dtim_period = arvif->dtim_period; Loading Loading @@ -5244,8 +5280,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, err_peer_delete: if (arvif->vdev_type == WMI_VDEV_TYPE_AP || arvif->vdev_type == WMI_VDEV_TYPE_IBSS) arvif->vdev_type == WMI_VDEV_TYPE_IBSS) { ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr); ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, vif->addr); } err_vdev_delete: ath10k_wmi_vdev_delete(ar, arvif->vdev_id); Loading Loading @@ -5280,6 +5319,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = (void *)vif->drv_priv; struct ath10k_peer *peer; unsigned long time_left; int ret; int i; Loading Loading @@ -5310,6 +5350,8 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n", arvif->vdev_id, ret); ath10k_wait_for_peer_delete_done(ar, arvif->vdev_id, vif->addr); kfree(arvif->u.ap.noa_data); } Loading @@ -5321,6 +5363,15 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", arvif->vdev_id, ret); if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { time_left = wait_for_completion_timeout(&ar->vdev_delete_done, ATH10K_VDEV_DELETE_TIMEOUT_HZ); if (time_left == 0) { ath10k_warn(ar, "Timeout in receiving vdev delete response\n"); goto out; } } /* Some firmware revisions don't notify host about self-peer removal * until after associated vdev is deleted. */ Loading Loading @@ -5371,6 +5422,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_mac_txq_unref(ar, vif->txq); out: mutex_unlock(&ar->conf_mutex); } Loading
drivers/net/wireless/ath/ath10k/wmi-tlv.c +60 −4 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -222,6 +223,13 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, return 0; } static void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar, struct sk_buff *skb) { ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n"); complete(&ar->vdev_delete_done); } static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar, struct sk_buff *skb) { Loading Loading @@ -412,6 +420,24 @@ static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, return 0; } static int ath10k_wmi_tlv_event_peer_delete_resp(struct ath10k *ar, struct sk_buff *skb) { struct wmi_peer_delete_resp_ev_arg *arg; struct wmi_tlv *tlv_hdr; tlv_hdr = (struct wmi_tlv *)skb->data; arg = (struct wmi_peer_delete_resp_ev_arg *)tlv_hdr->value; ath10k_dbg(ar, ATH10K_DBG_WMI, "vdev id %d", arg->vdev_id); ath10k_dbg(ar, ATH10K_DBG_WMI, "peer mac addr %pM", &arg->peer_addr); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete response\n"); complete(&ar->peer_delete_done); return 0; } /***********/ /* TLV ops */ /***********/ Loading Loading @@ -468,6 +494,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_TLV_VDEV_STOPPED_EVENTID: ath10k_wmi_event_vdev_stopped(ar, skb); break; case WMI_TLV_VDEV_DELETE_RESP_EVENTID: ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb); break; case WMI_TLV_PEER_STA_KICKOUT_EVENTID: ath10k_wmi_event_peer_sta_kickout(ar, skb); break; Loading Loading @@ -555,6 +584,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) case WMI_TLV_TX_PAUSE_EVENTID: ath10k_wmi_tlv_event_tx_pause(ar, skb); break; case WMI_TLV_PEER_DELETE_RESP_EVENTID: ath10k_wmi_tlv_event_peer_delete_resp(ar, skb); break; default: ath10k_warn(ar, "Unknown eventid: %d\n", id); break; Loading Loading @@ -1704,6 +1736,28 @@ ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar, return skb; } static int ath10k_wmi_tlv_op_get_vdev_subtype(struct ath10k *ar, enum wmi_vdev_subtype subtype) { switch (subtype) { case WMI_VDEV_SUBTYPE_NONE: return WMI_TLV_VDEV_SUBTYPE_NONE; case WMI_VDEV_SUBTYPE_P2P_DEVICE: return WMI_TLV_VDEV_SUBTYPE_P2P_DEV; case WMI_VDEV_SUBTYPE_P2P_CLIENT: return WMI_TLV_VDEV_SUBTYPE_P2P_CLI; case WMI_VDEV_SUBTYPE_P2P_GO: return WMI_TLV_VDEV_SUBTYPE_P2P_GO; case WMI_VDEV_SUBTYPE_PROXY_STA: return WMI_TLV_VDEV_SUBTYPE_PROXY_STA; case WMI_VDEV_SUBTYPE_MESH_11S: return WMI_TLV_VDEV_SUBTYPE_MESH_11S; case WMI_VDEV_SUBTYPE_MESH_NON_11S: return -ENOTSUPP; } return -ENOTSUPP; } static struct sk_buff * ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id, Loading Loading @@ -1932,9 +1986,11 @@ ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar, size_t len; void *ptr; if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] && arg->key_data) return ERR_PTR(-EINVAL); if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] && !arg->key_data) return ERR_PTR(-EINVAL); len = sizeof(*tlv) + sizeof(*cmd) + Loading Loading @@ -2611,7 +2667,7 @@ ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) ieee80211_is_deauth(hdr->frame_control) || ieee80211_is_disassoc(hdr->frame_control)) && ieee80211_has_protected(hdr->frame_control)) { len += IEEE80211_CCMP_MIC_LEN; skb_put(msdu, IEEE80211_CCMP_MIC_LEN); buf_len += IEEE80211_CCMP_MIC_LEN; } Loading Loading @@ -3826,7 +3882,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, .get_vdev_subtype = ath10k_wmi_tlv_op_get_vdev_subtype, .gen_echo = ath10k_wmi_tlv_op_gen_echo, .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, Loading
drivers/net/wireless/ath/ath10k/wmi-tlv.h +19 −0 Original line number Diff line number Diff line /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -309,11 +310,15 @@ enum wmi_tlv_event_id { WMI_TLV_VDEV_STOPPED_EVENTID, WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID, WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID, WMI_TLV_VDEV_TSF_REPORT_EVENTID, WMI_TLV_VDEV_DELETE_RESP_EVENTID, WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER), WMI_TLV_PEER_INFO_EVENTID, WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID, WMI_TLV_PEER_ESTIMATED_LINKSPEED_EVENTID, WMI_TLV_PEER_STATE_EVENTID, WMI_TLV_PEER_ASSOC_CONF_EVENTID, WMI_TLV_PEER_DELETE_RESP_EVENTID, WMI_TLV_MGMT_RX_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MGMT), WMI_TLV_HOST_SWBA_EVENTID, WMI_TLV_TBTTOFFSET_UPDATE_EVENTID, Loading Loading @@ -1554,6 +1559,10 @@ wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len) WMI_SERVICE_SAP_AUTH_OFFLOAD, len); SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI, WMI_SERVICE_MGMT_TX_WMI, len); SVCMAP(WMI_TLV_SERVICE_MESH_11S, WMI_SERVICE_MESH_11S, len); SVCMAP(WMI_TLV_SERVICE_SYNC_DELETE_CMDS, WMI_SERVICE_SYNC_DELETE_CMDS, len); } static inline void Loading Loading @@ -1721,6 +1730,16 @@ struct wmi_tlv_start_scan_cmd { struct wmi_mac_addr mac_mask; } __packed; enum wmi_tlv_vdev_subtype { WMI_TLV_VDEV_SUBTYPE_NONE = 0, WMI_TLV_VDEV_SUBTYPE_P2P_DEV = 1, WMI_TLV_VDEV_SUBTYPE_P2P_CLI = 2, WMI_TLV_VDEV_SUBTYPE_P2P_GO = 3, WMI_TLV_VDEV_SUBTYPE_PROXY_STA = 4, WMI_TLV_VDEV_SUBTYPE_MESH = 5, WMI_TLV_VDEV_SUBTYPE_MESH_11S = 6, }; struct wmi_tlv_vdev_start_cmd { __le32 vdev_id; __le32 requestor_id; Loading