qcacmn: Do not return pointer to the regulatory rules
Regulatory rules can change a lot of times depending on conditions. By returning pointer, the rules can change before rules are accessed using the pointer. Therefore always copy the rules. Change-Id: Ic0a8b5f515cb07279a8d8f204043e5d6aaac98f2 CRs-Fixed: 2319788
This commit is contained in:
@@ -134,6 +134,7 @@ struct wlan_regulatory_pdev_priv_obj {
|
||||
bool force_ssc_disable_indoor_channel;
|
||||
bool sap_state;
|
||||
struct reg_rule_info reg_rules;
|
||||
qdf_spinlock_t reg_rules_lock;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -2882,8 +2882,6 @@ static QDF_STATUS reg_sched_11d_msg(struct wlan_objmgr_psoc *psoc)
|
||||
|
||||
void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
|
||||
{
|
||||
if (reg_rules->reg_rules_ptr)
|
||||
qdf_mem_free(reg_rules->reg_rules_ptr);
|
||||
qdf_mem_zero(reg_rules, sizeof(*reg_rules));
|
||||
}
|
||||
|
||||
@@ -2894,28 +2892,29 @@ static void reg_save_reg_rules_to_pdev(struct reg_rule_info *psoc_reg_rules,
|
||||
uint32_t reg_rule_len;
|
||||
struct reg_rule_info *pdev_reg_rules;
|
||||
|
||||
qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
|
||||
|
||||
pdev_reg_rules = &pdev_priv_obj->reg_rules;
|
||||
reg_reset_reg_rules(pdev_reg_rules);
|
||||
|
||||
pdev_reg_rules->num_of_reg_rules = psoc_reg_rules->num_of_reg_rules;
|
||||
if (!pdev_reg_rules->num_of_reg_rules) {
|
||||
reg_debug("no reg rules in psoc");
|
||||
qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
|
||||
reg_err("no reg rules in psoc");
|
||||
return;
|
||||
}
|
||||
|
||||
reg_rule_len = pdev_reg_rules->num_of_reg_rules *
|
||||
sizeof(struct cur_reg_rule);
|
||||
pdev_reg_rules->reg_rules_ptr = qdf_mem_malloc(reg_rule_len);
|
||||
if (!pdev_reg_rules->reg_rules_ptr) {
|
||||
reg_err("mem alloc failed for pdev reg rules");
|
||||
return;
|
||||
}
|
||||
qdf_mem_copy(pdev_reg_rules->reg_rules_ptr,
|
||||
psoc_reg_rules->reg_rules_ptr,
|
||||
qdf_mem_copy(pdev_reg_rules->reg_rules,
|
||||
psoc_reg_rules->reg_rules,
|
||||
reg_rule_len);
|
||||
|
||||
qdf_mem_copy(pdev_reg_rules->alpha2, pdev_priv_obj->current_country,
|
||||
REG_ALPHA2_LEN + 1);
|
||||
pdev_reg_rules->dfs_region = pdev_priv_obj->dfs_region;
|
||||
reg_debug("num pdev reg rules saved %d",
|
||||
pdev_reg_rules->num_of_reg_rules);
|
||||
|
||||
qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
|
||||
}
|
||||
|
||||
static void reg_propagate_mas_chan_list_to_pdev(struct wlan_objmgr_psoc *psoc,
|
||||
@@ -3113,24 +3112,21 @@ QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info
|
||||
reg_reset_reg_rules(reg_rules);
|
||||
|
||||
reg_rules->num_of_reg_rules = num_5g_reg_rules + num_2g_reg_rules;
|
||||
if (reg_rules->num_of_reg_rules > MAX_REG_RULES) {
|
||||
reg_err("number of reg rules exceeds limit");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (reg_rules->num_of_reg_rules) {
|
||||
reg_rules->reg_rules_ptr =
|
||||
qdf_mem_malloc(reg_rules->num_of_reg_rules *
|
||||
sizeof(struct cur_reg_rule));
|
||||
if (!reg_rules->reg_rules_ptr) {
|
||||
reg_err("mem alloc failed for reg_rules");
|
||||
} else {
|
||||
if (num_2g_reg_rules)
|
||||
qdf_mem_copy(reg_rules->reg_rules_ptr,
|
||||
reg_rule_2g, num_2g_reg_rules *
|
||||
sizeof(struct cur_reg_rule));
|
||||
if (num_5g_reg_rules)
|
||||
qdf_mem_copy(reg_rules->reg_rules_ptr +
|
||||
num_2g_reg_rules, reg_rule_5g,
|
||||
num_5g_reg_rules *
|
||||
sizeof(struct cur_reg_rule));
|
||||
}
|
||||
if (num_2g_reg_rules)
|
||||
qdf_mem_copy(reg_rules->reg_rules,
|
||||
reg_rule_2g, num_2g_reg_rules *
|
||||
sizeof(struct cur_reg_rule));
|
||||
if (num_5g_reg_rules)
|
||||
qdf_mem_copy(reg_rules->reg_rules +
|
||||
num_2g_reg_rules, reg_rule_5g,
|
||||
num_5g_reg_rules *
|
||||
sizeof(struct cur_reg_rule));
|
||||
}
|
||||
|
||||
if (num_5g_reg_rules != 0)
|
||||
@@ -3628,6 +3624,8 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification(
|
||||
psoc_priv_obj->indoor_chan_enabled;
|
||||
pdev_priv_obj->en_chan_144 = true;
|
||||
|
||||
qdf_spinlock_create(&pdev_priv_obj->reg_rules_lock);
|
||||
|
||||
reg_cap_ptr = psoc_priv_obj->reg_cap;
|
||||
pdev_priv_obj->force_ssc_disable_indoor_channel =
|
||||
psoc_priv_obj->force_ssc_disable_indoor_channel;
|
||||
@@ -3718,7 +3716,12 @@ QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification(
|
||||
|
||||
reg_debug("reg pdev obj deleted with status %d", status);
|
||||
|
||||
qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
|
||||
reg_reset_reg_rules(&pdev_priv_obj->reg_rules);
|
||||
qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
|
||||
|
||||
qdf_spinlock_destroy(&pdev_priv_obj->reg_rules_lock);
|
||||
|
||||
qdf_mem_free(pdev_priv_obj);
|
||||
|
||||
return status;
|
||||
@@ -4246,22 +4249,28 @@ QDF_STATUS reg_program_default_cc(struct wlan_objmgr_pdev *pdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
struct reg_rule_info *reg_get_regd_rules(struct wlan_objmgr_pdev *pdev)
|
||||
QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
|
||||
struct reg_rule_info *reg_rules)
|
||||
{
|
||||
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
|
||||
|
||||
if (!pdev) {
|
||||
reg_err("pdev is NULL");
|
||||
return NULL;
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
pdev_priv_obj = reg_get_pdev_obj(pdev);
|
||||
|
||||
pdev_priv_obj = reg_get_pdev_obj(pdev);
|
||||
if (!pdev_priv_obj) {
|
||||
reg_err("pdev priv obj is NULL");
|
||||
return NULL;
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
return &pdev_priv_obj->reg_rules;
|
||||
qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
|
||||
qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules,
|
||||
sizeof(struct reg_rule_info));
|
||||
qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS reg_program_chan_list(struct wlan_objmgr_pdev *pdev,
|
||||
|
@@ -445,10 +445,12 @@ void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
|
||||
/**
|
||||
* reg_get_regd_rules() - provides the reg domain rules info
|
||||
* @pdev: pdev pointer
|
||||
* @reg_rules: regulatory rules
|
||||
*
|
||||
* Return: reg_rule_info pointer
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
struct reg_rule_info *reg_get_regd_rules(struct wlan_objmgr_pdev *pdev);
|
||||
QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
|
||||
struct reg_rule_info *reg_rules);
|
||||
|
||||
/**
|
||||
* reg_reset_reg_rules() - provides the reg domain rules info
|
||||
|
@@ -783,13 +783,13 @@ struct cur_regulatory_info {
|
||||
* @alpha2: alpha2 of reg rules
|
||||
* @dfs_region: dfs region
|
||||
* @num_of_reg_rules: number of reg rules
|
||||
* @reg_rules_ptr: regulatory rules pointer
|
||||
* @reg_rules: regulatory rules array
|
||||
*/
|
||||
struct reg_rule_info {
|
||||
uint8_t alpha2[REG_ALPHA2_LEN + 1];
|
||||
enum dfs_reg dfs_region;
|
||||
uint8_t num_of_reg_rules;
|
||||
struct cur_reg_rule *reg_rules_ptr;
|
||||
struct cur_reg_rule reg_rules[MAX_REG_RULES];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -258,10 +258,12 @@ void ucfg_reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
|
||||
/**
|
||||
* ucfg_reg_get_regd_rules() - provides the reg domain rules info pointer
|
||||
* @pdev: pdev ptr
|
||||
* @reg_rules: regulatory rules
|
||||
*
|
||||
* Return: reg_rule_info pointer
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
struct reg_rule_info *ucfg_reg_get_regd_rules(struct wlan_objmgr_pdev *pdev);
|
||||
QDF_STATUS ucfg_reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
|
||||
struct reg_rule_info *reg_rules);
|
||||
|
||||
/**
|
||||
* ucfg_reg_register_chan_change_callback () - add chan change cbk
|
||||
|
@@ -82,9 +82,10 @@ void ucfg_reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
|
||||
reg_program_mas_chan_list(psoc, reg_channels, alpha2, dfs_region);
|
||||
}
|
||||
|
||||
struct reg_rule_info *ucfg_reg_get_regd_rules(struct wlan_objmgr_pdev *pdev)
|
||||
QDF_STATUS ucfg_reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
|
||||
struct reg_rule_info *reg_rules)
|
||||
{
|
||||
return reg_get_regd_rules(pdev);
|
||||
return reg_get_regd_rules(pdev, reg_rules);
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_reg_program_default_cc(struct wlan_objmgr_pdev *pdev,
|
||||
|
Reference in New Issue
Block a user