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

Commit ea9208e2 authored by Surabhi Vishnoi's avatar Surabhi Vishnoi Committed by Madan Koyyalamudi
Browse files

qcacld-3.0: Acquire wakelock during roaming if key installation is pending

Currently, wakelock is only taken during initial connection if
pairwise key installation is pending and not during roaming. This
may lead to EAPOL delay/timeout during roaming as runtime pm and
suspend is allowed during roaming. To fix this issue, acquire
wakelock if key installation is pending during roaming.

This change also refactors the code and release the wakelock in
wma_remove_peer if EAPOL fails during initial connection or roaming.

Change-Id: Id4cac30b3c383ca3d3e963571846f8a30eaa1006
CRs-Fixed: 3189799
parent 4fd813b1
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#define mlme_legacy_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_MLME, params)
#define mlme_legacy_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_MLME, params)

#define MLME_PEER_SET_KEY_WAKELOCK_TIMEOUT WAKELOCK_DURATION_RECOMMENDED
/**
 * struct wlan_mlme_psoc_ext_obj -MLME ext psoc priv object
 * @cfg:     cfg items
@@ -85,6 +86,9 @@ struct sae_auth_retry {
 * @last_assoc_received_time: last assoc received time
 * @last_disassoc_deauth_received_time: last disassoc/deauth received time
 * @twt_ctx: TWT context
 * @peer_set_key_wakelock: wakelock to protect peer set key op with firmware
 * @peer_set_key_runtime_wakelock: runtime pm wakelock for set key
 * @is_key_wakelock_set: flag to check if key wakelock is pending to release
 */
struct peer_mlme_priv_obj {
	uint8_t last_pn_valid;
@@ -96,6 +100,9 @@ struct peer_mlme_priv_obj {
#ifdef WLAN_SUPPORT_TWT
	struct twt_context twt_ctx;
#endif
	qdf_wake_lock_t peer_set_key_wakelock;
	qdf_runtime_lock_t peer_set_key_runtime_wakelock;
	bool is_key_wakelock_set;
};

/**
@@ -562,6 +569,32 @@ void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer,
 */
bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer);


/**
 * wlan_acquire_peer_key_wakelock -api to get key wakelock
 * @pdev: pdev
 * @mac_addr: peer mac addr
 *
 * This function acquires wakelock and prevent runtime pm during key
 * installation
 *
 * Return: None
 */
void wlan_acquire_peer_key_wakelock(struct wlan_objmgr_pdev *pdev,
				    uint8_t *mac_addr);

/**
 * wlan_release_peer_key_wakelock -api to release key wakelock
 * @pdev: pdev
 * @mac_addr: peer mac addr
 *
 * This function releases wakelock and allow runtime pm after key
 * installation
 *
 * Return: None
 */
void wlan_release_peer_key_wakelock(struct wlan_objmgr_pdev *pdev,
				    uint8_t *mac_addr);
/**
 * mlme_set_discon_reason_n_from_ap() - set disconnect reason and from ap flag
 * @psoc: PSOC pointer
+90 −0
Original line number Diff line number Diff line
@@ -231,6 +231,10 @@ mlme_peer_object_created_notification(struct wlan_objmgr_peer *peer,
		qdf_mem_free(peer_priv);
	}

	qdf_wake_lock_create(&peer_priv->peer_set_key_wakelock, "peer_set_key");
	qdf_runtime_lock_init(&peer_priv->peer_set_key_runtime_wakelock);
	peer_priv->is_key_wakelock_set = false;

	return status;
}

@@ -253,6 +257,10 @@ mlme_peer_object_destroyed_notification(struct wlan_objmgr_peer *peer,
		return QDF_STATUS_E_FAILURE;
	}

	peer_priv->is_key_wakelock_set = false;
	qdf_runtime_lock_deinit(&peer_priv->peer_set_key_runtime_wakelock);
	qdf_wake_lock_destroy(&peer_priv->peer_set_key_wakelock);

	status = wlan_objmgr_peer_component_obj_detach(peer,
						       WLAN_UMAC_COMP_MLME,
						       peer_priv);
@@ -2839,6 +2847,88 @@ bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer)
	return peer_priv->is_pmf_enabled;
}

void
wlan_acquire_peer_key_wakelock(struct wlan_objmgr_pdev *pdev, uint8_t *mac_addr)
{
	uint8_t pdev_id;
	struct wlan_objmgr_peer *peer;
	struct peer_mlme_priv_obj *peer_priv;
	struct wlan_objmgr_psoc *psoc;

	psoc = wlan_pdev_get_psoc(pdev);
	if (!psoc)
		return;

	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
				    WLAN_LEGACY_MAC_ID);
	if (!peer)
		return;

	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
							  WLAN_UMAC_COMP_MLME);
	if (!peer_priv) {
		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
		return;
	}

	if (peer_priv->is_key_wakelock_set) {
		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
		return;
	}

	mlme_debug(QDF_MAC_ADDR_FMT ": Acquire set key wake lock for %d ms",
		QDF_MAC_ADDR_REF(mac_addr), MLME_PEER_SET_KEY_WAKELOCK_TIMEOUT);
	qdf_wake_lock_timeout_acquire(&peer_priv->peer_set_key_wakelock,
				      MLME_PEER_SET_KEY_WAKELOCK_TIMEOUT);
	qdf_runtime_pm_prevent_suspend(
			&peer_priv->peer_set_key_runtime_wakelock);
	peer_priv->is_key_wakelock_set = true;

	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
}

void
wlan_release_peer_key_wakelock(struct wlan_objmgr_pdev *pdev, uint8_t *mac_addr)
{
	uint8_t pdev_id;
	struct wlan_objmgr_peer *peer;
	struct peer_mlme_priv_obj *peer_priv;
	struct wlan_objmgr_psoc *psoc;

	psoc = wlan_pdev_get_psoc(pdev);
	if (!psoc)
		return;

	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
				    WLAN_LEGACY_MAC_ID);
	if (!peer)
		return;

	peer_priv = wlan_objmgr_peer_get_comp_private_obj(peer,
							  WLAN_UMAC_COMP_MLME);
	if (!peer_priv) {
		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
		return;
	}

	if (!peer_priv->is_key_wakelock_set) {
		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
		return;
	}

	peer_priv->is_key_wakelock_set = false;
	mlme_debug(QDF_MAC_ADDR_FMT ": Release set key wake lock",
		   QDF_MAC_ADDR_REF(mac_addr));
	qdf_wake_lock_release(&peer_priv->peer_set_key_wakelock,
			      WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP);
	qdf_runtime_pm_allow_suspend(
			&peer_priv->peer_set_key_runtime_wakelock);

	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
}

void mlme_set_discon_reason_n_from_ap(struct wlan_objmgr_psoc *psoc,
				      uint8_t vdev_id, bool from_ap,
				      uint32_t reason_code)
+2 −0
Original line number Diff line number Diff line
@@ -6982,6 +6982,8 @@ int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter, uint8_t *bssid,
			*((uint64_t *)roam_info_ptr->replay_ctr));
	} else {
		wlan_acquire_peer_key_wakelock(hdd_ctx->pdev,
					       roam_info_ptr->bssid.bytes);
		hdd_debug("No Auth Params TLV's");
		if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
					false)) {
+1 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -689,8 +690,6 @@ struct wma_invalid_peer_params {
 * @ns_offload_req: cached ns offload request
 * @rcpi_req: rcpi request
 * @in_bmps: Whether bmps for this interface has been enabled
 * @vdev_set_key_wakelock: wakelock to protect vdev set key op with firmware
 * @vdev_set_key_runtime_wakelock: runtime pm wakelock for set key
 * @ch_freq: channel frequency
 * @roam_scan_stats_req: cached roam scan stats request
 * @wma_invalid_peer_params: structure storing invalid peer params
@@ -738,8 +737,6 @@ struct wma_txrx_node {
	bool in_bmps;
	struct beacon_filter_param beacon_filter;
	bool beacon_filter_enabled;
	qdf_wake_lock_t vdev_set_key_wakelock;
	qdf_runtime_lock_t vdev_set_key_runtime_wakelock;
	struct roam_synch_frame_ind roam_synch_frame_ind;
	bool is_waiting_for_key;
	uint32_t ch_freq;
+1 −0
Original line number Diff line number Diff line
@@ -1644,6 +1644,7 @@ QDF_STATUS wma_remove_peer(tp_wma_handle wma, uint8_t *mac_addr,
			cdp_peer_delete(soc, vdev_id, peer_addr, bitmap);
	}

	wlan_release_peer_key_wakelock(wma->pdev, peer_mac);
	wma_remove_objmgr_peer(wma, wma->interfaces[vdev_id].vdev, peer_mac);

	wma->interfaces[vdev_id].peer_count--;
Loading