Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: ieee80211_tx_status: headroom too small
From: Johannes Berg @ 2009-10-31  9:25 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: Nikolai ZHUBR, linux-wireless
In-Reply-To: <200910310959.43260.IvDoorn@gmail.com>

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

On Sat, 2009-10-31 at 09:59 +0100, Ivo van Doorn wrote:
> On Saturday 31 October 2009, Johannes Berg wrote:
> > On Sat, 2009-10-31 at 09:51 +0100, Ivo van Doorn wrote:
> > 
> > > > Ok. I looked at the problem and it's a very odd problem -- mac80211
> > > > should always reserve enough headroom in buffers it passes to the
> > > > driver. Does rt61pci somehow realloc frames?
> > > 
> > > It does use skb_push. but will/should always stay within the limits
> > > of rt2x00dev->hw->extra_tx_headroom. Although I just realize there
> > > might be a situation where it needs to align the frame to a 4-byte boundary,
> > > it could exceed that amount. :(
> > 
> > extra_tx_headroom is set to max_t(driver, mac80211) so that there's
> > always some headroom. This doesn't take into account alignment though.
> > Should we simply add 2 to that value?
> 
> 4 actually, wasn't there some cases where the header could have an odd
> number of bytes and would require 3 bytes for alignment?

Hm, is there? I thought they changed the 11s draft to no longer have
that.

johannes

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

^ permalink raw reply

* Re: ieee80211_tx_status: headroom too small
From: Ivo van Doorn @ 2009-10-31  8:59 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Nikolai ZHUBR, linux-wireless
In-Reply-To: <1256979370.3555.91.camel@johannes.local>

On Saturday 31 October 2009, Johannes Berg wrote:
> On Sat, 2009-10-31 at 09:51 +0100, Ivo van Doorn wrote:
> 
> > > Ok. I looked at the problem and it's a very odd problem -- mac80211
> > > should always reserve enough headroom in buffers it passes to the
> > > driver. Does rt61pci somehow realloc frames?
> > 
> > It does use skb_push. but will/should always stay within the limits
> > of rt2x00dev->hw->extra_tx_headroom. Although I just realize there
> > might be a situation where it needs to align the frame to a 4-byte boundary,
> > it could exceed that amount. :(
> 
> extra_tx_headroom is set to max_t(driver, mac80211) so that there's
> always some headroom. This doesn't take into account alignment though.
> Should we simply add 2 to that value?

4 actually, wasn't there some cases where the header could have an odd
number of bytes and would require 3 bytes for alignment?

Ivo

^ permalink raw reply

* Re: ieee80211_tx_status: headroom too small
From: Johannes Berg @ 2009-10-31  8:56 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: Nikolai ZHUBR, linux-wireless
In-Reply-To: <200910310951.30016.IvDoorn@gmail.com>

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

On Sat, 2009-10-31 at 09:51 +0100, Ivo van Doorn wrote:

> > Ok. I looked at the problem and it's a very odd problem -- mac80211
> > should always reserve enough headroom in buffers it passes to the
> > driver. Does rt61pci somehow realloc frames?
> 
> It does use skb_push. but will/should always stay within the limits
> of rt2x00dev->hw->extra_tx_headroom. Although I just realize there
> might be a situation where it needs to align the frame to a 4-byte boundary,
> it could exceed that amount. :(

extra_tx_headroom is set to max_t(driver, mac80211) so that there's
always some headroom. This doesn't take into account alignment though.
Should we simply add 2 to that value?

johannes

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

^ permalink raw reply

* Re: ieee80211_tx_status: headroom too small
From: Ivo van Doorn @ 2009-10-31  8:51 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Nikolai ZHUBR, linux-wireless
In-Reply-To: <1256967967.3555.71.camel@johannes.local>

On Saturday 31 October 2009, Johannes Berg wrote:
> On Sat, 2009-10-31 at 00:56 +0300, Nikolai ZHUBR wrote:
> > Friday, October 30, 2009, 11:59:01 PM, Johannes Berg wrote:
> > >>
> > >> ieee80211_tx_status: headroom too small
> > 
> > > What driver are you using?
> > 
> > Ah, sorry, forgot to mention. It is rt61pci (RaLink mini-PCI card)
> 
> Ok. I looked at the problem and it's a very odd problem -- mac80211
> should always reserve enough headroom in buffers it passes to the
> driver. Does rt61pci somehow realloc frames?

It does use skb_push. but will/should always stay within the limits
of rt2x00dev->hw->extra_tx_headroom. Although I just realize there
might be a situation where it needs to align the frame to a 4-byte boundary,
it could exceed that amount. :(

Ivo

^ permalink raw reply

* [PATCH] mac80211: fix scan abort sanity checks
From: Johannes Berg @ 2009-10-31  6:44 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, mcgrof

Since sometimes mac80211 queues up a scan request
to only act on it later, it must be allowed to
(internally) cancel a not-yet-running scan, e.g.
when the interface is taken down. This condition
was missing since we always checked only the
local->scanning variable which isn't yet set in
that situation.

Reported-by: Luis R. Rodriguez <mcgrof@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/scan.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

--- wireless-testing.orig/net/mac80211/scan.c	2009-10-31 07:29:47.000000000 +0100
+++ wireless-testing/net/mac80211/scan.c	2009-10-31 07:31:21.000000000 +0100
@@ -288,10 +288,14 @@ void ieee80211_scan_completed(struct iee
 
 	mutex_lock(&local->scan_mtx);
 
-	if (WARN_ON(!local->scanning)) {
-		mutex_unlock(&local->scan_mtx);
-		return;
-	}
+	/*
+	 * It's ok to abort a not-yet-running scan (that
+	 * we have one at all will be verified by checking
+	 * local->scan_req next), but not to complete it
+	 * successfully.
+	 */
+	if (WARN_ON(!local->scanning && !aborted))
+		aborted = true;
 
 	if (WARN_ON(!local->scan_req)) {
 		mutex_unlock(&local->scan_mtx);



^ permalink raw reply

* [PATCH] cfg80211: fix NULL ptr deref
From: Johannes Berg @ 2009-10-31  6:40 UTC (permalink / raw)
  To: John Linville; +Cc: Parag Warudkar, linux-wireless

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

      cfg80211: sme: deauthenticate on assoc failure

introduced a potential NULL pointer dereference that
some people have been hitting for some reason -- the
params.bssid pointer is not guaranteed to be non-NULL
for what seems to be a race between various ways of
reaching the same thing.

While I'm trying to analyse the problem more let's
first fix the crash. I think the real fix may be to
avoid doing _anything_ if it ended up being NULL, but
right now I'm not sure yet.

I think
http://bugzilla.kernel.org/show_bug.cgi?id=14342
might also be this issue.

Reported-by: Parag Warudkar <parag.lkml@gmail.com>
Tested-by: Parag Warudkar <parag.lkml@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/wireless/sme.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

--- wireless-testing.orig/net/wireless/sme.c	2009-10-31 07:29:47.000000000 +0100
+++ wireless-testing/net/wireless/sme.c	2009-10-31 07:31:29.000000000 +0100
@@ -165,7 +165,7 @@ void cfg80211_conn_work(struct work_stru
 	struct cfg80211_registered_device *rdev =
 		container_of(work, struct cfg80211_registered_device, conn_work);
 	struct wireless_dev *wdev;
-	u8 bssid[ETH_ALEN];
+	u8 bssid_buf[ETH_ALEN], *bssid = NULL;
 
 	rtnl_lock();
 	cfg80211_lock_rdev(rdev);
@@ -181,7 +181,10 @@ void cfg80211_conn_work(struct work_stru
 			wdev_unlock(wdev);
 			continue;
 		}
-		memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN);
+		if (wdev->conn->params.bssid) {
+			memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
+			bssid = bssid_buf;
+		}
 		if (cfg80211_conn_do_work(wdev))
 			__cfg80211_connect_result(
 					wdev->netdev, bssid,



^ permalink raw reply

* Re: OOPS in cfg80211_conn_work
From: Johannes Berg @ 2009-10-31  6:34 UTC (permalink / raw)
  To: Parag Warudkar; +Cc: LKML, linux-wireless
In-Reply-To: <f7848160910301622t2cf43b5bo5ffeda03ec2cdbfe@mail.gmail.com>

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

On Fri, 2009-10-30 at 19:22 -0400, Parag Warudkar wrote:

> Seems to have fixed it.

Thanks Parag. Could you run

iw event -t -f > /tmp/log

[http://linuxwireless.org/en/users/Documentation/iw]

and try to reproduce again? I'm not sure whether or not we get spurious
events with this patch.

johannes

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

^ permalink raw reply

* Re: [PATCH 08/15] iwlwifi: move iwl_[un]init_drv to iwlagn
From: Johannes Berg @ 2009-10-31  5:56 UTC (permalink / raw)
  To: Reinette Chatre; +Cc: linville, linux-wireless, ipw3945-devel
In-Reply-To: <1256938578-9638-9-git-send-email-reinette.chatre@intel.com>

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

On Fri, 2009-10-30 at 14:36 -0700, Reinette Chatre wrote:
> From: Reinette Chatre <reinette.chatre@intel.com>
> 
> Since iwlagn is the only user of these functions, move it to this module.
> This results in a bit more code moving than just these functions since the
> functions only used by them are also moved and we need to export the
> symbols previously available to them directly.

The last bit (export previously available symbols) doesn't seem to make
sense -- if they weren't exported before then surely 3945 doesn't use
them so they could be moved as well? Unless maybe they're used by other
functions that _are_ used by 3945?

johannes

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

^ permalink raw reply

* Re: [PATCH 14/15] iwlwifi: add SM PS support for 6x50 series
From: Johannes Berg @ 2009-10-31  5:53 UTC (permalink / raw)
  To: Reinette Chatre; +Cc: linville, linux-wireless, ipw3945-devel, Wey-Yi Guy
In-Reply-To: <1256938578-9638-15-git-send-email-reinette.chatre@intel.com>

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

Hi,

> @@ -3012,6 +3012,10 @@ static int iwl_init_drv(struct iwl_priv *priv)
>  	priv->band = IEEE80211_BAND_2GHZ;
>  
>  	priv->iw_mode = NL80211_IFTYPE_STATION;
> +	if (priv->cfg->support_sm_ps)
> +		priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DYNAMIC;
> +	else
> +		priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;

Why bother with current_ht_config.sm_ps when ...

>  	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
> -	ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
> -			     (WLAN_HT_CAP_SM_PS_DISABLED << 2));
> +	if (priv->cfg->support_sm_ps)
> +		ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
> +				     (WLAN_HT_CAP_SM_PS_DYNAMIC << 2));
> +	else
> +		ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
> +				     (WLAN_HT_CAP_SM_PS_DISABLED << 2));

here we always and unconditionally advertise dynamic SM-PS mode?
 
> +	if (priv->cfg->support_sm_ps) {
> +		/* # Rx chains when idling and maybe trying to save power */
> +		switch (priv->current_ht_config.sm_ps) {
> +		case WLAN_HT_CAP_SM_PS_STATIC:
> +		case WLAN_HT_CAP_SM_PS_DYNAMIC:
> +			idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
> +				IWL_NUM_IDLE_CHAINS_SINGLE;
> +			break;
> +		case WLAN_HT_CAP_SM_PS_DISABLED:
> +			idle_cnt = (is_cam) ? active_cnt :
> +				IWL_NUM_IDLE_CHAINS_SINGLE;
> +			break;
> +		case WLAN_HT_CAP_SM_PS_INVALID:
> +		default:
> +			IWL_ERR(priv, "invalid sm_ps mode %d\n",
> +				priv->current_ht_config.sm_ps);
> +			WARN_ON(1);
> +			break;
> +		}
> +	}

This _should_ always hit the dynamic case since we've always advertised
that, were it not for a bug below. And even when powersave is turned off
the AP will have to do CTS/RTS handshake so we do not gain anything by
turning on all chains in that case.

I think the whole ht_config.sm_ps should be removed, and here we should
always and unconditionally use _SINGLE as that matches what we've
advertised to the AP via the HT capabilities.

>  /* up to 4 chains */
> @@ -2258,6 +2280,12 @@ static void iwl_ht_conf(struct iwl_priv *priv,
>  					>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
>  			maxstreams += 1;
>  
> +			ht_conf->sm_ps =
> +				(u8)((ht_cap->cap & IEEE80211_HT_CAP_SM_PS)
> +				>> 2);
> +			IWL_DEBUG_MAC80211(priv, "sm_ps: 0x%x\n",
> +				ht_conf->sm_ps);
> +

This is wrong; we cannot use the peer's SM_PS setting for our own SM_PS
setting, we've advertised dynamic SM PS so we better stick with it. The
peer's setting has no value for us, it means whether the peer will turn
off _its_ chains or not.

johannes

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

^ permalink raw reply

* Re: Re[2]: ieee80211_tx_status: headroom too small
From: Johannes Berg @ 2009-10-31  5:46 UTC (permalink / raw)
  To: Nikolai ZHUBR; +Cc: linux-wireless, Ivo Van Doorn
In-Reply-To: <7111590175.20091031005644@mail.ru>

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

On Sat, 2009-10-31 at 00:56 +0300, Nikolai ZHUBR wrote:
> Friday, October 30, 2009, 11:59:01 PM, Johannes Berg wrote:
> >>
> >> ieee80211_tx_status: headroom too small
> 
> > What driver are you using?
> 
> Ah, sorry, forgot to mention. It is rt61pci (RaLink mini-PCI card)

Ok. I looked at the problem and it's a very odd problem -- mac80211
should always reserve enough headroom in buffers it passes to the
driver. Does rt61pci somehow realloc frames?

johannes

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

^ permalink raw reply

* Re: [PATCH 2/2] nl80211: allow to authenticate to access point that we already authenticated
From: Johannes Berg @ 2009-10-31  5:44 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: linux-wireless, hostap@lists.shmoo.com
In-Reply-To: <1256939694.31271.16.camel@maxim-laptop>

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

On Fri, 2009-10-30 at 23:54 +0200, Maxim Levitsky wrote:
> >From 02be2525b95ec3c57323dda1a9e0c6da3a9817e6 Mon Sep 17 00:00:00 2001
> From: Maxim Levitsky <maximlevitsky@gmail.com>
> Date: Fri, 30 Oct 2009 23:50:27 +0200
> Subject: [PATCH 2/2] nl80211: allow to authenticate to access point that we already authenticated
> 
> This is permitted by standards, and used by driver_nl80211 of wpa_supplicant
> Just start new authentication as if we weren't authenticated before

NACK. This leaks the auth request here and in mac80211, so we cannot do
it this simply. Again though, the case you're running into should be
fixed by that wpa_supplicant patch.

johannes

> ---
>  net/wireless/mlme.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
> index 83c2a28..3d91b4e 100644
> --- a/net/wireless/mlme.c
> +++ b/net/wireless/mlme.c
> @@ -372,7 +372,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
>  		if (wdev->auth_bsses[i] &&
>  		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
>  						ETH_ALEN) == 0)
> -			return -EALREADY;
> +			wdev->auth_bsses[i] = NULL;
>  	}
>  
>  	memset(&req, 0, sizeof(req));


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

^ permalink raw reply

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

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

On Fri, 2009-10-30 at 23:52 +0200, Maxim Levitsky wrote:
> >From 1d13f997f652c7e632d4ddb053df3f3fad78da23 Mon Sep 17 00:00:00 2001
> From: Maxim Levitsky <maximlevitsky@gmail.com>
> Date: Fri, 30 Oct 2009 23:36:20 +0200
> Subject: [PATCH 1/2] Allow scanning while in authenticated only state
> 
> Since ifmgd->work_list is {ab}used as a storage for authenticated,
> but not associated access points (this is done using idle work items),
> allow scanning if all work items are in this state.
> 
> Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>

I don't think this is needed. While not _strictly_ wrong, I still
dislike the additional complexity.

I think you just need this wpa_supplicant patch:
http://johannes.sipsolutions.net/patches/hostap/all/2009-10-26-12%3a59/deauth-on-disassoc.patch

johannes

> ---
>  net/mac80211/scan.c |   12 +++++++++---
>  1 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> index c46ac01..c932765 100644
> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -418,6 +418,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
>  {
>  	struct ieee80211_local *local = sdata->local;
>  	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
> +	struct ieee80211_mgd_work *wk, *tmp;
>  	int rc;
>  
>  	if (local->scan_req)
> @@ -450,9 +451,14 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
>  	if (req != local->int_scan_req &&
>  	    sdata->vif.type == NL80211_IFTYPE_STATION &&
>  	    !list_empty(&ifmgd->work_list)) {
> -		/* actually wait for the work it's doing to finish/time out */
> -		set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
> -		return 0;
> +
> +		/* actually wait for the work it's doing to finish/time out*/
> +		list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
> +			if (wk->state != IEEE80211_MGD_STATE_IDLE) {
> +				set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
> +				return 0;
> +			}
> +		}
>  	}
>  
>  	if (local->ops->hw_scan)


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

^ permalink raw reply

* Re: [RFC] ath9k: fix listening to idle requests
From: Vasanthakumar Thiagarajan @ 2009-10-31  5:29 UTC (permalink / raw)
  To: Luis Rodriguez
  Cc: Vasanth Thiagarajan, linux-wireless@vger.kernel.org,
	ath9k-devel@lists.ath9k.org, Luis Rodriguez
In-Reply-To: <43e72e890910300738i29a81f54p57fd0c6fdccbcaf5@mail.gmail.com>

On Fri, Oct 30, 2009 at 08:08:22PM +0530, Luis Rodriguez wrote:
> On Thu, Oct 29, 2009 at 11:33 PM, Vasanthakumar Thiagarajan
> <vasanth@atheros.com> wrote:
> > On Fri, Oct 30, 2009 at 02:22:26AM +0530, Luis Rodriguez wrote:
> >> 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.
> >>
> >> Reported-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
> >> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
> >> ---
> >>
> >> Vasanth, what do you think?
> >
> > Still we will have issue when bringing up a sec wiphy while the
> > primary wiphy is in idle state. ath9k_start() does not brought up
> > the newly created wiphy interface when the state of at least one
> > previously created interface is in ACTIVE state. Unless already
> > brought up interfaces are put down we hit this situation whenever
> > we try to bring up a new secondary wiphy interface. So with this
> > patch the actual h/w will remain radio disabled state even after
> > a new interface is in active state. We need to bring the h/w into
> > active state if all old interfaces are in idle state in
> > ath9k_start().
> 
> I don't see what prevents a secondary virtual wiphy from getting the
> radio started -- perhaps I'm missing something. When a virtual wiphy
> needs to become non-idle that'll come from the mac80211 non-idle
> config call and that will find that one device is non-idle and hence
> start it.

mac80211 will issue config() for non-idle only when the respective
wiphy is already put into idle state.

Vasanth

^ permalink raw reply

* Incorrect signal levels reported using wpa_supplicant's driver_nl80211
From: Maxim Levitsky @ 2009-10-31  1:50 UTC (permalink / raw)
  To: hostap@lists.shmoo.com; +Cc: linux-wireless, networkmanager-list

Sorry for cross-posting, but this issue really spans all three systems.

I anylized why I get 100% quality on all access points except currently
connected, when I used driver_nl80211 of wpa_supplcant.

First, when NetworkManager plans to switch to this driver?
For me it gives me faster association speeds, especially when I toggle
wireless with rfkill button.


this is what happens on the kernel side:
--> n80211 encodes only dBm data. It does so in, nl80211_send_bss.
	(or it can encode unspecified data, which has little use...)

--> kernel also gives maximum ranges in, cfg80211_wext_giwrange, which is used by NM:
	range->max_qual.updated = IW_QUAL_NOISE_INVALID | IW_QUAL_DBM | IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED ;
	range->max_qual.level = -110;
	range->max_qual.qual = 70;
Thus it reports that it can't report noise.


driver_nl80211 side:

--> sends data as is, done in bss_info_handler:
	r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
	r->level /= 100; /* mBm to dBm */
	r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;

Again explicitly says that has no quality data, sends only dBm or unspecified data;



NM side:

--> three strategies used (in wireless_qual_to_percent)
	--> quality: (used with driver_wext), not reported by nl80211

	--> dbm: used only if:
		* valid and zero max_qual->level (but now set to -110....) 
		* valid level (OK)
		* valid positive max_qual->noise OR valid positive current noise (noise set to invalid and not reported even by my driver...)

	--> RSSI: (device reports numbers from 0 to max_qual.level):
		* nonzero valid max_qual->level, and it is assumed to be positive too...
		* valid level
		

currently RSSI path is taken and results in 100% quality.


I think that dBm strategy should be revised, and in addtion to that.

Of course whole NM currently depends on WEXT, for exmple it would get signal level for current AP via WEXT, and thus use quality level
as reported by driver. 

Thus there are differences between NM dBm quality calculation and driver ones, and therefore NM will report different quality levels... sigh...


Best regards,
	Maxim Levitsky


PS: I want signal quality bars back in NM....


^ permalink raw reply

* Re: [PATCH] libertas if_usb: Fix crash on 64-bit machines
From: Alan Stern @ 2009-10-31  1:41 UTC (permalink / raw)
  To: David Woodhouse
  Cc: Christian Lamparter, Larry Finger, linville, libertas-dev,
	linux-wireless, dcbw, davem
In-Reply-To: <1256928681.4030.112.camel@macbook.infradead.org>

On Fri, 30 Oct 2009, David Woodhouse wrote:

> On Fri, 2009-10-30 at 19:44 +0100, Christian Lamparter wrote:
> > 
> > that's just a fill-in macro.
> > AFAICT usb_submit_urb does the tricky dma mapping.
> 
> Ah, that makes sense. In that case, all we need to do is make
> map_urb_for_dma() do the right thing.

map_urb_for_dma() does little more than call dma_map_single().  That's 
what you'll have to fix.

Alan Stern


^ permalink raw reply

* Re: OOPS in cfg80211_conn_work
From: Parag Warudkar @ 2009-10-30 23:22 UTC (permalink / raw)
  To: Johannes Berg; +Cc: LKML, linux-wireless
In-Reply-To: <1256903425.3555.47.camel@johannes.local>

On Friday, October 30, 2009, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Fri, 2009-10-30 at 06:57 -0400, Parag Warudkar wrote:
>>
>> On Fri, 30 Oct 2009, Johannes Berg wrote:
>>
>> > On Thu, 2009-10-29 at 19:17 -0400, Parag Warudkar wrote:
>> > > Oct 29 18:59:06 parag-laptop kernel: [  143.180037] wlan0:
>> > > deauthenticating from 00:16:01:d6:6f:12 by local choice (reason=3)
>> > > Oct 29 18:59:06 parag-laptop kernel: [  143.181137] wlan0: direct
>> > > probe to AP 00:16:01:d6:6f:12 (try 1)
>> >
>> > sorry, I can't read this log. please provide a non-wrapped version
>> >
>> How does this look? (Sorry sent it in a rush earlier.)
>> Below also is a disassembly of cfg80211_conn_work.
>
> Thanks. I was going to ask for disassembly but you preempted me, I like
> that :)
>
> Since you say you can easily reproduce this, can you try the patch
> below?
>
> johannes
>
> ---
>  net/wireless/sme.c |    7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> --- wireless-testing.orig/net/wireless/sme.c    2009-10-30 12:48:09.000000000 +0100
> +++ wireless-testing/net/wireless/sme.c 2009-10-30 12:48:41.000000000 +0100
> @@ -165,7 +165,7 @@ void cfg80211_conn_work(struct work_stru
>         struct cfg80211_registered_device *rdev =
>                 container_of(work, struct cfg80211_registered_device, conn_work);
>         struct wireless_dev *wdev;
> -       u8 bssid[ETH_ALEN];
> +       u8 bssid_buf[ETH_ALEN], *bssid = NULL;
>
>         rtnl_lock();
>         cfg80211_lock_rdev(rdev);
> @@ -181,7 +181,10 @@ void cfg80211_conn_work(struct work_stru
>                         wdev_unlock(wdev);
>                         continue;
>                 }
> -               memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN);
> +               if (wdev->conn->params.bssid) {
> +                       memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
> +                       bssid = bssid_buf;
> +               }
>                 if (cfg80211_conn_do_work(wdev))
>                         __cfg80211_connect_result(
>                                         wdev->netdev, bssid,
>
>
Seems to have fixed it.

Thanks Johannes.

^ permalink raw reply

* Re: [PATH 0/2] Make driver_nl80211 really work
From: Maxim Levitsky @ 2009-10-30 22:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: hostap@lists.shmoo.com
In-Reply-To: <1256939391.31271.11.camel@maxim-laptop>

On Fri, 2009-10-30 at 23:49 +0200, Maxim Levitsky wrote: 
> Hi,
> 
> I seem to find proper fixes for problem with driver_nl80211.
> Despite workaround in wpa_supplicant that sends deauth when auth command
> fails, this driver still doesn't work.
> 
> Problem is that scanning is not allowed in authenticated but not
> associated state. I was told that this is feature, but afterwards I
> understood that it is legal for wpa_supplicant not to use deauthenticate
> command.
> 
> In the other hand mac80211 holds a work list of things todo that include
> pings, associations, authentications, etc...
> 
> Following the code it seems that this list is set to hold forever
> entries that belong to associated but not authenticated access points.
> For example ieee80211_mgd_deauth will fail if this condition isn't true.
> 
> So I modified __ieee80211_start_scan to work even if work list isn't
> empty but all entries are idle.
> 
> As for second problem, the lack of ability to do authentication to
> access point twice, I modified nl80211 by 'roughly' removing the check
> for this condition, treating new request as if ap was never
> authenticated. This seems to work very well.
> 
> 
> Best regards,
> Maxim Levitsky
> 


However, even with these patches, I found test case when it doesn't
work.
If I connect to different APs, then driver_nl80211 doesn't send deauth
at all.

On the other hand, nl80211/cfg80211 keeps track of all auth bsses, in
list that has 4 entries. As soon as this list is full, its not possible
to connect to a different AP.

Mess isn't it?

Best regards,
Maxim Levitsky


^ permalink raw reply

* [PATCH 2/2] nl80211: allow to authenticate to access point that we already authenticated
From: Maxim Levitsky @ 2009-10-30 21:54 UTC (permalink / raw)
  To: linux-wireless; +Cc: hostap@lists.shmoo.com
In-Reply-To: <1256939391.31271.11.camel@maxim-laptop>

>From 02be2525b95ec3c57323dda1a9e0c6da3a9817e6 Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Fri, 30 Oct 2009 23:50:27 +0200
Subject: [PATCH 2/2] nl80211: allow to authenticate to access point that we already authenticated

This is permitted by standards, and used by driver_nl80211 of wpa_supplicant
Just start new authentication as if we weren't authenticated before
---
 net/wireless/mlme.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 83c2a28..3d91b4e 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -372,7 +372,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 		if (wdev->auth_bsses[i] &&
 		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
 						ETH_ALEN) == 0)
-			return -EALREADY;
+			wdev->auth_bsses[i] = NULL;
 	}
 
 	memset(&req, 0, sizeof(req));
-- 
1.6.3.3



^ permalink raw reply related

* [PATCH 1/2] Allow scanning while in authenticated only state
From: Maxim Levitsky @ 2009-10-30 21:52 UTC (permalink / raw)
  To: linux-wireless; +Cc: hostap@lists.shmoo.com
In-Reply-To: <1256939391.31271.11.camel@maxim-laptop>

>From 1d13f997f652c7e632d4ddb053df3f3fad78da23 Mon Sep 17 00:00:00 2001
From: Maxim Levitsky <maximlevitsky@gmail.com>
Date: Fri, 30 Oct 2009 23:36:20 +0200
Subject: [PATCH 1/2] Allow scanning while in authenticated only state

Since ifmgd->work_list is {ab}used as a storage for authenticated,
but not associated access points (this is done using idle work items),
allow scanning if all work items are in this state.

Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
---
 net/mac80211/scan.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c46ac01..c932765 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -418,6 +418,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_mgd_work *wk, *tmp;
 	int rc;
 
 	if (local->scan_req)
@@ -450,9 +451,14 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	if (req != local->int_scan_req &&
 	    sdata->vif.type == NL80211_IFTYPE_STATION &&
 	    !list_empty(&ifmgd->work_list)) {
-		/* actually wait for the work it's doing to finish/time out */
-		set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
-		return 0;
+
+		/* actually wait for the work it's doing to finish/time out*/
+		list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
+			if (wk->state != IEEE80211_MGD_STATE_IDLE) {
+				set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
+				return 0;
+			}
+		}
 	}
 
 	if (local->ops->hw_scan)
-- 
1.6.3.3



^ permalink raw reply related

* [PATH 0/2] Make driver_nl80211 really work
From: Maxim Levitsky @ 2009-10-30 21:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: hostap@lists.shmoo.com

Hi,

I seem to find proper fixes for problem with driver_nl80211.
Despite workaround in wpa_supplicant that sends deauth when auth command
fails, this driver still doesn't work.

Problem is that scanning is not allowed in authenticated but not
associated state. I was told that this is feature, but afterwards I
understood that it is legal for wpa_supplicant not to use deauthenticate
command.

In the other hand mac80211 holds a work list of things todo that include
pings, associations, authentications, etc...

Following the code it seems that this list is set to hold forever
entries that belong to associated but not authenticated access points.
For example ieee80211_mgd_deauth will fail if this condition isn't true.

So I modified __ieee80211_start_scan to work even if work list isn't
empty but all entries are idle.

As for second problem, the lack of ability to do authentication to
access point twice, I modified nl80211 by 'roughly' removing the check
for this condition, treating new request as if ap was never
authenticated. This seems to work very well.


Best regards,
Maxim Levitsky


^ permalink raw reply

* Re[2]: ieee80211_tx_status: headroom too small
From: Nikolai ZHUBR @ 2009-10-30 21:56 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1256936341.3555.67.camel@johannes.local>

Friday, October 30, 2009, 11:59:01 PM, Johannes Berg wrote:
>>
>> ieee80211_tx_status: headroom too small

> What driver are you using?

Ah, sorry, forgot to mention. It is rt61pci (RaLink mini-PCI card)

Nikolai ZHUBR

> johannes



^ permalink raw reply

* [PATCH 12/15] iwlwifi: print warning when sending host command fails
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

From: Reinette Chatre <reinette.chatre@intel.com>

More information than the "-EIO" return code will be useful here.

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-tx.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1868093..b1a2de8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -980,7 +980,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	       !(cmd->flags & CMD_SIZE_HUGE));
 
 	if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
-		IWL_DEBUG_INFO(priv, "Not sending command - RF/CT KILL\n");
+		IWL_WARN(priv, "Not sending command - %s KILL\n",
+			 iwl_is_rfkill(priv) ? "RF" : "CT");
 		return -EIO;
 	}
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 15/15] iwlwifi: add wimax/wifi coexist support for 6x50 series
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

For 6x50 series, it is wimax/wifi combo device, so driver need to enable
the wimax/wifi co-exist function and send the coexist event priority
table to uCode for operation.

The priority table will be used by uCode to determine what is the proper
action it should take when co-exist with WiMAX.
For example, when WiFi runs a scan, it must own radio exclusively, therefore
will disconnect WiMAX if WiMAX is connected.

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     |   12 +---
 drivers/net/wireless/iwlwifi/iwl-6000.c     |    3 +
 drivers/net/wireless/iwlwifi/iwl-commands.h |   92 +++++++++++++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.c     |   59 +++++++++++++++++
 drivers/net/wireless/iwlwifi/iwl-core.h     |    3 +
 5 files changed, 158 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index b8ddd70..a97d93d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -592,16 +592,6 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
 		       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
 
-static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
-{
-	struct iwl_wimax_coex_cmd coex_cmd;
-
-	memset(&coex_cmd, 0, sizeof(coex_cmd));
-
-	return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
-				sizeof(coex_cmd), &coex_cmd);
-}
-
 int iwl5000_alive_notify(struct iwl_priv *priv)
 {
 	u32 a;
@@ -682,7 +672,7 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 
-	iwl5000_send_wimax_coex(priv);
+	iwl_send_wimax_coex(priv);
 
 	iwl5000_set_Xtal_calib(priv);
 	iwl_send_calib_results(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a4a8b5e..70e117f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -491,6 +491,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
 	.support_sm_ps = true,
+	.support_wimax_coexist = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -520,6 +521,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.support_wimax_coexist = true,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -581,6 +583,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
 	.support_sm_ps = true,
+	.support_wimax_coexist = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 43dd6af..b62c90e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3507,6 +3507,98 @@ struct iwl_led_cmd {
  * also used as potential "events" value for both
  * COEX_MEDIUM_NOTIFICATION and COEX_EVENT_CMD
  */
+
+/*
+ * COEX events entry flag masks
+ * RP - Requested Priority
+ * WP - Win Medium Priority: priority assigned when the contention has been won
+ */
+#define COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG        (0x1)
+#define COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG        (0x2)
+#define COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG  (0x4)
+
+#define COEX_CU_UNASSOC_IDLE_RP               4
+#define COEX_CU_UNASSOC_MANUAL_SCAN_RP        4
+#define COEX_CU_UNASSOC_AUTO_SCAN_RP          4
+#define COEX_CU_CALIBRATION_RP                4
+#define COEX_CU_PERIODIC_CALIBRATION_RP       4
+#define COEX_CU_CONNECTION_ESTAB_RP           4
+#define COEX_CU_ASSOCIATED_IDLE_RP            4
+#define COEX_CU_ASSOC_MANUAL_SCAN_RP          4
+#define COEX_CU_ASSOC_AUTO_SCAN_RP            4
+#define COEX_CU_ASSOC_ACTIVE_LEVEL_RP         4
+#define COEX_CU_RF_ON_RP                      6
+#define COEX_CU_RF_OFF_RP                     4
+#define COEX_CU_STAND_ALONE_DEBUG_RP          6
+#define COEX_CU_IPAN_ASSOC_LEVEL_RP           4
+#define COEX_CU_RSRVD1_RP                     4
+#define COEX_CU_RSRVD2_RP                     4
+
+#define COEX_CU_UNASSOC_IDLE_WP               3
+#define COEX_CU_UNASSOC_MANUAL_SCAN_WP        3
+#define COEX_CU_UNASSOC_AUTO_SCAN_WP          3
+#define COEX_CU_CALIBRATION_WP                3
+#define COEX_CU_PERIODIC_CALIBRATION_WP       3
+#define COEX_CU_CONNECTION_ESTAB_WP           3
+#define COEX_CU_ASSOCIATED_IDLE_WP            3
+#define COEX_CU_ASSOC_MANUAL_SCAN_WP          3
+#define COEX_CU_ASSOC_AUTO_SCAN_WP            3
+#define COEX_CU_ASSOC_ACTIVE_LEVEL_WP         3
+#define COEX_CU_RF_ON_WP                      3
+#define COEX_CU_RF_OFF_WP                     3
+#define COEX_CU_STAND_ALONE_DEBUG_WP          6
+#define COEX_CU_IPAN_ASSOC_LEVEL_WP           3
+#define COEX_CU_RSRVD1_WP                     3
+#define COEX_CU_RSRVD2_WP                     3
+
+#define COEX_UNASSOC_IDLE_FLAGS                     0
+#define COEX_UNASSOC_MANUAL_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_UNASSOC_AUTO_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_CALIBRATION_FLAGS			\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_PERIODIC_CALIBRATION_FLAGS             0
+/*
+ * COEX_CONNECTION_ESTAB:
+ * we need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network.
+ */
+#define COEX_CONNECTION_ESTAB_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+#define COEX_ASSOCIATED_IDLE_FLAGS                  0
+#define COEX_ASSOC_MANUAL_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_ASSOC_AUTO_SCAN_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_ASSOC_ACTIVE_LEVEL_FLAGS               0
+#define COEX_RF_ON_FLAGS                            0
+#define COEX_RF_OFF_FLAGS                           0
+#define COEX_STAND_ALONE_DEBUG_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG)
+#define COEX_IPAN_ASSOC_LEVEL_FLAGS		\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+#define COEX_RSRVD1_FLAGS                           0
+#define COEX_RSRVD2_FLAGS                           0
+/*
+ * COEX_CU_RF_ON is the event wrapping all radio ownership.
+ * We need DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network.
+ */
+#define COEX_CU_RF_ON_FLAGS			\
+	(COEX_EVT_FLAG_MEDIUM_FREE_NTFY_FLG |	\
+	 COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_FLG |	\
+	 COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_FLG)
+
+
 enum {
 	/* un-association part */
 	COEX_UNASSOC_IDLE		= 0,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 6a9d593..112181b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -47,6 +47,37 @@ MODULE_VERSION(IWLWIFI_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
 MODULE_LICENSE("GPL");
 
+static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
+	{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
+	 0, COEX_UNASSOC_IDLE_FLAGS},
+	{COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
+	 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+	{COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
+	 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+	{COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
+	 0, COEX_CALIBRATION_FLAGS},
+	{COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
+	 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+	{COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
+	 0, COEX_CONNECTION_ESTAB_FLAGS},
+	{COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
+	 0, COEX_ASSOCIATED_IDLE_FLAGS},
+	{COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
+	 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+	{COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
+	 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+	{COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
+	 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+	{COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
+	{COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
+	{COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
+	 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+	{COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
+	 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+	{COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
+	{COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
+};
+
 #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
 	[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
 				    IWL_RATE_SISO_##s##M_PLCP, \
@@ -2866,6 +2897,34 @@ void iwl_free_txq_mem(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_free_txq_mem);
 
+int iwl_send_wimax_coex(struct iwl_priv *priv)
+{
+	struct iwl_wimax_coex_cmd uninitialized_var(coex_cmd);
+
+	if (priv->cfg->support_wimax_coexist) {
+		/* UnMask wake up src at associated sleep */
+		coex_cmd.flags |= COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
+
+		/* UnMask wake up src at unassociated sleep */
+		coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
+		memcpy(coex_cmd.sta_prio, cu_priorities,
+			sizeof(struct iwl_wimax_coex_event_entry) *
+			 COEX_NUM_OF_EVENTS);
+
+		/* enabling the coexistence feature */
+		coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
+
+		/* enabling the priorities tables */
+		coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
+	} else {
+		/* coexistence is disabled */
+		memset(&coex_cmd, 0, sizeof(coex_cmd));
+	}
+	return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
+				sizeof(coex_cmd), &coex_cmd);
+}
+EXPORT_SYMBOL(iwl_send_wimax_coex);
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 
 #define IWL_TRAFFIC_DUMP_SIZE	(IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index d2e47da..9574d8f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -229,6 +229,7 @@ struct iwl_mod_params {
  * @adv_thermal_throttle: support advance thermal throttle
  * @support_ct_kill_exit: support ct kill exit condition
  * @support_sm_ps: support spatial multiplexing power save
+ * @support_wimax_coexist: support wimax/wifi co-exist
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -285,6 +286,7 @@ struct iwl_cfg {
 	bool adv_thermal_throttle;
 	bool support_ct_kill_exit;
 	bool support_sm_ps;
+	const bool support_wimax_coexist;
 };
 
 /***************************
@@ -340,6 +342,7 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv);
 void iwl_free_txq_mem(struct iwl_priv *priv);
 void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 				__le32 *tx_flags);
+int iwl_send_wimax_coex(struct iwl_priv *priv);
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_alloc_traffic_mem(struct iwl_priv *priv);
 void iwl_free_traffic_mem(struct iwl_priv *priv);
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 14/15] iwlwifi: add SM PS support for 6x50 series
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

Spatial Multiplexing Power Save was disabled to achieve better
throughput while in power save mode by activating all the rx chains all the time.
By doing so, the device power consumption is high.

Enable static/dynamic spatial multiplexing power save if device support
it, which can lower the power consumption without impact throughput.

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 |    2 +
 drivers/net/wireless/iwlwifi/iwl-agn.c  |    4 ++
 drivers/net/wireless/iwlwifi/iwl-core.c |   48 ++++++++++++++++++++++++------
 drivers/net/wireless/iwlwifi/iwl-core.h |    2 +
 drivers/net/wireless/iwlwifi/iwl-dev.h  |    1 +
 drivers/net/wireless/iwlwifi/iwl-sta.c  |    5 +++
 6 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 2f841a8..a4a8b5e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -490,6 +490,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.support_sm_ps = true,
 };
 
 struct iwl_cfg iwl6050_2abg_cfg = {
@@ -579,6 +580,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.supports_idle = true,
 	.adv_thermal_throttle = true,
 	.support_ct_kill_exit = true,
+	.support_sm_ps = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e99b753..2bbd04d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3012,6 +3012,10 @@ static int iwl_init_drv(struct iwl_priv *priv)
 	priv->band = IEEE80211_BAND_2GHZ;
 
 	priv->iw_mode = NL80211_IFTYPE_STATION;
+	if (priv->cfg->support_sm_ps)
+		priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DYNAMIC;
+	else
+		priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
 
 	/* Choose which receivers/antennas to use */
 	if (priv->cfg->ops->hcmd->set_rxon_chain)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 96eb476..6a9d593 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -415,8 +415,12 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
 	if (priv->cfg->ht_greenfield_support)
 		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
 	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
-	ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
-			     (WLAN_HT_CAP_SM_PS_DISABLED << 2));
+	if (priv->cfg->support_sm_ps)
+		ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
+				     (WLAN_HT_CAP_SM_PS_DYNAMIC << 2));
+	else
+		ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
+				     (WLAN_HT_CAP_SM_PS_DISABLED << 2));
 
 	max_bit_rate = MAX_BIT_RATE_20_MHZ;
 	if (priv->hw_params.ht40_channel & BIT(band)) {
@@ -964,17 +968,35 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
 }
 
 /*
- * When we are in power saving, there's no difference between
- * using multiple chains or just a single chain, but due to the
- * lack of SM PS we lose a lot of throughput if we use just a
- * single chain.
- *
- * Therefore, use the active count here (which will use multiple
- * chains unless connected to a legacy AP).
+ * When we are in power saving mode, unless device support spatial
+ * multiplexing power save, use the active count for rx chain count.
  */
 static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
 {
-	return active_cnt;
+	int idle_cnt = active_cnt;
+	bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+
+	if (priv->cfg->support_sm_ps) {
+		/* # Rx chains when idling and maybe trying to save power */
+		switch (priv->current_ht_config.sm_ps) {
+		case WLAN_HT_CAP_SM_PS_STATIC:
+		case WLAN_HT_CAP_SM_PS_DYNAMIC:
+			idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
+				IWL_NUM_IDLE_CHAINS_SINGLE;
+			break;
+		case WLAN_HT_CAP_SM_PS_DISABLED:
+			idle_cnt = (is_cam) ? active_cnt :
+				IWL_NUM_IDLE_CHAINS_SINGLE;
+			break;
+		case WLAN_HT_CAP_SM_PS_INVALID:
+		default:
+			IWL_ERR(priv, "invalid sm_ps mode %d\n",
+				priv->current_ht_config.sm_ps);
+			WARN_ON(1);
+			break;
+		}
+	}
+	return idle_cnt;
 }
 
 /* up to 4 chains */
@@ -2258,6 +2280,12 @@ static void iwl_ht_conf(struct iwl_priv *priv,
 					>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
 			maxstreams += 1;
 
+			ht_conf->sm_ps =
+				(u8)((ht_cap->cap & IEEE80211_HT_CAP_SM_PS)
+				>> 2);
+			IWL_DEBUG_MAC80211(priv, "sm_ps: 0x%x\n",
+				ht_conf->sm_ps);
+
 			if ((ht_cap->mcs.rx_mask[1] == 0) &&
 			    (ht_cap->mcs.rx_mask[2] == 0))
 				ht_conf->single_chain_sufficient = true;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ddf0998..d2e47da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -228,6 +228,7 @@ struct iwl_mod_params {
  * @chain_noise_num_beacons: number of beacons used to compute chain noise
  * @adv_thermal_throttle: support advance thermal throttle
  * @support_ct_kill_exit: support ct kill exit condition
+ * @support_sm_ps: support spatial multiplexing power save
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -283,6 +284,7 @@ struct iwl_cfg {
 	const bool supports_idle;
 	bool adv_thermal_throttle;
 	bool support_ct_kill_exit;
+	bool support_sm_ps;
 };
 
 /***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index e7ce673..cb2642c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -517,6 +517,7 @@ struct iwl_ht_config {
 	bool is_ht;
 	bool is_40mhz;
 	bool single_chain_sufficient;
+	u8 sm_ps;
 	/* BSS related data */
 	u8 extension_chan_offset;
 	u8 ht_protection;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index ce1ceac..74cc8db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -182,6 +182,11 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
 		goto done;
 
 	mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
+	IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
+			(mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
+			"static" :
+			(mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
+			"dynamic" : "disabled");
 
 	sta_flags = priv->stations[index].sta.station_flags;
 
-- 
1.5.6.3


^ permalink raw reply related

* [PATCH 13/15] iwlwifi: coex API data structure
From: Reinette Chatre @ 2009-10-30 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1256938578-9638-1-git-send-email-reinette.chatre@intel.com>

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

Add data structure define for COEX_MEDIUM_NOTIFICATION and
COEX_EVENT_CMD host commands.

COEX_MEDIUM_NOTIFICATION is notification from uCode to host to indicate
medium changes. COEX_EVENT_CMD is from host to uCode for coex event
request.

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 |   69 +++++++++++++++++++++++++-
 drivers/net/wireless/iwlwifi/iwl-hcmd.c     |    2 +
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 954bad6..43dd6af 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3503,30 +3503,42 @@ struct iwl_led_cmd {
 } __attribute__ ((packed));
 
 /*
- * Coexistence WIFI/WIMAX  Command
- * COEX_PRIORITY_TABLE_CMD = 0x5a
- *
+ * station priority table entries
+ * also used as potential "events" value for both
+ * COEX_MEDIUM_NOTIFICATION and COEX_EVENT_CMD
  */
 enum {
+	/* un-association part */
 	COEX_UNASSOC_IDLE		= 0,
 	COEX_UNASSOC_MANUAL_SCAN	= 1,
 	COEX_UNASSOC_AUTO_SCAN		= 2,
+	/* calibration */
 	COEX_CALIBRATION		= 3,
 	COEX_PERIODIC_CALIBRATION	= 4,
+	/* connection */
 	COEX_CONNECTION_ESTAB		= 5,
+	/* association part */
 	COEX_ASSOCIATED_IDLE		= 6,
 	COEX_ASSOC_MANUAL_SCAN		= 7,
 	COEX_ASSOC_AUTO_SCAN		= 8,
 	COEX_ASSOC_ACTIVE_LEVEL		= 9,
+	/* RF ON/OFF */
 	COEX_RF_ON			= 10,
 	COEX_RF_OFF			= 11,
 	COEX_STAND_ALONE_DEBUG		= 12,
+	/* IPAN */
 	COEX_IPAN_ASSOC_LEVEL		= 13,
+	/* reserved */
 	COEX_RSRVD1			= 14,
 	COEX_RSRVD2			= 15,
 	COEX_NUM_OF_EVENTS		= 16
 };
 
+/*
+ * Coexistence WIFI/WIMAX  Command
+ * COEX_PRIORITY_TABLE_CMD = 0x5a
+ *
+ */
 struct iwl_wimax_coex_event_entry {
 	u8 request_prio;
 	u8 win_medium_prio;
@@ -3551,6 +3563,55 @@ struct iwl_wimax_coex_cmd {
 	struct iwl_wimax_coex_event_entry sta_prio[COEX_NUM_OF_EVENTS];
 } __attribute__ ((packed));
 
+/*
+ * Coexistence MEDIUM NOTIFICATION
+ * COEX_MEDIUM_NOTIFICATION = 0x5b
+ *
+ * notification from uCode to host to indicate medium changes
+ *
+ */
+/*
+ * status field
+ * bit 0 - 2: medium status
+ * bit 3: medium change indication
+ * bit 4 - 31: reserved
+ */
+/* status option values, (0 - 2 bits) */
+#define COEX_MEDIUM_BUSY	(0x0) /* radio belongs to WiMAX */
+#define COEX_MEDIUM_ACTIVE	(0x1) /* radio belongs to WiFi */
+#define COEX_MEDIUM_PRE_RELEASE	(0x2) /* received radio release */
+#define COEX_MEDIUM_MSK		(0x7)
+
+/* send notification status (1 bit) */
+#define COEX_MEDIUM_CHANGED	(0x8)
+#define COEX_MEDIUM_CHANGED_MSK	(0x8)
+#define COEX_MEDIUM_SHIFT	(3)
+
+struct iwl_coex_medium_notification {
+	__le32 status;
+	__le32 events;
+} __attribute__ ((packed));
+
+/*
+ * Coexistence EVENT  Command
+ * COEX_EVENT_CMD = 0x5c
+ *
+ * send from host to uCode for coex event request.
+ */
+/* flags options */
+#define COEX_EVENT_REQUEST_MSK	(0x1)
+
+struct iwl_coex_event_cmd {
+	u8 flags;
+	u8 event;
+	__le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl_coex_event_resp {
+	__le32 status;
+} __attribute__ ((packed));
+
+
 /******************************************************************************
  * (13)
  * Union of all expected notifications/responses:
@@ -3587,6 +3648,8 @@ struct iwl_rx_packet {
 		struct iwl_notif_statistics stats;
 		struct iwl_compressed_ba_resp compressed_ba;
 		struct iwl_missed_beacon_notif missed_beacon;
+		struct iwl_coex_medium_notification coex_medium_notif;
+		struct iwl_coex_event_resp coex_event;
 		__le32 status;
 		u8 raw[0];
 	} u;
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index d7ebc5f..ccf50a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -56,6 +56,8 @@ const char *get_cmd_string(u8 cmd)
 		IWL_CMD(REPLY_LEDS_CMD);
 		IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
 		IWL_CMD(COEX_PRIORITY_TABLE_CMD);
+		IWL_CMD(COEX_MEDIUM_NOTIFICATION);
+		IWL_CMD(COEX_EVENT_CMD);
 		IWL_CMD(RADAR_NOTIFICATION);
 		IWL_CMD(REPLY_QUIET_CMD);
 		IWL_CMD(REPLY_CHANNEL_SWITCH);
-- 
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