summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravos <avos@FreeBSD.org>2016-06-09 21:19:46 +0000
committeravos <avos@FreeBSD.org>2016-06-09 21:19:46 +0000
commit11745a27b1c88a43294771a37db0f7d644d84653 (patch)
treeb9cbc558bf819bf4d2e3caf5410b277199eaae7d
parent28e76ab1691f7e8cdeb5b787fce595633d1be976 (diff)
downloadFreeBSD-src-11745a27b1c88a43294771a37db0f7d644d84653.zip
FreeBSD-src-11745a27b1c88a43294771a37db0f7d644d84653.tar.gz
urtwn: reinstall group keys on every device startup.
Since key table is cleared on every device shutdown, static WEP keys (which are set only once) need to be reinstalled manually every time when device starts running. Tested with RTL8188EU, STA (all ciphers) / IBSS (WPA-none) modes.
-rw-r--r--sys/dev/urtwn/if_urtwn.c58
-rw-r--r--sys/dev/urtwn/if_urtwnvar.h2
2 files changed, 54 insertions, 6 deletions
diff --git a/sys/dev/urtwn/if_urtwn.c b/sys/dev/urtwn/if_urtwn.c
index 2107fe1..999bb6e 100644
--- a/sys/dev/urtwn/if_urtwn.c
+++ b/sys/dev/urtwn/if_urtwn.c
@@ -373,6 +373,8 @@ static void urtwn_set_chan(struct urtwn_softc *,
static void urtwn_iq_calib(struct urtwn_softc *);
static void urtwn_lc_calib(struct urtwn_softc *);
static void urtwn_temp_calib(struct urtwn_softc *);
+static void urtwn_setup_static_keys(struct urtwn_softc *,
+ struct urtwn_vap *);
static int urtwn_init(struct urtwn_softc *);
static void urtwn_stop(struct urtwn_softc *);
static void urtwn_abort_xfers(struct urtwn_softc *);
@@ -2340,12 +2342,28 @@ static int
urtwn_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+ struct urtwn_vap *uvp = URTWN_VAP(vap);
if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
/* Not for us. */
return (1);
}
+ if (&vap->iv_nw_keys[0] <= k &&
+ k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) {
+ URTWN_LOCK(sc);
+ uvp->keys[k->wk_keyix] = k;
+ if ((sc->sc_flags & URTWN_RUNNING) == 0) {
+ /*
+ * The device was not started;
+ * the key will be installed later.
+ */
+ URTWN_UNLOCK(sc);
+ return (1);
+ }
+ URTWN_UNLOCK(sc);
+ }
+
return (!urtwn_cmd_sleepable(sc, k, sizeof(*k), urtwn_key_set_cb));
}
@@ -2353,12 +2371,25 @@ static int
urtwn_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+ struct urtwn_vap *uvp = URTWN_VAP(vap);
if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
/* Not for us. */
return (1);
}
+ if (&vap->iv_nw_keys[0] <= k &&
+ k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]) {
+ URTWN_LOCK(sc);
+ uvp->keys[k->wk_keyix] = NULL;
+ if ((sc->sc_flags & URTWN_RUNNING) == 0) {
+ /* All keys are removed on device reset. */
+ URTWN_UNLOCK(sc);
+ return (1);
+ }
+ URTWN_UNLOCK(sc);
+ }
+
return (!urtwn_cmd_sleepable(sc, k, sizeof(*k), urtwn_key_del_cb));
}
@@ -5230,6 +5261,20 @@ urtwn_temp_calib(struct urtwn_softc *sc)
}
}
+static void
+urtwn_setup_static_keys(struct urtwn_softc *sc, struct urtwn_vap *uvp)
+{
+ int i;
+
+ for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+ const struct ieee80211_key *k = uvp->keys[i];
+ if (k != NULL) {
+ urtwn_cmd_sleepable(sc, k, sizeof(*k),
+ urtwn_key_set_cb);
+ }
+ }
+}
+
static int
urtwn_init(struct urtwn_softc *sc)
{
@@ -5418,12 +5463,6 @@ urtwn_init(struct urtwn_softc *sc)
R92C_SECCFG_TXENC_ENA | R92C_SECCFG_RXDEC_ENA |
R92C_SECCFG_TXBCKEY_DEF | R92C_SECCFG_RXBCKEY_DEF);
- /*
- * Install static keys (if any).
- * Must be called after urtwn_cam_init().
- */
- ieee80211_runtask(ic, &sc->cmdq_task);
-
/* Enable hardware sequence numbering. */
urtwn_write_1(sc, R92C_HWSEQ_CTRL, R92C_TX_QUEUE_ALL);
@@ -5459,6 +5498,13 @@ urtwn_init(struct urtwn_softc *sc)
sc->sc_flags |= URTWN_RUNNING;
+ /*
+ * Install static keys (if any).
+ * Must be called after urtwn_cam_init().
+ */
+ if (vap != NULL)
+ urtwn_setup_static_keys(sc, URTWN_VAP(vap));
+
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
fail:
if (usb_err != USB_ERR_NORMAL_COMPLETION)
diff --git a/sys/dev/urtwn/if_urtwnvar.h b/sys/dev/urtwn/if_urtwnvar.h
index 7313f07..ada6439 100644
--- a/sys/dev/urtwn/if_urtwnvar.h
+++ b/sys/dev/urtwn/if_urtwnvar.h
@@ -107,6 +107,8 @@ struct urtwn_vap {
struct mbuf *bcn_mbuf;
struct task tsf_task_adhoc;
+ const struct ieee80211_key *keys[IEEE80211_WEP_NKID];
+
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
void (*recv_mgmt)(struct ieee80211_node *,
OpenPOWER on IntegriCloud