ieee80211_ht.h revision 183245
1139823Simp/*- 21541Srgrimes * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting 31541Srgrimes * All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 141541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 151541Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161541Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171541Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 181541Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201541Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211541Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221541Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231541Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241541Srgrimes * 251541Srgrimes * $FreeBSD: head/sys/net80211/ieee80211_ht.h 183245 2008-09-21 22:22:28Z sam $ 261541Srgrimes */ 271541Srgrimes#ifndef _NET80211_IEEE80211_HT_H_ 281541Srgrimes#define _NET80211_IEEE80211_HT_H_ 291541Srgrimes 301541Srgrimes/* 311541Srgrimes * 802.11n protocol implementation definitions. 321541Srgrimes */ 331541Srgrimes 341541Srgrimes#define IEEE80211_AGGR_BAWMAX 64 /* max block ack window size */ 351541Srgrimes/* threshold for aging overlapping non-HT bss */ 361541Srgrimes#define IEEE80211_NONHT_PRESENT_AGE msecs_to_ticks(60*1000) 371541Srgrimes 38172467Ssilbytypedef uint16_t ieee80211_seq; 39172467Ssilby 40172467Ssilbystruct ieee80211_tx_ampdu { 4132350Seivind u_short txa_flags; 42101090Srwatson#define IEEE80211_AGGR_IMMEDIATE 0x0001 /* BA policy */ 43142215Sglebius#define IEEE80211_AGGR_XCHGPEND 0x0002 /* ADDBA response pending */ 4432350Seivind#define IEEE80211_AGGR_RUNNING 0x0004 /* ADDBA response received */ 451541Srgrimes#define IEEE80211_AGGR_SETUP 0x0008 /* deferred state setup */ 4612693Sphk#define IEEE80211_AGGR_NAK 0x0010 /* peer NAK'd ADDBA request */ 4744078Sdfr uint8_t txa_ac; 4812693Sphk uint8_t txa_token; /* dialog token */ 491541Srgrimes int txa_lastsample; /* ticks @ last traffic sample */ 5012693Sphk int txa_pkts; /* packets over last sample interval */ 511541Srgrimes int txa_avgpps; /* filtered traffic over window */ 5218892Sbde int txa_qbytes; /* data queued (bytes) */ 531541Srgrimes short txa_qframes; /* data queued (frames) */ 54181803Sbz ieee80211_seq txa_start; /* BA window left edge */ 551541Srgrimes ieee80211_seq txa_seqpending; /* new txa_start pending BAR response */ 561541Srgrimes uint16_t txa_wnd; /* BA window size */ 571541Srgrimes uint8_t txa_attempts; /* # ADDBA requests w/o a response */ 5844165Sjulian int txa_nextrequest;/* soonest to make next ADDBA request */ 591541Srgrimes struct callout txa_timer; 608426Swollman void *txa_private; /* driver-private storage */ 6158313Slile}; 6271963Sjulian 631541Srgrimes/* return non-zero if AMPDU tx for the TID is running */ 641541Srgrimes#define IEEE80211_AMPDU_RUNNING(tap) \ 651541Srgrimes (((tap)->txa_flags & IEEE80211_AGGR_RUNNING) != 0) 661541Srgrimes 671541Srgrimes/* return non-zero if AMPDU tx for the TID is running or started */ 6884931Sfjoe#define IEEE80211_AMPDU_REQUESTED(tap) \ 6944627Sjulian (((tap)->txa_flags & \ 7044627Sjulian (IEEE80211_AGGR_RUNNING|IEEE80211_AGGR_XCHGPEND|IEEE80211_AGGR_NAK)) != 0) 71142215Sglebius 72142215Sglebius/* 73142215Sglebius * Traffic estimator support. We estimate packets/sec for 74142215Sglebius * each AC that is setup for AMPDU or will potentially be 75163606Srwatson * setup for AMPDU. The traffic rate can be used to decide 76163606Srwatson * when AMPDU should be setup (according to a threshold) 771541Srgrimes * and is available for drivers to do things like cache 781541Srgrimes * eviction when only a limited number of BA streams are 791541Srgrimes * available and more streams are requested than available. 8044078Sdfr */ 8112942Swollman 821541Srgrimesstatic __inline void 8312693Sphkieee80211_txampdu_update_pps(struct ieee80211_tx_ampdu *tap) 8412942Swollman{ 851541Srgrimes /* NB: scale factor of 2 was picked heuristically */ 8612942Swollman tap->txa_avgpps = ((tap->txa_avgpps << 2) - 87153478Semaste tap->txa_avgpps + tap->txa_pkts) >> 2; 8812693Sphk} 891541Srgrimes 901541Srgrimes/* 9111225Swollman * Count a packet towards the pps estimate. 92167796Sglebius */ 9311225Swollmanstatic __inline void 94110308Sorionieee80211_txampdu_count_packet(struct ieee80211_tx_ampdu *tap) 95110544Sorion{ 96152188Sglebius /* XXX bound loop/do more crude estimate? */ 9711225Swollman while (ticks - tap->txa_lastsample >= hz) { 9812693Sphk ieee80211_txampdu_update_pps(tap); 99111888Sjlemon /* reset to start new sample interval */ 100120727Ssam tap->txa_pkts = 0; 1011541Srgrimes if (tap->txa_avgpps == 0) { 10212693Sphk tap->txa_lastsample = ticks; 10312942Swollman break; 10412942Swollman } 1053282Swollman tap->txa_lastsample += hz; 10612942Swollman } 107153478Semaste tap->txa_pkts++; 10812942Swollman} 109153478Semaste 11012942Swollman/* 111153478Semaste * Get the current pps estimate. If the average is out of 11212693Sphk * date due to lack of traffic then we decay the estimate 11392723Salfred * to account for the idle time. 11492723Salfred */ 11592723Salfredstatic __inline int 11692723Salfredieee80211_txampdu_getpps(struct ieee80211_tx_ampdu *tap) 117111888Sjlemon{ 11892723Salfred /* XXX bound loop/do more crude estimate? */ 119148955Sglebius while (ticks - tap->txa_lastsample >= hz) { 120178888Sjulian ieee80211_txampdu_update_pps(tap); 12132350Seivind tap->txa_pkts = 0; 12292723Salfred if (tap->txa_avgpps == 0) { 12332350Seivind tap->txa_lastsample = ticks; 12412693Sphk break; 1251541Srgrimes } 126167796Sglebius tap->txa_lastsample += hz; 1271541Srgrimes } 1281541Srgrimes return tap->txa_avgpps; 129167796Sglebius} 1301541Srgrimes 131167796Sglebiusstruct ieee80211_rx_ampdu { 1321541Srgrimes int rxa_flags; 133167796Sglebius int rxa_qbytes; /* data queued (bytes) */ 134167796Sglebius short rxa_qframes; /* data queued (frames) */ 135167796Sglebius ieee80211_seq rxa_seqstart; 136167796Sglebius ieee80211_seq rxa_start; /* start of current BA window */ 137167796Sglebius uint16_t rxa_wnd; /* BA window size */ 138167796Sglebius int rxa_age; /* age of oldest frame in window */ 139167796Sglebius int rxa_nframes; /* frames since ADDBA */ 140167796Sglebius struct mbuf *rxa_m[IEEE80211_AGGR_BAWMAX]; 141148955Sglebius}; 142178888Sjulian 143178888Sjulianvoid ieee80211_ht_attach(struct ieee80211com *); 1441541Srgrimesvoid ieee80211_ht_detach(struct ieee80211com *); 1451541Srgrimesvoid ieee80211_ht_vattach(struct ieee80211vap *); 1461541Srgrimesvoid ieee80211_ht_vdetach(struct ieee80211vap *); 1471541Srgrimes 1481541Srgrimesvoid ieee80211_ht_announce(struct ieee80211com *); 1495196Swollman 150169454Srwatsonstruct ieee80211_mcs_rates { 1511541Srgrimes uint16_t ht20_rate_800ns; 152126936Smdodd uint16_t ht20_rate_400ns; 153126936Smdodd uint16_t ht40_rate_800ns; 1541541Srgrimes uint16_t ht40_rate_400ns; 155138615Smlaier}; 156138615Smlaierextern const struct ieee80211_mcs_rates ieee80211_htrates[16]; 1571541Srgrimesconst struct ieee80211_htrateset *ieee80211_get_suphtrates( 158120727Ssam struct ieee80211com *, const struct ieee80211_channel *); 159120727Ssam 1601541Srgrimesstruct ieee80211_node; 1611541Srgrimesint ieee80211_setup_htrates(struct ieee80211_node *, 162120727Ssam const uint8_t *htcap, int flags); 163120727Ssamvoid ieee80211_setup_basic_htrates(struct ieee80211_node *, 1641541Srgrimes const uint8_t *htinfo); 1651541Srgrimesstruct mbuf *ieee80211_decap_amsdu(struct ieee80211_node *, struct mbuf *); 1661541Srgrimesint ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *); 1671541Srgrimesvoid ieee80211_recv_bar(struct ieee80211_node *, struct mbuf *); 1681541Srgrimesvoid ieee80211_ht_node_init(struct ieee80211_node *, const uint8_t *); 1691541Srgrimesvoid ieee80211_ht_node_cleanup(struct ieee80211_node *); 1701541Srgrimesvoid ieee80211_ht_node_age(struct ieee80211_node *); 1711541Srgrimes 1721541Srgrimesstruct ieee80211_channel *ieee80211_ht_adjust_channel(struct ieee80211com *, 173136960Sbms struct ieee80211_channel *, int); 1741541Srgrimesvoid ieee80211_ht_wds_init(struct ieee80211_node *); 1751541Srgrimesvoid ieee80211_ht_node_join(struct ieee80211_node *); 1761541Srgrimesvoid ieee80211_ht_node_leave(struct ieee80211_node *); 1771541Srgrimesvoid ieee80211_htprot_update(struct ieee80211com *, int protmode); 1781541Srgrimesvoid ieee80211_ht_timeout(struct ieee80211com *); 1791541Srgrimesvoid ieee80211_parse_htcap(struct ieee80211_node *, const uint8_t *); 1801541Srgrimesvoid ieee80211_parse_htinfo(struct ieee80211_node *, const uint8_t *); 1811541Srgrimesvoid ieee80211_recv_action(struct ieee80211_node *, 1821541Srgrimes const uint8_t *, const uint8_t *); 1831541Srgrimesint ieee80211_ampdu_request(struct ieee80211_node *, 1841541Srgrimes struct ieee80211_tx_ampdu *); 185150351Sandrevoid ieee80211_ampdu_stop(struct ieee80211_node *, 1861541Srgrimes struct ieee80211_tx_ampdu *); 1871541Srgrimesint ieee80211_send_bar(struct ieee80211_node *, 1881541Srgrimes const struct ieee80211_tx_ampdu *); 1891541Srgrimesint ieee80211_send_action(struct ieee80211_node *, 19084931Sfjoe int, int, uint16_t [4]); 19136908Sjulianuint8_t *ieee80211_add_htcap(uint8_t *, struct ieee80211_node *); 19236908Sjulianuint8_t *ieee80211_add_htcap_vendor(uint8_t *, struct ieee80211_node *); 1931541Srgrimesuint8_t *ieee80211_add_htinfo(uint8_t *, struct ieee80211_node *); 1941541Srgrimesuint8_t *ieee80211_add_htinfo_vendor(uint8_t *, struct ieee80211_node *); 1951541Srgrimesstruct ieee80211_beacon_offsets; 1961541Srgrimesvoid ieee80211_ht_update_beacon(struct ieee80211vap *, 1971541Srgrimes struct ieee80211_beacon_offsets *); 198120727Ssam#endif /* _NET80211_IEEE80211_HT_H_ */ 199120698Sbms