return chanmode;
}
-static int ath_keyset(struct ath_softc *sc, u16 keyix,
- struct ath9k_keyval *hk, const u8 mac[ETH_ALEN])
-{
- bool status;
-
- status = ath9k_hw_set_keycache_entry(sc->sc_ah,
- keyix, hk, mac);
-
- return status != false;
-}
-
static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
struct ath9k_keyval *hk, const u8 *addr,
bool authenticator)
key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
if (addr == NULL) {
- /* Group key installation */
+ /*
+ * Group key installation - only two key cache entries are used
+ * regardless of splitmic capability since group key is only
+ * used either for TX or RX.
+ */
if (authenticator) {
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
}
- return ath_keyset(sc, keyix, hk, addr);
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
}
if (!sc->splitmic) {
- /*
- * data key goes at first index,
- * the hal handles the MIC keys at index+64.
- */
+ /* TX and RX keys share the same key cache entry. */
memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
- return ath_keyset(sc, keyix, hk, addr);
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
}
- /*
- * TX key goes at first index, RX key at +32.
- * The hal handles the MIC keys at index+64.
- */
+
+ /* Separate key cache entries for TX and RX */
+
+ /* TX key goes at first index, RX key at +32. */
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
- if (!ath_keyset(sc, keyix, hk, NULL)) {
- /* Txmic entry failed. No need to proceed further */
+ if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
+ /* TX MIC entry failed. No need to proceed further */
DPRINTF(sc, ATH_DBG_KEYCACHE,
"Setting TX MIC Key Failed\n");
return 0;
memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
/* XXX delete tx key on failure? */
- return ath_keyset(sc, keyix + 32, hk, addr);
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
}
static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
vif->type == NL80211_IFTYPE_AP);
else
- ret = ath_keyset(sc, idx, &hk, mac);
+ ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
if (!ret)
return -EIO;
/* Configure the beacon */
ath_beacon_config(sc, 0);
- sc->sc_flags |= SC_OP_BEACONS;
/* Reset rssi stats */
sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
avp->av_opmode = ic_opmode;
avp->av_bslot = -1;
- if (ic_opmode == NL80211_IFTYPE_AP)
+ if (ic_opmode == NL80211_IFTYPE_AP) {
ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+ sc->sc_flags |= SC_OP_TSF_RESET;
+ }
sc->vifs[0] = conf->vif;
sc->nvifs++;
if (changed & IEEE80211_CONF_CHANGE_POWER)
sc->config.txpowlimit = 2 * conf->power_level;
+ /*
+ * The HW TSF has to be reset when the beacon interval changes.
+ * We set the flag here, and ath_beacon_config_ap() would take this
+ * into account when it gets called through the subsequent
+ * config_interface() call - with IFCC_BEACON in the changed field.
+ */
+
+ if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
+ sc->sc_flags |= SC_OP_TSF_RESET;
+
mutex_unlock(&sc->mutex);
return 0;
u32 rfilt = 0;
int error, i;
+ mutex_lock(&sc->mutex);
+
/* TODO: Need to decide which hw opmode to use for multi-interface
* cases */
if (vif->type == NL80211_IFTYPE_AP &&
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
error = ath_beacon_alloc(sc, 0);
- if (error != 0)
+ if (error != 0) {
+ mutex_unlock(&sc->mutex);
return error;
+ }
- ath_beacon_sync(sc, 0);
+ ath_beacon_config(sc, 0);
}
}
if (vif->type == NL80211_IFTYPE_ADHOC)
ath_update_chainmask(sc, 0);
+ mutex_unlock(&sc->mutex);
+
return 0;
}