ieee80211_ht.h revision 219456
145095Ssos/*-
255333Ssos * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
345095Ssos * All rights reserved.
445095Ssos *
545095Ssos * Redistribution and use in source and binary forms, with or without
645095Ssos * modification, are permitted provided that the following conditions
745095Ssos * are met:
845095Ssos * 1. Redistributions of source code must retain the above copyright
945095Ssos *    notice, this list of conditions and the following disclaimer.
1045095Ssos * 2. Redistributions in binary form must reproduce the above copyright
1145095Ssos *    notice, this list of conditions and the following disclaimer in the
1245095Ssos *    documentation and/or other materials provided with the distribution.
1345095Ssos *
1445095Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1545095Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1645095Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1745095Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1845095Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1945095Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2045095Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2145095Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2245095Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2345095Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2445095Ssos *
2545095Ssos * $FreeBSD: head/sys/net80211/ieee80211_ht.h 219456 2011-03-10 18:17:24Z bschmidt $
2645095Ssos */
2745095Ssos#ifndef _NET80211_IEEE80211_HT_H_
2850477Speter#define _NET80211_IEEE80211_HT_H_
2945095Ssos
3045095Ssos/*
3145150Ssos * 802.11n protocol implementation definitions.
3245095Ssos */
3345095Ssos
3445095Ssos#define	IEEE80211_AGGR_BAWMAX	64	/* max block ack window size */
3545095Ssos/* threshold for aging overlapping non-HT bss */
3645798Ssos#define	IEEE80211_NONHT_PRESENT_AGE	msecs_to_ticks(60*1000)
3754270Ssos
3854270Ssosstruct ieee80211_tx_ampdu {
3951520Ssos	struct ieee80211_node *txa_ni;	/* back pointer */
4045095Ssos	u_short		txa_flags;
4147272Ssos#define	IEEE80211_AGGR_IMMEDIATE	0x0001	/* BA policy */
4245095Ssos#define	IEEE80211_AGGR_XCHGPEND		0x0002	/* ADDBA response pending */
4347272Ssos#define	IEEE80211_AGGR_RUNNING		0x0004	/* ADDBA response received */
4445095Ssos#define	IEEE80211_AGGR_SETUP		0x0008	/* deferred state setup */
4554270Ssos#define	IEEE80211_AGGR_NAK		0x0010	/* peer NAK'd ADDBA request */
4645095Ssos#define	IEEE80211_AGGR_BARPEND		0x0020	/* BAR response pending */
4756754Ssos	uint8_t		txa_ac;
4856754Ssos	uint8_t		txa_token;	/* dialog token */
4952067Ssos	int		txa_lastsample;	/* ticks @ last traffic sample */
5055333Ssos	int		txa_pkts;	/* packets over last sample interval */
5152067Ssos	int		txa_avgpps;	/* filtered traffic over window */
5252067Ssos	int		txa_qbytes;	/* data queued (bytes) */
5352067Ssos	short		txa_qframes;	/* data queued (frames) */
5445720Speter	ieee80211_seq	txa_start;	/* BA window left edge */
5545720Speter	ieee80211_seq	txa_seqpending;	/* new txa_start pending BAR response */
5651520Ssos	uint16_t	txa_wnd;	/* BA window size */
5745720Speter	uint8_t		txa_attempts;	/* # ADDBA/BAR requests w/o a response*/
5845720Speter	int		txa_nextrequest;/* soonest to make next request */
5956744Ssos	struct callout	txa_timer;
6045095Ssos	void		*txa_private;	/* driver-private storage */
6145095Ssos	uint64_t	txa_pad[4];
6245095Ssos};
6357325Ssos
6456558Ssos/* return non-zero if AMPDU tx for the TID is running */
6555333Ssos#define	IEEE80211_AMPDU_RUNNING(tap) \
6645095Ssos	(((tap)->txa_flags & IEEE80211_AGGR_RUNNING) != 0)
6756744Ssos
6856744Ssos/* return non-zero if AMPDU tx for the TID is running or started */
6956744Ssos#define	IEEE80211_AMPDU_REQUESTED(tap) \
7045095Ssos	(((tap)->txa_flags & \
7156744Ssos	 (IEEE80211_AGGR_RUNNING|IEEE80211_AGGR_XCHGPEND|IEEE80211_AGGR_NAK)) != 0)
7245095Ssos
7352067Ssos#define	IEEE80211_AGGR_BITS \
7452067Ssos	"\20\1IMMEDIATE\2XCHGPEND\3RUNNING\4SETUP\5NAK"
7552067Ssos
7652067Ssos/*
7752067Ssos * Traffic estimator support.  We estimate packets/sec for
7856558Ssos * each AC that is setup for AMPDU or will potentially be
7956744Ssos * setup for AMPDU.  The traffic rate can be used to decide
8052067Ssos * when AMPDU should be setup (according to a threshold)
8152067Ssos * and is available for drivers to do things like cache
8252067Ssos * eviction when only a limited number of BA streams are
8356558Ssos * available and more streams are requested than available.
8456558Ssos */
8545095Ssos
8656558Ssosstatic __inline void
8756744Ssosieee80211_txampdu_update_pps(struct ieee80211_tx_ampdu *tap)
8856558Ssos{
8956558Ssos	/* NB: scale factor of 2 was picked heuristically */
9056558Ssos	tap->txa_avgpps = ((tap->txa_avgpps << 2) -
9156558Ssos	     tap->txa_avgpps + tap->txa_pkts) >> 2;
9256744Ssos}
9356558Ssos
9456558Ssos/*
9545095Ssos * Count a packet towards the pps estimate.
9645095Ssos */
9755333Ssosstatic __inline void
9845095Ssosieee80211_txampdu_count_packet(struct ieee80211_tx_ampdu *tap)
9957391Ssos{
10057391Ssos	/* XXX bound loop/do more crude estimate? */
10157391Ssos	while (ticks - tap->txa_lastsample >= hz) {
10257391Ssos		ieee80211_txampdu_update_pps(tap);
10357391Ssos		/* reset to start new sample interval */
10457391Ssos		tap->txa_pkts = 0;
10557391Ssos		if (tap->txa_avgpps == 0) {
10657391Ssos			tap->txa_lastsample = ticks;
10757391Ssos			break;
10857391Ssos		}
10957391Ssos		tap->txa_lastsample += hz;
11057391Ssos	}
11157391Ssos	tap->txa_pkts++;
11257391Ssos}
11357391Ssos
11457391Ssos/*
11557391Ssos * Get the current pps estimate.  If the average is out of
11657391Ssos * date due to lack of traffic then we decay the estimate
11757391Ssos * to account for the idle time.
11857391Ssos */
11957391Ssosstatic __inline int
12057391Ssosieee80211_txampdu_getpps(struct ieee80211_tx_ampdu *tap)
12157391Ssos{
12257391Ssos	/* XXX bound loop/do more crude estimate? */
12357391Ssos	while (ticks - tap->txa_lastsample >= hz) {
12457391Ssos		ieee80211_txampdu_update_pps(tap);
12557391Ssos		tap->txa_pkts = 0;
12645095Ssos		if (tap->txa_avgpps == 0) {
12756138Ssos			tap->txa_lastsample = ticks;
12856138Ssos			break;
12945095Ssos		}
13051520Ssos		tap->txa_lastsample += hz;
13145095Ssos	}
13245095Ssos	return tap->txa_avgpps;
13353029Ssos}
13451520Ssos
13556558Ssosstruct ieee80211_rx_ampdu {
13656558Ssos	int		rxa_flags;
13756558Ssos	int		rxa_qbytes;	/* data queued (bytes) */
13856558Ssos	short		rxa_qframes;	/* data queued (frames) */
13953681Ssos	ieee80211_seq	rxa_seqstart;
14053681Ssos	ieee80211_seq	rxa_start;	/* start of current BA window */
14153681Ssos	uint16_t	rxa_wnd;	/* BA window size */
14257325Ssos	int		rxa_age;	/* age of oldest frame in window */
14357325Ssos	int		rxa_nframes;	/* frames since ADDBA */
14453681Ssos	struct mbuf *rxa_m[IEEE80211_AGGR_BAWMAX];
14556558Ssos	void		*rxa_private;
14656744Ssos	uint64_t	rxa_pad[3];
14753681Ssos};
14845095Ssos
14945095Ssosvoid	ieee80211_ht_attach(struct ieee80211com *);
15045095Ssosvoid	ieee80211_ht_detach(struct ieee80211com *);
15145095Ssosvoid	ieee80211_ht_vattach(struct ieee80211vap *);
15245095Ssosvoid	ieee80211_ht_vdetach(struct ieee80211vap *);
15345095Ssos
15445095Ssosvoid	ieee80211_ht_announce(struct ieee80211com *);
15545095Ssos
15657325Ssosstruct ieee80211_mcs_rates {
15757325Ssos	uint16_t	ht20_rate_800ns;
15857325Ssos	uint16_t	ht20_rate_400ns;
15951520Ssos	uint16_t	ht40_rate_800ns;
16051520Ssos	uint16_t	ht40_rate_400ns;
16151520Ssos};
16251520Ssosextern const struct ieee80211_mcs_rates ieee80211_htrates[];
16351520Ssosconst struct ieee80211_htrateset *ieee80211_get_suphtrates(
16451520Ssos		struct ieee80211com *, const struct ieee80211_channel *);
16551520Ssos
16651520Ssosstruct ieee80211_node;
16751520Ssosint	ieee80211_setup_htrates(struct ieee80211_node *,
16857325Ssos		const uint8_t *htcap, int flags);
16957325Ssosvoid	ieee80211_setup_basic_htrates(struct ieee80211_node *,
17045095Ssos		const uint8_t *htinfo);
17145095Ssosstruct mbuf *ieee80211_decap_amsdu(struct ieee80211_node *, struct mbuf *);
17253029Ssosint	ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *);
17351520Ssosvoid	ieee80211_recv_bar(struct ieee80211_node *, struct mbuf *);
17456558Ssosvoid	ieee80211_ht_node_init(struct ieee80211_node *);
17556558Ssosvoid	ieee80211_ht_node_cleanup(struct ieee80211_node *);
17656558Ssosvoid	ieee80211_ht_node_age(struct ieee80211_node *);
17756558Ssos
17856558Ssosstruct ieee80211_channel *ieee80211_ht_adjust_channel(struct ieee80211com *,
17953681Ssos		struct ieee80211_channel *, int);
18053681Ssosvoid	ieee80211_ht_wds_init(struct ieee80211_node *);
18153681Ssosvoid	ieee80211_ht_node_join(struct ieee80211_node *);
18253681Ssosvoid	ieee80211_ht_node_leave(struct ieee80211_node *);
18353681Ssosvoid	ieee80211_htprot_update(struct ieee80211com *, int protmode);
18453681Ssosvoid	ieee80211_ht_timeout(struct ieee80211com *);
18553681Ssosvoid	ieee80211_parse_htcap(struct ieee80211_node *, const uint8_t *);
18653681Ssosvoid	ieee80211_parse_htinfo(struct ieee80211_node *, const uint8_t *);
18753681Ssosvoid	ieee80211_ht_updateparams(struct ieee80211_node *, const uint8_t *,
18853681Ssos		const uint8_t *);
18953681Ssosvoid	ieee80211_ht_updatehtcap(struct ieee80211_node *, const uint8_t *);
19053681Ssosint	ieee80211_ampdu_request(struct ieee80211_node *,
19153681Ssos		struct ieee80211_tx_ampdu *);
19253681Ssosvoid	ieee80211_ampdu_stop(struct ieee80211_node *,
19353681Ssos		struct ieee80211_tx_ampdu *, int);
19453681Ssosint	ieee80211_send_bar(struct ieee80211_node *, struct ieee80211_tx_ampdu *,
19553681Ssos		ieee80211_seq);
19653681Ssosuint8_t	*ieee80211_add_htcap(uint8_t *, struct ieee80211_node *);
19753681Ssosuint8_t	*ieee80211_add_htcap_vendor(uint8_t *, struct ieee80211_node *);
19857325Ssosuint8_t	*ieee80211_add_htinfo(uint8_t *, struct ieee80211_node *);
19957325Ssosuint8_t	*ieee80211_add_htinfo_vendor(uint8_t *, struct ieee80211_node *);
20053681Ssosstruct ieee80211_beacon_offsets;
20157325Ssosvoid	ieee80211_ht_update_beacon(struct ieee80211vap *,
20257325Ssos		struct ieee80211_beacon_offsets *);
20353681Ssos#endif /* _NET80211_IEEE80211_HT_H_ */
20456558Ssos