Ejemplo n.º 1
0
Archivo: p2p.c Proyecto: AK101111/linux
int wil_p2p_listen(struct wil6210_priv *wil, unsigned int duration,
		   struct ieee80211_channel *chan, u64 *cookie)
{
	struct wil_p2p_info *p2p = &wil->p2p;
	u8 channel = P2P_DMG_SOCIAL_CHANNEL;
	int rc;

	if (!chan)
		return -EINVAL;

	channel = chan->hw_value;

	wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration);

	mutex_lock(&wil->mutex);

	if (p2p->discovery_started) {
		wil_err(wil, "%s: discovery already ongoing\n", __func__);
		rc = -EBUSY;
		goto out;
	}

	rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI);
	if (rc) {
		wil_err(wil, "%s: wmi_p2p_cfg failed\n", __func__);
		goto out;
	}

	rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
	if (rc) {
		wil_err(wil, "%s: wmi_set_ssid failed\n", __func__);
		goto out_stop;
	}

	rc = wmi_start_listen(wil);
	if (rc) {
		wil_err(wil, "%s: wmi_start_listen failed\n", __func__);
		goto out_stop;
	}

	memcpy(&p2p->listen_chan, chan, sizeof(*chan));
	*cookie = ++p2p->cookie;

	p2p->discovery_started = 1;
	INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired);
	mod_timer(&p2p->discovery_timer,
		  jiffies + msecs_to_jiffies(duration));

out_stop:
	if (rc)
		wmi_stop_discovery(wil);

out:
	mutex_unlock(&wil->mutex);
	return rc;
}
Ejemplo n.º 2
0
static int wil_p2p_start_listen(struct wil6210_priv *wil)
{
	struct wil_p2p_info *p2p = &wil->p2p;
	u8 channel = p2p->listen_chan.hw_value;
	int rc;

	lockdep_assert_held(&wil->mutex);

	rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI);
	if (rc) {
		wil_err(wil, "wmi_p2p_cfg failed\n");
		goto out;
	}

	rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
	if (rc) {
		wil_err(wil, "wmi_set_ssid failed\n");
		goto out_stop;
	}

	rc = wmi_start_listen(wil);
	if (rc) {
		wil_err(wil, "wmi_start_listen failed\n");
		goto out_stop;
	}

	INIT_WORK(&p2p->discovery_expired_work, wil_p2p_listen_expired);
	mod_timer(&p2p->discovery_timer,
		  jiffies + msecs_to_jiffies(p2p->listen_duration));
out_stop:
	if (rc)
		wmi_stop_discovery(wil);

out:
	return rc;
}
Ejemplo n.º 3
0
static int __wil_up(struct wil6210_priv *wil)
{
	struct net_device *ndev = wil_to_ndev(wil);
	struct wireless_dev *wdev = wil->wdev;
	struct ieee80211_channel *channel = wdev->preset_chandef.chan;
	int rc;
	int bi;
	u16 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);

	rc = wil_reset(wil);
	if (rc)
		return rc;

	/* FIXME Firmware works now in PBSS mode(ToDS=0, FromDS=0) */
	wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
	switch (wdev->iftype) {
	case NL80211_IFTYPE_STATION:
		wil_dbg_misc(wil, "type: STATION\n");
		bi = 0;
		ndev->type = ARPHRD_ETHER;
		break;
	case NL80211_IFTYPE_AP:
		wil_dbg_misc(wil, "type: AP\n");
		bi = 100;
		ndev->type = ARPHRD_ETHER;
		break;
	case NL80211_IFTYPE_P2P_CLIENT:
		wil_dbg_misc(wil, "type: P2P_CLIENT\n");
		bi = 0;
		ndev->type = ARPHRD_ETHER;
		break;
	case NL80211_IFTYPE_P2P_GO:
		wil_dbg_misc(wil, "type: P2P_GO\n");
		bi = 100;
		ndev->type = ARPHRD_ETHER;
		break;
	case NL80211_IFTYPE_MONITOR:
		wil_dbg_misc(wil, "type: Monitor\n");
		bi = 0;
		ndev->type = ARPHRD_IEEE80211_RADIOTAP;
		/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
		break;
	default:
		return -EOPNOTSUPP;
	}

	/* Apply profile in the following order: */
	/* SSID and channel for the AP */
	switch (wdev->iftype) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_P2P_GO:
		if (wdev->ssid_len == 0) {
			wil_err(wil, "SSID not set\n");
			return -EINVAL;
		}
		rc = wmi_set_ssid(wil, wdev->ssid_len, wdev->ssid);
		if (rc)
			return rc;
		break;
	default:
		break;
	}

	/* MAC address - pre-requisite for other commands */
	wmi_set_mac_address(wil, ndev->dev_addr);

	/* Set up beaconing if required. */
	if (bi > 0) {
		rc = wmi_pcp_start(wil, bi, wmi_nettype,
				   (channel ? channel->hw_value : 0));
		if (rc)
			return rc;
	}

	/* Rx VRING. After MAC and beacon */
	wil_rx_init(wil);

	return 0;
}
Ejemplo n.º 4
0
int wil_p2p_search(struct wil6210_priv *wil,
		   struct cfg80211_scan_request *request)
{
	int rc;
	struct wil_p2p_info *p2p = &wil->p2p;

	wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL);

	lockdep_assert_held(&wil->mutex);

	if (p2p->discovery_started) {
		wil_err(wil, "search failed. discovery already ongoing\n");
		rc = -EBUSY;
		goto out;
	}

	rc = wmi_p2p_cfg(wil, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI);
	if (rc) {
		wil_err(wil, "wmi_p2p_cfg failed\n");
		goto out;
	}

	rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
	if (rc) {
		wil_err(wil, "wmi_set_ssid failed\n");
		goto out_stop;
	}

	/* Set application IE to probe request and probe response */
	rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ,
			request->ie_len, request->ie);
	if (rc) {
		wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n");
		goto out_stop;
	}

	/* supplicant doesn't provide Probe Response IEs. As a workaround -
	 * re-use Probe Request IEs
	 */
	rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP,
			request->ie_len, request->ie);
	if (rc) {
		wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n");
		goto out_stop;
	}

	rc = wmi_start_search(wil);
	if (rc) {
		wil_err(wil, "wmi_start_search failed\n");
		goto out_stop;
	}

	p2p->discovery_started = 1;
	INIT_WORK(&p2p->discovery_expired_work, wil_p2p_search_expired);
	mod_timer(&p2p->discovery_timer,
		  jiffies + msecs_to_jiffies(P2P_SEARCH_DURATION_MS));

out_stop:
	if (rc)
		wmi_stop_discovery(wil);

out:
	return rc;
}
Ejemplo n.º 5
0
static int wil_cfg80211_start_ap(struct wiphy *wiphy,
                                 struct net_device *ndev,
                                 struct cfg80211_ap_settings *info)
{
    int rc = 0;
    struct wil6210_priv *wil = wiphy_to_wil(wiphy);
    struct wireless_dev *wdev = ndev->ieee80211_ptr;
    struct ieee80211_channel *channel = info->chandef.chan;
    struct cfg80211_beacon_data *bcon = &info->beacon;
    u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);

    if (!channel) {
        wil_err(wil, "AP: No channel???\n");
        return -EINVAL;
    }

    wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
                 channel->center_freq, info->privacy ? "secure" : "open");
    print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
                         info->ssid, info->ssid_len);

    if (wil_fix_bcon(wil, bcon))
        wil_dbg_misc(wil, "Fixed bcon\n");

    mutex_lock(&wil->mutex);

    rc = wil_reset(wil);
    if (rc)
        goto out;

    /* Rx VRING. */
    rc = wil_rx_init(wil);
    if (rc)
        goto out;

    rc = wmi_set_ssid(wil, info->ssid_len, info->ssid);
    if (rc)
        goto out;

    /* MAC address - pre-requisite for other commands */
    wmi_set_mac_address(wil, ndev->dev_addr);

    /* IE's */
    /* bcon 'head IE's are not relevant for 60g band */
    /*
     * FW do not form regular beacon, so bcon IE's are not set
     * For the DMG bcon, when it will be supported, bcon IE's will
     * be reused; add something like:
     * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
     * bcon->beacon_ies);
     */
    wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len,
               bcon->proberesp_ies);
    wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len,
               bcon->assocresp_ies);

    wil->secure_pcp = info->privacy;

    rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
                       channel->hw_value);
    if (rc)
        goto out;


    netif_carrier_on(ndev);

out:
    mutex_unlock(&wil->mutex);
    return rc;
}