qcacld-3.0: Code cleanup in Vendor ACS support code

1. Add modularity to the vendor acs logic
2. Add error conditions, return values and their handling.
3. Add appropriate kernel doc.

Change-Id: I5e07910d243686f77a8abbed373ea7970992b6d0
CRs-Fixed: 2100804
This commit is contained in:
Himanshu Agarwal 2017-08-29 19:49:05 +05:30 • committed by snandini
commit dfc4dcac67
8 changed files with 223 additions and 57 deletions

View file

@ -2123,6 +2123,17 @@ static inline bool hdd_scan_random_mac_addr_supported(void)
}
#endif
/**
* hdd_start_vendor_acs(): Start vendor ACS procedure
* @adapter: pointer to SAP adapter struct
*
* This function sends the ACS config to the ACS daemon and
* starts the vendor ACS timer to wait for the next command.
*
* Return: Status of vendor ACS procedure
*/
int hdd_start_vendor_acs(struct hdd_adapter *adapter);
void hdd_get_fw_version(struct hdd_context *hdd_ctx,
uint32_t *major_spid, uint32_t *minor_spid,
uint32_t *siid, uint32_t *crmid);
@ -2150,10 +2161,10 @@ int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter);
* @adapter: hdd adapter
* @reason: channel change reason
*
* Return: none
* Return: 0 for success else error code
*/
void hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
uint8_t reason);
int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
uint8_t reason);
/**
* hdd_update_acs_timer_reason() - update acs timer start reason
* @adapter: hdd adapter

View file

@ -1610,6 +1610,8 @@ static int wlan_hdd_reset_force_acs_chan_range(struct hdd_context *hdd_ctx,
bool is_dfs_mode_enabled = false;
uint32_t i, num_channels = 0;
uint8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
eCsrPhyMode hw_mode;
tSirMacHTChannelWidth ch_width;
if (hdd_ctx->config->force_sap_acs_st_ch >
hdd_ctx->config->force_sap_acs_end_ch) {
@ -1646,6 +1648,62 @@ static int wlan_hdd_reset_force_acs_chan_range(struct hdd_context *hdd_ctx,
qdf_mem_copy(sap_config->acs_cfg.ch_list, channels, num_channels);
sap_config->acs_cfg.ch_list_count = num_channels;
/* Derive ACS HW mode */
hw_mode = hdd_cfg_xlate_to_csr_phy_mode(hdd_ctx->config->dot11Mode);
if (hw_mode == eCSR_DOT11_MODE_AUTO) {
if (sme_is_feature_supported_by_fw(DOT11AX))
hw_mode = eCSR_DOT11_MODE_11ax;
else
hw_mode = eCSR_DOT11_MODE_11ac;
}
if (hdd_ctx->config->sap_force_11n_for_11ac) {
if (hw_mode == eCSR_DOT11_MODE_11ac ||
hw_mode == eCSR_DOT11_MODE_11ac_ONLY)
hw_mode = eCSR_DOT11_MODE_11n;
}
if ((hw_mode == eCSR_DOT11_MODE_11b ||
hw_mode == eCSR_DOT11_MODE_11g ||
hw_mode == eCSR_DOT11_MODE_11g_ONLY) &&
sap_config->acs_cfg.start_ch > 14) {
hdd_err("Invalid ACS HW Mode %d + CH range <%d - %d>",
hw_mode, sap_config->acs_cfg.start_ch,
sap_config->acs_cfg.end_ch);
return -EINVAL;
}
sap_config->acs_cfg.hw_mode = hw_mode;
/* Derive ACS BW */
ch_width = eHT_CHANNEL_WIDTH_20MHZ;
if (hw_mode == eCSR_DOT11_MODE_11ac ||
hw_mode == eCSR_DOT11_MODE_11ac_ONLY ||
hw_mode == eCSR_DOT11_MODE_11ax ||
hw_mode == eCSR_DOT11_MODE_11ax_ONLY) {
ch_width = hdd_ctx->config->vhtChannelWidth;
/* VHT in 2.4G depends on gChannelBondingMode24GHz INI param */
if (sap_config->acs_cfg.end_ch <= 14)
ch_width =
hdd_ctx->config->nChannelBondingMode24GHz ?
eHT_CHANNEL_WIDTH_40MHZ :
eHT_CHANNEL_WIDTH_20MHZ;
}
if (hw_mode == eCSR_DOT11_MODE_11n ||
hw_mode == eCSR_DOT11_MODE_11n_ONLY) {
if (sap_config->acs_cfg.end_ch <= 14)
ch_width =
hdd_ctx->config->nChannelBondingMode24GHz ?
eHT_CHANNEL_WIDTH_40MHZ :
eHT_CHANNEL_WIDTH_20MHZ;
else
ch_width =
hdd_ctx->config->nChannelBondingMode5GHz ?
eHT_CHANNEL_WIDTH_40MHZ :
eHT_CHANNEL_WIDTH_20MHZ;
}
sap_config->acs_cfg.ch_width = ch_width;
return 0;
}
@ -1656,9 +1714,9 @@ static int wlan_hdd_reset_force_acs_chan_range(struct hdd_context *hdd_ctx,
* This function sets the default ACS start and end channel for the given band
* and also parses the given ACS channel list.
*
* Return: None
* Return: status
*/
static void wlan_hdd_set_acs_ch_range(tsap_Config_t *sap_cfg, bool ht_enabled,
static int wlan_hdd_set_acs_ch_range(tsap_Config_t *sap_cfg, bool ht_enabled,
bool vht_enabled)
{
int i;
@ -1689,7 +1747,7 @@ static void wlan_hdd_set_acs_ch_range(tsap_Config_t *sap_cfg, bool ht_enabled,
/* Parse ACS Chan list from hostapd */
if (!sap_cfg->acs_cfg.ch_list)
return;
return -EINVAL;
sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[0];
sap_cfg->acs_cfg.end_ch =
@ -1702,6 +1760,8 @@ static void wlan_hdd_set_acs_ch_range(tsap_Config_t *sap_cfg, bool ht_enabled,
if (sap_cfg->acs_cfg.end_ch < sap_cfg->acs_cfg.ch_list[i])
sap_cfg->acs_cfg.end_ch = sap_cfg->acs_cfg.ch_list[i];
}
return 0;
}
@ -2158,12 +2218,12 @@ static void hdd_get_freq_list(uint8_t *channel_list, uint32_t *freq_list,
freq_list[count] = cds_chan_to_freq(channel_list[count]);
}
void hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
uint8_t reason)
int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
uint8_t reason)
{
struct sk_buff *skb;
tsap_Config_t *sap_config;
uint32_t channel_count = 0, status;
uint32_t channel_count = 0, status = -EINVAL;
uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0};
uint32_t freq_list[QDF_MAX_NUM_CHAN] = {0};
uint8_t vendor_pcl_list[QDF_MAX_NUM_CHAN] = {0};
@ -2178,7 +2238,7 @@ void hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
if (!hdd_ctx) {
hdd_err("HDD context is NULL");
return;
return -EINVAL;
}
ENTER();
@ -2238,7 +2298,7 @@ void hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
if (!skb) {
hdd_err("cfg80211_vendor_event_alloc failed");
return;
return -ENOMEM;
}
/*
* Application expects pcl to be a subset of channel list
@ -2324,27 +2384,45 @@ void hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
goto fail;
cfg80211_vendor_event(skb, GFP_KERNEL);
return;
return 0;
fail:
if (skb)
kfree_skb(skb);
return status;
}
/**
* hdd_create_acs_timer(): Initialize vendor ACS timer
* @adapter: pointer to SAP adapter struct
*
* This function initializes the vendor ACS timer.
*
* Return: Status of create vendor ACS timer
*/
static int hdd_create_acs_timer(struct hdd_adapter *adapter)
{
struct hdd_external_acs_timer_context *timer_context;
QDF_STATUS status;
if (adapter->sessionCtx.ap.vendor_acs_timer_initialized)
return 0;
hdd_notice("Starting vendor app based ACS");
hdd_debug("Starting vendor app based ACS");
timer_context = qdf_mem_malloc(sizeof(*timer_context));
if (!timer_context) {
hdd_err("Could not allocate for timer_context");
return -ENOMEM;
}
timer_context->adapter = adapter;
set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
qdf_mc_timer_init(&adapter->sessionCtx.ap.vendor_acs_timer,
status = qdf_mc_timer_init(&adapter->sessionCtx.ap.vendor_acs_timer,
QDF_TIMER_TYPE_SW,
hdd_acs_response_timeout_handler, timer_context);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to initialize acs response timeout timer");
return -EFAULT;
}
adapter->sessionCtx.ap.vendor_acs_timer_initialized = true;
return 0;
}
@ -2360,6 +2438,35 @@ wlan_hdd_cfg80211_do_acs_policy[QCA_WLAN_VENDOR_ATTR_ACS_MAX+1] = {
[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST] = { .type = NLA_UNSPEC },
};
int hdd_start_vendor_acs(struct hdd_adapter *adapter)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
int status;
status = hdd_create_acs_timer(adapter);
if (status != 0) {
hdd_err("failed to create acs timer");
return status;
}
status = hdd_update_acs_timer_reason(adapter,
QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT);
if (status != 0) {
hdd_err("failed to update acs timer reason");
return status;
}
if (hdd_ctx->config->acs_support_for_dfs_ltecoex)
status = qdf_status_to_os_return(wlan_sap_set_vendor_acs(
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
true));
else
status = qdf_status_to_os_return(wlan_sap_set_vendor_acs(
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
false));
return status;
}
/**
* __wlan_hdd_cfg80211_do_acs(): CFG80211 handler function for DO_ACS Vendor CMD
* @wiphy: Linux wiphy struct pointer
@ -2372,7 +2479,6 @@ wlan_hdd_cfg80211_do_acs_policy[QCA_WLAN_VENDOR_ATTR_ACS_MAX+1] = {
*
* Return: ACS procedure start status
*/
static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len)
@ -2431,6 +2537,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
if (!tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
hdd_err("Attr hw_mode failed");
status = -EINVAL;
goto out;
}
hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
@ -2504,8 +2611,11 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
sap_config->acs_cfg.ch_list = qdf_mem_malloc(
sizeof(uint8_t) *
sap_config->acs_cfg.ch_list_count);
if (sap_config->acs_cfg.ch_list == NULL)
if (!sap_config->acs_cfg.ch_list) {
hdd_err("ACS config alloc fail");
status = -ENOMEM;
goto out;
}
qdf_mem_copy(sap_config->acs_cfg.ch_list, tmp,
sap_config->acs_cfg.ch_list_count);
@ -2519,7 +2629,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
if (sap_config->acs_cfg.ch_list_count) {
sap_config->acs_cfg.ch_list = qdf_mem_malloc(
sap_config->acs_cfg.ch_list_count);
if (sap_config->acs_cfg.ch_list == NULL) {
if (!sap_config->acs_cfg.ch_list) {
hdd_err("ACS config alloc fail");
status = -ENOMEM;
goto out;
@ -2540,7 +2650,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
&sap_config->acs_cfg.pcl_ch_count,
sap_config->acs_cfg.pcl_channels_weight_list,
QDF_MAX_NUM_CHAN);
if (QDF_STATUS_SUCCESS != qdf_status)
if (qdf_status != QDF_STATUS_SUCCESS)
hdd_err("Get PCL failed");
if (sap_config->acs_cfg.pcl_ch_count) {
@ -2554,14 +2664,20 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
pcl_channels_weight_list[i]);
}
wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
status = wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
if (status) {
hdd_err("set acs channel range failed");
goto out;
}
if (hdd_ctx->config->force_sap_acs) {
hdd_debug("forcing SAP acs start and end channel");
status = wlan_hdd_reset_force_acs_chan_range(hdd_ctx,
sap_config);
if (status != 0)
if (status) {
hdd_err("reset force acs channel range failed");
goto out;
}
}
sap_config->acs_cfg.band = hw_mode;
@ -2618,20 +2734,9 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
status = 0;
} else {
/* Check if vendor specific acs is enabled */
if (hdd_ctx->config->vendor_acs_support) {
hdd_create_acs_timer(adapter);
hdd_update_acs_timer_reason(adapter,
QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT);
if (hdd_ctx->config->acs_support_for_dfs_ltecoex)
wlan_sap_set_vendor_acs(
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
true);
else
wlan_sap_set_vendor_acs(
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
false);
} else
if (hdd_ctx->config->vendor_acs_support)
status = hdd_start_vendor_acs(adapter);
else
status = wlan_hdd_cfg80211_start_acs(adapter);
}

View file

@ -7338,8 +7338,9 @@ QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx, struct hdd_adapter *
}
/**
* wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
* @adapter: pointer to adapter struct
* wlan_hdd_sap_p2p_11ac_overrides: API to overwrite 11ac config in case of
* SAP or p2p go
* @ap_adapter: pointer to adapter
*
* This function overrides SAP / P2P Go configuration based on driver INI
* parameters for 11AC override and ACS. This overrides are done to support
@ -7351,16 +7352,11 @@ QDF_STATUS wlan_hdd_config_acs(struct hdd_context *hdd_ctx, struct hdd_adapter *
*
* Return: 0 for Success or Negative error codes.
*/
static int wlan_hdd_setup_driver_overrides(struct hdd_adapter *ap_adapter)
static int wlan_hdd_sap_p2p_11ac_overrides(struct hdd_adapter *ap_adapter)
{
tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
if (ap_adapter->device_mode == QDF_SAP_MODE &&
hdd_ctx->config->force_sap_acs &&
!hdd_ctx->config->vendor_acs_support)
goto setup_acs_overrides;
/* Fixed channel 11AC override:
* 11AC override in qcacld is introduced for following reasons:
* 1. P2P GO also follows start_bss and since p2p GO could not be
@ -7405,14 +7401,33 @@ static int wlan_hdd_setup_driver_overrides(struct hdd_adapter *ap_adapter)
sap_cfg->ch_width_orig =
eHT_CHANNEL_WIDTH_20MHZ;
}
sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig;
wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, sap_cfg->channel,
sap_cfg->sec_ch, &sap_cfg->ch_params);
}
sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig;
wlan_reg_set_channel_params(hdd_ctx->hdd_pdev, sap_cfg->channel,
sap_cfg->sec_ch, &sap_cfg->ch_params);
return 0;
}
/**
* wlan_hdd_setup_acs_overrides : Overrides ACS configurations
* @adapter: pointer to adapter struct
*
* This function overrides ACS configuration based on driver INI
* parameters. These overrides are done to support android legacy
* configuration method.
*
* NOTE: Non android platform supports concurrency and these overrides shall
* not be used. Also future driver based overrides shall be consolidated in this
* function only. Avoid random overrides in other location based on ini.
*
* Return: 0 for Success or Negative error codes.
*/
static int wlan_hdd_setup_acs_overrides(struct hdd_adapter *ap_adapter)
{
tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
setup_acs_overrides:
hdd_debug("** Driver force ACS override **");
sap_cfg->channel = AUTO_CHANNEL_SELECT;
@ -7491,6 +7506,34 @@ setup_acs_overrides:
return 0;
}
/**
* wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
* @adapter: pointer to adapter struct
*
* This function overrides SAP / P2P Go configuration based on driver INI
* parameters for 11AC override and ACS. These overrides are done to support
* android legacy configuration method.
*
* NOTE: Non android platform supports concurrency and these overrides shall
* not be used. Also future driver based overrides shall be consolidated in this
* function only. Avoid random overrides in other location based on ini.
*
* Return: 0 for Success or Negative error codes.
*/
static int wlan_hdd_setup_driver_overrides(struct hdd_adapter *ap_adapter)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
if (!hdd_ctx->config->vendor_acs_support) {
if (ap_adapter->device_mode == QDF_SAP_MODE &&
hdd_ctx->config->force_sap_acs)
return wlan_hdd_setup_acs_overrides(ap_adapter);
else
return wlan_hdd_sap_p2p_11ac_overrides(ap_adapter);
} else
return 0;
}
/**
* wlan_hdd_cfg80211_start_bss() - start bss
* @adapter: Pointer to hostapd adapter

View file

@ -7199,6 +7199,8 @@ void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel)
int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
{
struct hdd_external_acs_timer_context *timer_context;
int status;
QDF_STATUS qdf_status;
set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
@ -7210,13 +7212,18 @@ int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
timer_context = (struct hdd_external_acs_timer_context *)
adapter->sessionCtx.ap.vendor_acs_timer.user_data;
timer_context->reason = reason;
/* Update config to application and start the timer */
hdd_cfg80211_update_acs_config(adapter, reason);
qdf_mc_timer_start(&adapter->sessionCtx.ap.vendor_acs_timer,
WLAN_VENDOR_ACS_WAIT_TIME);
qdf_status =
qdf_mc_timer_start(&adapter->sessionCtx.ap.vendor_acs_timer,
WLAN_VENDOR_ACS_WAIT_TIME);
if (qdf_status != QDF_STATUS_SUCCESS) {
hdd_err("failed to start external acs timer");
return -ENOSPC;
}
/* Update config to application */
status = hdd_cfg80211_update_acs_config(adapter, reason);
hdd_notice("Updated ACS config to nl with reason %d", reason);
return 0;
return status;
}
/**

View file

@ -1039,8 +1039,8 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId,
0;
}
/* if external acs enabled */
if (sap_ctx->vendor_acs_enabled &&
!mac_ctx->sap.SapDfsInfo.target_channel) {
if (sap_ctx->vendor_acs_dfs_lte_enabled &&
!mac_ctx->sap.SapDfsInfo.target_channel) {
/* Return from here, processing will be done later */
return 0;
}

View file

@ -4293,10 +4293,10 @@ uint8_t sap_indicate_radar(struct sap_context *sap_ctx)
return sap_ctx->chan_before_pre_cac;
}
if (sap_ctx->vendor_acs_enabled && (QDF_STATUS_SUCCESS ==
if (sap_ctx->vendor_acs_dfs_lte_enabled && (QDF_STATUS_SUCCESS ==
sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_NEXT_CHANNEL_REQ,
(void *) eSAP_STATUS_SUCCESS)))
return 0;
return 0;
target_channel = sap_random_channel_sel(sap_ctx);
if (!target_channel)

View file

@ -247,7 +247,7 @@ struct sap_context {
qdf_event_t sap_session_opened_evt;
bool is_pre_cac_on;
bool pre_cac_complete;
bool vendor_acs_enabled;
bool vendor_acs_dfs_lte_enabled;
uint8_t dfs_vendor_channel;
uint8_t dfs_vendor_chan_bw;
uint8_t chan_before_pre_cac;

View file

@ -2327,7 +2327,7 @@ QDF_STATUS wlan_sap_set_vendor_acs(struct sap_context *sap_context,
"%s: Invalid SAP pointer", __func__);
return QDF_STATUS_E_FAULT;
}
sap_context->vendor_acs_enabled = is_vendor_acs;
sap_context->vendor_acs_dfs_lte_enabled = is_vendor_acs;
return QDF_STATUS_SUCCESS;
}