Merge branch 'vendor_drops' into wifi
Conflicts:
drivers/net/wireless/ath/ath10k/ce.c
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/txrx.c
drivers/net/wireless/ath/ath10k/wmi.c
net/mac80211/agg-rx.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/wireless/genregdb.awk
NOTES:
The original patch backports-custom-0510-ath10k-memory-barrier.patch is
resolved by
http://lists.infradead.org/pipermail/ath10k/2014-August/002883.html
So I removed the temporary fix we put in.
The following patches have already been merged in the upstream backports drop.
backports-custom-0001-add-savedefconfig-target.patch
backports-custom-0522-ath10k-fix-rx-aggregation-reordering.patch
backports-custom-0001-log-beacon-info.patch
backports-custom-0523-ath10k-handle-attention-flags-correctly-when-A-MSDU.patch
backports-custom-0100-db.txt-parser-fix.patch
backports-custom-0524-correct-starting-seqno.patch
backports-custom-0515-reset-harder.patch
backports-custom-0530-firmware-10-2-support.patch
backports-custom-0516-retry-reset.patch
backports-custom-0600-set-antenna.patch
backports-custom-0520-fix-rx-reordering-with-RX_FLAG_AMSDU_MORE.patch
backports-custom-0650-ath9k-fix-aggregation-session-lockup.patch
backports-custom-0521-add-support-for-rx-reordering-offloading.patch
backports-custom-0910-ieee80211-phy-attrs.patch
Change-Id: Ifdd886c9ae68e5ba0d07aa5ed8b95d69780851cd
diff --git a/.local-symbols b/.local-symbols
index 8ed044e..82cfa7c 100644
--- a/.local-symbols
+++ b/.local-symbols
@@ -161,6 +161,9 @@
ATH10K_DEBUGFS=
ATH10K_TRACING=
ATH10K_DFS_CERTIFIED=
+ATH10K_USE_NCNB_DESCR=
+ATH10K_USE_NCNB_SKB=
+ATH10K_USE_COMCERTO_WIFI_FASTPATH=
WCN36XX=
WCN36XX_DEBUGFS=
B43=
diff --git a/backport-include/linux/nl80211.h b/backport-include/linux/nl80211.h
index fcb0b8b..2521809 100644
--- a/backport-include/linux/nl80211.h
+++ b/backport-include/linux/nl80211.h
@@ -3,8 +3,6 @@
#include_next <linux/nl80211.h>
#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
-#define NL80211_FEATURE_SK_TX_STATUS 0
-#endif
+#define NL80211_FEATURE_SK_TX_STATUS 1
#endif /* __BACKPORT_LINUX_NL80211_H */
diff --git a/compat/compat-3.6.c b/compat/compat-3.6.c
index c82bfb8..e63fdf9 100644
--- a/compat/compat-3.6.c
+++ b/compat/compat-3.6.c
@@ -149,6 +149,7 @@
EXPORT_SYMBOL_GPL(sg_alloc_table_from_pages);
/* whoopsie ! */
+#if 0
#ifndef CONFIG_COMMON_CLK
int clk_enable(struct clk *clk)
{
@@ -161,3 +162,4 @@
}
EXPORT_SYMBOL_GPL(clk_disable);
#endif
+#endif
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
index 5d5195d..eb8ecdf 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -48,3 +48,28 @@
---help---
This option enables DFS support for initiating radiation on
ath10k.
+
+config ATH10K_USE_NCNB_DESCR
+ bool "Atheros support for GFP_DMA_NCNB for descriptors"
+ depends on ATH10K
+ default n
+ ---help---
+ This option enables use of GFP_DMA_NCNB for descriptors
+ shared with the firmware, on platforms like the Mindspeed
+ Comcerto C2000.
+
+config ATH10K_USE_NCNB_SKB
+ bool "Atheros support for GFP_DMA_NCNB for sk_buffs"
+ depends on ATH10K
+ default n
+ ---help---
+ This option enables use of GFP_DMA_NCNB for sk_buffs on
+ platforms like the Mindspeed Comcerto C2000.
+
+config ATH10K_USE_COMCERTO_WIFI_FASTPATH
+ bool "Atheros support for comcerto_wifi_rx_fastpath"
+ depends on ATH10K
+ default n
+ ---help---
+ This option enables use of comcerto_wifi_rx_fastpath() on
+ Mindspeed Comcerto 2000 platforms.
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 101cadb..de7426a 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -314,6 +314,8 @@
/* Update Source Ring Write Index */
write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+ mb();
+
/* WORKAROUND */
if (!(flags & CE_SEND_FLAG_GATHER))
ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index);
@@ -899,19 +901,26 @@
struct ath10k_ce_ring *src_ring;
u32 nentries = attr->src_nentries;
dma_addr_t base_addr;
+ gfp_t gfpflag;
nentries = roundup_pow_of_two(nentries);
src_ring = kzalloc(sizeof(*src_ring) +
(nentries *
sizeof(*src_ring->per_transfer_context)),
- GFP_KERNEL);
+ GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (src_ring == NULL)
return ERR_PTR(-ENOMEM);
src_ring->nentries = nentries;
src_ring->nentries_mask = nentries - 1;
+#ifdef CPTCFG_ATH10K_USE_NCNB_DESCR
+ gfpflag = GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH|GFP_DMA_NCNB;
+#else
+ gfpflag = GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH;
+#endif
+
/*
* Legacy platforms that do not support cache
* coherent DMA are unsupported
@@ -920,7 +929,8 @@
dma_alloc_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
- &base_addr, GFP_KERNEL);
+ &base_addr, gfpflag);
+
if (!src_ring->base_addr_owner_space_unaligned) {
kfree(src_ring);
return ERR_PTR(-ENOMEM);
@@ -941,7 +951,7 @@
*/
src_ring->shadow_base_unaligned =
kmalloc((nentries * sizeof(struct ce_desc) +
- CE_DESC_RING_ALIGN), GFP_KERNEL);
+ CE_DESC_RING_ALIGN), GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!src_ring->shadow_base_unaligned) {
dma_free_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) +
@@ -972,7 +982,7 @@
dest_ring = kzalloc(sizeof(*dest_ring) +
(nentries *
sizeof(*dest_ring->per_transfer_context)),
- GFP_KERNEL);
+ GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (dest_ring == NULL)
return ERR_PTR(-ENOMEM);
@@ -987,7 +997,7 @@
dma_alloc_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
- &base_addr, GFP_KERNEL);
+ &base_addr, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!dest_ring->base_addr_owner_space_unaligned) {
kfree(dest_ring);
return ERR_PTR(-ENOMEM);
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index cee18c8..5a08f55 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -685,6 +685,16 @@
{
struct ath10k *ar = container_of(work, struct ath10k, restart_work);
+ if (ar->restart_do_reset) {
+ char *argv[] = { "/bin/ath10k-reset", NULL };
+ ar->restart_do_reset = 0;
+ ath10k_err(ar, "trying to call userspace: ath10k-reset\n");
+ if (!call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_EXEC)) {
+ return;
+ }
+ ath10k_err(ar, "failed to execute ath10k-reset. trying driver-level reset.\n");
+ }
+
mutex_lock(&ar->conf_mutex);
switch (ar->state) {
@@ -1130,6 +1140,7 @@
INIT_WORK(&ar->register_work, ath10k_core_register_work);
INIT_WORK(&ar->restart_work, ath10k_core_restart);
+ ar->restart_do_reset = 0;
ret = ath10k_debug_create(ar);
if (ret)
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 9a4ace1..d773aa0 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -41,7 +41,7 @@
#define ATH10K_SCAN_ID 0
#define WMI_READY_TIMEOUT (5 * HZ)
-#define ATH10K_FLUSH_TIMEOUT_HZ (5*HZ)
+#define ATH10K_FLUSH_TIMEOUT_HZ (1*HZ)
#define ATH10K_NUM_CHANS 38
/* Antenna noise floor */
@@ -202,9 +202,14 @@
#define ATH10K_MAX_NUM_PEER_IDS (1 << 11) /* htt rx_desc limit */
struct ath10k_peer {
+ /* protected by conf_mutex + data_lock */
struct list_head list;
+
+ /* protected by conf_mutex */
int vdev_id;
u8 addr[ETH_ALEN];
+
+ /* protected by data_lock */
DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS);
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
};
@@ -532,6 +537,7 @@
struct work_struct register_work;
struct work_struct restart_work;
+ int restart_do_reset;
/* cycle count is reported twice for each visited channel during scan.
* access protected by data_lock */
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index a01096e..f9a7cc3 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -200,7 +200,7 @@
bool enabled;
int i;
- buf = kzalloc(buf_len, GFP_KERNEL);
+ buf = kzalloc(buf_len, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!buf)
return -ENOMEM;
@@ -390,7 +390,7 @@
if (ar->state != ATH10K_STATE_ON)
goto exit;
- buf = kzalloc(buf_len, GFP_KERNEL);
+ buf = kzalloc(buf_len, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!buf)
goto exit;
@@ -612,6 +612,7 @@
struct ath10k *ar = file->private_data;
char buf[32];
int ret;
+ size_t ocount = count;
mutex_lock(&ar->conf_mutex);
@@ -656,7 +657,7 @@
goto exit;
}
- ret = count;
+ ret = ocount;
exit:
mutex_unlock(&ar->conf_mutex);
@@ -1108,7 +1109,7 @@
struct ath10k *ar = file->private_data;
char *buf;
- buf = kzalloc(size, GFP_KERNEL);
+ buf = kzalloc(size, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (buf == NULL)
return -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 9573b44..06923b4 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -36,6 +36,9 @@
ATH10K_DBG_REGULATORY = 0x00000800,
ATH10K_DBG_TESTMODE = 0x00001000,
ATH10K_DBG_ANY = 0xffffffff,
+
+ // Use high bit so conflicts are less likely with upstream updates.
+ ATH10K_DBG_BEACON = 0x10000000,
};
extern unsigned int ath10k_debug_mask;
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 676bd4e..769d594 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -44,7 +44,12 @@
struct sk_buff *skb;
struct ath10k_skb_cb *skb_cb;
+#ifdef CPTCFG_ATH10K_USE_NCNB_SKB
+ skb = __dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE,
+ GFP_DMA_NCNB | GFP_ATOMIC);
+#else
skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
+#endif
if (!skb)
return NULL;
@@ -803,7 +808,12 @@
{
struct sk_buff *skb;
+#ifdef CPTCFG_ATH10K_USE_NCNB_SKB
+ skb = __dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr),
+ GFP_DMA_NCNB | GFP_ATOMIC);
+#else
skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
+#endif
if (!skb)
return NULL;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 60d40a0..2cc15a1 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -134,7 +134,12 @@
idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr);
while (num > 0) {
+#ifdef CPTCFG_ATH10K_USE_NCNB_SKB
+ skb = __dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN,
+ GFP_DMA_NCNB | GFP_ATOMIC);
+#else
skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN);
+#endif
if (!skb) {
ret = -ENOMEM;
goto fail;
@@ -513,13 +518,14 @@
htt->rx_ring.netbufs_ring =
kzalloc(htt->rx_ring.size * sizeof(struct sk_buff *),
- GFP_KERNEL);
+ GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!htt->rx_ring.netbufs_ring)
goto err_netbuf;
size = htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring);
- vaddr = dma_alloc_coherent(htt->ar->dev, size, &paddr, GFP_DMA);
+ vaddr = dma_alloc_coherent(htt->ar->dev, size,
+ &paddr, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH|GFP_DMA);
if (!vaddr)
goto err_dma_ring;
@@ -528,7 +534,7 @@
vaddr = dma_alloc_coherent(htt->ar->dev,
sizeof(*htt->rx_ring.alloc_idx.vaddr),
- &paddr, GFP_DMA);
+ &paddr, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH|GFP_DMA);
if (!vaddr)
goto err_dma_idx;
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index bd87a35..49bb04d 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -103,13 +103,13 @@
htt->max_num_pending_tx);
htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) *
- htt->max_num_pending_tx, GFP_KERNEL);
+ htt->max_num_pending_tx, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!htt->pending_tx)
return -ENOMEM;
htt->used_msdu_ids = kzalloc(sizeof(unsigned long) *
BITS_TO_LONGS(htt->max_num_pending_tx),
- GFP_KERNEL);
+ GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!htt->used_msdu_ids) {
kfree(htt->pending_tx);
return -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index d381d5f..567c14d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -322,28 +322,61 @@
static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
{
+ struct ath10k_peer *peer;
int ret;
lockdep_assert_held(&ar->conf_mutex);
+ peer = ath10k_peer_find(ar, vdev_id, addr);
+ if (peer) {
+ ath10k_warn(ar, "peer %pM on vdev %i already exists\n",
+ addr, vdev_id);
+ return -EINVAL;
+ }
+
+ peer = kzalloc(sizeof(*peer), GFP_KERNEL);
+ if (!peer) {
+ ath10k_warn(ar, "failed to allocate peer %pM on vdev %i: not enough memory\n",
+ addr, vdev_id);
+ return -ENOMEM;
+ }
+
+ peer->vdev_id = vdev_id;
+ memcpy(peer->addr, addr, ETH_ALEN);
+
+ spin_lock_bh(&ar->data_lock);
+ list_add(&peer->list, &ar->peers);
+ spin_unlock_bh(&ar->data_lock);
+
ret = ath10k_wmi_peer_create(ar, vdev_id, addr);
if (ret) {
ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
addr, vdev_id, ret);
- return ret;
+ goto err_free;
}
ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
if (ret) {
ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
addr, vdev_id, ret);
- return ret;
+ goto err_free;
}
spin_lock_bh(&ar->data_lock);
ar->num_peers++;
spin_unlock_bh(&ar->data_lock);
return 0;
+
+err_free:
+ spin_lock_bh(&ar->data_lock);
+ list_del(&peer->list);
+ /* very unlikely, but check anyway */
+ if (!bitmap_empty(peer->peer_ids, ATH10K_MAX_NUM_PEER_IDS))
+ ath10k_warn(ar, "removing peer %pM on vdev %i still being mapped in firmware\n",
+ addr, vdev_id);
+ spin_unlock_bh(&ar->data_lock);
+ kfree(peer);
+ return ret;
}
static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
@@ -420,22 +453,46 @@
static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
{
+ struct ath10k_peer *peer;
int ret;
lockdep_assert_held(&ar->conf_mutex);
+ peer = ath10k_peer_find(ar, vdev_id, addr);
+ if (!peer) {
+ ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
+ addr, vdev_id);
+ return -ENOENT;
+ }
+
ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
- if (ret)
- return ret;
+ if (ret) {
+ ath10k_warn(ar, "failed to request wmi peer %pM on vdev %i removal: %d\n",
+ addr, vdev_id, ret);
+ goto out;
+ }
ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
- if (ret)
- return ret;
+ if (ret) {
+ ath10k_warn(ar, "failed to wait for wmi peer %pM on vdev %i removal: %d\n",
+ addr, vdev_id, ret);
+ goto out;
+ }
spin_lock_bh(&ar->data_lock);
ar->num_peers--;
spin_unlock_bh(&ar->data_lock);
+out:
+ spin_lock_bh(&ar->data_lock);
+ list_del(&peer->list);
+ if (!bitmap_empty(peer->peer_ids, ATH10K_MAX_NUM_PEER_IDS))
+ ath10k_warn(ar, "removing peer %pM on vdev %i still being mapped in firmware\n",
+ addr, vdev_id);
+ spin_unlock_bh(&ar->data_lock);
+
+ kfree(peer);
+
return 0;
}
@@ -1696,7 +1753,7 @@
}
len = sizeof(struct wmi_channel_arg) * arg.n_channels;
- arg.channels = kzalloc(len, GFP_KERNEL);
+ arg.channels = kzalloc(len, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!arg.channels)
return -ENOMEM;
@@ -2126,9 +2183,67 @@
}
}
+static void ath10k_mgmt_tx_flush(struct ath10k *ar, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_sta *sta;
+ struct ath10k_vif *arvif;
+ u8 *da = ieee80211_get_DA(hdr);
+ u8 vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
+ u32 bcn_intval = 0;
+ unsigned int msecs;
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (!is_unicast_ether_addr(da))
+ return;
+
+ rcu_read_lock();
+ sta = ieee80211_find_sta_by_ifaddr(ar->hw, da, NULL);
+ rcu_read_unlock();
+
+ /*
+ * FW Tx queues can be paused only for associated peers. Since this is
+ * a workaround just assume worst case if station simply entry exists.
+ */
+ if (!sta)
+ return;
+
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ if (arvif->vdev_id == vdev_id) {
+ bcn_intval = arvif->beacon_interval;
+ break;
+ }
+ }
+
+ if (!bcn_intval)
+ return;
+
+ /*
+ * Wait 2 beacon intervals before flushing so stations that are
+ * asleep but are actually still in range have a chance to see
+ * updated PVB, wake up and fetch the frame. There's no other way of
+ * synchronizing other than sleeping because there's no tx completion
+ * indication event for WMI management tx.
+ */
+ msecs = 2 * arvif->beacon_interval * 1024 / 1000;
+ ath10k_dbg(ar, ATH10K_DBG_MAC,
+ "mac flushing peer %pM on vdev %i mgmt tid for unicast mgmt (%d msecs)\n",
+ da, vdev_id, msecs);
+ msleep(msecs);
+
+ ret = ath10k_wmi_peer_flush(ar, vdev_id, da,
+ WMI_PEER_TID_MGMT_MASK);
+ if (ret)
+ ath10k_warn(ar, "failed to flush peer %pM mgmt tid: %d\n",
+ da, ret);
+}
+
void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
{
struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
+ struct ieee80211_tx_info *info;
struct sk_buff *skb;
int ret;
@@ -2137,12 +2252,50 @@
if (!skb)
break;
+ mutex_lock(&ar->conf_mutex);
+
ret = ath10k_wmi_mgmt_tx(ar, skb);
if (ret) {
ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
ret);
+ mutex_unlock(&ar->conf_mutex);
ieee80211_free_txskb(ar->hw, skb);
+ continue;
}
+
+ /*
+ * Each WMI management Tx consumes 1 HTC Tx credit and doesn't
+ * replenish it until the frame is actually transmitted out of
+ * firmware's Tx queues.
+ *
+ * If associated client was asleep and has gone out of range
+ * then unicast frames won't be released for FW/HW queues for a
+ * while (10 seconds per observation). This means that if more
+ * management frames are queued then HTC Tx credits are drained
+ * to 0 and no other commands can be submitted including
+ * beacons and peer removal.
+ *
+ * This could in turn result in clients disconnecting due to
+ * their beacon loss and may trigger spurious sta kickouts
+ * because wmi peer removal command may never reach firmware
+ * during disassociation.
+ *
+ * This could happen, e.g. when disconnecting client that has
+ * gone away while asleep.
+ *
+ * As a workaround flush unicast management frames that can
+ * possibly be buffered.
+ *
+ * Note: This is a deficiency in design of WMI_MGMT_TX command.
+ */
+ ath10k_mgmt_tx_flush(ar, skb);
+
+ mutex_unlock(&ar->conf_mutex);
+
+ /* there's no way to get ACK so just assume it's acked */
+ info = IEEE80211_SKB_CB(skb);
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ ieee80211_tx_status(ar->hw, skb);
}
}
@@ -3819,41 +3972,109 @@
return ret;
}
-static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- u32 queues, bool drop)
+static int ath10k_flush_all_peer_tids(struct ath10k *ar)
{
- struct ath10k *ar = hw->priv;
- bool skip;
+ struct ath10k_peer *peer;
int ret;
- /* mac80211 doesn't care if we really xmit queued frames or not
- * we'll collect those frames either way if we stop/delete vdevs */
- if (drop)
- return;
+ lockdep_assert_held(&ar->conf_mutex);
- mutex_lock(&ar->conf_mutex);
+ list_for_each_entry(peer, &ar->peers, list) {
+ ret = ath10k_wmi_peer_flush(ar, peer->vdev_id, peer->addr,
+ WMI_PEER_TID_ALL_MASK);
+ if (ret) {
+ ath10k_warn(ar, "failed to request peer %pM on vdev %i to flush %08x: %d\n",
+ peer->addr, peer->vdev_id, WMI_PEER_TID_ALL_MASK, ret);
+ return ret;
+ }
+ }
- if (ar->state == ATH10K_STATE_WEDGED)
- goto skip;
+ return 0;
+}
- ret = wait_event_timeout(ar->htt.empty_tx_wq, ({
- bool empty;
+static int ath10k_flush_wait(struct ath10k *ar)
+{
+ bool skip;
+ int ret = wait_event_timeout(ar->htt.empty_tx_wq, ({
+ bool htt_empty, wmi_empty;
+ unsigned long flags;
spin_lock_bh(&ar->htt.tx_lock);
- empty = (ar->htt.num_pending_tx == 0);
+ htt_empty = (ar->htt.num_pending_tx == 0);
spin_unlock_bh(&ar->htt.tx_lock);
+ spin_lock_irqsave(&ar->wmi_mgmt_tx_queue.lock, flags);
+ wmi_empty = skb_queue_len(&ar->wmi_mgmt_tx_queue) == 0;
+ spin_unlock_irqrestore(&ar->wmi_mgmt_tx_queue.lock,
+ flags);
+
skip = (ar->state == ATH10K_STATE_WEDGED);
- (empty || skip);
+ ((htt_empty && wmi_empty) || skip);
}), ATH10K_FLUSH_TIMEOUT_HZ);
- if (ret <= 0 || skip)
- ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %i\n",
- skip, ar->state, ret);
+ if (ret == 0)
+ ret = -ETIMEDOUT;
+ else if (ret > 0)
+ ret = 0;
-skip:
+ if (skip) {
+ ath10k_warn(ar, "ignoring flushing result because hardware is wedged\n");
+ ret = -EBUSY;
+ }
+
+ return ret;
+}
+
+static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop)
+{
+ struct ath10k *ar = hw->priv;
+ int ret;
+
+ mutex_lock(&ar->conf_mutex);
+
+ if (drop) {
+ ret = ath10k_flush_all_peer_tids(ar);
+ if (ret) {
+ ath10k_warn(ar, "failed to flush all peer tids: %d\n", ret);
+ goto out;
+ }
+
+ goto out;
+ }
+
+ if (ar->state == ATH10K_STATE_WEDGED) {
+ ath10k_warn(ar, "skipping flushing because hardware is wedged\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ret = ath10k_flush_wait(ar);
+ if (ret) {
+ ath10k_dbg(ar, ATH10K_DBG_MAC,
+ "failed to wait for tx to flush: %d, forcing\n",
+ ret);
+
+ ret = ath10k_flush_all_peer_tids(ar);
+ if (ret) {
+ ath10k_warn(ar, "failed to flush all peer tids: %d\n", ret);
+ goto out;
+ }
+
+ ret = ath10k_flush_wait(ar);
+ if (ret) {
+ ath10k_warn(ar, "failed to flush tx: %d\n", ret);
+ goto out;
+ }
+ }
+
+out:
mutex_unlock(&ar->conf_mutex);
+
+ /* empty mgmt tx queue doesn't mean mgmt tx is flushed because the last
+ * frame still may be processed by a worker */
+ if (ret == 0)
+ cancel_work_sync(&ar->wmi_mgmt_tx_work);
}
/* TODO: Implement this function properly
@@ -4759,7 +4980,7 @@
if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
channels = kmemdup(ath10k_2ghz_channels,
sizeof(ath10k_2ghz_channels),
- GFP_KERNEL);
+ GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!channels) {
ret = -ENOMEM;
goto err_free;
@@ -4780,7 +5001,7 @@
if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
channels = kmemdup(ath10k_5ghz_channels,
sizeof(ath10k_5ghz_channels),
- GFP_KERNEL);
+ GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!channels) {
ret = -ENOMEM;
goto err_free;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 59e0ea8..0d70674 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -380,7 +380,12 @@
lockdep_assert_held(&ar_pci->ce_lock);
+#ifdef CPTCFG_ATH10K_USE_NCNB_SKB
+ skb = __dev_alloc_skb(pipe->buf_sz,
+ GFP_DMA_NCNB | GFP_ATOMIC);
+#else
skb = dev_alloc_skb(pipe->buf_sz);
+#endif
if (!skb)
return -ENOMEM;
@@ -999,6 +1004,9 @@
spin_unlock_bh(&ar->data_lock);
+reset:
+ ath10k_err(ar, "scheduling ath10k-reset\n");
+ ar->restart_do_reset = 1;
queue_work(ar->workqueue, &ar->restart_work);
}
@@ -1292,7 +1300,7 @@
if (resp && resp_len && *resp_len == 0)
return -EINVAL;
- treq = kmemdup(req, req_len, GFP_KERNEL);
+ treq = kmemdup(req, req_len, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!treq)
return -ENOMEM;
@@ -1302,7 +1310,7 @@
goto err_dma;
if (resp && resp_len) {
- tresp = kzalloc(*resp_len, GFP_KERNEL);
+ tresp = kzalloc(*resp_len, GFP_KERNEL|__GFP_REPEAT|__GFP_HIGH);
if (!tresp) {
ret = -ENOMEM;
goto err_req;
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index a0cbc21..d498fe3 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -101,13 +101,13 @@
wake_up(&htt->empty_tx_wq);
}
+/* hold conf_mutex for simple iteration, or conf_mutex+data_lock for
+ * modifications */
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr)
{
struct ath10k_peer *peer;
- lockdep_assert_held(&ar->data_lock);
-
list_for_each_entry(peer, &ar->peers, list) {
if (peer->vdev_id != vdev_id)
continue;
@@ -139,10 +139,14 @@
int ret;
ret = wait_event_timeout(ar->peer_mapping_wq, ({
- bool mapped;
+ struct ath10k_peer *peer;
+ bool mapped = false;
spin_lock_bh(&ar->data_lock);
- mapped = !!ath10k_peer_find(ar, vdev_id, addr);
+ peer = ath10k_peer_find(ar, vdev_id, addr);
+ if (peer)
+ mapped = !bitmap_empty(peer->peer_ids,
+ ATH10K_MAX_NUM_PEER_IDS);
spin_unlock_bh(&ar->data_lock);
mapped == expect_mapped;
@@ -173,20 +177,16 @@
spin_lock_bh(&ar->data_lock);
peer = ath10k_peer_find(ar, ev->vdev_id, ev->addr);
if (!peer) {
- peer = kzalloc(sizeof(*peer), GFP_ATOMIC);
- if (!peer)
- goto exit;
-
- peer->vdev_id = ev->vdev_id;
- ether_addr_copy(peer->addr, ev->addr);
- list_add(&peer->list, &ar->peers);
- wake_up(&ar->peer_mapping_wq);
+ ath10k_warn(ar, "failed to map peer %pM on vdev %i: no such entry\n",
+ ev->addr, ev->vdev_id);
+ goto exit;
}
ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n",
ev->vdev_id, ev->addr, ev->peer_id);
set_bit(ev->peer_id, peer->peer_ids);
+ wake_up(&ar->peer_mapping_wq);
exit:
spin_unlock_bh(&ar->data_lock);
}
@@ -210,11 +210,8 @@
clear_bit(ev->peer_id, peer->peer_ids);
- if (bitmap_empty(peer->peer_ids, ATH10K_MAX_NUM_PEER_IDS)) {
- list_del(&peer->list);
- kfree(peer);
+ if (bitmap_empty(peer->peer_ids, ATH10K_MAX_NUM_PEER_IDS))
wake_up(&ar->peer_mapping_wq);
- }
exit:
spin_unlock_bh(&ar->data_lock);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index bd23ca6..fd39c22 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -681,25 +681,27 @@
return ret;
}
-static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
+/* Returns -1 on failure, 0 on success, or 1 if already sent. */
+static int ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
{
int ret;
lockdep_assert_held(&arvif->ar->data_lock);
if (arvif->beacon == NULL)
- return;
+ return -1;
if (arvif->beacon_sent)
- return;
+ return 1;
ret = ath10k_wmi_beacon_send_ref_nowait(arvif);
if (ret)
- return;
+ return -1;
/* We need to retain the arvif->beacon reference for DMA unmapping and
* freeing the skbuff later. */
arvif->beacon_sent = true;
+ return 0;
}
static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac,
@@ -760,7 +762,6 @@
struct wmi_mgmt_tx_cmd *cmd;
struct ieee80211_hdr *hdr;
struct sk_buff *wmi_skb;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int len;
u32 buf_len = skb->len;
u16 fc;
@@ -806,10 +807,6 @@
if (ret)
return ret;
- /* TODO: report tx status to mac80211 - temporary just ACK */
- info->flags |= IEEE80211_TX_STAT_ACK;
- ieee80211_tx_status_irqsafe(ar->hw, skb);
-
return ret;
}
@@ -1581,6 +1578,9 @@
struct sk_buff *bcn;
int ret, vdev_id = 0;
+ int attempted_to_send_beacon = 0;
+ static int beacon_count = 0;
+
ev = (struct wmi_host_swba_event *)skb->data;
map = __le32_to_cpu(ev->vdev_map);
@@ -1668,9 +1668,24 @@
arvif->beacon = bcn;
arvif->beacon_sent = false;
- ath10k_wmi_tx_beacon_nowait(arvif);
+ ret = ath10k_wmi_tx_beacon_nowait(arvif);
+ attempted_to_send_beacon = 1;
+ if (ret == 1) {
+ ath10k_warn(ar, "beacon_sent should have been false\n");
+ } else if (ret == -1) {
+ ath10k_warn(ar, "failed to send beacon\n");
+ } else {
+ ++beacon_count;
+ }
skip:
spin_unlock_bh(&ar->data_lock);
+
+ if (attempted_to_send_beacon == 0) {
+ ath10k_warn(ar, "beacon callback led to no beacon\n");
+ } else if ((ath10k_debug_mask & ATH10K_DBG_BEACON) && beacon_count >= 50) {
+ beacon_count = 0;
+ ath10k_dbg(ar, ATH10K_DBG_BEACON, "50 beacons sent\n");
+ }
}
}
@@ -2971,6 +2986,8 @@
config.ast_skid_limit = __cpu_to_le32(TARGET_AST_SKID_LIMIT);
config.tx_chain_mask = __cpu_to_le32(TARGET_TX_CHAIN_MASK);
config.rx_chain_mask = __cpu_to_le32(TARGET_RX_CHAIN_MASK);
+ ar->supp_tx_chainmask = TARGET_TX_CHAIN_MASK;
+ ar->supp_rx_chainmask = TARGET_RX_CHAIN_MASK;
config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
config.rx_timeout_pri_be = __cpu_to_le32(TARGET_RX_TIMEOUT_LO_PRI);
@@ -3065,6 +3082,9 @@
config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT);
config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK);
config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK);
+ /* TODO: Have to deal with 2x2 chips if/when the come out. */
+ ar->supp_tx_chainmask = TARGET_10X_TX_CHAIN_MASK;
+ ar->supp_rx_chainmask = TARGET_10X_RX_CHAIN_MASK;
config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
@@ -3567,6 +3587,8 @@
cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack);
cmd->beacon_interval = __cpu_to_le32(arg->bcn_intval);
cmd->dtim_period = __cpu_to_le32(arg->dtim_period);
+ printk(KERN_WARNING "ath10k_wmi_vdev_start_restart: dtim_period=%d\n",
+ arg->dtim_period);
cmd->flags = __cpu_to_le32(flags);
cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate);
cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 86f5ebc..048ba28 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4293,6 +4293,10 @@
struct wmi_mac_addr peer_macaddr;
} __packed;
+#define WMI_PEER_TID_MGMT 17
+#define WMI_PEER_TID_MGMT_MASK BIT(WMI_PEER_TID_MGMT)
+#define WMI_PEER_TID_ALL_MASK 0xFFFFFFFF
+
struct wmi_peer_flush_tids_cmd {
__le32 vdev_id;
struct wmi_mac_addr peer_macaddr;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 4f59abf..d8e9508 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -21,6 +21,7 @@
#include <linux/ath9k_platform.h>
#include <linux/module.h>
#include <linux/relay.h>
+#include <linux/spinlock.h>
#include <net/ieee80211_radiotap.h>
#include "ath9k.h"
@@ -37,8 +38,23 @@
MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
+static DEFINE_SPINLOCK(debug_lock);
static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
-module_param_named(debug, ath9k_debug, uint, 0);
+static int *ath_common_debug = NULL;
+static int ath9k_update_debug(const char *val, const struct kernel_param *kp) {
+ int ret = param_set_uint(val, kp);
+ if (ret < 0) return ret;
+
+ spin_lock(&debug_lock);
+ if (ath_common_debug) *ath_common_debug = ath9k_debug;
+ spin_unlock(&debug_lock);
+ return 0;
+}
+static const struct kernel_param_ops ath9k_debug_param_ops = {
+ .set = ath9k_update_debug,
+ .get = param_get_uint,
+};
+module_param_cb(debug, &ath9k_debug_param_ops, &ath9k_debug, 0644);
MODULE_PARM_DESC(debug, "Debugging mask");
int ath9k_modparam_nohwcrypt;
@@ -535,10 +551,14 @@
common->ah = ah;
common->hw = sc->hw;
common->priv = sc;
- common->debug_mask = ath9k_debug;
common->btcoex_enabled = ath9k_btcoex_enable == 1;
common->disable_ani = false;
+ spin_lock(&debug_lock);
+ ath_common_debug = &common->debug_mask;
+ spin_unlock(&debug_lock);
+ common->debug_mask = ath9k_debug;
+
/*
* Platform quirks.
*/
@@ -951,6 +971,9 @@
void ath9k_deinit_device(struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
+ spin_lock(&debug_lock);
+ ath_common_debug = NULL;
+ spin_unlock(&debug_lock);
ath9k_ps_wakeup(sc);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2ca7a9f..a46ff74 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1895,7 +1895,7 @@
* the frames sent while scanning on other channel will be
* lost)
*/
- if (sdata->u.ap.beacon &&
+ if (0 && sdata->u.ap.beacon &&
(!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
!(req->flags & NL80211_SCAN_FLAG_AP)))
return -EOPNOTSUPP;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 09f5387..21d7259 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1996,12 +1996,23 @@
if (skb) {
/* deliver to local stack */
- skb->protocol = eth_type_trans(skb, dev);
- memset(skb->cb, 0, sizeof(skb->cb));
- if (rx->local->napi)
- napi_gro_receive(rx->local->napi, skb);
- else
- netif_receive_skb(skb);
+#ifdef CPTCFG_ATH10K_USE_COMCERTO_WIFI_FASTPATH
+ extern int comcerto_wifi_rx_fastpath(struct sk_buff *skb);
+ int slowpath = 1;
+ if (!comcerto_wifi_rx_fastpath(skb)) {
+ /* fastpath handled this packet */
+ slowpath = 0;
+ }
+ if (slowpath)
+#endif
+ {
+ skb->protocol = eth_type_trans(skb, dev);
+ memset(skb->cb, 0, sizeof(skb->cb));
+ if (rx->local->napi)
+ napi_gro_receive(rx->local->napi, skb);
+ else
+ netif_receive_skb(skb);
+ }
}
if (xmit_skb) {
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 6232a12..fcab208 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -1,17 +1,845 @@
-#
-# This file is a placeholder to prevent accidental build breakage if someone
-# enables CPTCFG_CFG80211_INTERNAL_REGDB. Almost no one actually needs to
-# enable that build option.
-#
-# You should be using CRDA instead. It is even better if you use the CRDA
-# package provided by your distribution, since they will probably keep it
-# up-to-date on your behalf.
-#
-# If you _really_ intend to use CPTCFG_CFG80211_INTERNAL_REGDB then you will
-# need to replace this file with one containing appropriately formatted
-# regulatory rules that cover the regulatory domains you will be using. Your
-# best option is to extract the db.txt file from the wireless-regdb git
-# repository:
-#
-# git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
-#
+# This is the world regulatory domain
+country 00:
+ (2402 - 2472 @ 40), (20)
+ # Channel 12 - 13.
+ (2457 - 2482 @ 40), (20), NO-IR
+ # Channel 14. Only JP enables this and for 802.11b only
+ (2474 - 2494 @ 20), (20), NO-IR
+ # Channel 36 - 48
+ (5170 - 5250 @ 80), (20), NO-IR
+ # NB: 5260 MHz - 5700 MHz requies DFS
+ # Channel 149 - 165
+ (5735 - 5835 @ 80), (20), NO-IR
+ # IEEE 802.11ad (60GHz), channels 1..3
+ (57240 - 63720 @ 2160), (0)
+
+
+country AD:
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country AE: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20.00)
+ (5250 - 5330 @ 80), (20.00), DFS
+ (5490 - 5710 @ 80), (27.00), DFS
+
+country AM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (18)
+ (5250 - 5330 @ 80), (18), DFS
+
+country AN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country AR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country AU:
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5710 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country AW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country AZ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (18)
+ (5250 - 5330 @ 80), (18), DFS
+
+country BA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country BB: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BD: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country BE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country BG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country BH: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5735 - 5835 @ 80), (20)
+
+country BL:
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (18)
+ (5250 - 5330 @ 40), (18), DFS
+
+country BN: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5735 - 5835 @ 80), (20)
+
+country BO: DFS-JP
+ (2402 - 2482 @ 40), (30)
+ (5735 - 5835 @ 80), (30)
+
+country BR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country BY: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country BZ: DFS-JP
+ (2402 - 2482 @ 40), (30)
+ (5735 - 5835 @ 80), (30)
+
+country CA: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CH: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country CL: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5735 - 5835 @ 80), (20)
+
+country CN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+ # 60 gHz band channels 1,4: 28dBm, channels 2,3: 44dBm
+ # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
+ (57240 - 59400 @ 2160), (28)
+ (59400 - 63720 @ 2160), (44)
+ (63720 - 65880 @ 2160), (28)
+
+country CO: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CR: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country CY: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+# Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
+# and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
+# Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
+# implemented.
+country CZ: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR
+ (5470 - 5725 @ 80), (500 mW), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+# Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from
+# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf
+# For the 5GHz range also see
+# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf
+# The values have been reduced by a factor of 2 (3db) for non TPC devices
+# (in other words: devices with TPC can use twice the tx power of this table).
+# Note that the docs do not require TPC for 5150--5250; the reduction to
+# 100mW thus is not strictly required -- however the conservative 100mW
+# limit is used here as the non-interference with radar and satellite
+# apps relies on the attenuation by the building walls only in the
+# absence of DFS; the neighbour countries have 100mW limit here as well.
+
+country DE: DFS-ETSI
+ # entries 279004 and 280006
+ (2400 - 2483.5 @ 40), (100 mW)
+ # entry 303005, 304002 and 305002
+ (5150 - 5350 @ 80), (100 mW), NO-OUTDOOR
+ # entries 308002, 309001 and 310003
+ (5470 - 5725 @ 80), (500 mW), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country DK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country DO: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+
+country DZ: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170.000 - 5250.000 @ 80.000), (23.00)
+ (5250.000 - 5330.000 @ 80.000), (23.00), DFS
+ (5490.000 - 5670.000 @ 80.000), (23.00), DFS
+
+country EC: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country EE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country EG: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+
+country ES: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5250 @ 80), (100 mW), NO-OUTDOOR
+ (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR
+ (5470 - 5725 @ 80), (500 mW), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country FI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country FR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country GE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (18)
+ (5250 - 5330 @ 80), (18), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country GB: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country GD: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country GR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country GL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country GT: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+
+country GU: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HK:
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5710 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country HR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country HT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country HU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country ID: DFS-JP
+ # ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5815 @ 80), (23)
+
+country IE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country IL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5150 - 5350 @ 80), (200 mW), NO-OUTDOOR
+
+country IN: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5735 - 5835 @ 80), (20)
+
+country IS: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country IR: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country IT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country JM: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country JP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (2474 - 2494 @ 20), (20), NO-OFDM
+ (4910 - 4990 @ 40), (23)
+ (5030 - 5090 @ 40), (23)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 160), (23), DFS
+
+country JO: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5735 - 5835 @ 80), (23)
+
+country KE: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23)
+ (5490 - 5570 @ 80), (30), DFS
+ (5735 - 5775 @ 40), (23)
+
+country KH: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country KP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5630 @ 80), (30), DFS
+ (5735 - 5815 @ 80), (30)
+
+country KR: DFS-JP
+ (2402 - 2482 @ 20), (20)
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (30), DFS
+ (5735 - 5815 @ 80), (30)
+
+country KW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+
+country KZ:
+ (2402 - 2482 @ 40), (20)
+
+country LB: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country LI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country LK: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country LT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country LU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country LV: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country MC: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country MA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+
+country MO:
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 40), (23)
+ (5250 - 5330 @ 40), (23), DFS
+ (5735 - 5835 @ 40), (30)
+
+country MK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country MT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country MY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+
+country MX: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country NL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5330 @ 80), (20), NO-OUTDOOR
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country NO: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country NP: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5735 - 5835 @ 80), (20)
+
+country NZ: DFS-FCC
+ (2402 - 2482 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country OM: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country PA: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PE: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country PK: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country PL: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country PT: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country PR: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country QA: DFS-JP
+ (2402 - 2482 @ 40), (20)
+ (5735 - 5835 @ 80), (30)
+
+country RO: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+
+# Source:
+# http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
+country RS: DFS-ETSI
+ (2400 - 2483.5 @ 40), (100 mW)
+ (5150 - 5350 @ 40), (200 mW), NO-OUTDOOR
+ (5470 - 5725 @ 20), (1000 mW), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country RU: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5650 - 5730 @ 80), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country RW: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country SE: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country SG: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SI: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country SK: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country SV: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+
+country SY:
+ (2402 - 2482 @ 40), (20)
+
+country TW: DFS-JP
+ (2402 - 2472 @ 40), (30)
+ (5270 - 5330 @ 40), (17), DFS
+ (5490 - 5590 @ 80), (30), DFS
+ (5650 - 5710 @ 40), (30), DFS
+ (5735 - 5835 @ 80), (30)
+
+country TH: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country TT: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country TN: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+
+country TR: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+# Source:
+# #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
+# #1174 / 23 Oct 2008: http://www.nkrz.gov.ua/uk/activities/ruling/1225269361
+# (appendix 8)
+# Listed 5GHz range is a lowest common denominator for all related
+# rules in the referenced laws. Such a range is used because of
+# disputable definitions there.
+country UA: DFS-ETSI
+ (2400 - 2483.5 @ 40), (20), NO-OUTDOOR
+ (5150 - 5350 @ 40), (20), NO-OUTDOOR
+ (5490 - 5670 @ 80), (20), DFS
+ (5735 - 5835 @ 80), (20)
+ # 60 gHz band channels 1-4, ref: Etsi En 302 567
+ (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+
+country US: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+ # 60g band
+ # reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
+ # channels 1,2,3, EIRP=40dBm(43dBm peak)
+ (57240 - 63720 @ 2160), (40)
+
+country UY: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country UZ: DFS-FCC
+ (2402 - 2472 @ 40), (30)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country VE: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (23), DFS
+ (5735 - 5835 @ 80), (30)
+
+country VN: DFS-FCC
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (17)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
+ (5735 - 5835 @ 80), (30)
+
+country YE:
+ (2402 - 2482 @ 40), (20)
+
+country ZA: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
+country ZW: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (20)
+ (5250 - 5330 @ 80), (20), DFS
+ (5490 - 5710 @ 80), (27), DFS
+
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
index baf2426..37be759 100644
--- a/net/wireless/genregdb.awk
+++ b/net/wireless/genregdb.awk
@@ -66,6 +66,7 @@
sub(/\(/, "", power)
sub(/\),/, "", power)
+ sub(/\)/, "", power)
sub(/\),/, "", units)
sub(/\)/, "", units)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5e233a5..2a1733a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -697,6 +697,7 @@
{
unsigned int dscp;
unsigned char vlan_priority;
+ return 0;
/* skb->priority values from 256->263 are magic values to
* directly indicate a specific 802.1d priority. This is used