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

Commit 2043e54b authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 980f6e15 on remote branch

Change-Id: I23ede2eb29e68cefc37d6c75773884f6bc470d74
parents 58cb9fc5 980f6e15
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -3307,6 +3307,11 @@ cppflags-y += -DMON_ENABLE_DROP_FOR_MAC
cppflags-y += -DPCI_LINK_STATUS_SANITY
cppflags-y += -DDP_MON_RSSI_IN_DBM
cppflags-y += -DSYSTEM_PM_CHECK
cppflags-y += -DDISABLE_EAPOL_INTRABSS_FWD
endif

ifeq ($(CONFIG_TX_AGGREGATION_SIZE_ENABLE), y)
cppflags-y += -DTX_AGGREGATION_SIZE_ENABLE
endif

# Enable Low latency optimisation mode
@@ -3481,6 +3486,12 @@ cppflags-$(CONFIG_SAR_SAFETY_FEATURE) += -DSAR_SAFETY_FEATURE

cppflags-$(CONFIG_WLAN_FEATURE_DP_EVENT_HISTORY) += -DWLAN_FEATURE_DP_EVENT_HISTORY
cppflags-$(CONFIG_WLAN_FEATURE_DP_RX_RING_HISTORY) += -DWLAN_FEATURE_DP_RX_RING_HISTORY
cppflags-$(CONFIG_WLAN_FEATURE_DP_TX_DESC_HISTORY) += -DWLAN_FEATURE_DP_TX_DESC_HISTORY
cppflags-$(CONFIG_REO_QDESC_HISTORY) += -DREO_QDESC_HISTORY
cppflags-$(CONFIG_DP_TX_HW_DESC_HISTORY) += -DDP_TX_HW_DESC_HISTORY
ifdef CONFIG_QDF_NBUF_HISTORY_SIZE
ccflags-y += -DQDF_NBUF_HISTORY_SIZE=$(CONFIG_QDF_NBUF_HISTORY_SIZE)
endif
cppflags-$(CONFIG_WLAN_DP_PER_RING_TYPE_CONFIG) += -DWLAN_DP_PER_RING_TYPE_CONFIG
cppflags-$(CONFIG_WLAN_CE_INTERRUPT_THRESHOLD_CONFIG) += -DWLAN_CE_INTERRUPT_THRESHOLD_CONFIG
cppflags-$(CONFIG_SAP_DHCP_FW_IND) += -DSAP_DHCP_FW_IND
@@ -3744,8 +3755,8 @@ ccflags-$(CONFIG_GET_DRIVER_MODE) += -DFEATURE_GET_DRIVER_MODE
ifeq ($(CONFIG_SMP), y)
ifeq ($(CONFIG_HIF_DETECTION_LATENCY_ENABLE), y)
cppflags-y += -DHIF_DETECTION_LATENCY_ENABLE
cppflags-y += -DDETECTION_TIMER_TIMEOUT=2000
cppflags-y += -DDETECTION_LATENCY_THRESHOLD=1900
cppflags-y += -DDETECTION_TIMER_TIMEOUT=4000
cppflags-y += -DDETECTION_LATENCY_THRESHOLD=3900
endif
endif

+61 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2020-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 above
@@ -54,6 +54,49 @@ struct bssid_search_arg {
	uint8_t vdev_id;
};

/**
 * allow_mcc_go_diff_bi_definition - Defines the config values for allowing
 * different beacon intervals between P2P-G0 and STA
 * @ALLOW_MCC_GO_DIFF_BI_WFA_CERT: GO Beacon interval is not changed.
 *	MCC GO doesn't work well in optimized way. In worst scenario, it may
 *	invite STA disconnection.
 * @ALLOW_MCC_GO_DIFF_BI_WORKAROUND: Workaround 1 disassoc all the clients and
 *	update beacon Interval.
 * @ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN: Tear down the P2P link in
 *	auto/Non-autonomous -GO case.
 * @ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT: Don't disconnect the P2P client in
 *	autonomous/Non-autonomous -GO case update the BI dynamically
 */
enum allow_mcc_go_diff_bi_definition {
	ALLOW_MCC_GO_DIFF_BI_WFA_CERT = 1,
	ALLOW_MCC_GO_DIFF_BI_WORKAROUND,
	ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN,
	ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT,
};

/**
 * struct beacon_interval_arg - Contains beacon interval validation arguments
 * @curr_vdev_id: current iterator vdev ID
 * @curr_bss_opmode: current iterator BSS's opmode
 * @ch_freq: current operating channel frequency
 * @bss_beacon_interval: beacon interval that can be updated by callee
 * @status: status to be filled by callee
 * @is_done: boolean to stop iterating
 * @update_beacon_interval: boolean to mark beacon interval as updated by callee
 *
 * This structure is used to pass the candidate validation information to the
 * callback
 */
struct beacon_interval_arg {
	uint8_t curr_vdev_id;
	enum QDF_OPMODE curr_bss_opmode;
	qdf_freq_t ch_freq;
	uint16_t bss_beacon_interval;
	QDF_STATUS status;
	bool is_done;
	bool update_beacon_interval;
};

/**
 * if_mgr_enable_roaming() - interface manager enable roaming
 * @pdev: pdev object
@@ -120,6 +163,23 @@ QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect(
				struct wlan_objmgr_vdev *vdev,
				enum wlan_cm_rso_control_requestor requestor);

/**
 * if_mgr_is_beacon_interval_valid() - checks if the concurrent session is
 * valid
 * @pdev: pdev object
 * @vdev_id: vdev ID
 * @candidate: concurrent candidate info
 *
 * This function validates the beacon interval with all other active vdevs.
 *
 * Context: It should run in thread context
 *
 * Return: true if session is valid, false if not
 */
bool if_mgr_is_beacon_interval_valid(struct wlan_objmgr_pdev *pdev,
				     uint8_t vdev_id,
				     struct validate_bss_data *candidate);

/**
 * if_mgr_validate_candidate() - validate candidate event handler
 * @vdev: vdev object
+552 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2020-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 above
@@ -29,6 +29,9 @@
#include "wlan_p2p_ucfg_api.h"
#include "cds_api.h"
#include "sme_api.h"
#include "wlan_vdev_mgr_utils_api.h"
#include "wni_api.h"
#include "wlan_mlme_vdev_mgr_interface.h"

static void if_mgr_enable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev,
					  void *object, void *arg)
@@ -177,6 +180,519 @@ QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect(
	return status;
}

/**
 * if_mgr_calculate_mcc_beacon_interval() - Calculates the new beacon interval
 * @sta_bi: station beacon interval
 * @go_given_bi: P2P GO's given beacon interval
 *
 * This function has 3 stages. First it modifies the input go_given_bi to be
 * within 100 to 199. Then it checks if the sta_bi and go_given_bi are multiples
 * of each other. If they are, that means the 2 values are compatible, and just
 * return as is, otherwise, find new compatible BI for P2P GO
 *
 * Return: valid beacon interval value
 */
static uint16_t if_mgr_calculate_mcc_beacon_interval(uint16_t sta_bi,
						     uint16_t go_given_bi)
{
	uint8_t num_beacons, is_multiple;
	uint16_t go_calculated_bi, go_final_bi, sta_calculated_bi;

	/* ensure BI ranges between 100 and 200 */
	if (go_given_bi < 100)
		go_calculated_bi = 100;
	else
		go_calculated_bi = 100 + (go_given_bi % 100);

	if (sta_bi == 0) {
		/* There is possibility to receive zero as value.
		 * Which will cause divide by zero. Hence initialise with 100
		 */
		sta_bi = 100;
		ifmgr_warn("sta_bi 2nd parameter is zero, initialize to %d",
			   sta_bi);
	}
	/* check, if either one is multiple of another */
	if (sta_bi > go_calculated_bi)
		is_multiple = !(sta_bi % go_calculated_bi);
	else
		is_multiple = !(go_calculated_bi % sta_bi);

	/* if it is multiple, then accept GO's beacon interval
	 * range [100,199] as it is
	 */
	if (is_multiple)
		return go_calculated_bi;

	/* else , if it is not multiple, then then check for number of beacons
	 * to be inserted based on sta BI
	 */
	num_beacons = sta_bi / 100;
	if (num_beacons) {
		/* GO's final beacon interval will be aligned to sta beacon
		 * interval, but in the range of [100, 199].
		 */
		sta_calculated_bi = sta_bi / num_beacons;
		go_final_bi = sta_calculated_bi;
	} else {
		/* if STA beacon interval is less than 100, use GO's change
		 * beacon interval instead of updating to STA's beacon interval.
		 */
		go_final_bi = go_calculated_bi;
	}

	return go_final_bi;
}

static QDF_STATUS
if_mgr_send_chng_mcc_beacon_interval(struct wlan_objmgr_vdev *vdev,
				     struct beacon_interval_arg *bss_arg)
{
	struct scheduler_msg msg = {0};
	struct wlan_change_bi *p_msg;
	uint16_t len = 0;
	QDF_STATUS status;
	uint8_t *mac_addr;

	if (!bss_arg->update_beacon_interval)
		return QDF_STATUS_SUCCESS;

	bss_arg->update_beacon_interval = false;

	len = sizeof(*p_msg);
	p_msg = qdf_mem_malloc(len);
	if (!p_msg)
		return QDF_STATUS_E_NOMEM;

	p_msg->message_type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
	p_msg->length = len;

	mac_addr = wlan_vdev_get_hw_macaddr(vdev);
	qdf_mem_copy(&p_msg->bssid, mac_addr, QDF_MAC_ADDR_SIZE);
	ifmgr_debug(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
	p_msg->session_id = wlan_vdev_get_id(vdev);
	ifmgr_debug("session %d BeaconInterval %d", p_msg->session_id,
			bss_arg->bss_beacon_interval);
	p_msg->beacon_interval = bss_arg->bss_beacon_interval;

	msg.type = eWNI_SME_CHNG_MCC_BEACON_INTERVAL;
	msg.bodyval = 0;
	msg.bodyptr = p_msg;

	status = scheduler_post_message(QDF_MODULE_ID_PE,
					QDF_MODULE_ID_PE,
					QDF_MODULE_ID_PE, &msg);

	if (status != QDF_STATUS_SUCCESS)
		qdf_mem_free(p_msg);

	return status;
}

static void if_mgr_update_beacon_interval(struct wlan_objmgr_pdev *pdev,
					  void *object, void *arg)
{
	struct wlan_objmgr_psoc *psoc;
	uint8_t allow_mcc_go_diff_bi;
	struct wlan_objmgr_peer *peer;
	enum wlan_peer_type bss_persona;
	struct beacon_interval_arg *bss_arg = arg;
	struct wlan_objmgr_vdev *vdev = object;
	uint8_t vdev_id = wlan_vdev_get_id(vdev);

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

	policy_mgr_get_allow_mcc_go_diff_bi(psoc, &allow_mcc_go_diff_bi);

	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
	if (!peer)
		return;

	bss_persona = wlan_peer_get_peer_type(peer);

	wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);

	/*
	 * If GO in MCC support different beacon interval,
	 * change the BI of the P2P-GO
	 */
	if (bss_persona == WLAN_PEER_P2P_GO)
		return;
	/*
	 * Handle different BI scenario based on the
	 * configuration set. If Config is not set to 0x04 then
	 * Disconnect all the P2P clients associated. If config
	 * is set to 0x04 then update the BI without
	 * disconnecting all the clients
	 */
	if (allow_mcc_go_diff_bi == ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT &&
	    bss_arg->update_beacon_interval) {
		bss_arg->status =
			if_mgr_send_chng_mcc_beacon_interval(vdev, bss_arg);
		return;
	} else if (bss_arg->update_beacon_interval) {
		/*
		 * If the configuration of fAllowMCCGODiffBI is set to
		 * other than 0x04
		 */
		bss_arg->status = wlan_sap_disconnect_all_p2p_client(vdev_id);
		return;
	}
}

static QDF_STATUS
if_mgr_update_mcc_p2p_beacon_interval(struct wlan_objmgr_vdev *vdev,
				      struct beacon_interval_arg *bss_arg)
{
	struct wlan_objmgr_psoc *psoc;
	struct wlan_objmgr_pdev *pdev;
	uint8_t enable_mcc_mode;

	pdev = wlan_vdev_get_pdev(vdev);
	if (!pdev)
		return QDF_STATUS_E_FAILURE;

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

	/* If MCC is not supported just break and return SUCCESS */
	wlan_mlme_get_mcc_feature(psoc, &enable_mcc_mode);
	if (!enable_mcc_mode)
		return QDF_STATUS_E_FAILURE;

	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
					  if_mgr_update_beacon_interval,
					  bss_arg, 0, WLAN_IF_MGR_ID);

	return bss_arg->status;
}

static bool if_mgr_validate_sta_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
					   struct beacon_interval_arg *bss_arg)
{
	struct wlan_objmgr_psoc *psoc;
	struct vdev_mlme_obj *vdev_mlme;
	struct wlan_objmgr_peer *peer;
	uint16_t new_bcn_interval;
	uint32_t beacon_interval;
	struct wlan_channel *chan;
	enum QDF_OPMODE curr_persona;
	enum wlan_peer_type bss_persona;
	uint8_t allow_mcc_go_diff_bi;
	uint8_t conc_rule1 = 0, conc_rule2 = 0;
	uint8_t vdev_id = wlan_vdev_get_id(vdev);

	psoc = wlan_vdev_get_psoc(vdev);
	if (!psoc)
		return false;

	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
	if (!peer)
		return false;

	curr_persona = wlan_vdev_mlme_get_opmode(vdev);
	bss_persona = wlan_peer_get_peer_type(peer);

	wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);

	if (curr_persona == QDF_P2P_CLIENT_MODE) {
		ifmgr_debug("Bcn Intrvl validation not require for STA/CLIENT");
		return false;
	}

	chan = wlan_vdev_get_active_channel(vdev);
	if (!chan) {
		ifmgr_err("failed to get active channel");
		return false;
	}

	vdev_mlme =
		wlan_objmgr_vdev_get_comp_private_obj(vdev,
						      WLAN_UMAC_COMP_MLME);
	if (!vdev_mlme) {
		QDF_ASSERT(0);
		return false;
	}

	wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
				      &beacon_interval);

	if (bss_persona == WLAN_PEER_AP &&
	    (chan->ch_cfreq1 != bss_arg->ch_freq ||
	     chan->ch_cfreq2 != bss_arg->ch_freq)) {
		ifmgr_debug("*** MCC with SAP+STA sessions ****");
		bss_arg->status = QDF_STATUS_SUCCESS;
		return true;
	}

	if (bss_persona == WLAN_PEER_P2P_GO &&
	    (chan->ch_cfreq1 != bss_arg->ch_freq ||
	     chan->ch_cfreq2 != bss_arg->ch_freq) &&
	    beacon_interval != bss_arg->bss_beacon_interval) {
		policy_mgr_get_allow_mcc_go_diff_bi(psoc,
						    &allow_mcc_go_diff_bi);

		switch (allow_mcc_go_diff_bi) {
		case ALLOW_MCC_GO_DIFF_BI_WFA_CERT:
			bss_arg->status = QDF_STATUS_SUCCESS;
			return true;
		case ALLOW_MCC_GO_DIFF_BI_WORKAROUND:
			/* fall through */
		case ALLOW_MCC_GO_DIFF_BI_NO_DISCONNECT:
			policy_mgr_get_conc_rule1(psoc, &conc_rule1);
			policy_mgr_get_conc_rule2(psoc, &conc_rule2);
			if (conc_rule1 || conc_rule2)
				new_bcn_interval = CUSTOM_CONC_GO_BI;
			else
				new_bcn_interval =
					if_mgr_calculate_mcc_beacon_interval(
						bss_arg->bss_beacon_interval,
						beacon_interval);

			ifmgr_debug("Peer AP BI : %d, new Beacon Interval: %d",
				    bss_arg->bss_beacon_interval,
				    new_bcn_interval);

			/* Update the beacon interval */
			if (new_bcn_interval != beacon_interval) {
				ifmgr_err("Beacon Interval got changed config used: %d",
					  allow_mcc_go_diff_bi);
				bss_arg->bss_beacon_interval = new_bcn_interval;
				bss_arg->update_beacon_interval = true;
				bss_arg->status =
					if_mgr_update_mcc_p2p_beacon_interval(
								vdev,
								bss_arg);
				return true;
			}
			bss_arg->status = QDF_STATUS_SUCCESS;
			return true;
		case ALLOW_MCC_GO_DIFF_BI_TEAR_DOWN:
			bss_arg->update_beacon_interval = false;
			bss_arg->status = wlan_sap_stop_bss(vdev_id);
			return true;
		default:
			ifmgr_err("BcnIntrvl is diff can't connect to preferred AP");
			bss_arg->status = QDF_STATUS_E_FAILURE;
			return true;
		}
	}
	return false;
}

static bool if_mgr_validate_p2pcli_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
				       struct beacon_interval_arg *bss_arg)
{
	enum QDF_OPMODE curr_persona;
	enum wlan_peer_type bss_persona;
	uint32_t beacon_interval;
	struct wlan_channel *chan;
	struct wlan_objmgr_peer *peer;
	struct vdev_mlme_obj *vdev_mlme;

	curr_persona = wlan_vdev_mlme_get_opmode(vdev);

	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_IF_MGR_ID);
	if (!peer)
		return false;

	bss_persona = wlan_peer_get_peer_type(peer);

	wlan_objmgr_peer_release_ref(peer, WLAN_IF_MGR_ID);

	chan = wlan_vdev_get_active_channel(vdev);
	if (!chan) {
		ifmgr_err("failed to get active channel");
		return false;
	}

	vdev_mlme =
		wlan_objmgr_vdev_get_comp_private_obj(vdev,
						      WLAN_UMAC_COMP_MLME);
	if (!vdev_mlme) {
		QDF_ASSERT(0);
		return false;
	}

	wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
				      &beacon_interval);

	if (curr_persona == QDF_STA_MODE) {
		ifmgr_debug("Ignore Beacon Interval Validation...");
	} else if (bss_persona == WLAN_PEER_P2P_GO) {
		if ((chan->ch_cfreq1 != bss_arg->ch_freq ||
		     chan->ch_cfreq2 != bss_arg->ch_freq) &&
		    beacon_interval != bss_arg->bss_beacon_interval) {
			ifmgr_err("BcnIntrvl is diff can't connect to P2P_GO network");
			bss_arg->status = QDF_STATUS_E_FAILURE;
			return true;
		}
	}

	return false;
}

static bool
if_mgr_validate_p2pgo_bcn_intrvl(struct wlan_objmgr_vdev *vdev,
				 struct beacon_interval_arg *bss_arg)
{
	struct wlan_objmgr_psoc *psoc;
	struct vdev_mlme_obj *vdev_mlme;
	enum QDF_OPMODE curr_persona;
	uint32_t beacon_interval;
	struct wlan_channel *chan;
	uint8_t conc_rule1 = 0, conc_rule2 = 0;
	uint16_t new_bcn_interval;

	curr_persona = wlan_vdev_mlme_get_opmode(vdev);

	chan = wlan_vdev_get_active_channel(vdev);
	if (!chan) {
		ifmgr_err("failed to get active channel");
		return false;
	}

	vdev_mlme =
		wlan_objmgr_vdev_get_comp_private_obj(vdev,
						      WLAN_UMAC_COMP_MLME);
	if (!vdev_mlme) {
		QDF_ASSERT(0);
		return false;
	}

	psoc = wlan_vdev_get_psoc(vdev);
	if (!psoc)
		return false;

	wlan_util_vdev_mlme_get_param(vdev_mlme, WLAN_MLME_CFG_BEACON_INTERVAL,
				      &beacon_interval);

	if ((curr_persona == QDF_P2P_CLIENT_MODE) ||
	    (curr_persona == QDF_STA_MODE)) {
		/* check for P2P_client scenario */
		if ((chan->ch_cfreq1 == 0) && (chan->ch_cfreq2 == 0) &&
		    (beacon_interval == 0))
			return false;

		if (wlan_vdev_mlme_get_state(vdev) == WLAN_VDEV_S_UP &&
		    (chan->ch_cfreq1 != bss_arg->ch_freq ||
		     chan->ch_cfreq2 != bss_arg->ch_freq) &&
		    beacon_interval != bss_arg->bss_beacon_interval) {
			/*
			 * Updated beaconInterval should be used only when
			 * we are starting a new BSS not incase of
			 * client or STA case
			 */
			policy_mgr_get_conc_rule1(psoc, &conc_rule1);
			policy_mgr_get_conc_rule2(psoc, &conc_rule2);

			/* Calculate beacon Interval for P2P-GO incase of MCC */
			if (conc_rule1 || conc_rule2) {
				new_bcn_interval = CUSTOM_CONC_GO_BI;
			} else {
				new_bcn_interval =
					if_mgr_calculate_mcc_beacon_interval(
						beacon_interval,
						bss_arg->bss_beacon_interval);
			}
			if (new_bcn_interval != bss_arg->bss_beacon_interval)
				bss_arg->bss_beacon_interval = new_bcn_interval;
			bss_arg->status = QDF_STATUS_SUCCESS;
			return true;
		}
	}
	return false;
}

static void if_mgr_validate_beacon_interval(struct wlan_objmgr_pdev *pdev,
					    void *object, void *arg)
{
	struct beacon_interval_arg *bss_arg = arg;
	struct wlan_objmgr_vdev *vdev = object;
	uint8_t iter_vdev_id = wlan_vdev_get_id(vdev);
	bool is_done = false;

	if (iter_vdev_id == bss_arg->curr_vdev_id)
		return;

	if (wlan_vdev_mlme_get_state(vdev) != WLAN_VDEV_S_UP)
		return;

	if (bss_arg->is_done)
		return;

	switch (bss_arg->curr_bss_opmode) {
	case QDF_STA_MODE:
		is_done = if_mgr_validate_sta_bcn_intrvl(vdev, bss_arg);
		break;
	case QDF_P2P_CLIENT_MODE:
		is_done = if_mgr_validate_p2pcli_bcn_intrvl(vdev, bss_arg);
		break;
	case QDF_SAP_MODE:
	case QDF_IBSS_MODE:
		break;
	case QDF_P2P_GO_MODE:
		is_done = if_mgr_validate_p2pgo_bcn_intrvl(vdev, bss_arg);
		break;
	default:
		ifmgr_err("BSS opmode not supported: %d",
			  bss_arg->curr_bss_opmode);
	}

	if (is_done)
		bss_arg->is_done = is_done;
}

bool if_mgr_is_beacon_interval_valid(struct wlan_objmgr_pdev *pdev,
				     uint8_t vdev_id,
				     struct validate_bss_data *candidate)
{
	struct wlan_objmgr_psoc *psoc;
	struct beacon_interval_arg bss_arg;
	uint8_t enable_mcc_mode;
	struct wlan_objmgr_vdev *vdev;

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

	wlan_mlme_get_mcc_feature(psoc, &enable_mcc_mode);
	if (!enable_mcc_mode)
		return false;

	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
						    WLAN_IF_MGR_ID);
	if (!vdev)
		return false;

	bss_arg.curr_vdev_id = vdev_id;
	bss_arg.curr_bss_opmode = wlan_vdev_mlme_get_opmode(vdev);
	bss_arg.ch_freq = candidate->chan_freq;
	bss_arg.bss_beacon_interval = candidate->beacon_interval;
	bss_arg.is_done = false;

	wlan_objmgr_vdev_release_ref(vdev, WLAN_IF_MGR_ID);

	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
					  if_mgr_validate_beacon_interval,
					  &bss_arg, 0,
					  WLAN_IF_MGR_ID);

	if (!bss_arg.is_done)
		return true;

	if (bss_arg.bss_beacon_interval != candidate->beacon_interval) {
		candidate->beacon_interval = bss_arg.bss_beacon_interval;
		if (bss_arg.status == QDF_STATUS_SUCCESS)
			return true;
	}

	return false;
}

static void if_mgr_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
					  void *object, void *arg)
{
@@ -213,7 +729,10 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
	enum QDF_OPMODE op_mode;
	enum policy_mgr_con_mode mode;
	struct bssid_search_arg bssid_arg;
	uint32_t chan_freq = event_data->validate_bss_info.chan_freq;
	struct validate_bss_data *candidate_info =
		&event_data->validate_bss_info;
	uint32_t chan_freq = candidate_info->chan_freq;
	uint32_t conc_freq = 0;

	op_mode = wlan_vdev_mlme_get_opmode(vdev);

@@ -229,7 +748,7 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
	 * Ignore the BSS if any other vdev is already connected to it.
	 */
	qdf_copy_macaddr(&bssid_arg.peer_addr,
			 &event_data->validate_bss_info.peer_addr);
			 &candidate_info->peer_addr);
	bssid_arg.vdev_id = WLAN_INVALID_VDEV_ID;
	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
					  if_mgr_get_vdev_id_from_bssid,
@@ -253,7 +772,8 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
	if (!policy_mgr_is_concurrency_allowed(psoc, mode, chan_freq,
					       HW_MODE_20_MHZ)) {
		ifmgr_info("Concurrency not allowed for this channel freq %d bssid "QDF_MAC_ADDR_FMT", selecting next",
			   chan_freq, QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));
			   chan_freq,
			   QDF_MAC_ADDR_REF(bssid_arg.peer_addr.bytes));
		return QDF_STATUS_E_INVAL;
	}

@@ -268,5 +788,33 @@ QDF_STATUS if_mgr_validate_candidate(struct wlan_objmgr_vdev *vdev,
		return QDF_STATUS_E_INVAL;
	}

	/* validate beacon interval */
	if (policy_mgr_concurrent_open_sessions_running(psoc) &&
	    !if_mgr_is_beacon_interval_valid(pdev, wlan_vdev_get_id(vdev),
					     candidate_info)) {
		conc_freq = wlan_get_conc_freq();
		ifmgr_debug("csr Conc Channel freq: %d",
			    conc_freq);

		if (conc_freq) {
			if ((conc_freq == chan_freq) ||
			    (policy_mgr_is_hw_dbs_capable(psoc) &&
			    !wlan_reg_is_same_band_freqs(conc_freq,
							 chan_freq))) {
				/*
				 * make this 0 because we do not want the below
				 * check to pass as we don't want to connect on
				 * other channel
				 */
				ifmgr_debug("Conc chnl freq match: %d",
					    conc_freq);
				conc_freq = 0;
			}
		}
	}

	if (conc_freq)
		return QDF_STATUS_E_INVAL;

	return QDF_STATUS_SUCCESS;
}
+11 −5
Original line number Diff line number Diff line
@@ -1465,6 +1465,8 @@ struct policy_mgr_sme_cbacks {
 * @wlan_hdd_set_sap_csa_reason: Set the sap csa reason in cases like NAN.
 * @hdd_get_ap_6ghz_capable: get ap vdev 6ghz capable info from hdd ap adapter.
 * @wlan_hdd_indicate_active_ndp_cnt: indicate active ndp cnt to hdd
 * @wlan_get_ap_prefer_conc_ch_params: get prefer ap channel bw parameters
 *  based on target channel frequency and concurrent connections.
 */
struct policy_mgr_hdd_cbacks {
	void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc,
@@ -1486,6 +1488,10 @@ struct policy_mgr_hdd_cbacks {
					    uint8_t vdev_id);
	void (*wlan_hdd_indicate_active_ndp_cnt)(struct wlan_objmgr_psoc *psoc,
						 uint8_t vdev_id, uint8_t cnt);
	QDF_STATUS (*wlan_get_ap_prefer_conc_ch_params)(
			struct wlan_objmgr_psoc *psoc,
			uint8_t vdev_id, uint32_t chan_freq,
			struct ch_params *ch_params);
};


@@ -3194,18 +3200,18 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero(
		struct wlan_objmgr_psoc *psoc, uint32_t *pcl,
		uint32_t *len, uint8_t *weight_list, uint32_t weight_len);
/**
 * policy_mgr_is_sap_allowed_on_dfs_chan() - check if sap allowed on dfs channel
 * policy_mgr_is_sap_allowed_on_dfs_freq() - check if sap allowed on dfs freq
 * @pdev: id of objmgr pdev
 * @vdev_id: vdev id
 * @channel: channel number
 * @ch_freq: channel freq
 * This function is used to check if sta_sap_scc_on_dfs_chan ini is set,
 * DFS master capability is assumed disabled in the driver.
 *
 * Return: true if sap is allowed on dfs channel,
 * Return: true if sap is allowed on dfs freq,
 * otherwise false
 */
bool policy_mgr_is_sap_allowed_on_dfs_chan(struct wlan_objmgr_pdev *pdev,
					   uint8_t vdev_id, uint8_t channel);
bool policy_mgr_is_sap_allowed_on_dfs_freq(struct wlan_objmgr_pdev *pdev,
					   uint8_t vdev_id, qdf_freq_t ch_freq);
/**
 * policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc
 * allowed on dfs chan
+37 −4

File changed.

Preview size limit exceeded, changes collapsed.

Loading