qcacmn: Use VDEV response timer in PSOC for MAC update

Use the VDEV response timer infrastructure to hold MAC address update
requests sent to FW on VDEV which is in link switch progress.

As post disconnect and sending set MAC address request, the scheduler
thread is exited and to notify MLO mgr about set MAC address update
complete (or either timer expiry due to FW response timeout) and
further the link switch process based on response.

This code is only applicable for Link switch VDEV MAC address update
path. For MAC update request from userspace still use the same path
without starting the timer as for those wait event is already in place.

Change-Id: Ice3e6f7b00f0d9d08d6aa62ee9c1e4d183142358
CRs-Fixed: 3556517
This commit is contained in:
Vinod Kumar Pirla
2023-07-06 11:27:29 -07:00
committed by Rahul Choudhary
parent a61df6019c
commit a147f231ea
8 changed files with 159 additions and 5 deletions

View File

@@ -1597,6 +1597,8 @@ enum qdf_suspend_type {
* @QDF_FLUSH_LOGS : Recovery needed when sending flush completion to userspace * @QDF_FLUSH_LOGS : Recovery needed when sending flush completion to userspace
* @QDF_WMI_CMD_SENT_DURING_SUSPEND: WMI command is received when target is * @QDF_WMI_CMD_SENT_DURING_SUSPEND: WMI command is received when target is
* suspended * suspended
* @QDF_VDEV_MAC_ADDR_UPDATE_RESPONSE_TIMED_OUT: VDEV MAC address update
* request for Link switch timedout.
*/ */
enum qdf_hang_reason { enum qdf_hang_reason {
QDF_REASON_UNSPECIFIED, QDF_REASON_UNSPECIFIED,
@@ -1634,6 +1636,7 @@ enum qdf_hang_reason {
QDF_DEL_SELF_STA_FAILED, QDF_DEL_SELF_STA_FAILED,
QDF_FLUSH_LOGS, QDF_FLUSH_LOGS,
QDF_WMI_CMD_SENT_DURING_SUSPEND, QDF_WMI_CMD_SENT_DURING_SUSPEND,
QDF_VDEV_MAC_ADDR_UPDATE_RESPONSE_TIMED_OUT,
}; };
/** /**

View File

@@ -72,6 +72,47 @@ target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc,
} }
#endif #endif
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
static void
target_if_vdev_mgr_mac_addr_rsp_timeout(struct wlan_objmgr_psoc *psoc,
struct vdev_response_timer *vdev_rsp,
uint8_t vdev_id)
{
uint16_t rsp_pos;
struct wlan_objmgr_vdev *vdev;
enum qdf_hang_reason recovery_reason;
struct wlan_lmac_if_mlme_rx_ops *rx_ops;
rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
if (!rx_ops) {
mlme_err("No Rx Ops");
return;
}
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_VDEV_TARGET_IF_ID);
if (!vdev) {
mlme_err("Invalid vdev %d", vdev_id);
return;
}
rsp_pos = UPDATE_MAC_ADDR_RESPONSE_BIT;
recovery_reason = QDF_VDEV_MAC_ADDR_UPDATE_RESPONSE_TIMED_OUT;
target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);
target_if_vdev_mgr_handle_recovery(psoc, vdev_id,
recovery_reason, rsp_pos);
rx_ops->vdev_mgr_set_mac_addr_response(vdev, -EAGAIN);
wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
}
#else
static inline void
target_if_vdev_mgr_mac_addr_rsp_timeout(struct wlan_objmgr_psoc *psoc,
struct vdev_response_timer *vdev_rsp,
uint8_t vdev_id)
{
}
#endif
#ifdef DP_UMAC_HW_RESET_SUPPORT #ifdef DP_UMAC_HW_RESET_SUPPORT
/** /**
* target_if_check_and_restart_vdev_mgr_rsp_timer - Check and restart the vdev * target_if_check_and_restart_vdev_mgr_rsp_timer - Check and restart the vdev
@@ -147,6 +188,8 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg)
!qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, !qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
&vdev_rsp->rsp_status) && &vdev_rsp->rsp_status) &&
!qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT, !qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT,
&vdev_rsp->rsp_status) &&
!qdf_atomic_test_bit(UPDATE_MAC_ADDR_RESPONSE_BIT,
&vdev_rsp->rsp_status)) { &vdev_rsp->rsp_status)) {
mlme_debug("No response bit is set, ignoring actions :%d", mlme_debug("No response bit is set, ignoring actions :%d",
vdev_rsp->vdev_id); vdev_rsp->vdev_id);
@@ -238,6 +281,11 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg)
*/ */
mlme_debug("No rsp from FW received , continue with disconnect"); mlme_debug("No rsp from FW received , continue with disconnect");
target_if_send_rso_stop_failure_rsp(psoc, vdev_id); target_if_send_rso_stop_failure_rsp(psoc, vdev_id);
} else if (qdf_atomic_test_bit(UPDATE_MAC_ADDR_RESPONSE_BIT,
&vdev_rsp->rsp_status)) {
mlme_debug("VDEV %d MAC addr update resp timeout", vdev_id);
target_if_vdev_mgr_mac_addr_rsp_timeout(psoc,
vdev_rsp, vdev_id);
} else { } else {
mlme_err("PSOC_%d VDEV_%d: Unknown error", mlme_err("PSOC_%d VDEV_%d: Unknown error",
wlan_psoc_get_id(psoc), vdev_id); wlan_psoc_get_id(psoc), vdev_id);
@@ -1013,11 +1061,14 @@ static int target_if_update_macaddr_conf_evt_handler(ol_scn_t scn,
uint8_t *event_buff, uint8_t *event_buff,
uint32_t len) uint32_t len)
{ {
int8_t ret;
struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_vdev *vdev;
struct wmi_unified *wmi_handle; struct wmi_unified *wmi_handle;
uint8_t vdev_id, resp_status; uint8_t vdev_id, resp_status;
QDF_STATUS status; QDF_STATUS status;
struct wlan_lmac_if_mlme_rx_ops *rx_ops; struct wlan_lmac_if_mlme_rx_ops *rx_ops;
struct vdev_response_timer *vdev_rsp;
if (!event_buff) { if (!event_buff) {
mlme_err("Received NULL event ptr from FW"); mlme_err("Received NULL event ptr from FW");
@@ -1049,9 +1100,43 @@ static int target_if_update_macaddr_conf_evt_handler(ol_scn_t scn,
return -EINVAL; return -EINVAL;
} }
rx_ops->vdev_mgr_set_mac_addr_response(vdev_id, resp_status); vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_VDEV_TARGET_IF_ID);
if (!vdev) {
mlme_err("VDEV NULL");
return -EINVAL;
}
return 0; if (!wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
ret = 0;
goto send_rsp;
}
/* This is for LinkSwitch request case */
vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
if (!vdev_rsp) {
mlme_err("vdev response timer is null VDEV_%d PSOC_%d",
vdev_id, wlan_psoc_get_id(psoc));
ret = -EINVAL;
goto out;
}
status =
target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp,
UPDATE_MAC_ADDR_RESPONSE_BIT);
ret = qdf_status_to_os_return(status);
if (QDF_IS_STATUS_ERROR(status)) {
mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed",
wlan_psoc_get_id(psoc), vdev_id);
goto out;
}
send_rsp:
rx_ops->vdev_mgr_set_mac_addr_response(vdev, resp_status);
out:
wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
return ret;
} }
static inline void static inline void

View File

@@ -1320,8 +1320,13 @@ target_if_vdev_mgr_set_mac_address_send(struct qdf_mac_addr mac_addr,
struct qdf_mac_addr mld_addr, struct qdf_mac_addr mld_addr,
struct wlan_objmgr_vdev *vdev) struct wlan_objmgr_vdev *vdev)
{ {
QDF_STATUS status;
struct wlan_objmgr_psoc *psoc;
struct vdev_response_timer *vdev_rsp;
struct wlan_lmac_if_mlme_rx_ops *rx_ops;
struct set_mac_addr_params params = {0}; struct set_mac_addr_params params = {0};
struct wmi_unified *wmi_handle; struct wmi_unified *wmi_handle;
uint8_t vdev_id = wlan_vdev_get_id(vdev);
wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev);
if (!wmi_handle) { if (!wmi_handle) {
@@ -1329,7 +1334,40 @@ target_if_vdev_mgr_set_mac_address_send(struct qdf_mac_addr mac_addr,
return QDF_STATUS_E_INVAL; return QDF_STATUS_E_INVAL;
} }
params.vdev_id = wlan_vdev_get_id(vdev); if (!wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev))
goto send_req;
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc) {
mlme_err("PSOC NULL");
return QDF_STATUS_E_INVAL;
}
rx_ops = target_if_vdev_mgr_get_rx_ops(psoc);
if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) {
mlme_err("VDEV_%d: PSOC_%d No Rx Ops", vdev_id,
wlan_psoc_get_id(psoc));
return QDF_STATUS_E_INVAL;
}
vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id);
if (!vdev_rsp) {
mlme_err("VDEV_%d: PSOC_%d No vdev rsp timer", vdev_id,
wlan_psoc_get_id(psoc));
return QDF_STATUS_E_INVAL;
}
vdev_rsp->expire_time = WLAN_SET_MAC_ADDR_TIMEOUT;
status = target_if_vdev_mgr_rsp_timer_start(psoc, vdev_rsp,
UPDATE_MAC_ADDR_RESPONSE_BIT);
if (QDF_IS_STATUS_ERROR(status)) {
mlme_err("Start VDEV response timer failed");
return status;
}
send_req:
params.vdev_id = vdev_id;
params.mac_addr = mac_addr; params.mac_addr = mac_addr;
params.mld_addr = mld_addr; params.mld_addr = mld_addr;

View File

@@ -2681,7 +2681,8 @@ struct wlan_lmac_if_mlme_rx_ops {
struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id); uint8_t vdev_id);
#ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE
void (*vdev_mgr_set_mac_addr_response)(uint8_t vdev_id, uint8_t status); void (*vdev_mgr_set_mac_addr_response)(struct wlan_objmgr_vdev *vdev,
uint8_t status);
#endif #endif
void (*vdev_mgr_set_max_channel_switch_time) void (*vdev_mgr_set_max_channel_switch_time)
(struct wlan_objmgr_psoc *psoc, (struct wlan_objmgr_psoc *psoc,

View File

@@ -227,5 +227,16 @@ QDF_STATUS wlan_mlme_psoc_disable(struct wlan_objmgr_psoc *psoc);
QDF_STATUS wlan_vdev_mlme_send_set_mac_addr(struct qdf_mac_addr mac_addr, QDF_STATUS wlan_vdev_mlme_send_set_mac_addr(struct qdf_mac_addr mac_addr,
struct qdf_mac_addr mld_addr, struct qdf_mac_addr mld_addr,
struct wlan_objmgr_vdev *vdev); struct wlan_objmgr_vdev *vdev);
/**
* wlan_vdev_mlme_notify_set_mac_addr_response() - Notify FW set mac address
* response.
* @vdev: VDEV object manager.
* @resp_status: FW response status.
*
* Return: void
*/
void wlan_vdev_mlme_notify_set_mac_addr_response(struct wlan_objmgr_vdev *vdev,
uint8_t resp_status);
#endif #endif
#endif #endif

View File

@@ -35,6 +35,7 @@
#include <wlan_lmac_if_def.h> #include <wlan_lmac_if_def.h>
#include <target_if_vdev_mgr_tx_ops.h> #include <target_if_vdev_mgr_tx_ops.h>
#include "connection_mgr/core/src/wlan_cm_main.h" #include "connection_mgr/core/src/wlan_cm_main.h"
#include <wlan_mlo_mgr_public_api.h>
static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, static QDF_STATUS mlme_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev,
void *arg) void *arg)
@@ -327,4 +328,16 @@ QDF_STATUS wlan_vdev_mlme_send_set_mac_addr(struct qdf_mac_addr mac_addr,
{ {
return mlme_vdev_ops_send_set_mac_address(mac_addr, mld_addr, vdev); return mlme_vdev_ops_send_set_mac_address(mac_addr, mld_addr, vdev);
} }
void wlan_vdev_mlme_notify_set_mac_addr_response(struct wlan_objmgr_vdev *vdev,
uint8_t resp_status)
{
if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev)) {
wlan_mlo_mgr_link_switch_set_mac_addr_resp(vdev, resp_status);
return;
}
mlme_vdev_mgr_notify_set_mac_addr_response(wlan_vdev_get_id(vdev),
resp_status);
}
#endif #endif

View File

@@ -43,6 +43,7 @@
* @DELETE_RESPONSE_BIT: vdev delete response bit * @DELETE_RESPONSE_BIT: vdev delete response bit
* @PEER_DELETE_ALL_RESPONSE_BIT: vdev peer delete all response bit * @PEER_DELETE_ALL_RESPONSE_BIT: vdev peer delete all response bit
* @RSO_STOP_RESPONSE_BIT: RSO stop response bit * @RSO_STOP_RESPONSE_BIT: RSO stop response bit
* @UPDATE_MAC_ADDR_RESPONSE_BIT: MAC address update response bit
* @RESPONSE_BIT_MAX: Max enumeration * @RESPONSE_BIT_MAX: Max enumeration
*/ */
enum wlan_vdev_mgr_tgt_if_rsp_bit { enum wlan_vdev_mgr_tgt_if_rsp_bit {
@@ -52,6 +53,7 @@ enum wlan_vdev_mgr_tgt_if_rsp_bit {
DELETE_RESPONSE_BIT = 3, DELETE_RESPONSE_BIT = 3,
PEER_DELETE_ALL_RESPONSE_BIT = 4, PEER_DELETE_ALL_RESPONSE_BIT = 4,
RSO_STOP_RESPONSE_BIT = 5, RSO_STOP_RESPONSE_BIT = 5,
UPDATE_MAC_ADDR_RESPONSE_BIT = 6,
RESPONSE_BIT_MAX, RESPONSE_BIT_MAX,
}; };
@@ -70,6 +72,7 @@ static inline char *string_from_rsp_bit(enum wlan_vdev_mgr_tgt_if_rsp_bit bit)
"DELETE", "DELETE",
"PEER DELETE ALL", "PEER DELETE ALL",
"RSO STOP", "RSO STOP",
"UPDATE_MAC_ADDR",
"RESPONE MAX"}; "RESPONE MAX"};
return (char *)strings[bit]; return (char *)strings[bit];
} }

View File

@@ -273,7 +273,7 @@ static inline void tgt_vdev_mgr_reg_set_mac_address_response(
struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops) struct wlan_lmac_if_mlme_rx_ops *mlme_rx_ops)
{ {
mlme_rx_ops->vdev_mgr_set_mac_addr_response = mlme_rx_ops->vdev_mgr_set_mac_addr_response =
mlme_vdev_mgr_notify_set_mac_addr_response; wlan_vdev_mlme_notify_set_mac_addr_response;
} }
#else #else
static inline void tgt_vdev_mgr_reg_set_mac_address_response( static inline void tgt_vdev_mgr_reg_set_mac_address_response(