* Cross compilation compat-wireless in kernel-2.6.35 for powerpc
From: Suman Pandit @ 2013-05-24 6:24 UTC (permalink / raw)
To: linux-wireless
"WARNING: CONFIG_CFG80211_WEXT will be deactivated or not working because
kernel was compiled with CONFIG_WIRELESS_EXT=n. Tools using wext interface
like iwconfig will not work. To activate it build your kernel e.g. with
CONFIG_LIBIPW=m."
./scripts/gen-compat-autoconf.sh config.mk > include/linux/compat_autoconf.h
^ permalink raw reply
* RE: ath9k_htc p2p finding issue
From: Deng, Flavian @ 2013-05-24 1:46 UTC (permalink / raw)
To: Arend van Spriel, Zhou, Robie; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <519DCF76.8050704@broadcom.com>
SGkgQXJlbmQsDQpUaGFua3MgZm9yIHlvdXIgc3VnZ2VzdGlvbiwgYnV0IGl0IGxvb2tzIHRoZSBh
dGg5a19odGMgZGlkbid0IGdldCBwcm9iZSByZXF1ZXN0IGZyYW1lLiBJIGFkZGVkIGRlYnVnIG1l
c3NhZ2UgaW4gImF0aDlrX3J4X3Rhc2tsZXQoKSIoaHRjX2Rydl90eHJ4LmMpLCBidXQgbm8gcHJv
YmUgcmVxdWVzdCBmcmFtZSBhcnJpdmVkIHRoZXJlLg0KQWZ0ZXIgbW9yZSB0ZXN0LCBpdCBsb29r
cyB0aGlzIGlzc3VlIG9jY3VycmVkIGFmdGVyICJjb21wYXQtd2lyZWxlc3MtMy42LjItMSIsIGFu
ZCB0aGlzIGlzc3VlIGNvdWxkbid0IGJlIG9ic2VydmVkIGluICJjb21wYXQtd2lyZWxlc3MtMy41
LjQtMSIuDQoNCkRvIHlvdSBoYXZlIG90aGVyIHN1Z2dlc3Rpb24gZm9yIHRoaXMgaXNzdWU/DQoN
ClRoYW5rcw0KRmxhdmlhbiBEZW5nDQoNCg0KLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCkZy
b206IEFyZW5kIHZhbiBTcHJpZWwgW21haWx0bzphcmVuZEBicm9hZGNvbS5jb21dIA0KU2VudDog
MjAxM8TqNdTCMjPI1SAxNjoxMw0KVG86IFpob3UsIFJvYmllDQpDYzogbGludXgtd2lyZWxlc3NA
dmdlci5rZXJuZWwub3JnOyBEZW5nLCBGbGF2aWFuDQpTdWJqZWN0OiBSZTogYXRoOWtfaHRjIHAy
cCBmaW5kaW5nIGlzc3VlDQoNCk9uIDA1LzIzLzIwMTMgMDc6NTggQU0sIFpob3UsIFJvYmllIHdy
b3RlOg0KPiBIaSBhbGwsDQo+DQo+IFdlIG1lZXQgc29tZSBwcm9ibGVtIHdoZW4gdHJ5IFAyUCBi
eSB1c2luZyBhdGg5a19odGMgY29tcGF0LXdpcmVsZXNzLXYzLjYuOC0xLg0KPg0KPiBXaGVuIHVz
aW5nIHRoZSBjb21wYXQtd2lyZWxlc3MtdjMuNi44LTEsIEFSOTI3MSBjb3VsZCBmaW5kIG90aGVy
IFAyUCBkZXZpY2VzLCBidXQgb3RoZXIgUDJQIGRldmljZXMgY291bGRuJ3QgZmluZCBBUjkyNzEg
KHJ1bnMgYXRoOWtfaHRjKSBiZWNhdXNlIGRyaXZlciBjb3VsZG4ndCByZXBvcnQgUHJvYmUgUmVx
dWVzdCB0byB3cGFfc3VwcGxpY2FudC4NCj4NCj4gQW5kIHRoaXMgaXNzdWUgY291bGQgbm90IGJl
IG9ic2VydmVkIHdoZW4gdXNpbmcgY29tcGF0LXdpcmVsZXNzLXYzLjAuOS0xLCBieSBjb21wYXJl
IHdpdGggY29tcGF0LXdpcmVsZXNzLXYzLjAuOS0xLCBBVEg5SyBSWCBmaWx0ZXIgaXMgIHNldCBj
b3JyZWN0bHkgYWZ0ZXIgZ290ICJSZXBvcnQgUHJvYmUgUmVxdWVzdCIgY29tbWFuZCBmcm9tIHdw
YV9zdXBwbGljYW50LCBidXQgQVRIOUsgZHJpdmVyIGNvdWxkbid0IGdldCAiUHJvYmUgUmVxdWVz
dCIgZnJhbWUoSSBhZGQgZGVidWcgbXNnIGluIGllZWU4MDIxMV9yeF9oYW5kbGVycygpIGZ1bmN0
aW9uKS4NCj4NCj4gPDc+WyAgMjA1Ljc4NDExOF0gW0RGX0RCR10gICAgW2llZWU4MDIxMV9tZ210
X2ZyYW1lX3JlZ2lzdGVyXSA6IGxvY2FsLT5wcm9iZV9yZXFfcmVnID0gMTsNCj4gPDc+WyAgMjA1
LjgzMDIzMl0gW0RGX0RCR10gICAgW2F0aDlrX2h0Y19vcG1vZGVfaW5pdF0gICAgcmZpbHQgPSAw
eDE3OyAgIC0+ICAgYXRoOWtfaHdfc2V0cnhmaWx0ZXINCj4gPDc+WyAgMjA1LjgzMjg1OF0gW0RG
X0RCR10gICAgW2llZWU4MDIxMV9jb25maWd1cmVfZmlsdGVyXSA6IG5ld19mbGFncyB8PSBGSUZf
UFJPQkVfUkVROw0KPiA8Nz5bICAyMDUuODMzMTAxXSBbREZfREJHXSAgICBbYXRoOWtfaHRjX2Nv
bmZpZ3VyZV9maWx0ZXJdICAgIHJmaWx0ID0gMHgyODc7ICAgLT4gICBhdGg5a19od19zZXRyeGZp
bHRlcg0KPiA8Nz5bICAyMDUuODc4MjMwXSBbREZfREJHXSAgICBbYXRoOWtfaHRjX29wbW9kZV9p
bml0XSAgICByZmlsdCA9IDB4Mjg3OyAgIC0+ICAgYXRoOWtfaHdfc2V0cnhmaWx0ZXINCj4gPDc+
WyAgMjA1Ljg4MjU1Nl0gW0RGX0RCR10gICAgW2llZWU4MDIxMV9jb25maWd1cmVfZmlsdGVyXSA6
IG5ld19mbGFncyB8PSBGSUZfUFJPQkVfUkVROw0KPiA8Nz5bICAyMDUuODgzNjA2XSBbREZfREJH
XSAgICBbYXRoOWtfaHRjX2NvbmZpZ3VyZV9maWx0ZXJdICAgIHJmaWx0ID0gMHgyODc7ICAgLT4g
ICBhdGg5a19od19zZXRyeGZpbHRlcg0KPg0KPiA8Nz5bICAyMDYuMDEwODg2XSBbREZfREJHXSAg
ICBbaWVlZTgwMjExX21nbXRfZnJhbWVfcmVnaXN0ZXJdIDogbG9jYWwtPnByb2JlX3JlcV9yZWcg
PSAwOw0KPiA8Nz5bICAyMDYuMDM2MjM3XSBbREZfREJHXSAgICBbYXRoOWtfaHRjX29wbW9kZV9p
bml0XSAgICByZmlsdCA9IDB4Mjg3OyAgIC0+ICAgYXRoOWtfaHdfc2V0cnhmaWx0ZXINCj4gPDc+
WyAgMjA2LjA0MzM1N10gW0RGX0RCR10gICAgW2F0aDlrX2h0Y19jb25maWd1cmVfZmlsdGVyXSAg
ICByZmlsdCA9IDB4MTc7ICAgLT4gICBhdGg5a19od19zZXRyeGZpbHRlcg0KPiA8Nz5bICAyMDYu
MDQ0MTA3XSBbREZfREJHXSAgICBbYXRoOWtfaHRjX2NvbmZpZ3VyZV9maWx0ZXJdICAgIHJmaWx0
ID0gMHgxNzsgICAtPiAgIGF0aDlrX2h3X3NldHJ4ZmlsdGVyDQo+IDw3PlsgIDIwNi4wOTAxMDZd
IFtERl9EQkddICAgIFthdGg5a19odGNfb3Btb2RlX2luaXRdICAgIHJmaWx0ID0gMHgxNzsgICAt
PiAgIGF0aDlrX2h3X3NldHJ4ZmlsdGVyDQo+IDw3PlsgIDIwNi4xNjA3MzRdIFtERl9EQkddICAg
IFthdGg5a19odGNfb3Btb2RlX2luaXRdICAgIHJmaWx0ID0gMHgxNzsgICAtPiAgIGF0aDlrX2h3
X3NldHJ4ZmlsdGVyDQo+IDw3PlsgIDIwNi4yMzA3NDBdIFtERl9EQkddICAgIFthdGg5a19odGNf
b3Btb2RlX2luaXRdICAgIHJmaWx0ID0gMHgxNzsgICAtPiAgIGF0aDlrX2h3X3NldHJ4ZmlsdGVy
DQo+DQo+DQo+IERpZCBhbnlvbmUgZXZlciBtZWV0IHRoaXMgaXNzdWU/IEFueSBzdWdnZXN0aW9u
IGZvciBmdXJ0aGVyIGRlYnVnZ2luZyB0aGlzIGlzc3VlPw0KDQpEaWQgeW91IGNvbmZpcm0gYXRo
OWtfaHRjIGlzIGhhbmRpbmcgb3ZlciBwcm9iZSByZXF1ZXN0cyB0byBtYWM4MDIxMT8gDQpNaWdo
dCBiZSB1c2VmdWwgdG8gYWRkIGRlYnVnZ2luZyBpbiBwcmVwYXJlX2Zvcl9oYW5kbGVycygpIGlu
c3RlYWQuDQoNClJlZ2FyZHMsDQpBcmVuZA0KDQoNCg==
^ permalink raw reply
* [PATCH 3.10] mac80211: close AP_VLAN interfaces before unregistering all
From: Johannes Berg @ 2013-05-23 23:10 UTC (permalink / raw)
To: linux-wireless; +Cc: Eric Dumazet, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Since Eric's commit efe117ab8 ("Speedup ieee80211_remove_interfaces")
there's a bug in mac80211 when it unregisters with AP_VLAN interfaces
up. If the AP_VLAN interface was registered after the AP it belongs
to (which is the typical case) and then we get into this code path,
unregister_netdevice_many() will crash because it isn't prepared to
deal with interfaces being closed in the middle of it. Exactly this
happens though, because we iterate the list, find the AP master this
AP_VLAN belongs to and dev_close() the dependent VLANs. After this,
unregister_netdevice_many() won't pick up the fact that the AP_VLAN
is already down and will do it again, causing a crash.
Cc: stable@vger.kernel.org [2.6.33+]
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/iface.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 00e2238..ceef644 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1703,6 +1703,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
ASSERT_RTNL();
+ /*
+ * Close all AP_VLAN interfaces first, as otherwise they
+ * might be closed while the AP interface they belong to
+ * is closed, causing unregister_netdevice_many() to crash.
+ */
+ list_for_each_entry(sdata, &local->interfaces, list)
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ dev_close(sdata->dev);
+
mutex_lock(&local->iflist_mtx);
list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
list_del(&sdata->list);
--
1.8.0
^ permalink raw reply related
* RE: [PATCH v2 1/2] iw: use updated structures and enums for packet pattern
From: Bing Zhao @ 2013-05-23 22:36 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless@vger.kernel.org, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar
In-Reply-To: <1369348092.17244.0.camel@jlt4.sipsolutions.net>
SGkgSm9oYW5uZXMsDQoNCj4gPiBQbGVhc2UgbGV0IG1lIGtub3cgaWYgeW91IHdhbnQgbWUgdG8g
cmVzZW5kIDEvMiB3aXRoIHJldmlzZWQgY29tbWl0IGxvZy4NCj4gPiBPdGhlcndpc2UsIHBsZWFz
ZSBzaW1wbHkgZHJvcCAxLzIgYW5kIGFwcGx5IDIvMiBhbG9uZS4NCj4gDQo+IE5vLCBubyBuZWVk
LiBKdXN0IHdhbnRlZCB0byBkb3VibGUtY2hlY2suIEkgc3RhcnRlZCBnb2luZyB0aHJvdWdoIHRo
ZQ0KPiBrZXJuZWwgc2lkZSBwYXRjaGVzIGFuZCBoYWQgc29tZSBjb21tZW50cywgYnV0IEknbSB0
b28gdGlyZWQgdG8gZmluaXNoDQo+IG5vdy4NCg0KT0ssIE5vIGh1cnJ5Lg0KDQpUaGFua3MsDQpC
aW5nDQo=
^ permalink raw reply
* Re: [PATCH v2 1/2] iw: use updated structures and enums for packet pattern
From: Johannes Berg @ 2013-05-23 22:28 UTC (permalink / raw)
To: Bing Zhao
Cc: linux-wireless@vger.kernel.org, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar
In-Reply-To: <477F20668A386D41ADCC57781B1F70430E801DC656@SC-VEXCH1.marvell.com>
On Thu, 2013-05-23 at 15:23 -0700, Bing Zhao wrote:
> Hi Johannes,
>
> > On Thu, 2013-05-23 at 14:35 -0700, Bing Zhao wrote:
> > > From: Amitkumar Karwar <akarwar@marvell.com>
> > >
> > > They are renamed so that they can be used for new feature.
> >
> > This isn't really necessary, right? I mean, it should compile w/o this
> > even after the kernel patches, but this is just for making it look
> > nicer?
>
> Yes, it compiles w/o this patch. It does make it look nicer, I think.
> However, the commit message should be something like:
>
> "They are renamed to match new nl80211.h and make the code look nicer."
>
> Please let me know if you want me to resend 1/2 with revised commit log.
> Otherwise, please simply drop 1/2 and apply 2/2 alone.
No, no need. Just wanted to double-check. I started going through the
kernel side patches and had some comments, but I'm too tired to finish
now.
johannes
^ permalink raw reply
* RE: [PATCH v2 1/2] iw: use updated structures and enums for packet pattern
From: Bing Zhao @ 2013-05-23 22:23 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless@vger.kernel.org, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar
In-Reply-To: <1369345157.12002.87.camel@jlt4.sipsolutions.net>
SGkgSm9oYW5uZXMsDQoNCj4gT24gVGh1LCAyMDEzLTA1LTIzIGF0IDE0OjM1IC0wNzAwLCBCaW5n
IFpoYW8gd3JvdGU6DQo+ID4gRnJvbTogQW1pdGt1bWFyIEthcndhciA8YWthcndhckBtYXJ2ZWxs
LmNvbT4NCj4gPg0KPiA+IFRoZXkgYXJlIHJlbmFtZWQgc28gdGhhdCB0aGV5IGNhbiBiZSB1c2Vk
IGZvciBuZXcgZmVhdHVyZS4NCj4gDQo+IFRoaXMgaXNuJ3QgcmVhbGx5IG5lY2Vzc2FyeSwgcmln
aHQ/IEkgbWVhbiwgaXQgc2hvdWxkIGNvbXBpbGUgdy9vIHRoaXMNCj4gZXZlbiBhZnRlciB0aGUg
a2VybmVsIHBhdGNoZXMsIGJ1dCB0aGlzIGlzIGp1c3QgZm9yIG1ha2luZyBpdCBsb29rDQo+IG5p
Y2VyPw0KDQpZZXMsIGl0IGNvbXBpbGVzIHcvbyB0aGlzIHBhdGNoLiBJdCBkb2VzIG1ha2UgaXQg
bG9vayBuaWNlciwgSSB0aGluay4NCkhvd2V2ZXIsIHRoZSBjb21taXQgbWVzc2FnZSBzaG91bGQg
YmUgc29tZXRoaW5nIGxpa2U6DQoNCiJUaGV5IGFyZSByZW5hbWVkIHRvIG1hdGNoIG5ldyBubDgw
MjExLmggYW5kIG1ha2UgdGhlIGNvZGUgbG9vayBuaWNlci4iDQoNClBsZWFzZSBsZXQgbWUga25v
dyBpZiB5b3Ugd2FudCBtZSB0byByZXNlbmQgMS8yIHdpdGggcmV2aXNlZCBjb21taXQgbG9nLg0K
T3RoZXJ3aXNlLCBwbGVhc2Ugc2ltcGx5IGRyb3AgMS8yIGFuZCBhcHBseSAyLzIgYWxvbmUuDQoN
ClRoYW5rcywNCkJpbmcNCg0K
^ permalink raw reply
* Re: [PATCH v2 1/2] iw: use updated structures and enums for packet pattern
From: Johannes Berg @ 2013-05-23 21:39 UTC (permalink / raw)
To: Bing Zhao
Cc: linux-wireless, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar
In-Reply-To: <1369344941-11217-1-git-send-email-bzhao@marvell.com>
On Thu, 2013-05-23 at 14:35 -0700, Bing Zhao wrote:
> From: Amitkumar Karwar <akarwar@marvell.com>
>
> They are renamed so that they can be used for new feature.
This isn't really necessary, right? I mean, it should compile w/o this
even after the kernel patches, but this is just for making it look
nicer?
johannes
^ permalink raw reply
* [PATCH v2 1/2] iw: use updated structures and enums for packet pattern
From: Bing Zhao @ 2013-05-23 21:35 UTC (permalink / raw)
To: linux-wireless
Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar, Bing Zhao
From: Amitkumar Karwar <akarwar@marvell.com>
They are renamed so that they can be used for new feature.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
info.c | 2 +-
wowlan.c | 32 ++++++++++++++++----------------
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/info.c b/info.c
index 54d9a8d..d893ffc 100644
--- a/info.c
+++ b/info.c
@@ -432,7 +432,7 @@ broken_combination:
[NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
[NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
};
- struct nl80211_wowlan_pattern_support *pat;
+ struct nl80211_pattern_support *pat;
int err;
err = nla_parse_nested(tb_wowlan, MAX_NL80211_WOWLAN_TRIG,
diff --git a/wowlan.c b/wowlan.c
index b4a2715..d323ca7 100644
--- a/wowlan.c
+++ b/wowlan.c
@@ -261,11 +261,11 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
}
pattern = nla_nest_start(patterns, ++patnum);
- NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_MASK,
+ NLA_PUT(patterns, NL80211_PKTPAT_MASK,
DIV_ROUND_UP(patlen, 8), mask);
- NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_PATTERN,
- patlen, pat);
- NLA_PUT_U32(patterns, NL80211_WOWLAN_PKTPAT_OFFSET, pkt_offset);
+ NLA_PUT(patterns, NL80211_PKTPAT_PATTERN, patlen, pat);
+ NLA_PUT_U32(patterns, NL80211_PKTPAT_OFFSET,
+ pkt_offset);
nla_nest_end(patterns, pattern);
free(mask);
free(pat);
@@ -356,29 +356,29 @@ static int print_wowlan_handler(struct nl_msg *msg, void *arg)
nla_for_each_nested(pattern,
trig[NL80211_WOWLAN_TRIG_PKT_PATTERN],
rem_pattern) {
- struct nlattr *patattr[NUM_NL80211_WOWLAN_PKTPAT];
+ struct nlattr *patattr[NUM_NL80211_PKTPAT];
int i, patlen, masklen, pkt_offset;
uint8_t *mask, *pat;
- nla_parse(patattr, MAX_NL80211_WOWLAN_PKTPAT,
- nla_data(pattern), nla_len(pattern),
- NULL);
- if (!patattr[NL80211_WOWLAN_PKTPAT_MASK] ||
- !patattr[NL80211_WOWLAN_PKTPAT_PATTERN] ||
- !patattr[NL80211_WOWLAN_PKTPAT_OFFSET]) {
+ nla_parse(patattr, MAX_NL80211_PKTPAT,
+ nla_data(pattern), nla_len(pattern), NULL);
+ if (!patattr[NL80211_PKTPAT_MASK] ||
+ !patattr[NL80211_PKTPAT_PATTERN] ||
+ !patattr[NL80211_PKTPAT_OFFSET]) {
printf(" * (invalid pattern specification)\n");
continue;
}
- masklen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_MASK]);
- patlen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]);
- pkt_offset = nla_get_u32(patattr[NL80211_WOWLAN_PKTPAT_OFFSET]);
+ masklen = nla_len(patattr[NL80211_PKTPAT_MASK]);
+ patlen = nla_len(patattr[NL80211_PKTPAT_PATTERN]);
+ pkt_offset =
+ nla_get_u32(patattr[NL80211_PKTPAT_OFFSET]);
if (DIV_ROUND_UP(patlen, 8) != masklen) {
printf(" * (invalid pattern specification)\n");
continue;
}
printf(" * wake up on packet offset: %d", pkt_offset);
printf(" pattern: ");
- pat = nla_data(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]);
- mask = nla_data(patattr[NL80211_WOWLAN_PKTPAT_MASK]);
+ pat = nla_data(patattr[NL80211_PKTPAT_PATTERN]);
+ mask = nla_data(patattr[NL80211_PKTPAT_MASK]);
for (i = 0; i < patlen; i++) {
if (mask[i / 8] & (1 << (i % 8)))
printf("%.2x", pat[i]);
--
1.8.0
^ permalink raw reply related
* [PATCH v2 2/2] cfg80211/nl80211: Add packet coalesce support
From: Bing Zhao @ 2013-05-23 21:35 UTC (permalink / raw)
To: linux-wireless
Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar, Bing Zhao
In-Reply-To: <1369344908-11184-1-git-send-email-bzhao@marvell.com>
From: Amitkumar Karwar <akarwar@marvell.com>
In most cases, host that receives IPv4 and IPv6 multicast/broadcast
packets does not do anything with these packets. Therefore the
reception of these unwanted packets causes unnecessary processing
and power consumption.
Packet coalesce feature helps to reduce number of received
interrupts to host by buffering these packets in firmware/hardware
for some predefined time. Received interrupt will be generated when
one of the following events occur.
a) Expiration of hardware timer whose expiration time is set to
maximum coalescing delay of matching coalesce rule.
b) Coalescing buffer in hardware reaches it's limit.
c) Packet doesn't match any of the configured coalesce rules.
This patch adds set/get configuration support for packet coalesce.
User needs to configure following parameters for creating a coalesce
rule.
a) Maximum coalescing delay
b) List of packet patterns which needs to be matched
c) Condition for coalescence. pattern 'match' or 'no match'
Multiple such rules can be created.
This feature needs to be advertised during driver initialization.
Drivers are supposed to do required firmware/hardware settings based
on user configuration.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v2: add documentation in nl80211.h and elabiration of "coalesce"
in commit log (Luis R. Rodriguez)
include/net/cfg80211.h | 51 +++++++++
include/uapi/linux/nl80211.h | 82 ++++++++++++-
net/wireless/core.c | 2 +
net/wireless/core.h | 22 ++++
net/wireless/nl80211.c | 265 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 419 insertions(+), 3 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4585b63..dcbf125 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1739,6 +1739,35 @@ struct cfg80211_wowlan {
};
/**
+ * struct cfg80211_coalesce_rules - Coalesce rule parameters
+ *
+ * This structure defines coalesce rule for the device.
+ * @delay: maximum coalescing delay in msecs.
+ * @condition: condition for packet coalescence.
+ * i.e. pattern 'match' or 'no match'
+ * @patterns: array of packet patterns
+ * @n_patterns: number of patterns
+ */
+struct cfg80211_coalesce_rules {
+ int delay;
+ u8 condition;
+ struct cfg80211_pkt_pattern *patterns;
+ int n_patterns;
+};
+
+/**
+ * struct cfg80211_coalesce - Packet coalescing settings
+ *
+ * This structure defines coalescing settings.
+ * @rules: array of coalesce rules
+ * @n_rules: number of rules
+ */
+struct cfg80211_coalesce {
+ struct cfg80211_coalesce_rules **rules;
+ int n_rules;
+};
+
+/**
* struct cfg80211_wowlan_wakeup - wakeup report
* @disconnect: woke up by getting disconnected
* @magic_pkt: woke up by receiving magic packet
@@ -2024,6 +2053,7 @@ struct cfg80211_update_ft_ies_params {
* driver can take the most appropriate actions.
* @crit_proto_stop: Indicates critical protocol no longer needs increased link
* reliability. This operation can not fail.
+ * @set_coalesce: Set coalesce parameters.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2259,6 +2289,8 @@ struct cfg80211_ops {
u16 duration);
void (*crit_proto_stop)(struct wiphy *wiphy,
struct wireless_dev *wdev);
+ int (*set_coalesce)(struct wiphy *wiphy,
+ struct cfg80211_coalesce_rules *rule);
};
/*
@@ -2483,6 +2515,23 @@ struct wiphy_wowlan_support {
};
/**
+ * struct wiphy_coalesce_support - coalesce support data
+ * @n_rules: maximum number of coalesce rules
+ * @n_patterns: number of supported patterns
+ * (see nl80211.h for the pattern definition)
+ * @pattern_max_len: maximum length of each pattern
+ * @pattern_min_len: minimum length of each pattern
+ * @max_pkt_offset: maximum Rx packet offset
+ */
+struct wiphy_coalesce_support {
+ int n_rules;
+ int n_patterns;
+ int pattern_max_len;
+ int pattern_min_len;
+ int max_pkt_offset;
+};
+
+/**
* struct wiphy - wireless hardware description
* @reg_notifier: the driver's regulatory notification callback,
* note that if your driver uses wiphy_apply_custom_regulatory()
@@ -2589,6 +2638,7 @@ struct wiphy_wowlan_support {
* 802.11-2012 8.4.2.29 for the defined fields.
* @extended_capabilities_mask: mask of the valid values
* @extended_capabilities_len: length of the extended capabilities
+ * @wiphy_coalesce_support coalesce: coalesce support information
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -2697,6 +2747,7 @@ struct wiphy {
const struct iw_handler_def *wext;
#endif
+ struct wiphy_coalesce_support coalesce;
char priv[0] __aligned(NETDEV_ALIGN);
};
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1fa2bf4..34401a1 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -126,6 +126,31 @@
*/
/**
+ * DOC: packet coalesce support
+ *
+ * In most cases, host that receives IPv4 and IPv6 multicast/broadcast
+ * packets does not do anything with these packets. Therefore the
+ * reception of these unwanted packets causes unnecessary processing
+ * and power consumption.
+ *
+ * Packet coalesce feature helps to reduce number of received interrupts
+ * to host by buffering these packets in firmware/hardware for some
+ * predefined time. Received interrupt will be generated when one of the
+ * following events occur.
+ * a) Expiration of hardware timer whose expiration time is set to maximum
+ * coalescing delay of matching coalesce rule.
+ * b) Coalescing buffer in hardware reaches it's limit.
+ * c) Packet doesn't match any of the configured coalesce rules.
+ *
+ * User needs to configure following parameters for creating a coalesce
+ * rule.
+ * a) Maximum coalescing delay
+ * b) List of packet patterns which needs to be matched
+ * c) Condition for coalescence. pattern 'match' or 'no match'
+ * Multiple such rules can be created.
+ */
+
+/**
* enum nl80211_commands - supported nl80211 commands
*
* @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -648,6 +673,10 @@
* @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
* return back to normal.
*
+ * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules.
+ *
+ * @NL80211_CMD_SET_COALESCE: Add new coalesce rule.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -810,6 +839,9 @@ enum nl80211_commands {
NL80211_CMD_CRIT_PROTOCOL_START,
NL80211_CMD_CRIT_PROTOCOL_STOP,
+ NL80211_CMD_GET_COALESCE,
+ NL80211_CMD_SET_COALESCE,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1431,6 +1463,8 @@ enum nl80211_commands {
* @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which
* the connection should have increased reliability (u16).
*
+ * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1729,6 +1763,8 @@ enum nl80211_attrs {
NL80211_ATTR_CRIT_PROT_ID,
NL80211_ATTR_MAX_CRIT_PROT_DURATION,
+ NL80211_ATTR_COALESCE_RULE,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3027,7 +3063,6 @@ enum nl80211_cqm_rssi_threshold_event {
NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
};
-
/**
* enum nl80211_tx_power_setting - TX power adjustment
* @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power
@@ -3079,8 +3114,10 @@ enum nl80211_packet_pattern_attr {
* @max_pkt_offset: maximum Rx packet offset
*
* This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
- * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
- * capability information given by the kernel to userspace.
+ * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED or in
+ * %NL80211_ATTR_COALESCE_RULE_PKT_PATTERN when that is part of
+ * %NL80211_ATTR_COALESCE_RULE in the capability information given
+ * by the kernel to userspace.
*/
struct nl80211_pattern_support {
__u32 max_patterns;
@@ -3299,6 +3336,41 @@ enum nl80211_wowlan_tcp_attrs {
};
/**
+ * struct nl80211_coalesce_rule_support - coalesce rule support information
+ * @max_rules: maximum number of rules supported
+ * @pat: packet pattern support information
+ *
+ * This struct is carried in %NL80211_ATTR_COALESCE_RULE in the
+ * capability information given by the kernel to userspace.
+ */
+struct nl80211_coalesce_rule_support {
+ __u32 max_rules;
+ struct nl80211_pattern_support pat;
+} __attribute__((packed));
+
+/**
+ * enum nl80211_attr_coalesce_rule - coalesce rule attribute
+ * @__NL80211_COALESCE_RULE_INVALID: invalid number for nested attribute
+ * @NL80211_ATTR_COALESCE_RULE_DELAY: delay in msecs used for packet coalescing
+ * @NL80211_ATTR_COALESCE_RULE_CONDITION: condition for packet coalescence.
+ * i.e. pattern 'match' or 'no match'
+ * @NL80211_ATTR_COALESCE_RULE_PKT_PATTERN: packet offset, pattern is matched
+ * after these fixed number of bytes of received packet
+ * @NUM_NL80211_ATTR_COALESCE_RULE: number of attributes
+ * @NL80211_ATTR_COALESCE_RULE_MAX: max attribute number
+ */
+enum nl80211_attr_coalesce_rule {
+ __NL80211_COALESCE_RULE_INVALID,
+ NL80211_ATTR_COALESCE_RULE_DELAY,
+ NL80211_ATTR_COALESCE_RULE_CONDITION,
+ NL80211_ATTR_COALESCE_RULE_PKT_PATTERN,
+
+ /* keep last */
+ NUM_NL80211_ATTR_COALESCE_RULE,
+ NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1
+};
+
+/**
* enum nl80211_iface_limit_attrs - limit attributes
* @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
* @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
@@ -3578,6 +3650,9 @@ enum nl80211_ap_sme_features {
* Peering Management entity which may be implemented by registering for
* beacons or NL80211_CMD_NEW_PEER_CANDIDATE events. The mesh beacon is
* still generated by the driver.
+ * @NL80211_FEATURE_PACKET_COALESCE: This driver support packet coalescing
+ * feature. Packets are buffered in firmware based on configured rules
+ * to reduce unwanted packet or interrupt to host.
*/
enum nl80211_feature_flags {
NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
@@ -3597,6 +3672,7 @@ enum nl80211_feature_flags {
NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
+ NL80211_FEATURE_PACKET_COALESCE = 1 << 17,
};
/**
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 68f0c96..72a41da 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -737,6 +737,8 @@ void wiphy_unregister(struct wiphy *wiphy)
if (rdev->wowlan && rdev->ops->set_wakeup)
rdev_set_wakeup(rdev, false);
cfg80211_rdev_free_wowlan(rdev);
+
+ cfg80211_rdev_free_coalesce(rdev);
}
EXPORT_SYMBOL(wiphy_unregister);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index fd35dae..a0feff6 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -91,6 +91,8 @@ struct cfg80211_registered_device {
/* netlink port which started critical protocol (0 means not started) */
u32 crit_proto_nlportid;
+ struct cfg80211_coalesce *coalesce;
+
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __aligned(NETDEV_ALIGN);
@@ -119,6 +121,26 @@ cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
kfree(rdev->wowlan);
}
+static inline void
+cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
+{
+ int i, j;
+ struct cfg80211_coalesce_rules *rule;
+
+ if (!rdev->coalesce)
+ return;
+
+ for (i = 0; i < rdev->coalesce->n_rules; i++) {
+ rule = rdev->coalesce->rules[i];
+ for (j = 0; j < rule->n_patterns; j++)
+ kfree(rule->patterns[j].mask);
+ kfree(rule->patterns);
+ kfree(rule);
+ }
+ kfree(rdev->coalesce->rules);
+ kfree(rdev->coalesce);
+}
+
extern struct workqueue_struct *cfg80211_wq;
extern struct mutex cfg80211_mutex;
extern struct list_head cfg80211_rdev_list;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5f640de..8cfca0c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -432,6 +432,14 @@ nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
[NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
};
+/* policy for coalesce rule attributes */
+static const struct nla_policy
+nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
+ [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
+ [NL80211_ATTR_COALESCE_RULE_CONDITION] = { .type = NLA_U8 },
+ [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
+};
+
/* policy for GTK rekey offload attributes */
static const struct nla_policy
nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
@@ -1035,6 +1043,27 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
}
#endif
+static int nl80211_send_coalesce(struct sk_buff *msg,
+ struct cfg80211_registered_device *dev,
+ bool large)
+{
+ struct nl80211_coalesce_rule_support rule;
+
+ if (!dev->wiphy.coalesce.n_patterns || !dev->wiphy.coalesce.n_rules)
+ return 0;
+
+ rule.max_rules = dev->wiphy.coalesce.n_rules;
+ rule.pat.max_patterns = dev->wiphy.coalesce.n_patterns;
+ rule.pat.min_pattern_len = dev->wiphy.coalesce.pattern_min_len;
+ rule.pat.max_pattern_len = dev->wiphy.coalesce.pattern_max_len;
+ rule.pat.max_pkt_offset = dev->wiphy.coalesce.max_pkt_offset;
+
+ if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
+ return -ENOBUFS;
+
+ return 0;
+}
+
static int nl80211_send_band_rateinfo(struct sk_buff *msg,
struct ieee80211_supported_band *sband)
{
@@ -1546,6 +1575,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
dev->wiphy.vht_capa_mod_mask))
goto nla_put_failure;
+ (*split_start)++;
+ break;
+ case 10:
+ if (nl80211_send_coalesce(msg, dev, split))
+ goto nla_put_failure;
+
/* done */
*split_start = 0;
break;
@@ -8007,6 +8042,221 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
}
#endif
+static int nl80211_send_coalesce_rules(struct sk_buff *msg,
+ struct cfg80211_registered_device *rdev)
+{
+ struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
+ int i, j, pat_len;
+ struct cfg80211_coalesce_rules *rule;
+
+ if (!rdev->coalesce->n_rules)
+ return 0;
+
+ nl_rules = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
+ if (!nl_rules)
+ return -ENOBUFS;
+
+ for (i = 0; i < rdev->coalesce->n_rules; i++) {
+ nl_rule = nla_nest_start(msg, i + 1);
+ if (!nl_rule)
+ return -ENOBUFS;
+
+ rule = rdev->coalesce->rules[i];
+ if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
+ rule->delay))
+ return -ENOBUFS;
+
+ if (nla_put_u8(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
+ rule->condition))
+ return -ENOBUFS;
+
+ nl_pats = nla_nest_start(msg,
+ NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
+ if (!nl_pats)
+ return -ENOBUFS;
+
+ for (j = 0; j < rule->n_patterns; j++) {
+ nl_pat = nla_nest_start(msg, j + 1);
+ if (!nl_pat)
+ return -ENOBUFS;
+ pat_len = rule->patterns[j].pattern_len;
+ if (nla_put(msg, NL80211_PKTPAT_MASK,
+ DIV_ROUND_UP(pat_len, 8),
+ rule->patterns[j].mask) ||
+ nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
+ rule->patterns[j].pattern) ||
+ nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
+ rule->patterns[j].pkt_offset))
+ return -ENOBUFS;
+ nla_nest_end(msg, nl_pat);
+ }
+ nla_nest_end(msg, nl_pats);
+ nla_nest_end(msg, nl_rule);
+ }
+ nla_nest_end(msg, nl_rules);
+
+ return 0;
+}
+
+static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct sk_buff *msg;
+ void *hdr;
+
+ if (!rdev->wiphy.coalesce.n_patterns || !rdev->wiphy.coalesce.n_rules)
+ return -EOPNOTSUPP;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
+ NL80211_CMD_GET_COALESCE);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+ return genlmsg_reply(msg, info);
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return -ENOBUFS;
+}
+
+static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE];
+ struct wiphy_coalesce_support *coalesce = &rdev->wiphy.coalesce;
+ struct cfg80211_coalesce_rules new_rule = {};
+ struct cfg80211_coalesce_rules *nrule;
+ int err, i;
+
+ if (!(rdev->wiphy.features & NL80211_FEATURE_PACKET_COALESCE))
+ return -EOPNOTSUPP;
+ if (!rdev->ops->set_coalesce)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
+ cfg80211_rdev_free_coalesce(rdev);
+ rdev->coalesce = NULL;
+ rdev->ops->set_coalesce(&rdev->wiphy, NULL);
+ return 0;
+ }
+
+ if (!rdev->coalesce) {
+ rdev->coalesce = kzalloc(sizeof(*rdev->coalesce), GFP_KERNEL);
+ rdev->coalesce->rules = kcalloc(coalesce->n_rules,
+ sizeof(void *), GFP_KERNEL);
+ }
+
+ if (rdev->coalesce->n_rules >= coalesce->n_rules)
+ return -EOPNOTSUPP;
+
+ err = nla_parse(tb, NL80211_ATTR_COALESCE_RULE_MAX,
+ nla_data(info->attrs[NL80211_ATTR_COALESCE_RULE]),
+ nla_len(info->attrs[NL80211_ATTR_COALESCE_RULE]),
+ nl80211_coalesce_policy);
+ if (err)
+ return err;
+
+ new_rule.delay = nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
+ new_rule.condition =
+ nla_get_u8(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
+
+ if (tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN]) {
+ struct nlattr *pat;
+ int n_patterns = 0;
+ int rem, pat_len, mask_len, pkt_offset;
+ struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
+
+ nla_for_each_nested(pat,
+ tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
+ rem)
+ n_patterns++;
+ if (n_patterns > coalesce->n_patterns)
+ return -EINVAL;
+
+ new_rule.patterns = kcalloc(n_patterns,
+ sizeof(new_rule.patterns[0]),
+ GFP_KERNEL);
+ if (!new_rule.patterns)
+ return -ENOMEM;
+
+ new_rule.n_patterns = n_patterns;
+ i = 0;
+
+ nla_for_each_nested(pat,
+ tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
+ rem) {
+ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
+ nla_len(pat), NULL);
+ err = -EINVAL;
+ if (!pat_tb[NL80211_PKTPAT_MASK] ||
+ !pat_tb[NL80211_PKTPAT_PATTERN])
+ goto error;
+ pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
+ mask_len = DIV_ROUND_UP(pat_len, 8);
+ if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) !=
+ mask_len)
+ goto error;
+ if (pat_len > coalesce->pattern_max_len ||
+ pat_len < coalesce->pattern_min_len)
+ goto error;
+
+ if (!pat_tb[NL80211_PKTPAT_OFFSET])
+ pkt_offset = 0;
+ else
+ pkt_offset = nla_get_u32(
+ pat_tb[NL80211_PKTPAT_OFFSET]);
+ if (pkt_offset > coalesce->max_pkt_offset)
+ goto error;
+ new_rule.patterns[i].pkt_offset = pkt_offset;
+
+ new_rule.patterns[i].mask =
+ kmalloc(mask_len + pat_len, GFP_KERNEL);
+ if (!new_rule.patterns[i].mask) {
+ err = -ENOMEM;
+ goto error;
+ }
+ new_rule.patterns[i].pattern =
+ new_rule.patterns[i].mask + mask_len;
+ memcpy(new_rule.patterns[i].mask,
+ nla_data(pat_tb[NL80211_PKTPAT_MASK]),
+ mask_len);
+ new_rule.patterns[i].pattern_len = pat_len;
+ memcpy(new_rule.patterns[i].pattern,
+ nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
+ pat_len);
+ i++;
+ }
+ }
+
+ nrule = kmemdup(&new_rule, sizeof(new_rule), GFP_KERNEL);
+ if (!nrule) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ err = rdev->ops->set_coalesce(&rdev->wiphy, nrule);
+ if (err)
+ goto error;
+
+ rdev->coalesce->rules[rdev->coalesce->n_rules++] = nrule;
+
+ return 0;
+
+error:
+ for (i = 0; i < new_rule.n_patterns; i++)
+ kfree(new_rule.patterns[i].mask);
+ kfree(new_rule.patterns);
+ return err;
+}
+
static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -9026,6 +9276,21 @@ static struct genl_ops nl80211_ops[] = {
.flags = GENL_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_GET_COALESCE,
+ .doit = nl80211_get_coalesce,
+ .policy = nl80211_policy,
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_SET_COALESCE,
+ .doit = nl80211_set_coalesce,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
+ NL80211_FLAG_NEED_RTNL,
}
};
--
1.8.0
^ permalink raw reply related
* [PATCH v2 1/2] cfg80211/nl80211: rename packet pattern related structures and enums
From: Bing Zhao @ 2013-05-23 21:35 UTC (permalink / raw)
To: linux-wireless
Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar, Bing Zhao
From: Amitkumar Karwar <akarwar@marvell.com>
Currently packet patterns and it's enum/structures are used only
for WoWLAN feature. As we intend to reuse them for new feature
packet coalesce, they are renamed in this patch.
Older names are kept for backward compatibility purpose.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
v2: more details about the renames in commit log (Luis R. Rodriguez)
don't break the API with existing applications (Johannes Berg)
drivers/net/wireless/ath/ath9k/main.c | 2 +-
drivers/net/wireless/mwifiex/cfg80211.c | 3 +--
drivers/net/wireless/ti/wlcore/main.c | 10 ++++----
include/net/cfg80211.h | 6 ++---
include/uapi/linux/nl80211.h | 45 ++++++++++++++++++++-------------
net/wireless/nl80211.c | 34 ++++++++++++-------------
6 files changed, 53 insertions(+), 47 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6963862..57e290e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2123,7 +2123,7 @@ static void ath9k_wow_add_pattern(struct ath_softc *sc,
{
struct ath_hw *ah = sc->sc_ah;
struct ath9k_wow_pattern *wow_pattern = NULL;
- struct cfg80211_wowlan_trig_pkt_pattern *patterns = wowlan->patterns;
+ struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
int mask_len;
s8 i = 0;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index d3c8ece..7a06f51 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2250,8 +2250,7 @@ EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
#ifdef CONFIG_PM
static bool
-mwifiex_is_pattern_supported(struct cfg80211_wowlan_trig_pkt_pattern *pat,
- s8 *byte_seq)
+mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq)
{
int j, k, valid_byte_cnt = 0;
bool dont_care_byte = false;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 953111a..db3653f 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1328,7 +1328,7 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
#ifdef CONFIG_PM
static int
-wl1271_validate_wowlan_pattern(struct cfg80211_wowlan_trig_pkt_pattern *p)
+wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
{
int num_fields = 0, in_field = 0, fields_size = 0;
int i, pattern_len = 0;
@@ -1471,9 +1471,9 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
* Allocates an RX filter returned through f
* which needs to be freed using rx_filter_free()
*/
-static int wl1271_convert_wowlan_pattern_to_rx_filter(
- struct cfg80211_wowlan_trig_pkt_pattern *p,
- struct wl12xx_rx_filter **f)
+static int
+wl1271_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
+ struct wl12xx_rx_filter **f)
{
int i, j, ret = 0;
struct wl12xx_rx_filter *filter;
@@ -1575,7 +1575,7 @@ static int wl1271_configure_wowlan(struct wl1271 *wl,
/* Translate WoWLAN patterns into filters */
for (i = 0; i < wow->n_patterns; i++) {
- struct cfg80211_wowlan_trig_pkt_pattern *p;
+ struct cfg80211_pkt_pattern *p;
struct wl12xx_rx_filter *filter = NULL;
p = &wow->patterns[i];
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 32a2f1b..4585b63 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1661,7 +1661,7 @@ struct cfg80211_pmksa {
};
/**
- * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern
+ * struct cfg80211_pkt_pattern - packet pattern
* @mask: bitmask where to match pattern and where to ignore bytes,
* one bit per byte, in same format as nl80211
* @pattern: bytes to match where bitmask is 1
@@ -1671,7 +1671,7 @@ struct cfg80211_pmksa {
* Internal note: @mask and @pattern are allocated in one chunk of
* memory, free @mask only!
*/
-struct cfg80211_wowlan_trig_pkt_pattern {
+struct cfg80211_pkt_pattern {
u8 *mask, *pattern;
int pattern_len;
int pkt_offset;
@@ -1733,7 +1733,7 @@ struct cfg80211_wowlan {
bool any, disconnect, magic_pkt, gtk_rekey_failure,
eap_identity_req, four_way_handshake,
rfkill_release;
- struct cfg80211_wowlan_trig_pkt_pattern *patterns;
+ struct cfg80211_pkt_pattern *patterns;
struct cfg80211_wowlan_tcp *tcp;
int n_patterns;
};
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 0632071..1fa2bf4 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3041,11 +3041,11 @@ enum nl80211_tx_power_setting {
};
/**
- * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute
- * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute
- * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has
+ * enum nl80211_packet_pattern_attr - packet pattern attribute
+ * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute
+ * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has
* a zero bit are ignored
- * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have
+ * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have
* a bit for each byte in the pattern. The lowest-order bit corresponds
* to the first byte of the pattern, but the bytes of the pattern are
* in a little-endian-like format, i.e. the 9th byte of the pattern
@@ -3056,23 +3056,23 @@ enum nl80211_tx_power_setting {
* Note that the pattern matching is done as though frames were not
* 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
* first (including SNAP header unpacking) and then matched.
- * @NL80211_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after
+ * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after
* these fixed number of bytes of received packet
- * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
- * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
+ * @NUM_NL80211_PKTPAT: number of attributes
+ * @MAX_NL80211_PKTPAT: max attribute number
*/
-enum nl80211_wowlan_packet_pattern_attr {
- __NL80211_WOWLAN_PKTPAT_INVALID,
- NL80211_WOWLAN_PKTPAT_MASK,
- NL80211_WOWLAN_PKTPAT_PATTERN,
- NL80211_WOWLAN_PKTPAT_OFFSET,
+enum nl80211_packet_pattern_attr {
+ __NL80211_PKTPAT_INVALID,
+ NL80211_PKTPAT_MASK,
+ NL80211_PKTPAT_PATTERN,
+ NL80211_PKTPAT_OFFSET,
- NUM_NL80211_WOWLAN_PKTPAT,
- MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
+ NUM_NL80211_PKTPAT,
+ MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1,
};
/**
- * struct nl80211_wowlan_pattern_support - pattern support information
+ * struct nl80211_pattern_support - packet pattern support information
* @max_patterns: maximum number of patterns supported
* @min_pattern_len: minimum length of each pattern
* @max_pattern_len: maximum length of each pattern
@@ -3082,13 +3082,22 @@ enum nl80211_wowlan_packet_pattern_attr {
* that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
* capability information given by the kernel to userspace.
*/
-struct nl80211_wowlan_pattern_support {
+struct nl80211_pattern_support {
__u32 max_patterns;
__u32 min_pattern_len;
__u32 max_pattern_len;
__u32 max_pkt_offset;
} __attribute__((packed));
+/* only for backward compatibility */
+#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_INVALID,
+#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK
+#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN
+#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET
+#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT
+#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT
+#define nl80211_wowlan_pattern_support nl80211_pattern_support
+
/**
* enum nl80211_wowlan_triggers - WoWLAN trigger definitions
* @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
@@ -3108,7 +3117,7 @@ struct nl80211_wowlan_pattern_support {
* pattern matching is done after the packet is converted to the MSDU.
*
* In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
- * carrying a &struct nl80211_wowlan_pattern_support.
+ * carrying a &struct nl80211_pattern_support.
*
* When reporting wakeup. it is a u32 attribute containing the 0-based
* index of the pattern that caused the wakeup, in the patterns passed
@@ -3265,7 +3274,7 @@ struct nl80211_wowlan_tcp_data_token_feature {
* @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a
* u32 attribute holding the maximum length
* @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for
- * feature advertising. The mask works like @NL80211_WOWLAN_PKTPAT_MASK
+ * feature advertising. The mask works like @NL80211_PKTPAT_MASK
* but on the TCP payload only.
* @NUM_NL80211_WOWLAN_TCP: number of TCP attributes
* @MAX_NL80211_WOWLAN_TCP: highest attribute number
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5f10f7a..5f640de 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1014,7 +1014,7 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
return -ENOBUFS;
if (dev->wiphy.wowlan.n_patterns) {
- struct nl80211_wowlan_pattern_support pat = {
+ struct nl80211_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,
@@ -7570,12 +7570,11 @@ static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
if (!nl_pat)
return -ENOBUFS;
pat_len = rdev->wowlan->patterns[i].pattern_len;
- if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
- DIV_ROUND_UP(pat_len, 8),
+ if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
rdev->wowlan->patterns[i].mask) ||
- nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
- pat_len, rdev->wowlan->patterns[i].pattern) ||
- nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
+ nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
+ rdev->wowlan->patterns[i].pattern) ||
+ nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
rdev->wowlan->patterns[i].pkt_offset))
return -ENOBUFS;
nla_nest_end(msg, nl_pat);
@@ -7915,7 +7914,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
struct nlattr *pat;
int n_patterns = 0;
int rem, pat_len, mask_len, pkt_offset;
- struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
+ struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
rem)
@@ -7934,26 +7933,25 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
rem) {
- nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
- nla_data(pat), nla_len(pat), NULL);
+ nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
+ nla_len(pat), NULL);
err = -EINVAL;
- if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
- !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
+ if (!pat_tb[NL80211_PKTPAT_MASK] ||
+ !pat_tb[NL80211_PKTPAT_PATTERN])
goto error;
- pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
+ pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
mask_len = DIV_ROUND_UP(pat_len, 8);
- if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
- mask_len)
+ if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
goto error;
if (pat_len > wowlan->pattern_max_len ||
pat_len < wowlan->pattern_min_len)
goto error;
- if (!pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET])
+ if (!pat_tb[NL80211_PKTPAT_OFFSET])
pkt_offset = 0;
else
pkt_offset = nla_get_u32(
- pat_tb[NL80211_WOWLAN_PKTPAT_OFFSET]);
+ pat_tb[NL80211_PKTPAT_OFFSET]);
if (pkt_offset > wowlan->max_pkt_offset)
goto error;
new_triggers.patterns[i].pkt_offset = pkt_offset;
@@ -7967,11 +7965,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
new_triggers.patterns[i].pattern =
new_triggers.patterns[i].mask + mask_len;
memcpy(new_triggers.patterns[i].mask,
- nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
+ nla_data(pat_tb[NL80211_PKTPAT_MASK]),
mask_len);
new_triggers.patterns[i].pattern_len = pat_len;
memcpy(new_triggers.patterns[i].pattern,
- nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
+ nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
pat_len);
i++;
}
--
1.8.0
^ permalink raw reply related
* [PATCH v2 2/2] iw: add coalesce support
From: Bing Zhao @ 2013-05-23 21:35 UTC (permalink / raw)
To: linux-wireless
Cc: Johannes Berg, Luis R. Rodriguez, Jouni Malinen,
Vasanthakumar Thiagarajan, Senthil Balasubramanian,
Luciano Coelho, Amitkumar Karwar, Bing Zhao
In-Reply-To: <1369344941-11217-1-git-send-email-bzhao@marvell.com>
From: Amitkumar Karwar <akarwar@marvell.com>
User can add one coalesce rule at a time using 'iw coalesce add'
command. The settings can be cleared using 'iw coalesce disable'
command. 'iw coalesce show' displays current configuration.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
Makefile | 2 +-
coalesce.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
info.c | 14 ++++
3 files changed, 247 insertions(+), 1 deletion(-)
create mode 100644 coalesce.c
diff --git a/Makefile b/Makefile
index c485b5e..f042e30 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ OBJS = iw.o genl.o event.o info.o phy.o \
interface.o ibss.o station.o survey.o util.o \
mesh.o mpath.o scan.o reg.o version.o \
reason.o status.o connect.o link.o offch.o ps.o cqm.o \
- bitrate.o wowlan.o roc.o p2p.o
+ bitrate.o wowlan.o coalesce.o roc.o p2p.o
OBJS += sections.o
OBJS-$(HWSIM) += hwsim.o
diff --git a/coalesce.c b/coalesce.c
new file mode 100644
index 0000000..73f5d77
--- /dev/null
+++ b/coalesce.c
@@ -0,0 +1,232 @@
+#include <net/if.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include <arpa/inet.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+SECTION(coalesce);
+
+static int handle_coalesce_add(struct nl80211_state *state, struct nl_cb *cb,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *coalesce, *pattern;
+ struct nl_msg *patterns = NULL;
+ enum {
+ PS_REG,
+ PS_PAT,
+ } parse_state = PS_REG;
+ int err = -ENOBUFS;
+ unsigned char *pat, *mask;
+ size_t patlen;
+ int patnum = 0, pkt_offset;
+ char *eptr, *value1, *value2, *sptr = NULL, *end;
+ unsigned int condition;
+
+ coalesce = nla_nest_start(msg, NL80211_ATTR_COALESCE_RULE);
+ if (!coalesce)
+ return -ENOBUFS;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
+ strtoul(argv[0], &end, 10));
+ if (*end != '\0')
+ return 1;
+
+ argv++;
+ argc--;
+
+ condition = strtoul(argv[0], &end, 10);
+
+ if (condition != 1 && condition != 0)
+ return 1;
+
+ if (*end)
+ return 1;
+
+ NLA_PUT_U8(msg, NL80211_ATTR_COALESCE_RULE_CONDITION, condition);
+
+ argv++;
+ argc--;
+
+ while (argc) {
+ switch (parse_state) {
+ case PS_REG:
+ if (strcmp(argv[0], "patterns") == 0) {
+ parse_state = PS_PAT;
+ patterns = nlmsg_alloc();
+ if (!patterns) {
+ err = -ENOMEM;
+ goto nla_put_failure;
+ }
+ } else {
+ err = 1;
+ goto nla_put_failure;
+ }
+ break;
+ case PS_PAT:
+ value1 = strtok_r(argv[0], "+", &sptr);
+ value2 = strtok_r(NULL, "+", &sptr);
+
+ if (!value2) {
+ pkt_offset = 0;
+ value2 = value1;
+ } else {
+ pkt_offset = strtoul(value1, &eptr, 10);
+ if (eptr != value1 + strlen(value1)) {
+ err = 1;
+ goto nla_put_failure;
+ }
+ }
+
+ if (parse_hex_mask(value2, &pat, &patlen, &mask)) {
+ err = 1;
+ goto nla_put_failure;
+ }
+
+ pattern = nla_nest_start(patterns, ++patnum);
+ NLA_PUT(patterns, NL80211_PKTPAT_MASK,
+ DIV_ROUND_UP(patlen, 8), mask);
+ NLA_PUT(patterns, NL80211_PKTPAT_PATTERN, patlen, pat);
+ NLA_PUT_U32(patterns, NL80211_PKTPAT_OFFSET,
+ pkt_offset);
+ nla_nest_end(patterns, pattern);
+ free(mask);
+ free(pat);
+ break;
+ }
+ argv++;
+ argc--;
+ }
+
+ if (patterns)
+ nla_put_nested(msg, NL80211_ATTR_COALESCE_RULE_PKT_PATTERN,
+ patterns);
+
+ nla_nest_end(msg, coalesce);
+ err = 0;
+ nla_put_failure:
+ nlmsg_free(patterns);
+ return err;
+}
+COMMAND(coalesce, add, "<delay> <0|1> patterns [offset1+]<pattern1> ...]",
+ NL80211_CMD_SET_COALESCE, 0, CIB_PHY, handle_coalesce_add,
+ "Add coalesce rule.\n"
+ "Maximum coalescing delay in msec.\n"
+ "Condition is 0/1 i.e. 'not match'/'match' the patterns\n"
+ "Each pattern is given as a bytestring with '-' in places where any byte\n"
+ "may be present, e.g. 00:11:22:-:44 will match 00:11:22:33:44 and\n"
+ "00:11:22:33:ff:44 etc.\n"
+ "Offset and pattern should be separated by '+', e.g. 18+43:34:00:12 will\n"
+ "match '43:34:00:12' after 18 bytes of offset in Rx packet.\n");
+
+static int
+handle_coalesce_disable(struct nl80211_state *state, struct nl_cb *cb,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ /* just a set w/o coalesce attribute */
+ return 0;
+}
+COMMAND(coalesce, disable, "", NL80211_CMD_SET_COALESCE, 0, CIB_PHY,
+ handle_coalesce_disable, "Disable coalesce.");
+
+static int print_coalesce_handler(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *attrs[NL80211_ATTR_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ struct nlattr *pattern, *rule;
+ int rem_pattern, rem_rule;
+ bool condition;
+ int delay;
+
+ nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+
+ if (!attrs[NL80211_ATTR_COALESCE_RULE]) {
+ printf("Coalesce is disabled.\n");
+ return NL_SKIP;
+ }
+
+ printf("Coalesce is enabled:\n");
+
+ nla_for_each_nested(rule, attrs[NL80211_ATTR_COALESCE_RULE], rem_rule) {
+ struct nlattr *ruleattr[NUM_NL80211_ATTR_COALESCE_RULE];
+
+ nla_parse(ruleattr, NL80211_ATTR_COALESCE_RULE_MAX,
+ nla_data(rule), nla_len(rule), NULL);
+
+ delay = nla_get_u32(ruleattr[NL80211_ATTR_COALESCE_RULE_DELAY]);
+ condition =
+ nla_get_u8(ruleattr[NL80211_ATTR_COALESCE_RULE_CONDITION]);
+
+ printf("Rule - max coalescing delay: %dmsec condition:", delay);
+ if (condition)
+ printf("match\n");
+ else
+ printf("not match\n");
+
+ if (ruleattr[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN]) {
+ nla_for_each_nested(pattern,
+ ruleattr[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
+ rem_pattern) {
+ struct nlattr *patattr[NUM_NL80211_PKTPAT];
+ int i, patlen, masklen, pkt_offset;
+ uint8_t *mask, *pat;
+
+ nla_parse(patattr, MAX_NL80211_PKTPAT,
+ nla_data(pattern), nla_len(pattern),
+ NULL);
+ if (!patattr[NL80211_PKTPAT_MASK] ||
+ !patattr[NL80211_PKTPAT_PATTERN] ||
+ !patattr[NL80211_PKTPAT_OFFSET]) {
+ printf(" * (invalid pattern specification)\n");
+ continue;
+ }
+ masklen = nla_len(patattr[NL80211_PKTPAT_MASK]);
+ patlen = nla_len(patattr[NL80211_PKTPAT_PATTERN]);
+ pkt_offset = nla_get_u32(patattr[NL80211_PKTPAT_OFFSET]);
+ if (DIV_ROUND_UP(patlen, 8) != masklen) {
+ printf(" * (invalid pattern specification)\n");
+ continue;
+ }
+ printf(" * packet offset: %d", pkt_offset);
+ printf(" pattern: ");
+ pat = nla_data(patattr[NL80211_PKTPAT_PATTERN]);
+ mask = nla_data(patattr[NL80211_PKTPAT_MASK]);
+ for (i = 0; i < patlen; i++) {
+ if (mask[i / 8] & (1 << (i % 8)))
+ printf("%.2x", pat[i]);
+ else
+ printf("--");
+ if (i != patlen - 1)
+ printf(":");
+ }
+ printf("\n");
+ }
+ }
+ }
+
+ return NL_SKIP;
+}
+
+static int handle_coalesce_show(struct nl80211_state *state, struct nl_cb *cb,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
+ print_coalesce_handler, NULL);
+
+ return 0;
+}
+COMMAND(coalesce, show, "", NL80211_CMD_GET_COALESCE, 0, CIB_PHY, handle_coalesce_show,
+ "Show coalesce status.");
diff --git a/info.c b/info.c
index d893ffc..849da67 100644
--- a/info.c
+++ b/info.c
@@ -528,6 +528,20 @@ broken_combination:
printf("\tDevice supports AP scan.\n");
}
+ if (tb_msg[NL80211_ATTR_COALESCE_RULE]) {
+ struct nl80211_coalesce_rule_support *rule;
+ struct nl80211_pattern_support *pat;
+
+ printf("\tCoalesce support:\n");
+ rule = nla_data(tb_msg[NL80211_ATTR_COALESCE_RULE]);
+ pat = &rule->pat;
+ printf("\t\t * Maximum %u coalesce rules supported\n"
+ "\t\t * Each rule contains upto %u patterns of %u-%u bytes,\n"
+ "\t\t maximum packet offset %u bytes\n",
+ rule->max_rules, pat->max_patterns, pat->min_pattern_len,
+ pat->max_pattern_len, pat->max_pkt_offset);
+ }
+
return NL_SKIP;
}
--
1.8.0
^ permalink raw reply related
* Re: [PATCH v3 1/3] mac80211: add STBC flag for radiotap
From: Johannes Berg @ 2013-05-23 21:33 UTC (permalink / raw)
To: Oleksij Rempel; +Cc: ath9k-devel, linux-wireless
In-Reply-To: <1369318279-13768-1-git-send-email-linux@rempel-privat.de>
On Thu, 2013-05-23 at 16:11 +0200, Oleksij Rempel wrote:
> - *pos++ = local->hw.radiotap_mcs_details;
> +
> + /* MCS known field */
> + *pos = local->hw.radiotap_mcs_details;
> + if (stbc)
> + *pos |= IEEE80211_RADIOTAP_MCS_HAVE_STBC;
I think you shouldn't make this change, and the driver should include
the HAVE_STBC flag in the hw.radiotap_mcs_details. I actually thought of
this approach as well, but now just realized that this means that if the
driver _knows_ that a certain frame was received w/o STBC, this
knowledge cannot be transferred to the user, which would be a loss of
information.
> + if (stbc)
> + *pos |= (stbc >> RX_FLAG_STBC_SHIFT)
> + <<
> IEEE80211_RADIOTAP_MCS_STBC_SHIFT;
No need for the if() here, OR'ing in 0 doesn't do anything.
johannes
^ permalink raw reply
* [PATCH 3.10] mac80211: assign AP_VLAN hw queues correctly
From: Johannes Berg @ 2013-05-23 21:12 UTC (permalink / raw)
To: linux-wireless; +Cc: Jouni Malinen, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
A lot of code in mac80211 assumes that the hw queues are
set up correctly for all interfaces (except for monitor)
but this isn't true for AP_VLAN interfaces. Fix this by
copying the AP master configuration when an AP VLAN is
brought up, after this the AP interface can't change its
configuration any more and needs to be brought down to
change it, which also forces AP_VLAN interfaces down, so
just copying in open() is sufficient.
Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/iface.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 68f51c3..00e2238 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -474,6 +474,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
master->control_port_protocol;
sdata->control_port_no_encrypt =
master->control_port_no_encrypt;
+ sdata->vif.cab_queue = master->vif.cab_queue;
+ memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
+ sizeof(sdata->vif.hw_queue));
break;
}
case NL80211_IFTYPE_AP:
--
1.8.0
^ permalink raw reply related
* [PATCH 3.9] iwlwifi: mvm: remove P2P_DEVICE support
From: Johannes Berg @ 2013-05-23 20:24 UTC (permalink / raw)
To: linux-wireless; +Cc: stable, Jouni Malinen, Arend van Spriel, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Unfortunately, advertising P2P_DEVICE support was a little
premature, a number of issues came up in testing and have
been fixed for 3.10. Rather than try to backport all the
different fixes, disable P2P_DEVICE support in the drivers
using it. For iwlmvm that implies disabling P2P completely
as it can't support P2P operation w/o P2P Device.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index dd158ec..11dc7df 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -84,15 +84,6 @@ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
.types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP),
},
- {
- .max = 1,
- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
- BIT(NL80211_IFTYPE_P2P_GO),
- },
- {
- .max = 1,
- .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
- },
};
static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
@@ -161,10 +152,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt);
hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_P2P_CLIENT) |
- BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_DEVICE);
+ BIT(NL80211_IFTYPE_AP);
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_DISABLE_BEACON_HINTS |
--
1.8.0
^ permalink raw reply related
* [PATCH 3.6-3.9] mac80211_hwsim: remove P2P_DEVICE support
From: Johannes Berg @ 2013-05-23 20:24 UTC (permalink / raw)
To: linux-wireless; +Cc: stable, Jouni Malinen, Arend van Spriel, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Unfortunately, advertising P2P_DEVICE support was a little
premature, a number of issues came up in testing and have
been fixed for 3.10. Rather than try to backport all the
different fixes, disable P2P_DEVICE support in the drivers
using it.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
drivers/net/wireless/mac80211_hwsim.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index cb34c78..69bbf6f 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2169,7 +2169,6 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
#endif
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_GO) },
- { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
};
static struct ieee80211_iface_combination hwsim_if_comb = {
@@ -2295,8 +2294,7 @@ static int __init init_mac80211_hwsim(void)
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_MESH_POINT) |
- BIT(NL80211_IFTYPE_P2P_DEVICE);
+ BIT(NL80211_IFTYPE_MESH_POINT);
hw->flags = IEEE80211_HW_MFP_CAPABLE |
IEEE80211_HW_SIGNAL_DBM |
--
1.8.0
^ permalink raw reply related
* Re: [PATCH 3.10] cfg80211: fix reporting 64-bit station info tx bytes
From: Johannes Berg @ 2013-05-23 20:09 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless
In-Reply-To: <1369314359-99291-1-git-send-email-nbd@openwrt.org>
On Thu, 2013-05-23 at 15:05 +0200, Felix Fietkau wrote:
> Copy & paste mistake - STATION_INFO_TX_BYTES64 is the name of the flag,
> not NL80211_STA_INFO_TX_BYTES64.
Applied, thanks.
johannes
^ permalink raw reply
* [PATCH 3.10] mac80211: fix queue handling crash
From: Johannes Berg @ 2013-05-23 19:16 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
The code I added in "mac80211: don't start new netdev queues
if driver stopped" crashes for monitor and AP VLAN interfaces
because while they have a netdev, they don't have queues set
up by the driver.
To fix the crash, exclude these from queue accounting here
and just start their netdev queues unconditionally.
For monitor, this is the best we can do, as we can redirect
frames there to any other interface and don't know which one
that will since it can be different for each frame.
For AP VLAN interfaces, we can do better later and actually
properly track the queue status. Not doing this is really a
separate bug though.
Reported-by: Ilan Peer <ilan.peer@intel.com>
Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/iface.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 60f1ce5..68f51c3 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -653,7 +653,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
ieee80211_recalc_ps(local, -1);
- if (dev) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+ /* XXX: for AP_VLAN, actually track AP queues */
+ netif_tx_start_all_queues(dev);
+ } else if (dev) {
unsigned long flags;
int n_acs = IEEE80211_NUM_ACS;
int ac;
--
1.8.0
^ permalink raw reply related
* linux-firmware: pull-request Marvell mwifiex-firmware 2013-05-23
From: Bing Zhao @ 2013-05-23 18:49 UTC (permalink / raw)
To: Ben Hutchings; +Cc: linux-wireless, Frank Huang, Bing Zhao
The following changes since commit 07ea598af5b9dde3acdf279846b062fa1b2987b8:
Merge branch 'linux-firmware' of git://github.com/TI-OpenLink/firmwares (2013-05-06 14:21:49 +0100)
are available in the git repository at:
git://git.marvell.com/mwifiex-firmware.git master
for you to fetch changes up to 009719f9eca7a9d61b9c3cba5dbafbf937d93c80:
linux-firmware: add Marvell PCIe8897-B0 WLAN firmware image (2013-05-22 18:23:52 -0700)
----------------------------------------------------------------
Bing Zhao (1):
linux-firmware: add Marvell PCIe8897-B0 WLAN firmware image
WHENCE | 5 ++++-
mrvl/pcie8897_uapsta.bin | Bin 0 -> 350244 bytes
2 files changed, 4 insertions(+), 1 deletion(-)
create mode 100644 mrvl/pcie8897_uapsta.bin
diff --git a/WHENCE b/WHENCE
index c08336a..d1a2713 100644
--- a/WHENCE
+++ b/WHENCE
@@ -716,7 +716,7 @@ directly by Marvell.
--------------------------------------------------------------------------
-Driver: mwifiex - Marvell Wi-Fi fullmac-type 802.11n card
+Driver: mwifiex - Marvell Wi-Fi fullmac-type 802.11n/ac cards
File: mrvl/sd8787_uapsta.bin
Version: 14.66.9.p96
@@ -727,6 +727,9 @@ Version: 14.66.11.p151
File: mrvl/usb8797_uapsta.bin
Version: 14.69.11.p179
+File: mrvl/pcie8897_uapsta.bin
+Version: 15.69.201.p52
+
Licence: Redistributable. See LICENCE.Marvell for details. Originates from
http://git.marvell.com/?p=mwifiex-firmware.git
diff --git a/mrvl/pcie8897_uapsta.bin b/mrvl/pcie8897_uapsta.bin
new file mode 100644
index 0000000..b067689
Binary files /dev/null and b/mrvl/pcie8897_uapsta.bin differ
^ permalink raw reply related
* Re: [PATCH V7 1/3] cfg80211: introduce critical protocol indication from user-space
From: Dan Williams @ 2013-05-23 18:30 UTC (permalink / raw)
To: Arend van Spriel; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <1366292942-21038-1-git-send-email-arend@broadcom.com>
On Thu, 2013-04-18 at 15:49 +0200, Arend van Spriel wrote:
> Some protocols need a more reliable connection to complete
> successful in reasonable time. This patch adds a user-space
> API to indicate the wireless driver that a critical protocol
> is about to commence and when it is done, using nl80211 primitives
> NL80211_CMD_CRIT_PROTOCOL_START and NL80211_CRIT_PROTOCOL_STOP.
>
> There can be only on critical protocol session started per
> registered cfg80211 device.
Ok, so while implementing support for this in NetworkManager, I ran into
a few questions some issues.
1) Why have a new attribute? Why not just use NL80211_ATTR_DURATION
like all the other commands do?
2) Why have a restriction on a single critical protocol at a time? Even
if this is the case *now*, just for sake of time, we should pass the
protocol to the _STOP command to allow for multiples in the future.
Yeah, you won't have EAPOL running at the same time as DHCP, but think
about it from userspace's perspective:
a) process A starts critical protocol like EAPOL
b) process A forgets to stop critical protocol
c) process B starts critical protocol DHCP, oops, error!
d) process B has to clear old critical protocol
e) process B starts critical protocol DHCP
f) process A realizes it forgot (b) and stops protocol
I think there's a lot of opportunity for races here. This would at
least be reduced if the START/STOP commands were paired for a specific
protocol, and if something requested a STOP for a protocol that's
currently not started, it was rejected.
Better yet, why not just have an internal array of all the protocols
with their max duration and start time, and the stack manages when each
protocol gets stopped? (unless you think drivers will have different
behavior on a per-protocol basis, eg they'd do something different with
DHCP than with EAPOL...?)
Dan
> The driver can support this by implementing the cfg80211 callbacks
> .crit_proto_start() and .crit_proto_stop(). Examples of protocols
> that can benefit from this are DHCP, EAPOL, APIPA. Exactly how the
> link can/should be made more reliable is up to the driver. Things
> to consider are avoid scanning, no multi-channel operations, and
> alter coexistence schemes.
>
> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
> Signed-off-by: Arend van Spriel <arend@broadcom.com>
> ---
> Hi Johannes,
>
> Not sure whether you made the minor fixes already as you offered
> to do so. I saw the change pop-up in your repo a couple of nights
> ago, but it disappeared the next morning after another fetch.
>
> I also made related changes in our brcmfmac driver. Can you take
> them through your tree as well.
>
> Regards,
> Arend
>
> Changelog:
> ----------
> V7:
> - remove crit_proto_started field from wireless_dev.
> - remove CRIT_PROTO_STOPPED_EVENT definition.
> - allow always calling cfg80211_crit_proto_stopped().
> V6:
> - added crit_proto_stopped event message.
> - use nlportid as flag for critical protocol being active.
> - return error when duration is over specified limit.
> - remove logic from rdev_* inline wrappers.
> - added more documentation.
> - some renaming of identifiers.
> V5:
> - change return type for .crit_prot_stop() to void.
> - correct limiting the duration.
> V4:
> - added cfg80211_crit_proto_stopped() for drivers to use.
> - added back protocol identifier for drivers to use.
> - reject starting critical protocol session when already started.
> - critical protocol session tracked per registered device.
> V3:
> - remove protocol identifier.
> - remove delayed work from cfg80211.
> - guard maximum limit for duration.
> - do .crit_proto_stop() upon netlink socket release.
> V2:
> - subject changed. Below previous subject is given for reference:
> [RFC] cfg80211: configuration of Bluetooth coexistence mode
> - introduced dedicated nl80211 API.
> V1:
> - initial proposal.
> ---
> include/net/cfg80211.h | 23 +++++++++
> include/uapi/linux/nl80211.h | 39 ++++++++++++++
> net/wireless/core.h | 3 ++
> net/wireless/mlme.c | 5 ++
> net/wireless/nl80211.c | 117 ++++++++++++++++++++++++++++++++++++++++++
> net/wireless/rdev-ops.h | 24 ++++++++-
> net/wireless/trace.h | 35 +++++++++++++
> 7 files changed, 245 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index dff96d8..26b5b69 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -2002,6 +2002,12 @@ struct cfg80211_update_ft_ies_params {
> * @update_ft_ies: Provide updated Fast BSS Transition information to the
> * driver. If the SME is in the driver/firmware, this information can be
> * used in building Authentication and Reassociation Request frames.
> + *
> + * @crit_proto_start: Indicates a critical protocol needs more link reliability
> + * for a given duration (milliseconds). The protocol is provided so the
> + * driver can take the most appropriate actions.
> + * @crit_proto_stop: Indicates critical protocol no longer needs increased link
> + * reliability. This operation can not fail.
> */
> struct cfg80211_ops {
> int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
> @@ -2231,6 +2237,12 @@ struct cfg80211_ops {
> struct cfg80211_chan_def *chandef);
> int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
> struct cfg80211_update_ft_ies_params *ftie);
> + int (*crit_proto_start)(struct wiphy *wiphy,
> + struct wireless_dev *wdev,
> + enum nl80211_crit_proto_id protocol,
> + u16 duration);
> + void (*crit_proto_stop)(struct wiphy *wiphy,
> + struct wireless_dev *wdev);
> };
>
> /*
> @@ -4137,6 +4149,17 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
> struct cfg80211_wowlan_wakeup *wakeup,
> gfp_t gfp);
>
> +/**
> + * cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver.
> + *
> + * @wdev: the wireless device for which critical protocol is stopped.
> + *
> + * This function can be called by the driver to indicate it has reverted
> + * operation back to normal. One reason could be that the duration given
> + * by .crit_proto_start() has expired.
> + */
> +void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp);
> +
> /* Logging, debugging and troubleshooting/diagnostic helpers. */
>
> /* wiphy_printk helpers, similar to dev_printk */
> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index 79da871..d1e48b5 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -639,6 +639,13 @@
> * with the relevant Information Elements. This event is used to report
> * received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE).
> *
> + * @NL80211_CMD_CRIT_PROTOCOL_START: Indicates user-space will start running
> + * a critical protocol that needs more reliability in the connection to
> + * complete.
> + *
> + * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can
> + * return back to normal.
> + *
> * @NL80211_CMD_MAX: highest used command number
> * @__NL80211_CMD_AFTER_LAST: internal use
> */
> @@ -798,6 +805,9 @@ enum nl80211_commands {
> NL80211_CMD_UPDATE_FT_IES,
> NL80211_CMD_FT_EVENT,
>
> + NL80211_CMD_CRIT_PROTOCOL_START,
> + NL80211_CMD_CRIT_PROTOCOL_STOP,
> +
> /* add new commands above here */
>
> /* used to define NL80211_CMD_MAX below */
> @@ -1414,6 +1424,11 @@ enum nl80211_commands {
> * @NL80211_ATTR_IE_RIC: Resource Information Container Information
> * Element
> *
> + * @NL80211_ATTR_CRIT_PROT_ID: critical protocol identifier requiring increased
> + * reliability, see &enum nl80211_crit_proto_id (u16).
> + * @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which
> + * the connection should have increased reliability (u16).
> + *
> * @NL80211_ATTR_MAX: highest attribute number currently defined
> * @__NL80211_ATTR_AFTER_LAST: internal use
> */
> @@ -1709,6 +1724,9 @@ enum nl80211_attrs {
> NL80211_ATTR_MDID,
> NL80211_ATTR_IE_RIC,
>
> + NL80211_ATTR_CRIT_PROT_ID,
> + NL80211_ATTR_MAX_CRIT_PROT_DURATION,
> +
> /* add attributes here, update the policy in nl80211.c */
>
> __NL80211_ATTR_AFTER_LAST,
> @@ -3682,4 +3700,25 @@ enum nl80211_protocol_features {
> NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0,
> };
>
> +/**
> + * enum nl80211_crit_proto_id - nl80211 critical protocol identifiers
> + *
> + * @NL80211_CRIT_PROTO_UNSPEC: protocol unspecified.
> + * @NL80211_CRIT_PROTO_DHCP: BOOTP or DHCPv6 protocol.
> + * @NL80211_CRIT_PROTO_EAPOL: EAPOL protocol.
> + * @NL80211_CRIT_PROTO_APIPA: APIPA protocol.
> + * @NUM_NL80211_CRIT_PROTO: must be kept last.
> + */
> +enum nl80211_crit_proto_id {
> + NL80211_CRIT_PROTO_UNSPEC,
> + NL80211_CRIT_PROTO_DHCP,
> + NL80211_CRIT_PROTO_EAPOL,
> + NL80211_CRIT_PROTO_APIPA,
> + /* add other protocols before this one */
> + NUM_NL80211_CRIT_PROTO
> +};
> +
> +/* maximum duration for critical protocol measures */
> +#define NL80211_CRIT_PROTO_MAX_DURATION 5000 /* msec */
> +
> #endif /* __LINUX_NL80211_H */
> diff --git a/net/wireless/core.h b/net/wireless/core.h
> index d5d06fd..eac5308 100644
> --- a/net/wireless/core.h
> +++ b/net/wireless/core.h
> @@ -88,6 +88,9 @@ struct cfg80211_registered_device {
>
> struct delayed_work dfs_update_channels_wk;
>
> + /* netlink port which started critical protocol (0 means not started) */
> + u32 crit_proto_nlportid;
> +
> /* must be last because of the way we do wiphy_priv(),
> * and it should at least be aligned to NETDEV_ALIGN */
> struct wiphy wiphy __aligned(NETDEV_ALIGN);
> diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
> index 390198b..0c7b7dd 100644
> --- a/net/wireless/mlme.c
> +++ b/net/wireless/mlme.c
> @@ -648,6 +648,11 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
>
> spin_unlock_bh(&wdev->mgmt_registrations_lock);
>
> + if (nlportid && rdev->crit_proto_nlportid == nlportid) {
> + rdev->crit_proto_nlportid = 0;
> + rdev_crit_proto_stop(rdev, wdev);
> + }
> +
> if (nlportid == wdev->ap_unexpected_nlportid)
> wdev->ap_unexpected_nlportid = 0;
> }
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index f924d45..96ba1eb 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -1417,6 +1417,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
> }
> CMD(start_p2p_device, START_P2P_DEVICE);
> CMD(set_mcast_rate, SET_MCAST_RATE);
> + if (split) {
> + CMD(crit_proto_start, CRIT_PROTOCOL_START);
> + CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
> + }
>
> #ifdef CONFIG_NL80211_TESTMODE
> CMD(testmode_cmd, TESTMODE);
> @@ -8196,6 +8200,64 @@ static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
> return rdev_update_ft_ies(rdev, dev, &ft_params);
> }
>
> +static int nl80211_crit_protocol_start(struct sk_buff *skb,
> + struct genl_info *info)
> +{
> + struct cfg80211_registered_device *rdev = info->user_ptr[0];
> + struct wireless_dev *wdev = info->user_ptr[1];
> + enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
> + u16 duration;
> + int ret;
> +
> + if (!rdev->ops->crit_proto_start)
> + return -EOPNOTSUPP;
> +
> + if (WARN_ON(!rdev->ops->crit_proto_stop))
> + return -EINVAL;
> +
> + if (rdev->crit_proto_nlportid)
> + return -EBUSY;
> +
> + /* determine protocol if provided */
> + if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
> + proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
> +
> + if (proto >= NUM_NL80211_CRIT_PROTO)
> + return -EINVAL;
> +
> + /* timeout must be provided */
> + if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
> + return -EINVAL;
> +
> + duration =
> + nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
> +
> + if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
> + return -ERANGE;
> +
> + ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
> + if (!ret)
> + rdev->crit_proto_nlportid = info->snd_portid;
> +
> + return ret;
> +}
> +
> +static int nl80211_crit_protocol_stop(struct sk_buff *skb,
> + struct genl_info *info)
> +{
> + struct cfg80211_registered_device *rdev = info->user_ptr[0];
> + struct wireless_dev *wdev = info->user_ptr[1];
> +
> + if (!rdev->ops->crit_proto_stop)
> + return -EOPNOTSUPP;
> +
> + if (rdev->crit_proto_nlportid) {
> + rdev->crit_proto_nlportid = 0;
> + rdev_crit_proto_stop(rdev, wdev);
> + }
> + return 0;
> +}
> +
> #define NL80211_FLAG_NEED_WIPHY 0x01
> #define NL80211_FLAG_NEED_NETDEV 0x02
> #define NL80211_FLAG_NEED_RTNL 0x04
> @@ -8885,6 +8947,22 @@ static struct genl_ops nl80211_ops[] = {
> .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
> NL80211_FLAG_NEED_RTNL,
> },
> + {
> + .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
> + .doit = nl80211_crit_protocol_start,
> + .policy = nl80211_policy,
> + .flags = GENL_ADMIN_PERM,
> + .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
> + NL80211_FLAG_NEED_RTNL,
> + },
> + {
> + .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
> + .doit = nl80211_crit_protocol_stop,
> + .policy = nl80211_policy,
> + .flags = GENL_ADMIN_PERM,
> + .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
> + NL80211_FLAG_NEED_RTNL,
> + }
> };
>
> static struct genl_multicast_group nl80211_mlme_mcgrp = {
> @@ -10630,6 +10708,45 @@ void cfg80211_ft_event(struct net_device *netdev,
> }
> EXPORT_SYMBOL(cfg80211_ft_event);
>
> +void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
> +{
> + struct cfg80211_registered_device *rdev;
> + struct sk_buff *msg;
> + void *hdr;
> + u32 nlportid;
> +
> + rdev = wiphy_to_dev(wdev->wiphy);
> + if (!rdev->crit_proto_nlportid)
> + return;
> +
> + nlportid = rdev->crit_proto_nlportid;
> + rdev->crit_proto_nlportid = 0;
> +
> + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
> + if (!msg)
> + return;
> +
> + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
> + if (!hdr)
> + goto nla_put_failure;
> +
> + if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
> + nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)))
> + goto nla_put_failure;
> +
> + genlmsg_end(msg, hdr);
> +
> + genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
> + return;
> +
> + nla_put_failure:
> + if (hdr)
> + genlmsg_cancel(msg, hdr);
> + nlmsg_free(msg);
> +
> +}
> +EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
> +
> /* initialisation/exit functions */
>
> int nl80211_init(void)
> diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
> index d77e1c1..9f15f0a 100644
> --- a/net/wireless/rdev-ops.h
> +++ b/net/wireless/rdev-ops.h
> @@ -875,7 +875,7 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev,
> trace_rdev_stop_p2p_device(&rdev->wiphy, wdev);
> rdev->ops->stop_p2p_device(&rdev->wiphy, wdev);
> trace_rdev_return_void(&rdev->wiphy);
> -}
> +}
>
> static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev,
> struct net_device *dev,
> @@ -901,4 +901,26 @@ static inline int rdev_update_ft_ies(struct cfg80211_registered_device *rdev,
> return ret;
> }
>
> +static inline int rdev_crit_proto_start(struct cfg80211_registered_device *rdev,
> + struct wireless_dev *wdev,
> + enum nl80211_crit_proto_id protocol,
> + u16 duration)
> +{
> + int ret;
> +
> + trace_rdev_crit_proto_start(&rdev->wiphy, wdev, protocol, duration);
> + ret = rdev->ops->crit_proto_start(&rdev->wiphy, wdev,
> + protocol, duration);
> + trace_rdev_return_int(&rdev->wiphy, ret);
> + return ret;
> +}
> +
> +static inline void rdev_crit_proto_stop(struct cfg80211_registered_device *rdev,
> + struct wireless_dev *wdev)
> +{
> + trace_rdev_crit_proto_stop(&rdev->wiphy, wdev);
> + rdev->ops->crit_proto_stop(&rdev->wiphy, wdev);
> + trace_rdev_return_void(&rdev->wiphy);
> +}
> +
> #endif /* __CFG80211_RDEV_OPS */
> diff --git a/net/wireless/trace.h b/net/wireless/trace.h
> index ccadef2..499c982 100644
> --- a/net/wireless/trace.h
> +++ b/net/wireless/trace.h
> @@ -1805,6 +1805,41 @@ TRACE_EVENT(rdev_update_ft_ies,
> WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->md)
> );
>
> +TRACE_EVENT(rdev_crit_proto_start,
> + TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
> + enum nl80211_crit_proto_id protocol, u16 duration),
> + TP_ARGS(wiphy, wdev, protocol, duration),
> + TP_STRUCT__entry(
> + WIPHY_ENTRY
> + WDEV_ENTRY
> + __field(u16, proto)
> + __field(u16, duration)
> + ),
> + TP_fast_assign(
> + WIPHY_ASSIGN;
> + WDEV_ASSIGN;
> + __entry->proto = protocol;
> + __entry->duration = duration;
> + ),
> + TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", proto=%x, duration=%u",
> + WIPHY_PR_ARG, WDEV_PR_ARG, __entry->proto, __entry->duration)
> +);
> +
> +TRACE_EVENT(rdev_crit_proto_stop,
> + TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
> + TP_ARGS(wiphy, wdev),
> + TP_STRUCT__entry(
> + WIPHY_ENTRY
> + WDEV_ENTRY
> + ),
> + TP_fast_assign(
> + WIPHY_ASSIGN;
> + WDEV_ASSIGN;
> + ),
> + TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT,
> + WIPHY_PR_ARG, WDEV_PR_ARG)
> +);
> +
> /*************************************************************
> * cfg80211 exported functions traces *
> *************************************************************/
^ permalink raw reply
* Re: How to set basic rates in mesh mode?
From: Ashok Nagarajan @ 2013-05-23 16:49 UTC (permalink / raw)
To: Jean-Pierre Tosoni; +Cc: linux-wireless, devel
In-Reply-To: <002301ce57cc$dcaeef40$960ccdc0$@acksys.fr>
Hi Tosoni,
On Thu, May 23, 2013 at 8:47 AM, Jean-Pierre Tosoni <jp.tosoni@acksys.fr> wrote:
> Hi all,
>
> Is there a way to change the basic rates set in mesh mode ?
> (so that broadcasts and ACKs could be sent faster)
>
Not with the current ToT. But patches to support this feature have
been sent and is waiting to get merged.
If you would like to use the feature now, you could find these patches here.
1. https://patchwork.kernel.org/patch/2552611/
2. https://patchwork.kernel.org/patch/2552621/
and 3. https://patchwork.kernel.org/patch/2552641/
Thanks,
Ashok
> - iw does not do this, and cfg80211 rejects NL80211_CMD_SET_BSS for mesh
> interfaces, I cannot figure out another way ?
>
> Regards
> j.p. Tosoni
>
>
> --
> 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
--
Ashok Raj Nagarajan,
cozybit Inc.
http://www.cozybit.com
^ permalink raw reply
* Re: Ralink RT3290 proprietary drivers causing kernel panic
From: Andreas Hartmann @ 2013-05-23 16:18 UTC (permalink / raw)
To: Mohit, Gertjan van Wingerde, linux-wireless
In-Reply-To: <519E09BE.6060802@pdm.ac.in>
Mohit wrote:
[...]
> The drivers work in kernel 3.2 but stop working from either kernel ver.
> 3.3, 3.4 or 3.5.
>From my experience, it seems more to be a compiler / binutils problem:
See
http://news.gmane.org/find-root.php?group=gmane.linux.drivers.rt2x00.user&article=1765
> The drivers included in the kernel work, but they are a buggy, have low
> range, connection drops etc.
Exactly my experience here, especially the USB ones (but seems to be
heavily hardware dependent). And they produce enormous cpu load as soon
as throughput rises.
That's why I'm only using the vendor driver (for STA), too (besides the
point that rt2800usb doesn't support a Linksys AE3000 at all e.g.
(http://wikidevi.com/wiki/Linksys_AE3000), which is a really fine device!)
> I switched from Linux mint 13 kernel 3.2, installed the proprietary
> driver and it is way better than rt2800pci drivers interms of signal
> strength, latency, speed etc. I think the proprietary drivers use
> rt2860pci driver instead of a dedicated rt3290sta driver.
>
> Can the drivers included in the kernel be tweaked to match the
> proprietary driver?
It would be cool on the one hand, if Mediatek would integrate their own
drivers themselves to mac80211, but on the other hand, I fear, this is
mostly impossible because mac80211 (which was heavily built for and from
Atheros and Intel and therefore "optimized" for there own needs) doesn't
match the requirements of the Ralink hardware.
That's why I'm happy they don't integrate their drivers in the existing
mac80211 because I fear a likewise bad quality.
I think the maintainer of rt2800 do all they can given the opportunities
they have so far. Unfortunately, they have very little opportunities
from my point of view.
Kind regards,
Andreas
^ permalink raw reply
* [PATCH 3.10] cfg80211: check wdev->netdev in connection work
From: Johannes Berg @ 2013-05-23 16:12 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
If a P2P-Device is present and another virtual interface triggers
the connection work, the system crash because it tries to check
if the P2P-Device's netdev (which doesn't exist) is up. Skip any
wdevs that have no netdev to fix this.
Cc: stable@vger.kernel.org
Reported-by: YanBo <dreamfly281@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/wireless/sme.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index a9dc5c7..7801fff 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -231,6 +231,9 @@ void cfg80211_conn_work(struct work_struct *work)
mutex_lock(&rdev->sched_scan_mtx);
list_for_each_entry(wdev, &rdev->wdev_list, list) {
+ if (!wdev->netdev)
+ continue;
+
wdev_lock(wdev);
if (!netif_running(wdev->netdev)) {
wdev_unlock(wdev);
--
1.8.0
^ permalink raw reply related
* Re: [RFC v4] cfg80211: Android P2P-Device workaround
From: Johannes Berg @ 2013-05-23 16:08 UTC (permalink / raw)
To: YanBo; +Cc: Arend van Spriel, linux-wireless
In-Reply-To: <CAFuUQkiVHPNzRNdAnLnRkE0_w2ZERu_S4++3PcD504KCL8NBdA@mail.gmail.com>
On Thu, 2013-05-23 at 22:40 +0800, YanBo wrote:
> It do make crash in my test. and the crash point to this sentence,
> after apply this patch, the crash gone.
>
> Step in my test to reproduce this crash (on one android phone )
>
> 1: Create the p2p devices
> 2: Wake up both p2p0 and wlan0.
> 3: iw wlan0 scan to get the scan AP
> 4: iw wlan0 connect SSID freq macaddress to connect a open AP
> normally the crash will happened after step 4
Ok yeah I can reproduce this, it's entirely unrelated to this particular
patch but even upstream -- the function is missing a check
"wdev->netdev". I'll send a patch.
johannes
^ permalink raw reply
* How to set basic rates in mesh mode?
From: Jean-Pierre Tosoni @ 2013-05-23 15:47 UTC (permalink / raw)
To: linux-wireless, devel
Hi all,
Is there a way to change the basic rates set in mesh mode ?
(so that broadcasts and ACKs could be sent faster)
- iw does not do this, and cfg80211 rejects NL80211_CMD_SET_BSS for mesh
interfaces, I cannot figure out another way ?
Regards
j.p. Tosoni
^ permalink raw reply
* Re: [RFC v4] cfg80211: Android P2P-Device workaround
From: YanBo @ 2013-05-23 14:40 UTC (permalink / raw)
To: Johannes Berg; +Cc: Arend van Spriel, linux-wireless
In-Reply-To: <1369302019.12002.0.camel@jlt4.sipsolutions.net>
It do make crash in my test. and the crash point to this sentence,
after apply this patch, the crash gone.
Step in my test to reproduce this crash (on one android phone )
1: Create the p2p devices
2: Wake up both p2p0 and wlan0.
3: iw wlan0 scan to get the scan AP
4: iw wlan0 connect SSID freq macaddress to connect a open AP
normally the crash will happened after step 4
BR /Yanbo
On Thu, May 23, 2013 at 5:40 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Thu, 2013-05-23 at 11:18 +0800, YanBo wrote:
>> After create the p2p0 wireless device. When call the
>> cfg80211_conn_work
>
> How is that getting called in the first place? I'm not saying there's no
> bug, but your suggested fix is completely pointless, we shouldn't get
> there.
>
> johannes
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox