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)
 
 FILE_SECBOOT (FORBIDDEN)
 
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 28 of file ath5k_phy.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( MIT  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( FORBIDDEN  )

◆ min()

static int min ( int  x,
int  y 
)
inlinestatic

Definition at line 39 of file ath5k_phy.c.

40 {
41  return (x < y) ? x : y;
42 }
static unsigned int x
Definition: pixbuf.h:63
static unsigned int unsigned int y
Definition: pixbuf.h:63

References x, and y.

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 44 of file ath5k_phy.c.

45 {
46  return (x > y) ? x : y;
47 }
static unsigned int x
Definition: pixbuf.h:63
static unsigned int unsigned int y
Definition: pixbuf.h:63

References x, and y.

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 52 of file ath5k_phy.c.

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

References ah, ath5k_hw_bitswap(), ath5k_rf_reg::bank, ath5k_rfb_field::col, data, DBG, 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 159 of file ath5k_phy.c.

160 {
161  /* Initialize the gain optimization values */
162  switch (ah->ah_radio) {
163  case AR5K_RF5111:
164  ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
165  ah->ah_gain.g_low = 20;
166  ah->ah_gain.g_high = 35;
167  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
168  break;
169  case AR5K_RF5112:
170  ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
171  ah->ah_gain.g_low = 20;
172  ah->ah_gain.g_high = 85;
173  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
174  break;
175  default:
176  return -EINVAL;
177  }
178 
179  return 0;
180 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
static const struct ath5k_gain_opt rfgain_opt_5111
Definition: rfgain.h:478
static const struct ath5k_gain_opt rfgain_opt_5112
Definition: rfgain.h:504
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 195 of file ath5k_phy.c.

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

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 215 of file ath5k_phy.c.

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

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 270 of file ath5k_phy.c.

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

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 321 of file ath5k_phy.c.

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

391 {
392  u32 data, type;
393  struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
394 
395  if (ah->ah_rf_banks == NULL ||
396  ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
397  return AR5K_RFGAIN_INACTIVE;
398 
399  /* No check requested, either engine is inactive
400  * or an adjustment is already requested */
401  if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
402  goto done;
403 
404  /* Read the PAPD (Peak to Average Power Detector)
405  * register */
407 
408  /* No probe is scheduled, read gain_F measurement */
410  ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
412 
413  /* If tx packet is CCK correct the gain_F measurement
414  * by cck ofdm gain delta */
416  if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
417  ah->ah_gain.g_current +=
419  else
420  ah->ah_gain.g_current +=
422  }
423 
424  /* Further correct gain_F measurement for
425  * RF5112A radios */
426  if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
428  ah->ah_gain.g_current =
429  ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
430  (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
431  0;
432  }
433 
434  /* Check if measurement is ok and if we need
435  * to adjust gain, schedule a gain adjustment,
436  * else switch back to the acive state */
438  AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
440  ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
441  } else {
442  ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
443  }
444  }
445 
446 done:
447  return ah->ah_gain.g_state;
448 }
#define AR5K_PHY_PAPD_PROBE_GAINF_S
Definition: reg.h:2256
#define AR5K_PHY_PAPD_PROBE
Definition: reg.h:2242
#define AR5K_PHY_PAPD_PROBE_TYPE
Definition: reg.h:2250
uint32_t type
Operating system type.
Definition: ena.h:12
#define AR5K_GAIN_CCK_PROBE_CORR
Definition: rfgain.h:451
#define AR5K_PHY_PAPD_PROBE_TYPE_CCK
Definition: reg.h:2254
#define AR5K_REG_MS(_val, _flags)
Definition: ath5k.h:90
static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
Definition: ath5k_phy.c:215
#define AR5K_GAIN_CHECK_ADJUST(_g)
Definition: rfgain.h:457
static int ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
Definition: ath5k_phy.c:270
#define AR5K_PHY_PAPD_PROBE_TX_NEXT
Definition: reg.h:2248
static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
Definition: ath5k_phy.c:321
#define AR5K_SREV_RAD_5112A
Definition: ath5k.h:314
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:1216
u16 ee_cck_ofdm_gain_delta
Definition: eeprom.h:391
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct bofm_section_header done
Definition: bofm_test.c:46
uint32_t u32
Definition: stdint.h:24

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 453 of file ath5k_phy.c.

454 {
455  const struct ath5k_ini_rfgain *ath5k_rfg;
456  unsigned int i, size;
457 
458  switch (ah->ah_radio) {
459  case AR5K_RF5111:
460  ath5k_rfg = rfgain_5111;
462  break;
463  case AR5K_RF5112:
464  ath5k_rfg = rfgain_5112;
466  break;
467  case AR5K_RF2413:
468  ath5k_rfg = rfgain_2413;
470  break;
471  case AR5K_RF2316:
472  ath5k_rfg = rfgain_2316;
474  break;
475  case AR5K_RF5413:
476  ath5k_rfg = rfgain_5413;
478  break;
479  case AR5K_RF2317:
480  case AR5K_RF2425:
481  ath5k_rfg = rfgain_2425;
483  break;
484  default:
485  return -EINVAL;
486  }
487 
488  switch (freq) {
491  break;
492  default:
493  return -EINVAL;
494  }
495 
496  for (i = 0; i < size; i++) {
497  AR5K_REG_WAIT(i);
498  ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
499  (u32)ath5k_rfg[i].rfg_register);
500  }
501 
502  return 0;
503 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
u16 rfg_register
Definition: rfgain.h:29
#define AR5K_REG_WAIT(_i)
Definition: ath5k.h:135
#define AR5K_INI_RFGAIN_5GHZ
Definition: ath5k.h:141
uint16_t size
Buffer size.
Definition: dwmac.h:14
static const struct ath5k_ini_rfgain rfgain_2425[]
Definition: rfgain.h:379
static const struct ath5k_ini_rfgain rfgain_2316[]
Definition: rfgain.h:240
static const struct ath5k_ini_rfgain rfgain_5112[]
Definition: rfgain.h:103
static const struct ath5k_ini_rfgain rfgain_2413[]
Definition: rfgain.h:172
#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:1224
#define AR5K_INI_RFGAIN_2GHZ
Definition: ath5k.h:142
static const struct ath5k_ini_rfgain rfgain_5111[]
Definition: rfgain.h:34
uint8_t ah
Definition: registers.h:85
u32 rfg_value[2]
Definition: rfgain.h:30
static const struct ath5k_ini_rfgain rfgain_5413[]
Definition: rfgain.h:309
uint32_t u32
Definition: stdint.h:24

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 515 of file ath5k_phy.c.

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

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(), mode, 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 831 of file ath5k_phy.c.

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

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 849 of file ath5k_phy.c.

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

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 868 of file ath5k_phy.c.

870 {
871  u32 data;
872 
873  /*
874  * Set the channel and wait
875  */
879  mdelay(1);
880 
881  return 0;
882 }
#define AR5K_RF_BUFFER
Definition: reg.h:2127
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:1224
static u32 ath5k_hw_rf5110_chan2athchan(struct net80211_channel *channel)
Definition: ath5k_phy.c:849
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:79
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ah
Definition: registers.h:85
uint32_t u32
Definition: stdint.h:24
#define AR5K_RF_BUFFER_CONTROL_0
Definition: reg.h:2128

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 887 of file ath5k_phy.c.

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

918 {
919  struct ath5k_athchan_2ghz ath5k_channel_2ghz;
920  unsigned int ath5k_channel = ath5k_freq_to_channel(channel->center_freq);
921  u32 data0, data1, clock;
922  int ret;
923 
924  /*
925  * Set the channel on the RF5111 radio
926  */
927  data0 = data1 = 0;
928 
929  if (channel->hw_value & CHANNEL_2GHZ) {
930  /* Map 2GHz channel to 5GHz Atheros channel ID */
931  ret = ath5k_hw_rf5111_chan2athchan(ath5k_channel,
932  &ath5k_channel_2ghz);
933  if (ret)
934  return ret;
935 
936  ath5k_channel = ath5k_channel_2ghz.a2_athchan;
937  data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
938  << 5) | (1 << 4);
939  }
940 
941  if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
942  clock = 1;
943  data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
944  (clock << 1) | (1 << 10) | 1;
945  } else {
946  clock = 0;
947  data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
948  << 2) | (clock << 1) | (1 << 10) | 1;
949  }
950 
951  ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
953  ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
955 
956  return 0;
957 }
u32 data1
Definition: ar9003_mac.h:28
static u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
Definition: ath5k.h:1267
#define AR5K_RF_BUFFER
Definition: reg.h:2127
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:1224
#define AR5K_RF_BUFFER_CONTROL_3
Definition: reg.h:2132
uint8_t ah
Definition: registers.h:85
u32 data0
Definition: ar9003_mac.h:26
#define CHANNEL_2GHZ
Definition: ath5k.h:634
uint32_t u32
Definition: stdint.h:24
static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee, struct ath5k_athchan_2ghz *athchan)
Definition: ath5k_phy.c:887

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 962 of file ath5k_phy.c.

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

References ah, AR5K_RF_BUFFER, AR5K_RF_BUFFER_CONTROL_5, ath5k_hw_bitswap(), ath5k_hw_reg_write(), 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 1010 of file ath5k_phy.c.

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

References ah, AR5K_RF_BUFFER, AR5K_RF_BUFFER_CONTROL_5, ath5k_hw_bitswap(), ath5k_hw_reg_write(), 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 1049 of file ath5k_phy.c.

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

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 1128 of file ath5k_phy.c.

1129 {
1130  int ret;
1131  unsigned int i;
1132  s32 noise_floor;
1133 
1134  /*
1135  * Enable noise floor calibration
1136  */
1139 
1140  ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1141  AR5K_PHY_AGCCTL_NF, 0, 0);
1142 
1143  if (ret) {
1144  DBG("ath5k: noise floor calibration timeout (%d MHz)\n", freq);
1145  return -EAGAIN;
1146  }
1147 
1148  /* Wait until the noise floor is calibrated and read the value */
1149  for (i = 20; i > 0; i--) {
1150  mdelay(1);
1151  noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1152  noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
1153  if (noise_floor & AR5K_PHY_NF_ACTIVE) {
1154  noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
1155 
1156  if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
1157  break;
1158  }
1159  }
1160 
1161  DBG2("ath5k: noise floor %d\n", noise_floor);
1162 
1163  if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
1164  DBG("ath5k: noise floor calibration failed (%d MHz)\n", freq);
1165  return -EAGAIN;
1166  }
1167 
1168  ah->ah_noise_floor = noise_floor;
1169 
1170  return 0;
1171 }
#define AR5K_PHY_AGCCTL_NF
Definition: reg.h:2032
int32_t s32
Definition: stdint.h:23
#define AR5K_PHY_NF_ACTIVE
Definition: reg.h:2041
#define AR5K_PHY_NF_RVAL(_n)
Definition: reg.h:2042
#define AR5K_PHY_NF_AVAL(_n)
Definition: reg.h:2043
#define AR5K_PHY_AGCCTL
Definition: reg.h:2030
#define AR5K_PHY_NF
Definition: reg.h:2039
#define EAGAIN
Resource temporarily unavailable.
Definition: errno.h:319
#define AR5K_TUNE_NOISE_FLOOR
Definition: ath5k.h:192
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:79
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1216
#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:106

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 1178 of file ath5k_phy.c.

1180 {
1181  u32 phy_sig, phy_agc, phy_sat, beacon;
1182  int ret;
1183 
1184  /*
1185  * Disable beacons and RX/TX queues, wait
1186  */
1191 
1192  mdelay(2);
1193 
1194  /*
1195  * Set the channel (with AGC turned off)
1196  */
1198  udelay(10);
1199  ret = ath5k_hw_channel(ah, channel);
1200 
1201  /*
1202  * Activate PHY and wait
1203  */
1205  mdelay(1);
1206 
1208 
1209  if (ret)
1210  return ret;
1211 
1212  /*
1213  * Calibrate the radio chip
1214  */
1215 
1216  /* Remember normal state */
1217  phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
1219  phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
1220 
1221  /* Update radio registers */
1222  ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
1224 
1229 
1234 
1235  udelay(20);
1236 
1238  udelay(10);
1241 
1242  mdelay(1);
1243 
1244  /*
1245  * Enable calibration and wait until completion
1246  */
1248 
1249  ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1250  AR5K_PHY_AGCCTL_CAL, 0, 0);
1251 
1252  /* Reset to normal state */
1253  ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
1256 
1257  if (ret) {
1258  DBG("ath5k: calibration timeout (%d MHz)\n",
1259  channel->center_freq);
1260  return ret;
1261  }
1262 
1264 
1265  /*
1266  * Re-enable RX/TX and beacons
1267  */
1271 
1272  return 0;
1273 }
#define AR5K_PHY_SIG_FIRPWR
Definition: reg.h:2014
#define AR5K_PHY_AGCCOARSE
Definition: reg.h:2021
#define AR5K_PHY_AGC_DISABLE
Definition: reg.h:1909
#define AR5K_BEACON_ENABLE
Definition: reg.h:1250
#define AR5K_PHY_ADCSAT
Definition: reg.h:2053
#define AR5K_PHY_AGCCTL_CAL
Definition: reg.h:2031
#define AR5K_BEACON_5210
Definition: reg.h:1242
#define AR5K_PHY_SIG
Definition: reg.h:2011
#define AR5K_PHY_AGCCOARSE_LO
Definition: reg.h:2022
#define AR5K_PHY_AGC
Definition: reg.h:1907
#define AR5K_PHY_AGCCTL
Definition: reg.h:2030
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:61
#define AR5K_PHY_RFSTG
Definition: reg.h:2151
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:1049
#define AR5K_PHY_RFSTG_DISABLE
Definition: reg.h:2152
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1224
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:79
#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:109
#define AR5K_DIAG_SW_5210
Definition: reg.h:1392
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:1128
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1216
#define AR5K_DIAG_SW_DIS_TX
Definition: reg.h:1401
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define AR5K_PHY_ADCSAT_THR
Definition: reg.h:2056
#define AR5K_PHY_AGCCOARSE_HI
Definition: reg.h:2024
#define AR5K_PHY_ADCSAT_ICNT
Definition: reg.h:2054
uint32_t u32
Definition: stdint.h:24
#define AR5K_PHY_ACT_ENABLE
Definition: reg.h:1935
#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:106
#define AR5K_PHY_ACT
Definition: reg.h:1934
#define AR5K_DIAG_SW_DIS_RX_5210
Definition: reg.h:1402
#define AR5K_REG_SM(_val, _flags)
Definition: ath5k.h:86

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 1278 of file ath5k_phy.c.

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

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 1346 of file ath5k_phy.c.

1348 {
1349  int ret;
1350 
1351  if (ah->ah_radio == AR5K_RF5110)
1353  else
1355 
1356  return ret;
1357 }
static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, struct net80211_channel *channel)
Definition: ath5k_phy.c:1178
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:1278
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 1359 of file ath5k_phy.c.

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

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 1373 of file ath5k_phy.c.

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

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 1417 of file ath5k_phy.c.

1418 {
1419  if (ah->ah_version != AR5K_AR5210)
1421 }
#define AR5K_DEFAULT_ANTENNA
Definition: reg.h:1478
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1224
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 1423 of file ath5k_phy.c.

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

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 1444 of file ath5k_phy.c.

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

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 1477 of file ath5k_phy.c.

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

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 1529 of file ath5k_phy.c.

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

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 1581 of file ath5k_phy.c.

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

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, max(), and mode.

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 1661 of file ath5k_phy.c.

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

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(), mode, 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 1749 of file ath5k_phy.c.

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

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 1836 of file ath5k_phy.c.

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

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 1882 of file ath5k_phy.c.

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

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 1977 of file ath5k_phy.c.

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

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 2006 of file ath5k_phy.c.

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

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 2126 of file ath5k_phy.c.

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

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 2191 of file ath5k_phy.c.

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

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 2413 of file ath5k_phy.c.

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

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 2475 of file ath5k_phy.c.

2477 {
2478  struct ath5k_rate_pcal_info rate_info;
2479  u8 type;
2480  int ret;
2481 
2482  if (txpower > AR5K_TUNE_MAX_TXPOWER) {
2483  DBG("ath5k: invalid tx power %d\n", txpower);
2484  return -EINVAL;
2485  }
2486  if (txpower == 0)
2487  txpower = AR5K_TUNE_DEFAULT_TXPOWER;
2488 
2489  /* Reset TX power values */
2490  memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
2491  ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
2492  ah->ah_txpower.txp_min_pwr = 0;
2493  ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
2494 
2495  /* Initialize TX power table */
2496  switch (ah->ah_radio) {
2497  case AR5K_RF5111:
2499  break;
2500  case AR5K_RF5112:
2502  break;
2503  case AR5K_RF2413:
2504  case AR5K_RF5413:
2505  case AR5K_RF2316:
2506  case AR5K_RF2317:
2507  case AR5K_RF2425:
2509  break;
2510  default:
2511  return -EINVAL;
2512  }
2513 
2514  /* FIXME: Only on channel/mode change */
2515  ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
2516  if (ret)
2517  return ret;
2518 
2519  /* Limit max power if we have a CTL available */
2521 
2522  /* FIXME: Tx power limit for this regdomain
2523  * XXX: Mac80211/CRDA will do that anyway ? */
2524 
2525  /* FIXME: Antenna reduction stuff */
2526 
2527  /* FIXME: Limit power on turbo modes */
2528 
2529  /* FIXME: TPC scale reduction */
2530 
2531  /* Get surounding channels for per-rate power table
2532  * calibration */
2533  ath5k_get_rate_pcal_data(ah, channel, &rate_info);
2534 
2535  /* Setup rate power table */
2536  ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
2537 
2538  /* Write rate power table on hw */
2540  AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
2542 
2544  AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
2546 
2548  AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
2550 
2552  AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
2554 
2555  /* FIXME: TPC support */
2556  if (ah->ah_txpower.txp_tpc) {
2559 
2564  AR5K_TPC);
2565  } else {
2568  }
2569 
2570  return 0;
2571 }
#define EINVAL
Invalid argument.
Definition: errno.h:429
#define AR5K_PHY_TXPOWER_RATE_MAX
Definition: reg.h:2265
#define AR5K_TXPOWER_CCK(_r, _v)
Definition: ath5k.h:543
uint32_t type
Operating system type.
Definition: ena.h:12
#define AR5K_REG_MS(_val, _flags)
Definition: ath5k.h:90
#define AR5K_TPC_CHIRP
Definition: reg.h:1566
#define AR5K_PHY_TXPOWER_RATE1
Definition: reg.h:2263
#define AR5K_TUNE_DEFAULT_TXPOWER
Definition: ath5k.h:194
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:2413
#define AR5K_TPC
Definition: reg.h:1561
uint32_t channel
RNDIS channel.
Definition: netvsc.h:14
#define AR5K_TXPOWER_OFDM(_r, _v)
Definition: ath5k.h:538
#define AR5K_PHY_TXPOWER_RATE3
Definition: reg.h:2267
static int ath5k_setup_channel_powertable(struct ath5k_hw *ah, struct net80211_channel *channel, u8 ee_mode, u8 type)
Definition: ath5k_phy.c:2191
#define AR5K_TPC_CTS
Definition: reg.h:1564
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1224
#define AR5K_TUNE_TPC_TXPOWER
Definition: ath5k.h:195
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:1661
#define AR5K_TPC_ACK
Definition: reg.h:1562
uint8_t ah
Definition: registers.h:85
#define AR5K_PHY_TXPOWER_RATE4
Definition: reg.h:2268
#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:1749
#define AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE
Definition: reg.h:2266
#define AR5K_PHY_TXPOWER_RATE2
Definition: reg.h:2264
uint8_t u8
Definition: stdint.h:20
#define AR5K_TUNE_MAX_TXPOWER
Definition: ath5k.h:193
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 2573 of file ath5k_phy.c.

2574 {
2575  struct net80211_channel *channel = ah->ah_current_channel;
2576 
2577  DBG2("ath5k: changing txpower to %d\n", txpower);
2578 
2579  return ath5k_hw_txpower(ah, channel, mode, txpower);
2580 }
uint16_t mode
Acceleration mode.
Definition: ena.h:26
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:2475
#define DBG2(...)
Definition: compiler.h:515

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