qcacmn: Send roam auth mlo links event

After mlo roaming is complete send roam auth mlo links
event to kernel.
Also populate cfg roam info structure with mlo link info.

Change-Id: I8710e3a53f05c50b7b276d87a39411cb43d0983f
CRs-Fixed: 3279967
This commit is contained in:
Amruta Kulkarni
2022-08-28 21:45:25 +08:00
committed by Madan Koyyalamudi
parent 400309d015
commit c3051031c5
3 changed files with 393 additions and 87 deletions

View File

@@ -382,30 +382,8 @@ osif_populate_fils_params(struct cfg80211_connect_resp_params *rsp_params,
#endif /* WLAN_FEATURE_FILS_SK */
#endif
#if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
#ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
static struct wlan_objmgr_vdev *osif_get_partner_vdev(struct wlan_objmgr_vdev *vdev,
struct mlo_link_info rsp_partner_info)
{
return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id);
}
#endif
static
void osif_populate_connect_response_for_link(struct wlan_objmgr_vdev *vdev,
struct cfg80211_connect_resp_params *conn_rsp_params,
uint8_t link_id,
struct cfg80211_bss *bss)
{
osif_debug("Link_id :%d", link_id);
conn_rsp_params->valid_links |= BIT(link_id);
conn_rsp_params->links[link_id].bssid = bss->bssid;
conn_rsp_params->links[link_id].bss = bss;
conn_rsp_params->links[link_id].addr =
wlan_vdev_mlme_get_macaddr(vdev);
}
static QDF_STATUS
#ifdef WLAN_FEATURE_11BE_MLO
QDF_STATUS
osif_get_partner_info_from_mlie(struct wlan_cm_connect_resp *connect_rsp,
struct mlo_partner_info *partner_info)
{
@@ -434,38 +412,14 @@ osif_get_partner_info_from_mlie(struct wlan_cm_connect_resp *connect_rsp,
qdf_status = util_get_bvmlie_persta_partner_info(ml_ie, ml_ie_len,
partner_info);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
osif_err("Unable to find per-sta profile in ML IE :%d");
osif_err("Unable to find per-sta profile in ML IE");
return qdf_status;
}
return qdf_status;
}
static QDF_STATUS
osif_fill_peer_mld_mac_connect_resp(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_connect_resp_params *conn_rsp_params)
{
struct wlan_objmgr_peer *peer_obj;
struct wlan_objmgr_psoc *psoc;
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc)
return QDF_STATUS_E_INVAL;
peer_obj = wlan_objmgr_get_peer_by_mac(psoc,
rsp->bssid.bytes, WLAN_OSIF_ID);
if (!peer_obj)
return QDF_STATUS_E_INVAL;
conn_rsp_params->ap_mld_addr = wlan_peer_mlme_get_mldaddr(peer_obj);
wlan_objmgr_peer_release_ref(peer_obj, WLAN_OSIF_ID);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS
QDF_STATUS
osif_get_link_id_from_assoc_ml_ie(struct mlo_link_info *rsp_link_info,
struct mlo_partner_info *assoc_partner_info,
uint8_t *link_id)
@@ -484,7 +438,7 @@ osif_get_link_id_from_assoc_ml_ie(struct mlo_link_info *rsp_link_info,
return QDF_STATUS_E_INVAL;
}
static struct cfg80211_bss *
struct cfg80211_bss *
osif_get_chan_bss_from_kernel(struct wlan_objmgr_vdev *vdev,
struct mlo_link_info *rsp_link_info,
struct wlan_cm_connect_resp *rsp)
@@ -498,7 +452,7 @@ osif_get_chan_bss_from_kernel(struct wlan_objmgr_vdev *vdev,
rsp_link_info->chan_freq);
if (!chan) {
osif_err("Invalid partner channel");
NULL;
return NULL;
}
partner_bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
@@ -511,6 +465,49 @@ osif_get_chan_bss_from_kernel(struct wlan_objmgr_vdev *vdev,
return partner_bss;
}
#endif
#if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
#ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
static struct wlan_objmgr_vdev *osif_get_partner_vdev(struct wlan_objmgr_vdev *vdev,
struct mlo_link_info rsp_partner_info)
{
return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id);
}
#endif
static
void osif_populate_connect_response_for_link(struct wlan_objmgr_vdev *vdev,
struct cfg80211_connect_resp_params *conn_rsp_params,
uint8_t link_id,
struct cfg80211_bss *bss)
{
osif_debug("Link_id :%d", link_id);
conn_rsp_params->valid_links |= BIT(link_id);
conn_rsp_params->links[link_id].bssid = bss->bssid;
conn_rsp_params->links[link_id].bss = bss;
conn_rsp_params->links[link_id].addr =
wlan_vdev_mlme_get_macaddr(vdev);
}
static QDF_STATUS
osif_fill_peer_mld_mac_connect_resp(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_connect_resp_params *conn_rsp_params)
{
struct wlan_objmgr_peer *peer_obj;
peer_obj = wlan_objmgr_get_peer_by_mac(wlan_vdev_get_psoc(vdev),
rsp->bssid.bytes, WLAN_OSIF_ID);
if (!peer_obj)
return QDF_STATUS_E_INVAL;
conn_rsp_params->ap_mld_addr = wlan_peer_mlme_get_mldaddr(peer_obj);
wlan_objmgr_peer_release_ref(peer_obj, WLAN_OSIF_ID);
return QDF_STATUS_SUCCESS;
}
static void
osif_populate_partner_links_mlo_params(struct wlan_objmgr_pdev *pdev,

View File

@@ -80,7 +80,126 @@ void osif_copy_roamed_info(struct cfg80211_roam_info *info,
info->bss = bss;
}
#endif
static void osif_roamed_ind(struct net_device *dev, struct cfg80211_bss *bss,
#if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
static
void osif_populate_mlo_info_for_link(struct wlan_objmgr_vdev *vdev,
struct cfg80211_roam_info *roam_info_params,
uint8_t link_id,
struct cfg80211_bss *bss)
{
osif_debug("Link_id :%d", link_id);
roam_info_params->valid_links |= BIT(link_id);
roam_info_params->links[link_id].bssid = bss->bssid;
roam_info_params->links[link_id].bss = bss;
roam_info_params->links[link_id].addr =
wlan_vdev_mlme_get_macaddr(vdev);
}
static void
osif_populate_partner_links_roam_mlo_params(struct wlan_objmgr_pdev *pdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_roam_info *roam_info_params)
{
struct wlan_objmgr_vdev *partner_vdev;
struct mlo_link_info *rsp_partner_info;
struct mlo_partner_info assoc_partner_info = {0};
struct cfg80211_bss *bss = NULL;
QDF_STATUS qdf_status;
uint8_t link_id = 0, num_links;
int i;
qdf_status = osif_get_partner_info_from_mlie(rsp, &assoc_partner_info);
if (QDF_IS_STATUS_ERROR(qdf_status))
return;
num_links = rsp->ml_parnter_info.num_partner_links;
for (i = 0 ; i < num_links; i++) {
rsp_partner_info = &rsp->ml_parnter_info.partner_link_info[i];
qdf_status = osif_get_link_id_from_assoc_ml_ie(rsp_partner_info,
&assoc_partner_info,
&link_id);
if (QDF_IS_STATUS_ERROR(qdf_status))
continue;
partner_vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev,
rsp_partner_info->vdev_id,
WLAN_MLO_MGR_ID);
if (!partner_vdev)
continue;
bss = osif_get_chan_bss_from_kernel(partner_vdev,
rsp_partner_info, rsp);
if (!bss) {
wlan_objmgr_vdev_release_ref(partner_vdev,
WLAN_MLO_MGR_ID);
continue;
}
osif_populate_mlo_info_for_link(partner_vdev,
roam_info_params,
link_id, bss);
wlan_objmgr_vdev_release_ref(partner_vdev, WLAN_MLO_MGR_ID);
}
}
static QDF_STATUS
osif_fill_peer_mld_mac_roam_info(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_roam_info *roam_info_params)
{
struct wlan_objmgr_peer *peer_obj;
peer_obj = wlan_objmgr_get_peer_by_mac(wlan_vdev_get_psoc(vdev),
rsp->bssid.bytes, WLAN_OSIF_ID);
if (!peer_obj)
return QDF_STATUS_E_INVAL;
roam_info_params->ap_mld_addr = wlan_peer_mlme_get_mldaddr(peer_obj);
wlan_objmgr_peer_release_ref(peer_obj, WLAN_OSIF_ID);
return QDF_STATUS_SUCCESS;
}
static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_bss *bss,
struct cfg80211_roam_info *info)
{
QDF_STATUS qdf_status;
uint8_t assoc_link_id;
if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
return;
qdf_status = osif_fill_peer_mld_mac_roam_info(vdev, rsp,
info);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
osif_err("Unable to fill peer mld address: %d", qdf_status);
return;
}
assoc_link_id = wlan_vdev_get_link_id(vdev);
osif_populate_mlo_info_for_link(vdev, info,
assoc_link_id, bss);
osif_populate_partner_links_roam_mlo_params(wlan_vdev_get_pdev(vdev),
rsp,
info);
}
#else
static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_bss *bss,
struct cfg80211_roam_info *info)
{}
#endif
static void osif_roamed_ind(struct net_device *dev,
struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_bss *bss,
const uint8_t *req_ie,
size_t req_ie_len, const uint8_t *resp_ie,
size_t resp_ie_len)
@@ -92,14 +211,18 @@ static void osif_roamed_ind(struct net_device *dev, struct cfg80211_bss *bss,
info.req_ie_len = req_ie_len;
info.resp_ie = resp_ie;
info.resp_ie_len = resp_ie_len;
osif_fill_mlo_roam_params(vdev, rsp, bss, &info);
cfg80211_roamed(dev, &info, qdf_mem_malloc_flags());
}
#else
static inline void osif_roamed_ind(struct net_device *dev,
struct cfg80211_bss *bss,
const uint8_t *req_ie, size_t req_ie_len,
const uint8_t *resp_ie,
size_t resp_ie_len)
struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp,
struct cfg80211_bss *bss,
const uint8_t *req_ie,
size_t req_ie_len, const uint8_t *resp_ie,
size_t resp_ie_len)
{
cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
qdf_mem_malloc_flags());
@@ -190,6 +313,124 @@ static enum qca_roam_reason osif_get_roam_reason(uint16_t roam_scan_trigger)
return QCA_ROAM_REASON_UNKNOWN;
}
#ifdef WLAN_FEATURE_11BE_MLO
static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_peer *peer;
peer = wlan_vdev_get_bsspeer(vdev);
if (peer)
if (wlan_vdev_mlme_is_mlo_vdev(vdev))
return wlan_peer_mlme_get_mldaddr(peer);
else
return wlan_peer_get_macaddr(peer);
else
return NULL;
}
/**
* osif_send_roam_auth_mlo_links_event() - API to send roam auth mlo
* links event response to kernel
* @skb : sk buffer pointer
* @vdev: vdev pointer
* @rsp: Connection manager response
*
* This is called when wlan driver needs to send the mlo links roaming
* information after roaming.
*
* Context: Any context.
* Return: int
*/
static int
osif_send_roam_auth_mlo_links_event(struct sk_buff *skb,
struct wlan_objmgr_vdev *vdev,
struct vdev_osif_priv *osif_priv,
struct wlan_cm_connect_resp *rsp)
{
struct wlan_objmgr_psoc *psoc;
bool roam_offload_enable;
uint8_t i;
struct nlattr *mlo_links;
struct nlattr *mlo_links_info;
struct wlan_objmgr_vdev *link_vdev;
uint8_t link_vdev_id;
if (!vdev)
return -EINVAL;
psoc = wlan_vdev_get_psoc(vdev);
ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable);
if (!roam_offload_enable)
return -EINVAL;
mlo_links = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MLO_LINKS);
for (i = 0; i < rsp->ml_parnter_info.num_partner_links; i++) {
mlo_links_info = nla_nest_start(skb, i);
if (!mlo_links_info) {
osif_err("nla nest start fail");
return -EINVAL;
}
if (nla_put_u8(skb,
QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID,
rsp->ml_parnter_info.partner_link_info[i].link_id)) {
osif_err("nla put fail");
return -EINVAL;
}
if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID,
ETH_ALEN,
(void *)&rsp->ml_parnter_info.partner_link_info[i].link_addr)) {
osif_err("nla put fail");
return -EINVAL;
}
link_vdev_id = rsp->ml_parnter_info.partner_link_info[i].vdev_id;
link_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
link_vdev_id,
WLAN_OSIF_CM_ID);
if (!link_vdev) {
osif_err("link vdev is null");
return -EINVAL;
}
if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR,
ETH_ALEN, wlan_vdev_mlme_get_macaddr(link_vdev))) {
osif_err("nla put fail");
return -EINVAL;
}
nla_nest_end(skb, mlo_links_info);
}
nla_nest_end(skb, mlo_links);
return 0;
}
#else
static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_peer *peer;
peer = wlan_vdev_get_bsspeer(vdev);
if (peer)
return wlan_peer_get_macaddr(peer);
else
return NULL;
}
static inline int
osif_send_roam_auth_mlo_links_event(struct sk_buff *skb,
struct wlan_objmgr_vdev *vdev,
struct vdev_osif_priv *osif_priv,
struct wlan_cm_connect_resp *rsp)
{
return 0;
}
#endif
/**
* osif_send_roam_auth_event() - API to send roam auth event response to kernel
* @vdev: vdev pointer
@@ -229,6 +470,8 @@ static int osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev,
int status;
int32_t akm;
bool roam_offload_enable;
uint8_t *bss_mac_addr;
uint8_t num_of_links = 0;
psoc = wlan_vdev_get_psoc(vdev);
ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable);
@@ -248,24 +491,46 @@ static int osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev,
fils_params_len = roaming_info->pmk_len + PMKID_LEN +
sizeof(uint16_t) + (3 * NLMSG_HDRLEN);
skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
osif_priv->wdev,
ETH_ALEN + req_ie_len +
resp_ie_len +
sizeof(uint8_t) + REPLAY_CTR_LEN +
KCK_KEY_LEN + roaming_info->kek_len +
sizeof(uint16_t) + sizeof(uint8_t) +
(9 * NLMSG_HDRLEN) + fils_params_len,
QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
qdf_mem_malloc_flags());
if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
#ifdef WLAN_FEATURE_11BE_MLO
num_of_links = rsp->ml_parnter_info.num_partner_links;
#endif
skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
osif_priv->wdev,
(ETH_ALEN * num_of_links) +
(sizeof(uint8_t) * num_of_links) +
(ETH_ALEN * num_of_links) +
req_ie_len + resp_ie_len +
sizeof(uint8_t) + REPLAY_CTR_LEN +
KCK_KEY_LEN + roaming_info->kek_len +
sizeof(uint16_t) + sizeof(uint8_t) +
(9 * NLMSG_HDRLEN) + fils_params_len,
QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
qdf_mem_malloc_flags());
} else {
skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
osif_priv->wdev,
ETH_ALEN + req_ie_len +
resp_ie_len +
sizeof(uint8_t) + REPLAY_CTR_LEN +
KCK_KEY_LEN + roaming_info->kek_len +
sizeof(uint16_t) + sizeof(uint8_t) +
(9 * NLMSG_HDRLEN) + fils_params_len,
QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
qdf_mem_malloc_flags());
}
if (!skb) {
osif_err("cfg80211_vendor_event_alloc failed");
return -1;
}
bss_mac_addr = osif_get_bss_mac_addr(vdev);
if (!bss_mac_addr) {
osif_err("Invalid bss mac addr");
goto nla_put_failure;
}
if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
ETH_ALEN, rsp->bssid.bytes) ||
ETH_ALEN, bss_mac_addr) ||
nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
req_ie_len, req_ie) ||
nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
@@ -358,6 +623,15 @@ static int osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev,
}
}
if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
status = osif_send_roam_auth_mlo_links_event(skb, vdev,
osif_priv,
rsp);
if (status) {
osif_err("Send mlo link fail");
goto nla_put_failure;
}
}
cfg80211_vendor_event(skb, qdf_mem_malloc_flags());
return 0;
@@ -396,7 +670,6 @@ void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp)
{
struct net_device *dev = osif_priv->wdev->netdev;
struct wlan_objmgr_vdev *assoc_vdev;
size_t req_len = 0;
const uint8_t *req_ie = NULL;
size_t rsp_len = 0;
@@ -405,6 +678,10 @@ void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
struct ieee80211_channel *chan;
struct wlan_objmgr_psoc *psoc;
if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
wlan_vdev_mlme_is_mlo_link_vdev(vdev))
return;
if (QDF_IS_STATUS_ERROR(rsp->connect_status))
return;
@@ -412,22 +689,6 @@ void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
if (!psoc)
return;
if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
if (!assoc_vdev) {
osif_err("Assoc vdev is NULL");
return;
}
osif_priv = wlan_vdev_get_ospriv(assoc_vdev);
if (!osif_priv) {
osif_err("osif_priv is null");
return;
}
dev = osif_priv->wdev->netdev;
}
chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
rsp->freq);
bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
@@ -443,7 +704,7 @@ void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
&req_len, &req_ie);
osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
&rsp_len, &rsp_ie);
osif_roamed_ind(dev, bss, req_ie, req_len, rsp_ie, rsp_len);
osif_roamed_ind(dev, vdev, rsp, bss, req_ie, req_len, rsp_ie, rsp_len);
osif_send_roam_auth_event(vdev, osif_priv, rsp, req_ie, req_len, rsp_ie,
rsp_len);

View File

@@ -156,4 +156,52 @@ osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
bool locally_generated, const u8 *ie,
size_t ie_len, gfp_t gfp);
#ifdef WLAN_FEATURE_11BE_MLO
/**
* osif_get_partner_info_from_mlie() - API to get partner information
* from basic variant mlo ie
* @rsp: Connection manager connect response for the candidate
* @partner_info: mlo partner info pointer
*
* The API is is used get partner information from basic variant ml ie.
*
* Context: Any context.
* Return: QDF_STATUS
*/
QDF_STATUS
osif_get_partner_info_from_mlie(struct wlan_cm_connect_resp *connect_rsp,
struct mlo_partner_info *partner_info);
/**
* osif_get_link_id_from_assoc_ml_ie() - API to get link id from assoc rsp
* ml ie.
* @rsp_link_info: pointer to mlo link info
* @partner_info: mlo partner info pointer
* @link_id: Link id information
*
* The API is used to get link id from assoc response basic variant mlo ie
*
* Context: Any context.
* Return: QDF_STATUS
*/
QDF_STATUS
osif_get_link_id_from_assoc_ml_ie(struct mlo_link_info *rsp_link_info,
struct mlo_partner_info *assoc_partner_info,
uint8_t *link_id);
/**
* osif_get_chan_bss_from_kernel() - API to get chan bss from kernel
* @vdev: vdev pointer
* @rsp_link_info: pointer to mlo link info
* @rsp: Connection manager connect response for the candidate
*
* The API is used to get chan bss from kernel.
*
* Context: Any context.
* Return: QDF_STATUS
*/
struct cfg80211_bss *
osif_get_chan_bss_from_kernel(struct wlan_objmgr_vdev *vdev,
struct mlo_link_info *rsp_link_info,
struct wlan_cm_connect_resp *rsp);
#endif
#endif /* __OSIF_CM_RSP_H */