1 /*-
2 * SPDX-License-Identifier: ISC
3 *
4 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5 * Copyright (c) 2002-2008 Atheros Communications, Inc.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19 #include "opt_ah.h"
20
21 #include "ah.h"
22 #include "ah_internal.h"
23 #include "ah_devid.h"
24 #include "ah_desc.h" /* NB: for HAL_PHYERR* */
25
26 #include "ar5212/ar5212.h"
27 #include "ar5212/ar5212reg.h"
28 #include "ar5212/ar5212phy.h"
29
30 #include "ah_eeprom_v3.h"
31
32 #define AR_NUM_GPIO 6 /* 6 GPIO pins */
33 #define AR_GPIOD_MASK 0x0000002F /* GPIO data reg r/w mask */
34
35 void
ar5212GetMacAddress(struct ath_hal * ah,uint8_t * mac)36 ar5212GetMacAddress(struct ath_hal *ah, uint8_t *mac)
37 {
38 struct ath_hal_5212 *ahp = AH5212(ah);
39
40 OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN);
41 }
42
43 HAL_BOOL
ar5212SetMacAddress(struct ath_hal * ah,const uint8_t * mac)44 ar5212SetMacAddress(struct ath_hal *ah, const uint8_t *mac)
45 {
46 struct ath_hal_5212 *ahp = AH5212(ah);
47
48 OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN);
49 return AH_TRUE;
50 }
51
52 void
ar5212GetBssIdMask(struct ath_hal * ah,uint8_t * mask)53 ar5212GetBssIdMask(struct ath_hal *ah, uint8_t *mask)
54 {
55 struct ath_hal_5212 *ahp = AH5212(ah);
56
57 OS_MEMCPY(mask, ahp->ah_bssidmask, IEEE80211_ADDR_LEN);
58 }
59
60 HAL_BOOL
ar5212SetBssIdMask(struct ath_hal * ah,const uint8_t * mask)61 ar5212SetBssIdMask(struct ath_hal *ah, const uint8_t *mask)
62 {
63 struct ath_hal_5212 *ahp = AH5212(ah);
64
65 /* save it since it must be rewritten on reset */
66 OS_MEMCPY(ahp->ah_bssidmask, mask, IEEE80211_ADDR_LEN);
67
68 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
69 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
70 return AH_TRUE;
71 }
72
73 /*
74 * Attempt to change the cards operating regulatory domain to the given value
75 */
76 HAL_BOOL
ar5212SetRegulatoryDomain(struct ath_hal * ah,uint16_t regDomain,HAL_STATUS * status)77 ar5212SetRegulatoryDomain(struct ath_hal *ah,
78 uint16_t regDomain, HAL_STATUS *status)
79 {
80 HAL_STATUS ecode;
81
82 if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {
83 ecode = HAL_EINVAL;
84 goto bad;
85 }
86 if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {
87 ecode = HAL_EEWRITE;
88 goto bad;
89 }
90 #ifdef AH_SUPPORT_WRITE_REGDOMAIN
91 if (ath_hal_eepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) {
92 HALDEBUG(ah, HAL_DEBUG_ANY,
93 "%s: set regulatory domain to %u (0x%x)\n",
94 __func__, regDomain, regDomain);
95 AH_PRIVATE(ah)->ah_currentRD = regDomain;
96 return AH_TRUE;
97 }
98 #endif
99 ecode = HAL_EIO;
100 bad:
101 if (status)
102 *status = ecode;
103 return AH_FALSE;
104 }
105
106 /*
107 * Return the wireless modes (a,b,g,t) supported by hardware.
108 *
109 * This value is what is actually supported by the hardware
110 * and is unaffected by regulatory/country code settings.
111 */
112 u_int
ar5212GetWirelessModes(struct ath_hal * ah)113 ar5212GetWirelessModes(struct ath_hal *ah)
114 {
115 u_int mode = 0;
116
117 if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {
118 mode = HAL_MODE_11A;
119 if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))
120 mode |= HAL_MODE_TURBO | HAL_MODE_108A;
121 if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
122 mode |= HAL_MODE_11A_HALF_RATE;
123 if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
124 mode |= HAL_MODE_11A_QUARTER_RATE;
125 }
126 if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))
127 mode |= HAL_MODE_11B;
128 if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) &&
129 AH_PRIVATE(ah)->ah_subvendorid != AR_SUBVENDOR_ID_NOG) {
130 mode |= HAL_MODE_11G;
131 if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO2DISABLE))
132 mode |= HAL_MODE_108G;
133 if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
134 mode |= HAL_MODE_11G_HALF_RATE;
135 if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
136 mode |= HAL_MODE_11G_QUARTER_RATE;
137 }
138 return mode;
139 }
140
141 /*
142 * Set the interrupt and GPIO values so the ISR can disable RF
143 * on a switch signal. Assumes GPIO port and interrupt polarity
144 * are set prior to call.
145 */
146 void
ar5212EnableRfKill(struct ath_hal * ah)147 ar5212EnableRfKill(struct ath_hal *ah)
148 {
149 uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent;
150 int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL);
151 int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY);
152
153 /*
154 * Configure the desired GPIO port for input
155 * and enable baseband rf silence.
156 */
157 ath_hal_gpioCfgInput(ah, select);
158 OS_REG_SET_BIT(ah, AR_PHY(0), 0x00002000);
159 /*
160 * If radio disable switch connection to GPIO bit x is enabled
161 * program GPIO interrupt.
162 * If rfkill bit on eeprom is 1, setupeeprommap routine has already
163 * verified that it is a later version of eeprom, it has a place for
164 * rfkill bit and it is set to 1, indicating that GPIO bit x hardware
165 * connection is present.
166 */
167 ath_hal_gpioSetIntr(ah, select,
168 (ath_hal_gpioGet(ah, select) == polarity ? !polarity : polarity));
169 }
170
171 /*
172 * Change the LED blinking pattern to correspond to the connectivity
173 */
174 void
ar5212SetLedState(struct ath_hal * ah,HAL_LED_STATE state)175 ar5212SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
176 {
177 static const uint32_t ledbits[8] = {
178 AR_PCICFG_LEDCTL_NONE, /* HAL_LED_INIT */
179 AR_PCICFG_LEDCTL_PEND, /* HAL_LED_SCAN */
180 AR_PCICFG_LEDCTL_PEND, /* HAL_LED_AUTH */
181 AR_PCICFG_LEDCTL_ASSOC, /* HAL_LED_ASSOC*/
182 AR_PCICFG_LEDCTL_ASSOC, /* HAL_LED_RUN */
183 AR_PCICFG_LEDCTL_NONE,
184 AR_PCICFG_LEDCTL_NONE,
185 AR_PCICFG_LEDCTL_NONE,
186 };
187 uint32_t bits;
188
189 bits = OS_REG_READ(ah, AR_PCICFG);
190 if (IS_2417(ah)) {
191 /*
192 * Enable LED for Nala. There is a bit marked reserved
193 * that must be set and we also turn on the power led.
194 * Because we mark s/w LED control setting the control
195 * status bits below is meangless (the driver must flash
196 * the LED(s) using the GPIO lines).
197 */
198 bits = (bits &~ AR_PCICFG_LEDMODE)
199 | SM(AR_PCICFG_LEDMODE_POWON, AR_PCICFG_LEDMODE)
200 #if 0
201 | SM(AR_PCICFG_LEDMODE_NETON, AR_PCICFG_LEDMODE)
202 #endif
203 | 0x08000000;
204 }
205 bits = (bits &~ AR_PCICFG_LEDCTL)
206 | SM(ledbits[state & 0x7], AR_PCICFG_LEDCTL);
207 OS_REG_WRITE(ah, AR_PCICFG, bits);
208 }
209
210 /*
211 * Change association related fields programmed into the hardware.
212 * Writing a valid BSSID to the hardware effectively enables the hardware
213 * to synchronize its TSF to the correct beacons and receive frames coming
214 * from that BSSID. It is called by the SME JOIN operation.
215 */
216 void
ar5212WriteAssocid(struct ath_hal * ah,const uint8_t * bssid,uint16_t assocId)217 ar5212WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId)
218 {
219 struct ath_hal_5212 *ahp = AH5212(ah);
220
221 /* save bssid for possible re-use on reset */
222 OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN);
223 ahp->ah_assocId = assocId;
224 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
225 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) |
226 ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S));
227 }
228
229 /*
230 * Get the current hardware tsf for stamlme
231 */
232 uint64_t
ar5212GetTsf64(struct ath_hal * ah)233 ar5212GetTsf64(struct ath_hal *ah)
234 {
235 uint32_t low1, low2, u32;
236
237 /* sync multi-word read */
238 low1 = OS_REG_READ(ah, AR_TSF_L32);
239 u32 = OS_REG_READ(ah, AR_TSF_U32);
240 low2 = OS_REG_READ(ah, AR_TSF_L32);
241 if (low2 < low1) { /* roll over */
242 /*
243 * If we are not preempted this will work. If we are
244 * then we re-reading AR_TSF_U32 does no good as the
245 * low bits will be meaningless. Likewise reading
246 * L32, U32, U32, then comparing the last two reads
247 * to check for rollover doesn't help if preempted--so
248 * we take this approach as it costs one less PCI read
249 * which can be noticeable when doing things like
250 * timestamping packets in monitor mode.
251 */
252 u32++;
253 }
254 return (((uint64_t) u32) << 32) | ((uint64_t) low2);
255 }
256
257 /*
258 * Get the current hardware tsf for stamlme
259 */
260 uint32_t
ar5212GetTsf32(struct ath_hal * ah)261 ar5212GetTsf32(struct ath_hal *ah)
262 {
263 return OS_REG_READ(ah, AR_TSF_L32);
264 }
265
266 void
ar5212SetTsf64(struct ath_hal * ah,uint64_t tsf64)267 ar5212SetTsf64(struct ath_hal *ah, uint64_t tsf64)
268 {
269 OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
270 OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
271 }
272
273 /*
274 * Reset the current hardware tsf for stamlme.
275 */
276 void
ar5212ResetTsf(struct ath_hal * ah)277 ar5212ResetTsf(struct ath_hal *ah)
278 {
279
280 uint32_t val = OS_REG_READ(ah, AR_BEACON);
281
282 OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
283 /*
284 * When resetting the TSF, write twice to the
285 * corresponding register; each write to the RESET_TSF bit toggles
286 * the internal signal to cause a reset of the TSF - but if the signal
287 * is left high, it will reset the TSF on the next chip reset also!
288 * writing the bit an even number of times fixes this issue
289 */
290 OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
291 }
292
293 /*
294 * Set or clear hardware basic rate bit
295 * Set hardware basic rate set if basic rate is found
296 * and basic rate is equal or less than 2Mbps
297 */
298 void
ar5212SetBasicRate(struct ath_hal * ah,HAL_RATE_SET * rs)299 ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *rs)
300 {
301 const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
302 uint32_t reg;
303 uint8_t xset;
304 int i;
305
306 if (chan == AH_NULL || !IEEE80211_IS_CHAN_CCK(chan))
307 return;
308 xset = 0;
309 for (i = 0; i < rs->rs_count; i++) {
310 uint8_t rset = rs->rs_rates[i];
311 /* Basic rate defined? */
312 if ((rset & 0x80) && (rset &= 0x7f) >= xset)
313 xset = rset;
314 }
315 /*
316 * Set the h/w bit to reflect whether or not the basic
317 * rate is found to be equal or less than 2Mbps.
318 */
319 reg = OS_REG_READ(ah, AR_STA_ID1);
320 if (xset && xset/2 <= 2)
321 OS_REG_WRITE(ah, AR_STA_ID1, reg | AR_STA_ID1_BASE_RATE_11B);
322 else
323 OS_REG_WRITE(ah, AR_STA_ID1, reg &~ AR_STA_ID1_BASE_RATE_11B);
324 }
325
326 /*
327 * Grab a semi-random value from hardware registers - may not
328 * change often
329 */
330 uint32_t
ar5212GetRandomSeed(struct ath_hal * ah)331 ar5212GetRandomSeed(struct ath_hal *ah)
332 {
333 uint32_t nf;
334
335 nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
336 if (nf & 0x100)
337 nf = 0 - ((nf ^ 0x1ff) + 1);
338 return (OS_REG_READ(ah, AR_TSF_U32) ^
339 OS_REG_READ(ah, AR_TSF_L32) ^ nf);
340 }
341
342 /*
343 * Detect if our card is present
344 */
345 HAL_BOOL
ar5212DetectCardPresent(struct ath_hal * ah)346 ar5212DetectCardPresent(struct ath_hal *ah)
347 {
348 uint16_t macVersion, macRev;
349 uint32_t v;
350
351 /*
352 * Read the Silicon Revision register and compare that
353 * to what we read at attach time. If the same, we say
354 * a card/device is present.
355 */
356 v = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID;
357 macVersion = v >> AR_SREV_ID_S;
358 macRev = v & AR_SREV_REVISION;
359 return (AH_PRIVATE(ah)->ah_macVersion == macVersion &&
360 AH_PRIVATE(ah)->ah_macRev == macRev);
361 }
362
363 void
ar5212EnableMibCounters(struct ath_hal * ah)364 ar5212EnableMibCounters(struct ath_hal *ah)
365 {
366 /* NB: this just resets the mib counter machinery */
367 OS_REG_WRITE(ah, AR_MIBC,
368 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f);
369 }
370
371 void
ar5212DisableMibCounters(struct ath_hal * ah)372 ar5212DisableMibCounters(struct ath_hal *ah)
373 {
374 OS_REG_WRITE(ah, AR_MIBC, AR_MIBC | AR_MIBC_CMC);
375 }
376
377 /*
378 * Update MIB Counters
379 */
380 void
ar5212UpdateMibCounters(struct ath_hal * ah,HAL_MIB_STATS * stats)381 ar5212UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS* stats)
382 {
383 stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL);
384 stats->rts_bad += OS_REG_READ(ah, AR_RTS_FAIL);
385 stats->fcs_bad += OS_REG_READ(ah, AR_FCS_FAIL);
386 stats->rts_good += OS_REG_READ(ah, AR_RTS_OK);
387 stats->beacons += OS_REG_READ(ah, AR_BEACON_CNT);
388 }
389
390 /*
391 * Detect if the HW supports spreading a CCK signal on channel 14
392 */
393 HAL_BOOL
ar5212IsJapanChannelSpreadSupported(struct ath_hal * ah)394 ar5212IsJapanChannelSpreadSupported(struct ath_hal *ah)
395 {
396 return AH_TRUE;
397 }
398
399 /*
400 * Get the rssi of frame curently being received.
401 */
402 uint32_t
ar5212GetCurRssi(struct ath_hal * ah)403 ar5212GetCurRssi(struct ath_hal *ah)
404 {
405 return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff);
406 }
407
408 u_int
ar5212GetDefAntenna(struct ath_hal * ah)409 ar5212GetDefAntenna(struct ath_hal *ah)
410 {
411 return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7);
412 }
413
414 void
ar5212SetDefAntenna(struct ath_hal * ah,u_int antenna)415 ar5212SetDefAntenna(struct ath_hal *ah, u_int antenna)
416 {
417 OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
418 }
419
420 HAL_ANT_SETTING
ar5212GetAntennaSwitch(struct ath_hal * ah)421 ar5212GetAntennaSwitch(struct ath_hal *ah)
422 {
423 return AH5212(ah)->ah_antControl;
424 }
425
426 HAL_BOOL
ar5212SetAntennaSwitch(struct ath_hal * ah,HAL_ANT_SETTING setting)427 ar5212SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING setting)
428 {
429 struct ath_hal_5212 *ahp = AH5212(ah);
430 const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
431
432 if (!ahp->ah_phyPowerOn || chan == AH_NULL) {
433 /* PHY powered off, just stash settings */
434 ahp->ah_antControl = setting;
435 ahp->ah_diversity = (setting == HAL_ANT_VARIABLE);
436 return AH_TRUE;
437 }
438 return ar5212SetAntennaSwitchInternal(ah, setting, chan);
439 }
440
441 HAL_BOOL
ar5212IsSleepAfterBeaconBroken(struct ath_hal * ah)442 ar5212IsSleepAfterBeaconBroken(struct ath_hal *ah)
443 {
444 return AH_TRUE;
445 }
446
447 HAL_BOOL
ar5212SetSifsTime(struct ath_hal * ah,u_int us)448 ar5212SetSifsTime(struct ath_hal *ah, u_int us)
449 {
450 struct ath_hal_5212 *ahp = AH5212(ah);
451
452 if (us > ath_hal_mac_usec(ah, 0xffff)) {
453 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n",
454 __func__, us);
455 ahp->ah_sifstime = (u_int) -1; /* restore default handling */
456 return AH_FALSE;
457 } else {
458 /* convert to system clocks */
459 OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us-2));
460 ahp->ah_sifstime = us;
461 return AH_TRUE;
462 }
463 }
464
465 u_int
ar5212GetSifsTime(struct ath_hal * ah)466 ar5212GetSifsTime(struct ath_hal *ah)
467 {
468 u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SIFS) & 0xffff;
469 return ath_hal_mac_usec(ah, clks)+2; /* convert from system clocks */
470 }
471
472 HAL_BOOL
ar5212SetSlotTime(struct ath_hal * ah,u_int us)473 ar5212SetSlotTime(struct ath_hal *ah, u_int us)
474 {
475 struct ath_hal_5212 *ahp = AH5212(ah);
476
477 if (us < HAL_SLOT_TIME_6 || us > ath_hal_mac_usec(ah, 0xffff)) {
478 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n",
479 __func__, us);
480 ahp->ah_slottime = (u_int) -1; /* restore default handling */
481 return AH_FALSE;
482 } else {
483 /* convert to system clocks */
484 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath_hal_mac_clks(ah, us));
485 ahp->ah_slottime = us;
486 return AH_TRUE;
487 }
488 }
489
490 u_int
ar5212GetSlotTime(struct ath_hal * ah)491 ar5212GetSlotTime(struct ath_hal *ah)
492 {
493 u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
494 return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
495 }
496
497 HAL_BOOL
ar5212SetAckTimeout(struct ath_hal * ah,u_int us)498 ar5212SetAckTimeout(struct ath_hal *ah, u_int us)
499 {
500 struct ath_hal_5212 *ahp = AH5212(ah);
501
502 if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
503 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n",
504 __func__, us);
505 ahp->ah_acktimeout = (u_int) -1; /* restore default handling */
506 return AH_FALSE;
507 } else {
508 /* convert to system clocks */
509 OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
510 AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us));
511 ahp->ah_acktimeout = us;
512 return AH_TRUE;
513 }
514 }
515
516 u_int
ar5212GetAckTimeout(struct ath_hal * ah)517 ar5212GetAckTimeout(struct ath_hal *ah)
518 {
519 u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK);
520 return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
521 }
522
523 u_int
ar5212GetAckCTSRate(struct ath_hal * ah)524 ar5212GetAckCTSRate(struct ath_hal *ah)
525 {
526 return ((AH5212(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0);
527 }
528
529 HAL_BOOL
ar5212SetAckCTSRate(struct ath_hal * ah,u_int high)530 ar5212SetAckCTSRate(struct ath_hal *ah, u_int high)
531 {
532 struct ath_hal_5212 *ahp = AH5212(ah);
533
534 if (high) {
535 OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
536 ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB;
537 } else {
538 OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
539 ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB;
540 }
541 return AH_TRUE;
542 }
543
544 HAL_BOOL
ar5212SetCTSTimeout(struct ath_hal * ah,u_int us)545 ar5212SetCTSTimeout(struct ath_hal *ah, u_int us)
546 {
547 struct ath_hal_5212 *ahp = AH5212(ah);
548
549 if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
550 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n",
551 __func__, us);
552 ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */
553 return AH_FALSE;
554 } else {
555 /* convert to system clocks */
556 OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
557 AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us));
558 ahp->ah_ctstimeout = us;
559 return AH_TRUE;
560 }
561 }
562
563 u_int
ar5212GetCTSTimeout(struct ath_hal * ah)564 ar5212GetCTSTimeout(struct ath_hal *ah)
565 {
566 u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
567 return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
568 }
569
570 /* Setup decompression for given key index */
571 HAL_BOOL
ar5212SetDecompMask(struct ath_hal * ah,uint16_t keyidx,int en)572 ar5212SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
573 {
574 struct ath_hal_5212 *ahp = AH5212(ah);
575
576 if (keyidx >= HAL_DECOMP_MASK_SIZE)
577 return AH_FALSE;
578 OS_REG_WRITE(ah, AR_DCM_A, keyidx);
579 OS_REG_WRITE(ah, AR_DCM_D, en ? AR_DCM_D_EN : 0);
580 ahp->ah_decompMask[keyidx] = en;
581
582 return AH_TRUE;
583 }
584
585 /* Setup coverage class */
586 void
ar5212SetCoverageClass(struct ath_hal * ah,uint8_t coverageclass,int now)587 ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
588 {
589 uint32_t slot, timeout, eifs;
590 u_int clkRate;
591
592 AH_PRIVATE(ah)->ah_coverageClass = coverageclass;
593
594 if (now) {
595 if (AH_PRIVATE(ah)->ah_coverageClass == 0)
596 return;
597
598 /* Don't apply coverage class to non A channels */
599 if (!IEEE80211_IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan))
600 return;
601
602 /* Get core clock rate */
603 clkRate = ath_hal_mac_clks(ah, 1);
604
605 /* Compute EIFS */
606 slot = coverageclass * 3 * clkRate;
607 eifs = coverageclass * 6 * clkRate;
608 if (IEEE80211_IS_CHAN_HALF(AH_PRIVATE(ah)->ah_curchan)) {
609 slot += IFS_SLOT_HALF_RATE;
610 eifs += IFS_EIFS_HALF_RATE;
611 } else if (IEEE80211_IS_CHAN_QUARTER(AH_PRIVATE(ah)->ah_curchan)) {
612 slot += IFS_SLOT_QUARTER_RATE;
613 eifs += IFS_EIFS_QUARTER_RATE;
614 } else { /* full rate */
615 slot += IFS_SLOT_FULL_RATE;
616 eifs += IFS_EIFS_FULL_RATE;
617 }
618
619 /*
620 * Add additional time for air propagation for ACK and CTS
621 * timeouts. This value is in core clocks.
622 */
623 timeout = ACK_CTS_TIMEOUT_11A + (coverageclass * 3 * clkRate);
624
625 /*
626 * Write the values: slot, eifs, ack/cts timeouts.
627 */
628 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
629 OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
630 OS_REG_WRITE(ah, AR_TIME_OUT,
631 SM(timeout, AR_TIME_OUT_CTS)
632 | SM(timeout, AR_TIME_OUT_ACK));
633 }
634 }
635
636 HAL_STATUS
ar5212SetQuiet(struct ath_hal * ah,uint32_t period,uint32_t duration,uint32_t nextStart,HAL_QUIET_FLAG flag)637 ar5212SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
638 uint32_t nextStart, HAL_QUIET_FLAG flag)
639 {
640 OS_REG_WRITE(ah, AR_QUIET2, period | (duration << AR_QUIET2_QUIET_DUR_S));
641 if (flag & HAL_QUIET_ENABLE) {
642 OS_REG_WRITE(ah, AR_QUIET1, nextStart | (1 << 16));
643 }
644 else {
645 OS_REG_WRITE(ah, AR_QUIET1, nextStart);
646 }
647 return HAL_OK;
648 }
649
650 void
ar5212SetPCUConfig(struct ath_hal * ah)651 ar5212SetPCUConfig(struct ath_hal *ah)
652 {
653 ar5212SetOperatingMode(ah, AH_PRIVATE(ah)->ah_opmode);
654 }
655
656 /*
657 * Return whether an external 32KHz crystal should be used
658 * to reduce power consumption when sleeping. We do so if
659 * the crystal is present (obtained from EEPROM) and if we
660 * are not running as an AP and are configured to use it.
661 */
662 HAL_BOOL
ar5212Use32KHzclock(struct ath_hal * ah,HAL_OPMODE opmode)663 ar5212Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode)
664 {
665 if (opmode != HAL_M_HOSTAP) {
666 struct ath_hal_5212 *ahp = AH5212(ah);
667 return ath_hal_eepromGetFlag(ah, AR_EEP_32KHZCRYSTAL) &&
668 (ahp->ah_enable32kHzClock == USE_32KHZ ||
669 ahp->ah_enable32kHzClock == AUTO_32KHZ);
670 } else
671 return AH_FALSE;
672 }
673
674 /*
675 * If 32KHz clock exists, use it to lower power consumption during sleep
676 *
677 * Note: If clock is set to 32 KHz, delays on accessing certain
678 * baseband registers (27-31, 124-127) are required.
679 */
680 void
ar5212SetupClock(struct ath_hal * ah,HAL_OPMODE opmode)681 ar5212SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
682 {
683 if (ar5212Use32KHzclock(ah, opmode)) {
684 /*
685 * Enable clocks to be turned OFF in BB during sleep
686 * and also enable turning OFF 32MHz/40MHz Refclk
687 * from A2.
688 */
689 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
690 OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
691 IS_RAD5112_ANY(ah) || IS_5413(ah) ? 0x14 : 0x18);
692 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 1);
693 OS_REG_WRITE(ah, AR_TSF_PARM, 61); /* 32 KHz TSF incr */
694 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 1);
695
696 if (IS_2413(ah) || IS_5413(ah) || IS_2417(ah)) {
697 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x26);
698 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0d);
699 OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x07);
700 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0x3f);
701 /* # Set sleep clock rate to 32 KHz. */
702 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x2);
703 } else {
704 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x0a);
705 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0c);
706 OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x03);
707 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0x20);
708 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x3);
709 }
710 } else {
711 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x0);
712 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0);
713
714 OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32MHz TSF inc */
715
716 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
717 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x7f);
718
719 if (IS_2417(ah))
720 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0a);
721 else if (IS_HB63(ah))
722 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x32);
723 else
724 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
725 OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c);
726 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff);
727 OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
728 IS_RAD5112_ANY(ah) || IS_5413(ah) || IS_2417(ah) ? 0x14 : 0x18);
729 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
730 IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
731 }
732 }
733
734 /*
735 * If 32KHz clock exists, turn it off and turn back on the 32Mhz
736 */
737 void
ar5212RestoreClock(struct ath_hal * ah,HAL_OPMODE opmode)738 ar5212RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode)
739 {
740 if (ar5212Use32KHzclock(ah, opmode)) {
741 /* # Set sleep clock rate back to 32 MHz. */
742 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0);
743 OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0);
744
745 OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32 MHz TSF incr */
746 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
747 IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
748
749 /*
750 * Restore BB registers to power-on defaults
751 */
752 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
753 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x7f);
754 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
755 OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c);
756 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff);
757 OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
758 IS_RAD5112_ANY(ah) || IS_5413(ah) ? 0x14 : 0x18);
759 }
760 }
761
762 /*
763 * Adjust NF based on statistical values for 5GHz frequencies.
764 * Default method: this may be overridden by the rf backend.
765 */
766 int16_t
ar5212GetNfAdjust(struct ath_hal * ah,const HAL_CHANNEL_INTERNAL * c)767 ar5212GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
768 {
769 static const struct {
770 uint16_t freqLow;
771 int16_t adjust;
772 } adjustDef[] = {
773 { 5790, 11 }, /* NB: ordered high -> low */
774 { 5730, 10 },
775 { 5690, 9 },
776 { 5660, 8 },
777 { 5610, 7 },
778 { 5530, 5 },
779 { 5450, 4 },
780 { 5379, 2 },
781 { 5209, 0 },
782 { 3000, 1 },
783 { 0, 0 },
784 };
785 int i;
786
787 for (i = 0; c->channel <= adjustDef[i].freqLow; i++)
788 ;
789 return adjustDef[i].adjust;
790 }
791
792 HAL_STATUS
ar5212GetCapability(struct ath_hal * ah,HAL_CAPABILITY_TYPE type,uint32_t capability,uint32_t * result)793 ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
794 uint32_t capability, uint32_t *result)
795 {
796 #define MACVERSION(ah) AH_PRIVATE(ah)->ah_macVersion
797 struct ath_hal_5212 *ahp = AH5212(ah);
798 const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
799 const struct ar5212AniState *ani;
800
801 switch (type) {
802 case HAL_CAP_CIPHER: /* cipher handled in hardware */
803 switch (capability) {
804 case HAL_CIPHER_AES_CCM:
805 return pCap->halCipherAesCcmSupport ?
806 HAL_OK : HAL_ENOTSUPP;
807 case HAL_CIPHER_AES_OCB:
808 case HAL_CIPHER_TKIP:
809 case HAL_CIPHER_WEP:
810 case HAL_CIPHER_MIC:
811 case HAL_CIPHER_CLR:
812 return HAL_OK;
813 default:
814 return HAL_ENOTSUPP;
815 }
816 case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */
817 switch (capability) {
818 case 0: /* hardware capability */
819 return HAL_OK;
820 case 1:
821 return (ahp->ah_staId1Defaults &
822 AR_STA_ID1_CRPT_MIC_ENABLE) ? HAL_OK : HAL_ENXIO;
823 }
824 return HAL_EINVAL;
825 case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */
826 switch (capability) {
827 case 0: /* hardware capability */
828 return pCap->halTkipMicTxRxKeySupport ?
829 HAL_ENXIO : HAL_OK;
830 case 1: /* current setting */
831 return (ahp->ah_miscMode &
832 AR_MISC_MODE_MIC_NEW_LOC_ENABLE) ? HAL_ENXIO : HAL_OK;
833 }
834 return HAL_EINVAL;
835 case HAL_CAP_WME_TKIPMIC: /* hardware can do TKIP MIC w/ WMM */
836 /* XXX move to capability bit */
837 return MACVERSION(ah) > AR_SREV_VERSION_VENICE ||
838 (MACVERSION(ah) == AR_SREV_VERSION_VENICE &&
839 AH_PRIVATE(ah)->ah_macRev >= 8) ? HAL_OK : HAL_ENOTSUPP;
840 case HAL_CAP_DIVERSITY: /* hardware supports fast diversity */
841 switch (capability) {
842 case 0: /* hardware capability */
843 return HAL_OK;
844 case 1: /* current setting */
845 return ahp->ah_diversity ? HAL_OK : HAL_ENXIO;
846 case HAL_CAP_STRONG_DIV:
847 *result = OS_REG_READ(ah, AR_PHY_RESTART);
848 *result = MS(*result, AR_PHY_RESTART_DIV_GC);
849 return HAL_OK;
850 }
851 return HAL_EINVAL;
852 case HAL_CAP_DIAG:
853 *result = AH_PRIVATE(ah)->ah_diagreg;
854 return HAL_OK;
855 case HAL_CAP_TPC:
856 switch (capability) {
857 case 0: /* hardware capability */
858 return HAL_OK;
859 case 1:
860 return ahp->ah_tpcEnabled ? HAL_OK : HAL_ENXIO;
861 }
862 return HAL_OK;
863 case HAL_CAP_PHYDIAG: /* radar pulse detection capability */
864 switch (capability) {
865 case HAL_CAP_RADAR:
866 return ath_hal_eepromGetFlag(ah, AR_EEP_AMODE) ?
867 HAL_OK: HAL_ENXIO;
868 case HAL_CAP_AR:
869 return (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) ||
870 ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) ?
871 HAL_OK: HAL_ENXIO;
872 }
873 return HAL_ENXIO;
874 case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */
875 switch (capability) {
876 case 0: /* hardware capability */
877 return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENXIO;
878 case 1:
879 return (ahp->ah_staId1Defaults &
880 AR_STA_ID1_MCAST_KSRCH) ? HAL_OK : HAL_ENXIO;
881 }
882 return HAL_EINVAL;
883 case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */
884 switch (capability) {
885 case 0: /* hardware capability */
886 return pCap->halTsfAddSupport ? HAL_OK : HAL_ENOTSUPP;
887 case 1:
888 return (ahp->ah_miscMode & AR_MISC_MODE_TX_ADD_TSF) ?
889 HAL_OK : HAL_ENXIO;
890 }
891 return HAL_EINVAL;
892 case HAL_CAP_TPC_ACK:
893 *result = MS(ahp->ah_macTPC, AR_TPC_ACK);
894 return HAL_OK;
895 case HAL_CAP_TPC_CTS:
896 *result = MS(ahp->ah_macTPC, AR_TPC_CTS);
897 return HAL_OK;
898 case HAL_CAP_INTMIT: /* interference mitigation */
899 switch (capability) {
900 case HAL_CAP_INTMIT_PRESENT: /* hardware capability */
901 return HAL_OK;
902 case HAL_CAP_INTMIT_ENABLE:
903 return (ahp->ah_procPhyErr & HAL_ANI_ENA) ?
904 HAL_OK : HAL_ENXIO;
905 case HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL:
906 case HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL:
907 case HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR:
908 case HAL_CAP_INTMIT_FIRSTEP_LEVEL:
909 case HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL:
910 ani = ar5212AniGetCurrentState(ah);
911 if (ani == AH_NULL)
912 return HAL_ENXIO;
913 switch (capability) {
914 case 2: *result = ani->noiseImmunityLevel; break;
915 case 3: *result = !ani->ofdmWeakSigDetectOff; break;
916 case 4: *result = ani->cckWeakSigThreshold; break;
917 case 5: *result = ani->firstepLevel; break;
918 case 6: *result = ani->spurImmunityLevel; break;
919 }
920 return HAL_OK;
921 }
922 return HAL_EINVAL;
923 default:
924 return ath_hal_getcapability(ah, type, capability, result);
925 }
926 #undef MACVERSION
927 }
928
929 HAL_BOOL
ar5212SetCapability(struct ath_hal * ah,HAL_CAPABILITY_TYPE type,uint32_t capability,uint32_t setting,HAL_STATUS * status)930 ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
931 uint32_t capability, uint32_t setting, HAL_STATUS *status)
932 {
933 #define N(a) (sizeof(a)/sizeof(a[0]))
934 struct ath_hal_5212 *ahp = AH5212(ah);
935 const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
936 uint32_t v;
937
938 switch (type) {
939 case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */
940 if (setting)
941 ahp->ah_staId1Defaults |= AR_STA_ID1_CRPT_MIC_ENABLE;
942 else
943 ahp->ah_staId1Defaults &= ~AR_STA_ID1_CRPT_MIC_ENABLE;
944 return AH_TRUE;
945 case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */
946 if (!pCap->halTkipMicTxRxKeySupport)
947 return AH_FALSE;
948 /* NB: true =>'s use split key cache layout */
949 if (setting)
950 ahp->ah_miscMode &= ~AR_MISC_MODE_MIC_NEW_LOC_ENABLE;
951 else
952 ahp->ah_miscMode |= AR_MISC_MODE_MIC_NEW_LOC_ENABLE;
953 /* NB: write here so keys can be setup w/o a reset */
954 OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);
955 return AH_TRUE;
956 case HAL_CAP_DIVERSITY:
957 switch (capability) {
958 case 0:
959 return AH_FALSE;
960 case 1: /* setting */
961 if (ahp->ah_phyPowerOn) {
962 if (capability == HAL_CAP_STRONG_DIV) {
963 v = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
964 if (setting)
965 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
966 else
967 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
968 OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
969 }
970 }
971 ahp->ah_diversity = (setting != 0);
972 return AH_TRUE;
973
974 case HAL_CAP_STRONG_DIV:
975 if (! ahp->ah_phyPowerOn)
976 return AH_FALSE;
977 v = OS_REG_READ(ah, AR_PHY_RESTART);
978 v &= ~AR_PHY_RESTART_DIV_GC;
979 v |= SM(setting, AR_PHY_RESTART_DIV_GC);
980 OS_REG_WRITE(ah, AR_PHY_RESTART, v);
981 return AH_TRUE;
982 default:
983 return AH_FALSE;
984 }
985 case HAL_CAP_DIAG: /* hardware diagnostic support */
986 /*
987 * NB: could split this up into virtual capabilities,
988 * (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly
989 * seems worth the additional complexity.
990 */
991 AH_PRIVATE(ah)->ah_diagreg = setting;
992 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
993 return AH_TRUE;
994 case HAL_CAP_TPC:
995 ahp->ah_tpcEnabled = (setting != 0);
996 return AH_TRUE;
997 case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */
998 if (setting)
999 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1000 else
1001 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1002 return AH_TRUE;
1003 case HAL_CAP_TPC_ACK:
1004 case HAL_CAP_TPC_CTS:
1005 setting += ahp->ah_txPowerIndexOffset;
1006 if (setting > 63)
1007 setting = 63;
1008 if (type == HAL_CAP_TPC_ACK) {
1009 ahp->ah_macTPC &= AR_TPC_ACK;
1010 ahp->ah_macTPC |= MS(setting, AR_TPC_ACK);
1011 } else {
1012 ahp->ah_macTPC &= AR_TPC_CTS;
1013 ahp->ah_macTPC |= MS(setting, AR_TPC_CTS);
1014 }
1015 OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC);
1016 return AH_TRUE;
1017 case HAL_CAP_INTMIT: { /* interference mitigation */
1018 /* This maps the public ANI commands to the internal ANI commands */
1019 /* Private: HAL_ANI_CMD; Public: HAL_CAP_INTMIT_CMD */
1020 static const HAL_ANI_CMD cmds[] = {
1021 HAL_ANI_PRESENT,
1022 HAL_ANI_MODE,
1023 HAL_ANI_NOISE_IMMUNITY_LEVEL,
1024 HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
1025 HAL_ANI_CCK_WEAK_SIGNAL_THR,
1026 HAL_ANI_FIRSTEP_LEVEL,
1027 HAL_ANI_SPUR_IMMUNITY_LEVEL,
1028 };
1029 return capability < N(cmds) ?
1030 AH5212(ah)->ah_aniControl(ah, cmds[capability], setting) :
1031 AH_FALSE;
1032 }
1033 case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */
1034 if (pCap->halTsfAddSupport) {
1035 if (setting)
1036 ahp->ah_miscMode |= AR_MISC_MODE_TX_ADD_TSF;
1037 else
1038 ahp->ah_miscMode &= ~AR_MISC_MODE_TX_ADD_TSF;
1039 return AH_TRUE;
1040 }
1041 /* fall thru... */
1042 default:
1043 return ath_hal_setcapability(ah, type, capability,
1044 setting, status);
1045 }
1046 #undef N
1047 }
1048
1049 HAL_BOOL
ar5212GetDiagState(struct ath_hal * ah,int request,const void * args,uint32_t argsize,void ** result,uint32_t * resultsize)1050 ar5212GetDiagState(struct ath_hal *ah, int request,
1051 const void *args, uint32_t argsize,
1052 void **result, uint32_t *resultsize)
1053 {
1054 struct ath_hal_5212 *ahp = AH5212(ah);
1055 HAL_ANI_STATS *astats;
1056
1057 (void) ahp;
1058 if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize))
1059 return AH_TRUE;
1060 switch (request) {
1061 case HAL_DIAG_EEPROM:
1062 case HAL_DIAG_EEPROM_EXP_11A:
1063 case HAL_DIAG_EEPROM_EXP_11B:
1064 case HAL_DIAG_EEPROM_EXP_11G:
1065 case HAL_DIAG_RFGAIN:
1066 return ath_hal_eepromDiag(ah, request,
1067 args, argsize, result, resultsize);
1068 case HAL_DIAG_RFGAIN_CURSTEP:
1069 *result = __DECONST(void *, ahp->ah_gainValues.currStep);
1070 *resultsize = (*result == AH_NULL) ?
1071 0 : sizeof(GAIN_OPTIMIZATION_STEP);
1072 return AH_TRUE;
1073 case HAL_DIAG_PCDAC:
1074 *result = ahp->ah_pcdacTable;
1075 *resultsize = ahp->ah_pcdacTableSize;
1076 return AH_TRUE;
1077 case HAL_DIAG_TXRATES:
1078 *result = &ahp->ah_ratesArray[0];
1079 *resultsize = sizeof(ahp->ah_ratesArray);
1080 return AH_TRUE;
1081 case HAL_DIAG_ANI_CURRENT:
1082 *result = ar5212AniGetCurrentState(ah);
1083 *resultsize = (*result == AH_NULL) ?
1084 0 : sizeof(struct ar5212AniState);
1085 return AH_TRUE;
1086 case HAL_DIAG_ANI_STATS:
1087 OS_MEMZERO(&ahp->ext_ani_stats, sizeof(ahp->ext_ani_stats));
1088 astats = ar5212AniGetCurrentStats(ah);
1089 if (astats == NULL) {
1090 *result = NULL;
1091 *resultsize = 0;
1092 } else {
1093 OS_MEMCPY(&ahp->ext_ani_stats, astats, sizeof(HAL_ANI_STATS));
1094 *result = &ahp->ext_ani_stats;
1095 *resultsize = sizeof(ahp->ext_ani_stats);
1096 }
1097 return AH_TRUE;
1098 case HAL_DIAG_ANI_CMD:
1099 if (argsize != 2*sizeof(uint32_t))
1100 return AH_FALSE;
1101 AH5212(ah)->ah_aniControl(ah, ((const uint32_t *)args)[0],
1102 ((const uint32_t *)args)[1]);
1103 return AH_TRUE;
1104 case HAL_DIAG_ANI_PARAMS:
1105 /*
1106 * NB: We assume struct ar5212AniParams is identical
1107 * to HAL_ANI_PARAMS; if they diverge then we'll need
1108 * to handle it here
1109 */
1110 if (argsize == 0 && args == AH_NULL) {
1111 struct ar5212AniState *aniState =
1112 ar5212AniGetCurrentState(ah);
1113 if (aniState == AH_NULL)
1114 return AH_FALSE;
1115 *result = __DECONST(void *, aniState->params);
1116 *resultsize = sizeof(struct ar5212AniParams);
1117 return AH_TRUE;
1118 } else {
1119 if (argsize != sizeof(struct ar5212AniParams))
1120 return AH_FALSE;
1121 return ar5212AniSetParams(ah, args, args);
1122 }
1123 break;
1124 }
1125 return AH_FALSE;
1126 }
1127
1128 /*
1129 * Check whether there's an in-progress NF completion.
1130 *
1131 * Returns AH_TRUE if there's a in-progress NF calibration, AH_FALSE
1132 * otherwise.
1133 */
1134 HAL_BOOL
ar5212IsNFCalInProgress(struct ath_hal * ah)1135 ar5212IsNFCalInProgress(struct ath_hal *ah)
1136 {
1137 if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)
1138 return AH_TRUE;
1139 return AH_FALSE;
1140 }
1141
1142 /*
1143 * Wait for an in-progress NF calibration to complete.
1144 *
1145 * The completion function waits "i" times 10uS.
1146 * It returns AH_TRUE if the NF calibration completed (or was never
1147 * in progress); AH_FALSE if it was still in progress after "i" checks.
1148 */
1149 HAL_BOOL
ar5212WaitNFCalComplete(struct ath_hal * ah,int i)1150 ar5212WaitNFCalComplete(struct ath_hal *ah, int i)
1151 {
1152 int j;
1153 if (i <= 0)
1154 i = 1; /* it should run at least once */
1155 for (j = 0; j < i; j++) {
1156 if (! ar5212IsNFCalInProgress(ah))
1157 return AH_TRUE;
1158 OS_DELAY(10);
1159 }
1160 return AH_FALSE;
1161 }
1162
1163 void
ar5212EnableDfs(struct ath_hal * ah,HAL_PHYERR_PARAM * pe)1164 ar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
1165 {
1166 uint32_t val;
1167 val = OS_REG_READ(ah, AR_PHY_RADAR_0);
1168
1169 if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
1170 val &= ~AR_PHY_RADAR_0_FIRPWR;
1171 val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
1172 }
1173 if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
1174 val &= ~AR_PHY_RADAR_0_RRSSI;
1175 val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
1176 }
1177 if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
1178 val &= ~AR_PHY_RADAR_0_HEIGHT;
1179 val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
1180 }
1181 if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
1182 val &= ~AR_PHY_RADAR_0_PRSSI;
1183 val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
1184 }
1185 if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
1186 val &= ~AR_PHY_RADAR_0_INBAND;
1187 val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
1188 }
1189 if (pe->pe_enabled)
1190 val |= AR_PHY_RADAR_0_ENA;
1191 else
1192 val &= ~ AR_PHY_RADAR_0_ENA;
1193
1194 if (IS_5413(ah)) {
1195 if (pe->pe_blockradar == 1)
1196 OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
1197 AR_PHY_RADAR_2_BLOCKOFDMWEAK);
1198 else
1199 OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
1200 AR_PHY_RADAR_2_BLOCKOFDMWEAK);
1201
1202 if (pe->pe_en_relstep_check == 1)
1203 OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
1204 AR_PHY_RADAR_2_ENRELSTEPCHK);
1205 else
1206 OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
1207 AR_PHY_RADAR_2_ENRELSTEPCHK);
1208
1209 if (pe->pe_usefir128 == 1)
1210 OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
1211 AR_PHY_RADAR_2_USEFIR128);
1212 else
1213 OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
1214 AR_PHY_RADAR_2_USEFIR128);
1215
1216 if (pe->pe_enmaxrssi == 1)
1217 OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
1218 AR_PHY_RADAR_2_ENMAXRSSI);
1219 else
1220 OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
1221 AR_PHY_RADAR_2_ENMAXRSSI);
1222
1223 if (pe->pe_enrelpwr == 1)
1224 OS_REG_SET_BIT(ah, AR_PHY_RADAR_2,
1225 AR_PHY_RADAR_2_ENRELPWRCHK);
1226 else
1227 OS_REG_CLR_BIT(ah, AR_PHY_RADAR_2,
1228 AR_PHY_RADAR_2_ENRELPWRCHK);
1229
1230 if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL)
1231 OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_2,
1232 AR_PHY_RADAR_2_RELPWR, pe->pe_relpwr);
1233
1234 if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL)
1235 OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_2,
1236 AR_PHY_RADAR_2_RELSTEP, pe->pe_relstep);
1237
1238 if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL)
1239 OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_2,
1240 AR_PHY_RADAR_2_MAXLEN, pe->pe_maxlen);
1241 }
1242
1243 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
1244 }
1245
1246 /*
1247 * Parameters for the AR5212 PHY.
1248 */
1249 #define AR5212_DFS_FIRPWR -35
1250 #define AR5212_DFS_RRSSI 20
1251 #define AR5212_DFS_HEIGHT 14
1252 #define AR5212_DFS_PRSSI 6
1253 #define AR5212_DFS_INBAND 4
1254
1255 /*
1256 * Default parameters for the AR5413 PHY.
1257 */
1258 #define AR5413_DFS_FIRPWR -34
1259 #define AR5413_DFS_RRSSI 20
1260 #define AR5413_DFS_HEIGHT 10
1261 #define AR5413_DFS_PRSSI 15
1262 #define AR5413_DFS_INBAND 6
1263 #define AR5413_DFS_RELPWR 8
1264 #define AR5413_DFS_RELSTEP 31
1265 #define AR5413_DFS_MAXLEN 255
1266
1267 HAL_BOOL
ar5212GetDfsDefaultThresh(struct ath_hal * ah,HAL_PHYERR_PARAM * pe)1268 ar5212GetDfsDefaultThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
1269 {
1270
1271 if (IS_5413(ah)) {
1272 pe->pe_firpwr = AR5413_DFS_FIRPWR;
1273 pe->pe_rrssi = AR5413_DFS_RRSSI;
1274 pe->pe_height = AR5413_DFS_HEIGHT;
1275 pe->pe_prssi = AR5413_DFS_PRSSI;
1276 pe->pe_inband = AR5413_DFS_INBAND;
1277 pe->pe_relpwr = AR5413_DFS_RELPWR;
1278 pe->pe_relstep = AR5413_DFS_RELSTEP;
1279 pe->pe_maxlen = AR5413_DFS_MAXLEN;
1280 pe->pe_usefir128 = 0;
1281 pe->pe_blockradar = 1;
1282 pe->pe_enmaxrssi = 1;
1283 pe->pe_enrelpwr = 1;
1284 pe->pe_en_relstep_check = 0;
1285 } else {
1286 pe->pe_firpwr = AR5212_DFS_FIRPWR;
1287 pe->pe_rrssi = AR5212_DFS_RRSSI;
1288 pe->pe_height = AR5212_DFS_HEIGHT;
1289 pe->pe_prssi = AR5212_DFS_PRSSI;
1290 pe->pe_inband = AR5212_DFS_INBAND;
1291 pe->pe_relpwr = 0;
1292 pe->pe_relstep = 0;
1293 pe->pe_maxlen = 0;
1294 pe->pe_usefir128 = 0;
1295 pe->pe_blockradar = 0;
1296 pe->pe_enmaxrssi = 0;
1297 pe->pe_enrelpwr = 0;
1298 pe->pe_en_relstep_check = 0;
1299 }
1300
1301 return (AH_TRUE);
1302 }
1303
1304 void
ar5212GetDfsThresh(struct ath_hal * ah,HAL_PHYERR_PARAM * pe)1305 ar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
1306 {
1307 uint32_t val,temp;
1308
1309 val = OS_REG_READ(ah, AR_PHY_RADAR_0);
1310
1311 temp = MS(val,AR_PHY_RADAR_0_FIRPWR);
1312 temp |= 0xFFFFFF80;
1313 pe->pe_firpwr = temp;
1314 pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
1315 pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT);
1316 pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
1317 pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
1318 pe->pe_enabled = !! (val & AR_PHY_RADAR_0_ENA);
1319
1320 pe->pe_relpwr = 0;
1321 pe->pe_relstep = 0;
1322 pe->pe_maxlen = 0;
1323 pe->pe_usefir128 = 0;
1324 pe->pe_blockradar = 0;
1325 pe->pe_enmaxrssi = 0;
1326 pe->pe_enrelpwr = 0;
1327 pe->pe_en_relstep_check = 0;
1328 pe->pe_extchannel = AH_FALSE;
1329
1330 if (IS_5413(ah)) {
1331 val = OS_REG_READ(ah, AR_PHY_RADAR_2);
1332 pe->pe_relpwr = !! MS(val, AR_PHY_RADAR_2_RELPWR);
1333 pe->pe_relstep = !! MS(val, AR_PHY_RADAR_2_RELSTEP);
1334 pe->pe_maxlen = !! MS(val, AR_PHY_RADAR_2_MAXLEN);
1335
1336 pe->pe_usefir128 = !! (val & AR_PHY_RADAR_2_USEFIR128);
1337 pe->pe_blockradar = !! (val & AR_PHY_RADAR_2_BLOCKOFDMWEAK);
1338 pe->pe_enmaxrssi = !! (val & AR_PHY_RADAR_2_ENMAXRSSI);
1339 pe->pe_enrelpwr = !! (val & AR_PHY_RADAR_2_ENRELPWRCHK);
1340 pe->pe_en_relstep_check =
1341 !! (val & AR_PHY_RADAR_2_ENRELSTEPCHK);
1342 }
1343 }
1344
1345 /*
1346 * Process the radar phy error and extract the pulse duration.
1347 */
1348 HAL_BOOL
ar5212ProcessRadarEvent(struct ath_hal * ah,struct ath_rx_status * rxs,uint64_t fulltsf,const char * buf,HAL_DFS_EVENT * event)1349 ar5212ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
1350 uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
1351 {
1352 uint8_t dur;
1353 uint8_t rssi;
1354
1355 /* Check whether the given phy error is a radar event */
1356 if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
1357 (rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT))
1358 return AH_FALSE;
1359
1360 /*
1361 * The first byte is the pulse width - if there's
1362 * no data, simply set the duration to 0
1363 */
1364 if (rxs->rs_datalen >= 1)
1365 /* The pulse width is byte 0 of the data */
1366 dur = ((uint8_t) buf[0]) & 0xff;
1367 else
1368 dur = 0;
1369
1370 /* Pulse RSSI is the normal reported RSSI */
1371 rssi = (uint8_t) rxs->rs_rssi;
1372
1373 /* 0 duration/rssi is not a valid radar event */
1374 if (dur == 0 && rssi == 0)
1375 return AH_FALSE;
1376
1377 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n",
1378 __func__, rssi, dur);
1379
1380 /* Record the event */
1381 event->re_full_ts = fulltsf;
1382 event->re_ts = rxs->rs_tstamp;
1383 event->re_rssi = rssi;
1384 event->re_dur = dur;
1385 event->re_flags = HAL_DFS_EVENT_PRICH;
1386
1387 return AH_TRUE;
1388 }
1389
1390 /*
1391 * Return whether 5GHz fast-clock (44MHz) is enabled.
1392 * It's always disabled for AR5212 series NICs.
1393 */
1394 HAL_BOOL
ar5212IsFastClockEnabled(struct ath_hal * ah)1395 ar5212IsFastClockEnabled(struct ath_hal *ah)
1396 {
1397 return AH_FALSE;
1398 }
1399
1400 /*
1401 * Return what percentage of the extension channel is busy.
1402 * This is always disabled for AR5212 series NICs.
1403 */
1404 uint32_t
ar5212Get11nExtBusy(struct ath_hal * ah)1405 ar5212Get11nExtBusy(struct ath_hal *ah)
1406 {
1407 return 0;
1408 }
1409
1410 /*
1411 * Channel survey support.
1412 */
1413 HAL_BOOL
ar5212GetMibCycleCounts(struct ath_hal * ah,HAL_SURVEY_SAMPLE * hsample)1414 ar5212GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample)
1415 {
1416 struct ath_hal_5212 *ahp = AH5212(ah);
1417 u_int32_t good = AH_TRUE;
1418
1419 /* XXX freeze/unfreeze mib counters */
1420 uint32_t rc = OS_REG_READ(ah, AR_RCCNT);
1421 uint32_t rf = OS_REG_READ(ah, AR_RFCNT);
1422 uint32_t tf = OS_REG_READ(ah, AR_TFCNT);
1423 uint32_t cc = OS_REG_READ(ah, AR_CCCNT); /* read cycles last */
1424
1425 if (ahp->ah_cycleCount == 0 || ahp->ah_cycleCount > cc) {
1426 /*
1427 * Cycle counter wrap (or initial call); it's not possible
1428 * to accurately calculate a value because the registers
1429 * right shift rather than wrap--so punt and return 0.
1430 */
1431 HALDEBUG(ah, HAL_DEBUG_ANY,
1432 "%s: cycle counter wrap. ExtBusy = 0\n", __func__);
1433 good = AH_FALSE;
1434 } else {
1435 hsample->cycle_count = cc - ahp->ah_cycleCount;
1436 hsample->chan_busy = rc - ahp->ah_ctlBusy;
1437 hsample->ext_chan_busy = 0;
1438 hsample->rx_busy = rf - ahp->ah_rxBusy;
1439 hsample->tx_busy = tf - ahp->ah_txBusy;
1440 }
1441
1442 /*
1443 * Keep a copy of the MIB results so the next sample has something
1444 * to work from.
1445 */
1446 ahp->ah_cycleCount = cc;
1447 ahp->ah_rxBusy = rf;
1448 ahp->ah_ctlBusy = rc;
1449 ahp->ah_txBusy = tf;
1450
1451 return (good);
1452 }
1453
1454 void
ar5212SetChainMasks(struct ath_hal * ah,uint32_t tx_chainmask,uint32_t rx_chainmask)1455 ar5212SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask,
1456 uint32_t rx_chainmask)
1457 {
1458 }
1459
1460 /*
1461 * Get the current NAV value from the hardware.
1462 *
1463 * 0xdeadbeef indicates the hardware is currently powered off.
1464 */
1465 u_int
ar5212GetNav(struct ath_hal * ah)1466 ar5212GetNav(struct ath_hal *ah)
1467 {
1468 uint32_t reg;
1469
1470 reg = OS_REG_READ(ah, AR_NAV);
1471
1472 if (reg == 0xdeadbeef)
1473 return (0);
1474 return (reg);
1475 }
1476
1477 /*
1478 * Set the current NAV value to the hardware.
1479 */
1480 void
ar5212SetNav(struct ath_hal * ah,u_int val)1481 ar5212SetNav(struct ath_hal *ah, u_int val)
1482 {
1483
1484 OS_REG_WRITE(ah, AR_NAV, val);
1485 }
1486