* [PATCH v2] mac80211: use min rate as basic rate for buggy APs
From: Eliad Peller @ 2011-10-30 13:41 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
Some buggy APs (and even P2P_GO) don't advertise their
basic rates in the association response.
In such case, use the min supported rate as the
basic rate.
Reported-by: Pontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
v2: add debug print (Johannes)
net/mac80211/mlme.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0e5d8da..d3672e9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1482,6 +1482,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
int i, j, err;
bool have_higher_than_11mbit = false;
u16 ap_ht_cap_flags;
+ int min_rate = INT_MAX, min_rate_index = -1;
/* AssocResp and ReassocResp have identical structure */
@@ -1537,6 +1538,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
rates |= BIT(j);
if (is_basic)
basic_rates |= BIT(j);
+ if (rate < min_rate) {
+ min_rate = rate;
+ min_rate_index = j;
+ }
break;
}
}
@@ -1554,11 +1559,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
rates |= BIT(j);
if (is_basic)
basic_rates |= BIT(j);
+ if (rate < min_rate) {
+ min_rate = rate;
+ min_rate_index = j;
+ }
break;
}
}
}
+ /*
+ * some buggy APs don't advertise basic_rates. use the lowest
+ * supported rate instead.
+ */
+ if (unlikely(!basic_rates) && min_rate_index >= 0) {
+ printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
+ "Using min supported rate instead.\n", sdata->name);
+ basic_rates = BIT(min_rate_index);
+ }
+
sta->sta.supp_rates[wk->chan->band] = rates;
sdata->vif.bss_conf.basic_rates = basic_rates;
--
1.7.6.401.g6a319
^ permalink raw reply related
* [PATCH 3.2] iwlwifi: don't perform "echo test" when cmd queue stuck
From: Wey-Yi Guy @ 2011-10-30 6:15 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Wey-Yi Guy
Perform "echo test" when cmd queue stuck detected, somethime it will cause
calltrace. I am not sure how to fix it yet, just remove the action now until
find a better way to handle it.
Reported-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 10 ----------
1 files changed, 0 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index a779024..8efa10f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1450,16 +1450,6 @@ static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
{
if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
int ret;
- if (txq == priv->shrd->cmd_queue) {
- /*
- * validate command queue still working
- * by sending "ECHO" command
- */
- if (!iwl_cmd_echo_test(priv))
- return 0;
- else
- IWL_DEBUG_HC(priv, "echo testing fail\n");
- }
ret = iwl_force_reset(priv, IWL_FW_RESET, false);
return (ret == -EAGAIN) ? 0 : 1;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH] ipw2x00: remove unused function libipw_ratelimit_debug.
From: Stanislav Yakovlev @ 2011-10-30 6:47 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Stanislav Yakovlev
Looks like no one uses it.
Signed-off-by: Stanislav Yakovlev <stas.yakovlev@gmail.com>
---
drivers/net/wireless/ipw2x00/libipw.h | 8 --------
1 files changed, 0 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index 70f5586..3d5821e 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -66,16 +66,8 @@ extern u32 libipw_debug_level;
do { if (libipw_debug_level & (level)) \
printk(KERN_DEBUG "libipw: %c %s " fmt, \
in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-static inline bool libipw_ratelimit_debug(u32 level)
-{
- return (libipw_debug_level & level) && net_ratelimit();
-}
#else
#define LIBIPW_DEBUG(level, fmt, args...) do {} while (0)
-static inline bool libipw_ratelimit_debug(u32 level)
-{
- return false;
-}
#endif /* CONFIG_LIBIPW_DEBUG */
/*
--
1.7.2.5
^ permalink raw reply related
* Compat-wireless release for 2011-10-29 is baked
From: Compat-wireless cronjob account @ 2011-10-29 19:02 UTC (permalink / raw)
To: linux-wireless
compat-wireless code metrics
814862 - Total upstream lines of code being pulled
2431 - backport code changes
2113 - backport code additions
318 - backport code deletions
8588 - backport from compat module
11019 - total backport code
1.3523 - % of code consists of backport work
^ permalink raw reply
* iwlagn: memory corruption with WPA enterprise
From: Tomáš Janoušek @ 2011-10-29 17:15 UTC (permalink / raw)
To: linux-kernel, Wey-Yi Guy, linux-wireless
Hello,
ever since I got this ThinkPad T420, I've been having strange issues, which I
figured are caused by the iwlwifi driver. What happens is that when I'm
connected to a WPA enterprise (not PSK) access point, sooner or later things
start crashing -- sometimes the web browser goes down, and when I run some
heavy task like kernel compilation, I can be almost sure it will fail.
Some more information is provided by other people in this launchpad ticket:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/815148
I'm not a Ubuntu user, though, I'm running Debian with upstream kernels I
compile myself, and the issue still persists. I was able to reproduce it with
3.0.0 from Debian package, with upstream 3.0.4, with 3.1 and even with todays
davem/net-next merged into 3.1 (didn't try current Linus' tree, but that I
guess might be unnecessary).
Also, I tried two versions of uCode: 17.168.5.1 from Debian package and
17.168.5.3 from the intellinuxwireless webpage. None helps.
My reproduction steps are a bit different from what's in that launchpad
ticket, so I spell them here:
1. Connect to a WPA-EAP (enterprise) network.
2. Do some networking (torrent is a safe bet).
3. Run make -j4 on the kernel tree.
4. Wait until the compiler reports an internal error, segfaults, or does some
other weird thing it shouldn't do.
5. When this happens, things start to really go crazy -- if you for example
run 10 gccs in parallel again and again, and continue to do some
networking, it will fail every few seconds. Disconnecting from the network
and connecting again brings you to step 4 again, having to wait until
something somewhere goes wrong and thing start crashing.
Step 4 is a bit tricky and might sometimes take more than an hour (causing you
to repeat step 3). I've had great success accelerating it by telling my
friends that I just found a configuration which seems to work okay. This,
however, might not really help you reproduce the issue, but it did save me a
couple of tenminutes, I am sure.
Is there anything I can do to track this down? Perhaps try some experimental
uCode or something?
Thanks,
--
Tomáš Janoušek, a.k.a. Liskni_si, http://work.lisk.in/
^ permalink raw reply
* Re: RTL8188RU no injection?
From: Roman Proud @ 2011-10-29 12:06 UTC (permalink / raw)
To: Larry Finger; +Cc: linux-wireless
In-Reply-To: <4EA9E56D.5080300@lwfinger.net>
I really thank you guys for helping me.
I really learned a lot in this thread xD
Its an ALFA AWUS036NHR so i guess its me... but yeah, i also found
that there are many drivers already in the main kernel, but i didnt
know there is a difference between rtl and r and nothing ...
Btw i tried many drivers, not only directly from Realtek. I think my
netbook kernel, was the problem, since i'm on Orginal Arch im getting
straight forward to get this thing working :D
Now where i know that it should work, i can try and try without
worrying that it never will work, so really thx for testing this!
Greetings,
Roman
2011/10/28 Larry Finger <Larry.Finger@lwfinger.net>:
> On 10/27/2011 05:00 PM, Gábor Stefanik wrote:
>
>> As a former Aircrack developer, I can definitely state that Aircrack
>> uses the same injection method as packetspammer.
>
> I just built Aircrack and tested it with rtl8192cu on an ALFA AWUS036NHR,
> which has the RTL8188RU chip. It works just as you expected.
>
> Larry
>
>
>
^ permalink raw reply
* Re: [RFC v2 13/12] cfg80211/mac80211: allow management TX to not wait for ACK
From: Helmut Schaa @ 2011-10-29 12:01 UTC (permalink / raw)
To: Kalle Valo
Cc: Arend Van Spriel, Johannes Berg, linux-wireless@vger.kernel.org
In-Reply-To: <877h3pb5pp.fsf@purkki.adurom.net>
On Fri, Oct 28, 2011 at 3:34 PM, Kalle Valo <kvalo@adurom.com> wrote:
> Helmut Schaa <helmut.schaa@googlemail.com> writes:
>
>> The reason is the following: if you're running a mac80211 AP with multiple
>> bssids, hostapd will answer to broadcast probe requests sent by STAs with
>> one probe response per bssid (unicast of course). And since some clients
>> stay only for a short amount of time on the scan-channel (a few ms) under
>> some circumstances the probe responses aren't sent out yet before the
>> scanning STA leaves the channel and thus retried till the maximum retry
>> limit is reached. And these retries consume quite a lot of airtime. And to
>> avoid this we just don't want to retry the probe responses in that case.
>
> This is all good. But doesn't it also mean that this change increases
> probability that the client doesn't receive the probe response, for
> example due to interference where retransmission would help, and hence
> the AP isn't included in the client's scan results?
Correct. The probability to find the AP during a scan is lower then with
retries. However, some commercial APs (Aruba for example) do exactly this
and in some cases I noticed (on a mac80211 AP with 8 BSSIDs) one
scanning client took around 50ms of airtime :)
Also in a multi BSS scenario the probability of finding the second, third etc.
BSSID gets lower if probe responses are retried.
I've got a patch for hostapd to implement the don't-wait-for-ack behavior
only for broadcast probe responses that contain the wildcard ssid. But maybe
it makes sense to make this a configuration option? So it is up to the user
to decide about the behavior.
Helmut
^ permalink raw reply
* Re: [PATCH] brcm80211: smac: eliminate a null pointer dereference in dma.c
From: Julian Calaby @ 2011-10-29 10:44 UTC (permalink / raw)
To: Dominique Martinet; +Cc: Arend van Spriel, linux-wireless, Julia Lawall
In-Reply-To: <20111029102502.GA10582@nautica>
Hi,
On Sat, Oct 29, 2011 at 21:25, Dominique Martinet
<asmadeus@codewreck.org> wrote:
> Hi,
>
>
> Arend van Spriel wrote on Sat, Oct 29, 2011:
>> Though it's unlikely, di may be null, so we can't dereference
>> di->dma.dmactrlflags until we've checked it.
>
> I've got no experience whatsoever in kernel coding so feel free to tell
> me that's stupid, but if you say it's unlikely why not use the
> unlikely() macro as well for the check?
I'm not sure the check for whether di is NULL is necessary at all, as
my very quick check of where this function is called from turned up
only one place that it's called from, where di is most definitely not
null.
As for using unlikely() it produces an instruction for the compiler to
mangle the if statement into assembler in a certain way and, as I
understand it, is mostly used where we *know* that:
1. The test is unlikely to be true and
2. Telling the compiler to write the assembly code like this will
produce a performance improvement.
I.e. a good place to stick an unlikely is in a "fast-path", e.g. the
packet receive code - if we don't process packets fast enough, the
hardware will start dropping them, so a performance improvement of a
couple of cycles - which is what unlikely() will give us - may visibly
improve performance.
That said, there are a couple of reasons why we shouldn't:
- Compilers are getting smarter all the time, and can probably figure
out that we're unlikely to hit the test often
- Premature optimisation is considered harmful.
- If, as I suspect, this function is only used in one location, the
compiler will probably inline the function, then optimise it from
there - the only caller I could find calls the function with a proper
value for di, so the compiler will probably drop the entire if
statement.
I'm sure that there are many other things that could be worked on in
this driver before we start worrying about whether we should stick
unlikely()s in the code.
> (also, that's not the point of this patch, but can't hurt to point that
> out)
This is what I spend my life doing - this patch was just another
instance of this =)
Thanks,
--
Julian Calaby
Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
.Plan: http://sites.google.com/site/juliancalaby/
^ permalink raw reply
* Re: [PATCH] of: include errno.h
From: Grant Likely @ 2011-10-29 10:38 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Kalle Valo, devicetree-discuss, linux-wireless, linux-kernel
In-Reply-To: <CAMuHMdX-V6FqSZ_mmPm5aW_bTUNMk4sz5cADryX3Xyk627wRdg@mail.gmail.com>
On Sat, Oct 29, 2011 at 10:38:16AM +0200, Geert Uytterhoeven wrote:
> On Thu, Oct 6, 2011 at 14:40, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> > When compiling ath6kl for beagleboard (omap2plus_defconfig plus
> > CONFIG_ATH6KL, CONFIG_OF disable) with current linux-next compilation
> > fails:
> >
> > include/linux/of.h:269: error: 'ENOSYS' undeclared (first use in this function)
> > include/linux/of.h:276: error: 'ENOSYS' undeclared (first use in this function)
> > include/linux/of.h:289: error: 'ENOSYS' undeclared (first use in this function)
>
> And now this build failure (also on m68k) has hit Linus' tree, more
> than 3 weeks after
> its detection in -next...
>
> > Fix this by including errno.h from of.h.
> >
> > Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
>
> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Appied, thanks, and I'll push out to Linus as soon as the test build finishes.
g.
>
> > ---
> > include/linux/of.h | 1 +
> > 1 files changed, 1 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/of.h b/include/linux/of.h
> > index 9180dc5..219c29d 100644
> > --- a/include/linux/of.h
> > +++ b/include/linux/of.h
> > @@ -17,6 +17,7 @@
> > */
> > #include <linux/types.h>
> > #include <linux/bitops.h>
> > +#include <linux/errno.h>
> > #include <linux/kref.h>
> > #include <linux/mod_devicetable.h>
> > #include <linux/spinlock.h>
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] brcm80211: smac: eliminate a null pointer dereference in dma.c
From: Dominique Martinet @ 2011-10-29 10:25 UTC (permalink / raw)
To: Arend van Spriel; +Cc: linux-wireless, Julia Lawall, Julian Calaby
In-Reply-To: <1319880615-3000-1-git-send-email-arend@broadcom.com>
Hi,
Arend van Spriel wrote on Sat, Oct 29, 2011:
> Though it's unlikely, di may be null, so we can't dereference
> di->dma.dmactrlflags until we've checked it.
I've got no experience whatsoever in kernel coding so feel free to tell
me that's stupid, but if you say it's unlikely why not use the
unlikely() macro as well for the check?
(also, that's not the point of this patch, but can't hurt to point that
out)
> if (di == NULL) {
would change to
if (unlikely(di == NULL)) {
Regards,
--
Asmadeus | Dominique Martinet
^ permalink raw reply
* Re: [PATCH 2/4] mac80211: QoS multicast frames have No Ack policy
From: Christian Lamparter @ 2011-10-29 9:40 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: linux-wireless, devel, johannes, linville
In-Reply-To: <1319864732-11286-2-git-send-email-thomas@cozybit.com>
On Saturday 29 October 2011 07:05:30 Thomas Pedersen wrote:
> Previously QoS multicast frames had the Normal Acknowledgment QoS
> control bits set. This would cause broadcast frames to be discarded by
> peers with which we have a BA session, since their sequence number would
> fall outside the allowed range. Set No Ack QoS control bits on multicast
> QoS frames and filter these in de-aggregation code.
>
> Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
> ---
> net/mac80211/rx.c | 8 +++++++-
> net/mac80211/wme.c | 3 ++-
> 2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index b867bd5..ee9e71b 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -747,7 +747,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
> struct sta_info *sta = rx->sta;
> struct tid_ampdu_rx *tid_agg_rx;
> u16 sc;
> - int tid;
> + u8 tid, ack_policy;
>
> if (!ieee80211_is_data_qos(hdr->frame_control))
> goto dont_reorder;
> @@ -760,6 +760,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
> if (!sta)
> goto dont_reorder;
>
> + ack_policy = *ieee80211_get_qos_ctl(hdr) & ~IEEE80211_QOS_CTL_TID_MASK;
uh, while it might be a bit far fetched, but ack_policy might now clash with
frames that have set:
IEEE80211_QOS_CTL_EOSP (0x10)
IEEE80211_QOS_CTL_A_MSDU_PRESENT (0x80)
IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT (0x100)
so I think we would be better of with something like:
(in include/linux/ieee80211.h)
#define IEEE80211_QOS_CTL_ACK_POLICY_MASK 0x0060
ack_policy = *ieee80211_get_qos_ctl(hdr) & ~IEEE80211_QOS_CTL_ACK_POLICY_MASK;
> @@ -770,6 +771,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
> if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
> goto dont_reorder;
>
> + /* not part of a BA session */
> + if (!((ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK) ||
> + (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)))
> + goto dont_reorder;
> +
Regards,
Chr
^ permalink raw reply
* [PATCH] brcm80211: smac: eliminate a null pointer dereference in dma.c
From: Arend van Spriel @ 2011-10-29 9:30 UTC (permalink / raw)
To: linux-wireless; +Cc: Julia Lawall, Arend van Spriel, Julian Calaby
Though it's unlikely, di may be null, so we can't dereference
di->dma.dmactrlflags until we've checked it.
Move this de-reference after the check, and adjust the error
message to not require de-referencing di.
This is based upon Julia's original patch:
<1319846297-2985-2-git-send-email-julia@diku.dk>
Reported-by: Julia Lawall <julia@diku.dk>
Acked-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Julian Calaby <julian.calaby@gmail.com>
---
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index ae541fb..e286fb4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t)
static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
{
- uint dmactrlflags = di->dma.dmactrlflags;
+ uint dmactrlflags;
if (di == NULL) {
- DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+ DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
return 0;
}
+ dmactrlflags = di->dma.dmactrlflags;
dmactrlflags &= ~mask;
dmactrlflags |= flags;
--
1.7.4.1
^ permalink raw reply related
* Re: [PATCH 2/5] drivers/net/wireless/brcm80211/brcmsmac/dma.c: eliminate a null pointer dereference
From: Arend van Spriel @ 2011-10-29 9:28 UTC (permalink / raw)
To: Julian Calaby
Cc: Julia Lawall, John W. Linville, kernel-janitors@vger.kernel.org,
linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <4EAB6495.40707@gmail.com>
On 10/29/2011 04:27 AM, Julian Calaby wrote:
> On 29/10/11 10:58, Julia Lawall wrote:
>> From: Julia Lawall <julia@diku.dk>
>>
>> Delete di->name from the error reporting code, as it is meaningless if di
>> is NULL.
>>
>> The semantic match that finds this problem is as follows:
>> (http://coccinelle.lip6.fr/)
>>
>> // <smpl>
>> @r@
>> expression E, E1;
>> identifier f;
>> statement S1,S2,S3;
>> @@
>>
>> if (E == NULL)
>> {
>> ... when != if (E == NULL || ...) S1 else S2
>> when != E = E1
>> *E->f
>> ... when any
>> return ...;
>> }
>> else S3
>> // </smpl>
>>
>> Signed-off-by: Julia Lawall <julia@diku.dk>
>>
>> ---
>> drivers/net/wireless/brcm80211/brcmsmac/dma.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
>> index b56a302..1d66f53 100644
>> --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
>> +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
>> @@ -361,7 +361,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
>> uint dmactrlflags = di->dma.dmactrlflags;
>
> If di is null, we've already failed as it's dereferenced here.
>
>> if (di == NULL) {
>> - DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
>> + DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
>> return 0;
>> }
>
> So, a better patch would be something like this:
>
> (apologies if this doesn't apply - I've pretty much built it manually)
>
> ---
>
> Though it's unlikely, di may be null, so we can't dereference
> di->dma.dmactrlflags until we've checked it.
>
> Move this de-reference after the check, and adjust the error
> message to not require de-referencing di.
>
> This is based upon Julia's original patch:
> <1319846297-2985-2-git-send-email-julia@diku.dk>
>
> Reported-by: Julia Lawall <julia@diku.dk>
> Signed-off-by: Julian Calaby <julian.calaby@gmail.com>
> CC: Julia Lawall <julia@diku.dk>
>
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
> index b56a302..6ebec8f 100644
> --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
> +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
> @@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t
>
> static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
> {
> - uint dmactrlflags = di->dma.dmactrlflags;
> + uint dmactrlflags;
>
> if (di == NULL) {
> - DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
> + DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
> return 0;
> }
>
> + dmactrlflags = di->dma.dmactrlflags;
> dmactrlflags &= ~mask;
> dmactrlflags |= flags;
>
>
>
>
>
Hi Julian, Julia
That change looks good, but it does not apply on top of our pending
patches. Probably need to resend those after the merge window. I will
create a applying patch and send it to John (and resend later if
needed). Thanks for finding this one.
Gr. AvS
^ permalink raw reply
* Re: [PATCH] of: include errno.h
From: Geert Uytterhoeven @ 2011-10-29 8:38 UTC (permalink / raw)
To: Kalle Valo; +Cc: grant.likely, devicetree-discuss, linux-wireless, linux-kernel
In-Reply-To: <20111006124044.1066.7111.stgit@localhost6.localdomain6>
On Thu, Oct 6, 2011 at 14:40, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> When compiling ath6kl for beagleboard (omap2plus_defconfig plus
> CONFIG_ATH6KL, CONFIG_OF disable) with current linux-next compilation
> fails:
>
> include/linux/of.h:269: error: 'ENOSYS' undeclared (first use in this function)
> include/linux/of.h:276: error: 'ENOSYS' undeclared (first use in this function)
> include/linux/of.h:289: error: 'ENOSYS' undeclared (first use in this function)
And now this build failure (also on m68k) has hit Linus' tree, more
than 3 weeks after
its detection in -next...
> Fix this by including errno.h from of.h.
>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
> ---
> include/linux/of.h | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 9180dc5..219c29d 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -17,6 +17,7 @@
> */
> #include <linux/types.h>
> #include <linux/bitops.h>
> +#include <linux/errno.h>
> #include <linux/kref.h>
> #include <linux/mod_devicetable.h>
> #include <linux/spinlock.h>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH 4/4] mac80211: Populate QoS header on mesh frames sent to gates.
From: Thomas Pedersen @ 2011-10-29 5:05 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Javier Cardona, johannes, linville
In-Reply-To: <1319864732-11286-1-git-send-email-thomas@cozybit.com>
From: Javier Cardona <javier@cozybit.com>
Also set correct skb queue mapping once next hop is known, and set
txinfo jiffies when forwarding.
Signed-off-by: Javier Cardona <javier@cozybit.com>
---
net/mac80211/mesh_hwmp.c | 5 ++++-
net/mac80211/mesh_pathtbl.c | 5 +++++
net/mac80211/rx.c | 8 +++++---
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index b7d9dfd..d46109b 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1028,8 +1028,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
PREQ_Q_F_START | PREQ_Q_F_REFRESH);
}
next_hop = rcu_dereference(mpath->next_hop);
- if (next_hop)
+ if (next_hop) {
memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
+ skb_set_queue_mapping(skb,
+ ieee80211_select_queue(sdata, skb));
+ }
else
err = -ENOENT;
} else {
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 332b5ff1..9d2f55f 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -270,6 +270,11 @@ static void prepare_for_gate(struct sk_buff *skb, char *dst_addr,
memcpy(hdr->addr1, next_hop, ETH_ALEN);
rcu_read_unlock();
memcpy(hdr->addr3, dst_addr, ETH_ALEN);
+
+ /* once next hop is set we can set qos header */
+ skb_set_queue_mapping(skb,
+ ieee80211_select_queue(gate_mpath->sdata, skb));
+ ieee80211_set_qos_hdr(gate_mpath->sdata, skb);
}
/**
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ad39216..dc60a19 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1963,12 +1963,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
memset(info, 0, sizeof(*info));
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->control.vif = &rx->sdata->vif;
+ info->control.jiffies = jiffies;
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_mcast);
- skb_set_queue_mapping(fwd_skb,
- ieee80211_select_queue(sdata, fwd_skb));
- ieee80211_set_qos_hdr(sdata, fwd_skb);
} else {
int err;
/*
@@ -1989,6 +1987,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
}
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_frames);
+
+ /* next hop is now known, update the queue mapping */
+ skb_set_queue_mapping(fwd_skb,
+ ieee80211_select_queue(sdata, fwd_skb));
ieee80211_add_pending_skb(local, fwd_skb);
}
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH 3/4] mac80211: check if frame is really part of this BA
From: Thomas Pedersen @ 2011-10-29 5:05 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
In-Reply-To: <1319864732-11286-1-git-send-email-thomas@cozybit.com>
There was an an implicit assumption that any QoS data frame received
from a STA/TID with an active BA session was sent to this vif as part of
a BA. This is not true if IFF_PROMISC is enabled and the frame was
destined for a different peer, for example. Don't treat these frames as
part of a BA from the sending STA.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
net/mac80211/rx.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index ee9e71b..ad39216 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -776,6 +776,10 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
(ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)))
goto dont_reorder;
+ /* not actually part of this BA session */
+ if (compare_ether_addr(hdr->addr1, rx->sdata->vif.addr) != 0)
+ goto dont_reorder;
+
/* new, potentially un-ordered, ampdu frame - process it */
/* reset session timer */
--
1.7.5.4
^ permalink raw reply related
* [PATCH 2/4] mac80211: QoS multicast frames have No Ack policy
From: Thomas Pedersen @ 2011-10-29 5:05 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Thomas Pedersen, johannes, linville
In-Reply-To: <1319864732-11286-1-git-send-email-thomas@cozybit.com>
Previously QoS multicast frames had the Normal Acknowledgment QoS
control bits set. This would cause broadcast frames to be discarded by
peers with which we have a BA session, since their sequence number would
fall outside the allowed range. Set No Ack QoS control bits on multicast
QoS frames and filter these in de-aggregation code.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
net/mac80211/rx.c | 8 +++++++-
net/mac80211/wme.c | 3 ++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b867bd5..ee9e71b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -747,7 +747,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
struct sta_info *sta = rx->sta;
struct tid_ampdu_rx *tid_agg_rx;
u16 sc;
- int tid;
+ u8 tid, ack_policy;
if (!ieee80211_is_data_qos(hdr->frame_control))
goto dont_reorder;
@@ -760,6 +760,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
if (!sta)
goto dont_reorder;
+ ack_policy = *ieee80211_get_qos_ctl(hdr) & ~IEEE80211_QOS_CTL_TID_MASK;
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
@@ -770,6 +771,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
goto dont_reorder;
+ /* not part of a BA session */
+ if (!((ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK) ||
+ (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)))
+ goto dont_reorder;
+
/* new, potentially un-ordered, ampdu frame - process it */
/* reset session timer */
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index fd52e69..a440a4a 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -147,7 +147,8 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
- if (unlikely(sdata->local->wifi_wme_noack_test))
+ if (unlikely(sdata->local->wifi_wme_noack_test) ||
+ is_multicast_ether_addr(hdr->addr1))
ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
/* qos header is 2 bytes */
*p++ = ack_policy | tid;
--
1.7.5.4
^ permalink raw reply related
* [PATCH 1/4] mac80211: Avoid filling up mesh preq queue with redundant requests
From: Thomas Pedersen @ 2011-10-29 5:05 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, Javier Cardona, johannes, linville
From: Javier Cardona <javier@cozybit.com>
Don't accept redundant PREQs for a given destination. This fixes a
problem under high load:
kernel: [20386.250913] mesh_queue_preq: 235 callbacks suppressed
kernel: [20386.253335] Mesh HWMP (mesh0): PREQ node queue full
kernel: [20386.253352] Mesh HWMP (mesh0): PREQ node queue full
(...)
The 802.11s protocol has a provision to limit the rate of path requests
(PREQs) are transmitted (dot11MeshHWMPpreqMinInterval) but there was no
limit on the rate at which PREQs were being queued up. There is a valid
reason for queuing PREQs: this way we can even out PREQ bursts. But
queueing multiple PREQs for the same destination is useless.
Reported-by: Pedro Larbig <pedro.larbig@carhs.de>
Signed-off-by: Javier Cardona <javier@cozybit.com>
---
v2: fix merge conflict
net/mac80211/mesh.h | 3 +++
net/mac80211/mesh_hwmp.c | 15 +++++++++++++--
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 8c00e2d..b3745e8 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -31,6 +31,8 @@
* @MESH_PATH_FIXED: the mesh path has been manually set and should not be
* modified
* @MESH_PATH_RESOLVED: the mesh path can has been resolved
+ * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination
+ * already queued up, waiting for the discovery process to start.
*
* MESH_PATH_RESOLVED is used by the mesh path timer to
* decide when to stop or cancel the mesh path discovery.
@@ -41,6 +43,7 @@ enum mesh_path_flags {
MESH_PATH_SN_VALID = BIT(2),
MESH_PATH_FIXED = BIT(3),
MESH_PATH_RESOLVED = BIT(4),
+ MESH_PATH_REQ_QUEUED = BIT(5),
};
/**
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 9a1f8bb..b7d9dfd 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -867,9 +867,19 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
return;
}
+ spin_lock_bh(&mpath->state_lock);
+ if (mpath->flags & MESH_PATH_REQ_QUEUED) {
+ spin_unlock_bh(&mpath->state_lock);
+ spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
+ return;
+ }
+
memcpy(preq_node->dst, mpath->dst, ETH_ALEN);
preq_node->flags = flags;
+ mpath->flags |= MESH_PATH_REQ_QUEUED;
+ spin_unlock_bh(&mpath->state_lock);
+
list_add_tail(&preq_node->list, &ifmsh->preq_queue.list);
++ifmsh->preq_queue_len;
spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
@@ -921,6 +931,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
goto enddiscovery;
spin_lock_bh(&mpath->state_lock);
+ mpath->flags &= ~MESH_PATH_REQ_QUEUED;
if (preq_node->flags & PREQ_Q_F_START) {
if (mpath->flags & MESH_PATH_RESOLVING) {
spin_unlock_bh(&mpath->state_lock);
@@ -1028,8 +1039,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
mesh_queue_preq(mpath, PREQ_Q_F_START);
}
- if (skb_queue_len(&mpath->frame_queue) >=
- MESH_FRAME_QUEUE_LEN)
+ if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN)
skb_to_free = skb_dequeue(&mpath->frame_queue);
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
@@ -1062,6 +1072,7 @@ void mesh_path_timer(unsigned long data)
++mpath->discovery_retries;
mpath->discovery_timeout *= 2;
spin_unlock_bh(&mpath->state_lock);
+ mpath->flags &= ~MESH_PATH_REQ_QUEUED;
mesh_queue_preq(mpath, 0);
} else {
mpath->flags = 0;
--
1.7.5.4
^ permalink raw reply related
* Re: wifi iwlagn fails to authenticate after wake from suspend
From: Gene Smith @ 2011-10-29 4:32 UTC (permalink / raw)
To: linux-wireless; +Cc: linux-kernel
In-Reply-To: <alpine.DEB.2.00.1110252325090.20273@chino.kir.corp.google.com>
David Rientjes wrote, On 10/26/2011 02:27 AM:
>
> So we need to bisect between 2.4.38 and 3.0.0? :) I'm running ubuntu
> 11.10 on a home laptop so I'll give this a try as well when I can if I can
> put up with unity for that long.
>
Hi,
Any results on this home laptop test yet? (Running kde-ubuntu here :) ).
^ permalink raw reply
* Re: [PATCH 2/5] drivers/net/wireless/brcm80211/brcmsmac/dma.c: eliminate a null pointer dereference
From: Julian Calaby @ 2011-10-29 2:27 UTC (permalink / raw)
To: Julia Lawall
Cc: John W. Linville, kernel-janitors, linux-wireless, netdev,
linux-kernel
In-Reply-To: <1319846297-2985-2-git-send-email-julia@diku.dk>
On 29/10/11 10:58, Julia Lawall wrote:
> From: Julia Lawall <julia@diku.dk>
>
> Delete di->name from the error reporting code, as it is meaningless if di
> is NULL.
>
> The semantic match that finds this problem is as follows:
> (http://coccinelle.lip6.fr/)
>
> // <smpl>
> @r@
> expression E, E1;
> identifier f;
> statement S1,S2,S3;
> @@
>
> if (E == NULL)
> {
> ... when != if (E == NULL || ...) S1 else S2
> when != E = E1
> *E->f
> ... when any
> return ...;
> }
> else S3
> // </smpl>
>
> Signed-off-by: Julia Lawall <julia@diku.dk>
>
> ---
> drivers/net/wireless/brcm80211/brcmsmac/dma.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
> index b56a302..1d66f53 100644
> --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
> +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
> @@ -361,7 +361,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
> uint dmactrlflags = di->dma.dmactrlflags;
If di is null, we've already failed as it's dereferenced here.
> if (di == NULL) {
> - DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
> + DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
> return 0;
> }
So, a better patch would be something like this:
(apologies if this doesn't apply - I've pretty much built it manually)
---
Though it's unlikely, di may be null, so we can't dereference
di->dma.dmactrlflags until we've checked it.
Move this de-reference after the check, and adjust the error
message to not require de-referencing di.
This is based upon Julia's original patch:
<1319846297-2985-2-git-send-email-julia@diku.dk>
Reported-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Julian Calaby <julian.calaby@gmail.com>
CC: Julia Lawall <julia@diku.dk>
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index b56a302..6ebec8f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t
static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
{
- uint dmactrlflags = di->dma.dmactrlflags;
+ uint dmactrlflags;
if (di == NULL) {
- DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+ DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
return 0;
}
+ dmactrlflags = di->dma.dmactrlflags;
dmactrlflags &= ~mask;
dmactrlflags |= flags;
--
Julian Calaby
Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
.Plan: http://sites.google.com/site/juliancalaby
^ permalink raw reply related
* [PATCH 2/5] drivers/net/wireless/brcm80211/brcmsmac/dma.c: eliminate a null pointer dereference
From: Julia Lawall @ 2011-10-28 23:58 UTC (permalink / raw)
To: John W. Linville; +Cc: kernel-janitors, linux-wireless, netdev, linux-kernel
From: Julia Lawall <julia@diku.dk>
Delete di->name from the error reporting code, as it is meaningless if di
is NULL.
The semantic match that finds this problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@r@
expression E, E1;
identifier f;
statement S1,S2,S3;
@@
if (E == NULL)
{
... when != if (E == NULL || ...) S1 else S2
when != E = E1
*E->f
... when any
return ...;
}
else S3
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
---
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index b56a302..1d66f53 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -361,7 +361,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
uint dmactrlflags = di->dma.dmactrlflags;
if (di == NULL) {
- DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+ DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n"));
return 0;
}
^ permalink raw reply related
* [wireless-next PATCH v2 4/4] ath9k: Support modifying AMSDU and AMPDU settings.
From: greearb @ 2011-10-28 22:21 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <1319840474-2618-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
The driver appears to function properly with these
values modified from defaults, so add the feature
definitions.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 af1b325... 3f4e679... M drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/init.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index af1b325..3f4e679 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -673,6 +673,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SPECTRUM_MGMT |
+ IEEE80211_HW_SUPPORTS_AMPDU_MOD |
+ IEEE80211_HW_SUPPORTS_AMSDU_MOD |
IEEE80211_HW_REPORTS_TX_ACK_STATUS;
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
--
1.7.3.4
^ permalink raw reply related
* [wireless-next PATCH v2 3/4] wifi: Allow overriding some HT information.
From: greearb @ 2011-10-28 22:21 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <1319840474-2618-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
* Allow configuring the mcs (/n) rates available.
* Allow configuration of MAX-A-MSDU
* Allow configuration of A-MPDU factor & density.
Users can only remove existing rates. The MSDU and MPDU
values can be set to any value allowed by the 802.11n
specification, provided the hardware has enabled the
proper feature bits (IEEE80211_HW_SUPPORTS_AMPDU_MOD
and/or IEEE80211_HW_SUPPORTS_AMSDU_MOD)
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
* Added HW capability flags so that only drivers with these flags
may modify the MPDU and MSDU settings.
* Add #define for the minimum required MCS rates instead of hard-coding 8.
:100644 100644 48363c3... 25ea406... M include/linux/ieee80211.h
:100644 100644 9f50f90... 971da1d... M include/linux/nl80211.h
:100644 100644 9d7a5e0... 802ff5f... M include/net/cfg80211.h
:100644 100644 dc1123a... a2cbe4a... M include/net/mac80211.h
:100644 100644 c63d7f0... 1ac1910... M net/mac80211/cfg.c
:100644 100644 f80a35c... 0753c96... M net/mac80211/ht.c
:100644 100644 f4a7618... f279ee9... M net/mac80211/ieee80211_i.h
:100644 100644 164cdb1... 681ba4e... M net/mac80211/mlme.c
:100644 100644 94472eb... 9b614f8... M net/mac80211/work.c
:100644 100644 404378d... 9507f2f... M net/wireless/nl80211.c
include/linux/ieee80211.h | 6 ++++
include/linux/nl80211.h | 3 ++
include/net/cfg80211.h | 4 ++
include/net/mac80211.h | 6 ++++
net/mac80211/cfg.c | 40 ++++++++++++++++++++++++-
net/mac80211/ht.c | 70 +++++++++++++++++++++++++++++++++++++++++++-
net/mac80211/ieee80211_i.h | 9 +++++-
net/mac80211/mlme.c | 4 +-
net/mac80211/work.c | 35 +++++++++++++++------
net/wireless/nl80211.c | 14 +++++++++
10 files changed, 176 insertions(+), 15 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48363c3..25ea406 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -906,6 +906,12 @@ struct ieee80211_mcs_info {
#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2
#define IEEE80211_HT_MCS_TX_MAX_STREAMS 4
#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION 0x10
+/*
+ * Stations supporting 802.11n are required to support
+ * at least the first 8 MCS rates. See section 7.3.2.56.4
+ * and 20.1.1 of the 802.11n spec.
+ */
+#define IEEE80211_HT_MCS_REQ_RATES_STA 8
/*
* 802.11n D5.0 20.3.5 / 20.6 says:
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 9f50f90..971da1d 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1113,6 +1113,8 @@ enum nl80211_commands {
* function as /a/b/g interfaces.
* @NL80211_ATTR_DISABLE_HT40: Disable HT-40 even if AP and hardware
* support it.
+ * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the HT_CAPs
+ * to pay attention to.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1344,6 +1346,7 @@ enum nl80211_attrs {
NL80211_ATTR_DISABLE_HT,
NL80211_ATTR_DISABLE_HT40,
+ NL80211_ATTR_HT_CAPABILITY_MASK,
/* add attributes here, update the policy in nl80211.c */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9d7a5e0..802ff5f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -256,11 +256,15 @@ struct ieee80211_supported_band {
* @use_4addr: use 4-address frames
* @disable_11n: Don't use 11n features (HT, etc)
* @disable_ht40: Don't use HT40, even if hardware & AP support it.
+ * @ht_capa: HT Capabilities for this interface.
+ * @ht_capa_mask: Bits of ht_capa that are to be used.
*/
struct vif_params {
int use_4addr;
int disable_11n;
int disable_ht40;
+ struct ieee80211_ht_cap *ht_capa;
+ struct ieee80211_ht_cap *ht_capa_mask;
};
/**
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dc1123a..a2cbe4a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1128,6 +1128,10 @@ enum sta_notify_cmd {
* @IEEE80211_HW_TX_AMPDU_SETUP_IN_HW: The device handles TX A-MPDU session
* setup strictly in HW. mac80211 should not attempt to do this in
* software.
+ * @IEEE80211_HW_SUPPORTS_AMPDU_MOD: The hardware can handle the full
+ * range of ampdu factor & density settings.
+ * @IEEE80211_HW_SUPPORTS_AMSDU_MOD: The hardware supports enabling
+ * and disabling IEEE80211_HT_CAP_MAX_AMSDU.
*/
enum ieee80211_hw_flags {
IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -1154,6 +1158,8 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21,
IEEE80211_HW_AP_LINK_PS = 1<<22,
IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23,
+ IEEE80211_HW_SUPPORTS_AMPDU_MOD = 1<<24,
+ IEEE80211_HW_SUPPORTS_AMSDU_MOD = 1<<25,
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c63d7f0..1ac1910 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -105,6 +105,44 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
}
}
+ if (params->ht_capa) {
+ u8 *caps = (u8 *)(params->ht_capa);
+ u8 *mask = (u8 *)(params->ht_capa_mask);
+ u8 *scaps = (u8 *)(&sdata->ht_capa);
+ u8 *smask = (u8 *)(&sdata->ht_capa_mask);
+ int i;
+
+ /* Check AMPDU and AMSDU capabilities */
+ if ((params->ht_capa_mask->ampdu_params_info &
+ (IEEE80211_HT_AMPDU_PARM_FACTOR |
+ IEEE80211_HT_AMPDU_PARM_DENSITY)) &&
+ !(sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_AMPDU_MOD))
+ return -EINVAL;
+
+ if ((params->ht_capa_mask->cap_info &
+ IEEE80211_HT_CAP_MAX_AMSDU) &&
+ !(sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_AMSDU_MOD))
+ return -EINVAL;
+
+ for (i = 0; i < sizeof(sdata->ht_capa); i++) {
+ if (mask[i]) {
+ int q;
+ smask[i] |= mask[i];
+ for (q = 0; q < 8; q++) {
+ if (mask[i] & (1<<q)) {
+ if (caps[i] & (1<<q))
+ scaps[i] |= (1<<q);
+ else
+ scaps[i] &= ~(1<<q);
+ }
+ }
+ }
+ }
+ } else if (params->ht_capa_mask) {
+ memcpy(&sdata->ht_capa_mask, params->ht_capa_mask,
+ sizeof(sdata->ht_capa_mask));
+ }
+
return 0;
}
@@ -784,7 +822,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
}
if (params->ht_capa)
- ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
params->ht_capa,
&sta->sta.ht_cap);
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index f80a35c..0753c96 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -18,7 +18,70 @@
#include "ieee80211_i.h"
#include "rate.h"
-void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
+void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ int min_rates)
+{
+ u8 *scaps = (u8 *)(&sdata->ht_capa.mcs.rx_mask);
+ u8 *smask = (u8 *)(&sdata->ht_capa_mask.mcs.rx_mask);
+ int i;
+
+ /* check for HT over-rides, mcs rates only at this time,
+ * and can only disable them, not force new ones to be
+ * made available.
+ */
+ for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
+ int q;
+ for (q = 0; q < 8; q++) {
+ /*
+ * We always need to advert at least MCS0-7, to
+ * be a compliant HT station, for instance
+ */
+ if (((i * 8 + q) >= min_rates) &&
+ (smask[i] & (1<<q))) {
+ if (!(scaps[i] & (1<<q))) {
+ /*
+ * Can only disable rates, not force
+ * new ones
+ */
+ ht_cap->mcs.rx_mask[i] &= ~(1<<q);
+ }
+ }
+ }
+ }
+
+ /* Force removal of HT-40 capabilities? */
+ if (sdata->cfg_disable_ht40) {
+ ht_cap->cap &= ~(IEEE80211_HT_CAP_SUP_WIDTH_20_40
+ | IEEE80211_HT_CAP_SGI_40);
+ }
+
+ /* Allow user to set max AMDSU bit. */
+ if (sdata->ht_capa_mask.cap_info & IEEE80211_HT_CAP_MAX_AMSDU) {
+ if (sdata->ht_capa.cap_info & IEEE80211_HT_CAP_MAX_AMSDU)
+ ht_cap->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+ else
+ ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+ }
+
+ /* Set the AMPDU factor */
+ if (sdata->ht_capa_mask.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_FACTOR)
+ ht_cap->ampdu_factor = sdata->ht_capa.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_FACTOR;
+
+ /* Set the AMPDU density */
+ if (sdata->ht_capa_mask.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY)
+ ht_cap->ampdu_density =
+ (sdata->ht_capa.ampdu_params_info &
+ IEEE80211_HT_AMPDU_PARM_DENSITY)
+ >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT;
+}
+
+
+void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
struct ieee80211_ht_cap *ht_cap_ie,
struct ieee80211_sta_ht_cap *ht_cap)
{
@@ -102,6 +165,11 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
/* handle MCS rate 32 too */
if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1)
ht_cap->mcs.rx_mask[32/8] |= 1;
+
+ /* If user has specified capability over-rides, take care
+ * of that here.
+ */
+ ieee80211_apply_htcap_overrides(sdata, ht_cap, 0);
}
void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f4a7618..f279ee9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -598,6 +598,9 @@ struct ieee80211_sub_if_data {
bool cfg_disable_11n; /* configured to disable 11n? */
bool cfg_disable_ht40; /* configured to not use HT-40 */
+ struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
+ struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
+
/* Fragment table for host-based reassembly */
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
unsigned int fragment_next;
@@ -1181,7 +1184,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev);
/* HT */
-void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
+void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ int min_rates);
+void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_supported_band *sband,
struct ieee80211_ht_cap *ht_cap_ie,
struct ieee80211_sta_ht_cap *ht_cap);
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 164cdb1..681ba4e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1571,7 +1571,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
- ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems.ht_cap_elem, &sta->sta.ht_cap);
ap_ht_cap_flags = sta->sta.ht_cap.cap;
@@ -1940,7 +1940,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems.ht_cap_elem, &sta->sta.ht_cap);
ap_ht_cap_flags = sta->sta.ht_cap.cap;
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 94472eb..9b614f8 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -94,7 +94,8 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
/* frame sending functions */
-static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
+static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
+ struct sk_buff *skb, const u8 *ht_info_ie,
struct ieee80211_supported_band *sband,
struct ieee80211_channel *channel,
enum ieee80211_smps_mode smps)
@@ -102,11 +103,11 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
struct ieee80211_ht_info *ht_info;
u8 *pos;
u32 flags = channel->flags;
- u16 cap = sband->ht_cap.cap;
+ u16 cap;
__le16 tmp;
+ struct ieee80211_sta_ht_cap ht_cap;
- if (!sband->ht_cap.ht_supported)
- return;
+ BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
if (!ht_info_ie)
return;
@@ -114,6 +115,20 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
return;
+ memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
+ /*
+ * This is for an association attempt, and stations must
+ * support at least the first 8 MCS rates. See section 20.1.1
+ * of the 802.11n spec for details.
+ */
+ ieee80211_apply_htcap_overrides(sdata, &ht_cap,
+ IEEE80211_HT_MCS_REQ_RATES_STA);
+
+ cap = ht_cap.cap;
+
+ if (!ht_cap.ht_supported)
+ return;
+
ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
/* determine capability flags */
@@ -166,13 +181,13 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
pos += sizeof(u16);
/* AMPDU parameters */
- *pos++ = sband->ht_cap.ampdu_factor |
- (sband->ht_cap.ampdu_density <<
- IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+ *pos++ = ht_cap.ampdu_factor |
+ (ht_cap.ampdu_density <<
+ IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
/* MCS set */
- memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
- pos += sizeof(sband->ht_cap.mcs);
+ memcpy(pos, &ht_cap.mcs, sizeof(ht_cap.mcs));
+ pos += sizeof(ht_cap.mcs);
/* extended capabilities */
pos += sizeof(__le16);
@@ -356,7 +371,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
if (wk->assoc.use_11n && wk->assoc.wmm_used &&
local->hw.queues >= 4)
- ieee80211_add_ht_ie(skb, wk->assoc.ht_information_ie,
+ ieee80211_add_ht_ie(sdata, skb, wk->assoc.ht_information_ie,
sband, wk->chan, wk->assoc.smps);
/* if present, add any custom non-vendor IEs that go after HT */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 404378d..9507f2f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1655,6 +1655,20 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
params.disable_ht40 = -1;
}
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
+ params.ht_capa_mask =
+ nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]);
+ change = true;
+ }
+
+ if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
+ if (!params.ht_capa_mask)
+ return -EINVAL;
+ params.ht_capa =
+ nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
+ change = true;
+ }
+
if (change)
err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms);
else
--
1.7.3.4
^ permalink raw reply related
* [wireless-next PATCH v2 2/4] wifi: Support disabling ht40.
From: greearb @ 2011-10-28 22:21 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <1319840474-2618-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Allows users to forceably disable HT40 support in station
interfaces.
Other interface types may be supported later.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
* Tweaked patch description, no other significant changes.
:100644 100644 8a317c9... 9f50f90... M include/linux/nl80211.h
:100644 100644 1331a5b... 9d7a5e0... M include/net/cfg80211.h
:100644 100644 8221a3a... c63d7f0... M net/mac80211/cfg.c
:100644 100644 72c6726... f4a7618... M net/mac80211/ieee80211_i.h
:100644 100644 393b480... 164cdb1... M net/mac80211/mlme.c
:100644 100644 db24d25... 404378d... M net/wireless/nl80211.c
include/linux/nl80211.h | 4 ++++
include/net/cfg80211.h | 2 ++
net/mac80211/cfg.c | 3 +++
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/mlme.c | 1 +
net/wireless/nl80211.c | 7 +++++++
6 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 8a317c9..9f50f90 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1111,6 +1111,8 @@ enum nl80211_commands {
*
* @NL80211_ATTR_DISABLE_HT: Force /n capable interfaces to instead
* function as /a/b/g interfaces.
+ * @NL80211_ATTR_DISABLE_HT40: Disable HT-40 even if AP and hardware
+ * support it.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1341,6 +1343,8 @@ enum nl80211_attrs {
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
NL80211_ATTR_DISABLE_HT,
+ NL80211_ATTR_DISABLE_HT40,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1331a5b..9d7a5e0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -255,10 +255,12 @@ struct ieee80211_supported_band {
* struct vif_params - describes virtual interface parameters
* @use_4addr: use 4-address frames
* @disable_11n: Don't use 11n features (HT, etc)
+ * @disable_ht40: Don't use HT40, even if hardware & AP support it.
*/
struct vif_params {
int use_4addr;
int disable_11n;
+ int disable_ht40;
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 8221a3a..c63d7f0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -60,6 +60,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
if (params->disable_11n != -1)
sdata->cfg_disable_11n = params->disable_11n;
+ if (params->disable_ht40 != -1)
+ sdata->cfg_disable_ht40 = params->disable_ht40;
+
ret = ieee80211_if_change_type(sdata, type);
if (ret)
return ret;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 72c6726..f4a7618 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -596,6 +596,7 @@ struct ieee80211_sub_if_data {
bool old_idle;
bool cfg_disable_11n; /* configured to disable 11n? */
+ bool cfg_disable_ht40; /* configured to not use HT-40 */
/* Fragment table for host-based reassembly */
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 393b480..164cdb1 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -207,6 +207,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
channel_type = NL80211_CHAN_HT20;
if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
+ !sdata->cfg_disable_ht40 &&
(sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
(hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index db24d25..404378d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1648,6 +1648,13 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
params.disable_11n = -1;
}
+ if (info->attrs[NL80211_ATTR_DISABLE_HT40]) {
+ params.disable_ht40 = !!nla_get_u8(info->attrs[NL80211_ATTR_DISABLE_HT40]);
+ change = true;
+ } else {
+ params.disable_ht40 = -1;
+ }
+
if (change)
err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms);
else
--
1.7.3.4
^ permalink raw reply related
* [wireless-next PATCH v2 1/4] mac80211: Support forcing station to disable 11n.
From: greearb @ 2011-10-28 22:21 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
This allows a user to configure a wifi station interface
to disable 802.11n, even if the AP and NIC supports it.
Other interface types may be supported in the future.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
* Renamed NL80211_ATTR_DISABLE_11N to NL80211_ATTR_DISABLE_HT
* Fix patched description w/regard to 'netlink bits'.
* Didn't add checks for capability bits or nor moved the disable_11n
flag to u.mgd, pending answers to earlier questions.
:100644 100644 8049bf7... 8a317c9... M include/linux/nl80211.h
:100644 100644 92cf1c2... 1331a5b... M include/net/cfg80211.h
:100644 100644 e253afa... 8221a3a... M net/mac80211/cfg.c
:100644 100644 4c3d1f5... 72c6726... M net/mac80211/ieee80211_i.h
:100644 100644 0e5d8da... 393b480... M net/mac80211/mlme.c
:100644 100644 48260c2... db24d25... M net/wireless/nl80211.c
include/linux/nl80211.h | 4 ++++
include/net/cfg80211.h | 4 +++-
net/mac80211/cfg.c | 3 +++
net/mac80211/ieee80211_i.h | 2 ++
net/mac80211/mlme.c | 3 +++
net/wireless/nl80211.c | 7 +++++++
6 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 8049bf7..8a317c9 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1109,6 +1109,9 @@ enum nl80211_commands {
* %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
* used for asking the driver to perform a TDLS operation.
*
+ * @NL80211_ATTR_DISABLE_HT: Force /n capable interfaces to instead
+ * function as /a/b/g interfaces.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1337,6 +1340,7 @@ enum nl80211_attrs {
NL80211_ATTR_TDLS_SUPPORT,
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+ NL80211_ATTR_DISABLE_HT,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 92cf1c2..1331a5b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -254,9 +254,11 @@ struct ieee80211_supported_band {
/**
* struct vif_params - describes virtual interface parameters
* @use_4addr: use 4-address frames
+ * @disable_11n: Don't use 11n features (HT, etc)
*/
struct vif_params {
- int use_4addr;
+ int use_4addr;
+ int disable_11n;
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e253afa..8221a3a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -57,6 +57,9 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int ret;
+ if (params->disable_11n != -1)
+ sdata->cfg_disable_11n = params->disable_11n;
+
ret = ieee80211_if_change_type(sdata, type);
if (ret)
return ret;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4c3d1f5..72c6726 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -595,6 +595,8 @@ struct ieee80211_sub_if_data {
/* to detect idle changes */
bool old_idle;
+ bool cfg_disable_11n; /* configured to disable 11n? */
+
/* Fragment table for host-based reassembly */
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
unsigned int fragment_next;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0e5d8da..393b480 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2597,6 +2597,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+ if (sdata->cfg_disable_11n)
+ ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+
if (req->ie && req->ie_len) {
memcpy(wk->ie, req->ie, req->ie_len);
wk->ie_len = req->ie_len;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 48260c2..db24d25 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1641,6 +1641,13 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
change = true;
}
+ if (info->attrs[NL80211_ATTR_DISABLE_HT]) {
+ params.disable_11n = !!nla_get_u8(info->attrs[NL80211_ATTR_DISABLE_HT]);
+ change = true;
+ } else {
+ params.disable_11n = -1;
+ }
+
if (change)
err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms);
else
--
1.7.3.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