* Re: [PATCH] phy: Elimination the forced speed reduction algorithm.
From: David Miller @ 2013-03-15 12:51 UTC (permalink / raw)
To: joe
Cc: kapranoff, netdev, bhutchings, peppe.cavallaro, bruce.w.allan,
linux-kernel
In-Reply-To: <1363351729.2433.4.camel@joe-AO722>
From: Joe Perches <joe@perches.com>
Date: Fri, 15 Mar 2013 05:48:49 -0700
> The phy code also uses non standard kernel style tests like
> if (CONSTANT == variable)
> instead of
> if (variable == CONSTANT)
Right, to trigger compile time errors when "=" is accidently used
instead of "==".
But the whole driver is like this already.
^ permalink raw reply
* Re: [PATCH 0/4] mv643xx_eth: use mvmdio MDIO bus driver
From: Florian Fainelli @ 2013-03-15 12:51 UTC (permalink / raw)
To: David Miller
Cc: grant.likely, rob.herring, rob, jason, andrew, linux, benh,
paulus, buytenh, thomas.petazzoni, gregkh, devicetree-discuss,
linux-doc, linux-kernel, linux-arm-kernel, linuxppc-dev, netdev
In-Reply-To: <20130315.085321.1047694772636447477.davem@davemloft.net>
Le 03/15/13 13:53, David Miller a écrit :
> From: Florian Fainelli <florian@openwrt.org>
> Date: Thu, 14 Mar 2013 19:08:31 +0100
>
>> This patch converts the mv643xx_eth driver to use the mvmdio MDIO bus driver
>> instead of rolling its own implementation. As a result, all users of this
>> mv643xx_eth driver are converted to register an "orion-mdio" platform_device.
>> The mvmdio driver is also updated to support an interrupt line which reports
>> SMI error/completion, and to allow traditionnal platform device registration
>> instead of just device tree.
>>
>> David, I think it makes sense for you to merge all of this, since we do
>> not want the architecture files to be desynchronized from the mv643xx_eth to
>> avoid runtime breakage. The potential for merge conflicts should be very small.
>
> All applied to net-next, thanks.
>
Oh woah that was fast, maybe too fast, I will submit a follow-up patch
for patch 4 to address the issues I mentionned earlier.
--
Florian
^ permalink raw reply
* Re: [PATCH] phy: Elimination the forced speed reduction algorithm.
From: Joe Perches @ 2013-03-15 12:48 UTC (permalink / raw)
To: David Miller
Cc: kapranoff, netdev, bhutchings, peppe.cavallaro, bruce.w.allan,
linux-kernel
In-Reply-To: <20130315.083524.1244515166306242265.davem@davemloft.net>
On Fri, 2013-03-15 at 08:35 -0400, David Miller wrote:
> From: Kirill Kapranov <kapranoff@inbox.ru>
> Date: Thu, 14 Mar 2013 14:40:52 +0400
>
> > @@ -867,7 +821,6 @@ void phy_state_machine(struct work_struct *work)
> > netif_carrier_on(phydev->attached_dev);
> > } else {
> > if (0 == phydev->link_timeout--) {
> > - phy_force_reduction(phydev);
> > needs_aneg = 1;
> > }
>
> This is not a single-statement basic block, and therefore you
> should remove the surrounding braces.
s/not/now/
The phy code also uses non standard kernel style tests like
if (CONSTANT == variable)
instead of
if (variable == CONSTANT)
^ permalink raw reply
* Re: [PATCH 3.9-rc2] net: fec: fix missing napi_disable call
From: David Miller @ 2013-03-15 12:47 UTC (permalink / raw)
To: georg; +Cc: netdev, grant.likely, rob.herring
In-Reply-To: <1363280049.3967.21.camel@gh-dell>
From: Georg Hofmann <georg@hofmannsweb.com>
Date: Thu, 14 Mar 2013 17:54:09 +0100
> Commit dc975382d2ef36be7e78fac3717927de1a5abcd8 introduces napi support
> but never calls napi_disable. This will generate a kernel oops
> (kernel BUG at include/linux/netdevice.h:473!) every time, when
> ndo_stop is called followed by ndo_start.
> Add the missing napi_diable call.
>
> Signed-off-by: Georg Hofmann <georg@hofmannsweb.com>
Applied.
^ permalink raw reply
* Re: [PATCH] net: fec: restart the FEC when PHY speed changes
From: David Miller @ 2013-03-15 12:47 UTC (permalink / raw)
To: l.stach; +Cc: netdev, Frank.Li
In-Reply-To: <1363273921-5035-1-git-send-email-l.stach@pengutronix.de>
From: Lucas Stach <l.stach@pengutronix.de>
Date: Thu, 14 Mar 2013 16:12:01 +0100
> Proviously we would only restart the FEC when PHY link or duplex state
> changed. PHY does not always bring down the link for speed changes, in
> which case we would not detect any change and keep FEC running.
>
> Switching link speed without restarting the FEC results in the FEC being
> stuck in an indefinite state, generating error conditions for every
> packet.
>
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Applied.
^ permalink raw reply
* Re: [PATCH] phy: Elimination the forced speed reduction algorithm.
From: David Miller @ 2013-03-15 12:35 UTC (permalink / raw)
To: kapranoff
Cc: netdev, bhutchings, peppe.cavallaro, joe, bruce.w.allan,
linux-kernel
In-Reply-To: <1363257652-8255-1-git-send-email-kapranoff@inbox.ru>
From: Kirill Kapranov <kapranoff@inbox.ru>
Date: Thu, 14 Mar 2013 14:40:52 +0400
> @@ -867,7 +821,6 @@ void phy_state_machine(struct work_struct *work)
> netif_carrier_on(phydev->attached_dev);
> } else {
> if (0 == phydev->link_timeout--) {
> - phy_force_reduction(phydev);
> needs_aneg = 1;
> }
This is not a single-statement basic block, and therefore you
should remove the surrounding braces.
^ permalink raw reply
* Re: [PATCH] isdn: hisax: netjet requires VIRT_TO_BUS
From: David Miller @ 2013-03-15 12:33 UTC (permalink / raw)
To: arnd; +Cc: geert, linux-kernel, linux-arm-kernel, isdn, netdev, dhowells
In-Reply-To: <201303151229.52997.arnd@arndb.de>
From: Arnd Bergmann <arnd@arndb.de>
Date: Fri, 15 Mar 2013 12:29:52 +0000
> On Friday 15 March 2013, David Miller wrote:
>> I do not want to see us add such a Kconfig dependency knob.
>>
>> Then the real tendency will exist to make new drivers little-endian
>> only, refuse to fix endian-broken old drivers, etc.
>>
>> Which means that allmodconfig on my architecture will have build
>> coverage on less code, which is really the only thing that matters
>> for me. I want all drivers that could be effected by my changes
>> to be compile testable on as many platforms as possible.
>
> There are two separate issues here. The first one that David Howells
> brought up was ill-defined __BIG_ENDIAN/__LITTLE_ENDIAN macros.
> Using CONFIG_CPU_IS_BIG_ENDIAN/CONFIG_CPU_IS_LITTLE_ENDIAN in the code
> is what Linus suggested as a replacement, although I see little
> incentive to do mass conversion there, it would be mainly for new
> code.
>
> The other issue is the Kconfig logic where Geert would replace
> all the instances of "depends on BROKEN || !(SPARC || PPC || PARISC ||
> M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA &&
> !CPU_LITTLE_ENDIAN))" with something that actually reflects what
> we mean. I think it would be a nice cleanup, but I can also understand
> your hesitation there.
>
> Do you object to both uses of that symbol, or just to using it in order
> to disable drivers in Kconfig? I don't care too much right now, since
> nothing is actually broken at the moment, I would just like to get
> the VIRT_TO_BUS patch merged so people can also build allmodconfig
> on my architecture ;-)
The first usage seems reason, but the temtation is going to be quite
strong to misuse to block out drivers when there is "no value" in
spending time necessary to simply make them endian clean instead.
^ permalink raw reply
* Re: net: clean leftover of COMPAT_NET_DEV_OPS removal
From: David Miller @ 2013-03-15 12:31 UTC (permalink / raw)
To: fernando_b1; +Cc: netdev
In-Reply-To: <1363229845.5774.2.camel@nexus>
From: Fernando Luis Vázquez Cao <fernando_b1@lab.ntt.co.jp>
Date: Thu, 14 Mar 2013 11:57:25 +0900
> COMPAT_NET_DEV_OPS was removed a while back and with it the definition of
> netdev_resync_ops() went away. Let's finish the clean-up.
>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] isdn: hisax: netjet requires VIRT_TO_BUS
From: Arnd Bergmann @ 2013-03-15 12:29 UTC (permalink / raw)
To: David Miller
Cc: geert, linux-kernel, linux-arm-kernel, isdn, netdev, dhowells
In-Reply-To: <20130315.081659.636423702994054939.davem@davemloft.net>
On Friday 15 March 2013, David Miller wrote:
> I do not want to see us add such a Kconfig dependency knob.
>
> Then the real tendency will exist to make new drivers little-endian
> only, refuse to fix endian-broken old drivers, etc.
>
> Which means that allmodconfig on my architecture will have build
> coverage on less code, which is really the only thing that matters
> for me. I want all drivers that could be effected by my changes
> to be compile testable on as many platforms as possible.
There are two separate issues here. The first one that David Howells
brought up was ill-defined __BIG_ENDIAN/__LITTLE_ENDIAN macros.
Using CONFIG_CPU_IS_BIG_ENDIAN/CONFIG_CPU_IS_LITTLE_ENDIAN in the code
is what Linus suggested as a replacement, although I see little
incentive to do mass conversion there, it would be mainly for new
code.
The other issue is the Kconfig logic where Geert would replace
all the instances of "depends on BROKEN || !(SPARC || PPC || PARISC ||
M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA &&
!CPU_LITTLE_ENDIAN))" with something that actually reflects what
we mean. I think it would be a nice cleanup, but I can also understand
your hesitation there.
Do you object to both uses of that symbol, or just to using it in order
to disable drivers in Kconfig? I don't care too much right now, since
nothing is actually broken at the moment, I would just like to get
the VIRT_TO_BUS patch merged so people can also build allmodconfig
on my architecture ;-)
Arnd
^ permalink raw reply
* Re: [PATCH] VSOCK: Support VM sockets connected to the hypervisor.
From: David Miller @ 2013-03-15 12:25 UTC (permalink / raw)
To: grantr; +Cc: netdev, linux-kernel, pv-drivers
In-Reply-To: <1363117219-21911-1-git-send-email-grantr@vmware.com>
From: Reilly Grant <grantr@vmware.com>
Date: Tue, 12 Mar 2013 12:40:19 -0700
> The resource ID used for VM socket control packets (0) is already
> used for the VMCI_GET_CONTEXT_ID hypercall so a new ID (15) must be
> used when the guest sends these datagrams to the hypervisor.
>
> The hypervisor context ID must also be removed from the internal
> blacklist.
>
> Signed-off-by: Reilly Grant <grantr@vmware.com>
> Acked-by: Andy King <acking@vmware.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next v3] netxen: write IP address to firmware when using bonding
From: David Miller @ 2013-03-15 12:23 UTC (permalink / raw)
To: rajesh.borundia; +Cc: nikolay, netdev, agospoda, sony.chacko
In-Reply-To: <C562D0E12CBDE44E8A0CCAB7706009672C0F0F@AVMB1.qlogic.org>
From: Rajesh Borundia <rajesh.borundia@qlogic.com>
Date: Wed, 13 Mar 2013 11:51:46 +0000
> -----Original Message-----
>>From: Nikolay Aleksandrov [mailto:nikolay@redhat.com]
>>Sent: Tuesday, March 12, 2013 6:19 PM
>>To: netdev
>>Cc: Rajesh Borundia; David Miller; agospoda@redhat.com; Sony Chacko
>>Subject: [PATCH net-next v3] netxen: write IP address to firmware when
>>using bonding
>>
>>This patch allows LRO aggregation on bonded devices that contain an
>>NX3031 device. It also adds a for_each_netdev_in_bond_rcu(bond, slave)
>>macro which executes for each slave that has bond as master.
>>
>>V3: After testing and discussing this with Rajesh, I decided to keep the
>> vlan ip cache and just rename it to ip_cache since it will store
>>bond
>> ip addresses too. A new master flag has been added to the ip cache
>>to
>> denote that the address has been added because of a master device.
>> I've taken care of the enslave/release cases by checking for various
>> combinations of events and flags (e.g. netxen has a master, it's a
>> bond master and it's not marked as a slave means it is being
>>enslaved
>> and is dev_open()ed in bond_enslave).
>> I've changed netxen_free_ip_list() to have a "master" parameter
>>which
>> causes all IP addresses marked as master to be deleted (used when a
>> netxen is being released). I've made the patch use the new upper
>> device API as well. The following cases were tested:
>> - bond -> netxen
>> - vlan -> netxen
>> - vlan -> bond -> netxen
>
> Acked-by : Rajesh Borundia <rajesh.borundia@qlogic.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] isdn: hisax: netjet requires VIRT_TO_BUS
From: David Miller @ 2013-03-15 12:16 UTC (permalink / raw)
To: arnd; +Cc: geert, linux-kernel, linux-arm-kernel, isdn, netdev, dhowells
In-Reply-To: <201303151015.00746.arnd@arndb.de>
From: Arnd Bergmann <arnd@arndb.de>
Date: Fri, 15 Mar 2013 10:15:00 +0000
> David Howells brought up the topic of endian checks recently, noting
> that the way we define __BIG_ENDIAN and __LITTLE_ENDIAN in the kernel
> is incompatible to how do it in user space, and not much better either.
>
> A few architectures that are bi-endian (arc, arm, c6x, mips, sh) already
> have CONFIG_CPU_IS_LITTLE_ENDIAN and CONFIG_CPU_IS_BIG_ENDIAN. I guess
> it would be a good idea to provide these on all architectures.
I do not want to see us add such a Kconfig dependency knob.
Then the real tendency will exist to make new drivers little-endian
only, refuse to fix endian-broken old drivers, etc.
Which means that allmodconfig on my architecture will have build
coverage on less code, which is really the only thing that matters
for me. I want all drivers that could be effected by my changes
to be compile testable on as many platforms as possible.
^ permalink raw reply
* Re: sky2 negotiating only 100Mb/s (88E8055)
From: Rafał Miłecki @ 2013-03-15 12:03 UTC (permalink / raw)
To: Network Development, Mirko Lindner, Stephen Hemminger
In-Reply-To: <CACna6ry1z1LS9wMDb9dYyM+9z8kEpZADXKHL0NNoAahbm8wbNg@mail.gmail.com>
2013/3/3 Rafał Miłecki <zajec5@gmail.com>:
> I've problems with my:
> 08:00.0 Ethernet controller [0200]: Marvell Technology Group Ltd.
> 88E8055 PCI-E Gigabit Ethernet Controller [11ab:4363] (rev 13)
> using 3.4.28 kernel on my Sony notebook.
>
> I've tried connecting it to the:
> 1) HP#1 (Intel card)
> 2) HP#2 (Broadcom card)
> 3) Router based on BCM4706 with BCM53125 switch
> I've tried two different CAT5e cables for all the above devices. In
> every case sky2 established 100Mbps link only. It couldn't achieve
> 1000Mb/s. Forcing it to 1000Mbps broke link. Lower speeds (100 half
> duplex and 10 Mbps) are working fine.
>
> It's not the issue with the cable or devices, because all other
> configurations are working fine. I can connect:
> 1) HP#1 with HP#2
> 2) HP#1 with router
> 3) HP#2 with router
> and I always get 1000Mbps.
>
> So it looks like some bugged hardware or (more likely?) issue in sky2.
>
> sky2 0000:08:00.0: eth0: disabling interface
> sky2: driver version 1.30
> sky2 0000:08:00.0: Yukon-2 EC Ultra chip revision 3
> sky2 0000:08:00.0: irq 47 for MSI/MSI-X
> sky2 0000:08:00.0: eth0: addr 00:1d:ba:19:9e:db
> sky2 0000:08:00.0: eth0: enabling interface
> sky2 0000:08:00.0: eth0: Link is up at 100 Mbps, full duplex, flow control both
>
> Can you help me with that?
Ping?
--
Rafał
^ permalink raw reply
* Re: [PATCH] netfilter: register pernet subsystem before register L4 proto
From: Pablo Neira Ayuso @ 2013-03-15 11:55 UTC (permalink / raw)
To: Gao feng; +Cc: netdev, netfilter-devel, ebiederm, Alexey Dobriyan
In-Reply-To: <1362712846-12954-1-git-send-email-gaofeng@cn.fujitsu.com>
On Fri, Mar 08, 2013 at 11:20:46AM +0800, Gao feng wrote:
> In commit c296bb4d5d417d466c9bcc8afef68a3db5449a64
> "netfilter: nf_conntrack: refactor l4proto support for netns",
> we register l4proto gre/dccp/udplite/sctp before register
> pernet subsystem,it's a wrong order.
>
> We should register pernet subsystem before register L4proto,
> since after register L4proto, init_conntrack may try to access
> the resources which allocated in register_pernet_subsys.
Applied to nf tree, thanks.
^ permalink raw reply
* Re: [PATCH net-next] ipv6: use ipv6_iface_scope_id in conntrack to return scope id
From: Pablo Neira Ayuso @ 2013-03-15 11:48 UTC (permalink / raw)
To: netfilter-devel, yoshfuji, netdev
In-Reply-To: <20130312212136.GB14801@order.stressinduktion.org>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] bridge: netfilter: use PTR_RET instead of IS_ERR + PTR_ERR
From: Pablo Neira Ayuso @ 2013-03-15 11:48 UTC (permalink / raw)
To: Silviu-Mihai Popescu
Cc: netfilter-devel, bart.de.schuymer, kaber, stephen, davem,
netfilter, coreteam, bridge, netdev, linux-kernel
In-Reply-To: <1363111893-25146-1-git-send-email-silviupopescu1990@gmail.com>
On Tue, Mar 12, 2013 at 08:11:33PM +0200, Silviu-Mihai Popescu wrote:
> This uses PTR_RET instead of IS_ERR and PTR_ERR in order to increase
> readability.
Also applied, thanks.
^ permalink raw reply
* Re: [PATCH] ipv4: netfilter: use PTR_RET instead of IS_ERR + PTR_ERR
From: Pablo Neira Ayuso @ 2013-03-15 11:48 UTC (permalink / raw)
To: Silviu-Mihai Popescu
Cc: netfilter-devel, kaber, davem, kuznet, jmorris, yoshfuji,
coreteam, netdev, linux-kernel
In-Reply-To: <1363111675-21457-1-git-send-email-silviupopescu1990@gmail.com>
On Tue, Mar 12, 2013 at 08:07:55PM +0200, Silviu-Mihai Popescu wrote:
> This uses PTR_RET instead of IS_ERR and PTR_ERR in order to increase
> readability.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 4/4 v2] mv643xx_eth: convert to use the Marvell Orion MDIO driver
From: Thomas Petazzoni @ 2013-03-15 11:42 UTC (permalink / raw)
To: Florian Fainelli
Cc: davem, Grant Likely, Rob Herring, Rob Landley, Jason Cooper,
Andrew Lunn, Russell King, Benjamin Herrenschmidt, Paul Mackerras,
Lennert Buytenhek, Greg Kroah-Hartman, devicetree-discuss,
linux-doc, linux-kernel, linux-arm-kernel, linuxppc-dev, netdev
In-Reply-To: <514300E0.2030108@openwrt.org>
Dear Florian Fainelli,
On Fri, 15 Mar 2013 12:07:12 +0100, Florian Fainelli wrote:
> Thanks to the help of Andrew Lunn, there is at least two known issues
> with this patch version:
>
> - we need to move up the mvmdio line in
> drivers/net/ethernet/marvell/Makefile to make sure that configs having
> both mvmdio and mv643xx_eth built-in get the probing order right
I don't think it's the right way of fixing the problem. If there is no
dependency on the two devices through the device model (i.e they don't
have a parent->child relationship), then the mv643xx_eth driver should
probably return -EPROBE_DEFER when it can't find its PHY so that its
->probe() operation gets called once again by the kernel when other
drivers (including mvmdio) have been probed.
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* Re: linux-3.6+, gre+ipsec+forwarding = IP fragmentation broken
From: Timo Teras @ 2013-03-15 11:38 UTC (permalink / raw)
To: netdev
In-Reply-To: <20130315112516.4b1651ca@vostro>
On Fri, 15 Mar 2013 11:25:16 +0200
Timo Teras <timo.teras@iki.fi> wrote:
> On Wed, 13 Mar 2013 17:14:53 +0200
> Timo Teras <timo.teras@iki.fi> wrote:
>
> > In the typical DMVPN setup with IPv4-ESP-GRE-IPv4 stack, it seems
> > that IPv4 fragmentation got broke around 3.6 for forwarded packets.
> >
> > It would seem that fragmentation works for locally generated
> > packets. Also PMTU (DF set) seems to work for both forwarded and
> > locally generated packets. But forwarded packets to gre device that
> > gets IPsec encrypted do not get fragmented properly.
> >
> > 3.4.x kernels work, 3.6 and 3.8 series tested and fail similarly.
>
> Actually 3.4.x vanilla does not work. It works only with 38d523e
> "ipv4: Remove output route check in ipv4_mtu" applied which I've been
> cherry-picking to my builds.
>
> > I was going through the changelog and it seems that MTU is now
> > handled in nexthop exceptions and one needs to produce the full
> > flow info to update it. I'm wonding if this does not hold true in
> > my code path as ip_gre rewraps the forwarded packet and creates new
> > IP header - when it next goes to the xfrm code (which sends the
> > ICMP error) the inner iphdr is no longer accessible. Would this
> > cause the breakage that I'm seeing? Or the forward flow's mtu still
> > updated somehow?
>
> I have now a theory on what goes wrong.
>
> My gre tunnel is configured with 'ttl 64' so the tunnel IP header
> always gets DF bit set to do proper path-mtu. The kind of locally
> generated ICMP messages I get, imply that re-fragmentation happens
> only on the tunnel's IPv4 header level - but it'll be too late then:
> the large packet is queued, IPsec'ed and it is the IPsec'ed packet
> that gets is tried to be fragmented (but it has DF set so it fails and
> packet is dropped).
>
> I believe ip_gre should explicitly fragment the inner IPv4 and IPv6
> packets if the tunnel's ttl is not inherited (resulting in DF bit set
> in the tunnel's IPv4 header).
>
> So basically ip_gre worked wrong all along - things just happened to
> work due to GRO/GSO not implemented in ip_gre, and the way (the now
> deleted) routing cache exposed pmtu.
>
> Does this make sense?
Not really. Seems the fragmentation should happen already on the
earlier dst level. Though, this implies that GSO cannot be used in
ip_gre if ttl != inherit.
I added some ip_gre debugging and the following seems to happen:
- the mtu is calculated correctly on xmit path:
dst_mtu(&rt->dst) = 1458 (the tunnel's XFRMed IPv4 path)
- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
is called with mtu=1430, which seems correct
- dst_mtu(skb_dst(skb)) seems to still return after above call the
value 1472 which is wrong. so update_pmtu is not working.
- skb->dev->ifindex implies skb->dev points to gre device when
update_pmtu is being called (and not the ethX from which the packet
was received), so ip_rt_update_pmtu() which eventually calls
build_skb_flow_key() is likely using wrong ifindex for the flow
- Timo
^ permalink raw reply
* Re: [PATCH 4/4 v2] mv643xx_eth: convert to use the Marvell Orion MDIO driver
From: Florian Fainelli @ 2013-03-15 11:07 UTC (permalink / raw)
To: Florian Fainelli
Cc: davem, Grant Likely, Rob Herring, Rob Landley, Jason Cooper,
Andrew Lunn, Russell King, Benjamin Herrenschmidt, Paul Mackerras,
Lennert Buytenhek, Thomas Petazzoni, Greg Kroah-Hartman,
devicetree-discuss, linux-doc, linux-kernel, linux-arm-kernel,
linuxppc-dev, netdev
In-Reply-To: <1363284515-9865-5-git-send-email-florian@openwrt.org>
Le 03/14/13 19:08, Florian Fainelli a écrit :
> This patch converts the Marvell MV643XX ethernet driver to use the
> Marvell Orion MDIO driver. As a result, PowerPC and ARM platforms
> registering the Marvell MV643XX ethernet driver are also updated to
> register a Marvell Orion MDIO driver. This driver voluntarily overlaps
> with the Marvell Ethernet shared registers because it will use a subset
> of this shared register (shared_base + 0x4 - shared_base + 0x84). The
> Ethernet driver is also updated to look up for a PHY device using the
> Orion MDIO bus driver.
Thanks to the help of Andrew Lunn, there is at least two known issues
with this patch version:
- we need to move up the mvmdio line in
drivers/net/ethernet/marvell/Makefile to make sure that configs having
both mvmdio and mv643xx_eth built-in get the probing order right
- the bus name used by mv643xx_eth is not the right now (orion-mdio.0 vs
expected orion-mdio) so the PHY device will not be found during
phy_connect()
I will fix these two issues in the next version of the patchset.
--
Florian
^ permalink raw reply
* Re: [PATCH] isdn: hisax: netjet requires VIRT_TO_BUS
From: Arnd Bergmann @ 2013-03-15 10:15 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-kernel, linux-arm-kernel, Karsten Keil, netdev,
David Howells
In-Reply-To: <CAMuHMdVhjnX_hag5Y5VvDWVcjPK8tMM-qx-TQ2x=M88yTZQwYg@mail.gmail.com>
On Friday 15 March 2013, Geert Uytterhoeven wrote:
> On Thu, Mar 14, 2013 at 10:56 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > Disabling CONFIG_VIRT_TO_BUS on ARM showed that the hisax netjet
> > driver depends on this deprecated functionality but is not
> > marked so in Kconfig.
> >
> > Rather than adding ARM to the already long list of architectures
> > that this driver is broken on, this patch adds 'depends on
> > VIRT_TO_BUS' and removes the dependency on !SPARC, which is
> > also implied by that.
>
> IIRC, the real "arch" dependency for this driver is !BIG_ENDIAN, but
> unfortunately
> we don't have a generic Kconfig symbol for that.
> Perhaps we may want to introduce that?
> Of course we prefer to make drivers work on all endianness instead...
CONFIG_VIRT_TO_BUS is certainly also a dependency, since it fails
to build without that. I think we can address the two problems separately.
David Howells brought up the topic of endian checks recently, noting
that the way we define __BIG_ENDIAN and __LITTLE_ENDIAN in the kernel
is incompatible to how do it in user space, and not much better either.
A few architectures that are bi-endian (arc, arm, c6x, mips, sh) already
have CONFIG_CPU_IS_LITTLE_ENDIAN and CONFIG_CPU_IS_BIG_ENDIAN. I guess
it would be a good idea to provide these on all architectures.
Arnd
^ permalink raw reply
* [PATCHv3 vringh] caif_virtio: Introduce caif over virtio
From: Erwan Yvin @ 2013-03-15 9:42 UTC (permalink / raw)
To: David S. Miller, Rusty Russel
Cc: Sjur Braendeland, Linus Walleij, Ohad Ben-Cohen, virtualization,
netdev, Erwan Yvin, Rusty Russell
From: Erwan Yvin <erwan.yvin@stericsson.com>
Add the CAIF Virtio shared memory driver for talking
to a modem.
This CAIF Link layer communicates to the modem over
shared memory. It is implemented as a virtio_driver.
The underlying virtio device is managed by the remoteproc
framework. The Virtio queue is used for transmitting data
to the modem, and the new vringh is used for receiving data.
Genalloc is used for managing the shared memory used for TX
data. The default dma-alloc-coherent allocator can only
allocate whole pages, and this wastes too much shared memory.
Flow control is implemented by stopping the TX-queues if the
virtio queues go full or we run out of memory. Queued are
reopened when queues are below the watermark.
NAPI is used in RX path, and a dedicated tasklet is used
for releasing TX buffers.
Signed-off-by: Erwan Yvin <erwan.yvin@stericsson.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Rusty Russell <rusty@rustcorp.com.au>
---
caif-virtio is going to replace caif-shm.
This patch should be merged in rusty's tree. (vringh)
because there is a dependency with vringh wrapper.
Best Regards
drivers/net/caif/Kconfig | 13 +
drivers/net/caif/Makefile | 3 +
drivers/net/caif/caif_virtio.c | 786 +++++++++++++++++++++++++++++++++++++++
include/linux/virtio_caif.h | 24 ++
include/uapi/linux/virtio_ids.h | 1 +
5 files changed, 827 insertions(+)
create mode 100644 drivers/net/caif/caif_virtio.c
create mode 100644 include/linux/virtio_caif.h
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
index abf4d7a..604d274 100644
--- a/drivers/net/caif/Kconfig
+++ b/drivers/net/caif/Kconfig
@@ -47,3 +47,16 @@ config CAIF_HSI
The caif low level driver for CAIF over HSI.
Be aware that if you enable this then you also need to
enable a low-level HSI driver.
+
+config CAIF_VIRTIO
+ tristate "CAIF virtio transport driver"
+ depends on CAIF
+ select VHOST_RING
+ select VIRTIO
+ default n
+ ---help---
+ The caif driver for CAIF over Virtio.
+
+if CAIF_VIRTIO
+source "drivers/vhost/Kconfig"
+endif
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
index 91dff86..d9ee26a 100644
--- a/drivers/net/caif/Makefile
+++ b/drivers/net/caif/Makefile
@@ -13,3 +13,6 @@ obj-$(CONFIG_CAIF_SHM) += caif_shm.o
# HSI interface
obj-$(CONFIG_CAIF_HSI) += caif_hsi.o
+
+# Virtio interface
+obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
new file mode 100644
index 0000000..6a745dd
--- /dev/null
+++ b/drivers/net/caif/caif_virtio.c
@@ -0,0 +1,786 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2013
+ * Authors: Vicram Arv / vikram.arv@stericsson.com,
+ * Dmitry Tarnyagin / dmitry.tarnyagin@stericsson.com
+ * Sjur Brendeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/module.h>
+#include <linux/if_arp.h>
+#include <linux/virtio.h>
+#include <linux/vringh.h>
+#include <linux/debugfs.h>
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/remoteproc.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_caif.h>
+#include <linux/virtio_ring.h>
+#include <linux/dma-mapping.h>
+#include <net/caif/caif_dev.h>
+#include <linux/virtio_config.h>
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Vicram Arv <vikram.arv@stericsson.com>");
+MODULE_AUTHOR("Sjur Brendeland <sjur.brandeland@stericsson.com>");
+MODULE_DESCRIPTION("Virtio CAIF Driver");
+
+/* NAPI schedule quota */
+#define CFV_DEFAULT_QUOTA 32
+
+/* Defaults used if virtio config space is unavailable */
+#define CFV_DEF_MTU_SIZE 4096
+#define CFV_DEF_HEADROOM 32
+#define CFV_DEF_TAILROOM 32
+
+/* Required IP header alignment */
+#define IP_HDR_ALIGN 4
+
+/* struct cfv_napi_contxt - NAPI context info
+ * @riov: IOV holding data read from the ring. Note that riov may
+ * still hold data when cfv_rx_poll() returns.
+ * @head: Last descriptor ID we received from vringh_getdesc_kern.
+ * We use this to put descriptor back on the used ring. USHRT_MAX is
+ * used to indicate invalid head-id.
+ */
+struct cfv_napi_context {
+ struct vringh_kiov riov;
+ unsigned short head;
+};
+
+/* struct cfv_stats - statistics for debugfs
+ * @rx_napi_complete: Number of NAPI completions (RX)
+ * @rx_napi_resched: Number of calls where the full quota was used (RX)
+ * @rx_nomem: Number of SKB alloc failures (RX)
+ * @rx_kicks: Number of RX kicks
+ * @tx_full_ring: Number times TX ring was full
+ * @tx_no_mem: Number of times TX went out of memory
+ * @tx_flow_on: Number of flow on (TX)
+ * @tx_kicks: Number of TX kicks
+ */
+struct cfv_stats {
+ u32 rx_napi_complete;
+ u32 rx_napi_resched;
+ u32 rx_nomem;
+ u32 rx_kicks;
+ u32 tx_full_ring;
+ u32 tx_no_mem;
+ u32 tx_flow_on;
+ u32 tx_kicks;
+};
+
+/* struct cfv_info - Caif Virtio control structure
+ * @cfdev: caif common header
+ * @vdev: Associated virtio device
+ * @vr_rx: rx/downlink host vring
+ * @vq_tx: tx/uplink virtqueue
+ * @ndev: CAIF link layer device
+ * @watermark_tx: indicates number of free descriptors we need
+ * to reopen the tx-queues after overload.
+ * @tx_lock: protects vq_tx from concurrent use
+ * @tx_release_tasklet: Tasklet for freeing consumed TX buffers
+ * @napi: Napi context used in cfv_rx_poll()
+ * @ctx: Context data used in cfv_rx_poll()
+ * @tx_hr: transmit headroom
+ * @rx_hr: receive headroom
+ * @tx_tr: transmit tail room
+ * @rx_tr: receive tail room
+ * @mtu: transmit max size
+ * @mru: receive max size
+ * @allocsz: size of dma memory reserved for TX buffers
+ * @alloc_addr: virtual address to dma memory for TX buffers
+ * @alloc_dma: dma address to dma memory for TX buffers
+ * @genpool: Gen Pool used for allocating TX buffers
+ * @reserved_mem: Pointer to memory reserve allocated from genpool
+ * @reserved_size: Size of memory reserve allocated from genpool
+ * @stats: Statistics exposed in sysfs
+ * @debugfs: Debugfs dentry for statistic counters
+ */
+struct cfv_info {
+ struct caif_dev_common cfdev;
+ struct virtio_device *vdev;
+ struct vringh *vr_rx;
+ struct virtqueue *vq_tx;
+ struct net_device *ndev;
+ unsigned int watermark_tx;
+ /* Protect access to vq_tx */
+ spinlock_t tx_lock;
+ struct tasklet_struct tx_release_tasklet;
+ struct napi_struct napi;
+ struct cfv_napi_context ctx;
+ u16 tx_hr;
+ u16 rx_hr;
+ u16 tx_tr;
+ u16 rx_tr;
+ u32 mtu;
+ u32 mru;
+ size_t allocsz;
+ void *alloc_addr;
+ dma_addr_t alloc_dma;
+ struct gen_pool *genpool;
+ unsigned long reserved_mem;
+ size_t reserved_size;
+ struct cfv_stats stats;
+ struct dentry *debugfs;
+};
+
+/* struct buf_info - maintains transmit buffer data handle
+ * @size: size of transmit buffer
+ * @dma_handle: handle to allocated dma device memory area
+ * @vaddr: virtual address mapping to allocated memory area
+ */
+struct buf_info {
+ size_t size;
+ u8 *vaddr;
+};
+
+/* Called from virtio device, in IRQ context */
+static void cfv_release_cb(struct virtqueue *vq_tx)
+{
+ struct cfv_info *cfv = vq_tx->vdev->priv;
+
+ ++cfv->stats.tx_kicks;
+ tasklet_schedule(&cfv->tx_release_tasklet);
+}
+
+static void free_buf_info(struct cfv_info *cfv, struct buf_info *buf_info)
+{
+ if (!buf_info)
+ return;
+ gen_pool_free(cfv->genpool, (unsigned long) buf_info->vaddr,
+ buf_info->size);
+ kfree(buf_info);
+}
+
+/* This is invoked whenever the remote processor completed processing
+ * a TX msg we just sent, and the buffer is put back to the used ring.
+ */
+static void cfv_release_used_buf(struct virtqueue *vq_tx)
+{
+ struct cfv_info *cfv = vq_tx->vdev->priv;
+ unsigned long flags;
+
+ BUG_ON(vq_tx != cfv->vq_tx);
+
+ for (;;) {
+ unsigned int len;
+ struct buf_info *buf_info;
+
+ /* Get used buffer from used ring to recycle used descriptors */
+ spin_lock_irqsave(&cfv->tx_lock, flags);
+ buf_info = virtqueue_get_buf(vq_tx, &len);
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+
+ /* Stop looping if there are no more buffers to free */
+ if (!buf_info)
+ break;
+
+ free_buf_info(cfv, buf_info);
+
+ /* watermark_tx indicates if we previously stopped the tx
+ * queues. If we have enough free stots in the virtio ring,
+ * re-establish memory reserved and open up tx queues.
+ */
+ if (cfv->vq_tx->num_free <= cfv->watermark_tx)
+ continue;
+
+ /* Re-establish memory reserve */
+ if (cfv->reserved_mem == 0 && cfv->genpool)
+ cfv->reserved_mem =
+ gen_pool_alloc(cfv->genpool,
+ cfv->reserved_size);
+
+ /* Open up the tx queues */
+ if (cfv->reserved_mem) {
+ cfv->watermark_tx =
+ virtqueue_get_vring_size(cfv->vq_tx);
+ netif_tx_wake_all_queues(cfv->ndev);
+ /* Buffers are recycled in cfv_netdev_tx, so
+ * disable notifications when queues are opened.
+ */
+ virtqueue_disable_cb(cfv->vq_tx);
+ ++cfv->stats.tx_flow_on;
+ } else {
+ /* if no memory reserve, wait for more free slots */
+ WARN_ON(cfv->watermark_tx >
+ virtqueue_get_vring_size(cfv->vq_tx));
+ cfv->watermark_tx +=
+ virtqueue_get_vring_size(cfv->vq_tx) / 4;
+ }
+ }
+}
+
+/* Allocate a SKB and copy packet data to it */
+static struct sk_buff *cfv_alloc_and_copy_skb(int *err,
+ struct cfv_info *cfv,
+ u8 *frm, u32 frm_len)
+{
+ struct sk_buff *skb;
+ u32 cfpkt_len, pad_len;
+
+ *err = 0;
+ /* Verify that packet size with down-link header and mtu size */
+ if (frm_len > cfv->mru || frm_len <= cfv->rx_hr + cfv->rx_tr) {
+ netdev_err(cfv->ndev,
+ "Invalid frmlen:%u mtu:%u hr:%d tr:%d\n",
+ frm_len, cfv->mru, cfv->rx_hr,
+ cfv->rx_tr);
+ *err = -EPROTO;
+ return NULL;
+ }
+
+ cfpkt_len = frm_len - (cfv->rx_hr + cfv->rx_tr);
+ pad_len = (unsigned long)(frm + cfv->rx_hr) & (IP_HDR_ALIGN - 1);
+
+ skb = netdev_alloc_skb(cfv->ndev, frm_len + pad_len);
+ if (!skb) {
+ *err = -ENOMEM;
+ return NULL;
+ }
+
+ skb_reserve(skb, cfv->rx_hr + pad_len);
+
+ memcpy(skb_put(skb, cfpkt_len), frm + cfv->rx_hr, cfpkt_len);
+ return skb;
+}
+
+/* Get packets from the host vring */
+static int cfv_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct cfv_info *cfv = container_of(napi, struct cfv_info, napi);
+ int rxcnt = 0;
+ int err = 0;
+ void *buf;
+ struct sk_buff *skb;
+ struct vringh_kiov *riov = &cfv->ctx.riov;
+ unsigned int skb_len;
+
+again:
+ do {
+ skb = NULL;
+
+ /* Put the previous iovec back on the used ring and
+ * fetch a new iovec if we have processed all elements.
+ */
+ if (riov->i == riov->used) {
+ if (cfv->ctx.head != USHRT_MAX) {
+ vringh_complete_kern(cfv->vr_rx,
+ cfv->ctx.head,
+ 0);
+ cfv->ctx.head = USHRT_MAX;
+ }
+
+ err = vringh_getdesc_kern(
+ cfv->vr_rx,
+ riov,
+ NULL,
+ &cfv->ctx.head,
+ GFP_ATOMIC);
+
+ if (err <= 0)
+ goto exit;
+ }
+
+ buf = phys_to_virt((unsigned long) riov->iov[riov->i].iov_base);
+ /* TODO: Add check on valid buffer address */
+
+ skb = cfv_alloc_and_copy_skb(&err, cfv, buf,
+ riov->iov[riov->i].iov_len);
+ if (unlikely(err))
+ goto exit;
+
+ /* Push received packet up the stack. */
+ skb_len = skb->len;
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+ skb->dev = cfv->ndev;
+ err = netif_receive_skb(skb);
+ if (unlikely(err)) {
+ ++cfv->ndev->stats.rx_dropped;
+ } else {
+ ++cfv->ndev->stats.rx_packets;
+ cfv->ndev->stats.rx_bytes += skb_len;
+ }
+
+ ++riov->i;
+ ++rxcnt;
+ } while (rxcnt < quota);
+
+ ++cfv->stats.rx_napi_resched;
+ goto out;
+
+exit:
+ switch (err) {
+ case 0:
+ ++cfv->stats.rx_napi_complete;
+
+ /* Really out of patckets? (stolen from virtio_net)*/
+ napi_complete(napi);
+ if (unlikely(vringh_notify_enable_kern(cfv->vr_rx)) &&
+ napi_schedule_prep(napi)) {
+ vringh_notify_disable_kern(cfv->vr_rx);
+ __napi_schedule(napi);
+ goto again;
+ }
+ break;
+
+ case -ENOMEM:
+ ++cfv->stats.rx_nomem;
+ dev_kfree_skb(skb);
+ /* Stop NAPI poll on OOM, we hope to be polled later */
+ napi_complete(napi);
+ vringh_notify_enable_kern(cfv->vr_rx);
+ break;
+
+ default:
+ /* We're doomed, any modem fault is fatal */
+ netdev_warn(cfv->ndev, "Bad ring, disable device\n");
+ cfv->ndev->stats.rx_dropped = riov->used - riov->i;
+ napi_complete(napi);
+ vringh_notify_disable_kern(cfv->vr_rx);
+ netif_carrier_off(cfv->ndev);
+ break;
+ }
+out:
+ if (rxcnt && vringh_need_notify_kern(cfv->vr_rx) > 0)
+ vringh_notify(cfv->vr_rx);
+ return rxcnt;
+}
+
+static void cfv_recv(struct virtio_device *vdev, struct vringh *vr_rx)
+{
+ struct cfv_info *cfv = vdev->priv;
+
+ ++cfv->stats.rx_kicks;
+ vringh_notify_disable_kern(cfv->vr_rx);
+ napi_schedule(&cfv->napi);
+}
+
+static void cfv_destroy_genpool(struct cfv_info *cfv)
+{
+ if (cfv->alloc_addr)
+ dma_free_coherent(cfv->vdev->dev.parent->parent,
+ cfv->allocsz, cfv->alloc_addr,
+ cfv->alloc_dma);
+
+ if (!cfv->genpool)
+ return;
+ gen_pool_free(cfv->genpool, cfv->reserved_mem,
+ cfv->reserved_size);
+ gen_pool_destroy(cfv->genpool);
+ cfv->genpool = NULL;
+}
+
+static int cfv_create_genpool(struct cfv_info *cfv)
+{
+ int err;
+
+ /* dma_alloc can only allocate whole pages, and we need a more
+ * fine graned allocation so we use genpool. We ask for space needed
+ * by IP and a full ring. If the dma allcoation fails we retry with a
+ * smaller allocation size.
+ */
+ err = -ENOMEM;
+ cfv->allocsz = (virtqueue_get_vring_size(cfv->vq_tx) *
+ (ETH_DATA_LEN + cfv->tx_hr + cfv->tx_tr) * 11)/10;
+ if (cfv->allocsz <= (num_possible_cpus() + 1) * cfv->ndev->mtu)
+ return -EINVAL;
+
+ for (;;) {
+ if (cfv->allocsz <= num_possible_cpus() * cfv->ndev->mtu) {
+ netdev_info(cfv->ndev, "Not enough device memory\n");
+ return -ENOMEM;
+ }
+
+ cfv->alloc_addr = dma_alloc_coherent(
+ cfv->vdev->dev.parent->parent,
+ cfv->allocsz, &cfv->alloc_dma,
+ GFP_ATOMIC);
+ if (cfv->alloc_addr)
+ break;
+
+ cfv->allocsz = (cfv->allocsz * 3) >> 2;
+ }
+
+ netdev_dbg(cfv->ndev, "Allocated %zd bytes from dma-memory\n",
+ cfv->allocsz);
+
+ /* Allocate on 128 bytes boundaries (1 << 7)*/
+ cfv->genpool = gen_pool_create(7, -1);
+ if (!cfv->genpool)
+ goto err;
+
+ err = gen_pool_add_virt(cfv->genpool, (unsigned long)cfv->alloc_addr,
+ (phys_addr_t)virt_to_phys(cfv->alloc_addr),
+ cfv->allocsz, -1);
+ if (err)
+ goto err;
+
+ /* Reserve some memory for low memory situations. If we hit the roof
+ * in the memory pool, we stop TX flow and release the reserve.
+ */
+ cfv->reserved_size = num_possible_cpus() * cfv->ndev->mtu;
+ cfv->reserved_mem = gen_pool_alloc(cfv->genpool,
+ cfv->reserved_size);
+ if (!cfv->reserved_mem)
+ goto err;
+
+ cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx);
+ return 0;
+err:
+ cfv_destroy_genpool(cfv);
+ return err;
+}
+
+/* Enable the CAIF interface and allocate the memory-pool */
+static int cfv_netdev_open(struct net_device *netdev)
+{
+ struct cfv_info *cfv = netdev_priv(netdev);
+
+ if (cfv_create_genpool(cfv))
+ return -ENOMEM;
+
+ netif_carrier_on(netdev);
+ napi_enable(&cfv->napi);
+
+ /* Schedule NAPI to read any pending packets */
+ napi_schedule(&cfv->napi);
+ return 0;
+}
+
+/* Disable the CAIF interface and free the memory-pool */
+static int cfv_netdev_close(struct net_device *netdev)
+{
+ struct cfv_info *cfv = netdev_priv(netdev);
+ unsigned long flags;
+ struct buf_info *buf_info;
+
+ /* Disable interrupts, queues and NAPI polling */
+ netif_carrier_off(netdev);
+ virtqueue_disable_cb(cfv->vq_tx);
+ vringh_notify_disable_kern(cfv->vr_rx);
+ napi_disable(&cfv->napi);
+
+ /* Release any TX buffers on both used and avilable rings */
+ cfv_release_used_buf(cfv->vq_tx);
+ spin_lock_irqsave(&cfv->tx_lock, flags);
+ while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx)))
+ free_buf_info(cfv, buf_info);
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+
+ /* Release all dma allocated memory and destroy the pool */
+ cfv_destroy_genpool(cfv);
+ return 0;
+}
+
+/* Allocate a buffer in dma-memory and copy skb to it */
+static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv,
+ struct sk_buff *skb,
+ struct scatterlist *sg)
+{
+ struct caif_payload_info *info = (void *)&skb->cb;
+ struct buf_info *buf_info = NULL;
+ u8 pad_len, hdr_ofs;
+
+ if (!cfv->genpool)
+ goto err;
+
+ if (unlikely(cfv->tx_hr + skb->len + cfv->tx_tr > cfv->mtu)) {
+ netdev_warn(cfv->ndev, "Invalid packet len (%d > %d)\n",
+ cfv->tx_hr + skb->len + cfv->tx_tr, cfv->mtu);
+ goto err;
+ }
+
+ buf_info = kmalloc(sizeof(struct buf_info), GFP_ATOMIC);
+ if (unlikely(!buf_info))
+ goto err;
+
+ /* Make the IP header aligned in tbe buffer */
+ hdr_ofs = cfv->tx_hr + info->hdr_len;
+ pad_len = hdr_ofs & (IP_HDR_ALIGN - 1);
+ buf_info->size = cfv->tx_hr + skb->len + cfv->tx_tr + pad_len;
+
+ /* allocate dma memory buffer */
+ buf_info->vaddr = (void *)gen_pool_alloc(cfv->genpool, buf_info->size);
+ if (unlikely(!buf_info->vaddr))
+ goto err;
+
+ /* copy skbuf contents to send buffer */
+ skb_copy_bits(skb, 0, buf_info->vaddr + cfv->tx_hr + pad_len, skb->len);
+ sg_init_one(sg, buf_info->vaddr + pad_len,
+ skb->len + cfv->tx_hr + cfv->rx_hr);
+
+ return buf_info;
+err:
+ kfree(buf_info);
+ return NULL;
+}
+
+/* Put the CAIF packet on the virtio ring and kick the receiver */
+static int cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct cfv_info *cfv = netdev_priv(netdev);
+ struct buf_info *buf_info;
+ struct scatterlist sg;
+ unsigned long flags;
+ bool flow_off = false;
+ int ret;
+
+ /* garbage collect released buffers */
+ cfv_release_used_buf(cfv->vq_tx);
+ spin_lock_irqsave(&cfv->tx_lock, flags);
+
+ /* Flow-off check takes into account number of cpus to make sure
+ * virtqueue will not be overfilled in any possible smp conditions.
+ *
+ * Flow-on is triggered when sufficient buffers are freed
+ */
+ if (unlikely(cfv->vq_tx->num_free <= num_present_cpus())) {
+ flow_off = true;
+ cfv->stats.tx_full_ring++;
+ }
+
+ /* If we run out of memory, we release the memory reserve and retry
+ * allocation.
+ */
+ buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
+ if (unlikely(!buf_info)) {
+ cfv->stats.tx_no_mem++;
+ flow_off = true;
+
+ if (cfv->reserved_mem && cfv->genpool) {
+ gen_pool_free(cfv->genpool, cfv->reserved_mem,
+ cfv->reserved_size);
+ cfv->reserved_mem = 0;
+ buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
+ }
+ }
+
+ if (unlikely(flow_off)) {
+ /* Turn flow on when a 1/4 of the descriptors are released */
+ cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx) / 4;
+ /* Enable notifications of recycled TX buffers */
+ virtqueue_enable_cb(cfv->vq_tx);
+ netif_tx_stop_all_queues(netdev);
+ }
+
+ if (unlikely(!buf_info)) {
+ /* If the memory reserve does it's job, this shouldn't happen */
+ netdev_warn(cfv->ndev, "Out of gen_pool memory\n");
+ goto err;
+ }
+
+ ret = virtqueue_add_buf(cfv->vq_tx, &sg, 1, 0,
+ buf_info, GFP_ATOMIC);
+ if (unlikely((ret < 0))) {
+ /* If flow control works, this shouldn't happen */
+ netdev_warn(cfv->ndev, "Failed adding buffer to TX vring:%d\n",
+ ret);
+ goto err;
+ }
+
+ /* update netdev statistics */
+ cfv->ndev->stats.tx_packets++;
+ cfv->ndev->stats.tx_bytes += skb->len;
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+
+ /* tell the remote processor it has a pending message to read */
+ virtqueue_kick(cfv->vq_tx);
+
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+err:
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+ cfv->ndev->stats.tx_dropped++;
+ free_buf_info(cfv, buf_info);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+static void cfv_tx_release_tasklet(unsigned long drv)
+{
+ struct cfv_info *cfv = (struct cfv_info *)drv;
+ cfv_release_used_buf(cfv->vq_tx);
+}
+
+static const struct net_device_ops cfv_netdev_ops = {
+ .ndo_open = cfv_netdev_open,
+ .ndo_stop = cfv_netdev_close,
+ .ndo_start_xmit = cfv_netdev_tx,
+};
+
+static void cfv_netdev_setup(struct net_device *netdev)
+{
+ netdev->netdev_ops = &cfv_netdev_ops;
+ netdev->type = ARPHRD_CAIF;
+ netdev->tx_queue_len = 100;
+ netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ netdev->mtu = CFV_DEF_MTU_SIZE;
+ netdev->destructor = free_netdev;
+}
+
+/* Create debugfs counters for the device */
+static inline void debugfs_init(struct cfv_info *cfv)
+{
+ cfv->debugfs =
+ debugfs_create_dir(netdev_name(cfv->ndev), NULL);
+
+ if (IS_ERR(cfv->debugfs))
+ return;
+
+ debugfs_create_u32("rx-napi-complete", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_napi_complete);
+ debugfs_create_u32("rx-napi-resched", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_napi_resched);
+ debugfs_create_u32("rx-nomem", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_nomem);
+ debugfs_create_u32("rx-kicks", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_kicks);
+ debugfs_create_u32("tx-full-ring", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_full_ring);
+ debugfs_create_u32("tx-no-mem", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_no_mem);
+ debugfs_create_u32("tx-kicks", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_kicks);
+ debugfs_create_u32("tx-flow-on", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_flow_on);
+}
+
+/* Setup CAIF for the a virtio device */
+static int cfv_probe(struct virtio_device *vdev)
+{
+ vq_callback_t *vq_cbs = cfv_release_cb;
+ vrh_callback_t *vrh_cbs = cfv_recv;
+ const char *names = "output";
+ const char *cfv_netdev_name = "cfvrt";
+ struct net_device *netdev;
+ struct cfv_info *cfv;
+ int err = -EINVAL;
+
+ netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name,
+ cfv_netdev_setup);
+ if (!netdev)
+ return -ENOMEM;
+
+ cfv = netdev_priv(netdev);
+ cfv->vdev = vdev;
+ cfv->ndev = netdev;
+
+ spin_lock_init(&cfv->tx_lock);
+
+ /* Get the RX virtio ring. This is a "host side vring". */
+ err = vdev->vringh_config->find_vrhs(vdev, 1, &cfv->vr_rx, &vrh_cbs);
+ if (err)
+ goto err;
+
+ /* Get the TX virtio ring. This is a "guest side vring". */
+ err = vdev->config->find_vqs(vdev, 1, &cfv->vq_tx, &vq_cbs, &names);
+ if (err)
+ goto err;
+
+ /* Get the CAIF configuration from virtio config space, if available */
+#define GET_VIRTIO_CONFIG_OPS(_v, _var, _f) \
+ ((_v)->config->get(_v, offsetof(struct virtio_caif_transf_config, _f), \
+ &_var, \
+ FIELD_SIZEOF(struct virtio_caif_transf_config, _f)))
+
+ if (vdev->config->get) {
+ GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_hr, headroom);
+ GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_hr, headroom);
+ GET_VIRTIO_CONFIG_OPS(vdev, cfv->tx_tr, tailroom);
+ GET_VIRTIO_CONFIG_OPS(vdev, cfv->rx_tr, tailroom);
+ GET_VIRTIO_CONFIG_OPS(vdev, cfv->mtu, mtu);
+ GET_VIRTIO_CONFIG_OPS(vdev, cfv->mru, mtu);
+ } else {
+ cfv->tx_hr = CFV_DEF_HEADROOM;
+ cfv->rx_hr = CFV_DEF_HEADROOM;
+ cfv->tx_tr = CFV_DEF_TAILROOM;
+ cfv->rx_tr = CFV_DEF_TAILROOM;
+ cfv->mtu = CFV_DEF_MTU_SIZE;
+ cfv->mru = CFV_DEF_MTU_SIZE;
+ }
+
+ netdev->needed_headroom = cfv->tx_hr;
+ netdev->needed_tailroom = cfv->tx_tr;
+
+ /* Disable buffer release interrupts unless we have stopped TX queues */
+ virtqueue_disable_cb(cfv->vq_tx);
+
+ netdev->mtu = cfv->mtu - cfv->tx_tr;
+ vdev->priv = cfv;
+
+ /* Initialize NAPI poll context data */
+ vringh_kiov_init(&cfv->ctx.riov, NULL, 0);
+ cfv->ctx.head = USHRT_MAX;
+ netif_napi_add(netdev, &cfv->napi, cfv_rx_poll, CFV_DEFAULT_QUOTA);
+
+ tasklet_init(&cfv->tx_release_tasklet,
+ cfv_tx_release_tasklet,
+ (unsigned long)cfv);
+
+ /* Carrier is off until netdevice is opened */
+ netif_carrier_off(netdev);
+
+ /* register Netdev */
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err);
+ goto err;
+ }
+
+ debugfs_init(cfv);
+
+ return 0;
+err:
+ netdev_warn(cfv->ndev, "CAIF Virtio probe failed:%d\n", err);
+
+ if (cfv->vr_rx)
+ vdev->vringh_config->del_vrhs(cfv->vdev);
+ if (cfv->vdev)
+ vdev->config->del_vqs(cfv->vdev);
+ free_netdev(netdev);
+ return err;
+}
+
+static void cfv_remove(struct virtio_device *vdev)
+{
+ struct cfv_info *cfv = vdev->priv;
+
+ rtnl_lock();
+ dev_close(cfv->ndev);
+ rtnl_unlock();
+
+ tasklet_kill(&cfv->tx_release_tasklet);
+ debugfs_remove_recursive(cfv->debugfs);
+
+ vringh_kiov_cleanup(&cfv->ctx.riov);
+ vdev->config->reset(vdev);
+ vdev->vringh_config->del_vrhs(cfv->vdev);
+ cfv->vr_rx = NULL;
+ vdev->config->del_vqs(cfv->vdev);
+ unregister_netdev(cfv->ndev);
+}
+
+static struct virtio_device_id id_table[] = {
+ { VIRTIO_ID_CAIF, VIRTIO_DEV_ANY_ID },
+ { 0 },
+};
+
+static unsigned int features[] = {
+};
+
+static struct virtio_driver caif_virtio_driver = {
+ .feature_table = features,
+ .feature_table_size = ARRAY_SIZE(features),
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = cfv_probe,
+ .remove = cfv_remove,
+};
+
+module_virtio_driver(caif_virtio_driver);
+MODULE_DEVICE_TABLE(virtio, id_table);
diff --git a/include/linux/virtio_caif.h b/include/linux/virtio_caif.h
new file mode 100644
index 0000000..5d2d312
--- /dev/null
+++ b/include/linux/virtio_caif.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland <sjur.brandeland@stericsson.com>
+ *
+ * This header is BSD licensed so
+ * anyone can use the definitions to implement compatible remote processors
+ */
+
+#ifndef VIRTIO_CAIF_H
+#define VIRTIO_CAIF_H
+
+#include <linux/types.h>
+struct virtio_caif_transf_config {
+ u16 headroom;
+ u16 tailroom;
+ u32 mtu;
+ u8 reserved[4];
+};
+
+struct virtio_caif_config {
+ struct virtio_caif_transf_config uplink, downlink;
+ u8 reserved[8];
+};
+#endif
diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h
index a7630d0..284fc3a 100644
--- a/include/uapi/linux/virtio_ids.h
+++ b/include/uapi/linux/virtio_ids.h
@@ -38,5 +38,6 @@
#define VIRTIO_ID_SCSI 8 /* virtio scsi */
#define VIRTIO_ID_9P 9 /* 9p virtio console */
#define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */
+#define VIRTIO_ID_CAIF 12 /* Virtio caif */
#endif /* _LINUX_VIRTIO_IDS_H */
--
1.7.9.2
^ permalink raw reply related
* Re: linux-3.6+, gre+ipsec+forwarding = IP fragmentation broken
From: Timo Teras @ 2013-03-15 9:25 UTC (permalink / raw)
To: netdev
In-Reply-To: <20130313171453.0297f179@vostro>
On Wed, 13 Mar 2013 17:14:53 +0200
Timo Teras <timo.teras@iki.fi> wrote:
> In the typical DMVPN setup with IPv4-ESP-GRE-IPv4 stack, it seems that
> IPv4 fragmentation got broke around 3.6 for forwarded packets.
>
> It would seem that fragmentation works for locally generated packets.
> Also PMTU (DF set) seems to work for both forwarded and locally
> generated packets. But forwarded packets to gre device that gets IPsec
> encrypted do not get fragmented properly.
>
> 3.4.x kernels work, 3.6 and 3.8 series tested and fail similarly.
Actually 3.4.x vanilla does not work. It works only with 38d523e "ipv4:
Remove output route check in ipv4_mtu" applied which I've been
cherry-picking to my builds.
> I was going through the changelog and it seems that MTU is now handled
> in nexthop exceptions and one needs to produce the full flow info to
> update it. I'm wonding if this does not hold true in my code path as
> ip_gre rewraps the forwarded packet and creates new IP header - when
> it next goes to the xfrm code (which sends the ICMP error) the inner
> iphdr is no longer accessible. Would this cause the breakage that I'm
> seeing? Or the forward flow's mtu still updated somehow?
I have now a theory on what goes wrong.
My gre tunnel is configured with 'ttl 64' so the tunnel IP header
always gets DF bit set to do proper path-mtu. The kind of locally
generated ICMP messages I get, imply that re-fragmentation happens only
on the tunnel's IPv4 header level - but it'll be too late then: the
large packet is queued, IPsec'ed and it is the IPsec'ed packet that
gets is tried to be fragmented (but it has DF set so it fails and
packet is dropped).
I believe ip_gre should explicitly fragment the inner IPv4 and IPv6
packets if the tunnel's ttl is not inherited (resulting in DF bit set
in the tunnel's IPv4 header).
So basically ip_gre worked wrong all along - things just happened to
work due to GRO/GSO not implemented in ip_gre, and the way (the now
deleted) routing cache exposed pmtu.
Does this make sense?
- Timo
^ permalink raw reply
* [PATCH net-next] ipv4: replace ip_fast_csum with csum_replace2
From: roy.qing.li @ 2013-03-15 8:50 UTC (permalink / raw)
To: netdev
From: Li RongQing <roy.qing.li@gmail.com>
replace ip_fast_csum with csum_replace2 to save cpu cycles
Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
---
net/ipv4/inet_lro.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c
index cc280a3..1975f52 100644
--- a/net/ipv4/inet_lro.c
+++ b/net/ipv4/inet_lro.c
@@ -29,6 +29,7 @@
#include <linux/module.h>
#include <linux/if_vlan.h>
#include <linux/inet_lro.h>
+#include <net/checksum.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jan-Bernd Themann <themann@de.ibm.com>");
@@ -114,11 +115,9 @@ static void lro_update_tcp_ip_header(struct net_lro_desc *lro_desc)
*(p+2) = lro_desc->tcp_rcv_tsecr;
}
+ csum_replace2(&iph->check, iph->tot_len, htons(lro_desc->ip_tot_len));
iph->tot_len = htons(lro_desc->ip_tot_len);
- iph->check = 0;
- iph->check = ip_fast_csum((u8 *)lro_desc->iph, iph->ihl);
-
tcph->check = 0;
tcp_hdr_csum = csum_partial(tcph, TCP_HDR_LEN(tcph), 0);
lro_desc->data_csum = csum_add(lro_desc->data_csum, tcp_hdr_csum);
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH v3 2/7] USB: serial: comments on suspend failure
From: Johan Hovold @ 2013-03-15 9:02 UTC (permalink / raw)
To: Ming Lei
Cc: David S. Miller, Greg Kroah-Hartman, Jiri Kosina, Alan Stern,
Oliver Neukum, netdev, linux-usb, linux-input, Johan Hovold
In-Reply-To: <1363320539-23012-3-git-send-email-ming.lei@canonical.com>
On Fri, Mar 15, 2013 at 12:08:54PM +0800, Ming Lei wrote:
> If suspend callback fails in system sleep context, usb core will
> ignore the failure and let system sleep go ahead further, so
> this patch comments on the case and requires that serial->type->suspend()
> MUST return 0 in system sleep context.
>
> Cc: Johan Hovold <jhovold@gmail.com>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
> drivers/usb/serial/usb-serial.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
> index a19ed74..16eb02b 100644
> --- a/drivers/usb/serial/usb-serial.c
> +++ b/drivers/usb/serial/usb-serial.c
> @@ -1140,6 +1140,11 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
>
> serial->suspending = 1;
>
> + /*
> + * serial->type->suspend() MUST return 0 in system sleep context,
> + * otherwise, the resume callback has to recover device from
> + * previous suspend failure.
> + */
> if (serial->type->suspend) {
> r = serial->type->suspend(serial, message);
> if (r < 0) {
Acked-by: Johan Hovold <jhovold@gmail.com>
Thanks,
Johan
^ permalink raw reply
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