RE: [PATCH v2] net: stmmac: bug fix to synchronize stmmac_open and stmmac_dvr_probe

2016-12-27 Thread Kweh, Hock Leong
> -Original Message-
> From: David Miller [mailto:da...@davemloft.net]
> Sent: Wednesday, December 28, 2016 12:34 AM
> To: Kweh, Hock Leong 
> Cc: joao.pi...@synopsys.com; peppe.cavall...@st.com;
> seraphin.bonna...@st.com; f.faine...@gmail.com;
> alexandre.tor...@gmail.com; manab...@gmail.com; niklas.cas...@axis.com;
> jo...@kernel.org; pa...@ucw.cz; Ong, Boon Leong
> ; Voon, Weifeng ;
> lars.pers...@axis.com; netdev@vger.kernel.org; linux-ker...@vger.kernel.org
> Subject: Re: [PATCH v2] net: stmmac: bug fix to synchronize stmmac_open and
> stmmac_dvr_probe
> 
> From: "Kweh, Hock Leong"  
> Date: Tue, 27 Dec 2016 22:42:36 +0800
> 
> > From: "Kweh, Hock Leong" 
> 
> You are not the author of this change, do not take credit for it.
> 
> You have copied Florian's patch character by character, therefore
> he is the author.
> 
> You also didn't CC: the netdev mailing list properly.

Hi David & Florian,

Just to clarify that I do not copy exactly from Florian.
I have changed it to have proper handling on mdio unregister
while netdev_register() failed as showed below:

return 0;
 
-error_mdio_register:
-   unregister_netdev(ndev);
 error_netdev_register:
+   stmmac_mdio_unregister(ndev);
+error_mdio_register:
netif_napi_del(>napi);

Vs 

+
+   return ret;

 error_mdio_register:
-   unregister_netdev(ndev);
-error_netdev_register:
netif_napi_del(>napi);

Just to point it out here, so that Florian could aware if he/she submit
this fix to the mailing list.


Thanks & Regards,
Wilson  



Re: George's crazy full state idea (Re: HalfSipHash Acceptable Usage)

2016-12-27 Thread Hannes Frederic Sowa
Hello,

On Fri, 2016-12-23 at 20:17 -0500, George Spelvin wrote:
> Hannes Frederic Sowa wrote:
> > On 24.12.2016 00:39, George Spelvin wrote:
> > > We just finished discussing why 8 bytes isn't enough.  If you only
> > > feed back 8 bytes, an attacker who can do 2^64 computation can find it
> > > (by guessing and computing forward to verify the guess) and recover the
> > > previous state.  You need to feed back at least as much output as your
> > > security targete.  For /dev/urandom's ChaCha20, that's 256 bits.
> > I followed the discussion but it appeared to me that this has the
> > additional constraint of time until the next reseeding event happenes,
> > which is 300s (under the assumption that calls to get_random_int happen
> > regularly, which I expect right now). After that the existing reseeding
> > mechansim will ensure enough backtracking protection. The number of
> > bytes can easily be increased here, given that reseeding was shown to be
> > quite fast already and we produce enough output. But I am not sure if
> > this is a bit overengineered in the end?
> 
> I'm not following your description of how the time-based and call-based
> mechanisms interact, but for any mix-back, you should either do enough
> or none at all.  (Also called "catastrophic reseeding".)

We call extract_crng when we run out of batched entropy and reseed. How
often we call down to extract_crng depends on how much entropy we
extracted by calls to get_random_int/long, so the number of calls into
those functions matter.

In extract_crng we have a timer which reseeds every 300s the CPRNG and
either uses completely new entropy from the CRNG or calls down into the
CPRNG while also doing backtracing protection (which feeds chacha's
block size / 2 back into chacha, if I read the code correctly, thus
1024 bits, which should be enough).

> For example, two mix-backs of 64 bits gives you 65 bit security, not 128.
> (Because each mixback can be guessed and verified separately.)

Exactly, but the full reseed after running out of entropy is strong
enough to not be defeated by your argumentation. Neither the reseed
from the CRNG.

> > Also agreed. Given your solution below to prandom_u32, I do think it
> > might also work without the seqlock now.
> 
> It's not technically a seqlock; in particular the reader doesn't
> spin.  But the write side, and general logic is so similar it's
> a good mental model.
> 
> Basically, assume a 64-byte buffer.  The reader has gone through
> 32 bytes of it, and has 32 left, and when he reads another 8 bytes,
> has to distinguish three cases:
> 
> 1) No update; we read the old bytes and there are now 32 - 24 bytes left.
> 2) Update completed while we weren't looking.  There are now new
>bytes in the buffer, and we took 8 leaving 64 - 8 = 56.
> 3) Update in progress at the time of the read.  We don't know if we
>are seeing old bytes or new bytes, so we have to assume the worst
>and not proceeed unless 32 >= 8, but assume at the end there are
>64 - 8 = 56 new bytes left.
> 
> > I wouldn't have added a disable irqs, but given that I really like your
> > proposal, I would take it in my todo branch and submit it when net-next
> > window opens.
> 
> If you want that, I have a pile of patches to prandom I really
> should push upstream.  Shall I refresh them and send them to you?

I would like to have a look at them in the new year, certainly! I can
also take care about the core prandom patches, but don't know if I have
time to submit the others to the different subsystems.

Maybe, if David would be okay with that, we can submit all patches
through his tree, as he is also the dedicated maintainer for prandom.

> [... patch descriptions ...]

Thanks,
Hannes



Re: [PATCH 01/12] Make and configuration files.

2016-12-27 Thread David VomLehn

On 12/27/2016 08:47 PM, Rami Rosen wrote:

Hi, David,

For the Makefile, you should follow the pattern which is common in
Linux Kernel Ethernet drivers, for example,
http://lxr.free-electrons.com/source/drivers/net/ethernet/intel/i40e/Makefile or
http://lxr.free-electrons.com/source/drivers/net/ethernet/mellanox/mlx5/core/Makefile


Don't think that I ever saw usage of "-j" in a kernel module Makefile;
apart from it, "-j4" is specific to one platform with a given number
of cores, and of course there can be platforms with many more cores,
for which it is less suitable. You can pass the "-j" when running
"make" from the command line, there is no justification to put it in a
Makefile:


+all:
+   $(MAKE) -j4 CC=$(CC) -C $(BUILD_DIR) M=$(PWD) modules
+
+dox:   .doxygen
+   @doxygen $<
+
+clean:
+   $(MAKE) -j4 -C $(BUILD_DIR) M=$(PWD) clean

Don't think I ever encountered load/unload targets in Linux Kernel
Makefiles (not talking about out of tree  projects):


+load:
+   insmod ./$(TARGET).ko
+
+unload:
+   rmmod ./$(TARGET).ko


Regards,
Rami Rosen
You are right. The driver spent a while as an out-of-tree build module, 
where this made sense. It clearly no longer makes sense.



--
David VL



Re: [PATCH 05/12] Support for NIC-specific code

2016-12-27 Thread Rami Rosen
Hi, David,

Several nitpicks and comments, from a brief overview:

The commented label //err_exit:  should be removed
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> @@ -0,0 +1,993 @@
> +//err_exit:
> +//err_exit:

Shouldn't aq_nic_rss_init() be static? isn't it called only from
aq_nic_cfg_init_defaults()?
and it always returns 0, shouldn't it be void as well ? (+ remove
checking the return code when invoking it in
aq_nic_cfg_init_defaults())

> +int aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
> +{
> +   struct aq_nic_cfg_s *cfg = >aq_nic_cfg;
> +   struct aq_receive_scale_parameters *rss_params = >aq_rss;
> +   int i = 0;
> +
...
> +   return 0;
> +}


Shouldn't aq_nic_ndev_alloc() be static ? Isn't it invoked only from
aq_nic_alloc_cold()?

> +struct net_device *aq_nic_ndev_alloc(void)
> +{
...
> +}



> +
> +static unsigned int aq_nic_map_skb_lso(struct aq_nic_s *self,
> +  struct sk_buff *skb,
> +  struct aq_ring_buff_s *dx)
> +{
> +   unsigned int ret = 0U;
> +
> +   dx->flags = 0U;
> +   dx->len_pkt = skb->len;
> +   dx->len_l2 = ETH_HLEN;
> +   dx->len_l3 = ip_hdrlen(skb);
> +   dx->len_l4 = tcp_hdrlen(skb);
> +   dx->mss = skb_shinfo(skb)->gso_size;
> +   dx->is_txc = 1U;
> +   ret = 1U;
> +
Why not remove this "ret" variable, and simply return 1 ? the method
always returns 1:

> +   return ret;
> +}
> +

> +int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
> +{
> +   struct aq_ring_s *ring = NULL;
> +   unsigned int frags = 0U;
> +   unsigned int vec = skb->queue_mapping % self->aq_nic_cfg.vecs;
> +   unsigned int tc = 0U;
> +   int err = 0;
> +   bool is_nic_in_bad_state;
> +   bool is_locked = false;
> +   bool is_busy = false;
> +   struct aq_ring_buff_s buffers[AQ_CFG_SKB_FRAGS_MAX];
> +
> +   frags = skb_shinfo(skb)->nr_frags + 1;
> +
> +   ring = self->aq_ring_tx[AQ_NIC_TCVEC2RING(self, tc, vec)];
> +
> +   atomic_inc(>busy_count);
> +   is_busy = true;
> +
> +   if (frags > AQ_CFG_SKB_FRAGS_MAX) {
> +   dev_kfree_skb_any(skb);
> +   goto err_exit;
> +   }
> +
> +   is_nic_in_bad_state = AQ_OBJ_TST(self, AQ_NIC_FLAGS_IS_NOT_TX_READY) 
> ||
> +   (aq_ring_avail_dx(ring) < 
> AQ_CFG_SKB_FRAGS_MAX);
> +
> +   if (is_nic_in_bad_state) {
> +   aq_nic_ndev_queue_stop(self, ring->idx);
> +   err = NETDEV_TX_BUSY;
> +   goto err_exit;
> +   }
> +

Usage of this internal block is not common (unless it is under #ifdef,
and also not very common also in that case). I suggest move "unsigned
int trys" to the variables definitions in the beginning of the method
and remove the opening and closing brackets of the following block:
> +   {
> +   unsigned int trys = AQ_CFG_LOCK_TRYS;
> +
> +   frags = aq_nic_map_skb(self, skb, [0]);
> +
> +   do {
> +   is_locked = spin_trylock(>lock);
> +   } while (--trys && !is_locked);
> +   if (!(is_locked)) {
> +   err = NETDEV_TX_BUSY;
> +   goto err_exit;
> +   }
> +

Usually you don't let the mtu be less than 68, for example:
http://lxr.free-electrons.com/source/drivers/net/ethernet/intel/i40e/i40e_main.c#L2246
See also RFV 791:
https://tools.ietf.org/html/rfc791


> +int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu)
> +{
> +   int err = 0;
> +
> +   if (new_mtu > self->aq_hw_caps.mtu) {
> +   err = 0;
> +   goto err_exit;
> +   }
> +   self->aq_nic_cfg.mtu = new_mtu;
> +
> +err_exit:
> +   return err;
> +}

> +

> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h 
> b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
> new file mode 100644
> index 000..89958e7
> --- /dev/null
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
> @@ -0,0 +1,111 @@
> +/*
> + * Aquantia Corporation Network Driver
> + * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + */
> +
> +/*

Should be, of course, aq_nic.h:

> + * File aq_nic.c: Declaration of common code for NIC.
> + */
> +

Regards,
Rami Rosen


Re: [PATCH 01/12] Make and configuration files.

2016-12-27 Thread Rami Rosen
Hi, David,

For the Makefile, you should follow the pattern which is common in
Linux Kernel Ethernet drivers, for example,
http://lxr.free-electrons.com/source/drivers/net/ethernet/intel/i40e/Makefile or
http://lxr.free-electrons.com/source/drivers/net/ethernet/mellanox/mlx5/core/Makefile


Don't think that I ever saw usage of "-j" in a kernel module Makefile;
apart from it, "-j4" is specific to one platform with a given number
of cores, and of course there can be platforms with many more cores,
for which it is less suitable. You can pass the "-j" when running
"make" from the command line, there is no justification to put it in a
Makefile:

>+all:
>+   $(MAKE) -j4 CC=$(CC) -C $(BUILD_DIR) M=$(PWD) modules
>+
>+dox:   .doxygen
>+   @doxygen $<
>+
>+clean:
>+   $(MAKE) -j4 -C $(BUILD_DIR) M=$(PWD) clean

Don't think I ever encountered load/unload targets in Linux Kernel
Makefiles (not talking about out of tree  projects):

>+load:
>+   insmod ./$(TARGET).ko
>+
>+unload:
>+   rmmod ./$(TARGET).ko


Regards,
Rami Rosen


net-next is OPEN

2016-12-27 Thread David Miller

I know you are all chomping at the bit to bomb me with net-next
changes. :-)


Re: [PATCH] net: handle no dst on skb in icmp6_send

2016-12-27 Thread David Miller
From: Hannes Frederic Sowa 
Date: Thu, 08 Dec 2016 15:04:17 +0100

> Hello David,
> 
> On Mon, Nov 28, 2016, at 22:13, David Miller wrote:
>> From: David Ahern 
>> Date: Sun, 27 Nov 2016 18:52:53 -0800
>> 
>> > Andrey reported the following while fuzzing the kernel with syzkaller:
>>  ...
>> > icmp6_send / icmpv6_send is invoked for both rx and tx paths. In both
>> > cases the dst->dev should be preferred for determining the L3 domain
>> > if the dst has been set on the skb. Fallback to the skb->dev if it has
>> > not. This covers the case reported here where icmp6_send is invoked on
>> > Rx before the route lookup.
>> > 
>> > Fixes: 5d41ce29e ("net: icmp6_send should use dst dev to determine L3 
>> > domain")
>> > Reported-by: Andrey Konovalov 
>> > Signed-off-by: David Ahern 
>> 
>> Applied, thanks David.
> 
> could you queue this patch up for stable. You can remotely kill machines
> with this bug.

Sure, queued up, thanks.


Re: [PATCH net] net: stmmac: Fix race between stmmac_drv_probe and stmmac_open

2016-12-27 Thread David Miller
From: Florian Fainelli 
Date: Tue, 27 Dec 2016 18:23:06 -0800

> There is currently a small window during which the network device registered 
> by
> stmmac can be made visible, yet all resources, including and clock and MDIO 
> bus
> have not had a chance to be set up, this can lead to the following error to
> occur:
 ...
> Fix this by making sure that register_netdev() is the last thing being done,
> which guarantees that the clock and the MDIO bus are available.
> 
> Fixes: 4bfcbd7abce2 ("stmmac: Move the mdio_register/_unregister in 
> probe/remove")
> Reported-by: Kweh, Hock Leong 
> Signed-off-by: Florian Fainelli 

Applied and queued up for -stable, thanks Florian.


[PATCH net] net: stmmac: Fix race between stmmac_drv_probe and stmmac_open

2016-12-27 Thread Florian Fainelli
There is currently a small window during which the network device registered by
stmmac can be made visible, yet all resources, including and clock and MDIO bus
have not had a chance to be set up, this can lead to the following error to
occur:

[  473.919358] stmmaceth :01:00.0 (unnamed net_device) (uninitialized):
stmmac_dvr_probe: warning: cannot get CSR clock
[  473.919382] stmmaceth :01:00.0: no reset control found
[  473.919412] stmmac - user ID: 0x10, Synopsys ID: 0x42
[  473.919429] stmmaceth :01:00.0: DMA HW capability register supported
[  473.919436] stmmaceth :01:00.0: RX Checksum Offload Engine supported
[  473.919443] stmmaceth :01:00.0: TX Checksum insertion supported
[  473.919451] stmmaceth :01:00.0 (unnamed net_device) (uninitialized):
Enable RX Mitigation via HW Watchdog Timer
[  473.921395] libphy: PHY stmmac-1:00 not found
[  473.921417] stmmaceth :01:00.0 eth0: Could not attach to PHY
[  473.921427] stmmaceth :01:00.0 eth0: stmmac_open: Cannot attach to
PHY (error: -19)
[  473.959710] libphy: stmmac: probed
[  473.959724] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 0 IRQ POLL
(stmmac-1:00) active
[  473.959728] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 1 IRQ POLL
(stmmac-1:01)
[  473.959731] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 2 IRQ POLL
(stmmac-1:02)
[  473.959734] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 3 IRQ POLL
(stmmac-1:03)

Fix this by making sure that register_netdev() is the last thing being done,
which guarantees that the clock and the MDIO bus are available.

Fixes: 4bfcbd7abce2 ("stmmac: Move the mdio_register/_unregister in 
probe/remove")
Reported-by: Kweh, Hock Leong 
Signed-off-by: Florian Fainelli 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index bb40382e205d..5910ea51f8f6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3339,13 +3339,6 @@ int stmmac_dvr_probe(struct device *device,
 
spin_lock_init(>lock);
 
-   ret = register_netdev(ndev);
-   if (ret) {
-   netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
-  __func__, ret);
-   goto error_netdev_register;
-   }
-
/* If a specific clk_csr value is passed from the platform
 * this means that the CSR Clock Range selection cannot be
 * changed at run-time and it is fixed. Viceversa the driver'll try to
@@ -3372,11 +3365,14 @@ int stmmac_dvr_probe(struct device *device,
}
}
 
-   return 0;
+   ret = register_netdev(ndev);
+   if (ret)
+   netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
+  __func__, ret);
+
+   return ret;
 
 error_mdio_register:
-   unregister_netdev(ndev);
-error_netdev_register:
netif_napi_del(>napi);
 error_hw_init:
clk_disable_unprepare(priv->pclk);
-- 
2.9.3



RE: [PATCH v2] net: stmmac: bug fix to synchronize stmmac_open and stmmac_dvr_probe

2016-12-27 Thread Kweh, Hock Leong
> -Original Message-
> From: David Miller [mailto:da...@davemloft.net]
> Sent: Wednesday, December 28, 2016 12:34 AM
> To: Kweh, Hock Leong 
> Cc: joao.pi...@synopsys.com; peppe.cavall...@st.com;
> seraphin.bonna...@st.com; f.faine...@gmail.com;
> alexandre.tor...@gmail.com; manab...@gmail.com; niklas.cas...@axis.com;
> jo...@kernel.org; pa...@ucw.cz; Ong, Boon Leong
> ; Voon, Weifeng ;
> lars.pers...@axis.com; netdev@vger.kernel.org; linux-ker...@vger.kernel.org
> Subject: Re: [PATCH v2] net: stmmac: bug fix to synchronize stmmac_open and
> stmmac_dvr_probe
> 
> From: "Kweh, Hock Leong"  
> Date: Tue, 27 Dec 2016 22:42:36 +0800
> 
> > From: "Kweh, Hock Leong" 
> 
> You are not the author of this change, do not take credit for it.
> 
> You have copied Florian's patch character by character, therefore
> he is the author.
> 
> You also didn't CC: the netdev mailing list properly.

Noted & Thanks.

Hi Florian, could you submit this fix from your side so that you are the author.
I will help to test out.

Thanks & Regards,
Wilson



sunrpc: Illegal context switch in RCU read-side critical section!

2016-12-27 Thread Dave Jones
Just noticed this on 4.9. Will try and repro on 4.10rc1 later, but hitting
unrelated boot problems on that machine right now.

===
[ INFO: suspicious RCU usage. ]
4.9.0-backup-debug+ #1 Not tainted
---
./include/linux/rcupdate.h:557 Illegal context switch in RCU read-side critical 
section!

other info that might help us debug this:

rcu_scheduler_active = 1, debug_locks = 1
5 locks held by kworker/4:1/66:
 #0:  ("%s"("ipv6_addrconf")){.+.+..}, at: [] 
process_one_work+0x184/0x790
 #1:  ((addr_chk_work).work){+.+...}, at: [] 
process_one_work+0x184/0x790
 #2:  (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x17/0x20
 #3:  (rcu_read_lock_bh){..}, at: [] 
addrconf_verify_rtnl+0x23/0x500
 #4:  (rcu_read_lock){..}, at: [] 
atomic_notifier_call_chain+0x5/0x110

stack backtrace:
CPU: 4 PID: 66 Comm: kworker/4:1 Not tainted 4.9.0-backup-debug+ #1
Workqueue: ipv6_addrconf addrconf_verify_work
 c9273a28 8e5b4ca5 88042ae19780 0001
 c9273a58 8e0d530e  8efcc659
 09a7 8804180b8580 c9273a80 8e0ad2b7
Call Trace:
 [] dump_stack+0x68/0x93
 [] lockdep_rcu_suspicious+0xce/0xf0
 [] ___might_sleep.part.103+0xa7/0x230
 [] __might_sleep+0x4b/0x90
 [] lock_sock_nested+0x32/0xb0
 [] sock_setsockopt+0x8b/0xa50
 [] ? __local_bh_enable_ip+0x65/0xb0
 [] kernel_setsockopt+0x49/0x50
 [] svc_tcp_kill_temp_xprt+0x4a/0x60
 [] svc_age_temp_xprts_now+0x12f/0x1b0
 [] nfsd_inet6addr_event+0x192/0x1f0
 [] ? nfsd_inet6addr_event+0x5/0x1f0
 [] notifier_call_chain+0x39/0xa0
 [] atomic_notifier_call_chain+0x6e/0x110
 [] ? atomic_notifier_call_chain+0x5/0x110
 [] inet6addr_notifier_call_chain+0x1b/0x20
 [] ipv6_del_addr+0x12c/0x200
 [] addrconf_verify_rtnl+0x417/0x500
 [] ? addrconf_verify_rtnl+0x23/0x500
 [] addrconf_verify_work+0x13/0x20
 [] process_one_work+0x20b/0x790
 [] ? process_one_work+0x184/0x790
 [] worker_thread+0x4e/0x490
 [] ? process_one_work+0x790/0x790
 [] ? process_one_work+0x790/0x790
 [] kthread+0xff/0x120
 [] ? kthread_worker_fn+0x140/0x140
 [] ret_from_fork+0x27/0x40



Re: [PATCH] fddi: skfp: Use more common logging styles

2016-12-27 Thread David Miller

Applied.


Re: [PATCH] skfp: hwmtm: Use proper logging macros, correct mismatches

2016-12-27 Thread David Miller
From: Joe Perches 
Date: Wed, 21 Dec 2016 16:41:52 -0800

> Logging macros should allow format and argument validation.
> The DB_TX, DB_RX, and DB_GEN macros did not.
> 
> Update the macros and uses and add no_printk validation to the
> previously compiled away #ifndef DEBUG variants.
> 
> Done with coccinelle and some typing.
> 
> Signed-off-by: Joe Perches 

Applied.


Re: [PATCH] net: Use kmemdup instead of kmalloc and memcpy

2016-12-27 Thread David Miller
From: Shyam Saini 
Date: Sat, 24 Dec 2016 00:44:58 +0530

> when some other buffer is immediately copied into allocated region.
> Replace calls to kmalloc followed by a memcpy with a direct
> call to kmemdup.
> 
> Signed-off-by: Shyam Saini 

Applied.


RE: [RFC PATCH] i40e: enable PCIe relax ordering for SPARC

2016-12-27 Thread maowenan


> -Original Message-
> From: tndave [mailto:tushar.n.d...@oracle.com]
> Sent: Wednesday, December 28, 2016 6:28 AM
> To: maowenan; jeffrey.t.kirs...@intel.com; intel-wired-...@lists.osuosl.org
> Cc: netdev@vger.kernel.org; weiyongjun (A); Dingtianhong
> Subject: Re: [RFC PATCH] i40e: enable PCIe relax ordering for SPARC
> 
> 
> 
> On 12/26/2016 03:39 AM, maowenan wrote:
> >
> >
> >> -Original Message-
> >> From: netdev-ow...@vger.kernel.org
> >> [mailto:netdev-ow...@vger.kernel.org]
> >> On Behalf Of Tushar Dave
> >> Sent: Tuesday, December 06, 2016 1:07 AM
> >> To: jeffrey.t.kirs...@intel.com; intel-wired-...@lists.osuosl.org
> >> Cc: netdev@vger.kernel.org
> >> Subject: [RFC PATCH] i40e: enable PCIe relax ordering for SPARC
> >>
> >> Unlike previous generation NIC (e.g. ixgbe) i40e doesn't seem to have
> >> standard CSR where PCIe relaxed ordering can be set. Without PCIe
> >> relax ordering enabled, i40e performance is significantly low on SPARC.
> >>
> > [Mao Wenan]Hi Tushar, you have referred to i40e doesn't seem to have
> > standard CSR to set PCIe relaxed ordering, this CSR like TX DCA Control
> Register in 82599, right?
> Yes.
> i40e datasheet mentions some CSR that can be used to enable/disable PCIe
> relaxed ordering in device; however I don't see the exact definition of those
> register in datasheet.
> (https://www.mail-archive.com/netdev@vger.kernel.org/msg117219.html).
> 
> > Is DMA_ATTR_WEAK_ORDERING the same as TX control register in
> 82599?
> No.
> DMA_ATTR_WEAK_ORDERING applies to the PCIe root complex of the system.
> 
> -Tushar

I understand that the PCIe Root Complex is the Host Bridge in the CPU that
connects the CPU and memory to the PCIe architecture. So this attribute 
DMA_ATTR_WEAK_ORDERING is only applied on CPU side(the SPARC in you 
system), it can't apply on i40e, is it right? 
And it is not the same as 82599 DCA control register's relax ordering bits.
-Mao Wenan

> >
> > And to enable relax ordering mode in 82599 for SPARC using below codes:
> > s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) {
> > u32 i;
> >
> > /* Clear the rate limiters */
> > for (i = 0; i < hw->mac.max_tx_queues; i++) {
> > IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
> > IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
> > }
> > IXGBE_WRITE_FLUSH(hw);
> >
> > #ifndef CONFIG_SPARC
> > /* Disable relaxed ordering */
> > for (i = 0; i < hw->mac.max_tx_queues; i++) {
> > u32 regval;
> >
> > regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
> > regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
> > IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
> > }
> >
> > for (i = 0; i < hw->mac.max_rx_queues; i++) {
> > u32 regval;
> >
> > regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
> > regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
> > IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
> > IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
> > }
> > #endif
> > return 0;
> > }
> >
> >
> >
> >> This patch sets PCIe relax ordering for SPARC arch by setting dma
> >> attr DMA_ATTR_WEAK_ORDERING for every tx and rx DMA map/unmap.
> >> This has shown 10x increase in performance numbers.
> >>
> >> e.g.
> >> iperf TCP test with 10 threads on SPARC S7
> >>
> >> Test 1: Without this patch
> >>
> >> [root@brm-snt1-03 net]# iperf -s
> >> 
> >> Server listening on TCP port 5001
> >> TCP window size: 85.3 KByte (default)
> >> 
> >> [  4] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40926 [
> >> 5] local
> >> 16.0.0.7 port 5001 connected with 16.0.0.1 port 40934 [  6] local
> >> 16.0.0.7 port
> >> 5001 connected with 16.0.0.1 port 40930 [  7] local 16.0.0.7 port
> >> 5001 connected with 16.0.0.1 port 40928 [  8] local 16.0.0.7 port
> >> 5001 connected with 16.0.0.1 port 40922 [  9] local 16.0.0.7 port
> >> 5001 connected with 16.0.0.1 port 40932 [ 10] local 16.0.0.7 port
> >> 5001 connected with 16.0.0.1 port 40920 [ 11] local 16.0.0.7 port
> >> 5001 connected with 16.0.0.1 port 40924 [ 14] local
> >> 16.0.0.7 port 5001 connected with 16.0.0.1 port 40982 [ 12] local
> >> 16.0.0.7 port
> >> 5001 connected with 16.0.0.1 port 40980
> >> [ ID] Interval   Transfer Bandwidth
> >> [  4]  0.0-20.0 sec   566 MBytes   237 Mbits/sec
> >> [  5]  0.0-20.0 sec   532 MBytes   223 Mbits/sec
> >> [  6]  0.0-20.0 sec   537 MBytes   225 Mbits/sec
> >> [  8]  0.0-20.0 sec   546 MBytes   229 Mbits/sec
> >> [ 11]  0.0-20.0 sec   592 MBytes   248 Mbits/sec
> >> [  7]  0.0-20.0 sec   539 MBytes   226 Mbits/sec
> >> [  9]  0.0-20.0 sec   572 MBytes   240 Mbits/sec
> >> [ 10]  0.0-20.0 sec   604 MBytes   253 Mbits/sec
> >> [ 14]  0.0-20.0 sec   567 MBytes   238 Mbits/sec
> >> [ 12]  0.0-20.0 sec   511 MBytes   214 Mbits/sec
> >> [SUM]  0.0-20.0 sec  5.44 

RE: [Intel-wired-lan] [RFC PATCH] i40e: enable PCIe relax ordering for SPARC

2016-12-27 Thread maowenan


> -Original Message-
> From: netdev-ow...@vger.kernel.org [mailto:netdev-ow...@vger.kernel.org]
> On Behalf Of Alexander Duyck
> Sent: Tuesday, December 06, 2016 5:55 AM
> To: Tushar Dave
> Cc: Jeff Kirsher; intel-wired-lan; Netdev
> Subject: Re: [Intel-wired-lan] [RFC PATCH] i40e: enable PCIe relax ordering 
> for
> SPARC
> 
> On Mon, Dec 5, 2016 at 9:07 AM, Tushar Dave 
> wrote:
> > Unlike previous generation NIC (e.g. ixgbe) i40e doesn't seem to have
> > standard CSR where PCIe relaxed ordering can be set. Without PCIe
> > relax ordering enabled, i40e performance is significantly low on SPARC.
> >
> > This patch sets PCIe relax ordering for SPARC arch by setting dma attr
> > DMA_ATTR_WEAK_ORDERING for every tx and rx DMA map/unmap.
> > This has shown 10x increase in performance numbers.
> >
> > e.g.
> > iperf TCP test with 10 threads on SPARC S7
> >
> > Test 1: Without this patch
> >
> > [root@brm-snt1-03 net]# iperf -s
> > 
> > Server listening on TCP port 5001
> > TCP window size: 85.3 KByte (default)
> > 
> > [  4] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40926 [
> > 5] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40934 [  6]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40930 [  7]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40928 [  8]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40922 [  9]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40932 [ 10]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40920 [ 11]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40924 [ 14]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40982 [ 12]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40980
> > [ ID] Interval   Transfer Bandwidth
> > [  4]  0.0-20.0 sec   566 MBytes   237 Mbits/sec
> > [  5]  0.0-20.0 sec   532 MBytes   223 Mbits/sec
> > [  6]  0.0-20.0 sec   537 MBytes   225 Mbits/sec
> > [  8]  0.0-20.0 sec   546 MBytes   229 Mbits/sec
> > [ 11]  0.0-20.0 sec   592 MBytes   248 Mbits/sec
> > [  7]  0.0-20.0 sec   539 MBytes   226 Mbits/sec
> > [  9]  0.0-20.0 sec   572 MBytes   240 Mbits/sec
> > [ 10]  0.0-20.0 sec   604 MBytes   253 Mbits/sec
> > [ 14]  0.0-20.0 sec   567 MBytes   238 Mbits/sec
> > [ 12]  0.0-20.0 sec   511 MBytes   214 Mbits/sec
> > [SUM]  0.0-20.0 sec  5.44 GBytes  2.33 Gbits/sec
> >
> > Test 2: with this patch:
> >
> > [root@brm-snt1-03 net]# iperf -s
> > 
> > Server listening on TCP port 5001
> > TCP window size: 85.3 KByte (default)
> > 
> > TCP: request_sock_TCP: Possible SYN flooding on port 5001. Sending
> > cookies.  Check SNMP counters.
> > [  4] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46876 [
> > 5] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46874 [  6]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46872 [  7]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46880 [  8]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46878 [  9]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46884 [ 10]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46886 [ 11]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46890 [ 12]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46888 [ 13]
> > local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46882
> > [ ID] Interval   Transfer Bandwidth
> > [  4]  0.0-20.0 sec  7.45 GBytes  3.19 Gbits/sec [  5]  0.0-20.0 sec
> > 7.48 GBytes  3.21 Gbits/sec [  7]  0.0-20.0 sec  7.34 GBytes  3.15
> > Gbits/sec [  8]  0.0-20.0 sec  7.42 GBytes  3.18 Gbits/sec [  9]
> > 0.0-20.0 sec  7.24 GBytes  3.11 Gbits/sec [ 10]  0.0-20.0 sec  7.40
> > GBytes  3.17 Gbits/sec [ 12]  0.0-20.0 sec  7.49 GBytes  3.21
> > Gbits/sec [  6]  0.0-20.0 sec  7.30 GBytes  3.13 Gbits/sec [ 11]
> > 0.0-20.0 sec  7.44 GBytes  3.19 Gbits/sec [ 13]  0.0-20.0 sec  7.22
> > GBytes  3.10 Gbits/sec [SUM]  0.0-20.0 sec  73.8 GBytes  31.6
> > Gbits/sec
> >
> > NOTE: In my testing, this patch does _not_ show any harm to i40e
> > performance numbers on x86.
> >
> > Signed-off-by: Tushar Dave 
> 
> You went through and replaced all of the dma_unmap/map_page calls with
> dma_map/unmap_single_attrs  I would prefer you didn't do that.  I have
> patches to add the ability to map and unmap pages with attributes that should
> be available for 4.10-rc1 so if you could wait on this patch until then it 
> would be
> preferred.
> 
[Mao Wenan] Have you already sent out the related patches? I want to refer to
you how to enable this ability, then we can adopt it to configure relax 
ordering 
through DCA control register on device 82599.
Thank you.

> > ---
> >  drivers/net/ethernet/intel/i40e/i40e_txrx.c 

Re: driver r8169 suddenly failed

2016-12-27 Thread Francois Romieu
Robert Grasso  :
[...]
> So, what is your opinion :
> - should I broaden my request for help to other teams than yours (kernel
> maintainers) ?

If I had to untangle this mess, I would check that my router is not
configured with an empty dhcp range. Then I would put each and every
interface facing it in promiscuous (tcpdump) capture mode until one
of those is able to negotiate a dhcp lease. I would thereafter replace
it with the r8169 interface and compare the traffic (+ ethtool byte/packet
counters).

-- 
Ueimor


Re: [RFC PATCH] i40e: enable PCIe relax ordering for SPARC

2016-12-27 Thread tndave



On 12/26/2016 03:39 AM, maowenan wrote:




-Original Message-
From: netdev-ow...@vger.kernel.org [mailto:netdev-ow...@vger.kernel.org]
On Behalf Of Tushar Dave
Sent: Tuesday, December 06, 2016 1:07 AM
To: jeffrey.t.kirs...@intel.com; intel-wired-...@lists.osuosl.org
Cc: netdev@vger.kernel.org
Subject: [RFC PATCH] i40e: enable PCIe relax ordering for SPARC

Unlike previous generation NIC (e.g. ixgbe) i40e doesn't seem to have standard
CSR where PCIe relaxed ordering can be set. Without PCIe relax ordering
enabled, i40e performance is significantly low on SPARC.


[Mao Wenan]Hi Tushar, you have referred to i40e doesn't seem to have standard 
CSR
to set PCIe relaxed ordering, this CSR like TX DCA Control Register in 
82599, right?

Yes.
i40e datasheet mentions some CSR that can be used to enable/disable PCIe
relaxed ordering in device; however I don't see the exact definition of
those register in datasheet.
(https://www.mail-archive.com/netdev@vger.kernel.org/msg117219.html).


Is DMA_ATTR_WEAK_ORDERING the same as TX control register in
82599?

No.
DMA_ATTR_WEAK_ORDERING applies to the PCIe root complex of the system.

-Tushar



And to enable relax ordering mode in 82599 for SPARC using below codes:
s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
{
u32 i;

/* Clear the rate limiters */
for (i = 0; i < hw->mac.max_tx_queues; i++) {
IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
}
IXGBE_WRITE_FLUSH(hw);

#ifndef CONFIG_SPARC
/* Disable relaxed ordering */
for (i = 0; i < hw->mac.max_tx_queues; i++) {
u32 regval;

regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
}

for (i = 0; i < hw->mac.max_rx_queues; i++) {
u32 regval;

regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
}
#endif
return 0;
}




This patch sets PCIe relax ordering for SPARC arch by setting dma attr
DMA_ATTR_WEAK_ORDERING for every tx and rx DMA map/unmap.
This has shown 10x increase in performance numbers.

e.g.
iperf TCP test with 10 threads on SPARC S7

Test 1: Without this patch

[root@brm-snt1-03 net]# iperf -s

Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)

[  4] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40926 [  5] local
16.0.0.7 port 5001 connected with 16.0.0.1 port 40934 [  6] local 16.0.0.7 port
5001 connected with 16.0.0.1 port 40930 [  7] local 16.0.0.7 port 5001
connected with 16.0.0.1 port 40928 [  8] local 16.0.0.7 port 5001 connected
with 16.0.0.1 port 40922 [  9] local 16.0.0.7 port 5001 connected with 16.0.0.1
port 40932 [ 10] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40920
[ 11] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40924 [ 14] local
16.0.0.7 port 5001 connected with 16.0.0.1 port 40982 [ 12] local 16.0.0.7 port
5001 connected with 16.0.0.1 port 40980
[ ID] Interval   Transfer Bandwidth
[  4]  0.0-20.0 sec   566 MBytes   237 Mbits/sec
[  5]  0.0-20.0 sec   532 MBytes   223 Mbits/sec
[  6]  0.0-20.0 sec   537 MBytes   225 Mbits/sec
[  8]  0.0-20.0 sec   546 MBytes   229 Mbits/sec
[ 11]  0.0-20.0 sec   592 MBytes   248 Mbits/sec
[  7]  0.0-20.0 sec   539 MBytes   226 Mbits/sec
[  9]  0.0-20.0 sec   572 MBytes   240 Mbits/sec
[ 10]  0.0-20.0 sec   604 MBytes   253 Mbits/sec
[ 14]  0.0-20.0 sec   567 MBytes   238 Mbits/sec
[ 12]  0.0-20.0 sec   511 MBytes   214 Mbits/sec
[SUM]  0.0-20.0 sec  5.44 GBytes  2.33 Gbits/sec

Test 2: with this patch:

[root@brm-snt1-03 net]# iperf -s

Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)

TCP: request_sock_TCP: Possible SYN flooding on port 5001. Sending cookies.
Check SNMP counters.
[  4] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46876 [  5] local
16.0.0.7 port 5001 connected with 16.0.0.1 port 46874 [  6] local 16.0.0.7 port
5001 connected with 16.0.0.1 port 46872 [  7] local 16.0.0.7 port 5001
connected with 16.0.0.1 port 46880 [  8] local 16.0.0.7 port 5001 connected
with 16.0.0.1 port 46878 [  9] local 16.0.0.7 port 5001 connected with 16.0.0.1
port 46884 [ 10] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46886
[ 11] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46890 [ 12] local
16.0.0.7 port 5001 connected with 16.0.0.1 port 46888 [ 13] local 16.0.0.7 port
5001 connected with 16.0.0.1 

Re: [PATCH] staging: octeon: Call SET_NETDEV_DEV()

2016-12-27 Thread Florian Fainelli
On 12/20/2016 07:20 PM, David Miller wrote:
> From: Florian Fainelli 
> Date: Tue, 20 Dec 2016 17:02:37 -0800
> 
>> On 12/14/2016 05:13 PM, Florian Fainelli wrote:
>>> The Octeon driver calls into PHYLIB which now checks for
>>> net_device->dev.parent, so make sure we do set it before calling into
>>> any MDIO/PHYLIB related function.
>>>
>>> Fixes: ec988ad78ed6 ("phy: Don't increment MDIO bus refcount unless it's a 
>>> different owner")
>>> Reported-by: Aaro Koskinen 
>>> Signed-off-by: Florian Fainelli 
>>
>> Greg, David, since this is a fix for a regression introduced in the net
>> tree, it may make sense that David take it via his tree.
> 
> Since the change in question is in Linus's tree, it's equally valid
> for Greg to take it as well.

Sure, Greg, can you take this change? Thank you!
-- 
Florian


Re: [PATCH v3 2/2] drivers: net: ethernet: 3com: fix return value

2016-12-27 Thread David Dillow
On Sun, 2016-12-25 at 01:30 +0100, Thomas Preisner wrote:
> In some cases the return value of a failing function is not being used
> and the function typhoon_init_one() returns another negative error
> code instead.

I'm not sure these changes are especially valuable, since we'll need to
look at the dmesg log anyways to figure out what went wrong, but again I
don't feel strongly.

Fix up the subject issues and I'm happy to ack them.



Re: Re: [PATCH v2 1/2] drivers: net: ethernet: 3com: fix return value

2016-12-27 Thread David Dillow
On Sun, 2016-12-25 at 01:30 +0100, Thomas Preisner wrote:
> Those spaces were actually left out purposely: The file in question 
> (typhoon.c)
> is missing those spaces between the statements (if, for, while) and the
> following opening bracket pretty much always (except 2-3 times) and we figured
> that it might be better to keep the coding style consistent since this might
> aswell have been intended by the original author.

I'm not sure if we had the rule back then, or if I just missed it.
Either way, we should follow the rules for new code if we can.

I'm not sure it's worth fixing all of the instances -- usually
formatting-only changes are not worth the churn -- but I don't have a
strong opinion on the matter.



[GIT] Networking

2016-12-27 Thread David Miller

1) Various ipvlan fixes from Eric Dumazet and Mahesh Bandewar.  The most
   important is to not assume the packet is RX just because the destination
   address matches that of the device.  Such an assumption causes problems
   when an interface is put into loopback mode.

2) If we retry when creating a new tc entry (because we dropped the
   RTNL mutex in order to load a module, for example) we end up with
   -EAGAIN and then loop trying to replay the request.  Problem is we
   didn't reset some state when looping back to the top like this, and
   if another thread meanwhile inserted the same tc entry we were
   trying to, we re-link it creating an enless loop in the tc chain.
   Fix from Daniel Borkmann.

3) There are two different WRITE bits in the MDIO address register for
   the stmmac chip, depending upon the chip variant.  Due to a bug we
   could set them both, fix from Hock Leong Kweh.

4) Fix mlx4 bug in XDP_TX handling, from Tariq Toukan.

Please pull, thanks a lot!

The following changes since commit 50b17cfb1917b207612327d354e9043dbcbde431:

  Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (2016-12-23 
11:23:25 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git 

for you to fetch changes up to 5799fc905930f866c7d32aaf81b31f8027297506:

  net: stmmac: fix incorrect bit set in gmac4 mdio addr register (2016-12-27 
12:28:08 -0500)


Chun-Hao Lin (1):
  r8169: add support for RTL8168 series add-on card.

Daniel Borkmann (1):
  net, sched: fix soft lockup in tc_classify

Eric Dumazet (1):
  ipvlan: fix various issues in ipvlan_process_multicast()

Florian Fainelli (1):
  net: korina: Fix NAPI versus resources freeing

Haishuang Yan (1):
  ipv4: Namespaceify tcp_tw_reuse knob

Jason Wang (1):
  net: xdp: remove unused bfp_warn_invalid_xdp_buffer()

Jon Paul Maloy (1):
  tipc: don't send FIN message from connectionless socket

Kweh, Hock Leong (1):
  net: stmmac: fix incorrect bit set in gmac4 mdio addr register

Mahesh Bandewar (1):
  ipvlan: fix multicast processing

Tariq Toukan (1):
  net/mlx4_en: Fix user prio field in XDP forward

pravin shelar (1):
  openvswitch: upcall: Fix vlan handling.

 drivers/net/ethernet/korina.c |  8 
 drivers/net/ethernet/mellanox/mlx4/en_netdev.c|  3 ++-
 drivers/net/ethernet/realtek/r8169.c  |  1 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |  4 +++-
 drivers/net/ipvlan/ipvlan.h   |  5 +
 drivers/net/ipvlan/ipvlan_core.c  | 60 
++--
 drivers/net/ipvlan/ipvlan_main.c  |  7 ++-
 include/linux/filter.h|  1 -
 include/net/netns/ipv4.h  |  1 +
 include/net/tcp.h |  1 -
 net/core/filter.c |  6 --
 net/ipv4/sysctl_net_ipv4.c| 14 +++---
 net/ipv4/tcp_ipv4.c   |  4 ++--
 net/openvswitch/datapath.c|  1 -
 net/openvswitch/flow.c| 54 
+++---
 net/sched/cls_api.c   |  4 +++-
 net/tipc/socket.c | 24 +---
 17 files changed, 112 insertions(+), 86 deletions(-)


Re: driver r8169 suddenly failed

2016-12-27 Thread Robert Grasso

Hello,

I have some unexpected (and interesting) news. I did not run the test 
yet. While I was investigating my issue, I ordered a fast 
Ethernet-to-USB3 converter, able to reach 1000Mbit/s, in order to 
recover my broadband quickly : here is the chip as reported by dmesg :


[8.114327] ax88179_178a 4-1:1.0 eth2: register 'ax88179_178a' at 
usb-:03:00.0-1, ASIX AX88179 USB 3.0 Gigabit Ethernet, 00:0e:c6:c2:ce:d1


from the chinese brand  UGreen : at first sight, you do not seem to be 
related to it. On their advertisement, they allege they are compatible 
with kernel 2.6 and higher (which I confirmed on various forums before 
ordering it). However, guess what : I have the EXACT SAME behaviour !
- connected from the Shuttle (with USB3) on my cable modem, it fails to 
acquire the IP address as well (same endless loop) !
- from my laptop with Ubuntu 16.04 now : - connected on the LAN (and 
thus, on the Shuttle which runs my local DHCP server across YOUR 
perfectly functioning interface and driver) it works perfectly
 - connected on the cable 
modem, it fails too !


So, what is your opinion :
- should I broaden my request for help to other teams than yours (kernel 
maintainers) ?

- are you still interested in this test you asked for ?

Best regards

--
Robert Grasso
@home
---
UNIX was not designed to stop you from doing stupid things, because
  that would also stop you from doing clever things. -- Doug Gwyn

On 27/12/2016 01:12, Francois Romieu wrote:

Robert Grasso  :
[dhcp snafu]

First of all, can you confirm that I am doing right in posting to you
(addresses found in README.Debian) ?

It isn't completely wrong.


If I do, can you help ? I am not very proficient with Ethernet, and I am not
able to figure out what my provider changed : their hotline is
underqualified, they are just able to tell that "the signal on the line is
ok".

You're spoiled. It is more than decent for a company whose core business
used to sell cable TV.


But if you want me to run various tests, try new versions, I would be
glad to do so : I would appreciate if I could salvage this Shuttle.

Please try a recent stable vanilla kernel and send a complete dmesg
from boot. I need to identify the specific 816x chipset.

Then record some traffic:

# touch gonzo.pcap && tshark -w gonzo.pcap -i eth1

It should only exhibit small outgoing packets but, well, one never knows.

Check the leds activity to be sure that the network interfaces have not
been renumbered.

Use ethtool to check that tso is disabled. If it isn't, disable it.





Re: [PATCH] net: fix incorrect original ingress device index in PKTINFO

2016-12-27 Thread David Miller
From: Wei Zhang 
Date: Tue, 27 Dec 2016 17:52:24 +0800

> When we send a packet for our own local address on a non-loopback
> interface (e.g. eth0), due to the change had been introduced from
> commit 0b922b7a829c ("net: original ingress device index in PKTINFO"), the
> original ingress device index would be set as the loopback interface.
> However, the packet should be considered as if it is being arrived via the
> sending interface (eth0), otherwise it would break the expectation of the
> userspace application (e.g. the DHCPRELEASE message from dhcp_release
> binary would be ignored by the dnsmasq daemon, since it come from lo which
> is not the interface dnsmasq bind to)
> 
> Signed-off-by: Wei Zhang 

When you are fixing a problem introduced by another change, always CC:
the author of that change as I have done so here.

David, please take a look at this, thanks.

> ---
>  net/ipv4/ip_sockglue.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
> index b8a2d63..76d78a7 100644
> --- a/net/ipv4/ip_sockglue.c
> +++ b/net/ipv4/ip_sockglue.c
> @@ -1202,8 +1202,14 @@ void ipv4_pktinfo_prepare(const struct sock *sk, 
> struct sk_buff *skb)
>* which has interface index (iif) as the first member of the
>* underlying inet{6}_skb_parm struct. This code then overlays
>* PKTINFO_SKB_CB and in_pktinfo also has iif as the first
> -  * element so the iif is picked up from the prior IPCB
> +  * element so the iif is picked up from the prior IPCB except
> +  * iif is loopback interface which the packet should be
> +  * considered as if it is being arrived via the sending
> +  * interface
>*/
> + if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX)
> + pktinfo->ipi_ifindex = inet_iif(skb);
> +
>   pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
>   } else {
>   pktinfo->ipi_ifindex = 0;
> -- 
> 1.8.3.1
> 
> 


Re: [RFC PATCH 4.10 1/6] crypto/sha256: Refactor the API so it can be used without shash

2016-12-27 Thread Andy Lutomirski
On Tue, Dec 27, 2016 at 6:16 AM, Daniel Borkmann  wrote:
> On 12/27/2016 10:58 AM, Herbert Xu wrote:
>>
>> On Mon, Dec 26, 2016 at 10:08:48AM -0800, Andy Lutomirski wrote:
>>>
>>>
>>> According to Daniel, the networking folks want to let embedded systems
>>> include BPF without requiring the crypto core.
>>
>>
>> Last I checked the IPv4 stack depended on the crypto API so this
>> sounds bogus.
>
>
> I think there's a bit of a mixup here with what I said. To clarify,
> requirement back then from tracing folks was that bpf engine and
> therefore bpf syscall can be build w/o networking enabled for small
> devices, so dependencies preferably need to be kept on a absolute
> minimum, same counts for either making it suddenly a depend on
> CRYPTO or a select CRYPTO for just those few lines that can be
> pulled in from lib/ code instead.

Somehow I had that in my head as "networking" not "tracing", probably
because of the TCA stuff.  Whoops.

Anyway, I'm rewriting the crypto part of the patch completely based on
Ard's feedback.


Re: [net/mm PATCH v2 0/3] Page fragment updates

2016-12-27 Thread David Miller
From: Alexander Duyck 
Date: Tue, 27 Dec 2016 10:54:14 -0800

> Dave, I was wondering if you would be okay with me trying to push the
> three patches though net-next.  I'm thinking I might scale back the
> first patch so that it is just a rename instead of making any
> functional changes.  The main reason why I am thinking of trying to
> submit through net-next is because then I can then start working on
> submitting the driver patches for net-next.  Otherwise I'm looking at
> this set creating a merge mess since I don't see a good way to push
> the driver changes without already having these changes present.
> 
> I'll wait until Andrew can weigh in on the patches before
> resubmitting.  My thought was to get an Acked-by from him and then see
> if I can get them accepted into net-next.  That way there isn't any
> funky cross-tree merging that will need to go on, and it shouldn't
> really impact the mm tree all that much as the only consumers for the
> page frag code are the network stack anyway.

I'm fine with this plan.


[PATCH 2/2] ath9k: ar9003_mac: kill off ACCESS_ONCE()

2016-12-27 Thread Mark Rutland
For several reasons, it is desirable to use {READ,WRITE}_ONCE() in
preference to ACCESS_ONCE(), and new code is expected to use one of the
former. So far, there's been no reason to change most existing uses of
ACCESS_ONCE(), as these aren't currently harmful.

However, for some new features (e.g. KTSAN / Kernel Thread Sanitizer),
it is necessary to instrument reads and writes separately, which is not
possible with ACCESS_ONCE(). This distinction is critical to correct
operation.

It's possible to transform the bulk of kernel code using the Coccinelle
script below. However, for some files (including the ath9k ar9003 mac
driver), this mangles the formatting. As a preparatory step, this patch
converts the driver to use {READ,WRITE}_ONCE() without said mangling.


virtual patch

@ depends on patch @
expression E1, E2;
@@

- ACCESS_ONCE(E1) = E2
+ WRITE_ONCE(E1, E2)

@ depends on patch @
expression E;
@@

- ACCESS_ONCE(E)
+ READ_ONCE(E)


Signed-off-by: Mark Rutland 
Cc: ath9k-de...@qca.qualcomm.com
Cc: Kalle Valo 
Cc: linux-wirel...@vger.kernel.org
Cc: ath9k-de...@lists.ath9k.org
Cc: netdev@vger.kernel.org
---
 drivers/net/wireless/ath/ath9k/ar9003_mac.c | 92 ++---
 1 file changed, 46 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c 
b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index da84b70..cc5bb0a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -39,47 +39,47 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct 
ath_tx_info *i)
  (i->qcu << AR_TxQcuNum_S) | desc_len;
 
checksum += val;
-   ACCESS_ONCE(ads->info) = val;
+   WRITE_ONCE(ads->info, val);
 
checksum += i->link;
-   ACCESS_ONCE(ads->link) = i->link;
+   WRITE_ONCE(ads->link, i->link);
 
checksum += i->buf_addr[0];
-   ACCESS_ONCE(ads->data0) = i->buf_addr[0];
+   WRITE_ONCE(ads->data0, i->buf_addr[0]);
checksum += i->buf_addr[1];
-   ACCESS_ONCE(ads->data1) = i->buf_addr[1];
+   WRITE_ONCE(ads->data1, i->buf_addr[1]);
checksum += i->buf_addr[2];
-   ACCESS_ONCE(ads->data2) = i->buf_addr[2];
+   WRITE_ONCE(ads->data2, i->buf_addr[2]);
checksum += i->buf_addr[3];
-   ACCESS_ONCE(ads->data3) = i->buf_addr[3];
+   WRITE_ONCE(ads->data3, i->buf_addr[3]);
 
checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
-   ACCESS_ONCE(ads->ctl3) = val;
+   WRITE_ONCE(ads->ctl3, val);
checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
-   ACCESS_ONCE(ads->ctl5) = val;
+   WRITE_ONCE(ads->ctl5, val);
checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
-   ACCESS_ONCE(ads->ctl7) = val;
+   WRITE_ONCE(ads->ctl7, val);
checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
-   ACCESS_ONCE(ads->ctl9) = val;
+   WRITE_ONCE(ads->ctl9, val);
 
checksum = (u16) (((checksum & 0x) + (checksum >> 16)) & 0x);
-   ACCESS_ONCE(ads->ctl10) = checksum;
+   WRITE_ONCE(ads->ctl10, checksum);
 
if (i->is_first || i->is_last) {
-   ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0)
+   WRITE_ONCE(ads->ctl13, set11nTries(i->rates, 0)
| set11nTries(i->rates, 1)
| set11nTries(i->rates, 2)
| set11nTries(i->rates, 3)
| (i->dur_update ? AR_DurUpdateEna : 0)
-   | SM(0, AR_BurstDur);
+   | SM(0, AR_BurstDur));
 
-   ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0)
+   WRITE_ONCE(ads->ctl14, set11nRate(i->rates, 0)
| set11nRate(i->rates, 1)
| set11nRate(i->rates, 2)
-   | set11nRate(i->rates, 3);
+   | set11nRate(i->rates, 3));
} else {
-   ACCESS_ONCE(ads->ctl13) = 0;
-   ACCESS_ONCE(ads->ctl14) = 0;
+   WRITE_ONCE(ads->ctl13, 0);
+   WRITE_ONCE(ads->ctl14, 0);
}
 
ads->ctl20 = 0;
@@ -89,17 +89,17 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct 
ath_tx_info *i)
 
ctl17 = SM(i->keytype, AR_EncrType);
if (!i->is_first) {
-   ACCESS_ONCE(ads->ctl11) = 0;
-   ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
-   ACCESS_ONCE(ads->ctl15) = 0;
-   ACCESS_ONCE(ads->ctl16) = 0;
-   ACCESS_ONCE(ads->ctl17) = ctl17;
-   ACCESS_ONCE(ads->ctl18) = 0;
-   ACCESS_ONCE(ads->ctl19) = 0;
+   WRITE_ONCE(ads->ctl11, 0);
+   WRITE_ONCE(ads->ctl12, i->is_last ? 0 : AR_TxMore);
+   WRITE_ONCE(ads->ctl15, 0);
+   WRITE_ONCE(ads->ctl16, 0);
+   WRITE_ONCE(ads->ctl17, ctl17);
+

Re: [net/mm PATCH v2 0/3] Page fragment updates

2016-12-27 Thread Alexander Duyck
On Fri, Dec 23, 2016 at 9:50 AM, David Miller  wrote:
> From: Alexander Duyck 
> Date: Fri, 23 Dec 2016 09:16:39 -0800
>
>> I tried to get in touch with Andrew about this fix but I haven't heard any
>> reply to the email I sent out on Tuesday.  The last comment I had from
>> Andrew against v1 was "Looks good to me.  I have it all queued for post-4.9
>> processing.", but I haven't received any notice they were applied.
>
> Andrew, please follow up with Alex.

I'm assuming Andrew is probably out for the holidays since I didn't
hear anything, and since Linux pushed 4.10-rc1 I'm assuming I have
missed the merge window.

Dave, I was wondering if you would be okay with me trying to push the
three patches though net-next.  I'm thinking I might scale back the
first patch so that it is just a rename instead of making any
functional changes.  The main reason why I am thinking of trying to
submit through net-next is because then I can then start working on
submitting the driver patches for net-next.  Otherwise I'm looking at
this set creating a merge mess since I don't see a good way to push
the driver changes without already having these changes present.

I'll wait until Andrew can weigh in on the patches before
resubmitting.  My thought was to get an Acked-by from him and then see
if I can get them accepted into net-next.  That way there isn't any
funky cross-tree merging that will need to go on, and it shouldn't
really impact the mm tree all that much as the only consumers for the
page frag code are the network stack anyway.

Thanks.

- Alex


[PATCH 1/2] ath9k: ar9002_mac: kill off ACCESS_ONCE()

2016-12-27 Thread Mark Rutland
For several reasons, it is desirable to use {READ,WRITE}_ONCE() in
preference to ACCESS_ONCE(), and new code is expected to use one of the
former. So far, there's been no reason to change most existing uses of
ACCESS_ONCE(), as these aren't currently harmful.

However, for some new features (e.g. KTSAN / Kernel Thread Sanitizer),
it is necessary to instrument reads and writes separately, which is not
possible with ACCESS_ONCE(). This distinction is critical to correct
operation.

It's possible to transform the bulk of kernel code using the Coccinelle
script below. However, for some files (including the ath9k ar9002 mac
driver), this mangles the formatting. As a preparatory step, this patch
converts the driver to use {READ,WRITE}_ONCE() without said mangling.


virtual patch

@ depends on patch @
expression E1, E2;
@@

- ACCESS_ONCE(E1) = E2
+ WRITE_ONCE(E1, E2)

@ depends on patch @
expression E;
@@

- ACCESS_ONCE(E)
+ READ_ONCE(E)


Signed-off-by: Mark Rutland 
Cc: ath9k-de...@qca.qualcomm.com
Cc: Kalle Valo 
Cc: linux-wirel...@vger.kernel.org
Cc: ath9k-de...@lists.ath9k.org
Cc: netdev@vger.kernel.org
---
 drivers/net/wireless/ath/ath9k/ar9002_mac.c | 64 ++---
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c 
b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index f816909..4b3c9b1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -220,8 +220,8 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct 
ath_tx_info *i)
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 
-   ACCESS_ONCE(ads->ds_link) = i->link;
-   ACCESS_ONCE(ads->ds_data) = i->buf_addr[0];
+   WRITE_ONCE(ads->ds_link, i->link);
+   WRITE_ONCE(ads->ds_data, i->buf_addr[0]);
 
ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore);
ctl6 = SM(i->keytype, AR_EncrType);
@@ -235,26 +235,26 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct 
ath_tx_info *i)
 
if ((i->is_first || i->is_last) &&
i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
-   ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0)
+   WRITE_ONCE(ads->ds_ctl2, set11nTries(i->rates, 0)
| set11nTries(i->rates, 1)
| set11nTries(i->rates, 2)
| set11nTries(i->rates, 3)
| (i->dur_update ? AR_DurUpdateEna : 0)
-   | SM(0, AR_BurstDur);
+   | SM(0, AR_BurstDur));
 
-   ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0)
+   WRITE_ONCE(ads->ds_ctl3, set11nRate(i->rates, 0)
| set11nRate(i->rates, 1)
| set11nRate(i->rates, 2)
-   | set11nRate(i->rates, 3);
+   | set11nRate(i->rates, 3));
} else {
-   ACCESS_ONCE(ads->ds_ctl2) = 0;
-   ACCESS_ONCE(ads->ds_ctl3) = 0;
+   WRITE_ONCE(ads->ds_ctl2, 0);
+   WRITE_ONCE(ads->ds_ctl3, 0);
}
 
if (!i->is_first) {
-   ACCESS_ONCE(ads->ds_ctl0) = 0;
-   ACCESS_ONCE(ads->ds_ctl1) = ctl1;
-   ACCESS_ONCE(ads->ds_ctl6) = ctl6;
+   WRITE_ONCE(ads->ds_ctl0, 0);
+   WRITE_ONCE(ads->ds_ctl1, ctl1);
+   WRITE_ONCE(ads->ds_ctl6, ctl6);
return;
}
 
@@ -279,7 +279,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct 
ath_tx_info *i)
break;
}
 
-   ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
+   WRITE_ONCE(ads->ds_ctl0, (i->pkt_len & AR_FrameLen)
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
| SM(i->txpower[0], AR_XmitPower0)
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
@@ -287,29 +287,29 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct 
ath_tx_info *i)
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
-  (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
+  (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
 
-   ACCESS_ONCE(ads->ds_ctl1) = ctl1;
-   ACCESS_ONCE(ads->ds_ctl6) = ctl6;
+   WRITE_ONCE(ads->ds_ctl1, ctl1);
+   WRITE_ONCE(ads->ds_ctl6, ctl6);
 
if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
return;
 
-   ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
-   | set11nPktDurRTSCTS(i->rates, 1);
+   WRITE_ONCE(ads->ds_ctl4, set11nPktDurRTSCTS(i->rates, 0)
+   | set11nPktDurRTSCTS(i->rates, 1));
 
-   

[PATCH 0/2] ath9k: kill of ACCESS_ONCE() in MAC drivers

2016-12-27 Thread Mark Rutland
For several reasons, it would be beneficial to kill off ACCESS_ONCE()
tree-wide, in favour of {READ,WRITE}_ONCE(). These work with aggregate
types, more obviously document their intended behaviour, and are
necessary for tools like KTSAN to work correctly (as otherwise reads and
writes cannot be instrumented separately).

While it's possible to script a tree-wide conversion using Coccinelle,
some cases such as the ath9k MAC drivers require some manual
intervention to ensure that the resulting code remains legible. This
series moves the ath9k MAC drivers over to {READ,WRITE}_ONCE(). In both
cases this is functionally equivalent to the below Coccinelle script
being applied, though the existing formatting is retained.


virtual patch

@ depends on patch @
expression E1, E2;
@@

- ACCESS_ONCE(E1) = E2
+ WRITE_ONCE(E1, E2)

@ depends on patch @
expression E;
@@

- ACCESS_ONCE(E)
+ READ_ONCE(E)


Thanks,
Mark.

Mark Rutland (2):
  ath9k: ar9002_mac: kill off ACCESS_ONCE()
  ath9k: ar9003_mac: kill off ACCESS_ONCE()

 drivers/net/wireless/ath/ath9k/ar9002_mac.c | 64 ++--
 drivers/net/wireless/ath/ath9k/ar9003_mac.c | 92 ++---
 2 files changed, 78 insertions(+), 78 deletions(-)

-- 
2.7.4



Re: [Intel-wired-lan] [RFC PATCH] i40e: enable PCIe relax ordering for SPARC

2016-12-27 Thread Alexander Duyck
On Mon, Dec 26, 2016 at 3:39 AM, maowenan  wrote:
>
>
>> -Original Message-
>> From: netdev-ow...@vger.kernel.org [mailto:netdev-ow...@vger.kernel.org]
>> On Behalf Of Tushar Dave
>> Sent: Tuesday, December 06, 2016 1:07 AM
>> To: jeffrey.t.kirs...@intel.com; intel-wired-...@lists.osuosl.org
>> Cc: netdev@vger.kernel.org
>> Subject: [RFC PATCH] i40e: enable PCIe relax ordering for SPARC
>>
>> Unlike previous generation NIC (e.g. ixgbe) i40e doesn't seem to have 
>> standard
>> CSR where PCIe relaxed ordering can be set. Without PCIe relax ordering
>> enabled, i40e performance is significantly low on SPARC.
>>
> [Mao Wenan]Hi Tushar, you have referred to i40e doesn't seem to have standard 
> CSR
> to set PCIe relaxed ordering, this CSR like TX DCA Control Register in 
> 82599, right?
> Is DMA_ATTR_WEAK_ORDERING the same as TX control register in 82599?
>
> And to enable relax ordering mode in 82599 for SPARC using below codes:
> s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
> {
> u32 i;
>
> /* Clear the rate limiters */
> for (i = 0; i < hw->mac.max_tx_queues; i++) {
> IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
> IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
> }
> IXGBE_WRITE_FLUSH(hw);
>
> #ifndef CONFIG_SPARC
> /* Disable relaxed ordering */
> for (i = 0; i < hw->mac.max_tx_queues; i++) {
> u32 regval;
>
> regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
> regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
> IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
> }
>
> for (i = 0; i < hw->mac.max_rx_queues; i++) {
> u32 regval;
>
> regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
> regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN |
> IXGBE_DCA_RXCTRL_HEAD_WRO_EN);
> IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
> }
> #endif
> return 0;
> }
>
>
>

He isn't changing anything on the device itself.  The patches were
just added recently that support this for SPARC.  The IOMMU on some
SPARC platforms can indicate memory ordering rules, and by doing this
they get the goodness of relaxed ordering without having true relaxed
ordering enabled on the PCIe bus.

>> This patch sets PCIe relax ordering for SPARC arch by setting dma attr
>> DMA_ATTR_WEAK_ORDERING for every tx and rx DMA map/unmap.
>> This has shown 10x increase in performance numbers.
>>
>> e.g.
>> iperf TCP test with 10 threads on SPARC S7
>>
>> Test 1: Without this patch
>>
>> [root@brm-snt1-03 net]# iperf -s
>> 
>> Server listening on TCP port 5001
>> TCP window size: 85.3 KByte (default)
>> 
>> [  4] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40926 [  5] local
>> 16.0.0.7 port 5001 connected with 16.0.0.1 port 40934 [  6] local 16.0.0.7 
>> port
>> 5001 connected with 16.0.0.1 port 40930 [  7] local 16.0.0.7 port 5001
>> connected with 16.0.0.1 port 40928 [  8] local 16.0.0.7 port 5001 connected
>> with 16.0.0.1 port 40922 [  9] local 16.0.0.7 port 5001 connected with 
>> 16.0.0.1
>> port 40932 [ 10] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40920
>> [ 11] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 40924 [ 14] local
>> 16.0.0.7 port 5001 connected with 16.0.0.1 port 40982 [ 12] local 16.0.0.7 
>> port
>> 5001 connected with 16.0.0.1 port 40980
>> [ ID] Interval   Transfer Bandwidth
>> [  4]  0.0-20.0 sec   566 MBytes   237 Mbits/sec
>> [  5]  0.0-20.0 sec   532 MBytes   223 Mbits/sec
>> [  6]  0.0-20.0 sec   537 MBytes   225 Mbits/sec
>> [  8]  0.0-20.0 sec   546 MBytes   229 Mbits/sec
>> [ 11]  0.0-20.0 sec   592 MBytes   248 Mbits/sec
>> [  7]  0.0-20.0 sec   539 MBytes   226 Mbits/sec
>> [  9]  0.0-20.0 sec   572 MBytes   240 Mbits/sec
>> [ 10]  0.0-20.0 sec   604 MBytes   253 Mbits/sec
>> [ 14]  0.0-20.0 sec   567 MBytes   238 Mbits/sec
>> [ 12]  0.0-20.0 sec   511 MBytes   214 Mbits/sec
>> [SUM]  0.0-20.0 sec  5.44 GBytes  2.33 Gbits/sec
>>
>> Test 2: with this patch:
>>
>> [root@brm-snt1-03 net]# iperf -s
>> 
>> Server listening on TCP port 5001
>> TCP window size: 85.3 KByte (default)
>> 
>> TCP: request_sock_TCP: Possible SYN flooding on port 5001. Sending cookies.
>> Check SNMP counters.
>> [  4] local 16.0.0.7 port 5001 connected with 16.0.0.1 port 46876 [  5] local
>> 16.0.0.7 port 5001 connected with 16.0.0.1 port 46874 [  6] local 16.0.0.7 
>> port
>> 5001 connected with 16.0.0.1 port 46872 [  7] local 16.0.0.7 port 5001
>> connected with 16.0.0.1 port 46880 [  8] local 16.0.0.7 port 5001 connected
>> with 16.0.0.1 port 46878 [  9] local 16.0.0.7 port 5001 connected with 

Re: [PATCH] net: dev_weight: TX/RX orthogonality

2016-12-27 Thread Matthias Tafelmeier
On 12/27/2016 05:47 PM, Marcelo Ricardo Leitner wrote:
> On Tue, Dec 27, 2016 at 09:25:47AM +0100, Matthias Tafelmeier wrote:
>> Oftenly, introducing side effects on packet processing on the other half
>> of the stack by adjusting one of TX/RX via sysctl is not desirable.
>> There are cases of demand for asymmetric, orthogonal configurability.
>>
>> This holds true especially for nodes where RPS for RFS usage on top is
>> configured and therefore use the 'old dev_weight'. This is quite a
>> common base configuration setup nowadays, even with NICs of superior 
>> processing
>> support (e.g. aRFS).
>>
>> A good example use case are nodes acting as noSQL data bases with a
>> large number of tiny requests and rather fewer but large packets as 
>> responses.
>> It's affordable to have large budget and rx dev_weights for the
>> requests. But as a side effect having this large a number on TX
>> processed in one run can overwhelm drivers.
>>
>> This patch therefore introduces an independent configurability via sysctl to
>> userland.
>> ---
>>  include/linux/netdevice.h  |  2 ++
>>  net/core/dev.c |  4 +++-
>>  net/core/sysctl_net_core.c | 14 ++
>>  net/sched/sch_generic.c|  2 +-
>>  4 files changed, 20 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 994f742..bb331e0 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -3795,6 +3795,8 @@ void netdev_stats_to_stats64(struct rtnl_link_stats64 
>> *stats64,
>>  extern int  netdev_max_backlog;
>>  extern int  netdev_tstamp_prequeue;
>>  extern int  weight_p;
>> +extern int  dev_w_rx_bias;
>> +extern int  dev_w_tx_bias;
>>  
>>  bool netdev_has_upper_dev(struct net_device *dev, struct net_device 
>> *upper_dev);
>>  struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 8db5a0b..0dcbd28 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -3428,6 +3428,8 @@ EXPORT_SYMBOL(netdev_max_backlog);
>>  int netdev_tstamp_prequeue __read_mostly = 1;
>>  int netdev_budget __read_mostly = 300;
>>  int weight_p __read_mostly = 64;/* old backlog weight */
>> +int dev_w_rx_bias __read_mostly = 1;/* bias for backlog weight 
>> */
>> +int dev_w_tx_bias __read_mostly = 1;/* bias for output_queue 
>> quota */
>>  
>>  /* Called with irq disabled */
>>  static inline void napi_schedule(struct softnet_data *sd,
>> @@ -4833,7 +4835,7 @@ static int process_backlog(struct napi_struct *napi, 
>> int quota)
>>  net_rps_action_and_irq_enable(sd);
>>  }
>>  
>> -napi->weight = weight_p;
>> +napi->weight = weight_p * dev_w_rx_bias;
>>  while (again) {
>>  struct sk_buff *skb;
>>  
>> diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
>> index 2a46e40..a2ab149 100644
>> --- a/net/core/sysctl_net_core.c
>> +++ b/net/core/sysctl_net_core.c
>> @@ -276,6 +276,20 @@ static struct ctl_table net_core_table[] = {
>>  .proc_handler   = proc_dointvec
>>  },
>>  {
>> +.procname   = "dev_w_rx_bias",
>> +.data   = _w_rx_bias,
>> +.maxlen = sizeof(int),
>> +.mode   = 0644,
>> +.proc_handler   = proc_dointvec
>> +},
>> +{
>> +.procname   = "dev_w_tx_bias",
>> +.data   = _w_tx_bias,
>> +.maxlen = sizeof(int),
>> +.mode   = 0644,
>> +.proc_handler   = proc_dointvec
>> +},
>> +{
> Please describe these at Documentation/sysctl/net.txt, probably right
> after dev_weight. 
Sure, I'll do that.

> I'm not sure about the abbreviation, maybe it would be better the longer
> name as it doesn't block tab completion.
> dev_weight_tx_bias
> dev_weight_rx_bias
> dev_weight
>
Do not find the abbreviation/naming satisfactory, either. Rather saw
them as a draft. Could think of dev_weight distant naming:

ns_rps_cpu_rx_bias
ns_cpu_tx_bias

Though, makes me concerned about association etc. Maybe, that's nit
picking.




0x8ADF343B.asc
Description: application/pgp-keys


signature.asc
Description: OpenPGP digital signature


Re: [PATCH] net: stmmac: fix incorrect bit set in gmac4 mdio addr register

2016-12-27 Thread David Miller
From: "Kweh, Hock Leong"
Date: Wed, 28 Dec 2016 04:07:41 +0800

> From: "Kweh, Hock Leong" 
> 
> Fixing the gmac4 mdio write access to use MII_GMAC4_WRITE only instead of
> OR together with MII_WRITE.
> 
> Signed-off-by: Kweh, Hock Leong 

Applied.


Re: [PATCH net] net: xdp: remove unused bfp_warn_invalid_xdp_buffer()

2016-12-27 Thread David Miller
From: Jason Wang 
Date: Tue, 27 Dec 2016 10:49:54 +0800

> After commit 73b62bd085f4737679ea9afc7867fa5f99ba7d1b ("virtio-net:
> remove the warning before XDP linearizing"), there's no users for
> bpf_warn_invalid_xdp_buffer(), so remove it. This is a revert for
> commit f23bc46c30ca5ef58b8549434899fcbac41b2cfc.
> 
> Cc: Daniel Borkmann 
> Cc: John Fastabend 
> Signed-off-by: Jason Wang 

Applied.


Re: [PATCH net-next] r8169: add support for RTL8168 series add-on card.

2016-12-27 Thread David Miller
From: Chun-Hao Lin 
Date: Tue, 27 Dec 2016 16:29:43 +0800

> This chip is the same as RTL8168, but its device id is 0x8161.
> 
> Signed-off-by: Chun-Hao Lin 

Applied.


Re: [PATCH v2] ipv4: Namespaceify tcp_tw_reuse knob

2016-12-27 Thread David Miller
From: Haishuang Yan 
Date: Sun, 25 Dec 2016 14:33:16 +0800

> Different namespaces might have different requirements to reuse
> TIME-WAIT sockets for new connections. This might be required in
> cases where different namespace applications are in place which
> require TIME_WAIT socket connections to be reduced independently
> of the host.
> 
> Signed-off-by: Haishuang Yan 
> 
> ---
> Changes in v2:
>   - Make the commit message more clearer.

Applied.


Re: [PATCH net] openvswitch: upcall: Fix vlan handling.

2016-12-27 Thread David Miller
From: Pravin B Shelar 
Date: Mon, 26 Dec 2016 08:31:27 -0800

> Networking stack accelerate vlan tag handling by
> keeping topmost vlan header in skb. This works as
> long as packet remains in OVS datapath. But during
> OVS upcall vlan header is pushed on to the packet.
> When such packet is sent back to OVS datapath, core
> networking stack might not handle it correctly. Following
> patch avoids this issue by accelerating the vlan tag
> during flow key extract. This simplifies datapath by
> bringing uniform packet processing for packets from
> all code paths.
> 
> Fixes: 5108bbaddc ("openvswitch: add processing of L3 packets").
> CC: Jarno Rajahalme 
> CC: Jiri Benc 
> Signed-off-by: Pravin B Shelar 

Applied.


Re: [PATCH net-next 0/5] SCTP cleanups

2016-12-27 Thread David Miller
From: Marcelo Ricardo Leitner 
Date: Tue, 27 Dec 2016 15:08:27 -0200

> Some cleanups/simplifications I've been collecting.

Please resubmit these when I open the net-next tree back up.

Thank you.


[PATCH net-next 4/5] sctp: remove return value from sctp_packet_init/config

2016-12-27 Thread Marcelo Ricardo Leitner
There is no reason to use this cascading. It doesn't add anything.
Let's remove it and simplify.

Signed-off-by: Marcelo Ricardo Leitner 
---
 include/net/sctp/structs.h |  7 +++
 net/sctp/output.c  | 14 +-
 net/sctp/sm_statefuns.c|  5 +++--
 3 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 
92daabdc007d94a544baa10d278d229e42e40eb3..87d56cc80a3c1d8549b97391245dacc3b6193618
 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -722,10 +722,9 @@ struct sctp_packet {
ipfragok:1; /* So let ip fragment this packet */
 };
 
-struct sctp_packet *sctp_packet_init(struct sctp_packet *,
-struct sctp_transport *,
-__u16 sport, __u16 dport);
-struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
+void sctp_packet_init(struct sctp_packet *, struct sctp_transport *,
+ __u16 sport, __u16 dport);
+void sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
 sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *,
   struct sctp_chunk *, int, gfp_t);
 sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *,
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 
f5320a87341e160d46b1160edf4c38b569e7e79b..07ab5062e541dc663b619a278742425a92002945
 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -81,8 +81,8 @@ static void sctp_packet_reset(struct sctp_packet *packet)
 /* Config a packet.
  * This appears to be a followup set of initializations.
  */
-struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
-  __u32 vtag, int ecn_capable)
+void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,
+   int ecn_capable)
 {
struct sctp_transport *tp = packet->transport;
struct sctp_association *asoc = tp->asoc;
@@ -123,14 +123,12 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet 
*packet,
if (chunk)
sctp_packet_append_chunk(packet, chunk);
}
-
-   return packet;
 }
 
 /* Initialize the packet structure. */
-struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
-struct sctp_transport *transport,
-__u16 sport, __u16 dport)
+void sctp_packet_init(struct sctp_packet *packet,
+ struct sctp_transport *transport,
+ __u16 sport, __u16 dport)
 {
struct sctp_association *asoc = transport->asoc;
size_t overhead;
@@ -151,8 +149,6 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet 
*packet,
packet->overhead = overhead;
sctp_packet_reset(packet);
packet->vtag = 0;
-
-   return packet;
 }
 
 /* Free a packet.  */
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 
a95915ef9dbabad30f6171f77b26feab61752f36..9a223d5b2314ff166be0446462c33219b7eec1b9
 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -6032,8 +6032,9 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net 
*net,
sctp_transport_route(transport, (union sctp_addr *)>dest,
 sctp_sk(net->sctp.ctl_sock));
 
-   packet = sctp_packet_init(>packet, transport, sport, dport);
-   packet = sctp_packet_config(packet, vtag, 0);
+   packet = >packet;
+   sctp_packet_init(packet, transport, sport, dport);
+   sctp_packet_config(packet, vtag, 0);
 
return packet;
 
-- 
2.9.3



[PATCH net-next 5/5] sctp: sctp_chunk_length_valid should return bool

2016-12-27 Thread Marcelo Ricardo Leitner
Signed-off-by: Marcelo Ricardo Leitner 
---
 net/sctp/sm_statefuns.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 
9a223d5b2314ff166be0446462c33219b7eec1b9..3382ef254e7b41ae4723f2e72e5aca30d46a4a8e
 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -160,23 +160,22 @@ static sctp_disposition_t __sctp_sf_do_9_1_abort(struct 
net *net,
 /* Small helper function that checks if the chunk length
  * is of the appropriate length.  The 'required_length' argument
  * is set to be the size of a specific chunk we are testing.
- * Return Values:  1 = Valid length
- *0 = Invalid length
+ * Return Values:  true  = Valid length
+ *false = Invalid length
  *
  */
-static inline int
-sctp_chunk_length_valid(struct sctp_chunk *chunk,
-  __u16 required_length)
+static inline bool
+sctp_chunk_length_valid(struct sctp_chunk *chunk, __u16 required_length)
 {
__u16 chunk_length = ntohs(chunk->chunk_hdr->length);
 
/* Previously already marked? */
if (unlikely(chunk->pdiscard))
-   return 0;
+   return false;
if (unlikely(chunk_length < required_length))
-   return 0;
+   return false;
 
-   return 1;
+   return true;
 }
 
 /**
-- 
2.9.3



[PATCH net-next 3/5] sctp: simplify addr copy

2016-12-27 Thread Marcelo Ricardo Leitner
Make it a bit easier to read.

Signed-off-by: Marcelo Ricardo Leitner 
---
 net/sctp/ipv6.c | 16 +++-
 net/sctp/protocol.c | 18 +++---
 2 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 
176af3080a2b8f8ffc56b55f3ccb13a169e195fe..434167ac0c8e89078b0bac80f0a81da92be37e07
 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -412,22 +412,20 @@ static void sctp_v6_copy_addrlist(struct list_head 
*addrlist,
 static void sctp_v6_from_skb(union sctp_addr *addr, struct sk_buff *skb,
 int is_saddr)
 {
-   __be16 *port;
-   struct sctphdr *sh;
+   /* Always called on head skb, so this is safe */
+   struct sctphdr *sh = sctp_hdr(skb);
+   struct sockaddr_in6 *sa = >v6;
 
-   port = >v6.sin6_port;
addr->v6.sin6_family = AF_INET6;
addr->v6.sin6_flowinfo = 0; /* FIXME */
addr->v6.sin6_scope_id = ((struct inet6_skb_parm *)skb->cb)->iif;
 
-   /* Always called on head skb, so this is safe */
-   sh = sctp_hdr(skb);
if (is_saddr) {
-   *port  = sh->source;
-   addr->v6.sin6_addr = ipv6_hdr(skb)->saddr;
+   sa->sin6_port = sh->source;
+   sa->sin6_addr = ipv6_hdr(skb)->saddr;
} else {
-   *port = sh->dest;
-   addr->v6.sin6_addr = ipv6_hdr(skb)->daddr;
+   sa->sin6_port = sh->dest;
+   sa->sin6_addr = ipv6_hdr(skb)->daddr;
}
 }
 
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 
ad40fa153878f354a367b5cefa2ccd4322463eb2..fe6c62607e99961b5b3bf524b6f6f46d4be3251d
 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -237,23 +237,19 @@ int sctp_copy_local_addr_list(struct net *net, struct 
sctp_bind_addr *bp,
 static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
 int is_saddr)
 {
-   void *from;
-   __be16 *port;
-   struct sctphdr *sh;
+   /* Always called on head skb, so this is safe */
+   struct sctphdr *sh = sctp_hdr(skb);
+   struct sockaddr_in *sa = >v4;
 
-   port = >v4.sin_port;
addr->v4.sin_family = AF_INET;
 
-   /* Always called on head skb, so this is safe */
-   sh = sctp_hdr(skb);
if (is_saddr) {
-   *port  = sh->source;
-   from = _hdr(skb)->saddr;
+   sa->sin_port = sh->source;
+   sa->sin_addr.s_addr = ip_hdr(skb)->saddr;
} else {
-   *port = sh->dest;
-   from = _hdr(skb)->daddr;
+   sa->sin_port = sh->dest;
+   sa->sin_addr.s_addr = ip_hdr(skb)->daddr;
}
-   memcpy(>v4.sin_addr.s_addr, from, sizeof(struct in_addr));
 }
 
 /* Initialize an sctp_addr from a socket. */
-- 
2.9.3



[PATCH net-next 0/5] SCTP cleanups

2016-12-27 Thread Marcelo Ricardo Leitner
Some cleanups/simplifications I've been collecting.

Marcelo Ricardo Leitner (5):
  sctp: reduce indent level at sctp_sf_tabort_8_4_8
  sctp: reduce indent level in sctp_sf_shut_8_4_5
  sctp: simplify addr copy
  sctp: remove return value from sctp_packet_init/config
  sctp: sctp_chunk_length_valid should return bool

 include/net/sctp/structs.h |   7 ++-
 net/sctp/ipv6.c|  16 +++---
 net/sctp/output.c  |  14 ++
 net/sctp/protocol.c|  18 +++
 net/sctp/sm_statefuns.c| 122 ++---
 5 files changed, 81 insertions(+), 96 deletions(-)

-- 
2.9.3



[PATCH net-next 1/5] sctp: reduce indent level at sctp_sf_tabort_8_4_8

2016-12-27 Thread Marcelo Ricardo Leitner
Signed-off-by: Marcelo Ricardo Leitner 
---
 net/sctp/sm_statefuns.c | 44 +---
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 
8ec20a64a3f8055a0c3576627c5ec5dad7e99ca8..32587b1f84e729221965e270607fea7ef93a7430
 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3237,36 +3237,34 @@ static sctp_disposition_t sctp_sf_tabort_8_4_8(struct 
net *net,
struct sctp_chunk *abort;
 
packet = sctp_ootb_pkt_new(net, asoc, chunk);
+   if (!packet)
+   return SCTP_DISPOSITION_NOMEM;
 
-   if (packet) {
-   /* Make an ABORT. The T bit will be set if the asoc
-* is NULL.
-*/
-   abort = sctp_make_abort(asoc, chunk, 0);
-   if (!abort) {
-   sctp_ootb_pkt_free(packet);
-   return SCTP_DISPOSITION_NOMEM;
-   }
+   /* Make an ABORT. The T bit will be set if the asoc
+* is NULL.
+*/
+   abort = sctp_make_abort(asoc, chunk, 0);
+   if (!abort) {
+   sctp_ootb_pkt_free(packet);
+   return SCTP_DISPOSITION_NOMEM;
+   }
 
-   /* Reflect vtag if T-Bit is set */
-   if (sctp_test_T_bit(abort))
-   packet->vtag = ntohl(chunk->sctp_hdr->vtag);
+   /* Reflect vtag if T-Bit is set */
+   if (sctp_test_T_bit(abort))
+   packet->vtag = ntohl(chunk->sctp_hdr->vtag);
 
-   /* Set the skb to the belonging sock for accounting.  */
-   abort->skb->sk = ep->base.sk;
+   /* Set the skb to the belonging sock for accounting.  */
+   abort->skb->sk = ep->base.sk;
 
-   sctp_packet_append_chunk(packet, abort);
+   sctp_packet_append_chunk(packet, abort);
 
-   sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
-   SCTP_PACKET(packet));
-
-   SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
+   sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
+   SCTP_PACKET(packet));
 
-   sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
-   return SCTP_DISPOSITION_CONSUME;
-   }
+   SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
 
-   return SCTP_DISPOSITION_NOMEM;
+   sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+   return SCTP_DISPOSITION_CONSUME;
 }
 
 /*
-- 
2.9.3



[PATCH net-next 2/5] sctp: reduce indent level in sctp_sf_shut_8_4_5

2016-12-27 Thread Marcelo Ricardo Leitner
Signed-off-by: Marcelo Ricardo Leitner 
---
 net/sctp/sm_statefuns.c | 58 -
 1 file changed, 28 insertions(+), 30 deletions(-)

diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 
32587b1f84e729221965e270607fea7ef93a7430..a95915ef9dbabad30f6171f77b26feab61752f36
 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3501,45 +3501,43 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(struct net 
*net,
struct sctp_chunk *shut;
 
packet = sctp_ootb_pkt_new(net, asoc, chunk);
+   if (!packet)
+   return SCTP_DISPOSITION_NOMEM;
 
-   if (packet) {
-   /* Make an SHUTDOWN_COMPLETE.
-* The T bit will be set if the asoc is NULL.
-*/
-   shut = sctp_make_shutdown_complete(asoc, chunk);
-   if (!shut) {
-   sctp_ootb_pkt_free(packet);
-   return SCTP_DISPOSITION_NOMEM;
-   }
-
-   /* Reflect vtag if T-Bit is set */
-   if (sctp_test_T_bit(shut))
-   packet->vtag = ntohl(chunk->sctp_hdr->vtag);
+   /* Make an SHUTDOWN_COMPLETE.
+* The T bit will be set if the asoc is NULL.
+*/
+   shut = sctp_make_shutdown_complete(asoc, chunk);
+   if (!shut) {
+   sctp_ootb_pkt_free(packet);
+   return SCTP_DISPOSITION_NOMEM;
+   }
 
-   /* Set the skb to the belonging sock for accounting.  */
-   shut->skb->sk = ep->base.sk;
+   /* Reflect vtag if T-Bit is set */
+   if (sctp_test_T_bit(shut))
+   packet->vtag = ntohl(chunk->sctp_hdr->vtag);
 
-   sctp_packet_append_chunk(packet, shut);
+   /* Set the skb to the belonging sock for accounting.  */
+   shut->skb->sk = ep->base.sk;
 
-   sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
-   SCTP_PACKET(packet));
+   sctp_packet_append_chunk(packet, shut);
 
-   SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
+   sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
+   SCTP_PACKET(packet));
 
-   /* If the chunk length is invalid, we don't want to process
-* the reset of the packet.
-*/
-   if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
-   return sctp_sf_pdiscard(net, ep, asoc, type, arg, 
commands);
+   SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS);
 
-   /* We need to discard the rest of the packet to prevent
-* potential bomming attacks from additional bundled chunks.
-* This is documented in SCTP Threats ID.
-*/
+   /* If the chunk length is invalid, we don't want to process
+* the reset of the packet.
+*/
+   if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
-   }
 
-   return SCTP_DISPOSITION_NOMEM;
+   /* We need to discard the rest of the packet to prevent
+* potential bomming attacks from additional bundled chunks.
+* This is documented in SCTP Threats ID.
+*/
+   return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
 }
 
 /*
-- 
2.9.3



[PATCH v2 06/16] net: mvpp2: adjust the allocation/free of BM pools for PPv2.2

2016-12-27 Thread Thomas Petazzoni
This commit adjusts the allocation and freeing of BM pools to support
PPv2.2. This involves:

 - Checking that the number of buffer pointers is a multiple of 16, as
   required by the hardware.

 - Adjusting the size of the DMA coherent area allocated for buffer
   pointers. Indeed, PPv2.2 needs space for 2 pointers of 64-bits per
   buffer, as opposed to 2 pointers of 32-bits per buffer in
   PPv2.1. The size in bytes is now stored in a new field of the
   mvpp2_bm_pool structure.

 - On PPv2.2, the 32 high order bits of the BM pointer area physical
   address must be programmed in the MVPP2_BM_HIGH_BASE_REG register.

 - On PPv2.2, getting the physical and virtual address of each buffer
   requires reading the MVPP2_BM_ADDR_HIGH_ALLOC to get the high order
   bits of those addresses. A new utility function
   mvpp2_bm_bufs_get_addrs() is introduced to handle this.

 - On PPv2.2, releasing a buffer requires writing the high order 32 bits
   of the physical address to MVPP2_BM_PHY_VIRT_HIGH_RLS_REG. We no
   longer need to write the virtual address to MVPP2_BM_VIRT_RLS_REG.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 97 ++--
 1 file changed, 82 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 0e00ec0..160b787 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -208,17 +208,28 @@
 #define MVPP2_BM_BPPE_FULL_MASKBIT(3)
 #define MVPP2_BM_AVAILABLE_BP_LOW_MASK BIT(4)
 #define MVPP2_BM_INTR_MASK_REG(pool)   (0x6280 + ((pool) * 4))
+#define MVPP2_BM_HIGH_BASE_REG 0x6310
+#define MVPP2_BM_HIGH_BASE_MASK0xff
 #define MVPP2_BM_PHY_ALLOC_REG(pool)   (0x6400 + ((pool) * 4))
 #define MVPP2_BM_PHY_ALLOC_GRNTD_MASK  BIT(0)
 #define MVPP2_BM_VIRT_ALLOC_REG0x6440
+#define MVPP2_BM_ADDR_HIGH_ALLOC   0x6444
+#define MVPP2_BM_ADDR_HIGH_PHYS_MASK   0xff
+#define MVPP2_BM_ADDR_HIGH_VIRT_MASK   0xff00
+#define MVPP2_BM_ADDR_HIGH_VIRT_SHIFT  8
 #define MVPP2_BM_PHY_RLS_REG(pool) (0x6480 + ((pool) * 4))
 #define MVPP2_BM_PHY_RLS_MC_BUFF_MASK  BIT(0)
 #define MVPP2_BM_PHY_RLS_PRIO_EN_MASK  BIT(1)
 #define MVPP2_BM_PHY_RLS_GRNTD_MASKBIT(2)
 #define MVPP2_BM_VIRT_RLS_REG  0x64c0
-#define MVPP2_BM_MC_RLS_REG0x64c4
+#define MVPP21_BM_MC_RLS_REG   0x64c4
 #define MVPP2_BM_MC_ID_MASK0xfff
 #define MVPP2_BM_FORCE_RELEASE_MASKBIT(12)
+#define MVPP22_BM_ADDR_HIGH_RLS_REG0x64c4
+#define MVPP22_BM_ADDR_HIGH_PHYS_RLS_MASK  0xff
+#defineMVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK   0xff00
+#define MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT 8
+#define MVPP22_BM_MC_RLS_REG   0x64d4
 
 /* TX Scheduler registers */
 #define MVPP2_TXP_SCHED_PORT_INDEX_REG 0x8000
@@ -957,6 +968,8 @@ struct mvpp2_bm_pool {
 
/* Buffer Pointers Pool External (BPPE) size */
int size;
+   /* BPPE size in bytes */
+   int size_bytes;
/* Number of buffers for this pool */
int buf_num;
/* Pool buffer size */
@@ -3558,11 +3571,23 @@ static int mvpp2_bm_pool_create(struct platform_device 
*pdev,
struct mvpp2 *priv,
struct mvpp2_bm_pool *bm_pool, int size)
 {
-   int size_bytes;
u32 val;
 
-   size_bytes = sizeof(u32) * size;
-   bm_pool->virt_addr = dma_alloc_coherent(>dev, size_bytes,
+   /* Number of buffer pointers must be a multiple of 16, as per
+* hardware constraints
+*/
+   if (!IS_ALIGNED(size, 16))
+   return -EINVAL;
+
+   /* PPv2.1 needs 8 bytes per buffer pointer, PPv2.2 needs 16
+* bytes per buffer pointer
+*/
+   if (priv->hw_version == MVPP21)
+   bm_pool->size_bytes = 2 * sizeof(u32) * size;
+   else
+   bm_pool->size_bytes = 2 * sizeof(u64) * size;
+
+   bm_pool->virt_addr = dma_alloc_coherent(>dev, bm_pool->size_bytes,
_pool->phys_addr,
GFP_KERNEL);
if (!bm_pool->virt_addr)
@@ -3570,15 +3595,24 @@ static int mvpp2_bm_pool_create(struct platform_device 
*pdev,
 
if (!IS_ALIGNED((unsigned long)bm_pool->virt_addr,
MVPP2_BM_POOL_PTR_ALIGN)) {
-   dma_free_coherent(>dev, size_bytes, bm_pool->virt_addr,
- bm_pool->phys_addr);
+   dma_free_coherent(>dev, bm_pool->size_bytes,
+ bm_pool->virt_addr, bm_pool->phys_addr);
dev_err(>dev, "BM pool %d is not %d bytes 

Re: [PATCH v2 00/11] net: mvpp2: misc improvements and preparation patches

2016-12-27 Thread David Miller

net-next is still closed, please do not submit cleanups and new features


[PATCH v2 08/16] net: mvpp2: adapt mvpp2_defaults_set() to PPv2.2

2016-12-27 Thread Thomas Petazzoni
This commit modifies the mvpp2_defaults_set() function to not do the
loopback and FIFO threshold initialization, which are not needed for
PPv2.2.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 22 --
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 8fc818d..23f2368 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -4205,16 +4205,18 @@ static void mvpp2_defaults_set(struct mvpp2_port *port)
 {
int tx_port_num, val, queue, ptxq, lrxq;
 
-   /* Configure port to loopback if needed */
-   if (port->flags & MVPP2_F_LOOPBACK)
-   mvpp2_port_loopback_set(port);
-
-   /* Update TX FIFO MIN Threshold */
-   val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
-   val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK;
-   /* Min. TX threshold must be less than minimal packet length */
-   val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(64 - 4 - 2);
-   writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+   if (port->priv->hw_version == MVPP21) {
+   /* Configure port to loopback if needed */
+   if (port->flags & MVPP2_F_LOOPBACK)
+   mvpp2_port_loopback_set(port);
+
+   /* Update TX FIFO MIN Threshold */
+   val = readl(port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+   val &= ~MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK;
+   /* Min. TX threshold must be less than minimal packet length */
+   val |= MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(64 - 4 - 2);
+   writel(val, port->base + MVPP2_GMAC_PORT_FIFO_CFG_1_REG);
+   }
 
/* Disable Legacy WRR, Disable EJP, Release from reset */
tx_port_num = mvpp2_egress_port(port);
-- 
2.7.4



[PATCH v2 14/16] net: mvpp2: adapt rxq distribution to PPv2.2

2016-12-27 Thread Thomas Petazzoni
In PPv2.1, we have a maximum of 8 RXQs per port, with a default of 4
RXQs per port, and we were assigning RXQs 0->3 to the first port, 4->7
to the second port, 8->11 to the third port, etc.

In PPv2.2, we have a maximum of 32 RXQs per port, and we must allocate
RXQs from the range of 32 RXQs available for each port. So port 0 must
use RXQs in the range 0->31, port 1 in the range 32->63, etc.

This commit adapts the mvpp2 to this difference between PPv2.1 and
PPv2.2:

 - The constant definition MVPP2_MAX_RXQ is replaced by a new field
   'max_port_rxqs' in 'struct mvpp2', which stores the maximum number of
   RXQs per port. This field is initialized during ->probe() depending
   on the IP version.

 - MVPP2_RXQ_TOTAL_NUM is removed, and instead we calculate the total
   number of RXQs by multiplying the number of ports by the maximum of
   RXQs per port. This was anyway used in only one place.

 - In mvpp2_port_probe(), the calculation of port->first_rxq is adjusted
   to cope with the different allocation strategy between PPv2.1 and
   PPv2.2. Due to this change, the 'next_first_rxq' argument of this
   function is no longer needed and is removed.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 35 +++
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index baad991..20e9429 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -399,15 +399,9 @@
 /* Maximum number of TXQs used by single port */
 #define MVPP2_MAX_TXQ  8
 
-/* Maximum number of RXQs used by single port */
-#define MVPP2_MAX_RXQ  8
-
 /* Dfault number of RXQs in use */
 #define MVPP2_DEFAULT_RXQ  4
 
-/* Total number of RXQs available to all ports */
-#define MVPP2_RXQ_TOTAL_NUM(MVPP2_MAX_PORTS * MVPP2_MAX_RXQ)
-
 /* Max number of Rx descriptors */
 #define MVPP2_MAX_RXD  128
 
@@ -728,6 +722,9 @@ struct mvpp2 {
 
/* HW version */
enum { MVPP21, MVPP22 } hw_version;
+
+   /* Maximum number of RXQs per port */
+   unsigned int max_port_rxqs;
 };
 
 struct mvpp2_pcpu_stats {
@@ -6333,7 +6330,8 @@ static int mvpp2_port_init(struct mvpp2_port *port)
struct mvpp2_txq_pcpu *txq_pcpu;
int queue, cpu, err;
 
-   if (port->first_rxq + rxq_number > MVPP2_RXQ_TOTAL_NUM)
+   if (port->first_rxq + rxq_number >
+   MVPP2_MAX_PORTS * priv->max_port_rxqs)
return -EINVAL;
 
/* Disable port */
@@ -6452,8 +6450,7 @@ static int mvpp2_port_init(struct mvpp2_port *port)
 /* Ports initialization */
 static int mvpp2_port_probe(struct platform_device *pdev,
struct device_node *port_node,
-   struct mvpp2 *priv,
-   int *next_first_rxq)
+   struct mvpp2 *priv)
 {
struct device_node *phy_node;
struct mvpp2_port *port;
@@ -6511,7 +6508,11 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 
port->priv = priv;
port->id = id;
-   port->first_rxq = *next_first_rxq;
+   if (priv->hw_version == MVPP21)
+   port->first_rxq = port->id * rxq_number;
+   else
+   port->first_rxq = port->id * priv->max_port_rxqs;
+
port->phy_node = phy_node;
port->phy_interface = phy_mode;
 
@@ -6608,8 +6609,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
}
netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);
 
-   /* Increment the first Rx queue number to be used by the next port */
-   *next_first_rxq += rxq_number;
priv->port_list[id] = port;
return 0;
 
@@ -6755,7 +6754,7 @@ static int mvpp2_init(struct platform_device *pdev, 
struct mvpp2 *priv)
u32 val;
 
/* Checks for hardware constraints */
-   if (rxq_number % 4 || (rxq_number > MVPP2_MAX_RXQ) ||
+   if (rxq_number % 4 || (rxq_number > priv->max_port_rxqs) ||
(txq_number > MVPP2_MAX_TXQ)) {
dev_err(>dev, "invalid queue size parameter\n");
return -EINVAL;
@@ -6844,7 +6843,7 @@ static int mvpp2_probe(struct platform_device *pdev)
struct device_node *port_node;
struct mvpp2 *priv;
struct resource *res;
-   int port_count, first_rxq, cpu;
+   int port_count, cpu;
int err;
 
priv = devm_kzalloc(>dev, sizeof(struct mvpp2), GFP_KERNEL);
@@ -6879,6 +6878,11 @@ static int mvpp2_probe(struct platform_device *pdev)
priv->cpu_base[cpu] = priv->base + cpu * addr_space_sz;
}
 
+   if (priv->hw_version == MVPP21)
+   priv->max_port_rxqs = 8;
+   else
+   priv->max_port_rxqs = 32;
+
priv->pp_clk = devm_clk_get(>dev, "pp_clk");

[PATCH v2 10/16] net: mvpp2: handle register mapping and access for PPv2.2

2016-12-27 Thread Thomas Petazzoni
This commit adjusts the mvpp2 driver register mapping and access logic
to support PPv2.2, to handle a number of differences.

Due to how the registers are laid out in memory, the Device Tree binding
for the "reg" property is different:

 - On PPv2.1, we had a first area for the common registers, and then one
   area per port.

 - On PPv2.2, we have a first area for the common registers, and a
   second area for all the per-ports registers.

In addition, on PPv2.2, the area for the common registers is split into
so-called "address spaces" of 64 KB each. They allow to access the same
registers, but from different CPUs. Hence the introduction of cpu_base[]
in 'struct mvpp2', and the modification of the mvpp2_write() and
mvpp2_read() register accessors. For PPv2.1, the compatibility is
preserved by using an "address space" size of 0.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 78 +---
 1 file changed, 64 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 22f7970..389cc62 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -304,6 +304,9 @@
 #define  MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(v) (((v) << 6) & \
MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK)
 
+#define MVPP22_PORT_BASE   0x30e00
+#define MVPP22_PORT_OFFSET 0x1000
+
 #define MVPP2_CAUSE_TXQ_SENT_DESC_ALL_MASK 0xff
 
 /* Descriptor ring Macros */
@@ -631,6 +634,11 @@ enum mvpp2_prs_l3_cast {
  */
 #define MVPP2_BM_SHORT_PKT_SIZEMVPP2_RX_MAX_PKT_SIZE(512)
 
+#define MVPP21_ADDR_SPACE_SZ   0
+#define MVPP22_ADDR_SPACE_SZ   SZ_64K
+
+#define MVPP2_MAX_CPUS 4
+
 enum mvpp2_bm_type {
MVPP2_BM_FREE,
MVPP2_BM_SWF_LONG,
@@ -644,6 +652,13 @@ struct mvpp2 {
/* Shared registers' base addresses */
void __iomem *base;
void __iomem *lms_base;
+   void __iomem *iface_base;
+
+   /* On PPv2.2, each CPU can access the base register through a
+* separate address space, each 64 KB apart from each
+* other.
+*/
+   void __iomem *cpu_base[MVPP2_MAX_CPUS];
 
/* Common clocks */
struct clk *pp_clk;
@@ -1021,12 +1036,21 @@ static int txq_number = MVPP2_MAX_TXQ;
 
 static void mvpp2_write(struct mvpp2 *priv, u32 offset, u32 data)
 {
-   writel(data, priv->base + offset);
+   int cpu = get_cpu();
+
+   writel(data, priv->cpu_base[cpu] + offset);
+   put_cpu();
 }
 
 static u32 mvpp2_read(struct mvpp2 *priv, u32 offset)
 {
-   return readl(priv->base + offset);
+   int cpu = get_cpu();
+   u32 val;
+
+   val = readl(priv->cpu_base[cpu] + offset);
+   put_cpu();
+
+   return val;
 }
 
 static dma_addr_t mvpp2_txdesc_phys_addr_get(struct mvpp2_port *port,
@@ -6386,7 +6410,6 @@ static int mvpp2_port_probe(struct platform_device *pdev,
u32 id;
int features;
int phy_mode;
-   int priv_common_regs_num = 2;
int err, i, cpu;
 
dev = alloc_etherdev_mqs(sizeof(struct mvpp2_port), txq_number,
@@ -6436,12 +6459,24 @@ static int mvpp2_port_probe(struct platform_device 
*pdev,
port->phy_node = phy_node;
port->phy_interface = phy_mode;
 
-   res = platform_get_resource(pdev, IORESOURCE_MEM,
-   priv_common_regs_num + id);
-   port->base = devm_ioremap_resource(>dev, res);
-   if (IS_ERR(port->base)) {
-   err = PTR_ERR(port->base);
-   goto err_free_irq;
+   if (priv->hw_version == MVPP21) {
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 2 + id);
+   port->base = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(port->base)) {
+   err = PTR_ERR(port->base);
+   goto err_free_irq;
+   }
+   } else {
+   u32 gop_id;
+
+   if (of_property_read_u32(port_node, "gop-port-id", _id)) {
+   err = -EINVAL;
+   dev_err(>dev, "missing gop-port-id value\n");
+   goto err_free_irq;
+   }
+
+   port->base = priv->iface_base + MVPP22_PORT_BASE +
+   gop_id * MVPP22_PORT_OFFSET;
}
 
/* Alloc per-cpu stats */
@@ -6674,7 +6709,7 @@ static int mvpp2_probe(struct platform_device *pdev)
struct device_node *port_node;
struct mvpp2 *priv;
struct resource *res;
-   int port_count, first_rxq;
+   int port_count, first_rxq, cpu;
int err;
 
priv = devm_kzalloc(>dev, sizeof(struct mvpp2), GFP_KERNEL);
@@ -6689,10 +6724,25 @@ static int mvpp2_probe(struct platform_device *pdev)
if (IS_ERR(priv->base))
return 

[PATCH v2 02/16] net: mvpp2: add and use accessors for TX/RX descriptors

2016-12-27 Thread Thomas Petazzoni
The PPv2.2 IP has a different TX and RX descriptor layout compared to
PPv2.1. In order to prepare for the introduction of PPv2.2 support in
mvpp2, this commit adds accessors for the different fields of the TX
and RX descriptors, and changes the code to use them.

For now, the mvpp2_port argument passed to the accessors is not used,
but it will be used in follow-up to update the descriptor according to
the version of the IP being used.

Apart from the mechanical changes to use the newly introduced
accessors, a few other changes, needed to use the accessors, are made:

 - The mvpp2_txq_inc_put() function now takes a mvpp2_port as first
   argument, as it is needed to use the accessors.

 - Similarly, the mvpp2_bm_cookie_build() gains a mvpp2_port first
   argument, for the same reason.

 - In mvpp2_rx_error(), instead of accessing the RX descriptor in each
   case of the switch, we introduce a local variable to store the
   packet size.

 - Similarly, in mvpp2_buff_hdr_rx(), we introduce a local "cookie"
   variable to store the RX descriptor cookie, rather than accessing
   it from the descriptor each time.

 - In mvpp2_tx_frag_process() and mvpp2_tx() instead of accessing the
   packet size from the TX descriptor, we use the actual value
   available in the function, which is used to set the TX descriptor
   packet size a few lines before.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 187 +--
 1 file changed, 137 insertions(+), 50 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 2268808..fd84923 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -967,6 +967,77 @@ static u32 mvpp2_read(struct mvpp2 *priv, u32 offset)
return readl(priv->base + offset);
 }
 
+static dma_addr_t mvpp2_txdesc_phys_addr_get(struct mvpp2_port *port,
+struct mvpp2_tx_desc *tx_desc)
+{
+   return tx_desc->buf_phys_addr;
+}
+
+static void mvpp2_txdesc_phys_addr_set(struct mvpp2_port *port,
+  struct mvpp2_tx_desc *tx_desc,
+  dma_addr_t phys_addr)
+{
+   tx_desc->buf_phys_addr = phys_addr;
+}
+
+static size_t mvpp2_txdesc_size_get(struct mvpp2_port *port,
+   struct mvpp2_tx_desc *tx_desc)
+{
+   return tx_desc->data_size;
+}
+
+static void mvpp2_txdesc_size_set(struct mvpp2_port *port,
+ struct mvpp2_tx_desc *tx_desc,
+ size_t size)
+{
+   tx_desc->data_size = size;
+}
+
+static void mvpp2_txdesc_txq_set(struct mvpp2_port *port,
+struct mvpp2_tx_desc *tx_desc,
+unsigned int txq)
+{
+   tx_desc->phys_txq = txq;
+}
+
+static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port,
+struct mvpp2_tx_desc *tx_desc,
+unsigned int command)
+{
+   tx_desc->command = command;
+}
+
+static void mvpp2_txdesc_offset_set(struct mvpp2_port *port,
+   struct mvpp2_tx_desc *tx_desc,
+   unsigned int offset)
+{
+   tx_desc->packet_offset = offset;
+}
+
+static dma_addr_t mvpp2_rxdesc_phys_addr_get(struct mvpp2_port *port,
+struct mvpp2_rx_desc *rx_desc)
+{
+   return rx_desc->buf_phys_addr;
+}
+
+static unsigned long mvpp2_rxdesc_virt_addr_get(struct mvpp2_port *port,
+   struct mvpp2_rx_desc *rx_desc)
+{
+   return rx_desc->buf_cookie;
+}
+
+static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
+   struct mvpp2_rx_desc *rx_desc)
+{
+   return rx_desc->data_size;
+}
+
+static u32 mvpp2_rxdesc_status_get(struct mvpp2_port *port,
+  struct mvpp2_rx_desc *rx_desc)
+{
+   return rx_desc->status;
+}
+
 static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)
 {
txq_pcpu->txq_get_index++;
@@ -974,15 +1045,16 @@ static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu 
*txq_pcpu)
txq_pcpu->txq_get_index = 0;
 }
 
-static void mvpp2_txq_inc_put(struct mvpp2_txq_pcpu *txq_pcpu,
+static void mvpp2_txq_inc_put(struct mvpp2_port *port,
+ struct mvpp2_txq_pcpu *txq_pcpu,
  struct sk_buff *skb,
  struct mvpp2_tx_desc *tx_desc)
 {
struct mvpp2_txq_pcpu_buf *tx_buf =
txq_pcpu->buffs + txq_pcpu->txq_put_index;
tx_buf->skb = skb;
-   tx_buf->size = tx_desc->data_size;
-   tx_buf->phys = tx_desc->buf_phys_addr;
+   tx_buf->size = mvpp2_txdesc_size_get(port, tx_desc);
+   tx_buf->phys = 

[PATCH v2 09/16] net: mvpp2: adjust mvpp2_{rxq,txq}_init for PPv2.2

2016-12-27 Thread Thomas Petazzoni
In PPv2.2, the MVPP2_RXQ_DESC_ADDR_REG and MVPP2_TXQ_DESC_ADDR_REG
registers have a slightly different layout, because they need to contain
a 64-bit address for the RX and TX descriptor arrays. This commit
adjusts those functions accordingly.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 23f2368..22f7970 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -102,6 +102,7 @@
 /* Descriptor Manager Top Registers */
 #define MVPP2_RXQ_NUM_REG  0x2040
 #define MVPP2_RXQ_DESC_ADDR_REG0x2044
+#define MVPP22_DESC_ADDR_OFFS  8
 #define MVPP2_RXQ_DESC_SIZE_REG0x2048
 #define MVPP2_RXQ_DESC_SIZE_MASK   0x3ff0
 #define MVPP2_RXQ_STATUS_UPDATE_REG(rxq)   (0x3000 + 4 * (rxq))
@@ -143,6 +144,7 @@
 #define MVPP2_TXQ_RSVD_CLR_REG 0x20b8
 #define MVPP2_TXQ_RSVD_CLR_OFFSET  16
 #define MVPP2_AGGR_TXQ_DESC_ADDR_REG(cpu)  (0x2100 + 4 * (cpu))
+#define MVPP22_AGGR_TXQ_DESC_ADDR_OFFS 8
 #define MVPP2_AGGR_TXQ_DESC_SIZE_REG(cpu)  (0x2140 + 4 * (cpu))
 #define MVPP2_AGGR_TXQ_DESC_SIZE_MASK  0x3ff0
 #define MVPP2_AGGR_TXQ_STATUS_REG(cpu) (0x2180 + 4 * (cpu))
@@ -4769,6 +4771,8 @@ static int mvpp2_aggr_txq_init(struct platform_device 
*pdev,
   int desc_num, int cpu,
   struct mvpp2 *priv)
 {
+   u32 txq_phys;
+
/* Allocate memory for TX descriptors */
aggr_txq->descs = dma_alloc_coherent(>dev,
desc_num * MVPP2_DESC_ALIGNED_SIZE,
@@ -4782,10 +4786,16 @@ static int mvpp2_aggr_txq_init(struct platform_device 
*pdev,
aggr_txq->next_desc_to_proc = mvpp2_read(priv,
 MVPP2_AGGR_TXQ_INDEX_REG(cpu));
 
-   /* Set Tx descriptors queue starting address */
-   /* indirect access */
-   mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_ADDR_REG(cpu),
-   aggr_txq->descs_phys);
+   /* Set Tx descriptors queue starting address indirect
+* access
+*/
+   if (priv->hw_version == MVPP21)
+   txq_phys = aggr_txq->descs_phys;
+   else
+   txq_phys = aggr_txq->descs_phys >>
+   MVPP22_AGGR_TXQ_DESC_ADDR_OFFS;
+
+   mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_ADDR_REG(cpu), txq_phys);
mvpp2_write(priv, MVPP2_AGGR_TXQ_DESC_SIZE_REG(cpu), desc_num);
 
return 0;
@@ -4796,6 +4806,8 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
  struct mvpp2_rx_queue *rxq)
 
 {
+   u32 rxq_phys;
+
rxq->size = port->rx_ring_size;
 
/* Allocate memory for RX descriptors */
@@ -4812,7 +4824,11 @@ static int mvpp2_rxq_init(struct mvpp2_port *port,
 
/* Set Rx descriptors queue starting address - indirect access */
mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);
-   mvpp2_write(port->priv, MVPP2_RXQ_DESC_ADDR_REG, rxq->descs_phys);
+   if (port->priv->hw_version == MVPP21)
+   rxq_phys = rxq->descs_phys;
+   else
+   rxq_phys = rxq->descs_phys >> MVPP22_DESC_ADDR_OFFS;
+   mvpp2_write(port->priv, MVPP2_RXQ_DESC_ADDR_REG, rxq_phys);
mvpp2_write(port->priv, MVPP2_RXQ_DESC_SIZE_REG, rxq->size);
mvpp2_write(port->priv, MVPP2_RXQ_INDEX_REG, 0);
 
-- 
2.7.4



[PATCH v2 13/16] net: mvpp2: rework RXQ interrupt group initialization for PPv2.2

2016-12-27 Thread Thomas Petazzoni
This commit adjusts how the MVPP2_ISR_RXQ_GROUP_REG register is
configured, since it changed between PPv2.1 and PPv2.2.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 45 
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index d5b197d..baad991 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -188,7 +188,21 @@
 /* Interrupt Cause and Mask registers */
 #define MVPP2_ISR_RX_THRESHOLD_REG(rxq)(0x5200 + 4 * (rxq))
 #define MVPP2_MAX_ISR_RX_THRESHOLD 0xf0
-#define MVPP2_ISR_RXQ_GROUP_REG(rxq)   (0x5400 + 4 * (rxq))
+#define MVPP21_ISR_RXQ_GROUP_REG(rxq)  (0x5400 + 4 * (rxq))
+
+#define MVPP22_ISR_RXQ_GROUP_INDEX_REG  0x5400
+#define MVPP22_ISR_RXQ_GROUP_INDEX_SUBGROUP_MASK 0xf
+#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_MASK   0x380
+#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_OFFSET 7
+
+#define MVPP22_ISR_RXQ_GROUP_INDEX_SUBGROUP_MASK 0xf
+#define MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_MASK   0x380
+
+#define MVPP22_ISR_RXQ_SUB_GROUP_CONFIG_REG 0x5404
+#define MVPP22_ISR_RXQ_SUB_GROUP_STARTQ_MASK0x1f
+#define MVPP22_ISR_RXQ_SUB_GROUP_SIZE_MASK  0xf00
+#define MVPP22_ISR_RXQ_SUB_GROUP_SIZE_OFFSET8
+
 #define MVPP2_ISR_ENABLE_REG(port) (0x5420 + 4 * (port))
 #define MVPP2_ISR_ENABLE_INTERRUPT(mask)   ((mask) & 0x)
 #define MVPP2_ISR_DISABLE_INTERRUPT(mask)  (((mask) << 16) & 0x)
@@ -6385,7 +6399,18 @@ static int mvpp2_port_init(struct mvpp2_port *port)
}
 
/* Configure Rx queue group interrupt for this port */
-   mvpp2_write(priv, MVPP2_ISR_RXQ_GROUP_REG(port->id), rxq_number);
+   if (priv->hw_version == MVPP21)
+   mvpp2_write(priv, MVPP21_ISR_RXQ_GROUP_REG(port->id),
+   rxq_number);
+   else {
+   u32 val;
+
+   val = (port->id << MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_OFFSET);
+   mvpp2_write(priv, MVPP22_ISR_RXQ_GROUP_INDEX_REG, val);
+
+   val = (rxq_number << MVPP22_ISR_RXQ_SUB_GROUP_SIZE_OFFSET);
+   mvpp2_write(priv, MVPP22_ISR_RXQ_SUB_GROUP_CONFIG_REG, val);
+   }
 
/* Create Rx descriptor rings */
for (queue = 0; queue < rxq_number; queue++) {
@@ -6775,8 +6800,20 @@ static int mvpp2_init(struct platform_device *pdev, 
struct mvpp2 *priv)
mvpp2_rx_fifo_init(priv);
 
/* Reset Rx queue group interrupt configuration */
-   for (i = 0; i < MVPP2_MAX_PORTS; i++)
-   mvpp2_write(priv, MVPP2_ISR_RXQ_GROUP_REG(i), rxq_number);
+   for (i = 0; i < MVPP2_MAX_PORTS; i++) {
+   if (priv->hw_version == MVPP21)
+   mvpp2_write(priv, MVPP21_ISR_RXQ_GROUP_REG(i),
+   rxq_number);
+   else {
+   u32 val;
+
+   val = (i << MVPP22_ISR_RXQ_GROUP_INDEX_GROUP_OFFSET);
+   mvpp2_write(priv, MVPP22_ISR_RXQ_GROUP_INDEX_REG, val);
+
+   val = (rxq_number << 
MVPP22_ISR_RXQ_SUB_GROUP_SIZE_OFFSET);
+   mvpp2_write(priv, MVPP22_ISR_RXQ_SUB_GROUP_CONFIG_REG, 
val);
+   }
+   }
 
if (priv->hw_version == MVPP21)
writel(MVPP2_EXT_GLOBAL_CTRL_DEFAULT,
-- 
2.7.4



[PATCH v2 05/16] net: mvpp2: introduce PPv2.2 HW descriptors and adapt accessors

2016-12-27 Thread Thomas Petazzoni
This commit adds the definition of the PPv2.2 HW descriptors, adjusts
the mvpp2_tx_desc and mvpp2_rx_desc structures accordingly, and adapts
the accessors to work on both PPv2.1 and PPv2.2.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 109 +++
 1 file changed, 98 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index a37ff50..0e00ec0 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -773,18 +773,42 @@ struct mvpp21_rx_desc {
u32 reserved8;
 };
 
+/* HW TX descriptor for PPv2.2 */
+struct mvpp22_tx_desc {
+   u32 command;
+   u8  packet_offset;
+   u8  phys_txq;
+   u16 data_size;
+   u64 reserved1;
+   u64 buf_phys_addr_ptp;
+   u64 buf_cookie_misc;
+};
+
+/* HW RX descriptor for PPv2.2 */
+struct mvpp22_rx_desc {
+   u32 status;
+   u16 reserved1;
+   u16 data_size;
+   u32 reserved2;
+   u32 reserved3;
+   u64 buf_phys_addr_key_hash;
+   u64 buf_cookie_misc;
+};
+
 /* Opaque type used by the driver to manipulate the HW TX and RX
  * descriptors
  */
 struct mvpp2_tx_desc {
union {
struct mvpp21_tx_desc pp21;
+   struct mvpp22_tx_desc pp22;
};
 };
 
 struct mvpp2_rx_desc {
union {
struct mvpp21_rx_desc pp21;
+   struct mvpp22_rx_desc pp22;
};
 };
 
@@ -991,72 +1015,135 @@ static u32 mvpp2_read(struct mvpp2 *priv, u32 offset)
 static dma_addr_t mvpp2_txdesc_phys_addr_get(struct mvpp2_port *port,
 struct mvpp2_tx_desc *tx_desc)
 {
-   return tx_desc->pp21.buf_phys_addr;
+   if (port->priv->hw_version == MVPP21)
+   return tx_desc->pp21.buf_phys_addr;
+   else
+   return tx_desc->pp22.buf_phys_addr_ptp & DMA_BIT_MASK(40);
 }
 
 static void mvpp2_txdesc_phys_addr_set(struct mvpp2_port *port,
   struct mvpp2_tx_desc *tx_desc,
   dma_addr_t phys_addr)
 {
-   tx_desc->pp21.buf_phys_addr = phys_addr;
+   if (port->priv->hw_version == MVPP21) {
+   tx_desc->pp21.buf_phys_addr = phys_addr;
+   } else {
+   u64 val = (u64)phys_addr;
+
+   tx_desc->pp22.buf_phys_addr_ptp &= ~DMA_BIT_MASK(40);
+   tx_desc->pp22.buf_phys_addr_ptp |= val;
+   }
 }
 
 static size_t mvpp2_txdesc_size_get(struct mvpp2_port *port,
struct mvpp2_tx_desc *tx_desc)
 {
-   return tx_desc->pp21.data_size;
+   if (port->priv->hw_version == MVPP21)
+   return tx_desc->pp21.data_size;
+   else
+   return tx_desc->pp22.data_size;
 }
 
 static void mvpp2_txdesc_size_set(struct mvpp2_port *port,
  struct mvpp2_tx_desc *tx_desc,
  size_t size)
 {
-   tx_desc->pp21.data_size = size;
+   if (port->priv->hw_version == MVPP21)
+   tx_desc->pp21.data_size = size;
+   else
+   tx_desc->pp22.data_size = size;
 }
 
 static void mvpp2_txdesc_txq_set(struct mvpp2_port *port,
 struct mvpp2_tx_desc *tx_desc,
 unsigned int txq)
 {
-   tx_desc->pp21.phys_txq = txq;
+   if (port->priv->hw_version == MVPP21)
+   tx_desc->pp21.phys_txq = txq;
+   else
+   tx_desc->pp22.phys_txq = txq;
 }
 
 static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port,
 struct mvpp2_tx_desc *tx_desc,
 unsigned int command)
 {
-   tx_desc->pp21.command = command;
+   if (port->priv->hw_version == MVPP21)
+   tx_desc->pp21.command = command;
+   else
+   tx_desc->pp22.command = command;
 }
 
 static void mvpp2_txdesc_offset_set(struct mvpp2_port *port,
struct mvpp2_tx_desc *tx_desc,
unsigned int offset)
 {
-   tx_desc->pp21.packet_offset = offset;
+   if (port->priv->hw_version == MVPP21)
+   tx_desc->pp21.packet_offset = offset;
+   else
+   tx_desc->pp22.packet_offset = offset;
 }
 
 static dma_addr_t mvpp2_rxdesc_phys_addr_get(struct mvpp2_port *port,
 struct mvpp2_rx_desc *rx_desc)
 {
-   return rx_desc->pp21.buf_phys_addr;
+   if (port->priv->hw_version == MVPP21)
+   return rx_desc->pp21.buf_phys_addr;
+   else
+   return rx_desc->pp22.buf_phys_addr_key_hash & DMA_BIT_MASK(40);
 }
 
 static unsigned long mvpp2_rxdesc_virt_addr_get(struct mvpp2_port *port,
struct mvpp2_rx_desc *rx_desc)
 {
-   return 

[PATCH v2 01/16] dt-bindings: net: update Marvell PPv2 binding for PPv2.2 support

2016-12-27 Thread Thomas Petazzoni
The Marvell PPv2 Device Tree binding was so far only used to describe
the PPv2.1 network controller, used in the Marvell Armada 375.

A new version of this IP block, PPv2.2 is used in the Marvell Armada
7K/8K processor. This commit extends the existing binding so that it can
also be used to describe PPv2.2 hardware.

Signed-off-by: Thomas Petazzoni 
---
 .../devicetree/bindings/net/marvell-pp2.txt| 66 ++
 1 file changed, 55 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/marvell-pp2.txt 
b/Documentation/devicetree/bindings/net/marvell-pp2.txt
index aa4f423..76071f3 100644
--- a/Documentation/devicetree/bindings/net/marvell-pp2.txt
+++ b/Documentation/devicetree/bindings/net/marvell-pp2.txt
@@ -1,17 +1,28 @@
-* Marvell Armada 375 Ethernet Controller (PPv2)
+* Marvell Armada 375 Ethernet Controller (PPv2.1)
+  Marvell Armada 7K/8K Ethernet Controller (PPv2.2)
 
 Required properties:
 
-- compatible: should be "marvell,armada-375-pp2"
+- compatible: should be one of:
+"marvell,armada-375-pp2"
+"marvell,armada-7k-pp2"
 - reg: addresses and length of the register sets for the device.
-  Must contain the following register sets:
+  For "marvell,armada-375-pp2", must contain the following register
+  sets:
- common controller registers
- LMS registers
-  In addition, at least one port register set is required.
-- clocks: a pointer to the reference clocks for this device, consequently:
-   - main controller clock
-   - GOP clock
-- clock-names: names of used clocks, must be "pp_clk" and "gop_clk".
+   - one register area per Ethernet port
+  For "marvell,armda-7k-pp2", must contain the following register
+  sets:
+- common controller registers
+   - per-port registers
+
+- clocks: pointers to the reference clocks for this device, consequently:
+   - main controller clock (for both armada-375-pp2 and armada-7k-pp2)
+   - GOP clock (for both armada-375-pp2 and armada-7k-pp2)
+   - MG clock (only for armada-7k-pp2)
+- clock-names: names of used clocks, must be "pp_clk", "gop_clk" and
+  "mg_clk" (the latter only for armada-7k-pp2).
 
 The ethernet ports are represented by subnodes. At least one port is
 required.
@@ -19,8 +30,9 @@ required.
 Required properties (port):
 
 - interrupts: interrupt for the port
-- port-id: should be '0' or '1' for ethernet ports, and '2' for the
-   loopback port
+- port-id: ID of the port from the MAC point of view
+- gop-port-id: only for marvell,armada-7k-pp2, ID of the port from the
+  GOP (Group Of Ports) point of view
 - phy-mode: See ethernet.txt file in the same directory
 
 Optional properties (port):
@@ -31,7 +43,7 @@ Optional properties (port):
   then fixed link is assumed, and the 'fixed-link' property is
   mandatory.
 
-Example:
+Example for marvell,armada-375-pp2:
 
 ethernet@f {
compatible = "marvell,armada-375-pp2";
@@ -59,3 +71,35 @@ ethernet@f {
phy-mode = "gmii";
};
 };
+
+Example for marvell,armada-7k-pp2:
+
+cpm_ethernet: ethernet@0 {
+   compatible = "marvell,armada-7k-pp22";
+   reg = <0x0 0x10>,
+ <0x10 0x8>;
+   clocks = <_syscon0 1 3>, <_syscon0 1 9>, <_syscon0 1 5>;
+   clock-names = "pp_clk", "gop_clk", "gp_clk";
+   status = "disabled";
+
+   eth0: eth@0 {
+   interrupts = ;
+   port-id = <0>;
+   gop-port-id = <0>;
+   status = "disabled";
+   };
+
+   eth1: eth@1 {
+   interrupts = ;
+   port-id = <1>;
+   gop-port-id = <2>;
+   status = "disabled";
+   };
+
+   eth2: eth@2 {
+   interrupts = ;
+   port-id = <2>;
+   gop-port-id = <3>;
+   status = "disabled";
+   };
+};
-- 
2.7.4



[PATCH v2 16/16] net: mvpp2: finally add the PPv2.2 compatible string

2016-12-27 Thread Thomas Petazzoni
Now that the mvpp2 driver has been modified to accommodate the support
for PPv2.2, we can finally advertise this support by adding the
appropriate compatible string.

At the same time, we update the Kconfig description of the MVPP2 driver.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/Kconfig | 4 ++--
 drivers/net/ethernet/marvell/mvpp2.c | 4 
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/marvell/Kconfig 
b/drivers/net/ethernet/marvell/Kconfig
index d2555e8b..da6fb82 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -82,13 +82,13 @@ config MVNETA_BM
  that all dependencies are met.
 
 config MVPP2
-   tristate "Marvell Armada 375 network interface support"
+   tristate "Marvell Armada 375/7K/8K network interface support"
depends on ARCH_MVEBU || COMPILE_TEST
depends on HAS_DMA
select MVMDIO
---help---
  This driver supports the network interface units in the
- Marvell ARMADA 375 SoC.
+ Marvell ARMADA 375, 7K and 8K SoCs.
 
 config PXA168_ETH
tristate "Marvell pxa168 ethernet support"
diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 194de00..9e744d2 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -6997,6 +6997,10 @@ static const struct of_device_id mvpp2_match[] = {
.compatible = "marvell,armada-375-pp2",
.data = (void *)MVPP21,
},
+   {
+   .compatible = "marvell,armada-7k-pp22",
+   .data = (void *)MVPP22,
+   },
{ }
 };
 MODULE_DEVICE_TABLE(of, mvpp2_match);
-- 
2.7.4



[PATCH v2 07/16] net: mvpp2: adapt the mvpp2_rxq_*_pool_set functions to PPv2.2

2016-12-27 Thread Thomas Petazzoni
The MVPP2_RXQ_CONFIG_REG register has a slightly different layout
between PPv2.1 and PPv2.2, so this commit adapts the functions modifying
this register to accommodate for both the PPv2.1 and PPv2.2 cases.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 32 
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 160b787..8fc818d 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -50,9 +50,11 @@
 #define MVPP2_SNOOP_PKT_SIZE_MASK  0x1ff
 #define MVPP2_SNOOP_BUF_HDR_MASK   BIT(9)
 #define MVPP2_RXQ_POOL_SHORT_OFFS  20
-#define MVPP2_RXQ_POOL_SHORT_MASK  0x70
+#define MVPP21_RXQ_POOL_SHORT_MASK 0x70
+#define MVPP22_RXQ_POOL_SHORT_MASK 0xf0
 #define MVPP2_RXQ_POOL_LONG_OFFS   24
-#define MVPP2_RXQ_POOL_LONG_MASK   0x700
+#define MVPP21_RXQ_POOL_LONG_MASK  0x700
+#define MVPP22_RXQ_POOL_LONG_MASK  0xf00
 #define MVPP2_RXQ_PACKET_OFFSET_OFFS   28
 #define MVPP2_RXQ_PACKET_OFFSET_MASK   0x7000
 #define MVPP2_RXQ_DISABLE_MASK BIT(31)
@@ -3762,17 +3764,20 @@ static int mvpp2_bm_init(struct platform_device *pdev, 
struct mvpp2 *priv)
 static void mvpp2_rxq_long_pool_set(struct mvpp2_port *port,
int lrxq, int long_pool)
 {
-   u32 val;
+   u32 val, mask;
int prxq;
 
/* Get queue physical ID */
prxq = port->rxqs[lrxq]->id;
 
-   val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
-   val &= ~MVPP2_RXQ_POOL_LONG_MASK;
-   val |= ((long_pool << MVPP2_RXQ_POOL_LONG_OFFS) &
-   MVPP2_RXQ_POOL_LONG_MASK);
+   if (port->priv->hw_version == MVPP21)
+   mask = MVPP21_RXQ_POOL_LONG_MASK;
+   else
+   mask = MVPP22_RXQ_POOL_LONG_MASK;
 
+   val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
+   val &= ~mask;
+   val |= (long_pool << MVPP2_RXQ_POOL_LONG_OFFS) & mask;
mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
 }
 
@@ -3780,17 +3785,20 @@ static void mvpp2_rxq_long_pool_set(struct mvpp2_port 
*port,
 static void mvpp2_rxq_short_pool_set(struct mvpp2_port *port,
 int lrxq, int short_pool)
 {
-   u32 val;
+   u32 val, mask;
int prxq;
 
/* Get queue physical ID */
prxq = port->rxqs[lrxq]->id;
 
-   val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
-   val &= ~MVPP2_RXQ_POOL_SHORT_MASK;
-   val |= ((short_pool << MVPP2_RXQ_POOL_SHORT_OFFS) &
-   MVPP2_RXQ_POOL_SHORT_MASK);
+   if (port->priv->hw_version == MVPP21)
+   mask = MVPP21_RXQ_POOL_SHORT_MASK;
+   else
+   mask = MVPP22_RXQ_POOL_SHORT_MASK;
 
+   val = mvpp2_read(port->priv, MVPP2_RXQ_CONFIG_REG(prxq));
+   val &= ~mask;
+   val |= (short_pool << MVPP2_RXQ_POOL_SHORT_OFFS) & mask;
mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
 }
 
-- 
2.7.4



[PATCH v2 15/16] net: mvpp2: add support for an additional clock needed for PPv2.2

2016-12-27 Thread Thomas Petazzoni
The PPv2.2 variant of the network controller needs an additional
clock, the "MG clock" in order for the IP block to operate
properly. This commit adds support for this additional clock to the
driver, reworking as needed the error handling path.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 25 +
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 20e9429..194de00 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -702,6 +702,7 @@ struct mvpp2 {
/* Common clocks */
struct clk *pp_clk;
struct clk *gop_clk;
+   struct clk *mg_clk;
 
/* List of pointers to port structures */
struct mvpp2_port **port_list;
@@ -6899,6 +6900,18 @@ static int mvpp2_probe(struct platform_device *pdev)
if (err < 0)
goto err_pp_clk;
 
+   if (priv->hw_version == MVPP22) {
+   priv->mg_clk = devm_clk_get(>dev, "mg_clk");
+   if (IS_ERR(priv->mg_clk)) {
+   err = PTR_ERR(priv->mg_clk);
+   goto err_gop_clk;
+   }
+
+   err = clk_prepare_enable(priv->mg_clk);
+   if (err < 0)
+   goto err_gop_clk;
+   }
+
/* Get system's tclk rate */
priv->tclk = clk_get_rate(priv->pp_clk);
 
@@ -6906,14 +6919,14 @@ static int mvpp2_probe(struct platform_device *pdev)
err = mvpp2_init(pdev, priv);
if (err < 0) {
dev_err(>dev, "failed to initialize controller\n");
-   goto err_gop_clk;
+   goto err_mg_clk;
}
 
port_count = of_get_available_child_count(dn);
if (port_count == 0) {
dev_err(>dev, "no ports enabled\n");
err = -ENODEV;
-   goto err_gop_clk;
+   goto err_mg_clk;
}
 
priv->port_list = devm_kcalloc(>dev, port_count,
@@ -6921,19 +6934,22 @@ static int mvpp2_probe(struct platform_device *pdev)
  GFP_KERNEL);
if (!priv->port_list) {
err = -ENOMEM;
-   goto err_gop_clk;
+   goto err_mg_clk;
}
 
/* Initialize ports */
for_each_available_child_of_node(dn, port_node) {
err = mvpp2_port_probe(pdev, port_node, priv);
if (err < 0)
-   goto err_gop_clk;
+   goto err_mg_clk;
}
 
platform_set_drvdata(pdev, priv);
return 0;
 
+err_mg_clk:
+   if (priv->hw_version == MVPP22)
+   clk_disable_unprepare(priv->mg_clk);
 err_gop_clk:
clk_disable_unprepare(priv->gop_clk);
 err_pp_clk:
@@ -6969,6 +6985,7 @@ static int mvpp2_remove(struct platform_device *pdev)
  aggr_txq->descs_phys);
}
 
+   clk_disable_unprepare(priv->mg_clk);
clk_disable_unprepare(priv->pp_clk);
clk_disable_unprepare(priv->gop_clk);
 
-- 
2.7.4



[PATCH v2 06/11] net: mvpp2: simplify mvpp2_bm_bufs_add()

2016-12-27 Thread Thomas Petazzoni
The mvpp2_bm_bufs_add() currently creates a fake cookie by calling
mvpp2_bm_cookie_pool_set(), just to be able to call
mvpp2_pool_refill(). But all what mvpp2_pool_refill() does is extract
the pool ID from the cookie, and call mvpp2_bm_pool_put() with this ID.

Instead of doing this convoluted thing, just call mvpp2_bm_pool_put()
directly, since we have the BM pool ID.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index bfa9f77..8174f40 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -3626,7 +3626,6 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
 {
struct sk_buff *skb;
int i, buf_size, total_size;
-   u32 bm;
dma_addr_t phys_addr;
 
buf_size = MVPP2_RX_BUF_SIZE(bm_pool->pkt_size);
@@ -3640,13 +3639,12 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
return 0;
}
 
-   bm = mvpp2_bm_cookie_pool_set(0, bm_pool->id);
for (i = 0; i < buf_num; i++) {
skb = mvpp2_skb_alloc(port, bm_pool, _addr, GFP_KERNEL);
if (!skb)
break;
 
-   mvpp2_pool_refill(port, bm, (u32)phys_addr, (u32)skb);
+   mvpp2_bm_pool_put(port, bm_pool->id, (u32)phys_addr, (u32)skb);
}
 
/* Update BM driver with number of buffers added to pool */
-- 
2.7.4



[PATCH v2 11/16] net: mvpp2: handle misc PPv2.1/PPv2.2 differences

2016-12-27 Thread Thomas Petazzoni
This commit handles a few miscellaneous differences between PPv2.1 and
PPv2.2 in different areas, where code done for PPv2.1 doesn't apply for
PPv2.2 or needs to be adjusted (getting the MAC address, disabling PHY
polling, etc.).

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 31 ++-
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 389cc62..eb55576 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -304,6 +304,9 @@
 #define  MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(v) (((v) << 6) & \
MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK)
 
+#define MVPP22_SMI_MISC_CFG_REG0x2a204
+#define  MVPP22_SMI_POLLING_EN BIT(10)
+
 #define MVPP22_PORT_BASE   0x30e00
 #define MVPP22_PORT_OFFSET 0x1000
 
@@ -5823,7 +5826,7 @@ static int mvpp2_check_ringparam_valid(struct net_device 
*dev,
return 0;
 }
 
-static void mvpp2_get_mac_address(struct mvpp2_port *port, unsigned char *addr)
+static void mvpp21_get_mac_address(struct mvpp2_port *port, unsigned char 
*addr)
 {
u32 mac_addr_l, mac_addr_m, mac_addr_h;
 
@@ -6272,7 +6275,7 @@ static const struct ethtool_ops mvpp2_eth_tool_ops = {
 
 /* Driver initialization */
 
-static void mvpp2_port_power_up(struct mvpp2_port *port)
+static void mvpp21_port_power_up(struct mvpp2_port *port)
 {
mvpp2_port_mii_set(port);
mvpp2_port_periodic_xon_disable(port);
@@ -6491,7 +6494,8 @@ static int mvpp2_port_probe(struct platform_device *pdev,
mac_from = "device tree";
ether_addr_copy(dev->dev_addr, dt_mac_addr);
} else {
-   mvpp2_get_mac_address(port, hw_mac_addr);
+   if (priv->hw_version == MVPP21)
+   mvpp21_get_mac_address(port, hw_mac_addr);
if (is_valid_ether_addr(hw_mac_addr)) {
mac_from = "hardware";
ether_addr_copy(dev->dev_addr, hw_mac_addr);
@@ -6511,7 +6515,9 @@ static int mvpp2_port_probe(struct platform_device *pdev,
dev_err(>dev, "failed to init port %d\n", id);
goto err_free_stats;
}
-   mvpp2_port_power_up(port);
+
+   if (priv->hw_version == MVPP21)
+   mvpp21_port_power_up(port);
 
port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
if (!port->pcpu) {
@@ -6654,9 +6660,15 @@ static int mvpp2_init(struct platform_device *pdev, 
struct mvpp2 *priv)
mvpp2_conf_mbus_windows(dram_target_info, priv);
 
/* Disable HW PHY polling */
-   val = readl(priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
-   val |= MVPP2_PHY_AN_STOP_SMI0_MASK;
-   writel(val, priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
+   if (priv->hw_version == MVPP21) {
+   val = readl(priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
+   val |= MVPP2_PHY_AN_STOP_SMI0_MASK;
+   writel(val, priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
+   } else {
+   val = readl(priv->iface_base + MVPP22_SMI_MISC_CFG_REG);
+   val &= ~MVPP22_SMI_POLLING_EN;
+   writel(val, priv->iface_base + MVPP22_SMI_MISC_CFG_REG);
+   }
 
/* Allocate and initialize aggregated TXQs */
priv->aggr_txqs = devm_kcalloc(>dev, num_present_cpus(),
@@ -6681,8 +6693,9 @@ static int mvpp2_init(struct platform_device *pdev, 
struct mvpp2 *priv)
for (i = 0; i < MVPP2_MAX_PORTS; i++)
mvpp2_write(priv, MVPP2_ISR_RXQ_GROUP_REG(i), rxq_number);
 
-   writel(MVPP2_EXT_GLOBAL_CTRL_DEFAULT,
-  priv->lms_base + MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG);
+   if (priv->hw_version == MVPP21)
+   writel(MVPP2_EXT_GLOBAL_CTRL_DEFAULT,
+  priv->lms_base + MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG);
 
/* Allow cache snoop when transmiting packets */
mvpp2_write(priv, MVPP2_TX_SNOOP_REG, 0x1);
-- 
2.7.4



[PATCH v2 05/11] net: mvpp2: drop useless fields in mvpp2_bm_pool and related code

2016-12-27 Thread Thomas Petazzoni
This commit drops dead code from the mvpp2 driver. The 'in_use' and
'in_use_thresh' fields of 'struct mvpp2_bm_pool' are
incremented/decremented/initialized in various places. But they are only
used in one place:

   if (is_recycle &&
   (atomic_read(_pool->in_use) < bm_pool->in_use_thresh))
   return 0;

However 'is_recycle', passed as argument to mvpp2_rx_refill() is always
false. So in fact, this code is never reached, and the 'is_recycle'
argument is useless. So let's drop this code.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 18 +++---
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 6720cdac..bfa9f77 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -930,10 +930,6 @@ struct mvpp2_bm_pool {
 
/* Ports using BM pool */
u32 port_map;
-
-   /* Occupied buffers indicator */
-   atomic_t in_use;
-   int in_use_thresh;
 };
 
 struct mvpp2_buff_hdr {
@@ -3399,7 +3395,6 @@ static int mvpp2_bm_pool_create(struct platform_device 
*pdev,
bm_pool->size = size;
bm_pool->pkt_size = 0;
bm_pool->buf_num = 0;
-   atomic_set(_pool->in_use, 0);
 
return 0;
 }
@@ -3656,7 +3651,6 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
 
/* Update BM driver with number of buffers added to pool */
bm_pool->buf_num += i;
-   bm_pool->in_use_thresh = bm_pool->buf_num / 4;
 
netdev_dbg(port->dev,
   "%s pool %d: pkt_size=%4d, buf_size=%4d, total_size=%4d\n",
@@ -4997,23 +4991,18 @@ static void mvpp2_rx_csum(struct mvpp2_port *port, u32 
status,
 
 /* Reuse skb if possible, or allocate a new skb and add it to BM pool */
 static int mvpp2_rx_refill(struct mvpp2_port *port,
-  struct mvpp2_bm_pool *bm_pool,
-  u32 bm, int is_recycle)
+  struct mvpp2_bm_pool *bm_pool, u32 bm)
 {
struct sk_buff *skb;
dma_addr_t phys_addr;
 
-   if (is_recycle &&
-   (atomic_read(_pool->in_use) < bm_pool->in_use_thresh))
-   return 0;
-
/* No recycle or too many buffers are in use, so allocate a new skb */
skb = mvpp2_skb_alloc(port, bm_pool, _addr, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
 
mvpp2_pool_refill(port, bm, (u32)phys_addr, (u32)skb);
-   atomic_dec(_pool->in_use);
+
return 0;
 }
 
@@ -5139,7 +5128,7 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
 
skb = (struct sk_buff *)rx_desc->buf_cookie;
 
-   err = mvpp2_rx_refill(port, bm_pool, bm, 0);
+   err = mvpp2_rx_refill(port, bm_pool, bm);
if (err) {
netdev_err(port->dev, "failed to refill BM pools\n");
goto err_drop_frame;
@@ -5150,7 +5139,6 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo,
 
rcvd_pkts++;
rcvd_bytes += rx_bytes;
-   atomic_inc(_pool->in_use);
 
skb_reserve(skb, MVPP2_MH_SIZE);
skb_put(skb, rx_bytes);
-- 
2.7.4



[PATCH v2 10/11] net: mvpp2: switch to build_skb() in the RX path

2016-12-27 Thread Thomas Petazzoni
This commit adapts the mvpp2 RX path to use the build_skb() method. Not
only build_skb() is now the recommended mechanism, but it also
simplifies the addition of support for the PPv2.2 variant.

Indeed, without build_skb(), we have to keep track for each RX
descriptor of the physical address of the packet buffer, and the virtual
address of the SKB. However, in PPv2.2 running on 64 bits platform,
there is not enough space in the descriptor to store the virtual address
of the SKB. So having to take care only of the address of the packet
buffer, and building the SKB upon reception helps in supporting PPv2.2.

The implementation is fairly straightforward:

 - mvpp2_skb_alloc() is renamed to mvpp2_buf_alloc() and no longer
   allocates a SKB. Instead, it allocates a buffer using the new
   mvpp2_frag_alloc() function, with enough space for the data and SKB.

 - The initialization of the RX buffers in mvpp2_bm_bufs_add() as well
   as the refill of the RX buffers in mvpp2_rx_refill() is adjusted
   accordingly.

 - Finally, the mvpp2_rx() is modified to use build_skb().

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 77 +---
 1 file changed, 55 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 58cf9af..1e08e8f 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -918,6 +918,7 @@ struct mvpp2_bm_pool {
int buf_size;
/* Packet size */
int pkt_size;
+   int frag_size;
 
/* BPPE virtual base address */
u32 *virt_addr;
@@ -3354,6 +3355,22 @@ static void mvpp2_cls_oversize_rxq_set(struct mvpp2_port 
*port)
mvpp2_write(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG, val);
 }
 
+static void *mvpp2_frag_alloc(const struct mvpp2_bm_pool *pool)
+{
+   if (likely(pool->frag_size <= PAGE_SIZE))
+   return netdev_alloc_frag(pool->frag_size);
+   else
+   return kmalloc(pool->frag_size, GFP_ATOMIC);
+}
+
+static void mvpp2_frag_free(const struct mvpp2_bm_pool *pool, void *data)
+{
+   if (likely(pool->frag_size <= PAGE_SIZE))
+   skb_free_frag(data);
+   else
+   kfree(data);
+}
+
 /* Buffer Manager configuration routines */
 
 /* Create pool */
@@ -3428,7 +3445,8 @@ static void mvpp2_bm_bufs_free(struct device *dev, struct 
mvpp2 *priv,
 
if (!vaddr)
break;
-   dev_kfree_skb_any((struct sk_buff *)vaddr);
+
+   mvpp2_frag_free(bm_pool, (void *)vaddr);
}
 
/* Update BM driver with number of buffers removed from pool */
@@ -3542,29 +3560,28 @@ static void mvpp2_rxq_short_pool_set(struct mvpp2_port 
*port,
mvpp2_write(port->priv, MVPP2_RXQ_CONFIG_REG(prxq), val);
 }
 
-/* Allocate skb for BM pool */
-static struct sk_buff *mvpp2_skb_alloc(struct mvpp2_port *port,
-  struct mvpp2_bm_pool *bm_pool,
-  dma_addr_t *buf_phys_addr,
-  gfp_t gfp_mask)
+static void *mvpp2_buf_alloc(struct mvpp2_port *port,
+struct mvpp2_bm_pool *bm_pool,
+dma_addr_t *buf_phys_addr,
+gfp_t gfp_mask)
 {
-   struct sk_buff *skb;
dma_addr_t phys_addr;
+   void *data;
 
-   skb = __dev_alloc_skb(bm_pool->pkt_size, gfp_mask);
-   if (!skb)
+   data = mvpp2_frag_alloc(bm_pool);
+   if (!data)
return NULL;
 
-   phys_addr = dma_map_single(port->dev->dev.parent, skb->head,
+   phys_addr = dma_map_single(port->dev->dev.parent, data,
   MVPP2_RX_BUF_SIZE(bm_pool->pkt_size),
DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(port->dev->dev.parent, phys_addr))) {
-   dev_kfree_skb_any(skb);
+   mvpp2_frag_free(bm_pool, data);
return NULL;
}
*buf_phys_addr = phys_addr;
 
-   return skb;
+   return data;
 }
 
 /* Set pool number in a BM cookie */
@@ -3620,9 +3637,9 @@ static void mvpp2_pool_refill(struct mvpp2_port *port, 
u32 bm,
 static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
 struct mvpp2_bm_pool *bm_pool, int buf_num)
 {
-   struct sk_buff *skb;
int i, buf_size, total_size;
dma_addr_t phys_addr;
+   void *buf;
 
buf_size = MVPP2_RX_BUF_SIZE(bm_pool->pkt_size);
total_size = MVPP2_RX_TOTAL_SIZE(buf_size);
@@ -3636,11 +3653,11 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
}
 
for (i = 0; i < buf_num; i++) {
-   skb = mvpp2_skb_alloc(port, bm_pool, _addr, GFP_KERNEL);
-   if (!skb)
+   buf = mvpp2_buf_alloc(port, bm_pool, _addr, GFP_KERNEL);
+ 

[PATCH v2 02/11] net: mvpp2: handle too large value in mvpp2_rx_time_coal_set()

2016-12-27 Thread Thomas Petazzoni
When configuring the MVPP2_ISR_RX_THRESHOLD_REG with the RX coalescing
time threshold, we do not check for the maximum allowed value supported
by the driver, which means we might overflow and use a bogus value. This
commit adds a check for this situation, and if a value higher than what
is supported by the hardware is provided, then we use the maximum value
supported by the hardware.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 02d91e4..a1ba89f 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -154,6 +154,7 @@
 
 /* Interrupt Cause and Mask registers */
 #define MVPP2_ISR_RX_THRESHOLD_REG(rxq)(0x5200 + 4 * (rxq))
+#define MVPP2_MAX_ISR_RX_THRESHOLD 0xf0
 #define MVPP2_ISR_RXQ_GROUP_REG(rxq)   (0x5400 + 4 * (rxq))
 #define MVPP2_ISR_ENABLE_REG(port) (0x5420 + 4 * (port))
 #define MVPP2_ISR_ENABLE_INTERRUPT(mask)   ((mask) & 0x)
@@ -4397,6 +4398,12 @@ static void mvpp2_rx_time_coal_set(struct mvpp2_port 
*port,
u32 val;
 
val = (port->priv->tclk / USEC_PER_SEC) * usec;
+
+   if (val > MVPP2_MAX_ISR_RX_THRESHOLD) {
+   val = MVPP2_MAX_ISR_RX_THRESHOLD;
+   usec = (val * USEC_PER_SEC) / port->priv->tclk;
+   }
+
mvpp2_write(port->priv, MVPP2_ISR_RX_THRESHOLD_REG(rxq->id), val);
 
rxq->time_coal = usec;
-- 
2.7.4



[PATCH v2 03/16] net: mvpp2: add hw_version field in "struct mvpp2"

2016-12-27 Thread Thomas Petazzoni
In preparation to the introduction for the support of PPv2.2 in the
mvpp2 driver, this commit adds a hw_version field to the struct
mvpp2, and uses the .data field of the DT match table to fill it in.

Having the MVPP21 and MVPP22 definitions available will allow to start
adding the necessary conditional code to support PPv2.2.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index fd84923..bc359a9 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -649,6 +650,9 @@ struct mvpp2 {
 
/* Tclk value */
u32 tclk;
+
+   /* HW version */
+   enum { MVPP21, MVPP22 } hw_version;
 };
 
 struct mvpp2_pcpu_stats {
@@ -6480,6 +6484,9 @@ static int mvpp2_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
 
+   priv->hw_version =
+   (unsigned long)of_device_get_match_data(>dev);
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(>dev, res);
if (IS_ERR(priv->base))
@@ -6584,7 +6591,10 @@ static int mvpp2_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id mvpp2_match[] = {
-   { .compatible = "marvell,armada-375-pp2" },
+   {
+   .compatible = "marvell,armada-375-pp2",
+   .data = (void *)MVPP21,
+   },
{ }
 };
 MODULE_DEVICE_TABLE(of, mvpp2_match);
-- 
2.7.4



[PATCH v2 00/16] net: mvpp2: add basic support for PPv2.2

2016-12-27 Thread Thomas Petazzoni
Hello,

The goal of this patch series is to add basic support for PPv2.2 in
the existing mvpp2 driver. mvpp2 currently supported the PPv2.1
version of the IP, used in the 32 bits Marvell Armada 375 SoC. PPv2.2
is an evolution of this IP block, used in the 64 bits Marvell Armada
7K/8K SoCs.

In order to ease the review, the introduction of PPv2.2 support has
been made into multiple small commits, with the final commit adding
the compatible string that makes the PPv2.2 support actually
usable. The series remain fully bisectable.

This series depends on the series named "net: mvpp2: misc improvements
and preparation patches".

I'd like to thank Stefan Chulski and Marcin Wojtas, who helped me a
lot in the development of this patch series, by reviewing the patches,
and giving lots of useful hints to debug the driver on PPv2.2. Thanks!

Changes since v1:

 - Made a separate series from the set of patches doing preparation
   changes/fixes to the mvpp2 driver.

 - Rebased on top of v4.10-rc1.

 - Update Kconfig text of the mvpp2 driver to mention the support for
   Armada 7K and 8K (PPv2.2).

Best regards,

Thomas

Thomas Petazzoni (16):
  dt-bindings: net: update Marvell PPv2 binding for PPv2.2 support
  net: mvpp2: add and use accessors for TX/RX descriptors
  net: mvpp2: add hw_version field in "struct mvpp2"
  net: mvpp2: introduce an intermediate union for the TX/RX descriptors
  net: mvpp2: introduce PPv2.2 HW descriptors and adapt accessors
  net: mvpp2: adjust the allocation/free of BM pools for PPv2.2
  net: mvpp2: adapt the mvpp2_rxq_*_pool_set functions to PPv2.2
  net: mvpp2: adapt mvpp2_defaults_set() to PPv2.2
  net: mvpp2: adjust mvpp2_{rxq,txq}_init for PPv2.2
  net: mvpp2: handle register mapping and access for PPv2.2
  net: mvpp2: handle misc PPv2.1/PPv2.2 differences
  net: mvpp2: add AXI bridge initialization for PPv2.2
  net: mvpp2: rework RXQ interrupt group initialization for PPv2.2
  net: mvpp2: adapt rxq distribution to PPv2.2
  net: mvpp2: add support for an additional clock needed for PPv2.2
  net: mvpp2: finally add the PPv2.2 compatible string

 .../devicetree/bindings/net/marvell-pp2.txt|  66 +-
 drivers/net/ethernet/marvell/Kconfig   |   4 +-
 drivers/net/ethernet/marvell/mvpp2.c   | 783 +
 3 files changed, 700 insertions(+), 153 deletions(-)

-- 
2.7.4



[PATCH v2 11/11] net: mvpp2: enable building on 64-bit platforms

2016-12-27 Thread Thomas Petazzoni
The mvpp2 is going to be extended to support the Marvell Armada 7K/8K
platform, which is ARM64. As a preparation to this work, this commit
enables building the mvpp2 driver on ARM64, by:

 - Adjusting the Kconfig dependency

 - Fixing the types used in the driver so that they are 32/64-bits
   compliant. We use dma_addr_t for DMA addresses, and unsigned long
   for virtual addresses.

It is worth mentioning that after this commit, the driver is for now
still only used on 32-bits platforms.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/Kconfig |  3 +--
 drivers/net/ethernet/marvell/mvpp2.c | 29 +
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/marvell/Kconfig 
b/drivers/net/ethernet/marvell/Kconfig
index f4b7cf1..d2555e8b 100644
--- a/drivers/net/ethernet/marvell/Kconfig
+++ b/drivers/net/ethernet/marvell/Kconfig
@@ -83,9 +83,8 @@ config MVNETA_BM
 
 config MVPP2
tristate "Marvell Armada 375 network interface support"
-   depends on MACH_ARMADA_375 || COMPILE_TEST
+   depends on ARCH_MVEBU || COMPILE_TEST
depends on HAS_DMA
-   depends on !64BIT
select MVMDIO
---help---
  This driver supports the network interface units in the
diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 1e08e8f..2268808 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -3388,7 +3388,8 @@ static int mvpp2_bm_pool_create(struct platform_device 
*pdev,
if (!bm_pool->virt_addr)
return -ENOMEM;
 
-   if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVPP2_BM_POOL_PTR_ALIGN)) {
+   if (!IS_ALIGNED((unsigned long)bm_pool->virt_addr,
+   MVPP2_BM_POOL_PTR_ALIGN)) {
dma_free_coherent(>dev, size_bytes, bm_pool->virt_addr,
  bm_pool->phys_addr);
dev_err(>dev, "BM pool %d is not %d bytes aligned\n",
@@ -3433,7 +3434,7 @@ static void mvpp2_bm_bufs_free(struct device *dev, struct 
mvpp2 *priv,
 
for (i = 0; i < bm_pool->buf_num; i++) {
dma_addr_t buf_phys_addr;
-   u32 vaddr;
+   unsigned long vaddr;
 
/* Get buffer virtual address (indirect access) */
buf_phys_addr = mvpp2_read(priv,
@@ -3596,14 +3597,15 @@ static inline u32 mvpp2_bm_cookie_pool_set(u32 cookie, 
int pool)
 }
 
 /* Get pool number from a BM cookie */
-static inline int mvpp2_bm_cookie_pool_get(u32 cookie)
+static inline int mvpp2_bm_cookie_pool_get(unsigned long cookie)
 {
return (cookie >> MVPP2_BM_COOKIE_POOL_OFFS) & 0xFF;
 }
 
 /* Release buffer to BM */
 static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
-u32 buf_phys_addr, u32 buf_virt_addr)
+dma_addr_t buf_phys_addr,
+unsigned long buf_virt_addr)
 {
mvpp2_write(port->priv, MVPP2_BM_VIRT_RLS_REG, buf_virt_addr);
mvpp2_write(port->priv, MVPP2_BM_PHY_RLS_REG(pool), buf_phys_addr);
@@ -3611,7 +3613,8 @@ static inline void mvpp2_bm_pool_put(struct mvpp2_port 
*port, int pool,
 
 /* Release multicast buffer */
 static void mvpp2_bm_pool_mc_put(struct mvpp2_port *port, int pool,
-u32 buf_phys_addr, u32 buf_virt_addr,
+dma_addr_t buf_phys_addr,
+unsigned long buf_virt_addr,
 int mc_id)
 {
u32 val = 0;
@@ -3626,7 +3629,8 @@ static void mvpp2_bm_pool_mc_put(struct mvpp2_port *port, 
int pool,
 
 /* Refill BM pool */
 static void mvpp2_pool_refill(struct mvpp2_port *port, u32 bm,
- u32 phys_addr, u32 cookie)
+ dma_addr_t phys_addr,
+ unsigned long cookie)
 {
int pool = mvpp2_bm_cookie_pool_get(bm);
 
@@ -3657,7 +3661,8 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port,
if (!buf)
break;
 
-   mvpp2_bm_pool_put(port, bm_pool->id, (u32)phys_addr, (u32)buf);
+   mvpp2_bm_pool_put(port, bm_pool->id, phys_addr,
+ (unsigned long)buf);
}
 
/* Update BM driver with number of buffers added to pool */
@@ -5015,7 +5020,7 @@ static int mvpp2_rx_refill(struct mvpp2_port *port,
if (!buf)
return -ENOMEM;
 
-   mvpp2_pool_refill(port, bm, (u32)phys_addr, (u32)buf);
+   mvpp2_pool_refill(port, bm, phys_addr, (unsigned long)buf);
 
return 0;
 }
@@ -5057,10 +5062,10 @@ static void mvpp2_buff_hdr_rx(struct mvpp2_port *port,
struct mvpp2_buff_hdr *buff_hdr;
struct sk_buff *skb;
u32 rx_status = rx_desc->status;
-   u32 buff_phys_addr;
-   u32 

[PATCH v2 01/11] net: mvpp2: handle too large value handling in mvpp2_rx_pkts_coal_set()

2016-12-27 Thread Thomas Petazzoni
Currently, mvpp2_rx_pkts_coal_set() does the following to avoid setting
a too large value for the RX coalescing by packet number:

  val = (pkts & MVPP2_OCCUPIED_THRESH_MASK);

This means that if you set a value that is slightly higher the the
maximum number of packets, you in fact get a very low value. It makes a
lot more sense to simply check if the value is too high, and if it's too
high, limit it to the maximum possible value.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 4fe430c..02d91e4 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -4381,11 +4381,11 @@ static void mvpp2_txp_max_tx_size_set(struct mvpp2_port 
*port)
 static void mvpp2_rx_pkts_coal_set(struct mvpp2_port *port,
   struct mvpp2_rx_queue *rxq, u32 pkts)
 {
-   u32 val;
+   if (pkts > MVPP2_OCCUPIED_THRESH_MASK)
+   pkts = MVPP2_OCCUPIED_THRESH_MASK;
 
-   val = (pkts & MVPP2_OCCUPIED_THRESH_MASK);
mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);
-   mvpp2_write(port->priv, MVPP2_RXQ_THRESH_REG, val);
+   mvpp2_write(port->priv, MVPP2_RXQ_THRESH_REG, pkts);
 
rxq->pkts_coal = pkts;
 }
-- 
2.7.4



[PATCH v2 12/16] net: mvpp2: add AXI bridge initialization for PPv2.2

2016-12-27 Thread Thomas Petazzoni
The PPv2.2 unit is connected to an AXI bus on Armada 7K/8K, so this
commit adds the necessary initialization of the AXI bridge.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 85 
 1 file changed, 85 insertions(+)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index eb55576..d5b197d 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -157,6 +157,34 @@
 #define MVPP2_WIN_REMAP(w) (0x4040 + ((w) << 2))
 #define MVPP2_BASE_ADDR_ENABLE 0x4060
 
+/* AXI Bridge Registers */
+#define MVPP22_AXI_BM_WR_ATTR_REG  0x4100
+#define MVPP22_AXI_BM_RD_ATTR_REG  0x4104
+#define MVPP22_AXI_AGGRQ_DESCR_RD_ATTR_REG 0x4110
+#define MVPP22_AXI_TXQ_DESCR_WR_ATTR_REG   0x4114
+#define MVPP22_AXI_TXQ_DESCR_RD_ATTR_REG   0x4118
+#define MVPP22_AXI_RXQ_DESCR_WR_ATTR_REG   0x411c
+#define MVPP22_AXI_RX_DATA_WR_ATTR_REG 0x4120
+#define MVPP22_AXI_TX_DATA_RD_ATTR_REG 0x4130
+#define MVPP22_AXI_RD_NORMAL_CODE_REG  0x4150
+#define MVPP22_AXI_RD_SNOOP_CODE_REG   0x4154
+#define MVPP22_AXI_WR_NORMAL_CODE_REG  0x4160
+#define MVPP22_AXI_WR_SNOOP_CODE_REG   0x4164
+
+/* Values for AXI Bridge registers */
+#define MVPP22_AXI_ATTR_CACHE_OFFS 0
+#define MVPP22_AXI_ATTR_DOMAIN_OFFS12
+
+#define MVPP22_AXI_CODE_CACHE_OFFS 0
+#define MVPP22_AXI_CODE_DOMAIN_OFFS4
+
+#define MVPP22_AXI_CODE_CACHE_NON_CACHE0x3
+#define MVPP22_AXI_CODE_CACHE_WR_CACHE 0x7
+#define MVPP22_AXI_CODE_CACHE_RD_CACHE 0xb
+
+#define MVPP22_AXI_CODE_DOMAIN_OUTER_DOM   2
+#define MVPP22_AXI_CODE_DOMAIN_SYSTEM  3
+
 /* Interrupt Cause and Mask registers */
 #define MVPP2_ISR_RX_THRESHOLD_REG(rxq)(0x5200 + 4 * (rxq))
 #define MVPP2_MAX_ISR_RX_THRESHOLD 0xf0
@@ -6640,6 +6668,60 @@ static void mvpp2_rx_fifo_init(struct mvpp2 *priv)
mvpp2_write(priv, MVPP2_RX_FIFO_INIT_REG, 0x1);
 }
 
+static void mvpp2_axi_init(struct mvpp2 *priv)
+{
+   u32 val, rdval, wrval;
+
+   mvpp2_write(priv, MVPP22_BM_ADDR_HIGH_RLS_REG, 0x0);
+
+   /* AXI Bridge Configuration */
+
+   rdval = MVPP22_AXI_CODE_CACHE_RD_CACHE
+   << MVPP22_AXI_ATTR_CACHE_OFFS;
+   rdval |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
+   << MVPP22_AXI_ATTR_DOMAIN_OFFS;
+
+   wrval = MVPP22_AXI_CODE_CACHE_WR_CACHE
+   << MVPP22_AXI_ATTR_CACHE_OFFS;
+   wrval |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
+   << MVPP22_AXI_ATTR_DOMAIN_OFFS;
+
+   /* BM */
+   mvpp2_write(priv, MVPP22_AXI_BM_WR_ATTR_REG, wrval);
+   mvpp2_write(priv, MVPP22_AXI_BM_RD_ATTR_REG, rdval);
+
+   /* Descriptors */
+   mvpp2_write(priv, MVPP22_AXI_AGGRQ_DESCR_RD_ATTR_REG, rdval);
+   mvpp2_write(priv, MVPP22_AXI_TXQ_DESCR_WR_ATTR_REG, wrval);
+   mvpp2_write(priv, MVPP22_AXI_TXQ_DESCR_RD_ATTR_REG, rdval);
+   mvpp2_write(priv, MVPP22_AXI_RXQ_DESCR_WR_ATTR_REG, wrval);
+
+   /* Buffer Data */
+   mvpp2_write(priv, MVPP22_AXI_TX_DATA_RD_ATTR_REG, rdval);
+   mvpp2_write(priv, MVPP22_AXI_RX_DATA_WR_ATTR_REG, wrval);
+
+   val = MVPP22_AXI_CODE_CACHE_NON_CACHE
+   << MVPP22_AXI_CODE_CACHE_OFFS;
+   val |= MVPP22_AXI_CODE_DOMAIN_SYSTEM
+   << MVPP22_AXI_CODE_DOMAIN_OFFS;
+   mvpp2_write(priv, MVPP22_AXI_RD_NORMAL_CODE_REG, val);
+   mvpp2_write(priv, MVPP22_AXI_WR_NORMAL_CODE_REG, val);
+
+   val = MVPP22_AXI_CODE_CACHE_RD_CACHE
+   << MVPP22_AXI_CODE_CACHE_OFFS;
+   val |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
+   << MVPP22_AXI_CODE_DOMAIN_OFFS;
+
+   mvpp2_write(priv, MVPP22_AXI_RD_SNOOP_CODE_REG, val);
+
+   val = MVPP22_AXI_CODE_CACHE_WR_CACHE
+   << MVPP22_AXI_CODE_CACHE_OFFS;
+   val |= MVPP22_AXI_CODE_DOMAIN_OUTER_DOM
+   << MVPP22_AXI_CODE_DOMAIN_OFFS;
+
+   mvpp2_write(priv, MVPP22_AXI_WR_SNOOP_CODE_REG, val);
+}
+
 /* Initialize network controller common part HW */
 static int mvpp2_init(struct platform_device *pdev, struct mvpp2 *priv)
 {
@@ -6659,6 +6741,9 @@ static int mvpp2_init(struct platform_device *pdev, 
struct mvpp2 *priv)
if (dram_target_info)
mvpp2_conf_mbus_windows(dram_target_info, priv);
 
+   if (priv->hw_version == MVPP22)
+   mvpp2_axi_init(priv);
+
/* Disable HW PHY polling */
if (priv->hw_version == MVPP21) {
val = readl(priv->lms_base + MVPP2_PHY_AN_CFG0_REG);
-- 
2.7.4



[PATCH v2 09/11] net: mvpp2: simplify MVPP2_PRS_RI_* definitions

2016-12-27 Thread Thomas Petazzoni
Some of the MVPP2_PRS_RI_* definitions use the ~(value) syntax, which
doesn't compile nicely on 64-bit. Moreover, those definitions are in
fact unneeded, since they are always used in combination with a bit
mask that ensures only the appropriate bits are modified.

Therefore, such definitions should just be set to 0x0. For example:

 #define MVPP2_PRS_RI_L2_CAST_MASK  0x600
 #define MVPP2_PRS_RI_L2_UCAST  ~(BIT(9) | BIT(10))
 #define MVPP2_PRS_RI_L2_MCAST  BIT(9)
 #define MVPP2_PRS_RI_L2_BCAST  BIT(10)

becomes

 #define MVPP2_PRS_RI_L2_CAST_MASK  0x600
 #define MVPP2_PRS_RI_L2_UCAST  0x0
 #define MVPP2_PRS_RI_L2_MCAST  BIT(9)
 #define MVPP2_PRS_RI_L2_BCAST  BIT(10)

Because the values (MVPP2_PRS_RI_L2_UCAST, MVPP2_PRS_RI_L2_MCAST and
MVPP2_PRS_RI_L2_BCAST) are always applied with
MVPP2_PRS_RI_L2_CAST_MASK, and therefore there is no need for
MVPP2_PRS_RI_L2_UCAST to be defined as ~(BIT(9) | BIT(10)).

It fixes the following warnings when building the driver on a 64-bit
platform (which is not possible as of this commit, but will be enabled
in a follow-up commit):

drivers/net/ethernet/marvell/mvpp2.c: In function ‘mvpp2_prs_mac_promisc_set’:
drivers/net/ethernet/marvell/mvpp2.c:524:33: warning: large integer implicitly 
truncated to unsigned type [-Woverflow]
 #define MVPP2_PRS_RI_L2_UCAST   ~(BIT(9) | BIT(10))
 ^
drivers/net/ethernet/marvell/mvpp2.c:1459:33: note: in expansion of macro 
‘MVPP2_PRS_RI_L2_UCAST’
   mvpp2_prs_sram_ri_update(, MVPP2_PRS_RI_L2_UCAST,

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 36c73dc..58cf9af 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -511,19 +511,19 @@ enum mvpp2_tag_type {
 #define MVPP2_PRS_RI_MAC_ME_MASK   0x1
 #define MVPP2_PRS_RI_DSA_MASK  0x2
 #define MVPP2_PRS_RI_VLAN_MASK 0xc
-#define MVPP2_PRS_RI_VLAN_NONE ~(BIT(2) | BIT(3))
+#define MVPP2_PRS_RI_VLAN_NONE 0x0
 #define MVPP2_PRS_RI_VLAN_SINGLE   BIT(2)
 #define MVPP2_PRS_RI_VLAN_DOUBLE   BIT(3)
 #define MVPP2_PRS_RI_VLAN_TRIPLE   (BIT(2) | BIT(3))
 #define MVPP2_PRS_RI_CPU_CODE_MASK 0x70
 #define MVPP2_PRS_RI_CPU_CODE_RX_SPEC  BIT(4)
 #define MVPP2_PRS_RI_L2_CAST_MASK  0x600
-#define MVPP2_PRS_RI_L2_UCAST  ~(BIT(9) | BIT(10))
+#define MVPP2_PRS_RI_L2_UCAST  0x0
 #define MVPP2_PRS_RI_L2_MCAST  BIT(9)
 #define MVPP2_PRS_RI_L2_BCAST  BIT(10)
 #define MVPP2_PRS_RI_PPPOE_MASK0x800
 #define MVPP2_PRS_RI_L3_PROTO_MASK 0x7000
-#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14))
+#define MVPP2_PRS_RI_L3_UN 0x0
 #define MVPP2_PRS_RI_L3_IP4BIT(12)
 #define MVPP2_PRS_RI_L3_IP4_OPTBIT(13)
 #define MVPP2_PRS_RI_L3_IP4_OTHER  (BIT(12) | BIT(13))
@@ -531,7 +531,7 @@ enum mvpp2_tag_type {
 #define MVPP2_PRS_RI_L3_IP6_EXT(BIT(12) | BIT(14))
 #define MVPP2_PRS_RI_L3_ARP(BIT(13) | BIT(14))
 #define MVPP2_PRS_RI_L3_ADDR_MASK  0x18000
-#define MVPP2_PRS_RI_L3_UCAST  ~(BIT(15) | BIT(16))
+#define MVPP2_PRS_RI_L3_UCAST  0x0
 #define MVPP2_PRS_RI_L3_MCAST  BIT(15)
 #define MVPP2_PRS_RI_L3_BCAST  (BIT(15) | BIT(16))
 #define MVPP2_PRS_RI_IP_FRAG_MASK  0x2
-- 
2.7.4



[PATCH v2 04/16] net: mvpp2: introduce an intermediate union for the TX/RX descriptors

2016-12-27 Thread Thomas Petazzoni
Since the format of the HW descriptors is different between PPv2.1 and
PPv2.2, this commit introduces an intermediate union, with for now
only the PPv2.1 descriptors. The bulk of the driver code only
manipulates opaque mvpp2_tx_desc and mvpp2_rx_desc pointers, and the
descriptors can only be accessed and modified through the accessor
functions. A follow-up commit will add the descriptor definitions for
PPv2.2.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 43 +---
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index bc359a9..a37ff50 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -745,7 +745,8 @@ struct mvpp2_port {
 #define MVPP2_RXD_L3_IP6   BIT(30)
 #define MVPP2_RXD_BUF_HDR  BIT(31)
 
-struct mvpp2_tx_desc {
+/* HW TX descriptor for PPv2.1 */
+struct mvpp21_tx_desc {
u32 command;/* Options used by HW for packet transmitting.*/
u8  packet_offset;  /* the offset from the buffer beginning */
u8  phys_txq;   /* destination queue ID */
@@ -756,7 +757,8 @@ struct mvpp2_tx_desc {
u32 reserved2;  /* reserved (for future use)*/
 };
 
-struct mvpp2_rx_desc {
+/* HW RX descriptor for PPv2.1 */
+struct mvpp21_rx_desc {
u32 status; /* info about received packet   */
u16 reserved1;  /* parser_info (for future use, PnC)*/
u16 data_size;  /* size of received packet in bytes */
@@ -771,6 +773,21 @@ struct mvpp2_rx_desc {
u32 reserved8;
 };
 
+/* Opaque type used by the driver to manipulate the HW TX and RX
+ * descriptors
+ */
+struct mvpp2_tx_desc {
+   union {
+   struct mvpp21_tx_desc pp21;
+   };
+};
+
+struct mvpp2_rx_desc {
+   union {
+   struct mvpp21_rx_desc pp21;
+   };
+};
+
 struct mvpp2_txq_pcpu_buf {
/* Transmitted SKB */
struct sk_buff *skb;
@@ -974,72 +991,72 @@ static u32 mvpp2_read(struct mvpp2 *priv, u32 offset)
 static dma_addr_t mvpp2_txdesc_phys_addr_get(struct mvpp2_port *port,
 struct mvpp2_tx_desc *tx_desc)
 {
-   return tx_desc->buf_phys_addr;
+   return tx_desc->pp21.buf_phys_addr;
 }
 
 static void mvpp2_txdesc_phys_addr_set(struct mvpp2_port *port,
   struct mvpp2_tx_desc *tx_desc,
   dma_addr_t phys_addr)
 {
-   tx_desc->buf_phys_addr = phys_addr;
+   tx_desc->pp21.buf_phys_addr = phys_addr;
 }
 
 static size_t mvpp2_txdesc_size_get(struct mvpp2_port *port,
struct mvpp2_tx_desc *tx_desc)
 {
-   return tx_desc->data_size;
+   return tx_desc->pp21.data_size;
 }
 
 static void mvpp2_txdesc_size_set(struct mvpp2_port *port,
  struct mvpp2_tx_desc *tx_desc,
  size_t size)
 {
-   tx_desc->data_size = size;
+   tx_desc->pp21.data_size = size;
 }
 
 static void mvpp2_txdesc_txq_set(struct mvpp2_port *port,
 struct mvpp2_tx_desc *tx_desc,
 unsigned int txq)
 {
-   tx_desc->phys_txq = txq;
+   tx_desc->pp21.phys_txq = txq;
 }
 
 static void mvpp2_txdesc_cmd_set(struct mvpp2_port *port,
 struct mvpp2_tx_desc *tx_desc,
 unsigned int command)
 {
-   tx_desc->command = command;
+   tx_desc->pp21.command = command;
 }
 
 static void mvpp2_txdesc_offset_set(struct mvpp2_port *port,
struct mvpp2_tx_desc *tx_desc,
unsigned int offset)
 {
-   tx_desc->packet_offset = offset;
+   tx_desc->pp21.packet_offset = offset;
 }
 
 static dma_addr_t mvpp2_rxdesc_phys_addr_get(struct mvpp2_port *port,
 struct mvpp2_rx_desc *rx_desc)
 {
-   return rx_desc->buf_phys_addr;
+   return rx_desc->pp21.buf_phys_addr;
 }
 
 static unsigned long mvpp2_rxdesc_virt_addr_get(struct mvpp2_port *port,
struct mvpp2_rx_desc *rx_desc)
 {
-   return rx_desc->buf_cookie;
+   return rx_desc->pp21.buf_cookie;
 }
 
 static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
struct mvpp2_rx_desc *rx_desc)
 {
-   return rx_desc->data_size;
+   return rx_desc->pp21.data_size;
 }
 
 static u32 mvpp2_rxdesc_status_get(struct mvpp2_port *port,
   struct mvpp2_rx_desc *rx_desc)
 {
-   return rx_desc->status;
+   return rx_desc->pp21.status;
 }
 
 static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)
-- 

[PATCH v2 03/11] net: mvpp2: release reference to txq_cpu[] entry after unmapping

2016-12-27 Thread Thomas Petazzoni
The mvpp2_txq_bufs_free() function is called upon TX completion to DMA
unmap TX buffers, and free the corresponding SKBs. It gets the
references to the SKB to free and the DMA buffer to unmap from a per-CPU
txq_pcpu data structure.

However, the code currently increments the pointer to the next entry
before doing the DMA unmap and freeing the SKB. It does not cause any
visible problem because for a given SKB the TX completion is guaranteed
to take place on the CPU where the TX was started. However, it is much
more logical to increment the pointer to the next entry once the current
entry has been completely unmapped/released.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index a1ba89f..d098c7b 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -4420,13 +4420,12 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
struct mvpp2_txq_pcpu_buf *tx_buf =
txq_pcpu->buffs + txq_pcpu->txq_get_index;
 
-   mvpp2_txq_inc_get(txq_pcpu);
-
dma_unmap_single(port->dev->dev.parent, tx_buf->phys,
 tx_buf->size, DMA_TO_DEVICE);
-   if (!tx_buf->skb)
-   continue;
-   dev_kfree_skb_any(tx_buf->skb);
+   if (tx_buf->skb)
+   dev_kfree_skb_any(tx_buf->skb);
+
+   mvpp2_txq_inc_get(txq_pcpu);
}
 }
 
-- 
2.7.4



[PATCH v2 00/11] net: mvpp2: misc improvements and preparation patches

2016-12-27 Thread Thomas Petazzoni
Hello,

This series contains a number of misc improvements and preparation
patches for an upcoming series that adds support for the new PPv2.2
network controller to the mvpp2 driver.

The most significant improvements are:

 - Switching to using build_skb(), which is necessary for the upcoming
   PPv2.2 support, but anyway a good improvement to the current mvpp2
   driver (supporting PPv2.1).

 - Making the driver build on 64-bit platforms.

Changes since v1:

 - This series is split as a separate series from the larger patch set
   adding support for PPv2.2 in the mvpp2 driver, as requested by
   David Miller.

 - Rebased on top of v4.10-rc1.

Thanks!

Thomas

Thomas Petazzoni (11):
  net: mvpp2: handle too large value handling in
mvpp2_rx_pkts_coal_set()
  net: mvpp2: handle too large value in mvpp2_rx_time_coal_set()
  net: mvpp2: release reference to txq_cpu[] entry after unmapping
  net: mvpp2: remove unused 'tx_skb' field of 'struct mvpp2_tx_queue'
  net: mvpp2: drop useless fields in mvpp2_bm_pool and related code
  net: mvpp2: simplify mvpp2_bm_bufs_add()
  net: mvpp2: remove unused register definitions
  net: mvpp2: fix indentation of MVPP2_EXT_GLOBAL_CTRL_DEFAULT
  net: mvpp2: simplify MVPP2_PRS_RI_* definitions
  net: mvpp2: switch to build_skb() in the RX path
  net: mvpp2: enable building on 64-bit platforms

 drivers/net/ethernet/marvell/Kconfig |   3 +-
 drivers/net/ethernet/marvell/mvpp2.c | 161 ---
 2 files changed, 93 insertions(+), 71 deletions(-)

-- 
2.7.4



[PATCH v2 08/11] net: mvpp2: fix indentation of MVPP2_EXT_GLOBAL_CTRL_DEFAULT

2016-12-27 Thread Thomas Petazzoni
Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index edffcc1..36c73dc 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -254,7 +254,7 @@
 #define MVPP2_PHY_AN_CFG0_REG  0x34
 #define MVPP2_PHY_AN_STOP_SMI0_MASKBIT(7)
 #define MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG 0x305c
-#define MVPP2_EXT_GLOBAL_CTRL_DEFAULT  0x27
+#define MVPP2_EXT_GLOBAL_CTRL_DEFAULT  0x27
 
 /* Per-port registers */
 #define MVPP2_GMAC_CTRL_0_REG  0x0
-- 
2.7.4



[PATCH v2 07/11] net: mvpp2: remove unused register definitions

2016-12-27 Thread Thomas Petazzoni
Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index 8174f40..edffcc1 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -253,10 +253,6 @@
 #define MVPP2_SRC_ADDR_HIGH0x28
 #define MVPP2_PHY_AN_CFG0_REG  0x34
 #define MVPP2_PHY_AN_STOP_SMI0_MASKBIT(7)
-#define MVPP2_MIB_COUNTERS_BASE(port)  (0x1000 + ((port) >> 1) * \
-   0x400 + (port) * 0x400)
-#define MVPP2_MIB_LATE_COLLISION   0x7c
-#define MVPP2_ISR_SUM_MASK_REG 0x220c
 #define MVPP2_MNG_EXTENDED_GLOBAL_CTRL_REG 0x305c
 #define MVPP2_EXT_GLOBAL_CTRL_DEFAULT  0x27
 
-- 
2.7.4



[PATCH v2 04/11] net: mvpp2: remove unused 'tx_skb' field of 'struct mvpp2_tx_queue'

2016-12-27 Thread Thomas Petazzoni
This commit remove a field of 'struct mvpp2_tx_queue' that is not used
anywhere.

Signed-off-by: Thomas Petazzoni 
---
 drivers/net/ethernet/marvell/mvpp2.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c 
b/drivers/net/ethernet/marvell/mvpp2.c
index d098c7b..6720cdac 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -823,9 +823,6 @@ struct mvpp2_tx_queue {
/* Per-CPU control of physical Tx queues */
struct mvpp2_txq_pcpu __percpu *pcpu;
 
-   /* Array of transmitted skb */
-   struct sk_buff **tx_skb;
-
u32 done_pkts_coal;
 
/* Virtual address of thex Tx DMA descriptors array */
-- 
2.7.4



Re: [PATCH] net: dev_weight: TX/RX orthogonality

2016-12-27 Thread Marcelo Ricardo Leitner
On Tue, Dec 27, 2016 at 09:25:47AM +0100, Matthias Tafelmeier wrote:
> Oftenly, introducing side effects on packet processing on the other half
> of the stack by adjusting one of TX/RX via sysctl is not desirable.
> There are cases of demand for asymmetric, orthogonal configurability.
> 
> This holds true especially for nodes where RPS for RFS usage on top is
> configured and therefore use the 'old dev_weight'. This is quite a
> common base configuration setup nowadays, even with NICs of superior 
> processing
> support (e.g. aRFS).
> 
> A good example use case are nodes acting as noSQL data bases with a
> large number of tiny requests and rather fewer but large packets as responses.
> It's affordable to have large budget and rx dev_weights for the
> requests. But as a side effect having this large a number on TX
> processed in one run can overwhelm drivers.
> 
> This patch therefore introduces an independent configurability via sysctl to
> userland.
> ---
>  include/linux/netdevice.h  |  2 ++
>  net/core/dev.c |  4 +++-
>  net/core/sysctl_net_core.c | 14 ++
>  net/sched/sch_generic.c|  2 +-
>  4 files changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 994f742..bb331e0 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -3795,6 +3795,8 @@ void netdev_stats_to_stats64(struct rtnl_link_stats64 
> *stats64,
>  extern int   netdev_max_backlog;
>  extern int   netdev_tstamp_prequeue;
>  extern int   weight_p;
> +extern int   dev_w_rx_bias;
> +extern int   dev_w_tx_bias;
>  
>  bool netdev_has_upper_dev(struct net_device *dev, struct net_device 
> *upper_dev);
>  struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 8db5a0b..0dcbd28 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3428,6 +3428,8 @@ EXPORT_SYMBOL(netdev_max_backlog);
>  int netdev_tstamp_prequeue __read_mostly = 1;
>  int netdev_budget __read_mostly = 300;
>  int weight_p __read_mostly = 64;/* old backlog weight */
> +int dev_w_rx_bias __read_mostly = 1;/* bias for backlog weight */
> +int dev_w_tx_bias __read_mostly = 1;/* bias for output_queue 
> quota */
>  
>  /* Called with irq disabled */
>  static inline void napi_schedule(struct softnet_data *sd,
> @@ -4833,7 +4835,7 @@ static int process_backlog(struct napi_struct *napi, 
> int quota)
>   net_rps_action_and_irq_enable(sd);
>   }
>  
> - napi->weight = weight_p;
> + napi->weight = weight_p * dev_w_rx_bias;
>   while (again) {
>   struct sk_buff *skb;
>  
> diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
> index 2a46e40..a2ab149 100644
> --- a/net/core/sysctl_net_core.c
> +++ b/net/core/sysctl_net_core.c
> @@ -276,6 +276,20 @@ static struct ctl_table net_core_table[] = {
>   .proc_handler   = proc_dointvec
>   },
>   {
> + .procname   = "dev_w_rx_bias",
> + .data   = _w_rx_bias,
> + .maxlen = sizeof(int),
> + .mode   = 0644,
> + .proc_handler   = proc_dointvec
> + },
> + {
> + .procname   = "dev_w_tx_bias",
> + .data   = _w_tx_bias,
> + .maxlen = sizeof(int),
> + .mode   = 0644,
> + .proc_handler   = proc_dointvec
> + },
> + {

Please describe these at Documentation/sysctl/net.txt, probably right
after dev_weight. 

I'm not sure about the abbreviation, maybe it would be better the longer
name as it doesn't block tab completion.
dev_weight_tx_bias
dev_weight_rx_bias
dev_weight

>   .procname   = "netdev_max_backlog",
>   .data   = _max_backlog,
>   .maxlen = sizeof(int),
> diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
> index 6eb9c8e..4c07780 100644
> --- a/net/sched/sch_generic.c
> +++ b/net/sched/sch_generic.c
> @@ -247,7 +247,7 @@ static inline int qdisc_restart(struct Qdisc *q, int 
> *packets)
>  
>  void __qdisc_run(struct Qdisc *q)
>  {
> - int quota = weight_p;
> + int quota = weight_p * dev_w_tx_bias;
>   int packets;
>  
>   while (qdisc_restart(q, )) {
> -- 
> 2.7.4
> 


Re: [PATCH v2] net: stmmac: bug fix to synchronize stmmac_open and stmmac_dvr_probe

2016-12-27 Thread David Miller
From: "Kweh, Hock Leong"
Date: Tue, 27 Dec 2016 22:42:36 +0800

> From: "Kweh, Hock Leong" 

You are not the author of this change, do not take credit for it.

You have copied Florian's patch character by character, therefore
he is the author.

You also didn't CC: the netdev mailing list properly.


Patch

2016-12-27 Thread Joao Pinto
Hello David,

A few days ago you told me to resend a patch
(https://lkml.org/lkml/2016/12/20/416) when the next-net git tree opened.
Is this a good time to resend?

Thanks,
Joao



Patch

2016-12-27 Thread Joao Pinto
Hello David,

A few days ago you told me to resend a patch
(https://lkml.org/lkml/2016/12/20/416) when the next-net git tree opened.
Is this a good time to resend?

Thanks,
Joao



Re: [PATCH 01/12] Make and configuration files.

2016-12-27 Thread Joe Perches
On Tue, 2016-12-27 at 05:17 -0800, David VomLehn wrote:
> Patches to create the make and configuration files.

A few small things about this patch series that adds a
new driver:

These should be sent with a cover letter [0/N] so that
the reason this series is useful can be added to the
merge log.

Patch 1 will not build if CONFIG_AQTION is enabled.
Patch 1/12 should be reordered to be patch 12/12 and
all the other patches moved up appropriately.

The patches should ave a subject prefix of "AQtion: " so
the generic titles are recognizable.



Hi Dear !

2016-12-27 Thread Miss Lina Kipkalya
Hi Dear !

How are you doing today,hope fine, My name is Lina and i am a girl. I saw your 
profile today and decided to extend my greetings to you. But I do have the mind 
that you could be a nice person is my believe and there are nice people out 
there who can appreciate the value of friendship.and i will like to be your 
friend even more than that,but as time goes on we will know better.


Re: [PATCH v3 3/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel

2016-12-27 Thread Geoff Lansberry
Mark - I will split this off soon.

In the meantime - here is some more info about how we use it.

We do use NFC structures.I did find an interesting clue in that
there are certain bottles that cause neard to segfault,  I'm not sure
what is different about them.  We write a string, like
"coppola_chardonnay_2015" to the bottles.  Come to think of it, I
haven't done anything special to make that an ndef record, just
assumed that it would happen by default, I'll look into this further.
  Also, I've been running neard with --plugin nfctype2. Just in case
the problem was happening due to cycling through other tag types.   It
didn't seem to make any difference, but I have not gone back to
default.

Geoff
Geoff Lansberry


Engineering Guy
Kuvée, Inc
125 Kingston St., 3rd Floor
Boston, MA 02111
1-617-290-1118 (m)
geoff.lansberry (skype)
http://www.kuvee.com



On Sat, Dec 24, 2016 at 12:24 PM, Mark Greer  wrote:
> On Sat, Dec 24, 2016 at 11:17:18AM -0500, Geoff Lansberry wrote:
>> Mark - I'm sorry, but I did not write this code, and therefore was not
>> able to accurately describe it.   It is fixing a different issue, not
>> the neard segfault that we are still chasing. Last week Jaret Cantu
>> sent a separate email explaining the purpose of the code, which had
>> you copied, did you see that?
>
> Hm, no, I didn't.  I received an email from Justin Bronder but not from
> Jaret Cantu.  Justin's email did help but is still pretty high-level.
> We need a clear understanding as to what is happening in the digital
> layer and the driver to know how execution is getting into a block of
> error handling code that should never be executed.  Once we understand
> that we can start thinking about what the best fix is.
>
>> Does it explain why it was done to
>> your satisfaction?   I've asked him to join in on the effort to push
>> the change upstream, however he will not be available until the new
>> year.
>
> I expect that it would help if he joins.  After the holidays is fine -
> I think many people are taking it easy for the next week or so, anyway.
>
>> I know you did suggest that we split off that change from the others,
>> and if now is the time to do that, let me know.   If you don't have
>> the email from Jaret, also please let me know and I will forward it to
>> you.
>
> I think it would help you if you split it off because the first two patches
> have a good chance of being accepted but this one doesn't (yet).  If you
> separate the them, it will make it easier for Samuel to take the first two
> (or he may take the first two anyway but its always good to make it as
> easy maintainers as you can).
>
> Mark
> --


Re: [RFC PATCH 4.10 1/6] crypto/sha256: Refactor the API so it can be used without shash

2016-12-27 Thread Daniel Borkmann

On 12/27/2016 10:58 AM, Herbert Xu wrote:

On Mon, Dec 26, 2016 at 10:08:48AM -0800, Andy Lutomirski wrote:


According to Daniel, the networking folks want to let embedded systems
include BPF without requiring the crypto core.


Last I checked the IPv4 stack depended on the crypto API so this
sounds bogus.


I think there's a bit of a mixup here with what I said. To clarify,
requirement back then from tracing folks was that bpf engine and
therefore bpf syscall can be build w/o networking enabled for small
devices, so dependencies preferably need to be kept on a absolute
minimum, same counts for either making it suddenly a depend on
CRYPTO or a select CRYPTO for just those few lines that can be
pulled in from lib/ code instead.


[PATCH 04/12] Low-level hardware interfaces

2016-12-27 Thread David VomLehn
Add definitions of functions that interface directly with the hardware.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c | 1033 
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h |  587 +
 .../aquantia/atlantic/hw_atl/hw_atl_llh_internal.h | 2487 
 3 files changed, 4107 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
 create mode 100644 
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
new file mode 100644
index 000..4f1b322
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
@@ -0,0 +1,1033 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File hw_atl_llh.c: Definitions of bitfield and register access functions for
+ * Atlantic registers.
+ */
+
+#include "hw_atl_llh.h"
+#include "hw_atl_llh_internal.h"
+
+#include "../aq_hw_utils.h"
+
+/* global */
+void reg_glb_cpu_sem_set(struct aq_hw_s *aq_hw, u32 glb_cpu_sem, u32 semaphore)
+{
+   aq_hw_write_reg(aq_hw, glb_cpu_sem_adr(semaphore), glb_cpu_sem);
+}
+
+u32 reg_glb_cpu_sem_get(struct aq_hw_s *aq_hw, u32 semaphore)
+{
+   return aq_hw_read_reg(aq_hw, glb_cpu_sem_adr(semaphore));
+}
+
+void glb_glb_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 glb_reg_res_dis)
+{
+   aq_hw_utils_write_reg_bit(aq_hw, glb_reg_res_dis_adr,
+ glb_reg_res_dis_msk, glb_reg_res_dis_shift,
+ glb_reg_res_dis);
+}
+
+void glb_soft_res_set(struct aq_hw_s *aq_hw, u32 soft_res)
+{
+   aq_hw_utils_write_reg_bit(aq_hw, glb_soft_res_adr, glb_soft_res_msk,
+ glb_soft_res_shift, soft_res);
+}
+
+u32 glb_soft_res_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_utils_read_reg_bit(aq_hw, glb_soft_res_adr,
+   glb_soft_res_msk,
+   glb_soft_res_shift);
+}
+
+u32 reg_rx_dma_stat_counter7get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, rx_dma_stat_counter7_adr);
+}
+
+u32 reg_glb_mif_id_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, glb_mif_id_adr);
+}
+
+/* stats */
+
+u32 rpb_rx_dma_drop_pkt_cnt_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, rpb_rx_dma_drop_pkt_cnt_adr);
+}
+
+u32 stats_rx_dma_good_octet_counterlsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_rx_dma_good_octet_counterlsw__adr);
+}
+
+u32 stats_rx_dma_good_pkt_counterlsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_rx_dma_good_pkt_counterlsw__adr);
+}
+
+u32 stats_tx_dma_good_octet_counterlsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_tx_dma_good_octet_counterlsw__adr);
+}
+
+u32 stats_tx_dma_good_pkt_counterlsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_tx_dma_good_pkt_counterlsw__adr);
+}
+
+u32 stats_rx_dma_good_octet_countermsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_rx_dma_good_octet_countermsw__adr);
+}
+
+u32 stats_rx_dma_good_pkt_countermsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_rx_dma_good_pkt_countermsw__adr);
+}
+
+u32 stats_tx_dma_good_octet_countermsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_tx_dma_good_octet_countermsw__adr);
+}
+
+u32 stats_tx_dma_good_pkt_countermsw_get(struct aq_hw_s *aq_hw)
+{
+   return aq_hw_read_reg(aq_hw, stats_tx_dma_good_pkt_countermsw__adr);
+}
+
+/* interrupt */
+void itr_irq_auto_masklsw_set(struct aq_hw_s *aq_hw, u32 irq_auto_masklsw)
+{
+   aq_hw_write_reg(aq_hw, itr_iamrlsw_adr, irq_auto_masklsw);
+}
+
+void itr_irq_map_en_rx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_rx, u32 rx)
+{
+   aq_hw_utils_write_reg_bit(aq_hw, itr_imr_rxren_adr(rx),
+ itr_imr_rxren_msk(rx),
+ itr_imr_rxren_shift(rx),
+ irq_map_en_rx);
+}
+
+void itr_irq_map_en_tx_set(struct aq_hw_s *aq_hw, u32 irq_map_en_tx, u32 tx)
+{
+   aq_hw_utils_write_reg_bit(aq_hw, itr_imr_txten_adr(tx),
+ itr_imr_txten_msk(tx),
+ itr_imr_txten_shift(tx),
+ 

[PATCH 06/12] Atlantic A0 specific functions.

2016-12-27 Thread David VomLehn
Add Atlantic A0-specific functions.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  | 934 +
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.h  |  35 +
 .../aquantia/atlantic/hw_atl/hw_atl_a0_internal.h  | 119 +++
 3 files changed, 1088 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.h
 create mode 100644 
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
new file mode 100644
index 000..604239a
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -0,0 +1,934 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File hw_atl_a0.c: Definition of Atlantic hardware specific functions.
+ */
+
+#include "../aq_hw.h"
+#include "../aq_hw_utils.h"
+#include "../aq_ring.h"
+#include "hw_atl_a0.h"
+#include "hw_atl_utils.h"
+#include "hw_atl_llh.h"
+#include "hw_atl_a0_internal.h"
+
+#include 
+
+static struct aq_hw_caps_s hw_atl_a0_hw_caps_ = {
+   .ports = 1U,
+   .is_64_dma = true,
+   .msix_irqs = 4U,
+   .irq_mask = ~0U,
+   .vecs = HW_ATL_A0_RSS_MAX,
+   .tcs = HW_ATL_A0_TC_MAX,
+   .rxd_alignment = 1U,
+   .rxd_size = HW_ATL_A0_RXD_SIZE,
+   .rxds = 248U,
+   .txd_alignment = 1U,
+   .txd_size = HW_ATL_A0_TXD_SIZE,
+   .txds = 8U * 1024U,
+   .txhwb_alignment = 4096U,
+   .tx_rings = HW_ATL_A0_TX_RINGS,
+   .rx_rings = HW_ATL_A0_RX_RINGS,
+   .hw_features = NETIF_F_HW_CSUM |
+   NETIF_F_RXHASH |
+   NETIF_F_SG |
+   NETIF_F_TSO,
+   .hw_priv_flags = IFF_UNICAST_FLT,
+   .link_speed_msk = (HW_ATL_A0_RATE_10G |
+   HW_ATL_A0_RATE_5G |
+   HW_ATL_A0_RATE_2G5 |
+   HW_ATL_A0_RATE_1G |
+   HW_ATL_A0_RATE_100M),
+   .flow_control = true,
+   .mtu = HW_ATL_A0_MTU_JUMBO,
+   .mac_regs_count = 88,
+};
+
+static int hw_atl_a0_get_hw_caps(struct aq_hw_s *self,
+struct aq_hw_caps_s *aq_hw_caps)
+{
+   memcpy(aq_hw_caps, _atl_a0_hw_caps_, sizeof(*aq_hw_caps));
+   return 0;
+}
+
+static struct aq_hw_s *hw_atl_a0_create(struct aq_pci_func_s *aq_pci_func,
+   unsigned int port,
+   struct aq_hw_ops *ops)
+{
+   struct hw_atl_s *self = NULL;
+   int err = 0;
+
+   self = kzalloc(sizeof(*self), GFP_KERNEL);
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+   self->base.aq_pci_func = aq_pci_func;
+
+   self->base.not_ff_addr = 0x10U;
+
+err_exit:
+   return (struct aq_hw_s *)self;
+}
+
+static void hw_atl_a0_destroy(struct aq_hw_s *self)
+{
+   kfree(self);
+}
+
+static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
+{
+   int err = 0;
+
+   glb_glb_reg_res_dis_set(self, 1U);
+   pci_pci_reg_res_dis_set(self, 0U);
+   rx_rx_reg_res_dis_set(self, 0U);
+   tx_tx_reg_res_dis_set(self, 0U);
+
+   HW_ATL_FLUSH();
+   glb_soft_res_set(self, 1);
+
+   /* check 10 times by 1ms */
+   AQ_HW_WAIT_FOR(glb_soft_res_get(self) == 0, 1000U, 10U);
+   if (err < 0)
+   goto err_exit;
+
+   itr_irq_reg_res_dis_set(self, 0U);
+   itr_res_irq_set(self, 1U);
+
+   /* check 10 times by 1ms */
+   AQ_HW_WAIT_FOR(itr_res_irq_get(self) == 0, 1000U, 10U);
+   if (err < 0)
+   goto err_exit;
+
+   hw_atl_utils_mpi_set(self, MPI_RESET, 0x0U);
+
+   err = aq_hw_err_from_flags(self);
+
+err_exit:
+   return err;
+}
+
+static int hw_atl_a0_hw_qos_set(struct aq_hw_s *self)
+{
+   u32 tc = 0U;
+   u32 buff_size = 0U;
+   unsigned int i_priority = 0U;
+   bool is_rx_flow_control = false;
+
+   /* TPS Descriptor rate init */
+   tps_tx_pkt_shed_desc_rate_curr_time_res_set(self, 0x0U);
+   tps_tx_pkt_shed_desc_rate_lim_set(self, 0xA);
+
+   /* TPS VM init */
+   tps_tx_pkt_shed_desc_vm_arb_mode_set(self, 0U);
+
+   /* TPS TC credits init */
+   tps_tx_pkt_shed_desc_tc_arb_mode_set(self, 0U);
+   tps_tx_pkt_shed_data_arb_mode_set(self, 0U);
+
+   tps_tx_pkt_shed_tc_data_max_credit_set(self, 0xFFF, 0U);
+   

[PATCH 02/12] Common functions and definitions

2016-12-27 Thread David VomLehn
Add files containing the functions and definitions used in common in
different functional areas.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/aq_cfg.h| 83 ++
 drivers/net/ethernet/aquantia/atlantic/aq_common.h | 24 +++
 drivers/net/ethernet/aquantia/atlantic/aq_utils.h  | 55 ++
 3 files changed, 162 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_common.h
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_utils.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
new file mode 100644
index 000..054bc38
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
@@ -0,0 +1,83 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_cfg.h: Definition of configuration parameters and constants.
+ */
+
+#ifndef AQ_CFG_H
+#define AQ_CFG_H
+
+#define AQ_CFG_VECS_DEF   4U
+#define AQ_CFG_TCS_DEF1U
+
+#define AQ_CFG_TXDS_DEF4096U
+#define AQ_CFG_RXDS_DEF248U
+
+#define AQ_CFG_IS_POLLING_DEF 0U
+
+#define AQ_CFG_FORCE_LEGACY_INT 0U
+
+#define AQ_CFG_IS_INTERRUPT_MODERATION_DEF   1U
+#define AQ_CFG_INTERRUPT_MODERATION_RATE_DEF 0xU
+#define AQ_CFG_IRQ_MASK  0x1FFU
+
+#define AQ_CFG_VECS_MAX   8U
+#define AQ_CFG_TCS_MAX8U
+
+#define AQ_CFG_TXDS_MAX(16U * 1024U)
+#define AQ_CFG_RXDS_MAX(16U * 1024U)
+
+#define AQ_CFG_TX_FRAME_MAX  (16U * 1024U)
+#define AQ_CFG_RX_FRAME_MAX  (4U * 1024U)
+
+/* RSS */
+#define AQ_CFG_RSS_INDIRECTION_TABLE_MAX  128U
+#define AQ_CFG_RSS_HASHKEY_SIZE   320U
+
+#define AQ_CFG_IS_RSS_DEF   1U
+#define AQ_CFG_NUM_RSS_QUEUES_DEF   AQ_CFG_VECS_DEF
+#define AQ_CFG_RSS_BASE_CPU_NUM_DEF 0U
+
+#define AQ_CFG_PCI_FUNC_MSIX_IRQS   9U
+#define AQ_CFG_PCI_FUNC_PORTS   2U
+
+#define AQ_CFG_SERVICE_TIMER_INTERVAL(2 * HZ)
+#define AQ_CFG_POLLING_TIMER_INTERVAL   ((unsigned int)(2 * HZ))
+
+#define AQ_CFG_SKB_FRAGS_MAX   32U
+#define AQ_CFG_IP_ALIGN 0U
+
+#define AQ_CFG_NAPI_WEIGHT 64U
+
+#define AQ_CFG_MULTICAST_ADDRESS_MAX 32U
+
+//#define AQ_CFG_MAC_ADDR_PERMANENT {0x30, 0x0E, 0xE3, 0x12, 0x34, 0x56}
+
+#define AQ_CFG_FC_MODE 3U
+
+#define AQ_CFG_SPEED_MSK  0xU  /* 0xU==auto_neg */
+
+#define AQ_CFG_IS_AUTONEG_DEF   1U
+#define AQ_CFG_MTU_DEF  1514U
+
+#define AQ_CFG_LOCK_TRYS   100U
+
+#define TXT(_T_) #_T_
+#define TXTTXT(_T_) TXT(_T_)
+
+#define AQ_CFG_DRV_AUTHOR  "Aquantia"
+#define AQ_CFG_DRV_DESC"Aquantia Corporation(R) Network Driver"
+#define AQ_CFG_DRV_NAME"aquantia"
+#define AQ_CFG_DRV_VERSION TXTTXT(NIC_MAJOR_DRIVER_VERSION)"."\
+   TXTTXT(NIC_MINOR_DRIVER_VERSION)"."\
+   TXTTXT(NIC_BUILD_DRIVER_VERSION)"."\
+   TXTTXT(NIC_REVISION_DRIVER_VERSION)
+
+#endif /* AQ_CFG_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_common.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_common.h
new file mode 100644
index 000..f92201d
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_common.h
@@ -0,0 +1,24 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_common.h: Basic includes for all files in project.
+ */
+
+#ifndef AQ_COMMON_H
+#define AQ_COMMON_H
+
+#include 
+
+#include "ver.h"
+#include "aq_nic.h"
+#include "aq_cfg.h"
+#include "aq_utils.h"
+
+#endif /* AQ_COMMON_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
new file mode 100644
index 000..07b4618
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_utils.h
@@ -0,0 +1,55 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_utils.h: Useful macro and structures used in all layers of driver.
+ */
+
+#ifndef AQ_UTILS_H
+#define AQ_UTILS_H
+

[PATCH 05/12] Support for NIC-specific code

2016-12-27 Thread David VomLehn
Add support for code specific to the Atlantic NIC.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c| 993 +
 drivers/net/ethernet/aquantia/atlantic/aq_nic.h| 111 +++
 .../ethernet/aquantia/atlantic/aq_nic_internal.h   |  48 +
 3 files changed, 1152 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_nic.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_nic.h
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_nic_internal.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
new file mode 100644
index 000..bc4c672
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -0,0 +1,993 @@
+//err_exit:
+//err_exit:
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_nic.c: Definition of common code for NIC.
+ */
+
+#include "aq_nic.h"
+#include "aq_vec.h"
+#include "aq_ring.h"
+#include "aq_hw.h"
+#include "aq_pci_func.h"
+#include "aq_rss.h"
+#include "aq_nic_internal.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Fills aq_nic_cfg with valid defaults
+ */
+static int aq_nic_cfg_init_defaults(struct aq_nic_s *self)
+{
+   struct aq_nic_cfg_s *cfg = >aq_nic_cfg;
+   int err = 0;
+
+   cfg->aq_hw_caps = >aq_hw_caps;
+
+   cfg->vecs = AQ_CFG_VECS_DEF;
+   cfg->tcs = AQ_CFG_TCS_DEF;
+
+   cfg->rxds = AQ_CFG_RXDS_DEF;
+   cfg->txds = AQ_CFG_TXDS_DEF;
+
+   cfg->is_polling = AQ_CFG_IS_POLLING_DEF;
+
+   cfg->is_interrupt_moderation = AQ_CFG_IS_INTERRUPT_MODERATION_DEF;
+   cfg->itr = cfg->is_interrupt_moderation ?
+   AQ_CFG_INTERRUPT_MODERATION_RATE_DEF : 0U;
+
+   cfg->is_rss = AQ_CFG_IS_RSS_DEF;
+   cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF;
+   cfg->aq_rss.base_cpu_number = AQ_CFG_RSS_BASE_CPU_NUM_DEF;
+   cfg->flow_control = AQ_CFG_FC_MODE;
+
+   cfg->mtu = AQ_CFG_MTU_DEF;
+   cfg->link_speed_msk = AQ_CFG_SPEED_MSK;
+   cfg->is_autoneg = AQ_CFG_IS_AUTONEG_DEF;
+
+   cfg->vlan_id = 0U;
+
+   err = aq_nic_rss_init(self, cfg->num_rss_queues);
+   if (err < 0)
+   goto err_exit;
+
+err_exit:
+   return err;
+}
+
+/*
+ * Checks hw_caps and 'corrects' aq_nic_cfg in runtime
+ */
+int aq_nic_cfg_start(struct aq_nic_s *self)
+{
+   struct aq_nic_cfg_s *cfg = >aq_nic_cfg;
+
+   /*descriptors */
+   cfg->rxds = min(cfg->rxds, cfg->aq_hw_caps->rxds);
+   cfg->txds = min(cfg->txds, cfg->aq_hw_caps->txds);
+
+   /*rss rings */
+   cfg->vecs = min(cfg->vecs, cfg->aq_hw_caps->vecs);
+   cfg->vecs = min(cfg->vecs, num_online_cpus());
+
+   cfg->irq_type = aq_pci_func_get_irq_type(self->aq_pci_func);
+
+   if ((cfg->irq_type == AQ_IRQ_LEGACY) ||
+   (self->aq_hw_caps.vecs == 1U) ||
+   (cfg->vecs == 1U)) {
+   cfg->is_rss = 0U;
+   cfg->vecs = 1U;
+   }
+
+   cfg->link_speed_msk &= self->aq_hw_caps.link_speed_msk;
+
+   return 0;
+}
+
+static int aq_nic_cfg_read(struct aq_nic_s *self)
+{
+   return 0;
+}
+
+static int aq_nic_cfg_check(struct aq_nic_s *self)
+{
+   return 0;
+}
+
+int aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
+{
+   struct aq_nic_cfg_s *cfg = >aq_nic_cfg;
+   struct aq_receive_scale_parameters *rss_params = >aq_rss;
+   int i = 0;
+
+   static u8 rss_key[40] = {
+   0x1e, 0xad, 0x71, 0x87, 0x65, 0xfc, 0x26, 0x7d,
+   0x0d, 0x45, 0x67, 0x74, 0xcd, 0x06, 0x1a, 0x18,
+   0xb6, 0xc1, 0xf0, 0xc7, 0xbb, 0x18, 0xbe, 0xf8,
+   0x19, 0x13, 0x4b, 0xa9, 0xd0, 0x3e, 0xfe, 0x70,
+   0x25, 0x03, 0xab, 0x50, 0x6a, 0x8b, 0x82, 0x0c
+   };
+
+   rss_params->hash_secret_key_size = sizeof(rss_key);
+   memcpy(rss_params->hash_secret_key, rss_key, sizeof(rss_key));
+   rss_params->indirection_table_size = AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
+
+   for (i = rss_params->indirection_table_size; i--;)
+   rss_params->indirection_table[i] = i & (num_rss_queues - 1);
+   return 0;
+}
+
+static void aq_nic_service_timer_cb(unsigned long param)
+{
+   struct aq_nic_s *self = (struct aq_nic_s *)param;
+   int err = 0;
+   bool is_busy = false;
+   struct aq_hw_link_status_s link_status;
+
+   atomic_inc(>busy_count);
+   is_busy = true;
+   if (AQ_OBJ_TST(self, AQ_NIC_FLAGS_IS_NOT_READY)) {
+  

[PATCH 09/12] Atlantic hardware abstraction layer

2016-12-27 Thread David VomLehn
Add common functions for Atlantic hardware abstraction layer.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c| 545 +
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h| 214 
 2 files changed, 759 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
new file mode 100644
index 000..42ca100
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -0,0 +1,545 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File hw_atl_utils.c: Definition of common functions for Atlantic hardware
+ * abstraction layer.
+ */
+
+#include "../aq_hw.h"
+#include "../aq_hw_utils.h"
+#include "../aq_pci_func.h"
+#include "../aq_ring.h"
+#include "../aq_vec.h"
+#include "hw_atl_utils.h"
+#include "hw_atl_llh.h"
+
+#include 
+
+#define HW_ATL_UCP_0X370_REG0x0370U
+
+#define HW_ATL_FW_SM_RAM0x2U
+#define HW_ATL_MPI_CONTROL_ADR  0x0368U
+#define HW_ATL_MPI_STATE_ADR0x036CU
+
+#define HW_ATL_MPI_STATE_MSK0x00FFU
+#define HW_ATL_MPI_STATE_SHIFT  0U
+#define HW_ATL_MPI_SPEED_MSK0xU
+#define HW_ATL_MPI_SPEED_SHIFT  16U
+
+int hw_atl_utils_fw_download_dwords(struct aq_hw_s *self, u32 a, u32 *p,
+   u32 cnt)
+{
+   int err = 0;
+
+   AQ_HW_WAIT_FOR(reg_glb_cpu_sem_get(self,
+  HW_ATL_FW_SM_RAM) == 1U, 1U, 1000U);
+
+   if (err < 0) {
+   bool is_locked;
+
+   reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
+   is_locked = reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
+   if (!(is_locked)) {
+   err = ETIME;
+   goto err_exit;
+   }
+   }
+
+   aq_hw_write_reg(self, 0x0208U, a);
+
+   for (++cnt; --cnt;) {
+   u32 i = 0U;
+
+   aq_hw_write_reg(self, 0x0200U, 0x8000U);
+
+   for (i = 1024U;
+   (0x100U & aq_hw_read_reg(self, 0x0200U)) && --i;) {
+   }
+
+   *(p++) = aq_hw_read_reg(self, 0x020CU);
+   }
+
+   reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
+
+err_exit:
+   return err;
+}
+
+void hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
+  u32 cnt)
+{
+   int err = 0;
+   bool is_locked;
+
+   is_locked = reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
+   if (!(is_locked)) {
+   err = ETIME;
+   goto err_exit;
+   }
+
+   aq_hw_write_reg(self, 0x0208U, a);
+
+   for (++cnt; --cnt;) {
+   u32 i = 0U;
+
+   aq_hw_write_reg(self, 0x020CU, *(p++));
+   aq_hw_write_reg(self, 0x0200U, 0xC000U);
+
+   for (i = 1024U;
+   (0x100U & aq_hw_read_reg(self, 0x0200U)) && --i;) {
+   }
+   }
+
+   reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
+
+err_exit:;
+   (void)err;
+}
+
+int hw_atl_utils_init_ucp(struct aq_hw_s *self)
+{
+   int err = 0;
+
+   if (!aq_hw_read_reg(self, 0x370U)) {
+   unsigned int rnd = 0U;
+   unsigned int ucp_0x370 = 0U;
+
+   get_random_bytes(, sizeof(unsigned int));
+
+   ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
+   aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
+   }
+
+   reg_glb_cpu_scratch_scp_set(self, 0xU, 25U);
+
+   /* check 10 times by 1ms */
+   AQ_HW_WAIT_FOR(0U != (PHAL_ATLANTIC_A0->mbox_addr =
+   aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
+
+   return err;
+}
+
+#define HW_ATL_RPC_CONTROL_ADR 0x0338U
+#define HW_ATL_RPC_STATE_ADR   0x033CU
+
+struct aq_hw_atl_utils_fw_rpc_tid_s {
+   union {
+   u32 val;
+   struct {
+   u16 tid;
+   u16 len;
+   };
+   };
+};
+
+#define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
+
+int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
+{
+   int err = 0;
+   struct aq_hw_atl_utils_fw_rpc_tid_s sw;
+
+   if (!(IS_CHIP_FEATURE(MIPS))) {
+   err = -1;
+   

[PATCH 01/12] Make and configuration files.

2016-12-27 Thread David VomLehn
Patches to create the make and configuration files.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/Kconfig  |  9 ++
 drivers/net/ethernet/aquantia/atlantic/Makefile | 40 +
 drivers/net/ethernet/aquantia/atlantic/ver.h| 18 +++
 3 files changed, 67 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/Kconfig
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/Makefile
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/ver.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/Kconfig 
b/drivers/net/ethernet/aquantia/atlantic/Kconfig
new file mode 100644
index 000..33f1eb6
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/Kconfig
@@ -0,0 +1,9 @@
+#
+# Aquantia device configuration
+#
+
+config AQTION
+   tristate "Aquantia AQtion Support"
+   depends on PCI
+   ---help---
+ This enables the support for the Aquantia AQtion Ethernet card.
\ No newline at end of file
diff --git a/drivers/net/ethernet/aquantia/atlantic/Makefile 
b/drivers/net/ethernet/aquantia/atlantic/Makefile
new file mode 100644
index 000..f0d961f
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/Makefile
@@ -0,0 +1,40 @@
+TARGET:=atlantic
+
+CC = gcc
+
+ifeq "$(CC)" "gcc"
+   ccflags-y := -Wall
+endif
+
+ifneq ($(KERNELRELEASE),)
+   $(TARGET)-objs:=aq_main.o aq_nic.o aq_pci_func.o aq_nic.o aq_vec.o \
+   aq_ring.o aq_hw_utils.o aq_ethtool.o hw_atl/hw_atl_a0.o \
+   hw_atl/hw_atl_utils.o hw_atl/hw_atl_llh.o
+
+   obj-m:=$(TARGET).o
+else
+   ifndef KDIR
+   BUILD_DIR:=/lib/modules/$(shell uname -r)/build
+   else
+   BUILD_DIR:=$(KDIR)
+   endif
+
+   PWD:=$(shell pwd)
+
+all:
+   $(MAKE) -j4 CC=$(CC) -C $(BUILD_DIR) M=$(PWD) modules
+
+dox:   .doxygen
+   @doxygen $<
+
+clean:
+   $(MAKE) -j4 -C $(BUILD_DIR) M=$(PWD) clean
+   @-rm -rdf doc/html 2 > /dev/null
+
+load:
+   insmod ./$(TARGET).ko
+
+unload:
+   rmmod ./$(TARGET).ko
+
+endif
diff --git a/drivers/net/ethernet/aquantia/atlantic/ver.h 
b/drivers/net/ethernet/aquantia/atlantic/ver.h
new file mode 100644
index 000..225f561
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/ver.h
@@ -0,0 +1,18 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef VER_H
+#define VER_H
+
+#define NIC_MAJOR_DRIVER_VERSION   1
+#define NIC_MINOR_DRIVER_VERSION   4
+#define NIC_BUILD_DRIVER_VERSION   1671
+#define NIC_REVISION_DRIVER_VERSION0
+
+#endif /* VER_H */
-- 
2.7.4



[PATCH 11/12] Ethtool support

2016-12-27 Thread David VomLehn
Add the driver interfaces required for support by the ethtool utility.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 .../net/ethernet/aquantia/atlantic/aq_ethtool.c| 254 +
 .../net/ethernet/aquantia/atlantic/aq_ethtool.h|  21 ++
 2 files changed, 275 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
new file mode 100644
index 000..ab50aa1
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -0,0 +1,254 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_ethtool.c: Definition of ethertool related functions.
+ */
+
+#include "aq_ethtool.h"
+#include "aq_nic.h"
+
+static void aq_ethtool_get_regs(struct net_device *ndev,
+   struct ethtool_regs *regs, void *p)
+{
+   struct aq_nic_s *aq_nic = (struct aq_nic_s *)netdev_priv(ndev);
+   u32 regs_count = aq_nic_get_regs_count(aq_nic);
+
+   memset(p, 0, regs_count * sizeof(u32));
+   aq_nic_get_regs(aq_nic, regs, p);
+}
+
+static int aq_ethtool_get_regs_len(struct net_device *ndev)
+{
+   struct aq_nic_s *aq_nic = (struct aq_nic_s *)netdev_priv(ndev);
+   u32 regs_count = aq_nic_get_regs_count(aq_nic);
+
+   return regs_count * sizeof(u32);
+}
+
+static u32 aq_ethtool_get_link(struct net_device *ndev)
+{
+   struct aq_nic_s *aq_nic = (struct aq_nic_s *)netdev_priv(ndev);
+   u32 ret = 0U;
+
+   ret = aq_nic_get_link_speed(aq_nic) ? 1U : 0U;
+   return ret;
+}
+
+static int aq_ethtool_get_settings(struct net_device *ndev,
+  struct ethtool_cmd *cmd)
+{
+   struct aq_nic_s *aq_nic = (struct aq_nic_s *)netdev_priv(ndev);
+
+   cmd->port = PORT_TP;
+   cmd->transceiver = XCVR_EXTERNAL;
+
+   ethtool_cmd_speed_set(cmd, netif_carrier_ok(ndev) ?
+   aq_nic_get_link_speed(aq_nic) : 0U);
+
+   cmd->duplex = DUPLEX_FULL;
+   aq_nic_get_link_settings(aq_nic, cmd);
+   return 0;
+}
+
+static int aq_ethtool_set_settings(struct net_device *ndev,
+  struct ethtool_cmd *cmd)
+{
+   struct aq_nic_s *aq_nic = (struct aq_nic_s *)netdev_priv(ndev);
+
+   return aq_nic_set_link_settings(aq_nic, cmd);
+}
+
+static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
+   "InPackets",
+   "InUCast",
+   "InMCast",
+   "InBCast",
+   "InErrors",
+   "OutPackets",
+   "OutUCast",
+   "OutMCast",
+   "OutBCast",
+   "InUCastOctects",
+   "OutUCastOctects",
+   "InMCastOctects",
+   "OutMCastOctects",
+   "InBCastOctects",
+   "OutBCastOctects",
+   "InOctects",
+   "OutOctects",
+   "InPacketsDma",
+   "OutPacketsDma",
+   "InOctetsDma",
+   "OutOctetsDma",
+   "InDroppedDma",
+   "Queue[0] InPackets",
+   "Queue[0] OutPackets",
+   "Queue[0] InJumboPackets",
+   "Queue[0] InLroPackets",
+   "Queue[0] InErrors",
+#if 1 < AQ_CFG_VECS_DEF
+   "Queue[1] InPackets",
+   "Queue[1] OutPackets",
+   "Queue[1] InJumboPackets",
+   "Queue[1] InLroPackets",
+   "Queue[1] InErrors",
+#endif
+#if 2 < AQ_CFG_VECS_DEF
+   "Queue[2] InPackets",
+   "Queue[2] OutPackets",
+   "Queue[2] InJumboPackets",
+   "Queue[2] InLroPackets",
+   "Queue[2] InErrors",
+#endif
+#if 3 < AQ_CFG_VECS_DEF
+   "Queue[3] InPackets",
+   "Queue[3] OutPackets",
+   "Queue[3] InJumboPackets",
+   "Queue[3] InLroPackets",
+   "Queue[3] InErrors",
+#endif
+#if 4 < AQ_CFG_VECS_DEF
+   "Queue[4] InPackets",
+   "Queue[4] OutPackets",
+   "Queue[4] InJumboPackets",
+   "Queue[4] InLroPackets",
+   "Queue[4] InErrors",
+#endif
+#if 5 < AQ_CFG_VECS_DEF
+   "Queue[5] InPackets",
+   "Queue[5] OutPackets",
+   "Queue[5] InJumboPackets",
+   "Queue[5] InLroPackets",
+   "Queue[5] InErrors",
+#endif
+#if 6 < AQ_CFG_VECS_DEF
+   "Queue[6] InPackets",
+   "Queue[6] OutPackets",
+   "Queue[6] InJumboPackets",
+   "Queue[6] InLroPackets",
+   "Queue[6] InErrors",
+#endif
+#if 7 < AQ_CFG_VECS_DEF
+   "Queue[7] InPackets",
+   "Queue[7] OutPackets",
+   "Queue[7] InJumboPackets",
+   "Queue[7] InLroPackets",
+   "Queue[7] InErrors",
+#endif
+};
+
+static void aq_ethtool_stats(struct 

[PATCH 08/12] PCI operations

2016-12-27 Thread David VomLehn
Add functions that handle the PCI bus interface.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 .../net/ethernet/aquantia/atlantic/aq_pci_func.c   | 356 +
 .../net/ethernet/aquantia/atlantic/aq_pci_func.h   |  36 +++
 2 files changed, 392 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_pci_func.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
new file mode 100644
index 000..bdd15c8
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
@@ -0,0 +1,356 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_pci_func.c: Definition of PCI functions.
+ */
+
+#include "aq_pci_func.h"
+#include "aq_nic.h"
+#include "aq_vec.h"
+#include "aq_hw.h"
+
+#include 
+#include 
+
+struct aq_pci_func_s {
+   struct pci_dev *pdev;
+   struct aq_nic_s *port[AQ_CFG_PCI_FUNC_PORTS];
+   void __iomem *mmio;
+   void *aq_vec[AQ_CFG_PCI_FUNC_MSIX_IRQS];
+   resource_size_t mmio_pa;
+   unsigned int msix_entry_mask;
+   unsigned int irq_type;
+   unsigned int ports;
+   bool is_pci_enabled;
+   bool is_regions;
+   bool is_pci_using_dac;
+   struct aq_hw_caps_s aq_hw_caps;
+   struct msix_entry msix_entry[AQ_CFG_PCI_FUNC_MSIX_IRQS];
+};
+
+struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops,
+   struct pci_dev *pdev,
+   const struct net_device_ops *ndev_ops,
+   const struct ethtool_ops *eth_ops)
+{
+   struct aq_pci_func_s *self = NULL;
+   int err = 0;
+   unsigned int port = 0U;
+
+   if (!aq_hw_ops) {
+   err = -EFAULT;
+   goto err_exit;
+   }
+   self = kzalloc(sizeof(*self), GFP_KERNEL);
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+
+   pci_set_drvdata(pdev, self);
+   self->pdev = pdev;
+
+   err = aq_hw_ops->get_hw_caps(NULL, >aq_hw_caps);
+   if (err < 0)
+   goto err_exit;
+
+   self->ports = self->aq_hw_caps.ports;
+
+   for (port = 0; port < self->ports; ++port) {
+   struct aq_nic_s *aq_nic = aq_nic_alloc_cold(ndev_ops, eth_ops,
+   >dev, self,
+   port, aq_hw_ops);
+
+   if (!aq_nic) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+   self->port[port] = aq_nic;
+   }
+
+err_exit:
+   if (err < 0) {
+   if (self)
+   aq_pci_func_free(self);
+   self = NULL;
+   }
+
+   (void)err;
+   return self;
+}
+
+int aq_pci_func_init(struct aq_pci_func_s *self)
+{
+   int err = 0;
+   unsigned int bar = 0U;
+   unsigned int port = 0U;
+   unsigned int i = 0U;
+
+   err = pci_enable_device(self->pdev);
+   if (err < 0)
+   goto err_exit;
+
+   self->is_pci_enabled = true;
+
+   err = pci_set_dma_mask(self->pdev, DMA_BIT_MASK(64));
+   if (!err) {
+   err = pci_set_consistent_dma_mask(self->pdev, DMA_BIT_MASK(64));
+   self->is_pci_using_dac = 1;
+   }
+   if (err) {
+   err = pci_set_dma_mask(self->pdev, DMA_BIT_MASK(32));
+   if (!err)
+   err = pci_set_consistent_dma_mask(self->pdev,
+ DMA_BIT_MASK(32));
+   self->is_pci_using_dac = 0;
+   }
+   if (err != 0) {
+   err = -ENOSR;
+   goto err_exit;
+   }
+
+   err = pci_request_regions(self->pdev, AQ_CFG_DRV_NAME "_mmio");
+   if (err < 0)
+   goto err_exit;
+
+   self->is_regions = true;
+
+   pci_set_master(self->pdev);
+
+   for (bar = 0; bar < 4; ++bar) {
+   if (IORESOURCE_MEM & pci_resource_flags(self->pdev, bar)) {
+   resource_size_t reg_sz;
+
+   self->mmio_pa = pci_resource_start(self->pdev, bar);
+   if (self->mmio_pa == 0U) {
+   err = -EIO;
+   goto err_exit;
+   }
+
+   reg_sz = pci_resource_len(self->pdev, bar);
+ 

[PATCH 01/12] Make and configuration files.

2016-12-27 Thread David VomLehn
Patches to create the make and configuration files.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/Kconfig  |  9 ++
 drivers/net/ethernet/aquantia/atlantic/Makefile | 40 +
 drivers/net/ethernet/aquantia/atlantic/ver.h| 18 +++
 3 files changed, 67 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/Kconfig
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/Makefile
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/ver.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/Kconfig 
b/drivers/net/ethernet/aquantia/atlantic/Kconfig
new file mode 100644
index 000..33f1eb6
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/Kconfig
@@ -0,0 +1,9 @@
+#
+# Aquantia device configuration
+#
+
+config AQTION
+   tristate "Aquantia AQtion Support"
+   depends on PCI
+   ---help---
+ This enables the support for the Aquantia AQtion Ethernet card.
\ No newline at end of file
diff --git a/drivers/net/ethernet/aquantia/atlantic/Makefile 
b/drivers/net/ethernet/aquantia/atlantic/Makefile
new file mode 100644
index 000..f0d961f
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/Makefile
@@ -0,0 +1,40 @@
+TARGET:=atlantic
+
+CC = gcc
+
+ifeq "$(CC)" "gcc"
+   ccflags-y := -Wall
+endif
+
+ifneq ($(KERNELRELEASE),)
+   $(TARGET)-objs:=aq_main.o aq_nic.o aq_pci_func.o aq_nic.o aq_vec.o \
+   aq_ring.o aq_hw_utils.o aq_ethtool.o hw_atl/hw_atl_a0.o \
+   hw_atl/hw_atl_utils.o hw_atl/hw_atl_llh.o
+
+   obj-m:=$(TARGET).o
+else
+   ifndef KDIR
+   BUILD_DIR:=/lib/modules/$(shell uname -r)/build
+   else
+   BUILD_DIR:=$(KDIR)
+   endif
+
+   PWD:=$(shell pwd)
+
+all:
+   $(MAKE) -j4 CC=$(CC) -C $(BUILD_DIR) M=$(PWD) modules
+
+dox:   .doxygen
+   @doxygen $<
+
+clean:
+   $(MAKE) -j4 -C $(BUILD_DIR) M=$(PWD) clean
+   @-rm -rdf doc/html 2 > /dev/null
+
+load:
+   insmod ./$(TARGET).ko
+
+unload:
+   rmmod ./$(TARGET).ko
+
+endif
diff --git a/drivers/net/ethernet/aquantia/atlantic/ver.h 
b/drivers/net/ethernet/aquantia/atlantic/ver.h
new file mode 100644
index 000..225f561
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/ver.h
@@ -0,0 +1,18 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef VER_H
+#define VER_H
+
+#define NIC_MAJOR_DRIVER_VERSION   1
+#define NIC_MINOR_DRIVER_VERSION   4
+#define NIC_BUILD_DRIVER_VERSION   1671
+#define NIC_REVISION_DRIVER_VERSION0
+
+#endif /* VER_H */
-- 
2.7.4



[PATCH 03/12] Add ring spport code

2016-12-27 Thread David VomLehn
Add code to support the firmware transmit and receive ring buffers.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 383 +++
 drivers/net/ethernet/aquantia/atlantic/aq_ring.h | 150 +
 2 files changed, 533 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_ring.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_ring.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
new file mode 100644
index 000..bec5fcc
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c
@@ -0,0 +1,383 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_pci_ring.c: Definition of functions for Rx/Tx rings.
+ */
+
+#include "aq_ring.h"
+#include "aq_nic.h"
+#include "aq_hw.h"
+
+#include 
+#include 
+
+static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self,
+  struct aq_nic_s *aq_nic,
+  struct aq_nic_cfg_s *aq_nic_cfg)
+{
+   int err = 0;
+
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+   self->buff_ring = (struct aq_ring_buff_s *)
+   kzalloc(sizeof(struct aq_ring_buff_s) * self->size, GFP_KERNEL);
+
+   if (!self->buff_ring) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+   self->dx_ring = dma_alloc_coherent(aq_nic_get_dev(aq_nic),
+   self->size * self->dx_size,
+   >dx_ring_pa, GFP_KERNEL);
+   if (!self->dx_ring) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+
+err_exit:
+   if (err < 0) {
+   aq_ring_free(self);
+   self = NULL;
+   }
+   return self;
+}
+
+struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self,
+  struct aq_nic_s *aq_nic,
+  unsigned int idx,
+  struct aq_nic_cfg_s *aq_nic_cfg)
+{
+   int err = 0;
+
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+   self->aq_nic = aq_nic;
+   self->idx = idx;
+   self->size = aq_nic_cfg->txds;
+   self->dx_size = aq_nic_cfg->aq_hw_caps->txd_size;
+
+   self = aq_ring_alloc(self, aq_nic, aq_nic_cfg);
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+
+err_exit:
+   if (err < 0) {
+   aq_ring_free(self);
+   self = NULL;
+   }
+   return self;
+}
+
+struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self,
+  struct aq_nic_s *aq_nic,
+  unsigned int idx,
+  struct aq_nic_cfg_s *aq_nic_cfg)
+{
+   int err = 0;
+
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+   self->aq_nic = aq_nic;
+   self->idx = idx;
+   self->size = aq_nic_cfg->rxds;
+   self->dx_size = aq_nic_cfg->aq_hw_caps->rxd_size;
+
+   self = aq_ring_alloc(self, aq_nic, aq_nic_cfg);
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+
+err_exit:
+   if (err < 0) {
+   aq_ring_free(self);
+   self = NULL;
+   }
+   return self;
+}
+
+int aq_ring_init(struct aq_ring_s *self)
+{
+   self->hw_head = 0;
+   self->sw_head = 0;
+   self->sw_tail = 0;
+   return 0;
+}
+
+int aq_ring_deinit(struct aq_ring_s *self)
+{
+   return 0;
+}
+
+void aq_ring_free(struct aq_ring_s *self)
+{
+   if (!self)
+   goto err_exit;
+
+   kfree(self->buff_ring);
+
+   if (self->dx_ring)
+   dma_free_coherent(aq_nic_get_dev(self->aq_nic),
+ self->size * self->dx_size, self->dx_ring,
+ self->dx_ring_pa);
+
+err_exit:;
+}
+
+void aq_ring_tx_append_buffs(struct aq_ring_s *self,
+struct aq_ring_buff_s *buffer,
+unsigned int buffers)
+{
+   if (likely(self->sw_tail + buffers < self->size))
+   memcpy(>buff_ring[self->sw_tail], buffer,
+  sizeof(buffer[0]) * buffers);
+   else {
+   unsigned int first_part = self->size - self->sw_tail;
+   unsigned int second_part = 

[PATCH 10/12] Hardware interface and utility functions

2016-12-27 Thread David VomLehn
Add functions to interface with the hardware and some utility functions.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 170 +
 .../net/ethernet/aquantia/atlantic/aq_hw_utils.c   |  70 +
 .../net/ethernet/aquantia/atlantic/aq_hw_utils.h   |  54 +++
 3 files changed, 294 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_hw.h
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_hw_utils.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
new file mode 100644
index 000..15e35b1
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -0,0 +1,170 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_hw.h: Declaraion of abstract interface for NIC hardware specific
+ * functions.
+ */
+
+#ifndef AQ_HW_H
+#define AQ_HW_H
+
+#include "aq_common.h"
+
+/* NIC H/W capabilities */
+struct aq_hw_caps_s {
+   u64 hw_features;
+   u64 link_speed_msk;
+   unsigned int hw_priv_flags;
+   u32 rxds;
+   u32 txds;
+   u32 txhwb_alignment;
+   u32 irq_mask;
+   u32 vecs;
+   u32 mtu;
+   u32 mac_regs_count;
+   u8 ports;
+   u8 msix_irqs;
+   u8 tcs;
+   u8 rxd_alignment;
+   u8 rxd_size;
+   u8 txd_alignment;
+   u8 txd_size;
+   u8 tx_rings;
+   u8 rx_rings;
+   bool flow_control;
+   bool is_64_dma;
+};
+
+struct aq_hw_link_status_s {
+   u64 bps;
+};
+
+#define AQ_HW_POWER_STATE_D0   0U
+#define AQ_HW_POWER_STATE_D3   3U
+
+#define AQ_HW_FLAG_STARTED 0x0004U
+#define AQ_HW_FLAG_STOPPING0x0008U
+#define AQ_HW_FLAG_RESETTING   0x0010U
+#define AQ_HW_FLAG_CLOSING 0x0020U
+#define AQ_HW_LINK_DOWN0x0400U
+#define AQ_HW_FLAG_ERR_UNPLUG  0x4000U
+#define AQ_HW_FLAG_ERR_HW  0x8000U
+
+#define AQ_HW_FLAG_ERRORS  (AQ_HW_FLAG_ERR_HW | AQ_HW_FLAG_ERR_UNPLUG)
+
+struct aq_hw_s {
+   AQ_OBJ_HEADER;
+   struct aq_nic_cfg_s *aq_nic_cfg;
+   struct aq_pci_func_s *aq_pci_func;
+   void __iomem *mmio;
+   unsigned int not_ff_addr;
+   struct aq_hw_link_status_s aq_link_status;
+};
+
+struct aq_ring_s;
+struct aq_ring_param_s;
+struct aq_nic_cfg_s;
+struct sk_buff;
+
+struct aq_hw_ops {
+   struct aq_hw_s *(*create)(struct aq_pci_func_s *aq_pci_func,
+ unsigned int port, struct aq_hw_ops *ops);
+
+   void (*destroy)(struct aq_hw_s *self);
+
+   int (*get_hw_caps)(struct aq_hw_s *self,
+  struct aq_hw_caps_s *aq_hw_caps);
+
+   int (*hw_ring_tx_xmit)(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
+  unsigned int frags);
+
+   int (*hw_ring_rx_receive)(struct aq_hw_s *self,
+ struct aq_ring_s *aq_ring);
+
+   int (*hw_ring_rx_fill)(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
+  unsigned int sw_tail_old);
+
+   int (*hw_ring_tx_head_update)(struct aq_hw_s *self,
+ struct aq_ring_s *aq_ring);
+
+   int (*hw_get_mac_permanent)(struct aq_hw_s *self, u8 *mac);
+
+   int (*hw_set_mac_address)(struct aq_hw_s *self, u8 *mac_addr);
+
+   int (*hw_get_link_status)(struct aq_hw_s *self,
+ struct aq_hw_link_status_s *link_status);
+
+   int (*hw_set_link_speed)(struct aq_hw_s *self, u32 speed);
+
+   int (*hw_reset)(struct aq_hw_s *self);
+
+   int (*hw_init)(struct aq_hw_s *self, struct aq_nic_cfg_s *aq_nic_cfg,
+  u8 *mac_addr);
+
+   int (*hw_start)(struct aq_hw_s *self);
+
+   int (*hw_stop)(struct aq_hw_s *self);
+
+   int (*hw_ring_tx_init)(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
+  struct aq_ring_param_s *aq_ring_param);
+
+   int (*hw_ring_tx_start)(struct aq_hw_s *self,
+   struct aq_ring_s *aq_ring);
+
+   int (*hw_ring_tx_stop)(struct aq_hw_s *self,
+  struct aq_ring_s *aq_ring);
+
+   int (*hw_ring_rx_init)(struct aq_hw_s *self,
+  struct aq_ring_s *aq_ring,
+  struct aq_ring_param_s *aq_ring_param);
+
+   int (*hw_ring_rx_start)(struct aq_hw_s *self,
+   struct aq_ring_s *aq_ring);
+
+   

[PATCH 12/12] Receive side scaling

2016-12-27 Thread David VomLehn
Add definitions that support receive side scaling.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/aq_rss.h | 35 +
 1 file changed, 35 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_rss.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_rss.h 
b/drivers/net/ethernet/aquantia/atlantic/aq_rss.h
new file mode 100644
index 000..181d373
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_rss.h
@@ -0,0 +1,35 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_rss.h: Receive Side Scaling definitions.
+ */
+
+#ifndef AQ_RSS_H
+#define AQ_RSS_H
+
+#include "aq_common.h"
+#include "aq_cfg.h"
+
+#define HASH_TYPE_IPV4  0x0100U
+#define HASH_TYPE_TCP_IPV4  0x0200U
+#define HASH_TYPE_IPV6  0x0400U
+#define HASH_TYPE_IPV6_EX   0x0800U
+#define HASH_TYPE_TCP_IPV6  0x1000U
+#define HASH_TYPE_TCP_IPV6_EX   0x2000U
+
+struct aq_receive_scale_parameters {
+   u16 base_cpu_number;
+   u16 indirection_table_size;
+   u16 hash_secret_key_size;
+   u32 hash_secret_key[AQ_CFG_RSS_HASHKEY_SIZE / sizeof(u32)];
+   u8 indirection_table[AQ_CFG_RSS_INDIRECTION_TABLE_MAX];
+};
+
+#endif /* AQ_RSS_H */
-- 
2.7.4



[PATCH 07/12] Vector operations

2016-12-27 Thread David VomLehn
Add functions to manululate the vector of receive and transmit rings.

Signed-off-by: Dmitrii Tarakanov 
Signed-off-by: Alexander Loktionov 
Signed-off-by: David M. VomLehn 
---
 drivers/net/ethernet/aquantia/atlantic/aq_vec.c | 375 
 drivers/net/ethernet/aquantia/atlantic/aq_vec.h |  40 +++
 2 files changed, 415 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_vec.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/aq_vec.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c 
b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
new file mode 100644
index 000..c8340d7
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -0,0 +1,375 @@
+//err_exit:
+//err_exit:
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File aq_vec.c: Definition of common structure for vector of Rx and Tx rings.
+ * Definition of functions for Rx and Tx rings. Friendly module for aq_nic.
+ */
+
+#include "aq_vec.h"
+#include "aq_nic.h"
+#include "aq_ring.h"
+#include "aq_hw.h"
+
+#include 
+
+struct aq_vec_s {
+   AQ_OBJ_HEADER;
+   struct aq_hw_ops *aq_hw_ops;
+   struct aq_hw_s *aq_hw;
+   struct aq_nic_s *aq_nic;
+   unsigned int tx_rings;
+   unsigned int rx_rings;
+   struct aq_ring_param_s aq_ring_param;
+   struct napi_struct napi;
+   struct aq_ring_s ring[AQ_CFG_TCS_MAX][2];
+};
+
+#define AQ_VEC_TX_ID 0
+#define AQ_VEC_RX_ID 1
+
+struct aq_vec_s *aq_vec_alloc(struct aq_nic_s *aq_nic, unsigned int idx,
+ struct aq_nic_cfg_s *aq_nic_cfg)
+{
+   struct aq_vec_s *self = NULL;
+   struct aq_ring_s *ring = NULL;
+   unsigned int i = 0U;
+   int err = 0;
+
+   self = kzalloc(sizeof(*self), GFP_KERNEL);
+   if (!self) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+
+   self->aq_nic = aq_nic;
+   self->aq_ring_param.vec_idx = idx;
+   self->aq_ring_param.cpu =
+   idx + aq_nic_cfg->aq_rss.base_cpu_number;
+
+   cpumask_set_cpu(self->aq_ring_param.cpu,
+   >aq_ring_param.affinity_mask);
+
+   self->tx_rings = 0;
+   self->rx_rings = 0;
+
+   netif_napi_add(aq_nic_get_ndev(aq_nic), >napi,
+  aq_vec_poll, AQ_CFG_NAPI_WEIGHT);
+
+   for (i = 0; i < aq_nic_cfg->tcs; ++i) {
+   unsigned int idx_ring = AQ_NIC_TCVEC2RING(self->nic,
+   self->tx_rings,
+   self->aq_ring_param.vec_idx);
+
+   ring = aq_ring_tx_alloc(>ring[i][AQ_VEC_TX_ID], aq_nic,
+   idx_ring, aq_nic_cfg);
+   if (!ring) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+
+   ++self->tx_rings;
+
+   aq_nic_set_tx_ring(aq_nic, idx_ring, ring);
+
+   ring = aq_ring_rx_alloc(>ring[i][AQ_VEC_RX_ID], aq_nic,
+   idx_ring, aq_nic_cfg);
+   if (!ring) {
+   err = -ENOMEM;
+   goto err_exit;
+   }
+
+   ++self->rx_rings;
+   }
+
+err_exit:
+   if (err < 0) {
+   aq_vec_free(self);
+   self = NULL;
+   }
+   return self;
+}
+
+int aq_vec_init(struct aq_vec_s *self, struct aq_hw_ops *aq_hw_ops,
+   struct aq_hw_s *aq_hw)
+{
+   struct aq_ring_s *ring = NULL;
+   unsigned int i = 0U;
+   int err = 0;
+
+   self->aq_hw_ops = aq_hw_ops;
+   self->aq_hw = aq_hw;
+
+   spin_lock_init(>lock);
+
+   for (i = 0U, ring = self->ring[0];
+   self->tx_rings > i; ++i, ring = self->ring[i]) {
+   err = aq_ring_init([AQ_VEC_TX_ID]);
+   if (err < 0)
+   goto err_exit;
+
+   err = self->aq_hw_ops->hw_ring_tx_init(self->aq_hw,
+  [AQ_VEC_TX_ID],
+  >aq_ring_param);
+   if (err < 0)
+   goto err_exit;
+
+   err = aq_ring_init([AQ_VEC_RX_ID]);
+   if (err < 0)
+   goto err_exit;
+
+   err = self->aq_hw_ops->hw_ring_rx_init(self->aq_hw,
+  [AQ_VEC_RX_ID],
+  >aq_ring_param);
+   if (err < 0)
+   goto err_exit;
+
+   err = 

Re: [PATCH] net: stmmac: fix incorrect bit set in gmac4 mdio addr register

2016-12-27 Thread Joao Pinto
Às 8:07 PM de 12/27/2016, Kweh, Hock Leong escreveu:
> From: "Kweh, Hock Leong" 
> 
> Fixing the gmac4 mdio write access to use MII_GMAC4_WRITE only instead of
> OR together with MII_WRITE.
> 
> Signed-off-by: Kweh, Hock Leong 
> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> index fda01f7..b0344c2 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> @@ -116,7 +116,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int 
> phyaddr, int phyreg,
>   unsigned int mii_address = priv->hw->mii.addr;
>   unsigned int mii_data = priv->hw->mii.data;
>  
> - u32 value = MII_WRITE | MII_BUSY;
> + u32 value = MII_BUSY;
>  
>   value |= (phyaddr << priv->hw->mii.addr_shift)
>   & priv->hw->mii.addr_mask;
> @@ -126,6 +126,8 @@ static int stmmac_mdio_write(struct mii_bus *bus, int 
> phyaddr, int phyreg,
>   & priv->hw->mii.clk_csr_mask;
>   if (priv->plat->has_gmac4)
>   value |= MII_GMAC4_WRITE;
> + else
> + value |= MII_WRITE;
>  
>   /* Wait until any existing MII operation is complete */
>   if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
> 

Acked-By: Joao Pinto 


[PATCH] net: stmmac: fix incorrect bit set in gmac4 mdio addr register

2016-12-27 Thread Kweh, Hock Leong
From: "Kweh, Hock Leong" 

Fixing the gmac4 mdio write access to use MII_GMAC4_WRITE only instead of
OR together with MII_WRITE.

Signed-off-by: Kweh, Hock Leong 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index fda01f7..b0344c2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -116,7 +116,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int 
phyaddr, int phyreg,
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
 
-   u32 value = MII_WRITE | MII_BUSY;
+   u32 value = MII_BUSY;
 
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
@@ -126,6 +126,8 @@ static int stmmac_mdio_write(struct mii_bus *bus, int 
phyaddr, int phyreg,
& priv->hw->mii.clk_csr_mask;
if (priv->plat->has_gmac4)
value |= MII_GMAC4_WRITE;
+   else
+   value |= MII_WRITE;
 
/* Wait until any existing MII operation is complete */
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
-- 
1.7.9.5



Platform init code in stmmac_main

2016-12-27 Thread Joao Pinto
Hello,

I spotted in stmmac_main.c, *_dvr_probe() function, some clocks initializations
that are related with platform based setups:


priv->pclk = devm_clk_get(priv->device, "pclk");
if (IS_ERR(priv->pclk)) {
if (PTR_ERR(priv->pclk) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto error_pclk_get;
}
priv->pclk = NULL;
}
clk_prepare_enable(priv->pclk);

priv->stmmac_rst = devm_reset_control_get(priv->device,
  STMMAC_RESOURCE_NAME);
if (IS_ERR(priv->stmmac_rst)) {
if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto error_hw_init;
}
dev_info(priv->device, "no reset control found\n");
priv->stmmac_rst = NULL;
}
if (priv->stmmac_rst)
reset_control_deassert(priv->stmmac_rst);

I am using PCI based setup, so these initializations are executed since they are
in common space in stmmac_main.c. Wouldn't be better to map these clocks in
stmmac_platform? This hasn't any problem for me, but I think it would improve
code readbility.

I would like to have your opinion about the subject!

Thanks,
Joao


Re: [PATCH v2] net: stmmac: bug fix to synchronize stmmac_open and stmmac_dvr_probe

2016-12-27 Thread Pavel Machek
On Tue 2016-12-27 22:42:36, Kweh, Hock Leong wrote:
> From: "Kweh, Hock Leong" 
> 
> If kernel module stmmac driver being loaded after OS booted, there is a
> race condition between stmmac_open() and stmmac_mdio_register(), which is
> invoked inside stmmac_dvr_probe(), and the error is showed in dmesg log as
> PHY not found and stmmac_open() failed:
> [  473.919358] stmmaceth :01:00.0 (unnamed net_device) (uninitialized):
> stmmac_dvr_probe: warning: cannot get CSR clock
> [  473.919382] stmmaceth :01:00.0: no reset control found
> [  473.919412] stmmac - user ID: 0x10, Synopsys ID: 0x42
> [  473.919429] stmmaceth :01:00.0: DMA HW capability register supported
> [  473.919436] stmmaceth :01:00.0: RX Checksum Offload Engine supported
> [  473.919443] stmmaceth :01:00.0: TX Checksum insertion supported
> [  473.919451] stmmaceth :01:00.0 (unnamed net_device) (uninitialized):
> Enable RX Mitigation via HW Watchdog Timer
> [  473.921395] libphy: PHY stmmac-1:00 not found
> [  473.921417] stmmaceth :01:00.0 eth0: Could not attach to PHY
> [  473.921427] stmmaceth :01:00.0 eth0: stmmac_open: Cannot attach to
> PHY (error: -19)
> [  473.959710] libphy: stmmac: probed
> [  473.959724] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 0 IRQ POLL
> (stmmac-1:00) active
> [  473.959728] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 1 IRQ POLL
> (stmmac-1:01)
> [  473.959731] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 2 IRQ POLL
> (stmmac-1:02)
> [  473.959734] stmmaceth :01:00.0 eth0: PHY ID 01410cc2 at 3 IRQ POLL
> (stmmac-1:03)
> 
> The resolution moved the register_netdev() function call to the end of
> stmmac_dvr_probe() after stmmac_mdio_register().
> 
> Suggested-by: Florian Fainelli 
> Signed-off-by: Kweh, Hock Leong 

Acked-by: Pavel Machek 

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) 
http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html


signature.asc
Description: Digital signature


Re: [PATCH] net: fix incorrect original ingress device index in PKTINFO

2016-12-27 Thread Sergei Shtylyov

Hello!

On 12/27/2016 10:52 AM, Wei Zhang wrote:


When we send a packet for our own local address on a non-loopback interface
(e.g. eth0), due to the change had been introduced from commit 0b922b7a829c
("net: original ingress device index in PKTINFO"), the original ingress
device index would be set as the loopback interface. However, the packet
should be considered as if it is being arrived via the sending interface
(eth0), otherwise it would break the expectation of the userspace
application (e.g. the DHCPRELEASE message from dhcp_release binary would
be ignored by the dnsmasq daemon)

Signed-off-by: Wei Zhang 
---
 net/ipv4/ip_sockglue.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index b8a2d63..b6a6d35 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1202,8 +1202,13 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct 
sk_buff *skb)
 * which has interface index (iif) as the first member of the
 * underlying inet{6}_skb_parm struct. This code then overlays
 * PKTINFO_SKB_CB and in_pktinfo also has iif as the first
-* element so the iif is picked up from the prior IPCB
+* element so the iif is picked up from the prior IPCB except
+* iif is loopback interface which the packet should be


   Tail space.


+* considered as if it is being arrived via the sending 
interface
 */
+   if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX) {
+   pktinfo->ipi_ifindex = inet_iif(skb);
+   }


   {} not needed here.


pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
} else {
pktinfo->ipi_ifindex = 0;


MBR, Sergei



  1   2   >