|
@@ -9249,6 +9249,71 @@ static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
|
|
|
}
|
|
|
|
|
|
|
|
|
+static int hw_mode_to_qca_acs(enum hostapd_hw_mode hw_mode)
|
|
|
+{
|
|
|
+ switch (hw_mode) {
|
|
|
+ case HOSTAPD_MODE_IEEE80211B:
|
|
|
+ return QCA_ACS_MODE_IEEE80211B;
|
|
|
+ case HOSTAPD_MODE_IEEE80211G:
|
|
|
+ return QCA_ACS_MODE_IEEE80211G;
|
|
|
+ case HOSTAPD_MODE_IEEE80211A:
|
|
|
+ return QCA_ACS_MODE_IEEE80211A;
|
|
|
+ case HOSTAPD_MODE_IEEE80211AD:
|
|
|
+ return QCA_ACS_MODE_IEEE80211AD;
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
|
|
|
+{
|
|
|
+ struct i802_bss *bss = priv;
|
|
|
+ struct wpa_driver_nl80211_data *drv = bss->drv;
|
|
|
+ struct nl_msg *msg;
|
|
|
+ struct nlattr *data;
|
|
|
+ int ret = -ENOBUFS;
|
|
|
+ int mode;
|
|
|
+
|
|
|
+ mode = hw_mode_to_qca_acs(params->hw_mode);
|
|
|
+ if (mode < 0)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ msg = nlmsg_alloc();
|
|
|
+ if (!msg)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
|
|
|
+
|
|
|
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
|
|
+ NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
|
|
|
+ NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD,
|
|
|
+ QCA_NL80211_VENDOR_SUBCMD_DO_ACS);
|
|
|
+
|
|
|
+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
|
|
|
+ if (!data)
|
|
|
+ goto nla_put_failure;
|
|
|
+ NLA_PUT_U8(msg, QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE, mode);
|
|
|
+ if (params->ht_enabled)
|
|
|
+ NLA_PUT_FLAG(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED);
|
|
|
+ if (params->ht40_enabled)
|
|
|
+ NLA_PUT_FLAG(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED);
|
|
|
+ nla_nest_end(msg, data);
|
|
|
+
|
|
|
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
|
|
+ msg = NULL;
|
|
|
+ if (ret) {
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "nl80211: Failed to invoke driver ACS function: %s",
|
|
|
+ strerror(errno));
|
|
|
+ }
|
|
|
+
|
|
|
+nla_put_failure:
|
|
|
+ nlmsg_free(msg);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|
|
.name = "nl80211",
|
|
|
.desc = "Linux nl80211/cfg80211",
|
|
@@ -9353,4 +9418,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|
|
.br_set_net_param = wpa_driver_br_set_net_param,
|
|
|
.add_tx_ts = nl80211_add_ts,
|
|
|
.del_tx_ts = nl80211_del_ts,
|
|
|
+ .do_acs = wpa_driver_do_acs,
|
|
|
};
|