xref: /titanic_44/usr/src/uts/common/io/iwk/iwk_calibration.h (revision 0dc2366f7b9f9f36e10909b1e95edbf2a261c2ac)
1 /*
2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * Copyright (c) 2008, Intel Corporation
8  * All rights reserved.
9  */
10 
11 /*
12  * Sun elects to have this file available under and governed by the BSD
13  * license (see below for full license text). However, the following
14  * notice accompanied the original version of this file:
15  */
16 
17 /*
18  * This file is provided under a dual BSD/GPLv2 license.  When using or
19  * redistributing this file, you may do so under either license.
20  *
21  * GPL LICENSE SUMMARY
22  *
23  * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
24  *
25  * This program is free software; you can redistribute it and/or modify
26  * it under the terms of version 2 of the GNU Geeral Public License as
27  * published by the Free Software Foundation.
28  *
29  * This program is distributed in the hope that it will be useful, but
30  * WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
32  * General Public License for more details.
33  *
34  * You should have received a copy of the GNU General Public License
35  * along with this program; if not, write to the Free Software
36  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
37  * USA
38  *
39  * The full GNU General Public License is included in this distribution
40  * in the file called LICENSE.GPL.
41  *
42  * Contact Information:
43  * James P. Ketrenos <ipw2100-admin@linux.intel.com>
44  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
45  *
46  * BSD LICENSE
47  *
48  * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
49  * All rights reserved.
50  *
51  * Redistribution and use in source and binary forms, with or without
52  * modification, are permitted provided that the following conditions
53  * are met:
54  *
55  *  * Redistributions of source code must retain the above copyright
56  *    notice, this list of conditions and the following disclaimer.
57  *  * Redistributions in binary form must reproduce the above copyright
58  *    notice, this list of conditions and the following disclaimer in
59  *    the documentation and/or other materials provided with the
60  *    distribution.
61  *  * Neither the name Intel Corporation nor the names of its
62  *    contributors may be used to endorse or promote products derived
63  *    from this software without specific prior written permission.
64  *
65  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
66  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
67  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
68  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
69  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
70  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
71  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
72  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
73  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
75  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76  */
77 
78 
79 #ifndef _IWK_CALIBRATION_H_
80 #define	_IWK_CALIBRATION_H_
81 
82 /*
83  * Most Tx and Rx calibration is done by uCode during the initialization
84  * phase of uCode boot. Driver must calibrate only:
85  *
86  * 1)  Tx power (depends on temperature)
87  * 2)  Receiver gain balance (and detect disconnected antennas)
88  * 3)  Receiver sensitivity (to optimize signal detection)
89  */
90 
91 /* START TEMPERATURE */
92 
93 /*
94  * 4965 temperature calculation.
95  *
96  * The driver must calculate the device temperature before calculating
97  * a txpower setting (amplifier gain is temperature dependent).  The
98  * calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration
99  * values used for the life of the driver, and one of which (R4) is the
100  * real-time temperature indicator.
101  *
102  * uCode provides all 4 values to the driver via the "initialize alive"
103  * notification (see struct iwk_init_alive_resp).  After the runtime uCode
104  * image loads, uCode updates the R4 value via statistics notifications
105  * (see STATISTICS_NOTIFICATION), which occur after each received beacon
106  * when associated, or can be requested via REPLY_STATISTICS_CMD.
107  *
108  * NOTE:  uCode provides the R4 value as a 23-bit signed value.  Driver
109  *        must sign-extend to 32 bits before applying formula below.
110  *
111  * Formula:
112  *
113  * degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8
114  *
115  * NOTE:  The basic formula is 259 * (R4-R2) / (R3-R1).  The 97/100 is
116  * an additional correction, which should be centered around 0 degrees
117  * Celsius (273 degrees Kelvin).  The 8 (3 percent of 273) compensates for
118  * centering the 97/100 correction around 0 degrees K.
119  *
120  * Add 273 to Kelvin value to find degrees Celsius, for comparing current
121  * temperature with factory-measured temperatures when calculating txpower
122  * settings.
123  */
124 
125 /* END TEMPERATURE */
126 
127 /* START TXPOWER */
128 
129 /*
130  * 4965 txpower calculations rely on information from three sources:
131  *
132  *     1) EEPROM
133  *     2) "initialize" alive notification
134  *     3) statistics notifications
135  *
136  * EEPROM data consists of:
137  *
138  * 1)  Regulatory information (max txpower and channel usage flags) is provided
139  *     separately for each channel that can possibly supported by 4965.
140  *     40 MHz wide (.11n fat) channels are listed separately from 20 MHz
141  *     (legacy) channels.
142  *
143  *     See struct iwk_eep_channel for format, and struct iwk_eep for
144  *     locations in EEPROM.
145  *
146  * 2)  Factory txpower calibration information is provided separately for
147  *     sub-bands of contiguous channels.  2.4GHz has just one sub-band,
148  *     but 5 GHz has several sub-bands.
149  *
150  *     In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided.
151  *
152  *     See struct iwk_eep_calib_info (and the tree of structures contained
153  *     within it) for format, and struct iwk_eep for locations in EEPROM.
154  *
155  * "Initialization alive" notification (see struct iwk_init_alive_resp)
156  * consists of:
157  *
158  * 1)  Temperature calculation parameters.
159  *
160  * 2)  Power supply voltage measurement.
161  *
162  * 3)  Tx gain compensation to balance 2 transmitters for MIMO use.
163  *
164  * Statistics notifications deliver:
165  *
166  * 1)  Current values for temperature param R4.
167  */
168 
169 /*
170  * To calculate a txpower setting for a given desired target txpower, channel,
171  * modulation bit rate, and transmitter chain (4965 has 2 transmitters to
172  * support MIMO and transmit diversity), driver must do the following:
173  *
174  * 1)  Compare desired txpower vs. (EEPROM) regulatory limit for this channel.
175  *     Do not exceed regulatory limit; reduce target txpower if necessary.
176  *
177  *     If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31),
178  *     2 transmitters will be used simultaneously; driver must reduce the
179  *     regulatory limit by 3 dB (half-power) for each transmitter, so the
180  *     combined total output of the 2 transmitters is within regulatory limits.
181  *
182  *
183  * 2)  Compare target txpower vs. (EEPROM) saturation txpower *reduced by
184  *     backoff for this bit rate*.  Do not exceed (saturation - backoff[rate]);
185  *     reduce target txpower if necessary.
186  *
187  *     Backoff values below are in 1/2 dB units (equivalent to steps in
188  *     txpower gain tables):
189  *
190  *     OFDM 6 - 36 MBit:  10 steps (5 dB)
191  *     OFDM 48 MBit:      15 steps (7.5 dB)
192  *     OFDM 54 MBit:      17 steps (8.5 dB)
193  *     OFDM 60 MBit:      20 steps (10 dB)
194  *     CCK all rates:     10 steps (5 dB)
195  *
196  *     Backoff values apply to saturation txpower on a per-transmitter basis;
197  *     when using MIMO (2 transmitters), each transmitter uses the same
198  *     saturation level provided in EEPROM, and the same backoff values;
199  *     no reduction (such as with regulatory txpower limits) is required.
200  *
201  *     Saturation and Backoff values apply equally to 20 Mhz (legacy) channel
202  *     widths and 40 Mhz (.11n fat) channel widths; there is no separate
203  *     factory measurement for fat channels.
204  *
205  *     The result of this step is the final target txpower.  The rest of
206  *     the steps figure out the proper settings for the device.
207  *
208  *
209  * 3)  Determine (EEPROM) calibration subband for the target channel, by
210  *     comparing against first and last channels in each subband
211  *     (see struct iwk_eep_calib_subband_info).
212  *
213  *
214  * 4)  Linearly interpolate (EEPROM) factory calibration measurement sets,
215  *     referencing the 2 factory-measured (sample) channels within the subband.
216  *
217  *     Interpolation is based on difference between target channel's frequency
218  *     and the sample channels' frequencies.  Since channel numbers are based
219  *     on frequency (5 MHz between each channel number), this is equivalent
220  *     to interpolating based on channel number differences.
221  *
222  *     Note that the sample channels may or may not be the channels at the
223  *     edges of the subband.  The target channel may be "outside" of the
224  *     span of the sampled channels.
225  *
226  *     Driver may choose the pair (for 2 Tx chains) of measurements (see
227  *     struct iwk_eep_calib_channel_info) for which the actual measured
228  *     txpower comes closest to the desired txpower.  Usually, though,
229  *     the middle set of measurements is closest to the regulatory limits,
230  *     and is therefore a good choice for all txpower calculations.
231  *
232  *     Driver should interpolate both members of the chosen measurement pair,
233  *     i.e. for both Tx chains (radio transmitters), unless the driver knows
234  *     that only one of the chains will be used (e.g. only one tx antenna
235  *     connected, but this should be unusual).
236  *
237  *     Driver should interpolate factory values for temperature, gain table
238  *     index, and actual power.  The power amplifier detector values are
239  *     not used by the driver.
240  *
241  *     If the target channel happens to be one of the sample channels, the
242  *     results should agree with the sample channel's measurements!
243  *
244  *
245  * 5)  Find difference between desired txpower and (interpolated)
246  *     factory-measured txpower.  Using (interpolated) factory gain table index
247  *     as a starting point, adjust this index lower to increase txpower,
248  *     or higher to decrease txpower, until the target txpower is reached.
249  *     Each step in the gain table is 1/2 dB.
250  *
251  *     For example, if factory measured txpower is 16 dBm, and target txpower
252  *     is 13 dBm, add 6 steps to the factory gain index to reduce txpower
253  *     by 3 dB.
254  *
255  *
256  * 6)  Find difference between current device temperature and (interpolated)
257  *     factory-measured temperature for sub-band.  Factory values are in
258  *     degrees Celsius.  To calculate current temperature, see comments for
259  *     "4965 temperature calculation".
260  *
261  *     If current temperature is higher than factory temperature, driver must
262  *     increase gain (lower gain table index), and vice versa.
263  *
264  *     Temperature affects gain differently for different channels:
265  *
266  *     2.4 GHz all channels:  3.5 degrees per half-dB step
267  *     5 GHz channels 34-43:  4.5 degrees per half-dB step
268  *     5 GHz channels >= 44:  4.0 degrees per half-dB step
269  *
270  *     NOTE:  Temperature can increase rapidly when transmitting, especially
271  *            with heavy traffic at high txpowers.  Driver should update
272  *            temperature calculations often under these conditions to
273  *            maintain strong txpower in the face of rising temperature.
274  *
275  *
276  * 7)  Find difference between current power supply voltage indicator
277  *     (from "initialize alive") and factory-measured power supply voltage
278  *     indicator (EEPROM).
279  *
280  *     If the current voltage is higher (indicator is lower) than factory
281  *     voltage, gain should be reduced (gain table index increased) by:
282  *
283  *     (eeprom - current) / 7
284  *
285  *     If the current voltage is lower (indicator is higher) than factory
286  *     voltage, gain should be increased (gain table index decreased) by:
287  *
288  *     2 * (current - eeprom) / 7
289  *
290  *     If number of index steps in either direction turns out to be > 2,
291  *     something is wrong ... just use 0.
292  *
293  *     NOTE:  Voltage compensation is independent of band/channel.
294  *
295  *     NOTE:  "Initialize" uCode measures current voltage, which is assumed
296  *            to be constant after this initial measurement.  Voltage
297  *            compensation for txpower (number of steps in gain table)
298  *            may be calculated once and used until the next uCode bootload.
299  *
300  *
301  * 8)  If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31),
302  *     adjust txpower for each transmitter chain, so txpower is balanced
303  *     between the two chains.  There are 5 pairs of tx_atten[group][chain]
304  *     values in "initialize alive", one pair for each of 5 channel ranges:
305  *
306  *     Group 0:  5 GHz channel 34-43
307  *     Group 1:  5 GHz channel 44-70
308  *     Group 2:  5 GHz channel 71-124
309  *     Group 3:  5 GHz channel 125-200
310  *     Group 4:  2.4 GHz all channels
311  *
312  *     Add the tx_atten[group][chain] value to the index for the target chain.
313  *     The values are signed, but are in pairs of 0 and a non-negative number,
314  *     so as to reduce gain (if necessary) of the "hotter" channel.  This
315  *     avoids any need to double-check for regulatory compliance after
316  *     this step.
317  *
318  *
319  * 9)  If setting up for a CCK rate, lower the gain by adding a CCK compensation
320  *     value to the index:
321  *
322  *     Hardware rev B:  9 steps (4.5 dB)
323  *     Hardware rev C:  5 steps (2.5 dB)
324  *
325  *     Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG,
326  *     bits [3:2], 1 = B, 2 = C.
327  *
328  *     NOTE:  This compensation is in addition to any saturation backoff that
329  *            might have been applied in an earlier step.
330  *
331  *
332  * 10) Select the gain table, based on band (2.4 vs 5 GHz).
333  *
334  *     Limit the adjusted index to stay within the table!
335  *
336  *
337  * 11) Read gain table entries for DSP and radio gain, place into appropriate
338  *     location(s) in command.
339  */
340 
341 /* Temperature calibration offset is 3% 0C in Kelvin */
342 #define	TEMPERATURE_CALIB_KELVIN_OFFSET 8
343 #define	TEMPERATURE_CALIB_A_VAL 259
344 
345 #define	KELVIN_TO_CELSIUS(x) ((x)-273)
346 #define	CELSIUS_TO_KELVIN(x) ((x)+273)
347 
348 /* First and last channels of all groups */
349 #define	CALIB_IWK_TX_ATTEN_GR1_FCH 34
350 #define	CALIB_IWK_TX_ATTEN_GR1_LCH 43
351 #define	CALIB_IWK_TX_ATTEN_GR2_FCH 44
352 #define	CALIB_IWK_TX_ATTEN_GR2_LCH 70
353 #define	CALIB_IWK_TX_ATTEN_GR3_FCH 71
354 #define	CALIB_IWK_TX_ATTEN_GR3_LCH 124
355 #define	CALIB_IWK_TX_ATTEN_GR4_FCH 125
356 #define	CALIB_IWK_TX_ATTEN_GR4_LCH 200
357 #define	CALIB_IWK_TX_ATTEN_GR5_FCH 1
358 #define	CALIB_IWK_TX_ATTEN_GR5_LCH 20
359 
360 /* Limit range of txpower output target to be between these values */
361 #define	IWK_TX_POWER_TARGET_POWER_MIN  (0)   /* 0 dBm = 1 milliwatt */
362 #define	IWK_TX_POWER_TARGET_POWER_MAX  (16)  /* 16 dBm */
363 
364 #define	TX_POWER_IWK_ILLEGAL_VOLTAGE  (-10000)
365 
366 /*
367  * 4965 power supply voltage compensation
368  */
369 #define	TX_POWER_IWK_VOLTAGE_CODES_PER_03V  (7)
370 
371 /* Limit range of calculated temperature to be between these Kelvin values */
372 #define	IWK_TX_POWER_TEMPERATURE_MIN  (263)
373 #define	IWK_TX_POWER_TEMPERATURE_MAX  (410)
374 
375 union iwk_tx_power_dual_stream {
376 	struct {
377 		uint8_t radio_tx_gain[2];
378 		uint8_t dsp_predis_atten[2];
379 	} s;
380 	uint32_t dw;
381 };
382 
383 #define	POWER_TABLE_NUM_ENTRIES	(33)
384 #define	POWER_TABLE_CCK_ENTRY	(32)
385 
386 /*
387  * When MIMO is used (2 transmitters operating simultaneously), driver should
388  * limit each transmitter to deliver a max of 3 dB below the regulatory limit
389  * for the device.  That is, half power for each transmitter, so total power
390  * is within regulatory limits.
391  *
392  * The value "6" represents number of steps in gain table to reduce power.
393  * Each step is 1/2 dB.
394  */
395 #define	IWK_TX_POWER_MIMO_REGULATORY_COMPENSATION	(6)
396 
397 /*
398  * CCK gain compensation.
399  *
400  * When calculating txpowers for CCK, after making sure that the target power
401  * is within regulatory and saturation limits, driver must additionally
402  * back off gain by adding these values to the gain table index.
403  */
404 #define	IWK_TX_POWER_CCK_COMPENSATION_C_STEP	(5)
405 
406 /*
407  * Gain tables.
408  *
409  * The following tables contain pair of values for setting txpower, i.e.
410  * gain settings for the output of the device's digital signal processor (DSP),
411  * and for the analog gain structure of the transmitter.
412  *
413  * Each entry in the gain tables represents a step of 1/2 dB.  Note that these
414  * are *relative* steps, not indications of absolute output power.  Output
415  * power varies with temperature, voltage, and channel frequency, and also
416  * requires consideration of average power (to satisfy regulatory constraints),
417  * and peak power (to avoid distortion of the output signal).
418  *
419  * Each entry contains two values:
420  * 1)  DSP gain (or sometimes called DSP attenuation).  This is a fine-grained
421  *     linear value that multiplies the output of the digital signal processor,
422  *     before being sent to the analog radio.
423  * 2)  Radio gain.  This sets the analog gain of the radio Tx path.
424  *     It is a coarser setting, and behaves in a logarithmic (dB) fashion.
425  *
426  * EEPROM contains factory calibration data for txpower.  This maps actual
427  * measured txpower levels to gain settings in the "well known" tables
428  * below ("well-known" means here that both factory calibration *and* the
429  * driver work with the same table).
430  *
431  * There are separate tables for 2.4 GHz and 5 GHz bands.  The 5 GHz table
432  * has an extension (into negative indexes), in case the driver needs to
433  * boost power setting for high device temperatures (higher than would be
434  * present during factory calibration).  A 5 Ghz EEPROM index of "40"
435  * corresponds to the 49th entry in the table used by the driver.
436  */
437 #define	MIN_TX_GAIN_INDEX	(0) /* highest gain, lowest idx, 2.4 */
438 #define	MIN_TX_GAIN_INDEX_52GHZ_EXT	(-9) /* highest gain, lowest idx, 5 */
439 
440 struct gain_entry {
441 	uint8_t	dsp;
442 	uint8_t	radio;
443 };
444 
445 static const struct gain_entry gains_table[2][108] = {
446 	/* 5.2GHz power gain index table */
447 	{
448 		{123, 0x3F},	/* highest txpower */
449 		{117, 0x3F},
450 		{110, 0x3F},
451 		{104, 0x3F},
452 		{98, 0x3F},
453 		{110, 0x3E},
454 		{104, 0x3E},
455 		{98, 0x3E},
456 		{110, 0x3D},
457 		{104, 0x3D},
458 		{98, 0x3D},
459 		{110, 0x3C},
460 		{104, 0x3C},
461 		{98, 0x3C},
462 		{110, 0x3B},
463 		{104, 0x3B},
464 		{98, 0x3B},
465 		{110, 0x3A},
466 		{104, 0x3A},
467 		{98, 0x3A},
468 		{110, 0x39},
469 		{104, 0x39},
470 		{98, 0x39},
471 		{110, 0x38},
472 		{104, 0x38},
473 		{98, 0x38},
474 		{110, 0x37},
475 		{104, 0x37},
476 		{98, 0x37},
477 		{110, 0x36},
478 		{104, 0x36},
479 		{98, 0x36},
480 		{110, 0x35},
481 		{104, 0x35},
482 		{98, 0x35},
483 		{110, 0x34},
484 		{104, 0x34},
485 		{98, 0x34},
486 		{110, 0x33},
487 		{104, 0x33},
488 		{98, 0x33},
489 		{110, 0x32},
490 		{104, 0x32},
491 		{98, 0x32},
492 		{110, 0x31},
493 		{104, 0x31},
494 		{98, 0x31},
495 		{110, 0x30},
496 		{104, 0x30},
497 		{98, 0x30},
498 		{110, 0x25},
499 		{104, 0x25},
500 		{98, 0x25},
501 		{110, 0x24},
502 		{104, 0x24},
503 		{98, 0x24},
504 		{110, 0x23},
505 		{104, 0x23},
506 		{98, 0x23},
507 		{110, 0x22},
508 		{104, 0x18},
509 		{98, 0x18},
510 		{110, 0x17},
511 		{104, 0x17},
512 		{98, 0x17},
513 		{110, 0x16},
514 		{104, 0x16},
515 		{98, 0x16},
516 		{110, 0x15},
517 		{104, 0x15},
518 		{98, 0x15},
519 		{110, 0x14},
520 		{104, 0x14},
521 		{98, 0x14},
522 		{110, 0x13},
523 		{104, 0x13},
524 		{98, 0x13},
525 		{110, 0x12},
526 		{104, 0x08},
527 		{98, 0x08},
528 		{110, 0x07},
529 		{104, 0x07},
530 		{98, 0x07},
531 		{110, 0x06},
532 		{104, 0x06},
533 		{98, 0x06},
534 		{110, 0x05},
535 		{104, 0x05},
536 		{98, 0x05},
537 		{110, 0x04},
538 		{104, 0x04},
539 		{98, 0x04},
540 		{110, 0x03},
541 		{104, 0x03},
542 		{98, 0x03},
543 		{110, 0x02},
544 		{104, 0x02},
545 		{98, 0x02},
546 		{110, 0x01},
547 		{104, 0x01},
548 		{98, 0x01},
549 		{110, 0x00},
550 		{104, 0x00},
551 		{98, 0x00},
552 		{93, 0x00},
553 		{88, 0x00},
554 		{83, 0x00},
555 		{78, 0x00},
556 	},
557 	/* 2.4GHz power gain index table */
558 	{
559 		{110, 0x3f},	/* highest txpower */
560 		{104, 0x3f},
561 		{98, 0x3f},
562 		{110, 0x3e},
563 		{104, 0x3e},
564 		{98, 0x3e},
565 		{110, 0x3d},
566 		{104, 0x3d},
567 		{98, 0x3d},
568 		{110, 0x3c},
569 		{104, 0x3c},
570 		{98, 0x3c},
571 		{110, 0x3b},
572 		{104, 0x3b},
573 		{98, 0x3b},
574 		{110, 0x3a},
575 		{104, 0x3a},
576 		{98, 0x3a},
577 		{110, 0x39},
578 		{104, 0x39},
579 		{98, 0x39},
580 		{110, 0x38},
581 		{104, 0x38},
582 		{98, 0x38},
583 		{110, 0x37},
584 		{104, 0x37},
585 		{98, 0x37},
586 		{110, 0x36},
587 		{104, 0x36},
588 		{98, 0x36},
589 		{110, 0x35},
590 		{104, 0x35},
591 		{98, 0x35},
592 		{110, 0x34},
593 		{104, 0x34},
594 		{98, 0x34},
595 		{110, 0x33},
596 		{104, 0x33},
597 		{98, 0x33},
598 		{110, 0x32},
599 		{104, 0x32},
600 		{98, 0x32},
601 		{110, 0x31},
602 		{104, 0x31},
603 		{98, 0x31},
604 		{110, 0x30},
605 		{104, 0x30},
606 		{98, 0x30},
607 		{110, 0x6},
608 		{104, 0x6},
609 		{98, 0x6},
610 		{110, 0x5},
611 		{104, 0x5},
612 		{98, 0x5},
613 		{110, 0x4},
614 		{104, 0x4},
615 		{98, 0x4},
616 		{110, 0x3},
617 		{104, 0x3},
618 		{98, 0x3},
619 		{110, 0x2},
620 		{104, 0x2},
621 		{98, 0x2},
622 		{110, 0x1},
623 		{104, 0x1},
624 		{98, 0x1},
625 		{110, 0x0},
626 		{104, 0x0},
627 		{98, 0x0},
628 		{97, 0},
629 		{96, 0},
630 		{95, 0},
631 		{94, 0},
632 		{93, 0},
633 		{92, 0},
634 		{91, 0},
635 		{90, 0},
636 		{89, 0},
637 		{88, 0},
638 		{87, 0},
639 		{86, 0},
640 		{85, 0},
641 		{84, 0},
642 		{83, 0},
643 		{82, 0},
644 		{81, 0},
645 		{80, 0},
646 		{79, 0},
647 		{78, 0},
648 		{77, 0},
649 		{76, 0},
650 		{75, 0},
651 		{74, 0},
652 		{73, 0},
653 		{72, 0},
654 		{71, 0},
655 		{70, 0},
656 		{69, 0},
657 		{68, 0},
658 		{67, 0},
659 		{66, 0},
660 		{65, 0},
661 		{64, 0},
662 		{63, 0},
663 		{62, 0},
664 		{61, 0},
665 		{60, 0},
666 		{59, 0},
667 	}
668 };
669 
670 /* END TXPOWER */
671 
672 struct statistics_div {
673 	uint32_t tx_on_a;
674 	uint32_t tx_on_b;
675 	uint32_t exec_time;
676 	uint32_t probe_time;
677 	uint32_t reserved1;
678 	uint32_t reserved2;
679 };
680 
681 struct statistics_dbg {
682 	uint32_t burst_check;
683 	uint32_t burst_count;
684 	uint32_t reserved[4];
685 };
686 
687 
688 struct statistics_general {
689 	uint32_t temperature;
690 	uint32_t temperature_m;
691 	struct statistics_dbg dbg;
692 	uint32_t sleep_time;
693 	uint32_t slots_out;
694 	uint32_t slots_idle;
695 	uint32_t ttl_timestamp;
696 	struct statistics_div div;
697 	uint32_t rx_enable_counter;
698 	uint32_t reserved1;
699 	uint32_t reserved2;
700 	uint32_t reserved3;
701 };
702 
703 
704 struct statistics_tx_non_phy_agg {
705 	uint32_t ba_timeout;
706 	uint32_t ba_reschedule_frames;
707 	uint32_t scd_query_agg_frame_cnt;
708 	uint32_t scd_query_no_agg;
709 	uint32_t scd_query_agg;
710 	uint32_t scd_query_mismatch;
711 	uint32_t frame_not_ready;
712 	uint32_t underrun;
713 	uint32_t bt_prio_kill;
714 	uint32_t rx_ba_rsp_cnt;
715 	uint32_t reserved2;
716 	uint32_t reserved3;
717 };
718 
719 
720 struct statistics_tx {
721 	uint32_t preamble_cnt;
722 	uint32_t rx_detected_cnt;
723 	uint32_t bt_prio_defer_cnt;
724 	uint32_t bt_prio_kill_cnt;
725 	uint32_t few_bytes_cnt;
726 	uint32_t cts_timeout;
727 	uint32_t ack_timeout;
728 	uint32_t expected_ack_cnt;
729 	uint32_t actual_ack_cnt;
730 	uint32_t dump_msdu_cnt;
731 	uint32_t burst_abort_next_frame_mismatch_cnt;
732 	uint32_t burst_abort_missing_next_frame_cnt;
733 	uint32_t cts_timeout_collision;
734 	uint32_t ack_or_ba_timeout_collision;
735 	struct statistics_tx_non_phy_agg agg;
736 };
737 
738 
739 struct statistics_rx_ht_phy {
740 	uint32_t plcp_err;
741 	uint32_t overrun_err;
742 	uint32_t early_overrun_err;
743 	uint32_t crc32_good;
744 	uint32_t crc32_err;
745 	uint32_t mh_format_err;
746 	uint32_t agg_crc32_good;
747 	uint32_t agg_mpdu_cnt;
748 	uint32_t agg_cnt;
749 	uint32_t reserved2;
750 };
751 
752 struct statistics_rx_non_phy {
753 	uint32_t bogus_cts; /* CTS received when not expecting CTS */
754 	uint32_t bogus_ack; /* ACK received when not expecting ACK */
755 	uint32_t non_bssid_frames; /* number of frames with BSSID that */
756 					/* doesn't belong to the STA BSSID */
757 	uint32_t filtered_frames; /* count frames that were dumped in the */
758 					/* filtering process */
759 	uint32_t non_channel_beacons; /* beacons with our bss id but not on */
760 					/* our serving channel */
761 	uint32_t channel_beacons; /* beacons with our bss id and in our */
762 					/* serving channel */
763 	uint32_t num_missed_bcon; /* number of missed beacons */
764 	uint32_t adc_rx_saturation_time; /* count in 0.8us units the time */
765 					/* the ADC was in saturation */
766 	uint32_t ina_detection_search_time; /* total time (in 0.8us) */
767 						/* searched for INA */
768 	uint32_t beacon_silence_rssi_a; /* RSSI silence after beacon frame */
769 	uint32_t beacon_silence_rssi_b; /* RSSI silence after beacon frame */
770 	uint32_t beacon_silence_rssi_c; /* RSSI silence after beacon frame */
771 	uint32_t interference_data_flag; /* flag for interference data */
772 					/* availability. 1 when data is */
773 					/* available. */
774 	uint32_t channel_load; /* counts RX Enable time */
775 	uint32_t dsp_false_alarms; /* DSP false alarm (both OFDM */
776 					/* and CCK) counter */
777 	uint32_t beacon_rssi_a;
778 	uint32_t beacon_rssi_b;
779 	uint32_t beacon_rssi_c;
780 	uint32_t beacon_energy_a;
781 	uint32_t beacon_energy_b;
782 	uint32_t beacon_energy_c;
783 };
784 
785 struct statistics_rx_phy {
786 	uint32_t ina_cnt;
787 	uint32_t fina_cnt;
788 	uint32_t plcp_err;
789 	uint32_t crc32_err;
790 	uint32_t overrun_err;
791 	uint32_t early_overrun_err;
792 	uint32_t crc32_good;
793 	uint32_t false_alarm_cnt;
794 	uint32_t fina_sync_err_cnt;
795 	uint32_t sfd_timeout;
796 	uint32_t fina_timeout;
797 	uint32_t unresponded_rts;
798 	uint32_t rxe_frame_limit_overrun;
799 	uint32_t sent_ack_cnt;
800 	uint32_t sent_cts_cnt;
801 	uint32_t sent_ba_rsp_cnt;
802 	uint32_t dsp_self_kill;
803 	uint32_t mh_format_err;
804 	uint32_t re_acq_main_rssi_sum;
805 	uint32_t reserved3;
806 };
807 
808 struct statistics_rx {
809 	struct statistics_rx_phy ofdm;
810 	struct statistics_rx_phy cck;
811 	struct statistics_rx_non_phy general;
812 	struct statistics_rx_ht_phy ofdm_ht;
813 };
814 
815 struct iwk_notif_statistics {
816 	uint32_t flag;
817 	struct statistics_rx rx;
818 	struct statistics_tx tx;
819 	struct statistics_general general;
820 };
821 
822 /* START Receiver gain balance */
823 
824 /*
825  * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response)
826  *
827  * This command sets the relative gains of 4965's 3 radio receiver chains.
828  *
829  * After the first association, driver should accumulate signal and noise
830  * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20
831  * beacons from the associated network (don't collect statistics that come
832  * in from scanning, or any other non-network source).
833  *
834  * DISCONNECTED ANTENNA:
835  *
836  * Driver should determine which antennas are actually connected, by comparing
837  * average beacon signal levels for the 3 Rx chains.  Accumulate (add) the
838  * following values over 20 beacons, one accumulator for each of the chains
839  * a/b/c, from struct statistics_rx_non_phy:
840  *
841  * beacon_rssi_[abc] & 0x0FF (unsigned, units in dB)
842  *
843  * Find the strongest signal from among a/b/c.  Compare the other two to the
844  * strongest.  If any signal is more than 15 dB (times 20, unless you
845  * divide the accumulated values by 20) below the strongest, the driver
846  * considers that antenna to be disconnected, and should not try to use that
847  * antenna/chain for Rx or Tx.  If both A and B seem to be disconnected,
848  * driver should declare the stronger one as connected, and attempt to use it
849  * (A and B are the only 2 Tx chains!).
850  *
851  *
852  * RX BALANCE:
853  *
854  * Driver should balance the 3 receivers (but just the ones that are connected
855  * to antennas, see above) for gain, by comparing the average signal levels
856  * detected during the silence after each beacon (background noise).
857  * Accumulate (add) the following values over 20 beacons, one accumulator for
858  * each of the chains a/b/c, from struct statistics_rx_non_phy:
859  *
860  * beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB)
861  *
862  * Find the weakest background noise level from among a/b/c.  This Rx chain
863  * will be the reference, with 0 gain adjustment.  Attenuate other channels by
864  * finding noise difference:
865  *
866  * (accum_noise[i] - accum_noise[reference]) / 30
867  *
868  * The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB.
869  * For use in diff_gain_[abc] fields of struct iwk_calibration_cmd, the
870  * driver should limit the difference results to a range of 0-3 (0-4.5 dB),
871  * and set bit 2 to indicate "reduce gain".  The value for the reference
872  * (weakest) chain should be "0".
873  *
874  * diff_gain_[abc] bit fields:
875  *   2: (1) reduce gain, (0) increase gain
876  * 1-0: amount of gain, units of 1.5 dB
877  */
878 
879 #define	RX_CHAINS_NUM  (3)
880 #define	CHAIN_GAIN_DIFF_INIT_VAL  (4)
881 
882 #define	IWK_GAIN_DIFF_ALIVE (0)
883 #define	IWK_GAIN_DIFF_ACCUMULATE (1)
884 #define	IWK_GAIN_DIFF_CALIBRATED (2)
885 
886 #define	INTERFERENCE_DATA_AVAILABLE  (1)
887 #define	BEACON_NUM_20  (20)
888 #define	MAX_ALLOWED_DIFF  (15)
889 
890 struct iwk_rx_gain_diff {
891 	uint8_t		state;
892 	uint16_t	beacon_count;
893 	uint8_t		gain_diff_send;
894 	uint32_t	beacon_stren_a;
895 	uint32_t	beacon_stren_b;
896 	uint32_t	beacon_stren_c;
897 	uint32_t	noise_stren_a;
898 	uint32_t	noise_stren_b;
899 	uint32_t	noise_stren_c;
900 	uint8_t		disconnect_chain[RX_CHAINS_NUM];
901 	uint8_t		connected_chains;
902 	uint8_t		gain_diff_chain[RX_CHAINS_NUM];
903 };
904 
905 /* END Receiver gain balance */
906 
907 /* START Receiver sensitivity */
908 
909 /*
910  * SENSITIVITY_CMD = 0xa8
911  *
912  * This command sets up the Rx signal detector for a sensitivity level that
913  * is high enough to lock onto all signals within the associated network,
914  * but low enough to ignore signals that are below a certain threshold, so as
915  * not to have too many "false alarms".  False alarms are signals that the
916  * Rx DSP tries to lock onto, but then discards after determining that they
917  * are noise.
918  *
919  * The optimum number of false alarms is between 5 and 50 per 200 TUs
920  * (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e.
921  * time listening, not transmitting).  Driver must adjust sensitivity so that
922  * the ratio of actual false alarms to actual Rx time falls within this range.
923  *
924  * While associated, uCode delivers STATISTICS_NOTIFICATIONs after each
925  * received beacon.  These provide information to the driver to analyze the
926  * sensitivity.  Don't analyze statistics that come in from scanning, or any
927  * other non-associated-network source.  Pertinent statistics include:
928  *
929  * From "general" statistics (struct statistics_rx_non_phy):
930  *
931  * (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level)
932  *   Measure of energy of desired signal.  Used for establishing a level
933  *   below which the device does not detect signals.
934  *
935  * (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB)
936  *   Measure of background noise in silent period after beacon.
937  *
938  * channel_load
939  *   uSecs of actual Rx time during beacon period (varies according to
940  *   how much time was spent transmitting).
941  *
942  * From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately:
943  *
944  * false_alarm_cnt
945  *   Signal locks abandoned early (before phy-level header).
946  *
947  * plcp_err
948  *   Signal locks abandoned late (during phy-level header).
949  *
950  * NOTE:  Both false_alarm_cnt and plcp_err increment monotonically from
951  *        beacon to beacon, i.e. each value is an accumulation of all errors
952  *        before and including the latest beacon.  Values will wrap around to 0
953  *        after counting up to 2^32 - 1.  Driver must differentiate vs.
954  *        previous beacon's values to determine # false alarms in the current
955  *        beacon period.
956  *
957  * Total number of false alarms = false_alarms + plcp_errs
958  *
959  * For OFDM, adjust the following table entries in struct iwk_rx_sensitivity_cmd
960  * (notice that the start points for OFDM are at or close to settings for
961  * maximum sensitivity):
962  *
963  *                                             START  /  MIN  /  MAX
964  *   HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX          90   /   85  /  120
965  *   HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX     170   /  170  /  210
966  *   HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX         105   /  105  /  140
967  *   HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX     220   /  220  /  270
968  *
969  *   If actual rate of OFDM false alarms (+ plcp_errors) is too high
970  *   (greater than 50 for each 204.8 msecs listening), reduce sensitivity
971  *   by *adding* 1 to all 4 of the table entries above, up to the max for
972  *   each entry.  Conversely, if false alarm rate is too low (less than 5
973  *   for each 204.8 msecs listening), *subtract* 1 from each entry to
974  *   increase sensitivity.
975  *
976  * For CCK sensitivity, keep track of the following:
977  *
978  *   1).  20-beacon history of maximum background noise, indicated by
979  *        (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the
980  *        3 receivers.  For any given beacon, the "silence reference" is
981  *        the maximum of last 60 samples (20 beacons * 3 receivers).
982  *
983  *   2).  10-beacon history of strongest signal level, as indicated
984  *        by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers,
985  *        i.e. the strength of the signal through the best receiver at the
986  *        moment.  These measurements are "upside down", with lower values
987  *        for stronger signals, so max energy will be *minimum* value.
988  *
989  *        Then for any given beacon, the driver must determine the *weakest*
990  *        of the strongest signals; this is the minimum level that needs to be
991  *        successfully detected, when using the best receiver at the moment.
992  *        "Max cck energy" is the maximum (higher value means lower energy!)
993  *        of the last 10 minima.  Once this is determined, driver must add
994  *        a little margin by adding "6" to it.
995  *
996  *   3).  Number of consecutive beacon periods with too few false alarms.
997  *        Reset this to 0 at the first beacon period that falls within the
998  *        "good" range (5 to 50 false alarms per 204.8 milliseconds rx).
999  *
1000  * Then, adjust the following CCK table entries in struct iwk_rx_sensitivity_cmd
1001  * (notice that the start points for CCK are at maximum sensitivity):
1002  *
1003  *                                             START  /  MIN  /  MAX
1004  *   HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX         125   /  125  /  200
1005  *   HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX     200   /  200  /  400
1006  *   HD_MIN_ENERGY_CCK_DET_INDEX                100   /    0  /  100
1007  *
1008  *   If actual rate of CCK false alarms (+ plcp_errors) is too high
1009  *   (greater than 50 for each 204.8 msecs listening), method for reducing
1010  *   sensitivity is:
1011  *
1012  *   1)  *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX,
1013  *       up to max 400.
1014  *
1015  *   2)  If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160,
1016  *       sensitivity has been reduced a significant amount; bring it up to
1017  *       a moderate 161.  Otherwise, *add* 3, up to max 200.
1018  *
1019  *   3)  a)  If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160,
1020  *       sensitivity has been reduced only a moderate or small amount;
1021  *       *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX,
1022  *       down to min 0.  Otherwise (if gain has been significantly reduced),
1023  *       don't change the HD_MIN_ENERGY_CCK_DET_INDEX value.
1024  *
1025  *       b)  Save a snapshot of the "silence reference".
1026  *
1027  *   If actual rate of CCK false alarms (+ plcp_errors) is too low
1028  *   (less than 5 for each 204.8 msecs listening), method for increasing
1029  *   sensitivity is used only if:
1030  *
1031  *   1a)  Previous beacon did not have too many false alarms
1032  *   1b)  AND difference between previous "silence reference" and current
1033  *        "silence reference" (prev - current) is 2 or more,
1034  *   OR 2)  100 or more consecutive beacon periods have had rate of
1035  *          less than 5 false alarms per 204.8 milliseconds rx time.
1036  *
1037  *   Method for increasing sensitivity:
1038  *
1039  *   1)  *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX,
1040  *       down to min 125.
1041  *
1042  *   2)  *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX,
1043  *       down to min 200.
1044  *
1045  *   3)  *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100.
1046  *
1047  *   If actual rate of CCK false alarms (+ plcp_errors) is within good range
1048  *   (between 5 and 50 for each 204.8 msecs listening):
1049  *
1050  *   1)  Save a snapshot of the silence reference.
1051  *
1052  *   2)  If previous beacon had too many CCK false alarms (+ plcp_errors),
1053  *       give some extra margin to energy threshold by *subtracting* 8
1054  *       from value in HD_MIN_ENERGY_CCK_DET_INDEX.
1055  *
1056  *   For all cases (too few, too many, good range), make sure that the CCK
1057  *   detection threshold (energy) is below the energy level for robust
1058  *   detection over the past 10 beacon periods, the "Max cck energy".
1059  *   Lower values mean higher energy; this means making sure that the value
1060  *   in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy".
1061  *
1062  * Driver should set the following entries to fixed values:
1063  *
1064  *   HD_MIN_ENERGY_OFDM_DET_INDEX               100
1065  *   HD_BARKER_CORR_TH_ADD_MIN_INDEX            190
1066  *   HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX        390
1067  *   HD_OFDM_ENERGY_TH_IN_INDEX                  62
1068  */
1069 
1070 #define	IWK_SENSITIVITY_CALIB_ALLOW_MSK  (1 << 0)
1071 #define	IWK_SENSITIVITY_OFDM_UPDATE_MSK  (1 << 1)
1072 #define	IWK_SENSITIVITY_CCK_UPDATE_MSK   (1 << 2)
1073 
1074 #define	MIN_ENERGY_CCK_DET_IDX			(0)
1075 #define	MIN_ENERGY_OFDM_DET_IDX			(1)
1076 #define	AUTO_CORR32_X1_TH_ADD_MIN_IDX		(2)
1077 #define	AUTO_CORR32_X1_TH_ADD_MIN_MRC_IDX	(3)
1078 #define	AUTO_CORR40_X4_TH_ADD_MIN_MRC_IDX	(4)
1079 #define	AUTO_CORR32_X4_TH_ADD_MIN_IDX		(5)
1080 #define	AUTO_CORR32_X4_TH_ADD_MIN_MRC_IDX	(6)
1081 #define	BARKER_CORR_TH_ADD_MIN_IDX		(7)
1082 #define	BARKER_CORR_TH_ADD_MIN_MRC_IDX		(8)
1083 #define	AUTO_CORR40_X4_TH_ADD_MIN_IDX		(9)
1084 #define	PTAM_ENERGY_TH_IDX			(10)
1085 
1086 #define	IWK_GOOD_RANGE_FALSE_ALARM	(0)
1087 #define	IWK_TOO_MANY_FALSE_ALARM	(1)
1088 #define	IWK_TOO_FEW_FALSE_ALARM		(2)
1089 
1090 #define	IWK_SENSITIVITY_CONTROL_DEFAULT_TABLE	(0)
1091 #define	IWK_SENSITIVITY_CONTROL_WORK_TABLE	(1)
1092 
1093 struct iwk_rx_sensitivity_cmd {
1094 	uint16_t  control;
1095 	uint16_t  table[11];
1096 };
1097 
1098 struct iwk_rx_sensitivity {
1099 	uint16_t  auto_corr_ofdm_x4;
1100 	uint16_t  auto_corr_mrc_ofdm_x4;
1101 	uint16_t  auto_corr_ofdm_x1;
1102 	uint16_t  auto_corr_mrc_ofdm_x1;
1103 
1104 	uint16_t  auto_corr_cck_x4;
1105 	uint16_t  auto_corr_mrc_cck_x4;
1106 	uint16_t  min_energy_det_cck;
1107 
1108 	uint16_t  flags;
1109 
1110 	uint32_t  last_bad_plcp_cnt_ofdm;
1111 	uint32_t  last_false_alarm_cnt_ofdm;
1112 	uint32_t  last_bad_plcp_cnt_cck;
1113 	uint32_t  last_false_alarm_cnt_cck;
1114 
1115 	uint32_t  cck_curr_state;
1116 	uint32_t  cck_prev_state;
1117 	uint32_t  cck_beacon_min[10];
1118 	uint32_t  cck_beacon_idx;
1119 	uint8_t   cck_noise_max[20];
1120 	uint32_t  cck_noise_ref;
1121 	uint32_t  cck_noise_idx;
1122 	int32_t   cck_noise_diff;
1123 	uint32_t  cck_no_false_alarm_num;
1124 };
1125 
1126 /* END Receiver sensitivity */
1127 
1128 #endif /* _IWK_CALIBRATION_H_ */
1129