Lines Matching +full:always +full:- +full:turbo

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
54 * Atheros fast-frame encapsulation format.
60 /* fast frame header is 32-bits */
91 &ieee80211_ffppsmin, 0, "min packet rate before fast-frame staging");
92 static int ieee80211_ffagemax = -1; /* max time frames held on stage q */
96 "max hold time for fast-frame staging (ms)");
112 IEEE80211_FF_LOCK_INIT(ic, ic->ic_name); in ieee80211_superg_attach()
122 TIMEOUT_TASK_INIT(ic->ic_tq, &sg->ff_qtimer, 0, ff_age_all, ic); in ieee80211_superg_attach()
123 ic->ic_superg = sg; in ieee80211_superg_attach()
137 if (ic->ic_superg != NULL) { in ieee80211_superg_detach()
138 struct timeout_task *qtask = &ic->ic_superg->ff_qtimer; in ieee80211_superg_detach()
140 while (taskqueue_cancel_timeout(ic->ic_tq, qtask, NULL) != 0) in ieee80211_superg_detach()
141 taskqueue_drain_timeout(ic->ic_tq, qtask); in ieee80211_superg_detach()
142 IEEE80211_FREE(ic->ic_superg, M_80211_VAP); in ieee80211_superg_detach()
143 ic->ic_superg = NULL; in ieee80211_superg_detach()
151 struct ieee80211com *ic = vap->iv_ic; in ieee80211_superg_vattach()
153 if (ic->ic_superg == NULL) /* NB: can't do fast-frames w/o state */ in ieee80211_superg_vattach()
154 vap->iv_caps &= ~IEEE80211_C_FF; in ieee80211_superg_vattach()
155 if (vap->iv_caps & IEEE80211_C_FF) in ieee80211_superg_vattach()
156 vap->iv_flags |= IEEE80211_F_FF; in ieee80211_superg_vattach()
158 if (vap->iv_opmode == IEEE80211_M_STA && in ieee80211_superg_vattach()
159 (vap->iv_caps & IEEE80211_C_TURBOP)) in ieee80211_superg_vattach()
160 vap->iv_flags |= IEEE80211_F_TURBOP; in ieee80211_superg_vattach()
177 .ath_len = sizeof(struct ieee80211_ath_ie) - 2, in ieee80211_add_ath()
186 ath->ath_capability = caps; in ieee80211_add_ath()
188 ath->ath_defkeyix[0] = (defkeyix & 0xff); in ieee80211_add_ath()
189 ath->ath_defkeyix[1] = ((defkeyix >> 8) & 0xff); in ieee80211_add_ath()
191 ath->ath_defkeyix[0] = 0xff; in ieee80211_add_ath()
192 ath->ath_defkeyix[1] = 0x7f; in ieee80211_add_ath()
201 const struct ieee80211vap *vap = bss->ni_vap; in ieee80211_add_athcaps()
204 vap->iv_flags & IEEE80211_F_ATHEROS, in ieee80211_add_athcaps()
205 ((vap->iv_flags & IEEE80211_F_WPA) == 0 && in ieee80211_add_athcaps()
206 bss->ni_authmode != IEEE80211_AUTH_8021X) ? in ieee80211_add_athcaps()
207 vap->iv_def_txkey : IEEE80211_KEYIX_NONE); in ieee80211_add_athcaps()
216 ni->ni_ath_flags = ath->ath_capability; in ieee80211_parse_ath()
217 ni->ni_ath_defkeyix = le16dec(&ath->ath_defkeyix); in ieee80211_parse_ath()
224 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_parse_athparams()
230 if (len < sizeof(struct ieee80211_ath_ie)-2) { in ieee80211_parse_athparams()
234 return -1; in ieee80211_parse_athparams()
237 capschanged = (ni->ni_ath_flags != ath->ath_capability); in ieee80211_parse_athparams()
238 defkeyix = le16dec(ath->ath_defkeyix); in ieee80211_parse_athparams()
239 if (capschanged || defkeyix != ni->ni_ath_defkeyix) { in ieee80211_parse_athparams()
240 ni->ni_ath_flags = ath->ath_capability; in ieee80211_parse_athparams()
241 ni->ni_ath_defkeyix = defkeyix; in ieee80211_parse_athparams()
244 ni->ni_ath_flags, ni->ni_ath_defkeyix); in ieee80211_parse_athparams()
250 * Check for turbo mode switch. Calculate flags in ieee80211_parse_athparams()
253 newflags = curflags = vap->iv_ic->ic_bsschan->ic_flags; in ieee80211_parse_athparams()
255 if (ath->ath_capability & ATHEROS_CAP_BOOST) in ieee80211_parse_athparams()
274 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ff_decap()
284 * Check for fast-frame tunnel encapsulation. in ieee80211_ff_decap()
286 if (m->m_pkthdr.len < 3*FF_LLC_SIZE) in ieee80211_ff_decap()
288 if (m->m_len < FF_LLC_SIZE && in ieee80211_ff_decap()
291 ni->ni_macaddr, "fast-frame", in ieee80211_ff_decap()
293 vap->iv_stats.is_rx_tooshort++; in ieee80211_ff_decap()
298 if (llc->llc_snap.ether_type != htons(ATH_FF_ETH_TYPE)) in ieee80211_ff_decap()
304 ni->ni_macaddr, "fast-frame", in ieee80211_ff_decap()
306 vap->iv_stats.is_ff_badhdr++; in ieee80211_ff_decap()
311 m_adj(m, roundup(sizeof(uint32_t) - 2, 4) + 2); in ieee80211_ff_decap()
313 vap->iv_stats.is_ff_decap++; in ieee80211_ff_decap()
323 ni->ni_macaddr, "fast-frame", "%s", "first decap failed"); in ieee80211_ff_decap()
324 vap->iv_stats.is_ff_tooshort++; in ieee80211_ff_decap()
330 ni->ni_macaddr, "fast-frame", in ieee80211_ff_decap()
332 vap->iv_stats.is_ff_split++; in ieee80211_ff_decap()
337 vap->iv_deliver_data(vap, ni, m); /* 1st of pair */ in ieee80211_ff_decap()
342 m_adj(n, roundup2(framelen, 4) - framelen); /* padding */ in ieee80211_ff_decap()
346 ni->ni_macaddr, "fast-frame", "%s", "second decap failed"); in ieee80211_ff_decap()
347 vap->iv_stats.is_ff_tooshort++; in ieee80211_ff_decap()
370 m2 = m1->m_nextpkt; in ieee80211_ff_encap()
376 m1->m_nextpkt = NULL; in ieee80211_ff_encap()
381 KASSERT(m1->m_len >= sizeof(eh1), ("no ethernet header!")); in ieee80211_ff_encap()
396 KASSERT(m2->m_len >= sizeof(eh2), ("no ethernet header!")); in ieee80211_ff_encap()
417 * Pad leading frame to a 4-byte boundary. If there in ieee80211_ff_encap()
420 * frame. We know doing the second will always work in ieee80211_ff_encap()
424 for (m = m1; m->m_next != NULL; m = m->m_next) in ieee80211_ff_encap()
426 pad = roundup2(m1->m_pkthdr.len, 4) - m1->m_pkthdr.len; in ieee80211_ff_encap()
429 m2->m_data -= pad; in ieee80211_ff_encap()
430 m2->m_len += pad; in ieee80211_ff_encap()
431 m2->m_pkthdr.len += pad; in ieee80211_ff_encap()
433 m->m_len += pad; in ieee80211_ff_encap()
434 m1->m_pkthdr.len += pad; in ieee80211_ff_encap()
439 * A-MSDU's are just appended; the "I'm A-MSDU!" bit is in the in ieee80211_ff_encap()
444 m->m_next = m2; /* NB: last mbuf from above */ in ieee80211_ff_encap()
445 m1->m_pkthdr.len += m2->m_pkthdr.len; in ieee80211_ff_encap()
450 vap->iv_stats.is_tx_nobuf++; in ieee80211_ff_encap()
459 vap->iv_stats.is_tx_nobuf++; in ieee80211_ff_encap()
463 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; in ieee80211_ff_encap()
464 llc->llc_control = LLC_UI; in ieee80211_ff_encap()
465 llc->llc_snap.org_code[0] = ATH_FF_SNAP_ORGCODE_0; in ieee80211_ff_encap()
466 llc->llc_snap.org_code[1] = ATH_FF_SNAP_ORGCODE_1; in ieee80211_ff_encap()
467 llc->llc_snap.org_code[2] = ATH_FF_SNAP_ORGCODE_2; in ieee80211_ff_encap()
468 llc->llc_snap.ether_type = htons(ATH_FF_ETH_TYPE); in ieee80211_ff_encap()
470 vap->iv_stats.is_ff_encap++; in ieee80211_ff_encap()
474 vap->iv_stats.is_ff_encapfail++; in ieee80211_ff_encap()
483 * A-MSDU encapsulation.
486 * same queuing code and infrastructure as fast-frames.
501 m2 = m1->m_nextpkt; in ieee80211_amsdu_encap()
507 m1->m_nextpkt = NULL; in ieee80211_amsdu_encap()
510 * Include A-MSDU header in adjusting header layout. in ieee80211_amsdu_encap()
512 KASSERT(m1->m_len >= sizeof(eh1), ("no ethernet header!")); in ieee80211_amsdu_encap()
530 KASSERT(m2->m_len >= sizeof(eh2), ("no ethernet header!")); in ieee80211_amsdu_encap()
550 * Pad leading frame to a 4-byte boundary. If there in ieee80211_amsdu_encap()
553 * frame. We know doing the second will always work in ieee80211_amsdu_encap()
557 for (m = m1; m->m_next != NULL; m = m->m_next) in ieee80211_amsdu_encap()
559 pad = roundup2(m1->m_pkthdr.len, 4) - m1->m_pkthdr.len; in ieee80211_amsdu_encap()
562 m2->m_data -= pad; in ieee80211_amsdu_encap()
563 m2->m_len += pad; in ieee80211_amsdu_encap()
564 m2->m_pkthdr.len += pad; in ieee80211_amsdu_encap()
566 m->m_len += pad; in ieee80211_amsdu_encap()
567 m1->m_pkthdr.len += pad; in ieee80211_amsdu_encap()
574 m->m_next = m2; /* NB: last mbuf from above */ in ieee80211_amsdu_encap()
575 m1->m_pkthdr.len += m2->m_pkthdr.len; in ieee80211_amsdu_encap()
577 vap->iv_stats.is_amsdu_encap++; in ieee80211_amsdu_encap()
581 vap->iv_stats.is_amsdu_encapfail++; in ieee80211_amsdu_encap()
592 struct ieee80211vap *vap = ni->ni_vap; in ff_transmit()
593 struct ieee80211com *ic = ni->ni_ic; in ff_transmit()
606 * Flush frames to device; note we re-use the linked list
608 * which may be non-NULL.
618 next = m->m_nextpkt; in ff_flush()
619 m->m_nextpkt = NULL; in ff_flush()
621 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; in ff_flush()
622 vap = ni->ni_vap; in ff_flush()
626 vap->iv_stats.is_ff_flush++; in ff_flush()
643 if (sq->depth == 0) { in ieee80211_ff_age()
648 KASSERT(sq->head != NULL, ("stageq empty")); in ieee80211_ff_age()
650 head = sq->head; in ieee80211_ff_age()
651 while ((m = sq->head) != NULL && M_AGE_GET(m) < quanta) { in ieee80211_ff_age()
655 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; in ieee80211_ff_age()
656 KASSERT(ni->ni_tx_superg[tid] == m, ("staging queue empty")); in ieee80211_ff_age()
657 ni->ni_tx_superg[tid] = NULL; in ieee80211_ff_age()
659 sq->head = m->m_nextpkt; in ieee80211_ff_age()
660 sq->depth--; in ieee80211_ff_age()
663 sq->tail = NULL; in ieee80211_ff_age()
680 if (sq->tail != NULL) { in stageq_add()
681 sq->tail->m_nextpkt = m; in stageq_add()
682 age -= M_AGE_GET(sq->head); in stageq_add()
684 sq->head = m; in stageq_add()
686 struct timeout_task *qtask = &ic->ic_superg->ff_qtimer; in stageq_add()
687 taskqueue_enqueue_timeout(ic->ic_tq, qtask, age); in stageq_add()
691 m->m_nextpkt = NULL; in stageq_add()
692 sq->tail = m; in stageq_add()
693 sq->depth++; in stageq_add()
704 for (m = sq->head; m != NULL; m = m->m_nextpkt) { in stageq_remove()
707 sq->head = m->m_nextpkt; in stageq_remove()
709 mprev->m_nextpkt = m->m_nextpkt; in stageq_remove()
710 if (sq->tail == m) in stageq_remove()
711 sq->tail = mprev; in stageq_remove()
712 sq->depth--; in stageq_remove()
724 struct ieee80211com *ic = ni->ni_ic; in ff_approx_txtime()
725 struct ieee80211vap *vap = ni->ni_vap; in ff_approx_txtime()
732 * - 32: 802.11 encap + CRC in ff_approx_txtime()
733 * - 24: encryption overhead (if wep bit) in ff_approx_txtime()
734 * - 4 + 6: fast-frame header and padding in ff_approx_txtime()
735 * - 16: 2 LLC FF tunnel headers in ff_approx_txtime()
736 * - 14: 1 802.3 FF tunnel header (mbuf already accounts for 2nd) in ff_approx_txtime()
738 framelen = m1->m_pkthdr.len + 32 + in ff_approx_txtime()
740 if (vap->iv_flags & IEEE80211_F_PRIVACY) in ff_approx_txtime()
743 framelen += m2->m_pkthdr.len; in ff_approx_txtime()
746 * For now, we assume non-shortgi, 20MHz, just because I want to in ff_approx_txtime()
749 if (ni->ni_txrate & IEEE80211_RATE_MCS) in ff_approx_txtime()
751 ni->ni_txrate, in ff_approx_txtime()
752 IEEE80211_HT_RC_2_STREAMS(ni->ni_txrate), in ff_approx_txtime()
756 frame_time = ieee80211_compute_duration(ic->ic_rt, framelen, in ff_approx_txtime()
757 ni->ni_txrate, 0); in ff_approx_txtime()
769 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_ff_check()
770 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ff_check()
771 struct ieee80211_superg *sg = ic->ic_superg; in ieee80211_ff_check()
782 ic->ic_wme.wme_chanParams.cap_wmeParams[pri].wmep_txopLimit); in ieee80211_ff_check()
793 tap = &ni->ni_tx_ampdu[WME_AC_TO_TID(pri)]; in ieee80211_ff_check()
794 mstaged = ni->ni_tx_superg[WME_AC_TO_TID(pri)]; in ieee80211_ff_check()
795 /* XXX NOTE: reusing packet counter state from A-MPDU */ in ieee80211_ff_check()
797 * XXX NOTE: this means we're double-counting; it should just in ieee80211_ff_check()
798 * be done in ieee80211_output.c once for both superg and A-MPDU. in ieee80211_ff_check()
807 if (vap->iv_opmode != IEEE80211_M_STA && in ieee80211_ff_check()
808 ETHER_IS_MULTICAST(mtod(m, struct ether_header *)->ether_dhost)) { in ieee80211_ff_check()
822 sq = &sg->ff_stageq[pri]; in ieee80211_ff_check()
837 ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL; in ieee80211_ff_check()
860 ni->ni_tx_superg[WME_AC_TO_TID(pri)] = NULL; in ieee80211_ff_check()
865 "%s: aggregate fast-frame", __func__); in ieee80211_ff_check()
870 KASSERT(mstaged->m_pkthdr.rcvif == (void *)ni, in ieee80211_ff_check()
871 ("rcvif %p ni %p", mstaged->m_pkthdr.rcvif, ni)); in ieee80211_ff_check()
874 m->m_nextpkt = NULL; in ieee80211_ff_check()
875 mstaged->m_nextpkt = m; in ieee80211_ff_check()
876 mstaged->m_flags |= M_FF; /* NB: mark for encap work */ in ieee80211_ff_check()
878 KASSERT(ni->ni_tx_superg[WME_AC_TO_TID(pri)] == NULL, in ieee80211_ff_check()
880 ni->ni_tx_superg[WME_AC_TO_TID(pri)])); in ieee80211_ff_check()
881 ni->ni_tx_superg[WME_AC_TO_TID(pri)] = m; in ieee80211_ff_check()
887 "%s: stage frame, %u queued", __func__, sq->depth); in ieee80211_ff_check()
898 * and HTCAP requirements for the maximum A-MSDU in ieee80211_amsdu_check()
902 /* First: software A-MSDU transmit? */ in ieee80211_amsdu_check()
906 /* Next - EAPOL? Nope, don't aggregate; we don't QoS encap them */ in ieee80211_amsdu_check()
907 if (m->m_flags & (M_EAPOL | M_MCAST | M_BCAST)) in ieee80211_amsdu_check()
910 /* Next - needs to be a data frame, non-broadcast, etc */ in ieee80211_amsdu_check()
911 if (ETHER_IS_MULTICAST(mtod(m, struct ether_header *)->ether_dhost)) in ieee80211_amsdu_check()
921 * Clean FF state on re-associate. This handles the case in ieee80211_ff_node_init()
931 struct ieee80211com *ic = ni->ni_ic; in ieee80211_ff_node_cleanup()
932 struct ieee80211_superg *sg = ic->ic_superg; in ieee80211_ff_node_cleanup()
943 * This may be double-work for 11n stations; in ieee80211_ff_node_cleanup()
946 ieee80211_txampdu_init_pps(&ni->ni_tx_ampdu[tid]); in ieee80211_ff_node_cleanup()
947 m = ni->ni_tx_superg[tid]; in ieee80211_ff_node_cleanup()
949 ni->ni_tx_superg[tid] = NULL; in ieee80211_ff_node_cleanup()
950 stageq_remove(ic, &sg->ff_stageq[ac], m); in ieee80211_ff_node_cleanup()
951 m->m_nextpkt = head; in ieee80211_ff_node_cleanup()
963 next_m = m->m_nextpkt; in ieee80211_ff_node_cleanup()
971 * Switch between turbo and non-turbo operating modes.
979 struct ieee80211com *ic = vap->iv_ic; in ieee80211_dturbo_switch()
982 chan = ieee80211_find_channel(ic, ic->ic_bsschan->ic_freq, newflags); in ieee80211_dturbo_switch()
986 __func__, ic->ic_bsschan->ic_freq, newflags); in ieee80211_dturbo_switch()
991 "%s: %s -> %s (freq %u flags 0x%x)\n", __func__, in ieee80211_dturbo_switch()
992 ieee80211_phymode_name[ieee80211_chan2mode(ic->ic_bsschan)], in ieee80211_dturbo_switch()
994 chan->ic_freq, chan->ic_flags); in ieee80211_dturbo_switch()
996 ic->ic_bsschan = chan; in ieee80211_dturbo_switch()
997 ic->ic_prevchan = ic->ic_curchan; in ieee80211_dturbo_switch()
998 ic->ic_curchan = chan; in ieee80211_dturbo_switch()
999 ic->ic_rt = ieee80211_get_ratetable(chan); in ieee80211_dturbo_switch()
1000 ic->ic_set_channel(ic); in ieee80211_dturbo_switch()
1013 if (vap->iv_opmode == IEEE80211_M_STA && in getathcap()
1014 vap->iv_state == IEEE80211_S_RUN) in getathcap()
1015 return IEEE80211_ATH_CAP(vap, vap->iv_bss, cap) != 0; in getathcap()
1017 return (vap->iv_flags & cap) != 0; in getathcap()
1023 switch (ireq->i_type) { in superg_ioctl_get80211()
1025 ireq->i_val = getathcap(vap, IEEE80211_F_FF); in superg_ioctl_get80211()
1028 ireq->i_val = getathcap(vap, IEEE80211_F_TURBOP); in superg_ioctl_get80211()
1040 switch (ireq->i_type) { in superg_ioctl_set80211()
1042 if (ireq->i_val) { in superg_ioctl_set80211()
1043 if ((vap->iv_caps & IEEE80211_C_FF) == 0) in superg_ioctl_set80211()
1045 vap->iv_flags |= IEEE80211_F_FF; in superg_ioctl_set80211()
1047 vap->iv_flags &= ~IEEE80211_F_FF; in superg_ioctl_set80211()
1050 if (ireq->i_val) { in superg_ioctl_set80211()
1051 if ((vap->iv_caps & IEEE80211_C_TURBOP) == 0) in superg_ioctl_set80211()
1053 vap->iv_flags |= IEEE80211_F_TURBOP; in superg_ioctl_set80211()
1055 vap->iv_flags &= ~IEEE80211_F_TURBOP; in superg_ioctl_set80211()