diff --git a/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h b/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h index 92ca9f7b87..ca7f1a9ad6 100644 --- a/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h +++ b/os_if/linux/wifi_pos/inc/os_if_wifi_pos.h @@ -28,6 +28,7 @@ #include "qdf_status.h" #include #include "wifi_pos_public_struct.h" +#include "wlan_cfg80211.h" /* forward declaration */ struct wifi_pos_ch_info; @@ -35,6 +36,12 @@ struct wlan_objmgr_psoc; struct wifi_pos_driver_caps; #ifdef WIFI_POS_CONVERGED +#define FEATURE_WIFI_POS_11AZ_AUTH_EVENTS \ +[QCA_NL80211_VENDOR_SUBCMD_PASN_AUTH_STATUS_INDEX] = { \ + .vendor_id = QCA_NL80211_VENDOR_ID, \ + .subcmd = QCA_NL80211_VENDOR_SUBCMD_PASN, \ +}, + /** * os_if_wifi_pos_register_nl() - abstration API to register callback with GENL * socket. @@ -80,6 +87,8 @@ void os_if_wifi_pos_send_peer_status(struct qdf_mac_addr *peer_mac, int os_if_wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, struct wifi_pos_driver_caps *caps); #else +#define FEATURE_WIFI_POS_11AZ_AUTH_EVENTS + static inline int os_if_wifi_pos_register_nl(void) { return 0; diff --git a/os_if/linux/wifi_pos/inc/os_if_wifi_pos_utils.h b/os_if/linux/wifi_pos/inc/os_if_wifi_pos_utils.h index 26a6cbafe6..78febcbc55 100644 --- a/os_if/linux/wifi_pos/inc/os_if_wifi_pos_utils.h +++ b/os_if/linux/wifi_pos/inc/os_if_wifi_pos_utils.h @@ -37,9 +37,7 @@ struct wifi_pos_osif_ops { uint8_t num_pasn_peers, bool is_initiate_pasn); }; -#endif -#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) /** * osif_wifi_pos_register_ops() - Register Wifi-Pos module OS_IF callbacks * @psoc: Pointer to PSOC obj diff --git a/os_if/linux/wifi_pos/src/os_if_wifi_pos.c b/os_if/linux/wifi_pos/src/os_if_wifi_pos.c index f59904b6e2..c6d3754f12 100644 --- a/os_if/linux/wifi_pos/src/os_if_wifi_pos.c +++ b/os_if/linux/wifi_pos/src/os_if_wifi_pos.c @@ -1093,9 +1093,14 @@ os_if_wifi_pos_initiate_pasn_auth(struct wlan_objmgr_vdev *vdev, bool is_initiate_pasn) { struct net_device *netdev; - struct cfg80211_pasn_params *pasn_params; struct vdev_osif_priv *osif_priv; - int i, ret; + struct sk_buff *skb; + struct nlattr *attr, *nest_attr; + enum qca_wlan_vendor_pasn_action action; + int i; + int index = QCA_NL80211_VENDOR_SUBCMD_PASN_AUTH_STATUS_INDEX; + uint16_t record_size; + uint32_t len; QDF_STATUS status = QDF_STATUS_SUCCESS; osif_priv = wlan_vdev_get_ospriv(vdev); @@ -1106,43 +1111,79 @@ os_if_wifi_pos_initiate_pasn_auth(struct wlan_objmgr_vdev *vdev, netdev = osif_priv->wdev->netdev; - pasn_params = qdf_mem_malloc(sizeof(*pasn_params) + - (num_pasn_peers * - sizeof(struct pasn_peer))); - if (!pasn_params) + len = NLMSG_HDRLEN; + /* QCA_WLAN_VENDOR_ATTR_PASN_ACTION */ + len += nla_total_size(sizeof(u32)); + + /* + * size of nest containing + * QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR + * QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR + */ + record_size = nla_total_size(2 * nla_total_size(ETH_ALEN)); + + /* QCA_WLAN_VENDOR_ATTR_PASN_PEERS nest */ + len += nla_total_size(num_pasn_peers * record_size); + + skb = wlan_cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy, + osif_priv->wdev, len, + index, GFP_ATOMIC); + if (!skb) return QDF_STATUS_E_NOMEM; - pasn_params->action = (is_initiate_pasn ? - NL80211_PASN_ACTION_AUTH : NL80211_PASN_ACTION_DEAUTH); + action = is_initiate_pasn ? + QCA_WLAN_VENDOR_PASN_ACTION_AUTH : + QCA_WLAN_VENDOR_PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT; + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_PASN_ACTION, action)) { + osif_err("NLA put failed"); + goto nla_put_failure; + } + + attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_PASN_PEERS); + if (!attr) { + osif_err("NLA nest failed"); + status = QDF_STATUS_E_FAILURE; + goto nla_put_failure; + } - pasn_params->num_pasn_peers = num_pasn_peers; for (i = 0; i < num_pasn_peers; i++) { - qdf_mem_copy(pasn_params->peer[i].peer_addr, - pasn_peer[i].peer_mac.bytes, - QDF_MAC_ADDR_SIZE); - qdf_mem_copy(pasn_params->peer[i].src_addr, - pasn_peer[i].self_mac.bytes, - QDF_MAC_ADDR_SIZE); - if (pasn_peer[i].force_self_mac_usage) - pasn_params->peer[i].flags = PASN_PEER_USE_SRC_MAC; + osif_debug("PASN peer_mac[%d]:" QDF_MAC_ADDR_FMT "src_mac:" QDF_MAC_ADDR_FMT, i, + QDF_MAC_ADDR_REF(pasn_peer[i].peer_mac.bytes), + QDF_MAC_ADDR_REF(pasn_peer[i].self_mac.bytes)); + nest_attr = nla_nest_start(skb, i); + if (!nest_attr) { + osif_err("NLA nest failed for iter:%d", i); + status = QDF_STATUS_E_FAILURE; + goto nla_put_failure; + } - osif_debug("PASN peer_mac[%d]:" QDF_MAC_ADDR_FMT " src_mac:" QDF_MAC_ADDR_FMT, - i, - QDF_MAC_ADDR_REF(pasn_params->peer[i].peer_addr), - QDF_MAC_ADDR_REF(pasn_params->peer[i].src_addr)); + if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR, + ETH_ALEN, pasn_peer[i].peer_mac.bytes)) { + osif_err("NLA put failed"); + status = QDF_STATUS_E_FAILURE; + goto nla_put_failure; + } + + if (pasn_peer[i].force_self_mac_usage && + nla_put(skb, QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR, + ETH_ALEN, pasn_peer[i].self_mac.bytes)) { + osif_err("NLA put failed"); + status = QDF_STATUS_E_FAILURE; + goto nla_put_failure; + } + + nla_nest_end(skb, nest_attr); } + nla_nest_end(skb, attr); - osif_debug("action:%d num_pasn_peers:%d", pasn_params->action, - pasn_params->num_pasn_peers); + osif_debug("action:%d num_pasn_peers:%d", action, num_pasn_peers); - ret = cfg80211_pasn_auth_request(netdev, pasn_params, - qdf_mem_malloc_flags()); - if (ret) { - status = qdf_status_from_os_return(ret); - osif_err("PASN Auth request failed"); - } + wlan_cfg80211_vendor_event(skb, GFP_ATOMIC); - qdf_mem_free(pasn_params); + return status; + +nla_put_failure: + wlan_cfg80211_vendor_free_skb(skb); return status; } diff --git a/os_if/linux/wlan_cfg80211.h b/os_if/linux/wlan_cfg80211.h index 3d8ea179ab..38fccbcb3a 100644 --- a/os_if/linux/wlan_cfg80211.h +++ b/os_if/linux/wlan_cfg80211.h @@ -255,6 +255,7 @@ enum qca_nl80211_vendor_subcmds_index { QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA_INDEX, QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING_INDEX, QCA_NL80211_VENDOR_SUBCMD_DRIVER_READY_INDEX, + QCA_NL80211_VENDOR_SUBCMD_PASN_AUTH_STATUS_INDEX, #ifdef WLAN_SUPPORT_SCS QCA_NL80211_VENDOR_SUBCMD_SCS_RULE_CONFIG_INDEX, #endif diff --git a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c index 622cdc341b..6f850601bb 100644 --- a/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c +++ b/target_if/mlme/vdev_mgr/src/target_if_vdev_mgr_rx_ops.c @@ -164,6 +164,7 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg) } else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, &vdev_rsp->rsp_status)) { peer_del_all_rsp.vdev_id = vdev_id; + peer_del_all_rsp.peer_type_bitmap = vdev_rsp->peer_type_bitmap; rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT; recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT; target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c index d3a4818c15..6588434a74 100644 --- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c +++ b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c @@ -33,6 +33,7 @@ #endif #ifdef WIFI_POS_CONVERGED #include "target_if_wifi_pos.h" +#include "target_if_wifi_pos_rx_ops.h" #endif /* WIFI_POS_CONVERGED */ #include "wlan_reg_tgt_api.h" #ifdef CONVERGED_P2P_ENABLE diff --git a/umac/wifi_pos/inc/wifi_pos_pasn_api.h b/umac/wifi_pos/inc/wifi_pos_pasn_api.h index 742a64ec1e..03bf9108d0 100644 --- a/umac/wifi_pos/inc/wifi_pos_pasn_api.h +++ b/umac/wifi_pos/inc/wifi_pos_pasn_api.h @@ -154,6 +154,17 @@ wifi_pos_get_pasn_peer_count(struct wlan_objmgr_vdev *vdev); void wifi_pos_update_pasn_peer_count(struct wlan_objmgr_vdev *vdev, bool is_increment); +/** + * wifi_pos_cleanup_pasn_peers - Delete all PASN peer objects for + * given vdev + * @vdev: Pointer to vdev object + * + * Return: QDF_STATUS + */ +QDF_STATUS +wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev); + /** * wifi_pos_vdev_delete_all_ranging_peers() - Delete all ranging peers * associated with given vdev id @@ -176,6 +187,26 @@ wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev); QDF_STATUS wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); + +/** + * wifi_pos_is_delete_all_peer_in_progress() - Check if delete all + * pasn peers command is already in progress for a given vdev + * @vdev: Vdev object pointer + * + * Return: True if delete all pasn peer is in progress + */ +bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev); + +/** + * wifi_pos_set_delete_all_peer_in_progress() - API to set/unset delete all + * ranging peers is in progress + * @vdev: Pointer to vdev object + * @flag: value to indicate set or unset the flag + * + * Return: None + */ +void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev, + bool flag); #else static inline QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc, @@ -238,5 +269,23 @@ wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev) { return QDF_STATUS_SUCCESS; } + +static inline +bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev) +{ + return false; +} + +static inline QDF_STATUS +wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev, + bool flag) +{} #endif /* WIFI_POS_CONVERGED && WLAN_FEATURE_RTT_11AZ_SUPPORT */ #endif /* _WIFI_POS_PASN_API_H_ */ diff --git a/umac/wifi_pos/src/wifi_pos_pasn_api.c b/umac/wifi_pos/src/wifi_pos_pasn_api.c index 62da384860..b52caea5a2 100644 --- a/umac/wifi_pos/src/wifi_pos_pasn_api.c +++ b/umac/wifi_pos/src/wifi_pos_pasn_api.c @@ -177,7 +177,7 @@ void wifi_pos_move_peers_to_fail_list(struct wlan_objmgr_vdev *vdev, uint8_t i; struct wifi_pos_vdev_priv_obj *vdev_pos_obj; struct wifi_pos_11az_context *pasn_context; - struct wlan_pasn_request *secure_list, *unsecure_list, *list; + struct wlan_pasn_request *secure_list, *unsecure_list, *list = NULL; struct qdf_mac_addr entry_to_copy; if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) @@ -201,7 +201,12 @@ void wifi_pos_move_peers_to_fail_list(struct wlan_objmgr_vdev *vdev, if (peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER) list = pasn_context->secure_peer_list; else if (peer_type == WLAN_WIFI_POS_PASN_UNSECURE_PEER) - list = pasn_context->secure_peer_list; + list = pasn_context->unsecure_peer_list; + + if (!list) { + wifi_pos_err("No Valid list exists"); + return; + } for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) { /* @@ -478,6 +483,7 @@ wifi_pos_handle_ranging_peer_create_rsp(struct wlan_objmgr_psoc *psoc, wifi_pos_debug("Received peer create response for " QDF_MAC_ADDR_FMT " status:%d pending_count:%d", QDF_MAC_ADDR_REF(peer_mac->bytes), peer_create_status, pasn_context->num_pending_peer_creation); + if (peer_create_status) { wifi_pos_move_peers_to_fail_list(vdev, peer_mac, WLAN_WIFI_POS_PASN_PEER_TYPE_MAX); @@ -700,15 +706,55 @@ bool wifi_pos_is_ltf_keyseed_required_for_peer(struct wlan_objmgr_peer *peer) } static -void wifi_pos_delete_objmgr_ranging_peer(struct wlan_objmgr_vdev *vdev, +void wifi_pos_delete_objmgr_ranging_peer(struct wlan_objmgr_psoc *psoc, void *object, void *arg) { struct wlan_objmgr_peer *peer = object; + struct wlan_objmgr_vdev *vdev = arg; + uint8_t vdev_id, peer_vdev_id; + enum wlan_peer_type peer_type; QDF_STATUS status; + if (!peer) { + wifi_pos_err("Peer is NULL"); + return; + } + + peer_type = wlan_peer_get_peer_type(peer); + if (peer_type != WLAN_PEER_RTT_PASN) + return; + + if (!vdev) { + wifi_pos_err("VDEV is NULL"); + return; + } + + vdev_id = wlan_vdev_get_id(vdev); + peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); + if (vdev_id != peer_vdev_id) + return; + status = wlan_objmgr_peer_obj_delete(peer); if (QDF_IS_STATUS_ERROR(status)) wifi_pos_err("Failed to delete peer"); + + wifi_pos_update_pasn_peer_count(vdev, false); +} + +QDF_STATUS +wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status; + + wifi_pos_debug("Iterate and delete PASN peers"); + status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP, + wifi_pos_delete_objmgr_ranging_peer, + vdev, 0, WLAN_WIFI_POS_CORE_ID); + if (QDF_IS_STATUS_ERROR(status)) + wifi_pos_err("Delete objmgr peers failed"); + + return status; } QDF_STATUS @@ -729,11 +775,6 @@ wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_SUCCESS; vdev_pos_obj->is_delete_all_pasn_peer_in_progress = true; - status = wlan_objmgr_iterate_peerobj_list(vdev, - wifi_pos_delete_objmgr_ranging_peer, - NULL, WLAN_WIFI_POS_CORE_ID); - if (QDF_IS_STATUS_ERROR(status)) - wifi_pos_err("Delete objmgr peers failed"); vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); if (!vdev_mlme) { @@ -774,6 +815,12 @@ wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + status = wifi_pos_cleanup_pasn_peers(psoc, vdev); + if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); + return status; + } + vdev_pos_obj->is_delete_all_pasn_peer_in_progress = false; legacy_cb = wifi_pos_get_legacy_ops(psoc); @@ -791,3 +838,30 @@ wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc, return status; } + +bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev) +{ + struct wifi_pos_vdev_priv_obj *vdev_pos_obj; + + vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); + if (!vdev_pos_obj) { + wifi_pos_err("Wifi pos vdev priv obj is null"); + return false; + } + + return vdev_pos_obj->is_delete_all_pasn_peer_in_progress; +} + +void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev, + bool flag) +{ + struct wifi_pos_vdev_priv_obj *vdev_pos_obj; + + vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); + if (!vdev_pos_obj) { + wifi_pos_err("Wifi pos vdev priv obj is null"); + return; + } + + vdev_pos_obj->is_delete_all_pasn_peer_in_progress = flag; +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 3cee72d2e3..6d65a3ffa5 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -16486,6 +16486,10 @@ send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle, WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, &auth_status_tlv->source_mac_addr); auth_status_tlv->status = data->auth_status[i].status; + wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d", + QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes), + QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes), + auth_status_tlv->status); buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); }