* [RFC 0/5] Fix mac addr enforcement on monitor interfaces
From: Jakub Kicinski @ 2013-06-07 13:36 UTC (permalink / raw)
To: linux-wireless
Cc: Helmut Schaa, Felix Fietkau, Johannes Berg, nietrywialneprzejscie
From: Jakub Kicinski <kubakici@wp.pl>
It's still possible for users to hurt themselves
by setting incompatible mac addresses on hardware
that needs conformance to addr_mask. This series
aims to fix that and improve address assignment to
active monitors.
Unfortunately there is a merge conflict in mac80211.git
and mac80211-next.git between:
ac20976dca mac80211: Allow single vif mac address change with addr_mask
and
31eba5bc56 mac80211: support active monitor interfaces
so I got confused and based the series on
wireless-testing.git. Is this acceptable?
Jakub Kicinski (5):
mac80211: introduce __ieee80211_assign_perm_addr
mac80211: return new mac address as soon as possible
mac80211: always default to address compatible with mask
mac80211: enforce address verification on monitors
mac80211: assign right mac addr to active monitors
net/mac80211/cfg.c | 2 +-
net/mac80211/ieee80211_i.h | 2 +-
net/mac80211/iface.c | 197 ++++++++++++++++++++++-----------------------
net/mac80211/main.c | 2 +-
4 files changed, 99 insertions(+), 104 deletions(-)
--
1.8.1.4
^ permalink raw reply
* [PATCH v3] ath5k: make use of the new rate control API
From: Thomas Huehn @ 2013-06-07 12:47 UTC (permalink / raw)
To: linville
Cc: linux-wireless, nbd, johannes, mickflemm, mcgrof, rmanohar,
adrian, ath5k-devel, bvahl
This patch enabels ath5k to use the new rate table to lookup each
mrr rate and retry information per packet.
Signed-off-by: Benjamin Vahl <bvahl@net.t-labs.tu-berlin.de>
Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
---
drivers/net/wireless/ath/ath5k/base.c | 79 ++++++++++++++++++++-----
drivers/net/wireless/ath/ath5k/base.h | 14 +++--
drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +-
3 files changed, 74 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7f702fe..a86c37f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -60,6 +60,7 @@
#include <asm/unaligned.h>
+#include <net/mac80211.h>
#include "base.h"
#include "reg.h"
#include "debug.h"
@@ -666,9 +667,46 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
+static struct ieee80211_rate *
+ath5k_get_rate(const struct ieee80211_hw *hw,
+ const struct ieee80211_tx_info *info,
+ struct ath5k_buf *bf, int idx)
+{
+ /*
+ * convert a ieee80211_tx_rate RC-table entry to
+ * the respective ieee80211_rate struct
+ */
+ if (bf->rates[idx].idx < 0) {
+ return NULL;
+ }
+
+ return &hw->wiphy->bands[info->band]->bitrates[ bf->rates[idx].idx ];
+}
+
+static u16
+ath5k_get_rate_hw_value(const struct ieee80211_hw *hw,
+ const struct ieee80211_tx_info *info,
+ struct ath5k_buf *bf, int idx)
+{
+ struct ieee80211_rate *rate;
+ u16 hw_rate;
+ u8 rc_flags;
+
+ rate = ath5k_get_rate(hw, info, bf, idx);
+ if (!rate)
+ return 0;
+
+ rc_flags = bf->rates[idx].flags;
+ hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+ rate->hw_value_short : rate->hw_value;
+
+ return hw_rate;
+}
+
static int
ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
- struct ath5k_txq *txq, int padsize)
+ struct ath5k_txq *txq, int padsize,
+ struct ieee80211_tx_control *control)
{
struct ath5k_desc *ds = bf->desc;
struct sk_buff *skb = bf->skb;
@@ -688,7 +726,11 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len,
DMA_TO_DEVICE);
- rate = ieee80211_get_tx_rate(ah->hw, info);
+ ieee80211_get_tx_rates(info->control.vif, (control) ? control->sta : NULL, skb, bf->rates,
+ ARRAY_SIZE(bf->rates));
+
+ rate = ath5k_get_rate(ah->hw, info, bf, 0);
+
if (!rate) {
ret = -EINVAL;
goto err_unmap;
@@ -698,8 +740,8 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
flags |= AR5K_TXDESC_NOACK;
rc_flags = info->control.rates[0].flags;
- hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
- rate->hw_value_short : rate->hw_value;
+
+ hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0);
pktlen = skb->len;
@@ -722,12 +764,13 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw,
info->control.vif, pktlen, info));
}
+
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
ieee80211_get_hdrlen_from_skb(skb), padsize,
get_hw_packet_type(skb),
(ah->ah_txpower.txp_requested * 2),
hw_rate,
- info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
+ bf->rates[0].count, keyidx, ah->ah_tx_ant, flags,
cts_rate, duration);
if (ret)
goto err_unmap;
@@ -736,13 +779,15 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
if (ah->ah_capabilities.cap_has_mrr_support) {
memset(mrr_rate, 0, sizeof(mrr_rate));
memset(mrr_tries, 0, sizeof(mrr_tries));
+
for (i = 0; i < 3; i++) {
- rate = ieee80211_get_alt_retry_rate(ah->hw, info, i);
+
+ rate = ath5k_get_rate(ah->hw, info, bf, i);
if (!rate)
break;
- mrr_rate[i] = rate->hw_value;
- mrr_tries[i] = info->control.rates[i + 1].count;
+ mrr_rate[i] = ath5k_get_rate_hw_value(ah->hw, info, bf, i);
+ mrr_tries[i] = bf->rates[i].count;
}
ath5k_hw_setup_mrr_tx_desc(ah, ds,
@@ -1515,7 +1560,7 @@ unlock:
void
ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ath5k_txq *txq)
+ struct ath5k_txq *txq, struct ieee80211_tx_control *control)
{
struct ath5k_hw *ah = hw->priv;
struct ath5k_buf *bf;
@@ -1555,7 +1600,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
bf->skb = skb;
- if (ath5k_txbuf_setup(ah, bf, txq, padsize)) {
+ if (ath5k_txbuf_setup(ah, bf, txq, padsize, control)) {
bf->skb = NULL;
spin_lock_irqsave(&ah->txbuflock, flags);
list_add_tail(&bf->list, &ah->txbuf);
@@ -1571,11 +1616,13 @@ drop_packet:
static void
ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
- struct ath5k_txq *txq, struct ath5k_tx_status *ts)
+ struct ath5k_txq *txq, struct ath5k_tx_status *ts,
+ struct ath5k_buf *bf)
{
struct ieee80211_tx_info *info;
u8 tries[3];
int i;
+ int size = 0;
ah->stats.tx_all_count++;
ah->stats.tx_bytes_count += skb->len;
@@ -1587,6 +1634,9 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
ieee80211_tx_info_clear_status(info);
+ min_t(int, sizeof(info->status.rates), sizeof(bf->rates));
+ memcpy(info->status.rates, bf->rates, size);
+
for (i = 0; i < ts->ts_final_idx; i++) {
struct ieee80211_tx_rate *r =
&info->status.rates[i];
@@ -1663,7 +1713,7 @@ ath5k_tx_processq(struct ath5k_hw *ah, struct ath5k_txq *txq)
dma_unmap_single(ah->dev, bf->skbaddr, skb->len,
DMA_TO_DEVICE);
- ath5k_tx_frame_completed(ah, skb, txq, &ts);
+ ath5k_tx_frame_completed(ah, skb, txq, &ts, bf);
}
/*
@@ -1917,7 +1967,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
skb = ieee80211_get_buffered_bc(ah->hw, vif);
while (skb) {
- ath5k_tx_queue(ah->hw, skb, ah->cabq);
+ ath5k_tx_queue(ah->hw, skb, ah->cabq, NULL);
if (ah->cabq->txq_len >= ah->cabq->txq_max)
break;
@@ -2442,7 +2492,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_MFP_CAPABLE |
- IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_SUPPORTS_RC_TABLE;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 6c94c7f..ca9a83c 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -47,6 +47,7 @@ struct ath5k_hw;
struct ath5k_txq;
struct ieee80211_channel;
struct ath_bus_ops;
+struct ieee80211_tx_control;
enum nl80211_iftype;
enum ath5k_srev_type {
@@ -61,11 +62,12 @@ struct ath5k_srev_name {
};
struct ath5k_buf {
- struct list_head list;
- struct ath5k_desc *desc; /* virtual addr of desc */
- dma_addr_t daddr; /* physical addr of desc */
- struct sk_buff *skb; /* skbuff for buf */
- dma_addr_t skbaddr;/* physical addr of skb data */
+ struct list_head list;
+ struct ath5k_desc *desc; /* virtual addr of desc */
+ dma_addr_t daddr; /* physical addr of desc */
+ struct sk_buff *skb; /* skbuff for buf */
+ dma_addr_t skbaddr; /* physical addr of skb data */
+ struct ieee80211_tx_rate rates[4]; /* number of multi-rate stages */
};
struct ath5k_vif {
@@ -103,7 +105,7 @@ int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ath5k_txq *txq);
+ struct ath5k_txq *txq, struct ieee80211_tx_control *control);
const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 06f86f4..81b686c 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -66,7 +66,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
return;
}
- ath5k_tx_queue(hw, skb, &ah->txqs[qnum]);
+ ath5k_tx_queue(hw, skb, &ah->txqs[qnum], control);
}
--
1.7.9.5
^ permalink raw reply related
* Re: [ath5k-devel] [PATCH v2] ath5k: make use of the new rate control API
From: Thomas Hühn @ 2013-06-07 12:47 UTC (permalink / raw)
To: Felix Fietkau
Cc: bvahl, ath5k-devel, linux-wireless, linville, johannes, rmanohar
In-Reply-To: <51B1BCE1.6080200@openwrt.org>
Hi all,
>>>
>>> diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
>>> index 7f702fe..c63759f 100644
>>> --- a/drivers/net/wireless/ath/ath5k/base.c
>>> +++ b/drivers/net/wireless/ath/ath5k/base.c
>>> @@ -1587,6 +1633,8 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
>>>
>>> ieee80211_tx_info_clear_status(info);
>>>
>>> + memcpy(info->status.rates, bf->rates, sizeof(info->status.rates));
>>> +
>>> for (i = 0; i < ts->ts_final_idx; i++) {
>>> struct ieee80211_tx_rate *r =
>>> &info->status.rates[i];
>> Please make sure that either this code is able to deal with a size
>> mismatch of info->status.rates vs. bf->rates, or that it at least fails
>> at compile time if the size of info->status.rate gets changed.
>>
Good catch, V3 is coming.
Thomas
>> - Felix
>> _______________________________________________
>> ath5k-devel mailing list
>> ath5k-devel@lists.ath5k.org
>> https://lists.ath5k.org/mailman/listinfo/ath5k-devel
>
^ permalink raw reply
* Re: [PATCH v2 1/2] rt2x00: move extra_tx_headroom field from rt2x00_ops to rt2x00_dev
From: Stanislaw Gruszka @ 2013-06-07 11:18 UTC (permalink / raw)
To: Gabor Juhos; +Cc: John Linville, linux-wireless, users
In-Reply-To: <1370504180-10950-1-git-send-email-juhosg@openwrt.org>
On Thu, Jun 06, 2013 at 09:36:19AM +0200, Gabor Juhos wrote:
> The extra_tx_headroom field of struct rt2x00_ops
> indicates the extra TX headroom size required for
> a given device. This data is redundant, the value
> can be computed from the desc_size and winfo_size
> fields of the TX queues.
>
> Move the extra_tx_headroom field to struct rt2x00_dev,
> compute its value in the probe routine and use the
> cached value in the rest of the code.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> ---
> v2:
> - remove the callbacks and compute the extra_tx_headroom
> value from winfo_size and desc_size instead
> - change subject
Thanks. For series:
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
^ permalink raw reply
* Re: [PATCH v2] ath5k: make use of the new rate control API
From: Felix Fietkau @ 2013-06-07 10:58 UTC (permalink / raw)
To: Thomas Huehn
Cc: linville, linux-wireless, johannes, mickflemm, mcgrof, rmanohar,
adrian, ath5k-devel, bvahl
In-Reply-To: <1370593505-4439-1-git-send-email-thomas@net.t-labs.tu-berlin.de>
On 2013-06-07 10:25 AM, Thomas Huehn wrote:
> This patch enabels ath5k to use the new rate table to lookup each
> mrr rate and retry information per packet.
>
> Signed-off-by: Benjamin Vahl <bvahl@net.t-labs.tu-berlin.de>
> Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
> ---
> drivers/net/wireless/ath/ath5k/base.c | 77 ++++++++++++++++++++-----
> drivers/net/wireless/ath/ath5k/base.h | 14 +++--
> drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +-
> 3 files changed, 72 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
> index 7f702fe..c63759f 100644
> --- a/drivers/net/wireless/ath/ath5k/base.c
> +++ b/drivers/net/wireless/ath/ath5k/base.c
> @@ -1587,6 +1633,8 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
>
> ieee80211_tx_info_clear_status(info);
>
> + memcpy(info->status.rates, bf->rates, sizeof(info->status.rates));
> +
> for (i = 0; i < ts->ts_final_idx; i++) {
> struct ieee80211_tx_rate *r =
> &info->status.rates[i];
Please make sure that either this code is able to deal with a size
mismatch of info->status.rates vs. bf->rates, or that it at least fails
at compile time if the size of info->status.rate gets changed.
- Felix
^ permalink raw reply
* [PATCH] brcmfmac: free primary net_device when brcmf_bus_start() fails
From: Arend van Spriel @ 2013-06-07 9:03 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
When initialization within brcmf_bus_start() fails on steps
before the brcmf_net_attach() the net_device for the primary
interface needs to be freed.
This patch resolves a panic during kernel boot as reported
by Stephen Warren.
ref.: http://mid.gmane.org/51AD1F22.2080004@wwwdotorg.org
Tested-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 2982886..8c402e7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -941,6 +941,10 @@ fail:
brcmf_fws_del_interface(ifp);
brcmf_fws_deinit(drvr);
}
+ if (drvr->iflist[0]) {
+ free_netdev(ifp->ndev);
+ drvr->iflist[0] = NULL;
+ }
if (p2p_ifp) {
free_netdev(p2p_ifp->ndev);
drvr->iflist[1] = NULL;
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2] ath5k: make use of the new rate control API
From: Thomas Huehn @ 2013-06-07 8:25 UTC (permalink / raw)
To: linville
Cc: linux-wireless, nbd, johannes, mickflemm, mcgrof, rmanohar,
adrian, ath5k-devel, bvahl
This patch enabels ath5k to use the new rate table to lookup each
mrr rate and retry information per packet.
Signed-off-by: Benjamin Vahl <bvahl@net.t-labs.tu-berlin.de>
Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
---
drivers/net/wireless/ath/ath5k/base.c | 77 ++++++++++++++++++++-----
drivers/net/wireless/ath/ath5k/base.h | 14 +++--
drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +-
3 files changed, 72 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7f702fe..c63759f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -60,6 +60,7 @@
#include <asm/unaligned.h>
+#include <net/mac80211.h>
#include "base.h"
#include "reg.h"
#include "debug.h"
@@ -666,9 +667,46 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
return htype;
}
+static struct ieee80211_rate *
+ath5k_get_rate(const struct ieee80211_hw *hw,
+ const struct ieee80211_tx_info *info,
+ struct ath5k_buf *bf, int idx)
+{
+ /*
+ * convert a ieee80211_tx_rate RC-table entry to
+ * the respective ieee80211_rate struct
+ */
+ if (bf->rates[idx].idx < 0) {
+ return NULL;
+ }
+
+ return &hw->wiphy->bands[info->band]->bitrates[ bf->rates[idx].idx ];
+}
+
+static u16
+ath5k_get_rate_hw_value(const struct ieee80211_hw *hw,
+ const struct ieee80211_tx_info *info,
+ struct ath5k_buf *bf, int idx)
+{
+ struct ieee80211_rate *rate;
+ u16 hw_rate;
+ u8 rc_flags;
+
+ rate = ath5k_get_rate(hw, info, bf, idx);
+ if (!rate)
+ return 0;
+
+ rc_flags = bf->rates[idx].flags;
+ hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+ rate->hw_value_short : rate->hw_value;
+
+ return hw_rate;
+}
+
static int
ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
- struct ath5k_txq *txq, int padsize)
+ struct ath5k_txq *txq, int padsize,
+ struct ieee80211_tx_control *control)
{
struct ath5k_desc *ds = bf->desc;
struct sk_buff *skb = bf->skb;
@@ -688,7 +726,11 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len,
DMA_TO_DEVICE);
- rate = ieee80211_get_tx_rate(ah->hw, info);
+ ieee80211_get_tx_rates(info->control.vif, (control) ? control->sta : NULL, skb, bf->rates,
+ ARRAY_SIZE(bf->rates));
+
+ rate = ath5k_get_rate(ah->hw, info, bf, 0);
+
if (!rate) {
ret = -EINVAL;
goto err_unmap;
@@ -698,8 +740,8 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
flags |= AR5K_TXDESC_NOACK;
rc_flags = info->control.rates[0].flags;
- hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
- rate->hw_value_short : rate->hw_value;
+
+ hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0);
pktlen = skb->len;
@@ -722,12 +764,13 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw,
info->control.vif, pktlen, info));
}
+
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
ieee80211_get_hdrlen_from_skb(skb), padsize,
get_hw_packet_type(skb),
(ah->ah_txpower.txp_requested * 2),
hw_rate,
- info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
+ bf->rates[0].count, keyidx, ah->ah_tx_ant, flags,
cts_rate, duration);
if (ret)
goto err_unmap;
@@ -736,13 +779,15 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
if (ah->ah_capabilities.cap_has_mrr_support) {
memset(mrr_rate, 0, sizeof(mrr_rate));
memset(mrr_tries, 0, sizeof(mrr_tries));
+
for (i = 0; i < 3; i++) {
- rate = ieee80211_get_alt_retry_rate(ah->hw, info, i);
+
+ rate = ath5k_get_rate(ah->hw, info, bf, i);
if (!rate)
break;
- mrr_rate[i] = rate->hw_value;
- mrr_tries[i] = info->control.rates[i + 1].count;
+ mrr_rate[i] = ath5k_get_rate_hw_value(ah->hw, info, bf, i);
+ mrr_tries[i] = bf->rates[i].count;
}
ath5k_hw_setup_mrr_tx_desc(ah, ds,
@@ -1515,7 +1560,7 @@ unlock:
void
ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ath5k_txq *txq)
+ struct ath5k_txq *txq, struct ieee80211_tx_control *control)
{
struct ath5k_hw *ah = hw->priv;
struct ath5k_buf *bf;
@@ -1555,7 +1600,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
bf->skb = skb;
- if (ath5k_txbuf_setup(ah, bf, txq, padsize)) {
+ if (ath5k_txbuf_setup(ah, bf, txq, padsize, control)) {
bf->skb = NULL;
spin_lock_irqsave(&ah->txbuflock, flags);
list_add_tail(&bf->list, &ah->txbuf);
@@ -1571,7 +1616,8 @@ drop_packet:
static void
ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
- struct ath5k_txq *txq, struct ath5k_tx_status *ts)
+ struct ath5k_txq *txq, struct ath5k_tx_status *ts,
+ struct ath5k_buf *bf)
{
struct ieee80211_tx_info *info;
u8 tries[3];
@@ -1587,6 +1633,8 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
ieee80211_tx_info_clear_status(info);
+ memcpy(info->status.rates, bf->rates, sizeof(info->status.rates));
+
for (i = 0; i < ts->ts_final_idx; i++) {
struct ieee80211_tx_rate *r =
&info->status.rates[i];
@@ -1663,7 +1711,7 @@ ath5k_tx_processq(struct ath5k_hw *ah, struct ath5k_txq *txq)
dma_unmap_single(ah->dev, bf->skbaddr, skb->len,
DMA_TO_DEVICE);
- ath5k_tx_frame_completed(ah, skb, txq, &ts);
+ ath5k_tx_frame_completed(ah, skb, txq, &ts, bf);
}
/*
@@ -1917,7 +1965,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
skb = ieee80211_get_buffered_bc(ah->hw, vif);
while (skb) {
- ath5k_tx_queue(ah->hw, skb, ah->cabq);
+ ath5k_tx_queue(ah->hw, skb, ah->cabq, NULL);
if (ah->cabq->txq_len >= ah->cabq->txq_max)
break;
@@ -2442,7 +2490,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_MFP_CAPABLE |
- IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_SUPPORTS_RC_TABLE;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 6c94c7f..ca9a83c 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -47,6 +47,7 @@ struct ath5k_hw;
struct ath5k_txq;
struct ieee80211_channel;
struct ath_bus_ops;
+struct ieee80211_tx_control;
enum nl80211_iftype;
enum ath5k_srev_type {
@@ -61,11 +62,12 @@ struct ath5k_srev_name {
};
struct ath5k_buf {
- struct list_head list;
- struct ath5k_desc *desc; /* virtual addr of desc */
- dma_addr_t daddr; /* physical addr of desc */
- struct sk_buff *skb; /* skbuff for buf */
- dma_addr_t skbaddr;/* physical addr of skb data */
+ struct list_head list;
+ struct ath5k_desc *desc; /* virtual addr of desc */
+ dma_addr_t daddr; /* physical addr of desc */
+ struct sk_buff *skb; /* skbuff for buf */
+ dma_addr_t skbaddr; /* physical addr of skb data */
+ struct ieee80211_tx_rate rates[4]; /* number of multi-rate stages */
};
struct ath5k_vif {
@@ -103,7 +105,7 @@ int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ath5k_txq *txq);
+ struct ath5k_txq *txq, struct ieee80211_tx_control *control);
const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 06f86f4..81b686c 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -66,7 +66,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
return;
}
- ath5k_tx_queue(hw, skb, &ah->txqs[qnum]);
+ ath5k_tx_queue(hw, skb, &ah->txqs[qnum], control);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH] ath9k: Fix merge conflict
From: Sujith Manoharan @ 2013-06-06 23:53 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
The option config option ATH9K_MAC_DEBUG has been removed
in the commit, "ath9k: Remove MAC_DEBUG".
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/Kconfig | 8 --------
1 file changed, 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 3c2cbc9..760ab3f 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -84,14 +84,6 @@ config ATH9K_DFS_CERTIFIED
developed. At this point enabling this option won't do anything
except increase code size.
-config ATH9K_MAC_DEBUG
- bool "Atheros MAC statistics"
- depends on ATH9K_DEBUGFS
- default y
- ---help---
- This option enables collection of statistics for Rx/Tx status
- data and some other MAC related statistics
-
config ATH9K_LEGACY_RATE_CONTROL
bool "Atheros ath9k rate control"
depends on ATH9K
--
1.8.3
^ permalink raw reply related
* Re: Regression in 9390ace brcmfmac: free net device when registration fails
From: Stephen Warren @ 2013-06-06 21:36 UTC (permalink / raw)
To: Arend van Spriel
Cc: John W. Linville, Hante Meuleman,
'linux-wireless@vger.kernel.org',
linux-next@vger.kernel.org
In-Reply-To: <51B0FAC0.4080709@broadcom.com>
On 06/06/2013 03:10 PM, Arend van Spriel wrote:
> On 06/04/13 14:58, Arend van Spriel wrote:
>> On 06/04/2013 12:56 AM, Stephen Warren wrote:
>>> (John, note that this commit is part of the pull request you sent to
>>> Dave today)
>>>
>>> Arend,
>>>
>>> Commit 9390ace "brcmfmac: free net device when registration fails"
>>> causes a regression.
>>>
>>> I had the BCM4330 firmware present in my root fs, whereas my HW is a
>>> BCM4329. With this patch applied, I get a kernel panic on boot. With it
>>> reverted, I see that no issues of that nature. This is true in
>>> next-20130531 (and also 5/30 and 6/1 but not earlier). A bisect of
>>> Linus's tree followed by a merge of John's wireless pull request from
>>> today pointed at this same commit.
>>
>> Thanks, Stephen
>>
>> I will look into this.
>
> Hi Stephen,
>
> Can you try the attached patch? If it does not solve the issue, could
> you provide a log.
Yes, that works great, thanks.
Tested-by: Stephen Warren <swarren@nvidia.com>
>>> Related: Since the two hardware require different firmware, I wonder why
>>> the driver doesn't use a firmware filename that encodes the HW device ID
>>> instead of using the same name for all HW. This means that when I move
>>> my SD card between development systems, I have to copy different
>>> firmware over the top. That's a little painful...
>>
>> I agree that for development switching cards it is kinda awkward and I
>> have been fooled by it as well. We may want to change or if your itch is
>> annoying enough feel free to send a patch for it ;-)
>
> We have a patch for this that we can submit to wireless-next.
Oh, great! If you could Cc me, that'd be helpful, since I'm not on that
list. Thanks.
^ permalink raw reply
* Re: stop_machine lockup issue in 3.9.y.
From: Tejun Heo @ 2013-06-06 21:17 UTC (permalink / raw)
To: Ben Greear
Cc: Eric Dumazet, Rusty Russell, Joe Lawrence,
Linux Kernel Mailing List, stable, Luis R. Rodriguez,
Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian,
linux-wireless, ath9k-devel, Thomas Gleixner, Ingo Molnar
In-Reply-To: <51B0FBFC.8040809@candelatech.com>
On Thu, Jun 06, 2013 at 02:15:40PM -0700, Ben Greear wrote:
> >First of all, kudos for tracking the issue down. While the removal of
> >looping limit in softirq handling was the direct cause for making the
> >problem visible, it's very bothering that we have softirq runaway.
> >Finding out the perpetrator shouldn't be hard. Something like the
> >following should work (untested). Once we know which softirq (prolly
> >the network one), we can dig deeper.
>
> The patch below assumes my fix is not in the code, right?
Yeap.
> I'll work on this, but it will probably be next week before
> I have time...gotta catch up on some other things first.
Thanks a lot for hunting this down!
--
tejun
^ permalink raw reply
* Re: stop_machine lockup issue in 3.9.y.
From: Ben Greear @ 2013-06-06 21:15 UTC (permalink / raw)
To: Tejun Heo
Cc: Eric Dumazet, Rusty Russell, Joe Lawrence,
Linux Kernel Mailing List, stable, Luis R. Rodriguez,
Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian,
linux-wireless, ath9k-devel, Thomas Gleixner, Ingo Molnar
In-Reply-To: <20130606205514.GC5045@htj.dyndns.org>
On 06/06/2013 01:55 PM, Tejun Heo wrote:
> Hello, Ben.
>
> On Wed, Jun 05, 2013 at 08:41:01PM -0700, Ben Greear wrote:
>> On 06/05/2013 08:26 PM, Eric Dumazet wrote:
>>> On Wed, 2013-06-05 at 20:14 -0700, Tejun Heo wrote:
>>>> Ah, so, that's why it's showing up now. We probably have had the same
>>>> issue all along but it used to be masked by the softirq limiting. Do
>>>> you care to revive the 10 iterations limit so that it's limited by
>>>> both the count and timing? We do wanna find out why softirq is
>>>> spinning indefinitely tho.
>>>
>>> Yes, no problem, I can do that.
>>
>> Limiting it to 5000 fixes my problem, so if you wanted it larger than 10, that would
>> be fine by me.
>
> First of all, kudos for tracking the issue down. While the removal of
> looping limit in softirq handling was the direct cause for making the
> problem visible, it's very bothering that we have softirq runaway.
> Finding out the perpetrator shouldn't be hard. Something like the
> following should work (untested). Once we know which softirq (prolly
> the network one), we can dig deeper.
The patch below assumes my fix is not in the code, right?
I'll work on this, but it will probably be next week before
I have time...gotta catch up on some other things first.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: Regression in 9390ace brcmfmac: free net device when registration fails
From: Arend van Spriel @ 2013-06-06 21:10 UTC (permalink / raw)
To: Stephen Warren
Cc: John W. Linville, Hante Meuleman,
'linux-wireless@vger.kernel.org',
linux-next@vger.kernel.org
In-Reply-To: <51ADE47D.50700@broadcom.com>
[-- Attachment #1: Type: text/plain, Size: 1468 bytes --]
On 06/04/13 14:58, Arend van Spriel wrote:
> On 06/04/2013 12:56 AM, Stephen Warren wrote:
>> (John, note that this commit is part of the pull request you sent to
>> Dave today)
>>
>> Arend,
>>
>> Commit 9390ace "brcmfmac: free net device when registration fails"
>> causes a regression.
>>
>> I had the BCM4330 firmware present in my root fs, whereas my HW is a
>> BCM4329. With this patch applied, I get a kernel panic on boot. With it
>> reverted, I see that no issues of that nature. This is true in
>> next-20130531 (and also 5/30 and 6/1 but not earlier). A bisect of
>> Linus's tree followed by a merge of John's wireless pull request from
>> today pointed at this same commit.
>
> Thanks, Stephen
>
> I will look into this.
Hi Stephen,
Can you try the attached patch? If it does not solve the issue, could
you provide a log.
>> Related: Since the two hardware require different firmware, I wonder why
>> the driver doesn't use a firmware filename that encodes the HW device ID
>> instead of using the same name for all HW. This means that when I move
>> my SD card between development systems, I have to copy different
>> firmware over the top. That's a little painful...
>
> I agree that for development switching cards it is kinda awkward and I
> have been fooled by it as well. We may want to change or if your itch is
> annoying enough feel free to send a patch for it ;-)
We have a patch for this that we can submit to wireless-next.
Regards,
Arend
[-- Attachment #2: 0001-brcmfmac-free-primary-net_device-when-brcmf_bus_star.patch --]
[-- Type: text/plain, Size: 1080 bytes --]
>From 2c0bf2dc8ecf91175a4b9a28dc2c4e84aceee4cf Mon Sep 17 00:00:00 2001
From: Arend van Spriel <arend@broadcom.com>
Date: Thu, 6 Jun 2013 22:43:41 +0200
Subject: [PATCH] brcmfmac: free primary net_device when brcmf_bus_start()
fails
When initialization within brcmf_bus_start() fails on steps
before the brcmf_net_attach() the net_device for the primary
interface needs to be freed.
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 63cadf6..d7cf98e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -941,6 +941,10 @@ fail:
brcmf_fws_del_interface(ifp);
brcmf_fws_deinit(drvr);
}
+ if (drvr->iflist[0]) {
+ free_netdev(ipf->ndev);
+ drvr->iflist[0] = NULL;
+ }
if (p2p_ifp) {
free_netdev(p2p_ifp->ndev);
drvr->iflist[1] = NULL;
--
1.7.10.4
^ permalink raw reply related
* Re: stop_machine lockup issue in 3.9.y.
From: Tejun Heo @ 2013-06-06 20:55 UTC (permalink / raw)
To: Ben Greear
Cc: Eric Dumazet, Rusty Russell, Joe Lawrence,
Linux Kernel Mailing List, stable, Luis R. Rodriguez,
Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian,
linux-wireless, ath9k-devel, Thomas Gleixner, Ingo Molnar
In-Reply-To: <51B004CD.6080007@candelatech.com>
Hello, Ben.
On Wed, Jun 05, 2013 at 08:41:01PM -0700, Ben Greear wrote:
> On 06/05/2013 08:26 PM, Eric Dumazet wrote:
> >On Wed, 2013-06-05 at 20:14 -0700, Tejun Heo wrote:
> >>Ah, so, that's why it's showing up now. We probably have had the same
> >>issue all along but it used to be masked by the softirq limiting. Do
> >>you care to revive the 10 iterations limit so that it's limited by
> >>both the count and timing? We do wanna find out why softirq is
> >>spinning indefinitely tho.
> >
> >Yes, no problem, I can do that.
>
> Limiting it to 5000 fixes my problem, so if you wanted it larger than 10, that would
> be fine by me.
First of all, kudos for tracking the issue down. While the removal of
looping limit in softirq handling was the direct cause for making the
problem visible, it's very bothering that we have softirq runaway.
Finding out the perpetrator shouldn't be hard. Something like the
following should work (untested). Once we know which softirq (prolly
the network one), we can dig deeper.
Thanks.
diff --git a/kernel/softirq.c b/kernel/softirq.c
index b5197dc..5af3682 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -212,6 +212,7 @@ asmlinkage void __do_softirq(void)
unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
int cpu;
unsigned long old_flags = current->flags;
+ int cnt = 0;
/*
* Mask out PF_MEMALLOC s current task context is borrowed for the
@@ -244,6 +245,9 @@ restart:
kstat_incr_softirqs_this_cpu(vec_nr);
trace_softirq_entry(vec_nr);
+ if (++cnt >= 5000 && cnt < 5010)
+ printk("XXX __do_softirq: stuck handling softirqs, cnt=%d action=%pf\n",
+ cnt, h->action);
h->action(h);
trace_softirq_exit(vec_nr);
if (unlikely(prev_count != preempt_count())) {
--
tejun
^ permalink raw reply related
* Re: carl9170:5/10 MHz Channel Support on carl9170
From: Christian Lamparter @ 2013-06-06 20:53 UTC (permalink / raw)
To: linux-wireless; +Cc: C.B. Wang
In-Reply-To: <CAB-Tk72epLsrQZ36bD2+RGDJgrMiYbMaK8-82=NQ8_fon8NQMw@mail.gmail.com>
(Readded ML).
On Thursday, June 06, 2013 02:21:58 PM C.B. Wang wrote:
> > maybe by the ar7010+ar92xy combo
> Yes.The ar9280 and ar9285 all support spectral analysis.Will
> ar9170+ar9104 combo also do the job?
No idea. I don't have the PHY docs, just the MAC.
> >Can you tell me on what page/chapter?
> On page 19,chapter 17,it says "The OFDM system also provides a
> “half-clocked” operation using 10 MHz channel spacings with data com-
> munications capabilities of 3, 4.5, 6, 9, 12, 18, 24, and 27 Mbit/s."
> Also on page 31,there's a table describing OFDM PHY characteristics of
> 20MHz and 10MHz channel spacing for 802.11j.
Different page numbers here. So let's just stick to the chapter.
Anyway, If I'm reading it correctly it looks like OF1.7 aka
"10 MHz Channel spacing" is marked as an "O"ptional feature in A4.8.
The same seems to be true for the 4.9 GHz band (marked as optional
in OF3.12 in this old doc)?!
So, was this all a bit pointless? Because, as far as I can tell the
driver is 802.11j "compliant" as it is. Therefore let's close the
case with: "al[l|ready] done!".
Regards,
Chr
^ permalink raw reply
* pull request: wireless 2013-06-06
From: John W. Linville @ 2013-06-06 19:09 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 49370 bytes --]
Dave,
This pull request includes the non-Broadcom bits of the rejected pull
request, plus a few more accumulated fixes from the past week or so.
Among the latter are a couple of ath9k fixes intended to address the
problems observed by Linus w/ his Pixel, and a CVE fix for a potential
security issue in the b43 driver.
For the mac80211 bits, Johannes says:
"Here's one more fix for mac80211 (along with a constify patch it depends
on) to work around problems with certain (broken) APs that forget to
include HT IEs in their association responses."
Regarding the wl12xx bits, Luca says:
"Here are three patches that I'd like to get into 3.10. Two of them, by
me, are related to the firmware version checks in our driver. Without
them, the firmwares fail to load. The other one, by Eliad, fixes a typo
bug in our 5GHz scanning code."
And as for the Bluetooth bits, Gustavo says:
"The following patches are important bug fixes for 3.10, plus the
support for a new device. We do have three fixes from Johan. The first
one is a fix to avoid LE-only devices to rely on the (inexistent)
extended features data. The second patch fixes length checks on
incoming L2CAP signalling PDUs so we can discard PDU whose size
doesn't match the one reported in the header. The last one fixes
the handling of power on failures, we now report proper errors to
mgmt when hci_dev_open()."
Along with that...
Larry Finger corrects an rtlwifi problem that caused some devices to
refuse to connect to non-WPA2 networks if the device had previously
assocated with a WPA2 network. He also adds a one-line fix to prevent
false reports from kmemleak.
Mark A. Greer fixes an out of bounds array access in mwifiex.
Felix Fietkau reverts an earlier ath9k initval patch that reduced rx
sensitivity in a number of ath9k devices with no corresponding benefit.
Kees Cook fixes a potential uid-0 to ring-0 escalation in b43
(CVE-2013-2852).
Sujith Manoharan turns-off powersave mode by default for ath9k, and
also defaults ath9k to use the minstrel_ht rate control algorithm.
Both of these are believed to contribute to greater stability/usability
of ath9k in real-world situations.
Yijing Wang fixes an iwlegacy build error for il_pm_ops if CONFIG_PM
is set but CONFIG_PM_SLEEP is not set.
Please let me know if there are any problems!
Thanks,
John
---
The following changes since commit 4d3797d7e1861ac1af150a6189315786c5e1c820:
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2013-06-05 19:19:04 +0900)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
for you to fetch changes up to 97cc281d75c6dcc7466c8d356112bc13a31300a7:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-06-06 09:55:08 -0400)
----------------------------------------------------------------
Bing Zhao (1):
Bluetooth: btmrvl: support Marvell Bluetooth device SD8897
Eliad Peller (1):
wl12xx/wl18xx: scan all 5ghz channels
Felix Fietkau (1):
Revert "ath9k_hw: Update rx gain initval to improve rx sensitivity"
Johan Hedberg (3):
Bluetooth: Fix checks for LE support on LE-only controllers
Bluetooth: Fix missing length checks for L2CAP signalling PDUs
Bluetooth: Fix mgmt handling of power on failures
Johannes Berg (2):
mac80211: constify ieee802_11_parse_elems() argument
mac80211: work around broken APs not including HT info
John W. Linville (2):
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Kees Cook (1):
b43: stop format string leaking into error msgs
Larry Finger (2):
rtlwifi: rtl8192cu: Fix problem in connecting to WEP or WPA(1) networks
rtlwifi: Fix a false leak indication for PCI devices
Luciano Coelho (2):
wl12xx: fix minimum required firmware version for wl127x multirole
wl12xx: increase minimum singlerole firmware version required
Mark A. Greer (1):
mwifiex: debugfs: Fix out of bounds array access
Sujith Manoharan (2):
ath9k: Disable PowerSave by default
ath9k: Use minstrel rate control by default
Yijing Wang (1):
net: wireless: iwlegacy: fix build error for il_pm_ops
drivers/bluetooth/Kconfig | 4 +-
drivers/bluetooth/btmrvl_sdio.c | 28 +++++
drivers/net/wireless/ath/ath9k/Kconfig | 10 +-
drivers/net/wireless/ath/ath9k/Makefile | 2 +-
.../net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 10 +-
drivers/net/wireless/ath/ath9k/init.c | 7 +-
drivers/net/wireless/ath/ath9k/rc.h | 2 +-
drivers/net/wireless/b43/main.c | 2 +-
drivers/net/wireless/iwlegacy/common.h | 6 +-
drivers/net/wireless/mwifiex/debugfs.c | 22 +++-
drivers/net/wireless/rtlwifi/pci.c | 1 +
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 134 +++++++++++++++------
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | 4 -
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 18 ++-
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 4 +-
drivers/net/wireless/rtlwifi/rtl8192cu/sw.h | 3 +
drivers/net/wireless/rtlwifi/usb.c | 13 ++
drivers/net/wireless/rtlwifi/wifi.h | 4 +
drivers/net/wireless/ti/wl12xx/scan.c | 2 +-
drivers/net/wireless/ti/wl12xx/wl12xx.h | 6 +-
drivers/net/wireless/ti/wl18xx/scan.c | 2 +-
include/net/bluetooth/hci_core.h | 1 +
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/hci_core.c | 6 +-
net/bluetooth/l2cap_core.c | 70 ++++++++---
net/bluetooth/mgmt.c | 23 +++-
net/bluetooth/smp.c | 4 +-
net/mac80211/ieee80211_i.h | 5 +-
net/mac80211/mlme.c | 87 +++++++++++--
net/mac80211/util.c | 4 +-
30 files changed, 379 insertions(+), 106 deletions(-)
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index fdfd61a..11a6104 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -201,7 +201,7 @@ config BT_MRVL
The core driver to support Marvell Bluetooth devices.
This driver is required if you want to support
- Marvell Bluetooth devices, such as 8688/8787/8797.
+ Marvell Bluetooth devices, such as 8688/8787/8797/8897.
Say Y here to compile Marvell Bluetooth driver
into the kernel or say M to compile it as module.
@@ -214,7 +214,7 @@ config BT_MRVL_SDIO
The driver for Marvell Bluetooth chipsets with SDIO interface.
This driver is required if you want to use Marvell Bluetooth
- devices with SDIO interface. Currently SD8688/SD8787/SD8797
+ devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8897
chipsets are supported.
Say Y here to compile support for Marvell BT-over-SDIO driver
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index c63488c..13693b7 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -82,6 +82,23 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
.io_port_2 = 0x7a,
};
+static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
+ .cfg = 0x00,
+ .host_int_mask = 0x02,
+ .host_intstatus = 0x03,
+ .card_status = 0x50,
+ .sq_read_base_addr_a0 = 0x60,
+ .sq_read_base_addr_a1 = 0x61,
+ .card_revision = 0xbc,
+ .card_fw_status0 = 0xc0,
+ .card_fw_status1 = 0xc1,
+ .card_rx_len = 0xc2,
+ .card_rx_unit = 0xc3,
+ .io_port_0 = 0xd8,
+ .io_port_1 = 0xd9,
+ .io_port_2 = 0xda,
+};
+
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
@@ -103,6 +120,13 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.sd_blksz_fw_dl = 256,
};
+static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
+ .helper = NULL,
+ .firmware = "mrvl/sd8897_uapsta.bin",
+ .reg = &btmrvl_reg_88xx,
+ .sd_blksz_fw_dl = 256,
+};
+
static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8688 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
@@ -116,6 +140,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8797 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
.driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
+ /* Marvell SD8897 Bluetooth device */
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E),
+ .driver_data = (unsigned long) &btmrvl_sdio_sd8897 },
{ } /* Terminating entry */
};
@@ -1194,3 +1221,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
MODULE_FIRMWARE("mrvl/sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
+MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index f3dc124..3c2cbc9 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -92,13 +92,17 @@ config ATH9K_MAC_DEBUG
This option enables collection of statistics for Rx/Tx status
data and some other MAC related statistics
-config ATH9K_RATE_CONTROL
+config ATH9K_LEGACY_RATE_CONTROL
bool "Atheros ath9k rate control"
depends on ATH9K
- default y
+ default n
---help---
Say Y, if you want to use the ath9k specific rate control
- module instead of minstrel_ht.
+ module instead of minstrel_ht. Be warned that there are various
+ issues with the ath9k RC and minstrel is a more robust algorithm.
+ Note that even if this option is selected, "ath9k_rate_control"
+ has to be passed to mac80211 using the module parameter,
+ ieee80211_default_rc_algo.
config ATH9K_HTC
tristate "Atheros HTC based wireless cards support"
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 2ad8f94..75ee9e7 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -8,7 +8,7 @@ ath9k-y += beacon.o \
antenna.o
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
-ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
+ath9k-$(CONFIG_ATH9K_LEGACY_RATE_CONTROL) += rc.o
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index db5ffad..7546b9a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
{0x0000a074, 0x00000000},
{0x0000a078, 0x00000000},
{0x0000a07c, 0x00000000},
- {0x0000a080, 0x1a1a1a1a},
- {0x0000a084, 0x1a1a1a1a},
- {0x0000a088, 0x1a1a1a1a},
- {0x0000a08c, 0x1a1a1a1a},
- {0x0000a090, 0x171a1a1a},
+ {0x0000a080, 0x22222229},
+ {0x0000a084, 0x1d1d1d1d},
+ {0x0000a088, 0x1d1d1d1d},
+ {0x0000a08c, 0x1d1d1d1d},
+ {0x0000a090, 0x171d1d1d},
{0x0000a094, 0x11111717},
{0x0000a098, 0x00030311},
{0x0000a09c, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index aba4151..2ba4945 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -787,8 +787,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->wiphy->iface_combinations = if_comb;
hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
- if (AR_SREV_5416(sc->sc_ah))
- hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
@@ -830,10 +829,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
sc->ant_rx = hw->wiphy->available_antennas_rx;
sc->ant_tx = hw->wiphy->available_antennas_tx;
-#ifdef CONFIG_ATH9K_RATE_CONTROL
- hw->rate_control_algorithm = "ath9k_rate_control";
-#endif
-
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&sc->sbands[IEEE80211_BAND_2GHZ];
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 267dbfc..b9a8738 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -231,7 +231,7 @@ static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
}
#endif
-#ifdef CONFIG_ATH9K_RATE_CONTROL
+#ifdef CONFIG_ATH9K_LEGACY_RATE_CONTROL
int ath_rate_control_register(void);
void ath_rate_control_unregister(void);
#else
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 6dd07e2..a95b77a 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2458,7 +2458,7 @@ static void b43_request_firmware(struct work_struct *work)
for (i = 0; i < B43_NR_FWTYPES; i++) {
errmsg = ctx->errors[i];
if (strlen(errmsg))
- b43err(dev->wl, errmsg);
+ b43err(dev->wl, "%s", errmsg);
}
b43_print_fw_helptext(dev->wl, 1);
goto out;
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index f8246f2..4caaf52 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1832,16 +1832,16 @@ u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval);
__le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
u32 beacon_interval);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
extern const struct dev_pm_ops il_pm_ops;
#define IL_LEGACY_PM_OPS (&il_pm_ops)
-#else /* !CONFIG_PM */
+#else /* !CONFIG_PM_SLEEP */
#define IL_LEGACY_PM_OPS NULL
-#endif /* !CONFIG_PM */
+#endif /* !CONFIG_PM_SLEEP */
/*****************************************************
* Error Handling Debugging
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 753b568..a5f9875 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -26,10 +26,17 @@
static struct dentry *mwifiex_dfs_dir;
static char *bss_modes[] = {
- "Unknown",
- "Ad-hoc",
- "Managed",
- "Auto"
+ "UNSPECIFIED",
+ "ADHOC",
+ "STATION",
+ "AP",
+ "AP_VLAN",
+ "WDS",
+ "MONITOR",
+ "MESH_POINT",
+ "P2P_CLIENT",
+ "P2P_GO",
+ "P2P_DEVICE",
};
/* size/addr for mwifiex_debug_info */
@@ -200,7 +207,12 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
p += sprintf(p, "driver_version = %s", fmt);
p += sprintf(p, "\nverext = %s", priv->version_str);
p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
- p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
+
+ if (info.bss_mode >= ARRAY_SIZE(bss_modes))
+ p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode);
+ else
+ p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
+
p += sprintf(p, "media_state=\"%s\"\n",
(!priv->media_connected ? "Disconnected" : "Connected"));
p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 999ffc1..c97e9d3 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -764,6 +764,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
"can't alloc skb for rx\n");
goto done;
}
+ kmemleak_not_leak(new_skb);
pci_unmap_single(rtlpci->pdev,
*((dma_addr_t *) skb->cb),
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 3d0498e..189ba12 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1973,26 +1973,35 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
}
}
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
- struct ieee80211_sta *sta,
- u8 rssi_level)
+static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- u32 ratr_value = (u32) mac->basic_rates;
- u8 *mcsrate = mac->mcs;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ u32 ratr_value;
u8 ratr_index = 0;
u8 nmode = mac->ht_enable;
- u8 mimo_ps = 1;
- u16 shortgi_rate = 0;
- u32 tmp_ratr_value = 0;
+ u8 mimo_ps = IEEE80211_SMPS_OFF;
+ u16 shortgi_rate;
+ u32 tmp_ratr_value;
u8 curtxbw_40mhz = mac->bw_40;
- u8 curshortgi_40mhz = mac->sgi_40;
- u8 curshortgi_20mhz = mac->sgi_20;
+ u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ 1 : 0;
+ u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+ 1 : 0;
enum wireless_mode wirelessmode = mac->mode;
- ratr_value |= ((*(u16 *) (mcsrate))) << 12;
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ ratr_value = sta->supp_rates[1] << 4;
+ else
+ ratr_value = sta->supp_rates[0];
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ ratr_value = 0xfff;
+
+ ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+ sta->ht_cap.mcs.rx_mask[0] << 12);
switch (wirelessmode) {
case WIRELESS_MODE_B:
if (ratr_value & 0x0000000c)
@@ -2006,7 +2015,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
case WIRELESS_MODE_N_24G:
case WIRELESS_MODE_N_5G:
nmode = 1;
- if (mimo_ps == 0) {
+ if (mimo_ps == IEEE80211_SMPS_STATIC) {
ratr_value &= 0x0007F005;
} else {
u32 ratr_mask;
@@ -2016,8 +2025,7 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
ratr_mask = 0x000ff005;
else
ratr_mask = 0x0f0ff005;
- if (curtxbw_40mhz)
- ratr_mask |= 0x00000010;
+
ratr_value &= ratr_mask;
}
break;
@@ -2026,41 +2034,74 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
ratr_value &= 0x000ff0ff;
else
ratr_value &= 0x0f0ff0ff;
+
break;
}
+
ratr_value &= 0x0FFFFFFF;
- if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
- (!curtxbw_40mhz && curshortgi_20mhz))) {
+
+ if (nmode && ((curtxbw_40mhz &&
+ curshortgi_40mhz) || (!curtxbw_40mhz &&
+ curshortgi_20mhz))) {
+
ratr_value |= 0x10000000;
tmp_ratr_value = (ratr_value >> 12);
+
for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
if ((1 << shortgi_rate) & tmp_ratr_value)
break;
}
+
shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
- (shortgi_rate << 4) | (shortgi_rate);
+ (shortgi_rate << 4) | (shortgi_rate);
}
+
rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
+
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+ rtl_read_dword(rtlpriv, REG_ARFR0));
}
-void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
+static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ u8 rssi_level)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_phy *rtlphy = &(rtlpriv->phy);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- u32 ratr_bitmap = (u32) mac->basic_rates;
- u8 *p_mcsrate = mac->mcs;
- u8 ratr_index = 0;
- u8 curtxbw_40mhz = mac->bw_40;
- u8 curshortgi_40mhz = mac->sgi_40;
- u8 curshortgi_20mhz = mac->sgi_20;
- enum wireless_mode wirelessmode = mac->mode;
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
+ u32 ratr_bitmap;
+ u8 ratr_index;
+ u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0;
+ u8 curshortgi_40mhz = curtxbw_40mhz &&
+ (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ 1 : 0;
+ u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+ 1 : 0;
+ enum wireless_mode wirelessmode = 0;
bool shortgi = false;
u8 rate_mask[5];
u8 macid = 0;
- u8 mimops = 1;
-
- ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
+ u8 mimo_ps = IEEE80211_SMPS_OFF;
+
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ wirelessmode = sta_entry->wireless_mode;
+ if (mac->opmode == NL80211_IFTYPE_STATION ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT)
+ curtxbw_40mhz = mac->bw_40;
+ else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC)
+ macid = sta->aid + 1;
+
+ if (rtlhal->current_bandtype == BAND_ON_5G)
+ ratr_bitmap = sta->supp_rates[1] << 4;
+ else
+ ratr_bitmap = sta->supp_rates[0];
+ if (mac->opmode == NL80211_IFTYPE_ADHOC)
+ ratr_bitmap = 0xfff;
+ ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+ sta->ht_cap.mcs.rx_mask[0] << 12);
switch (wirelessmode) {
case WIRELESS_MODE_B:
ratr_index = RATR_INX_WIRELESS_B;
@@ -2071,6 +2112,7 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
break;
case WIRELESS_MODE_G:
ratr_index = RATR_INX_WIRELESS_GB;
+
if (rssi_level == 1)
ratr_bitmap &= 0x00000f00;
else if (rssi_level == 2)
@@ -2085,7 +2127,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
case WIRELESS_MODE_N_24G:
case WIRELESS_MODE_N_5G:
ratr_index = RATR_INX_WIRELESS_NGB;
- if (mimops == 0) {
+
+ if (mimo_ps == IEEE80211_SMPS_STATIC) {
if (rssi_level == 1)
ratr_bitmap &= 0x00070000;
else if (rssi_level == 2)
@@ -2128,8 +2171,10 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
}
}
}
+
if ((curtxbw_40mhz && curshortgi_40mhz) ||
(!curtxbw_40mhz && curshortgi_20mhz)) {
+
if (macid == 0)
shortgi = true;
else if (macid == 1)
@@ -2138,21 +2183,42 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
break;
default:
ratr_index = RATR_INX_WIRELESS_NGB;
+
if (rtlphy->rf_type == RF_1T2R)
ratr_bitmap &= 0x000ff0ff;
else
ratr_bitmap &= 0x0f0ff0ff;
break;
}
- RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n",
- ratr_bitmap);
- *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
- ratr_index << 28);
+ sta_entry->ratr_index = ratr_index;
+
+ RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+ "ratr_bitmap :%x\n", ratr_bitmap);
+ *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
+ (ratr_index << 28);
rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
"Rate_index:%x, ratr_val:%x, %5phC\n",
ratr_index, ratr_bitmap, rate_mask);
- rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
+ memcpy(rtlpriv->rate_mask, rate_mask, 5);
+ /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a
+ * "scheduled while atomic" if called directly */
+ schedule_work(&rtlpriv->works.fill_h2c_cmd);
+
+ if (macid != 0)
+ sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ u8 rssi_level)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ if (rtlpriv->dm.useramask)
+ rtl92cu_update_hal_rate_mask(hw, sta, rssi_level);
+ else
+ rtl92cu_update_hal_rate_table(hw, sta);
}
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
index f41a3aa..8e3ec1e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
@@ -98,10 +98,6 @@ void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
u32 add_msr, u32 rm_msr);
void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
- struct ieee80211_sta *sta,
- u8 rssi_level);
-void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index 85b6bdb..da4f587 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -289,14 +289,30 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
macaddr = cam_const_broad;
entry_id = key_index;
} else {
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ entry_id = rtl_cam_get_free_entry(hw,
+ p_macaddr);
+ if (entry_id >= TOTAL_CAM_ENTRY) {
+ RT_TRACE(rtlpriv, COMP_SEC,
+ DBG_EMERG,
+ "Can not find free hw security cam entry\n");
+ return;
+ }
+ } else {
+ entry_id = CAM_PAIRWISE_KEY_POSITION;
+ }
+
key_index = PAIRWISE_KEYIDX;
- entry_id = CAM_PAIRWISE_KEY_POSITION;
is_pairwise = true;
}
}
if (rtlpriv->sec.key_len[key_index] == 0) {
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
"delete one entry\n");
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT)
+ rtl_cam_del_entry(hw, p_macaddr);
rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
} else {
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 938b1e6..826f085 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -106,8 +106,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
.update_interrupt_mask = rtl92cu_update_interrupt_mask,
.get_hw_reg = rtl92cu_get_hw_reg,
.set_hw_reg = rtl92cu_set_hw_reg,
- .update_rate_tbl = rtl92cu_update_hal_rate_table,
- .update_rate_mask = rtl92cu_update_hal_rate_mask,
+ .update_rate_tbl = rtl92cu_update_hal_rate_tbl,
.fill_tx_desc = rtl92cu_tx_fill_desc,
.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
.fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc,
@@ -137,6 +136,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
.phy_lc_calibrate = _rtl92cu_phy_lc_calibrate,
.phy_set_bw_mode_callback = rtl92cu_phy_set_bw_mode_callback,
.dm_dynamic_txpower = rtl92cu_dm_dynamic_txpower,
+ .fill_h2c_cmd = rtl92c_fill_h2c_cmd,
};
static struct rtl_mod_params rtl92cu_mod_params = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
index a1310ab..262e1e4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
@@ -49,5 +49,8 @@ bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
enum radio_path rfpath, u32 regaddr, u32 bitmask);
void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ u8 rssi_level);
#endif
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 76732b0..a3532e0 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -824,6 +824,7 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
/* should after adapter start and interrupt enable. */
set_hal_stop(rtlhal);
+ cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
/* Enable software */
SET_USB_STOP(rtlusb);
rtl_usb_deinit(hw);
@@ -1026,6 +1027,16 @@ static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw,
return false;
}
+static void rtl_fill_h2c_cmd_work_callback(struct work_struct *work)
+{
+ struct rtl_works *rtlworks =
+ container_of(work, struct rtl_works, fill_h2c_cmd);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->cfg->ops->fill_h2c_cmd(hw, H2C_RA_MASK, 5, rtlpriv->rate_mask);
+}
+
static struct rtl_intf_ops rtl_usb_ops = {
.adapter_start = rtl_usb_start,
.adapter_stop = rtl_usb_stop,
@@ -1057,6 +1068,8 @@ int rtl_usb_probe(struct usb_interface *intf,
/* this spin lock must be initialized early */
spin_lock_init(&rtlpriv->locks.usb_lock);
+ INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
+ rtl_fill_h2c_cmd_work_callback);
rtlpriv->usb_data_index = 0;
init_completion(&rtlpriv->firmware_loading_complete);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 44328ba..cc03e7c 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1736,6 +1736,8 @@ struct rtl_hal_ops {
void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw,
bool mstate);
void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw);
+ void (*fill_h2c_cmd) (struct ieee80211_hw *hw, u8 element_id,
+ u32 cmd_len, u8 *p_cmdbuffer);
};
struct rtl_intf_ops {
@@ -1869,6 +1871,7 @@ struct rtl_works {
struct delayed_work fwevt_wq;
struct work_struct lps_change_work;
+ struct work_struct fill_h2c_cmd;
};
struct rtl_debug {
@@ -2048,6 +2051,7 @@ struct rtl_priv {
};
};
bool enter_ps; /* true when entering PS */
+ u8 rate_mask[5];
/*This must be the last item so
that it points to the data allocated
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c
index affdb3e..4a0bbb1 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wl12xx/scan.c
@@ -310,7 +310,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
memcpy(cmd->channels_2, cmd_channels->channels_2,
sizeof(cmd->channels_2));
memcpy(cmd->channels_5, cmd_channels->channels_5,
- sizeof(cmd->channels_2));
+ sizeof(cmd->channels_5));
/* channels_4 are not supported, so no need to copy them */
}
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index 222d035..9e5484a 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -36,12 +36,12 @@
#define WL127X_IFTYPE_SR_VER 3
#define WL127X_MAJOR_SR_VER 10
#define WL127X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
-#define WL127X_MINOR_SR_VER 115
+#define WL127X_MINOR_SR_VER 133
/* minimum multi-role FW version for wl127x */
#define WL127X_IFTYPE_MR_VER 5
#define WL127X_MAJOR_MR_VER 7
#define WL127X_SUBTYPE_MR_VER WLCORE_FW_VER_IGNORE
-#define WL127X_MINOR_MR_VER 115
+#define WL127X_MINOR_MR_VER 42
/* FW chip version for wl128x */
#define WL128X_CHIP_VER 7
@@ -49,7 +49,7 @@
#define WL128X_IFTYPE_SR_VER 3
#define WL128X_MAJOR_SR_VER 10
#define WL128X_SUBTYPE_SR_VER WLCORE_FW_VER_IGNORE
-#define WL128X_MINOR_SR_VER 115
+#define WL128X_MINOR_SR_VER 133
/* minimum multi-role FW version for wl128x */
#define WL128X_IFTYPE_MR_VER 5
#define WL128X_MAJOR_MR_VER 7
diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c
index 09d9445..2b642f8 100644
--- a/drivers/net/wireless/ti/wl18xx/scan.c
+++ b/drivers/net/wireless/ti/wl18xx/scan.c
@@ -34,7 +34,7 @@ static void wl18xx_adjust_channels(struct wl18xx_cmd_scan_params *cmd,
memcpy(cmd->channels_2, cmd_channels->channels_2,
sizeof(cmd->channels_2));
memcpy(cmd->channels_5, cmd_channels->channels_5,
- sizeof(cmd->channels_2));
+ sizeof(cmd->channels_5));
/* channels_4 are not supported, so no need to copy them */
}
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 35a57cd..7cb6d36 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1117,6 +1117,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_index_added(struct hci_dev *hdev);
int mgmt_index_removed(struct hci_dev *hdev);
+int mgmt_set_powered_failed(struct hci_dev *hdev, int err);
int mgmt_powered(struct hci_dev *hdev, u8 powered);
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 22980a7..9944c3e 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -42,6 +42,7 @@
#define MGMT_STATUS_NOT_POWERED 0x0f
#define MGMT_STATUS_CANCELLED 0x10
#define MGMT_STATUS_INVALID_INDEX 0x11
+#define MGMT_STATUS_RFKILLED 0x12
struct mgmt_hdr {
__le16 opcode;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 33843c5..d817c93 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = {
static void hci_power_on(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev, power_on);
+ int err;
BT_DBG("%s", hdev->name);
- if (hci_dev_open(hdev->id) < 0)
+ err = hci_dev_open(hdev->id);
+ if (err < 0) {
+ mgmt_set_powered_failed(hdev, err);
return;
+ }
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a76d1ac..24bee07 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3677,10 +3677,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
}
static inline int l2cap_command_rej(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
{
struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data;
+ if (cmd_len < sizeof(*rej))
+ return -EPROTO;
+
if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD)
return 0;
@@ -3829,11 +3833,14 @@ sendresp:
}
static int l2cap_connect_req(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{
struct hci_dev *hdev = conn->hcon->hdev;
struct hci_conn *hcon = conn->hcon;
+ if (cmd_len < sizeof(struct l2cap_conn_req))
+ return -EPROTO;
+
hci_dev_lock(hdev);
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
@@ -3847,7 +3854,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
}
static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
{
struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
u16 scid, dcid, result, status;
@@ -3855,6 +3863,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
u8 req[128];
int err;
+ if (cmd_len < sizeof(*rsp))
+ return -EPROTO;
+
scid = __le16_to_cpu(rsp->scid);
dcid = __le16_to_cpu(rsp->dcid);
result = __le16_to_cpu(rsp->result);
@@ -3952,6 +3963,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
struct l2cap_chan *chan;
int len, err = 0;
+ if (cmd_len < sizeof(*req))
+ return -EPROTO;
+
dcid = __le16_to_cpu(req->dcid);
flags = __le16_to_cpu(req->flags);
@@ -3975,7 +3989,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
/* Reject if config buffer is too small. */
len = cmd_len - sizeof(*req);
- if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) {
+ if (chan->conf_len + len > sizeof(chan->conf_req)) {
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
l2cap_build_conf_rsp(chan, rsp,
L2CAP_CONF_REJECT, flags), rsp);
@@ -4053,14 +4067,18 @@ unlock:
}
static inline int l2cap_config_rsp(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
{
struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data;
u16 scid, flags, result;
struct l2cap_chan *chan;
- int len = le16_to_cpu(cmd->len) - sizeof(*rsp);
+ int len = cmd_len - sizeof(*rsp);
int err = 0;
+ if (cmd_len < sizeof(*rsp))
+ return -EPROTO;
+
scid = __le16_to_cpu(rsp->scid);
flags = __le16_to_cpu(rsp->flags);
result = __le16_to_cpu(rsp->result);
@@ -4161,7 +4179,8 @@ done:
}
static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
{
struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data;
struct l2cap_disconn_rsp rsp;
@@ -4169,6 +4188,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
struct l2cap_chan *chan;
struct sock *sk;
+ if (cmd_len != sizeof(*req))
+ return -EPROTO;
+
scid = __le16_to_cpu(req->scid);
dcid = __le16_to_cpu(req->dcid);
@@ -4208,12 +4230,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
}
static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
{
struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data;
u16 dcid, scid;
struct l2cap_chan *chan;
+ if (cmd_len != sizeof(*rsp))
+ return -EPROTO;
+
scid = __le16_to_cpu(rsp->scid);
dcid = __le16_to_cpu(rsp->dcid);
@@ -4243,11 +4269,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
}
static inline int l2cap_information_req(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
{
struct l2cap_info_req *req = (struct l2cap_info_req *) data;
u16 type;
+ if (cmd_len != sizeof(*req))
+ return -EPROTO;
+
type = __le16_to_cpu(req->type);
BT_DBG("type 0x%4.4x", type);
@@ -4294,11 +4324,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn,
}
static inline int l2cap_information_rsp(struct l2cap_conn *conn,
- struct l2cap_cmd_hdr *cmd, u8 *data)
+ struct l2cap_cmd_hdr *cmd, u16 cmd_len,
+ u8 *data)
{
struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data;
u16 type, result;
+ if (cmd_len != sizeof(*rsp))
+ return -EPROTO;
+
type = __le16_to_cpu(rsp->type);
result = __le16_to_cpu(rsp->result);
@@ -5164,16 +5198,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
switch (cmd->code) {
case L2CAP_COMMAND_REJ:
- l2cap_command_rej(conn, cmd, data);
+ l2cap_command_rej(conn, cmd, cmd_len, data);
break;
case L2CAP_CONN_REQ:
- err = l2cap_connect_req(conn, cmd, data);
+ err = l2cap_connect_req(conn, cmd, cmd_len, data);
break;
case L2CAP_CONN_RSP:
case L2CAP_CREATE_CHAN_RSP:
- err = l2cap_connect_create_rsp(conn, cmd, data);
+ err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data);
break;
case L2CAP_CONF_REQ:
@@ -5181,15 +5215,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
break;
case L2CAP_CONF_RSP:
- err = l2cap_config_rsp(conn, cmd, data);
+ err = l2cap_config_rsp(conn, cmd, cmd_len, data);
break;
case L2CAP_DISCONN_REQ:
- err = l2cap_disconnect_req(conn, cmd, data);
+ err = l2cap_disconnect_req(conn, cmd, cmd_len, data);
break;
case L2CAP_DISCONN_RSP:
- err = l2cap_disconnect_rsp(conn, cmd, data);
+ err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data);
break;
case L2CAP_ECHO_REQ:
@@ -5200,11 +5234,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
break;
case L2CAP_INFO_REQ:
- err = l2cap_information_req(conn, cmd, data);
+ err = l2cap_information_req(conn, cmd, cmd_len, data);
break;
case L2CAP_INFO_RSP:
- err = l2cap_information_rsp(conn, cmd, data);
+ err = l2cap_information_rsp(conn, cmd, cmd_len, data);
break;
case L2CAP_CREATE_CHAN_REQ:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 35fef22..f8ecbc7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2700,7 +2700,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
break;
case DISCOV_TYPE_LE:
- if (!lmp_host_le_capable(hdev)) {
+ if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY,
MGMT_STATUS_NOT_SUPPORTED);
mgmt_pending_remove(cmd);
@@ -3418,6 +3418,27 @@ new_settings:
return err;
}
+int mgmt_set_powered_failed(struct hci_dev *hdev, int err)
+{
+ struct pending_cmd *cmd;
+ u8 status;
+
+ cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev);
+ if (!cmd)
+ return -ENOENT;
+
+ if (err == -ERFKILL)
+ status = MGMT_STATUS_RFKILLED;
+ else
+ status = MGMT_STATUS_FAILED;
+
+ err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status);
+
+ mgmt_pending_remove(cmd);
+
+ return err;
+}
+
int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
{
struct cmd_lookup match = { NULL, hdev };
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index b2296d3..b5562ab 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
- if (!lmp_host_le_capable(hcon->hdev))
+ if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags))
return 1;
if (sec_level == BT_SECURITY_LOW)
@@ -851,7 +851,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
__u8 reason;
int err = 0;
- if (!lmp_host_le_capable(conn->hcon->hdev)) {
+ if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) {
err = -ENOTSUPP;
reason = SMP_PAIRING_NOTSUPP;
goto done;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 44be28c..9ca8e32 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1497,10 +1497,11 @@ static inline void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata,
ieee80211_tx_skb_tid(sdata, skb, 7);
}
-u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action,
+u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
struct ieee802_11_elems *elems,
u64 filter, u32 crc);
-static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action,
+static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
+ bool action,
struct ieee802_11_elems *elems)
{
ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a8c2130..741448b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2522,8 +2522,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
u16 capab_info, aid;
struct ieee802_11_elems elems;
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
+ const struct cfg80211_bss_ies *bss_ies = NULL;
+ struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
u32 changed = 0;
int err;
+ bool ret;
/* AssocResp and ReassocResp have identical structure */
@@ -2555,21 +2558,86 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
ifmgd->aid = aid;
/*
+ * Some APs are erroneously not including some information in their
+ * (re)association response frames. Try to recover by using the data
+ * from the beacon or probe response. This seems to afflict mobile
+ * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
+ * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
+ */
+ if ((assoc_data->wmm && !elems.wmm_param) ||
+ (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
+ (!elems.ht_cap_elem || !elems.ht_operation)) ||
+ (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
+ (!elems.vht_cap_elem || !elems.vht_operation))) {
+ const struct cfg80211_bss_ies *ies;
+ struct ieee802_11_elems bss_elems;
+
+ rcu_read_lock();
+ ies = rcu_dereference(cbss->ies);
+ if (ies)
+ bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
+ GFP_ATOMIC);
+ rcu_read_unlock();
+ if (!bss_ies)
+ return false;
+
+ ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
+ false, &bss_elems);
+ if (assoc_data->wmm &&
+ !elems.wmm_param && bss_elems.wmm_param) {
+ elems.wmm_param = bss_elems.wmm_param;
+ sdata_info(sdata,
+ "AP bug: WMM param missing from AssocResp\n");
+ }
+
+ /*
+ * Also check if we requested HT/VHT, otherwise the AP doesn't
+ * have to include the IEs in the (re)association response.
+ */
+ if (!elems.ht_cap_elem && bss_elems.ht_cap_elem &&
+ !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
+ elems.ht_cap_elem = bss_elems.ht_cap_elem;
+ sdata_info(sdata,
+ "AP bug: HT capability missing from AssocResp\n");
+ }
+ if (!elems.ht_operation && bss_elems.ht_operation &&
+ !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
+ elems.ht_operation = bss_elems.ht_operation;
+ sdata_info(sdata,
+ "AP bug: HT operation missing from AssocResp\n");
+ }
+ if (!elems.vht_cap_elem && bss_elems.vht_cap_elem &&
+ !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
+ elems.vht_cap_elem = bss_elems.vht_cap_elem;
+ sdata_info(sdata,
+ "AP bug: VHT capa missing from AssocResp\n");
+ }
+ if (!elems.vht_operation && bss_elems.vht_operation &&
+ !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
+ elems.vht_operation = bss_elems.vht_operation;
+ sdata_info(sdata,
+ "AP bug: VHT operation missing from AssocResp\n");
+ }
+ }
+
+ /*
* We previously checked these in the beacon/probe response, so
* they should be present here. This is just a safety net.
*/
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
(!elems.wmm_param || !elems.ht_cap_elem || !elems.ht_operation)) {
sdata_info(sdata,
- "HT AP is missing WMM params or HT capability/operation in AssocResp\n");
- return false;
+ "HT AP is missing WMM params or HT capability/operation\n");
+ ret = false;
+ goto out;
}
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
(!elems.vht_cap_elem || !elems.vht_operation)) {
sdata_info(sdata,
- "VHT AP is missing VHT capability/operation in AssocResp\n");
- return false;
+ "VHT AP is missing VHT capability/operation\n");
+ ret = false;
+ goto out;
}
mutex_lock(&sdata->local->sta_mtx);
@@ -2580,7 +2648,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
sta = sta_info_get(sdata, cbss->bssid);
if (WARN_ON(!sta)) {
mutex_unlock(&sdata->local->sta_mtx);
- return false;
+ ret = false;
+ goto out;
}
sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
@@ -2633,7 +2702,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
sta->sta.addr);
WARN_ON(__sta_info_destroy(sta));
mutex_unlock(&sdata->local->sta_mtx);
- return false;
+ ret = false;
+ goto out;
}
mutex_unlock(&sdata->local->sta_mtx);
@@ -2673,7 +2743,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
ieee80211_sta_reset_beacon_monitor(sdata);
- return true;
+ ret = true;
+ out:
+ kfree(bss_ies);
+ return ret;
}
static enum rx_mgmt_action __must_check
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 27e0715..72e6292 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -661,12 +661,12 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL(ieee80211_queue_delayed_work);
-u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, bool action,
+u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
struct ieee802_11_elems *elems,
u64 filter, u32 crc)
{
size_t left = len;
- u8 *pos = start;
+ const u8 *pos = start;
bool calc_crc = filter != 0;
DECLARE_BITMAP(seen_elems, 256);
const u8 *ie;
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* [GIT] [3.10] NFC fixes
From: Samuel Ortiz @ 2013-06-06 15:20 UTC (permalink / raw)
To: John W. Linville; +Cc: Linux Wireless, Linux NFC
Hi John,
This is the 2nd NFC pull request for 3.10.
I wish this one could have been part of the first one, but we came back from
the NFC plugfest with a few more LLCP fixes:
- The well known services bitmask was sent with the wrong endianness and with
the first bit not set, which goes against the LLCP specifications. This
won't prevent most use cases and tests to pass, only picky implementations
seem to care about the WKS correctness.
- We were ignoring RNRs and were sending our pending frames regardless. We
should just re-queue them and send a SYMM instead.
- Non blocking LLCP connections were not handled properly as we found out
after implementing it from neard. Applications were immediatly woken up with
a SIGHUP and connection failed. This is fixed now, allowing us to have a
fully asynchronous NFC userspace daemon.
Thanks in advance for pulling them in.
The following changes since commit cee6dfa25831e0daac52fc582a04a7204f886220:
Revert "ath9k_hw: Update rx gain initval to improve rx sensitivity" (2013-06-05 10:42:29 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-fixes.git tags/nfc-fixes-3.10-2
for you to fetch changes up to fcd335b0010aeafb6e3dfd46360778ce59e1e201:
NFC: llcp: Fix the well known services endianness (2013-06-06 16:43:51 +0200)
----------------------------------------------------------------
Samuel Ortiz (4):
NFC: llcp: Fix non blocking sockets connections
NFC: llcp: Do not send pending Tx frames when the remote is not ready
NFC: llcp: Set the LLC Link Management well known service bit
NFC: llcp: Fix the well known services endianness
net/nfc/llcp.h | 1 +
net/nfc/llcp_core.c | 8 ++++++--
net/nfc/llcp_sock.c | 8 +++++---
3 files changed, 12 insertions(+), 5 deletions(-)
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply
* Re: wireless tree rebased (from 5/28), Broadcom bits dropped
From: John W. Linville @ 2013-06-05 20:19 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, Samuel Ortiz, Gustavo Padovan, Luciano Coelho
In-Reply-To: <20130605143700.GA2271@tuxdriver.com>
On Wed, Jun 05, 2013 at 10:37:01AM -0400, John W. Linville wrote:
> On Wed, Jun 05, 2013 at 08:59:46AM +0200, Johannes Berg wrote:
> > On Tue, 2013-06-04 at 17:53 -0400, John W. Linville wrote:
> I think I can fix the wireless tree and preserve the original mac80211
> tree commits. Everyone please hold off on doing anything else here, as
> I'm a bit busy and won't be able to get to this before this afternoon
> (Eastern USA time).
>
> Anyone object to one more wireless tree rebase today?
I've redone the wireless tree now. Please do the needful...
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCHv4 2/4] brcm80211: make mgmt_tx in brcmfmac accept a NULL channel
From: John W. Linville @ 2013-06-05 17:47 UTC (permalink / raw)
To: Johannes Berg
Cc: Arend van Spriel, Antonio Quartulli, linux-wireless,
Antonio Quartulli, brcm80211-dev-list
In-Reply-To: <1370446810.25710.6.camel@jlt4.sipsolutions.net>
On Wed, Jun 05, 2013 at 05:40:10PM +0200, Johannes Berg wrote:
> On Wed, 2013-06-05 at 17:35 +0200, Arend van Spriel wrote:
> > On 06/05/2013 05:34 PM, Arend van Spriel wrote:
> > > On 06/05/2013 05:09 PM, Antonio Quartulli wrote:
> > >> From: Antonio Quartulli <antonio@open-mesh.com>
> > >>
> > >> cfg80211 passes a NULL channel to mgmt_tx if the frame has
> > >> to be sent on the one currently in use by the device.
> > >> Make the implementation of mgmt_tx correctly handle this
> > >> case
> > >>
> > >> Cc: Arend van Spriel <arend@broadcom.com>
> > >> Cc: brcm80211-dev-list@broadcom.com
> > >> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> > >> ---
> > >
> > > For my name above you (or Johannes) can change 'Cc:' to 'Acked-by:'
> >
> > Or John?
>
> I think I'll take the whole series if that's ok with everyone, otherwise
> we get synchronisation issues between John and myself :)
Yes, please.
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: Incorrect resolution of merge conflict in net/mac80211/iface.c
From: John W. Linville @ 2013-06-05 17:45 UTC (permalink / raw)
To: Helmut Schaa; +Cc: Jakub Kicinski, linux-wireless, Felix Fietkau
In-Reply-To: <CAGXE3d_TRYRA-o0K+zL-76rp0Xsv98bQnOPRJVepAP+iogrsTg@mail.gmail.com>
On Wed, Jun 05, 2013 at 04:37:21PM +0200, Helmut Schaa wrote:
> On Wed, Jun 5, 2013 at 4:14 PM, Jakub Kicinski <kubakici@wp.pl> wrote:
> > Hi John,
> >
> > I'm afraid merge in commit 84e46e17c8 of wireless-testing is
> > not correct. I don't know how would you like to resolve this
> > technical error, I attach my fixup patch in case it will help
> > you. You may also want to take a look at commit a0f5d4b3a3
> > of linux-next, I believe Stephen have merged two offending
> > patches correctly there.
> >
> > BTW I think the way MAC addresses of active monitors are
> > handled for devices that use address masks need some work
> > on its own I hope to send a fix for that later this week.
>
> Indeed, good catch. Stephens merge looks correct to me.
Yep, looks fine -- thanks, Jakub!
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH] wil6210: Fix AP/PCP start flow
From: Vladimir Kondratiev @ 2013-06-06 12:48 UTC (permalink / raw)
To: Kirshenbaum Erez; +Cc: linux-wireless
In-Reply-To: <1370507740-9178-1-git-send-email-erezk@wilocity.com>
On Thursday, June 06, 2013 11:35:40 AM Kirshenbaum Erez wrote:
>
Please, provide explanation - what is motivation for the change,
what was wrong, why do you need this change etc.
Good comment is essential.
> Signed-off-by: Kirshenbaum Erez <erezk@wilocity.com>
> ---
> drivers/net/wireless/ath/wil6210/main.c | 35 ---------------------------------
> 1 file changed, 35 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
> index c97b864..271ee22 100644
> --- a/drivers/net/wireless/ath/wil6210/main.c
> +++ b/drivers/net/wireless/ath/wil6210/main.c
> @@ -286,41 +286,31 @@ static int __wil_up(struct wil6210_priv *wil)
> {
> struct net_device *ndev = wil_to_ndev(wil);
> struct wireless_dev *wdev = wil->wdev;
> - struct ieee80211_channel *channel = wdev->preset_chandef.chan;
> int rc;
> - int bi;
> - u16 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
>
> rc = wil_reset(wil);
> if (rc)
> return rc;
>
> - /* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
> - wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
> switch (wdev->iftype) {
> case NL80211_IFTYPE_STATION:
> wil_dbg_misc(wil, "type: STATION\n");
> - bi = 0;
> ndev->type = ARPHRD_ETHER;
> break;
> case NL80211_IFTYPE_AP:
> wil_dbg_misc(wil, "type: AP\n");
> - bi = 100;
> ndev->type = ARPHRD_ETHER;
> break;
> case NL80211_IFTYPE_P2P_CLIENT:
> wil_dbg_misc(wil, "type: P2P_CLIENT\n");
> - bi = 0;
> ndev->type = ARPHRD_ETHER;
> break;
> case NL80211_IFTYPE_P2P_GO:
> wil_dbg_misc(wil, "type: P2P_GO\n");
> - bi = 100;
> ndev->type = ARPHRD_ETHER;
> break;
> case NL80211_IFTYPE_MONITOR:
> wil_dbg_misc(wil, "type: Monitor\n");
> - bi = 0;
> ndev->type = ARPHRD_IEEE80211_RADIOTAP;
> /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
> break;
> @@ -328,34 +318,9 @@ static int __wil_up(struct wil6210_priv *wil)
> return -EOPNOTSUPP;
> }
>
> - /* Apply profile in the following order: */
> - /* SSID and channel for the AP */
> - switch (wdev->iftype) {
> - case NL80211_IFTYPE_AP:
> - case NL80211_IFTYPE_P2P_GO:
> - if (wdev->ssid_len == 0) {
> - wil_err(wil, "SSID not set\n");
> - return -EINVAL;
> - }
> - rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
> - if (rc)
> - return rc;
> - break;
> - default:
> - break;
> - }
> -
> /* MAC address - pre-requisite for other commands */
> wmi_set_mac_address(wil, ndev->dev_addr);
>
> - /* Set up beaconing if required. */
> - if (bi > 0) {
> - rc = wmi_pcp_start(wil, bi, wmi_nettype,
> - (channel ? channel->hw_value : 0));
> - if (rc)
> - return rc;
> - }
> -
> /* Rx VRING. After MAC and beacon */
> wil_rx_init(wil);
>
>
>From what I see in the code, you want not start AP through netdev open()
but want to keep NL80211_IFTYPE_AP and NL80211_IFTYPE_P2P_GO to be OK,
doing nothing. I agree that AP should be started via start_ap() instead, as
it is the way to pass all parameters like IE's and security.
What I want so see is why not return -EOPNOTSUPP for AP/P2P_GO?
Thanks, Vladimir
^ permalink raw reply
* Re: [PATCH 1/2] rt2x00: convert rt2x00_ops.extra_tx_headroom to be a fuction
From: Stanislaw Gruszka @ 2013-06-06 12:36 UTC (permalink / raw)
To: Gabor Juhos; +Cc: John Linville, linux-wireless, users
In-Reply-To: <51AF9852.5020404@openwrt.org>
On Wed, Jun 05, 2013 at 09:58:10PM +0200, Gabor Juhos wrote:
> > Could we rather get rid of that extra_tx_headroom variable and use queue
> > parameters: winfo_size and desc_size ?
>
> Yes, it seems that we can compute the value of extra_tx_headrom from those
> fields. The driver uses the following values now:
>
> driver/device desc_size winfo_size extra_tx_headroom
>
> rt2400pci TXD_DESC_SIZE 0 0
> rt2500pci TXD_DESC_SIZE 0 0
> rt2800pci TXD_DESC_SIZE TXWI_DESC_SIZE TXWI_DESC_SIZE
> rt61pci TXD_DESC_SIZE 0 0
>
> rt2500usb TXD_DESC_SIZE 0 TXD_DESC_SIZE
> rt2800usb TXINFO_DESC_SIZE TXWI_DESC_SIZE TXINFO_DESC_SIZE +
> TXWI_DESC_SIZE
> rt2800usb/RT5592 TXINFO_DESC_SIZE TXWI_DESC_SIZE_5592 TXINFO_DESC_SIZE +
> TXWI_DESC_SIZE_5592
> rt73usb TXD_DESC_SIZE 0 TXD_DESC_SIZE
>
> On USB devices we can get it from desc_size + winfo_size and on PCI/PCIe/SoC
> devices it equals with winfo_size. So the callbacks and the extra_tx_headroom
> field in rt2x00_ops can be removed.
>
> However I would keep the new extra_tx_headroom field in rt2x00_dev. It would
> ensure that we don't have to compute its value every time it is used.
Ok, that make sense.
Thanks
Stanislaw
^ permalink raw reply
* Re: [PATCH 03/15] brcmsmac: remove brcms_bss_cfg->BSS
From: Arend van Spriel @ 2013-06-06 12:05 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linville, linux-wireless, brcm80211-dev-list
In-Reply-To: <1364085963-25940-4-git-send-email-hauke@hauke-m.de>
On 03/24/2013 01:45 AM, Hauke Mehrtens wrote:
> This was a read only member. The checks using BSS are replaced by
> better fitting checks of the new type member.
>
> The change in brcms_c_tbtt() was based on code from b43, in
> brcms_c_ps_allowed() the same happens with BSS being true or false,
> beaconing and probe responses are just needed in ap mode.
>
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/main.c | 23 +++++++++--------------
> drivers/net/wireless/brcm80211/brcmsmac/main.h | 2 --
> 2 files changed, 9 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> index 4e420ea..90e6c0d 100644
> --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
> +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
> @@ -1069,7 +1069,7 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
>
> static void brcms_c_tbtt(struct brcms_c_info *wlc)
> {
> - if (!wlc->bsscfg->BSS)
> + if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC)
> /*
> * DirFrmQ is now valid...defer setting until end
> * of ATIM window
Hi Hauke,
Sorry for such a late comment. It seem that the above change is
incosistent with the changes below. You probably need to change it.
Gr. AvS
> @@ -7386,7 +7379,8 @@ void brcms_c_update_beacon(struct brcms_c_info *wlc)
> {
> struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
>
> - if (bsscfg->up && !bsscfg->BSS)
> + if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
> + bsscfg->type == BRCMS_TYPE_ADHOC))
> /* Clear the soft intmask */
> wlc->defmacintmask &= ~MI_BCNTPL;
> }
> @@ -7461,7 +7455,8 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
> struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
>
> /* update AP or IBSS probe responses */
> - if (bsscfg->up && !bsscfg->BSS)
> + if (bsscfg->up && (bsscfg->type == BRCMS_TYPE_AP ||
> + bsscfg->type == BRCMS_TYPE_ADHOC))
> brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
> }
>
^ permalink raw reply
* Re: [PATCH] ath9k_htc: fix skb_under_panic error
From: Oleksij Rempel @ 2013-06-06 12:06 UTC (permalink / raw)
To: Helmut Schaa; +Cc: Marc Kleine-Budde, linux-wireless, ath9k-devel
In-Reply-To: <CAGXE3d-kg7k=R81mKcqMfM9FFBDn0A9RNYmuTdQHXRUX37QhsA@mail.gmail.com>
Am 06.06.2013 13:48, schrieb Helmut Schaa:
> On Wed, Jun 5, 2013 at 7:03 PM, Oleksij Rempel <linux@rempel-privat.de> wrote:
>> I was running two stream netperf test for 2 hours without visible
>> regressions.
>
> With or without your pskb_expand_head patch applied?
>
> Thanks,
> Helmut
>
whithout my patch, on to of wireless-testing master git. But i didn't
had this problem before. So, may be this scenario was not used by me.
Shouldn't we actually have this check from my patch, to avoid other oopses?
--
Regards,
Oleksij
^ permalink raw reply
* Re: [PATCH 1/2] net: wireless: wl1251: Use module_spi_driver macro
From: Sachin Kamat @ 2013-06-06 11:51 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless, linville
In-Reply-To: <1370519207.5502.5.camel@cumari.coelho.fi>
Hi Luciano,
On 6 June 2013 17:16, Luciano Coelho <coelho@ti.com> wrote:
> Hi Sachin,
>
> On Thu, 2013-06-06 at 14:48 +0530, Sachin Kamat wrote:
>> On 29 May 2013 15:48, Sachin Kamat <sachin.kamat@linaro.org> wrote:
>> > module_spi_driver() eliminates some boiler plate and makes code
>> > simpler.
>> >
>> > Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
>> > ---
>> > drivers/net/wireless/ti/wl1251/spi.c | 24 +-----------------------
>> > 1 file changed, 1 insertion(+), 23 deletions(-)
>> >
>> > diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
>> > index 4c67c2f..dfd0877 100644
>> > --- a/drivers/net/wireless/ti/wl1251/spi.c
>> > +++ b/drivers/net/wireless/ti/wl1251/spi.c
>> > @@ -329,29 +329,7 @@ static struct spi_driver wl1251_spi_driver = {
>> > .remove = wl1251_spi_remove,
>> > };
>> >
>> > -static int __init wl1251_spi_init(void)
>> > -{
>> > - int ret;
>> > -
>> > - ret = spi_register_driver(&wl1251_spi_driver);
>> > - if (ret < 0) {
>> > - wl1251_error("failed to register spi driver: %d", ret);
>> > - goto out;
>> > - }
>> > -
>> > -out:
>> > - return ret;
>> > -}
>> > -
>> > -static void __exit wl1251_spi_exit(void)
>> > -{
>> > - spi_unregister_driver(&wl1251_spi_driver);
>> > -
>> > - wl1251_notice("unloaded");
>> > -}
>> > -
>> > -module_init(wl1251_spi_init);
>> > -module_exit(wl1251_spi_exit);
>> > +module_spi_driver(wl1251_spi_driver);
>> >
>> > MODULE_LICENSE("GPL");
>> > MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
>> > --
>> > 1.7.9.5
>> >
>>
>> Gentle ping on this series John.
>
> This is in my queue. Haven't had the time to review and apply them yet.
> And these are not urgent changes, so they can wait a little while.
Sure. Thanks.
--
With warm regards,
Sachin
^ permalink raw reply
* [PATCH V2 10/22] brcmfmac: Sent TIM information in case of data available.
From: Arend van Spriel @ 2013-06-06 11:49 UTC (permalink / raw)
To: John W. Linville
Cc: linux-wireless, Arend van Spriel, Dan Carpenter, Hante Meuleman
When data is available and fw signalling is enabled then TIM
information should be sent to firmware. If it can piggy back
on existing packet then do that otherwise create dummy packet
to get information out.
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
This patch replaces:
Message-ID: <1370517487-14395-11-git-send-email-arend@broadcom.com>
Regards,
Arend
---
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 167 ++++++++++++--------
1 file changed, 103 insertions(+), 64 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index abba7f7..758ddaf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -157,11 +157,13 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
* @BRCMF_FWS_SKBSTATE_NEW: sk_buff is newly arrived in the driver.
* @BRCMF_FWS_SKBSTATE_DELAYED: sk_buff had to wait on queue.
* @BRCMF_FWS_SKBSTATE_SUPPRESSED: sk_buff has been suppressed by firmware.
+ * @BRCMF_FWS_SKBSTATE_TIM: allocated for TIM update info.
*/
enum brcmf_fws_skb_state {
BRCMF_FWS_SKBSTATE_NEW,
BRCMF_FWS_SKBSTATE_DELAYED,
- BRCMF_FWS_SKBSTATE_SUPPRESSED
+ BRCMF_FWS_SKBSTATE_SUPPRESSED,
+ BRCMF_FWS_SKBSTATE_TIM
};
/**
@@ -278,6 +280,7 @@ struct brcmf_skbuff_cb {
/**
* enum brcmf_fws_fifo - fifo indices used by dongle firmware.
*
+ * @BRCMF_FWS_FIFO_FIRST: first fifo, ie. background.
* @BRCMF_FWS_FIFO_AC_BK: fifo for background traffic.
* @BRCMF_FWS_FIFO_AC_BE: fifo for best-effort traffic.
* @BRCMF_FWS_FIFO_AC_VI: fifo for video traffic.
@@ -287,7 +290,8 @@ struct brcmf_skbuff_cb {
* @BRCMF_FWS_FIFO_COUNT: number of fifos.
*/
enum brcmf_fws_fifo {
- BRCMF_FWS_FIFO_AC_BK,
+ BRCMF_FWS_FIFO_FIRST,
+ BRCMF_FWS_FIFO_AC_BK = BRCMF_FWS_FIFO_FIRST,
BRCMF_FWS_FIFO_AC_BE,
BRCMF_FWS_FIFO_AC_VI,
BRCMF_FWS_FIFO_AC_VO,
@@ -788,22 +792,95 @@ static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx)
brcmf_fws_hanger_cleanup(fws, matchfn, ifidx);
}
-static void brcmf_fws_tim_update(struct brcmf_fws_info *ctx,
- struct brcmf_fws_mac_descriptor *entry,
- int prec)
+static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
{
- if (entry->state == BRCMF_FWS_STATE_CLOSE) {
- /* check delayedQ and suppressQ in one call using bitmap */
- if (brcmu_pktq_mlen(&entry->psq, 3 << (prec * 2)) == 0)
- entry->traffic_pending_bmp =
- entry->traffic_pending_bmp & ~NBITVAL(prec);
- else
- entry->traffic_pending_bmp =
- entry->traffic_pending_bmp | NBITVAL(prec);
+ struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
+ u8 *wlh;
+ u16 data_offset = 0;
+ u8 fillers;
+ __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
+
+ brcmf_dbg(TRACE, "enter: ea=%pM, ifidx=%u (%u), pkttag=0x%08X, hslot=%d\n",
+ entry->ea, entry->interface_id,
+ brcmf_skb_if_flags_get_field(skb, INDEX),
+ le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
+ if (entry->send_tim_signal)
+ data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
+
+ /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
+ data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
+ fillers = round_up(data_offset, 4) - data_offset;
+ data_offset += fillers;
+
+ skb_push(skb, data_offset);
+ wlh = skb->data;
+
+ wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
+ wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
+ memcpy(&wlh[2], &pkttag, sizeof(pkttag));
+ wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
+
+ if (entry->send_tim_signal) {
+ entry->send_tim_signal = 0;
+ wlh[0] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP;
+ wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
+ wlh[2] = entry->mac_handle;
+ wlh[3] = entry->traffic_pending_bmp;
+ brcmf_dbg(TRACE, "adding TIM info: %02X:%02X:%02X:%02X\n",
+ wlh[0], wlh[1], wlh[2], wlh[3]);
+ wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
+ entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
}
- /* request a TIM update to firmware at the next piggyback opportunity */
+ if (fillers)
+ memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers);
+
+ brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX),
+ data_offset >> 2, skb);
+ return 0;
+}
+
+static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
+ struct brcmf_fws_mac_descriptor *entry,
+ int prec, bool send_immediately)
+{
+ struct sk_buff *skb;
+ struct brcmf_bus *bus;
+ struct brcmf_skbuff_cb *skcb;
+ s32 err;
+ u32 len;
+
+ /* check delayedQ and suppressQ in one call using bitmap */
+ if (brcmu_pktq_mlen(&entry->psq, 3 << (prec * 2)) == 0)
+ entry->traffic_pending_bmp &= ~NBITVAL(prec);
+ else
+ entry->traffic_pending_bmp |= NBITVAL(prec);
+
+ entry->send_tim_signal = false;
if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp)
entry->send_tim_signal = true;
+ if (send_immediately && entry->send_tim_signal &&
+ entry->state == BRCMF_FWS_STATE_CLOSE) {
+ /* create a dummy packet and sent that. The traffic */
+ /* bitmap info will automatically be attached to that packet */
+ len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 +
+ BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
+ 4 + fws->drvr->hdrlen;
+ skb = brcmu_pkt_buf_get_skb(len);
+ if (skb == NULL)
+ return false;
+ skb_pull(skb, len);
+ skcb = brcmf_skbcb(skb);
+ skcb->mac = entry;
+ skcb->state = BRCMF_FWS_SKBSTATE_TIM;
+ bus = fws->drvr->bus_if;
+ err = brcmf_fws_hdrpush(fws, skb);
+ if (err == 0)
+ err = brcmf_bus_txdata(bus, skb);
+ if (err)
+ brcmu_pkt_buf_free_skb(skb);
+ return true;
+ }
+ return false;
}
static void
@@ -891,7 +968,6 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
{
struct brcmf_fws_mac_descriptor *entry;
u8 mac_handle;
- int i;
mac_handle = data[0];
entry = &fws->desc.nodes[mac_handle & 0x1F];
@@ -899,18 +975,18 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
fws->stats.mac_ps_update_failed++;
return -ESRCH;
}
-
- brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type,
- entry->name);
- /* a state update should wipe old credits? */
+ /* a state update should wipe old credits */
entry->requested_credit = 0;
+ entry->requested_packet = 0;
if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
entry->state = BRCMF_FWS_STATE_OPEN;
return BRCMF_FWS_RET_OK_SCHEDULE;
} else {
entry->state = BRCMF_FWS_STATE_CLOSE;
- for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++)
- brcmf_fws_tim_update(fws, entry, i);
+ brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false);
+ brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false);
+ brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false);
+ brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true);
}
return BRCMF_FWS_RET_OK_NOSCHEDULE;
}
@@ -1111,7 +1187,7 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
* A packet has been pushed so update traffic
* availability bitmap, if applicable
*/
- brcmf_fws_tim_update(fws, entry, fifo);
+ brcmf_fws_tim_update(fws, entry, fifo, true);
brcmf_fws_flow_control_check(fws, &entry->psq,
brcmf_skb_if_flags_get_field(p, INDEX));
return 0;
@@ -1168,7 +1244,7 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
* A packet has been picked up, update traffic
* availability bitmap, if applicable
*/
- brcmf_fws_tim_update(fws, entry, fifo);
+ brcmf_fws_tim_update(fws, entry, fifo, false);
/*
* decrement total enqueued fifo packets and
@@ -1500,47 +1576,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
return 0;
}
-static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
-{
- struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
- u8 *wlh;
- u16 data_offset = 0;
- u8 fillers;
- __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
-
- if (entry->send_tim_signal)
- data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
-
- /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
- data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
- fillers = round_up(data_offset, 4) - data_offset;
- data_offset += fillers;
-
- skb_push(skb, data_offset);
- wlh = skb->data;
-
- wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
- wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
- memcpy(&wlh[2], &pkttag, sizeof(pkttag));
- wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
-
- if (entry->send_tim_signal) {
- entry->send_tim_signal = 0;
- wlh[0] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP;
- wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
- wlh[2] = entry->mac_handle;
- wlh[3] = entry->traffic_pending_bmp;
- wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
- entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
- }
- if (fillers)
- memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers);
-
- brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX),
- data_offset >> 2, skb);
- return 0;
-}
-
static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
struct sk_buff *p)
{
@@ -2013,6 +2048,10 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
ulong flags;
int fifo;
+ if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_TIM) {
+ brcmu_pkt_buf_free_skb(skb);
+ return;
+ }
brcmf_fws_lock(fws->drvr, flags);
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_FW_TOSSED,
brcmf_skb_htod_tag_get_field(skb, HSLOT), 0);
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox