Exemplo n.º 1
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;

	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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
	}
}