* Re: net/netfilter/nf_conntrack_proto_tcp.c:1606:9: error: ‘struct nf_proto_net’ has no member named ‘user’
From: Pablo Neira Ayuso @ 2012-06-12 9:29 UTC (permalink / raw)
To: Gao feng; +Cc: David Miller, wfg, netdev
In-Reply-To: <4FD69F5E.3060900@cn.fujitsu.com>
On Tue, Jun 12, 2012 at 09:46:06AM +0800, Gao feng wrote:
> 于 2012年06月12日 08:26, Pablo Neira Ayuso 写道:
> > Hi again David,
> >
> > On Mon, Jun 11, 2012 at 03:23:44PM -0700, David Miller wrote:
> >> From: Pablo Neira Ayuso <pablo@netfilter.org>
> >> Date: Tue, 12 Jun 2012 00:15:21 +0200
> >>
> >>> Could you please apply the following patch to net-next to resolve
> >>> this? Thanks.
> >>
> >> Applied, but you have to be kidding me with those ifdefs.
> >>
> >> This is exactly the same kind of thing Gao suggested for
> >> the inetpeer code recently and which I flat out rejected.
> >>
> >> You can't pepper foo.c files with ifdefs all over the place.
> >
> > Would you be OK if I send you patches to move all sysctl part of
> > nf_conntrack_proto_*.c to nf_conntrack_proto_*_sysctl.c
> >
> > I can also do the same for nf_conntrack_proto.c.
> >
> > This means more files under the net/netfilter directory, but less
> > ifdef kludges in the code.
> >
> > Please, have a look at the patch enclosed to this email in case you
> > want to see how it would look like in the end with my proposal.
>
> I am sorry for all the trouble aroused by my negligence.
>
> > static int tcpv4_init_net(struct net *net)
> > {
> > int i;
> > @@ -1600,11 +1373,7 @@ static int tcpv4_init_net(struct net *net)
> > struct nf_tcp_net *tn = tcp_pernet(net);
> > struct nf_proto_net *pn = (struct nf_proto_net *)tn;
> >
> > -#ifdef CONFIG_SYSCTL
> > - if (!pn->ctl_table) {
> > -#else
> > if (!pn->users++) {
>
> nf_proto_net.users has different meaning when SYSCTL enabled or disabled.
>
> when SYSCTL enabled,it means if both tcpv4 and tcpv6 register the sysctl,
> it is increased when register sysctl success and decreased when unregister sysctl.
> we can regard it as the refcnt of ctl_table.
>
> when SYSCTL disabled,it just used to identify if the proto's pernet data
> has been initialized.
We have to use two different counters for this. The conditional
meaning of that variable is really confusing.
^ permalink raw reply
* Re: Difficulties to get 1Gbps on be2net ethernet card
From: Jean-Michel Hautbois @ 2012-06-12 9:10 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Sathya.Perla, netdev
In-Reply-To: <1339491979.22704.23.camel@edumazet-glaptop>
2012/6/12 Eric Dumazet <eric.dumazet@gmail.com>:
> On Tue, 2012-06-12 at 11:01 +0200, Jean-Michel Hautbois wrote:
>
>> Can I do that using netperf ?
>
>
> Sure, you could use netperf -t UDP_RR
>
>
It sends, but no change on TX...
^ permalink raw reply
* Re: Possible deadlock in ipv6?
From: Eric Dumazet @ 2012-06-12 9:09 UTC (permalink / raw)
To: David Miller; +Cc: vdavydov, netdev
In-Reply-To: <20120611.235453.953830769326224643.davem@davemloft.net>
On Mon, 2012-06-11 at 23:54 -0700, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Wed, 06 Jun 2012 17:58:34 +0200
>
> > And it seems this neigh_down() can be removed, its called later
> > (after dev->ip6_ptr is cleared)
>
> It is unclear whether we need to do the the neigh_down() in both
> the 'how' and '!how' cases. If so then we can't make this change.
>
Hmm...
Is it expected we send traffic on device dismantle ?
If no, we could do :
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d81d026..16e0ddb 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -681,8 +681,6 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
while ((n = *np) != NULL) {
if (!dev || n->dev == dev) {
*np = n->next;
- if (tbl->pdestructor)
- tbl->pdestructor(n);
if (n->dev)
dev_put(n->dev);
release_net(pneigh_net(n));
^ permalink raw reply related
* Re: Difficulties to get 1Gbps on be2net ethernet card
From: Eric Dumazet @ 2012-06-12 9:06 UTC (permalink / raw)
To: Jean-Michel Hautbois; +Cc: Sathya.Perla, netdev
In-Reply-To: <CAL8zT=hKmnAG7kZE18noFNEksibvJpR_6Q9z59nGLhqbs5oxuw@mail.gmail.com>
On Tue, 2012-06-12 at 11:01 +0200, Jean-Michel Hautbois wrote:
> Can I do that using netperf ?
Sure, you could use netperf -t UDP_RR
^ permalink raw reply
* Re: Difficulties to get 1Gbps on be2net ethernet card
From: Jean-Michel Hautbois @ 2012-06-12 9:01 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Sathya.Perla, netdev
In-Reply-To: <1339491345.22704.22.camel@edumazet-glaptop>
2012/6/12 Eric Dumazet <eric.dumazet@gmail.com>:
> On Tue, 2012-06-12 at 10:24 +0200, Jean-Michel Hautbois wrote:
>> 2012/6/8 Jean-Michel Hautbois <jhautbois@gmail.com>:
>> > 2012/6/8 Eric Dumazet <eric.dumazet@gmail.com>:
>> >> On Fri, 2012-06-08 at 10:14 +0200, Jean-Michel Hautbois wrote:
>> >>> 2012/6/8 Eric Dumazet <eric.dumazet@gmail.com>:
>> >>> > On Thu, 2012-06-07 at 14:54 +0200, Jean-Michel Hautbois wrote:
>> >>> >
>> >>> >> eth1 Link encap:Ethernet HWaddr 68:b5:99:b9:8d:d4
>> >>> >> UP BROADCAST RUNNING SLAVE MULTICAST MTU:4096 Metric:1
>> >>> >> RX packets:0 errors:0 dropped:0 overruns:0 frame:0
>> >>> >> TX packets:15215387 errors:0 dropped:0 overruns:0 carrier:0
>> >>> >> collisions:0 txqueuelen:1000
>> >>> >> RX bytes:0 (0.0 B) TX bytes:61476524359 (57.2 GiB)
>> >>> >
>> >>> >> qdisc mq 0: dev eth1 root
>> >>> >> Sent 61476524359 bytes 15215387 pkt (dropped 45683472, overlimits 0
>> >>> >> requeues 17480)
>> >>> >
>> >>> > OK, and "tc -s -d cl show dev eth1"
>> >>> >
>> >>> > (How many queues are really used)
>> >>> >
>> >>> >
>> >>> >
>> >>>
>> >>> tc -s -d cl show dev eth1
>> >>> class mq :1 root
>> >>> Sent 9798071746 bytes 2425410 pkt (dropped 3442405, overlimits 0 requeues 2747)
>> >>> backlog 0b 0p requeues 2747
>> >>> class mq :2 root
>> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> >>> backlog 0b 0p requeues 0
>> >>> class mq :3 root
>> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> >>> backlog 0b 0p requeues 0
>> >>> class mq :4 root
>> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> >>> backlog 0b 0p requeues 0
>> >>> class mq :5 root
>> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> >>> backlog 0b 0p requeues 0
>> >>> class mq :6 root
>> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> >>> backlog 0b 0p requeues 0
>> >>> class mq :7 root
>> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> >>> backlog 0b 0p requeues 0
>> >>> class mq :8 root
>> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> >>> backlog 0b 0p requeues 0
>> >>
>> >>
>> >> Do you have the same distribution on old kernels as well ?
>> >> (ie only queue 0 is used)
>> >>
>> >>
>> >>
>> >
>> > On the old kernel, there is nothing returned by this command.
>> >
>> > JM
>>
>> I used perf in order to get more information.
>
> What happens if you force some traffic in the other way (say 50.000
> (small) packets per second in RX) while doing your tests ?
>
Can I do that using netperf ?
^ permalink raw reply
* Re: Difficulties to get 1Gbps on be2net ethernet card
From: Eric Dumazet @ 2012-06-12 8:55 UTC (permalink / raw)
To: Jean-Michel Hautbois; +Cc: Sathya.Perla, netdev
In-Reply-To: <CAL8zT=gNtcdyyVcPt5hB6jyF1btzQArEuZgVKWkb0Wd=a4LcVA@mail.gmail.com>
On Tue, 2012-06-12 at 10:24 +0200, Jean-Michel Hautbois wrote:
> 2012/6/8 Jean-Michel Hautbois <jhautbois@gmail.com>:
> > 2012/6/8 Eric Dumazet <eric.dumazet@gmail.com>:
> >> On Fri, 2012-06-08 at 10:14 +0200, Jean-Michel Hautbois wrote:
> >>> 2012/6/8 Eric Dumazet <eric.dumazet@gmail.com>:
> >>> > On Thu, 2012-06-07 at 14:54 +0200, Jean-Michel Hautbois wrote:
> >>> >
> >>> >> eth1 Link encap:Ethernet HWaddr 68:b5:99:b9:8d:d4
> >>> >> UP BROADCAST RUNNING SLAVE MULTICAST MTU:4096 Metric:1
> >>> >> RX packets:0 errors:0 dropped:0 overruns:0 frame:0
> >>> >> TX packets:15215387 errors:0 dropped:0 overruns:0 carrier:0
> >>> >> collisions:0 txqueuelen:1000
> >>> >> RX bytes:0 (0.0 B) TX bytes:61476524359 (57.2 GiB)
> >>> >
> >>> >> qdisc mq 0: dev eth1 root
> >>> >> Sent 61476524359 bytes 15215387 pkt (dropped 45683472, overlimits 0
> >>> >> requeues 17480)
> >>> >
> >>> > OK, and "tc -s -d cl show dev eth1"
> >>> >
> >>> > (How many queues are really used)
> >>> >
> >>> >
> >>> >
> >>>
> >>> tc -s -d cl show dev eth1
> >>> class mq :1 root
> >>> Sent 9798071746 bytes 2425410 pkt (dropped 3442405, overlimits 0 requeues 2747)
> >>> backlog 0b 0p requeues 2747
> >>> class mq :2 root
> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> >>> backlog 0b 0p requeues 0
> >>> class mq :3 root
> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> >>> backlog 0b 0p requeues 0
> >>> class mq :4 root
> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> >>> backlog 0b 0p requeues 0
> >>> class mq :5 root
> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> >>> backlog 0b 0p requeues 0
> >>> class mq :6 root
> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> >>> backlog 0b 0p requeues 0
> >>> class mq :7 root
> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> >>> backlog 0b 0p requeues 0
> >>> class mq :8 root
> >>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
> >>> backlog 0b 0p requeues 0
> >>
> >>
> >> Do you have the same distribution on old kernels as well ?
> >> (ie only queue 0 is used)
> >>
> >>
> >>
> >
> > On the old kernel, there is nothing returned by this command.
> >
> > JM
>
> I used perf in order to get more information.
What happens if you force some traffic in the other way (say 50.000
(small) packets per second in RX) while doing your tests ?
^ permalink raw reply
* Re: [PATCH v2] net/sh-eth: Add support selecting MII function for SH7734 and R8A7740
From: Florian Fainelli @ 2012-06-12 8:40 UTC (permalink / raw)
To: Nobuhiro Iwamatsu; +Cc: netdev
In-Reply-To: <1339486142-32480-1-git-send-email-nobuhiro.iwamatsu.yj@renesas.com>
On Tuesday 12 June 2012 16:29:02 Nobuhiro Iwamatsu wrote:
> Ethernet IP of SH7734 and R8A7740 has selecting MII register.
> The user needs to change a value according to MII to be used.
> This adds the function to change the value of this register.
>
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
> ---
> V2: Fix the check by select_mii.
> drivers/net/ethernet/renesas/sh_eth.c | 106
++++++++++++++++++++-------------
> drivers/net/ethernet/renesas/sh_eth.h | 1 +
> 2 files changed, 65 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/net/ethernet/renesas/sh_eth.c
b/drivers/net/ethernet/renesas/sh_eth.c
> index be3c221..5358804 100644
> --- a/drivers/net/ethernet/renesas/sh_eth.c
> +++ b/drivers/net/ethernet/renesas/sh_eth.c
> @@ -49,6 +49,33 @@
> NETIF_MSG_RX_ERR| \
> NETIF_MSG_TX_ERR)
>
> +#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
|| \
> + defined(CONFIG_ARCH_R8A7740)
> +static void sh_eth_select_mii(struct net_device *ndev)
> +{
> + u32 value = 0x0;
> + struct sh_eth_private *mdp = netdev_priv(ndev);
> +
> + switch (mdp->phy_interface) {
> + case PHY_INTERFACE_MODE_GMII:
> + value = 0x2;
> + break;
> + case PHY_INTERFACE_MODE_MII:
> + value = 0x1;
> + break;
> + case PHY_INTERFACE_MODE_RMII:
> + value = 0x0;
> + break;
> + default:
> + pr_warn("PHY interface mode was not setup. Set to MII.\n");
> + value = 0x1;
> + break;
> + }
> +
> + sh_eth_write(ndev, value, RMII_MII);
> +}
> +#endif
> +
> /* There is CPU dependent code */
> #if defined(CONFIG_CPU_SUBTYPE_SH7724)
> #define SH_ETH_RESET_DEFAULT 1
> @@ -283,6 +310,7 @@ static struct sh_eth_cpu_data
*sh_eth_get_cpu_data(struct sh_eth_private *mdp)
> #elif defined(CONFIG_CPU_SUBTYPE_SH7734) ||
defined(CONFIG_CPU_SUBTYPE_SH7763)
> #define SH_ETH_HAS_TSU 1
> static void sh_eth_reset_hw_crc(struct net_device *ndev);
> +
> static void sh_eth_chip_reset(struct net_device *ndev)
> {
> struct sh_eth_private *mdp = netdev_priv(ndev);
> @@ -292,35 +320,6 @@ static void sh_eth_chip_reset(struct net_device *ndev)
> mdelay(1);
> }
>
> -static void sh_eth_reset(struct net_device *ndev)
> -{
> - int cnt = 100;
> -
> - sh_eth_write(ndev, EDSR_ENALL, EDSR);
> - sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
> - while (cnt > 0) {
> - if (!(sh_eth_read(ndev, EDMR) & 0x3))
> - break;
> - mdelay(1);
> - cnt--;
> - }
> - if (cnt == 0)
> - printk(KERN_ERR "Device reset fail\n");
> -
> - /* Table Init */
> - sh_eth_write(ndev, 0x0, TDLAR);
> - sh_eth_write(ndev, 0x0, TDFAR);
> - sh_eth_write(ndev, 0x0, TDFXR);
> - sh_eth_write(ndev, 0x0, TDFFR);
> - sh_eth_write(ndev, 0x0, RDLAR);
> - sh_eth_write(ndev, 0x0, RDFAR);
> - sh_eth_write(ndev, 0x0, RDFXR);
> - sh_eth_write(ndev, 0x0, RDFFR);
> -
> - /* Reset HW CRC register */
> - sh_eth_reset_hw_crc(ndev);
> -}
> -
> static void sh_eth_set_duplex(struct net_device *ndev)
> {
> struct sh_eth_private *mdp = netdev_priv(ndev);
> @@ -377,9 +376,43 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
> .tsu = 1,
> #if defined(CONFIG_CPU_SUBTYPE_SH7734)
> .hw_crc = 1,
> + .select_mii = 1,
> #endif
> };
>
> +static void sh_eth_reset(struct net_device *ndev)
> +{
> + int cnt = 100;
> +
> + sh_eth_write(ndev, EDSR_ENALL, EDSR);
> + sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
> + while (cnt > 0) {
> + if (!(sh_eth_read(ndev, EDMR) & 0x3))
> + break;
> + mdelay(1);
> + cnt--;
> + }
> + if (cnt == 0)
> + printk(KERN_ERR "Device reset fail\n");
It looks like this would need a subsequent fix. Failing to reset the adapter
and just erroring out and not returning an error looks obviously wrong. Since
sh_eth_reset() is called in sh_eth_dev_init() which does return an int,
propagate the error back to the caller.
> +
> + /* Table Init */
> + sh_eth_write(ndev, 0x0, TDLAR);
> + sh_eth_write(ndev, 0x0, TDFAR);
> + sh_eth_write(ndev, 0x0, TDFXR);
> + sh_eth_write(ndev, 0x0, TDFFR);
> + sh_eth_write(ndev, 0x0, RDLAR);
> + sh_eth_write(ndev, 0x0, RDFAR);
> + sh_eth_write(ndev, 0x0, RDFXR);
> + sh_eth_write(ndev, 0x0, RDFFR);
> +
> + /* Reset HW CRC register */
> + sh_eth_reset_hw_crc(ndev);
> +
> + /* Select MII mode */
> + if (sh_eth_my_cpu_data.select_mii)
> + sh_eth_select_mii(ndev);
> +}
> +
> static void sh_eth_reset_hw_crc(struct net_device *ndev)
> {
> if (sh_eth_my_cpu_data.hw_crc)
> @@ -397,19 +430,7 @@ static void sh_eth_chip_reset(struct net_device *ndev)
> sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
> mdelay(1);
>
> - switch (mdp->phy_interface) {
> - case PHY_INTERFACE_MODE_GMII:
> - mii = 2;
> - break;
> - case PHY_INTERFACE_MODE_MII:
> - mii = 1;
> - break;
> - case PHY_INTERFACE_MODE_RMII:
> - default:
> - mii = 0;
> - break;
> - }
> - sh_eth_write(ndev, mii, RMII_MII);
> + sh_eth_select_mii(ndev);
> }
>
> static void sh_eth_reset(struct net_device *ndev)
> @@ -492,6 +513,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
> .no_trimd = 1,
> .no_ade = 1,
> .tsu = 1,
> + .select_mii = 1,
> };
>
> #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
> diff --git a/drivers/net/ethernet/renesas/sh_eth.h
b/drivers/net/ethernet/renesas/sh_eth.h
> index 57b8e1f..d6763b1392 100644
> --- a/drivers/net/ethernet/renesas/sh_eth.h
> +++ b/drivers/net/ethernet/renesas/sh_eth.h
> @@ -757,6 +757,7 @@ struct sh_eth_cpu_data {
> unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */
> unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */
> unsigned hw_crc:1; /* E-DMAC have CSMR */
> + unsigned select_mii:1; /* EtherC have RMII_MII (MII select register)
*/
> };
>
> struct sh_eth_private {
> --
> 1.7.10
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Florian
^ permalink raw reply
* Re: Difficulties to get 1Gbps on be2net ethernet card
From: Jean-Michel Hautbois @ 2012-06-12 8:24 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Sathya.Perla, netdev
In-Reply-To: <CAL8zT=i6zruaa0-bc-MG4FyhdM8RDtARd2E_o0+G-=p7RsJdGw@mail.gmail.com>
2012/6/8 Jean-Michel Hautbois <jhautbois@gmail.com>:
> 2012/6/8 Eric Dumazet <eric.dumazet@gmail.com>:
>> On Fri, 2012-06-08 at 10:14 +0200, Jean-Michel Hautbois wrote:
>>> 2012/6/8 Eric Dumazet <eric.dumazet@gmail.com>:
>>> > On Thu, 2012-06-07 at 14:54 +0200, Jean-Michel Hautbois wrote:
>>> >
>>> >> eth1 Link encap:Ethernet HWaddr 68:b5:99:b9:8d:d4
>>> >> UP BROADCAST RUNNING SLAVE MULTICAST MTU:4096 Metric:1
>>> >> RX packets:0 errors:0 dropped:0 overruns:0 frame:0
>>> >> TX packets:15215387 errors:0 dropped:0 overruns:0 carrier:0
>>> >> collisions:0 txqueuelen:1000
>>> >> RX bytes:0 (0.0 B) TX bytes:61476524359 (57.2 GiB)
>>> >
>>> >> qdisc mq 0: dev eth1 root
>>> >> Sent 61476524359 bytes 15215387 pkt (dropped 45683472, overlimits 0
>>> >> requeues 17480)
>>> >
>>> > OK, and "tc -s -d cl show dev eth1"
>>> >
>>> > (How many queues are really used)
>>> >
>>> >
>>> >
>>>
>>> tc -s -d cl show dev eth1
>>> class mq :1 root
>>> Sent 9798071746 bytes 2425410 pkt (dropped 3442405, overlimits 0 requeues 2747)
>>> backlog 0b 0p requeues 2747
>>> class mq :2 root
>>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>>> backlog 0b 0p requeues 0
>>> class mq :3 root
>>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>>> backlog 0b 0p requeues 0
>>> class mq :4 root
>>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>>> backlog 0b 0p requeues 0
>>> class mq :5 root
>>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>>> backlog 0b 0p requeues 0
>>> class mq :6 root
>>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>>> backlog 0b 0p requeues 0
>>> class mq :7 root
>>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>>> backlog 0b 0p requeues 0
>>> class mq :8 root
>>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>>> backlog 0b 0p requeues 0
>>
>>
>> Do you have the same distribution on old kernels as well ?
>> (ie only queue 0 is used)
>>
>>
>>
>
> On the old kernel, there is nothing returned by this command.
>
> JM
I used perf in order to get more information.
Here is the perf record -a sleep 10 result (I took only kernel) :
6.93% ModuleTester [kernel.kallsyms] [k]
copy_user_generic_string
2.99% swapper [kernel.kallsyms] [k] mwait_idle
2.60% kipmi0 [ipmi_si] [k] port_inb
1.75% swapper [kernel.kallsyms] [k] rb_prev
1.63% ModuleTester [kernel.kallsyms] [k] _raw_spin_lock
1.43% NodeManager [kernel.kallsyms] [k] delay_tsc
0.90% ModuleTester [kernel.kallsyms] [k] clear_page_c
0.88% ModuleTester [kernel.kallsyms] [k] dev_queue_xmit
0.80% ip [kernel.kallsyms] [k]
snmp_fold_field
0.73% ModuleTester [kernel.kallsyms] [k]
clflush_cache_range
0.69% grep [kernel.kallsyms] [k] page_fault
0.61% sh [kernel.kallsyms] [k] page_fault
0.59% ModuleTester [kernel.kallsyms] [k] udp_sendmsg
0.55% ModuleTester [kernel.kallsyms] [k] _raw_read_lock
0.53% sh [kernel.kallsyms] [k] unmap_vmas
0.52% ModuleTester [kernel.kallsyms] [k] rb_prev
0.51% ModuleTester [kernel.kallsyms] [k]
find_busiest_group
0.49% ModuleTester [kernel.kallsyms] [k] __ip_make_skb
0.48% ModuleTester [kernel.kallsyms] [k]
sock_alloc_send_pskb
0.48% ModuleTester libpthread-2.7.so [.]
pthread_mutex_lock
0.47% ModuleTester [kernel.kallsyms] [k]
__netif_receive_skb
0.44% ip [kernel.kallsyms] [k] find_next_bit
0.43% swapper [kernel.kallsyms] [k]
clflush_cache_range
0.41% ps [kernel.kallsyms] [k] format_decode
0.41% ModuleTester [bonding] [k]
bond_start_xmit
0.39% ModuleTester [be2net] [k] be_xmit
0.39% ModuleTester [kernel.kallsyms] [k]
__ip_append_data
0.38% ModuleTester [kernel.kallsyms] [k] netif_rx
0.37% swapper [be2net] [k] be_poll
0.37% swapper [kernel.kallsyms] [k] ktime_get
0.37% sh [kernel.kallsyms] [k] copy_page_c
0.36% swapper [kernel.kallsyms] [k]
irq_entries_start
0.36% ModuleTester [kernel.kallsyms] [k]
__alloc_pages_nodemask
0.35% ModuleTester [kernel.kallsyms] [k] __slab_free
0.35% ModuleTester [kernel.kallsyms] [k] ip_mc_output
0.34% ModuleTester [kernel.kallsyms] [k]
skb_release_data
0.33% ip [kernel.kallsyms] [k] page_fault
0.33% ModuleTester [kernel.kallsyms] [k] udp_send_skb
And here is the perf record -a result without bonding :
2.49% ModuleTester [kernel.kallsyms] [k]
csum_partial_copy_generic
1.35% ModuleTester [kernel.kallsyms] [k] _raw_spin_lock
1.29% ModuleTester [kernel.kallsyms] [k]
clflush_cache_range
1.16% jobprocess [kernel.kallsyms] [k] rb_prev
1.01% jobprocess [kernel.kallsyms] [k]
clflush_cache_range
0.81% ModuleTester [be2net] [k] be_xmit
0.78% jobprocess [kernel.kallsyms] [k] __slab_free
0.77% swapper [kernel.kallsyms] [k] mwait_idle
0.72% ModuleTester [kernel.kallsyms] [k]
__domain_mapping
0.66% jobprocess [kernel.kallsyms] [k] _raw_spin_lock
0.59% jobprocess [kernel.kallsyms] [k]
_raw_spin_lock_irqsave
0.56% ModuleTester [kernel.kallsyms] [k] rb_prev
0.53% swapper [kernel.kallsyms] [k] rb_prev
0.49% ModuleTester [kernel.kallsyms] [k] sock_wmalloc
0.47% jobprocess [be2net] [k] be_poll
0.47% ModuleTester [kernel.kallsyms] [k]
kmem_cache_alloc
0.47% swapper [kernel.kallsyms] [k]
clflush_cache_range
0.45% kipmi0 [ipmi_si] [k] port_inb
0.42% swapper [kernel.kallsyms] [k] __slab_free
0.41% jobprocess [kernel.kallsyms] [k] try_to_wake_up
0.40% ModuleTester [kernel.kallsyms] [k]
kmem_cache_alloc_node
0.40% jobprocess [kernel.kallsyms] [k] tg_load_down
0.39% jobprocess libodyssey.so.1.8.2 [.]
y8_deblocking_luma_vert_edge_h264_sse2
0.38% jobprocess libodyssey.so.1.8.2 [.]
y8_deblocking_luma_horz_edge_h264_ssse3
0.38% ModuleTester [kernel.kallsyms] [k] rb_insert_color
0.37% jobprocess [kernel.kallsyms] [k] find_iova
0.37% jobprocess [kernel.kallsyms] [k]
find_busiest_group
0.36% jobprocess libpthread-2.7.so [.]
pthread_mutex_lock
0.35% swapper [kernel.kallsyms] [k]
_raw_spin_unlock_irqrestore
0.34% ModuleTester [kernel.kallsyms] [k]
_raw_spin_lock_irqsave
0.33% ModuleTester [kernel.kallsyms] [k]
pfifo_fast_dequeue
0.32% ModuleTester [kernel.kallsyms] [k]
__kmalloc_node_track_caller
0.32% jobprocess [be2net] [k]
be_tx_compl_process
0.31% ModuleTester [kernel.kallsyms] [k] ip_fragment
0.29% swapper [kernel.kallsyms] [k]
__hrtimer_start_range_ns
0.29% jobprocess [kernel.kallsyms] [k] __schedule
0.29% ModuleTester [kernel.kallsyms] [k] dev_queue_xmit
0.28% swapper [kernel.kallsyms] [k] __schedule
First thing I notice is the difference in copy_user_generic_string (it
is only 0.11% on the second measure, I didn't reported it here).
I think perf can help in finding the issue I observe with bonding,
maybe do you have suggestions on the parameters to use ?
FYI, with bonding, TX goes up to 640Mbps, without bonding, I can send
2.4Gbps without suffering...
JM
^ permalink raw reply
* Re: [PATCH v2] net/sh-eth: Add support selecting MII function for SH7734 and R8A7740
From: David Miller @ 2012-06-12 7:29 UTC (permalink / raw)
To: nobuhiro.iwamatsu.yj; +Cc: netdev
In-Reply-To: <1339486142-32480-1-git-send-email-nobuhiro.iwamatsu.yj@renesas.com>
From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Date: Tue, 12 Jun 2012 16:29:02 +0900
> @@ -492,6 +513,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
> .no_trimd = 1,
> .no_ade = 1,
> .tsu = 1,
> + .select_mii = 1,
> };
>
Indent this new line consistently with those around it.
^ permalink raw reply
* [PATCH v2] net/sh-eth: Add support selecting MII function for SH7734 and R8A7740
From: Nobuhiro Iwamatsu @ 2012-06-12 7:29 UTC (permalink / raw)
To: netdev; +Cc: Nobuhiro Iwamatsu
Ethernet IP of SH7734 and R8A7740 has selecting MII register.
The user needs to change a value according to MII to be used.
This adds the function to change the value of this register.
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
---
V2: Fix the check by select_mii.
drivers/net/ethernet/renesas/sh_eth.c | 106 ++++++++++++++++++++-------------
drivers/net/ethernet/renesas/sh_eth.h | 1 +
2 files changed, 65 insertions(+), 42 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index be3c221..5358804 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -49,6 +49,33 @@
NETIF_MSG_RX_ERR| \
NETIF_MSG_TX_ERR)
+#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+ defined(CONFIG_ARCH_R8A7740)
+static void sh_eth_select_mii(struct net_device *ndev)
+{
+ u32 value = 0x0;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ switch (mdp->phy_interface) {
+ case PHY_INTERFACE_MODE_GMII:
+ value = 0x2;
+ break;
+ case PHY_INTERFACE_MODE_MII:
+ value = 0x1;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ value = 0x0;
+ break;
+ default:
+ pr_warn("PHY interface mode was not setup. Set to MII.\n");
+ value = 0x1;
+ break;
+ }
+
+ sh_eth_write(ndev, value, RMII_MII);
+}
+#endif
+
/* There is CPU dependent code */
#if defined(CONFIG_CPU_SUBTYPE_SH7724)
#define SH_ETH_RESET_DEFAULT 1
@@ -283,6 +310,7 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
#elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
#define SH_ETH_HAS_TSU 1
static void sh_eth_reset_hw_crc(struct net_device *ndev);
+
static void sh_eth_chip_reset(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -292,35 +320,6 @@ static void sh_eth_chip_reset(struct net_device *ndev)
mdelay(1);
}
-static void sh_eth_reset(struct net_device *ndev)
-{
- int cnt = 100;
-
- sh_eth_write(ndev, EDSR_ENALL, EDSR);
- sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
- while (cnt > 0) {
- if (!(sh_eth_read(ndev, EDMR) & 0x3))
- break;
- mdelay(1);
- cnt--;
- }
- if (cnt == 0)
- printk(KERN_ERR "Device reset fail\n");
-
- /* Table Init */
- sh_eth_write(ndev, 0x0, TDLAR);
- sh_eth_write(ndev, 0x0, TDFAR);
- sh_eth_write(ndev, 0x0, TDFXR);
- sh_eth_write(ndev, 0x0, TDFFR);
- sh_eth_write(ndev, 0x0, RDLAR);
- sh_eth_write(ndev, 0x0, RDFAR);
- sh_eth_write(ndev, 0x0, RDFXR);
- sh_eth_write(ndev, 0x0, RDFFR);
-
- /* Reset HW CRC register */
- sh_eth_reset_hw_crc(ndev);
-}
-
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -377,9 +376,43 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.tsu = 1,
#if defined(CONFIG_CPU_SUBTYPE_SH7734)
.hw_crc = 1,
+ .select_mii = 1,
#endif
};
+static void sh_eth_reset(struct net_device *ndev)
+{
+ int cnt = 100;
+
+ sh_eth_write(ndev, EDSR_ENALL, EDSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
+ while (cnt > 0) {
+ if (!(sh_eth_read(ndev, EDMR) & 0x3))
+ break;
+ mdelay(1);
+ cnt--;
+ }
+ if (cnt == 0)
+ printk(KERN_ERR "Device reset fail\n");
+
+ /* Table Init */
+ sh_eth_write(ndev, 0x0, TDLAR);
+ sh_eth_write(ndev, 0x0, TDFAR);
+ sh_eth_write(ndev, 0x0, TDFXR);
+ sh_eth_write(ndev, 0x0, TDFFR);
+ sh_eth_write(ndev, 0x0, RDLAR);
+ sh_eth_write(ndev, 0x0, RDFAR);
+ sh_eth_write(ndev, 0x0, RDFXR);
+ sh_eth_write(ndev, 0x0, RDFFR);
+
+ /* Reset HW CRC register */
+ sh_eth_reset_hw_crc(ndev);
+
+ /* Select MII mode */
+ if (sh_eth_my_cpu_data.select_mii)
+ sh_eth_select_mii(ndev);
+}
+
static void sh_eth_reset_hw_crc(struct net_device *ndev)
{
if (sh_eth_my_cpu_data.hw_crc)
@@ -397,19 +430,7 @@ static void sh_eth_chip_reset(struct net_device *ndev)
sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
mdelay(1);
- switch (mdp->phy_interface) {
- case PHY_INTERFACE_MODE_GMII:
- mii = 2;
- break;
- case PHY_INTERFACE_MODE_MII:
- mii = 1;
- break;
- case PHY_INTERFACE_MODE_RMII:
- default:
- mii = 0;
- break;
- }
- sh_eth_write(ndev, mii, RMII_MII);
+ sh_eth_select_mii(ndev);
}
static void sh_eth_reset(struct net_device *ndev)
@@ -492,6 +513,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.no_trimd = 1,
.no_ade = 1,
.tsu = 1,
+ .select_mii = 1,
};
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 57b8e1f..d6763b1392 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -757,6 +757,7 @@ struct sh_eth_cpu_data {
unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */
unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */
unsigned hw_crc:1; /* E-DMAC have CSMR */
+ unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */
};
struct sh_eth_private {
--
1.7.10
^ permalink raw reply related
* Re: [PATCH] net/sh-eth: Add support selecting MII function for SH7734 and R8A7740
From: Nobuhiro Iwamatsu @ 2012-06-12 7:28 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120611.164717.1390327462404819704.davem@davemloft.net>
David Miller さんは書きました:
> From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
> Date: Fri, 8 Jun 2012 15:01:51 +0900
>
>> + unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */
>
> Nothing tests this value.
>
Sorry, I sent old patch. I will sent new patch soon.
Best regards,
Nobuhiro
^ permalink raw reply
* [PATCH net-next v2 5/5] net: sh_eth: use NAPI
From: Shimoda, Yoshihiro @ 2012-06-12 6:59 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This patch modifies the driver to use NAPI.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
about v2:
- fix the condition which calls the netif_stop_queue()
drivers/net/ethernet/renesas/sh_eth.c | 101 +++++++++++++++++++++------------
drivers/net/ethernet/renesas/sh_eth.h | 3 +
2 files changed, 67 insertions(+), 37 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index c64a31c..9196777 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1035,7 +1035,7 @@ static int sh_eth_txfree(struct net_device *ndev)
}
/* Packet receive function */
-static int sh_eth_rx(struct net_device *ndev)
+static int sh_eth_rx(struct net_device *ndev, int *work, int budget)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_rxdesc *rxdesc;
@@ -1047,7 +1047,8 @@ static int sh_eth_rx(struct net_device *ndev)
u32 desc_status;
rxdesc = &mdp->rx_ring[entry];
- while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
+ while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT)) &&
+ *work < budget) {
desc_status = edmac_to_cpu(mdp, rxdesc->status);
pkt_len = rxdesc->frame_length;
@@ -1087,13 +1088,14 @@ static int sh_eth_rx(struct net_device *ndev)
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len);
skb->protocol = eth_type_trans(skb, ndev);
- netif_rx(skb);
+ netif_receive_skb(skb);
ndev->stats.rx_packets++;
ndev->stats.rx_bytes += pkt_len;
}
rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
entry = (++mdp->cur_rx) % mdp->num_rx_ring;
rxdesc = &mdp->rx_ring[entry];
+ (*work)++;
}
/* Refill the Rx ring buffers. */
@@ -1125,7 +1127,7 @@ static int sh_eth_rx(struct net_device *ndev)
/* Restart Rx engine if stopped. */
/* If we don't need to check status, don't. -KDU */
- if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
+ if (*work < budget && !(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
/* fix the values for the next receiving */
mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) -
sh_eth_read(ndev, RDLAR)) >> 4;
@@ -1281,38 +1283,61 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
/* Get interrpt stat */
intr_status = sh_eth_read(ndev, EESR);
- /* Clear interrupt */
if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
cd->tx_check | cd->eesr_err_check)) {
- sh_eth_write(ndev, intr_status, EESR);
+ if (napi_schedule_prep(&mdp->napi)) {
+ /* Disable interrupts of the channel */
+ sh_eth_write(ndev, 0, EESIPR);
+ __napi_schedule(&mdp->napi);
+ }
ret = IRQ_HANDLED;
- } else
- goto other_irq;
-
- if (intr_status & (EESR_FRC | /* Frame recv*/
- EESR_RMAF | /* Multi cast address recv*/
- EESR_RRF | /* Bit frame recv */
- EESR_RTLF | /* Long frame recv*/
- EESR_RTSF | /* short frame recv */
- EESR_PRE | /* PHY-LSI recv error */
- EESR_CERF)){ /* recv frame CRC error */
- sh_eth_rx(ndev);
}
- /* Tx Check */
- if (intr_status & cd->tx_check) {
- sh_eth_txfree(ndev);
- netif_wake_queue(ndev);
+ spin_unlock(&mdp->lock);
+
+ return ret;
+}
+
+static int sh_eth_poll(struct napi_struct *napi, int budget)
+{
+ struct sh_eth_private *mdp = container_of(napi, struct sh_eth_private,
+ napi);
+ struct net_device *ndev = mdp->ndev;
+ struct sh_eth_cpu_data *cd = mdp->cd;
+ int work_done = 0, txfree_num;
+ u32 intr_status = sh_eth_read(ndev, EESR);
+
+ /* Clear interrupt flags */
+ sh_eth_write(ndev, intr_status, EESR);
+
+ /* check txdesc */
+ txfree_num = sh_eth_txfree(ndev);
+ if (txfree_num) {
+ netif_tx_lock(ndev);
+ if (netif_queue_stopped(ndev))
+ netif_wake_queue(ndev);
+ netif_tx_unlock(ndev);
}
+ /* check rxdesc */
+ sh_eth_rx(ndev, &work_done, budget);
+
+ /* check error flags */
if (intr_status & cd->eesr_err_check)
sh_eth_error(ndev, intr_status);
-other_irq:
- spin_unlock(&mdp->lock);
+ /* get current interrupt flags */
+ intr_status = sh_eth_read(ndev, EESR);
- return ret;
+ /* check whether this driver should call napi_complete() */
+ if (work_done < budget) {
+ napi_complete(napi);
+ /* Enable all interrupts */
+ sh_eth_write(ndev, cd->eesipr_value, EESIPR);
+ }
+
+ return work_done;
}
/* PHY state control function */
@@ -1545,6 +1570,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
/* Stop the chip's Tx and Rx processes. */
sh_eth_write(ndev, 0, EDTRR);
sh_eth_write(ndev, 0, EDRRR);
+ napi_disable(&mdp->napi);
synchronize_irq(ndev->irq);
}
@@ -1569,6 +1595,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
}
if (netif_running(ndev)) {
+ napi_enable(&mdp->napi);
sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
/* Setting the Rx mode will start the Rx process. */
sh_eth_write(ndev, EDRRR_R, EDRRR);
@@ -1600,6 +1627,8 @@ static int sh_eth_open(struct net_device *ndev)
pm_runtime_get_sync(&mdp->pdev->dev);
+ napi_enable(&mdp->napi);
+
ret = request_irq(ndev->irq, sh_eth_interrupt,
#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7764) || \
@@ -1678,19 +1707,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_txdesc *txdesc;
u32 entry;
- unsigned long flags;
-
- spin_lock_irqsave(&mdp->lock, flags);
- if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
- if (!sh_eth_txfree(ndev)) {
- if (netif_msg_tx_queued(mdp))
- dev_warn(&ndev->dev, "TxFD exhausted.\n");
- netif_stop_queue(ndev);
- spin_unlock_irqrestore(&mdp->lock, flags);
- return NETDEV_TX_BUSY;
- }
- }
- spin_unlock_irqrestore(&mdp->lock, flags);
entry = mdp->cur_tx % mdp->num_tx_ring;
mdp->tx_skbuff[entry] = skb;
@@ -1716,6 +1732,12 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
+ if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
+ if (netif_msg_tx_queued(mdp))
+ dev_warn(&ndev->dev, "TxFD exhausted.\n");
+ netif_stop_queue(ndev);
+ }
+
return NETDEV_TX_OK;
}
@@ -1739,6 +1761,8 @@ static int sh_eth_close(struct net_device *ndev)
phy_disconnect(mdp->phydev);
}
+ napi_disable(&mdp->napi);
+
free_irq(ndev->irq, ndev);
/* Free all the skbuffs in the Rx queue. */
@@ -2368,6 +2392,9 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
#endif
sh_eth_set_default_cpu_data(mdp->cd);
+ mdp->ndev = ndev;
+ netif_napi_add(ndev, &mdp->napi, sh_eth_poll, SH_ETH_NAPI_WEIGHT);
+
/* set function */
ndev->netdev_ops = &sh_eth_netdev_ops;
SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index f1dbc27..93dad7b 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -35,6 +35,7 @@
#define PKT_BUF_SZ 1538
#define SH_ETH_TSU_TIMEOUT_MS 500
#define SH_ETH_TSU_CAM_ENTRIES 32
+#define SH_ETH_NAPI_WEIGHT 32
enum {
/* E-DMAC registers */
@@ -728,6 +729,8 @@ struct sh_eth_private {
int duplex;
int port; /* for TSU */
int vlan_num_ids; /* for VLAN tag filter */
+ struct napi_struct napi;
+ struct net_device *ndev;
unsigned no_ether_link:1;
unsigned ether_link_active_low:1;
--
1.7.1
^ permalink raw reply related
* Re: Possible deadlock in ipv6?
From: David Miller @ 2012-06-12 6:54 UTC (permalink / raw)
To: eric.dumazet; +Cc: vdavydov, netdev
In-Reply-To: <1338998314.26966.12.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 06 Jun 2012 17:58:34 +0200
> And it seems this neigh_down() can be removed, its called later
> (after dev->ip6_ptr is cleared)
It is unclear whether we need to do the the neigh_down() in both
the 'how' and '!how' cases. If so then we can't make this change.
^ permalink raw reply
* Re: 3.4-rc: NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out
From: Tomas Papan @ 2012-06-12 6:51 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20120612052631.GA14567@electric-eye.fr.zoreil.com>
Hi Francois,
I tried your patch, so far no exception has been generated (uptime 1
hour) . I'll keep it running for 1 day and then I'll come back to you.
Anyway thanks for the patch.
Regards
Tomas
On Tue, Jun 12, 2012 at 7:26 AM, Francois Romieu <romieu@fr.zoreil.com> wrote:
> Tomas Papan <tomas.papan@gmail.com> :
> [...]
>> [ 2.780758] r8169 0000:03:00.0: eth1: RTL8168e/8111e at
>> 0xffffc9000001c000, 80:ee:73:10:ad:44, XID 0c200000 IRQ 46
>
> Let's see if it behaves like RTL_GIGA_MAC_VER_34.
>
> Can you try the patch below ?
>
> diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
> index bbacb37..da46588 100644
> --- a/drivers/net/ethernet/realtek/r8169.c
> +++ b/drivers/net/ethernet/realtek/r8169.c
> @@ -3766,6 +3766,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
> case RTL_GIGA_MAC_VER_22:
> case RTL_GIGA_MAC_VER_23:
> case RTL_GIGA_MAC_VER_24:
> + case RTL_GIGA_MAC_VER_33:
> RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
> break;
> default:
>
>
^ permalink raw reply
* Re: [PATCH net-next 5/5] net: sh_eth: use NAPI
From: Shimoda, Yoshihiro @ 2012-06-12 6:47 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, SH-Linux
In-Reply-To: <1339480115.22704.20.camel@edumazet-glaptop>
2012/06/12 14:48, Eric Dumazet wrote:
> On Tue, 2012-06-12 at 14:19 +0900, Shimoda, Yoshihiro wrote:
< snip >
>> + if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
>> + if (netif_msg_tx_queued(mdp)) {
>> + dev_warn(&ndev->dev, "TxFD exhausted.\n");
>> + netif_stop_queue(ndev);
>> + }
>> + }
>> +
>> return NETDEV_TX_OK;
>> }
>
>
> I have no idea why you call netif_stop_queue() only if
> netif_msg_tx_queued(mdp)
>
> You should test your driver under heavy TX load.
>
Thank you for the point.
I checked the netif-msg.txt about netif_msg_tx_queued(). It is one of
the network interface message level setting. So, the driver's behavior
should not be changed by the level, I think.
I will modify the patch.
Best regards,
Yoshihiro Shimoda
^ permalink raw reply
* Re: [PATCH net V2] bonding:force to use primary slave
From: Weiping Pan @ 2012-06-12 6:37 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: netdev, nicolas.2p.debian
In-Reply-To: <7128.1339477247@death.nxdomain>
On 06/12/2012 01:00 PM, Jay Vosburgh wrote:
> Weiping Pan<wpan@redhat.com> wrote:
>
>> When we set primary slave with module parameters, bond will always use this
>> primary slave as active slave.
>>
>> But when we modify primary slave via sysfs, it will call
>> bond_should_change_active() and take into account primary_reselect.
>>
>> And I think we should use the new primary slave as the new active slave
>> regardless of the value of primary_reselect, since primary slave really should
>> have priority than other slaves.
> The whole point of primary_reselect is that the primary slave
> does not have priority unless it meets the reselect criteria, or it is
> being enslaved.
>
>> primary_reselect is introduced to handle the failure or recovery of primary
>> slave, but when we modify primary slave via sysfs, we want to give it higher
>> priority, and it may or may not be a failure or recovery slave.
>>
>> Thus the behavior is the same with module parameters and meets the
>> administrator's expectation.
> I still disagree with this patch. My comments regarding the
> prior version were intended to mean that we should document the current
> behavior, not change the behavior and document the new behavior.
>
> If an administrator wishes for the newly set primary to
> immediately become the active slave, they can either leave
> primary_reselect at its default setting or utilize the available
> mechanism to change the active slave. Applying this patch eliminates
> the ability to alter the primary slave setting without simultaneously
> changing the active slave.
Yes, this side effect is not good.
Thanks for your comments.
Weiping Pan
> Further, the default value for primary_reselect already does
> this (change to the new primary immediately); this patch only affects
> the case that primary_reselect is set to a non-default value. In my
> mind, this reinforces that the current behavior is correct, and that the
> primary_reselect setting should apply to the newly selected primary
> (because the administrator has explicitly chosen that behavior).
>
> -J
>
> ---
> -Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
>
^ permalink raw reply
* RE: kernel ipsec error
From: Marco Berizzi @ 2012-06-12 6:31 UTC (permalink / raw)
To: bhutchings; +Cc: netdev
In-Reply-To: <1339436963.2665.5.camel@bwh-desktop.uk.solarflarecom.com>
bhutchings@solarflare.com wrote:
> On Mon, 2012-06-11 at 14:45 +0200, Marco Berizzi wrote:
> > Hello everybody.
> >
> > After 12 days uptime I got this message.
> > Linux is 3.3.5 32bit, running openswan
> > (this is an ipsec gateway/netfilter
> > firewall) and squid.
> >
> > Jun 11 12:53:02 Pleiadi kernel: SLUB: Unable to allocate memory on node -1 (gfp=0x20)
> > Jun 11 12:53:02 Pleiadi kernel: cache: kmalloc-2048, object size: 2048, buffer size: 2048, default order: 2, min order: 0
> > Jun 11 12:53:02 Pleiadi kernel: node 0: slabs: 61, objs: 476, free: 0
> > Jun 11 12:53:02 Pleiadi kernel: kworker/0:2: page allocation failure: order:0, mode:0x4020
>
> So a single page allocation in atomic (non-sleeping) context failed.
>
> [...]
> > Jun 11 12:53:02 Pleiadi kernel: Free swap = 130908kB
> > Jun 11 12:53:02 Pleiadi kernel: Total swap = 151164kB
> > Jun 11 12:53:02 Pleiadi kernel: 40944 pages RAM
> [...]
>
> Not too surprising with this little RAM available (swap didn't help
> since we couldn't wait for swap-out).
yes, this is really a very old hardware.
> There could be a memory leak, but you would need to read /proc/meminfo
> and /proc/slabinfo at intervals to work out whether that was the case.
Kindly, may you tell me which should be the intervals? One second? one minute?
^ permalink raw reply
* Re: [PATCH net-next 5/5] net: sh_eth: use NAPI
From: Eric Dumazet @ 2012-06-12 5:48 UTC (permalink / raw)
To: Shimoda, Yoshihiro; +Cc: netdev, SH-Linux
In-Reply-To: <4FD6D154.1000000@renesas.com>
On Tue, 2012-06-12 at 14:19 +0900, Shimoda, Yoshihiro wrote:
> This patch modifies the driver to use NAPI.
>
...
> +static int sh_eth_poll(struct napi_struct *napi, int budget)
> +{
> + struct sh_eth_private *mdp = container_of(napi, struct sh_eth_private,
> + napi);
> + struct net_device *ndev = mdp->ndev;
> + struct sh_eth_cpu_data *cd = mdp->cd;
> + int work_done = 0, txfree_num;
> + u32 intr_status = sh_eth_read(ndev, EESR);
> +
> + /* Clear interrupt flags */
> + sh_eth_write(ndev, intr_status, EESR);
> +
> + /* check txdesc */
> + txfree_num = sh_eth_txfree(ndev);
> + if (txfree_num) {
> + netif_tx_lock(ndev);
> + if (netif_queue_stopped(ndev))
> + netif_wake_queue(ndev);
> + netif_tx_unlock(ndev);
> }
...
> @@ -1678,19 +1707,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
> struct sh_eth_private *mdp = netdev_priv(ndev);
> struct sh_eth_txdesc *txdesc;
> u32 entry;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mdp->lock, flags);
> - if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
> - if (!sh_eth_txfree(ndev)) {
> - if (netif_msg_tx_queued(mdp))
> - dev_warn(&ndev->dev, "TxFD exhausted.\n");
> - netif_stop_queue(ndev);
> - spin_unlock_irqrestore(&mdp->lock, flags);
> - return NETDEV_TX_BUSY;
> - }
> - }
> - spin_unlock_irqrestore(&mdp->lock, flags);
>
> entry = mdp->cur_tx % mdp->num_tx_ring;
> mdp->tx_skbuff[entry] = skb;
> @@ -1716,6 +1732,13 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
> if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
> sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
>
> + if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
> + if (netif_msg_tx_queued(mdp)) {
> + dev_warn(&ndev->dev, "TxFD exhausted.\n");
> + netif_stop_queue(ndev);
> + }
> + }
> +
> return NETDEV_TX_OK;
> }
I have no idea why you call netif_stop_queue() only if
netif_msg_tx_queued(mdp)
You should test your driver under heavy TX load.
^ permalink raw reply
* Re: 3.4-rc: NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out
From: Francois Romieu @ 2012-06-12 5:26 UTC (permalink / raw)
To: Tomas Papan; +Cc: netdev
In-Reply-To: <CAMGsXDT5xu_+gHber-XS=wv9RW7kyUzHNUJN87CuJuNevDuxSw@mail.gmail.com>
Tomas Papan <tomas.papan@gmail.com> :
[...]
> [ 2.780758] r8169 0000:03:00.0: eth1: RTL8168e/8111e at
> 0xffffc9000001c000, 80:ee:73:10:ad:44, XID 0c200000 IRQ 46
Let's see if it behaves like RTL_GIGA_MAC_VER_34.
Can you try the patch below ?
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index bbacb37..da46588 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3766,6 +3766,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_22:
case RTL_GIGA_MAC_VER_23:
case RTL_GIGA_MAC_VER_24:
+ case RTL_GIGA_MAC_VER_33:
RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST);
break;
default:
^ permalink raw reply related
* [PATCH net-next] bonding: remove packet cloning in recv_probe()
From: Eric Dumazet @ 2012-06-12 5:23 UTC (permalink / raw)
To: David Miller
Cc: netdev, Jay Vosburgh, Andy Gospodarek, Jiri Bohac,
Nicolas de Pesloüan, Maciej Żenczykowski
From: Eric Dumazet <edumazet@google.com>
Cloning all packets in input path have a significant cost.
Use skb_header_pointer()/skb_copy_bits() instead of pskb_may_pull() so
that recv_probe handlers (bond_3ad_lacpdu_recv / bond_arp_rcv /
rlb_arp_recv ) dont touch input skb.
bond_handle_frame() can avoid the skb_clone()/dev_kfree_skb()
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jay Vosburgh <fubar@us.ibm.com>
Cc: Andy Gospodarek <andy@greyhouse.net>
Cc: Jiri Bohac <jbohac@suse.cz>
Cc: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
Cc: Maciej Żenczykowski <maze@google.com>
---
drivers/net/bonding/bond_3ad.c | 11 +++++---
drivers/net/bonding/bond_3ad.h | 4 +--
drivers/net/bonding/bond_alb.c | 20 ++++------------
drivers/net/bonding/bond_main.c | 37 ++++++++++++++++--------------
drivers/net/bonding/bonding.h | 4 +--
5 files changed, 36 insertions(+), 40 deletions(-)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 3463b46..3031e04 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2460,18 +2460,21 @@ out:
return NETDEV_TX_OK;
}
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
- struct slave *slave)
+int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
int ret = RX_HANDLER_ANOTHER;
+ struct lacpdu *lacpdu, _lacpdu;
+
if (skb->protocol != PKT_TYPE_LACPDU)
return ret;
- if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
+ lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu);
+ if (!lacpdu)
return ret;
read_lock(&bond->lock);
- ret = bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
+ ret = bond_3ad_rx_indication(lacpdu, slave, skb->len);
read_unlock(&bond->lock);
return ret;
}
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 5ee7e3c..0cfaa4a 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -274,8 +274,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave);
void bond_3ad_handle_link_change(struct slave *slave, char link);
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
- struct slave *slave);
+int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave);
int bond_3ad_set_carrier(struct bonding *bond);
void bond_3ad_update_lacp_rate(struct bonding *bond);
#endif //__BOND_3AD_H__
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 0f59c15..ef3791a 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -342,27 +342,17 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
_unlock_rx_hashtbl_bh(bond);
}
-static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
- struct slave *slave)
+static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct arp_pkt *arp;
+ struct arp_pkt *arp, _arp;
if (skb->protocol != cpu_to_be16(ETH_P_ARP))
goto out;
- arp = (struct arp_pkt *) skb->data;
- if (!arp) {
- pr_debug("Packet has no ARP data\n");
+ arp = skb_header_pointer(skb, 0, sizeof(_arp), &_arp);
+ if (!arp)
goto out;
- }
-
- if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
- goto out;
-
- if (skb->len < sizeof(struct arp_pkt)) {
- pr_debug("Packet is too small to be an ARP\n");
- goto out;
- }
if (arp->op_code == htons(ARPOP_REPLY)) {
/* update rx hash table for this ARP */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2ee8cf9..9e2301e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1444,8 +1444,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
struct sk_buff *skb = *pskb;
struct slave *slave;
struct bonding *bond;
- int (*recv_probe)(struct sk_buff *, struct bonding *,
- struct slave *);
+ int (*recv_probe)(const struct sk_buff *, struct bonding *,
+ struct slave *);
int ret = RX_HANDLER_ANOTHER;
skb = skb_share_check(skb, GFP_ATOMIC);
@@ -1462,15 +1462,10 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
recv_probe = ACCESS_ONCE(bond->recv_probe);
if (recv_probe) {
- struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
-
- if (likely(nskb)) {
- ret = recv_probe(nskb, bond, slave);
- dev_kfree_skb(nskb);
- if (ret == RX_HANDLER_CONSUMED) {
- consume_skb(skb);
- return ret;
- }
+ ret = recv_probe(skb, bond, slave);
+ if (ret == RX_HANDLER_CONSUMED) {
+ consume_skb(skb);
+ return ret;
}
}
@@ -2737,25 +2732,31 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
}
}
-static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
- struct slave *slave)
+static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct arphdr *arp;
+ struct arphdr *arp = (struct arphdr *)skb->data;
unsigned char *arp_ptr;
__be32 sip, tip;
+ int alen;
if (skb->protocol != __cpu_to_be16(ETH_P_ARP))
return RX_HANDLER_ANOTHER;
read_lock(&bond->lock);
+ alen = arp_hdr_len(bond->dev);
pr_debug("bond_arp_rcv: bond %s skb->dev %s\n",
bond->dev->name, skb->dev->name);
- if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
- goto out_unlock;
+ if (alen > skb_headlen(skb)) {
+ arp = kmalloc(alen, GFP_ATOMIC);
+ if (!arp)
+ goto out_unlock;
+ if (skb_copy_bits(skb, 0, arp, alen) < 0)
+ goto out_unlock;
+ }
- arp = arp_hdr(skb);
if (arp->ar_hln != bond->dev->addr_len ||
skb->pkt_type == PACKET_OTHERHOST ||
skb->pkt_type == PACKET_LOOPBACK ||
@@ -2790,6 +2791,8 @@ static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
out_unlock:
read_unlock(&bond->lock);
+ if (arp != (struct arphdr *)skb->data)
+ kfree(arp);
return RX_HANDLER_ANOTHER;
}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 4581aa5..f8af2fc 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -218,8 +218,8 @@ struct bonding {
struct slave *primary_slave;
bool force_primary;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
- int (*recv_probe)(struct sk_buff *, struct bonding *,
- struct slave *);
+ int (*recv_probe)(const struct sk_buff *, struct bonding *,
+ struct slave *);
rwlock_t lock;
rwlock_t curr_slave_lock;
u8 send_peer_notif;
^ permalink raw reply related
* [PATCH net-next 5/5] net: sh_eth: use NAPI
From: Shimoda, Yoshihiro @ 2012-06-12 5:19 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This patch modifies the driver to use NAPI.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 102 +++++++++++++++++++++------------
drivers/net/ethernet/renesas/sh_eth.h | 3 +
2 files changed, 68 insertions(+), 37 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index c64a31c..1584cda 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1035,7 +1035,7 @@ static int sh_eth_txfree(struct net_device *ndev)
}
/* Packet receive function */
-static int sh_eth_rx(struct net_device *ndev)
+static int sh_eth_rx(struct net_device *ndev, int *work, int budget)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_rxdesc *rxdesc;
@@ -1047,7 +1047,8 @@ static int sh_eth_rx(struct net_device *ndev)
u32 desc_status;
rxdesc = &mdp->rx_ring[entry];
- while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
+ while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT)) &&
+ *work < budget) {
desc_status = edmac_to_cpu(mdp, rxdesc->status);
pkt_len = rxdesc->frame_length;
@@ -1087,13 +1088,14 @@ static int sh_eth_rx(struct net_device *ndev)
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len);
skb->protocol = eth_type_trans(skb, ndev);
- netif_rx(skb);
+ netif_receive_skb(skb);
ndev->stats.rx_packets++;
ndev->stats.rx_bytes += pkt_len;
}
rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
entry = (++mdp->cur_rx) % mdp->num_rx_ring;
rxdesc = &mdp->rx_ring[entry];
+ (*work)++;
}
/* Refill the Rx ring buffers. */
@@ -1125,7 +1127,7 @@ static int sh_eth_rx(struct net_device *ndev)
/* Restart Rx engine if stopped. */
/* If we don't need to check status, don't. -KDU */
- if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
+ if (*work < budget && !(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
/* fix the values for the next receiving */
mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) -
sh_eth_read(ndev, RDLAR)) >> 4;
@@ -1281,38 +1283,61 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
/* Get interrpt stat */
intr_status = sh_eth_read(ndev, EESR);
- /* Clear interrupt */
if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
cd->tx_check | cd->eesr_err_check)) {
- sh_eth_write(ndev, intr_status, EESR);
+ if (napi_schedule_prep(&mdp->napi)) {
+ /* Disable interrupts of the channel */
+ sh_eth_write(ndev, 0, EESIPR);
+ __napi_schedule(&mdp->napi);
+ }
ret = IRQ_HANDLED;
- } else
- goto other_irq;
-
- if (intr_status & (EESR_FRC | /* Frame recv*/
- EESR_RMAF | /* Multi cast address recv*/
- EESR_RRF | /* Bit frame recv */
- EESR_RTLF | /* Long frame recv*/
- EESR_RTSF | /* short frame recv */
- EESR_PRE | /* PHY-LSI recv error */
- EESR_CERF)){ /* recv frame CRC error */
- sh_eth_rx(ndev);
}
- /* Tx Check */
- if (intr_status & cd->tx_check) {
- sh_eth_txfree(ndev);
- netif_wake_queue(ndev);
+ spin_unlock(&mdp->lock);
+
+ return ret;
+}
+
+static int sh_eth_poll(struct napi_struct *napi, int budget)
+{
+ struct sh_eth_private *mdp = container_of(napi, struct sh_eth_private,
+ napi);
+ struct net_device *ndev = mdp->ndev;
+ struct sh_eth_cpu_data *cd = mdp->cd;
+ int work_done = 0, txfree_num;
+ u32 intr_status = sh_eth_read(ndev, EESR);
+
+ /* Clear interrupt flags */
+ sh_eth_write(ndev, intr_status, EESR);
+
+ /* check txdesc */
+ txfree_num = sh_eth_txfree(ndev);
+ if (txfree_num) {
+ netif_tx_lock(ndev);
+ if (netif_queue_stopped(ndev))
+ netif_wake_queue(ndev);
+ netif_tx_unlock(ndev);
}
+ /* check rxdesc */
+ sh_eth_rx(ndev, &work_done, budget);
+
+ /* check error flags */
if (intr_status & cd->eesr_err_check)
sh_eth_error(ndev, intr_status);
-other_irq:
- spin_unlock(&mdp->lock);
+ /* get current interrupt flags */
+ intr_status = sh_eth_read(ndev, EESR);
- return ret;
+ /* check whether this driver should call napi_complete() */
+ if (work_done < budget) {
+ napi_complete(napi);
+ /* Enable all interrupts */
+ sh_eth_write(ndev, cd->eesipr_value, EESIPR);
+ }
+
+ return work_done;
}
/* PHY state control function */
@@ -1545,6 +1570,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
/* Stop the chip's Tx and Rx processes. */
sh_eth_write(ndev, 0, EDTRR);
sh_eth_write(ndev, 0, EDRRR);
+ napi_disable(&mdp->napi);
synchronize_irq(ndev->irq);
}
@@ -1569,6 +1595,7 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
}
if (netif_running(ndev)) {
+ napi_enable(&mdp->napi);
sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
/* Setting the Rx mode will start the Rx process. */
sh_eth_write(ndev, EDRRR_R, EDRRR);
@@ -1600,6 +1627,8 @@ static int sh_eth_open(struct net_device *ndev)
pm_runtime_get_sync(&mdp->pdev->dev);
+ napi_enable(&mdp->napi);
+
ret = request_irq(ndev->irq, sh_eth_interrupt,
#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7764) || \
@@ -1678,19 +1707,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_txdesc *txdesc;
u32 entry;
- unsigned long flags;
-
- spin_lock_irqsave(&mdp->lock, flags);
- if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
- if (!sh_eth_txfree(ndev)) {
- if (netif_msg_tx_queued(mdp))
- dev_warn(&ndev->dev, "TxFD exhausted.\n");
- netif_stop_queue(ndev);
- spin_unlock_irqrestore(&mdp->lock, flags);
- return NETDEV_TX_BUSY;
- }
- }
- spin_unlock_irqrestore(&mdp->lock, flags);
entry = mdp->cur_tx % mdp->num_tx_ring;
mdp->tx_skbuff[entry] = skb;
@@ -1716,6 +1732,13 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
+ if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
+ if (netif_msg_tx_queued(mdp)) {
+ dev_warn(&ndev->dev, "TxFD exhausted.\n");
+ netif_stop_queue(ndev);
+ }
+ }
+
return NETDEV_TX_OK;
}
@@ -1739,6 +1762,8 @@ static int sh_eth_close(struct net_device *ndev)
phy_disconnect(mdp->phydev);
}
+ napi_disable(&mdp->napi);
+
free_irq(ndev->irq, ndev);
/* Free all the skbuffs in the Rx queue. */
@@ -2368,6 +2393,9 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
#endif
sh_eth_set_default_cpu_data(mdp->cd);
+ mdp->ndev = ndev;
+ netif_napi_add(ndev, &mdp->napi, sh_eth_poll, SH_ETH_NAPI_WEIGHT);
+
/* set function */
ndev->netdev_ops = &sh_eth_netdev_ops;
SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index f1dbc27..93dad7b 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -35,6 +35,7 @@
#define PKT_BUF_SZ 1538
#define SH_ETH_TSU_TIMEOUT_MS 500
#define SH_ETH_TSU_CAM_ENTRIES 32
+#define SH_ETH_NAPI_WEIGHT 32
enum {
/* E-DMAC registers */
@@ -728,6 +729,8 @@ struct sh_eth_private {
int duplex;
int port; /* for TSU */
int vlan_num_ids; /* for VLAN tag filter */
+ struct napi_struct napi;
+ struct net_device *ndev;
unsigned no_ether_link:1;
unsigned ether_link_active_low:1;
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 4/5] net: sh_eth: add support for set_ringparam/get_ringparam
From: Shimoda, Yoshihiro @ 2012-06-12 5:19 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This patch supports the ethtool's set_ringparam() and get_ringparam().
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 139 +++++++++++++++++++++++++--------
drivers/net/ethernet/renesas/sh_eth.h | 6 ++
2 files changed, 112 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index ff5a4a9..c64a31c 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -739,7 +739,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* Free Rx skb ringbuffer */
if (mdp->rx_skbuff) {
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_rx_ring; i++) {
if (mdp->rx_skbuff[i])
dev_kfree_skb(mdp->rx_skbuff[i]);
}
@@ -749,7 +749,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* Free Tx skb ringbuffer */
if (mdp->tx_skbuff) {
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_tx_ring; i++) {
if (mdp->tx_skbuff[i])
dev_kfree_skb(mdp->tx_skbuff[i]);
}
@@ -766,8 +766,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
struct sk_buff *skb;
struct sh_eth_rxdesc *rxdesc = NULL;
struct sh_eth_txdesc *txdesc = NULL;
- int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE;
- int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE;
+ int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring;
+ int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring;
mdp->cur_rx = mdp->cur_tx = 0;
mdp->dirty_rx = mdp->dirty_tx = 0;
@@ -775,7 +775,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
memset(mdp->rx_ring, 0, rx_ringsize);
/* build Rx ring buffer */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_rx_ring; i++) {
/* skb */
mdp->rx_skbuff[i] = NULL;
skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
@@ -801,7 +801,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
}
}
- mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
+ mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);
/* Mark the last entry as wrapping the ring. */
rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
@@ -809,7 +809,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
memset(mdp->tx_ring, 0, tx_ringsize);
/* build Tx ring buffer */
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_tx_ring; i++) {
mdp->tx_skbuff[i] = NULL;
txdesc = &mdp->tx_ring[i];
txdesc->status = cpu_to_edmac(mdp, TD_TFP);
@@ -843,7 +843,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->rx_buf_sz += NET_IP_ALIGN;
/* Allocate RX and TX skb rings */
- mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
+ mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * mdp->num_rx_ring,
GFP_KERNEL);
if (!mdp->rx_skbuff) {
dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
@@ -851,7 +851,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
return ret;
}
- mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
+ mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * mdp->num_tx_ring,
GFP_KERNEL);
if (!mdp->tx_skbuff) {
dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
@@ -860,7 +860,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
}
/* Allocate all Rx descriptors. */
- rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
GFP_KERNEL);
@@ -874,7 +874,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
mdp->dirty_rx = 0;
/* Allocate all Tx descriptors. */
- tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
GFP_KERNEL);
if (!mdp->tx_ring) {
@@ -903,21 +903,21 @@ static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
int ringsize;
if (mdp->rx_ring) {
- ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
dma_free_coherent(NULL, ringsize, mdp->rx_ring,
mdp->rx_desc_dma);
mdp->rx_ring = NULL;
}
if (mdp->tx_ring) {
- ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
dma_free_coherent(NULL, ringsize, mdp->tx_ring,
mdp->tx_desc_dma);
mdp->tx_ring = NULL;
}
}
-static int sh_eth_dev_init(struct net_device *ndev)
+static int sh_eth_dev_init(struct net_device *ndev, bool start)
{
int ret = 0;
struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -963,7 +963,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
RFLR);
sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
- sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+ if (start)
+ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
/* PAUSE Prohibition */
val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
@@ -978,7 +979,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
/* E-MAC Interrupt Enable register */
- sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
+ if (start)
+ sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
/* Set MAC address */
update_mac_address(ndev);
@@ -991,10 +993,12 @@ static int sh_eth_dev_init(struct net_device *ndev)
if (mdp->cd->tpauser)
sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
- /* Setting the Rx mode will start the Rx process. */
- sh_eth_write(ndev, EDRRR_R, EDRRR);
+ if (start) {
+ /* Setting the Rx mode will start the Rx process. */
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
- netif_start_queue(ndev);
+ netif_start_queue(ndev);
+ }
return ret;
}
@@ -1008,7 +1012,7 @@ static int sh_eth_txfree(struct net_device *ndev)
int entry = 0;
for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
- entry = mdp->dirty_tx % TX_RING_SIZE;
+ entry = mdp->dirty_tx % mdp->num_tx_ring;
txdesc = &mdp->tx_ring[entry];
if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
break;
@@ -1021,7 +1025,7 @@ static int sh_eth_txfree(struct net_device *ndev)
freeNum++;
}
txdesc->status = cpu_to_edmac(mdp, TD_TFP);
- if (entry >= TX_RING_SIZE - 1)
+ if (entry >= mdp->num_tx_ring - 1)
txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
ndev->stats.tx_packets++;
@@ -1036,8 +1040,8 @@ static int sh_eth_rx(struct net_device *ndev)
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_rxdesc *rxdesc;
- int entry = mdp->cur_rx % RX_RING_SIZE;
- int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
+ int entry = mdp->cur_rx % mdp->num_rx_ring;
+ int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx;
struct sk_buff *skb;
u16 pkt_len = 0;
u32 desc_status;
@@ -1088,13 +1092,13 @@ static int sh_eth_rx(struct net_device *ndev)
ndev->stats.rx_bytes += pkt_len;
}
rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
- entry = (++mdp->cur_rx) % RX_RING_SIZE;
+ entry = (++mdp->cur_rx) % mdp->num_rx_ring;
rxdesc = &mdp->rx_ring[entry];
}
/* Refill the Rx ring buffers. */
for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
- entry = mdp->dirty_rx % RX_RING_SIZE;
+ entry = mdp->dirty_rx % mdp->num_rx_ring;
rxdesc = &mdp->rx_ring[entry];
/* The size of the buffer is 16 byte boundary. */
rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
@@ -1111,7 +1115,7 @@ static int sh_eth_rx(struct net_device *ndev)
skb_checksum_none_assert(skb);
rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
}
- if (entry >= RX_RING_SIZE - 1)
+ if (entry >= mdp->num_rx_ring - 1)
rxdesc->status |=
cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
else
@@ -1509,6 +1513,71 @@ static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
}
}
+static void sh_eth_get_ringparam(struct net_device *ndev,
+ struct ethtool_ringparam *ring)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ ring->rx_max_pending = RX_RING_MAX;
+ ring->tx_max_pending = TX_RING_MAX;
+ ring->rx_pending = mdp->num_rx_ring;
+ ring->tx_pending = mdp->num_tx_ring;
+}
+
+static int sh_eth_set_ringparam(struct net_device *ndev,
+ struct ethtool_ringparam *ring)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ int ret;
+
+ if (ring->tx_pending > TX_RING_MAX ||
+ ring->rx_pending > RX_RING_MAX ||
+ ring->tx_pending < TX_RING_MIN ||
+ ring->rx_pending < RX_RING_MIN)
+ return -EINVAL;
+ if (ring->rx_mini_pending || ring->rx_jumbo_pending)
+ return -EINVAL;
+
+ if (netif_running(ndev)) {
+ netif_tx_disable(ndev);
+ /* Disable interrupts by clearing the interrupt mask. */
+ sh_eth_write(ndev, 0x0000, EESIPR);
+ /* Stop the chip's Tx and Rx processes. */
+ sh_eth_write(ndev, 0, EDTRR);
+ sh_eth_write(ndev, 0, EDRRR);
+ synchronize_irq(ndev->irq);
+ }
+
+ /* Free all the skbuffs in the Rx queue. */
+ sh_eth_ring_free(ndev);
+ /* Free DMA buffer */
+ sh_eth_free_dma_buffer(mdp);
+
+ /* Set new parameters */
+ mdp->num_rx_ring = ring->rx_pending;
+ mdp->num_tx_ring = ring->tx_pending;
+
+ ret = sh_eth_ring_init(ndev);
+ if (ret < 0) {
+ dev_err(&ndev->dev, "%s: sh_eth_ring_init failed.\n", __func__);
+ return ret;
+ }
+ ret = sh_eth_dev_init(ndev, false);
+ if (ret < 0) {
+ dev_err(&ndev->dev, "%s: sh_eth_dev_init failed.\n", __func__);
+ return ret;
+ }
+
+ if (netif_running(ndev)) {
+ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+ /* Setting the Rx mode will start the Rx process. */
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
+ netif_wake_queue(ndev);
+ }
+
+ return 0;
+}
+
static const struct ethtool_ops sh_eth_ethtool_ops = {
.get_settings = sh_eth_get_settings,
.set_settings = sh_eth_set_settings,
@@ -1519,6 +1588,8 @@ static const struct ethtool_ops sh_eth_ethtool_ops = {
.get_strings = sh_eth_get_strings,
.get_ethtool_stats = sh_eth_get_ethtool_stats,
.get_sset_count = sh_eth_get_sset_count,
+ .get_ringparam = sh_eth_get_ringparam,
+ .set_ringparam = sh_eth_set_ringparam,
};
/* network device open function */
@@ -1549,7 +1620,7 @@ static int sh_eth_open(struct net_device *ndev)
goto out_free_irq;
/* device init */
- ret = sh_eth_dev_init(ndev);
+ ret = sh_eth_dev_init(ndev, true);
if (ret)
goto out_free_irq;
@@ -1583,7 +1654,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
ndev->stats.tx_errors++;
/* Free all the skbuffs in the Rx queue. */
- for (i = 0; i < RX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_rx_ring; i++) {
rxdesc = &mdp->rx_ring[i];
rxdesc->status = 0;
rxdesc->addr = 0xBADF00D0;
@@ -1591,14 +1662,14 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
dev_kfree_skb(mdp->rx_skbuff[i]);
mdp->rx_skbuff[i] = NULL;
}
- for (i = 0; i < TX_RING_SIZE; i++) {
+ for (i = 0; i < mdp->num_tx_ring; i++) {
if (mdp->tx_skbuff[i])
dev_kfree_skb(mdp->tx_skbuff[i]);
mdp->tx_skbuff[i] = NULL;
}
/* device init */
- sh_eth_dev_init(ndev);
+ sh_eth_dev_init(ndev, true);
}
/* Packet transmit function */
@@ -1610,7 +1681,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
unsigned long flags;
spin_lock_irqsave(&mdp->lock, flags);
- if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) {
+ if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
if (!sh_eth_txfree(ndev)) {
if (netif_msg_tx_queued(mdp))
dev_warn(&ndev->dev, "TxFD exhausted.\n");
@@ -1621,7 +1692,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
spin_unlock_irqrestore(&mdp->lock, flags);
- entry = mdp->cur_tx % TX_RING_SIZE;
+ entry = mdp->cur_tx % mdp->num_tx_ring;
mdp->tx_skbuff[entry] = skb;
txdesc = &mdp->tx_ring[entry];
/* soft swap. */
@@ -1635,7 +1706,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
else
txdesc->buffer_length = skb->len;
- if (entry >= TX_RING_SIZE - 1)
+ if (entry >= mdp->num_tx_ring - 1)
txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
else
txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
@@ -2265,6 +2336,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
ether_setup(ndev);
mdp = netdev_priv(ndev);
+ mdp->num_tx_ring = TX_RING_SIZE;
+ mdp->num_rx_ring = RX_RING_SIZE;
mdp->addr = ioremap(res->start, resource_size(res));
if (mdp->addr == NULL) {
ret = -ENOMEM;
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 9525199..f1dbc27 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -27,6 +27,10 @@
#define TX_TIMEOUT (5*HZ)
#define TX_RING_SIZE 64 /* Tx ring size */
#define RX_RING_SIZE 64 /* Rx ring size */
+#define TX_RING_MIN 64
+#define RX_RING_MIN 64
+#define TX_RING_MAX 1024
+#define RX_RING_MAX 1024
#define ETHERSMALL 60
#define PKT_BUF_SZ 1538
#define SH_ETH_TSU_TIMEOUT_MS 500
@@ -700,6 +704,8 @@ struct sh_eth_private {
const u16 *reg_offset;
void __iomem *addr;
void __iomem *tsu_addr;
+ u32 num_rx_ring;
+ u32 num_tx_ring;
dma_addr_t rx_desc_dma;
dma_addr_t tx_desc_dma;
struct sh_eth_rxdesc *rx_ring;
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 3/5] net: sh_eth: fix up the buffer pointers
From: Shimoda, Yoshihiro @ 2012-06-12 5:19 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
After freeing the buffer, the driver should change the value of
the pointer to NULL.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 31 ++++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 906e410..ff5a4a9 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -745,6 +745,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
}
}
kfree(mdp->rx_skbuff);
+ mdp->rx_skbuff = NULL;
/* Free Tx skb ringbuffer */
if (mdp->tx_skbuff) {
@@ -754,6 +755,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
}
}
kfree(mdp->tx_skbuff);
+ mdp->tx_skbuff = NULL;
}
/* format skb and descriptor buffer */
@@ -890,10 +892,31 @@ desc_ring_free:
skb_ring_free:
/* Free Rx and Tx skb ring buffer */
sh_eth_ring_free(ndev);
+ mdp->tx_ring = NULL;
+ mdp->rx_ring = NULL;
return ret;
}
+static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
+{
+ int ringsize;
+
+ if (mdp->rx_ring) {
+ ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ dma_free_coherent(NULL, ringsize, mdp->rx_ring,
+ mdp->rx_desc_dma);
+ mdp->rx_ring = NULL;
+ }
+
+ if (mdp->tx_ring) {
+ ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ dma_free_coherent(NULL, ringsize, mdp->tx_ring,
+ mdp->tx_desc_dma);
+ mdp->tx_ring = NULL;
+ }
+}
+
static int sh_eth_dev_init(struct net_device *ndev)
{
int ret = 0;
@@ -1629,7 +1652,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
static int sh_eth_close(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- int ringsize;
netif_stop_queue(ndev);
@@ -1652,12 +1674,7 @@ static int sh_eth_close(struct net_device *ndev)
sh_eth_ring_free(ndev);
/* free DMA buffer */
- ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
- dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma);
-
- /* free DMA buffer */
- ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
- dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
+ sh_eth_free_dma_buffer(mdp);
pm_runtime_put_sync(&mdp->pdev->dev);
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 2/5] net: sh_eth: remove unnecessary members/definitions
From: Shimoda, Yoshihiro @ 2012-06-12 5:19 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This patch removes unnecessary members in sh_th_private.
This patch also removes unnecessary definitions in sh_eth.h
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 7 +---
drivers/net/ethernet/renesas/sh_eth.h | 69 ---------------------------------
2 files changed, 1 insertions(+), 75 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 4ccfd0f..906e410 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -898,7 +898,6 @@ static int sh_eth_dev_init(struct net_device *ndev)
{
int ret = 0;
struct sh_eth_private *mdp = netdev_priv(ndev);
- u_int32_t rx_int_var, tx_int_var;
u32 val;
/* Soft Reset */
@@ -926,9 +925,7 @@ static int sh_eth_dev_init(struct net_device *ndev)
/* Frame recv control */
sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);
- rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
- tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
- sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);
+ sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER);
if (mdp->cd->bculr)
sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */
@@ -2288,8 +2285,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
/* debug message level */
mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
- mdp->post_rx = POST_RX >> (devno << 1);
- mdp->post_fw = POST_FW >> (devno << 1);
/* read and set MAC address */
read_mac_address(ndev, pd->mac_addr);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 9e8e4d5..9525199 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -585,71 +585,6 @@ enum RPADIR_BIT {
/* FDR */
#define DEFAULT_FDR_INIT 0x00000707
-enum phy_offsets {
- PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
- PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
- PHY_16 = 16,
-};
-
-/* PHY_CTRL */
-enum PHY_CTRL_BIT {
- PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000,
- PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400,
- PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080,
-};
-#define DM9161_PHY_C_ANEGEN 0 /* auto nego special */
-
-/* PHY_STAT */
-enum PHY_STAT_BIT {
- PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000,
- PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020,
- PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004,
- PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001,
-};
-
-/* PHY_ANA */
-enum PHY_ANA_BIT {
- PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
- PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
- PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
- PHY_A_SEL = 0x001e,
-};
-/* PHY_ANL */
-enum PHY_ANL_BIT {
- PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000,
- PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100,
- PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020,
- PHY_L_SEL = 0x001f,
-};
-
-/* PHY_ANE */
-enum PHY_ANE_BIT {
- PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004,
- PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001,
-};
-
-/* DM9161 */
-enum PHY_16_BIT {
- PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000,
- PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800,
- PHY_16_TXselect = 0x0400,
- PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100,
- PHY_16_Force100LNK = 0x0080,
- PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020,
- PHY_16_RPDCTR_EN = 0x0010,
- PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004,
- PHY_16_Sleepmode = 0x0002,
- PHY_16_RemoteLoopOut = 0x0001,
-};
-
-#define POST_RX 0x08
-#define POST_FW 0x04
-#define POST0_RX (POST_RX)
-#define POST0_FW (POST_FW)
-#define POST1_RX (POST_RX >> 2)
-#define POST1_FW (POST_FW >> 2)
-#define POST_ALL (POST0_RX | POST0_FW | POST1_RX | POST1_FW)
-
/* ARSTR */
enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, };
@@ -785,10 +720,6 @@ struct sh_eth_private {
int msg_enable;
int speed;
int duplex;
- u32 rx_int_var, tx_int_var; /* interrupt control variables */
- char post_rx; /* POST receive */
- char post_fw; /* POST forward */
- struct net_device_stats tsu_stats; /* TSU forward status */
int port; /* for TSU */
int vlan_num_ids; /* for VLAN tag filter */
--
1.7.1
^ permalink raw reply related
* [PATCH net-next 1/5] net: sh_eth: remove unnecessary function
From: Shimoda, Yoshihiro @ 2012-06-12 5:18 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
The sh_eth_timer() called mod_timer() for itself.
So, this patch removes the function.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/ethernet/renesas/sh_eth.c | 22 ----------------------
drivers/net/ethernet/renesas/sh_eth.h | 1 -
2 files changed, 0 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 667169b..4ccfd0f 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1291,14 +1291,6 @@ other_irq:
return ret;
}
-static void sh_eth_timer(unsigned long data)
-{
- struct net_device *ndev = (struct net_device *)data;
- struct sh_eth_private *mdp = netdev_priv(ndev);
-
- mod_timer(&mdp->timer, jiffies + (10 * HZ));
-}
-
/* PHY state control function */
static void sh_eth_adjust_link(struct net_device *ndev)
{
@@ -1546,11 +1538,6 @@ static int sh_eth_open(struct net_device *ndev)
if (ret)
goto out_free_irq;
- /* Set the timer to check for link beat. */
- init_timer(&mdp->timer);
- mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
- setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev);
-
return ret;
out_free_irq:
@@ -1575,9 +1562,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
/* tx_errors count up */
ndev->stats.tx_errors++;
- /* timer off */
- del_timer_sync(&mdp->timer);
-
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
rxdesc = &mdp->rx_ring[i];
@@ -1595,10 +1579,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
/* device init */
sh_eth_dev_init(ndev);
-
- /* timer on */
- mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
- add_timer(&mdp->timer);
}
/* Packet transmit function */
@@ -1671,8 +1651,6 @@ static int sh_eth_close(struct net_device *ndev)
free_irq(ndev->irq, ndev);
- del_timer_sync(&mdp->timer);
-
/* Free all the skbuffs in the Rx queue. */
sh_eth_ring_free(ndev);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 57b8e1f..9e8e4d5 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -771,7 +771,6 @@ struct sh_eth_private {
struct sh_eth_txdesc *tx_ring;
struct sk_buff **rx_skbuff;
struct sk_buff **tx_skbuff;
- struct timer_list timer;
spinlock_t lock;
u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */
u32 cur_tx, dirty_tx;
--
1.7.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox