qcacld-3.0: Replace WMI_SOC_SET_PCL_CMDID with WMI_PDEV_SET_PCL_CMDID

Replace the obsolete WMI command WMI_SOC_SET_PCL_CMDID with
WMI_PDEV_SET_PCL_CMDID. WMI_PDEV_SET_PCL_CMDID carries the weightage
for all the channels (preferred and non-preferred) in the same order
and length as that of the command WMI_SCAN_CHAN_LIST_CMDID. This is
in contrast to the command WMI_SOC_SET_PCL_CMDID which carries only
the preferred channel list.

Change-Id: I040f4307491d3242d2e9409dbbe8005c4b307bf5
CRs-Fixed: 989502
This commit is contained in:
Manishekar Chandrasekaran 2016-04-21 19:14:15 +05:30 • committed by Gerrit - the friendly Code Review server
commit 7009f25399
15 changed files with 411 additions and 85 deletions

View file

@ -47,6 +47,51 @@
#define CONNECTION_UPDATE_TIMEOUT 1000
#endif
/* Some max value greater than the max length of the channel list */
#define MAX_WEIGHT_OF_PCL_CHANNELS 255
/* Some fixed weight difference between the groups */
#define PCL_GROUPS_WEIGHT_DIFFERENCE 20
/* Currently max, only 3 groups are possible as per 'enum cds_pcl_type'.
* i.e., in a PCL only 3 groups of channels can be present
* e.g., SCC channel on 2.4 Ghz, SCC channel on 5 Ghz & 5 Ghz channels.
* Group 1 has highest priority, group 2 has the next higher priority
* and so on.
*/
#define WEIGHT_OF_GROUP1_PCL_CHANNELS MAX_WEIGHT_OF_PCL_CHANNELS
#define WEIGHT_OF_GROUP2_PCL_CHANNELS \
(WEIGHT_OF_GROUP1_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE)
#define WEIGHT_OF_GROUP3_PCL_CHANNELS \
(WEIGHT_OF_GROUP2_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE)
#define WEIGHT_OF_NON_PCL_CHANNELS 1
/**
* enum cds_pcl_group_id - Identifies the pcl groups to be used
* @CDS_PCL_GROUP_ID1_ID2: Use weights of group1 and group2
* @CDS_PCL_GROUP_ID2_ID2: Use weights of group2 and group3
*
* Since maximum of three groups are possible, this will indicate which
* PCL group needs to be used.
*/
enum cds_pcl_group_id {
CDS_PCL_GROUP_ID1_ID2,
CDS_PCL_GROUP_ID2_ID3,
};
/**
* cds_pcl_channel_order - Order in which the PCL is requested
* @CDS_PCL_ORDER_NONE: no order
* @CDS_PCL_ORDER_24G_THEN_5G: 2.4 Ghz channel followed by 5 Ghz channel
* @CDS_PCL_ORDER_5G_THEN_2G: 5 Ghz channel followed by 2.4 Ghz channel
*
* Order in which the PCL is requested
*/
enum cds_pcl_channel_order {
CDS_PCL_ORDER_NONE,
CDS_PCL_ORDER_24G_THEN_5G,
CDS_PCL_ORDER_5G_THEN_2G,
};
/**
* enum cds_max_rx_ss - Maximum number of receive spatial streams
@ -588,7 +633,8 @@ void cds_decr_session_set_pcl(enum tQDF_ADAPTER_MODE mode,
QDF_STATUS cds_init_policy_mgr(void);
QDF_STATUS cds_deinit_policy_mgr(void);
QDF_STATUS cds_get_pcl(enum cds_con_mode mode,
uint8_t *pcl_Channels, uint32_t *len);
uint8_t *pcl_channels, uint32_t *len,
uint8_t *pcl_weight, uint32_t weight_len);
uint8_t cds_get_nondfs_preferred_channel(enum cds_con_mode mode,
bool for_existing_conn);
bool cds_is_any_nondfs_chnl_present(uint8_t *channel);
@ -697,5 +743,7 @@ QDF_STATUS cds_register_sap_restart_channel_switch_cb(
void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t));
#endif
QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode,
uint8_t *pcl_ch, uint32_t *len);
uint8_t *pcl_ch, uint32_t *len,
uint8_t *weight_list, uint32_t weight_len);
QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight);
#endif /* __CDS_CONCURRENCY_H */

View file

@ -3438,16 +3438,16 @@ void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode)
}
/**
* cds_soc_set_pcl() - Sets PCL to FW
* cds_pdev_set_pcl() - Sets PCL to FW
* @mode: adapter mode
*
* Fetches the PCL and sends the PCL to SME
* module which in turn will send the WMI
* command WMI_SOC_SET_PCL_CMDID to the fw
* command WMI_PDEV_SET_PCL_CMDID to the fw
*
* Return: None
*/
static void cds_soc_set_pcl(enum tQDF_ADAPTER_MODE mode)
static void cds_pdev_set_pcl(enum tQDF_ADAPTER_MODE mode)
{
QDF_STATUS status;
enum cds_con_mode con_mode;
@ -3485,13 +3485,14 @@ static void cds_soc_set_pcl(enum tQDF_ADAPTER_MODE mode)
cds_debug("get pcl to set it to the FW");
status = cds_get_pcl(con_mode,
pcl.pcl_list, &pcl.pcl_len);
pcl.pcl_list, &pcl.pcl_len,
pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
if (status != QDF_STATUS_SUCCESS) {
cds_err("Unable to set PCL to FW, Get PCL failed");
return;
}
status = sme_soc_set_pcl(hdd_ctx->hHal, pcl);
status = sme_pdev_set_pcl(hdd_ctx->hHal, pcl);
if (status != QDF_STATUS_SUCCESS)
cds_err("Send soc set PCL to SME failed");
else
@ -3552,7 +3553,7 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode,
*/
if (mode == QDF_STA_MODE) {
/* Set PCL of STA to the FW */
cds_soc_set_pcl(mode);
cds_pdev_set_pcl(mode);
cds_info("Set PCL of STA to FW");
}
cds_incr_connection_count(session_id);
@ -3671,7 +3672,7 @@ static void cds_set_pcl_for_existing_combo(enum cds_con_mode mode)
/* Check, store and temp delete the mode's parameter */
cds_store_and_del_conn_info(mode, &info);
/* Set the PCL to the FW since connection got updated */
cds_soc_set_pcl(pcl_mode);
cds_pdev_set_pcl(pcl_mode);
cds_info("Set PCL to FW for mode:%d", mode);
/* Restore the connection info */
cds_restore_deleted_conn_info(&info);
@ -3681,13 +3682,18 @@ static void cds_set_pcl_for_existing_combo(enum cds_con_mode mode)
/**
* cds_get_pcl_for_existing_conn() - Get PCL for existing connection
* @mode: Connection mode of type 'cds_con_mode'
* @pcl_ch: Pointer to the PCL
* @len: Pointer to the length of the PCL
* @pcl_weight: Pointer to the weights of the PCL
* @weight_len: Max length of the weights list
*
* Get the PCL for an existing connection
*
* Return: None
*/
QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode,
uint8_t *pcl_ch, uint32_t *len)
uint8_t *pcl_ch, uint32_t *len,
uint8_t *pcl_weight, uint32_t weight_len)
{
struct cds_conc_connection_info info;
@ -3703,7 +3709,7 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode,
/* Check, store and temp delete the mode's parameter */
cds_store_and_del_conn_info(mode, &info);
/* Set the PCL to the FW since connection got updated */
status = cds_get_pcl(mode, pcl_ch, len);
status = cds_get_pcl(mode, pcl_ch, len, pcl_weight, weight_len);
cds_info("Get PCL to FW for mode:%d", mode);
/* Restore the connection info */
cds_restore_deleted_conn_info(&info);
@ -4289,6 +4295,10 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id)
* @order: no order OR 2.4 Ghz channel followed by 5 Ghz
* channel OR 5 Ghz channel followed by 2.4 Ghz channel
* @skip_dfs_channel: if this flag is true then skip the dfs channel
* @pcl_weight: Pointer to the weights of PCL
* @weight_len: Max length of the weight list
* @index: Index from which the weight list needs to be populated
* @group_id: Next available groups for weight assignment
*
*
* This function provides the channel(s) on which current
@ -4297,11 +4307,14 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id)
* Return: QDF_STATUS
*/
QDF_STATUS cds_get_connection_channels(uint8_t *channels,
uint32_t *len, uint8_t order,
bool skip_dfs_channel)
uint32_t *len, enum cds_pcl_channel_order order,
bool skip_dfs_channel,
uint8_t *pcl_weight, uint32_t weight_len,
uint32_t *index, enum cds_pcl_group_id group_id)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
uint32_t conn_index = 0, num_channels = 0;
uint32_t weight1, weight2;
if ((NULL == channels) || (NULL == len)) {
cds_err("channels or len is NULL");
@ -4309,58 +4322,99 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
return status;
}
if (0 == order) {
/* CDS_PCL_GROUP_ID1_ID2 indicates that all three weights are
* available for assignment. i.e., WEIGHT_OF_GROUP1_PCL_CHANNELS,
* WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS
* are all available. Since in this function only two weights are
* assigned at max, only group1 and group2 weights are considered.
*
* The other possible group id CDS_PCL_GROUP_ID2_ID3 indicates that
* group1 was assigned the weight WEIGHT_OF_GROUP1_PCL_CHANNELS and
* only weights WEIGHT_OF_GROUP2_PCL_CHANNELS and
* WEIGHT_OF_GROUP3_PCL_CHANNELS are available for further weight
* assignments.
*
* e.g., when order is CDS_PCL_ORDER_24G_THEN_5G and group id is
* CDS_PCL_GROUP_ID2_ID3, WEIGHT_OF_GROUP2_PCL_CHANNELS is assigned to
* 2.4GHz channels and the weight WEIGHT_OF_GROUP3_PCL_CHANNELS is
* assigned to the 5GHz channels.
*/
if (group_id == CDS_PCL_GROUP_ID1_ID2) {
weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS;
weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
} else {
weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS;
weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
}
if (CDS_PCL_ORDER_NONE == order) {
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (skip_dfs_channel && CDS_IS_DFS_CH(
conc_connection_list[conn_index].chan))
conc_connection_list[conn_index].chan)) {
conn_index++;
else
} else {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
if (*index < weight_len)
pcl_weight[(*index)++] = weight1;
}
}
*len = num_channels;
} else if (1 == order) {
} else if (CDS_PCL_ORDER_24G_THEN_5G == order) {
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[conn_index].chan))
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
else
if (*index < weight_len)
pcl_weight[(*index)++] = weight1;
} else {
conn_index++;
}
}
conn_index = 0;
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (skip_dfs_channel && CDS_IS_DFS_CH(
conc_connection_list[conn_index].chan))
conc_connection_list[conn_index].chan)) {
conn_index++;
else if (CDS_IS_CHANNEL_5GHZ(
conc_connection_list[conn_index].chan))
} else if (CDS_IS_CHANNEL_5GHZ(
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
else
if (*index < weight_len)
pcl_weight[(*index)++] = weight2;
} else {
conn_index++;
}
}
*len = num_channels;
} else if (2 == order) {
} else if (CDS_PCL_ORDER_5G_THEN_2G == order) {
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (skip_dfs_channel && CDS_IS_DFS_CH(
conc_connection_list[conn_index].chan))
conc_connection_list[conn_index].chan)) {
conn_index++;
else if (CDS_IS_CHANNEL_5GHZ(
conc_connection_list[conn_index].chan))
} else if (CDS_IS_CHANNEL_5GHZ(
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
else
if (*index < weight_len)
pcl_weight[(*index)++] = weight1;
} else {
conn_index++;
}
}
conn_index = 0;
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (CDS_IS_CHANNEL_24GHZ(
conc_connection_list[conn_index].chan))
conc_connection_list[conn_index].chan)) {
channels[num_channels++] =
conc_connection_list[conn_index++].chan;
else
if (*index < weight_len)
pcl_weight[(*index)++] = weight2;
} else {
conn_index++;
}
}
*len = num_channels;
} else {
@ -4376,6 +4430,8 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
* channel list
* @pcl_channels: channel list
* @len: length of the list
* @weight_list: Weights of the PCL
* @weight_len: Max length of the weights list
*
* This function provides the safe channel list from the list
* provided after consulting the channel avoidance list
@ -4383,10 +4439,12 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
* Return: None
*/
#ifdef CONFIG_CNSS
void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len,
uint8_t *weight_list, uint32_t weight_len)
{
uint16_t unsafe_channel_list[MAX_NUM_CHAN];
uint8_t current_channel_list[MAX_NUM_CHAN];
uint8_t org_weight_list[MAX_NUM_CHAN];
uint16_t unsafe_channel_count = 0;
uint8_t is_unsafe = 1;
uint8_t i, j;
@ -4409,6 +4467,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
qdf_mem_zero(pcl_channels,
sizeof(*pcl_channels)*current_channel_count);
qdf_mem_copy(org_weight_list, weight_list, MAX_NUM_CHAN);
qdf_mem_zero(weight_list, weight_len);
for (i = 0; i < current_channel_count; i++) {
is_unsafe = 0;
for (j = 0; j < unsafe_channel_count; j++) {
@ -4424,6 +4485,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
if (!is_unsafe) {
pcl_channels[safe_channel_count++] =
current_channel_list[i];
if (safe_channel_count < weight_len)
weight_list[safe_channel_count++] =
org_weight_list[i];
}
}
*len = safe_channel_count;
@ -4431,7 +4495,8 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
return;
}
#else
void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len,
uint8_t *weight_list, uint32_t weight_len)
{
return;
}
@ -4439,11 +4504,12 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
/**
* cds_get_channel_list() - provides the channel list
* suggestion for new connection
* @hdd_ctx: HDD Context
* @pcl: The preferred channel list enum
* @pcl_channels: PCL channels
* @len: length of the PCL
* @mode: concurrency mode for which channel list is requested
* @pcl_weights: Weights of the PCL
* @weight_len: Max length of the weight list
*
* This function provides the actual channel list based on the
* current regulatory domain derived using preferred channel
@ -4452,7 +4518,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len)
* Return: Channel List
*/
QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
uint8_t *pcl_channels, uint32_t *len, enum cds_con_mode mode)
uint8_t *pcl_channels, uint32_t *len,
enum cds_con_mode mode,
uint8_t *pcl_weights, uint32_t weight_len)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
uint32_t num_channels = WNI_CFG_VALID_CHANNEL_LIST_LEN;
@ -4462,6 +4530,7 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
uint8_t channel_list_5[MAX_NUM_CHAN] = {0};
bool skip_dfs_channel = false;
hdd_context_t *hdd_ctx;
uint32_t i = 0, j = 0;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@ -4529,23 +4598,61 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
}
num_channels = 0;
/* In the below switch case, the channel list is populated based on the
* pcl. e.g., if the pcl is CDS_SCC_CH_24G, the SCC channel group is
* populated first followed by the 2.4GHz channel group. Along with
* this, the weights are also populated in the same order for each of
* these groups. There are three weight groups:
* WEIGHT_OF_GROUP1_PCL_CHANNELS, WEIGHT_OF_GROUP2_PCL_CHANNELS and
* WEIGHT_OF_GROUP3_PCL_CHANNELS.
*
* e.g., if pcl is CDS_SCC_ON_5_SCC_ON_24_24G: scc on 5GHz (group1)
* channels take the weight WEIGHT_OF_GROUP1_PCL_CHANNELS, scc on 2.4GHz
* (group2) channels take the weight WEIGHT_OF_GROUP2_PCL_CHANNELS and
* 2.4GHz (group3) channels take the weight
* WEIGHT_OF_GROUP3_PCL_CHANNELS.
*
* When the weight to be assigned to the group is known along with the
* number of channels, the weights are directly assigned to the
* pcl_weights list. But, the channel list is populated using
* cds_get_connection_channels(), the order of weights to be used is
* passed as an argument to the function cds_get_connection_channels()
* using 'enum cds_pcl_group_id' which indicates the next available
* weights to be used and cds_get_connection_channels() will take care
* of the weight assignments.
*
* e.g., 'enum cds_pcl_group_id' value of CDS_PCL_GROUP_ID2_ID3
* indicates that the next available groups for weight assignment are
* WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS and
* that the weight WEIGHT_OF_GROUP1_PCL_CHANNELS was already allocated.
* So, in the same example, when order is CDS_PCL_ORDER_24G_THEN_5G,
* cds_get_connection_channels() will assign the weight
* WEIGHT_OF_GROUP2_PCL_CHANNELS to 2.4GHz channels and assign the
* weight WEIGHT_OF_GROUP3_PCL_CHANNELS to 5GHz channels.
*/
switch (pcl) {
case CDS_24G:
qdf_mem_copy(pcl_channels, channel_list_24,
chan_index_24);
*len = chan_index_24;
for (i = 0; ((i < *len) && (i < weight_len)); i++)
pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
case CDS_5G:
qdf_mem_copy(pcl_channels, channel_list_5,
chan_index_5);
*len = chan_index_5;
for (i = 0; ((i < *len) && (i < weight_len)); i++)
pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
case CDS_SCC_CH:
case CDS_MCC_CH:
cds_get_connection_channels(
channel_list, &num_channels, 0, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_NONE,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
status = QDF_STATUS_SUCCESS;
@ -4553,24 +4660,33 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
case CDS_SCC_CH_24G:
case CDS_MCC_CH_24G:
cds_get_connection_channels(
channel_list, &num_channels, 0, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_NONE,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
qdf_mem_copy(&pcl_channels[num_channels],
channel_list_24, chan_index_24);
*len += chan_index_24;
for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++)
pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
case CDS_SCC_CH_5G:
case CDS_MCC_CH_5G:
cds_get_connection_channels(
channel_list, &num_channels, 0, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_NONE,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list,
num_channels);
*len = num_channels;
qdf_mem_copy(&pcl_channels[num_channels],
channel_list_5, chan_index_5);
*len += chan_index_5;
for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++)
pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
case CDS_24G_SCC_CH:
@ -4578,8 +4694,12 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
qdf_mem_copy(pcl_channels, channel_list_24,
chan_index_24);
*len = chan_index_24;
for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++)
pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
cds_get_connection_channels(
channel_list, &num_channels, 0, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_NONE,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID2_ID3);
qdf_mem_copy(&pcl_channels[chan_index_24],
channel_list, num_channels);
*len += num_channels;
@ -4590,8 +4710,12 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
qdf_mem_copy(pcl_channels, channel_list_5,
chan_index_5);
*len = chan_index_5;
for (i = 0; ((i < chan_index_5) && (i < weight_len)); i++)
pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS;
cds_get_connection_channels(
channel_list, &num_channels, 0, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_NONE,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID2_ID3);
qdf_mem_copy(&pcl_channels[chan_index_5],
channel_list, num_channels);
*len += num_channels;
@ -4599,7 +4723,9 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
break;
case CDS_SCC_ON_24_SCC_ON_5:
cds_get_connection_channels(
channel_list, &num_channels, 1, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list,
num_channels);
*len = num_channels;
@ -4607,49 +4733,67 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
break;
case CDS_SCC_ON_5_SCC_ON_24:
cds_get_connection_channels(
channel_list, &num_channels, 2, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
status = QDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_24_SCC_ON_5_24G:
cds_get_connection_channels(
channel_list, &num_channels, 1, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
qdf_mem_copy(&pcl_channels[num_channels],
channel_list_24, chan_index_24);
*len += chan_index_24;
for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++)
pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_24_SCC_ON_5_5G:
cds_get_connection_channels(
channel_list, &num_channels, 1, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
qdf_mem_copy(&pcl_channels[num_channels],
channel_list_5, chan_index_5);
*len += chan_index_5;
for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++)
pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_5_SCC_ON_24_24G:
cds_get_connection_channels(
channel_list, &num_channels, 2, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
qdf_mem_copy(&pcl_channels[num_channels],
channel_list_24, chan_index_24);
*len += chan_index_24;
for (j = 0; ((j < chan_index_24) && (i < weight_len)); i++, j++)
pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
case CDS_SCC_ON_5_SCC_ON_24_5G:
cds_get_connection_channels(
channel_list, &num_channels, 2, skip_dfs_channel);
channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G,
skip_dfs_channel, pcl_weights, weight_len, &i,
CDS_PCL_GROUP_ID1_ID2);
qdf_mem_copy(pcl_channels, channel_list, num_channels);
*len = num_channels;
qdf_mem_copy(&pcl_channels[num_channels],
channel_list_5, chan_index_5);
*len += chan_index_5;
for (j = 0; ((j < chan_index_5) && (i < weight_len)); i++, j++)
pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS;
status = QDF_STATUS_SUCCESS;
break;
default:
@ -4657,8 +4801,13 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl,
break;
}
if ((*len != 0) && (*len != i))
cds_info("pcl len (%d) and weight list len mismatch (%d)",
*len, i);
/* check the channel avoidance list */
cds_update_with_safe_channel_list(pcl_channels, len);
cds_update_with_safe_channel_list(pcl_channels, len,
pcl_weights, weight_len);
return status;
}
@ -4708,6 +4857,8 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode,
* @mode: Device mode
* @pcl_channels: PCL channels
* @len: lenght of the PCL
* @pcl_weight: Weights of the PCL
* @weight_len: Max length of the weights list
*
* This function provides the preferred channel list on which
* policy manager wants the new connection to come up. Various
@ -4717,7 +4868,8 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode,
* Return: QDF_STATUS
*/
QDF_STATUS cds_get_pcl(enum cds_con_mode mode,
uint8_t *pcl_channels, uint32_t *len)
uint8_t *pcl_channels, uint32_t *len,
uint8_t *pcl_weight, uint32_t weight_len)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
uint32_t num_connections = 0;
@ -4805,12 +4957,14 @@ QDF_STATUS cds_get_pcl(enum cds_con_mode mode,
/* once the PCL enum is obtained find out the exact channel list with
* help from sme_get_cfg_valid_channels
*/
status = cds_get_channel_list(pcl, pcl_channels, len, mode);
status = cds_get_channel_list(pcl, pcl_channels, len, mode,
pcl_weight, weight_len);
if (status == QDF_STATUS_SUCCESS) {
uint32_t i;
cds_debug("pcl len:%d", *len);
for (i = 0; i < *len; i++)
cds_debug("chan:%d", pcl_channels[i]);
cds_debug("chan:%d weight:%d",
pcl_channels[i], pcl_weight[i]);
}
return status;
@ -8217,6 +8371,8 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode,
bool for_existing_conn)
{
uint8_t pcl_channels[NUM_CHANNELS];
uint8_t pcl_weight[NUM_CHANNELS];
/*
* in worst case if we can't find any channel at all
* then return 2.4G channel, so atleast we won't fall
@ -8235,11 +8391,13 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode,
return channel;
if (QDF_STATUS_SUCCESS != cds_get_pcl_for_existing_conn(mode,
&pcl_channels[0], &pcl_len))
&pcl_channels[0], &pcl_len,
pcl_weight, QDF_ARRAY_SIZE(pcl_weight)))
return channel;
} else {
if (QDF_STATUS_SUCCESS != cds_get_pcl(mode,
&pcl_channels[0], &pcl_len))
&pcl_channels[0], &pcl_len,
pcl_weight, QDF_ARRAY_SIZE(pcl_weight)))
return channel;
}
@ -8263,6 +8421,8 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode,
}
return channel;
}
/**
* cds_is_any_nondfs_chnl_present() - Find any non-dfs channel from conc table
* @channel: pointer to channel which needs to be filled
@ -8296,3 +8456,47 @@ bool cds_is_any_nondfs_chnl_present(uint8_t *channel)
return status;
}
/**
* cds_get_valid_chan_weights() - Get the weightage for all valid channels
* @weight: Pointer to the structure containing pcl, saved channel list and
* weighed channel list
*
* Provides the weightage for all valid channels. This compares the PCL list
* with the valid channel list. The channels present in the PCL get their
* corresponding weightage and the non-PCL channels get the default weightage
* of WEIGHT_OF_NON_PCL_CHANNELS.
*
* Return: QDF_STATUS
*/
QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight)
{
uint32_t i, j;
if (!weight->pcl_list) {
cds_err("Invalid pcl");
return QDF_STATUS_E_FAILURE;
}
if (!weight->saved_chan_list) {
cds_err("Invalid valid channel list");
return QDF_STATUS_E_FAILURE;
}
if (!weight->weighed_valid_list) {
cds_err("Invalid weighed valid channel list");
return QDF_STATUS_E_FAILURE;
}
for (i = 0; i < weight->saved_num_chan; i++) {
weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS;
for (j = 0; j < weight->pcl_len; j++) {
if (weight->saved_chan_list[i] == weight->pcl_list[j]) {
weight->weighed_valid_list[i] =
weight->weight_list[j];
break;
}
}
}
return QDF_STATUS_SUCCESS;
}

View file

@ -1396,6 +1396,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
bool ht_enabled, ht40_enabled, vht_enabled;
uint8_t ch_width;
uint8_t weight_list[MAX_NUM_CHAN];
/* ***Note*** Donot set SME config related to ACS operation here because
* ACS operation is not synchronouse and ACS for Second AP may come when
@ -1532,8 +1533,9 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
/* consult policy manager to get PCL */
status = cds_get_pcl(CDS_SAP_MODE,
sap_config->acs_cfg.pcl_channels,
&sap_config->acs_cfg.pcl_ch_count);
sap_config->acs_cfg.pcl_channels,
&sap_config->acs_cfg.pcl_ch_count,
weight_list, QDF_ARRAY_SIZE(weight_list));
if (QDF_STATUS_SUCCESS != status)
hddLog(LOGE, FL("Get PCL failed"));
@ -4215,7 +4217,7 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy,
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
int i, ret = 0;
QDF_STATUS status;
uint8_t pcl[MAX_NUM_CHAN];
uint8_t pcl[MAX_NUM_CHAN], weight_list[MAX_NUM_CHAN];
uint32_t pcl_len = 0;
uint32_t freq_list[MAX_NUM_CHAN];
enum cds_con_mode intf_mode;
@ -4249,7 +4251,8 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy,
hdd_debug("Userspace requested pref freq list");
status = cds_get_pcl(intf_mode, pcl, &pcl_len);
status = cds_get_pcl(intf_mode, pcl, &pcl_len,
weight_list, QDF_ARRAY_SIZE(weight_list));
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Get pcl failed");
return -EINVAL;

View file

@ -625,7 +625,7 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx)
enum cds_con_mode sub_type;
enum cds_conc_priority_mode system_pref =
hdd_ctx->config->conc_system_pref;
uint8_t pcl[MAX_NUM_CHAN] = {0};
uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0};
uint32_t pcl_len = 0;
bool status = false;
enum cds_pcl_type pcl_type;
@ -651,7 +651,8 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx)
pcl_type = get_pcl_from_first_conn_table(sub_type, system_pref);
/* check PCL value for second connection is correct or no */
cds_get_pcl(sub_type, pcl, &pcl_len);
cds_get_pcl(sub_type, pcl, &pcl_len,
weight_list, QDF_ARRAY_SIZE(weight_list));
status = wlan_hdd_validate_pcl(hdd_ctx,
pcl_type, pcl, pcl_len, 0, 0,
reason, sizeof(reason));
@ -671,7 +672,7 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx,
{
uint8_t vdevid = 0, tx_stream = 2, rx_stream = 2;
uint8_t type = WMI_VDEV_TYPE_STA, channel_id = first_chnl, mac_id = 1;
uint8_t pcl[MAX_NUM_CHAN] = {0};
uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0};
uint32_t pcl_len = 0;
enum cds_chain_mode chain_mask = first_chain_mask;
enum cds_con_mode sub_type, next_sub_type, dummy_type;
@ -723,7 +724,8 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx,
next_sub_type, system_pref,
wma_is_hw_dbs_capable());
/* check PCL for second connection is correct or no */
cds_get_pcl(next_sub_type, pcl, &pcl_len);
cds_get_pcl(next_sub_type, pcl, &pcl_len,
weight_list, QDF_ARRAY_SIZE(weight_list));
status = wlan_hdd_validate_pcl(hdd_ctx,
pcl_type, pcl, pcl_len, channel_id, 0,
reason, sizeof(reason));
@ -749,7 +751,7 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
uint8_t channel_id_1 = first_chnl, channel_id_2 = second_chnl;
uint8_t mac_id_1, mac_id_2;
uint8_t type_1 = WMI_VDEV_TYPE_STA, type_2 = WMI_VDEV_TYPE_STA;
uint8_t pcl[MAX_NUM_CHAN] = {0};
uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0};
uint32_t pcl_len = 0;
enum cds_chain_mode chain_mask_1;
enum cds_chain_mode chain_mask_2;
@ -838,7 +840,9 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx,
system_pref,
wma_is_hw_dbs_capable());
cds_get_pcl(next_sub_type,
pcl, &pcl_len);
pcl, &pcl_len,
weight_list,
QDF_ARRAY_SIZE(weight_list));
status = wlan_hdd_validate_pcl(hdd_ctx,
pcl_type, pcl, pcl_len,
channel_id_1, channel_id_2,

View file

@ -7927,13 +7927,15 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
case WE_POLICY_MANAGER_PCL_CMD:
{
uint8_t pcl[MAX_NUM_CHAN] = {0};
uint8_t weight_list[MAX_NUM_CHAN] = {0};
uint32_t pcl_len = 0, i = 0;
hddLog(LOGE,
FL("<iwpriv wlan0 pm_pcl> is called\n"));
cds_get_pcl(apps_args[0],
pcl, &pcl_len);
pcl, &pcl_len,
weight_list, QDF_ARRAY_SIZE(weight_list));
pr_info("PCL list for role[%d] is {", apps_args[0]);
for (i = 0 ; i < pcl_len; i++)
pr_info(" %d, ", pcl[i]);

View file

@ -3205,13 +3205,36 @@ enum set_hw_mode_status {
/**
* struct sir_pcl_list - Format of PCL
* @pcl_list: List of preferred channels
* @weight_list: Weights of the PCL
* @pcl_len: Number of channels in the PCL
*/
struct sir_pcl_list {
uint8_t pcl_list[128];
uint8_t weight_list[128];
uint32_t pcl_len;
};
/**
* struct sir_pcl_chan_weights - Params to get the valid weighed list
* @pcl_list: Preferred channel list already sorted in the order of preference
* @pcl_len: Length of the PCL
* @saved_chan_list: Valid channel list updated as part of
* WMA_UPDATE_CHAN_LIST_REQ
* @saved_num_chan: Length of the valid channel list
* @weighed_valid_list: Weights of the valid channel list. This will have one
* to one mapping with valid_chan_list. FW expects channel order and size to be
* as per the list provided in WMI_SCAN_CHAN_LIST_CMDID.
* @weight_list: Weights assigned by policy manager
*/
struct sir_pcl_chan_weights {
uint8_t pcl_list[128];
uint32_t pcl_len;
uint8_t saved_chan_list[128];
uint32_t saved_num_chan;
uint8_t weighed_valid_list[128];
uint8_t weight_list[128];
};
/**
* struct sir_hw_mode_params - HW mode params
* @mac0_tx_ss: MAC0 Tx spatial stream

View file

@ -421,7 +421,7 @@ typedef struct sSirMbMsgP2p {
#define SIR_HAL_FLUSH_LOG_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160)
#define SIR_HAL_SOC_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161)
#define SIR_HAL_PDEV_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161)
/* 162 unused */

View file

@ -526,7 +526,7 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg)
CASE_RETURN_STRING(SIR_HAL_CONFIG_GUARD_TIME);
CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING);
CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW);
CASE_RETURN_STRING(SIR_HAL_SOC_SET_PCL_TO_FW);
CASE_RETURN_STRING(SIR_HAL_PDEV_SET_PCL_TO_FW);
CASE_RETURN_STRING(SIR_HAL_SOC_SET_HW_MODE);
CASE_RETURN_STRING(SIR_HAL_SOC_DUAL_MAC_CFG_REQ);
CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND);

View file

@ -4488,7 +4488,8 @@ static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext)
}
status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE,
pcl.pcl_list, &pcl.pcl_len);
pcl.pcl_list, &pcl.pcl_len,
pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
if (status != QDF_STATUS_SUCCESS) {
cds_err("Get PCL failed");
return status;

View file

@ -986,7 +986,7 @@ QDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss);
bool sme_is_any_session_in_connected_state(tHalHandle h_hal);
QDF_STATUS sme_soc_set_pcl(tHalHandle hal,
QDF_STATUS sme_pdev_set_pcl(tHalHandle hal,
struct sir_pcl_list msg);
QDF_STATUS sme_soc_set_hw_mode(tHalHandle hal,
struct sir_hw_mode msg);

View file

@ -14797,20 +14797,20 @@ QDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req)
#endif /* WLAN_FEATURE_MEMDUMP */
/*
* sme_soc_set_pcl() - Send WMI_SOC_SET_PCL_CMDID to the WMA
* sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA
* @hal: Handle returned by macOpen
* @msg: PCL channel list and length structure
*
* Sends the command to WMA to send WMI_SOC_SET_PCL_CMDID to FW
* Sends the command to WMA to send WMI_PDEV_SET_PCL_CMDID to FW
* Return: QDF_STATUS_SUCCESS on successful posting
*/
QDF_STATUS sme_soc_set_pcl(tHalHandle hal,
QDF_STATUS sme_pdev_set_pcl(tHalHandle hal,
struct sir_pcl_list msg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
tpAniSirGlobal mac = PMAC_STRUCT(hal);
cds_msg_t cds_message;
struct sir_pcl_list *req_msg;
struct wmi_pcl_chan_weights *req_msg;
uint32_t len, i;
len = sizeof(*req_msg);
@ -14823,8 +14823,10 @@ QDF_STATUS sme_soc_set_pcl(tHalHandle hal,
qdf_mem_zero(req_msg, len);
for (i = 0; i < msg.pcl_len; i++)
for (i = 0; i < msg.pcl_len; i++) {
req_msg->pcl_list[i] = msg.pcl_list[i];
req_msg->weight_list[i] = msg.weight_list[i];
}
req_msg->pcl_len = msg.pcl_len;
@ -14839,7 +14841,7 @@ QDF_STATUS sme_soc_set_pcl(tHalHandle hal,
/* Serialize the req through MC thread */
cds_message.bodyptr = req_msg;
cds_message.type = SIR_HAL_SOC_SET_PCL_TO_FW;
cds_message.type = SIR_HAL_PDEV_SET_PCL_TO_FW;
status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sms_log(mac, LOGE,

View file

@ -1991,6 +1991,7 @@ csr_parse_scan_results(tpAniSirGlobal pMac,
eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
uint32_t len = 0;
enum cds_con_mode new_mode;
uint8_t weight_list[MAX_NUM_CHAN];
csr_ll_lock(&pMac->scan.scanResultList);
@ -1999,7 +2000,8 @@ csr_parse_scan_results(tpAniSirGlobal pMac,
if (cds_map_concurrency_mode(
&pFilter->csrPersona, &new_mode)) {
status = cds_get_pcl(new_mode,
&pFilter->pcl_channels.channelList[0], &len);
&pFilter->pcl_channels.channelList[0], &len,
weight_list, QDF_ARRAY_SIZE(weight_list));
pFilter->pcl_channels.numChannels = (uint8_t)len;
}
}

View file

@ -1041,6 +1041,17 @@ struct wma_ini_config {
uint8_t max_no_of_peers;
};
/**
* struct wmi_valid_channels - Channel details part of WMI_SCAN_CHAN_LIST_CMDID
* @num_channels: Number of channels
* @channel_list: Channel list
*/
struct wma_valid_channels {
uint8_t num_channels;
uint8_t channel_list[MAX_NUM_CHAN];
};
/**
* struct t_wma_handle - wma context
* @wmi_handle: wmi handle
@ -1165,6 +1176,7 @@ struct wma_ini_config {
* @service_ready_ext_evt: Wait event for service ready ext
* @wmi_cmd_rsp_wake_lock: wmi command response wake lock
* @wmi_cmd_rsp_runtime_lock: wmi command response bus lock
* @saved_chan: saved channel list sent as part of WMI_SCAN_CHAN_LIST_CMDID
*/
typedef struct {
void *wmi_handle;
@ -1350,6 +1362,7 @@ typedef struct {
qdf_runtime_lock_t wma_runtime_resume_lock;
uint32_t fine_time_measurement_cap;
struct wma_ini_config ini_config;
struct wma_valid_channels saved_chan;
} t_wma_handle, *tp_wma_handle;
/**
@ -1956,8 +1969,8 @@ void wma_log_completion_timeout(void *data);
QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma,
struct rssi_monitor_req *req);
QDF_STATUS wma_send_soc_set_pcl_cmd(tp_wma_handle wma_handle,
struct sir_pcl_list *msg);
QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
struct wmi_pcl_chan_weights *msg);
QDF_STATUS wma_send_soc_set_hw_mode_cmd(tp_wma_handle wma_handle,
struct sir_hw_mode *msg);

View file

@ -1798,6 +1798,7 @@ QDF_STATUS wma_open(void *cds_context,
wma_handle->dfs_radar_indication_cb = radar_ind_cb;
wma_handle->old_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
wma_handle->new_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX;
wma_handle->saved_chan.num_channels = 0;
qdf_status = qdf_event_create(&wma_handle->wma_ready_event);
if (qdf_status != QDF_STATUS_SUCCESS) {
@ -5165,9 +5166,9 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg)
(struct fw_dump_req *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case SIR_HAL_SOC_SET_PCL_TO_FW:
wma_send_soc_set_pcl_cmd(wma_handle,
(struct sir_pcl_list *)msg->bodyptr);
case SIR_HAL_PDEV_SET_PCL_TO_FW:
wma_send_pdev_set_pcl_cmd(wma_handle,
(struct wmi_pcl_chan_weights *)msg->bodyptr);
qdf_mem_free(msg->bodyptr);
break;
case SIR_HAL_SOC_SET_HW_MODE:
@ -5297,30 +5298,49 @@ void wma_log_completion_timeout(void *data)
}
/**
* wma_send_soc_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW
* wma_send_pdev_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW
* @wma_handle: WMA handle
* @msg: PCL structure containing the PCL and the number of channels
*
* WMI_SOC_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
* WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN
* firmware. The DBS Manager is the consumer of this information in the WLAN
* firmware. The channel list will be used when a Virtual DEVice (VDEV) needs
* to migrate to a new channel without host driver involvement. An example of
* this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will
* manage the channel selection without firmware involvement.
*
* WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual
* channel list. The weights corresponds to the channels sent in
* WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher
* weightage compared to the non PCL channels.
*
* Return: Success if the cmd is sent successfully to the firmware
*/
QDF_STATUS wma_send_soc_set_pcl_cmd(tp_wma_handle wma_handle,
struct sir_pcl_list *msg)
QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle,
struct wmi_pcl_chan_weights *msg)
{
uint32_t i;
QDF_STATUS status;
if (!wma_handle) {
WMA_LOGE("%s: WMA handle is NULL. Cannot issue command",
__func__);
return QDF_STATUS_E_NULL_VALUE;
}
if (wmi_unified_soc_set_pcl_cmd(wma_handle->wmi_handle,
(struct wmi_pcl_list *) msg))
for (i = 0; i < wma_handle->saved_chan.num_channels; i++) {
msg->saved_chan_list[i] =
wma_handle->saved_chan.channel_list[i];
}
msg->saved_num_chan = wma_handle->saved_chan.num_channels;
status = cds_get_valid_chan_weights((struct sir_pcl_chan_weights *)msg);
if (!QDF_IS_STATUS_SUCCESS(status)) {
WMA_LOGE("%s: Error in creating weighed pcl", __func__);
return status;
}
if (wmi_unified_pdev_set_pcl_cmd(wma_handle->wmi_handle, msg))
return QDF_STATUS_E_FAILURE;
return QDF_STATUS_SUCCESS;

View file

@ -642,6 +642,7 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle,
WMA_LOGD("no of channels = %d", chan_list->numChan);
tchan_info = scan_ch_param.chan_info;
scan_ch_param.num_scan_chans = chan_list->numChan;
wma_handle->saved_chan.num_channels = chan_list->numChan;
for (i = 0; i < chan_list->numChan; ++i) {
tchan_info->mhz =
@ -649,8 +650,11 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle,
tchan_info->band_center_freq1 =
tchan_info->mhz;
tchan_info->band_center_freq2 = 0;
wma_handle->saved_chan.channel_list[i] =
chan_list->chanParam[i].chanId;
WMA_LOGD("chan[%d] = %u", i, tchan_info->mhz);
WMA_LOGD("chan[%d] = freq:%u chan:%d", i, tchan_info->mhz,
chan_list->chanParam[i].chanId);
if (chan_list->chanParam[i].dfsSet) {
WMI_SET_CHANNEL_FLAG(tchan_info, WMI_CHAN_FLAG_PASSIVE);
WMA_LOGI("chan[%d] DFS[%d]\n",