phy.c (1846ac3dbec0894095520b2756b68c4fd81e3fbb) phy.c (c47faa364cfb249d5d7670fb7293a6f9acd8aa9e)
1/*
1/*
2 * PHY functions
3 *
4 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 */
22
2 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
5 * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21/***********************\
22* PHY related functions *
23\***********************/
24
23#include <linux/delay.h>
24#include <linux/slab.h>
25#include <asm/unaligned.h>
26
27#include "ath5k.h"
28#include "reg.h"
29#include "rfbuffer.h"
30#include "rfgain.h"
31#include "../regd.h"
32
33
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <asm/unaligned.h>
28
29#include "ath5k.h"
30#include "reg.h"
31#include "rfbuffer.h"
32#include "rfgain.h"
33#include "../regd.h"
34
35
36/**
37 * DOC: PHY related functions
38 *
39 * Here we handle the low-level functions related to baseband
40 * and analog frontend (RF) parts. This is by far the most complex
41 * part of the hw code so make sure you know what you are doing.
42 *
43 * Here is a list of what this is all about:
44 *
45 * - Channel setting/switching
46 *
47 * - Automatic Gain Control (AGC) calibration
48 *
49 * - Noise Floor calibration
50 *
51 * - I/Q imbalance calibration (QAM correction)
52 *
53 * - Calibration due to thermal changes (gain_F)
54 *
55 * - Spur noise mitigation
56 *
57 * - RF/PHY initialization for the various operating modes and bwmodes
58 *
59 * - Antenna control
60 *
61 * - TX power control per channel/rate/packet type
62 *
63 * Also have in mind we never got documentation for most of these
64 * functions, what we have comes mostly from Atheros's code, reverse
65 * engineering and patent docs/presentations etc.
66 */
67
68
34/******************\
35* Helper functions *
36\******************/
37
69/******************\
70* Helper functions *
71\******************/
72
38/*
39 * Get the PHY Chip revision
73/**
74 * ath5k_hw_radio_revision() - Get the PHY Chip revision
75 * @ah: The &struct ath5k_hw
76 * @band: One of enum ieee80211_band
77 *
78 * Returns the revision number of a 2GHz, 5GHz or single chip
79 * radio.
40 */
80 */
41u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band)
81u16
82ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band)
42{
43 unsigned int i;
44 u32 srev;
45 u16 ret;
46
47 /*
48 * Set the radio chip access register
49 */

--- 26 unchanged lines hidden (view full) ---

76 }
77
78 /* Reset to the 5GHz mode */
79 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
80
81 return ret;
82}
83
83{
84 unsigned int i;
85 u32 srev;
86 u16 ret;
87
88 /*
89 * Set the radio chip access register
90 */

--- 26 unchanged lines hidden (view full) ---

117 }
118
119 /* Reset to the 5GHz mode */
120 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
121
122 return ret;
123}
124
84/*
85 * Check if a channel is supported
125/**
126 * ath5k_channel_ok() - Check if a channel is supported by the hw
127 * @ah: The &struct ath5k_hw
128 * @channel: The &struct ieee80211_channel
129 *
130 * Note: We don't do any regulatory domain checks here, it's just
131 * a sanity check.
86 */
132 */
87bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel)
133bool
134ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel)
88{
89 u16 freq = channel->center_freq;
90
91 /* Check if the channel is in our supported range */
92 if (channel->band == IEEE80211_BAND_2GHZ) {
93 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
94 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
95 return true;
96 } else if (channel->band == IEEE80211_BAND_5GHZ)
97 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
98 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
99 return true;
100
101 return false;
102}
103
135{
136 u16 freq = channel->center_freq;
137
138 /* Check if the channel is in our supported range */
139 if (channel->band == IEEE80211_BAND_2GHZ) {
140 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
141 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
142 return true;
143 } else if (channel->band == IEEE80211_BAND_5GHZ)
144 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
145 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
146 return true;
147
148 return false;
149}
150
104bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
151/**
152 * ath5k_hw_chan_has_spur_noise() - Check if channel is sensitive to spur noise
153 * @ah: The &struct ath5k_hw
154 * @channel: The &struct ieee80211_channel
155 */
156bool
157ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
105 struct ieee80211_channel *channel)
106{
107 u8 refclk_freq;
108
109 if ((ah->ah_radio == AR5K_RF5112) ||
110 (ah->ah_radio == AR5K_RF5413) ||
111 (ah->ah_radio == AR5K_RF2413) ||
112 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))

--- 4 unchanged lines hidden (view full) ---

117 if ((channel->center_freq % refclk_freq != 0) &&
118 ((channel->center_freq % refclk_freq < 10) ||
119 (channel->center_freq % refclk_freq > 22)))
120 return true;
121 else
122 return false;
123}
124
158 struct ieee80211_channel *channel)
159{
160 u8 refclk_freq;
161
162 if ((ah->ah_radio == AR5K_RF5112) ||
163 (ah->ah_radio == AR5K_RF5413) ||
164 (ah->ah_radio == AR5K_RF2413) ||
165 (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))

--- 4 unchanged lines hidden (view full) ---

170 if ((channel->center_freq % refclk_freq != 0) &&
171 ((channel->center_freq % refclk_freq < 10) ||
172 (channel->center_freq % refclk_freq > 22)))
173 return true;
174 else
175 return false;
176}
177
125/*
126 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
178/**
179 * ath5k_hw_rfb_op() - Perform an operation on the given RF Buffer
180 * @ah: The &struct ath5k_hw
181 * @rf_regs: The struct ath5k_rf_reg
182 * @val: New value
183 * @reg_id: RF register ID
184 * @set: Indicate we need to swap data
185 *
186 * This is an internal function used to modify RF Banks before
187 * writing them to AR5K_RF_BUFFER. Check out rfbuffer.h for more
188 * infos.
127 */
189 */
128static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
129 const struct ath5k_rf_reg *rf_regs,
190static unsigned int
191ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs,
130 u32 val, u8 reg_id, bool set)
131{
132 const struct ath5k_rf_reg *rfreg = NULL;
133 u8 offset, bank, num_bits, col, position;
134 u16 entry;
135 u32 mask, data, last_bit, bits_shifted, first_bit;
136 u32 *rfb;
137 s32 bits_left;

--- 61 unchanged lines hidden (view full) ---

199 }
200
201 data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
202
203 return data;
204}
205
206/**
192 u32 val, u8 reg_id, bool set)
193{
194 const struct ath5k_rf_reg *rfreg = NULL;
195 u8 offset, bank, num_bits, col, position;
196 u16 entry;
197 u32 mask, data, last_bit, bits_shifted, first_bit;
198 u32 *rfb;
199 s32 bits_left;

--- 61 unchanged lines hidden (view full) ---

261 }
262
263 data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
264
265 return data;
266}
267
268/**
207 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
208 *
269 * ath5k_hw_write_ofdm_timings() - set OFDM timings on AR5212
209 * @ah: the &struct ath5k_hw
210 * @channel: the currently set channel upon reset
211 *
212 * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
213 * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init.
214 *
215 * Since delta slope is floating point we split it on its exponent and
216 * mantissa and provide these values on hw.
217 *
218 * For more infos i think this patent is related
270 * @ah: the &struct ath5k_hw
271 * @channel: the currently set channel upon reset
272 *
273 * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
274 * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init.
275 *
276 * Since delta slope is floating point we split it on its exponent and
277 * mantissa and provide these values on hw.
278 *
279 * For more infos i think this patent is related
219 * http://www.freepatentsonline.com/7184495.html
280 * "http://www.freepatentsonline.com/7184495.html"
220 */
281 */
221static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
222 struct ieee80211_channel *channel)
282static inline int
283ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
284 struct ieee80211_channel *channel)
223{
224 /* Get exponent and mantissa and set it */
225 u32 coef_scaled, coef_exp, coef_man,
226 ds_coef_exp, ds_coef_man, clock;
227
228 BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
229 (channel->hw_value == AR5K_MODE_11B));
230

--- 42 unchanged lines hidden (view full) ---

273 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
274 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
275 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
276 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
277
278 return 0;
279}
280
285{
286 /* Get exponent and mantissa and set it */
287 u32 coef_scaled, coef_exp, coef_man,
288 ds_coef_exp, ds_coef_man, clock;
289
290 BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
291 (channel->hw_value == AR5K_MODE_11B));
292

--- 42 unchanged lines hidden (view full) ---

335 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
336 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
337 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
338 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
339
340 return 0;
341}
342
343/**
344 * ath5k_hw_phy_disable() - Disable PHY
345 * @ah: The &struct ath5k_hw
346 */
281int ath5k_hw_phy_disable(struct ath5k_hw *ah)
282{
283 /*Just a try M.F.*/
284 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
285
286 return 0;
287}
288
347int ath5k_hw_phy_disable(struct ath5k_hw *ah)
348{
349 /*Just a try M.F.*/
350 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
351
352 return 0;
353}
354
289/*
290 * Wait for synth to settle
355/**
356 * ath5k_hw_wait_for_synth() - Wait for synth to settle
357 * @ah: The &struct ath5k_hw
358 * @channel: The &struct ieee80211_channel
291 */
359 */
292static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
360static void
361ath5k_hw_wait_for_synth(struct ath5k_hw *ah,
293 struct ieee80211_channel *channel)
294{
295 /*
296 * On 5211+ read activation -> rx delay
297 * and use it (100ns steps).
298 */
299 if (ah->ah_version != AR5K_AR5210) {
300 u32 delay;

--- 13 unchanged lines hidden (view full) ---

314 }
315}
316
317
318/**********************\
319* RF Gain optimization *
320\**********************/
321
362 struct ieee80211_channel *channel)
363{
364 /*
365 * On 5211+ read activation -> rx delay
366 * and use it (100ns steps).
367 */
368 if (ah->ah_version != AR5K_AR5210) {
369 u32 delay;

--- 13 unchanged lines hidden (view full) ---

383 }
384}
385
386
387/**********************\
388* RF Gain optimization *
389\**********************/
390
322/*
391/**
392 * DOC: RF Gain optimization
393 *
323 * This code is used to optimize RF gain on different environments
324 * (temperature mostly) based on feedback from a power detector.
325 *
326 * It's only used on RF5111 and RF5112, later RF chips seem to have
327 * auto adjustment on hw -notice they have a much smaller BANK 7 and
328 * no gain optimization ladder-.
329 *
330 * For more infos check out this patent doc
394 * This code is used to optimize RF gain on different environments
395 * (temperature mostly) based on feedback from a power detector.
396 *
397 * It's only used on RF5111 and RF5112, later RF chips seem to have
398 * auto adjustment on hw -notice they have a much smaller BANK 7 and
399 * no gain optimization ladder-.
400 *
401 * For more infos check out this patent doc
331 * http://www.freepatentsonline.com/7400691.html
402 * "http://www.freepatentsonline.com/7400691.html"
332 *
333 * This paper describes power drops as seen on the receiver due to
334 * probe packets
403 *
404 * This paper describes power drops as seen on the receiver due to
405 * probe packets
335 * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
336 * %20of%20Power%20Control.pdf
406 * "http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
407 * %20of%20Power%20Control.pdf"
337 *
338 * And this is the MadWiFi bug entry related to the above
408 *
409 * And this is the MadWiFi bug entry related to the above
339 * http://madwifi-project.org/ticket/1659
410 * "http://madwifi-project.org/ticket/1659"
340 * with various measurements and diagrams
341 */
342
411 * with various measurements and diagrams
412 */
413
343/* Initialize ah_gain during attach */
414/**
415 * ath5k_hw_rfgain_opt_init() - Initialize ah_gain during attach
416 * @ah: The &struct ath5k_hw
417 */
344int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
345{
346 /* Initialize the gain optimization values */
347 switch (ah->ah_radio) {
348 case AR5K_RF5111:
349 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
350 ah->ah_gain.g_low = 20;
351 ah->ah_gain.g_high = 35;

--- 7 unchanged lines hidden (view full) ---

359 break;
360 default:
361 return -EINVAL;
362 }
363
364 return 0;
365}
366
418int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
419{
420 /* Initialize the gain optimization values */
421 switch (ah->ah_radio) {
422 case AR5K_RF5111:
423 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
424 ah->ah_gain.g_low = 20;
425 ah->ah_gain.g_high = 35;

--- 7 unchanged lines hidden (view full) ---

433 break;
434 default:
435 return -EINVAL;
436 }
437
438 return 0;
439}
440
367/* Schedule a gain probe check on the next transmitted packet.
441/**
442 * ath5k_hw_request_rfgain_probe() - Request a PAPD probe packet
443 * @ah: The &struct ath5k_hw
444 *
445 * Schedules a gain probe check on the next transmitted packet.
368 * That means our next packet is going to be sent with lower
369 * tx power and a Peak to Average Power Detector (PAPD) will try
370 * to measure the gain.
371 *
372 * TODO: Force a tx packet (bypassing PCU arbitrator etc)
373 * just after we enable the probe so that we don't mess with
374 * standard traffic.
375 */
446 * That means our next packet is going to be sent with lower
447 * tx power and a Peak to Average Power Detector (PAPD) will try
448 * to measure the gain.
449 *
450 * TODO: Force a tx packet (bypassing PCU arbitrator etc)
451 * just after we enable the probe so that we don't mess with
452 * standard traffic.
453 */
376static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
454static void
455ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
377{
378
379 /* Skip if gain calibration is inactive or
380 * we already handle a probe request */
381 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
382 return;
383
384 /* Send the packet with 2dB below max power as
385 * patent doc suggest */
386 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
387 AR5K_PHY_PAPD_PROBE_TXPOWER) |
388 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
389
390 ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
391
392}
393
456{
457
458 /* Skip if gain calibration is inactive or
459 * we already handle a probe request */
460 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
461 return;
462
463 /* Send the packet with 2dB below max power as
464 * patent doc suggest */
465 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
466 AR5K_PHY_PAPD_PROBE_TXPOWER) |
467 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
468
469 ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
470
471}
472
394/* Calculate gain_F measurement correction
395 * based on the current step for RF5112 rev. 2 */
396static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
473/**
474 * ath5k_hw_rf_gainf_corr() - Calculate Gain_F measurement correction
475 * @ah: The &struct ath5k_hw
476 *
477 * Calculate Gain_F measurement correction
478 * based on the current step for RF5112 rev. 2
479 */
480static u32
481ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
397{
398 u32 mix, step;
399 u32 *rf;
400 const struct ath5k_gain_opt *go;
401 const struct ath5k_gain_opt_step *g_step;
402 const struct ath5k_rf_reg *rf_regs;
403
404 /* Only RF5112 Rev. 2 supports it */

--- 36 unchanged lines hidden (view full) ---

441 default:
442 ah->ah_gain.g_f_corr = 0;
443 break;
444 }
445
446 return ah->ah_gain.g_f_corr;
447}
448
482{
483 u32 mix, step;
484 u32 *rf;
485 const struct ath5k_gain_opt *go;
486 const struct ath5k_gain_opt_step *g_step;
487 const struct ath5k_rf_reg *rf_regs;
488
489 /* Only RF5112 Rev. 2 supports it */

--- 36 unchanged lines hidden (view full) ---

526 default:
527 ah->ah_gain.g_f_corr = 0;
528 break;
529 }
530
531 return ah->ah_gain.g_f_corr;
532}
533
449/* Check if current gain_F measurement is in the range of our
534/**
535 * ath5k_hw_rf_check_gainf_readback() - Validate Gain_F feedback from detector
536 * @ah: The &struct ath5k_hw
537 *
538 * Check if current gain_F measurement is in the range of our
450 * power detector windows. If we get a measurement outside range
451 * we know it's not accurate (detectors can't measure anything outside
539 * power detector windows. If we get a measurement outside range
540 * we know it's not accurate (detectors can't measure anything outside
452 * their detection window) so we must ignore it */
453static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
541 * their detection window) so we must ignore it.
542 *
543 * Returns true if readback was O.K. or false on failure
544 */
545static bool
546ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
454{
455 const struct ath5k_rf_reg *rf_regs;
456 u32 step, mix_ovr, level[4];
457 u32 *rf;
458
459 if (ah->ah_rf_banks == NULL)
460 return false;
461

--- 35 unchanged lines hidden (view full) ---

497 }
498
499 return (ah->ah_gain.g_current >= level[0] &&
500 ah->ah_gain.g_current <= level[1]) ||
501 (ah->ah_gain.g_current >= level[2] &&
502 ah->ah_gain.g_current <= level[3]);
503}
504
547{
548 const struct ath5k_rf_reg *rf_regs;
549 u32 step, mix_ovr, level[4];
550 u32 *rf;
551
552 if (ah->ah_rf_banks == NULL)
553 return false;
554

--- 35 unchanged lines hidden (view full) ---

590 }
591
592 return (ah->ah_gain.g_current >= level[0] &&
593 ah->ah_gain.g_current <= level[1]) ||
594 (ah->ah_gain.g_current >= level[2] &&
595 ah->ah_gain.g_current <= level[3]);
596}
597
505/* Perform gain_F adjustment by choosing the right set
506 * of parameters from RF gain optimization ladder */
507static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
598/**
599 * ath5k_hw_rf_gainf_adjust() - Perform Gain_F adjustment
600 * @ah: The &struct ath5k_hw
601 *
602 * Choose the right target gain based on current gain
603 * and RF gain optimization ladder
604 */
605static s8
606ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
508{
509 const struct ath5k_gain_opt *go;
510 const struct ath5k_gain_opt_step *g_step;
511 int ret = 0;
512
513 switch (ah->ah_radio) {
514 case AR5K_RF5111:
515 go = &rfgain_opt_5111;

--- 47 unchanged lines hidden (view full) ---

563 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
564 "ret %d, gain step %u, current gain %u, target gain %u\n",
565 ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
566 ah->ah_gain.g_target);
567
568 return ret;
569}
570
607{
608 const struct ath5k_gain_opt *go;
609 const struct ath5k_gain_opt_step *g_step;
610 int ret = 0;
611
612 switch (ah->ah_radio) {
613 case AR5K_RF5111:
614 go = &rfgain_opt_5111;

--- 47 unchanged lines hidden (view full) ---

662 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
663 "ret %d, gain step %u, current gain %u, target gain %u\n",
664 ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
665 ah->ah_gain.g_target);
666
667 return ret;
668}
669
571/* Main callback for thermal RF gain calibration engine
670/**
671 * ath5k_hw_gainf_calibrate() - Do a gain_F calibration
672 * @ah: The &struct ath5k_hw
673 *
674 * Main callback for thermal RF gain calibration engine
572 * Check for a new gain reading and schedule an adjustment
573 * if needed.
675 * Check for a new gain reading and schedule an adjustment
676 * if needed.
677 *
678 * Returns one of enum ath5k_rfgain codes
574 */
679 */
575enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
680enum ath5k_rfgain
681ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
576{
577 u32 data, type;
578 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
579
580 if (ah->ah_rf_banks == NULL ||
581 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
582 return AR5K_RFGAIN_INACTIVE;
583

--- 43 unchanged lines hidden (view full) ---

627 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
628 }
629 }
630
631done:
632 return ah->ah_gain.g_state;
633}
634
682{
683 u32 data, type;
684 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
685
686 if (ah->ah_rf_banks == NULL ||
687 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
688 return AR5K_RFGAIN_INACTIVE;
689

--- 43 unchanged lines hidden (view full) ---

733 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
734 }
735 }
736
737done:
738 return ah->ah_gain.g_state;
739}
740
635/* Write initial RF gain table to set the RF sensitivity
636 * this one works on all RF chips and has nothing to do
637 * with gain_F calibration */
638static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band)
741/**
742 * ath5k_hw_rfgain_init() - Write initial RF gain settings to hw
743 * @ah: The &struct ath5k_hw
744 * @band: One of enum ieee80211_band
745 *
746 * Write initial RF gain table to set the RF sensitivity.
747 *
748 * NOTE: This one works on all RF chips and has nothing to do
749 * with Gain_F calibration
750 */
751static int
752ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band)
639{
640 const struct ath5k_ini_rfgain *ath5k_rfg;
641 unsigned int i, size, index;
642
643 switch (ah->ah_radio) {
644 case AR5K_RF5111:
645 ath5k_rfg = rfgain_5111;
646 size = ARRAY_SIZE(rfgain_5111);

--- 30 unchanged lines hidden (view full) ---

677 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
678 (u32)ath5k_rfg[i].rfg_register);
679 }
680
681 return 0;
682}
683
684
753{
754 const struct ath5k_ini_rfgain *ath5k_rfg;
755 unsigned int i, size, index;
756
757 switch (ah->ah_radio) {
758 case AR5K_RF5111:
759 ath5k_rfg = rfgain_5111;
760 size = ARRAY_SIZE(rfgain_5111);

--- 30 unchanged lines hidden (view full) ---

791 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
792 (u32)ath5k_rfg[i].rfg_register);
793 }
794
795 return 0;
796}
797
798
685
686/********************\
687* RF Registers setup *
688\********************/
689
799/********************\
800* RF Registers setup *
801\********************/
802
690/*
691 * Setup RF registers by writing RF buffer on hw
803/**
804 * ath5k_hw_rfregs_init() - Initialize RF register settings
805 * @ah: The &struct ath5k_hw
806 * @channel: The &struct ieee80211_channel
807 * @mode: One of enum ath5k_driver_mode
808 *
809 * Setup RF registers by writing RF buffer on hw. For
810 * more infos on this, check out rfbuffer.h
692 */
811 */
693static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
694 struct ieee80211_channel *channel, unsigned int mode)
812static int
813ath5k_hw_rfregs_init(struct ath5k_hw *ah,
814 struct ieee80211_channel *channel,
815 unsigned int mode)
695{
696 const struct ath5k_rf_reg *rf_regs;
697 const struct ath5k_ini_rfbuffer *ini_rfb;
698 const struct ath5k_gain_opt *go = NULL;
699 const struct ath5k_gain_opt_step *g_step;
700 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
701 u8 ee_mode = 0;
702 u32 *rfb;

--- 341 unchanged lines hidden (view full) ---

1044 return 0;
1045}
1046
1047
1048/**************************\
1049 PHY/RF channel functions
1050\**************************/
1051
816{
817 const struct ath5k_rf_reg *rf_regs;
818 const struct ath5k_ini_rfbuffer *ini_rfb;
819 const struct ath5k_gain_opt *go = NULL;
820 const struct ath5k_gain_opt_step *g_step;
821 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
822 u8 ee_mode = 0;
823 u32 *rfb;

--- 341 unchanged lines hidden (view full) ---

1165 return 0;
1166}
1167
1168
1169/**************************\
1170 PHY/RF channel functions
1171\**************************/
1172
1052/*
1053 * Conversion needed for RF5110
1173/**
1174 * ath5k_hw_rf5110_chan2athchan() - Convert channel freq on RF5110
1175 * @channel: The &struct ieee80211_channel
1176 *
1177 * Map channel frequency to IEEE channel number and convert it
1178 * to an internal channel value used by the RF5110 chipset.
1054 */
1179 */
1055static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
1180static u32
1181ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
1056{
1057 u32 athchan;
1058
1182{
1183 u32 athchan;
1184
1059 /*
1060 * Convert IEEE channel/MHz to an internal channel value used
1061 * by the AR5210 chipset. This has not been verified with
1062 * newer chipsets like the AR5212A who have a completely
1063 * different RF/PHY part.
1064 */
1065 athchan = (ath5k_hw_bitswap(
1066 (ieee80211_frequency_to_channel(
1067 channel->center_freq) - 24) / 2, 5)
1068 << 1) | (1 << 6) | 0x1;
1069 return athchan;
1070}
1071
1185 athchan = (ath5k_hw_bitswap(
1186 (ieee80211_frequency_to_channel(
1187 channel->center_freq) - 24) / 2, 5)
1188 << 1) | (1 << 6) | 0x1;
1189 return athchan;
1190}
1191
1072/*
1073 * Set channel on RF5110
1192/**
1193 * ath5k_hw_rf5110_channel() - Set channel frequency on RF5110
1194 * @ah: The &struct ath5k_hw
1195 * @channel: The &struct ieee80211_channel
1074 */
1196 */
1075static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
1197static int
1198ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
1076 struct ieee80211_channel *channel)
1077{
1078 u32 data;
1079
1080 /*
1081 * Set the channel and wait
1082 */
1083 data = ath5k_hw_rf5110_chan2athchan(channel);
1084 ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
1085 ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
1086 usleep_range(1000, 1500);
1087
1088 return 0;
1089}
1090
1199 struct ieee80211_channel *channel)
1200{
1201 u32 data;
1202
1203 /*
1204 * Set the channel and wait
1205 */
1206 data = ath5k_hw_rf5110_chan2athchan(channel);
1207 ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
1208 ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
1209 usleep_range(1000, 1500);
1210
1211 return 0;
1212}
1213
1091/*
1092 * Conversion needed for 5111
1214/**
1215 * ath5k_hw_rf5111_chan2athchan() - Handle 2GHz channels on RF5111/2111
1216 * @ieee: IEEE channel number
1217 * @athchan: The &struct ath5k_athchan_2ghz
1218 *
1219 * In order to enable the RF2111 frequency converter on RF5111/2111 setups
1220 * we need to add some offsets and extra flags to the data values we pass
1221 * on to the PHY. So for every 2GHz channel this function gets called
1222 * to do the conversion.
1093 */
1223 */
1094static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
1224static int
1225ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
1095 struct ath5k_athchan_2ghz *athchan)
1096{
1097 int channel;
1098
1099 /* Cast this value to catch negative channel numbers (>= -19) */
1100 channel = (int)ieee;
1101
1102 /*

--- 9 unchanged lines hidden (view full) ---

1112 athchan->a2_athchan = ((channel - 14) * 4) + 132;
1113 athchan->a2_flags = 0x46;
1114 } else
1115 return -EINVAL;
1116
1117 return 0;
1118}
1119
1226 struct ath5k_athchan_2ghz *athchan)
1227{
1228 int channel;
1229
1230 /* Cast this value to catch negative channel numbers (>= -19) */
1231 channel = (int)ieee;
1232
1233 /*

--- 9 unchanged lines hidden (view full) ---

1243 athchan->a2_athchan = ((channel - 14) * 4) + 132;
1244 athchan->a2_flags = 0x46;
1245 } else
1246 return -EINVAL;
1247
1248 return 0;
1249}
1250
1120/*
1121 * Set channel on 5111
1251/**
1252 * ath5k_hw_rf5111_channel() - Set channel frequency on RF5111/2111
1253 * @ah: The &struct ath5k_hw
1254 * @channel: The &struct ieee80211_channel
1122 */
1255 */
1123static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
1256static int
1257ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
1124 struct ieee80211_channel *channel)
1125{
1126 struct ath5k_athchan_2ghz ath5k_channel_2ghz;
1127 unsigned int ath5k_channel =
1128 ieee80211_frequency_to_channel(channel->center_freq);
1129 u32 data0, data1, clock;
1130 int ret;
1131

--- 28 unchanged lines hidden (view full) ---

1160 ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
1161 AR5K_RF_BUFFER);
1162 ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
1163 AR5K_RF_BUFFER_CONTROL_3);
1164
1165 return 0;
1166}
1167
1258 struct ieee80211_channel *channel)
1259{
1260 struct ath5k_athchan_2ghz ath5k_channel_2ghz;
1261 unsigned int ath5k_channel =
1262 ieee80211_frequency_to_channel(channel->center_freq);
1263 u32 data0, data1, clock;
1264 int ret;
1265

--- 28 unchanged lines hidden (view full) ---

1294 ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
1295 AR5K_RF_BUFFER);
1296 ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
1297 AR5K_RF_BUFFER_CONTROL_3);
1298
1299 return 0;
1300}
1301
1168/*
1169 * Set channel on 5112 and newer
1302/**
1303 * ath5k_hw_rf5112_channel() - Set channel frequency on 5112 and newer
1304 * @ah: The &struct ath5k_hw
1305 * @channel: The &struct ieee80211_channel
1306 *
1307 * On RF5112/2112 and newer we don't need to do any conversion.
1308 * We pass the frequency value after a few modifications to the
1309 * chip directly.
1310 *
1311 * NOTE: Make sure channel frequency given is within our range or else
1312 * we might damage the chip ! Use ath5k_channel_ok before calling this one.
1170 */
1313 */
1171static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
1314static int
1315ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
1172 struct ieee80211_channel *channel)
1173{
1174 u32 data, data0, data1, data2;
1175 u16 c;
1176
1177 data = data0 = data1 = data2 = 0;
1178 c = channel->center_freq;
1179
1316 struct ieee80211_channel *channel)
1317{
1318 u32 data, data0, data1, data2;
1319 u16 c;
1320
1321 data = data0 = data1 = data2 = 0;
1322 c = channel->center_freq;
1323
1324 /* My guess based on code:
1325 * 2GHz RF has 2 synth modes, one with a Local Oscillator
1326 * at 2224Hz and one with a LO at 2192Hz. IF is 1520Hz
1327 * (3040/2). data0 is used to set the PLL divider and data1
1328 * selects synth mode. */
1180 if (c < 4800) {
1329 if (c < 4800) {
1330 /* Channel 14 and all frequencies with 2Hz spacing
1331 * below/above (non-standard channels) */
1181 if (!((c - 2224) % 5)) {
1332 if (!((c - 2224) % 5)) {
1333 /* Same as (c - 2224) / 5 */
1182 data0 = ((2 * (c - 704)) - 3040) / 10;
1183 data1 = 1;
1334 data0 = ((2 * (c - 704)) - 3040) / 10;
1335 data1 = 1;
1336 /* Channel 1 and all frequencies with 5Hz spacing
1337 * below/above (standard channels without channel 14) */
1184 } else if (!((c - 2192) % 5)) {
1338 } else if (!((c - 2192) % 5)) {
1339 /* Same as (c - 2192) / 5 */
1185 data0 = ((2 * (c - 672)) - 3040) / 10;
1186 data1 = 0;
1187 } else
1188 return -EINVAL;
1189
1190 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
1340 data0 = ((2 * (c - 672)) - 3040) / 10;
1341 data1 = 0;
1342 } else
1343 return -EINVAL;
1344
1345 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
1346 /* This is more complex, we have a single synthesizer with
1347 * 4 reference clock settings (?) based on frequency spacing
1348 * and set using data2. LO is at 4800Hz and data0 is again used
1349 * to set some divider.
1350 *
1351 * NOTE: There is an old atheros presentation at Stanford
1352 * that mentions a method called dual direct conversion
1353 * with 1GHz sliding IF for RF5110. Maybe that's what we
1354 * have here, or an updated version. */
1191 } else if ((c % 5) != 2 || c > 5435) {
1192 if (!(c % 20) && c >= 5120) {
1193 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1194 data2 = ath5k_hw_bitswap(3, 2);
1195 } else if (!(c % 10)) {
1196 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1197 data2 = ath5k_hw_bitswap(2, 2);
1198 } else if (!(c % 5)) {

--- 9 unchanged lines hidden (view full) ---

1208 data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
1209
1210 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1211 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1212
1213 return 0;
1214}
1215
1355 } else if ((c % 5) != 2 || c > 5435) {
1356 if (!(c % 20) && c >= 5120) {
1357 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1358 data2 = ath5k_hw_bitswap(3, 2);
1359 } else if (!(c % 10)) {
1360 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1361 data2 = ath5k_hw_bitswap(2, 2);
1362 } else if (!(c % 5)) {

--- 9 unchanged lines hidden (view full) ---

1372 data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
1373
1374 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1375 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1376
1377 return 0;
1378}
1379
1216/*
1217 * Set the channel on the RF2425
1380/**
1381 * ath5k_hw_rf2425_channel() - Set channel frequency on RF2425
1382 * @ah: The &struct ath5k_hw
1383 * @channel: The &struct ieee80211_channel
1384 *
1385 * AR2425/2417 have a different 2GHz RF so code changes
1386 * a little bit from RF5112.
1218 */
1387 */
1219static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
1388static int
1389ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
1220 struct ieee80211_channel *channel)
1221{
1222 u32 data, data0, data2;
1223 u16 c;
1224
1225 data = data0 = data2 = 0;
1226 c = channel->center_freq;
1227

--- 19 unchanged lines hidden (view full) ---

1247 data = (data0 << 4) | data2 << 2 | 0x1001;
1248
1249 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1250 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1251
1252 return 0;
1253}
1254
1390 struct ieee80211_channel *channel)
1391{
1392 u32 data, data0, data2;
1393 u16 c;
1394
1395 data = data0 = data2 = 0;
1396 c = channel->center_freq;
1397

--- 19 unchanged lines hidden (view full) ---

1417 data = (data0 << 4) | data2 << 2 | 0x1001;
1418
1419 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1420 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1421
1422 return 0;
1423}
1424
1255/*
1256 * Set a channel on the radio chip
1425/**
1426 * ath5k_hw_channel() - Set a channel on the radio chip
1427 * @ah: The &struct ath5k_hw
1428 * @channel: The &struct ieee80211_channel
1429 *
1430 * This is the main function called to set a channel on the
1431 * radio chip based on the radio chip version.
1257 */
1432 */
1258static int ath5k_hw_channel(struct ath5k_hw *ah,
1433static int
1434ath5k_hw_channel(struct ath5k_hw *ah,
1259 struct ieee80211_channel *channel)
1260{
1261 int ret;
1262 /*
1263 * Check bounds supported by the PHY (we don't care about regulatory
1264 * restrictions at this point).
1265 */
1266 if (!ath5k_channel_ok(ah, channel)) {

--- 35 unchanged lines hidden (view full) ---

1302 AR5K_PHY_CCKTXCTL_WORLD);
1303 }
1304
1305 ah->ah_current_channel = channel;
1306
1307 return 0;
1308}
1309
1435 struct ieee80211_channel *channel)
1436{
1437 int ret;
1438 /*
1439 * Check bounds supported by the PHY (we don't care about regulatory
1440 * restrictions at this point).
1441 */
1442 if (!ath5k_channel_ok(ah, channel)) {

--- 35 unchanged lines hidden (view full) ---

1478 AR5K_PHY_CCKTXCTL_WORLD);
1479 }
1480
1481 ah->ah_current_channel = channel;
1482
1483 return 0;
1484}
1485
1486
1310/*****************\
1311 PHY calibration
1312\*****************/
1313
1487/*****************\
1488 PHY calibration
1489\*****************/
1490
1314static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1491/**
1492 * DOC: PHY Calibration routines
1493 *
1494 * Noise floor calibration: When we tell the hardware to
1495 * perform a noise floor calibration by setting the
1496 * AR5K_PHY_AGCCTL_NF bit on AR5K_PHY_AGCCTL, it will periodically
1497 * sample-and-hold the minimum noise level seen at the antennas.
1498 * This value is then stored in a ring buffer of recently measured
1499 * noise floor values so we have a moving window of the last few
1500 * samples. The median of the values in the history is then loaded
1501 * into the hardware for its own use for RSSI and CCA measurements.
1502 * This type of calibration doesn't interfere with traffic.
1503 *
1504 * AGC calibration: When we tell the hardware to perform
1505 * an AGC (Automatic Gain Control) calibration by setting the
1506 * AR5K_PHY_AGCCTL_CAL, hw disconnects the antennas and does
1507 * a calibration on the DC offsets of ADCs. During this period
1508 * rx/tx gets disabled so we have to deal with it on the driver
1509 * part.
1510 *
1511 * I/Q calibration: When we tell the hardware to perform
1512 * an I/Q calibration, it tries to correct I/Q imbalance and
1513 * fix QAM constellation by sampling data from rxed frames.
1514 * It doesn't interfere with traffic.
1515 *
1516 * For more infos on AGC and I/Q calibration check out patent doc
1517 * #03/094463.
1518 */
1519
1520/**
1521 * ath5k_hw_read_measured_noise_floor() - Read measured NF from hw
1522 * @ah: The &struct ath5k_hw
1523 */
1524static s32
1525ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah)
1315{
1316 s32 val;
1317
1318 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1319 return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
1320}
1321
1526{
1527 s32 val;
1528
1529 val = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1530 return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8);
1531}
1532
1322void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
1533/**
1534 * ath5k_hw_init_nfcal_hist() - Initialize NF calibration history buffer
1535 * @ah: The &struct ath5k_hw
1536 */
1537void
1538ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah)
1323{
1324 int i;
1325
1326 ah->ah_nfcal_hist.index = 0;
1327 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++)
1328 ah->ah_nfcal_hist.nfval[i] = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1329}
1330
1539{
1540 int i;
1541
1542 ah->ah_nfcal_hist.index = 0;
1543 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++)
1544 ah->ah_nfcal_hist.nfval[i] = AR5K_TUNE_CCA_MAX_GOOD_VALUE;
1545}
1546
1547/**
1548 * ath5k_hw_update_nfcal_hist() - Update NF calibration history buffer
1549 * @ah: The &struct ath5k_hw
1550 * @noise_floor: The NF we got from hw
1551 */
1331static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
1332{
1333 struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
1334 hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX - 1);
1335 hist->nfval[hist->index] = noise_floor;
1336}
1337
1552static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor)
1553{
1554 struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist;
1555 hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX - 1);
1556 hist->nfval[hist->index] = noise_floor;
1557}
1558
1338static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1559/**
1560 * ath5k_hw_get_median_noise_floor() - Get median NF from history buffer
1561 * @ah: The &struct ath5k_hw
1562 */
1563static s16
1564ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah)
1339{
1340 s16 sort[ATH5K_NF_CAL_HIST_MAX];
1341 s16 tmp;
1342 int i, j;
1343
1344 memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
1345 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
1346 for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {

--- 6 unchanged lines hidden (view full) ---

1353 }
1354 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
1355 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1356 "cal %d:%d\n", i, sort[i]);
1357 }
1358 return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2];
1359}
1360
1565{
1566 s16 sort[ATH5K_NF_CAL_HIST_MAX];
1567 s16 tmp;
1568 int i, j;
1569
1570 memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort));
1571 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) {
1572 for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) {

--- 6 unchanged lines hidden (view full) ---

1579 }
1580 for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) {
1581 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1582 "cal %d:%d\n", i, sort[i]);
1583 }
1584 return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2];
1585}
1586
1361/*
1362 * When we tell the hardware to perform a noise floor calibration
1363 * by setting the AR5K_PHY_AGCCTL_NF bit, it will periodically
1364 * sample-and-hold the minimum noise level seen at the antennas.
1365 * This value is then stored in a ring buffer of recently measured
1366 * noise floor values so we have a moving window of the last few
1367 * samples.
1587/**
1588 * ath5k_hw_update_noise_floor() - Update NF on hardware
1589 * @ah: The &struct ath5k_hw
1368 *
1590 *
1369 * The median of the values in the history is then loaded into the
1370 * hardware for its own use for RSSI and CCA measurements.
1591 * This is the main function we call to perform a NF calibration,
1592 * it reads NF from hardware, calculates the median and updates
1593 * NF on hw.
1371 */
1594 */
1372void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1595void
1596ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
1373{
1374 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1375 u32 val;
1376 s16 nf, threshold;
1377 u8 ee_mode;
1378
1379 /* keep last value if calibration hasn't completed */
1380 if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {

--- 50 unchanged lines hidden (view full) ---

1431 ah->ah_noise_floor = nf;
1432
1433 ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
1434
1435 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1436 "noise floor calibrated: %d\n", nf);
1437}
1438
1597{
1598 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1599 u32 val;
1600 s16 nf, threshold;
1601 u8 ee_mode;
1602
1603 /* keep last value if calibration hasn't completed */
1604 if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) {

--- 50 unchanged lines hidden (view full) ---

1655 ah->ah_noise_floor = nf;
1656
1657 ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF;
1658
1659 ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE,
1660 "noise floor calibrated: %d\n", nf);
1661}
1662
1439/*
1440 * Perform a PHY calibration on RF5110
1441 * -Fix BPSK/QAM Constellation (I/Q correction)
1663/**
1664 * ath5k_hw_rf5110_calibrate() - Perform a PHY calibration on RF5110
1665 * @ah: The &struct ath5k_hw
1666 * @channel: The &struct ieee80211_channel
1667 *
1668 * Do a complete PHY calibration (AGC + NF + I/Q) on RF5110
1442 */
1669 */
1443static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1670static int
1671ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1444 struct ieee80211_channel *channel)
1445{
1446 u32 phy_sig, phy_agc, phy_sat, beacon;
1447 int ret;
1448
1449 /*
1450 * Disable beacons and RX/TX queues, wait
1451 */

--- 78 unchanged lines hidden (view full) ---

1530 */
1531 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
1532 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1533 ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
1534
1535 return 0;
1536}
1537
1672 struct ieee80211_channel *channel)
1673{
1674 u32 phy_sig, phy_agc, phy_sat, beacon;
1675 int ret;
1676
1677 /*
1678 * Disable beacons and RX/TX queues, wait
1679 */

--- 78 unchanged lines hidden (view full) ---

1758 */
1759 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
1760 AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
1761 ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
1762
1763 return 0;
1764}
1765
1538/*
1539 * Perform I/Q calibration on RF5111/5112 and newer chips
1766/**
1767 * ath5k_hw_rf511x_iq_calibrate() - Perform I/Q calibration on RF5111 and newer
1768 * @ah: The &struct ath5k_hw
1540 */
1541static int
1542ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1543{
1544 u32 i_pwr, q_pwr;
1545 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1546 int i;
1547

--- 57 unchanged lines hidden (view full) ---

1605 * the same values again and again */
1606 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1607 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1608 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
1609
1610 return 0;
1611}
1612
1769 */
1770static int
1771ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah)
1772{
1773 u32 i_pwr, q_pwr;
1774 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1775 int i;
1776

--- 57 unchanged lines hidden (view full) ---

1834 * the same values again and again */
1835 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
1836 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
1837 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
1838
1839 return 0;
1840}
1841
1613/*
1614 * Perform a PHY calibration
1842/**
1843 * ath5k_hw_phy_calibrate() - Perform a PHY calibration
1844 * @ah: The &struct ath5k_hw
1845 * @channel: The &struct ieee80211_channel
1846 *
1847 * The main function we call from above to perform
1848 * a short or full PHY calibration based on RF chip
1849 * and current channel
1615 */
1850 */
1616int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1851int
1852ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1617 struct ieee80211_channel *channel)
1618{
1619 int ret;
1620
1621 if (ah->ah_radio == AR5K_RF5110)
1622 return ath5k_hw_rf5110_calibrate(ah, channel);
1623
1624 ret = ath5k_hw_rf511x_iq_calibrate(ah);

--- 38 unchanged lines hidden (view full) ---

1663 return ret;
1664}
1665
1666
1667/***************************\
1668* Spur mitigation functions *
1669\***************************/
1670
1853 struct ieee80211_channel *channel)
1854{
1855 int ret;
1856
1857 if (ah->ah_radio == AR5K_RF5110)
1858 return ath5k_hw_rf5110_calibrate(ah, channel);
1859
1860 ret = ath5k_hw_rf511x_iq_calibrate(ah);

--- 38 unchanged lines hidden (view full) ---

1899 return ret;
1900}
1901
1902
1903/***************************\
1904* Spur mitigation functions *
1905\***************************/
1906
1907/**
1908 * ath5k_hw_set_spur_mitigation_filter() - Configure SPUR filter
1909 * @ah: The &struct ath5k_hw
1910 * @channel: The &struct ieee80211_channel
1911 *
1912 * This function gets called during PHY initialization to
1913 * configure the spur filter for the given channel. Spur is noise
1914 * generated due to "reflection" effects, for more information on this
1915 * method check out patent US7643810
1916 */
1671static void
1672ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1673 struct ieee80211_channel *channel)
1674{
1675 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1676 u32 mag_mask[4] = {0, 0, 0, 0};
1677 u32 pilot_mask[2] = {0, 0};
1678 /* Note: fbin values are scaled up by 2 */

--- 223 unchanged lines hidden (view full) ---

1902 }
1903}
1904
1905
1906/*****************\
1907* Antenna control *
1908\*****************/
1909
1917static void
1918ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
1919 struct ieee80211_channel *channel)
1920{
1921 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1922 u32 mag_mask[4] = {0, 0, 0, 0};
1923 u32 pilot_mask[2] = {0, 0};
1924 /* Note: fbin values are scaled up by 2 */

--- 223 unchanged lines hidden (view full) ---

2148 }
2149}
2150
2151
2152/*****************\
2153* Antenna control *
2154\*****************/
2155
1910static void /*TODO:Boundary check*/
2156/**
2157 * DOC: Antenna control
2158 *
2159 * Hw supports up to 14 antennas ! I haven't found any card that implements
2160 * that. The maximum number of antennas I've seen is up to 4 (2 for 2GHz and 2
2161 * for 5GHz). Antenna 1 (MAIN) should be omnidirectional, 2 (AUX)
2162 * omnidirectional or sectorial and antennas 3-14 sectorial (or directional).
2163 *
2164 * We can have a single antenna for RX and multiple antennas for TX.
2165 * RX antenna is our "default" antenna (usually antenna 1) set on
2166 * DEFAULT_ANTENNA register and TX antenna is set on each TX control descriptor
2167 * (0 for automatic selection, 1 - 14 antenna number).
2168 *
2169 * We can let hw do all the work doing fast antenna diversity for both
2170 * tx and rx or we can do things manually. Here are the options we have
2171 * (all are bits of STA_ID1 register):
2172 *
2173 * AR5K_STA_ID1_DEFAULT_ANTENNA -> When 0 is set as the TX antenna on TX
2174 * control descriptor, use the default antenna to transmit or else use the last
2175 * antenna on which we received an ACK.
2176 *
2177 * AR5K_STA_ID1_DESC_ANTENNA -> Update default antenna after each TX frame to
2178 * the antenna on which we got the ACK for that frame.
2179 *
2180 * AR5K_STA_ID1_RTS_DEF_ANTENNA -> Use default antenna for RTS or else use the
2181 * one on the TX descriptor.
2182 *
2183 * AR5K_STA_ID1_SELFGEN_DEF_ANT -> Use default antenna for self generated frames
2184 * (ACKs etc), or else use current antenna (the one we just used for TX).
2185 *
2186 * Using the above we support the following scenarios:
2187 *
2188 * AR5K_ANTMODE_DEFAULT -> Hw handles antenna diversity etc automatically
2189 *
2190 * AR5K_ANTMODE_FIXED_A -> Only antenna A (MAIN) is present
2191 *
2192 * AR5K_ANTMODE_FIXED_B -> Only antenna B (AUX) is present
2193 *
2194 * AR5K_ANTMODE_SINGLE_AP -> Sta locked on a single ap
2195 *
2196 * AR5K_ANTMODE_SECTOR_AP -> AP with tx antenna set on tx desc
2197 *
2198 * AR5K_ANTMODE_SECTOR_STA -> STA with tx antenna set on tx desc
2199 *
2200 * AR5K_ANTMODE_DEBUG Debug mode -A -> Rx, B-> Tx-
2201 *
2202 * Also note that when setting antenna to F on tx descriptor card inverts
2203 * current tx antenna.
2204 */
2205
2206/**
2207 * ath5k_hw_set_def_antenna() - Set default rx antenna on AR5211/5212 and newer
2208 * @ah: The &struct ath5k_hw
2209 * @ant: Antenna number
2210 */
2211static void
1911ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
1912{
1913 if (ah->ah_version != AR5K_AR5210)
1914 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
1915}
1916
2212ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
2213{
2214 if (ah->ah_version != AR5K_AR5210)
2215 ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
2216}
2217
1917/*
1918 * Enable/disable fast rx antenna diversity
2218/**
2219 * ath5k_hw_set_fast_div() - Enable/disable fast rx antenna diversity
2220 * @ah: The &struct ath5k_hw
2221 * @ee_mode: One of enum ath5k_driver_mode
2222 * @enable: True to enable, false to disable
1919 */
1920static void
1921ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
1922{
1923 switch (ee_mode) {
1924 case AR5K_EEPROM_MODE_11G:
1925 /* XXX: This is set to
1926 * disabled on initvals !!! */

--- 23 unchanged lines hidden (view full) ---

1950 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
1951 AR5K_PHY_RESTART_DIV_GC, 0);
1952
1953 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
1954 AR5K_PHY_FAST_ANT_DIV_EN);
1955 }
1956}
1957
2223 */
2224static void
2225ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
2226{
2227 switch (ee_mode) {
2228 case AR5K_EEPROM_MODE_11G:
2229 /* XXX: This is set to
2230 * disabled on initvals !!! */

--- 23 unchanged lines hidden (view full) ---

2254 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
2255 AR5K_PHY_RESTART_DIV_GC, 0);
2256
2257 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
2258 AR5K_PHY_FAST_ANT_DIV_EN);
2259 }
2260}
2261
2262/**
2263 * ath5k_hw_set_antenna_switch() - Set up antenna switch table
2264 * @ah: The &struct ath5k_hw
2265 * @ee_mode: One of enum ath5k_driver_mode
2266 *
2267 * Switch table comes from EEPROM and includes information on controlling
2268 * the 2 antenna RX attenuators
2269 */
1958void
1959ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode)
1960{
1961 u8 ant0, ant1;
1962
1963 /*
1964 * In case a fixed antenna was set as default
1965 * use the same switch table twice.

--- 15 unchanged lines hidden (view full) ---

1981
1982 /* Set antenna switch tables */
1983 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0],
1984 AR5K_PHY_ANT_SWITCH_TABLE_0);
1985 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1],
1986 AR5K_PHY_ANT_SWITCH_TABLE_1);
1987}
1988
2270void
2271ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode)
2272{
2273 u8 ant0, ant1;
2274
2275 /*
2276 * In case a fixed antenna was set as default
2277 * use the same switch table twice.

--- 15 unchanged lines hidden (view full) ---

2293
2294 /* Set antenna switch tables */
2295 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0],
2296 AR5K_PHY_ANT_SWITCH_TABLE_0);
2297 ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1],
2298 AR5K_PHY_ANT_SWITCH_TABLE_1);
2299}
2300
1989/*
1990 * Set antenna operating mode
2301/**
2302 * ath5k_hw_set_antenna_mode() - Set antenna operating mode
2303 * @ah: The &struct ath5k_hw
2304 * @ant_mode: One of enum ath5k_ant_mode
1991 */
1992void
1993ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
1994{
1995 struct ieee80211_channel *channel = ah->ah_current_channel;
1996 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
1997 bool use_def_for_sg;
1998 int ee_mode;

--- 106 unchanged lines hidden (view full) ---

2105/****************\
2106* TX power setup *
2107\****************/
2108
2109/*
2110 * Helper functions
2111 */
2112
2305 */
2306void
2307ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
2308{
2309 struct ieee80211_channel *channel = ah->ah_current_channel;
2310 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
2311 bool use_def_for_sg;
2312 int ee_mode;

--- 106 unchanged lines hidden (view full) ---

2419/****************\
2420* TX power setup *
2421\****************/
2422
2423/*
2424 * Helper functions
2425 */
2426
2113/*
2114 * Do linear interpolation between two given (x, y) points
2427/**
2428 * ath5k_get_interpolated_value() - Get interpolated Y val between two points
2429 * @target: X value of the middle point
2430 * @x_left: X value of the left point
2431 * @x_right: X value of the right point
2432 * @y_left: Y value of the left point
2433 * @y_right: Y value of the right point
2115 */
2116static s16
2117ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
2118 s16 y_left, s16 y_right)
2119{
2120 s16 ratio, result;
2121
2122 /* Avoid divide by zero and skip interpolation

--- 10 unchanged lines hidden (view full) ---

2133 ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left));
2134
2135 /* Now scale down to be in range */
2136 result = y_left + (ratio * (target - x_left) / 100);
2137
2138 return result;
2139}
2140
2434 */
2435static s16
2436ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
2437 s16 y_left, s16 y_right)
2438{
2439 s16 ratio, result;
2440
2441 /* Avoid divide by zero and skip interpolation

--- 10 unchanged lines hidden (view full) ---

2452 ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left));
2453
2454 /* Now scale down to be in range */
2455 result = y_left + (ratio * (target - x_left) / 100);
2456
2457 return result;
2458}
2459
2141/*
2142 * Find vertical boundary (min pwr) for the linear PCDAC curve.
2460/**
2461 * ath5k_get_linear_pcdac_min() - Find vertical boundary (min pwr) for the
2462 * linear PCDAC curve
2463 * @stepL: Left array with y values (pcdac steps)
2464 * @stepR: Right array with y values (pcdac steps)
2465 * @pwrL: Left array with x values (power steps)
2466 * @pwrR: Right array with x values (power steps)
2143 *
2144 * Since we have the top of the curve and we draw the line below
2145 * until we reach 1 (1 pcdac step) we need to know which point
2467 *
2468 * Since we have the top of the curve and we draw the line below
2469 * until we reach 1 (1 pcdac step) we need to know which point
2146 * (x value) that is so that we don't go below y axis and have negative
2147 * pcdac values when creating the curve, or fill the table with zeroes.
2470 * (x value) that is so that we don't go below x axis and have negative
2471 * pcdac values when creating the curve, or fill the table with zeros.
2148 */
2149static s16
2150ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
2151 const s16 *pwrL, const s16 *pwrR)
2152{
2153 s8 tmp;
2154 s16 min_pwrL, min_pwrR;
2155 s16 pwr_i;

--- 29 unchanged lines hidden (view full) ---

2185
2186 min_pwrR = pwr_i;
2187 }
2188
2189 /* Keep the right boundary so that it works for both curves */
2190 return max(min_pwrL, min_pwrR);
2191}
2192
2472 */
2473static s16
2474ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
2475 const s16 *pwrL, const s16 *pwrR)
2476{
2477 s8 tmp;
2478 s16 min_pwrL, min_pwrR;
2479 s16 pwr_i;

--- 29 unchanged lines hidden (view full) ---

2509
2510 min_pwrR = pwr_i;
2511 }
2512
2513 /* Keep the right boundary so that it works for both curves */
2514 return max(min_pwrL, min_pwrR);
2515}
2516
2193/*
2517/**
2518 * ath5k_create_power_curve() - Create a Power to PDADC or PCDAC curve
2519 * @pmin: Minimum power value (xmin)
2520 * @pmax: Maximum power value (xmax)
2521 * @pwr: Array of power steps (x values)
2522 * @vpd: Array of matching PCDAC/PDADC steps (y values)
2523 * @num_points: Number of provided points
2524 * @vpd_table: Array to fill with the full PCDAC/PDADC values (y values)
2525 * @type: One of enum ath5k_powertable_type (eeprom.h)
2526 *
2194 * Interpolate (pwr,vpd) points to create a Power to PDADC or a
2195 * Power to PCDAC curve.
2196 *
2197 * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
2198 * steps (offsets) on y axis. Power can go up to 31.5dB and max
2199 * PCDAC/PDADC step for each curve is 64 but we can write more than
2200 * one curves on hw so we can go up to 128 (which is the max step we
2201 * can write on the final table).

--- 41 unchanged lines hidden (view full) ---

2243 vpd[idx[0]], vpd[idx[1]]);
2244
2245 /* Increase by 0.5dB
2246 * (0.25 dB units) */
2247 pwr_i += 2;
2248 }
2249}
2250
2527 * Interpolate (pwr,vpd) points to create a Power to PDADC or a
2528 * Power to PCDAC curve.
2529 *
2530 * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
2531 * steps (offsets) on y axis. Power can go up to 31.5dB and max
2532 * PCDAC/PDADC step for each curve is 64 but we can write more than
2533 * one curves on hw so we can go up to 128 (which is the max step we
2534 * can write on the final table).

--- 41 unchanged lines hidden (view full) ---

2576 vpd[idx[0]], vpd[idx[1]]);
2577
2578 /* Increase by 0.5dB
2579 * (0.25 dB units) */
2580 pwr_i += 2;
2581 }
2582}
2583
2251/*
2584/**
2585 * ath5k_get_chan_pcal_surrounding_piers() - Get surrounding calibration piers
2586 * for a given channel.
2587 * @ah: The &struct ath5k_hw
2588 * @channel: The &struct ieee80211_channel
2589 * @pcinfo_l: The &struct ath5k_chan_pcal_info to put the left cal. pier
2590 * @pcinfo_r: The &struct ath5k_chan_pcal_info to put the right cal. pier
2591 *
2252 * Get the surrounding per-channel power calibration piers
2253 * for a given frequency so that we can interpolate between
2254 * them and come up with an appropriate dataset for our current
2255 * channel.
2256 */
2257static void
2258ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
2259 struct ieee80211_channel *channel,

--- 66 unchanged lines hidden (view full) ---

2326 }
2327 }
2328
2329done:
2330 *pcinfo_l = &pcinfo[idx_l];
2331 *pcinfo_r = &pcinfo[idx_r];
2332}
2333
2592 * Get the surrounding per-channel power calibration piers
2593 * for a given frequency so that we can interpolate between
2594 * them and come up with an appropriate dataset for our current
2595 * channel.
2596 */
2597static void
2598ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
2599 struct ieee80211_channel *channel,

--- 66 unchanged lines hidden (view full) ---

2666 }
2667 }
2668
2669done:
2670 *pcinfo_l = &pcinfo[idx_l];
2671 *pcinfo_r = &pcinfo[idx_r];
2672}
2673
2334/*
2674/**
2675 * ath5k_get_rate_pcal_data() - Get the interpolated per-rate power
2676 * calibration data
2677 * @ah: The &struct ath5k_hw *ah,
2678 * @channel: The &struct ieee80211_channel
2679 * @rates: The &struct ath5k_rate_pcal_info to fill
2680 *
2335 * Get the surrounding per-rate power calibration data
2336 * for a given frequency and interpolate between power
2337 * values to set max target power supported by hw for
2681 * Get the surrounding per-rate power calibration data
2682 * for a given frequency and interpolate between power
2683 * values to set max target power supported by hw for
2338 * each rate.
2684 * each rate on this frequency.
2339 */
2340static void
2341ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
2342 struct ieee80211_channel *channel,
2343 struct ath5k_rate_pcal_info *rates)
2344{
2345 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2346 struct ath5k_rate_pcal_info *rpinfo;

--- 71 unchanged lines hidden (view full) ---

2418
2419 rates->target_power_54 =
2420 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2421 rpinfo[idx_r].freq,
2422 rpinfo[idx_l].target_power_54,
2423 rpinfo[idx_r].target_power_54);
2424}
2425
2685 */
2686static void
2687ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
2688 struct ieee80211_channel *channel,
2689 struct ath5k_rate_pcal_info *rates)
2690{
2691 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2692 struct ath5k_rate_pcal_info *rpinfo;

--- 71 unchanged lines hidden (view full) ---

2764
2765 rates->target_power_54 =
2766 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2767 rpinfo[idx_r].freq,
2768 rpinfo[idx_l].target_power_54,
2769 rpinfo[idx_r].target_power_54);
2770}
2771
2426/*
2772/**
2773 * ath5k_get_max_ctl_power() - Get max edge power for a given frequency
2774 * @ah: the &struct ath5k_hw
2775 * @channel: The &struct ieee80211_channel
2776 *
2427 * Get the max edge power for this channel if
2428 * we have such data from EEPROM's Conformance Test
2429 * Limits (CTL), and limit max power if needed.
2430 */
2431static void
2432ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2433 struct ieee80211_channel *channel)
2434{

--- 63 unchanged lines hidden (view full) ---

2498 ah->ah_txpower.txp_max_pwr = 4 * min(edge_pwr, max_chan_pwr);
2499}
2500
2501
2502/*
2503 * Power to PCDAC table functions
2504 */
2505
2777 * Get the max edge power for this channel if
2778 * we have such data from EEPROM's Conformance Test
2779 * Limits (CTL), and limit max power if needed.
2780 */
2781static void
2782ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2783 struct ieee80211_channel *channel)
2784{

--- 63 unchanged lines hidden (view full) ---

2848 ah->ah_txpower.txp_max_pwr = 4 * min(edge_pwr, max_chan_pwr);
2849}
2850
2851
2852/*
2853 * Power to PCDAC table functions
2854 */
2855
2506/*
2507 * Fill Power to PCDAC table on RF5111
2856/**
2857 * DOC: Power to PCDAC table functions
2508 *
2858 *
2859 * For RF5111 we have an XPD -eXternal Power Detector- curve
2860 * for each calibrated channel. Each curve has 0,5dB Power steps
2861 * on x axis and PCDAC steps (offsets) on y axis and looks like an
2862 * exponential function. To recreate the curve we read 11 points
2863 * from eeprom (eeprom.c) and interpolate here.
2864 *
2865 * For RF5112 we have 4 XPD -eXternal Power Detector- curves
2866 * for each calibrated channel on 0, -6, -12 and -18dBm but we only
2867 * use the higher (3) and the lower (0) curves. Each curve again has 0.5dB
2868 * power steps on x axis and PCDAC steps on y axis and looks like a
2869 * linear function. To recreate the curve and pass the power values
2870 * on hw, we get 4 points for xpd 0 (lower gain -> max power)
2871 * and 3 points for xpd 3 (higher gain -> lower power) from eeprom (eeprom.c)
2872 * and interpolate here.
2873 *
2874 * For a given channel we get the calibrated points (piers) for it or
2875 * -if we don't have calibration data for this specific channel- from the
2876 * available surrounding channels we have calibration data for, after we do a
2877 * linear interpolation between them. Then since we have our calibrated points
2878 * for this channel, we do again a linear interpolation between them to get the
2879 * whole curve.
2880 *
2881 * We finally write the Y values of the curve(s) (the PCDAC values) on hw
2882 */
2883
2884/**
2885 * ath5k_fill_pwr_to_pcdac_table() - Fill Power to PCDAC table on RF5111
2886 * @ah: The &struct ath5k_hw
2887 * @table_min: Minimum power (x min)
2888 * @table_max: Maximum power (x max)
2889 *
2509 * No further processing is needed for RF5111, the only thing we have to
2510 * do is fill the values below and above calibration range since eeprom data
2511 * may not cover the entire PCDAC table.
2512 */
2513static void
2514ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
2515 s16 *table_max)
2516{

--- 23 unchanged lines hidden (view full) ---

2540 }
2541
2542 /* Extrapolate above maximum */
2543 while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
2544 pcdac_out[pcdac_i++] = pcdac_n;
2545
2546}
2547
2890 * No further processing is needed for RF5111, the only thing we have to
2891 * do is fill the values below and above calibration range since eeprom data
2892 * may not cover the entire PCDAC table.
2893 */
2894static void
2895ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
2896 s16 *table_max)
2897{

--- 23 unchanged lines hidden (view full) ---

2921 }
2922
2923 /* Extrapolate above maximum */
2924 while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
2925 pcdac_out[pcdac_i++] = pcdac_n;
2926
2927}
2928
2548/*
2549 * Combine available XPD Curves and fill Linear Power to PCDAC table
2550 * on RF5112
2929/**
2930 * ath5k_combine_linear_pcdac_curves() - Combine available PCDAC Curves
2931 * @ah: The &struct ath5k_hw
2932 * @table_min: Minimum power (x min)
2933 * @table_max: Maximum power (x max)
2934 * @pdcurves: Number of pd curves
2551 *
2935 *
2936 * Combine available XPD Curves and fill Linear Power to PCDAC table on RF5112
2552 * RFX112 can have up to 2 curves (one for low txpower range and one for
2553 * higher txpower range). We need to put them both on pcdac_out and place
2554 * them in the correct location. In case we only have one curve available
2555 * just fit it on pcdac_out (it's supposed to cover the entire range of
2556 * available pwr levels since it's always the higher power curve). Extrapolate
2557 * below and above final table if needed.
2558 */
2559static void

--- 85 unchanged lines hidden (view full) ---

2645 if (pcdac_out[i] > 126)
2646 pcdac_out[i] = 126;
2647
2648 /* Decrease by a 0.5dB step */
2649 pwr--;
2650 }
2651}
2652
2937 * RFX112 can have up to 2 curves (one for low txpower range and one for
2938 * higher txpower range). We need to put them both on pcdac_out and place
2939 * them in the correct location. In case we only have one curve available
2940 * just fit it on pcdac_out (it's supposed to cover the entire range of
2941 * available pwr levels since it's always the higher power curve). Extrapolate
2942 * below and above final table if needed.
2943 */
2944static void

--- 85 unchanged lines hidden (view full) ---

3030 if (pcdac_out[i] > 126)
3031 pcdac_out[i] = 126;
3032
3033 /* Decrease by a 0.5dB step */
3034 pwr--;
3035 }
3036}
3037
2653/* Write PCDAC values on hw */
3038/**
3039 * ath5k_write_pcdac_table() - Write the PCDAC values on hw
3040 * @ah: The &struct ath5k_hw
3041 */
2654static void
2655ath5k_write_pcdac_table(struct ath5k_hw *ah)
2656{
2657 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
2658 int i;
2659
2660 /*
2661 * Write TX power values

--- 6 unchanged lines hidden (view full) ---

2668 }
2669}
2670
2671
2672/*
2673 * Power to PDADC table functions
2674 */
2675
3042static void
3043ath5k_write_pcdac_table(struct ath5k_hw *ah)
3044{
3045 u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
3046 int i;
3047
3048 /*
3049 * Write TX power values

--- 6 unchanged lines hidden (view full) ---

3056 }
3057}
3058
3059
3060/*
3061 * Power to PDADC table functions
3062 */
3063
2676/*
2677 * Set the gain boundaries and create final Power to PDADC table
3064/**
3065 * DOC: Power to PDADC table functions
2678 *
3066 *
3067 * For RF2413 and later we have a Power to PDADC table (Power Detector)
3068 * instead of a PCDAC (Power Control) and 4 pd gain curves for each
3069 * calibrated channel. Each curve has power on x axis in 0.5 db steps and
3070 * PDADC steps on y axis and looks like an exponential function like the
3071 * RF5111 curve.
3072 *
3073 * To recreate the curves we read the points from eeprom (eeprom.c)
3074 * and interpolate here. Note that in most cases only 2 (higher and lower)
3075 * curves are used (like RF5112) but vendors have the opportunity to include
3076 * all 4 curves on eeprom. The final curve (higher power) has an extra
3077 * point for better accuracy like RF5112.
3078 *
3079 * The process is similar to what we do above for RF5111/5112
3080 */
3081
3082/**
3083 * ath5k_combine_pwr_to_pdadc_curves() - Combine the various PDADC curves
3084 * @ah: The &struct ath5k_hw
3085 * @pwr_min: Minimum power (x min)
3086 * @pwr_max: Maximum power (x max)
3087 * @pdcurves: Number of available curves
3088 *
3089 * Combine the various pd curves and create the final Power to PDADC table
2679 * We can have up to 4 pd curves, we need to do a similar process
2680 * as we do for RF5112. This time we don't have an edge_flag but we
2681 * set the gain boundaries on a separate register.
2682 */
2683static void
2684ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
2685 s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
2686{

--- 107 unchanged lines hidden (view full) ---

2794 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
2795 AR5K_PHY_TPC_RG5);
2796
2797 /* Used for setting rate power table */
2798 ah->ah_txpower.txp_min_idx = pwr_min[0];
2799
2800}
2801
3090 * We can have up to 4 pd curves, we need to do a similar process
3091 * as we do for RF5112. This time we don't have an edge_flag but we
3092 * set the gain boundaries on a separate register.
3093 */
3094static void
3095ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
3096 s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
3097{

--- 107 unchanged lines hidden (view full) ---

3205 AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
3206 AR5K_PHY_TPC_RG5);
3207
3208 /* Used for setting rate power table */
3209 ah->ah_txpower.txp_min_idx = pwr_min[0];
3210
3211}
3212
2802/* Write PDADC values on hw */
3213/**
3214 * ath5k_write_pwr_to_pdadc_table() - Write the PDADC values on hw
3215 * @ah: The &struct ath5k_hw
3216 * @ee_mode: One of enum ath5k_driver_mode
3217 */
2803static void
2804ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
2805{
2806 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2807 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
2808 u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode];
2809 u8 pdcurves = ee->ee_pd_gains[ee_mode];
2810 u32 reg;

--- 40 unchanged lines hidden (view full) ---

2851 }
2852}
2853
2854
2855/*
2856 * Common code for PCDAC/PDADC tables
2857 */
2858
3218static void
3219ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
3220{
3221 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
3222 u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
3223 u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode];
3224 u8 pdcurves = ee->ee_pd_gains[ee_mode];
3225 u32 reg;

--- 40 unchanged lines hidden (view full) ---

3266 }
3267}
3268
3269
3270/*
3271 * Common code for PCDAC/PDADC tables
3272 */
3273
2859/*
3274/**
3275 * ath5k_setup_channel_powertable() - Set up power table for this channel
3276 * @ah: The &struct ath5k_hw
3277 * @channel: The &struct ieee80211_channel
3278 * @ee_mode: One of enum ath5k_driver_mode
3279 * @type: One of enum ath5k_powertable_type (eeprom.h)
3280 *
2860 * This is the main function that uses all of the above
2861 * to set PCDAC/PDADC table on hw for the current channel.
2862 * This table is used for tx power calibration on the baseband,
2863 * without it we get weird tx power levels and in some cases
2864 * distorted spectral mask
2865 */
2866static int
2867ath5k_setup_channel_powertable(struct ath5k_hw *ah,

--- 181 unchanged lines hidden (view full) ---

3049 return -EINVAL;
3050 }
3051
3052 ah->ah_txpower.txp_setup = true;
3053
3054 return 0;
3055}
3056
3281 * This is the main function that uses all of the above
3282 * to set PCDAC/PDADC table on hw for the current channel.
3283 * This table is used for tx power calibration on the baseband,
3284 * without it we get weird tx power levels and in some cases
3285 * distorted spectral mask
3286 */
3287static int
3288ath5k_setup_channel_powertable(struct ath5k_hw *ah,

--- 181 unchanged lines hidden (view full) ---

3470 return -EINVAL;
3471 }
3472
3473 ah->ah_txpower.txp_setup = true;
3474
3475 return 0;
3476}
3477
3057/* Write power table for current channel to hw */
3478/**
3479 * ath5k_write_channel_powertable() - Set power table for current channel on hw
3480 * @ah: The &struct ath5k_hw
3481 * @ee_mode: One of enum ath5k_driver_mode
3482 * @type: One of enum ath5k_powertable_type (eeprom.h)
3483 */
3058static void
3059ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
3060{
3061 if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
3062 ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
3063 else
3064 ath5k_write_pcdac_table(ah);
3065}
3066
3484static void
3485ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
3486{
3487 if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
3488 ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
3489 else
3490 ath5k_write_pcdac_table(ah);
3491}
3492
3067/*
3068 * Per-rate tx power setting
3493
3494/**
3495 * DOC: Per-rate tx power setting
3069 *
3496 *
3070 * This is the code that sets the desired tx power (below
3497 * This is the code that sets the desired tx power limit (below
3071 * maximum) on hw for each rate (we also have TPC that sets
3498 * maximum) on hw for each rate (we also have TPC that sets
3072 * power per packet). We do that by providing an index on the
3073 * PCDAC/PDADC table we set up.
3074 */
3075
3076/*
3077 * Set rate power table
3499 * power per packet type). We do that by providing an index on the
3500 * PCDAC/PDADC table we set up above, for each rate.
3078 *
3079 * For now we only limit txpower based on maximum tx power
3501 *
3502 * For now we only limit txpower based on maximum tx power
3080 * supported by hw (what's inside rate_info). We need to limit
3081 * this even more, based on regulatory domain etc.
3503 * supported by hw (what's inside rate_info) + conformance test
3504 * limits. We need to limit this even more, based on regulatory domain
3505 * etc to be safe. Normally this is done from above so we don't care
3506 * here, all we care is that the tx power we set will be O.K.
3507 * for the hw (e.g. won't create noise on PA etc).
3082 *
3508 *
3083 * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
3084 * and is indexed as follows:
3509 * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps -
3510 * x values) and is indexed as follows:
3085 * rates[0] - rates[7] -> OFDM rates
3086 * rates[8] - rates[14] -> CCK rates
3087 * rates[15] -> XR rates (they all have the same power)
3088 */
3511 * rates[0] - rates[7] -> OFDM rates
3512 * rates[8] - rates[14] -> CCK rates
3513 * rates[15] -> XR rates (they all have the same power)
3514 */
3515
3516/**
3517 * ath5k_setup_rate_powertable() - Set up rate power table for a given tx power
3518 * @ah: The &struct ath5k_hw
3519 * @max_pwr: The maximum tx power requested in 0.5dB steps
3520 * @rate_info: The &struct ath5k_rate_pcal_info to fill
3521 * @ee_mode: One of enum ath5k_driver_mode
3522 */
3089static void
3090ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
3091 struct ath5k_rate_pcal_info *rate_info,
3092 u8 ee_mode)
3093{
3094 unsigned int i;
3095 u16 *rates;
3096

--- 54 unchanged lines hidden (view full) ---

3151
3152 /* Min/max in 0.25dB units */
3153 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
3154 ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
3155 ah->ah_txpower.txp_ofdm = rates[7];
3156}
3157
3158
3523static void
3524ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
3525 struct ath5k_rate_pcal_info *rate_info,
3526 u8 ee_mode)
3527{
3528 unsigned int i;
3529 u16 *rates;
3530

--- 54 unchanged lines hidden (view full) ---

3585
3586 /* Min/max in 0.25dB units */
3587 ah->ah_txpower.txp_min_pwr = 2 * rates[7];
3588 ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
3589 ah->ah_txpower.txp_ofdm = rates[7];
3590}
3591
3592
3159/*
3160 * Set transmission power
3593/**
3594 * ath5k_hw_txpower() - Set transmission power limit for a given channel
3595 * @ah: The &struct ath5k_hw
3596 * @channel: The &struct ieee80211_channel
3597 * @txpower: Requested tx power in 0.5dB steps
3598 *
3599 * Combines all of the above to set the requested tx power limit
3600 * on hw.
3161 */
3162static int
3163ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3164 u8 txpower)
3165{
3166 struct ath5k_rate_pcal_info rate_info;
3167 struct ieee80211_channel *curr_channel = ah->ah_current_channel;
3168 int ee_mode;

--- 101 unchanged lines hidden (view full) ---

3270 } else {
3271 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
3272 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
3273 }
3274
3275 return 0;
3276}
3277
3601 */
3602static int
3603ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3604 u8 txpower)
3605{
3606 struct ath5k_rate_pcal_info rate_info;
3607 struct ieee80211_channel *curr_channel = ah->ah_current_channel;
3608 int ee_mode;

--- 101 unchanged lines hidden (view full) ---

3710 } else {
3711 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
3712 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
3713 }
3714
3715 return 0;
3716}
3717
3278int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3718/**
3719 * ath5k_hw_set_txpower_limit() - Set txpower limit for the current channel
3720 * @ah: The &struct ath5k_hw
3721 * @txpower: The requested tx power limit in 0.5dB steps
3722 *
3723 * This function provides access to ath5k_hw_txpower to the driver in
3724 * case user or an application changes it while PHY is running.
3725 */
3726int
3727ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3279{
3280 ATH5K_DBG(ah, ATH5K_DEBUG_TXPOWER,
3281 "changing txpower to %d\n", txpower);
3282
3283 return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
3284}
3285
3728{
3729 ATH5K_DBG(ah, ATH5K_DEBUG_TXPOWER,
3730 "changing txpower to %d\n", txpower);
3731
3732 return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
3733}
3734
3735
3286/*************\
3287 Init function
3288\*************/
3289
3736/*************\
3737 Init function
3738\*************/
3739
3290int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3740/**
3741 * ath5k_hw_phy_init() - Initialize PHY
3742 * @ah: The &struct ath5k_hw
3743 * @channel: The @struct ieee80211_channel
3744 * @mode: One of enum ath5k_driver_mode
3745 * @fast: Try a fast channel switch instead
3746 *
3747 * This is the main function used during reset to initialize PHY
3748 * or do a fast channel change if possible.
3749 *
3750 * NOTE: Do not call this one from the driver, it assumes PHY is in a
3751 * warm reset state !
3752 */
3753int
3754ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3291 u8 mode, bool fast)
3292{
3293 struct ieee80211_channel *curr_channel;
3294 int ret, i;
3295 u32 phy_tst1;
3296 ret = 0;
3297
3298 /*

--- 201 unchanged lines hidden ---
3755 u8 mode, bool fast)
3756{
3757 struct ieee80211_channel *curr_channel;
3758 int ret, i;
3759 u32 phy_tst1;
3760 ret = 0;
3761
3762 /*

--- 201 unchanged lines hidden ---