Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: D-link USB Wlan Adapter DWA 160A  crashes after a while
From: Christian Lamparter @ 2009-10-23 16:19 UTC (permalink / raw)
  To: Adhari; +Cc: linux-wireless
In-Reply-To: <005001ca53e9$307bde30$91739a90$@de>

On Friday 23 October 2009 16:00:32 Adhari wrote:
> Hello Everybody
> 
> I´m usind a D-link USB Wlan Adapter DWA 160A (ar9170usb) under Debian (kernel 2.6.31)
> 
> First when I connect this device, everything is fine. I have to do some measurements concerning Mipv6 (I´m only using Ipv6 here)
> after a while using this W-lan Adapter (30 to 60mn) the system is not be able to receive any packets.
> 
> 
> The only solution is to plug the USB interface out and to connect it again.
> ifconfig down and up has no effect and sometimes rebooting either don´t correct this.
> 
> Any idea what the problem could be?
> [ 1270.206139] usb 5-2: kill pending tx urbs.

Is this some sort of trick question? Because you gave
the correct answer already in the "Subject" line?!

my suggestion:

1. get & compile compat-wireless (this will give you
	an updated ar9170usb.ko driver. http://linuxwireless.org/en/users/Download )

2. replace the old two-stage firmware files with one-stage ar9170.fw
   (link: http://wireless.kernel.org/en/users/Drivers/ar9170 )

Regards,
	Chr

^ permalink raw reply

* Re: [RFC] libertas: monster-patch to make CFG/WEXT configurable
From: Dan Williams @ 2009-10-23 16:27 UTC (permalink / raw)
  To: Holger Schurig; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <200910231738.18965.hs4233@mail.mn-solutions.de>

On Fri, 2009-10-23 at 17:38 +0200, Holger Schurig wrote:
> Johannes, 
> 
> Little forword: it might be the case that you still have my 
> RTF/WIP cfg80211 patch in your head that removes all of 
> WEXT/MESH for good. I abandoned that concept.

(I've read below, but replying here)

The OLPC mesh interface does not care about BSSID.  All mesh frames can
be seen by all other mesh-enabled nodes on the same channel, as long as
the encryption settings for nodes are the same.  Because the STA and the
mesh share the same PHY of course they have to be on the same channel,
so if you change the channel of the STA interface, the mesh channel also
changes.  The mesh SSID is more informational than anything else.

Most mesh operations boil down to MESH_CONFIG which you give a channel
and SSID.  Whenever the channel changes (on the STA interface) and the
mesh interface is active, you send MESH_CONFIG + START with the new
channel number.  That's it.

So I think it's actually pretty simple.  The STA interface can be
completely cfg80211, and you can rip out *all* of the internal BSS list
handling, rip out the association worker, etc.  The mesh interface
doesn't need any of that.  The mesh interface could have a simple WEXT
handler that redirects most stuff to the cfg80211 handler, and then for
the 4 operations that are mesh-specific (get/set mesh SSID, set freq,
get mode) you can have custom mesh implementations that do the right
thing.

For the monitor interface, I have no idea :)  But mesh should be pretty
simple.

Dan

> 
> > On Tue, 2009-10-20 at 08:35 +0200, Holger Schurig wrote:
> > > > I really don't understand the point. Can't you just use the
> > > > cfg80211 hooks and keep both functional at the same time?
> > > > Just like orinoco does it uses cfg80211 only partially.
> > > 
> > > I think I can't do this in a sane way.
> > 
> > I don't see why not.
> 
> So, from your point of view it's ok if two different code pieces 
> to the same and copete for each other?
> 
> You think it's ok that two different code paths 
> report "connection" lost, once via an 
> wireless_send_event(priv->dev, SIOCGIWAP ...) and once via 
> cfg80211_disconnected()
> 
> You think it's ok to keep a list of scanned APs both in 
> cfg80211's bss list and in libertas own bss list?
> 
> You think it's okay to have an association worker (which heavily 
> relies on libertas' internal bss list) in libertas and at the 
> same time a cfg80211_ops' .connect() function that might do the 
> same, but quite differently?
> 
> Maybe you'll need more japanese tee :-)
> 
> 
> 
> > > Oh, and please don't compare libertas all the time with
> > > orinoco. Orinoco is FULLMAC, libertas is HALFMAC.
> > > 
> > > Because libertas firmware doesn't roam, it has to be done in 
> > > software. Libertas does this in assoc.c, partly in scan.c,
> > > cmd.c and wext.c and even main.c. For example, libertas keeps
> > > its own list of BSS entries, has code to select the best
> > > matching BSS when it comes to associating ... things like
> > > this. 
> > 
> > None of this code is relevant to mesh.
> 
> Right, but where did I say that this.
> 
> 
> > > cfg80211 has this code too.
> > 
> > No, it has no roaming etc.
> 
> Did I write that?  Whatever you understood: with the libertas' 
> firmware, there's *NO* firmware command where you just 
> say "associate to SSID xzy" and then wait till the firmware 
> scanned and associated. You've to do this by yourself.
> 
> But of course cfg80211 a code-path where you say "iw XXX connect 
> ssid BLAH" and it calls the right things behind the scenes. And 
> libertas has a similar codepath --- just not in the firmware.
> 
> 
> 
> > > Having two competing implementations running in one driver is
> > > a way to havoc.
> > 
> > I'm not saying you should keep the old _station_ code, I'm just 
> > saying you should hook it up in a way that doesn't make it
> > exclusive with mesh. 
> 
> I'm not sure that I understand what you mean. I'm not 
> making "station code" (whatever that is) "exclusive with mesh" 
> (whatever that means).
> 
> Both libertas+WEXT and libertas+CFG80211 have code that allows 
> the libertas card to be a station. The code however is *VERY* 
> different, and I'm going so far to say this is a necessity. I 
> cannot use "one station code" and hook this to both WEXT and 
> CFG80211. Or maybe I can, but it would then be far from elegant.
> 
> And if you insist on doing that, then you'll have to do it by 
> yourself: in that minute I'll stop working on Libertas + 
> cfg80211.
> 
> 
> 
> > I'm not saying you should do mesh. I'm saying that instead of
> > ripping out _all_ wext code you should just redirect/rewrite
> > the wext handlers and call the cfg80211 ones, so that for
> > _managed_ mode you get the new stuff, but for _mesh_ mode you
> > keep the old code. 
> 
> If I redirect WEXT handler --- why should I do this in the 
> driver, there is net/wireless/wext-compat.c, or?
> 
> And if would do it: then I couldn't rip out WEXT, because stuff 
> goes via some WEXT handlers. But ripping out WEXT completely out 
> of libertas is my long-term goal.
> 
> 
> I don't want such a frankenstein in the code for eternity. I want 
> to use cfg80211 for everything: Station, Adhoc, Mesh, Monitor. 
> That's the end-goal. It's quite do-able, and very much cleaner 
> than any WEXT hookiness.
> 
> 
> > Otherwise you're not doing the driver any good at all, since
> > your patch then just means that both versions need to be
> > maintained. 
> 
> There's not much maintenance in the WEXT part, isn't it?
> 
> 
> 
> 
> Currently we have this situation (with my latest RFC patch):
> 
> CONFIG_LIBERTAS_WEXT defined:
> 
> * basic cfg80211 handler, if someone wants to add deep-sleep,
>   or other functions where we don't want to enhance WEXT
> * station via WEXT
> * monitor mode via sysfs-file
> * mesh via WEXT
> * addhoc via WEXT
> * scanning via WEXT
> * associating via WEXT
> * disconnect notification via WEXT
> 
> CONFIG_LIBERTAS_CFG80211 defined:
> 
> * "full" cfg80211 handler
> * station via CFG80211
> * monitor mode partly done (no packet injection)
> * mesh not done at all, should be implemented via
>   .add_virtual_intf() by someone how has mesh-capable
>   devices
> * adhoc not done, but I'll do that once wireless-testing
>   and ath5k can do adhoc again
> * scanning via cfg80211
> * associating via cfg80211
> * disconnect notification via cfg80211_disconnected()
> 
> So, functionality-wise Libertas + cfg80211 is inferior, but on 
> the same side it's future-proof. And because 
> CONFIG_LIBERTAS_WEXT exist, I'm not taking any functionality 
> away for people that need them.
> 
> On the other side, the implementation for libertas + cfg80211 is 
> much cleaner and smaller than the old WEXT stuff.
> 


^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Dan Williams @ 2009-10-23 16:28 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Holger Schurig, linux-wireless, John Linville
In-Reply-To: <1256313851.12174.131.camel@johannes.local>

On Fri, 2009-10-23 at 18:04 +0200, Johannes Berg wrote:
> On Fri, 2009-10-23 at 08:49 -0700, Dan Williams wrote:
> 
> > > -	(iw_handler) lbs_set_freq,      /* SIOCSIWFREQ */
> > > +	(iw_handler) cfg80211_wext_siwfreq,
> > > 
> > > etc.
> > > 
> > > That's why those exist and are exported. And that way you don't need the
> > > Kconfig at all, and can remove most of the wext code.
> > 
> > I *think* because Holger is trying to keep WEXT around for a bit,
> > because cfg80211 won't be mature enough yet (IMHO, I could be wrong) by
> > 2.6.33, and because it doesn't support the OLPC-style mesh stuff and the
> > libertas monitor interface code.  There's a few loose-ends that need to
> > be tied up before a cfg80211 conversion would completely replace the
> > functionality of the WEXT code.
> 
> I just don't understand why he thinks that wext and cfg80211 need to be
> mutually exclusive. cfg80211 has exported its handlers for exactly this
> purpose, so that you could have everything that cfg80211 supports via
> it, and everything else directly.

I thought about it more, and I think we can go all cfg80211 with a small
WEXT handler for the mesh bits (it only cares about 4 of the WEXT
operations and redirected the rest to the STA interface handlers).  The
mesh stuff is actually quite simple operationally.

Dan


^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Dan Williams @ 2009-10-23 16:30 UTC (permalink / raw)
  To: Holger Schurig; +Cc: Johannes Berg, linux-wireless, John Linville
In-Reply-To: <200910231756.47472.hs4233@mail.mn-solutions.de>

On Fri, 2009-10-23 at 17:56 +0200, Holger Schurig wrote:
> On Friday 23 October 2009 16:19:31 Johannes Berg wrote:
> > On Thu, 2009-10-22 at 15:31 +0200, Holger Schurig wrote:
> > 
> > > +#ifdef CONFIG_LIBERTAS_WEXT
> > >  	dev->ethtool_ops = &lbs_ethtool_ops;
> > >  	dev->wireless_handlers = &lbs_handler_def;
> > >  #endif
> > 
> > So here you make the wireless_handlers optional.
> > 
> > I still don't understand why you can't just replace only some 
> of the
> > handlers, i.e. instead of doing this, simply do
> > 
> > -	(iw_handler) lbs_set_freq,      /* SIOCSIWFREQ */
> > +	(iw_handler) cfg80211_wext_siwfreq,
> > 
> > etc.
> > 
> > That's why those exist and are exported. And that way you don't
> > need the Kconfig at all, and can remove most of the wext code.
> 
> The Kconfig has *NOTHING* to do with mesh.
> 
> MESH should be implemented via add_virtual_intf() / 
> change_virtual_intf(). This code isn't there yet, mesh_dev is 
> always NULL in the CONFIG_LIBERTAS_CFG80211 case, so there's no 
> need to export anything to ethtool or WEXT.
> 
> And having cfg80211 + (mesh_dev != NULL) is something that
> I cannot program, due to (sigh) missing hardware, time,
> testing ability. Repeat rinse wash, repeat rinse wash ...
> 
> 
> Okay, I now stop talking about this. Please talk with Dan about 
> the matter. He knows cfg80211 and libertas probably better than 
> I. Once you two have found a decision, I'm looking if I'm still 
> interested.

Please keep going :)  At this point, you likely understand cfg80211
better than I do.  And as I"ve commented in a few other mails this
morning, I don't think it'll be as complex as I thought it was earlier.

Dan



^ permalink raw reply

* Re: [ath9k-devel] mac80211/ath9k/hostapd: Some clients unable to associate with AP
From: Jouni Malinen @ 2009-10-23 16:30 UTC (permalink / raw)
  To: Björn Smedman
  Cc: Joerg Pommnitz, Will Dyson, Johannes Berg, ath9k-devel,
	linux-wireless
In-Reply-To: <133e8d7e0910230827x4febf4ccw6920d88830444abd@mail.gmail.com>

On Fri, Oct 23, 2009 at 05:27:27PM +0200, Björn Smedman wrote:

> It seems the problem is a typo in net/mac80211/tx.c that causes
> injected frames from hostapd not to be associated with the correct ap
> interface before going into ieee80211_tx_h_sequence(). This tiny patch
> solves my problems (and looks reasonable to me in any case):

Thanks! Would you be able to make the same patch against the
wireless-testing.git repository and add a Signed-off-by line to meet the
kernel submission requirements?

> diff -urN compat-wireless-2009-10-21-before_seqnum_fix/net/mac80211/tx.c
> compat-wireless-2009-10-21/net/mac80211/tx.c
> @@ -1445,7 +1445,7 @@
>                                 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
>                                         continue;
>                                 if (compare_ether_addr(tmp_sdata->dev->dev_addr,
> -                                                      hdr->addr2)) {
> +                                                      hdr->addr2) == 0) {
>                                         dev_hold(tmp_sdata->dev);
>                                         dev_put(sdata->dev);
>                                         sdata = tmp_sdata;

This does indeed look like a typo. Though, I'm not sure how this would
have caused a regression between compat-wireless-2009-06-02 and
compat-wireless-2.6.32-rc1. The incorrect compare_ether_addr() use seems
to be there in the original commit that added this code
(25d834e16294c8dfd923dae6bdb8a055391a99a5 from September 12, 2008)..

Johannes: Any idea why the sequence number allocation for injected
frames from hostapd would have changed between 2009-06-02 and now? This
bug seems to be too old to explain that ;-).

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Dan Williams @ 2009-10-23 16:31 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Holger Schurig, linux-wireless, John Linville
In-Reply-To: <1256315335.2164.44.camel@localhost.localdomain>

On Fri, 2009-10-23 at 09:28 -0700, Dan Williams wrote:
> On Fri, 2009-10-23 at 18:04 +0200, Johannes Berg wrote:
> > On Fri, 2009-10-23 at 08:49 -0700, Dan Williams wrote:
> > 
> > > > -	(iw_handler) lbs_set_freq,      /* SIOCSIWFREQ */
> > > > +	(iw_handler) cfg80211_wext_siwfreq,
> > > > 
> > > > etc.
> > > > 
> > > > That's why those exist and are exported. And that way you don't need the
> > > > Kconfig at all, and can remove most of the wext code.
> > > 
> > > I *think* because Holger is trying to keep WEXT around for a bit,
> > > because cfg80211 won't be mature enough yet (IMHO, I could be wrong) by
> > > 2.6.33, and because it doesn't support the OLPC-style mesh stuff and the
> > > libertas monitor interface code.  There's a few loose-ends that need to
> > > be tied up before a cfg80211 conversion would completely replace the
> > > functionality of the WEXT code.
> > 
> > I just don't understand why he thinks that wext and cfg80211 need to be
> > mutually exclusive. cfg80211 has exported its handlers for exactly this
> > purpose, so that you could have everything that cfg80211 supports via
> > it, and everything else directly.
> 
> I thought about it more, and I think we can go all cfg80211 with a small
> WEXT handler for the mesh bits (it only cares about 4 of the WEXT
> operations and redirected the rest to the STA interface handlers).  The
> mesh stuff is actually quite simple operationally.

Which should allow us to use cfg80211 by default, and then have only the
LIBERTAS_MESH Kconfig option depend on WEXT.  Maybe?

Dan
 


^ permalink raw reply

* Re: NOHZ: local_softirq_pending 08
From: Tilman Schmidt @ 2009-10-23 16:33 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Jarek Poplawski, David Miller, hidave.darkstar, linux-kernel,
	tglx, linux-wireless, linux-ppp, netdev, paulus, isdn4linux,
	i4ldeveloper, Karsten Keil
In-Reply-To: <1256308311.12174.38.camel@johannes.local>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Johannes Berg schrieb:
> On Fri, 2009-10-23 at 16:27 +0200, Tilman Schmidt wrote:
>> Johannes Berg schrieb:
>>> So you've verified that the entire i4l stack can cope with being called
>>> twice on the same CPU, from different contexts?
>> What makes you think so?
> 
> I thought I'd explained this in my other email. *sigh*
[snip]

Ah, I see. You misunderstood my posting. I did not propose that
patch as a definitive and verified solution, but rather as a
request for comments from the people who know and maintain the
code in question. I thought that was clear from the facts that
- - I didn't include "[PATCH]" in the subject line
- - I didn't add a "Signed-off-by" line
- - I wrote "fixed the messages", not "solved the problem"
- - I explicitly wrote "Comments?" and "Adding i4l people to CC"

Apparently all that was still not clear enough. Sorry about that.
So let me try to make my concern as explicit as possible:

- - The patch I posted had the effect that the test which reliably
  triggered the local_softirq_pending message before did not do
  so anymore.

- - To me, this seems to indicate that the netif_rx(skb) call in
  line 1177 of source file drivers/isdn/i4l/isdn_ppp.c is indeed
  involved in the problem.

- - Now I'm asking people who know more than myself about the
  ramifications of that message (ie., you) and/or the code I
  narrowed it down to (ie., the ISDN4Linux maintainers - which
  is why I added them to the CC list) to have a look and determine
  how to fix the problem properly.

- - This would of course include, in finis, the verification you
  mistakenly assumed I might have done already.

I hope that's clear enough. If you have any questions, feel free
to ask.

Thanks,
Tilman

- --
Tilman Schmidt                    E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFK4drJQ3+did9BuFsRAmstAJ94UF/LupINlYpjbxzz9xoiN5w34wCfflRz
YfR/fXt3HasrxUSP29REOnE=
=VQ/C
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Johannes Berg @ 2009-10-23 16:39 UTC (permalink / raw)
  To: Dan Williams; +Cc: Holger Schurig, linux-wireless, John Linville
In-Reply-To: <1256315496.2164.47.camel@localhost.localdomain>

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

On Fri, 2009-10-23 at 09:31 -0700, Dan Williams wrote:

> > > I just don't understand why he thinks that wext and cfg80211 need to be
> > > mutually exclusive. cfg80211 has exported its handlers for exactly this
> > > purpose, so that you could have everything that cfg80211 supports via
> > > it, and everything else directly.
> > 
> > I thought about it more, and I think we can go all cfg80211 with a small
> > WEXT handler for the mesh bits (it only cares about 4 of the WEXT
> > operations and redirected the rest to the STA interface handlers).  The
> > mesh stuff is actually quite simple operationally.
> 
> Which should allow us to use cfg80211 by default, and then have only the
> LIBERTAS_MESH Kconfig option depend on WEXT.  Maybe?

Well if you want to push the mesh wext bits through to cfg80211
(temporarily) you wouldn't even need to depend on WEXT. I'd prefer,
however, to not do this, and just use the cfg80211 wext handlers in
libertas and depend on WEXT for now.

johannes

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

^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Dan Williams @ 2009-10-23 16:42 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Holger Schurig, linux-wireless, John Linville
In-Reply-To: <1256315972.12174.168.camel@johannes.local>

On Fri, 2009-10-23 at 18:39 +0200, Johannes Berg wrote:
> On Fri, 2009-10-23 at 09:31 -0700, Dan Williams wrote:
> 
> > > > I just don't understand why he thinks that wext and cfg80211 need to be
> > > > mutually exclusive. cfg80211 has exported its handlers for exactly this
> > > > purpose, so that you could have everything that cfg80211 supports via
> > > > it, and everything else directly.
> > > 
> > > I thought about it more, and I think we can go all cfg80211 with a small
> > > WEXT handler for the mesh bits (it only cares about 4 of the WEXT
> > > operations and redirected the rest to the STA interface handlers).  The
> > > mesh stuff is actually quite simple operationally.
> > 
> > Which should allow us to use cfg80211 by default, and then have only the
> > LIBERTAS_MESH Kconfig option depend on WEXT.  Maybe?
> 
> Well if you want to push the mesh wext bits through to cfg80211
> (temporarily) you wouldn't even need to depend on WEXT. I'd prefer,
> however, to not do this, and just use the cfg80211 wext handlers in
> libertas and depend on WEXT for now.

Yeah, I think it's best to handle the mesh WEXT ioctls separately for
now.  There are really only 4 of them (get/set SSID, set channel, get
mode) that matter for mesh.  The rest of the ioctls that the mesh
interface supports get redirected to the cfg80211 handlers because they
aren't specific to mesh.

Dan



^ permalink raw reply

* Re: [ath9k-devel] mac80211/ath9k/hostapd: Some clients unable to associate with AP
From: Johannes Berg @ 2009-10-23 16:45 UTC (permalink / raw)
  To: Jouni Malinen
  Cc: Björn Smedman, Joerg Pommnitz, Will Dyson, ath9k-devel,
	linux-wireless
In-Reply-To: <20091023163001.GA4911@jm.kir.nu>

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

On Fri, 2009-10-23 at 09:30 -0700, Jouni Malinen wrote:

> > diff -urN compat-wireless-2009-10-21-before_seqnum_fix/net/mac80211/tx.c
> > compat-wireless-2009-10-21/net/mac80211/tx.c
> > @@ -1445,7 +1445,7 @@
> >                                 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
> >                                         continue;
> >                                 if (compare_ether_addr(tmp_sdata->dev->dev_addr,
> > -                                                      hdr->addr2)) {
> > +                                                      hdr->addr2) == 0) {
> >                                         dev_hold(tmp_sdata->dev);
> >                                         dev_put(sdata->dev);
> >                                         sdata = tmp_sdata;
> 
> This does indeed look like a typo. Though, I'm not sure how this would
> have caused a regression between compat-wireless-2009-06-02 and
> compat-wireless-2.6.32-rc1. The incorrect compare_ether_addr() use seems
> to be there in the original commit that added this code
> (25d834e16294c8dfd923dae6bdb8a055391a99a5 from September 12, 2008)..
> 
> Johannes: Any idea why the sequence number allocation for injected
> frames from hostapd would have changed between 2009-06-02 and now? This
> bug seems to be too old to explain that ;-).

Indeed, I have no idea though.

johannes

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

^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Johannes Berg @ 2009-10-23 16:48 UTC (permalink / raw)
  To: Dan Williams; +Cc: Holger Schurig, linux-wireless, John Linville
In-Reply-To: <1256316179.2164.53.camel@localhost.localdomain>

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

On Fri, 2009-10-23 at 09:42 -0700, Dan Williams wrote:

> Yeah, I think it's best to handle the mesh WEXT ioctls separately for
> now.  There are really only 4 of them (get/set SSID, set channel, get
> mode) that matter for mesh.  The rest of the ioctls that the mesh
> interface supports get redirected to the cfg80211 handlers because they
> aren't specific to mesh.

So why can't we simply do

set_ssid()
{
	if (mesh)
		return mesh_set_ssid();
	else
		return cfg80211_wext_iwessid()
}

johannes

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

^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Dan Williams @ 2009-10-23 16:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Holger Schurig, linux-wireless, John Linville
In-Reply-To: <1256316535.12174.186.camel@johannes.local>

On Fri, 2009-10-23 at 18:48 +0200, Johannes Berg wrote:
> On Fri, 2009-10-23 at 09:42 -0700, Dan Williams wrote:
> 
> > Yeah, I think it's best to handle the mesh WEXT ioctls separately for
> > now.  There are really only 4 of them (get/set SSID, set channel, get
> > mode) that matter for mesh.  The rest of the ioctls that the mesh
> > interface supports get redirected to the cfg80211 handlers because they
> > aren't specific to mesh.
> 
> So why can't we simply do
> 
> set_ssid()
> {
> 	if (mesh)
> 		return mesh_set_ssid();
> 	else
> 		return cfg80211_wext_iwessid()
> }

The mesh interface is a completely separate netdev, with its own WEXT
handler struct.  So we'd never be in that situation.

Dan



^ permalink raw reply

* Re: [PATCH 17/19] [RFC, v2] libertas: Kconfig entry for libertas+cfg80211
From: Johannes Berg @ 2009-10-23 17:04 UTC (permalink / raw)
  To: Dan Williams; +Cc: Holger Schurig, linux-wireless, John Linville
In-Reply-To: <1256316776.2164.54.camel@localhost.localdomain>

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

On Fri, 2009-10-23 at 09:52 -0700, Dan Williams wrote:

> > > Yeah, I think it's best to handle the mesh WEXT ioctls separately for
> > > now.  There are really only 4 of them (get/set SSID, set channel, get
> > > mode) that matter for mesh.  The rest of the ioctls that the mesh
> > > interface supports get redirected to the cfg80211 handlers because they
> > > aren't specific to mesh.
> > 
> > So why can't we simply do
> > 
> > set_ssid()
> > {
> > 	if (mesh)
> > 		return mesh_set_ssid();
> > 	else
> > 		return cfg80211_wext_iwessid()
> > }
> 
> The mesh interface is a completely separate netdev, with its own WEXT
> handler struct.  So we'd never be in that situation.

Ah right. Yes then it makes sense to just remove all the non-mesh WEXT
stuff.

johannes

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

^ permalink raw reply

* Re: [RFC v2 0/5] orinoco: use cfg80211 for key manipulation
From: Dave @ 2009-10-23 19:05 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless
In-Reply-To: <b88bb1ad0909121654w43215f60lf9d7b90d4b54bf35@mail.gmail.com>

Dave Kilroy wrote:
> On Tue, Sep 1, 2009 at 5:59 AM, John W. Linville <linville@tuxdriver.com> wrote:
>> On Wed, Aug 19, 2009 at 01:04:08AM +0100, David Kilroy wrote:
>>> This series basically works (at least after the last patch is applied)

>> Any word on this series?  Time is short for 2.6.32...
> 
> I'm on holiday right now, but will be back in a week.

FYI I haven't had much time to look at this lately, and will definitely
not be able to do anything with it in the next month. So this will
probably slip another release.

Current status: I've addressed Johannes' comments, and reworked things
so cfg80211 would scan if it doesn't find the bss struct after
connecting. Unfortunately it's not working and I haven't found the time
for a proper debugging session.


Dave.

^ permalink raw reply

* [PATCH 01/18] iwlwifi: add missing commands to syslog messages
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Jay Sternberg, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Jay Sternberg <jay.e.sternberg@intel.com>

Two commands missing from list of commands such that when debug is
enabled, these commands are shown as UNKNOWN.

Missing commands are TX_ANT_CONFIGURATION_CMD and
TEMPERATURE_NOTIFICATION.

Signed-off-by: Jay Sternberg <jay.e.sternberg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-commands.h |    1 +
 drivers/net/wireless/iwlwifi/iwl-hcmd.c     |    2 ++
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 7d4f131..1a7c0d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -114,6 +114,7 @@ enum {
 	COEX_EVENT_CMD = 0x5c,
 
 	/* Calibration */
+	TEMPERATURE_NOTIFICATION = 0x62,
 	CALIBRATION_CFG_CMD = 0x65,
 	CALIBRATION_RES_NOTIFICATION = 0x66,
 	CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 22a21a1..f2a60dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -92,6 +92,8 @@ const char *get_cmd_string(u8 cmd)
 		IWL_CMD(CALIBRATION_RES_NOTIFICATION);
 		IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
 		IWL_CMD(REPLY_TX_POWER_DBM_CMD);
+		IWL_CMD(TEMPERATURE_NOTIFICATION);
+		IWL_CMD(TX_ANT_CONFIGURATION_CMD);
 	default:
 		return "UNKNOWN";
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 02/18] iwlwifi: fix gain computation for 5000 series and up
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

In Rx gain balancing (chain noise) computation for 5000 series and up,
the delta gain calculation should use the average noise of default
chain, not "chain 0" which do not exist for all the devices.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-5000.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 17555c7..afa88a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -236,7 +236,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
 			data->delta_gain_code[i] = 0;
 			continue;
 		}
-		delta_g = (1000 * ((s32)average_noise[0] -
+		delta_g = (1000 * ((s32)average_noise[default_chain] -
 			(s32)average_noise[i])) / 1500;
 		/* bound gain by 2 bits value max, 3rd bit is sign */
 		data->delta_gain_code[i] =
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 00/18] iwlwifi updates 10/23/2009
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre

This series includes the cleanup patch promised after feedback on "iwlwifi:
rework for static power save" from previous series.

Ben M Cahill (2):
  iwlwifi: consolidate apm_init() functions
  iwlwifi: make sure device is reset when unloading driver

Jay Sternberg (1):
  iwlwifi: add missing commands to syslog messages

Reinette Chatre (1):
  iwlwifi: remove duplicate defines

Wey-Yi Guy (12):
  iwlwifi: fix gain computation for 5000 series and up
  iwlwifi: separate led function from statistic notification
  iwlwifi: update bt co-exit configuration parameter
  iwlwifi: specify the valid tx/rx chain in device config structure
  iwlwifi: increase max tfd payload size
  iwlwifi: choose thermal throttle method based on device config
  iwlwifi: issue ct_kill host command based on device config
  iwlwifi: add channel switch support to 5000 series and up
  iwlwifi: remove unused parameters
  iwlwifi: remove duplicated define
  iwlwifi: update lowest API version support for 6x00 & 6x50 series
  iwlwifi: minor comments changes for wimax co-exist command

Zhu Yi (2):
  iwlwifi: fix use after free bug for paged rx
  iwlwifi: reuse page for notification packets

 drivers/net/wireless/iwlwifi/iwl-1000.c     |   12 ++-
 drivers/net/wireless/iwlwifi/iwl-3945-hw.h  |    6 -
 drivers/net/wireless/iwlwifi/iwl-3945.c     |   79 +++-----------
 drivers/net/wireless/iwlwifi/iwl-3945.h     |    8 --
 drivers/net/wireless/iwlwifi/iwl-4965.c     |   78 +++-----------
 drivers/net/wireless/iwlwifi/iwl-5000.c     |  120 ++++++++++------------
 drivers/net/wireless/iwlwifi/iwl-6000.c     |   98 +++++++++++++++---
 drivers/net/wireless/iwlwifi/iwl-agn.c      |   49 ++++++---
 drivers/net/wireless/iwlwifi/iwl-commands.h |   16 +++-
 drivers/net/wireless/iwlwifi/iwl-core.c     |  150 ++++++++++++++++++++++++---
 drivers/net/wireless/iwlwifi/iwl-core.h     |   13 ++-
 drivers/net/wireless/iwlwifi/iwl-dev.h      |   18 ++--
 drivers/net/wireless/iwlwifi/iwl-hcmd.c     |    2 +
 drivers/net/wireless/iwlwifi/iwl-power.c    |   12 +--
 drivers/net/wireless/iwlwifi/iwl-power.h    |    2 -
 drivers/net/wireless/iwlwifi/iwl-rx.c       |   24 +++--
 drivers/net/wireless/iwlwifi/iwl-tx.c       |    9 +--
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   54 +++++++---
 18 files changed, 446 insertions(+), 304 deletions(-)


^ permalink raw reply

* [PATCH 03/18] iwlwifi: consolidate apm_init() functions
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Ben Cahill, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Ben Cahill <ben.m.cahill@intel.com>

Consolidate most iwlXXXX_apm_init() functions into single iwl_apm_init().
Keep iwl3945_apm_init(), but leverage iwl_apm_init() for most functionality.
Update 4965 init sequence to follow most recent factory recommendations.

Add following members to struct iwl_cfg to guide the init sequence:
pll_cfg_val (replaces needs_pll_cfg), set_l0s, use_bsm

Move L0S enable/disable from nic_config() functions to iwl_apm_init().
This satisifies the "FIXME: put here L1A -L0S w/a" notice, and complies
with factory-recommended sequence.

Add debug info message in iwl_apm_init(), and symmetrical message
in iwl_apm_stop().

Signed-off-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-1000.c |   10 ++-
 drivers/net/wireless/iwlwifi/iwl-3945.c |   56 ++-------------
 drivers/net/wireless/iwlwifi/iwl-4965.c |   56 +--------------
 drivers/net/wireless/iwlwifi/iwl-5000.c |   86 ++++++------------------
 drivers/net/wireless/iwlwifi/iwl-6000.c |   42 ++++++++---
 drivers/net/wireless/iwlwifi/iwl-core.c |  114 +++++++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.h |    8 ++-
 drivers/net/wireless/iwlwifi/iwl-dev.h  |    1 -
 8 files changed, 190 insertions(+), 183 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index a00f947..3da5913 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -110,7 +110,7 @@ static struct iwl_lib_ops iwl1000_lib = {
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
+		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
 		.config = iwl1000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
@@ -163,7 +163,9 @@ struct iwl_cfg iwl1000_bgn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = false,
+	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
 	.shadow_ram_support = false,
 	.ht_greenfield_support = true,
@@ -186,7 +188,9 @@ struct iwl_cfg iwl1000_bg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = false,
+	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
 	.shadow_ram_support = false,
 	.ht_greenfield_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 9f18b4c..7142aa5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1013,55 +1013,15 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
 	return rc;
 }
 
+
 /*
- * Start up NIC's basic functionality after it has been reset
- * (e.g. after platform boot, or shutdown via iwl3945_apm_stop())
+ * Start up 3945's basic functionality after it has been reset
+ * (e.g. after platform boot, or shutdown via iwl_apm_stop())
  * NOTE:  This does not load uCode nor start the embedded processor
  */
 static int iwl3945_apm_init(struct iwl_priv *priv)
 {
-	int ret;
-
-	/* Configure chip clock phase-lock-loop */
-	iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
-
-	/*
-	 * Disable L0S exit timer (platform NMI Work/Around)
-	 * (does this do anything on 3945, or just 4965 and beyond?)
-	 */
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	/* Disable L0s without affecting L1; don't wait for ICH (L0s bug W/A) */
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-	/* Set FH wait threshold to maximum (HW error during stress W/A) */
-	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
-
-	/*
-	 * Set "initialization complete" bit to move adapter from
-	 * D0U* --> D0A* (powered-up active) state.
-	 */
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	/*
-	 * Wait for clock stabilization; once stabilized, access to
-	 * device-internal resources is supported, e.g. iwl_write_prph()
-	 * and accesses to uCode SRAM.
-	 */
-	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out;
-	}
-
-	/* Enable DMA and BSM clocks, wait for them to stabilize */
-	iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
-						APMG_CLK_VAL_BSM_CLK_RQT);
-	udelay(20);
+	int ret = iwl_apm_init(priv);
 
 	/* Clear APMG (NIC's internal power management) interrupts */
 	iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
@@ -1072,11 +1032,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
 	udelay(5);
 	iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
 
-	/* Disable L1-Active */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-out:
 	return ret;
 }
 
@@ -2876,6 +2831,9 @@ static struct iwl_cfg iwl3945_bg_cfg = {
 	.ops = &iwl3945_ops,
 	.num_of_queues = IWL39_NUM_QUEUES,
 	.mod_params = &iwl3945_mod_params,
+	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+	.set_l0s = false,
+	.use_bsm = true,
 	.use_isr_legacy = true,
 	.ht_greenfield_support = false,
 	.led_compensation = 64,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 1a622aa..32d5f3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -317,64 +317,13 @@ static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask)
 	iwl_write_prph(priv, IWL49_SCD_TXFACT, mask);
 }
 
-static int iwl4965_apm_init(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	/* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-	/* set "initialization complete" bit to move adapter
-	 * D0U* --> D0A* state */
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	/* wait for clock stabilization */
-	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out;
-	}
-
-	/* enable DMA */
-	iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
-						APMG_CLK_VAL_BSM_CLK_RQT);
-
-	udelay(20);
-
-	/* disable L1-Active */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-out:
-	return ret;
-}
-
-
 static void iwl4965_nic_config(struct iwl_priv *priv)
 {
 	unsigned long flags;
 	u16 radio_cfg;
-	u16 lctl;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	lctl = iwl_pcie_link_ctl(priv);
-
-	/* HW bug W/A - negligible power consumption */
-	/* L1-ASPM is enabled by BIOS */
-	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-		/* L1-ASPM enabled: disable L0S  */
-		iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-	else
-		/* L1-ASPM disabled: enable L0S */
-		iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-
 	radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 
 	/* write radio config values to register */
@@ -2223,7 +2172,7 @@ static struct iwl_lib_ops iwl4965_lib = {
 	.dump_nic_event_log = iwl_dump_nic_event_log,
 	.dump_nic_error_log = iwl_dump_nic_error_log,
 	.apm_ops = {
-		.init = iwl4965_apm_init,
+		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
 		.config = iwl4965_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
@@ -2276,6 +2225,9 @@ struct iwl_cfg iwl4965_agn_cfg = {
 	.num_of_queues = IWL49_NUM_QUEUES,
 	.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl4965_mod_params,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = true,
 	.use_isr_legacy = true,
 	.ht_greenfield_support = false,
 	.broken_powersave = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index afa88a3..a6e347b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -72,72 +72,14 @@ static const u16 iwl5000_default_queue_to_tx_fifo[] = {
 	IWL_TX_FIFO_HCCA_2
 };
 
-int iwl5000_apm_init(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-		    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	/* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
-	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-		    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-	/* Set FH wait threshold to maximum (HW error during stress W/A) */
-	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
-
-	/* enable HAP INTA to move device L1a -> L0s */
-	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
-		    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
-
-	if (priv->cfg->need_pll_cfg)
-		iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
-
-	/* set "initialization complete" bit to move adapter
-	 * D0U* --> D0A* state */
-	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	/* wait for clock stabilization */
-	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		return ret;
-	}
-
-	/* enable DMA */
-	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
-
-	udelay(20);
-
-	/* disable L1-Active */
-	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-	return ret;
-}
-
 /* NIC configuration for 5000 series */
 void iwl5000_nic_config(struct iwl_priv *priv)
 {
 	unsigned long flags;
 	u16 radio_cfg;
-	u16 lctl;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	lctl = iwl_pcie_link_ctl(priv);
-
-	/* HW bug W/A */
-	/* L1-ASPM is enabled by BIOS */
-	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-		/* L1-APSM enabled: disable L0S  */
-		iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-	else
-		/* L1-ASPM disabled: enable L0S */
-		iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
-
 	radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
 
 	/* write radio config values to register */
@@ -1488,7 +1430,7 @@ struct iwl_lib_ops iwl5000_lib = {
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
+		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
 		.config = iwl5000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
@@ -1539,7 +1481,7 @@ static struct iwl_lib_ops iwl5150_lib = {
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
+		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
 		.config = iwl5000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
@@ -1607,7 +1549,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1628,7 +1572,9 @@ struct iwl_cfg iwl5100_bg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1649,7 +1595,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1670,7 +1618,9 @@ struct iwl_cfg iwl5100_agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1691,7 +1641,9 @@ struct iwl_cfg iwl5350_agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
@@ -1712,7 +1664,9 @@ struct iwl_cfg iwl5150_agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = true,
+	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
+	.set_l0s = true,
+	.use_bsm = false,
 	.ht_greenfield_support = true,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index b531813..5211872 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -193,7 +193,7 @@ static struct iwl_lib_ops iwl6000_lib = {
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.apm_ops = {
-		.init =	iwl5000_apm_init,
+		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
 		.config = iwl6000_nic_config,
 		.set_pwr_src = iwl_set_pwr_src,
@@ -266,7 +266,9 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_HYBRID,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
@@ -292,7 +294,9 @@ struct iwl_cfg iwl6000h_2abg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_HYBRID,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
@@ -317,7 +321,9 @@ struct iwl_cfg iwl6000h_2bg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_HYBRID,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
@@ -345,7 +351,9 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_BC,
 	.valid_rx_ant = ANT_BC,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
@@ -371,7 +379,9 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_BC,
 	.valid_rx_ant = ANT_BC,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
@@ -396,7 +406,9 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_BC,
 	.valid_rx_ant = ANT_BC,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_INTERNAL,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
@@ -421,7 +433,9 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
 	.shadow_ram_support = true,
@@ -447,7 +461,9 @@ struct iwl_cfg iwl6050_2abg_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
 	.shadow_ram_support = true,
@@ -472,7 +488,9 @@ struct iwl_cfg iwl6000_3agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
@@ -498,7 +516,9 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
-	.need_pll_cfg = false,
+	.pll_cfg_val = 0,
+	.set_l0s = false,
+	.use_bsm = false,
 	.pa_type = IWL_PA_SYSTEM,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
 	.shadow_ram_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 7ce8663..1d7248c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1369,6 +1369,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
 {
 	unsigned long flags;
 
+	IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
+
 	iwl_apm_stop_master(priv);
 
 	spin_lock_irqsave(&priv->lock, flags);
@@ -1382,6 +1384,118 @@ void iwl_apm_stop(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_apm_stop);
 
+
+/*
+ * Start up NIC's basic functionality after it has been reset
+ * (e.g. after platform boot, or shutdown via iwl_apm_stop())
+ * NOTE:  This does not load uCode nor start the embedded processor
+ */
+int iwl_apm_init(struct iwl_priv *priv)
+{
+	int ret = 0;
+	u16 lctl;
+
+	IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
+
+	/*
+	 * Use "set_bit" below rather than "write", to preserve any hardware
+	 * bits already set by default after reset.
+	 */
+
+	/* Disable L0S exit timer (platform NMI Work/Around) */
+	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+	/*
+	 * Disable L0s without affecting L1;
+	 *  don't wait for ICH L0s (ICH bug W/A)
+	 */
+	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+	/* Set FH wait threshold to maximum (HW error during stress W/A) */
+	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
+
+	/*
+	 * Enable HAP INTA (interrupt from management bus) to
+	 * wake device's PCI Express link L1a -> L0s
+	 * NOTE:  This is no-op for 3945 (non-existant bit)
+	 */
+	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
+
+	/*
+	 * HW bug W/A - costs negligible power consumption ...
+	 * Check if BIOS (or OS) enabled L1-ASPM on this device
+	 */
+	if (priv->cfg->set_l0s) {
+		lctl = iwl_pcie_link_ctl(priv);
+		if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+					PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+			/* L1-ASPM enabled; disable(!) L0S  */
+			iwl_set_bit(priv, CSR_GIO_REG,
+					CSR_GIO_REG_VAL_L0S_ENABLED);
+			IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
+		} else {
+			/* L1-ASPM disabled; enable(!) L0S */
+			iwl_clear_bit(priv, CSR_GIO_REG,
+					CSR_GIO_REG_VAL_L0S_ENABLED);
+			IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
+		}
+	}
+
+	/* Configure analog phase-lock-loop before activating to D0A */
+	if (priv->cfg->pll_cfg_val)
+		iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val);
+
+	/*
+	 * Set "initialization complete" bit to move adapter from
+	 * D0U* --> D0A* (powered-up active) state.
+	 */
+	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+	/*
+	 * Wait for clock stabilization; once stabilized, access to
+	 * device-internal resources is supported, e.g. iwl_write_prph()
+	 * and accesses to uCode SRAM.
+	 */
+	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+	if (ret < 0) {
+		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
+		goto out;
+	}
+
+	/*
+	 * Enable DMA and BSM (if used) clocks, wait for them to stabilize.
+	 * BSM (Boostrap State Machine) is only in 3945 and 4965;
+	 * later devices (i.e. 5000 and later) have non-volatile SRAM,
+	 * and don't need BSM to restore data after power-saving sleep.
+	 *
+	 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
+	 * do not disable clocks.  This preserves any hardware bits already
+	 * set by default in "CLK_CTRL_REG" after reset.
+	 */
+	if (priv->cfg->use_bsm)
+		iwl_write_prph(priv, APMG_CLK_EN_REG,
+			APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
+	else
+		iwl_write_prph(priv, APMG_CLK_EN_REG,
+			APMG_CLK_VAL_DMA_CLK_RQT);
+	udelay(20);
+
+	/* Disable L1-Active */
+	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+out:
+	return ret;
+}
+EXPORT_SYMBOL(iwl_apm_init);
+
+
+
 void iwl_configure_filter(struct ieee80211_hw *hw,
 			  unsigned int changed_flags,
 			  unsigned int *total_flags,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a2a580d..a2d526a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -262,7 +262,12 @@ struct iwl_cfg {
 	const struct iwl_mod_params *mod_params;
 	u8   valid_tx_ant;
 	u8   valid_rx_ant;
-	bool need_pll_cfg;
+
+	/* for iwl_apm_init() */
+	u32 pll_cfg_val;
+	bool set_l0s;
+	bool use_bsm;
+
 	bool use_isr_legacy;
 	enum iwl_pa_type pa_type;
 	const u16 max_ll_items;
@@ -663,6 +668,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
 					   struct iwl_rx_mem_buffer *rxb);
 void iwl_apm_stop(struct iwl_priv *priv);
 int iwl_apm_stop_master(struct iwl_priv *priv);
+int iwl_apm_init(struct iwl_priv *priv);
 
 void iwl_setup_rxon_timing(struct iwl_priv *priv);
 static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 6ba082d..1378654 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -85,7 +85,6 @@ extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 				    __le32 *tx_flags);
 extern int iwl5000_calc_rssi(struct iwl_priv *priv,
 			     struct iwl_rx_phy_res *rx_resp);
-extern int iwl5000_apm_init(struct iwl_priv *priv);
 extern void iwl5000_nic_config(struct iwl_priv *priv);
 extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv);
 extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 04/18] iwlwifi: separate led function from statistic notification
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Detach led background task from statistic notification routine. if led
blinking is required; the blink rate is based on the traffic condition.
It do not relate to statistics notification. In addition to that, there is
not a requirement for statistics notification has to occur all the time.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-3945.c |    2 --
 drivers/net/wireless/iwlwifi/iwl-agn.c  |    2 ++
 drivers/net/wireless/iwlwifi/iwl-rx.c   |    3 ---
 3 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 7142aa5..269b988 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -359,8 +359,6 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
 		     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
 
 	memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
-
-	iwl_leds_background(priv);
 }
 
 /******************************************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 64d9187..a34acb7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1019,6 +1019,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 	if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
 		iwl_rx_handle(priv);
 		priv->isr_stats.rx++;
+		iwl_leds_background(priv);
 		handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
 	}
 
@@ -1220,6 +1221,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 				    CSR_INT_PERIODIC_ENA);
 
 		priv->isr_stats.rx++;
+		iwl_leds_background(priv);
 	}
 
 	if (inta & CSR_INT_BIT_FH_TX) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 0a407f7..cfc31ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -627,9 +627,6 @@ void iwl_rx_statistics(struct iwl_priv *priv,
 		iwl_rx_calc_noise(priv);
 		queue_work(priv->workqueue, &priv->run_time_calib_work);
 	}
-
-	iwl_leds_background(priv);
-
 	if (priv->cfg->ops->lib->temp_ops.temperature && change)
 		priv->cfg->ops->lib->temp_ops.temperature(priv);
 }
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 06/18] iwlwifi: specify the valid tx/rx chain in device config structure
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Specify both Tx and Rx chain in device configuration structure instead
of hard code in set_hw_params() for 4965

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-4965.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 32d5f3d..bd856df 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -653,10 +653,10 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
 
 	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
 
-	priv->hw_params.tx_chains_num = 2;
-	priv->hw_params.rx_chains_num = 2;
-	priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
-	priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
+	priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
+	priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
+	priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
 		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
 
@@ -2225,6 +2225,8 @@ struct iwl_cfg iwl4965_agn_cfg = {
 	.num_of_queues = IWL49_NUM_QUEUES,
 	.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
 	.mod_params = &iwl4965_mod_params,
+	.valid_tx_ant = ANT_AB,
+	.valid_rx_ant = ANT_AB,
 	.pll_cfg_val = 0,
 	.set_l0s = true,
 	.use_bsm = true,
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 05/18] iwlwifi: update bt co-exit configuration parameter
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Adding parameter ranges for bt co-exist configuration command.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-commands.h |   13 +++++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.c     |    6 +++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 1a7c0d0..0d660a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2218,6 +2218,19 @@ struct iwl_link_quality_cmd {
 	__le32 reserved2;
 } __attribute__ ((packed));
 
+#define BT_COEX_DISABLE (0x0)
+#define BT_COEX_MODE_2W (0x1)
+#define BT_COEX_MODE_3W (0x2)
+#define BT_COEX_MODE_4W (0x3)
+
+#define BT_LEAD_TIME_MIN (0x0)
+#define BT_LEAD_TIME_DEF (0x1E)
+#define BT_LEAD_TIME_MAX (0xFF)
+
+#define BT_MAX_KILL_MIN (0x1)
+#define BT_MAX_KILL_DEF (0x5)
+#define BT_MAX_KILL_MAX (0xFF)
+
 /*
  * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
  *
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1d7248c..77b9825 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2003,9 +2003,9 @@ EXPORT_SYMBOL(iwl_isr_legacy);
 int iwl_send_bt_config(struct iwl_priv *priv)
 {
 	struct iwl_bt_cmd bt_cmd = {
-		.flags = 3,
-		.lead_time = 0xAA,
-		.max_kill = 1,
+		.flags = BT_COEX_MODE_4W,
+		.lead_time = BT_LEAD_TIME_DEF,
+		.max_kill = BT_MAX_KILL_DEF,
 		.kill_ack_mask = 0,
 		.kill_cts_mask = 0,
 	};
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 09/18] iwlwifi: choose thermal throttle method based on device config
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Using device configuration structure to decide the type of thermal
throttle method for the device.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-6000.c  |   10 ++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.h  |    2 ++
 drivers/net/wireless/iwlwifi/iwl-power.c |    8 ++------
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 5211872..0873322 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -277,6 +277,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6000h_2abg_cfg = {
@@ -304,6 +305,7 @@ struct iwl_cfg iwl6000h_2abg_cfg = {
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6000h_2bg_cfg = {
@@ -331,6 +333,7 @@ struct iwl_cfg iwl6000h_2bg_cfg = {
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 /*
@@ -362,6 +365,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -389,6 +393,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -416,6 +421,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6050_2agn_cfg = {
@@ -444,6 +450,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -471,6 +478,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -499,6 +507,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 struct iwl_cfg iwl6050_3agn_cfg = {
@@ -527,6 +536,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.use_rts_for_ht = true, /* use rts/cts protection */
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.supports_idle = true,
+	.adv_thermal_throttle = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a2d526a..9dbf598 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -225,6 +225,7 @@ struct iwl_mod_params {
  *	The detail algorithm is described in iwl-led.c
  * @use_rts_for_ht: use rts/cts protection for HT traffic
  * @chain_noise_num_beacons: number of beacons used to compute chain noise
+ * @adv_thermal_throttle: support advance thermal throttle
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -278,6 +279,7 @@ struct iwl_cfg {
 	bool use_rts_for_ht;
 	int chain_noise_num_beacons;
 	const bool supports_idle;
+	bool adv_thermal_throttle;
 };
 
 /***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 150ff87..432f465 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -893,9 +893,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
 	INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
 	INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
 
-	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-	case CSR_HW_REV_TYPE_6x00:
-	case CSR_HW_REV_TYPE_6x50:
+	if (priv->cfg->adv_thermal_throttle) {
 		IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
 		tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
 					 IWL_TI_STATE_MAX, GFP_KERNEL);
@@ -928,11 +926,9 @@ void iwl_tt_initialize(struct iwl_priv *priv)
 				&restriction_range[0], size);
 			priv->thermal_throttle.advanced_tt = true;
 		}
-		break;
-	default:
+	} else {
 		IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
 		priv->thermal_throttle.advanced_tt = false;
-		break;
 	}
 }
 EXPORT_SYMBOL(iwl_tt_initialize);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 07/18] iwlwifi: fix use after free bug for paged rx
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Zhu Yi, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Zhu Yi <yi.zhu@intel.com>

In the paged rx patch (4854fde2), I introduced a bug that could possibly
touch an already freed page. It is fixed by avoiding the access in this
patch. I've also added some comments so that other people touching the
code won't make the same mistake. In the future, if we cannot avoid
access the page after being handled to the upper layer, we can use
get_page/put_page to handle it. For now, it's just not necessary.

It also fixed a debug message print bug reported by Stanislaw Gruszka
<sgruszka@redhat.com>.

Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-3945.c     |   15 ++++++++++-----
 drivers/net/wireless/iwlwifi/iwl-agn.c      |   11 +++++++++--
 drivers/net/wireless/iwlwifi/iwl-rx.c       |   21 ++++++++++++++-------
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   18 +++++++++++++-----
 4 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 269b988..f5d7528 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -548,6 +548,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
 	u16 len = le16_to_cpu(rx_hdr->len);
 	struct sk_buff *skb;
 	int ret;
+	__le16 fc = hdr->frame_control;
 
 	/* We received data from the HW, so stop the watchdog */
 	if (unlikely(len + IWL39_RX_FRAME_SIZE >
@@ -580,9 +581,9 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
 	/* mac80211 currently doesn't support paged SKB. Convert it to
 	 * linear SKB for management frame and data frame requires
 	 * software decryption or software defragementation. */
-	if (ieee80211_is_mgmt(hdr->frame_control) ||
-	    ieee80211_has_protected(hdr->frame_control) ||
-	    ieee80211_has_morefrags(hdr->frame_control) ||
+	if (ieee80211_is_mgmt(fc) ||
+	    ieee80211_has_protected(fc) ||
+	    ieee80211_has_morefrags(fc) ||
 	    le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
 		ret = skb_linearize(skb);
 	else
@@ -594,11 +595,15 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
 		goto out;
 	}
 
-	iwl_update_stats(priv, false, hdr->frame_control, len);
+	/*
+	 * XXX: We cannot touch the page and its virtual memory (pkt) after
+	 * here. It might have already been freed by the above skb change.
+	 */
 
+	iwl_update_stats(priv, false, fc, len);
 	memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
-	ieee80211_rx(priv->hw, skb);
 
+	ieee80211_rx(priv->hw, skb);
  out:
 	priv->alloc_rxb_page--;
 	rxb->page = NULL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a34acb7..0d38865 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -814,8 +814,8 @@ void iwl_rx_handle(struct iwl_priv *priv)
 		if (priv->rx_handlers[pkt->hdr.cmd]) {
 			IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
 				i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
-			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 			priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
+			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 		} else {
 			/* No handling needed */
 			IWL_DEBUG_RX(priv,
@@ -824,11 +824,18 @@ void iwl_rx_handle(struct iwl_priv *priv)
 				pkt->hdr.cmd);
 		}
 
+		/*
+		 * XXX: After here, we should always check rxb->page
+		 * against NULL before touching it or its virtual
+		 * memory (pkt). Because some rx_handler might have
+		 * already taken or freed the pages.
+		 */
+
 		if (reclaim) {
 			/* Invoke any callbacks, transfer the buffer to caller,
 			 * and fire off the (possibly) blocking iwl_send_cmd()
 			 * as we reclaim the driver command queue */
-			if (rxb && rxb->page)
+			if (rxb->page)
 				iwl_tx_cmd_complete(priv, rxb);
 			else
 				IWL_WARN(priv, "Claim null rxb?\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index cfc31ae..e5339c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -241,6 +241,7 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 	struct iwl_rx_mem_buffer *rxb;
 	struct page *page;
 	unsigned long flags;
+	gfp_t gfp_mask = priority;
 
 	while (1) {
 		spin_lock_irqsave(&rxq->lock, flags);
@@ -251,13 +252,13 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
 		if (rxq->free_count > RX_LOW_WATERMARK)
-			priority |= __GFP_NOWARN;
+			gfp_mask |= __GFP_NOWARN;
 
 		if (priv->hw_params.rx_page_order > 0)
-			priority |= __GFP_COMP;
+			gfp_mask |= __GFP_COMP;
 
 		/* Alloc a new receive buffer */
-		page = alloc_pages(priority, priv->hw_params.rx_page_order);
+		page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
 		if (!page) {
 			if (net_ratelimit())
 				IWL_DEBUG_INFO(priv, "alloc_pages failed, "
@@ -922,6 +923,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 {
 	struct sk_buff *skb;
 	int ret = 0;
+	__le16 fc = hdr->frame_control;
 
 	/* We only process data packets if the interface is open */
 	if (unlikely(!priv->is_open)) {
@@ -946,9 +948,9 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 	/* mac80211 currently doesn't support paged SKB. Convert it to
 	 * linear SKB for management frame and data frame requires
 	 * software decryption or software defragementation. */
-	if (ieee80211_is_mgmt(hdr->frame_control) ||
-	    ieee80211_has_protected(hdr->frame_control) ||
-	    ieee80211_has_morefrags(hdr->frame_control) ||
+	if (ieee80211_is_mgmt(fc) ||
+	    ieee80211_has_protected(fc) ||
+	    ieee80211_has_morefrags(fc) ||
 	    le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
 		ret = skb_linearize(skb);
 	else
@@ -960,7 +962,12 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 		goto out;
 	}
 
-	iwl_update_stats(priv, false, hdr->frame_control, len);
+	/*
+	 * XXX: We cannot touch the page and its virtual memory (hdr) after
+	 * here. It might have already been freed by the above skb change.
+	 */
+
+	iwl_update_stats(priv, false, fc, len);
 	memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 
 	ieee80211_rx(priv->hw, skb);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5977a57..8b08bdc 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1124,6 +1124,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 	struct iwl_rx_mem_buffer *rxb;
 	struct page *page;
 	unsigned long flags;
+	gfp_t gfp_mask = priority;
 
 	while (1) {
 		spin_lock_irqsave(&rxq->lock, flags);
@@ -1135,13 +1136,13 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
 		if (rxq->free_count > RX_LOW_WATERMARK)
-			priority |= __GFP_NOWARN;
+			gfp_mask |= __GFP_NOWARN;
 
 		if (priv->hw_params.rx_page_order > 0)
-			priority |= __GFP_COMP;
+			gfp_mask |= __GFP_COMP;
 
 		/* Alloc a new receive buffer */
-		page = alloc_pages(priority, priv->hw_params.rx_page_order);
+		page = alloc_pages(gfp_mask, priv->hw_params.rx_page_order);
 		if (!page) {
 			if (net_ratelimit())
 				IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
@@ -1410,8 +1411,8 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
 		if (priv->rx_handlers[pkt->hdr.cmd]) {
 			IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i,
 				get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
-			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 			priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
+			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 		} else {
 			/* No handling needed */
 			IWL_DEBUG_RX(priv,
@@ -1420,11 +1421,18 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
 				pkt->hdr.cmd);
 		}
 
+		/*
+		 * XXX: After here, we should always check rxb->page
+		 * against NULL before touching it or its virtual
+		 * memory (pkt). Because some rx_handler might have
+		 * already taken or freed the pages.
+		 */
+
 		if (reclaim) {
 			/* Invoke any callbacks, transfer the buffer to caller,
 			 * and fire off the (possibly) blocking iwl_send_cmd()
 			 * as we reclaim the driver command queue */
-			if (rxb && rxb->page)
+			if (rxb->page)
 				iwl_tx_cmd_complete(priv, rxb);
 			else
 				IWL_WARN(priv, "Claim null rxb?\n");
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 08/18] iwlwifi: increase max tfd payload size
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Increase the size of TFD_MAX_PAYLOAD_SIZE (the size of iwl_device_cmd)
to accommodate iwl6000_channel_switch_cmd data structure.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Acked-by: Ben Cahill <ben.m.cahill@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-dev.h |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 1378654..b520e55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -364,7 +364,7 @@ enum {
 	CMD_WANT_SKB = (1 << 2),
 };
 
-#define IWL_CMD_MAX_PAYLOAD 320
+#define DEF_CMD_PAYLOAD_SIZE 320
 
 /*
  * IWL_LINK_HDR_MAX should include ieee80211_hdr, radiotap header,
@@ -388,7 +388,8 @@ struct iwl_device_cmd {
 		u16 val16;
 		u32 val32;
 		struct iwl_tx_cmd tx;
-		u8 payload[IWL_CMD_MAX_PAYLOAD];
+		struct iwl6000_channel_switch_cmd chswitch;
+		u8 payload[DEF_CMD_PAYLOAD_SIZE];
 	} __attribute__ ((packed)) cmd;
 } __attribute__ ((packed));
 
@@ -741,7 +742,11 @@ static inline int iwl_queue_used(const struct iwl_queue *q, int i)
 
 static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
 {
-	/* This is for scan command, the big buffer at end of command array */
+	/*
+	 * This is for init calibration result and scan command which
+	 * required buffer > TFD_MAX_PAYLOAD_SIZE,
+	 * the big buffer at end of command array
+	 */
 	if (is_huge)
 		return q->n_window;	/* must be power of 2 */
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 11/18] iwlwifi: add channel switch support to 5000 series and up
From: Reinette Chatre @ 2009-10-23 20:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256330556-20997-1-git-send-email-reinette.chatre@intel.com>

From: Wey-Yi Guy <wey-yi.w.guy@intel.com>

Support "channel switch" request by issue "channel switch" host command
to uCode.

There is no separated "channel switch" indication from mac80211,
when detected "IEEE80211_CONF_CHANGE_CHANNEL" flag in iwl_mac_config(),
if the station is in "associated" state, then assume "channel switch
announcement" IE was received by mac80211.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-3945.c |    6 -----
 drivers/net/wireless/iwlwifi/iwl-3945.h |    2 -
 drivers/net/wireless/iwlwifi/iwl-4965.c |   12 ++++++----
 drivers/net/wireless/iwlwifi/iwl-5000.c |   32 +++++++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-6000.c |   32 +++++++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.c |   21 ++++++++++++++++---
 drivers/net/wireless/iwlwifi/iwl-core.h |    1 +
 7 files changed, 89 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index f5d7528..09a7bd2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1982,12 +1982,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
 	return 0;
 }
 
-/* will add 3945 channel switch cmd handling later */
-int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
-{
-	return 0;
-}
-
 /**
  * iwl3945_reg_txpower_periodic -  called when time to check our temperature.
  *
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index f3907c1..964c019 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -280,8 +280,6 @@ extern void iwl3945_config_ap(struct iwl_priv *priv);
  */
 extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
 
-extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel);
-
 /*
  * Forward declare iwl-3945.c functions for iwl-base.c
  */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index bd856df..1ff465a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1433,14 +1433,13 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
 	return ret;
 }
 
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
 static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 {
 	int rc;
 	u8 band = 0;
 	bool is_ht40 = false;
 	u8 ctrl_chan_high = 0;
-	struct iwl4965_channel_switch_cmd cmd = { 0 };
+	struct iwl4965_channel_switch_cmd cmd;
 	const struct iwl_channel_info *ch_info;
 
 	band = priv->band == IEEE80211_BAND_2GHZ;
@@ -1461,8 +1460,11 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 	cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
 	if (ch_info)
 		cmd.expect_beacon = is_channel_radar(ch_info);
-	else
-		cmd.expect_beacon = 1;
+	else {
+		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
+			priv->active_rxon.channel, channel);
+		return -EFAULT;
+	}
 
 	rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40,
 				      ctrl_chan_high, &cmd.tx_power);
@@ -1474,7 +1476,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 	rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
 	return rc;
 }
-#endif
 
 /**
  * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
@@ -2171,6 +2172,7 @@ static struct iwl_lib_ops iwl4965_lib = {
 	.load_ucode = iwl4965_load_bsm,
 	.dump_nic_event_log = iwl_dump_nic_event_log,
 	.dump_nic_error_log = iwl_dump_nic_error_log,
+	.set_channel_switch = iwl4965_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a6e347b..d256fec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1382,6 +1382,36 @@ IWL5000_UCODE_GET(init_size);
 IWL5000_UCODE_GET(init_data_size);
 IWL5000_UCODE_GET(boot_size);
 
+static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
+{
+	struct iwl5000_channel_switch_cmd cmd;
+	const struct iwl_channel_info *ch_info;
+	struct iwl_host_cmd hcmd = {
+		.id = REPLY_CHANNEL_SWITCH,
+		.len = sizeof(cmd),
+		.flags = CMD_SIZE_HUGE,
+		.data = &cmd,
+	};
+
+	IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
+		priv->active_rxon.channel, channel);
+	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
+	cmd.channel = cpu_to_le16(channel);
+	cmd.rxon_flags = priv->active_rxon.flags;
+	cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
+	cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
+	ch_info = iwl_get_channel_info(priv, priv->band, channel);
+	if (ch_info)
+		cmd.expect_beacon = is_channel_radar(ch_info);
+	else {
+		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
+			priv->active_rxon.channel, channel);
+		return -EFAULT;
+	}
+
+	return iwl_send_cmd_sync(priv, &hcmd);
+}
+
 struct iwl_hcmd_ops iwl5000_hcmd = {
 	.rxon_assoc = iwl5000_send_rxon_assoc,
 	.commit_rxon = iwl_commit_rxon,
@@ -1429,6 +1459,7 @@ struct iwl_lib_ops iwl5000_lib = {
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
+	.set_channel_switch = iwl5000_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
@@ -1480,6 +1511,7 @@ static struct iwl_lib_ops iwl5150_lib = {
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
+	.set_channel_switch = iwl5000_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index f585529..f5639b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -172,6 +172,37 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 	return 0;
 }
 
+static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
+{
+	struct iwl6000_channel_switch_cmd cmd;
+	const struct iwl_channel_info *ch_info;
+	struct iwl_host_cmd hcmd = {
+		.id = REPLY_CHANNEL_SWITCH,
+		.len = sizeof(cmd),
+		.flags = CMD_SIZE_HUGE,
+		.data = &cmd,
+	};
+
+	IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
+		priv->active_rxon.channel, channel);
+
+	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
+	cmd.channel = cpu_to_le16(channel);
+	cmd.rxon_flags = priv->active_rxon.flags;
+	cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
+	cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
+	ch_info = iwl_get_channel_info(priv, priv->band, channel);
+	if (ch_info)
+		cmd.expect_beacon = is_channel_radar(ch_info);
+	else {
+		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
+			priv->active_rxon.channel, channel);
+		return -EFAULT;
+	}
+
+	return iwl_send_cmd_sync(priv, &hcmd);
+}
+
 static struct iwl_lib_ops iwl6000_lib = {
 	.set_hw_params = iwl6000_hw_set_hw_params,
 	.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -192,6 +223,7 @@ static struct iwl_lib_ops iwl6000_lib = {
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
+	.set_channel_switch = iwl6000_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
 		.stop = iwl_apm_stop,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e43469c..d2b56ba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1284,10 +1284,15 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
 	struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
 	struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
-	IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n",
-		      le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
-	rxon->channel = csa->channel;
-	priv->staging_rxon.channel = csa->channel;
+
+	if (!le32_to_cpu(csa->status)) {
+		rxon->channel = csa->channel;
+		priv->staging_rxon.channel = csa->channel;
+		IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
+		      le16_to_cpu(csa->channel));
+	} else
+		IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+		      le16_to_cpu(csa->channel));
 }
 EXPORT_SYMBOL(iwl_rx_csa);
 
@@ -2714,6 +2719,14 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
 			goto set_ch_out;
 		}
 
+		if (iwl_is_associated(priv) &&
+		    (le16_to_cpu(priv->active_rxon.channel) != ch) &&
+		    priv->cfg->ops->lib->set_channel_switch) {
+			ret = priv->cfg->ops->lib->set_channel_switch(priv,
+				ch);
+			goto out;
+		}
+
 		spin_lock_irqsave(&priv->lock, flags);
 
 		/* Configure HT40 channels */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 02bacc4..b875dcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -169,6 +169,7 @@ struct iwl_lib_ops {
 	int (*load_ucode)(struct iwl_priv *priv);
 	void (*dump_nic_event_log)(struct iwl_priv *priv);
 	void (*dump_nic_error_log)(struct iwl_priv *priv);
+	int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
 	/* power management */
 	struct iwl_apm_ops apm_ops;
 
-- 
1.5.6.3


^ permalink raw reply related


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