iwl-4965-rs.h 8.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/******************************************************************************
 *
 * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
 *
 * 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:
 * James P. Ketrenos <ipw2100-admin@linux.intel.com>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/

#ifndef __iwl_4965_rs_h__
#define __iwl_4965_rs_h__

#include "iwl-4965.h"

32
struct iwl4965_rate_info {
33 34 35 36
	u8 plcp;	/* uCode API:  IWL_RATE_6M_PLCP, etc. */
	u8 plcp_siso;	/* uCode API:  IWL_RATE_SISO_6M_PLCP, etc. */
	u8 plcp_mimo;	/* uCode API:  IWL_RATE_MIMO_6M_PLCP, etc. */
	u8 ieee;	/* MAC header:  IWL_RATE_6M_IEEE, etc. */
37 38 39 40 41 42 43 44
	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 */
};

45 46 47 48
/*
 * These serve as indexes into
 * struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT];
 */
49 50 51 52 53 54 55 56 57 58 59 60 61 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,
	IWL_RATE_COUNT,
	IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
	IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
};

enum {
	IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
	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' */
76 77 78 79 80 81 82 83 84 85 86 87 88
#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)
89

90
/* 4965 uCode API values for legacy bit rates, both OFDM and CCK */
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
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,
	IWL_RATE_60M_PLCP = 3,
	IWL_RATE_1M_PLCP  = 10,
	IWL_RATE_2M_PLCP  = 20,
	IWL_RATE_5M_PLCP  = 55,
	IWL_RATE_11M_PLCP = 110,
};

107
/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
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,
	IWL_RATE_MIMO_6M_PLCP  = 0x8,
	IWL_RATE_MIMO_12M_PLCP = 0x9,
	IWL_RATE_MIMO_18M_PLCP = 0xa,
	IWL_RATE_MIMO_24M_PLCP = 0xb,
	IWL_RATE_MIMO_36M_PLCP = 0xc,
	IWL_RATE_MIMO_48M_PLCP = 0xd,
	IWL_RATE_MIMO_54M_PLCP = 0xe,
	IWL_RATE_MIMO_60M_PLCP = 0xf,
	IWL_RATE_SISO_INVM_PLCP,
	IWL_RATE_MIMO_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
};

129
/* MAC header values for bit rates */
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
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          \
       (IWL_BASIC_RATES_MASK      | \
	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)

172
#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
173 174 175 176 177 178

#define IWL_INVALID_VALUE    -1

#define IWL_MIN_RSSI_VAL                 -100
#define IWL_MAX_RSSI_VAL                    0

179 180
/* These values specify how many Tx frame attempts before
 * searching for a new modulation mode */
181 182 183 184 185 186 187 188
#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

189 190 191 192 193 194
/* 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% */
#define IWL_RATE_INCREASE_TH            8960	/*  70% */
#define IWL_RATE_DECREASE_TH		1920	/*  15% */
195

196 197 198 199 200 201
/* possible actions when in legacy mode */
#define IWL_LEGACY_SWITCH_ANTENNA	0
#define IWL_LEGACY_SWITCH_SISO		1
#define IWL_LEGACY_SWITCH_MIMO	        2

/* possible actions when in siso mode */
202 203 204 205
#define IWL_SISO_SWITCH_ANTENNA		0
#define IWL_SISO_SWITCH_MIMO		1
#define IWL_SISO_SWITCH_GI		2

206
/* possible actions when in mimo mode */
207 208 209 210
#define IWL_MIMO_SWITCH_ANTENNA_A	0
#define IWL_MIMO_SWITCH_ANTENNA_B	1
#define IWL_MIMO_SWITCH_GI		2

211 212 213
#define IWL_ACTION_LIMIT		3	/* # possible actions */

#define LQ_SIZE		2	/* 2 mode tables:  "Active" and "Search" */
214

215
extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT];
216

217
enum iwl4965_table_type {
218
	LQ_NONE,
219
	LQ_G,		/* legacy types */
220
	LQ_A,
221
	LQ_SISO,	/* high-throughput types */
222 223 224 225
	LQ_MIMO,
	LQ_MAX,
};

226 227 228 229 230 231 232
#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
#define is_siso(tbl) (((tbl) == LQ_SISO))
#define is_mimo(tbl) (((tbl) == LQ_MIMO))
#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
#define is_a_band(tbl) (((tbl) == LQ_A))
#define is_g_and(tbl) (((tbl) == LQ_G))

233
/* 4965 has 2 antennas/chains for Tx (but 3 for Rx) */
234
enum iwl4965_antenna_type {
235 236 237 238 239 240
	ANT_NONE,
	ANT_MAIN,
	ANT_AUX,
	ANT_BOTH,
};

241
static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
242
{
243
	u8 rate = iwl4965_rates[rate_index].prev_ieee;
244 245 246 247 248 249

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

250
extern int iwl4965_rate_index_from_plcp(int plcp);
251 252

/**
253
 * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
254 255
 *
 * NOTE:  This is provided as a quick mechanism for a user to visualize
256
 * the performance of the rate control algorithm and is not meant to be
257 258
 * parsed software.
 */
259
extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
260 261

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

/**
270
 * iwl4965_rate_control_register - Register the rate control algorithm callbacks
271 272 273
 *
 * 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
274
 * iwl4965_rate_control_register in order to register the rate control callbacks
275 276 277 278
 * with the mac80211 subsystem.  This should be performed prior to calling
 * ieee80211_register_hw
 *
 */
279
extern void iwl4965_rate_control_register(struct ieee80211_hw *hw);
280 281

/**
282
 * iwl4965_rate_control_unregister - Unregister the rate control callbacks
283 284 285 286
 *
 * This should be called after calling ieee80211_unregister_hw, but before
 * the driver is unloaded.
 */
287
extern void iwl4965_rate_control_unregister(struct ieee80211_hw *hw);
288 289

#endif