iPXE
Macros | Functions
ath5k_phy.c File Reference
#include <unistd.h>
#include <stdlib.h>
#include "ath5k.h"
#include "reg.h"
#include "base.h"
#include "rfbuffer.h"
#include "rfgain.h"

Go to the source code of this file.

Macros

#define _ATH5K_PHY
 

Functions

 FILE_LICENCE (MIT)
 
static int min (int x, int y)
 
static int max (int x, int y)
 
static unsigned int ath5k_hw_rfb_op (struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs, u32 val, u8 reg_id, int set)
 
int ath5k_hw_rfgain_opt_init (struct ath5k_hw *ah)
 
static void ath5k_hw_request_rfgain_probe (struct ath5k_hw *ah)
 
static u32 ath5k_hw_rf_gainf_corr (struct ath5k_hw *ah)
 
static int ath5k_hw_rf_check_gainf_readback (struct ath5k_hw *ah)
 
static s8 ath5k_hw_rf_gainf_adjust (struct ath5k_hw *ah)
 
enum ath5k_rfgain ath5k_hw_gainf_calibrate (struct ath5k_hw *ah)
 
int ath5k_hw_rfgain_init (struct ath5k_hw *ah, unsigned int freq)
 
int ath5k_hw_rfregs_init (struct ath5k_hw *ah, struct net80211_channel *channel, unsigned int mode)
 
int ath5k_channel_ok (struct ath5k_hw *ah, u16 freq, unsigned int flags)
 
static u32 ath5k_hw_rf5110_chan2athchan (struct net80211_channel *channel)
 
static int ath5k_hw_rf5110_channel (struct ath5k_hw *ah, struct net80211_channel *channel)
 
static int ath5k_hw_rf5111_chan2athchan (unsigned int ieee, struct ath5k_athchan_2ghz *athchan)
 
static int ath5k_hw_rf5111_channel (struct ath5k_hw *ah, struct net80211_channel *channel)
 
static int ath5k_hw_rf5112_channel (struct ath5k_hw *ah, struct net80211_channel *channel)
 
static int ath5k_hw_rf2425_channel (struct ath5k_hw *ah, struct net80211_channel *channel)
 
int ath5k_hw_channel (struct ath5k_hw *ah, struct net80211_channel *channel)
 
int ath5k_hw_noise_floor_calibration (struct ath5k_hw *ah, short freq)
 ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration More...
 
static int ath5k_hw_rf5110_calibrate (struct ath5k_hw *ah, struct net80211_channel *channel)
 
static int ath5k_hw_rf511x_calibrate (struct ath5k_hw *ah, struct net80211_channel *channel)
 
int ath5k_hw_phy_calibrate (struct ath5k_hw *ah, struct net80211_channel *channel)
 
int ath5k_hw_phy_disable (struct ath5k_hw *ah)
 
u16 ath5k_hw_radio_revision (struct ath5k_hw *ah, unsigned int chan)
 
void ath5k_hw_set_def_antenna (struct ath5k_hw *ah, unsigned int ant)
 
unsigned int ath5k_hw_get_def_antenna (struct ath5k_hw *ah)
 
static s16 ath5k_get_interpolated_value (s16 target, s16 x_left, s16 x_right, s16 y_left, s16 y_right)
 
static s16 ath5k_get_linear_pcdac_min (const u8 *stepL, const u8 *stepR, const s16 *pwrL, const s16 *pwrR)
 
static void ath5k_create_power_curve (s16 pmin, s16 pmax, const s16 *pwr, const u8 *vpd, u8 num_points, u8 *vpd_table, u8 type)
 
static void ath5k_get_chan_pcal_surrounding_piers (struct ath5k_hw *ah, struct net80211_channel *channel, struct ath5k_chan_pcal_info **pcinfo_l, struct ath5k_chan_pcal_info **pcinfo_r)
 
static void ath5k_get_rate_pcal_data (struct ath5k_hw *ah, struct net80211_channel *channel, struct ath5k_rate_pcal_info *rates)
 
static void ath5k_get_max_ctl_power (struct ath5k_hw *ah, struct net80211_channel *channel)
 
static void ath5k_fill_pwr_to_pcdac_table (struct ath5k_hw *ah, s16 *table_min, s16 *table_max)
 
static void ath5k_combine_linear_pcdac_curves (struct ath5k_hw *ah, s16 *table_min, s16 *table_max, u8 pdcurves)
 
static void ath5k_setup_pcdac_table (struct ath5k_hw *ah)
 
static void ath5k_combine_pwr_to_pdadc_curves (struct ath5k_hw *ah, s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
 
static void ath5k_setup_pwr_to_pdadc_table (struct ath5k_hw *ah, u8 pdcurves, u8 *pdg_to_idx)
 
static int ath5k_setup_channel_powertable (struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 type)
 
static void ath5k_setup_rate_powertable (struct ath5k_hw *ah, u16 max_pwr, struct ath5k_rate_pcal_info *rate_info, u8 ee_mode)
 
int ath5k_hw_txpower (struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 txpower)
 
int ath5k_hw_set_txpower_limit (struct ath5k_hw *ah, u8 mode, u8 txpower)
 

Macro Definition Documentation

◆ _ATH5K_PHY

#define _ATH5K_PHY

Definition at line 27 of file ath5k_phy.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( MIT  )

◆ min()

static int min ( int  x,
int  y 
)
inlinestatic

Definition at line 38 of file ath5k_phy.c.

39 {
40  return (x < y) ? x : y;
41 }

Referenced by ath5k_get_max_ctl_power(), ath5k_setup_channel_powertable(), and ath5k_setup_rate_powertable().

◆ max()

static int max ( int  x,
int  y 
)
inlinestatic

Definition at line 43 of file ath5k_phy.c.

44 {
45  return (x > y) ? x : y;
46 }

Referenced by ath5k_get_chan_pcal_surrounding_piers(), ath5k_get_linear_pcdac_min(), ath5k_get_rate_pcal_data(), and ath5k_setup_channel_powertable().

◆ ath5k_hw_rfb_op()

static unsigned int ath5k_hw_rfb_op ( struct ath5k_hw ah,
const struct ath5k_rf_reg rf_regs,
u32  val,
u8  reg_id,
int  set 
)
static

Definition at line 51 of file ath5k_phy.c.

54 {
55  const struct ath5k_rf_reg *rfreg = NULL;
56  u8 offset, bank, num_bits, col, position;
57  u16 entry;
58  u32 mask, data, last_bit, bits_shifted, first_bit;
59  u32 *rfb;
60  s32 bits_left;
61  unsigned i;
62 
63  data = 0;
64  rfb = ah->ah_rf_banks;
65 
66  for (i = 0; i < ah->ah_rf_regs_count; i++) {
67  if (rf_regs[i].index == reg_id) {
68  rfreg = &rf_regs[i];
69  break;
70  }
71  }
72 
73  if (rfb == NULL || rfreg == NULL) {
74  DBG("ath5k: RF register not found!\n");
75  /* should not happen */
76  return 0;
77  }
78 
79  bank = rfreg->bank;
80  num_bits = rfreg->field.len;
81  first_bit = rfreg->field.pos;
82  col = rfreg->field.col;
83 
84  /* first_bit is an offset from bank's
85  * start. Since we have all banks on
86  * the same array, we use this offset
87  * to mark each bank's start */
88  offset = ah->ah_offset[bank];
89 
90  /* Boundary check */
91  if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
92  DBG("ath5k: RF invalid values at offset %d\n", offset);
93  return 0;
94  }
95 
96  entry = ((first_bit - 1) / 8) + offset;
97  position = (first_bit - 1) % 8;
98 
99  if (set)
100  data = ath5k_hw_bitswap(val, num_bits);
101 
102  for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
103  position = 0, entry++) {
104 
105  last_bit = (position + bits_left > 8) ? 8 :
106  position + bits_left;
107 
108  mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
109  (col * 8);
110 
111  if (set) {
112  rfb[entry] &= ~mask;
113  rfb[entry] |= ((data << position) << (col * 8)) & mask;
114  data >>= (8 - position);
115  } else {
116  data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
117  << bits_shifted;
118  bits_shifted += last_bit - position;
119  }
120 
121  bits_left -= 8 - position;
122  }
123 
124  data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
125 
126  return data;
127 }
uint16_t u16
Definition: stdint.h:21
struct option_descriptor set[0]
Definition: nvo_cmd.c:111
int32_t s32
Definition: stdint.h:22
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1265
struct ath5k_rfb_field field
Definition: rfbuffer.h:74
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
void __asmcall int val
Definition: setjmp.h:28
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ah
Definition: registers.h:85
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23

References ah, ath5k_hw_bitswap(), ath5k_rf_reg::bank, ath5k_rfb_field::col, data, DBG, entry, ath5k_rf_reg::field, index, ath5k_rfb_field::len, NULL, offset, ath5k_rfb_field::pos, set, and val.

Referenced by ath5k_hw_rf_check_gainf_readback(), ath5k_hw_rf_gainf_corr(), and ath5k_hw_rfregs_init().

◆ ath5k_hw_rfgain_opt_init()

int ath5k_hw_rfgain_opt_init ( struct ath5k_hw ah)

Definition at line 158 of file ath5k_phy.c.

159 {
160  /* Initialize the gain optimization values */
161  switch (ah->ah_radio) {
162  case AR5K_RF5111:
163  ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
164  ah->ah_gain.g_low = 20;
165  ah->ah_gain.g_high = 35;
166  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
167  break;
168  case AR5K_RF5112:
169  ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
170  ah->ah_gain.g_low = 20;
171  ah->ah_gain.g_high = 85;
172  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
173  break;
174  default:
175  return -EINVAL;
176  }
177 
178  return 0;
179 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static const struct ath5k_gain_opt rfgain_opt_5111
Definition: rfgain.h:476
static const struct ath5k_gain_opt rfgain_opt_5112
Definition: rfgain.h:502
uint8_t ah
Definition: registers.h:85

References ah, AR5K_RF5111, AR5K_RF5112, AR5K_RFGAIN_ACTIVE, EINVAL, ath5k_gain_opt::go_default, rfgain_opt_5111, and rfgain_opt_5112.

Referenced by ath5k_hw_attach().

◆ ath5k_hw_request_rfgain_probe()

static void ath5k_hw_request_rfgain_probe ( struct ath5k_hw ah)
static

Definition at line 194 of file ath5k_phy.c.

195 {
196 
197  /* Skip if gain calibration is inactive or
198  * we already handle a probe request */
199  if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
200  return;
201 
202  /* Send the packet with 2dB below max power as
203  * patent doc suggest */
204  ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
207 
208  ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
209 
210 }
#define AR5K_PHY_PAPD_PROBE_TXPOWER
Definition: reg.h:2244
#define AR5K_PHY_PAPD_PROBE
Definition: reg.h:2240
#define AR5K_PHY_PAPD_PROBE_TX_NEXT
Definition: reg.h:2246
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
uint8_t ah
Definition: registers.h:85
#define AR5K_REG_SM(_val, _flags)
Definition: ath5k.h:84

References ah, AR5K_PHY_PAPD_PROBE, AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE_TXPOWER, AR5K_REG_SM, AR5K_RFGAIN_ACTIVE, AR5K_RFGAIN_READ_REQUESTED, and ath5k_hw_reg_write().

Referenced by ath5k_hw_rf511x_calibrate().

◆ ath5k_hw_rf_gainf_corr()

static u32 ath5k_hw_rf_gainf_corr ( struct ath5k_hw ah)
static

Definition at line 214 of file ath5k_phy.c.

215 {
216  u32 mix, step;
217  const struct ath5k_gain_opt *go;
218  const struct ath5k_gain_opt_step *g_step;
219  const struct ath5k_rf_reg *rf_regs;
220 
221  /* Only RF5112 Rev. 2 supports it */
222  if ((ah->ah_radio != AR5K_RF5112) ||
223  (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
224  return 0;
225 
226  go = &rfgain_opt_5112;
227  rf_regs = rf_regs_5112a;
228  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
229 
230  g_step = &go->go_step[ah->ah_gain.g_step_idx];
231 
232  if (ah->ah_rf_banks == NULL)
233  return 0;
234 
235  ah->ah_gain.g_f_corr = 0;
236 
237  /* No VGA (Variable Gain Amplifier) override, skip */
238  if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, 0) != 1)
239  return 0;
240 
241  /* Mix gain stepping */
242  step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, 0);
243 
244  /* Mix gain override */
245  mix = g_step->gos_param[0];
246 
247  switch (mix) {
248  case 3:
249  ah->ah_gain.g_f_corr = step * 2;
250  break;
251  case 2:
252  ah->ah_gain.g_f_corr = (step - 5) * 2;
253  break;
254  case 1:
255  ah->ah_gain.g_f_corr = step;
256  break;
257  default:
258  ah->ah_gain.g_f_corr = 0;
259  break;
260  }
261 
262  return ah->ah_gain.g_f_corr;
263 }
static const struct ath5k_rf_reg rf_regs_5112a[]
Definition: rfbuffer.h:479
const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT]
Definition: rfgain.h:466
static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs, u32 val, u8 reg_id, int set)
Definition: ath5k_phy.c:51
s8 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS]
Definition: rfgain.h:459
#define ARRAY_SIZE(x)
Definition: efx_common.h:43
static const struct ath5k_gain_opt rfgain_opt_5112
Definition: rfgain.h:502
#define AR5K_SREV_RAD_5112A
Definition: ath5k.h:312
void step(void)
Single-step a single process.
Definition: process.c:98
uint8_t ah
Definition: registers.h:85
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_RF5112, AR5K_RF_MIXGAIN_STEP, AR5K_RF_MIXVGA_OVR, AR5K_SREV_RAD_5112A, ARRAY_SIZE, ath5k_hw_rfb_op(), ath5k_gain_opt::go_step, ath5k_gain_opt_step::gos_param, NULL, rf_regs_5112a, rfgain_opt_5112, and step().

Referenced by ath5k_hw_gainf_calibrate().

◆ ath5k_hw_rf_check_gainf_readback()

static int ath5k_hw_rf_check_gainf_readback ( struct ath5k_hw ah)
static

Definition at line 269 of file ath5k_phy.c.

270 {
271  const struct ath5k_rf_reg *rf_regs;
272  u32 step, mix_ovr, level[4];
273 
274  if (ah->ah_rf_banks == NULL)
275  return 0;
276 
277  if (ah->ah_radio == AR5K_RF5111) {
278 
279  rf_regs = rf_regs_5111;
280  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
281 
283  0);
284 
285  level[0] = 0;
286  level[1] = (step == 63) ? 50 : step + 4;
287  level[2] = (step != 63) ? 64 : level[0];
288  level[3] = level[2] + 50 ;
289 
290  ah->ah_gain.g_high = level[3] -
291  (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
292  ah->ah_gain.g_low = level[0] +
293  (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
294  } else {
295 
296  rf_regs = rf_regs_5112;
297  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
298 
299  mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
300  0);
301 
302  level[0] = level[2] = 0;
303 
304  if (mix_ovr == 1) {
305  level[1] = level[3] = 83;
306  } else {
307  level[1] = level[3] = 107;
308  ah->ah_gain.g_high = 55;
309  }
310  }
311 
312  return (ah->ah_gain.g_current >= level[0] &&
313  ah->ah_gain.g_current <= level[1]) ||
314  (ah->ah_gain.g_current >= level[2] &&
315  ah->ah_gain.g_current <= level[3]);
316 }
static const struct ath5k_rf_reg rf_regs_5112[]
Definition: rfbuffer.h:309
#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN
Definition: rfgain.h:447
static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs, u32 val, u8 reg_id, int set)
Definition: ath5k_phy.c:51
#define ARRAY_SIZE(x)
Definition: efx_common.h:43
static const struct ath5k_rf_reg rf_regs_5111[]
Definition: rfbuffer.h:160
#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN
Definition: rfgain.h:448
void step(void)
Single-step a single process.
Definition: process.c:98
uint8_t ah
Definition: registers.h:85
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_GAIN_DYN_ADJUST_HI_MARGIN, AR5K_GAIN_DYN_ADJUST_LO_MARGIN, AR5K_RF5111, AR5K_RF_MIXVGA_OVR, AR5K_RF_RFGAIN_STEP, ARRAY_SIZE, ath5k_hw_rfb_op(), NULL, rf_regs_5111, rf_regs_5112, and step().

Referenced by ath5k_hw_gainf_calibrate().

◆ ath5k_hw_rf_gainf_adjust()

static s8 ath5k_hw_rf_gainf_adjust ( struct ath5k_hw ah)
static

Definition at line 320 of file ath5k_phy.c.

321 {
322  const struct ath5k_gain_opt *go;
323  const struct ath5k_gain_opt_step *g_step;
324  int ret = 0;
325 
326  switch (ah->ah_radio) {
327  case AR5K_RF5111:
328  go = &rfgain_opt_5111;
329  break;
330  case AR5K_RF5112:
331  go = &rfgain_opt_5112;
332  break;
333  default:
334  return 0;
335  }
336 
337  g_step = &go->go_step[ah->ah_gain.g_step_idx];
338 
339  if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
340 
341  /* Reached maximum */
342  if (ah->ah_gain.g_step_idx == 0)
343  return -1;
344 
345  for (ah->ah_gain.g_target = ah->ah_gain.g_current;
346  ah->ah_gain.g_target >= ah->ah_gain.g_high &&
347  ah->ah_gain.g_step_idx > 0;
348  g_step = &go->go_step[ah->ah_gain.g_step_idx])
349  ah->ah_gain.g_target -= 2 *
350  (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
351  g_step->gos_gain);
352 
353  ret = 1;
354  goto done;
355  }
356 
357  if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
358 
359  /* Reached minimum */
360  if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
361  return -2;
362 
363  for (ah->ah_gain.g_target = ah->ah_gain.g_current;
364  ah->ah_gain.g_target <= ah->ah_gain.g_low &&
365  ah->ah_gain.g_step_idx < go->go_steps_count-1;
366  g_step = &go->go_step[ah->ah_gain.g_step_idx])
367  ah->ah_gain.g_target -= 2 *
368  (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
369  g_step->gos_gain);
370 
371  ret = 2;
372  goto done;
373  }
374 
375 done:
376  DBG2("ath5k RF adjust: ret %d, gain step %d, current gain %d, "
377  "target gain %d\n", ret, ah->ah_gain.g_step_idx,
378  ah->ah_gain.g_current, ah->ah_gain.g_target);
379 
380  return ret;
381 }
static const struct ath5k_gain_opt rfgain_opt_5111
Definition: rfgain.h:476
const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT]
Definition: rfgain.h:466
u8 go_steps_count
Definition: rfgain.h:465
static const struct ath5k_gain_opt rfgain_opt_5112
Definition: rfgain.h:502
uint8_t ah
Definition: registers.h:85
struct bofm_section_header done
Definition: bofm_test.c:46
#define DBG2(...)
Definition: compiler.h:515

References ah, AR5K_RF5111, AR5K_RF5112, DBG2, done, ath5k_gain_opt::go_step, ath5k_gain_opt::go_steps_count, ath5k_gain_opt_step::gos_gain, rfgain_opt_5111, and rfgain_opt_5112.

Referenced by ath5k_hw_gainf_calibrate().

◆ ath5k_hw_gainf_calibrate()

enum ath5k_rfgain ath5k_hw_gainf_calibrate ( struct ath5k_hw ah)

Definition at line 389 of file ath5k_phy.c.

390 {
391  u32 data, type;
392  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
393 
394  if (ah->ah_rf_banks == NULL ||
395  ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
396  return AR5K_RFGAIN_INACTIVE;
397 
398  /* No check requested, either engine is inactive
399  * or an adjustment is already requested */
400  if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
401  goto done;
402 
403  /* Read the PAPD (Peak to Average Power Detector)
404  * register */
406 
407  /* No probe is scheduled, read gain_F measurement */
409  ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
411 
412  /* If tx packet is CCK correct the gain_F measurement
413  * by cck ofdm gain delta */
415  if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
416  ah->ah_gain.g_current +=
418  else
419  ah->ah_gain.g_current +=
421  }
422 
423  /* Further correct gain_F measurement for
424  * RF5112A radios */
425  if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
427  ah->ah_gain.g_current =
428  ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
429  (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
430  0;
431  }
432 
433  /* Check if measurement is ok and if we need
434  * to adjust gain, schedule a gain adjustment,
435  * else switch back to the acive state */
437  AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
439  ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
440  } else {
441  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
442  }
443  }
444 
445 done:
446  return ah->ah_gain.g_state;
447 }
#define AR5K_PHY_PAPD_PROBE_GAINF_S
Definition: reg.h:2254
#define AR5K_PHY_PAPD_PROBE
Definition: reg.h:2240
#define AR5K_PHY_PAPD_PROBE_TYPE
Definition: reg.h:2248
#define AR5K_GAIN_CCK_PROBE_CORR
Definition: rfgain.h:449
#define AR5K_PHY_PAPD_PROBE_TYPE_CCK
Definition: reg.h:2252
#define AR5K_REG_MS(_val, _flags)
Definition: ath5k.h:88
static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
Definition: ath5k_phy.c:214
#define AR5K_GAIN_CHECK_ADJUST(_g)
Definition: rfgain.h:455
static int ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
Definition: ath5k_phy.c:269
#define AR5K_PHY_PAPD_PROBE_TX_NEXT
Definition: reg.h:2246
static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
Definition: ath5k_phy.c:320
uint32_t type
Operating system type.
Definition: ena.h:12
#define AR5K_SREV_RAD_5112A
Definition: ath5k.h:312
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
u16 ee_cck_ofdm_gain_delta
Definition: eeprom.h:389
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct bofm_section_header done
Definition: bofm_test.c:46
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_GAIN_CCK_PROBE_CORR, AR5K_GAIN_CHECK_ADJUST, AR5K_PHY_PAPD_PROBE, AR5K_PHY_PAPD_PROBE_GAINF_S, AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE_TYPE, AR5K_PHY_PAPD_PROBE_TYPE_CCK, AR5K_REG_MS, AR5K_RFGAIN_ACTIVE, AR5K_RFGAIN_INACTIVE, AR5K_RFGAIN_NEED_CHANGE, AR5K_RFGAIN_READ_REQUESTED, AR5K_SREV_RAD_5112A, ath5k_hw_reg_read(), ath5k_hw_rf_check_gainf_readback(), ath5k_hw_rf_gainf_adjust(), ath5k_hw_rf_gainf_corr(), data, done, ath5k_eeprom_info::ee_cck_ofdm_gain_delta, NULL, and type.

Referenced by ath5k_calibrate(), and ath5k_hw_reset().

◆ ath5k_hw_rfgain_init()

int ath5k_hw_rfgain_init ( struct ath5k_hw ah,
unsigned int  freq 
)

Definition at line 452 of file ath5k_phy.c.

453 {
454  const struct ath5k_ini_rfgain *ath5k_rfg;
455  unsigned int i, size;
456 
457  switch (ah->ah_radio) {
458  case AR5K_RF5111:
459  ath5k_rfg = rfgain_5111;
461  break;
462  case AR5K_RF5112:
463  ath5k_rfg = rfgain_5112;
465  break;
466  case AR5K_RF2413:
467  ath5k_rfg = rfgain_2413;
469  break;
470  case AR5K_RF2316:
471  ath5k_rfg = rfgain_2316;
473  break;
474  case AR5K_RF5413:
475  ath5k_rfg = rfgain_5413;
477  break;
478  case AR5K_RF2317:
479  case AR5K_RF2425:
480  ath5k_rfg = rfgain_2425;
482  break;
483  default:
484  return -EINVAL;
485  }
486 
487  switch (freq) {
490  break;
491  default:
492  return -EINVAL;
493  }
494 
495  for (i = 0; i < size; i++) {
496  AR5K_REG_WAIT(i);
497  ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
498  (u32)ath5k_rfg[i].rfg_register);
499  }
500 
501  return 0;
502 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
u16 rfg_register
Definition: rfgain.h:27
#define AR5K_REG_WAIT(_i)
Definition: ath5k.h:133
#define AR5K_INI_RFGAIN_5GHZ
Definition: ath5k.h:139
static const struct ath5k_ini_rfgain rfgain_2425[]
Definition: rfgain.h:377
static const struct ath5k_ini_rfgain rfgain_2316[]
Definition: rfgain.h:238
static const struct ath5k_ini_rfgain rfgain_5112[]
Definition: rfgain.h:101
static const struct ath5k_ini_rfgain rfgain_2413[]
Definition: rfgain.h:170
#define ARRAY_SIZE(x)
Definition: efx_common.h:43
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_INI_RFGAIN_2GHZ
Definition: ath5k.h:140
static const struct ath5k_ini_rfgain rfgain_5111[]
Definition: rfgain.h:32
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
uint8_t ah
Definition: registers.h:85
u32 rfg_value[2]
Definition: rfgain.h:28
static const struct ath5k_ini_rfgain rfgain_5413[]
Definition: rfgain.h:307
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_INI_RFGAIN_2GHZ, AR5K_INI_RFGAIN_5GHZ, AR5K_REG_WAIT, AR5K_RF2316, AR5K_RF2317, AR5K_RF2413, AR5K_RF2425, AR5K_RF5111, AR5K_RF5112, AR5K_RF5413, ARRAY_SIZE, ath5k_hw_reg_write(), EINVAL, ath5k_ini_rfgain::rfg_register, ath5k_ini_rfgain::rfg_value, rfgain_2316, rfgain_2413, rfgain_2425, rfgain_5111, rfgain_5112, rfgain_5413, and size.

Referenced by ath5k_hw_reset().

◆ ath5k_hw_rfregs_init()

int ath5k_hw_rfregs_init ( struct ath5k_hw ah,
struct net80211_channel channel,
unsigned int  mode 
)

Definition at line 514 of file ath5k_phy.c.

516 {
517  const struct ath5k_rf_reg *rf_regs;
518  const struct ath5k_ini_rfbuffer *ini_rfb;
519  const struct ath5k_gain_opt *go = NULL;
520  const struct ath5k_gain_opt_step *g_step;
521  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
522  u8 ee_mode = 0;
523  u32 *rfb;
524  int obdb = -1, bank = -1;
525  unsigned i;
526 
527  switch (ah->ah_radio) {
528  case AR5K_RF5111:
529  rf_regs = rf_regs_5111;
530  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
531  ini_rfb = rfb_5111;
532  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
533  go = &rfgain_opt_5111;
534  break;
535  case AR5K_RF5112:
536  if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
537  rf_regs = rf_regs_5112a;
538  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
539  ini_rfb = rfb_5112a;
540  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
541  } else {
542  rf_regs = rf_regs_5112;
543  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
544  ini_rfb = rfb_5112;
545  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
546  }
547  go = &rfgain_opt_5112;
548  break;
549  case AR5K_RF2413:
550  rf_regs = rf_regs_2413;
551  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
552  ini_rfb = rfb_2413;
553  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
554  break;
555  case AR5K_RF2316:
556  rf_regs = rf_regs_2316;
557  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
558  ini_rfb = rfb_2316;
559  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
560  break;
561  case AR5K_RF5413:
562  rf_regs = rf_regs_5413;
563  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
564  ini_rfb = rfb_5413;
565  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
566  break;
567  case AR5K_RF2317:
568  rf_regs = rf_regs_2425;
569  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
570  ini_rfb = rfb_2317;
571  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
572  break;
573  case AR5K_RF2425:
574  rf_regs = rf_regs_2425;
575  ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
576  if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
577  ini_rfb = rfb_2425;
578  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
579  } else {
580  ini_rfb = rfb_2417;
581  ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
582  }
583  break;
584  default:
585  return -EINVAL;
586  }
587 
588  /* If it's the first time we set rf buffer, allocate
589  * ah->ah_rf_banks based on ah->ah_rf_banks_size
590  * we set above */
591  if (ah->ah_rf_banks == NULL) {
592  ah->ah_rf_banks = malloc(sizeof(u32) * ah->ah_rf_banks_size);
593  if (ah->ah_rf_banks == NULL) {
594  return -ENOMEM;
595  }
596  }
597 
598  /* Copy values to modify them */
599  rfb = ah->ah_rf_banks;
600 
601  for (i = 0; i < ah->ah_rf_banks_size; i++) {
602  if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
603  DBG("ath5k: invalid RF register bank\n");
604  return -EINVAL;
605  }
606 
607  /* Bank changed, write down the offset */
608  if (bank != ini_rfb[i].rfb_bank) {
609  bank = ini_rfb[i].rfb_bank;
610  ah->ah_offset[bank] = i;
611  }
612 
613  rfb[i] = ini_rfb[i].rfb_mode_data[mode];
614  }
615 
616  /* Set Output and Driver bias current (OB/DB) */
617  if (channel->hw_value & CHANNEL_2GHZ) {
618 
619  if (channel->hw_value & CHANNEL_CCK)
620  ee_mode = AR5K_EEPROM_MODE_11B;
621  else
622  ee_mode = AR5K_EEPROM_MODE_11G;
623 
624  /* For RF511X/RF211X combination we
625  * use b_OB and b_DB parameters stored
626  * in eeprom on ee->ee_ob[ee_mode][0]
627  *
628  * For all other chips we use OB/DB for 2Ghz
629  * stored in the b/g modal section just like
630  * 802.11a on ee->ee_ob[ee_mode][1] */
631  if ((ah->ah_radio == AR5K_RF5111) ||
632  (ah->ah_radio == AR5K_RF5112))
633  obdb = 0;
634  else
635  obdb = 1;
636 
637  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
638  AR5K_RF_OB_2GHZ, 1);
639 
640  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
641  AR5K_RF_DB_2GHZ, 1);
642 
643  /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
644  } else if ((channel->hw_value & CHANNEL_5GHZ) ||
645  (ah->ah_radio == AR5K_RF5111)) {
646 
647  /* For 11a, Turbo and XR we need to choose
648  * OB/DB based on frequency range */
649  ee_mode = AR5K_EEPROM_MODE_11A;
650  obdb = channel->center_freq >= 5725 ? 3 :
651  (channel->center_freq >= 5500 ? 2 :
652  (channel->center_freq >= 5260 ? 1 :
653  (channel->center_freq > 4000 ? 0 : -1)));
654 
655  if (obdb < 0)
656  return -EINVAL;
657 
658  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
659  AR5K_RF_OB_5GHZ, 1);
660 
661  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
662  AR5K_RF_DB_5GHZ, 1);
663  }
664 
665  g_step = &go->go_step[ah->ah_gain.g_step_idx];
666 
667  /* Bank Modifications (chip-specific) */
668  if (ah->ah_radio == AR5K_RF5111) {
669 
670  /* Set gain_F settings according to current step */
671  if (channel->hw_value & CHANNEL_OFDM) {
672 
675  g_step->gos_param[0]);
676 
677  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
678  AR5K_RF_PWD_90, 1);
679 
680  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
681  AR5K_RF_PWD_84, 1);
682 
683  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
684  AR5K_RF_RFGAIN_SEL, 1);
685 
686  /* We programmed gain_F parameters, switch back
687  * to active state */
688  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
689 
690  }
691 
692  /* Bank 6/7 setup */
693 
694  ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
695  AR5K_RF_PWD_XPD, 1);
696 
697  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
698  AR5K_RF_XPD_GAIN, 1);
699 
700  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
701  AR5K_RF_GAIN_I, 1);
702 
703  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
704  AR5K_RF_PLO_SEL, 1);
705 
706  /* TODO: Half/quarter channel support */
707  }
708 
709  if (ah->ah_radio == AR5K_RF5112) {
710 
711  /* Set gain_F settings according to current step */
712  if (channel->hw_value & CHANNEL_OFDM) {
713 
714  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
716 
717  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
718  AR5K_RF_PWD_138, 1);
719 
720  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
721  AR5K_RF_PWD_137, 1);
722 
723  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
724  AR5K_RF_PWD_136, 1);
725 
726  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
727  AR5K_RF_PWD_132, 1);
728 
729  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
730  AR5K_RF_PWD_131, 1);
731 
732  ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
733  AR5K_RF_PWD_130, 1);
734 
735  /* We programmed gain_F parameters, switch back
736  * to active state */
737  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
738  }
739 
740  /* Bank 6/7 setup */
741 
742  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
743  AR5K_RF_XPD_SEL, 1);
744 
745  if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
746  /* Rev. 1 supports only one xpd */
747  ath5k_hw_rfb_op(ah, rf_regs,
748  ee->ee_x_gain[ee_mode],
749  AR5K_RF_XPD_GAIN, 1);
750 
751  } else {
752  /* TODO: Set high and low gain bits */
753  ath5k_hw_rfb_op(ah, rf_regs,
754  ee->ee_x_gain[ee_mode],
755  AR5K_RF_PD_GAIN_LO, 1);
756  ath5k_hw_rfb_op(ah, rf_regs,
757  ee->ee_x_gain[ee_mode],
758  AR5K_RF_PD_GAIN_HI, 1);
759 
760  /* Lower synth voltage on Rev 2 */
761  ath5k_hw_rfb_op(ah, rf_regs, 2,
762  AR5K_RF_HIGH_VC_CP, 1);
763 
764  ath5k_hw_rfb_op(ah, rf_regs, 2,
765  AR5K_RF_MID_VC_CP, 1);
766 
767  ath5k_hw_rfb_op(ah, rf_regs, 2,
768  AR5K_RF_LOW_VC_CP, 1);
769 
770  ath5k_hw_rfb_op(ah, rf_regs, 2,
771  AR5K_RF_PUSH_UP, 1);
772 
773  /* Decrease power consumption on 5213+ BaseBand */
774  if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
775  ath5k_hw_rfb_op(ah, rf_regs, 1,
776  AR5K_RF_PAD2GND, 1);
777 
778  ath5k_hw_rfb_op(ah, rf_regs, 1,
779  AR5K_RF_XB2_LVL, 1);
780 
781  ath5k_hw_rfb_op(ah, rf_regs, 1,
782  AR5K_RF_XB5_LVL, 1);
783 
784  ath5k_hw_rfb_op(ah, rf_regs, 1,
785  AR5K_RF_PWD_167, 1);
786 
787  ath5k_hw_rfb_op(ah, rf_regs, 1,
788  AR5K_RF_PWD_166, 1);
789  }
790  }
791 
792  ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
793  AR5K_RF_GAIN_I, 1);
794 
795  /* TODO: Half/quarter channel support */
796 
797  }
798 
799  if (ah->ah_radio == AR5K_RF5413 &&
800  channel->hw_value & CHANNEL_2GHZ) {
801 
803  1);
804 
805  /* Set optimum value for early revisions (on pci-e chips) */
806  if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
807  ah->ah_mac_srev < AR5K_SREV_AR5413)
808  ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
810 
811  }
812 
813  /* Write RF banks on hw */
814  for (i = 0; i < ah->ah_rf_banks_size; i++) {
815  AR5K_REG_WAIT(i);
816  ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
817  }
818 
819  return 0;
820 }
static const struct ath5k_rf_reg rf_regs_2413[]
Definition: rfbuffer.h:643
#define EINVAL
Invalid argument.
Definition: errno.h:428
static const struct ath5k_rf_reg rf_regs_5112a[]
Definition: rfbuffer.h:479
#define AR5K_PHY_FRAME_CTL
Definition: reg.h:2273
static const struct ath5k_rf_reg rf_regs_5112[]
Definition: rfbuffer.h:309
#define AR5K_EEPROM_MODE_11G
Definition: eeprom.h:64
#define AR5K_REG_WAIT(_i)
Definition: ath5k.h:133
#define AR5K_EEPROM_MODE_11A
Definition: eeprom.h:62
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1265
static const struct ath5k_rf_reg rf_regs_2425[]
Definition: rfbuffer.h:938
static const struct ath5k_ini_rfbuffer rfb_5413[]
Definition: rfbuffer.h:837
#define AR5K_MAX_RF_BANKS
Definition: ath5k.h:950
static const struct ath5k_ini_rfbuffer rfb_2417[]
Definition: rfbuffer.h:1107
u16 ee_x_gain[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:410
u32 rfb_mode_data[5]
Definition: rfbuffer.h:54
#define AR5K_SREV_AR5424
Definition: ath5k.h:298
#define AR5K_SREV_AR2417
Definition: ath5k.h:305
static const struct ath5k_gain_opt rfgain_opt_5111
Definition: rfgain.h:476
const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT]
Definition: rfgain.h:466
u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]
Definition: eeprom.h:403
#define CHANNEL_CCK
Definition: ath5k.h:630
#define ENOMEM
Not enough space.
Definition: errno.h:534
static const struct ath5k_rf_reg rf_regs_5413[]
Definition: rfbuffer.h:827
static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs, u32 val, u8 reg_id, int set)
Definition: ath5k_phy.c:51
#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val)
Definition: ath5k.h:96
static const struct ath5k_ini_rfbuffer rfb_2316[]
Definition: rfbuffer.h:737
s8 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS]
Definition: rfgain.h:459
#define AR5K_SREV_AR5413
Definition: ath5k.h:299
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
static const struct ath5k_ini_rfbuffer rfb_5112[]
Definition: rfbuffer.h:337
static const struct ath5k_rf_reg rf_regs_2316[]
Definition: rfbuffer.h:731
static const struct ath5k_ini_rfbuffer rfb_2425[]
Definition: rfbuffer.h:946
#define AR5K_EEPROM_MODE_11B
Definition: eeprom.h:63
#define ARRAY_SIZE(x)
Definition: efx_common.h:43
static const struct ath5k_gain_opt rfgain_opt_5112
Definition: rfgain.h:502
#define CHANNEL_OFDM
Definition: ath5k.h:631
static const struct ath5k_rf_reg rf_regs_5111[]
Definition: rfbuffer.h:160
u16 ee_i_gain[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:411
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
static const struct ath5k_ini_rfbuffer rfb_2413[]
Definition: rfbuffer.h:651
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
u16 ee_xpd[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:409
static const struct ath5k_ini_rfbuffer rfb_5112a[]
Definition: rfbuffer.h:517
#define AR5K_SREV_RAD_5112A
Definition: ath5k.h:312
#define CHANNEL_5GHZ
Definition: ath5k.h:633
uint8_t ah
Definition: registers.h:85
#define AR5K_SREV_PHY_5212A
Definition: ath5k.h:327
u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]
Definition: eeprom.h:402
static const struct ath5k_ini_rfbuffer rfb_2317[]
Definition: rfbuffer.h:1026
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define CHANNEL_2GHZ
Definition: ath5k.h:632
#define AR5K_PHY_FRAME_CTL_TX_CLIP
Definition: reg.h:2276
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
static const struct ath5k_ini_rfbuffer rfb_5111[]
Definition: rfbuffer.h:179

References ah, AR5K_EEPROM_MODE_11A, AR5K_EEPROM_MODE_11B, AR5K_EEPROM_MODE_11G, AR5K_MAX_RF_BANKS, AR5K_PHY_FRAME_CTL, AR5K_PHY_FRAME_CTL_TX_CLIP, AR5K_REG_WAIT, AR5K_REG_WRITE_BITS, AR5K_RF2316, AR5K_RF2317, AR5K_RF2413, AR5K_RF2425, AR5K_RF5111, AR5K_RF5112, AR5K_RF5413, AR5K_RF_DB_2GHZ, AR5K_RF_DB_5GHZ, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF_GAIN_I, AR5K_RF_HIGH_VC_CP, AR5K_RF_LOW_VC_CP, AR5K_RF_MID_VC_CP, AR5K_RF_MIXGAIN_OVR, AR5K_RF_OB_2GHZ, AR5K_RF_OB_5GHZ, AR5K_RF_PAD2GND, AR5K_RF_PD_GAIN_HI, AR5K_RF_PD_GAIN_LO, AR5K_RF_PLO_SEL, AR5K_RF_PUSH_UP, AR5K_RF_PWD_130, AR5K_RF_PWD_131, AR5K_RF_PWD_132, AR5K_RF_PWD_136, AR5K_RF_PWD_137, AR5K_RF_PWD_138, AR5K_RF_PWD_166, AR5K_RF_PWD_167, AR5K_RF_PWD_84, AR5K_RF_PWD_90, AR5K_RF_PWD_ICLOBUF_2G, AR5K_RF_PWD_XPD, AR5K_RF_RFGAIN_SEL, AR5K_RF_XB2_LVL, AR5K_RF_XB5_LVL, AR5K_RF_XPD_GAIN, AR5K_RF_XPD_SEL, AR5K_RFGAIN_ACTIVE, AR5K_SREV_AR2417, AR5K_SREV_AR5413, AR5K_SREV_AR5424, AR5K_SREV_PHY_5212A, AR5K_SREV_RAD_5112A, ARRAY_SIZE, ath5k_hw_bitswap(), ath5k_hw_reg_write(), ath5k_hw_rfb_op(), channel, CHANNEL_2GHZ, CHANNEL_5GHZ, CHANNEL_CCK, CHANNEL_OFDM, DBG, ath5k_eeprom_info::ee_db, ath5k_eeprom_info::ee_i_gain, ath5k_eeprom_info::ee_ob, ath5k_eeprom_info::ee_x_gain, ath5k_eeprom_info::ee_xpd, EINVAL, ENOMEM, ath5k_gain_opt::go_step, ath5k_gain_opt_step::gos_param, malloc(), NULL, rf_regs_2316, rf_regs_2413, rf_regs_2425, rf_regs_5111, rf_regs_5112, rf_regs_5112a, rf_regs_5413, rfb_2316, rfb_2317, rfb_2413, rfb_2417, rfb_2425, rfb_5111, rfb_5112, rfb_5112a, rfb_5413, ath5k_ini_rfbuffer::rfb_bank, ath5k_ini_rfbuffer::rfb_mode_data, rfgain_opt_5111, and rfgain_opt_5112.

Referenced by ath5k_hw_reset().

◆ ath5k_channel_ok()

int ath5k_channel_ok ( struct ath5k_hw ah,
u16  freq,
unsigned int  flags 
)

Definition at line 830 of file ath5k_phy.c.

831 {
832  /* Check if the channel is in our supported range */
833  if (flags & CHANNEL_2GHZ) {
834  if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
835  (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
836  return 1;
837  } else if (flags & CHANNEL_5GHZ)
838  if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
839  (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
840  return 1;
841 
842  return 0;
843 }
#define CHANNEL_5GHZ
Definition: ath5k.h:633
uint8_t ah
Definition: registers.h:85
#define CHANNEL_2GHZ
Definition: ath5k.h:632
uint8_t flags
Flags.
Definition: ena.h:18

References ah, CHANNEL_2GHZ, CHANNEL_5GHZ, and flags.

Referenced by ath5k_copy_channels(), and ath5k_hw_channel().

◆ ath5k_hw_rf5110_chan2athchan()

static u32 ath5k_hw_rf5110_chan2athchan ( struct net80211_channel channel)
static

Definition at line 848 of file ath5k_phy.c.

849 {
850  u32 athchan;
851 
852  /*
853  * Convert IEEE channel/MHz to an internal channel value used
854  * by the AR5210 chipset. This has not been verified with
855  * newer chipsets like the AR5212A who have a completely
856  * different RF/PHY part.
857  */
858  athchan = (ath5k_hw_bitswap((ath5k_freq_to_channel(channel->center_freq)
859  - 24) / 2, 5) << 1)
860  | (1 << 6) | 0x1;
861  return athchan;
862 }
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1265
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
uint32_t u32
Definition: stdint.h:23

References ath5k_hw_bitswap(), and channel.

Referenced by ath5k_hw_rf5110_channel().

◆ ath5k_hw_rf5110_channel()

static int ath5k_hw_rf5110_channel ( struct ath5k_hw ah,
struct net80211_channel channel 
)
static

Definition at line 867 of file ath5k_phy.c.

869 {
870  u32 data;
871 
872  /*
873  * Set the channel and wait
874  */
878  mdelay(1);
879 
880  return 0;
881 }
#define AR5K_RF_BUFFER
Definition: reg.h:2125
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
static u32 ath5k_hw_rf5110_chan2athchan(struct net80211_channel *channel)
Definition: ath5k_phy.c:848
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ah
Definition: registers.h:85
uint32_t u32
Definition: stdint.h:23
#define AR5K_RF_BUFFER_CONTROL_0
Definition: reg.h:2126

References ah, AR5K_RF_BUFFER, AR5K_RF_BUFFER_CONTROL_0, ath5k_hw_reg_write(), ath5k_hw_rf5110_chan2athchan(), channel, data, and mdelay().

Referenced by ath5k_hw_channel().

◆ ath5k_hw_rf5111_chan2athchan()

static int ath5k_hw_rf5111_chan2athchan ( unsigned int  ieee,
struct ath5k_athchan_2ghz athchan 
)
static

Definition at line 886 of file ath5k_phy.c.

888 {
889  int channel;
890 
891  /* Cast this value to catch negative channel numbers (>= -19) */
892  channel = (int)ieee;
893 
894  /*
895  * Map 2GHz IEEE channel to 5GHz Atheros channel
896  */
897  if (channel <= 13) {
898  athchan->a2_athchan = 115 + channel;
899  athchan->a2_flags = 0x46;
900  } else if (channel == 14) {
901  athchan->a2_athchan = 124;
902  athchan->a2_flags = 0x44;
903  } else if (channel >= 15 && channel <= 26) {
904  athchan->a2_athchan = ((channel - 14) * 4) + 132;
905  athchan->a2_flags = 0x46;
906  } else
907  return -EINVAL;
908 
909  return 0;
910 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14

References ath5k_athchan_2ghz::a2_athchan, ath5k_athchan_2ghz::a2_flags, channel, and EINVAL.

Referenced by ath5k_hw_rf5111_channel().

◆ ath5k_hw_rf5111_channel()

static int ath5k_hw_rf5111_channel ( struct ath5k_hw ah,
struct net80211_channel channel 
)
static

Definition at line 915 of file ath5k_phy.c.

917 {
918  struct ath5k_athchan_2ghz ath5k_channel_2ghz;
919  unsigned int ath5k_channel = ath5k_freq_to_channel(channel->center_freq);
920  u32 data0, data1, clock;
921  int ret;
922 
923  /*
924  * Set the channel on the RF5111 radio
925  */
926  data0 = data1 = 0;
927 
928  if (channel->hw_value & CHANNEL_2GHZ) {
929  /* Map 2GHz channel to 5GHz Atheros channel ID */
930  ret = ath5k_hw_rf5111_chan2athchan(ath5k_channel,
931  &ath5k_channel_2ghz);
932  if (ret)
933  return ret;
934 
935  ath5k_channel = ath5k_channel_2ghz.a2_athchan;
936  data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
937  << 5) | (1 << 4);
938  }
939 
940  if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
941  clock = 1;
942  data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
943  (clock << 1) | (1 << 10) | 1;
944  } else {
945  clock = 0;
946  data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
947  << 2) | (clock << 1) | (1 << 10) | 1;
948  }
949 
950  ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
952  ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
954 
955  return 0;
956 }
u32 data1
Definition: ar9003_mac.h:71
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1265
#define AR5K_RF_BUFFER
Definition: reg.h:2125
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_RF_BUFFER_CONTROL_3
Definition: reg.h:2130
uint8_t ah
Definition: registers.h:85
u32 data0
Definition: ar9003_mac.h:69
#define CHANNEL_2GHZ
Definition: ath5k.h:632
uint32_t u32
Definition: stdint.h:23
static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee, struct ath5k_athchan_2ghz *athchan)
Definition: ath5k_phy.c:886

References ath5k_athchan_2ghz::a2_athchan, ath5k_athchan_2ghz::a2_flags, ah, AR5K_RF_BUFFER, AR5K_RF_BUFFER_CONTROL_3, ath5k_hw_bitswap(), ath5k_hw_reg_write(), ath5k_hw_rf5111_chan2athchan(), channel, CHANNEL_2GHZ, data0, and data1.

Referenced by ath5k_hw_channel().

◆ ath5k_hw_rf5112_channel()

static int ath5k_hw_rf5112_channel ( struct ath5k_hw ah,
struct net80211_channel channel 
)
static

Definition at line 961 of file ath5k_phy.c.

963 {
964  u32 data, data0, data1, data2;
965  u16 c;
966 
967  data = data0 = data1 = data2 = 0;
968  c = channel->center_freq;
969 
970  if (c < 4800) {
971  if (!((c - 2224) % 5)) {
972  data0 = ((2 * (c - 704)) - 3040) / 10;
973  data1 = 1;
974  } else if (!((c - 2192) % 5)) {
975  data0 = ((2 * (c - 672)) - 3040) / 10;
976  data1 = 0;
977  } else
978  return -EINVAL;
979 
980  data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
981  } else if ((c - (c % 5)) != 2 || c > 5435) {
982  if (!(c % 20) && c >= 5120) {
983  data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
984  data2 = ath5k_hw_bitswap(3, 2);
985  } else if (!(c % 10)) {
986  data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
987  data2 = ath5k_hw_bitswap(2, 2);
988  } else if (!(c % 5)) {
989  data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
990  data2 = ath5k_hw_bitswap(1, 2);
991  } else
992  return -EINVAL;
993  } else {
994  data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
995  data2 = ath5k_hw_bitswap(0, 2);
996  }
997 
998  data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
999 
1002 
1003  return 0;
1004 }
uint16_t u16
Definition: stdint.h:21
uint32_t c
Definition: md4.c:30
#define EINVAL
Invalid argument.
Definition: errno.h:428
u32 data1
Definition: ar9003_mac.h:71
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1265
#define AR5K_RF_BUFFER
Definition: reg.h:2125
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
#define AR5K_RF_BUFFER_CONTROL_5
Definition: reg.h:2139
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
u32 data2
Definition: ar9003_mac.h:73
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ah
Definition: registers.h:85
u32 data0
Definition: ar9003_mac.h:69
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_RF_BUFFER, AR5K_RF_BUFFER_CONTROL_5, ath5k_hw_bitswap(), ath5k_hw_reg_write(), c, channel, data, data0, data1, data2, and EINVAL.

Referenced by ath5k_hw_channel().

◆ ath5k_hw_rf2425_channel()

static int ath5k_hw_rf2425_channel ( struct ath5k_hw ah,
struct net80211_channel channel 
)
static

Definition at line 1009 of file ath5k_phy.c.

1011 {
1012  u32 data, data0, data2;
1013  u16 c;
1014 
1015  data = data0 = data2 = 0;
1016  c = channel->center_freq;
1017 
1018  if (c < 4800) {
1019  data0 = ath5k_hw_bitswap((c - 2272), 8);
1020  data2 = 0;
1021  /* ? 5GHz ? */
1022  } else if ((c - (c % 5)) != 2 || c > 5435) {
1023  if (!(c % 20) && c < 5120)
1024  data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1025  else if (!(c % 10))
1026  data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1027  else if (!(c % 5))
1028  data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1029  else
1030  return -EINVAL;
1031  data2 = ath5k_hw_bitswap(1, 2);
1032  } else {
1033  data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
1034  data2 = ath5k_hw_bitswap(0, 2);
1035  }
1036 
1037  data = (data0 << 4) | data2 << 2 | 0x1001;
1038 
1041 
1042  return 0;
1043 }
uint16_t u16
Definition: stdint.h:21
uint32_t c
Definition: md4.c:30
#define EINVAL
Invalid argument.
Definition: errno.h:428
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1265
#define AR5K_RF_BUFFER
Definition: reg.h:2125
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
#define AR5K_RF_BUFFER_CONTROL_5
Definition: reg.h:2139
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
u32 data2
Definition: ar9003_mac.h:73
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ah
Definition: registers.h:85
u32 data0
Definition: ar9003_mac.h:69
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_RF_BUFFER, AR5K_RF_BUFFER_CONTROL_5, ath5k_hw_bitswap(), ath5k_hw_reg_write(), c, channel, data, data0, data2, and EINVAL.

Referenced by ath5k_hw_channel().

◆ ath5k_hw_channel()

int ath5k_hw_channel ( struct ath5k_hw ah,
struct net80211_channel channel 
)

Definition at line 1048 of file ath5k_phy.c.

1049 {
1050  int ret;
1051  /*
1052  * Check bounds supported by the PHY (we don't care about regultory
1053  * restrictions at this point). Note: hw_value already has the band
1054  * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok()
1055  * of the band by that */
1056  if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) {
1057  DBG("ath5k: channel frequency (%d MHz) out of supported "
1058  "range\n", channel->center_freq);
1059  return -EINVAL;
1060  }
1061 
1062  /*
1063  * Set the channel and wait
1064  */
1065  switch (ah->ah_radio) {
1066  case AR5K_RF5110:
1068  break;
1069  case AR5K_RF5111:
1071  break;
1072  case AR5K_RF2425:
1074  break;
1075  default:
1077  break;
1078  }
1079 
1080  if (ret) {
1081  DBG("ath5k: setting channel failed: %s\n", strerror(ret));
1082  return ret;
1083  }
1084 
1085  /* Set JAPAN setting for channel 14 */
1086  if (channel->center_freq == 2484) {
1089  } else {
1092  }
1093 
1094  ah->ah_current_channel = channel;
1095  ah->ah_turbo = (channel->hw_value == CHANNEL_T ? 1 : 0);
1096 
1097  return 0;
1098 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:1009
static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:961
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:867
#define CHANNEL_T
Definition: ath5k.h:641
int ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
Definition: ath5k_phy.c:830
uint8_t ah
Definition: registers.h:85
#define AR5K_PHY_CCKTXCTL_WORLD
Definition: reg.h:2522
static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:915
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define AR5K_PHY_CCKTXCTL
Definition: reg.h:2521
#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:104
#define AR5K_PHY_CCKTXCTL_JAPAN
Definition: reg.h:2523

References ah, AR5K_PHY_CCKTXCTL, AR5K_PHY_CCKTXCTL_JAPAN, AR5K_PHY_CCKTXCTL_WORLD, AR5K_REG_ENABLE_BITS, AR5K_RF2425, AR5K_RF5110, AR5K_RF5111, ath5k_channel_ok(), ath5k_hw_rf2425_channel(), ath5k_hw_rf5110_channel(), ath5k_hw_rf5111_channel(), ath5k_hw_rf5112_channel(), channel, CHANNEL_T, DBG, EINVAL, and strerror().

Referenced by ath5k_hw_reset(), and ath5k_hw_rf5110_calibrate().

◆ ath5k_hw_noise_floor_calibration()

int ath5k_hw_noise_floor_calibration ( struct ath5k_hw ah,
short  freq 
)

ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration

@ah: struct ath5k_hw pointer we are operating on @freq: the channel frequency, just used for error logging

This function performs a noise floor calibration of the PHY and waits for it to complete. Then the noise floor value is compared to some maximum noise floor we consider valid.

Note that this is different from what the madwifi HAL does: it reads the noise floor and afterwards initiates the calibration. Since the noise floor calibration can take some time to finish, depending on the current channel use, that avoids the occasional timeout warnings we are seeing now.

See the following link for an Atheros patent on noise floor calibration: http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \ &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7

XXX: Since during noise floor calibration antennas are detached according to the patent, we should stop tx queues here.

Definition at line 1127 of file ath5k_phy.c.

1128 {
1129  int ret;
1130  unsigned int i;
1131  s32 noise_floor;
1132 
1133  /*
1134  * Enable noise floor calibration
1135  */
1138 
1139  ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1140  AR5K_PHY_AGCCTL_NF, 0, 0);
1141 
1142  if (ret) {
1143  DBG("ath5k: noise floor calibration timeout (%d MHz)\n", freq);
1144  return -EAGAIN;
1145  }
1146 
1147  /* Wait until the noise floor is calibrated and read the value */
1148  for (i = 20; i > 0; i--) {
1149  mdelay(1);
1150  noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1151  noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
1152  if (noise_floor & AR5K_PHY_NF_ACTIVE) {
1153  noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
1154 
1155  if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
1156  break;
1157  }
1158  }
1159 
1160  DBG2("ath5k: noise floor %d\n", noise_floor);
1161 
1162  if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
1163  DBG("ath5k: noise floor calibration failed (%d MHz)\n", freq);
1164  return -EAGAIN;
1165  }
1166 
1167  ah->ah_noise_floor = noise_floor;
1168 
1169  return 0;
1170 }
#define AR5K_PHY_AGCCTL_NF
Definition: reg.h:2030
int32_t s32
Definition: stdint.h:22
#define AR5K_PHY_NF_ACTIVE
Definition: reg.h:2039
#define AR5K_PHY_NF_RVAL(_n)
Definition: reg.h:2040
#define AR5K_PHY_NF_AVAL(_n)
Definition: reg.h:2041
#define AR5K_PHY_AGCCTL
Definition: reg.h:2028
#define AR5K_PHY_NF
Definition: reg.h:2037
#define EAGAIN
Resource temporarily unavailable.
Definition: errno.h:318
#define AR5K_TUNE_NOISE_FLOOR
Definition: ath5k.h:190
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define DBG2(...)
Definition: compiler.h:515
#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:104

References ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF, AR5K_PHY_NF, AR5K_PHY_NF_ACTIVE, AR5K_PHY_NF_AVAL, AR5K_PHY_NF_RVAL, AR5K_REG_ENABLE_BITS, AR5K_TUNE_NOISE_FLOOR, ath5k_hw_reg_read(), DBG, DBG2, EAGAIN, and mdelay().

Referenced by ath5k_hw_reset(), ath5k_hw_rf5110_calibrate(), and ath5k_hw_rf511x_calibrate().

◆ ath5k_hw_rf5110_calibrate()

static int ath5k_hw_rf5110_calibrate ( struct ath5k_hw ah,
struct net80211_channel channel 
)
static

Definition at line 1177 of file ath5k_phy.c.

1179 {
1180  u32 phy_sig, phy_agc, phy_sat, beacon;
1181  int ret;
1182 
1183  /*
1184  * Disable beacons and RX/TX queues, wait
1185  */
1190 
1191  mdelay(2);
1192 
1193  /*
1194  * Set the channel (with AGC turned off)
1195  */
1197  udelay(10);
1198  ret = ath5k_hw_channel(ah, channel);
1199 
1200  /*
1201  * Activate PHY and wait
1202  */
1204  mdelay(1);
1205 
1207 
1208  if (ret)
1209  return ret;
1210 
1211  /*
1212  * Calibrate the radio chip
1213  */
1214 
1215  /* Remember normal state */
1216  phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
1218  phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
1219 
1220  /* Update radio registers */
1221  ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
1223 
1228 
1233 
1234  udelay(20);
1235 
1237  udelay(10);
1240 
1241  mdelay(1);
1242 
1243  /*
1244  * Enable calibration and wait until completion
1245  */
1247 
1248  ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1249  AR5K_PHY_AGCCTL_CAL, 0, 0);
1250 
1251  /* Reset to normal state */
1252  ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
1255 
1256  if (ret) {
1257  DBG("ath5k: calibration timeout (%d MHz)\n",
1258  channel->center_freq);
1259  return ret;
1260  }
1261 
1263 
1264  /*
1265  * Re-enable RX/TX and beacons
1266  */
1270 
1271  return 0;
1272 }
#define AR5K_PHY_SIG_FIRPWR
Definition: reg.h:2012
#define AR5K_PHY_AGCCOARSE
Definition: reg.h:2019
#define AR5K_PHY_AGC_DISABLE
Definition: reg.h:1907
#define AR5K_BEACON_ENABLE
Definition: reg.h:1248
#define AR5K_PHY_ADCSAT
Definition: reg.h:2051
#define AR5K_PHY_AGCCTL_CAL
Definition: reg.h:2029
#define AR5K_BEACON_5210
Definition: reg.h:1240
#define AR5K_PHY_SIG
Definition: reg.h:2009
#define AR5K_PHY_AGCCOARSE_LO
Definition: reg.h:2020
#define AR5K_PHY_AGC
Definition: reg.h:1905
#define AR5K_PHY_AGCCTL
Definition: reg.h:2028
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
#define AR5K_PHY_RFSTG
Definition: reg.h:2149
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
int ath5k_hw_channel(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:1048
#define AR5K_PHY_RFSTG_DISABLE
Definition: reg.h:2150
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:107
#define AR5K_DIAG_SW_5210
Definition: reg.h:1390
int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
Definition: ath5k_phy.c:1127
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_DIAG_SW_DIS_TX
Definition: reg.h:1399
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define AR5K_PHY_ADCSAT_THR
Definition: reg.h:2054
#define AR5K_PHY_AGCCOARSE_HI
Definition: reg.h:2022
#define AR5K_PHY_ADCSAT_ICNT
Definition: reg.h:2052
uint32_t u32
Definition: stdint.h:23
#define AR5K_PHY_ACT_ENABLE
Definition: reg.h:1933
#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:104
#define AR5K_PHY_ACT
Definition: reg.h:1932
#define AR5K_DIAG_SW_DIS_RX_5210
Definition: reg.h:1400
#define AR5K_REG_SM(_val, _flags)
Definition: ath5k.h:84

References ah, AR5K_BEACON_5210, AR5K_BEACON_ENABLE, AR5K_DIAG_SW_5210, AR5K_DIAG_SW_DIS_RX_5210, AR5K_DIAG_SW_DIS_TX, AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ADCSAT, AR5K_PHY_ADCSAT_ICNT, AR5K_PHY_ADCSAT_THR, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, AR5K_PHY_AGCCOARSE_LO, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL, AR5K_PHY_RFSTG, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, AR5K_REG_DISABLE_BITS, AR5K_REG_ENABLE_BITS, AR5K_REG_SM, ath5k_hw_channel(), ath5k_hw_noise_floor_calibration(), ath5k_hw_reg_read(), ath5k_hw_reg_write(), channel, DBG, mdelay(), and udelay().

Referenced by ath5k_hw_phy_calibrate().

◆ ath5k_hw_rf511x_calibrate()

static int ath5k_hw_rf511x_calibrate ( struct ath5k_hw ah,
struct net80211_channel channel 
)
static

Definition at line 1277 of file ath5k_phy.c.

1279 {
1280  u32 i_pwr, q_pwr;
1281  s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1282  int i;
1283 
1284  if (!ah->ah_calibration ||
1286  goto done;
1287 
1288  /* Calibration has finished, get the results and re-run */
1289  for (i = 0; i <= 10; i++) {
1293  }
1294 
1295  i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1296  q_coffd = q_pwr >> 7;
1297 
1298  /* No correction */
1299  if (i_coffd == 0 || q_coffd == 0)
1300  goto done;
1301 
1302  i_coff = ((-iq_corr) / i_coffd) & 0x3f;
1303 
1304  /* Boundary check */
1305  if (i_coff > 31)
1306  i_coff = 31;
1307  if (i_coff < -32)
1308  i_coff = -32;
1309 
1310  q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
1311 
1312  /* Boundary check */
1313  if (q_coff > 15)
1314  q_coff = 15;
1315  if (q_coff < -16)
1316  q_coff = -16;
1317 
1318  /* Commit new I/Q value */
1320  ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
1321 
1322  /* Re-enable calibration -if we don't we'll commit
1323  * the same values again and again */
1327 
1328 done:
1329 
1330  /* TODO: Separate noise floor calibration from I/Q calibration
1331  * since noise floor calibration interrupts rx path while I/Q
1332  * calibration doesn't. We don't need to run noise floor calibration
1333  * as often as I/Q calibration.*/
1335 
1336  /* Initiate a gain_F calibration */
1338 
1339  return 0;
1340 }
#define AR5K_PHY_IQRES_CAL_CORR
Definition: reg.h:2418
int32_t s32
Definition: stdint.h:22
#define AR5K_PHY_IQ_CORR_ENABLE
Definition: reg.h:2194
#define AR5K_PHY_IQ
Definition: reg.h:2190
#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val)
Definition: ath5k.h:96
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
Definition: ath5k_phy.c:194
#define AR5K_PHY_IQ_CAL_NUM_LOG_MAX
Definition: reg.h:2195
#define AR5K_PHY_IQ_CORR_Q_I_COFF_S
Definition: reg.h:2193
#define AR5K_PHY_IQRES_CAL_PWR_I
Definition: reg.h:2416
int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
Definition: ath5k_phy.c:1127
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_PHY_IQ_RUN
Definition: reg.h:2197
#define AR5K_PHY_IQRES_CAL_PWR_Q
Definition: reg.h:2417
struct bofm_section_header done
Definition: bofm_test.c:46
uint32_t u32
Definition: stdint.h:23
#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:104

References ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CAL_NUM_LOG_MAX, AR5K_PHY_IQ_CORR_ENABLE, AR5K_PHY_IQ_CORR_Q_I_COFF_S, AR5K_PHY_IQ_RUN, AR5K_PHY_IQRES_CAL_CORR, AR5K_PHY_IQRES_CAL_PWR_I, AR5K_PHY_IQRES_CAL_PWR_Q, AR5K_REG_ENABLE_BITS, AR5K_REG_WRITE_BITS, ath5k_hw_noise_floor_calibration(), ath5k_hw_reg_read(), ath5k_hw_request_rfgain_probe(), channel, and done.

Referenced by ath5k_hw_phy_calibrate().

◆ ath5k_hw_phy_calibrate()

int ath5k_hw_phy_calibrate ( struct ath5k_hw ah,
struct net80211_channel channel 
)

Definition at line 1345 of file ath5k_phy.c.

1347 {
1348  int ret;
1349 
1350  if (ah->ah_radio == AR5K_RF5110)
1352  else
1354 
1355  return ret;
1356 }
static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:1177
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:1277
uint8_t ah
Definition: registers.h:85

References ah, AR5K_RF5110, ath5k_hw_rf5110_calibrate(), ath5k_hw_rf511x_calibrate(), and channel.

Referenced by ath5k_calibrate().

◆ ath5k_hw_phy_disable()

int ath5k_hw_phy_disable ( struct ath5k_hw ah)

Definition at line 1358 of file ath5k_phy.c.

1359 {
1361 
1362  return 0;
1363 }
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_PHY_ACT_DISABLE
Definition: reg.h:1934
uint8_t ah
Definition: registers.h:85
#define AR5K_PHY_ACT
Definition: reg.h:1932

References ah, AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE, and ath5k_hw_reg_write().

Referenced by ath5k_stop_hw().

◆ ath5k_hw_radio_revision()

u16 ath5k_hw_radio_revision ( struct ath5k_hw ah,
unsigned int  chan 
)

Definition at line 1372 of file ath5k_phy.c.

1373 {
1374  unsigned int i;
1375  u32 srev;
1376  u16 ret;
1377 
1378  /*
1379  * Set the radio chip access register
1380  */
1381  switch (chan) {
1382  case CHANNEL_2GHZ:
1384  break;
1385  case CHANNEL_5GHZ:
1387  break;
1388  default:
1389  return 0;
1390  }
1391 
1392  mdelay(2);
1393 
1394  /* ...wait until PHY is ready and read the selected radio revision */
1395  ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
1396 
1397  for (i = 0; i < 8; i++)
1398  ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
1399 
1400  if (ah->ah_version == AR5K_AR5210) {
1401  srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
1402  ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
1403  } else {
1404  srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
1405  ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
1406  ((srev & 0x0f) << 4), 8);
1407  }
1408 
1409  /* Reset to the 5GHz mode */
1411 
1412  return ret;
1413 }
#define AR5K_PHY_SHIFT_5GHZ
Definition: reg.h:1884
#define u16
Definition: vga.h:20
uint16_t u16
Definition: stdint.h:21
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1265
#define AR5K_PHY_SHIFT_2GHZ
Definition: reg.h:1883
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
#define AR5K_PHY(_n)
Definition: reg.h:1861
#define CHANNEL_5GHZ
Definition: ath5k.h:633
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define CHANNEL_2GHZ
Definition: ath5k.h:632
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_AR5210, AR5K_PHY, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY_SHIFT_5GHZ, ath5k_hw_bitswap(), ath5k_hw_reg_read(), ath5k_hw_reg_write(), CHANNEL_2GHZ, CHANNEL_5GHZ, mdelay(), and u16.

Referenced by ath5k_hw_attach().

◆ ath5k_hw_set_def_antenna()

void ath5k_hw_set_def_antenna ( struct ath5k_hw ah,
unsigned int  ant 
)

Definition at line 1416 of file ath5k_phy.c.

1417 {
1418  if (ah->ah_version != AR5K_AR5210)
1420 }
#define AR5K_DEFAULT_ANTENNA
Definition: reg.h:1476
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
uint8_t ah
Definition: registers.h:85

References ah, AR5K_AR5210, AR5K_DEFAULT_ANTENNA, and ath5k_hw_reg_write().

◆ ath5k_hw_get_def_antenna()

unsigned int ath5k_hw_get_def_antenna ( struct ath5k_hw ah)

Definition at line 1422 of file ath5k_phy.c.

1423 {
1424  if (ah->ah_version != AR5K_AR5210)
1426 
1427  return 0; /*XXX: What do we return for 5210 ?*/
1428 }
#define AR5K_DEFAULT_ANTENNA
Definition: reg.h:1476
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214

References ah, AR5K_AR5210, AR5K_DEFAULT_ANTENNA, and ath5k_hw_reg_read().

◆ ath5k_get_interpolated_value()

static s16 ath5k_get_interpolated_value ( s16  target,
s16  x_left,
s16  x_right,
s16  y_left,
s16  y_right 
)
static

Definition at line 1443 of file ath5k_phy.c.

1445 {
1446  s16 ratio, result;
1447 
1448  /* Avoid divide by zero and skip interpolation
1449  * if we have the same point */
1450  if ((x_left == x_right) || (y_left == y_right))
1451  return y_left;
1452 
1453  /*
1454  * Since we use ints and not fps, we need to scale up in
1455  * order to get a sane ratio value (or else we 'll eg. get
1456  * always 1 instead of 1.25, 1.75 etc). We scale up by 100
1457  * to have some accuracy both for 0.5 and 0.25 steps.
1458  */
1459  ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
1460 
1461  /* Now scale down to be in range */
1462  result = y_left + (ratio * (target - x_left) / 100);
1463 
1464  return result;
1465 }
int16_t s16
Definition: stdint.h:20
static const void const void void * result
Definition: crypto.h:335

References result.

Referenced by ath5k_create_power_curve(), ath5k_get_linear_pcdac_min(), ath5k_get_rate_pcal_data(), and ath5k_setup_channel_powertable().

◆ ath5k_get_linear_pcdac_min()

static s16 ath5k_get_linear_pcdac_min ( const u8 stepL,
const u8 stepR,
const s16 pwrL,
const s16 pwrR 
)
static

Definition at line 1476 of file ath5k_phy.c.

1478 {
1479  s8 tmp;
1480  s16 min_pwrL, min_pwrR;
1481  s16 pwr_i;
1482 
1483  if (pwrL[0] == pwrL[1])
1484  min_pwrL = pwrL[0];
1485  else {
1486  pwr_i = pwrL[0];
1487  do {
1488  pwr_i--;
1490  pwrL[0], pwrL[1],
1491  stepL[0], stepL[1]);
1492  } while (tmp > 1);
1493 
1494  min_pwrL = pwr_i;
1495  }
1496 
1497  if (pwrR[0] == pwrR[1])
1498  min_pwrR = pwrR[0];
1499  else {
1500  pwr_i = pwrR[0];
1501  do {
1502  pwr_i--;
1504  pwrR[0], pwrR[1],
1505  stepR[0], stepR[1]);
1506  } while (tmp > 1);
1507 
1508  min_pwrR = pwr_i;
1509  }
1510 
1511  /* Keep the right boundary so that it works for both curves */
1512  return max(min_pwrL, min_pwrR);
1513 }
int8_t s8
Definition: stdint.h:18
int16_t s16
Definition: stdint.h:20
static int max(int x, int y)
Definition: ath5k_phy.c:43
unsigned long tmp
Definition: linux_pci.h:53
static s16 ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right, s16 y_left, s16 y_right)
Definition: ath5k_phy.c:1443

References ath5k_get_interpolated_value(), max(), and tmp.

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_create_power_curve()

static void ath5k_create_power_curve ( s16  pmin,
s16  pmax,
const s16 pwr,
const u8 vpd,
u8  num_points,
u8 vpd_table,
u8  type 
)
static

Definition at line 1528 of file ath5k_phy.c.

1532 {
1533  u8 idx[2] = { 0, 1 };
1534  s16 pwr_i = 2*pmin;
1535  int i;
1536 
1537  if (num_points < 2)
1538  return;
1539 
1540  /* We want the whole line, so adjust boundaries
1541  * to cover the entire power range. Note that
1542  * power values are already 0.25dB so no need
1543  * to multiply pwr_i by 2 */
1545  pwr_i = pmin;
1546  pmin = 0;
1547  pmax = 63;
1548  }
1549 
1550  /* Find surrounding turning points (TPs)
1551  * and interpolate between them */
1552  for (i = 0; (i <= (u16) (pmax - pmin)) &&
1553  (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
1554 
1555  /* We passed the right TP, move to the next set of TPs
1556  * if we pass the last TP, extrapolate above using the last
1557  * two TPs for ratio */
1558  if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
1559  idx[0]++;
1560  idx[1]++;
1561  }
1562 
1563  vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
1564  pwr[idx[0]], pwr[idx[1]],
1565  vpd[idx[0]], vpd[idx[1]]);
1566 
1567  /* Increase by 0.5dB
1568  * (0.25 dB units) */
1569  pwr_i += 2;
1570  }
1571 }
#define u16
Definition: vga.h:20
int16_t s16
Definition: stdint.h:20
#define AR5K_EEPROM_POWER_TABLE_SIZE
Definition: eeprom.h:215
static s16 ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right, s16 y_left, s16 y_right)
Definition: ath5k_phy.c:1443
#define u8
Definition: igbvf_osdep.h:38
uint32_t type
Operating system type.
Definition: ena.h:12
uint8_t u8
Definition: stdint.h:19

References AR5K_EEPROM_POWER_TABLE_SIZE, AR5K_PWRTABLE_LINEAR_PCDAC, ath5k_get_interpolated_value(), type, u16, and u8.

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_get_chan_pcal_surrounding_piers()

static void ath5k_get_chan_pcal_surrounding_piers ( struct ath5k_hw ah,
struct net80211_channel channel,
struct ath5k_chan_pcal_info **  pcinfo_l,
struct ath5k_chan_pcal_info **  pcinfo_r 
)
static

Definition at line 1580 of file ath5k_phy.c.

1584 {
1585  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1586  struct ath5k_chan_pcal_info *pcinfo;
1587  u8 idx_l, idx_r;
1588  u8 mode, max, i;
1589  u32 target = channel->center_freq;
1590 
1591  idx_l = 0;
1592  idx_r = 0;
1593 
1594  if (!(channel->hw_value & CHANNEL_OFDM)) {
1595  pcinfo = ee->ee_pwr_cal_b;
1596  mode = AR5K_EEPROM_MODE_11B;
1597  } else if (channel->hw_value & CHANNEL_2GHZ) {
1598  pcinfo = ee->ee_pwr_cal_g;
1599  mode = AR5K_EEPROM_MODE_11G;
1600  } else {
1601  pcinfo = ee->ee_pwr_cal_a;
1602  mode = AR5K_EEPROM_MODE_11A;
1603  }
1604  max = ee->ee_n_piers[mode] - 1;
1605 
1606  /* Frequency is below our calibrated
1607  * range. Use the lowest power curve
1608  * we have */
1609  if (target < pcinfo[0].freq) {
1610  idx_l = idx_r = 0;
1611  goto done;
1612  }
1613 
1614  /* Frequency is above our calibrated
1615  * range. Use the highest power curve
1616  * we have */
1617  if (target > pcinfo[max].freq) {
1618  idx_l = idx_r = max;
1619  goto done;
1620  }
1621 
1622  /* Frequency is inside our calibrated
1623  * channel range. Pick the surrounding
1624  * calibration piers so that we can
1625  * interpolate */
1626  for (i = 0; i <= max; i++) {
1627 
1628  /* Frequency matches one of our calibration
1629  * piers, no need to interpolate, just use
1630  * that calibration pier */
1631  if (pcinfo[i].freq == target) {
1632  idx_l = idx_r = i;
1633  goto done;
1634  }
1635 
1636  /* We found a calibration pier that's above
1637  * frequency, use this pier and the previous
1638  * one to interpolate */
1639  if (target < pcinfo[i].freq) {
1640  idx_r = i;
1641  idx_l = idx_r - 1;
1642  goto done;
1643  }
1644  }
1645 
1646 done:
1647  *pcinfo_l = &pcinfo[idx_l];
1648  *pcinfo_r = &pcinfo[idx_r];
1649 
1650  return;
1651 }
#define AR5K_EEPROM_MODE_11G
Definition: eeprom.h:64
#define AR5K_EEPROM_MODE_11A
Definition: eeprom.h:62
static int max(int x, int y)
Definition: ath5k_phy.c:43
struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:427
struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:428
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
u8 ee_n_piers[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:425
#define AR5K_EEPROM_MODE_11B
Definition: eeprom.h:63
#define CHANNEL_OFDM
Definition: ath5k.h:631
struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN]
Definition: eeprom.h:426
uint8_t ah
Definition: registers.h:85
#define CHANNEL_2GHZ
Definition: ath5k.h:632
struct bofm_section_header done
Definition: bofm_test.c:46
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_EEPROM_MODE_11A, AR5K_EEPROM_MODE_11B, AR5K_EEPROM_MODE_11G, channel, CHANNEL_2GHZ, CHANNEL_OFDM, done, ath5k_eeprom_info::ee_n_piers, ath5k_eeprom_info::ee_pwr_cal_a, ath5k_eeprom_info::ee_pwr_cal_b, ath5k_eeprom_info::ee_pwr_cal_g, ath5k_chan_pcal_info::freq, and max().

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_get_rate_pcal_data()

static void ath5k_get_rate_pcal_data ( struct ath5k_hw ah,
struct net80211_channel channel,
struct ath5k_rate_pcal_info rates 
)
static

Definition at line 1660 of file ath5k_phy.c.

1663 {
1664  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1665  struct ath5k_rate_pcal_info *rpinfo;
1666  u8 idx_l, idx_r;
1667  u8 mode, max, i;
1668  u32 target = channel->center_freq;
1669 
1670  idx_l = 0;
1671  idx_r = 0;
1672 
1673  if (!(channel->hw_value & CHANNEL_OFDM)) {
1674  rpinfo = ee->ee_rate_tpwr_b;
1675  mode = AR5K_EEPROM_MODE_11B;
1676  } else if (channel->hw_value & CHANNEL_2GHZ) {
1677  rpinfo = ee->ee_rate_tpwr_g;
1678  mode = AR5K_EEPROM_MODE_11G;
1679  } else {
1680  rpinfo = ee->ee_rate_tpwr_a;
1681  mode = AR5K_EEPROM_MODE_11A;
1682  }
1683  max = ee->ee_rate_target_pwr_num[mode] - 1;
1684 
1685  /* Get the surrounding calibration
1686  * piers - same as above */
1687  if (target < rpinfo[0].freq) {
1688  idx_l = idx_r = 0;
1689  goto done;
1690  }
1691 
1692  if (target > rpinfo[max].freq) {
1693  idx_l = idx_r = max;
1694  goto done;
1695  }
1696 
1697  for (i = 0; i <= max; i++) {
1698 
1699  if (rpinfo[i].freq == target) {
1700  idx_l = idx_r = i;
1701  goto done;
1702  }
1703 
1704  if (target < rpinfo[i].freq) {
1705  idx_r = i;
1706  idx_l = idx_r - 1;
1707  goto done;
1708  }
1709  }
1710 
1711 done:
1712  /* Now interpolate power value, based on the frequency */
1713  rates->freq = target;
1714 
1715  rates->target_power_6to24 =
1716  ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1717  rpinfo[idx_r].freq,
1718  rpinfo[idx_l].target_power_6to24,
1719  rpinfo[idx_r].target_power_6to24);
1720 
1721  rates->target_power_36 =
1722  ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1723  rpinfo[idx_r].freq,
1724  rpinfo[idx_l].target_power_36,
1725  rpinfo[idx_r].target_power_36);
1726 
1727  rates->target_power_48 =
1728  ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1729  rpinfo[idx_r].freq,
1730  rpinfo[idx_l].target_power_48,
1731  rpinfo[idx_r].target_power_48);
1732 
1733  rates->target_power_54 =
1734  ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
1735  rpinfo[idx_r].freq,
1736  rpinfo[idx_l].target_power_54,
1737  rpinfo[idx_r].target_power_54);
1738 }
#define AR5K_EEPROM_MODE_11G
Definition: eeprom.h:64
#define AR5K_EEPROM_MODE_11A
Definition: eeprom.h:62
u8 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:431
static int max(int x, int y)
Definition: ath5k_phy.c:43
static s16 ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right, s16 y_left, s16 y_right)
Definition: ath5k_phy.c:1443
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
#define AR5K_EEPROM_MODE_11B
Definition: eeprom.h:63
#define CHANNEL_OFDM
Definition: ath5k.h:631
struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:433
u8 rates[0]
Rates data, one rate per byte.
Definition: ieee80211.h:16
struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN]
Definition: eeprom.h:432
struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]
Definition: eeprom.h:434
uint8_t ah
Definition: registers.h:85
#define CHANNEL_2GHZ
Definition: ath5k.h:632
struct bofm_section_header done
Definition: bofm_test.c:46
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_EEPROM_MODE_11A, AR5K_EEPROM_MODE_11B, AR5K_EEPROM_MODE_11G, ath5k_get_interpolated_value(), channel, CHANNEL_2GHZ, CHANNEL_OFDM, done, ath5k_eeprom_info::ee_rate_target_pwr_num, ath5k_eeprom_info::ee_rate_tpwr_a, ath5k_eeprom_info::ee_rate_tpwr_b, ath5k_eeprom_info::ee_rate_tpwr_g, ath5k_rate_pcal_info::freq, max(), rates, ath5k_rate_pcal_info::target_power_36, ath5k_rate_pcal_info::target_power_48, ath5k_rate_pcal_info::target_power_54, and ath5k_rate_pcal_info::target_power_6to24.

Referenced by ath5k_hw_txpower().

◆ ath5k_get_max_ctl_power()

static void ath5k_get_max_ctl_power ( struct ath5k_hw ah,
struct net80211_channel channel 
)
static

Definition at line 1748 of file ath5k_phy.c.

1750 {
1751  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1752  struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
1753  u8 *ctl_val = ee->ee_ctl;
1754  s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
1755  s16 edge_pwr = 0;
1756  u8 rep_idx;
1757  u8 i, ctl_mode;
1758  u8 ctl_idx = 0xFF;
1759  u32 target = channel->center_freq;
1760 
1761  /* Find out a CTL for our mode that's not mapped
1762  * on a specific reg domain.
1763  *
1764  * TODO: Map our current reg domain to one of the 3 available
1765  * reg domain ids so that we can support more CTLs. */
1766  switch (channel->hw_value & CHANNEL_MODES) {
1767  case CHANNEL_A:
1768  ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
1769  break;
1770  case CHANNEL_G:
1771  ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
1772  break;
1773  case CHANNEL_B:
1774  ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
1775  break;
1776  case CHANNEL_T:
1778  break;
1779  case CHANNEL_TG:
1781  break;
1782  case CHANNEL_XR:
1783  /* Fall through */
1784  default:
1785  return;
1786  }
1787 
1788  for (i = 0; i < ee->ee_ctls; i++) {
1789  if (ctl_val[i] == ctl_mode) {
1790  ctl_idx = i;
1791  break;
1792  }
1793  }
1794 
1795  /* If we have a CTL dataset available grab it and find the
1796  * edge power for our frequency */
1797  if (ctl_idx == 0xFF)
1798  return;
1799 
1800  /* Edge powers are sorted by frequency from lower
1801  * to higher. Each CTL corresponds to 8 edge power
1802  * measurements. */
1803  rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
1804 
1805  /* Don't do boundaries check because we
1806  * might have more that one bands defined
1807  * for this mode */
1808 
1809  /* Get the edge power that's closer to our
1810  * frequency */
1811  for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
1812  rep_idx += i;
1813  if (target <= rep[rep_idx].freq)
1814  edge_pwr = (s16) rep[rep_idx].edge;
1815  }
1816 
1817  if (edge_pwr) {
1818  ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
1819  }
1820 }
int16_t s16
Definition: stdint.h:20
u8 ee_ctl[AR5K_EEPROM_MAX_CTLS]
Definition: eeprom.h:438
static int min(int x, int y)
Definition: ath5k_phy.c:38
#define CHANNEL_A
Definition: ath5k.h:638
#define CHANNEL_G
Definition: ath5k.h:640
#define CHANNEL_XR
Definition: ath5k.h:636
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
#define AR5K_EEPROM_N_EDGES
Definition: eeprom.h:189
#define CHANNEL_T
Definition: ath5k.h:641
#define CHANNEL_MODES
Definition: ath5k.h:651
uint8_t ah
Definition: registers.h:85
struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES *AR5K_EEPROM_MAX_CTLS]
Definition: eeprom.h:439
#define CHANNEL_B
Definition: ath5k.h:639
#define CHANNEL_TG
Definition: ath5k.h:642
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
#define AR5K_CTL_NO_REGDOMAIN
Definition: eeprom.h:269

References ah, AR5K_CTL_11A, AR5K_CTL_11B, AR5K_CTL_11G, AR5K_CTL_NO_REGDOMAIN, AR5K_CTL_TURBO, AR5K_CTL_TURBOG, AR5K_EEPROM_N_EDGES, channel, CHANNEL_A, CHANNEL_B, CHANNEL_G, CHANNEL_MODES, CHANNEL_T, CHANNEL_TG, CHANNEL_XR, ath5k_edge_power::edge, ath5k_eeprom_info::ee_ctl, ath5k_eeprom_info::ee_ctl_pwr, ath5k_eeprom_info::ee_ctls, ath5k_edge_power::freq, and min().

Referenced by ath5k_hw_txpower().

◆ ath5k_fill_pwr_to_pcdac_table()

static void ath5k_fill_pwr_to_pcdac_table ( struct ath5k_hw ah,
s16 table_min,
s16 table_max 
)
static

Definition at line 1835 of file ath5k_phy.c.

1837 {
1838  u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
1839  u8 *pcdac_tmp = ah->ah_txpower.tmpL[0];
1840  u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
1841  s16 min_pwr, max_pwr;
1842 
1843  /* Get table boundaries */
1844  min_pwr = table_min[0];
1845  pcdac_0 = pcdac_tmp[0];
1846 
1847  max_pwr = table_max[0];
1848  pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
1849 
1850  /* Extrapolate below minimum using pcdac_0 */
1851  pcdac_i = 0;
1852  for (i = 0; i < min_pwr; i++)
1853  pcdac_out[pcdac_i++] = pcdac_0;
1854 
1855  /* Copy values from pcdac_tmp */
1856  pwr_idx = min_pwr;
1857  for (i = 0 ; pwr_idx <= max_pwr &&
1858  pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
1859  pcdac_out[pcdac_i++] = pcdac_tmp[i];
1860  pwr_idx++;
1861  }
1862 
1863  /* Extrapolate above maximum */
1864  while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
1865  pcdac_out[pcdac_i++] = pcdac_n;
1866 
1867 }
int16_t s16
Definition: stdint.h:20
#define AR5K_EEPROM_POWER_TABLE_SIZE
Definition: eeprom.h:215
uint8_t ah
Definition: registers.h:85
uint8_t u8
Definition: stdint.h:19

References ah, and AR5K_EEPROM_POWER_TABLE_SIZE.

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_combine_linear_pcdac_curves()

static void ath5k_combine_linear_pcdac_curves ( struct ath5k_hw ah,
s16 table_min,
s16 table_max,
u8  pdcurves 
)
static

Definition at line 1881 of file ath5k_phy.c.

1883 {
1884  u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
1885  u8 *pcdac_low_pwr;
1886  u8 *pcdac_high_pwr;
1887  u8 *pcdac_tmp;
1888  u8 pwr;
1889  s16 max_pwr_idx;
1890  s16 min_pwr_idx;
1891  s16 mid_pwr_idx = 0;
1892  /* Edge flag turs on the 7nth bit on the PCDAC
1893  * to delcare the higher power curve (force values
1894  * to be greater than 64). If we only have one curve
1895  * we don't need to set this, if we have 2 curves and
1896  * fill the table backwards this can also be used to
1897  * switch from higher power curve to lower power curve */
1898  u8 edge_flag;
1899  int i;
1900 
1901  /* When we have only one curve available
1902  * that's the higher power curve. If we have
1903  * two curves the first is the high power curve
1904  * and the next is the low power curve. */
1905  if (pdcurves > 1) {
1906  pcdac_low_pwr = ah->ah_txpower.tmpL[1];
1907  pcdac_high_pwr = ah->ah_txpower.tmpL[0];
1908  mid_pwr_idx = table_max[1] - table_min[1] - 1;
1909  max_pwr_idx = (table_max[0] - table_min[0]) / 2;
1910 
1911  /* If table size goes beyond 31.5dB, keep the
1912  * upper 31.5dB range when setting tx power.
1913  * Note: 126 = 31.5 dB in quarter dB steps */
1914  if (table_max[0] - table_min[1] > 126)
1915  min_pwr_idx = table_max[0] - 126;
1916  else
1917  min_pwr_idx = table_min[1];
1918 
1919  /* Since we fill table backwards
1920  * start from high power curve */
1921  pcdac_tmp = pcdac_high_pwr;
1922 
1923  edge_flag = 0x40;
1924  } else {
1925  pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
1926  pcdac_high_pwr = ah->ah_txpower.tmpL[0];
1927  min_pwr_idx = table_min[0];
1928  max_pwr_idx = (table_max[0] - table_min[0]) / 2;
1929  pcdac_tmp = pcdac_high_pwr;
1930  edge_flag = 0;
1931  }
1932 
1933  /* This is used when setting tx power*/
1934  ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
1935 
1936  /* Fill Power to PCDAC table backwards */
1937  pwr = max_pwr_idx;
1938  for (i = 63; i >= 0; i--) {
1939  /* Entering lower power range, reset
1940  * edge flag and set pcdac_tmp to lower
1941  * power curve.*/
1942  if (edge_flag == 0x40 &&
1943  (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
1944  edge_flag = 0x00;
1945  pcdac_tmp = pcdac_low_pwr;
1946  pwr = mid_pwr_idx/2;
1947  }
1948 
1949  /* Don't go below 1, extrapolate below if we have
1950  * already swithced to the lower power curve -or
1951  * we only have one curve and edge_flag is zero
1952  * anyway */
1953  if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
1954  while (i >= 0) {
1955  pcdac_out[i] = pcdac_out[i + 1];
1956  i--;
1957  }
1958  break;
1959  }
1960 
1961  pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
1962 
1963  /* Extrapolate above if pcdac is greater than
1964  * 126 -this can happen because we OR pcdac_out
1965  * value with edge_flag on high power curve */
1966  if (pcdac_out[i] > 126)
1967  pcdac_out[i] = 126;
1968 
1969  /* Decrease by a 0.5dB step */
1970  pwr--;
1971  }
1972 }
int16_t s16
Definition: stdint.h:20
uint8_t ah
Definition: registers.h:85
uint8_t u8
Definition: stdint.h:19

References ah.

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_setup_pcdac_table()

static void ath5k_setup_pcdac_table ( struct ath5k_hw ah)
static

Definition at line 1976 of file ath5k_phy.c.

1977 {
1978  u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
1979  int i;
1980 
1981  /*
1982  * Write TX power values
1983  */
1984  for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
1986  (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
1987  (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
1989  }
1990 }
#define AR5K_EEPROM_POWER_TABLE_SIZE
Definition: eeprom.h:215
#define AR5K_PHY_PCDAC_TXPOWER(_n)
Definition: reg.h:2498
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
uint8_t ah
Definition: registers.h:85
uint8_t u8
Definition: stdint.h:19

References ah, AR5K_EEPROM_POWER_TABLE_SIZE, AR5K_PHY_PCDAC_TXPOWER, and ath5k_hw_reg_write().

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_combine_pwr_to_pdadc_curves()

static void ath5k_combine_pwr_to_pdadc_curves ( struct ath5k_hw ah,
s16 pwr_min,
s16 pwr_max,
u8  pdcurves 
)
static

Definition at line 2005 of file ath5k_phy.c.

2007 {
2008  u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
2009  u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
2010  u8 *pdadc_tmp;
2011  s16 pdadc_0;
2012  u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
2013  u8 pd_gain_overlap;
2014 
2015  /* Note: Register value is initialized on initvals
2016  * there is no feedback from hw.
2017  * XXX: What about pd_gain_overlap from EEPROM ? */
2018  pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
2020 
2021  /* Create final PDADC table */
2022  for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
2023  pdadc_tmp = ah->ah_txpower.tmpL[pdg];
2024 
2025  if (pdg == pdcurves - 1)
2026  /* 2 dB boundary stretch for last
2027  * (higher power) curve */
2028  gain_boundaries[pdg] = pwr_max[pdg] + 4;
2029  else
2030  /* Set gain boundary in the middle
2031  * between this curve and the next one */
2032  gain_boundaries[pdg] =
2033  (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
2034 
2035  /* Sanity check in case our 2 db stretch got out of
2036  * range. */
2037  if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
2038  gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
2039 
2040  /* For the first curve (lower power)
2041  * start from 0 dB */
2042  if (pdg == 0)
2043  pdadc_0 = 0;
2044  else
2045  /* For the other curves use the gain overlap */
2046  pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
2047  pd_gain_overlap;
2048 
2049  /* Force each power step to be at least 0.5 dB */
2050  if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
2051  pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
2052  else
2053  pwr_step = 1;
2054 
2055  /* If pdadc_0 is negative, we need to extrapolate
2056  * below this pdgain by a number of pwr_steps */
2057  while ((pdadc_0 < 0) && (pdadc_i < 128)) {
2058  s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
2059  pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
2060  pdadc_0++;
2061  }
2062 
2063  /* Set last pwr level, using gain boundaries */
2064  pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
2065  /* Limit it to be inside pwr range */
2066  table_size = pwr_max[pdg] - pwr_min[pdg];
2067  max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
2068 
2069  /* Fill pdadc_out table */
2070  while (pdadc_0 < max_idx)
2071  pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
2072 
2073  /* Need to extrapolate above this pdgain? */
2074  if (pdadc_n <= max_idx)
2075  continue;
2076 
2077  /* Force each power step to be at least 0.5 dB */
2078  if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
2079  pwr_step = pdadc_tmp[table_size - 1] -
2080  pdadc_tmp[table_size - 2];
2081  else
2082  pwr_step = 1;
2083 
2084  /* Extrapolate above */
2085  while ((pdadc_0 < (s16) pdadc_n) &&
2086  (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
2087  s16 tmp = pdadc_tmp[table_size - 1] +
2088  (pdadc_0 - max_idx) * pwr_step;
2089  pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
2090  pdadc_0++;
2091  }
2092  }
2093 
2094  while (pdg < AR5K_EEPROM_N_PD_GAINS) {
2095  gain_boundaries[pdg] = gain_boundaries[pdg - 1];
2096  pdg++;
2097  }
2098 
2099  while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
2100  pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
2101  pdadc_i++;
2102  }
2103 
2104  /* Set gain boundaries */
2106  AR5K_REG_SM(pd_gain_overlap,
2108  AR5K_REG_SM(gain_boundaries[0],
2110  AR5K_REG_SM(gain_boundaries[1],
2112  AR5K_REG_SM(gain_boundaries[2],
2114  AR5K_REG_SM(gain_boundaries[3],
2117 
2118  /* Used for setting rate power table */
2119  ah->ah_txpower.txp_min_idx = pwr_min[0];
2120 
2121 }
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4
Definition: reg.h:2582
int16_t s16
Definition: stdint.h:20
#define AR5K_EEPROM_N_PD_GAINS
Definition: eeprom.h:207
#define AR5K_EEPROM_POWER_TABLE_SIZE
Definition: eeprom.h:215
unsigned long tmp
Definition: linux_pci.h:53
#define u8
Definition: igbvf_osdep.h:38
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1
Definition: reg.h:2576
#define AR5K_PHY_TPC_RG5
Definition: reg.h:2573
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP
Definition: reg.h:2574
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3
Definition: reg.h:2580
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2
Definition: reg.h:2578
uint8_t u8
Definition: stdint.h:19
#define AR5K_TUNE_MAX_TXPOWER
Definition: ath5k.h:191
#define AR5K_REG_SM(_val, _flags)
Definition: ath5k.h:84

References ah, AR5K_EEPROM_N_PD_GAINS, AR5K_EEPROM_POWER_TABLE_SIZE, AR5K_PHY_TPC_RG5, AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1, AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2, AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3, AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4, AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP, AR5K_REG_SM, AR5K_TUNE_MAX_TXPOWER, ath5k_hw_reg_read(), ath5k_hw_reg_write(), tmp, and u8.

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_setup_pwr_to_pdadc_table()

static void ath5k_setup_pwr_to_pdadc_table ( struct ath5k_hw ah,
u8  pdcurves,
u8 pdg_to_idx 
)
static

Definition at line 2125 of file ath5k_phy.c.

2127 {
2128  u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
2129  u32 reg;
2130  u8 i;
2131 
2132  /* Select the right pdgain curves */
2133 
2134  /* Clear current settings */
2140 
2141  /*
2142  * Use pd_gains curve from eeprom
2143  *
2144  * This overrides the default setting from initvals
2145  * in case some vendors (e.g. Zcomax) don't use the default
2146  * curves. If we don't honor their settings we 'll get a
2147  * 5dB (1 * gain overlap ?) drop.
2148  */
2150 
2151  switch (pdcurves) {
2152  case 3:
2153  reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
2154  /* Fall through */
2155  case 2:
2156  reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
2157  /* Fall through */
2158  case 1:
2159  reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
2160  break;
2161  }
2163 
2164  /*
2165  * Write TX power values
2166  */
2167  for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
2169  ((pdadc_out[4*i + 0] & 0xff) << 0) |
2170  ((pdadc_out[4*i + 1] & 0xff) << 8) |
2171  ((pdadc_out[4*i + 2] & 0xff) << 16) |
2172  ((pdadc_out[4*i + 3] & 0xff) << 24),
2174  }
2175 }
#define AR5K_PHY_TPC_RG1_PDGAIN_2
Definition: reg.h:2568
static unsigned int unsigned int reg
Definition: myson.h:162
#define AR5K_PHY_TPC_RG1_PDGAIN_3
Definition: reg.h:2570
#define AR5K_EEPROM_POWER_TABLE_SIZE
Definition: eeprom.h:215
#define AR5K_PHY_TPC_RG1_PDGAIN_1
Definition: reg.h:2566
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
uint8_t ah
Definition: registers.h:85
#define AR5K_PHY_TPC_RG1
Definition: reg.h:2563
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN
Definition: reg.h:2564
#define AR5K_PHY_PDADC_TXPOWER(_n)
Definition: reg.h:2589
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23
#define AR5K_REG_SM(_val, _flags)
Definition: ath5k.h:84

References ah, AR5K_EEPROM_POWER_TABLE_SIZE, AR5K_PHY_PDADC_TXPOWER, AR5K_PHY_TPC_RG1, AR5K_PHY_TPC_RG1_NUM_PD_GAIN, AR5K_PHY_TPC_RG1_PDGAIN_1, AR5K_PHY_TPC_RG1_PDGAIN_2, AR5K_PHY_TPC_RG1_PDGAIN_3, AR5K_REG_SM, ath5k_hw_reg_read(), ath5k_hw_reg_write(), and reg.

Referenced by ath5k_setup_channel_powertable().

◆ ath5k_setup_channel_powertable()

static int ath5k_setup_channel_powertable ( struct ath5k_hw ah,
struct net80211_channel channel,
u8  ee_mode,
u8  type 
)
static

Definition at line 2190 of file ath5k_phy.c.

2193 {
2194  struct ath5k_pdgain_info *pdg_L, *pdg_R;
2195  struct ath5k_chan_pcal_info *pcinfo_L;
2196  struct ath5k_chan_pcal_info *pcinfo_R;
2197  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2198  u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
2199  s16 table_min[AR5K_EEPROM_N_PD_GAINS];
2200  s16 table_max[AR5K_EEPROM_N_PD_GAINS];
2201  u8 *tmpL;
2202  u8 *tmpR;
2203  u32 target = channel->center_freq;
2204  int pdg, i;
2205 
2206  /* Get surounding freq piers for this channel */
2208  &pcinfo_L,
2209  &pcinfo_R);
2210 
2211  /* Loop over pd gain curves on
2212  * surounding freq piers by index */
2213  for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
2214 
2215  /* Fill curves in reverse order
2216  * from lower power (max gain)
2217  * to higher power. Use curve -> idx
2218  * backmaping we did on eeprom init */
2219  u8 idx = pdg_curve_to_idx[pdg];
2220 
2221  /* Grab the needed curves by index */
2222  pdg_L = &pcinfo_L->pd_curves[idx];
2223  pdg_R = &pcinfo_R->pd_curves[idx];
2224 
2225  /* Initialize the temp tables */
2226  tmpL = ah->ah_txpower.tmpL[pdg];
2227  tmpR = ah->ah_txpower.tmpR[pdg];
2228 
2229  /* Set curve's x boundaries and create
2230  * curves so that they cover the same
2231  * range (if we don't do that one table
2232  * will have values on some range and the
2233  * other one won't have any so interpolation
2234  * will fail) */
2235  table_min[pdg] = min(pdg_L->pd_pwr[0],
2236  pdg_R->pd_pwr[0]) / 2;
2237 
2238  table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
2239  pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
2240 
2241  /* Now create the curves on surrounding channels
2242  * and interpolate if needed to get the final
2243  * curve for this gain on this channel */
2244  switch (type) {
2246  /* Override min/max so that we don't loose
2247  * accuracy (don't divide by 2) */
2248  table_min[pdg] = min(pdg_L->pd_pwr[0],
2249  pdg_R->pd_pwr[0]);
2250 
2251  table_max[pdg] =
2252  max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
2253  pdg_R->pd_pwr[pdg_R->pd_points - 1]);
2254 
2255  /* Override minimum so that we don't get
2256  * out of bounds while extrapolating
2257  * below. Don't do this when we have 2
2258  * curves and we are on the high power curve
2259  * because table_min is ok in this case */
2260  if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
2261 
2262  table_min[pdg] =
2264  pdg_R->pd_step,
2265  pdg_L->pd_pwr,
2266  pdg_R->pd_pwr);
2267 
2268  /* Don't go too low because we will
2269  * miss the upper part of the curve.
2270  * Note: 126 = 31.5dB (max power supported)
2271  * in 0.25dB units */
2272  if (table_max[pdg] - table_min[pdg] > 126)
2273  table_min[pdg] = table_max[pdg] - 126;
2274  }
2275 
2276  /* Fall through */
2279 
2280  ath5k_create_power_curve(table_min[pdg],
2281  table_max[pdg],
2282  pdg_L->pd_pwr,
2283  pdg_L->pd_step,
2284  pdg_L->pd_points, tmpL, type);
2285 
2286  /* We are in a calibration
2287  * pier, no need to interpolate
2288  * between freq piers */
2289  if (pcinfo_L == pcinfo_R)
2290  continue;
2291 
2292  ath5k_create_power_curve(table_min[pdg],
2293  table_max[pdg],
2294  pdg_R->pd_pwr,
2295  pdg_R->pd_step,
2296  pdg_R->pd_points, tmpR, type);
2297  break;
2298  default:
2299  return -EINVAL;
2300  }
2301 
2302  /* Interpolate between curves
2303  * of surounding freq piers to
2304  * get the final curve for this
2305  * pd gain. Re-use tmpL for interpolation
2306  * output */
2307  for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
2308  (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
2309  tmpL[i] = (u8) ath5k_get_interpolated_value(target,
2310  (s16) pcinfo_L->freq,
2311  (s16) pcinfo_R->freq,
2312  (s16) tmpL[i],
2313  (s16) tmpR[i]);
2314  }
2315  }
2316 
2317  /* Now we have a set of curves for this
2318  * channel on tmpL (x range is table_max - table_min
2319  * and y values are tmpL[pdg][]) sorted in the same
2320  * order as EEPROM (because we've used the backmaping).
2321  * So for RF5112 it's from higher power to lower power
2322  * and for RF2413 it's from lower power to higher power.
2323  * For RF5111 we only have one curve. */
2324 
2325  /* Fill min and max power levels for this
2326  * channel by interpolating the values on
2327  * surounding channels to complete the dataset */
2328  ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
2329  (s16) pcinfo_L->freq,
2330  (s16) pcinfo_R->freq,
2331  pcinfo_L->min_pwr, pcinfo_R->min_pwr);
2332 
2333  ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
2334  (s16) pcinfo_L->freq,
2335  (s16) pcinfo_R->freq,
2336  pcinfo_L->max_pwr, pcinfo_R->max_pwr);
2337 
2338  /* We are ready to go, fill PCDAC/PDADC
2339  * table and write settings on hardware */
2340  switch (type) {
2342  /* For RF5112 we can have one or two curves
2343  * and each curve covers a certain power lvl
2344  * range so we need to do some more processing */
2345  ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
2346  ee->ee_pd_gains[ee_mode]);
2347 
2348  /* Set txp.offset so that we can
2349  * match max power value with max
2350  * table index */
2351  ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
2352 
2353  /* Write settings on hw */
2355  break;
2357  /* We are done for RF5111 since it has only
2358  * one curve, just fit the curve on the table */
2359  ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
2360 
2361  /* No rate powertable adjustment for RF5111 */
2362  ah->ah_txpower.txp_min_idx = 0;
2363  ah->ah_txpower.txp_offset = 0;
2364 
2365  /* Write settings on hw */
2367  break;
2369  /* Set PDADC boundaries and fill
2370  * final PDADC table */
2371  ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
2372  ee->ee_pd_gains[ee_mode]);
2373 
2374  /* Write settings on hw */
2375  ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
2376 
2377  /* Set txp.offset, note that table_min
2378  * can be negative */
2379  ah->ah_txpower.txp_offset = table_min[0];
2380  break;
2381  default:
2382  return -EINVAL;
2383  }
2384 
2385  return 0;
2386 }
#define u16
Definition: vga.h:20
#define EINVAL
Invalid argument.
Definition: errno.h:428
u8 ee_pd_gains[AR5K_EEPROM_N_MODES]
Definition: eeprom.h:421
int16_t s16
Definition: stdint.h:20
static void ath5k_create_power_curve(s16 pmin, s16 pmax, const s16 *pwr, const u8 *vpd, u8 num_points, u8 *vpd_table, u8 type)
Definition: ath5k_phy.c:1528
struct ath5k_pdgain_info * pd_curves
Definition: eeprom.h:340
static void ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16 *table_min, s16 *table_max)
Definition: ath5k_phy.c:1835
u8 ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS]
Definition: eeprom.h:423
static void ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 pdcurves, u8 *pdg_to_idx)
Definition: ath5k_phy.c:2125
static void ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16 *table_min, s16 *table_max, u8 pdcurves)
Definition: ath5k_phy.c:1881
static int min(int x, int y)
Definition: ath5k_phy.c:38
static int max(int x, int y)
Definition: ath5k_phy.c:43
#define AR5K_EEPROM_N_PD_GAINS
Definition: eeprom.h:207
#define AR5K_EEPROM_POWER_TABLE_SIZE
Definition: eeprom.h:215
static s16 ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right, s16 y_left, s16 y_right)
Definition: ath5k_phy.c:1443
static void ath5k_setup_pcdac_table(struct ath5k_hw *ah)
Definition: ath5k_phy.c:1976
#define u8
Definition: igbvf_osdep.h:38
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
static void ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah, struct net80211_channel *channel, struct ath5k_chan_pcal_info **pcinfo_l, struct ath5k_chan_pcal_info **pcinfo_r)
Definition: ath5k_phy.c:1580
static void ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
Definition: ath5k_phy.c:2005
static s16 ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR, const s16 *pwrL, const s16 *pwrR)
Definition: ath5k_phy.c:1476
uint32_t type
Operating system type.
Definition: ena.h:12
uint8_t ah
Definition: registers.h:85
uint8_t u8
Definition: stdint.h:19
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_EEPROM_N_PD_GAINS, AR5K_EEPROM_POWER_TABLE_SIZE, AR5K_PWRTABLE_LINEAR_PCDAC, AR5K_PWRTABLE_PWR_TO_PCDAC, AR5K_PWRTABLE_PWR_TO_PDADC, ath5k_combine_linear_pcdac_curves(), ath5k_combine_pwr_to_pdadc_curves(), ath5k_create_power_curve(), ath5k_fill_pwr_to_pcdac_table(), ath5k_get_chan_pcal_surrounding_piers(), ath5k_get_interpolated_value(), ath5k_get_linear_pcdac_min(), ath5k_setup_pcdac_table(), ath5k_setup_pwr_to_pdadc_table(), channel, ath5k_eeprom_info::ee_pd_gains, ath5k_eeprom_info::ee_pdc_to_idx, EINVAL, ath5k_chan_pcal_info::freq, max(), ath5k_chan_pcal_info::max_pwr, min(), ath5k_chan_pcal_info::min_pwr, ath5k_chan_pcal_info::pd_curves, ath5k_pdgain_info::pd_points, ath5k_pdgain_info::pd_pwr, ath5k_pdgain_info::pd_step, type, u16, and u8.

Referenced by ath5k_hw_txpower().

◆ ath5k_setup_rate_powertable()

static void ath5k_setup_rate_powertable ( struct ath5k_hw ah,
u16  max_pwr,
struct ath5k_rate_pcal_info rate_info,
u8  ee_mode 
)
static

Definition at line 2412 of file ath5k_phy.c.

2415 {
2416  unsigned int i;
2417  u16 *rates;
2418 
2419  /* max_pwr is power level we got from driver/user in 0.5dB
2420  * units, switch to 0.25dB units so we can compare */
2421  max_pwr *= 2;
2422  max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
2423 
2424  /* apply rate limits */
2425  rates = ah->ah_txpower.txp_rates_power_table;
2426 
2427  /* OFDM rates 6 to 24Mb/s */
2428  for (i = 0; i < 5; i++)
2429  rates[i] = min(max_pwr, rate_info->target_power_6to24);
2430 
2431  /* Rest OFDM rates */
2432  rates[5] = min(rates[0], rate_info->target_power_36);
2433  rates[6] = min(rates[0], rate_info->target_power_48);
2434  rates[7] = min(rates[0], rate_info->target_power_54);
2435 
2436  /* CCK rates */
2437  /* 1L */
2438  rates[8] = min(rates[0], rate_info->target_power_6to24);
2439  /* 2L */
2440  rates[9] = min(rates[0], rate_info->target_power_36);
2441  /* 2S */
2442  rates[10] = min(rates[0], rate_info->target_power_36);
2443  /* 5L */
2444  rates[11] = min(rates[0], rate_info->target_power_48);
2445  /* 5S */
2446  rates[12] = min(rates[0], rate_info->target_power_48);
2447  /* 11L */
2448  rates[13] = min(rates[0], rate_info->target_power_54);
2449  /* 11S */
2450  rates[14] = min(rates[0], rate_info->target_power_54);
2451 
2452  /* XR rates */
2453  rates[15] = min(rates[0], rate_info->target_power_6to24);
2454 
2455  /* CCK rates have different peak to average ratio
2456  * so we have to tweak their power so that gainf
2457  * correction works ok. For this we use OFDM to
2458  * CCK delta from eeprom */
2459  if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
2460  (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
2461  for (i = 8; i <= 15; i++)
2462  rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
2463 
2464  ah->ah_txpower.txp_min_pwr = rates[7];
2465  ah->ah_txpower.txp_max_pwr = rates[0];
2466  ah->ah_txpower.txp_ofdm = rates[7];
2467 }
uint16_t u16
Definition: stdint.h:21
#define AR5K_EEPROM_MODE_11G
Definition: eeprom.h:64
static int min(int x, int y)
Definition: ath5k_phy.c:38
u8 rates[0]
Rates data, one rate per byte.
Definition: ieee80211.h:16
uint8_t ah
Definition: registers.h:85
#define AR5K_SREV_PHY_5212A
Definition: ath5k.h:327

References ah, AR5K_EEPROM_MODE_11G, AR5K_SREV_PHY_5212A, min(), rates, ath5k_rate_pcal_info::target_power_36, ath5k_rate_pcal_info::target_power_48, ath5k_rate_pcal_info::target_power_54, and ath5k_rate_pcal_info::target_power_6to24.

Referenced by ath5k_hw_txpower().

◆ ath5k_hw_txpower()

int ath5k_hw_txpower ( struct ath5k_hw ah,
struct net80211_channel channel,
u8  ee_mode,
u8  txpower 
)

Definition at line 2474 of file ath5k_phy.c.

2476 {
2477  struct ath5k_rate_pcal_info rate_info;
2478  u8 type;
2479  int ret;
2480 
2481  if (txpower > AR5K_TUNE_MAX_TXPOWER) {
2482  DBG("ath5k: invalid tx power %d\n", txpower);
2483  return -EINVAL;
2484  }
2485  if (txpower == 0)
2486  txpower = AR5K_TUNE_DEFAULT_TXPOWER;
2487 
2488  /* Reset TX power values */
2489  memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
2490  ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
2491  ah->ah_txpower.txp_min_pwr = 0;
2492  ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
2493 
2494  /* Initialize TX power table */
2495  switch (ah->ah_radio) {
2496  case AR5K_RF5111:
2498  break;
2499  case AR5K_RF5112:
2501  break;
2502  case AR5K_RF2413:
2503  case AR5K_RF5413:
2504  case AR5K_RF2316:
2505  case AR5K_RF2317:
2506  case AR5K_RF2425:
2508  break;
2509  default:
2510  return -EINVAL;
2511  }
2512 
2513  /* FIXME: Only on channel/mode change */
2514  ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
2515  if (ret)
2516  return ret;
2517 
2518  /* Limit max power if we have a CTL available */
2520 
2521  /* FIXME: Tx power limit for this regdomain
2522  * XXX: Mac80211/CRDA will do that anyway ? */
2523 
2524  /* FIXME: Antenna reduction stuff */
2525 
2526  /* FIXME: Limit power on turbo modes */
2527 
2528  /* FIXME: TPC scale reduction */
2529 
2530  /* Get surounding channels for per-rate power table
2531  * calibration */
2532  ath5k_get_rate_pcal_data(ah, channel, &rate_info);
2533 
2534  /* Setup rate power table */
2535  ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
2536 
2537  /* Write rate power table on hw */
2539  AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
2541 
2543  AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
2545 
2547  AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
2549 
2551  AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
2553 
2554  /* FIXME: TPC support */
2555  if (ah->ah_txpower.txp_tpc) {
2558 
2563  AR5K_TPC);
2564  } else {
2567  }
2568 
2569  return 0;
2570 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define AR5K_PHY_TXPOWER_RATE_MAX
Definition: reg.h:2263
#define AR5K_TXPOWER_CCK(_r, _v)
Definition: ath5k.h:541
#define AR5K_REG_MS(_val, _flags)
Definition: ath5k.h:88
#define AR5K_TPC_CHIRP
Definition: reg.h:1564
#define AR5K_PHY_TXPOWER_RATE1
Definition: reg.h:2261
#define AR5K_TUNE_DEFAULT_TXPOWER
Definition: ath5k.h:192
static void ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, struct ath5k_rate_pcal_info *rate_info, u8 ee_mode)
Definition: ath5k_phy.c:2412
#define AR5K_TPC
Definition: reg.h:1559
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
#define AR5K_TXPOWER_OFDM(_r, _v)
Definition: ath5k.h:536
#define AR5K_PHY_TXPOWER_RATE3
Definition: reg.h:2265
static int ath5k_setup_channel_powertable(struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 type)
Definition: ath5k_phy.c:2190
#define AR5K_TPC_CTS
Definition: reg.h:1562
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_TUNE_TPC_TXPOWER
Definition: ath5k.h:193
static void ath5k_get_rate_pcal_data(struct ath5k_hw *ah, struct net80211_channel *channel, struct ath5k_rate_pcal_info *rates)
Definition: ath5k_phy.c:1660
uint32_t type
Operating system type.
Definition: ena.h:12
#define AR5K_TPC_ACK
Definition: reg.h:1560
uint8_t ah
Definition: registers.h:85
#define AR5K_PHY_TXPOWER_RATE4
Definition: reg.h:2266
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static void ath5k_get_max_ctl_power(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:1748
#define AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE
Definition: reg.h:2264
#define AR5K_PHY_TXPOWER_RATE2
Definition: reg.h:2262
uint8_t u8
Definition: stdint.h:19
#define AR5K_TUNE_MAX_TXPOWER
Definition: ath5k.h:191
void * memset(void *dest, int character, size_t len) __nonnull

References ah, AR5K_PHY_TXPOWER_RATE1, AR5K_PHY_TXPOWER_RATE2, AR5K_PHY_TXPOWER_RATE3, AR5K_PHY_TXPOWER_RATE4, AR5K_PHY_TXPOWER_RATE_MAX, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE, AR5K_PWRTABLE_LINEAR_PCDAC, AR5K_PWRTABLE_PWR_TO_PCDAC, AR5K_PWRTABLE_PWR_TO_PDADC, AR5K_REG_MS, AR5K_RF2316, AR5K_RF2317, AR5K_RF2413, AR5K_RF2425, AR5K_RF5111, AR5K_RF5112, AR5K_RF5413, AR5K_TPC, AR5K_TPC_ACK, AR5K_TPC_CHIRP, AR5K_TPC_CTS, AR5K_TUNE_DEFAULT_TXPOWER, AR5K_TUNE_MAX_TXPOWER, AR5K_TUNE_TPC_TXPOWER, AR5K_TXPOWER_CCK, AR5K_TXPOWER_OFDM, ath5k_get_max_ctl_power(), ath5k_get_rate_pcal_data(), ath5k_hw_reg_write(), ath5k_setup_channel_powertable(), ath5k_setup_rate_powertable(), channel, DBG, EINVAL, memset(), and type.

Referenced by ath5k_hw_reset(), and ath5k_hw_set_txpower_limit().

◆ ath5k_hw_set_txpower_limit()

int ath5k_hw_set_txpower_limit ( struct ath5k_hw ah,
u8  mode,
u8  txpower 
)

Definition at line 2572 of file ath5k_phy.c.

2573 {
2574  struct net80211_channel *channel = ah->ah_current_channel;
2575 
2576  DBG2("ath5k: changing txpower to %d\n", txpower);
2577 
2578  return ath5k_hw_txpower(ah, channel, mode, txpower);
2579 }
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
An 802.11 RF channel.
Definition: net80211.h:385
uint8_t ah
Definition: registers.h:85
int ath5k_hw_txpower(struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 txpower)
Definition: ath5k_phy.c:2474
#define DBG2(...)
Definition: compiler.h:515

References ah, ath5k_hw_txpower(), channel, and DBG2.