Linux wireless drivers development
 help / color / mirror / Atom feed
* ath6kl_mgmt_tx with NULL chan (was Re: [PATCH 1/2] nl80211: allow sending CMD_FRAME without specifying any frequency)
From: Antonio Quartulli @ 2013-06-03 17:14 UTC (permalink / raw)
  To: Nicolas Cavallari
  Cc: Johannes Berg, linux-wireless, Antonio Quartulli, Kalle Valo
In-Reply-To: <51ACB068.8070006@lri.fr>

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

On Mon, Jun 03, 2013 at 05:04:08PM +0200, Nicolas Cavallari wrote:
> On 03/06/2013 16:59, Johannes Berg wrote:
> > On Mon, 2013-06-03 at 08:39 +0200, Antonio Quartulli wrote:
> >> From: Antonio Quartulli <antonio@open-mesh.com>
> >>
> >> Users may want to send a frame on the current channel
> >> without specifying it.
> >>
> >> Make mgmt_tx pass a NULL channel to mac80211 if none has
> >> been specified by the user.
> > 
> > cfg80211 isn't just a mac80211 frontend ... ;-)
> > 
> > Also, as Nicolas said, ath6kl_mgmt_tx() will crash after this patch if
> > it's called in AP mode w/o a channel, so you need to think about that.
> 
> It will crash unconditionally. All ath6kl_mgmt_tx()'s code paths access
> chan->center_freq at some point.

Hello Nicolas,
I'm also CCing Kalle Valo since get_maintainer.pl told me he is the guy for
these kind of questions :-)

I'm looking at ath6kl_mgmt_tx() in ath6kl/cfg80211.c and I've seen that the
currently "configured" frequency can be obtained by reading the
ath6kl_vif->ch_hint field.

But, is this correct? I couldn't see any real relation between the ch_hint field
and the real frequency (probably because a lot of logic is hidden to the
driver).
I could only understand that the ch_hint field stores the frequency passed as
parameter during the connection, but I have found no guarantee that this is the
really used one.

Can someone please clarify on this?

Cheers,

-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto "Che" Guevara

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

^ permalink raw reply

* using ieee80211_restart_hw()
From: Arend van Spriel @ 2013-06-03 17:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Greene

Hi Johannes,

In brcmsmac a fatal error in the device results in calling 
ieee80211_restart_hw(). This was done under the assumption that mac80211 
would reconfigure everything doing .start(), .add_interface() etc, but 
looking at a log in redhat bugzilla makes me suspicious about that.

The only reason I could find in ieee80211_reconfig is that 
local->open_count would be zero, right?

At the time of the fatal error AMPDU packets were being transmitted so I 
assume local->open_count would *not* be zero as it seems to match the 
state of the netdev interface.

Regards,
Arend

---8<--------------------------------------------------------------
	/* everything else happens only if HW was up & running */
	if (!local->open_count)
		goto wake_up;

	/*
	 * Upon resume hardware can sometimes be goofy due to
	 * various platform / driver / bus issues, so restarting
	 * the device may at times not work immediately. Propagate
	 * the error.
	 */
	res = drv_start(local);



^ permalink raw reply

* Re: [rt2x00-users] [PATCH 1/7] rt2x00: rt2x00dev: use rt2x00dev->tx->limit
From: Jakub Kicinski @ 2013-06-03 17:09 UTC (permalink / raw)
  To: Gabor Juhos; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <1367421455-18463-2-git-send-email-juhosg@openwrt.org>

Hi Gabor!

On Wed,  1 May 2013 17:17:29 +0200, Gabor Juhos wrote:
> The TX data queue is initialized already when
> the rt2x00lib_probe_hw() function is called.
>
> Fetch the number of the queue entries from that
> instead of using the entry_num field of the data
> queue descriptor.
>
> The two values are the same, and the use of the
> rt2x00dev->tx->limit value allows us to get rid
> of a superfluous pointer dereference.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> ---
>  drivers/net/wireless/rt2x00/rt2x00dev.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
> index 90dc143..b287467 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00dev.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
> @@ -1077,7 +1077,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
>   		 */
>  		int kfifo_size =
>  			roundup_pow_of_two(rt2x00dev->ops->tx_queues *
> -					   rt2x00dev->ops->tx->entry_num *
> +					   rt2x00dev->tx->limit *
>  					   sizeof(u32));
>  
>  		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,

Unfortunately this does not work without your "get rid of
static data queue descriptors" series as well.

queue->limit is set when rt2x00lib_start is called, not on
probe. kfifo_alloc will fail with EINVAL here. As a result
support for all rt2x00 devices is broken on wireless-testing.

Maybe you can just post the mentioned series for inclusion?
I have been running with it since you posted it as RFC and
I did not notice any problems so far...

 -- kuba

^ permalink raw reply

* Re: [PATCH] brcmsmac: Reduce log spam in heavy tx, make err print in debug
From: Arend van Spriel @ 2013-06-03 17:07 UTC (permalink / raw)
  To: John Greene; +Cc: linville, linux-wireless
In-Reply-To: <1370267259-19712-1-git-send-email-jogreene@redhat.com>

On 06/03/2013 03:47 PM, John Greene wrote:
> Move message to debug mode to reduce log spam under heavy tx (iperf) load.
> This message prints in ht debug mode only:
> brcms_c_ampdu_dotxstatus_complete: Pkt tx suppressed, illegal channel
> possibly 153

Acked-by: Arend van Spriel <arend@broadcom.com>
> Signed-off-by: John Greene <jogreene@redhat.com>
> ---
>   drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>


^ permalink raw reply

* Re: [PATCH] brcmsmac: Reduce log spam in heavy tx, make err print in debug
From: Arend van Spriel @ 2013-06-03 17:06 UTC (permalink / raw)
  To: Joe Perches; +Cc: John Greene, linville, linux-wireless
In-Reply-To: <1370278476.2025.41.camel@joe-AO722>

On 06/03/2013 06:54 PM, Joe Perches wrote:
> On Mon, 2013-06-03 at 09:47 -0400, John Greene wrote:
>> Move message to debug mode to reduce log spam under heavy tx (iperf) load.
> []
>> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
> []
>> @@ -900,7 +900,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
>>   		if (supr_status) {
>>   			update_rate = false;
>>   			if (supr_status == TX_STATUS_SUPR_BADCH) {
>> -				brcms_err(wlc->hw->d11core,
>> +				brcms_dbg_ht(wlc->hw->d11core,
>>   					  "%s: Pkt tx suppressed, illegal channel possibly %d\n",
>>   					  __func__, CHSPEC_CHANNEL(
>>   					  wlc->default_bss->chanspec));
>
> net_ratelimited instead?

Yes and only when driver debug level is set.

Regards,
Arend



^ permalink raw reply

* Re: [PATCH] brcmsmac: Reduce log spam in heavy tx, make err print in debug
From: Joe Perches @ 2013-06-03 16:54 UTC (permalink / raw)
  To: John Greene; +Cc: linville, arend, linux-wireless
In-Reply-To: <1370267259-19712-1-git-send-email-jogreene@redhat.com>

On Mon, 2013-06-03 at 09:47 -0400, John Greene wrote:
> Move message to debug mode to reduce log spam under heavy tx (iperf) load.
[]
> diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
[]
> @@ -900,7 +900,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
>  		if (supr_status) {
>  			update_rate = false;
>  			if (supr_status == TX_STATUS_SUPR_BADCH) {
> -				brcms_err(wlc->hw->d11core,
> +				brcms_dbg_ht(wlc->hw->d11core,
>  					  "%s: Pkt tx suppressed, illegal channel possibly %d\n",
>  					  __func__, CHSPEC_CHANNEL(
>  					  wlc->default_bss->chanspec));

net_ratelimited instead?



^ permalink raw reply

* [PATCH 2/2] mac80211: expire mesh peers based on mesh configuration
From: Colleen Twitty @ 2013-06-03 16:53 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wirelss, open80211s
In-Reply-To: <1370278420-10135-1-git-send-email-colleen@cozybit.com>

The time it takes to see the peer link expire may differ
by a minute since sta_expire() is run once a minute as a
mesh housekeeping task.

Signed-off-by: Colleen Twitty <colleen@cozybit.com>
---
 net/mac80211/cfg.c  |    2 ++
 net/mac80211/mesh.c |    2 +-
 net/mac80211/mesh.h |    1 -
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1a89c80..97bb950 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1856,6 +1856,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
 	if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask))
 		conf->dot11MeshAwakeWindowDuration =
 			nconf->dot11MeshAwakeWindowDuration;
+	if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask))
+		conf->plink_timeout = nconf->plink_timeout;
 	ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
 	return 0;
 }
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6952760..37a0533 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -573,7 +573,7 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 	u32 changed;
 
-	ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
+	ieee80211_sta_expire(sdata, ifmsh->mshcfg.plink_timeout * HZ);
 	mesh_path_expire(sdata);
 
 	changed = mesh_accept_plinks_update(sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index da15877..faf6ce4 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -188,7 +188,6 @@ struct mesh_rmc {
 	u32 idx_mask;
 };
 
-#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
 #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
 
 #define MESH_PATH_EXPIRE (600 * HZ)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/2] {nl,cfg}80211: make peer link expiration time configurable
From: Colleen Twitty @ 2013-06-03 16:53 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wirelss, open80211s

If a STA has a peer that it hasn't seen any tx activity
from for a certain length of time, the peer link is
expired. This means the inactive STA is removed from the
list of peers and that STA is not considered a peer again
unless it re-peers.  Previously, this inactivity time was
always 30 minutes.  Now, add it to the mesh configuration
and allow it to be configured.  Retain 30 minutes as a
default value.

Signed-off-by: Colleen Twitty <colleen@cozybit.com>
---
 include/net/cfg80211.h       |    4 ++++
 include/uapi/linux/nl80211.h |    5 +++++
 net/wireless/mesh.c          |    2 ++
 net/wireless/nl80211.c       |    8 +++++++-
 4 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 26b5b69..684fa2e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1108,6 +1108,9 @@ struct bss_parameters {
  *	setting for new peer links.
  * @dot11MeshAwakeWindowDuration: The duration in TUs the STA will remain awake
  *	after transmitting its beacon.
+ * @plink_timeout: If no tx activity is seen from a STA we've established
+ *	peering with for longer than this time (in seconds), then remove it
+ *	from the STA's list of peers.  Default is 30 minutes.
  */
 struct mesh_config {
 	u16 dot11MeshRetryTimeout;
@@ -1137,6 +1140,7 @@ struct mesh_config {
 	u16 dot11MeshHWMPconfirmationInterval;
 	enum nl80211_mesh_power_mode power_mode;
 	u16 dot11MeshAwakeWindowDuration;
+	u32 plink_timeout;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d1e48b5..302bc4b 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2559,6 +2559,10 @@ enum nl80211_mesh_power_mode {
  *
  * @NL80211_MESHCONF_AWAKE_WINDOW: awake window duration (in TUs)
  *
+ * @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've
+ *	established peering with for longer than this time (in seconds), then
+ *	remove it from the STA's list of peers.  Default is 30 minutes.
+ *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
  */
 enum nl80211_meshconf_params {
@@ -2590,6 +2594,7 @@ enum nl80211_meshconf_params {
 	NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
 	NL80211_MESHCONF_POWER_MODE,
 	NL80211_MESHCONF_AWAKE_WINDOW,
+	NL80211_MESHCONF_PLINK_TIMEOUT,
 
 	/* keep last */
 	__NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 0bb93f3..71e981e 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -18,6 +18,7 @@
 #define MESH_PATH_TO_ROOT_TIMEOUT      6000
 #define MESH_ROOT_INTERVAL     5000
 #define MESH_ROOT_CONFIRMATION_INTERVAL 2000
+#define MESH_DEFAULT_PLINK_TIMEOUT	1800 /* timeout in seconds */
 
 /*
  * Minimum interval between two consecutive PREQs originated by the same
@@ -75,6 +76,7 @@ const struct mesh_config default_mesh_config = {
 	.dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
 	.power_mode = NL80211_MESH_POWER_ACTIVE,
 	.dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
+	.plink_timeout = MESH_DEFAULT_PLINK_TIMEOUT,
 };
 
 const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index dfdb5e6..0bb3e65 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4585,7 +4585,9 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
 	    nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
 			cur_params.power_mode) ||
 	    nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
-			cur_params.dot11MeshAwakeWindowDuration))
+			cur_params.dot11MeshAwakeWindowDuration) ||
+	    nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
+			cur_params.plink_timeout))
 		goto nla_put_failure;
 	nla_nest_end(msg, pinfoattr);
 	genlmsg_end(msg, hdr);
@@ -4626,6 +4628,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
 	[NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
 	[NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
 	[NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
+	[NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
 };
 
 static const struct nla_policy
@@ -4762,6 +4765,9 @@ do {									    \
 	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
 				  0, 65535, mask,
 				  NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
+	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 1, 0xffffffff,
+				  mask, NL80211_MESHCONF_PLINK_TIMEOUT,
+				  nla_get_u32);
 	if (mask_out)
 		*mask_out = mask;
 
-- 
1.7.9.5


^ permalink raw reply related

* RE: [PATCH v2 2/2] cfg80211/nl80211: Add packet coalesce support
From: Amitkumar Karwar @ 2013-06-03 16:47 UTC (permalink / raw)
  To: 'Johannes Berg'
  Cc: Bing Zhao, linux-wireless@vger.kernel.org, Luis R. Rodriguez,
	Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian,
	Luciano Coelho
In-Reply-To: <1370273291.8227.24.camel@jlt4.sipsolutions.net>

Hi Johannes,

> Hi,
> 
> sorry for the late reply. I did see you sent another version, but wanted
> to comment here anyway.
> 
> > > This is curious, you already discard those that you don't care about
> by
> > > way of multicast filtering, no? What's the added advantage here? Would
> > > you coalesce interrupts for those packets that pass the filter(s)?
> >
> > Yes. we don't want to simply discard those packets, because few of
> > them may be useful for the host.
> > The advantage here is instead of getting random per packet receive
> > interrupts, host receives multiple buffered packets with a single
> > receive interrupt.
> 
> I guess that makes some sense.
> 
> > > Actually, you should probably make that a pointer, then it can be NULL
> > > for drivers not supporting it, and static const for those that do.
> Means
> > > you should make it a const pointer, of course.
> > >
> > > Userspace can tell by checking if the support is advertised.
> >
> > We will use following condition to check if driver is not supporting
> > the feature. (wowlan code does the same thing)
> >
> > "if (!dev->wiphy.coalesce.n_patterns || !dev->wiphy.coalesce.n_rules)"
> 
> Hmm. I think wowlan should probably be changed though, no need to make
> the struct larger just for this, right? Not all drivers are going to
> support it.
> 
> For WoWLAN I'm going to apply this:
> http://p.sipsolutions.net/fa808e0722a7624a.txt
> 

This looks good. We don't need to unnecessarily allocate space in wiphy. We will make similar changes for coalesce.

> > > This is bad. You leave rdev->coalesce assigned, but it's completely
> > > invalid data. IMHO you should use a temporary variable and only assign
> > > it when it's fully parsed, freeing it if not. That way, you also don't
> > > kill old values when new invalid values are parsed.
> >
> > "iw coalesce add" command adds one coalesce rule at a time. "iw
> > coalesce disable" command removes all configured rules.
> 
> Can you please change this to "iw coalesce set" and make it set all the
> rules in one?

"iw coalesce add" was used, because command for adding multiple rules at the same time will be a bit lengthy(user will need to enter multiple lists of packet patterns) and syntax check in iw will also need some efforts. 

> Otherwise you're going to have very awkward races and need
> to always clear etc. The code would also be easier, though obviously
> you'd need to be able to specify multiple rules at the same time.

For "iw coalesce set" also user needs to always clear the settings using "iw coalesce disable". Also similar to "coalesce set", for "coalesce add" we clear the settings and free allocations while unloading the driver.

Please let us know if you prefer "coalesce set" over "coalesce add".

Thanks,
Amit

> 
> johannes


^ permalink raw reply

* Re: [ath9k-devel] AR9287; WiFi AP Mode - Increase interbeacon duration of 100ms
From: Ben Greear @ 2013-06-03 16:16 UTC (permalink / raw)
  To: sandeep suresh; +Cc: Adrian Chadd, ath9k-devel, linux-wireless@vger.kernel.org
In-Reply-To: <1370254531.75129.YahooMailNeo@web193504.mail.sg3.yahoo.com>

On 06/03/2013 03:15 AM, sandeep suresh wrote:
> Hello All,
>      Gentle reminder; really will be greatful, if you can give me some directions on this, Please.
> Regards
> Sandeep
>
> *From:* sandeep suresh <sandeep.suresh@yahoo.co.in>
> *To:* Adrian Chadd <adrian@freebsd.org>; ath9k-devel <ath9k-devel@lists.ath9k.org>
> *Cc:* "linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>
> *Sent:* Monday, 27 May 2013 1:40 PM
> *Subject:* AR9287; WiFi AP Mode - Increase interbeacon duration of 100ms
>
> Hello All,
>      This is regarding the inter beacon timing for AR9287 WiFi module when configured in WiFi Access Point mode. In this mode, the beacons are generated every
> 100ms by the WiFi AP. I have the following questions:
> 1. As per documentation available on the internet, the minimum inter beacon timing is 100ms. But can we increase the the inter beacon timing above this value?
> say 250ms, 500ms etc
> 2. As per standard, does increase in inter beacon time > 100ms, have any impact on the WiFi Clients connected to AR9287 WiFi AP? Even though I might test with
> some WiFi clients without any side effects but there may be some WiFi clients (which I might be unaware of )that might not work.
> 3. Has anyone attempted to do this? Please let me know if you have any observations on this?

We have been using a default of 250ms beacon timer for years in our ath9k APs.  Seems to work
just fine, but we mostly use them for internal testing with other ath9k systems acting as
the stations.

Thanks,
Ben

> Thanks & regards
> Sandeep
>
>
>
>
> _______________________________________________
> ath9k-devel mailing list
> ath9k-devel@lists.ath9k.org
> https://lists.ath9k.org/mailman/listinfo/ath9k-devel
>


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* Re: [PATCH] Fix channel index in WMI PCP start
From: Vladimir Kondratiev @ 2013-06-03 15:50 UTC (permalink / raw)
  To: Kirshenbaum Erez; +Cc: linux-wireless
In-Reply-To: <1370251153-13791-1-git-send-email-erezk@wilocity.com>

On Monday, June 03, 2013 12:19:13 PM Kirshenbaum Erez wrote:
> Signed-off-by: Kirshenbaum Erez <erezk@wilocity.com>
> ---
>  drivers/net/wireless/ath/wil6210/wmi.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
> index 45b04e3..26f760a 100644
> --- a/drivers/net/wireless/ath/wil6210/wmi.c
> +++ b/drivers/net/wireless/ath/wil6210/wmi.c
> @@ -724,7 +724,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
>  		.bcon_interval = cpu_to_le16(bi),
>  		.network_type = wmi_nettype,
>  		.disable_sec_offload = 1,
> -		.channel = chan,
> +		.channel = chan-1,
>  	};

Fix for this already merged, see commit
adc2d12 - wil6210: channel off by 1

To make sure you are aligned, please, prior to sending patch,
rebase on 'master' from
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git

>  	struct {
>  		struct wil6210_mbox_hdr_wmi wmi;
> @@ -733,9 +733,9 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
>  
>  	if (!wil->secure_pcp)
>  		cmd.disable_sec = 1;
> -
> +	/* This may take some time (FW set/calibrate new freq) */
>  	rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd),
> -		      WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 100);
> +		      WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000);
>  	if (rc)
>  		return rc;
This chunk does not belong to this patch, yes?

Thanks, Vladimir

^ permalink raw reply

* [PATCH v2] cfg80211: take WoWLAN support information out of wiphy struct
From: Johannes Berg @ 2013-06-03 15:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

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

There's no need to take up the space for devices that don't
support WoWLAN, and most drivers can even make the support
data static const (except where it's modified at runtime.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c  | 24 ++++++++-----
 drivers/net/wireless/ath/ath9k/init.c       | 20 ++++++-----
 drivers/net/wireless/iwlwifi/dvm/dev.h      |  3 ++
 drivers/net/wireless/iwlwifi/dvm/mac80211.c | 17 ++++-----
 drivers/net/wireless/iwlwifi/mvm/mac80211.c | 26 +++++++-------
 drivers/net/wireless/iwlwifi/mvm/mvm.h      |  1 +
 drivers/net/wireless/mwifiex/cfg80211.c     | 16 ++++++---
 drivers/net/wireless/ti/wlcore/main.c       | 19 +++++-----
 include/net/cfg80211.h                      |  2 +-
 net/mac80211/main.c                         |  3 +-
 net/wireless/core.c                         | 20 ++++++-----
 net/wireless/nl80211.c                      | 56 ++++++++++++++---------------
 12 files changed, 115 insertions(+), 92 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 5c9736a..f7995b2 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -3679,6 +3679,20 @@ err:
 	return NULL;
 }
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT |
+		 WIPHY_WOWLAN_DISCONNECT |
+		 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
+		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+		 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
+		 WIPHY_WOWLAN_4WAY_HANDSHAKE,
+	.n_patterns = WOW_MAX_FILTERS_PER_LIST,
+	.pattern_min_len = 1,
+	.pattern_max_len = WOW_PATTERN_SIZE,
+};
+#endif
+
 int ath6kl_cfg80211_init(struct ath6kl *ar)
 {
 	struct wiphy *wiphy = ar->wiphy;
@@ -3772,15 +3786,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
 	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 
 #ifdef CONFIG_PM
-	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-			      WIPHY_WOWLAN_DISCONNECT |
-			      WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
-			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-			      WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
-			      WIPHY_WOWLAN_4WAY_HANDSHAKE;
-	wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
-	wiphy->wowlan.pattern_min_len = 1;
-	wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
+	wiphy->wowlan = &ath6kl_wowlan_support;
 #endif
 
 	wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 0237b28..f993362 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -755,6 +755,15 @@ static const struct ieee80211_iface_combination if_comb[] = {
 	}
 };
 
+#ifdef CONFIG_PM
+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;
@@ -797,15 +806,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 #ifdef CONFIG_PM_SLEEP
 
 	if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
-	    device_can_wakeup(sc->dev)) {
-
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT;
-		hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
-		hw->wiphy->wowlan.pattern_min_len = 1;
-		hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
-
-	}
+	    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);
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 71ea775..e71acfd 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -870,6 +870,9 @@ struct iwl_priv {
 	__le64 replay_ctr;
 	__le16 last_seq_ctl;
 	bool have_rekey_data;
+#ifdef CONFIG_PM_SLEEP
+	struct wiphy_wowlan_support wowlan_support;
+#endif
 
 	/* device_pointers: pointers to ucode event tables */
 	struct {
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index cab23af..661b5e7 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -208,20 +208,21 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 	    priv->trans->ops->d3_suspend &&
 	    priv->trans->ops->d3_resume &&
 	    device_can_wakeup(priv->trans->dev)) {
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT |
-					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
-					  WIPHY_WOWLAN_RFKILL_RELEASE;
+		priv->wowlan_support.flags = WIPHY_WOWLAN_MAGIC_PKT |
+					     WIPHY_WOWLAN_DISCONNECT |
+					     WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+					     WIPHY_WOWLAN_RFKILL_RELEASE;
 		if (!iwlwifi_mod_params.sw_crypto)
-			hw->wiphy->wowlan.flags |=
+			priv->wowlan_support.flags |=
 				WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
 				WIPHY_WOWLAN_GTK_REKEY_FAILURE;
 
-		hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
-		hw->wiphy->wowlan.pattern_min_len =
+		priv->wowlan_support.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
+		priv->wowlan_support.pattern_min_len =
 					IWLAGN_WOWLAN_MIN_PATTERN_LEN;
-		hw->wiphy->wowlan.pattern_max_len =
+		priv->wowlan_support.pattern_max_len =
 					IWLAGN_WOWLAN_MAX_PATTERN_LEN;
+		hw->wiphy->wowlan = &priv->wowlan_support;
 	}
 #endif
 
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index dd158ec..827fa64 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -222,20 +222,20 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	    mvm->trans->ops->d3_suspend &&
 	    mvm->trans->ops->d3_resume &&
 	    device_can_wakeup(mvm->trans->dev)) {
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT |
-					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
-					  WIPHY_WOWLAN_RFKILL_RELEASE;
+		mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
+				    WIPHY_WOWLAN_DISCONNECT |
+				    WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+				    WIPHY_WOWLAN_RFKILL_RELEASE;
 		if (!iwlwifi_mod_params.sw_crypto)
-			hw->wiphy->wowlan.flags |=
-				WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-				WIPHY_WOWLAN_GTK_REKEY_FAILURE |
-				WIPHY_WOWLAN_4WAY_HANDSHAKE;
-
-		hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
-		hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
-		hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
-		hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
+			mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+					     WIPHY_WOWLAN_GTK_REKEY_FAILURE |
+					     WIPHY_WOWLAN_4WAY_HANDSHAKE;
+
+		mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
+		mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
+		mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
+		mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
+		hw->wiphy->wowlan = &mvm->wowlan;
 	}
 #endif
 
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 8269bc5..b62a948 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -336,6 +336,7 @@ struct iwl_mvm {
 	struct ieee80211_vif *p2p_device_vif;
 
 #ifdef CONFIG_PM_SLEEP
+	struct wiphy_wowlan_support wowlan;
 	int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
 #endif
 
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index e42b266..6007789 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2426,6 +2426,16 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
 #endif
 };
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT,
+	.n_patterns = MWIFIEX_MAX_FILTERS,
+	.pattern_min_len = 1,
+	.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
+	.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
+};
+#endif
+
 /*
  * This function registers the device with CFG802.11 subsystem.
  *
@@ -2483,11 +2493,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
 	wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
 
 #ifdef CONFIG_PM
-	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
-	wiphy->wowlan.n_patterns = MWIFIEX_MAX_FILTERS;
-	wiphy->wowlan.pattern_min_len = 1;
-	wiphy->wowlan.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN;
-	wiphy->wowlan.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN;
+	wiphy->wowlan = &mwifiex_wowlan_support;
 #endif
 
 	wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 953111a..796928b 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -6018,6 +6018,15 @@ int wlcore_free_hw(struct wl1271 *wl)
 }
 EXPORT_SYMBOL_GPL(wlcore_free_hw);
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support wlcore_wowlan_support = {
+	.flags = WIPHY_WOWLAN_ANY,
+	.n_patterns = WL1271_MAX_RX_FILTERS,
+	.pattern_min_len = 1,
+	.pattern_max_len = WL1271_RX_FILTER_MAX_PATTERN_SIZE,
+};
+#endif
+
 static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 {
 	struct wl1271 *wl = context;
@@ -6071,14 +6080,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	if (!ret) {
 		wl->irq_wake_enabled = true;
 		device_init_wakeup(wl->dev, 1);
-		if (pdata->pwr_in_suspend) {
-			wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
-			wl->hw->wiphy->wowlan.n_patterns =
-				WL1271_MAX_RX_FILTERS;
-			wl->hw->wiphy->wowlan.pattern_min_len = 1;
-			wl->hw->wiphy->wowlan.pattern_max_len =
-				WL1271_RX_FILTER_MAX_PATTERN_SIZE;
-		}
+		if (pdata->pwr_in_suspend)
+			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
 	}
 #endif
 	disable_irq(wl->irq);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6dd1959..6169fca 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2654,7 +2654,7 @@ struct wiphy {
 	u32 hw_version;
 
 #ifdef CONFIG_PM
-	struct wiphy_wowlan_support wowlan;
+	const struct wiphy_wowlan_support *wowlan;
 	struct cfg80211_wowlan *wowlan_config;
 #endif
 
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1998f14..626c83c 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -686,8 +686,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		return -EINVAL;
 
 #ifdef CONFIG_PM
-	if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) &&
-	    (!local->ops->suspend || !local->ops->resume))
+	if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume))
 		return -EINVAL;
 #endif
 
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 41cec17..f553b94 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -449,8 +449,13 @@ int wiphy_register(struct wiphy *wiphy)
 	u16 ifmodes = wiphy->interface_modes;
 
 #ifdef CONFIG_PM
-	if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
-		    !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
+	if (WARN_ON(wiphy->wowlan &&
+		    (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
+		    !(wiphy->wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
+		return -EINVAL;
+	if (WARN_ON(wiphy->wowlan &&
+		    !wiphy->wowlan->flags && !wiphy->wowlan->n_patterns &&
+		    !wiphy->wowlan->tcp))
 		return -EINVAL;
 #endif
 
@@ -540,12 +545,11 @@ int wiphy_register(struct wiphy *wiphy)
 	}
 
 #ifdef CONFIG_PM
-	if (rdev->wiphy.wowlan.n_patterns) {
-		if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
-			    rdev->wiphy.wowlan.pattern_min_len >
-			    rdev->wiphy.wowlan.pattern_max_len))
-			return -EINVAL;
-	}
+	if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns &&
+		    (!rdev->wiphy.wowlan->pattern_min_len ||
+		     rdev->wiphy.wowlan->pattern_min_len >
+				rdev->wiphy.wowlan->pattern_max_len)))
+		return -EINVAL;
 #endif
 
 	/* check and set up bitrates */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 31d265f..34cac2f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -908,7 +908,7 @@ nla_put_failure:
 static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
 					struct sk_buff *msg)
 {
-	const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
+	const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
 	struct nlattr *nl_tcp;
 
 	if (!tcp)
@@ -951,37 +951,37 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
 {
 	struct nlattr *nl_wowlan;
 
-	if (!dev->wiphy.wowlan.flags && !dev->wiphy.wowlan.n_patterns)
+	if (!dev->wiphy.wowlan)
 		return 0;
 
 	nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
 	if (!nl_wowlan)
 		return -ENOBUFS;
 
-	if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) &&
+	if (((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
 		return -ENOBUFS;
 
-	if (dev->wiphy.wowlan.n_patterns) {
+	if (dev->wiphy.wowlan->n_patterns) {
 		struct nl80211_wowlan_pattern_support pat = {
-			.max_patterns = dev->wiphy.wowlan.n_patterns,
-			.min_pattern_len = dev->wiphy.wowlan.pattern_min_len,
-			.max_pattern_len = dev->wiphy.wowlan.pattern_max_len,
-			.max_pkt_offset = dev->wiphy.wowlan.max_pkt_offset,
+			.max_patterns = dev->wiphy.wowlan->n_patterns,
+			.min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
+			.max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
+			.max_pkt_offset = dev->wiphy.wowlan->max_pkt_offset,
 		};
 
 		if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
@@ -7580,8 +7580,7 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
 	void *hdr;
 	u32 size = NLMSG_DEFAULT_SIZE;
 
-	if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
-	    !rdev->wiphy.wowlan.tcp)
+	if (!rdev->wiphy.wowlan)
 		return -EOPNOTSUPP;
 
 	if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
@@ -7654,7 +7653,7 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 	u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
 	int err, port;
 
-	if (!rdev->wiphy.wowlan.tcp)
+	if (!rdev->wiphy.wowlan->tcp)
 		return -EINVAL;
 
 	err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
@@ -7674,16 +7673,16 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 		return -EINVAL;
 
 	data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
-	if (data_size > rdev->wiphy.wowlan.tcp->data_payload_max)
+	if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
 		return -EINVAL;
 
 	if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
-			rdev->wiphy.wowlan.tcp->data_interval_max ||
+			rdev->wiphy.wowlan->tcp->data_interval_max ||
 	    nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
 		return -EINVAL;
 
 	wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
-	if (wake_size > rdev->wiphy.wowlan.tcp->wake_payload_max)
+	if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
 		return -EINVAL;
 
 	wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
@@ -7698,13 +7697,13 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 
 		if (!tok->len || tokens_size % tok->len)
 			return -EINVAL;
-		if (!rdev->wiphy.wowlan.tcp->tok)
+		if (!rdev->wiphy.wowlan->tcp->tok)
 			return -EINVAL;
-		if (tok->len > rdev->wiphy.wowlan.tcp->tok->max_len)
+		if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
 			return -EINVAL;
-		if (tok->len < rdev->wiphy.wowlan.tcp->tok->min_len)
+		if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
 			return -EINVAL;
-		if (tokens_size > rdev->wiphy.wowlan.tcp->tok->bufsize)
+		if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
 			return -EINVAL;
 		if (tok->offset + tok->len > data_size)
 			return -EINVAL;
@@ -7712,7 +7711,7 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 
 	if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
 		seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
-		if (!rdev->wiphy.wowlan.tcp->seq)
+		if (!rdev->wiphy.wowlan->tcp->seq)
 			return -EINVAL;
 		if (seq->len == 0 || seq->len > 4)
 			return -EINVAL;
@@ -7793,12 +7792,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
 	struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
 	struct cfg80211_wowlan new_triggers = {};
 	struct cfg80211_wowlan *ntrig;
-	struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
+	struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
 	int err, i;
 	bool prev_enabled = rdev->wiphy.wowlan_config;
 
-	if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
-	    !rdev->wiphy.wowlan.tcp)
+	if (!wowlan)
 		return -EOPNOTSUPP;
 
 	if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
-- 
1.8.0


^ permalink raw reply related

* Re: pull request: bluetooth 2013-05-30
From: John W. Linville @ 2013-05-31 16:58 UTC (permalink / raw)
  To: Gustavo Padovan, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20130530225232.GB14083@joana>

On Thu, May 30, 2013 at 07:52:32PM -0300, Gustavo Padovan wrote:
> Hi John,
> 
> The following patches are important bug fixes for 3.10, plus the support for a
> new device. We do have three fixes from Johan. The first one is a fix to avoid
> LE-only devices to rely on the (inexistent) extended features data. The second
> patch fixes length checks on incoming L2CAP signalling PDUs so we can discard
> PDU whose size doesn't match the one reported in the header.
> The last one fixes the handling of power on failures, we now report proper
> errors to mgmt when hci_dev_open().
> 
> Please pull or let me know of any issues! Thanks.
> 
> 	Gustavo
> 
> ---
> 
> The following changes since commit f942d116b80feb3ae618a0d8ce2df6e853526d3c:
> 
>   brcmsmac: fix regression observed in 3.10-rc1 (2013-05-29 14:46:51 -0400)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth master
> 
> for you to fetch changes up to 0f9e216b0e12971af8a1d39c98c353c76533283b:
> 
>   Bluetooth: Fix mgmt handling of power on failures (2013-05-30 18:36:08 -0300)

Pulling now...

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

^ permalink raw reply

* [PATCH] cfg80211: take WoWLAN support information out of wiphy struct
From: Johannes Berg @ 2013-06-03 15:28 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

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

There's no need to take up the space for devices that don't
support WoWLAN, and most drivers can even make the support
data static const (except where it's modified at runtime.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c  | 24 ++++++++-----
 drivers/net/wireless/ath/ath9k/init.c       | 20 ++++++-----
 drivers/net/wireless/iwlwifi/dvm/dev.h      |  3 ++
 drivers/net/wireless/iwlwifi/dvm/mac80211.c | 17 ++++-----
 drivers/net/wireless/iwlwifi/mvm/mac80211.c | 26 +++++++-------
 drivers/net/wireless/iwlwifi/mvm/mvm.h      |  1 +
 drivers/net/wireless/mwifiex/cfg80211.c     | 16 ++++++---
 drivers/net/wireless/ti/wlcore/main.c       | 19 +++++-----
 include/net/cfg80211.h                      |  2 +-
 net/wireless/core.c                         | 20 ++++++-----
 net/wireless/nl80211.c                      | 56 ++++++++++++++---------------
 11 files changed, 114 insertions(+), 90 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 5c9736a..f7995b2 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -3679,6 +3679,20 @@ err:
 	return NULL;
 }
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT |
+		 WIPHY_WOWLAN_DISCONNECT |
+		 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
+		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+		 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
+		 WIPHY_WOWLAN_4WAY_HANDSHAKE,
+	.n_patterns = WOW_MAX_FILTERS_PER_LIST,
+	.pattern_min_len = 1,
+	.pattern_max_len = WOW_PATTERN_SIZE,
+};
+#endif
+
 int ath6kl_cfg80211_init(struct ath6kl *ar)
 {
 	struct wiphy *wiphy = ar->wiphy;
@@ -3772,15 +3786,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
 	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 
 #ifdef CONFIG_PM
-	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-			      WIPHY_WOWLAN_DISCONNECT |
-			      WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
-			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-			      WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
-			      WIPHY_WOWLAN_4WAY_HANDSHAKE;
-	wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
-	wiphy->wowlan.pattern_min_len = 1;
-	wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
+	wiphy->wowlan = &ath6kl_wowlan_support;
 #endif
 
 	wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 0237b28..f993362 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -755,6 +755,15 @@ static const struct ieee80211_iface_combination if_comb[] = {
 	}
 };
 
+#ifdef CONFIG_PM
+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;
@@ -797,15 +806,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 #ifdef CONFIG_PM_SLEEP
 
 	if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
-	    device_can_wakeup(sc->dev)) {
-
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT;
-		hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
-		hw->wiphy->wowlan.pattern_min_len = 1;
-		hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
-
-	}
+	    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);
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 71ea775..e71acfd 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -870,6 +870,9 @@ struct iwl_priv {
 	__le64 replay_ctr;
 	__le16 last_seq_ctl;
 	bool have_rekey_data;
+#ifdef CONFIG_PM_SLEEP
+	struct wiphy_wowlan_support wowlan_support;
+#endif
 
 	/* device_pointers: pointers to ucode event tables */
 	struct {
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index cab23af..661b5e7 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -208,20 +208,21 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 	    priv->trans->ops->d3_suspend &&
 	    priv->trans->ops->d3_resume &&
 	    device_can_wakeup(priv->trans->dev)) {
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT |
-					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
-					  WIPHY_WOWLAN_RFKILL_RELEASE;
+		priv->wowlan_support.flags = WIPHY_WOWLAN_MAGIC_PKT |
+					     WIPHY_WOWLAN_DISCONNECT |
+					     WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+					     WIPHY_WOWLAN_RFKILL_RELEASE;
 		if (!iwlwifi_mod_params.sw_crypto)
-			hw->wiphy->wowlan.flags |=
+			priv->wowlan_support.flags |=
 				WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
 				WIPHY_WOWLAN_GTK_REKEY_FAILURE;
 
-		hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
-		hw->wiphy->wowlan.pattern_min_len =
+		priv->wowlan_support.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
+		priv->wowlan_support.pattern_min_len =
 					IWLAGN_WOWLAN_MIN_PATTERN_LEN;
-		hw->wiphy->wowlan.pattern_max_len =
+		priv->wowlan_support.pattern_max_len =
 					IWLAGN_WOWLAN_MAX_PATTERN_LEN;
+		hw->wiphy->wowlan = &priv->wowlan_support;
 	}
 #endif
 
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index dd158ec..827fa64 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -222,20 +222,20 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 	    mvm->trans->ops->d3_suspend &&
 	    mvm->trans->ops->d3_resume &&
 	    device_can_wakeup(mvm->trans->dev)) {
-		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-					  WIPHY_WOWLAN_DISCONNECT |
-					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
-					  WIPHY_WOWLAN_RFKILL_RELEASE;
+		mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
+				    WIPHY_WOWLAN_DISCONNECT |
+				    WIPHY_WOWLAN_EAP_IDENTITY_REQ |
+				    WIPHY_WOWLAN_RFKILL_RELEASE;
 		if (!iwlwifi_mod_params.sw_crypto)
-			hw->wiphy->wowlan.flags |=
-				WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-				WIPHY_WOWLAN_GTK_REKEY_FAILURE |
-				WIPHY_WOWLAN_4WAY_HANDSHAKE;
-
-		hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
-		hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
-		hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
-		hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
+			mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+					     WIPHY_WOWLAN_GTK_REKEY_FAILURE |
+					     WIPHY_WOWLAN_4WAY_HANDSHAKE;
+
+		mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
+		mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
+		mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
+		mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
+		hw->wiphy->wowlan = &mvm->wowlan;
 	}
 #endif
 
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 8269bc5..b62a948 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -336,6 +336,7 @@ struct iwl_mvm {
 	struct ieee80211_vif *p2p_device_vif;
 
 #ifdef CONFIG_PM_SLEEP
+	struct wiphy_wowlan_support wowlan;
 	int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
 #endif
 
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index e42b266..6007789 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2426,6 +2426,16 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
 #endif
 };
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
+	.flags = WIPHY_WOWLAN_MAGIC_PKT,
+	.n_patterns = MWIFIEX_MAX_FILTERS,
+	.pattern_min_len = 1,
+	.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
+	.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN,
+};
+#endif
+
 /*
  * This function registers the device with CFG802.11 subsystem.
  *
@@ -2483,11 +2493,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
 	wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
 
 #ifdef CONFIG_PM
-	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
-	wiphy->wowlan.n_patterns = MWIFIEX_MAX_FILTERS;
-	wiphy->wowlan.pattern_min_len = 1;
-	wiphy->wowlan.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN;
-	wiphy->wowlan.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN;
+	wiphy->wowlan = &mwifiex_wowlan_support;
 #endif
 
 	wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 953111a..796928b 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -6018,6 +6018,15 @@ int wlcore_free_hw(struct wl1271 *wl)
 }
 EXPORT_SYMBOL_GPL(wlcore_free_hw);
 
+#ifdef CONFIG_PM
+static const struct wiphy_wowlan_support wlcore_wowlan_support = {
+	.flags = WIPHY_WOWLAN_ANY,
+	.n_patterns = WL1271_MAX_RX_FILTERS,
+	.pattern_min_len = 1,
+	.pattern_max_len = WL1271_RX_FILTER_MAX_PATTERN_SIZE,
+};
+#endif
+
 static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 {
 	struct wl1271 *wl = context;
@@ -6071,14 +6080,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	if (!ret) {
 		wl->irq_wake_enabled = true;
 		device_init_wakeup(wl->dev, 1);
-		if (pdata->pwr_in_suspend) {
-			wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
-			wl->hw->wiphy->wowlan.n_patterns =
-				WL1271_MAX_RX_FILTERS;
-			wl->hw->wiphy->wowlan.pattern_min_len = 1;
-			wl->hw->wiphy->wowlan.pattern_max_len =
-				WL1271_RX_FILTER_MAX_PATTERN_SIZE;
-		}
+		if (pdata->pwr_in_suspend)
+			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
 	}
 #endif
 	disable_irq(wl->irq);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6dd1959..6169fca 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2654,7 +2654,7 @@ struct wiphy {
 	u32 hw_version;
 
 #ifdef CONFIG_PM
-	struct wiphy_wowlan_support wowlan;
+	const struct wiphy_wowlan_support *wowlan;
 	struct cfg80211_wowlan *wowlan_config;
 #endif
 
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 41cec17..f553b94 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -449,8 +449,13 @@ int wiphy_register(struct wiphy *wiphy)
 	u16 ifmodes = wiphy->interface_modes;
 
 #ifdef CONFIG_PM
-	if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
-		    !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
+	if (WARN_ON(wiphy->wowlan &&
+		    (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
+		    !(wiphy->wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
+		return -EINVAL;
+	if (WARN_ON(wiphy->wowlan &&
+		    !wiphy->wowlan->flags && !wiphy->wowlan->n_patterns &&
+		    !wiphy->wowlan->tcp))
 		return -EINVAL;
 #endif
 
@@ -540,12 +545,11 @@ int wiphy_register(struct wiphy *wiphy)
 	}
 
 #ifdef CONFIG_PM
-	if (rdev->wiphy.wowlan.n_patterns) {
-		if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
-			    rdev->wiphy.wowlan.pattern_min_len >
-			    rdev->wiphy.wowlan.pattern_max_len))
-			return -EINVAL;
-	}
+	if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns &&
+		    (!rdev->wiphy.wowlan->pattern_min_len ||
+		     rdev->wiphy.wowlan->pattern_min_len >
+				rdev->wiphy.wowlan->pattern_max_len)))
+		return -EINVAL;
 #endif
 
 	/* check and set up bitrates */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 31d265f..34cac2f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -908,7 +908,7 @@ nla_put_failure:
 static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
 					struct sk_buff *msg)
 {
-	const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
+	const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
 	struct nlattr *nl_tcp;
 
 	if (!tcp)
@@ -951,37 +951,37 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
 {
 	struct nlattr *nl_wowlan;
 
-	if (!dev->wiphy.wowlan.flags && !dev->wiphy.wowlan.n_patterns)
+	if (!dev->wiphy.wowlan)
 		return 0;
 
 	nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
 	if (!nl_wowlan)
 		return -ENOBUFS;
 
-	if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) &&
+	if (((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
-	    ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
+	    ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
 	     nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
 		return -ENOBUFS;
 
-	if (dev->wiphy.wowlan.n_patterns) {
+	if (dev->wiphy.wowlan->n_patterns) {
 		struct nl80211_wowlan_pattern_support pat = {
-			.max_patterns = dev->wiphy.wowlan.n_patterns,
-			.min_pattern_len = dev->wiphy.wowlan.pattern_min_len,
-			.max_pattern_len = dev->wiphy.wowlan.pattern_max_len,
-			.max_pkt_offset = dev->wiphy.wowlan.max_pkt_offset,
+			.max_patterns = dev->wiphy.wowlan->n_patterns,
+			.min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
+			.max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
+			.max_pkt_offset = dev->wiphy.wowlan->max_pkt_offset,
 		};
 
 		if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
@@ -7580,8 +7580,7 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
 	void *hdr;
 	u32 size = NLMSG_DEFAULT_SIZE;
 
-	if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
-	    !rdev->wiphy.wowlan.tcp)
+	if (!rdev->wiphy.wowlan)
 		return -EOPNOTSUPP;
 
 	if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
@@ -7654,7 +7653,7 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 	u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
 	int err, port;
 
-	if (!rdev->wiphy.wowlan.tcp)
+	if (!rdev->wiphy.wowlan->tcp)
 		return -EINVAL;
 
 	err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
@@ -7674,16 +7673,16 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 		return -EINVAL;
 
 	data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
-	if (data_size > rdev->wiphy.wowlan.tcp->data_payload_max)
+	if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
 		return -EINVAL;
 
 	if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
-			rdev->wiphy.wowlan.tcp->data_interval_max ||
+			rdev->wiphy.wowlan->tcp->data_interval_max ||
 	    nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
 		return -EINVAL;
 
 	wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
-	if (wake_size > rdev->wiphy.wowlan.tcp->wake_payload_max)
+	if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
 		return -EINVAL;
 
 	wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
@@ -7698,13 +7697,13 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 
 		if (!tok->len || tokens_size % tok->len)
 			return -EINVAL;
-		if (!rdev->wiphy.wowlan.tcp->tok)
+		if (!rdev->wiphy.wowlan->tcp->tok)
 			return -EINVAL;
-		if (tok->len > rdev->wiphy.wowlan.tcp->tok->max_len)
+		if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
 			return -EINVAL;
-		if (tok->len < rdev->wiphy.wowlan.tcp->tok->min_len)
+		if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
 			return -EINVAL;
-		if (tokens_size > rdev->wiphy.wowlan.tcp->tok->bufsize)
+		if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
 			return -EINVAL;
 		if (tok->offset + tok->len > data_size)
 			return -EINVAL;
@@ -7712,7 +7711,7 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
 
 	if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
 		seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
-		if (!rdev->wiphy.wowlan.tcp->seq)
+		if (!rdev->wiphy.wowlan->tcp->seq)
 			return -EINVAL;
 		if (seq->len == 0 || seq->len > 4)
 			return -EINVAL;
@@ -7793,12 +7792,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
 	struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
 	struct cfg80211_wowlan new_triggers = {};
 	struct cfg80211_wowlan *ntrig;
-	struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
+	struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
 	int err, i;
 	bool prev_enabled = rdev->wiphy.wowlan_config;
 
-	if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
-	    !rdev->wiphy.wowlan.tcp)
+	if (!wowlan)
 		return -EOPNOTSUPP;
 
 	if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
-- 
1.8.0


^ permalink raw reply related

* Re: [PATCH v2 2/2] cfg80211/nl80211: Add packet coalesce support
From: Johannes Berg @ 2013-06-03 15:28 UTC (permalink / raw)
  To: Amitkumar Karwar
  Cc: Bing Zhao, linux-wireless@vger.kernel.org, Luis R. Rodriguez,
	Jouni Malinen, Vasanthakumar Thiagarajan, Senthil Balasubramanian,
	Luciano Coelho
In-Reply-To: <5FF020A1CFFEEC49BD1E09530C4FF5950F313C2CA5@SC-VEXCH1.marvell.com>

Hi,

sorry for the late reply. I did see you sent another version, but wanted
to comment here anyway.

> > This is curious, you already discard those that you don't care about by
> > way of multicast filtering, no? What's the added advantage here? Would
> > you coalesce interrupts for those packets that pass the filter(s)?
> 
> Yes. we don't want to simply discard those packets, because few of
> them may be useful for the host.
> The advantage here is instead of getting random per packet receive
> interrupts, host receives multiple buffered packets with a single
> receive interrupt.

I guess that makes some sense.

> > Actually, you should probably make that a pointer, then it can be NULL
> > for drivers not supporting it, and static const for those that do. Means
> > you should make it a const pointer, of course.
> > 
> > Userspace can tell by checking if the support is advertised.
> 
> We will use following condition to check if driver is not supporting
> the feature. (wowlan code does the same thing)
> 
> "if (!dev->wiphy.coalesce.n_patterns || !dev->wiphy.coalesce.n_rules)"

Hmm. I think wowlan should probably be changed though, no need to make
the struct larger just for this, right? Not all drivers are going to
support it.

For WoWLAN I'm going to apply this:
http://p.sipsolutions.net/fa808e0722a7624a.txt

> > This is bad. You leave rdev->coalesce assigned, but it's completely
> > invalid data. IMHO you should use a temporary variable and only assign
> > it when it's fully parsed, freeing it if not. That way, you also don't
> > kill old values when new invalid values are parsed.
> 
> "iw coalesce add" command adds one coalesce rule at a time. "iw
> coalesce disable" command removes all configured rules.

Can you please change this to "iw coalesce set" and make it set all the
rules in one? Otherwise you're going to have very awkward races and need
to always clear etc. The code would also be easier, though obviously
you'd need to be able to specify multiple rules at the same time.

johannes


^ permalink raw reply

* Re: [PATCH 2/7] ath9k: Enable WoW only for AR9462
From: Sujith Manoharan @ 2013-06-03 15:17 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: John Linville, linux-wireless
In-Reply-To: <20130603150846.GB2146@redhat.com>

Stanislaw Gruszka wrote:
> Do this feature will be added back in the future? If so, when? Or there
> are some limitations regarding WoW support on older chips?

WoW hasn't been tested or verified with ath9k using AR9280 at all, so we
don't know what is missing in ath9k to handle the chip's peculiarities.

> I'm asking because, we have RHEL customer that request WoWLAN support
> for AR9280. I thought this will be matter of backport ath9k driver
> from upstream to RHEL, since we have commits that add WoW for AR9002,
> including AR9280. But since you're now removing that feature I'm a bit
> worried. Will WoW be supported on AR9280, or we should rather ask
> customer to use different chip i.e. AR9462 ?

If AR9280 is used, getting support for WoW would be difficult. AR9462 has
been through internal test-cycles for WoW, so it seems a more sensible choice.

But, the AR9002-specific code can be retained in the driver if RH needs it.

Sujith

^ permalink raw reply

* Re: [PATCH] cfg80211: fix deadlock in cfg80211_leave_mesh()
From: Bob Copeland @ 2013-06-03 15:19 UTC (permalink / raw)
  To: Johannes Berg; +Cc: thomas, linux-wireless, devel
In-Reply-To: <1370271421.8227.14.camel@jlt4.sipsolutions.net>

On Mon, Jun 03, 2013 at 04:57:01PM +0200, Johannes Berg wrote:
> However, I think that in mac80211 we can instead just remove the locking
> and the cancel_work_sync() since the latter will happen whenever the
> interface goes down, in a different code path outside of this. Just need
> to make sure the work can cope with running while the interface is not
> joined to a mesh, but I guess that's not going to be a big problem.

Yeah, that would be a better approach.  We (myself or Thomas) can give
that a shot today.

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* Re: [PATCH 2/7] ath9k: Enable WoW only for AR9462
From: Stanislaw Gruszka @ 2013-06-03 15:08 UTC (permalink / raw)
  To: Sujith Manoharan; +Cc: John Linville, linux-wireless
In-Reply-To: <1370231369-16241-2-git-send-email-sujith@msujith.org>

Hi

On Mon, Jun 03, 2013 at 09:19:24AM +0530, Sujith Manoharan wrote:
> From: Sujith Manoharan <c_manoha@qca.qualcomm.com>
> 
> The only card with which WoW has been tested and verified is
> AR9462. Do not enable it for all cards since WoW is really quirky
> and needs to be tested properly with each chip.

Do this feature will be added back in the future? If so, when? Or there
are some limitations regarding WoW support on older chips?

I'm asking because, we have RHEL customer that request WoWLAN support
for AR9280. I thought this will be matter of backport ath9k driver
from upstream to RHEL, since we have commits that add WoW for AR9002,
including AR9280. But since you're now removing that feature I'm a bit
worried. Will WoW be supported on AR9280, or we should rather ask
customer to use different chip i.e. AR9462 ?

Thanks
Stanislaw


^ permalink raw reply

* Re: [PATCH 1/2] nl80211: allow sending CMD_FRAME without specifying any frequency
From: Nicolas Cavallari @ 2013-06-03 15:04 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Antonio Quartulli, linux-wireless, Antonio Quartulli
In-Reply-To: <1370271547.8227.16.camel@jlt4.sipsolutions.net>

On 03/06/2013 16:59, Johannes Berg wrote:
> On Mon, 2013-06-03 at 08:39 +0200, Antonio Quartulli wrote:
>> From: Antonio Quartulli <antonio@open-mesh.com>
>>
>> Users may want to send a frame on the current channel
>> without specifying it.
>>
>> Make mgmt_tx pass a NULL channel to mac80211 if none has
>> been specified by the user.
> 
> cfg80211 isn't just a mac80211 frontend ... ;-)
> 
> Also, as Nicolas said, ath6kl_mgmt_tx() will crash after this patch if
> it's called in AP mode w/o a channel, so you need to think about that.

It will crash unconditionally. All ath6kl_mgmt_tx()'s code paths access
chan->center_freq at some point.

^ permalink raw reply

* Re: [PATCH v2] mac80211: set mesh formation field properly
From: Johannes Berg @ 2013-06-03 15:03 UTC (permalink / raw)
  To: Jacob Minshall; +Cc: linux-wireless, devel
In-Reply-To: <1369863156-26149-1-git-send-email-jacob@cozybit.com>

On Wed, 2013-05-29 at 14:32 -0700, Jacob Minshall wrote:
> Cap max peerings at 63 in accordance with IEEE-2012 8.4.2.100.7.
> Triggers a beacon regeneration every time the number of peerings changes.
> Previously this would only happen if the "accepting peerings" bit changed.

Applied.

johannes


^ permalink raw reply

* Re: [PATCH] iw: Allow basic rates to be configured when joining mesh
From: Johannes Berg @ 2013-06-03 15:02 UTC (permalink / raw)
  To: Ashok Nagarajan; +Cc: linux-wireless, Javier Cardona, devel
In-Reply-To: <CACcxo+ruNm9+xch42j08dBG9jR28=TX+spgy83oGkQHNSesL7A@mail.gmail.com>

On Thu, 2013-05-30 at 11:20 -0700, Ashok Nagarajan wrote:
> Hi Johannes,
> 
> I am changing the API for mesh join here as per our recent discussion,
> which is to accept basic-rates only when passed the 'freq' attribute.
> I was wondering what would be an acceptable style in iw to convey this
> to user.
> 
> 1. mesh join <mesh ID> [freq in MHz [HT20|HT40+|HT40-|NOHT]
> [basic-rates <rate in Mbps,rate2,...>]] or
> 2. mesh join <mesh ID> [freq in MHz] [HT20|HT40+|HT40-|NOHT]
> [basic-rates <rate in Mbps,rate2,...>]
> 
> Note the nested brackets in style 1.
> 
> Please let me know what you think.

Honestly? I don't really care. The first might be clearer, but it
doesn't matter all that much to me, I don't use mesh anyway ;-)

johannes


^ permalink raw reply

* Re: [PATCH 2/2] mac80211: in mgmt_tx use the current channel if none has been specified
From: Johannes Berg @ 2013-06-03 15:01 UTC (permalink / raw)
  To: Antonio Quartulli; +Cc: linux-wireless, Antonio Quartulli
In-Reply-To: <1370241587-2609-2-git-send-email-ordex@autistici.org>

On Mon, 2013-06-03 at 08:39 +0200, Antonio Quartulli wrote:

> @@ -2845,6 +2852,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
>  		rcu_read_lock();
>  		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
>  
> +		/* if no channel was specified, use the current one */
> +		if (chanctx_conf && !chan)
> +			chan = chanctx_conf->def.chan;
> +
>  		if (chanctx_conf)
>  			need_offchan = chan != chanctx_conf->def.chan;
>  		else
> @@ -2852,6 +2863,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
>  		rcu_read_unlock();
>  	}
>  
> +	/* at this point a channel should have been chosen */
> +	if (!chan) {
> +		ret = -EINVAL;
> +		goto out_unlock;
> +	}
> +

These two changes make no sense at all. If you look at the function
you'll see that "chan" isn't used at all after the check, and modifying
the "check if ..." part to use the channel also doesn't make sense.

johannes


^ permalink raw reply

* Re: [PATCH 1/2] nl80211: allow sending CMD_FRAME without specifying any frequency
From: Johannes Berg @ 2013-06-03 14:59 UTC (permalink / raw)
  To: Antonio Quartulli; +Cc: linux-wireless, Antonio Quartulli
In-Reply-To: <1370241587-2609-1-git-send-email-ordex@autistici.org>

On Mon, 2013-06-03 at 08:39 +0200, Antonio Quartulli wrote:
> From: Antonio Quartulli <antonio@open-mesh.com>
> 
> Users may want to send a frame on the current channel
> without specifying it.
> 
> Make mgmt_tx pass a NULL channel to mac80211 if none has
> been specified by the user.

cfg80211 isn't just a mac80211 frontend ... ;-)

Also, as Nicolas said, ath6kl_mgmt_tx() will crash after this patch if
it's called in AP mode w/o a channel, so you need to think about that.

Tracing looks fine though.

johannes


^ permalink raw reply

* Re: [PATCH] cfg80211: fix deadlock in cfg80211_leave_mesh()
From: Johannes Berg @ 2013-06-03 14:57 UTC (permalink / raw)
  To: Bob Copeland; +Cc: thomas, linux-wireless, devel
In-Reply-To: <20130601131916.GA2484@localhost>

On Sat, 2013-06-01 at 09:19 -0400, Bob Copeland wrote:
> As of "cfg80211/mac80211: use cfg80211 wdev mutex in mac80211",
> mac80211 expects to be able to take the wdev mutex around sdata
> accesses.  This causes a recursive deadlock since
> __cfg80211_leave_mesh() already holds the wdev mutex.  Removing
> the sdata_lock() calls in ieee80211_stop_mesh() alone won't fix
> this, as the cancel_work_sync() in mesh runs the iface work,
> and various work items also want to take the wdev lock (not
> just in mesh, see e.g.  ieee80211_sta_rx_queued_mgmt().)

Ouch. My mistake, clearly.

> diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
> index 5dfb289..6344a81 100644
> --- a/net/wireless/mesh.c
> +++ b/net/wireless/mesh.c
> @@ -250,7 +250,9 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
>  	if (!wdev->mesh_id_len)
>  		return -ENOTCONN;
>  
> +	wdev_unlock(wdev);
>  	err = rdev_leave_mesh(rdev, dev);
> +	wdev_lock(wdev);

I'm not really happy much with this, like you said, and it's also
incomplete because the same can happen in an error path in mac80211 in
rdev_join_mesh().

I also don't really want to think about races with mesh_id_len,
particularly in the join.

However, I think that in mac80211 we can instead just remove the locking
and the cancel_work_sync() since the latter will happen whenever the
interface goes down, in a different code path outside of this. Just need
to make sure the work can cope with running while the interface is not
joined to a mesh, but I guess that's not going to be a big problem.

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: don't check local mesh TTL on TX
From: Johannes Berg @ 2013-06-03 14:54 UTC (permalink / raw)
  To: Thomas Pedersen; +Cc: linux-wireless, open80211s
In-Reply-To: <1370047307-19248-1-git-send-email-thomas@cozybit.com>

On Fri, 2013-05-31 at 17:41 -0700, Thomas Pedersen wrote:
> nl80211 has already verified the mesh TTL on setting the
> mesh config, so no need to check it again in mac80211.

makes sense, applied.

johannes


^ 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