Deleted Added
full compact
ieee80211_ht.c (234018) ieee80211_ht.c (234324)
1/*-
2 * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27#ifdef __FreeBSD__
1/*-
2 * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <sys/cdefs.h>
27#ifdef __FreeBSD__
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ht.c 234018 2012-04-08 04:51:25Z adrian $");
28__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_ht.c 234324 2012-04-15 20:29:39Z adrian $");
29#endif
30
31/*
32 * IEEE 802.11n protocol support.
33 */
34
35#include "opt_inet.h"
36#include "opt_wlan.h"

--- 981 unchanged lines hidden (view full) ---

1018 * Setup HT-specific state in a node. Called only
1019 * when HT use is negotiated so we don't do extra
1020 * work for temporary and/or legacy sta's.
1021 */
1022void
1023ieee80211_ht_node_init(struct ieee80211_node *ni)
1024{
1025 struct ieee80211_tx_ampdu *tap;
29#endif
30
31/*
32 * IEEE 802.11n protocol support.
33 */
34
35#include "opt_inet.h"
36#include "opt_wlan.h"

--- 981 unchanged lines hidden (view full) ---

1018 * Setup HT-specific state in a node. Called only
1019 * when HT use is negotiated so we don't do extra
1020 * work for temporary and/or legacy sta's.
1021 */
1022void
1023ieee80211_ht_node_init(struct ieee80211_node *ni)
1024{
1025 struct ieee80211_tx_ampdu *tap;
1026 int ac;
1026 int tid;
1027
1028 if (ni->ni_flags & IEEE80211_NODE_HT) {
1029 /*
1030 * Clean AMPDU state on re-associate. This handles the case
1031 * where a station leaves w/o notifying us and then returns
1032 * before node is reaped for inactivity.
1033 */
1034 ieee80211_ht_node_cleanup(ni);
1035 }
1027
1028 if (ni->ni_flags & IEEE80211_NODE_HT) {
1029 /*
1030 * Clean AMPDU state on re-associate. This handles the case
1031 * where a station leaves w/o notifying us and then returns
1032 * before node is reaped for inactivity.
1033 */
1034 ieee80211_ht_node_cleanup(ni);
1035 }
1036 for (ac = 0; ac < WME_NUM_AC; ac++) {
1037 tap = &ni->ni_tx_ampdu[ac];
1038 tap->txa_ac = ac;
1036 for (tid = 0; tid < WME_NUM_TID; tid++) {
1037 tap = &ni->ni_tx_ampdu[tid];
1038 tap->txa_tid = tid;
1039 tap->txa_ni = ni;
1040 /* NB: further initialization deferred */
1041 }
1042 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
1043}
1044
1045/*
1046 * Cleanup HT-specific state in a node. Called only
1047 * when HT use has been marked.
1048 */
1049void
1050ieee80211_ht_node_cleanup(struct ieee80211_node *ni)
1051{
1052 struct ieee80211com *ic = ni->ni_ic;
1053 int i;
1054
1055 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT node"));
1056
1057 /* XXX optimize this */
1039 tap->txa_ni = ni;
1040 /* NB: further initialization deferred */
1041 }
1042 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
1043}
1044
1045/*
1046 * Cleanup HT-specific state in a node. Called only
1047 * when HT use has been marked.
1048 */
1049void
1050ieee80211_ht_node_cleanup(struct ieee80211_node *ni)
1051{
1052 struct ieee80211com *ic = ni->ni_ic;
1053 int i;
1054
1055 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT node"));
1056
1057 /* XXX optimize this */
1058 for (i = 0; i < WME_NUM_AC; i++) {
1058 for (i = 0; i < WME_NUM_TID; i++) {
1059 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[i];
1060 if (tap->txa_flags & IEEE80211_AGGR_SETUP)
1061 ampdu_tx_stop(tap);
1062 }
1063 for (i = 0; i < WME_NUM_TID; i++)
1064 ic->ic_ampdu_rx_stop(ni, &ni->ni_rx_ampdu[i]);
1065
1066 ni->ni_htcap = 0;

--- 88 unchanged lines hidden (view full) ---

1155/*
1156 * Setup HT-specific state for a legacy WDS peer.
1157 */
1158void
1159ieee80211_ht_wds_init(struct ieee80211_node *ni)
1160{
1161 struct ieee80211vap *vap = ni->ni_vap;
1162 struct ieee80211_tx_ampdu *tap;
1059 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[i];
1060 if (tap->txa_flags & IEEE80211_AGGR_SETUP)
1061 ampdu_tx_stop(tap);
1062 }
1063 for (i = 0; i < WME_NUM_TID; i++)
1064 ic->ic_ampdu_rx_stop(ni, &ni->ni_rx_ampdu[i]);
1065
1066 ni->ni_htcap = 0;

--- 88 unchanged lines hidden (view full) ---

1155/*
1156 * Setup HT-specific state for a legacy WDS peer.
1157 */
1158void
1159ieee80211_ht_wds_init(struct ieee80211_node *ni)
1160{
1161 struct ieee80211vap *vap = ni->ni_vap;
1162 struct ieee80211_tx_ampdu *tap;
1163 int ac;
1163 int tid;
1164
1165 KASSERT(vap->iv_flags_ht & IEEE80211_FHT_HT, ("no HT requested"));
1166
1167 /* XXX check scan cache in case peer has an ap and we have info */
1168 /*
1169 * If setup with a legacy channel; locate an HT channel.
1170 * Otherwise if the inherited channel (from a companion
1171 * AP) is suitable use it so we use the same location

--- 21 unchanged lines hidden (view full) ---

1193 ni->ni_htctlchan = ni->ni_chan->ic_ieee;
1194 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS)
1195 ni->ni_flags |= IEEE80211_NODE_RIFS;
1196 /* XXX does it make sense to enable SMPS? */
1197
1198 ni->ni_htopmode = 0; /* XXX need protection state */
1199 ni->ni_htstbc = 0; /* XXX need info */
1200
1164
1165 KASSERT(vap->iv_flags_ht & IEEE80211_FHT_HT, ("no HT requested"));
1166
1167 /* XXX check scan cache in case peer has an ap and we have info */
1168 /*
1169 * If setup with a legacy channel; locate an HT channel.
1170 * Otherwise if the inherited channel (from a companion
1171 * AP) is suitable use it so we use the same location

--- 21 unchanged lines hidden (view full) ---

1193 ni->ni_htctlchan = ni->ni_chan->ic_ieee;
1194 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS)
1195 ni->ni_flags |= IEEE80211_NODE_RIFS;
1196 /* XXX does it make sense to enable SMPS? */
1197
1198 ni->ni_htopmode = 0; /* XXX need protection state */
1199 ni->ni_htstbc = 0; /* XXX need info */
1200
1201 for (ac = 0; ac < WME_NUM_AC; ac++) {
1202 tap = &ni->ni_tx_ampdu[ac];
1203 tap->txa_ac = ac;
1201 for (tid = 0; tid < WME_NUM_TID; tid++) {
1202 tap = &ni->ni_tx_ampdu[tid];
1203 tap->txa_tid = tid;
1204 }
1205 /* NB: AMPDU tx/rx governed by IEEE80211_FHT_AMPDU_{TX,RX} */
1206 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
1207}
1208
1209/*
1210 * Notify hostap vaps of a change in the HTINFO ie.
1211 */

--- 468 unchanged lines hidden (view full) ---

1680
1681static void
1682ampdu_tx_stop(struct ieee80211_tx_ampdu *tap)
1683{
1684 struct ieee80211_node *ni = tap->txa_ni;
1685 struct ieee80211com *ic = ni->ni_ic;
1686
1687 KASSERT(tap->txa_flags & IEEE80211_AGGR_SETUP,
1204 }
1205 /* NB: AMPDU tx/rx governed by IEEE80211_FHT_AMPDU_{TX,RX} */
1206 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
1207}
1208
1209/*
1210 * Notify hostap vaps of a change in the HTINFO ie.
1211 */

--- 468 unchanged lines hidden (view full) ---

1680
1681static void
1682ampdu_tx_stop(struct ieee80211_tx_ampdu *tap)
1683{
1684 struct ieee80211_node *ni = tap->txa_ni;
1685 struct ieee80211com *ic = ni->ni_ic;
1686
1687 KASSERT(tap->txa_flags & IEEE80211_AGGR_SETUP,
1688 ("txa_flags 0x%x ac %d", tap->txa_flags, tap->txa_ac));
1688 ("txa_flags 0x%x tid %d ac %d", tap->txa_flags, tap->txa_tid,
1689 TID_TO_WME_AC(tap->txa_tid)));
1689
1690 /*
1691 * Stop BA stream if setup so driver has a chance
1692 * to reclaim any resources it might have allocated.
1693 */
1694 ic->ic_addba_stop(ni, tap);
1695 /*
1696 * Stop any pending BAR transmit.

--- 196 unchanged lines hidden (view full) ---

1893 const struct ieee80211_frame *wh,
1894 const uint8_t *frm, const uint8_t *efrm)
1895{
1896 struct ieee80211com *ic = ni->ni_ic;
1897 struct ieee80211vap *vap = ni->ni_vap;
1898 struct ieee80211_tx_ampdu *tap;
1899 uint8_t dialogtoken, policy;
1900 uint16_t baparamset, batimeout, code;
1690
1691 /*
1692 * Stop BA stream if setup so driver has a chance
1693 * to reclaim any resources it might have allocated.
1694 */
1695 ic->ic_addba_stop(ni, tap);
1696 /*
1697 * Stop any pending BAR transmit.

--- 196 unchanged lines hidden (view full) ---

1894 const struct ieee80211_frame *wh,
1895 const uint8_t *frm, const uint8_t *efrm)
1896{
1897 struct ieee80211com *ic = ni->ni_ic;
1898 struct ieee80211vap *vap = ni->ni_vap;
1899 struct ieee80211_tx_ampdu *tap;
1900 uint8_t dialogtoken, policy;
1901 uint16_t baparamset, batimeout, code;
1901 int tid, ac, bufsiz;
1902 int tid, bufsiz;
1902
1903 dialogtoken = frm[2];
1904 code = LE_READ_2(frm+3);
1905 baparamset = LE_READ_2(frm+5);
1906 tid = MS(baparamset, IEEE80211_BAPS_TID);
1907 bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
1908 policy = MS(baparamset, IEEE80211_BAPS_POLICY);
1909 batimeout = LE_READ_2(frm+7);
1910
1903
1904 dialogtoken = frm[2];
1905 code = LE_READ_2(frm+3);
1906 baparamset = LE_READ_2(frm+5);
1907 tid = MS(baparamset, IEEE80211_BAPS_TID);
1908 bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
1909 policy = MS(baparamset, IEEE80211_BAPS_POLICY);
1910 batimeout = LE_READ_2(frm+7);
1911
1911 ac = TID_TO_WME_AC(tid);
1912 tap = &ni->ni_tx_ampdu[ac];
1912 tap = &ni->ni_tx_ampdu[tid];
1913 if ((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0) {
1914 IEEE80211_DISCARD_MAC(vap,
1915 IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
1916 ni->ni_macaddr, "ADDBA response",
1917 "no pending ADDBA, tid %d dialogtoken %u "
1918 "code %d", tid, dialogtoken, code);
1919 vap->iv_stats.is_addba_norequest++;
1920 return 0;

--- 46 unchanged lines hidden (view full) ---

1967ht_recv_action_ba_delba(struct ieee80211_node *ni,
1968 const struct ieee80211_frame *wh,
1969 const uint8_t *frm, const uint8_t *efrm)
1970{
1971 struct ieee80211com *ic = ni->ni_ic;
1972 struct ieee80211_rx_ampdu *rap;
1973 struct ieee80211_tx_ampdu *tap;
1974 uint16_t baparamset, code;
1913 if ((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0) {
1914 IEEE80211_DISCARD_MAC(vap,
1915 IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
1916 ni->ni_macaddr, "ADDBA response",
1917 "no pending ADDBA, tid %d dialogtoken %u "
1918 "code %d", tid, dialogtoken, code);
1919 vap->iv_stats.is_addba_norequest++;
1920 return 0;

--- 46 unchanged lines hidden (view full) ---

1967ht_recv_action_ba_delba(struct ieee80211_node *ni,
1968 const struct ieee80211_frame *wh,
1969 const uint8_t *frm, const uint8_t *efrm)
1970{
1971 struct ieee80211com *ic = ni->ni_ic;
1972 struct ieee80211_rx_ampdu *rap;
1973 struct ieee80211_tx_ampdu *tap;
1974 uint16_t baparamset, code;
1975 int tid, ac;
1975 int tid;
1976
1977 baparamset = LE_READ_2(frm+2);
1978 code = LE_READ_2(frm+4);
1979
1980 tid = MS(baparamset, IEEE80211_DELBAPS_TID);
1981
1982 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
1983 "recv DELBA: baparamset 0x%x (tid %d initiator %d) "
1984 "code %d", baparamset, tid,
1985 MS(baparamset, IEEE80211_DELBAPS_INIT), code);
1986
1987 if ((baparamset & IEEE80211_DELBAPS_INIT) == 0) {
1976
1977 baparamset = LE_READ_2(frm+2);
1978 code = LE_READ_2(frm+4);
1979
1980 tid = MS(baparamset, IEEE80211_DELBAPS_TID);
1981
1982 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
1983 "recv DELBA: baparamset 0x%x (tid %d initiator %d) "
1984 "code %d", baparamset, tid,
1985 MS(baparamset, IEEE80211_DELBAPS_INIT), code);
1986
1987 if ((baparamset & IEEE80211_DELBAPS_INIT) == 0) {
1988 ac = TID_TO_WME_AC(tid);
1989 tap = &ni->ni_tx_ampdu[ac];
1988 tap = &ni->ni_tx_ampdu[tid];
1990 ic->ic_addba_stop(ni, tap);
1991 } else {
1992 rap = &ni->ni_rx_ampdu[tid];
1993 ic->ic_ampdu_rx_stop(ni, rap);
1994 }
1995 return 0;
1996}
1997

--- 55 unchanged lines hidden (view full) ---

2053 * such as link state conditions in making the decision.
2054 */
2055static int
2056ieee80211_ampdu_enable(struct ieee80211_node *ni,
2057 struct ieee80211_tx_ampdu *tap)
2058{
2059 struct ieee80211vap *vap = ni->ni_vap;
2060
1989 ic->ic_addba_stop(ni, tap);
1990 } else {
1991 rap = &ni->ni_rx_ampdu[tid];
1992 ic->ic_ampdu_rx_stop(ni, rap);
1993 }
1994 return 0;
1995}
1996

--- 55 unchanged lines hidden (view full) ---

2052 * such as link state conditions in making the decision.
2053 */
2054static int
2055ieee80211_ampdu_enable(struct ieee80211_node *ni,
2056 struct ieee80211_tx_ampdu *tap)
2057{
2058 struct ieee80211vap *vap = ni->ni_vap;
2059
2061 if (tap->txa_avgpps < vap->iv_ampdu_mintraffic[tap->txa_ac])
2060 if (tap->txa_avgpps <
2061 vap->iv_ampdu_mintraffic[TID_TO_WME_AC(tap->txa_tid)])
2062 return 0;
2063 /* XXX check rssi? */
2064 if (tap->txa_attempts >= ieee80211_addba_maxtries &&
2065 ticks < tap->txa_nextrequest) {
2066 /*
2067 * Don't retry too often; txa_nextrequest is set
2068 * to the minimum interval we'll retry after
2069 * ieee80211_addba_maxtries failed attempts are made.
2070 */
2071 return 0;
2072 }
2073 IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
2062 return 0;
2063 /* XXX check rssi? */
2064 if (tap->txa_attempts >= ieee80211_addba_maxtries &&
2065 ticks < tap->txa_nextrequest) {
2066 /*
2067 * Don't retry too often; txa_nextrequest is set
2068 * to the minimum interval we'll retry after
2069 * ieee80211_addba_maxtries failed attempts are made.
2070 */
2071 return 0;
2072 }
2073 IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
2074 "enable AMPDU on %s, avgpps %d pkts %d",
2075 ieee80211_wme_acnames[tap->txa_ac], tap->txa_avgpps, tap->txa_pkts);
2074 "enable AMPDU on tid %d (%s), avgpps %d pkts %d",
2075 tap->txa_tid, ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)],
2076 tap->txa_avgpps, tap->txa_pkts);
2076 return 1;
2077}
2078
2079/*
2080 * Request A-MPDU tx aggregation. Setup local state and
2081 * issue an ADDBA request. BA use will only happen after
2082 * the other end replies with ADDBA response.
2083 */

--- 10 unchanged lines hidden (view full) ---

2094 if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) {
2095 /* do deferred setup of state */
2096 ampdu_tx_setup(tap);
2097 }
2098 /* XXX hack for not doing proper locking */
2099 tap->txa_flags &= ~IEEE80211_AGGR_NAK;
2100
2101 dialogtoken = (tokens+1) % 63; /* XXX */
2077 return 1;
2078}
2079
2080/*
2081 * Request A-MPDU tx aggregation. Setup local state and
2082 * issue an ADDBA request. BA use will only happen after
2083 * the other end replies with ADDBA response.
2084 */

--- 10 unchanged lines hidden (view full) ---

2095 if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) {
2096 /* do deferred setup of state */
2097 ampdu_tx_setup(tap);
2098 }
2099 /* XXX hack for not doing proper locking */
2100 tap->txa_flags &= ~IEEE80211_AGGR_NAK;
2101
2102 dialogtoken = (tokens+1) % 63; /* XXX */
2102 tid = WME_AC_TO_TID(tap->txa_ac);
2103 tid = tap->txa_tid;
2103 tap->txa_start = ni->ni_txseqs[tid];
2104
2105 args[0] = dialogtoken;
2106 args[1] = 0; /* NB: status code not used */
2107 args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE
2108 | SM(tid, IEEE80211_BAPS_TID)
2109 | SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ)
2110 ;
2111 args[3] = 0; /* batimeout */
2112 /* NB: do first so there's no race against reply */
2113 if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) {
2114 /* unable to setup state, don't make request */
2115 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2104 tap->txa_start = ni->ni_txseqs[tid];
2105
2106 args[0] = dialogtoken;
2107 args[1] = 0; /* NB: status code not used */
2108 args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE
2109 | SM(tid, IEEE80211_BAPS_TID)
2110 | SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ)
2111 ;
2112 args[3] = 0; /* batimeout */
2113 /* NB: do first so there's no race against reply */
2114 if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) {
2115 /* unable to setup state, don't make request */
2116 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2116 ni, "%s: could not setup BA stream for AC %d",
2117 __func__, tap->txa_ac);
2117 ni, "%s: could not setup BA stream for TID %d AC %d",
2118 __func__, tap->txa_tid, TID_TO_WME_AC(tap->txa_tid));
2118 /* defer next try so we don't slam the driver with requests */
2119 tap->txa_attempts = ieee80211_addba_maxtries;
2120 /* NB: check in case driver wants to override */
2121 if (tap->txa_nextrequest <= ticks)
2122 tap->txa_nextrequest = ticks + ieee80211_addba_backoff;
2123 return 0;
2124 }
2125 tokens = dialogtoken; /* allocate token */

--- 16 unchanged lines hidden (view full) ---

2142 struct ieee80211com *ic = ni->ni_ic;
2143 struct ieee80211vap *vap = ni->ni_vap;
2144 uint16_t args[4];
2145
2146 /* XXX locking */
2147 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
2148 if (IEEE80211_AMPDU_RUNNING(tap)) {
2149 IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
2119 /* defer next try so we don't slam the driver with requests */
2120 tap->txa_attempts = ieee80211_addba_maxtries;
2121 /* NB: check in case driver wants to override */
2122 if (tap->txa_nextrequest <= ticks)
2123 tap->txa_nextrequest = ticks + ieee80211_addba_backoff;
2124 return 0;
2125 }
2126 tokens = dialogtoken; /* allocate token */

--- 16 unchanged lines hidden (view full) ---

2143 struct ieee80211com *ic = ni->ni_ic;
2144 struct ieee80211vap *vap = ni->ni_vap;
2145 uint16_t args[4];
2146
2147 /* XXX locking */
2148 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
2149 if (IEEE80211_AMPDU_RUNNING(tap)) {
2150 IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
2150 ni, "%s: stop BA stream for AC %d (reason %d)",
2151 __func__, tap->txa_ac, reason);
2151 ni, "%s: stop BA stream for TID %d (reason %d)",
2152 __func__, tap->txa_tid, reason);
2152 vap->iv_stats.is_ampdu_stop++;
2153
2154 ic->ic_addba_stop(ni, tap);
2153 vap->iv_stats.is_ampdu_stop++;
2154
2155 ic->ic_addba_stop(ni, tap);
2155 args[0] = WME_AC_TO_TID(tap->txa_ac);
2156 args[0] = tap->txa_tid;
2156 args[1] = IEEE80211_DELBAPS_INIT;
2157 args[2] = reason; /* XXX reason code */
2158 ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
2159 IEEE80211_ACTION_BA_DELBA, args);
2160 } else {
2161 IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
2157 args[1] = IEEE80211_DELBAPS_INIT;
2158 args[2] = reason; /* XXX reason code */
2159 ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
2160 IEEE80211_ACTION_BA_DELBA, args);
2161 } else {
2162 IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
2162 ni, "%s: BA stream for AC %d not running (reason %d)",
2163 __func__, tap->txa_ac, reason);
2163 ni, "%s: BA stream for TID %d not running (reason %d)",
2164 __func__, tap->txa_tid, reason);
2164 vap->iv_stats.is_ampdu_stop_failed++;
2165 }
2166}
2167
2168static void
2169bar_timeout(void *arg)
2170{
2171 struct ieee80211_tx_ampdu *tap = arg;
2172 struct ieee80211_node *ni = tap->txa_ni;
2173
2174 KASSERT((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0,
2175 ("bar/addba collision, flags 0x%x", tap->txa_flags));
2176
2177 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2178 ni, "%s: tid %u flags 0x%x attempts %d", __func__,
2165 vap->iv_stats.is_ampdu_stop_failed++;
2166 }
2167}
2168
2169static void
2170bar_timeout(void *arg)
2171{
2172 struct ieee80211_tx_ampdu *tap = arg;
2173 struct ieee80211_node *ni = tap->txa_ni;
2174
2175 KASSERT((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0,
2176 ("bar/addba collision, flags 0x%x", tap->txa_flags));
2177
2178 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2179 ni, "%s: tid %u flags 0x%x attempts %d", __func__,
2179 tap->txa_ac, tap->txa_flags, tap->txa_attempts);
2180 tap->txa_tid, tap->txa_flags, tap->txa_attempts);
2180
2181 /* guard against race with bar_tx_complete */
2182 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0)
2183 return;
2184 /* XXX ? */
2185 if (tap->txa_attempts >= ieee80211_bar_maxtries) {
2186 ni->ni_vap->iv_stats.is_ampdu_bar_tx_fail++;
2187 ieee80211_ampdu_stop(ni, tap, IEEE80211_REASON_TIMEOUT);

--- 17 unchanged lines hidden (view full) ---

2205
2206static void
2207bar_tx_complete(struct ieee80211_node *ni, void *arg, int status)
2208{
2209 struct ieee80211_tx_ampdu *tap = arg;
2210
2211 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2212 ni, "%s: tid %u flags 0x%x pending %d status %d",
2181
2182 /* guard against race with bar_tx_complete */
2183 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0)
2184 return;
2185 /* XXX ? */
2186 if (tap->txa_attempts >= ieee80211_bar_maxtries) {
2187 ni->ni_vap->iv_stats.is_ampdu_bar_tx_fail++;
2188 ieee80211_ampdu_stop(ni, tap, IEEE80211_REASON_TIMEOUT);

--- 17 unchanged lines hidden (view full) ---

2206
2207static void
2208bar_tx_complete(struct ieee80211_node *ni, void *arg, int status)
2209{
2210 struct ieee80211_tx_ampdu *tap = arg;
2211
2212 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2213 ni, "%s: tid %u flags 0x%x pending %d status %d",
2213 __func__, tap->txa_ac, tap->txa_flags,
2214 __func__, tap->txa_tid, tap->txa_flags,
2214 callout_pending(&tap->txa_timer), status);
2215
2216 ni->ni_vap->iv_stats.is_ampdu_bar_tx++;
2217 /* XXX locking */
2218 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) &&
2219 callout_pending(&tap->txa_timer)) {
2220 struct ieee80211com *ic = ni->ni_ic;
2221

--- 10 unchanged lines hidden (view full) ---

2232{
2233
2234 if (status == 0) { /* got ACK */
2235 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2236 ni, "BAR moves BA win <%u:%u> (%u frames) txseq %u tid %u",
2237 tap->txa_start,
2238 IEEE80211_SEQ_ADD(tap->txa_start, tap->txa_wnd-1),
2239 tap->txa_qframes, tap->txa_seqpending,
2215 callout_pending(&tap->txa_timer), status);
2216
2217 ni->ni_vap->iv_stats.is_ampdu_bar_tx++;
2218 /* XXX locking */
2219 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) &&
2220 callout_pending(&tap->txa_timer)) {
2221 struct ieee80211com *ic = ni->ni_ic;
2222

--- 10 unchanged lines hidden (view full) ---

2233{
2234
2235 if (status == 0) { /* got ACK */
2236 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2237 ni, "BAR moves BA win <%u:%u> (%u frames) txseq %u tid %u",
2238 tap->txa_start,
2239 IEEE80211_SEQ_ADD(tap->txa_start, tap->txa_wnd-1),
2240 tap->txa_qframes, tap->txa_seqpending,
2240 WME_AC_TO_TID(tap->txa_ac));
2241 tap->txa_tid);
2241
2242 /* NB: timer already stopped in bar_tx_complete */
2243 tap->txa_start = tap->txa_seqpending;
2244 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
2245 }
2246}
2247
2248/*

--- 38 unchanged lines hidden (view full) ---

2287
2288 bar = mtod(m, struct ieee80211_frame_bar *);
2289 bar->i_fc[0] = IEEE80211_FC0_VERSION_0 |
2290 IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR;
2291 bar->i_fc[1] = 0;
2292 IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr);
2293 IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr);
2294
2242
2243 /* NB: timer already stopped in bar_tx_complete */
2244 tap->txa_start = tap->txa_seqpending;
2245 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
2246 }
2247}
2248
2249/*

--- 38 unchanged lines hidden (view full) ---

2288
2289 bar = mtod(m, struct ieee80211_frame_bar *);
2290 bar->i_fc[0] = IEEE80211_FC0_VERSION_0 |
2291 IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR;
2292 bar->i_fc[1] = 0;
2293 IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr);
2294 IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr);
2295
2295 tid = WME_AC_TO_TID(tap->txa_ac);
2296 tid = tap->txa_tid;
2296 barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ?
2297 0 : IEEE80211_BAR_NOACK)
2298 | IEEE80211_BAR_COMP
2299 | SM(tid, IEEE80211_BAR_TID)
2300 ;
2301 barseqctl = SM(seq, IEEE80211_BAR_SEQ_START);
2302 /* NB: known to have proper alignment */
2303 bar->i_ctl = htole16(barctl);

--- 492 unchanged lines hidden ---
2297 barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ?
2298 0 : IEEE80211_BAR_NOACK)
2299 | IEEE80211_BAR_COMP
2300 | SM(tid, IEEE80211_BAR_TID)
2301 ;
2302 barseqctl = SM(seq, IEEE80211_BAR_SEQ_START);
2303 /* NB: known to have proper alignment */
2304 bar->i_ctl = htole16(barctl);

--- 492 unchanged lines hidden ---