summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2008-05-28 23:33:29 +0000
committersam <sam@FreeBSD.org>2008-05-28 23:33:29 +0000
commita881f390cdde665597b4b8d5a9bc5a8c436cde49 (patch)
treeadaf8db76e4f6fcb5d2f7603e88533d97df03c8a /sys/net80211
parent7aa0974e2beebe0274ddf6e9c4c6663f0153b9fb (diff)
downloadFreeBSD-src-a881f390cdde665597b4b8d5a9bc5a8c436cde49.zip
FreeBSD-src-a881f390cdde665597b4b8d5a9bc5a8c436cde49.tar.gz
Add ieee80211_crypto_reload_keys to push all keys known
to net80211 back into the device; intended for use on resume by devices that lose the contents of their h/w key table.
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_crypto.c43
-rw-r--r--sys/net80211/ieee80211_crypto.h1
2 files changed, 44 insertions, 0 deletions
diff --git a/sys/net80211/ieee80211_crypto.c b/sys/net80211/ieee80211_crypto.c
index 1329bd4..761697f 100644
--- a/sys/net80211/ieee80211_crypto.c
+++ b/sys/net80211/ieee80211_crypto.c
@@ -609,3 +609,46 @@ ieee80211_crypto_decap(struct ieee80211_node *ni, struct mbuf *m, int hdrlen)
#undef IEEE80211_WEP_MINLEN
#undef IEEE80211_WEP_HDRLEN
}
+
+static void
+load_ucastkey(void *arg, struct ieee80211_node *ni)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_key *k;
+
+ if (vap->iv_state != IEEE80211_S_RUN)
+ return;
+ k = &ni->ni_ucastkey;
+ if (k->wk_keyix != IEEE80211_KEYIX_NONE)
+ dev_key_set(vap, k);
+}
+
+/*
+ * Re-load all keys known to the 802.11 layer that may
+ * have hardware state backing them. This is used by
+ * drivers on resume to push keys down into the device.
+ */
+void
+ieee80211_crypto_reload_keys(struct ieee80211com *ic)
+{
+ struct ieee80211vap *vap;
+ int i;
+
+ /*
+ * Keys in the global key table of each vap.
+ */
+ /* NB: used only during resume so don't lock for now */
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ if (vap->iv_state != IEEE80211_S_RUN)
+ continue;
+ for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+ const struct ieee80211_key *k = &vap->iv_nw_keys[i];
+ if (k->wk_keyix != IEEE80211_KEYIX_NONE)
+ dev_key_set(vap, k);
+ }
+ }
+ /*
+ * Unicast keys.
+ */
+ ieee80211_iterate_nodes(&ic->ic_sta, load_ucastkey, NULL);
+}
diff --git a/sys/net80211/ieee80211_crypto.h b/sys/net80211/ieee80211_crypto.h
index f6f666c..89f0e78 100644
--- a/sys/net80211/ieee80211_crypto.h
+++ b/sys/net80211/ieee80211_crypto.h
@@ -147,6 +147,7 @@ int ieee80211_crypto_delkey(struct ieee80211vap *,
struct ieee80211_key *);
int ieee80211_crypto_setkey(struct ieee80211vap *, struct ieee80211_key *);
void ieee80211_crypto_delglobalkeys(struct ieee80211vap *);
+void ieee80211_crypto_reload_keys(struct ieee80211com *);
/*
* Template for a supported cipher. Ciphers register with the
OpenPOWER on IntegriCloud