qcacld-3.0: T2LM timer changes
Code changes to run the T2LM timer in FW instead of host. Change-Id: Ic66da9e0311121d2ae23c600c97f225c56aa215f CRs-Fixed: 3595388
This commit is contained in:

committed by
Rahul Choudhary

orang tua
0084ccba11
melakukan
fc51b6ff4f
@@ -1618,6 +1618,9 @@ cm_update_tid_mapping(struct wlan_objmgr_vdev *vdev)
|
||||
if (!vdev || !vdev->mlo_dev_ctx)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
if (!wlan_cm_is_vdev_connected(vdev))
|
||||
return QDF_STATUS_E_AGAIN;
|
||||
|
||||
if (!wlan_vdev_mlme_is_mlo_link_vdev(vdev) ||
|
||||
!mlo_check_if_all_links_up(vdev))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
@@ -1628,7 +1631,7 @@ cm_update_tid_mapping(struct wlan_objmgr_vdev *vdev)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
status = wlan_process_bcn_prbrsp_t2lm_ie(vdev, t2lm_ctx, t2lm_ctx->tsf);
|
||||
status = wlan_update_t2lm_mapping(vdev, t2lm_ctx, t2lm_ctx->tsf);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
mlme_err("T2LM IE beacon process failed");
|
||||
}
|
||||
|
@@ -246,7 +246,44 @@ wlan_t2lm_clear_all_tid_mapping(struct wlan_objmgr_vdev *vdev);
|
||||
QDF_STATUS
|
||||
wlan_populate_link_disable_t2lm_frame(struct wlan_objmgr_vdev *vdev,
|
||||
struct mlo_link_disable_request_evt_params *params);
|
||||
|
||||
/**
|
||||
* wlan_update_t2lm_mapping - Update t2lm mapping to fw
|
||||
* @vdev: pointer to vdev
|
||||
* @rx_t2lm: received t2lm mapping from beacon
|
||||
* @tsf: timing sync function value
|
||||
*
|
||||
* Return: qdf status
|
||||
*/
|
||||
QDF_STATUS wlan_update_t2lm_mapping(
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_t2lm_context *rx_t2lm,
|
||||
uint64_t tsf);
|
||||
|
||||
/**
|
||||
* wlan_t2lm_init_default_mapping - Initialize t2lm to default mapping
|
||||
* @t2lm_ctx: t2lm ctx stored in ml dev ctx
|
||||
*
|
||||
* Return: qdf status
|
||||
*/
|
||||
QDF_STATUS
|
||||
wlan_t2lm_init_default_mapping(struct wlan_t2lm_context *t2lm_ctx);
|
||||
|
||||
#else
|
||||
static inline QDF_STATUS
|
||||
wlan_t2lm_init_default_mapping(struct wlan_t2lm_context *t2lm_ctx)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS wlan_update_t2lm_mapping(
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_t2lm_context *rx_t2lm,
|
||||
uint64_t tsf)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
wlan_populate_link_disable_t2lm_frame(struct wlan_objmgr_vdev *vdev,
|
||||
struct mlo_link_disable_request_evt_params *params)
|
||||
|
@@ -729,3 +729,205 @@ QDF_STATUS wlan_t2lm_deliver_event(struct wlan_objmgr_vdev *vdev,
|
||||
return t2lm_deliver_event(vdev, peer, event, event_data,
|
||||
frame_len, dialog_token);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_t2lm_init_default_mapping(struct wlan_t2lm_context *t2lm_ctx)
|
||||
{
|
||||
if (!t2lm_ctx)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
qdf_mem_zero(t2lm_ctx, sizeof(struct wlan_t2lm_context));
|
||||
|
||||
t2lm_ctx->established_t2lm.t2lm.default_link_mapping = 1;
|
||||
t2lm_ctx->established_t2lm.t2lm.direction = WLAN_T2LM_BIDI_DIRECTION;
|
||||
t2lm_ctx->established_t2lm.t2lm.link_mapping_size = 0;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_update_t2lm_mapping(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_t2lm_context *rx_t2lm, uint64_t tsf)
|
||||
{
|
||||
struct wlan_t2lm_context *t2lm_ctx;
|
||||
struct wlan_mlo_dev_context *mlo_dev_ctx;
|
||||
uint64_t mst_start_tsf;
|
||||
uint64_t mst_end_tsf;
|
||||
uint64_t rx_bcn_tsf_exp_dur;
|
||||
uint64_t mst_end_tsf_low;
|
||||
uint64_t mst_end_tsf_high;
|
||||
uint16_t mst;
|
||||
uint32_t exp_dur;
|
||||
|
||||
if (!vdev)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
mlo_dev_ctx = wlan_vdev_get_mlo_dev_ctx(vdev);
|
||||
if (!mlo_dev_ctx)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
t2lm_ctx = &mlo_dev_ctx->t2lm_ctx;
|
||||
if (rx_t2lm->upcoming_t2lm.t2lm.direction == WLAN_T2LM_INVALID_DIRECTION &&
|
||||
rx_t2lm->established_t2lm.t2lm.direction == WLAN_T2LM_INVALID_DIRECTION) {
|
||||
if (!t2lm_ctx->established_t2lm.t2lm.default_link_mapping) {
|
||||
wlan_t2lm_init_default_mapping(t2lm_ctx);
|
||||
t2lm_debug("initialize to default T2LM mapping");
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (rx_t2lm->established_t2lm.t2lm.expected_duration &&
|
||||
!rx_t2lm->established_t2lm.t2lm.mapping_switch_time_present &&
|
||||
rx_t2lm->upcoming_t2lm.t2lm.expected_duration &&
|
||||
rx_t2lm->upcoming_t2lm.t2lm.mapping_switch_time_present) {
|
||||
if (!qdf_mem_cmp(t2lm_ctx->established_t2lm.t2lm.ieee_link_map_tid,
|
||||
rx_t2lm->established_t2lm.t2lm.ieee_link_map_tid,
|
||||
sizeof(uint16_t) * T2LM_MAX_NUM_TIDS)) {
|
||||
t2lm_debug("T2LM mapping is already configured");
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
|
||||
qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm,
|
||||
&rx_t2lm->established_t2lm.t2lm,
|
||||
sizeof(struct wlan_t2lm_info));
|
||||
|
||||
t2lm_ctx->established_t2lm.t2lm.expected_duration = 0;
|
||||
t2lm_ctx->established_t2lm.t2lm.expected_duration_present = 0;
|
||||
t2lm_ctx->established_t2lm.t2lm.mapping_switch_time = 0;
|
||||
t2lm_ctx->established_t2lm.t2lm.mapping_switch_time_present = 0;
|
||||
|
||||
wlan_mlo_dev_t2lm_notify_link_update(vdev,
|
||||
&t2lm_ctx->established_t2lm.t2lm);
|
||||
wlan_clear_peer_level_tid_to_link_mapping(vdev);
|
||||
t2lm_debug("Update T2LM established mapping to FW");
|
||||
wlan_send_tid_to_link_mapping(
|
||||
vdev, &t2lm_ctx->established_t2lm.t2lm);
|
||||
|
||||
if (!qdf_mem_cmp(t2lm_ctx->upcoming_t2lm.t2lm.ieee_link_map_tid,
|
||||
rx_t2lm->upcoming_t2lm.t2lm.ieee_link_map_tid,
|
||||
sizeof(uint16_t) * T2LM_MAX_NUM_TIDS)) {
|
||||
t2lm_debug("Ongoing mapping is already established");
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm,
|
||||
&rx_t2lm->upcoming_t2lm.t2lm,
|
||||
sizeof(struct wlan_t2lm_info));
|
||||
t2lm_debug("Update T2LM upcoming mapping to FW");
|
||||
wlan_send_tid_to_link_mapping(
|
||||
vdev, &t2lm_ctx->upcoming_t2lm.t2lm);
|
||||
}
|
||||
|
||||
if (t2lm_ctx->established_t2lm.t2lm.expected_duration_present &&
|
||||
rx_t2lm->established_t2lm.t2lm.expected_duration_present) {
|
||||
/* Established T2LM is already saved in the T2LM context.
|
||||
* T2LM IE in the beacon/probe response frame has the updated
|
||||
* expected duration.
|
||||
*/
|
||||
if (!qdf_mem_cmp(t2lm_ctx->established_t2lm.t2lm.ieee_link_map_tid,
|
||||
rx_t2lm->established_t2lm.t2lm.ieee_link_map_tid,
|
||||
sizeof(uint16_t) * T2LM_MAX_NUM_TIDS)) {
|
||||
if (!t2lm_ctx->mst_start_tsf) {
|
||||
t2lm_ctx->mst_end_tsf = tsf + (rx_t2lm->established_t2lm.t2lm.expected_duration << 10);
|
||||
t2lm_ctx->mst_start_tsf = tsf;
|
||||
}
|
||||
|
||||
/* Check if AP has updated expected duration value
|
||||
* more than expected delta between 2 beacons,
|
||||
* calculation as following:
|
||||
* 1.when receive a beacon with mapping switch
|
||||
* time set, calculate the mapping switch start TSF
|
||||
* by replacing bit25~bit10 in the bcn TSF
|
||||
* mst_start_tsf = (bcn_tsf & (~mst_mask)) | (mst << 10);
|
||||
* 2.based on the expected duration,
|
||||
* calculate the mapping end time tsf
|
||||
* mst_end_tsf = mst_start_tsf + expected_duration;
|
||||
* 3.then after the TSF become established mapping,
|
||||
* whenever host receive a beacon,
|
||||
* check if the new expected duration based
|
||||
* on current beacon TSF has a big drift to the old one.
|
||||
* mst_end_tsf - (200 << 10) < rx_bcn_tsf_exp_dur +
|
||||
* rx_bcn_tsf_exp_dur < mst_end_tsf + (200 << 10)
|
||||
*/
|
||||
rx_bcn_tsf_exp_dur = tsf + (rx_t2lm->established_t2lm.t2lm.expected_duration << 10);
|
||||
mst_end_tsf_low = t2lm_ctx->mst_end_tsf - (200 << 10);
|
||||
mst_end_tsf_high = t2lm_ctx->mst_end_tsf + (200 << 10);
|
||||
if (t2lm_ctx->mst_end_tsf && (rx_bcn_tsf_exp_dur < mst_end_tsf_low) &&
|
||||
(rx_bcn_tsf_exp_dur > mst_end_tsf_high)) {
|
||||
t2lm_ctx->established_t2lm.t2lm.expected_duration =
|
||||
rx_t2lm->established_t2lm.t2lm.expected_duration;
|
||||
wlan_send_tid_to_link_mapping(
|
||||
vdev, &t2lm_ctx->established_t2lm.t2lm);
|
||||
} else {
|
||||
t2lm_debug("T2LM exp duration in range");
|
||||
}
|
||||
}
|
||||
} else if (rx_t2lm->established_t2lm.t2lm.expected_duration_present &&
|
||||
!rx_t2lm->established_t2lm.t2lm.mapping_switch_time_present) {
|
||||
if (!qdf_mem_cmp(t2lm_ctx->established_t2lm.t2lm.ieee_link_map_tid,
|
||||
rx_t2lm->established_t2lm.t2lm.ieee_link_map_tid,
|
||||
sizeof(uint16_t) * T2LM_MAX_NUM_TIDS)) {
|
||||
t2lm_debug("T2LM mapping is already configured");
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
|
||||
mst_start_tsf = tsf;
|
||||
t2lm_ctx->mst_start_tsf = mst_start_tsf;
|
||||
mst_end_tsf = mst_start_tsf + (rx_t2lm->established_t2lm.t2lm.expected_duration << 10);
|
||||
t2lm_ctx->mst_end_tsf = mst_end_tsf;
|
||||
|
||||
/* Mapping switch time is already expired when STA receives the
|
||||
* T2LM IE from beacon/probe response frame.
|
||||
*/
|
||||
qdf_mem_copy(&t2lm_ctx->established_t2lm.t2lm,
|
||||
&rx_t2lm->established_t2lm.t2lm,
|
||||
sizeof(struct wlan_t2lm_info));
|
||||
|
||||
/* Notify the registered caller about the link update*/
|
||||
wlan_mlo_dev_t2lm_notify_link_update(vdev,
|
||||
&t2lm_ctx->established_t2lm.t2lm);
|
||||
wlan_clear_peer_level_tid_to_link_mapping(vdev);
|
||||
t2lm_debug("MST expired, update established T2LM mapping to FW");
|
||||
wlan_send_tid_to_link_mapping(
|
||||
vdev, &t2lm_ctx->established_t2lm.t2lm);
|
||||
}
|
||||
|
||||
if (rx_t2lm->upcoming_t2lm.t2lm.mapping_switch_time_present) {
|
||||
if (!qdf_mem_cmp(t2lm_ctx->upcoming_t2lm.t2lm.ieee_link_map_tid,
|
||||
rx_t2lm->upcoming_t2lm.t2lm.ieee_link_map_tid,
|
||||
sizeof(uint16_t) * T2LM_MAX_NUM_TIDS)) {
|
||||
t2lm_debug("Ongoing mapping is already established");
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
|
||||
mst = rx_t2lm->upcoming_t2lm.t2lm.mapping_switch_time;
|
||||
exp_dur = rx_t2lm->upcoming_t2lm.t2lm.expected_duration;
|
||||
if (mst) {
|
||||
mst_start_tsf = (tsf & (~WLAN_T2LM_MAPPING_SWITCH_TSF_BITS)) | (mst << 10);
|
||||
mst_end_tsf = mst_start_tsf + exp_dur;
|
||||
t2lm_ctx->mst_start_tsf = mst_start_tsf;
|
||||
t2lm_ctx->mst_end_tsf = mst_end_tsf;
|
||||
}
|
||||
|
||||
qdf_mem_copy(&t2lm_ctx->upcoming_t2lm.t2lm,
|
||||
&rx_t2lm->upcoming_t2lm.t2lm,
|
||||
sizeof(struct wlan_t2lm_info));
|
||||
t2lm_debug("Update T2LM upcoming mapping to FW");
|
||||
wlan_send_tid_to_link_mapping(
|
||||
vdev, &t2lm_ctx->upcoming_t2lm.t2lm);
|
||||
} else {
|
||||
if (t2lm_ctx->established_t2lm.t2lm.direction == WLAN_T2LM_INVALID_DIRECTION &&
|
||||
t2lm_ctx->upcoming_t2lm.t2lm.direction != WLAN_T2LM_INVALID_DIRECTION) {
|
||||
t2lm_debug("Copy upcoming T2LM mapping to expected T2LM");
|
||||
qdf_mem_copy(&t2lm_ctx->established_t2lm,
|
||||
&t2lm_ctx->upcoming_t2lm,
|
||||
sizeof(struct wlan_mlo_t2lm_ie));
|
||||
}
|
||||
/* Upcoming mapping should be cleared as mapping switch time has expired */
|
||||
qdf_mem_zero(&t2lm_ctx->upcoming_t2lm,
|
||||
sizeof(struct wlan_mlo_t2lm_ie));
|
||||
t2lm_ctx->upcoming_t2lm.t2lm.direction = WLAN_T2LM_INVALID_DIRECTION;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user