qcacmn: Update the current bss for non-assoc link
wdev->current_bss is not updated for a non-assoc link STA vdevs. As a result, a WARN_ON error is seen in cfg80211_ch_switch_notify() when it’s called for non-assoc link. To resolve this, update the wdev->current_bss for non-assoc links as part of connection and clean up this as part of disconnection. Change-Id: I5020200fb927dd72d2e1bf0ed73e7a5750897619 CRs-Fixed: 3618438
This commit is contained in:

committed by
Rahul Choudhary

parent
ab8c55ec38
commit
8713c007bd
@@ -878,6 +878,121 @@ static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
|
|||||||
|
|
||||||
}
|
}
|
||||||
#else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
|
#else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE == KERNEL_VERSION(5, 4, 0))
|
||||||
|
/**
|
||||||
|
* osif_update_current_bss() - Wrapper API to call cfg80211_update_current_bss
|
||||||
|
* @dev: network device
|
||||||
|
* @bss: bss info
|
||||||
|
* @rsp: Connection manager connect response
|
||||||
|
* @vdev: pointer to vdev
|
||||||
|
*
|
||||||
|
* This API is used as wrapper to update the current bss param of non-assoc link
|
||||||
|
* sta vdev.
|
||||||
|
*
|
||||||
|
* Context: Any context.
|
||||||
|
* Return: QDF_STATUS.
|
||||||
|
*/
|
||||||
|
static QDF_STATUS osif_update_current_bss(struct net_device *dev,
|
||||||
|
struct cfg80211_bss *bss,
|
||||||
|
struct wlan_cm_connect_resp *rsp,
|
||||||
|
struct wlan_objmgr_vdev *vdev)
|
||||||
|
{
|
||||||
|
struct cfg80211_connect_resp_params conn_rsp_params;
|
||||||
|
enum ieee80211_statuscode status;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
osif_enter_dev(dev);
|
||||||
|
|
||||||
|
qdf_mem_zero(&conn_rsp_params, sizeof(conn_rsp_params));
|
||||||
|
|
||||||
|
status = osif_get_connect_status_code(rsp);
|
||||||
|
conn_rsp_params.status = status;
|
||||||
|
osif_copy_connected_info(&conn_rsp_params, rsp, bss, vdev);
|
||||||
|
|
||||||
|
osif_debug("Connect resp status %d", conn_rsp_params.status);
|
||||||
|
ret = cfg80211_update_current_bss(dev, &conn_rsp_params, rsp->ssid.ssid,
|
||||||
|
rsp->ssid.length);
|
||||||
|
if (ret)
|
||||||
|
osif_err("cfg80211_update_current_bss failed for psoc:%d pdev:%d vdev:%d",
|
||||||
|
wlan_vdev_get_psoc_id(vdev),
|
||||||
|
wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)),
|
||||||
|
wlan_vdev_get_id(vdev));
|
||||||
|
|
||||||
|
return qdf_status_from_os_return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* osif_update_current_bss_for_non_assoc_link_vdevs() - API to update the
|
||||||
|
* current_bss param of non-assoc link STA vdev.
|
||||||
|
* @vdev: Pointer to vdev
|
||||||
|
* @arg: Connection manager connect response
|
||||||
|
*
|
||||||
|
* Return: None.
|
||||||
|
*/
|
||||||
|
static void osif_update_current_bss_for_non_assoc_link_vdevs(
|
||||||
|
struct wlan_objmgr_vdev *vdev, void *arg)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_vdev *assoc_vdev;
|
||||||
|
struct wlan_cm_connect_resp resp = {0};
|
||||||
|
struct qdf_mac_addr macaddr = {0};
|
||||||
|
struct vdev_osif_priv *osif_priv = NULL;
|
||||||
|
struct wlan_cm_connect_resp *assoc_link_rsp;
|
||||||
|
|
||||||
|
assoc_link_rsp = (struct wlan_cm_connect_resp *)arg;
|
||||||
|
if (!assoc_link_rsp) {
|
||||||
|
osif_err("assoc_link_rsp is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev);
|
||||||
|
|
||||||
|
/* For assoc vdev cfg80211_connect_done() is called to update the
|
||||||
|
* current bss param. Hence, skip the assoc vdev here.
|
||||||
|
*/
|
||||||
|
if (vdev == assoc_vdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wlan_vdev_mlme_get_ssid(vdev, resp.ssid.ssid, &resp.ssid.length);
|
||||||
|
|
||||||
|
wlan_vdev_get_bss_peer_mac(vdev, &macaddr);
|
||||||
|
qdf_mem_copy(resp.bssid.bytes, macaddr.bytes, QDF_MAC_ADDR_SIZE);
|
||||||
|
|
||||||
|
resp.connect_status = assoc_link_rsp->connect_status;
|
||||||
|
|
||||||
|
osif_debug("vdev:%p bssid:" QDF_MAC_ADDR_FMT " ssid.length:%d ssid: " QDF_SSID_FMT,
|
||||||
|
vdev, QDF_MAC_ADDR_REF(macaddr.bytes), resp.ssid.length,
|
||||||
|
QDF_SSID_REF(resp.ssid.length, resp.ssid.ssid));
|
||||||
|
|
||||||
|
osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||||
|
osif_update_current_bss(osif_priv->wdev->netdev, NULL, &resp, vdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* osif_update_current_bss_for_non_assoc_links() - API to update the
|
||||||
|
* current_bss param of non-assoc link STA vdev.
|
||||||
|
* @assoc_vdev: Pointer to assoc vdev
|
||||||
|
* @rsp: Connection manager connect response
|
||||||
|
*
|
||||||
|
* Return: None.
|
||||||
|
*/
|
||||||
|
static void osif_update_current_bss_for_non_assoc_links(
|
||||||
|
struct wlan_objmgr_vdev *assoc_vdev,
|
||||||
|
struct wlan_cm_connect_resp *rsp)
|
||||||
|
{
|
||||||
|
mlo_iterate_connected_vdev_list(
|
||||||
|
assoc_vdev,
|
||||||
|
osif_update_current_bss_for_non_assoc_link_vdevs,
|
||||||
|
rsp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void osif_update_current_bss_for_non_assoc_links(
|
||||||
|
struct wlan_objmgr_vdev *assoc_vdev,
|
||||||
|
struct wlan_cm_connect_resp *rsp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
|
static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
|
||||||
struct vdev_osif_priv *osif_priv,
|
struct vdev_osif_priv *osif_priv,
|
||||||
struct wlan_cm_connect_resp *rsp)
|
struct wlan_cm_connect_resp *rsp)
|
||||||
@@ -915,7 +1030,7 @@ static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
|
|||||||
return;
|
return;
|
||||||
qdf_mem_copy(&resp, rsp, sizeof(struct wlan_cm_connect_resp));
|
qdf_mem_copy(&resp, rsp, sizeof(struct wlan_cm_connect_resp));
|
||||||
tmp_osif_priv = wlan_vdev_get_ospriv(assoc_vdev);
|
tmp_osif_priv = wlan_vdev_get_ospriv(assoc_vdev);
|
||||||
freq = vdev->vdev_mlme.bss_chan->ch_freq;
|
freq = assoc_vdev->vdev_mlme.bss_chan->ch_freq;
|
||||||
qdf_mem_copy(macaddr.bytes, rsp->bssid.bytes,
|
qdf_mem_copy(macaddr.bytes, rsp->bssid.bytes,
|
||||||
QDF_MAC_ADDR_SIZE);
|
QDF_MAC_ADDR_SIZE);
|
||||||
if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
|
if (QDF_IS_STATUS_SUCCESS(rsp->connect_status)) {
|
||||||
@@ -938,6 +1053,10 @@ static void osif_indcate_connect_results(struct wlan_objmgr_vdev *vdev,
|
|||||||
if (osif_update_connect_results(tmp_osif_priv->wdev->netdev, bss,
|
if (osif_update_connect_results(tmp_osif_priv->wdev->netdev, bss,
|
||||||
&resp, assoc_vdev))
|
&resp, assoc_vdev))
|
||||||
osif_connect_bss(tmp_osif_priv->wdev->netdev, bss, &resp);
|
osif_connect_bss(tmp_osif_priv->wdev->netdev, bss, &resp);
|
||||||
|
|
||||||
|
if (QDF_IS_STATUS_SUCCESS(rsp->connect_status))
|
||||||
|
osif_update_current_bss_for_non_assoc_links(assoc_vdev,
|
||||||
|
rsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
|
#endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
|
||||||
|
@@ -146,6 +146,58 @@ osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
|
#else /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* osif_cm_get_anchor_vdev() - API to get the anchor vdev
|
||||||
|
* @vdev: Pointer to vdev
|
||||||
|
*
|
||||||
|
* Return: If the assoc vdev is available, return it. Otherwise, if the MLD is
|
||||||
|
* disconnected, return the current vdev. If neither is available, return NULL.
|
||||||
|
*/
|
||||||
|
static struct wlan_objmgr_vdev *osif_cm_get_anchor_vdev(
|
||||||
|
struct wlan_objmgr_vdev *vdev)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_vdev *assoc_vdev = NULL;
|
||||||
|
|
||||||
|
assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
|
||||||
|
if (assoc_vdev)
|
||||||
|
return assoc_vdev;
|
||||||
|
else if (ucfg_mlo_is_mld_disconnected(vdev))
|
||||||
|
return vdev;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE == KERNEL_VERSION(5, 4, 0))
|
||||||
|
/**
|
||||||
|
* osif_cm_indicate_disconnect_for_non_assoc_link() - Wrapper API to clear
|
||||||
|
* current bss param of non-assoc link
|
||||||
|
* @netdev: Pointer to netdev of non-assoc link vdev
|
||||||
|
* @vdev: Pointer to non-assoc link vdev
|
||||||
|
*
|
||||||
|
* Return: None
|
||||||
|
*/
|
||||||
|
static void osif_cm_indicate_disconnect_for_non_assoc_link(
|
||||||
|
struct net_device *netdev,
|
||||||
|
struct wlan_objmgr_vdev *vdev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = cfg80211_clear_current_bss(netdev);
|
||||||
|
if (ret)
|
||||||
|
osif_err("cfg80211_clear_current_bss failed for psoc:%d pdev:%d vdev:%d",
|
||||||
|
wlan_vdev_get_psoc_id(vdev),
|
||||||
|
wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)),
|
||||||
|
wlan_vdev_get_id(vdev));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void osif_cm_indicate_disconnect_for_non_assoc_link(
|
||||||
|
struct net_device *netdev,
|
||||||
|
struct wlan_objmgr_vdev *vdev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
|
osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
@@ -155,7 +207,7 @@ osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
|
|||||||
{
|
{
|
||||||
struct net_device *netdev = dev;
|
struct net_device *netdev = dev;
|
||||||
struct vdev_osif_priv *osif_priv = NULL;
|
struct vdev_osif_priv *osif_priv = NULL;
|
||||||
struct wlan_objmgr_vdev *assoc_vdev = NULL;
|
struct wlan_objmgr_vdev *anchor_vdev;
|
||||||
|
|
||||||
if (!wlan_vdev_mlme_is_mlo_vdev(vdev) || (link_id != -1)) {
|
if (!wlan_vdev_mlme_is_mlo_vdev(vdev) || (link_id != -1)) {
|
||||||
osif_cm_indicate_disconnect_result(
|
osif_cm_indicate_disconnect_result(
|
||||||
@@ -164,7 +216,12 @@ osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ucfg_mlo_is_mld_disconnected(vdev)) {
|
anchor_vdev = osif_cm_get_anchor_vdev(vdev);
|
||||||
|
|
||||||
|
if (vdev != anchor_vdev)
|
||||||
|
osif_cm_indicate_disconnect_for_non_assoc_link(netdev, vdev);
|
||||||
|
|
||||||
|
if (anchor_vdev && ucfg_mlo_is_mld_disconnected(vdev)) {
|
||||||
/**
|
/**
|
||||||
* Kernel maintains some extra state on the assoc netdev.
|
* Kernel maintains some extra state on the assoc netdev.
|
||||||
* If the assoc vdev exists, send disconnected event on the
|
* If the assoc vdev exists, send disconnected event on the
|
||||||
@@ -173,11 +230,8 @@ osif_cm_indicate_disconnect(struct wlan_objmgr_vdev *vdev,
|
|||||||
* already cleaned up the extra state while processing the
|
* already cleaned up the extra state while processing the
|
||||||
* disconnected event sent as part of the link removal.
|
* disconnected event sent as part of the link removal.
|
||||||
*/
|
*/
|
||||||
assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
|
osif_priv = wlan_vdev_get_ospriv(anchor_vdev);
|
||||||
if (assoc_vdev) {
|
netdev = osif_priv->wdev->netdev;
|
||||||
osif_priv = wlan_vdev_get_ospriv(assoc_vdev);
|
|
||||||
netdev = osif_priv->wdev->netdev;
|
|
||||||
}
|
|
||||||
|
|
||||||
osif_cm_indicate_disconnect_result(
|
osif_cm_indicate_disconnect_result(
|
||||||
netdev, reason,
|
netdev, reason,
|
||||||
|
Reference in New Issue
Block a user