All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jerome Pouiller <Jerome.Pouiller@silabs.com>
To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org
Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Kalle Valo" <kvalo@codeaurora.org>,
	"David S . Miller" <davem@davemloft.net>,
	devicetree@vger.kernel.org, "Rob Herring" <robh+dt@kernel.org>,
	"Jérôme Pouiller" <jerome.pouiller@silabs.com>
Subject: [PATCH 19/23] wfx: add scan.c/scan.h
Date: Mon, 12 Oct 2020 12:46:44 +0200	[thread overview]
Message-ID: <20201012104648.985256-20-Jerome.Pouiller@silabs.com> (raw)
In-Reply-To: <20201012104648.985256-1-Jerome.Pouiller@silabs.com>

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/net/wireless/silabs/wfx/scan.c | 132 +++++++++++++++++++++++++
 drivers/net/wireless/silabs/wfx/scan.h |  22 +++++
 2 files changed, 154 insertions(+)
 create mode 100644 drivers/net/wireless/silabs/wfx/scan.c
 create mode 100644 drivers/net/wireless/silabs/wfx/scan.h

diff --git a/drivers/net/wireless/silabs/wfx/scan.c b/drivers/net/wireless/silabs/wfx/scan.c
new file mode 100644
index 000000000000..fb47c7cddf2f
--- /dev/null
+++ b/drivers/net/wireless/silabs/wfx/scan.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Scan related functions.
+ *
+ * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#include <net/mac80211.h>
+
+#include "scan.h"
+#include "wfx.h"
+#include "sta.h"
+#include "hif_tx_mib.h"
+
+static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw,
+					      bool aborted)
+{
+	struct cfg80211_scan_info info = {
+		.aborted = aborted,
+	};
+
+	ieee80211_scan_completed(hw, &info);
+}
+
+static int update_probe_tmpl(struct wfx_vif *wvif,
+			     struct cfg80211_scan_request *req)
+{
+	struct sk_buff *skb;
+
+	skb = ieee80211_probereq_get(wvif->wdev->hw, wvif->vif->addr,
+				     NULL, 0, req->ie_len);
+	if (!skb)
+		return -ENOMEM;
+
+	skb_put_data(skb, req->ie, req->ie_len);
+	hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBREQ, 0);
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static int send_scan_req(struct wfx_vif *wvif,
+			 struct cfg80211_scan_request *req, int start_idx)
+{
+	int i, ret, timeout;
+	struct ieee80211_channel *ch_start, *ch_cur;
+
+	for (i = start_idx; i < req->n_channels; i++) {
+		ch_start = req->channels[start_idx];
+		ch_cur = req->channels[i];
+		WARN(ch_cur->band != NL80211_BAND_2GHZ, "band not supported");
+		if (ch_cur->max_power != ch_start->max_power)
+			break;
+		if ((ch_cur->flags ^ ch_start->flags) & IEEE80211_CHAN_NO_IR)
+			break;
+	}
+	wfx_tx_lock_flush(wvif->wdev);
+	wvif->scan_abort = false;
+	reinit_completion(&wvif->scan_complete);
+	ret = hif_scan(wvif, req, start_idx, i - start_idx, &timeout);
+	if (ret) {
+		wfx_tx_unlock(wvif->wdev);
+		return -EIO;
+	}
+	ret = wait_for_completion_timeout(&wvif->scan_complete, timeout);
+	if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower)
+		hif_set_output_power(wvif, wvif->vif->bss_conf.txpower);
+	wfx_tx_unlock(wvif->wdev);
+	if (!ret) {
+		dev_notice(wvif->wdev->dev, "scan timeout\n");
+		hif_stop_scan(wvif);
+		return -ETIMEDOUT;
+	}
+	if (wvif->scan_abort) {
+		dev_notice(wvif->wdev->dev, "scan abort\n");
+		return -ECONNABORTED;
+	}
+	return i - start_idx;
+}
+
+/*
+ * It is not really necessary to run scan request asynchronously. However,
+ * there is a bug in "iw scan" when ieee80211_scan_completed() is called before
+ * wfx_hw_scan() return
+ */
+void wfx_hw_scan_work(struct work_struct *work)
+{
+	struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan_work);
+	struct ieee80211_scan_request *hw_req = wvif->scan_req;
+	int chan_cur, ret;
+
+	mutex_lock(&wvif->wdev->conf_mutex);
+	mutex_lock(&wvif->scan_lock);
+	if (wvif->join_in_progress) {
+		dev_info(wvif->wdev->dev, "%s: abort in-progress REQ_JOIN",
+			 __func__);
+		wfx_reset(wvif);
+	}
+	update_probe_tmpl(wvif, &hw_req->req);
+	chan_cur = 0;
+	do {
+		ret = send_scan_req(wvif, &hw_req->req, chan_cur);
+		if (ret > 0)
+			chan_cur += ret;
+	} while (ret > 0 && chan_cur < hw_req->req.n_channels);
+	mutex_unlock(&wvif->scan_lock);
+	mutex_unlock(&wvif->wdev->conf_mutex);
+	__ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0);
+}
+
+int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		struct ieee80211_scan_request *hw_req)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS);
+	wvif->scan_req = hw_req;
+	schedule_work(&wvif->scan_work);
+	return 0;
+}
+
+void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	wvif->scan_abort = true;
+	hif_stop_scan(wvif);
+}
+
+void wfx_scan_complete(struct wfx_vif *wvif)
+{
+	complete(&wvif->scan_complete);
+}
diff --git a/drivers/net/wireless/silabs/wfx/scan.h b/drivers/net/wireless/silabs/wfx/scan.h
new file mode 100644
index 000000000000..c7496a766478
--- /dev/null
+++ b/drivers/net/wireless/silabs/wfx/scan.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Scan related functions.
+ *
+ * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#ifndef WFX_SCAN_H
+#define WFX_SCAN_H
+
+#include <net/mac80211.h>
+
+struct wfx_dev;
+struct wfx_vif;
+
+void wfx_hw_scan_work(struct work_struct *work);
+int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		struct ieee80211_scan_request *req);
+void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void wfx_scan_complete(struct wfx_vif *wvif);
+
+#endif /* WFX_SCAN_H */
-- 
2.28.0


WARNING: multiple messages have this Message-ID (diff)
From: Jerome Pouiller <Jerome.Pouiller@silabs.com>
To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org
Cc: devel@driverdev.osuosl.org, devicetree@vger.kernel.org,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-kernel@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	"David S . Miller" <davem@davemloft.net>,
	Kalle Valo <kvalo@codeaurora.org>
Subject: [PATCH 19/23] wfx: add scan.c/scan.h
Date: Mon, 12 Oct 2020 12:46:44 +0200	[thread overview]
Message-ID: <20201012104648.985256-20-Jerome.Pouiller@silabs.com> (raw)
In-Reply-To: <20201012104648.985256-1-Jerome.Pouiller@silabs.com>

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/net/wireless/silabs/wfx/scan.c | 132 +++++++++++++++++++++++++
 drivers/net/wireless/silabs/wfx/scan.h |  22 +++++
 2 files changed, 154 insertions(+)
 create mode 100644 drivers/net/wireless/silabs/wfx/scan.c
 create mode 100644 drivers/net/wireless/silabs/wfx/scan.h

diff --git a/drivers/net/wireless/silabs/wfx/scan.c b/drivers/net/wireless/silabs/wfx/scan.c
new file mode 100644
index 000000000000..fb47c7cddf2f
--- /dev/null
+++ b/drivers/net/wireless/silabs/wfx/scan.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Scan related functions.
+ *
+ * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#include <net/mac80211.h>
+
+#include "scan.h"
+#include "wfx.h"
+#include "sta.h"
+#include "hif_tx_mib.h"
+
+static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw,
+					      bool aborted)
+{
+	struct cfg80211_scan_info info = {
+		.aborted = aborted,
+	};
+
+	ieee80211_scan_completed(hw, &info);
+}
+
+static int update_probe_tmpl(struct wfx_vif *wvif,
+			     struct cfg80211_scan_request *req)
+{
+	struct sk_buff *skb;
+
+	skb = ieee80211_probereq_get(wvif->wdev->hw, wvif->vif->addr,
+				     NULL, 0, req->ie_len);
+	if (!skb)
+		return -ENOMEM;
+
+	skb_put_data(skb, req->ie, req->ie_len);
+	hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBREQ, 0);
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static int send_scan_req(struct wfx_vif *wvif,
+			 struct cfg80211_scan_request *req, int start_idx)
+{
+	int i, ret, timeout;
+	struct ieee80211_channel *ch_start, *ch_cur;
+
+	for (i = start_idx; i < req->n_channels; i++) {
+		ch_start = req->channels[start_idx];
+		ch_cur = req->channels[i];
+		WARN(ch_cur->band != NL80211_BAND_2GHZ, "band not supported");
+		if (ch_cur->max_power != ch_start->max_power)
+			break;
+		if ((ch_cur->flags ^ ch_start->flags) & IEEE80211_CHAN_NO_IR)
+			break;
+	}
+	wfx_tx_lock_flush(wvif->wdev);
+	wvif->scan_abort = false;
+	reinit_completion(&wvif->scan_complete);
+	ret = hif_scan(wvif, req, start_idx, i - start_idx, &timeout);
+	if (ret) {
+		wfx_tx_unlock(wvif->wdev);
+		return -EIO;
+	}
+	ret = wait_for_completion_timeout(&wvif->scan_complete, timeout);
+	if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower)
+		hif_set_output_power(wvif, wvif->vif->bss_conf.txpower);
+	wfx_tx_unlock(wvif->wdev);
+	if (!ret) {
+		dev_notice(wvif->wdev->dev, "scan timeout\n");
+		hif_stop_scan(wvif);
+		return -ETIMEDOUT;
+	}
+	if (wvif->scan_abort) {
+		dev_notice(wvif->wdev->dev, "scan abort\n");
+		return -ECONNABORTED;
+	}
+	return i - start_idx;
+}
+
+/*
+ * It is not really necessary to run scan request asynchronously. However,
+ * there is a bug in "iw scan" when ieee80211_scan_completed() is called before
+ * wfx_hw_scan() return
+ */
+void wfx_hw_scan_work(struct work_struct *work)
+{
+	struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan_work);
+	struct ieee80211_scan_request *hw_req = wvif->scan_req;
+	int chan_cur, ret;
+
+	mutex_lock(&wvif->wdev->conf_mutex);
+	mutex_lock(&wvif->scan_lock);
+	if (wvif->join_in_progress) {
+		dev_info(wvif->wdev->dev, "%s: abort in-progress REQ_JOIN",
+			 __func__);
+		wfx_reset(wvif);
+	}
+	update_probe_tmpl(wvif, &hw_req->req);
+	chan_cur = 0;
+	do {
+		ret = send_scan_req(wvif, &hw_req->req, chan_cur);
+		if (ret > 0)
+			chan_cur += ret;
+	} while (ret > 0 && chan_cur < hw_req->req.n_channels);
+	mutex_unlock(&wvif->scan_lock);
+	mutex_unlock(&wvif->wdev->conf_mutex);
+	__ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0);
+}
+
+int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		struct ieee80211_scan_request *hw_req)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS);
+	wvif->scan_req = hw_req;
+	schedule_work(&wvif->scan_work);
+	return 0;
+}
+
+void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+	struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
+
+	wvif->scan_abort = true;
+	hif_stop_scan(wvif);
+}
+
+void wfx_scan_complete(struct wfx_vif *wvif)
+{
+	complete(&wvif->scan_complete);
+}
diff --git a/drivers/net/wireless/silabs/wfx/scan.h b/drivers/net/wireless/silabs/wfx/scan.h
new file mode 100644
index 000000000000..c7496a766478
--- /dev/null
+++ b/drivers/net/wireless/silabs/wfx/scan.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Scan related functions.
+ *
+ * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#ifndef WFX_SCAN_H
+#define WFX_SCAN_H
+
+#include <net/mac80211.h>
+
+struct wfx_dev;
+struct wfx_vif;
+
+void wfx_hw_scan_work(struct work_struct *work);
+int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		struct ieee80211_scan_request *req);
+void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+void wfx_scan_complete(struct wfx_vif *wvif);
+
+#endif /* WFX_SCAN_H */
-- 
2.28.0

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

  parent reply	other threads:[~2020-10-12 10:50 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-12 10:46 [PATCH 00/23] wfx: get out from the staging area Jerome Pouiller
2020-10-12 10:46 ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 01/23] dt-bindings: introduce silabs,wfx.yaml Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-13 16:49   ` Rob Herring
2020-10-13 16:49     ` Rob Herring
2020-10-14 13:49     ` Jérôme Pouiller
2020-10-14 13:49       ` Jérôme Pouiller
2020-11-02 15:58       ` Kalle Valo
2020-11-02 15:58         ` Kalle Valo
2020-10-12 10:46 ` [PATCH 02/23] wfx: add Makefile/Kconfig Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 03/23] wfx: add wfx.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 04/23] wfx: add main.c/main.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 05/23] wfx: add bus.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 06/23] wfx: add bus_spi.c Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 07/23] wfx: add bus_sdio.c Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-13 20:11   ` Pali Rohár
2020-10-13 20:11     ` Pali Rohár
2020-10-14 11:52     ` Jérôme Pouiller
2020-10-14 11:52       ` Jérôme Pouiller
2020-10-14 12:43       ` Pali Rohár
2020-10-14 12:43         ` Pali Rohár
2020-10-15 14:03         ` Jérôme Pouiller
2020-10-15 14:03           ` Jérôme Pouiller
2020-10-16 11:54           ` Ulf Hansson
2020-10-16 11:54             ` Ulf Hansson
2020-11-02 16:02             ` Kalle Valo
2020-11-02 16:02               ` Kalle Valo
2020-10-16 11:30   ` Ulf Hansson
2020-10-16 11:30     ` Ulf Hansson
2020-10-16 12:16     ` Jérôme Pouiller
2020-10-16 12:16       ` Jérôme Pouiller
2020-10-12 10:46 ` [PATCH 08/23] wfx: add hwio.c/hwio.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 09/23] wfx: add fwio.c/fwio.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 10/23] wfx: add bh.c/bh.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 11/23] wfx: add hif_api_*.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 12/23] wfx: add hif_tx*.c/hif_tx*.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 13/23] wfx: add key.c/key.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 14/23] wfx: add hif_rx.c/hif_rx.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 15/23] wfx: add data_rx.c/data_rx.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 16/23] wfx: add queue.c/queue.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 17/23] wfx: add data_tx.c/data_tx.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 18/23] wfx: add sta.c/sta.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` Jerome Pouiller [this message]
2020-10-12 10:46   ` [PATCH 19/23] wfx: add scan.c/scan.h Jerome Pouiller
2020-10-12 10:46 ` [PATCH 20/23] wfx: add debug.c/debug.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 21/23] wfx: add traces.h Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 22/23] wfx: remove from the staging area Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller
2020-10-12 10:46 ` [PATCH 23/23] wfx: get out " Jerome Pouiller
2020-10-12 10:46   ` Jerome Pouiller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201012104648.985256-20-Jerome.Pouiller@silabs.com \
    --to=jerome.pouiller@silabs.com \
    --cc=davem@davemloft.net \
    --cc=devel@driverdev.osuosl.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=kvalo@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.