Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 1/4] nl80211: check nla_put_* return values
From: Johannes Berg @ 2013-10-28 14:08 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Coverity pointed out that in a few functions we don't
check the return value of the nla_put_*() calls. Most
of these are fairly harmless because the input isn't
very dynamic and controlled by the kernel, but the
pattern is simply wrong, so fix this.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wireless/nl80211.c | 52 +++++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8ced6bc..1fef427 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9633,8 +9633,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
 	    nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
 		goto nla_put_failure;
 
-	if (req->flags)
-		nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags);
+	if (req->flags &&
+	    nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
+		goto nla_put_failure;
 
 	return 0;
  nla_put_failure:
@@ -11118,16 +11119,18 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
 				wakeup->pattern_idx))
 			goto free_msg;
 
-		if (wakeup->tcp_match)
-			nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH);
+		if (wakeup->tcp_match &&
+		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
+			goto free_msg;
 
-		if (wakeup->tcp_connlost)
-			nla_put_flag(msg,
-				     NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST);
+		if (wakeup->tcp_connlost &&
+		    nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
+			goto free_msg;
 
-		if (wakeup->tcp_nomoretokens)
-			nla_put_flag(msg,
-				NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS);
+		if (wakeup->tcp_nomoretokens &&
+		    nla_put_flag(msg,
+				 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
+			goto free_msg;
 
 		if (wakeup->packet) {
 			u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
@@ -11263,24 +11266,29 @@ void cfg80211_ft_event(struct net_device *netdev,
 		return;
 
 	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
-	if (!hdr) {
-		nlmsg_free(msg);
-		return;
-	}
+	if (!hdr)
+		goto out;
+
+	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
+		goto out;
 
-	nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
-	nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
-	nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap);
-	if (ft_event->ies)
-		nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies);
-	if (ft_event->ric_ies)
-		nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
-			ft_event->ric_ies);
+	if (ft_event->ies &&
+	    nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
+		goto out;
+	if (ft_event->ric_ies &&
+	    nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
+		    ft_event->ric_ies))
+		goto out;
 
 	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, GFP_KERNEL);
+	return;
+ out:
+	nlmsg_free(msg);
 }
 EXPORT_SYMBOL(cfg80211_ft_event);
 
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH] nl80211: fix channel switch parsing
From: Johannes Berg @ 2013-10-28 14:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: Andrei Otcheretianski

From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

The nl80211 attribute NL80211_ATTR_CSA_C_OFF_BEACON should be nested
inside NL80211_ATTR_CSA_IES, but commit ee4bc9e75811d2c0cb5f2a2fc5b5
("nl80211: enable IBSS support for channel switch announcements")
added a check in the outer message attributes.

Fix channel switch calls by removing the erroneus condition.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
[reword commit message]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wireless/nl80211.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c49f0af..8ced6bc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5713,9 +5713,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
 		return -EINVAL;
 
 	/* only important for AP, IBSS and mesh create IEs internally */
-	if (need_new_beacon &&
-	    (!info->attrs[NL80211_ATTR_CSA_IES] ||
-	     !info->attrs[NL80211_ATTR_CSA_C_OFF_BEACON]))
+	if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
 		return -EINVAL;
 
 	params.count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
-- 
1.8.4.rc3


^ permalink raw reply related

* Re: iwlegacy (4965) - what would 0x8000 as the completed TX rate indicate?
From: Johannes Berg @ 2013-10-28 14:02 UTC (permalink / raw)
  To: Adrian Chadd; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <CAJ-Vmok4rDn1Q5qCU2Oz=CVsqkJvYC0D+CmQL+WpwU+9qKHzrw@mail.gmail.com>

On Sat, 2013-10-26 at 16:56 -0700, Adrian Chadd wrote:
> Hi all,
> 
> I'm debugging some issues that i see with the 4965 driver on FreeBSD. I
> figure maybe someone here with experience with the iwlegacy driver may know.

My 4965 knowledge is rusty ...

> I've set it up to do non-aggregate 11abg only traffic in my tests and I do
> occasionally see the TX rate control completion status show the rate is
> 0x8000. I don't know to interpret it. It typically happens with the retry
> count being non-zero, but there are also completed frames with non-zero
> retry and normal rate results. The returned status is OK.

> Oct 26 16:06:11 lucy kernel: iwn4965_tx_done: qid 0 idx 210 retries 0 nkill 0 rate 4003 duration 294 status 201
> Oct 26 16:06:11 lucy kernel: iwn4965_tx_done: qid 0 idx 211 retries 0 nkill 0 rate 4003 duration 182 status 201
> Oct 26 16:06:11 lucy kernel: iwn4965_tx_done: qid 0 idx 212 retries 1 nkill 0 rate 8000 duration 616 status 201
> Oct 26 16:06:12 lucy kernel: iwn4965_tx_done: qid 0 idx 213 retries 0 nkill 0 rate 4003 duration 294 status 201
> Oct 26 16:06:12 lucy kernel: iwn4965_tx_done: qid 0 idx 214 retries 1 nkill 0 rate 8000 duration 292 status 201
> Oct 26 16:06:12 lucy kernel: iwn4965_tx_done: qid 0 idx 215 retries 0 nkill 0 rate 4003 duration 86 status 201
> Oct 26 16:06:12 lucy kernel: iwn4965_tx_done: qid 0 idx 216 retries 0 nkill 0 rate 4003 duration 86 status 201
> 
> I definitely am programming the initial rate control fine and the flags
> field doesn't have the linkq stuff set, so it should be transmitting only
> at that rate.
> 
> The status indicates things are transmitting and completing fine.
> 
> So, any ideas what that 0x8000 rate in the rate completion means?

I think that just means it used the other antenna and rate 0, since the
bits 0x1c000 contain the antenna bitmap that was used (up to three can
be used for each transmission)

johannes


^ permalink raw reply

* Re: [PATCH 16/16] wl1251: Add sysfs file address for setting permanent mac address
From: Pali Rohár @ 2013-10-28 14:00 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Luciano Coelho, John W. Linville, David S. Miller, linux-wireless,
	netdev, linux-kernel, freemangordon, aaro.koskinen, pavel, sre,
	joni.lapilainen
In-Reply-To: <1382968522.17956.11.camel@jlt4.sipsolutions.net>

[-- Attachment #1: Type: Text/Plain, Size: 1415 bytes --]

On Monday 28 October 2013 14:55:22 Johannes Berg wrote:
> On Mon, 2013-10-28 at 14:49 +0100, Pali Rohár wrote:
> > On Monday 28 October 2013 14:45:05 Johannes Berg wrote:
> > > On Sat, 2013-10-26 at 22:34 +0200, Pali Rohár wrote:
> > > > Driver wl1251 generating mac address randomly at startup
> > > > and there is no way to set permanent mac address via
> > > > SET_IEEE80211_PERM_ADDR. This patch export sysfs file
> > > > which can set permanent mac address by userspace helper
> > > > program. Patch is needed for devices which do not store
> > > > mac address in internal wl1251 eeprom.
> > > 
> > > This doesn't really seem like a good idea since you can
> > > also just use 'ip' or whatever to set the MAC address.
> > > 
> > > johannes
> > 
> > AFAIK you cannot set permanent address (show by ethtool -P
> > wlan0) via ip/ifconfig.
> 
> You probably can't, but that address also doesn't matter at
> all and isn't really used anywhere.
> 
> johannes

There are some (proprietary) applications which using permanent 
address for something...

And also more important: some network managing tools using it. 
NetworkManager resetting current MAC address to permanent one 
before starting configuring interface.

So this will lead to never use correct MAC address (but random 
permanent one) assigned for that wl1251 wireless card...

-- 
Pali Rohár
pali.rohar@gmail.com

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

^ permalink raw reply

* Re: [PATCH 0/2] cfg80211: a few genregdb.awk updates
From: Johannes Berg @ 2013-10-28 13:58 UTC (permalink / raw)
  To: Luis R. Rodriguez, John Linville; +Cc: linux-wireless, wireless-regdb
In-Reply-To: <1382926786-7904-1-git-send-email-mcgrof@do-not-panic.com>

I'd apply this, but would prefer John to take a look - he wrote the awk
script and I'm not familiar with it.

johannes


^ permalink raw reply

* Re: [PATCH 16/16] wl1251: Add sysfs file address for setting permanent mac address
From: Johannes Berg @ 2013-10-28 13:55 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Luciano Coelho, John W. Linville, David S. Miller, linux-wireless,
	netdev, linux-kernel, freemangordon, aaro.koskinen, pavel, sre,
	joni.lapilainen
In-Reply-To: <201310281449.58170@pali>

On Mon, 2013-10-28 at 14:49 +0100, Pali Rohár wrote:
> On Monday 28 October 2013 14:45:05 Johannes Berg wrote:
> > On Sat, 2013-10-26 at 22:34 +0200, Pali Rohár wrote:
> > > Driver wl1251 generating mac address randomly at startup and
> > > there is no way to set permanent mac address via
> > > SET_IEEE80211_PERM_ADDR. This patch export sysfs file which
> > > can set permanent mac address by userspace helper program.
> > > Patch is needed for devices which do not store mac address
> > > in internal wl1251 eeprom.
> > 
> > This doesn't really seem like a good idea since you can also
> > just use 'ip' or whatever to set the MAC address.
> > 
> > johannes
> 
> AFAIK you cannot set permanent address (show by ethtool -P wlan0) 
> via ip/ifconfig.

You probably can't, but that address also doesn't matter at all and
isn't really used anywhere.

johannes



^ permalink raw reply

* Re: [PATCH 16/16] wl1251: Add sysfs file address for setting permanent mac address
From: Pali Rohár @ 2013-10-28 13:49 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Luciano Coelho, John W. Linville, David S. Miller, linux-wireless,
	netdev, linux-kernel, freemangordon, aaro.koskinen, pavel, sre,
	joni.lapilainen
In-Reply-To: <1382967905.17956.8.camel@jlt4.sipsolutions.net>

[-- Attachment #1: Type: Text/Plain, Size: 726 bytes --]

On Monday 28 October 2013 14:45:05 Johannes Berg wrote:
> On Sat, 2013-10-26 at 22:34 +0200, Pali Rohár wrote:
> > Driver wl1251 generating mac address randomly at startup and
> > there is no way to set permanent mac address via
> > SET_IEEE80211_PERM_ADDR. This patch export sysfs file which
> > can set permanent mac address by userspace helper program.
> > Patch is needed for devices which do not store mac address
> > in internal wl1251 eeprom.
> 
> This doesn't really seem like a good idea since you can also
> just use 'ip' or whatever to set the MAC address.
> 
> johannes

AFAIK you cannot set permanent address (show by ethtool -P wlan0) 
via ip/ifconfig.

-- 
Pali Rohár
pali.rohar@gmail.com

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

^ permalink raw reply

* Re: [PATCH 01/16] mac80211: fix TX device statistics for monitor interfaces
From: Johannes Berg @ 2013-10-28 13:47 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Luciano Coelho, John W. Linville, David S. Miller, linux-wireless,
	netdev, linux-kernel, freemangordon, aaro.koskinen, pavel, sre,
	joni.lapilainen, David Gnedt
In-Reply-To: <1382819655-30430-2-git-send-email-pali.rohar@gmail.com>

On Sat, 2013-10-26 at 22:34 +0200, Pali Rohár wrote:

> +	dev->stats.tx_packets++;
> +	dev->stats.tx_bytes += skb->len;

We can still easily drop the packet after this - we can't guarantee
it'll go out but maybe we shouldn't do it here?

johannes


^ permalink raw reply

* Re: [PATCH 15/16] wl1251: Add sysfs file tx_mgmt_frm_rate for setting rate
From: Johannes Berg @ 2013-10-28 13:45 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Luciano Coelho, John W. Linville, David S. Miller, linux-wireless,
	netdev, linux-kernel, freemangordon, aaro.koskinen, pavel, sre,
	joni.lapilainen
In-Reply-To: <1382819655-30430-16-git-send-email-pali.rohar@gmail.com>

On Sat, 2013-10-26 at 22:34 +0200, Pali Rohár wrote:
> This patch was extracted from Maemo 2.6.28 kernel

That's not a description or justification for the patch ....

but again, it seems like a bad idea to use sysfs.

johannes


^ permalink raw reply

* Re: [PATCH 16/16] wl1251: Add sysfs file address for setting permanent mac address
From: Johannes Berg @ 2013-10-28 13:45 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Luciano Coelho, John W. Linville, David S. Miller, linux-wireless,
	netdev, linux-kernel, freemangordon, aaro.koskinen, pavel, sre,
	joni.lapilainen
In-Reply-To: <1382819655-30430-17-git-send-email-pali.rohar@gmail.com>

On Sat, 2013-10-26 at 22:34 +0200, Pali Rohár wrote:
> Driver wl1251 generating mac address randomly at startup and there is no way to
> set permanent mac address via SET_IEEE80211_PERM_ADDR. This patch export sysfs
> file which can set permanent mac address by userspace helper program. Patch is
> needed for devices which do not store mac address in internal wl1251 eeprom.

This doesn't really seem like a good idea since you can also just use
'ip' or whatever to set the MAC address.

johannes


^ permalink raw reply

* [PATCH] rtlwifi: fix null dereference on efuse_word on kmalloc fail  returns NULL
From: Colin King @ 2013-10-28 12:58 UTC (permalink / raw)
  To: Larry Finger, John W. Linville, linux-wireless

From: Colin Ian King <colin.king@canonical.com>

kmalloc on efuse_word can return null, leading to free'ing of
elements in efuse_word on the error exit path even though it has not
been allocated.  Instead, don't free the elements of efuse_word if
kmalloc failed.

Also, kmalloc of any of the arrays in efuse_word[] can also fail,
leading to undefined contents in the remaining elements leading to
problems when free'ing these elements later on.  So kzalloc efuse_word
to ensure the kfree on the remaining elements won't cause breakage.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/net/wireless/rtlwifi/efuse.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
index 838a1ed..66f0b2d 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -262,9 +262,9 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 			    sizeof(u8), GFP_ATOMIC);
 	if (!efuse_tbl)
 		return;
-	efuse_word = kmalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC);
+	efuse_word = kzalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC);
 	if (!efuse_word)
-		goto done;
+		goto out;
 	for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
 		efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16),
 					GFP_ATOMIC);
@@ -378,6 +378,7 @@ done:
 	for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
 		kfree(efuse_word[i]);
 	kfree(efuse_word);
+out:
 	kfree(efuse_tbl);
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* Re: [RFC] carl9170: new firmware for linux-firmware.git
From: Rick Farina @ 2013-10-28 12:46 UTC (permalink / raw)
  To: Christian Lamparter, Ben Hutchings; +Cc: linux-wireless
In-Reply-To: <1542665.mhS5oZO9DU@debian64>



On 10/25/2013 07:15 PM, Christian Lamparter wrote:
> Hi Ben,
> 
> I'm currently updating the carl9170 firmware to the latest
> version (1.9.9). I've already pushed out the sources and
> updated the binaries over at our wiki (for the last time,
> all future update will be via linux-firmware.git).
> 
> Now, the last item on my check off list is:
> [ ]     new firmware for linux-firmware.git
> 
> Last time - when this topic came up - we had a short brainstorm
> about how to handle updates in the future: 
> <http://marc.info/?l=linux-wireless&m=136115736909708>
> 
> So, I've now prepared some options: 
> 
> 1. Reorganize carl9170 by creating a new subdirectory "carl9170"
>    and move everything in it.
>    * A carl9170fw-x.y.z.tar.xz with the source is generated for
>      each release and placed under carl9170/source/.
> 
>    * new firmware binaries are placed in carl9170/.
>      (The firmware file name will include the version e.g. 
>      carl9170-1.9.9.fw, it won't clash with a previous release.)
> 
>    * A symlink from the linux-firmware.git root to the latest 
>      carl9170-1.fw in the carl9170 subfolder is added/updated for
>      each release.

Why do we need multiple files at all?  Why do they all need to be named
carl9170-1.fw?  imho if the files are compatible then we only need one,
and if they are not compatible then it is insane that they are all
recognized as "carl9170-1.fw" as that makes it impossible for a user to
know "which carl9170-1.fw" they need for a given kernel.

Thanks,
Zero
> 
>    For a preview see: [1]
>    116 files changed, 3 insertions(+), 26313 deletions(-)
>    
> 2. Simply replace code and firmware binary
>    * The code is simply dumped from the carl9170 firmware repository
>      into the existing carl9170fw directory.
> 
>    * The old firmware binary "carl9170-1.fw" file is replaced by the
>      new version.
> 
>    For a preview see: [2]
>    70 files changed, 2479 insertions(+), 4560 deletions(-)
> 
> I would prefer to go with option 1 and move everything into a carl9170
> subdirectory. This way has the advantage that we can have multiple 
> firmware binaries and sources coexisting in one place. However, I'm 
> also aware of the additional "space and bandwidth" cost in this case. 
> 
> Please tell me which option you like best or if it should be done
> differently. I've prepared a few RFCs (see links), but once we 
> settled for the process, I'll make a proper announcement + patches.
> 
> Regards
> 
> Christian
> 
> [1] <https://drive.google.com/folderview?id=0BwOU1CguSZuBdGYxVVlTWnpXSm8>
> [2] <https://drive.google.com/folderview?id=0BwOU1CguSZuBT1V2V0s2Smp0UmM>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: I always need a miracle to connect with iwlwifi
From: Krishna Chaitanya @ 2013-10-28 11:00 UTC (permalink / raw)
  To: Felipe Contreras
  Cc: Oleksij Rempel, linux-wireless Mailing List, ilw,
	hostap@lists.shmoo.com
In-Reply-To: <CAMP44s2G63ptScncpPE0ercLY0fT7q0RAvSO6ROyMxm_jLRYXA@mail.gmail.com>

On Mon, Oct 28, 2013 at 3:07 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
>> Looks like there is "maximum clients" feature is enabled in the AP, most AP's
>> send deauth for Auth/Assoc Request but some AP's silently discard the
>> Assoc Request.
>>
>> That explains why it works after reboot/adhoc mode. Try increasing the
>> number if thats the case.
>
> Then why am I able to connect from my phone, other machines, and in
> this machine with Windows 7?
>
So lets say "max clients=5" and first all of your devices except the
linux connec
to the AP, then they have no issues connecting. Now if the linux is
the 6th device
then it might have trouble connecting to the AP?? Its possible.

^ permalink raw reply

* Re: I always need a miracle to connect with iwlwifi
From: Oleksij Rempel @ 2013-10-28  9:52 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: linux-wireless Mailing List, ilw, hostap@lists.shmoo.com
In-Reply-To: <CAMP44s0ypeV5JeoF=KWPM-VqZbyR_joJ-4Xg5icKqp2QiNN=Tw@mail.gmail.com>

Am 28.10.2013 10:38, schrieb Felipe Contreras:
> On Mon, Oct 28, 2013 at 2:31 AM, Oleksij Rempel <linux@rempel-privat.de> wrote:
>> Am 28.10.2013 07:24, schrieb Felipe Contreras:
>>> Hi,
>>>
>>> I already reported this problem [1] and I got no feedback whatsoever
>>> at all. The issue keeps happening and I've tried many things.
>>>
>>> First of all, when Linux is failing, my phone connects fine, other
>>> computers connect fine, and this machine with Windows 7 as well. I've
>>> tried reloading the driver, rebooting, different module parameters,
>>> nothing works.
>>>
>>> I logged a session [2] where I waited 30 minutes for the link to come
>>> up, but it never did. You can see the same thing happening over and
>>> over:
>>>
>>> 1382936199.582861: nl80211: Association request send successfully
>>> 1382936199.797063: nl80211: Event message available
>>> 1382936199.797097: nl80211: Delete station e0:1d:3b:46:82:a0
>>> 1382936199.797881: nl80211: Event message available
>>> 1382936199.797905: nl80211: MLME event 38; timeout with e0:1d:3b:46:82:a0
>>> 1382936199.797915: wlan0: Event ASSOC_TIMED_OUT (15) received
>>> 1382936199.797920: wlan0: SME: Association timed out
>>> 1382936199.797924: Added BSSID e0:1d:3b:46:82:a0 into blacklist
>>>
>>> If I reboot the router, it works immediately, another thing that works
>>> is connecting with ad-hoc mode (mode=1), and then back to normal mode
>>> (mode=0).
>>>
>>> Here's a log [3] where I tried reloading the module multiple times and
>>> finally tried ad-hoc mode, after which the link came up.
>>>
>>> Clearly the Linux kernel has a bug. Can somebody point out what needs
>>> to be done to get this fixed?
>>>
>>> Cheers.
>>>
>>> [1] http://article.gmane.org/gmane.linux.kernel.wireless.general/108004
>>> [2] http://people.freedesktop.org/~felipec/wpa/wpa-bad-30-min-wait.log
>>> [3] http://people.freedesktop.org/~felipec/wpa/wpa-good-nothing-worked-except-mode-switch.log
>>>
>>
>> Heh... this logs look like miracle :)
>> My first assumption would be buggy router. There is no answer in
>> wpa_supplicant log.
> 
> Yeah, I bet the router is buggy, which router isn't? But why Windows 7
> connects fine?

May be it includes some workaround?
You do not need to fight with devs, i think they are agree that some
thing is wrong. But believe me, there are so many access points, which
make problems or wear things. If you have a bug, does not mean other
user have it.
If it depends on some AP option, it would be good to know which one.
Then it will be easier to find some fix.

Beside, how many clients use this AP? How big is the distance? What do
you configure in AdHock mode?

>> Take wireshark and capture working and not working associational request.
> 
> I'll try that. If only it was that easy to get a working association.

Compare it with windows.

and please read this, it will help to provide more information.
http://wireless.kernel.org/en/users/Documentation/Reporting_bugs

-- 
Regards,
Oleksij

^ permalink raw reply

* Re: I always need a miracle to connect with iwlwifi
From: Felipe Contreras @ 2013-10-28  9:38 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: linux-wireless Mailing List, ilw, hostap@lists.shmoo.com
In-Reply-To: <526E20EA.9090203@rempel-privat.de>

On Mon, Oct 28, 2013 at 2:31 AM, Oleksij Rempel <linux@rempel-privat.de> wrote:
> Am 28.10.2013 07:24, schrieb Felipe Contreras:
>> Hi,
>>
>> I already reported this problem [1] and I got no feedback whatsoever
>> at all. The issue keeps happening and I've tried many things.
>>
>> First of all, when Linux is failing, my phone connects fine, other
>> computers connect fine, and this machine with Windows 7 as well. I've
>> tried reloading the driver, rebooting, different module parameters,
>> nothing works.
>>
>> I logged a session [2] where I waited 30 minutes for the link to come
>> up, but it never did. You can see the same thing happening over and
>> over:
>>
>> 1382936199.582861: nl80211: Association request send successfully
>> 1382936199.797063: nl80211: Event message available
>> 1382936199.797097: nl80211: Delete station e0:1d:3b:46:82:a0
>> 1382936199.797881: nl80211: Event message available
>> 1382936199.797905: nl80211: MLME event 38; timeout with e0:1d:3b:46:82:a0
>> 1382936199.797915: wlan0: Event ASSOC_TIMED_OUT (15) received
>> 1382936199.797920: wlan0: SME: Association timed out
>> 1382936199.797924: Added BSSID e0:1d:3b:46:82:a0 into blacklist
>>
>> If I reboot the router, it works immediately, another thing that works
>> is connecting with ad-hoc mode (mode=1), and then back to normal mode
>> (mode=0).
>>
>> Here's a log [3] where I tried reloading the module multiple times and
>> finally tried ad-hoc mode, after which the link came up.
>>
>> Clearly the Linux kernel has a bug. Can somebody point out what needs
>> to be done to get this fixed?
>>
>> Cheers.
>>
>> [1] http://article.gmane.org/gmane.linux.kernel.wireless.general/108004
>> [2] http://people.freedesktop.org/~felipec/wpa/wpa-bad-30-min-wait.log
>> [3] http://people.freedesktop.org/~felipec/wpa/wpa-good-nothing-worked-except-mode-switch.log
>>
>
> Heh... this logs look like miracle :)
> My first assumption would be buggy router. There is no answer in
> wpa_supplicant log.

Yeah, I bet the router is buggy, which router isn't? But why Windows 7
connects fine?

> Take wireshark and capture working and not working associational request.

I'll try that. If only it was that easy to get a working association.

-- 
Felipe Contreras

^ permalink raw reply

* Re: I always need a miracle to connect with iwlwifi
From: Felipe Contreras @ 2013-10-28  9:37 UTC (permalink / raw)
  To: Krishna Chaitanya
  Cc: Oleksij Rempel, linux-wireless Mailing List, ilw,
	hostap@lists.shmoo.com
In-Reply-To: <CABPxzYJ8HpdwOYZ4hA40m3MOo_r7CwktzzpM9g6SLdPf6Rkqjg@mail.gmail.com>

On Mon, Oct 28, 2013 at 3:23 AM, Krishna Chaitanya
<chaitanya.mgit@gmail.com> wrote:
> On Mon, Oct 28, 2013 at 2:01 PM, Oleksij Rempel <linux@rempel-privat.de> wrote:
>>> I logged a session [2] where I waited 30 minutes for the link to come
>>> up, but it never did. You can see the same thing happening over and
>>> over:
>>>
>>> 1382936199.582861: nl80211: Association request send successfully
>>> 1382936199.797063: nl80211: Event message available
>>> 1382936199.797097: nl80211: Delete station e0:1d:3b:46:82:a0
>>> 1382936199.797881: nl80211: Event message available
>>> 1382936199.797905: nl80211: MLME event 38; timeout with e0:1d:3b:46:82:a0
>>> 1382936199.797915: wlan0: Event ASSOC_TIMED_OUT (15) received
>>> 1382936199.797920: wlan0: SME: Association timed out
>>> 1382936199.797924: Added BSSID e0:1d:3b:46:82:a0 into blacklist
>>>
>>> If I reboot the router, it works immediately, another thing that works
>>> is connecting with ad-hoc mode (mode=1), and then back to normal mode
>>> (mode=0).
>>>
> Looks like there is "maximum clients" feature is enabled in the AP, most AP's
> send deauth for Auth/Assoc Request but some AP's silently discard the
> Assoc Request.
>
> That explains why it works after reboot/adhoc mode. Try increasing the
> number if thats the case.

Then why am I able to connect from my phone, other machines, and in
this machine with Windows 7?

-- 
Felipe Contreras

^ permalink raw reply

* Re: ath10k hits warning in sta_info.c:839.
From: Kalle Valo @ 2013-10-28  9:23 UTC (permalink / raw)
  To: Michal Kazior; +Cc: Ben Greear, linux-wireless@vger.kernel.org, ath10k
In-Reply-To: <CA+BoTQmomxywSjUB9nrniMT+HeZeBD=L3m2K8c=m6ehGcSp7eQ@mail.gmail.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> On 23 October 2013 00:22, Ben Greear <greearb@candelatech.com> wrote:
>> On 10/22/2013 11:25 AM, Ben Greear wrote:
>>> Kernel is stock 'ath' tree, with small printk to debug an ath10k
>>> crash.
>>>
>>> This is FYI for now...will be looking at other ath10k crash bugs
>>> before digging into this tone.
>>>
>>> Setup is 2 stations trying to associate to same AP, which causes
>>> endless failures and firmware crashes.  Good for chasing bugs :)
>>>
>>>
>>> DMAR:[fault reason 05] PTE Write access is not set
>>> dmar: DRHD: handling fault status reg 3
>>> dmar: DMAR:[DMA Write] Request device [05:00.0] fault addr ffd52000
>>> DMAR:[fault reason 05] PTE Write access is not set
>>> dmar: DRHD: handling fault status reg 3
>>> dmar: DMAR:[DMA Write] Request device [05:00.0] fault addr ffd52000
>>> DMAR:[fault reason 05] PTE Write access is not set
>>>
>>> sta300: authentication with 00:03:83:3d:30:aa timed out
>>> [root@ct523-9292 ~]# ath10k: Failed to delete peer: 00:03:83:3d:30:aa for VDEV: 1
>>> ath10k: WMI vdev stop failed: ret -108
>>
>>> ------------[ cut here ]------------
>>> WARNING: CPU: 1 PID: 6 at /mnt/sda/home/greearb/git/ath/net/mac80211/sta_info.c:839 __sta_info_destroy+0x12)
>>> Modules linked in: nf_nat_ipv4 nf_nat veth 8021q garp stp mrp llc macvlan pktgen lockd f71882fg coretemp hw]
>>
>> I think this may be a result of whatever bug or limitation
>> caused the firmware to error and/or crash when adding a second
>> station VIF and trying to associate it to the same AP.
>>
>> Probably not a problem with the rest of the wifi stacks.
>
> Yup. This originates from the firmware limitation. It's unable to
> handle two peer nodes with same mac addr on different vdevs. That's
> why it's impossible to associate 2 (or more) station interfaces to the
> same BSS.

I think we should add some sort of check to ath10k to detect that and
not crash firmware.

-- 
Kalle Valo

^ permalink raw reply

* Re: I always need a miracle to connect with iwlwifi
From: Krishna Chaitanya @ 2013-10-28  9:23 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Felipe Contreras, linux-wireless Mailing List, ilw,
	hostap@lists.shmoo.com
In-Reply-To: <526E20EA.9090203@rempel-privat.de>

On Mon, Oct 28, 2013 at 2:01 PM, Oleksij Rempel <linux@rempel-privat.de> wrote:
>> I logged a session [2] where I waited 30 minutes for the link to come
>> up, but it never did. You can see the same thing happening over and
>> over:
>>
>> 1382936199.582861: nl80211: Association request send successfully
>> 1382936199.797063: nl80211: Event message available
>> 1382936199.797097: nl80211: Delete station e0:1d:3b:46:82:a0
>> 1382936199.797881: nl80211: Event message available
>> 1382936199.797905: nl80211: MLME event 38; timeout with e0:1d:3b:46:82:a0
>> 1382936199.797915: wlan0: Event ASSOC_TIMED_OUT (15) received
>> 1382936199.797920: wlan0: SME: Association timed out
>> 1382936199.797924: Added BSSID e0:1d:3b:46:82:a0 into blacklist
>>
>> If I reboot the router, it works immediately, another thing that works
>> is connecting with ad-hoc mode (mode=1), and then back to normal mode
>> (mode=0).
>>
Looks like there is "maximum clients" feature is enabled in the AP, most AP's
send deauth for Auth/Assoc Request but some AP's silently discard the
Assoc Request.

That explains why it works after reboot/adhoc mode. Try increasing the
number if thats the case.

^ permalink raw reply

* Re: I always need a miracle to connect with iwlwifi
From: Oleksij Rempel @ 2013-10-28  8:31 UTC (permalink / raw)
  To: Felipe Contreras, linux-wireless Mailing List, ilw, hostap
In-Reply-To: <CAMP44s1XJRHV8bAX=_-TkSKMkY8Nw1=eHorqTCZ2QmtR5m8uJA@mail.gmail.com>

Am 28.10.2013 07:24, schrieb Felipe Contreras:
> Hi,
> 
> I already reported this problem [1] and I got no feedback whatsoever
> at all. The issue keeps happening and I've tried many things.
> 
> First of all, when Linux is failing, my phone connects fine, other
> computers connect fine, and this machine with Windows 7 as well. I've
> tried reloading the driver, rebooting, different module parameters,
> nothing works.
> 
> I logged a session [2] where I waited 30 minutes for the link to come
> up, but it never did. You can see the same thing happening over and
> over:
> 
> 1382936199.582861: nl80211: Association request send successfully
> 1382936199.797063: nl80211: Event message available
> 1382936199.797097: nl80211: Delete station e0:1d:3b:46:82:a0
> 1382936199.797881: nl80211: Event message available
> 1382936199.797905: nl80211: MLME event 38; timeout with e0:1d:3b:46:82:a0
> 1382936199.797915: wlan0: Event ASSOC_TIMED_OUT (15) received
> 1382936199.797920: wlan0: SME: Association timed out
> 1382936199.797924: Added BSSID e0:1d:3b:46:82:a0 into blacklist
> 
> If I reboot the router, it works immediately, another thing that works
> is connecting with ad-hoc mode (mode=1), and then back to normal mode
> (mode=0).
> 
> Here's a log [3] where I tried reloading the module multiple times and
> finally tried ad-hoc mode, after which the link came up.
> 
> Clearly the Linux kernel has a bug. Can somebody point out what needs
> to be done to get this fixed?
> 
> Cheers.
> 
> [1] http://article.gmane.org/gmane.linux.kernel.wireless.general/108004
> [2] http://people.freedesktop.org/~felipec/wpa/wpa-bad-30-min-wait.log
> [3] http://people.freedesktop.org/~felipec/wpa/wpa-good-nothing-worked-except-mode-switch.log
> 

Heh... this logs look like miracle :)
My first assumption would be buggy router. There is no answer in
wpa_supplicant log.
Take wireshark and capture working and not working associational request.

-- 
Regards,
Oleksij

^ permalink raw reply

* [PATCH 4/4] ath9k: Add an initialization routine for WoW
From: Sujith Manoharan @ 2013-10-28  7:38 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1382945891-12779-1-git-send-email-sujith@msujith.org>

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  4 ++++
 drivers/net/wireless/ath/ath9k/init.c  | 20 +-------------------
 drivers/net/wireless/ath/ath9k/wow.c   | 20 ++++++++++++++++++++
 3 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 9e1b728..b351df3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -575,11 +575,15 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
 /************************/
 
 #ifdef CONFIG_ATH9K_WOW
+void ath9k_init_wow(struct ieee80211_hw *hw);
 int ath9k_suspend(struct ieee80211_hw *hw,
 		  struct cfg80211_wowlan *wowlan);
 int ath9k_resume(struct ieee80211_hw *hw);
 void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
 #else
+static inline void ath9k_init_wow(struct ieee80211_hw *hw)
+{
+}
 static inline int ath9k_suspend(struct ieee80211_hw *hw,
 				struct cfg80211_wowlan *wowlan)
 {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index ee7da65..600aa0b 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -870,15 +870,6 @@ static const struct ieee80211_iface_combination if_comb[] = {
 	}
 };
 
-#ifdef CONFIG_ATH9K_WOW
-static const struct wiphy_wowlan_support ath9k_wowlan_support = {
-	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
-	.n_patterns = MAX_NUM_USER_PATTERN,
-	.pattern_min_len = 1,
-	.pattern_max_len = MAX_PATTERN_SIZE,
-};
-#endif
-
 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -928,16 +919,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
 	hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 
-#ifdef CONFIG_ATH9K_WOW
-	if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
-	    (sc->driver_data & ATH9K_PCI_WOW) &&
-	    device_can_wakeup(sc->dev))
-		hw->wiphy->wowlan = &ath9k_wowlan_support;
-
-	atomic_set(&sc->wow_sleep_proc_intr, -1);
-	atomic_set(&sc->wow_got_bmiss_intr, -1);
-#endif
-
 	hw->queues = 4;
 	hw->max_rates = 4;
 	hw->channel_change_time = 5000;
@@ -963,6 +944,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 			&sc->sbands[IEEE80211_BAND_5GHZ];
 
+	ath9k_init_wow(hw);
 	ath9k_reload_chainmask_settings(sc);
 
 	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index e161bbc..f1cde81 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -16,6 +16,13 @@
 
 #include "ath9k.h"
 
+static const struct wiphy_wowlan_support ath9k_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
+	.n_patterns = MAX_NUM_USER_PATTERN,
+	.pattern_min_len = 1,
+	.pattern_max_len = MAX_PATTERN_SIZE,
+};
+
 static void ath9k_wow_map_triggers(struct ath_softc *sc,
 				   struct cfg80211_wowlan *wowlan,
 				   u32 *wow_triggers)
@@ -339,3 +346,16 @@ void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
 	device_set_wakeup_enable(sc->dev, enabled);
 	mutex_unlock(&sc->mutex);
 }
+
+void ath9k_init_wow(struct ieee80211_hw *hw)
+{
+	struct ath_softc *sc = hw->priv;
+
+	if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
+	    (sc->driver_data & ATH9K_PCI_WOW) &&
+	    device_can_wakeup(sc->dev))
+		hw->wiphy->wowlan = &ath9k_wowlan_support;
+
+	atomic_set(&sc->wow_sleep_proc_intr, -1);
+	atomic_set(&sc->wow_got_bmiss_intr, -1);
+}
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 1/4] ath9k: Fix wow.c compilation
From: Sujith Manoharan @ 2013-10-28  7:38 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

The HW routines to set various WoW registers are present
in wow.c. For some reason, it has been compiled as part
of the main ath9k.ko module all this time, when it should
really be part of ath9k_hw.ko. This patch renames the file to
ar9003_wow.ko and adds it to ath9k_hw.ko.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/Makefile     |   3 +-
 drivers/net/wireless/ath/ath9k/ar9003_wow.c | 422 ++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/wow.c        | 422 ----------------------------
 3 files changed, 424 insertions(+), 423 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/ar9003_wow.c
 delete mode 100644 drivers/net/wireless/ath/ath9k/wow.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index f86a261..796686a 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -14,7 +14,6 @@ ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
 ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
 ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
-ath9k-$(CONFIG_PM_SLEEP) += wow.o
 ath9k-$(CONFIG_ATH9K_TX99) += tx99.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
@@ -41,6 +40,8 @@ ath9k_hw-y:=	\
 		ar9003_eeprom.o \
 		ar9003_paprd.o
 
+ath9k_hw-$(CONFIG_PM_SLEEP) += ar9003_wow.o
+
 ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
 					   ar9003_mci.o
 obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
new file mode 100644
index 0000000..81c88dd
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/export.h>
+#include "ath9k.h"
+#include "reg.h"
+#include "hw-ops.h"
+
+const char *ath9k_hw_wow_event_to_string(u32 wow_event)
+{
+	if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
+		return "Magic pattern";
+	if (wow_event & AH_WOW_USER_PATTERN_EN)
+		return "User pattern";
+	if (wow_event & AH_WOW_LINK_CHANGE)
+		return "Link change";
+	if (wow_event & AH_WOW_BEACON_MISS)
+		return "Beacon miss";
+
+	return  "unknown reason";
+}
+EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
+
+static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+
+	/* set rx disable bit */
+	REG_WRITE(ah, AR_CR, AR_CR_RXD);
+
+	if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
+		ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+			REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
+		return;
+	}
+
+	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
+}
+
+static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
+	u32 ctl[13] = {0};
+	u32 data_word[KAL_NUM_DATA_WORDS];
+	u8 i;
+	u32 wow_ka_data_word0;
+
+	memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
+	memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
+
+	/* set the transmit buffer */
+	ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
+	ctl[1] = 0;
+	ctl[3] = 0xb;	/* OFDM_6M hardware value for this rate */
+	ctl[4] = 0;
+	ctl[7] = (ah->txchainmask) << 2;
+	ctl[2] = 0xf << 16; /* tx_tries 0 */
+
+	for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
+		REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+
+	REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
+
+	data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
+		       (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
+	data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
+		       (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
+	data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
+		       (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
+	data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
+		       (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
+	data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
+		       (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
+	data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
+
+	if (AR_SREV_9462_20(ah)) {
+		/* AR9462 2.0 has an extra descriptor word (time based
+		 * discard) compared to other chips */
+		REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
+		wow_ka_data_word0 = AR_WOW_TXBUF(13);
+	} else {
+		wow_ka_data_word0 = AR_WOW_TXBUF(12);
+	}
+
+	for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
+		REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
+
+}
+
+void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
+				u8 *user_mask, int pattern_count,
+				int pattern_len)
+{
+	int i;
+	u32 pattern_val, mask_val;
+	u32 set, clr;
+
+	/* FIXME: should check count by querying the hardware capability */
+	if (pattern_count >= MAX_NUM_PATTERN)
+		return;
+
+	REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
+
+	/* set the registers for pattern */
+	for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
+		memcpy(&pattern_val, user_pattern, 4);
+		REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
+			  pattern_val);
+		user_pattern += 4;
+	}
+
+	/* set the registers for mask */
+	for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
+		memcpy(&mask_val, user_mask, 4);
+		REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
+		user_mask += 4;
+	}
+
+	/* set the pattern length to be matched
+	 *
+	 * AR_WOW_LENGTH1_REG1
+	 * bit 31:24 pattern 0 length
+	 * bit 23:16 pattern 1 length
+	 * bit 15:8 pattern 2 length
+	 * bit 7:0 pattern 3 length
+	 *
+	 * AR_WOW_LENGTH1_REG2
+	 * bit 31:24 pattern 4 length
+	 * bit 23:16 pattern 5 length
+	 * bit 15:8 pattern 6 length
+	 * bit 7:0 pattern 7 length
+	 *
+	 * the below logic writes out the new
+	 * pattern length for the corresponding
+	 * pattern_count, while masking out the
+	 * other fields
+	 */
+
+	ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
+
+	if (pattern_count < 4) {
+		/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
+		set = (pattern_len & AR_WOW_LENGTH_MAX) <<
+		       AR_WOW_LEN1_SHIFT(pattern_count);
+		clr = AR_WOW_LENGTH1_MASK(pattern_count);
+		REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
+	} else {
+		/* Pattern 4-7 uses AR_WOW_LENGTH2 register */
+		set = (pattern_len & AR_WOW_LENGTH_MAX) <<
+		       AR_WOW_LEN2_SHIFT(pattern_count);
+		clr = AR_WOW_LENGTH2_MASK(pattern_count);
+		REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
+	}
+
+}
+EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
+
+u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
+{
+	u32 wow_status = 0;
+	u32 val = 0, rval;
+
+	/*
+	 * read the WoW status register to know
+	 * the wakeup reason
+	 */
+	rval = REG_READ(ah, AR_WOW_PATTERN);
+	val = AR_WOW_STATUS(rval);
+
+	/*
+	 * mask only the WoW events that we have enabled. Sometimes
+	 * we have spurious WoW events from the AR_WOW_PATTERN
+	 * register. This mask will clean it up.
+	 */
+
+	val &= ah->wow_event_mask;
+
+	if (val) {
+		if (val & AR_WOW_MAGIC_PAT_FOUND)
+			wow_status |= AH_WOW_MAGIC_PATTERN_EN;
+		if (AR_WOW_PATTERN_FOUND(val))
+			wow_status |= AH_WOW_USER_PATTERN_EN;
+		if (val & AR_WOW_KEEP_ALIVE_FAIL)
+			wow_status |= AH_WOW_LINK_CHANGE;
+		if (val & AR_WOW_BEACON_FAIL)
+			wow_status |= AH_WOW_BEACON_MISS;
+	}
+
+	/*
+	 * set and clear WOW_PME_CLEAR registers for the chip to
+	 * generate next wow signal.
+	 * disable D3 before accessing other registers ?
+	 */
+
+	/* do we need to check the bit value 0x01000000 (7-10) ?? */
+	REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
+		AR_PMCTRL_PWR_STATE_D1D3);
+
+	/*
+	 * clear all events
+	 */
+	REG_WRITE(ah, AR_WOW_PATTERN,
+		  AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
+
+	/*
+	 * restore the beacon threshold to init value
+	 */
+	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
+
+	/*
+	 * Restore the way the PCI-E reset, Power-On-Reset, external
+	 * PCIE_POR_SHORT pins are tied to its original value.
+	 * Previously just before WoW sleep, we untie the PCI-E
+	 * reset to our Chip's Power On Reset so that any PCI-E
+	 * reset from the bus will not reset our chip
+	 */
+	if (ah->is_pciexpress)
+		ath9k_hw_configpcipowersave(ah, false);
+
+	ah->wow_event_mask = 0;
+
+	return wow_status;
+}
+EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
+
+void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
+{
+	u32 wow_event_mask;
+	u32 set, clr;
+
+	/*
+	 * wow_event_mask is a mask to the AR_WOW_PATTERN register to
+	 * indicate which WoW events we have enabled. The WoW events
+	 * are from the 'pattern_enable' in this function and
+	 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
+	 */
+	wow_event_mask = ah->wow_event_mask;
+
+	/*
+	 * Untie Power-on-Reset from the PCI-E-Reset. When we are in
+	 * WOW sleep, we do want the Reset from the PCI-E to disturb
+	 * our hw state
+	 */
+	if (ah->is_pciexpress) {
+		/*
+		 * we need to untie the internal POR (power-on-reset)
+		 * to the external PCI-E reset. We also need to tie
+		 * the PCI-E Phy reset to the PCI-E reset.
+		 */
+		set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
+		clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
+		REG_RMW(ah, AR_WA, set, clr);
+	}
+
+	/*
+	 * set the power states appropriately and enable PME
+	 */
+	set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
+	      AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
+
+	/*
+	 * set and clear WOW_PME_CLEAR registers for the chip
+	 * to generate next wow signal.
+	 */
+	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
+	clr = AR_PMCTRL_WOW_PME_CLR;
+	REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+
+	/*
+	 * Setup for:
+	 *	- beacon misses
+	 *	- magic pattern
+	 *	- keep alive timeout
+	 *	- pattern matching
+	 */
+
+	/*
+	 * Program default values for pattern backoff, aifs/slot/KAL count,
+	 * beacon miss timeout, KAL timeout, etc.
+	 */
+	set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
+	REG_SET_BIT(ah, AR_WOW_PATTERN, set);
+
+	set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
+	      AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
+	      AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
+	REG_SET_BIT(ah, AR_WOW_COUNT, set);
+
+	if (pattern_enable & AH_WOW_BEACON_MISS)
+		set = AR_WOW_BEACON_TIMO;
+	/* We are not using beacon miss, program a large value */
+	else
+		set = AR_WOW_BEACON_TIMO_MAX;
+
+	REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
+
+	/*
+	 * Keep alive timo in ms except AR9280
+	 */
+	if (!pattern_enable)
+		set = AR_WOW_KEEP_ALIVE_NEVER;
+	else
+		set = KAL_TIMEOUT * 32;
+
+	REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
+
+	/*
+	 * Keep alive delay in us. based on 'power on clock',
+	 * therefore in usec
+	 */
+	set = KAL_DELAY * 1000;
+	REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
+
+	/*
+	 * Create keep alive pattern to respond to beacons
+	 */
+	ath9k_wow_create_keep_alive_pattern(ah);
+
+	/*
+	 * Configure MAC WoW Registers
+	 */
+	set = 0;
+	/* Send keep alive timeouts anyway */
+	clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
+
+	if (pattern_enable & AH_WOW_LINK_CHANGE)
+		wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
+	else
+		set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
+
+	set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
+	REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
+
+	/*
+	 * we are relying on a bmiss failure. ensure we have
+	 * enough threshold to prevent false positives
+	 */
+	REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
+		      AR_WOW_BMISSTHRESHOLD);
+
+	set = 0;
+	clr = 0;
+
+	if (pattern_enable & AH_WOW_BEACON_MISS) {
+		set = AR_WOW_BEACON_FAIL_EN;
+		wow_event_mask |= AR_WOW_BEACON_FAIL;
+	} else {
+		clr = AR_WOW_BEACON_FAIL_EN;
+	}
+
+	REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
+
+	set = 0;
+	clr = 0;
+	/*
+	 * Enable the magic packet registers
+	 */
+	if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
+		set = AR_WOW_MAGIC_EN;
+		wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
+	} else {
+		clr = AR_WOW_MAGIC_EN;
+	}
+	set |= AR_WOW_MAC_INTR_EN;
+	REG_RMW(ah, AR_WOW_PATTERN, set, clr);
+
+	REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
+		  AR_WOW_PATTERN_SUPPORTED);
+
+	/*
+	 * Set the power states appropriately and enable PME
+	 */
+	clr = 0;
+	set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
+	      AR_PMCTRL_PWR_PM_CTRL_ENA;
+
+	clr = AR_PCIE_PM_CTRL_ENA;
+	REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
+
+	/*
+	 * this is needed to prevent the chip waking up
+	 * the host within 3-4 seconds with certain
+	 * platform/BIOS. The fix is to enable
+	 * D1 & D3 to match original definition and
+	 * also match the OTP value. Anyway this
+	 * is more related to SW WOW.
+	 */
+	clr = AR_PMCTRL_PWR_STATE_D1D3;
+	REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
+
+	set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
+	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
+
+	REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
+
+	/* to bring down WOW power low margin */
+	set = BIT(13);
+	REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
+	/* HW WoW */
+	clr = BIT(5);
+	REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
+
+	ath9k_hw_set_powermode_wow_sleep(ah);
+	ah->wow_event_mask = wow_event_mask;
+}
+EXPORT_SYMBOL(ath9k_hw_wow_enable);
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
deleted file mode 100644
index 81c88dd..0000000
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (c) 2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/export.h>
-#include "ath9k.h"
-#include "reg.h"
-#include "hw-ops.h"
-
-const char *ath9k_hw_wow_event_to_string(u32 wow_event)
-{
-	if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
-		return "Magic pattern";
-	if (wow_event & AH_WOW_USER_PATTERN_EN)
-		return "User pattern";
-	if (wow_event & AH_WOW_LINK_CHANGE)
-		return "Link change";
-	if (wow_event & AH_WOW_BEACON_MISS)
-		return "Beacon miss";
-
-	return  "unknown reason";
-}
-EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
-
-static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-
-	/* set rx disable bit */
-	REG_WRITE(ah, AR_CR, AR_CR_RXD);
-
-	if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
-		ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
-			REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
-		return;
-	}
-
-	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
-}
-
-static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
-	u32 ctl[13] = {0};
-	u32 data_word[KAL_NUM_DATA_WORDS];
-	u8 i;
-	u32 wow_ka_data_word0;
-
-	memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
-	memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
-
-	/* set the transmit buffer */
-	ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
-	ctl[1] = 0;
-	ctl[3] = 0xb;	/* OFDM_6M hardware value for this rate */
-	ctl[4] = 0;
-	ctl[7] = (ah->txchainmask) << 2;
-	ctl[2] = 0xf << 16; /* tx_tries 0 */
-
-	for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
-		REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
-
-	REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
-
-	data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
-		       (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
-	data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
-		       (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
-	data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
-		       (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
-	data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
-		       (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
-	data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
-		       (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
-	data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
-
-	if (AR_SREV_9462_20(ah)) {
-		/* AR9462 2.0 has an extra descriptor word (time based
-		 * discard) compared to other chips */
-		REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
-		wow_ka_data_word0 = AR_WOW_TXBUF(13);
-	} else {
-		wow_ka_data_word0 = AR_WOW_TXBUF(12);
-	}
-
-	for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
-		REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
-
-}
-
-void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
-				u8 *user_mask, int pattern_count,
-				int pattern_len)
-{
-	int i;
-	u32 pattern_val, mask_val;
-	u32 set, clr;
-
-	/* FIXME: should check count by querying the hardware capability */
-	if (pattern_count >= MAX_NUM_PATTERN)
-		return;
-
-	REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
-
-	/* set the registers for pattern */
-	for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
-		memcpy(&pattern_val, user_pattern, 4);
-		REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
-			  pattern_val);
-		user_pattern += 4;
-	}
-
-	/* set the registers for mask */
-	for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
-		memcpy(&mask_val, user_mask, 4);
-		REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
-		user_mask += 4;
-	}
-
-	/* set the pattern length to be matched
-	 *
-	 * AR_WOW_LENGTH1_REG1
-	 * bit 31:24 pattern 0 length
-	 * bit 23:16 pattern 1 length
-	 * bit 15:8 pattern 2 length
-	 * bit 7:0 pattern 3 length
-	 *
-	 * AR_WOW_LENGTH1_REG2
-	 * bit 31:24 pattern 4 length
-	 * bit 23:16 pattern 5 length
-	 * bit 15:8 pattern 6 length
-	 * bit 7:0 pattern 7 length
-	 *
-	 * the below logic writes out the new
-	 * pattern length for the corresponding
-	 * pattern_count, while masking out the
-	 * other fields
-	 */
-
-	ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
-
-	if (pattern_count < 4) {
-		/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
-		set = (pattern_len & AR_WOW_LENGTH_MAX) <<
-		       AR_WOW_LEN1_SHIFT(pattern_count);
-		clr = AR_WOW_LENGTH1_MASK(pattern_count);
-		REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
-	} else {
-		/* Pattern 4-7 uses AR_WOW_LENGTH2 register */
-		set = (pattern_len & AR_WOW_LENGTH_MAX) <<
-		       AR_WOW_LEN2_SHIFT(pattern_count);
-		clr = AR_WOW_LENGTH2_MASK(pattern_count);
-		REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
-	}
-
-}
-EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
-
-u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
-{
-	u32 wow_status = 0;
-	u32 val = 0, rval;
-
-	/*
-	 * read the WoW status register to know
-	 * the wakeup reason
-	 */
-	rval = REG_READ(ah, AR_WOW_PATTERN);
-	val = AR_WOW_STATUS(rval);
-
-	/*
-	 * mask only the WoW events that we have enabled. Sometimes
-	 * we have spurious WoW events from the AR_WOW_PATTERN
-	 * register. This mask will clean it up.
-	 */
-
-	val &= ah->wow_event_mask;
-
-	if (val) {
-		if (val & AR_WOW_MAGIC_PAT_FOUND)
-			wow_status |= AH_WOW_MAGIC_PATTERN_EN;
-		if (AR_WOW_PATTERN_FOUND(val))
-			wow_status |= AH_WOW_USER_PATTERN_EN;
-		if (val & AR_WOW_KEEP_ALIVE_FAIL)
-			wow_status |= AH_WOW_LINK_CHANGE;
-		if (val & AR_WOW_BEACON_FAIL)
-			wow_status |= AH_WOW_BEACON_MISS;
-	}
-
-	/*
-	 * set and clear WOW_PME_CLEAR registers for the chip to
-	 * generate next wow signal.
-	 * disable D3 before accessing other registers ?
-	 */
-
-	/* do we need to check the bit value 0x01000000 (7-10) ?? */
-	REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
-		AR_PMCTRL_PWR_STATE_D1D3);
-
-	/*
-	 * clear all events
-	 */
-	REG_WRITE(ah, AR_WOW_PATTERN,
-		  AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
-
-	/*
-	 * restore the beacon threshold to init value
-	 */
-	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
-
-	/*
-	 * Restore the way the PCI-E reset, Power-On-Reset, external
-	 * PCIE_POR_SHORT pins are tied to its original value.
-	 * Previously just before WoW sleep, we untie the PCI-E
-	 * reset to our Chip's Power On Reset so that any PCI-E
-	 * reset from the bus will not reset our chip
-	 */
-	if (ah->is_pciexpress)
-		ath9k_hw_configpcipowersave(ah, false);
-
-	ah->wow_event_mask = 0;
-
-	return wow_status;
-}
-EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
-
-void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
-{
-	u32 wow_event_mask;
-	u32 set, clr;
-
-	/*
-	 * wow_event_mask is a mask to the AR_WOW_PATTERN register to
-	 * indicate which WoW events we have enabled. The WoW events
-	 * are from the 'pattern_enable' in this function and
-	 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
-	 */
-	wow_event_mask = ah->wow_event_mask;
-
-	/*
-	 * Untie Power-on-Reset from the PCI-E-Reset. When we are in
-	 * WOW sleep, we do want the Reset from the PCI-E to disturb
-	 * our hw state
-	 */
-	if (ah->is_pciexpress) {
-		/*
-		 * we need to untie the internal POR (power-on-reset)
-		 * to the external PCI-E reset. We also need to tie
-		 * the PCI-E Phy reset to the PCI-E reset.
-		 */
-		set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
-		clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
-		REG_RMW(ah, AR_WA, set, clr);
-	}
-
-	/*
-	 * set the power states appropriately and enable PME
-	 */
-	set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
-	      AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
-
-	/*
-	 * set and clear WOW_PME_CLEAR registers for the chip
-	 * to generate next wow signal.
-	 */
-	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
-	clr = AR_PMCTRL_WOW_PME_CLR;
-	REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-
-	/*
-	 * Setup for:
-	 *	- beacon misses
-	 *	- magic pattern
-	 *	- keep alive timeout
-	 *	- pattern matching
-	 */
-
-	/*
-	 * Program default values for pattern backoff, aifs/slot/KAL count,
-	 * beacon miss timeout, KAL timeout, etc.
-	 */
-	set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
-	REG_SET_BIT(ah, AR_WOW_PATTERN, set);
-
-	set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
-	      AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
-	      AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
-	REG_SET_BIT(ah, AR_WOW_COUNT, set);
-
-	if (pattern_enable & AH_WOW_BEACON_MISS)
-		set = AR_WOW_BEACON_TIMO;
-	/* We are not using beacon miss, program a large value */
-	else
-		set = AR_WOW_BEACON_TIMO_MAX;
-
-	REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
-
-	/*
-	 * Keep alive timo in ms except AR9280
-	 */
-	if (!pattern_enable)
-		set = AR_WOW_KEEP_ALIVE_NEVER;
-	else
-		set = KAL_TIMEOUT * 32;
-
-	REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
-
-	/*
-	 * Keep alive delay in us. based on 'power on clock',
-	 * therefore in usec
-	 */
-	set = KAL_DELAY * 1000;
-	REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
-
-	/*
-	 * Create keep alive pattern to respond to beacons
-	 */
-	ath9k_wow_create_keep_alive_pattern(ah);
-
-	/*
-	 * Configure MAC WoW Registers
-	 */
-	set = 0;
-	/* Send keep alive timeouts anyway */
-	clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
-
-	if (pattern_enable & AH_WOW_LINK_CHANGE)
-		wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
-	else
-		set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-
-	set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-	REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
-
-	/*
-	 * we are relying on a bmiss failure. ensure we have
-	 * enough threshold to prevent false positives
-	 */
-	REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
-		      AR_WOW_BMISSTHRESHOLD);
-
-	set = 0;
-	clr = 0;
-
-	if (pattern_enable & AH_WOW_BEACON_MISS) {
-		set = AR_WOW_BEACON_FAIL_EN;
-		wow_event_mask |= AR_WOW_BEACON_FAIL;
-	} else {
-		clr = AR_WOW_BEACON_FAIL_EN;
-	}
-
-	REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
-
-	set = 0;
-	clr = 0;
-	/*
-	 * Enable the magic packet registers
-	 */
-	if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
-		set = AR_WOW_MAGIC_EN;
-		wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
-	} else {
-		clr = AR_WOW_MAGIC_EN;
-	}
-	set |= AR_WOW_MAC_INTR_EN;
-	REG_RMW(ah, AR_WOW_PATTERN, set, clr);
-
-	REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
-		  AR_WOW_PATTERN_SUPPORTED);
-
-	/*
-	 * Set the power states appropriately and enable PME
-	 */
-	clr = 0;
-	set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
-	      AR_PMCTRL_PWR_PM_CTRL_ENA;
-
-	clr = AR_PCIE_PM_CTRL_ENA;
-	REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
-
-	/*
-	 * this is needed to prevent the chip waking up
-	 * the host within 3-4 seconds with certain
-	 * platform/BIOS. The fix is to enable
-	 * D1 & D3 to match original definition and
-	 * also match the OTP value. Anyway this
-	 * is more related to SW WOW.
-	 */
-	clr = AR_PMCTRL_PWR_STATE_D1D3;
-	REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-
-	set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
-	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
-
-	REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
-
-	/* to bring down WOW power low margin */
-	set = BIT(13);
-	REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
-	/* HW WoW */
-	clr = BIT(5);
-	REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
-
-	ath9k_hw_set_powermode_wow_sleep(ah);
-	ah->wow_event_mask = wow_event_mask;
-}
-EXPORT_SYMBOL(ath9k_hw_wow_enable);
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 3/4] ath9k: Use CONFIG_ATH9K_WOW
From: Sujith Manoharan @ 2013-10-28  7:38 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1382945891-12779-1-git-send-email-sujith@msujith.org>

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Move the WoW code to wow.c and compile it conditionally
based on CONFIG_ATH9K_WOW.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/Makefile |   3 +-
 drivers/net/wireless/ath/ath9k/ath9k.h  |  28 ++-
 drivers/net/wireless/ath/ath9k/hw.h     |   4 +-
 drivers/net/wireless/ath/ath9k/init.c   |   4 +-
 drivers/net/wireless/ath/ath9k/main.c   | 338 +------------------------------
 drivers/net/wireless/ath/ath9k/wow.c    | 341 ++++++++++++++++++++++++++++++++
 6 files changed, 381 insertions(+), 337 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath9k/wow.c

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 796686a..337c459 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -15,6 +15,7 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
 ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
 ath9k-$(CONFIG_ATH9K_TX99) += tx99.o
+ath9k-$(CONFIG_ATH9K_WOW) += wow.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
 
@@ -40,7 +41,7 @@ ath9k_hw-y:=	\
 		ar9003_eeprom.o \
 		ar9003_paprd.o
 
-ath9k_hw-$(CONFIG_PM_SLEEP) += ar9003_wow.o
+ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o
 
 ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
 					   ar9003_mci.o
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 62f5892..9e1b728 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -570,6 +570,30 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
 }
 #endif
 
+/************************/
+/* Wake on Wireless LAN */
+/************************/
+
+#ifdef CONFIG_ATH9K_WOW
+int ath9k_suspend(struct ieee80211_hw *hw,
+		  struct cfg80211_wowlan *wowlan);
+int ath9k_resume(struct ieee80211_hw *hw);
+void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
+#else
+static inline int ath9k_suspend(struct ieee80211_hw *hw,
+				struct cfg80211_wowlan *wowlan)
+{
+	return 0;
+}
+static inline int ath9k_resume(struct ieee80211_hw *hw)
+{
+	return 0;
+}
+static inline void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+}
+#endif /* CONFIG_ATH9K_WOW */
+
 /*******************************/
 /* Antenna diversity/combining */
 /*******************************/
@@ -784,7 +808,7 @@ struct ath_softc {
 	bool tx99_state;
 	s16 tx99_power;
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
 	atomic_t wow_got_bmiss_intr;
 	atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
 	u32 wow_intr_before_sleep;
@@ -983,6 +1007,8 @@ extern bool is_ath9k_unloaded;
 u8 ath9k_parse_mpdudensity(u8 mpdudensity);
 irqreturn_t ath_isr(int irq, void *dev);
 int ath_reset(struct ath_softc *sc);
+void ath_cancel_work(struct ath_softc *sc);
+void ath_restart_work(struct ath_softc *sc);
 int ath9k_init_device(u16 devid, struct ath_softc *sc,
 		    const struct ath_bus_ops *bus_ops);
 void ath9k_deinit_device(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9ea24f1..69542c1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -920,7 +920,7 @@ struct ath_hw {
 	/* Enterprise mode cap */
 	u32 ent_mode;
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
 	u32 wow_event_mask;
 #endif
 	bool is_clk_25mhz;
@@ -1126,7 +1126,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
 #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
 
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
 const char *ath9k_hw_wow_event_to_string(u32 wow_event);
 void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
 				u8 *user_mask, int pattern_count,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 17502b4..ee7da65 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -870,7 +870,7 @@ static const struct ieee80211_iface_combination if_comb[] = {
 	}
 };
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_ATH9K_WOW
 static const struct wiphy_wowlan_support ath9k_wowlan_support = {
 	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
 	.n_patterns = MAX_NUM_USER_PATTERN,
@@ -928,7 +928,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 	hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
 	hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
 	if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
 	    (sc->driver_data & ATH9K_PCI_WOW) &&
 	    device_can_wakeup(sc->dev))
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3d17398..e54ffdd 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -163,13 +163,13 @@ static void __ath_cancel_work(struct ath_softc *sc)
 #endif
 }
 
-static void ath_cancel_work(struct ath_softc *sc)
+void ath_cancel_work(struct ath_softc *sc)
 {
 	__ath_cancel_work(sc);
 	cancel_work_sync(&sc->hw_reset_work);
 }
 
-static void ath_restart_work(struct ath_softc *sc)
+void ath_restart_work(struct ath_softc *sc)
 {
 	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
 
@@ -579,7 +579,8 @@ irqreturn_t ath_isr(int irq, void *dev)
 
 		goto chip_reset;
 	}
-#ifdef CONFIG_PM_SLEEP
+
+#ifdef CONFIG_ATH9K_WOW
 	if (status & ATH9K_INT_BMISS) {
 		if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
 			ath_dbg(common, ANY, "during WoW we got a BMISS\n");
@@ -588,6 +589,8 @@ irqreturn_t ath_isr(int irq, void *dev)
 		}
 	}
 #endif
+
+
 	if (status & ATH9K_INT_SWBA)
 		tasklet_schedule(&sc->bcon_tasklet);
 
@@ -2021,333 +2024,6 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
-static void ath9k_wow_map_triggers(struct ath_softc *sc,
-				   struct cfg80211_wowlan *wowlan,
-				   u32 *wow_triggers)
-{
-	if (wowlan->disconnect)
-		*wow_triggers |= AH_WOW_LINK_CHANGE |
-				 AH_WOW_BEACON_MISS;
-	if (wowlan->magic_pkt)
-		*wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
-
-	if (wowlan->n_patterns)
-		*wow_triggers |= AH_WOW_USER_PATTERN_EN;
-
-	sc->wow_enabled = *wow_triggers;
-
-}
-
-static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
-{
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-	int pattern_count = 0;
-	int i, byte_cnt;
-	u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
-	u8 dis_deauth_mask[MAX_PATTERN_SIZE];
-
-	memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
-	memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
-
-	/*
-	 * Create Dissassociate / Deauthenticate packet filter
-	 *
-	 *     2 bytes        2 byte    6 bytes   6 bytes  6 bytes
-	 *  +--------------+----------+---------+--------+--------+----
-	 *  + Frame Control+ Duration +   DA    +  SA    +  BSSID +
-	 *  +--------------+----------+---------+--------+--------+----
-	 *
-	 * The above is the management frame format for disassociate/
-	 * deauthenticate pattern, from this we need to match the first byte
-	 * of 'Frame Control' and DA, SA, and BSSID fields
-	 * (skipping 2nd byte of FC and Duration feild.
-	 *
-	 * Disassociate pattern
-	 * --------------------
-	 * Frame control = 00 00 1010
-	 * DA, SA, BSSID = x:x:x:x:x:x
-	 * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-	 *			    | x:x:x:x:x:x  -- 22 bytes
-	 *
-	 * Deauthenticate pattern
-	 * ----------------------
-	 * Frame control = 00 00 1100
-	 * DA, SA, BSSID = x:x:x:x:x:x
-	 * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-	 *			    | x:x:x:x:x:x  -- 22 bytes
-	 */
-
-	/* Create Disassociate Pattern first */
-
-	byte_cnt = 0;
-
-	/* Fill out the mask with all FF's */
-
-	for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
-		dis_deauth_mask[i] = 0xff;
-
-	/* copy the first byte of frame control field */
-	dis_deauth_pattern[byte_cnt] = 0xa0;
-	byte_cnt++;
-
-	/* skip 2nd byte of frame control and Duration field */
-	byte_cnt += 3;
-
-	/*
-	 * need not match the destination mac address, it can be a broadcast
-	 * mac address or an unicast to this station
-	 */
-	byte_cnt += 6;
-
-	/* copy the source mac address */
-	memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
-
-	byte_cnt += 6;
-
-	/* copy the bssid, its same as the source mac address */
-
-	memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
-
-	/* Create Disassociate pattern mask */
-
-	dis_deauth_mask[0] = 0xfe;
-	dis_deauth_mask[1] = 0x03;
-	dis_deauth_mask[2] = 0xc0;
-
-	ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
-
-	ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-				   pattern_count, byte_cnt);
-
-	pattern_count++;
-	/*
-	 * for de-authenticate pattern, only the first byte of the frame
-	 * control field gets changed from 0xA0 to 0xC0
-	 */
-	dis_deauth_pattern[0] = 0xC0;
-
-	ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-				   pattern_count, byte_cnt);
-
-}
-
-static void ath9k_wow_add_pattern(struct ath_softc *sc,
-				  struct cfg80211_wowlan *wowlan)
-{
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath9k_wow_pattern *wow_pattern = NULL;
-	struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
-	int mask_len;
-	s8 i = 0;
-
-	if (!wowlan->n_patterns)
-		return;
-
-	/*
-	 * Add the new user configured patterns
-	 */
-	for (i = 0; i < wowlan->n_patterns; i++) {
-
-		wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
-
-		if (!wow_pattern)
-			return;
-
-		/*
-		 * TODO: convert the generic user space pattern to
-		 * appropriate chip specific/802.11 pattern.
-		 */
-
-		mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
-		memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
-		memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
-		memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
-		       patterns[i].pattern_len);
-		memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
-		wow_pattern->pattern_len = patterns[i].pattern_len;
-
-		/*
-		 * just need to take care of deauth and disssoc pattern,
-		 * make sure we don't overwrite them.
-		 */
-
-		ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
-					   wow_pattern->mask_bytes,
-					   i + 2,
-					   wow_pattern->pattern_len);
-		kfree(wow_pattern);
-
-	}
-
-}
-
-static int ath9k_suspend(struct ieee80211_hw *hw,
-			 struct cfg80211_wowlan *wowlan)
-{
-	struct ath_softc *sc = hw->priv;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-	u32 wow_triggers_enabled = 0;
-	int ret = 0;
-
-	mutex_lock(&sc->mutex);
-
-	ath_cancel_work(sc);
-	ath_stop_ani(sc);
-	del_timer_sync(&sc->rx_poll_timer);
-
-	if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
-		ath_dbg(common, ANY, "Device not present\n");
-		ret = -EINVAL;
-		goto fail_wow;
-	}
-
-	if (WARN_ON(!wowlan)) {
-		ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
-		ret = -EINVAL;
-		goto fail_wow;
-	}
-
-	if (!device_can_wakeup(sc->dev)) {
-		ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
-		ret = 1;
-		goto fail_wow;
-	}
-
-	/*
-	 * none of the sta vifs are associated
-	 * and we are not currently handling multivif
-	 * cases, for instance we have to seperately
-	 * configure 'keep alive frame' for each
-	 * STA.
-	 */
-
-	if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
-		ath_dbg(common, WOW, "None of the STA vifs are associated\n");
-		ret = 1;
-		goto fail_wow;
-	}
-
-	if (sc->nvifs > 1) {
-		ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
-		ret = 1;
-		goto fail_wow;
-	}
-
-	ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
-
-	ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
-		wow_triggers_enabled);
-
-	ath9k_ps_wakeup(sc);
-
-	ath9k_stop_btcoex(sc);
-
-	/*
-	 * Enable wake up on recieving disassoc/deauth
-	 * frame by default.
-	 */
-	ath9k_wow_add_disassoc_deauth_pattern(sc);
-
-	if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
-		ath9k_wow_add_pattern(sc, wowlan);
-
-	spin_lock_bh(&sc->sc_pcu_lock);
-	/*
-	 * To avoid false wake, we enable beacon miss interrupt only
-	 * when we go to sleep. We save the current interrupt mask
-	 * so we can restore it after the system wakes up
-	 */
-	sc->wow_intr_before_sleep = ah->imask;
-	ah->imask &= ~ATH9K_INT_GLOBAL;
-	ath9k_hw_disable_interrupts(ah);
-	ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
-	ath9k_hw_set_interrupts(ah);
-	ath9k_hw_enable_interrupts(ah);
-
-	spin_unlock_bh(&sc->sc_pcu_lock);
-
-	/*
-	 * we can now sync irq and kill any running tasklets, since we already
-	 * disabled interrupts and not holding a spin lock
-	 */
-	synchronize_irq(sc->irq);
-	tasklet_kill(&sc->intr_tq);
-
-	ath9k_hw_wow_enable(ah, wow_triggers_enabled);
-
-	ath9k_ps_restore(sc);
-	ath_dbg(common, ANY, "WoW enabled in ath9k\n");
-	atomic_inc(&sc->wow_sleep_proc_intr);
-
-fail_wow:
-	mutex_unlock(&sc->mutex);
-	return ret;
-}
-
-static int ath9k_resume(struct ieee80211_hw *hw)
-{
-	struct ath_softc *sc = hw->priv;
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-	u32 wow_status;
-
-	mutex_lock(&sc->mutex);
-
-	ath9k_ps_wakeup(sc);
-
-	spin_lock_bh(&sc->sc_pcu_lock);
-
-	ath9k_hw_disable_interrupts(ah);
-	ah->imask = sc->wow_intr_before_sleep;
-	ath9k_hw_set_interrupts(ah);
-	ath9k_hw_enable_interrupts(ah);
-
-	spin_unlock_bh(&sc->sc_pcu_lock);
-
-	wow_status = ath9k_hw_wow_wakeup(ah);
-
-	if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
-		/*
-		 * some devices may not pick beacon miss
-		 * as the reason they woke up so we add
-		 * that here for that shortcoming.
-		 */
-		wow_status |= AH_WOW_BEACON_MISS;
-		atomic_dec(&sc->wow_got_bmiss_intr);
-		ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
-	}
-
-	atomic_dec(&sc->wow_sleep_proc_intr);
-
-	if (wow_status) {
-		ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
-			ath9k_hw_wow_event_to_string(wow_status), wow_status);
-	}
-
-	ath_restart_work(sc);
-	ath9k_start_btcoex(sc);
-
-	ath9k_ps_restore(sc);
-	mutex_unlock(&sc->mutex);
-
-	return 0;
-}
-
-static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
-{
-	struct ath_softc *sc = hw->priv;
-
-	mutex_lock(&sc->mutex);
-	device_init_wakeup(sc->dev, 1);
-	device_set_wakeup_enable(sc->dev, enabled);
-	mutex_unlock(&sc->mutex);
-}
-
-#endif
 static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 {
 	struct ath_softc *sc = hw->priv;
@@ -2403,7 +2079,7 @@ struct ieee80211_ops ath9k_ops = {
 	.set_antenna	    = ath9k_set_antenna,
 	.get_antenna	    = ath9k_get_antenna,
 
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_ATH9K_WOW
 	.suspend	    = ath9k_suspend,
 	.resume		    = ath9k_resume,
 	.set_wakeup	    = ath9k_set_wakeup,
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
new file mode 100644
index 0000000..e161bbc
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2013 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+static void ath9k_wow_map_triggers(struct ath_softc *sc,
+				   struct cfg80211_wowlan *wowlan,
+				   u32 *wow_triggers)
+{
+	if (wowlan->disconnect)
+		*wow_triggers |= AH_WOW_LINK_CHANGE |
+				 AH_WOW_BEACON_MISS;
+	if (wowlan->magic_pkt)
+		*wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
+
+	if (wowlan->n_patterns)
+		*wow_triggers |= AH_WOW_USER_PATTERN_EN;
+
+	sc->wow_enabled = *wow_triggers;
+
+}
+
+static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	int pattern_count = 0;
+	int i, byte_cnt;
+	u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
+	u8 dis_deauth_mask[MAX_PATTERN_SIZE];
+
+	memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
+	memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
+
+	/*
+	 * Create Dissassociate / Deauthenticate packet filter
+	 *
+	 *     2 bytes        2 byte    6 bytes   6 bytes  6 bytes
+	 *  +--------------+----------+---------+--------+--------+----
+	 *  + Frame Control+ Duration +   DA    +  SA    +  BSSID +
+	 *  +--------------+----------+---------+--------+--------+----
+	 *
+	 * The above is the management frame format for disassociate/
+	 * deauthenticate pattern, from this we need to match the first byte
+	 * of 'Frame Control' and DA, SA, and BSSID fields
+	 * (skipping 2nd byte of FC and Duration feild.
+	 *
+	 * Disassociate pattern
+	 * --------------------
+	 * Frame control = 00 00 1010
+	 * DA, SA, BSSID = x:x:x:x:x:x
+	 * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
+	 *			    | x:x:x:x:x:x  -- 22 bytes
+	 *
+	 * Deauthenticate pattern
+	 * ----------------------
+	 * Frame control = 00 00 1100
+	 * DA, SA, BSSID = x:x:x:x:x:x
+	 * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
+	 *			    | x:x:x:x:x:x  -- 22 bytes
+	 */
+
+	/* Create Disassociate Pattern first */
+
+	byte_cnt = 0;
+
+	/* Fill out the mask with all FF's */
+
+	for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
+		dis_deauth_mask[i] = 0xff;
+
+	/* copy the first byte of frame control field */
+	dis_deauth_pattern[byte_cnt] = 0xa0;
+	byte_cnt++;
+
+	/* skip 2nd byte of frame control and Duration field */
+	byte_cnt += 3;
+
+	/*
+	 * need not match the destination mac address, it can be a broadcast
+	 * mac address or an unicast to this station
+	 */
+	byte_cnt += 6;
+
+	/* copy the source mac address */
+	memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
+
+	byte_cnt += 6;
+
+	/* copy the bssid, its same as the source mac address */
+
+	memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
+
+	/* Create Disassociate pattern mask */
+
+	dis_deauth_mask[0] = 0xfe;
+	dis_deauth_mask[1] = 0x03;
+	dis_deauth_mask[2] = 0xc0;
+
+	ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
+
+	ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
+				   pattern_count, byte_cnt);
+
+	pattern_count++;
+	/*
+	 * for de-authenticate pattern, only the first byte of the frame
+	 * control field gets changed from 0xA0 to 0xC0
+	 */
+	dis_deauth_pattern[0] = 0xC0;
+
+	ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
+				   pattern_count, byte_cnt);
+
+}
+
+static void ath9k_wow_add_pattern(struct ath_softc *sc,
+				  struct cfg80211_wowlan *wowlan)
+{
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath9k_wow_pattern *wow_pattern = NULL;
+	struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
+	int mask_len;
+	s8 i = 0;
+
+	if (!wowlan->n_patterns)
+		return;
+
+	/*
+	 * Add the new user configured patterns
+	 */
+	for (i = 0; i < wowlan->n_patterns; i++) {
+
+		wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
+
+		if (!wow_pattern)
+			return;
+
+		/*
+		 * TODO: convert the generic user space pattern to
+		 * appropriate chip specific/802.11 pattern.
+		 */
+
+		mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
+		memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
+		memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
+		memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
+		       patterns[i].pattern_len);
+		memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
+		wow_pattern->pattern_len = patterns[i].pattern_len;
+
+		/*
+		 * just need to take care of deauth and disssoc pattern,
+		 * make sure we don't overwrite them.
+		 */
+
+		ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
+					   wow_pattern->mask_bytes,
+					   i + 2,
+					   wow_pattern->pattern_len);
+		kfree(wow_pattern);
+
+	}
+
+}
+
+int ath9k_suspend(struct ieee80211_hw *hw,
+		  struct cfg80211_wowlan *wowlan)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 wow_triggers_enabled = 0;
+	int ret = 0;
+
+	mutex_lock(&sc->mutex);
+
+	ath_cancel_work(sc);
+	ath_stop_ani(sc);
+	del_timer_sync(&sc->rx_poll_timer);
+
+	if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
+		ath_dbg(common, ANY, "Device not present\n");
+		ret = -EINVAL;
+		goto fail_wow;
+	}
+
+	if (WARN_ON(!wowlan)) {
+		ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
+		ret = -EINVAL;
+		goto fail_wow;
+	}
+
+	if (!device_can_wakeup(sc->dev)) {
+		ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
+		ret = 1;
+		goto fail_wow;
+	}
+
+	/*
+	 * none of the sta vifs are associated
+	 * and we are not currently handling multivif
+	 * cases, for instance we have to seperately
+	 * configure 'keep alive frame' for each
+	 * STA.
+	 */
+
+	if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
+		ath_dbg(common, WOW, "None of the STA vifs are associated\n");
+		ret = 1;
+		goto fail_wow;
+	}
+
+	if (sc->nvifs > 1) {
+		ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
+		ret = 1;
+		goto fail_wow;
+	}
+
+	ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
+
+	ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
+		wow_triggers_enabled);
+
+	ath9k_ps_wakeup(sc);
+
+	ath9k_stop_btcoex(sc);
+
+	/*
+	 * Enable wake up on recieving disassoc/deauth
+	 * frame by default.
+	 */
+	ath9k_wow_add_disassoc_deauth_pattern(sc);
+
+	if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
+		ath9k_wow_add_pattern(sc, wowlan);
+
+	spin_lock_bh(&sc->sc_pcu_lock);
+	/*
+	 * To avoid false wake, we enable beacon miss interrupt only
+	 * when we go to sleep. We save the current interrupt mask
+	 * so we can restore it after the system wakes up
+	 */
+	sc->wow_intr_before_sleep = ah->imask;
+	ah->imask &= ~ATH9K_INT_GLOBAL;
+	ath9k_hw_disable_interrupts(ah);
+	ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
+	ath9k_hw_set_interrupts(ah);
+	ath9k_hw_enable_interrupts(ah);
+
+	spin_unlock_bh(&sc->sc_pcu_lock);
+
+	/*
+	 * we can now sync irq and kill any running tasklets, since we already
+	 * disabled interrupts and not holding a spin lock
+	 */
+	synchronize_irq(sc->irq);
+	tasklet_kill(&sc->intr_tq);
+
+	ath9k_hw_wow_enable(ah, wow_triggers_enabled);
+
+	ath9k_ps_restore(sc);
+	ath_dbg(common, ANY, "WoW enabled in ath9k\n");
+	atomic_inc(&sc->wow_sleep_proc_intr);
+
+fail_wow:
+	mutex_unlock(&sc->mutex);
+	return ret;
+}
+
+int ath9k_resume(struct ieee80211_hw *hw)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 wow_status;
+
+	mutex_lock(&sc->mutex);
+
+	ath9k_ps_wakeup(sc);
+
+	spin_lock_bh(&sc->sc_pcu_lock);
+
+	ath9k_hw_disable_interrupts(ah);
+	ah->imask = sc->wow_intr_before_sleep;
+	ath9k_hw_set_interrupts(ah);
+	ath9k_hw_enable_interrupts(ah);
+
+	spin_unlock_bh(&sc->sc_pcu_lock);
+
+	wow_status = ath9k_hw_wow_wakeup(ah);
+
+	if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
+		/*
+		 * some devices may not pick beacon miss
+		 * as the reason they woke up so we add
+		 * that here for that shortcoming.
+		 */
+		wow_status |= AH_WOW_BEACON_MISS;
+		atomic_dec(&sc->wow_got_bmiss_intr);
+		ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
+	}
+
+	atomic_dec(&sc->wow_sleep_proc_intr);
+
+	if (wow_status) {
+		ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
+			ath9k_hw_wow_event_to_string(wow_status), wow_status);
+	}
+
+	ath_restart_work(sc);
+	ath9k_start_btcoex(sc);
+
+	ath9k_ps_restore(sc);
+	mutex_unlock(&sc->mutex);
+
+	return 0;
+}
+
+void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+	struct ath_softc *sc = hw->priv;
+
+	mutex_lock(&sc->mutex);
+	device_init_wakeup(sc->dev, 1);
+	device_set_wakeup_enable(sc->dev, enabled);
+	mutex_unlock(&sc->mutex);
+}
-- 
1.8.4.1


^ permalink raw reply related

* [PATCH 2/4] ath9k: Add a config option for WoW
From: Sujith Manoharan @ 2013-10-28  7:38 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1382945891-12779-1-git-send-email-sujith@msujith.org>

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 3ffa4ea..30d273c 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -104,6 +104,14 @@ config ATH9K_TX99
 	  be evaluated to meet the RF exposure limits set forth in the
 	  governmental SAR regulations.
 
+config ATH9K_WOW
+	bool "Wake on Wireless LAN support (EXPERIMENTAL)"
+	depends on ATH9K && PM
+	default n
+	---help---
+	  This option enables Wake on Wireless LAN support for certain cards.
+	  Currently, AR9462 is supported.
+
 config ATH9K_LEGACY_RATE_CONTROL
 	bool "Atheros ath9k rate control"
 	depends on ATH9K
-- 
1.8.4.1


^ permalink raw reply related

* Re: [PATCH 4/4] wl1251: spi: add device tree support
From: Kumar Gala @ 2013-10-28  6:37 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Sebastian Reichel, Luciano Coelho, Rob Herring, Pawel Moll,
	Mark Rutland, Stephen Warren, Ian Campbell, Rob Landley,
	Tony Lindgren, Russell King, John W. Linville, Felipe Balbi,
	Sachin Kamat, Greg Kroah-Hartman, Bill Pemberton, devicetree,
	linux-doc, linux-kernel, linux-omap, linux-arm-kernel,
	linux-wireless, netdev
In-Reply-To: <1382890469-25286-5-git-send-email-sre@debian.org>


On Oct 27, 2013, at 11:14 AM, Sebastian Reichel wrote:

> Add device tree support for the spi variant of wl1251
> and document the binding.
> 
> Signed-off-by: Sebastian Reichel <sre@debian.org>
> ---
> .../devicetree/bindings/net/wireless/ti,wl1251.txt | 36 ++++++++++++++++++++++
> drivers/net/wireless/ti/wl1251/spi.c               | 23 ++++++++++----
> 2 files changed, 53 insertions(+), 6 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
> new file mode 100644
> index 0000000..5f8a154
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
> @@ -0,0 +1,36 @@
> +* Texas Instruments wl1251 controller
> +
> +The wl1251 chip can be connected via SPI or via SDIO. The linux
> +kernel currently only supports device tree for the SPI variant.
> +

>From the binding I have no idea what this chip actually does, also we don't normally reference linux kernel support in bindings specs (so please remove it).

However, what would expect the SDIO binding to look like?  Or more specifically, how would you distinguish the SPI vs SDIO binding/connection?  I'm wondering if the compatible should be something like "ti,wl1251-spi" and than the sdio can be "ti,wl1251-sdio"

> +Required properties:
> +- compatible : Should be "ti,wl1251"

reg is not listed as a required prop.

> +- interrupts : Should contain interrupt line
> +- interrupt-parent : Should be the phandle for the interrupt
> +  controller that services interrupts for this device
> +- vio-supply : phandle to regulator providing VIO
> +- power-gpio : GPIO connected to chip's PMEN pin

should be vendor prefixed: ti,power-gpio

> +- For additional required properties on SPI, please consult
> +  Documentation/devicetree/bindings/spi/spi-bus.txt
> +
> +Optional properties:
> +- ti,use-eeprom : If found, configuration will be loaded from eeprom.

can you be a bit more specific on what cfg will be loaded.  Also, is this property a boolean, if so how do I know which eeprom the cfg is loaded from (is it one that is directly connected to the wl1251?

> +
> +Examples:
> +
> +&spi1 {
> +	wl1251_spi@0 {
> +		compatible = "ti,wl1251";
> +
> +		reg = <0>;
> +		spi-max-frequency = <48000000>;
> +		spi-cpol;
> +		spi-cpha;
> +
> +		interrupt-parent = <&gpio2>;
> +		interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
> +
> +		vio-supply = <&vio>;
> +		power-gpio = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */
> +	};
> +};

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


^ permalink raw reply

* I always need a miracle to connect with iwlwifi
From: Felipe Contreras @ 2013-10-28  6:24 UTC (permalink / raw)
  To: linux-wireless Mailing List, ilw, hostap

Hi,

I already reported this problem [1] and I got no feedback whatsoever
at all. The issue keeps happening and I've tried many things.

First of all, when Linux is failing, my phone connects fine, other
computers connect fine, and this machine with Windows 7 as well. I've
tried reloading the driver, rebooting, different module parameters,
nothing works.

I logged a session [2] where I waited 30 minutes for the link to come
up, but it never did. You can see the same thing happening over and
over:

1382936199.582861: nl80211: Association request send successfully
1382936199.797063: nl80211: Event message available
1382936199.797097: nl80211: Delete station e0:1d:3b:46:82:a0
1382936199.797881: nl80211: Event message available
1382936199.797905: nl80211: MLME event 38; timeout with e0:1d:3b:46:82:a0
1382936199.797915: wlan0: Event ASSOC_TIMED_OUT (15) received
1382936199.797920: wlan0: SME: Association timed out
1382936199.797924: Added BSSID e0:1d:3b:46:82:a0 into blacklist

If I reboot the router, it works immediately, another thing that works
is connecting with ad-hoc mode (mode=1), and then back to normal mode
(mode=0).

Here's a log [3] where I tried reloading the module multiple times and
finally tried ad-hoc mode, after which the link came up.

Clearly the Linux kernel has a bug. Can somebody point out what needs
to be done to get this fixed?

Cheers.

[1] http://article.gmane.org/gmane.linux.kernel.wireless.general/108004
[2] http://people.freedesktop.org/~felipec/wpa/wpa-bad-30-min-wait.log
[3] http://people.freedesktop.org/~felipec/wpa/wpa-good-nothing-worked-except-mode-switch.log

-- 
Felipe Contreras

^ permalink raw reply


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