Flesh out a new HAL method to fetch the radar PHY error frame information.

For the AR5211/AR5212, this is apparently a one byte pulse duration
counter value. It is only coded up here for the AR5212 as I don't have
any AR5211-series hardware to test it on.

This information was extracted from the Madwifi DFS branch along with
some local additions.

Please note - all this does is extract out the radar event duration,
it in no way reflects the presence of a radar. Further code is needed
to take a set of radar events and filter them to extract out correct
radar pulse trains (and ignore other events.)

For further information, please see:

http://wiki.freebsd.org/dev/ath_hal%284%29/RadarDetection

This includes references to the relevant patents which describe what
is going on.

Obtained from:	Madwifi
This commit is contained in:
Adrian Chadd 2011-06-07 09:03:28 +00:00
parent 033e1e35d3
commit 3d423111f6
8 changed files with 84 additions and 0 deletions

View File

@ -745,6 +745,17 @@ typedef enum {
HAL_QUIET_ADD_SWBA_RESP_TIME = 0x4, /* add beacon response time to next_start offset */
} HAL_QUIET_FLAG;
#define HAL_DFS_EVENT_PRICH 0x0000001
struct dfs_event {
uint64_t re_full_ts; /* 64-bit full timestamp from interrupt time */
uint32_t re_ts; /* Original 15 bit recv timestamp */
uint8_t re_rssi; /* rssi of radar event */
uint8_t re_dur; /* duration of radar pulse */
uint32_t re_flags; /* Flags (see above) */
};
typedef struct dfs_event HAL_DFS_EVENT;
/*
* Hardware Access Layer (HAL) API.
*
@ -928,6 +939,9 @@ struct ath_hal {
HAL_PHYERR_PARAM *pe);
void __ahdecl(*ah_getDfsThresh)(struct ath_hal *ah,
HAL_PHYERR_PARAM *pe);
HAL_BOOL __ahdecl(*ah_procRadarEvent)(struct ath_hal *ah,
struct ath_rx_status *rxs, uint64_t fulltsf,
const char *buf, HAL_DFS_EVENT *event);
/* Key Cache Functions */
uint32_t __ahdecl(*ah_getKeyCacheSize)(struct ath_hal*);

View File

@ -622,5 +622,8 @@ extern HAL_BOOL ar5212IsNFCalInProgress(struct ath_hal *ah);
extern HAL_BOOL ar5212WaitNFCalComplete(struct ath_hal *ah, int i);
extern void ar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern void ar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern HAL_BOOL ar5212ProcessRadarEvent(struct ath_hal *ah,
struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf,
HAL_DFS_EVENT *event);
#endif /* _ATH_AR5212_H_ */

View File

@ -132,6 +132,7 @@ static const struct ath_hal_private ar5212hal = {{
/* DFS Functions */
.ah_enableDfs = ar5212EnableDfs,
.ah_getDfsThresh = ar5212GetDfsThresh,
.ah_procRadarEvent = ar5212ProcessRadarEvent,
/* Key Cache Functions */
.ah_getKeyCacheSize = ar5212GetKeyCacheSize,

View File

@ -1180,3 +1180,47 @@ ar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
pe->pe_extchannel = AH_FALSE;
}
/*
* Process the radar phy error and extract the pulse duration.
*/
HAL_BOOL
ar5212ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
{
uint8_t dur;
uint8_t rssi;
/* Check whether the given phy error is a radar event */
if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) &&
(rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT))
return AH_FALSE;
/*
* The first byte is the pulse width - if there's
* no data, simply set the duration to 0
*/
if (rxs->rs_datalen >= 1)
/* The pulse width is byte 0 of the data */
dur = ((uint8_t) buf[0]) & 0xff;
else
dur = 0;
/* Pulse RSSI is the normal reported RSSI */
rssi = (uint8_t) rxs->rs_rssi;
/* 0 duration/rssi is not a valid radar event */
if (dur == 0 && rssi == 0)
return AH_FALSE;
HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n",
__func__, rssi, dur);
/* Record the event */
event->re_full_ts = fulltsf;
event->re_ts = rxs->rs_tstamp;
event->re_rssi = rssi;
event->re_dur = dur;
event->re_flags = HAL_DFS_EVENT_PRICH;
return AH_TRUE;
}

View File

@ -205,6 +205,9 @@ extern HAL_BOOL ar5416SetRifsDelay(struct ath_hal *ah,
const struct ieee80211_channel *chan, HAL_BOOL enable);
extern void ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern void ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe);
extern HAL_BOOL ar5416ProcessRadarEvent(struct ath_hal *ah,
struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf,
HAL_DFS_EVENT *event);
extern HAL_BOOL ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode,
int setChip);

View File

@ -147,6 +147,7 @@ ar5416InitState(struct ath_hal_5416 *ahp5416, uint16_t devid, HAL_SOFTC sc,
/* DFS Functions */
ah->ah_enableDfs = ar5416EnableDfs;
ah->ah_getDfsThresh = ar5416GetDfsThresh;
ah->ah_procRadarEvent = ar5416ProcessRadarEvent;
/* Power Management Functions */
ah->ah_setPowerMode = ar5416SetPowerMode;

View File

@ -692,3 +692,19 @@ ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
}
}
/*
* Extract the radar event information from the given phy error.
*
* Returns AH_TRUE if the phy error was actually a phy error,
* AH_FALSE if the phy error wasn't a phy error.
*/
HAL_BOOL
ar5416ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs,
uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event)
{
/*
* For now, this isn't implemented.
*/
return AH_FALSE;
}

View File

@ -709,6 +709,8 @@ void ath_intr(void *);
((*(_ah)->ah_enableDfs)((_ah), (_param)))
#define ath_hal_getdfsthresh(_ah, _param) \
((*(_ah)->ah_getDfsThresh)((_ah), (_param)))
#define ath_hal_procradarevent(_ah, _rxs, _fulltsf, _buf, _event) \
((*(_ah)->ah_procRadarEvent)((_ah), (_rxs), (_fulltsf), (_buf), (_event)))
#define ath_hal_gpioCfgOutput(_ah, _gpio, _type) \
((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio), (_type)))