From 8db87e40794dfde6de6db1db14820bfe3d7d010c Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 8 Aug 2011 16:22:42 +0000 Subject: [PATCH] Introduce some more DFS related hooks, inspired both by local work and the Atheros reference code. The radar detection code needs to know what the current DFS domain is. Since net80211 doesn't currently know this information, it's extracted from the HAL regulatory domain information. The specifics: * add a new ath_dfs API hook, ath_dfs_init_radar_filters(), which updates the radar filters whenever the regulatory domain changes. * add HAL_DFS_DOMAIN which describes the currently configured DFS domain . * add a new HAL internal variable which tracks the currently configured HAL DFS domain. * add a new HAL capability, HAL_CAP_DFS_DMN, which returns the currently configured HAL DFS domain setting. * update the HAL DFS domain setting whenever the channel setting is updated. Since this isn't currently used by any radar code, these should all be no-ops for existing users. Obtained from: Atheros Submitted by: KBC Networks, sibridge Approved by: re (kib, blanket) --- sys/dev/ath/ath_dfs/null/dfs_null.c | 10 ++++++++++ sys/dev/ath/ath_hal/ah.c | 3 +++ sys/dev/ath/ath_hal/ah.h | 9 +++++++++ sys/dev/ath/ath_hal/ah_internal.h | 1 + sys/dev/ath/ath_hal/ah_regdomain.c | 15 ++++++++++++++- sys/dev/ath/if_ath.c | 7 +++++++ sys/dev/ath/if_athdfs.h | 4 +++- 7 files changed, 47 insertions(+), 2 deletions(-) diff --git a/sys/dev/ath/ath_dfs/null/dfs_null.c b/sys/dev/ath/ath_dfs/null/dfs_null.c index a3bae914585..e001a4260d5 100644 --- a/sys/dev/ath/ath_dfs/null/dfs_null.c +++ b/sys/dev/ath/ath_dfs/null/dfs_null.c @@ -226,3 +226,13 @@ ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param) ath_hal_getdfsthresh(sc->sc_ah, param); return 1; } + +/* + * Update the current radar patterns based on the + * current operating mode/regulatory domain. + */ +int +ath_dfs_init_radar_filters(struct ath_softc *sc) +{ + return 1; +} diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c index 647f32205bd..2739f97305a 100644 --- a/sys/dev/ath/ath_hal/ah.c +++ b/sys/dev/ath/ath_hal/ah.c @@ -522,6 +522,9 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, case HAL_CAP_REG_DMN: /* regulatory domain */ *result = AH_PRIVATE(ah)->ah_currentRD; return HAL_OK; + case HAL_CAP_DFS_DMN: /* DFS Domain */ + *result = AH_PRIVATE(ah)->ah_dfsDomain; + return HAL_OK; case HAL_CAP_CIPHER: /* cipher handled in hardware */ case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ return HAL_ENOTSUPP; diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index 0dbb986da90..05ac87d9f43 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -735,6 +735,15 @@ typedef struct { #define HAL_PHYERR_PARAM_NOVAL 65535 #define HAL_PHYERR_PARAM_ENABLE 0x8000 /* Enable/Disable if applicable */ +/* + * DFS operating mode flags. + */ +typedef enum { + HAL_DFS_UNINIT_DOMAIN = 0, /* Uninitialized dfs domain */ + HAL_DFS_FCC_DOMAIN = 1, /* FCC3 dfs domain */ + HAL_DFS_ETSI_DOMAIN = 2, /* ETSI dfs domain */ + HAL_DFS_MKK4_DOMAIN = 3, /* Japan dfs domain */ +} HAL_DFS_DOMAIN; /* * Flag for setting QUIET period diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index 120620c8751..28c88413f12 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -303,6 +303,7 @@ struct ath_hal_private { */ HAL_REG_DOMAIN ah_currentRD; /* EEPROM regulatory domain */ HAL_REG_DOMAIN ah_currentRDext; /* EEPROM extended regdomain flags */ + HAL_DFS_DOMAIN ah_dfsDomain; /* current DFS domain */ HAL_CHANNEL_INTERNAL ah_channels[AH_MAXCHAN]; /* private chan state */ u_int ah_nchan; /* valid items in ah_channels */ const struct regDomain *ah_rd2GHz; /* reg state for 2G band */ diff --git a/sys/dev/ath/ath_hal/ah_regdomain.c b/sys/dev/ath/ath_hal/ah_regdomain.c index 43f2b9ba1bd..21bd2c83e80 100644 --- a/sys/dev/ath/ath_hal/ah_regdomain.c +++ b/sys/dev/ath/ath_hal/ah_regdomain.c @@ -687,8 +687,9 @@ ath_hal_init_channels(struct ath_hal *ah, HAL_BOOL enableExtendedChannels) { COUNTRY_CODE_TO_ENUM_RD *country; - REG_DOMAIN *rd5GHz, *rd2GHz; + REG_DOMAIN *rd5GHz = AH_NULL, *rd2GHz; HAL_STATUS status; + HAL_DFS_DOMAIN dfsDomain = HAL_DFS_UNINIT_DOMAIN; status = getchannels(ah, chans, maxchans, nchans, modeSelect, cc, regDmn, enableExtendedChannels, &country, &rd2GHz, &rd5GHz); @@ -702,6 +703,18 @@ ath_hal_init_channels(struct ath_hal *ah, __func__, ah->ah_countryCode); } else status = HAL_EINVAL; + + /* Update the DFS setting for the current regulatory domain */ + if (status == HAL_OK && rd5GHz != AH_NULL) { + if (rd5GHz->dfsMask & DFS_FCC3) + dfsDomain = HAL_DFS_FCC_DOMAIN; + if (rd5GHz->dfsMask & DFS_ETSI) + dfsDomain = HAL_DFS_ETSI_DOMAIN; + if (rd5GHz->dfsMask & DFS_MKK4) + dfsDomain = HAL_DFS_MKK4_DOMAIN; + } + AH_PRIVATE(ah)->ah_dfsDomain = dfsDomain; + return status; } diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 782b790a3a0..1208f1d44db 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -5031,6 +5031,13 @@ ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *reg, __func__, status); return EINVAL; /* XXX */ } + + /* + * Setting country code might change the DFS domain + * so initialize the DFS Radar filters + */ + ath_dfs_init_radar_filters(sc); + return 0; } diff --git a/sys/dev/ath/if_athdfs.h b/sys/dev/ath/if_athdfs.h index 88ee7fc7af8..8cc348db37d 100644 --- a/sys/dev/ath/if_athdfs.h +++ b/sys/dev/ath/if_athdfs.h @@ -42,6 +42,8 @@ extern int ath_dfs_process_radar_event(struct ath_softc *sc, extern int ath_dfs_tasklet_needed(struct ath_softc *sc, struct ieee80211_channel *chan); extern int ath_ioctl_phyerr(struct ath_softc *sc, struct ath_diag *ad); -extern int ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param); +extern int ath_dfs_get_thresholds(struct ath_softc *sc, + HAL_PHYERR_PARAM *param); +extern int ath_dfs_init_radar_filters(struct ath_softc *sc); #endif /* __IF_ATHDFS_H__ */