qcacmn: Moving spectral module to cmn_dev

As part of second phase of Spectral Analysis(SA)
convergence [WIN & MCL], spectral module code is being moved to cmn_dev.
Also includes fixes for checkpatch.

CRs-Fixed: 2146231
Change-Id: I939509193786b0bd2cbd5f1af64d4a94739a2af5
This commit is contained in:
Shiva Krishna Pittala
2017-11-07 11:56:58 +05:30
committed by snandini
parent f5a56570a9
commit de0cb20d07
23 changed files with 10098 additions and 0 deletions

205
spectral/Kbuild Normal file
View File

@@ -0,0 +1,205 @@
ifeq ($(obj),)
obj := .
endif
DEPTH := ../..
ifeq ($(strip ${QCA_PARTNER_MAKE_F_SUPPORT}),1)
export QCA_PARTNER_MAKE_F_INC=1
endif
include $(obj)/$(DEPTH)/os/linux/Makefile-linux.common
INCS += -I$(HAL) -I$(HAL)/$(OS) -I$(ATH) -I$(ATH_RATE) -I$(ATH_PKTLOG) -I$(WLAN) -I$(IF_WLAN) -I$(ATH_SPECTRAL) -I$(ATHEROSPATH) -I$(obj)/$(DEPTH)/../../apps/spectral/common
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/inc -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/obj_mgr/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/cmn_defs/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/scan/dispatcher/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/cmn_defs/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/global_umac_dispatcher/lmac_if/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/scheduler/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/global_lmac_if/inc
INCS += -I$(obj)/$(DEPTH)/umac/scan
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/mgmt_txrx/dispatcher/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/regulatory/dispatcher/inc
INCS += -I$(obj)/$(DEPTH)/umac/son/dispatcher/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/dfs/dispatcher/inc
ifeq ($(WLAN_CONV_CRYPTO_SUPPORTED), 1)
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/crypto/inc
endif
#Start of offload related deifines
HOST_CMN_CONVG_SRC := $(DEPTH)/cmn_dev
HOST_CMN_CONVG_HIF_SRC := $(DEPTH)/cmn_dev/hif/src
HOST_CMN_CONVG_HIF_INC1 := $(DEPTH)/cmn_dev/hif
HOST_CMN_CONVG_HTC_INC := $(DEPTH)/cmn_dev/htc
HOST_CMN_CONVG_DP_INC := $(DEPTH)/cmn_dev/dp/wifi3.0
HOST_CMN_CONVG_CFG_INC := $(DEPTH)/cmn_dev/wlan_cfg
HOST_CMN_CONVG_HAL_INC := $(DEPTH)/cmn_dev/hal/inc
HOST_CMN_CONVG_HAL_WIFI_INC := $(DEPTH)/cmn_dev/hal/wifi3.0
INCS += -I$(obj)/$(DEPTH)/include -I$(obj)/$(DEPTH)/umac/include \
-I$(obj)/$(DEPTH)/umac/if_lmac -I$(obj)/$(DEPTH)/umac/crypto \
-I$(obj)/$(DEPTH)/umac/scan -I$(obj)/$(DEPTH)/umac/resmgr \
-I$(obj)/$(DEPTH)/umac/pm -I$(obj)/$(DEPTH)/umac/txrx \
-I$(obj)/$(DEPTH)/umac/acs -I$(obj)/$(DEPTH)/umac/txbf \
-I$(obj)/$(DEPTH)/umac/wnm \
-I$(obj)/$(DEPTH)/umac/tdls \
-I$(obj)/$(DEPTH)/umac/rpt_placement \
-I$(obj)/$(DEPTH)/umac/wifipos \
-I$(obj)/$(DEPTH)/umac/wds -I$(obj)/$(DEPTH)/umac/ique \
-I$(obj)/$(DEPTH)/hal -I$(obj)/$(DEPTH)/lmac/ath_dev \
-I$(obj)/$(DEPTH)/hal/$(OS) \
-I$(obj)/$(DEPTH)/umac/vi_dbg \
-I$(obj)/$(DEPTH)/umac/smart_antenna \
-I$(obj)/$(DEPTH)/umac/smart_ant \
-I$(obj)/$(DEPTH)/umac/ald \
-I$(obj)/$(DEPTH)/lmac/ath_pktlog \
-I$(obj)/$(DEPTH)/lmac/ratectrl \
-I$(obj)/$(DEPTH)/os/linux/mem/ \
-I$(obj)/$(DEPTH)/umac/base \
-I$(obj)/$(DEPTH)/qca_ol \
-I$(obj)/$(DEPTH)/cmn_dev/qdf/inc \
-I$(obj)/$(DEPTH)/cmn_dev/qdf/linux/src \
-I$(obj)/$(DEPTH)/cmn_dev/hif \
-I$(obj)/$(DEPTH)/cmn_dev/hif/inc \
-I$(obj)/$(DEPTH)/cmn_dev/hif/src \
-I$(obj)/$(DEPTH)/cmn_dev/hif/src/ce \
-I$(obj)/$(DEPTH)/cmn_dev/hif/src/pcie \
-I$(obj)/$(DEPTH)/cmn_dev/hif/src/snoc \
-I$(obj)/$(DEPTH)/cmn_dev/hif/src/dispatcher \
-I$(obj)/$(DEPTH)/cmn_dev/pld_stub/inc \
-I$(obj)/$(DEPTH)/cmn_dev/hal/inc \
-I$(obj)/$(DEPTH)/cmn_dev/hal/wifi3.0 \
-I$(obj)/$(DEPTH)/cmn_dev/dp/inc \
-I$(obj)/$(DEPTH)/cmn_dev/dp/wifi3.0 \
-I$(obj)/$(DEPTH)/cmn_dev/wlan_cfg \
-I$(obj)/$(HOST_CMN_CONVG_SRC)/htc \
-I$(obj)/$(DEPTH)/cmn_dev/wmi/inc \
-I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/obj_mgr/inc \
-I$(obj)/$(HOST_CMN_CONVG_SRC)/scheduler/inc \
-I$(obj)/$(HOST_CMN_CONVG_SRC)/init_deinit/dispatcher/inc \
-I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/inc \
-I$(obj)/$(DEPTH)/cmn_dev/umac/global_umac_dispatcher/lmac_if/inc \
-I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/mgmt_txrx/dispatcher/inc \
-I$(obj)/$(DEPTH)/cmn_dev/target_if/init_deinit/inc \
-I$(obj)/$(DEPTH)/cmn_dev/global_lmac_if/inc \
-I$(obj)/$(DEPTH)/cmn_dev/os_if/linux \
-I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/cmn_defs/inc \
-I$(obj)/$(DEPTH)/cmn_dev/target_if/core/inc \
-I$(obj)/$(DEPTH)/cmn_dev/umac/scan/dispatcher/inc \
-I$(obj)/$(DEPTH)/umac/scan \
-I$(obj)/$(DEPTH)/cmn_dev/ol_if \
-I$(obj)/$(DEPTH)/cmn_dev/target_if/scan/inc \
-I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/serialization/core/inc \
-I$(obj)/$(DEPTH)/cmn_dev/umac/regulatory/dispatcher/inc \
-I$(obj)/$(DEPTH)/cmn_dev/target_if/regulatory/inc \
PERF_PWR_OFFLOAD_INC += -I$(PERF_PWR_OFFLOAD_DIR_PATH)/wlan/include \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/wlan/ath_pktlog/include \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/htt/include \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/wlan/txrx/include \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/include \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/include \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/hif/pci \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/hif/pci/linux \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/os/linux/include \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/wlan/regdmn \
-I$(PERF_PWR_OFFLOAD_DIR_PATH)/wlan/lmac_offload_if \
-I$(HOST_CMN_CONVG_HIF_INC1)/inc \
-I$(HOST_CMN_CONVG_HIF_INC1)/src \
-I$(HOST_CMN_CONVG_HIF_INC1)/src/pcie \
-I$(HOST_CMN_CONVG_HIF_INC1)/src/snoc \
-I$(HOST_CMN_CONVG_SRC)/pld_stub/inc \
-I$(HOST_CMN_CONVG_HIF_SRC)/ce \
-I$(HOST_CMN_CONVG_HTC_INC) \
-I$(HOST_CMN_CONVG_CFG_INC) \
-I$(HOST_CMN_CONVG_DP_INC) \
-I$(HOST_CMN_CONVG_HAL_INC) \
-I$(HOST_CMN_CONVG_HAL_WIFI_INC) \
-I$(PERF_PWR_OFFLOAD_WMI_SRC)/inc \
-I$(obj)/$(DEPTH)/offload/extra_include
INCS += $(PERF_PWR_OFFLOAD_INC)
INCS += -I$(obj)/$(DEPTH)/cmn_dev/target_if/spectral
INCS += -I$(obj)/$(DEPTH)/cmn_dev/wmi/inc
INCS += -I$(PERF_PWR_OFFLOAD_DIR_PATH)/hw/include
#end of offload related defines
#Start of Legacy spectral related defines
INCS += -I$(HAL) -I$(HAL)/$(OS) -I$(ATH) -I$(ATH_RATE) -I$(ATH_PKTLOG) -I$(WLAN) -I$(IF_WLAN) -I$(ATH_SPECTRAL) -I$(ATHEROSPATH) -I$(obj)/$(DEPTH)/../../apps/spectral/common
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/inc -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/obj_mgr/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/cmn_defs/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/scan/dispatcher/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/cmn_defs/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/global_umac_dispatcher/lmac_if/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/scheduler/inc
INCS += -I$(obj)/$(DEPTH)/umac/scan
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/cmn_services/mgmt_txrx/dispatcher/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/regulatory/dispatcher/inc
INCS += -I$(obj)/$(DEPTH)/cmn_dev/umac/dfs/dispatcher/inc
SPECTRAL_DA_OBJS := $(DEPTH)/lmac/spectral/spectral.o \
$(DEPTH)/lmac/spectral/spectral_netlink.o \
$(DEPTH)/lmac/spectral/spectral_cmds.o \
$(DEPTH)/lmac/spectral/spectral_process_data.o \
$(DEPTH)/lmac/spectral/spectral_phyerr.o
#End of legacy spectral defines
ifeq ($(QCA_AIRTIME_FAIRNESS), 1)
ccflags-y+= -DWLAN_ATF_ENABLE
INCS += -I$(obj)/$(DEPTH)/umac/airtime_fairness/dispatcher/inc
endif
ifeq ($(UNIFIED_SMARTANTENNA), 1)
ccflags-y+= -DWLAN_SA_API_ENABLE
INCS += -I$(obj)/$(DEPTH)/umac/sa_api/dispatcher/inc
endif
ifeq ($(strip ${QCA_DFS_COMPONENT_ENABLE}),1)
ccflags-y+= -DDFS_COMPONENT_ENABLE
endif
obj-m += qca_spectral.o
ccflags-y+= $(INCS) $(COPTS) -DSPECTRAL_USE_NETLINK_SOCKETS=1 -DWLAN_SPECTRAL_ENABLE=1
ifeq ($(strip ${QCA_PARTNER_MAKE_F_SUPPORT}),1)
MOD_CFLAGS = -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(qca_spectral.mod)" -D"KBUILD_MODNAME=KBUILD_STR(qca_spectral)"
endif
INCS += -I$(obj)/$(DEPTH)/spectral/dispatcher/inc
SPECTRAL_TIF_OBJS += $(DEPTH)/cmn_dev/target_if/spectral/target_if_spectral.o \
$(DEPTH)/cmn_dev/target_if/spectral/target_if_spectral_netlink.o \
$(DEPTH)/cmn_dev/target_if/spectral/target_if_spectral_phyerr.o \
$(DEPTH)/cmn_dev/target_if/spectral/target_if_spectral_sim.o
SPECTRAL_CMN_OBJS += core/spectral_direct_attach.o \
core/spectral_offload.o \
core/spectral_common.o \
dispatcher/src/wlan_spectral_utils_api.o \
dispatcher/src/wlan_spectral_ucfg_api.o \
dispatcher/src/wlan_spectral_tgt_api.o \
core/spectral_module.o
qca_spectral-objs += ${SPECTRAL_CMN_OBJS} \
${SPECTRAL_TIF_OBJS} \
${SPECTRAL_DA_OBJS}
ifeq ($(strip ${QCA_PARTNER_MAKE_F_SUPPORT}),1)
all: qca_spectral.ko
qca_spectral.mod.o: qca_spectral.mod.c
${CC} -c -o $@ ${ccflags-y} ${MOD_CFLAGS} $<
qca_spectral.o: ${qca_spectral-objs}
$(LD) -m elf32btsmip -r -o qca_spectral.o $(qca_spectral-objs)
$(KERNELPATH)/scripts/mod/modpost qca_spectral.o
qca_spectral.ko: qca_spectral.o qca_spectral.mod.o
$(LD) $(LDOPTS) -o qca_spectral.ko qca_spectral.o qca_spectral.mod.o
%.o: %.c
${CC} -c -o $@ ${ccflags-y} $<
endif

View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SPECTRAL_CMN_API_I_H_
#define _SPECTRAL_CMN_API_I_H_
#include "spectral_defs_i.h"
/**
* wlan_spectral_psoc_obj_create_handler(): handler for psoc object create
* @psoc: reference to global psoc object
* @arg: reference to argument provided during registration of handler
*
* This is a handler to indicate psoc object created. Hence spectral_context
* object can be created and attached to psoc component list.
*
* Return: QDF_STATUS_SUCCESS on success
* QDF_STATUS_E_FAILURE if psoc is null
* QDF_STATUS_E_NOMEM on failure of spectral object allocation
*/
QDF_STATUS wlan_spectral_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc,
void *arg);
/**
* wlan_spectral_psoc_obj_destroy_handler(): handler for psoc object delete
* @psoc: reference to global psoc object
* @arg: reference to argument provided during registration of handler
*
* This is a handler to indicate psoc object going to be deleted.
* Hence spectral_context object can be detached from psoc component list.
* Then spectral_context object can be deleted.
*
* Return: QDF_STATUS_SUCCESS on success
* QDF_STATUS_E_FAILURE on failure
*/
QDF_STATUS wlan_spectral_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc,
void *arg);
/**
* wlan_spectral_pdev_obj_create_handler(): handler for pdev object create
* @pdev: reference to global pdev object
* @arg: reference to argument provided during registration of handler
*
* This is a handler to indicate pdev object created. Hence pdev specific
* spectral object can be created and attached to pdev component list.
*
* Return: QDF_STATUS_SUCCESS on success
* QDF_STATUS_E_FAILURE if pdev is null
* QDF_STATUS_E_NOMEM on failure of spectral object allocation
*/
QDF_STATUS wlan_spectral_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev,
void *arg);
/**
* wlan_spectral_pdev_obj_destroy_handler(): handler for pdev object delete
* @pdev: reference to global pdev object
* @arg: reference to argument provided during registration of handler
*
* This is a handler to indicate pdev object going to be deleted.
* Hence pdev specific spectral object can be detached from pdev component list.
* Then pdev_spectral object can be deleted.
*
* Return: QDF_STATUS_SUCCESS on success
* QDF_STATUS_E_FAILURE on failure
*/
QDF_STATUS wlan_spectral_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
void *arg);
/**
* spectral_control_cmn(): common handler for demultiplexing requests from
* higher layer
* @pdev: reference to global pdev object
* @id: spectral config command id
* @indata: reference to input data
* @insize: input data size
* @outdata: reference to output data
* @outsize: reference to output data size
*
* This function processes the spectral config command
* and appropriate handlers are invoked.
*
* Return: 0 success else failure
*/
int spectral_control_cmn(
struct wlan_objmgr_pdev *pdev,
u_int id,
void *indata,
u_int32_t insize,
void *outdata, u_int32_t *outsize);
/**
* spectral_get_spectral_ctx_from_pdev() - API to get spectral context object
* from pdev
* @pdev : Reference to pdev global object
*
* This API used to get spectral context object from global pdev reference.
* Null check should be done before invoking this inline function.
*
* Return : Reference to spectral_context object
*/
static inline
struct spectral_context *spectral_get_spectral_ctx_from_pdev(
struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
struct spectral_context *sc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
if (psoc) {
sc = wlan_objmgr_psoc_get_comp_private_obj(
psoc,
WLAN_UMAC_COMP_SPECTRAL);
}
return sc;
}
#endif /* _SPECTRAL_CMN_API_I_H_*/

View File

@@ -0,0 +1,562 @@
/*
* Copyright (c) 2011,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "spectral_cmn_api_i.h"
#include "spectral_da_api_i.h"
#include "spectral_ol_api_i.h"
#include <qdf_mem.h>
#include <qdf_types.h>
#include <osif_private.h>
#include <wlan_spectral_public_structs.h>
#include <wlan_mlme_dispatcher.h>
/**
* spectral_get_vdev() - Get pointer to vdev to be used for Spectral
* operations
* @pdev: Pointer to pdev
*
* Spectral operates on pdev. However, in order to retrieve some WLAN
* properties, a vdev is required. To facilitate this, the function returns the
* first vdev in our pdev. The caller should release the reference to the vdev
* once it is done using it. Additionally, the caller should ensure it has a
* reference to the pdev at the time of calling this function, and should
* release the pdev reference either after this function returns or at a later
* time when the caller is done using pdev.
* TODO:
* - If the framework later provides an API to obtain the first active
* vdev, then it would be preferable to use this API.
* - Use a common get_vdev() handler for core and target_if using Rx ops. This
* is deferred till details emerge on framework providing API to get first
* active vdev.
*
* Return: Pointer to vdev on success, NULL on failure
*/
struct wlan_objmgr_vdev*
spectral_get_vdev(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_vdev *vdev = NULL;
qdf_assert_always(pdev);
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, 0, WLAN_SPECTRAL_ID);
if (!vdev) {
qdf_print("%s: Unable to get first vdev of pdev.\n", __func__);
return NULL;
}
return vdev;
}
int spectral_control_cmn(
struct wlan_objmgr_pdev *pdev,
u_int id,
void *indata,
u_int32_t insize,
void *outdata, u_int32_t *outsize)
{
int error = 0;
int temp_debug;
struct spectral_config sp_out;
struct spectral_config *sp_in;
struct spectral_config *spectralparams;
struct spectral_context *sc;
struct wlan_objmgr_vdev *vdev = NULL;
u_int8_t vdev_rxchainmask = 0;
if (!pdev) {
spectral_err("PDEV is NULL!\n");
error = -EINVAL;
goto bad;
}
sc = spectral_get_spectral_ctx_from_pdev(pdev);
if (!sc) {
spectral_err("atf context is NULL!\n");
error = -EINVAL;
goto bad;
}
switch (id) {
case SPECTRAL_SET_CONFIG:
{
if (insize < sizeof(struct spectral_config) || !indata) {
error = -EINVAL;
break;
}
sp_in = (struct spectral_config *)indata;
if (sp_in->ss_count != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_SCAN_COUNT,
sp_in->ss_count))
error = -EINVAL;
}
if (sp_in->ss_fft_period != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_FFT_PERIOD,
sp_in->ss_fft_period))
error = -EINVAL;
}
if (sp_in->ss_period != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_SCAN_PERIOD,
sp_in->ss_period))
error = -EINVAL;
}
if (sp_in->ss_short_report != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_SHORT_REPORT,
(u_int32_t)(sp_in->ss_short_report ? 1 : 0)))
error = -EINVAL;
}
if (sp_in->ss_spectral_pri != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_SPECT_PRI,
(u_int32_t)(sp_in->ss_spectral_pri)))
error = -EINVAL;
}
if (sp_in->ss_fft_size != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_FFT_SIZE,
sp_in->ss_fft_size))
error = -EINVAL;
}
if (sp_in->ss_gc_ena != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_GC_ENA,
sp_in->ss_gc_ena))
error = -EINVAL;
}
if (sp_in->ss_restart_ena != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_RESTART_ENA,
sp_in->ss_restart_ena))
error = -EINVAL;
}
if (sp_in->ss_noise_floor_ref != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_NOISE_FLOOR_REF,
sp_in->ss_noise_floor_ref))
error = -EINVAL;
}
if (sp_in->ss_init_delay != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_INIT_DELAY,
sp_in->ss_init_delay))
error = -EINVAL;
}
if (sp_in->ss_nb_tone_thr != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_NB_TONE_THR,
sp_in->ss_nb_tone_thr))
error = -EINVAL;
}
if (sp_in->ss_str_bin_thr != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_STR_BIN_THR,
sp_in->ss_str_bin_thr))
error = -EINVAL;
}
if (sp_in->ss_wb_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_WB_RPT_MODE,
sp_in->ss_wb_rpt_mode))
error = -EINVAL;
}
if (sp_in->ss_rssi_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_RSSI_RPT_MODE,
sp_in->ss_rssi_rpt_mode))
error = -EINVAL;
}
if (sp_in->ss_rssi_thr != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_RSSI_THR,
sp_in->ss_rssi_thr))
error = -EINVAL;
}
if (sp_in->ss_pwr_format != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_PWR_FORMAT,
sp_in->ss_pwr_format))
error = -EINVAL;
}
if (sp_in->ss_rpt_mode != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_RPT_MODE,
sp_in->ss_rpt_mode))
error = -EINVAL;
}
if (sp_in->ss_bin_scale != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_BIN_SCALE,
sp_in->ss_bin_scale))
error = -EINVAL;
}
if (sp_in->ss_dBm_adj != SPECTRAL_PHYERR_PARAM_NOVAL) {
if (!sc->sptrlc_set_spectral_config(
pdev,
SPECTRAL_PARAM_DBM_ADJ,
sp_in->ss_dBm_adj))
error = -EINVAL;
}
if (sp_in->ss_chn_mask != SPECTRAL_PHYERR_PARAM_NOVAL) {
/* Check if any of the inactive Rx antenna chains is
* set active in
* spectral chainmask
*/
vdev = spectral_get_vdev(pdev);
if (!vdev) {
error = -ENOENT;
break;
}
vdev_rxchainmask = wlan_vdev_mlme_get_rxchainmask(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
if (!(sp_in->ss_chn_mask & vdev_rxchainmask)) {
qdf_print("Invalid Spectral Chainmask - "
"Inactive Rx antenna chain cannot "
"be an active spectral chain\n");
error = -EINVAL;
break;
} else if (!sc->sptrlc_set_spectral_config(pdev,
SPECTRAL_PARAM_CHN_MASK, sp_in->ss_chn_mask)) {
error = -EINVAL;
}
}
}
break;
case SPECTRAL_GET_CONFIG:
{
if (!outdata || !outsize || (*outsize < sizeof(
struct spectral_config))) {
error = -EINVAL;
break;
}
*outsize = sizeof(struct spectral_config);
sc->sptrlc_get_spectral_config(pdev, &sp_out);
spectralparams = (struct spectral_config *)outdata;
spectralparams->ss_fft_period = sp_out.ss_fft_period;
spectralparams->ss_period = sp_out.ss_period;
spectralparams->ss_count = sp_out.ss_count;
spectralparams->ss_short_report = sp_out.ss_short_report;
spectralparams->ss_spectral_pri = sp_out.ss_spectral_pri;
spectralparams->ss_fft_size = sp_out.ss_fft_size;
spectralparams->ss_gc_ena = sp_out.ss_gc_ena;
spectralparams->ss_restart_ena = sp_out.ss_restart_ena;
spectralparams->ss_noise_floor_ref = sp_out.ss_noise_floor_ref;
spectralparams->ss_init_delay = sp_out.ss_init_delay;
spectralparams->ss_nb_tone_thr = sp_out.ss_nb_tone_thr;
spectralparams->ss_str_bin_thr = sp_out.ss_str_bin_thr;
spectralparams->ss_wb_rpt_mode = sp_out.ss_wb_rpt_mode;
spectralparams->ss_rssi_rpt_mode = sp_out.ss_rssi_rpt_mode;
spectralparams->ss_rssi_thr = sp_out.ss_rssi_thr;
spectralparams->ss_pwr_format = sp_out.ss_pwr_format;
spectralparams->ss_rpt_mode = sp_out.ss_rpt_mode;
spectralparams->ss_bin_scale = sp_out.ss_bin_scale;
spectralparams->ss_dBm_adj = sp_out.ss_dBm_adj;
spectralparams->ss_chn_mask = sp_out.ss_chn_mask;
}
break;
case SPECTRAL_IS_ACTIVE:
{
if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
error = -EINVAL;
break;
}
*outsize = sizeof(u_int32_t);
*((u_int32_t *)outdata) =
(u_int32_t)sc->sptrlc_is_spectral_active(pdev);
}
break;
case SPECTRAL_IS_ENABLED:
{
if (!outdata || !outsize || *outsize < sizeof(u_int32_t)) {
error = -EINVAL;
break;
}
*outsize = sizeof(u_int32_t);
*((u_int32_t *)outdata) =
(u_int32_t)sc->sptrlc_is_spectral_enabled(pdev);
}
break;
case SPECTRAL_SET_DEBUG_LEVEL:
{
if (insize < sizeof(u_int32_t) || !indata) {
error = -EINVAL;
break;
}
temp_debug = *(u_int32_t *)indata;
sc->sptrlc_set_debug_level(pdev, temp_debug);
}
break;
case SPECTRAL_ACTIVATE_SCAN:
{
sc->sptrlc_start_spectral_scan(pdev);
}
break;
case SPECTRAL_STOP_SCAN:
{
sc->sptrlc_stop_spectral_scan(pdev);
}
break;
case SPECTRAL_GET_CAPABILITY_INFO:
{
if (!outdata || !outsize ||
*outsize < sizeof(struct spectral_caps)) {
error = -EINVAL;
break;
}
*outsize = sizeof(struct spectral_caps);
sc->sptrlc_get_spectral_capinfo(pdev, outdata);
}
break;
case SPECTRAL_GET_DIAG_STATS:
{
if (!outdata || !outsize ||
(*outsize < sizeof(struct spectral_diag_stats))) {
error = -EINVAL;
break;
}
*outsize = sizeof(struct spectral_diag_stats);
sc->sptrlc_get_spectral_diagstats(pdev, outdata);
}
break;
case SPECTRAL_GET_CHAN_WIDTH:
{
u_int32_t chan_width;
vdev = spectral_get_vdev(pdev);
if (!vdev)
return -ENOENT;
chan_width = wlan_vdev_get_ch_width(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
if (!outdata || !outsize ||
*outsize < sizeof(chan_width)) {
error = -EINVAL;
break;
}
*outsize = sizeof(chan_width);
*((u_int32_t *)outdata) = (u_int32_t)chan_width;
}
break;
default:
error = -EINVAL;
break;
}
bad:
return error;
}
static void spectral_ctx_deinit(struct spectral_context *sc)
{
if (sc) {
sc->sptrlc_ucfg_phyerr_config = NULL;
sc->sptrlc_pdev_spectral_init = NULL;
sc->sptrlc_pdev_spectral_deinit = NULL;
sc->sptrlc_set_spectral_config = NULL;
sc->sptrlc_get_spectral_config = NULL;
sc->sptrlc_start_spectral_scan = NULL;
sc->sptrlc_stop_spectral_scan = NULL;
sc->sptrlc_is_spectral_active = NULL;
sc->sptrlc_is_spectral_enabled = NULL;
sc->sptrlc_set_debug_level = NULL;
sc->sptrlc_get_debug_level = NULL;
sc->sptrlc_get_spectral_capinfo = NULL;
sc->sptrlc_get_spectral_diagstats = NULL;
}
}
QDF_STATUS
wlan_spectral_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
{
struct spectral_context *sc = NULL;
if (!psoc) {
spectral_err("PSOC is NULL\n");
return QDF_STATUS_E_FAILURE;
}
sc = (struct spectral_context *)qdf_mem_malloc(
sizeof(struct spectral_context));
if (!sc) {
spectral_err("Failed to allocate spectral_ctx object\n");
return QDF_STATUS_E_NOMEM;
}
qdf_mem_zero(sc, sizeof(struct spectral_context));
sc->psoc_obj = psoc;
if (wlan_objmgr_psoc_get_dev_type(psoc) == WLAN_DEV_DA)
spectral_ctx_init_da(sc);
else if (wlan_objmgr_psoc_get_dev_type(psoc) == WLAN_DEV_OL)
spectral_ctx_init_ol(sc);
wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_SPECTRAL,
(void *)sc, QDF_STATUS_SUCCESS);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlan_spectral_psoc_obj_destroy_handler(
struct wlan_objmgr_psoc *psoc,
void *arg)
{
struct spectral_context *sc = NULL;
if (!psoc) {
spectral_err("PSOC is NULL\n");
return QDF_STATUS_E_FAILURE;
}
sc = wlan_objmgr_psoc_get_comp_private_obj(
psoc,
WLAN_UMAC_COMP_SPECTRAL);
if (sc) {
wlan_objmgr_psoc_component_obj_detach(
psoc,
WLAN_UMAC_COMP_SPECTRAL,
(void *)sc);
/* Deinitilise function pointers from spectral context */
spectral_ctx_deinit(sc);
qdf_mem_free(sc);
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_spectral_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
{
struct pdev_spectral *ps = NULL;
struct spectral_context *sc = NULL;
void *target_handle = NULL;
if (!pdev) {
spectral_err("PDEV is NULL\n");
return QDF_STATUS_E_FAILURE;
}
ps = (struct pdev_spectral *)qdf_mem_malloc(
sizeof(struct pdev_spectral));
if (!ps) {
spectral_err("Failed to allocate pdev_spectral object\n");
return QDF_STATUS_E_NOMEM;
}
sc = spectral_get_spectral_ctx_from_pdev(pdev);
if (!sc) {
spectral_err("Spectral context is NULL!\n");
goto cleanup;
}
qdf_mem_zero(ps, sizeof(struct pdev_spectral));
ps->psptrl_pdev = pdev;
if (sc->sptrlc_pdev_spectral_init) {
target_handle = sc->sptrlc_pdev_spectral_init(pdev);
if (!target_handle) {
spectral_err("Spectral lmac object is NULL!\n");
goto cleanup;
}
ps->psptrl_target_handle = target_handle;
}
wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_UMAC_COMP_SPECTRAL,
(void *)ps, QDF_STATUS_SUCCESS);
return QDF_STATUS_SUCCESS;
cleanup:
qdf_mem_free(ps);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wlan_spectral_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg)
{
struct pdev_spectral *ps = NULL;
struct spectral_context *sc = NULL;
if (!pdev) {
spectral_err("PDEV is NULL\n");
return QDF_STATUS_E_FAILURE;
}
sc = spectral_get_spectral_ctx_from_pdev(pdev);
if (!sc) {
spectral_err("Spectral context is NULL!\n");
return QDF_STATUS_E_FAILURE;
}
ps = wlan_objmgr_pdev_get_comp_private_obj(
pdev,
WLAN_UMAC_COMP_SPECTRAL);
if (ps) {
if (sc->sptrlc_pdev_spectral_deinit)
sc->sptrlc_pdev_spectral_deinit(pdev);
ps->psptrl_target_handle = NULL;
wlan_objmgr_pdev_component_obj_detach(
pdev,
WLAN_UMAC_COMP_SPECTRAL,
(void *)ps);
qdf_mem_free(ps);
}
return QDF_STATUS_SUCCESS;
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SPECTRAL_DA_API_I_H_
#define _SPECTRAL_DA_API_I_H_
#include "spectral_defs_i.h"
/**
* spectral_ctx_init_da() - Internal function to initialise spectral context
* with direct attach specific functions
* @sc : spectral context
*
* Return : void
*/
void spectral_ctx_init_da(struct spectral_context *sc);
#endif /* _SPECTRAL_DA_API_I_H_ */

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SPECTRAL_DEFS_I_H_
#define _SPECTRAL_DEFS_I_H_
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <qdf_list.h>
#include <qdf_timer.h>
#include <qdf_util.h>
#include <wlan_spectral_public_structs.h>
#include <if_athioctl.h>
#include <spectral_ioctl.h>
#define spectral_log(level, args...) \
QDF_PRINT_INFO(QDF_PRINT_IDX_SHARED, QDF_MODULE_ID_SPECTRAL, level, ## args)
#define spectral_logfl(level, format, args...) \
spectral_log(level, FL(format), ## args)
#define spectral_fatal(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
#define spectral_err(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
#define spectral_warn(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
#define spectral_info(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
#define spectral_debug(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
/**
* struct pdev_spectral - Radio specific spectral object
* @psptrl_pdev: Back-pointer to struct wlan_objmgr_pdev
* @psptrl_nl_sock: Spectral Netlink socket for sending samples to
* applications
* @psptrl_target_handle: reference to spectral lmac object
*/
struct pdev_spectral {
struct wlan_objmgr_pdev *psptrl_pdev;
struct sock *psptrl_nl_sock;
void *psptrl_target_handle;
};
/**
* struct spectral_context : spectral global context
*
* @psoc_obj: Reference to psoc global object
*
* Call back functions to invoke independent of OL/DA
* @sptrlc_ucfg_phyerr_config: ucfg handler for phyerr
* @sptrlc_pdev_spectral_init: Init spectral
* @sptrlc_pdev_spectral_deinit: Deinit spectral
* @sptrlc_set_spectral_config: Set spectral configurations
* @sptrlc_get_spectral_config: Get spectral configurations
* @sptrlc_start_spectral_scan: Start spectral scan
* @sptrlc_stop_spectral_scan: Stop spectral scan
* @sptrlc_is_spectral_active: Check if spectral scan is active
* @sptrlc_is_spectral_enabled: Check if spectral is enabled
* @sptrlc_set_debug_level: Set debug level
* @sptrlc_get_debug_level: Get debug level
* @sptrlc_get_spectral_capinfo: Get spectral capability info
* @sptrlc_get_spectral_diagstats: Get spectral diag status
*/
struct spectral_context {
struct wlan_objmgr_psoc *psoc_obj;
int (*sptrlc_spectral_control)(struct wlan_objmgr_pdev *pdev, u_int id,
void *indata, u_int32_t insize,
void *outdata, u_int32_t *outsize);
int (*sptrlc_ucfg_phyerr_config)(struct wlan_objmgr_pdev *pdev,
struct ath_diag *ad);
void * (*sptrlc_pdev_spectral_init)(struct wlan_objmgr_pdev *pdev);
void (*sptrlc_pdev_spectral_deinit)(struct wlan_objmgr_pdev *pdev);
int (*sptrlc_set_spectral_config)(
struct wlan_objmgr_pdev *pdev,
const u_int32_t threshtype, const u_int32_t value);
void (*sptrlc_get_spectral_config)(
struct wlan_objmgr_pdev *pdev,
struct spectral_config *sptrl_config);
int (*sptrlc_start_spectral_scan)(struct wlan_objmgr_pdev *pdev);
void (*sptrlc_stop_spectral_scan)(struct wlan_objmgr_pdev *pdev);
bool (*sptrlc_is_spectral_active)(struct wlan_objmgr_pdev *pdev);
bool (*sptrlc_is_spectral_enabled)(struct wlan_objmgr_pdev *pdev);
int (*sptrlc_set_debug_level)(struct wlan_objmgr_pdev *pdev,
u_int32_t debug_level);
u_int32_t (*sptrlc_get_debug_level)(struct wlan_objmgr_pdev *pdev);
void (*sptrlc_get_spectral_capinfo)(struct wlan_objmgr_pdev *pdev,
void *outdata);
void (*sptrlc_get_spectral_diagstats)(struct wlan_objmgr_pdev *pdev,
void *outdata);
};
#endif /* _SPECTRAL_DEFS_I_H_ */

View File

@@ -0,0 +1,209 @@
/*
* Copyright (c) 2011,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "spectral_cmn_api_i.h"
int spectral_control_da(struct wlan_objmgr_pdev *pdev, u_int id, void *indata,
u_int32_t insize, void *outdata, u_int32_t *outsize)
{
struct spectral_context *sc;
int error = 0;
if (!pdev) {
spectral_err("PDEV is NULL!\n");
return -EPERM;
}
sc = spectral_get_spectral_ctx_from_pdev(pdev);
if (!sc) {
spectral_err("spectral context is NULL!\n");
return -EPERM;
}
switch (id) {
#if ATH_SUPPORT_RAW_ADC_CAPTURE
case SPECTRAL_ADC_ENABLE_TEST_ADDAC_MODE:
error = spectral_enter_raw_capture_mode(dev, indata);
break;
case SPECTRAL_ADC_DISABLE_TEST_ADDAC_MODE:
error = spectral_exit_raw_capture_mode(dev);
break;
case SPECTRAL_ADC_RETRIEVE_DATA:
error = spectral_retrieve_raw_capture(dev, outdata, outsize);
break;
#endif
default:
error = spectral_control_cmn(
pdev,
id,
indata,
insize,
outdata,
outsize);
break;
}
return error;
}
static void *pdev_spectral_init_da(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_pdev_spectral_init(
pdev);
}
static void pdev_spectral_deinit_da(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_pdev_spectral_deinit(pdev);
}
static int set_spectral_config_da(
struct wlan_objmgr_pdev *pdev,
const u_int32_t threshtype, const u_int32_t value)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_spectral_config(
pdev,
threshtype,
value);
}
static void get_spectral_config_da(struct wlan_objmgr_pdev *pdev,
struct spectral_config *sptrl_config)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_spectral_config(pdev,
sptrl_config);
}
static int start_spectral_scan_da(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_start_spectral_scan(
pdev);
}
static void stop_spectral_scan_da(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_stop_spectral_scan(pdev);
}
static bool is_spectral_active_da(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_is_spectral_active(
pdev);
}
static bool is_spectral_enabled_da(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_is_spectral_enabled(
pdev);
}
static int set_debug_level_da(struct wlan_objmgr_pdev *pdev,
u_int32_t debug_level)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_debug_level(pdev,
debug_level);
}
static u_int32_t get_debug_level_da(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_debug_level(pdev);
}
static void get_spectral_capinfo_da(struct wlan_objmgr_pdev *pdev,
void *outdata)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_spectral_capinfo(
pdev,
outdata);
}
static void get_spectral_diagstats_da(struct wlan_objmgr_pdev *pdev,
void *outdata)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_spectral_diagstats(
pdev,
outdata);
}
void spectral_ctx_init_da(struct spectral_context *sc)
{
if (!sc) {
spectral_err("spectral context is null!\n");
return;
}
sc->sptrlc_spectral_control = spectral_control_da;
sc->sptrlc_pdev_spectral_init = pdev_spectral_init_da;
sc->sptrlc_pdev_spectral_deinit = pdev_spectral_deinit_da;
sc->sptrlc_set_spectral_config = set_spectral_config_da;
sc->sptrlc_get_spectral_config = get_spectral_config_da;
sc->sptrlc_start_spectral_scan = start_spectral_scan_da;
sc->sptrlc_stop_spectral_scan = stop_spectral_scan_da;
sc->sptrlc_is_spectral_active = is_spectral_active_da;
sc->sptrlc_is_spectral_enabled = is_spectral_enabled_da;
sc->sptrlc_set_debug_level = set_debug_level_da;
sc->sptrlc_get_debug_level = get_debug_level_da;
sc->sptrlc_get_spectral_capinfo = get_spectral_capinfo_da;
sc->sptrlc_get_spectral_diagstats = get_spectral_diagstats_da;
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2011,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include<linux/module.h>
#include <wlan_spectral_utils_api.h>
#include <qdf_types.h>
#include<wlan_global_lmac_if_api.h>
/**
* spectral_init_module() - Initialize Spectral module
*
* Return: None
*/
static int __init
spectral_init_module(void)
{
qdf_print("qca_spectral module loaded\n");
wlan_spectral_init();
/* register spectral rxops*/
wlan_lmac_if_sptrl_set_rx_ops_register_cb(
wlan_lmac_if_sptrl_register_rx_ops);
return 0;
}
/**
* spectral_exit_module() - De-initialize and exit Spectral module
*
* Return: None
*/
static void __exit
spectral_exit_module(void)
{
wlan_spectral_deinit();
qdf_print("qca_spectral module unloaded\n");
}
module_init(spectral_init_module);
module_exit(spectral_exit_module);

View File

@@ -0,0 +1,177 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "spectral_cmn_api_i.h"
int spectral_control_ol(
struct wlan_objmgr_pdev *pdev,
u_int id,
void *indata,
u_int32_t insize,
void *outdata, u_int32_t *outsize)
{
struct spectral_context *sc;
if (!pdev) {
spectral_err("PDEV is NULL!\n");
return -EPERM;
}
sc = spectral_get_spectral_ctx_from_pdev(pdev);
if (!sc) {
spectral_err("spectral context is NULL!\n");
return -EPERM;
}
return spectral_control_cmn(pdev, id, indata, insize, outdata, outsize);
}
static void *pdev_spectral_init_ol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_pdev_spectral_init(
pdev);
}
static void pdev_spectral_deinit_ol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_pdev_spectral_deinit(pdev);
}
static int set_spectral_config_ol(
struct wlan_objmgr_pdev *pdev,
const u_int32_t threshtype, const u_int32_t value)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_spectral_config(
pdev,
threshtype, value);
}
static void get_spectral_config_ol(struct wlan_objmgr_pdev *pdev,
struct spectral_config *sptrl_config)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_spectral_config(pdev,
sptrl_config);
}
static int start_spectral_scan_ol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_start_spectral_scan(
pdev);
}
static void stop_spectral_scan_ol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_stop_spectral_scan(pdev);
}
static bool is_spectral_active_ol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_is_spectral_active(
pdev);
}
static bool is_spectral_enabled_ol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_is_spectral_enabled(
pdev);
}
static int set_debug_level_ol(struct wlan_objmgr_pdev *pdev,
u_int32_t debug_level)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_debug_level(pdev,
debug_level);
}
static u_int32_t get_debug_level_ol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_debug_level(pdev);
}
static void get_spectral_capinfo_ol(struct wlan_objmgr_pdev *pdev,
void *outdata)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_spectral_capinfo(
pdev,
outdata);
}
static void get_spectral_diagstats_ol(struct wlan_objmgr_pdev *pdev,
void *outdata)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_get_spectral_diagstats(
pdev,
outdata);
}
void spectral_ctx_init_ol(struct spectral_context *sc)
{
if (!sc) {
spectral_err("spectral context is null!\n");
return;
}
sc->sptrlc_spectral_control = spectral_control_ol;
sc->sptrlc_pdev_spectral_init = pdev_spectral_init_ol;
sc->sptrlc_pdev_spectral_deinit = pdev_spectral_deinit_ol;
sc->sptrlc_set_spectral_config = set_spectral_config_ol;
sc->sptrlc_get_spectral_config = get_spectral_config_ol;
sc->sptrlc_start_spectral_scan = start_spectral_scan_ol;
sc->sptrlc_stop_spectral_scan = stop_spectral_scan_ol;
sc->sptrlc_is_spectral_active = is_spectral_active_ol;
sc->sptrlc_is_spectral_enabled = is_spectral_enabled_ol;
sc->sptrlc_set_debug_level = set_debug_level_ol;
sc->sptrlc_get_debug_level = get_debug_level_ol;
sc->sptrlc_get_spectral_capinfo = get_spectral_capinfo_ol;
sc->sptrlc_get_spectral_diagstats = get_spectral_diagstats_ol;
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SPECTRAL_OL_API_I_H_
#define _SPECTRAL_OL_API_I_H_
#include "spectral_defs_i.h"
/**
* spectral_ctx_init_ol() - Internal function to initialise spectral context
* with offload specific functions
* @sc : spectral context
*
* Return : void
*/
void spectral_ctx_init_ol(struct spectral_context *sc);
#endif /* _SPECTRAL_OL_API_I_H_ */

View File

@@ -0,0 +1,477 @@
/*
* Copyright (c) 2011,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <qdf_types.h>
#include "wlan_dfs_ioctl.h"
#ifndef _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_
#define _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_
#ifdef WIN32
#pragma pack(push, spectral, 1)
#define __ATTRIB_PACKED
#else
#ifndef __ATTRIB_PACKED
#define __ATTRIB_PACKED __attribute__ ((packed))
#endif
#endif
#ifndef AH_MAX_CHAINS
#define AH_MAX_CHAINS 3
#endif
#define MAX_NUM_CHANNELS 255
#define MAX_SPECTRAL_CHAINS 3
#define MAX_NUM_BINS 520
#define SPECTRAL_PHYERR_PARAM_NOVAL 65535
/* 5 categories x (lower + upper) bands */
#define MAX_INTERF 10
/* ioctl parameter types */
#define SPECTRAL_PARAM_FFT_PERIOD (1)
#define SPECTRAL_PARAM_SCAN_PERIOD (2)
#define SPECTRAL_PARAM_SCAN_COUNT (3)
#define SPECTRAL_PARAM_SHORT_REPORT (4)
#define SPECTRAL_PARAM_SPECT_PRI (5)
#define SPECTRAL_PARAM_FFT_SIZE (6)
#define SPECTRAL_PARAM_GC_ENA (7)
#define SPECTRAL_PARAM_RESTART_ENA (8)
#define SPECTRAL_PARAM_NOISE_FLOOR_REF (9)
#define SPECTRAL_PARAM_INIT_DELAY (10)
#define SPECTRAL_PARAM_NB_TONE_THR (11)
#define SPECTRAL_PARAM_STR_BIN_THR (12)
#define SPECTRAL_PARAM_WB_RPT_MODE (13)
#define SPECTRAL_PARAM_RSSI_RPT_MODE (14)
#define SPECTRAL_PARAM_RSSI_THR (15)
#define SPECTRAL_PARAM_PWR_FORMAT (16)
#define SPECTRAL_PARAM_RPT_MODE (17)
#define SPECTRAL_PARAM_BIN_SCALE (18)
#define SPECTRAL_PARAM_DBM_ADJ (19)
#define SPECTRAL_PARAM_CHN_MASK (20)
#define SPECTRAL_PARAM_ACTIVE (21)
#define SPECTRAL_PARAM_STOP (22)
#define SPECTRAL_PARAM_ENABLE (23)
#ifdef ATH_SPECTRAL_USE_EMU_DEFAULTS
/* Use defaults from emulation */
#define SPECTRAL_SCAN_ACTIVE_DEFAULT (0x0)
#define SPECTRAL_SCAN_ENABLE_DEFAULT (0x0)
#define SPECTRAL_SCAN_COUNT_DEFAULT (0x0)
#define SPECTRAL_SCAN_PERIOD_DEFAULT (250)
#define SPECTRAL_SCAN_PRIORITY_DEFAULT (0x1)
#define SPECTRAL_SCAN_FFT_SIZE_DEFAULT (0x7)
#define SPECTRAL_SCAN_GC_ENA_DEFAULT (0x1)
#define SPECTRAL_SCAN_RESTART_ENA_DEFAULT (0x0)
#define SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT (0xa0)
#define SPECTRAL_SCAN_INIT_DELAY_DEFAULT (0x50)
#define SPECTRAL_SCAN_NB_TONE_THR_DEFAULT (0xc)
#define SPECTRAL_SCAN_STR_BIN_THR_DEFAULT (0x7)
#define SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT (0x0)
#define SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT (0x1)
#define SPECTRAL_SCAN_RSSI_THR_DEFAULT (0xf)
#define SPECTRAL_SCAN_PWR_FORMAT_DEFAULT (0x1)
#define SPECTRAL_SCAN_RPT_MODE_DEFAULT (0x2)
#define SPECTRAL_SCAN_BIN_SCALE_DEFAULT (0x1)
#define SPECTRAL_SCAN_DBM_ADJ_DEFAULT (0x0)
#define SPECTRAL_SCAN_CHN_MASK_DEFAULT (0x1)
#else
/* Static default values for spectral state and configuration.
* These definitions should be treated as temporary. Ideally,
* we should get the defaults from firmware - this will be discussed.
*
* Use defaults from Spectral Hardware Micro-Architecture
* document (v1.0)
*/
#define SPECTRAL_SCAN_ACTIVE_DEFAULT (0)
#define SPECTRAL_SCAN_ENABLE_DEFAULT (0)
#define SPECTRAL_SCAN_COUNT_DEFAULT (0)
#define SPECTRAL_SCAN_PERIOD_DEFAULT (35)
#define SPECTRAL_SCAN_PRIORITY_DEFAULT (1)
#define SPECTRAL_SCAN_FFT_SIZE_DEFAULT (7)
#define SPECTRAL_SCAN_GC_ENA_DEFAULT (1)
#define SPECTRAL_SCAN_RESTART_ENA_DEFAULT (0)
#define SPECTRAL_SCAN_NOISE_FLOOR_REF_DEFAULT (-96)
#define SPECTRAL_SCAN_INIT_DELAY_DEFAULT (80)
#define SPECTRAL_SCAN_NB_TONE_THR_DEFAULT (12)
#define SPECTRAL_SCAN_STR_BIN_THR_DEFAULT (8)
#define SPECTRAL_SCAN_WB_RPT_MODE_DEFAULT (0)
#define SPECTRAL_SCAN_RSSI_RPT_MODE_DEFAULT (0)
#define SPECTRAL_SCAN_RSSI_THR_DEFAULT (0xf0)
#define SPECTRAL_SCAN_PWR_FORMAT_DEFAULT (0)
#define SPECTRAL_SCAN_RPT_MODE_DEFAULT (2)
#define SPECTRAL_SCAN_BIN_SCALE_DEFAULT (1)
#define SPECTRAL_SCAN_DBM_ADJ_DEFAULT (1)
#define SPECTRAL_SCAN_CHN_MASK_DEFAULT (1)
#endif /* ATH_SPECTRAL_USE_EMU_DEFAULTS */
/* The below two definitions apply only to pre-11ac chipsets */
#define SPECTRAL_SCAN_SHORT_REPORT_DEFAULT (1)
#define SPECTRAL_SCAN_FFT_PERIOD_DEFAULT (1)
/**
* enum spectral_debug - Spectral debug level
* @ATH_DEBUG_SPECTRAL: Minimal SPECTRAL debug
* @ATH_DEBUG_SPECTRAL1: Normal SPECTRAL debug
* @ATH_DEBUG_SPECTRAL2: Maximal SPECTRAL debug
* @ATH_DEBUG_SPECTRAL3: Matched filterID display
* @ATH_DEBUG_SPECTRAL4: One time dump of FFT report
*/
enum spectral_debug {
ATH_DEBUG_SPECTRAL = 0x00000100,
ATH_DEBUG_SPECTRAL1 = 0x00000200,
ATH_DEBUG_SPECTRAL2 = 0x00000400,
ATH_DEBUG_SPECTRAL3 = 0x00000800,
ATH_DEBUG_SPECTRAL4 = 0x00001000,
};
/**
* enum SPECTRAL_CAPABILITY_TYPE - Spectral capability type
* @SPECTRAL_CAP_PHYDIAG: Phydiag capability
* @SPECTRAL_CAP_RADAR: Radar detection capability
* @SPECTRAL_CAP_SPECTRAL_SCAN: Spectral capability
* @SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN: Advanced spectral capability
*/
typedef enum {
SPECTRAL_CAP_PHYDIAG,
SPECTRAL_CAP_RADAR,
SPECTRAL_CAP_SPECTRAL_SCAN,
SPECTRAL_CAP_ADVNCD_SPECTRAL_SCAN,
} SPECTRAL_CAPABILITY_TYPE;
/**
* struct spectral_chan_stats - channel status info
* @cycle_count: Cycle count
* @channel_load: Channel load
* @per: Period
* @noisefloor: Noise floor
* @comp_usablity: Computed usability
* @maxregpower: Maximum allowed regulatory power
* @comp_usablity_sec80: Computed usability of secondary 80 Mhz
* @maxregpower_sec80: Max regulatory power of secondary 80 Mhz
*/
struct spectral_chan_stats {
int cycle_count;
int channel_load;
int per;
int noisefloor;
u_int16_t comp_usablity;
int8_t maxregpower;
u_int16_t comp_usablity_sec80;
int8_t maxregpower_sec80;
};
/**
* struct spectral_diag_stats - spectral diag stats
* @spectral_mismatch: Spectral TLV signature mismatches
* @spectral_sec80_sfft_insufflen: Insufficient length when parsing for
* Secondary 80 Search FFT report
* @spectral_no_sec80_sfft: Secondary 80 Search FFT report
* TLV not found
* @spectral_vhtseg1id_mismatch: VHT Operation Segment 1 ID
* mismatches in Search FFT report
* @spectral_vhtseg2id_mismatch: VHT Operation Segment 2 ID
* mismatches in Search FFT report
*/
struct spectral_diag_stats {
u_int64_t spectral_mismatch;
u_int64_t spectral_sec80_sfft_insufflen;
u_int64_t spectral_no_sec80_sfft;
u_int64_t spectral_vhtseg1id_mismatch;
u_int64_t spectral_vhtseg2id_mismatch;
};
/**
* struct spectral_caps - Spectral capabilities structure
* @phydiag_cap: Phydiag capability
* @radar_cap: Radar detection capability
* @spectral_cap: Spectral capability
* @advncd_spectral_cap: Advanced spectral capability
*/
struct spectral_caps {
u_int8_t phydiag_cap;
u_int8_t radar_cap;
u_int8_t spectral_cap;
u_int8_t advncd_spectral_cap;
};
/**
* struct spectral_config
* @ss_fft_period: Skip interval for FFT reports
* @ss_period: Spectral scan period
* @ss_count: # of reports to return from ss_active
* @ss_short_report: Set to report only 1 set of FFT results
* @radar_bin_thresh_sel: Select threshold to classify strong bin for FFT
* @ss_spectral_pri: Priority, and are we doing a noise power cal ?
* @ss_fft_size: Defines the number of FFT data points to compute,
* defined as a log index num_fft_pts =
* 2^ss_fft_size
* @ss_gc_ena: Set, to enable targeted gain change before
* starting the spectral scan FFT
* @ss_restart_ena: Set, to enable abort of receive frames when in high
* priority and a spectral scan is queued
* @ss_noise_floor_ref: Noise floor reference number (signed) for the
* calculation of bin power (dBm) Though stored as an
* unsigned this should be treated as a signed 8-bit int.
* @ss_init_delay: Disallow spectral scan triggers after tx/rx packets
* by setting this delay value to roughly SIFS time
* period or greater Delay timer count in units of 0.25us
* @ss_nb_tone_thr: Number of strong bins (inclusive) per sub-channel,
* below which a signal is declared a narrowband tone
* @ss_str_bin_thr: Bin/max_bin ratio threshold over which a bin is
* declared strong (for spectral scan bandwidth analysis)
* @ss_wb_rpt_mode: Set this bit to report spectral scans as EXT_BLOCKER
* (phy_error=36), if none of the sub-channels are
* deemed narrowband
* @ss_rssi_rpt_mode: Set this bit to report spectral scans as EXT_BLOCKER
* (phy_error=36), if the ADC RSSI is below the
* threshold ss_rssi_thr
* @ss_rssi_thr: ADC RSSI must be greater than or equal to this
* threshold (signed Db) to ensure spectral scan
* reporting with normal phy error codes (please see
* ss_rssi_rpt_mode above).Though stored as an unsigned
* value, this should be treated as a signed 8-bit int
* @ss_pwr_format: Format of frequency bin magnitude for spectral scan
* triggered FFTs 0: linear magnitude
* 1: log magnitude (20*log10(lin_mag), 1/2 dB step size)
* @ss_rpt_mode: Format of per-FFT reports to software for spectral
* scan triggered FFTs
* 0: No FFT report (only pulse end summary)
* 1: 2-dword summary of metrics for each completed FFT
* 2: 2-dword summary + 1x-oversampled bins(in-band) per
* FFT
* 3: 2-dword summary + 2x-oversampled bins (all) per FFT
* @ss_bin_scale: Number of LSBs to shift out to scale the FFT bins
* for spectral scan triggered FFTs
* @ss_dBm_adj: Set (with ss_pwr_format=1), to report bin
* magnitudes
* converted to dBm power using the noisefloor
* calibration results
* @ss_chn_mask: Per chain enable mask to select input ADC for search
* FFT
* @ss_nf_cal: nf calibrated values for ctl+ext
* @ss_nf_pwr: nf pwr values for ctl+ext
* @ss_nf_temp_data: temperature data taken during nf scan
*/
struct spectral_config {
u_int16_t ss_fft_period;
u_int16_t ss_period;
u_int16_t ss_count;
u_int16_t ss_short_report;
u_int8_t radar_bin_thresh_sel;
u_int16_t ss_spectral_pri;
u_int16_t ss_fft_size;
u_int16_t ss_gc_ena;
u_int16_t ss_restart_ena;
u_int16_t ss_noise_floor_ref;
u_int16_t ss_init_delay;
u_int16_t ss_nb_tone_thr;
u_int16_t ss_str_bin_thr;
u_int16_t ss_wb_rpt_mode;
u_int16_t ss_rssi_rpt_mode;
u_int16_t ss_rssi_thr;
u_int16_t ss_pwr_format;
u_int16_t ss_rpt_mode;
u_int16_t ss_bin_scale;
u_int16_t ss_dBm_adj;
u_int16_t ss_chn_mask;
int8_t ss_nf_cal[AH_MAX_CHAINS * 2];
int8_t ss_nf_pwr[AH_MAX_CHAINS * 2];
int32_t ss_nf_temp_data;
};
/**
* struct spectral_caps - Spectral capabilities structure
* @phydiag_cap: Phydiag capability
* @radar_cap: Radar detection capability
* @spectral_cap: Spectral capability
* @advncd_spectral_cap: Advanced spectral capability
*/
typedef enum _dcs_int_type {
SPECTRAL_DCS_INT_NONE,
SPECTRAL_DCS_INT_CW,
SPECTRAL_DCS_INT_WIFI
} DCS_INT_TYPE;
/**
* struct INTERF_RSP - Interference record
* @interf_type: eINTERF_TYPE giving type of interference
* @interf_min_freq: Minimum frequency in MHz at which interference has been
* found
* @interf_max_freq: Maximum frequency in MHz at which interference has been
* found
* @advncd_spectral_cap: Advanced spectral capability
*/
struct INTERF_RSP {
u_int8_t interf_type;
u_int16_t interf_min_freq;
u_int16_t interf_max_freq;
} __ATTRIB_PACKED;
/**
* struct INTERF_SRC_RSP - List of interference sources
* @count: Number of interference records
* @interf: Array of interference records
*/
struct INTERF_SRC_RSP {
u_int16_t count;
struct INTERF_RSP interf[MAX_INTERF];
} __ATTRIB_PACKED;
/**
* struct spectral_classifier_params -
* @spectral_20_40_mode: Is AP in 20/40 mode?
* @spectral_dc_index: DC index
* @spectral_dc_in_mhz: DC in MHz
* @upper_chan_in_mhz: Upper channel in MHz
* @lower_chan_in_mhz: Lower channel in MHz
*/
typedef struct spectral_classifier_params {
int spectral_20_40_mode;
int spectral_dc_index;
int spectral_dc_in_mhz;
int upper_chan_in_mhz;
int lower_chan_in_mhz;
} __ATTRIB_PACKED SPECTRAL_CLASSIFIER_PARAMS;
/**
* struct spectral_samp_data - Spectral Analysis Messaging Protocol Data format
* @spectral_data_len: Indicates the bin size
* @spectral_data_len_sec80: Indicates the bin size for secondary 80 segment
* @spectral_rssi: Indicates RSSI
* @spectral_rssi_sec80: Indicates RSSI for secondary 80 segment
* @spectral_combined_rssi: Indicates combined RSSI from all antennas
* @spectral_upper_rssi: Indicates RSSI of upper band
* @spectral_lower_rssi: Indicates RSSI of lower band
* @spectral_chain_ctl_rssi: RSSI for control channel, for all antennas
* @spectral_chain_ext_rssi: RSSI for extension channel, for all antennas
* @spectral_max_scale: Indicates scale factor
* @spectral_bwinfo: Indicates bandwidth info
* @spectral_tstamp: Indicates timestamp
* @spectral_max_index: Indicates the index of max magnitude
* @spectral_max_index_sec80: Indicates the index of max magnitude for secondary
* 80 segment
* @spectral_max_mag: Indicates the maximum magnitude
* @spectral_max_mag_sec80: Indicates the maximum magnitude for secondary 80
* segment
* @spectral_max_exp: Indicates the max exp
* @spectral_last_tstamp: Indicates the last time stamp
* @spectral_upper_max_index: Indicates the index of max mag in upper band
* @spectral_lower_max_index: Indicates the index of max mag in lower band
* @spectral_nb_upper: Not Used
* @spectral_nb_lower: Not Used
* @classifier_params: Indicates classifier parameters
* @bin_pwr_count: Indicates the number of FFT bins
* @lb_edge_extrabins: Number of extra bins on left band edge
* @rb_edge_extrabins: Number of extra bins on right band edge
* @bin_pwr_count_sec80: Indicates the number of FFT bins in secondary 80
* segment
* @bin_pwr: Contains FFT magnitudes
* @bin_pwr_sec80: Contains FFT magnitudes for the secondary 80
* segment
* @interf_list: List of interfernce sources
* @noise_floor: Indicates the current noise floor
* @noise_floor_sec80: Indicates the current noise floor for secondary 80
* segment
* @ch_width: Channel width 20/40/80/160 MHz
*/
typedef struct spectral_samp_data {
int16_t spectral_data_len;
int16_t spectral_data_len_sec80;
int16_t spectral_rssi;
int16_t spectral_rssi_sec80;
int8_t spectral_combined_rssi;
int8_t spectral_upper_rssi;
int8_t spectral_lower_rssi;
int8_t spectral_chain_ctl_rssi[MAX_SPECTRAL_CHAINS];
int8_t spectral_chain_ext_rssi[MAX_SPECTRAL_CHAINS];
u_int8_t spectral_max_scale;
int16_t spectral_bwinfo;
int32_t spectral_tstamp;
int16_t spectral_max_index;
int16_t spectral_max_index_sec80;
int16_t spectral_max_mag;
int16_t spectral_max_mag_sec80;
u_int8_t spectral_max_exp;
int32_t spectral_last_tstamp;
int16_t spectral_upper_max_index;
int16_t spectral_lower_max_index;
u_int8_t spectral_nb_upper;
u_int8_t spectral_nb_lower;
struct spectral_classifier_params classifier_params;
u_int16_t bin_pwr_count;
/* For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are
* delivered. However, there can be additional bins reported for
* AR900B version 2.0 and QCA9984 as described next:
*
* AR900B version 2.0: An additional tone is processed on the right
* hand side in order to facilitate detection of radar pulses out to
* the extreme band-edge of the channel frequency.
* Since the HW design processes four tones at a time,
* this requires one additional Dword to be added to the
* search FFT report.
*
* QCA9984: When spectral_scan_rpt_mode=2, i.e 2-dword summary +
* 1x-oversampled bins (in-band) per FFT,
* then 8 more bins (4 more on left side and 4 more on right side)
* are added.
*/
u_int8_t lb_edge_extrabins;
u_int8_t rb_edge_extrabins;
u_int16_t bin_pwr_count_sec80;
u_int8_t bin_pwr[MAX_NUM_BINS];
u_int8_t bin_pwr_sec80[MAX_NUM_BINS];
struct INTERF_SRC_RSP interf_list;
int16_t noise_floor;
int16_t noise_floor_sec80;
u_int32_t ch_width;
} __ATTRIB_PACKED SPECTRAL_SAMP_DATA;
/**
* struct spectral_samp_msg - Spectral SAMP message
* @signature: Validates the SAMP message
* @freq: Operating frequency in MHz
* @vhtop_ch_freq_seg1: VHT Segment 1 centre frequency in MHz
* @vhtop_ch_freq_seg2: VHT Segment 2 centre frequency in MHz
* @freq_loading: How busy was the channel
* @dcs_enabled: Whether DCS is enabled
* @int_type: Interference type indicated by DCS
* @macaddr: Indicates the device interface
* @samp_data: SAMP Data
*/
typedef struct spectral_samp_msg {
u_int32_t signature;
u_int16_t freq;
u_int16_t vhtop_ch_freq_seg1;
u_int16_t vhtop_ch_freq_seg2;
u_int16_t freq_loading;
u_int16_t dcs_enabled;
DCS_INT_TYPE int_type;
u_int8_t macaddr[6];
SPECTRAL_SAMP_DATA samp_data;
} __ATTRIB_PACKED SPECTRAL_SAMP_MSG;
#ifdef WIN32
#pragma pack(pop, spectral)
#endif
#ifdef __ATTRIB_PACKED
#undef __ATTRIB_PACKED
#endif
#endif /* _WLAN_SPECTRAL_PUBLIC_STRUCTS_H_ */

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _WLAN_SPECTRAL_TGT_API_H_
#define _WLAN_SPECTRAL_TGT_API_H_
#include <wlan_objmgr_cmn.h>
#include <qdf_types.h>
/**
* tgt_send_phydata() - Send Spectral PHY data over netlink
* @pdev: Pointer to pdev
* @sock: Netlink socket to use
* @nbuf: Network buffer containing PHY data to send
*
* Return: 0 on success, negative value on failure
*/
int tgt_send_phydata(struct wlan_objmgr_pdev *pdev,
struct sock *sock, qdf_nbuf_t nbuf);
/**
* tgt_get_target_handle() - Get handle to target_if internal Spectral data
* @pdev: Pointer to pdev
*
* Return: Handle to target_if internal Spectral data on success, NULL on
* failure
*/
void *tgt_get_target_handle(struct wlan_objmgr_pdev *pdev);
#endif /* _WLAN_SPECTRAL_TGT_API_H_*/

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _WLAN_SPECTRAL_UCFG_API_H_
#define _WLAN_SPECTRAL_UCFG_API_H_
#include <wlan_objmgr_cmn.h>
#include <wlan_spectral_public_structs.h>
/* Spectral specific UCFG set operations */
/**
* ucfg_spectral_control() - Carry out Spectral control get/set operations
* @pdev: Pointer to pdev
* @id: Spectral operation ID
* @indata: Pointer to input data
* @insize: Size of indata buffer
* @outdata: Pointer to buffer where the output should be stored
* @outsize: Size of outdata buffer
*
* Return: 0 on success, negative value on failure
*/
int ucfg_spectral_control(
struct wlan_objmgr_pdev *pdev,
u_int id,
void *indata,
u_int32_t insize,
void *outdata, u_int32_t *outsize);
#endif /* _WLAN_SPECTRAL_UCFG_API_H_*/

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _WLAN_SPECTRAL_UTILS_API_H_
#define _WLAN_SPECTRAL_UTILS_API_H_
#include <wlan_objmgr_cmn.h>
#include <wlan_lmac_if_def.h>
/**
* wlan_spectral_init(): API to init spectral component
*
* This API is invoked from dispatcher init during all component init.
* This API will register all required handlers for pdev and peer object
* create/delete notification.
*
* Return: SUCCESS,
* Failure
*/
QDF_STATUS wlan_spectral_init(void);
/**
* wlan_spectral_deinit(): API to deinit spectral component
*
* This API is invoked from dispatcher deinit during all component deinit.
* This API will unregister all registered handlers for pdev and peer object
* create/delete notification.
*
* Return: SUCCESS,
* Failure
*/
QDF_STATUS wlan_spectral_deinit(void);
/**
* wlan_lmac_if_sptrl_register_rx_ops(): Register lmac interface Rx operations
* @rx_ops: Pointer to lmac interface Rx operations structure
*
* Return: None
*/
void wlan_lmac_if_sptrl_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops);
#endif /* _WLAN_SPECTRAL_UTILS_API_H_*/

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2011,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <wlan_spectral_tgt_api.h>
#include "../../core/spectral_cmn_api_i.h"
int tgt_send_phydata(struct wlan_objmgr_pdev *pdev,
struct sock *sock, qdf_nbuf_t nbuf)
{
return netlink_broadcast(sock, nbuf, 0, 1, GFP_ATOMIC);
}
void *tgt_get_target_handle(struct wlan_objmgr_pdev *pdev)
{
struct pdev_spectral *ps;
if (!pdev) {
spectral_err("PDEV is NULL!\n");
return NULL;
}
ps = wlan_objmgr_pdev_get_comp_private_obj(
pdev,
WLAN_UMAC_COMP_SPECTRAL);
if (!ps) {
spectral_err("PDEV SPECTRAL object is NULL!\n");
return NULL;
}
return ps->psptrl_target_handle;
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <wlan_spectral_ucfg_api.h>
#include "../../core/spectral_cmn_api_i.h"
#include <wlan_spectral_utils_api.h>
int ucfg_spectral_control(
struct wlan_objmgr_pdev *pdev,
u_int id,
void *indata,
u_int32_t insize,
void *outdata, u_int32_t *outsize)
{
struct spectral_context *sc;
if (!pdev) {
spectral_err("PDEV is NULL!\n");
return -EPERM;
}
sc = spectral_get_spectral_ctx_from_pdev(pdev);
if (!sc) {
spectral_err("spectral context is NULL!\n");
return -EPERM;
}
return sc->sptrlc_spectral_control(
pdev,
id,
indata,
insize,
outdata,
outsize);
}
EXPORT_SYMBOL(ucfg_spectral_control);

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <wlan_spectral_utils_api.h>
#include <qdf_module.h>
#include "../../core/spectral_cmn_api_i.h"
#include <wlan_spectral_tgt_api.h>
QDF_STATUS wlan_spectral_init(void)
{
if (wlan_objmgr_register_psoc_create_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_psoc_obj_create_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_register_psoc_destroy_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_psoc_obj_destroy_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_register_pdev_create_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_pdev_obj_create_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_register_pdev_destroy_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_pdev_obj_destroy_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wlan_spectral_deinit(void)
{
if (wlan_objmgr_unregister_psoc_create_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_psoc_obj_create_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_unregister_psoc_destroy_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_psoc_obj_destroy_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_unregister_pdev_create_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_pdev_obj_create_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
if (wlan_objmgr_unregister_pdev_destroy_handler(
WLAN_UMAC_COMP_SPECTRAL,
wlan_spectral_pdev_obj_destroy_handler,
NULL) != QDF_STATUS_SUCCESS) {
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
void wlan_lmac_if_sptrl_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
{
struct wlan_lmac_if_sptrl_rx_ops *sptrl_rx_ops = &rx_ops->sptrl_rx_ops;
/* Spectral rx ops */
sptrl_rx_ops->sptrlro_send_phydata = tgt_send_phydata;
sptrl_rx_ops->sptrlro_get_target_handle = tgt_get_target_handle;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,982 @@
/*
* Copyright (c) 2011,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _TARGET_IF_SPECTRAL_H_
#define _TARGET_IF_SPECTRAL_H_
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <qdf_lock.h>
#include <wlan_spectral_public_structs.h>
#include <reg_services_public_struct.h>
extern int spectral_debug_level;
#ifdef WIN32
#pragma pack(push, target_if_spectral, 1)
#define __ATTRIB_PACK
#else
#ifndef __ATTRIB_PACK
#define __ATTRIB_PACK __attribute__ ((packed))
#endif
#endif
#define spectral_log(level, args...) \
QDF_PRINT_INFO(QDF_PRINT_IDX_SHARED, QDF_MODULE_ID_SPECTRAL, level, ## args)
#define spectral_logfl(level, format, args...) \
spectral_log(level, FL(format), ## args)
#define spectral_fatal(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
#define spectral_err(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
#define spectral_warn(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
#define spectral_info(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
#define spectral_debug(format, args...) \
spectral_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
#define STATUS_PASS 1
#define STATUS_FAIL 0
#define line() \
qdf_print("----------------------------------------------------\n")
#define SPECTRAL_TODO(str) \
qdf_print(KERN_INFO "SPECTRAL : %s (%s : %d)\n", \
(str), __func__, __LINE__)
#define spectral_ops_not_registered(str) \
qdf_print(KERN_INFO "SPECTRAL : %s not registered\n", (str))
#define not_yet_implemented() \
qdf_print("SPECTRAL : %s : %d Not yet implemented\n", \
__func__, __LINE__)
#define SPECTRAL_HT20_NUM_BINS 56
#define SPECTRAL_HT20_FFT_LEN 56
#define SPECTRAL_HT20_DC_INDEX (SPECTRAL_HT20_FFT_LEN / 2)
#define SPECTRAL_HT20_DATA_LEN 60
#define SPECTRAL_HT20_TOTAL_DATA_LEN (SPECTRAL_HT20_DATA_LEN + 3)
#define SPECTRAL_HT40_TOTAL_NUM_BINS 128
#define SPECTRAL_HT40_DATA_LEN 135
#define SPECTRAL_HT40_TOTAL_DATA_LEN (SPECTRAL_HT40_DATA_LEN + 3)
#define SPECTRAL_HT40_FFT_LEN 128
#define SPECTRAL_HT40_DC_INDEX (SPECTRAL_HT40_FFT_LEN / 2)
/* Used for the SWAR to obtain approximate combined rssi
* in secondary 80Mhz segment
*/
#define OFFSET_CH_WIDTH_20 65
#define OFFSET_CH_WIDTH_40 62
#define OFFSET_CH_WIDTH_80 56
#define OFFSET_CH_WIDTH_160 50
#ifdef BIG_ENDIAN_HOST
#define SPECTRAL_MSG_COPY_CHAR_ARRAY(destp, srcp, len) do { \
int j; \
u_int32_t *src, *dest; \
src = (u_int32_t *)(srcp); \
dest = (u_int32_t *)(destp); \
for (j = 0; j < roundup((len), sizeof(u_int32_t)) / 4; j++) { \
*(dest + j) = qdf_le32_to_cpu(*(src + j)); \
} \
} while (0)
#else
#define SPECTRAL_MSG_COPY_CHAR_ARRAY(destp, srcp, len) \
OS_MEMCPY((destp), (srcp), (len));
#endif
/* 5 categories x (lower + upper) bands */
#define MAX_INTERF 10
#define ATH_HOST_MAX_ANTENNA 3
/* Mask for time stamp from descriptor */
#define SPECTRAL_TSMASK 0xFFFFFFFF
#define SPECTRAL_SIGNATURE 0xdeadbeef
#define MAX_SPECTRAL_PAYLOAD 1500
#ifndef NETLINK_ATHEROS
#define NETLINK_ATHEROS (NETLINK_GENERIC + 1)
#endif
/* START of spectral GEN II HW specific details */
#define SPECTRAL_PHYERR_SIGNATURE_GEN2 0xbb
#define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2 0xF9
#define TLV_TAG_ADC_REPORT_GEN2 0xFA
#define TLV_TAG_SEARCH_FFT_REPORT_GEN2 0xFB
/**
* struct spectral_search_fft_info_gen2 - spectral search fft report for gen2
* @relpwr_db: Total bin power in db
* @num_str_bins_ib: Number of strong bins
* @base_pwr: Base power
* @total_gain_info: Total gain
* @fft_chn_idx: FFT chain on which report is originated
* @avgpwr_db: Average power in db
* @peak_mag: Peak power seen in the bins
* @peak_inx: Index of bin holding peak power
*/
typedef struct spectral_search_fft_info_gen2 {
uint32_t relpwr_db;
uint32_t num_str_bins_ib;
uint32_t base_pwr;
uint32_t total_gain_info;
uint32_t fft_chn_idx;
uint32_t avgpwr_db;
uint32_t peak_mag;
int16_t peak_inx;
} SPECTRAL_SEARCH_FFT_INFO_GEN2;
/* XXX Check if we should be handling the endinness difference in some
* other way opaque to the host
*/
#ifdef BIG_ENDIAN_HOST
/**
* struct spectral_phyerr_tlv_gen2 - phyerr tlv info for big endian host
* @signature: signature
* @tag: tag
* @length: length
*/
typedef struct spectral_phyerr_tlv_gen2 {
u_int8_t signature;
u_int8_t tag;
u_int16_t length;
} __ATTRIB_PACK SPECTRAL_PHYERR_TLV_GEN2;
#else
/**
* struct spectral_phyerr_tlv_gen2 - phyerr tlv info for little endian host
* @length: length
* @tag: tag
* @signature: signature
*/
typedef struct spectral_phyerr_tlv_gen2 {
u_int16_t length;
u_int8_t tag;
u_int8_t signature;
} __ATTRIB_PACK SPECTRAL_PHYERR_TLV_GEN2;
#endif /* BIG_ENDIAN_HOST */
/**
* struct spectral_phyerr_hdr_gen2 - phyerr header for gen2 HW
* @hdr_a: Header[0:31]
* @hdr_b: Header[32:63]
*/
typedef struct spectral_phyerr_hdr_gen2 {
u_int32_t hdr_a;
u_int32_t hdr_b;
} SPECTRAL_PHYERR_HDR_GEN2;
/* Segment ID information for 80+80.
*
* If the HW micro-architecture specification extends this DWORD for other
* purposes, then redefine+rename accordingly. For now, the specification
* mentions only segment ID (though this doesn't require an entire DWORD)
* without mention of any generic terminology for the DWORD, or any reservation.
* We use nomenclature accordingly.
*/
typedef u_int32_t SPECTRAL_SEGID_INFO;
/**
* struct spectral_phyerr_fft_gen2 - fft info in phyerr event
* @buf: fft report
*/
typedef struct spectral_phyerr_fft_gen2 {
u_int8_t buf[0];
} SPECTRAL_PHYERR_FFT_GEN2;
/* END of spectral GEN II HW specific details */
/* START of spectral GEN III HW specific details */
#define get_bitfield(value, size, pos) \
(((value) >> (pos)) & ((1 << (size)) - 1))
#define unsigned_to_signed(value, width) \
(((value) >= (1 << ((width) - 1))) ? \
(value - (1 << (width))) : (value))
#define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA)
#define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02)
#define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03)
#define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4)
#define PHYERR_HDR_SIG_POS \
(offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_sig))
#define PHYERR_HDR_TAG_POS \
(offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_tag))
#define SPECTRAL_FFT_BINS_POS \
(offsetof(struct spectral_phyerr_fft_report_gen3, buf))
/**
* struct phyerr_info - spectral search fft report for gen3
* @data: handle to phyerror buffer
* @datalen: length of phyerror bufer
* @p_rfqual: rf quality matrices
* @p_chaninfo: pointer to chaninfo
* @tsf64: 64 bit TSF
* @acs_stats: acs stats
*/
struct phyerr_info {
u_int8_t *data;
u_int32_t datalen;
struct target_if_spectral_rfqual_info *p_rfqual;
struct target_if_spectral_chan_info *p_chaninfo;
u_int64_t tsf64;
struct target_if_spectral_acs_stats *acs_stats;
};
/**
* struct spectral_search_fft_info_gen3 - spectral search fft report for gen3
* @timestamp: Timestamp at which fft report was generated
* @fft_detector_id: Which radio generated this report
* @fft_num: The FFT count number. Set to 0 for short FFT.
* @fft_radar_check: NA for spectral
* @fft_peak_sidx: Index of bin with maximum power
* @fft_chn_idx: Rx chain index
* @fft_base_pwr_db: Base power in dB
* @fft_total_gain_db: Total gain in dB
* @fft_num_str_bins_ib: Number of strong bins in the report
* @fft_peak_mag: Peak magnitude
* @fft_avgpwr_db: Average power in dB
* @fft_relpwr_db: Relative power in dB
*/
struct spectral_search_fft_info_gen3 {
uint32_t timestamp;
uint32_t fft_detector_id;
uint32_t fft_num;
uint32_t fft_radar_check;
int32_t fft_peak_sidx;
uint32_t fft_chn_idx;
uint32_t fft_base_pwr_db;
uint32_t fft_total_gain_db;
uint32_t fft_num_str_bins_ib;
int32_t fft_peak_mag;
uint32_t fft_avgpwr_db;
uint32_t fft_relpwr_db;
};
/**
* struct spectral_phyerr_sfftreport_gen3 - fft info in phyerr event
* @fft_timestamp: Timestamp at which fft report was generated
* @fft_hdr_sig: signature
* @fft_hdr_tag: tag
* @fft_hdr_length: length
* @hdr_a: Header[0:31]
* @hdr_b: Header[32:63]
* @hdr_c: Header[64:95]
* @resv: Header[96:127]
* @buf: fft bins
*/
struct spectral_phyerr_fft_report_gen3 {
u_int32_t fft_timestamp;
#ifdef BIG_ENDIAN_HOST
u_int8_t fft_hdr_sig;
u_int8_t fft_hdr_tag;
u_int16_t fft_hdr_length;
#else
u_int16_t fft_hdr_length;
u_int8_t fft_hdr_tag;
u_int8_t fft_hdr_sig;
#endif /* BIG_ENDIAN_HOST */
u_int32_t hdr_a;
u_int32_t hdr_b;
u_int32_t hdr_c;
u_int32_t resv;
u_int8_t buf[0];
} __ATTRIB_PACK;
/* END of spectral GEN III HW specific details */
typedef signed char pwr_dbm;
/**
* enum spectral_gen - spectral hw generation
* @SPECTRAL_GEN1 : spectral hw gen 1
* @SPECTRAL_GEN2 : spectral hw gen 2
* @SPECTRAL_GEN3 : spectral hw gen 3
*/
enum spectral_gen {
SPECTRAL_GEN1,
SPECTRAL_GEN2,
SPECTRAL_GEN3,
};
#if ATH_PERF_PWR_OFFLOAD
/**
* enum ol_spectral_info_spec - Enumerations for specifying which spectral
* information (among parameters and states)
* is desired.
* @OL_SPECTRAL_INFO_SPEC_ACTIVE: Indicated whether spectral is active
* @OL_SPECTRAL_INFO_SPEC_ENABLED: Indicated whether spectral is enabled
* @OL_SPECTRAL_INFO_SPEC_PARAMS: Config params
*/
enum ol_spectral_info_spec {
OL_SPECTRAL_INFO_SPEC_ACTIVE,
OL_SPECTRAL_INFO_SPEC_ENABLED,
OL_SPECTRAL_INFO_SPEC_PARAMS,
};
#endif /* ATH_PERF_PWR_OFFLOAD */
/* forward declaration */
struct target_if_spectral;
/**
* struct target_if_spectral_chan_info - Channel information
* @center_freq1: center frequency 1 in MHz
* @center_freq2: center frequency 2 in MHz -valid only for
* 11ACVHT 80PLUS80 mode
* @chan_width: channel width in MHz
*/
struct target_if_spectral_chan_info {
u_int16_t center_freq1;
u_int16_t center_freq2;
u_int8_t chan_width;
};
/**
* struct target_if_spectral_acs_stats - EACS stats from spectral samples
* @nfc_ctl_rssi: Control chan rssi
* @nfc_ext_rssi: Extension chan rssi
* @ctrl_nf: Control chan Noise Floor
* @ext_nf: Extension chan Noise Floor
*/
struct target_if_spectral_acs_stats {
int8_t nfc_ctl_rssi;
int8_t nfc_ext_rssi;
int8_t ctrl_nf;
int8_t ext_nf;
};
/**
* struct target_if_spectral_perchain_rssi_info - per chain rssi info
* @rssi_pri20: Rssi of primary 20 Mhz
* @rssi_sec20: Rssi of secondary 20 Mhz
* @rssi_sec40: Rssi of secondary 40 Mhz
* @rssi_sec80: Rssi of secondary 80 Mhz
*/
struct target_if_spectral_perchain_rssi_info {
int8_t rssi_pri20;
int8_t rssi_sec20;
int8_t rssi_sec40;
int8_t rssi_sec80;
};
/**
* struct target_if_spectral_rfqual_info - RF measurement information
* @rssi_comb: RSSI Information
* @pc_rssi_info: XXX : For now, we know we are getting information
* for only 4 chains at max. For future extensions
* use a define
* @noise_floor: Noise floor information
*/
struct target_if_spectral_rfqual_info {
int8_t rssi_comb;
struct target_if_spectral_perchain_rssi_info pc_rssi_info[4];
int16_t noise_floor[4];
};
#define GET_TIF_SPECTRAL_OPS(spectral) \
((struct target_if_spectral_ops *)(&((spectral)->spectral_ops)))
/**
* struct target_if_spectral_ops - spectral low level ops table
* @get_tsf64: Get 64 bit TSF value
* @get_capability: Get capability info
* @set_rxfilter: Set rx filter
* @get_rxfilter: Get rx filter
* @is_spectral_active: Check whether icm is active
* @is_spectral_enabled: Check whether spectral is enabled
* @start_spectral_scan: Start spectral scan
* @stop_spectral_scan: Stop spectral scan
* @get_extension_channel: Get extension channel
* @get_ctl_noisefloor: Get control noise floor
* @get_ext_noisefloor: Get extension noise floor
* @configure_spectral: Set spectral configurations
* @get_spectral_config: Get spectral configurations
* @get_ent_spectral_mask: Get spectral mask
* @get_mac_address: Get mac address
* @get_current_channel: Get current channel
* @reset_hw: Reset HW
* @get_chain_noise_floor: Get Channel noise floor
* @spectral_process_phyerr: Process phyerr event
*/
struct target_if_spectral_ops {
u_int64_t (*get_tsf64)(void *arg);
u_int32_t (*get_capability)(void *arg, SPECTRAL_CAPABILITY_TYPE type);
u_int32_t (*set_rxfilter)(void *arg, int rxfilter);
u_int32_t (*get_rxfilter)(void *arg);
u_int32_t (*is_spectral_active)(void *arg);
u_int32_t (*is_spectral_enabled)(void *arg);
u_int32_t (*start_spectral_scan)(void *arg);
u_int32_t (*stop_spectral_scan)(void *arg);
u_int32_t (*get_extension_channel)(void *arg);
int8_t (*get_ctl_noisefloor)(void *arg);
int8_t (*get_ext_noisefloor)(void *arg);
u_int32_t (*configure_spectral)(
void *arg,
struct spectral_config *params);
u_int32_t (*get_spectral_config)(
void *arg,
struct spectral_config *params);
u_int32_t (*get_ent_spectral_mask)(void *arg);
u_int32_t (*get_mac_address)(void *arg, char *addr);
u_int32_t (*get_current_channel)(void *arg);
u_int32_t (*reset_hw)(void *arg);
u_int32_t (*get_chain_noise_floor)(void *arg, int16_t *nf_buf);
int (*spectral_process_phyerr)(struct target_if_spectral *spectral,
u_int8_t *data, u_int32_t datalen,
struct target_if_spectral_rfqual_info *p_rfqual,
struct target_if_spectral_chan_info *p_chaninfo,
u_int64_t tsf64,
struct target_if_spectral_acs_stats *acs_stats);
};
/**
* struct target_if_spectral_stats - spectral stats info
* @num_spectral_detects: Total num. of spectral detects
* @total_phy_errors: Total number of phyerrors
* @owl_phy_errors: Indicated phyerrors in old gen1 chipsets
* @pri_phy_errors: Phyerrors in primary channel
* @ext_phy_errors: Phyerrors in secondary channel
* @dc_phy_errors: Phyerrors due to dc
* @early_ext_phy_errors: Early secondary channel phyerrors
* @bwinfo_errors: Bandwidth info errors
* @datalen_discards: Invalid data length errors, seen in gen1 chipsets
* @rssi_discards bw: Indicates reports dropped due to RSSI threshold
* @last_reset_tstamp: Last reset time stamp
*/
struct target_if_spectral_stats {
u_int32_t num_spectral_detects;
u_int32_t total_phy_errors;
u_int32_t owl_phy_errors;
u_int32_t pri_phy_errors;
u_int32_t ext_phy_errors;
u_int32_t dc_phy_errors;
u_int32_t early_ext_phy_errors;
u_int32_t bwinfo_errors;
u_int32_t datalen_discards;
u_int32_t rssi_discards;
u_int64_t last_reset_tstamp;
};
/**
* struct target_if_spectral_event - spectral event structure
* @se_ts: Original 15 bit recv timestamp
* @se_full_ts: 64-bit full timestamp from interrupt time
* @se_rssi: Rssi of spectral event
* @se_bwinfo: Rssi of spectral event
* @se_dur: Duration of spectral pulse
* @se_chanindex: Channel of event
* @se_list: List of spectral events
*/
struct target_if_spectral_event {
u_int32_t se_ts;
u_int64_t se_full_ts;
u_int8_t se_rssi;
u_int8_t se_bwinfo;
u_int8_t se_dur;
u_int8_t se_chanindex;
STAILQ_ENTRY(spectral_event) se_list;
};
/**
* struct target_if_chain_noise_pwr_info - Noise power info for each channel
* @rptcount: Count of reports in pwr array
* @un_cal_nf: Uncalibrated noise floor
* @factory_cal_nf: Noise floor as calibrated at the factory for module
* @median_pwr: Median power (median of pwr array)
* @pwr: Power reports
*/
struct target_if_chain_noise_pwr_info {
int rptcount;
pwr_dbm un_cal_nf;
pwr_dbm factory_cal_nf;
pwr_dbm median_pwr;
pwr_dbm pwr[];
} __ATTRIB_PACK;
/**
* struct target_if_spectral_chan_stats - Channel information
* @cycle_count: Cycle count
* @channel_load: Channel load
* @per: Period
* @noisefloor: Noise floor
* @comp_usablity: Computed usability
* @maxregpower: Maximum allowed regulatary power
* @comp_usablity_sec80: Computed usability of secondary 80 Mhz
* @maxregpower_sec80: Max regulatory power in secondary 80 Mhz
*/
struct target_if_spectral_chan_stats {
int cycle_count;
int channel_load;
int per;
int noisefloor;
u_int16_t comp_usablity;
int8_t maxregpower;
u_int16_t comp_usablity_sec80;
int8_t maxregpower_sec80;
};
#if ATH_PERF_PWR_OFFLOAD
/* Locking operations
* We have a separate set of definitions for offload to accommodate
* offload specific changes in the future.
*/
#define OL_SPECTRAL_LOCK_INIT(_lock) qdf_spinlock_create((_lock))
#define OL_SPECTRAL_LOCK_DESTROY(_lock) qdf_spinlock_destroy((_lock))
#define OL_SPECTRAL_LOCK(_lock) qdf_spin_lock((_lock))
#define OL_SPECTRAL_UNLOCK(_lock) qdf_spin_unlock((_lock))
/**
* struct target_if_spectral_cache - Cache used to minimize WMI operations
* in offload architecture
* @osc_spectral_enabled: Whether Spectral is enabled
* @osc_spectral_active: Whether spectral is active
* XXX: Ideally, we should NOT cache this
* since the hardware can self clear the bit,
* the firmware can possibly stop spectral due to
* intermittent off-channel activity, etc
* A WMI read command should be introduced to handle
* this This will be discussed.
* @osc_params: Spectral parameters
* @osc_is_valid: Whether the cache is valid
*/
struct target_if_spectral_cache {
u_int8_t osc_spectral_enabled;
u_int8_t osc_spectral_active;
struct spectral_config osc_params;
u_int8_t osc_is_valid;
};
/**
* struct target_if_spectral_param_state_info - Structure used to represent and
* manage spectral information
* (parameters and states)
* @osps_lock: Lock to synchronize accesses to information
* @osps_cache: Cacheable' information
*/
struct target_if_spectral_param_state_info {
qdf_spinlock_t osps_lock;
struct target_if_spectral_cache osps_cache;
/* XXX - Non-cacheable information goes here, in the future */
};
#endif /* ATH_PERF_PWR_OFFLOAD */
/**
* struct target_if_spectral - main spectral structure
* @pdev: Pointer to pdev
* @spectral_ops: Target if internal Spectral low level operations table
* @capability: Spectral capabilities structure
* @ath_spectral_lock: Lock used for internal Spectral operations
* @spectral_curchan_radindex: Current channel spectral index
* @spectral_extchan_radindex: Extension channel spectral index
* @spectraldomain: Current Spectral domain
* @spectral_proc_phyerr: Flags to process for PHY errors
* @spectral_defaultparams: Default PHY params per Spectral stat
* @ath_spectral_stats: Spectral related stats
* @events: Events structure
* @sc_spectral_ext_chan_ok: Can spectral be detected on the extension channel?
* @sc_spectral_combined_rssi_ok: Can use combined spectral RSSI?
* @sc_spectral_20_40_mode: Is AP in 20-40 mode?
* @sc_spectral_noise_pwr_cal: Noise power cal required?
* @sc_spectral_non_edma: Is the spectral capable device Non-EDMA?
* @upper_is_control: Upper segment is primary
* @upper_is_extension: Upper segment is secondary
* @lower_is_control: Lower segment is primary
* @lower_is_extension: Lower segment is secondary
* @sc_spectraltest_ieeechan: IEEE channel number to return to after a spectral
* mute test
* @spectral_numbins: Number of bins
* @spectral_fft_len: FFT length
* @spectral_data_len: Total phyerror report length
* @lb_edge_extrabins: Number of extra bins on left band edge
* @rb_edge_extrabins: Number of extra bins on right band edge
* @spectral_max_index_offset: Max FFT index offset (20 MHz mode)
* @spectral_upper_max_index_offset: Upper max FFT index offset (20/40 MHz mode)
* @spectral_lower_max_index_offset: Lower max FFT index offset (20/40 MHz mode)
* @spectral_dc_index: At which index DC is present
* @send_single_packet: Deprecated
* @spectral_sent_msg: Indicates whether we send report to upper layers
* @params: Spectral parameters
* @last_capture_time: Indicates timestamp of previouse report
* @num_spectral_data: Number of Spectral samples received in current session
* @total_spectral_data: Total number of Spectral samples received
* @max_rssi: Maximum RSSI
* @detects_control_channel: NA
* @detects_extension_channel: NA
* @detects_below_dc: NA
* @detects_above_dc: NA
* @sc_scanning: Indicates active wifi scan
* @sc_spectral_scan: Indicates active specral scan
* @sc_spectral_full_scan: Deprecated
* @scan_start_tstamp: Deprecated
* @last_tstamp: Deprecated
* @first_tstamp: Deprecated
* @spectral_samp_count: Deprecated
* @sc_spectral_samp_count: Deprecated
* @noise_pwr_reports_reqd: Number of noise power reports required
* @noise_pwr_reports_recv: Number of noise power reports received
* @noise_pwr_reports_lock: Lock used for Noise power report processing
* @noise_pwr_chain_ctl: Noise power report - control channel
* @noise_pwr_chain_ext: Noise power report - extension channel
* @chaninfo: Channel statistics
* @tsf64: Latest TSF Value
* @ol_info: Offload architecture Spectral parameter cache information
* @ch_width: Indicates Channel Width 20/40/80/160 MHz with values 0, 1, 2, 3
* respectively
* @diag_stats: Diagnostic statistics
* @is_160_format: Indicates whether information provided by HW is in altered
* format for 802.11ac 160/80+80 MHz support (QCA9984 onwards)
* @is_lb_edge_extrabins_format: Indicates whether information provided by
* HW has 4 extra bins, at left band edge, for report mode 2
* @is_rb_edge_extrabins_format: Indicates whether information provided
* by HW has 4 extra bins, at right band edge, for report mode 2
* @is_sec80_rssi_war_required: Indicates whether the software workaround is
* required to obtain approximate combined RSSI for secondary 80Mhz segment
* @simctx: Spectral Simulation context
* @spectral_gen: Spectral hardware generation
* @hdr_sig_exp: Expected signature in PHYERR TLV header, for the given hardware
* generation
* @tag_sscan_summary_exp: Expected Spectral Scan Summary tag in PHYERR TLV
* header, for the given hardware generation
* @tag_sscan_fft_exp: Expected Spectral Scan FFT report tag in PHYERR TLV
* header, for the given hardware generation
* @tlvhdr_size: Expected PHYERR TLV header size, for the given hardware
* generation
*/
struct target_if_spectral {
struct wlan_objmgr_pdev *pdev_obj;
struct target_if_spectral_ops spectral_ops;
struct spectral_caps capability;
qdf_spinlock_t ath_spectral_lock;
int16_t spectral_curchan_radindex;
int16_t spectral_extchan_radindex;
u_int32_t spectraldomain;
u_int32_t spectral_proc_phyerr;
struct spectral_config spectral_defaultparams;
struct target_if_spectral_stats ath_spectral_stats;
struct target_if_spectral_event *events;
unsigned int sc_spectral_ext_chan_ok:1,
sc_spectral_combined_rssi_ok:1,
sc_spectral_20_40_mode:1,
sc_spectral_noise_pwr_cal:1,
sc_spectral_non_edma:1;
int upper_is_control;
int upper_is_extension;
int lower_is_control;
int lower_is_extension;
u_int8_t sc_spectraltest_ieeechan;
struct sock *spectral_sock;
struct sk_buff *spectral_skb;
struct nlmsghdr *spectral_nlh;
u_int32_t spectral_pid;
STAILQ_HEAD(, target_if_spectral_skb_event) spectral_skbq;
qdf_spinlock_t spectral_skbqlock;
int spectral_numbins;
int spectral_fft_len;
int spectral_data_len;
/* For 11ac chipsets prior to AR900B version 2.0, a max of 512 bins are
* delivered. However, there can be additional bins reported for
* AR900B version 2.0 and QCA9984 as described next:
*
* AR900B version 2.0: An additional tone is processed on the right
* hand side in order to facilitate detection of radar pulses out to
* the extreme band-edge of the channel frequency. Since the HW design
* processes four tones at a time, this requires one additional Dword
* to be added to the search FFT report.
*
* QCA9984: When spectral_scan_rpt_mode = 2, i.e 2-dword summary +
* 1x-oversampled bins (in-band) per FFT, then 8 more bins
* (4 more on left side and 4 more on right side)are added.
*/
int lb_edge_extrabins;
int rb_edge_extrabins;
int spectral_max_index_offset;
int spectral_upper_max_index_offset;
int spectral_lower_max_index_offset;
int spectral_dc_index;
int send_single_packet;
int spectral_sent_msg;
int classify_scan;
os_timer_t classify_timer;
struct spectral_config params;
struct spectral_classifier_params classifier_params;
int last_capture_time;
int num_spectral_data;
int total_spectral_data;
int max_rssi;
int detects_control_channel;
int detects_extension_channel;
int detects_below_dc;
int detects_above_dc;
int sc_scanning;
int sc_spectral_scan;
int sc_spectral_full_scan;
u_int64_t scan_start_tstamp;
u_int32_t last_tstamp;
u_int32_t first_tstamp;
u_int32_t spectral_samp_count;
u_int32_t sc_spectral_samp_count;
int noise_pwr_reports_reqd;
int noise_pwr_reports_recv;
qdf_spinlock_t noise_pwr_reports_lock;
struct target_if_chain_noise_pwr_info
*noise_pwr_chain_ctl[ATH_HOST_MAX_ANTENNA];
struct target_if_chain_noise_pwr_info
*noise_pwr_chain_ext[ATH_HOST_MAX_ANTENNA];
u_int64_t tsf64;
#if ATH_PERF_PWR_OFFLOAD
struct target_if_spectral_param_state_info ol_info;
#endif
u_int32_t ch_width;
struct spectral_diag_stats diag_stats;
bool is_160_format;
bool is_lb_edge_extrabins_format;
bool is_rb_edge_extrabins_format;
bool is_sec80_rssi_war_required;
#if QCA_SUPPORT_SPECTRAL_SIMULATION
void *simctx;
#endif
enum spectral_gen spectral_gen;
u_int8_t hdr_sig_exp;
u_int8_t tag_sscan_summary_exp;
u_int8_t tag_sscan_fft_exp;
u_int8_t tlvhdr_size;
};
/**
* struct target_if_spectral_skb_event - Used to broadcast FFT report to
* applications
* @sp_skb: Pointer to skb
* @sp_nlh: Pointer to nl message header
* @spectral_skb_list: Linked list to manipulate the reports
*/
struct target_if_spectral_skb_event {
struct sk_buff *sp_skb;
struct nlmsghdr *sp_nlh;
STAILQ_ENTRY(target_if_spectral_skb_event) spectral_skb_list;
};
/* TODO:COMMENTS */
struct target_if_samp_msg_params {
int8_t rssi;
int8_t rssi_sec80;
int8_t lower_rssi;
int8_t upper_rssi;
int8_t chain_ctl_rssi[ATH_HOST_MAX_ANTENNA];
int8_t chain_ext_rssi[ATH_HOST_MAX_ANTENNA];
uint16_t bwinfo;
uint16_t datalen;
uint16_t datalen_sec80;
uint32_t tstamp;
uint32_t last_tstamp;
uint16_t max_mag;
uint16_t max_mag_sec80;
uint16_t max_index;
uint16_t max_index_sec80;
uint8_t max_exp;
int peak;
int pwr_count;
int pwr_count_sec80;
int8_t nb_lower;
int8_t nb_upper;
uint16_t max_lower_index;
uint16_t max_upper_index;
u_int8_t *bin_pwr_data;
u_int8_t *bin_pwr_data_sec80;
u_int16_t freq;
u_int16_t vhtop_ch_freq_seg1;
u_int16_t vhtop_ch_freq_seg2;
u_int16_t freq_loading;
int16_t noise_floor;
int16_t noise_floor_sec80;
struct INTERF_SRC_RSP interf_list;
SPECTRAL_CLASSIFIER_PARAMS classifier_params;
struct ath_softc *sc;
};
/* NETLINK related declarations */
#ifdef SPECTRAL_USE_NETLINK_SOCKETS
#if (KERNEL_VERSION(2, 6, 31) > LINUX_VERSION_CODE)
void spectral_nl_data_ready(struct sock *sk, int len);
#else
void spectral_nl_data_ready(struct sk_buff *skb);
#endif /* VERSION CHECK */
#endif /* SPECTRAL_USE_NETLINK_SOCKETS defined */
void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
extern struct net init_net;
int target_if_spectral_init_netlink(struct target_if_spectral *spectral);
int target_if_spectral_destroy_netlink(struct target_if_spectral *spectral);
void target_if_spectral_unicast_msg(struct target_if_spectral *spectral);
void target_if_spectral_bcast_msg(struct target_if_spectral *spectral);
void target_if_spectral_prep_skb(struct target_if_spectral *spectral);
void target_if_spectral_skb_dequeue(unsigned long data);
void target_if_spectral_create_samp_msg(
struct target_if_spectral *spectral,
struct target_if_samp_msg_params *params);
int spectral_process_phyerr_gen3(
struct target_if_spectral *spectral,
u_int8_t *data,
u_int32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual,
struct target_if_spectral_chan_info *p_chaninfo,
u_int64_t tsf64,
struct target_if_spectral_acs_stats *acs_stats);
int spectral_process_phyerr_gen2(
struct target_if_spectral *spectral,
u_int8_t *data,
u_int32_t datalen, struct target_if_spectral_rfqual_info *p_rfqual,
struct target_if_spectral_chan_info *p_chaninfo,
u_int64_t tsf64,
struct target_if_spectral_acs_stats *acs_stats);
void target_if_spectral_send_intf_found_msg(
struct wlan_objmgr_pdev *pdev,
u_int16_t cw_int, u_int32_t dcs_enabled);
void target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev);
struct wlan_objmgr_vdev *target_if_spectral_get_vdev(
struct target_if_spectral *spectral);
int spectral_dump_header_gen2(SPECTRAL_PHYERR_HDR_GEN2 *phdr);
int8_t get_combined_rssi_sec80_segment_gen2(
struct target_if_spectral *spectral,
SPECTRAL_SEARCH_FFT_INFO_GEN2 *p_sfft_sec80);
int spectral_dump_tlv_gen2(SPECTRAL_PHYERR_TLV_GEN2 *ptlv, bool is_160_format);
int spectral_dump_phyerr_data_gen2(
u_int8_t *data,
u_int32_t datalen,
bool is_160_format);
int spectral_dump_fft_report_gen3(
struct spectral_phyerr_fft_report_gen3 *p_fft_report,
struct spectral_search_fft_info_gen3 *p_sfft);
void target_if_dbg_print_SAMP_msg(SPECTRAL_SAMP_MSG *pmsg);
/* START of spectral GEN III HW specific function declarations */
/* [FIXME] fix the declaration */
int process_search_fft_report_gen3(
struct spectral_phyerr_fft_report_gen3 *p_fft_report,
struct spectral_search_fft_info_gen3 *p_fft_info);
/* END of spectral GEN III HW specific function declarations */
/**
* target_if_send_phydata() - Send Spectral PHY data over netlink
* @pdev: Pointer to pdev
* @sock: Netlink socket to use
* @nbuf: Network buffer containing PHY data to send
*
* Return: 0 on success, negative value on failure
*/
static inline uint32_t target_if_send_phydata(
struct wlan_objmgr_pdev *pdev,
struct sock *sock, qdf_nbuf_t nbuf)
{
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
return psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_send_phydata(pdev,
sock, nbuf);
}
/**
* get_target_if_spectral_handle_from_pdev() - Get handle to target_if internal
* Spectral data
* @pdev: Pointer to pdev
*
* Return: Handle to target_if internal Spectral data on success, NULL on
* failure
*/
static inline
struct target_if_spectral *get_target_if_spectral_handle_from_pdev(
struct wlan_objmgr_pdev *pdev)
{
struct target_if_spectral *spectral = NULL;
struct wlan_objmgr_psoc *psoc = NULL;
psoc = wlan_pdev_get_psoc(pdev);
spectral = (struct target_if_spectral *)
psoc->soc_cb.rx_ops.sptrl_rx_ops.sptrlro_get_target_handle(
pdev);
return spectral;
}
/**
* target_if_spectral_set_rxchainmask() - Set Spectral Rx chainmask
* @pdev: Pointer to pdev
* @spectral_rx_chainmask: Spectral Rx chainmask
*
* Return: None
*/
static inline
void target_if_spectral_set_rxchainmask(struct wlan_objmgr_pdev *pdev,
u_int8_t spectral_rx_chainmask)
{
struct target_if_spectral *spectral = NULL;
spectral = get_target_if_spectral_handle_from_pdev(pdev);
spectral->params.ss_chn_mask = spectral_rx_chainmask;
}
/**
* target_if_spectral_process_phyerr() - Process Spectral PHY error
* @pdev: Pointer to pdev
* @data: PHY error data received from FW
* @datalen: Length of data
* @p_rfqual: Pointer to RF Quality information
* @p_chaninfo: Pointer to channel information
* @tsf: TSF time instance at which the Spectral sample was received
* @acs_stats: ACS stats
*
* Process Spectral PHY error by extracting necessary information from the data
* sent by FW, and send the extracted information to application layer.
*
* Return: None
*/
static inline
void target_if_spectral_process_phyerr(
struct wlan_objmgr_pdev *pdev,
u_int8_t *data, u_int32_t datalen,
struct target_if_spectral_rfqual_info *p_rfqual,
struct target_if_spectral_chan_info *p_chaninfo,
u_int64_t tsf64,
struct target_if_spectral_acs_stats *acs_stats)
{
struct target_if_spectral *spectral = NULL;
struct target_if_spectral_ops *p_sops = NULL;
spectral = get_target_if_spectral_handle_from_pdev(pdev);
p_sops = GET_TIF_SPECTRAL_OPS(spectral);
p_sops->spectral_process_phyerr(spectral, data, datalen,
p_rfqual, p_chaninfo,
tsf64, acs_stats);
}
#ifdef WIN32
#pragma pack(pop, target_if_spectral)
#endif
#ifdef __ATTRIB_PACK
#undef __ATTRIB_PACK
#endif
#endif /* _TARGET_IF_SPECTRAL_H_ */

View File

@@ -0,0 +1,590 @@
/*
* Copyright (c) 2011,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <osdep.h>
#include <wlan_tgt_def_config.h>
#include <hif.h>
#include <hif_hw_version.h>
#include <wmi_unified_api.h>
#include <target_if_spectral.h>
#include <wlan_lmac_if_def.h>
#include <wlan_osif_priv.h>
#ifdef HOST_OFFLOAD
extern void
atd_spectral_msg_send(
struct net_device *dev,
SPECTRAL_SAMP_MSG *msg,
uint16_t msg_len);
#endif
#ifdef SPECTRAL_USE_NETLINK_SOCKETS
struct sock *target_if_spectral_nl_sock;
static atomic_t spectral_nl_users = ATOMIC_INIT(0);
#if (KERNEL_VERSION(2, 6, 31) > LINUX_VERSION_CODE)
void target_if_spectral_nl_data_ready(struct sock *sk, int len)
{
qdf_print("%s %d\n", __func__, __LINE__);
}
#else
void target_if_spectral_nl_data_ready(struct sk_buff *skb)
{
qdf_print("%s %d\n", __func__, __LINE__);
}
#endif /* VERSION */
int target_if_spectral_init_netlink(struct target_if_spectral *spectral)
{
#if KERNEL_VERSION(3, 6, 0) <= LINUX_VERSION_CODE
struct netlink_kernel_cfg cfg = {
.groups = 1,
.input = target_if_spectral_nl_data_ready,
};
#endif
if (!spectral) {
qdf_print("%s: sc_spectral is NULL\n", __func__);
return -EIO;
}
spectral->spectral_sent_msg = 0;
if (!target_if_spectral_nl_sock) {
#if KERNEL_VERSION(3, 7, 0) <= LINUX_VERSION_CODE
target_if_spectral_nl_sock = (struct sock *)netlink_kernel_create(
&init_net,
NETLINK_ATHEROS,
&cfg);
#elif KERNEL_VERSION(3, 6, 0) <= LINUX_VERSION_CODE
target_if_spectral_nl_sock = (struct sock *)netlink_kernel_create(
&init_net,
NETLINK_ATHEROS,
THIS_MODULE,
&cfg);
#elif (KERNEL_VERSION(2, 6, 31) > LINUX_VERSION_CODE)
target_if_spectral_nl_sock = (
struct sock *)netlink_kernel_create(NETLINK_ATHEROS,
1,
&target_if_spectral_nl_data_ready,
THIS_MODULE);
#else
#if (KERNEL_VERSION(3, 10, 0) <= LINUX_VERSION_CODE)
struct netlink_kernel_cfg cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.groups = 1;
cfg.input = &target_if_spectral_nl_data_ready;
target_if_spectral_nl_sock = (struct sock *)netlink_kernel_create(
&init_net, NETLINK_ATHEROS, &cfg);
#else
target_if_spectral_nl_sock = (struct sock *)netlink_kernel_create(
&init_net,
NETLINK_ATHEROS,
1,
&target_if_spectral_nl_data_ready,
NULL,
THIS_MODULE);
#endif
#endif
if (!target_if_spectral_nl_sock) {
qdf_print("%s NETLINK_KERNEL_CREATE FAILED\n", __func__);
return -ENODEV;
}
}
atomic_inc(&spectral_nl_users);
spectral->spectral_sock = target_if_spectral_nl_sock;
if ((!spectral) || (!spectral->spectral_sock)) {
qdf_print("%s NULL pointers (spectral=%d) (sock=%d)\n",
__func__, (!spectral), (!spectral->spectral_sock));
return -ENODEV;
}
if (!spectral->spectral_skb)
qdf_print(KERN_ERR "%s %d NULL SKB\n", __func__, __LINE__);
return 0;
}
int target_if_spectral_destroy_netlink(struct target_if_spectral *spectral)
{
spectral->spectral_sock = NULL;
if (atomic_dec_and_test(&spectral_nl_users)) {
sock_release(target_if_spectral_nl_sock->sk_socket);
target_if_spectral_nl_sock = NULL;
}
return 0;
}
#endif /* SPECTRAL_USE_NETLINK_SOCKETS */
static void spectral_process_noise_pwr_report(
struct target_if_spectral *spectral,
const SPECTRAL_SAMP_MSG *spec_samp_msg)
{
int i, done;
/*
* qdf_print(
* "%s: #%d/%d datalen=%d tstamp=%x last_tstamp=%x "
* "rssi=%d nb_lower=%d peak=%d\n",
* __func__, spectral->noise_pwr_reports_recv,
* spectral->noise_pwr_reports_reqd,
* spec_samp_msg->samp_data.spectral_data_len,
* spec_samp_msg->samp_data.spectral_tstamp,
* spec_samp_msg->samp_data.spectral_last_tstamp,
* spec_samp_msg->samp_data.spectral_lower_rssi,
* spec_samp_msg->samp_data.spectral_nb_lower,
* spec_samp_msg->samp_data.spectral_lower_max_index);
*/
qdf_spin_lock(&spectral->noise_pwr_reports_lock);
if (!spectral->noise_pwr_reports_reqd) {
qdf_spin_unlock(&spectral->noise_pwr_reports_lock);
return;
}
if (spectral->noise_pwr_reports_recv <
spectral->noise_pwr_reports_reqd) {
spectral->noise_pwr_reports_recv++;
/*
* qdf_print(
* "#%d/%d: rssi=%3d,%3d,%3d %3d,%3d,%3d\n",
* spectral->noise_pwr_reports_recv,
* spectral->noise_pwr_reports_reqd,
* spec_samp_msg->samp_data.spectral_chain_ctl_rssi[0],
* spec_samp_msg->samp_data.spectral_chain_ctl_rssi[1],
* spec_samp_msg->samp_data.spectral_chain_ctl_rssi[2],
* spec_samp_msg->samp_data.spectral_chain_ext_rssi[0],
* spec_samp_msg->samp_data.spectral_chain_ext_rssi[1],
* spec_samp_msg->samp_data.spectral_chain_ext_rssi[2]);
*/
for (i = 0; i < ATH_HOST_MAX_ANTENNA; i++) {
uint32_t index;
if (spectral->noise_pwr_chain_ctl[i]) {
index = spectral->noise_pwr_chain_ctl[i]->rptcount++;
spectral->noise_pwr_chain_ctl[i]->pwr[index] =
spec_samp_msg->samp_data.spectral_chain_ctl_rssi[i];
}
if (spectral->noise_pwr_chain_ext[i]) {
index = spectral->noise_pwr_chain_ext[i]->rptcount++;
spectral->noise_pwr_chain_ext[i]->pwr[index] =
spec_samp_msg->samp_data.spectral_chain_ext_rssi[i];
}
}
}
done = (spectral->noise_pwr_reports_recv >=
spectral->noise_pwr_reports_reqd);
qdf_spin_unlock(&spectral->noise_pwr_reports_lock);
if (done) {
qdf_spin_lock(&spectral->ath_spectral_lock);
target_if_stop_spectral_scan(spectral->pdev_obj);
spectral->sc_spectral_scan = 0;
qdf_spin_unlock(&spectral->ath_spectral_lock);
/*
* qdf_print(
* "%s: done: %d/%d recv - set sc_spectral_scan = 0\n",
* __func__, spectral->noise_pwr_reports_recv,
* spectral->noise_pwr_reports_reqd);
*/
}
}
/*
* Function : spectral_create_samp_msg
* Description : create SAMP message and send it host
* Input :
* Output :
*
*/
void target_if_spectral_create_samp_msg(
struct target_if_spectral *spectral,
struct target_if_samp_msg_params *params)
{
/*
* XXX : Non-Rentrant. Will be an issue with dual concurrent
* operation on multi-processor system
*/
int temp_samp_msg_len = 0;
static SPECTRAL_SAMP_MSG spec_samp_msg;
SPECTRAL_SAMP_MSG *msg = NULL;
SPECTRAL_SAMP_DATA *data = NULL;
u_int8_t *bin_pwr_data = NULL;
SPECTRAL_CLASSIFIER_PARAMS *cp = NULL;
SPECTRAL_CLASSIFIER_PARAMS *pcp = NULL;
struct target_if_spectral_ops *p_sops = NULL;
struct target_if_spectral_skb_event *sp_skb_event = NULL;
#ifdef SPECTRAL_USE_NETLINK_SOCKETS
static int samp_msg_index;
#endif
p_sops = GET_TIF_SPECTRAL_OPS(spectral);
temp_samp_msg_len = sizeof(SPECTRAL_SAMP_MSG) -
(MAX_NUM_BINS * sizeof(u_int8_t));
temp_samp_msg_len += (params->pwr_count * sizeof(u_int8_t));
if (spectral->ch_width == IEEE80211_CWM_WIDTH160)
temp_samp_msg_len +=
(params->pwr_count_sec80 * sizeof(u_int8_t));
bin_pwr_data = params->bin_pwr_data;
memset(&spec_samp_msg, 0, sizeof(SPECTRAL_SAMP_MSG));
data = &spec_samp_msg.samp_data;
spec_samp_msg.signature = SPECTRAL_SIGNATURE;
spec_samp_msg.freq = params->freq;
spec_samp_msg.freq_loading = params->freq_loading;
spec_samp_msg.samp_data.spectral_data_len = params->datalen;
spec_samp_msg.samp_data.spectral_rssi = params->rssi;
spec_samp_msg.samp_data.ch_width = spectral->ch_width;
spec_samp_msg.samp_data.spectral_combined_rssi =
(u_int8_t)params->rssi;
spec_samp_msg.samp_data.spectral_upper_rssi = params->upper_rssi;
spec_samp_msg.samp_data.spectral_lower_rssi = params->lower_rssi;
OS_MEMCPY(
spec_samp_msg.samp_data.spectral_chain_ctl_rssi,
params->chain_ctl_rssi,
sizeof(params->chain_ctl_rssi));
OS_MEMCPY(
spec_samp_msg.samp_data.spectral_chain_ext_rssi,
params->chain_ext_rssi,
sizeof(params->chain_ext_rssi));
spec_samp_msg.samp_data.spectral_bwinfo = params->bwinfo;
spec_samp_msg.samp_data.spectral_tstamp = params->tstamp;
spec_samp_msg.samp_data.spectral_max_index = params->max_index;
/* Classifier in user space needs access to these */
spec_samp_msg.samp_data.spectral_lower_max_index =
params->max_lower_index;
spec_samp_msg.samp_data.spectral_upper_max_index =
params->max_upper_index;
spec_samp_msg.samp_data.spectral_nb_lower =
params->nb_lower;
spec_samp_msg.samp_data.spectral_nb_upper = params->nb_upper;
spec_samp_msg.samp_data.spectral_last_tstamp =
params->last_tstamp;
spec_samp_msg.samp_data.spectral_max_mag = params->max_mag;
spec_samp_msg.samp_data.bin_pwr_count =
params->pwr_count;
spec_samp_msg.samp_data.lb_edge_extrabins =
spectral->lb_edge_extrabins;
spec_samp_msg.samp_data.rb_edge_extrabins =
spectral->rb_edge_extrabins;
spec_samp_msg.samp_data.spectral_combined_rssi = params->rssi;
spec_samp_msg.samp_data.spectral_max_scale = params->max_exp;
#ifdef SPECTRAL_USE_NETLINK_SOCKETS
/*
* This is a dirty hack to get the Windows build pass.
* Currently Windows and Linux builds source spectral_data.h
* form two different place. The windows version do not
* have noise_floor member in it.
*
* As a temp workaround this variable is set under the
* SPECTRAL_USE_NETLINK_SOCKETS as this is called only
* under the linux build and this saves the day
*
* The plan to sync of header files in under the way
*
*/
spec_samp_msg.samp_data.noise_floor = params->noise_floor;
#endif /* SPECTRAL_USE_NETLINK_SOCKETS */
/* Classifier in user space needs access to these */
cp = &spec_samp_msg.samp_data.classifier_params;
pcp = &params->classifier_params;
OS_MEMCPY(cp, pcp, sizeof(SPECTRAL_CLASSIFIER_PARAMS));
SPECTRAL_MSG_COPY_CHAR_ARRAY(
&data->bin_pwr[0],
bin_pwr_data,
params->pwr_count);
#ifdef SPECTRAL_USE_NETLINK_SOCKETS
spec_samp_msg.vhtop_ch_freq_seg1 =
params->vhtop_ch_freq_seg1;
spec_samp_msg.vhtop_ch_freq_seg2 =
params->vhtop_ch_freq_seg2;
if (spectral->ch_width == IEEE80211_CWM_WIDTH160) {
spec_samp_msg.samp_data.spectral_rssi_sec80 = params->rssi_sec80;
spec_samp_msg.samp_data.noise_floor_sec80 = params->noise_floor_sec80;
spec_samp_msg.samp_data.spectral_data_len_sec80 =
params->datalen_sec80;
spec_samp_msg.samp_data.spectral_max_index_sec80 =
params->max_index_sec80;
spec_samp_msg.samp_data.spectral_max_mag_sec80 =
params->max_mag_sec80;
spec_samp_msg.samp_data.bin_pwr_count_sec80 =
params->pwr_count_sec80;
SPECTRAL_MSG_COPY_CHAR_ARRAY(&data->bin_pwr_sec80[0],
(params->bin_pwr_data_sec80),
params->pwr_count_sec80);
/* Note: REVERSE_ORDER is not a known use case for secondary 80 data at
* this point.
*/
}
#endif /* SPECTRAL_USE_NETLINK_SOCKETS */
#ifdef SPECTRAL_CLASSIFIER_IN_KERNEL
if (params->interf_list.count)
OS_MEMCPY(
&data->interf_list,
&params->interf_list,
sizeof(struct INTERF_SRC_RSP));
else
#endif
data->interf_list.count = 0;
#ifdef SPECTRAL_USE_NETLINK_SOCKETS
target_if_spectral_prep_skb(spectral);
if (spectral->spectral_skb) {
p_sops->get_mac_address(spectral, spec_samp_msg.macaddr);
spectral->spectral_nlh =
(struct nlmsghdr *)spectral->spectral_skb->data;
memcpy(NLMSG_DATA(spectral->spectral_nlh),
&spec_samp_msg,
sizeof(SPECTRAL_SAMP_MSG));
msg = (SPECTRAL_SAMP_MSG *)NLMSG_DATA(spectral->spectral_nlh);
/* Broadcast spectral data only if it is a edma supported device */
if (!spectral->sc_spectral_non_edma)
target_if_spectral_bcast_msg(spectral);
samp_msg_index++;
}
/* Check if the device is non-edma and follow the required broadcast
* path if true
*/
if (spectral->sc_spectral_non_edma) {
/* Allocating memory for the queue entity to hold the spectral socket
* buffer
*/
sp_skb_event = (struct target_if_spectral_skb_event
*)qdf_mem_malloc(sizeof(struct target_if_spectral_skb_event));
if (sp_skb_event) {
OS_MEMZERO(
sp_skb_event,
sizeof(struct target_if_spectral_skb_event));
sp_skb_event->sp_skb = spectral->spectral_skb;
sp_skb_event->sp_nlh = spectral->spectral_nlh;
spectral->spectral_skb = NULL;
spectral->spectral_nlh = NULL;
/* Queue spectral socket buffers to be broadcasted outside irq
* lock
*/
qdf_spin_lock(&spectral->spectral_skbqlock);
STAILQ_INSERT_TAIL(
&spectral->spectral_skbq,
sp_skb_event,
spectral_skb_list);
qdf_spin_unlock(&spectral->spectral_skbqlock);
}
}
#else
/*
* call the indicate function to pass the data to the net layer
* Windows will pass to a spectral WIN32 service
*/
msg = (SPECTRAL_SAMP_MSG *)qdf_mem_malloc(sizeof(SPECTRAL_SAMP_MSG));
if (msg) {
OS_MEMCPY(msg, &spec_samp_msg, sizeof(SPECTRAL_SAMP_MSG));
ath_spectral_indicate(
params->sc,
(void *)msg,
sizeof(SPECTRAL_SAMP_MSG));
OS_FREE(msg);
msg = NULL;
} else {
qdf_print("No buffer\n");
}
#endif /* SPECTRAL_USE_NETLINK_SOCKETS */
#ifdef HOST_OFFLOAD
atd_spectral_msg_send(spectral->ic->ic_osdev->netdev,
&spec_samp_msg,
sizeof(SPECTRAL_SAMP_MSG));
#endif
if (spectral->sc_spectral_noise_pwr_cal)
spectral_process_noise_pwr_report(spectral, &spec_samp_msg);
}
#ifdef SPECTRAL_USE_NETLINK_SOCKETS
void target_if_spectral_prep_skb(struct target_if_spectral *spectral)
{
spectral->spectral_skb = dev_alloc_skb(MAX_SPECTRAL_PAYLOAD);
if (spectral->spectral_skb) {
skb_put(spectral->spectral_skb, MAX_SPECTRAL_PAYLOAD);
spectral->spectral_nlh =
(struct nlmsghdr *)spectral->spectral_skb->data;
OS_MEMZERO(spectral->spectral_nlh, sizeof(*spectral->spectral_nlh));
/* Possible bug that size of SPECTRAL_SAMP_MSG and SPECTRAL_MSG
* differ by 3 bytes so we miss 3 bytes
*/
spectral->spectral_nlh->nlmsg_len =
NLMSG_SPACE(sizeof(SPECTRAL_SAMP_MSG));
spectral->spectral_nlh->nlmsg_pid = 0;
spectral->spectral_nlh->nlmsg_flags = 0;
} else {
spectral->spectral_skb = NULL;
spectral->spectral_nlh = NULL;
}
}
void target_if_spectral_unicast_msg(struct target_if_spectral *spectral)
{
if (!spectral) {
qdf_print("%s Spectral is NULL\n", __func__);
return;
}
if (!spectral->spectral_sock) {
qdf_print("%s Spectral Socket is invalid\n", __func__);
dev_kfree_skb(spectral->spectral_skb);
spectral->spectral_skb = NULL;
return;
}
if (spectral->spectral_skb) {
#if (KERNEL_VERSION(2, 6, 31) > LINUX_VERSION_CODE)
NETLINK_CB(spectral->spectral_skb).dst_pid = spectral->spectral_pid;
#endif /* VERSION - field depracated by newer kernel */
#if KERNEL_VERSION(3, 7, 0) > LINUX_VERSION_CODE
NETLINK_CB(spectral->spectral_skb).pid = 0; /* from kernel */
#else
NETLINK_CB(spectral->spectral_skb).portid = 0; /* from kernel */
#endif
/* to mcast group 1<<0 */
NETLINK_CB(spectral->spectral_skb).dst_group = 0;
netlink_unicast(
spectral->spectral_sock,
spectral->spectral_skb,
spectral->spectral_pid,
MSG_DONTWAIT);
}
}
/*
* Function : target_if_spectral_bcast_msg
* Description : Passes the Spectral Message to Host
* Input : Pointer to spectral
* Output : Void
*
*/
void target_if_spectral_bcast_msg(struct target_if_spectral *spectral)
{
#if (KERNEL_VERSION(2, 6, 31) >= LINUX_VERSION_CODE)
fd_set write_set;
#endif
SPECTRAL_SAMP_MSG *msg = NULL;
struct nlmsghdr *nlh = NULL;
int status;
#if (KERNEL_VERSION(2, 6, 31) >= LINUX_VERSION_CODE)
FD_ZERO(&write_set);
#endif
if (!spectral)
return;
if (!spectral->spectral_sock) {
dev_kfree_skb(spectral->spectral_skb);
spectral->spectral_skb = NULL;
return;
}
if (!spectral->spectral_skb)
return;
nlh = (struct nlmsghdr *)spectral->spectral_skb->data;
msg = (SPECTRAL_SAMP_MSG *)NLMSG_DATA(spectral->spectral_nlh);
/* print_samp_msg (msg, sc); */
status = target_if_send_phydata(
spectral->pdev_obj,
spectral->spectral_sock,
spectral->spectral_skb);
if (status == 0)
spectral->spectral_sent_msg++;
/* netlink will have freed the skb */
if (spectral->spectral_skb)
spectral->spectral_skb = NULL;
}
void target_if_spectral_skb_dequeue(unsigned long data)
{
struct target_if_spectral *spectral =
(struct target_if_spectral *)data;
struct target_if_spectral_skb_event *sp_skb_event = NULL;
qdf_spin_lock(&spectral->spectral_skbqlock);
/* Deque all the spectral socket buffers queued */
while (!STAILQ_EMPTY(&spectral->spectral_skbq)) {
sp_skb_event = STAILQ_FIRST(&spectral->spectral_skbq);
if (sp_skb_event) {
spectral->spectral_skb = sp_skb_event->sp_skb;
spectral->spectral_nlh = sp_skb_event->sp_nlh;
STAILQ_REMOVE_HEAD(
&spectral->spectral_skbq,
spectral_skb_list);
qdf_spin_unlock(&spectral->spectral_skbqlock);
OS_FREE(sp_skb_event);
/* Broadcast spectral data after dequeing */
target_if_spectral_bcast_msg(spectral);
qdf_spin_lock(&spectral->spectral_skbqlock);
}
}
qdf_spin_unlock(&spectral->spectral_skbqlock);
}
#endif /* SPECTRAL_USE_NETLINK_SOCKETS */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,958 @@
/*
* Copyright (c) 2015,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#if QCA_SUPPORT_SPECTRAL_SIMULATION
#include "target_if_spectral.h"
#include "target_if_spectral_sim.h"
#include "target_if_spectral_sim_int.h"
#include "_ieee80211.h"
#include "ieee80211_api.h"
#include "ieee80211_defines.h"
#include "qdf_types.h"
#include "ieee80211_var.h"
#include <wlan_mlme_dispatcher.h>
/* Helper functions */
int tif_populate_reportset_fromfile(ath_spectralsim_reportset * reportset,
enum phy_ch_width width,
bool is_80_80);
static int populate_report_static_gen2(ath_spectralsim_report *report,
enum phy_ch_width width,
bool is_80_80);
static int populate_report_static_gen3(ath_spectralsim_report *report,
enum phy_ch_width width,
bool is_80_80);
static void depopulate_report(ath_spectralsim_report *report);
static int populate_reportset_static(ath_spectralsim_context *simctx,
ath_spectralsim_reportset *reportset,
enum phy_ch_width width,
bool is_80_80);
static void depopulate_reportset(ath_spectralsim_reportset *reportset);
static int populate_simdata(ath_spectralsim_context *simctx);
static void depopulate_simdata(ath_spectralsim_context *simctx);
static OS_TIMER_FUNC(spectral_sim_phyerrdelivery_handler);
/* Static configuration.
* For now, we will be having a single configuration per BW, and a single
* report per configuration (since we need the data only for ensuring correct
* format handling).
*
* Extend this for more functionality if required in the future.
*/
/* Statically populate simulation data for one report. */
static int populate_report_static_gen2(ath_spectralsim_report *report,
enum phy_ch_width width,
bool is_80_80)
{
qdf_assert_always(report);
switch (width) {
case CH_WIDTH_20MHZ:
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_20_gen2));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate memory for "
"report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_20_gen2);
qdf_mem_copy(report->data,
reportdata_20_gen2, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_20, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_20, sizeof(report->chan_info));
break;
case CH_WIDTH_40MHZ:
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_40_gen2));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate memory for "
"report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_40_gen2);
qdf_mem_copy(report->data,
reportdata_40_gen2, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_40, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_40, sizeof(report->chan_info));
break;
case CH_WIDTH_80MHZ:
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_80_gen2));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate memory for "
"report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_80_gen2);
qdf_mem_copy(report->data,
reportdata_80_gen2, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_80, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_80, sizeof(report->chan_info));
break;
case CH_WIDTH_160MHZ:
if (is_80_80) {
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_80_80_gen2));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate "
"memory for report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_80_80_gen2);
qdf_mem_copy(report->data,
reportdata_80_80_gen2, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_80_80, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_80_80, sizeof(report->chan_info));
} else {
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_160_gen2));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate "
"memory for report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_160_gen2);
qdf_mem_copy(report->data,
reportdata_160_gen2, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_160, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_160, sizeof(report->chan_info));
}
break;
default:
qdf_print("Unhandled width. Please correct. Asserting\n");
qdf_assert_always(0);
}
return 0;
bad:
return -EPERM;
}
/* Statically populate simulation data for one report. */
static int populate_report_static_gen3(ath_spectralsim_report *report,
enum phy_ch_width width,
bool is_80_80)
{
qdf_assert_always(report);
switch (width) {
case CH_WIDTH_20MHZ:
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_20_gen3));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate "
"memory for report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_20_gen3);
qdf_mem_copy(report->data,
reportdata_20_gen3, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_20, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_20, sizeof(report->chan_info));
break;
case CH_WIDTH_40MHZ:
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_40_gen3));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate "
"memory for report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_40_gen3);
qdf_mem_copy(report->data,
reportdata_40_gen3, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_40, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_40, sizeof(report->chan_info));
break;
case CH_WIDTH_80MHZ:
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_80_gen3));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate memory for "
"report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_80_gen3);
qdf_mem_copy(report->data,
reportdata_80_gen3, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_80, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_80, sizeof(report->chan_info));
break;
case CH_WIDTH_160MHZ:
if (is_80_80) {
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_80_80_gen3));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate "
"memory for report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_80_80_gen3);
qdf_mem_copy(report->data,
reportdata_80_80_gen3, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_80_80, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_80_80, sizeof(report->chan_info));
} else {
report->data = NULL;
report->data = (u_int8_t *)
qdf_mem_malloc(sizeof(reportdata_160_gen3));
if (!report->data) {
qdf_print("Spectral simulation: Could not allocate "
"memory for report data\n");
goto bad;
}
report->datasize = sizeof(reportdata_160_gen3);
qdf_mem_copy(report->data,
reportdata_160_gen3, report->datasize);
qdf_mem_copy(&report->rfqual_info,
&rfqual_info_160, sizeof(report->rfqual_info));
qdf_mem_copy(&report->chan_info,
&chan_info_160, sizeof(report->chan_info));
}
break;
default:
qdf_print("Unhandled width. Please correct. Asserting\n");
qdf_assert_always(0);
}
return 0;
bad:
return -EPERM;
}
static void depopulate_report(ath_spectralsim_report *report)
{
if (!report)
return;
if (report->data) {
qdf_mem_free(report->data);
report->data = NULL;
report->datasize = 0;
}
}
/* Statically populate simulation data for a given configuration. */
static int populate_reportset_static(ath_spectralsim_context *simctx,
ath_spectralsim_reportset *reportset,
enum phy_ch_width width,
bool is_80_80)
{
int ret = 0;
ath_spectralsim_report *report = NULL;
qdf_assert_always(reportset);
reportset->headreport = NULL;
reportset->curr_report = NULL;
/* For now, we populate only one report */
report = (ath_spectralsim_report *)
qdf_mem_malloc(sizeof(ath_spectralsim_report));
if (!report) {
qdf_print("Spectral simulation: Could not allocate memory "
"for report.\n");
goto bad;
}
qdf_mem_zero(report, sizeof(*report));
switch (width) {
case CH_WIDTH_20MHZ:
qdf_mem_copy(&reportset->config,
&config_20_1, sizeof(reportset->config));
ret = simctx->populate_report_static(report, CH_WIDTH_20MHZ, 0);
if (ret != 0)
goto bad;
report->next = NULL;
reportset->headreport = report;
break;
case CH_WIDTH_40MHZ:
qdf_mem_copy(&reportset->config,
&config_40_1, sizeof(reportset->config));
ret = simctx->populate_report_static(report, CH_WIDTH_40MHZ, 0);
if (ret != 0)
goto bad;
report->next = NULL;
reportset->headreport = report;
break;
case CH_WIDTH_80MHZ:
qdf_mem_copy(&reportset->config,
&config_80_1, sizeof(reportset->config));
ret = simctx->populate_report_static(report, CH_WIDTH_80MHZ, 0);
if (ret != 0)
goto bad;
report->next = NULL;
reportset->headreport = report;
break;
case CH_WIDTH_160MHZ:
if (is_80_80) {
qdf_mem_copy(&reportset->config,
&config_80_80_1, sizeof(reportset->config));
ret = simctx->populate_report_static(
report,
CH_WIDTH_160MHZ,
1);
if (ret != 0)
goto bad;
report->next = NULL;
reportset->headreport = report;
} else {
qdf_mem_copy(&reportset->config,
&config_160_1, sizeof(reportset->config));
ret = simctx->populate_report_static(
report,
CH_WIDTH_160MHZ,
0);
if (ret != 0)
goto bad;
report->next = NULL;
reportset->headreport = report;
}
break;
default:
qdf_print("Unhandled width. Please rectify.\n");
qdf_assert_always(0);
};
reportset->curr_report = reportset->headreport;
return 0;
bad:
depopulate_reportset(reportset);
return -EPERM;
}
static void depopulate_reportset(ath_spectralsim_reportset *reportset)
{
ath_spectralsim_report *curr_report = NULL;
ath_spectralsim_report *next_report = NULL;
if (!reportset)
return;
curr_report = reportset->headreport;
while (curr_report) {
next_report = curr_report->next;
depopulate_report(curr_report);
qdf_mem_free(curr_report);
curr_report = next_report;
}
}
/* Populate simulation data for a given bandwidth by loading from a file.
* This is a place-holder only. To be implemented in the future on a need
* basis.
*
* A different file per bandwidth is suggested for better segregation of data
* sets (since data is likely to be very different across BWs).
*/
int tif_populate_reportset_fromfile(ath_spectralsim_reportset *reportset,
enum phy_ch_width width,
bool is_80_80)
{
qdf_print("%s: To be implemented if required\n", __func__);
return 0;
}
/* Populate simulation data */
static int populate_simdata(ath_spectralsim_context *simctx)
{
/* For now, we use static population. Switch to loading from a file if
* needed in the future.
*/
simctx->bw20_headreportset = NULL;
SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
simctx->bw20_headreportset,
CH_WIDTH_20MHZ,
0);
simctx->bw40_headreportset = NULL;
SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
simctx->bw40_headreportset,
CH_WIDTH_40MHZ,
0);
simctx->bw80_headreportset = NULL;
SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
simctx->bw80_headreportset,
CH_WIDTH_80MHZ,
0);
simctx->bw160_headreportset = NULL;
SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
simctx->bw160_headreportset,
CH_WIDTH_160MHZ,
0);
simctx->bw80_80_headreportset = NULL;
SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
simctx->bw80_80_headreportset,
CH_WIDTH_160MHZ,
1);
simctx->curr_reportset = NULL;
simctx->is_enabled = false;
simctx->is_active = false;
simctx->ssim_starting_tsf64 = 0;
simctx->ssim_count = 0;
simctx->ssim_period_ms = 0;
return 0;
}
static void depopulate_simdata(ath_spectralsim_context *simctx)
{
if (!simctx)
return;
SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw20_headreportset);
SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw40_headreportset);
SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw80_headreportset);
SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw160_headreportset);
SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw80_80_headreportset);
}
static
OS_TIMER_FUNC(spectral_sim_phyerrdelivery_handler)
{
struct target_if_spectral *spectral = NULL;
ath_spectralsim_context *simctx = NULL;
ath_spectralsim_reportset *curr_reportset = NULL;
ath_spectralsim_report *curr_report = NULL;
struct target_if_spectral_acs_stats acs_stats;
u_int64_t curr_tsf64 = 0;
struct target_if_spectral_ops *p_sops;
OS_GET_TIMER_ARG(spectral, struct target_if_spectral *);
qdf_assert_always(spectral);
p_sops = GET_TIF_SPECTRAL_OPS(spectral);
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
if (!simctx->is_active)
return;
curr_reportset = simctx->curr_reportset;
qdf_assert_always(curr_reportset);
curr_report = curr_reportset->curr_report;
qdf_assert_always(curr_report);
qdf_assert_always(curr_reportset->headreport);
/* We use a simulation TSF since in offload architectures we can't
* expect to
* get an accurate current TSF from HW.
* In case of TSF wrap over, we'll use it as-is for now since the
* simulation
* is intended only for format verification.
*/
curr_tsf64 = simctx->ssim_starting_tsf64 +
((simctx->ssim_period_ms * simctx->ssim_count) * 1000);
p_sops->spectral_process_phyerr(spectral,
curr_report->data,
curr_report->datasize,
&curr_report->rfqual_info,
&curr_report->chan_info,
curr_tsf64,
&acs_stats);
simctx->ssim_count++;
if (curr_report->next)
curr_reportset->curr_report = curr_report->next;
else
curr_reportset->curr_report = curr_reportset->headreport;
if (curr_reportset->config.ss_count != 0 &&
simctx->ssim_count == curr_reportset->config.ss_count) {
tif_spectral_sim_stop_spectral_scan(spectral);
} else {
qdf_timer_start(&simctx->ssim_pherrdelivery_timer,
simctx->ssim_period_ms);
}
}
/* Module services */
int target_if_spectral_sim_attach(struct target_if_spectral *spectral)
{
ath_spectralsim_context *simctx = NULL;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)
qdf_mem_malloc(sizeof(ath_spectralsim_context));
if (!simctx) {
qdf_print("Spectral simulation: Could not allocate memory for "
"context\n");
return -EPERM;
}
qdf_mem_zero(simctx, sizeof(*simctx));
spectral->simctx = simctx;
if (spectral->spectral_gen == SPECTRAL_GEN2)
simctx->populate_report_static = populate_report_static_gen2;
else if (spectral->spectral_gen == SPECTRAL_GEN3)
simctx->populate_report_static = populate_report_static_gen3;
if (populate_simdata(simctx) != 0) {
qdf_mem_free(simctx);
spectral->simctx = NULL;
qdf_print("Spectral simulation attach failed\n");
return -EPERM;
}
qdf_timer_init(NULL,
&simctx->ssim_pherrdelivery_timer,
spectral_sim_phyerrdelivery_handler,
(void *)(spectral),
QDF_TIMER_TYPE_WAKE_APPS);
qdf_print("Spectral simulation attached\n");
return 0;
}
void target_if_spectral_sim_detach(struct target_if_spectral *spectral)
{
ath_spectralsim_context *simctx = NULL;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
qdf_timer_free(&simctx->ssim_pherrdelivery_timer);
depopulate_simdata(simctx);
qdf_mem_free(simctx);
spectral->simctx = NULL;
qdf_print("Spectral simulation detached\n");
}
u_int32_t tif_spectral_sim_is_spectral_active(void *arg)
{
struct target_if_spectral *spectral = NULL;
ath_spectralsim_context *simctx = NULL;
spectral = (struct target_if_spectral *)arg;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
return simctx->is_active;
}
EXPORT_SYMBOL(tif_spectral_sim_is_spectral_active);
u_int32_t tif_spectral_sim_is_spectral_enabled(void *arg)
{
struct target_if_spectral *spectral = NULL;
ath_spectralsim_context *simctx = NULL;
spectral = (struct target_if_spectral *)arg;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
return simctx->is_enabled;
}
EXPORT_SYMBOL(tif_spectral_sim_is_spectral_enabled);
u_int32_t tif_spectral_sim_start_spectral_scan(void *arg)
{
struct target_if_spectral *spectral = NULL;
ath_spectralsim_context *simctx = NULL;
spectral = (struct target_if_spectral *)arg;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
if (!simctx->curr_reportset) {
qdf_print("Spectral simulation: No current report set "
"configured - unable to start simulated Spectral "
"scan\n");
return 0;
}
if (!simctx->curr_reportset->curr_report) {
qdf_print("Spectral simulation: No report data instances "
"populated - unable to start simulated Spectral "
"scan\n");
return 0;
}
if (!simctx->is_enabled)
simctx->is_enabled = true;
simctx->is_active = true;
/* Hardcoding current time as zero since it is simulation */
simctx->ssim_starting_tsf64 = 0;
simctx->ssim_count = 0;
/* TODO: Support high resolution timer in microseconds if required, so
* that
* we can support default periods such as ~200 us. For now, we use 1
* millisecond since the current use case for the simulation is to
* validate
* formats rather than have a time dependent classification.
*/
simctx->ssim_period_ms = 1;
qdf_timer_start(&simctx->ssim_pherrdelivery_timer,
simctx->ssim_period_ms);
return 1;
}
EXPORT_SYMBOL(tif_spectral_sim_start_spectral_scan);
u_int32_t tif_spectral_sim_stop_spectral_scan(void *arg)
{
struct target_if_spectral *spectral = NULL;
ath_spectralsim_context *simctx = NULL;
spectral = (struct target_if_spectral *)arg;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
qdf_timer_stop(&simctx->ssim_pherrdelivery_timer);
simctx->is_active = false;
simctx->is_enabled = false;
simctx->ssim_starting_tsf64 = 0;
simctx->ssim_count = 0;
simctx->ssim_period_ms = 0;
return 1;
}
EXPORT_SYMBOL(tif_spectral_sim_stop_spectral_scan);
u_int32_t tif_spectral_sim_configure_params(
void *arg,
struct spectral_config *params)
{
struct target_if_spectral *spectral = NULL;
ath_spectralsim_context *simctx = NULL;
enum wlan_phymode phymode;
u_int8_t bw;
ath_spectralsim_reportset *des_headreportset = NULL;
ath_spectralsim_reportset *temp_reportset = NULL;
bool is_invalid_width = false;
struct wlan_objmgr_vdev *vdev = NULL;
qdf_assert_always(params);
#ifdef SPECTRAL_SIM_DUMP_PARAM_DATA
{
int i = 0;
qdf_print("\n");
qdf_print("Spectral simulation: Param data dump:\n"
"ss_fft_period=%hu\n"
"ss_period=%hu\n"
"ss_count=%hu\n"
"ss_short_report=%hu\n"
"radar_bin_thresh_sel=%hhu\n"
"ss_spectral_pri=%hu\n"
"ss_fft_size=%hu\n"
"ss_gc_ena=%hu\n"
"ss_restart_ena=%hu\n"
"ss_noise_floor_ref=%hu\n"
"ss_init_delay=%hu\n"
"ss_nb_tone_thr=%hu\n"
"ss_str_bin_thr=%hu\n"
"ss_wb_rpt_mode=%hu\n"
"ss_rssi_rpt_mode=%hu\n"
"ss_rssi_thr=%hu\n"
"ss_pwr_format=%hu\n"
"ss_rpt_mode=%hu\n"
"ss_bin_scale=%hu\n"
"ss_dBm_adj=%hu\n"
"ss_chn_mask=%hu\n"
"ss_nf_temp_data=%d\n",
params->ss_fft_period,
params->ss_period,
params->ss_count,
params->ss_short_report,
params->radar_bin_thresh_sel,
params->ss_spectral_pri,
params->ss_fft_size,
params->ss_gc_ena,
params->ss_restart_ena,
params->ss_noise_floor_ref,
params->ss_init_delay,
params->ss_nb_tone_thr,
params->ss_str_bin_thr,
params->ss_wb_rpt_mode,
params->ss_rssi_rpt_mode,
params->ss_rssi_thr,
params->ss_pwr_format,
params->ss_rpt_mode,
params->ss_bin_scale,
params->ss_dBm_adj,
params->ss_chn_mask,
params->ss_nf_temp_data);
for (i = 0; i < AH_MAX_CHAINS * 2; i++)
qdf_print("ss_nf_cal[%d]=%hhd\n", i, params->ss_nf_cal[i]);
for (i = 0; i < AH_MAX_CHAINS * 2; i++)
qdf_print("ss_nf_pwr[%d]=%hhd\n", i, params->ss_nf_pwr[i]);
qdf_print("\n");
}
#endif /* SPECTRAL_SIM_DUMP_PARAM_DATA */
spectral = (struct target_if_spectral *)arg;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
vdev = target_if_spectral_get_vdev(spectral);
if (!vdev) {
qdf_print("Spectral simulation: No VAPs found - not proceeding"
" with param config.\n");
return 0;
}
bw = wlan_vdev_get_ch_width(vdev);
switch (bw) {
case CH_WIDTH_20MHZ:
des_headreportset = simctx->bw20_headreportset;
break;
case CH_WIDTH_40MHZ:
des_headreportset = simctx->bw40_headreportset;
break;
case CH_WIDTH_80MHZ:
des_headreportset = simctx->bw80_headreportset;
break;
case CH_WIDTH_160MHZ:
phymode = wlan_vdev_get_phymode(vdev);
if (phymode == WLAN_PHYMODE_11AC_VHT160) {
des_headreportset = simctx->bw160_headreportset;
} else if (phymode == WLAN_PHYMODE_11AC_VHT80_80) {
des_headreportset = simctx->bw80_80_headreportset;
} else {
qdf_print("Spectral simulation: Unexpected PHY mode %u"
" found for width 160 MHz...asserting.\n",
phymode);
qdf_assert_always(0);
}
break;
case IEEE80211_CWM_WIDTHINVALID:
qdf_print("Spectral simulation: Invalid width configured - not"
" proceeding with param config.\n");
is_invalid_width = true;
default:
qdf_print("Spectral simulation: Unknown width %u...asserting\n"
, bw);
qdf_assert_always(0);
break;
}
wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
if (is_invalid_width)
return 0;
if (!des_headreportset) {
qdf_print("Spectral simulation: No simulation data present for"
" configured bandwidth/PHY mode - unable to proceed "
" with param config.\n");
return 0;
}
simctx->curr_reportset = NULL;
temp_reportset = des_headreportset;
while (temp_reportset) {
if (qdf_mem_cmp(&temp_reportset->config,
params, sizeof(struct spectral_config)) == 0) {
/* Found a matching config. We are done. */
simctx->curr_reportset = temp_reportset;
break;
}
temp_reportset = temp_reportset->next;
}
if (!simctx->curr_reportset) {
qdf_print("Spectral simulation: No simulation data present for"
" desired Spectral configuration - unable to proceed"
" with param config.\n");
return 0;
}
if (!simctx->curr_reportset->curr_report) {
qdf_print("Spectral simulation: No report data instances "
"populated for desired Spectral configuration - "
"unable to proceed with param config\n");
return 0;
}
return 1;
}
EXPORT_SYMBOL(tif_spectral_sim_configure_params);
u_int32_t tif_spectral_sim_get_params(
void *arg,
struct spectral_config *params)
{
struct target_if_spectral *spectral = NULL;
ath_spectralsim_context *simctx = NULL;
qdf_assert_always(params);
spectral = (struct target_if_spectral *)arg;
qdf_assert_always(spectral);
simctx = (ath_spectralsim_context *)spectral->simctx;
qdf_assert_always(simctx);
if (!simctx->curr_reportset) {
qdf_print("Spectral simulation: No configured reportset found.\n");
return 0;
}
qdf_mem_copy(params, &simctx->curr_reportset->config, sizeof(*params));
return 1;
}
EXPORT_SYMBOL(tif_spectral_sim_get_params);
#endif /* QCA_SUPPORT_SPECTRAL_SIMULATION */

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2015,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SPECTRAL_SIM_H_
#define _SPECTRAL_SIM_H_
#if QCA_SUPPORT_SPECTRAL_SIMULATION
#include "target_if_spectral.h"
/**
* @brief Initialize Spectral Simulation functionality
* @details
* Setup data structures to be used for serving out data corresponding to
* various bandwidths and configurations.
*
* @param spectral - ath_spectral structure
* @return Integer status value. 0:Success, -1:Failure
*/
int target_if_spectral_sim_attach(struct target_if_spectral *spectral);
/**
* @brief De-initialize Spectral Simulation functionality
* @details
* Free up data structures used for serving out data corresponding to various
* bandwidths and configurations.
*
* @param spectral - ath_spectral structure
*/
void target_if_spectral_sim_detach(struct target_if_spectral *spectral);
/**
* @brief Check if Spectral (simulated) is active
*
* @param arg - pointer to ath_spectral structure
* @return Integer status value. 0: Not active, 1: Active
*/
u_int32_t tif_spectral_sim_is_spectral_active(void *arg);
/**
* @brief Check if Spectral (simulated) is enabled
*
* @param arg - pointer to ath_spectral structure
* @return Integer status value. 0: Not enabled, 1: Enabled
*/
u_int32_t tif_spectral_sim_is_spectral_enabled(void *arg);
/**
* @brief Start Spectral simulation
*
* @param arg - pointer to ath_spectral structure
* @return Integer status value. 0: Failure, 1: Success
*/
u_int32_t tif_spectral_sim_start_spectral_scan(void *arg);
/**
* @brief Stop Spectral simulation
*
* @param arg - pointer to ath_spectral structure
* @return Integer status value. 0: Failure, 1: Success
*/
u_int32_t tif_spectral_sim_stop_spectral_scan(void *arg);
/**
* @brief Configure Spectral parameters into simulation
* @details
* Internally, this function actually searches if a record set with the desired
* configuration has been loaded. If so, it points to the record set for
* later usage when the simulation is started. If not, it returns an error.
*
* @param arg - pointer to ath_spectral structure
* @param params - pointer to struct spectral_config structure bearing Spectral
* configuration
* @return Integer status value. 0: Failure, 1: Success
*/
u_int32_t tif_spectral_sim_configure_params(
void *arg,
struct spectral_config *params);
/**
* @brief Get Spectral parameters configured into simulation
*
* @param arg - pointer to ath_spectral structure
* @param params - pointer to struct spectral_config structure which should be
* populated with Spectral configuration
* @return Integer status value. 0: Failure, 1: Success
*/
u_int32_t tif_spectral_sim_get_params(
void *arg,
struct spectral_config *params);
#endif /* QCA_SUPPORT_SPECTRAL_SIMULATION */
#endif /* _SPECTRAL_SIM_H_ */

View File

@@ -0,0 +1,961 @@
/*
* Copyright (c) 2015,2017 The Linux Foundation. All rights reserved.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _SPECTRAL_SIM_INTERNAL_H_
#define _SPECTRAL_SIM_INTERNAL_H_
#if QCA_SUPPORT_SPECTRAL_SIMULATION
#include "target_if_spectral.h"
/* #define SPECTRAL_SIM_DUMP_PARAM_DATA 1 */
/* Spectral report data instance. Usable in a linked list.
* - In the case of Direct Attach chipsets, one instance should correspond to
* one PHY Data Error frame received from the HW.
* XXX Direct Attach support to be implemented if needed. Any modifications
* required here can be made at the time of implementation.
* - In the case of 802.11ac offload chipsets, one instance should correspond to
* one report received from HW, inclusive of all TLVs.
*/
typedef struct _ath_spectralsim_report {
/* 11ac onwards only */
struct target_if_spectral_rfqual_info rfqual_info;
/* 11ac onwards only */
struct target_if_spectral_chan_info chan_info;
u_int32_t datasize;
u_int8_t *data;
struct _ath_spectralsim_report *next;
} ath_spectralsim_report;
/* Set of Spectral report data instances corresponding to one particular
* configuration. Usable in a linked list.
*/
typedef struct _ath_spectralsim_reportset {
struct spectral_config config;
ath_spectralsim_report *headreport;
ath_spectralsim_report *curr_report;
struct _ath_spectralsim_reportset *next;
} ath_spectralsim_reportset;
/* Main structure for Spectral simulation. All data and controls get linked
* here.
*
* For each width (20/40/80/160/80+80), we will have a linked list of
* ath_spectralsim_reportset nodes. Each ath_spectralsim_reportset will have a
* linked list of ath_spectralsim_report nodes. When the user requests for a
* given PHY mode and Spectral configuration, we find the appropriate
* ath_spectralsim_reportset, and then serve ath_spectralsim_report instances
* from the linked list. If required report count is higher than size of linked
* list (or infinite), we repeatedly cycle through the linked list. There can
* be more elaborate data structures devised taking care of a large number of
* possibilities, but we stick to a simple scheme given limited simulation
* needs.
*/
typedef struct _ath_spectralsim_context {
ath_spectralsim_reportset *bw20_headreportset;
ath_spectralsim_reportset *bw40_headreportset;
ath_spectralsim_reportset *bw80_headreportset;
ath_spectralsim_reportset *bw160_headreportset;
ath_spectralsim_reportset *bw80_80_headreportset;
ath_spectralsim_reportset *curr_reportset;
bool is_enabled;
bool is_active;
qdf_timer_t ssim_pherrdelivery_timer;
u_int64_t ssim_starting_tsf64;
u_int32_t ssim_period_ms; /* TODO: Support in microseconds */
u_int32_t ssim_count;
int (*populate_report_static)(ath_spectralsim_report *report,
enum phy_ch_width width,
bool is_80_80);
} ath_spectralsim_context;
/* Helper Macros */
/* Allocate and populate reportset for a single configuration */
#define SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx, reportset, width, \
is_80_80) \
{ \
(reportset) = (ath_spectralsim_reportset *) \
qdf_mem_malloc(sizeof(ath_spectralsim_reportset)); \
\
if ((reportset) == NULL) { \
qdf_print("Spectral simulation: Could not allocate memory " \
"for report set\n"); \
depopulate_simdata((simctx)); \
return -EPERM; \
} \
\
qdf_mem_zero((reportset), sizeof(ath_spectralsim_reportset)); \
\
if (populate_reportset_static( \
(simctx), (reportset), (width), (is_80_80)) != 0) { \
depopulate_simdata((simctx)); \
return -EPERM; \
} \
\
(reportset)->next = NULL; \
}
/* Depopulate and free list of report sets */
#define SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(reportset) \
{ \
ath_spectralsim_reportset *curr_reportset = NULL; \
ath_spectralsim_reportset *next_reportset = NULL; \
\
curr_reportset = (reportset); \
\
while (curr_reportset) { \
next_reportset = curr_reportset->next; \
depopulate_reportset(curr_reportset); \
qdf_mem_free(curr_reportset); \
curr_reportset = next_reportset; \
} \
\
(reportset) = NULL; \
}
/* Values for static population */
/* 20 MHz */
static uint8_t reportdata_20_gen2[] = {
#ifdef BIG_ENDIAN_HOST
0xbb, /* Signature */
0xfb, /* Tag */
0x00, /* Size */
0x54,
0x2e, 0x60, 0x0f, 0xe8, /* FFT Summary A */
0x00, 0x00, 0x04, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#else
0x54, /* Length */
0x00,
0xfb, /* Tag */
0xbb, /* Signature */
0xe8, 0x0f, 0x60, 0x2e, /* FFT Summary A */
0x00, 0x04, 0x00, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 2, 0, 1, 1, 1, 0,
0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1,
1, 1, 0, 2, 1, 2, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0,
};
static uint8_t reportdata_20_gen3[] = {
#ifdef BIG_ENDIAN_HOST
0x12, 0x34, 0x56, 0x78, /* fft_timestamp */
0xfa, /* fft_hdr_sig */
0x03, /* fft_hdr_tag */
0x00, /* fft_hdr_length */
0x14,
0x0f, 0xf6, 0x00, 0xe0,
0x00, 0x00, 0x2f, 0xba,
0x20, 0xb4, 0x2c, 0x01,
0x00, 0x00, 0x00, 0x00, /* reserved */
#else
0x78, 0x56, 0x34, 0x12, /* fft_timestamp */
0x14, /* fft_hdr_length */
0x00,
0x03, /* fft_hdr_tag */
0xfa, /* fft_hdr_sig */
0xe0, 0x00, 0xf6, 0x0f,
0xba, 0x2f, 0x00, 0x00,
0x01, 0x2c, 0xb4, 0x20,
0x00, 0x00, 0x00, 0x00, /* reserved */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 2, 0, 1, 1, 1, 0,
0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1,
1, 1, 0, 2, 1, 2, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
};
static struct target_if_spectral_rfqual_info rfqual_info_20 = {
.rssi_comb = 1,
.pc_rssi_info[0].rssi_pri20 = 1,
.pc_rssi_info[0].rssi_sec20 = 128,
.pc_rssi_info[0].rssi_sec40 = 128,
.pc_rssi_info[0].rssi_sec80 = 128,
.pc_rssi_info[1].rssi_pri20 = 128,
.pc_rssi_info[1].rssi_sec20 = 128,
.pc_rssi_info[1].rssi_sec40 = 128,
.pc_rssi_info[1].rssi_sec80 = 128,
.pc_rssi_info[2].rssi_pri20 = 128,
.pc_rssi_info[2].rssi_sec20 = 128,
.pc_rssi_info[2].rssi_sec40 = 128,
.pc_rssi_info[2].rssi_sec80 = 128,
.pc_rssi_info[3].rssi_pri20 = 128,
.pc_rssi_info[3].rssi_sec20 = 128,
.pc_rssi_info[3].rssi_sec40 = 128,
.pc_rssi_info[3].rssi_sec80 = 128,
.noise_floor[0] = -90,
.noise_floor[1] = -90,
.noise_floor[2] = -90,
.noise_floor[3] = -90,
};
static struct target_if_spectral_chan_info chan_info_20 = {
.center_freq1 = 5180,
.center_freq2 = 0,
.chan_width = 20,
};
static struct spectral_config config_20_1 = {
.ss_fft_period = 1,
.ss_period = 35,
.ss_count = 0,
.ss_short_report = 1,
.radar_bin_thresh_sel = 0,
.ss_spectral_pri = 1,
.ss_fft_size = 7,
.ss_gc_ena = 1,
.ss_restart_ena = 0,
.ss_noise_floor_ref = 65440,
.ss_init_delay = 80,
.ss_nb_tone_thr = 12,
.ss_str_bin_thr = 8,
.ss_wb_rpt_mode = 0,
.ss_rssi_rpt_mode = 0,
.ss_rssi_thr = 240,
.ss_pwr_format = 0,
.ss_rpt_mode = 2,
.ss_bin_scale = 1,
.ss_dBm_adj = 1,
.ss_chn_mask = 1,
.ss_nf_cal[0] = 0,
.ss_nf_cal[1] = 0,
.ss_nf_cal[2] = 0,
.ss_nf_cal[3] = 0,
.ss_nf_cal[4] = 0,
.ss_nf_cal[5] = 0,
.ss_nf_pwr[0] = 0,
.ss_nf_pwr[1] = 0,
.ss_nf_pwr[2] = 0,
.ss_nf_pwr[3] = 0,
.ss_nf_pwr[4] = 0,
.ss_nf_pwr[5] = 0,
.ss_nf_temp_data = 0,
};
/* 40 MHz */
static uint8_t reportdata_40_gen2[] = {
#ifdef BIG_ENDIAN_HOST
0xbb, /* Signature */
0xfb, /* Tag */
0x00, /* Size */
0x94,
0x2e, 0x61, 0x0f, 0x80, /* FFT Summary A */
0x00, 0x00, 0x06, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#else
0x94, /* Length */
0x00,
0xfb, /* Tag */
0xbb, /* Signature */
0x80, 0x0f, 0x61, 0x2e, /* FFT Summary A */
0x00, 0x06, 0x00, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1,
0, 0, 0, 1, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0,
1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
};
static uint8_t reportdata_40_gen3[] = {
#ifdef BIG_ENDIAN_HOST
0x12, 0x34, 0x56, 0x78, /* fft_timestamp */
0xfa, /* fft_hdr_sig */
0x03, /* fft_hdr_tag */
0x00, /* fft_hdr_length */
0x24,
0x0f, 0xf6, 0x00, 0xe0,
0x00, 0x00, 0x2f, 0xba,
0x20, 0xb4, 0x2c, 0x01,
0x00, 0x00, 0x00, 0x00, /* reserved */
#else
0x78, 0x56, 0x34, 0x12, /* fft_timestamp */
0x24, /* fft_hdr_length */
0x00,
0x03, /* fft_hdr_tag */
0xfa, /* fft_hdr_sig */
0xe0, 0x00, 0xf6, 0x0f,
0xba, 0x2f, 0x00, 0x00,
0x01, 0x2c, 0xb4, 0x20,
0x00, 0x00, 0x00, 0x00, /* reserved */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1,
0, 0, 0, 1, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0,
1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 0,
};
static struct target_if_spectral_rfqual_info rfqual_info_40 = {
.rssi_comb = 1,
.pc_rssi_info[0].rssi_pri20 = 1,
.pc_rssi_info[0].rssi_sec20 = 2,
.pc_rssi_info[0].rssi_sec40 = 128,
.pc_rssi_info[0].rssi_sec80 = 128,
.pc_rssi_info[1].rssi_pri20 = 128,
.pc_rssi_info[1].rssi_sec20 = 128,
.pc_rssi_info[1].rssi_sec40 = 128,
.pc_rssi_info[1].rssi_sec80 = 128,
.pc_rssi_info[2].rssi_pri20 = 128,
.pc_rssi_info[2].rssi_sec20 = 128,
.pc_rssi_info[2].rssi_sec40 = 128,
.pc_rssi_info[2].rssi_sec80 = 128,
.pc_rssi_info[3].rssi_pri20 = 128,
.pc_rssi_info[3].rssi_sec20 = 128,
.pc_rssi_info[3].rssi_sec40 = 128,
.pc_rssi_info[3].rssi_sec80 = 128,
.noise_floor[0] = -90,
.noise_floor[1] = -90,
.noise_floor[2] = -90,
.noise_floor[3] = -90,
};
static struct target_if_spectral_chan_info chan_info_40 = {
.center_freq1 = 5180,
.center_freq2 = 0,
.chan_width = 40,
};
static struct spectral_config config_40_1 = {
.ss_fft_period = 1,
.ss_period = 35,
.ss_count = 0,
.ss_short_report = 1,
.radar_bin_thresh_sel = 0,
.ss_spectral_pri = 1,
.ss_fft_size = 8,
.ss_gc_ena = 1,
.ss_restart_ena = 0,
.ss_noise_floor_ref = 65440,
.ss_init_delay = 80,
.ss_nb_tone_thr = 12,
.ss_str_bin_thr = 8,
.ss_wb_rpt_mode = 0,
.ss_rssi_rpt_mode = 0,
.ss_rssi_thr = 240,
.ss_pwr_format = 0,
.ss_rpt_mode = 2,
.ss_bin_scale = 1,
.ss_dBm_adj = 1,
.ss_chn_mask = 1,
.ss_nf_cal[0] = 0,
.ss_nf_cal[1] = 0,
.ss_nf_cal[2] = 0,
.ss_nf_cal[3] = 0,
.ss_nf_cal[4] = 0,
.ss_nf_cal[5] = 0,
.ss_nf_pwr[0] = 0,
.ss_nf_pwr[1] = 0,
.ss_nf_pwr[2] = 0,
.ss_nf_pwr[3] = 0,
.ss_nf_pwr[4] = 0,
.ss_nf_pwr[5] = 0,
.ss_nf_temp_data = 0,
};
/* 80 MHz */
static uint8_t reportdata_80_gen2[] = {
#ifdef BIG_ENDIAN_HOST
0xbb, /* Signature */
0xfb, /* Tag */
0x01, /* Size */
0x14,
0x19, 0xeb, 0x80, 0x40, /* FFT Summary A */
0x00, 0x00, 0x10, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#else
0x14, /* Length */
0x01,
0xfb, /* Tag */
0xbb, /* Signature */
0x40, 0x80, 0xeb, 0x19, /* FFT Summary A */
0x00, 0x10, 0x00, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static uint8_t reportdata_80_gen3[] = {
#ifdef BIG_ENDIAN_HOST
0x12, 0x34, 0x56, 0x78, /* fft_timestamp */
0xfa, /* fft_hdr_sig */
0x03, /* fft_hdr_tag */
0x00, /* fft_hdr_length */
0x44,
0x0f, 0xf6, 0x00, 0xe0,
0x00, 0x00, 0x2f, 0xba,
0x20, 0xb4, 0x2c, 0x01,
0x00, 0x00, 0x00, 0x00, /* reserved */
#else
0x78, 0x56, 0x34, 0x12, /* fft_timestamp */
0x44, /* fft_hdr_length */
0x00,
0x03, /* fft_hdr_tag */
0xfa, /* fft_hdr_sig */
0xe0, 0x00, 0xf6, 0x0f,
0xba, 0x2f, 0x00, 0x00,
0x01, 0x2c, 0xb4, 0x20,
0x00, 0x00, 0x00, 0x00, /* reserved */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static struct target_if_spectral_rfqual_info rfqual_info_80 = {
.rssi_comb = 16,
.pc_rssi_info[0].rssi_pri20 = 16,
.pc_rssi_info[0].rssi_sec20 = 17,
.pc_rssi_info[0].rssi_sec40 = 0,
.pc_rssi_info[0].rssi_sec80 = 128,
.pc_rssi_info[1].rssi_pri20 = 128,
.pc_rssi_info[1].rssi_sec20 = 128,
.pc_rssi_info[1].rssi_sec40 = 128,
.pc_rssi_info[1].rssi_sec80 = 128,
.pc_rssi_info[2].rssi_pri20 = 128,
.pc_rssi_info[2].rssi_sec20 = 128,
.pc_rssi_info[2].rssi_sec40 = 128,
.pc_rssi_info[2].rssi_sec80 = 128,
.pc_rssi_info[3].rssi_pri20 = 128,
.pc_rssi_info[3].rssi_sec20 = 128,
.pc_rssi_info[3].rssi_sec40 = 128,
.pc_rssi_info[3].rssi_sec80 = 128,
.noise_floor[0] = -90,
.noise_floor[1] = -90,
.noise_floor[2] = -90,
.noise_floor[3] = -90,
};
static struct target_if_spectral_chan_info chan_info_80 = {
.center_freq1 = 5210,
.center_freq2 = 0,
.chan_width = 80,
};
static struct spectral_config config_80_1 = {
.ss_fft_period = 1,
.ss_period = 35,
.ss_count = 0,
.ss_short_report = 1,
.radar_bin_thresh_sel = 0,
.ss_spectral_pri = 1,
.ss_fft_size = 9,
.ss_gc_ena = 1,
.ss_restart_ena = 0,
.ss_noise_floor_ref = 65440,
.ss_init_delay = 80,
.ss_nb_tone_thr = 12,
.ss_str_bin_thr = 8,
.ss_wb_rpt_mode = 0,
.ss_rssi_rpt_mode = 0,
.ss_rssi_thr = 240,
.ss_pwr_format = 0,
.ss_rpt_mode = 2,
.ss_bin_scale = 1,
.ss_dBm_adj = 1,
.ss_chn_mask = 1,
.ss_nf_cal[0] = 0,
.ss_nf_cal[1] = 0,
.ss_nf_cal[2] = 0,
.ss_nf_cal[3] = 0,
.ss_nf_cal[4] = 0,
.ss_nf_cal[5] = 0,
.ss_nf_pwr[0] = 0,
.ss_nf_pwr[1] = 0,
.ss_nf_pwr[2] = 0,
.ss_nf_pwr[3] = 0,
.ss_nf_pwr[4] = 0,
.ss_nf_pwr[5] = 0,
.ss_nf_temp_data = 0,
};
/* 160 MHz */
static uint8_t reportdata_160_gen2[] = {
/* Segment 1 */
#ifdef BIG_ENDIAN_HOST
0xbb, /* Signature */
0xfb, /* Tag */
0x01, /* Size */
0x14,
0x23, 0x66, 0x00, 0x40, /* FFT Summary A */
0x5c, 0x5c, 0x78, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#else
0x14, /* Length */
0x01,
0xfb, /* Tag */
0xbb, /* Signature */
0x40, 0x00, 0x66, 0x23, /* FFT Summary A */
0x00, 0x78, 0x5c, 0x5c, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 2, 4, 60, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
/* Segment 2 */
#ifdef BIG_ENDIAN_HOST
0xbb, /* Signature */
0xfb, /* Tag */
0x01, /* Size */
0x14,
0x23, 0x66, 0x00, 0x40, /* FFT Summary A */
0x5c, 0x5c, 0x78, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x01, /* Segment ID */
#else
0x14, /* Length */
0x01,
0xfb, /* Tag */
0xbb, /* Signature */
0x40, 0x00, 0x66, 0x23, /* FFT Summary A */
0x00, 0x78, 0x5c, 0x5c, /* FFT Summary B */
0x01, 0x00, 0x00, 0x00, /* Segment ID */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 2, 4, 60, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
};
static uint8_t reportdata_160_gen3[] = {
/* Segment 1 */
#ifdef BIG_ENDIAN_HOST
0x12, 0x34, 0x56, 0x78, /* fft_timestamp */
0xfa, /* fft_hdr_sig */
0x03, /* fft_hdr_tag */
0x00, /* fft_hdr_length */
0x44,
0x0f, 0xf6, 0x00, 0xe0,
0x00, 0x00, 0x2f, 0xba,
0x20, 0xb4, 0x2c, 0x01,
0x00, 0x00, 0x00, 0x00, /* reserved */
#else
0x78, 0x56, 0x34, 0x12, /* fft_timestamp */
0x44, /* fft_hdr_length */
0x00,
0x03, /* fft_hdr_tag */
0xfa, /* fft_hdr_sig */
0xe0, 0x00, 0xf6, 0x0f,
0xba, 0x2f, 0x00, 0x00,
0x01, 0x2c, 0xb4, 0x20,
0x00, 0x00, 0x00, 0x00, /* reserved */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 2, 4, 60, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* Segment 2 */
#ifdef BIG_ENDIAN_HOST
0x12, 0x34, 0x56, 0x78, /* fft_timestamp */
0xfa, /* fft_hdr_sig */
0x03, /* fft_hdr_tag */
0x00, /* fft_hdr_length */
0x44,
0x0f, 0xf6, 0x00, 0xe1,
0x00, 0x00, 0x2f, 0xba,
0x20, 0xb4, 0x2c, 0x01,
0x00, 0x00, 0x00, 0x00, /* reserved */
#else
0x78, 0x56, 0x34, 0x12, /* fft_timestamp */
0x44, /* fft_hdr_length */
0x00,
0x03, /* fft_hdr_tag */
0xfa, /* fft_hdr_sig */
0xe1, 0x00, 0xf6, 0x0f,
0xba, 0x2f, 0x00, 0x00,
0x01, 0x2c, 0xb4, 0x20,
0x00, 0x00, 0x00, 0x00, /* reserved */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 2, 4, 60, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static struct target_if_spectral_rfqual_info rfqual_info_160 = {
.rssi_comb = 3,
.pc_rssi_info[0].rssi_pri20 = 3,
.pc_rssi_info[0].rssi_sec20 = 12,
.pc_rssi_info[0].rssi_sec40 = 41,
.pc_rssi_info[0].rssi_sec80 = 128,
.pc_rssi_info[1].rssi_pri20 = 128,
.pc_rssi_info[1].rssi_sec20 = 128,
.pc_rssi_info[1].rssi_sec40 = 128,
.pc_rssi_info[1].rssi_sec80 = 128,
.pc_rssi_info[2].rssi_pri20 = 128,
.pc_rssi_info[2].rssi_sec20 = 128,
.pc_rssi_info[2].rssi_sec40 = 128,
.pc_rssi_info[2].rssi_sec80 = 128,
.pc_rssi_info[3].rssi_pri20 = 128,
.pc_rssi_info[3].rssi_sec20 = 128,
.pc_rssi_info[3].rssi_sec40 = 128,
.pc_rssi_info[3].rssi_sec80 = 128,
.noise_floor[0] = -90,
.noise_floor[1] = -90,
.noise_floor[2] = -90,
.noise_floor[3] = -90,
};
static struct target_if_spectral_chan_info chan_info_160 = {
.center_freq1 = 5250,
.center_freq2 = 0,
.chan_width = 160,
};
static struct spectral_config config_160_1 = {
.ss_fft_period = 1,
.ss_period = 35,
.ss_count = 0,
.ss_short_report = 1,
.radar_bin_thresh_sel = 0,
.ss_spectral_pri = 1,
.ss_fft_size = 9,
.ss_gc_ena = 1,
.ss_restart_ena = 0,
.ss_noise_floor_ref = 65440,
.ss_init_delay = 80,
.ss_nb_tone_thr = 12,
.ss_str_bin_thr = 8,
.ss_wb_rpt_mode = 0,
.ss_rssi_rpt_mode = 0,
.ss_rssi_thr = 240,
.ss_pwr_format = 0,
.ss_rpt_mode = 2,
.ss_bin_scale = 1,
.ss_dBm_adj = 1,
.ss_chn_mask = 1,
.ss_nf_cal[0] = 0,
.ss_nf_cal[1] = 0,
.ss_nf_cal[2] = 0,
.ss_nf_cal[3] = 0,
.ss_nf_cal[4] = 0,
.ss_nf_cal[5] = 0,
.ss_nf_pwr[0] = 0,
.ss_nf_pwr[1] = 0,
.ss_nf_pwr[2] = 0,
.ss_nf_pwr[3] = 0,
.ss_nf_pwr[4] = 0,
.ss_nf_pwr[5] = 0,
.ss_nf_temp_data = 0,
};
/* 80+80 MHz */
static uint8_t reportdata_80_80_gen2[] = {
/* Segment 1 */
#ifdef BIG_ENDIAN_HOST
0xbb, /* Signature */
0xfb, /* Tag */
0x01, /* Size */
0x14,
0x23, 0x66, 0x00, 0x40, /* FFT Summary A */
0x64, 0x64, 0x89, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#else
0x14, /* Length */
0x01,
0xfb, /* Tag */
0xbb, /* Signature */
0x40, 0x00, 0x66, 0x23, /* FFT Summary A */
0x00, 0x89, 0x64, 0x64, /* FFT Summary B */
0x00, 0x00, 0x00, 0x00, /* Segment ID */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 2, 6, 68, 5, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
/* Segment 2 */
#ifdef BIG_ENDIAN_HOST
0xbb, /* Signature */
0xfb, /* Tag */
0x01, /* Size */
0x14,
0x23, 0x66, 0x00, 0x40, /* FFT Summary A */
0x64, 0x64, 0x89, 0x00, /* FFT Summary B */
0x00, 0x00, 0x00, 0x01, /* Segment ID */
#else
0x14, /* Length */
0x01,
0xfb, /* Tag */
0xbb, /* Signature */
0x40, 0x00, 0x66, 0x23, /* FFT Summary A */
0x00, 0x89, 0x64, 0x64, /* FFT Summary B */
0x01, 0x00, 0x00, 0x00, /* Segment ID */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 2, 6, 68, 5, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
};
static uint8_t reportdata_80_80_gen3[] = {
/* Segment 1 */
#ifdef BIG_ENDIAN_HOST
0x12, 0x34, 0x56, 0x78, /* fft_timestamp */
0xfa, /* fft_hdr_sig */
0x03, /* fft_hdr_tag */
0x00, /* fft_hdr_length */
0x44,
0x0f, 0xf6, 0x00, 0xe0,
0x00, 0x00, 0x2f, 0xba,
0x20, 0xb4, 0x2c, 0x01,
0x00, 0x00, 0x00, 0x00, /* reserved */
#else
0x78, 0x56, 0x34, 0x12, /* fft_timestamp */
0x44, /* fft_hdr_length */
0x00,
0x03, /* fft_hdr_tag */
0xfa, /* fft_hdr_sig */
0xe0, 0x00, 0xf6, 0x0f,
0xba, 0x2f, 0x00, 0x00,
0x01, 0x2c, 0xb4, 0x20,
0x00, 0x00, 0x00, 0x00, /* reserved */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 2, 6, 68, 5, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* Segment 2 */
#ifdef BIG_ENDIAN_HOST
0x12, 0x34, 0x56, 0x78, /* fft_timestamp */
0xfa, /* fft_hdr_sig */
0x03, /* fft_hdr_tag */
0x00, /* fft_hdr_length */
0x44,
0x0f, 0xf6, 0x00, 0xe1,
0x00, 0x00, 0x2f, 0xba,
0x20, 0xb4, 0x2c, 0x01,
0x00, 0x00, 0x00, 0x00, /* reserved */
#else
0x78, 0x56, 0x34, 0x12, /* fft_timestamp */
0x44, /* fft_hdr_length */
0x00,
0x03, /* fft_hdr_tag */
0xfa, /* fft_hdr_sig */
0xe1, 0x00, 0xf6, 0x0f,
0xba, 0x2f, 0x00, 0x00,
0x01, 0x2c, 0xb4, 0x20,
0x00, 0x00, 0x00, 0x00, /* reserved */
#endif /* BIG_ENDIAN_HOST */
/* FFT Data */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 2, 6, 68, 5, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static struct target_if_spectral_rfqual_info rfqual_info_80_80 = {
.rssi_comb = 1,
.pc_rssi_info[0].rssi_pri20 = 1,
.pc_rssi_info[0].rssi_sec20 = 17,
.pc_rssi_info[0].rssi_sec40 = 40,
.pc_rssi_info[0].rssi_sec80 = 128,
.pc_rssi_info[1].rssi_pri20 = 128,
.pc_rssi_info[1].rssi_sec20 = 128,
.pc_rssi_info[1].rssi_sec40 = 128,
.pc_rssi_info[1].rssi_sec80 = 128,
.pc_rssi_info[2].rssi_pri20 = 128,
.pc_rssi_info[2].rssi_sec20 = 128,
.pc_rssi_info[2].rssi_sec40 = 128,
.pc_rssi_info[2].rssi_sec80 = 128,
.pc_rssi_info[3].rssi_pri20 = 128,
.pc_rssi_info[3].rssi_sec20 = 128,
.pc_rssi_info[3].rssi_sec40 = 128,
.pc_rssi_info[3].rssi_sec80 = 128,
.noise_floor[0] = -90,
.noise_floor[1] = -90,
.noise_floor[2] = -90,
.noise_floor[3] = -90,
};
static struct target_if_spectral_chan_info chan_info_80_80 = {
.center_freq1 = 5210,
.center_freq2 = 5530,
.chan_width = 160,
};
static struct spectral_config config_80_80_1 = {
.ss_fft_period = 1,
.ss_period = 35,
.ss_count = 0,
.ss_short_report = 1,
.radar_bin_thresh_sel = 0,
.ss_spectral_pri = 1,
.ss_fft_size = 9,
.ss_gc_ena = 1,
.ss_restart_ena = 0,
.ss_noise_floor_ref = 65440,
.ss_init_delay = 80,
.ss_nb_tone_thr = 12,
.ss_str_bin_thr = 8,
.ss_wb_rpt_mode = 0,
.ss_rssi_rpt_mode = 0,
.ss_rssi_thr = 240,
.ss_pwr_format = 0,
.ss_rpt_mode = 2,
.ss_bin_scale = 1,
.ss_dBm_adj = 1,
.ss_chn_mask = 1,
.ss_nf_cal[0] = 0,
.ss_nf_cal[1] = 0,
.ss_nf_cal[2] = 0,
.ss_nf_cal[3] = 0,
.ss_nf_cal[4] = 0,
.ss_nf_cal[5] = 0,
.ss_nf_pwr[0] = 0,
.ss_nf_pwr[1] = 0,
.ss_nf_pwr[2] = 0,
.ss_nf_pwr[3] = 0,
.ss_nf_pwr[4] = 0,
.ss_nf_pwr[5] = 0,
.ss_nf_temp_data = 0,
};
#endif /* QCA_SUPPORT_SPECTRAL_SIMULATION */
#endif /* _SPECTRAL_SIM_INTERNAL_H_ */