qcacmn: Add 2x2+1x1 DBS Action type

Add new DBS Action types and handle
the Actions in policy_mgr_next_actions
API.

Change-Id: Iccc62303383c0701955446a172ed956d1aea0e0f
CRs-Fixed: 2257692
This commit is contained in:
Liangwei Dong 2018-05-25 01:25:24 -04:00 • committed by nshrivas
commit 10a38dcc42
5 changed files with 328 additions and 29 deletions

View file

@ -1730,11 +1730,51 @@ bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc);
* DBS and there is no need for downgrading while entering DBS.
* true: DBS 2x2 can always be supported
* false: hw_modes support DBS 1x1 as well
* Genoa DBS 2x2 + 1x1 will not be included.
*
* Return: true - DBS2x2, false - DBS1x1
*/
bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc);
/*
* policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not
* @psoc: PSOC object data
*
* This routine is called to check 2x2 5G + 1x1 2G (DBS1) or
* 2x2 2G + 1x1 5G (DBS2) support or not.
* Either DBS1 or DBS2 supported
*
* Return: true/false
*/
bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc);
/*
* policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not
* @psoc: PSOC object data
*
* This routine is called to check support DBS1 or not.
* Notes: DBS1: 2x2 5G + 1x1 2G.
* This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match
* the HW mode from hw mode list. The parameters will also be matched to
* 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone
* with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with
* policy_mgr_get_hw_mode_idx_from_dbs_hw_list.
*
* Return: true/false
*/
bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc);
/*
* policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not
* @psoc: PSOC object data
*
* This routine is called to check support DBS2 or not.
* Notes: DBS2: 2x2 2G + 1x1 5G
*
* Return: true/false
*/
bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc);
/**
* policy_mgr_init() - Policy Manager component initialization
* routine

View file

@ -689,6 +689,12 @@ enum policy_mgr_two_connection_mode {
* @PM_SBS_DOWNGRADE: switch to SBS mode & downgrade to 1x1
* @PM_DOWNGRADE: downgrade to 1x1
* @PM_UPGRADE: upgrade to 2x2
* @PM_DBS1: switch to DBS 1
* @PM_DBS1_DOWNGRADE: downgrade 2G beaconing entity to 1x1 and switch to DBS1.
* @PM_DBS2: switch to DBS 2
* @PM_DBS2_DOWNGRADE: downgrade 5G beaconing entity to 1x1 and switch to DBS2.
* @PM_UPGRADE_5G: upgrade 5g beaconing entity to 2x2.
* @PM_UPGRADE_2G: upgrade 2g beaconing entity to 2x2.
* @PM_MAX_CONC_PRIORITY_MODE: Max place holder
*
* These are generic IDs that identify the various roles
@ -705,6 +711,12 @@ enum policy_mgr_conc_next_action {
PM_SBS_DOWNGRADE,
PM_DOWNGRADE,
PM_UPGRADE,
PM_DBS1,
PM_DBS1_DOWNGRADE,
PM_DBS2,
PM_DBS2_DOWNGRADE,
PM_UPGRADE_5G,
PM_UPGRADE_2G,
PM_MAX_CONC_NEXT_ACTION
};
@ -882,8 +894,10 @@ struct policy_mgr_conc_connection_info {
* @mac0_bw: MAC0 bandwidth
* @mac1_bw: MAC1 bandwidth
* @mac0_band_cap: mac0 band (5g/2g) capability
* @dbs_cap: DBS capability
* @agile_dfs_cap: Agile DFS capability
* @dbs_cap: DBS capabality
* @agile_dfs_cap: Agile DFS capabality
* @action_type: for dbs mode, the field indicates the "Action type" to be
* used to switch to the mode. To help the hw mode validation.
*/
struct policy_mgr_hw_mode_params {
uint8_t mac0_tx_ss;
@ -896,6 +910,7 @@ struct policy_mgr_hw_mode_params {
uint8_t dbs_cap;
uint8_t agile_dfs_cap;
uint8_t sbs_cap;
enum policy_mgr_conc_next_action action_type;
};
/**

View file

@ -620,14 +620,108 @@ done:
return status;
}
QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc,
/**
* policy_mgr_validate_dbs_switch() - Check DBS action valid or not
* @psoc: Pointer to psoc
* @session_id: vdev id
* @action: action requested
* @reason: reason of hw mode change
*
* This routine will check the current hw mode with requested action.
* If we are already in the mode, the caller will do nothing.
* This will be called by policy_mgr_next_actions to check the action needed
* or not.
*
* return : QDF_STATUS_SUCCESS, action is allowed.
* QDF_STATUS_E_ALREADY, action is not needed.
* QDF_STATUS_E_FAILURE, error happens.
* QDF_STATUS_E_NOSUPPORT, the requested mode not supported.
*/
static
QDF_STATUS policy_mgr_validate_dbs_switch(
struct wlan_objmgr_psoc *psoc,
uint32_t session_id,
enum policy_mgr_conc_next_action action,
enum policy_mgr_conn_update_reason reason)
{
QDF_STATUS status;
struct policy_mgr_hw_mode_params hw_mode;
/* check for the current HW index to see if really need any action */
status = policy_mgr_get_current_hw_mode(psoc, &hw_mode);
if (!QDF_IS_STATUS_SUCCESS(status)) {
policy_mgr_err("policy_mgr_get_current_hw_mode failed");
return status;
}
if (hw_mode.sbs_cap) {
if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) {
if (!policy_mgr_is_hw_sbs_capable(psoc)) {
/* No action */
policy_mgr_notice("firmware is not sbs capable");
return QDF_STATUS_E_NOSUPPORT;
}
/* current mode is already SBS nothing to be
* done
*/
policy_mgr_notice("current mode is already SBS");
return QDF_STATUS_E_ALREADY;
} else {
return QDF_STATUS_SUCCESS;
}
}
if (!hw_mode.dbs_cap) {
if (action == PM_SINGLE_MAC ||
action == PM_SINGLE_MAC_UPGRADE) {
policy_mgr_notice("current mode is already single MAC");
return QDF_STATUS_E_ALREADY;
} else {
return QDF_STATUS_SUCCESS;
}
}
/**
* If already in DBS, no need to request DBS again (HL, Napier).
* For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1
* switching, we need to check the current DBS mode is same as
* requested or not.
*/
if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) ||
policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) {
policy_mgr_info("curr dbs action %d new action %d",
hw_mode.action_type, action);
if (hw_mode.action_type == PM_DBS1 &&
((action == PM_DBS1 ||
action == PM_DBS1_DOWNGRADE))) {
policy_mgr_err("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed",
hw_mode.action_type, action);
return QDF_STATUS_E_ALREADY;
} else if (hw_mode.action_type == PM_DBS2 &&
((action == PM_DBS2 ||
action == PM_DBS2_DOWNGRADE))) {
policy_mgr_err("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed",
hw_mode.action_type, action);
return QDF_STATUS_E_ALREADY;
}
} else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) ||
(action == PM_DBS_UPGRADE)) {
policy_mgr_err("driver is already in %s mode, no further action needed",
(hw_mode.dbs_cap) ? "dbs" : "non dbs");
return QDF_STATUS_E_ALREADY;
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS policy_mgr_next_actions(
struct wlan_objmgr_psoc *psoc,
uint32_t session_id,
enum policy_mgr_conc_next_action action,
enum policy_mgr_conn_update_reason reason)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
struct policy_mgr_hw_mode_params hw_mode;
struct dbs_nss nss_dbs = {0};
struct policy_mgr_hw_mode_params hw_mode;
enum policy_mgr_conc_next_action next_action;
if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
policy_mgr_err("driver isn't dbs capable, no further action needed");
@ -640,28 +734,14 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc,
policy_mgr_err("policy_mgr_get_current_hw_mode failed");
return status;
}
/**
* if already in DBS no need to request DBS. Might be needed
* to extend the logic when multiple dbs HW mode is available
*/
if ((((PM_DBS_DOWNGRADE == action) || (PM_DBS == action) ||
(PM_DBS_UPGRADE == action))
&& hw_mode.dbs_cap)) {
policy_mgr_err("driver is already in %s mode, no further action needed",
(hw_mode.dbs_cap) ? "dbs" : "non dbs");
return QDF_STATUS_E_ALREADY;
}
if ((PM_SBS == action) || (action == PM_SBS_DOWNGRADE)) {
if (!policy_mgr_is_hw_sbs_capable(psoc)) {
/* No action */
policy_mgr_notice("firmware is not sbs capable");
return QDF_STATUS_E_NOSUPPORT;
}
/* check if current mode is already SBS nothing to be
* done
*/
/* check for the current HW index to see if really need any action */
status = policy_mgr_validate_dbs_switch(psoc, session_id, action,
reason);
if (!QDF_IS_STATUS_SUCCESS(status)) {
policy_mgr_err(" not take action %d reason %d session %d status %d",
action, reason, session_id, status);
return status;
}
switch (action) {
@ -755,6 +835,70 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc,
status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2,
PM_NOP, POLICY_MGR_ANY, reason);
break;
case PM_DBS1_DOWNGRADE:
status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
PM_DBS1, reason,
session_id);
break;
case PM_DBS2_DOWNGRADE:
status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1,
PM_DBS2, reason,
session_id);
break;
case PM_DBS1:
/*
* PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous
* mode is DBS, that should be 2x2 2G + 1x1 5G mode and
* the 5G band was downgraded to 1x1. So, we need to
* upgrade 5G vdevs after hw mode change.
*/
if (hw_mode.dbs_cap)
next_action = PM_UPGRADE_5G;
else
next_action = PM_NOP;
status = policy_mgr_pdev_set_hw_mode(
psoc, session_id,
HW_MODE_SS_2x2,
HW_MODE_80_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
HW_MODE_MAC_BAND_5G,
HW_MODE_DBS,
HW_MODE_AGILE_DFS_NONE,
HW_MODE_SBS_NONE,
reason, next_action);
break;
case PM_DBS2:
/*
* PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous
* mode is DBS, that should be 2x2 5G + 1x1 2G mode and
* the 2G band was downgraded to 1x1. So, we need to
* upgrade 5G vdevs after hw mode change.
*/
if (hw_mode.dbs_cap)
next_action = PM_UPGRADE_2G;
else
next_action = PM_NOP;
status = policy_mgr_pdev_set_hw_mode(
psoc, session_id,
HW_MODE_SS_2x2,
HW_MODE_40_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
HW_MODE_MAC_BAND_2G,
HW_MODE_DBS,
HW_MODE_AGILE_DFS_NONE,
HW_MODE_SBS_NONE,
reason, next_action);
break;
case PM_UPGRADE_5G:
status = policy_mgr_nss_update(
psoc, POLICY_MGR_RX_NSS_2,
PM_NOP, POLICY_MGR_BAND_5, reason);
break;
case PM_UPGRADE_2G:
status = policy_mgr_nss_update(
psoc, POLICY_MGR_RX_NSS_2,
PM_NOP, POLICY_MGR_BAND_24, reason);
break;
default:
policy_mgr_err("unexpected action value %d", action);
status = QDF_STATUS_E_FAILURE;

View file

@ -480,6 +480,8 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx(
{
uint32_t param;
struct policy_mgr_psoc_priv_obj *pm_ctx;
uint8_t mac0_min_ss;
uint8_t mac1_min_ss;
uint32_t i, hw_mode_id;
pm_ctx = policy_mgr_get_context(psoc);
@ -514,7 +516,20 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx(
hw_mode->dbs_cap = POLICY_MGR_HW_MODE_DBS_MODE_GET(param);
hw_mode->agile_dfs_cap = POLICY_MGR_HW_MODE_AGILE_DFS_GET(param);
hw_mode->sbs_cap = POLICY_MGR_HW_MODE_SBS_MODE_GET(param);
if (hw_mode->dbs_cap) {
mac0_min_ss = QDF_MIN(hw_mode->mac0_tx_ss, hw_mode->mac0_rx_ss);
mac1_min_ss = QDF_MIN(hw_mode->mac1_tx_ss, hw_mode->mac1_rx_ss);
if (hw_mode->mac0_band_cap == WLAN_5G_CAPABILITY &&
mac0_min_ss && mac1_min_ss &&
mac0_min_ss > mac1_min_ss)
hw_mode->action_type = PM_DBS1;
else if (hw_mode->mac0_band_cap == WLAN_2G_CAPABILITY &&
mac0_min_ss && mac1_min_ss &&
mac0_min_ss > mac1_min_ss)
hw_mode->action_type = PM_DBS2;
else
hw_mode->action_type = PM_DBS;
}
return QDF_STATUS_SUCCESS;
}
@ -2613,6 +2628,7 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc,
uint32_t session_id)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
enum policy_mgr_band downgrade_band;
if (policy_mgr_is_hw_dbs_capable(psoc) == false) {
policy_mgr_err("driver isn't dbs capable, no further action needed");
@ -2624,8 +2640,15 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc,
* protection. So, not taking any lock inside
* policy_mgr_complete_action() during pm_conc_connection_list access.
*/
if (next_action == PM_DBS1)
downgrade_band = POLICY_MGR_BAND_24;
else if (next_action == PM_DBS2)
downgrade_band = POLICY_MGR_BAND_5;
else
downgrade_band = POLICY_MGR_ANY;
status = policy_mgr_nss_update(psoc, new_nss, next_action,
POLICY_MGR_ANY, reason);
downgrade_band, reason);
if (!QDF_IS_STATUS_SUCCESS(status))
status = policy_mgr_next_actions(psoc, session_id,
next_action, reason);

View file

@ -769,9 +769,86 @@ bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc)
bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc)
{
struct dbs_nss nss_dbs;
uint32_t nss;
return ((policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs)) >= HW_MODE_SS_2x2)
? true : false;
nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss == nss_dbs.mac1_ss))
return true;
else
return false;
}
/*
* policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not
* @psoc: PSOC object data
*
* This routine is called to check 2x2 5G + 1x1 2G (DBS1) or
* 2x2 2G + 1x1 5G (DBS2) support or not.
* Either DBS1 or DBS2 supported
*
* Return: true/false
*/
bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc)
{
struct dbs_nss nss_dbs;
uint32_t nss;
nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs);
if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss > nss_dbs.mac1_ss))
return true;
else
return false;
}
/*
* policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not
* @psoc: PSOC object data
*
* This routine is called to check support DBS1 or not.
* Notes: DBS1: 2x2 5G + 1x1 2G.
* This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match
* the HW mode from hw mode list. The parameters will also be matched to
* 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone
* with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with
* policy_mgr_get_hw_mode_idx_from_dbs_hw_list.
*
* Return: true/false
*/
bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc)
{
return policy_mgr_is_2x2_1x1_dbs_capable(psoc) &&
(policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
psoc,
HW_MODE_SS_2x2,
HW_MODE_80_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
HW_MODE_MAC_BAND_5G,
HW_MODE_DBS,
HW_MODE_AGILE_DFS_NONE,
HW_MODE_SBS_NONE) >= 0);
}
/*
* policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not
* @psoc: PSOC object data
*
* This routine is called to check support DBS2 or not.
* Notes: DBS2: 2x2 2G + 1x1 5G
*
* Return: true/false
*/
bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc)
{
return policy_mgr_is_2x2_1x1_dbs_capable(psoc) &&
(policy_mgr_get_hw_mode_idx_from_dbs_hw_list(
psoc,
HW_MODE_SS_2x2,
HW_MODE_40_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
HW_MODE_MAC_BAND_2G,
HW_MODE_DBS,
HW_MODE_AGILE_DFS_NONE,
HW_MODE_SBS_NONE) >= 0);
}
uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc)