Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c
39566 views
1
/*-
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5
* Copyright (c) 2002-2006 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
24
#include "ar5211/ar5211.h"
25
#include "ar5211/ar5211reg.h"
26
#include "ar5211/ar5211phy.h"
27
28
#include "ah_eeprom_v3.h"
29
30
#define AR_NUM_GPIO 6 /* 6 GPIO bits */
31
#define AR_GPIOD_MASK 0x2f /* 6-bit mask */
32
33
void
34
ar5211GetMacAddress(struct ath_hal *ah, uint8_t *mac)
35
{
36
struct ath_hal_5211 *ahp = AH5211(ah);
37
38
OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN);
39
}
40
41
HAL_BOOL
42
ar5211SetMacAddress(struct ath_hal *ah, const uint8_t *mac)
43
{
44
struct ath_hal_5211 *ahp = AH5211(ah);
45
46
OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN);
47
return AH_TRUE;
48
}
49
50
void
51
ar5211GetBssIdMask(struct ath_hal *ah, uint8_t *mask)
52
{
53
static const uint8_t ones[IEEE80211_ADDR_LEN] =
54
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
55
OS_MEMCPY(mask, ones, IEEE80211_ADDR_LEN);
56
}
57
58
HAL_BOOL
59
ar5211SetBssIdMask(struct ath_hal *ah, const uint8_t *mask)
60
{
61
return AH_FALSE;
62
}
63
64
/*
65
* Read 16 bits of data from the specified EEPROM offset.
66
*/
67
HAL_BOOL
68
ar5211EepromRead(struct ath_hal *ah, u_int off, uint16_t *data)
69
{
70
OS_REG_WRITE(ah, AR_EEPROM_ADDR, off);
71
OS_REG_WRITE(ah, AR_EEPROM_CMD, AR_EEPROM_CMD_READ);
72
73
if (!ath_hal_wait(ah, AR_EEPROM_STS,
74
AR_EEPROM_STS_READ_COMPLETE | AR_EEPROM_STS_READ_ERROR,
75
AR_EEPROM_STS_READ_COMPLETE)) {
76
HALDEBUG(ah, HAL_DEBUG_ANY,
77
"%s: read failed for entry 0x%x\n", __func__, off);
78
return AH_FALSE;
79
}
80
*data = OS_REG_READ(ah, AR_EEPROM_DATA) & 0xffff;
81
return AH_TRUE;
82
}
83
84
#ifdef AH_SUPPORT_WRITE_EEPROM
85
/*
86
* Write 16 bits of data to the specified EEPROM offset.
87
*/
88
HAL_BOOL
89
ar5211EepromWrite(struct ath_hal *ah, u_int off, uint16_t data)
90
{
91
return AH_FALSE;
92
}
93
#endif /* AH_SUPPORT_WRITE_EEPROM */
94
95
/*
96
* Attempt to change the cards operating regulatory domain to the given value
97
*/
98
HAL_BOOL
99
ar5211SetRegulatoryDomain(struct ath_hal *ah,
100
uint16_t regDomain, HAL_STATUS *status)
101
{
102
HAL_STATUS ecode;
103
104
if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {
105
ecode = HAL_EINVAL;
106
goto bad;
107
}
108
/*
109
* Check if EEPROM is configured to allow this; must
110
* be a proper version and the protection bits must
111
* permit re-writing that segment of the EEPROM.
112
*/
113
if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {
114
ecode = HAL_EEWRITE;
115
goto bad;
116
}
117
#ifdef AH_SUPPORT_WRITE_REGDOMAIN
118
if (ar5211EepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) {
119
HALDEBUG(ah, HAL_DEBUG_ANY,
120
"%s: set regulatory domain to %u (0x%x)\n",
121
__func__, regDomain, regDomain);
122
AH_PRIVATE(ah)->ah_currentRD = regDomain;
123
return AH_TRUE;
124
}
125
#endif
126
ecode = HAL_EIO;
127
bad:
128
if (status)
129
*status = ecode;
130
return AH_FALSE;
131
}
132
133
/*
134
* Return the wireless modes (a,b,g,t) supported by hardware.
135
*
136
* This value is what is actually supported by the hardware
137
* and is unaffected by regulatory/country code settings.
138
*
139
*/
140
u_int
141
ar5211GetWirelessModes(struct ath_hal *ah)
142
{
143
u_int mode = 0;
144
145
if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {
146
mode = HAL_MODE_11A;
147
if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))
148
mode |= HAL_MODE_TURBO | HAL_MODE_108A;
149
}
150
if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))
151
mode |= HAL_MODE_11B;
152
return mode;
153
}
154
155
#if 0
156
HAL_BOOL
157
ar5211GetTurboDisable(struct ath_hal *ah)
158
{
159
return (AH5211(ah)->ah_turboDisable != 0);
160
}
161
#endif
162
163
/*
164
* Called if RfKill is supported (according to EEPROM). Set the interrupt and
165
* GPIO values so the ISR and can disable RF on a switch signal
166
*/
167
void
168
ar5211EnableRfKill(struct ath_hal *ah)
169
{
170
uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent;
171
int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL);
172
int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY);
173
174
/*
175
* Configure the desired GPIO port for input
176
* and enable baseband rf silence.
177
*/
178
ar5211GpioCfgInput(ah, select);
179
OS_REG_SET_BIT(ah, AR_PHY_BASE, 0x00002000);
180
/*
181
* If radio disable switch connection to GPIO bit x is enabled
182
* program GPIO interrupt.
183
* If rfkill bit on eeprom is 1, setupeeprommap routine has already
184
* verified that it is a later version of eeprom, it has a place for
185
* rfkill bit and it is set to 1, indicating that GPIO bit x hardware
186
* connection is present.
187
*/
188
ar5211GpioSetIntr(ah, select, (ar5211GpioGet(ah, select) != polarity));
189
}
190
191
/*
192
* Configure GPIO Output lines
193
*/
194
HAL_BOOL
195
ar5211GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type)
196
{
197
uint32_t reg;
198
199
HALASSERT(gpio < AR_NUM_GPIO);
200
201
reg = OS_REG_READ(ah, AR_GPIOCR);
202
reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT));
203
reg |= AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT);
204
205
OS_REG_WRITE(ah, AR_GPIOCR, reg);
206
return AH_TRUE;
207
}
208
209
/*
210
* Configure GPIO Input lines
211
*/
212
HAL_BOOL
213
ar5211GpioCfgInput(struct ath_hal *ah, uint32_t gpio)
214
{
215
uint32_t reg;
216
217
HALASSERT(gpio < AR_NUM_GPIO);
218
219
reg = OS_REG_READ(ah, AR_GPIOCR);
220
reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT));
221
reg |= AR_GPIOCR_0_CR_N << (gpio * AR_GPIOCR_CR_SHIFT);
222
223
OS_REG_WRITE(ah, AR_GPIOCR, reg);
224
return AH_TRUE;
225
}
226
227
/*
228
* Once configured for I/O - set output lines
229
*/
230
HAL_BOOL
231
ar5211GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val)
232
{
233
uint32_t reg;
234
235
HALASSERT(gpio < AR_NUM_GPIO);
236
237
reg = OS_REG_READ(ah, AR_GPIODO);
238
reg &= ~(1 << gpio);
239
reg |= (val&1) << gpio;
240
241
OS_REG_WRITE(ah, AR_GPIODO, reg);
242
return AH_TRUE;
243
}
244
245
/*
246
* Once configured for I/O - get input lines
247
*/
248
uint32_t
249
ar5211GpioGet(struct ath_hal *ah, uint32_t gpio)
250
{
251
if (gpio < AR_NUM_GPIO) {
252
uint32_t val = OS_REG_READ(ah, AR_GPIODI);
253
val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1;
254
return val;
255
} else {
256
return 0xffffffff;
257
}
258
}
259
260
/*
261
* Set the GPIO 0 Interrupt (gpio is ignored)
262
*/
263
void
264
ar5211GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel)
265
{
266
uint32_t val = OS_REG_READ(ah, AR_GPIOCR);
267
268
/* Clear the bits that we will modify. */
269
val &= ~(AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_SELH | AR_GPIOCR_INT_ENA |
270
AR_GPIOCR_0_CR_A);
271
272
val |= AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_ENA;
273
if (ilevel)
274
val |= AR_GPIOCR_INT_SELH;
275
276
/* Don't need to change anything for low level interrupt. */
277
OS_REG_WRITE(ah, AR_GPIOCR, val);
278
279
/* Change the interrupt mask. */
280
ar5211SetInterrupts(ah, AH5211(ah)->ah_maskReg | HAL_INT_GPIO);
281
}
282
283
/*
284
* Change the LED blinking pattern to correspond to the connectivity
285
*/
286
void
287
ar5211SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
288
{
289
static const uint32_t ledbits[8] = {
290
AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_INIT */
291
AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_SCAN */
292
AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_AUTH */
293
AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_ASSOC*/
294
AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_RUN */
295
AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND,
296
AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND,
297
AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND,
298
};
299
OS_REG_WRITE(ah, AR_PCICFG,
300
(OS_REG_READ(ah, AR_PCICFG) &~
301
(AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE))
302
| ledbits[state & 0x7]
303
);
304
}
305
306
/*
307
* Change association related fields programmed into the hardware.
308
* Writing a valid BSSID to the hardware effectively enables the hardware
309
* to synchronize its TSF to the correct beacons and receive frames coming
310
* from that BSSID. It is called by the SME JOIN operation.
311
*/
312
void
313
ar5211WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId)
314
{
315
struct ath_hal_5211 *ahp = AH5211(ah);
316
317
/* XXX save bssid for possible re-use on reset */
318
OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN);
319
OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
320
OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) |
321
((assocId & 0x3fff)<<AR_BSS_ID1_AID_S));
322
}
323
324
/*
325
* Get the current hardware tsf for stamlme.
326
*/
327
uint64_t
328
ar5211GetTsf64(struct ath_hal *ah)
329
{
330
uint32_t low1, low2, u32;
331
332
/* sync multi-word read */
333
low1 = OS_REG_READ(ah, AR_TSF_L32);
334
u32 = OS_REG_READ(ah, AR_TSF_U32);
335
low2 = OS_REG_READ(ah, AR_TSF_L32);
336
if (low2 < low1) { /* roll over */
337
/*
338
* If we are not preempted this will work. If we are
339
* then we re-reading AR_TSF_U32 does no good as the
340
* low bits will be meaningless. Likewise reading
341
* L32, U32, U32, then comparing the last two reads
342
* to check for rollover doesn't help if preempted--so
343
* we take this approach as it costs one less PCI
344
* read which can be noticeable when doing things
345
* like timestamping packets in monitor mode.
346
*/
347
u32++;
348
}
349
return (((uint64_t) u32) << 32) | ((uint64_t) low2);
350
}
351
352
/*
353
* Get the current hardware tsf for stamlme.
354
*/
355
uint32_t
356
ar5211GetTsf32(struct ath_hal *ah)
357
{
358
return OS_REG_READ(ah, AR_TSF_L32);
359
}
360
361
/*
362
* Reset the current hardware tsf for stamlme
363
*/
364
void
365
ar5211ResetTsf(struct ath_hal *ah)
366
{
367
uint32_t val = OS_REG_READ(ah, AR_BEACON);
368
369
OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
370
}
371
372
/*
373
* Grab a semi-random value from hardware registers - may not
374
* change often
375
*/
376
uint32_t
377
ar5211GetRandomSeed(struct ath_hal *ah)
378
{
379
uint32_t nf;
380
381
nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
382
if (nf & 0x100)
383
nf = 0 - ((nf ^ 0x1ff) + 1);
384
return (OS_REG_READ(ah, AR_TSF_U32) ^
385
OS_REG_READ(ah, AR_TSF_L32) ^ nf);
386
}
387
388
/*
389
* Detect if our card is present
390
*/
391
HAL_BOOL
392
ar5211DetectCardPresent(struct ath_hal *ah)
393
{
394
uint16_t macVersion, macRev;
395
uint32_t v;
396
397
/*
398
* Read the Silicon Revision register and compare that
399
* to what we read at attach time. If the same, we say
400
* a card/device is present.
401
*/
402
v = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID_M;
403
macVersion = v >> AR_SREV_ID_S;
404
macRev = v & AR_SREV_REVISION_M;
405
return (AH_PRIVATE(ah)->ah_macVersion == macVersion &&
406
AH_PRIVATE(ah)->ah_macRev == macRev);
407
}
408
409
/*
410
* Update MIB Counters
411
*/
412
void
413
ar5211UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS *stats)
414
{
415
stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL);
416
stats->rts_bad += OS_REG_READ(ah, AR_RTS_FAIL);
417
stats->fcs_bad += OS_REG_READ(ah, AR_FCS_FAIL);
418
stats->rts_good += OS_REG_READ(ah, AR_RTS_OK);
419
stats->beacons += OS_REG_READ(ah, AR_BEACON_CNT);
420
}
421
422
HAL_BOOL
423
ar5211SetSifsTime(struct ath_hal *ah, u_int us)
424
{
425
struct ath_hal_5211 *ahp = AH5211(ah);
426
427
if (us > ath_hal_mac_usec(ah, 0xffff)) {
428
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n",
429
__func__, us);
430
ahp->ah_sifstime = (u_int) -1; /* restore default handling */
431
return AH_FALSE;
432
} else {
433
/* convert to system clocks */
434
OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us));
435
ahp->ah_slottime = us;
436
return AH_TRUE;
437
}
438
}
439
440
u_int
441
ar5211GetSifsTime(struct ath_hal *ah)
442
{
443
u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SIFS) & 0xffff;
444
return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
445
}
446
447
HAL_BOOL
448
ar5211SetSlotTime(struct ath_hal *ah, u_int us)
449
{
450
struct ath_hal_5211 *ahp = AH5211(ah);
451
452
if (us < HAL_SLOT_TIME_9 || us > ath_hal_mac_usec(ah, 0xffff)) {
453
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n",
454
__func__, us);
455
ahp->ah_slottime = us; /* restore default handling */
456
return AH_FALSE;
457
} else {
458
/* convert to system clocks */
459
OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath_hal_mac_clks(ah, us));
460
ahp->ah_slottime = us;
461
return AH_TRUE;
462
}
463
}
464
465
u_int
466
ar5211GetSlotTime(struct ath_hal *ah)
467
{
468
u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
469
return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
470
}
471
472
HAL_BOOL
473
ar5211SetAckTimeout(struct ath_hal *ah, u_int us)
474
{
475
struct ath_hal_5211 *ahp = AH5211(ah);
476
477
if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
478
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n",
479
__func__, us);
480
ahp->ah_acktimeout = (u_int) -1; /* restore default handling */
481
return AH_FALSE;
482
} else {
483
/* convert to system clocks */
484
OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
485
AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us));
486
ahp->ah_acktimeout = us;
487
return AH_TRUE;
488
}
489
}
490
491
u_int
492
ar5211GetAckTimeout(struct ath_hal *ah)
493
{
494
u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK);
495
return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
496
}
497
498
u_int
499
ar5211GetAckCTSRate(struct ath_hal *ah)
500
{
501
return ((AH5211(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0);
502
}
503
504
HAL_BOOL
505
ar5211SetAckCTSRate(struct ath_hal *ah, u_int high)
506
{
507
struct ath_hal_5211 *ahp = AH5211(ah);
508
509
if (high) {
510
OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
511
ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB;
512
} else {
513
OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
514
ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB;
515
}
516
return AH_TRUE;
517
}
518
519
HAL_BOOL
520
ar5211SetCTSTimeout(struct ath_hal *ah, u_int us)
521
{
522
struct ath_hal_5211 *ahp = AH5211(ah);
523
524
if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
525
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n",
526
__func__, us);
527
ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */
528
return AH_FALSE;
529
} else {
530
/* convert to system clocks */
531
OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
532
AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us));
533
ahp->ah_ctstimeout = us;
534
return AH_TRUE;
535
}
536
}
537
538
u_int
539
ar5211GetCTSTimeout(struct ath_hal *ah)
540
{
541
u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
542
return ath_hal_mac_usec(ah, clks); /* convert from system clocks */
543
}
544
545
HAL_BOOL
546
ar5211SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
547
{
548
/* nothing to do */
549
return AH_TRUE;
550
}
551
552
void
553
ar5211SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
554
{
555
}
556
557
HAL_STATUS
558
ar5211SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
559
uint32_t next_start, HAL_QUIET_FLAG flags)
560
{
561
return HAL_OK;
562
}
563
564
/*
565
* Control Adaptive Noise Immunity Parameters
566
*/
567
HAL_BOOL
568
ar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
569
{
570
return AH_FALSE;
571
}
572
573
void
574
ar5211AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan)
575
{
576
}
577
578
void
579
ar5211RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats,
580
const struct ieee80211_channel *chan)
581
{
582
}
583
584
void
585
ar5211MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats)
586
{
587
}
588
589
/*
590
* Get the rssi of frame curently being received.
591
*/
592
uint32_t
593
ar5211GetCurRssi(struct ath_hal *ah)
594
{
595
return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff);
596
}
597
598
u_int
599
ar5211GetDefAntenna(struct ath_hal *ah)
600
{
601
return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7);
602
}
603
604
void
605
ar5211SetDefAntenna(struct ath_hal *ah, u_int antenna)
606
{
607
OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
608
}
609
610
HAL_ANT_SETTING
611
ar5211GetAntennaSwitch(struct ath_hal *ah)
612
{
613
return AH5211(ah)->ah_diversityControl;
614
}
615
616
HAL_BOOL
617
ar5211SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
618
{
619
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
620
621
if (chan == AH_NULL) {
622
AH5211(ah)->ah_diversityControl = settings;
623
return AH_TRUE;
624
}
625
return ar5211SetAntennaSwitchInternal(ah, settings, chan);
626
}
627
628
HAL_STATUS
629
ar5211GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
630
uint32_t capability, uint32_t *result)
631
{
632
633
switch (type) {
634
case HAL_CAP_CIPHER: /* cipher handled in hardware */
635
switch (capability) {
636
case HAL_CIPHER_AES_OCB:
637
case HAL_CIPHER_WEP:
638
case HAL_CIPHER_CLR:
639
return HAL_OK;
640
default:
641
return HAL_ENOTSUPP;
642
}
643
default:
644
return ath_hal_getcapability(ah, type, capability, result);
645
}
646
}
647
648
HAL_BOOL
649
ar5211SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
650
uint32_t capability, uint32_t setting, HAL_STATUS *status)
651
{
652
switch (type) {
653
case HAL_CAP_DIAG: /* hardware diagnostic support */
654
/*
655
* NB: could split this up into virtual capabilities,
656
* (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly
657
* seems worth the additional complexity.
658
*/
659
#ifdef AH_DEBUG
660
AH_PRIVATE(ah)->ah_diagreg = setting;
661
#else
662
AH_PRIVATE(ah)->ah_diagreg = setting & 0x6; /* ACK+CTS */
663
#endif
664
OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
665
return AH_TRUE;
666
default:
667
return ath_hal_setcapability(ah, type, capability,
668
setting, status);
669
}
670
}
671
672
HAL_BOOL
673
ar5211GetDiagState(struct ath_hal *ah, int request,
674
const void *args, uint32_t argsize,
675
void **result, uint32_t *resultsize)
676
{
677
struct ath_hal_5211 *ahp = AH5211(ah);
678
679
(void) ahp;
680
if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize))
681
return AH_TRUE;
682
switch (request) {
683
case HAL_DIAG_EEPROM:
684
return ath_hal_eepromDiag(ah, request,
685
args, argsize, result, resultsize);
686
case HAL_DIAG_RFGAIN:
687
*result = &ahp->ah_gainValues;
688
*resultsize = sizeof(GAIN_VALUES);
689
return AH_TRUE;
690
case HAL_DIAG_RFGAIN_CURSTEP:
691
*result = __DECONST(void *, ahp->ah_gainValues.currStep);
692
*resultsize = (*result == AH_NULL) ?
693
0 : sizeof(GAIN_OPTIMIZATION_STEP);
694
return AH_TRUE;
695
}
696
return AH_FALSE;
697
}
698
699
/*
700
* Return what percentage of the extension channel is busy.
701
* This is always disabled for AR5211 series NICs.
702
*/
703
uint32_t
704
ar5211Get11nExtBusy(struct ath_hal *ah)
705
{
706
return (0);
707
}
708
709
/*
710
* There's no channel survey support for the AR5211.
711
*/
712
HAL_BOOL
713
ar5211GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample)
714
{
715
716
return (AH_FALSE);
717
}
718
719
void
720
ar5211SetChainMasks(struct ath_hal *ah, uint32_t txchainmask,
721
uint32_t rxchainmask)
722
{
723
}
724
725
void
726
ar5211EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
727
{
728
}
729
730
void
731
ar5211GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
732
{
733
}
734
735
/*
736
* Get the current NAV value from the hardware.
737
*/
738
u_int
739
ar5211GetNav(struct ath_hal *ah)
740
{
741
uint32_t reg;
742
743
reg = OS_REG_READ(ah, AR_NAV);
744
return (reg);
745
}
746
747
/*
748
* Set the current NAV value to the hardware.
749
*/
750
void
751
ar5211SetNav(struct ath_hal *ah, u_int val)
752
{
753
754
OS_REG_WRITE(ah, AR_NAV, val);
755
}
756
757
758