Extend hw_mode to support any band for offloaded ACS case
[mech_eap.git] / src / drivers / driver_nl80211_capa.c
index 36c8ce2..e23c57e 100644 (file)
@@ -71,6 +71,7 @@ struct wiphy_info_data {
        unsigned int connect_supported:1;
        unsigned int p2p_go_supported:1;
        unsigned int p2p_client_supported:1;
+       unsigned int p2p_go_ctwindow_supported:1;
        unsigned int p2p_concurrent:1;
        unsigned int channel_switch_supported:1;
        unsigned int set_qos_map_supported:1;
@@ -334,6 +335,33 @@ static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
 }
 
 
+static int ext_feature_isset(const u8 *ext_features, int ext_features_len,
+                            enum nl80211_ext_feature_index ftidx)
+{
+       u8 ft_byte;
+
+       if ((int) ftidx / 8 >= ext_features_len)
+               return 0;
+
+       ft_byte = ext_features[ftidx / 8];
+       return (ft_byte & BIT(ftidx % 8)) != 0;
+}
+
+
+static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
+                                        struct nlattr *tb)
+{
+       struct wpa_driver_capa *capa = info->capa;
+
+       if (tb == NULL)
+               return;
+
+       if (ext_feature_isset(nla_data(tb), nla_len(tb),
+                             NL80211_EXT_FEATURE_VHT_IBSS))
+               capa->flags |= WPA_DRIVER_FLAGS_VHT_IBSS;
+}
+
+
 static void wiphy_info_feature_flags(struct wiphy_info_data *info,
                                     struct nlattr *tb)
 {
@@ -365,6 +393,9 @@ static void wiphy_info_feature_flags(struct wiphy_info_data *info,
                capa->flags |= WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH;
        }
 
+       if (flags & NL80211_FEATURE_P2P_GO_CTWIN)
+               info->p2p_go_ctwindow_supported = 1;
+
        if (flags & NL80211_FEATURE_LOW_PRIORITY_SCAN)
                info->have_low_prio_scan = 1;
 
@@ -505,6 +536,7 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
                info->device_ap_sme = 1;
 
        wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
+       wiphy_info_ext_feature_flags(info, tb[NL80211_ATTR_EXT_FEATURES]);
        wiphy_info_probe_resp_offload(capa,
                                      tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
 
@@ -543,19 +575,25 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
                                continue;
                        }
                        vinfo = nla_data(nl);
-                       switch (vinfo->subcmd) {
-                       case QCA_NL80211_VENDOR_SUBCMD_ROAMING:
-                               drv->roaming_vendor_cmd_avail = 1;
-                               break;
-                       case QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY:
-                               drv->dfs_vendor_cmd_avail = 1;
-                               break;
-                       case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
-                               drv->get_features_vendor_cmd_avail = 1;
-                               break;
-                       case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
-                               drv->capa.flags |= WPA_DRIVER_FLAGS_ACS_OFFLOAD;
-                               break;
+                       if (vinfo->vendor_id == OUI_QCA) {
+                               switch (vinfo->subcmd) {
+                               case QCA_NL80211_VENDOR_SUBCMD_TEST:
+                                       drv->vendor_cmd_test_avail = 1;
+                                       break;
+                               case QCA_NL80211_VENDOR_SUBCMD_ROAMING:
+                                       drv->roaming_vendor_cmd_avail = 1;
+                                       break;
+                               case QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY:
+                                       drv->dfs_vendor_cmd_avail = 1;
+                                       break;
+                               case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
+                                       drv->get_features_vendor_cmd_avail = 1;
+                                       break;
+                               case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
+                                       drv->capa.flags |=
+                                               WPA_DRIVER_FLAGS_ACS_OFFLOAD;
+                                       break;
+                               }
                        }
 
                        wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
@@ -775,6 +813,9 @@ static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
 
        if (check_feature(QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD, &info))
                drv->capa.flags |= WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD;
+
+       if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY, &info))
+               drv->capa.flags |= WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
 }
 
 
@@ -824,6 +865,7 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
        drv->device_ap_sme = info.device_ap_sme;
        drv->poll_command_supported = info.poll_command_supported;
        drv->data_tx_status = info.data_tx_status;
+       drv->p2p_go_ctwindow_supported = info.p2p_go_ctwindow_supported;
        if (info.set_qos_map_supported)
                drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
        drv->have_low_prio_scan = info.have_low_prio_scan;