* Re: [PATCH] ath10k: Remove return statement from a void function
From: Arend Van Spriel @ 2017-02-21 9:44 UTC (permalink / raw)
To: Marcin Rokicki, ath10k; +Cc: linux-wireless
In-Reply-To: <1487667873-3493-1-git-send-email-marcin.rokicki@tieto.com>
On 21-2-2017 10:04, Marcin Rokicki wrote:
> The empty 'return;' statement in a void function should be
> used to return from somewhere else then the end.
>
> Signed-off-by: Marcin Rokicki <marcin.rokicki@tieto.com>
> ---
> drivers/net/wireless/ath/ath10k/core.c | 11 +++++------
> 1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
> index 59729aa..d65850e 100644
> --- a/drivers/net/wireless/ath/ath10k/core.c
> +++ b/drivers/net/wireless/ath/ath10k/core.c
> @@ -2268,7 +2268,7 @@ static void ath10k_core_register_work(struct work_struct *work)
> status = ath10k_core_probe_fw(ar);
> if (status) {
> ath10k_err(ar, "could not probe fw (%d)\n", status);
> - goto err;
> + return;
The subject seems misleading as you add a return here. Also removing the
goto will break the desired behavior as expressed in the TODO below.
> }
>
> status = ath10k_mac_register(ar);
> @@ -2307,11 +2307,10 @@ static void ath10k_core_register_work(struct work_struct *work)
> ath10k_mac_unregister(ar);
> err_release_fw:
> ath10k_core_free_firmware_files(ar);
> -err:
> - /* TODO: It's probably a good idea to release device from the driver
> - * but calling device_release_driver() here will cause a deadlock.
> - */
> - return;
So to me removing this return statement and no more is sufficient for
this patch. Just leave the label and TODO comment in place or fix it
properly by scheduling a "release driver" work here or whatever is
needed to prevent the deadlock.
Regards,
Arend
> +
> +/* TODO: It's probably a good idea to release device from the driver
> + * but calling device_release_driver() here will cause a deadlock.
> + */
> }
>
> int ath10k_core_register(struct ath10k *ar, u32 chip_id)
>
^ permalink raw reply
* [PATCH V3 1/2] firmware: add more flexible request_firmware_async function
From: Rafał Miłecki @ 2017-02-21 9:47 UTC (permalink / raw)
To: Ming Lei, Luis R . Rodriguez, Greg KH, Linux Kernel Mailing List
Cc: Kalle Valo, Arend van Spriel, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
In-Reply-To: <20170216072636.7128-1-zajec5@gmail.com>
From: Rafał Miłecki <rafal@milecki.pl>
So far we got only one function for loading firmware asynchronously:
request_firmware_nowait. It didn't allow much customization of firmware
loading process - there is only one bool uevent argument. Moreover this
bool also controls user helper in an unclear way.
Resolve this problem by adding a one flexible function and making old
request_firmware_nowait a simple inline using new solution. This
implementation:
1) Modifies only single bits on existing code
2) Doesn't require adjusting / rewriting current drivers
3) Adds new function for drivers that need more control over loading a
firmware. Thanks to using flags more features can be added later.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
This patch is based on top of
[PATCH V2 RESEND] firmware: simplify defining and handling FW_OPT_FALLBACK
applied on top of Linux 4.10-rc8.
Ming/Luis/Greg: assuming this gets a positive review, could someone of you pick
this patchset? Second patch modifies brcmfmac, I'll try to get a proper Ack for
that one.
Unless you want this to go through wireless tree, then let me know please.
---
drivers/base/firmware_class.c | 25 ++++++-------------------
include/linux/firmware.h | 34 +++++++++++++++++++++++++++++-----
2 files changed, 35 insertions(+), 24 deletions(-)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index d05be1732c8b..7b3f0a018dc3 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -182,18 +182,6 @@ static int __fw_state_check(struct fw_state *fw_st, enum fw_status status)
#endif /* CONFIG_FW_LOADER_USER_HELPER */
-/* firmware behavior options */
-#define FW_OPT_UEVENT (1U << 0)
-#define FW_OPT_NOWAIT (1U << 1)
-#ifdef CONFIG_FW_LOADER_USER_HELPER
-#define FW_OPT_USERHELPER (1U << 2)
-#else
-#define FW_OPT_USERHELPER 0
-#endif
-#define FW_OPT_NO_WARN (1U << 3)
-#define FW_OPT_NOCACHE (1U << 4)
-#define FW_OPT_FALLBACK (1U << 5)
-
struct firmware_cache {
/* firmware_buf instance will be added into the below list */
spinlock_t lock;
@@ -1356,7 +1344,7 @@ static void request_firmware_work_func(struct work_struct *work)
_request_firmware(&fw, fw_work->name, fw_work->device, NULL, 0,
fw_work->opt_flags);
fw_work->cont(fw, fw_work->context);
- put_device(fw_work->device); /* taken in request_firmware_nowait() */
+ put_device(fw_work->device); /* taken in request_firmware_async() */
module_put(fw_work->module);
kfree_const(fw_work->name);
@@ -1364,7 +1352,7 @@ static void request_firmware_work_func(struct work_struct *work)
}
/**
- * request_firmware_nowait - asynchronous version of request_firmware
+ * request_firmware_async - asynchronous version of request_firmware
* @module: module requesting the firmware
* @uevent: sends uevent to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually.
@@ -1387,8 +1375,8 @@ static void request_firmware_work_func(struct work_struct *work)
* - can't sleep at all if @gfp is GFP_ATOMIC.
**/
int
-request_firmware_nowait(
- struct module *module, bool uevent,
+request_firmware_async(
+ struct module *module, unsigned int opt_flags,
const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
@@ -1407,8 +1395,7 @@ request_firmware_nowait(
fw_work->device = device;
fw_work->context = context;
fw_work->cont = cont;
- fw_work->opt_flags = FW_OPT_NOWAIT | FW_OPT_FALLBACK |
- (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
+ fw_work->opt_flags = FW_OPT_NOWAIT | opt_flags;
if (!try_module_get(module)) {
kfree_const(fw_work->name);
@@ -1421,7 +1408,7 @@ request_firmware_nowait(
schedule_work(&fw_work->work);
return 0;
}
-EXPORT_SYMBOL(request_firmware_nowait);
+EXPORT_SYMBOL(request_firmware_async);
#ifdef CONFIG_PM_SLEEP
static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index b1f9f0ccb8ac..1f2bf14aa441 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -8,6 +8,18 @@
#define FW_ACTION_NOHOTPLUG 0
#define FW_ACTION_HOTPLUG 1
+/* firmware behavior options */
+#define FW_OPT_UEVENT (1U << 0)
+#define FW_OPT_NOWAIT (1U << 1)
+#ifdef CONFIG_FW_LOADER_USER_HELPER
+#define FW_OPT_USERHELPER (1U << 2)
+#else
+#define FW_OPT_USERHELPER 0
+#endif
+#define FW_OPT_NO_WARN (1U << 3)
+#define FW_OPT_NOCACHE (1U << 4)
+#define FW_OPT_FALLBACK (1U << 5)
+
struct firmware {
size_t size;
const u8 *data;
@@ -41,8 +53,8 @@ struct builtin_fw {
#if defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE))
int request_firmware(const struct firmware **fw, const char *name,
struct device *device);
-int request_firmware_nowait(
- struct module *module, bool uevent,
+int request_firmware_async(
+ struct module *module, unsigned int opt_flags,
const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context));
int request_firmware_direct(const struct firmware **fw, const char *name,
@@ -58,8 +70,8 @@ static inline int request_firmware(const struct firmware **fw,
{
return -EINVAL;
}
-static inline int request_firmware_nowait(
- struct module *module, bool uevent,
+static inline int request_firmware_async(
+ struct module *module, unsigned int opt_flags,
const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
@@ -82,6 +94,18 @@ static inline int request_firmware_into_buf(const struct firmware **firmware_p,
{
return -EINVAL;
}
-
#endif
+
+static inline int request_firmware_nowait(
+ struct module *module, bool uevent,
+ const char *name, struct device *device, gfp_t gfp, void *context,
+ void (*cont)(const struct firmware *fw, void *context))
+{
+ unsigned int opt_flags = FW_OPT_FALLBACK |
+ (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
+
+ return request_firmware_async(module, opt_flags, name, device, gfp,
+ context, cont);
+}
+
#endif
--
2.11.0
^ permalink raw reply related
* [PATCH V3 2/2] brcmfmac: don't warn user about NVRAM if fallback to platform one succeeds
From: Rafał Miłecki @ 2017-02-21 9:47 UTC (permalink / raw)
To: Ming Lei, Luis R . Rodriguez, Greg KH, Linux Kernel Mailing List
Cc: Kalle Valo, Arend van Spriel, linux-wireless,
brcm80211-dev-list.pdl, Rafał Miłecki
In-Reply-To: <20170221094754.15406-1-zajec5@gmail.com>
From: Rafał Miłecki <rafal@milecki.pl>
Failing to load NVRAM file isn't critical if we manage to get platform
one in the fallback path. It means warnings like:
[ 10.801506] brcmfmac 0000:01:00.0: Direct firmware load for brcm/brcmfmac43602-pcie.txt failed with error -2
are unnecessary & disturbing for people with platform NVRAM. This is
very common case for Broadcom home routers.
So instead of printing warning immediately with the firmware subsystem
let's first try our fallback code. If that fails as well, then it's a
right moment to print an error.
This should reduce amount of false reports from users seeing this
warning while having wireless working perfectly fine.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
V2: Update commit message as it wasn't clear enough (thanks Andy) & add extra
messages to the firmware.c.
V3: Set FW_OPT_UEVENT to don't change behavior
Kalle, Arend: this patch is strictly related to the bigger 1/2. Could you ack
this change as I expect this patchset to be picked by Ming, Luis or Greg?
---
.../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index c7c1e9906500..6dbcceff2529 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -462,8 +462,14 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
raw_nvram = false;
} else {
data = bcm47xx_nvram_get_contents(&data_len);
- if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
- goto fail;
+ if (!data) {
+ brcmf_dbg(TRACE, "Failed to get platform NVRAM\n");
+ if (!(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) {
+ brcmf_err("Loading NVRAM from %s and using platform one both failed\n",
+ fwctx->nvram_name);
+ goto fail;
+ }
+ }
raw_nvram = true;
}
@@ -504,9 +510,10 @@ static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
return;
}
fwctx->code = fw;
- ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
- fwctx->dev, GFP_KERNEL, fwctx,
- brcmf_fw_request_nvram_done);
+ ret = request_firmware_async(THIS_MODULE,
+ FW_OPT_UEVENT | FW_OPT_NO_WARN,
+ fwctx->nvram_name, fwctx->dev, GFP_KERNEL,
+ fwctx, brcmf_fw_request_nvram_done);
if (!ret)
return;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH V3 2/2] brcmfmac: don't warn user about NVRAM if fallback to platform one succeeds
From: Arend Van Spriel @ 2017-02-21 9:57 UTC (permalink / raw)
To: Rafał Miłecki, Ming Lei, Luis R . Rodriguez, Greg KH,
Linux Kernel Mailing List
Cc: Kalle Valo, linux-wireless, brcm80211-dev-list.pdl,
Rafał Miłecki
In-Reply-To: <20170221094754.15406-2-zajec5@gmail.com>
On 21-2-2017 10:47, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> Failing to load NVRAM file isn't critical if we manage to get platform
> one in the fallback path. It means warnings like:
> [ 10.801506] brcmfmac 0000:01:00.0: Direct firmware load for brcm/brcmfmac43602-pcie.txt failed with error -2
> are unnecessary & disturbing for people with platform NVRAM. This is
> very common case for Broadcom home routers.
>
> So instead of printing warning immediately with the firmware subsystem
> let's first try our fallback code. If that fails as well, then it's a
> right moment to print an error.
>
> This should reduce amount of false reports from users seeing this
> warning while having wireless working perfectly fine.
I think FW_OPT_NO_WARN does not cover all warnings in firmware_class
although I did not check. Anyway...
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
> V2: Update commit message as it wasn't clear enough (thanks Andy) & add extra
> messages to the firmware.c.
> V3: Set FW_OPT_UEVENT to don't change behavior
>
> Kalle, Arend: this patch is strictly related to the bigger 1/2. Could you ack
> this change as I expect this patchset to be picked by Ming, Luis or Greg?
> ---
> .../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 17 ++++++++++++-----
> 1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
> index c7c1e9906500..6dbcceff2529 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
> @@ -462,8 +462,14 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
> raw_nvram = false;
> } else {
> data = bcm47xx_nvram_get_contents(&data_len);
> - if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
> - goto fail;
> + if (!data) {
> + brcmf_dbg(TRACE, "Failed to get platform NVRAM\n");
> + if (!(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) {
> + brcmf_err("Loading NVRAM from %s and using platform one both failed\n",
> + fwctx->nvram_name);
> + goto fail;
> + }
> + }
> raw_nvram = true;
> }
>
> @@ -504,9 +510,10 @@ static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
> return;
> }
> fwctx->code = fw;
> - ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
> - fwctx->dev, GFP_KERNEL, fwctx,
> - brcmf_fw_request_nvram_done);
> + ret = request_firmware_async(THIS_MODULE,
> + FW_OPT_UEVENT | FW_OPT_NO_WARN,
> + fwctx->nvram_name, fwctx->dev, GFP_KERNEL,
> + fwctx, brcmf_fw_request_nvram_done);
^ permalink raw reply
* [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Johannes Berg @ 2017-02-21 10:09 UTC (permalink / raw)
To: linux-wireless; +Cc: Arend Van Spriel, Eliad Peller
From: Eliad Peller <eliad@wizery.com>
Let drivers advertise support for station-mode 4-way handshake
offloading with a new NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA
flag.
Add a new NL80211_ATTR_PMK attribute that might be passed as part
of NL80211_CMD_CONNECT command, and contain the PSK (which is the
PMK, hence the name.)
The driver/device is assumed to handle the 4-way handshake by
itself in this case (including key derivations, etc.), instead
of relying on the supplicant.
This patch is somewhat based on this one (by Vladimir Kondratiev):
https://patchwork.kernel.org/patch/1309561/.
Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/linux/ieee80211.h | 1 +
include/net/cfg80211.h | 2 ++
include/uapi/linux/nl80211.h | 9 +++++++++
net/wireless/nl80211.c | 8 ++++++++
4 files changed, 20 insertions(+)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 6ea381c98aae..2049e983a994 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2357,6 +2357,7 @@ enum ieee80211_sa_query_action {
#define WLAN_MAX_KEY_LEN 32
#define WLAN_PMKID_LEN 16
+#define WLAN_PMK_LEN 32
#define WLAN_OUI_WFA 0x506f9a
#define WLAN_OUI_TYPE_WFA_P2P 9
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 86c12f85fb53..4ca968927d60 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -643,6 +643,7 @@ struct survey_info {
* @wep_keys: static WEP keys, if not NULL points to an array of
* CFG80211_MAX_WEP_KEYS WEP keys
* @wep_tx_key: key index (0..3) of the default TX static WEP key
+ * @psk: PSK (for devices supporting 4-way-handshake offload)
*/
struct cfg80211_crypto_settings {
u32 wpa_versions;
@@ -656,6 +657,7 @@ struct cfg80211_crypto_settings {
bool control_port_no_encrypt;
struct key_params *wep_keys;
int wep_tx_key;
+ const u8 *psk;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9a499b15cfbc..ba102c937750 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2012,6 +2012,9 @@ enum nl80211_commands {
* u32 attribute with an &enum nl80211_timeout_reason value. This is used,
* e.g., with %NL80211_CMD_CONNECT event.
*
+ * @NL80211_ATTR_PMK: PSK for offloaded 4-Way Handshake. Relevant only
+ * with %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks).
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2423,6 +2426,8 @@ enum nl80211_attrs {
NL80211_ATTR_TIMEOUT_REASON,
+ NL80211_ATTR_PMK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -4759,6 +4764,9 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the
* %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more
* RSSI threshold values to monitor rather than exactly one threshold.
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA: Device supports
+ * doing 4-way handshake in station mode (PSK is passed as part
+ * of the connect command).
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4778,6 +4786,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
NL80211_EXT_FEATURE_CQM_RSSI_LIST,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d516527fcb8e..34b551edbc4f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -410,6 +410,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
.len = sizeof(struct nl80211_bss_select_rssi_adjust)
},
[NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
+ [NL80211_ATTR_PMK] = { .len = WLAN_PMK_LEN },
};
/* policy for the key attributes */
@@ -8039,6 +8040,13 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
memcpy(settings->akm_suites, data, len);
}
+ if (info->attrs[NL80211_ATTR_PMK]) {
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA))
+ return -EINVAL;
+ settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
+ }
+
return 0;
}
--
2.9.3
^ permalink raw reply related
* [RFC] nl80211/cfg80211: Add API for setting the PMK to the driver
From: Johannes Berg @ 2017-02-21 10:26 UTC (permalink / raw)
To: linux-wireless; +Cc: Arend Van Spriel, Avraham Stern
From: Avraham Stern <avraham.stern@intel.com>
Add API for setting the PMK to the driver. For FT support, allow
setting also the PMK-R0 Name.
This can be used by drivers that support 4-Way handshake offload
while IEEE802.1X authentication is managed by upper layers.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
We reused the PSK feature bit here since the 4-way-HS is the same,
but perhaps we should split it if some firmware/driver can't or
doesn't want to implement both?
---
include/linux/ieee80211.h | 3 ++
include/net/cfg80211.h | 27 ++++++++++++
include/uapi/linux/nl80211.h | 23 ++++++++--
net/wireless/nl80211.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 25 +++++++++++
net/wireless/trace.h | 60 +++++++++++++++++++++++++++
6 files changed, 234 insertions(+), 3 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 2049e983a994..fb1f533e75b3 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2356,8 +2356,11 @@ enum ieee80211_sa_query_action {
#define WLAN_MAX_KEY_LEN 32
+#define WLAN_PMK_NAME_LEN 16
#define WLAN_PMKID_LEN 16
+#define WLAN_PMK_LEN_EAP_LEAP 16
#define WLAN_PMK_LEN 32
+#define WLAN_PMK_LEN_SUITE_B_192 48
#define WLAN_OUI_WFA 0x506f9a
#define WLAN_OUI_TYPE_WFA_P2P 9
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4ca968927d60..a68c6db6ac55 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2507,6 +2507,23 @@ struct cfg80211_nan_func {
};
/**
+ * struct cfg80211_pmk_conf - PMK configuration
+ *
+ * @aa: authenticator address
+ * @pmk_len: PMK length in bytes.
+ * @pmk: the PMK material
+ * @pmk_r0_name: PMK-R0 Name. NULL if not applicable (i.e., the PMK
+ * is not PMK-R0). When pmk_r0_name is not NULL, the pmk field
+ * holds PMK-R0.
+ */
+struct cfg80211_pmk_conf {
+ const u8 *aa;
+ u8 pmk_len;
+ const u8 *pmk;
+ const u8 *pmk_r0_name;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2823,6 +2840,11 @@ struct cfg80211_nan_func {
* All other parameters must be ignored.
*
* @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
+ *
+ * @set_pmk: configure the PMK to be used for offloaded 4-Way handshake.
+ * (invoked with the wireless_dev mutex held)
+ * @del_pmk: delete the previously configured PMK for the given authenticator.
+ * (invoked with the wireless_dev mutex held)
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3111,6 +3133,11 @@ struct cfg80211_ops {
int (*set_multicast_to_unicast)(struct wiphy *wiphy,
struct net_device *dev,
const bool enabled);
+
+ int (*set_pmk)(struct wiphy *wiphy, struct net_device *dev,
+ const struct cfg80211_pmk_conf *conf);
+ int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *aa);
};
/*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ba102c937750..6ca7fb4a3d71 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -901,6 +901,14 @@
* does not result in a change for the current association. Currently,
* only the %NL80211_ATTR_IE data is used and updated with this command.
*
+ * @NL80211_CMD_SET_PMK: For offloaded 4-Way handshake, set the PMK or PMK-R0
+ * for the given authenticator address (specified with &NL80211_ATTR_MAC).
+ * When &NL80211_ATTR_PMKR0_NAME is set, &NL80211_ATTR_PMK specifies the
+ * PMK-R0, otherwise it specifies the PMK.
+ * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
+ * configured PMK for the authenticator address identified by
+ * &NL80211_ATTR_MAC.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1100,6 +1108,9 @@ enum nl80211_commands {
NL80211_CMD_UPDATE_CONNECT_PARAMS,
+ NL80211_CMD_SET_PMK,
+ NL80211_CMD_DEL_PMK,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -2012,8 +2023,12 @@ enum nl80211_commands {
* u32 attribute with an &enum nl80211_timeout_reason value. This is used,
* e.g., with %NL80211_CMD_CONNECT event.
*
- * @NL80211_ATTR_PMK: PSK for offloaded 4-Way Handshake. Relevant only
- * with %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks).
+ * @NL80211_ATTR_PMK: PMK for offloaded 4-Way Handshake. Relevant with
+ * %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks) when PSK is used, or
+ * with %NL80211_CMD_SET_PMK when 802.1X authentication is used.
+ * When &NL80211_ATTR_PMKR0_NAME is specified, this attribute specifies
+ * the PMK-R0.
+ * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -2427,6 +2442,7 @@ enum nl80211_attrs {
NL80211_ATTR_TIMEOUT_REASON,
NL80211_ATTR_PMK,
+ NL80211_ATTR_PMKR0_NAME,
/* add attributes here, update the policy in nl80211.c */
@@ -4766,7 +4782,8 @@ enum nl80211_feature_flags {
* RSSI threshold values to monitor rather than exactly one threshold.
* @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA: Device supports
* doing 4-way handshake in station mode (PSK is passed as part
- * of the connect command).
+ * of the connect command and the PMK for 802.1X is set with the
+ * %NL80211_CMD_SET_PMK command.)
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 34b551edbc4f..a78bc4c27ed0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12075,6 +12075,90 @@ static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
return rdev_set_multicast_to_unicast(rdev, dev, enabled);
}
+static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_pmk_conf pmk_conf = {};
+ int ret;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
+
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA))
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
+ return -EINVAL;
+
+ wdev_lock(wdev);
+ if (!wdev->current_bss) {
+ ret = -ENOTCONN;
+ goto out;
+ }
+
+ pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
+ pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
+ if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
+ pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
+ int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
+
+ if (r0_name_len != WLAN_PMK_NAME_LEN) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pmk_conf.pmk_r0_name =
+ nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
+ }
+
+ ret = rdev_set_pmk(rdev, dev, &pmk_conf);
+out:
+ wdev_unlock(wdev);
+ return ret;
+}
+
+static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ const u8 *aa;
+ int ret;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
+
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA))
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ wdev_lock(wdev);
+ aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ ret = rdev_del_pmk(rdev, dev, aa);
+ wdev_unlock(wdev);
+
+ return ret;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -12950,6 +13034,21 @@ static const struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_SET_PMK,
+ .doit = nl80211_set_pmk,
+ .policy = nl80211_policy,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_DEL_PMK,
+ .doit = nl80211_del_pmk,
+ .policy = nl80211_policy,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+
};
static struct genl_family nl80211_fam __ro_after_init = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index f2baf5921091..06698552f1f2 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1165,4 +1165,29 @@ rdev_set_coalesce(struct cfg80211_registered_device *rdev,
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
+
+static inline int rdev_set_pmk(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_pmk_conf *pmk_conf)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_set_pmk(&rdev->wiphy, dev, pmk_conf);
+ if (rdev->ops->set_pmk)
+ ret = rdev->ops->set_pmk(&rdev->wiphy, dev, pmk_conf);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
+static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *aa)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_del_pmk(&rdev->wiphy, dev, aa);
+ if (rdev->ops->del_pmk)
+ ret = rdev->ops->del_pmk(&rdev->wiphy, dev, aa);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index fd55786f0462..47a5e8d4b113 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2252,6 +2252,66 @@ TRACE_EVENT(rdev_tdls_cancel_channel_switch,
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr))
);
+TRACE_EVENT(rdev_set_pmk,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_pmk_conf *pmk_conf),
+
+ TP_ARGS(wiphy, netdev, pmk_conf),
+
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(aa)
+ __field(u8, pmk_len)
+ __field(u8, pmk_r0_name_len)
+ __dynamic_array(u8, pmk, pmk_conf->pmk_len)
+ __dynamic_array(u8, pmk_r0_name, WLAN_PMK_NAME_LEN)
+ ),
+
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(aa, pmk_conf->aa);
+ __entry->pmk_len = pmk_conf->pmk_len;
+ __entry->pmk_r0_name_len =
+ pmk_conf->pmk_r0_name ? WLAN_PMK_NAME_LEN : 0;
+ memcpy(__get_dynamic_array(pmk), pmk_conf->pmk,
+ pmk_conf->pmk_len);
+ memcpy(__get_dynamic_array(pmk_r0_name), pmk_conf->pmk_r0_name,
+ pmk_conf->pmk_r0_name ? WLAN_PMK_NAME_LEN : 0);
+ ),
+
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT
+ "pmk_len=%u, pmk: %s pmk_r0_name: %s", WIPHY_PR_ARG,
+ NETDEV_PR_ARG, MAC_PR_ARG(aa), __entry->pmk_len,
+ __print_array(__get_dynamic_array(pmk),
+ __get_dynamic_array_len(pmk), 1),
+ __entry->pmk_r0_name_len ?
+ __print_array(__get_dynamic_array(pmk_r0_name),
+ __get_dynamic_array_len(pmk_r0_name), 1) : "")
+);
+
+TRACE_EVENT(rdev_del_pmk,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *aa),
+
+ TP_ARGS(wiphy, netdev, aa),
+
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(aa)
+ ),
+
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(aa, aa);
+ ),
+
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT,
+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
+);
+
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
--
2.9.3
^ permalink raw reply related
* [PATCH v2] ath10k: Remove return statement from a void function
From: Marcin Rokicki @ 2017-02-21 10:28 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, arend.vanspriel
The empty 'return;' statement in a void function should be
used to return from somewhere else than the end.
Signed-off-by: Marcin Rokicki <marcin.rokicki@tieto.com>
---
Changes for v2
-remove only return statement instead of empty err label
which can be used in the future
---
drivers/net/wireless/ath/ath10k/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 59729aa..a22d3c9 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2311,7 +2311,7 @@ static void ath10k_core_register_work(struct work_struct *work)
/* TODO: It's probably a good idea to release device from the driver
* but calling device_release_driver() here will cause a deadlock.
*/
- return;
+ ;
}
int ath10k_core_register(struct ath10k *ar, u32 chip_id)
--
2.7.4
^ permalink raw reply related
* [RFC] mac80211_hwsim: report survey data for scanned channels
From: Johannes Berg @ 2017-02-21 10:31 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Currently, hwsim is reporting survey data (only a fake noise floor)
for the current channel. This breaks when the multi-channel support
is enabled since then there's no current channel.
Make the dummy implementation closer to a real one and only report
data while scanning, for all the scanned channels. At other times,
no survey data might be available (in real hardware) due to power-
save for example.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
Had this lying around - is it useful for anyone?
---
drivers/net/wireless/mac80211_hwsim.c | 73 ++++++++++++++++++++++++++++-------
1 file changed, 60 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 0150747c79ac..5a636b09320b 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -525,6 +525,11 @@ struct mac80211_hwsim_data {
struct ieee80211_vif *hw_scan_vif;
int scan_chan_idx;
u8 scan_addr[ETH_ALEN];
+ struct {
+ struct ieee80211_channel *channel;
+ unsigned long next_start, start, end;
+ } survey_data[ARRAY_SIZE(hwsim_channels_2ghz) +
+ ARRAY_SIZE(hwsim_channels_5ghz)];
struct ieee80211_channel *channel;
u64 beacon_int /* beacon interval in us */;
@@ -1576,6 +1581,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
[IEEE80211_SMPS_STATIC] = "static",
[IEEE80211_SMPS_DYNAMIC] = "dynamic",
};
+ int idx;
if (conf->chandef.chan)
wiphy_debug(hw->wiphy,
@@ -1598,9 +1604,33 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
- data->channel = conf->chandef.chan;
+ WARN_ON(conf->chandef.chan && data->use_chanctx);
+
+ mutex_lock(&data->mutex);
+ if (data->scanning && conf->chandef.chan) {
+ for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
+ if (data->survey_data[idx].channel == data->channel) {
+ data->survey_data[idx].start =
+ data->survey_data[idx].next_start;
+ data->survey_data[idx].end = jiffies;
+ break;
+ }
+ }
- WARN_ON(data->channel && data->use_chanctx);
+ data->channel = conf->chandef.chan;
+
+ for (idx = 0; idx < ARRAY_SIZE(data->survey_data); idx++) {
+ if (data->survey_data[idx].channel &&
+ data->survey_data[idx].channel != data->channel)
+ continue;
+ data->survey_data[idx].channel = data->channel;
+ data->survey_data[idx].next_start = jiffies;
+ break;
+ }
+ } else {
+ data->channel = conf->chandef.chan;
+ }
+ mutex_unlock(&data->mutex);
data->power_level = conf->power_level;
if (!data->started || !data->beacon_int)
@@ -1787,28 +1817,39 @@ static int mac80211_hwsim_conf_tx(
return 0;
}
-static int mac80211_hwsim_get_survey(
- struct ieee80211_hw *hw, int idx,
- struct survey_info *survey)
+static int mac80211_hwsim_get_survey(struct ieee80211_hw *hw, int idx,
+ struct survey_info *survey)
{
- struct ieee80211_conf *conf = &hw->conf;
+ struct mac80211_hwsim_data *hwsim = hw->priv;
wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx);
- if (idx != 0)
+ if (idx < 0 || idx >= ARRAY_SIZE(hwsim->survey_data))
return -ENOENT;
- /* Current channel */
- survey->channel = conf->chandef.chan;
+ mutex_lock(&hwsim->mutex);
+ survey->channel = hwsim->survey_data[idx].channel;
+ if (!survey->channel) {
+ mutex_unlock(&hwsim->mutex);
+ return -ENOENT;
+ }
/*
- * Magically conjured noise level --- this is only ok for simulated hardware.
+ * Magically conjured dummy values --- this is only ok for simulated hardware.
*
- * A real driver which cannot determine the real channel noise MUST NOT
- * report any noise, especially not a magically conjured one :-)
+ * A real driver which cannot determine real values noise MUST NOT
+ * report any, especially not a magically conjured ones :-)
*/
- survey->filled = SURVEY_INFO_NOISE_DBM;
+ survey->filled = SURVEY_INFO_NOISE_DBM |
+ SURVEY_INFO_CHANNEL_TIME |
+ SURVEY_INFO_CHANNEL_TIME_BUSY;
survey->noise = -92;
+ survey->channel_time =
+ jiffies_to_msecs(hwsim->survey_data[idx].end -
+ hwsim->survey_data[idx].start);
+ /* report 12.5% of channel time is used */
+ survey->channel_time_busy = survey->channel_time/8;
+ mutex_unlock(&hwsim->mutex);
return 0;
}
@@ -1986,6 +2027,10 @@ static void hw_scan_work(struct work_struct *work)
}
ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan,
msecs_to_jiffies(dwell));
+ hwsim->survey_data[hwsim->scan_chan_idx].channel = hwsim->tmp_chan;
+ hwsim->survey_data[hwsim->scan_chan_idx].start = jiffies;
+ hwsim->survey_data[hwsim->scan_chan_idx].end =
+ jiffies + msecs_to_jiffies(dwell);
hwsim->scan_chan_idx++;
mutex_unlock(&hwsim->mutex);
}
@@ -2011,6 +2056,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
hw_req->req.mac_addr_mask);
else
memcpy(hwsim->scan_addr, vif->addr, ETH_ALEN);
+ memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
mutex_unlock(&hwsim->mutex);
wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
@@ -2057,6 +2103,7 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw,
memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
hwsim->scanning = true;
+ memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
out:
mutex_unlock(&hwsim->mutex);
--
2.9.3
^ permalink raw reply related
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Arend Van Spriel @ 2017-02-21 10:32 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: Eliad Peller
In-Reply-To: <20170221100957.30965-1-johannes@sipsolutions.net>
On 21-2-2017 11:09, Johannes Berg wrote:
> From: Eliad Peller <eliad@wizery.com>
>
> Let drivers advertise support for station-mode 4-way handshake
> offloading with a new NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA
> flag.
I find use of the term OFFLOAD a bit redundant as it is implied by its
presence anyway.
> Add a new NL80211_ATTR_PMK attribute that might be passed as part
> of NL80211_CMD_CONNECT command, and contain the PSK (which is the
> PMK, hence the name.)
>
> The driver/device is assumed to handle the 4-way handshake by
> itself in this case (including key derivations, etc.), instead
> of relying on the supplicant.
>
> This patch is somewhat based on this one (by Vladimir Kondratiev):
> https://patchwork.kernel.org/patch/1309561/.
It also looks quite like this one we posted a while ago [1]. Our bad
that we did not follow-up :-p
Thanks,
Arend
[1] https://www.spinics.net/lists/linux-wireless/msg129387.html
> Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
> Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
> include/linux/ieee80211.h | 1 +
> include/net/cfg80211.h | 2 ++
> include/uapi/linux/nl80211.h | 9 +++++++++
> net/wireless/nl80211.c | 8 ++++++++
> 4 files changed, 20 insertions(+)
>
> diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
> index 6ea381c98aae..2049e983a994 100644
> --- a/include/linux/ieee80211.h
> +++ b/include/linux/ieee80211.h
> @@ -2357,6 +2357,7 @@ enum ieee80211_sa_query_action {
> #define WLAN_MAX_KEY_LEN 32
>
> #define WLAN_PMKID_LEN 16
> +#define WLAN_PMK_LEN 32
>
> #define WLAN_OUI_WFA 0x506f9a
> #define WLAN_OUI_TYPE_WFA_P2P 9
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 86c12f85fb53..4ca968927d60 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -643,6 +643,7 @@ struct survey_info {
> * @wep_keys: static WEP keys, if not NULL points to an array of
> * CFG80211_MAX_WEP_KEYS WEP keys
> * @wep_tx_key: key index (0..3) of the default TX static WEP key
> + * @psk: PSK (for devices supporting 4-way-handshake offload)
> */
> struct cfg80211_crypto_settings {
> u32 wpa_versions;
> @@ -656,6 +657,7 @@ struct cfg80211_crypto_settings {
> bool control_port_no_encrypt;
> struct key_params *wep_keys;
> int wep_tx_key;
> + const u8 *psk;
> };
>
> /**
> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index 9a499b15cfbc..ba102c937750 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -2012,6 +2012,9 @@ enum nl80211_commands {
> * u32 attribute with an &enum nl80211_timeout_reason value. This is used,
> * e.g., with %NL80211_CMD_CONNECT event.
> *
> + * @NL80211_ATTR_PMK: PSK for offloaded 4-Way Handshake. Relevant only
> + * with %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks).
> + *
> * @NUM_NL80211_ATTR: total number of nl80211_attrs available
> * @NL80211_ATTR_MAX: highest attribute number currently defined
> * @__NL80211_ATTR_AFTER_LAST: internal use
> @@ -2423,6 +2426,8 @@ enum nl80211_attrs {
>
> NL80211_ATTR_TIMEOUT_REASON,
>
> + NL80211_ATTR_PMK,
> +
> /* add attributes here, update the policy in nl80211.c */
>
> __NL80211_ATTR_AFTER_LAST,
> @@ -4759,6 +4764,9 @@ enum nl80211_feature_flags {
> * @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the
> * %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more
> * RSSI threshold values to monitor rather than exactly one threshold.
> + * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA: Device supports
> + * doing 4-way handshake in station mode (PSK is passed as part
> + * of the connect command).
> *
> * @NUM_NL80211_EXT_FEATURES: number of extended features.
> * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
> @@ -4778,6 +4786,7 @@ enum nl80211_ext_feature_index {
> NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
> NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
> NL80211_EXT_FEATURE_CQM_RSSI_LIST,
> + NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA,
>
> /* add new features before the definition below */
> NUM_NL80211_EXT_FEATURES,
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index d516527fcb8e..34b551edbc4f 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -410,6 +410,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
> .len = sizeof(struct nl80211_bss_select_rssi_adjust)
> },
> [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
> + [NL80211_ATTR_PMK] = { .len = WLAN_PMK_LEN },
> };
>
> /* policy for the key attributes */
> @@ -8039,6 +8040,13 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
> memcpy(settings->akm_suites, data, len);
> }
>
> + if (info->attrs[NL80211_ATTR_PMK]) {
> + if (!wiphy_ext_feature_isset(&rdev->wiphy,
> + NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA))
> + return -EINVAL;
> + settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
> + }
> +
> return 0;
> }
>
>
^ permalink raw reply
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Johannes Berg @ 2017-02-21 10:40 UTC (permalink / raw)
To: Arend Van Spriel, linux-wireless; +Cc: Eliad Peller
In-Reply-To: <231f969e-eac1-3196-07c2-80e37e6dda55@broadcom.com>
On Tue, 2017-02-21 at 11:32 +0100, Arend Van Spriel wrote:
> On 21-2-2017 11:09, Johannes Berg wrote:
> > From: Eliad Peller <eliad@wizery.com>
> >
> > Let drivers advertise support for station-mode 4-way handshake
> > offloading with a new
> > NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA
> > flag.
>
> I find use of the term OFFLOAD a bit redundant as it is implied by
> its presence anyway.
Fair enough, we can remove that.
> > Add a new NL80211_ATTR_PMK attribute that might be passed as part
> > of NL80211_CMD_CONNECT command, and contain the PSK (which is the
> > PMK, hence the name.)
> >
> > The driver/device is assumed to handle the 4-way handshake by
> > itself in this case (including key derivations, etc.), instead
> > of relying on the supplicant.
> >
> > This patch is somewhat based on this one (by Vladimir Kondratiev):
> > https://patchwork.kernel.org/patch/1309561/.
>
> It also looks quite like this one we posted a while ago [1]. Our bad
> that we did not follow-up :-p
Indeed, I was looking for the better link (had gmane recorded in the
internal commit log) and found a few that all looked the same ... :)
Would this work for you? We should have wpa_supplicant support too, but
need to ask Andrei to look at that.
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Arend Van Spriel @ 2017-02-21 11:34 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: Eliad Peller
In-Reply-To: <1487673603.2215.3.camel@sipsolutions.net>
On 21-2-2017 11:40, Johannes Berg wrote:
> On Tue, 2017-02-21 at 11:32 +0100, Arend Van Spriel wrote:
>> On 21-2-2017 11:09, Johannes Berg wrote:
>>> From: Eliad Peller <eliad@wizery.com>
>>>
>>> Let drivers advertise support for station-mode 4-way handshake
>>> offloading with a new
>>> NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA
>>> flag.
>>
>> I find use of the term OFFLOAD a bit redundant as it is implied by
>> its presence anyway.
>
> Fair enough, we can remove that.
>
>>> Add a new NL80211_ATTR_PMK attribute that might be passed as part
>>> of NL80211_CMD_CONNECT command, and contain the PSK (which is the
>>> PMK, hence the name.)
It is also added to NL80211_CMD_ASSOCIATE. Maybe worth mentioning.
>>> The driver/device is assumed to handle the 4-way handshake by
>>> itself in this case (including key derivations, etc.), instead
>>> of relying on the supplicant.
What I am also missing is how to deal with NL80211_CMD_CONNECTED event
signalling. Should that be given after (un)successful completion of the
4-way handshake or should we have a separate event for that?
Regards,
Arend
>>> This patch is somewhat based on this one (by Vladimir Kondratiev):
>>> https://patchwork.kernel.org/patch/1309561/.
>>
>> It also looks quite like this one we posted a while ago [1]. Our bad
>> that we did not follow-up :-p
>
> Indeed, I was looking for the better link (had gmane recorded in the
> internal commit log) and found a few that all looked the same ... :)
>
> Would this work for you? We should have wpa_supplicant support too, but
> need to ask Andrei to look at that.
>
> johannes
>
^ permalink raw reply
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Arend Van Spriel @ 2017-02-21 11:45 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: Eliad Peller
In-Reply-To: <c38019e8-32b5-5fa2-1da7-8022cbb62b13@broadcom.com>
On 21-2-2017 12:34, Arend Van Spriel wrote:
> On 21-2-2017 11:40, Johannes Berg wrote:
>> On Tue, 2017-02-21 at 11:32 +0100, Arend Van Spriel wrote:
>>> On 21-2-2017 11:09, Johannes Berg wrote:
>>>> From: Eliad Peller <eliad@wizery.com>
>>>>
>>>> Let drivers advertise support for station-mode 4-way handshake
>>>> offloading with a new
>>>> NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA
>>>> flag.
>>>
>>> I find use of the term OFFLOAD a bit redundant as it is implied by
>>> its presence anyway.
>>
>> Fair enough, we can remove that.
>>
>>>> Add a new NL80211_ATTR_PMK attribute that might be passed as part
>>>> of NL80211_CMD_CONNECT command, and contain the PSK (which is the
>>>> PMK, hence the name.)
>
> It is also added to NL80211_CMD_ASSOCIATE. Maybe worth mentioning.
>
>>>> The driver/device is assumed to handle the 4-way handshake by
>>>> itself in this case (including key derivations, etc.), instead
>>>> of relying on the supplicant.
>
> What I am also missing is how to deal with NL80211_CMD_CONNECTED event
> signalling. Should that be given after (un)successful completion of the
> 4-way handshake or should we have a separate event for that?
>
> Regards,
> Arend
>
>>>> This patch is somewhat based on this one (by Vladimir Kondratiev):
>>>> https://patchwork.kernel.org/patch/1309561/.
>>>
>>> It also looks quite like this one we posted a while ago [1]. Our bad
>>> that we did not follow-up :-p
>>
>> Indeed, I was looking for the better link (had gmane recorded in the
>> internal commit log) and found a few that all looked the same ... :)
>>
>> Would this work for you? We should have wpa_supplicant support too, but
>> need to ask Andrei to look at that.
Forgot to reply to this. Yes, this will work. Can come up with wpa_supp
changes.
Regards,
Arend
^ permalink raw reply
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Johannes Berg @ 2017-02-21 11:46 UTC (permalink / raw)
To: Arend Van Spriel, linux-wireless; +Cc: Eliad Peller
In-Reply-To: <a021dbf9-854d-0339-b87d-b27b746ccd1b@broadcom.com>
> > > Would this work for you? We should have wpa_supplicant support
> > > too, but need to ask Andrei to look at that.
>
> Forgot to reply to this. Yes, this will work. Can come up with
> wpa_supp changes.
No, we have them. Just need to see where they are :)
johannes
^ permalink raw reply
* Re: [PATCH V3 2/2] brcmfmac: don't warn user about NVRAM if fallback to platform one succeeds
From: Kalle Valo @ 2017-02-21 11:46 UTC (permalink / raw)
To: Arend Van Spriel
Cc: Rafał Miłecki, Ming Lei, Luis R . Rodriguez, Greg KH,
Linux Kernel Mailing List, linux-wireless, brcm80211-dev-list.pdl,
Rafał Miłecki
In-Reply-To: <9ac0557a-2746-bc61-7397-a7fa58a02787@broadcom.com>
Arend Van Spriel <arend.vanspriel@broadcom.com> writes:
> On 21-2-2017 10:47, Rafa=C5=82 Mi=C5=82ecki wrote:
>> From: Rafa=C5=82 Mi=C5=82ecki <rafal@milecki.pl>
>>=20
>> Failing to load NVRAM file isn't critical if we manage to get platform
>> one in the fallback path. It means warnings like:
>> [ 10.801506] brcmfmac 0000:01:00.0: Direct firmware load for
>> brcm/brcmfmac43602-pcie.txt failed with error -2
>> are unnecessary & disturbing for people with platform NVRAM. This is
>> very common case for Broadcom home routers.
>>=20
>> So instead of printing warning immediately with the firmware subsystem
>> let's first try our fallback code. If that fails as well, then it's a
>> right moment to print an error.
>>=20
>> This should reduce amount of false reports from users seeing this
>> warning while having wireless working perfectly fine.
>
> I think FW_OPT_NO_WARN does not cover all warnings in firmware_class
> although I did not check. Anyway...
>
> Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Acked-by: Kalle Valo <kvalo@codeaurora.org>
Feel free to this via some another tree.
--=20
Kalle Valo
^ permalink raw reply
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Arend Van Spriel @ 2017-02-21 11:54 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: Eliad Peller
In-Reply-To: <1487677574.2215.4.camel@sipsolutions.net>
On 21-2-2017 12:46, Johannes Berg wrote:
>
>>>> Would this work for you? We should have wpa_supplicant support
>>>> too, but need to ask Andrei to look at that.
>>
>> Forgot to reply to this. Yes, this will work. Can come up with
>> wpa_supp changes.
>
> No, we have them. Just need to see where they are :)
I see. Will keep an eye on hostapd list ;-)
Gr. AvS
^ permalink raw reply
* Re: [PATCH] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Johannes Berg @ 2017-02-21 12:37 UTC (permalink / raw)
To: Arend Van Spriel, linux-wireless; +Cc: Eliad Peller, Jouni Malinen
In-Reply-To: <c38019e8-32b5-5fa2-1da7-8022cbb62b13@broadcom.com>
> What I am also missing is how to deal with NL80211_CMD_CONNECTED
> event signalling. Should that be given after (un)successful
> completion of the 4-way handshake or should we have a separate event
> for that?
That's a good point. I don't think a new event really works well, but
perhaps we should extend the NL80211_TIMEOUT_* values with this? It's
not strictly a timeout, I guess, but it's not a direct rejection of the
association either.
Any thoughts?
johannes
^ permalink raw reply
* [RFC v2 2/2] cfg80211: support 4-way handshake offloading for 802.1X
From: Johannes Berg @ 2017-02-21 12:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Avraham Stern
In-Reply-To: <20170221123758.5339-1-johannes@sipsolutions.net>
From: Avraham Stern <avraham.stern@intel.com>
Add API for setting the PMK to the driver. For FT support, allow
setting also the PMK-R0 Name.
This can be used by drivers that support 4-Way handshake offload
while IEEE802.1X authentication is managed by upper layers.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/linux/ieee80211.h | 3 ++
include/net/cfg80211.h | 27 ++++++++++++
include/uapi/linux/nl80211.h | 24 ++++++++++-
net/wireless/core.c | 5 +++
net/wireless/nl80211.c | 99 ++++++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 25 +++++++++++
net/wireless/trace.h | 60 +++++++++++++++++++++++++++
7 files changed, 241 insertions(+), 2 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 2049e983a994..fb1f533e75b3 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2356,8 +2356,11 @@ enum ieee80211_sa_query_action {
#define WLAN_MAX_KEY_LEN 32
+#define WLAN_PMK_NAME_LEN 16
#define WLAN_PMKID_LEN 16
+#define WLAN_PMK_LEN_EAP_LEAP 16
#define WLAN_PMK_LEN 32
+#define WLAN_PMK_LEN_SUITE_B_192 48
#define WLAN_OUI_WFA 0x506f9a
#define WLAN_OUI_TYPE_WFA_P2P 9
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4ca968927d60..a68c6db6ac55 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2507,6 +2507,23 @@ struct cfg80211_nan_func {
};
/**
+ * struct cfg80211_pmk_conf - PMK configuration
+ *
+ * @aa: authenticator address
+ * @pmk_len: PMK length in bytes.
+ * @pmk: the PMK material
+ * @pmk_r0_name: PMK-R0 Name. NULL if not applicable (i.e., the PMK
+ * is not PMK-R0). When pmk_r0_name is not NULL, the pmk field
+ * holds PMK-R0.
+ */
+struct cfg80211_pmk_conf {
+ const u8 *aa;
+ u8 pmk_len;
+ const u8 *pmk;
+ const u8 *pmk_r0_name;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2823,6 +2840,11 @@ struct cfg80211_nan_func {
* All other parameters must be ignored.
*
* @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
+ *
+ * @set_pmk: configure the PMK to be used for offloaded 4-Way handshake.
+ * (invoked with the wireless_dev mutex held)
+ * @del_pmk: delete the previously configured PMK for the given authenticator.
+ * (invoked with the wireless_dev mutex held)
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3111,6 +3133,11 @@ struct cfg80211_ops {
int (*set_multicast_to_unicast)(struct wiphy *wiphy,
struct net_device *dev,
const bool enabled);
+
+ int (*set_pmk)(struct wiphy *wiphy, struct net_device *dev,
+ const struct cfg80211_pmk_conf *conf);
+ int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *aa);
};
/*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index bb5e1904a107..89295fc2336b 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -901,6 +901,14 @@
* does not result in a change for the current association. Currently,
* only the %NL80211_ATTR_IE data is used and updated with this command.
*
+ * @NL80211_CMD_SET_PMK: For offloaded 4-Way handshake, set the PMK or PMK-R0
+ * for the given authenticator address (specified with &NL80211_ATTR_MAC).
+ * When &NL80211_ATTR_PMKR0_NAME is set, &NL80211_ATTR_PMK specifies the
+ * PMK-R0, otherwise it specifies the PMK.
+ * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
+ * configured PMK for the authenticator address identified by
+ * &NL80211_ATTR_MAC.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1100,6 +1108,9 @@ enum nl80211_commands {
NL80211_CMD_UPDATE_CONNECT_PARAMS,
+ NL80211_CMD_SET_PMK,
+ NL80211_CMD_DEL_PMK,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -2012,8 +2023,12 @@ enum nl80211_commands {
* u32 attribute with an &enum nl80211_timeout_reason value. This is used,
* e.g., with %NL80211_CMD_CONNECT event.
*
- * @NL80211_ATTR_PMK: PSK for offloaded 4-Way Handshake. Relevant only
- * with %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks).
+ * @NL80211_ATTR_PMK: PMK for offloaded 4-Way Handshake. Relevant with
+ * %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks) when PSK is used, or
+ * with %NL80211_CMD_SET_PMK when 802.1X authentication is used.
+ * When &NL80211_ATTR_PMKR0_NAME is specified, this attribute specifies
+ * the PMK-R0.
+ * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -2427,6 +2442,7 @@ enum nl80211_attrs {
NL80211_ATTR_TIMEOUT_REASON,
NL80211_ATTR_PMK,
+ NL80211_ATTR_PMKR0_NAME,
/* add attributes here, update the policy in nl80211.c */
@@ -4767,6 +4783,9 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK: Device supports doing 4-way
* handshake with PSK in station mode (PSK is passed as part of the connect
* and associate commands).
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X: Device supports doing 4-way
+ * handshake with 802.1X in station mode (needs to pass EAP frames to
+ * the host and accept the set_pmk/del_pmk commands).
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4787,6 +4806,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
NL80211_EXT_FEATURE_CQM_RSSI_LIST,
NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 76e664144c8e..65f4b4d4a805 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -691,6 +691,11 @@ int wiphy_register(struct wiphy *wiphy)
(wiphy->bss_select_support & ~(BIT(__NL80211_BSS_SELECT_ATTR_AFTER_LAST) - 2))))
return -EINVAL;
+ if (WARN_ON(wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X) &&
+ (!rdev->ops->set_pmk || !rdev->ops->del_pmk)))
+ return -EINVAL;
+
if (wiphy->addresses)
memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 494b50b3eb71..f67098559c3b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12075,6 +12075,90 @@ static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
return rdev_set_multicast_to_unicast(rdev, dev, enabled);
}
+static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_pmk_conf pmk_conf = {};
+ int ret;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
+
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
+ return -EINVAL;
+
+ wdev_lock(wdev);
+ if (!wdev->current_bss) {
+ ret = -ENOTCONN;
+ goto out;
+ }
+
+ pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
+ pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
+ if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
+ pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
+ int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
+
+ if (r0_name_len != WLAN_PMK_NAME_LEN) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pmk_conf.pmk_r0_name =
+ nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
+ }
+
+ ret = rdev_set_pmk(rdev, dev, &pmk_conf);
+out:
+ wdev_unlock(wdev);
+ return ret;
+}
+
+static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct net_device *dev = info->user_ptr[1];
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ const u8 *aa;
+ int ret;
+
+ if (wdev->iftype != NL80211_IFTYPE_STATION &&
+ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
+ return -EOPNOTSUPP;
+
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ wdev_lock(wdev);
+ aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
+ ret = rdev_del_pmk(rdev, dev, aa);
+ wdev_unlock(wdev);
+
+ return ret;
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -12950,6 +13034,21 @@ static const struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_SET_PMK,
+ .doit = nl80211_set_pmk,
+ .policy = nl80211_policy,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
+ .cmd = NL80211_CMD_DEL_PMK,
+ .doit = nl80211_del_pmk,
+ .policy = nl80211_policy,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+
};
static struct genl_family nl80211_fam __ro_after_init = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index f2baf5921091..06698552f1f2 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1165,4 +1165,29 @@ rdev_set_coalesce(struct cfg80211_registered_device *rdev,
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}
+
+static inline int rdev_set_pmk(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_pmk_conf *pmk_conf)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_set_pmk(&rdev->wiphy, dev, pmk_conf);
+ if (rdev->ops->set_pmk)
+ ret = rdev->ops->set_pmk(&rdev->wiphy, dev, pmk_conf);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
+static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
+ struct net_device *dev, const u8 *aa)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_del_pmk(&rdev->wiphy, dev, aa);
+ if (rdev->ops->del_pmk)
+ ret = rdev->ops->del_pmk(&rdev->wiphy, dev, aa);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index fd55786f0462..47a5e8d4b113 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2252,6 +2252,66 @@ TRACE_EVENT(rdev_tdls_cancel_channel_switch,
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(addr))
);
+TRACE_EVENT(rdev_set_pmk,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_pmk_conf *pmk_conf),
+
+ TP_ARGS(wiphy, netdev, pmk_conf),
+
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(aa)
+ __field(u8, pmk_len)
+ __field(u8, pmk_r0_name_len)
+ __dynamic_array(u8, pmk, pmk_conf->pmk_len)
+ __dynamic_array(u8, pmk_r0_name, WLAN_PMK_NAME_LEN)
+ ),
+
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(aa, pmk_conf->aa);
+ __entry->pmk_len = pmk_conf->pmk_len;
+ __entry->pmk_r0_name_len =
+ pmk_conf->pmk_r0_name ? WLAN_PMK_NAME_LEN : 0;
+ memcpy(__get_dynamic_array(pmk), pmk_conf->pmk,
+ pmk_conf->pmk_len);
+ memcpy(__get_dynamic_array(pmk_r0_name), pmk_conf->pmk_r0_name,
+ pmk_conf->pmk_r0_name ? WLAN_PMK_NAME_LEN : 0);
+ ),
+
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT
+ "pmk_len=%u, pmk: %s pmk_r0_name: %s", WIPHY_PR_ARG,
+ NETDEV_PR_ARG, MAC_PR_ARG(aa), __entry->pmk_len,
+ __print_array(__get_dynamic_array(pmk),
+ __get_dynamic_array_len(pmk), 1),
+ __entry->pmk_r0_name_len ?
+ __print_array(__get_dynamic_array(pmk_r0_name),
+ __get_dynamic_array_len(pmk_r0_name), 1) : "")
+);
+
+TRACE_EVENT(rdev_del_pmk,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *aa),
+
+ TP_ARGS(wiphy, netdev, aa),
+
+ TP_STRUCT__entry(
+ WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(aa)
+ ),
+
+ TP_fast_assign(
+ WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(aa, aa);
+ ),
+
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT,
+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
+);
+
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
--
2.9.3
^ permalink raw reply related
* [RFC v2 1/2] cfg80211: support 4-way handshake offloading for WPA/WPA2-PSK
From: Johannes Berg @ 2017-02-21 12:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Eliad Peller
From: Eliad Peller <eliad@wizery.com>
Let drivers advertise support for station-mode 4-way handshake
offloading with a new NL80211_EXT_FEATURE_4WAY_HANDSHAKE_OFFLOAD_STA
flag.
Add a new NL80211_ATTR_PMK attribute that might be passed as part
of NL80211_CMD_CONNECT command, and contain the PSK (which is the
PMK, hence the name.)
The driver/device is assumed to handle the 4-way handshake by
itself in this case (including key derivations, etc.), instead
of relying on the supplicant.
This patch is somewhat based on this one (by Vladimir Kondratiev):
https://patchwork.kernel.org/patch/1309561/.
Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/linux/ieee80211.h | 1 +
include/net/cfg80211.h | 2 ++
include/uapi/linux/nl80211.h | 9 +++++++++
net/wireless/nl80211.c | 8 ++++++++
4 files changed, 20 insertions(+)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 6ea381c98aae..2049e983a994 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2357,6 +2357,7 @@ enum ieee80211_sa_query_action {
#define WLAN_MAX_KEY_LEN 32
#define WLAN_PMKID_LEN 16
+#define WLAN_PMK_LEN 32
#define WLAN_OUI_WFA 0x506f9a
#define WLAN_OUI_TYPE_WFA_P2P 9
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 86c12f85fb53..4ca968927d60 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -643,6 +643,7 @@ struct survey_info {
* @wep_keys: static WEP keys, if not NULL points to an array of
* CFG80211_MAX_WEP_KEYS WEP keys
* @wep_tx_key: key index (0..3) of the default TX static WEP key
+ * @psk: PSK (for devices supporting 4-way-handshake offload)
*/
struct cfg80211_crypto_settings {
u32 wpa_versions;
@@ -656,6 +657,7 @@ struct cfg80211_crypto_settings {
bool control_port_no_encrypt;
struct key_params *wep_keys;
int wep_tx_key;
+ const u8 *psk;
};
/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9a499b15cfbc..bb5e1904a107 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2012,6 +2012,9 @@ enum nl80211_commands {
* u32 attribute with an &enum nl80211_timeout_reason value. This is used,
* e.g., with %NL80211_CMD_CONNECT event.
*
+ * @NL80211_ATTR_PMK: PSK for offloaded 4-Way Handshake. Relevant only
+ * with %NL80211_CMD_CONNECT (for WPA/WPA2-PSK networks).
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2423,6 +2426,8 @@ enum nl80211_attrs {
NL80211_ATTR_TIMEOUT_REASON,
+ NL80211_ATTR_PMK,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -4759,6 +4764,9 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_CQM_RSSI_LIST: With this driver the
* %NL80211_ATTR_CQM_RSSI_THOLD attribute accepts a list of zero or more
* RSSI threshold values to monitor rather than exactly one threshold.
+ * @NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK: Device supports doing 4-way
+ * handshake with PSK in station mode (PSK is passed as part of the connect
+ * and associate commands).
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4778,6 +4786,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED,
NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
NL80211_EXT_FEATURE_CQM_RSSI_LIST,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d516527fcb8e..494b50b3eb71 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -410,6 +410,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
.len = sizeof(struct nl80211_bss_select_rssi_adjust)
},
[NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
+ [NL80211_ATTR_PMK] = { .len = WLAN_PMK_LEN },
};
/* policy for the key attributes */
@@ -8039,6 +8040,13 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
memcpy(settings->akm_suites, data, len);
}
+ if (info->attrs[NL80211_ATTR_PMK]) {
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
+ return -EINVAL;
+ settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
+ }
+
return 0;
}
--
2.9.3
^ permalink raw reply related
* Re: [OpenWrt-Devel] ATH10K VLAN firmware issue
From: Valo, Kalle @ 2017-02-21 13:19 UTC (permalink / raw)
To: voncken
Cc: 'OpenWrt Development List', 'linux-wireless',
ath10k@lists.infradead.org
In-Reply-To: <027001d28c42$5042c910$f0c85b30$@acksys.fr>
voncken <cedric.voncken@acksys.fr> writes:
> Do you know if the firmware team planned to fix the VLAN issue on ath10k
> firmware?
I reported it forward only this week.
--=20
Kalle Valo=
^ permalink raw reply
* [PATCH 00/10] wil6210 patches
From: Maya Erez @ 2017-02-21 14:31 UTC (permalink / raw)
To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210
various wil6210 patches
Dedy Lansky (4):
wil6210: use print_hex_dump_debug instead of print_hex_dump_bytes
wil6210: store bss object and use cfg80211_connect_bss()
wil6210: use WMI_DISCONNECT_CMDID upon connect timeout
wil6210: correctly report locally generated disconnect in STA mode
Hamad Kadmany (2):
wil6210: set dma mask to reflect device capability
wil6210: protect list of pending wmi events during flush
Lior David (3):
wil6210: do not start regular scan on stopped p2p device
wil6210: bus_request platform operation refinement
wil6210: add oob_mode for AP certification
Maya Erez (1):
wil6210: missing reinit_completion in HALP voting
drivers/net/wireless/ath/wil6210/cfg80211.c | 68 ++++++++++++++------------
drivers/net/wireless/ath/wil6210/main.c | 75 +++++++++++++++++++++++------
drivers/net/wireless/ath/wil6210/pcie_bus.c | 16 ++++++
drivers/net/wireless/ath/wil6210/pmc.c | 17 ++++++-
drivers/net/wireless/ath/wil6210/txrx.c | 19 +++++++-
drivers/net/wireless/ath/wil6210/wil6210.h | 21 +++++++-
drivers/net/wireless/ath/wil6210/wmi.c | 21 ++++++--
7 files changed, 183 insertions(+), 54 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH 01/10] wil6210: set dma mask to reflect device capability
From: Maya Erez @ 2017-02-21 14:31 UTC (permalink / raw)
To: Kalle Valo; +Cc: Hamad Kadmany, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1487687528-12832-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Hamad Kadmany <qca_hkadmany@qca.qualcomm.com>
device supports 48bit addresses, reflect that by
setting the dma mask accordingly.
Signed-off-by: Hamad Kadmany <qca_hkadmany@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/pcie_bus.c | 16 ++++++++++++++++
drivers/net/wireless/ath/wil6210/pmc.c | 17 ++++++++++++++++-
drivers/net/wireless/ath/wil6210/txrx.c | 19 ++++++++++++++++++-
drivers/net/wireless/ath/wil6210/wil6210.h | 1 +
4 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 874c787..b38515f 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -211,6 +211,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev_err(dev, "wil_if_alloc failed: %d\n", rc);
return rc;
}
+
wil->pdev = pdev;
pci_set_drvdata(pdev, wil);
/* rollback to if_free */
@@ -224,6 +225,21 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* rollback to err_plat */
+ /* device supports 48bit addresses */
+ rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+ if (rc) {
+ dev_err(dev, "dma_set_mask_and_coherent(48) failed: %d\n", rc);
+ rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (rc) {
+ dev_err(dev,
+ "dma_set_mask_and_coherent(32) failed: %d\n",
+ rc);
+ goto err_plat;
+ }
+ } else {
+ wil->use_extended_dma_addr = 1;
+ }
+
rc = pci_enable_device(pdev);
if (rc) {
wil_err(wil,
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c
index 3ff4f4c..b067fdf 100644
--- a/drivers/net/wireless/ath/wil6210/pmc.c
+++ b/drivers/net/wireless/ath/wil6210/pmc.c
@@ -107,13 +107,28 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
/* Allocate pring buffer and descriptors.
* vring->va should be aligned on its size rounded up to power of 2
- * This is granted by the dma_alloc_coherent
+ * This is granted by the dma_alloc_coherent.
+ *
+ * HW has limitation that all vrings addresses must share the same
+ * upper 16 msb bits part of 48 bits address. To workaround that,
+ * if we are using 48 bit addresses switch to 32 bit allocation
+ * before allocating vring memory.
+ *
+ * There's no check for the return value of dma_set_mask_and_coherent,
+ * since we assume if we were able to set the mask during
+ * initialization in this system it will not fail if we set it again
*/
+ if (wil->use_extended_dma_addr)
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+
pmc->pring_va = dma_alloc_coherent(dev,
sizeof(struct vring_tx_desc) * num_descriptors,
&pmc->pring_pa,
GFP_KERNEL);
+ if (wil->use_extended_dma_addr)
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+
wil_dbg_misc(wil,
"pmc_alloc: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
pmc->pring_va, &pmc->pring_pa,
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 072182e..67f50ae 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -123,15 +123,32 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
vring->va = NULL;
return -ENOMEM;
}
+
/* vring->va should be aligned on its size rounded up to power of 2
- * This is granted by the dma_alloc_coherent
+ * This is granted by the dma_alloc_coherent.
+ *
+ * HW has limitation that all vrings addresses must share the same
+ * upper 16 msb bits part of 48 bits address. To workaround that,
+ * if we are using 48 bit addresses switch to 32 bit allocation
+ * before allocating vring memory.
+ *
+ * There's no check for the return value of dma_set_mask_and_coherent,
+ * since we assume if we were able to set the mask during
+ * initialization in this system it will not fail if we set it again
*/
+ if (wil->use_extended_dma_addr)
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+
vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
if (!vring->va) {
kfree(vring->ctx);
vring->ctx = NULL;
return -ENOMEM;
}
+
+ if (wil->use_extended_dma_addr)
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
+
/* initially, all descriptors are SW owned
* For Tx and Rx, ownership bit is at the same location, thus
* we can use any
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 085a2db..ea1e5b34 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -657,6 +657,7 @@ struct wil6210_priv {
u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
struct wil_sta_info sta[WIL6210_MAX_CID];
int bcast_vring;
+ bool use_extended_dma_addr; /* indicates whether we are using 48 bits */
/* scan */
struct cfg80211_scan_request *scan_request;
--
1.9.1
^ permalink raw reply related
* [PATCH 02/10] wil6210: do not start regular scan on stopped p2p device
From: Maya Erez @ 2017-02-21 14:32 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1487687528-12832-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lior David <qca_liord@qca.qualcomm.com>
The driver should not allow starting any type of scan on a stopped
P2P device. Current implementation only checked social scan.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 83155b5..14aa6d3 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -390,22 +390,23 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
}
mutex_unlock(&wil->p2p_wdev_mutex);
- /* social scan on P2P_DEVICE is handled as p2p search */
- if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE &&
- wil_p2p_is_social_scan(request)) {
+ if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
if (!wil->p2p.p2p_dev_started) {
wil_err(wil, "P2P search requested on stopped P2P device\n");
rc = -EIO;
goto out;
}
- wil->scan_request = request;
- wil->radio_wdev = wdev;
- rc = wil_p2p_search(wil, request);
- if (rc) {
- wil->radio_wdev = wil_to_wdev(wil);
- wil->scan_request = NULL;
+ /* social scan on P2P_DEVICE is handled as p2p search */
+ if (wil_p2p_is_social_scan(request)) {
+ wil->scan_request = request;
+ wil->radio_wdev = wdev;
+ rc = wil_p2p_search(wil, request);
+ if (rc) {
+ wil->radio_wdev = wil_to_wdev(wil);
+ wil->scan_request = NULL;
+ }
+ goto out;
}
- goto out;
}
(void)wil_p2p_stop_discovery(wil);
--
1.9.1
^ permalink raw reply related
* [PATCH 03/10] wil6210: bus_request platform operation refinement
From: Maya Erez @ 2017-02-21 14:32 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1487687528-12832-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lior David <qca_liord@qca.qualcomm.com>
The driver uses the bus_request platform operation to
request resources from the platform for a specific bandwidth.
Currently the driver requests resources for the maximum
theoretical bandwidth, when interface is brought up.
Refine this process a bit: now the driver will request a
small amount of resources when interface is up, and will only
issue the maximum request when connected.
This mechanism will be improved further in the future to make
more refined requests based on actual bandwidth.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 4 ++++
drivers/net/wireless/ath/wil6210/main.c | 14 +++++++++-----
drivers/net/wireless/ath/wil6210/wil6210.h | 5 +++--
drivers/net/wireless/ath/wil6210/wmi.c | 1 +
4 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 14aa6d3..2dc594d 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -680,6 +680,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
if (rc == 0) {
netif_carrier_on(ndev);
+ wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
/* Connect can take lots of time */
mod_timer(&wil->connect_timer,
jiffies + msecs_to_jiffies(2000));
@@ -1199,6 +1200,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
wil->pbss = pbss;
netif_carrier_on(ndev);
+ wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
rc = wmi_pcp_start(wil, bi, wmi_nettype, chan, hidden_ssid, is_go);
if (rc)
@@ -1214,6 +1216,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
wmi_pcp_stop(wil);
err_pcp_start:
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
out:
mutex_unlock(&wil->mutex);
return rc;
@@ -1320,6 +1323,7 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
wil_dbg_misc(wil, "stop_ap\n");
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
wil_set_recovery_state(wil, fw_recovery_idle);
mutex_lock(&wil->mutex);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index efb1f59..21b7fac 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -274,6 +274,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
wil_bcast_fini(wil);
wil_update_net_queues_bh(wil, NULL, true);
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
if (test_bit(wil_status_fwconnected, wil->status)) {
clear_bit(wil_status_fwconnected, wil->status);
@@ -555,6 +556,12 @@ int wil_priv_init(struct wil6210_priv *wil)
return -EAGAIN;
}
+void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps)
+{
+ if (wil->platform_ops.bus_request)
+ wil->platform_ops.bus_request(wil->platform_handle, kbps);
+}
+
/**
* wil6210_disconnect - disconnect one connection
* @wil: driver context
@@ -1066,9 +1073,7 @@ int __wil_up(struct wil6210_priv *wil)
napi_enable(&wil->napi_tx);
set_bit(wil_status_napi_en, wil->status);
- if (wil->platform_ops.bus_request)
- wil->platform_ops.bus_request(wil->platform_handle,
- WIL_MAX_BUS_REQUEST_KBPS);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
return 0;
}
@@ -1092,8 +1097,7 @@ int __wil_down(struct wil6210_priv *wil)
set_bit(wil_status_resetting, wil->status);
- if (wil->platform_ops.bus_request)
- wil->platform_ops.bus_request(wil->platform_handle, 0);
+ wil6210_bus_request(wil, 0);
wil_disable_irq(wil);
if (test_and_clear_bit(wil_status_napi_en, wil->status)) {
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index ea1e5b34..12de74a 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -40,6 +40,7 @@
#define WIL_FW_NAME_SPARROW_PLUS "wil6210_sparrow_plus.fw" /* code Sparrow D0 */
#define WIL_BOARD_FILE_NAME "wil6210.brd" /* board & radio parameters */
+#define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */
#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
/**
@@ -900,7 +901,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
int wmi_abort_scan(struct wil6210_priv *wil);
void wil_abort_scan(struct wil6210_priv *wil, bool sync);
-
+void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps);
void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
u16 reason_code, bool from_event);
void wil_probe_client_flush(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 1f22c19..a7a4ac1 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -565,6 +565,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
(wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
if (rc) {
netif_carrier_off(ndev);
+ wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
wil_err(wil, "cfg80211_connect_result with failure\n");
cfg80211_connect_result(ndev, evt->bssid, NULL, 0,
NULL, 0,
--
1.9.1
^ permalink raw reply related
* [PATCH 04/10] wil6210: use print_hex_dump_debug instead of print_hex_dump_bytes
From: Maya Erez @ 2017-02-21 14:32 UTC (permalink / raw)
To: Kalle Valo; +Cc: Dedy Lansky, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1487687528-12832-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Dedy Lansky <qca_dlansky@qca.qualcomm.com>
Some dynamic debug printouts in driver are using print_hex_dump_bytes.
However, with dynamic debug disabled, print_hex_dump_bytes outputs to
log unconditionally.
Use print_hex_dump_debug instead to prevent log pollution when dynamic
debug disabled.
Signed-off-by: Dedy Lansky <qca_dlansky@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 41 +++++++++++++++--------------
drivers/net/wireless/ath/wil6210/wil6210.h | 12 +++++++++
2 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 2dc594d..581a4e2 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -416,9 +416,9 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
for (i = 0; i < request->n_ssids; i++) {
wil_dbg_misc(wil, "SSID[%d]", i);
- print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
- request->ssids[i].ssid,
- request->ssids[i].ssid_len);
+ wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
+ request->ssids[i].ssid,
+ request->ssids[i].ssid_len, true);
}
if (request->n_ssids)
@@ -455,8 +455,8 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
}
if (request->ie_len)
- print_hex_dump_bytes("Scan IE ", DUMP_PREFIX_OFFSET,
- request->ie, request->ie_len);
+ wil_hex_dump_misc("Scan IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ request->ie, request->ie_len, true);
else
wil_dbg_misc(wil, "Scan has no IE's\n");
@@ -762,7 +762,8 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
*/
wil_dbg_misc(wil, "mgmt_tx\n");
- print_hex_dump_bytes("mgmt tx frame ", DUMP_PREFIX_OFFSET, buf, len);
+ wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
+ len, true);
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
if (!cmd) {
@@ -1095,18 +1096,18 @@ static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len,
static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
{
- print_hex_dump_bytes("head ", DUMP_PREFIX_OFFSET,
- b->head, b->head_len);
- print_hex_dump_bytes("tail ", DUMP_PREFIX_OFFSET,
- b->tail, b->tail_len);
- print_hex_dump_bytes("BCON IE ", DUMP_PREFIX_OFFSET,
- b->beacon_ies, b->beacon_ies_len);
- print_hex_dump_bytes("PROBE ", DUMP_PREFIX_OFFSET,
- b->probe_resp, b->probe_resp_len);
- print_hex_dump_bytes("PROBE IE ", DUMP_PREFIX_OFFSET,
- b->proberesp_ies, b->proberesp_ies_len);
- print_hex_dump_bytes("ASSOC IE ", DUMP_PREFIX_OFFSET,
- b->assocresp_ies, b->assocresp_ies_len);
+ wil_hex_dump_misc("head ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->head, b->head_len, true);
+ wil_hex_dump_misc("tail ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->tail, b->tail_len, true);
+ wil_hex_dump_misc("BCON IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->beacon_ies, b->beacon_ies_len, true);
+ wil_hex_dump_misc("PROBE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->probe_resp, b->probe_resp_len, true);
+ wil_hex_dump_misc("PROBE IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->proberesp_ies, b->proberesp_ies_len, true);
+ wil_hex_dump_misc("ASSOC IE ", DUMP_PREFIX_OFFSET, 16, 1,
+ b->assocresp_ies, b->assocresp_ies_len, true);
}
/* internal functions for device reset and starting AP */
@@ -1302,8 +1303,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
info->dtim_period);
wil_dbg_misc(wil, "PBSS %d\n", info->pbss);
- print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
- info->ssid, info->ssid_len);
+ wil_hex_dump_misc("SSID ", DUMP_PREFIX_OFFSET, 16, 1,
+ info->ssid, info->ssid_len, true);
wil_print_bcon_data(bcon);
wil_print_crypto(wil, crypto);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 12de74a..89e7eb7 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -766,6 +766,12 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val)
print_hex_dump_debug("DBG[ WMI]" prefix_str,\
prefix_type, rowsize, \
groupsize, buf, len, ascii)
+
+#define wil_hex_dump_misc(prefix_str, prefix_type, rowsize, \
+ groupsize, buf, len, ascii) \
+ print_hex_dump_debug("DBG[MISC]" prefix_str,\
+ prefix_type, rowsize, \
+ groupsize, buf, len, ascii)
#else /* defined(CONFIG_DYNAMIC_DEBUG) */
static inline
void wil_hex_dump_txrx(const char *prefix_str, int prefix_type, int rowsize,
@@ -778,6 +784,12 @@ void wil_hex_dump_wmi(const char *prefix_str, int prefix_type, int rowsize,
int groupsize, const void *buf, size_t len, bool ascii)
{
}
+
+static inline
+void wil_hex_dump_misc(const char *prefix_str, int prefix_type, int rowsize,
+ int groupsize, const void *buf, size_t len, bool ascii)
+{
+}
#endif /* defined(CONFIG_DYNAMIC_DEBUG) */
void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
--
1.9.1
^ permalink raw reply related
* [PATCH 05/10] wil6210: missing reinit_completion in HALP voting
From: Maya Erez @ 2017-02-21 14:32 UTC (permalink / raw)
To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210
In-Reply-To: <1487687528-12832-1-git-send-email-qca_merez@qca.qualcomm.com>
After setting HALP ICR bit, we keep it set until HALP unvote.
Masking HALP ICR should protect the driver from hitting the HALP ICR
over and over again. However, in case there is another MISC ICR
we will read the HALP ICR and issue a completion. This can lead to
a case where HALP voting is completed immediately, as the completion
is already set.
Reinit the HALP completion before the actual vote will clear previous
completions and protect from such cases.
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 21b7fac..dddde94 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -1158,6 +1158,7 @@ void wil_halp_vote(struct wil6210_priv *wil)
wil->halp.ref_cnt);
if (++wil->halp.ref_cnt == 1) {
+ reinit_completion(&wil->halp.comp);
wil6210_set_halp(wil);
rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
if (!rc) {
--
1.9.1
^ permalink raw reply related
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