aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-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);