hostapd: Move CSA parameters to hostapd_data
This prepares CSA structure and logic in hostapd for multi-BSS channel switching. Signed-hostap: Michal Kazior <michal.kazior@tieto.com>
This commit is contained in:
parent
1de809e152
commit
6782b6846b
6 changed files with 54 additions and 44 deletions
|
@ -265,18 +265,18 @@ static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid)
|
||||||
{
|
{
|
||||||
u8 chan;
|
u8 chan;
|
||||||
|
|
||||||
if (!hapd->iface->cs_freq_params.freq)
|
if (!hapd->cs_freq_params.freq)
|
||||||
return eid;
|
return eid;
|
||||||
|
|
||||||
if (ieee80211_freq_to_chan(hapd->iface->cs_freq_params.freq, &chan) ==
|
if (ieee80211_freq_to_chan(hapd->cs_freq_params.freq, &chan) ==
|
||||||
NUM_HOSTAPD_MODES)
|
NUM_HOSTAPD_MODES)
|
||||||
return eid;
|
return eid;
|
||||||
|
|
||||||
*eid++ = WLAN_EID_CHANNEL_SWITCH;
|
*eid++ = WLAN_EID_CHANNEL_SWITCH;
|
||||||
*eid++ = 3;
|
*eid++ = 3;
|
||||||
*eid++ = hapd->iface->cs_block_tx;
|
*eid++ = hapd->cs_block_tx;
|
||||||
*eid++ = chan;
|
*eid++ = chan;
|
||||||
*eid++ = hapd->iface->cs_count;
|
*eid++ = hapd->cs_count;
|
||||||
|
|
||||||
return eid;
|
return eid;
|
||||||
}
|
}
|
||||||
|
@ -286,12 +286,12 @@ static u8 * hostapd_eid_secondary_channel(struct hostapd_data *hapd, u8 *eid)
|
||||||
{
|
{
|
||||||
u8 sec_ch;
|
u8 sec_ch;
|
||||||
|
|
||||||
if (!hapd->iface->cs_freq_params.sec_channel_offset)
|
if (!hapd->cs_freq_params.sec_channel_offset)
|
||||||
return eid;
|
return eid;
|
||||||
|
|
||||||
if (hapd->iface->cs_freq_params.sec_channel_offset == -1)
|
if (hapd->cs_freq_params.sec_channel_offset == -1)
|
||||||
sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
|
sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
|
||||||
else if (hapd->iface->cs_freq_params.sec_channel_offset == 1)
|
else if (hapd->cs_freq_params.sec_channel_offset == 1)
|
||||||
sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
|
sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
|
||||||
else
|
else
|
||||||
return eid;
|
return eid;
|
||||||
|
@ -409,7 +409,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||||
pos = hostapd_eid_roaming_consortium(hapd, pos);
|
pos = hostapd_eid_roaming_consortium(hapd, pos);
|
||||||
|
|
||||||
pos = hostapd_add_csa_elems(hapd, pos, (u8 *)resp,
|
pos = hostapd_add_csa_elems(hapd, pos, (u8 *)resp,
|
||||||
&hapd->iface->cs_c_off_proberesp);
|
&hapd->cs_c_off_proberesp);
|
||||||
#ifdef CONFIG_IEEE80211AC
|
#ifdef CONFIG_IEEE80211AC
|
||||||
pos = hostapd_eid_vht_capabilities(hapd, pos);
|
pos = hostapd_eid_vht_capabilities(hapd, pos);
|
||||||
pos = hostapd_eid_vht_operation(hapd, pos);
|
pos = hostapd_eid_vht_operation(hapd, pos);
|
||||||
|
@ -824,7 +824,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
tailpos = hostapd_eid_adv_proto(hapd, tailpos);
|
tailpos = hostapd_eid_adv_proto(hapd, tailpos);
|
||||||
tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
|
tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
|
||||||
tailpos = hostapd_add_csa_elems(hapd, tailpos, tail,
|
tailpos = hostapd_add_csa_elems(hapd, tailpos, tail,
|
||||||
&hapd->iface->cs_c_off_beacon);
|
&hapd->cs_c_off_beacon);
|
||||||
#ifdef CONFIG_IEEE80211AC
|
#ifdef CONFIG_IEEE80211AC
|
||||||
tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
|
tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
|
||||||
tailpos = hostapd_eid_vht_operation(hapd, tailpos);
|
tailpos = hostapd_eid_vht_operation(hapd, tailpos);
|
||||||
|
@ -957,7 +957,7 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
|
||||||
struct wpabuf *beacon, *proberesp, *assocresp;
|
struct wpabuf *beacon, *proberesp, *assocresp;
|
||||||
int res, ret = -1;
|
int res, ret = -1;
|
||||||
|
|
||||||
if (hapd->iface->csa_in_progress) {
|
if (hapd->csa_in_progress) {
|
||||||
wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
|
wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
14
src/ap/dfs.c
14
src/ap/dfs.c
|
@ -756,6 +756,16 @@ static int hostapd_dfs_start_channel_switch_cac(struct hostapd_iface *iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_csa_in_progress(struct hostapd_iface *iface)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < iface->num_bss; i++)
|
||||||
|
if (iface->bss[i]->csa_in_progress)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
|
static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
|
||||||
{
|
{
|
||||||
struct hostapd_channel_data *channel;
|
struct hostapd_channel_data *channel;
|
||||||
|
@ -769,10 +779,10 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
|
wpa_printf(MSG_DEBUG, "%s called (CAC active: %s, CSA active: %s)",
|
||||||
__func__, iface->cac_started ? "yes" : "no",
|
__func__, iface->cac_started ? "yes" : "no",
|
||||||
iface->csa_in_progress ? "yes" : "no");
|
hostapd_csa_in_progress(iface) ? "yes" : "no");
|
||||||
|
|
||||||
/* Check if CSA in progress */
|
/* Check if CSA in progress */
|
||||||
if (iface->csa_in_progress)
|
if (hostapd_csa_in_progress(iface))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Check if active CAC */
|
/* Check if active CAC */
|
||||||
|
|
|
@ -489,9 +489,10 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
||||||
hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
|
hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
|
||||||
hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx;
|
hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx;
|
||||||
|
|
||||||
if (hapd->iface->csa_in_progress &&
|
if (hapd->csa_in_progress &&
|
||||||
freq == hapd->iface->cs_freq_params.freq) {
|
freq == hapd->cs_freq_params.freq) {
|
||||||
hostapd_cleanup_cs_params(hapd);
|
hostapd_cleanup_cs_params(hapd);
|
||||||
|
ieee802_11_set_beacon(hapd);
|
||||||
|
|
||||||
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d",
|
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED "freq=%d",
|
||||||
freq);
|
freq);
|
||||||
|
|
|
@ -2175,13 +2175,12 @@ static void free_beacon_data(struct beacon_data *beacon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_build_beacon_data(struct hostapd_iface *iface,
|
static int hostapd_build_beacon_data(struct hostapd_data *hapd,
|
||||||
struct beacon_data *beacon)
|
struct beacon_data *beacon)
|
||||||
{
|
{
|
||||||
struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
|
struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
|
||||||
struct wpa_driver_ap_params params;
|
struct wpa_driver_ap_params params;
|
||||||
int ret;
|
int ret;
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
|
||||||
|
|
||||||
os_memset(beacon, 0, sizeof(*beacon));
|
os_memset(beacon, 0, sizeof(*beacon));
|
||||||
ret = ieee802_11_build_ap_params(hapd, ¶ms);
|
ret = ieee802_11_build_ap_params(hapd, ¶ms);
|
||||||
|
@ -2305,14 +2304,15 @@ static int hostapd_change_config_freq(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
|
static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
|
||||||
struct csa_settings *settings)
|
struct csa_settings *settings)
|
||||||
{
|
{
|
||||||
|
struct hostapd_iface *iface = hapd->iface;
|
||||||
struct hostapd_freq_params old_freq;
|
struct hostapd_freq_params old_freq;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
os_memset(&old_freq, 0, sizeof(old_freq));
|
os_memset(&old_freq, 0, sizeof(old_freq));
|
||||||
if (!iface || !iface->freq || iface->csa_in_progress)
|
if (!iface || !iface->freq || hapd->csa_in_progress)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
|
ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
|
||||||
|
@ -2321,7 +2321,7 @@ static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = hostapd_build_beacon_data(iface, &settings->beacon_after);
|
ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
|
||||||
|
|
||||||
/* change back the configuration */
|
/* change back the configuration */
|
||||||
hostapd_change_config_freq(iface->bss[0], iface->conf,
|
hostapd_change_config_freq(iface->bss[0], iface->conf,
|
||||||
|
@ -2331,18 +2331,18 @@ static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* set channel switch parameters for csa ie */
|
/* set channel switch parameters for csa ie */
|
||||||
iface->cs_freq_params = settings->freq_params;
|
hapd->cs_freq_params = settings->freq_params;
|
||||||
iface->cs_count = settings->cs_count;
|
hapd->cs_count = settings->cs_count;
|
||||||
iface->cs_block_tx = settings->block_tx;
|
hapd->cs_block_tx = settings->block_tx;
|
||||||
|
|
||||||
ret = hostapd_build_beacon_data(iface, &settings->beacon_csa);
|
ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
free_beacon_data(&settings->beacon_after);
|
free_beacon_data(&settings->beacon_after);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings->counter_offset_beacon = iface->cs_c_off_beacon;
|
settings->counter_offset_beacon = hapd->cs_c_off_beacon;
|
||||||
settings->counter_offset_presp = iface->cs_c_off_proberesp;
|
settings->counter_offset_presp = hapd->cs_c_off_proberesp;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2350,13 +2350,12 @@ static int hostapd_fill_csa_settings(struct hostapd_iface *iface,
|
||||||
|
|
||||||
void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
|
void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
|
||||||
{
|
{
|
||||||
os_memset(&hapd->iface->cs_freq_params, 0,
|
os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
|
||||||
sizeof(hapd->iface->cs_freq_params));
|
hapd->cs_count = 0;
|
||||||
hapd->iface->cs_count = 0;
|
hapd->cs_block_tx = 0;
|
||||||
hapd->iface->cs_block_tx = 0;
|
hapd->cs_c_off_beacon = 0;
|
||||||
hapd->iface->cs_c_off_beacon = 0;
|
hapd->cs_c_off_proberesp = 0;
|
||||||
hapd->iface->cs_c_off_proberesp = 0;
|
hapd->csa_in_progress = 0;
|
||||||
hapd->iface->csa_in_progress = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2364,7 +2363,7 @@ int hostapd_switch_channel(struct hostapd_data *hapd,
|
||||||
struct csa_settings *settings)
|
struct csa_settings *settings)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ret = hostapd_fill_csa_settings(hapd->iface, settings);
|
ret = hostapd_fill_csa_settings(hapd, settings);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -2378,7 +2377,7 @@ int hostapd_switch_channel(struct hostapd_data *hapd,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
hapd->iface->csa_in_progress = 1;
|
hapd->csa_in_progress = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,14 @@ struct hostapd_data {
|
||||||
size_t psk_len);
|
size_t psk_len);
|
||||||
void *new_psk_cb_ctx;
|
void *new_psk_cb_ctx;
|
||||||
|
|
||||||
|
/* channel switch parameters */
|
||||||
|
struct hostapd_freq_params cs_freq_params;
|
||||||
|
u8 cs_count;
|
||||||
|
int cs_block_tx;
|
||||||
|
unsigned int cs_c_off_beacon;
|
||||||
|
unsigned int cs_c_off_proberesp;
|
||||||
|
int csa_in_progress;
|
||||||
|
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
struct p2p_data *p2p;
|
struct p2p_data *p2p;
|
||||||
struct p2p_group *p2p_group;
|
struct p2p_group *p2p_group;
|
||||||
|
@ -343,14 +351,6 @@ struct hostapd_iface {
|
||||||
/* lowest observed noise floor in dBm */
|
/* lowest observed noise floor in dBm */
|
||||||
s8 lowest_nf;
|
s8 lowest_nf;
|
||||||
|
|
||||||
/* channel switch parameters */
|
|
||||||
struct hostapd_freq_params cs_freq_params;
|
|
||||||
u8 cs_count;
|
|
||||||
int cs_block_tx;
|
|
||||||
unsigned int cs_c_off_beacon;
|
|
||||||
unsigned int cs_c_off_proberesp;
|
|
||||||
int csa_in_progress;
|
|
||||||
|
|
||||||
unsigned int dfs_cac_ms;
|
unsigned int dfs_cac_ms;
|
||||||
struct os_reltime dfs_cac_start;
|
struct os_reltime dfs_cac_start;
|
||||||
|
|
||||||
|
|
|
@ -1680,7 +1680,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
|
||||||
|
|
||||||
bss->freq = data.ch_switch.freq;
|
bss->freq = data.ch_switch.freq;
|
||||||
|
|
||||||
wpa_supplicant_event(drv->ctx, EVENT_CH_SWITCH, &data);
|
wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12118,7 +12118,7 @@ static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
|
nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count);
|
NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count);
|
||||||
ret = nl80211_put_freq_params(msg, &settings->freq_params);
|
ret = nl80211_put_freq_params(msg, &settings->freq_params);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue