PERFORCE change 80454 for review
Sam Leffler
sam at FreeBSD.org
Mon Jul 18 16:59:43 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80454
Change 80454 by sam at 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
More information about the p4-projects
mailing list