Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH 1/5] nl80211: allow reporting RTT information in scan results
From: Dan Williams @ 2016-11-17 16:15 UTC (permalink / raw)
  To: Arend van Spriel, Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1479382792-13131-2-git-send-email-arend.vanspriel@broadcom.com>

On Thu, 2016-11-17 at 11:39 +0000, Arend van Spriel wrote:
> Add distance and its variance to the BSS structure so drivers
> may provide RTT information for BSS instances found during
> scanning.
> 
> Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
> Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.co
> m>
> Reviewed-by: Franky Lin <franky.lin@broadcom.com>
> Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> ---
>  include/net/cfg80211.h       | 11 +++++++++++
>  include/uapi/linux/nl80211.h |  6 ++++++
>  net/wireless/nl80211.c       |  8 ++++++++
>  net/wireless/scan.c          |  2 ++
>  4 files changed, 27 insertions(+)
> 
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 2019310..d1217da 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -1675,6 +1675,9 @@ enum cfg80211_signal_type {
>   * @scan_width: scan width that was used
>   * @signal: signal strength value, according to the wiphy's
>   *	signal type
> + * @distance: distance to AP with %parent_bssid in centimeters. Zero
> + *	value indicates this is undetermined.
> + * @var_distance: variance of %distance indicating accurracy.

"accuracy" without the second 'r'.

Also, what unit is the variance in?  Needs more documentation.

Dan

>   * @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was
>   *	received; should match the time when the frame was
> actually
>   *	received by the device (not just by the host, in case it
> was
> @@ -1691,6 +1694,8 @@ struct cfg80211_inform_bss {
>  	struct ieee80211_channel *chan;
>  	enum nl80211_bss_scan_width scan_width;
>  	s32 signal;
> +	u32 distance;
> +	u32 var_distance;
>  	u64 boottime_ns;
>  	u64 parent_tsf;
>  	u8 parent_bssid[ETH_ALEN] __aligned(2);
> @@ -1737,6 +1742,9 @@ struct cfg80211_bss_ies {
>   *	that holds the beacon data. @beacon_ies is still valid, of
> course, and
>   *	points to the same data as hidden_beacon_bss->beacon_ies
> in that case.
>   * @signal: signal strength value (type depends on the wiphy's
> signal_type)
> + * @distance: distance to AP with %parent_bssid in centimeters. Zero
> + *	value indicates this is undetermined.
> + * @var_distance: variance of %distance indicating accurracy.
>   * @priv: private area for driver use, has at least wiphy-
> >bss_priv_size bytes
>   */
>  struct cfg80211_bss {
> @@ -1756,6 +1764,9 @@ struct cfg80211_bss {
>  
>  	u8 bssid[ETH_ALEN];
>  
> +	u32 distance;
> +	u32 var_distance;
> +
>  	u8 priv[0] __aligned(sizeof(void *));
>  };
>  
> diff --git a/include/uapi/linux/nl80211.h
> b/include/uapi/linux/nl80211.h
> index 259c9c7..7e935f6 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -3651,6 +3651,10 @@ enum nl80211_bss_scan_width {
>   *	@NL80211_BSS_PARENT_BSSID. (u64).
>   * @NL80211_BSS_PARENT_BSSID: the BSS according to which
> @NL80211_BSS_PARENT_TSF
>   *	is set.
> + * @NL80211_BSS_DISTANCE: distance to AP with
> @NL80211_BSS_PARENT_BSSID in
> + *	centimeters (u32).
> + * @NL80211_BSS_VARIANCE_DISTANCE: variance of @NL80211_BSS_DISTANCE
> value (u32).
> + *
>   * @__NL80211_BSS_AFTER_LAST: internal
>   * @NL80211_BSS_MAX: highest BSS attribute
>   */
> @@ -3674,6 +3678,8 @@ enum nl80211_bss {
>  	NL80211_BSS_PAD,
>  	NL80211_BSS_PARENT_TSF,
>  	NL80211_BSS_PARENT_BSSID,
> +	NL80211_BSS_DISTANCE,
> +	NL80211_BSS_VARIANCE_DISTANCE,
>  
>  	/* keep last */
>  	__NL80211_BSS_AFTER_LAST,
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 24ab199..ffce566 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -7515,6 +7515,14 @@ static int nl80211_send_bss(struct sk_buff
> *msg, struct netlink_callback *cb,
>  			      intbss->ts_boottime, NL80211_BSS_PAD))
>  		goto nla_put_failure;
>  
> +	if (res->distance && nla_put_u32(msg, NL80211_BSS_DISTANCE,
> +					 res->distance))
> +		goto nla_put_failure;
> +
> +	if (res->var_distance && nla_put_u32(msg,
> NL80211_BSS_VARIANCE_DISTANCE,
> +					     res->var_distance))
> +		goto nla_put_failure;
> +
>  	switch (rdev->wiphy.signal_type) {
>  	case CFG80211_SIGNAL_TYPE_MBM:
>  		if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res-
> >signal))
> diff --git a/net/wireless/scan.c b/net/wireless/scan.c
> index b5bd58d..afda1f9 100644
> --- a/net/wireless/scan.c
> +++ b/net/wireless/scan.c
> @@ -973,6 +973,8 @@ struct cfg80211_bss *
>  	tmp.pub.signal = data->signal;
>  	tmp.pub.beacon_interval = beacon_interval;
>  	tmp.pub.capability = capability;
> +	tmp.pub.distance = data->distance;
> +	tmp.pub.var_distance = data->var_distance;
>  	tmp.ts_boottime = data->boottime_ns;
>  
>  	/*

^ permalink raw reply

* [PATCH V2] cfg80211: get rid of name indirection trick for ieee80211_get_channel()
From: Arend van Spriel @ 2016-11-17 12:48 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel

The comment on the name indirection suggested an issue but turned out
to be untrue. Digging in older kernel version showed issue with ipw2x00
but that is no longer true so get rid on the name indirection.

Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c        |  3 +--
 drivers/net/wireless/marvell/mwifiex/cfg80211.c |  2 +-
 include/net/cfg80211.h                          | 17 +++--------------
 net/wireless/util.c                             |  5 ++---
 4 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 0b4c156..01f3803 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2329,8 +2329,7 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 		u32 phymode = __le32_to_cpu(resp->chan_change.phymode);
 		u32 freq = __le32_to_cpu(resp->chan_change.freq);
 
-		ar->tgt_oper_chan =
-			__ieee80211_get_channel(ar->hw->wiphy, freq);
+		ar->tgt_oper_chan = ieee80211_get_channel(ar->hw->wiphy, freq);
 		ath10k_dbg(ar, ATH10K_DBG_HTT,
 			   "htt chan change freq %u phymode %s\n",
 			   freq, ath10k_wmi_phymode_str(phymode));
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 39ce76a..9efc3d9 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2072,7 +2072,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
 	ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
 
 	band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
-	chan = __ieee80211_get_channel(priv->wdev.wiphy,
+	chan = ieee80211_get_channel(priv->wdev.wiphy,
 			ieee80211_channel_to_frequency(bss_info.bss_chan,
 						       band));
 
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 2019310..ef42749 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3955,26 +3955,15 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
  */
 int ieee80211_frequency_to_channel(int freq);
 
-/*
- * Name indirection necessary because the ieee80211 code also has
- * a function named "ieee80211_get_channel", so if you include
- * cfg80211's header file you get cfg80211's version, if you try
- * to include both header files you'll (rightfully!) get a symbol
- * clash.
- */
-struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
-						  int freq);
 /**
  * ieee80211_get_channel - get channel struct from wiphy for specified frequency
+ *
  * @wiphy: the struct wiphy to get the channel for
  * @freq: the center frequency of the channel
+ *
  * Return: The channel struct from @wiphy at @freq.
  */
-static inline struct ieee80211_channel *
-ieee80211_get_channel(struct wiphy *wiphy, int freq)
-{
-	return __ieee80211_get_channel(wiphy, freq);
-}
+struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq);
 
 /**
  * ieee80211_get_response_rate - get basic rate for a given rate
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 88725f8..f717694 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -114,8 +114,7 @@ int ieee80211_frequency_to_channel(int freq)
 }
 EXPORT_SYMBOL(ieee80211_frequency_to_channel);
 
-struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
-						  int freq)
+struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq)
 {
 	enum nl80211_band band;
 	struct ieee80211_supported_band *sband;
@@ -135,7 +134,7 @@ struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
 
 	return NULL;
 }
-EXPORT_SYMBOL(__ieee80211_get_channel);
+EXPORT_SYMBOL(ieee80211_get_channel);
 
 static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
 				     enum nl80211_band band)
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH 3/5] nl80211: add support for gscan
From: kbuild test robot @ 2016-11-17 12:10 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: kbuild-all, Johannes Berg, linux-wireless, Arend van Spriel
In-Reply-To: <1479382792-13131-4-git-send-email-arend.vanspriel@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 2031 bytes --]

Hi Arend,

[auto build test ERROR on mac80211-next/master]
[also build test ERROR on next-20161117]
[cannot apply to v4.9-rc5]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Arend-van-Spriel/nl80211-add-support-for-g-scan/20161117-194818
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master
config: i386-randconfig-x004-201646 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

Note: the linux-review/Arend-van-Spriel/nl80211-add-support-for-g-scan/20161117-194818 HEAD 407f604bb543a049c99ae0f9974943f1c64ea880 builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   net/wireless/scan.c: In function '__cfg80211_stop_gscan':
>> net/wireless/scan.c:358:2: error: implicit declaration of function 'nl80211_send_scan_event' [-Werror=implicit-function-declaration]
     nl80211_send_scan_event(rdev, dev, NL80211_CMD_GSCAN_STOPPED);
     ^~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors
--
   net/wireless/nl80211.c: In function 'nl80211_start_gscan':
>> net/wireless/nl80211.c:12167:2: error: implicit declaration of function 'nl80211_send_scan_event' [-Werror=implicit-function-declaration]
     nl80211_send_scan_event(rdev, dev,
     ^~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/nl80211_send_scan_event +358 net/wireless/scan.c

   352		if (!driver_initiated) {
   353			int err = rdev_stop_gscan(rdev, dev);
   354			if (err)
   355				return err;
   356		}
   357	
 > 358		nl80211_send_scan_event(rdev, dev, NL80211_CMD_GSCAN_STOPPED);
   359	
   360		RCU_INIT_POINTER(rdev->gscan_req, NULL);
   361		kfree_rcu(gscan_req, rcu_head);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 24258 bytes --]

^ permalink raw reply

* Re: [v7] mwifiex: parse device tree node for PCIe
From: Brian Norris @ 2016-11-17 17:38 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Amitkumar Karwar, linux-wireless, Cathy Luo, Nishant Sarmukadam,
	rajatja, dmitry.torokhov, Xinming Hu
In-Reply-To: <20161117123920.E159F6162A@smtp.codeaurora.org>

On Thu, Nov 17, 2016 at 12:39:20PM +0000, Kalle Valo wrote:
> Amitkumar Karwar <akarwar@marvell.com> wrote:
> > From: Xinming Hu <huxm@marvell.com>
> > 
> > This patch derives device tree node from pcie bus layer framework.
> > Device tree bindings file has been renamed(marvell-sd8xxx.txt ->
> > marvell-8xxx.txt) to accommodate PCIe changes.
> > 
> > Signed-off-by: Xinming Hu <huxm@marvell.com>
> > Signed-off-by: Rajat Jain <rajatja@google.com>
> > Reviewed-by: Brian Norris <briannorris@chromium.org>
> > Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> 
> You should CC the device tree list when making changes to the bindings.

FWIW, Rajat had that right on v6...

> Patch set to Changes Requested.

Brian

^ permalink raw reply

* Re: [net-next] rtl8xxxu: Fix non static symbol warning
From: Kalle Valo @ 2016-11-17 12:53 UTC (permalink / raw)
  To: Wei Yongjun; +Cc: Jes Sorensen, Wei Yongjun, linux-wireless
In-Reply-To: <1478011688-26698-1-git-send-email-weiyj.lk@gmail.com>

Wei Yongjun <weiyj.lk@gmail.com> wrote:
> From: Wei Yongjun <weiyongjun1@huawei.com>
> 
> Fixes the following sparse warning:
> 
> drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c:1559:6: warning:
>  symbol 'rtl8192eu_power_off' was not declared. Should it be static?
> 
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>

Jes will take this.

-- 
https://patchwork.kernel.org/patch/9407491/

Documentation about submitting wireless patches and checking status
from patchwork:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply

* Re: [net-next] rtl8xxxu: Fix non static symbol warning
From: Jes Sorensen @ 2016-11-17 13:03 UTC (permalink / raw)
  To: Kalle Valo; +Cc: Wei Yongjun, Wei Yongjun, linux-wireless
In-Reply-To: <20161117125314.0968961635@smtp.codeaurora.org>

Kalle Valo <kvalo@codeaurora.org> writes:
> Wei Yongjun <weiyj.lk@gmail.com> wrote:
>> From: Wei Yongjun <weiyongjun1@huawei.com>
>> 
>> Fixes the following sparse warning:
>> 
>> drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c:1559:6: warning:
>>  symbol 'rtl8192eu_power_off' was not declared. Should it be static?
>> 
>> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
>
> Jes will take this.

Thanks Kalle - yes it's on my list, Wei your patch has not been
forgotten.

Cheers,
Jes

^ permalink raw reply

* Re: [PATCH 5/5] nl80211: add driver api for gscan notifications
From: Arend Van Spriel @ 2016-11-17 12:11 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1479382792-13131-6-git-send-email-arend.vanspriel@broadcom.com>

On 17-11-2016 12:39, Arend van Spriel wrote:
> The driver can indicate gscan results are available or gscan operation
> has stopped.
> 
> Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
> Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
> Reviewed-by: Franky Lin <franky.lin@broadcom.com>
> Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
> ---
>  include/net/cfg80211.h       | 28 ++++++++++++++++++++
>  include/uapi/linux/nl80211.h |  2 ++
>  net/wireless/core.c          |  2 ++
>  net/wireless/core.h          |  2 ++
>  net/wireless/nl80211.c       | 19 ++++++++++++++
>  net/wireless/nl80211.h       |  2 ++
>  net/wireless/scan.c          | 61 ++++++++++++++++++++++++++++++++++++++++++++
>  net/wireless/trace.h         | 10 ++++++++
>  8 files changed, 126 insertions(+)
> 
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index b4b0536..d85a439 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -4570,6 +4570,34 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request,
>  void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy);
>  
>  /**
> + * cfg80211_gscan_results - notify that new scan results are available
> + *
> + * @wiphy: the wiphy which got GScan results
> + */
> +void cfg80211_gscan_results(struct wiphy *wiphy);
> +
> +/**
> + * cfg80211_gscan_stopped - notify that the GScan has stopped
> + *
> + * @wiphy: the wiphy on which the GScan stopped.
> + *
> + * The driver can call this function to inform cfg80211 that the
> + * GScan had to be stopped, for whatever reason.
> + */
> +void cfg80211_gscan_stopped(struct wiphy *wiphy);
> +
> +/**
> + * cfg80211_gscan_stopped_rtnl - notify that the GScan has stopped
> + *
> + * @wiphy: the wiphy on which the GScan stopped.
> + *
> + * The driver can call this function to inform cfg80211 that the
> + * GScan had to be stopped, for whatever reason.
> + * This function should be called with rtnl locked.
> + */
> +void cfg80211_gscan_stopped_rtnl(struct wiphy *wiphy);
> +
> +/**
>   * cfg80211_inform_bss_frame_data - inform cfg80211 of a received BSS frame
>   * @wiphy: the wiphy reporting the BSS
>   * @data: the BSS metadata
> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index 8071dae..c4c9005 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -896,6 +896,7 @@
>   *
>   * @NL80211_CMD_START_GSCAN: start GScan.
>   * @NL80211_CMD_STOP_GSCAN: request to stop current GScan.
> + * @NL80211_CMD_GSCAN_RESULTS: indicates that there GScan results available.
>   * @NL80211_CMD_GSCAN_STOPPED: indicates that the currently running GScan
>   *	has stopped. This event is generated upon @NL80211_CMD_STOP_GSCAN and
>   *	the driver may issue this event at any time when a GScan is running.
> @@ -1101,6 +1102,7 @@ enum nl80211_commands {
>  
>  	NL80211_CMD_START_GSCAN,
>  	NL80211_CMD_STOP_GSCAN,
> +	NL80211_CMD_GSCAN_RESULTS,
>  	NL80211_CMD_GSCAN_STOPPED,
>  
>  	/* add new commands above here */
> diff --git a/net/wireless/core.c b/net/wireless/core.c
> index 760a2fb..69eea4c 100644
> --- a/net/wireless/core.c
> +++ b/net/wireless/core.c
> @@ -453,6 +453,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
>  	INIT_LIST_HEAD(&rdev->bss_list);
>  	INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
>  	INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
> +	INIT_WORK(&rdev->gscan_results_wk, __cfg80211_gscan_results);
>  	INIT_LIST_HEAD(&rdev->mlme_unreg);
>  	spin_lock_init(&rdev->mlme_unreg_lock);
>  	INIT_WORK(&rdev->mlme_unreg_wk, cfg80211_mlme_unreg_wk);
> @@ -935,6 +936,7 @@ void wiphy_unregister(struct wiphy *wiphy)
>  	cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
>  	flush_work(&rdev->destroy_work);
>  	flush_work(&rdev->sched_scan_stop_wk);
> +	flush_work(&rdev->gscan_stop_wk);
>  	flush_work(&rdev->mlme_unreg_wk);
>  
>  #ifdef CONFIG_PM
> diff --git a/net/wireless/core.h b/net/wireless/core.h
> index b0f2519..1d56ef4 100644
> --- a/net/wireless/core.h
> +++ b/net/wireless/core.h
> @@ -78,6 +78,7 @@ struct cfg80211_registered_device {
>  	unsigned long suspend_at;
>  	struct work_struct scan_done_wk;
>  	struct work_struct sched_scan_results_wk;
> +	struct work_struct gscan_results_wk;
>  
>  	struct genl_info *cur_cmd_info;
>  
> @@ -423,6 +424,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
>  void __cfg80211_sched_scan_results(struct work_struct *wk);
>  int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
>  			       bool driver_initiated);
> +void __cfg80211_gscan_results(struct work_struct *wk);
>  int __cfg80211_stop_gscan(struct cfg80211_registered_device *rdev,
>  			  bool driver_initiated);
>  void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 5b22310..f0099ee 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -13304,6 +13304,25 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
>  				NL80211_MCGRP_SCAN, GFP_KERNEL);
>  }
>  
> +void nl80211_send_gscan_results(struct cfg80211_registered_device *rdev,
> +				struct net_device *netdev)
> +{
> +	struct sk_buff *msg;
> +
> +	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> +	if (!msg)
> +		return;
> +
> +	if (nl80211_send_scan_event_msg(msg, rdev, netdev, 0, 0, 0,
> +					NL80211_CMD_GSCAN_RESULTS) < 0) {
> +		nlmsg_free(msg);
> +		return;
> +	}
> +
> +	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
> +				NL80211_MCGRP_SCAN, GFP_KERNEL);
> +}
> +
>  void nl80211_send_scan_event(struct cfg80211_registered_device *rdev,
>  			     struct net_device *netdev, u32 cmd)
>  {
> diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
> index fb304ce9..4eec856 100644
> --- a/net/wireless/nl80211.h
> +++ b/net/wireless/nl80211.h
> @@ -20,6 +20,8 @@ void nl80211_send_scan_event(struct cfg80211_registered_device *rdev,
>  			     struct net_device *netdev, u32 cmd);
>  void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
>  				     struct net_device *netdev);
> +void nl80211_send_gscan_results(struct cfg80211_registered_device *rdev,
> +				     struct net_device *netdev);
>  void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
>  				     struct regulatory_request *request);
>  
> diff --git a/net/wireless/scan.c b/net/wireless/scan.c
> index 327b23c..f34d5d4 100644
> --- a/net/wireless/scan.c
> +++ b/net/wireless/scan.c
> @@ -287,6 +287,47 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy)
>  }
>  EXPORT_SYMBOL(cfg80211_sched_scan_results);
>  
> +void __cfg80211_gscan_results(struct work_struct *wk)
> +{
> +	struct cfg80211_registered_device *rdev;
> +	struct cfg80211_gscan_request *request;
> +
> +	rdev = container_of(wk, struct cfg80211_registered_device,
> +			    gscan_results_wk);
> +
> +	rtnl_lock();
> +
> +	request = rtnl_dereference(rdev->gscan_req);
> +
> +	/* we don't have sched_scan_req anymore if the scan is stopping */
> +	if (request) {
> +#if 0
> +		/* TODO: how to deal with flush */
> +		if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
> +			/* flush entries from previous scans */
> +			spin_lock_bh(&rdev->bss_lock);
> +			__cfg80211_bss_expire(rdev, request->scan_start);
> +			spin_unlock_bh(&rdev->bss_lock);
> +			request->scan_start = jiffies;
> +		}
> +#endif

Yikes. Still subject to discussion, but need it is bss storage with last
results is sufficient.

> +		nl80211_send_gscan_results(rdev, request->dev);
> +	}
> +
> +	rtnl_unlock();
> +}

Regards,
Arend

^ permalink raw reply

* Re: [PATCH 1/2] cfg80211: get rid of name indirection trick for ieee80211_get_channel()
From: Arend Van Spriel @ 2016-11-17 12:38 UTC (permalink / raw)
  To: kbuild test robot; +Cc: kbuild-all, Johannes Berg, linux-wireless
In-Reply-To: <201611172039.TxaaQE2O%fengguang.wu@intel.com>

On 17-11-2016 13:32, kbuild test robot wrote:
> Hi Arend,
> 
> [auto build test ERROR on mac80211-next/master]
> [also build test ERROR on v4.9-rc5 next-20161117]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Arend-van-Spriel/cfg80211-get-rid-of-name-indirection-trick-for-ieee80211_get_channel/20161117-175449
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master
> config: x86_64-allmodconfig (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 

Ah. Two drivers that are not fooled by the indirection. Will create a V2.

Regards,
Arend

> All error/warnings (new ones prefixed by >>):
> 
>    drivers/net/wireless/ath/ath10k/htt_rx.c: In function 'ath10k_htt_t2h_msg_handler':
>>> drivers/net/wireless/ath/ath10k/htt_rx.c:2333:4: error: implicit declaration of function '__ieee80211_get_channel' [-Werror=implicit-function-declaration]
>        __ieee80211_get_channel(ar->hw->wiphy, freq);
>        ^~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/net/wireless/ath/ath10k/htt_rx.c:2332:21: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
>       ar->tgt_oper_chan =
>                         ^
>    cc1: some warnings being treated as errors
> 
> vim +/__ieee80211_get_channel +2333 drivers/net/wireless/ath/ath10k/htt_rx.c
> 
> c545070e Michal Kazior      2015-01-24  2326  	case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
> 8348db29 Rajkumar Manoharan 2015-03-25  2327  		break;
> 2ce9b25c Rajkumar Manoharan 2016-03-08  2328  	case HTT_T2H_MSG_TYPE_CHAN_CHANGE: {
> 2ce9b25c Rajkumar Manoharan 2016-03-08  2329  		u32 phymode = __le32_to_cpu(resp->chan_change.phymode);
> 2ce9b25c Rajkumar Manoharan 2016-03-08  2330  		u32 freq = __le32_to_cpu(resp->chan_change.freq);
> 2ce9b25c Rajkumar Manoharan 2016-03-08  2331  
> 2ce9b25c Rajkumar Manoharan 2016-03-08 @2332  		ar->tgt_oper_chan =
> 2ce9b25c Rajkumar Manoharan 2016-03-08 @2333  			__ieee80211_get_channel(ar->hw->wiphy, freq);
> 2ce9b25c Rajkumar Manoharan 2016-03-08  2334  		ath10k_dbg(ar, ATH10K_DBG_HTT,
> 2ce9b25c Rajkumar Manoharan 2016-03-08  2335  			   "htt chan change freq %u phymode %s\n",
> 2ce9b25c Rajkumar Manoharan 2016-03-08  2336  			   freq, ath10k_wmi_phymode_str(phymode));
> 
> :::::: The code at line 2333 was first introduced by commit
> :::::: 2ce9b25cefa64f11bcb21b21cf4a5e8c58c6d0af ath10k: handle channel change htt event
> 
> :::::: TO: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
> :::::: CC: Kalle Valo <kvalo@qca.qualcomm.com>
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> 

^ permalink raw reply

* [RFC V2 1/5] nl80211: allow reporting RTT information in scan results
From: Arend van Spriel @ 2016-11-17 13:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1479388726-3288-1-git-send-email-arend.vanspriel@broadcom.com>

Add distance and its variance to the BSS structure so drivers
may provide RTT information for BSS instances found during
scanning.

Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 include/net/cfg80211.h       | 11 +++++++++++
 include/uapi/linux/nl80211.h |  6 ++++++
 net/wireless/nl80211.c       |  8 ++++++++
 net/wireless/scan.c          |  2 ++
 4 files changed, 27 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 2019310..d1217da 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1675,6 +1675,9 @@ enum cfg80211_signal_type {
  * @scan_width: scan width that was used
  * @signal: signal strength value, according to the wiphy's
  *	signal type
+ * @distance: distance to AP with %parent_bssid in centimeters. Zero
+ *	value indicates this is undetermined.
+ * @var_distance: variance of %distance indicating accurracy.
  * @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was
  *	received; should match the time when the frame was actually
  *	received by the device (not just by the host, in case it was
@@ -1691,6 +1694,8 @@ struct cfg80211_inform_bss {
 	struct ieee80211_channel *chan;
 	enum nl80211_bss_scan_width scan_width;
 	s32 signal;
+	u32 distance;
+	u32 var_distance;
 	u64 boottime_ns;
 	u64 parent_tsf;
 	u8 parent_bssid[ETH_ALEN] __aligned(2);
@@ -1737,6 +1742,9 @@ struct cfg80211_bss_ies {
  *	that holds the beacon data. @beacon_ies is still valid, of course, and
  *	points to the same data as hidden_beacon_bss->beacon_ies in that case.
  * @signal: signal strength value (type depends on the wiphy's signal_type)
+ * @distance: distance to AP with %parent_bssid in centimeters. Zero
+ *	value indicates this is undetermined.
+ * @var_distance: variance of %distance indicating accurracy.
  * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
  */
 struct cfg80211_bss {
@@ -1756,6 +1764,9 @@ struct cfg80211_bss {
 
 	u8 bssid[ETH_ALEN];
 
+	u32 distance;
+	u32 var_distance;
+
 	u8 priv[0] __aligned(sizeof(void *));
 };
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 259c9c7..7e935f6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3651,6 +3651,10 @@ enum nl80211_bss_scan_width {
  *	@NL80211_BSS_PARENT_BSSID. (u64).
  * @NL80211_BSS_PARENT_BSSID: the BSS according to which @NL80211_BSS_PARENT_TSF
  *	is set.
+ * @NL80211_BSS_DISTANCE: distance to AP with @NL80211_BSS_PARENT_BSSID in
+ *	centimeters (u32).
+ * @NL80211_BSS_VARIANCE_DISTANCE: variance of @NL80211_BSS_DISTANCE value (u32).
+ *
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -3674,6 +3678,8 @@ enum nl80211_bss {
 	NL80211_BSS_PAD,
 	NL80211_BSS_PARENT_TSF,
 	NL80211_BSS_PARENT_BSSID,
+	NL80211_BSS_DISTANCE,
+	NL80211_BSS_VARIANCE_DISTANCE,
 
 	/* keep last */
 	__NL80211_BSS_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 24ab199..ffce566 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7515,6 +7515,14 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
 			      intbss->ts_boottime, NL80211_BSS_PAD))
 		goto nla_put_failure;
 
+	if (res->distance && nla_put_u32(msg, NL80211_BSS_DISTANCE,
+					 res->distance))
+		goto nla_put_failure;
+
+	if (res->var_distance && nla_put_u32(msg, NL80211_BSS_VARIANCE_DISTANCE,
+					     res->var_distance))
+		goto nla_put_failure;
+
 	switch (rdev->wiphy.signal_type) {
 	case CFG80211_SIGNAL_TYPE_MBM:
 		if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index b5bd58d..afda1f9 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -973,6 +973,8 @@ struct cfg80211_bss *
 	tmp.pub.signal = data->signal;
 	tmp.pub.beacon_interval = beacon_interval;
 	tmp.pub.capability = capability;
+	tmp.pub.distance = data->distance;
+	tmp.pub.var_distance = data->var_distance;
 	tmp.ts_boottime = data->boottime_ns;
 
 	/*
-- 
1.9.1

^ permalink raw reply related

* [RFC V2 2/5] nl80211: add reporting of gscan capabilities
From: Arend van Spriel @ 2016-11-17 13:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel, Arend van Spriel
In-Reply-To: <1479388726-3288-1-git-send-email-arend.vanspriel@broadcom.com>

From: Arend van Spriel <arend@broadcom.com>

GScan is a scan offload feature used in recent Android releases. This
patch adds possibility for wireless device drivers to report their
capabilities and provide it to user-space.

Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 include/net/cfg80211.h       | 36 +++++++++++++++++++++++++++
 include/uapi/linux/nl80211.h | 58 ++++++++++++++++++++++++++++++++++++++++++++
 net/wireless/nl80211.c       | 45 +++++++++++++++++++++++++++++++++-
 3 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d1217da..c77bb08 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3372,6 +3372,40 @@ struct wiphy_iftype_ext_capab {
 };
 
 /**
+ * struct wiphy_gscan_caps -  gscan capabilities of the device.
+ *
+ * @max_scan_cache_size: total space allocated for scan results (in bytes).
+ * @max_scan_buckets: maximum number of channel buckets.
+ * @max_ap_cache_per_scan: maximum number of APs that can be stored per scan.
+ * @max_rssi_sample_size: number of RSSI samples used for averaging RSSI.
+ * @max_scan_reporting_threshold: max possible report threshold. in percentage.
+ * @max_hotlist_bssids: maximum number of entries for hotlist BSSIDs.
+ * @max_hotlist_ssids: maximum number of entries for hotlist SSIDs.
+ * @max_significant_wifi_change_aps: maximum number of entries for significant
+ *	change APs.
+ * @max_bssid_history_entries: number of BSSID/RSSI entries that device can
+ *	hold.
+ * @max_epno_networks: max number of hashed epno entries.
+ * @max_epno_networks_by_ssid: max number of epno entries for which an
+ *	exact match of SSID is required or which are hidded SSIDs.
+ * @max_white_list_ssid: max number of white listed SSIDs.
+ */
+struct wiphy_gscan_caps {
+	u32 max_scan_cache_size;
+	u32 max_scan_buckets;
+	u32 max_ap_cache_per_scan;
+	u32 max_rssi_sample_size;
+	u32 max_scan_reporting_threshold;
+	u32 max_hotlist_bssids;
+	u32 max_hotlist_ssids;
+	u32 max_significant_wifi_change_aps;
+	u32 max_bssid_history_entries;
+	u32 max_epno_hashed_networks;
+	u32 max_epno_exact_networks;
+	u32 max_white_list_ssid;
+};
+
+/**
  * struct wiphy - wireless hardware description
  * @reg_notifier: the driver's regulatory notification callback,
  *	note that if your driver uses wiphy_apply_custom_regulatory()
@@ -3524,6 +3558,7 @@ struct wiphy_iftype_ext_capab {
  * @bss_select_support: bitmask indicating the BSS selection criteria supported
  *	by the driver in the .connect() callback. The bit position maps to the
  *	attribute indices defined in &enum nl80211_bss_select_attr.
+ * @gscan: structure holding the hardware capabilities for gscan.
  *
  * @cookie_counter: unique generic cookie counter, used to identify objects.
  */
@@ -3654,6 +3689,7 @@ struct wiphy {
 	u8 max_adj_channel_rssi_comp;
 
 	u32 bss_select_support;
+	const struct wiphy_gscan_caps *gscan;
 
 	u64 cookie_counter;
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 7e935f6..232a792 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1977,6 +1977,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED: Indicates whether or not multicast
  *	packets should be send out as unicast to all stations (flag attribute).
  *
+ * @NL80211_ATTR_GSCAN_CAPS: indicating capabilities of GScan functionality
+ *	of the device. This is a nested attribute.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2381,6 +2384,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED,
 
+	NL80211_ATTR_GSCAN_CAPS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -5188,4 +5193,57 @@ enum nl80211_nan_match_attributes {
 	NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
 };
 
+/**
+ * enum nl80211_gscan_caps_attr - GScan capabilities attributes.
+ *
+ * @__NL80211_GSCAN_CAPS_ATTR_INVALID: reserved.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_CACHE_SIZE: total space allocated for
+ *	scan results (in bytes).
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_BUCKETS: maximum number of channel buckets.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_AP_CACHE_PER_SCAN: maximum number of APs that
+ *	can be stored per scan.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_RSSI_SAMPLE_SIZE:  number of RSSI samples used
+ *	for averaging RSSI.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_REPORTING_THRESHOLD: max possible report
+ *	threshold. in percentage.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_HOTLIST_BSSID: maximum number of entries for
+ *	hotlist BSSIDs.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_HOTLIST_SSID: maximum number of entries for
+ *	hotlist SSIDs.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_SIGNIFICANT_WIFI_CHANGE_APS: maximum number of
+ *	entries for significant change APs.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_BSSID_HISTORY: number of BSSID/RSSI entries that
+ *	device can hold.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_EPNO_HASHED_NETWORKS: max number of hashed epno
+ *	entries.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_EPNO_EXACT_NETWORKS: max number of epno entries
+ *	for which an exact match of SSID is required or which are hidded SSIDs.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX_WHITE_LIST_SSID: max number of white listed
+ *	SSIDs.
+ * @NL80211_GSCAN_CAPS_ATTR_MAX: highest GScan capability attribute.
+ *
+ * @__NL80211_GSCAN_CAPS_ATTR_AFTER_LAST: internal use.
+ *
+ * All attributes are u32 type.
+ */
+enum nl80211_gscan_caps_attr {
+	__NL80211_GSCAN_CAPS_ATTR_INVALID,
+	NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_CACHE_SIZE,
+	NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_BUCKETS,
+	NL80211_GSCAN_CAPS_ATTR_MAX_AP_CACHE_PER_SCAN,
+	NL80211_GSCAN_CAPS_ATTR_MAX_RSSI_SAMPLE_SIZE,
+	NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_REPORTING_THRESHOLD,
+	NL80211_GSCAN_CAPS_ATTR_MAX_HOTLIST_BSSID,
+	NL80211_GSCAN_CAPS_ATTR_MAX_HOTLIST_SSID,
+	NL80211_GSCAN_CAPS_ATTR_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
+	NL80211_GSCAN_CAPS_ATTR_MAX_BSSID_HISTORY,
+	NL80211_GSCAN_CAPS_ATTR_MAX_EPNO_HASHED_NETWORKS,
+	NL80211_GSCAN_CAPS_ATTR_MAX_EPNO_EXACT_NETWORKS,
+	NL80211_GSCAN_CAPS_ATTR_MAX_WHITE_LIST_SSID,
+
+	/* keep last */
+	__NL80211_GSCAN_CAPS_ATTR_AFTER_LAST,
+	NL80211_GSCAN_CAPS_ATTR_MAX = __NL80211_GSCAN_CAPS_ATTR_AFTER_LAST - 1
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ffce566..4606fc9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1423,9 +1423,10 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
 	void *hdr;
 	struct nlattr *nl_bands, *nl_band;
 	struct nlattr *nl_freqs, *nl_freq;
-	struct nlattr *nl_cmds;
+	struct nlattr *nl_cmds, *nl_gscan;
 	enum nl80211_band band;
 	struct ieee80211_channel *chan;
+	const struct wiphy_gscan_caps *gscan;
 	int i;
 	const struct ieee80211_txrx_stypes *mgmt_stypes =
 				rdev->wiphy.mgmt_stypes;
@@ -1880,6 +1881,48 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
 			}
 		}
 
+		state->split_start++;
+		break;
+	case 14:
+		if (!rdev->wiphy.gscan) {
+			/* done */
+			state->split_start = 0;
+			break;
+		}
+		gscan = rdev->wiphy.gscan;
+		nl_gscan = nla_nest_start(msg, NL80211_ATTR_GSCAN_CAPS);
+		if (!nl_gscan ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_CACHE_SIZE,
+				gscan->max_scan_cache_size) ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_BUCKETS,
+				gscan->max_scan_buckets) ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_AP_CACHE_PER_SCAN,
+				gscan->max_ap_cache_per_scan) ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_RSSI_SAMPLE_SIZE,
+				gscan->max_rssi_sample_size) ||
+		    nla_put_u32(msg,
+				NL80211_GSCAN_CAPS_ATTR_MAX_SCAN_REPORTING_THRESHOLD,
+				gscan->max_scan_reporting_threshold) ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_HOTLIST_BSSID,
+				gscan->max_hotlist_bssids) ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_HOTLIST_SSID,
+				gscan->max_hotlist_ssids) ||
+		    nla_put_u32(msg,
+				NL80211_GSCAN_CAPS_ATTR_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
+				gscan->max_significant_wifi_change_aps) ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_BSSID_HISTORY,
+				gscan->max_bssid_history_entries) ||
+		    nla_put_u32(msg,
+				NL80211_GSCAN_CAPS_ATTR_MAX_EPNO_HASHED_NETWORKS,
+				gscan->max_epno_hashed_networks) ||
+		    nla_put_u32(msg,
+				NL80211_GSCAN_CAPS_ATTR_MAX_EPNO_EXACT_NETWORKS,
+				gscan->max_epno_exact_networks) ||
+		    nla_put_u32(msg, NL80211_GSCAN_CAPS_ATTR_MAX_WHITE_LIST_SSID,
+				gscan->max_white_list_ssid))
+			goto nla_put_failure;
+		nla_nest_end(msg, nl_gscan);
+
 		/* done */
 		state->split_start = 0;
 		break;
-- 
1.9.1

^ permalink raw reply related

* [RFC V2 3/5] nl80211: rename some notification functions
From: Arend van Spriel @ 2016-11-17 13:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1479388726-3288-1-git-send-email-arend.vanspriel@broadcom.com>

The functions nl80211_send_sched_scan() and nl80211_send_sched_scan_msg()
take command as parameter, which strictly speaking makes them general
purpose and not directly related to scheduled scan functionality. The
message are sent to "scan" multicast group so renaming them to
nl80211_send_scan_event{,_msg}().

Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
 net/wireless/nl80211.c | 10 +++++-----
 net/wireless/nl80211.h |  2 +-
 net/wireless/scan.c    |  4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4606fc9..073280d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7236,7 +7236,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
 
 	rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
 
-	nl80211_send_sched_scan(rdev, dev,
+	nl80211_send_scan_event(rdev, dev,
 				NL80211_CMD_START_SCHED_SCAN);
 	return 0;
 
@@ -12878,7 +12878,7 @@ static int nl80211_send_scan_msg(struct sk_buff *msg,
 }
 
 static int
-nl80211_send_sched_scan_msg(struct sk_buff *msg,
+nl80211_send_scan_event_msg(struct sk_buff *msg,
 			    struct cfg80211_registered_device *rdev,
 			    struct net_device *netdev,
 			    u32 portid, u32 seq, int flags, u32 cmd)
@@ -12958,7 +12958,7 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
 	if (!msg)
 		return;
 
-	if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
+	if (nl80211_send_scan_event_msg(msg, rdev, netdev, 0, 0, 0,
 					NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
 		nlmsg_free(msg);
 		return;
@@ -12968,7 +12968,7 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
 				NL80211_MCGRP_SCAN, GFP_KERNEL);
 }
 
-void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
+void nl80211_send_scan_event(struct cfg80211_registered_device *rdev,
 			     struct net_device *netdev, u32 cmd)
 {
 	struct sk_buff *msg;
@@ -12977,7 +12977,7 @@ void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
 	if (!msg)
 		return;
 
-	if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
+	if (nl80211_send_scan_event_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
 		nlmsg_free(msg);
 		return;
 	}
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 7e3821d..fb304ce9 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -16,7 +16,7 @@ struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
 				       struct wireless_dev *wdev, bool aborted);
 void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
 			      struct sk_buff *msg);
-void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
+void nl80211_send_scan_event(struct cfg80211_registered_device *rdev,
 			     struct net_device *netdev, u32 cmd);
 void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
 				     struct net_device *netdev);
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index afda1f9..dbdb53f 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -327,7 +327,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
 			return err;
 	}
 
-	nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
+	nl80211_send_scan_event(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
 
 	RCU_INIT_POINTER(rdev->sched_scan_req, NULL);
 	kfree_rcu(sched_scan_req, rcu_head);
@@ -1080,7 +1080,7 @@ struct cfg80211_bss *
 	else
 		rcu_assign_pointer(tmp.pub.beacon_ies, ies);
 	rcu_assign_pointer(tmp.pub.ies, ies);
-	
+
 	memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
 	tmp.pub.channel = channel;
 	tmp.pub.scan_width = data->scan_width;
-- 
1.9.1

^ permalink raw reply related

* [RFC V2 5/5] nl80211: add driver api for gscan notifications
From: Arend van Spriel @ 2016-11-17 13:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1479388726-3288-1-git-send-email-arend.vanspriel@broadcom.com>

The driver can indicate gscan results are available or gscan operation
has stopped.

Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
V2:
 - removed #if 0 code block.
---
 include/net/cfg80211.h       | 28 +++++++++++++++++++++++++
 include/uapi/linux/nl80211.h |  2 ++
 net/wireless/core.c          |  2 ++
 net/wireless/core.h          |  2 ++
 net/wireless/nl80211.c       | 19 +++++++++++++++++
 net/wireless/nl80211.h       |  2 ++
 net/wireless/scan.c          | 50 ++++++++++++++++++++++++++++++++++++++++++++
 net/wireless/trace.h         | 10 +++++++++
 8 files changed, 115 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b4b0536..d85a439 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4570,6 +4570,34 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request,
 void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy);
 
 /**
+ * cfg80211_gscan_results - notify that new scan results are available
+ *
+ * @wiphy: the wiphy which got GScan results
+ */
+void cfg80211_gscan_results(struct wiphy *wiphy);
+
+/**
+ * cfg80211_gscan_stopped - notify that the GScan has stopped
+ *
+ * @wiphy: the wiphy on which the GScan stopped.
+ *
+ * The driver can call this function to inform cfg80211 that the
+ * GScan had to be stopped, for whatever reason.
+ */
+void cfg80211_gscan_stopped(struct wiphy *wiphy);
+
+/**
+ * cfg80211_gscan_stopped_rtnl - notify that the GScan has stopped
+ *
+ * @wiphy: the wiphy on which the GScan stopped.
+ *
+ * The driver can call this function to inform cfg80211 that the
+ * GScan had to be stopped, for whatever reason.
+ * This function should be called with rtnl locked.
+ */
+void cfg80211_gscan_stopped_rtnl(struct wiphy *wiphy);
+
+/**
  * cfg80211_inform_bss_frame_data - inform cfg80211 of a received BSS frame
  * @wiphy: the wiphy reporting the BSS
  * @data: the BSS metadata
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 8071dae..c4c9005 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -896,6 +896,7 @@
  *
  * @NL80211_CMD_START_GSCAN: start GScan.
  * @NL80211_CMD_STOP_GSCAN: request to stop current GScan.
+ * @NL80211_CMD_GSCAN_RESULTS: indicates that there GScan results available.
  * @NL80211_CMD_GSCAN_STOPPED: indicates that the currently running GScan
  *	has stopped. This event is generated upon @NL80211_CMD_STOP_GSCAN and
  *	the driver may issue this event at any time when a GScan is running.
@@ -1101,6 +1102,7 @@ enum nl80211_commands {
 
 	NL80211_CMD_START_GSCAN,
 	NL80211_CMD_STOP_GSCAN,
+	NL80211_CMD_GSCAN_RESULTS,
 	NL80211_CMD_GSCAN_STOPPED,
 
 	/* add new commands above here */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 760a2fb..69eea4c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -453,6 +453,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
 	INIT_LIST_HEAD(&rdev->bss_list);
 	INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
 	INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
+	INIT_WORK(&rdev->gscan_results_wk, __cfg80211_gscan_results);
 	INIT_LIST_HEAD(&rdev->mlme_unreg);
 	spin_lock_init(&rdev->mlme_unreg_lock);
 	INIT_WORK(&rdev->mlme_unreg_wk, cfg80211_mlme_unreg_wk);
@@ -935,6 +936,7 @@ void wiphy_unregister(struct wiphy *wiphy)
 	cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
 	flush_work(&rdev->destroy_work);
 	flush_work(&rdev->sched_scan_stop_wk);
+	flush_work(&rdev->gscan_stop_wk);
 	flush_work(&rdev->mlme_unreg_wk);
 
 #ifdef CONFIG_PM
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b0f2519..1d56ef4 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -78,6 +78,7 @@ struct cfg80211_registered_device {
 	unsigned long suspend_at;
 	struct work_struct scan_done_wk;
 	struct work_struct sched_scan_results_wk;
+	struct work_struct gscan_results_wk;
 
 	struct genl_info *cur_cmd_info;
 
@@ -423,6 +424,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
 void __cfg80211_sched_scan_results(struct work_struct *wk);
 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
 			       bool driver_initiated);
+void __cfg80211_gscan_results(struct work_struct *wk);
 int __cfg80211_stop_gscan(struct cfg80211_registered_device *rdev,
 			  bool driver_initiated);
 void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7ec4bd5..3d7ef91 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -13297,6 +13297,25 @@ void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
 				NL80211_MCGRP_SCAN, GFP_KERNEL);
 }
 
+void nl80211_send_gscan_results(struct cfg80211_registered_device *rdev,
+				struct net_device *netdev)
+{
+	struct sk_buff *msg;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	if (nl80211_send_scan_event_msg(msg, rdev, netdev, 0, 0, 0,
+					NL80211_CMD_GSCAN_RESULTS) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+				NL80211_MCGRP_SCAN, GFP_KERNEL);
+}
+
 void nl80211_send_scan_event(struct cfg80211_registered_device *rdev,
 			     struct net_device *netdev, u32 cmd)
 {
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index fb304ce9..4eec856 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -20,6 +20,8 @@ void nl80211_send_scan_event(struct cfg80211_registered_device *rdev,
 			     struct net_device *netdev, u32 cmd);
 void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
 				     struct net_device *netdev);
+void nl80211_send_gscan_results(struct cfg80211_registered_device *rdev,
+				     struct net_device *netdev);
 void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
 				     struct regulatory_request *request);
 
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 327b23c..4695821 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -287,6 +287,36 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy)
 }
 EXPORT_SYMBOL(cfg80211_sched_scan_results);
 
+void __cfg80211_gscan_results(struct work_struct *wk)
+{
+	struct cfg80211_registered_device *rdev;
+	struct cfg80211_gscan_request *request;
+
+	rdev = container_of(wk, struct cfg80211_registered_device,
+			    gscan_results_wk);
+
+	rtnl_lock();
+
+	request = rtnl_dereference(rdev->gscan_req);
+
+	/* we don't have sched_scan_req anymore if the scan is stopping */
+	if (request)
+		nl80211_send_gscan_results(rdev, request->dev);
+
+	rtnl_unlock();
+}
+
+void cfg80211_gscan_results(struct wiphy *wiphy)
+{
+	trace_cfg80211_gscan_results(wiphy);
+	/* ignore if we're not scanning */
+
+	if (rcu_access_pointer(wiphy_to_rdev(wiphy)->gscan_req))
+		queue_work(cfg80211_wq,
+			   &wiphy_to_rdev(wiphy)->gscan_results_wk);
+}
+EXPORT_SYMBOL(cfg80211_gscan_results);
+
 void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy)
 {
 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
@@ -307,6 +337,26 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
 }
 EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
 
+void cfg80211_gscan_stopped_rtnl(struct wiphy *wiphy)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+
+	ASSERT_RTNL();
+
+	trace_cfg80211_gscan_stopped(wiphy);
+
+	__cfg80211_stop_gscan(rdev, true);
+}
+EXPORT_SYMBOL(cfg80211_gscan_stopped_rtnl);
+
+void cfg80211_gscan_stopped(struct wiphy *wiphy)
+{
+	rtnl_lock();
+	cfg80211_gscan_stopped_rtnl(wiphy);
+	rtnl_unlock();
+}
+EXPORT_SYMBOL(cfg80211_gscan_stopped);
+
 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
 			       bool driver_initiated)
 {
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 1d0fde9..f3f5d82 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2799,6 +2799,16 @@
 	TP_ARGS(wiphy)
 );
 
+DEFINE_EVENT(wiphy_only_evt, cfg80211_gscan_results,
+	TP_PROTO(struct wiphy *wiphy),
+	TP_ARGS(wiphy)
+);
+
+DEFINE_EVENT(wiphy_only_evt, cfg80211_gscan_stopped,
+	TP_PROTO(struct wiphy *wiphy),
+	TP_ARGS(wiphy)
+);
+
 TRACE_EVENT(cfg80211_get_bss,
 	TP_PROTO(struct wiphy *wiphy, struct ieee80211_channel *channel,
 		 const u8 *bssid, const u8 *ssid, size_t ssid_len,
-- 
1.9.1

^ permalink raw reply related

* [RFC 0/5] nl80211: add support for g-scan
From: Arend van Spriel @ 2016-11-17 13:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel

Android employs a Wifi-HAL layer in its wireless frame. It basically abstracts
dealing with netlink messages from the framework. For some features it employs
nl80211 vendor commands. The goal I set myself is to be able to have a generic
nl80211 Wifi-HAL implementation. One of the features currently requiring the
vendor commands is g-scan. We can only guess what the 'g' stands for ;-) This
series converts the vendor command api into common nl80211 api.

Before making an attempt to explain more about the g-scan functionality first
this. While I am still testing the driver implementation resulting in numerous
questions Dmitry send the email below to bring a related discussion to the
table..eh.. the linux-wireless list. This is probably a good thing as anyone
can dive in and share their thoughts.

On 16-11-2016 23:47, dimitrysh@google.com wrote:
> From 68a9d37a4c7e9dc7a90a6e922cdea52737a98d66 Mon Sep 17 00:00:00 2001
> From: Dmitry Shmidt <dimitrysh@google.com>
> Date: Wed, 16 Nov 2016 14:27:26 -0800
> Subject: [PATCH] RFC: Universal scan proposal
>
>   Currently we have sched scan with possibility of various
> intervals. We would like to extend it to support also
> different types of scan.

Extending would be an option, but replacing sched_scan by uscan does not
seem like a good idea although you are only redefining the driver api, but
it seems elaborate to map all user-space scans to the new uscan callback.

>   In case of powerful wlan CPU, all this functionality
> can be offloaded.
>   In general case FW processes additional scan requests
> and puts them into queue based on start time and interval.
> Once current request is fulfilled, FW adds it (if interval != 0)
> again to the queue with proper interval. If requests are
> overlapping, new request can be combined with either one before,
> or one after, assuming that requests are not mutually exclusive.
>   Combining requests is done by combining scan channels, ssids,
> bssids and types of scan result. Once combined request was fulfilled
> it will be reinserted as two (or three) different requests based on
> their type and interval.
>   Each request has attribute:
> Type: connectivity / location
> Report: none / batch / immediate

These probably need more explanation. The 'Type' attribute gives hint about
the high-level use-case, ie. (android) connectivity or location service. This
obviously should have a different behaviour in the driver/device so we need to
describe that behaviour.

>   Request may have priority and can be inserted into
> the head of the queue.
>   Types of scans:
> - Normal scan
> - Scheduled scan
> - Hotlist (BSSID scan)
> - Roaming
> - AutoJoin

Are these last two really scans? How should AutoJoin work dealing with the
connection state of wpa_supplicant and driver/device if establishing the
connection is entirely offloaded including eapol handshakes and key derivation.

Now getting back to this series, it adds basic support of g-scan (or GScan, or
gscan, or something completely different; suggestions are welcome). A basic
g-scan request consists of some common attributes and so-called buckets. Each
bucket represents a re-occurring scan request with a given interval and a set
of channels. The common attributes specify how much scans (m) should be stored
and how many BSS-es (n) should be kept per scan before an event is sent. The
other option is to specify a percentage at which an event is sent, where 100%
equals (m * n). It also specifies the base period, but we may drop that as it
is the gcd() of the individual buckets. A special case of bucket is the
exponential backoff bucket, which has a increasing interval.

Whether this type of scan offload is a good addition depends on the high-level
use-case(s). It would help this discussion greatly to know those use-case(s).
A current hurdle for me is that the device stores m scans so a BSS could end up
in the result of either of them. However, cfg80211 stores BSS-es uniquely with
latest scan information. Does user-space need results per scan or is flat BSS
storage fine.

Anyway, here is some more fuel to the discussion.

Regards,
Arend

Changes:
 V2
  - remove pr_err() statement from nl80211.c
  - get rid of #if 0 code.
  - reordered patches resolving compilation issue.

Arend van Spriel (5):
  nl80211: allow reporting RTT information in scan results
  nl80211: add reporting of gscan capabilities
  nl80211: rename some notification functions
  nl80211: add support for gscan
  nl80211: add driver api for gscan notifications

 include/net/cfg80211.h       | 166 +++++++++++++++-
 include/uapi/linux/nl80211.h | 212 +++++++++++++++++++++
 net/wireless/core.c          |  33 ++++
 net/wireless/core.h          |   6 +
 net/wireless/nl80211.c       | 440 +++++++++++++++++++++++++++++++++++++++++--
 net/wireless/nl80211.h       |   4 +-
 net/wireless/rdev-ops.h      |  25 +++
 net/wireless/scan.c          |  95 +++++++++-
 net/wireless/trace.h         |  19 ++
 9 files changed, 984 insertions(+), 16 deletions(-)

--
1.9.1

^ permalink raw reply

* [PATCH] rtlwifi: rtl8723be: Fix bug in ant_sel code from commit c18d8f509571
From: Larry Finger @ 2016-11-17 18:05 UTC (permalink / raw)
  To: kvalo; +Cc: devel, linux-wireless, Ping-Ke Shih, Larry Finger, Stable

From: Ping-Ke Shih <pkshih@realtek.com>

In commit c18d8f509571 ("rtlwifi: rtl8723be: Add antenna select module
parameter"), wifi was fixed for those laptops that have only a single
antenna but have an incorrectly coded EEPROM. This error causes the
driver to select the wrong antenna. In that commit, one necessary change
that affects Bluetooth operation was missed.

Fixes: c18d8f509571 ("rtlwifi: rtl8723be: Add antenna select module parameter")
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@vger.kernel.org>
---
 drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
index aba60c3..cb046ec 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
@@ -2664,9 +2664,12 @@ void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
 	}
 
 	/* override ant_num / ant_path */
-	if (mod_params->ant_sel)
+	if (mod_params->ant_sel) {
 		rtlpriv->btcoexist.btc_info.ant_num =
 			(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
+		rtlpriv->btcoexist.btc_info.single_ant_path =
+			(mod_params->ant_sel == 1 ? 0 : 1);
+	}
 }
 
 void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
-- 
2.10.0

^ permalink raw reply related

* [RFC V2 4/5] nl80211: add support for gscan
From: Arend van Spriel @ 2016-11-17 13:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1479388726-3288-1-git-send-email-arend.vanspriel@broadcom.com>

This patch adds support for GScan which is a scan offload feature
used in Android.

Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
---
V2:
 - removed pr_err() statements.
---
 include/net/cfg80211.h       |  91 ++++++++++-
 include/uapi/linux/nl80211.h | 146 ++++++++++++++++++
 net/wireless/core.c          |  31 ++++
 net/wireless/core.h          |   4 +
 net/wireless/nl80211.c       | 351 ++++++++++++++++++++++++++++++++++++++++++-
 net/wireless/rdev-ops.h      |  25 +++
 net/wireless/scan.c          |  28 ++++
 net/wireless/trace.h         |   9 ++
 8 files changed, 678 insertions(+), 7 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c77bb08..b4b0536 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2464,6 +2464,90 @@ struct cfg80211_nan_func {
 };
 
 /**
+ * struct cfg80211_gscan_channel - GScan channel parameters.
+ *
+
+ * @ch: specific channel.
+ * @dwell_time: hint for dwell time in milliseconds.
+ * @passive: indicates passive scan is requested.
+ */
+struct cfg80211_gscan_channel {
+    struct ieee80211_channel *ch;
+    int dwell_time;
+    bool passive;
+};
+
+/**
+ * struct cfg80211_gscan_bucket - GScan bucket parameters.
+ *
+ * @idx: unique bucket index.
+ * @band: bit flags for band(s) to use, see %enum nl80211_bucket_band.
+ * @period: period in which the bucket is scheduled to be scanned. If the
+ *	period is too small for driver it should not fail but report results
+ *	as fast as it can. For exponential backoff bucket this is the minimum
+ *	period.
+ * @report_events: This is a bit field according %enum nl80211_bucket_report_event.
+ * @max_period: used only for the exponential backoff bucket whose scan period will
+ *	grow exponentially to a maximum period of max_period.
+ * @exponent: used only for the exponential backoff bucket.
+ * @step_count: used only for the exponential backoff bucket.
+ * @n_channels: number of channels in @channels array.
+ * @channels: channels to scan which may include DFS channels.
+ */
+struct cfg80211_gscan_bucket {
+	int idx;
+	u32 band;
+	int period;
+	u8 report_events;
+	int max_period;
+	int exponent;
+	int step_count;
+	int n_channels;
+	struct cfg80211_gscan_channel *channels;
+};
+
+/**
+ * struct cfg80211_gscan_request - GScan request parameters.
+ *
+ * @flags: scan request flags according %enum nl80211_scan_flags.
+ * @base_period: base timer period in milliseconds.
+ * @max_ap_per_scan: number of APs to store in each scan entry in the BSSID/RSSI
+ *	history buffer (keep APS with highest RSSI).
+ * @report_threshold_percent: wake up system when scan buffer is filled to this
+ *	percentage.
+ * @report_threshold_num_scans: wake up system when this many scans are stored
+ *	in scan buffer.
+ * @mac: MAC address used for randomisation.
+ * @mac_mask: MAC address mask. bits that are 0 in the mask should be
+ *	randomised, bits that are 1 should be taken as is from @mac.
+ * @n_buckets: number of entries in @buckets array.
+ * @buckets: array of GScan buckets.
+ *
+ * @dev: net device for which GScan is requested.
+ * @rcu_head: RCU callback used to free the struct.
+ * @owner_nlportid: netlink port which initiated this request.
+ */
+struct cfg80211_gscan_request {
+	u32 flags;
+	int base_period;
+	int max_ap_per_scan;
+	u8 report_threshold_percent;
+	int report_threshold_num_scans;
+	u8 mac[ETH_ALEN];
+	u8 mac_mask[ETH_ALEN];
+
+	int n_buckets;
+
+	/* internal */
+	struct net_device *dev;
+	struct rcu_head rcu_head;
+	u32 owner_nlportid;
+
+	/* keep last */
+	struct cfg80211_gscan_bucket buckets[0];
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2773,8 +2857,9 @@ struct cfg80211_nan_func {
  * @nan_change_conf: changes NAN configuration. The changed parameters must
  *	be specified in @changes (using &enum cfg80211_nan_conf_changes);
  *	All other parameters must be ignored.
- *
  * @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
+ * @start_gscan: start the GSCAN scanning offload.
+ * @stop_gscan: stop the GSCAN scanning offload.
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3055,10 +3140,12 @@ struct cfg80211_ops {
 				   struct wireless_dev *wdev,
 				   struct cfg80211_nan_conf *conf,
 				   u32 changes);
-
 	int	(*set_multicast_to_unicast)(struct wiphy *wiphy,
 					    struct net_device *dev,
 					    const bool enabled);
+	int	(*start_gscan)(struct wiphy *wiphy, struct net_device *dev,
+			       struct cfg80211_gscan_request *gscan_req);
+	int	(*stop_gscan)(struct wiphy *wiphy, struct net_device *dev);
 };
 
 /*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 232a792..8071dae 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -894,6 +894,12 @@
  *	does not result in a change for the current association. Currently,
  *	only the %NL80211_ATTR_IE data is used and updated with this command.
  *
+ * @NL80211_CMD_START_GSCAN: start GScan.
+ * @NL80211_CMD_STOP_GSCAN: request to stop current GScan.
+ * @NL80211_CMD_GSCAN_STOPPED: indicates that the currently running GScan
+ *	has stopped. This event is generated upon @NL80211_CMD_STOP_GSCAN and
+ *	the driver may issue this event at any time when a GScan is running.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1093,6 +1099,10 @@ enum nl80211_commands {
 
 	NL80211_CMD_UPDATE_CONNECT_PARAMS,
 
+	NL80211_CMD_START_GSCAN,
+	NL80211_CMD_STOP_GSCAN,
+	NL80211_CMD_GSCAN_STOPPED,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -2385,6 +2395,7 @@ enum nl80211_attrs {
 	NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED,
 
 	NL80211_ATTR_GSCAN_CAPS,
+	NL80211_ATTR_GSCAN_PARAMS,
 
 	/* add attributes here, update the policy in nl80211.c */
 
@@ -4779,12 +4790,15 @@ enum nl80211_connect_failed_reason {
  *	locally administered 1, multicast 0) is assumed.
  *	This flag must not be requested when the feature isn't supported, check
  *	the nl80211 feature flags for the device.
+ * @NL80211_SCAN_FLAGS_IE_DATA: request the device to supply IE data in the
+ *	request.
  */
 enum nl80211_scan_flags {
 	NL80211_SCAN_FLAG_LOW_PRIORITY			= 1<<0,
 	NL80211_SCAN_FLAG_FLUSH				= 1<<1,
 	NL80211_SCAN_FLAG_AP				= 1<<2,
 	NL80211_SCAN_FLAG_RANDOM_ADDR			= 1<<3,
+	NL80211_SCAN_FLAG_IE_DATA			= 1<<4,
 };
 
 /**
@@ -5246,4 +5260,136 @@ enum nl80211_gscan_caps_attr {
 	NL80211_GSCAN_CAPS_ATTR_MAX = __NL80211_GSCAN_CAPS_ATTR_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_gscan_attr - common GScan parameters.
+ *
+ * @__NL80211_GSCAN_ATTR_INVALID: reserved.
+ * @NL80211_GSCAN_ATTR_BASE_PERIOD: base timer period in milliseconds.
+ * @NL80211_GSCAN_ATTR_MAX_AP_PER_SCAN: number of APs that are kept per
+ *	scan. The kept APs are the ones with strongest RSSI level.
+ * @NL80211_GSCAN_ATTR_REPORT_PERC: threshold specifying percentage of
+ *	scan cache filled that should trigger event for scan results.
+ * @NL80211_GSCAN_ATTR_REPORT_SCANS: threshold specifying number of scans
+ *	after which an event is expected for scan results.
+ * @NL80211_GSCAN_ATTR_BUCKETS: nested attribute specifying
+ *	per-bucket parameters for GScan. See %enum nl80211_gscan_bucket_attr
+ *	for description.
+ * @NL80211_GSCAN_ATTR_MAX: highest GScan attribute.
+ * @__NL80211_GSCAN_ATTR_AFTER_LAST: internal use.
+ */
+enum nl80211_gscan_attr {
+	__NL80211_GSCAN_ATTR_INVALID,
+	NL80211_GSCAN_ATTR_BASE_PERIOD,
+	NL80211_GSCAN_ATTR_MAX_AP_PER_SCAN,
+	NL80211_GSCAN_ATTR_REPORT_PERC,
+	NL80211_GSCAN_ATTR_REPORT_SCANS,
+	NL80211_GSCAN_ATTR_BUCKETS,
+
+	/* keep last */
+	__NL80211_GSCAN_ATTR_AFTER_LAST,
+	NL80211_GSCAN_ATTR_MAX = __NL80211_GSCAN_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_gscan_bucket_attr - per-bucket GScan parameters.
+ *
+ * @__NL80211_GSCAN_BUCKET_ATTR_INVALID,
+ * @NL80211_GSCAN_BUCKET_ATTR_ID: unique bucket id.
+ * @NL80211_GSCAN_BUCKET_ATTR_BAND: specifies the band to be scanned
+ *	according %enum nl80211_bucket_band. If specified
+ *	@NL80211_GSCAN_BUCKET_ATTR_CHANNELS is ignored.
+ * @NL80211_GSCAN_BUCKET_ATTR_PERIOD: specifies the period between
+ *	consecutive scans of this bucket. For backoff bucket this
+ *	is period(0).
+ * @NL80211_GSCAN_BUCKET_ATTR_REPORT: specifies reporting flags according
+ *	%enum nl80211_bucket_report_event.
+ * @NL80211_GSCAN_BUCKET_ATTR_MAX_PERIOD: maximum period between
+ *	consecutive scans. If specified this is a backoff bucket in
+ *	which the period increases according formula:
+ *	period(N) = period(0) * (base ^ (N/step_count))
+ * @NL80211_GSCAN_BUCKET_ATTR_EXPONENT: exponential base value as used
+ *	in given formula. This attribute is required when
+ *	@NL80211_GSCAN_BUCKET_ATTR_MAX_PERIOD is specified.
+ * @NL80211_GSCAN_BUCKET_ATTR_STEPS: step count as used in given formula.
+ *	This attribute is required when @NL80211_GSCAN_BUCKET_ATTR_MAX_PERIOD
+ *	is specified.
+ * @NL80211_GSCAN_BUCKET_ATTR_CHANNELS: nested attribute specifying the
+ *	channels that are to be scanned for this bucket.
+ * @NL80211_GSCAN_BUCKET_ATTR_MAX: highest GScan bucket attribute.
+ * @__NL80211_GSCAN_BUCKET_ATTR_AFTER_LAST: internal use.
+ */
+enum nl80211_gscan_bucket_attr {
+	__NL80211_GSCAN_BUCKET_ATTR_INVALID,
+	NL80211_GSCAN_BUCKET_ATTR_ID,
+	NL80211_GSCAN_BUCKET_ATTR_BAND,
+	NL80211_GSCAN_BUCKET_ATTR_PERIOD,
+	NL80211_GSCAN_BUCKET_ATTR_REPORT,
+	NL80211_GSCAN_BUCKET_ATTR_MAX_PERIOD,
+	NL80211_GSCAN_BUCKET_ATTR_EXPONENT,
+	NL80211_GSCAN_BUCKET_ATTR_STEPS,
+	NL80211_GSCAN_BUCKET_ATTR_CHANNELS,
+
+	/* keep last */
+	__NL80211_GSCAN_BUCKET_ATTR_AFTER_LAST,
+	NL80211_GSCAN_BUCKET_ATTR_MAX = __NL80211_GSCAN_BUCKET_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_gscan_chan_attr - GScan bucket channel parameters.
+ *
+ * @__NL80211_GSCAN_CHAN_ATTR_INVALID: reserved.
+ * @NL80211_GSCAN_CHAN_ATTR_FREQ: frequency of channel.
+ * @NL80211_GSCAN_CHAN_ATTR_DWELL_TIME: dwell time to be used for scanning
+ *	this channel.
+ * @NL80211_GSCAN_CHAN_ATTR_NO_IR: scanning should be done passive.
+ * @NL80211_GSCAN_CHAN_ATTR_MAX: highest GScan channel attribute.
+ * @__NL80211_GSCAN_CHAN_ATTR_AFTER_LAST: internal use.
+ */
+enum nl80211_gscan_chan_attr {
+	__NL80211_GSCAN_CHAN_ATTR_INVALID,
+	NL80211_GSCAN_CHAN_ATTR_FREQ,
+	NL80211_GSCAN_CHAN_ATTR_DWELL_TIME,
+	NL80211_GSCAN_CHAN_ATTR_NO_IR,
+
+	/* keep last */
+	__NL80211_GSCAN_CHAN_ATTR_AFTER_LAST,
+	NL80211_GSCAN_CHAN_ATTR_MAX = __NL80211_GSCAN_CHAN_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_bucket_band - GScan bucket band selection.
+ *
+ * @NL80211_BUCKET_BAND_2GHZ: consider all device supported channels
+ *	in 2G band.
+ * @NL80211_BUCKET_BAND_5GHZ: consider all device supported channels
+ *	in 5G band, ie. both DFS and non-DFS when @NL80211_BUCKET_BAND_NODFS
+ *	and @NL80211_BUCKET_BAND_DFS_ONLY are not set.
+ * @NL80211_BUCKET_BAND_NODFS: only consider non-DFS channels. Only
+ *	applicable when 5G band is selected, otherwise ignored.
+ * @NL80211_BUCKET_BAND_DFS_ONLY: only consider DFS channels. Only
+ *	applicable when 5G band is selected, otherwise ignored.
+ *
+ * Setting both @NL80211_BUCKET_BAND_NODFS and @NL80211_BUCKET_BAND_DFS_ONLY
+ * is considerd invalid.
+ */
+enum nl80211_bucket_band {
+	NL80211_BUCKET_BAND_2GHZ	= (1 << 0),
+	NL80211_BUCKET_BAND_5GHZ	= (1 << 1),
+	NL80211_BUCKET_BAND_NODFS	= (1 << 2),
+	NL80211_BUCKET_BAND_DFS_ONLY	= (1 << 3),
+};
+
+/**
+ * enum nl80211_bucket_report_event - GScan bucket report flags.
+ *
+ * @NL80211_BUCKET_REPORT_EACH_SCAN: trigger event after each scan.
+ * @NL80211_BUCKET_REPORT_FULL_RESULTS: report full scan results.
+ * @NL80211_BUCKET_REPORT_NO_BATCH: no batching required.
+ */
+enum nl80211_bucket_report_event {
+	NL80211_BUCKET_REPORT_EACH_SCAN		= (1 << 0),
+	NL80211_BUCKET_REPORT_FULL_RESULTS	= (1 << 1),
+	NL80211_BUCKET_REPORT_NO_BATCH		= (1 << 2),
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 158c59e..760a2fb 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -357,6 +357,20 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct *work)
 	rtnl_unlock();
 }
 
+static void cfg80211_gscan_stop_wk(struct work_struct *work)
+{
+	struct cfg80211_registered_device *rdev;
+
+	rdev = container_of(work, struct cfg80211_registered_device,
+			    gscan_stop_wk);
+
+	rtnl_lock();
+
+	__cfg80211_stop_gscan(rdev, false);
+
+	rtnl_unlock();
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
@@ -383,6 +397,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
 	WARN_ON(ops->remain_on_channel && !ops->cancel_remain_on_channel);
 	WARN_ON(ops->tdls_channel_switch && !ops->tdls_cancel_channel_switch);
 	WARN_ON(ops->add_tx_ts && !ops->del_tx_ts);
+	WARN_ON(ops->start_gscan && !ops->stop_gscan);
 
 	alloc_size = sizeof(*rdev) + sizeof_priv;
 
@@ -456,6 +471,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
 	spin_lock_init(&rdev->destroy_list_lock);
 	INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
 	INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
+	INIT_WORK(&rdev->gscan_stop_wk, cfg80211_gscan_stop_wk);
 
 #ifdef CONFIG_CFG80211_DEFAULT_PS
 	rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -690,6 +706,12 @@ int wiphy_register(struct wiphy *wiphy)
 		    (wiphy->bss_select_support & ~(BIT(__NL80211_BSS_SELECT_ATTR_AFTER_LAST) - 2))))
 		return -EINVAL;
 
+	/* buckets must have unique index and in nl80211 parsing
+	 * a u32 is used to verify that hence this limit.
+	 */
+	if (WARN_ON(wiphy->gscan && wiphy->gscan->max_scan_buckets > 32))
+		return -EINVAL;
+
 	if (wiphy->addresses)
 		memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
 
@@ -1001,6 +1023,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
 {
 	struct net_device *dev = wdev->netdev;
 	struct cfg80211_sched_scan_request *sched_scan_req;
+	struct cfg80211_gscan_request *gscan_req;
 
 	ASSERT_RTNL();
 	ASSERT_WDEV_LOCK(wdev);
@@ -1014,6 +1037,9 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
 		sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
 		if (sched_scan_req && dev == sched_scan_req->dev)
 			__cfg80211_stop_sched_scan(rdev, false);
+		gscan_req = rtnl_dereference(rdev->gscan_req);
+		if (gscan_req && dev == gscan_req->dev)
+			__cfg80211_stop_gscan(rdev, false);
 
 #ifdef CONFIG_CFG80211_WEXT
 		kfree(wdev->wext.ie);
@@ -1089,6 +1115,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev;
 	struct cfg80211_sched_scan_request *sched_scan_req;
+	struct cfg80211_gscan_request *gscan_req;
 
 	if (!wdev)
 		return NOTIFY_DONE;
@@ -1160,6 +1187,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
 			    sched_scan_req->dev == wdev->netdev)) {
 			__cfg80211_stop_sched_scan(rdev, false);
 		}
+		gscan_req = rtnl_dereference(rdev->gscan_req);
+		if (WARN_ON(gscan_req && gscan_req->dev == wdev->netdev)) {
+			__cfg80211_stop_gscan(rdev, false);
+		}
 
 		rdev->opencount--;
 		wake_up(&rdev->dev_wait);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index fb2fcd5..b0f2519 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -74,6 +74,7 @@ struct cfg80211_registered_device {
 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
 	struct sk_buff *scan_msg;
 	struct cfg80211_sched_scan_request __rcu *sched_scan_req;
+	struct cfg80211_gscan_request __rcu *gscan_req;
 	unsigned long suspend_at;
 	struct work_struct scan_done_wk;
 	struct work_struct sched_scan_results_wk;
@@ -95,6 +96,7 @@ struct cfg80211_registered_device {
 	struct work_struct destroy_work;
 
 	struct work_struct sched_scan_stop_wk;
+	struct work_struct gscan_stop_wk;
 
 	/* must be last because of the way we do wiphy_priv(),
 	 * and it should at least be aligned to NETDEV_ALIGN */
@@ -421,6 +423,8 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
 void __cfg80211_sched_scan_results(struct work_struct *wk);
 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
 			       bool driver_initiated);
+int __cfg80211_stop_gscan(struct cfg80211_registered_device *rdev,
+			  bool driver_initiated);
 void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
 int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev, enum nl80211_iftype ntype,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 073280d..7ec4bd5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -404,6 +404,7 @@ enum nl80211_multicast_groups {
 				    .len = FILS_MAX_KEK_LEN },
 	[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
 	[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
+	[NL80211_ATTR_GSCAN_PARAMS] = { .type = NLA_NESTED },
 };
 
 /* policy for the key attributes */
@@ -11860,6 +11861,318 @@ static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
 	return rdev_set_multicast_to_unicast(rdev, dev, enabled);
 }
 
+static const
+struct nla_policy nl80211_gscan_policy[NL80211_GSCAN_ATTR_MAX + 1] = {
+	[NL80211_GSCAN_ATTR_BASE_PERIOD] = { .type = NLA_U32 },
+	[NL80211_GSCAN_ATTR_MAX_AP_PER_SCAN] = { .type = NLA_U32 },
+	[NL80211_GSCAN_ATTR_REPORT_PERC] = { .type = NLA_U8 },
+	[NL80211_GSCAN_ATTR_REPORT_SCANS] = { .type = NLA_U32 },
+	[NL80211_GSCAN_ATTR_BUCKETS] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+nl80211_gscan_bucket_policy[NL80211_GSCAN_BUCKET_ATTR_MAX + 1] = {
+	[NL80211_GSCAN_BUCKET_ATTR_ID] = { .type = NLA_U32 },
+	[NL80211_GSCAN_BUCKET_ATTR_BAND] = { .type = NLA_U32 },
+	[NL80211_GSCAN_BUCKET_ATTR_PERIOD] = { .type = NLA_U32 },
+	[NL80211_GSCAN_BUCKET_ATTR_REPORT] = { .type = NLA_U32 },
+	[NL80211_GSCAN_BUCKET_ATTR_MAX_PERIOD] = { .type = NLA_U32 },
+	[NL80211_GSCAN_BUCKET_ATTR_EXPONENT] = { .type = NLA_U32 },
+	[NL80211_GSCAN_BUCKET_ATTR_STEPS] = { .type = NLA_U32 },
+	[NL80211_GSCAN_BUCKET_ATTR_CHANNELS] = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy
+nl80211_gscan_channel_policy[NL80211_GSCAN_CHAN_ATTR_MAX + 1] = {
+        [NL80211_GSCAN_CHAN_ATTR_FREQ] = { .type = NLA_U32 },
+        [NL80211_GSCAN_CHAN_ATTR_DWELL_TIME] = { .type = NLA_U32 },
+        [NL80211_GSCAN_CHAN_ATTR_NO_IR] = { .type = NLA_FLAG },
+};
+
+static int nl80211_parse_gscan_channel(struct cfg80211_registered_device *rdev,
+				       struct nlattr *nattr,
+				       struct cfg80211_gscan_channel *chan)
+{
+	struct nlattr *tb[NL80211_GSCAN_CHAN_ATTR_MAX + 1];
+	struct ieee80211_channel *ch;
+	int err;
+
+	err = nla_parse(tb, NL80211_GSCAN_CHAN_ATTR_MAX, nla_data(nattr),
+			nla_len(nattr), nl80211_gscan_channel_policy);
+	if (err)
+		return err;
+
+	if (!tb[NL80211_GSCAN_CHAN_ATTR_FREQ])
+		return -EINVAL;
+
+	ch = ieee80211_get_channel(&rdev->wiphy,
+				   nla_get_u32(tb[NL80211_GSCAN_CHAN_ATTR_FREQ]));
+	if (!ch || (ch->flags & IEEE80211_CHAN_DISABLED))
+		return -EINVAL;
+
+	chan->ch = ch;
+
+	if (tb[NL80211_GSCAN_CHAN_ATTR_DWELL_TIME])
+		chan->dwell_time = nla_get_u32(tb[NL80211_GSCAN_CHAN_ATTR_DWELL_TIME]);
+	if (tb[NL80211_GSCAN_CHAN_ATTR_NO_IR])
+		chan->passive = true;
+	return 0;
+}
+
+static int nl80211_parse_gscan_bucket(struct cfg80211_registered_device *rdev,
+				      struct nlattr *nattr,
+				      struct cfg80211_gscan_bucket *bucket,
+				      struct cfg80211_gscan_channel *channels)
+{
+	struct nlattr *tb[NL80211_GSCAN_BUCKET_ATTR_MAX + 1];
+	struct nlattr *chan;
+	struct cfg80211_gscan_channel *ch;
+	int err, rem;
+	int num_chans = 0;
+	u32 band_select = 0;
+	u32 dfs_invalid_mask;
+
+	err = nla_parse(tb, NL80211_GSCAN_BUCKET_ATTR_MAX, nla_data(nattr),
+			nla_len(nattr), nl80211_gscan_bucket_policy);
+	if (err)
+		return err;
+
+	if (!tb[NL80211_GSCAN_BUCKET_ATTR_ID] ||
+	    !tb[NL80211_GSCAN_BUCKET_ATTR_PERIOD])
+		return -EINVAL;
+
+	bucket->idx = nla_get_u32(tb[NL80211_GSCAN_BUCKET_ATTR_ID]);
+	if (tb[NL80211_GSCAN_BUCKET_ATTR_BAND]) {
+		band_select = nla_get_u32(tb[NL80211_GSCAN_BUCKET_ATTR_BAND]);
+
+		/* only makes sense if a band is selected */
+		if (!(band_select & (NL80211_BUCKET_BAND_2GHZ | NL80211_BUCKET_BAND_5GHZ)))
+			return -EINVAL;
+	}
+
+	dfs_invalid_mask = NL80211_BUCKET_BAND_5GHZ | NL80211_BUCKET_BAND_NODFS |
+			   NL80211_BUCKET_BAND_DFS_ONLY;
+	if ((band_select & dfs_invalid_mask) == dfs_invalid_mask)
+		return -EINVAL;
+
+	bucket->band = band_select;
+	bucket->period = nla_get_u32(tb[NL80211_GSCAN_BUCKET_ATTR_PERIOD]);
+
+	if (tb[NL80211_GSCAN_BUCKET_ATTR_MAX_PERIOD])
+		bucket->max_period = nla_get_u32(tb[NL80211_GSCAN_BUCKET_ATTR_MAX_PERIOD]);
+
+	if (bucket->max_period) {
+		if (bucket->max_period < bucket->period)
+			return -EINVAL;
+		/* additional attributes required for backoff bucket */
+		if (bucket->max_period > bucket->period) {
+			if (!tb[NL80211_GSCAN_BUCKET_ATTR_EXPONENT] ||
+			    !tb[NL80211_GSCAN_BUCKET_ATTR_STEPS])
+				return -EINVAL;
+
+			bucket->exponent = nla_get_u32(tb[NL80211_GSCAN_BUCKET_ATTR_EXPONENT]);
+			bucket->step_count = nla_get_u32(tb[NL80211_GSCAN_BUCKET_ATTR_STEPS]);
+		}
+	}
+
+	/* ignore channels if band is specified */
+	if (band_select)
+		return 0;
+
+        nla_for_each_nested(chan, tb[NL80211_GSCAN_BUCKET_ATTR_CHANNELS], rem) {
+                num_chans++;
+        }
+	if (num_chans > 16)
+		return -EINVAL;
+
+	bucket->n_channels = num_chans;
+	if (!num_chans)
+		return 0;
+
+	bucket->channels = channels;
+	ch = &bucket->channels[0];
+        nla_for_each_nested(chan, tb[NL80211_GSCAN_BUCKET_ATTR_CHANNELS], rem) {
+		err = nl80211_parse_gscan_channel(rdev, chan, ch);
+		if (err) {
+			return err;
+		}
+		ch++;
+        }
+
+	return 0;
+}
+
+static struct cfg80211_gscan_request *
+nl80211_alloc_gscan_request(struct cfg80211_registered_device *rdev,
+			    struct nlattr *buckets_attr)
+{
+	struct cfg80211_gscan_request *req;
+	struct cfg80211_gscan_bucket *b;
+	struct cfg80211_gscan_channel *ch;
+	int n_buckets, n_channels;
+	struct nlattr *attr, *bucket, *channel;
+	int rem, rem_b, rem_c;
+	size_t reqsize;
+
+	if (!buckets_attr)
+		return ERR_PTR(-EINVAL);
+
+	n_buckets = 0;
+	n_channels = 0;
+	nla_for_each_nested(bucket, buckets_attr, rem) {
+		n_buckets++;
+		if (n_buckets > rdev->wiphy.gscan->max_scan_buckets)
+			return ERR_PTR(-EINVAL);
+
+		nla_for_each_nested(attr, bucket, rem_b) {
+			if (nla_type(attr) == NL80211_GSCAN_BUCKET_ATTR_CHANNELS) {
+				nla_for_each_nested(channel, attr, rem_c)
+					n_channels++;
+			}
+		}
+	}
+
+	reqsize = sizeof(*req) +
+		  sizeof(*b) * n_buckets +
+		  sizeof(*ch) * n_channels;
+
+	req = kzalloc(reqsize, GFP_KERNEL);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->n_buckets = n_buckets;
+	return req;
+}
+
+static int nl80211_parse_gscan_params(struct cfg80211_registered_device *rdev,
+				      struct nlattr *attrs[],
+				      struct cfg80211_gscan_request **request)
+{
+	struct cfg80211_gscan_request *req;
+	struct nlattr *tb[NL80211_GSCAN_ATTR_MAX + 1];
+	struct nlattr *bucket;
+	struct cfg80211_gscan_bucket *b;
+	struct cfg80211_gscan_channel *ch;
+	int err, rem, i;
+	u32 bucket_map;
+
+	if (!attrs[NL80211_ATTR_GSCAN_PARAMS])
+		return -EINVAL;
+
+	err = nla_parse(tb, NL80211_GSCAN_ATTR_MAX,
+			nla_data(attrs[NL80211_ATTR_GSCAN_PARAMS]),
+			nla_len(attrs[NL80211_ATTR_GSCAN_PARAMS]),
+			nl80211_gscan_policy);
+	if (err)
+		return err;
+
+	req = nl80211_alloc_gscan_request(rdev, tb[NL80211_GSCAN_ATTR_BUCKETS]);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	if (!tb[NL80211_GSCAN_ATTR_BASE_PERIOD])
+		return -EINVAL;
+
+	req->base_period = nla_get_u32(tb[NL80211_GSCAN_ATTR_BASE_PERIOD]);
+
+	if (tb[NL80211_GSCAN_ATTR_MAX_AP_PER_SCAN])
+		req->max_ap_per_scan = nla_get_u32(tb[NL80211_GSCAN_ATTR_MAX_AP_PER_SCAN]);
+	if (tb[NL80211_GSCAN_ATTR_REPORT_PERC])
+		req->report_threshold_percent = nla_get_u8(tb[NL80211_GSCAN_ATTR_REPORT_PERC]);
+	if (tb[NL80211_GSCAN_ATTR_REPORT_SCANS])
+		req->report_threshold_num_scans = nla_get_u32(tb[NL80211_GSCAN_ATTR_REPORT_SCANS]);
+	if (attrs[NL80211_ATTR_MAC])
+		memcpy(req->mac, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
+	if (attrs[NL80211_ATTR_MAC_MASK])
+		memcpy(req->mac_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]),
+		       ETH_ALEN);
+	if (attrs[NL80211_ATTR_SCAN_FLAGS])
+		req->flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
+
+	b = &req->buckets[0];
+	ch = (struct cfg80211_gscan_channel *)(&req->buckets[req->n_buckets]);
+	nla_for_each_nested(bucket, tb[NL80211_GSCAN_ATTR_BUCKETS], rem) {
+		err = nl80211_parse_gscan_bucket(rdev, bucket, b, ch);
+		if (err)
+			goto free_req;
+		ch += b->n_channels;
+		b++;
+	}
+	bucket_map = 0;
+	for (i = 0; i < req->n_buckets; i++) {
+		if (BIT(req->buckets[i].idx) & bucket_map) {
+			err = -EINVAL;
+			goto free_req;
+		}
+		bucket_map |= BIT(req->buckets[i].idx);
+
+		if (req->buckets[i].period % req->base_period) {
+			err = -EINVAL;
+			goto free_req;
+		}
+		if (req->buckets[i].max_period &&
+		    (req->buckets[i].max_period % req->base_period)) {
+			err = -EINVAL;
+			goto free_req;
+		}
+	}
+	*request = req;
+	return 0;
+
+free_req:
+	kfree(req);
+	return err;
+}
+
+static int nl80211_start_gscan(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_gscan_request *request;
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	if (!rdev->wiphy.gscan ||
+	    !rdev->ops->start_gscan)
+		return -EOPNOTSUPP;
+
+	if (rdev->gscan_req)
+		return -EINPROGRESS;
+
+	err = nl80211_parse_gscan_params(rdev, info->attrs, &request);
+	if (err)
+		return err;
+
+	wdev_lock(wdev);
+	err = rdev_start_gscan(rdev, dev, request);
+	wdev_unlock(wdev);
+	if (err) {
+		kfree(request);
+		return err;
+	}
+
+	request->dev = dev;
+	if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
+		request->owner_nlportid = info->snd_portid;
+
+	rcu_assign_pointer(rdev->gscan_req, request);
+
+	nl80211_send_scan_event(rdev, dev,
+				NL80211_CMD_START_GSCAN);
+	return 0;
+}
+
+static int nl80211_stop_gscan(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+
+	if (!rdev->wiphy.gscan ||
+	    !rdev->ops->stop_gscan)
+		return -EOPNOTSUPP;
+
+	return __cfg80211_stop_gscan(rdev, false);
+}
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -12735,6 +13048,22 @@ static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL80211_CMD_START_GSCAN,
+		.doit = nl80211_start_gscan,
+		.policy = nl80211_policy,
+		.flags = GENL_UNS_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
+	{
+		.cmd = NL80211_CMD_STOP_GSCAN,
+		.doit = nl80211_stop_gscan,
+		.policy = nl80211_policy,
+		.flags = GENL_UNS_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
@@ -14540,12 +14869,18 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
 	list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
 		bool schedule_destroy_work = false;
 		bool schedule_scan_stop = false;
+		bool schedule_gscan_stop = false;
 		struct cfg80211_sched_scan_request *sched_scan_req =
 			rcu_dereference(rdev->sched_scan_req);
+		struct cfg80211_gscan_request *gscan_req =
+			rcu_dereference(rdev->gscan_req);
 
 		if (sched_scan_req && notify->portid &&
 		    sched_scan_req->owner_nlportid == notify->portid)
 			schedule_scan_stop = true;
+		if (gscan_req && notify->portid &&
+		    gscan_req->owner_nlportid == notify->portid)
+			schedule_gscan_stop = true;
 
 		list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
 			cfg80211_mlme_unregister_socket(wdev, notify->portid);
@@ -14576,12 +14911,18 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
 				spin_unlock(&rdev->destroy_list_lock);
 				schedule_work(&rdev->destroy_work);
 			}
-		} else if (schedule_scan_stop) {
-			sched_scan_req->owner_nlportid = 0;
+		} else {
+			if (schedule_scan_stop) {
+				sched_scan_req->owner_nlportid = 0;
 
-			if (rdev->ops->sched_scan_stop &&
-			    rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
-				schedule_work(&rdev->sched_scan_stop_wk);
+				if (rdev->ops->sched_scan_stop &&
+				    rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
+					schedule_work(&rdev->sched_scan_stop_wk);
+			}
+			if (schedule_gscan_stop) {
+				gscan_req->owner_nlportid = 0;
+				schedule_work(&rdev->gscan_stop_wk);
+			}
 		}
 	}
 
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 2f42507..196e6a7 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1153,4 +1153,29 @@ static inline int rdev_set_qos_map(struct cfg80211_registered_device *rdev,
 	trace_rdev_return_int(&rdev->wiphy, ret);
 	return ret;
 }
+
+static inline int
+rdev_start_gscan(struct cfg80211_registered_device *rdev,
+		 struct net_device *dev,
+		 struct cfg80211_gscan_request *request)
+{
+	int ret;
+
+	trace_rdev_start_gscan(&rdev->wiphy, dev);
+	ret = rdev->ops->start_gscan(&rdev->wiphy, dev, request);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
+static inline int
+rdev_stop_gscan(struct cfg80211_registered_device *rdev,
+		struct net_device *dev)
+{
+	int ret;
+
+	trace_rdev_stop_gscan(&rdev->wiphy, dev);
+	ret = rdev->ops->stop_gscan(&rdev->wiphy, dev);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
 #endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index dbdb53f..327b23c 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -335,6 +335,34 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
 	return 0;
 }
 
+int __cfg80211_stop_gscan(struct cfg80211_registered_device *rdev,
+			  bool driver_initiated)
+{
+	struct cfg80211_gscan_request *gscan_req;
+	struct net_device *dev;
+
+	ASSERT_RTNL();
+
+	if (!rdev->gscan_req)
+		return -ENOENT;
+
+	gscan_req = rtnl_dereference(rdev->gscan_req);
+	dev = gscan_req->dev;
+
+	if (!driver_initiated) {
+		int err = rdev_stop_gscan(rdev, dev);
+		if (err)
+			return err;
+	}
+
+	nl80211_send_scan_event(rdev, dev, NL80211_CMD_GSCAN_STOPPED);
+
+	RCU_INIT_POINTER(rdev->gscan_req, NULL);
+	kfree_rcu(gscan_req, rcu_head);
+
+	return 0;
+}
+
 void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
                       unsigned long age_secs)
 {
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ea1b47e..1d0fde9 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3067,6 +3067,15 @@
 		  WIPHY_PR_ARG, NETDEV_PR_ARG,
 		  BOOL_TO_STR(__entry->enabled))
 );
+
+DEFINE_EVENT(wiphy_netdev_evt, rdev_start_gscan,
+	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
+	TP_ARGS(wiphy, netdev)
+);
+DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_gscan,
+	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
+	TP_ARGS(wiphy, netdev)
+);
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH
-- 
1.9.1

^ permalink raw reply related

* Question about regional "adaptivity" / CCA settings
From: Vuille, Martin (Martin) @ 2016-11-17 18:08 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org

ETSI EN-300-328 and EN-301-893 set requirements for "adaptivity"
behaviour of Wi-Fi controllers.

Other regions may have different requirements.

If I understand correctly, regional requirements related to DFS are
managed through the Linux wireless infrastructure and the wireless-regdb.

Is there anything similar for "adaptivity"?

MV

^ permalink raw reply

* Re: [PATCH] rtlwifi: rtl8723be: Fix bug in ant_sel code from commit c18d8f509571
From: Larry Finger @ 2016-11-17 18:20 UTC (permalink / raw)
  To: kvalo; +Cc: devel, linux-wireless, Ping-Ke Shih, Stable
In-Reply-To: <20161117180533.16136-1-Larry.Finger@lwfinger.net>

On 11/17/2016 12:05 PM, Larry Finger wrote:
> From: Ping-Ke Shih <pkshih@realtek.com>
>
> In commit c18d8f509571 ("rtlwifi: rtl8723be: Add antenna select module
> parameter"), wifi was fixed for those laptops that have only a single
> antenna but have an incorrectly coded EEPROM. This error causes the
> driver to select the wrong antenna. In that commit, one necessary change
> that affects Bluetooth operation was missed.
>
> Fixes: c18d8f509571 ("rtlwifi: rtl8723be: Add antenna select module parameter")
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> Cc: Stable <stable@vger.kernel.org>
> ---
>  drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
> index aba60c3..cb046ec 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
> @@ -2664,9 +2664,12 @@ void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
>  	}
>
>  	/* override ant_num / ant_path */
> -	if (mod_params->ant_sel)
> +	if (mod_params->ant_sel) {
>  		rtlpriv->btcoexist.btc_info.ant_num =
>  			(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
> +		rtlpriv->btcoexist.btc_info.single_ant_path =
> +			(mod_params->ant_sel == 1 ? 0 : 1);
> +	}
>  }
>
>  void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
>

Please drop this patch. It contains an error.

Sorry,

Larry

^ permalink raw reply

* Re: [PATCH] rtlwifi: rtl8723be: Fix bug in ant_sel code from commit c18d8f509571
From: kbuild test robot @ 2016-11-17 19:33 UTC (permalink / raw)
  To: Larry Finger
  Cc: kbuild-all, kvalo, devel, Ping-Ke Shih, linux-wireless, Stable,
	Larry Finger
In-Reply-To: <20161117180533.16136-1-Larry.Finger@lwfinger.net>

[-- Attachment #1: Type: text/plain, Size: 1692 bytes --]

Hi Ping-Ke,

[auto build test ERROR on wireless-drivers-next/master]
[also build test ERROR on v4.9-rc5]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Larry-Finger/rtlwifi-rtl8723be-Fix-bug-in-ant_sel-code-from-commit-c18d8f509571/20161118-024559
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

   drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c: In function 'rtl8723be_read_bt_coexist_info_from_hwpg':
>> drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c:2670:30: error: 'struct rtl_btc_info' has no member named 'single_ant_path'
      rtlpriv->btcoexist.btc_info.single_ant_path =
                                 ^

vim +2670 drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c

  2664		}
  2665	
  2666		/* override ant_num / ant_path */
  2667		if (mod_params->ant_sel) {
  2668			rtlpriv->btcoexist.btc_info.ant_num =
  2669				(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
> 2670			rtlpriv->btcoexist.btc_info.single_ant_path =
  2671				(mod_params->ant_sel == 1 ? 0 : 1);
  2672		}
  2673	}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 45106 bytes --]

^ permalink raw reply

* Re: [PATCH 1/5] nl80211: allow reporting RTT information in scan results
From: Arend Van Spriel @ 2016-11-17 19:50 UTC (permalink / raw)
  To: Dan Williams, Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1479399340.6110.8.camel@redhat.com>

On 17-11-2016 17:15, Dan Williams wrote:
> On Thu, 2016-11-17 at 11:39 +0000, Arend van Spriel wrote:
>> Add distance and its variance to the BSS structure so drivers
>> may provide RTT information for BSS instances found during
>> scanning.
>>
>> Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
>> Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.co
>> m>
>> Reviewed-by: Franky Lin <franky.lin@broadcom.com>
>> Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
>> ---
>>  include/net/cfg80211.h       | 11 +++++++++++
>>  include/uapi/linux/nl80211.h |  6 ++++++
>>  net/wireless/nl80211.c       |  8 ++++++++
>>  net/wireless/scan.c          |  2 ++
>>  4 files changed, 27 insertions(+)
>>
>> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
>> index 2019310..d1217da 100644
>> --- a/include/net/cfg80211.h
>> +++ b/include/net/cfg80211.h
>> @@ -1675,6 +1675,9 @@ enum cfg80211_signal_type {
>>   * @scan_width: scan width that was used
>>   * @signal: signal strength value, according to the wiphy's
>>   *	signal type
>> + * @distance: distance to AP with %parent_bssid in centimeters. Zero
>> + *	value indicates this is undetermined.
>> + * @var_distance: variance of %distance indicating accurracy.
> 
> "accuracy" without the second 'r'.
> 
> Also, what unit is the variance in?  Needs more documentation.

The term variance here is the standard statistical term. You can read
more info here [1]. As distance is in centimeters, the variance of the
distance is in square centimeters. I can add that.

Regards,
Arend

[1] http://www.mathsisfun.com/data/standard-deviation.html

> Dan
> 
>>   * @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was
>>   *	received; should match the time when the frame was
>> actually
>>   *	received by the device (not just by the host, in case it
>> was
>> @@ -1691,6 +1694,8 @@ struct cfg80211_inform_bss {
>>  	struct ieee80211_channel *chan;
>>  	enum nl80211_bss_scan_width scan_width;
>>  	s32 signal;
>> +	u32 distance;
>> +	u32 var_distance;
>>  	u64 boottime_ns;
>>  	u64 parent_tsf;
>>  	u8 parent_bssid[ETH_ALEN] __aligned(2);
>> @@ -1737,6 +1742,9 @@ struct cfg80211_bss_ies {
>>   *	that holds the beacon data. @beacon_ies is still valid, of
>> course, and
>>   *	points to the same data as hidden_beacon_bss->beacon_ies
>> in that case.
>>   * @signal: signal strength value (type depends on the wiphy's
>> signal_type)
>> + * @distance: distance to AP with %parent_bssid in centimeters. Zero
>> + *	value indicates this is undetermined.
>> + * @var_distance: variance of %distance indicating accurracy.
>>   * @priv: private area for driver use, has at least wiphy-
>>> bss_priv_size bytes
>>   */
>>  struct cfg80211_bss {
>> @@ -1756,6 +1764,9 @@ struct cfg80211_bss {
>>  
>>  	u8 bssid[ETH_ALEN];
>>  
>> +	u32 distance;
>> +	u32 var_distance;
>> +
>>  	u8 priv[0] __aligned(sizeof(void *));
>>  };
>>  
>> diff --git a/include/uapi/linux/nl80211.h
>> b/include/uapi/linux/nl80211.h
>> index 259c9c7..7e935f6 100644
>> --- a/include/uapi/linux/nl80211.h
>> +++ b/include/uapi/linux/nl80211.h
>> @@ -3651,6 +3651,10 @@ enum nl80211_bss_scan_width {
>>   *	@NL80211_BSS_PARENT_BSSID. (u64).
>>   * @NL80211_BSS_PARENT_BSSID: the BSS according to which
>> @NL80211_BSS_PARENT_TSF
>>   *	is set.
>> + * @NL80211_BSS_DISTANCE: distance to AP with
>> @NL80211_BSS_PARENT_BSSID in
>> + *	centimeters (u32).
>> + * @NL80211_BSS_VARIANCE_DISTANCE: variance of @NL80211_BSS_DISTANCE
>> value (u32).
>> + *
>>   * @__NL80211_BSS_AFTER_LAST: internal
>>   * @NL80211_BSS_MAX: highest BSS attribute
>>   */
>> @@ -3674,6 +3678,8 @@ enum nl80211_bss {
>>  	NL80211_BSS_PAD,
>>  	NL80211_BSS_PARENT_TSF,
>>  	NL80211_BSS_PARENT_BSSID,
>> +	NL80211_BSS_DISTANCE,
>> +	NL80211_BSS_VARIANCE_DISTANCE,
>>  
>>  	/* keep last */
>>  	__NL80211_BSS_AFTER_LAST,
>> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
>> index 24ab199..ffce566 100644
>> --- a/net/wireless/nl80211.c
>> +++ b/net/wireless/nl80211.c
>> @@ -7515,6 +7515,14 @@ static int nl80211_send_bss(struct sk_buff
>> *msg, struct netlink_callback *cb,
>>  			      intbss->ts_boottime, NL80211_BSS_PAD))
>>  		goto nla_put_failure;
>>  
>> +	if (res->distance && nla_put_u32(msg, NL80211_BSS_DISTANCE,
>> +					 res->distance))
>> +		goto nla_put_failure;
>> +
>> +	if (res->var_distance && nla_put_u32(msg,
>> NL80211_BSS_VARIANCE_DISTANCE,
>> +					     res->var_distance))
>> +		goto nla_put_failure;
>> +
>>  	switch (rdev->wiphy.signal_type) {
>>  	case CFG80211_SIGNAL_TYPE_MBM:
>>  		if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res-
>>> signal))
>> diff --git a/net/wireless/scan.c b/net/wireless/scan.c
>> index b5bd58d..afda1f9 100644
>> --- a/net/wireless/scan.c
>> +++ b/net/wireless/scan.c
>> @@ -973,6 +973,8 @@ struct cfg80211_bss *
>>  	tmp.pub.signal = data->signal;
>>  	tmp.pub.beacon_interval = beacon_interval;
>>  	tmp.pub.capability = capability;
>> +	tmp.pub.distance = data->distance;
>> +	tmp.pub.var_distance = data->var_distance;
>>  	tmp.ts_boottime = data->boottime_ns;
>>  
>>  	/*

^ permalink raw reply

* Re: [RFC 0/5] nl80211: add support for g-scan
From: Arend Van Spriel @ 2016-11-17 20:23 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Dmitry Shmidt
In-Reply-To: <1479393551.1463.11.camel@sipsolutions.net>

On 17-11-2016 15:39, Johannes Berg wrote:
> On Thu, 2016-11-17 at 13:18 +0000, Arend van Spriel wrote:
>> Android employs a Wifi-HAL layer in its wireless frame. It basically
>> abstracts dealing with netlink messages from the framework. For some
>> features it employs nl80211 vendor commands. The goal I set myself is
>> to be able to have a generic nl80211 Wifi-HAL implementation. One of
>> the features currently requiring the vendor commands is g-scan. We
>> can only guess what the 'g' stands for ;-) This series converts the
>> vendor command api into common nl80211 api.
> 
> Hehe :)
> We also have gscan API. If you're interested, you can see it here:
> https://git.kernel.org/cgit/linux/kernel/git/iwlwifi/backport-iwlwifi.git/tree/drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.h#n96

I am interested and I did have a look at it when I found out, but I had
already tinkered out a large portion so decided to stick with that.

>> Before making an attempt to explain more about the g-scan
>> functionality first this. While I am still testing the driver
>> implementation resulting in numerous questions Dmitry send the email
>> below to bring a related discussion to the table..eh.. the linux-
>> wireless list. This is probably a good thing as anyone can dive in
>> and share their thoughts.
> 
> 
> Yeah. How does this overlap? Have you looked at it already?

The overlap occurred when Dmitry pointed me to this thread in response
to questions I had regarding gscan :-p Now the similarity is reflected
mainly in terms used for functionality like bss hotlist, batch results,
etc. which are also found in gscan defintions in android wifi hal.

The main difference between the gscan and universal scan is that gscan
specifies everything in a single start request and the universal scan
api can be used to add/remove individual scans, which would be
equivalent with the ability to add/remove buckets in gscan.

I will comment more replying the RFC email from Dmitry.

Regards,
Arend

^ permalink raw reply

* Re: [PATCH] RFC: Universal scan proposal
From: Arend Van Spriel @ 2016-11-17 20:56 UTC (permalink / raw)
  To: dimitrysh, linux-wireless
In-Reply-To: <94eb2c110db85c2379054172dad0@google.com>

On 16-11-2016 23:47, dimitrysh@google.com wrote:
> From 68a9d37a4c7e9dc7a90a6e922cdea52737a98d66 Mon Sep 17 00:00:00 2001
> From: Dmitry Shmidt <dimitrysh@google.com>
> Date: Wed, 16 Nov 2016 14:27:26 -0800
> Subject: [PATCH] RFC: Universal scan proposal
> 
>   Currently we have sched scan with possibility of various
> intervals. We would like to extend it to support also
> different types of scan.
>   In case of powerful wlan CPU, all this functionality
> can be offloaded.
>   In general case FW processes additional scan requests
> and puts them into queue based on start time and interval.
> Once current request is fulfilled, FW adds it (if interval != 0)
> again to the queue with proper interval. If requests are
> overlapping, new request can be combined with either one before,
> or one after, assuming that requests are not mutually exclusive.
>   Combining requests is done by combining scan channels, ssids,
> bssids and types of scan result. Once combined request was fulfilled
> it will be reinserted as two (or three) different requests based on
> their type and interval.
>   Each request has attribute:
> Type: connectivity / location

Don't see this type in the patch below (guess it was a last minute
addition ;-) ).

> Report: none / batch / immediate
>   Request may have priority and can be inserted into
> the head of the queue.
>   Types of scans:
> - Normal scan
> - Scheduled scan
> - Hotlist (BSSID scan)
> - Roaming
> - AutoJoin

Don't see the last one mentioned in the patch below.

> Change-Id: I9f3e4c975784f1c1c5156887144d80fc5a26bffa
> Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
> ---
>  include/net/cfg80211.h | 37 +++++++++++++++++++++++++++++++------
>  1 file changed, 31 insertions(+), 6 deletions(-)
> 
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 14b51d7..1ae2570 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -1602,8 +1602,10 @@ struct cfg80211_sched_scan_plan {
>   *    cycle.  The driver may ignore this parameter and start
>   *    immediately (or at any other time), if this feature is not
>   *    supported.

At the the top of this kernel doc section it probably still refers to
struct cfg80211_sched_scan_request.

> + * @uscan_type: uscan type (scan, sched_scan, hotlist, scan_history,
> roaming)
> + * @uscan_results: uscan results report (none/batch/immediate)

If you change the type to struct cfg80211_uscan_request it seems a bit
redundant to prefix the field names with 'uscan_'.

>   */
> -struct cfg80211_sched_scan_request {
> +struct cfg80211_uscan_request {
>      struct cfg80211_ssid *ssids;
>      int n_ssids;
>      u32 n_channels;
> @@ -1621,6 +1623,10 @@ struct cfg80211_sched_scan_request {
>      u8 mac_addr[ETH_ALEN] __aligned(2);
>      u8 mac_addr_mask[ETH_ALEN] __aligned(2);
> 
> +    /* universal scan fields */

As the struct name changed it seems to me all fields in the struct are
universal scan fields.

> +    u32 uscan_type;
> +    u32 uscan_results;
> +
>      /* internal */
>      struct wiphy *wiphy;
>      struct net_device *dev;
> @@ -1633,6 +1639,21 @@ struct cfg80211_sched_scan_request {
>  };
> 
>  /**
> + * struct cfg80211_uscan_capa - universal scan capabilities
> + *
> + * @uscan_type: uscan type (scan, sched_scan, hotlist, scan_history,
> roaming)
> + * @max_ssids: max amount of ssids in sched scan
> + * @max_hotlist: max amount of bssids in hotlist
> + * @max_history: max amount of records in history
> + */
> +struct cfg80211_uscan_capa {
> +    u32 uscan_type;
> +    u32 max_ssids;
> +    u32 max_hotlist;
> +    u32 max_history;
> +};
> +
> +/**
>   * enum cfg80211_signal_type - signal type
>   *
>   * @CFG80211_SIGNAL_TYPE_NONE: no signal strength information available
> @@ -2898,10 +2919,13 @@ struct cfg80211_ops {
>      int    (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
>      int    (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
> 
> -    int    (*sched_scan_start)(struct wiphy *wiphy,
> +    int    (*uscan_get_capa)(struct wiphy *wiphy, struct net_device *dev,
> +                struct cfg80211_uscan_capa *uscan_capa);

Not sure if people start worrying about the size of struct wiphy
already, but for static information like capabilities I think a callback
is overkill.

> +    int    (*uscan_start)(struct wiphy *wiphy,
>                  struct net_device *dev,
> -                struct cfg80211_sched_scan_request *request);
> -    int    (*sched_scan_stop)(struct wiphy *wiphy, struct net_device
> *dev);
> +                struct cfg80211_uscan_request *request);

So given the two extra fields, what different driver/device behaviour is
required, eg. if uscan_type == roaming what will be different compared
to a normal scan.

> +    int    (*uscan_stop)(struct wiphy *wiphy, struct net_device *dev,
> +                int uscan_id);

The uscan_id is probably referring to a specific scan request started by
uscan_start. So who hands out that id (wiphy->cookie_counter?) and how
does the driver know about it. If cfg80211 determines the id it probably
need to be passed in the uscan request.

>      int    (*set_rekey_data)(struct wiphy *wiphy, struct net_device *dev,
>                    struct cfg80211_gtk_rekey_data *data);
> @@ -4305,11 +4329,12 @@ void cfg80211_scan_done(struct
> cfg80211_scan_request *request,
>              struct cfg80211_scan_info *info);
> 
>  /**
> - * cfg80211_sched_scan_results - notify that new scan results are
> available
> + * cfg80211_uscan_results - notify that new uscan results are available
>   *
>   * @wiphy: the wiphy which got scheduled scan results
> + * @uscan_id: type of scan results

Confused now. What is uscan_id here? Same as in .uscan_stop() callback?

>   */
> -void cfg80211_sched_scan_results(struct wiphy *wiphy);
> +void cfg80211_sched_scan_results(struct wiphy *wiphy, int uscan_id);

should this be renamed to cfg80211_uscan_results().

>  /**
>   * cfg80211_sched_scan_stopped - notify that the scheduled scan has
> stopped

Also change to cfg80211_uscan_stopped()? Does it need an additional
argument, ie. uscan_id.

Regards,
Arend

^ permalink raw reply

* [PATCH] mmc: pwrseq: add support for Marvell SD8787 chip
From: Matt Ranostay @ 2016-11-18  1:55 UTC (permalink / raw)
  To: linux-wireless, linux-kernel, devicetree, linux-mmc
  Cc: Matt Ranostay, Tony Lindgren, Ulf Hansson, Mark Rutland,
	Srinivas Kandagatla

Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
This can be abstracted to other chipsets if needed in the future.

Cc: Tony Lindgren <tony@atomide.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
---
 .../devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt  |  14 +++
 .../bindings/net/wireless/marvell-sd8xxx.txt       |   4 +
 drivers/mmc/core/Kconfig                           |  10 ++
 drivers/mmc/core/Makefile                          |   1 +
 drivers/mmc/core/pwrseq_sd8787.c                   | 117 +++++++++++++++++++++
 5 files changed, 146 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
 create mode 100644 drivers/mmc/core/pwrseq_sd8787.c

diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
new file mode 100644
index 000000000000..1b658351629b
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt
@@ -0,0 +1,14 @@
+* Marvell SD8787 power sequence provider
+
+Required properties:
+- compatible: must be "mmc-pwrseq-sd8787".
+- pwndn-gpio: contains a power down GPIO specifier.
+- reset-gpio: contains a reset GPIO specifier.
+
+Example:
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-sd8787";
+		pwrdn-gpio = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
+		reset-gpio = <&twl_gpio 1 GPIO_ACTIVE_LOW>;
+	}
diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
index c421aba0a5bc..08fd65d35725 100644
--- a/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
+++ b/Documentation/devicetree/bindings/net/wireless/marvell-sd8xxx.txt
@@ -32,6 +32,9 @@ Optional properties:
 		 so that the wifi chip can wakeup host platform under certain condition.
 		 during system resume, the irq will be disabled to make sure
 		 unnecessary interrupt is not received.
+  - vmmc-supply: a phandle of a regulator, supplying VCC to the card
+  - mmc-pwrseq:  phandle to the MMC power sequence node. See "mmc-pwrseq-*"
+		 for documentation of MMC power sequence bindings.
 
 Example:
 
@@ -44,6 +47,7 @@ so that firmware can wakeup host using this device side pin.
 &mmc3 {
 	status = "okay";
 	vmmc-supply = <&wlan_en_reg>;
+	mmc-pwrseq = <&wifi_pwrseq>;
 	bus-width = <4>;
 	cap-power-off-card;
 	keep-power-in-suspend;
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index 250f223aaa80..cf61d676ac06 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -12,6 +12,16 @@ config PWRSEQ_EMMC
 	  This driver can also be built as a module. If so, the module
 	  will be called pwrseq_emmc.
 
+config PWRSEQ_SD8787
+	tristate "HW reset support for SD8787 BT + Wifi module"
+	depends on OF && (MWIFIEX || BT_MRVL_SDIO)
+	help
+	  This selects hardware reset support for the SD8787 BT + Wifi
+	  module. By default this option is set to n.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called pwrseq_sd8787.
+
 config PWRSEQ_SIMPLE
 	tristate "Simple HW reset support for MMC"
 	default y
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index f007151dfdc6..f1c060e56d4e 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -10,5 +10,6 @@ mmc_core-y			:= core.o bus.o host.o \
 				   quirks.o slot-gpio.o
 mmc_core-$(CONFIG_OF)		+= pwrseq.o
 obj-$(CONFIG_PWRSEQ_SIMPLE)	+= pwrseq_simple.o
+obj-$(CONFIG_PWRSEQ_SD8787)	+= pwrseq_sd8787.o
 obj-$(CONFIG_PWRSEQ_EMMC)	+= pwrseq_emmc.o
 mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o
diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
new file mode 100644
index 000000000000..f4080fe6439e
--- /dev/null
+++ b/drivers/mmc/core/pwrseq_sd8787.c
@@ -0,0 +1,117 @@
+/*
+ * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip
+ *
+ * Copyright (C) 2016 Matt Ranostay <matt@ranostay.consulting>
+ *
+ * Based on the original work pwrseq_simple.c
+ *  Copyright (C) 2014 Linaro Ltd
+ *  Author: Ulf Hansson <ulf.hansson@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+
+#include <linux/mmc/host.h>
+
+#include "pwrseq.h"
+
+struct mmc_pwrseq_sd8787 {
+	struct mmc_pwrseq pwrseq;
+	struct gpio_desc *reset_gpio;
+	struct gpio_desc *pwrdn_gpio;
+};
+
+#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
+
+static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
+{
+	struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
+
+	gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
+
+	msleep(300);
+	gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
+}
+
+static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
+{
+	struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
+
+	gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
+	gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
+}
+
+static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
+	.pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
+	.power_off = mmc_pwrseq_sd8787_power_off,
+};
+
+static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
+	{ .compatible = "mmc-pwrseq-sd8787",},
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
+
+static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
+{
+	struct mmc_pwrseq_sd8787 *pwrseq;
+	struct device *dev = &pdev->dev;
+
+	pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
+	if (!pwrseq)
+		return -ENOMEM;
+
+	pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
+	if (IS_ERR(pwrseq->pwrdn_gpio))
+		return PTR_ERR(pwrseq->pwrdn_gpio);
+
+	pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(pwrseq->reset_gpio))
+		return PTR_ERR(pwrseq->reset_gpio);
+
+	pwrseq->pwrseq.dev = dev;
+	pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
+	pwrseq->pwrseq.owner = THIS_MODULE;
+	platform_set_drvdata(pdev, pwrseq);
+
+	return mmc_pwrseq_register(&pwrseq->pwrseq);
+}
+
+static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
+{
+	struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
+
+	mmc_pwrseq_unregister(&pwrseq->pwrseq);
+
+	return 0;
+}
+
+static struct platform_driver mmc_pwrseq_sd8787_driver = {
+	.probe = mmc_pwrseq_sd8787_probe,
+	.remove = mmc_pwrseq_sd8787_remove,
+	.driver = {
+		.name = "pwrseq_sd8787",
+		.of_match_table = mmc_pwrseq_sd8787_of_match,
+	},
+};
+
+module_platform_driver(mmc_pwrseq_sd8787_driver);
+MODULE_LICENSE("GPL v2");
-- 
2.7.4

^ permalink raw reply related

* [PATCH V2] brcmfmac: update beacon IE after bss up and clear when AP stopped
From: Wright Feng @ 2016-11-18  1:59 UTC (permalink / raw)
  To: arend.vanspriel, franky.lin, hante.meuleman, pieterpg, kvalo,
	brcm80211-dev-list.pdl, linux-wireless
  Cc: Chi-Hsien Lin, wright.feng

Firmware doesn't update beacon/Probe Response vendor IEs correctly when
bss is down, so we move brcmf_config_ap_mgmt_ie after BSS up. And host
driver should clear IEs when AP stopped so that the IEs in host side will
be synced with in firmware side.

Signed-off-by: Wright Feng <wright.feng@cypress.com>
---
V2: word wrap the commit log
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index b777e1b..d022605 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -4578,8 +4578,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
 		brcmf_configure_opensecurity(ifp);
 	}
 
-	brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
-
 	/* Parameters shared by all radio interfaces */
 	if (!mbss) {
 		if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
@@ -4708,6 +4706,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
 		WARN_ON(1);
 	}
 
+	brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
 	set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
 	brcmf_net_setcarrier(ifp, true);
 
@@ -4764,6 +4763,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
 		if (err < 0)
 			brcmf_err("BRCMF_C_UP error %d\n", err);
+
+		brcmf_vif_clear_mgmt_ies(ifp->vif);
 	} else {
 		bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
 		bss_enable.enable = cpu_to_le32(0);
-- 
2.1.0

^ permalink raw reply related

* pull-request: mac80211 2016-11-18
From: Johannes Berg @ 2016-11-18  7:52 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-wireless

Hi Dave,

Due to travel/vacation, this is a bit late, but there aren't
that many fixes either. Most interesting/important are the
fixes from Felix and perhaps the scan entry limit.

Please pull and let me know if there's any problem.

Thanks,
johannes



The following changes since commit 269ebce4531b8edc4224259a02143181a1c1d77c:

  xen-netfront: cast grant table reference first to type int (2016-11-02 15:33:36 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2016-11-18

for you to fetch changes up to 9853a55ef1bb66d7411136046060bbfb69c714fa:

  cfg80211: limit scan results cache size (2016-11-18 08:44:44 +0100)

----------------------------------------------------------------
A few more bugfixes:
 * limit # of scan results stored in memory - this is a long-standing bug
   Jouni and I only noticed while discussing other things in Santa Fe
 * revert AP_LINK_PS patch that was causing issues (Felix)
 * various A-MSDU/A-MPDU fixes for TXQ code (Felix)
 * interoperability workaround for peers with broken VHT capabilities
   (Filip Matusiak)
 * add bitrate definition for a VHT MCS that's supposed to be invalid
   but gets used by some hardware anyway (Thomas Pedersen)
 * beacon timer fix in hwsim (Benjamin Beichler)

----------------------------------------------------------------
Benjamin Beichler (1):
      mac80211_hwsim: fix beacon delta calculation

Felix Fietkau (4):
      Revert "mac80211: allow using AP_LINK_PS with mac80211-generated TIM IE"
      mac80211: update A-MPDU flag on tx dequeue
      mac80211: remove bogus skb vif assignment
      mac80211: fix A-MSDU aggregation with fast-xmit + txq

Filip Matusiak (1):
      mac80211: Ignore VHT IE from peer with wrong rx_mcs_map

Johannes Berg (1):
      cfg80211: limit scan results cache size

Pedersen, Thomas (1):
      cfg80211: add bitrate for 20MHz MCS 9

 drivers/net/wireless/mac80211_hwsim.c |  2 +-
 net/mac80211/sta_info.c               |  2 +-
 net/mac80211/tx.c                     | 14 +++++--
 net/mac80211/vht.c                    | 16 ++++++++
 net/wireless/core.h                   |  1 +
 net/wireless/scan.c                   | 69 +++++++++++++++++++++++++++++++++++
 net/wireless/util.c                   |  3 +-
 7 files changed, 100 insertions(+), 7 deletions(-)

^ permalink raw reply

* [PATCH 0/7] Fix -Wunused-but-set-variable in mwifiex/
From: Kirtika Ruchandani @ 2016-11-18  8:43 UTC (permalink / raw)
  To: Amitkumar Karwar
  Cc: Arnd Bergmann, Kalle Valo, linux-wireless, Nishant Sarmukadam,
	Zhaoyang Liu, Bing Zhao, Xinming Hu, Avinash Patil

This patchset is part of the effort led by Arnd Bergmann to clean up
warnings in the kernel. This and following patchsets will focus on
"-Wunused-but-set-variable" as it among the noisier ones. These were
found compiling with W=1.

Kirtika Ruchandani (7):
  mwifiex: Removed unused mwifiex_private* 'priv' variable
  mwifiex: Remove unused  'chan_num' variable
  mwifiex: Remove unused 'sta_ptr' variable
  mwifiex: Remove unused 'adapter'variable
  mwifiex: Remove unused 'pm_flag' variable
  mwifiex: Removed unused 'pkt_type' variable
  mwifiex: Remove unused 'bcd_usb' variable

 drivers/net/wireless/marvell/mwifiex/cfg80211.c | 2 --
 drivers/net/wireless/marvell/mwifiex/main.c     | 3 ---
 drivers/net/wireless/marvell/mwifiex/scan.c     | 8 +++-----
 drivers/net/wireless/marvell/mwifiex/sdio.c     | 5 -----
 drivers/net/wireless/marvell/mwifiex/sta_cmd.c  | 2 --
 drivers/net/wireless/marvell/mwifiex/usb.c      | 3 +--
 6 files changed, 4 insertions(+), 19 deletions(-)

--
2.8.0.rc3.226.g39d4020

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox