xref: /onnv-gate/usr/src/uts/common/io/arn/arn_rc.h (revision 11729:8922e660c576)
19999SWang.Lin@Sun.COM /*
2*11729SWang.Lin@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
39999SWang.Lin@Sun.COM  * Use is subject to license terms.
49999SWang.Lin@Sun.COM  */
59999SWang.Lin@Sun.COM 
69999SWang.Lin@Sun.COM /*
79999SWang.Lin@Sun.COM  * Copyright (c) 2004 Sam Leffler, Errno Consulting
89999SWang.Lin@Sun.COM  * Copyright (c) 2004 Video54 Technologies, Inc.
99999SWang.Lin@Sun.COM  * Copyright (c) 2008 Atheros Communications Inc.
109999SWang.Lin@Sun.COM  *
119999SWang.Lin@Sun.COM  * Permission to use, copy, modify, and/or distribute this software for any
129999SWang.Lin@Sun.COM  * purpose with or without fee is hereby granted, provided that the above
139999SWang.Lin@Sun.COM  * copyright notice and this permission notice appear in all copies.
149999SWang.Lin@Sun.COM  *
159999SWang.Lin@Sun.COM  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
169999SWang.Lin@Sun.COM  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
179999SWang.Lin@Sun.COM  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
189999SWang.Lin@Sun.COM  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
199999SWang.Lin@Sun.COM  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
209999SWang.Lin@Sun.COM  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
219999SWang.Lin@Sun.COM  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
229999SWang.Lin@Sun.COM  */
239999SWang.Lin@Sun.COM 
249999SWang.Lin@Sun.COM #ifndef	_ARN_RC_H
259999SWang.Lin@Sun.COM #define	_ARN_RC_H
269999SWang.Lin@Sun.COM 
279999SWang.Lin@Sun.COM #ifdef __cplusplus
289999SWang.Lin@Sun.COM extern "C" {
299999SWang.Lin@Sun.COM #endif
309999SWang.Lin@Sun.COM 
319999SWang.Lin@Sun.COM #include "arn_ath9k.h"
329999SWang.Lin@Sun.COM 
339999SWang.Lin@Sun.COM struct arn_softc;
34*11729SWang.Lin@Sun.COM struct ath_buf;
359999SWang.Lin@Sun.COM 
369999SWang.Lin@Sun.COM #define	ATH_RATE_MAX		30
379999SWang.Lin@Sun.COM #define	RATE_TABLE_SIZE		64
389999SWang.Lin@Sun.COM #define	MAX_TX_RATE_PHY		48
399999SWang.Lin@Sun.COM 
409999SWang.Lin@Sun.COM /*
419999SWang.Lin@Sun.COM  * VALID_ALL - valid for 20/40/Legacy,
429999SWang.Lin@Sun.COM  * VALID - Legacy only,
439999SWang.Lin@Sun.COM  * VALID_20 - HT 20 only,
449999SWang.Lin@Sun.COM  * VALID_40 - HT 40 only
459999SWang.Lin@Sun.COM  */
469999SWang.Lin@Sun.COM 
479999SWang.Lin@Sun.COM #define	INVALID		0x0
489999SWang.Lin@Sun.COM #define	VALID		0x1
499999SWang.Lin@Sun.COM #define	VALID_20	0x2
509999SWang.Lin@Sun.COM #define	VALID_40	0x4
519999SWang.Lin@Sun.COM #define	VALID_2040	(VALID_20|VALID_40)
529999SWang.Lin@Sun.COM #define	VALID_ALL	(VALID_2040|VALID)
539999SWang.Lin@Sun.COM 
54*11729SWang.Lin@Sun.COM enum {
55*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_OFDM,
56*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_CCK,
57*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_20_SS,
58*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_20_DS,
59*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_40_SS,
60*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_40_DS,
61*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_20_SS_HGI,
62*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_20_DS_HGI,
63*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_40_SS_HGI,
64*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_HT_40_DS_HGI,
65*11729SWang.Lin@Sun.COM 	WLAN_RC_PHY_MAX
66*11729SWang.Lin@Sun.COM };
67*11729SWang.Lin@Sun.COM 
689999SWang.Lin@Sun.COM #define	WLAN_RC_PHY_DS(_phy)	((_phy == WLAN_RC_PHY_HT_20_DS)		|| \
699999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_40_DS)		|| \
709999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_20_DS_HGI)	|| \
719999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_40_DS_HGI))
729999SWang.Lin@Sun.COM #define	WLAN_RC_PHY_40(_phy)	((_phy == WLAN_RC_PHY_HT_40_SS) 	|| \
739999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_40_DS)		|| \
749999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_40_SS_HGI)	|| \
759999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_40_DS_HGI))
769999SWang.Lin@Sun.COM #define	WLAN_RC_PHY_SGI(_phy)	((_phy == WLAN_RC_PHY_HT_20_SS_HGI)	|| \
779999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_20_DS_HGI)	|| \
789999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_40_SS_HGI)	|| \
799999SWang.Lin@Sun.COM 				(_phy == WLAN_RC_PHY_HT_40_DS_HGI))
809999SWang.Lin@Sun.COM 
819999SWang.Lin@Sun.COM #define	WLAN_RC_PHY_HT(_phy)	(_phy >= WLAN_RC_PHY_HT_20_SS)
829999SWang.Lin@Sun.COM 
839999SWang.Lin@Sun.COM #define	WLAN_RC_CAP_MODE(capflag)	(((capflag & WLAN_RC_HT_FLAG) ?	\
849999SWang.Lin@Sun.COM 	(capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID))
859999SWang.Lin@Sun.COM 
869999SWang.Lin@Sun.COM /*
879999SWang.Lin@Sun.COM  * Return TRUE if flag supports HT20 && client supports HT20 or
889999SWang.Lin@Sun.COM  * return TRUE if flag supports HT40 && client supports HT40.
899999SWang.Lin@Sun.COM  * This is used becos some rates overlap between HT20/HT40.
909999SWang.Lin@Sun.COM  */
919999SWang.Lin@Sun.COM #define	WLAN_RC_PHY_HT_VALID(flag, capflag)			\
929999SWang.Lin@Sun.COM 	(((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
939999SWang.Lin@Sun.COM 	((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
949999SWang.Lin@Sun.COM 
959999SWang.Lin@Sun.COM #define	WLAN_RC_DS_FLAG		(0x01)
969999SWang.Lin@Sun.COM #define	WLAN_RC_40_FLAG		(0x02)
979999SWang.Lin@Sun.COM #define	WLAN_RC_SGI_FLAG	(0x04)
989999SWang.Lin@Sun.COM #define	WLAN_RC_HT_FLAG		(0x08)
999999SWang.Lin@Sun.COM 
1009999SWang.Lin@Sun.COM /*
1019999SWang.Lin@Sun.COM  * struct ath_rate_table - Rate Control table
1029999SWang.Lin@Sun.COM  * @valid: valid for use in rate control
1039999SWang.Lin@Sun.COM  * @valid_single_stream: valid for use in rate control for
1049999SWang.Lin@Sun.COM  * 	single stream operation
1059999SWang.Lin@Sun.COM  * @phy: CCK/OFDM
1069999SWang.Lin@Sun.COM  * @ratekbps: rate in Kbits per second
1079999SWang.Lin@Sun.COM  * @user_ratekbps: user rate in Kbits per second
1089999SWang.Lin@Sun.COM  * @ratecode: rate that goes into HW descriptors
1099999SWang.Lin@Sun.COM  * @short_preamble: Mask for enabling short preamble in ratecode for CCK
1109999SWang.Lin@Sun.COM  * @dot11rate: value that goes into supported
1119999SWang.Lin@Sun.COM  * 	rates info element of MLME
1129999SWang.Lin@Sun.COM  * @ctrl_rate: Index of next lower basic rate, used for duration computation
1139999SWang.Lin@Sun.COM  * @max_4ms_framelen: maximum frame length(bytes) for tx duration
1149999SWang.Lin@Sun.COM  * @probe_interval: interval for rate control to probe for other rates
1159999SWang.Lin@Sun.COM  * @rssi_reduce_interval: interval for rate control to reduce rssi
1169999SWang.Lin@Sun.COM  * @initial_ratemax: initial ratemax value
1179999SWang.Lin@Sun.COM  */
1189999SWang.Lin@Sun.COM struct ath_rate_table {
1199999SWang.Lin@Sun.COM 	int rate_cnt;
1209999SWang.Lin@Sun.COM 	uint8_t rateCodeToIndex[256];
1219999SWang.Lin@Sun.COM 	struct {
1229999SWang.Lin@Sun.COM 		int valid;
1239999SWang.Lin@Sun.COM 		int valid_single_stream;
1249999SWang.Lin@Sun.COM 		uint8_t phy;
1259999SWang.Lin@Sun.COM 		uint32_t ratekbps;
1269999SWang.Lin@Sun.COM 		uint32_t user_ratekbps;
1279999SWang.Lin@Sun.COM 		uint8_t ratecode;
1289999SWang.Lin@Sun.COM 		uint8_t short_preamble;
1299999SWang.Lin@Sun.COM 		uint8_t dot11rate;
1309999SWang.Lin@Sun.COM 		uint8_t ctrl_rate;
1319999SWang.Lin@Sun.COM 		int8_t rssi_ack_validmin;
1329999SWang.Lin@Sun.COM 		int8_t rssi_ack_deltamin;
1339999SWang.Lin@Sun.COM 		uint8_t base_index;
1349999SWang.Lin@Sun.COM 		uint8_t cw40index;
1359999SWang.Lin@Sun.COM 		uint8_t sgi_index;
1369999SWang.Lin@Sun.COM 		uint8_t ht_index;
1379999SWang.Lin@Sun.COM 		uint32_t max_4ms_framelen;
1389999SWang.Lin@Sun.COM 		uint16_t lpAckDuration;
1399999SWang.Lin@Sun.COM 		uint16_t spAckDuration;
1409999SWang.Lin@Sun.COM 	} info[RATE_TABLE_SIZE];
1419999SWang.Lin@Sun.COM 	uint32_t probe_interval;
1429999SWang.Lin@Sun.COM 	uint32_t rssi_reduce_interval;
1439999SWang.Lin@Sun.COM 	uint8_t initial_ratemax;
1449999SWang.Lin@Sun.COM };
1459999SWang.Lin@Sun.COM 
1469999SWang.Lin@Sun.COM struct ath_tx_ratectrl_state {
1479999SWang.Lin@Sun.COM 	int8_t rssi_thres; /* required rssi for this rate (dB) */
1489999SWang.Lin@Sun.COM 	uint8_t per; /* recent estimate of packet error rate (%) */
1499999SWang.Lin@Sun.COM };
1509999SWang.Lin@Sun.COM 
1519999SWang.Lin@Sun.COM struct ath_rateset {
1529999SWang.Lin@Sun.COM 	uint8_t rs_nrates;
1539999SWang.Lin@Sun.COM 	uint8_t rs_rates[ATH_RATE_MAX];
1549999SWang.Lin@Sun.COM };
1559999SWang.Lin@Sun.COM 
1569999SWang.Lin@Sun.COM /*
1579999SWang.Lin@Sun.COM  * struct ath_rate_priv - Rate Control priv data
1589999SWang.Lin@Sun.COM  * @state: RC state
1599999SWang.Lin@Sun.COM  * @rssi_last: last ACK rssi
1609999SWang.Lin@Sun.COM  * @rssi_last_lookup: last ACK rssi used for lookup
1619999SWang.Lin@Sun.COM  * @rssi_last_prev: previous last ACK rssi
1629999SWang.Lin@Sun.COM  * @rssi_last_prev2: 2nd previous last ACK rssi
1639999SWang.Lin@Sun.COM  * @rssi_sum_cnt: count of rssi_sum for averaging
1649999SWang.Lin@Sun.COM  * @rssi_sum_rate: rate that we are averaging
1659999SWang.Lin@Sun.COM  * @rssi_sum: running sum of rssi for averaging
1669999SWang.Lin@Sun.COM  * @probe_rate: rate we are probing at
1679999SWang.Lin@Sun.COM  * @rssi_time: msec timestamp for last ack rssi
1689999SWang.Lin@Sun.COM  * @rssi_down_time: msec timestamp for last down step
1699999SWang.Lin@Sun.COM  * @probe_time: msec timestamp for last probe
1709999SWang.Lin@Sun.COM  * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
1719999SWang.Lin@Sun.COM  * @max_valid_rate: maximum number of valid rate
1729999SWang.Lin@Sun.COM  * @per_down_time: msec timestamp for last PER down step
1739999SWang.Lin@Sun.COM  * @valid_phy_ratecnt: valid rate count
1749999SWang.Lin@Sun.COM  * @rate_max_phy: phy index for the max rate
1759999SWang.Lin@Sun.COM  * @probe_interval: interval for ratectrl to probe for other rates
1769999SWang.Lin@Sun.COM  * @prev_data_rix: rate idx of last data frame
1779999SWang.Lin@Sun.COM  * @ht_cap: HT capabilities
1789999SWang.Lin@Sun.COM  * @single_stream: When TRUE, only single TX stream possible
1799999SWang.Lin@Sun.COM  * @neg_rates: Negotatied rates
1809999SWang.Lin@Sun.COM  * @neg_ht_rates: Negotiated HT rates
1819999SWang.Lin@Sun.COM  */
1829999SWang.Lin@Sun.COM struct ath_rate_priv {
1839999SWang.Lin@Sun.COM 	int8_t rssi_last;
1849999SWang.Lin@Sun.COM 	int8_t rssi_last_lookup;
1859999SWang.Lin@Sun.COM 	int8_t rssi_last_prev;
1869999SWang.Lin@Sun.COM 	int8_t rssi_last_prev2;
1879999SWang.Lin@Sun.COM 	int32_t rssi_sum_cnt;
1889999SWang.Lin@Sun.COM 	int32_t rssi_sum_rate;
1899999SWang.Lin@Sun.COM 	int32_t rssi_sum;
1909999SWang.Lin@Sun.COM 	uint8_t rate_table_size;
1919999SWang.Lin@Sun.COM 	uint8_t probe_rate;
1929999SWang.Lin@Sun.COM 	uint8_t hw_maxretry_pktcnt;
1939999SWang.Lin@Sun.COM 	uint8_t max_valid_rate;
1949999SWang.Lin@Sun.COM 	uint8_t valid_rate_index[RATE_TABLE_SIZE];
1959999SWang.Lin@Sun.COM 	uint8_t ht_cap;
1969999SWang.Lin@Sun.COM 	uint8_t single_stream;
1979999SWang.Lin@Sun.COM 	uint8_t valid_phy_ratecnt[WLAN_RC_PHY_MAX];
1989999SWang.Lin@Sun.COM 	uint8_t valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
1999999SWang.Lin@Sun.COM 	uint8_t rc_phy_mode;
2009999SWang.Lin@Sun.COM 	uint8_t rate_max_phy;
2019999SWang.Lin@Sun.COM 	uint32_t rssi_time;
2029999SWang.Lin@Sun.COM 	uint32_t rssi_down_time;
2039999SWang.Lin@Sun.COM 	uint32_t probe_time;
2049999SWang.Lin@Sun.COM 	uint32_t per_down_time;
2059999SWang.Lin@Sun.COM 	uint32_t probe_interval;
2069999SWang.Lin@Sun.COM 	uint32_t prev_data_rix;
2079999SWang.Lin@Sun.COM 	uint32_t tx_triglevel_max;
2089999SWang.Lin@Sun.COM 	struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE];
2099999SWang.Lin@Sun.COM 	struct ath_rateset neg_rates;
2109999SWang.Lin@Sun.COM 	struct ath_rateset neg_ht_rates;
2119999SWang.Lin@Sun.COM };
2129999SWang.Lin@Sun.COM 
213*11729SWang.Lin@Sun.COM enum ath9k_internal_frame_type {
214*11729SWang.Lin@Sun.COM 	ATH9K_NOT_INTERNAL,
215*11729SWang.Lin@Sun.COM 	ATH9K_INT_PAUSE,
216*11729SWang.Lin@Sun.COM 	ATH9K_INT_UNPAUSE
217*11729SWang.Lin@Sun.COM };
218*11729SWang.Lin@Sun.COM 
2199999SWang.Lin@Sun.COM struct ath_tx_info_priv {
2209999SWang.Lin@Sun.COM 	struct ath_tx_status tx;
2219999SWang.Lin@Sun.COM 	int n_frames;
2229999SWang.Lin@Sun.COM 	int n_bad_frames;
2239999SWang.Lin@Sun.COM 	boolean_t update_rc;
224*11729SWang.Lin@Sun.COM 	enum ath9k_internal_frame_type frame_type;
2259999SWang.Lin@Sun.COM };
2269999SWang.Lin@Sun.COM 
2279999SWang.Lin@Sun.COM #define	ATH_TX_INFO_PRIV(tx_info)	\
2289999SWang.Lin@Sun.COM 	((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
2299999SWang.Lin@Sun.COM 
230*11729SWang.Lin@Sun.COM /* Temp private definitions for RC */
231*11729SWang.Lin@Sun.COM struct ath9k_tx_rate {
232*11729SWang.Lin@Sun.COM 	int8_t idx;
233*11729SWang.Lin@Sun.COM 	uint8_t count;
234*11729SWang.Lin@Sun.COM 	uint8_t flags;
235*11729SWang.Lin@Sun.COM };
236*11729SWang.Lin@Sun.COM 
237*11729SWang.Lin@Sun.COM enum ath9k_rate_control_flags {
238*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_USE_RTS_CTS		= BIT(0),
239*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_USE_CTS_PROTECT		= BIT(1),
240*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_USE_SHORT_PREAMBLE	= BIT(2),
241*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_MCS			= BIT(3),
242*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_GREEN_FIELD		= BIT(4),
243*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_40_MHZ_WIDTH		= BIT(5),
244*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_DUP_DATA		= BIT(6),
245*11729SWang.Lin@Sun.COM 	ATH9K_TX_RC_SHORT_GI		= BIT(7),
246*11729SWang.Lin@Sun.COM };
247*11729SWang.Lin@Sun.COM 
2489999SWang.Lin@Sun.COM /* RATE */
249*11729SWang.Lin@Sun.COM void arn_tx_status(struct arn_softc *sc, struct ath_buf *bf, boolean_t is_data);
250*11729SWang.Lin@Sun.COM void arn_get_rate(struct arn_softc *sc, struct ath_buf *bf,
251*11729SWang.Lin@Sun.COM     struct ieee80211_frame *wh);
252*11729SWang.Lin@Sun.COM void arn_rate_init(struct arn_softc *sc, struct ieee80211_node *in);
253*11729SWang.Lin@Sun.COM 
254*11729SWang.Lin@Sun.COM 
2559999SWang.Lin@Sun.COM void arn_rate_attach(struct arn_softc *sc);
256*11729SWang.Lin@Sun.COM void arn_rate_update(struct arn_softc *sc,
257*11729SWang.Lin@Sun.COM     struct ieee80211_node *in, int32_t rate);
2589999SWang.Lin@Sun.COM void arn_rate_ctl_start(struct arn_softc *sc, struct ieee80211_node *in);
2599999SWang.Lin@Sun.COM void arn_rate_cb(void *arg, struct ieee80211_node *in);
2609999SWang.Lin@Sun.COM void arn_rate_ctl_reset(struct arn_softc *sc, enum ieee80211_state state);
2619999SWang.Lin@Sun.COM void arn_rate_ctl(void *arg, struct ieee80211_node *in);
2629999SWang.Lin@Sun.COM 
2639999SWang.Lin@Sun.COM #ifdef __cplusplus
2649999SWang.Lin@Sun.COM }
2659999SWang.Lin@Sun.COM #endif
2669999SWang.Lin@Sun.COM 
2679999SWang.Lin@Sun.COM #endif /* _ARN_RC_H */
268