Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH] iwlwifi: work around clang -Wuninitialized warning
From: Arnd Bergmann @ 2019-03-23 11:28 UTC (permalink / raw)
  To: Luca Coelho
  Cc: Johannes Berg, clang-built-linux, Nick Desaulniers,
	Nathan Chancellor, Emmanuel Grumbach, Intel Linux Wireless,
	Kalle Valo, David S. Miller, Sara Sharon, Avraham Stern,
	linux-wireless, Networking, Linux Kernel Mailing List
In-Reply-To: <a92bc0994d5f3fa5da5da471d0ccd01f8cefeee5.camel@coelho.fi>

On Sat, Mar 23, 2019 at 7:11 AM Luca Coelho <luca@coelho.fi> wrote:
>
> On Fri, 2019-03-22 at 15:13 +0100, Arnd Bergmann wrote:
> > Clang incorrectly warns about an uninitialized variable:
> >
> >
> > This cannot happen because the if/else if/else if block always
> > has one code path that is entered. However, we can simply
> > rearrange the code to let clang see this as well.
> >
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > ---
>
> Thanks for the patch, Arnd! But I have already queued up an equivalent
> patch for v5.2 (should probably reach linux-next by the end of next
> week or so):
>
> https://patchwork.kernel.org/patch/10844025/

Thanks, and sorry for the duplicate. I forgot to check for the
patches that Nathan had already done when I started sending
out my own series on the same issues.

       Arnd

^ permalink raw reply

* Re: [PATCH] mt76: tx: check return value of tx_queue_skb in mt76_tx
From: Felix Fietkau @ 2019-03-23 11:36 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-wireless, lorenzo.bianconi, sgruszka
In-Reply-To: <c57c934c56942a64d6bb09d8fbc6c704568c707c.1553204966.git.lorenzo@kernel.org>

On 2019-03-21 22:51, Lorenzo Bianconi wrote:
> Do not kick the queue if tx_queue_skb fails in mt76_tx
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
tx_queue_skb will fail only in rare corner cases, and kicking the queue
without adding extra packets is harmless.
Because of that, I think this patch is unnecessary.

- Felix

^ permalink raw reply

* Re: [RFC PATCH] mac80211/cfg80211: update bss channel on channel switch
From: Johannes Berg @ 2019-03-23 12:32 UTC (permalink / raw)
  To: Sergey Matyukevich, linux-wireless@vger.kernel.org
  Cc: Igor Mitsyanko, Arend van Spriel
In-Reply-To: <20190321151915.16826-1-sergey.matyukevich.os@quantenna.com>

On Thu, 2019-03-21 at 15:19 +0000, Sergey Matyukevich wrote:
> FullMAC STAs have no way to update bss channel after CSA channel switch
> completion. As a result, user-space tools may provide inconsistent
> channel info. For instance, consider the following two commands:
> $ sudo iw dev wlan0 link
> $ sudo iw dev wlan0 info
> The latter command gets channel info from the hardware, so most probably
> its output will be correct. However the former command gets channel info
> from scan cache, so its output will contain outdated channel info.
> In fact, current bss channel info will not be updated until the
> next [re-]connect.
> 
> Note that mac80211 STAs have a workaround for this, but it requires
> access to internal cfg80211 data, see ieee80211_chswitch_work:
> 
> 	/* XXX: shouldn't really modify cfg80211-owned data! */
> 	ifmgd->associated->channel = sdata->csa_chandef.chan;
> 
> This patch suggests to convert mac80211 workaround to cfg80211 behavior
> and to update current bss channel in cfg80211_ch_switch_notify.
> 
> Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
> 
> ---
> 
> This issue has been observed for both qtnfmac and brcmfmac. Fix tested
> for qtnfmac and iwlwifi, to make sure there is no regression for mac80211.
> However this is not going to be enough to fix brcmfmac behavior as it
> does not use cfg80211_ch_switch_notify. This issue may also affect
> ath6kl and mwifiex, but I have no hardware to check.

Yeah, I think this makes sense.

> +	if (wdev->iftype == NL80211_IFTYPE_STATION) {
> +		if (wdev->current_bss)
> +			wdev->current_bss->pub.channel = chandef->chan;
> +	}

Maybe do

	if (wdev->iftype == ... &&
	    !WARN_ON(!wdev->current_bss))
		wdev->current_bss->... = ...

I worry slightly about locking too, since there's no protection on the
wdev->current_bss pointer here.

johannes


^ permalink raw reply

* Re: [PATCH 03/11] nl80211: copy the length of dst of src in nl80211_notify_radar_detection()
From: Johannes Berg @ 2019-03-23 12:34 UTC (permalink / raw)
  To: Luca Coelho; +Cc: linux-wireless, Luca Coelho
In-Reply-To: <20190315153907.16192-4-luca@coelho.fi>

On Fri, 2019-03-15 at 17:38 +0200, Luca Coelho wrote:
> From: Luca Coelho <luciano.coelho@intel.com>
> 
> It is generally safer to copy the length of the destination instead of
> the length of the source, because if the sizes don't match, it's
> usually better to leak some data from the source than to write data
> out of bounds in the destination.
> 
> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
> ---
>  net/wireless/nl80211.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 25a9e3b5c154..239be0e2f9e1 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -8061,7 +8061,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,
>  
>  	cfg80211_sched_dfs_chan_update(rdev);
>  
> -	memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
> +	memcpy(&rdev->radar_chandef, &chandef, sizeof(rdev->radar_chandef));

I think we're better off doing a struct assignment here.

johannes


^ permalink raw reply

* [PATCH] mac80211_hwsim: calculate if_combination.max_interfaces
From: Johannes Berg @ 2019-03-23 12:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

If we just set this to 2048, and have multiple limits you
can select from, the total number might run over and cause
a warning in cfg80211. This doesn't make sense, so we just
calculate the total max_interfaces now.

Reported-by: syzbot+8f91bd563bbff230d0ee@syzkaller.appspotmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/mac80211_hwsim.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 77bce2d27841..1fe94dfee5c6 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2644,7 +2644,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 	enum nl80211_band band;
 	const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
 	struct net *net;
-	int idx;
+	int idx, i;
 	int n_limits = 0;
 
 	if (WARN_ON(param->channels > 1 && !param->use_chanctx))
@@ -2768,8 +2768,12 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 		goto failed_hw;
 	}
 
+	data->if_combination.max_interfaces = 0;
+	for (i = 0; i < n_limits; i++)
+		data->if_combination.max_interfaces +=
+			data->if_limits[n_limits].max;
+
 	data->if_combination.n_limits = n_limits;
-	data->if_combination.max_interfaces = 2048;
 	data->if_combination.limits = data->if_limits;
 
 	hw->wiphy->iface_combinations = &data->if_combination;
-- 
2.17.2


^ permalink raw reply related

* [PATCH v2] rsi: Fix NULL pointer dereference in kmalloc
From: Aditya Pakki @ 2019-03-23 20:49 UTC (permalink / raw)
  To: pakki001
  Cc: kjlu, Amitkumar Karwar, Siva Rebbagondla, Kalle Valo,
	David S. Miller, linux-wireless, netdev, linux-kernel

kmalloc can fail in rsi_register_rates_channels but memcpy still attempts
to write to channels. The patch replaces these calls with kmemdup and
passes the error upstream.

Signed-off-by: Aditya Pakki <pakki001@umn.edu>

---
v1: Fix kmalloc failure by displaying a message. Change it to return the
error upstream, suggested by Joe, Johannes.
---
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 30 ++++++++++++---------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 831046e760f8..49df3bb08d41 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -188,27 +188,27 @@ bool rsi_is_cipher_wep(struct rsi_common *common)
  * @adapter: Pointer to the adapter structure.
  * @band: Operating band to be set.
  *
- * Return: None.
+ * Return: int - 0 on success, negative error on failure.
  */
-static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
+static int rsi_register_rates_channels(struct rsi_hw *adapter, int band)
 {
 	struct ieee80211_supported_band *sbands = &adapter->sbands[band];
 	void *channels = NULL;
 
 	if (band == NL80211_BAND_2GHZ) {
-		channels = kmalloc(sizeof(rsi_2ghz_channels), GFP_KERNEL);
-		memcpy(channels,
-		       rsi_2ghz_channels,
-		       sizeof(rsi_2ghz_channels));
+		channels = kmemdup(rsi_2ghz_channels, sizeof(rsi_2ghz_channels),
+				   GFP_KERNEL);
+		if (!channels)
+			return -ENOMEM;
 		sbands->band = NL80211_BAND_2GHZ;
 		sbands->n_channels = ARRAY_SIZE(rsi_2ghz_channels);
 		sbands->bitrates = rsi_rates;
 		sbands->n_bitrates = ARRAY_SIZE(rsi_rates);
 	} else {
-		channels = kmalloc(sizeof(rsi_5ghz_channels), GFP_KERNEL);
-		memcpy(channels,
-		       rsi_5ghz_channels,
-		       sizeof(rsi_5ghz_channels));
+		channels = kmemdup(rsi_5ghz_channels, sizeof(rsi_5ghz_channels),
+				   GFP_KERNEL);
+		if (!channels)
+			return -ENOMEM;
 		sbands->band = NL80211_BAND_5GHZ;
 		sbands->n_channels = ARRAY_SIZE(rsi_5ghz_channels);
 		sbands->bitrates = &rsi_rates[4];
@@ -227,6 +227,7 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
 	sbands->ht_cap.mcs.rx_mask[0] = 0xff;
 	sbands->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
 	/* sbands->ht_cap.mcs.rx_highest = 0x82; */
+	return 0;
 }
 
 static int rsi_mac80211_hw_scan_start(struct ieee80211_hw *hw,
@@ -2064,11 +2065,16 @@ int rsi_mac80211_attach(struct rsi_common *common)
 	wiphy->available_antennas_rx = 1;
 	wiphy->available_antennas_tx = 1;
 
-	rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
+	status = rsi_register_rates_channels(adapter, NL80211_BAND_2GHZ);
+	if (status)
+		return status;
 	wiphy->bands[NL80211_BAND_2GHZ] =
 		&adapter->sbands[NL80211_BAND_2GHZ];
 	if (common->num_supp_bands > 1) {
-		rsi_register_rates_channels(adapter, NL80211_BAND_5GHZ);
+		status = rsi_register_rates_channels(adapter,
+						     NL80211_BAND_5GHZ);
+		if (status)
+			return status;
 		wiphy->bands[NL80211_BAND_5GHZ] =
 			&adapter->sbands[NL80211_BAND_5GHZ];
 	}
-- 
2.17.1


^ permalink raw reply related

* [PATCH] net: mwifiex: fix a missing check of ssid
From: Kangjie Lu @ 2019-03-23 22:33 UTC (permalink / raw)
  To: kjlu
  Cc: pakki001, Amitkumar Karwar, Nishant Sarmukadam, Ganapathi Bhat,
	Xinming Hu, Kalle Valo, David S. Miller, linux-wireless, netdev,
	linux-kernel

sme->ssid may be invalid and thus should be checked.

The fix adds such a check and returns an error if it is invalid.

Signed-off-by: Kangjie Lu <kjlu@umn.edu>
---
 drivers/net/wireless/marvell/mwifiex/cfg80211.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index c46f0a54a0c7..a46820cf609f 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2343,6 +2343,12 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	struct mwifiex_adapter *adapter = priv->adapter;
 	int ret;
 
+	if (!sme->ssid) {
+		mwifiex_dbg(adapter, ERROR,
+			    "%s: Invalid ssid\n", dev->name);
+		return -EOPNOTSUPP;
+	}
+
 	if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
 		mwifiex_dbg(adapter, ERROR,
 			    "%s: reject infra assoc request in non-STA role\n",
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH v2 00/12] mt76x02: AP support for USB with PS
From: Felix Fietkau @ 2019-03-24  7:23 UTC (permalink / raw)
  To: Stanislaw Gruszka, linux-wireless; +Cc: Lorenzo Bianconi
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>

On 2019-03-19 11:37, Stanislaw Gruszka wrote:
> On USB we do not have available PSD queue. Using standard AC queues is
> unreliable for sending PS buffered frames, stations can go sleep again
> before frames are sent. Only reliable way I could find to sent broadcast
> PS buffered frames is put them into beacon data registers, then frames
> are sent just after proper beacon. HW do the work when we encrypt the 
> frames in software.
> 
> I tested functionality used arping to iwlwifi station that do
> aggressive PS, it works like this:
> 
> # arping -c 1 -I wlan0 192.168.9.110 
> ARPING 192.168.9.110 from 192.168.9.1 wlan0
> Unicast reply from 192.168.9.110 [4C:34:88:5E:76:D5]  324.885ms
> Sent 1 probes (1 broadcast(s))
> 
> Otherwise arping fails:
> 
> # arping -c 1 -I wlan0 192.168.9.110 
> ARPING 192.168.9.110 from 192.168.1.148 wlan0
> Sent 1 probes (1 broadcast(s))
> Received 0 response(s)
> 
> Tested on MT7610U and MT7630E (on this device TX hang
> in AP mode on 2.4GHz band, but this is not related to this
> patch set).
Applied, thanks.

- Felix

^ permalink raw reply

* Re: [PATCH 00/12] mt76usb: some cleanups and optimizations
From: Felix Fietkau @ 2019-03-24  7:25 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, linux-wireless
In-Reply-To: <20190321152537.19105-1-sgruszka@redhat.com>

On 2019-03-21 16:25, Stanislaw Gruszka wrote:
> Significant change is remove mt76u_buf and use urb directly
> and allocate urb and sg as linear data for better cache usage.
> Other that that, set consist only of some minor cleanups.
> 
> RFC -> v1:
> - introduce mt76u_tx_setup_buffers
> - calculate data_len differently
> - fix *usb->sg bug on intermediate patches
> - use (struct scatterlist *)(e->urb + 1) trick
> 
> Rebased on latest tree and 
> [PATCH v2 00/12] mt76x02: AP support for USB with PS
> https://lore.kernel.org/linux-wireless/1552991867-5087-1-git-send-email-sgruszka@redhat.com/
>   
> Not rebased on
> [PATCH 1/6] mt76: use mac80211 txq scheduling
> https://lore.kernel.org/linux-wireless/20190316204242.73560-1-nbd@nbd.name/
> It easer to rebase '[PATCH 5/6] mt76: move tx tasklet to struct mt76_dev'
> from that set of top of my 2 pending sets. 
Applied, thanks.

- Felix

^ permalink raw reply

* [mac80211-next:netlink-validate-build-test-2 3/7] net/sched/act_tunnel_key.c:128:8: error: implicit declaration of function 'nla_validate'; did you mean '__nla_validate'?
From: kbuild test robot @ 2019-03-24  8:45 UTC (permalink / raw)
  To: Johannes Berg; +Cc: kbuild-all, linux-wireless

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

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git netlink-validate-build-test-2
head:   eefd811df5bc7a7ad129ce4ac3ff473802736ad9
commit: 1217489aab75c491228eeb01ebbceabd29e989cc [3/7] netlink: make validation more configurable for future strictness
config: i386-randconfig-i2-201912 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        git checkout 1217489aab75c491228eeb01ebbceabd29e989cc
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   net/sched/act_tunnel_key.c: In function 'tunnel_key_copy_opts':
>> net/sched/act_tunnel_key.c:128:8: error: implicit declaration of function 'nla_validate'; did you mean '__nla_validate'? [-Werror=implicit-function-declaration]
     err = nla_validate(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
           ^~~~~~~~~~~~
           __nla_validate
   cc1: some warnings being treated as errors

vim +128 net/sched/act_tunnel_key.c

0ed5269f Simon Horman 2018-06-26  121  
0ed5269f Simon Horman 2018-06-26  122  static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
0ed5269f Simon Horman 2018-06-26  123  				int dst_len, struct netlink_ext_ack *extack)
0ed5269f Simon Horman 2018-06-26  124  {
0ed5269f Simon Horman 2018-06-26  125  	int err, rem, opt_len, len = nla_len(nla), opts_len = 0;
0ed5269f Simon Horman 2018-06-26  126  	const struct nlattr *attr, *head = nla_data(nla);
0ed5269f Simon Horman 2018-06-26  127  
0ed5269f Simon Horman 2018-06-26 @128  	err = nla_validate(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
0ed5269f Simon Horman 2018-06-26  129  			   enc_opts_policy, extack);
0ed5269f Simon Horman 2018-06-26  130  	if (err)
0ed5269f Simon Horman 2018-06-26  131  		return err;
0ed5269f Simon Horman 2018-06-26  132  
0ed5269f Simon Horman 2018-06-26  133  	nla_for_each_attr(attr, head, len, rem) {
0ed5269f Simon Horman 2018-06-26  134  		switch (nla_type(attr)) {
0ed5269f Simon Horman 2018-06-26  135  		case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
0ed5269f Simon Horman 2018-06-26  136  			opt_len = tunnel_key_copy_geneve_opt(attr, dst,
0ed5269f Simon Horman 2018-06-26  137  							     dst_len, extack);
0ed5269f Simon Horman 2018-06-26  138  			if (opt_len < 0)
0ed5269f Simon Horman 2018-06-26  139  				return opt_len;
0ed5269f Simon Horman 2018-06-26  140  			opts_len += opt_len;
0ed5269f Simon Horman 2018-06-26  141  			if (dst) {
0ed5269f Simon Horman 2018-06-26  142  				dst_len -= opt_len;
0ed5269f Simon Horman 2018-06-26  143  				dst += opt_len;
0ed5269f Simon Horman 2018-06-26  144  			}
0ed5269f Simon Horman 2018-06-26  145  			break;
0ed5269f Simon Horman 2018-06-26  146  		}
0ed5269f Simon Horman 2018-06-26  147  	}
0ed5269f Simon Horman 2018-06-26  148  
0ed5269f Simon Horman 2018-06-26  149  	if (!opts_len) {
0ed5269f Simon Horman 2018-06-26  150  		NL_SET_ERR_MSG(extack, "Empty list of tunnel options");
0ed5269f Simon Horman 2018-06-26  151  		return -EINVAL;
0ed5269f Simon Horman 2018-06-26  152  	}
0ed5269f Simon Horman 2018-06-26  153  
0ed5269f Simon Horman 2018-06-26  154  	if (rem > 0) {
0ed5269f Simon Horman 2018-06-26  155  		NL_SET_ERR_MSG(extack, "Trailing data after parsing tunnel key options attributes");
0ed5269f Simon Horman 2018-06-26  156  		return -EINVAL;
0ed5269f Simon Horman 2018-06-26  157  	}
0ed5269f Simon Horman 2018-06-26  158  
0ed5269f Simon Horman 2018-06-26  159  	return opts_len;
0ed5269f Simon Horman 2018-06-26  160  }
0ed5269f Simon Horman 2018-06-26  161  

:::::: The code at line 128 was first introduced by commit
:::::: 0ed5269f9e41f495c8e9020c85f5e1644c1afc57 net/sched: add tunnel option support to act_tunnel_key

:::::: TO: Simon Horman <simon.horman@netronome.com>
:::::: CC: David S. Miller <davem@davemloft.net>

---
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: 30524 bytes --]

^ permalink raw reply

* [mac80211-next:netlink-validate-build-test-2 3/7] net/sched/act_tunnel_key.c:128:8: error: implicit declaration of function 'nla_validate'; did you mean 'key_validate'?
From: kbuild test robot @ 2019-03-24 10:35 UTC (permalink / raw)
  To: Johannes Berg; +Cc: kbuild-all, linux-wireless

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

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git netlink-validate-build-test-2
head:   eefd811df5bc7a7ad129ce4ac3ff473802736ad9
commit: 1217489aab75c491228eeb01ebbceabd29e989cc [3/7] netlink: make validation more configurable for future strictness
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout 1217489aab75c491228eeb01ebbceabd29e989cc
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

   net/sched/act_tunnel_key.c: In function 'tunnel_key_copy_opts':
>> net/sched/act_tunnel_key.c:128:8: error: implicit declaration of function 'nla_validate'; did you mean 'key_validate'? [-Werror=implicit-function-declaration]
     err = nla_validate(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
           ^~~~~~~~~~~~
           key_validate
   cc1: some warnings being treated as errors

vim +128 net/sched/act_tunnel_key.c

0ed5269f Simon Horman 2018-06-26  121  
0ed5269f Simon Horman 2018-06-26  122  static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
0ed5269f Simon Horman 2018-06-26  123  				int dst_len, struct netlink_ext_ack *extack)
0ed5269f Simon Horman 2018-06-26  124  {
0ed5269f Simon Horman 2018-06-26  125  	int err, rem, opt_len, len = nla_len(nla), opts_len = 0;
0ed5269f Simon Horman 2018-06-26  126  	const struct nlattr *attr, *head = nla_data(nla);
0ed5269f Simon Horman 2018-06-26  127  
0ed5269f Simon Horman 2018-06-26 @128  	err = nla_validate(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
0ed5269f Simon Horman 2018-06-26  129  			   enc_opts_policy, extack);
0ed5269f Simon Horman 2018-06-26  130  	if (err)
0ed5269f Simon Horman 2018-06-26  131  		return err;
0ed5269f Simon Horman 2018-06-26  132  
0ed5269f Simon Horman 2018-06-26  133  	nla_for_each_attr(attr, head, len, rem) {
0ed5269f Simon Horman 2018-06-26  134  		switch (nla_type(attr)) {
0ed5269f Simon Horman 2018-06-26  135  		case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
0ed5269f Simon Horman 2018-06-26  136  			opt_len = tunnel_key_copy_geneve_opt(attr, dst,
0ed5269f Simon Horman 2018-06-26  137  							     dst_len, extack);
0ed5269f Simon Horman 2018-06-26  138  			if (opt_len < 0)
0ed5269f Simon Horman 2018-06-26  139  				return opt_len;
0ed5269f Simon Horman 2018-06-26  140  			opts_len += opt_len;
0ed5269f Simon Horman 2018-06-26  141  			if (dst) {
0ed5269f Simon Horman 2018-06-26  142  				dst_len -= opt_len;
0ed5269f Simon Horman 2018-06-26  143  				dst += opt_len;
0ed5269f Simon Horman 2018-06-26  144  			}
0ed5269f Simon Horman 2018-06-26  145  			break;
0ed5269f Simon Horman 2018-06-26  146  		}
0ed5269f Simon Horman 2018-06-26  147  	}
0ed5269f Simon Horman 2018-06-26  148  
0ed5269f Simon Horman 2018-06-26  149  	if (!opts_len) {
0ed5269f Simon Horman 2018-06-26  150  		NL_SET_ERR_MSG(extack, "Empty list of tunnel options");
0ed5269f Simon Horman 2018-06-26  151  		return -EINVAL;
0ed5269f Simon Horman 2018-06-26  152  	}
0ed5269f Simon Horman 2018-06-26  153  
0ed5269f Simon Horman 2018-06-26  154  	if (rem > 0) {
0ed5269f Simon Horman 2018-06-26  155  		NL_SET_ERR_MSG(extack, "Trailing data after parsing tunnel key options attributes");
0ed5269f Simon Horman 2018-06-26  156  		return -EINVAL;
0ed5269f Simon Horman 2018-06-26  157  	}
0ed5269f Simon Horman 2018-06-26  158  
0ed5269f Simon Horman 2018-06-26  159  	return opts_len;
0ed5269f Simon Horman 2018-06-26  160  }
0ed5269f Simon Horman 2018-06-26  161  

:::::: The code at line 128 was first introduced by commit
:::::: 0ed5269f9e41f495c8e9020c85f5e1644c1afc57 net/sched: add tunnel option support to act_tunnel_key

:::::: TO: Simon Horman <simon.horman@netronome.com>
:::::: CC: David S. Miller <davem@davemloft.net>

---
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: 52845 bytes --]

^ permalink raw reply

* Re: wil6210 firmware version
From: merez @ 2019-03-24 12:30 UTC (permalink / raw)
  To: Robert Marko; +Cc: linux-wireless, wil6210, linux-wireless-owner
In-Reply-To: <CAOX2RU6wFpaP7Zm1MmvJTkxXL12Cz9VcWFvYTJzn=1=9g3wj9Q@mail.gmail.com>

On 2019-03-14 12:05, Robert Marko wrote:
> Biggest thing would be Channel 4 support as it is supported by driver
> but requires FW support also.
> But I would also like 20 station limit instead of 8.
> 
> Cheers
> Robert Marko

Those features are supported only on Talyn device (latest wil6210 HW), 
which is not available in market yet.

Thanks,
Maya

> 
> On Thu, 14 Mar 2019 at 11:03, <merez@codeaurora.org> wrote:
>> 
>> On 2019-03-14 11:07, Robert Marko wrote:
>> > Hi,
>> > I am working on OpenWrt support for device using wil6210 card.
>> > I am using firmware and board file provided in linux-firmware for its
>> > development but it appears tha most of newer features that driver
>> > enables are firmware dependant and version 5.2 in linux-firmware is
>> > too old to expose those.
>> >
>> > Is there any chance of QCA pushing updated version to linux-firmware?
>> >
>> > Thanks
>> > Robert Marko
>> 
>> Is there any specific feature you are interested in?
>> 
>> --
>> Maya Erez
>> Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc.
>> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
>> a
>> Linux Foundation Collaborative Project

-- 
Maya Erez
Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a 
Linux Foundation Collaborative Project

^ permalink raw reply

* Re: wil6210 firmware version
From: Robert Marko @ 2019-03-24 12:32 UTC (permalink / raw)
  To: merez; +Cc: linux-wireless, wil6210, linux-wireless-owner
In-Reply-To: <64d97528f4fb088830a5dbcd8b74e934@codeaurora.org>

Well, that was not noted anywhere.
I am sure that there are also other interesting things in newer
firmware, especially since the device that I am working on is using
6.2 FW itself in stock firmware.

On Sun, 24 Mar 2019 at 13:30, <merez@codeaurora.org> wrote:
>
> On 2019-03-14 12:05, Robert Marko wrote:
> > Biggest thing would be Channel 4 support as it is supported by driver
> > but requires FW support also.
> > But I would also like 20 station limit instead of 8.
> >
> > Cheers
> > Robert Marko
>
> Those features are supported only on Talyn device (latest wil6210 HW),
> which is not available in market yet.
>
> Thanks,
> Maya
>
> >
> > On Thu, 14 Mar 2019 at 11:03, <merez@codeaurora.org> wrote:
> >>
> >> On 2019-03-14 11:07, Robert Marko wrote:
> >> > Hi,
> >> > I am working on OpenWrt support for device using wil6210 card.
> >> > I am using firmware and board file provided in linux-firmware for its
> >> > development but it appears tha most of newer features that driver
> >> > enables are firmware dependant and version 5.2 in linux-firmware is
> >> > too old to expose those.
> >> >
> >> > Is there any chance of QCA pushing updated version to linux-firmware?
> >> >
> >> > Thanks
> >> > Robert Marko
> >>
> >> Is there any specific feature you are interested in?
> >>
> >> --
> >> Maya Erez
> >> Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc.
> >> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> >> a
> >> Linux Foundation Collaborative Project
>
> --
> Maya Erez
> Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a
> Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH 0/4] add missing bits for mt7615 support
From: Lorenzo Bianconi @ 2019-03-24 13:31 UTC (permalink / raw)
  To: nbd; +Cc: ryder.lee, roychl666, lorenzo.bianconi, linux-wireless

This is a preliminary series to add support for mt7615.
Dynamically allocate txwi descriptor.
Add missing bit in dma error data path.
This series is based on https://patchwork.kernel.org/patch/10856027/

Lorenzo Bianconi (4):
  mt76: set txwi_size according to the driver value
  mt76: add skb pointer to mt76_tx_info
  mt76: dma: introduce skb and flags fields in mt76_txwi_cache
  mt76: dma: add skb check for dummy pointer

 drivers/net/wireless/mediatek/mt76/dma.c      | 29 +++++++++++--------
 drivers/net/wireless/mediatek/mt76/dma.h      |  2 ++
 drivers/net/wireless/mediatek/mt76/mt76.h     | 19 ++++++++----
 .../net/wireless/mediatek/mt76/mt7603/mac.c   | 11 +++----
 .../wireless/mediatek/mt76/mt7603/mt7603.h    |  4 +--
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  4 +--
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  4 ++-
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c |  1 -
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c | 12 ++++----
 .../net/wireless/mediatek/mt76/mt76x02_usb.h  |  4 +--
 .../wireless/mediatek/mt76/mt76x02_usb_core.c | 18 ++++++------
 drivers/net/wireless/mediatek/mt76/tx.c       | 14 +++++----
 drivers/net/wireless/mediatek/mt76/usb.c      | 14 +++++----
 13 files changed, 80 insertions(+), 56 deletions(-)

-- 
2.20.1


^ permalink raw reply

* [PATCH 1/4] mt76: set txwi_size according to the driver value
From: Lorenzo Bianconi @ 2019-03-24 13:31 UTC (permalink / raw)
  To: nbd; +Cc: ryder.lee, roychl666, lorenzo.bianconi, linux-wireless
In-Reply-To: <cover.1553425942.git.lorenzo@kernel.org>

Dynamically allocate txwi since new chipsets will use longer txwi
descriptors

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/dma.c          |  8 +++++---
 drivers/net/wireless/mediatek/mt76/mt76.h         | 10 +++++++---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  |  4 +++-
 drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c |  1 -
 drivers/net/wireless/mediatek/mt76/tx.c           | 12 +++++++-----
 5 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 35010915697c..4ad2a457cd54 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -296,12 +296,14 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 	struct mt76_txwi_cache *t;
 	struct sk_buff *iter;
 	dma_addr_t addr;
+	u8 *txwi;
 
 	t = mt76_get_txwi(dev);
 	if (!t) {
 		ieee80211_free_txskb(dev->hw, skb);
 		return -ENOMEM;
 	}
+	txwi = mt76_get_txwi_ptr(dev, t);
 
 	skb->prev = skb->next = NULL;
 	if (dev->drv->tx_aligned4_skbs)
@@ -331,11 +333,11 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 	}
 	tx_info.nbuf = n;
 
-	dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
+	dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
 				DMA_TO_DEVICE);
-	ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, qid, wcid, sta,
+	ret = dev->drv->tx_prepare_skb(dev, txwi, skb, qid, wcid, sta,
 				       &tx_info);
-	dma_sync_single_for_device(dev->dev, t->dma_addr, sizeof(t->txwi),
+	dma_sync_single_for_device(dev->dev, t->dma_addr, dev->drv->txwi_size,
 				   DMA_TO_DEVICE);
 	if (ret < 0)
 		goto unmap;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 070353dcae4c..3391dd1cbb32 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -231,12 +231,10 @@ struct mt76_txq {
 };
 
 struct mt76_txwi_cache {
-	u32 txwi[8];
-	dma_addr_t dma_addr;
 	struct list_head list;
+	dma_addr_t dma_addr;
 };
 
-
 struct mt76_rx_tid {
 	struct rcu_head rcu_head;
 
@@ -618,6 +616,12 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
 int mt76_eeprom_init(struct mt76_dev *dev, int len);
 void mt76_eeprom_override(struct mt76_dev *dev);
 
+static inline u8 *
+mt76_get_txwi_ptr(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+{
+	return (u8 *)t - dev->drv->txwi_size;
+}
+
 /* increment with wrap-around */
 static inline int mt76_incr(int val, int size)
 {
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index e887c5c809aa..ce0af06943fb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -773,6 +773,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
 {
 	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
 	struct mt76x02_txwi *txwi;
+	u8 *txwi_ptr;
 
 	if (!e->txwi) {
 		dev_kfree_skb_any(e->skb);
@@ -781,7 +782,8 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
 
 	mt76x02_mac_poll_tx_status(dev, false);
 
-	txwi = (struct mt76x02_txwi *) &e->txwi->txwi;
+	txwi_ptr = mt76_get_txwi_ptr(mdev, e->txwi);
+	txwi = (struct mt76x02_txwi *)txwi_ptr;
 	trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid);
 
 	mt76_tx_complete_skb(mdev, e->skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 7e11ab0d7252..a7eadf947846 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -177,7 +177,6 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
 	struct mt76_queue *q;
 	void *status_fifo;
 
-	BUILD_BUG_ON(sizeof(t->txwi) < sizeof(struct mt76x02_txwi));
 	BUILD_BUG_ON(sizeof(struct mt76x02_rxwi) > MT_RX_HEADROOM);
 
 	fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x02_tx_status));
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 60bbb6561d8f..880f3ad0b254 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -21,15 +21,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
 {
 	struct mt76_txwi_cache *t;
 	dma_addr_t addr;
+	u8 *txwi;
 	int size;
 
-	size = (sizeof(*t) + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1);
-	t = devm_kzalloc(dev->dev, size, GFP_ATOMIC);
-	if (!t)
+	size = L1_CACHE_ALIGN(dev->drv->txwi_size + sizeof(*t));
+	txwi = devm_kzalloc(dev->dev, size, GFP_ATOMIC);
+	if (!txwi)
 		return NULL;
 
-	addr = dma_map_single(dev->dev, &t->txwi, sizeof(t->txwi),
+	addr = dma_map_single(dev->dev, txwi, dev->drv->txwi_size,
 			      DMA_TO_DEVICE);
+	t = (struct mt76_txwi_cache *)(txwi + dev->drv->txwi_size);
 	t->dma_addr = addr;
 
 	return t;
@@ -78,7 +80,7 @@ void mt76_tx_free(struct mt76_dev *dev)
 	struct mt76_txwi_cache *t;
 
 	while ((t = __mt76_get_txwi(dev)) != NULL)
-		dma_unmap_single(dev->dev, t->dma_addr, sizeof(t->txwi),
+		dma_unmap_single(dev->dev, t->dma_addr, dev->drv->txwi_size,
 				 DMA_TO_DEVICE);
 }
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH 2/4] mt76: add skb pointer to mt76_tx_info
From: Lorenzo Bianconi @ 2019-03-24 13:31 UTC (permalink / raw)
  To: nbd; +Cc: ryder.lee, roychl666, lorenzo.bianconi, linux-wireless
In-Reply-To: <cover.1553425942.git.lorenzo@kernel.org>

Pass skb pointer to tx_prepare_skb through mt76_tx_info data structure.
This is a preliminary patch to properly support dma error path for
new chipsets (e.g. 7615)

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/dma.c       | 11 ++++++-----
 drivers/net/wireless/mediatek/mt76/mt76.h      |  4 ++--
 .../net/wireless/mediatek/mt76/mt7603/mac.c    | 11 ++++++-----
 .../net/wireless/mediatek/mt76/mt7603/mt7603.h |  4 ++--
 drivers/net/wireless/mediatek/mt76/mt76x02.h   |  4 ++--
 .../net/wireless/mediatek/mt76/mt76x02_txrx.c  | 12 ++++++------
 .../net/wireless/mediatek/mt76/mt76x02_usb.h   |  4 ++--
 .../wireless/mediatek/mt76/mt76x02_usb_core.c  | 18 +++++++++---------
 drivers/net/wireless/mediatek/mt76/usb.c       | 14 ++++++++------
 9 files changed, 43 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 4ad2a457cd54..f4c2dd5366bc 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -290,7 +290,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 		      struct ieee80211_sta *sta)
 {
 	struct mt76_queue *q = dev->q_tx[qid].q;
-	struct mt76_tx_info tx_info = {};
+	struct mt76_tx_info tx_info = {
+		.skb = skb,
+	};
 	int len, n = 0, ret = -ENOMEM;
 	struct mt76_queue_entry e;
 	struct mt76_txwi_cache *t;
@@ -335,8 +337,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 
 	dma_sync_single_for_cpu(dev->dev, t->dma_addr, dev->drv->txwi_size,
 				DMA_TO_DEVICE);
-	ret = dev->drv->tx_prepare_skb(dev, txwi, skb, qid, wcid, sta,
-				       &tx_info);
+	ret = dev->drv->tx_prepare_skb(dev, txwi, qid, wcid, sta, &tx_info);
 	dma_sync_single_for_device(dev->dev, t->dma_addr, dev->drv->txwi_size,
 				   DMA_TO_DEVICE);
 	if (ret < 0)
@@ -348,7 +349,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 	}
 
 	return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
-				tx_info.info, skb, t);
+				tx_info.info, tx_info.skb, t);
 
 unmap:
 	for (n--; n > 0; n--)
@@ -356,7 +357,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 				 tx_info.buf[n].len, DMA_TO_DEVICE);
 
 free:
-	e.skb = skb;
+	e.skb = tx_info.skb;
 	e.txwi = t;
 	dev->drv->tx_complete_skb(dev, qid, &e);
 	mt76_put_txwi(dev, t);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 3391dd1cbb32..0d7ae7c5ceba 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -85,6 +85,7 @@ struct mt76_queue_buf {
 
 struct mt76_tx_info {
 	struct mt76_queue_buf buf[32];
+	struct sk_buff *skb;
 	int nbuf;
 	u32 info;
 };
@@ -293,8 +294,7 @@ struct mt76_driver_ops {
 	void (*update_survey)(struct mt76_dev *dev);
 
 	int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr,
-			      struct sk_buff *skb, enum mt76_txq_id qid,
-			      struct mt76_wcid *wcid,
+			      enum mt76_txq_id qid, struct mt76_wcid *wcid,
 			      struct ieee80211_sta *sta,
 			      struct mt76_tx_info *tx_info);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 1d6e2ba5925e..e49816942604 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -941,13 +941,13 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
 }
 
 int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
-			  struct sk_buff *skb, enum mt76_txq_id qid,
-			  struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+			  enum mt76_txq_id qid, struct mt76_wcid *wcid,
+			  struct ieee80211_sta *sta,
 			  struct mt76_tx_info *tx_info)
 {
 	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
 	struct mt7603_sta *msta = container_of(wcid, struct mt7603_sta, wcid);
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
 	struct ieee80211_key_conf *key = info->control.hw_key;
 	int pid;
 
@@ -963,7 +963,7 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 			mt7603_wtbl_set_ps(dev, msta, false);
 	}
 
-	pid = mt76_tx_status_skb_add(mdev, wcid, skb);
+	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
 
 	if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) {
 		spin_lock_bh(&dev->mt76.lock);
@@ -973,7 +973,8 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 		spin_unlock_bh(&dev->mt76.lock);
 	}
 
-	mt7603_mac_write_txwi(dev, txwi_ptr, skb, qid, wcid, sta, pid, key);
+	mt7603_mac_write_txwi(dev, txwi_ptr, tx_info->skb, qid, wcid,
+			      sta, pid, key);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 1559ca122b9a..ddc302609ed1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -221,8 +221,8 @@ void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
 void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort);
 
 int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
-			  struct sk_buff *skb, enum mt76_txq_id qid,
-			  struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+			  enum mt76_txq_id qid, struct mt76_wcid *wcid,
+			  struct ieee80211_sta *sta,
 			  struct mt76_tx_info *tx_info);
 
 void mt7603_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 850502b89caf..3f3868ae7f30 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -183,8 +183,8 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance);
 void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
 		struct sk_buff *skb);
 int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
-			   struct sk_buff *skb, enum mt76_txq_id qid,
-			   struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+			   enum mt76_txq_id qid, struct mt76_wcid *wcid,
+			   struct ieee80211_sta *sta,
 			   struct mt76_tx_info *tx_info);
 void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		     const u8 *mac);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index dd7d04b9b8db..cf7abd9b7d2e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -147,12 +147,12 @@ bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update)
 EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);
 
 int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
-			   struct sk_buff *skb, enum mt76_txq_id qid,
-			   struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+			   enum mt76_txq_id qid, struct mt76_wcid *wcid,
+			   struct ieee80211_sta *sta,
 			   struct mt76_tx_info *tx_info)
 {
 	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
 	struct mt76x02_txwi *txwi = txwi_ptr;
 	int hdrlen, len, pid, qsel = MT_QSEL_EDCA;
 
@@ -160,10 +160,10 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 		mt76x02_mac_wcid_set_drop(dev, wcid->idx, false);
 
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
-	len = skb->len - (hdrlen & 2);
-	mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
+	len = tx_info->skb->len - (hdrlen & 2);
+	mt76x02_mac_write_txwi(dev, txwi, tx_info->skb, wcid, sta, len);
 
-	pid = mt76_tx_status_skb_add(mdev, wcid, skb);
+	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
 	txwi->pktid = pid;
 
 	if (pid >= MT_PACKET_ID_FIRST)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
index a012410c5ae7..7b53f9e57f29 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
@@ -26,8 +26,8 @@ int mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, const void *data,
 
 int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags);
 int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
-			    struct sk_buff *skb, enum mt76_txq_id qid,
-			    struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+			    enum mt76_txq_id qid, struct mt76_wcid *wcid,
+			    struct ieee80211_sta *sta,
 			    struct mt76_tx_info *tx_info);
 void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
 			      struct mt76_queue_entry *e);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index c403218533da..818b96064dec 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -72,23 +72,23 @@ int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags)
 }
 
 int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
-			    struct sk_buff *skb, enum mt76_txq_id qid,
-			    struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+			    enum mt76_txq_id qid, struct mt76_wcid *wcid,
+			    struct ieee80211_sta *sta,
 			    struct mt76_tx_info *tx_info)
 {
 	struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
-	int pid, len = skb->len, ep = q2ep(mdev->q_tx[qid].q->hw_idx);
+	int pid, len = tx_info->skb->len, ep = q2ep(mdev->q_tx[qid].q->hw_idx);
 	struct mt76x02_txwi *txwi;
 	enum mt76_qsel qsel;
 	u32 flags;
 
-	mt76_insert_hdr_pad(skb);
+	mt76_insert_hdr_pad(tx_info->skb);
 
-	txwi = (struct mt76x02_txwi *)(skb->data - sizeof(struct mt76x02_txwi));
-	mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
-	skb_push(skb, sizeof(struct mt76x02_txwi));
+	txwi = (struct mt76x02_txwi *)(tx_info->skb->data - sizeof(*txwi));
+	mt76x02_mac_write_txwi(dev, txwi, tx_info->skb, wcid, sta, len);
+	skb_push(tx_info->skb, sizeof(*txwi));
 
-	pid = mt76_tx_status_skb_add(mdev, wcid, skb);
+	pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
 	txwi->pktid = pid;
 
 	if (pid >= MT_PACKET_ID_FIRST || ep == MT_EP_OUT_HCCA)
@@ -101,7 +101,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
 	if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv)
 		flags |= MT_TXD_INFO_WIV;
 
-	return mt76x02u_skb_dma_info(skb, WLAN_PORT, flags);
+	return mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
 }
 EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);
 
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 277d85cd6d5e..1e40c9bb5d5a 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -734,7 +734,9 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 		   struct ieee80211_sta *sta)
 {
 	struct mt76_queue *q = dev->q_tx[qid].q;
-	struct urb *urb;
+	struct mt76_tx_info tx_info = {
+		.skb = skb,
+	};
 	u16 idx = q->tail;
 	int err;
 
@@ -742,20 +744,20 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 		return -ENOSPC;
 
 	skb->prev = skb->next = NULL;
-	err = dev->drv->tx_prepare_skb(dev, NULL, skb, qid, wcid, sta, NULL);
+	err = dev->drv->tx_prepare_skb(dev, NULL, qid, wcid, sta, &tx_info);
 	if (err < 0)
 		return err;
 
-	urb = q->entry[idx].urb;
-	err = mt76u_tx_setup_buffers(dev, skb, urb);
+	err = mt76u_tx_setup_buffers(dev, tx_info.skb, q->entry[idx].urb);
 	if (err < 0)
 		return err;
 
 	mt76u_fill_bulk_urb(dev, USB_DIR_OUT, q2ep(q->hw_idx),
-			    urb, mt76u_complete_tx, &q->entry[idx]);
+			    q->entry[idx].urb, mt76u_complete_tx,
+			    &q->entry[idx]);
 
 	q->tail = (q->tail + 1) % q->ndesc;
-	q->entry[idx].skb = skb;
+	q->entry[idx].skb = tx_info.skb;
 	q->queued++;
 
 	return idx;
-- 
2.20.1


^ permalink raw reply related

* [PATCH 3/4] mt76: dma: introduce skb and flags fields in mt76_txwi_cache
From: Lorenzo Bianconi @ 2019-03-24 13:31 UTC (permalink / raw)
  To: nbd; +Cc: ryder.lee, roychl666, lorenzo.bianconi, linux-wireless
In-Reply-To: <cover.1553425942.git.lorenzo@kernel.org>

Introduce skb and flags fields in mt76_txwi_cache since new chipsets
will release mt76_txwi_cache/skbs at tx completion instead of dma one.
This is a preliminary patch to add mt7615 support

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/dma.c  | 3 ++-
 drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++++
 drivers/net/wireless/mediatek/mt76/tx.c   | 2 ++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index f4c2dd5366bc..8302ebd89338 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -174,7 +174,8 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
 			dev->drv->tx_complete_skb(dev, qid, &entry);
 
 		if (entry.txwi) {
-			mt76_put_txwi(dev, entry.txwi);
+			if (!(entry.txwi->flags & MT_TXWI_NO_FREE))
+				mt76_put_txwi(dev, entry.txwi);
 			wake = !flush;
 		}
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 0d7ae7c5ceba..f024ccfcf139 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -231,9 +231,13 @@ struct mt76_txq {
 	bool aggr;
 };
 
+#define MT_TXWI_NO_FREE			BIT(0)
 struct mt76_txwi_cache {
 	struct list_head list;
 	dma_addr_t dma_addr;
+
+	struct sk_buff *skb;
+	u32 flags;
 };
 
 struct mt76_rx_tid {
@@ -289,6 +293,7 @@ struct mt76_hw_cap {
 
 struct mt76_driver_ops {
 	bool tx_aligned4_skbs;
+	u32 txwi_flags;
 	u16 txwi_size;
 
 	void (*update_survey)(struct mt76_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 880f3ad0b254..f00782f05c62 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -32,6 +32,7 @@ mt76_alloc_txwi(struct mt76_dev *dev)
 	addr = dma_map_single(dev->dev, txwi, dev->drv->txwi_size,
 			      DMA_TO_DEVICE);
 	t = (struct mt76_txwi_cache *)(txwi + dev->drv->txwi_size);
+	t->flags = dev->drv->txwi_flags;
 	t->dma_addr = addr;
 
 	return t;
@@ -74,6 +75,7 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
 	list_add(&t->list, &dev->txwi_cache);
 	spin_unlock_bh(&dev->lock);
 }
+EXPORT_SYMBOL_GPL(mt76_put_txwi);
 
 void mt76_tx_free(struct mt76_dev *dev)
 {
-- 
2.20.1


^ permalink raw reply related

* [PATCH 4/4] mt76: dma: add skb check for dummy pointer
From: Lorenzo Bianconi @ 2019-03-24 13:31 UTC (permalink / raw)
  To: nbd; +Cc: ryder.lee, roychl666, lorenzo.bianconi, linux-wireless
In-Reply-To: <cover.1553425942.git.lorenzo@kernel.org>

Introduce skb check for dummy address in mt76_dma_tx_cleanup_idx.
This is a preliminary patch to add support for new chipsets (e.g. 7615)

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/dma.c | 9 +++++----
 drivers/net/wireless/mediatek/mt76/dma.h | 2 ++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 8302ebd89338..8a4b935d03b2 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -18,8 +18,6 @@
 #include "mt76.h"
 #include "dma.h"
 
-#define DMA_DUMMY_TXWI	((void *) ~0)
-
 static int
 mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
 		     int idx, int n_desc, int bufsize,
@@ -67,7 +65,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
 	int i, idx = -1;
 
 	if (txwi)
-		q->entry[q->head].txwi = DMA_DUMMY_TXWI;
+		q->entry[q->head].txwi = DMA_DUMMY_DATA;
 
 	for (i = 0; i < nbufs; i += 2, buf += 2) {
 		u32 buf0 = buf[0].addr, buf1 = 0;
@@ -126,9 +124,12 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx,
 				 DMA_TO_DEVICE);
 	}
 
-	if (e->txwi == DMA_DUMMY_TXWI)
+	if (e->txwi == DMA_DUMMY_DATA)
 		e->txwi = NULL;
 
+	if (e->skb == DMA_DUMMY_DATA)
+		e->skb = NULL;
+
 	*prev_e = *e;
 	memset(e, 0, sizeof(*e));
 }
diff --git a/drivers/net/wireless/mediatek/mt76/dma.h b/drivers/net/wireless/mediatek/mt76/dma.h
index e3292df5e9b2..03dd2bafa4e8 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.h
+++ b/drivers/net/wireless/mediatek/mt76/dma.h
@@ -16,6 +16,8 @@
 #ifndef __MT76_DMA_H
 #define __MT76_DMA_H
 
+#define DMA_DUMMY_DATA			((void *)~0)
+
 #define MT_RING_SIZE			0x10
 
 #define MT_DMA_CTL_SD_LEN1		GENMASK(13, 0)
-- 
2.20.1


^ permalink raw reply related

* [PATCH] mt76: usb: reduce locking in mt76u_tx_tasklet
From: Lorenzo Bianconi @ 2019-03-24 14:51 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, sgruszka
In-Reply-To: <cover.1553437543.git.lorenzo@kernel.org>

Similar to pci counterpart, reduce locking in mt76u_tx_tasklet since
q->head is managed just in mt76u_tx_tasklet and q->queued is updated
holding q->lock

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes since RFC:
- reset done to false in mt76u_tx_tasklet instead of in mt76u_tx_queue_skb
---
 drivers/net/wireless/mediatek/mt76/usb.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 15aeda0582e7..f06112180694 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -624,28 +624,35 @@ static void mt76u_tx_tasklet(unsigned long data)
 	int i;
 
 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+		u32 n_queued = 0, n_sw_queued = 0;
+		int idx;
+
 		sq = &dev->q_tx[i];
 		q = sq->q;
 
-		spin_lock_bh(&q->lock);
-		while (true) {
-			if (!q->entry[q->head].done || !q->queued)
+		while (q->queued > n_queued) {
+			if (!q->entry[q->head].done)
 				break;
 
 			if (q->entry[q->head].schedule) {
 				q->entry[q->head].schedule = false;
-				sq->swq_queued--;
+				n_sw_queued++;
 			}
 
+			idx = q->head;
 			entry = q->entry[q->head];
 			q->head = (q->head + 1) % q->ndesc;
-			q->queued--;
+			n_queued++;
 
-			spin_unlock_bh(&q->lock);
 			dev->drv->tx_complete_skb(dev, i, &entry);
-			spin_lock_bh(&q->lock);
+			q->entry[idx].done = false;
 		}
 
+		spin_lock_bh(&q->lock);
+
+		sq->swq_queued -= n_sw_queued;
+		q->queued -= n_queued;
+
 		wake = q->stopped && q->queued < q->ndesc - 8;
 		if (wake)
 			q->stopped = false;
@@ -741,7 +748,6 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
 	if (err < 0)
 		return err;
 
-	q->entry[idx].done = false;
 	urb = q->entry[idx].urb;
 	err = mt76u_tx_setup_buffers(dev, skb, urb);
 	if (err < 0)
-- 
2.20.1


^ permalink raw reply related

* [PATCH] nfc: fix a NULL pointer dereference
From: Kangjie Lu @ 2019-03-24 23:06 UTC (permalink / raw)
  To: kjlu; +Cc: pakki001, Samuel Ortiz, linux-wireless, linux-kernel

In case devm_kzalloc, the fix returns -ENOMEM to avoid the NULL
pointer dereference.

Signed-off-by: Kangjie Lu <kjlu@umn.edu>
---
 drivers/nfc/st21nfca/se.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c
index 4bed9e842db3..fd967a38a94a 100644
--- a/drivers/nfc/st21nfca/se.c
+++ b/drivers/nfc/st21nfca/se.c
@@ -328,6 +328,8 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host,
 
 		transaction = (struct nfc_evt_transaction *)devm_kzalloc(dev,
 						   skb->len - 2, GFP_KERNEL);
+		if (!transaction)
+			return -ENOMEM;
 
 		transaction->aid_len = skb->data[1];
 		memcpy(transaction->aid, &skb->data[2],
-- 
2.17.1


^ permalink raw reply related

* [PATCH] mac80211: when using iTXQ, select the queue in ieee80211_subif_start_xmit
From: Felix Fietkau @ 2019-03-25  7:59 UTC (permalink / raw)
  To: linux-wireless; +Cc: johannes

When using iTXQ, the network stack does not need the real queue number, since
mac80211 is using its internal queues anyway. In that case we can defer
selecting the queue and remove a redundant station lookup in the tx path to save
some CPU cycles.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 net/mac80211/tx.c  | 11 ++++++-
 net/mac80211/wme.c | 82 +++++++++++++++++++++++++---------------------
 net/mac80211/wme.h |  2 ++
 3 files changed, 56 insertions(+), 39 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e22de40a7790..e9d4a811ddce 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3790,6 +3790,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
 				  u32 info_flags)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = sdata->local;
 	struct sta_info *sta;
 	struct sk_buff *next;
 
@@ -3803,7 +3804,15 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
 	if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
 		goto out_free;
 
-	if (!IS_ERR_OR_NULL(sta)) {
+	if (IS_ERR(sta))
+		sta = NULL;
+
+	if (local->ops->wake_tx_queue) {
+		u16 queue = __ieee80211_select_queue(sdata, sta, skb);
+		skb_set_queue_mapping(skb, queue);
+	}
+
+	if (sta) {
 		struct ieee80211_fast_tx *fast_tx;
 
 		sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 5f7c96368b11..6a3187883c4b 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -141,6 +141,42 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
 	return ieee80211_downgrade_queue(sdata, NULL, skb);
 }
 
+u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
+			     struct sta_info *sta, struct sk_buff *skb)
+{
+	struct mac80211_qos_map *qos_map;
+	bool qos;
+
+	/* all mesh/ocb stations are required to support WME */
+	if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
+	    sdata->vif.type == NL80211_IFTYPE_OCB)
+		qos = true;
+	else if (sta)
+		qos = sta->sta.wme;
+	else
+		qos = false;
+
+	if (!qos) {
+		skb->priority = 0; /* required for correct WPA/11i MIC */
+		return IEEE80211_AC_BE;
+	}
+
+	if (skb->protocol == sdata->control_port_protocol) {
+		skb->priority = 7;
+		goto downgrade;
+	}
+
+	/* use the data classifier to determine what 802.1d tag the
+	 * data frame has */
+	qos_map = rcu_dereference(sdata->qos_map);
+	skb->priority = cfg80211_classify8021d(skb, qos_map ?
+					       &qos_map->qos_map : NULL);
+
+ downgrade:
+	return ieee80211_downgrade_queue(sdata, sta, skb);
+}
+
+
 /* Indicate which queue to use. */
 u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
 			   struct sk_buff *skb)
@@ -148,10 +184,12 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_local *local = sdata->local;
 	struct sta_info *sta = NULL;
 	const u8 *ra = NULL;
-	bool qos = false;
-	struct mac80211_qos_map *qos_map;
 	u16 ret;
 
+	/* when using iTXQ, we can do this later */
+	if (local->ops->wake_tx_queue)
+		return 0;
+
 	if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
 		skb->priority = 0; /* required for correct WPA/11i MIC */
 		return 0;
@@ -161,10 +199,8 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
 	switch (sdata->vif.type) {
 	case NL80211_IFTYPE_AP_VLAN:
 		sta = rcu_dereference(sdata->u.vlan.sta);
-		if (sta) {
-			qos = sta->sta.wme;
+		if (sta)
 			break;
-		}
 		/* fall through */
 	case NL80211_IFTYPE_AP:
 		ra = skb->data;
@@ -172,56 +208,26 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
 	case NL80211_IFTYPE_WDS:
 		ra = sdata->u.wds.remote_addr;
 		break;
-#ifdef CONFIG_MAC80211_MESH
-	case NL80211_IFTYPE_MESH_POINT:
-		qos = true;
-		break;
-#endif
 	case NL80211_IFTYPE_STATION:
 		/* might be a TDLS station */
 		sta = sta_info_get(sdata, skb->data);
 		if (sta)
-			qos = sta->sta.wme;
+			break;
 
 		ra = sdata->u.mgd.bssid;
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		ra = skb->data;
 		break;
-	case NL80211_IFTYPE_OCB:
-		/* all stations are required to support WME */
-		qos = true;
-		break;
 	default:
 		break;
 	}
 
-	if (!sta && ra && !is_multicast_ether_addr(ra)) {
+	if (!sta && ra && !is_multicast_ether_addr(ra))
 		sta = sta_info_get(sdata, ra);
-		if (sta)
-			qos = sta->sta.wme;
-	}
 
-	if (!qos) {
-		skb->priority = 0; /* required for correct WPA/11i MIC */
-		ret = IEEE80211_AC_BE;
-		goto out;
-	}
+	ret = __ieee80211_select_queue(sdata, sta, skb);
 
-	if (skb->protocol == sdata->control_port_protocol) {
-		skb->priority = 7;
-		goto downgrade;
-	}
-
-	/* use the data classifier to determine what 802.1d tag the
-	 * data frame has */
-	qos_map = rcu_dereference(sdata->qos_map);
-	skb->priority = cfg80211_classify8021d(skb, qos_map ?
-					       &qos_map->qos_map : NULL);
-
- downgrade:
-	ret = ieee80211_downgrade_queue(sdata, sta, skb);
- out:
 	rcu_read_unlock();
 	return ret;
 }
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index 80151edc5195..b1b1439cb91b 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -16,6 +16,8 @@
 u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
 				 struct sk_buff *skb,
 				 struct ieee80211_hdr *hdr);
+u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
+			     struct sta_info *sta, struct sk_buff *skb);
 u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
 			   struct sk_buff *skb);
 void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
-- 
2.17.0


^ permalink raw reply related

* [PATCH] mac80211: HE: add Spatial Reuse IE parsing support
From: John Crispin @ 2019-03-25  8:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, John Crispin

Add support to mac80211 for parsing SPR IEs as per
P802.11ax_D3.0 section 9.4.2.241.

Signed-off-by: John Crispin <john@phrozen.org>
---
 include/linux/ieee80211.h  | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/util.c        |  4 ++++
 3 files changed, 54 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48703ec60d06..9e4ca3053ab1 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1629,6 +1629,18 @@ struct ieee80211_he_operation {
 } __packed;
 
 /**
+ * struct ieee80211_he_spr - HE spatial reuse element
+ *
+ * This structure is the "HE spatial reuse element" element as
+ * described in P802.11ax_D3.0 section 9.4.2.241
+ */
+struct ieee80211_he_spr {
+	u8 he_sr_control;
+	/* Optional 0 to 19 bytes: depends on @he_sr_control */
+	u8 optional[0];
+} __packed;
+
+/**
  * struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field
  *
  * This structure is the "MU AC Parameter Record" fields as
@@ -2063,6 +2075,42 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
 	return oper_len;
 }
 
+/* HE Spatial Reuse defines */
+#define IEEE80211_HE_SPR_NONE_SRG_OFFSET_PRESENT		0x4
+#define IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT		0x8
+
+/*
+ * ieee80211_he_spr_size - calculate 802.11ax HE Spatial Reuse IE size
+ * @he_spr_ie: byte data of the He Spatial Reuse IE, stating from the the byte
+ *	after the ext ID byte. It is assumed that he_spr_ie has at least
+ *	sizeof(struct ieee80211_he_spr) bytes, checked already in
+ *	ieee802_11_parse_elems_crc()
+ * @return the actual size of the IE data (not including header), or 0 on error
+ */
+static inline u8
+ieee80211_he_spr_size(const u8 *he_spr_ie)
+{
+	struct ieee80211_he_spr *he_spr = (void *)he_spr_ie;
+	u8 spr_len = sizeof(struct ieee80211_he_spr);
+	u32 he_spr_params;
+
+	/* Make sure the input is not NULL */
+	if (!he_spr_ie)
+		return 0;
+
+	/* Calc required length */
+	he_spr_params = le32_to_cpu(he_spr->he_sr_control);
+	if (he_spr_params & IEEE80211_HE_SPR_NONE_SRG_OFFSET_PRESENT)
+		spr_len++;
+	if (he_spr_params & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT)
+		spr_len += 2;
+
+	/* Add the first byte (extension ID) to the total length */
+	spr_len++;
+
+	return spr_len;
+}
+
 /* Authentication algorithms */
 #define WLAN_AUTH_OPEN 0
 #define WLAN_AUTH_SHARED_KEY 1
@@ -2485,6 +2533,7 @@ enum ieee80211_eid_ext {
 	WLAN_EID_EXT_HE_OPERATION = 36,
 	WLAN_EID_EXT_UORA = 37,
 	WLAN_EID_EXT_HE_MU_EDCA = 38,
+	WLAN_EID_EXT_HE_SPR = 39,
 	WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52,
 	WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55,
 };
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e170f986d226..5c455681d1b8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1482,6 +1482,7 @@ struct ieee802_11_elems {
 	const struct ieee80211_meshconf_ie *mesh_config;
 	const u8 *he_cap;
 	const struct ieee80211_he_operation *he_operation;
+	const struct ieee80211_he_spr *he_spr;
 	const struct ieee80211_mu_edca_param_set *mu_edca_param_set;
 	const u8 *uora_element;
 	const u8 *mesh_id;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 4c1655972565..1b7076d24c18 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1282,6 +1282,10 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
 				   WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION &&
 				   elen == 3) {
 				elems->mbssid_config_ie = (void *)&pos[1];
+			} else if (pos[0] == WLAN_EID_EXT_HE_SPR &&
+				   elen >= sizeof(*elems->he_spr) &&
+				   elen >= ieee80211_he_spr_size(&pos[1])) {
+				elems->he_spr = (void *)&pos[1];
 			}
 			break;
 		default:
-- 
2.11.0


^ permalink raw reply related

* Re: preparing for 802.11ah channels
From: Johannes Berg @ 2019-03-25  8:47 UTC (permalink / raw)
  To: thomas; +Cc: linux-wireless
In-Reply-To: <CABWD38nXRk5d7LPafnt9dvXc6nxFrEzeoDEREbdswga+WjpEMw@mail.gmail.com>

On Fri, 2019-03-22 at 15:29 -0700, thomas wrote:
> 
> I guess it's a tradeoff between leaving MHz-only drivers alone and
> wrapping existing assignments and comparisons in maybe a macro to
> extract the final KHz value. The current set of changes is about 150
> lines in net/mac80211/ and net/wireless/ [1] with drivers/ being about
> the same.
> 
> Adding the KHz part to center_freq, center_freq1, and rx_status->freq
> may be fewer overall changes in mac80211 and cfg80211, and should be
> none for existing drivers.

Yes. I was also thinking that perhaps keeping "MHz-mostly" would lead in
less overall new binary size, since you don't need to do "/1000" in that
many places. I can't see it any more, but IIRC your patch did add a
number of "KHZ_TO_MHZ()" or so?

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: HE: add Spatial Reuse IE parsing support
From: Johannes Berg @ 2019-03-25  8:49 UTC (permalink / raw)
  To: John Crispin; +Cc: linux-wireless
In-Reply-To: <20190325082057.26710-1-john@phrozen.org>

On Mon, 2019-03-25 at 09:20 +0100, John Crispin wrote:
> Add support to mac80211 for parsing SPR IEs as per
> P802.11ax_D3.0 section 9.4.2.241.

Hmm, if you're not going to use it, why parse it? Am I missing a follow-
up patch?

Also, consider checking against D4.0, Luca just sent a patch to update
to that for all the rest of the code.

johannes


^ permalink raw reply

* [PATCH 2/2] mac80211: minstrel_ht: automatically calculate rate duration shift
From: Felix Fietkau @ 2019-03-25  8:50 UTC (permalink / raw)
  To: linux-wireless; +Cc: johannes
In-Reply-To: <20190325085016.53727-1-nbd@nbd.name>

A per-group shift was added to reduce the size of the per-rate transmit
duration field to u16 without sacrificing a lot of precision
This patch changes the macros to automatically calculate the best value for
this shift based on the lowest rate within the group.
This simplifies adding more groups and slightly improves accuracy for some of
the existing groups.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 net/mac80211/rc80211_minstrel_ht.c | 134 +++++++++++++++++------------
 1 file changed, 80 insertions(+), 54 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 00a3a8ce27fe..8b168724c5e7 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -51,8 +51,13 @@
 	MINSTREL_MAX_STREAMS * _sgi +	\
 	_streams - 1
 
+#define _MAX(a, b) (((a)>(b))?(a):(b))
+
+#define GROUP_SHIFT(duration)						\
+	_MAX(0, 16 - __builtin_clz(duration))
+
 /* MCS rate information for an MCS group */
-#define MCS_GROUP(_streams, _sgi, _ht40, _s)				\
+#define __MCS_GROUP(_streams, _sgi, _ht40, _s)				\
 	[GROUP_IDX(_streams, _sgi, _ht40)] = {				\
 	.streams = _streams,						\
 	.shift = _s,							\
@@ -72,6 +77,13 @@
 	}								\
 }
 
+#define MCS_GROUP_SHIFT(_streams, _sgi, _ht40)				\
+	GROUP_SHIFT(MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26))
+
+#define MCS_GROUP(_streams, _sgi, _ht40)				\
+	__MCS_GROUP(_streams, _sgi, _ht40,				\
+		    MCS_GROUP_SHIFT(_streams, _sgi, _ht40))
+
 #define VHT_GROUP_IDX(_streams, _sgi, _bw)				\
 	(MINSTREL_VHT_GROUP_0 +						\
 	 MINSTREL_MAX_STREAMS * 2 * (_bw) +				\
@@ -81,7 +93,7 @@
 #define BW2VBPS(_bw, r3, r2, r1)					\
 	(_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1)
 
-#define VHT_GROUP(_streams, _sgi, _bw, _s)				\
+#define __VHT_GROUP(_streams, _sgi, _bw, _s)				\
 	[VHT_GROUP_IDX(_streams, _sgi, _bw)] = {			\
 	.streams = _streams,						\
 	.shift = _s,							\
@@ -114,6 +126,14 @@
 	}								\
 }
 
+#define VHT_GROUP_SHIFT(_streams, _sgi, _bw)				\
+	GROUP_SHIFT(MCS_DURATION(_streams, _sgi,			\
+				 BW2VBPS(_bw,  117,  54,  26)))
+
+#define VHT_GROUP(_streams, _sgi, _bw)					\
+	__VHT_GROUP(_streams, _sgi, _bw,				\
+		    VHT_GROUP_SHIFT(_streams, _sgi, _bw))
+
 #define CCK_DURATION(_bitrate, _short, _len)		\
 	(1000 * (10 /* SIFS */ +			\
 	 (_short ? 72 + 24 : 144 + 48) +		\
@@ -129,7 +149,7 @@
 	CCK_ACK_DURATION(55, _short) >> _s,		\
 	CCK_ACK_DURATION(110, _short) >> _s
 
-#define CCK_GROUP(_s)					\
+#define __CCK_GROUP(_s)					\
 	[MINSTREL_CCK_GROUP] = {			\
 		.streams = 1,				\
 		.flags = 0,				\
@@ -140,6 +160,12 @@
 		}					\
 	}
 
+#define CCK_GROUP_SHIFT					\
+	GROUP_SHIFT(CCK_ACK_DURATION(10, false))
+
+#define CCK_GROUP __CCK_GROUP(CCK_GROUP_SHIFT)
+
+
 static bool minstrel_vht_only = true;
 module_param(minstrel_vht_only, bool, 0644);
 MODULE_PARM_DESC(minstrel_vht_only,
@@ -154,57 +180,57 @@ MODULE_PARM_DESC(minstrel_vht_only,
  * BW -> SGI -> #streams
  */
 const struct mcs_group minstrel_mcs_groups[] = {
-	MCS_GROUP(1, 0, BW_20, 5),
-	MCS_GROUP(2, 0, BW_20, 4),
-	MCS_GROUP(3, 0, BW_20, 4),
-	MCS_GROUP(4, 0, BW_20, 4),
-
-	MCS_GROUP(1, 1, BW_20, 5),
-	MCS_GROUP(2, 1, BW_20, 4),
-	MCS_GROUP(3, 1, BW_20, 4),
-	MCS_GROUP(4, 1, BW_20, 4),
-
-	MCS_GROUP(1, 0, BW_40, 4),
-	MCS_GROUP(2, 0, BW_40, 4),
-	MCS_GROUP(3, 0, BW_40, 4),
-	MCS_GROUP(4, 0, BW_40, 4),
-
-	MCS_GROUP(1, 1, BW_40, 4),
-	MCS_GROUP(2, 1, BW_40, 4),
-	MCS_GROUP(3, 1, BW_40, 4),
-	MCS_GROUP(4, 1, BW_40, 4),
-
-	CCK_GROUP(8),
-
-	VHT_GROUP(1, 0, BW_20, 5),
-	VHT_GROUP(2, 0, BW_20, 4),
-	VHT_GROUP(3, 0, BW_20, 4),
-	VHT_GROUP(4, 0, BW_20, 4),
-
-	VHT_GROUP(1, 1, BW_20, 5),
-	VHT_GROUP(2, 1, BW_20, 4),
-	VHT_GROUP(3, 1, BW_20, 4),
-	VHT_GROUP(4, 1, BW_20, 4),
-
-	VHT_GROUP(1, 0, BW_40, 4),
-	VHT_GROUP(2, 0, BW_40, 4),
-	VHT_GROUP(3, 0, BW_40, 4),
-	VHT_GROUP(4, 0, BW_40, 3),
-
-	VHT_GROUP(1, 1, BW_40, 4),
-	VHT_GROUP(2, 1, BW_40, 4),
-	VHT_GROUP(3, 1, BW_40, 4),
-	VHT_GROUP(4, 1, BW_40, 3),
-
-	VHT_GROUP(1, 0, BW_80, 4),
-	VHT_GROUP(2, 0, BW_80, 4),
-	VHT_GROUP(3, 0, BW_80, 4),
-	VHT_GROUP(4, 0, BW_80, 2),
-
-	VHT_GROUP(1, 1, BW_80, 4),
-	VHT_GROUP(2, 1, BW_80, 4),
-	VHT_GROUP(3, 1, BW_80, 4),
-	VHT_GROUP(4, 1, BW_80, 2),
+	MCS_GROUP(1, 0, BW_20),
+	MCS_GROUP(2, 0, BW_20),
+	MCS_GROUP(3, 0, BW_20),
+	MCS_GROUP(4, 0, BW_20),
+
+	MCS_GROUP(1, 1, BW_20),
+	MCS_GROUP(2, 1, BW_20),
+	MCS_GROUP(3, 1, BW_20),
+	MCS_GROUP(4, 1, BW_20),
+
+	MCS_GROUP(1, 0, BW_40),
+	MCS_GROUP(2, 0, BW_40),
+	MCS_GROUP(3, 0, BW_40),
+	MCS_GROUP(4, 0, BW_40),
+
+	MCS_GROUP(1, 1, BW_40),
+	MCS_GROUP(2, 1, BW_40),
+	MCS_GROUP(3, 1, BW_40),
+	MCS_GROUP(4, 1, BW_40),
+
+	CCK_GROUP,
+
+	VHT_GROUP(1, 0, BW_20),
+	VHT_GROUP(2, 0, BW_20),
+	VHT_GROUP(3, 0, BW_20),
+	VHT_GROUP(4, 0, BW_20),
+
+	VHT_GROUP(1, 1, BW_20),
+	VHT_GROUP(2, 1, BW_20),
+	VHT_GROUP(3, 1, BW_20),
+	VHT_GROUP(4, 1, BW_20),
+
+	VHT_GROUP(1, 0, BW_40),
+	VHT_GROUP(2, 0, BW_40),
+	VHT_GROUP(3, 0, BW_40),
+	VHT_GROUP(4, 0, BW_40),
+
+	VHT_GROUP(1, 1, BW_40),
+	VHT_GROUP(2, 1, BW_40),
+	VHT_GROUP(3, 1, BW_40),
+	VHT_GROUP(4, 1, BW_40),
+
+	VHT_GROUP(1, 0, BW_80),
+	VHT_GROUP(2, 0, BW_80),
+	VHT_GROUP(3, 0, BW_80),
+	VHT_GROUP(4, 0, BW_80),
+
+	VHT_GROUP(1, 1, BW_80),
+	VHT_GROUP(2, 1, BW_80),
+	VHT_GROUP(3, 1, BW_80),
+	VHT_GROUP(4, 1, BW_80),
 };
 
 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
-- 
2.17.0


^ permalink raw reply related


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