qcacmn: PreCAC auto channel switch support

Changes to switch to the preferred preCAC channel after the
preCAC is done.
User can configure non-DFS channel as an intermediate
channel to reduce AP bringup time, and configure the DFS
channel as usual. PreCAC Logic will use the intermediate
channel as the home channel and will prioritize the DFS channel
to start preCAC first and switch automatically after the preCAC
timeout.
Command to configure intermediate non-DFS channel
iwpriv wifiX interCACChan <non-DFS channel num>
Assumption:
Intermediate channel should be configured before configuring
the DFS channel as operating channel.

Change-Id: I1dc00fa395aec53bfe5a6361095cd7d77ced503c
CRs-Fixed: 2272085
Этот коммит содержится в:
Shreedhar Parande
2018-05-29 11:13:24 +05:30
коммит произвёл nshrivas
родитель 0508016ef9
Коммит 62f2bb9136
12 изменённых файлов: 755 добавлений и 94 удалений

Просмотреть файл

@@ -135,17 +135,22 @@ int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev,
* @dfs_ch_vhtop_ch_freq_seg1: Channel Center frequency.
* @dfs_ch_vhtop_ch_freq_seg2: Channel Center frequency applicable for 80+80MHz
* mode of operation.
*
* Return:
* * QDF_STATUS_SUCCESS : Channel found.
* * QDF_STATUS_E_FAILURE: Channel not found.
*/
void dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev,
uint8_t ieee,
uint8_t des_cfreq2,
int mode,
uint16_t *dfs_ch_freq,
uint64_t *dfs_ch_flags,
uint16_t *dfs_ch_flagext,
uint8_t *dfs_ch_ieee,
uint8_t *dfs_ch_vhtop_ch_freq_seg1,
uint8_t *dfs_ch_vhtop_ch_freq_seg2);
QDF_STATUS
dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev,
uint8_t ieee,
uint8_t des_cfreq2,
int mode,
uint16_t *dfs_ch_freq,
uint64_t *dfs_ch_flags,
uint16_t *dfs_ch_flagext,
uint8_t *dfs_ch_ieee,
uint8_t *dfs_ch_vhtop_ch_freq_seg1,
uint8_t *dfs_ch_vhtop_ch_freq_seg2);
/**
* dfs_mlme_get_dfs_ch_channels() - Get channel from channel list.
@@ -160,13 +165,13 @@ void dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev,
* @index: Index into channel list.
*/
void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev,
uint16_t *dfs_ch_freq,
uint64_t *dfs_ch_flags,
uint16_t *dfs_ch_flagext,
uint8_t *dfs_ch_ieee,
uint8_t *dfs_ch_vhtop_ch_freq_seg1,
uint8_t *dfs_ch_vhtop_ch_freq_seg2,
int index);
uint16_t *dfs_ch_freq,
uint64_t *dfs_ch_flags,
uint16_t *dfs_ch_flagext,
uint8_t *dfs_ch_ieee,
uint8_t *dfs_ch_vhtop_ch_freq_seg1,
uint8_t *dfs_ch_vhtop_ch_freq_seg2,
int index);
/**
* dfs_mlme_dfs_ch_flags_ext() - Get extension channel flags.

Просмотреть файл

@@ -48,6 +48,8 @@
* @mlme_get_dfs_ch_channels: Get the channel list.
* @mlme_dfs_ch_flags_ext: Gets channel extension flag.
* @mlme_channel_change_by_precac: Channel change triggered by PreCAC.
* @mlme_precac_chan_change_csa: Channel change triggered by PrCAC using
* Channel Switch Announcement.
* @mlme_nol_timeout_notification: NOL timeout notification.
* @mlme_clist_update: Updates the channel list.
* @mlme_get_cac_timeout: Gets the CAC timeout.
@@ -119,6 +121,10 @@ struct dfs_to_mlme {
uint16_t *flag_ext);
QDF_STATUS (*mlme_channel_change_by_precac)(
struct wlan_objmgr_pdev *pdev);
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
QDF_STATUS (*mlme_precac_chan_change_csa)(struct wlan_objmgr_pdev *pdev,
uint8_t ch_ieee);
#endif
QDF_STATUS (*mlme_nol_timeout_notification)(
struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*mlme_clist_update)(struct wlan_objmgr_pdev *pdev,
@@ -227,7 +233,7 @@ QDF_STATUS ucfg_dfs_override_precac_timeout(struct wlan_objmgr_pdev *pdev,
* This function called from outside of dfs component.
*/
QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev,
uint32_t value);
uint32_t value);
/**
* ucfg_dfs_get_precac_enable() - Get precac enable flag.
@@ -239,6 +245,52 @@ QDF_STATUS ucfg_dfs_set_precac_enable(struct wlan_objmgr_pdev *pdev,
*/
QDF_STATUS ucfg_dfs_get_precac_enable(struct wlan_objmgr_pdev *pdev, int *buff);
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
/**
* ucfg_dfs_set_precac_intermediate_chan() - Set intermediate channel
* for preCAC.
* @pdev: Pointer to DFS pdev object.
* @value: Channel number of intermediate channel
*
* Wrapper function for dfs_set_precac_intermediate_chan().
* This function is called from outside of dfs component.
*
* Return:
* * QDF_STATUS_SUCCESS : Successfully set intermediate channel.
* * QDF_STATUS_E_FAILURE: Failed to set intermediate channel.
*/
QDF_STATUS ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
uint32_t value);
/**
* ucfg_dfs_get_precac_intermediate_chan() - Get intermediate channel
* for preCAC.
* @pdev: Pointer to DFS pdev object.
* @buff: Pointer to Channel number of intermediate channel.
*
* Wrapper function for dfs_get_precac_intermediate_chan().
* This function is called from outside of dfs component.
*
* Return: Configured intermediate precac channel.
*/
QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
int *buff);
/**
* ucfg_dfs_get_precac_chan_state() - Get precac status for the given channel.
* @pdev: Pointer to DFS pdev object.
* @precac_chan: Channel number for which precac state needs to be determined.
*
* Wrapper function for dfs_get_precac_chan_state().
* This function called from outside of dfs component.
*
* Return: Precac state of the given channel.
*/
enum precac_chan_state
ucfg_dfs_get_precac_chan_state(struct wlan_objmgr_pdev *pdev,
uint8_t precac_chan);
#endif
#ifdef QCA_MCL_DFS_SUPPORT
/**
* ucfg_dfs_update_config() - Update DFS user config.

Просмотреть файл

@@ -136,6 +136,19 @@ static inline QDF_STATUS utils_dfs_reset_etsi_precaclists(
*/
QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev);
/**
* utils_dfs_start_precac_timer() - Start the precac timer.
* @pdev: Pointer to DFS pdev object.
*
* Wrapper function for dfs_start_precac_timer(). This function called from
* outside of dfs component.
*
* Return:
* * QDF_STATUS_E_FAILURE: Failed to start timer.
* * QDF_STATUS_SUCCESS: Timer started successfully.
*/
QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev);
/**
* utils_dfs_is_precac_done() - Is precac done.
* @pdev: Pointer to DFS pdev object.
@@ -146,6 +159,23 @@ QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev);
QDF_STATUS utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
bool *is_precac_done);
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
/**
* utils_dfs_precac_decide_pref_chan() - Choose preferred channel
* @pdev: Pointer to DFS pdev object.
* @ch_ieee: Pointer to channel number
* Wrapper function for dfs_decide_precac_preferred_chan(). This
* function called from outside of dfs component.
*
* Return:
* * QDF_STATUS_E_FAILURE: Failed to decide preferred channel.
* * QDF_STATUS_SUCCESS: Set preferred channel successfully.
*/
QDF_STATUS utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev,
uint8_t *ch_ieee);
#endif
/**
* utils_dfs_is_esti_precac_done() - Is ETSI precac done.
* @pdev: Pointer to DFS pdev object.

Просмотреть файл

@@ -47,6 +47,23 @@ struct wlan_dfs *wlan_pdev_get_dfs_obj(struct wlan_objmgr_pdev *pdev)
}
#ifndef QCA_MCL_DFS_SUPPORT
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
static inline void
register_dfs_precac_auto_chan_callbacks(struct dfs_to_mlme *mlme_callback)
{
if (!mlme_callback)
return;
mlme_callback->mlme_precac_chan_change_csa =
mlme_dfs_precac_chan_change_csa;
}
#else
static inline void
register_dfs_precac_auto_chan_callbacks(struct dfs_to_mlme *mlme_callback)
{
}
#endif
void register_dfs_callbacks(void)
{
struct dfs_to_mlme *tmp_dfs_to_mlme = &global_dfs_to_mlme;
@@ -85,6 +102,11 @@ void register_dfs_callbacks(void)
mlme_dfs_restart_vaps_with_non_dfs_chan;
tmp_dfs_to_mlme->mlme_check_allowed_prim_chanlist =
mlme_dfs_check_allowed_prim_chanlist;
/*
* Register precac auto channel switch feature related callbacks
*/
register_dfs_precac_auto_chan_callbacks(tmp_dfs_to_mlme);
}
#else
void register_dfs_callbacks(void)

Просмотреть файл

@@ -188,28 +188,30 @@ int dfs_mlme_ieee2mhz(struct wlan_objmgr_pdev *pdev, int ieee, uint64_t flag)
return freq;
}
void dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev,
uint8_t ieee,
uint8_t des_cfreq2,
int mode,
uint16_t *dfs_ch_freq,
uint64_t *dfs_ch_flags,
uint16_t *dfs_ch_flagext,
uint8_t *dfs_ch_ieee,
uint8_t *dfs_ch_vhtop_ch_freq_seg1,
uint8_t *dfs_ch_vhtop_ch_freq_seg2)
QDF_STATUS
dfs_mlme_find_dot11_channel(struct wlan_objmgr_pdev *pdev,
uint8_t ieee,
uint8_t des_cfreq2,
int mode,
uint16_t *dfs_ch_freq,
uint64_t *dfs_ch_flags,
uint16_t *dfs_ch_flagext,
uint8_t *dfs_ch_ieee,
uint8_t *dfs_ch_vhtop_ch_freq_seg1,
uint8_t *dfs_ch_vhtop_ch_freq_seg2)
{
if (global_dfs_to_mlme.mlme_find_dot11_channel != NULL)
global_dfs_to_mlme.mlme_find_dot11_channel(pdev,
ieee,
des_cfreq2,
mode,
dfs_ch_freq,
dfs_ch_flags,
dfs_ch_flagext,
dfs_ch_ieee,
dfs_ch_vhtop_ch_freq_seg1,
dfs_ch_vhtop_ch_freq_seg2);
return global_dfs_to_mlme.mlme_find_dot11_channel(pdev,
ieee,
des_cfreq2,
mode,
dfs_ch_freq,
dfs_ch_flags,
dfs_ch_flagext,
dfs_ch_ieee,
dfs_ch_vhtop_ch_freq_seg1,
dfs_ch_vhtop_ch_freq_seg2);
return QDF_STATUS_E_FAILURE;
}
void dfs_mlme_get_dfs_ch_channels(struct wlan_objmgr_pdev *pdev,

Просмотреть файл

@@ -154,6 +154,62 @@ QDF_STATUS ucfg_dfs_get_precac_enable(struct wlan_objmgr_pdev *pdev,
}
qdf_export_symbol(ucfg_dfs_get_precac_enable);
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
QDF_STATUS ucfg_dfs_set_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
uint32_t value)
{
struct wlan_dfs *dfs;
dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return QDF_STATUS_E_FAILURE;
}
dfs_set_precac_intermediate_chan(dfs, value);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS ucfg_dfs_get_precac_intermediate_chan(struct wlan_objmgr_pdev *pdev,
int *buff)
{
struct wlan_dfs *dfs;
dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return QDF_STATUS_E_FAILURE;
}
*buff = dfs_get_precac_intermediate_chan(dfs);
return QDF_STATUS_SUCCESS;
}
enum precac_chan_state
ucfg_dfs_get_precac_chan_state(struct wlan_objmgr_pdev *pdev,
uint8_t precac_chan)
{
struct wlan_dfs *dfs;
enum precac_chan_state retval = PRECAC_ERR;
dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return PRECAC_ERR;
}
retval = dfs_get_precac_chan_state(dfs, precac_chan);
if (PRECAC_ERR == retval) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
"Could not find precac channel state");
}
return retval;
}
#endif
#ifdef QCA_MCL_DFS_SUPPORT
QDF_STATUS ucfg_dfs_update_config(struct wlan_objmgr_psoc *psoc,
struct dfs_user_config *req)

Просмотреть файл

@@ -118,6 +118,36 @@ QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev)
}
qdf_export_symbol(utils_dfs_cancel_precac_timer);
QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
return QDF_STATUS_E_FAILURE;
}
dfs_start_precac_timer(dfs, dfs->dfs_precac_secondary_freq);
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
QDF_STATUS utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev,
uint8_t *ch_ieee)
{
struct wlan_dfs *dfs;
dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
return QDF_STATUS_E_FAILURE;
}
dfs_decide_precac_preferred_chan(dfs, ch_ieee);
return QDF_STATUS_SUCCESS;
}
#endif
QDF_STATUS utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
bool *is_precac_done)
{
@@ -127,7 +157,7 @@ QDF_STATUS utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
if (!dfs)
return QDF_STATUS_E_FAILURE;
*is_precac_done = dfs_is_precac_done(dfs);
*is_precac_done = dfs_is_precac_done(dfs, dfs->dfs_curchan);
return QDF_STATUS_SUCCESS;
}