qcacmn: Restructure dfs_check_for_cac_start API

In dfs_check_for_cac_start API, the following checks (in addition
to few more unchanged ones) are done:
  1. If CAC timer is running, is the current channel a subset of the
     CAC started channel (dfs_cac_started_chan).
  2. If CAC timer is not running, is the current channel a subset of the
     last CAC started channel and was the last CAC not aborted.

The variable dfs_cac_started_chan is filled when CAC timer is started. It
is then reset only if, after vdev response, if the new channel is non DFS
or when the next CAC timer is started (with new channel value).

With the above logic, the cases where CAC is not skipped for a DFS
channel (e.g. preCACed channel) is not taken care of.

Consider the following scenario:
 1. The current channel is 100 and the preCAC is completed on all
    channels.
 2. When CAC is started on this channel (100), the dfs_cac_started_chan
    becomes 100.
 3. If radar is found on 100 and the new channel selected is one
    of the preCACed DFS channels, CAC is skipped.
    dfs_cac_started_chan still remains 100.
 4. After NOL timeout, if the radio is switched back to 100, the last
    CAC started channel is 100 and new channel is also 100, which results
    in CAC being skipped.

Rewrite the dfs_check_for_cac_start logic by checking the following:
  1. If CAC timer is running, check if the current channel is a
     subset of dfs_cac_started_chan.
  2. If CAC timer is not running, check if the current channel is a
     subset of previous channel (input).

Clear the dfs_cac_started_chan when the CAC timer stops or expires.

Also, in the API "dfs_is_subset_channel", while checking if one channel
is a subset of another, the DFS subchannels are determined based on the
channel flags. This is handled for two cases:
 1. If secondary channel alone is DFS.
 2. If primary and secondary channels are DFS.

The case "If primary channel alone is DFS" is not handled.

In case of channel 116HT80_80 with secondary 80 being non DFS,
all subchannels are considered as DFS subchannels.

Add a new API "dfs_find_dfs_sub_channels" where all the above
mentioned cases of DFS channels are handled to find proper DFS
subchannels.

Change-Id: I893430ff010746c84ce340323b25c17af25bc45a
CRs-Fixed: 2504840
Цей коміт міститься в:
Vignesh Mohan
2019-08-14 15:43:31 +05:30
зафіксовано nshrivas
джерело 10b86d636a
коміт 7d7cb84e5e
4 змінених файлів з 143 додано та 108 видалено

Переглянути файл

@@ -729,16 +729,20 @@ void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev,
bool nol_history_ch);
/**
* utils_dfs_check_for_cac_start() - Check for DFS CAC start conditions.
* utils_dfs_is_cac_required() - Check if CAC is required on the cur_chan.
* @pdev: pdev ptr
* @cur_chan: Pointer to current channel of wlan_channel structure.
* @prev_chan: Pointer to previous channel of wlan_channel structure.
* @continue_current_cac: If AP can start CAC then this variable indicates
* whether to continue with the current CAC or restart the CAC. This variable
* is valid only if this function returns true.
*
* Return: true if AP can start or continue the current CAC, else false.
* Return: true if AP requires CAC or can continue current CAC, else false.
*/
bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev,
bool *continue_current_cac);
bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev,
struct wlan_channel *cur_chan,
struct wlan_channel *prev_chan,
bool *continue_current_cac);
/** utils_dfs_is_precac_done() - Check if precac has been done in chosen channel
* @pdev: Pointer to DFS pdev object.
@@ -779,10 +783,4 @@ QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
*/
void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq,
enum WLAN_DFS_EVENTS event);
/**
* utils_dfs_clear_cac_started_chan() - Clear dfs cac started channel.
* @pdev: pdev ptr
*/
void utils_dfs_clear_cac_started_chan(struct wlan_objmgr_pdev *pdev);
#endif /* _WLAN_DFS_UTILS_API_H_ */

Переглянути файл

@@ -233,17 +233,6 @@ QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev)
}
qdf_export_symbol(utils_dfs_cac_stop);
void utils_dfs_clear_cac_started_chan(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return;
dfs_clear_cac_started_chan(dfs);
}
/** dfs_fill_chan_info() - Fill the dfs channel structure with wlan
* channel.
* @chan: Pointer to DFS channel structure.
@@ -277,16 +266,26 @@ bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
return dfs_is_precac_done(dfs, &chan);
}
bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev,
bool *continue_current_cac)
bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev,
struct wlan_channel *cur_chan,
struct wlan_channel *prev_chan,
bool *continue_current_cac)
{
struct wlan_dfs *dfs;
struct dfs_channel cur_channel;
struct dfs_channel prev_channel;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return false;
return dfs_check_for_cac_start(dfs, continue_current_cac);
dfs_fill_chan_info(&cur_channel, cur_chan);
dfs_fill_chan_info(&prev_channel, prev_chan);
return dfs_is_cac_required(dfs,
&cur_channel,
&prev_channel,
continue_current_cac);
}
QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev)