From 4c56122dc64fc32e519e8df9e0524251565efdf2 Mon Sep 17 00:00:00 2001 From: Alexander Egorenkov Date: Wed, 10 Mar 2010 15:23:45 +0100 Subject: [PATCH] Update WCID attribute for group key in HOSTAP mode --- rt2870.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/rt2870.c b/rt2870.c index 5e67ac5..c52b6ec 100644 --- a/rt2870.c +++ b/rt2870.c @@ -2826,7 +2826,7 @@ static void rt2870_vap_key_set_cb(struct rt2870_softc *sc, void *arg) iv[7] = (k->wk_keytsc >> 40); RT2870_DPRINTF(sc, RT2870_DEBUG_KEY, - "%s: set key: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n", + "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n", device_get_nameunit(sc->dev), iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]); } @@ -2865,6 +2865,7 @@ static void rt2870_vap_key_set_cb(struct rt2870_softc *sc, void *arg) /* install group key */ vapid = 0; + wcid = 0; /* mcast/bcast WCID */ key_base = RT2870_REG_SKEY(vapid, k->wk_keyix); keymode_base = RT2870_REG_SKEY_MODE(vapid); @@ -2894,6 +2895,51 @@ static void rt2870_vap_key_set_cb(struct rt2870_softc *sc, void *arg) tmp |= (mode << (k->wk_keyix * 4 + 16 * (vapid % 2))); rt2870_io_mac_write(sc, keymode_base, tmp); + + if (vap->iv_opmode == IEEE80211_M_HOSTAP) + { + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP) + { + memset(iv, 0, 8); + + iv[3] = (k->wk_keyix << 6); + } + else + { + if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) + { + iv[0] = (k->wk_keytsc >> 8); + iv[1] = ((iv[0] | 0x20) & 0x7f); + iv[2] = k->wk_keytsc; + } + else + { + /* AES CCMP */ + + iv[0] = k->wk_keytsc; + iv[1] = k->wk_keytsc >> 8; + iv[2] = 0; + } + + iv[3] = ((k->wk_keyix << 6) | IEEE80211_WEP_EXTIV); + iv[4] = (k->wk_keytsc >> 16); + iv[5] = (k->wk_keytsc >> 24); + iv[6] = (k->wk_keytsc >> 32); + iv[7] = (k->wk_keytsc >> 40); + + RT2870_DPRINTF(sc, RT2870_DEBUG_KEY, + "%s: VAP key set: iv=%02x %02x %02x %02x %02x %02x %02x %02x\n", + device_get_nameunit(sc->dev), + iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]); + } + + rt2870_io_mac_write_multi(sc, RT2870_REG_IVEIV(wcid), iv, 8); + + tmp = ((vapid & RT2870_REG_VAP_MASK) << RT2870_REG_VAP_SHIFT) | + (mode << RT2870_REG_CIPHER_MODE_SHIFT); + + rt2870_io_mac_write(sc, RT2870_REG_WCID_ATTR(wcid), tmp); + } } RT2870_SOFTC_UNLOCK(sc); @@ -4462,8 +4508,10 @@ static int rt2870_tx_data(struct rt2870_softc *sc, else mcs = rt2870_rate2mcs(rate); - wcid = (type == IEEE80211_FC0_TYPE_DATA) ? - RT2870_AID2WCID(ni->ni_associd) : 0xff; + if (type == IEEE80211_FC0_TYPE_DATA) + wcid = !IEEE80211_IS_MULTICAST(wh->i_addr1) ? RT2870_AID2WCID(ni->ni_associd) : 0; + else + wcid = 0xff; /* calculate MPDU length without padding */ -- 2.11.4.GIT