qcacmn: Handle scan failure and vdev start caused by NOL violation

This commit includes the following changes:
Send usenol pdev param to FW.
Set and get dfs_disable_radar_marking flag.
Handle scan failure due to NOL violation.

Change-Id: I814f6381145f98eccf465af730734238c60d8896
CRs-Fixed: 2328894
This commit is contained in:
Priyadarshnee S
2018-10-08 19:35:58 +05:30
committed by nshrivas
parent 26ebbe4492
commit d3173ca81c
11 changed files with 242 additions and 3 deletions

View File

@@ -364,6 +364,28 @@
#define HOST_DFS_STATUS_WAIT_TIMER_MS 200
#endif
/*
* USENOL_DISABLE_NOL_HOST_AND_FW : Do not add radar hit channel to NOL
* in host and FW. Enable CSA on the same channel.
*/
#define USENOL_DISABLE_NOL_HOST_AND_FW 0
/*
* USENOL_ENABLE_NOL_HOST_AND_FW : Add the radar hit channel to NOL in
* host and FW (in case of FO). NOL timer cannot be configured by the user
* as FW does not allow manipulating NOL timeout. If noltimeout is configured,
* (say 1 min) FW will not be intimated about the configuration and hence NOL
* timer may elapse at different instances in host (after 1 min) and FW (after
* default 30 min) which could lead to DFS Violation if host tries to come up
* on the channel after host NOL timeout (of 1 min) as the FW would still
* have the channel in NOL list.
*/
#define USENOL_ENABLE_NOL_HOST_AND_FW 1
/*
* USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW : Add the radar hit channel to NOL
* in host. NOL timer can be configured by user. NOL in FW (for FO) is disabled.
*/
#define USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW 2
/**
* struct dfs_pulseparams - DFS pulse param structure.
* @p_time: Time for start of pulse in usecs.
@@ -979,6 +1001,7 @@ struct dfs_event_log {
* @dfs_bw_reduced: DFS bandwidth reduced channel bit.
* @dfs_freq_offset: Frequency offset where radar was found.
* @dfs_cac_aborted: DFS cac is aborted.
* @dfs_disable_radar_marking: To mark or unmark NOL chan as radar hit.
*/
struct wlan_dfs {
uint32_t dfs_debug_mask;
@@ -1071,7 +1094,9 @@ struct wlan_dfs {
os_timer_t dfs_precac_timer;
int dfs_precac_timeout_override;
uint8_t dfs_num_precac_freqs;
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
uint8_t dfs_disable_radar_marking;
#endif
TAILQ_HEAD(, dfs_precac_entry) dfs_precac_required_list;
TAILQ_HEAD(, dfs_precac_entry) dfs_precac_done_list;
TAILQ_HEAD(, dfs_precac_entry) dfs_precac_nol_list;
@@ -2472,4 +2497,27 @@ void dfs_task_testtimer_detach(struct wlan_dfs *dfs);
* @dfs: Pointer to wlan_dfs structure.
*/
void dfs_timer_detach(struct wlan_dfs *dfs);
/**
* dfs_is_disable_radar_marking_set() - Check if radar marking is set on
* NOL chan.
* @dfs: Pointer to wlan_dfs structure.
*/
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
int dfs_is_disable_radar_marking_set(struct wlan_dfs *dfs,
bool *disable_radar_marking);
#else
static inline int dfs_is_disable_radar_marking_set(struct wlan_dfs *dfs,
bool *disable_radar_marking)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* dfs_get_disable_radar_marking() - Get the value of disable radar marking.
* @dfs: Pointer to wlan_dfs structure.
*/
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs);
#endif
#endif /* _DFS_H_ */

View File

@@ -33,6 +33,9 @@
#include "../dfs_etsi_precac.h"
#include "../dfs_partial_offload_radar.h"
/* Disable NOL in FW. */
#define DISABLE_NOL_FW 0
#ifndef WLAN_DFS_STATIC_MEM_ALLOC
/*
* dfs_alloc_wlan_dfs() - allocate wlan_dfs buffer
@@ -274,6 +277,35 @@ void dfs_destroy_object(struct wlan_dfs *dfs)
}
#endif
/* dfs_set_disable_radar_marking()- Set the flag to mark/unmark a radar flag
* on NOL channel.
* @dfs: Pointer to wlan_dfs structure.
* @disable_radar_marking: Flag to enable/disable marking channel as radar.
*/
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
static void dfs_set_disable_radar_marking(struct wlan_dfs *dfs,
bool disable_radar_marking)
{
dfs->dfs_disable_radar_marking = disable_radar_marking;
}
#else
static inline void dfs_set_disable_radar_marking(struct wlan_dfs *dfs,
bool disable_radar_marking)
{
}
#endif
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs)
{
return dfs->dfs_disable_radar_marking;
}
#else
static inline bool dfs_get_disable_radar_marking(struct wlan_dfs *dfs)
{
return QDF_STATUS_SUCCESS;
}
#endif
int dfs_control(struct wlan_dfs *dfs,
u_int id,
void *indata,
@@ -290,6 +322,7 @@ int dfs_control(struct wlan_dfs *dfs,
uint32_t *data = NULL;
int i;
struct dfs_emulate_bang_radar_test_cmd dfs_unit_test;
int usenol_pdev_param;
qdf_mem_zero(&dfs_unit_test, sizeof(dfs_unit_test));
@@ -574,6 +607,36 @@ int dfs_control(struct wlan_dfs *dfs,
break;
}
dfs->dfs_use_nol = *(uint32_t *)indata;
usenol_pdev_param = dfs->dfs_use_nol;
if (dfs->dfs_is_offload_enabled) {
if (dfs->dfs_use_nol ==
USENOL_ENABLE_NOL_HOST_DISABLE_NOL_FW)
usenol_pdev_param = DISABLE_NOL_FW;
tgt_dfs_send_usenol_pdev_param(dfs->dfs_pdev_obj,
usenol_pdev_param);
}
break;
case DFS_SET_DISABLE_RADAR_MARKING:
if (dfs->dfs_is_offload_enabled &&
(utils_get_dfsdomain(dfs->dfs_pdev_obj) ==
DFS_FCC_DOMAIN)) {
if (insize < sizeof(uint32_t) || !indata) {
error = -EINVAL;
break;
}
dfs_set_disable_radar_marking(dfs, *(uint8_t *)indata);
}
break;
case DFS_GET_DISABLE_RADAR_MARKING:
if (!outdata || !outsize || *outsize < sizeof(uint8_t)) {
error = -EINVAL;
break;
}
if (dfs->dfs_is_offload_enabled) {
*outsize = sizeof(uint8_t);
*((uint8_t *)outdata) =
dfs_get_disable_radar_marking(dfs);
}
break;
case DFS_GET_NOL:
if (!outdata || !outsize ||
@@ -605,12 +668,12 @@ int dfs_control(struct wlan_dfs *dfs,
dfs_print_nolhistory(dfs);
break;
case DFS_BANGRADAR:
dfs->dfs_bangradar = 1;
if (dfs->dfs_is_offload_enabled) {
error = dfs_fill_emulate_bang_radar_test(dfs,
SEG_ID_PRIMARY,
&dfs_unit_test);
} else {
dfs->dfs_bangradar = 1;
error = dfs_start_host_based_bangradar(dfs);
}
break;

View File

@@ -52,13 +52,15 @@
#define DFS_SHOW_PRECAC_LISTS 24
#define DFS_RESET_PRECAC_LISTS 25
#define DFS_BANGRADAR_ENH 26
#define DFS_SET_DISABLE_RADAR_MARKING 27
#define DFS_GET_DISABLE_RADAR_MARKING 28
/*
* Spectral IOCTLs use DFS_LAST_IOCTL as the base.
* This must always be the last IOCTL in DFS and have
* the highest value.
*/
#define DFS_LAST_IOCTL 27
#define DFS_LAST_IOCTL 29
#ifndef DFS_CHAN_MAX
#define DFS_CHAN_MAX 1023

View File

@@ -267,4 +267,18 @@ bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
return true;
}
#endif
/**
* dfs_mlme_handle_dfs_scan_violation() - Handle scan start failure
* due to DFS violation (presence of NOL channel in scan channel list).
* @pdev: Pointer to pdev object.
*/
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev);
#else
static inline
void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
{
}
#endif
#endif /* _WLAN_DFS_MLME_API_H_ */

View File

@@ -402,4 +402,22 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev)
* Return: true if the pdev supports 5GHz, else false.
*/
bool tgt_dfs_is_pdev_5ghz(struct wlan_objmgr_pdev *pdev);
/**
* tgt_dfs_send_usenol_pdev_param() - Send usenol pdev param to FW.
* @pdev: Pointer to pdev object.
* @usenol: Value of usenol
*
* Return: QDF_STATUS
*/
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
bool usenol);
#else
static inline
QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
bool usenol)
{
return QDF_STATUS_SUCCESS;
}
#endif
#endif /* _WLAN_DFS_TGT_API_H_ */

View File

@@ -59,6 +59,8 @@
* @mlme_check_allowed_prim_chanlist: Check whether the given channel is
* present in the primary allowed channel
* list or not.
* @mlme_update_scan_channel_list: Update the scan channel list sent to FW.
* @mlme_bringdown_vaps: Bringdown vaps if no chans is present.
*/
struct dfs_to_mlme {
QDF_STATUS (*pdev_component_obj_attach)(struct wlan_objmgr_pdev *pdev,
@@ -141,6 +143,10 @@ struct dfs_to_mlme {
(struct wlan_objmgr_pdev *pdev, int no_chans_avail);
bool (*mlme_check_allowed_prim_chanlist)
(struct wlan_objmgr_pdev *pdev, uint32_t chan_num);
QDF_STATUS (*mlme_update_scan_channel_list)
(struct wlan_objmgr_pdev *pdev);
QDF_STATUS (*mlme_bringdown_vaps)
(struct wlan_objmgr_pdev *pdev);
};
extern struct dfs_to_mlme global_dfs_to_mlme;

View File

@@ -571,4 +571,22 @@ void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
*/
bool utils_dfs_check_for_cac_start(struct wlan_objmgr_pdev *pdev,
bool *continue_current_cac);
/**
* utils_dfs_get_disable_radar_marking - Retrieve the value of disable radar
* marking.
* @pdev: Pointer to DFS pdev object.
* @dis_radar_marking: pointer to retrieve the value of disable_radar_marking.
*/
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
bool *disable_radar_marking);
#else
static inline
QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
bool *disable_radar_marking)
{
return QDF_STATUS_SUCCESS;
}
#endif
#endif /* _WLAN_DFS_UTILS_API_H_ */

View File

@@ -34,6 +34,8 @@
#include "a_types.h"
#include "wlan_serialization_api.h"
#include <qdf_trace.h>
#include "wlan_scan_ucfg_api.h"
#include "wlan_dfs_mlme_api.h"
struct dfs_to_mlme global_dfs_to_mlme;
@@ -102,6 +104,10 @@ 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;
tmp_dfs_to_mlme->mlme_update_scan_channel_list =
mlme_dfs_update_scan_channel_list;
tmp_dfs_to_mlme->mlme_bringdown_vaps =
mlme_dfs_bringdown_vaps;
/*
* Register precac auto channel switch feature related callbacks

View File

@@ -26,6 +26,7 @@
#include "wlan_objmgr_pdev_obj.h"
#include "../../core/src/dfs.h"
#include "scheduler_api.h"
#include <wlan_reg_ucfg_api.h>
#ifdef QCA_MCL_DFS_SUPPORT
#include "wni_api.h"
#endif
@@ -322,4 +323,18 @@ bool dfs_mlme_check_allowed_prim_chanlist(struct wlan_objmgr_pdev *pdev,
return global_dfs_to_mlme.mlme_check_allowed_prim_chanlist(pdev,
chan_num);
}
#endif
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
void dfs_mlme_handle_dfs_scan_violation(struct wlan_objmgr_pdev *pdev)
{
bool dfs_enable = 0;
/*Disable all DFS channels in master channel list and ic channel list */
ucfg_reg_enable_dfs_channels(pdev, dfs_enable);
/* send the updated channel list to FW */
global_dfs_to_mlme.mlme_update_scan_channel_list(pdev);
}
#endif

View File

@@ -584,3 +584,29 @@ QDF_STATUS tgt_dfs_reset_spoof_test(struct wlan_objmgr_pdev *pdev)
qdf_export_symbol(tgt_dfs_reset_spoof_test);
#endif
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
QDF_STATUS tgt_dfs_send_usenol_pdev_param(struct wlan_objmgr_pdev *pdev,
bool usenol)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "psoc is null");
return QDF_STATUS_E_FAILURE;
}
dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
if (dfs_tx_ops && dfs_tx_ops->dfs_send_usenol_pdev_param)
return dfs_tx_ops->dfs_send_usenol_pdev_param(pdev, usenol);
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
"dfs_tx_ops=%pK", dfs_tx_ops);
return QDF_STATUS_E_FAILURE;
}
qdf_export_symbol(tgt_dfs_send_usenol_pdev_param);
#endif

View File

@@ -979,3 +979,26 @@ int dfs_get_num_chans(void)
{
return NUM_CHANNELS;
}
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
bool *disable_radar_marking)
{
struct wlan_dfs *dfs;
if (!tgt_dfs_is_pdev_5ghz(pdev))
return QDF_STATUS_SUCCESS;
dfs = global_dfs_to_mlme.pdev_get_comp_private_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null");
return QDF_STATUS_E_FAILURE;
}
*disable_radar_marking = dfs_get_disable_radar_marking(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_get_disable_radar_marking);
#endif