From owner-svn-src-all@FreeBSD.ORG Thu Mar 18 11:06:38 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 984D41065672; Thu, 18 Mar 2010 11:06:38 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 865E78FC16; Thu, 18 Mar 2010 11:06:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2IB6c05004024; Thu, 18 Mar 2010 11:06:38 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2IB6cUd004019; Thu, 18 Mar 2010 11:06:38 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <201003181106.o2IB6cUd004019@svn.freebsd.org> From: Rui Paulo Date: Thu, 18 Mar 2010 11:06:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205277 - head/sys/net80211 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Mar 2010 11:06:38 -0000 Author: rpaulo Date: Thu Mar 18 11:06:38 2010 New Revision: 205277 URL: http://svn.freebsd.org/changeset/base/205277 Log: Fix a couple of bugs with 802.11n: o Process the BAR frame on the adhoc, mesh and sta modes o Fix the format of the ADDBA reply frame o Fix references to the spec section numbers Also, print the all the MCS rates in bootverbose. Sponsored by: iXsystems, Inc. Obtained from: //depot/user/rpaulo/80211n/... Modified: head/sys/net80211/ieee80211_adhoc.c head/sys/net80211/ieee80211_ht.c head/sys/net80211/ieee80211_mesh.c head/sys/net80211/ieee80211_sta.c Modified: head/sys/net80211/ieee80211_adhoc.c ============================================================================== --- head/sys/net80211/ieee80211_adhoc.c Thu Mar 18 09:09:59 2010 (r205276) +++ head/sys/net80211/ieee80211_adhoc.c Thu Mar 18 11:06:38 2010 (r205277) @@ -922,6 +922,12 @@ ahdemo_recv_mgmt(struct ieee80211_node * } static void -adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m0, int subtype) +adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) { + + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_BAR: + ieee80211_recv_bar(ni, m); + break; + } } Modified: head/sys/net80211/ieee80211_ht.c ============================================================================== --- head/sys/net80211/ieee80211_ht.c Thu Mar 18 09:09:59 2010 (r205276) +++ head/sys/net80211/ieee80211_ht.c Thu Mar 18 11:06:38 2010 (r205277) @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #define SM(_v, _f) (((_v) << _f##_S) & _f) const struct ieee80211_mcs_rates ieee80211_htrates[16] = { + /* 20Mhz SGI 40Mhz SGI */ { 13, 14, 27, 30 }, /* MCS 0 */ { 26, 29, 54, 60 }, /* MCS 1 */ { 39, 43, 81, 90 }, /* MCS 2 */ @@ -248,25 +249,60 @@ ieee80211_ht_vdetach(struct ieee80211vap } static void -ht_announce(struct ieee80211com *ic, int mode, - const struct ieee80211_htrateset *rs) +ht_rateprint(struct ieee80211com *ic, int mode, + const struct ieee80211_htrateset *rs, int maxmcs, int ratetype) { - struct ifnet *ifp = ic->ic_ifp; int i, rate, mword; - if_printf(ifp, "%s MCS: ", ieee80211_phymode_name[mode]); - for (i = 0; i < rs->rs_nrates; i++) { + for (i = 0; i < rs->rs_nrates && i < maxmcs; i++) { mword = ieee80211_rate2media(ic, rs->rs_rates[i] | IEEE80211_RATE_MCS, mode); if (IFM_SUBTYPE(mword) != IFM_IEEE80211_MCS) continue; - rate = ieee80211_htrates[rs->rs_rates[i]].ht40_rate_400ns; + switch (ratetype) { + case 0: + rate = ieee80211_htrates[ + rs->rs_rates[i]].ht20_rate_800ns; + break; + case 1: + rate = ieee80211_htrates[ + rs->rs_rates[i]].ht20_rate_400ns; + break; + case 2: + rate = ieee80211_htrates[ + rs->rs_rates[i]].ht40_rate_800ns; + break; + default: + rate = ieee80211_htrates[ + rs->rs_rates[i]].ht40_rate_400ns; + break; + } printf("%s%d%sMbps", (i != 0 ? " " : ""), rate / 2, ((rate & 0x1) != 0 ? ".5" : "")); } printf("\n"); } +static void +ht_announce(struct ieee80211com *ic, int mode, + const struct ieee80211_htrateset *rs) +{ + struct ifnet *ifp = ic->ic_ifp; + int maxmcs = ic->ic_rxstream * 8; + const char *modestr = ieee80211_phymode_name[mode]; + + KASSERT(maxmcs <= 16, ("maxmcs > 16")); + if_printf(ifp, "%d MCS rates\n", maxmcs); + if_printf(ifp, "%s MCS 20Mhz: ", modestr); + ht_rateprint(ic, mode, rs, maxmcs, 0); + if_printf(ifp, "%s MCS 20Mhz SGI: ", modestr); + ht_rateprint(ic, mode, rs, maxmcs, 1); + if_printf(ifp, "%s MCS 40Mhz: ", modestr); + ht_rateprint(ic, mode, rs, maxmcs, 2); + if_printf(ifp, "%s MCS 40Mhz SGI: ", modestr); + ht_rateprint(ic, mode, rs, maxmcs, 3); +} + void ieee80211_ht_announce(struct ieee80211com *ic) { @@ -396,6 +432,7 @@ ampdu_rx_start(struct ieee80211_node *ni static void ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) { + ampdu_rx_purge(rap); rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND); } @@ -656,7 +693,7 @@ again: if (off < rap->rxa_wnd) { /* * Common case (hopefully): in the BA window. - * Sec 9.10.7.6 a) (D2.04 p.118 line 47) + * Sec 9.10.7.6.2 a) (p.137) */ #ifdef IEEE80211_AMPDU_AGE /* @@ -721,7 +758,7 @@ again: /* * Outside the BA window, but within range; * flush the reorder q and move the window. - * Sec 9.10.7.6 b) (D2.04 p.118 line 60) + * Sec 9.10.7.6.2 b) (p.138) */ IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni, "move BA win <%u:%u> (%u frames) rxseq %u tid %u", @@ -745,7 +782,7 @@ again: } else { /* * Outside the BA window and out of range; toss. - * Sec 9.10.7.6 c) (D2.04 p.119 line 16) + * Sec 9.10.7.6.2 c) (p.138) */ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, @@ -809,7 +846,7 @@ ieee80211_recv_bar(struct ieee80211_node if (off < IEEE80211_SEQ_BA_RANGE) { /* * Flush the reorder q up to rxseq and move the window. - * Sec 9.10.7.6 a) (D2.04 p.119 line 22) + * Sec 9.10.7.6.3 a) (p.138) */ IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni, "BAR moves BA win <%u:%u> (%u frames) rxseq %u tid %u", @@ -830,7 +867,7 @@ ieee80211_recv_bar(struct ieee80211_node } else { /* * Out of range; toss. - * Sec 9.10.7.6 b) (D2.04 p.119 line 41) + * Sec 9.10.7.6.3 b) (p.138) */ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, @@ -1621,7 +1658,7 @@ ht_recv_action_ba_addba_request(struct i struct ieee80211_rx_ampdu *rap; uint8_t dialogtoken; uint16_t baparamset, batimeout, baseqctl; - uint16_t args[4]; + uint16_t args[5]; int tid; dialogtoken = frm[2]; @@ -1671,6 +1708,7 @@ ht_recv_action_ba_addba_request(struct i | SM(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ) ; args[3] = 0; + args[4] = 0; ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, IEEE80211_ACTION_BA_ADDBA_RESPONSE, args); return 0; @@ -1874,7 +1912,7 @@ ieee80211_ampdu_request(struct ieee80211 struct ieee80211_tx_ampdu *tap) { struct ieee80211com *ic = ni->ni_ic; - uint16_t args[4]; + uint16_t args[5]; int tid, dialogtoken; static int tokens = 0; /* XXX */ @@ -1891,13 +1929,14 @@ ieee80211_ampdu_request(struct ieee80211 tap->txa_start = ni->ni_txseqs[tid]; args[0] = dialogtoken; - args[1] = IEEE80211_BAPS_POLICY_IMMEDIATE + args[1] = 0; /* NB: status code not used */ + args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE | SM(tid, IEEE80211_BAPS_TID) | SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ) ; - args[2] = 0; /* batimeout */ + args[3] = 0; /* batimeout */ /* NB: do first so there's no race against reply */ - if (!ic->ic_addba_request(ni, tap, dialogtoken, args[1], args[2])) { + if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) { /* unable to setup state, don't make request */ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, "%s: could not setup BA stream for AC %d", @@ -1911,7 +1950,7 @@ ieee80211_ampdu_request(struct ieee80211 } tokens = dialogtoken; /* allocate token */ /* NB: after calling ic_addba_request so driver can set txa_start */ - args[3] = SM(tap->txa_start, IEEE80211_BASEQ_START) + args[4] = SM(tap->txa_start, IEEE80211_BASEQ_START) | SM(0, IEEE80211_BASEQ_FRAG) ; return ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, @@ -2157,12 +2196,12 @@ ht_send_action_ba_addba(struct ieee80211 uint8_t *frm; IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send ADDBA %s: dialogtoken %d " + "send ADDBA %s: dialogtoken %d status %d " "baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x", (action == IEEE80211_ACTION_BA_ADDBA_REQUEST) ? "request" : "response", - args[0], args[1], MS(args[1], IEEE80211_BAPS_TID), - args[2], args[3]); + args[0], args[1], args[2], MS(args[2], IEEE80211_BAPS_TID), + args[3], args[4]); IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, @@ -2179,10 +2218,12 @@ ht_send_action_ba_addba(struct ieee80211 *frm++ = category; *frm++ = action; *frm++ = args[0]; /* dialog token */ - ADDSHORT(frm, args[1]); /* baparamset */ - ADDSHORT(frm, args[2]); /* batimeout */ + if (action == IEEE80211_ACTION_BA_ADDBA_RESPONSE) + ADDSHORT(frm, args[1]); /* status code */ + ADDSHORT(frm, args[2]); /* baparamset */ + ADDSHORT(frm, args[3]); /* batimeout */ if (action == IEEE80211_ACTION_BA_ADDBA_REQUEST) - ADDSHORT(frm, args[3]); /* baseqctl */ + ADDSHORT(frm, args[4]); /* baseqctl */ m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); return ht_action_output(ni, m); } else { Modified: head/sys/net80211/ieee80211_mesh.c ============================================================================== --- head/sys/net80211/ieee80211_mesh.c Thu Mar 18 09:09:59 2010 (r205276) +++ head/sys/net80211/ieee80211_mesh.c Thu Mar 18 11:06:38 2010 (r205277) @@ -82,6 +82,7 @@ static void mesh_forward(struct ieee8021 static int mesh_input(struct ieee80211_node *, struct mbuf *, int, int); static void mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int, int, int); +static void mesh_recv_ctl(struct ieee80211_node *, struct mbuf *, int); static void mesh_peer_timeout_setup(struct ieee80211_node *); static void mesh_peer_timeout_backoff(struct ieee80211_node *); static void mesh_peer_timeout_cb(void *); @@ -520,6 +521,7 @@ mesh_vattach(struct ieee80211vap *vap) vap->iv_input = mesh_input; vap->iv_opdetach = mesh_vdetach; vap->iv_recv_mgmt = mesh_recv_mgmt; + vap->iv_recv_ctl = mesh_recv_ctl; ms = malloc(sizeof(struct ieee80211_mesh_state), M_80211_VAP, M_NOWAIT | M_ZERO); if (ms == NULL) { @@ -1535,6 +1537,17 @@ mesh_recv_mgmt(struct ieee80211_node *ni } } +static void +mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) +{ + + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_BAR: + ieee80211_recv_bar(ni, m); + break; + } +} + /* * Parse meshpeering action ie's for open+confirm frames; the * important bits are returned in the supplied structure. Modified: head/sys/net80211/ieee80211_sta.c ============================================================================== --- head/sys/net80211/ieee80211_sta.c Thu Mar 18 09:09:59 2010 (r205276) +++ head/sys/net80211/ieee80211_sta.c Thu Mar 18 11:06:38 2010 (r205277) @@ -1739,6 +1739,11 @@ sta_recv_mgmt(struct ieee80211_node *ni, } static void -sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m0, int subtype) +sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype) { + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_BAR: + ieee80211_recv_bar(ni, m); + break; + } }