/* * CFG802.11 operation handler for scan request. * * This function issues a scan request to the firmware based upon * the user specified scan configuration. On successfull completion, * it also informs the results. */ static int mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int i; struct ieee80211_channel *chan; wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); priv->scan_request = request; priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); if (!priv->user_scan_cfg) { dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); return -ENOMEM; } priv->user_scan_cfg->num_ssids = request->n_ssids; priv->user_scan_cfg->ssid_list = request->ssids; for (i = 0; i < request->n_channels; i++) { chan = request->channels[i]; priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; priv->user_scan_cfg->chan_list[i].radio_type = chan->band; if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) priv->user_scan_cfg->chan_list[i].scan_type = MWIFIEX_SCAN_TYPE_PASSIVE; else priv->user_scan_cfg->chan_list[i].scan_type = MWIFIEX_SCAN_TYPE_ACTIVE; priv->user_scan_cfg->chan_list[i].scan_time = 0; } if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) return -EFAULT; return 0; }
/* * CFG802.11 operation handler for scan request. * * This function issues a scan request to the firmware based upon * the user specified scan configuration. On successfull completion, * it also informs the results. */ static int mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int i; struct ieee80211_channel *chan; wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); priv->scan_request = request; priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); if (!priv->user_scan_cfg) { dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); return -ENOMEM; } priv->user_scan_cfg->num_ssids = request->n_ssids; priv->user_scan_cfg->ssid_list = request->ssids; if (request->ie && request->ie_len) { for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) { if (priv->vs_ie[i].mask != MWIFIEX_VSIE_MASK_CLEAR) continue; priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_SCAN; memcpy(&priv->vs_ie[i].ie, request->ie, request->ie_len); break; } } for (i = 0; i < min_t(u32, request->n_channels, MWIFIEX_USER_SCAN_CHAN_MAX); i++) { chan = request->channels[i]; priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; priv->user_scan_cfg->chan_list[i].radio_type = chan->band; if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) priv->user_scan_cfg->chan_list[i].scan_type = MWIFIEX_SCAN_TYPE_PASSIVE; else priv->user_scan_cfg->chan_list[i].scan_type = MWIFIEX_SCAN_TYPE_ACTIVE; priv->user_scan_cfg->chan_list[i].scan_time = 0; } if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) return -EFAULT; if (request->ie && request->ie_len) { for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) { if (priv->vs_ie[i].mask == MWIFIEX_VSIE_MASK_SCAN) { priv->vs_ie[i].mask = MWIFIEX_VSIE_MASK_CLEAR; memset(&priv->vs_ie[i].ie, 0, MWIFIEX_MAX_VSIE_LEN); } } } return 0; }
/* * 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; } }