Resolve conflicts.
This commit is contained in:
parent
afe9d603ec
commit
d2ba878019
370
sys/dev/ic/ath.c
370
sys/dev/ic/ath.c
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ath.c,v 1.54 2005/07/06 23:58:14 dyoung Exp $ */
|
||||
/* $NetBSD: ath.c,v 1.55 2005/07/26 22:52:48 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
|
||||
|
@ -38,10 +38,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.88 2005/04/12 17:56:43 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.94 2005/07/07 00:04:50 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.54 2005/07/06 23:58:14 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.55 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -78,6 +78,7 @@ __KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.54 2005/07/06 23:58:14 dyoung Exp $");
|
|||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_ether.h>
|
||||
#include <net/if_llc.h>
|
||||
|
@ -101,7 +102,7 @@ __KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.54 2005/07/06 23:58:14 dyoung Exp $");
|
|||
#include <contrib/dev/ic/athhal_desc.h>
|
||||
#include <contrib/dev/ic/athhal_devid.h> /* XXX for softled */
|
||||
|
||||
/* unaligned little endian access */
|
||||
/* unaligned little endian access */
|
||||
#define LE_READ_2(p) \
|
||||
((u_int16_t) \
|
||||
((((u_int8_t *)(p))[0] ) | (((u_int8_t *)(p))[1] << 8)))
|
||||
|
@ -116,7 +117,8 @@ enum {
|
|||
ATH_LED_POLL,
|
||||
};
|
||||
|
||||
static int ath_init(struct ifnet *);
|
||||
static int ath_ifinit(struct ifnet *);
|
||||
static int ath_init(struct ath_softc *);
|
||||
static void ath_stop_locked(struct ifnet *, int);
|
||||
static void ath_stop(struct ifnet *, int);
|
||||
static void ath_start(struct ifnet *);
|
||||
|
@ -126,7 +128,6 @@ static int ath_ioctl(struct ifnet *, u_long, caddr_t);
|
|||
static void ath_fatal_proc(void *, int);
|
||||
static void ath_rxorn_proc(void *, int);
|
||||
static void ath_bmiss_proc(void *, int);
|
||||
static void ath_initkeytable(struct ath_softc *);
|
||||
static int ath_key_alloc(struct ieee80211com *,
|
||||
const struct ieee80211_key *);
|
||||
static int ath_key_delete(struct ieee80211com *,
|
||||
|
@ -176,6 +177,7 @@ static void ath_chan_change(struct ath_softc *, struct ieee80211_channel *);
|
|||
static void ath_next_scan(void *);
|
||||
static void ath_calibrate(void *);
|
||||
static int ath_newstate(struct ieee80211com *, enum ieee80211_state, int);
|
||||
static void ath_setup_stationkey(struct ieee80211_node *);
|
||||
static void ath_newassoc(struct ieee80211com *,
|
||||
struct ieee80211_node *, int);
|
||||
static int ath_getchannels(struct ath_softc *, u_int cc,
|
||||
|
@ -298,7 +300,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
|||
{
|
||||
struct ifnet *ifp = &sc->sc_if;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ath_hal *ah;
|
||||
struct ath_hal *ah = NULL;
|
||||
HAL_STATUS status;
|
||||
int error = 0, i;
|
||||
|
||||
|
@ -344,11 +346,10 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
|||
* Get the hardware key cache size.
|
||||
*/
|
||||
sc->sc_keymax = ath_hal_keycachesize(ah);
|
||||
if (sc->sc_keymax > sizeof(sc->sc_keymap) * NBBY) {
|
||||
if_printf(ifp,
|
||||
"Warning, using only %zu of %u key cache slots\n",
|
||||
sizeof(sc->sc_keymap) * NBBY, sc->sc_keymax);
|
||||
sc->sc_keymax = sizeof(sc->sc_keymap) * NBBY;
|
||||
if (sc->sc_keymax > ATH_KEYMAX) {
|
||||
if_printf(ifp, "Warning, using only %u of %u key cache slots\n",
|
||||
ATH_KEYMAX, sc->sc_keymax);
|
||||
sc->sc_keymax = ATH_KEYMAX;
|
||||
}
|
||||
/*
|
||||
* Reset the key cache since some parts do not
|
||||
|
@ -512,7 +513,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
|||
ifp->if_start = ath_start;
|
||||
ifp->if_watchdog = ath_watchdog;
|
||||
ifp->if_ioctl = ath_ioctl;
|
||||
ifp->if_init = ath_init;
|
||||
ifp->if_init = ath_ifinit;
|
||||
IFQ_SET_READY(&ifp->if_snd);
|
||||
|
||||
ic->ic_ifp = ifp;
|
||||
|
@ -554,6 +555,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
|||
if (ath_hal_tkipsplit(ah))
|
||||
sc->sc_splitmic = 1;
|
||||
}
|
||||
sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR);
|
||||
sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah);
|
||||
/*
|
||||
* TPC support can be done either with a global cap or
|
||||
* per-packet support. The latter is not available on
|
||||
|
@ -571,7 +574,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
|
|||
if (sc->sc_ac2q[WME_AC_BE] != sc->sc_ac2q[WME_AC_BK])
|
||||
ic->ic_caps |= IEEE80211_C_WME;
|
||||
/*
|
||||
* Check for frame bursting capability.
|
||||
* Check for misc other capabilities.
|
||||
*/
|
||||
if (ath_hal_hasbursting(ah))
|
||||
ic->ic_caps |= IEEE80211_C_BURST;
|
||||
|
@ -741,7 +744,7 @@ ath_resume(struct ath_softc *sc, int why)
|
|||
__func__, ifp->if_flags);
|
||||
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
ath_init(ifp);
|
||||
ath_init(sc);
|
||||
#if 0
|
||||
(void)ath_intr(sc);
|
||||
#endif
|
||||
|
@ -750,6 +753,10 @@ ath_resume(struct ath_softc *sc, int why)
|
|||
if (ifp->if_flags & IFF_RUNNING)
|
||||
ath_start(ifp);
|
||||
}
|
||||
if (sc->sc_softled) {
|
||||
ath_hal_gpioCfgOutput(sc->sc_ah, sc->sc_ledpin);
|
||||
ath_hal_gpioset(sc->sc_ah, sc->sc_ledpin, !sc->sc_ledon);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -926,9 +933,17 @@ ath_chan2flags(struct ieee80211com *ic, struct ieee80211_channel *chan)
|
|||
}
|
||||
|
||||
static int
|
||||
ath_init(struct ifnet *ifp)
|
||||
ath_ifinit(struct ifnet *ifp)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *)ifp->if_softc;
|
||||
|
||||
return ath_init(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
ath_init(struct ath_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp = &sc->sc_if;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_node *ni;
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
|
@ -978,7 +993,6 @@ ath_init(struct ifnet *ifp)
|
|||
* in the frame output path; there's nothing to do
|
||||
* here except setup the interrupt mask.
|
||||
*/
|
||||
ath_initkeytable(sc); /* XXX still needed? */
|
||||
if ((error = ath_startrecv(sc)) != 0) {
|
||||
if_printf(ifp, "unable to start recv logic\n");
|
||||
goto done;
|
||||
|
@ -1306,7 +1320,7 @@ ath_media_change(struct ifnet *ifp)
|
|||
error = ieee80211_media_change(ifp);
|
||||
if (error == ENETRESET) {
|
||||
if (IS_UP(ifp))
|
||||
ath_init(ifp); /* XXX lose error */
|
||||
ath_init(ifp->if_softc); /* XXX lose error */
|
||||
error = 0;
|
||||
}
|
||||
return error;
|
||||
|
@ -1376,14 +1390,11 @@ ath_keyset_tkip(struct ath_softc *sc, const struct ieee80211_key *k,
|
|||
* TX/RX key goes at first index.
|
||||
* The hal handles the MIC keys are index+64.
|
||||
*/
|
||||
KASSERT(k->wk_keyix < IEEE80211_WEP_NKID,
|
||||
("group key at index %u", k->wk_keyix));
|
||||
memcpy(hk->kv_mic, k->wk_flags & IEEE80211_KEY_XMIT ?
|
||||
k->wk_txmic : k->wk_rxmic, sizeof(hk->kv_mic));
|
||||
KEYPRINTF(sc, k->wk_keyix, hk, zerobssid);
|
||||
return ath_hal_keyset(ah, k->wk_keyix, hk, zerobssid);
|
||||
KEYPRINTF(sc, k->wk_keyix, hk, mac);
|
||||
return ath_hal_keyset(ah, k->wk_keyix, hk, mac);
|
||||
}
|
||||
/* XXX key w/o xmit/recv; need this for compression? */
|
||||
return 0;
|
||||
#undef IEEE80211_KEY_XR
|
||||
}
|
||||
|
@ -1395,7 +1406,8 @@ ath_keyset_tkip(struct ath_softc *sc, const struct ieee80211_key *k,
|
|||
*/
|
||||
static int
|
||||
ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k,
|
||||
const u_int8_t mac[IEEE80211_ADDR_LEN])
|
||||
const u_int8_t mac0[IEEE80211_ADDR_LEN],
|
||||
struct ieee80211_node *bss)
|
||||
{
|
||||
#define N(a) (sizeof(a)/sizeof(a[0]))
|
||||
static const u_int8_t ciphermap[] = {
|
||||
|
@ -1409,6 +1421,8 @@ ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k,
|
|||
};
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
const struct ieee80211_cipher *cip = k->wk_cipher;
|
||||
u_int8_t gmac[IEEE80211_ADDR_LEN];
|
||||
const u_int8_t *mac;
|
||||
HAL_KEYVAL hk;
|
||||
|
||||
memset(&hk, 0, sizeof(hk));
|
||||
|
@ -1426,6 +1440,18 @@ ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k,
|
|||
} else
|
||||
hk.kv_type = HAL_CIPHER_CLR;
|
||||
|
||||
if ((k->wk_flags & IEEE80211_KEY_GROUP) && sc->sc_mcastkey) {
|
||||
/*
|
||||
* Group keys on hardware that supports multicast frame
|
||||
* key search use a mac that is the sender's address with
|
||||
* the high bit set instead of the app-specified address.
|
||||
*/
|
||||
IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr);
|
||||
gmac[0] |= 0x80;
|
||||
mac = gmac;
|
||||
} else
|
||||
mac = mac0;
|
||||
|
||||
if (hk.kv_type == HAL_CIPHER_TKIP &&
|
||||
(k->wk_flags & IEEE80211_KEY_SWMIC) == 0 &&
|
||||
sc->sc_splitmic) {
|
||||
|
@ -1437,36 +1463,6 @@ ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k,
|
|||
#undef N
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the hardware key cache with key entries.
|
||||
*/
|
||||
static void
|
||||
ath_initkeytable(struct ath_softc *sc)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ifnet *ifp = &sc->sc_if;
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
const u_int8_t *bssid;
|
||||
int i;
|
||||
|
||||
/* XXX maybe should reset all keys when !PRIVACY */
|
||||
if (ic->ic_state == IEEE80211_S_SCAN)
|
||||
bssid = ifp->if_broadcastaddr;
|
||||
else
|
||||
bssid = ic->ic_bss->ni_bssid;
|
||||
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
|
||||
struct ieee80211_key *k = &ic->ic_nw_keys[i];
|
||||
|
||||
if (k->wk_keylen == 0) {
|
||||
ath_hal_keyreset(ah, i);
|
||||
DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: reset key %u\n",
|
||||
__func__, i);
|
||||
} else {
|
||||
ath_keyset(sc, k, bssid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate tx/rx key slots for TKIP. We allocate two slots for
|
||||
* each key, one for decrypt/encrypt and the other for the MIC.
|
||||
|
@ -1619,17 +1615,32 @@ ath_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
|
|||
struct ath_softc *sc = ic->ic_ifp->if_softc;
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
const struct ieee80211_cipher *cip = k->wk_cipher;
|
||||
struct ieee80211_node *ni;
|
||||
u_int keyix = k->wk_keyix;
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: delete key %u\n", __func__, keyix);
|
||||
|
||||
ath_hal_keyreset(ah, keyix);
|
||||
/*
|
||||
* Check the key->node map and flush any ref.
|
||||
*/
|
||||
ni = sc->sc_keyixmap[keyix];
|
||||
if (ni != NULL) {
|
||||
ieee80211_free_node(ni);
|
||||
sc->sc_keyixmap[keyix] = NULL;
|
||||
}
|
||||
/*
|
||||
* Handle split tx/rx keying required for TKIP with h/w MIC.
|
||||
*/
|
||||
if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
|
||||
(k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic)
|
||||
(k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic) {
|
||||
ath_hal_keyreset(ah, keyix+32); /* RX key */
|
||||
ni = sc->sc_keyixmap[keyix+32];
|
||||
if (ni != NULL) { /* as above... */
|
||||
ieee80211_free_node(ni);
|
||||
sc->sc_keyixmap[keyix+32] = NULL;
|
||||
}
|
||||
}
|
||||
if (keyix >= IEEE80211_WEP_NKID) {
|
||||
/*
|
||||
* Don't touch keymap entries for global keys so
|
||||
|
@ -1657,7 +1668,7 @@ ath_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
|
|||
{
|
||||
struct ath_softc *sc = ic->ic_ifp->if_softc;
|
||||
|
||||
return ath_keyset(sc, k, mac);
|
||||
return ath_keyset(sc, k, mac, ic->ic_bss);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1857,10 +1868,52 @@ ath_beaconq_setup(struct ath_hal *ah)
|
|||
qi.tqi_aifs = HAL_TXQ_USEDEFAULT;
|
||||
qi.tqi_cwmin = HAL_TXQ_USEDEFAULT;
|
||||
qi.tqi_cwmax = HAL_TXQ_USEDEFAULT;
|
||||
/* NB: don't enable any interrupts */
|
||||
/* NB: for dynamic turbo, don't enable any other interrupts */
|
||||
qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
|
||||
return ath_hal_setuptxqueue(ah, HAL_TX_QUEUE_BEACON, &qi);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the transmit queue parameters for the beacon queue.
|
||||
*/
|
||||
static int
|
||||
ath_beaconq_config(struct ath_softc *sc)
|
||||
{
|
||||
#define ATH_EXPONENT_TO_VALUE(v) ((1<<(v))-1)
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
HAL_TXQ_INFO qi;
|
||||
|
||||
ath_hal_gettxqueueprops(ah, sc->sc_bhalq, &qi);
|
||||
if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
|
||||
/*
|
||||
* Always burst out beacon and CAB traffic.
|
||||
*/
|
||||
qi.tqi_aifs = ATH_BEACON_AIFS_DEFAULT;
|
||||
qi.tqi_cwmin = ATH_BEACON_CWMIN_DEFAULT;
|
||||
qi.tqi_cwmax = ATH_BEACON_CWMAX_DEFAULT;
|
||||
} else {
|
||||
struct wmeParams *wmep =
|
||||
&ic->ic_wme.wme_chanParams.cap_wmeParams[WME_AC_BE];
|
||||
/*
|
||||
* Adhoc mode; important thing is to use 2x cwmin.
|
||||
*/
|
||||
qi.tqi_aifs = wmep->wmep_aifsn;
|
||||
qi.tqi_cwmin = 2*ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
|
||||
qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);
|
||||
}
|
||||
|
||||
if (!ath_hal_settxqueueprops(ah, sc->sc_bhalq, &qi)) {
|
||||
device_printf(sc->sc_dev, "unable to update parameters for "
|
||||
"beacon hardware queue!\n");
|
||||
return 0;
|
||||
} else {
|
||||
ath_hal_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
|
||||
return 1;
|
||||
}
|
||||
#undef ATH_EXPONENT_TO_VALUE
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and setup an initial beacon frame.
|
||||
*/
|
||||
|
@ -2156,13 +2209,16 @@ ath_beacon_free(struct ath_softc *sc)
|
|||
static void
|
||||
ath_beacon_config(struct ath_softc *sc)
|
||||
{
|
||||
#define TSF_TO_TU(_h,_l) (((_h) << 22) | ((_l) >> 10))
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_node *ni = ic->ic_bss;
|
||||
u_int32_t nexttbtt, intval;
|
||||
|
||||
nexttbtt = (LE_READ_4(ni->ni_tstamp.data + 4) << 22) |
|
||||
(LE_READ_4(ni->ni_tstamp.data) >> 10);
|
||||
/* extract tstamp from last beacon and convert to TU */
|
||||
nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4),
|
||||
LE_READ_4(ni->ni_tstamp.data));
|
||||
/* NB: the beacon interval is kept internally in TU's */
|
||||
intval = ni->ni_intval & HAL_BEACON_PERIOD;
|
||||
if (nexttbtt == 0) /* e.g. for ap mode */
|
||||
nexttbtt = intval;
|
||||
|
@ -2172,21 +2228,59 @@ ath_beacon_config(struct ath_softc *sc)
|
|||
__func__, nexttbtt, intval, ni->ni_intval);
|
||||
if (ic->ic_opmode == IEEE80211_M_STA) {
|
||||
HAL_BEACON_STATE bs;
|
||||
u_int64_t tsf;
|
||||
u_int32_t tsftu;
|
||||
int dtimperiod, dtimcount;
|
||||
int cfpperiod, cfpcount;
|
||||
|
||||
/* NB: no PCF support right now */
|
||||
/*
|
||||
* Setup dtim and cfp parameters according to
|
||||
* last beacon we received (which may be none).
|
||||
*/
|
||||
dtimperiod = ni->ni_dtim_period;
|
||||
if (dtimperiod <= 0) /* NB: 0 if not known */
|
||||
dtimperiod = 1;
|
||||
dtimcount = ni->ni_dtim_count;
|
||||
if (dtimcount >= dtimperiod) /* NB: sanity check */
|
||||
dtimcount = 0; /* XXX? */
|
||||
cfpperiod = 1; /* NB: no PCF support yet */
|
||||
cfpcount = 0;
|
||||
#define FUDGE 2
|
||||
/*
|
||||
* Pull nexttbtt forward to reflect the current
|
||||
* TSF and calculate dtim+cfp state for the result.
|
||||
*/
|
||||
tsf = ath_hal_gettsf64(ah);
|
||||
tsftu = TSF_TO_TU((u_int32_t)(tsf>>32), (u_int32_t)tsf) + FUDGE;
|
||||
do {
|
||||
nexttbtt += intval;
|
||||
if (--dtimcount < 0) {
|
||||
dtimcount = dtimperiod - 1;
|
||||
if (--cfpcount < 0)
|
||||
cfpcount = cfpperiod - 1;
|
||||
}
|
||||
} while (nexttbtt < tsftu);
|
||||
#undef FUDGE
|
||||
memset(&bs, 0, sizeof(bs));
|
||||
bs.bs_intval = intval;
|
||||
bs.bs_nexttbtt = nexttbtt;
|
||||
bs.bs_dtimperiod = bs.bs_intval;
|
||||
bs.bs_nextdtim = nexttbtt;
|
||||
bs.bs_dtimperiod = dtimperiod*intval;
|
||||
bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
|
||||
bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
|
||||
bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
|
||||
bs.bs_cfpmaxduration = 0;
|
||||
#if 0
|
||||
/*
|
||||
* The 802.11 layer records the offset to the DTIM
|
||||
* bitmap while receiving beacons; use it here to
|
||||
* enable h/w detection of our AID being marked in
|
||||
* the bitmap vector (to indicate frames for us are
|
||||
* pending at the AP).
|
||||
* XXX do DTIM handling in s/w to WAR old h/w bugs
|
||||
* XXX enable based on h/w rev for newer chips
|
||||
*/
|
||||
bs.bs_timoffset = ni->ni_timoff;
|
||||
#endif
|
||||
/*
|
||||
* Calculate the number of consecutive beacons to miss
|
||||
* before taking a BMISS interrupt. The configuration
|
||||
|
@ -2215,8 +2309,9 @@ ath_beacon_config(struct ath_softc *sc)
|
|||
bs.bs_sleepduration = roundup(bs.bs_sleepduration, bs.bs_dtimperiod);
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"%s: intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u sleep %u cfp:period %u maxdur %u next %u timoffset %u\n"
|
||||
"%s: tsf %ju tsf:tu %u intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u sleep %u cfp:period %u maxdur %u next %u timoffset %u\n"
|
||||
, __func__
|
||||
, tsf, tsftu
|
||||
, bs.bs_intval
|
||||
, bs.bs_nexttbtt
|
||||
, bs.bs_dtimperiod
|
||||
|
@ -2247,6 +2342,7 @@ ath_beacon_config(struct ath_softc *sc)
|
|||
intval |= HAL_BEACON_ENA;
|
||||
if (!sc->sc_hasveol)
|
||||
sc->sc_imask |= HAL_INT_SWBA;
|
||||
ath_beaconq_config(sc);
|
||||
} else if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
|
||||
/*
|
||||
* In AP mode we enable the beacon timers and
|
||||
|
@ -2254,6 +2350,7 @@ ath_beacon_config(struct ath_softc *sc)
|
|||
*/
|
||||
intval |= HAL_BEACON_ENA;
|
||||
sc->sc_imask |= HAL_INT_SWBA; /* beacon prepare */
|
||||
ath_beaconq_config(sc);
|
||||
}
|
||||
ath_hal_beaconinit(ah, nexttbtt, intval);
|
||||
sc->sc_bmisscount = 0;
|
||||
|
@ -2265,6 +2362,7 @@ ath_beacon_config(struct ath_softc *sc)
|
|||
if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol)
|
||||
ath_beacon_proc(sc, 0);
|
||||
}
|
||||
#undef TSF_TO_TU
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2867,16 +2965,51 @@ rx_accept:
|
|||
/*
|
||||
* Locate the node for sender, track state, and then
|
||||
* pass the (referenced) node up to the 802.11 layer
|
||||
* for its use.
|
||||
* for its use. If the sender is unknown spam the
|
||||
* frame; it'll be dropped where it's not wanted.
|
||||
*/
|
||||
ni = ieee80211_find_rxnode(ic,
|
||||
mtod(m, const struct ieee80211_frame_min *));
|
||||
|
||||
/*
|
||||
* Track rx rssi and do any rx antenna management.
|
||||
*/
|
||||
an = ATH_NODE(ni);
|
||||
ATH_RSSI_LPF(an->an_avgrssi, ds->ds_rxstat.rs_rssi);
|
||||
if (ds->ds_rxstat.rs_keyix != HAL_RXKEYIX_INVALID &&
|
||||
(ni = sc->sc_keyixmap[ds->ds_rxstat.rs_keyix]) != NULL) {
|
||||
/*
|
||||
* Fast path: node is present in the key map;
|
||||
* grab a reference for processing the frame.
|
||||
*/
|
||||
an = ATH_NODE(ieee80211_ref_node(ni));
|
||||
ATH_RSSI_LPF(an->an_avgrssi, ds->ds_rxstat.rs_rssi);
|
||||
type = ieee80211_input(ic, m, ni,
|
||||
ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
|
||||
} else {
|
||||
/*
|
||||
* Locate the node for sender, track state, and then
|
||||
* pass the (referenced) node up to the 802.11 layer
|
||||
* for its use.
|
||||
*/
|
||||
ni = ieee80211_find_rxnode(ic,
|
||||
mtod(m, const struct ieee80211_frame_min *));
|
||||
/*
|
||||
* Track rx rssi and do any rx antenna management.
|
||||
*/
|
||||
an = ATH_NODE(ni);
|
||||
ATH_RSSI_LPF(an->an_avgrssi, ds->ds_rxstat.rs_rssi);
|
||||
/*
|
||||
* Send frame up for processing.
|
||||
*/
|
||||
type = ieee80211_input(ic, m, ni,
|
||||
ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
|
||||
if (ni != ic->ic_bss) {
|
||||
u_int16_t keyix;
|
||||
/*
|
||||
* If the station has a key cache slot assigned
|
||||
* update the key->node mapping table.
|
||||
*/
|
||||
keyix = ni->ni_ucastkey.wk_keyix;
|
||||
if (keyix != IEEE80211_KEYIX_NONE &&
|
||||
sc->sc_keyixmap[keyix] == NULL)
|
||||
sc->sc_keyixmap[keyix] =
|
||||
ieee80211_ref_node(ni);
|
||||
}
|
||||
}
|
||||
ieee80211_free_node(ni);
|
||||
if (sc->sc_diversity) {
|
||||
/*
|
||||
* When using fast diversity, change the default rx
|
||||
|
@ -2890,13 +3023,6 @@ rx_accept:
|
|||
} else
|
||||
sc->sc_rxotherant = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send frame up for processing.
|
||||
*/
|
||||
type = ieee80211_input(ic, m, ni,
|
||||
ds->ds_rxstat.rs_rssi, ds->ds_rxstat.rs_tstamp);
|
||||
|
||||
if (sc->sc_softled) {
|
||||
/*
|
||||
* Blink for any data frame. Otherwise do a
|
||||
|
@ -2910,11 +3036,6 @@ rx_accept:
|
|||
} else if (ticks - sc->sc_ledevent >= sc->sc_ledidle)
|
||||
ath_led_event(sc, ATH_LED_POLL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim node reference.
|
||||
*/
|
||||
ieee80211_free_node(ni);
|
||||
rx_next:
|
||||
STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
|
||||
} while (ath_rxbuf_init(sc, bf) == 0);
|
||||
|
@ -2964,7 +3085,7 @@ ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
|||
qnum = ath_hal_setuptxqueue(ah, qtype, &qi);
|
||||
if (qnum == -1) {
|
||||
/*
|
||||
* NB: don't print a message, this happens
|
||||
* NB: don't print a message, this happens
|
||||
* normally on parts with too few tx queues
|
||||
*/
|
||||
return NULL;
|
||||
|
@ -3056,7 +3177,7 @@ ath_txq_update(struct ath_softc *sc, int ac)
|
|||
/*
|
||||
* Callback from the 802.11 layer to update WME parameters.
|
||||
*/
|
||||
static int
|
||||
static int
|
||||
ath_wme_update(struct ieee80211com *ic)
|
||||
{
|
||||
struct ath_softc *sc = ic->ic_ifp->if_softc;
|
||||
|
@ -3253,6 +3374,13 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
|
|||
|
||||
/* packet header may have moved, reset our local pointer */
|
||||
wh = mtod(m0, struct ieee80211_frame *);
|
||||
} else if (ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) {
|
||||
/*
|
||||
* Use station key cache slot, if assigned.
|
||||
*/
|
||||
keyix = ni->ni_ucastkey.wk_keyix;
|
||||
if (keyix == IEEE80211_KEYIX_NONE)
|
||||
keyix = HAL_TXKEYIX_INVALID;
|
||||
} else
|
||||
keyix = HAL_TXKEYIX_INVALID;
|
||||
|
||||
|
@ -3565,6 +3693,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf
|
|||
, ctsrate /* rts/cts rate */
|
||||
, ctsduration /* rts/cts duration */
|
||||
);
|
||||
bf->bf_flags = flags;
|
||||
/*
|
||||
* Setup the multi-rate retry state only when we're
|
||||
* going to use it. This assumes ath_hal_setuptxdesc
|
||||
|
@ -3740,7 +3869,9 @@ ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
|||
/*
|
||||
* Hand the descriptor to the rate control algorithm.
|
||||
*/
|
||||
ath_rate_tx_complete(sc, an, ds, ds0);
|
||||
if ((ds->ds_txstat.ts_status & HAL_TXERR_FILT) == 0 &&
|
||||
(bf->bf_flags & HAL_TXDESC_NOACK) == 0)
|
||||
ath_rate_tx_complete(sc, an, ds, ds0);
|
||||
/*
|
||||
* Reclaim reference to node.
|
||||
*
|
||||
|
@ -4174,7 +4305,7 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
|||
/*
|
||||
* NB: disable interrupts so we don't rx frames.
|
||||
*/
|
||||
ath_hal_intrset(ah, sc->sc_imask &~ ~HAL_INT_GLOBAL);
|
||||
ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL);
|
||||
/*
|
||||
* Notify the rate control algorithm.
|
||||
*/
|
||||
|
@ -4223,12 +4354,12 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
|||
, ni->ni_capinfo
|
||||
, ieee80211_chan2ieee(ic, ni->ni_chan));
|
||||
|
||||
/*
|
||||
* Allocate and setup the beacon frame for AP or adhoc mode.
|
||||
*/
|
||||
if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
|
||||
ic->ic_opmode == IEEE80211_M_IBSS) {
|
||||
switch (ic->ic_opmode) {
|
||||
case IEEE80211_M_HOSTAP:
|
||||
case IEEE80211_M_IBSS:
|
||||
/*
|
||||
* Allocate and setup the beacon frame.
|
||||
*
|
||||
* Stop any previous beacon DMA. This may be
|
||||
* necessary, for example, when an ibss merge
|
||||
* causes reconfiguration; there will be a state
|
||||
|
@ -4240,6 +4371,18 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
|||
error = ath_beacon_alloc(sc, ni);
|
||||
if (error != 0)
|
||||
goto bad;
|
||||
break;
|
||||
case IEEE80211_M_STA:
|
||||
/*
|
||||
* Allocate a key cache slot to the station.
|
||||
*/
|
||||
if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0 &&
|
||||
sc->sc_hasclrkey &&
|
||||
ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE)
|
||||
ath_setup_stationkey(ni);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4272,6 +4415,36 @@ bad:
|
|||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a key cache slot to the station so we can
|
||||
* setup a mapping from key index to node. The key cache
|
||||
* slot is needed for managing antenna state and for
|
||||
* compression when stations do not use crypto. We do
|
||||
* it uniliaterally here; if crypto is employed this slot
|
||||
* will be reassigned.
|
||||
*/
|
||||
static void
|
||||
ath_setup_stationkey(struct ieee80211_node *ni)
|
||||
{
|
||||
struct ieee80211com *ic = ni->ni_ic;
|
||||
struct ath_softc *sc = ic->ic_ifp->if_softc;
|
||||
u_int16_t keyix;
|
||||
|
||||
keyix = ath_key_alloc(ic, &ni->ni_ucastkey);
|
||||
if (keyix == IEEE80211_KEYIX_NONE) {
|
||||
/*
|
||||
* Key cache is full; we'll fall back to doing
|
||||
* the more expensive lookup in software. Note
|
||||
* this also means no h/w compression.
|
||||
*/
|
||||
/* XXX msg+statistic */
|
||||
} else {
|
||||
ni->ni_ucastkey.wk_keyix = keyix;
|
||||
/* NB: this will create a pass-thru key entry */
|
||||
ath_keyset(sc, &ni->ni_ucastkey, ni->ni_macaddr, ic->ic_bss);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup driver-specific state for a newly associated node.
|
||||
* Note that we're called also on a re-associate, the isnew
|
||||
|
@ -4283,6 +4456,13 @@ ath_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
|
|||
struct ath_softc *sc = ic->ic_ifp->if_softc;
|
||||
|
||||
ath_rate_newassoc(sc, ATH_NODE(ni), isnew);
|
||||
if (isnew &&
|
||||
(ic->ic_flags & IEEE80211_F_PRIVACY) == 0 && sc->sc_hasclrkey) {
|
||||
KASSERT(ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE,
|
||||
("new assoc with a unicast key already setup (keyix %u)",
|
||||
ni->ni_ucastkey.wk_keyix));
|
||||
ath_setup_stationkey(ni);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -4683,7 +4863,7 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
* probably a better way to deal with this.
|
||||
*/
|
||||
if (!sc->sc_invalid && ic->ic_bss != NULL)
|
||||
ath_init(ifp); /* XXX lose error */
|
||||
ath_init(sc); /* XXX lose error */
|
||||
} else
|
||||
ath_stop_locked(ifp, 1);
|
||||
break;
|
||||
|
@ -4720,7 +4900,7 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
if (error == ENETRESET) {
|
||||
if (IS_RUNNING(ifp) &&
|
||||
ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
|
||||
ath_init(ifp); /* XXX lose error */
|
||||
ath_init(sc); /* XXX lose error */
|
||||
error = 0;
|
||||
}
|
||||
if (error == ERESTART)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: athioctl.h,v 1.8 2005/06/30 00:52:56 dyoung Exp $ */
|
||||
/* $NetBSD: athioctl.h,v 1.9 2005/07/26 22:52:48 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/amrr/amrr.c,v 1.7 2005/04/02 18:54:30 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/amrr/amrr.c,v 1.8 2005/06/10 16:49:04 brooks Exp $");
|
||||
|
||||
/*
|
||||
* AMRR rate control. See:
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.c,v 1.7 2005/04/02 18:54:30 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.c,v 1.8 2005/06/10 16:49:04 brooks Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: athrate-onoe.c,v 1.4 2005/06/30 00:52:56 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: athrate-onoe.c,v 1.5 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: athvar.h,v 1.12 2005/06/30 00:52:56 dyoung Exp $ */
|
||||
/* $NetBSD: athvar.h,v 1.13 2005/07/26 22:52:48 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
|
||||
|
@ -35,7 +35,7 @@
|
|||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*
|
||||
* $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.23 2005/04/12 17:56:43 sam Exp $
|
||||
* $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.27 2005/07/07 00:04:50 sam Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -58,6 +58,21 @@
|
|||
#define ATH_TXMAXTRY 11 /* max number of transmit attempts */
|
||||
#define ATH_TXINTR_PERIOD 5 /* max number of batched tx descriptors */
|
||||
|
||||
#define ATH_BEACON_AIFS_DEFAULT 0 /* default aifs for ap beacon q */
|
||||
#define ATH_BEACON_CWMIN_DEFAULT 0 /* default cwmin for ap beacon q */
|
||||
#define ATH_BEACON_CWMAX_DEFAULT 0 /* default cwmax for ap beacon q */
|
||||
|
||||
/*
|
||||
* The key cache is used for h/w cipher state and also for
|
||||
* tracking station state such as the current tx antenna.
|
||||
* We also setup a mapping table between key cache slot indices
|
||||
* and station state to short-circuit node lookups on rx.
|
||||
* Different parts have different size key caches. We handle
|
||||
* up to ATH_KEYMAX entries (could dynamically allocate state).
|
||||
*/
|
||||
#define ATH_KEYMAX 128 /* max key cache size we handle */
|
||||
#define ATH_KEYBYTES (ATH_KEYMAX/NBBY) /* storage space in bytes */
|
||||
|
||||
/* driver-specific node state */
|
||||
struct ath_node {
|
||||
struct ieee80211_node an_node; /* base class */
|
||||
|
@ -84,6 +99,7 @@ struct ath_node {
|
|||
struct ath_buf {
|
||||
STAILQ_ENTRY(ath_buf) bf_list;
|
||||
#define bf_nseg bf_dmamap->dm_nsegs
|
||||
int bf_flags; /* tx descriptor flags */
|
||||
struct ath_desc *bf_desc; /* virtual addr of desc */
|
||||
bus_addr_t bf_daddr; /* physical addr of desc */
|
||||
bus_dmamap_t bf_dmamap; /* DMA map for mbuf chain */
|
||||
|
@ -176,7 +192,7 @@ struct ath_softc {
|
|||
struct ath_hal *sc_ah; /* Atheros HAL */
|
||||
struct ath_ratectrl *sc_rc; /* tx rate control support */
|
||||
void (*sc_setdefantenna)(struct ath_softc *, u_int);
|
||||
unsigned int sc_invalid : 1,/* disable hardware accesses */
|
||||
unsigned int sc_invalid : 1, /* disable hardware accesses */
|
||||
sc_mrretry : 1, /* multi-rate retry support */
|
||||
sc_softled : 1, /* enable LED gpio status */
|
||||
sc_splitmic: 1, /* split TKIP MIC keys */
|
||||
|
@ -187,7 +203,8 @@ struct ath_softc {
|
|||
sc_hastpc : 1, /* per-packet TPC support */
|
||||
sc_ledstate: 1, /* LED on/off state */
|
||||
sc_blinking: 1, /* LED blink operation active */
|
||||
sc_mcastkey: 1; /* mcast key cache search */
|
||||
sc_mcastkey: 1, /* mcast key cache search */
|
||||
sc_hasclrkey:1; /* CLR key supported */
|
||||
/* rate tables */
|
||||
const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
|
||||
const HAL_RATE_TABLE *sc_currates; /* current rate table */
|
||||
|
@ -206,7 +223,8 @@ struct ath_softc {
|
|||
u_int sc_txantenna; /* tx antenna (fixed or auto) */
|
||||
HAL_INT sc_imask; /* interrupt mask copy */
|
||||
u_int sc_keymax; /* size of key cache */
|
||||
u_int8_t sc_keymap[16]; /* bit map of key cache use */
|
||||
u_int8_t sc_keymap[ATH_KEYBYTES];/* key use bit map */
|
||||
struct ieee80211_node *sc_keyixmap[ATH_KEYMAX];/* key ix->node map */
|
||||
|
||||
u_int sc_ledpin; /* GPIO pin for driving LED */
|
||||
u_int sc_ledon; /* pin setting for LED on */
|
||||
|
@ -472,6 +490,14 @@ extern int ath_debug;
|
|||
ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL)
|
||||
#define ath_hal_hasbursting(_ah) \
|
||||
(ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK)
|
||||
#ifdef notyet
|
||||
#define ath_hal_hasmcastkeysearch(_ah) \
|
||||
(ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, NULL) == HAL_OK)
|
||||
#define ath_hal_getmcastkeysearch(_ah) \
|
||||
(ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 1, NULL) == HAL_OK)
|
||||
#else
|
||||
#define ath_hal_getmcastkeysearch(_ah) 0
|
||||
#endif
|
||||
|
||||
#define ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
|
||||
((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ieee80211.c,v 1.39 2005/07/11 17:15:30 dyoung Exp $ */
|
||||
/* $NetBSD: ieee80211.c,v 1.40 2005/07/26 22:52:48 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2001 Atsushi Onoe
|
||||
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
|
||||
|
@ -36,7 +36,7 @@
|
|||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211.c,v 1.19 2005/01/27 17:39:17 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.39 2005/07/11 17:15:30 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.40 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ieee80211.h,v 1.13 2005/06/22 06:16:02 dyoung Exp $ */
|
||||
/* $NetBSD: ieee80211.h,v 1.14 2005/07/26 22:52:48 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2001 Atsushi Onoe
|
||||
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
|
||||
|
@ -30,7 +30,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/net80211/ieee80211.h,v 1.8 2004/12/31 22:44:26 sam Exp $
|
||||
* $FreeBSD: src/sys/net80211/ieee80211.h,v 1.9 2005/06/10 04:42:34 sam Exp $
|
||||
*/
|
||||
#ifndef _NET80211_IEEE80211_H_
|
||||
#define _NET80211_IEEE80211_H_
|
||||
|
@ -623,12 +623,6 @@ enum {
|
|||
#define IEEE80211_AID_DEF 128
|
||||
|
||||
#define IEEE80211_AID(b) ((b) &~ 0xc000)
|
||||
#define IEEE80211_AID_SET(b, w) \
|
||||
((w)[IEEE80211_AID(b) / 32] |= (1 << (IEEE80211_AID(b) % 32)))
|
||||
#define IEEE80211_AID_CLR(b, w) \
|
||||
((w)[IEEE80211_AID(b) / 32] &= ~(1 << (IEEE80211_AID(b) % 32)))
|
||||
#define IEEE80211_AID_ISSET(b, w) \
|
||||
((w)[IEEE80211_AID(b) / 32] & (1 << (IEEE80211_AID(b) % 32)))
|
||||
|
||||
/*
|
||||
* RTS frame length parameters. The default is specified in
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_acl.c,v 1.3 2004/12/31 22:42:38 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_acl.c,v 1.2 2005/06/22 06:16:02 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_acl.c,v 1.3 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ieee80211_crypto.c,v 1.8 2005/07/06 23:44:15 dyoung Exp $ */
|
||||
/* $NetBSD: ieee80211_crypto.c,v 1.9 2005/07/26 22:52:48 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2001 Atsushi Onoe
|
||||
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
|
||||
|
@ -33,10 +33,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto.c,v 1.7 2004/12/31 22:42:38 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto.c,v 1.10 2005/07/09 23:15:30 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto.c,v 1.8 2005/07/06 23:44:15 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto.c,v 1.9 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
@ -83,7 +83,24 @@ static int _ieee80211_crypto_delkey(struct ieee80211com *,
|
|||
static int
|
||||
null_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k)
|
||||
{
|
||||
return IEEE80211_KEYIX_NONE;
|
||||
if (!(&ic->ic_nw_keys[0] <= k &&
|
||||
k < &ic->ic_nw_keys[IEEE80211_WEP_NKID])) {
|
||||
/*
|
||||
* Not in the global key table, the driver should handle this
|
||||
* by allocating a slot in the h/w key table/cache. In
|
||||
* lieu of that return key slot 0 for any unicast key
|
||||
* request. We disallow the request if this is a group key.
|
||||
* This default policy does the right thing for legacy hardware
|
||||
* with a 4 key table. It also handles devices that pass
|
||||
* packets through untouched when marked with the WEP bit
|
||||
* and key index 0.
|
||||
*/
|
||||
if ((k->wk_flags & IEEE80211_KEY_GROUP) == 0)
|
||||
return 0; /* NB: use key index 0 for ucast key */
|
||||
else
|
||||
return IEEE80211_KEYIX_NONE;
|
||||
}
|
||||
return k - ic->ic_nw_keys;
|
||||
}
|
||||
static int
|
||||
null_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
|
||||
|
@ -551,7 +568,7 @@ bad:
|
|||
*/
|
||||
struct ieee80211_key *
|
||||
ieee80211_crypto_decap(struct ieee80211com *ic,
|
||||
struct ieee80211_node *ni, struct mbuf *m)
|
||||
struct ieee80211_node *ni, struct mbuf *m, int hdrlen)
|
||||
{
|
||||
#define IEEE80211_WEP_HDRLEN (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
|
||||
#define IEEE80211_WEP_MINLEN \
|
||||
|
@ -562,7 +579,6 @@ ieee80211_crypto_decap(struct ieee80211com *ic,
|
|||
const struct ieee80211_cipher *cip;
|
||||
const u_int8_t *ivp;
|
||||
u_int8_t keyid;
|
||||
int hdrlen;
|
||||
|
||||
/* NB: this minimum size data frame could be bigger */
|
||||
if (m->m_pkthdr.len < IEEE80211_WEP_MINLEN) {
|
||||
|
@ -580,7 +596,6 @@ ieee80211_crypto_decap(struct ieee80211com *ic,
|
|||
* the key id in the header is meaningless (typically 0).
|
||||
*/
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
hdrlen = ieee80211_hdrsize(wh);
|
||||
ivp = mtod(m, const u_int8_t *) + hdrlen; /* XXX contig */
|
||||
keyid = ivp[IEEE80211_WEP_IVLEN];
|
||||
if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
|
||||
|
@ -602,7 +617,7 @@ ieee80211_crypto_decap(struct ieee80211com *ic,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return (cip->ic_decap(k, m) ? k : NULL);
|
||||
return (cip->ic_decap(k, m, hdrlen) ? k : NULL);
|
||||
#undef IEEE80211_WEP_MINLEN
|
||||
#undef IEEE80211_WEP_HDRLEN
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ieee80211_crypto.h,v 1.4 2005/06/26 21:51:37 erh Exp $ */
|
||||
/* $NetBSD: ieee80211_crypto.h,v 1.5 2005/07/26 22:52:48 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2001 Atsushi Onoe
|
||||
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
|
||||
|
@ -31,6 +31,7 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/net80211/ieee80211_crypto.h,v 1.5 2004/12/31 22:44:26 sam Exp $
|
||||
* $FreeBSD: src/sys/net80211/ieee80211_crypto.h,v 1.9 2005/06/10 16:11:24 sam Exp $
|
||||
*/
|
||||
#ifndef _NET80211_IEEE80211_CRYPTO_H_
|
||||
#define _NET80211_IEEE80211_CRYPTO_H_
|
||||
|
@ -162,9 +163,9 @@ struct ieee80211_cipher {
|
|||
int (*ic_setkey)(struct ieee80211_key *);
|
||||
int (*ic_encap)(struct ieee80211_key *, struct mbuf *,
|
||||
u_int8_t keyid);
|
||||
int (*ic_decap)(struct ieee80211_key *, struct mbuf *);
|
||||
int (*ic_enmic)(struct ieee80211_key *, struct mbuf *);
|
||||
int (*ic_demic)(struct ieee80211_key *, struct mbuf *);
|
||||
int (*ic_decap)(struct ieee80211_key *, struct mbuf *, int);
|
||||
int (*ic_enmic)(struct ieee80211_key *, struct mbuf *, int);
|
||||
int (*ic_demic)(struct ieee80211_key *, struct mbuf *, int);
|
||||
};
|
||||
extern const struct ieee80211_cipher ieee80211_cipher_none;
|
||||
extern const struct ieee80211_cipher ieee80211_cipher_wep;
|
||||
|
@ -178,17 +179,17 @@ int ieee80211_crypto_available(u_int cipher);
|
|||
struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211com *,
|
||||
struct ieee80211_node *, struct mbuf *);
|
||||
struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211com *,
|
||||
struct ieee80211_node *, struct mbuf *);
|
||||
struct ieee80211_node *, struct mbuf *, int);
|
||||
|
||||
/*
|
||||
* Check and remove any MIC.
|
||||
*/
|
||||
static __inline int
|
||||
ieee80211_crypto_demic(struct ieee80211com *ic, struct ieee80211_key *k,
|
||||
struct mbuf *m)
|
||||
struct mbuf *m, int force)
|
||||
{
|
||||
const struct ieee80211_cipher *cip = k->wk_cipher;
|
||||
return (cip->ic_miclen > 0 ? cip->ic_demic(k, m) : 1);
|
||||
return (cip->ic_miclen > 0 ? cip->ic_demic(k, m, force) : 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -196,10 +197,10 @@ ieee80211_crypto_demic(struct ieee80211com *ic, struct ieee80211_key *k,
|
|||
*/
|
||||
static __inline int
|
||||
ieee80211_crypto_enmic(struct ieee80211com *ic,
|
||||
struct ieee80211_key *k, struct mbuf *m)
|
||||
struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
const struct ieee80211_cipher *cip = k->wk_cipher;
|
||||
return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m) : 1);
|
||||
return (cip->ic_miclen > 0 ? cip->ic_enmic(k, m, force) : 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_ccmp.c,v 1.4 2004/12/31 22:42:38 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_ccmp.c,v 1.7 2005/07/11 03:06:23 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_ccmp.c,v 1.2 2005/06/22 06:16:02 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_ccmp.c,v 1.3 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -70,9 +70,9 @@ static void *ccmp_attach(struct ieee80211com *, struct ieee80211_key *);
|
|||
static void ccmp_detach(struct ieee80211_key *);
|
||||
static int ccmp_setkey(struct ieee80211_key *);
|
||||
static int ccmp_encap(struct ieee80211_key *k, struct mbuf *, u_int8_t keyid);
|
||||
static int ccmp_decap(struct ieee80211_key *, struct mbuf *);
|
||||
static int ccmp_enmic(struct ieee80211_key *, struct mbuf *);
|
||||
static int ccmp_demic(struct ieee80211_key *, struct mbuf *);
|
||||
static int ccmp_decap(struct ieee80211_key *, struct mbuf *, int);
|
||||
static int ccmp_enmic(struct ieee80211_key *, struct mbuf *, int);
|
||||
static int ccmp_demic(struct ieee80211_key *, struct mbuf *, int);
|
||||
|
||||
const struct ieee80211_cipher ieee80211_cipher_ccmp = {
|
||||
.ic_name = "AES-CCM",
|
||||
|
@ -182,7 +182,7 @@ ccmp_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid)
|
|||
* Add MIC to the frame as needed.
|
||||
*/
|
||||
static int
|
||||
ccmp_enmic(struct ieee80211_key *k, struct mbuf *m)
|
||||
ccmp_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
|
||||
return 1;
|
||||
|
@ -202,20 +202,18 @@ READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
|
|||
* is also verified.
|
||||
*/
|
||||
static int
|
||||
ccmp_decap(struct ieee80211_key *k, struct mbuf *m)
|
||||
ccmp_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
|
||||
{
|
||||
struct ccmp_ctx *ctx = k->wk_private;
|
||||
struct ieee80211_frame *wh;
|
||||
uint8_t *ivp;
|
||||
uint64_t pn;
|
||||
int hdrlen;
|
||||
|
||||
/*
|
||||
* Header should have extended IV and sequence number;
|
||||
* verify the former and validate the latter.
|
||||
*/
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
hdrlen = ieee80211_hdrsize(wh);
|
||||
ivp = mtod(m, uint8_t *) + hdrlen;
|
||||
if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
|
||||
/*
|
||||
|
@ -267,7 +265,7 @@ ccmp_decap(struct ieee80211_key *k, struct mbuf *m)
|
|||
* Verify and strip MIC from the frame.
|
||||
*/
|
||||
static int
|
||||
ccmp_demic(struct ieee80211_key *k, struct mbuf *m)
|
||||
ccmp_demic(struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -408,11 +406,10 @@ ccmp_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
|
|||
struct ccmp_ctx *ctx = key->wk_private;
|
||||
struct ieee80211_frame *wh;
|
||||
struct mbuf *m = m0;
|
||||
int data_len, i;
|
||||
int data_len, i, space;
|
||||
uint8_t aad[2 * AES_BLOCK_LEN], b0[AES_BLOCK_LEN], b[AES_BLOCK_LEN],
|
||||
e[AES_BLOCK_LEN], s0[AES_BLOCK_LEN];
|
||||
uint8_t *pos;
|
||||
u_int space;
|
||||
|
||||
ctx->cc_ic->ic_stats.is_crypto_ccmp++;
|
||||
|
||||
|
@ -451,27 +448,75 @@ ccmp_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
|
|||
}
|
||||
if (space != 0) {
|
||||
uint8_t *pos_next;
|
||||
u_int space_next;
|
||||
u_int len;
|
||||
int space_next;
|
||||
int len, dl, sp;
|
||||
struct mbuf *n;
|
||||
|
||||
/*
|
||||
* Block straddles buffers, split references. We
|
||||
* do not handle splits that require >2 buffers.
|
||||
* Block straddles one or more mbufs, gather data
|
||||
* into the block buffer b, apply the cipher, then
|
||||
* scatter the results back into the mbuf chain.
|
||||
* The buffer will automatically get space bytes
|
||||
* of data at offset 0 copied in+out by the
|
||||
* CCMP_ENCRYPT request so we must take care of
|
||||
* the remaining data.
|
||||
*/
|
||||
pos_next = mtod(m, uint8_t *);
|
||||
len = min(data_len, AES_BLOCK_LEN);
|
||||
space_next = len > space ? len - space : 0;
|
||||
IASSERT(m->m_len >= space_next,
|
||||
("not enough data in following buffer, "
|
||||
"m_len %u need %u\n", m->m_len, space_next));
|
||||
n = m;
|
||||
dl = data_len;
|
||||
sp = space;
|
||||
for (;;) {
|
||||
pos_next = mtod(n, uint8_t *);
|
||||
len = min(dl, AES_BLOCK_LEN);
|
||||
space_next = len > sp ? len - sp : 0;
|
||||
if (n->m_len >= space_next) {
|
||||
/*
|
||||
* This mbuf has enough data; just grab
|
||||
* what we need and stop.
|
||||
*/
|
||||
xor_block(b+sp, pos_next, space_next);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* This mbuf's contents are insufficient,
|
||||
* take 'em all and prepare to advance to
|
||||
* the next mbuf.
|
||||
*/
|
||||
xor_block(b+sp, pos_next, n->m_len);
|
||||
sp += n->m_len, dl -= n->m_len;
|
||||
n = n->m_next;
|
||||
if (n == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
xor_block(b+space, pos_next, space_next);
|
||||
CCMP_ENCRYPT(i, b, b0, pos, e, space);
|
||||
xor_block(pos_next, e+space, space_next);
|
||||
data_len -= len;
|
||||
/* XXX could check for data_len <= 0 */
|
||||
i++;
|
||||
|
||||
/* NB: just like above, but scatter data to mbufs */
|
||||
dl = data_len;
|
||||
sp = space;
|
||||
for (;;) {
|
||||
pos_next = mtod(m, uint8_t *);
|
||||
len = min(dl, AES_BLOCK_LEN);
|
||||
space_next = len > sp ? len - sp : 0;
|
||||
if (m->m_len >= space_next) {
|
||||
xor_block(pos_next, e+sp, space_next);
|
||||
break;
|
||||
}
|
||||
xor_block(pos_next, e+sp, m->m_len);
|
||||
sp += m->m_len, dl -= m->m_len;
|
||||
m = m->m_next;
|
||||
if (m == NULL)
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* Do bookkeeping. m now points to the last mbuf
|
||||
* we grabbed data from. We know we consumed a
|
||||
* full block of data as otherwise we'd have hit
|
||||
* the end of the mbuf chain, so deduct from data_len.
|
||||
* Otherwise advance the block number (i) and setup
|
||||
* pos+space to reflect contents of the new mbuf.
|
||||
*/
|
||||
data_len -= AES_BLOCK_LEN;
|
||||
i++;
|
||||
pos = pos_next + space_next;
|
||||
space = m->m_len - space_next;
|
||||
} else {
|
||||
|
@ -482,6 +527,7 @@ ccmp_encrypt(struct ieee80211_key *key, struct mbuf *m0, int hdrlen)
|
|||
space = m->m_len;
|
||||
}
|
||||
}
|
||||
done:
|
||||
/* tack on MIC */
|
||||
xor_block(b, s0, ccmp.ic_trailer);
|
||||
return m_append(m0, ccmp.ic_trailer, b);
|
||||
|
@ -547,7 +593,9 @@ ccmp_decrypt(struct ieee80211_key *key, u_int64_t pn, struct mbuf *m, int hdrlen
|
|||
|
||||
/*
|
||||
* Block straddles buffers, split references. We
|
||||
* do not handle splits that require >2 buffers.
|
||||
* do not handle splits that require >2 buffers
|
||||
* since rx'd frames are never badly fragmented
|
||||
* because drivers typically recv in clusters.
|
||||
*/
|
||||
pos_next = mtod(m, uint8_t *);
|
||||
len = min(data_len, AES_BLOCK_LEN);
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_none.c,v 1.3 2004/12/31 22:42:38 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_none.c,v 1.5 2005/06/10 16:11:24 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_none.c,v 1.2 2005/06/22 06:16:02 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_none.c,v 1.3 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -55,9 +55,9 @@ static void *none_attach(struct ieee80211com *, struct ieee80211_key *);
|
|||
static void none_detach(struct ieee80211_key *);
|
||||
static int none_setkey(struct ieee80211_key *);
|
||||
static int none_encap(struct ieee80211_key *, struct mbuf *, u_int8_t);
|
||||
static int none_decap(struct ieee80211_key *, struct mbuf *);
|
||||
static int none_enmic(struct ieee80211_key *, struct mbuf *);
|
||||
static int none_demic(struct ieee80211_key *, struct mbuf *);
|
||||
static int none_decap(struct ieee80211_key *, struct mbuf *, int);
|
||||
static int none_enmic(struct ieee80211_key *, struct mbuf *, int);
|
||||
static int none_demic(struct ieee80211_key *, struct mbuf *, int);
|
||||
|
||||
const struct ieee80211_cipher ieee80211_cipher_none = {
|
||||
.ic_name = "NONE",
|
||||
|
@ -113,7 +113,7 @@ none_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid)
|
|||
}
|
||||
|
||||
static int
|
||||
none_decap(struct ieee80211_key *k, struct mbuf *m)
|
||||
none_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
|
||||
{
|
||||
struct ieee80211com *ic = k->wk_private;
|
||||
#ifdef IEEE80211_DEBUG
|
||||
|
@ -134,7 +134,7 @@ none_decap(struct ieee80211_key *k, struct mbuf *m)
|
|||
}
|
||||
|
||||
static int
|
||||
none_enmic(struct ieee80211_key *k, struct mbuf *m)
|
||||
none_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
struct ieee80211com *ic = k->wk_private;
|
||||
|
||||
|
@ -143,7 +143,7 @@ none_enmic(struct ieee80211_key *k, struct mbuf *m)
|
|||
}
|
||||
|
||||
static int
|
||||
none_demic(struct ieee80211_key *k, struct mbuf *m)
|
||||
none_demic(struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
struct ieee80211com *ic = k->wk_private;
|
||||
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_tkip.c,v 1.7 2004/12/31 22:42:38 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_tkip.c,v 1.9 2005/06/10 16:11:24 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_tkip.c,v 1.2 2005/06/22 06:16:02 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_tkip.c,v 1.3 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -62,9 +62,9 @@ static void *tkip_attach(struct ieee80211com *, struct ieee80211_key *);
|
|||
static void tkip_detach(struct ieee80211_key *);
|
||||
static int tkip_setkey(struct ieee80211_key *);
|
||||
static int tkip_encap(struct ieee80211_key *, struct mbuf *m, u_int8_t keyid);
|
||||
static int tkip_enmic(struct ieee80211_key *, struct mbuf *);
|
||||
static int tkip_decap(struct ieee80211_key *, struct mbuf *);
|
||||
static int tkip_demic(struct ieee80211_key *, struct mbuf *);
|
||||
static int tkip_enmic(struct ieee80211_key *, struct mbuf *, int);
|
||||
static int tkip_decap(struct ieee80211_key *, struct mbuf *, int);
|
||||
static int tkip_demic(struct ieee80211_key *, struct mbuf *, int);
|
||||
|
||||
const struct ieee80211_cipher ieee80211_cipher_tkip = {
|
||||
.ic_name = "TKIP",
|
||||
|
@ -213,11 +213,11 @@ tkip_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid)
|
|||
* Add MIC to the frame as needed.
|
||||
*/
|
||||
static int
|
||||
tkip_enmic(struct ieee80211_key *k, struct mbuf *m)
|
||||
tkip_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
struct tkip_ctx *ctx = k->wk_private;
|
||||
|
||||
if (k->wk_flags & IEEE80211_KEY_SWMIC) {
|
||||
if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
|
||||
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
|
||||
struct ieee80211com *ic = ctx->tc_ic;
|
||||
int hdrlen;
|
||||
|
@ -248,20 +248,18 @@ READ_6(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5)
|
|||
* the specified key.
|
||||
*/
|
||||
static int
|
||||
tkip_decap(struct ieee80211_key *k, struct mbuf *m)
|
||||
tkip_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
|
||||
{
|
||||
struct tkip_ctx *ctx = k->wk_private;
|
||||
struct ieee80211com *ic = ctx->tc_ic;
|
||||
struct ieee80211_frame *wh;
|
||||
uint8_t *ivp;
|
||||
int hdrlen;
|
||||
|
||||
/*
|
||||
* Header should have extended IV and sequence number;
|
||||
* verify the former and validate the latter.
|
||||
*/
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
hdrlen = ieee80211_hdrsize(wh);
|
||||
ivp = mtod(m, uint8_t *) + hdrlen;
|
||||
if ((ivp[IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV) == 0) {
|
||||
/*
|
||||
|
@ -325,17 +323,18 @@ tkip_decap(struct ieee80211_key *k, struct mbuf *m)
|
|||
* Verify and strip MIC from the frame.
|
||||
*/
|
||||
static int
|
||||
tkip_demic(struct ieee80211_key *k, struct mbuf *m)
|
||||
tkip_demic(struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
struct tkip_ctx *ctx = k->wk_private;
|
||||
|
||||
if (k->wk_flags & IEEE80211_KEY_SWMIC) {
|
||||
if (force || (k->wk_flags & IEEE80211_KEY_SWMIC)) {
|
||||
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
|
||||
int hdrlen = ieee80211_hdrsize(wh);
|
||||
struct ieee80211com *ic = ctx->tc_ic;
|
||||
int hdrlen = ieee80211_hdrspace(ic, wh);
|
||||
u8 mic[IEEE80211_WEP_MICLEN];
|
||||
u8 mic0[IEEE80211_WEP_MICLEN];
|
||||
|
||||
ctx->tc_ic->ic_stats.is_crypto_tkipdemic++;
|
||||
ic->ic_stats.is_crypto_tkipdemic++;
|
||||
|
||||
michael_mic(ctx, k->wk_rxmic,
|
||||
m, hdrlen, m->m_pkthdr.len - (hdrlen + tkip.ic_miclen),
|
||||
|
@ -344,8 +343,7 @@ tkip_demic(struct ieee80211_key *k, struct mbuf *m)
|
|||
tkip.ic_miclen, mic0);
|
||||
if (memcmp(mic, mic0, tkip.ic_miclen)) {
|
||||
/* NB: 802.11 layer handles statistic and debug msg */
|
||||
ieee80211_notify_michael_failure(ctx->tc_ic, wh,
|
||||
k->wk_keyix);
|
||||
ieee80211_notify_michael_failure(ic, wh, k->wk_keyix);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_wep.c,v 1.5 2004/12/31 22:42:38 sam Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_crypto_wep.c,v 1.7 2005/06/10 16:11:24 sam Exp $");
|
||||
#endif
|
||||
#ifdef __NetBSD__
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_wep.c,v 1.2 2005/06/22 06:16:02 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ieee80211_crypto_wep.c,v 1.3 2005/07/26 22:52:48 dyoung Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -58,9 +58,9 @@ static void *wep_attach(struct ieee80211com *, struct ieee80211_key *);
|
|||
static void wep_detach(struct ieee80211_key *);
|
||||
static int wep_setkey(struct ieee80211_key *);
|
||||
static int wep_encap(struct ieee80211_key *, struct mbuf *, u_int8_t keyid);
|
||||
static int wep_decap(struct ieee80211_key *, struct mbuf *);
|
||||
static int wep_enmic(struct ieee80211_key *, struct mbuf *);
|
||||
static int wep_demic(struct ieee80211_key *, struct mbuf *);
|
||||
static int wep_decap(struct ieee80211_key *, struct mbuf *, int hdrlen);
|
||||
static int wep_enmic(struct ieee80211_key *, struct mbuf *, int);
|
||||
static int wep_demic(struct ieee80211_key *, struct mbuf *, int);
|
||||
|
||||
const struct ieee80211_cipher ieee80211_cipher_wep = {
|
||||
.ic_name = "WEP",
|
||||
|
@ -198,7 +198,7 @@ wep_encap(struct ieee80211_key *k, struct mbuf *m, u_int8_t keyid)
|
|||
* Add MIC to the frame as needed.
|
||||
*/
|
||||
static int
|
||||
wep_enmic(struct ieee80211_key *k, struct mbuf *m)
|
||||
wep_enmic(struct ieee80211_key *k, struct mbuf *m, int force)
|
||||
{
|
||||
|
||||
return 1;
|
||||
|
@ -210,14 +210,12 @@ wep_enmic(struct ieee80211_key *k, struct mbuf *m)
|
|||
* the specified key.
|
||||
*/
|
||||
static int
|
||||
wep_decap(struct ieee80211_key *k, struct mbuf *m)
|
||||
wep_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
|
||||
{
|
||||
struct wep_ctx *ctx = k->wk_private;
|
||||
struct ieee80211_frame *wh;
|
||||
int hdrlen;
|
||||
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
hdrlen = ieee80211_hdrsize(wh);
|
||||
|
||||
/*
|
||||
* Check if the device handled the decrypt in hardware.
|
||||
|
@ -247,7 +245,7 @@ wep_decap(struct ieee80211_key *k, struct mbuf *m)
|
|||
* Verify and strip MIC from the frame.
|
||||
*/
|
||||
static int
|
||||
wep_demic(struct ieee80211_key *k, struct mbuf *skb)
|
||||
wep_demic(struct ieee80211_key *k, struct mbuf *skb, int force)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue