Commit 945ce30a authored by Jérôme Pouiller's avatar Jérôme Pouiller Committed by Greg Kroah-Hartman
Browse files

staging: wfx: simplify hif_scan() usage



The structures hif_req_start_scan and hif_ssid_def come from hardware
API. It is not intended to be manipulated in upper layers of the driver.

So, this patch relocate handling of theses structures to hif_scan()
(the low level function). This change also allows to drop struct
wfx_scan_params.

Signed-off-by: default avatarJérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20191217161318.31402-48-Jerome.Pouiller@silabs.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1a53df55
Loading
Loading
Loading
Loading
+47 −29
Original line number Original line Diff line number Diff line
@@ -220,41 +220,59 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val,
	return ret;
	return ret;
}
}


int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg)
int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req,
	     int chan_start_idx, int chan_num)
{
{
	int ret, i;
	int ret, i;
	struct hif_msg *hif;
	struct hif_msg *hif;
	struct hif_ssid_def *ssids;
	size_t buf_len =
	size_t buf_len = sizeof(struct hif_req_start_scan) +
		sizeof(struct hif_req_start_scan_alt) + chan_num * sizeof(u8);
		arg->scan_req.num_of_channels * sizeof(u8) +
	struct hif_req_start_scan_alt *body = wfx_alloc_hif(buf_len, &hif);
		arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def);
	int tmo_chan_fg, tmo_chan_bg, tmo;
	struct hif_req_start_scan *body = wfx_alloc_hif(buf_len, &hif);

	u8 *ptr = (u8 *) body + sizeof(*body);
	WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params");

	WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params");
	WARN(arg->scan_req.num_of_channels > HIF_API_MAX_NB_CHANNELS, "invalid params");

	WARN(arg->scan_req.num_of_ssids > 2, "invalid params");
	compiletime_assert(IEEE80211_MAX_SSID_LEN == HIF_API_SSID_SIZE,
	WARN(arg->scan_req.band > 1, "invalid params");
			   "API inconsistency");

	for (i = 0; i < req->n_ssids; i++) {
	// FIXME: This API is unnecessary complex, fixing NumOfChannels and
		memcpy(body->ssid_def[i].ssid, req->ssids[i].ssid,
	// adding a member SsidDef at end of struct hif_req_start_scan would
		       IEEE80211_MAX_SSID_LEN);
	// simplify that a lot.
		body->ssid_def[i].ssid_length =
	memcpy(body, &arg->scan_req, sizeof(*body));
			cpu_to_le32(req->ssids[i].ssid_len);
	cpu_to_le32s(&body->min_channel_time);
	}
	cpu_to_le32s(&body->max_channel_time);
	body->num_of_ssids = HIF_API_MAX_NB_SSIDS;
	cpu_to_le32s(&body->tx_power_level);
	// Background scan is always a good idea
	memcpy(ptr, arg->ssids,
	body->scan_type.type = 1;
	       arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def));
	body->scan_flags.fbg = 1;
	ssids = (struct hif_ssid_def *) ptr;
	body->tx_power_level =
	for (i = 0; i < body->num_of_ssids; ++i)
		cpu_to_le32(req->channels[chan_start_idx]->max_power);
		cpu_to_le32s(&ssids[i].ssid_length);
	body->num_of_channels = chan_num;
	ptr += arg->scan_req.num_of_ssids * sizeof(struct hif_ssid_def);
	for (i = 0; i < chan_num; i++)
	memcpy(ptr, arg->ch, arg->scan_req.num_of_channels * sizeof(u8));
		body->channel_list[i] =
	ptr += arg->scan_req.num_of_channels * sizeof(u8);
			req->channels[i + chan_start_idx]->hw_value;
	WARN(buf_len != ptr - (u8 *) body, "allocation size mismatch");
	if (req->no_cck)
		body->max_transmit_rate = API_RATE_INDEX_G_6MBPS;
	else
		body->max_transmit_rate = API_RATE_INDEX_B_1MBPS;
	if (req->channels[chan_start_idx]->flags & IEEE80211_CHAN_NO_IR) {
		body->min_channel_time = cpu_to_le32(50);
		body->max_channel_time = cpu_to_le32(150);
	} else {
		body->min_channel_time = cpu_to_le32(10);
		body->max_channel_time = cpu_to_le32(50);
		body->num_of_probe_requests = 2;
		body->probe_delay = 100;
	}
	tmo_chan_bg = le32_to_cpu(body->max_channel_time) * USEC_PER_TU;
	tmo_chan_fg = 512 * USEC_PER_TU + body->probe_delay;
	tmo_chan_fg *= body->num_of_probe_requests;
	tmo = chan_num * max(tmo_chan_bg, tmo_chan_fg);

	wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len);
	wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len);
	ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
	ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
	kfree(hif);
	kfree(hif);
	return ret;
	return ret ? ret : usecs_to_jiffies(tmo);
}
}


int hif_stop_scan(struct wfx_vif *wvif)
int hif_stop_scan(struct wfx_vif *wvif)
+3 −7
Original line number Original line Diff line number Diff line
@@ -13,15 +13,10 @@
#include "hif_api_cmd.h"
#include "hif_api_cmd.h"


struct ieee80211_tx_queue_params;
struct ieee80211_tx_queue_params;
struct cfg80211_scan_request;
struct wfx_dev;
struct wfx_dev;
struct wfx_vif;
struct wfx_vif;


struct wfx_scan_params {
	struct hif_req_start_scan scan_req;
	struct hif_ssid_def *ssids;
	u8 *ch;
};

struct wfx_hif_cmd {
struct wfx_hif_cmd {
	struct mutex      lock;
	struct mutex      lock;
	struct mutex      key_renew_lock;
	struct mutex      key_renew_lock;
@@ -45,7 +40,8 @@ int hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id,
		 void *buf, size_t buf_size);
		 void *buf, size_t buf_size);
int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id,
int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id,
		  void *buf, size_t buf_size);
		  void *buf, size_t buf_size);
int hif_scan(struct wfx_vif *wvif, const struct wfx_scan_params *arg);
int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211,
	     int chan_start, int chan_num);
int hif_stop_scan(struct wfx_vif *wvif);
int hif_stop_scan(struct wfx_vif *wvif);
int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg);
int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg);
int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout);
int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout);
+8 −46
Original line number Original line Diff line number Diff line
@@ -34,19 +34,18 @@ static void wfx_scan_restart_delayed(struct wfx_vif *wvif)
	}
	}
}
}


static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan)
static int wfx_scan_start(struct wfx_vif *wvif,
			  int chan_start_idx, int chan_num)
{
{
	int tmo = 500;
	int tmo;


	if (wvif->state == WFX_STATE_PRE_STA)
	if (wvif->state == WFX_STATE_PRE_STA)
		return -EBUSY;
		return -EBUSY;


	tmo += scan->scan_req.num_of_channels *
	       ((20 * (scan->scan_req.max_channel_time)) + 10);
	atomic_set(&wvif->scan.in_progress, 1);
	atomic_set(&wvif->scan.in_progress, 1);


	schedule_delayed_work(&wvif->scan.timeout, msecs_to_jiffies(tmo));
	tmo = hif_scan(wvif, wvif->scan.req, chan_start_idx, chan_num);
	hif_scan(wvif, scan);
	schedule_delayed_work(&wvif->scan.timeout, tmo);
	return 0;
	return 0;
}
}


@@ -128,9 +127,6 @@ void wfx_scan_work(struct work_struct *work)
{
{
	struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan.work);
	struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan.work);
	struct ieee80211_channel **it;
	struct ieee80211_channel **it;
	struct wfx_scan_params scan = {
		.scan_req.scan_type.type = 0,    /* Foreground */
	};
	struct ieee80211_channel *first;
	struct ieee80211_channel *first;
	int i;
	int i;


@@ -173,48 +169,14 @@ void wfx_scan_work(struct work_struct *work)
		    (*it)->max_power != first->max_power)
		    (*it)->max_power != first->max_power)
			break;
			break;
	}
	}
	scan.scan_req.band = first->band;

	if (wvif->scan.req->no_cck)
		scan.scan_req.max_transmit_rate = API_RATE_INDEX_G_6MBPS;
	else
		scan.scan_req.max_transmit_rate = API_RATE_INDEX_B_1MBPS;
	scan.scan_req.num_of_probe_requests =
		(first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2;
	scan.scan_req.num_of_ssids = wvif->scan.n_ssids;
	scan.ssids = &wvif->scan.ssids[0];
	scan.scan_req.num_of_channels = it - wvif->scan.curr;
	scan.scan_req.probe_delay = 100;
	// FIXME: Check if FW can do active scan while joined.
	if (wvif->state == WFX_STATE_STA) {
		scan.scan_req.scan_type.type = 1;
		scan.scan_req.scan_flags.fbg = 1;
	}

	scan.ch = kcalloc(scan.scan_req.num_of_channels,
			  sizeof(u8), GFP_KERNEL);

	if (!scan.ch) {
		wvif->scan.status = -ENOMEM;
		goto fail;
	}
	for (i = 0; i < scan.scan_req.num_of_channels; ++i)
		scan.ch[i] = wvif->scan.curr[i]->hw_value;

	if (wvif->scan.curr[0]->flags & IEEE80211_CHAN_NO_IR) {
		scan.scan_req.min_channel_time = 50;
		scan.scan_req.max_channel_time = 150;
	} else {
		scan.scan_req.min_channel_time = 10;
		scan.scan_req.max_channel_time = 50;
	}
	if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
	if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
	    wvif->scan.output_power != first->max_power) {
	    wvif->scan.output_power != first->max_power) {
		wvif->scan.output_power = first->max_power;
		wvif->scan.output_power = first->max_power;
		hif_set_output_power(wvif, wvif->scan.output_power * 10);
		hif_set_output_power(wvif, wvif->scan.output_power * 10);
	}
	}
	wvif->scan.status = wfx_scan_start(wvif, &scan);
	wvif->scan.status = wfx_scan_start(wvif,
	kfree(scan.ch);
					   wvif->scan.curr - wvif->scan.begin,
					   it - wvif->scan.curr);
	if (wvif->scan.status)
	if (wvif->scan.status)
		goto fail;
		goto fail;
	wvif->scan.curr = it;
	wvif->scan.curr = it;
+1 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
#include "hif_api_general.h"
#include "hif_api_general.h"


#define USEC_PER_TXOP 32 // see struct ieee80211_tx_queue_params
#define USEC_PER_TXOP 32 // see struct ieee80211_tx_queue_params
#define USEC_PER_TU 1024


struct hwbus_ops;
struct hwbus_ops;