qcacld-3.0: cleanup IPA STA iface, if STA disconnect failed

If STA disconnect failed for any reason, cleanup IPA STA iface
if not already done.

Change-Id: I27ff33324bc4724e8470af9a0c434fa03e8aa5c3
CRs-Fixed: 2505563
This commit is contained in:
Vevek Venkatesan 2019-08-12 22:25:15 +05:30 • committed by nshrivas
commit e81bca8057
7 changed files with 97 additions and 4 deletions

View file

@ -637,6 +637,19 @@ int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
*/
bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx);
/**
* wlan_ipa_uc_cleanup_sta - disconnect and cleanup sta iface
* @ipa_ctx: IPA context
* @net_dev: Interface net device
*
* Send disconnect sta event to IPA driver and cleanup IPA iface
* if not yet done
*
* Return: void
*/
void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx,
qdf_netdev_t net_dev);
/**
* wlan_ipa_uc_disconnect_ap() - send ap disconnect event
* @ipa_ctx: IPA context

View file

@ -377,6 +377,19 @@ int ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
*/
bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
/**
* ipa_uc_cleanup_sta() - disconnect and cleanup sta iface
* @pdev: pdev obj
* @net_dev: Interface net device
*
* Send disconnect sta event to IPA driver and cleanup IPA iface,
* if not yet done
*
* Return: void
*/
void ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev);
/**
* ipa_uc_disconnect_ap() - send ap disconnect event
* @pdev: pdev obj

View file

@ -3343,6 +3343,27 @@ static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev,
return QDF_STATUS_SUCCESS;
}
void wlan_ipa_uc_cleanup_sta(struct wlan_ipa_priv *ipa_ctx,
qdf_netdev_t net_dev)
{
struct wlan_ipa_iface_context *iface_ctx;
int i;
ipa_debug("enter");
for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) {
iface_ctx = &ipa_ctx->iface_context[i];
if (iface_ctx && iface_ctx->device_mode == QDF_STA_MODE &&
iface_ctx->dev == net_dev && iface_ctx->tl_context) {
wlan_ipa_uc_send_evt(net_dev, QDF_IPA_STA_DISCONNECT,
net_dev->dev_addr);
wlan_ipa_cleanup_iface(iface_ctx);
}
}
ipa_debug("exit");
}
QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx,
qdf_netdev_t net_dev)
{

View file

@ -541,6 +541,20 @@ bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
return wlan_ipa_is_fw_wdi_activated(ipa_obj);
}
void ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev)
{
struct wlan_ipa_priv *ipa_obj;
ipa_obj = ipa_pdev_get_priv_obj(pdev);
if (!ipa_obj) {
ipa_err("IPA object is NULL");
return;
}
return wlan_ipa_uc_cleanup_sta(ipa_obj, net_dev);
}
QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev)
{

View file

@ -285,6 +285,19 @@ int ucfg_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr);
*/
bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev);
/**
* ucfg_ipa_uc_cleanup_sta() - disconnect and cleanup sta iface
* @pdev: pdev obj
* @net_dev: Interface net device
*
* Send disconnect sta event to IPA driver and cleanup IPA iface,
* if not yet done
*
* Return: void
*/
void ucfg_ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev);
/**
* ucfg_ipa_uc_disconnect_ap() - send ap disconnect event
* @pdev: pdev obj
@ -507,6 +520,12 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
return false;
}
static inline
void ucfg_ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev)
{
}
static inline
QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev)

View file

@ -174,6 +174,12 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev)
return ipa_is_fw_wdi_activated(pdev);
}
void ucfg_ipa_uc_cleanup_sta(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev)
{
return ipa_uc_cleanup_sta(pdev, net_dev);
}
QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev,
qdf_netdev_t net_dev)
{

View file

@ -5857,14 +5857,21 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
mac_handle,
adapter->vdev_id,
eCSR_DISCONNECT_REASON_IBSS_LEAVE);
else if (adapter->device_mode == QDF_STA_MODE)
wlan_hdd_disconnect(adapter,
eCSR_DISCONNECT_REASON_DEAUTH);
else
else if (adapter->device_mode == QDF_STA_MODE) {
rc = wlan_hdd_disconnect(
adapter,
eCSR_DISCONNECT_REASON_DEAUTH);
if (rc != 0 && ucfg_ipa_is_enabled()) {
hdd_err("STA disconnect failed");
ucfg_ipa_uc_cleanup_sta(hdd_ctx->pdev,
adapter->dev);
}
} else {
status = sme_roam_disconnect(
mac_handle,
adapter->vdev_id,
eCSR_DISCONNECT_REASON_UNSPECIFIED);
}
/* success implies disconnect is queued */
if (QDF_IS_STATUS_SUCCESS(status) &&
adapter->device_mode != QDF_STA_MODE) {