qcacld-3.0: Take care of hw mode change in Connection mgr

Set hw mode before initiating connection request
and send vdev start to FW.

Change-Id: I76e17465b3e40762df62d6c08deb9066ff98a6a7
CRs-Fixed: 2763362
This commit is contained in:
gaurank kathpalia 2020-08-25 21:45:13 +05:30 • committed by snandini
commit 249f7a6467
4 changed files with 144 additions and 0 deletions

View file

@ -990,6 +990,23 @@ policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
enum policy_mgr_conn_update_reason,
uint32_t request_id);
/**
* policy_mgr_change_hw_mode_sta_connect() - Change HW mode for STA connect
* @psoc: psoc object
* @scan_list: candidates for conenction
* @vdev_id: vdev id for STA/CLI
* @connect_id: connect id of the conenct request
*
* When a new connection is about to come up, change hw mode for STA/CLI
* based upon the scan results and hw type.
*
* Return: status ifset HW mode is fail or already taken care of.
*/
QDF_STATUS
policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
qdf_list_t *scan_list, uint8_t vdev_id,
uint32_t connect_id);
/**
* policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current
* concurreny

View file

@ -905,6 +905,7 @@ enum policy_mgr_band {
* to the other DBS mode. This reason code indicates such condition.
* @POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY: NAN Discovery related
* @POLICY_MGR_UPDATE_REASON_NDP_UPDATE: NAN Datapath related update
* @POLICY_MGR_UPDATE_REASON_STA_CONNECT: STA/CLI connection to peer
*/
enum policy_mgr_conn_update_reason {
POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN,
@ -922,6 +923,7 @@ enum policy_mgr_conn_update_reason {
POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY,
POLICY_MGR_UPDATE_REASON_NDP_UPDATE,
POLICY_MGR_UPDATE_REASON_LFR2_ROAM,
POLICY_MGR_UPDATE_REASON_STA_CONNECT,
};
/**

View file

@ -907,6 +907,116 @@ policy_mgr_get_next_action(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
static bool
policy_mgr_is_hw_mode_change_required(struct wlan_objmgr_psoc *psoc,
uint32_t ch_freq, uint8_t vdev_id)
{
if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G)) {
if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))
return true;
} else {
if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) &&
policy_mgr_is_any_mode_active_on_band_along_with_session
(psoc, vdev_id, POLICY_MGR_BAND_5))
return true;
if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
policy_mgr_is_any_mode_active_on_band_along_with_session
(psoc, vdev_id, POLICY_MGR_BAND_24))
return true;
}
return false;
}
static uint32_t
policy_mgr_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
qdf_list_t *scan_list, uint8_t vdev_id)
{
struct scan_cache_node *scan_node = NULL;
qdf_list_node_t *cur_node = NULL, *next_node = NULL;
uint32_t ch_freq = 0;
struct scan_cache_entry *entry;
if (!scan_list || !qdf_list_size(scan_list)) {
policy_mgr_debug("Scan list is NULL or No BSSIDs present");
goto end;
}
if (!policy_mgr_is_hw_dbs_capable(psoc)) {
policy_mgr_debug("Driver isn't DBS capable");
goto end;
}
if (!policy_mgr_is_dbs_allowed_for_concurrency(psoc, QDF_STA_MODE)) {
policy_mgr_debug("DBS not allowed for concurrency combo");
goto end;
}
if (!policy_mgr_is_hw_dbs_2x2_capable(psoc) &&
!policy_mgr_is_hw_dbs_required_for_band(psoc,
HW_MODE_MAC_BAND_2G) &&
!policy_mgr_get_connection_count(psoc)) {
policy_mgr_debug("1x1 DBS with no existing connection, HW mode change not required");
goto end;
}
qdf_list_peek_front(scan_list, &cur_node);
while (cur_node) {
qdf_list_peek_next(scan_list, cur_node, &next_node);
scan_node = qdf_container_of(cur_node, struct scan_cache_node,
node);
entry = scan_node->entry;
ch_freq = entry->channel.chan_freq;
if (policy_mgr_is_hw_mode_change_required(psoc, ch_freq,
vdev_id)) {
policy_mgr_debug("Scan list has BSS of freq %d hw mode required",
ch_freq);
break;
}
cur_node = next_node;
next_node = NULL;
}
end:
return ch_freq;
}
QDF_STATUS
policy_mgr_change_hw_mode_sta_connect(struct wlan_objmgr_psoc *psoc,
qdf_list_t *scan_list, uint8_t vdev_id,
uint32_t connect_id)
{
QDF_STATUS status;
uint32_t ch_freq;
ch_freq = policy_mgr_check_for_hw_mode_change(psoc, scan_list, vdev_id);
if (!ch_freq)
return QDF_STATUS_E_ALREADY;
status = policy_mgr_current_connections_update(psoc, vdev_id, ch_freq,
POLICY_MGR_UPDATE_REASON_STA_CONNECT, connect_id);
/*
* If status is success then the callback of policy mgr hw mode change
* would be called.
* If status is no support then the DUT is already in required HW mode.
*/
if (status == QDF_STATUS_E_FAILURE)
policy_mgr_err("Hw mode change failed");
else if (status == QDF_STATUS_E_NOSUPPORT)
status = QDF_STATUS_E_ALREADY;
return status;
}
QDF_STATUS
policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc,
uint32_t session_id, uint32_t ch_freq,

View file

@ -67,6 +67,7 @@
#include "mac_init_api.h"
#include "wlan_cm_roam_api.h"
#include "wlan_cm_tgt_if_tx_api.h"
#include "wlan_cm_api.h"
static QDF_STATUS init_sme_cmd_list(struct mac_context *mac);
@ -161,6 +162,7 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t
enum policy_mgr_conn_update_reason reason;
struct csr_roam_session *session;
uint32_t session_id;
uint32_t request_id;
param = (struct sir_set_hw_mode_resp *)msg;
if (!param) {
@ -190,6 +192,7 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t
callback = command->u.set_hw_mode_cmd.set_hw_mode_cb;
reason = command->u.set_hw_mode_cmd.reason;
session_id = command->u.set_hw_mode_cmd.session_id;
request_id = command->u.set_hw_mode_cmd.request_id;
sme_debug("reason: %d session: %d",
command->u.set_hw_mode_cmd.reason,
@ -257,6 +260,18 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t
if (reason == POLICY_MGR_UPDATE_REASON_LFR2_ROAM)
csr_continue_lfr2_connect(mac, session_id);
if (reason == POLICY_MGR_UPDATE_REASON_STA_CONNECT) {
QDF_STATUS status = QDF_STATUS_E_FAILURE;
sme_info("Continue connect on vdev %d", session_id);
if (param->status == SET_HW_MODE_STATUS_OK ||
param->status == SET_HW_MODE_STATUS_ALREADY)
status = QDF_STATUS_SUCCESS;
wlan_cm_hw_mode_change_resp(mac->pdev, session_id, request_id,
status);
}
end:
found = csr_nonscan_active_ll_remove_entry(mac, entry,
LL_ACCESS_LOCK);