qcacmn: Save the unsafe channels in policy manager

Save the list of unsafe channels in policy manager to be used on PCL.

Change-Id: Ibb705830e878d1cc03dfbc76e49c169d2febd75d
CRs-Fixed: 2095290
This commit is contained in:
Tushnim Bhattacharyya 2017-04-27 12:31:41 -07:00 • committed by pramod kotreshappa
commit ddfe26635d
5 changed files with 121 additions and 5 deletions

View file

@ -304,6 +304,7 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
/**
* policy_mgr_update_with_safe_channel_list() - provides the safe
* channel list
* @psoc: PSOC object information
* @pcl_channels: channel list
* @len: length of the list
* @weight_list: Weights of the PCL
@ -314,8 +315,9 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc,
*
* Return: None
*/
void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels,
uint32_t *len, uint8_t *weight_list, uint32_t weight_len);
void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
uint8_t *pcl_channels, uint32_t *len,
uint8_t *weight_list, uint32_t weight_len);
/**
* policy_mgr_get_nondfs_preferred_channel() - to get non-dfs preferred channel

View file

@ -2106,7 +2106,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc,
*len, i);
/* check the channel avoidance list */
policy_mgr_update_with_safe_channel_list(pcl_channels, len,
policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, len,
pcl_weights, weight_len);
return status;

View file

@ -224,6 +224,8 @@ extern enum policy_mgr_conc_next_action
* change is in progress
* @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler
* value from INI
* @unsafe_channel_list: LTE coex channel avoidance list
* @unsafe_channel_count: LTE coex channel avoidance list count
*/
struct policy_mgr_psoc_priv_obj {
struct wlan_objmgr_psoc *psoc;
@ -250,6 +252,8 @@ struct policy_mgr_psoc_priv_obj {
struct dual_mac_config dual_mac_cfg;
uint32_t hw_mode_change_in_progress;
struct policy_mgr_user_cfg user_cfg;
uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN];
uint16_t unsafe_channel_count;
};
/**
@ -403,4 +407,23 @@ QDF_STATUS policy_mgr_reset_sap_mandatory_channels(
bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc,
uint8_t *channel, uint8_t *vdev_id,
enum policy_mgr_con_mode mode);
/**
* policy_mgr_reg_chan_change_callback() - Callback to be
* invoked by regulatory module when valid channel list changes
* @psoc: PSOC object information
* @pdev: PDEV object information
* @chan_list: New channel list
* @avoid_freq_ind: LTE coex avoid channel list
* @arg: Information passed at registration
*
* Get updated channel list from regulatory module
*
* Return: None
*/
void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct regulatory_channel *chan_list,
struct avoid_freq_ind_data *avoid_freq_ind,
void *arg);
#endif

View file

@ -101,6 +101,9 @@ static QDF_STATUS policy_mgr_pdev_obj_create_cb(struct wlan_objmgr_pdev *pdev,
policy_mgr_ctx->pdev = pdev;
wlan_reg_register_chan_change_callback(psoc,
policy_mgr_reg_chan_change_callback, NULL);
return QDF_STATUS_SUCCESS;
}
@ -118,6 +121,8 @@ static QDF_STATUS policy_mgr_pdev_obj_destroy_cb(struct wlan_objmgr_pdev *pdev,
}
policy_mgr_ctx->pdev = NULL;
wlan_reg_unregister_chan_change_callback(psoc,
policy_mgr_reg_chan_change_callback);
return QDF_STATUS_SUCCESS;
}

View file

@ -142,9 +142,95 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc,
return;
}
void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels,
uint32_t *len, uint8_t *weight_list, uint32_t weight_len)
void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct regulatory_channel *chan_list,
struct avoid_freq_ind_data *avoid_freq_ind,
void *arg)
{
struct policy_mgr_psoc_priv_obj *pm_ctx;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return;
}
if (!avoid_freq_ind) {
policy_mgr_debug("avoid_freq_ind NULL");
return;
}
pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.ch_cnt >=
QDF_MAX_NUM_CHAN ?
QDF_MAX_NUM_CHAN : avoid_freq_ind->chan_list.ch_cnt;
if (pm_ctx->unsafe_channel_count)
qdf_mem_copy(pm_ctx->unsafe_channel_list,
avoid_freq_ind->chan_list.ch_list,
pm_ctx->unsafe_channel_count);
policy_mgr_debug("Channel list update, recieved %d avoided channels",
pm_ctx->unsafe_channel_count);
}
void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc,
uint8_t *pcl_channels, uint32_t *len,
uint8_t *weight_list, uint32_t weight_len)
{
uint8_t current_channel_list[QDF_MAX_NUM_CHAN];
uint8_t org_weight_list[QDF_MAX_NUM_CHAN];
uint8_t is_unsafe = 1;
uint8_t i, j;
uint32_t safe_channel_count = 0, current_channel_count = 0;
struct policy_mgr_psoc_priv_obj *pm_ctx;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return;
}
if (len) {
current_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN);
} else {
policy_mgr_err("invalid number of channel length");
return;
}
if (pm_ctx->unsafe_channel_count == 0) {
policy_mgr_debug("There are no unsafe channels");
return;
}
qdf_mem_copy(current_channel_list, pcl_channels,
current_channel_count);
qdf_mem_zero(pcl_channels, current_channel_count);
qdf_mem_copy(org_weight_list, weight_list, QDF_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 < pm_ctx->unsafe_channel_count; j++) {
if (current_channel_list[i] ==
pm_ctx->unsafe_channel_list[j]) {
/* Found unsafe channel, update it */
is_unsafe = 1;
policy_mgr_warn("CH %d is not safe",
current_channel_list[i]);
break;
}
}
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];
safe_channel_count++;
}
}
*len = safe_channel_count;
return;
}