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

Commit 0af3ea00 authored by Lincoln Tran's avatar Lincoln Tran Committed by Gerrit - the friendly Code Review server
Browse files

qcacld-3.0: Add synchronization around country set

When the country is being updated via WMI, FW responds with a channel
list after some time. During this time, another event can come, blocking
the channel list from being updated. Add synchronization so that these
requests are blocked until the channel list is updated.

Change-Id: I4c1b7d33242226b8153821fdc14db54fff764c17
CRs-fixed: 2884840
parent 47ddbb98
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2189,6 +2189,9 @@ struct hdd_context {
#endif
	bool disconnect_for_sta_mon_conc;
	bool is_dual_mac_cfg_updated;
	bool is_regulatory_update_in_progress;
	qdf_event_t regulatory_update_event;
	qdf_mutex_t regulatory_status_lock;
};

/**
+3 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-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
@@ -31,6 +31,8 @@ struct hdd_context;
#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR
#endif

#define CHANNEL_LIST_UPDATE_TIMEOUT 4500

/**
 * hdd_update_regulatory_config() - API to update regulatory config parameters
 * @hdd_ctx: HDD context
+20 −0
Original line number Diff line number Diff line
@@ -3051,6 +3051,16 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
		qdf_event_reset(&adapter->acs_complete_event);
	}
	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
	if (hdd_ctx->is_regulatory_update_in_progress) {
		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
		hdd_debug("waiting for channel list to update");
		qdf_wait_for_event_completion(&hdd_ctx->regulatory_update_event,
					      CHANNEL_LIST_UPDATE_TIMEOUT);
	} else {
		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
	}
	ret = wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX, data,
					 data_len,
					 wlan_hdd_cfg80211_do_acs_policy);
@@ -20817,6 +20827,16 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
	if (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc))
		return -EINVAL;
	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
	if (hdd_ctx->is_regulatory_update_in_progress) {
		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
		hdd_debug("waiting for channel list to update");
		qdf_wait_for_event_completion(&hdd_ctx->regulatory_update_event,
					      CHANNEL_LIST_UPDATE_TIMEOUT);
	} else {
		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
	}
	if (req->bssid)
		bssid = req->bssid;
	else if (bssid_hint)
+10 −0
Original line number Diff line number Diff line
@@ -6480,6 +6480,16 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
		}
	}

	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
	if (hdd_ctx->is_regulatory_update_in_progress) {
		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
		hdd_debug("waiting for channel list to update");
		qdf_wait_for_event_completion(&hdd_ctx->regulatory_update_event,
					      CHANNEL_LIST_UPDATE_TIMEOUT);
	} else {
		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
	}

	channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
	channel = ieee80211_frequency_to_channel(
				params->chandef.chan->center_freq);
+19 −0
Original line number Diff line number Diff line
@@ -751,6 +751,11 @@ int hdd_reg_set_country(struct hdd_context *hdd_ctx, char *country_code)
	qdf_mem_copy(cc, country_code, REG_ALPHA2_LEN);
	cc[REG_ALPHA2_LEN] = '\0';

	qdf_event_reset(&hdd_ctx->regulatory_update_event);
	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
	hdd_ctx->is_regulatory_update_in_progress = true;
	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);

	status = ucfg_reg_set_country(hdd_ctx->pdev, cc);
	if (QDF_IS_STATUS_ERROR(status))
		hdd_err("Failed to set country");
@@ -910,6 +915,11 @@ void hdd_reg_notifier(struct wiphy *wiphy,
		    NL80211_USER_REG_HINT_CELL_BASE)
			return;

		qdf_event_reset(&hdd_ctx->regulatory_update_event);
		qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
		hdd_ctx->is_regulatory_update_in_progress = true;
		qdf_mutex_release(&hdd_ctx->regulatory_status_lock);

		qdf_mem_copy(country, request->alpha2, QDF_MIN(
			     sizeof(request->alpha2), sizeof(country)));
		status = ucfg_reg_set_country(hdd_ctx->pdev, country);
@@ -1653,6 +1663,10 @@ static void hdd_regulatory_dyn_cbk(struct wlan_objmgr_psoc *psoc,

	hdd_config_tdls_with_band_switch(hdd_ctx);
	qdf_sched_work(0, &hdd_ctx->country_change_work);
	qdf_event_set(&hdd_ctx->regulatory_update_event);
	qdf_mutex_acquire(&hdd_ctx->regulatory_status_lock);
	hdd_ctx->is_regulatory_update_in_progress = false;
	qdf_mutex_release(&hdd_ctx->regulatory_status_lock);
}

int hdd_update_regulatory_config(struct hdd_context *hdd_ctx)
@@ -1682,6 +1696,9 @@ int hdd_regulatory_init(struct hdd_context *hdd_ctx, struct wiphy *wiphy)
					       hdd_regulatory_dyn_cbk,
					       NULL);

	qdf_event_create(&hdd_ctx->regulatory_update_event);
	qdf_mutex_create(&hdd_ctx->regulatory_status_lock);
	hdd_ctx->is_regulatory_update_in_progress = false;

	wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
	/* Check the kernel version for upstream commit aced43ce780dc5 that
@@ -1745,6 +1762,8 @@ void hdd_regulatory_deinit(struct hdd_context *hdd_ctx)
{
	qdf_flush_work(&hdd_ctx->country_change_work);
	qdf_destroy_work(0, &hdd_ctx->country_change_work);
	qdf_event_destroy(&hdd_ctx->regulatory_update_event);
	qdf_mutex_destroy(&hdd_ctx->regulatory_status_lock);
}

void hdd_update_regdb_offload_config(struct hdd_context *hdd_ctx)