Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9ace944 authored by Deeksha Gupta's avatar Deeksha Gupta Committed by Madan Koyyalamudi
Browse files

qcacld-3.0: Add new timer for roam invoke response

Host driver sends roam invoke command to firmware as part
of supplicant initiated reassociation or nud failure.
In response, firmware sends roam synch indication if
roaming is successful or roam invoke fail or handoff failure
if roaming failed. On sending the roam invoke command, host
driver sets the roam_invoke_in_progress flag to true.
This flag is checked when scan request is received to avoid
scan during roam invoke. If firmware is not able to respond
to the roam invoke event, then the roam_invoke_in_progress
flag is set indefinitely resulting in continuous scan
rejection.

Add a new roam_invoke_timer timer and start this
wakeable timer after roam invoke command is sent to
firmware. On timeout reset the roam invoke in progress flag.
And host ignore the roam invoke response if firmware sends
roam invoke response without roam invoke request.

Change-Id: I5ca4497e06a26c3bec38bf401ae2bf77a6eade5e
CRs-Fixed: 2917870
parent 4d19cdfa
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
@@ -77,6 +77,7 @@
/* Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) */
#define CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15

#define QDF_ROAM_INVOKE_TIMEOUT 10000 /* in msec */
/* Used to determine what to set to the MLME_DOT11_MODE */
enum csr_cfgdot11mode {
	eCSR_CFG_DOT11_MODE_ABG,
@@ -614,6 +615,10 @@ struct csr_roam_session {
	bool is_adaptive_11r_connection;
	struct csr_disconnect_stats disconnect_stats;
	qdf_mc_timer_t join_retry_timer;
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
	qdf_mc_timer_t roam_invoke_timer;
	struct csr_timer_info roam_invoke_timer_info;
#endif
};

struct csr_roamstruct {
+4 −0
Original line number Diff line number Diff line
@@ -14447,6 +14447,10 @@ QDF_STATUS sme_roam_invoke_nud_fail(mac_handle_t mac_handle, uint8_t vdev_id)
	} else {
		vdev_roam_params->roam_invoke_in_progress = true;
		vdev_roam_params->source = CONNECTION_MGR_INITIATED;
		session->roam_invoke_timer_info.mac = mac_ctx;
		session->roam_invoke_timer_info.vdev_id = vdev_id;
		qdf_mc_timer_start(&session->roam_invoke_timer,
				   QDF_ROAM_INVOKE_TIMEOUT);
	}

	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
+117 −5
Original line number Diff line number Diff line
@@ -12216,6 +12216,38 @@ void csr_roam_roaming_offload_timeout_handler(void *timer_data)
	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
}
static void csr_roam_invoke_timeout_handler(void *data)
{
	struct csr_timer_info *info = data;
	struct wlan_objmgr_vdev *vdev;
	struct mlme_roam_after_data_stall *vdev_roam_params;
	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(info->mac->psoc,
						    info->vdev_id,
						    WLAN_LEGACY_SME_ID);
	vdev_roam_params = mlme_get_roam_invoke_params(vdev);
	if (!vdev_roam_params) {
		sme_err("Invalid vdev roam params, aborting timeout handler");
		goto rel;
	}
	sme_debug("Roam invoke timer expired source %d nud behaviour %d",
		  vdev_roam_params->source, info->mac->nud_fail_behaviour);
	if (vdev_roam_params->source == USERSPACE_INITIATED ||
	    info->mac->nud_fail_behaviour == DISCONNECT_AFTER_ROAM_FAIL) {
		csr_roam_disconnect(info->mac, info->vdev_id,
				    eCSR_DISCONNECT_REASON_DEAUTH,
				    REASON_USER_TRIGGERED_ROAM_FAILURE);
	}
	vdev_roam_params->roam_invoke_in_progress = false;
rel:
	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
}
QDF_STATUS csr_roam_start_roaming_timer(struct mac_context *mac,
					uint32_t vdev_id,
					uint32_t interval)
@@ -12361,6 +12393,75 @@ void csr_roam_roaming_offload_timer_action(
		qdf_mc_timer_stop(&csr_session->roaming_offload_timer);
}
static QDF_STATUS csr_roam_invoke_timer_init(
					struct csr_roam_session *csr_session)
{
	QDF_STATUS status;
	status = qdf_mc_timer_init(&csr_session->roam_invoke_timer,
				   QDF_TIMER_TYPE_WAKE_APPS,
				   csr_roam_invoke_timeout_handler,
				   &csr_session->roam_invoke_timer_info);
	if (QDF_IS_STATUS_ERROR(status))
		sme_err("timer init failed for roam invoke timer");
	return status;
}
static QDF_STATUS csr_roam_invoke_timer_destroy(
					struct csr_roam_session *csr_session)
{
	QDF_STATUS status;
	status = qdf_mc_timer_destroy(&csr_session->roam_invoke_timer);
	if (QDF_IS_STATUS_ERROR(status))
		sme_err("timer deinit failed for roam invoke timer");
	return status;
}
static QDF_STATUS csr_roam_invoke_timer_stop(struct mac_context *mac_ctx,
					     uint8_t vdev_id)
{
	struct csr_roam_session *csr_session;
	csr_session = CSR_GET_SESSION(mac_ctx, vdev_id);
	if (!csr_session) {
		sme_err("LFR3: session %d not found", vdev_id);
		return QDF_STATUS_E_FAILURE;
	}
	if (QDF_TIMER_STATE_RUNNING ==
	    qdf_mc_timer_get_current_state(&csr_session->roam_invoke_timer)) {
		sme_debug("Stop Roam invoke timer for session ID: %d", vdev_id);
		qdf_mc_timer_stop(&csr_session->roam_invoke_timer);
		return QDF_STATUS_SUCCESS;
	}
	return QDF_STATUS_E_FAILURE;
}
#else
static inline QDF_STATUS csr_roam_invoke_timer_init(
					struct csr_roam_session *csr_session)
{
	return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS csr_roam_invoke_timer_destroy(
					struct csr_roam_session *session)
{
	return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS csr_roam_invoke_timer_stop(struct mac_context *mac_ctx,
						    uint8_t vdev_id)
{
	return QDF_STATUS_SUCCESS;
}
#endif
static QDF_STATUS csr_roam_start_wait_for_key_timer(
@@ -16312,11 +16413,9 @@ QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme)
		sme_err("mem fail for roaming timer");
		return status;
	}
	if (QDF_IS_STATUS_ERROR(status)) {
		sme_err("timer init failed for join failure timer");
	status = csr_roam_invoke_timer_init(session);
	if (QDF_IS_STATUS_ERROR(status))
		return status;
	}
	ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info;
	session->ht_config.ht_rx_ldpc = ht_cap_info->adv_coding_cap;
@@ -16382,6 +16481,7 @@ void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id)
		csr_roam_free_connected_info(mac, &pSession->connectedInfo);
		csr_roam_free_connected_info(mac,
					     &pSession->prev_assoc_ap_info);
		csr_roam_invoke_timer_destroy(pSession);
		qdf_mc_timer_destroy(&pSession->hTimerRoaming);
		qdf_mc_timer_destroy(&pSession->roaming_offload_timer);
		csr_init_session(mac, vdev_id);
@@ -19792,6 +19892,7 @@ void csr_process_ho_fail_ind(struct mac_context *mac_ctx, void *msg_buf)
	ap_info.source = ADDED_BY_DRIVER;
	wlan_blm_add_bssid_to_reject_list(mac_ctx->pdev, &ap_info);
	csr_roam_invoke_timer_stop(mac_ctx, sessionId);
	/* Roaming is supported only on Infra STA Mode. */
	if (!csr_roam_is_sta_mode(mac_ctx, sessionId)) {
@@ -20549,6 +20650,10 @@ QDF_STATUS csr_fast_reassoc(mac_handle_t mac_handle,
	} else {
		vdev_roam_params->roam_invoke_in_progress = true;
		vdev_roam_params->source = USERSPACE_INITIATED;
		session->roam_invoke_timer_info.mac = mac_ctx;
		session->roam_invoke_timer_info.vdev_id = vdev_id;
		qdf_mc_timer_start(&session->roam_invoke_timer,
				   QDF_ROAM_INVOKE_TIMEOUT);
	}
	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID);
@@ -20763,7 +20868,7 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
		 */
		csr_roam_roaming_offload_timer_action(mac_ctx,
				0, session_id, ROAMING_OFFLOAD_TIMER_STOP);
		csr_roam_invoke_timer_stop(mac_ctx, session_id);
		if (session->discon_in_progress) {
			sme_err("LFR3: vdev:%d Disconnect is in progress roam_synch is not allowed",
				session_id);
@@ -20834,6 +20939,7 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
					   REASON_ROAM_ABORT);
		csr_roam_roaming_offload_timer_action(mac_ctx,
				0, session_id, ROAMING_OFFLOAD_TIMER_STOP);
		csr_roam_invoke_timer_stop(mac_ctx, session_id);
		csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
				eCSR_ROAM_ABORT, eCSR_ROAM_RESULT_SUCCESS);
		vdev_roam_params->roam_invoke_in_progress = false;
@@ -20845,6 +20951,11 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
	case SIR_ROAMING_INVOKE_FAIL:
		sme_debug("Roaming triggered failed source %d nud behaviour %d",
			  vdev_roam_params->source, mac_ctx->nud_fail_behaviour);
		status = csr_roam_invoke_timer_stop(mac_ctx, session_id);
		if (QDF_IS_STATUS_ERROR(status)) {
			sme_debug("Ignoring roam invoke fail event as host didn't send roam invoke request");
			goto end;
		}
		/* Userspace roam req fail, disconnect with AP */
		if (vdev_roam_params->source == USERSPACE_INITIATED ||
@@ -20932,6 +21043,7 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
	case SIR_ROAMING_DEAUTH:
		csr_roam_roaming_offload_timer_action(
			mac_ctx, 0, session_id, ROAMING_OFFLOAD_TIMER_STOP);
		csr_roam_invoke_timer_stop(mac_ctx, session_id);
		goto end;
	default:
		status = QDF_STATUS_E_FAILURE;