From owner-p4-projects@FreeBSD.ORG Mon Jul 18 16:59:43 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B7F6416A421; Mon, 18 Jul 2005 16:59:42 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7A71816A41C for ; Mon, 18 Jul 2005 16:59:42 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2EF1B43D45 for ; Mon, 18 Jul 2005 16:59:42 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6IGxgoA064370 for ; Mon, 18 Jul 2005 16:59:42 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6IGxfmu064367 for perforce@freebsd.org; Mon, 18 Jul 2005 16:59:41 GMT (envelope-from sam@freebsd.org) Date: Mon, 18 Jul 2005 16:59:41 GMT Message-Id: <200507181659.j6IGxfmu064367@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 80454 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Jul 2005 16:59:43 -0000 http://perforce.freebsd.org/chv.cgi?CH=80454 Change 80454 by sam@sam_ebb on 2005/07/18 16:58:57 o update for new scan api o more of the 11j support o track revised api's from vap work o separate min rate index for mgt/ctl frames o purge defrag test glop Affected files ... .. //depot/projects/wifi/sys/dev/ath/if_ath.c#87 edit .. //depot/projects/wifi/sys/dev/ath/if_athvar.h#37 edit Differences ... ==== //depot/projects/wifi/sys/dev/ath/if_ath.c#87 (text+ko) ==== @@ -159,18 +159,20 @@ static void ath_stoprecv(struct ath_softc *); static int ath_startrecv(struct ath_softc *); static void ath_chan_change(struct ath_softc *, struct ieee80211_channel *); -static void ath_next_scan(void *); +static void ath_scan_start(struct ieee80211com *); +static void ath_scan_end(struct ieee80211com *); +static void ath_set_channel(struct ieee80211com *); 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 void ath_newassoc(struct ieee80211_node *, int); static int ath_getchannels(struct ath_softc *, u_int cc, HAL_BOOL outdoor, HAL_BOOL xchanmode); static void ath_led_event(struct ath_softc *, int); static void ath_update_txpow(struct ath_softc *); static int ath_rate_setup(struct ath_softc *, u_int mode); +static void ath_setup_subrates(struct ath_softc *); static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode); static void ath_sysctlattach(struct ath_softc *); @@ -180,9 +182,6 @@ SYSCTL_DECL(_hw_ath); /* XXX validate sysctl values */ -static int ath_dwelltime = 200; /* 5 channels/second */ -SYSCTL_INT(_hw_ath, OID_AUTO, dwell, CTLFLAG_RW, &ath_dwelltime, - 0, "channel dwell time (ms) for AP/station scanning"); static int ath_calinterval = 30; /* calibrate every 30 secs */ SYSCTL_INT(_hw_ath, OID_AUTO, calibrate, CTLFLAG_RW, &ath_calinterval, 0, "chip calibration interval (secs)"); @@ -360,6 +359,7 @@ ath_rate_setup(sc, IEEE80211_MODE_11G); ath_rate_setup(sc, IEEE80211_MODE_TURBO_A); ath_rate_setup(sc, IEEE80211_MODE_TURBO_G); + ath_setup_subrates(sc); /* half/quarter rates */ /* NB: setup here so ath_rate_update is happy */ ath_setcurmode(sc, IEEE80211_MODE_11A); @@ -371,7 +371,6 @@ if_printf(ifp, "failed to allocate descriptors: %d\n", error); goto bad; } - callout_init(&sc->sc_scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0); callout_init(&sc->sc_cal_ch, CALLOUT_MPSAFE); ATH_TXBUF_LOCK_INIT(sc); @@ -503,6 +502,7 @@ | IEEE80211_C_SHPREAMBLE /* short preamble supported */ | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ + | IEEE80211_C_BGSCAN /* capable of bg scanning */ ; /* * Query the hal to figure out h/w crypto support. @@ -592,6 +592,9 @@ ic->ic_recv_mgmt = ath_recv_mgmt; sc->sc_newstate = ic->ic_newstate; ic->ic_newstate = ath_newstate; + ic->ic_scan_start = ath_scan_start; + ic->ic_scan_end = ath_scan_end; + ic->ic_set_channel = ath_set_channel; ic->ic_crypto.cs_key_alloc = ath_key_alloc; ic->ic_crypto.cs_key_delete = ath_key_delete; ic->ic_crypto.cs_key_set = ath_key_set; @@ -843,14 +846,20 @@ CHANNEL_B, /* IEEE80211_MODE_11B */ CHANNEL_PUREG, /* IEEE80211_MODE_11G */ 0, /* IEEE80211_MODE_FH */ - CHANNEL_T, /* IEEE80211_MODE_TURBO_A */ + CHANNEL_108A, /* IEEE80211_MODE_TURBO_A */ CHANNEL_108G /* IEEE80211_MODE_TURBO_G */ }; enum ieee80211_phymode mode = ieee80211_chan2mode(chan); + int flags; KASSERT(mode < N(modeflags), ("unexpected phy mode %u", mode)); KASSERT(modeflags[mode] != 0, ("mode %u undefined", mode)); - return modeflags[mode]; + flags = modeflags[mode]; + if (IEEE80211_IS_CHAN_HALF(chan)) + flags |= CHANNEL_HALF; + else if (IEEE80211_IS_CHAN_QUARTER(chan)) + flags |= CHANNEL_QUARTER; + return flags; #undef N } @@ -1449,7 +1458,7 @@ * to the 802.11 layer and continue. We'll get * the frame back when the time is right. */ - ieee80211_pwrsave(ic, ni, m); + ieee80211_pwrsave(ni, m); goto reclaim; } /* calculate priority so we can find the tx queue */ @@ -1960,14 +1969,15 @@ * - when scanning */ static u_int32_t -ath_calcrxfilter(struct ath_softc *sc, enum ieee80211_state state) +ath_calcrxfilter(struct ath_softc *sc) { +#define RX_FILTER_PRESERVE (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR) struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; struct ifnet *ifp = sc->sc_ifp; u_int32_t rfilt; - rfilt = (ath_hal_getrxfilter(ah) & HAL_RX_FILTER_PHYERR) + rfilt = (ath_hal_getrxfilter(ah) & RX_FILTER_PRESERVE) | HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST; if (ic->ic_opmode != IEEE80211_M_STA) rfilt |= HAL_RX_FILTER_PROBEREQ; @@ -1976,9 +1986,10 @@ rfilt |= HAL_RX_FILTER_PROM; if (ic->ic_opmode == IEEE80211_M_STA || ic->ic_opmode == IEEE80211_M_IBSS || - state == IEEE80211_S_SCAN) + sc->sc_scanning) rfilt |= HAL_RX_FILTER_BEACON; return rfilt; +#undef RX_FILTER_PRESERVE } static void @@ -1992,7 +2003,7 @@ struct ifmultiaddr *ifma; /* configure rx filter */ - rfilt = ath_calcrxfilter(sc, ic->ic_state); + rfilt = ath_calcrxfilter(sc); ath_hal_setrxfilter(ah, rfilt); /* configure operational mode */ @@ -2181,10 +2192,10 @@ struct ieee80211com *ic = ni->ni_ic; struct mbuf *m = bf->bf_m; struct ath_hal *ah = sc->sc_ah; - struct ath_node *an = ATH_NODE(ni); struct ath_desc *ds; int flags, antenna; - u_int8_t rate; + const HAL_RATE_TABLE *rt; + u_int8_t rix, rate; DPRINTF(sc, ATH_DEBUG_BEACON, "%s: m %p len %u\n", __func__, m, m->m_len); @@ -2216,10 +2227,11 @@ * Calculate rate code. * XXX everything at min xmit rate */ + rix = sc->sc_minrateix; + rt = sc->sc_currates; + rate = rt->info[rix].rateCode; if (USE_SHPREAMBLE(ic)) - rate = an->an_tx_mgtratesp; - else - rate = an->an_tx_mgtrate; + rate |= rt->info[rix].shortPreamble; ath_hal_setuptxdesc(ah, ds , m->m_len + IEEE80211_CRC_LEN /* frame length */ , sizeof(struct ieee80211_frame)/* header length */ @@ -2575,6 +2587,7 @@ if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol) ath_beacon_proc(sc, 0); } + sc->sc_syncbeacon = 0; #undef TSF_TO_TU } @@ -2931,6 +2944,14 @@ case IEEE80211_FC0_SUBTYPE_BEACON: /* update rssi statistics for use by the hal */ ATH_RSSI_LPF(ATH_NODE(ni)->an_halstats.ns_avgbrssi, rssi); + if (sc->sc_syncbeacon && + ni == ic->ic_bss && ic->ic_state == IEEE80211_S_RUN) { + /* + * Resync beacon timers using the tsf of the beacon + * frame we just received. + */ + ath_beacon_config(sc); + } /* fall thru... */ case IEEE80211_FC0_SUBTYPE_PROBE_RESP: if (ic->ic_opmode == IEEE80211_M_IBSS && @@ -2951,7 +2972,7 @@ "ibss merge, rstamp %u tsf %ju " "tstamp %ju\n", rstamp, (uintmax_t)tsf, (uintmax_t)ni->ni_tstamp.tsf); - (void) ieee80211_ibss_merge(ic, ni); + (void) ieee80211_ibss_merge(ni); } } break; @@ -3202,7 +3223,8 @@ * frame; it'll be dropped where it's not wanted. */ if (ds->ds_rxstat.rs_keyix != HAL_RXKEYIX_INVALID && - (ni = sc->sc_keyixmap[ds->ds_rxstat.rs_keyix]) != NULL) { + (ni = sc->sc_keyixmap[ds->ds_rxstat.rs_keyix]) != NULL && + ieee80211_node_refcnt(ni) > 1) { /* * Fast path: node is present in the key map; * grab a reference for processing the frame. @@ -3443,18 +3465,6 @@ ath_tx_cleanupq(sc, &sc->sc_txq[i]); } -SYSCTL_NODE(_hw_ath, OID_AUTO, defrag, CTLFLAG_RD, 0, "defrag testing"); -static int ath_maxfrags = 4; -SYSCTL_INT(_hw_ath_defrag, OID_AUTO, max, CTLFLAG_RW, &ath_maxfrags, 0, ""); -static int ath_defrags; -SYSCTL_INT(_hw_ath_defrag, OID_AUTO, calls, CTLFLAG_RW, &ath_defrags, 0, ""); -static int ath_collectedfrags; -SYSCTL_INT(_hw_ath_defrag, OID_AUTO, combined, CTLFLAG_RW, &ath_collectedfrags, 0, ""); -static int ath_replacedfrags; -SYSCTL_INT(_hw_ath_defrag, OID_AUTO, replaced, CTLFLAG_RW, &ath_replacedfrags, 0, ""); -static int ath_defragsfail; -SYSCTL_INT(_hw_ath_defrag, OID_AUTO, fail, CTLFLAG_RW, &ath_defragsfail, 0, ""); - /* * Defragment an mbuf chain, returning at most maxfrags separate * mbufs+clusters. If this is not possible NULL is returned and @@ -3468,14 +3478,12 @@ struct mbuf *m, *n, *n2, **prev; u_int curfrags; -ath_defrags++;/*XXX*/ /* * Calculate the current number of frags. */ curfrags = 0; for (m = m0; m != NULL; m = m->m_next) curfrags++; -if (curfrags <= maxfrags) return m0; /* XXX for testing */ /* * First, try to collapse mbufs. Note that we always collapse * towards the front so we don't need to deal with moving the @@ -3495,7 +3503,6 @@ m->m_len += n->m_len; m->m_next = n->m_next; m_free(n); -ath_collectedfrags++;/*XXX*/ if (--curfrags <= maxfrags) return m0; } else @@ -3521,7 +3528,6 @@ *prev = m; m_free(n); m_free(n2); -ath_replacedfrags++;/*XXX*/ if (--curfrags <= maxfrags) /* +1 cl -2 mbufs */ return m0; /* @@ -3540,7 +3546,6 @@ * packet header). */ bad: -ath_defragsfail++;/*XXX*/ return NULL; } @@ -3632,8 +3637,6 @@ pktlen += IEEE80211_CRC_LEN; -m = ath_defrag(m0, M_DONTWAIT, ath_maxfrags); if (m != NULL) m0 = m; /*XXX*/ - /* * Load the DMA map so any coalescing is done. This * also calculates the number of descriptors we need. @@ -3718,12 +3721,11 @@ atype = HAL_PKT_TYPE_ATIM; else atype = HAL_PKT_TYPE_NORMAL; /* XXX */ - rix = 0; /* XXX lowest rate */ + rix = sc->sc_minrateix; + txrate = rt->info[rix].rateCode; + if (shortPreamble) + txrate |= rt->info[rix].shortPreamble; try0 = ATH_TXMAXTRY; - if (shortPreamble) - txrate = an->an_tx_mgtratesp; - else - txrate = an->an_tx_mgtrate; /* NB: force all management frames to highest queue */ if (ni->ni_flags & IEEE80211_NODE_QOS) { /* NB: force all management frames to highest queue */ @@ -3734,12 +3736,11 @@ break; case IEEE80211_FC0_TYPE_CTL: atype = HAL_PKT_TYPE_PSPOLL; /* stop setting of duration */ - rix = 0; /* XXX lowest rate */ + rix = sc->sc_minrateix; + txrate = rt->info[rix].rateCode; + if (shortPreamble) + txrate |= rt->info[rix].shortPreamble; try0 = ATH_TXMAXTRY; - if (shortPreamble) - txrate = an->an_tx_mgtratesp; - else - txrate = an->an_tx_mgtrate; /* NB: force all ctl frames to highest queue */ if (ni->ni_flags & IEEE80211_NODE_QOS) { /* NB: force all ctl frames to highest queue */ @@ -4491,16 +4492,6 @@ return 0; } -static void -ath_next_scan(void *arg) -{ - struct ath_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - - if (ic->ic_state == IEEE80211_S_SCAN) - ieee80211_next_scan(ic); -} - /* * Periodically recalibrate the PHY to account * for temperature/environment changes. @@ -4533,6 +4524,61 @@ callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc); } +static void +ath_scan_start(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; + struct ath_hal *ah = sc->sc_ah; + u_int32_t rfilt; + + /* XXX calibration timer? */ + + sc->sc_scanning = 1; + sc->sc_syncbeacon = 0; + rfilt = ath_calcrxfilter(sc); + ath_hal_setrxfilter(ah, rfilt); + ath_hal_setassocid(ah, ifp->if_broadcastaddr, 0); + + DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0\n", + __func__, rfilt, ether_sprintf(ifp->if_broadcastaddr)); +} + +static void +ath_scan_end(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; + struct ath_hal *ah = sc->sc_ah; + u_int32_t rfilt; + + sc->sc_scanning = 0; + rfilt = ath_calcrxfilter(sc); + ath_hal_setrxfilter(ah, rfilt); + ath_hal_setassocid(ah, sc->sc_curbssid, sc->sc_curaid); + + DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0x%x\n", + __func__, rfilt, ether_sprintf(sc->sc_curbssid), + sc->sc_curaid); +} + +static void +ath_set_channel(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; + + (void) ath_chan_set(sc, ic->ic_curchan); + /* + * If we are returning to our bss channel then mark state + * so the next recv'd beacon's tsf will be used to sync the + * beacon timers. Note that since we only hear beacons in + * sta/ibss mode this has no effect in other operating modes. + */ + if (!sc->sc_scanning && ic->ic_curchan == ic->ic_bsschan) + sc->sc_syncbeacon = 1; +} + static int ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) { @@ -4540,8 +4586,7 @@ struct ath_softc *sc = ifp->if_softc; struct ath_hal *ah = sc->sc_ah; struct ieee80211_node *ni; - int i, error; - const u_int8_t *bssid; + int i, error, stamode; u_int32_t rfilt; static const HAL_LED_STATE leds[] = { HAL_LED_INIT, /* IEEE80211_S_INIT */ @@ -4555,7 +4600,6 @@ ieee80211_state_name[ic->ic_state], ieee80211_state_name[nstate]); - callout_stop(&sc->sc_scan_ch); callout_stop(&sc->sc_cal_ch); ath_hal_setledstate(ah, leds[nstate]); /* set LED */ @@ -4572,26 +4616,30 @@ goto done; } ni = ic->ic_bss; - error = ath_chan_set(sc, ic->ic_curchan); - if (error != 0) - goto bad; - rfilt = ath_calcrxfilter(sc, nstate); - if (nstate == IEEE80211_S_SCAN) - bssid = ifp->if_broadcastaddr; - else - bssid = ni->ni_bssid; + + rfilt = ath_calcrxfilter(sc); + stamode = (ic->ic_opmode == IEEE80211_M_STA || + ic->ic_opmode == IEEE80211_M_IBSS || + ic->ic_opmode == IEEE80211_M_AHDEMO); + if (stamode && nstate == IEEE80211_S_RUN) { + sc->sc_curaid = ni->ni_associd; + IEEE80211_ADDR_COPY(sc->sc_curbssid, ni->ni_bssid); + } else + sc->sc_curaid = 0; + + DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0x%x\n", + __func__, rfilt, ether_sprintf(sc->sc_curbssid), + sc->sc_curaid); + ath_hal_setrxfilter(ah, rfilt); - DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s\n", - __func__, rfilt, ether_sprintf(bssid)); + if (stamode) + ath_hal_setassocid(ah, sc->sc_curbssid, ni->ni_associd); - if (nstate == IEEE80211_S_RUN && ic->ic_opmode == IEEE80211_M_STA) - ath_hal_setassocid(ah, bssid, ni->ni_associd); - else - ath_hal_setassocid(ah, bssid, 0); - if (ic->ic_flags & IEEE80211_F_PRIVACY) { + if (ic->ic_opmode != IEEE80211_M_STA && + (ic->ic_flags & IEEE80211_F_PRIVACY)) { for (i = 0; i < IEEE80211_WEP_NKID; i++) if (ath_hal_keyisvalid(ah, i)) - ath_hal_keysetmac(ah, i, bssid); + ath_hal_keysetmac(ah, i, ni->ni_bssid); } /* @@ -4672,10 +4720,6 @@ /* start periodic recalibration timer */ callout_reset(&sc->sc_cal_ch, ath_calinterval * hz, ath_calibrate, sc); - } else if (nstate == IEEE80211_S_SCAN) { - /* start ap/neighbor scan timer */ - callout_reset(&sc->sc_scan_ch, (ath_dwelltime * hz) / 1000, - ath_next_scan, sc); } bad: return error; @@ -4717,8 +4761,9 @@ * param tells us if this is the first time or not. */ static void -ath_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew) +ath_newassoc(struct ieee80211_node *ni, int isnew) { + struct ieee80211com *ic = ni->ni_ic; struct ath_softc *sc = ic->ic_ifp->if_softc; ath_rate_newassoc(sc, ATH_NODE(ni), isnew); @@ -4855,51 +4900,74 @@ ic->ic_bss->ni_txpower = txpow; } +static void +rate_setup(struct ath_softc *sc, + const HAL_RATE_TABLE *rt, struct ieee80211_rateset *rs) +{ + int i, maxrates; + + if (rt->rateCount > IEEE80211_RATE_MAXSIZE) { + DPRINTF(sc, ATH_DEBUG_ANY, + "%s: rate table too small (%u > %u)\n", + __func__, rt->rateCount, IEEE80211_RATE_MAXSIZE); + maxrates = IEEE80211_RATE_MAXSIZE; + } else + maxrates = rt->rateCount; + for (i = 0; i < maxrates; i++) + rs->rs_rates[i] = rt->info[i].dot11Rate; + rs->rs_nrates = maxrates; +} + static int ath_rate_setup(struct ath_softc *sc, u_int mode) { struct ath_hal *ah = sc->sc_ah; struct ieee80211com *ic = &sc->sc_ic; const HAL_RATE_TABLE *rt; - struct ieee80211_rateset *rs; - int i, maxrates; switch (mode) { case IEEE80211_MODE_11A: - sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11A); + rt = ath_hal_getratetable(ah, HAL_MODE_11A); break; case IEEE80211_MODE_11B: - sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11B); + rt = ath_hal_getratetable(ah, HAL_MODE_11B); break; case IEEE80211_MODE_11G: - sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_11G); + rt = ath_hal_getratetable(ah, HAL_MODE_11G); break; case IEEE80211_MODE_TURBO_A: - sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_TURBO); + rt = ath_hal_getratetable(ah, HAL_MODE_TURBO); break; case IEEE80211_MODE_TURBO_G: - sc->sc_rates[mode] = ath_hal_getratetable(ah, HAL_MODE_108G); + rt = ath_hal_getratetable(ah, HAL_MODE_108G); break; default: DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid mode %u\n", __func__, mode); return 0; } - rt = sc->sc_rates[mode]; - if (rt == NULL) + sc->sc_rates[mode] = rt; + if (rt != NULL) { + rate_setup(sc, rt, &ic->ic_sup_rates[mode]); + return 1; + } else return 0; - if (rt->rateCount > IEEE80211_RATE_MAXSIZE) { - DPRINTF(sc, ATH_DEBUG_ANY, - "%s: rate table too small (%u > %u)\n", - __func__, rt->rateCount, IEEE80211_RATE_MAXSIZE); - maxrates = IEEE80211_RATE_MAXSIZE; - } else - maxrates = rt->rateCount; - rs = &ic->ic_sup_rates[mode]; - for (i = 0; i < maxrates; i++) - rs->rs_rates[i] = rt->info[i].dot11Rate; - rs->rs_nrates = maxrates; - return 1; +} + +static void +ath_setup_subrates(struct ath_softc *sc) +{ + struct ath_hal *ah = sc->sc_ah; + struct ieee80211com *ic = &sc->sc_ic; + + sc->sc_half_rates = ath_hal_getratetable(ah, HAL_MODE_11A_HALF_RATE); + if (sc->sc_half_rates != NULL) + rate_setup(sc, sc->sc_half_rates, &ic->ic_sup_half_rates); + + sc->sc_quarter_rates = + ath_hal_getratetable(ah, HAL_MODE_11A_QUARTER_RATE); + if (sc->sc_quarter_rates != NULL) + rate_setup(sc, sc->sc_quarter_rates, &ic->ic_sup_quarter_rates); } static void @@ -4970,6 +5038,8 @@ */ sc->sc_protrix = (mode == IEEE80211_MODE_11G ? 1 : 0); /* NB: caller is responsible for reseting rate control state */ + /* rate index used to send management frames */ + sc->sc_minrateix = 0; #undef N } ==== //depot/projects/wifi/sys/dev/ath/if_athvar.h#37 (text+ko) ==== @@ -226,13 +226,19 @@ sc_ledstate: 1, /* LED on/off state */ sc_blinking: 1, /* LED blink operation active */ sc_mcastkey: 1, /* mcast key cache search */ + sc_scanning: 1, /* scanning active */ + sc_syncbeacon:1,/* sync/resync beacon timers */ sc_hasclrkey:1; /* CLR key supported */ /* rate tables */ const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX]; + const HAL_RATE_TABLE *sc_half_rates; /* half rate table */ + const HAL_RATE_TABLE *sc_quarter_rates;/* quarter rate table */ const HAL_RATE_TABLE *sc_currates; /* current rate table */ enum ieee80211_phymode sc_curmode; /* current phy mode */ u_int16_t sc_curtxpow; /* current tx power limit */ + u_int16_t sc_curaid; /* current association id */ HAL_CHANNEL sc_curchan; /* current h/w channel */ + u_int8_t sc_curbssid[IEEE80211_ADDR_LEN]; u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */ struct { u_int8_t ieeerate; /* IEEE rate */ @@ -241,6 +247,7 @@ u_int16_t ledon; /* softled on time */ u_int16_t ledoff; /* softled off time */ } sc_hwmap[32]; /* h/w rate ix mappings */ + u_int8_t sc_minrateix; /* min h/w rate index */ u_int8_t sc_protrix; /* protection rate index */ u_int8_t sc_lastdatarix; /* last data frame rate index */ u_int sc_fftxqmin; /* min frames before staging */ @@ -309,7 +316,6 @@ } sc_updateslot; /* slot time update fsm */ struct callout sc_cal_ch; /* callout handle for cals */ - struct callout sc_scan_ch; /* callout handle for scan */ HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */ }; #define sc_tx_th u_tx_rt.th