Lines Matching +full:touch +full:- +full:hold +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()
366 for (range = ranges; range->txstream != 0; range++) { in ht_rateprint()
367 if (ic->ic_txstream < range->txstream) in ht_rateprint()
369 if (range->htcapflags && in ht_rateprint()
370 (ic->ic_htcaps & range->htcapflags) == 0) in ht_rateprint()
372 if (ratetype < range->ratetype) in ht_rateprint()
374 minrate = ht_getrate(ic, range->minmcs, mode, ratetype); in ht_rateprint()
375 maxrate = ht_getrate(ic, range->maxmcs, mode, ratetype); in ht_rateprint()
376 if (range->maxmcs) { in ht_rateprint()
377 ic_printf(ic, "MCS %d-%d: %d%sMbps - %d%sMbps\n", in ht_rateprint()
378 range->minmcs, range->maxmcs, in ht_rateprint()
382 ic_printf(ic, "MCS %d: %d%sMbps\n", range->minmcs, in ht_rateprint()
395 if (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) { in ht_announce()
399 if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) { in ht_announce()
403 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && in ht_announce()
404 (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) { in ht_announce()
414 if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) || in ieee80211_ht_announce()
415 isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) in ieee80211_ht_announce()
416 ic_printf(ic, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream); in ieee80211_ht_announce()
417 if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA)) in ieee80211_ht_announce()
419 if (isset(ic->ic_modecaps, IEEE80211_MODE_11NG)) in ieee80211_ht_announce()
427 htrateset->rs_rates[htrateset->rs_nrates] = x; \ in ieee80211_init_suphtrates()
428 htrateset->rs_nrates++; \ in ieee80211_init_suphtrates()
430 struct ieee80211_htrateset *htrateset = &ic->ic_sup_htrates; in ieee80211_init_suphtrates()
434 for (i = 0; i < ic->ic_txstream * 8; i++) in ieee80211_init_suphtrates()
436 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && in ieee80211_init_suphtrates()
437 (ic->ic_htcaps & IEEE80211_HTC_TXMCS32)) in ieee80211_init_suphtrates()
439 if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) { in ieee80211_init_suphtrates()
440 if (ic->ic_txstream >= 2) { in ieee80211_init_suphtrates()
444 if (ic->ic_txstream >= 3) { in ieee80211_init_suphtrates()
448 if (ic->ic_txstream == 4) { in ieee80211_init_suphtrates()
461 * Decap the encapsulated A-MSDU frames and dispatch all but
468 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_decap_amsdu()
475 vap->iv_stats.is_amsdu_decap++; in ieee80211_decap_amsdu()
487 ni->ni_macaddr, "a-msdu", "%s", "decap failed"); in ieee80211_decap_amsdu()
488 vap->iv_stats.is_amsdu_tooshort++; in ieee80211_decap_amsdu()
491 if (m->m_pkthdr.len == framelen) in ieee80211_decap_amsdu()
496 ni->ni_macaddr, "a-msdu", in ieee80211_decap_amsdu()
498 vap->iv_stats.is_amsdu_split++; in ieee80211_decap_amsdu()
502 vap->iv_deliver_data(vap, ni, m); in ieee80211_decap_amsdu()
506 * is required to be aligned to a 4-byte boundary. in ieee80211_decap_amsdu()
509 m_adj(m, roundup2(framelen, 4) - framelen); /* padding */ in ieee80211_decap_amsdu()
521 m = mbufq_dequeue(&rap->rxa_mq[i]); in ampdu_rx_purge_slot()
524 rap->rxa_qbytes -= m->m_pkthdr.len; in ampdu_rx_purge_slot()
525 rap->rxa_qframes--; in ampdu_rx_purge_slot()
533 * For future offloaded A-MSDU handling where multiple frames with
545 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_add_slot()
559 * per-slot to know that we've finished receiving the frame list. in ampdu_rx_add_slot()
563 * end of the reassembly slot to see if its F_AMSDU w/ no F_AMSDU_MORE - in ampdu_rx_add_slot()
570 if (!mbufq_empty(&rap->rxa_mq[off])) { in ampdu_rx_add_slot()
571 rxs_final = ieee80211_get_rx_params_ptr(mbufq_last(&rap->rxa_mq[off])); in ampdu_rx_add_slot()
600 if (mbufq_empty(&rap->rxa_mq[off]) || (toss_dup == 0)) { in ampdu_rx_add_slot()
601 if (mbufq_enqueue(&rap->rxa_mq[off], m) != 0) { in ampdu_rx_add_slot()
603 ni->ni_macaddr, in ampdu_rx_add_slot()
604 "a-mpdu queue fail", in ampdu_rx_add_slot()
606 rxseq, tid, rap->rxa_start, in ampdu_rx_add_slot()
607 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ampdu_rx_add_slot()
609 mbufq_len(&rap->rxa_mq[off]), in ampdu_rx_add_slot()
610 rap->rxa_mq[off].mq_maxlen); in ampdu_rx_add_slot()
615 rap->rxa_qframes++; in ampdu_rx_add_slot()
616 rap->rxa_qbytes += m->m_pkthdr.len; in ampdu_rx_add_slot()
617 vap->iv_stats.is_ampdu_rx_reorder++; in ampdu_rx_add_slot()
632 ni->ni_macaddr, "a-mpdu duplicate", in ampdu_rx_add_slot()
634 rxseq, tid, rap->rxa_start, in ampdu_rx_add_slot()
635 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1)); in ampdu_rx_add_slot()
639 ni->ni_macaddr, "a-mpdu duplicate", in ampdu_rx_add_slot()
641 rxseq, tid, rxs->c_pktflags); in ampdu_rx_add_slot()
646 ni->ni_macaddr, "a-mpdu duplicate", in ampdu_rx_add_slot()
648 rxs_final->c_pktflags); in ampdu_rx_add_slot()
650 vap->iv_stats.is_rx_dup++; in ampdu_rx_add_slot()
660 * Purge all frames in the A-MPDU re-order queue.
667 for (i = 0; i < rap->rxa_wnd; i++) { in ampdu_rx_purge()
669 if (rap->rxa_qframes == 0) in ampdu_rx_purge()
672 KASSERT(rap->rxa_qbytes == 0 && rap->rxa_qframes == 0, in ampdu_rx_purge()
674 rap->rxa_qbytes, rap->rxa_qframes)); in ampdu_rx_purge()
686 mbufq_init(&rap->rxa_mq[i], 256); in ieee80211_ampdu_rx_init_rap()
690 * Start A-MPDU rx/re-order processing for the specified TID.
696 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_start()
699 if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) { in ampdu_rx_start()
707 rap->rxa_wnd = (bufsiz == 0) ? in ampdu_rx_start()
709 rap->rxa_start = _IEEE80211_MASKSHIFT(baseqctl, IEEE80211_BASEQ_START); in ampdu_rx_start()
710 rap->rxa_flags |= IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND; in ampdu_rx_start()
713 if ((vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU) && in ampdu_rx_start()
715 rap->rxa_flags |= IEEE80211_AGGR_AMSDU; in ampdu_rx_start()
717 rap->rxa_flags &= ~IEEE80211_AGGR_AMSDU; in ampdu_rx_start()
732 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ampdu_rx_start_ext()
734 if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) { in ieee80211_ampdu_rx_start_ext()
744 rap->rxa_wnd = (baw== 0) ? in ieee80211_ampdu_rx_start_ext()
746 if (seq == -1) { in ieee80211_ampdu_rx_start_ext()
748 rap->rxa_start = 0; in ieee80211_ampdu_rx_start_ext()
749 rap->rxa_flags |= IEEE80211_AGGR_WAITRX; in ieee80211_ampdu_rx_start_ext()
751 rap->rxa_start = seq; in ieee80211_ampdu_rx_start_ext()
753 rap->rxa_flags |= IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND; in ieee80211_ampdu_rx_start_ext()
757 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ieee80211_ampdu_rx_start_ext()
762 rap->rxa_wnd, in ieee80211_ampdu_rx_start_ext()
763 rap->rxa_flags); in ieee80211_ampdu_rx_start_ext()
777 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ampdu_rx_stop_ext()
782 * Stop A-MPDU rx processing for the specified TID.
789 rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING in ampdu_rx_stop()
795 * Dispatch a frame from the A-MPDU reorder queue. The
798 * permits ieee80211_input to optimize re-processing).
803 m->m_flags |= M_AMPDU_MPDU; /* bypass normal processing */ in ampdu_dispatch()
816 m = mbufq_dequeue(&rap->rxa_mq[i]); in ampdu_dispatch_slot()
821 rap->rxa_qbytes -= m->m_pkthdr.len; in ampdu_dispatch_slot()
822 rap->rxa_qframes--; in ampdu_dispatch_slot()
833 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_moveup()
839 if (rap->rxa_qframes != 0) { in ampdu_rx_moveup()
840 int n = rap->rxa_qframes, j; in ampdu_rx_moveup()
841 for (j = i+1; j < rap->rxa_wnd; j++) { in ampdu_rx_moveup()
846 if (mbufq_len(&rap->rxa_mq[j]) != 0) { in ampdu_rx_moveup()
847 n = n - mbufq_len(&rap->rxa_mq[j]); in ampdu_rx_moveup()
848 mbufq_concat(&rap->rxa_mq[j-i], &rap->rxa_mq[j]); in ampdu_rx_moveup()
856 __func__, n, rap->rxa_qframes, i, rap->rxa_start, in ampdu_rx_moveup()
857 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ampdu_rx_moveup()
859 vap->iv_stats.is_ampdu_rx_copy += rap->rxa_qframes; in ampdu_rx_moveup()
864 * Dispatch as many frames as possible from the re-order queue.
874 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_dispatch()
879 for (i = 1; i < rap->rxa_wnd; i++) { in ampdu_rx_dispatch()
887 ampdu_rx_moveup(rap, ni, i, -1); in ampdu_rx_dispatch()
893 rap->rxa_start = IEEE80211_SEQ_ADD(rap->rxa_start, i); in ampdu_rx_dispatch()
894 vap->iv_stats.is_ampdu_rx_oor += r2; in ampdu_rx_dispatch()
896 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ampdu_rx_dispatch()
900 rap->rxa_start, in ampdu_rx_dispatch()
905 * Dispatch all frames in the A-MPDU re-order queue.
912 for (i = 0; i < rap->rxa_wnd; i++) { in ampdu_rx_flush()
916 ni->ni_vap->iv_stats.is_ampdu_rx_oor += r; in ampdu_rx_flush()
918 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ampdu_rx_flush()
922 rap->rxa_start, in ampdu_rx_flush()
925 if (rap->rxa_qframes == 0) in ampdu_rx_flush()
931 * Dispatch all frames in the A-MPDU re-order queue
939 struct ieee80211vap *vap = ni->ni_vap; in ampdu_rx_flush_upto()
950 seqno = rap->rxa_start; in ampdu_rx_flush_upto()
951 for (i = 0; i < rap->rxa_wnd; i++) { in ampdu_rx_flush_upto()
952 if ((r = mbufq_len(&rap->rxa_mq[i])) != 0) { in ampdu_rx_flush_upto()
958 vap->iv_stats.is_ampdu_rx_oor += r; in ampdu_rx_flush_upto()
961 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, ni, in ampdu_rx_flush_upto()
981 rap->rxa_start = seqno; in ampdu_rx_flush_upto()
986 * A-MPDU reordering: if this frame is received out of order
987 * and falls within the BA window hold onto it. Otherwise if
992 * A-MSDU: handle hardware decap'ed A-MSDU frames that are
1002 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ampdu_reorder()
1011 KASSERT((m->m_flags & (M_AMPDU | M_AMPDU_MPDU)) == M_AMPDU, in ieee80211_ampdu_reorder()
1012 ("!a-mpdu or already re-ordered, flags 0x%x", m->m_flags)); in ieee80211_ampdu_reorder()
1013 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta")); in ieee80211_ampdu_reorder()
1026 * 802.11-2012 9.3.2.10 - Duplicate detection and recovery. in ieee80211_ampdu_reorder()
1029 * counter, not the per-TID counter. in ieee80211_ampdu_reorder()
1031 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) in ieee80211_ampdu_reorder()
1036 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ampdu_reorder()
1037 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { in ieee80211_ampdu_reorder()
1039 * No ADDBA request yet, don't touch. in ieee80211_ampdu_reorder()
1043 rxseq = le16toh(*(uint16_t *)wh->i_seq); in ieee80211_ampdu_reorder()
1049 IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, in ieee80211_ampdu_reorder()
1050 "A-MPDU", "fragment, rxseq 0x%x tid %u%s", rxseq, tid, in ieee80211_ampdu_reorder()
1051 wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); in ieee80211_ampdu_reorder()
1052 vap->iv_stats.is_ampdu_rx_drop++; in ieee80211_ampdu_reorder()
1058 rap->rxa_nframes++; in ieee80211_ampdu_reorder()
1065 if (rap->rxa_flags & IEEE80211_AGGR_WAITRX) { in ieee80211_ampdu_reorder()
1066 rap->rxa_flags &= ~IEEE80211_AGGR_WAITRX; in ieee80211_ampdu_reorder()
1067 rap->rxa_start = rxseq; in ieee80211_ampdu_reorder()
1070 if (rxseq == rap->rxa_start) { in ieee80211_ampdu_reorder()
1074 if (rap->rxa_qframes != 0) { in ieee80211_ampdu_reorder()
1078 KASSERT(mbufq_empty(&rap->rxa_mq[0]), ("unexpected dup")); in ieee80211_ampdu_reorder()
1089 rap->rxa_start = IEEE80211_SEQ_INC(rxseq); in ieee80211_ampdu_reorder()
1095 rap->rxa_start = IEEE80211_SEQ_INC(rxseq); in ieee80211_ampdu_reorder()
1104 off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start); in ieee80211_ampdu_reorder()
1105 if (off < rap->rxa_wnd) { in ieee80211_ampdu_reorder()
1128 if (rap->rxa_qframes != 0) { in ieee80211_ampdu_reorder()
1130 if (ticks - rap->rxa_age > ieee80211_ampdu_age) { in ieee80211_ampdu_reorder()
1135 if (rap->rxa_qframes != 0) { in ieee80211_ampdu_reorder()
1136 vap->iv_stats.is_ampdu_rx_age += in ieee80211_ampdu_reorder()
1137 rap->rxa_qframes; in ieee80211_ampdu_reorder()
1146 rap->rxa_start = in ieee80211_ampdu_reorder()
1155 rap->rxa_start = in ieee80211_ampdu_reorder()
1164 rap->rxa_age = ticks; in ieee80211_ampdu_reorder()
1167 /* save packet - this consumes, no matter what */ in ieee80211_ampdu_reorder()
1179 rap->rxa_start, in ieee80211_ampdu_reorder()
1180 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_ampdu_reorder()
1181 rap->rxa_qframes, rxseq, tid); in ieee80211_ampdu_reorder()
1182 vap->iv_stats.is_ampdu_rx_move++; in ieee80211_ampdu_reorder()
1186 * WinStart_B = rxseq - rap->rxa_wnd + 1 in ieee80211_ampdu_reorder()
1194 IEEE80211_SEQ_SUB(rxseq, rap->rxa_wnd-1)); in ieee80211_ampdu_reorder()
1202 IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, in ieee80211_ampdu_reorder()
1204 rap->rxa_start, in ieee80211_ampdu_reorder()
1205 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_ampdu_reorder()
1206 rap->rxa_qframes, rxseq, tid, in ieee80211_ampdu_reorder()
1207 wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); in ieee80211_ampdu_reorder()
1208 vap->iv_stats.is_ampdu_rx_drop++; in ieee80211_ampdu_reorder()
1225 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_recv_bar()
1234 ni->ni_macaddr, "BAR", "%s", "processing disabled"); in ieee80211_recv_bar()
1236 vap->iv_stats.is_ampdu_bar_bad++; in ieee80211_recv_bar()
1241 tid = _IEEE80211_MASKSHIFT(le16toh(wh->i_ctl), IEEE80211_BAR_TID); in ieee80211_recv_bar()
1242 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_recv_bar()
1243 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { in ieee80211_recv_bar()
1245 * No ADDBA request yet, don't touch. in ieee80211_recv_bar()
1249 ni->ni_macaddr, "BAR", "no BA stream, tid %u", tid); in ieee80211_recv_bar()
1250 vap->iv_stats.is_ampdu_bar_bad++; in ieee80211_recv_bar()
1253 vap->iv_stats.is_ampdu_bar_rx++; in ieee80211_recv_bar()
1254 rxseq = le16toh(wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; in ieee80211_recv_bar()
1255 if (rxseq == rap->rxa_start) in ieee80211_recv_bar()
1258 off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start); in ieee80211_recv_bar()
1266 rap->rxa_start, in ieee80211_recv_bar()
1267 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_recv_bar()
1268 rap->rxa_qframes, rxseq, tid); in ieee80211_recv_bar()
1269 vap->iv_stats.is_ampdu_bar_move++; in ieee80211_recv_bar()
1272 if (off >= rap->rxa_wnd) { in ieee80211_recv_bar()
1278 rap->rxa_start = rxseq; in ieee80211_recv_bar()
1286 IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr, in ieee80211_recv_bar()
1288 rap->rxa_start, in ieee80211_recv_bar()
1289 IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1), in ieee80211_recv_bar()
1290 rap->rxa_qframes, rxseq, tid, in ieee80211_recv_bar()
1291 wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : ""); in ieee80211_recv_bar()
1292 vap->iv_stats.is_ampdu_bar_oow++; in ieee80211_recv_bar()
1298 * Setup HT-specific state in a node. Called only
1308 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ht_node_init()
1314 if (ni->ni_flags & IEEE80211_NODE_HT) { in ieee80211_ht_node_init()
1316 * Clean AMPDU state on re-associate. This handles the case in ieee80211_ht_node_init()
1320 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ht_node_init()
1327 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ht_node_init()
1328 tap->txa_tid = tid; in ieee80211_ht_node_init()
1329 tap->txa_ni = ni; in ieee80211_ht_node_init()
1332 ieee80211_ampdu_rx_init_rap(ni, &ni->ni_rx_ampdu[tid]); in ieee80211_ht_node_init()
1334 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU | in ieee80211_ht_node_init()
1339 * Cleanup HT-specific state in a node. Called only
1345 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ht_node_cleanup()
1348 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ht_node_cleanup()
1353 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT node")); in ieee80211_ht_node_cleanup()
1357 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[i]; in ieee80211_ht_node_cleanup()
1358 if (tap->txa_flags & IEEE80211_AGGR_SETUP) in ieee80211_ht_node_cleanup()
1362 ic->ic_ampdu_rx_stop(ni, &ni->ni_rx_ampdu[i]); in ieee80211_ht_node_cleanup()
1364 ni->ni_htcap = 0; in ieee80211_ht_node_cleanup()
1365 ni->ni_flags &= ~IEEE80211_NODE_HT_ALL; in ieee80211_ht_node_cleanup()
1374 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_node_age()
1377 KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta")); in ieee80211_ht_node_age()
1382 rap = &ni->ni_rx_ampdu[tid]; in ieee80211_ht_node_age()
1383 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) in ieee80211_ht_node_age()
1385 if (rap->rxa_qframes == 0) in ieee80211_ht_node_age()
1392 if (ticks - rap->rxa_age > ieee80211_ampdu_age) { in ieee80211_ht_node_age()
1397 vap->iv_stats.is_ampdu_rx_age += rap->rxa_qframes; in ieee80211_ht_node_age()
1406 return ieee80211_find_channel(ic, c->ic_freq, in findhtchan()
1407 (c->ic_flags &~ IEEE80211_CHAN_HT) | htflags); in findhtchan()
1411 * Adjust a channel to be HT/non-HT according to the vap's configuration.
1423 /* NB: arbitrarily pick ht40+ over ht40- */ in ieee80211_ht_adjust_channel()
1441 c = ieee80211_find_channel(ic, chan->ic_freq, in ieee80211_ht_adjust_channel()
1442 chan->ic_flags &~ IEEE80211_CHAN_HT); in ieee80211_ht_adjust_channel()
1450 * Setup HT-specific state for a legacy WDS peer.
1455 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_wds_init()
1459 KASSERT(vap->iv_flags_ht & IEEE80211_FHT_HT, ("no HT requested")); in ieee80211_ht_wds_init()
1468 ni->ni_chan = ieee80211_ht_adjust_channel(ni->ni_ic, in ieee80211_ht_wds_init()
1469 ni->ni_chan, ieee80211_htchanflags(ni->ni_chan)); in ieee80211_ht_wds_init()
1471 ni->ni_htcap = 0; in ieee80211_ht_wds_init()
1472 if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) in ieee80211_ht_wds_init()
1473 ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI20; in ieee80211_ht_wds_init()
1474 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { in ieee80211_ht_wds_init()
1475 ni->ni_htcap |= IEEE80211_HTCAP_CHWIDTH40; in ieee80211_ht_wds_init()
1476 ni->ni_chw = IEEE80211_STA_RX_BW_40; in ieee80211_ht_wds_init()
1477 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan)) in ieee80211_ht_wds_init()
1478 ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_ABOVE; in ieee80211_ht_wds_init()
1479 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan)) in ieee80211_ht_wds_init()
1480 ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_BELOW; in ieee80211_ht_wds_init()
1481 if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) in ieee80211_ht_wds_init()
1482 ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI40; in ieee80211_ht_wds_init()
1484 ni->ni_chw = IEEE80211_STA_RX_BW_20; in ieee80211_ht_wds_init()
1485 ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_NONE; in ieee80211_ht_wds_init()
1487 ni->ni_htctlchan = ni->ni_chan->ic_ieee; in ieee80211_ht_wds_init()
1488 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) in ieee80211_ht_wds_init()
1489 ni->ni_flags |= IEEE80211_NODE_RIFS; in ieee80211_ht_wds_init()
1492 ni->ni_htopmode = 0; /* XXX need protection state */ in ieee80211_ht_wds_init()
1493 ni->ni_htstbc = 0; /* XXX need info */ in ieee80211_ht_wds_init()
1496 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ht_wds_init()
1497 tap->txa_tid = tid; in ieee80211_ht_wds_init()
1501 ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU | in ieee80211_ht_wds_init()
1515 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_htinfo_notify()
1517 if (vap->iv_opmode != IEEE80211_M_HOSTAP) in ieee80211_htinfo_notify()
1519 if (vap->iv_state != IEEE80211_S_RUN || in ieee80211_htinfo_notify()
1520 !IEEE80211_IS_CHAN_HT(vap->iv_bss->ni_chan)) in ieee80211_htinfo_notify()
1525 vap->iv_bss, in ieee80211_htinfo_notify()
1528 , vap->iv_sta_assoc in ieee80211_htinfo_notify()
1529 , vap->iv_ht_sta_assoc in ieee80211_htinfo_notify()
1530 , vap->iv_ht40_sta_assoc in ieee80211_htinfo_notify()
1531 , (vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) ? in ieee80211_htinfo_notify()
1532 ", non-HT sta present" : "" in ieee80211_htinfo_notify()
1533 , vap->iv_curhtprotmode); in ieee80211_htinfo_notify()
1545 struct ieee80211com *ic = vap->iv_ic; in htinfo_update()
1548 if (vap->iv_sta_assoc != vap->iv_ht_sta_assoc) { in htinfo_update()
1551 } else if (vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) { in htinfo_update()
1554 } else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && in htinfo_update()
1555 IEEE80211_IS_CHAN_HT40(ic->ic_bsschan) && in htinfo_update()
1556 vap->iv_sta_assoc != vap->iv_ht40_sta_assoc) { in htinfo_update()
1561 if (protmode != vap->iv_curhtprotmode) { in htinfo_update()
1562 vap->iv_curhtprotmode = protmode; in htinfo_update()
1574 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_node_join()
1576 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_ht_node_join()
1578 if (ni->ni_flags & IEEE80211_NODE_HT) { in ieee80211_ht_node_join()
1579 vap->iv_ht_sta_assoc++; in ieee80211_ht_node_join()
1580 if (ni->ni_chw == IEEE80211_STA_RX_BW_40) in ieee80211_ht_node_join()
1581 vap->iv_ht40_sta_assoc++; in ieee80211_ht_node_join()
1592 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_node_leave()
1594 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_ht_node_leave()
1596 if (ni->ni_flags & IEEE80211_NODE_HT) { in ieee80211_ht_node_leave()
1597 vap->iv_ht_sta_assoc--; in ieee80211_ht_node_leave()
1598 if (ni->ni_chw == IEEE80211_STA_RX_BW_40) in ieee80211_ht_node_leave()
1599 vap->iv_ht40_sta_assoc--; in ieee80211_ht_node_leave()
1613 * change PROTOPT -> MIXED; only MIXED -> PROTOPT). This
1620 struct ieee80211com *ic = vap->iv_ic; in ieee80211_htprot_update()
1624 /* track non-HT station presence */ in ieee80211_htprot_update()
1627 vap->iv_flags_ht |= IEEE80211_FHT_NONHT_PR; in ieee80211_htprot_update()
1628 vap->iv_lastnonht = ticks; in ieee80211_htprot_update()
1630 if (protmode != vap->iv_curhtprotmode && in ieee80211_htprot_update()
1631 (OPMODE(vap->iv_curhtprotmode) != IEEE80211_HTINFO_OPMODE_MIXED || in ieee80211_htprot_update()
1633 vap->iv_curhtprotmode = protmode; in ieee80211_htprot_update()
1642 * Time out presence of an overlapping bss with non-HT
1644 * beacons from other stations and if we identify a non-HT
1646 * HTINFO ie. To identify when all non-HT stations are
1653 IEEE80211_LOCK_ASSERT(vap->iv_ic); in ieee80211_ht_timeout()
1655 if ((vap->iv_flags_ht & IEEE80211_FHT_NONHT_PR) && in ieee80211_ht_timeout()
1656 ieee80211_time_after(ticks, vap->iv_lastnonht + IEEE80211_NONHT_PRESENT_AGE)) { in ieee80211_ht_timeout()
1658 "%s", "time out non-HT STA present on channel"); in ieee80211_ht_timeout()
1659 vap->iv_flags_ht &= ~IEEE80211_FHT_NONHT_PR; in ieee80211_ht_timeout()
1676 ni->ni_flags |= IEEE80211_NODE_HTCOMPAT; in ieee80211_parse_htcap()
1679 ni->ni_flags &= ~IEEE80211_NODE_HTCOMPAT; in ieee80211_parse_htcap()
1681 ni->ni_htcap = le16dec(ie + in ieee80211_parse_htcap()
1683 ni->ni_htparam = ie[__offsetof(struct ieee80211_ie_htcap, hc_param)]; in ieee80211_parse_htcap()
1692 ni->ni_htctlchan = htinfo->hi_ctrlchannel; in htinfo_parse()
1693 ni->ni_ht2ndchan = _IEEE80211_SHIFTMASK(htinfo->hi_byte1, in htinfo_parse()
1695 w = le16dec(&htinfo->hi_byte2); in htinfo_parse()
1696 ni->ni_htopmode = _IEEE80211_SHIFTMASK(w, IEEE80211_HTINFO_OPMODE); in htinfo_parse()
1697 w = le16dec(&htinfo->hi_byte45); in htinfo_parse()
1698 ni->ni_htstbc = _IEEE80211_SHIFTMASK(w, IEEE80211_HTINFO_BASIC_STBCMCS); in htinfo_parse()
1729 struct ieee80211com *ic = ni->ni_ic; in htinfo_update_chw()
1735 * First step - do HT/VHT only channel lookup based on operating mode in htinfo_update_chw()
1740 chanflags = (ni->ni_chan->ic_flags &~ in htinfo_update_chw()
1743 if (chanflags == ni->ni_chan->ic_flags) in htinfo_update_chw()
1752 chanflags = (ni->ni_chan->ic_flags &~ in htinfo_update_chw()
1754 /* XXX not right for ht40- */ in htinfo_update_chw()
1755 c = ieee80211_find_channel(ic, ni->ni_chan->ic_freq, chanflags); in htinfo_update_chw()
1761 c = findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT20); in htinfo_update_chw()
1763 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1766 ni->ni_chan->ic_freq); in htinfo_update_chw()
1771 /* Nothing found - leave it alone; move onto VHT */ in htinfo_update_chw()
1773 c = ni->ni_chan; in htinfo_update_chw()
1776 * If it's non-HT, then bail out now. in htinfo_update_chw()
1779 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1782 c->ic_freq, c->ic_flags); in htinfo_update_chw()
1787 * Next step - look at the current VHT flags and determine in htinfo_update_chw()
1792 if (IEEE80211_CONF_VHT(ic) && ni->ni_vhtcap != 0 && vhtflags != 0) { in htinfo_update_chw()
1793 chanflags = (c->ic_flags in htinfo_update_chw()
1796 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1800 __func__, ni->ni_vht_chanwidth, vhtflags); in htinfo_update_chw()
1802 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1806 __func__, c->ic_freq, chanflags); in htinfo_update_chw()
1807 c = ieee80211_find_channel(ic, c->ic_freq, chanflags); in htinfo_update_chw()
1811 if (c != NULL && c != ni->ni_chan) { in htinfo_update_chw()
1812 IEEE80211_NOTE(ni->ni_vap, in htinfo_update_chw()
1818 c->ic_freq, c->ic_flags); in htinfo_update_chw()
1819 ni->ni_chan = c; in htinfo_update_chw()
1826 ni->ni_chw = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? in htinfo_update_chw()
1837 uint16_t oflags = ni->ni_flags; in htcap_update_mimo_ps()
1839 switch (ni->ni_htcap & IEEE80211_HTCAP_SMPS) { in htcap_update_mimo_ps()
1841 ni->ni_flags |= IEEE80211_NODE_MIMO_PS; in htcap_update_mimo_ps()
1842 ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; in htcap_update_mimo_ps()
1845 ni->ni_flags |= IEEE80211_NODE_MIMO_PS; in htcap_update_mimo_ps()
1846 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; in htcap_update_mimo_ps()
1850 ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; in htcap_update_mimo_ps()
1851 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; in htcap_update_mimo_ps()
1854 return (oflags ^ ni->ni_flags); in htcap_update_mimo_ps()
1864 struct ieee80211vap *vap = ni->ni_vap; in htcap_update_shortgi()
1866 ni->ni_flags &= ~(IEEE80211_NODE_SGI20|IEEE80211_NODE_SGI40); in htcap_update_shortgi()
1867 if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) && in htcap_update_shortgi()
1868 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20)) in htcap_update_shortgi()
1869 ni->ni_flags |= IEEE80211_NODE_SGI20; in htcap_update_shortgi()
1870 if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) && in htcap_update_shortgi()
1871 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40)) in htcap_update_shortgi()
1872 ni->ni_flags |= IEEE80211_NODE_SGI40; in htcap_update_shortgi()
1882 struct ieee80211vap *vap = ni->ni_vap; in htcap_update_ldpc()
1884 if ((ni->ni_htcap & IEEE80211_HTCAP_LDPC) && in htcap_update_ldpc()
1885 (vap->iv_flags_ht & IEEE80211_FHT_LDPC_TX)) in htcap_update_ldpc()
1886 ni->ni_flags |= IEEE80211_NODE_LDPC; in htcap_update_ldpc()
1890 * Parse and update HT-related state extracted from
1902 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updateparams()
1906 if (vap->iv_htcaps & IEEE80211_HTC_SMPS) in ieee80211_ht_updateparams()
1921 if ((htinfo->hi_byte1 & IEEE80211_HTINFO_RIFSMODE_PERM) && in ieee80211_ht_updateparams()
1922 (vap->iv_flags_ht & IEEE80211_FHT_RIFS)) in ieee80211_ht_updateparams()
1923 ni->ni_flags |= IEEE80211_NODE_RIFS; in ieee80211_ht_updateparams()
1925 ni->ni_flags &= ~IEEE80211_NODE_RIFS; in ieee80211_ht_updateparams()
1931 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_vht_get_vhtflags()
1935 if (ni->ni_flags & IEEE80211_NODE_VHT && vap->iv_vht_flags & IEEE80211_FVHT_VHT) { in ieee80211_vht_get_vhtflags()
1936 if ((ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_160MHZ) && in ieee80211_vht_get_vhtflags()
1938 (_IEEE80211_MASKSHIFT(vap->iv_vht_cap.vht_cap_info, in ieee80211_vht_get_vhtflags()
1940 (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT160)) { in ieee80211_vht_get_vhtflags()
1948 } else if ((ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_80P80MHZ) && in ieee80211_vht_get_vhtflags()
1950 (_IEEE80211_MASKSHIFT(vap->iv_vht_cap.vht_cap_info, in ieee80211_vht_get_vhtflags()
1952 (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT80P80)) { in ieee80211_vht_get_vhtflags()
1960 } else if ((ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_80MHZ) && in ieee80211_vht_get_vhtflags()
1961 (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT80)) { in ieee80211_vht_get_vhtflags()
1969 } else if (ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_USE_HT) { in ieee80211_vht_get_vhtflags()
1979 (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT40)) { in ieee80211_vht_get_vhtflags()
1983 (vap->iv_vht_flags & IEEE80211_FVHT_USEVHT40)) { in ieee80211_vht_get_vhtflags()
2008 * is called - which will change the channel config for the
2015 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updateparams_final()
2022 htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ? in ieee80211_ht_updateparams_final()
2026 if ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH_2040) && in ieee80211_ht_updateparams_final()
2027 (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) { in ieee80211_ht_updateparams_final()
2028 if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_ABOVE) in ieee80211_ht_updateparams_final()
2030 else if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_BELOW) in ieee80211_ht_updateparams_final()
2035 * VHT flags - do much the same; check whether VHT is available in ieee80211_ht_updateparams_final()
2037 * capabilities and the (pre-parsed) VHT info IE. in ieee80211_ht_updateparams_final()
2048 * Parse and update HT-related state extracted from the HT cap ie
2056 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updatehtcap()
2059 if (vap->iv_htcaps & IEEE80211_HTC_SMPS) in ieee80211_ht_updatehtcap()
2066 * Called once HT and VHT capabilities are parsed in hostap mode -
2073 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ht_updatehtcap_final()
2079 htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ? in ieee80211_ht_updatehtcap_final()
2081 if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) && in ieee80211_ht_updatehtcap_final()
2082 (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) { in ieee80211_ht_updatehtcap_final()
2083 if (IEEE80211_IS_CHAN_HT40U(vap->iv_bss->ni_chan)) in ieee80211_ht_updatehtcap_final()
2085 else if (IEEE80211_IS_CHAN_HT40D(vap->iv_bss->ni_chan)) in ieee80211_ht_updatehtcap_final()
2089 * VHT flags - do much the same; check whether VHT is available in ieee80211_ht_updatehtcap_final()
2091 * capabilities and the (pre-parsed) VHT info IE. in ieee80211_ht_updatehtcap_final()
2104 struct ieee80211com *ic = ni->ni_ic; in ieee80211_setup_htrates()
2105 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_setup_htrates()
2110 maxequalmcs = ic->ic_txstream * 8 - 1; in ieee80211_setup_htrates()
2112 if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) { in ieee80211_setup_htrates()
2113 if (ic->ic_txstream >= 2) in ieee80211_setup_htrates()
2115 if (ic->ic_txstream >= 3) in ieee80211_setup_htrates()
2117 if (ic->ic_txstream >= 4) in ieee80211_setup_htrates()
2121 rs = &ni->ni_htrates; in ieee80211_setup_htrates()
2128 if (isclr(htcap->hc_mcsset, i)) in ieee80211_setup_htrates()
2130 if (rs->rs_nrates == IEEE80211_HTRATE_MAXSIZE) { in ieee80211_setup_htrates()
2135 vap->iv_stats.is_rx_rstoobig++; in ieee80211_setup_htrates()
2141 (ic->ic_htcaps & IEEE80211_HTC_TXMCS32) == 0) in ieee80211_setup_htrates()
2145 rs->rs_rates[rs->rs_nrates++] = i; in ieee80211_setup_htrates()
2165 rs = &ni->ni_htrates; in ieee80211_setup_basic_htrates()
2166 if (rs->rs_nrates == 0) { in ieee80211_setup_basic_htrates()
2167 IEEE80211_NOTE(ni->ni_vap, in ieee80211_setup_basic_htrates()
2173 if (isclr(htinfo->hi_basicmcsset, i)) in ieee80211_setup_basic_htrates()
2175 for (j = 0; j < rs->rs_nrates; j++) in ieee80211_setup_basic_htrates()
2176 if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == i) in ieee80211_setup_basic_htrates()
2177 rs->rs_rates[j] |= IEEE80211_RATE_BASIC; in ieee80211_setup_basic_htrates()
2184 callout_init(&tap->txa_timer, 1); in ampdu_tx_setup()
2185 tap->txa_flags |= IEEE80211_AGGR_SETUP; in ampdu_tx_setup()
2186 tap->txa_lastsample = ticks; in ampdu_tx_setup()
2192 struct ieee80211_node *ni = tap->txa_ni; in ampdu_tx_stop()
2193 struct ieee80211com *ic = ni->ni_ic; in ampdu_tx_stop()
2195 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ampdu_tx_stop()
2196 tap->txa_ni, in ampdu_tx_stop()
2200 KASSERT(tap->txa_flags & IEEE80211_AGGR_SETUP, in ampdu_tx_stop()
2201 ("txa_flags 0x%x tid %d ac %d", tap->txa_flags, tap->txa_tid, in ampdu_tx_stop()
2202 TID_TO_WME_AC(tap->txa_tid))); in ampdu_tx_stop()
2208 ic->ic_addba_stop(ni, tap); in ampdu_tx_stop()
2219 /* NB: clearing NAK means we may re-send ADDBA */ in ampdu_tx_stop()
2220 tap->txa_flags &= ~(IEEE80211_AGGR_SETUP | IEEE80211_AGGR_NAK); in ampdu_tx_stop()
2226 * If software aggregation and per-TID queue management was done here,
2233 struct ieee80211_node *ni = tap->txa_ni; in addba_timeout()
2234 struct ieee80211com *ic = ni->ni_ic; in addba_timeout()
2237 tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND; in addba_timeout()
2238 tap->txa_attempts++; in addba_timeout()
2239 ic->ic_addba_response_timeout(ni, tap); in addba_timeout()
2246 callout_reset(&tap->txa_timer, ieee80211_addba_timeout, in addba_start_timeout()
2248 tap->txa_flags |= IEEE80211_AGGR_XCHGPEND; in addba_start_timeout()
2249 tap->txa_nextrequest = ticks + ieee80211_addba_timeout; in addba_start_timeout()
2256 if (tap->txa_flags & IEEE80211_AGGR_XCHGPEND) { in addba_stop_timeout()
2257 callout_stop(&tap->txa_timer); in addba_stop_timeout()
2258 tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND; in addba_stop_timeout()
2269 * Default method for requesting A-MPDU tx aggregation.
2281 tap->txa_token = dialogtoken; in ieee80211_addba_request()
2282 tap->txa_flags |= IEEE80211_AGGR_IMMEDIATE; in ieee80211_addba_request()
2284 tap->txa_wnd = (bufsiz == 0) ? in ieee80211_addba_request()
2301 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ampdu_tx_request_ext()
2304 if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) { in ieee80211_ampdu_tx_request_ext()
2309 tap->txa_flags &= ~IEEE80211_AGGR_NAK; in ieee80211_ampdu_tx_request_ext()
2325 tap = &ni->ni_tx_ampdu[tid]; in ieee80211_ampdu_tx_request_active_ext()
2330 tap->txa_flags |= IEEE80211_AGGR_RUNNING; in ieee80211_ampdu_tx_request_active_ext()
2331 tap->txa_attempts = 0; in ieee80211_ampdu_tx_request_active_ext()
2334 tap->txa_flags |= IEEE80211_AGGR_NAK; in ieee80211_ampdu_tx_request_active_ext()
2340 * Default method for processing an A-MPDU tx aggregation
2349 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_addba_response()
2357 tap->txa_wnd = (bufsiz == 0) ? in ieee80211_addba_response()
2362 tap->txa_flags |= IEEE80211_AGGR_RUNNING; in ieee80211_addba_response()
2363 tap->txa_attempts = 0; in ieee80211_addba_response()
2365 if ((vap->iv_htcaps & IEEE80211_HTC_TX_AMSDU_AMPDU) && in ieee80211_addba_response()
2366 (ni->ni_flags & IEEE80211_NODE_AMSDU_TX) && in ieee80211_addba_response()
2368 tap->txa_flags |= IEEE80211_AGGR_AMSDU; in ieee80211_addba_response()
2370 tap->txa_flags &= ~IEEE80211_AGGR_AMSDU; in ieee80211_addba_response()
2373 tap->txa_flags |= IEEE80211_AGGR_NAK; in ieee80211_addba_response()
2379 * Default method for stopping A-MPDU tx aggregation.
2387 if (tap->txa_flags & IEEE80211_AGGR_RUNNING) { in ieee80211_addba_stop()
2389 tap->txa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_AMSDU); in ieee80211_addba_stop()
2391 tap->txa_attempts = 0; in ieee80211_addba_stop()
2396 * policy. We intercept ADDBA-related frames and use them to
2405 struct ieee80211com *ic = ni->ni_ic; in ht_recv_action_ba_addba_request()
2406 struct ieee80211vap *vap = ni->ni_vap; in ht_recv_action_ba_addba_request()
2430 rap = &ni->ni_rx_ampdu[tid]; in ht_recv_action_ba_addba_request()
2439 if ((ni->ni_flags & IEEE80211_NODE_AMPDU_RX) && in ht_recv_action_ba_addba_request()
2440 (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_RX)) { in ht_recv_action_ba_addba_request()
2442 ic->ic_ampdu_rx_start(ni, rap, in ht_recv_action_ba_addba_request()
2449 ni->ni_flags & IEEE80211_NODE_AMPDU_RX ? in ht_recv_action_ba_addba_request()
2452 vap->iv_stats.is_addba_reject++; in ht_recv_action_ba_addba_request()
2458 | _IEEE80211_SHIFTMASK(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ) in ht_recv_action_ba_addba_request()
2466 (ni->ni_flags & IEEE80211_NODE_AMSDU_RX) && in ht_recv_action_ba_addba_request()
2467 (vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU)) in ht_recv_action_ba_addba_request()
2472 ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, in ht_recv_action_ba_addba_request()
2482 struct ieee80211com *ic = ni->ni_ic; in ht_recv_action_ba_addba_response()
2483 struct ieee80211vap *vap = ni->ni_vap; in ht_recv_action_ba_addba_response()
2503 tap = &ni->ni_tx_ampdu[tid]; in ht_recv_action_ba_addba_response()
2504 if ((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0) { in ht_recv_action_ba_addba_response()
2507 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2510 vap->iv_stats.is_addba_norequest++; in ht_recv_action_ba_addba_response()
2513 if (dialogtoken != tap->txa_token) { in ht_recv_action_ba_addba_response()
2516 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2519 tap->txa_token, dialogtoken, tid, code); in ht_recv_action_ba_addba_response()
2520 vap->iv_stats.is_addba_badtoken++; in ht_recv_action_ba_addba_response()
2524 if (policy != (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE)) { in ht_recv_action_ba_addba_response()
2527 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2530 tap->txa_flags & IEEE80211_AGGR_IMMEDIATE, in ht_recv_action_ba_addba_response()
2532 vap->iv_stats.is_addba_badpolicy++; in ht_recv_action_ba_addba_response()
2540 ni->ni_macaddr, "ADDBA response", in ht_recv_action_ba_addba_response()
2544 vap->iv_stats.is_addba_badbawinsize++; in ht_recv_action_ba_addba_response()
2556 ic->ic_addba_response(ni, tap, code, baparamset, batimeout); in ht_recv_action_ba_addba_response()
2565 struct ieee80211com *ic = ni->ni_ic; in ht_recv_action_ba_delba()
2581 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, in ht_recv_action_ba_delba()
2587 tap = &ni->ni_tx_ampdu[tid]; in ht_recv_action_ba_delba()
2588 ic->ic_addba_stop(ni, tap); in ht_recv_action_ba_delba()
2590 rap = &ni->ni_rx_ampdu[tid]; in ht_recv_action_ba_delba()
2591 ic->ic_ampdu_rx_stop(ni, rap); in ht_recv_action_ba_delba()
2604 if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) == 0) in ht_recv_action_ht_txchwidth()
2610 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, in ht_recv_action_ht_txchwidth()
2612 __func__, chw, IEEE80211_NI_CHW_BITS, ni->ni_chw != chw ? "*" : ""); in ht_recv_action_ht_txchwidth()
2613 if (chw != ni->ni_chw) { in ht_recv_action_ht_txchwidth()
2615 ni->ni_chw = chw; in ht_recv_action_ht_txchwidth()
2630 if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA) in ht_recv_action_ht_mimopwrsave()
2631 ni->ni_flags |= IEEE80211_NODE_MIMO_PS; in ht_recv_action_ht_mimopwrsave()
2633 ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; in ht_recv_action_ht_mimopwrsave()
2634 if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE) in ht_recv_action_ht_mimopwrsave()
2635 ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; in ht_recv_action_ht_mimopwrsave()
2637 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; in ht_recv_action_ht_mimopwrsave()
2639 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, in ht_recv_action_ht_mimopwrsave()
2641 (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ? "on" : "off", in ht_recv_action_ht_mimopwrsave()
2642 (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ? "+rts" : "" in ht_recv_action_ht_mimopwrsave()
2652 * Check if A-MPDU should be requested/enabled for a stream.
2653 * We require a traffic rate above a per-AC threshold and we
2663 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ampdu_enable()
2665 if (tap->txa_avgpps < in ieee80211_ampdu_enable()
2666 vap->iv_ampdu_mintraffic[TID_TO_WME_AC(tap->txa_tid)]) in ieee80211_ampdu_enable()
2669 if (tap->txa_attempts >= ieee80211_addba_maxtries && in ieee80211_ampdu_enable()
2670 ieee80211_time_after(ticks, tap->txa_nextrequest)) { in ieee80211_ampdu_enable()
2680 tap->txa_tid, ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)], in ieee80211_ampdu_enable()
2681 tap->txa_avgpps, tap->txa_pkts, tap->txa_attempts); in ieee80211_ampdu_enable()
2686 * Request A-MPDU tx aggregation. Setup local state and
2694 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ampdu_request()
2700 if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) { in ieee80211_ampdu_request()
2705 tap->txa_flags &= ~IEEE80211_AGGR_NAK; in ieee80211_ampdu_request()
2708 tid = tap->txa_tid; in ieee80211_ampdu_request()
2713 tap->txa_start = ni->ni_txseqs[tid]; in ieee80211_ampdu_request()
2724 if ((ni->ni_flags & IEEE80211_NODE_AMSDU_TX) && in ieee80211_ampdu_request()
2725 (ni->ni_vap->iv_htcaps & IEEE80211_HTC_TX_AMSDU_AMPDU)) in ieee80211_ampdu_request()
2730 if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) { in ieee80211_ampdu_request()
2732 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_ampdu_request()
2734 __func__, tap->txa_tid, TID_TO_WME_AC(tap->txa_tid)); in ieee80211_ampdu_request()
2736 tap->txa_attempts = ieee80211_addba_maxtries; in ieee80211_ampdu_request()
2738 if (tap->txa_nextrequest <= ticks) in ieee80211_ampdu_request()
2739 tap->txa_nextrequest = ticks + ieee80211_addba_backoff; in ieee80211_ampdu_request()
2744 args[4] = _IEEE80211_SHIFTMASK(tap->txa_start, IEEE80211_BASEQ_START) in ieee80211_ampdu_request()
2747 return ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, in ieee80211_ampdu_request()
2759 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ampdu_stop()
2760 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ampdu_stop()
2764 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; in ieee80211_ampdu_stop()
2768 __func__, tap->txa_tid, reason, in ieee80211_ampdu_stop()
2770 vap->iv_stats.is_ampdu_stop++; in ieee80211_ampdu_stop()
2772 ic->ic_addba_stop(ni, tap); in ieee80211_ampdu_stop()
2773 args[0] = tap->txa_tid; in ieee80211_ampdu_stop()
2776 ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA, in ieee80211_ampdu_stop()
2781 "(reason: %d (%s))", __func__, tap->txa_tid, reason, in ieee80211_ampdu_stop()
2783 vap->iv_stats.is_ampdu_stop_failed++; in ieee80211_ampdu_stop()
2794 struct ieee80211_node *ni = tap->txa_ni; in bar_timeout()
2796 KASSERT((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0, in bar_timeout()
2797 ("bar/addba collision, flags 0x%x", tap->txa_flags)); in bar_timeout()
2799 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in bar_timeout()
2801 tap->txa_tid, tap->txa_flags, tap->txa_attempts); in bar_timeout()
2804 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0) in bar_timeout()
2807 if (tap->txa_attempts >= ieee80211_bar_maxtries) { in bar_timeout()
2808 struct ieee80211com *ic = ni->ni_ic; in bar_timeout()
2810 ni->ni_vap->iv_stats.is_ampdu_bar_tx_fail++; in bar_timeout()
2819 ic->ic_bar_response(ni, tap, 1); in bar_timeout()
2822 ni->ni_vap->iv_stats.is_ampdu_bar_tx_retry++; in bar_timeout()
2823 if (ieee80211_send_bar(ni, tap, tap->txa_seqpending) != 0) { in bar_timeout()
2824 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in bar_timeout()
2836 tap->txa_flags |= IEEE80211_AGGR_BARPEND; in bar_timeout()
2845 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in bar_start_timer()
2846 tap->txa_ni, in bar_start_timer()
2849 callout_reset(&tap->txa_timer, ieee80211_bar_timeout, bar_timeout, tap); in bar_start_timer()
2855 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in bar_stop_timer()
2856 tap->txa_ni, in bar_stop_timer()
2859 callout_stop(&tap->txa_timer); in bar_stop_timer()
2867 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in bar_tx_complete()
2869 __func__, tap->txa_tid, tap->txa_flags, in bar_tx_complete()
2870 callout_pending(&tap->txa_timer), status); in bar_tx_complete()
2872 ni->ni_vap->iv_stats.is_ampdu_bar_tx++; in bar_tx_complete()
2874 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) && in bar_tx_complete()
2875 callout_pending(&tap->txa_timer)) { in bar_tx_complete()
2876 struct ieee80211com *ic = ni->ni_ic; in bar_tx_complete()
2880 ic->ic_bar_response(ni, tap, status); in bar_tx_complete()
2890 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_bar_response()
2891 tap->txa_ni, in ieee80211_bar_response()
2895 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_bar_response()
2897 tap->txa_start, in ieee80211_bar_response()
2898 IEEE80211_SEQ_ADD(tap->txa_start, tap->txa_wnd-1), in ieee80211_bar_response()
2899 tap->txa_qframes, tap->txa_seqpending, in ieee80211_bar_response()
2900 tap->txa_tid); in ieee80211_bar_response()
2903 tap->txa_start = tap->txa_seqpending; in ieee80211_bar_response()
2904 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; in ieee80211_bar_response()
2919 #define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0) in ieee80211_send_bar()
2920 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_send_bar()
2921 struct ieee80211com *ic = ni->ni_ic; in ieee80211_send_bar()
2928 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_send_bar()
2929 tap->txa_ni, in ieee80211_send_bar()
2933 if ((tap->txa_flags & IEEE80211_AGGR_RUNNING) == 0) { in ieee80211_send_bar()
2943 m = ieee80211_getmgtframe(&frm, ic->ic_headroom, sizeof(*bar)); in ieee80211_send_bar()
2954 bar->i_fc[0] = IEEE80211_FC0_VERSION_0 | in ieee80211_send_bar()
2956 bar->i_fc[1] = 0; in ieee80211_send_bar()
2957 IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr); in ieee80211_send_bar()
2958 IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr); in ieee80211_send_bar()
2960 tid = tap->txa_tid; in ieee80211_send_bar()
2961 barctl = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ? in ieee80211_send_bar()
2968 bar->i_ctl = htole16(barctl); in ieee80211_send_bar()
2969 bar->i_seq = htole16(barseqctl); in ieee80211_send_bar()
2970 m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_bar); in ieee80211_send_bar()
2978 if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0) in ieee80211_send_bar()
2979 tap->txa_attempts = 1; in ieee80211_send_bar()
2981 tap->txa_attempts++; in ieee80211_send_bar()
2982 tap->txa_seqpending = seq; in ieee80211_send_bar()
2983 tap->txa_flags |= IEEE80211_AGGR_BARPEND; in ieee80211_send_bar()
2987 tid, barctl, seq, tap->txa_attempts); in ieee80211_send_bar()
3001 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; in ieee80211_send_bar()
3002 vap->iv_stats.is_ampdu_bar_tx_fail++; in ieee80211_send_bar()
3006 if (tap->txa_flags & IEEE80211_AGGR_BARPEND) in ieee80211_send_bar()
3010 IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N, in ieee80211_send_bar()
3011 tap->txa_ni, in ieee80211_send_bar()
3014 vap->iv_stats.is_ampdu_bar_tx_fail++; in ieee80211_send_bar()
3027 params.ibp_rate0 = ni->ni_txparms->mgmtrate; in ht_action_output()
3029 params.ibp_try0 = ni->ni_txparms->maxretry; in ht_action_output()
3030 params.ibp_power = ni->ni_txpower; in ht_action_output()
3050 struct ieee80211vap *vap = ni->ni_vap; in ht_send_action_ba_addba()
3051 struct ieee80211com *ic = ni->ni_ic; in ht_send_action_ba_addba()
3067 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in ht_send_action_ba_addba()
3071 ic->ic_headroom + sizeof(struct ieee80211_frame), in ht_send_action_ba_addba()
3086 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in ht_send_action_ba_addba()
3089 vap->iv_stats.is_tx_nobuf++; in ht_send_action_ba_addba()
3099 struct ieee80211vap *vap = ni->ni_vap; in ht_send_action_ba_delba()
3100 struct ieee80211com *ic = ni->ni_ic; in ht_send_action_ba_delba()
3115 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in ht_send_action_ba_delba()
3119 ic->ic_headroom + sizeof(struct ieee80211_frame), in ht_send_action_ba_delba()
3129 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in ht_send_action_ba_delba()
3132 vap->iv_stats.is_tx_nobuf++; in ht_send_action_ba_delba()
3142 struct ieee80211vap *vap = ni->ni_vap; in ht_send_action_ht_txchwidth()
3143 struct ieee80211com *ic = ni->ni_ic; in ht_send_action_ht_txchwidth()
3149 IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20); in ht_send_action_ht_txchwidth()
3153 ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1); in ht_send_action_ht_txchwidth()
3157 ic->ic_headroom + sizeof(struct ieee80211_frame), in ht_send_action_ht_txchwidth()
3165 *frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? in ht_send_action_ht_txchwidth()
3168 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); in ht_send_action_ht_txchwidth()
3171 vap->iv_stats.is_tx_nobuf++; in ht_send_action_ht_txchwidth()
3188 KASSERT((ic->ic_rxstream > 0 && ic->ic_rxstream <= 4), in ieee80211_set_mcsset()
3189 ("ic_rxstream %d out of range", ic->ic_rxstream)); in ieee80211_set_mcsset()
3190 KASSERT((ic->ic_txstream > 0 && ic->ic_txstream <= 4), in ieee80211_set_mcsset()
3191 ("ic_txstream %d out of range", ic->ic_txstream)); in ieee80211_set_mcsset()
3193 for (i = 0; i < ic->ic_rxstream * 8; i++) in ieee80211_set_mcsset()
3195 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) && in ieee80211_set_mcsset()
3196 (ic->ic_htcaps & IEEE80211_HTC_RXMCS32)) in ieee80211_set_mcsset()
3198 if (ic->ic_htcaps & IEEE80211_HTC_RXUNEQUAL) { in ieee80211_set_mcsset()
3199 if (ic->ic_rxstream >= 2) { in ieee80211_set_mcsset()
3203 if (ic->ic_rxstream >= 3) { in ieee80211_set_mcsset()
3207 if (ic->ic_rxstream >= 4) { in ieee80211_set_mcsset()
3214 if (ic->ic_rxstream != ic->ic_txstream) { in ieee80211_set_mcsset()
3216 txparams |= (ic->ic_txstream - 1) << 2; /* num TX streams */ in ieee80211_set_mcsset()
3217 if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) in ieee80211_set_mcsset()
3235 struct ieee80211com *ic = ni->ni_ic; in ieee80211_add_htcap_body()
3236 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_add_htcap_body()
3241 caps = vap->iv_htcaps & 0xffff; in ieee80211_add_htcap_body()
3250 if (vap->iv_opmode == IEEE80211_M_STA) { in ieee80211_add_htcap_body()
3252 if (vap->iv_flags_ht & IEEE80211_FHT_USEHT40) in ieee80211_add_htcap_body()
3258 rxmax = _IEEE80211_MASKSHIFT(ni->ni_htparam, in ieee80211_add_htcap_body()
3260 density = _IEEE80211_MASKSHIFT(ni->ni_htparam, in ieee80211_add_htcap_body()
3268 vap->iv_ampdu_rxmax, in ieee80211_add_htcap_body()
3269 vap->iv_ampdu_density); in ieee80211_add_htcap_body()
3272 if (rxmax > vap->iv_ampdu_rxmax) in ieee80211_add_htcap_body()
3273 rxmax = vap->iv_ampdu_rxmax; in ieee80211_add_htcap_body()
3278 * (Larger density value == larger minimum gap between A-MPDU in ieee80211_add_htcap_body()
3281 if (vap->iv_ampdu_density > density) in ieee80211_add_htcap_body()
3282 density = vap->iv_ampdu_density; in ieee80211_add_htcap_body()
3290 if (ni->ni_chan != IEEE80211_CHAN_ANYC && in ieee80211_add_htcap_body()
3291 findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40U) == NULL && in ieee80211_add_htcap_body()
3292 findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40D) == NULL) in ieee80211_add_htcap_body()
3296 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) in ieee80211_add_htcap_body()
3302 rxmax = vap->iv_ampdu_rxmax; in ieee80211_add_htcap_body()
3303 density = vap->iv_ampdu_density; in ieee80211_add_htcap_body()
3307 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) in ieee80211_add_htcap_body()
3309 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0 || in ieee80211_add_htcap_body()
3314 if ((vap->iv_flags_ht & IEEE80211_FHT_STBC_RX) == 0) in ieee80211_add_htcap_body()
3318 if ((vap->iv_flags_ht & IEEE80211_FHT_LDPC_RX) == 0) in ieee80211_add_htcap_body()
3329 /* pre-zero remainder of ie */ in ieee80211_add_htcap_body()
3330 memset(frm, 0, sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body()
3340 ieee80211_set_mcsset(ni->ni_ic, frm); in ieee80211_add_htcap_body()
3342 frm += __offsetof(struct ieee80211_ie_htcap, hc_extcap) - in ieee80211_add_htcap_body()
3346 extcaps = vap->iv_htextcaps & 0xffff; in ieee80211_add_htcap_body()
3350 frm += sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body()
3364 frm[1] = sizeof(struct ieee80211_ie_htcap) - 2; in ieee80211_add_htcap()
3369 * Non-associated probe request - add HT capabilities based on
3381 struct ieee80211com *ic = vap->iv_ic; in ieee80211_add_htcap_body_ch()
3386 caps = vap->iv_htcaps & 0xffff; in ieee80211_add_htcap_body_ch()
3401 rxmax = vap->iv_ampdu_rxmax; in ieee80211_add_htcap_body_ch()
3402 density = vap->iv_ampdu_density; in ieee80211_add_htcap_body_ch()
3405 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) in ieee80211_add_htcap_body_ch()
3407 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0 || in ieee80211_add_htcap_body_ch()
3418 /* pre-zero remainder of ie */ in ieee80211_add_htcap_body_ch()
3419 memset(frm, 0, sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body_ch()
3431 frm += __offsetof(struct ieee80211_ie_htcap, hc_extcap) - in ieee80211_add_htcap_body_ch()
3435 extcaps = vap->iv_htextcaps & 0xffff; in ieee80211_add_htcap_body_ch()
3439 frm += sizeof(struct ieee80211_ie_htcap) - in ieee80211_add_htcap_body_ch()
3454 frm[1] = sizeof(struct ieee80211_ie_htcap) - 2; in ieee80211_add_htcap_ch()
3460 * used for compatibility w/ pre-draft implementations.
3466 frm[1] = 4 + sizeof(struct ieee80211_ie_htcap) - 2; in ieee80211_add_htcap_vendor()
3483 for (i = 0; i < rs->rs_nrates; i++) { in ieee80211_set_basic_htrates()
3484 int r = rs->rs_rates[i] & IEEE80211_RATE_VAL; in ieee80211_set_basic_htrates()
3485 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && in ieee80211_set_basic_htrates()
3503 struct ieee80211com *ic = vap->iv_ic; in ieee80211_ht_update_beacon()
3505 (struct ieee80211_ie_htinfo *) bo->bo_htinfo; in ieee80211_ht_update_beacon()
3507 ni = ieee80211_ref_node(vap->iv_bss); in ieee80211_ht_update_beacon()
3508 bsschan = ni->ni_chan; in ieee80211_ht_update_beacon()
3511 ht->hi_ctrlchannel = ieee80211_chan2ieee(ic, bsschan); in ieee80211_ht_update_beacon()
3512 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) in ieee80211_ht_update_beacon()
3513 ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PERM; in ieee80211_ht_update_beacon()
3515 ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PROH; in ieee80211_ht_update_beacon()
3517 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_ABOVE; in ieee80211_ht_update_beacon()
3519 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_BELOW; in ieee80211_ht_update_beacon()
3521 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_NONE; in ieee80211_ht_update_beacon()
3523 ht->hi_byte1 |= IEEE80211_HTINFO_TXWIDTH_2040; in ieee80211_ht_update_beacon()
3527 * XXX TODO: this uses the global flag, not the per-VAP flag. in ieee80211_ht_update_beacon()
3528 * Eventually (once the protection modes are done per-channel in ieee80211_ht_update_beacon()
3529 * rather than per-VAP) we can flip this over to be per-VAP but in ieee80211_ht_update_beacon()
3532 ht->hi_byte2 = (ht->hi_byte2 &~ PROTMODE) | ic->ic_curhtprotmode; in ieee80211_ht_update_beacon()
3550 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_add_htinfo_body()
3551 struct ieee80211com *ic = ni->ni_ic; in ieee80211_add_htinfo_body()
3553 /* pre-zero remainder of ie */ in ieee80211_add_htinfo_body()
3554 memset(frm, 0, sizeof(struct ieee80211_ie_htinfo) - 2); in ieee80211_add_htinfo_body()
3557 *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan); in ieee80211_add_htinfo_body()
3559 if (vap->iv_flags_ht & IEEE80211_FHT_RIFS) in ieee80211_add_htinfo_body()
3563 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan)) in ieee80211_add_htinfo_body()
3565 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan)) in ieee80211_add_htinfo_body()
3569 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) in ieee80211_add_htinfo_body()
3574 * this will respect the per-VAP flags. in ieee80211_add_htinfo_body()
3576 frm[1] = vap->iv_curhtprotmode; in ieee80211_add_htinfo_body()
3581 ieee80211_set_basic_htrates(frm, &ni->ni_htrates); in ieee80211_add_htinfo_body()
3582 frm += sizeof(struct ieee80211_ie_htinfo) - in ieee80211_add_htinfo_body()
3594 frm[1] = sizeof(struct ieee80211_ie_htinfo) - 2; in ieee80211_add_htinfo()
3600 * used for compatibility w/ pre-draft implementations.
3606 frm[1] = 4 + sizeof(struct ieee80211_ie_htinfo) - 2; in ieee80211_add_htinfo_vendor()
3618 * Larger values are longer A-MPDU density spacing values, and
3627 vap = ni->ni_vap; in ieee80211_ht_get_node_ampdu_density()
3629 _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY); in ieee80211_ht_get_node_ampdu_density()
3630 if (vap->iv_ampdu_density > peer_mpdudensity) in ieee80211_ht_get_node_ampdu_density()
3631 peer_mpdudensity = vap->iv_ampdu_density; in ieee80211_ht_get_node_ampdu_density()
3636 * Get the transmit A-MPDU limit for the given 802.11n node.
3639 * Smaller values indicate smaller maximum A-MPDU sizes, and
3640 * should be used when forming an A-MPDU to the given peer.
3648 vap = ni->ni_vap; in ieee80211_ht_get_node_ampdu_limit()
3650 _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU); in ieee80211_ht_get_node_ampdu_limit()
3652 return (MIN(vap->iv_ampdu_limit, peer_mpdulimit)); in ieee80211_ht_get_node_ampdu_limit()
3656 * Return true if short-GI is available when transmitting to
3671 vap = ni->ni_vap; in ieee80211_ht_check_tx_shortgi_20()
3672 ic = ni->ni_ic; in ieee80211_ht_check_tx_shortgi_20()
3674 return ((ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) && in ieee80211_ht_check_tx_shortgi_20()
3675 (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) && in ieee80211_ht_check_tx_shortgi_20()
3676 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20)); in ieee80211_ht_check_tx_shortgi_20()
3680 * Return true if short-GI is available when transmitting to
3695 vap = ni->ni_vap; in ieee80211_ht_check_tx_shortgi_40()
3696 ic = ni->ni_ic; in ieee80211_ht_check_tx_shortgi_40()
3698 return ((ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40) && in ieee80211_ht_check_tx_shortgi_40()
3699 (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) && in ieee80211_ht_check_tx_shortgi_40()
3700 (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40)); in ieee80211_ht_check_tx_shortgi_40()
3715 if (ni == NULL || ni->ni_chan == IEEE80211_CHAN_ANYC || in ieee80211_ht_check_tx_ht()
3716 ni->ni_vap == NULL || ni->ni_vap->iv_bss == NULL) in ieee80211_ht_check_tx_ht()
3719 vap = ni->ni_vap; in ieee80211_ht_check_tx_ht()
3720 bss_chan = vap->iv_bss->ni_chan; in ieee80211_ht_check_tx_ht()
3725 if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && in ieee80211_ht_check_tx_ht()
3726 ni->ni_htrates.rs_nrates == 0) in ieee80211_ht_check_tx_ht()
3728 return (IEEE80211_IS_CHAN_HT(ni->ni_chan)); in ieee80211_ht_check_tx_ht()
3746 vap = ni->ni_vap; in ieee80211_ht_check_tx_ht40()
3747 bss_chan = vap->iv_bss->ni_chan; in ieee80211_ht_check_tx_ht40()
3750 IEEE80211_IS_CHAN_HT40(ni->ni_chan) && in ieee80211_ht_check_tx_ht40()
3751 (ni->ni_chw == IEEE80211_STA_RX_BW_40)); in ieee80211_ht_check_tx_ht40()