aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-10-19 02:33:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-30 16:50:37 -0400
commit131d1d036ac7e7c8ad063581b57ba3bb5f7c881d (patch)
treebc2e9cac34c38086b0a4b4aeec59a720bdfbda4b /drivers
parentc75724d1747230abdd37d0594ac5277b867befd4 (diff)
ath9k_hw: start documenting 802.11n RF anlong front ends
Document what we can about the RF analog front ends (radios) of Atheros 802.11n devices. What should be clearer now is the what we do for old pre AR5416 and AR5418 MAC based devices in comparison to the modern sigle-chip 802.11n solutions. All devices after AR9280 are single chip and require less programming -- the RF registers no longer need to be initialized as they all have the RF analog front end embedded together with the MAC/BB; this includes the AR9271. Older devices such as the ones with the AR5416 MACs (PCI) or AR5418 MACs (PCI-E) have an external 2.4 GHz AR2133 radio or a dual band 2.4 GHz / 5 GHz AR5133 radio. These external radios require additional programming of the RF registers. Clarify which parts are for what devices and which code is shared. This patch has no functional changes. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c166
2 files changed, 170 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 48b6c71144a7..007b41426b27 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -148,6 +148,15 @@ enum wireless_mode {
148 ATH9K_MODE_MAX, 148 ATH9K_MODE_MAX,
149}; 149};
150 150
151/**
152 * ath9k_ant_setting - transmit antenna settings
153 *
154 * Configures the antenna setting to use for transmit.
155 *
156 * @ATH9K_ANT_VARIABLE: this means transmit on all active antennas
157 * @ATH9K_ANT_FIXED_A: this means transmit on the first antenna only
158 * @ATH9K_ANT_FIXED_B: this means transmit on the second antenna only
159 */
151enum ath9k_ant_setting { 160enum ath9k_ant_setting {
152 ATH9K_ANT_VARIABLE = 0, 161 ATH9K_ANT_VARIABLE = 0,
153 ATH9K_ANT_FIXED_A, 162 ATH9K_ANT_FIXED_A,
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 72a17c43a5a0..9e515033b878 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -14,8 +14,44 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17/**
18 * DOC: Programming Atheros 802.11n analog front end radios
19 *
20 * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
21 * devices have either an external AR2133 analog front end radio for single
22 * band 2.4 GHz communication or an AR5133 analog front end radio for dual
23 * band 2.4 GHz / 5 GHz communication.
24 *
25 * All devices after the AR5416 and AR5418 family starting with the AR9280
26 * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
27 * into a single-chip and require less programming.
28 *
29 * The following single-chips exist with a respective embedded radio:
30 *
31 * AR9280 - 11n dual-band 2x2 MIMO for PCIe
32 * AR9281 - 11n single-band 1x2 MIMO for PCIe
33 * AR9285 - 11n single-band 1x1 for PCIe
34 * AR9287 - 11n single-band 2x2 MIMO for PCIe
35 *
36 * AR9220 - 11n dual-band 2x2 MIMO for PCI
37 * AR9223 - 11n single-band 2x2 MIMO for PCI
38 *
39 * AR9287 - 11n single-band 1x1 MIMO for USB
40 */
41
17#include "hw.h" 42#include "hw.h"
18 43
44/**
45 * ath9k_hw_write_regs - ??
46 *
47 * @ah: atheros hardware structure
48 * @modesIndex:
49 * @freqIndex:
50 * @regWrites:
51 *
52 * Used for both the chipsets with an external AR2133/AR5133 radios and
53 * single-chip devices.
54 */
19void 55void
20ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex, 56ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
21 int regWrites) 57 int regWrites)
@@ -23,6 +59,15 @@ ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
23 REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); 59 REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
24} 60}
25 61
62/**
63 * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
64 * @ah: atheros hardware stucture
65 * @chan:
66 *
67 * For the external AR2133/AR5133 radios, takes the MHz channel value and set
68 * the channel value. Assumes writes enabled to analog bus and bank6 register
69 * cache in ah->analogBank6Data.
70 */
26bool 71bool
27ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) 72ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
28{ 73{
@@ -97,6 +142,27 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
97 return true; 142 return true;
98} 143}
99 144
145/**
146 * ath9k_hw_ar9280_set_channel - set channel on single-chip device
147 * @ah: atheros hardware structure
148 * @chan:
149 *
150 * This is the function to change channel on single-chip devices, that is
151 * all devices after ar9280.
152 *
153 * This function takes the channel value in MHz and sets
154 * hardware channel value. Assumes writes have been enabled to analog bus.
155 *
156 * Actual Expression,
157 *
158 * For 2GHz channel,
159 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
160 * (freq_ref = 40MHz)
161 *
162 * For 5GHz channel,
163 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
164 * (freq_ref = 40MHz/(24>>amodeRefSel))
165 */
100void ath9k_hw_ar9280_set_channel(struct ath_hw *ah, 166void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
101 struct ath9k_channel *chan) 167 struct ath9k_channel *chan)
102{ 168{
@@ -111,7 +177,7 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
111 reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL); 177 reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
112 reg32 &= 0xc0000000; 178 reg32 &= 0xc0000000;
113 179
114 if (freq < 4800) { 180 if (freq < 4800) { /* 2 GHz, fractional mode */
115 u32 txctl; 181 u32 txctl;
116 int regWrites = 0; 182 int regWrites = 0;
117 183
@@ -122,6 +188,7 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
122 188
123 if (AR_SREV_9287_11_OR_LATER(ah)) { 189 if (AR_SREV_9287_11_OR_LATER(ah)) {
124 if (freq == 2484) { 190 if (freq == 2484) {
191 /* Enable channel spreading for channel 14 */
125 REG_WRITE_ARRAY(&ah->iniCckfirJapan2484, 192 REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
126 1, regWrites); 193 1, regWrites);
127 } else { 194 } else {
@@ -155,10 +222,15 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
155 case 1: 222 case 1:
156 default: 223 default:
157 aModeRefSel = 0; 224 aModeRefSel = 0;
225 /*
226 * Enable 2G (fractional) mode for channels
227 * which are 5MHz spaced.
228 */
158 fracMode = 1; 229 fracMode = 1;
159 refDivA = 1; 230 refDivA = 1;
160 channelSel = (freq * 0x8000) / 15; 231 channelSel = (freq * 0x8000) / 15;
161 232
233 /* RefDivA setting */
162 REG_RMW_FIELD(ah, AR_AN_SYNTH9, 234 REG_RMW_FIELD(ah, AR_AN_SYNTH9,
163 AR_AN_SYNTH9_REFDIVA, refDivA); 235 AR_AN_SYNTH9_REFDIVA, refDivA);
164 236
@@ -182,6 +254,17 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
182 ah->curchan_rad_index = -1; 254 ah->curchan_rad_index = -1;
183} 255}
184 256
257/**
258 * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
259 * @rfbuf:
260 * @reg32:
261 * @numBits:
262 * @firstBit:
263 * @column:
264 *
265 * Performs analog "swizzling" of parameters into their location.
266 * Used on external AR2133/AR5133 radios.
267 */
185static void 268static void
186ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32, 269ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
187 u32 numBits, u32 firstBit, 270 u32 numBits, u32 firstBit,
@@ -209,6 +292,18 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
209 } 292 }
210} 293}
211 294
295/* *
296 * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
297 * @ah: atheros hardware structure
298 * @chan:
299 * @modesIndex:
300 *
301 * Used for the external AR2133/AR5133 radios.
302 *
303 * Reads the EEPROM header info from the device structure and programs
304 * all rf registers. This routine requires access to the analog
305 * rf device. This is not required for single-chip devices.
306 */
212bool 307bool
213ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan, 308ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
214 u16 modesIndex) 309 u16 modesIndex)
@@ -218,17 +313,27 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
218 u32 ob2GHz = 0, db2GHz = 0; 313 u32 ob2GHz = 0, db2GHz = 0;
219 int regWrites = 0; 314 int regWrites = 0;
220 315
316 /*
317 * Software does not need to program bank data
318 * for single chip devices, that is AR9280 or anything
319 * after that.
320 */
221 if (AR_SREV_9280_10_OR_LATER(ah)) 321 if (AR_SREV_9280_10_OR_LATER(ah))
222 return true; 322 return true;
223 323
324 /* Setup rf parameters */
224 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); 325 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
225 326
327 /* Setup Bank 0 Write */
226 RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); 328 RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
227 329
330 /* Setup Bank 1 Write */
228 RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); 331 RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
229 332
333 /* Setup Bank 2 Write */
230 RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); 334 RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
231 335
336 /* Setup Bank 6 Write */
232 RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, 337 RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
233 modesIndex); 338 modesIndex);
234 { 339 {
@@ -239,6 +344,7 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
239 } 344 }
240 } 345 }
241 346
347 /* Only the 5 or 2 GHz OB/DB need to be set for a mode */
242 if (eepMinorRev >= 2) { 348 if (eepMinorRev >= 2) {
243 if (IS_CHAN_2GHZ(chan)) { 349 if (IS_CHAN_2GHZ(chan)) {
244 ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2); 350 ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
@@ -257,8 +363,10 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
257 } 363 }
258 } 364 }
259 365
366 /* Setup Bank 7 Setup */
260 RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); 367 RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
261 368
369 /* Write Analog registers */
262 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, 370 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
263 regWrites); 371 regWrites);
264 REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, 372 REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
@@ -275,6 +383,11 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
275 return true; 383 return true;
276} 384}
277 385
386/**
387 * ath9k_hw_rf_free - Free memory for analog bank scratch buffers
388 * @ah: atheros hardware struture
389 * For the external AR2133/AR5133 radios.
390 */
278void 391void
279ath9k_hw_rf_free(struct ath_hw *ah) 392ath9k_hw_rf_free(struct ath_hw *ah)
280{ 393{
@@ -295,6 +408,13 @@ ath9k_hw_rf_free(struct ath_hw *ah)
295#undef ATH_FREE_BANK 408#undef ATH_FREE_BANK
296} 409}
297 410
411/**
412 * ath9k_hw_init_rf - initialize external radio structures
413 * @ah: atheros hardware structure
414 * @status:
415 *
416 * Only required for older devices with external AR2133/AR5133 radios.
417 */
298bool ath9k_hw_init_rf(struct ath_hw *ah, int *status) 418bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
299{ 419{
300 struct ath_common *common = ath9k_hw_common(ah); 420 struct ath_common *common = ath9k_hw_common(ah);
@@ -360,6 +480,33 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
360 return true; 480 return true;
361} 481}
362 482
483/**
484 * ath9k_hw_decrease_chain_power()
485 *
486 * @ah: atheros hardware structure
487 * @chan:
488 *
489 * Only used on the AR5416 and AR5418 with the external AR2133/AR5133 radios.
490 *
491 * Sets a chain internal RF path to the lowest output power. Any
492 * further writes to bank6 after this setting will override these
493 * changes. Thus this function must be the last function in the
494 * sequence to modify bank 6.
495 *
496 * This function must be called after ar5416SetRfRegs() which is
497 * called from ath9k_hw_process_ini() due to swizzling of bank 6.
498 * Depends on ah->analogBank6Data being initialized by
499 * ath9k_hw_set_rf_regs()
500 *
501 * Additional additive reduction in power -
502 * change chain's switch table so chain's tx state is actually the rx
503 * state value. May produce different results in 2GHz/5GHz as well as
504 * board to board but in general should be a reduction.
505 *
506 * Activated by #ifdef ALTER_SWITCH. Not tried yet. If so, must be
507 * called after ah->eep_ops->set_board_values() due to RMW of
508 * PHY_SWITCH_CHAIN_0.
509 */
363void 510void
364ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan) 511ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
365{ 512{
@@ -371,26 +518,35 @@ ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
371 case ATH9K_ANT_FIXED_A: 518 case ATH9K_ANT_FIXED_A:
372 bank6SelMask = 519 bank6SelMask =
373 (ah->config.antenna_switch_swap & ANTSWAP_AB) ? 520 (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
374 REDUCE_CHAIN_0 : REDUCE_CHAIN_1; 521 REDUCE_CHAIN_0 : /* swapped, reduce chain 0 */
522 REDUCE_CHAIN_1; /* normal, select chain 1/2 to reduce */
375 break; 523 break;
376 case ATH9K_ANT_FIXED_B: 524 case ATH9K_ANT_FIXED_B:
377 bank6SelMask = 525 bank6SelMask =
378 (ah->config.antenna_switch_swap & ANTSWAP_AB) ? 526 (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
379 REDUCE_CHAIN_1 : REDUCE_CHAIN_0; 527 REDUCE_CHAIN_1 : /* swapped, reduce chain 1/2 */
528 REDUCE_CHAIN_0; /* normal, select chain 0 to reduce */
380 break; 529 break;
381 case ATH9K_ANT_VARIABLE: 530 case ATH9K_ANT_VARIABLE:
382 return; 531 return; /* do not change anything */
383 break; 532 break;
384 default: 533 default:
385 return; 534 return; /* do not change anything */
386 break; 535 break;
387 } 536 }
388 537
389 for (i = 0; i < ah->iniBank6.ia_rows; i++) 538 for (i = 0; i < ah->iniBank6.ia_rows; i++)
390 bank6Temp[i] = ah->analogBank6Data[i]; 539 bank6Temp[i] = ah->analogBank6Data[i];
391 540
541 /* Write Bank 5 to switch Bank 6 write to selected chain only */
392 REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask); 542 REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
393 543
544 /*
545 * Modify Bank6 selected chain to use lowest amplification.
546 * Modifies the parameters to a value of 1.
547 * Depends on existing bank 6 values to be cached in
548 * ah->analogBank6Data
549 */
394 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0); 550 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
395 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0); 551 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
396 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0); 552 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);