}
+#ifdef CONFIG_DRIVER_NL80211_QCA
+static void connect_ext_feature_set(u8 *features,
+ enum qca_wlan_connect_ext_features idx)
+{
+ u8 *idx_byte = &features[idx / 8];
+
+ *idx_byte |= BIT(idx % 8);
+}
+#endif /* CONFIG_DRIVER_NL80211_QCA */
+
+
+static int nl80211_connect_ext(struct wpa_driver_nl80211_data *drv,
+ struct wpa_driver_associate_params *params)
+{
+#ifdef CONFIG_DRIVER_NL80211_QCA
+ struct nl_msg *msg;
+ struct nlattr *attr;
+ u8 features[(NUM_QCA_CONNECT_EXT_FEATURES + 7) / 8] = {};
+
+ if (!drv->connect_ext_vendor_cmd_avail)
+ return -1;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Connect_ext (ifindex=%d)",
+ drv->ifindex);
+
+ 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_CONNECT_EXT))
+ goto fail;
+
+ attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!attr)
+ goto fail;
+
+ if (params->rsn_overriding) {
+ wpa_printf(MSG_DEBUG, "- RSN overriding");
+ connect_ext_feature_set(features, QCA_CONNECT_EXT_FEATURE_RSNO);
+ }
+
+ if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_FEATURES,
+ sizeof(features), features))
+ goto fail;
+
+ nla_nest_end(msg, attr);
+
+ return send_and_recv_cmd(drv, msg);
+fail:
+ nlmsg_free(msg);
+#endif /* CONFIG_DRIVER_NL80211_QCA */
+ return -1;
+}
+
+
static int wpa_driver_nl80211_try_connect(
struct wpa_driver_nl80211_data *drv,
struct wpa_driver_associate_params *params,
}
#endif /* CONFIG_DRIVER_NL80211_QCA */
+ nl80211_connect_ext(drv, params);
wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_CONNECT);
if (!msg)
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_OVERRIDE,
RSN_OVERRIDE_NOT_USED);
- if (!wpas_driver_bss_selection(wpa_s) &&
- wpas_rsn_overriding(wpa_s) &&
+ if (wpas_rsn_overriding(wpa_s) &&
wpas_ap_supports_rsn_overriding(wpa_s, bss) &&
wpa_ie_len + 2 + 4 + 1 <= max_wpa_ie_len) {
u8 *pos = wpa_ie + wpa_ie_len, *start = pos;
wpa_ie_len += pos - start;
}
- if (wpas_driver_bss_selection(wpa_s) &&
- wpas_rsn_overriding(wpa_s)) {
- /* TODO: Replace this indication of support for RSN overriding
- * to the driver in driver-based BSS selection cases with
- * something cleaner. */
- if (wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
- u8 *pos = wpa_ie + wpa_ie_len;
-
- *pos++ = WLAN_EID_VENDOR_SPECIFIC;
- *pos++ = 4;
- WPA_PUT_BE32(pos, RSNE_OVERRIDE_IE_VENDOR_TYPE);
- pos += 4;
- wpa_hexdump(MSG_MSGDUMP, "RSNE Override", wpa_ie,
- pos - wpa_ie);
- wpa_ie_len += 2 + 4;
- }
-
- if (wpa_ie_len + 2 + 4 <= max_wpa_ie_len) {
- u8 *pos = wpa_ie + wpa_ie_len;
-
- *pos++ = WLAN_EID_VENDOR_SPECIFIC;
- *pos++ = 4;
- WPA_PUT_BE32(pos, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
- pos += 4;
- wpa_hexdump(MSG_MSGDUMP, "RSNE Override 2",
- wpa_ie, pos - wpa_ie);
- wpa_ie_len += 2 + 4;
- }
- }
-
+ params->rsn_overriding = wpas_rsn_overriding(wpa_s);
params->wpa_ie = wpa_ie;
params->wpa_ie_len = wpa_ie_len;
params->auth_alg = algs;