* Re: [PATCH] Implementation of the IEEE80211_RADIOTAP_RATE option
From: Rafael Laufer @ 2009-08-21 18:03 UTC (permalink / raw)
To: Gábor Stefanik; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <69e28c910908210630m47eda1eegcd502c212736decd@mail.gmail.com>
Gábor Stefanik wrote:
>
> Maybe a new IEEE80211_TX_CTL_ or IEEE80211_TX_RC_ flag will also be
> needed, so Radiotap can indicate whether rate_control_get_rate needs
> to be called.
ok, I am resending the patch. I included a new flag called
IEEE80211_TX_CTL_RATE_RADIOTAP to indicate if the rate has
been set in the radiotap header. If not, then the rate control
algorithm is called.
Note that in the future there must be other flags like this to
indicate if other parameters, such as power, was also set in
the radiotap header.
Signed-off-by: Rafael Laufer <rlaufer@cs.ucla.edu>
---
Implementation of the IEEE80211_RADIOTAP_RATE
option when parsing radiotap headers to allow
rate selection on a per-packet basis. A new
flag IEEE80211_TX_CTL_RATE_RADIOTAP is also
included to indicate that the rate was set in
the radiotap header and therefore the rate
control algorithm should not change it.
include/net/mac80211.h | 4 ++++
net/mac80211/tx.c | 22 +++++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index aac84d7..819b01e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -272,6 +272,9 @@ struct ieee80211_bss_conf {
* transmit function after the current frame, this can be used
* by drivers to kick the DMA queue only if unset or when the
* queue gets full.
+ * @IEEE80211_TX_CTL_RATE_RADIOTAP: completely internal to mac80211,
+ * used to indicate that the rate was defined in the received radiotap
+ * header and therefore the rate control algorithm should not change it.
*/
enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -293,6 +296,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
IEEE80211_TX_CTL_PSPOLL_RESPONSE = BIT(17),
IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),
+ IEEE80211_TX_CTL_RATE_RADIOTAP = BIT(19),
};
/**
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 10a1099..f675844 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -549,7 +549,12 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
* If we're associated with the sta at this point we know we can at
* least send the frame at the lowest bit rate.
*/
- rate_control_get_rate(tx->sdata, tx->sta, &txrc);
+
+ /* In monitor mode, if the IEEE80211_RADIOTAP_RATE option is set in
+ * the received radiotap header, do not call the rate control algorithm.
+ */
+ if (likely(!(info->flags & IEEE80211_TX_CTL_RATE_RADIOTAP)))
+ rate_control_get_rate(tx->sdata, tx->sta, &txrc);
if (unlikely(info->control.rates[0].idx < 0))
return TX_DROP;
@@ -972,6 +977,21 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
tx->flags |= IEEE80211_TX_FRAGMENTED;
break;
+ /* Get the rate parameter from the radiotap header,
+ * allowing rate selection on a per-packet basis
+ */
+ case IEEE80211_RADIOTAP_RATE:
+ bitrate = (*iterator.this_arg) * 5;
+ for (i = 0; i < sband->n_bitrates; i++) {
+ if (sband->bitrates[i].bitrate == bitrate)
+ break;
+ }
+ if (i != sband->n_bitrates) {
+ info->control.rates[0].idx = i;
+ info->flags |= IEEE80211_TX_CTL_RATE_RADIOTAP;
+ }
+ break;
+
/*
* Please update the file
* Documentation/networking/mac80211-injection.txt
--
1.6.0.4
^ permalink raw reply related
* Re: [PATCH] iwlwifi: Make injection of non-broadcast frames work again
From: reinette chatre @ 2009-08-21 17:59 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Zhu, Yi, Guy, Wey-Yi W, Rafael Laufer,
ipw3945-devel, linux-wireless
In-Reply-To: <69e28c910908211024n1c255b3p160839c60ae0b3a@mail.gmail.com>
Hi Gábor,
On Fri, 2009-08-21 at 10:24 -0700, Gábor Stefanik wrote:
> For some odd reason, reverting Wei-Yi Guy's patch makes the bug go
> away
ah - now I see. The driver defaulted to monitor mode in iwl_mac_start.
This is not correct and this patch rightly removed that code.
> ... should we do that instead for 2.6.31? (I'm all for it, if this
> patch is not the right thing to do, as Wey-Yi's patch was not a bug
> fix, just a cleanup.)
No, this patch was more than code cleanup - it changed the driver to
behave correctly wrt monitor interface type. Unfortunately the
workaround to get packet injection working was not apparent enough and
was missed.
> My guess is that the "default to MONITOR mode"
> change is the culprit.
yeah ...
> Maybe we should check info->flags & IEEE80211_TX_CTL_INJECTED
> instead... is there a way to access the ieee80211_tx_info structure
> from this function (e.g. through priv)?
No, but it may not be necessary. Why is is necessary to call this
function in the first place if you know this is an injection packet?
Specifically, in iwl_tx_skb and iwl3945_tx_skb (where ieee80211_tx_info)
is known) there could just be a test if this is an injected packet, if
it is, then do not call iwl_get_sta_id, but just use "bcast_sta_id"
directly. Would this work? Is a test for monitor mode still needed in
this case?
Reinette
^ permalink raw reply
* Re: pull request: wireless-2.6 2009-08-21
From: Larry Finger @ 2009-08-21 17:25 UTC (permalink / raw)
To: John W. Linville; +Cc: davem, linux-wireless, netdev, linux-kernel
In-Reply-To: <20090821170324.GC8532@tuxdriver.com>
John W. Linville wrote:
> Dave,
>
> One more straggler for 2.6.31...without this rtl8187b devices simply
> don't work. :-(
>
> The patch is small and isolated to rtl8187. I think we should take
> it for 2.6.31.
Note: This patch should fix Bugzilla #13960, which is a regression
since 2.6.30. The OP has not yet reported back, but it fixed the same
condition on my computer.
^ permalink raw reply
* Re: [PATCH] iwlwifi: Make injection of non-broadcast frames work again
From: Gábor Stefanik @ 2009-08-21 17:24 UTC (permalink / raw)
To: reinette chatre
Cc: John Linville, Zhu, Yi, Guy, Wey-Yi W, Rafael Laufer,
ipw3945-devel, linux-wireless
In-Reply-To: <1250872433.30019.14430.camel@rc-desk>
2009/8/21 reinette chatre <reinette.chatre@intel.com>:
> Hi Gábor,
>
> On Thu, 2009-08-20 at 15:08 -0700, Gábor Stefanik wrote:
>> Commit 1ccb84d87d04df3c76cd4352fe69786d8c7cf016 by Wey-Yi Guy
>> ("iwlwifi: clean up unused NL80211_IFTYPE_MONITOR for Monitor mode")
>> broke injection of non-broadcast frames to unassociated stations
>> (causing a SYSASSERT for all such injected frames), due to injected
>> frames no longer automatically getting a broadcast station ID assigned,
>> and instead ending up with invalid station IDs.
>> This patch restores the old behavior, fixing the aforementioned
>> regression.
>
> The patch you are quoting cannot be the culprit here. As that commit
> message indicates we never set NL80211_IFTYPE_MONITOR for the interface
> type, so when that code removed the test for this interface type in
> iwl_get_sta_id it essentially removed dead code.
For some odd reason, reverting Wei-Yi Guy's patch makes the bug go
away... should we do that instead for 2.6.31? (I'm all for it, if this
patch is not the right thing to do, as Wey-Yi's patch was not a bug
fix, just a cleanup.) My guess is that the "default to MONITOR mode"
change is the culprit.
>
>> /* If this frame is broadcast or management, use broadcast station id */
>> - if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
>> + if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
>> + iwl_is_monitor_mode(priv)) /* Injected frames need broadcast too */
>> return priv->hw_params.bcast_sta_id;
>
> I think my comment ties in with what Johannes said. When we are
> associated (whether in station, adhoc, or AP mode) we want this function
> to return the correct station ID. We also know that an interface can be
> in monitor mode while it is in any of these other modes. When this
> happens we do not want to return the broadcast station id ... we still
> want to return the station id. Your patch changes this behavior and will
> in this case always return the broadcast station id.
Maybe we should check info->flags & IEEE80211_TX_CTL_INJECTED
instead... is there a way to access the ieee80211_tx_info structure
from this function (e.g. through priv)?
>
> Reinette
>
>
>
>
>
--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
^ permalink raw reply
* pull request: wireless-2.6 2009-08-21
From: John W. Linville @ 2009-08-21 17:03 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
Dave,
One more straggler for 2.6.31...without this rtl8187b devices simply
don't work. :-(
The patch is small and isolated to rtl8187. I think we should take
it for 2.6.31.
Please let me know if there are problems!
John
---
Patch available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-2.6/
---
The following changes since commit 08fdef99342955a62884fb5c49ab43431a1cafbf:
David S. Miller (1):
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master
Herton Ronaldo Krzesinski (1):
rtl8187: always set MSR_LINK_ENEDCA flag with RTL8187B
drivers/net/wireless/rtl818x/rtl8187_dev.c | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 294250e..87a9558 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -869,6 +869,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
priv->aifsn[3] = 3; /* AIFSN[AC_BE] */
rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
+ /* ENEDCA flag must always be set, transmit issues? */
+ rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA);
+
return 0;
}
@@ -1173,13 +1176,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
rtl818x_iowrite8(priv, &priv->map->BSSID[i],
info->bssid[i]);
+ if (priv->is_rtl8187b)
+ reg = RTL818X_MSR_ENEDCA;
+ else
+ reg = 0;
+
if (is_valid_ether_addr(info->bssid)) {
- reg = RTL818X_MSR_INFRA;
- if (priv->is_rtl8187b)
- reg |= RTL818X_MSR_ENEDCA;
+ reg |= RTL818X_MSR_INFRA;
rtl818x_iowrite8(priv, &priv->map->MSR, reg);
} else {
- reg = RTL818X_MSR_NO_LINK;
+ reg |= RTL818X_MSR_NO_LINK;
rtl818x_iowrite8(priv, &priv->map->MSR, reg);
}
--
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 related
* Re: [PATCH] iwlwifi: Make injection of non-broadcast frames work again
From: John W. Linville @ 2009-08-21 16:43 UTC (permalink / raw)
To: reinette chatre
Cc: Gábor Stefanik, Zhu, Yi, Guy, Wey-Yi W, Rafael Laufer,
ipw3945-devel, linux-wireless
In-Reply-To: <1250872433.30019.14430.camel@rc-desk>
On Fri, Aug 21, 2009 at 09:33:53AM -0700, reinette chatre wrote:
> Hi Gábor,
>
> On Thu, 2009-08-20 at 15:08 -0700, Gábor Stefanik wrote:
> > Commit 1ccb84d87d04df3c76cd4352fe69786d8c7cf016 by Wey-Yi Guy
> > ("iwlwifi: clean up unused NL80211_IFTYPE_MONITOR for Monitor mode")
> > broke injection of non-broadcast frames to unassociated stations
> > (causing a SYSASSERT for all such injected frames), due to injected
> > frames no longer automatically getting a broadcast station ID assigned,
> > and instead ending up with invalid station IDs.
> > This patch restores the old behavior, fixing the aforementioned
> > regression.
>
> The patch you are quoting cannot be the culprit here. As that commit
> message indicates we never set NL80211_IFTYPE_MONITOR for the interface
> type, so when that code removed the test for this interface type in
> iwl_get_sta_id it essentially removed dead code.
>
> > /* If this frame is broadcast or management, use broadcast station id */
> > - if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
> > + if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
> > + iwl_is_monitor_mode(priv)) /* Injected frames need broadcast too */
> > return priv->hw_params.bcast_sta_id;
>
> I think my comment ties in with what Johannes said. When we are
> associated (whether in station, adhoc, or AP mode) we want this function
> to return the correct station ID. We also know that an interface can be
> in monitor mode while it is in any of these other modes. When this
> happens we do not want to return the broadcast station id ... we still
> want to return the station id. Your patch changes this behavior and will
> in this case always return the broadcast station id.
Dropping on the basis of this. Please repost when/if this is resolved.
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: [PATCH] iwlwifi: Make injection of non-broadcast frames work again
From: reinette chatre @ 2009-08-21 16:33 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Zhu, Yi, Guy, Wey-Yi W, Rafael Laufer,
ipw3945-devel, linux-wireless
In-Reply-To: <4A8DC955.9060100@gmail.com>
Hi Gábor,
On Thu, 2009-08-20 at 15:08 -0700, Gábor Stefanik wrote:
> Commit 1ccb84d87d04df3c76cd4352fe69786d8c7cf016 by Wey-Yi Guy
> ("iwlwifi: clean up unused NL80211_IFTYPE_MONITOR for Monitor mode")
> broke injection of non-broadcast frames to unassociated stations
> (causing a SYSASSERT for all such injected frames), due to injected
> frames no longer automatically getting a broadcast station ID assigned,
> and instead ending up with invalid station IDs.
> This patch restores the old behavior, fixing the aforementioned
> regression.
The patch you are quoting cannot be the culprit here. As that commit
message indicates we never set NL80211_IFTYPE_MONITOR for the interface
type, so when that code removed the test for this interface type in
iwl_get_sta_id it essentially removed dead code.
> /* If this frame is broadcast or management, use broadcast station id */
> - if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
> + if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
> + iwl_is_monitor_mode(priv)) /* Injected frames need broadcast too */
> return priv->hw_params.bcast_sta_id;
I think my comment ties in with what Johannes said. When we are
associated (whether in station, adhoc, or AP mode) we want this function
to return the correct station ID. We also know that an interface can be
in monitor mode while it is in any of these other modes. When this
happens we do not want to return the broadcast station id ... we still
want to return the station id. Your patch changes this behavior and will
in this case always return the broadcast station id.
Reinette
^ permalink raw reply
* Re: Plans for an online meeting regarding Radiotap
From: Johannes Berg @ 2009-08-21 15:11 UTC (permalink / raw)
To: Gábor Stefanik
Cc: Richard Farina, Mike Kershaw, Sam Leffler, Rafael Laufer,
Damien Bergamini, Sepherosa Ziehau, Thomas d'Otreppe,
Dave Young, radiotap, linux-wireless, freebsd-mobile,
misc-openbsd, tech-openbsd, netbsd-net, wireshark-dev
In-Reply-To: <69e28c910908210804h6181aab1w4a864392239aa1ac@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 939 bytes --]
On Fri, 2009-08-21 at 17:04 +0200, Gábor Stefanik wrote:
> I've reworked RTS/CTS since then, just haven't got to sending a new
> proposal yet. The current plan is as follows:
>
> TX_FLAGS & 0x0002: Use CTS
> TX_FLAGS & 0x0004: Use RTS
> TX_FLAGS & 0x0020: Disable RTS/CTS usage
Seems a bit strange, wouldn't setting neither RTS nor CTS have the
effect? Seems like 0x20 should rather be "use automatic and ignore the
other bits". Anyway, not appropriate here, you should just bring a new
proposal.
> If I remember correctly, I made an implementation for the Linux kernel
> (a generator-side implementation) and one for Wireshark (a parser-side
> implementation). Or should I make two generator-side implementations
> according to the requirement (e.g. one for Linux, another for
> OpenBSD)?
No, that was ok, I just meant that therefore by definition it can't be a
problem of lack of implementations.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: Plans for an online meeting regarding Radiotap
From: Gábor Stefanik @ 2009-08-21 15:04 UTC (permalink / raw)
To: Johannes Berg
Cc: Richard Farina, Mike Kershaw, Sam Leffler, Rafael Laufer,
Damien Bergamini, Sepherosa Ziehau, Thomas d'Otreppe,
Dave Young, radiotap, linux-wireless, freebsd-mobile,
misc-openbsd, tech-openbsd, netbsd-net, wireshark-dev
In-Reply-To: <1250865918.4600.9.camel@johannes.local>
2009/8/21 Johannes Berg <johannes@sipsolutions.net>:
> On Fri, 2009-08-21 at 16:41 +0200, Gábor Stefanik wrote:
>
>> My intention with the meeting is to form an actual proposal that all
>> implementors can agree on. We can produce proposals, and even new
>> standardized fields to no avail, as some implementors (especially
>> OpenBSD) appear to be stuck with implementations that collide with the
>> standard. These implementors need to be "awakened" and entered into
>> the discussions before anything can be done.
>
> There's nothing the standard can do about that. Like I said, we've
> talked about that enough in my opinion.
>
>> > Your own proposal had technical flaws (and in my opinion tried to do too
>> > much at a time) that you haven't addressed -- doing that would be much
>> > more productive than any such meeting.
>>
>> What technical flaws are you trying to point out exactly? (The TX
>> flags field? My point is that it's worthless to "standardize" TX flags
>> by extending it and moving to "Defined fields" if noone is willing to
>> implement it.)
>
> But people are already implementing it, and if they do something else
> that's their problem. The flaw I'm thinking of was over the RTS/CTS
> handling where some people (including myself) had comments.
I've reworked RTS/CTS since then, just haven't got to sending a new
proposal yet. The current plan is as follows:
TX_FLAGS & 0x0002: Use CTS
TX_FLAGS & 0x0004: Use RTS
TX_FLAGS & 0x0020: Disable RTS/CTS usage
Or, in more C++-like notation:
switch (TX_FLAGS & 0x0026) {
case 0x0002:
Use CTS;
break;
case 0x0004:
case 0x0006:
Use RTS;
break;
case 0x0020:
Disable RTS/CTS usage;
break;
default:
fall back to automatic selection
}
> Besides,
> you're supposed to make at least two implementations when proposing a
> standard field.
If I remember correctly, I made an implementation for the Linux kernel
(a generator-side implementation) and one for Wireshark (a parser-side
implementation). Or should I make two generator-side implementations
according to the requirement (e.g. one for Linux, another for
OpenBSD)?
>
> johannes
>
--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
^ permalink raw reply
* Re: Plans for an online meeting regarding Radiotap
From: Johannes Berg @ 2009-08-21 14:45 UTC (permalink / raw)
To: Gábor Stefanik
Cc: Richard Farina, Mike Kershaw, Sam Leffler, Rafael Laufer,
Damien Bergamini, Sepherosa Ziehau, Thomas d'Otreppe,
Dave Young, radiotap, linux-wireless, freebsd-mobile,
misc-openbsd, tech-openbsd, netbsd-net, wireshark-dev
In-Reply-To: <69e28c910908210741wd3bc391x311523f5b55fd4f1@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1325 bytes --]
On Fri, 2009-08-21 at 16:41 +0200, Gábor Stefanik wrote:
> My intention with the meeting is to form an actual proposal that all
> implementors can agree on. We can produce proposals, and even new
> standardized fields to no avail, as some implementors (especially
> OpenBSD) appear to be stuck with implementations that collide with the
> standard. These implementors need to be "awakened" and entered into
> the discussions before anything can be done.
There's nothing the standard can do about that. Like I said, we've
talked about that enough in my opinion.
> > Your own proposal had technical flaws (and in my opinion tried to do too
> > much at a time) that you haven't addressed -- doing that would be much
> > more productive than any such meeting.
>
> What technical flaws are you trying to point out exactly? (The TX
> flags field? My point is that it's worthless to "standardize" TX flags
> by extending it and moving to "Defined fields" if noone is willing to
> implement it.)
But people are already implementing it, and if they do something else
that's their problem. The flaw I'm thinking of was over the RTS/CTS
handling where some people (including myself) had comments. Besides,
you're supposed to make at least two implementations when proposing a
standard field.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: Plans for an online meeting regarding Radiotap
From: Gábor Stefanik @ 2009-08-21 14:41 UTC (permalink / raw)
To: Johannes Berg
Cc: Richard Farina, Mike Kershaw, Sam Leffler, Rafael Laufer,
Damien Bergamini, Sepherosa Ziehau, Thomas d'Otreppe,
Dave Young, radiotap, linux-wireless, freebsd-mobile,
misc-openbsd, tech-openbsd, netbsd-net, wireshark-dev
In-Reply-To: <1250865255.4600.6.camel@johannes.local>
2009/8/21 Johannes Berg <johannes@sipsolutions.net>:
> On Fri, 2009-08-21 at 16:31 +0200, Gábor Stefanik wrote:
>
>> Hope to see you on Freenode at the set date. Again, if the time is a
>> problem, respond, and I will try to find a better time.
>
> I don't think there's any need to have an IRC meeting. We've hashed out
> the way forward multiple times on the radiotap list. What is missing now
> isn't a consensus of how do things, but proposals and implementations.
My intention with the meeting is to form an actual proposal that all
implementors can agree on. We can produce proposals, and even new
standardized fields to no avail, as some implementors (especially
OpenBSD) appear to be stuck with implementations that collide with the
standard. These implementors need to be "awakened" and entered into
the discussions before anything can be done.
>
> Your own proposal had technical flaws (and in my opinion tried to do too
> much at a time) that you haven't addressed -- doing that would be much
> more productive than any such meeting.
What technical flaws are you trying to point out exactly? (The TX
flags field? My point is that it's worthless to "standardize" TX flags
by extending it and moving to "Defined fields" if noone is willing to
implement it.)
>
> johannes
>
--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
^ permalink raw reply
* [PATCH] libertas: clean up and clarify get_common_rates
From: Dan Williams @ 2009-08-21 14:35 UTC (permalink / raw)
To: linux-wireless; +Cc: Andrey Yurovsky, John W. Linville, Roel Kluin
Clarify what the heck the function is doing with better variable names
and less indirection and better comments. Also ensure callers use the
proper minimum size, even though all rates arrays should be size
MAX_RATES anyway. Reverts part of Andrey's dynamic alloc patch since we
don't really need it. Also leaves the passed-in rates array alone on
errors.
Signed-off-by: Dan Williams <dcbw@redhat.com>
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index e9b2731..bf16212 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -35,7 +35,8 @@ static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
*
* @param priv A pointer to struct lbs_private structure
* @param rates the buffer which keeps input and output
- * @param rates_size the size of rate1 buffer; new size of buffer on return
+ * @param rates_size the size of rates buffer; new size of buffer on return,
+ * which will be less than or equal to original rates_size
*
* @return 0 on success, or -1 on error
*/
@@ -43,46 +44,41 @@ static int get_common_rates(struct lbs_private *priv,
u8 *rates,
u16 *rates_size)
{
- u8 *card_rates = lbs_bg_rates;
int i, j;
- u8 *tmp;
- size_t tmp_size = 0;
+ u8 intersection[MAX_RATES];
+ u16 intersection_size;
+ u16 num_rates = 0;
- tmp = kzalloc(MAX_RATES * ARRAY_SIZE(lbs_bg_rates), GFP_KERNEL);
- if (!tmp)
- return -1;
+ intersection_size = min_t(u16, *rates_size, ARRAY_SIZE(intersection));
- /* For each rate in card_rates that exists in rate1, copy to tmp */
- for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && card_rates[i]; i++) {
- for (j = 0; j < *rates_size && rates[j]; j++) {
- if (rates[j] == card_rates[i])
- tmp[tmp_size++] = card_rates[i];
- }
- }
+ /* Allow each rate from 'rates' that is supported by the hardware */
+ for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && lbs_bg_rates[i]; i++) {
+ for (j = 0; j < intersection_size && rates[j]; j++) {
+ if (rates[j] == lbs_bg_rates[i])
+ intersection[num_rates++] = rates[j];
+ }
+ }
lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size);
- lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates,
+ lbs_deb_hex(LBS_DEB_JOIN, "card rates ", lbs_bg_rates,
ARRAY_SIZE(lbs_bg_rates));
- lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
+ lbs_deb_hex(LBS_DEB_JOIN, "common rates", intersection, num_rates);
lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
- memset(rates, 0, *rates_size);
- *rates_size = min_t(u16, tmp_size, *rates_size);
- memcpy(rates, tmp, *rates_size);
-
if (!priv->enablehwauto) {
- for (i = 0; i < tmp_size; i++) {
- if (tmp[i] == priv->cur_rate)
- break;
- }
- if (i == tmp_size) {
- lbs_pr_alert("Previously set fixed data rate %#x isn't "
- "compatible with the network.\n",
- priv->cur_rate);
- return -1;
+ for (i = 0; i < num_rates; i++) {
+ if (intersection[i] == priv->cur_rate)
+ goto done;
}
+ lbs_pr_alert("Previously set fixed data rate %#x isn't "
+ "compatible with the network.\n", priv->cur_rate);
+ return -1;
}
- kfree(tmp);
+
+done:
+ memset(rates, 0, *rates_size);
+ *rates_size = num_rates;
+ memcpy(rates, intersection, num_rates);
return 0;
}
@@ -325,7 +321,7 @@ static int lbs_associate(struct lbs_private *priv,
rates = (struct mrvl_ie_rates_param_set *) pos;
rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
- tmplen = min_t(u16, ARRAY_SIZE(rates->rates), MAX_RATES);
+ tmplen = min_t(u16, ARRAY_SIZE(bss->rates), MAX_RATES);
memcpy(&rates->rates, &bss->rates, tmplen);
if (get_common_rates(priv, rates->rates, &tmplen)) {
ret = -1;
@@ -600,7 +596,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
/* Copy Data rates from the rates recorded in scan response */
memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates));
- ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), MAX_RATES);
+ ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), ARRAY_SIZE (bss->rates));
memcpy(cmd.bss.rates, bss->rates, ratesize);
if (get_common_rates(priv, cmd.bss.rates, &ratesize)) {
lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n");
^ permalink raw reply related
* Re: Plans for an online meeting regarding Radiotap
From: Johannes Berg @ 2009-08-21 14:34 UTC (permalink / raw)
To: Gábor Stefanik
Cc: Richard Farina, Mike Kershaw, Sam Leffler, Rafael Laufer,
Damien Bergamini, Sepherosa Ziehau, Thomas d'Otreppe,
Dave Young, radiotap, linux-wireless, freebsd-mobile,
misc-openbsd, tech-openbsd, netbsd-net, wireshark-dev
In-Reply-To: <4A8EAFA6.9010608@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 614 bytes --]
On Fri, 2009-08-21 at 16:31 +0200, Gábor Stefanik wrote:
> Hope to see you on Freenode at the set date. Again, if the time is a
> problem, respond, and I will try to find a better time.
I don't think there's any need to have an IRC meeting. We've hashed out
the way forward multiple times on the radiotap list. What is missing now
isn't a consensus of how do things, but proposals and implementations.
Your own proposal had technical flaws (and in my opinion tried to do too
much at a time) that you haven't addressed -- doing that would be much
more productive than any such meeting.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Plans for an online meeting regarding Radiotap
From: Gábor Stefanik @ 2009-08-21 14:31 UTC (permalink / raw)
To: Johannes Berg, Richard Farina, Mike Kershaw, Sam Leffler,
Rafael Laufer, Damien Bergamini, Sepherosa Ziehau,
Thomas d'Otreppe, Dave Young
Cc: radiotap, linux-wireless, freebsd-mobile, misc-openbsd,
tech-openbsd, netbsd-net, wireshark-dev
Radiotap is a de-facto standard for 802.11 frame injection and reception.
Up to field ID 13, it can truly considered a standard (all current
implementations
agree on fields 1-13), but after that, implementations diverge widely.
Here is a map of how current implementations define field IDs 14 and up:
Linux (both mac80211 & madwifi, not sure about libertas) & NetBSD:
Field 14: RX flags (standardized field)
Field 15: TX flags
Field 16: RTS retries
Field 17: Data retries
FreeBSD:
Fields 14...17 skipped (incliding standardized field 14), field 18:
Extended channel
OpenBSD:
Field 14: FCS of the frame (clashes with standard - field 14 is defined
as RX flags!)
Field 15: Hardware queue
Field 16: RSSI
DragonFly BSD: No fields above 13 implemented.
Aircrack-ng:
Field 14: RX flags (as in the standard)
Field 15: TX flags
CACE AirPcap software:
Field 14: FCS of the frame (clashes with standard; the FCS is also appended
to the end of the packet, so this usage is unneeded)
Wireshark:
Field 14: RX flags, with option to decode FCS instead
Fields 15...17 skipped
Field 18: Extended channel
Radiotap fields 14 and up need to be sorted out to allow further
advancements
of the standard. In the current state, essentially no fields can be
added without
risking a collision between implementations. To remedy this, I would
like to propose
an online mini-summit to be held on Freenode, with the goal of defining
a standard
way to use fields 14 and up.
The summit is to be held in IRC channel #radiotap, where interested
parties can join
the discussion and propose changes. My preferred time for this event is
August 25, 2009, 18:00 GMT; please let me know if this date is
unsuitable for any of
you, and I will try to find a better time for the summit when everyone
interested can attend.
My current proposal for the future standard field ordering beyond field 14:
Field 14: RX flags (as defined by the standard)
Field 15: TX flags (as used by Linux, NetBSD and aircrack-ng)
Field 16: RTS retry count (as used by Linux and NetBSD)
Field 17: Data retry count (as used by Linux and NetBSD)
Field 18: Extended channel (as used by FreeBSD and Wireshark)
Field 19: RSSI (OpenBSD's field 16 moved to field ID 19 to avoid collisions)
In addition, the following new fields may be worth addition to the standard:
RTS threshold, Fragmentation threshold, Extended rate (with MCS index
support).
I'm deliberately not assigning field numbers to these proposed fields
yet to prevent
early, divergent implementations of them; the field IDs for these should
be decided
during the summit.
I'm for dropping the following fields, please let me know during the summit
if there are any use cases for them:
-FCS of the frame (if we have FCS data, then it should be appended to the
end of the frame, not put into the header)
-Hardware queue (I don't see the point of this... maybe a full QoS
control field
would be needed instead)
Hope to see you on Freenode at the set date. Again, if the time is a
problem,
respond, and I will try to find a better time.
Sincerely,
Gábor Stefanik <netrolller.3d@gmail.com>
^ permalink raw reply
* Re: WARNING: at net/mac80211/mlme.c:2292
From: Bob Copeland @ 2009-08-21 14:19 UTC (permalink / raw)
To: Fabio Comolli; +Cc: linux-wireless, Luis R. Rodriguez
In-Reply-To: <b6c5339f0908191442j6b5733f3rb28967060abdbace@mail.gmail.com>
On Wed, Aug 19, 2009 at 5:42 PM, Bob Copeland<me@bobcopeland.com> wrote:
> On Wed, Aug 19, 2009 at 4:47 PM, Fabio Comolli<fabio.comolli@gmail.com> wrote:
>> Hi all.
>> I see the following warning on an eeePC 900 (AR5001) running
>> 2.6.31-rc6 after a suspend/resume cycle:
>>
>> [ 292.377941] ------------[ cut here ]------------
>> [ 292.377976] WARNING: at net/mac80211/mlme.c:2292
>> ieee80211_sta_work+0x89/0xc39 [mac80211]()
>
> if (WARN_ON(local->suspended)) ...
Okay, I think I see what is going on here.
suspend
ieee80211_scan_cancel
ieee80211_notify_scan_completed
ieee80211_mlme_scan_completed
ieee80211_ibss_scan_completed
ieee80211_mesh_scan_completed
All of these completed() notifications queue work. That's not a problem
because we flush the workqueue shortly thereafter. However, flushing the
workqueue runs the scheduled work, which can queue _more_ work (sometimes
on a timer with queue_delayed_work), and none of the work functions in
2.6.31 currently check for local->quiesced.
Repeat this process once more and we eventually hit the warning.
Can we just replace the last flush_workqueue() with cancel_delayed_work_sync()
or will that break something?
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* [PATCH] mac80211: Remove unnused throughput field from minstrel_rate.
From: Arnd Hannemann @ 2009-08-21 14:11 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Arnd Hannemann
I noticed that the throughput field of the minstrel_rate struct is never used,
so remove it.
Signed-off-by: Arnd Hannemann <hannemann@nets.rwth-aachen.de>
---
net/mac80211/rc80211_minstrel.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 869fe0e..38bf416 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -33,7 +33,6 @@ struct minstrel_rate {
/* per-rate throughput */
u32 cur_tp;
- u32 throughput;
u64 succ_hist;
u64 att_hist;
--
1.5.4
^ permalink raw reply related
* Re: [PATCH] Implementation of the IEEE80211_RADIOTAP_RATE option
From: Gábor Stefanik @ 2009-08-21 13:30 UTC (permalink / raw)
To: Johannes Berg; +Cc: Rafael Laufer, linux-wireless
In-Reply-To: <1250842695.13872.5.camel@johannes.local>
On Fri, Aug 21, 2009 at 10:18 AM, Johannes
Berg<johannes@sipsolutions.net> wrote:
> On Thu, 2009-08-20 at 17:40 -0700, Rafael Laufer wrote:
>> This patch implements the IEEE80211_RADIOTAP_RATE
>> option when parsing radiotap headers to allow rate
>> selection on a per-packet basis.
>>
>>
>> Signed-off-by: Rafael Laufer <rlaufer@cs.ucla.edu>
>> ---
>> Implementation of the IEEE80211_RADIOTAP_RATE
>> option when parsing radiotap headers to allow
>> rate selection on a per-packet basis.
>>
>> net/mac80211/tx.c | 18 +++++++++++++++++-
>> 1 files changed, 17 insertions(+), 1 deletions(-)
>>
>> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
>> index 10a1099..41d636b 100644
>> --- a/net/mac80211/tx.c
>> +++ b/net/mac80211/tx.c
>> @@ -549,7 +549,10 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
>> * If we're associated with the sta at this point we know we can at
>> * least send the frame at the lowest bit rate.
>> */
>> - rate_control_get_rate(tx->sdata, tx->sta, &txrc);
>> +
>> + /* in monitor mode, we already have the rate from the radiotap header */
>> + if (likely(!(info->flags & IEEE80211_TX_CTL_INJECTED)))
>> + rate_control_get_rate(tx->sdata, tx->sta, &txrc);
>
> NAK, the rate is optional in the radiotap header, and if not given then
> regular rate control must be used.
>
> johannes
>
Also, I think something more powerful than the current "rate" field
would be needed, with support for MCS indexes, channel width, retry
count, etc. - one that can configure all values rate_control_get_rate
would perform. I'm planning a Radiotap meeting on Freenode with the
radiotap.h maintainers in various OSes participating, so the field 14+
mess can be cleaned up once for all - that's when I'll probably
propose this field.
Maybe a new IEEE80211_TX_CTL_ or IEEE80211_TX_RC_ flag will also be
needed, so Radiotap can indicate whether rate_control_get_rate needs
to be called.
--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
^ permalink raw reply
* Re: [PATCH] iwlwifi: Make injection of non-broadcast frames work again
From: Johannes Berg @ 2009-08-21 13:28 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Reinette Chatre, Zhu Yi, Wey-Yi Guy, Rafael Laufer,
ipw3945-devel, linux-wireless
In-Reply-To: <69e28c910908210621t3e239f09w6a2037e8c37b40ae@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 831 bytes --]
On Fri, 2009-08-21 at 15:21 +0200, Gábor Stefanik wrote:
> > And remove the warning in the
> > default case, since that's what happens if in pure monitor mode afaict.
>
> From my limited testing, in monitor mode, the vif type will be
> IFTYPE_STATION, so the default case is never hit. (Is this a bug?)
It's the way iwlwifi handles things I guess.
> (BTW now that in mac80211, we internally use IFTYPE_MONITOR in monitor
> mode, as opposed to just checking for a missing STA - why can't we
> propagate this to the drivers, and have a much saner way of informing
> the driver of monitor mode? This is especially a problem for zd1211rw,
> where to get proper monitor mode, ZD_SNIFFER_ON needs to be turned
> on.)
Think about it again (hint: multiple interfaces), and then ask the
question again.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH] libertas: don't use dynamic-sized array
From: Dan Williams @ 2009-08-21 13:24 UTC (permalink / raw)
To: Andrey Yurovsky; +Cc: linux-wireless
In-Reply-To: <1250701760.5351.42.camel@localhost.localdomain>
On Wed, 2009-08-19 at 12:09 -0500, Dan Williams wrote:
> On Thu, 2009-08-13 at 17:34 -0700, Andrey Yurovsky wrote:
> > sparse complains about a bad constant expression due to the use of a
> > dynamic-sized array in get_common_rates(). Allocate and free the array
> > instead.
>
> Mind testing this patch from libertas-dev? It should fix this but also
> clears up some of the confustion:
FWIW this patch now tested with sd8686.
Dan
> Subject:
> Re: Libertas: Association request to
> the driver failed
> Date:
> Wed, 12 Aug 2009 12:34:17 -0500
>
> Signed-off-by: Dan Williams <dcbw@redhat.com>
>
>
> diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
> index 1902b6f..8c05388 100644
> --- a/drivers/net/wireless/libertas/assoc.c
> +++ b/drivers/net/wireless/libertas/assoc.c
> @@ -35,7 +35,8 @@ static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
> *
> * @param priv A pointer to struct lbs_private structure
> * @param rates the buffer which keeps input and output
> - * @param rates_size the size of rate1 buffer; new size of buffer on return
> + * @param rates_size the size of rates buffer; new size of buffer on return,
> + * which will be less than or equal to original rates_size
> *
> * @return 0 on success, or -1 on error
> */
> @@ -43,39 +44,42 @@ static int get_common_rates(struct lbs_private *priv,
> u8 *rates,
> u16 *rates_size)
> {
> - u8 *card_rates = lbs_bg_rates;
> - int ret = 0, i, j;
> - u8 tmp[(ARRAY_SIZE(lbs_bg_rates) - 1) * (*rates_size - 1)];
> - size_t tmp_size = 0;
> -
> - /* For each rate in card_rates that exists in rate1, copy to tmp */
> - for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && card_rates[i]; i++) {
> - for (j = 0; j < *rates_size && rates[j]; j++) {
> - if (rates[j] == card_rates[i])
> - tmp[tmp_size++] = card_rates[i];
> + int i, j;
> + u8 intersection[MAX_RATES];
> + u16 intersection_size;
> + u16 num_rates = 0;
> +
> + intersection_size = min_t(u16, *rates_size, ARRAY_SIZE(intersection));
> +
> + /* Allow each rate from 'rates' that is supported by the hardware */
> + for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && lbs_bg_rates[i]; i++) {
> + for (j = 0; j < intersection_size && rates[j]; j++) {
> + if (rates[j] == lbs_bg_rates[i])
> + intersection[num_rates++] = rates[j];
> }
> }
>
> lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size);
> - lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates,
> + lbs_deb_hex(LBS_DEB_JOIN, "card rates ", lbs_bg_rates,
> ARRAY_SIZE(lbs_bg_rates));
> - lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
> + lbs_deb_hex(LBS_DEB_JOIN, "common rates", intersection, num_rates);
> lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
>
> if (!priv->enablehwauto) {
> - for (i = 0; i < tmp_size; i++) {
> - if (tmp[i] == priv->cur_rate)
> + for (i = 0; i < num_rates; i++) {
> + if (intersection[i] == priv->cur_rate)
> goto done;
> }
> lbs_pr_alert("Previously set fixed data rate %#x isn't "
> "compatible with the network.\n", priv->cur_rate);
> - ret = -1;
> + return -1;
> }
> +
> done:
> memset(rates, 0, *rates_size);
> - *rates_size = min_t(int, tmp_size, *rates_size);
> - memcpy(rates, tmp, *rates_size);
> - return ret;
> + *rates_size = num_rates;
> + memcpy(rates, intersection, num_rates);
> + return 0;
> }
>
>
> @@ -317,8 +321,8 @@ static int lbs_associate(struct lbs_private *priv,
>
> rates = (struct mrvl_ie_rates_param_set *) pos;
> rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
> - memcpy(&rates->rates, &bss->rates, MAX_RATES);
> - tmplen = min_t(u16, ARRAY_SIZE(rates->rates), MAX_RATES);
> + tmplen = min_t(u16, ARRAY_SIZE(bss->rates), MAX_RATES);
> + memcpy(&rates->rates, &bss->rates, tmplen);
> if (get_common_rates(priv, rates->rates, &tmplen)) {
> ret = -1;
> goto done;
> @@ -592,7 +596,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
>
> /* Copy Data rates from the rates recorded in scan response */
> memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates));
> - ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), MAX_RATES);
> + ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), ARRAY_SIZE (bss->rates));
> memcpy(cmd.bss.rates, bss->rates, ratesize);
> if (get_common_rates(priv, cmd.bss.rates, &ratesize)) {
> lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n");
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] iwlwifi: Make injection of non-broadcast frames work again
From: Gábor Stefanik @ 2009-08-21 13:21 UTC (permalink / raw)
To: Johannes Berg
Cc: John Linville, Reinette Chatre, Zhu Yi, Wey-Yi Guy, Rafael Laufer,
ipw3945-devel, linux-wireless
In-Reply-To: <1250842889.13872.8.camel@johannes.local>
2009/8/21 Johannes Berg <johannes@sipsolutions.net>:
> On Fri, 2009-08-21 at 00:08 +0200, Gábor Stefanik wrote:
>
>> /* If this frame is broadcast or management, use broadcast station id */
>> - if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
>> + if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
>> + iwl_is_monitor_mode(priv)) /* Injected frames need broadcast too */
>> return priv->hw_params.bcast_sta_id;
>
> Now you still can't transmit frames to another AP when connected to one,
> which will, for example, be required for 11r. IMHO that code should, in
> STATION mode, be checking the RA against the BSSID, and if they match
> use the AP ID, otherwise the bcast ID.
I'll probably do that, in a separate patch. This patch is a regression
fix targeted at the next 2.6.31-rc (injection of non-broadcasts works
fine in 2.6.30, but causes an ucode SYSASSERT in 2.6.31 and up). The
problem you are describing is not a regression AFAIK, it's something
that never worked; so it should be targeted @ 2.6.32.
> And remove the warning in the
> default case, since that's what happens if in pure monitor mode afaict.
>From my limited testing, in monitor mode, the vif type will be
IFTYPE_STATION, so the default case is never hit. (Is this a bug?)
(BTW now that in mac80211, we internally use IFTYPE_MONITOR in monitor
mode, as opposed to just checking for a missing STA - why can't we
propagate this to the drivers, and have a much saner way of informing
the driver of monitor mode? This is especially a problem for zd1211rw,
where to get proper monitor mode, ZD_SNIFFER_ON needs to be turned
on.)
>
> johannes
>
--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
^ permalink raw reply
* [PATCH v2] cfg80211: clean up properly on interface type change
From: Johannes Berg @ 2009-08-21 12:51 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <1250851157.14573.0.camel@johannes.local>
When the interface type changes while connected, and the
driver does not require the interface to be down for a
type change, it is currently possible to get very strange
results unless the driver takes special care, which it
shouldn't have to.
To fix this, take care to disconnect/leave IBSS when
changing the interface type -- even if the driver may fail
the call. Also process all events that may be pending to
avoid running into a situation where an event is reported
but only processed after the type has already changed,
which would lead to missing events and warnings.
A side effect of this is that you will have disconnected
or left the IBSS even if the mode change ultimately fails,
but since the intention was to change it and thus leave or
disconnect, this is not a problem.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
v2: rebase on current wireless-testing, sorry
net/wireless/core.c | 54 ----------------------
net/wireless/core.h | 4 +
net/wireless/nl80211.c | 16 ------
net/wireless/util.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
net/wireless/wext-compat.c | 16 +-----
5 files changed, 117 insertions(+), 81 deletions(-)
--- wireless-testing.orig/net/wireless/core.c 2009-08-21 14:47:07.000000000 +0200
+++ wireless-testing/net/wireless/core.c 2009-08-21 14:48:46.000000000 +0200
@@ -294,69 +294,17 @@ static void cfg80211_rfkill_sync_work(st
cfg80211_rfkill_set_block(rdev, rfkill_blocked(rdev->rfkill));
}
-static void cfg80211_process_events(struct wireless_dev *wdev)
-{
- struct cfg80211_event *ev;
- unsigned long flags;
-
- spin_lock_irqsave(&wdev->event_lock, flags);
- while (!list_empty(&wdev->event_list)) {
- ev = list_first_entry(&wdev->event_list,
- struct cfg80211_event, list);
- list_del(&ev->list);
- spin_unlock_irqrestore(&wdev->event_lock, flags);
-
- wdev_lock(wdev);
- switch (ev->type) {
- case EVENT_CONNECT_RESULT:
- __cfg80211_connect_result(
- wdev->netdev, is_zero_ether_addr(ev->cr.bssid) ?
- NULL : ev->cr.bssid,
- ev->cr.req_ie, ev->cr.req_ie_len,
- ev->cr.resp_ie, ev->cr.resp_ie_len,
- ev->cr.status,
- ev->cr.status == WLAN_STATUS_SUCCESS,
- NULL);
- break;
- case EVENT_ROAMED:
- __cfg80211_roamed(wdev, ev->rm.bssid,
- ev->rm.req_ie, ev->rm.req_ie_len,
- ev->rm.resp_ie, ev->rm.resp_ie_len);
- break;
- case EVENT_DISCONNECTED:
- __cfg80211_disconnected(wdev->netdev,
- ev->dc.ie, ev->dc.ie_len,
- ev->dc.reason, true);
- break;
- case EVENT_IBSS_JOINED:
- __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
- break;
- }
- wdev_unlock(wdev);
-
- kfree(ev);
-
- spin_lock_irqsave(&wdev->event_lock, flags);
- }
- spin_unlock_irqrestore(&wdev->event_lock, flags);
-}
-
static void cfg80211_event_work(struct work_struct *work)
{
struct cfg80211_registered_device *rdev;
- struct wireless_dev *wdev;
rdev = container_of(work, struct cfg80211_registered_device,
event_work);
rtnl_lock();
cfg80211_lock_rdev(rdev);
- mutex_lock(&rdev->devlist_mtx);
- list_for_each_entry(wdev, &rdev->netdev_list, list)
- cfg80211_process_events(wdev);
-
- mutex_unlock(&rdev->devlist_mtx);
+ cfg80211_process_rdev_events(rdev);
cfg80211_unlock_rdev(rdev);
rtnl_unlock();
}
--- wireless-testing.orig/net/wireless/core.h 2009-08-21 14:47:13.000000000 +0200
+++ wireless-testing/net/wireless/core.h 2009-08-21 14:48:46.000000000 +0200
@@ -372,6 +372,10 @@ void cfg80211_sme_disassoc(struct net_de
void __cfg80211_scan_done(struct work_struct *wk);
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
+int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, enum nl80211_iftype ntype,
+ u32 *flags, struct vif_params *params);
+void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
struct ieee80211_channel *
rdev_fixed_channel(struct cfg80211_registered_device *rdev,
--- wireless-testing.orig/net/wireless/nl80211.c 2009-08-21 14:44:55.000000000 +0200
+++ wireless-testing/net/wireless/nl80211.c 2009-08-21 14:48:46.000000000 +0200
@@ -977,12 +977,6 @@ static int nl80211_set_interface(struct
}
}
- if (!rdev->ops->change_virtual_intf ||
- !(rdev->wiphy.interface_modes & (1 << ntype))) {
- err = -EOPNOTSUPP;
- goto unlock;
- }
-
if (info->attrs[NL80211_ATTR_MESH_ID]) {
if (ntype != NL80211_IFTYPE_MESH_POINT) {
err = -EINVAL;
@@ -1008,18 +1002,10 @@ static int nl80211_set_interface(struct
}
if (change)
- err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev,
- ntype, flags, ¶ms);
+ err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms);
else
err = 0;
- WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
-
- if (!err && (ntype != otype)) {
- if (otype == NL80211_IFTYPE_ADHOC)
- cfg80211_clear_ibss(dev, false);
- }
-
unlock:
dev_put(dev);
cfg80211_unlock_rdev(rdev);
--- wireless-testing.orig/net/wireless/util.c 2009-08-21 14:44:55.000000000 +0200
+++ wireless-testing/net/wireless/util.c 2009-08-21 14:49:37.000000000 +0200
@@ -574,3 +574,111 @@ void cfg80211_upload_connect_keys(struct
kfree(wdev->connect_keys);
wdev->connect_keys = NULL;
}
+
+static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
+{
+ struct cfg80211_event *ev;
+ unsigned long flags;
+ const u8 *bssid = NULL;
+
+ spin_lock_irqsave(&wdev->event_lock, flags);
+ while (!list_empty(&wdev->event_list)) {
+ ev = list_first_entry(&wdev->event_list,
+ struct cfg80211_event, list);
+ list_del(&ev->list);
+ spin_unlock_irqrestore(&wdev->event_lock, flags);
+
+ wdev_lock(wdev);
+ switch (ev->type) {
+ case EVENT_CONNECT_RESULT:
+ if (!is_zero_ether_addr(ev->cr.bssid))
+ bssid = ev->cr.bssid;
+ __cfg80211_connect_result(
+ wdev->netdev, bssid,
+ ev->cr.req_ie, ev->cr.req_ie_len,
+ ev->cr.resp_ie, ev->cr.resp_ie_len,
+ ev->cr.status,
+ ev->cr.status == WLAN_STATUS_SUCCESS,
+ NULL);
+ break;
+ case EVENT_ROAMED:
+ __cfg80211_roamed(wdev, ev->rm.bssid,
+ ev->rm.req_ie, ev->rm.req_ie_len,
+ ev->rm.resp_ie, ev->rm.resp_ie_len);
+ break;
+ case EVENT_DISCONNECTED:
+ __cfg80211_disconnected(wdev->netdev,
+ ev->dc.ie, ev->dc.ie_len,
+ ev->dc.reason, true);
+ break;
+ case EVENT_IBSS_JOINED:
+ __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
+ break;
+ }
+ wdev_unlock(wdev);
+
+ kfree(ev);
+
+ spin_lock_irqsave(&wdev->event_lock, flags);
+ }
+ spin_unlock_irqrestore(&wdev->event_lock, flags);
+}
+
+void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
+{
+ struct wireless_dev *wdev;
+
+ ASSERT_RTNL();
+ ASSERT_RDEV_LOCK(rdev);
+
+ mutex_lock(&rdev->devlist_mtx);
+
+ list_for_each_entry(wdev, &rdev->netdev_list, list)
+ cfg80211_process_wdev_events(wdev);
+
+ mutex_unlock(&rdev->devlist_mtx);
+}
+
+int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, enum nl80211_iftype ntype,
+ u32 *flags, struct vif_params *params)
+{
+ int err;
+ enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
+
+ ASSERT_RDEV_LOCK(rdev);
+
+ /* don't support changing VLANs, you just re-create them */
+ if (otype == NL80211_IFTYPE_AP_VLAN)
+ return -EOPNOTSUPP;
+
+ if (!rdev->ops->change_virtual_intf ||
+ !(rdev->wiphy.interface_modes & (1 << ntype)))
+ return -EOPNOTSUPP;
+
+ if (ntype != otype) {
+ switch (otype) {
+ case NL80211_IFTYPE_ADHOC:
+ cfg80211_leave_ibss(rdev, dev, false);
+ break;
+ case NL80211_IFTYPE_STATION:
+ cfg80211_disconnect(rdev, dev,
+ WLAN_REASON_DEAUTH_LEAVING, true);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ /* mesh should be handled? */
+ break;
+ default:
+ break;
+ }
+
+ cfg80211_process_rdev_events(rdev);
+ }
+
+ err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev,
+ ntype, flags, params);
+
+ WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
+
+ return err;
+}
--- wireless-testing.orig/net/wireless/wext-compat.c 2009-08-21 14:44:55.000000000 +0200
+++ wireless-testing/net/wireless/wext-compat.c 2009-08-21 14:48:46.000000000 +0200
@@ -70,18 +70,8 @@ int cfg80211_wext_siwmode(struct net_dev
enum nl80211_iftype type;
int ret;
- if (!wdev)
- return -EOPNOTSUPP;
-
rdev = wiphy_to_dev(wdev->wiphy);
- if (!rdev->ops->change_virtual_intf)
- return -EOPNOTSUPP;
-
- /* don't support changing VLANs, you just re-create them */
- if (wdev->iftype == NL80211_IFTYPE_AP_VLAN)
- return -EOPNOTSUPP;
-
switch (*mode) {
case IW_MODE_INFRA:
type = NL80211_IFTYPE_STATION;
@@ -104,9 +94,9 @@ int cfg80211_wext_siwmode(struct net_dev
memset(&vifparams, 0, sizeof(vifparams));
- ret = rdev->ops->change_virtual_intf(wdev->wiphy, dev, type,
- NULL, &vifparams);
- WARN_ON(!ret && wdev->iftype != type);
+ cfg80211_lock_rdev(rdev);
+ ret = cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);
+ cfg80211_unlock_rdev(rdev);
return ret;
}
^ permalink raw reply
* Re: USB wireless support for ARM device and old kernel version
From: Miguel Garcia-Lopez @ 2009-08-21 12:46 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1250858377.5137.1.camel@johannes.local>
On 21/08/2009, at 14:39, Johannes Berg wrote:
> There are none. 2.6.10 basically has no wireless drivers. You can
> try to
> backport compat-wireless, but you're on your own. Just upgrade your
> kernel to 2.6.27 or later.
Thanks so much for the concise and quick response. We will try to find
out wether the kernel upgrade is possible for our board.
Regards and thanks again!
--
Miguel García López
Director Técnico
Technical Manager
.......................................................
E N V I T E L
Parque Científico de Madrid - Local 105
PTM - C/Santiago Grisolía, 2
28760 Tres Cantos - Madrid - Spain
T: +34 91 334 06 56
F: +34 91 358 52 36
M: +34 649 91 60 60
.......................................
mgarcia@envitel.com
www.envitel.com
^ permalink raw reply
* [PATCH] mac80211: remove tasklet enable/disable
From: Johannes Berg @ 2009-08-21 12:44 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Due to the way the tasklets work in mac80211 there's
no need to ever disable them.
However, we need to clear the pending packets when
taking down the last interface because otherwise
the tx_pending_tasklet might be queued if the
driver mucks with the queues (which it shouldn't).
I've had a situation occasionally with ar9170 in
which ksoftirq was using 100% CPU time because
a disabled tasklet was scheduled, and I think that
was due to ar9170 receiving a packet while the
tasklet was disabled. That's strange and it really
should not do that for other reasons, but there's
no need to waste that much CPU time over it, it
should just warn instead.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/driver-ops.h | 14 +++++++++++++-
net/mac80211/ieee80211_i.h | 3 +++
net/mac80211/iface.c | 9 +--------
net/mac80211/main.c | 2 --
net/mac80211/rx.c | 9 +++++++++
5 files changed, 26 insertions(+), 11 deletions(-)
--- wireless-testing.orig/net/mac80211/main.c 2009-08-21 14:28:57.000000000 +0200
+++ wireless-testing/net/mac80211/main.c 2009-08-21 14:28:58.000000000 +0200
@@ -715,12 +715,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(
skb_queue_head_init(&local->pending[i]);
tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
(unsigned long)local);
- tasklet_disable(&local->tx_pending_tasklet);
tasklet_init(&local->tasklet,
ieee80211_tasklet_handler,
(unsigned long) local);
- tasklet_disable(&local->tasklet);
skb_queue_head_init(&local->skb_queue);
skb_queue_head_init(&local->skb_queue_unreliable);
--- wireless-testing.orig/net/mac80211/iface.c 2009-08-21 14:28:57.000000000 +0200
+++ wireless-testing/net/mac80211/iface.c 2009-08-21 14:30:33.000000000 +0200
@@ -277,11 +277,6 @@ static int ieee80211_open(struct net_dev
}
}
- if (local->open_count == 0) {
- tasklet_enable(&local->tx_pending_tasklet);
- tasklet_enable(&local->tasklet);
- }
-
/*
* set_multicast_list will be invoked by the networking core
* which will check whether any increments here were done in
@@ -552,11 +547,9 @@ static int ieee80211_stop(struct net_dev
ieee80211_recalc_ps(local, -1);
if (local->open_count == 0) {
+ ieee80211_clear_tx_pending(local);
ieee80211_stop_device(local);
- tasklet_disable(&local->tx_pending_tasklet);
- tasklet_disable(&local->tasklet);
-
/* no reconfiguring after stop! */
hw_reconf_flags = 0;
}
--- wireless-testing.orig/net/mac80211/driver-ops.h 2009-08-21 14:28:57.000000000 +0200
+++ wireless-testing/net/mac80211/driver-ops.h 2009-08-21 14:36:43.000000000 +0200
@@ -12,7 +12,11 @@ static inline int drv_tx(struct ieee8021
static inline int drv_start(struct ieee80211_local *local)
{
- int ret = local->ops->start(&local->hw);
+ int ret;
+
+ local->started = true;
+ smp_mb();
+ ret = local->ops->start(&local->hw);
trace_drv_start(local, ret);
return ret;
}
@@ -21,6 +25,14 @@ static inline void drv_stop(struct ieee8
{
local->ops->stop(&local->hw);
trace_drv_stop(local);
+
+ /* sync away all work on the tasklet before clearing started */
+ tasklet_disable(&local->tasklet);
+ tasklet_enable(&local->tasklet);
+
+ barrier();
+
+ local->started = false;
}
static inline int drv_add_interface(struct ieee80211_local *local,
--- wireless-testing.orig/net/mac80211/ieee80211_i.h 2009-08-21 14:28:57.000000000 +0200
+++ wireless-testing/net/mac80211/ieee80211_i.h 2009-08-21 14:37:11.000000000 +0200
@@ -659,6 +659,9 @@ struct ieee80211_local {
*/
bool quiescing;
+ /* device is started */
+ bool started;
+
int tx_headroom; /* required headroom for hardware/radiotap */
/* Tasklet and skb queue to process calls from IRQ mode. All frames
--- wireless-testing.orig/net/mac80211/rx.c 2009-08-21 14:28:57.000000000 +0200
+++ wireless-testing/net/mac80211/rx.c 2009-08-21 14:35:23.000000000 +0200
@@ -2465,6 +2465,15 @@ void __ieee80211_rx(struct ieee80211_hw
return;
}
+ /*
+ * The same happens when we're not even started,
+ * but that's worth a warning.
+ */
+ if (WARN_ON(!local->started)) {
+ kfree_skb(skb);
+ return;
+ }
+
if (status->flag & RX_FLAG_HT) {
/* rate_idx is MCS index */
if (WARN_ON(status->rate_idx < 0 ||
^ permalink raw reply
* Re: Abour linux driver supports BCM4325
From: Johannes Berg @ 2009-08-21 12:40 UTC (permalink / raw)
To: Larry Finger; +Cc: feng tian, linux-wireless
In-Reply-To: <4A8E8F59.9050706@lwfinger.net>
[-- Attachment #1: Type: text/plain, Size: 798 bytes --]
On Fri, 2009-08-21 at 07:13 -0500, Larry Finger wrote:
> > We are working on a project which supports the BCM4325 linux wireless
> > driver. The interface between the BCM chip and SOC(pxa310) is SDIO.
> > I did some searches online and found that there is no available driver
> > for this chip. Do I have to implement this myself? Is there anyone can
> > provide us some related materials? Thanks very much.
>
> The code for the LP PHY, which I believe is present in the 4325, is
> just being written. At the moment, the chip is able to receive on some
> channels, and may be able to transmit. These results are reported on
> this mailing list, and the code is being applied to the wireless
> testing git tree.
Also, somebody is working on SDIO support with Michael.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: USB wireless support for ARM device and old kernel version
From: Johannes Berg @ 2009-08-21 12:39 UTC (permalink / raw)
To: Miguel Garcia-Lopez; +Cc: linux-wireless
In-Reply-To: <55FEAD01-712B-4165-9F4D-260BDC3CA14A@envitel.com>
[-- Attachment #1: Type: text/plain, Size: 364 bytes --]
On Fri, 2009-08-21 at 14:12 +0200, Miguel Garcia-Lopez wrote:
> Any hints on what to try or driver sources distributions I could try
> to compile against my 2.6.10 kernel?
There are none. 2.6.10 basically has no wireless drivers. You can try to
backport compat-wireless, but you're on your own. Just upgrade your
kernel to 2.6.27 or later.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
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