int cfg80211_mgd_wext_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) { struct wireless_dev *wdev = dev->ieee80211_ptr; /* call only for station! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) return -EINVAL; data->flags = 0; wdev_lock(wdev); if (wdev->current_bss) { const u8 *ie = ieee80211_bss_get_ie(&wdev->current_bss->pub, WLAN_EID_SSID); if (ie) { data->flags = 1; data->length = ie[1]; memcpy(ssid, ie + 2, data->length); } } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) { data->flags = 1; data->length = wdev->wext.connect.ssid_len; memcpy(ssid, wdev->wext.connect.ssid, data->length); } wdev_unlock(wdev); return 0; }
static int mwifiex_process_country_ie(struct mwifiex_private *priv, struct cfg80211_bss *bss) { const u8 *country_ie; u8 country_ie_len; struct mwifiex_802_11d_domain_reg *domain_info = &priv->adapter->domain_reg; rcu_read_lock(); country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY); if (!country_ie) { rcu_read_unlock(); return 0; } country_ie_len = country_ie[1]; if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) { rcu_read_unlock(); return 0; } if (!strncmp(priv->adapter->country_code, &country_ie[2], 2)) { rcu_read_unlock(); wiphy_dbg(priv->wdev->wiphy, "11D: skip setting domain info in FW\n"); return 0; } memcpy(priv->adapter->country_code, &country_ie[2], 2); domain_info->country_code[0] = country_ie[2]; domain_info->country_code[1] = country_ie[3]; domain_info->country_code[2] = ' '; country_ie_len -= IEEE80211_COUNTRY_STRING_LEN; domain_info->no_of_triplet = country_ie_len / sizeof(struct ieee80211_country_ie_triplet); memcpy((u8 *)domain_info->triplet, &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len); rcu_read_unlock(); if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, HostCmd_ACT_GEN_SET, 0, NULL, false)) { wiphy_err(priv->adapter->wiphy, "11D: setting domain info in FW\n"); return -1; } mwifiex_dnld_txpwr_table(priv); return 0; }
static int mwifiex_process_country_ie(struct mwifiex_private *priv, struct cfg80211_bss *bss) { u8 *country_ie, country_ie_len; struct mwifiex_802_11d_domain_reg *domain_info = &priv->adapter->domain_reg; country_ie = (u8 *)ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY); if (!country_ie) return 0; country_ie_len = country_ie[1]; if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) return 0; domain_info->country_code[0] = country_ie[2]; domain_info->country_code[1] = country_ie[3]; domain_info->country_code[2] = ' '; country_ie_len -= IEEE80211_COUNTRY_STRING_LEN; domain_info->no_of_triplet = country_ie_len / sizeof(struct ieee80211_country_ie_triplet); memcpy((u8 *)domain_info->triplet, &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len); if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(priv->adapter->wiphy, "11D: setting domain info in FW\n"); return -1; } return 0; }
static int wil_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) { struct wil6210_priv *wil = wiphy_to_wil(wiphy); struct cfg80211_bss *bss; struct wmi_connect_cmd conn; const u8 *ssid_eid; const u8 *rsn_eid; int ch; int rc = 0; if (test_bit(wil_status_fwconnecting, &wil->status) || test_bit(wil_status_fwconnected, &wil->status)) return -EALREADY; bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid, sme->ssid_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); if (!bss) { wil_err(wil, "Unable to find BSS\n"); return -ENOENT; } ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); if (!ssid_eid) { wil_err(wil, "No SSID\n"); rc = -ENOENT; goto out; } rsn_eid = sme->ie ? cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) : NULL; if (rsn_eid) { if (sme->ie_len > WMI_MAX_IE_LEN) { rc = -ERANGE; wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len); goto out; } /* * For secure assoc, send: * (1) WMI_DELETE_CIPHER_KEY_CMD * (2) WMI_SET_APPIE_CMD */ rc = wmi_del_cipher_key(wil, 0, bss->bssid); if (rc) { wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n"); goto out; } /* WMI_SET_APPIE_CMD */ rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); if (rc) { wil_err(wil, "WMI_SET_APPIE_CMD failed\n"); goto out; } } /* WMI_CONNECT_CMD */ memset(&conn, 0, sizeof(conn)); switch (bss->capability & WLAN_CAPABILITY_DMG_TYPE_MASK) { case WLAN_CAPABILITY_DMG_TYPE_AP: conn.network_type = WMI_NETTYPE_INFRA; break; case WLAN_CAPABILITY_DMG_TYPE_PBSS: conn.network_type = WMI_NETTYPE_P2P; break; default: wil_err(wil, "Unsupported BSS type, capability= 0x%04x\n", bss->capability); goto out; } if (rsn_eid) { conn.dot11_auth_mode = WMI_AUTH11_SHARED; conn.auth_mode = WMI_AUTH_WPA2_PSK; conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP; conn.pairwise_crypto_len = 16; } else { conn.dot11_auth_mode = WMI_AUTH11_OPEN; conn.auth_mode = WMI_AUTH_NONE; } conn.ssid_len = min_t(u8, ssid_eid[1], 32); memcpy(conn.ssid, ssid_eid+2, conn.ssid_len); ch = bss->channel->hw_value; if (ch == 0) { wil_err(wil, "BSS at unknown frequency %dMhz\n", bss->channel->center_freq); rc = -EOPNOTSUPP; goto out; } conn.channel = ch - 1; memcpy(conn.bssid, bss->bssid, ETH_ALEN); memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); set_bit(wil_status_fwconnecting, &wil->status); rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); if (rc == 0) { /* Connect can take lots of time */ mod_timer(&wil->connect_timer, jiffies + msecs_to_jiffies(2000)); } else { clear_bit(wil_status_fwconnecting, &wil->status); } out: cfg80211_put_bss(wiphy, bss); return rc; }