struct hostapd_hw_modes *
hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
- u16 *flags)
+ u16 *flags, u8 *dfs_domain)
{
if (hapd->driver == NULL ||
hapd->driver->get_hw_feature_data == NULL)
return NULL;
return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
- flags);
+ flags, dfs_domain);
}
int cw_min, int cw_max, int burst_time);
struct hostapd_hw_modes *
hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
- u16 *flags);
+ u16 *flags, u8 *dfs_domain);
int hostapd_driver_commit(struct hostapd_data *hapd);
int hostapd_drv_none(struct hostapd_data *hapd);
int hostapd_driver_scan(struct hostapd_data *hapd,
int i, j;
u16 num_modes, flags;
struct hostapd_hw_modes *modes;
+ u8 dfs_domain;
if (hostapd_drv_none(hapd))
return -1;
- modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags);
+ modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags,
+ &dfs_domain);
if (modes == NULL) {
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
/* Filter unicast IP packets encrypted using the GTK */
#define WPA_DATA_FRAME_FILTER_FLAG_GTK BIT(2)
+#define HOSTAPD_DFS_REGION_FCC 1
+#define HOSTAPD_DFS_REGION_ETSI 2
+#define HOSTAPD_DFS_REGION_JP 3
+
/**
* enum reg_change_initiator - Regulatory change initiator
*/
* @priv: Private driver interface data
* @num_modes: Variable for returning the number of returned modes
* flags: Variable for returning hardware feature flags
+ * @dfs: Variable for returning DFS region (HOSTAPD_DFS_REGION_*)
* Returns: Pointer to allocated hardware data on success or %NULL on
* failure. Caller is responsible for freeing this.
*/
struct hostapd_hw_modes * (*get_hw_feature_data)(void *priv,
u16 *num_modes,
- u16 *flags);
+ u16 *flags, u8 *dfs);
/**
* send_mlme - Send management frame from MLME
static struct hostapd_hw_modes * hostap_get_hw_feature_data(void *priv,
u16 *num_modes,
- u16 *flags)
+ u16 *flags, u8 *dfs)
{
struct hostapd_hw_modes *mode;
int i, clen, rlen;
*num_modes = 1;
*flags = 0;
+ *dfs = 0;
mode->mode = HOSTAPD_MODE_IEEE80211B;
mode->num_channels = 14;
int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv);
struct hostapd_hw_modes *
-nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags);
+nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
+ u8 *dfs_domain);
int process_global_event(struct nl_msg *msg, void *arg);
int process_bss_event(struct nl_msg *msg, void *arg);
struct hostapd_hw_modes *modes;
int last_mode, last_chan_idx;
int failed;
+ u8 dfs_domain;
};
static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
}
+static void nl80211_set_dfs_domain(enum nl80211_dfs_regions region,
+ u8 *dfs_domain)
+{
+ if (region == NL80211_DFS_FCC)
+ *dfs_domain = HOSTAPD_DFS_REGION_FCC;
+ else if (region == NL80211_DFS_ETSI)
+ *dfs_domain = HOSTAPD_DFS_REGION_ETSI;
+ else if (region == NL80211_DFS_JP)
+ *dfs_domain = HOSTAPD_DFS_REGION_JP;
+ else
+ *dfs_domain = 0;
+}
+
+
static const char * dfs_domain_name(enum nl80211_dfs_regions region)
{
switch (region) {
if (tb_msg[NL80211_ATTR_DFS_REGION]) {
enum nl80211_dfs_regions dfs_domain;
dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
+ nl80211_set_dfs_domain(dfs_domain, &results->dfs_domain);
wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
(char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
dfs_domain_name(dfs_domain));
struct hostapd_hw_modes *
-nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
+nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
+ u8 *dfs_domain)
{
u32 feat;
struct i802_bss *bss = priv;
.modes = NULL,
.last_mode = -1,
.failed = 0,
+ .dfs_domain = 0,
};
*num_modes = 0;
*flags = 0;
+ *dfs_domain = 0;
feat = get_nl80211_protocol_features(drv);
if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
*num_modes = 0;
return NULL;
}
+
+ *dfs_domain = result.dfs_domain;
+
return wpa_driver_nl80211_postprocess_modes(result.modes,
num_modes);
}
static inline struct hostapd_hw_modes *
wpa_drv_get_hw_feature_data(struct wpa_supplicant *wpa_s, u16 *num_modes,
- u16 *flags)
+ u16 *flags, u8 *dfs_domain)
{
if (wpa_s->driver->get_hw_feature_data)
return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv,
- num_modes, flags);
+ num_modes, flags,
+ dfs_domain);
return NULL;
}
struct wpa_supplicant *wpa_s, struct channel_list_changed *info)
{
struct wpa_supplicant *ifs;
+ u8 dfs_domain;
/*
* To allow backwards compatibility with higher level layers that
ifs->ifname);
free_hw_features(ifs);
ifs->hw.modes = wpa_drv_get_hw_feature_data(
- ifs, &ifs->hw.num_modes, &ifs->hw.flags);
+ ifs, &ifs->hw.num_modes, &ifs->hw.flags, &dfs_domain);
/* Restart PNO/sched_scan with updated channel list */
if (ifs->pno) {
{
struct wpa_driver_capa capa;
int capa_res;
+ u8 dfs_domain;
wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
"'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
&wpa_s->hw.num_modes,
- &wpa_s->hw.flags);
+ &wpa_s->hw.flags,
+ &dfs_domain);
if (wpa_s->hw.modes) {
u16 i;