2 * Copyright (c) 2007-2008 Atheros Communications Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 #include "../80211core/cprecomp.h"
21 extern u16_t
zfDelayWriteInternalReg(zdev_t
*dev
, u32_t addr
, u32_t val
);
22 extern u16_t
zfFlushDelayWrite(zdev_t
*dev
);
25 * Anti noise immunity support. We track phy errors and react
26 * to excessive errors by adjusting the noise immunity parameters.
29 /******************************************************************************
31 * New Ani Algorithm for Station side only
33 *****************************************************************************/
35 #define ZM_HAL_NOISE_IMMUNE_MAX 4 /* Max noise immunity level */
36 #define ZM_HAL_SPUR_IMMUNE_MAX 7 /* Max spur immunity level */
37 #define ZM_HAL_FIRST_STEP_MAX 2 /* Max first step level */
39 #define ZM_HAL_ANI_OFDM_TRIG_HIGH 500
40 #define ZM_HAL_ANI_OFDM_TRIG_LOW 200
41 #define ZM_HAL_ANI_CCK_TRIG_HIGH 200
42 #define ZM_HAL_ANI_CCK_TRIG_LOW 100
43 #define ZM_HAL_ANI_NOISE_IMMUNE_LVL 4
44 #define ZM_HAL_ANI_USE_OFDM_WEAK_SIG TRUE
45 #define ZM_HAL_ANI_CCK_WEAK_SIG_THR FALSE
46 #define ZM_HAL_ANI_SPUR_IMMUNE_LVL 7
47 #define ZM_HAL_ANI_FIRSTEP_LVL 0
48 #define ZM_HAL_ANI_RSSI_THR_HIGH 40
49 #define ZM_HAL_ANI_RSSI_THR_LOW 7
50 #define ZM_HAL_ANI_PERIOD 100
52 #define ZM_HAL_EP_RND(x, mul) \
53 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
55 s32_t
BEACON_RSSI(zdev_t
*dev
)
58 struct zsHpPriv
*HpPriv
;
60 zmw_get_wlan_dev(dev
);
61 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
63 rssi
= ZM_HAL_EP_RND(HpPriv
->stats
.ast_nodestats
.ns_avgbrssi
, ZM_HAL_RSSI_EP_MULTIPLIER
);
69 * Setup ANI handling. Sets all thresholds and levels to default level AND
70 * resets the channel statistics
73 void zfHpAniAttach(zdev_t
*dev
)
76 struct zsHpPriv
*HpPriv
;
78 const int totalSizeDesired
[] = { -55, -55, -55, -55, -62 };
79 const int coarseHigh
[] = { -14, -14, -14, -14, -12 };
80 const int coarseLow
[] = { -64, -64, -64, -64, -70 };
81 const int firpwr
[] = { -78, -78, -78, -78, -80 };
83 zmw_get_wlan_dev(dev
);
84 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
86 for (i
= 0; i
< 5; i
++) {
87 HpPriv
->totalSizeDesired
[i
] = totalSizeDesired
[i
];
88 HpPriv
->coarseHigh
[i
] = coarseHigh
[i
];
89 HpPriv
->coarseLow
[i
] = coarseLow
[i
];
90 HpPriv
->firpwr
[i
] = firpwr
[i
];
93 /* owl has phy counters */
94 HpPriv
->hasHwPhyCounters
= 1;
96 memset((char *)&HpPriv
->ani
, 0, sizeof(HpPriv
->ani
));
97 for (i
= 0; i
< ARRAY_SIZE(HpPriv
->ani
); i
++) {
99 HpPriv
->ani
[i
].ofdmTrigHigh
= ZM_HAL_ANI_OFDM_TRIG_HIGH
;
100 HpPriv
->ani
[i
].ofdmTrigLow
= ZM_HAL_ANI_OFDM_TRIG_LOW
;
101 HpPriv
->ani
[i
].cckTrigHigh
= ZM_HAL_ANI_CCK_TRIG_HIGH
;
102 HpPriv
->ani
[i
].cckTrigLow
= ZM_HAL_ANI_CCK_TRIG_LOW
;
103 HpPriv
->ani
[i
].rssiThrHigh
= ZM_HAL_ANI_RSSI_THR_HIGH
;
104 HpPriv
->ani
[i
].rssiThrLow
= ZM_HAL_ANI_RSSI_THR_LOW
;
105 HpPriv
->ani
[i
].ofdmWeakSigDetectOff
= !ZM_HAL_ANI_USE_OFDM_WEAK_SIG
;
106 HpPriv
->ani
[i
].cckWeakSigThreshold
= ZM_HAL_ANI_CCK_WEAK_SIG_THR
;
107 HpPriv
->ani
[i
].spurImmunityLevel
= ZM_HAL_ANI_SPUR_IMMUNE_LVL
;
108 HpPriv
->ani
[i
].firstepLevel
= ZM_HAL_ANI_FIRSTEP_LVL
;
109 if (HpPriv
->hasHwPhyCounters
) {
110 HpPriv
->ani
[i
].ofdmPhyErrBase
= 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_OFDM_TRIG_HIGH;
111 HpPriv
->ani
[i
].cckPhyErrBase
= 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_CCK_TRIG_HIGH;
114 if (HpPriv
->hasHwPhyCounters
) {
115 //zm_debug_msg2("Setting OfdmErrBase = 0x", HpPriv->ani[0].ofdmPhyErrBase);
116 //zm_debug_msg2("Setting cckErrBase = 0x", HpPriv->ani[0].cckPhyErrBase);
117 //OS_REG_WRITE(ah, AR_PHY_ERR_1, HpPriv->ani[0].ofdmPhyErrBase);
118 //OS_REG_WRITE(ah, AR_PHY_ERR_2, HpPriv->ani[0].cckPhyErrBase);
120 HpPriv
->aniPeriod
= ZM_HAL_ANI_PERIOD
;
121 //if (ath_hal_enableANI)
122 HpPriv
->procPhyErr
|= ZM_HAL_PROCESS_ANI
;
124 HpPriv
->stats
.ast_nodestats
.ns_avgbrssi
= ZM_RSSI_DUMMY_MARKER
;
125 HpPriv
->stats
.ast_nodestats
.ns_avgrssi
= ZM_RSSI_DUMMY_MARKER
;
126 HpPriv
->stats
.ast_nodestats
.ns_avgtxrssi
= ZM_RSSI_DUMMY_MARKER
;
130 * Control Adaptive Noise Immunity Parameters
132 u8_t
zfHpAniControl(zdev_t
*dev
, ZM_HAL_ANI_CMD cmd
, int param
)
134 typedef s32_t TABLE
[];
135 struct zsHpPriv
*HpPriv
;
136 struct zsAniState
*aniState
;
138 zmw_get_wlan_dev(dev
);
139 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
140 aniState
= HpPriv
->curani
;
144 case ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL
:
148 if (level
>= ARRAY_SIZE(HpPriv
->totalSizeDesired
)) {
149 zm_debug_msg1("level out of range, desired level : ", level
);
150 zm_debug_msg1("max level : ", ARRAY_SIZE(HpPriv
->totalSizeDesired
));
154 zfDelayWriteInternalReg(dev
, AR_PHY_DESIRED_SZ
,
155 (HpPriv
->regPHYDesiredSZ
& ~AR_PHY_DESIRED_SZ_TOT_DES
)
156 | ((HpPriv
->totalSizeDesired
[level
] << AR_PHY_DESIRED_SZ_TOT_DES_S
)
157 & AR_PHY_DESIRED_SZ_TOT_DES
));
158 zfDelayWriteInternalReg(dev
, AR_PHY_AGC_CTL1
,
159 (HpPriv
->regPHYAgcCtl1
& ~AR_PHY_AGC_CTL1_COARSE_LOW
)
160 | ((HpPriv
->coarseLow
[level
] << AR_PHY_AGC_CTL1_COARSE_LOW_S
)
161 & AR_PHY_AGC_CTL1_COARSE_LOW
));
162 zfDelayWriteInternalReg(dev
, AR_PHY_AGC_CTL1
,
163 (HpPriv
->regPHYAgcCtl1
& ~AR_PHY_AGC_CTL1_COARSE_HIGH
)
164 | ((HpPriv
->coarseHigh
[level
] << AR_PHY_AGC_CTL1_COARSE_HIGH_S
)
165 & AR_PHY_AGC_CTL1_COARSE_HIGH
));
166 zfDelayWriteInternalReg(dev
, AR_PHY_FIND_SIG
,
167 (HpPriv
->regPHYFindSig
& ~AR_PHY_FIND_SIG_FIRPWR
)
168 | ((HpPriv
->firpwr
[level
] << AR_PHY_FIND_SIG_FIRPWR_S
)
169 & AR_PHY_FIND_SIG_FIRPWR
));
170 zfFlushDelayWrite(dev
);
172 if (level
> aniState
->noiseImmunityLevel
)
173 HpPriv
->stats
.ast_ani_niup
++;
174 else if (level
< aniState
->noiseImmunityLevel
)
175 HpPriv
->stats
.ast_ani_nidown
++;
176 aniState
->noiseImmunityLevel
= (u8_t
)level
;
179 case ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
:
181 const TABLE m1ThreshLow
= { 127, 50 };
182 const TABLE m2ThreshLow
= { 127, 40 };
183 const TABLE m1Thresh
= { 127, 0x4d };
184 const TABLE m2Thresh
= { 127, 0x40 };
185 const TABLE m2CountThr
= { 31, 16 };
186 const TABLE m2CountThrLow
= { 63, 48 };
187 u32_t on
= param
? 1 : 0;
189 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR_LOW
,
190 (HpPriv
->regPHYSfcorrLow
& ~AR_PHY_SFCORR_LOW_M1_THRESH_LOW
)
191 | ((m1ThreshLow
[on
] << AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S
)
192 & AR_PHY_SFCORR_LOW_M1_THRESH_LOW
));
193 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR_LOW
,
194 (HpPriv
->regPHYSfcorrLow
& ~AR_PHY_SFCORR_LOW_M2_THRESH_LOW
)
195 | ((m2ThreshLow
[on
] << AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S
)
196 & AR_PHY_SFCORR_LOW_M2_THRESH_LOW
));
197 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR
,
198 (HpPriv
->regPHYSfcorr
& ~AR_PHY_SFCORR_M1_THRESH
)
199 | ((m1Thresh
[on
] << AR_PHY_SFCORR_M1_THRESH_S
)
200 & AR_PHY_SFCORR_M1_THRESH
));
201 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR
,
202 (HpPriv
->regPHYSfcorr
& ~AR_PHY_SFCORR_M2_THRESH
)
203 | ((m2Thresh
[on
] << AR_PHY_SFCORR_M2_THRESH_S
)
204 & AR_PHY_SFCORR_M2_THRESH
));
205 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR
,
206 (HpPriv
->regPHYSfcorr
& ~AR_PHY_SFCORR_M2COUNT_THR
)
207 | ((m2CountThr
[on
] << AR_PHY_SFCORR_M2COUNT_THR_S
)
208 & AR_PHY_SFCORR_M2COUNT_THR
));
209 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR_LOW
,
210 (HpPriv
->regPHYSfcorrLow
& ~AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW
)
211 | ((m2CountThrLow
[on
] << AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S
)
212 & AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW
));
216 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR_LOW
,
217 HpPriv
->regPHYSfcorrLow
| AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW
);
221 zfDelayWriteInternalReg(dev
, AR_PHY_SFCORR_LOW
,
222 HpPriv
->regPHYSfcorrLow
& ~AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW
);
224 zfFlushDelayWrite(dev
);
225 if (!on
!= aniState
->ofdmWeakSigDetectOff
)
228 HpPriv
->stats
.ast_ani_ofdmon
++;
230 HpPriv
->stats
.ast_ani_ofdmoff
++;
231 aniState
->ofdmWeakSigDetectOff
= !on
;
235 case ZM_HAL_ANI_CCK_WEAK_SIGNAL_THR
:
237 const TABLE weakSigThrCck
= { 8, 6 };
238 u32_t high
= param
? 1 : 0;
240 zfDelayWriteInternalReg(dev
, AR_PHY_CCK_DETECT
,
241 (HpPriv
->regPHYCckDetect
& ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK
)
242 | ((weakSigThrCck
[high
] << AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S
)
243 & AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK
));
244 zfFlushDelayWrite(dev
);
245 if (high
!= aniState
->cckWeakSigThreshold
)
248 HpPriv
->stats
.ast_ani_cckhigh
++;
250 HpPriv
->stats
.ast_ani_ccklow
++;
251 aniState
->cckWeakSigThreshold
= (u8_t
)high
;
255 case ZM_HAL_ANI_FIRSTEP_LEVEL
:
257 const TABLE firstep
= { 0, 4, 8 };
260 if (level
>= ARRAY_SIZE(firstep
))
262 zm_debug_msg1("level out of range, desired level : ", level
);
263 zm_debug_msg1("max level : ", ARRAY_SIZE(firstep
));
266 zfDelayWriteInternalReg(dev
, AR_PHY_FIND_SIG
,
267 (HpPriv
->regPHYFindSig
& ~AR_PHY_FIND_SIG_FIRSTEP
)
268 | ((firstep
[level
] << AR_PHY_FIND_SIG_FIRSTEP_S
)
269 & AR_PHY_FIND_SIG_FIRSTEP
));
270 zfFlushDelayWrite(dev
);
271 if (level
> aniState
->firstepLevel
)
272 HpPriv
->stats
.ast_ani_stepup
++;
273 else if (level
< aniState
->firstepLevel
)
274 HpPriv
->stats
.ast_ani_stepdown
++;
275 aniState
->firstepLevel
= (u8_t
)level
;
278 case ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL
:
280 const TABLE cycpwrThr1
= { 2, 4, 6, 8, 10, 12, 14, 16 };
283 if (level
>= ARRAY_SIZE(cycpwrThr1
))
285 zm_debug_msg1("level out of range, desired level : ", level
);
286 zm_debug_msg1("max level : ", ARRAY_SIZE(cycpwrThr1
));
289 zfDelayWriteInternalReg(dev
, AR_PHY_TIMING5
,
290 (HpPriv
->regPHYTiming5
& ~AR_PHY_TIMING5_CYCPWR_THR1
)
291 | ((cycpwrThr1
[level
] << AR_PHY_TIMING5_CYCPWR_THR1_S
)
292 & AR_PHY_TIMING5_CYCPWR_THR1
));
293 zfFlushDelayWrite(dev
);
294 if (level
> aniState
->spurImmunityLevel
)
295 HpPriv
->stats
.ast_ani_spurup
++;
296 else if (level
< aniState
->spurImmunityLevel
)
297 HpPriv
->stats
.ast_ani_spurdown
++;
298 aniState
->spurImmunityLevel
= (u8_t
)level
;
301 case ZM_HAL_ANI_PRESENT
:
303 #ifdef AH_PRIVATE_DIAG
304 case ZM_HAL_ANI_MODE
:
307 HpPriv
->procPhyErr
&= ~ZM_HAL_PROCESS_ANI
;
308 /* Turn off HW counters if we have them */
310 //zfHpSetRxFilter(dev, zfHpGetRxFilter(dev) &~ HAL_RX_FILTER_PHYERR);
313 { /* normal/auto mode */
314 HpPriv
->procPhyErr
|= ZM_HAL_PROCESS_ANI
;
315 if (HpPriv
->hasHwPhyCounters
)
317 //zfHpSetRxFilter(dev, zfHpGetRxFilter(dev) &~ HAL_RX_FILTER_PHYERR);
321 //zfHpSetRxFilter(dev, zfHpGetRxFilter(dev) | HAL_RX_FILTER_PHYERR);
325 case ZM_HAL_ANI_PHYERR_RESET
:
326 HpPriv
->stats
.ast_ani_ofdmerrs
= 0;
327 HpPriv
->stats
.ast_ani_cckerrs
= 0;
329 #endif /* AH_PRIVATE_DIAG */
331 zm_debug_msg1("invalid cmd ", cmd
);
337 void zfHpAniRestart(zdev_t
* dev
)
339 struct zsAniState
*aniState
;
340 struct zsHpPriv
*HpPriv
;
342 zmw_get_wlan_dev(dev
);
343 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
344 aniState
= HpPriv
->curani
;
346 aniState
->listenTime
= 0;
347 if (HpPriv
->hasHwPhyCounters
)
349 //if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX)
351 // aniState->ofdmPhyErrBase = 0;
352 // zm_debug_msg0("OFDM Trigger is too high for hw counters");
355 // aniState->ofdmPhyErrBase = AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
356 //if (aniState->cckTrigHigh > AR_PHY_COUNTMAX)
358 // aniState->cckPhyErrBase = 0;
359 // zm_debug_msg0("CCK Trigger is too high for hw counters");
362 // aniState->cckPhyErrBase = AR_PHY_COUNTMAX - aniState->cckTrigHigh;
363 //zm_debug_msg2("Writing ofdmbase = 0x", aniState->ofdmPhyErrBase);
364 //zm_debug_msg2("Writing cckbase = 0x", aniState->cckPhyErrBase);
365 //OS_REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
366 //OS_REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
367 //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
368 //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
369 aniState
->ofdmPhyErrBase
= 0;
370 aniState
->cckPhyErrBase
= 0;
372 aniState
->ofdmPhyErrCount
= 0;
373 aniState
->cckPhyErrCount
= 0;
376 void zfHpAniOfdmErrTrigger(zdev_t
* dev
)
378 struct zsAniState
*aniState
;
380 struct zsHpPriv
*HpPriv
;
382 zmw_get_wlan_dev(dev
);
383 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
385 //HALASSERT(chan != NULL);
387 if ((HpPriv
->procPhyErr
& ZM_HAL_PROCESS_ANI
) == 0)
390 aniState
= HpPriv
->curani
;
391 /* First, raise noise immunity level, up to max */
392 if (aniState
->noiseImmunityLevel
< ZM_HAL_NOISE_IMMUNE_MAX
)
394 zfHpAniControl(dev
, ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL
, aniState
->noiseImmunityLevel
+ 1);
397 /* then, raise spur immunity level, up to max */
398 if (aniState
->spurImmunityLevel
< ZM_HAL_SPUR_IMMUNE_MAX
)
400 zfHpAniControl(dev
, ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL
, aniState
->spurImmunityLevel
+ 1);
403 rssi
= BEACON_RSSI(dev
);
404 if (rssi
> aniState
->rssiThrHigh
)
407 * Beacon rssi is high, can turn off ofdm weak sig detect.
409 if (!aniState
->ofdmWeakSigDetectOff
)
411 zfHpAniControl(dev
, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
, FALSE
);
412 zfHpAniControl(dev
, ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL
, 0);
416 * If weak sig detect is already off, as last resort, raise
419 if (aniState
->firstepLevel
< ZM_HAL_FIRST_STEP_MAX
)
421 zfHpAniControl(dev
, ZM_HAL_ANI_FIRSTEP_LEVEL
, aniState
->firstepLevel
+ 1);
425 else if (rssi
> aniState
->rssiThrLow
)
428 * Beacon rssi in mid range, need ofdm weak signal detect,
429 * but we can raise firststepLevel
431 if (aniState
->ofdmWeakSigDetectOff
)
432 zfHpAniControl(dev
, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
, TRUE
);
433 if (aniState
->firstepLevel
< ZM_HAL_FIRST_STEP_MAX
)
434 zfHpAniControl(dev
, ZM_HAL_ANI_FIRSTEP_LEVEL
, aniState
->firstepLevel
+ 1);
440 * Beacon rssi is low, if in 11b/g mode, turn off ofdm
441 * weak sign detction and zero firstepLevel to maximize
444 if (wd
->frequency
< 3000)
446 if (!aniState
->ofdmWeakSigDetectOff
)
447 zfHpAniControl(dev
, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
, FALSE
);
448 if (aniState
->firstepLevel
> 0)
449 zfHpAniControl(dev
, ZM_HAL_ANI_FIRSTEP_LEVEL
, 0);
455 void zfHpAniCckErrTrigger(zdev_t
* dev
)
457 struct zsAniState
*aniState
;
459 struct zsHpPriv
*HpPriv
;
461 zmw_get_wlan_dev(dev
);
462 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
464 //HALASSERT(chan != NULL);
466 if ((HpPriv
->procPhyErr
& ZM_HAL_PROCESS_ANI
) == 0)
469 /* first, raise noise immunity level, up to max */
470 aniState
= HpPriv
->curani
;
471 if (aniState
->noiseImmunityLevel
< ZM_HAL_NOISE_IMMUNE_MAX
)
473 zfHpAniControl(dev
, ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL
,
474 aniState
->noiseImmunityLevel
+ 1);
477 rssi
= BEACON_RSSI(dev
);
478 if (rssi
> aniState
->rssiThrLow
)
481 * Beacon signal in mid and high range, raise firsteplevel.
483 if (aniState
->firstepLevel
< ZM_HAL_FIRST_STEP_MAX
)
484 zfHpAniControl(dev
, ZM_HAL_ANI_FIRSTEP_LEVEL
, aniState
->firstepLevel
+ 1);
489 * Beacon rssi is low, zero firstepLevel to maximize
492 if (wd
->frequency
< 3000)
494 if (aniState
->firstepLevel
> 0)
495 zfHpAniControl(dev
, ZM_HAL_ANI_FIRSTEP_LEVEL
, 0);
500 void zfHpAniLowerImmunity(zdev_t
* dev
)
502 struct zsAniState
*aniState
;
504 struct zsHpPriv
*HpPriv
;
506 zmw_get_wlan_dev(dev
);
507 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
508 aniState
= HpPriv
->curani
;
510 rssi
= BEACON_RSSI(dev
);
511 if (rssi
> aniState
->rssiThrHigh
)
514 * Beacon signal is high, leave ofdm weak signal detection off
515 * or it may oscillate. Let it fall through.
518 else if (rssi
> aniState
->rssiThrLow
)
521 * Beacon rssi in mid range, turn on ofdm weak signal
522 * detection or lower first step level.
524 if (aniState
->ofdmWeakSigDetectOff
)
526 zfHpAniControl(dev
, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION
, TRUE
);
529 if (aniState
->firstepLevel
> 0)
531 zfHpAniControl(dev
, ZM_HAL_ANI_FIRSTEP_LEVEL
, aniState
->firstepLevel
- 1);
538 * Beacon rssi is low, reduce first step level.
540 if (aniState
->firstepLevel
> 0)
542 zfHpAniControl(dev
, ZM_HAL_ANI_FIRSTEP_LEVEL
, aniState
->firstepLevel
- 1);
546 /* then lower spur immunity level, down to zero */
547 if (aniState
->spurImmunityLevel
> 0)
549 zfHpAniControl(dev
, ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL
, aniState
->spurImmunityLevel
- 1);
553 * if all else fails, lower noise immunity level down to a min value
556 if (aniState
->noiseImmunityLevel
> 0)
558 zfHpAniControl(dev
, ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL
, aniState
->noiseImmunityLevel
- 1);
563 #define CLOCK_RATE 44000
564 /* convert HW counter values to ms using 11g clock rate, goo9d enough
568 * Return an approximation of the time spent ``listening'' by
569 * deducting the cycles spent tx'ing and rx'ing from the total
570 * cycle count since our last call. A return value <0 indicates
571 * an invalid/inconsistent time.
573 s32_t
zfHpAniGetListenTime(zdev_t
* dev
)
575 struct zsAniState
*aniState
;
576 u32_t txFrameCount
, rxFrameCount
, cycleCount
;
578 struct zsHpPriv
*HpPriv
;
580 zmw_get_wlan_dev(dev
);
581 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
583 txFrameCount
= 0;//OS_REG_READ(ah, AR_TFCNT);
584 rxFrameCount
= 0;//OS_REG_READ(ah, AR_RFCNT);
585 cycleCount
= 0;//OS_REG_READ(ah, AR_CCCNT);
587 aniState
= HpPriv
->curani
;
588 if (aniState
->cycleCount
== 0 || aniState
->cycleCount
> cycleCount
)
591 * Cycle counter wrap (or initial call); it's not possible
592 * to accurately calculate a value because the registers
593 * right shift rather than wrap--so punt and return 0.
596 HpPriv
->stats
.ast_ani_lzero
++;
600 s32_t ccdelta
= cycleCount
- aniState
->cycleCount
;
601 s32_t rfdelta
= rxFrameCount
- aniState
->rxFrameCount
;
602 s32_t tfdelta
= txFrameCount
- aniState
->txFrameCount
;
603 listenTime
= (ccdelta
- rfdelta
- tfdelta
) / CLOCK_RATE
;
605 aniState
->cycleCount
= cycleCount
;
606 aniState
->txFrameCount
= txFrameCount
;
607 aniState
->rxFrameCount
= rxFrameCount
;
612 * Do periodic processing. This routine is called from the
613 * driver's rx interrupt handler after processing frames.
615 void zfHpAniArPoll(zdev_t
* dev
, u32_t listenTime
, u32_t phyCnt1
, u32_t phyCnt2
)
617 struct zsAniState
*aniState
;
619 struct zsHpPriv
*HpPriv
;
621 zmw_get_wlan_dev(dev
);
622 HpPriv
= (struct zsHpPriv
*)wd
->hpPrivate
;
625 * Since we're called from end of rx tasklet, we also check for
629 aniState
= HpPriv
->curani
;
630 //HpPriv->stats.ast_nodestats = *stats;
632 //listenTime = zfHpAniGetListenTime(dev);
633 //if (listenTime < 0)
635 // HpPriv->stats.ast_ani_lneg++;
636 // /* restart ANI period if listenTime is invalid */
637 // zfHpAniRestart(dev);
640 aniState
->listenTime
+= listenTime
;
642 if (HpPriv
->hasHwPhyCounters
)
644 //u32_t phyCnt1, phyCnt2;
645 u32_t ofdmPhyErrCnt
, cckPhyErrCnt
;
647 /* NB: these are not reset-on-read */
648 //phyCnt1 = 0;//OS_REG_READ(ah, AR_PHY_ERR_1);
649 //phyCnt2 = 0;//OS_REG_READ(ah, AR_PHY_ERR_2);
650 //if (phyCnt1 < aniState->ofdmPhyErrBase ||
651 // phyCnt2 < aniState->cckPhyErrBase)
653 // if (phyCnt1 < aniState->ofdmPhyErrBase)
655 // zm_debug_msg2("phyCnt1 = 0x", phyCnt1);
656 // zm_debug_msg2("resetting counter value to 0x", aniState->ofdmPhyErrBase);
657 // //OS_REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
658 // //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
660 // if (phyCnt2 < aniState->cckPhyErrBase)
662 // zm_debug_msg2("phyCnt2 = 0x", phyCnt2);
663 // zm_debug_msg2("resetting counter value to 0x", aniState->cckPhyErrBase);
664 // //OS_REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
665 // //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
669 /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
670 //ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
671 //HpPriv->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
672 //aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
673 ofdmPhyErrCnt
= phyCnt1
;
674 HpPriv
->stats
.ast_ani_ofdmerrs
+= ofdmPhyErrCnt
;
675 aniState
->ofdmPhyErrCount
+= ofdmPhyErrCnt
;
677 //cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
678 //HpPriv->stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount;
679 //aniState->cckPhyErrCount = cckPhyErrCnt;
680 cckPhyErrCnt
= phyCnt2
;
681 HpPriv
->stats
.ast_ani_cckerrs
+= cckPhyErrCnt
;
682 aniState
->cckPhyErrCount
+= cckPhyErrCnt
;
685 * If ani is not enabled, return after we've collected
688 if ((HpPriv
->procPhyErr
& ZM_HAL_PROCESS_ANI
) == 0)
690 if (aniState
->listenTime
> 5 * HpPriv
->aniPeriod
)
693 * Check to see if need to lower immunity if
694 * 5 aniPeriods have passed
696 if (aniState
->ofdmPhyErrCount
<= aniState
->listenTime
*
697 aniState
->ofdmTrigLow
/1000 &&
698 aniState
->cckPhyErrCount
<= aniState
->listenTime
*
699 aniState
->cckTrigLow
/1000)
700 zfHpAniLowerImmunity(dev
);
703 else if (aniState
->listenTime
> HpPriv
->aniPeriod
)
705 /* check to see if need to raise immunity */
706 if (aniState
->ofdmPhyErrCount
> aniState
->listenTime
*
707 aniState
->ofdmTrigHigh
/ 1000)
709 zfHpAniOfdmErrTrigger(dev
);
712 else if (aniState
->cckPhyErrCount
> aniState
->listenTime
*
713 aniState
->cckTrigHigh
/ 1000)
715 zfHpAniCckErrTrigger(dev
);