linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arend van Spriel <arend@broadcom.com>
To: Kalle Valo <kvalo@codeaurora.org>
Cc: linux-wireless <linux-wireless@vger.kernel.org>,
	Hante Meuleman <meuleman@broadcom.com>,
	Arend van Spriel <arend@broadcom.com>
Subject: [PATCH 14/21] brcmfmac: add wowl gtk rekeying offload support
Date: Wed, 17 Feb 2016 11:27:03 +0100	[thread overview]
Message-ID: <1455704830-10088-15-git-send-email-arend@broadcom.com> (raw)
In-Reply-To: <1455704830-10088-1-git-send-email-arend@broadcom.com>

From: Hante Meuleman <meuleman@broadcom.com>

This patch adds support for gtk rekeying offload and for gtk
rekeying failure during wowl mode.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 65 ++++++++++++++++++----
 .../broadcom/brcm80211/brcmfmac/cfg80211.h         |  2 +
 .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 12 ++++
 .../wireless/broadcom/brcm80211/brcmfmac/feature.h |  6 +-
 .../broadcom/brcm80211/brcmfmac/fwil_types.h       | 21 ++++++-
 5 files changed, 93 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 71f1fdf..6d849bb 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3526,6 +3526,10 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
 			else
 				wakeup_data.net_detect = cfg->wowl.nd_info;
 		}
+		if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
+			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
+			wakeup_data.gtk_rekey_failure = true;
+		}
 	} else {
 		wakeup = NULL;
 	}
@@ -3607,6 +3611,8 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
 		brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
 				    brcmf_wowl_nd_results);
 	}
+	if (wowl->gtk_rekey_failure)
+		wowl_config |= BRCMF_WOWL_GTK_FAILURE;
 	if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
 		wowl_config |= BRCMF_WOWL_UNASSOC;
 
@@ -4874,7 +4880,32 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
 	return ret;
 }
 
-static struct cfg80211_ops wl_cfg80211_ops = {
+#ifdef CONFIG_PM
+static int
+brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
+			      struct cfg80211_gtk_rekey_data *gtk)
+{
+	struct brcmf_if *ifp = netdev_priv(ndev);
+	struct brcmf_gtk_keyinfo_le gtk_le;
+	int ret;
+
+	brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
+
+	memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
+	memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
+	memcpy(gtk_le.replay_counter, gtk->replay_ctr,
+	       sizeof(gtk_le.replay_counter));
+
+	ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", &gtk_le,
+				       sizeof(gtk_le));
+	if (ret < 0)
+		brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret);
+
+	return ret;
+}
+#endif
+
+static struct cfg80211_ops brcmf_cfg80211_ops = {
 	.add_virtual_intf = brcmf_cfg80211_add_iface,
 	.del_virtual_intf = brcmf_cfg80211_del_iface,
 	.change_virtual_intf = brcmf_cfg80211_change_iface,
@@ -6139,19 +6170,18 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
 {
 #ifdef CONFIG_PM
 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
-	s32 err;
-	u32 wowl_cap;
 
 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
-		err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap);
-		if (!err) {
-			if (wowl_cap & BRCMF_WOWL_PFN_FOUND) {
-				brcmf_wowlan_support.flags |=
-							WIPHY_WOWLAN_NET_DETECT;
-				init_waitqueue_head(&cfg->wowl.nd_data_wait);
-			}
+		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
+			brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
+			init_waitqueue_head(&cfg->wowl.nd_data_wait);
 		}
 	}
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
+		brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
+		brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
+	}
+
 	wiphy->wowlan = &brcmf_wowlan_support;
 #endif
 }
@@ -6538,6 +6568,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
 	struct brcmf_cfg80211_info *cfg;
 	struct wiphy *wiphy;
+	struct cfg80211_ops *ops;
 	struct brcmf_cfg80211_vif *vif;
 	struct brcmf_if *ifp;
 	s32 err = 0;
@@ -6549,8 +6580,17 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 		return NULL;
 	}
 
+	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
+	if (!ops)
+		return NULL;
+
+	memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops));
 	ifp = netdev_priv(ndev);
-	wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
+#ifdef CONFIG_PM
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
+		ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
+#endif
+	wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
 	if (!wiphy) {
 		brcmf_err("Could not allocate wiphy device\n");
 		return NULL;
@@ -6560,6 +6600,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 
 	cfg = wiphy_priv(wiphy);
 	cfg->wiphy = wiphy;
+	cfg->ops = ops;
 	cfg->pub = drvr;
 	init_vif_event(&cfg->vif_event);
 	INIT_LIST_HEAD(&cfg->vif_list);
@@ -6686,6 +6727,7 @@ priv_out:
 	ifp->vif = NULL;
 wiphy_out:
 	brcmf_free_wiphy(wiphy);
+	kfree(ops);
 	return NULL;
 }
 
@@ -6696,6 +6738,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
 
 	brcmf_btcoex_detach(cfg);
 	wiphy_unregister(cfg->wiphy);
+	kfree(cfg->ops);
 	wl_deinit_priv(cfg);
 	brcmf_free_wiphy(cfg->wiphy);
 }
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 01f096f..e4c1d43 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -256,6 +256,7 @@ struct brcmf_cfg80211_wowl {
  * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
  *
  * @wiphy: wiphy object for cfg80211 interface.
+ * @ops: pointer to copy of ops as registered with wiphy object.
  * @conf: dongle configuration.
  * @p2p: peer-to-peer specific information.
  * @btcoex: Bluetooth coexistence information.
@@ -288,6 +289,7 @@ struct brcmf_cfg80211_wowl {
  */
 struct brcmf_cfg80211_info {
 	struct wiphy *wiphy;
+	struct cfg80211_ops *ops;
 	struct brcmf_cfg80211_conf *conf;
 	struct brcmf_p2p_info p2p;
 	struct brcmf_btcoex_info *btcoex;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 1ffa95f..098732a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -136,6 +136,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
 {
 	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
 	struct brcmf_pno_macaddr_le pfn_mac;
+	u32 wowl_cap;
 	s32 err;
 
 	brcmf_feat_firmware_capabilities(ifp);
@@ -143,6 +144,17 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
 	brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
 	if (drvr->bus_if->wowl_supported)
 		brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
+	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) {
+		err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap);
+		if (!err) {
+			if (wowl_cap & BRCMF_WOWL_PFN_FOUND)
+				ifp->drvr->feat_flags |=
+					BIT(BRCMF_FEAT_WOWL_ND);
+			if (wowl_cap & BRCMF_WOWL_GTK_FAILURE)
+				ifp->drvr->feat_flags |=
+					BIT(BRCMF_FEAT_WOWL_GTK);
+		}
+	}
 	/* MBSS does not work for 43362 */
 	if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
 		ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
index 2e2479d..f940c29 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
@@ -27,6 +27,8 @@
  * RSDB: Real Simultaneous Dual Band
  * TDLS: Tunneled Direct Link Setup
  * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan.
+ * WOWL_ND: WOWL net detect (PNO)
+ * WOWL_GTK: (WOWL) GTK rekeying offload
  */
 #define BRCMF_FEAT_LIST \
 	BRCMF_FEAT_DEF(MBSS) \
@@ -36,7 +38,9 @@
 	BRCMF_FEAT_DEF(P2P) \
 	BRCMF_FEAT_DEF(RSDB) \
 	BRCMF_FEAT_DEF(TDLS) \
-	BRCMF_FEAT_DEF(SCAN_RANDOM_MAC)
+	BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \
+	BRCMF_FEAT_DEF(WOWL_ND) \
+	BRCMF_FEAT_DEF(WOWL_GTK)
 
 /*
  * Quirks:
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index e9e177d..6d41ae3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -111,7 +111,9 @@
 /* Wakeup if received matched secured pattern: */
 #define BRCMF_WOWL_SECURE		(1 << 25)
 /* Wakeup on finding preferred network */
-#define BRCMF_WOWL_PFN_FOUND		(1 << 26)
+#define BRCMF_WOWL_PFN_FOUND		(1 << 27)
+/* Wakeup on receiving pairwise key EAP packets: */
+#define WIPHY_WOWL_EAP_PK		(1 << 28)
 /* Link Down indication in WoWL mode: */
 #define BRCMF_WOWL_LINKDOWN		(1 << 31)
 
@@ -136,6 +138,10 @@
 
 #define BRCMF_MCSSET_LEN		16
 
+#define BRCMF_RSN_KCK_LENGTH		16
+#define BRCMF_RSN_KEK_LENGTH		16
+#define BRCMF_RSN_REPLAY_LEN		8
+
 /* join preference types for join_pref iovar */
 enum brcmf_join_pref_types {
 	BRCMF_JOIN_PREF_RSSI = 1,
@@ -789,4 +795,17 @@ struct brcmf_pktcnt_le {
 	__le32 rx_ocast_good_pkt;
 };
 
+/**
+ * struct brcmf_gtk_keyinfo_le - GTP rekey data
+ *
+ * @kck: key confirmation key.
+ * @kek: key encryption key.
+ * @replay_counter: replay counter.
+ */
+struct brcmf_gtk_keyinfo_le {
+	u8 kck[BRCMF_RSN_KCK_LENGTH];
+	u8 kek[BRCMF_RSN_KEK_LENGTH];
+	u8 replay_counter[BRCMF_RSN_REPLAY_LEN];
+};
+
 #endif /* FWIL_TYPES_H_ */
-- 
1.9.1


  parent reply	other threads:[~2016-02-17 10:27 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-17 10:26 [PATCH 00/21] brcmfmac: driver setting concept and other changes Arend van Spriel
2016-02-17 10:26 ` [PATCH 01/21] brcmfmac: change function name for brcmf_cfg80211_wait_vif_event_timeout() Arend van Spriel
2016-03-07 12:19   ` [01/21] brcmfmac: change function name forbrcmf_cfg80211_wait_vif_event_timeout() Kalle Valo
2016-03-07 12:49     ` Kalle Valo
2016-03-07 20:03       ` Arend Van Spriel
2016-03-08  8:46         ` Kalle Valo
2016-02-17 10:26 ` [PATCH 02/21] brcmfmac: Limit memory allocs to <64K Arend van Spriel
2016-02-17 10:26 ` [PATCH 03/21] brcmfmac: check for wowl support before enumerating feature flag Arend van Spriel
2016-02-17 10:26 ` [PATCH 04/21] brcmfmac: Configure country code using device specific settings Arend van Spriel
2016-02-17 10:26 ` [PATCH 05/21] brcmfmac: Add length checks on firmware events Arend van Spriel
2016-02-17 10:26 ` [PATCH 06/21] brcmfmac: add neighbor discovery offload ip address table configuration Arend van Spriel
2016-02-17 10:26 ` [PATCH 07/21] brcmfmac: check return for ARP ip setting iovar Arend van Spriel
2016-02-17 10:26 ` [PATCH 08/21] brcmfmac: use device memsize config from fw if defined Arend van Spriel
2016-02-17 10:26 ` [PATCH 09/21] brcmfmac: use bar1 window size as provided by pci subsystem Arend van Spriel
2016-02-17 10:26 ` [PATCH 10/21] brcmfmac: add support for the PCIE 4366c0 chip Arend van Spriel
2016-02-17 10:27 ` [PATCH 11/21] brcmfmac: remove pcie gen1 support Arend van Spriel
2016-02-17 10:27 ` [PATCH 12/21] brcmfmac: increase timeout for tx eapol Arend van Spriel
2016-02-17 10:27 ` [PATCH 13/21] brcmfmac: move module init and exit to common Arend van Spriel
2016-02-17 10:27 ` Arend van Spriel [this message]
2016-02-17 10:27 ` [PATCH 15/21] brcmfmac: move platform data retrieval code " Arend van Spriel
2016-02-17 10:27 ` [PATCH 16/21] brcmfmac: keep ARP and ND offload enabled during WOWL Arend van Spriel
2016-02-17 10:27 ` [PATCH 17/21] brcmfmac: fix sdio sg table alloc crash Arend van Spriel
2016-02-17 10:27 ` [PATCH 18/21] brcmfmac: switch to new platform data Arend van Spriel
2016-03-04 14:49   ` Kalle Valo
2016-03-04 20:02     ` Arend Van Spriel
2016-02-17 10:27 ` [PATCH 19/21] brcmfmac: merge platform data and module paramaters Arend van Spriel
2016-02-17 10:27 ` [PATCH 20/21] brcmfmac: integrate add_keyext in add_key Arend van Spriel
2016-02-17 10:27 ` [PATCH 21/21] brcmfmac: add 802.11w management frame protection support Arend van Spriel
2016-02-25 22:26 ` [PATCH 00/21] brcmfmac: driver setting concept and other changes Rafał Miłecki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1455704830-10088-15-git-send-email-arend@broadcom.com \
    --to=arend@broadcom.com \
    --cc=kvalo@codeaurora.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=meuleman@broadcom.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).