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 --- |