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__ */