Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7fd871ed authored by Masakazu Mokuno's avatar Masakazu Mokuno Committed by John W. Linville
Browse files

PS3: gelic: Add support for ESSID scan



This adds the support for ESSID scanning

Signed-off-by: default avatarMasakazu Mokuno <mokuno@sm.sony.co.jp>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 552fe53f
Loading
Loading
Loading
Loading
+58 −7
Original line number Original line Diff line number Diff line
@@ -45,7 +45,8 @@
#include "ps3_gelic_wireless.h"
#include "ps3_gelic_wireless.h"




static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan);
static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan,
			       u8 *essid, size_t essid_len);
static int gelic_wl_try_associate(struct net_device *netdev);
static int gelic_wl_try_associate(struct net_device *netdev);


/*
/*
@@ -105,6 +106,7 @@ static const struct eurus_cmd_arg_info cmd_info[GELIC_EURUS_CMD_MAX_INDEX] = {
	[GELIC_EURUS_CMD_GET_WEP_CFG]    = { .post_arg = 1},
	[GELIC_EURUS_CMD_GET_WEP_CFG]    = { .post_arg = 1},
	[GELIC_EURUS_CMD_GET_WPA_CFG]    = { .post_arg = 1},
	[GELIC_EURUS_CMD_GET_WPA_CFG]    = { .post_arg = 1},
	[GELIC_EURUS_CMD_GET_RSSI_CFG]   = { .post_arg = 1},
	[GELIC_EURUS_CMD_GET_RSSI_CFG]   = { .post_arg = 1},
	[GELIC_EURUS_CMD_START_SCAN]     = { .pre_arg = 1},
	[GELIC_EURUS_CMD_GET_SCAN]       = { .post_arg = 1},
	[GELIC_EURUS_CMD_GET_SCAN]       = { .post_arg = 1},
};
};


@@ -163,7 +165,9 @@ static void gelic_eurus_sync_cmd_worker(struct work_struct *work)
	card = port_to_card(wl_port(wl));
	card = port_to_card(wl_port(wl));


	if (cmd_info[cmd->cmd].pre_arg) {
	if (cmd_info[cmd->cmd].pre_arg) {
		arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer));
		arg1 = (cmd->buffer) ?
			ps3_mm_phys_to_lpar(__pa(cmd->buffer)) :
			0;
		arg2 = cmd->buf_size;
		arg2 = cmd->buf_size;
	} else {
	} else {
		arg1 = 0;
		arg1 = 0;
@@ -360,6 +364,9 @@ static int gelic_wl_get_range(struct net_device *netdev,
	range->num_encoding_sizes = 3;
	range->num_encoding_sizes = 3;
	range->max_encoding_tokens = GELIC_WEP_KEYS;
	range->max_encoding_tokens = GELIC_WEP_KEYS;


	/* scan capability */
	range->scan_capa = IW_SCAN_CAPA_ESSID;

	pr_debug("%s: ->\n", __func__);
	pr_debug("%s: ->\n", __func__);
	return 0;
	return 0;


@@ -371,8 +378,18 @@ static int gelic_wl_set_scan(struct net_device *netdev,
			   union iwreq_data *wrqu, char *extra)
			   union iwreq_data *wrqu, char *extra)
{
{
	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
	struct iw_scan_req *req;
	u8 *essid = NULL;
	size_t essid_len = 0;


	return gelic_wl_start_scan(wl, 1);
	if (wrqu->data.length == sizeof(struct iw_scan_req) &&
	    wrqu->data.flags & IW_SCAN_THIS_ESSID) {
		req = (struct iw_scan_req*)extra;
		essid = req->essid;
		essid_len = req->essid_len;
		pr_debug("%s: ESSID scan =%s\n", __func__, essid);
	}
	return gelic_wl_start_scan(wl, 1, essid, essid_len);
}
}


#define OUI_LEN 3
#define OUI_LEN 3
@@ -1534,10 +1551,13 @@ static struct iw_statistics *gelic_wl_get_wireless_stats(
/*
/*
 *  scanning helpers
 *  scanning helpers
 */
 */
static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan,
			       u8 *essid, size_t essid_len)
{
{
	struct gelic_eurus_cmd *cmd;
	struct gelic_eurus_cmd *cmd;
	int ret = 0;
	int ret = 0;
	void *buf = NULL;
	size_t len;


	pr_debug("%s: <- always=%d\n", __func__, always_scan);
	pr_debug("%s: <- always=%d\n", __func__, always_scan);
	if (mutex_lock_interruptible(&wl->scan_lock))
	if (mutex_lock_interruptible(&wl->scan_lock))
@@ -1560,12 +1580,27 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
		complete(&wl->scan_done);
		complete(&wl->scan_done);
		goto out;
		goto out;
	}
	}

	/* ESSID scan ? */
	if (essid_len && essid) {
		buf = (void *)__get_free_page(GFP_KERNEL);
		if (!buf) {
			ret = -ENOMEM;
			goto out;
		}
		len = IW_ESSID_MAX_SIZE; /* hypervisor always requires 32 */
		memset(buf, 0, len);
		memcpy(buf, essid, essid_len);
		pr_debug("%s: essid scan='%s'\n", __func__, (char *)buf);
	} else
		len = 0;

	/*
	/*
	 * issue start scan request
	 * issue start scan request
	 */
	 */
	wl->scan_stat = GELIC_WL_SCAN_STAT_SCANNING;
	wl->scan_stat = GELIC_WL_SCAN_STAT_SCANNING;
	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_START_SCAN,
	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_START_SCAN,
				   NULL, 0);
				   buf, len);
	if (!cmd || cmd->status || cmd->cmd_status) {
	if (!cmd || cmd->status || cmd->cmd_status) {
		wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
		wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
		complete(&wl->scan_done);
		complete(&wl->scan_done);
@@ -1574,6 +1609,7 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
	}
	}
	kfree(cmd);
	kfree(cmd);
out:
out:
	free_page((unsigned long)buf);
	mutex_unlock(&wl->scan_lock);
	mutex_unlock(&wl->scan_lock);
	pr_debug("%s: ->\n", __func__);
	pr_debug("%s: ->\n", __func__);
	return ret;
	return ret;
@@ -2261,6 +2297,9 @@ static void gelic_wl_assoc_worker(struct work_struct *work)


	struct gelic_wl_scan_info *best_bss;
	struct gelic_wl_scan_info *best_bss;
	int ret;
	int ret;
	unsigned long irqflag;
	u8 *essid;
	size_t essid_len;


	wl = container_of(work, struct gelic_wl_info, assoc_work.work);
	wl = container_of(work, struct gelic_wl_info, assoc_work.work);


@@ -2269,7 +2308,19 @@ static void gelic_wl_assoc_worker(struct work_struct *work)
	if (wl->assoc_stat != GELIC_WL_ASSOC_STAT_DISCONN)
	if (wl->assoc_stat != GELIC_WL_ASSOC_STAT_DISCONN)
		goto out;
		goto out;


	ret = gelic_wl_start_scan(wl, 0);
	spin_lock_irqsave(&wl->lock, irqflag);
	if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat)) {
		pr_debug("%s: assoc ESSID configured %s\n", __func__,
			 wl->essid);
		essid = wl->essid;
		essid_len = wl->essid_len;
	} else {
		essid = NULL;
		essid_len = 0;
	}
	spin_unlock_irqrestore(&wl->lock, irqflag);

	ret = gelic_wl_start_scan(wl, 0, essid, essid_len);
	if (ret == -ERESTARTSYS) {
	if (ret == -ERESTARTSYS) {
		pr_debug("%s: scan start failed association\n", __func__);
		pr_debug("%s: scan start failed association\n", __func__);
		schedule_delayed_work(&wl->assoc_work, HZ/10); /*FIXME*/
		schedule_delayed_work(&wl->assoc_work, HZ/10); /*FIXME*/