iwl-agn-rs.h 15.8 KB
Newer Older
Z
Zhu Yi 已提交
1 2
/******************************************************************************
 *
3
 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
Z
Zhu Yi 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 *
 * The full GNU General Public License is included in this distribution in the
 * file called LICENSE.
 *
 * Contact Information:
22
 *  Intel Linux Wireless <ilw@linux.intel.com>
Z
Zhu Yi 已提交
23 24 25 26
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/

27 28
#ifndef __iwl_agn_rs_h__
#define __iwl_agn_rs_h__
Z
Zhu Yi 已提交
29

30
struct iwl_rate_info {
31 32
	u8 plcp;	/* uCode API:  IWL_RATE_6M_PLCP, etc. */
	u8 plcp_siso;	/* uCode API:  IWL_RATE_SISO_6M_PLCP, etc. */
G
Guy Cohen 已提交
33 34
	u8 plcp_mimo2;	/* uCode API:  IWL_RATE_MIMO2_6M_PLCP, etc. */
	u8 plcp_mimo3;  /* uCode API:  IWL_RATE_MIMO3_6M_PLCP, etc. */
35
	u8 ieee;	/* MAC header:  IWL_RATE_6M_IEEE, etc. */
Z
Zhu Yi 已提交
36 37 38 39 40 41 42 43
	u8 prev_ieee;    /* previous rate in IEEE speeds */
	u8 next_ieee;    /* next rate in IEEE speeds */
	u8 prev_rs;      /* previous rate used in rs algo */
	u8 next_rs;      /* next rate used in rs algo */
	u8 prev_rs_tgg;  /* previous rate used in TGG rs algo */
	u8 next_rs_tgg;  /* next rate used in TGG rs algo */
};

44 45 46 47 48 49 50 51 52 53 54 55 56
struct iwl3945_rate_info {
	u8 plcp;		/* uCode API:  IWL_RATE_6M_PLCP, etc. */
	u8 ieee;		/* MAC header:  IWL_RATE_6M_IEEE, etc. */
	u8 prev_ieee;		/* previous rate in IEEE speeds */
	u8 next_ieee;		/* next rate in IEEE speeds */
	u8 prev_rs;		/* previous rate used in rs algo */
	u8 next_rs;		/* next rate used in rs algo */
	u8 prev_rs_tgg;		/* previous rate used in TGG rs algo */
	u8 next_rs_tgg;		/* next rate used in TGG rs algo */
	u8 table_rs_index;	/* index in rate scale table cmd */
	u8 prev_table_rs;	/* prev in rate table cmd */
};

57

58 59
/*
 * These serve as indexes into
60
 * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
61
 */
Z
Zhu Yi 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74 75
enum {
	IWL_RATE_1M_INDEX = 0,
	IWL_RATE_2M_INDEX,
	IWL_RATE_5M_INDEX,
	IWL_RATE_11M_INDEX,
	IWL_RATE_6M_INDEX,
	IWL_RATE_9M_INDEX,
	IWL_RATE_12M_INDEX,
	IWL_RATE_18M_INDEX,
	IWL_RATE_24M_INDEX,
	IWL_RATE_36M_INDEX,
	IWL_RATE_48M_INDEX,
	IWL_RATE_54M_INDEX,
	IWL_RATE_60M_INDEX,
G
Guy Cohen 已提交
76
	IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
77
	IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1,	/* Excluding 60M */
78
	IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
Z
Zhu Yi 已提交
79
	IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
G
Guy Cohen 已提交
80
	IWL_RATE_INVALID = IWL_RATE_COUNT,
Z
Zhu Yi 已提交
81 82
};

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
enum {
	IWL_RATE_6M_INDEX_TABLE = 0,
	IWL_RATE_9M_INDEX_TABLE,
	IWL_RATE_12M_INDEX_TABLE,
	IWL_RATE_18M_INDEX_TABLE,
	IWL_RATE_24M_INDEX_TABLE,
	IWL_RATE_36M_INDEX_TABLE,
	IWL_RATE_48M_INDEX_TABLE,
	IWL_RATE_54M_INDEX_TABLE,
	IWL_RATE_1M_INDEX_TABLE,
	IWL_RATE_2M_INDEX_TABLE,
	IWL_RATE_5M_INDEX_TABLE,
	IWL_RATE_11M_INDEX_TABLE,
	IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1,
};

Z
Zhu Yi 已提交
99 100
enum {
	IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
101
	IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
Z
Zhu Yi 已提交
102 103 104 105 106 107
	IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
	IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
	IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
};

/* #define vs. enum to keep from defaulting to 'large integer' */
108 109 110 111 112 113 114 115 116 117 118 119 120
#define	IWL_RATE_6M_MASK   (1 << IWL_RATE_6M_INDEX)
#define	IWL_RATE_9M_MASK   (1 << IWL_RATE_9M_INDEX)
#define	IWL_RATE_12M_MASK  (1 << IWL_RATE_12M_INDEX)
#define	IWL_RATE_18M_MASK  (1 << IWL_RATE_18M_INDEX)
#define	IWL_RATE_24M_MASK  (1 << IWL_RATE_24M_INDEX)
#define	IWL_RATE_36M_MASK  (1 << IWL_RATE_36M_INDEX)
#define	IWL_RATE_48M_MASK  (1 << IWL_RATE_48M_INDEX)
#define	IWL_RATE_54M_MASK  (1 << IWL_RATE_54M_INDEX)
#define IWL_RATE_60M_MASK  (1 << IWL_RATE_60M_INDEX)
#define	IWL_RATE_1M_MASK   (1 << IWL_RATE_1M_INDEX)
#define	IWL_RATE_2M_MASK   (1 << IWL_RATE_2M_INDEX)
#define	IWL_RATE_5M_MASK   (1 << IWL_RATE_5M_INDEX)
#define	IWL_RATE_11M_MASK  (1 << IWL_RATE_11M_INDEX)
Z
Zhu Yi 已提交
121

122
/* uCode API values for legacy bit rates, both OFDM and CCK */
Z
Zhu Yi 已提交
123 124 125 126 127 128 129 130 131
enum {
	IWL_RATE_6M_PLCP  = 13,
	IWL_RATE_9M_PLCP  = 15,
	IWL_RATE_12M_PLCP = 5,
	IWL_RATE_18M_PLCP = 7,
	IWL_RATE_24M_PLCP = 9,
	IWL_RATE_36M_PLCP = 11,
	IWL_RATE_48M_PLCP = 1,
	IWL_RATE_54M_PLCP = 3,
G
Guy Cohen 已提交
132
	IWL_RATE_60M_PLCP = 3,/*FIXME:RS:should be removed*/
Z
Zhu Yi 已提交
133 134 135 136
	IWL_RATE_1M_PLCP  = 10,
	IWL_RATE_2M_PLCP  = 20,
	IWL_RATE_5M_PLCP  = 55,
	IWL_RATE_11M_PLCP = 110,
G
Guy Cohen 已提交
137 138
	/*FIXME:RS:change to IWL_RATE_LEGACY_??M_PLCP */
	/*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
Z
Zhu Yi 已提交
139 140
};

141
/* uCode API values for OFDM high-throughput (HT) bit rates */
Z
Zhu Yi 已提交
142 143 144 145 146 147 148 149 150
enum {
	IWL_RATE_SISO_6M_PLCP = 0,
	IWL_RATE_SISO_12M_PLCP = 1,
	IWL_RATE_SISO_18M_PLCP = 2,
	IWL_RATE_SISO_24M_PLCP = 3,
	IWL_RATE_SISO_36M_PLCP = 4,
	IWL_RATE_SISO_48M_PLCP = 5,
	IWL_RATE_SISO_54M_PLCP = 6,
	IWL_RATE_SISO_60M_PLCP = 7,
G
Guy Cohen 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	IWL_RATE_MIMO2_6M_PLCP  = 0x8,
	IWL_RATE_MIMO2_12M_PLCP = 0x9,
	IWL_RATE_MIMO2_18M_PLCP = 0xa,
	IWL_RATE_MIMO2_24M_PLCP = 0xb,
	IWL_RATE_MIMO2_36M_PLCP = 0xc,
	IWL_RATE_MIMO2_48M_PLCP = 0xd,
	IWL_RATE_MIMO2_54M_PLCP = 0xe,
	IWL_RATE_MIMO2_60M_PLCP = 0xf,
	IWL_RATE_MIMO3_6M_PLCP  = 0x10,
	IWL_RATE_MIMO3_12M_PLCP = 0x11,
	IWL_RATE_MIMO3_18M_PLCP = 0x12,
	IWL_RATE_MIMO3_24M_PLCP = 0x13,
	IWL_RATE_MIMO3_36M_PLCP = 0x14,
	IWL_RATE_MIMO3_48M_PLCP = 0x15,
	IWL_RATE_MIMO3_54M_PLCP = 0x16,
	IWL_RATE_MIMO3_60M_PLCP = 0x17,
Z
Zhu Yi 已提交
167
	IWL_RATE_SISO_INVM_PLCP,
G
Guy Cohen 已提交
168 169
	IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
	IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
Z
Zhu Yi 已提交
170 171
};

172
/* MAC header values for bit rates */
Z
Zhu Yi 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
enum {
	IWL_RATE_6M_IEEE  = 12,
	IWL_RATE_9M_IEEE  = 18,
	IWL_RATE_12M_IEEE = 24,
	IWL_RATE_18M_IEEE = 36,
	IWL_RATE_24M_IEEE = 48,
	IWL_RATE_36M_IEEE = 72,
	IWL_RATE_48M_IEEE = 96,
	IWL_RATE_54M_IEEE = 108,
	IWL_RATE_60M_IEEE = 120,
	IWL_RATE_1M_IEEE  = 2,
	IWL_RATE_2M_IEEE  = 4,
	IWL_RATE_5M_IEEE  = 11,
	IWL_RATE_11M_IEEE = 22,
};

#define IWL_CCK_BASIC_RATES_MASK    \
       (IWL_RATE_1M_MASK          | \
	IWL_RATE_2M_MASK)

#define IWL_CCK_RATES_MASK          \
194
       (IWL_CCK_BASIC_RATES_MASK  | \
Z
Zhu Yi 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
	IWL_RATE_5M_MASK          | \
	IWL_RATE_11M_MASK)

#define IWL_OFDM_BASIC_RATES_MASK   \
	(IWL_RATE_6M_MASK         | \
	IWL_RATE_12M_MASK         | \
	IWL_RATE_24M_MASK)

#define IWL_OFDM_RATES_MASK         \
       (IWL_OFDM_BASIC_RATES_MASK | \
	IWL_RATE_9M_MASK          | \
	IWL_RATE_18M_MASK         | \
	IWL_RATE_36M_MASK         | \
	IWL_RATE_48M_MASK         | \
	IWL_RATE_54M_MASK)

#define IWL_BASIC_RATES_MASK         \
	(IWL_OFDM_BASIC_RATES_MASK | \
	 IWL_CCK_BASIC_RATES_MASK)

215
#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
Z
Zhu Yi 已提交
216 217 218 219 220 221

#define IWL_INVALID_VALUE    -1

#define IWL_MIN_RSSI_VAL                 -100
#define IWL_MAX_RSSI_VAL                    0

222 223
/* These values specify how many Tx frame attempts before
 * searching for a new modulation mode */
Z
Zhu Yi 已提交
224 225 226 227 228 229 230 231
#define IWL_LEGACY_FAILURE_LIMIT	160
#define IWL_LEGACY_SUCCESS_LIMIT	480
#define IWL_LEGACY_TABLE_COUNT		160

#define IWL_NONE_LEGACY_FAILURE_LIMIT	400
#define IWL_NONE_LEGACY_SUCCESS_LIMIT	4500
#define IWL_NONE_LEGACY_TABLE_COUNT	1500

232 233 234 235
/* Success ratio (ACKed / attempted tx frames) values (perfect is 128 * 100) */
#define IWL_RS_GOOD_RATIO		12800	/* 100% */
#define IWL_RATE_SCALE_SWITCH		10880	/*  85% */
#define IWL_RATE_HIGH_TH		10880	/*  85% */
236
#define IWL_RATE_INCREASE_TH		6400	/*  50% */
237
#define IWL_RATE_DECREASE_TH		1920	/*  15% */
Z
Zhu Yi 已提交
238

239
/* possible actions when in legacy mode */
240 241 242 243 244 245
#define IWL_LEGACY_SWITCH_ANTENNA1      0
#define IWL_LEGACY_SWITCH_ANTENNA2      1
#define IWL_LEGACY_SWITCH_SISO          2
#define IWL_LEGACY_SWITCH_MIMO2_AB      3
#define IWL_LEGACY_SWITCH_MIMO2_AC      4
#define IWL_LEGACY_SWITCH_MIMO2_BC      5
246
#define IWL_LEGACY_SWITCH_MIMO3_ABC     6
247 248

/* possible actions when in siso mode */
249 250 251 252 253 254
#define IWL_SISO_SWITCH_ANTENNA1        0
#define IWL_SISO_SWITCH_ANTENNA2        1
#define IWL_SISO_SWITCH_MIMO2_AB        2
#define IWL_SISO_SWITCH_MIMO2_AC        3
#define IWL_SISO_SWITCH_MIMO2_BC        4
#define IWL_SISO_SWITCH_GI              5
255 256
#define IWL_SISO_SWITCH_MIMO3_ABC       6

Z
Zhu Yi 已提交
257

258
/* possible actions when in mimo mode */
259 260 261 262 263 264
#define IWL_MIMO2_SWITCH_ANTENNA1       0
#define IWL_MIMO2_SWITCH_ANTENNA2       1
#define IWL_MIMO2_SWITCH_SISO_A         2
#define IWL_MIMO2_SWITCH_SISO_B         3
#define IWL_MIMO2_SWITCH_SISO_C         4
#define IWL_MIMO2_SWITCH_GI             5
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
#define IWL_MIMO2_SWITCH_MIMO3_ABC      6


/* possible actions when in mimo3 mode */
#define IWL_MIMO3_SWITCH_ANTENNA1       0
#define IWL_MIMO3_SWITCH_ANTENNA2       1
#define IWL_MIMO3_SWITCH_SISO_A         2
#define IWL_MIMO3_SWITCH_SISO_B         3
#define IWL_MIMO3_SWITCH_SISO_C         4
#define IWL_MIMO3_SWITCH_MIMO2_AB       5
#define IWL_MIMO3_SWITCH_MIMO2_AC       6
#define IWL_MIMO3_SWITCH_MIMO2_BC       7
#define IWL_MIMO3_SWITCH_GI             8


280 281
#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
G
Guy Cohen 已提交
282

T
Tomas Winkler 已提交
283
/*FIXME:RS:add possible actions for MIMO3*/
G
Guy Cohen 已提交
284

285 286 287
#define IWL_ACTION_LIMIT		3	/* # possible actions */

#define LQ_SIZE		2	/* 2 mode tables:  "Active" and "Search" */
Z
Zhu Yi 已提交
288

289 290 291 292 293 294 295 296 297 298 299 300
/* load per tid defines for A-MPDU activation */
#define IWL_AGG_TPT_THREHOLD	0
#define IWL_AGG_LOAD_THRESHOLD	10
#define IWL_AGG_ALL_TID		0xff
#define TID_QUEUE_CELL_SPACING	50	/*mS */
#define TID_QUEUE_MAX_SIZE	20
#define TID_ROUND_VALUE		5	/* mS */
#define TID_MAX_LOAD_COUNT	8

#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING)
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))

301
extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
302
extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
Z
Zhu Yi 已提交
303

G
Guy Cohen 已提交
304
enum iwl_table_type {
Z
Zhu Yi 已提交
305
	LQ_NONE,
306
	LQ_G,		/* legacy types */
Z
Zhu Yi 已提交
307
	LQ_A,
308
	LQ_SISO,	/* high-throughput types */
G
Guy Cohen 已提交
309 310
	LQ_MIMO2,
	LQ_MIMO3,
Z
Zhu Yi 已提交
311 312 313
	LQ_MAX,
};

314
#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
G
Guy Cohen 已提交
315 316 317 318
#define is_siso(tbl) ((tbl) == LQ_SISO)
#define is_mimo2(tbl) ((tbl) == LQ_MIMO2)
#define is_mimo3(tbl) ((tbl) == LQ_MIMO3)
#define is_mimo(tbl) (is_mimo2(tbl) || is_mimo3(tbl))
319
#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
G
Guy Cohen 已提交
320 321 322 323 324 325 326 327 328 329 330 331
#define is_a_band(tbl) ((tbl) == LQ_A)
#define is_g_and(tbl) ((tbl) == LQ_G)

#define	ANT_NONE	0x0
#define	ANT_A		BIT(0)
#define	ANT_B		BIT(1)
#define	ANT_AB		(ANT_A | ANT_B)
#define ANT_C		BIT(2)
#define	ANT_AC		(ANT_A | ANT_C)
#define ANT_BC		(ANT_B | ANT_C)
#define ANT_ABC		(ANT_AB | ANT_C)

332 333 334 335 336 337 338
#define IWL_MAX_MCS_DISPLAY_SIZE	12

struct iwl_rate_mcs_info {
	char	mbps[IWL_MAX_MCS_DISPLAY_SIZE];
	char	mcs[IWL_MAX_MCS_DISPLAY_SIZE];
};

339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
/**
 * struct iwl_rate_scale_data -- tx success history for one rate
 */
struct iwl_rate_scale_data {
	u64 data;		/* bitmap of successful frames */
	s32 success_counter;	/* number of frames successful */
	s32 success_ratio;	/* per-cent * 128  */
	s32 counter;		/* number of frames attempted */
	s32 average_tpt;	/* success ratio * expected throughput */
	unsigned long stamp;
};

/**
 * struct iwl_scale_tbl_info -- tx params and success history for all rates
 *
 * There are two of these in struct iwl_lq_sta,
 * one for "active", and one for "search".
 */
struct iwl_scale_tbl_info {
	enum iwl_table_type lq_type;
	u8 ant_type;
	u8 is_SGI;	/* 1 = short guard interval */
	u8 is_ht40;	/* 1 = 40 MHz channel width */
	u8 is_dup;	/* 1 = duplicated data streams */
	u8 action;	/* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
	u8 max_search;	/* maximun number of tables we can search */
	s32 *expected_tpt;	/* throughput metrics; expected_tpt_G, etc. */
	u32 current_rate;  /* rate_n_flags, uCode API format */
	struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
};

struct iwl_traffic_load {
	unsigned long time_stamp;	/* age of the oldest statistics */
	u32 packet_count[TID_QUEUE_MAX_SIZE];   /* packet count in this time
						 * slice */
	u32 total;			/* total num of packets during the
					 * last TID_MAX_TIME_DIFF */
	u8 queue_count;			/* number of queues that has
					 * been used since the last cleanup */
	u8 head;			/* start of the circular buffer */
};

/**
 * struct iwl_lq_sta -- driver's rate scaling private structure
 *
 * Pointer to this gets passed back and forth between driver and mac80211.
 */
struct iwl_lq_sta {
	u8 active_tbl;		/* index of active table, range 0-1 */
	u8 enable_counter;	/* indicates HT mode */
	u8 stay_in_tbl;		/* 1: disallow, 0: allow search for new mode */
	u8 search_better_tbl;	/* 1: currently trying alternate mode */
	s32 last_tpt;

	/* The following determine when to search for a new mode */
	u32 table_count_limit;
	u32 max_failure_limit;	/* # failed frames before new search */
	u32 max_success_limit;	/* # successful frames before new search */
	u32 table_count;
	u32 total_failed;	/* total failed frames, any/all rates */
	u32 total_success;	/* total successful frames, any/all rates */
	u64 flush_timer;	/* time staying in mode before new search */

	u8 action_counter;	/* # mode-switch actions tried */
	u8 is_green;
	u8 is_dup;
	enum ieee80211_band band;

	/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
	u32 supp_rates;
	u16 active_legacy_rate;
	u16 active_siso_rate;
	u16 active_mimo2_rate;
	u16 active_mimo3_rate;
	s8 max_rate_idx;     /* Max rate set by user */
	u8 missed_rate_counter;

	struct iwl_link_quality_cmd lq;
	struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
	struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
	u8 tx_agg_tid_en;
#ifdef CONFIG_MAC80211_DEBUGFS
	struct dentry *rs_sta_dbgfs_scale_table_file;
	struct dentry *rs_sta_dbgfs_stats_table_file;
	struct dentry *rs_sta_dbgfs_rate_scale_data_file;
	struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
	u32 dbg_fixed_rate;
#endif
	struct iwl_priv *drv;

	/* used to be in sta_info */
	int last_txrate_idx;
	/* last tx rate_n_flags */
	u32 last_rate_n_flags;
	/* packets destined for this STA are aggregated */
	u8 is_agg;
};

G
Guy Cohen 已提交
437 438 439 440 441 442
static inline u8 num_of_ant(u8 mask)
{
	return  !!((mask) & ANT_A) +
		!!((mask) & ANT_B) +
		!!((mask) & ANT_C);
}
Z
Zhu Yi 已提交
443

444 445 446 447 448 449 450 451 452 453
static inline u8 first_antenna(u8 mask)
{
	if (mask & ANT_A)
		return ANT_A;
	if (mask & ANT_B)
		return ANT_B;
	return ANT_C;
}


454
static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
Z
Zhu Yi 已提交
455
{
456
	u8 rate = iwl_rates[rate_index].prev_ieee;
Z
Zhu Yi 已提交
457 458 459 460 461 462

	if (rate == IWL_RATE_INVALID)
		rate = rate_index;
	return rate;
}

463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
{
	u8 rate = iwl3945_rates[rate_index].prev_ieee;

	if (rate == IWL_RATE_INVALID)
		rate = rate_index;
	return rate;
}

/**
 * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
 *
 * The specific throughput table used is based on the type of network
 * the associated with, including A, B, G, and G w/ TGG protection
 */
extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);

480 481 482 483 484 485
/* Initialize station's rate scaling information after adding station */
extern void iwl_rs_rate_init(struct iwl_priv *priv,
			     struct ieee80211_sta *sta, u8 sta_id);
extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
				 struct ieee80211_sta *sta, u8 sta_id);

Z
Zhu Yi 已提交
486
/**
487
 * iwl_rate_control_register - Register the rate control algorithm callbacks
Z
Zhu Yi 已提交
488 489 490
 *
 * Since the rate control algorithm is hardware specific, there is no need
 * or reason to place it as a stand alone module.  The driver can call
491
 * iwl_rate_control_register in order to register the rate control callbacks
Z
Zhu Yi 已提交
492 493 494 495
 * with the mac80211 subsystem.  This should be performed prior to calling
 * ieee80211_register_hw
 *
 */
496
extern int iwlagn_rate_control_register(void);
497
extern int iwl3945_rate_control_register(void);
Z
Zhu Yi 已提交
498 499

/**
500
 * iwl_rate_control_unregister - Unregister the rate control callbacks
Z
Zhu Yi 已提交
501 502 503 504
 *
 * This should be called after calling ieee80211_unregister_hw, but before
 * the driver is unloaded.
 */
505
extern void iwlagn_rate_control_unregister(void);
506
extern void iwl3945_rate_control_unregister(void);
Z
Zhu Yi 已提交
507

508
#endif /* __iwl_agn__rs__ */