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