diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2010-04-15 17:38:38 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-16 15:43:24 -0400 |
commit | cffb5e49a147cfc6491f561f9b330e1001276185 (patch) | |
tree | b0606c760f1c234a0403e5e33f22f009891204af /drivers/net/wireless | |
parent | 13ce3e997c8a63269e49f1b6c239035d79bb18e8 (diff) |
ath9k_hw: add helpers for processing the AR9003 INI
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.c | 186 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/reg.h | 13 |
3 files changed, 198 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 3e3472e493a4..acbf122a150d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -186,7 +186,40 @@ static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah, | |||
186 | static void ar9003_hw_set_channel_regs(struct ath_hw *ah, | 186 | static void ar9003_hw_set_channel_regs(struct ath_hw *ah, |
187 | struct ath9k_channel *chan) | 187 | struct ath9k_channel *chan) |
188 | { | 188 | { |
189 | /* TODO */ | 189 | u32 phymode; |
190 | u32 enableDacFifo = 0; | ||
191 | |||
192 | enableDacFifo = | ||
193 | (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO); | ||
194 | |||
195 | /* Enable 11n HT, 20 MHz */ | ||
196 | phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH | | ||
197 | AR_PHY_GC_SHORT_GI_40 | enableDacFifo; | ||
198 | |||
199 | /* Configure baseband for dynamic 20/40 operation */ | ||
200 | if (IS_CHAN_HT40(chan)) { | ||
201 | phymode |= AR_PHY_GC_DYN2040_EN; | ||
202 | /* Configure control (primary) channel at +-10MHz */ | ||
203 | if ((chan->chanmode == CHANNEL_A_HT40PLUS) || | ||
204 | (chan->chanmode == CHANNEL_G_HT40PLUS)) | ||
205 | phymode |= AR_PHY_GC_DYN2040_PRI_CH; | ||
206 | |||
207 | } | ||
208 | |||
209 | /* make sure we preserve INI settings */ | ||
210 | phymode |= REG_READ(ah, AR_PHY_GEN_CTRL); | ||
211 | /* turn off Green Field detection for STA for now */ | ||
212 | phymode &= ~AR_PHY_GC_GF_DETECT_EN; | ||
213 | |||
214 | REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode); | ||
215 | |||
216 | /* Configure MAC for 20/40 operation */ | ||
217 | ath9k_hw_set11nmac2040(ah); | ||
218 | |||
219 | /* global transmit timeout (25 TUs default)*/ | ||
220 | REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); | ||
221 | /* carrier sense timeout */ | ||
222 | REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); | ||
190 | } | 223 | } |
191 | 224 | ||
192 | static void ar9003_hw_init_bb(struct ath_hw *ah, | 225 | static void ar9003_hw_init_bb(struct ath_hw *ah, |
@@ -195,11 +228,158 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, | |||
195 | /* TODO */ | 228 | /* TODO */ |
196 | } | 229 | } |
197 | 230 | ||
231 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) | ||
232 | { | ||
233 | switch (rx) { | ||
234 | case 0x5: | ||
235 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
236 | AR_PHY_SWAP_ALT_CHAIN); | ||
237 | case 0x3: | ||
238 | case 0x1: | ||
239 | case 0x2: | ||
240 | case 0x7: | ||
241 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); | ||
242 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); | ||
243 | break; | ||
244 | default: | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); | ||
249 | if (tx == 0x5) { | ||
250 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
251 | AR_PHY_SWAP_ALT_CHAIN); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * Override INI values with chip specific configuration. | ||
257 | */ | ||
258 | static void ar9003_hw_override_ini(struct ath_hw *ah) | ||
259 | { | ||
260 | u32 val; | ||
261 | |||
262 | /* | ||
263 | * Set the RX_ABORT and RX_DIS and clear it only after | ||
264 | * RXE is set for MAC. This prevents frames with | ||
265 | * corrupted descriptor status. | ||
266 | */ | ||
267 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
268 | |||
269 | /* | ||
270 | * For AR9280 and above, there is a new feature that allows | ||
271 | * Multicast search based on both MAC Address and Key ID. By default, | ||
272 | * this feature is enabled. But since the driver is not using this | ||
273 | * feature, we switch it off; otherwise multicast search based on | ||
274 | * MAC addr only will fail. | ||
275 | */ | ||
276 | val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE); | ||
277 | REG_WRITE(ah, AR_PCU_MISC_MODE2, | ||
278 | val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE); | ||
279 | } | ||
280 | |||
281 | static void ar9003_hw_prog_ini(struct ath_hw *ah, | ||
282 | struct ar5416IniArray *iniArr, | ||
283 | int column) | ||
284 | { | ||
285 | unsigned int i, regWrites = 0; | ||
286 | |||
287 | /* New INI format: Array may be undefined (pre, core, post arrays) */ | ||
288 | if (!iniArr->ia_array) | ||
289 | return; | ||
290 | |||
291 | /* | ||
292 | * New INI format: Pre, core, and post arrays for a given subsystem | ||
293 | * may be modal (> 2 columns) or non-modal (2 columns). Determine if | ||
294 | * the array is non-modal and force the column to 1. | ||
295 | */ | ||
296 | if (column >= iniArr->ia_columns) | ||
297 | column = 1; | ||
298 | |||
299 | for (i = 0; i < iniArr->ia_rows; i++) { | ||
300 | u32 reg = INI_RA(iniArr, i, 0); | ||
301 | u32 val = INI_RA(iniArr, i, column); | ||
302 | |||
303 | REG_WRITE(ah, reg, val); | ||
304 | |||
305 | /* | ||
306 | * Determine if this is a shift register value, and insert the | ||
307 | * configured delay if so. | ||
308 | */ | ||
309 | if (reg >= 0x16000 && reg < 0x17000 | ||
310 | && ah->config.analog_shiftreg) | ||
311 | udelay(100); | ||
312 | |||
313 | DO_DELAY(regWrites); | ||
314 | } | ||
315 | } | ||
316 | |||
198 | static int ar9003_hw_process_ini(struct ath_hw *ah, | 317 | static int ar9003_hw_process_ini(struct ath_hw *ah, |
199 | struct ath9k_channel *chan) | 318 | struct ath9k_channel *chan) |
200 | { | 319 | { |
201 | /* TODO */ | 320 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
202 | return -1; | 321 | unsigned int regWrites = 0, i; |
322 | struct ieee80211_channel *channel = chan->chan; | ||
323 | u32 modesIndex, freqIndex; | ||
324 | |||
325 | switch (chan->chanmode) { | ||
326 | case CHANNEL_A: | ||
327 | case CHANNEL_A_HT20: | ||
328 | modesIndex = 1; | ||
329 | freqIndex = 1; | ||
330 | break; | ||
331 | case CHANNEL_A_HT40PLUS: | ||
332 | case CHANNEL_A_HT40MINUS: | ||
333 | modesIndex = 2; | ||
334 | freqIndex = 1; | ||
335 | break; | ||
336 | case CHANNEL_G: | ||
337 | case CHANNEL_G_HT20: | ||
338 | case CHANNEL_B: | ||
339 | modesIndex = 4; | ||
340 | freqIndex = 2; | ||
341 | break; | ||
342 | case CHANNEL_G_HT40PLUS: | ||
343 | case CHANNEL_G_HT40MINUS: | ||
344 | modesIndex = 3; | ||
345 | freqIndex = 2; | ||
346 | break; | ||
347 | |||
348 | default: | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
352 | for (i = 0; i < ATH_INI_NUM_SPLIT; i++) { | ||
353 | ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex); | ||
354 | ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); | ||
355 | ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); | ||
356 | ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); | ||
357 | } | ||
358 | |||
359 | REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); | ||
360 | REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); | ||
361 | |||
362 | /* | ||
363 | * For 5GHz channels requiring Fast Clock, apply | ||
364 | * different modal values. | ||
365 | */ | ||
366 | if (IS_CHAN_A_5MHZ_SPACED(chan)) | ||
367 | REG_WRITE_ARRAY(&ah->iniModesAdditional, | ||
368 | modesIndex, regWrites); | ||
369 | |||
370 | ar9003_hw_override_ini(ah); | ||
371 | ar9003_hw_set_channel_regs(ah, chan); | ||
372 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | ||
373 | |||
374 | /* Set TX power */ | ||
375 | ah->eep_ops->set_txpower(ah, chan, | ||
376 | ath9k_regd_get_ctl(regulatory, chan), | ||
377 | channel->max_antenna_gain * 2, | ||
378 | channel->max_power * 2, | ||
379 | min((u32) MAX_RATE_POWER, | ||
380 | (u32) regulatory->power_limit)); | ||
381 | |||
382 | return 0; | ||
203 | } | 383 | } |
204 | 384 | ||
205 | static void ar9003_hw_set_rfmode(struct ath_hw *ah, | 385 | static void ar9003_hw_set_rfmode(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 2e51e5795a31..70e647b13e0a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -801,4 +801,6 @@ | |||
801 | 801 | ||
802 | #define AR_PHY_BB_WD_STATUS_CLR 0x00000008 | 802 | #define AR_PHY_BB_WD_STATUS_CLR 0x00000008 |
803 | 803 | ||
804 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); | ||
805 | |||
804 | #endif /* AR9003_PHY_H */ | 806 | #endif /* AR9003_PHY_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 9d632861aaff..96b2cfee8e33 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -1756,4 +1756,17 @@ enum { | |||
1756 | #define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ | 1756 | #define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ |
1757 | #define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ | 1757 | #define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ |
1758 | 1758 | ||
1759 | #define AR_AGG_WEP_ENABLE_FIX 0x00000008 /* This allows the use of AR_AGG_WEP_ENABLE */ | ||
1760 | #define AR_ADHOC_MCAST_KEYID_ENABLE 0x00000040 /* This bit enables the Multicast search | ||
1761 | * based on both MAC Address and Key ID. | ||
1762 | * If bit is 0, then Multicast search is | ||
1763 | * based on MAC address only. | ||
1764 | * For Merlin and above only. | ||
1765 | */ | ||
1766 | #define AR_AGG_WEP_ENABLE 0x00020000 /* This field enables AGG_WEP feature, | ||
1767 | * when it is enable, AGG_WEP would takes | ||
1768 | * charge of the encryption interface of | ||
1769 | * pcu_txsm. | ||
1770 | */ | ||
1771 | |||
1759 | #endif | 1772 | #endif |