From 10ddbd5a8c608508fe7e7d44c25fa1b9844e8fff Mon Sep 17 00:00:00 2001 From: Vinod Kumar Pirla Date: Thu, 27 Oct 2022 03:55:25 -0700 Subject: [PATCH] qcacld-3.0: Send peer ML info on BSS join/leave to cfg80211 On client connection, send the client's MLD address, assoc response IEs and the link_id of SAP on which the new client is added. For non-MLO capable clients the MLD is sent as NULL address On ML client disconnection, use MLD address of the client as argument to cfg80211_del_sta(). For non-MLO client disconnection, use the legacy address of the client as argument to cfg80211_del_sta(). Change-Id: I43cb8e688251b6118932e1ae88f7abdf53dd54a0 CRs-Fixed: 3324216 --- .../mlme/dispatcher/inc/wlan_mlme_api.h | 15 ++++ .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 20 +++++ .../mlme/dispatcher/src/wlan_mlme_api.c | 24 ++++++ core/hdd/src/wlan_hdd_hostapd.c | 77 ++++++++++++++++++- 4 files changed, 132 insertions(+), 4 deletions(-) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 3ed77d1715..ac4535de7f 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -1228,6 +1228,21 @@ QDF_STATUS wlan_mlme_set_default_primary_iface(struct wlan_objmgr_psoc *psoc); */ bool wlan_mlme_is_primary_interface_configured(struct wlan_objmgr_psoc *psoc); +/** + * wlan_mlme_peer_get_assoc_rsp_ies() - Get the assoc response IEs of peer + * @peer: WLAN peer objmgr + * @ie_buf: Pointer to IE buffer + * @ie_len: Length of the IE buffer + * + * Get the pointer to assoc response IEs of the peer from MLME + * and length of the IE buffer. + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlme_peer_get_assoc_rsp_ies(struct wlan_objmgr_peer *peer, + const uint8_t **ie_buf, + size_t *ie_len); + /** * wlan_mlme_get_mcc_duty_cycle_percentage() - Get primary STA iface duty * cycle percentage diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 5b32e04c9c..d5ff957107 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -2522,6 +2522,26 @@ ucfg_mlme_get_vht_tx_mcs_2x2(struct wlan_objmgr_psoc *psoc, uint8_t *value) return wlan_mlme_get_vht_tx_mcs_2x2(psoc, value); } +/** + * ucfg_mlme_peer_get_assoc_rsp_ies() - Get assoc response sent to peer + * @peer: WLAN peer objmgr + * @ie_buf: Pointer to IE buffer + * @ie_len: Length of the IE buffer + * + * This API is used to get the assoc response sent to peer + * as part of association. + * Caller to hold reference for peer. + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +ucfg_mlme_peer_get_assoc_rsp_ies(struct wlan_objmgr_peer *peer, + const uint8_t **ie_buf, + size_t *ie_len) +{ + return wlan_mlme_peer_get_assoc_rsp_ies(peer, ie_buf, ie_len); +} + /** * ucfg_mlme_get_ini_vdev_config() - get the ini capability of vdev * @vdev: pointer to the vdev obj diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 2684afb42d..7ba4349b37 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -2811,6 +2811,30 @@ bool wlan_mlme_is_primary_interface_configured(struct wlan_objmgr_psoc *psoc) QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY); } +QDF_STATUS wlan_mlme_peer_get_assoc_rsp_ies(struct wlan_objmgr_peer *peer, + const uint8_t **ie_buf, + size_t *ie_len) +{ + struct peer_mlme_priv_obj *peer_priv; + + if (!peer || !ie_buf || !ie_len) + return QDF_STATUS_E_INVAL; + + *ie_buf = NULL; + *ie_len = 0; + + peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer, + WLAN_UMAC_COMP_MLME); + + if (!peer_priv || peer_priv->assoc_rsp.len == 0) + return QDF_STATUS_SUCCESS; + + *ie_buf = peer_priv->assoc_rsp.ptr; + *ie_len = peer_priv->assoc_rsp.len; + + return QDF_STATUS_SUCCESS; +} + int wlan_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev) { struct wlan_objmgr_psoc *psoc = NULL; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 26f2c57bf7..11ef683ffe 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1872,6 +1872,59 @@ release_ref: } } +#ifdef WLAN_MLD_AP_STA_CONNECT_SUPPORT +static void +hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter *adapter, + struct station_info *sta_info, + uint8_t *peer_mac) +{ + bool is_mlo_vdev; + QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_peer *sta_peer; + + vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_OSIF_ID); + if (!vdev) { + hdd_err("Failed to get link id, VDEV NULL"); + return; + } + + is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev); + if (is_mlo_vdev) + sta_info->link_id = wlan_vdev_get_link_id(vdev); + else + sta_info->link_id = -1; + hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID); + + if (!is_mlo_vdev) + return; + + sta_peer = wlan_objmgr_get_peer_by_mac(adapter->hdd_ctx->psoc, + peer_mac, WLAN_OSIF_ID); + + if (!sta_peer) { + hdd_err("Peer not found with MAC " QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(peer_mac)); + return; + } + qdf_mem_copy(sta_info->mld_addr, wlan_peer_mlme_get_mldaddr(sta_peer), + ETH_ALEN); + + status = ucfg_mlme_peer_get_assoc_rsp_ies( + sta_peer, + &sta_info->assoc_resp_ies, + &sta_info->assoc_resp_ies_len); + wlan_objmgr_peer_release_ref(sta_peer, WLAN_OSIF_ID); +} +#else +static void +hdd_hostapd_sap_fill_peer_ml_info(struct hdd_adapter *adapter, + struct station_info *sta_info, + uint8_t *peer_mac) +{ +} +#endif + QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, void *context) { @@ -1910,6 +1963,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, uint8_t pdev_id; bool notify_new_sta = true; struct wlan_objmgr_vdev *vdev; + struct qdf_mac_addr sta_addr = {0}; qdf_freq_t dfs_freq; dev = context; @@ -2509,6 +2563,14 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, */ sta_info->filled |= STATION_INFO_ASSOC_REQ_IES; #endif + /* For ML clients need to fill assoc resp IEs + * and MLD address. + * For Legacy clients MLD address will be + * NULL MAC address. + */ + hdd_hostapd_sap_fill_peer_ml_info(adapter, sta_info, + event->staMac.bytes); + if (notify_new_sta) cfg80211_new_sta(dev, (const u8 *)&event-> @@ -2607,7 +2669,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, return QDF_STATUS_E_INVAL; } - if (wlan_vdev_mlme_is_mlo_vdev(adapter->vdev)) { + if (wlan_vdev_mlme_is_mlo_vdev(adapter->vdev) && + !qdf_is_macaddr_zero(&stainfo->mld_addr)) { mld_sta_info = hdd_get_sta_info_by_mac( &adapter->sta_info_list, stainfo->mld_addr.bytes, @@ -2620,7 +2683,13 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, hdd_put_sta_info_ref(&adapter->sta_info_list, &mld_sta_info, true, STA_INFO_HOSTAPD_SAP_EVENT_CB); + qdf_copy_macaddr(&sta_addr, &stainfo->mld_addr); } + } else { + /* Copy legacy MAC address on + * non-ML type client disassoc. + */ + qdf_copy_macaddr(&sta_addr, &disassoc_comp->staMac); } vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_DP_ID); @@ -2674,12 +2743,12 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event, * SSR in progress. Since supplicant will change mode * fail and down during this time. */ + if ((adapter->device_mode != QDF_P2P_GO_MODE) || (!cds_is_driver_recovering())) { cfg80211_del_sta(dev, - (const u8 *)&sap_event->sapevt. - sapStationDisassocCompleteEvent.staMac. - bytes[0], GFP_KERNEL); + (const u8 *)&sta_addr.bytes[0], + GFP_KERNEL); hdd_debug("indicate sta deletion event"); }