Lines Matching +full:touch +full:- +full:timeout +full:- +full:ms

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
132 static int ieee80211_ampdu_age = -1; /* threshold for ampdu reorder q (ms) */
136 "AMPDU max reorder age (ms)");
142 static int ieee80211_addba_timeout = -1;/* timeout for ADDBA response */
146 "ADDBA request timeout (ms)");
147 static int ieee80211_addba_backoff = -1;/* backoff after max ADDBA requests */
151 "ADDBA request backoff (ms)");
156 static int ieee80211_bar_timeout = -1; /* timeout waiting for BAR response */
229 ic->ic_recv_action = ieee80211_recv_action; in ieee80211_ht_attach()
230 ic->ic_send_action = ieee80211_send_action; in ieee80211_ht_attach()
231 ic->ic_ampdu_enable = ieee80211_ampdu_enable; in ieee80211_ht_attach()
232 ic->ic_addba_request = ieee80211_addba_request; in ieee80211_ht_attach()
233 ic->ic_addba_response = ieee80211_addba_response; in ieee80211_ht_attach()
234 ic->ic_addba_response_timeout = null_addba_response_timeout; in ieee80211_ht_attach()
235 ic->ic_addba_stop = ieee80211_addba_stop; in ieee80211_ht_attach()
236 ic->ic_bar_response = ieee80211_bar_response; in ieee80211_ht_attach()
237 ic->ic_ampdu_rx_start = ampdu_rx_start; in ieee80211_ht_attach()
238 ic->ic_ampdu_rx_stop = ampdu_rx_stop; in ieee80211_ht_attach()
240 ic->ic_htprotmode = IEEE80211_PROT_RTSCTS; in ieee80211_ht_attach()
241 ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_PURE; in ieee80211_ht_attach()
254 vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_8K; in ieee80211_ht_vattach()
255 vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_NA; in ieee80211_ht_vattach()
256 vap->iv_ampdu_limit = vap->iv_ampdu_rxmax; in ieee80211_ht_vattach()
257 vap->iv_amsdu_limit = vap->iv_htcaps & IEEE80211_HTCAP_MAXAMSDU; in ieee80211_ht_vattach()
259 vap->iv_ampdu_mintraffic[WME_AC_BK] = 128; in ieee80211_ht_vattach()
260 vap->iv_ampdu_mintraffic[WME_AC_BE] = 64; in ieee80211_ht_vattach()
261 vap->iv_ampdu_mintraffic[WME_AC_VO] = 32; in ieee80211_ht_vattach()
262 vap->iv_ampdu_mintraffic[WME_AC_VI] = 32; in ieee80211_ht_vattach()
264 vap->iv_htprotmode = IEEE80211_PROT_RTSCTS; in ieee80211_ht_vattach()
265 vap->iv_curhtprotmode = IEEE80211_HTINFO_OPMODE_PURE; in ieee80211_ht_vattach()
267 if (vap->iv_htcaps & IEEE80211_HTC_HT) { in ieee80211_ht_vattach()
269 * Device is HT capable; enable all HT-related in ieee80211_ht_vattach()
273 vap->iv_flags_ht |= IEEE80211_FHT_HT in ieee80211_ht_vattach()
276 if (vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI20) in ieee80211_ht_vattach()
277 vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI20; in ieee80211_ht_vattach()
279 if (vap->iv_htcaps & IEEE80211_HTCAP_CHWIDTH40) { in ieee80211_ht_vattach()
280 vap->iv_flags_ht |= IEEE80211_FHT_USEHT40; in ieee80211_ht_vattach()
281 if (vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI40) in ieee80211_ht_vattach()
282 vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI40; in ieee80211_ht_vattach()
285 if (vap->iv_htcaps & IEEE80211_HTC_RIFS) in ieee80211_ht_vattach()
286 vap->iv_flags_ht |= IEEE80211_FHT_RIFS; in ieee80211_ht_vattach()
288 /* NB: A-MPDU and A-MSDU rx are mandated, these are tx only */ in ieee80211_ht_vattach()
289 vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_RX; in ieee80211_ht_vattach()
290 if (vap->iv_htcaps & IEEE80211_HTC_AMPDU) in ieee80211_ht_vattach()
291 vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_TX; in ieee80211_ht_vattach()
292 vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_RX; in ieee80211_ht_vattach()
293 if (vap->iv_htcaps & IEEE80211_HTC_AMSDU) in ieee80211_ht_vattach()
294 vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_TX; in ieee80211_ht_vattach()
296 if (vap->iv_htcaps & IEEE80211_HTCAP_TXSTBC) in ieee80211_ht_vattach()
297 vap->iv_flags_ht |= IEEE80211_FHT_STBC_TX; in ieee80211_ht_vattach()
298 if (vap->iv_htcaps & IEEE80211_HTCAP_RXSTBC) in ieee80211_ht_vattach()
299 vap->iv_flags_ht |= IEEE80211_FHT_STBC_RX; in ieee80211_ht_vattach()
301 if (vap->iv_htcaps & IEEE80211_HTCAP_LDPC) in ieee80211_ht_vattach()
302 vap->iv_flags_ht |= IEEE80211_FHT_LDPC_RX; in ieee80211_ht_vattach()
303 if (vap->iv_htcaps & IEEE80211_HTC_TXLDPC) in ieee80211_ht_vattach()
304 vap->iv_flags_ht |= IEEE80211_FHT_LDPC_TX; in ieee80211_ht_vattach()
307 if (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY) in ieee80211_ht_vattach()
308 vap->iv_flags_ht &= ~IEEE80211_FHT_HT; in ieee80211_ht_vattach()
369 for (range = ranges; range->txstream != 0; range++) { in ht_rateprint()
370 if (ic->ic_txstream < range->txstream) in ht_rateprint()
372 if (range->htcapflags && in ht_rateprint()
373 (ic->ic_htcaps & range->htcapflags) == 0) in ht_rateprint()
375 if (ratetype < range->ratetype) in ht_rateprint()
377 minrate = ht_getrate(ic, range->minmcs, mode, ratetype); in ht_rateprint()
378 maxrate = ht_getrate(ic, range->maxmcs, mode, ratetype); in ht_rateprint()
379 if (range->maxmcs) { in ht_rateprint()
380 ic_printf(ic, "MCS %d-%d: %d%sMbps - %d%sMbps\n", in ht_rateprint()
381 range->minmcs, range->maxmcs, in ht_rateprint()
385 ic_printf(ic, "MCS %d: %d%sMbps\n", range->minmcs, in ht_rateprint()
398 if (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) { in ht_announce()
402 if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) { in ht_announce()
406 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && in ht_announce()
407 (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) { in ht_announce()
417 if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) || in ieee80211_ht_announce()
418 isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) in ieee80211_ht_announce()
419 ic_printf(ic, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream); in ieee80211_ht_announce()
420 if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA)) in ieee80211_ht_announce()
422 if (isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) in ieee80211_ht_announce()
430 htrateset->rs_rates[htrateset->rs_nrates] = x; \ in ieee80211_init_suphtrates()
431 htrateset->rs_nrates++; \ in ieee80211_init_suphtrates()
433 struct ieee80211_htrateset *htrateset = &ic->ic_sup_htrates; in ieee80211_init_suphtrates()
437 for (i = 0; i < ic->ic_txstream * 8; i++) in ieee80211_init_suphtrates()
439 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && in ieee80211_init_suphtrates()
440 (ic->ic_htcaps & IEEE80211_HTC_TXMCS32)) in ieee80211_init_suphtrates()
442 if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) { in ieee80211_init_suphtrates()
443 if (ic->ic_txstream >= 2) { in ieee80211_init_suphtrates()
447 if (ic->ic_txstream >= 3) { in ieee80211_init_suphtrates()
451 if (ic->ic_txstream == 4) { in ieee80211_init_suphtrates()
464 * Decap the encapsulated A-MSDU frames and dispatch all but
471 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_decap_amsdu()
478 vap->iv_stats.is_amsdu_decap++; in ieee80211_decap_amsdu()
490 ni->ni_macaddr, "a-msdu", "%s", "decap failed"); in ieee80211_decap_amsdu()
491 vap->iv_stats.is_amsdu_tooshort++; in ieee80211_decap_amsdu()
494 if (m->m_pkthdr.len == framelen) in ieee80211_decap_amsdu()
499 ni->ni_macaddr, "a-msdu", in ieee80211_decap_amsdu()
501 vap->iv_stats.is_amsdu_split++; in ieee80211_decap_amsdu()
505 vap->iv_deliver_data(vap, ni, m); in ieee80211_decap_amsdu()
509 * is required to be aligned to a 4-byte boundary. in ieee80211_decap_amsdu()
512 m_adj(m, roundup2(framelen, 4) - framelen); /* padding */ in ieee80211_decap_amsdu()
524 m = mbufq_dequeue(&rap->rxa_mq[i]); in ampdu_rx_purge_slot()
527 rap->rxa_qbytes -= m->m_pkthdr.len; in ampdu_rx_purge_slot()
528 rap->rxa_qframes--; in ampdu_rx_purge_slot()
536 * For future offloaded A-MSDU handling where multiple frames with
548 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_add_slot()
562 * per-slot to know that we've finished receiving the frame list. in ampdu_rx_add_slot()
566 * end of the reassembly slot to see if its F_AMSDU w/ no F_AMSDU_MORE - in ampdu_rx_add_slot()
573 if (!mbufq_empty(&rap->rxa_mq[off])) { in ampdu_rx_add_slot()
574 rxs_final = ieee80211_get_rx_params_ptr(mbufq_last(&rap->rxa_mq[off])); in ampdu_rx_add_slot()
603 if (mbufq_empty(&rap->rxa_mq[off]) || (toss_dup == 0)) { in ampdu_rx_add_slot()
604 if (mbufq_enqueue(&rap->rxa_mq[off], m) != 0) { in ampdu_rx_add_slot()
606 ni->ni_macaddr, in ampdu_rx_add_slot()
607 "a-mpdu queue fail", in ampdu_rx_add_slot()
609 rxseq, tid, rap->rxa_start, in ampdu_rx_add_slot()
610 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ampdu_rx_add_slot()
612 mbufq_len(&rap->rxa_mq[off]), in ampdu_rx_add_slot()
613 rap->rxa_mq[off].mq_maxlen); in ampdu_rx_add_slot()
618 rap->rxa_qframes++; in ampdu_rx_add_slot()
619 rap->rxa_qbytes += m->m_pkthdr.len; in ampdu_rx_add_slot()
620 vap->iv_stats.is_ampdu_rx_reorder++; in ampdu_rx_add_slot()
635 ni->ni_macaddr, "a-mpdu duplicate", in ampdu_rx_add_slot()
637 rxseq, tid, rap->rxa_start, in ampdu_rx_add_slot()
638 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1)); in ampdu_rx_add_slot()
642 ni->ni_macaddr, "a-mpdu duplicate", in ampdu_rx_add_slot()
644 rxseq, tid, rxs->c_pktflags); in ampdu_rx_add_slot()
649 ni->ni_macaddr, "a-mpdu duplicate", in ampdu_rx_add_slot()
651 rxs_final->c_pktflags); in ampdu_rx_add_slot()
653 vap->iv_stats.is_rx_dup++; in ampdu_rx_add_slot()
663 * Purge all frames in the A-MPDU re-order queue.
670 for (i = 0; i < rap->rxa_wnd; i++) { in ampdu_rx_purge()
672 if (rap->rxa_qframes == 0) in ampdu_rx_purge()
675 KASSERT(rap->rxa_qbytes == 0 && rap->rxa_qframes == 0, in ampdu_rx_purge()
677 rap->rxa_qbytes, rap->rxa_qframes)); in ampdu_rx_purge()
689 mbufq_init(&rap->rxa_mq[i], 256); in ieee80211_ampdu_rx_init_rap()
693 * Start A-MPDU rx/re-order processing for the specified TID.
699 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_start()
702 if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) { in ampdu_rx_start()
710 rap->rxa_wnd = (bufsiz == 0) ? in ampdu_rx_start()
712 rap->rxa_start = _IEEE80211_MASKSHIFT(baseqctl, IEEE80211_BASEQ_START); in ampdu_rx_start()
713 rap->rxa_flags |= IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND; in ampdu_rx_start()
716 if ((vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU) && in ampdu_rx_start()
718 rap->rxa_flags |= IEEE80211_AGGR_AMSDU; in ampdu_rx_start()
720 rap->rxa_flags &= ~IEEE80211_AGGR_AMSDU; in ampdu_rx_start()
735 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ampdu_rx_start_ext()
737 if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) { in ieee80211_ampdu_rx_start_ext()
747 rap->rxa_wnd = (baw== 0) ? in ieee80211_ampdu_rx_start_ext()
749 if (seq == -1) { in ieee80211_ampdu_rx_start_ext()
751 rap->rxa_start = 0; in ieee80211_ampdu_rx_start_ext()
752 rap->rxa_flags |= IEEE80211_AGGR_WAITRX; in ieee80211_ampdu_rx_start_ext()
754 rap->rxa_start = seq; in ieee80211_ampdu_rx_start_ext()
756 rap->rxa_flags |= IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND; in ieee80211_ampdu_rx_start_ext()
760 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ieee80211_ampdu_rx_start_ext()
765 rap->rxa_wnd, in ieee80211_ampdu_rx_start_ext()
766 rap->rxa_flags); in ieee80211_ampdu_rx_start_ext()
780 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ampdu_rx_stop_ext()
785 * Stop A-MPDU rx processing for the specified TID.
792 rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING in ampdu_rx_stop()
798 * Dispatch a frame from the A-MPDU reorder queue. The
801 * permits ieee80211_input to optimize re-processing).
806 m->m_flags |= M_AMPDU_MPDU; /* bypass normal processing */ in ampdu_dispatch()
819 m = mbufq_dequeue(&rap->rxa_mq[i]); in ampdu_dispatch_slot()
824 rap->rxa_qbytes -= m->m_pkthdr.len; in ampdu_dispatch_slot()
825 rap->rxa_qframes--; in ampdu_dispatch_slot()
836 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_moveup()
842 if (rap->rxa_qframes != 0) { in ampdu_rx_moveup()
843 int n = rap->rxa_qframes, j; in ampdu_rx_moveup()
844 for (j = i+1; j < rap->rxa_wnd; j++) { in ampdu_rx_moveup()
849 if (mbufq_len(&rap->rxa_mq[j]) != 0) { in ampdu_rx_moveup()
850 n = n - mbufq_len(&rap->rxa_mq[j]); in ampdu_rx_moveup()
851 mbufq_concat(&rap->rxa_mq[j-i], &rap->rxa_mq[j]); in ampdu_rx_moveup()
859 __func__, n, rap->rxa_qframes, i, rap->rxa_start, in ampdu_rx_moveup()
860 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ampdu_rx_moveup()
862 vap->iv_stats.is_ampdu_rx_copy += rap->rxa_qframes; in ampdu_rx_moveup()
867 * Dispatch as many frames as possible from the re-order queue.
877 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_dispatch()
882 for (i = 1; i < rap->rxa_wnd; i++) { in ampdu_rx_dispatch()
890 ampdu_rx_moveup(rap, ni, i, -1); in ampdu_rx_dispatch()
896 rap->rxa_start = IEEE80211_SEQ_ADD(rap->rxa_start, i); in ampdu_rx_dispatch()
897 vap->iv_stats.is_ampdu_rx_oor += r2; in ampdu_rx_dispatch()
899 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ampdu_rx_dispatch()
903 rap->rxa_start, in ampdu_rx_dispatch()
908 * Dispatch all frames in the A-MPDU re-order queue.
915 for (i = 0; i < rap->rxa_wnd; i++) { in ampdu_rx_flush()
919 ni->ni_vap->iv_stats.is_ampdu_rx_oor += r; in ampdu_rx_flush()
921 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ampdu_rx_flush()
925 rap->rxa_start, in ampdu_rx_flush()
928 if (rap->rxa_qframes == 0) in ampdu_rx_flush()
934 * Dispatch all frames in the A-MPDU re-order queue
942 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_flush_upto()
953 seqno = rap->rxa_start; in ampdu_rx_flush_upto()
954 for (i = 0; i < rap->rxa_wnd; i++) { in ampdu_rx_flush_upto()
955 if ((r = mbufq_len(&rap->rxa_mq[i])) != 0) { in ampdu_rx_flush_upto()
961 vap->iv_stats.is_ampdu_rx_oor += r; in ampdu_rx_flush_upto()
964 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ampdu_rx_flush_upto()
984 rap->rxa_start = seqno; in ampdu_rx_flush_upto()
989 * A-MPDU reordering: if this frame is received out of order
995 * A-MSDU: handle hardware decap'ed A-MSDU frames that are
1005 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ampdu_reorder()
1014 KASSERT((m->m_flags & (M_AMPDU | M_AMPDU_MPDU)) == M_AMPDU, in ieee80211_ampdu_reorder()
1015 ("!a-mpdu or already re-ordered, flags 0x%x", m->m_flags)); in ieee80211_ampdu_reorder()
1016 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta")); in ieee80211_ampdu_reorder()
1029 * 802.11-2012 9.3.2.10 - Duplicate detection and recovery. in ieee80211_ampdu_reorder()
1032 * counter, not the per-TID counter. in ieee80211_ampdu_reorder()
1034 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) in ieee80211_ampdu_reorder()
1039 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ampdu_reorder()
1040 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { in ieee80211_ampdu_reorder()
1042 * No ADDBA request yet, don't touch. in ieee80211_ampdu_reorder()
1046 rxseq = le16toh(*(uint16_t *)wh->i_seq); in ieee80211_ampdu_reorder()
1052 IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, in ieee80211_ampdu_reorder()
1053 "A-MPDU", "fragment, rxseq 0x%x tid %u%s", rxseq, tid, in ieee80211_ampdu_reorder()
1054 wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); in ieee80211_ampdu_reorder()
1055 vap->iv_stats.is_ampdu_rx_drop++; in ieee80211_ampdu_reorder()
1061 rap->rxa_nframes++; in ieee80211_ampdu_reorder()
1068 if (rap->rxa_flags & IEEE80211_AGGR_WAITRX) { in ieee80211_ampdu_reorder()
1069 rap->rxa_flags &= ~IEEE80211_AGGR_WAITRX; in ieee80211_ampdu_reorder()
1070 rap->rxa_start = rxseq; in ieee80211_ampdu_reorder()
1073 if (rxseq == rap->rxa_start) { in ieee80211_ampdu_reorder()
1077 if (rap->rxa_qframes != 0) { in ieee80211_ampdu_reorder()
1081 KASSERT(mbufq_empty(&rap->rxa_mq[0]), ("unexpected dup")); in ieee80211_ampdu_reorder()
1092 rap->rxa_start = IEEE80211_SEQ_INC(rxseq); in ieee80211_ampdu_reorder()
1098 rap->rxa_start = IEEE80211_SEQ_INC(rxseq); in ieee80211_ampdu_reorder()
1107 off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start); in ieee80211_ampdu_reorder()
1108 if (off < rap->rxa_wnd) { in ieee80211_ampdu_reorder()
1131 if (rap->rxa_qframes != 0) { in ieee80211_ampdu_reorder()
1133 if (ticks - rap->rxa_age > ieee80211_ampdu_age) { in ieee80211_ampdu_reorder()
1138 if (rap->rxa_qframes != 0) { in ieee80211_ampdu_reorder()
1139 vap->iv_stats.is_ampdu_rx_age += in ieee80211_ampdu_reorder()
1140 rap->rxa_qframes; in ieee80211_ampdu_reorder()
1149 rap->rxa_start = in ieee80211_ampdu_reorder()
1158 rap->rxa_start = in ieee80211_ampdu_reorder()
1167 rap->rxa_age = ticks; in ieee80211_ampdu_reorder()
1170 /* save packet - this consumes, no matter what */ in ieee80211_ampdu_reorder()
1182 rap->rxa_start, in ieee80211_ampdu_reorder()
1183 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_ampdu_reorder()
1184 rap->rxa_qframes, rxseq, tid); in ieee80211_ampdu_reorder()
1185 vap->iv_stats.is_ampdu_rx_move++; in ieee80211_ampdu_reorder()
1189 * WinStart_B = rxseq - rap->rxa_wnd + 1 in ieee80211_ampdu_reorder()
1197 IEEE80211_SEQ_SUB(rxseq, rap->rxa_wnd-1)); in ieee80211_ampdu_reorder()
1205 IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, in ieee80211_ampdu_reorder()
1207 rap->rxa_start, in ieee80211_ampdu_reorder()
1208 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_ampdu_reorder()
1209 rap->rxa_qframes, rxseq, tid, in ieee80211_ampdu_reorder()
1210 wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); in ieee80211_ampdu_reorder()
1211 vap->iv_stats.is_ampdu_rx_drop++; in ieee80211_ampdu_reorder()
1228 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_recv_bar()
1237 ni->ni_macaddr, "BAR", "%s", "processing disabled"); in ieee80211_recv_bar()
1239 vap->iv_stats.is_ampdu_bar_bad++; in ieee80211_recv_bar()
1244 tid = _IEEE80211_MASKSHIFT(le16toh(wh->i_ctl), IEEE80211_BAR_TID); in ieee80211_recv_bar()
1245 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_recv_bar()
1246 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { in ieee80211_recv_bar()
1248 * No ADDBA request yet, don't touch. in ieee80211_recv_bar()
1252 ni->ni_macaddr, "BAR", "no BA stream, tid %u", tid); in ieee80211_recv_bar()
1253 vap->iv_stats.is_ampdu_bar_bad++; in ieee80211_recv_bar()
1256 vap->iv_stats.is_ampdu_bar_rx++; in ieee80211_recv_bar()
1257 rxseq = le16toh(wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; in ieee80211_recv_bar()
1258 if (rxseq == rap->rxa_start) in ieee80211_recv_bar()
1261 off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start); in ieee80211_recv_bar()
1269 rap->rxa_start, in ieee80211_recv_bar()
1270 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_recv_bar()
1271 rap->rxa_qframes, rxseq, tid); in ieee80211_recv_bar()
1272 vap->iv_stats.is_ampdu_bar_move++; in ieee80211_recv_bar()
1275 if (off >= rap->rxa_wnd) { in ieee80211_recv_bar()
1281 rap->rxa_start = rxseq; in ieee80211_recv_bar()
1289 IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, in ieee80211_recv_bar()
1291 rap->rxa_start, in ieee80211_recv_bar()
1292 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_recv_bar()
1293 rap->rxa_qframes, rxseq, tid, in ieee80211_recv_bar()
1294 wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); in ieee80211_recv_bar()
1295 vap->iv_stats.is_ampdu_bar_oow++; in ieee80211_recv_bar()
1301 * Setup HT-specific state in a node. Called only
1311 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ht_node_init()
1317 if (ni->ni_flags & IEEE80211_NODE_HT) { in ieee80211_ht_node_init()
1319 * Clean AMPDU state on re-associate. This handles the case in ieee80211_ht_node_init()
1323 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ht_node_init()
1330 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ht_node_init()
1331 tap->txa_tid = tid; in ieee80211_ht_node_init()
1332 tap->txa_ni = ni; in ieee80211_ht_node_init()
1335 ieee80211_ampdu_rx_init_rap(ni, &ni->ni_rx_ampdu[tid]); in ieee80211_ht_node_init()
1337 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU | in ieee80211_ht_node_init()
1342 * Cleanup HT-specific state in a node. Called only
1348 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ht_node_cleanup()
1351 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ht_node_cleanup()
1356 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT node")); in ieee80211_ht_node_cleanup()
1360 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[i]; in ieee80211_ht_node_cleanup()
1361 if (tap->txa_flags & IEEE80211_AGGR_SETUP) in ieee80211_ht_node_cleanup()
1365 ic->ic_ampdu_rx_stop(ni, &ni->ni_rx_ampdu[i]); in ieee80211_ht_node_cleanup()
1367 ni->ni_htcap = 0; in ieee80211_ht_node_cleanup()
1368 ni->ni_flags &= ~IEEE80211_NODE_HT_ALL; in ieee80211_ht_node_cleanup()
1377 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_node_age()
1380 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta")); in ieee80211_ht_node_age()
1385 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ht_node_age()
1386 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) in ieee80211_ht_node_age()
1388 if (rap->rxa_qframes == 0) in ieee80211_ht_node_age()
1395 if (ticks - rap->rxa_age > ieee80211_ampdu_age) { in ieee80211_ht_node_age()
1400 vap->iv_stats.is_ampdu_rx_age += rap->rxa_qframes; in ieee80211_ht_node_age()
1409 return ieee80211_find_channel(ic, c->ic_freq, in findhtchan()
1410 (c->ic_flags &~ IEEE80211_CHAN_HT) | htflags); in findhtchan()
1414 * Adjust a channel to be HT/non-HT according to the vap's configuration.
1426 /* NB: arbitrarily pick ht40+ over ht40- */ in ieee80211_ht_adjust_channel()
1444 c = ieee80211_find_channel(ic, chan->ic_freq, in ieee80211_ht_adjust_channel()
1445 chan->ic_flags &~ IEEE80211_CHAN_HT); in ieee80211_ht_adjust_channel()
1453 * Setup HT-specific state for a legacy WDS peer.
1458 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_wds_init()
1462 KASSERT(vap->iv_flags_ht & IEEE80211_FHT_HT, ("no HT requested")); in ieee80211_ht_wds_init()
1471 ni->ni_chan = ieee80211_ht_adjust_channel(ni->ni_ic, in ieee80211_ht_wds_init()
1472 ni->ni_chan, ieee80211_htchanflags(ni->ni_chan)); in ieee80211_ht_wds_init()
1474 ni->ni_htcap = 0; in ieee80211_ht_wds_init()
1475 if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) in ieee80211_ht_wds_init()
1476 ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI20; in ieee80211_ht_wds_init()
1477 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { in ieee80211_ht_wds_init()
1478 ni->ni_htcap |= IEEE80211_HTCAP_CHWIDTH40; in ieee80211_ht_wds_init()
1479 ni->ni_chw = IEEE80211_STA_RX_BW_40; in ieee80211_ht_wds_init()
1480 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan)) in ieee80211_ht_wds_init()
1481 ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_ABOVE; in ieee80211_ht_wds_init()
1482 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan)) in ieee80211_ht_wds_init()
1483 ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_BELOW; in ieee80211_ht_wds_init()
1484 if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) in ieee80211_ht_wds_init()
1485 ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI40; in ieee80211_ht_wds_init()
1487 ni->ni_chw = IEEE80211_STA_RX_BW_20; in ieee80211_ht_wds_init()
1488 ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_NONE; in ieee80211_ht_wds_init()
1490 ni->ni_htctlchan = ni->ni_chan->ic_ieee; in ieee80211_ht_wds_init()
1491 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) in ieee80211_ht_wds_init()
1492 ni->ni_flags |= IEEE80211_NODE_RIFS; in ieee80211_ht_wds_init()
1495 ni->ni_htopmode = 0; /* XXX need protection state */ in ieee80211_ht_wds_init()
1496 ni->ni_htstbc = 0; /* XXX need info */ in ieee80211_ht_wds_init()
1499 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ht_wds_init()
1500 tap->txa_tid = tid; in ieee80211_ht_wds_init()
1504 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU | in ieee80211_ht_wds_init()
1518 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_htinfo_notify()
1520 if (vap->iv_opmode != IEEE80211_M_HOSTAP) in ieee80211_htinfo_notify()
1522 if (vap->iv_state != IEEE80211_S_RUN || in ieee80211_htinfo_notify()
1523 !IEEE80211_IS_CHAN_HT(vap->iv_bss->ni_chan)) in ieee80211_htinfo_notify()
1528 vap->iv_bss, in ieee80211_htinfo_notify()
1531 , vap->iv_sta_assoc in ieee80211_htinfo_notify()
1532 , vap->iv_ht_sta_assoc in ieee80211_htinfo_notify()
1533 , vap->iv_ht40_sta_assoc in ieee80211_htinfo_notify()
1534 , (vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) ? in ieee80211_htinfo_notify()
1535 ", non-HT sta present" : "" in ieee80211_htinfo_notify()
1536 , vap->iv_curhtprotmode); in ieee80211_htinfo_notify()
1548 struct ieee80211com *ic = vap->iv_ic; in htinfo_update()
1551 if (vap->iv_sta_assoc != vap->iv_ht_sta_assoc) { in htinfo_update()
1554 } else if (vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) { in htinfo_update()
1557 } else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && in htinfo_update()
1558 IEEE80211_IS_CHAN_HT40(ic->ic_bsschan) && in htinfo_update()
1559 vap->iv_sta_assoc != vap->iv_ht40_sta_assoc) { in htinfo_update()
1564 if (protmode != vap->iv_curhtprotmode) { in htinfo_update()
1565 vap->iv_curhtprotmode = protmode; in htinfo_update()
1577 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_node_join()
1579 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_ht_node_join()
1581 if (ni->ni_flags & IEEE80211_NODE_HT) { in ieee80211_ht_node_join()
1582 vap->iv_ht_sta_assoc++; in ieee80211_ht_node_join()
1583 if (ni->ni_chw == IEEE80211_STA_RX_BW_40) in ieee80211_ht_node_join()
1584 vap->iv_ht40_sta_assoc++; in ieee80211_ht_node_join()
1595 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_node_leave()
1597 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_ht_node_leave()
1599 if (ni->ni_flags & IEEE80211_NODE_HT) { in ieee80211_ht_node_leave()
1600 vap->iv_ht_sta_assoc--; in ieee80211_ht_node_leave()
1601 if (ni->ni_chw == IEEE80211_STA_RX_BW_40) in ieee80211_ht_node_leave()
1602 vap->iv_ht40_sta_assoc--; in ieee80211_ht_node_leave()
1616 * change PROTOPT -> MIXED; only MIXED -> PROTOPT). This
1623 struct ieee80211com *ic = vap->iv_ic; in ieee80211_htprot_update()
1627 /* track non-HT station presence */ in ieee80211_htprot_update()
1630 vap->iv_flags_ht |= IEEE80211_FHT_NONHT_PR; in ieee80211_htprot_update()
1631 vap->iv_lastnonht = ticks; in ieee80211_htprot_update()
1633 if (protmode != vap->iv_curhtprotmode && in ieee80211_htprot_update()
1634 (OPMODE(vap->iv_curhtprotmode) != IEEE80211_HTINFO_OPMODE_MIXED || in ieee80211_htprot_update()
1636 vap->iv_curhtprotmode = protmode; in ieee80211_htprot_update()
1645 * Time out presence of an overlapping bss with non-HT
1647 * beacons from other stations and if we identify a non-HT
1649 * HTINFO ie. To identify when all non-HT stations are
1656 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_ht_timeout()
1658 if ((vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) && in ieee80211_ht_timeout()
1659 ieee80211_time_after(ticks, vap->iv_lastnonht + IEEE80211_NONHT_PRESENT_AGE)) { in ieee80211_ht_timeout()
1661 "%s", "time out non-HT STA present on channel"); in ieee80211_ht_timeout()
1662 vap->iv_flags_ht &= ~IEEE80211_FHT_NONHT_PR; in ieee80211_ht_timeout()
1679 ni->ni_flags |= IEEE80211_NODE_HTCOMPAT; in ieee80211_parse_htcap()
1682 ni->ni_flags &= ~IEEE80211_NODE_HTCOMPAT; in ieee80211_parse_htcap()
1684 ni->ni_htcap = le16dec(ie + in ieee80211_parse_htcap()
1686 ni->ni_htparam = ie[__offsetof(struct ieee80211_ie_htcap, hc_param)]; in ieee80211_parse_htcap()
1695 ni->ni_htctlchan = htinfo->hi_ctrlchannel; in htinfo_parse()
1696 ni->ni_ht2ndchan = _IEEE80211_SHIFTMASK(htinfo->hi_byte1, in htinfo_parse()
1698 w = le16dec(&htinfo->hi_byte2); in htinfo_parse()
1699 ni->ni_htopmode = _IEEE80211_SHIFTMASK(w, IEEE80211_HTINFO_OPMODE); in htinfo_parse()
1700 w = le16dec(&htinfo->hi_byte45); in htinfo_parse()
1701 ni->ni_htstbc = _IEEE80211_SHIFTMASK(w, IEEE80211_HTINFO_BASIC_STBCMCS); in htinfo_parse()
1732 struct ieee80211com *ic = ni->ni_ic; in htinfo_update_chw()
1738 * First step - do HT/VHT only channel lookup based on operating mode in htinfo_update_chw()
1743 chanflags = (ni->ni_chan->ic_flags &~ in htinfo_update_chw()
1746 if (chanflags == ni->ni_chan->ic_flags) in htinfo_update_chw()
1755 chanflags = (ni->ni_chan->ic_flags &~ in htinfo_update_chw()
1757 /* XXX not right for ht40- */ in htinfo_update_chw()
1758 c = ieee80211_find_channel(ic, ni->ni_chan->ic_freq, chanflags); in htinfo_update_chw()
1764 c = findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT20); in htinfo_update_chw()
1766 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1769 ni->ni_chan->ic_freq); in htinfo_update_chw()
1774 /* Nothing found - leave it alone; move onto VHT */ in htinfo_update_chw()
1776 c = ni->ni_chan; in htinfo_update_chw()
1779 * If it's non-HT, then bail out now. in htinfo_update_chw()
1782 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1785 c->ic_freq, c->ic_flags); in htinfo_update_chw()
1790 * Next step - look at the current VHT flags and determine in htinfo_update_chw()
1795 if (IEEE80211_CONF_VHT(ic) && ni->ni_vhtcap != 0 && vhtflags != 0) { in htinfo_update_chw()
1796 chanflags = (c->ic_flags in htinfo_update_chw()
1799 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1803 __func__, ni->ni_vht_chanwidth, vhtflags); in htinfo_update_chw()
1805 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1809 __func__, c->ic_freq, chanflags); in htinfo_update_chw()
1810 c = ieee80211_find_channel(ic, c->ic_freq, chanflags); in htinfo_update_chw()
1814 if (c != NULL && c != ni->ni_chan) { in htinfo_update_chw()
1815 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1821 c->ic_freq, c->ic_flags); in htinfo_update_chw()
1822 ni->ni_chan = c; in htinfo_update_chw()
1829 ni->ni_chw = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? in htinfo_update_chw()
1840 uint16_t oflags = ni->ni_flags; in htcap_update_mimo_ps()
1842 switch (ni->ni_htcap & IEEE80211_HTCAP_SMPS) { in htcap_update_mimo_ps()
1844 ni->ni_flags |= IEEE80211_NODE_MIMO_PS; in htcap_update_mimo_ps()
1845 ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; in htcap_update_mimo_ps()
1848 ni->ni_flags |= IEEE80211_NODE_MIMO_PS; in htcap_update_mimo_ps()
1849 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; in htcap_update_mimo_ps()
1853 ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; in htcap_update_mimo_ps()
1854 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; in htcap_update_mimo_ps()
1857 return (oflags ^ ni->ni_flags); in htcap_update_mimo_ps()
1867 struct ieee80211vap *vap = ni->ni_vap; in htcap_update_shortgi()
1869 ni->ni_flags &= ~(IEEE80211_NODE_SGI20|IEEE80211_NODE_SGI40); in htcap_update_shortgi()
1870 if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) && in htcap_update_shortgi()
1871 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20)) in htcap_update_shortgi()
1872 ni->ni_flags |= IEEE80211_NODE_SGI20; in htcap_update_shortgi()
1873 if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) && in htcap_update_shortgi()
1874 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40)) in htcap_update_shortgi()
1875 ni->ni_flags |= IEEE80211_NODE_SGI40; in htcap_update_shortgi()
1885 struct ieee80211vap *vap = ni->ni_vap; in htcap_update_ldpc()
1887 if ((ni->ni_htcap & IEEE80211_HTCAP_LDPC) && in htcap_update_ldpc()
1888 (vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX)) in htcap_update_ldpc()
1889 ni->ni_flags |= IEEE80211_NODE_LDPC; in htcap_update_ldpc()
1893 * Parse and update HT-related state extracted from
1905 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updateparams()
1909 if (vap->iv_htcaps & IEEE80211_HTC_SMPS) in ieee80211_ht_updateparams()
1924 if ((htinfo->hi_byte1 & IEEE80211_HTINFO_RIFSMODE_PERM) && in ieee80211_ht_updateparams()
1925 (vap->iv_flags_ht & IEEE80211_FHT_RIFS)) in ieee80211_ht_updateparams()
1926 ni->ni_flags |= IEEE80211_NODE_RIFS; in ieee80211_ht_updateparams()
1928 ni->ni_flags &= ~IEEE80211_NODE_RIFS; in ieee80211_ht_updateparams()
1936 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, \ in ieee80211_vht_get_vhtflags()
1947 vap = ni->ni_vap; in ieee80211_vht_get_vhtflags()
1950 if ((ni->ni_flags & IEEE80211_NODE_VHT) == 0 || in ieee80211_vht_get_vhtflags()
1951 (vap->iv_vht_flags & IEEE80211_FVHT_VHT) == 0) in ieee80211_vht_get_vhtflags()
1956 * 802.11ac-2013, Table 8-183x-VHT Operation Information subfields. in ieee80211_vht_get_vhtflags()
1957 * 802.11-2020, Table 9-274-VHT Operation Information subfields in ieee80211_vht_get_vhtflags()
1961 * 802.11-2020, 11.38.1 Basic VHT BSS functionality. in ieee80211_vht_get_vhtflags()
1964 htinfo = (const struct ieee80211_ie_htinfo *)ni->ni_ies.htinfo_ie; in ieee80211_vht_get_vhtflags()
1965 ht40 = ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH) == in ieee80211_vht_get_vhtflags()
1971 /* Check for the full valid combination -- other fields be 0. */ in ieee80211_vht_get_vhtflags()
1972 if (ni->ni_vht_chanwidth != IEEE80211_VHT_CHANWIDTH_USE_HT || in ieee80211_vht_get_vhtflags()
1973 ni->ni_vht_chan2 != 0) in ieee80211_vht_get_vhtflags()
1974 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ieee80211_vht_get_vhtflags()
1976 __func__, ni->ni_vht_chanwidth, in ieee80211_vht_get_vhtflags()
1977 ni->ni_vht_chan1, ni->ni_vht_chan2); in ieee80211_vht_get_vhtflags()
1991 if (ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_USE_HT) { in ieee80211_vht_get_vhtflags()
1992 if (ni->ni_vht_chan2 != 0) in ieee80211_vht_get_vhtflags()
1993 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ieee80211_vht_get_vhtflags()
1995 __func__, ni->ni_vht_chanwidth, in ieee80211_vht_get_vhtflags()
1996 ni->ni_vht_chan1, ni->ni_vht_chan2); in ieee80211_vht_get_vhtflags()
1998 if ((vap->iv_vht_flags & IEEE80211_FVHT_USEVHT40) != 0) { in ieee80211_vht_get_vhtflags()
2010 if ((ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ) && in ieee80211_vht_get_vhtflags()
2011 IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(vap->iv_vht_cap.vht_cap_info) && in ieee80211_vht_get_vhtflags()
2012 (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT160) != 0) in ieee80211_vht_get_vhtflags()
2016 if ((ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_80P80MHZ) && in ieee80211_vht_get_vhtflags()
2017 IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(vap->iv_vht_cap.vht_cap_info) && in ieee80211_vht_get_vhtflags()
2018 (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT80P80) != 0) in ieee80211_vht_get_vhtflags()
2021 if (ni->ni_vht_chanwidth != IEEE80211_VHT_CHANWIDTH_80MHZ) { in ieee80211_vht_get_vhtflags()
2022 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ieee80211_vht_get_vhtflags()
2024 ni->ni_vht_chanwidth, ni->ni_vht_chan2); in ieee80211_vht_get_vhtflags()
2029 /* CCFS1 > 0 and | CCFS1 - CCFS0 | = 8 */ in ieee80211_vht_get_vhtflags()
2030 if (ni->ni_vht_chan2 > 0 && (ni->ni_vht_chan2 - ni->ni_vht_chan1) == 8) in ieee80211_vht_get_vhtflags()
2033 /* CCFS1 > 0 and | CCFS1 - CCFS0 | > 16 */ in ieee80211_vht_get_vhtflags()
2034 if (ni->ni_vht_chan2 > 0 && (ni->ni_vht_chan2 - ni->ni_vht_chan1) > 16) in ieee80211_vht_get_vhtflags()
2038 if (ni->ni_vht_chan2 == 0) in ieee80211_vht_get_vhtflags()
2041 if (can_vht160 && (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT160) != 0) in ieee80211_vht_get_vhtflags()
2044 if (can_vht80p80 && (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT80P80) != 0) in ieee80211_vht_get_vhtflags()
2047 if (can_vht80 && (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT80) != 0) in ieee80211_vht_get_vhtflags()
2050 if (ht40 && (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT40) != 0) { in ieee80211_vht_get_vhtflags()
2073 * is called - which will change the channel config for the
2080 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updateparams_final()
2087 htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ? in ieee80211_ht_updateparams_final()
2091 if ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH_2040) && in ieee80211_ht_updateparams_final()
2092 (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) { in ieee80211_ht_updateparams_final()
2093 if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_ABOVE) in ieee80211_ht_updateparams_final()
2095 else if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_BELOW) in ieee80211_ht_updateparams_final()
2100 * VHT flags - do much the same; check whether VHT is available in ieee80211_ht_updateparams_final()
2102 * capabilities and the (pre-parsed) VHT info IE. in ieee80211_ht_updateparams_final()
2113 * Parse and update HT-related state extracted from the HT cap ie
2121 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updatehtcap()
2124 if (vap->iv_htcaps & IEEE80211_HTC_SMPS) in ieee80211_ht_updatehtcap()
2131 * Called once HT and VHT capabilities are parsed in hostap mode -
2138 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updatehtcap_final()
2144 htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ? in ieee80211_ht_updatehtcap_final()
2146 if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) && in ieee80211_ht_updatehtcap_final()
2147 (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) { in ieee80211_ht_updatehtcap_final()
2148 if (IEEE80211_IS_CHAN_HT40U(vap->iv_bss->ni_chan)) in ieee80211_ht_updatehtcap_final()
2150 else if (IEEE80211_IS_CHAN_HT40D(vap->iv_bss->ni_chan)) in ieee80211_ht_updatehtcap_final()
2154 * VHT flags - do much the same; check whether VHT is available in ieee80211_ht_updatehtcap_final()
2156 * capabilities and the (pre-parsed) VHT info IE. in ieee80211_ht_updatehtcap_final()
2169 struct ieee80211com *ic = ni->ni_ic; in ieee80211_setup_htrates()
2170 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_setup_htrates()
2175 maxequalmcs = ic->ic_txstream * 8 - 1; in ieee80211_setup_htrates()
2177 if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) { in ieee80211_setup_htrates()
2178 if (ic->ic_txstream >= 2) in ieee80211_setup_htrates()
2180 if (ic->ic_txstream >= 3) in ieee80211_setup_htrates()
2182 if (ic->ic_txstream >= 4) in ieee80211_setup_htrates()
2186 rs = &ni->ni_htrates; in ieee80211_setup_htrates()
2193 if (isclr(htcap->hc_mcsset, i)) in ieee80211_setup_htrates()
2195 if (rs->rs_nrates == IEEE80211_HTRATE_MAXSIZE) { in ieee80211_setup_htrates()
2200 vap->iv_stats.is_rx_rstoobig++; in ieee80211_setup_htrates()
2206 (ic->ic_htcaps & IEEE80211_HTC_TXMCS32) == 0) in ieee80211_setup_htrates()
2210 rs->rs_rates[rs->rs_nrates++] = i; in ieee80211_setup_htrates()
2230 rs = &ni->ni_htrates; in ieee80211_setup_basic_htrates()
2231 if (rs->rs_nrates == 0) { in ieee80211_setup_basic_htrates()
2232 IEEE80211_NOTE(ni->ni_vap, in ieee80211_setup_basic_htrates()
2238 if (isclr(htinfo->hi_basicmcsset, i)) in ieee80211_setup_basic_htrates()
2240 for (j = 0; j < rs->rs_nrates; j++) in ieee80211_setup_basic_htrates()
2241 if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == i) in ieee80211_setup_basic_htrates()
2242 rs->rs_rates[j] |= IEEE80211_RATE_BASIC; in ieee80211_setup_basic_htrates()
2249 callout_init(&tap->txa_timer, 1); in ampdu_tx_setup()
2250 tap->txa_flags |= IEEE80211_AGGR_SETUP; in ampdu_tx_setup()
2251 tap->txa_lastsample = ticks; in ampdu_tx_setup()
2257 struct ieee80211_node *ni = tap->txa_ni; in ampdu_tx_stop()
2258 struct ieee80211com *ic = ni->ni_ic; in ampdu_tx_stop()
2260 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ampdu_tx_stop()
2261 tap->txa_ni, in ampdu_tx_stop()
2265 KASSERT(tap->txa_flags & IEEE80211_AGGR_SETUP, in ampdu_tx_stop()
2266 ("txa_flags 0x%x tid %d ac %d", tap->txa_flags, tap->txa_tid, in ampdu_tx_stop()
2267 TID_TO_WME_AC(tap->txa_tid))); in ampdu_tx_stop()
2273 ic->ic_addba_stop(ni, tap); in ampdu_tx_stop()
2284 /* NB: clearing NAK means we may re-send ADDBA */ in ampdu_tx_stop()
2285 tap->txa_flags &= ~(IEEE80211_AGGR_SETUP | IEEE80211_AGGR_NAK); in ampdu_tx_stop()
2289 * ADDBA response timeout.
2291 * If software aggregation and per-TID queue management was done here,
2292 * that queue would be unpaused after the ADDBA timeout occurs.
2298 struct ieee80211_node *ni = tap->txa_ni; in addba_timeout()
2299 struct ieee80211com *ic = ni->ni_ic; in addba_timeout()
2302 tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND; in addba_timeout()
2303 tap->txa_attempts++; in addba_timeout()
2304 ic->ic_addba_response_timeout(ni, tap); in addba_timeout()
2311 callout_reset(&tap->txa_timer, ieee80211_addba_timeout, in addba_start_timeout()
2313 tap->txa_flags |= IEEE80211_AGGR_XCHGPEND; in addba_start_timeout()
2314 tap->txa_nextrequest = ticks + ieee80211_addba_timeout; in addba_start_timeout()
2321 if (tap->txa_flags & IEEE80211_AGGR_XCHGPEND) { in addba_stop_timeout()
2322 callout_stop(&tap->txa_timer); in addba_stop_timeout()
2323 tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND; in addba_stop_timeout()
2334 * Default method for requesting A-MPDU tx aggregation.
2346 tap->txa_token = dialogtoken; in ieee80211_addba_request()
2347 tap->txa_flags |= IEEE80211_AGGR_IMMEDIATE; in ieee80211_addba_request()
2349 tap->txa_wnd = (bufsiz == 0) ? in ieee80211_addba_request()
2366 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ampdu_tx_request_ext()
2369 if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) { in ieee80211_ampdu_tx_request_ext()
2374 tap->txa_flags &= ~IEEE80211_AGGR_NAK; in ieee80211_ampdu_tx_request_ext()
2390 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ampdu_tx_request_active_ext()
2395 tap->txa_flags |= IEEE80211_AGGR_RUNNING; in ieee80211_ampdu_tx_request_active_ext()
2396 tap->txa_attempts = 0; in ieee80211_ampdu_tx_request_active_ext()
2399 tap->txa_flags |= IEEE80211_AGGR_NAK; in ieee80211_ampdu_tx_request_active_ext()
2405 * Default method for processing an A-MPDU tx aggregation
2414 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_addba_response()
2422 tap->txa_wnd = (bufsiz == 0) ? in ieee80211_addba_response()
2427 tap->txa_flags |= IEEE80211_AGGR_RUNNING; in ieee80211_addba_response()
2428 tap->txa_attempts = 0; in ieee80211_addba_response()
2430 if ((vap->iv_htcaps & IEEE80211_HTC_TX_AMSDU_AMPDU) && in ieee80211_addba_response()
2431 (ni->ni_flags & IEEE80211_NODE_AMSDU_TX) && in ieee80211_addba_response()
2433 tap->txa_flags |= IEEE80211_AGGR_AMSDU; in ieee80211_addba_response()
2435 tap->txa_flags &= ~IEEE80211_AGGR_AMSDU; in ieee80211_addba_response()
2438 tap->txa_flags |= IEEE80211_AGGR_NAK; in ieee80211_addba_response()
2444 * Default method for stopping A-MPDU tx aggregation.
2452 if (tap->txa_flags & IEEE80211_AGGR_RUNNING) { in ieee80211_addba_stop()
2454 tap->txa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_AMSDU); in ieee80211_addba_stop()
2456 tap->txa_attempts = 0; in ieee80211_addba_stop()
2461 * policy. We intercept ADDBA-related frames and use them to
2470 struct ieee80211com *ic = ni->ni_ic; in ht_recv_action_ba_addba_request()
2471 struct ieee80211vap *vap = ni->ni_vap; in ht_recv_action_ba_addba_request()
2495 rap = &ni->ni_rx_ampdu[tid]; in ht_recv_action_ba_addba_request()
2504 if ((ni->ni_flags & IEEE80211_NODE_AMPDU_RX) && in ht_recv_action_ba_addba_request()
2505 (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_RX)) { in ht_recv_action_ba_addba_request()
2507 ic->ic_ampdu_rx_start(ni, rap, in ht_recv_action_ba_addba_request()
2514 ni->ni_flags & IEEE80211_NODE_AMPDU_RX ? in ht_recv_action_ba_addba_request()
2517 vap->iv_stats.is_addba_reject++; in ht_recv_action_ba_addba_request()
2523 | _IEEE80211_SHIFTMASK(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ) in ht_recv_action_ba_addba_request()
2531 (ni->ni_flags & IEEE80211_NODE_AMSDU_RX) && in ht_recv_action_ba_addba_request()
2532 (vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU)) in ht_recv_action_ba_addba_request()
2537 ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, in ht_recv_action_ba_addba_request()
2547 struct ieee80211com *ic = ni->ni_ic; in ht_recv_action_ba_addba_response()
2548 struct ieee80211vap *vap = ni->ni_vap; in ht_recv_action_ba_addba_response()
2568 tap = &ni->ni_tx_ampdu[tid]; in ht_recv_action_ba_addba_response()
2569 if ((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { in ht_recv_action_ba_addba_response()
2572 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2575 vap->iv_stats.is_addba_norequest++; in ht_recv_action_ba_addba_response()
2578 if (dialogtoken != tap->txa_token) { in ht_recv_action_ba_addba_response()
2581 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2584 tap->txa_token, dialogtoken, tid, code); in ht_recv_action_ba_addba_response()
2585 vap->iv_stats.is_addba_badtoken++; in ht_recv_action_ba_addba_response()
2589 if (policy != (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE)) { in ht_recv_action_ba_addba_response()
2592 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2595 tap->txa_flags & IEEE80211_AGGR_IMMEDIATE, in ht_recv_action_ba_addba_response()
2597 vap->iv_stats.is_addba_badpolicy++; in ht_recv_action_ba_addba_response()
2605 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2609 vap->iv_stats.is_addba_badbawinsize++; in ht_recv_action_ba_addba_response()
2621 ic->ic_addba_response(ni, tap, code, baparamset, batimeout); in ht_recv_action_ba_addba_response()
2630 struct ieee80211com *ic = ni->ni_ic; in ht_recv_action_ba_delba()
2646 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, in ht_recv_action_ba_delba()
2652 tap = &ni->ni_tx_ampdu[tid]; in ht_recv_action_ba_delba()
2653 ic->ic_addba_stop(ni, tap); in ht_recv_action_ba_delba()
2655 rap = &ni->ni_rx_ampdu[tid]; in ht_recv_action_ba_delba()
2656 ic->ic_ampdu_rx_stop(ni, rap); in ht_recv_action_ba_delba()
2664 * 802.11-2020 9.6.11.2 (Notify Channel Width frame format).
2674 if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) == 0) in ht_recv_action_ht_txchwidth()
2685 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, in ht_recv_action_ht_txchwidth()
2687 chw, ni->ni_chw != chw ? "*" : "", ieee80211_ni_chw_to_str(chw)); in ht_recv_action_ht_txchwidth()
2688 if (chw != ni->ni_chw) { in ht_recv_action_ht_txchwidth()
2690 ni->ni_chw = chw; in ht_recv_action_ht_txchwidth()
2705 if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA) in ht_recv_action_ht_mimopwrsave()
2706 ni->ni_flags |= IEEE80211_NODE_MIMO_PS; in ht_recv_action_ht_mimopwrsave()
2708 ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; in ht_recv_action_ht_mimopwrsave()
2709 if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE) in ht_recv_action_ht_mimopwrsave()
2710 ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; in ht_recv_action_ht_mimopwrsave()
2712 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; in ht_recv_action_ht_mimopwrsave()
2714 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, in ht_recv_action_ht_mimopwrsave()
2716 (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ? "on" : "off", in ht_recv_action_ht_mimopwrsave()
2717 (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ? "+rts" : "" in ht_recv_action_ht_mimopwrsave()
2727 * Check if A-MPDU should be requested/enabled for a stream.
2728 * We require a traffic rate above a per-AC threshold and we
2738 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ampdu_enable()
2740 if (tap->txa_avgpps < in ieee80211_ampdu_enable()
2741 vap->iv_ampdu_mintraffic[TID_TO_WME_AC(tap->txa_tid)]) in ieee80211_ampdu_enable()
2744 if (tap->txa_attempts >= ieee80211_addba_maxtries && in ieee80211_ampdu_enable()
2745 ieee80211_time_after(ticks, tap->txa_nextrequest)) { in ieee80211_ampdu_enable()
2755 tap->txa_tid, ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)], in ieee80211_ampdu_enable()
2756 tap->txa_avgpps, tap->txa_pkts, tap->txa_attempts); in ieee80211_ampdu_enable()
2761 * Request A-MPDU tx aggregation. Setup local state and
2769 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ampdu_request()
2775 if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) { in ieee80211_ampdu_request()
2780 tap->txa_flags &= ~IEEE80211_AGGR_NAK; in ieee80211_ampdu_request()
2783 tid = tap->txa_tid; in ieee80211_ampdu_request()
2788 tap->txa_start = ni->ni_txseqs[tid]; in ieee80211_ampdu_request()
2799 if ((ni->ni_flags & IEEE80211_NODE_AMSDU_TX) && in ieee80211_ampdu_request()
2800 (ni->ni_vap->iv_htcaps & IEEE80211_HTC_TX_AMSDU_AMPDU)) in ieee80211_ampdu_request()
2805 if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) { in ieee80211_ampdu_request()
2807 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ampdu_request()
2809 __func__, tap->txa_tid, TID_TO_WME_AC(tap->txa_tid)); in ieee80211_ampdu_request()
2811 tap->txa_attempts = ieee80211_addba_maxtries; in ieee80211_ampdu_request()
2813 if (tap->txa_nextrequest <= ticks) in ieee80211_ampdu_request()
2814 tap->txa_nextrequest = ticks + ieee80211_addba_backoff; in ieee80211_ampdu_request()
2819 args[4] = _IEEE80211_SHIFTMASK(tap->txa_start, IEEE80211_BASEQ_START) in ieee80211_ampdu_request()
2822 return ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, in ieee80211_ampdu_request()
2834 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ampdu_stop()
2835 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ampdu_stop()
2839 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; in ieee80211_ampdu_stop()
2843 __func__, tap->txa_tid, reason, in ieee80211_ampdu_stop()
2845 vap->iv_stats.is_ampdu_stop++; in ieee80211_ampdu_stop()
2847 ic->ic_addba_stop(ni, tap); in ieee80211_ampdu_stop()
2848 args[0] = tap->txa_tid; in ieee80211_ampdu_stop()
2851 ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, in ieee80211_ampdu_stop()
2856 "(reason: %d (%s))", __func__, tap->txa_tid, reason, in ieee80211_ampdu_stop()
2858 vap->iv_stats.is_ampdu_stop_failed++; in ieee80211_ampdu_stop()
2869 struct ieee80211_node *ni = tap->txa_ni; in bar_timeout()
2871 KASSERT((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0, in bar_timeout()
2872 ("bar/addba collision, flags 0x%x", tap->txa_flags)); in bar_timeout()
2874 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in bar_timeout()
2876 tap->txa_tid, tap->txa_flags, tap->txa_attempts); in bar_timeout()
2879 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0) in bar_timeout()
2882 if (tap->txa_attempts >= ieee80211_bar_maxtries) { in bar_timeout()
2883 struct ieee80211com *ic = ni->ni_ic; in bar_timeout()
2885 ni->ni_vap->iv_stats.is_ampdu_bar_tx_fail++; in bar_timeout()
2887 * If (at least) the last BAR TX timeout was due to in bar_timeout()
2894 ic->ic_bar_response(ni, tap, 1); in bar_timeout()
2897 ni->ni_vap->iv_stats.is_ampdu_bar_tx_retry++; in bar_timeout()
2898 if (ieee80211_send_bar(ni, tap, tap->txa_seqpending) != 0) { in bar_timeout()
2899 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in bar_timeout()
2908 * during the next timeout. in bar_timeout()
2911 tap->txa_flags |= IEEE80211_AGGR_BARPEND; in bar_timeout()
2920 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in bar_start_timer()
2921 tap->txa_ni, in bar_start_timer()
2924 callout_reset(&tap->txa_timer, ieee80211_bar_timeout, bar_timeout, tap); in bar_start_timer()
2930 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in bar_stop_timer()
2931 tap->txa_ni, in bar_stop_timer()
2934 callout_stop(&tap->txa_timer); in bar_stop_timer()
2942 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in bar_tx_complete()
2944 __func__, tap->txa_tid, tap->txa_flags, in bar_tx_complete()
2945 callout_pending(&tap->txa_timer), status); in bar_tx_complete()
2947 ni->ni_vap->iv_stats.is_ampdu_bar_tx++; in bar_tx_complete()
2949 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) && in bar_tx_complete()
2950 callout_pending(&tap->txa_timer)) { in bar_tx_complete()
2951 struct ieee80211com *ic = ni->ni_ic; in bar_tx_complete()
2955 ic->ic_bar_response(ni, tap, status); in bar_tx_complete()
2965 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_bar_response()
2966 tap->txa_ni, in ieee80211_bar_response()
2970 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_bar_response()
2972 tap->txa_start, in ieee80211_bar_response()
2973 IEEE80211_SEQ_ADD(tap->txa_start, tap->txa_wnd-1), in ieee80211_bar_response()
2974 tap->txa_qframes, tap->txa_seqpending, in ieee80211_bar_response()
2975 tap->txa_tid); in ieee80211_bar_response()
2978 tap->txa_start = tap->txa_seqpending; in ieee80211_bar_response()
2979 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; in ieee80211_bar_response()
2994 #define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0) in ieee80211_send_bar()
2995 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_send_bar()
2996 struct ieee80211com *ic = ni->ni_ic; in ieee80211_send_bar()
3003 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_send_bar()
3004 tap->txa_ni, in ieee80211_send_bar()
3008 if ((tap->txa_flags & IEEE80211_AGGR_RUNNING) == 0) { in ieee80211_send_bar()
3018 m = ieee80211_getmgtframe(&frm, ic->ic_headroom, sizeof(*bar)); in ieee80211_send_bar()
3029 bar->i_fc[0] = IEEE80211_FC0_VERSION_0 | in ieee80211_send_bar()
3031 bar->i_fc[1] = 0; in ieee80211_send_bar()
3032 IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr); in ieee80211_send_bar()
3033 IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr); in ieee80211_send_bar()
3035 tid = tap->txa_tid; in ieee80211_send_bar()
3036 barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ? in ieee80211_send_bar()
3043 bar->i_ctl = htole16(barctl); in ieee80211_send_bar()
3044 bar->i_seq = htole16(barseqctl); in ieee80211_send_bar()
3045 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_bar); in ieee80211_send_bar()
3053 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0) in ieee80211_send_bar()
3054 tap->txa_attempts = 1; in ieee80211_send_bar()
3056 tap->txa_attempts++; in ieee80211_send_bar()
3057 tap->txa_seqpending = seq; in ieee80211_send_bar()
3058 tap->txa_flags |= IEEE80211_AGGR_BARPEND; in ieee80211_send_bar()
3062 tid, barctl, seq, tap->txa_attempts); in ieee80211_send_bar()
3076 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; in ieee80211_send_bar()
3077 vap->iv_stats.is_ampdu_bar_tx_fail++; in ieee80211_send_bar()
3081 if (tap->txa_flags & IEEE80211_AGGR_BARPEND) in ieee80211_send_bar()
3085 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_send_bar()
3086 tap->txa_ni, in ieee80211_send_bar()
3089 vap->iv_stats.is_ampdu_bar_tx_fail++; in ieee80211_send_bar()
3102 params.ibp_rate0 = ni->ni_txparms->mgmtrate; in ht_action_output()
3104 params.ibp_try0 = ni->ni_txparms->maxretry; in ht_action_output()
3105 params.ibp_power = ni->ni_txpower; in ht_action_output()
3125 struct ieee80211vap *vap = ni->ni_vap; in ht_send_action_ba_addba()
3126 struct ieee80211com *ic = ni->ni_ic; in ht_send_action_ba_addba()
3142 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in ht_send_action_ba_addba()
3146 ic->ic_headroom + sizeof(struct ieee80211_frame), in ht_send_action_ba_addba()
3161 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in ht_send_action_ba_addba()
3164 vap->iv_stats.is_tx_nobuf++; in ht_send_action_ba_addba()
3174 struct ieee80211vap *vap = ni->ni_vap; in ht_send_action_ba_delba()
3175 struct ieee80211com *ic = ni->ni_ic; in ht_send_action_ba_delba()
3190 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in ht_send_action_ba_delba()
3194 ic->ic_headroom + sizeof(struct ieee80211_frame), in ht_send_action_ba_delba()
3204 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in ht_send_action_ba_delba()
3207 vap->iv_stats.is_tx_nobuf++; in ht_send_action_ba_delba()
3217 struct ieee80211vap *vap = ni->ni_vap; in ht_send_action_ht_txchwidth()
3218 struct ieee80211com *ic = ni->ni_ic; in ht_send_action_ht_txchwidth()
3224 IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20); in ht_send_action_ht_txchwidth()
3228 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in ht_send_action_ht_txchwidth()
3232 ic->ic_headroom + sizeof(struct ieee80211_frame), in ht_send_action_ht_txchwidth()
3240 *frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? in ht_send_action_ht_txchwidth()
3243 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in ht_send_action_ht_txchwidth()
3246 vap->iv_stats.is_tx_nobuf++; in ht_send_action_ht_txchwidth()
3263 KASSERT((ic->ic_rxstream > 0 && ic->ic_rxstream <= 4), in ieee80211_set_mcsset()
3264 ("ic_rxstream %d out of range", ic->ic_rxstream)); in ieee80211_set_mcsset()
3265 KASSERT((ic->ic_txstream > 0 && ic->ic_txstream <= 4), in ieee80211_set_mcsset()
3266 ("ic_txstream %d out of range", ic->ic_txstream)); in ieee80211_set_mcsset()
3268 for (i = 0; i < ic->ic_rxstream * 8; i++) in ieee80211_set_mcsset()
3270 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && in ieee80211_set_mcsset()
3271 (ic->ic_htcaps & IEEE80211_HTC_RXMCS32)) in ieee80211_set_mcsset()
3273 if (ic->ic_htcaps & IEEE80211_HTC_RXUNEQUAL) { in ieee80211_set_mcsset()
3274 if (ic->ic_rxstream >= 2) { in ieee80211_set_mcsset()
3278 if (ic->ic_rxstream >= 3) { in ieee80211_set_mcsset()
3282 if (ic->ic_rxstream >= 4) { in ieee80211_set_mcsset()
3289 if (ic->ic_rxstream != ic->ic_txstream) { in ieee80211_set_mcsset()
3291 txparams |= (ic->ic_txstream - 1) << 2; /* num TX streams */ in ieee80211_set_mcsset()
3292 if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) in ieee80211_set_mcsset()
3310 struct ieee80211com *ic = ni->ni_ic; in ieee80211_add_htcap_body()
3311 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_add_htcap_body()
3316 caps = vap->iv_htcaps & 0xffff; in ieee80211_add_htcap_body()
3325 if (vap->iv_opmode == IEEE80211_M_STA) { in ieee80211_add_htcap_body()
3327 if (vap->iv_flags_ht & IEEE80211_FHT_USEHT40) in ieee80211_add_htcap_body()
3333 rxmax = _IEEE80211_MASKSHIFT(ni->ni_htparam, in ieee80211_add_htcap_body()
3335 density = _IEEE80211_MASKSHIFT(ni->ni_htparam, in ieee80211_add_htcap_body()
3343 vap->iv_ampdu_rxmax, in ieee80211_add_htcap_body()
3344 vap->iv_ampdu_density); in ieee80211_add_htcap_body()
3347 if (rxmax > vap->iv_ampdu_rxmax) in ieee80211_add_htcap_body()
3348 rxmax = vap->iv_ampdu_rxmax; in ieee80211_add_htcap_body()
3353 * (Larger density value == larger minimum gap between A-MPDU in ieee80211_add_htcap_body()
3356 if (vap->iv_ampdu_density > density) in ieee80211_add_htcap_body()
3357 density = vap->iv_ampdu_density; in ieee80211_add_htcap_body()
3365 if (ni->ni_chan != IEEE80211_CHAN_ANYC && in ieee80211_add_htcap_body()
3366 findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40U) == NULL && in ieee80211_add_htcap_body()
3367 findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40D) == NULL) in ieee80211_add_htcap_body()
3371 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) in ieee80211_add_htcap_body()
3377 rxmax = vap->iv_ampdu_rxmax; in ieee80211_add_htcap_body()
3378 density = vap->iv_ampdu_density; in ieee80211_add_htcap_body()
3382 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) in ieee80211_add_htcap_body()
3384 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0 || in ieee80211_add_htcap_body()
3389 if ((vap->iv_flags_ht & IEEE80211_FHT_STBC_RX) == 0) in ieee80211_add_htcap_body()
3393 if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX) == 0) in ieee80211_add_htcap_body()
3404 /* pre-zero remainder of ie */ in ieee80211_add_htcap_body()
3405 memset(frm, 0, sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body()
3415 ieee80211_set_mcsset(ni->ni_ic, frm); in ieee80211_add_htcap_body()
3417 frm += __offsetof(struct ieee80211_ie_htcap, hc_extcap) - in ieee80211_add_htcap_body()
3421 extcaps = vap->iv_htextcaps & 0xffff; in ieee80211_add_htcap_body()
3425 frm += sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body()
3439 frm[1] = sizeof(struct ieee80211_ie_htcap) - 2; in ieee80211_add_htcap()
3444 * Non-associated probe request - add HT capabilities based on
3456 struct ieee80211com *ic = vap->iv_ic; in ieee80211_add_htcap_body_ch()
3461 caps = vap->iv_htcaps & 0xffff; in ieee80211_add_htcap_body_ch()
3476 rxmax = vap->iv_ampdu_rxmax; in ieee80211_add_htcap_body_ch()
3477 density = vap->iv_ampdu_density; in ieee80211_add_htcap_body_ch()
3480 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) in ieee80211_add_htcap_body_ch()
3482 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0 || in ieee80211_add_htcap_body_ch()
3493 /* pre-zero remainder of ie */ in ieee80211_add_htcap_body_ch()
3494 memset(frm, 0, sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body_ch()
3506 frm += __offsetof(struct ieee80211_ie_htcap, hc_extcap) - in ieee80211_add_htcap_body_ch()
3510 extcaps = vap->iv_htextcaps & 0xffff; in ieee80211_add_htcap_body_ch()
3514 frm += sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body_ch()
3529 frm[1] = sizeof(struct ieee80211_ie_htcap) - 2; in ieee80211_add_htcap_ch()
3535 * used for compatibility w/ pre-draft implementations.
3541 frm[1] = 4 + sizeof(struct ieee80211_ie_htcap) - 2; in ieee80211_add_htcap_vendor()
3558 for (i = 0; i < rs->rs_nrates; i++) { in ieee80211_set_basic_htrates()
3559 int r = rs->rs_rates[i] & IEEE80211_RATE_VAL; in ieee80211_set_basic_htrates()
3560 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && in ieee80211_set_basic_htrates()
3578 struct ieee80211com *ic = vap->iv_ic; in ieee80211_ht_update_beacon()
3580 (struct ieee80211_ie_htinfo *) bo->bo_htinfo; in ieee80211_ht_update_beacon()
3582 ni = ieee80211_ref_node(vap->iv_bss); in ieee80211_ht_update_beacon()
3583 bsschan = ni->ni_chan; in ieee80211_ht_update_beacon()
3586 ht->hi_ctrlchannel = ieee80211_chan2ieee(ic, bsschan); in ieee80211_ht_update_beacon()
3587 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) in ieee80211_ht_update_beacon()
3588 ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PERM; in ieee80211_ht_update_beacon()
3590 ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PROH; in ieee80211_ht_update_beacon()
3592 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_ABOVE; in ieee80211_ht_update_beacon()
3594 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_BELOW; in ieee80211_ht_update_beacon()
3596 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_NONE; in ieee80211_ht_update_beacon()
3598 ht->hi_byte1 |= IEEE80211_HTINFO_TXWIDTH_2040; in ieee80211_ht_update_beacon()
3602 * XXX TODO: this uses the global flag, not the per-VAP flag. in ieee80211_ht_update_beacon()
3603 * Eventually (once the protection modes are done per-channel in ieee80211_ht_update_beacon()
3604 * rather than per-VAP) we can flip this over to be per-VAP but in ieee80211_ht_update_beacon()
3607 ht->hi_byte2 = (ht->hi_byte2 &~ PROTMODE) | ic->ic_curhtprotmode; in ieee80211_ht_update_beacon()
3625 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_add_htinfo_body()
3626 struct ieee80211com *ic = ni->ni_ic; in ieee80211_add_htinfo_body()
3628 /* pre-zero remainder of ie */ in ieee80211_add_htinfo_body()
3629 memset(frm, 0, sizeof(struct ieee80211_ie_htinfo) - 2); in ieee80211_add_htinfo_body()
3632 *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan); in ieee80211_add_htinfo_body()
3634 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) in ieee80211_add_htinfo_body()
3638 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan)) in ieee80211_add_htinfo_body()
3640 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan)) in ieee80211_add_htinfo_body()
3644 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) in ieee80211_add_htinfo_body()
3649 * this will respect the per-VAP flags. in ieee80211_add_htinfo_body()
3651 frm[1] = vap->iv_curhtprotmode; in ieee80211_add_htinfo_body()
3656 ieee80211_set_basic_htrates(frm, &ni->ni_htrates); in ieee80211_add_htinfo_body()
3657 frm += sizeof(struct ieee80211_ie_htinfo) - in ieee80211_add_htinfo_body()
3669 frm[1] = sizeof(struct ieee80211_ie_htinfo) - 2; in ieee80211_add_htinfo()
3675 * used for compatibility w/ pre-draft implementations.
3681 frm[1] = 4 + sizeof(struct ieee80211_ie_htinfo) - 2; in ieee80211_add_htinfo_vendor()
3693 * Larger values are longer A-MPDU density spacing values, and
3702 vap = ni->ni_vap; in ieee80211_ht_get_node_ampdu_density()
3704 _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY); in ieee80211_ht_get_node_ampdu_density()
3705 if (vap->iv_ampdu_density > peer_mpdudensity) in ieee80211_ht_get_node_ampdu_density()
3706 peer_mpdudensity = vap->iv_ampdu_density; in ieee80211_ht_get_node_ampdu_density()
3711 * Get the transmit A-MPDU limit for the given 802.11n node.
3714 * Smaller values indicate smaller maximum A-MPDU sizes, and
3715 * should be used when forming an A-MPDU to the given peer.
3723 vap = ni->ni_vap; in ieee80211_ht_get_node_ampdu_limit()
3725 _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU); in ieee80211_ht_get_node_ampdu_limit()
3727 return (MIN(vap->iv_ampdu_limit, peer_mpdulimit)); in ieee80211_ht_get_node_ampdu_limit()
3731 * Return true if short-GI is available when transmitting to
3746 vap = ni->ni_vap; in ieee80211_ht_check_tx_shortgi_20()
3747 ic = ni->ni_ic; in ieee80211_ht_check_tx_shortgi_20()
3749 return ((ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) && in ieee80211_ht_check_tx_shortgi_20()
3750 (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) && in ieee80211_ht_check_tx_shortgi_20()
3751 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20)); in ieee80211_ht_check_tx_shortgi_20()
3755 * Return true if short-GI is available when transmitting to
3770 vap = ni->ni_vap; in ieee80211_ht_check_tx_shortgi_40()
3771 ic = ni->ni_ic; in ieee80211_ht_check_tx_shortgi_40()
3773 return ((ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40) && in ieee80211_ht_check_tx_shortgi_40()
3774 (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) && in ieee80211_ht_check_tx_shortgi_40()
3775 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40)); in ieee80211_ht_check_tx_shortgi_40()
3790 if (ni == NULL || ni->ni_chan == IEEE80211_CHAN_ANYC || in ieee80211_ht_check_tx_ht()
3791 ni->ni_vap == NULL || ni->ni_vap->iv_bss == NULL) in ieee80211_ht_check_tx_ht()
3794 vap = ni->ni_vap; in ieee80211_ht_check_tx_ht()
3795 bss_chan = vap->iv_bss->ni_chan; in ieee80211_ht_check_tx_ht()
3800 if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && in ieee80211_ht_check_tx_ht()
3801 ni->ni_htrates.rs_nrates == 0) in ieee80211_ht_check_tx_ht()
3803 return (IEEE80211_IS_CHAN_HT(ni->ni_chan)); in ieee80211_ht_check_tx_ht()
3821 vap = ni->ni_vap; in ieee80211_ht_check_tx_ht40()
3822 bss_chan = vap->iv_bss->ni_chan; in ieee80211_ht_check_tx_ht40()
3825 IEEE80211_IS_CHAN_HT40(ni->ni_chan) && in ieee80211_ht_check_tx_ht40()
3826 (ni->ni_chw == IEEE80211_STA_RX_BW_40)); in ieee80211_ht_check_tx_ht40()