Netdev List
 help / color / mirror / Atom feed
* Re: KASAN: use-after-free Read in atusb_disconnect
From: syzbot @ 2019-09-19 12:32 UTC (permalink / raw)
  To: alex.aring, andreyknvl, davem, johan, linux-kernel, linux-wpan,
	netdev, stable, stefan, syzkaller-bugs
In-Reply-To: <20190919121234.30620-1-johan@kernel.org>

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger  
crash:

Reported-and-tested-by:  
syzbot+f4509a9138a1472e7e80@syzkaller.appspotmail.com

Tested on:

commit:         f0df5c1b usb-fuzzer: main usb gadget fuzzer driver
git tree:       https://github.com/google/kasan.git
kernel config:  https://syzkaller.appspot.com/x/.config?x=5c6633fa4ed00be5
dashboard link: https://syzkaller.appspot.com/bug?extid=f4509a9138a1472e7e80
compiler:       gcc (GCC) 9.0.0 20181231 (experimental)
patch:          https://syzkaller.appspot.com/x/patch.diff?x=10f3ebb5600000

Note: testing is done by a robot and is best-effort only.

^ permalink raw reply

* Re: [PATCH net-next] tcp: force a PSH flag on TSO packets
From: David Miller @ 2019-09-19 12:32 UTC (permalink / raw)
  To: gerlitz.or
  Cc: edumazet, netdev, eric.dumazet, soheil, ncardwell, ycheng, daniel,
	tariqt
In-Reply-To: <CAJ3xEMhh=Ow-fZqnPtxUyZsCN89dRmy=NcaO+iK+iZZYBdZbqA@mail.gmail.com>

From: Or Gerlitz <gerlitz.or@gmail.com>
Date: Thu, 19 Sep 2019 15:17:54 +0300

> On Wed, Sep 11, 2019 at 12:54 AM Eric Dumazet <edumazet@google.com> wrote:
>> When tcp sends a TSO packet, adding a PSH flag on it
>> reduces the sojourn time of GRO packet in GRO receivers.
>>
>> This is particularly the case under pressure, since RX queues
>> receive packets for many concurrent flows.
>>
>> A sender can give a hint to GRO engines when it is
>> appropriate to flush a super-packet, especially when pacing
> 
> Hi Eric,
> 
> Is this correct that we add here the push flag for the tcp header template
> from which all the tcp headers for SW GSO packets will be generated?
> 
> Wouldn't that cause a too early flush on GRO engines at the receiver side?

I thought segmentation offload mechanism are not supposed to propagate
the PSH to all of the packets.

^ permalink raw reply

* Re: [PATCH bpf] xsk: relax UMEM headroom alignment
From: Daniel Borkmann @ 2019-09-19 12:33 UTC (permalink / raw)
  To: Björn Töpel
  Cc: ast, netdev, Björn Töpel, magnus.karlsson,
	magnus.karlsson, bpf, jonathan.lemon
In-Reply-To: <20190918075739.19451-1-bjorn.topel@gmail.com>

On Wed, Sep 18, 2019 at 09:57:39AM +0200, Björn Töpel wrote:
> From: Björn Töpel <bjorn.topel@intel.com>
> 
> This patch removes the 64B alignment of the UMEM headroom. There is
> really no reason for it, and having a headroom less than 64B should be
> valid.
> 
> Fixes: c0c77d8fb787 ("xsk: add user memory registration support sockopt")
> Signed-off-by: Björn Töpel <bjorn.topel@intel.com>

Applied, thanks!

^ permalink raw reply

* Re: [PATCH bpf 0/2] bpf: BTF fixes
From: Daniel Borkmann @ 2019-09-19 12:33 UTC (permalink / raw)
  To: Alexei Starovoitov; +Cc: davem, netdev, bpf, kernel-team
In-Reply-To: <20190917174538.1295523-1-ast@kernel.org>

On Tue, Sep 17, 2019 at 10:45:36AM -0700, Alexei Starovoitov wrote:
> Two trivial BTF fixes.
> 
> Alexei Starovoitov (2):
>   bpf: fix BTF verification of enums
>   bpf: fix BTF limits
> 
>  include/uapi/linux/btf.h | 4 ++--
>  kernel/bpf/btf.c         | 5 ++---
>  2 files changed, 4 insertions(+), 5 deletions(-)

Applied, thanks!

^ permalink raw reply

* Re: [PATCH] stmmac: selftest: avoid large stack usage
From: Arnd Bergmann @ 2019-09-19 12:34 UTC (permalink / raw)
  To: Jose Abreu
  Cc: Giuseppe Cavallaro, Alexandre Torgue, David S. Miller,
	Maxime Coquelin, netdev@vger.kernel.org,
	linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <BN8PR12MB3266E044DDF00F227B9B191CD3890@BN8PR12MB3266.namprd12.prod.outlook.com>

On Thu, Sep 19, 2019 at 9:58 AM Jose Abreu <Jose.Abreu@synopsys.com> wrote:
>
> From: Arnd Bergmann <arnd@arndb.de>
> Date: Sep/18/2019, 20:54:34 (UTC+00:00)
>
> > +     if (!cfg || !cfg->enable) {
> >               value &= ~XGMAC_RSSE;
> >               writel(value, ioaddr + XGMAC_RSS_CTRL);
> >               return 0;
> >       }
> >
> >       for (i = 0; i < (sizeof(cfg->key) / sizeof(u32)); i++) {
> > -             ret = dwxgmac2_rss_write_reg(ioaddr, true, i, *key++);
> > +             if (cfg)
> > +                     ret = dwxgmac2_rss_write_reg(ioaddr, true, i, cfg->key[i]);
> > +             else
> > +                     ret = dwxgmac2_rss_write_reg(ioaddr, true, i, 0);
> > +
> >               if (ret)
> >                       return ret;
> >       }
> >
> >       for (i = 0; i < ARRAY_SIZE(cfg->table); i++) {
> > -             ret = dwxgmac2_rss_write_reg(ioaddr, false, i, cfg->table[i]);
> > +             if (cfg)
> > +                     ret = dwxgmac2_rss_write_reg(ioaddr, false, i, cfg->table[i]);
> > +             else
> > +                     ret = dwxgmac2_rss_write_reg(ioaddr, false, i, 0);
> > +
>
> I don't get these "if (cfg)" checks. You already check earlier if cfg is
> NULL and return if so. I don't think you need these extra checks.

Ah, you are right, I missed the 'return 0', that makes it much easier.

> Also, your subject line should be something like: "net: stmmac:
> selftests: ..."

I think both styles is common for network drivers, though I think most
just leave out the 'net:'. I changed it in v2 now.

      Arnd

^ permalink raw reply

* [PATCH] [v2] net: stmmac: selftest: avoid large stack usage
From: Arnd Bergmann @ 2019-09-19 12:33 UTC (permalink / raw)
  To: Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu, David S. Miller,
	Maxime Coquelin
  Cc: Arnd Bergmann, netdev, linux-stm32, linux-arm-kernel,
	linux-kernel

Putting a struct stmmac_rss object on the stack is a bad idea,
as it exceeds the warning limit for a stack frame on 32-bit architectures:

drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c:1221:12: error: stack frame size of 1208 bytes in function '__stmmac_test_l3filt' [-Werror,-Wframe-larger-than=]
drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c:1338:12: error: stack frame size of 1208 bytes in function '__stmmac_test_l4filt' [-Werror,-Wframe-larger-than=]

As the object is the trivial empty case, change the called function
to accept a NULL pointer to mean the same thing and remove the
large variable in the two callers.

Fixes: 4647e021193d ("net: stmmac: selftests: Add selftest for L3/L4 Filters")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2: simply configure function, based on feedback from Jose
---
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c    |  5 ++---
 .../net/ethernet/stmicro/stmmac/stmmac_selftests.c | 14 ++++----------
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index d5173dd02a71..2b277b2c586b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -523,19 +523,18 @@ static int dwxgmac2_rss_configure(struct mac_device_info *hw,
 				  struct stmmac_rss *cfg, u32 num_rxq)
 {
 	void __iomem *ioaddr = hw->pcsr;
-	u32 *key = (u32 *)cfg->key;
 	int i, ret;
 	u32 value;
 
 	value = readl(ioaddr + XGMAC_RSS_CTRL);
-	if (!cfg->enable) {
+	if (!cfg || !cfg->enable) {
 		value &= ~XGMAC_RSSE;
 		writel(value, ioaddr + XGMAC_RSS_CTRL);
 		return 0;
 	}
 
 	for (i = 0; i < (sizeof(cfg->key) / sizeof(u32)); i++) {
-		ret = dwxgmac2_rss_write_reg(ioaddr, true, i, *key++);
+		ret = dwxgmac2_rss_write_reg(ioaddr, true, i, cfg->key[i]);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index c56e89e1ae56..9c8d210b2d6a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -1233,12 +1233,9 @@ static int __stmmac_test_l3filt(struct stmmac_priv *priv, u32 dst, u32 src,
 		return -EOPNOTSUPP;
 	if (!priv->dma_cap.l3l4fnum)
 		return -EOPNOTSUPP;
-	if (priv->rss.enable) {
-		struct stmmac_rss rss = { .enable = false, };
-
-		stmmac_rss_configure(priv, priv->hw, &rss,
+	if (priv->rss.enable)
+		stmmac_rss_configure(priv, priv->hw, NULL,
 				     priv->plat->rx_queues_to_use);
-	}
 
 	dissector = kzalloc(sizeof(*dissector), GFP_KERNEL);
 	if (!dissector) {
@@ -1357,12 +1354,9 @@ static int __stmmac_test_l4filt(struct stmmac_priv *priv, u32 dst, u32 src,
 		return -EOPNOTSUPP;
 	if (!priv->dma_cap.l3l4fnum)
 		return -EOPNOTSUPP;
-	if (priv->rss.enable) {
-		struct stmmac_rss rss = { .enable = false, };
-
-		stmmac_rss_configure(priv, priv->hw, &rss,
+	if (priv->rss.enable)
+		stmmac_rss_configure(priv, priv->hw, NULL,
 				     priv->plat->rx_queues_to_use);
-	}
 
 	dissector = kzalloc(sizeof(*dissector), GFP_KERNEL);
 	if (!dissector) {
-- 
2.20.0


^ permalink raw reply related

* Re: [PATCH RFC v3 0/5] Support fraglist GRO/GSO
From: Or Gerlitz @ 2019-09-19 12:37 UTC (permalink / raw)
  To: Steffen Klassert, Edward Cree, Willem de Bruijn
  Cc: Linux Netdev List, Paolo Abeni
In-Reply-To: <20190918072517.16037-1-steffen.klassert@secunet.com>

On Wed, Sep 18, 2019 at 2:48 PM Steffen Klassert
<steffen.klassert@secunet.com> wrote:
> This patchset adds support to do GRO/GSO by chaining packets
> of the same flow at the SKB frag_list pointer. This avoids
> the overhead to merge payloads into one big packet, and
> on the other end, if GSO is needed it avoids the overhead
> of splitting the big packet back to the native form.
>
> Patch 1 Enables UDP GRO by default.
>
> Patch 2 adds a netdev feature flag to enable listifyed GRO,
> this implements one of the configuration options discussed
> at netconf 2019.
[..]

The slide say that linked packets travel together though the stack.

This sounds somehow similar to the approach suggested by Ed
for skb lists. I wonder what we can say on cases where each of the
approaches would function better.

Or.

^ permalink raw reply

* RE: [PATCH v3] bonding: force enable lacp port after link state recovery for 802.3ad
From: zhangsha (A) @ 2019-09-19 12:46 UTC (permalink / raw)
  To: Jay Vosburgh, zaharov@selectel.ru
  Cc: vfalico@gmail.com, andy@greyhouse.net, davem@davemloft.net,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org, yuehaibing,
	hunongda, Chenzhendong (alex)
In-Reply-To: <10098.1568880711@nyx>



> -----Original Message-----
> From: Jay Vosburgh [mailto:jay.vosburgh@canonical.com]
> Sent: 2019年9月19日 16:12
> To: zhangsha (A) <zhangsha.zhang@huawei.com>
> Cc: vfalico@gmail.com; andy@greyhouse.net; davem@davemloft.net;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org; yuehaibing
> <yuehaibing@huawei.com>; hunongda <hunongda@huawei.com>;
> Chenzhendong (alex) <alex.chen@huawei.com>
> Subject: Re: [PATCH v3] bonding: force enable lacp port after link state
> recovery for 802.3ad
> 
> zhangsha (A) <zhangsha.zhang@huawei.com> wrote:
> 
> >> -----Original Message-----
> >> From: zhangsha (A)
> >> Sent: 2019年9月18日 21:06
> >> To: jay.vosburgh@canonical.com; vfalico@gmail.com;
> >> andy@greyhouse.net; davem@davemloft.net; netdev@vger.kernel.org;
> >> linux-kernel@vger.kernel.org; yuehaibing <yuehaibing@huawei.com>;
> >> hunongda <hunongda@huawei.com>; Chenzhendong (alex)
> >> <alex.chen@huawei.com>; zhangsha (A) <zhangsha.zhang@huawei.com>
> >> Subject: [PATCH v3] bonding: force enable lacp port after link state
> >> recovery for 802.3ad
> >>
> >> From: Sha Zhang <zhangsha.zhang@huawei.com>
> >>
> >> After the commit 334031219a84 ("bonding/802.3ad: fix slave link
> >> initialization transition states") merged, the slave's link status
> >> will be changed to BOND_LINK_FAIL from BOND_LINK_DOWN in the
> following scenario:
> >> - Driver reports loss of carrier and
> >>   bonding driver receives NETDEV_DOWN notifier
> >> - slave's duplex and speed is zerod and
> >>   its port->is_enabled is cleard to 'false';
> >> - Driver reports link recovery and
> >>   bonding driver receives NETDEV_UP notifier;
> >> - If speed/duplex getting failed here, the link status
> >>   will be changed to BOND_LINK_FAIL;
> >> - The MII monotor later recover the slave's speed/duplex
> >>   and set link status to BOND_LINK_UP, but remains
> >>   the 'port->is_enabled' to 'false'.
> >>
> >> In this scenario, the lacp port will not be enabled even its speed
> >> and duplex are valid. The bond will not send LACPDU's, and its state is
> 'AD_STATE_DEFAULTED'
> >> forever. The simplest fix I think is to call
> >> bond_3ad_handle_link_change() in bond_miimon_commit, this function
> >> can enable lacp after port slave speed check.
> >> As enabled, the lacp port can run its state machine normally after link
> recovery.
> >>
> >> Signed-off-by: Sha Zhang <zhangsha.zhang@huawei.com>
> >> ---
> >>  drivers/net/bonding/bond_main.c | 3 ++-
> >>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/net/bonding/bond_main.c
> >> b/drivers/net/bonding/bond_main.c index 931d9d9..76324a5 100644
> >> --- a/drivers/net/bonding/bond_main.c
> >> +++ b/drivers/net/bonding/bond_main.c
> >> @@ -2206,7 +2206,8 @@ static void bond_miimon_commit(struct bonding
> >> *bond)
> >>  			 */
> >>  			if (BOND_MODE(bond) == BOND_MODE_8023AD &&
> >>  			    slave->link == BOND_LINK_UP)
> >> -
> >> 	bond_3ad_adapter_speed_duplex_changed(slave);
> >> +				bond_3ad_handle_link_change(slave,
> >> +							    BOND_LINK_UP);
> >>  			continue;
> >>
> >>  		case BOND_LINK_UP:
> >
> >Hi, David,
> >I have replied your email for a while,  I guess you may miss my email, so I
> resend it.
> >The following link address is the last email, please review the new one again,
> thank you.
> >https://patchwork.ozlabs.org/patch/1151915/
> >
> >Last time, you doubted this is a driver specific problem, I prefer to
> >believe it's not because I find the commit 4d2c0cda, its log says "
> >Some NIC drivers don't have correct speed/duplex settings at the time
> >they send NETDEV_UP notification ...".
> >
> >Anyway, I think the lacp status should be fixed correctly, since
> >link-monitoring (miimon) set SPEED/DUPLEX right here.
> 
> 	I suspect this is going to be related to the concurrent discussion with
> Aleksei, and would like to see the instrumentation results from his tests before
> adding another change to attempt to resolve this.
> 
> 	Also, what device are you using for your testing, and are you able to
> run the instrumentation patch that I provided to Aleksei and provide its results?
> 	
> 	-J
> 

Yes, I think it's the same problem.
I am using a Huawei hinic card with kernel 4.19 and got the same message and the
weird system mac "00:00:00:00:00:00":
"link status definitely down for interface eth6, disabling it
 link status up again after 0 ms for interface eth6"

I will run your instrumentation patch, but maybe I need more times.
In fact, I have tried to reproduce the problem for thousands of times, but never succeeded.

> ---
> 	-Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply

* Re: [PATCH net v3] net/sched: cls_api: Fix nooffloaddevcnt counter when indr block call success
From: Or Gerlitz @ 2019-09-19 12:50 UTC (permalink / raw)
  To: wenxu, Pieter Jansen van Vuuren, Oz Shlomo
  Cc: David Miller, Linux Netdev List, Roi Dayan, Paul Blakey,
	Jiri Pirko
In-Reply-To: <1568882232-12847-1-git-send-email-wenxu@ucloud.cn>

On Thu, Sep 19, 2019 at 11:39 AM <wenxu@ucloud.cn> wrote:
>
> From: wenxu <wenxu@ucloud.cn>
>
> A vxlan or gretap device offload through indr block methord. If the device

nit: method --> method

> successfully bind with a real hw through indr block call, It also add
> nooffloadcnt counter. This counter will lead the rule add failed in
> fl_hw_replace_filter-->tc_setup_cb_call with skip_sw flags.

wait.. indirect tc callbacks are typically used to do hw offloading
for decap rules (tunnel key unset action) set on SW devices (gretap, vxlan).

However, AFAIK, it's been couple of years since the kernel doesn't support
skip_sw for such rules. Did we enable it again? when? I am somehow
far from the details, so copied some folks..

Or.


>
> In the tc_setup_cb_call will check the nooffloaddevcnt and skip_sw flags
> as following:
> if (block->nooffloaddevcnt && err_stop)
>         return -EOPNOTSUPP;
>
> So with this patch, if the indr block call success, it will not modify
> the nooffloaddevcnt counter.
>
> Fixes: 7f76fa36754b ("net: sched: register callbacks for indirect tc block binds")
> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
> v3: rebase to the net
>
>  net/sched/cls_api.c | 30 +++++++++++++++++-------------
>  1 file changed, 17 insertions(+), 13 deletions(-)
>
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index 32577c2..c980127 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -607,11 +607,11 @@ static void tc_indr_block_get_and_ing_cmd(struct net_device *dev,
>         tc_indr_block_ing_cmd(dev, block, cb, cb_priv, command);
>  }
>
> -static void tc_indr_block_call(struct tcf_block *block,
> -                              struct net_device *dev,
> -                              struct tcf_block_ext_info *ei,
> -                              enum flow_block_command command,
> -                              struct netlink_ext_ack *extack)
> +static int tc_indr_block_call(struct tcf_block *block,
> +                             struct net_device *dev,
> +                             struct tcf_block_ext_info *ei,
> +                             enum flow_block_command command,
> +                             struct netlink_ext_ack *extack)
>  {
>         struct flow_block_offload bo = {
>                 .command        = command,
> @@ -621,10 +621,15 @@ static void tc_indr_block_call(struct tcf_block *block,
>                 .block_shared   = tcf_block_shared(block),
>                 .extack         = extack,
>         };
> +
>         INIT_LIST_HEAD(&bo.cb_list);
>
>         flow_indr_block_call(dev, &bo, command);
> -       tcf_block_setup(block, &bo);
> +
> +       if (list_empty(&bo.cb_list))
> +               return -EOPNOTSUPP;
> +
> +       return tcf_block_setup(block, &bo);
>  }
>
>  static bool tcf_block_offload_in_use(struct tcf_block *block)
> @@ -681,8 +686,6 @@ static int tcf_block_offload_bind(struct tcf_block *block, struct Qdisc *q,
>                 goto no_offload_dev_inc;
>         if (err)
>                 goto err_unlock;
> -
> -       tc_indr_block_call(block, dev, ei, FLOW_BLOCK_BIND, extack);
>         up_write(&block->cb_lock);
>         return 0;
>
> @@ -691,9 +694,10 @@ static int tcf_block_offload_bind(struct tcf_block *block, struct Qdisc *q,
>                 err = -EOPNOTSUPP;
>                 goto err_unlock;
>         }
> +       err = tc_indr_block_call(block, dev, ei, FLOW_BLOCK_BIND, extack);
> +       if (err)
> +               block->nooffloaddevcnt++;
>         err = 0;
> -       block->nooffloaddevcnt++;
> -       tc_indr_block_call(block, dev, ei, FLOW_BLOCK_BIND, extack);
>  err_unlock:
>         up_write(&block->cb_lock);
>         return err;
> @@ -706,8 +710,6 @@ static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q,
>         int err;
>
>         down_write(&block->cb_lock);
> -       tc_indr_block_call(block, dev, ei, FLOW_BLOCK_UNBIND, NULL);
> -
>         if (!dev->netdev_ops->ndo_setup_tc)
>                 goto no_offload_dev_dec;
>         err = tcf_block_offload_cmd(block, dev, ei, FLOW_BLOCK_UNBIND, NULL);
> @@ -717,7 +719,9 @@ static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q,
>         return;
>
>  no_offload_dev_dec:
> -       WARN_ON(block->nooffloaddevcnt-- == 0);
> +       err = tc_indr_block_call(block, dev, ei, FLOW_BLOCK_UNBIND, NULL);
> +       if (err)
> +               WARN_ON(block->nooffloaddevcnt-- == 0);
>         up_write(&block->cb_lock);
>  }
>
> --
> 1.8.3.1
>

^ permalink raw reply

* Re: [PATCH v4 1/3] kernel/notifier.c: intercepting duplicate registrations to avoid infinite loops
From: Xiaoming Ni @ 2019-09-19 12:55 UTC (permalink / raw)
  To: Greg KH
  Cc: akpm, vvs, torvalds, adobriyan, anna.schumaker, arjan, bfields,
	chuck.lever, davem, jlayton, luto, mingo, Nadia.Derbey, paulmck,
	semen.protsenko, stern, tglx, trond.myklebust, viresh.kumar,
	stable, dylix.dailei, yuehaibing, linux-kernel, linux-nfs, netdev
In-Reply-To: <20190919063615.GA2069346@kroah.com>

On 2019/9/19 14:36, Greg KH wrote:
> On Thu, Sep 19, 2019 at 10:58:06AM +0800, Xiaoming Ni wrote:
>> Registering the same notifier to a hook repeatedly can cause the hook
>> list to form a ring or lose other members of the list.
>>
>> case1: An infinite loop in notifier_chain_register() can cause soft lockup
>>         atomic_notifier_chain_register(&test_notifier_list, &test1);
>>         atomic_notifier_chain_register(&test_notifier_list, &test1);
>>         atomic_notifier_chain_register(&test_notifier_list, &test2);
>>
>> case2: An infinite loop in notifier_chain_register() can cause soft lockup
>>         atomic_notifier_chain_register(&test_notifier_list, &test1);
>>         atomic_notifier_chain_register(&test_notifier_list, &test1);
>>         atomic_notifier_call_chain(&test_notifier_list, 0, NULL);
>>
>> case3: lose other hook test2
>>         atomic_notifier_chain_register(&test_notifier_list, &test1);
>>         atomic_notifier_chain_register(&test_notifier_list, &test2);
>>         atomic_notifier_chain_register(&test_notifier_list, &test1);
>>
>> case4: Unregister returns 0, but the hook is still in the linked list,
>>         and it is not really registered. If you call notifier_call_chain
>>         after ko is unloaded, it will trigger oops.
>>
>> If the system is configured with softlockup_panic and the same
>> hook is repeatedly registered on the panic_notifier_list, it
>> will cause a loop panic.
>>
>> Add a check in notifier_chain_register(),
>> Intercepting duplicate registrations to avoid infinite loops
>>
>> Signed-off-by: Xiaoming Ni <nixiaoming@huawei.com>
>> Reviewed-by: Vasily Averin <vvs@virtuozzo.com>
>> ---
>>  kernel/notifier.c | 5 ++++-
>>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> <formletter>
> 
> This is not the correct way to submit patches for inclusion in the
> stable kernel tree.  Please read:
>     https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
> for how to do this properly.
> 
thanks for your guidance
I thought that as long as the code exists in the stable branch, it should be copied to stable@kernel.org
it is my mistake,

These patches are intended to be sent to the main line.
Should I resend it again?

> </formletter>
> 
> Same thing goes for all of the patches in this series.
> 
> thanks,
> 
> greg k-h
> 
> .
> 

thanks

Xiaoming Ni


^ permalink raw reply

* Re: [PATCH RFC v3 0/5] Support fraglist GRO/GSO
From: Willem de Bruijn @ 2019-09-19 12:55 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: Willem de Bruijn, Steffen Klassert, Network Development,
	Paolo Abeni
In-Reply-To: <20190918165817.GA3431@localhost.localdomain>

On Wed, Sep 18, 2019 at 12:58 PM Marcelo Ricardo Leitner
<marcelo.leitner@gmail.com> wrote:
>
> On Wed, Sep 18, 2019 at 12:17:08PM -0400, Willem de Bruijn wrote:
> > On Wed, Sep 18, 2019 at 3:25 AM Steffen Klassert
> > <steffen.klassert@secunet.com> wrote:
> > >
> > > This patchset adds support to do GRO/GSO by chaining packets
> > > of the same flow at the SKB frag_list pointer. This avoids
> > > the overhead to merge payloads into one big packet, and
> > > on the other end, if GSO is needed it avoids the overhead
> > > of splitting the big packet back to the native form.
> > >
> > > Patch 1 Enables UDP GRO by default.
> > >
> > > Patch 2 adds a netdev feature flag to enable listifyed GRO,
> > > this implements one of the configuration options discussed
> > > at netconf 2019.
> > >
> > > Patch 3 adds a netdev software feature set that defaults to off
> > > and assigns the new listifyed GRO feature flag to it.
> > >
> > > Patch 4 adds the core infrastructure to do fraglist GRO/GSO.
> > >
> > > Patch 5 enables UDP to use fraglist GRO/GSO if configured and no
> > > GRO supported socket is found.
> >
> > Very nice feature, Steffen. Aside from questions around performance,
> > my only question is really how this relates to GSO_BY_FRAGS.
>
> They do the exact same thing AFAICT: they GSO according to a
> pre-formatted list of fragments/packets, and not to a specific size
> (such as MSS).
>
> >
> > More specifically, whether we can remove that in favor of using your
> > new skb_segment_list. That would actually be a big first step in
> > simplifying skb_segment back to something manageable.
>
> The main issue (that I know) on obsoleting GSO_BY_FRAGS is that
> dealing with frags instead of frag_list was considered easier to be
> offloaded, if ever attempted.  So this would be a step back on that
> aspect.  Other than this, it should be doable.

But GSO_BY_FRAGS also uses frag_list, not frags?

And list_skb->len for mss.

^ permalink raw reply

* RE: [PATCH] [v2] net: stmmac: selftest: avoid large stack usage
From: Jose Abreu @ 2019-09-19 13:01 UTC (permalink / raw)
  To: Arnd Bergmann, Giuseppe Cavallaro, Alexandre Torgue,
	David S. Miller, Maxime Coquelin
  Cc: netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <20190919123416.3070938-1-arnd@arndb.de>

From: Arnd Bergmann <arnd@arndb.de>
Date: Sep/19/2019, 13:33:43 (UTC+00:00)

> Putting a struct stmmac_rss object on the stack is a bad idea,
> as it exceeds the warning limit for a stack frame on 32-bit architectures:
> 
> drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c:1221:12: error: stack frame size of 1208 bytes in function '__stmmac_test_l3filt' [-Werror,-Wframe-larger-than=]
> drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c:1338:12: error: stack frame size of 1208 bytes in function '__stmmac_test_l4filt' [-Werror,-Wframe-larger-than=]
> 
> As the object is the trivial empty case, change the called function
> to accept a NULL pointer to mean the same thing and remove the
> large variable in the two callers.
> 
> Fixes: 4647e021193d ("net: stmmac: selftests: Add selftest for L3/L4 Filters")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> v2: simply configure function, based on feedback from Jose

Looks good to me. Thanks for the fix :)

Acked-by: Jose Abreu <joabreu@synopsys.com>

---
Thanks,
Jose Miguel Abreu

^ permalink raw reply

* Re: [PATCH RFC v3 0/5] Support fraglist GRO/GSO
From: Marcelo Ricardo Leitner @ 2019-09-19 13:07 UTC (permalink / raw)
  To: Willem de Bruijn; +Cc: Steffen Klassert, Network Development, Paolo Abeni
In-Reply-To: <CA+FuTSf0N9uhOM3r8xvXiVj0xhx0KqL6-rV9EGhBJ=d8oGaxyg@mail.gmail.com>

On Thu, Sep 19, 2019 at 08:55:22AM -0400, Willem de Bruijn wrote:
> On Wed, Sep 18, 2019 at 12:58 PM Marcelo Ricardo Leitner
> <marcelo.leitner@gmail.com> wrote:
> >
> > On Wed, Sep 18, 2019 at 12:17:08PM -0400, Willem de Bruijn wrote:
> > > On Wed, Sep 18, 2019 at 3:25 AM Steffen Klassert
> > > <steffen.klassert@secunet.com> wrote:
> > > >
> > > > This patchset adds support to do GRO/GSO by chaining packets
> > > > of the same flow at the SKB frag_list pointer. This avoids
> > > > the overhead to merge payloads into one big packet, and
> > > > on the other end, if GSO is needed it avoids the overhead
> > > > of splitting the big packet back to the native form.
> > > >
> > > > Patch 1 Enables UDP GRO by default.
> > > >
> > > > Patch 2 adds a netdev feature flag to enable listifyed GRO,
> > > > this implements one of the configuration options discussed
> > > > at netconf 2019.
> > > >
> > > > Patch 3 adds a netdev software feature set that defaults to off
> > > > and assigns the new listifyed GRO feature flag to it.
> > > >
> > > > Patch 4 adds the core infrastructure to do fraglist GRO/GSO.
> > > >
> > > > Patch 5 enables UDP to use fraglist GRO/GSO if configured and no
> > > > GRO supported socket is found.
> > >
> > > Very nice feature, Steffen. Aside from questions around performance,
> > > my only question is really how this relates to GSO_BY_FRAGS.
> >
> > They do the exact same thing AFAICT: they GSO according to a
> > pre-formatted list of fragments/packets, and not to a specific size
> > (such as MSS).
> >
> > >
> > > More specifically, whether we can remove that in favor of using your
> > > new skb_segment_list. That would actually be a big first step in
> > > simplifying skb_segment back to something manageable.
> >
> > The main issue (that I know) on obsoleting GSO_BY_FRAGS is that
> > dealing with frags instead of frag_list was considered easier to be
> > offloaded, if ever attempted.  So this would be a step back on that
> > aspect.  Other than this, it should be doable.
> 
> But GSO_BY_FRAGS also uses frag_list, not frags?

/me is scratching his head.
My bad. I thought it was already using frags. Thanks.

> 
> And list_skb->len for mss.

Which stands more for 'current frag size', yes.
(list_skb, not head_skb)

^ permalink raw reply

* Re: [RFC v4 0/3] vhost: introduce mdev based hardware backend
From: Jason Wang @ 2019-09-19 13:08 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Tiwei Bie, alex.williamson, maxime.coquelin, linux-kernel, kvm,
	virtualization, netdev, dan.daly, cunming.liang, zhihong.wang,
	lingshan.zhu
In-Reply-To: <20190918102923-mutt-send-email-mst@kernel.org>


On 2019/9/18 下午10:32, Michael S. Tsirkin wrote:
>>>> So I have some questions:
>>>>
>>>> 1) Compared to method 2, what's the advantage of creating a new vhost char
>>>> device? I guess it's for keep the API compatibility?
>>> One benefit is that we can avoid doing vhost ioctls on
>>> VFIO device fd.
>> Yes, but any benefit from doing this?
> It does seem a bit more modular, but it's certainly not a big deal.


Ok, if we go this way, it could be as simple as provide some callback to 
vhost, then vhost can just forward the ioctl through parent_ops.


>
>>>> 2) For method 2, is there any easy way for user/admin to distinguish e.g
>>>> ordinary vfio-mdev for vhost from ordinary vfio-mdev?
>>> I think device-api could be a choice.
>> Ok.
>>
>>
>>>> I saw you introduce
>>>> ops matching helper but it's not friendly to management.
>>> The ops matching helper is just to check whether a given
>>> vfio-device is based on a mdev device.
>>>
>>>> 3) A drawback of 1) and 2) is that it must follow vfio_device_ops that
>>>> assumes the parameter comes from userspace, it prevents support kernel
>>>> virtio drivers.
>>>>
>>>> 4) So comes the idea of method 3, since it register a new vhost-mdev driver,
>>>> we can use device specific ops instead of VFIO ones, then we can have a
>>>> common API between vDPA parent and vhost-mdev/virtio-mdev drivers.
>>> As the above draft shows, this requires introducing a new
>>> VFIO device driver. I think Alex's opinion matters here.


Just to clarify, a new type of mdev driver but provides dummy 
vfio_device_ops for VFIO to make container DMA ioctl work.

Thanks


>> Yes, it is.
>>
>> Thanks
>>
>>

^ permalink raw reply

* Re: [PATCH RFC v3 0/5] Support fraglist GRO/GSO
From: Marcelo Ricardo Leitner @ 2019-09-19 13:11 UTC (permalink / raw)
  To: Steffen Klassert; +Cc: Willem de Bruijn, Network Development, Paolo Abeni
In-Reply-To: <20190919094106.GM2879@gauss3.secunet.de>

On Thu, Sep 19, 2019 at 11:41:06AM +0200, Steffen Klassert wrote:
> On Wed, Sep 18, 2019 at 12:17:08PM -0400, Willem de Bruijn wrote:
> > On Wed, Sep 18, 2019 at 3:25 AM Steffen Klassert
> > <steffen.klassert@secunet.com> wrote:
> > >
> > > This patchset adds support to do GRO/GSO by chaining packets
> > > of the same flow at the SKB frag_list pointer. This avoids
> > > the overhead to merge payloads into one big packet, and
> > > on the other end, if GSO is needed it avoids the overhead
> > > of splitting the big packet back to the native form.
> > >
> > > Patch 1 Enables UDP GRO by default.
> > >
> > > Patch 2 adds a netdev feature flag to enable listifyed GRO,
> > > this implements one of the configuration options discussed
> > > at netconf 2019.
> > >
> > > Patch 3 adds a netdev software feature set that defaults to off
> > > and assigns the new listifyed GRO feature flag to it.
> > >
> > > Patch 4 adds the core infrastructure to do fraglist GRO/GSO.
> > >
> > > Patch 5 enables UDP to use fraglist GRO/GSO if configured and no
> > > GRO supported socket is found.
> > 
> > Very nice feature, Steffen.
> 
> Thanks!
> 
> > Aside from questions around performance,
> > my only question is really how this relates to GSO_BY_FRAGS.
> > 
> > More specifically, whether we can remove that in favor of using your
> > new skb_segment_list. That would actually be a big first step in
> > simplifying skb_segment back to something manageable.
> 
> As Marcelo pointed out, this should be doable.

And easier than I had thought :)
But please let me know if you need anything on it. This approach is
much cleaner.

^ permalink raw reply

* Re: dsa traffic priorization
From: Jan Lübbe @ 2019-09-19 13:21 UTC (permalink / raw)
  To: Florian Fainelli, Vladimir Oltean, Sascha Hauer
  Cc: netdev, Vivien Didelot, kernel, Andrew Lunn
In-Reply-To: <1b80f9ed-7a62-99c4-10bc-bc1887f80867@gmail.com>

Hi,

On Wed, 2019-09-18 at 10:41 -0700, Florian Fainelli wrote:
> > Technically, configuring a match-all rxnfc rule with ethtool would
> > count as 'default priority' - I have proposed that before. Now I'm not
> > entirely sure how intuitive it is, but I'm also interested in being
> > able to configure this.
> 
> That does not sound too crazy from my perspective.

Sascha and myself aren't that familiar with that part of ethtool.
You're talking about using ethtool --config-nfc/--config-ntuple on the
(external) sw1p1, sw1p2 ports? Something like this (completely untested
from the manpage):
ethtool --config-nfc sw1p1 flow-type ether queue 2 # high prio queue for ethercat
ethtool --config-nfc sw1p2 flow-type ether queue 1 # normal for rest

Currently, there seems to be no "match-all" option.

Alternatives to "queue X" might be "action" or "context", but I don't
know enough about the details to prefer one above the other.

Regards,
Jan


^ permalink raw reply

* Re: [PATCH RFC v3 0/5] Support fraglist GRO/GSO
From: Willem de Bruijn @ 2019-09-19 13:25 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: Willem de Bruijn, Steffen Klassert, Network Development,
	Paolo Abeni
In-Reply-To: <20190919130746.GC3431@localhost.localdomain>

On Thu, Sep 19, 2019 at 9:07 AM Marcelo Ricardo Leitner
<marcelo.leitner@gmail.com> wrote:
>
> On Thu, Sep 19, 2019 at 08:55:22AM -0400, Willem de Bruijn wrote:
> > On Wed, Sep 18, 2019 at 12:58 PM Marcelo Ricardo Leitner
> > <marcelo.leitner@gmail.com> wrote:
> > >
> > > On Wed, Sep 18, 2019 at 12:17:08PM -0400, Willem de Bruijn wrote:
> > > > On Wed, Sep 18, 2019 at 3:25 AM Steffen Klassert
> > > > <steffen.klassert@secunet.com> wrote:
> > > > >
> > > > > This patchset adds support to do GRO/GSO by chaining packets
> > > > > of the same flow at the SKB frag_list pointer. This avoids
> > > > > the overhead to merge payloads into one big packet, and
> > > > > on the other end, if GSO is needed it avoids the overhead
> > > > > of splitting the big packet back to the native form.
> > > > >
> > > > > Patch 1 Enables UDP GRO by default.
> > > > >
> > > > > Patch 2 adds a netdev feature flag to enable listifyed GRO,
> > > > > this implements one of the configuration options discussed
> > > > > at netconf 2019.
> > > > >
> > > > > Patch 3 adds a netdev software feature set that defaults to off
> > > > > and assigns the new listifyed GRO feature flag to it.
> > > > >
> > > > > Patch 4 adds the core infrastructure to do fraglist GRO/GSO.
> > > > >
> > > > > Patch 5 enables UDP to use fraglist GRO/GSO if configured and no
> > > > > GRO supported socket is found.
> > > >
> > > > Very nice feature, Steffen. Aside from questions around performance,
> > > > my only question is really how this relates to GSO_BY_FRAGS.
> > >
> > > They do the exact same thing AFAICT: they GSO according to a
> > > pre-formatted list of fragments/packets, and not to a specific size
> > > (such as MSS).
> > >
> > > >
> > > > More specifically, whether we can remove that in favor of using your
> > > > new skb_segment_list. That would actually be a big first step in
> > > > simplifying skb_segment back to something manageable.
> > >
> > > The main issue (that I know) on obsoleting GSO_BY_FRAGS is that
> > > dealing with frags instead of frag_list was considered easier to be
> > > offloaded, if ever attempted.  So this would be a step back on that
> > > aspect.  Other than this, it should be doable.
> >
> > But GSO_BY_FRAGS also uses frag_list, not frags?
>
> /me is scratching his head.
> My bad. I thought it was already using frags. Thanks.
>
> >
> > And list_skb->len for mss.
>
> Which stands more for 'current frag size', yes.
> (list_skb, not head_skb)

Great. I thought I missed something :)

Frags might be cheaper from an allocation point. If at some point
going down that road.

But in the meantime, it looks like we can handle these too with
skb_segment_list, then (not necessarily in the initial patch set).

^ permalink raw reply

* Re: dsa traffic priorization
From: Vladimir Oltean @ 2019-09-19 13:33 UTC (permalink / raw)
  To: Jan Lübbe
  Cc: Florian Fainelli, Sascha Hauer, netdev, Vivien Didelot, kernel,
	Andrew Lunn
In-Reply-To: <06d2ca7441c899b4da8475f82dc706351edd0976.camel@pengutronix.de>

Hi Jan,

On Thu, 19 Sep 2019 at 16:21, Jan Lübbe <jlu@pengutronix.de> wrote:
>
> Hi,
>
> On Wed, 2019-09-18 at 10:41 -0700, Florian Fainelli wrote:
> > > Technically, configuring a match-all rxnfc rule with ethtool would
> > > count as 'default priority' - I have proposed that before. Now I'm not
> > > entirely sure how intuitive it is, but I'm also interested in being
> > > able to configure this.
> >
> > That does not sound too crazy from my perspective.
>
> Sascha and myself aren't that familiar with that part of ethtool.
> You're talking about using ethtool --config-nfc/--config-ntuple on the
> (external) sw1p1, sw1p2 ports? Something like this (completely untested
> from the manpage):
> ethtool --config-nfc sw1p1 flow-type ether queue 2 # high prio queue for ethercat
> ethtool --config-nfc sw1p2 flow-type ether queue 1 # normal for rest
>

Yes, something like that.

> Currently, there seems to be no "match-all" option.
>

Well, some keys for flow steering can be masked. See:

           src xx:yy:zz:aa:bb:cc [m xx:yy:zz:aa:bb:cc]
                  Includes the source MAC address, specified as 6
bytes in hexadecimal separated by colons, along with an optional mask.
Valid only for flow-type ether.

           dst xx:yy:zz:aa:bb:cc [m xx:yy:zz:aa:bb:cc]
                  Includes the destination MAC address, specified as 6
bytes in hexadecimal separated by colons, along with an optional mask.
Valid only for flow-type ether.

           proto N [m N]
                  Includes the Ethernet protocol number (ethertype)
and an optional mask.  Valid only for flow-type ether.

The idea is that any rule with e.g. src 00:00:00:00:00:00 and m
00:00:00:00:00:00 is an implicit match-all, because any (SMAC & m) ==
src.
The issue I see (and why I said it's not intuitive) is that there is
more than 1 way to express the same thing, and that it raises sanity
questions about rule ordering (if the rule is first, should all
subsequent flow steering rules be ignored?). Also, the driver would
have to open-code the "matchall" condition in order to detect it and
configure the default qpri.

It appears that there is a way to do this with tc-flower (or any other
classifier) as well, by specifying any null key with a mask of zero.

I don't know enough either to understand what is preferable.

> Alternatives to "queue X" might be "action" or "context", but I don't
> know enough about the details to prefer one above the other.
>
> Regards,
> Jan
>

Thanks,
-Vladimir

^ permalink raw reply

* Re: dsa traffic priorization
From: Andrew Lunn @ 2019-09-19 13:34 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Vladimir Oltean, netdev, Vivien Didelot, Florian Fainelli, kernel
In-Reply-To: <20190919080051.mr3cszpyypwqjwu4@pengutronix.de>

On Thu, Sep 19, 2019 at 10:00:51AM +0200, Sascha Hauer wrote:
> Hi Vladimir,
> 
> On Wed, Sep 18, 2019 at 05:36:08PM +0300, Vladimir Oltean wrote:
> > Hi Sascha,
> > 
> > On Wed, 18 Sep 2019 at 17:03, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > >
> > > Hi All,
> > >
> > > We have a customer using a Marvell 88e6240 switch with Ethercat on one port and
> > > regular network traffic on another port. The customer wants to configure two things
> > > on the switch: First Ethercat traffic shall be priorized over other network traffic
> > > (effectively prioritizing traffic based on port). Second the ethernet controller
> > > in the CPU is not able to handle full bandwidth traffic, so the traffic to the CPU
> > > port shall be rate limited.
> > >
> > 
> > You probably already know this, but egress shaping will not drop
> > frames, just let them accumulate in the egress queue until something
> > else happens (e.g. queue occupancy threshold triggers pause frames, or
> > tail dropping is enabled, etc). Is this what you want?
> 
> If I understand correctly then the switch has multiple output queues per
> port.

There are 4 egress queues per port.

> The Ethercat traffic will go to a higher priority queue and on
> congestion on other queues, frames designated for that queue will be
> dropped.

On ingress, there are various ways to add a priority to a frame, which
then determines which egress queue it lands in. This can be static,
all frames which ingress port X have priority Y. It can look at the
802.1p header and map the l2 priority to an queue priority. It can
look at the IPv4 TOS/DSCP value and map it to a queue priority. And
you can also use the TCAM, when it matches on a frame, it can specify
the frame priority.

If the egress queue, as selected by the queue priority is full, the
frame will be dropped.

> I just talked to our customer and he verified that their
> Ethercat traffic still goes through even when the ports with the general
> traffic are jammed with packets. So yes, I think this is what I want.

Taking frames out of the port egress queues and passing them out the
interface is then determined by the scheduler. There are two different
configurations which can be used

1) Strict priority. Frames are taken from the highest priority queue,
until it is empty. If the highest priority queue is empty, frames are
taken from the second highest priority queue. And if the second
priority is empty, the third priority queue is used, etc. This can
lead to starvation, when the lower priority queue never get serviced
because the higher priority queue have sufficient frames to keep the
line busy.

2) Weighted round robin. It takes up to 8 frames from the highest
priority queue, then up to 4 frames from the second highest priority
queue, then up to 2 frames from the 3rd highest priority queue, and
then 1 frame from the lower priority frame. And then it starts the
cycle again. This scheduler ensure there is no starvation of the
queues, but you do loose more high priority frames when congested.

> The bottleneck here is in the CPU interface. The SoC simply can't handle
> all frames coming into a fully occupied link, so we indeed have to limit
> the number of packets coming into the SoC which speaks for egress rate
> limiting. We could of course limit the ingress packets on the other
> ports, but that would mean we have to rate limit each port to the total
> desired rate divided by the number of ports to be safe, not very
> optimal.

Pause frames then start playing a role, maybe instead of, or in
combination with, egress traffic shaping.

If the SoC is overloaded, it can send a pause frame. The Switch will
then pause the scheduler. No packets are sent to the SoC, until it
unpauses. What i don't know is if the switch itself will send out
pause frames downstream, when egress queues are getting full. That
could have bad effects on overall network bandwidth, for frames which
are not destined for the SoC.

If you use egress shaping, you have to make a guess at how many bits
per second the SoC can handle, and configure the egress shaping to
that. The scheduler will then take frames from the queues at that
rate. At least for the older generation of switches, egress shaping
was rather course grained at the higher speed. Something like 500Mbps,
256Mbps, 128Mbps, 64Mbps, etc. So it might not do what you want. And
older generation switches, ingress shaping is very course grained,
mostly designed to limit broadcast storms.

There are lots of options here, how you solve your problem. But you
cannot look at just the SoC and switch combination. You need to look
at your whole network design. If you are using 802.1p, who is setting
the priority bits? If you are using TOS/DSCP, who is setting those
bits? Is there policing going on in the network edge to ensure other
traffic in the network is using the lower priority settings? Do you
really want Ethercat to take the highest priority? I would put it at
second priority, and make my SSH and SNMP client/server use the
highest priority, so when it all goes wrong, i can login and take a
look around to see what happened.

Once you have a network design, and know what you want the SoC/switch
combination to do, we can then figure out the correct API to configure
this. It might be TC with offloads, it might be ethtool with offloads,
etc.

	Andrew

^ permalink raw reply

* Re: dsa traffic priorization
From: Jan Lübbe @ 2019-09-19 13:35 UTC (permalink / raw)
  To: Florian Fainelli, Vladimir Oltean, Sascha Hauer
  Cc: netdev, Vivien Didelot, kernel, Andrew Lunn
In-Reply-To: <1b80f9ed-7a62-99c4-10bc-bc1887f80867@gmail.com>

On Wed, 2019-09-18 at 10:41 -0700, Florian Fainelli wrote:
> > > The other part of the problem seems to be that the CPU port has no network device
> > > representation in Linux, so there's no interface to configure the egress limits via tc.
> > > This has been discussed before, but it seems there hasn't been any consensous regarding how
> > > we want to proceed?
> 
> You have the DSA master network device which is on the other side of the
> switch,

We thought it might be intutive to allow configuration of this via tc
on the DSA master device (eth0, the i.MX FEC in our case). You'd
specify ingress policing via tc, and the kernel would try to hw-offload 
that to the switch's CPU egress side first, maybe fall back to offload
on the SoC's network controler and finally use the normal SW
implementation.

If that sounds reasonable, the next question would be how to express
matching on switchdev information (such as the ingress port or vlan
priority).

Regards,
Jan


^ permalink raw reply

* Re: [PATCH net-next] tcp: force a PSH flag on TSO packets
From: Eric Dumazet @ 2019-09-19 13:46 UTC (permalink / raw)
  To: Or Gerlitz, Eric Dumazet
  Cc: David S . Miller, netdev, Eric Dumazet, Soheil Hassas Yeganeh,
	Neal Cardwell, Yuchung Cheng, Daniel Borkmann, Tariq Toukan
In-Reply-To: <CAJ3xEMhh=Ow-fZqnPtxUyZsCN89dRmy=NcaO+iK+iZZYBdZbqA@mail.gmail.com>



On 9/19/19 5:17 AM, Or Gerlitz wrote:
> On Wed, Sep 11, 2019 at 12:54 AM Eric Dumazet <edumazet@google.com> wrote:
>> When tcp sends a TSO packet, adding a PSH flag on it
>> reduces the sojourn time of GRO packet in GRO receivers.
>>
>> This is particularly the case under pressure, since RX queues
>> receive packets for many concurrent flows.
>>
>> A sender can give a hint to GRO engines when it is
>> appropriate to flush a super-packet, especially when pacing
> 
> Hi Eric,
> 
> Is this correct that we add here the push flag for the tcp header template
> from which all the tcp headers for SW GSO packets will be generated?
> 
> Wouldn't that cause a too early flush on GRO engines at the receiver side?


If a TSO engine is buggy enough to add the PSH on all the segments, it needs
to be fixed urgently :)


^ permalink raw reply

* Re: [PATCH RFC v3 0/5] Support fraglist GRO/GSO
From: Paolo Abeni @ 2019-09-19 13:51 UTC (permalink / raw)
  To: Or Gerlitz, Steffen Klassert, Edward Cree, Willem de Bruijn
  Cc: Linux Netdev List
In-Reply-To: <CAJ3xEMjucmc-6k=kvEp99uZbCA50tUwPMK1z__wAG+ah7qNzsg@mail.gmail.com>

On Thu, 2019-09-19 at 15:37 +0300, Or Gerlitz wrote:
> On Wed, Sep 18, 2019 at 2:48 PM Steffen Klassert
> <steffen.klassert@secunet.com> wrote:
> > This patchset adds support to do GRO/GSO by chaining packets
> > of the same flow at the SKB frag_list pointer. This avoids
> > the overhead to merge payloads into one big packet, and
> > on the other end, if GSO is needed it avoids the overhead
> > of splitting the big packet back to the native form.
> > 
> > Patch 1 Enables UDP GRO by default.
> > 
> > Patch 2 adds a netdev feature flag to enable listifyed GRO,
> > this implements one of the configuration options discussed
> > at netconf 2019.
> [..]
> 
> The slide say that linked packets travel together though the stack.
> 
> This sounds somehow similar to the approach suggested by Ed
> for skb lists. I wonder what we can say on cases where each of the
> approaches would function better.

The 'listification' by Ed Cree can potentially aggregate across
multiple flows, so it can trigger when UDP GRO can not.

On the other side, fraglist performance impact is more limited, because
we still have to walk the list on each step. UDP GRO will improve
performances considerably more, if it can be triggered - e.g. all pkts
belong to the same flow.

Cheers,

Paolo


^ permalink raw reply

* [PATCH v2 00/20] Add support for Silicon Labs WiFi chip WF200 and further
From: Jerome Pouiller @ 2019-09-19 13:52 UTC (permalink / raw)
  To: devel@driverdev.osuosl.org, linux-wireless@vger.kernel.org
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Greg Kroah-Hartman, Kalle Valo, David S . Miller, David Le Goff,
	Jerome Pouiller

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

Hello all,

This series add support for Silicon Labs WiFi chip WF200 and further:

   https://www.silabs.com/documents/public/data-sheets/wf200-datasheet.pdf

This driver is an export from:

   https://github.com/SiliconLabs/wfx-linux-driver/
   
I squashed all commits from github (it definitely does not make sense to
import history). Then I split it in comprehensible (at least try to be)
commits. I hope it will help readers to understand driver architecture.
IMHO, firsts commits are clean enough to be reviewed. Things get more
difficult when I introduce mac8011 API. I tried to extract important
parts like Rx/Tx process but, big and complex patches seem unavoidable
in this part.

Architecture itself is described in commit messages.

The series below is aligned on version 2.3.1 on github. If compare this
series with github, you will find traditional differences between
external and a in-tree driver: Documentation, build infrastructure,
compatibility with older kernel revisions, etc... In add, I dropped all
code in CONFIG_WFX_SECURE_LINK. Indeed, "Secure Link" feature depends
on mbedtls and I don't think to pull mbedtls in kernel is an option
(see "TODO" file in first commit).


Changes in v2:
  - Add TODO file (and dropped todo list from cover letter)
  - Drop code relative to compatibility with older kernels
  
Jérôme Pouiller (20):
  staging: wfx: add infrastructure for new driver
  staging: wfx: add support for I/O access
  staging: wfx: add I/O API
  staging: wfx: add tracepoints for I/O access
  staging: wfx: load firmware
  staging: wfx: import HIF API headers
  staging: wfx: add IRQ handling
  staging: wfx: add tracepoints for HIF
  staging: wfx: add support for start-up indication
  staging: wfx: instantiate mac80211 data
  staging: wfx: allow to send commands to chip
  staging: wfx: add HIF commands helpers
  staging: wfx: introduce "secure link"
  staging: wfx: setup initial chip configuration
  staging: wfx: add debug files and trace debug events
  staging: wfx: allow to send 802.11 frames
  staging: wfx: allow to receive 802.11 frames
  staging: wfx: allow to scan networks
  staging: wfx: implement 802.11 key handling
  staging: wfx: implement the rest of mac80211 API

 MAINTAINERS                                   |    5 +
 drivers/staging/Kconfig                       |    2 +
 drivers/staging/Makefile                      |    1 +
 .../bindings/net/wireless/siliabs,wfx.txt     |   97 +
 drivers/staging/wfx/Kconfig                   |    7 +
 drivers/staging/wfx/Makefile                  |   24 +
 drivers/staging/wfx/TODO                      |   20 +
 drivers/staging/wfx/bh.c                      |  316 ++++
 drivers/staging/wfx/bh.h                      |   32 +
 drivers/staging/wfx/bus.h                     |   34 +
 drivers/staging/wfx/bus_sdio.c                |  268 +++
 drivers/staging/wfx/bus_spi.c                 |  264 +++
 drivers/staging/wfx/data_rx.c                 |  208 +++
 drivers/staging/wfx/data_rx.h                 |   18 +
 drivers/staging/wfx/data_tx.c                 |  799 ++++++++
 drivers/staging/wfx/data_tx.h                 |   93 +
 drivers/staging/wfx/debug.c                   |  305 +++
 drivers/staging/wfx/debug.h                   |   19 +
 drivers/staging/wfx/fwio.c                    |  387 ++++
 drivers/staging/wfx/fwio.h                    |   15 +
 drivers/staging/wfx/hif_api_cmd.h             |  681 +++++++
 drivers/staging/wfx/hif_api_general.h         |  437 +++++
 drivers/staging/wfx/hif_api_mib.h             |  558 ++++++
 drivers/staging/wfx/hif_rx.c                  |  336 ++++
 drivers/staging/wfx/hif_rx.h                  |   18 +
 drivers/staging/wfx/hif_tx.c                  |  470 +++++
 drivers/staging/wfx/hif_tx.h                  |   67 +
 drivers/staging/wfx/hif_tx_mib.h              |  281 +++
 drivers/staging/wfx/hwio.c                    |  338 ++++
 drivers/staging/wfx/hwio.h                    |   75 +
 drivers/staging/wfx/key.c                     |  258 +++
 drivers/staging/wfx/key.h                     |   22 +
 drivers/staging/wfx/main.c                    |  500 +++++
 drivers/staging/wfx/main.h                    |   48 +
 drivers/staging/wfx/queue.c                   |  606 ++++++
 drivers/staging/wfx/queue.h                   |   59 +
 drivers/staging/wfx/scan.c                    |  289 +++
 drivers/staging/wfx/scan.h                    |   42 +
 drivers/staging/wfx/secure_link.h             |   46 +
 drivers/staging/wfx/sta.c                     | 1643 +++++++++++++++++
 drivers/staging/wfx/sta.h                     |  101 +
 drivers/staging/wfx/traces.h                  |  434 +++++
 drivers/staging/wfx/wfx.h                     |  204 ++
 drivers/staging/wfx/wfx_version.h             |    3 +
 44 files changed, 10430 insertions(+)
 create mode 100644 drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt
 create mode 100644 drivers/staging/wfx/Kconfig
 create mode 100644 drivers/staging/wfx/Makefile
 create mode 100644 drivers/staging/wfx/TODO
 create mode 100644 drivers/staging/wfx/bh.c
 create mode 100644 drivers/staging/wfx/bh.h
 create mode 100644 drivers/staging/wfx/bus.h
 create mode 100644 drivers/staging/wfx/bus_sdio.c
 create mode 100644 drivers/staging/wfx/bus_spi.c
 create mode 100644 drivers/staging/wfx/data_rx.c
 create mode 100644 drivers/staging/wfx/data_rx.h
 create mode 100644 drivers/staging/wfx/data_tx.c
 create mode 100644 drivers/staging/wfx/data_tx.h
 create mode 100644 drivers/staging/wfx/debug.c
 create mode 100644 drivers/staging/wfx/debug.h
 create mode 100644 drivers/staging/wfx/fwio.c
 create mode 100644 drivers/staging/wfx/fwio.h
 create mode 100644 drivers/staging/wfx/hif_api_cmd.h
 create mode 100644 drivers/staging/wfx/hif_api_general.h
 create mode 100644 drivers/staging/wfx/hif_api_mib.h
 create mode 100644 drivers/staging/wfx/hif_rx.c
 create mode 100644 drivers/staging/wfx/hif_rx.h
 create mode 100644 drivers/staging/wfx/hif_tx.c
 create mode 100644 drivers/staging/wfx/hif_tx.h
 create mode 100644 drivers/staging/wfx/hif_tx_mib.h
 create mode 100644 drivers/staging/wfx/hwio.c
 create mode 100644 drivers/staging/wfx/hwio.h
 create mode 100644 drivers/staging/wfx/key.c
 create mode 100644 drivers/staging/wfx/key.h
 create mode 100644 drivers/staging/wfx/main.c
 create mode 100644 drivers/staging/wfx/main.h
 create mode 100644 drivers/staging/wfx/queue.c
 create mode 100644 drivers/staging/wfx/queue.h
 create mode 100644 drivers/staging/wfx/scan.c
 create mode 100644 drivers/staging/wfx/scan.h
 create mode 100644 drivers/staging/wfx/secure_link.h
 create mode 100644 drivers/staging/wfx/sta.c
 create mode 100644 drivers/staging/wfx/sta.h
 create mode 100644 drivers/staging/wfx/traces.h
 create mode 100644 drivers/staging/wfx/wfx.h
 create mode 100644 drivers/staging/wfx/wfx_version.h

-- 
2.20.1

-- 
Jérôme Pouiller
Silicon Labs

^ permalink raw reply

* [PATCH v2 01/20] staging: wfx: add infrastructure for new driver
From: Jerome Pouiller @ 2019-09-19 13:52 UTC (permalink / raw)
  To: devel@driverdev.osuosl.org, linux-wireless@vger.kernel.org
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Greg Kroah-Hartman, Kalle Valo, David S . Miller, David Le Goff,
	Jerome Pouiller
In-Reply-To: <20190919135220.30663-1-Jerome.Pouiller@silabs.com>

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

Instantiate build infrastructure WFx driver. This driver provides support
for Wifi chipset Silicon Labs WF200 and further:

   https://www.silabs.com/documents/public/data-sheets/wf200-datasheet.pdf

This chip support SPI and SDIO bus.

SDIO interface has two particularities:
    1. Some parameters may be useful for end user (I will talk about
       gpio_wakeup later).
    2. The SDIO VID and PID of WF200 are 0000:0001 which are too much
       generic to rely on.

So, current code checks VID/PID and looks for a node in DT (since WF200
targets embedded platforms, I don't think it is a problem to rely on
DT). DT can also be used to define to parameters for driver. Currently,
if no node is found, a warning is emitted, but it could be changed in
error.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 MAINTAINERS                                   |  5 +
 drivers/staging/Kconfig                       |  2 +
 drivers/staging/Makefile                      |  1 +
 .../bindings/net/wireless/siliabs,wfx.txt     | 97 +++++++++++++++++++
 drivers/staging/wfx/Kconfig                   |  7 ++
 drivers/staging/wfx/Makefile                  |  8 ++
 drivers/staging/wfx/TODO                      | 20 ++++
 drivers/staging/wfx/bus.h                     | 17 ++++
 drivers/staging/wfx/bus_sdio.c                | 70 +++++++++++++
 drivers/staging/wfx/bus_spi.c                 | 53 ++++++++++
 drivers/staging/wfx/main.c                    | 47 +++++++++
 drivers/staging/wfx/wfx_version.h             |  3 +
 12 files changed, 330 insertions(+)
 create mode 100644 drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt
 create mode 100644 drivers/staging/wfx/Kconfig
 create mode 100644 drivers/staging/wfx/Makefile
 create mode 100644 drivers/staging/wfx/TODO
 create mode 100644 drivers/staging/wfx/bus.h
 create mode 100644 drivers/staging/wfx/bus_sdio.c
 create mode 100644 drivers/staging/wfx/bus_spi.c
 create mode 100644 drivers/staging/wfx/main.c
 create mode 100644 drivers/staging/wfx/wfx_version.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b2326dece28e..0ad6fbde3ac9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14755,6 +14755,11 @@ S:	Maintained
 F:	drivers/input/touchscreen/silead.c
 F:	drivers/platform/x86/touchscreen_dmi.c
 
+SILICON LABS WIRELESS DRIVERS (for WFxxx series)
+M:	Jérôme Pouiller <jerome.pouiller@silabs.com>
+S:	Supported
+F:	drivers/staging/wfx/
+
 SILICON MOTION SM712 FRAME BUFFER DRIVER
 M:	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
 M:	Teddy Wang <teddy.wang@siliconmotion.com>
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 6f1fa4c849a1..a490141a0e88 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -125,4 +125,6 @@ source "drivers/staging/exfat/Kconfig"
 
 source "drivers/staging/qlge/Kconfig"
 
+source "drivers/staging/wfx/Kconfig"
+
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index a90f9b308c8d..4cb548a0ff87 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -53,3 +53,4 @@ obj-$(CONFIG_UWB)		+= uwb/
 obj-$(CONFIG_USB_WUSB)		+= wusbcore/
 obj-$(CONFIG_EXFAT_FS)		+= exfat/
 obj-$(CONFIG_QLGE)		+= qlge/
+obj-$(CONFIG_WFX)		+= wfx/
diff --git a/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt b/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt
new file mode 100644
index 000000000000..15965c9b4180
--- /dev/null
+++ b/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt
@@ -0,0 +1,97 @@
+The WFxxx chip series can be connected via SPI or via SDIO.
+
+SPI
+---
+
+You have to declare the WFxxx chip in your device tree.
+
+Required properties:
+ - compatible: Should be "silabs,wfx-spi"
+ - reg: Chip select address of device
+ - spi-max-frequency: Maximum SPI clocking speed of device in Hz
+ - interrupts-extended: Should contain interrupt line (interrupt-parent +
+   interrupt can also been used). Trigger should be `IRQ_TYPE_EDGE_RISING`.
+
+Optional properties:
+ - reset-gpios: phandle of gpio that will be used to reset chip during probe.
+   Without this property, you may encounter issues with warm boot.
+
+Please consult Documentation/devicetree/bindings/spi/spi-bus.txt for optional
+SPI connection related properties,
+
+Example:
+
+&spi1 {
+	wfx {
+		compatible = "silabs,wfx-spi";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wfx_irq &wfx_gpios>;
+		interrupts-extended = <&gpio 16 IRQ_TYPE_EDGE_RISING>;
+		wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		reg = <0>;
+		spi-max-frequency = <42000000>;
+	};
+};
+
+
+SDIO
+----
+
+The driver is able to detect a WFxxx chip on SDIO bus by matching its Vendor ID
+and Product ID. However, driver will only provide limited features in this
+case. Thus declaring WFxxx chip in device tree is strongly recommended (and may
+become mandatory in the future).
+
+Required properties:
+ - compatible: Should be "silabs,wfx-sdio"
+ - reg: Should be 1
+
+In addition, it is recommended to declare a mmc-pwrseq on SDIO host above WFx.
+Without it, you may encounter issues with warm boot. mmc-pwrseq should be
+compatible with mmc-pwrseq-simple. Please consult
+Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt for more
+information.
+
+Example:
+
+/ {
+	wfx_pwrseq: wfx_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wfx_reset>;
+		reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&mmc1 {
+	mmc-pwrseq = <&wfx_pwrseq>;
+	#address-size = <1>;
+	#size = <0>;
+
+	mmc@1 {
+		compatible = "silabs,wfx-sdio";
+		reg = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wfx_wakeup>;
+		wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+Note that #address-size and #size shoud already be defined in node mmc1, but it
+is rarely the case.
+
+Common properties
+-----------------
+
+Some properties are recognized either by SPI and SDIO versions:
+ - wakeup-gpios: phandle of gpio that will be used to wake-up chip. Without
+   this property, driver will disable most of power saving features.
+ - config-file: Use an alternative file as PDS. Default is `wf200.pds`. Only
+   necessary for development/debug purpose.
+ - slk_key: String representing hexdecimal value of secure link key to use.
+   Must contains 64 hexadecimal digits. Not supported in current version.
+
+WFx driver also supports `mac-address` and `local-mac-address` as described in
+Documentation/devicetree/binding/net/ethernet.txt
+
diff --git a/drivers/staging/wfx/Kconfig b/drivers/staging/wfx/Kconfig
new file mode 100644
index 000000000000..9b8a1c7a9e90
--- /dev/null
+++ b/drivers/staging/wfx/Kconfig
@@ -0,0 +1,7 @@
+config WFX
+	tristate "Silicon Labs wireless chips WF200 and further"
+	depends on MAC80211
+	depends on (SPI || MMC)
+	help
+	  This is a driver for Silicons Labs WFxxx series (WF200 and further)
+	  chipsets. This chip can be found on SPI or SDIO buses.
diff --git a/drivers/staging/wfx/Makefile b/drivers/staging/wfx/Makefile
new file mode 100644
index 000000000000..74939a5a0a1c
--- /dev/null
+++ b/drivers/staging/wfx/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+
+wfx-y := \
+	main.o
+wfx-$(CONFIG_SPI) += bus_spi.o
+wfx-$(subst m,y,$(CONFIG_MMC)) += bus_sdio.o
+
+obj-$(CONFIG_WFX) += wfx.o
diff --git a/drivers/staging/wfx/TODO b/drivers/staging/wfx/TODO
new file mode 100644
index 000000000000..be990e8f18b1
--- /dev/null
+++ b/drivers/staging/wfx/TODO
@@ -0,0 +1,20 @@
+This is a list of things that need to be done to get this driver out of the
+staging directory.
+
+  - wfx_version.h is still there in order to ensure synchronization with github.
+    It can be dropped as soon as development is entirely in kernel
+
+  - I have to take a decision about secure link support. I can:
+      - drop completely
+      - keep it in an external patch (my preferred option)
+      - replace call to mbedtls with kernel crypto API (necessitate a
+        bunch of work)
+      - pull mbedtls in kernel (non-realistic)
+
+  - mac80211 interface does not (yet) have expected quality to be placed
+    outside of staging:
+      - Some processings are redundant with mac80211 ones
+      - Many members from wfx_dev/wfx_vif can be retrieved from mac80211
+        structures
+      - Some functions are too complex
+      - ...
diff --git a/drivers/staging/wfx/bus.h b/drivers/staging/wfx/bus.h
new file mode 100644
index 000000000000..8ce871a8a9ff
--- /dev/null
+++ b/drivers/staging/wfx/bus.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Common bus abstraction layer.
+ *
+ * Copyright (c) 2017-2018, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#ifndef WFX_BUS_H
+#define WFX_BUS_H
+
+#include <linux/mmc/sdio_func.h>
+#include <linux/spi/spi.h>
+
+extern struct sdio_driver wfx_sdio_driver;
+extern struct spi_driver wfx_spi_driver;
+
+#endif
diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c
new file mode 100644
index 000000000000..4b26c994f43c
--- /dev/null
+++ b/drivers/staging/wfx/bus_sdio.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SDIO interface.
+ *
+ * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#include <linux/module.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+#include <linux/of_irq.h>
+
+#include "bus.h"
+
+static const struct of_device_id wfx_sdio_of_match[];
+static int wfx_sdio_probe(struct sdio_func *func,
+			  const struct sdio_device_id *id)
+{
+	struct device_node *np = func->dev.of_node;
+
+	if (func->num != 1) {
+		dev_err(&func->dev, "SDIO function number is %d while it should always be 1 (unsupported chip?)\n", func->num);
+		return -ENODEV;
+	}
+
+	if (np) {
+		if (!of_match_node(wfx_sdio_of_match, np)) {
+			dev_warn(&func->dev, "no compatible device found in DT\n");
+			return -ENODEV;
+		}
+	} else {
+		dev_warn(&func->dev, "device is not declared in DT, features will be limited\n");
+		// FIXME: ignore VID/PID and only rely on device tree
+		// return -ENODEV;
+	}
+	return -EIO; // FIXME: not yet supported
+}
+
+static void wfx_sdio_remove(struct sdio_func *func)
+{
+}
+
+#define SDIO_VENDOR_ID_SILABS        0x0000
+#define SDIO_DEVICE_ID_SILABS_WF200  0x1000
+static const struct sdio_device_id wfx_sdio_ids[] = {
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_SILABS, SDIO_DEVICE_ID_SILABS_WF200) },
+	// FIXME: ignore VID/PID and only rely on device tree
+	// { SDIO_DEVICE(SDIO_ANY_ID, SDIO_ANY_ID) },
+	{ },
+};
+MODULE_DEVICE_TABLE(sdio, wfx_sdio_ids);
+
+#ifdef CONFIG_OF
+static const struct of_device_id wfx_sdio_of_match[] = {
+	{ .compatible = "silabs,wfx-sdio" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, wfx_sdio_of_match);
+#endif
+
+struct sdio_driver wfx_sdio_driver = {
+	.name = "wfx-sdio",
+	.id_table = wfx_sdio_ids,
+	.probe = wfx_sdio_probe,
+	.remove = wfx_sdio_remove,
+	.drv = {
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(wfx_sdio_of_match),
+	}
+};
diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c
new file mode 100644
index 000000000000..574b60f513e9
--- /dev/null
+++ b/drivers/staging/wfx/bus_spi.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SPI interface.
+ *
+ * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
+ * Copyright (c) 2011, Sagrad Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/of.h>
+
+#include "bus.h"
+
+static int wfx_spi_probe(struct spi_device *func)
+{
+	return -EIO;
+}
+
+/* Disconnect Function to be called by SPI stack when device is disconnected */
+static int wfx_spi_disconnect(struct spi_device *func)
+{
+	return 0;
+}
+
+/*
+ * For dynamic driver binding, kernel does not use OF to match driver. It only
+ * use modalias and modalias is a copy of 'compatible' DT node with vendor
+ * stripped.
+ */
+static const struct spi_device_id wfx_spi_id[] = {
+	{ "wfx-spi", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, wfx_spi_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id wfx_spi_of_match[] = {
+	{ .compatible = "silabs,wfx-spi" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, wfx_spi_of_match);
+#endif
+
+struct spi_driver wfx_spi_driver = {
+	.driver = {
+		.name = "wfx-spi",
+		.of_match_table = of_match_ptr(wfx_spi_of_match),
+	},
+	.id_table = wfx_spi_id,
+	.probe = wfx_spi_probe,
+	.remove = wfx_spi_disconnect,
+};
diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c
new file mode 100644
index 000000000000..cd69f955f531
--- /dev/null
+++ b/drivers/staging/wfx/main.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Device probe and register.
+ *
+ * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ * Copyright (c) 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ */
+#include <linux/module.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+
+#include "bus.h"
+#include "wfx_version.h"
+
+MODULE_DESCRIPTION("Silicon Labs 802.11 Wireless LAN driver for WFx");
+MODULE_AUTHOR("Jérôme Pouiller <jerome.pouiller@silabs.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(WFX_LABEL);
+
+static int __init wfx_core_init(void)
+{
+	int ret = 0;
+
+	pr_info("wfx: Silicon Labs " WFX_LABEL "\n");
+
+	if (IS_ENABLED(CONFIG_SPI))
+		ret = spi_register_driver(&wfx_spi_driver);
+	if (IS_ENABLED(CONFIG_MMC) && !ret)
+		ret = sdio_register_driver(&wfx_sdio_driver);
+	return ret;
+}
+module_init(wfx_core_init);
+
+static void __exit wfx_core_exit(void)
+{
+	if (IS_ENABLED(CONFIG_MMC))
+		sdio_unregister_driver(&wfx_sdio_driver);
+	if (IS_ENABLED(CONFIG_SPI))
+		spi_unregister_driver(&wfx_spi_driver);
+}
+module_exit(wfx_core_exit);
diff --git a/drivers/staging/wfx/wfx_version.h b/drivers/staging/wfx/wfx_version.h
new file mode 100644
index 000000000000..6e7f30207c73
--- /dev/null
+++ b/drivers/staging/wfx/wfx_version.h
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT! */
+#define WFX_LABEL "2.3.1"
-- 
2.20.1

^ permalink raw reply related

* [PATCH v2 18/20] staging: wfx: allow to scan networks
From: Jerome Pouiller @ 2019-09-19 13:52 UTC (permalink / raw)
  To: devel@driverdev.osuosl.org, linux-wireless@vger.kernel.org
  Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Greg Kroah-Hartman, Kalle Valo, David S . Miller, David Le Goff,
	Jerome Pouiller
In-Reply-To: <20190919135220.30663-1-Jerome.Pouiller@silabs.com>

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

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/Makefile |   1 +
 drivers/staging/wfx/bh.c     |   2 +-
 drivers/staging/wfx/hif_rx.c |  13 ++
 drivers/staging/wfx/main.c   |   5 +
 drivers/staging/wfx/scan.c   | 249 +++++++++++++++++++++++++++++++++++
 drivers/staging/wfx/scan.h   |  42 ++++++
 drivers/staging/wfx/sta.c    |  23 +++-
 drivers/staging/wfx/sta.h    |   4 +
 drivers/staging/wfx/wfx.h    |  11 ++
 9 files changed, 348 insertions(+), 2 deletions(-)
 create mode 100644 drivers/staging/wfx/scan.c
 create mode 100644 drivers/staging/wfx/scan.h

diff --git a/drivers/staging/wfx/Makefile b/drivers/staging/wfx/Makefile
index d9e21515d08e..2b8a5fa86fac 100644
--- a/drivers/staging/wfx/Makefile
+++ b/drivers/staging/wfx/Makefile
@@ -12,6 +12,7 @@ wfx-y := \
 	queue.o \
 	data_tx.o \
 	data_rx.o \
+	scan.o \
 	sta.o \
 	main.o \
 	sta.o \
diff --git a/drivers/staging/wfx/bh.c b/drivers/staging/wfx/bh.c
index ed81c3924d98..6000c03bb658 100644
--- a/drivers/staging/wfx/bh.c
+++ b/drivers/staging/wfx/bh.c
@@ -268,7 +268,7 @@ static void bh_work(struct work_struct *work)
 
 	if (last_op_is_rx)
 		ack_sdio_data(wdev);
-	if (!wdev->hif.tx_buffers_used && !work_pending(work)) {
+	if (!wdev->hif.tx_buffers_used && !work_pending(work) && !atomic_read(&wdev->scan_in_progress)) {
 		device_release(wdev);
 		release_chip = true;
 	}
diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c
index c07984b0535d..d386fab0a90f 100644
--- a/drivers/staging/wfx/hif_rx.c
+++ b/drivers/staging/wfx/hif_rx.c
@@ -11,6 +11,7 @@
 
 #include "hif_rx.h"
 #include "wfx.h"
+#include "scan.h"
 #include "data_rx.h"
 #include "secure_link.h"
 #include "hif_api_cmd.h"
@@ -143,6 +144,17 @@ static int hif_receive_indication(struct wfx_dev *wdev, struct hif_msg *hif, voi
 	return 0;
 }
 
+static int hif_scan_complete_indication(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
+{
+	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
+	struct hif_ind_scan_cmpl *body = buf;
+
+	WARN_ON(!wvif);
+	wfx_scan_complete_cb(wvif, body);
+
+	return 0;
+}
+
 static int hif_join_complete_indication(struct wfx_dev *wdev, struct hif_msg *hif, void *buf)
 {
 	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
@@ -230,6 +242,7 @@ static const struct {
 	{ HIF_IND_ID_STARTUP,              hif_startup_indication },
 	{ HIF_IND_ID_WAKEUP,               hif_wakeup_indication },
 	{ HIF_IND_ID_JOIN_COMPLETE,        hif_join_complete_indication },
+	{ HIF_IND_ID_SCAN_CMPL,            hif_scan_complete_indication },
 	{ HIF_IND_ID_SL_EXCHANGE_PUB_KEYS, hif_keys_indication },
 	{ HIF_IND_ID_GENERIC,              hif_generic_indication },
 	{ HIF_IND_ID_ERROR,                hif_error_indication },
diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c
index cce4e30dd94a..06220bac5b75 100644
--- a/drivers/staging/wfx/main.c
+++ b/drivers/staging/wfx/main.c
@@ -55,6 +55,7 @@ static const struct ieee80211_ops wfx_ops = {
 	.add_interface		= wfx_add_interface,
 	.remove_interface	= wfx_remove_interface,
 	.tx			= wfx_tx,
+	.hw_scan		= wfx_hw_scan,
 };
 
 bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor)
@@ -203,6 +204,8 @@ struct wfx_dev *wfx_init_common(struct device *dev,
 	hw->extra_tx_headroom = sizeof(struct hif_sl_msg_hdr) + sizeof(struct hif_msg)
 				+ sizeof(struct hif_req_tx)
 				+ 4 /* alignment */ + 8 /* TKIP IV */;
+	hw->wiphy->max_scan_ssids = 2;
+	hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
 
 	wdev = hw->priv;
 	wdev->hw = hw;
@@ -214,6 +217,7 @@ struct wfx_dev *wfx_init_common(struct device *dev,
 	wdev->pdata.gpio_wakeup = wfx_get_gpio(dev, gpio_wakeup, "wakeup");
 	wfx_fill_sl_key(dev, &wdev->pdata);
 
+	mutex_init(&wdev->conf_mutex);
 	mutex_init(&wdev->rx_stats_lock);
 	init_completion(&wdev->firmware_ready);
 	wfx_init_hif_cmd(&wdev->hif_cmd);
@@ -225,6 +229,7 @@ struct wfx_dev *wfx_init_common(struct device *dev,
 void wfx_free_common(struct wfx_dev *wdev)
 {
 	mutex_destroy(&wdev->rx_stats_lock);
+	mutex_destroy(&wdev->conf_mutex);
 	wfx_tx_queues_deinit(wdev);
 	ieee80211_free_hw(wdev->hw);
 }
diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c
new file mode 100644
index 000000000000..207b26ebc9fd
--- /dev/null
+++ b/drivers/staging/wfx/scan.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Scan related functions.
+ *
+ * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#include <net/mac80211.h>
+
+#include "scan.h"
+#include "wfx.h"
+#include "sta.h"
+#include "hif_tx_mib.h"
+
+static void __ieee80211_scan_completed_compat(struct ieee80211_hw *hw, bool aborted)
+{
+	struct cfg80211_scan_info info = {
+		.aborted = aborted ? 1 : 0,
+	};
+
+	ieee80211_scan_completed(hw, &info);
+}
+
+static int wfx_scan_start(struct wfx_vif *wvif, struct wfx_scan_params *scan)
+{
+	int ret;
+	int tmo = 500;
+
+	tmo += scan->scan_req.num_of_channels *
+	       ((20 * (scan->scan_req.max_channel_time)) + 10);
+	atomic_set(&wvif->scan.in_progress, 1);
+	atomic_set(&wvif->wdev->scan_in_progress, 1);
+
+	schedule_delayed_work(&wvif->scan.timeout, msecs_to_jiffies(tmo));
+	ret = hif_scan(wvif, scan);
+	if (ret) {
+		wfx_scan_failed_cb(wvif);
+		atomic_set(&wvif->scan.in_progress, 0);
+		atomic_set(&wvif->wdev->scan_in_progress, 0);
+		cancel_delayed_work_sync(&wvif->scan.timeout);
+	}
+	return ret;
+}
+
+int wfx_hw_scan(struct ieee80211_hw *hw,
+		   struct ieee80211_vif *vif,
+		   struct ieee80211_scan_request *hw_req)
+{
+	struct wfx_dev *wdev = hw->priv;
+	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
+	struct cfg80211_scan_request *req = &hw_req->req;
+	struct sk_buff *skb;
+	int i, ret;
+	struct hif_mib_template_frame *p;
+
+	if (!wvif)
+		return -EINVAL;
+
+	if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
+		req->n_ssids = 0;
+
+	if (req->n_ssids > HIF_API_MAX_NB_SSIDS)
+		return -EINVAL;
+
+	skb = ieee80211_probereq_get(hw, wvif->vif->addr, NULL, 0, req->ie_len);
+	if (!skb)
+		return -ENOMEM;
+
+	if (req->ie_len)
+		memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
+
+	mutex_lock(&wdev->conf_mutex);
+
+	p = (struct hif_mib_template_frame *)skb_push(skb, 4);
+	p->frame_type = HIF_TMPLT_PRBREQ;
+	p->frame_length = cpu_to_le16(skb->len - 4);
+	ret = hif_set_template_frame(wvif, p);
+	skb_pull(skb, 4);
+
+	if (!ret)
+		/* Host want to be the probe responder. */
+		ret = wfx_fwd_probe_req(wvif, true);
+	if (ret) {
+		mutex_unlock(&wdev->conf_mutex);
+		dev_kfree_skb(skb);
+		return ret;
+	}
+
+	wfx_tx_lock_flush(wdev);
+
+	BUG_ON(wvif->scan.req);
+	wvif->scan.req = req;
+	wvif->scan.n_ssids = 0;
+	wvif->scan.status = 0;
+	wvif->scan.begin = &req->channels[0];
+	wvif->scan.curr = wvif->scan.begin;
+	wvif->scan.end = &req->channels[req->n_channels];
+	wvif->scan.output_power = wdev->output_power;
+
+	for (i = 0; i < req->n_ssids; ++i) {
+		struct hif_ssid_def *dst = &wvif->scan.ssids[wvif->scan.n_ssids];
+
+		memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
+		dst->ssid_length = req->ssids[i].ssid_len;
+		++wvif->scan.n_ssids;
+	}
+
+	mutex_unlock(&wdev->conf_mutex);
+
+	if (skb)
+		dev_kfree_skb(skb);
+	schedule_work(&wvif->scan.work);
+	return 0;
+}
+
+void wfx_scan_work(struct work_struct *work)
+{
+	struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan.work);
+	struct ieee80211_channel **it;
+	struct wfx_scan_params scan = {
+		.scan_req.scan_type.type = 0,    /* Foreground */
+	};
+	struct ieee80211_channel *first;
+	int i;
+
+	down(&wvif->scan.lock);
+	mutex_lock(&wvif->wdev->conf_mutex);
+
+	if (!wvif->scan.req || wvif->scan.curr == wvif->scan.end) {
+		if (wvif->scan.output_power != wvif->wdev->output_power)
+			hif_set_output_power(wvif, wvif->wdev->output_power * 10);
+
+		if (wvif->scan.status < 0)
+			dev_warn(wvif->wdev->dev, "scan failed\n");
+		else if (wvif->scan.req)
+			dev_dbg(wvif->wdev->dev, "scan completed\n");
+		else
+			dev_dbg(wvif->wdev->dev, "scan canceled\n");
+
+		wvif->scan.req = NULL;
+		wfx_tx_unlock(wvif->wdev);
+		mutex_unlock(&wvif->wdev->conf_mutex);
+		__ieee80211_scan_completed_compat(wvif->wdev->hw, wvif->scan.status ? 1 : 0);
+		up(&wvif->scan.lock);
+		return;
+	}
+	first = *wvif->scan.curr;
+
+	for (it = wvif->scan.curr + 1, i = 1;
+	     it != wvif->scan.end && i < HIF_API_MAX_NB_CHANNELS;
+	     ++it, ++i) {
+		if ((*it)->band != first->band)
+			break;
+		if (((*it)->flags ^ first->flags) &
+				IEEE80211_CHAN_NO_IR)
+			break;
+		if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
+		    (*it)->max_power != first->max_power)
+			break;
+	}
+	scan.scan_req.band = first->band;
+
+	if (wvif->scan.req->no_cck)
+		scan.scan_req.max_transmit_rate = API_RATE_INDEX_G_6MBPS;
+	else
+		scan.scan_req.max_transmit_rate = API_RATE_INDEX_B_1MBPS;
+	scan.scan_req.num_of_probe_requests =
+		(first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2;
+	scan.scan_req.num_of_ssi_ds = wvif->scan.n_ssids;
+	scan.ssids = &wvif->scan.ssids[0];
+	scan.scan_req.num_of_channels = it - wvif->scan.curr;
+	scan.scan_req.probe_delay = 100;
+
+	scan.ch = kcalloc(scan.scan_req.num_of_channels, sizeof(u8), GFP_KERNEL);
+
+	if (!scan.ch) {
+		wvif->scan.status = -ENOMEM;
+		goto fail;
+	}
+	for (i = 0; i < scan.scan_req.num_of_channels; ++i)
+		scan.ch[i] = wvif->scan.curr[i]->hw_value;
+
+	if (wvif->scan.curr[0]->flags & IEEE80211_CHAN_NO_IR) {
+		scan.scan_req.min_channel_time = 50;
+		scan.scan_req.max_channel_time = 150;
+	} else {
+		scan.scan_req.min_channel_time = 10;
+		scan.scan_req.max_channel_time = 50;
+	}
+	if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
+	    wvif->scan.output_power != first->max_power) {
+		wvif->scan.output_power = first->max_power;
+		hif_set_output_power(wvif, wvif->scan.output_power * 10);
+	}
+	wvif->scan.status = wfx_scan_start(wvif, &scan);
+	kfree(scan.ch);
+	if (wvif->scan.status)
+		goto fail;
+	wvif->scan.curr = it;
+	mutex_unlock(&wvif->wdev->conf_mutex);
+	return;
+
+fail:
+	wvif->scan.curr = wvif->scan.end;
+	mutex_unlock(&wvif->wdev->conf_mutex);
+	up(&wvif->scan.lock);
+	schedule_work(&wvif->scan.work);
+}
+
+static void wfx_scan_complete(struct wfx_vif *wvif)
+{
+	up(&wvif->scan.lock);
+	atomic_set(&wvif->wdev->scan_in_progress, 0);
+
+	wfx_scan_work(&wvif->scan.work);
+}
+
+void wfx_scan_failed_cb(struct wfx_vif *wvif)
+{
+	if (cancel_delayed_work_sync(&wvif->scan.timeout) > 0) {
+		wvif->scan.status = -EIO;
+		schedule_work(&wvif->scan.timeout.work);
+	}
+}
+
+void wfx_scan_complete_cb(struct wfx_vif *wvif, struct hif_ind_scan_cmpl *arg)
+{
+	if (cancel_delayed_work_sync(&wvif->scan.timeout) > 0) {
+		wvif->scan.status = 1;
+		schedule_work(&wvif->scan.timeout.work);
+	}
+}
+
+void wfx_scan_timeout(struct work_struct *work)
+{
+	struct wfx_vif *wvif = container_of(work, struct wfx_vif, scan.timeout.work);
+
+	if (atomic_xchg(&wvif->scan.in_progress, 0)) {
+		if (wvif->scan.status > 0) {
+			wvif->scan.status = 0;
+		} else if (!wvif->scan.status) {
+			dev_warn(wvif->wdev->dev, "timeout waiting for scan complete notification\n");
+			wvif->scan.status = -ETIMEDOUT;
+			wvif->scan.curr = wvif->scan.end;
+			hif_stop_scan(wvif);
+		}
+		wfx_scan_complete(wvif);
+	}
+}
diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h
new file mode 100644
index 000000000000..b4ddd0771a9b
--- /dev/null
+++ b/drivers/staging/wfx/scan.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Scan related functions.
+ *
+ * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+#ifndef WFX_SCAN_H
+#define WFX_SCAN_H
+
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <net/mac80211.h>
+
+#include "hif_api_cmd.h"
+
+struct wfx_dev;
+struct wfx_vif;
+
+struct wfx_scan {
+	struct semaphore lock;
+	struct work_struct work;
+	struct delayed_work timeout;
+	struct cfg80211_scan_request *req;
+	struct ieee80211_channel **begin;
+	struct ieee80211_channel **curr;
+	struct ieee80211_channel **end;
+	struct hif_ssid_def ssids[HIF_API_MAX_NB_SSIDS];
+	int output_power;
+	int n_ssids;
+	int status;
+	atomic_t in_progress;
+};
+
+int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+		struct ieee80211_scan_request *req);
+void wfx_scan_work(struct work_struct *work);
+void wfx_scan_timeout(struct work_struct *work);
+void wfx_scan_complete_cb(struct wfx_vif *wvif, struct hif_ind_scan_cmpl *arg);
+void wfx_scan_failed_cb(struct wfx_vif *wvif);
+
+#endif /* WFX_SCAN_H */
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 5714aba1432c..5a8140100e97 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -9,9 +9,18 @@
 
 #include "sta.h"
 #include "wfx.h"
+#include "scan.h"
+#include "hif_tx_mib.h"
 
 #define TXOP_UNIT 32
 
+int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable)
+{
+	wvif->fwd_probe_req = enable;
+	return hif_set_rx_filter(wvif, wvif->filter_bssid,
+				 wvif->fwd_probe_req);
+}
+
 static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
 {
 	struct sk_buff *skb;
@@ -128,6 +137,8 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 		default_edca_params[IEEE80211_AC_BK].queue_id = HIF_QUEUE_ID_BESTEFFORT;
 	}
 
+	mutex_lock(&wdev->conf_mutex);
+
 	for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
 		if (!wdev->vif[i]) {
 			wdev->vif[i] = vif;
@@ -135,8 +146,10 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 			break;
 		}
 	}
-	if (i == ARRAY_SIZE(wdev->vif))
+	if (i == ARRAY_SIZE(wdev->vif)) {
+		mutex_unlock(&wdev->conf_mutex);
 		return -EOPNOTSUPP;
+	}
 	wvif->vif = vif;
 	wvif->wdev = wdev;
 
@@ -148,6 +161,12 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	INIT_WORK(&wvif->mcast_start_work, wfx_mcast_start_work);
 	INIT_WORK(&wvif->mcast_stop_work, wfx_mcast_stop_work);
 	timer_setup(&wvif->mcast_timeout, wfx_mcast_timeout, 0);
+
+	sema_init(&wvif->scan.lock, 1);
+	INIT_WORK(&wvif->scan.work, wfx_scan_work);
+	INIT_DELAYED_WORK(&wvif->scan.timeout, wfx_scan_timeout);
+
+	mutex_unlock(&wdev->conf_mutex);
 	BUG_ON(ARRAY_SIZE(default_edca_params) != ARRAY_SIZE(wvif->edca.params));
 	for (i = 0; i < IEEE80211_NUM_ACS; i++)
 		memcpy(&wvif->edca.params[i], &default_edca_params[i], sizeof(default_edca_params[i]));
@@ -175,7 +194,9 @@ void wfx_stop(struct ieee80211_hw *hw)
 	struct wfx_dev *wdev = hw->priv;
 
 	wfx_tx_lock_flush(wdev);
+	mutex_lock(&wdev->conf_mutex);
 	wfx_tx_queues_clear(wdev);
+	mutex_unlock(&wdev->conf_mutex);
 	wfx_tx_unlock(wdev);
 	WARN(atomic_read(&wdev->tx_lock), "tx_lock is locked");
 }
diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h
index f36d94f907c7..dd1b6b3fc2f1 100644
--- a/drivers/staging/wfx/sta.h
+++ b/drivers/staging/wfx/sta.h
@@ -12,6 +12,8 @@
 
 #include "hif_api_cmd.h"
 
+struct wfx_vif;
+
 struct wfx_edca_params {
 	/* NOTE: index is a linux queue id. */
 	struct hif_req_edca_queue_params params[IEEE80211_NUM_ACS];
@@ -29,4 +31,6 @@ void wfx_stop(struct ieee80211_hw *hw);
 int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
 void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
 
+int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable);
+
 #endif /* WFX_STA_H */
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 11775b1e06ef..50c0d9c0e528 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -19,6 +19,7 @@
 #include "queue.h"
 #include "secure_link.h"
 #include "sta.h"
+#include "scan.h"
 #include "hif_tx.h"
 #include "hif_api_general.h"
 
@@ -39,6 +40,7 @@ struct wfx_dev {
 	struct wfx_hif		hif;
 	struct sl_context	sl;
 	int			chip_frozen;
+	struct mutex		conf_mutex;
 
 	struct wfx_hif_cmd	hif_cmd;
 	struct wfx_queue	tx_queue[4];
@@ -48,6 +50,9 @@ struct wfx_dev {
 
 	struct hif_rx_stats	rx_stats;
 	struct mutex		rx_stats_lock;
+
+	int			output_power;
+	atomic_t		scan_in_progress;
 };
 
 struct wfx_vif {
@@ -71,11 +76,17 @@ struct wfx_vif {
 
 	struct tx_policy_cache	tx_policy_cache;
 	struct work_struct	tx_policy_upload_work;
+
 	u32			sta_asleep_mask;
 	u32			pspoll_mask;
 	spinlock_t		ps_state_lock;
 
+	bool			filter_bssid;
+	bool			fwd_probe_req;
+
 	struct wfx_edca_params	edca;
+
+	struct wfx_scan		scan;
 };
 
 static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id)
-- 
2.20.1

^ 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