2017-03-23 13:30:54

by Simon Wunderlich

[permalink] [raw]
Subject: [PATCH v2 0/3] Channels in licensed bands, noise floor override

This is the revised series for adding channels in licensed bands and the
noise floor override. Thanks for the previous discussions, I've adopted
suggestions from Zefir and Sebastian accordingly and rebased the series.

For more background info, please check the v1 series:

https://www.spinics.net/lists/linux-wireless/msg160266.html

Cheers,
Simon

Ben Greear (1):
ath9k: Support channels in licensed bands

Simon Wunderlich (2):
ath10k: add support for channels in licensed bands
ath9k: add noise floor override option

drivers/net/wireless/ath/ath10k/Kconfig | 20 +++++++++
drivers/net/wireless/ath/ath10k/core.h | 4 ++
drivers/net/wireless/ath/ath10k/mac.c | 10 +++++
drivers/net/wireless/ath/ath10k/wmi.c | 53 +++++++++++++++++-------
drivers/net/wireless/ath/ath9k/Kconfig | 20 +++++++++
drivers/net/wireless/ath/ath9k/calib.c | 5 ++-
drivers/net/wireless/ath/ath9k/common-init.c | 15 +++++++
drivers/net/wireless/ath/ath9k/debug.c | 62 ++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 5 +++
9 files changed, 177 insertions(+), 17 deletions(-)

--
2.11.0


2017-03-23 13:30:54

by Simon Wunderlich

[permalink] [raw]
Subject: [PATCH v2 2/3] ath10k: add support for channels in licensed bands

Many chips support channels in licensed bands. Add support for those,
along with a corresponding kernel config option to disable them by
default. Note that these channels are not selectable even if the
option has been compiled unless the user modifies the regulatory
database to explicitly enable the corresponding channels.

NOTE: These channels must not be used in most regulatory
domains unless you have a license from the FCC or similar!

This patch also re-introduces the phy_mode_to_band function to allow
selecting the band in a more clean way.

Signed-off-by: Simon Wunderlich <[email protected]>
Signed-off-by: Mathias Kretschmer <[email protected]>
---
Changes to PATCHv1:
* re-introduce and clean up phy to mode conversion (thanks Sebastian)
---
drivers/net/wireless/ath/ath10k/Kconfig | 20 +++++++++++++
drivers/net/wireless/ath/ath10k/core.h | 4 +++
drivers/net/wireless/ath/ath10k/mac.c | 10 +++++++
drivers/net/wireless/ath/ath10k/wmi.c | 53 +++++++++++++++++++++++----------
4 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
index b4241cf9b7ed..13a23ed33f91 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -53,3 +53,23 @@ config ATH10K_DFS_CERTIFIED
---help---
This option enables DFS support for initiating radiation on
ath10k.
+
+config ATH10K_LICENSED_CHAN
+ bool "Support channels in licensed bands"
+ depends on ATH10K && CFG80211_CERTIFICATION_ONUS
+ default n
+ ---help---
+ This option enables support for licensed channels on such as
+ 4.9 GHz (public safety).
+
+ These are PUBLIC SAFETY CHANNELS and MUST NOT BE USED in most
+ regulatory domains UNLESS YOU HAVE A FULL LICENSE for their use from
+ your local radio regulator, e.g. the FCC or equivalent. Using these
+ channels without proper authorisation may result in serious legal
+ consequences.
+
+ You will also have to build a regulatory database with these channels
+ enabled to actually use them.
+
+ If you are a distro kernel builder or have any doubt whatsoever about
+ your legal ability to use these channels, say N.
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index d4b9a0ec1bdc..7674641537b4 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -46,7 +46,11 @@
#define WMI_READY_TIMEOUT (5 * HZ)
#define ATH10K_FLUSH_TIMEOUT_HZ (5 * HZ)
#define ATH10K_CONNECTION_LOSS_HZ (3 * HZ)
+#ifdef CONFIG_ATH10K_LICENSED_CHAN
+#define ATH10K_NUM_CHANS 47
+#else
#define ATH10K_NUM_CHANS 40
+#endif

/* Antenna noise floor */
#define ATH10K_DEFAULT_NOISE_FLOOR -95
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index d60086cdc584..81848e0a3a5e 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7669,6 +7669,16 @@ static const struct ieee80211_channel ath10k_5ghz_channels[] = {
CHAN5G(161, 5805, 0),
CHAN5G(165, 5825, 0),
CHAN5G(169, 5845, 0),
+#ifdef CONFIG_ATH10K_LICENSED_CHAN
+ CHAN5G(184, 4920, 0),
+ CHAN5G(188, 4940, 0),
+ CHAN5G(192, 4960, 0),
+ CHAN5G(196, 4980, 0),
+ CHAN5G(8, 5040, 0),
+ CHAN5G(12, 5060, 0),
+ CHAN5G(16, 5080, 0),
+#endif
+
};

struct ath10k *ath10k_mac_create(size_t priv_size)
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 4e60caec7ab4..d78c778eae4c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2271,6 +2271,41 @@ static bool ath10k_wmi_rx_is_decrypted(struct ath10k *ar,
return true;
}

+static inline enum nl80211_band phy_mode_to_band(u32 phy_mode, u32 channel)
+{
+ enum nl80211_band band;
+
+ switch (phy_mode) {
+ case MODE_11A:
+ case MODE_11NA_HT20:
+ case MODE_11NA_HT40:
+ case MODE_11AC_VHT20:
+ case MODE_11AC_VHT40:
+ case MODE_11AC_VHT80:
+ band = NL80211_BAND_5GHZ;
+ break;
+ case MODE_11B:
+ /* Hardware can Rx CCK rates on 5GHz. In that case phy_mode is
+ * set to MODE_11B.
+ */
+ if (channel < 1 || channel > 14) {
+ band = NL80211_BAND_5GHZ;
+ break;
+ }
+ case MODE_11G:
+ case MODE_11GONLY:
+ case MODE_11NG_HT20:
+ case MODE_11NG_HT40:
+ case MODE_11AC_VHT20_2G:
+ case MODE_11AC_VHT40_2G:
+ case MODE_11AC_VHT80_2G:
+ default:
+ band = NL80211_BAND_2GHZ;
+ }
+
+ return band;
+}
+
int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
{
struct wmi_mgmt_rx_ev_arg arg = {};
@@ -2320,22 +2355,8 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
__le64_to_cpu(arg.ext_info.rx_mac_timestamp);
status->flag |= RX_FLAG_MACTIME_END;
}
- /* Hardware can Rx CCK rates on 5GHz. In that case phy_mode is set to
- * MODE_11B. This means phy_mode is not a reliable source for the band
- * of mgmt rx.
- */
- if (channel >= 1 && channel <= 14) {
- status->band = NL80211_BAND_2GHZ;
- } else if (channel >= 36 && channel <= 169) {
- status->band = NL80211_BAND_5GHZ;
- } else {
- /* Shouldn't happen unless list of advertised channels to
- * mac80211 has been changed.
- */
- WARN_ON_ONCE(1);
- dev_kfree_skb(skb);
- return 0;
- }
+
+ status->band = phy_mode_to_band(phy_mode, channel);

if (phy_mode == MODE_11B && status->band == NL80211_BAND_5GHZ)
ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n");
--
2.11.0

2017-03-23 13:30:54

by Simon Wunderlich

[permalink] [raw]
Subject: [PATCH v2 1/3] ath9k: Support channels in licensed bands

From: Ben Greear <[email protected]>

Many chips support channels in licensed bands. Add support for those,
along with a corresponding kernel config option to disable them by
default. Note that these channels are not selectable even if the
option has been compiled unless the user modifies the regulatory
database to explicitly enable the corresponding channels.

NOTE: These channels must not be used in most regulatory
domains unless you have a license from the FCC or similar!

Signed-off-by: Ben Greear <[email protected]>
[Hide this support behind a Kconfig option]
Signed-off-by: Julian Calaby <[email protected]>
[only use the 20 mhz channels, add 5 ghz, change to 4.9ghz to licensed bands, simplify]
Signed-off-by: Simon Wunderlich <[email protected]>
Signed-off-by: Mathias Kretschmer <[email protected]>
---
Changes to PATCHv1:
* fix bug reported by Zefir, and simplify patch more
---
drivers/net/wireless/ath/ath9k/Kconfig | 20 ++++++++++++++++++++
drivers/net/wireless/ath/ath9k/common-init.c | 15 +++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 4 ++++
3 files changed, 39 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 783a38f1a626..23b8abf4449a 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -116,6 +116,26 @@ config ATH9K_DFS_CERTIFIED
developed. At this point enabling this option won't do anything
except increase code size.

+config ATH9K_LICENSED_CHAN
+ bool "Support channels in licensed bands"
+ depends on ATH9K && CFG80211_CERTIFICATION_ONUS
+ default n
+ ---help---
+ This option enables support for licensed channels on such as
+ 4.9 GHz (public safety).
+
+ These are PUBLIC SAFETY CHANNELS and MUST NOT BE USED in most
+ regulatory domains UNLESS YOU HAVE A FULL LICENSE for their use from
+ your local radio regulator, e.g. the FCC or equivalent. Using these
+ channels without proper authorisation may result in serious legal
+ consequences.
+
+ You will also have to build a regulatory database with these channels
+ enabled to actually use them.
+
+ If you are a distro kernel builder or have any doubt whatsoever about
+ your legal ability to use these channels, say N.
+
config ATH9K_DYNACK
bool "Atheros ath9k ACK timeout estimation algorithm (EXPERIMENTAL)"
depends on ATH9K
diff --git a/drivers/net/wireless/ath/ath9k/common-init.c b/drivers/net/wireless/ath/ath9k/common-init.c
index 8b4f7fdabf58..3d65dce13048 100644
--- a/drivers/net/wireless/ath/ath9k/common-init.c
+++ b/drivers/net/wireless/ath/ath9k/common-init.c
@@ -86,6 +86,21 @@ static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
CHAN5G(5785, 35), /* Channel 157 */
CHAN5G(5805, 36), /* Channel 161 */
CHAN5G(5825, 37), /* Channel 165 */
+
+#ifdef CONFIG_ATH9K_LICENSED_CHAN
+ /* 4.9Ghz channels, public safety channels, license is required in US
+ * and most other regulatory domains!
+ */
+ /* 802.11j 4.9 GHz (20 MHz) */
+ CHAN5G(4920, 38), /* channel 184 */
+ CHAN5G(4940, 39), /* channel 188 */
+ CHAN5G(4960, 40), /* channel 192 */
+ CHAN5G(4980, 41), /* channel 196 */
+ /* 802.11j 5.030 - 5.080 GHz (20 MHz) */
+ CHAN5G(5040, 42), /* channel 8 */
+ CHAN5G(5060, 43), /* channel 12 */
+ CHAN5G(5080, 44), /* channel 16 */
+#endif
};

/* Atheros hardware rate code addition for short premble */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9cbca1229bac..2166f644599d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -73,7 +73,11 @@

#define ATH9K_RSSI_BAD -128

+#ifdef CONFIG_ATH9K_LICENSED_CHAN
+#define ATH9K_NUM_CHANNELS 45
+#else
#define ATH9K_NUM_CHANNELS 38
+#endif

/* Register read/write primitives */
#define REG_WRITE(_ah, _reg, _val) \
--
2.11.0

2017-03-23 13:30:55

by Simon Wunderlich

[permalink] [raw]
Subject: [PATCH v2 3/3] ath9k: add noise floor override option

Introduce a debugfs option to manually override the noise floor,
ignoring the automatically tuned noise floor of the driver/hw.

In my tests with a AR9580 based module and a tx99 5 MHz interferer,
I could tune the noisefloor to -95 dBm or above to allow communication
again. The automatic noise floor calibration sometimes could adapt to
the situation as well, but not reliably and permanently.

I would consider this "feature" experimental and interesting for people
debugging the noise floor calibration or other effects of the hardware.

Signed-off-by: Simon Wunderlich <[email protected]>
Signed-off-by: Mathias Kretschmer <[email protected]>
---
drivers/net/wireless/ath/ath9k/calib.c | 5 ++-
drivers/net/wireless/ath/ath9k/debug.c | 62 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 1 +
3 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 0f71146b781d..13ab6bc46775 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -254,7 +254,9 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan))
continue;

- if (h)
+ if (ah->nf_override)
+ nfval = ah->nf_override;
+ else if (h)
nfval = h[i].privNF;
else
nfval = default_nf;
@@ -348,6 +350,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)

return 0;
}
+EXPORT_SYMBOL(ath9k_hw_loadnf);


static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 43930c336987..2e64977a8ab6 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1191,6 +1191,65 @@ static const struct file_operations fops_tpc = {
.llseek = default_llseek,
};

+static ssize_t read_file_nf_override(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath_hw *ah = sc->sc_ah;
+ char buf[32];
+ unsigned int len;
+
+ if (ah->nf_override == 0)
+ len = sprintf(buf, "off\n");
+ else
+ len = sprintf(buf, "%d\n", ah->nf_override);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_nf_override(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath_hw *ah = sc->sc_ah;
+ long val;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (strncmp("off", buf, 3) == 0)
+ val = 0;
+ else if (kstrtol(buf, 0, &val))
+ return -EINVAL;
+
+ if (val > 0)
+ return -EINVAL;
+
+ if (val < -120)
+ return -EINVAL;
+
+ ah->nf_override = val;
+
+ if (ah->curchan)
+ ath9k_hw_loadnf(ah, ah->curchan);
+
+ return count;
+}
+
+static const struct file_operations fops_nf_override = {
+ .read = read_file_nf_override,
+ .write = write_file_nf_override,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
/* Ethtool support for get-stats */

#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
@@ -1402,5 +1461,8 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_u16("airtime_flags", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->airtime_flags);

+ debugfs_create_file("nf_override", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_nf_override);
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 2166f644599d..f06e02d1c342 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -807,6 +807,7 @@ struct ath_hw {
u32 rfkill_gpio;
u32 rfkill_polarity;
u32 ah_flags;
+ s16 nf_override;

bool reset_power_on;
bool htc_reset_init;
--
2.11.0

2017-04-18 14:36:55

by Kalle Valo

[permalink] [raw]
Subject: Re: [v2,1/3] ath9k: Support channels in licensed bands

Simon Wunderlich <[email protected]> wrote:
> From: Ben Greear <[email protected]>
>
> Many chips support channels in licensed bands. Add support for those,
> along with a corresponding kernel config option to disable them by
> default. Note that these channels are not selectable even if the
> option has been compiled unless the user modifies the regulatory
> database to explicitly enable the corresponding channels.
>
> NOTE: These channels must not be used in most regulatory
> domains unless you have a license from the FCC or similar!
>
> Signed-off-by: Ben Greear <[email protected]>
> [Hide this support behind a Kconfig option]
> Signed-off-by: Julian Calaby <[email protected]>
> [only use the 20 mhz channels, add 5 ghz, change to 4.9ghz to licensed bands, simplify]
> Signed-off-by: Simon Wunderlich <[email protected]>
> Signed-off-by: Mathias Kretschmer <[email protected]>

I am not sure that we should support unlicensed bands in Linux and hence
hesitant to apply these. My view is that due to regulatory restrictions we
should not make it too easy to use unlicensed bands. But I'm open for
discussion, this is a challenging area and my knowledge here is limited.

--
https://patchwork.kernel.org/patch/9641105/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

2017-04-19 14:08:56

by Kalle Valo

[permalink] [raw]
Subject: Re: [v2,3/3] ath9k: add noise floor override option

Simon Wunderlich <[email protected]> wrote:
> Introduce a debugfs option to manually override the noise floor,
> ignoring the automatically tuned noise floor of the driver/hw.
>
> In my tests with a AR9580 based module and a tx99 5 MHz interferer,
> I could tune the noisefloor to -95 dBm or above to allow communication
> again. The automatic noise floor calibration sometimes could adapt to
> the situation as well, but not reliably and permanently.
>
> I would consider this "feature" experimental and interesting for people
> debugging the noise floor calibration or other effects of the hardware.
>
> Signed-off-by: Simon Wunderlich <[email protected]>
> Signed-off-by: Mathias Kretschmer <[email protected]>

Patch applied to ath-next branch of ath.git, thanks.

b90189759a7f ath9k: add noise floor override option

--
https://patchwork.kernel.org/patch/9641107/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches