static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) { uint i; struct net_device *ndev = wil_to_ndev(wil); struct wireless_dev *wdev = wil->wdev; wil_dbg_misc(wil, "%s()\n", __func__); wil_link_off(wil); clear_bit(wil_status_fwconnected, &wil->status); switch (wdev->sme_state) { case CFG80211_SME_CONNECTED: cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE, NULL, 0, GFP_KERNEL); break; case CFG80211_SME_CONNECTING: cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); break; default: break; } for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) wil_vring_fini_tx(wil, i); clear_bit(wil_status_dontscan, &wil->status); }
/* Interface callback functions, passing data back up to the cfg80211 layer */ void prism2_connect_result(wlandevice_t *wlandev, u8 failed) { u16 status = failed ? WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS; cfg80211_connect_result(wlandev->netdev, wlandev->bssid, NULL, 0, NULL, 0, status, GFP_KERNEL); }
VOID kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRoleIndex, IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason) { P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; do { if (prGlueInfo == NULL) { ASSERT(FALSE); break; } prGlueP2pInfo = prGlueInfo->prP2PInfo; if (prP2pConnInfo) { cfg80211_connect_result(prGlueP2pInfo->aprRoleHandler[ucRoleIndex], /* struct net_device * dev, */ prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, prP2pConnInfo->u4BufLength, pucRxIEBuf, u2RxIELen, u2StatusReason, GFP_KERNEL); /* gfp_t gfp *//* allocation flags */ prP2pConnInfo->eConnRequest = P2P_CONNECTION_TYPE_IDLE; } else { /* Disconnect, what if u2StatusReason == 0? */ cfg80211_disconnected(prGlueP2pInfo->aprRoleHandler[ucRoleIndex], /* struct net_device * dev, */ u2StatusReason, pucRxIEBuf, u2RxIELen, GFP_KERNEL); } } while (FALSE); } /* kalP2PGCIndicateConnectionStatus */
void qtnf_virtual_intf_cleanup(struct net_device *ndev) { struct qtnf_vif *vif = qtnf_netdev_get_priv(ndev); struct qtnf_wmac *mac = wiphy_priv(vif->wdev.wiphy); if (vif->wdev.iftype == NL80211_IFTYPE_STATION) { switch (vif->sta_state) { case QTNF_STA_DISCONNECTED: break; case QTNF_STA_CONNECTING: cfg80211_connect_result(vif->netdev, vif->bss_cfg.bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); qtnf_disconnect(vif->wdev.wiphy, ndev, WLAN_REASON_DEAUTH_LEAVING); break; case QTNF_STA_CONNECTED: cfg80211_disconnected(vif->netdev, WLAN_REASON_DEAUTH_LEAVING, NULL, 0, 1, GFP_KERNEL); qtnf_disconnect(vif->wdev.wiphy, ndev, WLAN_REASON_DEAUTH_LEAVING); break; } vif->sta_state = QTNF_STA_DISCONNECTED; qtnf_scan_done(mac, true); } }
/* * CFG802.11 operation handler for association request. * * This function does not work when the current mode is set to Ad-Hoc, or * when there is already an association procedure going on. The given BSS * information is used to associate. */ static int mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int ret = 0; if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { wiphy_err(wiphy, "received infra assoc request " "when station is in ibss mode\n"); goto done; } wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", (char *) sme->ssid, sme->bssid); ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, priv->bss_mode, sme->channel, sme, 0); done: if (!ret) { cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0, NULL, 0, WLAN_STATUS_SUCCESS, GFP_KERNEL); dev_dbg(priv->adapter->dev, "info: associated to bssid %pM successfully\n", priv->cfg_bssid); } else { dev_dbg(priv->adapter->dev, "info: association to bssid %pM failed\n", priv->cfg_bssid); memset(priv->cfg_bssid, 0, ETH_ALEN); } return ret; }
void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 proto_reason) { if (ar->scan_req) { cfg80211_scan_done(ar->scan_req, true); ar->scan_req = NULL; } if (ar->nw_type & ADHOC_NETWORK) { if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: ath6k not in ibss mode\n", __func__); return; } memset(bssid, 0, ETH_ALEN); cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL); return; } if (ar->nw_type & INFRA_NETWORK) { if (ar->wdev->iftype != NL80211_IFTYPE_STATION && ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: ath6k not in station mode\n", __func__); return; } } /* * Send a disconnect command to target when a disconnect event is * received with reason code other than 3 (DISCONNECT_CMD - disconnect * request from host) to make the firmware stop trying to connect even * after giving disconnect event. There will be one more disconnect * event for this disconnect command with reason code DISCONNECT_CMD * which will be notified to cfg80211. */ if (reason != DISCONNECT_CMD) { ath6kl_wmi_disconnect_cmd(ar->wmi); return; } clear_bit(CONNECT_PEND, &ar->flag); if (ar->sme_state == SME_CONNECTING) { cfg80211_connect_result(ar->net_dev, bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); } else if (ar->sme_state == SME_CONNECTED) { cfg80211_disconnected(ar->net_dev, reason, NULL, 0, GFP_KERNEL); } ar->sme_state = SME_DISCONNECTED; }
static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) { int cid = -ENOENT; struct net_device *ndev = wil_to_ndev(wil); struct wireless_dev *wdev = wil->wdev; might_sleep(); if (bssid) { cid = wil_find_cid(wil, bssid); wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); } else { wil_dbg_misc(wil, "%s(all)\n", __func__); } if (cid >= 0) /* disconnect 1 peer */ wil_disconnect_cid(wil, cid); else /* disconnect all */ for (cid = 0; cid < WIL6210_MAX_CID; cid++) wil_disconnect_cid(wil, cid); /* link state */ switch (wdev->iftype) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: wil_link_off(wil); if (test_bit(wil_status_fwconnected, &wil->status)) { clear_bit(wil_status_fwconnected, &wil->status); cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE, NULL, 0, GFP_KERNEL); } else if (test_bit(wil_status_fwconnecting, &wil->status)) { cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); } clear_bit(wil_status_fwconnecting, &wil->status); break; default: break; } }
void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif) { if (vif->wdev.iftype == NL80211_IFTYPE_STATION) { switch (vif->sta_state) { case QTNF_STA_CONNECTING: cfg80211_connect_result(vif->netdev, vif->bss_cfg.bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); break; case QTNF_STA_CONNECTED: cfg80211_disconnected(vif->netdev, WLAN_REASON_DEAUTH_LEAVING, NULL, 0, 1, GFP_KERNEL); break; case QTNF_STA_DISCONNECTED: break; } } cfg80211_shutdown_all_interfaces(vif->wdev.wiphy); vif->sta_state = QTNF_STA_DISCONNECTED; }
static void r92su_bss_connect_work(struct work_struct *work) { struct r92su *r92su; struct c2h_join_bss_event *join_bss = NULL; struct cfg80211_bss *cfg_bss = NULL; struct r92su_bss_priv *bss_priv; u8 *resp_ie = NULL; unsigned int resp_ie_len = 0; u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE; r92su = container_of(work, struct r92su, connect_bss_work); mutex_lock(&r92su->lock); if (!r92su_is_open(r92su)) goto out; cfg_bss = r92su->want_connect_bss; join_bss = r92su->connect_result; if (!cfg_bss || !join_bss) goto out; bss_priv = r92su_get_bss_priv(cfg_bss); r92su->connect_result = NULL; if (le32_to_cpu(join_bss->bss.ie_length) < 12) goto report_cfg80211; if (join_bss->join_result) { struct r92su_bss_priv *bss_priv = r92su_get_bss_priv(cfg_bss); struct r92su_sta *sta; sta = r92su_sta_alloc(r92su, join_bss->bss.bssid, BSS_MACID, le32_to_cpu(join_bss->aid), GFP_KERNEL); if (!sta) goto report_cfg80211; resp_ie = join_bss->bss.ies.ie; resp_ie_len = le32_to_cpu(join_bss->bss.ie_length) - 12; sta->enc_sta = le32_to_cpu(join_bss->bss.privacy) ? true : false; sta->qos_sta = r92su_parse_wmm_cap_ie(r92su, resp_ie, resp_ie_len); /* The 802.11-2012 spec says that a HT STA has to be QoS STA * as well. So in theory we should do instead: * sta->qos_sta |= sta->ht_sta; * However, the QoS parameters are needed for legacy STAs as * well. Therefore, there's no excuse for a HT STA to forget * the WMM IE! */ if (sta->qos_sta) sta->ht_sta = r92su_parse_ht_cap_ie(r92su, resp_ie, resp_ie_len); status = WLAN_STATUS_SUCCESS; bss_priv->sta = sta; rcu_assign_pointer(r92su->connect_bss, cfg_bss); r92su->want_connect_bss = NULL; r92su_set_state(r92su, R92SU_CONNECTED); } report_cfg80211: switch (r92su->wdev.iftype) { case NL80211_IFTYPE_STATION: cfg80211_connect_result(r92su->wdev.netdev, join_bss->bss.bssid, bss_priv->assoc_ie, bss_priv->assoc_ie_len, resp_ie, resp_ie_len, status, GFP_KERNEL); if (status == WLAN_STATUS_SUCCESS) r92su_set_power(r92su, true); break; case NL80211_IFTYPE_ADHOC: if (status == WLAN_STATUS_SUCCESS) { cfg80211_ibss_joined(r92su->wdev.netdev, join_bss->bss.bssid, cfg_bss->channel, GFP_KERNEL); } break; default: WARN(1, "unsupported network type %d\n", r92su->wdev.iftype); break; } kfree(bss_priv->assoc_ie); bss_priv->assoc_ie = NULL; out: mutex_unlock(&r92su->lock); kfree(join_bss); if (status == WLAN_STATUS_SUCCESS) { netif_tx_start_all_queues(r92su->wdev.netdev); netif_carrier_on(r92su->wdev.netdev); } else { r92su_bss_free(r92su, cfg_bss); } }
static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid) { int cid = -ENOENT; struct net_device *ndev = wil_to_ndev(wil); struct wireless_dev *wdev = wil->wdev; might_sleep(); if (bssid) { cid = wil_find_cid(wil, bssid); wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); } else { wil_dbg_misc(wil, "%s(all)\n", __func__); } if (cid >= 0) /* disconnect 1 peer */ wil_disconnect_cid(wil, cid); else {/* disconnect all */ /* * BUG FIX: Disconnect single sta only * We may get to here few times * with BSSID address */ if(ndev->dev_addr && bssid) { if(ether_addr_equal(ndev->dev_addr, bssid) ) { for (cid = 0; cid < WIL6210_MAX_CID; cid++) wil_disconnect_cid(wil, cid); } } } /* link state */ switch (wdev->iftype) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: wil_link_off(wil); clear_bit(wil_status_fwconnected, &wil->status); switch (wdev->sme_state) { case CFG80211_SME_CONNECTED: cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE, NULL, 0, GFP_KERNEL); break; case CFG80211_SME_CONNECTING: cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); break; default: break; } wil_dbg_misc(wil, "clear_bit(wil_status_dontscan)\n"); clear_bit(wil_status_dontscan, &wil->status); break; default: /* AP-like interface and monitor: * never scan, always connected */ if (bssid) cfg80211_del_sta(ndev, bssid, GFP_KERNEL); break; } }
/* * This function handles the result of different pending network operations. * * The following operations are handled and CFG802.11 subsystem is * notified accordingly - * - Scan request completion * - Association request completion * - IBSS join request completion * - Disconnect request completion */ void mwifiex_cfg80211_results(struct work_struct *work) { struct mwifiex_private *priv = container_of(work, struct mwifiex_private, cfg_workqueue); struct mwifiex_user_scan_cfg *scan_req; int ret = 0, i; struct ieee80211_channel *chan; if (priv->scan_request) { scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); if (!scan_req) { dev_err(priv->adapter->dev, "failed to alloc " "scan_req\n"); return; } for (i = 0; i < priv->scan_request->n_ssids; i++) { memcpy(scan_req->ssid_list[i].ssid, priv->scan_request->ssids[i].ssid, priv->scan_request->ssids[i].ssid_len); scan_req->ssid_list[i].max_len = priv->scan_request->ssids[i].ssid_len; } for (i = 0; i < priv->scan_request->n_channels; i++) { chan = priv->scan_request->channels[i]; scan_req->chan_list[i].chan_number = chan->hw_value; scan_req->chan_list[i].radio_type = chan->band; if (chan->flags & IEEE80211_CHAN_DISABLED) scan_req->chan_list[i].scan_type = MWIFIEX_SCAN_TYPE_PASSIVE; else scan_req->chan_list[i].scan_type = MWIFIEX_SCAN_TYPE_ACTIVE; scan_req->chan_list[i].scan_time = 0; } if (mwifiex_set_user_scan_ioctl(priv, scan_req)) { ret = -EFAULT; goto done; } if (mwifiex_inform_bss_from_scan_result(priv, NULL)) ret = -EFAULT; done: priv->scan_result_status = ret; dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n", __func__); cfg80211_scan_done(priv->scan_request, (priv->scan_result_status < 0)); priv->scan_request = NULL; kfree(scan_req); } if (priv->assoc_request == 1) { if (!priv->assoc_result) { cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0, NULL, 0, WLAN_STATUS_SUCCESS, GFP_KERNEL); dev_dbg(priv->adapter->dev, "info: associated to bssid %pM successfully\n", priv->cfg_bssid); } else { dev_dbg(priv->adapter->dev, "info: association to bssid %pM failed\n", priv->cfg_bssid); memset(priv->cfg_bssid, 0, ETH_ALEN); } priv->assoc_request = 0; priv->assoc_result = 0; } if (priv->ibss_join_request == 1) { if (!priv->ibss_join_result) { cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); dev_dbg(priv->adapter->dev, "info: joined/created adhoc network with bssid" " %pM successfully\n", priv->cfg_bssid); } else { dev_dbg(priv->adapter->dev, "info: failed creating/joining adhoc network\n"); } priv->ibss_join_request = 0; priv->ibss_join_result = 0; } if (priv->disconnect) { memset(priv->cfg_bssid, 0, ETH_ALEN); priv->disconnect = 0; } }
void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid, u16 listen_intvl, u16 beacon_intvl, enum network_type nw_type, u8 beacon_ie_len, u8 assoc_req_len, u8 assoc_resp_len, u8 *assoc_info) { struct ieee80211_channel *chan; /* capinfo + listen interval */ u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16); /* capinfo + status code + associd */ u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16); u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset; u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len + assoc_resp_ie_offset; assoc_req_len -= assoc_req_ie_offset; assoc_resp_len -= assoc_resp_ie_offset; /* * Store Beacon interval here; DTIM period will be available only once * a Beacon frame from the AP is seen. */ ar->assoc_bss_beacon_int = beacon_intvl; clear_bit(DTIM_PERIOD_AVAIL, &ar->flag); if (nw_type & ADHOC_NETWORK) { if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: ath6k not in ibss mode\n", __func__); return; } } if (nw_type & INFRA_NETWORK) { if (ar->wdev->iftype != NL80211_IFTYPE_STATION && ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: ath6k not in station mode\n", __func__); return; } } chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel); if (nw_type & ADHOC_NETWORK) { cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL); return; } if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info, beacon_ie_len) < 0) { ath6kl_err("could not add cfg80211 bss entry for " "connect/roamed notification\n"); return; } if (ar->sme_state == SME_CONNECTING) { /* inform connect result to cfg80211 */ ar->sme_state = SME_CONNECTED; cfg80211_connect_result(ar->net_dev, bssid, assoc_req_ie, assoc_req_len, assoc_resp_ie, assoc_resp_len, WLAN_STATUS_SUCCESS, GFP_KERNEL); } else if (ar->sme_state == SME_CONNECTED) { /* inform roam event to cfg80211 */ cfg80211_roamed(ar->net_dev, chan, bssid, assoc_req_ie, assoc_req_len, assoc_resp_ie, assoc_resp_len, GFP_KERNEL); } }
static int qtnf_event_handle_bss_join(struct qtnf_vif *vif, const struct qlink_event_bss_join *join_info, u16 len) { struct wiphy *wiphy = priv_to_wiphy(vif->mac); enum ieee80211_statuscode status = le16_to_cpu(join_info->status); struct cfg80211_chan_def chandef; struct cfg80211_bss *bss = NULL; u8 *ie = NULL; size_t payload_len; u16 tlv_type; u16 tlv_value_len; size_t tlv_full_len; const struct qlink_tlv_hdr *tlv; const u8 *rsp_ies = NULL; size_t rsp_ies_len = 0; if (unlikely(len < sizeof(*join_info))) { pr_err("VIF%u.%u: payload is too short (%u < %zu)\n", vif->mac->macid, vif->vifid, len, sizeof(struct qlink_event_bss_join)); return -EINVAL; } if (vif->wdev.iftype != NL80211_IFTYPE_STATION) { pr_err("VIF%u.%u: BSS_JOIN event when not in STA mode\n", vif->mac->macid, vif->vifid); return -EPROTO; } pr_debug("VIF%u.%u: BSSID:%pM status:%u\n", vif->mac->macid, vif->vifid, join_info->bssid, status); if (status != WLAN_STATUS_SUCCESS) goto done; qlink_chandef_q2cfg(wiphy, &join_info->chan, &chandef); if (!cfg80211_chandef_valid(&chandef)) { pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n", vif->mac->macid, vif->vifid, chandef.chan->center_freq, chandef.center_freq1, chandef.center_freq2, chandef.width); status = WLAN_STATUS_UNSPECIFIED_FAILURE; goto done; } bss = cfg80211_get_bss(wiphy, chandef.chan, join_info->bssid, NULL, 0, IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY); if (!bss) { pr_warn("VIF%u.%u: add missing BSS:%pM chan:%u\n", vif->mac->macid, vif->vifid, join_info->bssid, chandef.chan->hw_value); if (!vif->wdev.ssid_len) { pr_warn("VIF%u.%u: SSID unknown for BSS:%pM\n", vif->mac->macid, vif->vifid, join_info->bssid); status = WLAN_STATUS_UNSPECIFIED_FAILURE; goto done; } ie = kzalloc(2 + vif->wdev.ssid_len, GFP_KERNEL); if (!ie) { pr_warn("VIF%u.%u: IE alloc failed for BSS:%pM\n", vif->mac->macid, vif->vifid, join_info->bssid); status = WLAN_STATUS_UNSPECIFIED_FAILURE; goto done; } ie[0] = WLAN_EID_SSID; ie[1] = vif->wdev.ssid_len; memcpy(ie + 2, vif->wdev.ssid, vif->wdev.ssid_len); bss = cfg80211_inform_bss(wiphy, chandef.chan, CFG80211_BSS_FTYPE_UNKNOWN, join_info->bssid, 0, WLAN_CAPABILITY_ESS, 100, ie, 2 + vif->wdev.ssid_len, 0, GFP_KERNEL); if (!bss) { pr_warn("VIF%u.%u: can't connect to unknown BSS: %pM\n", vif->mac->macid, vif->vifid, join_info->bssid); status = WLAN_STATUS_UNSPECIFIED_FAILURE; goto done; } } payload_len = len - sizeof(*join_info); tlv = (struct qlink_tlv_hdr *)join_info->ies; while (payload_len >= sizeof(struct qlink_tlv_hdr)) { tlv_type = le16_to_cpu(tlv->type); tlv_value_len = le16_to_cpu(tlv->len); tlv_full_len = tlv_value_len + sizeof(struct qlink_tlv_hdr); if (payload_len < tlv_full_len) { pr_warn("invalid %u TLV\n", tlv_type); status = WLAN_STATUS_UNSPECIFIED_FAILURE; goto done; } if (tlv_type == QTN_TLV_ID_IE_SET) { const struct qlink_tlv_ie_set *ie_set; unsigned int ie_len; if (payload_len < sizeof(*ie_set)) { pr_warn("invalid IE_SET TLV\n"); status = WLAN_STATUS_UNSPECIFIED_FAILURE; goto done; } ie_set = (const struct qlink_tlv_ie_set *)tlv; ie_len = tlv_value_len - (sizeof(*ie_set) - sizeof(ie_set->hdr)); switch (ie_set->type) { case QLINK_IE_SET_ASSOC_RESP: if (ie_len) { rsp_ies = ie_set->ie_data; rsp_ies_len = ie_len; } break; default: pr_warn("unexpected IE type: %u\n", ie_set->type); break; } } payload_len -= tlv_full_len; tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); } if (payload_len) pr_warn("VIF%u.%u: unexpected remaining payload: %zu\n", vif->mac->macid, vif->vifid, payload_len); done: cfg80211_connect_result(vif->netdev, join_info->bssid, NULL, 0, rsp_ies, rsp_ies_len, status, GFP_KERNEL); if (bss) { if (!ether_addr_equal(vif->bssid, join_info->bssid)) ether_addr_copy(vif->bssid, join_info->bssid); cfg80211_put_bss(wiphy, bss); } if (status == WLAN_STATUS_SUCCESS) netif_carrier_on(vif->netdev); kfree(ie); return 0; }