PERFORCE change 81452 for review
Sam Leffler
sam at FreeBSD.org
Thu Aug 4 16:15:55 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=81452
Change 81452 by sam at sam_ebb on 2005/08/04 16:15:47
revamp ath protocol handling to be like madwifi
Affected files ...
.. //depot/projects/wifi/sys/net80211/ieee80211.h#12 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#59 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#61 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#30 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_output.c#53 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.c#34 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_proto.h#21 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_var.h#33 edit
Differences ...
==== //depot/projects/wifi/sys/net80211/ieee80211.h#12 (text+ko) ====
@@ -445,7 +445,10 @@
#define ATHEROS_CAP_TURBO_PRIME 0x01 /* dynamic turbo--aka Turbo' */
#define ATHEROS_CAP_COMPRESSION 0x02 /* data compression */
#define ATHEROS_CAP_FAST_FRAME 0x04 /* fast (jumbo) frames */
-/* bits 3-6 reserved */
+#define ATHEROS_CAP_XR 0x08 /* Xtended Range support */
+#define ATHEROS_CAP_AR 0x10 /* Advanded Radar support */
+#define ATHEROS_CAP_BURST 0x20 /* Bursting - not negotiated */
+#define ATHEROS_CAP_WME 0x40 /* CWMin tuning */
#define ATHEROS_CAP_BOOST 0x80 /* use turbo/!turbo mode */
u_int8_t ath_defkeyix[2];
} __packed;
==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#59 (text+ko) ====
@@ -479,7 +479,7 @@
IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len);
#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc))
- if ((ni->ni_flags & IEEE80211_NODE_FF) &&
+ if ((ni->ni_ath_flags & IEEE80211_NODE_FF) &&
m->m_pkthdr.len >= 3*FF_LLC_SIZE) {
struct llc *llc;
@@ -1824,7 +1824,8 @@
struct ieee80211com *ic = ni->ni_ic;
const struct ieee80211_ath_ie *ath;
u_int len = frm[1];
- int caps;
+ int capschanged;
+ u_int16_t defkeyix;
if (len < sizeof(struct ieee80211_ath_ie)-2) {
IEEE80211_DISCARD_IE(ic,
@@ -1833,22 +1834,44 @@
return -1;
}
ath = (const struct ieee80211_ath_ie *)frm;
- caps = 0;
- if ((ath->ath_capability & ATHEROS_CAP_TURBO_PRIME) &&
- (ic->ic_flags & IEEE80211_F_TURBOP))
- caps |= IEEE80211_NODE_TURBOP;
- if ((ath->ath_capability & ATHEROS_CAP_FAST_FRAME) &&
- (ic->ic_flags & IEEE80211_F_FF))
- caps |= IEEE80211_NODE_FF;
- if ((ni->ni_flags ^ caps) & IEEE80211_NODE_ATH) {
+ capschanged = (ni->ni_ath_flags != ath->ath_capability);
+ defkeyix = LE_READ_2(ath->ath_defkeyix);
+ if (capschanged || defkeyix != ni->ni_ath_defkeyix) {
+ ni->ni_ath_flags = ath->ath_capability;
+ ni->ni_ath_defkeyix = defkeyix;
IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG,
- "[%s] ath ie: caps 0x%x defkeyix 0x%x, use 0x%x\n",
+ "[%s] ath ie change: new caps 0x%x defkeyix 0x%x\n",
ether_sprintf(ni->ni_macaddr),
- ath->ath_capability, LE_READ_2(ath->ath_defkeyix), caps);
- ni->ni_flags = (ni->ni_flags &~ IEEE80211_NODE_ATH) | caps;
- return 1;
- } else
- return 0; /* NB: no change */
+ ni->ni_ath_flags, ni->ni_ath_defkeyix);
+ }
+ if (IEEE80211_ATH_CAP(ic, ni, ATHEROS_CAP_TURBO_PRIME)) {
+ u_int16_t curflags, newflags;
+
+ /*
+ * Check for turbo mode switch. Calculate flags
+ * for the new mode and effect the switch.
+ */
+ newflags = curflags = ic->ic_bsschan->ic_flags;
+ /* NB: BOOST is not in ic_flags, so get it from the ie */
+ if (ath->ath_capability & ATHEROS_CAP_BOOST)
+ newflags |= IEEE80211_CHAN_TURBO;
+ else
+ newflags &= ~IEEE80211_CHAN_TURBO;
+ if (newflags != curflags)
+ ieee80211_dturbo_switch(ic, newflags);
+ }
+ return capschanged;
+}
+
+void
+ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie)
+{
+ const struct ieee80211_ath_ie *ath =
+ (const struct ieee80211_ath_ie *) ie;
+
+ ni->ni_ath_flags = ath->ath_capability;
+ ni->ni_ath_defkeyix = LE_READ_2(&ath->ath_defkeyix);
+ ieee80211_saveie(&ni->ni_ath_ie, ie);
}
void
@@ -1868,18 +1891,6 @@
/* XXX note failure */
}
-void
-ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie)
-{
-#if 0
- const struct ieee80211_ath_ie *ath =
- (const struct ieee80211_ath_ie *) ie;
-
- ni->ni_ath_flags = ath->ath_capability;
-#endif
- ieee80211_saveie(&ni->ni_ath_ie, ie);
-}
-
static __inline int
contbgscan(struct ieee80211com *ic)
{
@@ -2245,10 +2256,6 @@
"[%s] recv probe req\n", ether_sprintf(wh->i_addr2));
ni->ni_rssi = rssi;
ni->ni_rstamp = rstamp;
- if (ath != NULL) {
- ieee80211_saveie(&ni->ni_ath_ie, ath);
- (void) ieee80211_parse_athparams(ni, ath, wh);
- }
rate = ieee80211_setup_rates(ni, rates, xrates,
IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
| IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
@@ -2264,7 +2271,8 @@
if (allocbs && ic->ic_opmode != IEEE80211_M_IBSS) {
/* reclaim immediately */
ieee80211_free_node(ni);
- }
+ } else if (ath != NULL)
+ ieee80211_saveath(ni, ath);
break;
case IEEE80211_FC0_SUBTYPE_AUTH: {
@@ -2543,15 +2551,14 @@
* record the information element for
* applications that require it.
*/
- ieee80211_saveie(&ni->ni_ath_ie, ath);
- (void) ieee80211_parse_athparams(ni, ath, wh);
+ ieee80211_saveath(ni, ath);
} else if (ni->ni_ath_ie != NULL) {
/*
* Flush any state from a previous association.
*/
FREE(ni->ni_ath_ie, M_DEVBUF);
ni->ni_ath_ie = NULL;
- ni->ni_flags &= ~IEEE80211_NODE_ATH;
+ ni->ni_ath_flags = 0;
}
ieee80211_node_join(ic, ni, resp);
break;
@@ -2672,8 +2679,10 @@
ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",
- ni->ni_flags & IEEE80211_NODE_FF ? ", fast-frames" : "",
- ni->ni_flags & IEEE80211_NODE_TURBOP ? ", turbo'" : ""
+ IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_FF) ?
+ ", fast-frames" : "",
+ IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_TURBOP) ?
+ ", turbo" : ""
);
ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
break;
==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#61 (text+ko) ====
@@ -727,6 +727,7 @@
ieee80211_crypto_resetkey(ic, &ni->ni_ucastkey, IEEE80211_KEYIX_NONE);
ni->ni_inact_reload = nt->nt_inact_init;
ni->ni_inact = ni->ni_inact_reload;
+ ni->ni_ath_defkeyix = 0x7fff;
IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");
IEEE80211_NODE_LOCK(nt);
@@ -1552,8 +1553,10 @@
ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long",
ic->ic_flags & IEEE80211_F_USEPROT ? ", protection" : "",
ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "",
- ni->ni_flags & IEEE80211_NODE_FF ? ", fast-frames" : "",
- ni->ni_flags & IEEE80211_NODE_TURBOP ? ", turbo'" : ""
+ IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_FF) ?
+ ", fast-frames" : "",
+ IEEE80211_ATH_CAP(ic, ni, IEEE80211_NODE_TURBOP) ?
+ ", turbo" : ""
);
/* give driver a chance to setup state like ni_txrate */
==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#30 (text+ko) ====
@@ -94,6 +94,15 @@
u_int ni_refcnt;
u_int ni_scangen; /* gen# for timeout scan */
u_int8_t ni_authmode; /* authentication algorithm */
+ u_int8_t ni_ath_flags; /* Atheros feature flags */
+ /* NB: These must have the same values as IEEE80211_ATHC_* */
+#define IEEE80211_NODE_TURBOP 0x0001 /* Turbo prime enable */
+#define IEEE80211_NODE_COMP 0x0002 /* Compresssion enable */
+#define IEEE80211_NODE_FF 0x0004 /* Fast Frame capable */
+#define IEEE80211_NODE_XR 0x0008 /* Atheros WME enable */
+#define IEEE80211_NODE_AR 0x0010 /* AR capable */
+#define IEEE80211_NODE_BOOST 0x0080
+#define IEEE80211_NODE_PS_CHANGED 0x0200 /* PS state change */
u_int16_t ni_flags; /* special-purpose state */
#define IEEE80211_NODE_AUTH 0x0001 /* authorized for data */
#define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */
@@ -101,8 +110,7 @@
/* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */
#define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */
#define IEEE80211_NODE_AREF 0x0020 /* authentication ref held */
-#define IEEE80211_NODE_FF 0x0040 /* Atheros fast-frames enabled*/
-#define IEEE80211_NODE_TURBOP 0x0080 /* Atheros Turbo' enabled */
+ u_int16_t ni_ath_defkeyix;/* Atheros def key index */
u_int16_t ni_associd; /* assoc response */
u_int16_t ni_txpower; /* current transmit power */
u_int16_t ni_vlan; /* vlan tag */
==== //depot/projects/wifi/sys/net80211/ieee80211_output.c#53 (text+ko) ====
@@ -1252,7 +1252,7 @@
* Add a WME information element to a frame.
*/
static u_int8_t *
-ieee80211_add_ath(u_int8_t *frm, struct ieee80211_node *ni)
+ieee80211_add_ath(u_int8_t *frm, u_int8_t caps, u_int16_t defkeyix)
{
static const struct ieee80211_ath_ie info = {
.ath_id = IEEE80211_ELEMID_VENDOR,
@@ -1261,15 +1261,13 @@
.ath_oui_type = ATH_OUI_TYPE,
.ath_oui_subtype= ATH_OUI_SUBTYPE,
.ath_version = ATH_OUI_VERSION,
- .ath_defkeyix = { 0x7f, 0xff, },
};
struct ieee80211_ath_ie *ath = (struct ieee80211_ath_ie *) frm;
memcpy(frm, &info, sizeof(info));
- if (ni->ni_flags & IEEE80211_NODE_FF)
- ath->ath_capability |= ATHEROS_CAP_FAST_FRAME;
- if (ni->ni_flags & IEEE80211_NODE_TURBOP)
- ath->ath_capability |= ATHEROS_CAP_TURBO_PRIME;
+ ath->ath_capability = caps;
+ ath->ath_defkeyix[0] = (defkeyix & 0xff);
+ ath->ath_defkeyix[1] = ((defkeyix >> 8) & 0xff);
return frm + sizeof(info);
}
#undef ATH_OUI_BYTES
@@ -1476,7 +1474,8 @@
if (ic->ic_flags & IEEE80211_F_WME)
frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
if (ni->ni_ath_ie != NULL)
- frm = ieee80211_add_ath(frm, ni);
+ frm = ieee80211_add_ath(frm, ni->ni_ath_flags,
+ ni->ni_ath_defkeyix);
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
break;
@@ -1567,7 +1566,7 @@
* [tlv] supported rates
* [tlv] extended supported rates
* [tlv] WME
- * [tlv] Atheros capabilities
+ * [tlv] Atheros capabilities (if negotiated)
* [tlv] user-specified ie's
*/
m = ieee80211_getmgtframe(&frm,
@@ -1617,8 +1616,13 @@
frm = ieee80211_add_xrates(frm, &ni->ni_rates);
if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
- if (ni->ni_ath_ie != NULL)
- frm = ieee80211_add_ath(frm, ni);
+ if (IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS))
+ frm = ieee80211_add_ath(frm,
+ IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS),
+ (ic->ic_flags & IEEE80211_F_WPA) == 0 &&
+ ni->ni_authmode != IEEE80211_AUTH_8021X &&
+ ic->ic_def_txkey != IEEE80211_KEYIX_NONE ?
+ ic->ic_def_txkey : 0x7fff);
if (ic->ic_opt_ie != NULL) {
memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
frm += ic->ic_opt_ie_len;
@@ -1638,6 +1642,7 @@
* [tlv] supported rates
* [tlv] extended supported rates
* [tlv] WME (if enabled and STA enabled)
+ * [tlv] Atheros capabilities (if enabled and STA enabled)
*/
m = ieee80211_getmgtframe(&frm,
sizeof(u_int16_t)
@@ -1646,6 +1651,7 @@
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ sizeof(struct ieee80211_wme_param)
+ + sizeof(struct ieee80211_ath_ie)
);
if (m == NULL)
senderr(ENOMEM, is_tx_nobuf);
@@ -1675,6 +1681,10 @@
frm = ieee80211_add_xrates(frm, &ni->ni_rates);
if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
+ if (IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS))
+ frm = ieee80211_add_ath(frm,
+ IEEE80211_ATH_CAP(ic, ni, IEEE80211_F_ATHEROS),
+ ni->ni_ath_defkeyix);
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
break;
==== //depot/projects/wifi/sys/net80211/ieee80211_proto.c#34 (text+ko) ====
@@ -842,7 +842,39 @@
}
}
+/*
+ * Switch between turbo and non-turbo operating modes.
+ * Use the specified channel flags to locate the new
+ * channel, update 802.11 state, and then call back into
+ * the driver to effect the change.
+ */
void
+ieee80211_dturbo_switch(struct ieee80211com *ic, int newflags)
+{
+ struct ieee80211_channel *chan;
+
+ chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags);
+ if (chan == NULL) { /* XXX should not happen */
+ IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG,
+ "%s: no channel with freq %u flags 0x%x\n",
+ __func__, ic->ic_bsschan->ic_freq, newflags);
+ return;
+ }
+
+ IEEE80211_DPRINTF(ic, IEEE80211_MSG_SUPERG,
+ "%s: %s -> %s (freq %u flags 0x%x)\n", __func__,
+ ieee80211_phymode_name[ieee80211_chan2mode(ic->ic_bsschan)],
+ ieee80211_phymode_name[ieee80211_chan2mode(chan)],
+ chan->ic_freq, chan->ic_flags);
+
+ ic->ic_bsschan = chan;
+ ic->ic_prevchan = ic->ic_curchan;
+ ic->ic_curchan = chan;
+ ic->ic_set_channel(ic);
+ /* NB: do not need to reset ERP state 'cuz we're in sta mode */
+}
+
+void
ieee80211_beacon_miss(struct ieee80211com *ic)
{
@@ -850,8 +882,7 @@
/* XXX check ic_curchan != ic_bsschan? */
return;
}
- IEEE80211_DPRINTF(ic,
- IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
+ IEEE80211_DPRINTF(ic, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
"%s\n", "beacon miss");
/*
@@ -863,16 +894,14 @@
ic->ic_state != IEEE80211_S_RUN)
return;
if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
-#ifdef ATH_SUPERG_DYNTURBO
/*
* If we receive a beacon miss interrupt when using
* dynamic turbo, attempt to switch modes before
* reassociating.
*/
- if (IEEE80211_ATH_CAP(ic, ic->ic_bss, IEEE80211_ATHC_TURBOP))
+ if (IEEE80211_ATH_CAP(ic, ic->ic_bss, IEEE80211_NODE_TURBOP))
ieee80211_dturbo_switch(ic,
ic->ic_bsschan->ic_flags ^ IEEE80211_CHAN_TURBO);
-#endif /* ATH_SUPERG_DYNTURBO */
/*
* Try to reassociate before scanning for a new ap.
*/
==== //depot/projects/wifi/sys/net80211/ieee80211_proto.h#21 (text+ko) ====
@@ -214,6 +214,7 @@
#define ieee80211_new_state(_ic, _nstate, _arg) \
(((_ic)->ic_newstate)((_ic), (_nstate), (_arg)))
+void ieee80211_dturbo_switch(struct ieee80211com *, int newflags);
void ieee80211_beacon_miss(struct ieee80211com *);
void ieee80211_print_essid(const u_int8_t *, int);
void ieee80211_dump_pkt(struct ieee80211com *,
==== //depot/projects/wifi/sys/net80211/ieee80211_var.h#33 (text+ko) ====
@@ -248,8 +248,9 @@
/* ic_flags */
/* NB: bits 0x4c available */
-#define IEEE80211_F_FF 0x00000001 /* CONF: ATH FF enabled */
-#define IEEE80211_F_TURBOP 0x00000002 /* CONF: ATH Turbo enabled*/
+#define IEEE80211_F_TURBOP 0x00000001 /* CONF: ATH Turbo enabled*/
+#define IEEE80211_F_COMP 0x00000002 /* CONF: ATH comp enabled */
+#define IEEE80211_F_FF 0x00000004 /* CONF: ATH FF enabled */
/* NB: this is intentionally setup to be IEEE80211_CAPINFO_PRIVACY */
#define IEEE80211_F_PRIVACY 0x00000010 /* CONF: privacy enabled */
#define IEEE80211_F_PUREG 0x00000020 /* CONF: 11g w/o 11b sta's */
@@ -279,6 +280,13 @@
#define IEEE80211_F_NOBRIDGE 0x10000000 /* CONF: dis. internal bridge */
#define IEEE80211_F_WMEUPDATE 0x20000000 /* STATUS: update beacon wme */
+/* Atheros protocol-specific flags */
+#define IEEE80211_F_ATHEROS \
+ (IEEE80211_F_FF | IEEE80211_F_COMP | IEEE80211_F_TURBOP)
+/* Check if an Atheros capability was negotiated for use */
+#define IEEE80211_ATH_CAP(ic, ni, bit) \
+ ((ic)->ic_flags & (ni)->ni_ath_flags & (bit))
+
/* ic_flags_ext */
#define IEEE80211_FEXT_WDS 0x00000001 /* CONF: 4 addr allowed */
/* 0x00000006 reserved */
More information about the p4-projects
mailing list