Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH 5/7] rt2x00: Move PCI/USB specific register initializations to rt2800{pci,usb}.
From: Ivo van Doorn @ 2010-05-19 18:26 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-6-git-send-email-gwingerde@gmail.com>

On Wednesday 19 May 2010 17:26:07 Gertjan van Wingerde wrote:
> This prevents us having common code depend on PCI or USB specific code.
> 
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
> ---

To which tree are you creating your diffs?
This one doesn't apply to latest wireless-testing.git or rt2x00,git

Ivo

^ permalink raw reply

* Re: [PATCH] cfg80211: make action channel type optional
From: Pavel Roskin @ 2010-05-19 18:19 UTC (permalink / raw)
  To: Johannes Berg; +Cc: John Linville, Jouni Malinen, linux-wireless
In-Reply-To: <1274264232.3874.7.camel@jlt3.sipsolutions.net>

On Wed, 2010-05-19 at 12:17 +0200, Johannes Berg wrote:

> @@ -1168,6 +1168,7 @@ struct cfg80211_ops {
>  	int	(*action)(struct wiphy *wiphy, struct net_device *dev,
>  			  struct ieee80211_channel *chan,
>  			  enum nl80211_channel_type channel_type,
> +			  bool channel_type_valid,
>  			  const u8 *buf, size_t len, u64 *cookie);

Would not it be easier to introduce NL80211_CHAN_UNSPECIFIED in enum
nl80211_channel_type?

-- 
Regards,
Pavel Roskin

^ permalink raw reply

* Re: [PATCH 7/7] rt2x00: Fix HT40 operation in rt2800.
From: Ivo Van Doorn @ 2010-05-19 18:14 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-8-git-send-email-gwingerde@gmail.com>

> +u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> +                           struct ieee80211_conf *conf)
> +{
> +       struct hw_mode_spec *spec = &rt2x00dev->spec;
> +       int center_channel;
> +       u16 i;
> +
> +       /*
> +        * Initialize center channel to current channel.
> +        */
> +       center_channel = spec->channels[conf->channel->hw_value].channel;
> +
> +       /*
> +        * Adjust center channel to HT40+ and HT40- operation.
> +        */
> +       if (conf_is_ht40_plus(conf))
> +               center_channel += 2;
> +       else if (conf_is_ht40_minus(conf))
> +               center_channel -= (center_channel == 14) ? 1 : 2;
> +
> +       for (i = 0; i < spec->num_channels; i++)
> +               if (spec->channels[i].channel == center_channel)
> +                       return i;
> +
> +       BUG();
> +}

This isn't worth a BUG(), perhaps a debug message or WARN(),
I would say a debug message and retuning the hw_value.

Ivo

^ permalink raw reply

* Re: [PATCH 6/7] rt2x00: Sync rt2800 MCU boot signal with Ralink driver.
From: Ivo Van Doorn @ 2010-05-19 18:12 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-7-git-send-email-gwingerde@gmail.com>

On Wed, May 19, 2010 at 5:26 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> Latest versions of the Ralink rt2800 family drivers use 0 as the token value,
> not 0xff.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

^ permalink raw reply

* Re: [PATCH 5/7] rt2x00: Move PCI/USB specific register initializations to rt2800{pci,usb}.
From: Ivo Van Doorn @ 2010-05-19 18:12 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-6-git-send-email-gwingerde@gmail.com>

On Wed, May 19, 2010 at 5:26 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> This prevents us having common code depend on PCI or USB specific code.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

^ permalink raw reply

* Re: [PATCH 4/7] rt2x00: Simplify check for external LNA in rt2800_init_rfcsr.
From: Ivo Van Doorn @ 2010-05-19 18:11 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-5-git-send-email-gwingerde@gmail.com>

On Wed, May 19, 2010 at 5:26 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> Instead of parsing the EEPROM information, use the flag that was set during
> device initialization.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

^ permalink raw reply

* Re: [PATCH 3/7] rt2x00: Introduce separate interface type for PCI-express.
From: Ivo Van Doorn @ 2010-05-19 18:10 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-4-git-send-email-gwingerde@gmail.com>

On Wed, May 19, 2010 at 5:26 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> Needed later for PCI-express specific code in rt2800pci.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

^ permalink raw reply

* Re: [PATCH 2/7] rt2x00: Move all register definitions for rt2800 to rt2800.h.
From: Ivo Van Doorn @ 2010-05-19 18:10 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-3-git-send-email-gwingerde@gmail.com>

On Wed, May 19, 2010 at 5:26 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> There is no point on having them separated across 3 files.
> At the same time rename USB_CYC_CFG to its proper name US_CYC_CNT
> (as per the datasheet).
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

^ permalink raw reply

* Re: [PATCH 1/7] rt2x00: Remove RT2870 chipset identification.
From: Ivo Van Doorn @ 2010-05-19 18:09 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Helmut Schaa, linux-wireless, users
In-Reply-To: <1274282769-19244-2-git-send-email-gwingerde@gmail.com>

On Wed, May 19, 2010 at 5:26 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> There is no evidence, either in adapters or in the Ralink code, that such
> a device actually exists. All so-call RT2870 adapter identify themselves
> as RT2860.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>

Acked-by: Ivo van Doorn <IvDoorn@gmail.com>

^ permalink raw reply

* WLAN Regulatory Domain Germany
From: Kurt Garloff @ 2010-05-19 17:29 UTC (permalink / raw)
  To: linux-wireless

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

Hi,

studying the three documents

WLAN 5GHz (Vfg. 7/2010)
http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf

WLAN 2.4GHz (Vfg. 89/2003)
http://www.bundesnetzagentur.de/cae/servlet/contentblob/38214/publicationFile/2557/FundstelleId313pdf.pdf

Frequenznutzungsplan
http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf

I think the data in db.txt is slightly inaccurate.

Find below my suggested entry into db.txt.
Suggested changes:
* Updated references (they restructured their webserver/CMS it seems)
* Split 5150 -- 5350 range into two
  - the first range does not require DFS
* 5470 -- 5725 does not have a NO-OUTDOOR requirement
  - (and 500mW translates to 27db, not 26db AFAICT)

Sidenote: The values include lowering txpower by a factor of 2 (3db)
 for non TPC devices -- the wording in Vfg. 7/2010 does NOT require
 this for 5150 -- 5250; so we could actually use 200mW/23db there. As 
 this is out of line with the neighbour countries, I have sticked with
 the conservative value of 100mW here.

What is the process for checking the correctness and getting the crda DB 
updated?

8<------------------------------------------------------------------------

# Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from 
# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf
# For the 5GHz range also see 
# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf
# The values have been reduced by a factor of 2 (3db) for non TPC devcies
# (in other words: devices with TPC can use twice the tx power of this table).

country DE:
	# entries 279004 and 280006
	(2400 - 2483.5 @ 40), (N/A, 100 mW)
	# entry 303005
	(5150 - 5250 @ 40), (N/A, 100 mW), NO-OUTDOOR
	# entries 304002 and 305002
	(5250 - 5350 @ 40), (N/A, 100 mW), NO-OUTDOOR, DFS
	# entries 308002, 309001 and 310003
	(5470 - 5725 @ 40), (N/A, 500 mW), DFS

8<------------------------------------------------------------------------

(Or in db, as displayed by iw reg get)
country DE:
        (2400 - 2483 @ 40), (N/A, 20)
	(5150 - 5250 @ 40), (N/A, 20), NO-OUTDOOR
        (5250 - 5350 @ 40), (N/A, 20), NO-OUTDOOR, DFS
        (5470 - 5725 @ 40), (N/A, 27), DFS

PS: I'm not subscribed, please copy responses to me.

Best,
-- 
Kurt Garloff                   <kurt@garloff.de>        [Private, Koeln]
Linux: VP OPS PartnerEng       <garloff@suse.de>            [Novell Inc]

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH v2 13/20] cfg80211: Add nl80211 antenna configuration
From: Luis R. Rodriguez @ 2010-05-19 17:07 UTC (permalink / raw)
  To: Bruno Randolf; +Cc: linville, ath5k-devel, linux-wireless
In-Reply-To: <20100519013147.22206.71360.stgit@tt-desk>

On Tue, May 18, 2010 at 6:31 PM, Bruno Randolf <br1@einfach.org> wrote:

> + * @NL80211_ATTR_ANTENNA_TX: Bitmap of antennas to use for transmitting.
> + * @NL80211_ATTR_ANTENNA_RX: Bitmap of antennas to use for receiving.

This gets the job done, but that's it. The API defined allows for a
hugely loose implementation on each driver. Users could end up using
for ath5k:

iw dev wlan0 set_tx_antenna 1 # for AR5K_ANTMODE_FIXED_A
iw dev wlan0 set_tx_antenna 2 # for AR5K_ANTMODE_FIXED_B
iw dev wlan0 set_tx_antenna 3 # for AR5K_ANTMODE_DEFAULT

And yet for another driver it could be something completely different
in usersepace. I think it would be better for us to define a static
API for all legacy cards and another for 802.11n cards, or unify them
but to be very specific about the API for antenna settings/chainmask
settings.

  Luis

^ permalink raw reply

* Re: [PATCH] cfg80211: Add a missing null pointer check
From: Felix Fietkau @ 2010-05-19 15:56 UTC (permalink / raw)
  To: Jussi Haakana
  Cc: John Linville, Johannes Berg, linux-wireless@vger.kernel.org
In-Reply-To: <0290AB2F0A8E124B9FFC144088A1A95609D6AA414B@EX-MBS04.nbl.local>

On 2010-05-19 12:27 PM, Jussi Haakana wrote:
> If a network interface is down while setting a channel,
> missing null pointer check causes an oops in cfg80211_set_freq:
> 
> # iw phy phy0 interface add ath1 type monitor
> # iw dev ath1 set channel 3
> Unable to handle kernel paging request for data at address 0x00000004
> Faulting instruction address: 0xca16d778
> Oops: Kernel access of bad area, sig: 11 [#1]
> ...
> 
> Signed-off-by: Jussi Haakana <Jussi.Haakana@7signal.com>
That's exactly what I sent 4 days ago ;)

- Felix

^ permalink raw reply

* Re: [PATCH 7/7] rt2x00: Fix HT40 operation in rt2800.
From: Helmut Schaa @ 2010-05-19 15:51 UTC (permalink / raw)
  To: Gertjan van Wingerde
  Cc: John W. Linville, Ivo van Doorn, linux-wireless, users
In-Reply-To: <1274282769-19244-8-git-send-email-gwingerde@gmail.com>

Am Mittwoch 19 Mai 2010 schrieb Gertjan van Wingerde:
> Closer inspection of the legacy Ralink driver reveals that in case of HT40+
> or HT40- we must adjust the frequency settings that we program to the device.
> Implement the same adjustment in the rt2x00 code.
> 
> With this HT40 seems to work for all devices supported by rt2800pci and
> rt2800usb.

Awesome, I'll give it a shot tomorrow.

Helmut

> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
> ---
>  drivers/net/wireless/rt2x00/rt2800lib.c    |    5 +----
>  drivers/net/wireless/rt2x00/rt2x00config.c |   12 ++++++++----
>  drivers/net/wireless/rt2x00/rt2x00ht.c     |   27 +++++++++++++++++++++++++++
>  drivers/net/wireless/rt2x00/rt2x00lib.h    |    9 +++++++++
>  4 files changed, 45 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 8ffbc3c..15322f0 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -2530,11 +2530,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>  	else
>  		spec->ht.ht_supported = false;
>  
> -	/*
> -	 * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes
> -	 * reception problems with HT40 capable 11n APs
> -	 */
>  	spec->ht.cap =
> +	    IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
>  	    IEEE80211_HT_CAP_GRN_FLD |
>  	    IEEE80211_HT_CAP_SGI_20 |
>  	    IEEE80211_HT_CAP_SGI_40 |
> diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
> index 098315a..8dbd634 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00config.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00config.c
> @@ -170,23 +170,27 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
>  		      unsigned int ieee80211_flags)
>  {
>  	struct rt2x00lib_conf libconf;
> +	u16 hw_value;
>  
>  	memset(&libconf, 0, sizeof(libconf));
>  
>  	libconf.conf = conf;
>  
>  	if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
> -		if (conf_is_ht40(conf))
> +		if (conf_is_ht40(conf)) {
>  			__set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
> -		else
> +			hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
> +		} else {
>  			__clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
> +			hw_value = conf->channel->hw_value;
> +		}
>  
>  		memcpy(&libconf.rf,
> -		       &rt2x00dev->spec.channels[conf->channel->hw_value],
> +		       &rt2x00dev->spec.channels[hw_value],
>  		       sizeof(libconf.rf));
>  
>  		memcpy(&libconf.channel,
> -		       &rt2x00dev->spec.channels_info[conf->channel->hw_value],
> +		       &rt2x00dev->spec.channels_info[hw_value],
>  		       sizeof(libconf.channel));
>  	}
>  
> diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
> index 5a40760..588c766 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00ht.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
> @@ -84,3 +84,30 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
>  	else
>  		txdesc->txop = TXOP_HTTXOP;
>  }
> +
> +u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> +			    struct ieee80211_conf *conf)
> +{
> +	struct hw_mode_spec *spec = &rt2x00dev->spec;
> +	int center_channel;
> +	u16 i;
> +
> +	/*
> +	 * Initialize center channel to current channel.
> +	 */
> +	center_channel = spec->channels[conf->channel->hw_value].channel;
> +
> +	/*
> +	 * Adjust center channel to HT40+ and HT40- operation.
> +	 */
> +	if (conf_is_ht40_plus(conf))
> +		center_channel += 2;
> +	else if (conf_is_ht40_minus(conf))
> +		center_channel -= (center_channel == 14) ? 1 : 2;
> +
> +	for (i = 0; i < spec->num_channels; i++)
> +		if (spec->channels[i].channel == center_channel)
> +			return i;
> +
> +	BUG();
> +}
> diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
> index 822affc..ed27de1 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00lib.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
> @@ -367,12 +367,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
>  void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
>  				   struct txentry_desc *txdesc,
>  				   const struct rt2x00_rate *hwrate);
> +
> +u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> +			    struct ieee80211_conf *conf);
>  #else
>  static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
>  						 struct txentry_desc *txdesc,
>  						 const struct rt2x00_rate *hwrate)
>  {
>  }
> +
> +static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> +					  struct ieee80211_conf *conf)
> +{
> +	return conf->channel->hw_value;
> +}
>  #endif /* CONFIG_RT2X00_LIB_HT */
>  
>  /*
> 


^ permalink raw reply

* Re: [PATCH 10/17] wireless: update gfp/slab.h includes
From: Stephen Rothwell @ 2010-05-19 15:50 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-next, linux-kernel, Tejun Heo, linux-wireless
In-Reply-To: <1269885165-18617-11-git-send-email-tj@kernel.org>

Hi John,

On Tue, 30 Mar 2010 02:52:38 +0900 Tejun Heo <tj@kernel.org> wrote:
>
> Implicit slab.h inclusion via percpu.h is about to go away.  Make sure
> gfp.h or slab.h is included as necessary.

Please apply to the wireless tree (patch reposted below).

From: Tejun Heo <tj@kernel.org>
To: sfr@canb.auug.org.au, linux-next@vger.kernel.org,
        linux-kernel@vger.kernel.org
Cc: Tejun Heo <tj@kernel.org>, "John W. Linville" <linville@tuxdriver.com>
Subject: [PATCH 10/17] wireless: update gfp/slab.h includes
Date: Tue, 30 Mar 2010 02:52:38 +0900

Implicit slab.h inclusion via percpu.h is about to go away.  Make sure
gfp.h or slab.h is included as necessary.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: John W. Linville <linville@tuxdriver.com>
---
 drivers/net/wireless/ath/ath9k/htc.h       |    1 +
 drivers/net/wireless/iwlwifi/iwl-agn-ict.c |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 7770649..4497479 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -23,6 +23,7 @@
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/leds.h>
+#include <linux/slab.h>
 #include <net/mac80211.h>
 
 #include "common.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
index 4c5395e..0cc7fd9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
+#include <linux/gfp.h>
 #include <net/mac80211.h>
 
 #include "iwl-dev.h"
-- 
1.6.4.2

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply related

* [PATCH 5/7] rt2x00: Move PCI/USB specific register initializations to rt2800{pci,usb}.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde
In-Reply-To: <1274282769-19244-1-git-send-email-gwingerde@gmail.com>

This prevents us having common code depend on PCI or USB specific code.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   61 ++-----------------------------
 drivers/net/wireless/rt2x00/rt2800lib.h |    9 +++++
 drivers/net/wireless/rt2x00/rt2800pci.c |   34 +++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800usb.c |   40 ++++++++++++++++++++
 4 files changed, 87 insertions(+), 57 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index d46d1b8..8ffbc3c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -37,12 +37,8 @@
 #include <linux/module.h>
 
 #include "rt2x00.h"
-#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
-#include "rt2x00usb.h"
-#endif
 #include "rt2800lib.h"
 #include "rt2800.h"
-#include "rt2800usb.h"
 
 MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
 MODULE_DESCRIPTION("rt2800 library");
@@ -1271,6 +1267,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	u32 reg;
 	u16 eeprom;
 	unsigned int i;
+	int ret;
 
 	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
@@ -1280,59 +1277,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
 	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
 
-	if (rt2x00_is_usb(rt2x00dev)) {
-		/*
-		 * Wait until BBP and RF are ready.
-		 */
-		for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-			rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
-			if (reg && reg != ~0)
-				break;
-			msleep(1);
-		}
-
-		if (i == REGISTER_BUSY_COUNT) {
-			ERROR(rt2x00dev, "Unstable hardware.\n");
-			return -EBUSY;
-		}
-
-		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
-		rt2800_register_write(rt2x00dev, PBF_SYS_CTRL,
-				      reg & ~0x00002000);
-	} else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) {
-		/*
-		 * Reset DMA indexes
-		 */
-		rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
-		rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
-		rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
-		rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
-		rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
-		rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
-		rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
-		rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
-		rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
-
-		rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
-		rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
-
-		rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
-	}
-
-	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
-	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
-	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
-	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
-	if (rt2x00_is_usb(rt2x00dev)) {
-		rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
-#if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE)
-		rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
-					    USB_MODE_RESET, REGISTER_TIMEOUT);
-#endif
-	}
-
-	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+	ret = rt2800_drv_init_registers(rt2x00dev);
+	if (ret)
+		return ret;
 
 	rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
 	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index b16fd6d..8313dbf 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -40,6 +40,8 @@ struct rt2800_ops {
 	int (*regbusy_read)(struct rt2x00_dev *rt2x00dev,
 			    const unsigned int offset,
 			    const struct rt2x00_field32 field, u32 *reg);
+
+	int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
 };
 
 static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
@@ -107,6 +109,13 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev,
 	return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg);
 }
 
+static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->priv;
+
+	return rt2800ops->drv_init_registers(rt2x00dev);
+}
+
 void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
 			const u8 command, const u8 token,
 			const u8 arg0, const u8 arg1);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index f271836..846600f 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -446,6 +446,38 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
 	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
 }
 
+static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+
+	/*
+	 * Reset DMA indexes
+	 */
+	rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
+	rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+
+	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+	return 0;
+}
+
 static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -944,6 +976,8 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
 	.register_multiwrite	= rt2x00pci_register_multiwrite,
 
 	.regbusy_read		= rt2x00pci_regbusy_read,
+
+	.drv_init_registers	= rt2800pci_init_registers,
 };
 
 static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 8a15ffb..6a2ed50 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -243,6 +243,44 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
 	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 }
 
+static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+	int i;
+
+	/*
+	 * Wait until BBP and RF are ready.
+	 */
+	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_register_read(rt2x00dev, MAC_CSR0, &reg);
+		if (reg && reg != ~0)
+			break;
+		msleep(1);
+	}
+
+	if (i == REGISTER_BUSY_COUNT) {
+		ERROR(rt2x00dev, "Unstable hardware.\n");
+		return -EBUSY;
+	}
+
+	rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+
+	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+	rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
+
+	rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+				    USB_MODE_RESET, REGISTER_TIMEOUT);
+
+	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+	return 0;
+}
+
 static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -549,6 +587,8 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = {
 	.register_multiwrite	= rt2x00usb_register_multiwrite,
 
 	.regbusy_read		= rt2x00usb_regbusy_read,
+
+	.drv_init_registers	= rt2800usb_init_registers,
 };
 
 static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
-- 
1.7.1


^ permalink raw reply related

* [PATCH 7/7] rt2x00: Fix HT40 operation in rt2800.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde
In-Reply-To: <1274282769-19244-1-git-send-email-gwingerde@gmail.com>

Closer inspection of the legacy Ralink driver reveals that in case of HT40+
or HT40- we must adjust the frequency settings that we program to the device.
Implement the same adjustment in the rt2x00 code.

With this HT40 seems to work for all devices supported by rt2800pci and
rt2800usb.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800lib.c    |    5 +----
 drivers/net/wireless/rt2x00/rt2x00config.c |   12 ++++++++----
 drivers/net/wireless/rt2x00/rt2x00ht.c     |   27 +++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2x00lib.h    |    9 +++++++++
 4 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 8ffbc3c..15322f0 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2530,11 +2530,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	else
 		spec->ht.ht_supported = false;
 
-	/*
-	 * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes
-	 * reception problems with HT40 capable 11n APs
-	 */
 	spec->ht.cap =
+	    IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
 	    IEEE80211_HT_CAP_GRN_FLD |
 	    IEEE80211_HT_CAP_SGI_20 |
 	    IEEE80211_HT_CAP_SGI_40 |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 098315a..8dbd634 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -170,23 +170,27 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
 		      unsigned int ieee80211_flags)
 {
 	struct rt2x00lib_conf libconf;
+	u16 hw_value;
 
 	memset(&libconf, 0, sizeof(libconf));
 
 	libconf.conf = conf;
 
 	if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
-		if (conf_is_ht40(conf))
+		if (conf_is_ht40(conf)) {
 			__set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
-		else
+			hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
+		} else {
 			__clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+			hw_value = conf->channel->hw_value;
+		}
 
 		memcpy(&libconf.rf,
-		       &rt2x00dev->spec.channels[conf->channel->hw_value],
+		       &rt2x00dev->spec.channels[hw_value],
 		       sizeof(libconf.rf));
 
 		memcpy(&libconf.channel,
-		       &rt2x00dev->spec.channels_info[conf->channel->hw_value],
+		       &rt2x00dev->spec.channels_info[hw_value],
 		       sizeof(libconf.channel));
 	}
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
index 5a40760..588c766 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ht.c
+++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
@@ -84,3 +84,30 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
 	else
 		txdesc->txop = TXOP_HTTXOP;
 }
+
+u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
+			    struct ieee80211_conf *conf)
+{
+	struct hw_mode_spec *spec = &rt2x00dev->spec;
+	int center_channel;
+	u16 i;
+
+	/*
+	 * Initialize center channel to current channel.
+	 */
+	center_channel = spec->channels[conf->channel->hw_value].channel;
+
+	/*
+	 * Adjust center channel to HT40+ and HT40- operation.
+	 */
+	if (conf_is_ht40_plus(conf))
+		center_channel += 2;
+	else if (conf_is_ht40_minus(conf))
+		center_channel -= (center_channel == 14) ? 1 : 2;
+
+	for (i = 0; i < spec->num_channels; i++)
+		if (spec->channels[i].channel == center_channel)
+			return i;
+
+	BUG();
+}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 822affc..ed27de1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -367,12 +367,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
 void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
 				   struct txentry_desc *txdesc,
 				   const struct rt2x00_rate *hwrate);
+
+u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
+			    struct ieee80211_conf *conf);
 #else
 static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
 						 struct txentry_desc *txdesc,
 						 const struct rt2x00_rate *hwrate)
 {
 }
+
+static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
+					  struct ieee80211_conf *conf)
+{
+	return conf->channel->hw_value;
+}
 #endif /* CONFIG_RT2X00_LIB_HT */
 
 /*
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/7] rt2x00: Further cleanups and fixes.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde

The next set up cleanups and fixes for rt2x00. Highlights of the patch
series include:
    - Fixes to the HT40 operation of rt2x00. This works now!!
    - Cleanup of rt2800lib.c. Now no bus details (USB or PCI specifics) are
      part of rt2800lib.c anymore.
    - Further preparations for the inclusion of support for RT3572 devices.

Patches are on top of all the previous patch series I sent out, and are
relative to wireless-next-2.6.

There are no critical bug-fixes in here that need to be merged into 2.6.35.


Gertjan van Wingerde (7):
  rt2x00: Remove RT2870 chipset identification.
  rt2x00: Move all register definitions for rt2800 to rt2800.h.
  rt2x00: Introduce separate interface type for PCI-express.
  rt2x00: Simplify check for external LNA in rt2800_init_rfcsr.
  rt2x00: Move PCI/USB specific register initializations to rt2800{pci,usb}.
  rt2x00: Sync rt2800 MCU boot signal with Ralink driver.
  rt2x00: Fix HT40 operation in rt2800.

 drivers/net/wireless/rt2x00/rt2800.h       |   49 +++++++++++++++++-
 drivers/net/wireless/rt2x00/rt2800lib.c    |   80 ++++------------------------
 drivers/net/wireless/rt2x00/rt2800lib.h    |    9 +++
 drivers/net/wireless/rt2x00/rt2800pci.c    |   36 ++++++++++++-
 drivers/net/wireless/rt2x00/rt2800pci.h    |   19 -------
 drivers/net/wireless/rt2x00/rt2800usb.c    |   42 ++++++++++++++-
 drivers/net/wireless/rt2x00/rt2800usb.h    |   37 -------------
 drivers/net/wireless/rt2x00/rt2x00.h       |   12 +++-
 drivers/net/wireless/rt2x00/rt2x00config.c |   12 +++--
 drivers/net/wireless/rt2x00/rt2x00ht.c     |   27 +++++++++
 drivers/net/wireless/rt2x00/rt2x00lib.h    |    9 +++
 drivers/net/wireless/rt2x00/rt2x00pci.c    |    5 ++-
 12 files changed, 200 insertions(+), 137 deletions(-)


^ permalink raw reply

* [PATCH 6/7] rt2x00: Sync rt2800 MCU boot signal with Ralink driver.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde
In-Reply-To: <1274282769-19244-1-git-send-email-gwingerde@gmail.com>

Latest versions of the Ralink rt2800 family drivers use 0 as the token value,
not 0xff.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |    2 +-
 drivers/net/wireless/rt2x00/rt2800usb.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 846600f..b5a871e 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -497,7 +497,7 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Send signal to firmware during boot time.
 	 */
-	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
+	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
 
 	/*
 	 * Enable RX.
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 6a2ed50..df3d7a6 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -193,7 +193,7 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Send signal to firmware during boot time.
 	 */
-	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
+	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
 
 	if (rt2x00_rt(rt2x00dev, RT3070) ||
 	    rt2x00_rt(rt2x00dev, RT3071) ||
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/7] rt2x00: Move all register definitions for rt2800 to rt2800.h.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde
In-Reply-To: <1274282769-19244-1-git-send-email-gwingerde@gmail.com>

There is no point on having them separated across 3 files.
At the same time rename USB_CYC_CFG to its proper name US_CYC_CNT
(as per the datasheet).

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800.h    |   48 +++++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800lib.c |    6 ++--
 drivers/net/wireless/rt2x00/rt2800pci.h |   19 ------------
 drivers/net/wireless/rt2x00/rt2800usb.h |   37 -----------------------
 4 files changed, 51 insertions(+), 59 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 35afe63..16bfaa8 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -98,6 +98,21 @@
  */
 
 /*
+ * E2PROM_CSR: PCI EEPROM control register.
+ * RELOAD: Write 1 to reload eeprom content.
+ * TYPE: 0: 93c46, 1:93c66.
+ * LOAD_STATUS: 1:loading, 0:done.
+ */
+#define E2PROM_CSR			0x0004
+#define E2PROM_CSR_DATA_CLOCK		FIELD32(0x00000001)
+#define E2PROM_CSR_CHIP_SELECT		FIELD32(0x00000002)
+#define E2PROM_CSR_DATA_IN		FIELD32(0x00000004)
+#define E2PROM_CSR_DATA_OUT		FIELD32(0x00000008)
+#define E2PROM_CSR_TYPE			FIELD32(0x00000030)
+#define E2PROM_CSR_LOAD_STATUS		FIELD32(0x00000040)
+#define E2PROM_CSR_RELOAD		FIELD32(0x00000080)
+
+/*
  * OPT_14: Unknown register used by rt3xxx devices.
  */
 #define OPT_14_CSR			0x0114
@@ -321,6 +336,39 @@
 #define RX_DRX_IDX			0x029c
 
 /*
+ * USB_DMA_CFG
+ * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
+ * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
+ * PHY_CLEAR: phy watch dog enable.
+ * TX_CLEAR: Clear USB DMA TX path.
+ * TXOP_HALT: Halt TXOP count down when TX buffer is full.
+ * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation.
+ * RX_BULK_EN: Enable USB DMA Rx.
+ * TX_BULK_EN: Enable USB DMA Tx.
+ * EP_OUT_VALID: OUT endpoint data valid.
+ * RX_BUSY: USB DMA RX FSM busy.
+ * TX_BUSY: USB DMA TX FSM busy.
+ */
+#define USB_DMA_CFG			0x02a0
+#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT	FIELD32(0x000000ff)
+#define USB_DMA_CFG_RX_BULK_AGG_LIMIT	FIELD32(0x0000ff00)
+#define USB_DMA_CFG_PHY_CLEAR		FIELD32(0x00010000)
+#define USB_DMA_CFG_TX_CLEAR		FIELD32(0x00080000)
+#define USB_DMA_CFG_TXOP_HALT		FIELD32(0x00100000)
+#define USB_DMA_CFG_RX_BULK_AGG_EN	FIELD32(0x00200000)
+#define USB_DMA_CFG_RX_BULK_EN		FIELD32(0x00400000)
+#define USB_DMA_CFG_TX_BULK_EN		FIELD32(0x00800000)
+#define USB_DMA_CFG_EP_OUT_VALID	FIELD32(0x3f000000)
+#define USB_DMA_CFG_RX_BUSY		FIELD32(0x40000000)
+#define USB_DMA_CFG_TX_BUSY		FIELD32(0x80000000)
+
+/*
+ * US_CYC_CNT
+ */
+#define US_CYC_CNT			0x02a4
+#define US_CYC_CNT_CLOCK_CYCLE		FIELD32(0x000000ff)
+
+/*
  * PBF_SYS_CTRL
  * HOST_RAM_WRITE: enable Host program ram write selection
  */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b1dfb57..5183249 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1619,9 +1619,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
 
 	if (rt2x00_is_usb(rt2x00dev)) {
-		rt2800_register_read(rt2x00dev, USB_CYC_CFG, &reg);
-		rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
-		rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg);
+		rt2800_register_read(rt2x00dev, US_CYC_CNT, &reg);
+		rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, 30);
+		rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
 	}
 
 	rt2800_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
index afc8e7d..5a8dda9 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -35,25 +35,6 @@
 #define RT2800PCI_H
 
 /*
- * PCI registers.
- */
-
-/*
- * E2PROM_CSR: EEPROM control register.
- * RELOAD: Write 1 to reload eeprom content.
- * TYPE: 0: 93c46, 1:93c66.
- * LOAD_STATUS: 1:loading, 0:done.
- */
-#define E2PROM_CSR			0x0004
-#define E2PROM_CSR_DATA_CLOCK		FIELD32(0x00000001)
-#define E2PROM_CSR_CHIP_SELECT		FIELD32(0x00000002)
-#define E2PROM_CSR_DATA_IN		FIELD32(0x00000004)
-#define E2PROM_CSR_DATA_OUT		FIELD32(0x00000008)
-#define E2PROM_CSR_TYPE			FIELD32(0x00000030)
-#define E2PROM_CSR_LOAD_STATUS		FIELD32(0x00000040)
-#define E2PROM_CSR_RELOAD		FIELD32(0x00000080)
-
-/*
  * Queue register offset macros
  */
 #define TX_QUEUE_REG_OFFSET		0x10
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 2bca6a7..0722bad 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -32,43 +32,6 @@
 #define RT2800USB_H
 
 /*
- * USB registers.
- */
-
-/*
- * USB_DMA_CFG
- * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
- * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
- * PHY_CLEAR: phy watch dog enable.
- * TX_CLEAR: Clear USB DMA TX path.
- * TXOP_HALT: Halt TXOP count down when TX buffer is full.
- * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation.
- * RX_BULK_EN: Enable USB DMA Rx.
- * TX_BULK_EN: Enable USB DMA Tx.
- * EP_OUT_VALID: OUT endpoint data valid.
- * RX_BUSY: USB DMA RX FSM busy.
- * TX_BUSY: USB DMA TX FSM busy.
- */
-#define USB_DMA_CFG			0x02a0
-#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT	FIELD32(0x000000ff)
-#define USB_DMA_CFG_RX_BULK_AGG_LIMIT	FIELD32(0x0000ff00)
-#define USB_DMA_CFG_PHY_CLEAR		FIELD32(0x00010000)
-#define USB_DMA_CFG_TX_CLEAR		FIELD32(0x00080000)
-#define USB_DMA_CFG_TXOP_HALT		FIELD32(0x00100000)
-#define USB_DMA_CFG_RX_BULK_AGG_EN	FIELD32(0x00200000)
-#define USB_DMA_CFG_RX_BULK_EN		FIELD32(0x00400000)
-#define USB_DMA_CFG_TX_BULK_EN		FIELD32(0x00800000)
-#define USB_DMA_CFG_EP_OUT_VALID	FIELD32(0x3f000000)
-#define USB_DMA_CFG_RX_BUSY		FIELD32(0x40000000)
-#define USB_DMA_CFG_TX_BUSY		FIELD32(0x80000000)
-
-/*
- * USB_CYC_CFG
- */
-#define USB_CYC_CFG			0x02a4
-#define USB_CYC_CFG_CLOCK_CYCLE		FIELD32(0x000000ff)
-
-/*
  * 8051 firmware image.
  */
 #define FIRMWARE_RT2870			"rt2870.bin"
-- 
1.7.1


^ permalink raw reply related

* [PATCH 4/7] rt2x00: Simplify check for external LNA in rt2800_init_rfcsr.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde
In-Reply-To: <1274282769-19244-1-git-send-email-gwingerde@gmail.com>

Instead of parsing the EEPROM information, use the flag that was set during
device initialization.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800lib.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 5183249..d46d1b8 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2071,8 +2071,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 	if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
 	    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
 	    rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
-		if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
 			rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
 	}
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 3/7] rt2x00: Introduce separate interface type for PCI-express.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde
In-Reply-To: <1274282769-19244-1-git-send-email-gwingerde@gmail.com>

Needed later for PCI-express specific code in rt2800pci.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00.h    |    9 ++++++++-
 drivers/net/wireless/rt2x00/rt2x00pci.c |    5 ++++-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 9fc3612..e7acc6a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -160,6 +160,7 @@ struct avg_val {
 
 enum rt2x00_chip_intf {
 	RT2X00_CHIP_INTF_PCI,
+	RT2X00_CHIP_INTF_PCIE,
 	RT2X00_CHIP_INTF_USB,
 	RT2X00_CHIP_INTF_SOC,
 };
@@ -980,7 +981,13 @@ static inline bool rt2x00_intf(struct rt2x00_dev *rt2x00dev,
 
 static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev)
 {
-	return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
+	return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI) ||
+	       rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
+}
+
+static inline bool rt2x00_is_pcie(struct rt2x00_dev *rt2x00dev)
+{
+	return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
 }
 
 static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 19b8683..fe4b00b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -350,7 +350,10 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 	rt2x00dev->irq = pci_dev->irq;
 	rt2x00dev->name = pci_name(pci_dev);
 
-	rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
+	if (pci_dev->is_pcie)
+		rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
+	else
+		rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI);
 
 	retval = rt2x00pci_alloc_reg(rt2x00dev);
 	if (retval)
-- 
1.7.1


^ permalink raw reply related

* [PATCH 1/7] rt2x00: Remove RT2870 chipset identification.
From: Gertjan van Wingerde @ 2010-05-19 15:26 UTC (permalink / raw)
  To: John W. Linville
  Cc: Ivo van Doorn, Helmut Schaa, linux-wireless, users,
	Gertjan van Wingerde
In-Reply-To: <1274282769-19244-1-git-send-email-gwingerde@gmail.com>

There is no evidence, either in adapters or in the Ralink code, that such
a device actually exists. All so-call RT2870 adapter identify themselves
as RT2860.

Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800.h    |    1 -
 drivers/net/wireless/rt2x00/rt2800lib.c |    5 +----
 drivers/net/wireless/rt2x00/rt2x00.h    |    3 +--
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 2aa0375..35afe63 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -63,7 +63,6 @@
  */
 #define REV_RT2860C			0x0100
 #define REV_RT2860D			0x0101
-#define REV_RT2870D			0x0101
 #define REV_RT2872E			0x0200
 #define REV_RT3070E			0x0200
 #define REV_RT3070F			0x0201
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 9ee4ffa..b1dfb57 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1765,8 +1765,7 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
 	rt2800_bbp_write(rt2x00dev, 82, 0x62);
 	rt2800_bbp_write(rt2x00dev, 83, 0x6a);
 
-	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D) ||
-	    rt2x00_rt_rev(rt2x00dev, RT2870, REV_RT2870D))
+	if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
 		rt2800_bbp_write(rt2x00dev, 84, 0x19);
 	else
 		rt2800_bbp_write(rt2x00dev, 84, 0x99);
@@ -2206,7 +2205,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 		rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
 		EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
 	} else if (rt2x00_rt(rt2x00dev, RT2860) ||
-		   rt2x00_rt(rt2x00dev, RT2870) ||
 		   rt2x00_rt(rt2x00dev, RT2872)) {
 		/*
 		 * There is a max of 2 RX streams for RT28x0 series
@@ -2310,7 +2308,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
 			value, rt2x00_get_field32(reg, MAC_CSR0_REVISION));
 
 	if (!rt2x00_rt(rt2x00dev, RT2860) &&
-	    !rt2x00_rt(rt2x00dev, RT2870) &&
 	    !rt2x00_rt(rt2x00dev, RT2872) &&
 	    !rt2x00_rt(rt2x00dev, RT2883) &&
 	    !rt2x00_rt(rt2x00dev, RT3070) &&
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 889a372..9fc3612 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -176,8 +176,7 @@ struct rt2x00_chip {
 #define RT2570		0x2570
 #define RT2661		0x2661
 #define RT2573		0x2573
-#define RT2860		0x2860	/* 2.4GHz PCI/CB */
-#define RT2870		0x2870
+#define RT2860		0x2860	/* 2.4GHz */
 #define RT2872		0x2872	/* WSOC */
 #define RT2883		0x2883	/* WSOC */
 #define RT3070		0x3070
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH v2 00/20] pending ath5k + antenna patches
From: John W. Linville @ 2010-05-19 12:59 UTC (permalink / raw)
  To: Bruno Randolf; +Cc: ath5k-devel, linux-wireless
In-Reply-To: <20100519012528.22206.77550.stgit@tt-desk>

On Wed, May 19, 2010 at 10:30:39AM +0900, Bruno Randolf wrote:

> Also i'd like to note that there are quite a few ath5k patches which haven't
> made it into linux-next yet. It would be great to get them into 2.6.35...

That probably won't happen.  The exception would be for self-contained
bug fixes.  As for linux-next, Stephen usually asks not to merge
anything into linux-next feeder trees during the merge window unless
they are intended to go to the current release.  So, non-bugfix patches
probably won't be going to linux-next either for another week or so.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* [PATCH] cfg80211: Add a missing null pointer check
From: Jussi Haakana @ 2010-05-19 10:27 UTC (permalink / raw)
  To: John Linville; +Cc: Johannes Berg, linux-wireless@vger.kernel.org

If a network interface is down while setting a channel,
missing null pointer check causes an oops in cfg80211_set_freq:

# iw phy phy0 interface add ath1 type monitor
# iw dev ath1 set channel 3
Unable to handle kernel paging request for data at address 0x00000004
Faulting instruction address: 0xca16d778
Oops: Kernel access of bad area, sig: 11 [#1]
...

Signed-off-by: Jussi Haakana <Jussi.Haakana@7signal.com>
---
 net/wireless/chan.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index d92d088..b01a6f6 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -50,7 +50,7 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
        struct ieee80211_channel *chan;
        int result;

-       if (wdev->iftype == NL80211_IFTYPE_MONITOR)
+       if (wdev && wdev->iftype == NL80211_IFTYPE_MONITOR)
                wdev = NULL;

        if (wdev) {
--
1.5.5.6


^ permalink raw reply related

* [PATCH v4] libertas: Added callback functions to support SDIO suspend/resume.
From: Amitkumar Karwar @ 2010-05-19 10:24 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org, libertas-dev@lists.infradead.org
  Cc: Kiran Divekar, Amitkumar Karwar
In-Reply-To: <5FF020A1CFFEEC49BD1E09530C4FF595056D1B6FCD@SC-VEXCH1.marvell.com>

In suspend() host sleep is activated using already configured
host sleep parameters through wol command, and in resume() host
sleep is cancelled. Earlier priv->fw_ready flag used to reset and
set in suspend and resume handler respectively. Since after suspend
only host goes into sleep state and firmware is always ready, those
changes in flag state are removed.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/libertas/cmd.c     |   37 ++++++++++++--
 drivers/net/wireless/libertas/cmdresp.c |   30 ++---------
 drivers/net/wireless/libertas/decl.h    |    2 +-
 drivers/net/wireless/libertas/dev.h     |    6 ++
 drivers/net/wireless/libertas/ethtool.c |   15 +++---
 drivers/net/wireless/libertas/if_sdio.c |   58 ++++++++++++++++++++++
 drivers/net/wireless/libertas/if_usb.c  |    6 ++
 drivers/net/wireless/libertas/main.c    |   79 +++++++++++++++++++++---------
 8 files changed, 171 insertions(+), 62 deletions(-)

diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index cdb9b96..0fa6b0e 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -70,6 +70,8 @@ static u8 is_command_allowed_in_ps(u16 cmd)
 	switch (cmd) {
 	case CMD_802_11_RSSI:
 		return 1;
+	case CMD_802_11_HOST_SLEEP_CFG:
+		return 1;
 	default:
 		break;
 	}
@@ -185,6 +187,23 @@ out:
 	return ret;
 }
 
+static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
+			struct cmd_header *resp)
+{
+	lbs_deb_enter(LBS_DEB_CMD);
+	if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
+		priv->is_host_sleep_configured = 0;
+		if (priv->psstate == PS_STATE_FULL_POWER) {
+			priv->is_host_sleep_activated = 0;
+			wake_up_interruptible(&priv->host_sleep_q);
+		}
+	} else {
+		priv->is_host_sleep_configured = 1;
+	}
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+}
+
 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 		struct wol_config *p_wol_config)
 {
@@ -202,12 +221,11 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 	else
 		cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
 
-	ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
+	ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
+			le16_to_cpu(cmd_config.hdr.size),
+			lbs_ret_host_sleep_cfg, 0);
 	if (!ret) {
-		if (criteria) {
-			lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
-			priv->wol_criteria = criteria;
-		} else
+		if (p_wol_config)
 			memcpy((uint8_t *) p_wol_config,
 					(uint8_t *)&cmd_config.wol_conf,
 					sizeof(struct wol_config));
@@ -712,6 +730,10 @@ static void lbs_queue_cmd(struct lbs_private *priv,
 		}
 	}
 
+	if (le16_to_cpu(cmdnode->cmdbuf->command) ==
+			CMD_802_11_WAKEUP_CONFIRM)
+		addtail = 0;
+
 	spin_lock_irqsave(&priv->driver_lock, flags);
 
 	if (addtail)
@@ -1353,6 +1375,11 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
 	/* We don't get a response on the sleep-confirmation */
 	priv->dnld_sent = DNLD_RES_RECEIVED;
 
+	if (priv->is_host_sleep_configured) {
+		priv->is_host_sleep_activated = 1;
+		wake_up_interruptible(&priv->host_sleep_q);
+	}
+
 	/* If nothing to do, go back to sleep (?) */
 	if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
 		priv->psstate = PS_STATE_SLEEP;
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 88f7131..d6c3063 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -17,6 +17,7 @@
 #include "dev.h"
 #include "assoc.h"
 #include "wext.h"
+#include "cmd.h"
 
 /**
  *  @brief This function handles disconnect event. it
@@ -341,32 +342,10 @@ done:
 	return ret;
 }
 
-static int lbs_send_confirmwake(struct lbs_private *priv)
-{
-	struct cmd_header cmd;
-	int ret = 0;
-
-	lbs_deb_enter(LBS_DEB_HOST);
-
-	cmd.command = cpu_to_le16(CMD_802_11_WAKEUP_CONFIRM);
-	cmd.size = cpu_to_le16(sizeof(cmd));
-	cmd.seqnum = cpu_to_le16(++priv->seqnum);
-	cmd.result = 0;
-
-	lbs_deb_hex(LBS_DEB_HOST, "wake confirm", (u8 *) &cmd,
-		sizeof(cmd));
-
-	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &cmd, sizeof(cmd));
-	if (ret)
-		lbs_pr_alert("SEND_WAKEC_CMD: Host to Card failed for Confirm Wake\n");
-
-	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
-	return ret;
-}
-
 int lbs_process_event(struct lbs_private *priv, u32 event)
 {
 	int ret = 0;
+	struct cmd_header cmd;
 
 	lbs_deb_enter(LBS_DEB_CMD);
 
@@ -410,7 +389,10 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
 		if (priv->reset_deep_sleep_wakeup)
 			priv->reset_deep_sleep_wakeup(priv);
 		priv->is_deep_sleep = 0;
-		lbs_send_confirmwake(priv);
+		lbs_cmd_async(priv, CMD_802_11_WAKEUP_CONFIRM, &cmd,
+				sizeof(cmd));
+		priv->is_host_sleep_activated = 0;
+		wake_up_interruptible(&priv->host_sleep_q);
 		break;
 
 	case MACREG_INT_CODE_DEEP_SLEEP_AWAKE:
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 709ffca..61db8bc 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -38,7 +38,7 @@ int lbs_set_mac_address(struct net_device *dev, void *addr);
 void lbs_set_multicast_list(struct net_device *dev);
 
 int lbs_suspend(struct lbs_private *priv);
-void lbs_resume(struct lbs_private *priv);
+int lbs_resume(struct lbs_private *priv);
 
 void lbs_queue_event(struct lbs_private *priv, u32 event);
 void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index a54880e..71c5ad4 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -75,6 +75,7 @@ struct lbs_private {
 
 	/* Deep sleep */
 	int is_deep_sleep;
+	int deep_sleep_required;
 	int is_auto_deep_sleep_enabled;
 	int wakeup_dev_required;
 	int is_activity_detected;
@@ -82,6 +83,11 @@ struct lbs_private {
 	wait_queue_head_t ds_awake_q;
 	struct timer_list auto_deepsleep_timer;
 
+	/* Host sleep*/
+	int is_host_sleep_configured;
+	int is_host_sleep_activated;
+	wait_queue_head_t host_sleep_q;
+
 	/* Hardware access */
 	void *card;
 	u8 fw_ready;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 3804a58..6a36c99 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -91,23 +91,22 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
 			       struct ethtool_wolinfo *wol)
 {
 	struct lbs_private *priv = dev->ml_priv;
-	uint32_t criteria = 0;
 
 	if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
 		return -EOPNOTSUPP;
 
+	priv->wol_criteria = 0;
 	if (wol->wolopts & WAKE_UCAST)
-		criteria |= EHS_WAKE_ON_UNICAST_DATA;
+		priv->wol_criteria |= EHS_WAKE_ON_UNICAST_DATA;
 	if (wol->wolopts & WAKE_MCAST)
-		criteria |= EHS_WAKE_ON_MULTICAST_DATA;
+		priv->wol_criteria |= EHS_WAKE_ON_MULTICAST_DATA;
 	if (wol->wolopts & WAKE_BCAST)
-		criteria |= EHS_WAKE_ON_BROADCAST_DATA;
+		priv->wol_criteria |= EHS_WAKE_ON_BROADCAST_DATA;
 	if (wol->wolopts & WAKE_PHY)
-		criteria |= EHS_WAKE_ON_MAC_EVENT;
+		priv->wol_criteria |= EHS_WAKE_ON_MAC_EVENT;
 	if (wol->wolopts == 0)
-		criteria |= EHS_REMOVE_WAKEUP;
-
-	return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
+		priv->wol_criteria |= EHS_REMOVE_WAKEUP;
+	return 0;
 }
 
 const struct ethtool_ops lbs_ethtool_ops = {
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 64dd345..6e71346 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -1182,11 +1182,69 @@ static void if_sdio_remove(struct sdio_func *func)
 	lbs_deb_leave(LBS_DEB_SDIO);
 }
 
+static int if_sdio_suspend(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	int ret;
+	struct if_sdio_card *card = sdio_get_drvdata(func);
+
+	mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
+
+	lbs_pr_info("%s: suspend: PM flags = 0x%x\n",
+						sdio_func_id(func), flags);
+
+	/* If we aren't being asked to wake on anything, we should bail out
+	 * and let the SD stack power down the card.
+	 */
+	if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
+		lbs_pr_info("Suspend without wake params -- "
+						"powering down card.");
+		return -ENOSYS;
+	}
+
+	if (!(flags & MMC_PM_KEEP_POWER)) {
+		lbs_pr_err("%s: cannot remain alive while host is suspended\n",
+			sdio_func_id(func));
+		return -ENOSYS;
+	}
+
+	ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+	if (ret)
+		return ret;
+
+	ret = lbs_suspend(card->priv);
+	if (ret)
+		return ret;
+
+	return sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+}
+
+static int if_sdio_resume(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct if_sdio_card *card = sdio_get_drvdata(func);
+	int ret;
+
+	lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func));
+
+	ret = lbs_resume(card->priv);
+
+	return ret;
+}
+
+static const struct dev_pm_ops if_sdio_pm_ops = {
+	.suspend	= if_sdio_suspend,
+	.resume		= if_sdio_resume,
+};
+
 static struct sdio_driver if_sdio_driver = {
 	.name		= "libertas_sdio",
 	.id_table	= if_sdio_ids,
 	.probe		= if_sdio_probe,
 	.remove		= if_sdio_remove,
+	.drv = {
+		.pm = &if_sdio_pm_ops,
+	},
 };
 
 /*******************************************************************/
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index fcea574..e5e6801 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -1047,6 +1047,12 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 	if (priv->psstate != PS_STATE_FULL_POWER)
 		return -1;
 
+	if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
+		lbs_pr_info("Suspend attempt without "
+						"configuring wake params!\n");
+		return -ENOSYS;
+	}
+
 	ret = lbs_suspend(priv);
 	if (ret)
 		goto out;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index d35ebca..25c5734 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -625,16 +625,13 @@ static int lbs_thread(void *data)
 	return 0;
 }
 
-static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy,
-				struct cmd_header *cmd)
+static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
+		unsigned long dummy,
+		struct cmd_header *cmd)
 {
 	lbs_deb_enter(LBS_DEB_FW);
-
-	netif_device_detach(priv->dev);
-	if (priv->mesh_dev)
-		netif_device_detach(priv->mesh_dev);
-
-	priv->fw_ready = 0;
+	priv->is_host_sleep_activated = 1;
+	wake_up_interruptible(&priv->host_sleep_q);
 	lbs_deb_leave(LBS_DEB_FW);
 	return 0;
 }
@@ -646,39 +643,65 @@ int lbs_suspend(struct lbs_private *priv)
 
 	lbs_deb_enter(LBS_DEB_FW);
 
-	if (priv->wol_criteria == 0xffffffff) {
-		lbs_pr_info("Suspend attempt without configuring wake params!\n");
-		return -EINVAL;
+	if (priv->is_deep_sleep) {
+		ret = lbs_set_deep_sleep(priv, 0);
+		if (ret) {
+			lbs_pr_err("deep sleep cancellation failed: %d\n", ret);
+			return ret;
+		}
+		priv->deep_sleep_required = 1;
 	}
 
 	memset(&cmd, 0, sizeof(cmd));
+	ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
+						(struct wol_config *)NULL);
+	if (ret) {
+		lbs_pr_info("Host sleep configuration failed: %d\n", ret);
+		return ret;
+	}
+	if (priv->psstate == PS_STATE_FULL_POWER) {
+		ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
+				sizeof(cmd), lbs_ret_host_sleep_activate, 0);
+		if (ret)
+			lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
+	}
 
-	ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
-			sizeof(cmd), lbs_suspend_callback, 0);
-	if (ret)
-		lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
+	if (!wait_event_interruptible_timeout(priv->host_sleep_q,
+				priv->is_host_sleep_activated, (10 * HZ))) {
+		lbs_pr_err("host_sleep_q: timer expired\n");
+		ret = -1;
+	}
+	netif_device_detach(priv->dev);
+	if (priv->mesh_dev)
+		netif_device_detach(priv->mesh_dev);
 
 	lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(lbs_suspend);
 
-void lbs_resume(struct lbs_private *priv)
+int lbs_resume(struct lbs_private *priv)
 {
-	lbs_deb_enter(LBS_DEB_FW);
+	int ret;
+	uint32_t criteria = EHS_REMOVE_WAKEUP;
 
-	priv->fw_ready = 1;
+	lbs_deb_enter(LBS_DEB_FW);
 
-	/* Firmware doesn't seem to give us RX packets any more
-	   until we send it some command. Might as well update */
-	lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
-				     0, 0, NULL);
+	ret = lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
 
 	netif_device_attach(priv->dev);
 	if (priv->mesh_dev)
 		netif_device_attach(priv->mesh_dev);
 
-	lbs_deb_leave(LBS_DEB_FW);
+	if (priv->deep_sleep_required) {
+		priv->deep_sleep_required = 0;
+		ret = lbs_set_deep_sleep(priv, 1);
+		if (ret)
+			lbs_pr_err("deep sleep activation failed: %d\n", ret);
+	}
+
+	lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(lbs_resume);
 
@@ -834,10 +857,13 @@ static int lbs_init_adapter(struct lbs_private *priv)
 	priv->psstate = PS_STATE_FULL_POWER;
 	priv->is_deep_sleep = 0;
 	priv->is_auto_deep_sleep_enabled = 0;
+	priv->deep_sleep_required = 0;
 	priv->wakeup_dev_required = 0;
 	init_waitqueue_head(&priv->ds_awake_q);
 	priv->authtype_auto = 1;
-
+	priv->is_host_sleep_configured = 0;
+	priv->is_host_sleep_activated = 0;
+	init_waitqueue_head(&priv->host_sleep_q);
 	mutex_init(&priv->lock);
 
 	setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
@@ -976,6 +1002,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 
 	priv->wol_criteria = 0xffffffff;
 	priv->wol_gpio = 0xff;
+	priv->wol_gap = 20;
 
 	goto done;
 
@@ -1031,6 +1058,10 @@ void lbs_remove_card(struct lbs_private *priv)
 		wake_up_interruptible(&priv->ds_awake_q);
 	}
 
+	priv->is_host_sleep_configured = 0;
+	priv->is_host_sleep_activated = 0;
+	wake_up_interruptible(&priv->host_sleep_q);
+
 	/* Stop the thread servicing the interrupts */
 	priv->surpriseremoved = 1;
 	kthread_stop(priv->main_thread);
-- 
1.5.3.4


^ 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