* Re: [PATCHv2 2/3] mac80211: enable DFS for IBSS mode
From: Johannes Berg @ 2013-10-09 8:03 UTC (permalink / raw)
To: Simon Wunderlich; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1381164067-4830-3-git-send-email-siwu@hrz.tu-chemnitz.de>
On Mon, 2013-10-07 at 18:41 +0200, Simon Wunderlich wrote:
> Allow changing to DFS channels if the channel is available for
> beaconing and userspace controls DFS operation.
>
> Channel switch announcement from other stations on DFS channels will
> be interpreted as radar event. These channels will then be marked as
> unvailable.
Applied
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: Pass station supported channel and oper class info to kernel
From: Johannes Berg @ 2013-10-09 8:31 UTC (permalink / raw)
To: Undekari, Sunil Dutt; +Cc: j@w1.fi.com, linux-wireless
In-Reply-To: <26F3B0343EE4744AA14EEEF9E1E534511F725129@aphydexd01a>
On Wed, 2013-10-09 at 08:19 +0000, Undekari, Sunil Dutt wrote:
> Hi Johannes,
>
> >I guess then wpa_supplicant would have to remove the info - maybe the failure case shouldn't be quite as draconic? Maybe make it ignore any extra trailing byte?
> Thanks for your point.
> I suppose, returning a failure for the length being less than 2 even after ignoring the trailing byte is not required for the reason that the supported channels is not a mandatory field (at least w.r.t TDLS). It should be fine to just pass the length as 0 to the host driver. Please correct me.
It's just a question of where to address this - in the kernel or the
supplicant. In a way, I'd rather have the kernel reject it and do the
policy of ignoring invalid stuff in the supplicant.
johannes
^ permalink raw reply
* [PATCH] rt2x00: use generic EWMA functions for average RSSI calculations
From: Gabor Juhos @ 2013-10-09 9:00 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, users, Gabor Juhos
Remove the local MOVING_AVERAGE implementation, and use
the generic EWMA functions instead.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
drivers/net/wireless/rt2x00/Kconfig | 1 +
drivers/net/wireless/rt2x00/rt2x00.h | 16 ++-----
drivers/net/wireless/rt2x00/rt2x00link.c | 70 +++++++++++-------------------
3 files changed, 29 insertions(+), 58 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 68dbbb9..a18b005 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -219,6 +219,7 @@ config RT2X00_LIB_USB
config RT2X00_LIB
tristate
+ select AVERAGE
config RT2X00_LIB_FIRMWARE
boolean
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index fe4c572..30ed92a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -39,6 +39,7 @@
#include <linux/input-polldev.h>
#include <linux/kfifo.h>
#include <linux/hrtimer.h>
+#include <linux/average.h>
#include <net/mac80211.h>
@@ -138,17 +139,6 @@
#define SHORT_EIFS ( SIFS + SHORT_DIFS + \
GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
-/*
- * Structure for average calculation
- * The avg field contains the actual average value,
- * but avg_weight is internally used during calculations
- * to prevent rounding errors.
- */
-struct avg_val {
- int avg;
- int avg_weight;
-};
-
enum rt2x00_chip_intf {
RT2X00_CHIP_INTF_PCI,
RT2X00_CHIP_INTF_PCIE,
@@ -297,7 +287,7 @@ struct link_ant {
* Similar to the avg_rssi in the link_qual structure
* this value is updated by using the walking average.
*/
- struct avg_val rssi_ant;
+ struct ewma rssi_ant;
};
/*
@@ -326,7 +316,7 @@ struct link {
/*
* Currently active average RSSI value
*/
- struct avg_val avg_rssi;
+ struct ewma avg_rssi;
/*
* Work structure for scheduling periodic link tuning.
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 8368aab..a0e3c02 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -35,50 +35,28 @@
*/
#define DEFAULT_RSSI -128
-/*
- * Helper struct and macro to work with moving/walking averages.
- * When adding a value to the average value the following calculation
- * is needed:
- *
- * avg_rssi = ((avg_rssi * 7) + rssi) / 8;
- *
- * The advantage of this approach is that we only need 1 variable
- * to store the average in (No need for a count and a total).
- * But more importantly, normal average values will over time
- * move less and less towards newly added values this results
- * that with link tuning, the device can have a very good RSSI
- * for a few minutes but when the device is moved away from the AP
- * the average will not decrease fast enough to compensate.
- * The walking average compensates this and will move towards
- * the new values correctly allowing a effective link tuning,
- * the speed of the average moving towards other values depends
- * on the value for the number of samples. The higher the number
- * of samples, the slower the average will move.
- * We use two variables to keep track of the average value to
- * compensate for the rounding errors. This can be a significant
- * error (>5dBm) if the factor is too low.
- */
-#define AVG_SAMPLES 8
-#define AVG_FACTOR 1000
-#define MOVING_AVERAGE(__avg, __val) \
-({ \
- struct avg_val __new; \
- __new.avg_weight = \
- (__avg).avg_weight ? \
- ((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \
- ((__val) * (AVG_FACTOR))) / \
- (AVG_SAMPLES)) : \
- ((__val) * (AVG_FACTOR)); \
- __new.avg = __new.avg_weight / (AVG_FACTOR); \
- __new; \
-})
+/* Constants for EWMA calculations. */
+#define RT2X00_EWMA_FACTOR 1024
+#define RT2X00_EWMA_WEIGHT 8
+
+static inline int rt2x00link_get_avg_rssi(struct ewma *ewma)
+{
+ unsigned long avg;
+
+ avg = ewma_read(ewma);
+ if (avg)
+ return -avg;
+
+ return DEFAULT_RSSI;
+}
static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev)
{
struct link_ant *ant = &rt2x00dev->link.ant;
- if (ant->rssi_ant.avg && rt2x00dev->link.qual.rx_success)
- return ant->rssi_ant.avg;
+ if (rt2x00dev->link.qual.rx_success)
+ return rt2x00link_get_avg_rssi(&ant->rssi_ant);
+
return DEFAULT_RSSI;
}
@@ -100,8 +78,8 @@ static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev,
static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev)
{
- rt2x00dev->link.ant.rssi_ant.avg = 0;
- rt2x00dev->link.ant.rssi_ant.avg_weight = 0;
+ ewma_init(&rt2x00dev->link.ant.rssi_ant, RT2X00_EWMA_FACTOR,
+ RT2X00_EWMA_WEIGHT);
}
static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
@@ -249,12 +227,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
/*
* Update global RSSI
*/
- link->avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi);
+ ewma_add(&link->avg_rssi, -rxdesc->rssi);
/*
* Update antenna RSSI
*/
- ant->rssi_ant = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi);
+ ewma_add(&ant->rssi_ant, -rxdesc->rssi);
}
void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
@@ -309,6 +287,8 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
*/
rt2x00dev->link.count = 0;
memset(qual, 0, sizeof(*qual));
+ ewma_init(&rt2x00dev->link.avg_rssi, RT2X00_EWMA_FACTOR,
+ RT2X00_EWMA_WEIGHT);
/*
* Restore the VGC level as stored in the registers,
@@ -363,10 +343,10 @@ static void rt2x00link_tuner(struct work_struct *work)
* collect the RSSI data we could use this. Otherwise we
* must fallback to the default RSSI value.
*/
- if (!link->avg_rssi.avg || !qual->rx_success)
+ if (!qual->rx_success)
qual->rssi = DEFAULT_RSSI;
else
- qual->rssi = link->avg_rssi.avg;
+ qual->rssi = rt2x00link_get_avg_rssi(&link->avg_rssi);
/*
* Check if link tuning is supported by the hardware, some hardware
--
1.7.10
^ permalink raw reply related
* RE: [PATCH] cfg80211: Pass station supported channel and oper class info to kernel
From: Undekari, Sunil Dutt @ 2013-10-09 9:13 UTC (permalink / raw)
To: Johannes Berg; +Cc: j@w1.fi.com, linux-wireless@vger.kernel.org
In-Reply-To: <1381307517.14186.5.camel@jlt4.sipsolutions.net>
PiBJdCdzIGp1c3QgYSBxdWVzdGlvbiBvZiB3aGVyZSB0byBhZGRyZXNzIHRoaXMgLSBpbiB0aGUg
a2VybmVsIG9yIHRoZSBzdXBwbGljYW50LiBJbiBhIHdheSwgSSdkIHJhdGhlciBoYXZlIHRoZSBr
ZXJuZWwgcmVqZWN0IGl0IGFuZCBkbyB0aGUgcG9saWN5IG9mIGlnbm9yaW5nIGludmFsaWQgc3R1
ZmYgaW4gdGhlIHN1cHBsaWNhbnQuDQpUaGUgYWJvdmUgc3RhdGVtZW50IGZyb20geW91IG1hZGUg
bWUgdG8gcmV0aGluayBmb3IgdGhlIGZvbGxvd2luZyBjaGVjayBpbiB0aGUgcGF0Y2ggc2VudC4g
IA0KDQorICAgICAgICAgICAgICAgaWYgKHBhcmFtcy0+c3VwcG9ydGVkX29wZXJfY2xhc3Nlc19s
ZW4gPCAyIHx8DQorICAgICAgICAgICAgICAgICAgIHBhcmFtcy0+c3VwcG9ydGVkX29wZXJfY2xh
c3Nlc19sZW4gPiAyNTMpDQorICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsN
Cg0KQXJlIHlvdSBmaW5lIHRvIHJldHVybiBhIGZhaWx1cmUgZm9yIHRoZSBpbnZhbGlkIGxlbmd0
aCBmb3IgdGhlIHN1cHBvcnRlZF9vcGVyX2NsYXNzZXNfbGVuPyBJZiB5ZXMsIHRoZW4gc2hvdWxk
bid0IHdlIGFsc28gZG8gdGhlIHNpbWlsYXIgY2hlY2sgZm9yIGludmFsaWQgc3VwcG9ydGVkX2No
YW5uZWxzX2xlbiAoIDwgMiApLg0KDQpSZWdhcmRzLA0KU3VuaWwNCg0KLS0tLS1PcmlnaW5hbCBN
ZXNzYWdlLS0tLS0NCkZyb206IEpvaGFubmVzIEJlcmcgW21haWx0bzpqb2hhbm5lc0BzaXBzb2x1
dGlvbnMubmV0XSANClNlbnQ6IFdlZG5lc2RheSwgT2N0b2JlciAwOSwgMjAxMyAyOjAyIFBNDQpU
bzogVW5kZWthcmksIFN1bmlsIER1dHQNCkNjOiBqQHcxLmZpLmNvbTsgbGludXgtd2lyZWxlc3NA
dmdlci5rZXJuZWwub3JnDQpTdWJqZWN0OiBSZTogW1BBVENIXSBjZmc4MDIxMTogUGFzcyBzdGF0
aW9uIHN1cHBvcnRlZCBjaGFubmVsIGFuZCBvcGVyIGNsYXNzIGluZm8gdG8ga2VybmVsDQoNCk9u
IFdlZCwgMjAxMy0xMC0wOSBhdCAwODoxOSArMDAwMCwgVW5kZWthcmksIFN1bmlsIER1dHQgd3Jv
dGU6DQo+IEhpIEpvaGFubmVzLA0KPiANCj4gPkkgZ3Vlc3MgdGhlbiB3cGFfc3VwcGxpY2FudCB3
b3VsZCBoYXZlIHRvIHJlbW92ZSB0aGUgaW5mbyAtIG1heWJlIHRoZSBmYWlsdXJlIGNhc2Ugc2hv
dWxkbid0IGJlIHF1aXRlIGFzIGRyYWNvbmljPyBNYXliZSBtYWtlIGl0IGlnbm9yZSBhbnkgZXh0
cmEgdHJhaWxpbmcgYnl0ZT8NCj4gVGhhbmtzIGZvciB5b3VyIHBvaW50LiANCj4gSSBzdXBwb3Nl
LCByZXR1cm5pbmcgYSBmYWlsdXJlIGZvciB0aGUgbGVuZ3RoIGJlaW5nIGxlc3MgdGhhbiAyIGV2
ZW4gYWZ0ZXIgaWdub3JpbmcgdGhlIHRyYWlsaW5nIGJ5dGUgaXMgbm90IHJlcXVpcmVkIGZvciB0
aGUgcmVhc29uIHRoYXQgdGhlIHN1cHBvcnRlZCBjaGFubmVscyBpcyBub3QgYSBtYW5kYXRvcnkg
ZmllbGQgKGF0IGxlYXN0IHcuci50IFRETFMpLiBJdCBzaG91bGQgYmUgZmluZSB0byBqdXN0IHBh
c3MgdGhlIGxlbmd0aCBhcyAwIHRvIHRoZSBob3N0IGRyaXZlci4gUGxlYXNlIGNvcnJlY3QgbWUu
DQoNCkl0J3MganVzdCBhIHF1ZXN0aW9uIG9mIHdoZXJlIHRvIGFkZHJlc3MgdGhpcyAtIGluIHRo
ZSBrZXJuZWwgb3IgdGhlIHN1cHBsaWNhbnQuIEluIGEgd2F5LCBJJ2QgcmF0aGVyIGhhdmUgdGhl
IGtlcm5lbCByZWplY3QgaXQgYW5kIGRvIHRoZSBwb2xpY3kgb2YgaWdub3JpbmcgaW52YWxpZCBz
dHVmZiBpbiB0aGUgc3VwcGxpY2FudC4NCg0Kam9oYW5uZXMNCg0K
^ permalink raw reply
* Re: [PATCH] cfg80211: Pass station supported channel and oper class info to kernel
From: Johannes Berg @ 2013-10-09 9:17 UTC (permalink / raw)
To: Undekari, Sunil Dutt; +Cc: j@w1.fi.com, linux-wireless@vger.kernel.org
In-Reply-To: <26F3B0343EE4744AA14EEEF9E1E534511F7251E7@aphydexd01a>
On Wed, 2013-10-09 at 09:13 +0000, Undekari, Sunil Dutt wrote:
> > It's just a question of where to address this - in the kernel or the supplicant. In a way, I'd rather have the kernel reject it and do the policy of ignoring invalid stuff in the supplicant.
> The above statement from you made me to rethink for the following check in the patch sent.
>
> + if (params->supported_oper_classes_len < 2 ||
> + params->supported_oper_classes_len > 253)
> + return -EINVAL;
>
> Are you fine to return a failure for the invalid length for the supported_oper_classes_len? If yes, then shouldn't we also do the similar check for invalid supported_channels_len ( < 2 ).
Certainly works for me - but there should also be something like % 2 I
guess
johannes
^ permalink raw reply
* [PATCH] cfg80211: Pass station supported channel and oper class info to kernel
From: Sunil Dutt @ 2013-10-09 11:43 UTC (permalink / raw)
To: johannes; +Cc: j, linux-wireless, c_duttus
The information of the peer's supported channels and supported operating
classes are required for the driver to perform TDLS off channel
operations. This commit enhances the function nl80211_(new)set_station
to pass this information of the peer to the driver.
---
include/net/cfg80211.h | 8 ++++++++
include/uapi/linux/nl80211.h | 9 +++++++++
net/wireless/nl80211.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index cb71091..b1cfc93 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -735,6 +735,10 @@ enum station_parameters_apply_mask {
* @capability: station capability
* @ext_capab: extended capabilities of the station
* @ext_capab_len: number of extended capabilities
+ * @supported_channels: supported channels in IEEE 802.11 format
+ * @supported_channels_len: number of supported channels
+ * @supported_oper_classes: supported oper classes in IEEE 802.11 format
+ * @supported_oper_classes_len: number of supported operating classes
*/
struct station_parameters {
const u8 *supported_rates;
@@ -754,6 +758,10 @@ struct station_parameters {
u16 capability;
const u8 *ext_capab;
u8 ext_capab_len;
+ const u8 *supported_channels;
+ u8 supported_channels_len;
+ const u8 *supported_oper_classes;
+ u8 supported_oper_classes_len;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index fde2c02..aec9a8a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1496,6 +1496,11 @@ enum nl80211_commands {
* @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
* As specified in the &enum nl80211_rxmgmt_flags.
*
+ * @NL80211_ATTR_STA_SUPPORTED_CHANNELS: array of supported channels.
+ *
+ * @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported
+ * supported operating classes.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1806,6 +1811,10 @@ enum nl80211_attrs {
NL80211_ATTR_RXMGMT_FLAGS,
+ NL80211_ATTR_STA_SUPPORTED_CHANNELS,
+
+ NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 626dc3b..c234836 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -354,6 +354,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
+ [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
+ [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
};
/* policy for the key attributes */
@@ -3896,9 +3898,43 @@ static int nl80211_parse_sta_wme(struct genl_info *info,
return 0;
}
+static int nl80211_parse_sta_channel_info(struct genl_info *info,
+ struct station_parameters *params)
+{
+ if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
+ params->supported_channels =
+ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
+ params->supported_channels_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
+ /*
+ * Need to include at least One (first channel, number of
+ * channels) tuple for each subband.Thus, reject any trailing
+ * byte.
+ */
+ if (params->supported_channels_len % 2)
+ params->supported_channels_len -= 1;
+ }
+
+ if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
+ params->supported_oper_classes =
+ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
+ params->supported_oper_classes_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
+ /*
+ * The value of the Length field of the Supported Operating
+ * Classes element is between 2 and 253.
+ */
+ if (params->supported_oper_classes_len < 2 ||
+ params->supported_oper_classes_len > 253)
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int nl80211_set_station_tdls(struct genl_info *info,
struct station_parameters *params)
{
+ int err;
/* Dummy STA entry gets updated once the peer capabilities are known */
if (info->attrs[NL80211_ATTR_PEER_AID])
params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
@@ -3909,6 +3945,10 @@ static int nl80211_set_station_tdls(struct genl_info *info,
params->vht_capa =
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+ err = nl80211_parse_sta_channel_info(info, params);
+ if (err)
+ return err;
+
return nl80211_parse_sta_wme(info, params);
}
@@ -4089,6 +4129,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}
+ err = nl80211_parse_sta_channel_info(info, ¶ms);
+ if (err)
+ return err;
+
err = nl80211_parse_sta_wme(info, ¶ms);
if (err)
return err;
--
1.8.2.1
^ permalink raw reply related
* Re: [PATCH] cfg80211: Pass station supported channel and oper class info to kernel
From: Johannes Berg @ 2013-10-09 11:48 UTC (permalink / raw)
To: Sunil Dutt; +Cc: j, linux-wireless
In-Reply-To: <1381319011-7714-1-git-send-email-c_duttus@qti.qualcomm.com>
> +static int nl80211_parse_sta_channel_info(struct genl_info *info,
> + struct station_parameters *params)
> +{
> + if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
> + params->supported_channels =
> + nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
> + params->supported_channels_len =
> + nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
> + /*
> + * Need to include at least One (first channel, number of
> + * channels) tuple for each subband.Thus, reject any trailing
> + * byte.
> + */
> + if (params->supported_channels_len % 2)
> + params->supported_channels_len -= 1;
> + }
That's not 'reject', that's ignore - and you're also not checking that
it's at least 2 bytes long.
> +
> + if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
> + params->supported_oper_classes =
> + nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
> + params->supported_oper_classes_len =
> + nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
> + /*
> + * The value of the Length field of the Supported Operating
> + * Classes element is between 2 and 253.
> + */
> + if (params->supported_oper_classes_len < 2 ||
> + params->supported_oper_classes_len > 253)
> + return -EINVAL;
And this would be inconsistent, one is rejected and the other ignored?
Also - you missed sign-off.
johannes
^ permalink raw reply
* [PATCH] iwlwifi: don't WARN on bad firmware state
From: Stanislaw Gruszka @ 2013-10-09 13:24 UTC (permalink / raw)
To: ilw; +Cc: linux-wireless
When we restart firmware and it is marked as not alive, we can still get
calls from mac80211. Don't WARN on in this situation as this triggers
automatic bug reports with no valuable information.
This continuation of:
commit 8ca95995e64f5d270889badb3e449dca91106a2b
Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Date: Sun Sep 15 11:37:17 2013 +0300
iwlwifi: don't WARN on host commands sent when firmware is dead
which remove WARN_ONCE from one place, but those warnings are also
triggered from other functions.
Patch also adds unlikely() statement.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/iwlwifi/iwl-trans.h | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 80b4750..c6bac7c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -601,7 +601,7 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
{
int ret;
- if (trans->state != IWL_TRANS_FW_ALIVE) {
+ if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) {
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
return -EIO;
}
@@ -640,8 +640,8 @@ static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_device_cmd *dev_cmd, int queue)
{
- WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
- "%s bad state = %d", __func__, trans->state);
+ if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
+ IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
return trans->ops->tx(trans, skb, dev_cmd, queue);
}
@@ -649,16 +649,16 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
int ssn, struct sk_buff_head *skbs)
{
- WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
- "%s bad state = %d", __func__, trans->state);
+ if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
+ IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
trans->ops->reclaim(trans, queue, ssn, skbs);
}
static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue)
{
- WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
- "%s bad state = %d", __func__, trans->state);
+ if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
+ IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
trans->ops->txq_disable(trans, queue);
}
@@ -669,8 +669,8 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
{
might_sleep();
- WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
- "%s bad state = %d", __func__, trans->state);
+ if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
+ IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
trans->ops->txq_enable(trans, queue, fifo, sta_id, tid,
frame_limit, ssn);
@@ -685,8 +685,8 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
{
- WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
- "%s bad state = %d", __func__, trans->state);
+ if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
+ IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
return trans->ops->wait_tx_queue_empty(trans);
}
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] iwlwifi: don't WARN on bad firmware state
From: Emmanuel Grumbach @ 2013-10-09 13:40 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: ilw@linux.intel.com, linux-wireless
In-Reply-To: <20131009132429.GA1265@redhat.com>
On Wed, Oct 9, 2013 at 4:24 PM, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> When we restart firmware and it is marked as not alive, we can still get
> calls from mac80211. Don't WARN on in this situation as this triggers
> automatic bug reports with no valuable information.
>
> This continuation of:
>
> commit 8ca95995e64f5d270889badb3e449dca91106a2b
> Author: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
> Date: Sun Sep 15 11:37:17 2013 +0300
>
> iwlwifi: don't WARN on host commands sent when firmware is dead
>
> which remove WARN_ONCE from one place, but those warnings are also
> triggered from other functions.
>
> Patch also adds unlikely() statement.
>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
I picked it up. Thanks.
^ permalink raw reply
* Re: [mac80211] connection drop up to 20x/hour at office
From: Oleksij Rempel @ 2013-10-09 13:54 UTC (permalink / raw)
To: ASIC Felix, linux-wireless, ath9k-devel@lists.ath9k.org
In-Reply-To: <CAJqaZwy4priN+Zjnejvj2bbpBm6wN_smSZZi5FBSNrbDaLgiGw@mail.gmail.com>
Am 09.10.2013 06:29, schrieb ASIC Felix:
> I get this connection drop several times an hour, at office up to
> 20x/hour, with current Ubuntu Kernel + Backports wifi even at home,
> before only at the office. Wifi connection recovers eventually, but
> breaks VM and often even VPN connections.
20x per hour? it mean each 3 mints. Hmm... looks like scan interval of
wpa_supplicant.
Is it possible to change time to live setting of access point?
> Does anyone else see this? Further info needed?
>
> Ubuntu: 12-04 LTS
> Kernel: 3.2.0-54-generic #82-Ubuntu SMP x86_64
> Backports: v3.11-rc3-1-0-g4e81a94
> make menuconfig: [ ] enable powersave by default
>
> [ 1955.984833] wlan0: Aggregation is on for 00:24:01:45:51:41 tid 0
> [ 1961.168180] wlan0: tx session timer expired on 00:24:01:45:51:41 tid 0
> [ 1961.168259] wlan0: Tx BA session stop requested for 00:24:01:45:51:41 tid 0
> [ 1968.356133] wlan0: Stopping Tx BA session for 00:24:01:45:51:41 tid 0
> [ 1969.919269] wlan0: Rx BA session stop requested for
> 00:24:01:45:51:41 tid 1 recipient reason: 36
> [ 1969.921269] wlan0: moving STA 00:24:01:45:51:41 to state 3
> [ 1969.921280] wlan0: moving STA 00:24:01:45:51:41 to state 2
> [ 1969.921289] wlan0: moving STA 00:24:01:45:51:41 to state 1
> [ 1969.921294] wlan0: Removed STA 00:24:01:45:51:41
> [ 1969.994841] wlan0: Destroyed STA 00:24:01:45:51:41
> [ 1969.994901] cfg80211: Calling CRDA to update world regulatory domain
> [ 1970.007475] cfg80211: World regulatory domain updated:
> [ 1970.007483] cfg80211: (start_freq - end_freq @ bandwidth),
> (max_antenna_gain, max_eirp)
> [ 1970.007491] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz),
> (300 mBi, 2000 mBm)
> [ 1970.007497] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz),
> (300 mBi, 2000 mBm)
> [ 1970.007503] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz),
> (300 mBi, 2000 mBm)
> [ 1970.007509] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz),
> (300 mBi, 2000 mBm)
> [ 1970.007515] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz),
> (300 mBi, 2000 mBm)
> [ 1973.450965] wlan0: authenticate with 00:24:01:45:51:41
> [ 1973.450986] wlan0: Allocated STA 00:24:01:45:51:41
> [ 1973.463343] wlan0: Inserted STA 00:24:01:45:51:41
> [ 1973.463352] wlan0: send auth to 00:24:01:45:51:41 (try 1/3)
> [ 1973.573146] wlan0: send auth to 00:24:01:45:51:41 (try 2/3)
> [ 1973.753188] wlan0: authentication with 00:24:01:45:51:41 timed out
> [ 1973.757595] wlan0: Removed STA 00:24:01:45:51:41
>
> Driver / Wifi module etc:
>
> Loading modules backported from Linux version v3.11-rc3-0-g5ae90d8
> Backport generated by backports.git v3.11-rc3-1-0-g4e81a94
> cfg80211: Calling CRDA to update world regulatory domain
> cfg80211: World regulatory domain updated:
> cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
> cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
> cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300 mBi, 2000 mBm)
> cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
> ath9k 0000:0d:00.0: PCI INT A -> GSI 18 (level, low) -> IRQ 18
> ath9k 0000:0d:00.0: setting latency timer to 64
> ath: phy0: ASPM enabled: 0x42
> ath: EEPROM regdomain: 0x6a
> ath: EEPROM indicates we should expect a direct regpair map
> ath: Country alpha2 being used: 00
> ath: Regpair used: 0x6a
> ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
> Registered led device: ath9k-phy0
> ieee80211 phy0: Atheros AR9300 Rev:3 mem=0xffffc900118c0000, irq=18
>
>
> Felix
> --
> 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
>
--
Regards,
Oleksij
^ permalink raw reply
* Re: [PATCH] ath10k: fix ath10k_debug_start() locking
From: Kalle Valo @ 2013-10-09 14:15 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless
In-Reply-To: <20131008184525.32604.64051.stgit@localhost6.localdomain6>
Kalle Valo <kvalo@qca.qualcomm.com> writes:
> ath10k_debug_start() was not called with conf_mutex, fix that. Also there was a
> deadlock in ath10k_debug_stop(), rename it to ath10k_debug_destroy() and call
> it only when the device is destroyed.
>
> Reported-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Applied.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH] ath10k: remove unneded semicolon from ath10k_core_fetch_firmware_api_n()
From: Kalle Valo @ 2013-10-09 14:17 UTC (permalink / raw)
To: ath10k; +Cc: Fengguang Wu, linux-wireless
In-Reply-To: <20131008184815.3778.52129.stgit@localhost6.localdomain6>
Kalle Valo <kvalo@qca.qualcomm.com> writes:
> From: Fengguang Wu <fengguang.wu@intel.com>
>
> drivers/net/wireless/ath/ath10k/core.c:507:2-3: Unneeded semicolon
>
> Removes unneeded semicolon.
>
> Generated by: coccinelle/misc/semicolon.cocci
>
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Applied.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH 06/11] bcma: convert bus code to use dev_groups
From: John W. Linville @ 2013-10-09 15:13 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafał Miłecki, linux-wireless
In-Reply-To: <1381128950-28125-7-git-send-email-gregkh@linuxfoundation.org>
On Sun, Oct 06, 2013 at 11:55:45PM -0700, Greg Kroah-Hartman wrote:
> The dev_attrs field of struct bus_type is going away soon, dev_groups
> should be used instead. This converts the bcma bus code to use the
> correct field.
>
> Cc: Rafał Miłecki <zajec5@gmail.com>
> Cc: <linux-wireless@vger.kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>
> Rafał, I can take this through my driver-core tree if you like, just let
> me know what would be the easiest for you.
Makes sense to me...
>
> drivers/bcma/main.c | 23 ++++++++++++++++-------
> 1 file changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index 90ee350..e15430a 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -30,28 +30,37 @@ static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, cha
> struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> return sprintf(buf, "0x%03X\n", core->id.manuf);
> }
> +static DEVICE_ATTR_RO(manuf);
> +
> static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> return sprintf(buf, "0x%03X\n", core->id.id);
> }
> +static DEVICE_ATTR_RO(id);
> +
> static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> return sprintf(buf, "0x%02X\n", core->id.rev);
> }
> +static DEVICE_ATTR_RO(rev);
> +
> static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
> {
> struct bcma_device *core = container_of(dev, struct bcma_device, dev);
> return sprintf(buf, "0x%X\n", core->id.class);
> }
> -static struct device_attribute bcma_device_attrs[] = {
> - __ATTR_RO(manuf),
> - __ATTR_RO(id),
> - __ATTR_RO(rev),
> - __ATTR_RO(class),
> - __ATTR_NULL,
> +static DEVICE_ATTR_RO(class);
> +
> +static struct attribute *bcma_device_attrs[] = {
> + &dev_attr_manuf.attr,
> + &dev_attr_id.attr,
> + &dev_attr_rev.attr,
> + &dev_attr_class.attr,
> + NULL,
> };
> +ATTRIBUTE_GROUPS(bcma_device);
>
> static struct bus_type bcma_bus_type = {
> .name = "bcma",
> @@ -59,7 +68,7 @@ static struct bus_type bcma_bus_type = {
> .probe = bcma_device_probe,
> .remove = bcma_device_remove,
> .uevent = bcma_device_uevent,
> - .dev_attrs = bcma_device_attrs,
> + .dev_groups = bcma_device_groups,
> };
>
> static u16 bcma_cc_core_id(struct bcma_bus *bus)
> --
> 1.8.4.6.g82e253f.dirty
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
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: Pass station supported channel and oper class info to kernel
From: Sunil Dutt @ 2013-10-09 15:15 UTC (permalink / raw)
To: johannes; +Cc: j, linux-wireless, c_duttus
The information of the peer's supported channels and supported operating
classes are required for the driver to perform TDLS off channel
operations. This commit enhances the function nl80211_(new)set_station
to pass this information of the peer to the driver.
Signed-off-by: Sunil Dutt <c_duttus@qti.qualcomm.com>
---
include/net/cfg80211.h | 8 ++++++++
include/uapi/linux/nl80211.h | 9 +++++++++
net/wireless/nl80211.c | 46 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index cb71091..b1cfc93 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -735,6 +735,10 @@ enum station_parameters_apply_mask {
* @capability: station capability
* @ext_capab: extended capabilities of the station
* @ext_capab_len: number of extended capabilities
+ * @supported_channels: supported channels in IEEE 802.11 format
+ * @supported_channels_len: number of supported channels
+ * @supported_oper_classes: supported oper classes in IEEE 802.11 format
+ * @supported_oper_classes_len: number of supported operating classes
*/
struct station_parameters {
const u8 *supported_rates;
@@ -754,6 +758,10 @@ struct station_parameters {
u16 capability;
const u8 *ext_capab;
u8 ext_capab_len;
+ const u8 *supported_channels;
+ u8 supported_channels_len;
+ const u8 *supported_oper_classes;
+ u8 supported_oper_classes_len;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index fde2c02..aec9a8a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1496,6 +1496,11 @@ enum nl80211_commands {
* @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
* As specified in the &enum nl80211_rxmgmt_flags.
*
+ * @NL80211_ATTR_STA_SUPPORTED_CHANNELS: array of supported channels.
+ *
+ * @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported
+ * supported operating classes.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1806,6 +1811,10 @@ enum nl80211_attrs {
NL80211_ATTR_RXMGMT_FLAGS,
+ NL80211_ATTR_STA_SUPPORTED_CHANNELS,
+
+ NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 626dc3b..dca1e8f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -354,6 +354,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
+ [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
+ [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
};
/* policy for the key attributes */
@@ -3896,9 +3898,45 @@ static int nl80211_parse_sta_wme(struct genl_info *info,
return 0;
}
+static int nl80211_parse_sta_channel_info(struct genl_info *info,
+ struct station_parameters *params)
+{
+ if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
+ params->supported_channels =
+ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
+ params->supported_channels_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
+ /*
+ * Need to include at least One (first channel, number of
+ * channels) tuple for each subband.
+ */
+ if (params->supported_channels_len < 2)
+ return -EINVAL;
+ /* Ignore any trailing byte signifying an invalid Tuple.*/
+ if (params->supported_channels_len % 2)
+ params->supported_channels_len -= 1;
+ }
+
+ if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
+ params->supported_oper_classes =
+ nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
+ params->supported_oper_classes_len =
+ nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
+ /*
+ * The value of the Length field of the Supported Operating
+ * Classes element is between 2 and 253.
+ */
+ if (params->supported_oper_classes_len < 2 ||
+ params->supported_oper_classes_len > 253)
+ return -EINVAL;
+ }
+ return 0;
+}
+
static int nl80211_set_station_tdls(struct genl_info *info,
struct station_parameters *params)
{
+ int err;
/* Dummy STA entry gets updated once the peer capabilities are known */
if (info->attrs[NL80211_ATTR_PEER_AID])
params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
@@ -3909,6 +3947,10 @@ static int nl80211_set_station_tdls(struct genl_info *info,
params->vht_capa =
nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
+ err = nl80211_parse_sta_channel_info(info, params);
+ if (err)
+ return err;
+
return nl80211_parse_sta_wme(info, params);
}
@@ -4089,6 +4131,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}
+ err = nl80211_parse_sta_channel_info(info, ¶ms);
+ if (err)
+ return err;
+
err = nl80211_parse_sta_wme(info, ¶ms);
if (err)
return err;
--
1.8.2.1
^ permalink raw reply related
* pull request: wireless 2013-10-09
From: John W. Linville @ 2013-10-09 15:28 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 16475 bytes --]
Dave,
Please pull this batch of fixes intended for 3.12...
Most of the bits are for iwlwifi -- Johannes says:
"I have a fix for WoWLAN/D3, a PCIe device fix, we're removing a
warning, there's a fix for RF-kill while scanning (which goes together
with a mac80211 fix) and last but not least we have many new PCI IDs."
Also for iwlwifi is a patch from Johannes to correct some merge damage
that crept into the tree before the last merge window.
On top of that, Felix Fietkau sends an ath9k patch to avoid a Tx
scheduling hang when changing channels to do a scan.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 9684d7b0dab3cf3a897edd85dca501d413888d56:
Merge branch 'sfc-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc (2013-10-08 21:56:09 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
for you to fetch changes up to b26082b9945a9aca85d51be37824f852617c7129:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-10-09 11:19:05 -0400)
----------------------------------------------------------------
Alexander Bondar (1):
iwlwifi: mvm: Disable uAPSD for D3 image
Emmanuel Grumbach (4):
iwlwifi: pcie: don't reset the TX queue counter
iwlwifi: don't WARN on host commands sent when firmware is dead
iwlwifi: pcie: add SKUs for 6000, 6005 and 6235 series
iwlwifi: mvm: call ieee80211_scan_completed when needed
Felix Fietkau (1):
ath9k: fix tx queue scheduling after channel changes
Johannes Berg (1):
iwlwifi: pcie: fix merge damage
John W. Linville (2):
Merge branch 'for-john' of git://git.kernel.org/.../iwlwifi/iwlwifi-fixes
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Matti Gottlieb (1):
iwlwifi: pcie: add new SKUs for 7000 & 3160 NIC series
drivers/net/wireless/ath/ath9k/main.c | 23 ++++++++---------
drivers/net/wireless/iwlwifi/iwl-6000.c | 6 +++++
drivers/net/wireless/iwlwifi/iwl-config.h | 1 +
drivers/net/wireless/iwlwifi/iwl-trans.h | 6 +++--
drivers/net/wireless/iwlwifi/mvm/power.c | 5 +++-
drivers/net/wireless/iwlwifi/mvm/scan.c | 12 ++++++++-
drivers/net/wireless/iwlwifi/pcie/drv.c | 42 +++++++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/pcie/trans.c | 8 +++---
drivers/net/wireless/iwlwifi/pcie/tx.c | 2 ++
9 files changed, 85 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index e4f6590..709301f 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -208,6 +208,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
unsigned long flags;
+ int i;
if (ath_startrecv(sc) != 0) {
ath_err(common, "Unable to restart recv logic\n");
@@ -235,6 +236,15 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
}
work:
ath_restart_work(sc);
+
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (!ATH_TXQ_SETUP(sc, i))
+ continue;
+
+ spin_lock_bh(&sc->tx.txq[i].axq_lock);
+ ath_txq_schedule(sc, &sc->tx.txq[i]);
+ spin_unlock_bh(&sc->tx.txq[i].axq_lock);
+ }
}
ieee80211_wake_queues(sc->hw);
@@ -539,21 +549,10 @@ chip_reset:
static int ath_reset(struct ath_softc *sc)
{
- int i, r;
+ int r;
ath9k_ps_wakeup(sc);
-
r = ath_reset_internal(sc, NULL);
-
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (!ATH_TXQ_SETUP(sc, i))
- continue;
-
- spin_lock_bh(&sc->tx.txq[i].axq_lock);
- ath_txq_schedule(sc, &sc->tx.txq[i]);
- spin_unlock_bh(&sc->tx.txq[i].axq_lock);
- }
-
ath9k_ps_restore(sc);
return r;
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 30d45e2..8ac305b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -240,6 +240,12 @@ const struct iwl_cfg iwl6035_2agn_cfg = {
.ht_params = &iwl6000_ht_params,
};
+const struct iwl_cfg iwl6035_2agn_sff_cfg = {
+ .name = "Intel(R) Centrino(R) Ultimate-N 6235 AGN",
+ IWL_DEVICE_6035,
+ .ht_params = &iwl6000_ht_params,
+};
+
const struct iwl_cfg iwl1030_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
IWL_DEVICE_6030,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index e4d370b..b03c25e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -280,6 +280,7 @@ extern const struct iwl_cfg iwl2000_2bgn_cfg;
extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
extern const struct iwl_cfg iwl2030_2bgn_cfg;
extern const struct iwl_cfg iwl6035_2agn_cfg;
+extern const struct iwl_cfg iwl6035_2agn_sff_cfg;
extern const struct iwl_cfg iwl105_bgn_cfg;
extern const struct iwl_cfg iwl105_bgn_d_cfg;
extern const struct iwl_cfg iwl135_bgn_cfg;
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index dd57a36..80b4750 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -601,8 +601,10 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
{
int ret;
- WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
- "%s bad state = %d", __func__, trans->state);
+ if (trans->state != IWL_TRANS_FW_ALIVE) {
+ IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
+ return -EIO;
+ }
if (!(cmd->flags & CMD_ASYNC))
lock_map_acquire_read(&trans->sync_cmd_lockdep_map);
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 21407a3..d58e393 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -273,7 +273,10 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
if (!mvmvif->queue_params[ac].uapsd)
continue;
- cmd->flags |= cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
+ if (mvm->cur_ucode != IWL_UCODE_WOWLAN)
+ cmd->flags |=
+ cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
+
cmd->uapsd_ac_flags |= BIT(ac);
/* QNDP TID - the highest TID with no admission control */
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 9a7ab84..621fb71 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -394,6 +394,11 @@ static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
return false;
}
+ /*
+ * If scan cannot be aborted, it means that we had a
+ * SCAN_COMPLETE_NOTIFICATION in the pipe and it called
+ * ieee80211_scan_completed already.
+ */
IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n",
*resp);
return true;
@@ -417,14 +422,19 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
SCAN_COMPLETE_NOTIFICATION };
int ret;
+ if (mvm->scan_status == IWL_MVM_SCAN_NONE)
+ return;
+
iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
scan_abort_notif,
ARRAY_SIZE(scan_abort_notif),
iwl_mvm_scan_abort_notif, NULL);
- ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL);
+ ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD,
+ CMD_SYNC | CMD_SEND_IN_RFKILL, 0, NULL);
if (ret) {
IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
+ /* mac80211's state will be cleaned in the fw_restart flow */
goto out_remove_notif;
}
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index dc02cb9..26108a1 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -139,13 +139,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
/* 6x00 Series */
{IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)},
{IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)},
{IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)},
{IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)},
{IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)},
{IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)},
{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
@@ -153,12 +156,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)},
{IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)},
{IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
{IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)},
{IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */
{IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */
@@ -240,8 +247,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
/* 6x35 Series */
{IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)},
{IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},
{IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)},
@@ -260,54 +270,86 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
#if IS_ENABLED(CONFIG_IWLMVM)
/* 7000 Series */
{IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B2, 0x4272, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B2, 0x426A, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x4472, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x446A, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg_high_temp)},
{IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg_high_temp)},
{IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg_high_temp)},
+ {IWL_PCI_DEVICE(0x08B1, 0x4570, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x4560, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC072, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC06A, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7260_n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC472, iwl7260_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC570, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC560, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B2, 0xC370, iwl7260_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC360, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)},
+ {IWL_PCI_DEVICE(0x08B1, 0xC02A, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)},
{IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)},
/* 3160 Series */
{IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B3, 0x0072, iwl3160_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B3, 0x0172, iwl3160_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)},
{IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B4, 0x0272, iwl3160_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B3, 0x0472, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B4, 0x0370, iwl3160_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B3, 0x8072, iwl3160_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B3, 0x8172, iwl3160_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
{IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
{IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)},
#endif /* CONFIG_IWLMVM */
{0}
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index bad95d2..c3f904d 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1401,6 +1401,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
spin_lock_init(&trans_pcie->reg_lock);
init_waitqueue_head(&trans_pcie->ucode_write_waitq);
+ err = pci_enable_device(pdev);
+ if (err)
+ goto out_no_pci;
+
if (!cfg->base_params->pcie_l1_allowed) {
/*
* W/A - seems to solve weird behavior. We need to remove this
@@ -1412,10 +1416,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
PCIE_LINK_STATE_CLKPM);
}
- err = pci_enable_device(pdev);
- if (err)
- goto out_no_pci;
-
pci_set_master(pdev);
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index f45eb29..1424335 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1102,6 +1102,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
* non-AGG queue.
*/
iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
+
+ ssn = trans_pcie->txq[txq_id].q.read_ptr;
}
/* Place first TFD at index corresponding to start sequence number.
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* Re: [PATCH] wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware
From: Eugene Krasnikov @ 2013-10-09 15:59 UTC (permalink / raw)
To: Joe Perches; +Cc: John Linville, linux-wireless, wcn36xx
In-Reply-To: <1381265688.23020.11.camel@joe-AO722>
Hi Joe,
Thanx for you comments. Would you mind if we fix those trivias after
wcn36xx is merged?
On Tue, Oct 8, 2013 at 9:54 PM, Joe Perches <joe@perches.com> wrote:
> On Tue, 2013-10-08 at 21:25 +0100, Eugene Krasnikov wrote:
>> This is a mac80211 driver for Qualcomm WCN3660/WCN3680 devices. So
>> far WCN3660/WCN3680 is available only on MSM platform.
>
> some trivia:
>
>> diff --git a/drivers/net/wireless/ath/wcn36xx/debug.c b/drivers/net/wireless/ath/wcn36xx/debug.c
> []
>> +static ssize_t read_file_bool_bmps(struct file *file, char __user *user_buf,
>> + size_t count, loff_t *ppos)
>> +{
>> + struct wcn36xx *wcn = file->private_data;
>> + struct wcn36xx_vif *vif_priv = NULL;
>> + struct ieee80211_vif *vif = NULL;
>> + char buf[3];
>> +
>> + list_for_each_entry(vif_priv, &wcn->vif_list, list) {
>> + vif = container_of((void *)vif_priv,
>> + struct ieee80211_vif,
>> + drv_priv);
>> + if (NL80211_IFTYPE_STATION == vif->type) {
>> + if (vif_priv->pw_state == WCN36XX_BMPS)
>> + buf[0] = '1';
>> + else
>> + buf[0] = '0';
>> + break;
>> + }
>
> please indent this properly.
>
> list_for_each...(...) {
> statement...;
> statement...;
> }
>
> []
>
>> +static ssize_t write_file_bool_bmps(struct file *file,
>> + const char __user *user_buf,
>> + size_t count, loff_t *ppos)
>> +{
>> + struct wcn36xx *wcn = file->private_data;
>> + struct wcn36xx_vif *vif_priv = NULL;
>> + struct ieee80211_vif *vif = NULL;
>> +
>> + char buf[32];
>> + int buf_size;
>> +
>> + buf_size = min(count, (sizeof(buf)-1));
>> + if (copy_from_user(buf, user_buf, buf_size))
>> + return -EFAULT;
>> +
>> + switch (buf[0]) {
>> + case 'y':
>> + case 'Y':
>> + case '1':
>> + list_for_each_entry(vif_priv, &wcn->vif_list, list) {
>> + vif = container_of((void *)vif_priv,
>> + struct ieee80211_vif,
>> + drv_priv);
>> + if (NL80211_IFTYPE_STATION == vif->type) {
>
> trivia:
>
> Please use
> if (test == CONSTANT)
>
> Yes, I know the compiler complains if you
> mistakenly leave out one of the = this way.
>
>> +#define ADD_FILE(name, mode, fop, priv_data) \
>> + do { \
>> + struct dentry *d; \
>> + d = debugfs_create_file(__stringify(name), \
>> + mode, dfs->rootdir, \
>> + priv_data, fop); \
>> + dfs->file_##name.dentry = d; \
>> + if (IS_ERR(d)) { \
>> + wcn36xx_warn("Create the debugfs entry failed");\
>
> missing "\n" newline
>
>> + dfs->file_##name.dentry = NULL; \
> []
>
>> diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
> []
>> +static int wcn36xx_dxe_init_descs(struct wcn36xx_dxe_ch *wcn_ch)
>> +{
>> + struct wcn36xx_dxe_desc *cur_dxe = NULL;
>> + struct wcn36xx_dxe_desc *prev_dxe = NULL;
>> + struct wcn36xx_dxe_ctl *cur_ctl = NULL;
>> + size_t size;
>> + int i;
>> +
>> + size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc);
>> + wcn_ch->cpu_addr = dma_alloc_coherent(NULL, size, &wcn_ch->dma_addr,
>> + GFP_KERNEL);
>
> dma_zalloc_coherent
>
> []
>> + memset(wcn_ch->cpu_addr, 0, size);
>
> No longer required.
>
>> + if (0 == i) {
>
> too many styles mixing i == 0 and 0 == i
>
> []
>
>> +int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn)
>> +{
>> + size_t s;
>
> mixing s and size above, please use one style/name.
>
>> + void *cpu_addr;
>> +
>> + /* Allocate BD headers for MGMT frames */
>> +
>> + /* Where this come from ask QC */
>> + wcn->mgmt_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE +
>> + 16 - (WCN36XX_BD_CHUNK_SIZE % 8);
>> +
>> + s = wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H;
>> + cpu_addr = dma_alloc_coherent(NULL, s, &wcn->mgmt_mem_pool.phy_addr,
>> + GFP_KERNEL);
>
> same use of dma_zalloc_coherent(...)
>
>> + if (!cpu_addr)
>> + goto out_err;
>> +
>> + wcn->mgmt_mem_pool.virt_addr = cpu_addr;
>> + memset(cpu_addr, 0, s);
>
> Now unnecessary memset.
>
> too long, stopped reading.
>
>
>
>
--
Best regards,
Eugene
^ permalink raw reply
* Re: [PATCH] wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware
From: Joe Perches @ 2013-10-09 16:03 UTC (permalink / raw)
To: Eugene Krasnikov; +Cc: John Linville, linux-wireless, wcn36xx
In-Reply-To: <CAFSJ42Y_QE9_ep6iArNDkUffmi-kMkU_Y8AeEN8tJXyuAZ1y4Q@mail.gmail.com>
On Wed, 2013-10-09 at 16:59 +0100, Eugene Krasnikov wrote:
> Hi Joe,
Hi Eugene.
> Thanx for you comments. Would you mind if we fix those trivias after
> wcn36xx is merged?
Not at all.
^ permalink raw reply
* [PATCH] wireless: cw1200: acquire hwbus lock around cw1200_irq_handler() call.
From: Solomon Peachy @ 2013-10-09 16:15 UTC (permalink / raw)
To: linux-wireless; +Cc: Solomon Peachy, stable, David Mosberger
This fixes "lost interrupt" problems that occurred on SPI-based systems.
cw1200_irq_handler() expects the hwbus to be locked, but on the
SPI-path, that lock wasn't taken (unlike in the SDIO-path, where the
generic SDIO-code takes care of acquiring the lock).
Cc: stable@vger.kernel.org
Signed-off-by: David Mosberger <davidm@egauge.net>
Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
Please consider this for 3.12-rc if it's not too late!
drivers/net/wireless/cw1200/cw1200_spi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 899cad3..755a0c8 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -237,7 +237,9 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
struct hwbus_priv *self = dev_id;
if (self->core) {
+ cw1200_spi_lock(self);
cw1200_irq_handler(self->core);
+ cw1200_spi_unlock(self);
return IRQ_HANDLED;
} else {
return IRQ_NONE;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware
From: Eugene Krasnikov @ 2013-10-09 16:17 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, wcn36xx, Joe Perches
In-Reply-To: <1381334592.2050.14.camel@joe-AO722>
Hi John,
Please pull wcn36xx and let me know if there are any problems.
On Wed, Oct 9, 2013 at 5:03 PM, Joe Perches <joe@perches.com> wrote:
> On Wed, 2013-10-09 at 16:59 +0100, Eugene Krasnikov wrote:
>> Hi Joe,
>
> Hi Eugene.
>
>> Thanx for you comments. Would you mind if we fix those trivias after
>> wcn36xx is merged?
>
> Not at all.
>
--
Best regards,
Eugene
^ permalink raw reply
* Re: pull request: wireless 2013-10-09
From: David Miller @ 2013-10-09 18:04 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20131009152841.GD14381@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Wed, 9 Oct 2013 11:28:41 -0400
> Please pull this batch of fixes intended for 3.12...
>
> Most of the bits are for iwlwifi -- Johannes says:
>
> "I have a fix for WoWLAN/D3, a PCIe device fix, we're removing a
> warning, there's a fix for RF-kill while scanning (which goes together
> with a mac80211 fix) and last but not least we have many new PCI IDs."
>
> Also for iwlwifi is a patch from Johannes to correct some merge damage
> that crept into the tree before the last merge window.
>
> On top of that, Felix Fietkau sends an ath9k patch to avoid a Tx
> scheduling hang when changing channels to do a scan.
>
> Please let me know if there are problems!
Pulled, thanks a lot John.
^ permalink raw reply
* [PATCH] staging: vt6656: make pControlURB available life time of driver.
From: Malcolm Priestley @ 2013-10-09 19:18 UTC (permalink / raw)
To: gregkh@linuxfoundation.org; +Cc: linux-wireless
There is no need remove and add the control urb in device open/close.
Move to the probe and disconnect. This make the USB control in/out
functions always available to driver.
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
---
drivers/staging/vt6656/main_usb.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index e5add18..0de2156 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -707,6 +707,12 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
INIT_WORK(&pDevice->read_work_item, RXvWorkItem);
INIT_WORK(&pDevice->rx_mng_work_item, RXvMngWorkItem);
+ pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!pDevice->pControlURB) {
+ DBG_PRT(MSG_LEVEL_ERR, KERN_ERR"Failed to alloc control urb\n");
+ goto err_nomem;
+ }
+
pDevice->tx_80211 = device_dma0_tx_80211;
pDevice->vnt_mgmt.pAdapter = (void *) pDevice;
@@ -853,23 +859,15 @@ static bool device_alloc_bufs(struct vnt_private *pDevice)
pRCB++;
}
- pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
- if (pDevice->pControlURB == NULL) {
- DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
- goto free_rx_tx;
- }
-
pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
if (pDevice->pInterruptURB == NULL) {
DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
- usb_free_urb(pDevice->pControlURB);
goto free_rx_tx;
}
pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
if (pDevice->intBuf.pDataBuf == NULL) {
DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
- usb_free_urb(pDevice->pControlURB);
usb_free_urb(pDevice->pInterruptURB);
goto free_rx_tx;
}
@@ -1040,9 +1038,7 @@ free_rx_tx:
device_free_rx_bufs(pDevice);
device_free_tx_bufs(pDevice);
device_free_int_bufs(pDevice);
- usb_kill_urb(pDevice->pControlURB);
usb_kill_urb(pDevice->pInterruptURB);
- usb_free_urb(pDevice->pControlURB);
usb_free_urb(pDevice->pInterruptURB);
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
@@ -1113,9 +1109,7 @@ static int device_close(struct net_device *dev)
device_free_int_bufs(pDevice);
device_free_frag_bufs(pDevice);
- usb_kill_urb(pDevice->pControlURB);
usb_kill_urb(pDevice->pInterruptURB);
- usb_free_urb(pDevice->pControlURB);
usb_free_urb(pDevice->pInterruptURB);
BSSvClearNodeDBTable(pDevice, 0);
@@ -1139,9 +1133,12 @@ static void vt6656_disconnect(struct usb_interface *intf)
if (device->dev) {
unregister_netdev(device->dev);
+
+ usb_kill_urb(device->pControlURB);
+ usb_free_urb(device->pControlURB);
+
free_netdev(device->dev);
}
-
}
static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
--
1.8.3.2
^ permalink raw reply related
* [PATCH v2 tip/core/rcu 10/13] mac80211: Apply rcu_access_pointer() to avoid sparse false positive
From: Paul E. McKenney @ 2013-10-09 21:29 UTC (permalink / raw)
To: linux-kernel
Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, niv, tglx,
peterz, rostedt, dhowells, edumazet, darren, fweisbec, sbw,
Paul E. McKenney, John W. Linville, Johannes Berg,
David S. Miller, linux-wireless, netdev
In-Reply-To: <1381354186-16285-1-git-send-email-paulmck@linux.vnet.ibm.com>
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
The sparse checking for rcu_assign_pointer() was recently upgraded
to reject non-__kernel address spaces. This also rejects __rcu,
which is almost always the right thing to do. However, the uses in
sta_info_hash_del() are legitimate: They are assigning a pointer to an
element from an RCU-protected list, and all elements of this list are
already visible to caller.
This commit therefore silences this false positive by laundering the
pointer using rcu_access_pointer() as suggested by Josh Triplett.
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
---
net/mac80211/sta_info.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index aeb967a0aeed..d18ab89a5725 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -75,7 +75,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
return -ENOENT;
if (s == sta) {
rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)],
- s->hnext);
+ rcu_access_pointer(s->hnext));
return 0;
}
@@ -84,7 +84,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
s = rcu_dereference_protected(s->hnext,
lockdep_is_held(&local->sta_mtx));
if (rcu_access_pointer(s->hnext)) {
- rcu_assign_pointer(s->hnext, sta->hnext);
+ rcu_assign_pointer(s->hnext, rcu_access_pointer(sta->hnext));
return 0;
}
--
1.8.1.5
^ permalink raw reply related
* Re: [mac80211] connection drop up to 20x/hour at office
From: ASIC Felix @ 2013-10-10 2:06 UTC (permalink / raw)
To: Oleksij Rempel; +Cc: linux-wireless, ath9k-devel@lists.ath9k.org
In-Reply-To: <52556024.20302@rempel-privat.de>
On Wed, Oct 9, 2013 at 6:54 AM, Oleksij Rempel <linux@rempel-privat.de> wrote:
> Am 09.10.2013 06:29, schrieb ASIC Felix:
>> I get this connection drop several times an hour, at office up to
>> 20x/hour, with current Ubuntu Kernel + Backports wifi even at home,
>> before only at the office. Wifi connection recovers eventually, but
>> breaks VM and often even VPN connections.
>
> 20x per hour? it mean each 3 mints. Hmm... looks like scan interval of
> wpa_supplicant.
> Is it possible to change time to live setting of access point?
I'm the only one with an issue, everyone else uses windoz with intel
wifi and their connection remains solid.
Felix
^ permalink raw reply
* [PATCH v3] mac80211: port CCMP to cryptoapi's CCM driver
From: Ard Biesheuvel @ 2013-10-10 7:55 UTC (permalink / raw)
To: linux-wireless, netdev; +Cc: patches, johannes, Ard Biesheuvel
Use the generic CCM aead chaining mode driver rather than a local
implementation that sits right on top of the core AES cipher.
This allows the use of accelerated implementations of either
CCM as a whole or the CTR mode which it encapsulates.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
Changes since v2:
- removed the redundant length setting in vector b_0 (and updated the comment
accordingly);
Changes since v1:
- use a better way to allocate the variable size aead_request struct on the
stack;
- pass only a single data pointer argument as we always encrypt/decrypt in
place;
- add a comment about how vector b_0 is generated.
net/mac80211/Kconfig | 1 +
net/mac80211/aes_ccm.c | 169 ++++++++++++++++---------------------------------
net/mac80211/aes_ccm.h | 14 ++--
net/mac80211/key.h | 2 +-
net/mac80211/wpa.c | 44 ++++++-------
5 files changed, 84 insertions(+), 146 deletions(-)
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 62535fe..dc31ec3 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -4,6 +4,7 @@ config MAC80211
select CRYPTO
select CRYPTO_ARC4
select CRYPTO_AES
+ select CRYPTO_CCM
select CRC32
select AVERAGE
---help---
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index be7614b9..7c7df47 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -2,6 +2,8 @@
* Copyright 2003-2004, Instant802 Networks, Inc.
* Copyright 2005-2006, Devicescape Software, Inc.
*
+ * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -17,134 +19,75 @@
#include "key.h"
#include "aes_ccm.h"
-static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
+void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+ u8 *data, size_t data_len, u8 *mic)
{
- int i;
- u8 *b_0, *aad, *b, *s_0;
-
- b_0 = scratch + 3 * AES_BLOCK_SIZE;
- aad = scratch + 4 * AES_BLOCK_SIZE;
- b = scratch;
- s_0 = scratch + AES_BLOCK_SIZE;
-
- crypto_cipher_encrypt_one(tfm, b, b_0);
+ struct scatterlist assoc, pt, ct[2];
+ struct {
+ struct aead_request req;
+ u8 priv[crypto_aead_reqsize(tfm)];
+ } aead_req;
- /* Extra Authenticate-only data (always two AES blocks) */
- for (i = 0; i < AES_BLOCK_SIZE; i++)
- aad[i] ^= b[i];
- crypto_cipher_encrypt_one(tfm, b, aad);
+ memset(&aead_req, 0, sizeof(aead_req));
- aad += AES_BLOCK_SIZE;
+ sg_init_one(&pt, data, data_len);
+ sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
+ sg_init_table(ct, 2);
+ sg_set_buf(&ct[0], data, data_len);
+ sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
- for (i = 0; i < AES_BLOCK_SIZE; i++)
- aad[i] ^= b[i];
- crypto_cipher_encrypt_one(tfm, a, aad);
+ aead_request_set_tfm(&aead_req.req, tfm);
+ aead_request_set_assoc(&aead_req.req, &assoc, assoc.length);
+ aead_request_set_crypt(&aead_req.req, &pt, ct, data_len, b_0);
- /* Mask out bits from auth-only-b_0 */
- b_0[0] &= 0x07;
-
- /* S_0 is used to encrypt T (= MIC) */
- b_0[14] = 0;
- b_0[15] = 0;
- crypto_cipher_encrypt_one(tfm, s_0, b_0);
+ crypto_aead_encrypt(&aead_req.req);
}
-
-void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
- u8 *data, size_t data_len,
- u8 *cdata, u8 *mic)
+int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+ u8 *data, size_t data_len, u8 *mic)
{
- int i, j, last_len, num_blocks;
- u8 *pos, *cpos, *b, *s_0, *e, *b_0;
-
- b = scratch;
- s_0 = scratch + AES_BLOCK_SIZE;
- e = scratch + 2 * AES_BLOCK_SIZE;
- b_0 = scratch + 3 * AES_BLOCK_SIZE;
-
- num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
- last_len = data_len % AES_BLOCK_SIZE;
- aes_ccm_prepare(tfm, scratch, b);
-
- /* Process payload blocks */
- pos = data;
- cpos = cdata;
- for (j = 1; j <= num_blocks; j++) {
- int blen = (j == num_blocks && last_len) ?
- last_len : AES_BLOCK_SIZE;
-
- /* Authentication followed by encryption */
- for (i = 0; i < blen; i++)
- b[i] ^= pos[i];
- crypto_cipher_encrypt_one(tfm, b, b);
-
- b_0[14] = (j >> 8) & 0xff;
- b_0[15] = j & 0xff;
- crypto_cipher_encrypt_one(tfm, e, b_0);
- for (i = 0; i < blen; i++)
- *cpos++ = *pos++ ^ e[i];
- }
-
- for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
- mic[i] = b[i] ^ s_0[i];
+ struct scatterlist assoc, pt, ct[2];
+ struct {
+ struct aead_request req;
+ u8 priv[crypto_aead_reqsize(tfm)];
+ } aead_req;
+
+ memset(&aead_req, 0, sizeof(aead_req));
+
+ sg_init_one(&pt, data, data_len);
+ sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
+ sg_init_table(ct, 2);
+ sg_set_buf(&ct[0], data, data_len);
+ sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
+
+ aead_request_set_tfm(&aead_req.req, tfm);
+ aead_request_set_assoc(&aead_req.req, &assoc, assoc.length);
+ aead_request_set_crypt(&aead_req.req, ct, &pt,
+ data_len + IEEE80211_CCMP_MIC_LEN, b_0);
+
+ return crypto_aead_decrypt(&aead_req.req);
}
-
-int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
- u8 *cdata, size_t data_len, u8 *mic, u8 *data)
+struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[])
{
- int i, j, last_len, num_blocks;
- u8 *pos, *cpos, *b, *s_0, *a, *b_0;
-
- b = scratch;
- s_0 = scratch + AES_BLOCK_SIZE;
- a = scratch + 2 * AES_BLOCK_SIZE;
- b_0 = scratch + 3 * AES_BLOCK_SIZE;
-
- num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
- last_len = data_len % AES_BLOCK_SIZE;
- aes_ccm_prepare(tfm, scratch, a);
-
- /* Process payload blocks */
- cpos = cdata;
- pos = data;
- for (j = 1; j <= num_blocks; j++) {
- int blen = (j == num_blocks && last_len) ?
- last_len : AES_BLOCK_SIZE;
-
- /* Decryption followed by authentication */
- b_0[14] = (j >> 8) & 0xff;
- b_0[15] = j & 0xff;
- crypto_cipher_encrypt_one(tfm, b, b_0);
- for (i = 0; i < blen; i++) {
- *pos = *cpos++ ^ b[i];
- a[i] ^= *pos++;
- }
- crypto_cipher_encrypt_one(tfm, a, a);
- }
-
- for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
- if ((mic[i] ^ s_0[i]) != a[i])
- return -1;
- }
-
- return 0;
-}
+ struct crypto_aead *tfm;
+ int err;
+ tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm))
+ return tfm;
-struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
-{
- struct crypto_cipher *tfm;
+ err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
+ if (!err)
+ err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN);
+ if (!err)
+ return tfm;
- tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- if (!IS_ERR(tfm))
- crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
-
- return tfm;
+ crypto_free_aead(tfm);
+ return ERR_PTR(err);
}
-
-void ieee80211_aes_key_free(struct crypto_cipher *tfm)
+void ieee80211_aes_key_free(struct crypto_aead *tfm)
{
- crypto_free_cipher(tfm);
+ crypto_free_aead(tfm);
}
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h
index 5b7d744..2c7ab19 100644
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
@@ -12,13 +12,11 @@
#include <linux/crypto.h>
-struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
-void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
- u8 *data, size_t data_len,
- u8 *cdata, u8 *mic);
-int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
- u8 *cdata, size_t data_len,
- u8 *mic, u8 *data);
-void ieee80211_aes_key_free(struct crypto_cipher *tfm);
+struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]);
+void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+ u8 *data, size_t data_len, u8 *mic);
+int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+ u8 *data, size_t data_len, u8 *mic);
+void ieee80211_aes_key_free(struct crypto_aead *tfm);
#endif /* AES_CCM_H */
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 036d57e..aaae0ed 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -83,7 +83,7 @@ struct ieee80211_key {
* Management frames.
*/
u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
- struct crypto_cipher *tfm;
+ struct crypto_aead *tfm;
u32 replays; /* dot11RSNAStatsCCMPReplays */
} ccmp;
struct {
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index c9edfcb..d657282 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -301,22 +301,16 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
}
-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
int encrypted)
{
__le16 mask_fc;
int a4_included, mgmt;
u8 qos_tid;
- u8 *b_0, *aad;
- u16 data_len, len_a;
+ u16 len_a;
unsigned int hdrlen;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- memset(scratch, 0, 6 * AES_BLOCK_SIZE);
-
- b_0 = scratch + 3 * AES_BLOCK_SIZE;
- aad = scratch + 4 * AES_BLOCK_SIZE;
-
/*
* Mask FC: zero subtype b4 b5 b6 (if not mgmt)
* Retry, PwrMgt, MoreData; set Protected
@@ -338,20 +332,21 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
else
qos_tid = 0;
- data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
- if (encrypted)
- data_len -= IEEE80211_CCMP_MIC_LEN;
+ /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
+ * mode authentication are not allowed to collide, yet both are derived
+ * from this vector b_0. We only set L := 1 here to indicate that the
+ * data size can be represented in (L+1) bytes. The CCM layer will take
+ * care of storing the data length in the top (L+1) bytes and setting
+ * and clearing the other bits as is required to derive the two IVs.
+ */
+ b_0[0] = 0x1;
- /* First block, b_0 */
- b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
/* Nonce: Nonce Flags | A2 | PN
* Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
*/
b_0[1] = qos_tid | (mgmt << 4);
memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
- /* l(m) */
- put_unaligned_be16(data_len, &b_0[14]);
/* AAD (extra authenticate-only data) / masked 802.11 header
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
@@ -407,7 +402,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
u8 *pos;
u8 pn[6];
u64 pn64;
- u8 scratch[6 * AES_BLOCK_SIZE];
+ u8 aad[2 * AES_BLOCK_SIZE];
+ u8 b_0[AES_BLOCK_SIZE];
if (info->control.hw_key &&
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
@@ -460,9 +456,9 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
return 0;
pos += IEEE80211_CCMP_HDR_LEN;
- ccmp_special_blocks(skb, pn, scratch, 0);
- ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
- pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
+ ccmp_special_blocks(skb, pn, b_0, aad, 0);
+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
+ skb_put(skb, IEEE80211_CCMP_MIC_LEN));
return 0;
}
@@ -525,16 +521,16 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
}
if (!(status->flag & RX_FLAG_DECRYPTED)) {
- u8 scratch[6 * AES_BLOCK_SIZE];
+ u8 aad[2 * AES_BLOCK_SIZE];
+ u8 b_0[AES_BLOCK_SIZE];
/* hardware didn't decrypt/verify MIC */
- ccmp_special_blocks(skb, pn, scratch, 1);
+ ccmp_special_blocks(skb, pn, b_0, aad, 1);
if (ieee80211_aes_ccm_decrypt(
- key->u.ccmp.tfm, scratch,
+ key->u.ccmp.tfm, b_0, aad,
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
data_len,
- skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
- skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
+ skb->data + skb->len - IEEE80211_CCMP_MIC_LEN))
return RX_DROP_UNUSABLE;
}
--
1.8.1.2
^ permalink raw reply related
* Re: [PATCH 06/11] bcma: convert bus code to use dev_groups
From: Rafał Miłecki @ 2013-10-10 8:08 UTC (permalink / raw)
To: John W. Linville
Cc: Greg Kroah-Hartman, Linux Kernel Mailing List,
linux-wireless@vger.kernel.org
In-Reply-To: <20131009151330.GC14381@tuxdriver.com>
2013/10/9 John W. Linville <linville@tuxdriver.com>:
> On Sun, Oct 06, 2013 at 11:55:45PM -0700, Greg Kroah-Hartman wrote:
>> The dev_attrs field of struct bus_type is going away soon, dev_groups
>> should be used instead. This converts the bcma bus code to use the
>> correct field.
>>
>> Cc: Rafał Miłecki <zajec5@gmail.com>
>> Cc: <linux-wireless@vger.kernel.org>
>> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> ---
>>
>> Rafał, I can take this through my driver-core tree if you like, just let
>> me know what would be the easiest for you.
>
> Makes sense to me...
Oops, sorry, missed that. I'll just agree with John :)
^ 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