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
This commit is contained in:
Vinod Kumar Pirla
2022-10-27 03:55:25 -07:00
committed by Madan Koyyalamudi
parent 188e55a759
commit 10ddbd5a8c
4 changed files with 132 additions and 4 deletions

View File

@@ -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); 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 * wlan_mlme_get_mcc_duty_cycle_percentage() - Get primary STA iface duty
* cycle percentage * cycle percentage

View File

@@ -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); 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 * ucfg_mlme_get_ini_vdev_config() - get the ini capability of vdev
* @vdev: pointer to the vdev obj * @vdev: pointer to the vdev obj

View File

@@ -2811,6 +2811,30 @@ bool wlan_mlme_is_primary_interface_configured(struct wlan_objmgr_psoc *psoc)
QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY); 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) int wlan_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev)
{ {
struct wlan_objmgr_psoc *psoc = NULL; struct wlan_objmgr_psoc *psoc = NULL;

View File

@@ -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, QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
void *context) void *context)
{ {
@@ -1910,6 +1963,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
uint8_t pdev_id; uint8_t pdev_id;
bool notify_new_sta = true; bool notify_new_sta = true;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
struct qdf_mac_addr sta_addr = {0};
qdf_freq_t dfs_freq; qdf_freq_t dfs_freq;
dev = context; 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; sta_info->filled |= STATION_INFO_ASSOC_REQ_IES;
#endif #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) if (notify_new_sta)
cfg80211_new_sta(dev, cfg80211_new_sta(dev,
(const u8 *)&event-> (const u8 *)&event->
@@ -2607,7 +2669,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
return QDF_STATUS_E_INVAL; 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( mld_sta_info = hdd_get_sta_info_by_mac(
&adapter->sta_info_list, &adapter->sta_info_list,
stainfo->mld_addr.bytes, 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, hdd_put_sta_info_ref(&adapter->sta_info_list,
&mld_sta_info, true, &mld_sta_info, true,
STA_INFO_HOSTAPD_SAP_EVENT_CB); 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); 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 * SSR in progress. Since supplicant will change mode
* fail and down during this time. * fail and down during this time.
*/ */
if ((adapter->device_mode != QDF_P2P_GO_MODE) || if ((adapter->device_mode != QDF_P2P_GO_MODE) ||
(!cds_is_driver_recovering())) { (!cds_is_driver_recovering())) {
cfg80211_del_sta(dev, cfg80211_del_sta(dev,
(const u8 *)&sap_event->sapevt. (const u8 *)&sta_addr.bytes[0],
sapStationDisassocCompleteEvent.staMac. GFP_KERNEL);
bytes[0], GFP_KERNEL);
hdd_debug("indicate sta deletion event"); hdd_debug("indicate sta deletion event");
} }