aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c')
-rw-r--r--sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c b/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
new file mode 100644
index 000000000000..df951c325312
--- /dev/null
+++ b/sys/dev/ath/ath_hal/ar5416/ar5416_spectral.c
@@ -0,0 +1,243 @@
+/*-
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2012 Qualcomm Atheros, 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 "opt_ah.h"
+
+#include "ah.h"
+#include "ah_internal.h"
+#include "ah_devid.h"
+#include "ah_desc.h" /* NB: for HAL_PHYERR* */
+
+#include "ar5416/ar5416.h"
+#include "ar5416/ar5416reg.h"
+#include "ar5416/ar5416phy.h"
+
+/*
+ * Default AR9280 spectral scan parameters
+ */
+#define AR5416_SPECTRAL_SCAN_ENA 0
+#define AR5416_SPECTRAL_SCAN_ACTIVE 0
+#define AR5416_SPECTRAL_SCAN_FFT_PERIOD 8
+#define AR5416_SPECTRAL_SCAN_PERIOD 1
+#define AR5416_SPECTRAL_SCAN_COUNT 16 //used to be 128
+#define AR5416_SPECTRAL_SCAN_SHORT_REPEAT 1
+
+/* constants */
+#define MAX_RADAR_RSSI_THRESH 0x3f
+#define MAX_RADAR_HEIGHT 0x3f
+#define ENABLE_ALL_PHYERR 0xffffffff
+
+static void ar5416DisableRadar(struct ath_hal *ah);
+static void ar5416PrepSpectralScan(struct ath_hal *ah);
+
+static void
+ar5416DisableRadar(struct ath_hal *ah)
+{
+ uint32_t val;
+
+ // Enable radar FFT
+ val = OS_REG_READ(ah, AR_PHY_RADAR_0);
+ val |= AR_PHY_RADAR_0_FFT_ENA;
+
+ // set radar detect thresholds to max to effectively disable radar
+ val &= ~AR_PHY_RADAR_0_RRSSI;
+ val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI);
+
+ val &= ~AR_PHY_RADAR_0_HEIGHT;
+ val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT);
+
+ val &= ~(AR_PHY_RADAR_0_ENA);
+ OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
+
+ // disable extension radar detect
+ val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
+ OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
+
+ val = OS_REG_READ(ah, AR_RX_FILTER);
+ val |= (1<<13);
+ OS_REG_WRITE(ah, AR_RX_FILTER, val);
+}
+
+static void
+ar5416PrepSpectralScan(struct ath_hal *ah)
+{
+
+ ar5416DisableRadar(ah);
+ OS_REG_WRITE(ah, AR_PHY_ERR, ENABLE_ALL_PHYERR);
+}
+
+void
+ar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
+{
+ uint32_t val;
+
+ ar5416PrepSpectralScan(ah);
+
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+ if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) {
+ val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD;
+ val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
+ }
+
+ if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
+ val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
+ val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
+ }
+
+ if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) {
+ val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD;
+ val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD);
+ }
+
+ /* This section is different for Kiwi and Merlin */
+ if (AR_SREV_MERLIN(ah) ) {
+ if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
+ val &= ~AR_PHY_SPECTRAL_SCAN_COUNT;
+ val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT);
+ }
+
+ if (ss->ss_short_report == AH_TRUE) {
+ val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
+ } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) {
+ val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
+ }
+ } else {
+ if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) {
+ /*
+ * In Merlin, for continuous scan, scan_count = 128.
+ * In case of Kiwi, this value should be 0
+ */
+ if (ss->ss_count == 128)
+ ss->ss_count = 0;
+ val &= ~AR_PHY_SPECTRAL_SCAN_COUNT_KIWI;
+ val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI);
+ }
+
+ if (ss->ss_short_report == AH_TRUE) {
+ val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
+ } else if (ss->ss_short_report != HAL_SPECTRAL_PARAM_NOVAL) {
+ val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
+ }
+
+ //Select the mask to be same as before
+ val |= AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT_KIWI;
+ }
+ // Enable spectral scan
+ OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENA);
+
+ ar5416GetSpectralParams(ah, ss);
+}
+
+/*
+ * Get the spectral parameter values and return them in the pe
+ * structure
+ */
+void
+ar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
+{
+ uint32_t val;
+
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+ ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
+ ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD);
+ if (AR_SREV_MERLIN(ah) ) {
+ ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT);
+ ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+ } else {
+ ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT_KIWI);
+ ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI);
+ }
+ val = OS_REG_READ(ah, AR_PHY_RADAR_1);
+ ss->radar_bin_thresh_sel = MS(val, AR_PHY_RADAR_1_BIN_THRESH_SELECT);
+}
+
+HAL_BOOL
+ar5416IsSpectralActive(struct ath_hal *ah)
+{
+ uint32_t val;
+
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+ return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE);
+}
+
+HAL_BOOL
+ar5416IsSpectralEnabled(struct ath_hal *ah)
+{
+ uint32_t val;
+
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+ return MS(val,AR_PHY_SPECTRAL_SCAN_ENA);
+}
+
+void
+ar5416StartSpectralScan(struct ath_hal *ah)
+{
+ uint32_t val;
+
+ ar5416PrepSpectralScan(ah);
+
+ // Activate spectral scan
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+ val |= AR_PHY_SPECTRAL_SCAN_ENA;
+ val |= AR_PHY_SPECTRAL_SCAN_ACTIVE;
+ OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+ val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG);
+ OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR);
+}
+
+void
+ar5416StopSpectralScan(struct ath_hal *ah)
+{
+ uint32_t val;
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+ // Deactivate spectral scan
+ val &= ~AR_PHY_SPECTRAL_SCAN_ENA;
+ val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE;
+ OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+ val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR);
+ OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val);
+}
+
+uint32_t
+ar5416GetSpectralConfig(struct ath_hal *ah)
+{
+ uint32_t val;
+
+ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+ return val;
+}
+
+void
+ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval)
+{
+ uint32_t curval;
+
+ ar5416PrepSpectralScan(ah);
+
+ curval = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);
+
+ if (restoreval != curval) {
+ restoreval |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
+ OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, restoreval);
+ }
+ return;
+}