qcacld-3.0: Add retries to TWT DEL dialog cmd during ps mode

If power save disable command commes, implicitly driver
teardown the existing TWT session by sending out
TWT_DEL_DIALOG command to fw. In firmware if
command fails due to firmware scan_in_progress or
chan_switch_in_progress then driver should retries
TWT_DEL_DIALOG implicitly.

In driver, add retries logic to the twt del dialog command in
case of power save disable.

CRs-Fixed: 3584286
Change-Id: I71299ea8239f33d194d2b55499f2d8e5946c42ba
This commit is contained in:
Deeksha Gupta 2023-09-04 19:53:53 +05:30 committed by Rahul Choudhary
parent 25396041b8
commit 6e303e37aa
6 changed files with 57 additions and 16 deletions

View File

@ -2286,6 +2286,7 @@ void wlan_twt_set_work_params(
struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *peer_mac,
uint8_t dialog_id,
bool is_ps_disabled,
uint32_t twt_next_action)
{
struct twt_vdev_priv_obj *twt_vdev_priv;
@ -2300,10 +2301,12 @@ void wlan_twt_set_work_params(
qdf_copy_macaddr(&twt_vdev_priv->peer_macaddr, peer_mac);
twt_vdev_priv->dialog_id = dialog_id;
twt_vdev_priv->is_ps_disabled = is_ps_disabled;
twt_vdev_priv->next_action = twt_next_action;
twt_debug("renego: twt_terminate: dialog_id:%d next_action:%d peer mac_addr "
twt_debug("TWT terminate: dialog_id:%d is_ps_disabled:%d next_action:%d peer mac_addr "
QDF_MAC_ADDR_FMT, twt_vdev_priv->dialog_id,
twt_vdev_priv->is_ps_disabled,
twt_vdev_priv->next_action,
QDF_MAC_ADDR_REF(twt_vdev_priv->peer_macaddr.bytes));
}
@ -2323,5 +2326,6 @@ void wlan_twt_get_work_params(struct wlan_objmgr_vdev *vdev,
qdf_copy_macaddr(&params->peer_macaddr, &twt_vdev_priv->peer_macaddr);
params->dialog_id = twt_vdev_priv->dialog_id;
params->is_ps_disabled = twt_vdev_priv->is_ps_disabled;
*next_action = twt_vdev_priv->next_action;
}

View File

@ -295,6 +295,7 @@ bool wlan_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
* @vdev: vdev pointer
* @peer_mac: mac address of peer
* @dialog_id: dialog_id of TWT session
* @is_ps_disabled: Whether power save is disabled or not
* @twt_next_action: Set next action to do before work scheduled
*
* Return: None
@ -303,6 +304,7 @@ void wlan_twt_set_work_params(
struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *peer_mac,
uint8_t dialog_id,
bool is_ps_disabled,
uint32_t twt_next_action);
/**

View File

@ -283,6 +283,7 @@ bool ucfg_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc,
* @vdev: Vdev pointer
* @peer_mac: peer mac address
* @dialog_id: dialog_id
* @is_ps_disabled: Whether Power saave is disabled or not
* @twt_next_action: Set TWT next action to do before work schedule
*
* Return: None
@ -291,6 +292,7 @@ void ucfg_twt_set_work_params(
struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *peer_mac,
uint8_t dialog_id,
bool is_ps_disabled,
uint32_t twt_next_action);
/**
@ -415,6 +417,7 @@ ucfg_twt_set_work_params(
struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *peer_mac,
uint8_t dialog_id,
bool is_ps_disabled,
uint32_t twt_next_action)
{
}

View File

@ -228,10 +228,11 @@ void ucfg_twt_set_work_params(
struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *peer_mac,
uint8_t dialog_id,
bool is_ps_disabled,
uint32_t twt_next_action)
{
return wlan_twt_set_work_params(vdev, peer_mac, dialog_id,
twt_next_action);
is_ps_disabled, twt_next_action);
}
void ucfg_twt_get_work_params(

View File

@ -2225,12 +2225,10 @@ int wlan_hdd_set_powersave(struct wlan_hdd_link_info *link_info,
hdd_ctx->mac_handle, link_info->vdev_id,
allow_power_save, timeout,
sta_ctx->ap_supports_immediate_power_save);
if (!allow_power_save) {
if (adapter->device_mode == QDF_STA_MODE)
hdd_twt_del_dialog_in_ps_disable(hdd_ctx,
&sta_ctx->conn_info.bssid,
link_info->vdev_id);
}
if (!allow_power_save && adapter->device_mode == QDF_STA_MODE)
hdd_twt_del_dialog_in_ps_disable(hdd_ctx,
&sta_ctx->conn_info.bssid,
link_info->vdev_id);
return qdf_status_to_os_return(status);
}

View File

@ -45,6 +45,7 @@
#define TWT_SETUP_WAKE_DURATION_MAX 0xFFFF
#define TWT_SETUP_WAKE_INTVL_EXP_MAX 31
#define TWT_MAX_NEXT_TWT_SIZE 3
#define TWT_DEL_DIALOG_REQ_MAX_RETRY 10
static const struct nla_policy
qca_wlan_vendor_twt_add_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = {
@ -462,12 +463,13 @@ osif_twt_ack_wait_response(struct wlan_objmgr_psoc *psoc,
static void
osif_send_twt_delete_cmd(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *peer_mac, uint8_t dialog_id)
struct qdf_mac_addr *peer_mac, uint8_t dialog_id,
bool is_ps_disabled)
{
uint32_t twt_next_action = HOST_TWT_SEND_DELETE_CMD;
ucfg_twt_set_work_params(vdev, peer_mac,
dialog_id, twt_next_action);
ucfg_twt_set_work_params(vdev, peer_mac, dialog_id, is_ps_disabled,
twt_next_action);
qdf_sched_work(0, &vdev->twt_work);
}
@ -531,7 +533,7 @@ osif_send_twt_setup_req(struct wlan_objmgr_vdev *vdev,
osif_debug("setup_done set, renego failure");
osif_send_twt_delete_cmd(vdev,
&twt_params->peer_macaddr,
twt_params->dialog_id);
twt_params->dialog_id, false);
} else {
ucfg_twt_init_context(psoc, &twt_params->peer_macaddr,
twt_params->dialog_id);
@ -959,9 +961,12 @@ void osif_twt_teardown_in_ps_disable(struct wlan_objmgr_psoc *psoc,
osif_debug("vdev%d: Terminate existing TWT session %d due to ps disable",
params.vdev_id, params.dialog_id);
ret = osif_send_sta_twt_teardown_req(vdev, psoc, &params);
if (ret)
if (ret) {
osif_debug("TWT teardown is failed on vdev: %d",
vdev_id);
osif_send_twt_delete_cmd(vdev, mac_addr,
params.dialog_id, true);
}
}
wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
}
@ -1126,7 +1131,7 @@ osif_twt_handle_renego_failure(struct wlan_objmgr_psoc *psoc,
}
osif_send_twt_delete_cmd(vdev, &event->params.peer_macaddr,
event->params.dialog_id);
event->params.dialog_id, false);
wlan_objmgr_vdev_release_ref(vdev, WLAN_TWT_ID);
@ -2407,6 +2412,25 @@ int osif_twt_set_param(struct wlan_objmgr_vdev *vdev,
return ret;
}
static void osif_twt_teardown_req_retry(struct wlan_objmgr_vdev *vdev,
struct wlan_objmgr_psoc *psoc,
struct twt_del_dialog_param params)
{
int retries = 1;
int ret;
while (retries < TWT_DEL_DIALOG_REQ_MAX_RETRY) {
osif_debug("Implicitly TWT teardown req retry count:%d", retries);
ret = osif_send_sta_twt_teardown_req(vdev, psoc, &params);
if (ret != -EBUSY)
break;
retries++;
}
if (retries >= TWT_DEL_DIALOG_REQ_MAX_RETRY)
osif_debug("TWT Del Dialog req max retries reached");
}
void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
{
struct twt_del_dialog_param params = {0};
@ -2414,6 +2438,7 @@ void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
struct wlan_objmgr_psoc *psoc;
uint8_t vdev_id;
uint32_t next_action;
int ret;
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc) {
@ -2425,7 +2450,7 @@ void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
ucfg_twt_get_work_params(vdev, &twt_work_params, &next_action);
if (next_action != HOST_TWT_SEND_DELETE_CMD) {
osif_debug("Do not send STA teardown req as TWT renegotiation work is not scheduled");
osif_debug("Do not send STA teardown req as TWT renegotiation or power save work is not scheduled");
return;
}
@ -2433,7 +2458,15 @@ void __osif_twt_work_handler(struct wlan_objmgr_vdev *vdev)
params.dialog_id = twt_work_params.dialog_id;
params.vdev_id = vdev_id;
osif_send_sta_twt_teardown_req(vdev, psoc, &params);
ret = osif_send_sta_twt_teardown_req(vdev, psoc, &params);
/*
* In case of FW returns ack_event with status as scan_in_progress or
* Channel switch in progress and TWT teardown happens due to power
* save disable then host will retry the TWT teardown cmd.
*/
if (ret == -EBUSY && twt_work_params.is_ps_disabled)
osif_twt_teardown_req_retry(vdev, psoc, params);
}
void osif_twt_work_handler(void *data)