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
next prev 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: linkBe 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.