Date: Fri, 3 Oct 2008 21:26:09 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 150901 for review Message-ID: <200810032126.m93LQ9fD090638@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=150901 Change 150901 by sam@sam_ebb on 2008/10/03 21:25:09 make ieee80211_send_nulldata send a QoS null data frame when a station is setup w/ QoS; the spec says we should not be sending non-QoS frames Affected files ... .. //depot/projects/vap/sys/net80211/ieee80211_output.c#61 edit Differences ... ==== //depot/projects/vap/sys/net80211/ieee80211_output.c#61 (text+ko) ==== @@ -406,15 +406,14 @@ /* * Set the direction field and address fields of an outgoing - * non-QoS frame. Note this should be called early on in - * constructing a frame as it sets i_fc[1]; other bits can - * then be or'd in. + * frame. Note this should be called early on in constructing + * a frame as it sets i_fc[1]; other bits can then be or'd in. */ static void ieee80211_send_setup( struct ieee80211_node *ni, struct ieee80211_frame *wh, - int type, + int type, int tid, const uint8_t sa[IEEE80211_ADDR_LEN], const uint8_t da[IEEE80211_ADDR_LEN], const uint8_t bssid[IEEE80211_ADDR_LEN]) @@ -462,11 +461,9 @@ IEEE80211_ADDR_COPY(wh->i_addr3, bssid); } *(uint16_t *)&wh->i_dur[0] = 0; - /* XXX probe response use per-vap seq#? */ - /* NB: use non-QoS tid */ *(uint16_t *)&wh->i_seq[0] = - htole16(ni->ni_txseqs[IEEE80211_NONQOS_TID] << IEEE80211_SEQ_SEQ_SHIFT); - ni->ni_txseqs[IEEE80211_NONQOS_TID]++; + htole16(ni->ni_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT); + ni->ni_txseqs[tid]++; #undef WH4 } @@ -507,9 +504,9 @@ } wh = mtod(m, struct ieee80211_frame *); - ieee80211_send_setup(ni, wh, - IEEE80211_FC0_TYPE_MGT | type, - vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); + ieee80211_send_setup(ni, wh, + IEEE80211_FC0_TYPE_MGT | type, IEEE80211_NONQOS_TID, + vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); if (params->ibp_flags & IEEE80211_BPF_CRYPTO) { IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr1, "encrypting frame (%s)", __func__); @@ -538,7 +535,9 @@ } /* - * Send a null data frame to the specified node. + * Send a null data frame to the specified node. If the station + * is setup for QoS then a QoS Null Data frame is constructed. + * If this is a WDS station then a 4-address frame is constructed. * * NB: the caller is assumed to have setup a node reference * for use; this is necessary to deal with a race condition @@ -565,10 +564,16 @@ return EIO; /* XXX */ } - if (vap->iv_opmode == IEEE80211_M_WDS) - hdrlen = sizeof(struct ieee80211_frame_addr4); + if (ni->ni_flags & (IEEE80211_NODE_QOS|IEEE80211_NODE_HT)) + hdrlen = sizeof(struct ieee80211_qosframe); else hdrlen = sizeof(struct ieee80211_frame); + /* NB: only WDS vap's get 4-address frames */ + if (vap->iv_opmode == IEEE80211_M_WDS) + hdrlen += IEEE80211_ADDR_LEN; + if (ic->ic_flags & IEEE80211_F_DATAPAD) + hdrlen = roundup(hdrlen, sizeof(uint32_t)); + m = ieee80211_getmgtframe(&frm, ic->ic_headroom + hdrlen, 0); if (m == NULL) { /* XXX debug msg */ @@ -586,9 +591,28 @@ } wh = mtod(m, struct ieee80211_frame *); /* NB: a little lie */ - ieee80211_send_setup(ni, wh, - IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA, - vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); + if (ni->ni_flags & IEEE80211_NODE_QOS) { + const int tid = WME_AC_TO_TID(WME_AC_BE); + uint8_t *qos; + + ieee80211_send_setup(ni, wh, + IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS_NULL, + tid, vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); + + if (vap->iv_opmode == IEEE80211_M_WDS) + qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos; + else + qos = ((struct ieee80211_qosframe *) wh)->i_qos; + qos[0] = tid & IEEE80211_QOS_TID; + if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[WME_AC_BE].wmep_noackPolicy) + qos[0] |= IEEE80211_QOS_ACKPOLICY_NOACK; + qos[1] = 0; + } else { + ieee80211_send_setup(ni, wh, + IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA, + IEEE80211_NONQOS_TID, + vap->iv_myaddr, ni->ni_macaddr, ni->ni_bssid); + } if (vap->iv_opmode != IEEE80211_M_WDS) { /* NB: power management bit is never sent by an AP */ if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && @@ -603,7 +627,8 @@ IEEE80211_NODE_STAT(ni, tx_data); IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS, ni, - "send null data frame on channel %u, pwr mgt %s", + "send %snull data frame on channel %u, pwr mgt %s", + ni->ni_flags & IEEE80211_NODE_QOS ? "QoS " : "", ieee80211_chan2ieee(ic, ic->ic_curchan), wh->i_fc[1] & IEEE80211_FC1_PWR_MGT ? "ena" : "dis"); @@ -1751,8 +1776,8 @@ wh = mtod(m, struct ieee80211_frame *); ieee80211_send_setup(ni, wh, - IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ, - sa, da, bssid); + IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ, + IEEE80211_NONQOS_TID, sa, da, bssid); /* XXX power management? */ m->m_flags |= M_ENCAP; /* mark encapsulated */ @@ -2341,8 +2366,8 @@ wh = mtod(m, struct ieee80211_frame *); ieee80211_send_setup(bss, wh, - IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP, - vap->iv_myaddr, da, bss->ni_bssid); + IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP, + IEEE80211_NONQOS_TID, vap->iv_myaddr, da, bss->ni_bssid); /* XXX power management? */ m->m_flags |= M_ENCAP; /* mark encapsulated */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810032126.m93LQ9fD090638>