qcacmn: Enable configurable dfs_pri_multiplier

Enable configurable dfs_pri_multiplier. The ETSI typ2 type3 radar
detection ratio is lower than expected(>80%) while channel loading is
high(>30%). The host improvement for this are:
	1. Add configurable dfs_pri_multiplier, controlled by
	   DFS_PRI_MULTIPLIER. Default value 2, min 1, max 10.
	2. Lower adrastea ETSI type 2/3/4 radar filter rssi_threshold,
	   controlled by DFS_OVERRIDE_RF_THRESHOLD, dfs log shows that
	   QCS405 target report RSSI range [18, 45] while radar power
	   is 3 dbm. By using default rssi_threshold 24 will reject
	   many radar pulses, which leads to low detection ratio.
	3. Calculate deltapri for each searchpri based on dfs_pri_multiplier
	   in dfs_count_the_other_delay_elements(), check deltapri
	   between [1, dfs_pri_multiplier] * refpri and searchpri, if
	   the primargin is desired, mark it as matched pulse.
	4. Pick lowpri as refpri for the radar filter with
	   rf_ignore_pri_window equals to 0 while DFS_PRI_MULTIPLIER is
	   enabled. Observed original findref logic has some problems
	   which selects refpri is bigger than lowpri, which leads to
	   the lowpri pulses pri_match are set to 0, and in this case,
	   radar was not detected. Example for the issue, assume
	   rf->rf_pulseid 34 (ETSI type 2) has 7 pulses with pri:
	   1489, 2978, 2978, 2978, 1489, 2978, 1489 us in this case,
	   highscore is 4 (2978), scoreindex is 5, refpri is 2978, which
	   leads to: index 0, 4, 6 pulses with pri_match 0 in
	   dfs_count_the_other_delay_elements(). The fix is to select
	   lowpri as refpri(1489 in this case).

Change-Id: I1f3ca3298c9ab1f1e2651ad6b4a0a4810f83f8a1
CRs-Fixed: 2531811
This commit is contained in:
Hangtian Zhu
2019-09-20 14:36:31 +08:00
committed by nshrivas
parent 31a575b99e
commit 62547ed826
8 changed files with 157 additions and 9 deletions

View File

@@ -494,6 +494,14 @@ bool target_is_tgt_type_qca9984(uint32_t target_type);
*/
bool target_is_tgt_type_qca9888(uint32_t target_type);
/**
* target_is_tgt_type_adrastea() - Check if the target type is QCS40X
* @target_type: target type to be checked.
*
* Return: true if the target_type is QCS40X, else false.
*/
bool target_is_tgt_type_adrastea(uint32_t target_type);
/**
* target_psoc_set_wlan_init_status() - set info wlan_init_status

View File

@@ -362,6 +362,9 @@ static void target_if_target_tx_ops_register(
target_tx_ops->tgt_is_tgt_type_qca9888 =
target_is_tgt_type_qca9888;
target_tx_ops->tgt_is_tgt_type_adrastea =
target_is_tgt_type_adrastea;
target_tx_ops->tgt_get_tgt_type =
lmac_get_tgt_type;
@@ -597,3 +600,8 @@ bool target_is_tgt_type_qca9888(uint32_t target_type)
{
return target_type == TARGET_TYPE_QCA9888;
}
bool target_is_tgt_type_adrastea(uint32_t target_type)
{
return target_type == TARGET_TYPE_ADRASTEA;
}

View File

@@ -213,6 +213,27 @@ static bool target_if_dfs_offload(struct wlan_objmgr_psoc *psoc)
wmi_service_dfs_phyerr_offload);
}
static QDF_STATUS target_if_dfs_get_target_type(struct wlan_objmgr_pdev *pdev,
uint32_t *target_type)
{
struct wlan_objmgr_psoc *psoc;
struct target_psoc_info *tgt_psoc_info;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
target_if_err("null psoc");
return QDF_STATUS_E_FAILURE;
}
tgt_psoc_info = wlan_psoc_get_tgt_if_handle(psoc);
if (!tgt_psoc_info) {
target_if_err("null tgt_psoc_info");
return QDF_STATUS_E_FAILURE;
}
*target_type = target_psoc_get_target_type(tgt_psoc_info);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS target_if_dfs_register_event_handler(
struct wlan_objmgr_psoc *psoc)
{
@@ -386,5 +407,6 @@ QDF_STATUS target_if_register_dfs_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
&target_send_usenol_pdev_param;
dfs_tx_ops->dfs_send_subchan_marking_pdev_param =
&target_send_subchan_marking_pdev_param;
dfs_tx_ops->dfs_get_target_type = &target_if_dfs_get_target_type;
return QDF_STATUS_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2002-2010, Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -322,6 +322,7 @@ void dfs_add_pulse(
dl->dl_numelems = n+1;
}
}
dfs_debug(dfs, WLAN_DEBUG_DFS2, "dl firstElem = %d lastElem = %d",
dl->dl_firstelem, dl->dl_lastelem);
}
@@ -544,6 +545,55 @@ static inline int dfs_bin_basic_sanity(
return 1;
}
/**
* dfs_pick_lowpri() - Pick lowpri as refpri
* @dfs: Pointer to wlan_dfs structure.
* @dl: Pointer to dfs delayline.
* @rf: Pointer to dfs_filter structure.
* @lowpriindex: Low PRI index.
* @scoreindex: score index.
* @primargin: PRI margin.
*/
#ifdef DFS_PRI_MULTIPLIER
static inline void dfs_pick_lowpri(struct wlan_dfs *dfs,
struct dfs_delayline *dl,
struct dfs_filter *rf,
uint32_t lowpriindex,
uint32_t *scoreindex,
uint32_t primargin)
{
uint32_t candidate_refpri, deltapri, lowpri;
uint32_t dindex_candidate, dindex_lowpri;
uint32_t i;
dindex_candidate = (dl->dl_firstelem + *scoreindex) & DFS_MAX_DL_MASK;
dindex_lowpri = (dl->dl_firstelem + lowpriindex) & DFS_MAX_DL_MASK;
candidate_refpri = dl->dl_elems[dindex_candidate].de_time;
lowpri = dl->dl_elems[dindex_lowpri].de_time;
if (rf->rf_ignore_pri_window == 0 &&
candidate_refpri != lowpri) {
for (i = 1; i <= dfs->dfs_pri_multiplier; i++) {
deltapri = DFS_DIFF(candidate_refpri, i * lowpri);
if (deltapri < primargin) {
*scoreindex = lowpriindex;
break;
}
}
}
}
#else
static inline void dfs_pick_lowpri(struct wlan_dfs *dfs,
struct dfs_delayline *dl,
struct dfs_filter *rf,
uint32_t lowpriindex,
uint32_t *scoreindex,
uint32_t primargin)
{
}
#endif
/**
* dfs_find_scoreindex() - Find score index
* @rf: Pointer to dfs_filter structure.
@@ -667,6 +717,18 @@ int dfs_bin_check(
dfs_find_scoreindex(rf, highscore, lowpriindex, highscoreindex,
&scoreindex);
/*
* Observed ETSI type2 while channel loading 31% with pulse pri:
* 1489, 2978, 2978, 2978, 1489, 2978, 1489 us. With above logic,
* the highscore will be 4 (2978), scoreindex is 5. In this case,
* index 0, 4, 6 pulses will be not matched later in
* dfs_count_the_other_delay_elements(), which leads to the radar was
* not detected. The fix is: compare the highscore pri with lowpri,
* if they have relationship, within primargin of
* [1, dfs_pri_multiplier] times of lowpri, choose lowpri as refpri.
*/
dfs_pick_lowpri(dfs, dl, rf, lowpriindex, &scoreindex, primargin);
/* We got the possible pri, save its parameters as reference. */
dfs_find_refs(dl, rf, scoreindex, &refdur, &refpri);
@@ -802,8 +864,8 @@ static void dfs_count_the_other_delay_elements(
int fundamentalpri)
{
int delayindex;
uint32_t searchpri, searchdur, deltadur, deltapri1, deltapri2;
uint32_t j = 0, delta_time_stamps, deltapri;
uint32_t searchpri, searchdur, deltadur;
uint32_t j = 0, delta_time_stamps, deltapri, k;
int dindex, primatch, numpulsetochk = 2;
int32_t sidx_min = DFS_BIG_SIDX;
int32_t sidx_max = -DFS_BIG_SIDX;
@@ -819,23 +881,28 @@ static void dfs_count_the_other_delay_elements(
dl->dl_elems[dindex].de_time -= refpri;
searchpri = refpri;
}
searchdur = dl->dl_elems[delayindex].de_dur;
deltadur = DFS_DIFF(searchdur, refdur);
deltapri = DFS_DIFF(searchpri, refpri);
deltapri1 = DFS_DIFF(searchpri, refpri);
deltapri2 = DFS_DIFF(searchpri, 2 * refpri);
primatch = 0;
if ((rf->rf_ignore_pri_window > 0) && (rf->rf_patterntype != 2)) {
for (j = 0; j < rf->rf_numpulses; j++) {
deltapri1 = DFS_DIFF(searchpri, (j + 1) * refpri);
if (deltapri1 < (2 * primargin)) {
deltapri = DFS_DIFF(searchpri, (j + 1) * refpri);
if (deltapri < (2 * primargin)) {
primatch = 1;
break;
}
}
} else {
for (k = 1; k <= dfs->dfs_pri_multiplier; k++) {
deltapri = DFS_DIFF(searchpri, k * refpri);
if (deltapri < primargin) {
primatch = 1;
break;
}
}
} else if ((deltapri1 < primargin) || (deltapri2 < primargin)) {
primatch = 1;
}
if (primatch && (deltadur < durmargin)) {

View File

@@ -262,6 +262,7 @@ static struct dfs_pulse dfs_korea_radars[] = {
};
#define RSSI_THERSH_AR900B 15
#define RSSI_THERSH_ADRASTEA 18
/**
* dfs_assign_fcc_pulse_table() - Assign FCC pulse table
@@ -292,6 +293,37 @@ static inline void dfs_assign_fcc_pulse_table(
}
}
#ifdef DFS_OVERRIDE_RF_THRESHOLD
static void dfs_set_adrastea_rf_thrshold(
struct wlan_objmgr_psoc *psoc,
int dfsdomain,
uint32_t target_type,
struct wlan_dfs_radar_tab_info *rinfo)
{
int i;
struct wlan_lmac_if_target_tx_ops *tx_ops;
tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops;
if (tx_ops->tgt_is_tgt_type_adrastea(target_type) &&
dfsdomain == DFS_ETSI_DOMAIN) {
for (i = 0; i < rinfo->numradars; i++) {
rinfo->dfs_radars[i].rp_rssithresh =
DFS_MIN(rinfo->dfs_radars[i].rp_rssithresh,
RSSI_THERSH_ADRASTEA);
}
}
}
#else
static inline void dfs_set_adrastea_rf_thrshold(
struct wlan_objmgr_psoc *psoc,
int dfsdomain,
uint32_t target_type,
struct wlan_dfs_radar_tab_info *rinfo)
{
}
#endif
void dfs_get_po_radars(struct wlan_dfs *dfs)
{
struct wlan_dfs_radar_tab_info rinfo;
@@ -426,6 +458,8 @@ void dfs_get_po_radars(struct wlan_dfs *dfs)
rinfo.dfs_radars[i].rp_rssithresh = RSSI_THERSH_AR900B;
}
dfs_set_adrastea_rf_thrshold(psoc, dfsdomain, target_type, &rinfo);
WLAN_DFS_DATA_STRUCT_LOCK(dfs);
dfs_init_radar_filters(dfs, &rinfo);
WLAN_DFS_DATA_STRUCT_UNLOCK(dfs);

View File

@@ -719,6 +719,12 @@ int dfs_control(struct wlan_dfs *dfs,
}
dfs_allow_hw_pulses(dfs, !!(*(u_int8_t *)indata));
break;
case DFS_SET_PRI_MULTIPILER:
dfs->dfs_pri_multiplier = *(int *)indata;
dfs_debug(dfs, WLAN_DEBUG_DFS_ALWAYS,
"Set dfs pri multiplier to %d, dfsdomain %d",
dfs->dfs_pri_multiplier, dfs->dfsdomain);
break;
default:
error = -EINVAL;
}

View File

@@ -55,6 +55,7 @@
#define DFS_INJECT_SEQUENCE 27
#define DFS_ALLOW_HW_PULSES 28
#define DFS_SET_PRI_MULTIPILER 29
/*
* Spectral IOCTLs use DFS_LAST_IOCTL as the base.

View File

@@ -798,6 +798,7 @@ struct wlan_lmac_if_dfs_tx_ops {
* @tgt_is_tgt_type_ipq4019: To check IPQ4019 target type.
* @tgt_is_tgt_type_qca9984: To check QCA9984 target type.
* @tgt_is_tgt_type_qca9888: To check QCA9888 target type.
* @tgt_is_tgt_type_adrastea: To check QCS40X target type.
* @tgt_get_tgt_type: Get target type
* @tgt_get_tgt_version: Get target version
* @tgt_get_tgt_revision: Get target revision
@@ -807,6 +808,7 @@ struct wlan_lmac_if_target_tx_ops {
bool (*tgt_is_tgt_type_ipq4019)(uint32_t);
bool (*tgt_is_tgt_type_qca9984)(uint32_t);
bool (*tgt_is_tgt_type_qca9888)(uint32_t);
bool (*tgt_is_tgt_type_adrastea)(uint32_t);
uint32_t (*tgt_get_tgt_type)(struct wlan_objmgr_psoc *psoc);
uint32_t (*tgt_get_tgt_version)(struct wlan_objmgr_psoc *psoc);
uint32_t (*tgt_get_tgt_revision)(struct wlan_objmgr_psoc *psoc);