Allowed frequency list configuration for AP operation
Add support to configure the allowed frequency list for AP operation using a QCA vendor interface before NL80211_CMD_NEW_BEACON/ NL80211_CMD_START_AP. hostapd generates the allowed frequency list by intersecting user configured frequency list and all the frequencies advertised by the driver including disabled channels. If user doesn't specify allowed frequency list, all the frequencies advertised by the driver, including disabled channels, will be configured. Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
This commit is contained in:
parent
9bad3c975d
commit
9932ff30c4
7 changed files with 94 additions and 7 deletions
|
@ -883,10 +883,10 @@ int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
|
||||
static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
|
||||
struct hostapd_hw_modes *mode,
|
||||
int acs_ch_list_all,
|
||||
int **freq_list)
|
||||
void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
|
||||
struct hostapd_hw_modes *mode,
|
||||
int acs_ch_list_all, bool allow_disabled,
|
||||
int **freq_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -912,7 +912,7 @@ static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
|
|||
(!hapd->iface->conf->ieee80211ax &&
|
||||
!hapd->iface->conf->ieee80211be)))
|
||||
continue;
|
||||
if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
|
||||
if ((!(chan->flag & HOSTAPD_CHAN_DISABLED) || allow_disabled) &&
|
||||
!(hapd->iface->conf->acs_exclude_dfs &&
|
||||
(chan->flag & HOSTAPD_CHAN_RADAR)) &&
|
||||
!(chan->max_tx_power < hapd->iface->conf->min_tx_power))
|
||||
|
@ -969,7 +969,7 @@ int hostapd_drv_do_acs(struct hostapd_data *hapd)
|
|||
selected_mode != mode->mode)
|
||||
continue;
|
||||
hostapd_get_hw_mode_any_channels(hapd, mode, acs_ch_list_all,
|
||||
&freq_list);
|
||||
false, &freq_list);
|
||||
}
|
||||
|
||||
params.freq_list = freq_list;
|
||||
|
|
|
@ -156,6 +156,11 @@ int hostapd_drv_set_qos_map(struct hostapd_data *hapd, const u8 *qos_map_set,
|
|||
|
||||
void hostapd_get_ext_capa(struct hostapd_iface *iface);
|
||||
|
||||
void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
|
||||
struct hostapd_hw_modes *mode,
|
||||
int acs_ch_list_all, bool allow_disabled,
|
||||
int **freq_list);
|
||||
|
||||
static inline int hostapd_drv_set_countermeasures(struct hostapd_data *hapd,
|
||||
int enabled)
|
||||
{
|
||||
|
|
|
@ -2058,6 +2058,8 @@ void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
|
|||
os_free(params->unsol_bcast_probe_resp_tmpl);
|
||||
params->unsol_bcast_probe_resp_tmpl = NULL;
|
||||
#endif /* CONFIG_IEEE80211AX */
|
||||
os_free(params->allowed_freqs);
|
||||
params->allowed_freqs = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2069,7 +2071,8 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
|
|||
struct hostapd_config *iconf = iface->conf;
|
||||
struct hostapd_hw_modes *cmode = iface->current_mode;
|
||||
struct wpabuf *beacon, *proberesp, *assocresp;
|
||||
int res, ret = -1;
|
||||
int res, ret = -1, i;
|
||||
struct hostapd_hw_modes *mode;
|
||||
|
||||
if (!hapd->drv_priv) {
|
||||
wpa_printf(MSG_ERROR, "Interface is disabled");
|
||||
|
@ -2144,6 +2147,19 @@ static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
|
|||
&cmode->eht_capab[IEEE80211_MODE_AP]) == 0)
|
||||
params.freq = &freq;
|
||||
|
||||
for (i = 0; i < hapd->iface->num_hw_features; i++) {
|
||||
mode = &hapd->iface->hw_features[i];
|
||||
|
||||
if (iconf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
|
||||
iconf->hw_mode != mode->mode)
|
||||
continue;
|
||||
|
||||
hostapd_get_hw_mode_any_channels(hapd, mode,
|
||||
!(iconf->acs_freq_list.num ||
|
||||
iconf->acs_ch_list.num),
|
||||
true, ¶ms.allowed_freqs);
|
||||
}
|
||||
|
||||
res = hostapd_drv_set_ap(hapd, ¶ms);
|
||||
hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
|
||||
if (res)
|
||||
|
|
|
@ -1748,6 +1748,16 @@ struct wpa_driver_ap_params {
|
|||
* The driver will use these to include RNR elements in EMA beacons.
|
||||
*/
|
||||
u8 **rnr_elem_offset;
|
||||
|
||||
/**
|
||||
* allowed_freqs - List of allowed 20 MHz channel center frequencies in
|
||||
* MHz for AP operation. Drivers which support this parameter will
|
||||
* generate a new list based on this provided list by filtering out
|
||||
* channels that cannot be used at that time due to regulatory or other
|
||||
* constraints. The resulting list is used as the list of all allowed
|
||||
* channels whenever performing operations like ACS and DFS.
|
||||
*/
|
||||
int *allowed_freqs;
|
||||
};
|
||||
|
||||
struct wpa_driver_mesh_bss_params {
|
||||
|
|
|
@ -4753,6 +4753,52 @@ static int nl80211_mbssid(struct nl_msg *msg,
|
|||
#endif /* CONFIG_IEEE80211AX */
|
||||
|
||||
|
||||
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||
static void qca_set_allowed_ap_freqs(struct wpa_driver_nl80211_data *drv,
|
||||
const int *freqs, int num_freqs)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
struct nlattr *params, *freqs_list;
|
||||
int i, ret;
|
||||
|
||||
if (!drv->set_wifi_conf_vendor_cmd_avail || !drv->qca_ap_allowed_freqs)
|
||||
return;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Set AP allowed frequency list");
|
||||
|
||||
if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
|
||||
QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
|
||||
!(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
|
||||
goto err;
|
||||
|
||||
freqs_list = nla_nest_start(
|
||||
msg, QCA_WLAN_VENDOR_ATTR_CONFIG_AP_ALLOWED_FREQ_LIST);
|
||||
if (!freqs_list)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < num_freqs; i++) {
|
||||
if (nla_put_u32(msg, i, freqs[i]))
|
||||
goto err;
|
||||
}
|
||||
|
||||
nla_nest_end(msg, freqs_list);
|
||||
nla_nest_end(msg, params);
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
if (ret)
|
||||
wpa_printf(MSG_ERROR,
|
||||
"nl80211: Failed set AP alllowed frequency list: %d (%s)",
|
||||
ret, strerror(-ret));
|
||||
|
||||
return;
|
||||
err:
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
|
||||
|
||||
static int wpa_driver_nl80211_set_ap(void *priv,
|
||||
struct wpa_driver_ap_params *params)
|
||||
{
|
||||
|
@ -5075,6 +5121,12 @@ static int wpa_driver_nl80211_set_ap(void *priv,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DRIVER_NL80211_QCA
|
||||
if (cmd == NL80211_CMD_NEW_BEACON && params->allowed_freqs)
|
||||
qca_set_allowed_ap_freqs(drv, params->allowed_freqs,
|
||||
int_array_len(params->allowed_freqs));
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
|
||||
ret = send_and_recv_msgs_connect_handle(drv, msg, bss, 1);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
|
||||
|
|
|
@ -199,6 +199,7 @@ struct wpa_driver_nl80211_data {
|
|||
unsigned int uses_6ghz:1;
|
||||
unsigned int secure_ranging_ctx_vendor_cmd_avail:1;
|
||||
unsigned int puncturing:1;
|
||||
unsigned int qca_ap_allowed_freqs:1;
|
||||
|
||||
u64 vendor_scan_cookie;
|
||||
u64 remain_on_chan_cookie;
|
||||
|
|
|
@ -1405,6 +1405,9 @@ static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
|
|||
QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_AP,
|
||||
&info))
|
||||
drv->capa.flags2 |= WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP;
|
||||
if (check_feature(QCA_WLAN_VENDOR_FEATURE_AP_ALLOWED_FREQ_LIST,
|
||||
&info))
|
||||
drv->qca_ap_allowed_freqs = 1;
|
||||
os_free(info.flags);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue