Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH] ar9170usb: add mode-switching for AVM Fritz!WLAN USB N devices in cdrom mode
From: Oliver Neukum @ 2009-11-03 10:57 UTC (permalink / raw)
  To: Matthew Dharm; +Cc: Dan Williams, Frank Schaefer, linux-wireless, linux-usb
In-Reply-To: <20091102211123.GI24436@one-eyed-alien.net>

Am Montag, 2. November 2009 22:11:23 schrieb Matthew Dharm:
> It's worth noting that for some of these which are handled in-kernel, it
> had to be done that way because their storage-emulation was so poor that
> the normal 'eject' WOULD NOT work properly.
>
> Any device which can be handled in userspace SHOULD be handled there.

Do these devices survive a reset and stay in the correct mode?
Has that been tested?

	Regards
		Oliver


^ permalink raw reply

* Re: [PATCH] ar9170usb: add mode-switching for AVM Fritz!WLAN USB N devices in cdrom mode
From: Oliver Neukum @ 2009-11-03 10:55 UTC (permalink / raw)
  To: Dan Williams; +Cc: Matthew Dharm, Frank Schaefer, linux-wireless, linux-usb
In-Reply-To: <1257198124.1027.63.camel@localhost.localdomain>

Am Montag, 2. November 2009 22:42:04 schrieb Dan Williams:
> The kernel drivers know which devices are supported and how to drive
> them.  But because the eject code isn't in kernelspace, all that device
> selection logic has to be duplicated in userspace with usb_modeswitch.
> Pretty dumb.

No, the kernel doesn't have to know which devices need a mode switch.
Nor does user space need to know which driver a device needs to switch its
mode.

	Regards
		Oliver


^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Johannes Berg @ 2009-11-03  8:57 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Marcel Holtmann, David Miller, torvalds, linville, linux-kernel,
	linux-wireless
In-Reply-To: <20091103084744.GH3212@core.coreip.homeip.net>

[-- Attachment #1: Type: text/plain, Size: 1225 bytes --]

On Tue, 2009-11-03 at 00:47 -0800, Dmitry Torokhov wrote:

> > I just think that it's a matter of courtesy that should be independent
> > from the release cycle to ask the author/maintainer by default, not as a
> > second thought ("unless [...] have other solution"). You can always CC
> > Linus and ask him to revert if you don't get a response.
> > 
> > What's wrong with that? It doesn't actually delay the action, but it
> > makes the discussion much more friendly and cooperative instead of
> > giving the author and maintainer the feeling that their opinion only
> > matters as a second thought.
> > 
> 
> I think you are reading too much into who was addressed directly and who
> was "only" CCed... 

Maybe. But it seems to be happening pretty often recently that people
first ask for a revert and then for a fix, ignoring any thought that
might have gone into a particular commit...

> OK, next time (which I hope won't happen :) ) 

So do I! :)

> I'll just address everyone directly. Will that work?

Much better, at least for me. Hey, I try to respond quickly.

(incidentally, I can't imagine an upstream revert actually helping at
all ... that just creates a merge mess)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Dmitry Torokhov @ 2009-11-03  8:47 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Marcel Holtmann, David Miller, torvalds, linville, linux-kernel,
	linux-wireless
In-Reply-To: <1257237061.28469.43.camel@johannes.local>

On Tue, Nov 03, 2009 at 09:31:01AM +0100, Johannes Berg wrote:
> On Tue, 2009-11-03 at 00:22 -0800, Dmitry Torokhov wrote:
> 
> > I do not understand what the fuss is about. We are pretty far in release
> > process (rc6 is about to be cut I'd expect) and we have an issue that
> > for all practical purposes kills the box on resume. Yes, I want action
> > to be swift in this case and (unless author or maintainer - who were
> > CCed on the email - have otehr solutiuon) the offending commit to be
> > reverted. If it was rc1 or rc2 or 3 I'd feel differently.
> 
> Oh, I don't disagree that swift action is good.
> 
> I just think that it's a matter of courtesy that should be independent
> from the release cycle to ask the author/maintainer by default, not as a
> second thought ("unless [...] have other solution"). You can always CC
> Linus and ask him to revert if you don't get a response.
> 
> What's wrong with that? It doesn't actually delay the action, but it
> makes the discussion much more friendly and cooperative instead of
> giving the author and maintainer the feeling that their opinion only
> matters as a second thought.
> 

I think you are reading too much into who was addressed directly and who
was "only" CCed... OK, next time (which I hope won't happen :) ) I'll
just address everyone directly. Will that work?

-- 
Dmitry

^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Johannes Berg @ 2009-11-03  8:31 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Marcel Holtmann, David Miller, torvalds, linville, linux-kernel,
	linux-wireless
In-Reply-To: <20091103082201.GG3212@core.coreip.homeip.net>

[-- Attachment #1: Type: text/plain, Size: 1070 bytes --]

On Tue, 2009-11-03 at 00:22 -0800, Dmitry Torokhov wrote:

> I do not understand what the fuss is about. We are pretty far in release
> process (rc6 is about to be cut I'd expect) and we have an issue that
> for all practical purposes kills the box on resume. Yes, I want action
> to be swift in this case and (unless author or maintainer - who were
> CCed on the email - have otehr solutiuon) the offending commit to be
> reverted. If it was rc1 or rc2 or 3 I'd feel differently.

Oh, I don't disagree that swift action is good.

I just think that it's a matter of courtesy that should be independent
from the release cycle to ask the author/maintainer by default, not as a
second thought ("unless [...] have other solution"). You can always CC
Linus and ask him to revert if you don't get a response.

What's wrong with that? It doesn't actually delay the action, but it
makes the discussion much more friendly and cooperative instead of
giving the author and maintainer the feeling that their opinion only
matters as a second thought.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Dmitry Torokhov @ 2009-11-03  8:22 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Marcel Holtmann, David Miller, torvalds, linville, linux-kernel,
	linux-wireless
In-Reply-To: <1257234299.28469.25.camel@johannes.local>

On Tue, Nov 03, 2009 at 08:44:59AM +0100, Johannes Berg wrote:
> On Tue, 2009-11-03 at 16:16 +0900, Marcel Holtmann wrote:
> 
> > and can we please stop jumping the gun here and going past the subsystem
> > maintainers. I think this happens a little bit too much lately.
> 
> I'll rant a bit too -- I've been very annoyed by this many times. Note
> this isn't really against you (Dmitry) in particular, just another
> case ... but it does tick me off that many times when somebody manages
> to blame a failure on a specific commit the first thing they do is ask
> somebody way "above" (in terms of patch flow into mainline) the person
> writing the patch (like Linus here) to revert it.
> 

I do not understand what the fuss is about. We are pretty far in release
process (rc6 is about to be cut I'd expect) and we have an issue that
for all practical purposes kills the box on resume. Yes, I want action
to be swift in this case and (unless author or maintainer - who were
CCed on the email - have otehr solutiuon) the offending commit to be
reverted. If it was rc1 or rc2 or 3 I'd feel differently.

> It'd help communication and be so much more friendly if the subject was
> "found problem with commit ..." instead of "please consider
> reverting ..." (which was comparatively friendly already!). You can even
> leave the body almost identical, but I think it's presumptuous to
> effectively say "hey I know the solution for the problem already".

Not at all. I do know the solution since reverting this commit makes by
laptop operable again. It may not be the best solution in the long run
but a solution nonetheless.

> I'll
> venture a guess and say that wasn't even the intent, but it certainly
> comes across like that if you write an email with this subject, and
> start the body with "Hi Linus," not even addressing the patch author,
> just adding them to CC out of courtesy.
> 
> Should I think this is accepted practice?
> 

Again, I do not see the problem here. We have a severe regression so
yes, I am addressing Linus and asking him to consider reverting bad
commit. I also CCing the author and the wireless maintainer so they
can object if they have alternative solution. If the problem was in a
single driver I might consider doing it differenty but I think this
commit affects many wireless drivers.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 1/2] Allow scanning while in authenticated only state
From: Johannes Berg @ 2009-11-03  8:16 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: Jouni Malinen, hostap@lists.shmoo.com, linux-wireless
In-Reply-To: <1257203821.6717.24.camel@maxim-laptop>

[-- Attachment #1: Type: text/plain, Size: 1819 bytes --]

On Tue, 2009-11-03 at 01:17 +0200, Maxim Levitsky wrote:

> > There should be no need for doing both disassoc and deauth; just send
> > deauth only if that is needed. This will save one extra frame
> > transmission and speeds up roaming a bit.
> > 
> > Though, is this enough to handle the roaming cases where wpa_supplicant
> > may not try to send either disassociation or deauthentication?

> Currently wpa_supplicant sends only disassociation.
> deauthentication is send only in rare cases, usually due to [suspected]
> authentication error.
> Other that that I don't know, what I need is a clear statement about how
> things should work that is:
> 
> 
> * Should kernel allow authentication while in authenticated? I guess yes
> To same AP? To different APs?

It does allow it to different APs (up to 3/4 at a time), but not to the
same AP -- I plan on fixing the latter case.

> * What should kernel do if it done authentication to several APs?, but
> not association.
> should it timeout, or let wpa_suplicant do it?
> Currently it allows 4 (or 3) such APs, and then then bugs out with
> -ENOSPC

IMHO it should not make the decision on how long authentications are
valid. Any such value might be wrong if wpa_supplicant is really slow,
say it's swapped out.

> * Should kernel allow scanning while in authenticated but not associated
> case? 
> I have send patch to do so, I hope it will be accepted.

I don't think it should, and as such don't think I want to accept the
patch. You need to make a much much better case for it if you want me to
accept it. I see no reason to ever be in a situation where there are
authentications (that aren't either killed off or used to associate) for
a long enough period of time for it to make sense to scan in that time.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: Incorrect signal levels reported using wpa_supplicant's driver_nl80211
From: Johannes Berg @ 2009-11-03  8:06 UTC (permalink / raw)
  To: Dan Williams
  Cc: Maxim Levitsky, hostap@lists.shmoo.com, linux-wireless,
	networkmanager-list
In-Reply-To: <1257190833.1027.4.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 1891 bytes --]

On Mon, 2009-11-02 at 11:40 -0800, Dan Williams wrote:

> > 	--> dbm: used only if:
> > 		* valid and zero max_qual->level (but now set to -110....) 
> 
> IIRC non-zero max_qual->level was the indication that the driver wanted
> to use RSSI, not dBm.

Are you sure? Weird ... we've had it set at -110 practically forever in
mac80211-based drivers.

> Since the real "max" dBm is around 0 (ie, that's
> the highest signal strength you'll ever really see), max_qual->level
> meant the driver was reporting signal strength in dBm.  max_qual->level
> == -110 is kinda wrong, because that's the _minimum_ level, not the max.
> The noise floor is almost always around -100 dBm so setting
> max_qual->level is pretty useless.
> 
> This is *exactly* why 'qual' is there: so that the driver itself can
> figure out what the hell it's signal level is, and so that NM doesn't
> have to go around assuming stuff.
> 
> For WEXT reporting, mac80211 should really be constructing a 'qual'
> instead of leaving it 0.  Then we don't have ambiguities with dBm, RSSI,
> unspec, etc.

We do that -- I think the problem here is not the max_qual value but
that you're not getting a "qual" value since -Dnl80211 doesn't construct
that.

What effectively happens is that you're trying to discover device
capabilities based on wext, but then use the information provided by
nl80211, which while effectively the same information comes in a
different format. When using nl80211, you really should discover whether
the device uses dBm or RSSI values by the kind of attribute it gave you
in the scan result.

So IMHO the solution is to move all that "what kind of crap am I
getting" detection into driver_wext and only export the sanitised values
from wpa_supplicant.

johannes

PS: Please trim your quoting, it should be easy enough to kill
everything after your signature.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Johannes Berg @ 2009-11-03  7:44 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Dmitry Torokhov, David Miller, torvalds, linville, linux-kernel,
	linux-wireless
In-Reply-To: <1257232587.3420.55.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 1500 bytes --]

On Tue, 2009-11-03 at 16:16 +0900, Marcel Holtmann wrote:

> and can we please stop jumping the gun here and going past the subsystem
> maintainers. I think this happens a little bit too much lately.

I'll rant a bit too -- I've been very annoyed by this many times. Note
this isn't really against you (Dmitry) in particular, just another
case ... but it does tick me off that many times when somebody manages
to blame a failure on a specific commit the first thing they do is ask
somebody way "above" (in terms of patch flow into mainline) the person
writing the patch (like Linus here) to revert it.

It'd help communication and be so much more friendly if the subject was
"found problem with commit ..." instead of "please consider
reverting ..." (which was comparatively friendly already!). You can even
leave the body almost identical, but I think it's presumptuous to
effectively say "hey I know the solution for the problem already". I'll
venture a guess and say that wasn't even the intent, but it certainly
comes across like that if you write an email with this subject, and
start the body with "Hi Linus," not even addressing the patch author,
just adding them to CC out of courtesy.

Should I think this is accepted practice?

</rant>

Before you get the wrong impression, yes, certainly this particular
commit was bad, and it shouldn't have happened. I tested it, but clearly
not every aspect of it. That's clearly my fault, I apologise for that.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Marcel Holtmann @ 2009-11-03  7:16 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: David Miller, torvalds, johannes, linville, linux-kernel,
	linux-wireless
In-Reply-To: <20091103065238.GE3212@core.coreip.homeip.net>

Hi Dmitry,

> > > It looks like
> > > 
> > > commit 7d930bc33653d5592dc386a76a38f39c2e962344
> > > Author: Johannes Berg <johannes@sipsolutions.net>
> > > Date:   Tue Oct 20 15:08:53 2009 +0900
> >  ...
> > > is causing oops on resume:
> > 
> > There is a fix for this in my tree and I'll push it to Linus
> > tonight.
> 
> Ah, even better ;) Thanks David.

and can we please stop jumping the gun here and going past the subsystem
maintainers. I think this happens a little bit too much lately.

Regards

Marcel



^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Dmitry Torokhov @ 2009-11-03  6:52 UTC (permalink / raw)
  To: David Miller; +Cc: torvalds, johannes, linville, linux-kernel, linux-wireless
In-Reply-To: <20091102.224957.32364226.davem@davemloft.net>

On Mon, Nov 02, 2009 at 10:49:57PM -0800, David Miller wrote:
> From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Date: Mon, 2 Nov 2009 21:31:56 -0800
> 
> > Hi Linus,
> > 
> > It looks like
> > 
> > commit 7d930bc33653d5592dc386a76a38f39c2e962344
> > Author: Johannes Berg <johannes@sipsolutions.net>
> > Date:   Tue Oct 20 15:08:53 2009 +0900
>  ...
> > is causing oops on resume:
> 
> There is a fix for this in my tree and I'll push it to Linus
> tonight.

Ah, even better ;) Thanks David.

-- 
Dmitry

^ permalink raw reply

* Re: Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: David Miller @ 2009-11-03  6:49 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: torvalds, johannes, linville, linux-kernel, linux-wireless
In-Reply-To: <20091103053156.GA3212@core.coreip.homeip.net>

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: Mon, 2 Nov 2009 21:31:56 -0800

> Hi Linus,
> 
> It looks like
> 
> commit 7d930bc33653d5592dc386a76a38f39c2e962344
> Author: Johannes Berg <johannes@sipsolutions.net>
> Date:   Tue Oct 20 15:08:53 2009 +0900
 ...
> is causing oops on resume:

There is a fix for this in my tree and I'll push it to Linus
tonight.

^ permalink raw reply

* Re: linux-next: Tree for November 2 (wireless/wl1271)
From: Luciano Coelho @ 2009-11-03  6:03 UTC (permalink / raw)
  To: ext John W. Linville
  Cc: Valo Kalle (Nokia-D/Tampere), Randy Dunlap, Stephen Rothwell,
	linux-next@vger.kernel.org, LKML, linux-wireless@vger.kernel.org
In-Reply-To: <4AEF4ACB.5040302@nokia.com>

Coelho Luciano (Nokia-D/Helsinki) wrote:
> ext John W. Linville wrote:
>> Helps if I actually Cc: Luca...
> 
> Yes, it does. :) I would see this at some point but CCing me speed things up 
> quite a lot.


BTW, I think we need this for wl1251 as well.  CC'ing Kalle too.


>> On Mon, Nov 02, 2009 at 01:44:49PM -0500, John W. Linville wrote:
>>> On Mon, Nov 02, 2009 at 10:01:35AM -0800, Randy Dunlap wrote:
>>>> Stephen Rothwell wrote:
>>>>> Hi all,
>>>>>
>>>>> Changes since 20091030:
>>>> wl1271 build fails when CONFIG_INET=n.
>>>> Should this driver depend on INET?
>>>>
>>>> Why does this driver, unlike all other wireless drivers,
>>>> want to use register_inetaddr_notifier()?
>>>>
>>>> wl1271_main.c:(.text+0x271052): undefined reference to `unregister_inetaddr_notifier'
>>>> wl1271_main.c:(.text+0x2714d7): undefined reference to `register_inetaddr_notifier'
>>> Yeah, that driver is doing some filtering based on IPv4.
>>>
>>> Luca, is that necessary?  If so, then we need a patch like the one below...?
> 
> Yes, this is necessary.  We are doing ARP filtering according to the IP address 
> of the interface, as you have realized.  Our implementation is rather ugly at 
> the moment, so the plan is to try to get rid of this dependency on INET, but we 
> need it for now.
> 
> Thanks Randy for finding this and thanks John for fixing it.
> 
>>> From ba823accfad68151d80503ff5fb04c049c9eadc2 Mon Sep 17 00:00:00 2001
>>> From: John W. Linville <linville@tuxdriver.com>
>>> Date: Mon, 2 Nov 2009 13:43:32 -0500
>>> Subject: [PATCH] wl1271: depend on INET
>>>
>>> wl1271_main.c:(.text+0x271052): undefined reference to `unregister_inetaddr_notifier'
>>> wl1271_main.c:(.text+0x2714d7): undefined reference to `register_inetaddr_notifier'
>>>
>>> Driver is doing some filtering based on IP addresses...
>>>
>>> Signed-off-by: John W. Linville <linville@tuxdriver.com>
>>> ---
>>>  drivers/net/wireless/wl12xx/Kconfig |    1 +
>>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
>>> index 33de7fa..785e024 100644
>>> --- a/drivers/net/wireless/wl12xx/Kconfig
>>> +++ b/drivers/net/wireless/wl12xx/Kconfig
>>> @@ -42,6 +42,7 @@ config WL1251_SDIO
>>>  config WL1271
>>>  	tristate "TI wl1271 support"
>>>  	depends on WL12XX && SPI_MASTER && GENERIC_HARDIRQS
>>> +	depends on INET
>>>  	select FW_LOADER
>>>  	select CRC7
>>>  	---help---
>>> -- 
>>> 1.6.2.5
> 
> Acked-by: Luciano Coelho <luciano.coelho@nokia.com>
> 


-- 
Cheers,
Luca.

^ permalink raw reply

* Please consider reverting 7d930bc33653d5592dc386a76a38f39c2e962344
From: Dmitry Torokhov @ 2009-11-03  5:31 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Johannes Berg, John W. Linville, LKML, linux-wireless

Hi Linus,

It looks like

commit 7d930bc33653d5592dc386a76a38f39c2e962344
Author: Johannes Berg <johannes@sipsolutions.net>
Date:   Tue Oct 20 15:08:53 2009 +0900

    cfg80211: sme: deauthenticate on assoc failure

    When the in-kernel SME gets an association failure from
    the AP we don't deauthenticate, and thus get into a very
    confused state which will lead to warnings later on. Fix
    this by actually deauthenticating when the AP indicates
    an association failure.

    (Brought to you by the hacking session at Kernel Summit 2009 in Tokyo,
    Japan. -- JWL)

    Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
    Signed-off-by: John W. Linville <linville@tuxdriver.com>

is causing oops on resume:

Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588844] BUG: unable to handle kernel NULL pointer dereference at (null)
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588852] IP: [<ffffffffa0b6d4d3>] cfg80211_conn_work+0x87/0x128 [cfg80211]
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588869] PGD 110bb4067 PUD 11a605067 PMD 0
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588875] Oops: 0000 [#1] PREEMPT SMP
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588880] last sysfs file: /sys/power/state
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588884] CPU 0
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588886] Modules linked in: fuse rfcomm sco bnep l2cap crc16 sunrpc autofs4 coretemp hwmon vmnet vmblock vsock vmci vmmon acpi_cpufreq uinput arc4 ecb snd_hda_codec_idt iwl3945 joydev iwlcore snd_hda_intel firewire_ohci snd_hda_codec snd_hwdep snd_pcm ppdev mac80211 tg3 firewire_core parport_pc psmouse snd_timer yenta_socket dell_laptop parport cfg80211 dcdbas nvidia(P) wmi video ac btusb bluetooth crc_itu_t rsrc_nonstatic serio_raw snd libphy battery pcspkr output iTCO_wdt soundcore snd_page_alloc i2c_i801 i2c_core iTCO_vendor_support ohci_hcd [last unloaded: microcode]
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588957] Pid: 9, comm: events/0 Tainted: P           2.6.32-rc5 #78 Latitude D630
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588960] RIP: 0010:[<ffffffffa0b6d4d3>]  [<ffffffffa0b6d4d3>] cfg80211_conn_work+0x87/0x128 [cfg80211]
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588970] RSP: 0000:ffff88011f8afd10  EFLAGS: 00010246
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588973] RAX: 0000000000000000 RBX: ffff8801183d4810 RCX: 0000000000000000
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588975] RDX: 0000000000000000 RSI: 0000000000000003 RDI: ffff8801183d4810
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588978] RBP: ffff88011f8afd80 R08: ffff8801183d4870 R09: 0000000000000000
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588981] R10: 0000000000000000 R11: 0000000000000000 R12: ffff880118de0000
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588983] R13: ffff88011f8afd40 R14: ffff880118de00f8 R15: ffff880118de0018
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588986] FS:  0000000000000000(0000) GS:ffff880028200000(0000) knlGS:0000000000000000
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588989] CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588992] CR2: 0000000000000000 CR3: 000000011afe5000 CR4: 00000000000006f0
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588995] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.588997] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589001] Process events/0 (pid: 9, threadinfo ffff88011f8ae000, task ffff88011f8b8000)
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589003] Stack:
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589005]  0000000000000000 ffffffff8105b93e ffff880100000000 0000000000000046
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006] <0> ffff88011f8afd50 ffff880118de0170 ffff88011f8afdf0 0000000000000246
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006] <0> ffff88011f8afd60 ffff8800282169c0 ffff88011f8b8000 ffff880118de0260
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006] Call Trace:
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105b93e>] ? run_workqueue+0x12f/0x26d
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105b990>] run_workqueue+0x181/0x26d
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105b93e>] ? run_workqueue+0x12f/0x26d
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffffa0b6d44c>] ? cfg80211_conn_work+0x0/0x128 [cfg80211]
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105bb5c>] worker_thread+0xe0/0xf3
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105f951>] ? autoremove_wake_function+0x0/0x34
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105ba7c>] ? worker_thread+0x0/0xf3
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105f5ed>] kthread+0x7a/0x82
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8100cc9a>] child_rip+0xa/0x20
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8100c600>] ? restore_args+0x0/0x30
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8105f573>] ? kthread+0x0/0x82
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  [<ffffffff8100cc90>] ? child_rip+0x0/0x20
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006] Code: eb 7f 48 89 df e8 ba e7 ff ff 48 8b 43 20 f6 40 48 01 74 5d 83 bb fc 00 00 00 01 75 54 48 8b 83 00 01 00 00 48 89 df 48 8b 40 08 <8b> 10 41 89 55 00 66 8b 40 04 66 41 89 45 04 e8 c6 eb ff ff 85
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006] RIP  [<ffffffffa0b6d4d3>] cfg80211_conn_work+0x87/0x128 [cfg80211]
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006]  RSP <ffff88011f8afd10>
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589006] CR2: 0000000000000000
Nov  2 20:24:01 dtor-d630 kernel: [ 4696.589257] ---[ end trace 7169bd444788bb37 ]---

Reverting this particular commit allows me to suspend/resume again.

Thanks!

-- 
Dmitry

^ permalink raw reply

* Re: pull request: wireless-2.6 2009-11-02
From: David Miller @ 2009-11-03  3:19 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20091102214022.GM14046@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Mon, 2 Nov 2009 16:40:22 -0500

> git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master

Pulled, thanks a lot John.

^ permalink raw reply

* [RFT 8/9] ath9k: handle low buffer space for virtual wiphys
From: Luis R. Rodriguez @ 2009-11-03  3:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

ath9k virtual wiphys all share the same internal buffer space
for TX but they do not share the mac80211 skb queues. When
ath9k detects it is running low on buffer space to TX it tells
mac80211 to stop sending it skbs its way but it always does
this only for the primary wiphy. This means mac80211 won't know
its best to avoid sending ath9k more skbs on a separate virtual
wiphy. The same issue is present for reliving the skb queue.

Since ath9k does not keep track of which virtual wiphy is hammering
on TX silence all wiphy's TX when we're low on buffer space. When
we're free on buffer space only bother informing the virtual wiphy
which is active that we have free buffers.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    3 ++
 drivers/net/wireless/ath/ath9k/virtual.c |   52 ++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/xmit.c    |   10 +++---
 3 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 59ce7ec..4169d2b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -695,5 +695,8 @@ void ath9k_wiphy_work(struct work_struct *work);
 bool ath9k_all_wiphys_idle(struct ath_softc *sc);
 void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
+
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 69a871b..0a36b57 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -697,3 +697,55 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
 		  wiphy_name(aphy->hw->wiphy),
 		  idle ? "idle" : "not-idle");
 }
+/* Only bother starting a queue on an active virtual wiphy */
+void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Start the primary wiphy */
+	if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
+		ieee80211_wake_queue(hw, skb_queue);
+		goto unlock;
+	}
+
+	/* Now start the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		if (aphy->state != ATH_WIPHY_ACTIVE)
+			continue;
+
+		hw = aphy->hw;
+		ieee80211_wake_queue(hw, skb_queue);
+		break;
+	}
+
+unlock:
+	spin_unlock_bh(&sc->wiphy_lock);
+}
+
+/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
+void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue)
+{
+	struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+	unsigned int i;
+
+	spin_lock_bh(&sc->wiphy_lock);
+
+	/* Stop the primary wiphy */
+	ieee80211_stop_queue(hw, skb_queue);
+
+	/* Now stop the secondary wiphy queues */
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		hw = aphy->hw;
+		ieee80211_stop_queue(hw, skb_queue);
+	}
+	spin_unlock_bh(&sc->wiphy_lock);
+}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 427bd1d..40d34ed 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -914,9 +914,10 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
 struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ath_txq *txq = NULL;
+	u16 skb_queue = skb_get_queue_mapping(skb);
 	int qnum;
 
-	qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+	qnum = ath_get_hal_qnum(skb_queue, sc);
 	txq = &sc->tx.txq[qnum];
 
 	spin_lock_bh(&txq->axq_lock);
@@ -925,7 +926,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
 		ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT,
 			  "TX queue: %d is full, depth: %d\n",
 			  qnum, txq->axq_depth);
-		ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
+		ath_mac80211_stop_queue(sc, skb_queue);
 		txq->stopped = 1;
 		spin_unlock_bh(&txq->axq_lock);
 		return NULL;
@@ -1704,8 +1705,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 * on the queue */
 		spin_lock_bh(&txq->axq_lock);
 		if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
-			ieee80211_stop_queue(sc->hw,
-				skb_get_queue_mapping(skb));
+			ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
 			txq->stopped = 1;
 		}
 		spin_unlock_bh(&txq->axq_lock);
@@ -1945,7 +1945,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
 	    sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
 		qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
 		if (qnum != -1) {
-			ieee80211_wake_queue(sc->hw, qnum);
+			ath_mac80211_start_queue(sc, qnum);
 			txq->stopped = 0;
 		}
 	}
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 4/9] ath9k: use the passed ieee80211_hw on ath_rx_prepare()
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

this now uses the proper hw which should mean finding the
right sta when using ath9k virtual wiphy stuff.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 330cd3b..10decfa 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -200,7 +200,7 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	}
 
 	rcu_read_lock();
-	sta = ieee80211_find_sta(sc->hw, hdr->addr2);
+	sta = ieee80211_find_sta(hw, hdr->addr2);
 	if (sta) {
 		an = (struct ath_node *) sta->drv_priv;
 		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 7/9] ath9k: use the right hw on ath_tx_setup_buffer() for HT
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

When using virtual wiphys the base sc->hw was being used, the correct
hw is passed along the caller already so just use that.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5d0851b..427bd1d 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1575,7 +1575,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
 
 	bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
 
-	if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+	if (conf_is_ht(&hw->conf) && !is_pae(skb))
 		bf->bf_state.bf_type |= BUF_HT;
 
 	bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 9/9] ath9k: do not pass the entire descriptor to ath_rx_prepare()
From: Luis R. Rodriguez @ 2009-11-03  3:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

Its not needed, so just pass the hardware RX status.
We'll be simplfying ath_rx_prepare() with code we can share
between ath9k and ath9k_htc. This will help make that code
easier to read and manage.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |   70 +++++++++++++++++----------------
 1 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 10decfa..b36ecb2 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -106,7 +106,7 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
  * decryption key or real decryption error. This let us keep statistics there.
  */
 static int ath_rx_prepare(struct ieee80211_hw *hw,
-			  struct sk_buff *skb, struct ath_desc *ds,
+			  struct sk_buff *skb, struct ath_rx_status *rxstats,
 			  struct ieee80211_rx_status *rx_status, bool *decrypt_error,
 			  struct ath_softc *sc)
 {
@@ -121,7 +121,7 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	fc = hdr->frame_control;
 	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
 
-	if (ds->ds_rxstat.rs_more) {
+	if (rxstats->rs_more) {
 		/*
 		 * Frame spans multiple descriptors; this cannot happen yet
 		 * as we don't support jumbograms. If not in monitor mode,
@@ -130,22 +130,22 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 		 */
 		if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
 			goto rx_next;
-	} else if (ds->ds_rxstat.rs_status != 0) {
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
+	} else if (rxstats->rs_status != 0) {
+		if (rxstats->rs_status & ATH9K_RXERR_CRC)
 			rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
+		if (rxstats->rs_status & ATH9K_RXERR_PHY)
 			goto rx_next;
 
-		if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
+		if (rxstats->rs_status & ATH9K_RXERR_DECRYPT) {
 			*decrypt_error = true;
-		} else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
+		} else if (rxstats->rs_status & ATH9K_RXERR_MIC) {
 			if (ieee80211_is_ctl(fc))
 				/*
 				 * Sometimes, we get invalid
 				 * MIC failures on valid control frames.
 				 * Remove these mic errors.
 				 */
-				ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
+				rxstats->rs_status &= ~ATH9K_RXERR_MIC;
 			else
 				rx_status->flag |= RX_FLAG_MMIC_ERROR;
 		}
@@ -155,26 +155,26 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 		 * we also ignore the CRC error.
 		 */
 		if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
-			if (ds->ds_rxstat.rs_status &
+			if (rxstats->rs_status &
 			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
 			      ATH9K_RXERR_CRC))
 				goto rx_next;
 		} else {
-			if (ds->ds_rxstat.rs_status &
+			if (rxstats->rs_status &
 			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
 				goto rx_next;
 			}
 		}
 	}
 
-	ratecode = ds->ds_rxstat.rs_rate;
+	ratecode = rxstats->rs_rate;
 
 	if (ratecode & 0x80) {
 		/* HT rate */
 		rx_status->flag |= RX_FLAG_HT;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
+		if (rxstats->rs_flags & ATH9K_RX_2040)
 			rx_status->flag |= RX_FLAG_40MHZ;
-		if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
+		if (rxstats->rs_flags & ATH9K_RX_GI)
 			rx_status->flag |= RX_FLAG_SHORT_GI;
 		rx_status->rate_idx = ratecode & 0x7f;
 	} else {
@@ -203,31 +203,31 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	sta = ieee80211_find_sta(hw, hdr->addr2);
 	if (sta) {
 		an = (struct ath_node *) sta->drv_priv;
-		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
-		   !ds->ds_rxstat.rs_moreaggr)
-			ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
+		if (rxstats->rs_rssi != ATH9K_RSSI_BAD &&
+		   !rxstats->rs_moreaggr)
+			ATH_RSSI_LPF(an->last_rssi, rxstats->rs_rssi);
 		last_rssi = an->last_rssi;
 	}
 	rcu_read_unlock();
 
 	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-		ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
-					ATH_RSSI_EP_MULTIPLIER);
-	if (ds->ds_rxstat.rs_rssi < 0)
-		ds->ds_rxstat.rs_rssi = 0;
-	else if (ds->ds_rxstat.rs_rssi > 127)
-		ds->ds_rxstat.rs_rssi = 127;
+		rxstats->rs_rssi = ATH_EP_RND(last_rssi,
+					      ATH_RSSI_EP_MULTIPLIER);
+	if (rxstats->rs_rssi < 0)
+		rxstats->rs_rssi = 0;
+	else if (rxstats->rs_rssi > 127)
+		rxstats->rs_rssi = 127;
 
 	/* Update Beacon RSSI, this is used by ANI. */
 	if (ieee80211_is_beacon(fc))
-		sc->sc_ah->stats.avgbrssi = ds->ds_rxstat.rs_rssi;
+		sc->sc_ah->stats.avgbrssi = rxstats->rs_rssi;
 
-	rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
+	rx_status->mactime = ath_extend_tsf(sc, rxstats->rs_tstamp);
 	rx_status->band = hw->conf.channel->band;
 	rx_status->freq = hw->conf.channel->center_freq;
 	rx_status->noise = sc->ani.noise_floor;
-	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
-	rx_status->antenna = ds->ds_rxstat.rs_antenna;
+	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rxstats->rs_rssi;
+	rx_status->antenna = rxstats->rs_antenna;
 
 	/*
 	 * Theory for reporting quality:
@@ -251,9 +251,9 @@ static int ath_rx_prepare(struct ieee80211_hw *hw,
 	 *
 	 */
 	if (conf_is_ht(&hw->conf))
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+		rx_status->qual =  rxstats->rs_rssi * 100 / 45;
 	else
-		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 35;
+		rx_status->qual =  rxstats->rs_rssi * 100 / 35;
 
 	/* rssi can be more than 45 though, anything above that
 	 * should be considered at 100% */
@@ -658,6 +658,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 
 	struct ath_buf *bf;
 	struct ath_desc *ds;
+	struct ath_rx_status *rxstats;
 	struct sk_buff *skb = NULL, *requeue_skb;
 	struct ieee80211_rx_status rx_status;
 	struct ath_hw *ah = sc->sc_ah;
@@ -749,6 +750,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 
 		hdr = (struct ieee80211_hdr *) skb->data;
 		hw = ath_get_virt_hw(sc, hdr);
+		rxstats = &ds->ds_rxstat;
 
 		/*
 		 * If we're asked to flush receive queue, directly
@@ -757,14 +759,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		if (flush)
 			goto requeue;
 
-		if (!ds->ds_rxstat.rs_datalen)
+		if (!rxstats->rs_datalen)
 			goto requeue;
 
 		/* The status portion of the descriptor could get corrupted. */
-		if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
+		if (sc->rx.bufsize < rxstats->rs_datalen)
 			goto requeue;
 
-		if (!ath_rx_prepare(hw, skb, ds,
+		if (!ath_rx_prepare(hw, skb, rxstats,
 				    &rx_status, &decrypt_error, sc))
 			goto requeue;
 
@@ -784,7 +786,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 				 sc->rx.bufsize,
 				 DMA_FROM_DEVICE);
 
-		skb_put(skb, ds->ds_rxstat.rs_datalen);
+		skb_put(skb, rxstats->rs_datalen);
 
 		/* see if any padding is done by the hw and remove it */
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -804,7 +806,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 			skb_pull(skb, padsize);
 		}
 
-		keyix = ds->ds_rxstat.rs_keyix;
+		keyix = rxstats->rs_keyix;
 
 		if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
 			rx_status.flag |= RX_FLAG_DECRYPTED;
@@ -844,7 +846,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		 */
 		if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
 			if (++sc->rx.rxotherant >= 3)
-				ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
+				ath_setdefantenna(sc, rxstats->rs_antenna);
 		} else {
 			sc->rx.rxotherant = 0;
 		}
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 2/9] ath9k: update hw configuration for virtual wiphys
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

ath9k supports its own virtual wiphys. The hardware code
relies on the ieee80211_hw for the present interface but
with recent changes introduced the common->hw was never
updated and is required for virtual wiphys.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/virtual.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index e6a50f3..7678c4a 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -298,6 +298,7 @@ static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
 void ath9k_wiphy_chan_work(struct work_struct *work)
 {
 	struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_wiphy *aphy = sc->next_wiphy;
 
 	if (aphy == NULL)
@@ -313,6 +314,10 @@ void ath9k_wiphy_chan_work(struct work_struct *work)
 	/* XXX: remove me eventually */
 	ath9k_update_ichannel(sc, aphy->hw,
 			      &sc->sc_ah->channels[sc->chan_idx]);
+
+	/* sync hw configuration for hw code */
+	common->hw = aphy->hw;
+
 	ath_update_chainmask(sc, sc->chan_is_ht);
 	if (ath_set_channel(sc, aphy->hw,
 			    &sc->sc_ah->channels[sc->chan_idx]) < 0) {
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 6/9] ath9k: use correct hw for tx aggregation TX completion
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

When ath9k virtual wiphys are used the sc->hw will not always represent
the active hw, instead we need to get it from the skb->cb private
driver area. This ensures the right hw is used to find a sta for
the TX'd skb.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/xmit.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 2a4efcb..5d0851b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -267,7 +267,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	struct ath_node *an = NULL;
 	struct sk_buff *skb;
 	struct ieee80211_sta *sta;
+	struct ieee80211_hw *hw;
 	struct ieee80211_hdr *hdr;
+	struct ieee80211_tx_info *tx_info;
+	struct ath_tx_info_priv *tx_info_priv;
 	struct ath_atx_tid *tid = NULL;
 	struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
 	struct ath_desc *ds = bf_last->bf_desc;
@@ -280,9 +283,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
 
+	tx_info = IEEE80211_SKB_CB(skb);
+	tx_info_priv = (struct ath_tx_info_priv *) tx_info->rate_driver_data[0];
+	hw = tx_info_priv->aphy->hw;
+
 	rcu_read_lock();
 
-	sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+	sta = ieee80211_find_sta(hw, hdr->addr1);
 	if (!sta) {
 		rcu_read_unlock();
 		return;
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 3/9] ath9k: simpify RX by calling ath_get_virt_hw() once
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

ath_get_virt_hw() is required on RX to determine for which virtual
wiphy an skb came in for. Instead of searching for the hw twice do
it only once.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/recv.c |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c880a55..330cd3b 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -105,23 +105,21 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
  * up the frame up to let mac80211 handle the actual error case, be it no
  * decryption key or real decryption error. This let us keep statistics there.
  */
-static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
+static int ath_rx_prepare(struct ieee80211_hw *hw,
+			  struct sk_buff *skb, struct ath_desc *ds,
 			  struct ieee80211_rx_status *rx_status, bool *decrypt_error,
 			  struct ath_softc *sc)
 {
 	struct ieee80211_hdr *hdr;
 	u8 ratecode;
 	__le16 fc;
-	struct ieee80211_hw *hw;
 	struct ieee80211_sta *sta;
 	struct ath_node *an;
 	int last_rssi = ATH_RSSI_DUMMY_MARKER;
 
-
 	hdr = (struct ieee80211_hdr *)skb->data;
 	fc = hdr->frame_control;
 	memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-	hw = ath_get_virt_hw(sc, hdr);
 
 	if (ds->ds_rxstat.rs_more) {
 		/*
@@ -615,7 +613,8 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
 	}
 }
 
-static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
+static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
+				    struct ath_softc *sc, struct sk_buff *skb,
 				    struct ieee80211_rx_status *rx_status)
 {
 	struct ieee80211_hdr *hdr;
@@ -647,7 +646,7 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
 	} else {
 		/* Deliver unicast frames based on receiver address */
 		memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
-		ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
+		ieee80211_rx(hw, skb);
 	}
 }
 
@@ -663,6 +662,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 	struct ieee80211_rx_status rx_status;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
+	/*
+	 * The hw can techncically differ from common->hw when using ath9k
+	 * virtual wiphy so to account for that we iterate over the active
+	 * wiphys and find the appropriate wiphy and therefore hw.
+	 */
+	struct ieee80211_hw *hw = NULL;
 	struct ieee80211_hdr *hdr;
 	int hdrlen, padsize, retval;
 	bool decrypt_error = false;
@@ -742,6 +747,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 				sc->rx.bufsize,
 				DMA_FROM_DEVICE);
 
+		hdr = (struct ieee80211_hdr *) skb->data;
+		hw = ath_get_virt_hw(sc, hdr);
+
 		/*
 		 * If we're asked to flush receive queue, directly
 		 * chain it back at the queue without processing it.
@@ -756,7 +764,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
 			goto requeue;
 
-		if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
+		if (!ath_rx_prepare(hw, skb, ds,
+				    &rx_status, &decrypt_error, sc))
 			goto requeue;
 
 		/* Ensure we always have an skb to requeue once we are done
@@ -778,7 +787,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 		skb_put(skb, ds->ds_rxstat.rs_datalen);
 
 		/* see if any padding is done by the hw and remove it */
-		hdr = (struct ieee80211_hdr *)skb->data;
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 		fc = hdr->frame_control;
 
@@ -825,7 +833,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 			bf->bf_mpdu = NULL;
 			ath_print(common, ATH_DBG_FATAL,
 				  "dma_mapping_error() on RX\n");
-			ath_rx_send_to_mac80211(sc, skb, &rx_status);
+			ath_rx_send_to_mac80211(hw, sc, skb, &rx_status);
 			break;
 		}
 		bf->bf_dmacontext = bf->bf_buf_addr;
@@ -846,7 +854,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 					     SC_OP_WAIT_FOR_PSPOLL_DATA)))
 			ath_rx_ps(sc, skb);
 
-		ath_rx_send_to_mac80211(sc, skb, &rx_status);
+		ath_rx_send_to_mac80211(hw, sc, skb, &rx_status);
 
 requeue:
 		list_move_tail(&bf->list, &sc->rx.rxbuf);
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 5/9] ath9k: pass the ieee80211_hw on radio enable/disable
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

We use the ieee80211_hw for radio enable/disable but the wrong
structure hw was being used in consideration for virtual wiphys
as each virtual wiphy has its own ieee80211_hw struct.

Just pass the hw struct to ensure we use the right one. This should
fix the hw used and passed for radio enable/disable. This includes
the stoping / starting of the software TX queues so mac80211 doesn't
send us data for a specific virtual wiphy. ath9k already takes care
of pausing virtual wiphys and stopping the respective queues on its
own, but this should handle the idle mac80211 conf calls as well.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    5 +++--
 drivers/net/wireless/ath/ath9k/main.c    |   18 +++++++++---------
 drivers/net/wireless/ath/ath9k/virtual.c |    5 +++--
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index da53578..59ce7ec 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -655,8 +655,9 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
 void ath_update_chainmask(struct ath_softc *sc, int is_ht);
 int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
 		    struct ath9k_channel *hchan);
-void ath_radio_enable(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc);
+
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
 
 #ifdef CONFIG_PCI
 int ath_pci_init(void);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index bdce0ab..11aaa7d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1200,11 +1200,11 @@ fail:
 	ath_deinit_leds(sc);
 }
 
-void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
@@ -1241,18 +1241,18 @@ void ath_radio_enable(struct ath_softc *sc)
 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
 
-	ieee80211_wake_queues(sc->hw);
+	ieee80211_wake_queues(hw);
 	ath9k_ps_restore(sc);
 }
 
-void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ieee80211_channel *channel = sc->hw->conf.channel;
+	struct ieee80211_channel *channel = hw->conf.channel;
 	int r;
 
 	ath9k_ps_wakeup(sc);
-	ieee80211_stop_queues(sc->hw);
+	ieee80211_stop_queues(hw);
 
 	/* Disable LED */
 	ath9k_hw_set_gpio(ah, ah->led_pin, 1);
@@ -1266,7 +1266,7 @@ void ath_radio_disable(struct ath_softc *sc)
 	ath_flushrecv(sc);		/* flush recv queue */
 
 	if (!ah->curchan)
-		ah->curchan = ath_get_curchannel(sc, sc->hw);
+		ah->curchan = ath_get_curchannel(sc, hw);
 
 	spin_lock_bh(&sc->sc_resetlock);
 	r = ath9k_hw_reset(ah, ah->curchan, false);
@@ -2719,7 +2719,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 		spin_unlock_bh(&sc->wiphy_lock);
 
 		if (enable_radio) {
-			ath_radio_enable(sc);
+			ath_radio_enable(sc, hw);
 			ath_print(common, ATH_DBG_CONFIG,
 				  "not-idle: enabling radio\n");
 		}
@@ -2800,7 +2800,7 @@ skip_chan_change:
 
 	if (disable_radio) {
 		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
-		ath_radio_disable(sc);
+		ath_radio_disable(sc, hw);
 	}
 
 	mutex_unlock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 7678c4a..69a871b 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -526,8 +526,9 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
 			 * frame being completed)
 			 */
 			spin_unlock_bh(&sc->wiphy_lock);
-			ath_radio_disable(sc);
-			ath_radio_enable(sc);
+			ath_radio_disable(sc, aphy->hw);
+			ath_radio_enable(sc, aphy->hw);
+			/* Only the primary wiphy hw is used for queuing work */
 			ieee80211_queue_work(aphy->sc->hw,
 				   &aphy->sc->chan_work);
 			return -EBUSY; /* previous select still in progress */
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 1/9] ath9k: fix listening to idle requests
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Jouni.Malinen
In-Reply-To: <1257217681-27180-1-git-send-email-lrodriguez@atheros.com>

The way idle configuration detection was implemented as
busted due to the fact that it assumed the ath9k virtual wiphy,
the aphy, would be marked as inactive if it was not used but
it turns out an aphy is always active if its the only wiphy
present. We need to distinguish between aphy activity and
idleness so we now add an idle bool for the aphy and mark
it as such based on the passed IEEE80211_CONF_CHANGE_IDLE
from mac80211.

Previous to all_wiphys_idle would never be true when using
only one device so we never really were using
IEEE80211_CONF_CHANGE_IDLE -- we never turned the radio
off or on upon IEEE80211_CONF_CHANGE_IDLE changes as radio
changes depended on all_wiphys_idle being true either to
turn the radio on or off. Since it was always false for
one device this code was doing nothing.

Cc: Jouni.Malinen <Jouni.Malinen@atheros.com>
Reported-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h   |    2 +
 drivers/net/wireless/ath/ath9k/main.c    |   33 +++++++++++++++++++++++------
 drivers/net/wireless/ath/ath9k/virtual.c |   17 ++++++++++++--
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 13dd020..da53578 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -620,6 +620,7 @@ struct ath_wiphy {
 		ATH_WIPHY_PAUSED,
 		ATH_WIPHY_SCAN,
 	} state;
+	bool idle;
 	int chan_idx;
 	int chan_is_ht;
 };
@@ -691,6 +692,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
 bool ath9k_wiphy_scanning(struct ath_softc *sc);
 void ath9k_wiphy_work(struct work_struct *work);
 bool ath9k_all_wiphys_idle(struct ath_softc *sc);
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
 
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 9fefc51..bdce0ab 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2688,22 +2688,37 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ath_hw *ah = sc->sc_ah;
-	bool all_wiphys_idle = false, disable_radio = false;
+	bool disable_radio;
 
 	mutex_lock(&sc->mutex);
 
-	/* Leave this as the first check */
+	/*
+	 * Leave this as the first check because we need to turn on the
+	 * radio if it was disabled before prior to processing the rest
+	 * of the changes. Likewise we must only disable the radio towards
+	 * the end.
+	 */
 	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		bool enable_radio;
+		bool all_wiphys_idle;
+		bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
 
 		spin_lock_bh(&sc->wiphy_lock);
 		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
+		ath9k_set_wiphy_idle(aphy, idle);
+
+		if (!idle && all_wiphys_idle)
+			enable_radio = true;
+
+		/*
+		 * After we unlock here its possible another wiphy
+		 * can be re-renabled so to account for that we will
+		 * only disable the radio toward the end of this routine
+		 * if by then all wiphys are still idle.
+		 */
 		spin_unlock_bh(&sc->wiphy_lock);
 
-		if (conf->flags & IEEE80211_CONF_IDLE){
-			if (all_wiphys_idle)
-				disable_radio = true;
-		}
-		else if (all_wiphys_idle) {
+		if (enable_radio) {
 			ath_radio_enable(sc);
 			ath_print(common, ATH_DBG_CONFIG,
 				  "not-idle: enabling radio\n");
@@ -2779,6 +2794,10 @@ skip_chan_change:
 	if (changed & IEEE80211_CONF_CHANGE_POWER)
 		sc->config.txpowlimit = 2 * conf->power_level;
 
+	spin_lock_bh(&sc->wiphy_lock);
+	disable_radio = ath9k_all_wiphys_idle(sc);
+	spin_unlock_bh(&sc->wiphy_lock);
+
 	if (disable_radio) {
 		ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n");
 		ath_radio_disable(sc);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index bc7d173..e6a50f3 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -668,15 +668,26 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
 bool ath9k_all_wiphys_idle(struct ath_softc *sc)
 {
 	unsigned int i;
-	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+	if (!sc->pri_wiphy->idle)
 		return false;
-	}
 	for (i = 0; i < sc->num_sec_wiphy; i++) {
 		struct ath_wiphy *aphy = sc->sec_wiphy[i];
 		if (!aphy)
 			continue;
-		if (aphy->state != ATH_WIPHY_INACTIVE)
+		if (!aphy->idle)
 			return false;
 	}
 	return true;
 }
+
+/* caller must hold wiphy_lock */
+void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
+{
+	struct ath_softc *sc = aphy->sc;
+
+	aphy->idle = idle;
+	ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+		  "Marking %s as %s\n",
+		  wiphy_name(aphy->hw->wiphy),
+		  idle ? "idle" : "not-idle");
+}
-- 
1.6.5.2.143.g8cc62


^ permalink raw reply related

* [RFT 0/9] ath9k: few updates for virtual wiphy
From: Luis R. Rodriguez @ 2009-11-03  3:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

Here are a few fixes for the ath9k virtual wiphy. I thought I was
going to have time to test them all today but that didn't happen
so instead of letting them rot in my queue for a few days I'm
posting them for review.

I was not able to find an easy way to deal with the ah->opmode,
that should be updated based on the currently used ieee80211_vif
but mac80211 doesn't exactly tell us which vif we're using at any
given time -- instead each driver is supposed to support different
modes of operation on different vifs on one wiphy. With ath9k
virtual wiphy we've taken a different approach: two vifs can
have different operating modes but on at least they get to use
their own separate channel.

While we can reap benefits of using a separate channel with the
current implementation there are a few cases where mac80211 makes
it difficult to guess your current hw configuration, mainly because
it wasn't designed for two vifs on separate wiphys on the same hardware.

We'd still need to figure out a way to deal with the ah->opmode but
that varies depending on the used vif, and the rx filter also changes
depending on the vif we're on but we have no way of triggering an
appropriate filter update unless mac80211 does it by chance for us.

Luis R. Rodriguez (9):
  ath9k: fix listening to idle requests
  ath9k: update hw configuration for virtual wiphys
  ath9k: simpify RX by calling ath_get_virt_hw() once
  ath9k: use the passed ieee80211_hw on ath_rx_prepare()
  ath9k: pass the ieee80211_hw on radio enable/disable
  ath9k: use correct hw for tx aggregation TX completion
  ath9k: use the right hw on ath_tx_setup_buffer() for HT
  ath9k: handle low buffer space for virtual wiphys
  ath9k: do not pass the entire descriptor to ath_rx_prepare()

 drivers/net/wireless/ath/ath9k/ath9k.h   |   10 +++-
 drivers/net/wireless/ath/ath9k/main.c    |   51 +++++++++++-----
 drivers/net/wireless/ath/ath9k/recv.c    |   96 ++++++++++++++++-------------
 drivers/net/wireless/ath/ath9k/virtual.c |   79 +++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/xmit.c    |   21 ++++--
 5 files changed, 184 insertions(+), 73 deletions(-)


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox