📄 ar5212_radar.c
字号:
/* * Copyright (c) 2002-2005 Atheros Communications, Inc. * All rights reserved. * */#include "opt_ah.h"#ifdef AH_SUPPORT_AR5212#include "ah.h"#include "ah_internal.h"#include "ar5212/ar5212.h"#include "ar5212/ar5212reg.h"#include "ar5212/ar5212desc.h"#include "ar5212/ar5212phy.h"#include "ar5212/ar5212radar.h"/* * Find the internal HAL channel corresponding to the * public HAL channel specified in c */static HAL_CHANNEL_INTERNAL *getchannel(struct ath_hal *ah, const HAL_CHANNEL *c){#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) HAL_CHANNEL_INTERNAL *base, *cc; int flags = c->channelFlags & CHAN_FLAGS; int n, lim; /* * Check current channel to avoid the lookup. */ cc = AH_PRIVATE(ah)->ah_curchan; if (cc != AH_NULL && cc->channel == c->channel && (cc->channelFlags & CHAN_FLAGS) == flags) { return cc; } /* binary search based on known sorting order */ base = AH_PRIVATE(ah)->ah_channels; n = AH_PRIVATE(ah)->ah_nchan; /* binary search based on known sorting order */ for (lim = n; lim != 0; lim >>= 1) { HAL_CHANNEL_INTERNAL *cc = &base[lim>>1]; int d = c->channel - cc->channel; if (d == 0) { if ((cc->channelFlags & CHAN_FLAGS) == flags) { return cc; } d = flags - (cc->channelFlags & CHAN_FLAGS); } HALDEBUGn(ah, 9, "%s: channel %u/0x%x d %d\n", __func__, cc->channel, cc->channelFlags, d); if (d > 0) { base = cc + 1; lim--; } } HALDEBUG(ah, "%s: no match for %u/0x%x\n", __func__, c->channel, c->channelFlags); return AH_NULL;#undef CHAN_FLAGS}/* Check the internal channel list to see if the desired channel * is ok to release from the NOL. If not, then do nothing. If so, * mark the channel as clear and reset the internal tsf time */voidar5212CheckDfs(struct ath_hal *ah, HAL_CHANNEL *chan){ HAL_CHANNEL_INTERNAL *ichan=AH_NULL; u_int64_t tsf; ichan = getchannel(ah, chan); if (ichan == AH_NULL) return; if (!(ichan->privFlags & CHANNEL_INTERFERENCE)) return; tsf = ar5212GetTsf64(ah); if (tsf >= ichan->dfsTsf) { ichan->privFlags &= ~CHANNEL_INTERFERENCE; ichan->dfsTsf = 0; chan->privFlags &= ~CHANNEL_INTERFERENCE; }}/* * This function marks the channel as having found a dfs event * It also marks the end time that the dfs event should be cleared * If the channel is already marked, then tsf end time can only * be increased */voidar5212DfsFound(struct ath_hal *ah, HAL_CHANNEL *chan, u_int64_t nolTime){ HAL_CHANNEL_INTERNAL *ichan; ichan = getchannel(ah, chan); if (ichan == AH_NULL) return; if (!(ichan->privFlags & CHANNEL_INTERFERENCE)) ichan->dfsTsf = ar5212GetTsf64(ah); ichan->dfsTsf += nolTime; ichan->privFlags |= CHANNEL_INTERFERENCE; chan->privFlags |= CHANNEL_INTERFERENCE;}voidar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe){ u_int32_t val; val = OS_REG_READ(ah, AR_PHY_RADAR_0); if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR); } if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_RRSSI; val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI); } if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_HEIGHT; val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT); } if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_PRSSI; val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); } if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_INBAND; val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND); } OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA); if (IS_5413(ah)) { /* Eagle */ val = OS_REG_READ(ah, AR_PHY_RADAR_2); val |=( /* AR_PHY_RADAR_2_ENRELSTEPCHK | */ AR_PHY_RADAR_2_ENMAXRSSI | AR_PHY_RADAR_2_BLOCKOFDMWEAK | /* AR_PHY_RADAR_2_USEFIR128 | */ AR_PHY_RADAR_2_ENRELPWRCHK ); if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_2_RELPWR; val |= SM(pe->pe_relpwr, AR_PHY_RADAR_2_RELPWR); }#if 0 if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_2_RELSTEP; val |= SM(pe->pe_relstep, AR_PHY_RADAR_2_RELSTEP); }#endif if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_2_MAXLEN; val |= SM(pe->pe_maxlen, AR_PHY_RADAR_2_MAXLEN); } OS_REG_WRITE(ah, AR_PHY_RADAR_2, val); }}voidar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe){ u_int32_t val,temp; val = OS_REG_READ(ah, AR_PHY_RADAR_0); temp = MS(val,AR_PHY_RADAR_0_FIRPWR); temp |= 0xFFFFFF80; pe->pe_firpwr = temp; pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI); pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT); pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI); pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND); if (IS_5413(ah)) { /* Eagle */ val = OS_REG_READ(ah, AR_PHY_RADAR_2); pe->pe_relpwr = MS(val, AR_PHY_RADAR_2_RELPWR); pe->pe_relstep = MS(val, AR_PHY_RADAR_2_RELSTEP); pe->pe_maxlen = MS(val, AR_PHY_RADAR_2_MAXLEN); }}HAL_BOOLar5212RadarWait(struct ath_hal *ah, HAL_CHANNEL *chan){ struct ath_hal_private *ahp= AH_PRIVATE(ah);#ifdef AH_SUPPORT_DFS u_int64_t tsf; if(!ahp->ah_curchan) return AH_TRUE; tsf = ar5212GetTsf64(ah); ahp->ah_curchan->ah_channel_time += (tsf - ahp->ah_curchan->ah_tsf_last); ahp->ah_curchan->ah_tsf_last = tsf; chan->channel = ahp->ah_curchan->channel; chan->channelFlags = ahp->ah_curchan->channelFlags; chan->privFlags = ahp->ah_curchan->privFlags; chan->maxRegTxPower = ahp->ah_curchan->maxRegTxPower; if (ahp->ah_curchan->ah_channel_time > (HAL_RADAR_WAIT_TIME)) { ahp->ah_curchan->privFlags |= CHANNEL_DFS_CLEAR; chan->privFlags = ahp->ah_curchan->privFlags; ar5212TxEnable(ah,AH_TRUE); return AH_FALSE; } return AH_TRUE;#else chan->channel = ahp->ah_curchan->channel; ahp->ah_curchan->privFlags |= CHANNEL_DFS_CLEAR; chan->privFlags |= CHANNEL_DFS_CLEAR; chan->channelFlags = ahp->ah_curchan->channelFlags; chan->privFlags = ahp->ah_curchan->privFlags; chan->maxRegTxPower = ahp->ah_curchan->maxRegTxPower; return AH_FALSE;#endif /* AH_SUPPORT_DFS */}#endif /* AH_SUPPORT_AR5212 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -