* Re: [PATCH net] net: ethernet: davicom: Allow to select DM9000 for nios2
From: Tobias Klauser @ 2014-12-12 9:57 UTC (permalink / raw)
To: David Laight; +Cc: netdev@vger.kernel.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1CA0BA4C@AcuExch.aculab.com>
On 2014-12-12 at 10:49:13 +0100, David Laight <David.Laight@ACULAB.COM> wrote:
> From: Tobias Klauser
> > This chip is present on older revisions of the DE2 development kit.
>
> Doesn't that mean the selector should be DE2 not NIOS2.
>
> NIOS2 is a cpu not a board and I think this is an external peripheral
> not something implemented in the fpga itself.
You're of course right, but since nios2 relies on device tree there is
no notion of a specific board at compile time.
Moreover, the chip might be used on other boards (I personally know of
at least one) based on the nios2 softcore.
Cheers
Tobias
^ permalink raw reply
* Re: [PATCH v2 1/1] net/macb: add TX multiqueue support for gem
From: Cyrille Pitchen @ 2014-12-12 9:57 UTC (permalink / raw)
To: David Laight, 'Thomas Petazzoni'
Cc: nicolas.ferre@atmel.com, davem@davemloft.net,
linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org,
soren.brinkmann@xilinx.com, linux-kernel@vger.kernel.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1CA0BA7D@AcuExch.aculab.com>
Le 12/12/2014 10:59, David Laight a écrit :
> From: Cyrille Pitchen [...
>>> It will probably add a lot of object code and, depending on how often
>>> the registers are accesses, might have performance impact.
>>>
>>> Having:
>>> #define GEM_ISR(n) (0x400 + (n) << 4)
>>> will save source code.
>>>
>>> David
>>>
>>>
>>>
>> So you suggest that we keep the unsigned int fields ISR, IMR, IER, IDR, TBQP in
>> the struct macb_queue and initialize them once for all in macb_probe() like
>> patch v2 does but only replace the GEM_ISR1 .. GEM_ISR7 defines by GEM_ISR(n)
>> in macb.h?
>>
>> This way there would be to test at run time and we can handle the special
>> register mapping of queue0.
>>
>> Is it what you meant?
>
> In one word, yes.
>
> David
>
>
>
OK, so I'm working on v3
Thanks
Cyrille
^ permalink raw reply
* RE: [PATCH v2 1/1] net/macb: add TX multiqueue support for gem
From: David Laight @ 2014-12-12 9:59 UTC (permalink / raw)
To: 'Cyrille Pitchen', 'Thomas Petazzoni'
Cc: nicolas.ferre@atmel.com, davem@davemloft.net,
linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org,
soren.brinkmann@xilinx.com, linux-kernel@vger.kernel.org
In-Reply-To: <548AAE66.8070501@atmel.com>
From: Cyrille Pitchen [...
> > It will probably add a lot of object code and, depending on how often
> > the registers are accesses, might have performance impact.
> >
> > Having:
> > #define GEM_ISR(n) (0x400 + (n) << 4)
> > will save source code.
> >
> > David
> >
> >
> >
> So you suggest that we keep the unsigned int fields ISR, IMR, IER, IDR, TBQP in
> the struct macb_queue and initialize them once for all in macb_probe() like
> patch v2 does but only replace the GEM_ISR1 .. GEM_ISR7 defines by GEM_ISR(n)
> in macb.h?
>
> This way there would be to test at run time and we can handle the special
> register mapping of queue0.
>
> Is it what you meant?
In one word, yes.
David
^ permalink raw reply
* RE: [PATCH net] net: ethernet: davicom: Allow to select DM9000 for nios2
From: David Laight @ 2014-12-12 10:08 UTC (permalink / raw)
To: 'Tobias Klauser'; +Cc: netdev@vger.kernel.org
In-Reply-To: <20141212095717.GF16916@distanz.ch>
From: Tobias Klauser
> On 2014-12-12 at 10:49:13 +0100, David Laight <David.Laight@ACULAB.COM> wrote:
> > From: Tobias Klauser
> > > This chip is present on older revisions of the DE2 development kit.
> >
> > Doesn't that mean the selector should be DE2 not NIOS2.
> >
> > NIOS2 is a cpu not a board and I think this is an external peripheral
> > not something implemented in the fpga itself.
>
> You're of course right, but since nios2 relies on device tree there is
> no notion of a specific board at compile time.
>
> Moreover, the chip might be used on other boards (I personally know of
> at least one) based on the nios2 softcore.
And I've got several boards on my desk that have Altera fpgas and
could conceivably run linux, none of which have that chip.
Given the typical memory size constraints of such systems I can't
actually imagine anyone wanting to run anything other than a
specific cut-down kernel with a similarly cut-down userspace.
With actual hardware you might want any PCIe device (since the
fpga can be a PCIe host).
So whereas you might want almost any device, you probably want
almost none of them.
So trying to build a 'one size fits all' kernel is completely doomed.
David
^ permalink raw reply
* Re: [PATCH net] net: ethernet: davicom: Allow to select DM9000 for nios2
From: Tobias Klauser @ 2014-12-12 10:17 UTC (permalink / raw)
To: David Laight; +Cc: netdev@vger.kernel.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1CA0BA8C@AcuExch.aculab.com>
On 2014-12-12 at 11:08:03 +0100, David Laight <David.Laight@ACULAB.COM> wrote:
> From: Tobias Klauser
> > On 2014-12-12 at 10:49:13 +0100, David Laight <David.Laight@ACULAB.COM> wrote:
> > > From: Tobias Klauser
> > > > This chip is present on older revisions of the DE2 development kit.
> > >
> > > Doesn't that mean the selector should be DE2 not NIOS2.
> > >
> > > NIOS2 is a cpu not a board and I think this is an external peripheral
> > > not something implemented in the fpga itself.
> >
> > You're of course right, but since nios2 relies on device tree there is
> > no notion of a specific board at compile time.
> >
> > Moreover, the chip might be used on other boards (I personally know of
> > at least one) based on the nios2 softcore.
>
> And I've got several boards on my desk that have Altera fpgas and
> could conceivably run linux, none of which have that chip.
>
> Given the typical memory size constraints of such systems I can't
> actually imagine anyone wanting to run anything other than a
> specific cut-down kernel with a similarly cut-down userspace.
>
> With actual hardware you might want any PCIe device (since the
> fpga can be a PCIe host).
> So whereas you might want almost any device, you probably want
> almost none of them.
>
> So trying to build a 'one size fits all' kernel is completely doomed.
I completely agree. However I don't see how this has anything to do with
this patch, as it only allows to select the driver but doesn't do so by
default.
^ permalink raw reply
* Re: [PATCH net] net: ethernet: davicom: Allow to select DM9000 for nios2
From: Simon Horman @ 2014-12-12 11:28 UTC (permalink / raw)
To: Tobias Klauser; +Cc: netdev
In-Reply-To: <1418376071-28709-1-git-send-email-tklauser@distanz.ch>
On Fri, Dec 12, 2014 at 10:21:11AM +0100, Tobias Klauser wrote:
> This chip is present on older revisions of the DE2 development kit.
>
> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
I wonder if || COMPILE_TEST should also be added to allow extra build
coverage. Is there a specific reason it won't compile more widely?
Likewise for your smsc patch.
> ---
> drivers/net/ethernet/davicom/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/davicom/Kconfig b/drivers/net/ethernet/davicom/Kconfig
> index 316c5e5..7ec2d74 100644
> --- a/drivers/net/ethernet/davicom/Kconfig
> +++ b/drivers/net/ethernet/davicom/Kconfig
> @@ -4,7 +4,7 @@
>
> config DM9000
> tristate "DM9000 support"
> - depends on ARM || BLACKFIN || MIPS || COLDFIRE
> + depends on ARM || BLACKFIN || MIPS || COLDFIRE || NIOS2
> select CRC32
> select MII
> ---help---
> --
> 2.2.0
>
>
> --
> 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
>
^ permalink raw reply
* Re: [PATCH net-next RESEND] net: Do not call ndo_dflt_fdb_dump if ndo_fdb_dump is defined.
From: Hubert Sokolowski @ 2014-12-12 11:38 UTC (permalink / raw)
To: Roopa Prabhu; +Cc: netdev, Jamal Hadi Salim
In-Reply-To: <5489D53E.5010603@cumulusnetworks.com>
> On 12/11/14, 9:06 AM, Hubert Sokolowski wrote:
>> My apologies for sending again, I forgot to include a sample output you asked.
>>
>>> Also, if i hear your concern correctly, for bridge ports that implement
>>> ndo_fdb_dump, with commit 5e6d243587990a588143b9da3974833649595587, we
>>> will get two entries for each 'self' entry above.
>>> Can you also paste sample output for that ?.
>>>
>> [root@silpixa00378825 ~]# bridge fdb show brport mac0
>> 33:33:00:00:00:01 self permanent
>> 33:33:00:00:00:01 self permanent
>>
>>
> Thanks. yes, that is a problem. And, this mac0 is not a bridge port
> correct ?.
>
in that part of the code it does not matter whether it is a bridge
port or not. I can show all devices and the entry is duplicated.
I can still filter by dev and you will see same problem, because
for every network device the dflt callback is called without checking
if the ndo_fdb_dump was defined:
[root@silpixa00378825 ~]# bridge fdb show
33:33:00:00:00:01 dev em1 self permanent
01:00:5e:00:00:01 dev em1 self permanent
33:33:00:00:00:01 dev p4p1 self permanent
01:00:5e:00:00:01 dev p4p1 self permanent
33:33:ff:81:56:db dev p4p1 self permanent
01:00:5e:00:00:fb dev p4p1 self permanent
33:33:00:00:00:01 dev dummy0 self permanent
33:33:00:00:00:01 dev mac0 self permanent
33:33:00:00:00:01 dev mac0 self permanent
[root@silpixa00378825 ~]# bridge fdb show dev mac0
33:33:00:00:00:01 self permanent
33:33:00:00:00:01 self permanent
Please see how the ndo_dflt_fdb_add and del are called:
if (dev->netdev_ops->ndo_fdb_add)
err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
vid,
nlh->nlmsg_flags);
else
err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
nlh->nlmsg_flags);
> But, for the same test case, when mac0 is a bridge port, does your patch
> under review make both the entries go away for a bridge port ?.
> (If i understand jamal correctly, this is his concern).
>
As it was suggested by Ronen I can modify the patch so the dflt callback
is always called for bridge devices if this is desirable. Either by calling
it when following expression is true:
(dev->priv_flags & IFF_BRIDGE_PORT)
or by modifying br_fdb_dump to call ndo_dflt_fdb_dump.
thanks,
Hubert
^ permalink raw reply
* Re: [PATCH net-next RESEND] net: Do not call ndo_dflt_fdb_dump if ndo_fdb_dump is defined.
From: Jamal Hadi Salim @ 2014-12-12 11:54 UTC (permalink / raw)
To: Hubert Sokolowski, Roopa Prabhu; +Cc: netdev@vger.kernel.org, Vlad Yasevich
In-Reply-To: <8d4ec5c1ae73c77866a0a154fb528f23.squirrel@poczta.wsisiz.edu.pl>
On 12/12/14 06:38, Hubert Sokolowski wrote:
>> On 12/11/14, 9:06 AM, Hubert Sokolowski wrote:
> Please see how the ndo_dflt_fdb_add and del are called:
> if (dev->netdev_ops->ndo_fdb_add)
> err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
> vid,
> nlh->nlmsg_flags);
> else
> err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
> nlh->nlmsg_flags);
>
Semantically add and dump are not the same.
Add adds a specific entry.
Dump not only dumps the fdb table but also the unicast and multicast
addresses.
the default dumper does the uni/multicast dumping.
> As it was suggested by Ronen I can modify the patch so the dflt callback
> is always called for bridge devices if this is desirable. Either by calling
> it when following expression is true:
> (dev->priv_flags & IFF_BRIDGE_PORT)
> or by modifying br_fdb_dump to call ndo_dflt_fdb_dump.
>
Are you saying the above is going to work? You need to TEST please.
It seems to me drivers which do this:
---
.ndo_fdb_dump = my_fdb_dump,
and then my_fdb_dump is:
return ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx);
are broken because we always have to dump the uni/multicast
addresses *unconditionally* and these drivers claim to be
overriding the dumper but are in fact calling the default dumper.
They are not filtering anything as you had stated.
I wish Vlad (Cced) would show up and say something ;->
IOW, fix all the broken driver to not do that.
cheers,
jamal
^ permalink raw reply
* Re: [PATCH] stmmac: platform: adjust messages and move to dev level
From: Andy Shevchenko @ 2014-12-12 11:56 UTC (permalink / raw)
To: David Miller; +Cc: peppe.cavallaro, netdev
In-Reply-To: <20141210.114434.1468466024696543408.davem@davemloft.net>
On Wed, 2014-12-10 at 11:44 -0500, David Miller wrote:
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Date: Wed, 10 Dec 2014 12:47:51 +0200
>
> > On Tue, 2014-12-09 at 18:28 -0500, David Miller wrote:
> >> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> >> Date: Tue, 9 Dec 2014 11:59:13 +0200
> >>
> >> > This patch amendes error and warning messages across the platform driver. It
> >> > includes the following changes:
> >> > - remove unneccessary message when no memory is available
> >> > - change info level to warn in the validation functions
> >> > - append \n to the end of messages
> >> > - change pr_* macros to dev_*
> >> >
> >> > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> >>
> >> This does not apply to the net-next tree, please respin.
> >
> > Yeah, maybe because the fix (*) you mentioned in previos mail is not in
> > net-next by some reason?
> >
> > (*) I refer to commit 28603d13997e2ef47f18589cc9a44553aad49c86
>
> It's in the 'net' tree which hasn't been merged into net-next.
It seems it can be clearly applied on top of recent net-next.
--
Andy Shevchenko <andriy.shevchenko@intel.com>
Intel Finland Oy
^ permalink raw reply
* Re: errors in alignment changes..
From: Sergei Shtylyov @ 2014-12-12 12:00 UTC (permalink / raw)
To: Simon Horman, David Miller; +Cc: mitsuhiro.kimura.kc, netdev
In-Reply-To: <20141212043010.GC17790@verge.net.au>
Hello.
On 12/12/2014 7:30 AM, Simon Horman wrote:
>> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>> Date: Thu, 11 Dec 2014 01:08:07 +0300
>>> I guess we can just do:
>>> rxdesc->addr = dma_map_single(...);
>> Best not to leave a potentially invalid DMA address in a
>> receive descriptor the chip can potentially fetch and
>> look at.
>> That's why I said to put it into a local variable and
>> check for errors first.
> Hi Dave,
> this patch ending up in net is partially my fault.
> Sergei, do you have time to address David's concerns in relation to this
> patch?
No, I probably don't.
> If not I would like to suggest reverting it for now.
Why? The patch does what it was intended for. Getting rid of
virt_to_phys() calls is a separate issue, IMO.
WBR, Sergei
^ permalink raw reply
* Re: am335x: cpsw: interrupt failure
From: Yegor Yefremov @ 2014-12-12 12:00 UTC (permalink / raw)
To: Felipe Balbi; +Cc: netdev, N, Mugunthan V
In-Reply-To: <CAGm1_ktYg4iDgK7jyi5etSVup61LdookkV+SaQZOpLb6M=y7hA@mail.gmail.com>
On Wed, Dec 10, 2014 at 11:56 PM, Yegor Yefremov
<yegorslists@googlemail.com> wrote:
> On Wed, Dec 10, 2014 at 10:02 PM, Felipe Balbi <balbi@ti.com> wrote:
>> Hi,
>>
>> On Wed, Dec 10, 2014 at 09:58:23PM +0100, Yegor Yefremov wrote:
>>
>> [snip]
>>
>>> >> git revert failed as the driver has more changes meanwhile or I'm
>>> >> missing some params. I've tried to force the driver to use legacy
>>> >> routines, but then I don't get pass U-Boot's "Starting kernel ..." See
>>> >> attached patch.
>>> >>
>>> >> Compiler used:
>>> >>
>>> >> Linux version 3.18.0-rc7 (...) (gcc version 4.8.3 20140320
>>> >> (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #309 SMP Fri Dec 5
>>> >> 10:59:38 CET 2014
>>> >>
>>> >> Btw, what am335x based hardware do you have? I can run tests on both
>>> >> BBB and am335x-evmsk.
>>> >
>>> > coming back to this. I have BBB only. Can you provide some extra
>>> > information on how I can trigger this problem here ?
>>>
>>> I have basically two am335x based boards, where I can trigger this
>>
>> too bad, I have a single am335x board available here and that's my BBB.
>>
>> Do both boards stall or only the server or only the client ?
>>
>> If only one of them fail, then I try connecting my BBB to my AM437x SK
>> and see if that'll die too.
>
> I have following setup: all three devices (am335x-evmsk inclusively)
> are connected to my development host via Gigabit switch. And on all of
> them I run "nuttcp -S" and my dev host is client (nuttcp -t). Just
> normal setup, when you try to measure am335x network performance. So
> am335x devices communicate only with my host and not with each other.
>
> If I use 3.18 I can only observe, that the system freezes, but when I
> use the kernel with above mentioned commit I see interrupt errors,
> like I described in my first e-mail.
>
>>> problem via nuttcp (I think iperf would do the job too). The first
>>> system stalls almost immediately, the second one was working for about
>>> 7 minutes. I have tried the same kernel on am335x-evmsk - and this
>>> system didn't stall. I could provide dts files for both systems.
>>>
>>> I've tried to reduce my dts as much as I could to match am335x-evmsk
>>> dts, I have even removed entries for the PMIC, but still the system
>>> stalls. Btw PMIC's INT line is connected to a GPIO pin on processor.
>>>
>>> I've used omap2plus_defconfig for all 3 devices. Any other info I can
>>> supply?
>>
>> just the extra bit of info above.
I've got BBB stalled. I could do it from two different hosts: one
Windows 7 64-bit machine with Xubuntu VM and one older native Linux
server. Command used on both PC's (not simultaneously):
nuttcp -t -N 4 -T30m 192.168.1.235
BBB stalled after some minutes.
Kernel defconfig:
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_FHANDLE=y
CONFIG_AUDIT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_CGROUPS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
CONFIG_SLAB=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MULTI_V6=y
CONFIG_POWER_AVS_OMAP=y
CONFIG_POWER_AVS_OMAP_CLASS3=y
CONFIG_OMAP_RESET_CLOCKS=y
CONFIG_OMAP_MUX_DEBUG=y
CONFIG_ARCH_OMAP2=y
CONFIG_ARCH_OMAP3=y
CONFIG_ARCH_OMAP4=y
CONFIG_SOC_OMAP5=y
CONFIG_SOC_AM33XX=y
CONFIG_SOC_AM43XX=y
CONFIG_SOC_DRA7XX=y
CONFIG_ARM_THUMBEE=y
CONFIG_ARM_ERRATA_411920=y
CONFIG_ARM_ERRATA_430973=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_CMA=y
CONFIG_SECCOMP=y
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
CONFIG_KEXEC=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
CONFIG_CPU_IDLE=y
CONFIG_BINFMT_MISC=y
CONFIG_PM_DEBUG=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_XFRM_USER=y
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
# CONFIG_INET_LRO is not set
CONFIG_NETFILTER=y
CONFIG_CAN=m
CONFIG_CAN_C_CAN=m
CONFIG_CAN_C_CAN_PLATFORM=m
CONFIG_BT=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_H4=y
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_CFG80211=m
CONFIG_MAC80211=m
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y
CONFIG_OMAP_OCP2SCP=y
CONFIG_CONNECTOR=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_OOPS=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_BCH=y
CONFIG_MTD_NAND_OMAP2=y
CONFIG_MTD_ONENAND=y
CONFIG_MTD_ONENAND_VERIFY_WRITE=y
CONFIG_MTD_ONENAND_OMAP2=y
CONFIG_MTD_UBI=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_SENSORS_TSL2550=m
CONFIG_BMP085_I2C=m
CONFIG_SRAM=y
CONFIG_SENSORS_LIS3_I2C=m
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_MD=y
CONFIG_NETDEVICES=y
CONFIG_KS8851=y
CONFIG_KS8851_MLL=y
CONFIG_SMC91X=y
CONFIG_SMSC911X=y
CONFIG_TI_CPSW=y
CONFIG_AT803X_PHY=y
CONFIG_SMSC_PHY=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_DEBUG=y
CONFIG_WL_TI=y
CONFIG_WL12XX=m
CONFIG_WL18XX=m
CONFIG_WLCORE_SPI=m
CONFIG_WLCORE_SDIO=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
CONFIG_MWIFIEX_USB=m
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_MATRIX=m
CONFIG_KEYBOARD_TWL4030=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ADS7846=m
CONFIG_TOUCHSCREEN_TSC2005=m
CONFIG_TOUCHSCREEN_TSC2007=m
CONFIG_INPUT_MISC=y
CONFIG_INPUT_TWL4030_PWRBUTTON=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=32
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_OMAP=y
CONFIG_SERIAL_OMAP_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_I2C_CHARDEV=y
CONFIG_SPI=y
CONFIG_SPI_OMAP24XX=y
CONFIG_PINCTRL_SINGLE=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_TWL4030=y
CONFIG_W1=y
CONFIG_BATTERY_BQ27x00=m
CONFIG_CHARGER_ISP1704=m
CONFIG_CHARGER_TWL4030=m
CONFIG_CHARGER_BQ2415X=m
CONFIG_CHARGER_BQ24190=m
CONFIG_CHARGER_BQ24735=m
CONFIG_POWER_RESET=y
CONFIG_POWER_AVS=y
CONFIG_SENSORS_LM75=m
CONFIG_THERMAL=y
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_CPU_THERMAL=y
CONFIG_TI_SOC_THERMAL=y
CONFIG_TI_THERMAL=y
CONFIG_OMAP4_THERMAL=y
CONFIG_OMAP5_THERMAL=y
CONFIG_DRA752_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_OMAP_WATCHDOG=y
CONFIG_TWL4030_WATCHDOG=y
CONFIG_MFD_PALMAS=y
CONFIG_MFD_TPS65217=y
CONFIG_MFD_TPS65218=y
CONFIG_MFD_TPS65910=y
CONFIG_TWL6040_CORE=y
CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_PBIAS=y
CONFIG_REGULATOR_TI_ABB=y
CONFIG_REGULATOR_TPS65023=y
CONFIG_REGULATOR_TPS6507X=y
CONFIG_REGULATOR_TPS65217=y
CONFIG_REGULATOR_TPS65218=y
CONFIG_REGULATOR_TPS65910=y
CONFIG_REGULATOR_TWL4030=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
CONFIG_OMAP2_DSS=m
CONFIG_OMAP5_DSS_HDMI=y
CONFIG_OMAP2_DSS_SDI=y
CONFIG_OMAP2_DSS_DSI=y
CONFIG_FB_OMAP2=m
CONFIG_DISPLAY_ENCODER_TFP410=m
CONFIG_DISPLAY_ENCODER_TPD12S015=m
CONFIG_DISPLAY_CONNECTOR_DVI=m
CONFIG_DISPLAY_CONNECTOR_HDMI=m
CONFIG_DISPLAY_CONNECTOR_ANALOG_TV=m
CONFIG_DISPLAY_PANEL_DPI=m
CONFIG_DISPLAY_PANEL_DSI_CM=m
CONFIG_DISPLAY_PANEL_SONY_ACX565AKM=m
CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02=m
CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01=m
CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1=m
CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1=m
CONFIG_DISPLAY_PANEL_NEC_NL8048HL11=m
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_PLATFORM=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_GENERIC=m
CONFIG_BACKLIGHT_PWM=m
CONFIG_BACKLIGHT_PANDORA=m
CONFIG_BACKLIGHT_GPIO=m
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_LOGO=y
CONFIG_SOUND=m
CONFIG_SND=m
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_USB_AUDIO=m
CONFIG_SND_SOC=m
CONFIG_SND_OMAP_SOC=m
CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m
CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m
CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_MON=y
CONFIG_USB_ACM=y
CONFIG_USB_WDM=y
CONFIG_USB_STORAGE=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_DSPS=y
CONFIG_USB_TI_CPPI41_DMA=y
CONFIG_USB_DWC3=m
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_TEST=y
CONFIG_AM335X_PHY_USB=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_ZERO=m
CONFIG_MMC=y
CONFIG_SDIO_UART=y
CONFIG_MMC_OMAP=y
CONFIG_MMC_OMAP_HS=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_TWL92330=y
CONFIG_RTC_DRV_TWL4030=y
CONFIG_RTC_DRV_OMAP=y
CONFIG_DMADEVICES=y
CONFIG_TI_EDMA=y
CONFIG_DMA_OMAP=y
CONFIG_EXTCON=y
CONFIG_EXTCON_PALMAS=y
CONFIG_PWM=y
CONFIG_PWM_TWL=y
CONFIG_PWM_TWL_LED=y
CONFIG_OMAP_USB2=y
CONFIG_TI_PIPE3=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_EXT4_FS=y
CONFIG_FANOTIFY=y
CONFIG_QUOTA=y
CONFIG_QFMT_V2=y
CONFIG_AUTOFS4_FS=m
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_LZO=y
CONFIG_JFFS2_RUBIN=y
CONFIG_UBIFS_FS=y
CONFIG_CRAMFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
CONFIG_PROVE_LOCKING=y
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_SECURITY=y
CONFIG_CRYPTO_MICHAEL_MIC=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC_CCITT=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
Buildroot defconfig:
BR2_arm=y
BR2_cortex_a8=y
BR2_JLEVEL=24
BR2_CCACHE=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TARGET_GENERIC_GETTY_PORT="ttyO0"
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_DEFCONFIG="omap2plus"
BR2_LINUX_KERNEL_ZIMAGE=y
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="am335x-evmsk am335x-boneblack"
BR2_LINUX_KERNEL_INSTALL_TARGET=y
BR2_PACKAGE_NUTTCP=y
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_SER2NET=y
BR2_TARGET_ROOTFS_TAR_BZIP2=y
BR2_TARGET_UBOOT=y
BR2_TARGET_UBOOT_BOARDNAME="am335x_evm"
BR2_TARGET_UBOOT_FORMAT_IMG=y
BR2_TARGET_UBOOT_SPL=y
BR2_TARGET_UBOOT_SPL_NAME="MLO"
U-Boot version: 2014.07
Kernel config is omap2plus with enabled USB
# cat /proc/version
Linux version 3.18.0 (user@user-VirtualBox) (gcc version 4.8.3
20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #6 SMP
Mon Dec 8 22:47:43 CET 2014
^ permalink raw reply
* [PATCH v3 0/1] net/macb: add TX multiqueue support for gem
From: Cyrille Pitchen @ 2014-12-12 12:26 UTC (permalink / raw)
To: nicolas.ferre, davem, linux-arm-kernel, netdev, soren.brinkmann
Cc: linux-kernel, Cyrille Pitchen
ChangeLog
v3:
- reduce the number of added #define in macb.h
- simplify the queue initialization
- add some more comments
- use "hw_q" index when dealing with the hardware queue mask and "q" index for
linux (software) queue index in "for" loops
v2:
fix compilation warnings for netdev_vdbg("%u...", queue - bp->queues, ...) calls
v1:
At the first look this patch may look quite big but it cannot be splitted.
Each queue has its own dedicated IRQ, which should be handled.
Also the Transmit Base Queue Pointer register of each available queue must be
initialized before starting the transmission, otherwise the transmission will be
halted immediately as HRESP errors are likely to occur.
In addition, some fields had to be moved from struct macb into struct macb_queue
so a common code could manage the queues.
This patch was applied to net-next and tested on a sama5d36ek board, which embeds
both macb and gem IPs, to check the backward compatibility.
Also it was tested on a sama5dx FPGA platform with a gem designed to use 3 queues.
Then we used the tc program to set a queue discipline policy as describe in the
Documentation/networking/multiqueue.txt: we successfully used each queue.
Cyrille Pitchen (1):
net/macb: add TX multiqueue support for gem
drivers/net/ethernet/cadence/macb.c | 456 +++++++++++++++++++++++-------------
drivers/net/ethernet/cadence/macb.h | 36 ++-
2 files changed, 328 insertions(+), 164 deletions(-)
--
1.8.2.2
^ permalink raw reply
* [PATCH v3 1/1] net/macb: add TX multiqueue support for gem
From: Cyrille Pitchen @ 2014-12-12 12:26 UTC (permalink / raw)
To: nicolas.ferre, davem, linux-arm-kernel, netdev, soren.brinkmann
Cc: linux-kernel, Cyrille Pitchen
In-Reply-To: <cover.1418383702.git.cyrille.pitchen@atmel.com>
gem devices designed with multiqueue CANNOT work without this patch.
When probing a gem device, the driver must first prepare and enable the
peripheral clock before accessing I/O registers. The second step is to read the
MID register to find whether the device is a gem or an old macb IP.
For gem devices, it reads the Design Configuration Register 6 (DCFG6) to
compute to total number of queues, whereas macb devices always have a single
queue.
Only then it can call alloc_etherdev_mq() with the correct number of queues.
This is the reason why the order of some initializations has been changed in
macb_probe().
Eventually, the dedicated IRQ and TX ring buffer descriptors are initialized
for each queue.
For backward compatibility reasons, queue0 uses the legacy registers ISR, IER,
IDR, IMR, TBQP and RBQP. On the other hand, the other queues use new registers
ISR[1..7], IER[1..7], IDR[1..7], IMR[1..7], TBQP[1..7] and RBQP[1..7].
Except this hardware detail there is no real difference between queue0 and the
others. The driver hides that thanks to the struct macb_queue.
This structure allows us to share a common set of functions for all the queues.
Besides when a TX error occurs, the gem MUST be halted before writing any of
the TBQP registers to reset the relevant queue. An immediate side effect is
that the other queues too aren't processed anymore by the gem.
So macb_tx_error_task() calls netif_tx_stop_all_queues() to notify the Linux
network engine that all transmissions are stopped.
Also macb_tx_error_task() now calls spin_lock_irqsave() to prevent the
interrupt handlers of the other queues from running as each of them may wake
its associated queue up (please refer to macb_tx_interrupt()).
Finally, as all queues have previously been stopped, they should be restarted
calling netif_tx_start_all_queues() and setting the TSTART bit into the Network
Control Register. Before this patch, when dealing with a single queue, the
driver used to defer the reset of the faulting queue and the write of the
TSTART bit until the next call of macb_start_xmit().
As explained before, this bit is now set by macb_tx_error_task() too. That's
why the faulting queue MUST be reset by setting the TX_USED bit in its first
buffer descriptor before writing the TSTART bit.
Queue 0 always exits and is the lowest priority when other queues are available.
The higher the index of the queue is, the higher its priority is.
When transmitting frames, the TX queue is selected by the skb->queue_mapping
value. So queue discipline can be used to define the queue priority policy.
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
---
drivers/net/ethernet/cadence/macb.c | 456 +++++++++++++++++++++++-------------
drivers/net/ethernet/cadence/macb.h | 36 ++-
2 files changed, 328 insertions(+), 164 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 9ddc9bf..79feb82 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -66,23 +66,25 @@ static unsigned int macb_tx_ring_wrap(unsigned int index)
return index & (TX_RING_SIZE - 1);
}
-static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
+static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue,
+ unsigned int index)
{
- return &bp->tx_ring[macb_tx_ring_wrap(index)];
+ return &queue->tx_ring[macb_tx_ring_wrap(index)];
}
-static struct macb_tx_skb *macb_tx_skb(struct macb *bp, unsigned int index)
+static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue,
+ unsigned int index)
{
- return &bp->tx_skb[macb_tx_ring_wrap(index)];
+ return &queue->tx_skb[macb_tx_ring_wrap(index)];
}
-static dma_addr_t macb_tx_dma(struct macb *bp, unsigned int index)
+static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index)
{
dma_addr_t offset;
offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc);
- return bp->tx_ring_dma + offset;
+ return queue->tx_ring_dma + offset;
}
static unsigned int macb_rx_ring_wrap(unsigned int index)
@@ -490,38 +492,49 @@ static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb)
static void macb_tx_error_task(struct work_struct *work)
{
- struct macb *bp = container_of(work, struct macb, tx_error_task);
+ struct macb_queue *queue = container_of(work, struct macb_queue,
+ tx_error_task);
+ struct macb *bp = queue->bp;
struct macb_tx_skb *tx_skb;
+ struct macb_dma_desc *desc;
struct sk_buff *skb;
unsigned int tail;
+ unsigned long flags;
+
+ netdev_vdbg(bp->dev, "macb_tx_error_task: q = %u, t = %u, h = %u\n",
+ (unsigned int)(queue - bp->queues),
+ queue->tx_tail, queue->tx_head);
- netdev_vdbg(bp->dev, "macb_tx_error_task: t = %u, h = %u\n",
- bp->tx_tail, bp->tx_head);
+ /* Prevent the queue IRQ handlers from running: each of them may call
+ * macb_tx_interrupt(), which in turn may call netif_wake_subqueue().
+ * As explained below, we have to halt the transmission before updating
+ * TBQP registers so we call netif_tx_stop_all_queues() to notify the
+ * network engine about the macb/gem being halted.
+ */
+ spin_lock_irqsave(&bp->lock, flags);
/* Make sure nobody is trying to queue up new packets */
- netif_stop_queue(bp->dev);
+ netif_tx_stop_all_queues(bp->dev);
/*
* Stop transmission now
* (in case we have just queued new packets)
+ * macb/gem must be halted to write TBQP register
*/
if (macb_halt_tx(bp))
/* Just complain for now, reinitializing TX path can be good */
netdev_err(bp->dev, "BUG: halt tx timed out\n");
- /* No need for the lock here as nobody will interrupt us anymore */
-
/*
* Treat frames in TX queue including the ones that caused the error.
* Free transmit buffers in upper layer.
*/
- for (tail = bp->tx_tail; tail != bp->tx_head; tail++) {
- struct macb_dma_desc *desc;
- u32 ctrl;
+ for (tail = queue->tx_tail; tail != queue->tx_head; tail++) {
+ u32 ctrl;
- desc = macb_tx_desc(bp, tail);
+ desc = macb_tx_desc(queue, tail);
ctrl = desc->ctrl;
- tx_skb = macb_tx_skb(bp, tail);
+ tx_skb = macb_tx_skb(queue, tail);
skb = tx_skb->skb;
if (ctrl & MACB_BIT(TX_USED)) {
@@ -529,7 +542,7 @@ static void macb_tx_error_task(struct work_struct *work)
while (!skb) {
macb_tx_unmap(bp, tx_skb);
tail++;
- tx_skb = macb_tx_skb(bp, tail);
+ tx_skb = macb_tx_skb(queue, tail);
skb = tx_skb->skb;
}
@@ -558,45 +571,56 @@ static void macb_tx_error_task(struct work_struct *work)
macb_tx_unmap(bp, tx_skb);
}
+ /* Set end of TX queue */
+ desc = macb_tx_desc(queue, 0);
+ desc->addr = 0;
+ desc->ctrl = MACB_BIT(TX_USED);
+
/* Make descriptor updates visible to hardware */
wmb();
/* Reinitialize the TX desc queue */
- macb_writel(bp, TBQP, bp->tx_ring_dma);
+ queue_writel(queue, TBQP, queue->tx_ring_dma);
/* Make TX ring reflect state of hardware */
- bp->tx_head = bp->tx_tail = 0;
-
- /* Now we are ready to start transmission again */
- netif_wake_queue(bp->dev);
+ queue->tx_head = 0;
+ queue->tx_tail = 0;
/* Housework before enabling TX IRQ */
macb_writel(bp, TSR, macb_readl(bp, TSR));
- macb_writel(bp, IER, MACB_TX_INT_FLAGS);
+ queue_writel(queue, IER, MACB_TX_INT_FLAGS);
+
+ /* Now we are ready to start transmission again */
+ netif_tx_start_all_queues(bp->dev);
+ macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
+
+ spin_unlock_irqrestore(&bp->lock, flags);
}
-static void macb_tx_interrupt(struct macb *bp)
+static void macb_tx_interrupt(struct macb_queue *queue)
{
unsigned int tail;
unsigned int head;
u32 status;
+ struct macb *bp = queue->bp;
+ u16 queue_index = queue - bp->queues;
status = macb_readl(bp, TSR);
macb_writel(bp, TSR, status);
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
- macb_writel(bp, ISR, MACB_BIT(TCOMP));
+ queue_writel(queue, ISR, MACB_BIT(TCOMP));
netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n",
(unsigned long)status);
- head = bp->tx_head;
- for (tail = bp->tx_tail; tail != head; tail++) {
+ head = queue->tx_head;
+ for (tail = queue->tx_tail; tail != head; tail++) {
struct macb_tx_skb *tx_skb;
struct sk_buff *skb;
struct macb_dma_desc *desc;
u32 ctrl;
- desc = macb_tx_desc(bp, tail);
+ desc = macb_tx_desc(queue, tail);
/* Make hw descriptor updates visible to CPU */
rmb();
@@ -611,7 +635,7 @@ static void macb_tx_interrupt(struct macb *bp)
/* Process all buffers of the current transmitted frame */
for (;; tail++) {
- tx_skb = macb_tx_skb(bp, tail);
+ tx_skb = macb_tx_skb(queue, tail);
skb = tx_skb->skb;
/* First, update TX stats if needed */
@@ -634,11 +658,11 @@ static void macb_tx_interrupt(struct macb *bp)
}
}
- bp->tx_tail = tail;
- if (netif_queue_stopped(bp->dev)
- && CIRC_CNT(bp->tx_head, bp->tx_tail,
- TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH)
- netif_wake_queue(bp->dev);
+ queue->tx_tail = tail;
+ if (__netif_subqueue_stopped(bp->dev, queue_index) &&
+ CIRC_CNT(queue->tx_head, queue->tx_tail,
+ TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH)
+ netif_wake_subqueue(bp->dev, queue_index);
}
static void gem_rx_refill(struct macb *bp)
@@ -949,11 +973,12 @@ static int macb_poll(struct napi_struct *napi, int budget)
static irqreturn_t macb_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct macb *bp = netdev_priv(dev);
+ struct macb_queue *queue = dev_id;
+ struct macb *bp = queue->bp;
+ struct net_device *dev = bp->dev;
u32 status;
- status = macb_readl(bp, ISR);
+ status = queue_readl(queue, ISR);
if (unlikely(!status))
return IRQ_NONE;
@@ -963,11 +988,13 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
while (status) {
/* close possible race with dev_close */
if (unlikely(!netif_running(dev))) {
- macb_writel(bp, IDR, -1);
+ queue_writel(queue, IDR, -1);
break;
}
- netdev_vdbg(bp->dev, "isr = 0x%08lx\n", (unsigned long)status);
+ netdev_vdbg(bp->dev, "queue = %u, isr = 0x%08lx\n",
+ (unsigned int)(queue - bp->queues),
+ (unsigned long)status);
if (status & MACB_RX_INT_FLAGS) {
/*
@@ -977,9 +1004,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
* is already scheduled, so disable interrupts
* now.
*/
- macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
+ queue_writel(queue, IDR, MACB_RX_INT_FLAGS);
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
- macb_writel(bp, ISR, MACB_BIT(RCOMP));
+ queue_writel(queue, ISR, MACB_BIT(RCOMP));
if (napi_schedule_prep(&bp->napi)) {
netdev_vdbg(bp->dev, "scheduling RX softirq\n");
@@ -988,17 +1015,17 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
}
if (unlikely(status & (MACB_TX_ERR_FLAGS))) {
- macb_writel(bp, IDR, MACB_TX_INT_FLAGS);
- schedule_work(&bp->tx_error_task);
+ queue_writel(queue, IDR, MACB_TX_INT_FLAGS);
+ schedule_work(&queue->tx_error_task);
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
- macb_writel(bp, ISR, MACB_TX_ERR_FLAGS);
+ queue_writel(queue, ISR, MACB_TX_ERR_FLAGS);
break;
}
if (status & MACB_BIT(TCOMP))
- macb_tx_interrupt(bp);
+ macb_tx_interrupt(queue);
/*
* Link change detection isn't possible with RMII, so we'll
@@ -1013,7 +1040,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
bp->hw_stats.macb.rx_overruns++;
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
- macb_writel(bp, ISR, MACB_BIT(ISR_ROVR));
+ queue_writel(queue, ISR, MACB_BIT(ISR_ROVR));
}
if (status & MACB_BIT(HRESP)) {
@@ -1025,10 +1052,10 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
netdev_err(dev, "DMA bus error: HRESP not OK\n");
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
- macb_writel(bp, ISR, MACB_BIT(HRESP));
+ queue_writel(queue, ISR, MACB_BIT(HRESP));
}
- status = macb_readl(bp, ISR);
+ status = queue_readl(queue, ISR);
}
spin_unlock(&bp->lock);
@@ -1043,10 +1070,14 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
*/
static void macb_poll_controller(struct net_device *dev)
{
+ struct macb *bp = netdev_priv(dev);
+ struct macb_queue *queue;
unsigned long flags;
+ unsigned int q;
local_irq_save(flags);
- macb_interrupt(dev->irq, dev);
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
+ macb_interrupt(dev->irq, queue);
local_irq_restore(flags);
}
#endif
@@ -1058,10 +1089,11 @@ static inline unsigned int macb_count_tx_descriptors(struct macb *bp,
}
static unsigned int macb_tx_map(struct macb *bp,
+ struct macb_queue *queue,
struct sk_buff *skb)
{
dma_addr_t mapping;
- unsigned int len, entry, i, tx_head = bp->tx_head;
+ unsigned int len, entry, i, tx_head = queue->tx_head;
struct macb_tx_skb *tx_skb = NULL;
struct macb_dma_desc *desc;
unsigned int offset, size, count = 0;
@@ -1075,7 +1107,7 @@ static unsigned int macb_tx_map(struct macb *bp,
while (len) {
size = min(len, bp->max_tx_length);
entry = macb_tx_ring_wrap(tx_head);
- tx_skb = &bp->tx_skb[entry];
+ tx_skb = &queue->tx_skb[entry];
mapping = dma_map_single(&bp->pdev->dev,
skb->data + offset,
@@ -1104,7 +1136,7 @@ static unsigned int macb_tx_map(struct macb *bp,
while (len) {
size = min(len, bp->max_tx_length);
entry = macb_tx_ring_wrap(tx_head);
- tx_skb = &bp->tx_skb[entry];
+ tx_skb = &queue->tx_skb[entry];
mapping = skb_frag_dma_map(&bp->pdev->dev, frag,
offset, size, DMA_TO_DEVICE);
@@ -1143,14 +1175,14 @@ static unsigned int macb_tx_map(struct macb *bp,
i = tx_head;
entry = macb_tx_ring_wrap(i);
ctrl = MACB_BIT(TX_USED);
- desc = &bp->tx_ring[entry];
+ desc = &queue->tx_ring[entry];
desc->ctrl = ctrl;
do {
i--;
entry = macb_tx_ring_wrap(i);
- tx_skb = &bp->tx_skb[entry];
- desc = &bp->tx_ring[entry];
+ tx_skb = &queue->tx_skb[entry];
+ desc = &queue->tx_ring[entry];
ctrl = (u32)tx_skb->size;
if (eof) {
@@ -1167,17 +1199,17 @@ static unsigned int macb_tx_map(struct macb *bp,
*/
wmb();
desc->ctrl = ctrl;
- } while (i != bp->tx_head);
+ } while (i != queue->tx_head);
- bp->tx_head = tx_head;
+ queue->tx_head = tx_head;
return count;
dma_error:
netdev_err(bp->dev, "TX DMA map failed\n");
- for (i = bp->tx_head; i != tx_head; i++) {
- tx_skb = macb_tx_skb(bp, i);
+ for (i = queue->tx_head; i != tx_head; i++) {
+ tx_skb = macb_tx_skb(queue, i);
macb_tx_unmap(bp, tx_skb);
}
@@ -1187,14 +1219,16 @@ dma_error:
static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
+ u16 queue_index = skb_get_queue_mapping(skb);
struct macb *bp = netdev_priv(dev);
+ struct macb_queue *queue = &bp->queues[queue_index];
unsigned long flags;
unsigned int count, nr_frags, frag_size, f;
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
netdev_vdbg(bp->dev,
- "start_xmit: len %u head %p data %p tail %p end %p\n",
- skb->len, skb->head, skb->data,
+ "start_xmit: queue %hu len %u head %p data %p tail %p end %p\n",
+ queue_index, skb->len, skb->head, skb->data,
skb_tail_pointer(skb), skb_end_pointer(skb));
print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, 16, true);
@@ -1214,16 +1248,16 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&bp->lock, flags);
/* This is a hard error, log it. */
- if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < count) {
- netif_stop_queue(dev);
+ if (CIRC_SPACE(queue->tx_head, queue->tx_tail, TX_RING_SIZE) < count) {
+ netif_stop_subqueue(dev, queue_index);
spin_unlock_irqrestore(&bp->lock, flags);
netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n",
- bp->tx_head, bp->tx_tail);
+ queue->tx_head, queue->tx_tail);
return NETDEV_TX_BUSY;
}
/* Map socket buffer for DMA transfer */
- if (!macb_tx_map(bp, skb)) {
+ if (!macb_tx_map(bp, queue, skb)) {
dev_kfree_skb_any(skb);
goto unlock;
}
@@ -1235,8 +1269,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
- if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1)
- netif_stop_queue(dev);
+ if (CIRC_SPACE(queue->tx_head, queue->tx_tail, TX_RING_SIZE) < 1)
+ netif_stop_subqueue(dev, queue_index);
unlock:
spin_unlock_irqrestore(&bp->lock, flags);
@@ -1304,20 +1338,24 @@ static void macb_free_rx_buffers(struct macb *bp)
static void macb_free_consistent(struct macb *bp)
{
- if (bp->tx_skb) {
- kfree(bp->tx_skb);
- bp->tx_skb = NULL;
- }
+ struct macb_queue *queue;
+ unsigned int q;
+
bp->macbgem_ops.mog_free_rx_buffers(bp);
if (bp->rx_ring) {
dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES,
bp->rx_ring, bp->rx_ring_dma);
bp->rx_ring = NULL;
}
- if (bp->tx_ring) {
- dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES,
- bp->tx_ring, bp->tx_ring_dma);
- bp->tx_ring = NULL;
+
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ kfree(queue->tx_skb);
+ queue->tx_skb = NULL;
+ if (queue->tx_ring) {
+ dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES,
+ queue->tx_ring, queue->tx_ring_dma);
+ queue->tx_ring = NULL;
+ }
}
}
@@ -1354,12 +1392,27 @@ static int macb_alloc_rx_buffers(struct macb *bp)
static int macb_alloc_consistent(struct macb *bp)
{
+ struct macb_queue *queue;
+ unsigned int q;
int size;
- size = TX_RING_SIZE * sizeof(struct macb_tx_skb);
- bp->tx_skb = kmalloc(size, GFP_KERNEL);
- if (!bp->tx_skb)
- goto out_err;
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ size = TX_RING_BYTES;
+ queue->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
+ &queue->tx_ring_dma,
+ GFP_KERNEL);
+ if (!queue->tx_ring)
+ goto out_err;
+ netdev_dbg(bp->dev,
+ "Allocated TX ring for queue %u of %d bytes at %08lx (mapped %p)\n",
+ q, size, (unsigned long)queue->tx_ring_dma,
+ queue->tx_ring);
+
+ size = TX_RING_SIZE * sizeof(struct macb_tx_skb);
+ queue->tx_skb = kmalloc(size, GFP_KERNEL);
+ if (!queue->tx_skb)
+ goto out_err;
+ }
size = RX_RING_BYTES;
bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
@@ -1370,15 +1423,6 @@ static int macb_alloc_consistent(struct macb *bp)
"Allocated RX ring of %d bytes at %08lx (mapped %p)\n",
size, (unsigned long)bp->rx_ring_dma, bp->rx_ring);
- size = TX_RING_BYTES;
- bp->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
- &bp->tx_ring_dma, GFP_KERNEL);
- if (!bp->tx_ring)
- goto out_err;
- netdev_dbg(bp->dev,
- "Allocated TX ring of %d bytes at %08lx (mapped %p)\n",
- size, (unsigned long)bp->tx_ring_dma, bp->tx_ring);
-
if (bp->macbgem_ops.mog_alloc_rx_buffers(bp))
goto out_err;
@@ -1391,15 +1435,22 @@ out_err:
static void gem_init_rings(struct macb *bp)
{
+ struct macb_queue *queue;
+ unsigned int q;
int i;
- for (i = 0; i < TX_RING_SIZE; i++) {
- bp->tx_ring[i].addr = 0;
- bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ queue->tx_ring[i].addr = 0;
+ queue->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+ }
+ queue->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+ queue->tx_head = 0;
+ queue->tx_tail = 0;
}
- bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
- bp->rx_tail = bp->rx_prepared_head = bp->tx_head = bp->tx_tail = 0;
+ bp->rx_tail = 0;
+ bp->rx_prepared_head = 0;
gem_rx_refill(bp);
}
@@ -1418,16 +1469,21 @@ static void macb_init_rings(struct macb *bp)
bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
for (i = 0; i < TX_RING_SIZE; i++) {
- bp->tx_ring[i].addr = 0;
- bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
+ bp->queues[0].tx_ring[i].addr = 0;
+ bp->queues[0].tx_ring[i].ctrl = MACB_BIT(TX_USED);
+ bp->queues[0].tx_head = 0;
+ bp->queues[0].tx_tail = 0;
}
- bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+ bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
- bp->rx_tail = bp->tx_head = bp->tx_tail = 0;
+ bp->rx_tail = 0;
}
static void macb_reset_hw(struct macb *bp)
{
+ struct macb_queue *queue;
+ unsigned int q;
+
/*
* Disable RX and TX (XXX: Should we halt the transmission
* more gracefully?)
@@ -1442,8 +1498,10 @@ static void macb_reset_hw(struct macb *bp)
macb_writel(bp, RSR, -1);
/* Disable all interrupts */
- macb_writel(bp, IDR, -1);
- macb_readl(bp, ISR);
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ queue_writel(queue, IDR, -1);
+ queue_readl(queue, ISR);
+ }
}
static u32 gem_mdc_clk_div(struct macb *bp)
@@ -1540,6 +1598,9 @@ static void macb_configure_dma(struct macb *bp)
static void macb_init_hw(struct macb *bp)
{
+ struct macb_queue *queue;
+ unsigned int q;
+
u32 config;
macb_reset_hw(bp);
@@ -1565,16 +1626,18 @@ static void macb_init_hw(struct macb *bp)
/* Initialize TX and RX buffers */
macb_writel(bp, RBQP, bp->rx_ring_dma);
- macb_writel(bp, TBQP, bp->tx_ring_dma);
+ for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
+ queue_writel(queue, TBQP, queue->tx_ring_dma);
+
+ /* Enable interrupts */
+ queue_writel(queue, IER,
+ MACB_RX_INT_FLAGS |
+ MACB_TX_INT_FLAGS |
+ MACB_BIT(HRESP));
+ }
/* Enable TX and RX */
macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
-
- /* Enable interrupts */
- macb_writel(bp, IER, (MACB_RX_INT_FLAGS
- | MACB_TX_INT_FLAGS
- | MACB_BIT(HRESP)));
-
}
/*
@@ -1736,7 +1799,7 @@ static int macb_open(struct net_device *dev)
/* schedule a link state check */
phy_start(bp->phy_dev);
- netif_start_queue(dev);
+ netif_tx_start_all_queues(dev);
return 0;
}
@@ -1746,7 +1809,7 @@ static int macb_close(struct net_device *dev)
struct macb *bp = netdev_priv(dev);
unsigned long flags;
- netif_stop_queue(dev);
+ netif_tx_stop_all_queues(dev);
napi_disable(&bp->napi);
if (bp->phy_dev)
@@ -1895,8 +1958,8 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
regs->version = (macb_readl(bp, MID) & ((1 << MACB_REV_SIZE) - 1))
| MACB_GREGS_VERSION;
- tail = macb_tx_ring_wrap(bp->tx_tail);
- head = macb_tx_ring_wrap(bp->tx_head);
+ tail = macb_tx_ring_wrap(bp->queues[0].tx_tail);
+ head = macb_tx_ring_wrap(bp->queues[0].tx_head);
regs_buff[0] = macb_readl(bp, NCR);
regs_buff[1] = macb_or_gem_readl(bp, NCFGR);
@@ -1909,8 +1972,8 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
regs_buff[8] = tail;
regs_buff[9] = head;
- regs_buff[10] = macb_tx_dma(bp, tail);
- regs_buff[11] = macb_tx_dma(bp, head);
+ regs_buff[10] = macb_tx_dma(&bp->queues[0], tail);
+ regs_buff[11] = macb_tx_dma(&bp->queues[0], head);
if (macb_is_gem(bp)) {
regs_buff[12] = gem_readl(bp, USRIO);
@@ -2061,16 +2124,44 @@ static void macb_configure_caps(struct macb *bp)
netdev_dbg(bp->dev, "Cadence caps 0x%08x\n", bp->caps);
}
+static void macb_probe_queues(void __iomem *mem,
+ unsigned int *queue_mask,
+ unsigned int *num_queues)
+{
+ unsigned int hw_q;
+ u32 mid;
+
+ *queue_mask = 0x1;
+ *num_queues = 1;
+
+ /* is it macb or gem ? */
+ mid = __raw_readl(mem + MACB_MID);
+ if (MACB_BFEXT(IDNUM, mid) != 0x2)
+ return;
+
+ /* bit 0 is never set but queue 0 always exists */
+ *queue_mask = __raw_readl(mem + GEM_DCFG6) & 0xff;
+ *queue_mask |= 0x1;
+
+ for (hw_q = 1; hw_q < MACB_MAX_QUEUES; ++hw_q)
+ if (*queue_mask & (1 << hw_q))
+ (*num_queues)++;
+}
+
static int __init macb_probe(struct platform_device *pdev)
{
struct macb_platform_data *pdata;
struct resource *regs;
struct net_device *dev;
struct macb *bp;
+ struct macb_queue *queue;
struct phy_device *phydev;
u32 config;
int err = -ENXIO;
const char *mac;
+ void __iomem *mem;
+ unsigned int hw_q, queue_mask, q, num_queues, q_irq = 0;
+ struct clk *pclk, *hclk, *tx_clk;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
@@ -2078,72 +2169,112 @@ static int __init macb_probe(struct platform_device *pdev)
goto err_out;
}
- err = -ENOMEM;
- dev = alloc_etherdev(sizeof(*bp));
- if (!dev)
- goto err_out;
-
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- bp = netdev_priv(dev);
- bp->pdev = pdev;
- bp->dev = dev;
-
- spin_lock_init(&bp->lock);
- INIT_WORK(&bp->tx_error_task, macb_tx_error_task);
-
- bp->pclk = devm_clk_get(&pdev->dev, "pclk");
- if (IS_ERR(bp->pclk)) {
- err = PTR_ERR(bp->pclk);
+ pclk = devm_clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(pclk)) {
+ err = PTR_ERR(pclk);
dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err);
- goto err_out_free_dev;
+ goto err_out;
}
- bp->hclk = devm_clk_get(&pdev->dev, "hclk");
- if (IS_ERR(bp->hclk)) {
- err = PTR_ERR(bp->hclk);
+ hclk = devm_clk_get(&pdev->dev, "hclk");
+ if (IS_ERR(hclk)) {
+ err = PTR_ERR(hclk);
dev_err(&pdev->dev, "failed to get hclk (%u)\n", err);
- goto err_out_free_dev;
+ goto err_out;
}
- bp->tx_clk = devm_clk_get(&pdev->dev, "tx_clk");
+ tx_clk = devm_clk_get(&pdev->dev, "tx_clk");
- err = clk_prepare_enable(bp->pclk);
+ err = clk_prepare_enable(pclk);
if (err) {
dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err);
- goto err_out_free_dev;
+ goto err_out;
}
- err = clk_prepare_enable(bp->hclk);
+ err = clk_prepare_enable(hclk);
if (err) {
dev_err(&pdev->dev, "failed to enable hclk (%u)\n", err);
goto err_out_disable_pclk;
}
- if (!IS_ERR(bp->tx_clk)) {
- err = clk_prepare_enable(bp->tx_clk);
+ if (!IS_ERR(tx_clk)) {
+ err = clk_prepare_enable(tx_clk);
if (err) {
dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n",
- err);
+ err);
goto err_out_disable_hclk;
}
}
- bp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
- if (!bp->regs) {
+ err = -ENOMEM;
+ mem = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
+ if (!mem) {
dev_err(&pdev->dev, "failed to map registers, aborting.\n");
- err = -ENOMEM;
goto err_out_disable_clocks;
}
- dev->irq = platform_get_irq(pdev, 0);
- err = devm_request_irq(&pdev->dev, dev->irq, macb_interrupt, 0,
- dev->name, dev);
- if (err) {
- dev_err(&pdev->dev, "Unable to request IRQ %d (error %d)\n",
- dev->irq, err);
+ macb_probe_queues(mem, &queue_mask, &num_queues);
+ dev = alloc_etherdev_mq(sizeof(*bp), num_queues);
+ if (!dev)
goto err_out_disable_clocks;
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ bp = netdev_priv(dev);
+ bp->pdev = pdev;
+ bp->dev = dev;
+ bp->regs = mem;
+ bp->num_queues = num_queues;
+ bp->pclk = pclk;
+ bp->hclk = hclk;
+ bp->tx_clk = tx_clk;
+
+ spin_lock_init(&bp->lock);
+
+ /* set the queue register mapping once for all: queue0 has a special
+ * register mapping but we don't want to test the queue index then
+ * compute the corresponding register offset at run time.
+ */
+ for (hw_q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) {
+ if (!(queue_mask & (1 << hw_q)))
+ continue;
+
+ queue = &bp->queues[q_irq];
+ queue->bp = bp;
+ if (hw_q) {
+ queue->ISR = GEM_ISR(hw_q - 1);
+ queue->IER = GEM_IER(hw_q - 1);
+ queue->IDR = GEM_IDR(hw_q - 1);
+ queue->IMR = GEM_IMR(hw_q - 1);
+ queue->TBQP = GEM_TBQP(hw_q - 1);
+ } else {
+ /* queue0 uses legacy registers */
+ queue->ISR = MACB_ISR;
+ queue->IER = MACB_IER;
+ queue->IDR = MACB_IDR;
+ queue->IMR = MACB_IMR;
+ queue->TBQP = MACB_TBQP;
+ }
+
+ /* get irq: here we use the linux queue index, not the hardware
+ * queue index. the queue irq definitions in the device tree
+ * must remove the optional gaps that could exist in the
+ * hardware queue mask.
+ */
+ queue->irq = platform_get_irq(pdev, q_irq);
+ err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt,
+ 0, dev->name, queue);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Unable to request IRQ %d (error %d)\n",
+ queue->irq, err);
+ goto err_out_free_irq;
+ }
+
+ INIT_WORK(&queue->tx_error_task, macb_tx_error_task);
+ q_irq++;
}
+ dev->irq = bp->queues[0].irq;
dev->netdev_ops = &macb_netdev_ops;
netif_napi_add(dev, &bp->napi, macb_poll, 64);
@@ -2219,7 +2350,7 @@ static int __init macb_probe(struct platform_device *pdev)
err = register_netdev(dev);
if (err) {
dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
- goto err_out_disable_clocks;
+ goto err_out_free_irq;
}
err = macb_mii_init(bp);
@@ -2242,15 +2373,17 @@ static int __init macb_probe(struct platform_device *pdev)
err_out_unregister_netdev:
unregister_netdev(dev);
+err_out_free_irq:
+ for (q = 0, queue = bp->queues; q < q_irq; ++q, ++queue)
+ devm_free_irq(&pdev->dev, queue->irq, queue);
+ free_netdev(dev);
err_out_disable_clocks:
- if (!IS_ERR(bp->tx_clk))
- clk_disable_unprepare(bp->tx_clk);
+ if (!IS_ERR(tx_clk))
+ clk_disable_unprepare(tx_clk);
err_out_disable_hclk:
- clk_disable_unprepare(bp->hclk);
+ clk_disable_unprepare(hclk);
err_out_disable_pclk:
- clk_disable_unprepare(bp->pclk);
-err_out_free_dev:
- free_netdev(dev);
+ clk_disable_unprepare(pclk);
err_out:
return err;
}
@@ -2259,6 +2392,8 @@ static int __exit macb_remove(struct platform_device *pdev)
{
struct net_device *dev;
struct macb *bp;
+ struct macb_queue *queue;
+ unsigned int q;
dev = platform_get_drvdata(pdev);
@@ -2270,11 +2405,14 @@ static int __exit macb_remove(struct platform_device *pdev)
kfree(bp->mii_bus->irq);
mdiobus_free(bp->mii_bus);
unregister_netdev(dev);
+ queue = bp->queues;
+ for (q = 0; q < bp->num_queues; ++q, ++queue)
+ devm_free_irq(&pdev->dev, queue->irq, queue);
+ free_netdev(dev);
if (!IS_ERR(bp->tx_clk))
clk_disable_unprepare(bp->tx_clk);
clk_disable_unprepare(bp->hclk);
clk_disable_unprepare(bp->pclk);
- free_netdev(dev);
}
return 0;
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 517c09d..084191b 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -12,6 +12,7 @@
#define MACB_GREGS_NBR 16
#define MACB_GREGS_VERSION 1
+#define MACB_MAX_QUEUES 8
/* MACB register offsets */
#define MACB_NCR 0x0000
@@ -89,6 +90,13 @@
#define GEM_DCFG6 0x0294
#define GEM_DCFG7 0x0298
+#define GEM_ISR(hw_q) (0x0400 + ((hw_q) << 2))
+#define GEM_TBQP(hw_q) (0x0440 + ((hw_q) << 2))
+#define GEM_RBQP(hw_q) (0x0480 + ((hw_q) << 2))
+#define GEM_IER(hw_q) (0x0600 + ((hw_q) << 2))
+#define GEM_IDR(hw_q) (0x0620 + ((hw_q) << 2))
+#define GEM_IMR(hw_q) (0x0640 + ((hw_q) << 2))
+
/* Bitfields in NCR */
#define MACB_LB_OFFSET 0
#define MACB_LB_SIZE 1
@@ -376,6 +384,10 @@
__raw_readl((port)->regs + GEM_##reg)
#define gem_writel(port, reg, value) \
__raw_writel((value), (port)->regs + GEM_##reg)
+#define queue_readl(queue, reg) \
+ __raw_readl((queue)->bp->regs + (queue)->reg)
+#define queue_writel(queue, reg, value) \
+ __raw_writel((value), (queue)->bp->regs + (queue)->reg)
/*
* Conditional GEM/MACB macros. These perform the operation to the correct
@@ -597,6 +609,23 @@ struct macb_config {
unsigned int dma_burst_length;
};
+struct macb_queue {
+ struct macb *bp;
+ int irq;
+
+ unsigned int ISR;
+ unsigned int IER;
+ unsigned int IDR;
+ unsigned int IMR;
+ unsigned int TBQP;
+
+ unsigned int tx_head, tx_tail;
+ struct macb_dma_desc *tx_ring;
+ struct macb_tx_skb *tx_skb;
+ dma_addr_t tx_ring_dma;
+ struct work_struct tx_error_task;
+};
+
struct macb {
void __iomem *regs;
@@ -607,9 +636,8 @@ struct macb {
void *rx_buffers;
size_t rx_buffer_size;
- unsigned int tx_head, tx_tail;
- struct macb_dma_desc *tx_ring;
- struct macb_tx_skb *tx_skb;
+ unsigned int num_queues;
+ struct macb_queue queues[MACB_MAX_QUEUES];
spinlock_t lock;
struct platform_device *pdev;
@@ -618,7 +646,6 @@ struct macb {
struct clk *tx_clk;
struct net_device *dev;
struct napi_struct napi;
- struct work_struct tx_error_task;
struct net_device_stats stats;
union {
struct macb_stats macb;
@@ -626,7 +653,6 @@ struct macb {
} hw_stats;
dma_addr_t rx_ring_dma;
- dma_addr_t tx_ring_dma;
dma_addr_t rx_buffers_dma;
struct macb_or_gem_ops macbgem_ops;
--
1.8.2.2
^ permalink raw reply related
* Re: [PATCH] net: phy: export fixed_phy_register()
From: Florian Fainelli @ 2014-12-12 12:31 UTC (permalink / raw)
To: Mark Salter; +Cc: netdev, linux-kernel, davem
In-Reply-To: <1418357006-2450-1-git-send-email-msalter@redhat.com>
Le 11/12/2014 20:03, Mark Salter a écrit :
> When building the bcmgenet driver as module, I get:
>
> ERROR: "fixed_phy_register" [drivers/net/ethernet/broadcom/genet/genet.ko] undefined!
>
> commit b0ba512e225d72 ("net: bcmgenet: enable driver to work without device
> tree") which added a call to fixed_phy_register. But fixed_phy_register
> needs to be exported if used from a module.
>
> Signed-off-by: Mark Salter <msalter@redhat.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
I will have to rework the GENET/SYSTEMPORT/SF2 dependencies anyway, thanks!
> ---
> drivers/net/phy/fixed.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
> index 47872caa..3ad0e6e 100644
> --- a/drivers/net/phy/fixed.c
> +++ b/drivers/net/phy/fixed.c
> @@ -274,6 +274,7 @@ struct phy_device *fixed_phy_register(unsigned int irq,
>
> return phy;
> }
> +EXPORT_SYMBOL_GPL(fixed_phy_register);
>
> static int __init fixed_mdio_bus_init(void)
> {
>
^ permalink raw reply
* [PATCH 0/2] Remove redundant function
From: Quentin Lambert @ 2014-12-12 12:34 UTC (permalink / raw)
To: Guo-Fu Tseng, netdev, linux-kernel
tasklet_hi_enable and tasklet_enable are redundant. Since
tasklet_hi_enable is used only 6 times in 1 file, the first
patch changes calls to the function with calls to tasklet_enable.
The second patch removes tasklet_hi_enable definition.
Quentin Lambert (2):
jme: replace calls to redundant function
linux/interrupt.h: remove the definition of unused tasklet_hi_enable
drivers/net/ethernet/jme.c | 12 ++++++------
include/linux/interrupt.h | 6 ------
2 files changed, 6 insertions(+), 12 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH 1/2] jme: replace calls to redundant function
From: Quentin Lambert @ 2014-12-12 12:35 UTC (permalink / raw)
To: Guo-Fu Tseng; +Cc: netdev, linux-kernel
Calls to tasklet_hi_enable are replaced by calls to
tasklet_enable since the 2 functions are redundant.
Signed-off-by: Quentin Lambert <lambert.quentin@gmail.com>
Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
---
drivers/net/ethernet/jme.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 4a1be34..44ce7d8 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1364,8 +1364,8 @@ err_out_free_rx_resources:
jme_free_rx_resources(jme);
out_enable_tasklet:
tasklet_enable(&jme->txclean_task);
- tasklet_hi_enable(&jme->rxclean_task);
- tasklet_hi_enable(&jme->rxempty_task);
+ tasklet_enable(&jme->rxclean_task);
+ tasklet_enable(&jme->rxempty_task);
out:
atomic_inc(&jme->link_changing);
}
@@ -2408,8 +2408,8 @@ static inline void jme_resume_rx(struct jme_adapter *jme)
if (test_bit(JME_FLAG_POLL, &jme->flags)) {
JME_NAPI_ENABLE(jme);
} else {
- tasklet_hi_enable(&jme->rxclean_task);
- tasklet_hi_enable(&jme->rxempty_task);
+ tasklet_enable(&jme->rxclean_task);
+ tasklet_enable(&jme->rxempty_task);
}
dpi->cur = PCC_P1;
dpi->attempt = PCC_P1;
@@ -3290,8 +3290,8 @@ jme_suspend(struct device *dev)
}
tasklet_enable(&jme->txclean_task);
- tasklet_hi_enable(&jme->rxclean_task);
- tasklet_hi_enable(&jme->rxempty_task);
+ tasklet_enable(&jme->rxclean_task);
+ tasklet_enable(&jme->rxempty_task);
jme_powersave_phy(jme);
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] linux/interrupt.h: remove the definition of unused tasklet_hi_enable
From: Quentin Lambert @ 2014-12-12 12:36 UTC (permalink / raw)
To: Guo-Fu Tseng; +Cc: netdev, linux-kernel
Signed-off-by: Quentin Lambert <lambert.quentin@gmail.com>
Signed-off-by: Valentin Rothberg <valentinrothberg@gmail.com>
---
include/linux/interrupt.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 69517a2..d9b05b5 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -556,12 +556,6 @@ static inline void tasklet_enable(struct tasklet_struct *t)
atomic_dec(&t->count);
}
-static inline void tasklet_hi_enable(struct tasklet_struct *t)
-{
- smp_mb__before_atomic();
- atomic_dec(&t->count);
-}
-
extern void tasklet_kill(struct tasklet_struct *t);
extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu);
extern void tasklet_init(struct tasklet_struct *t,
--
1.9.1
^ permalink raw reply related
* Re: [PATCH net] net: ethernet: davicom: Allow to select DM9000 for nios2
From: Tobias Klauser @ 2014-12-12 12:40 UTC (permalink / raw)
To: Simon Horman; +Cc: netdev
In-Reply-To: <20141212112842.GA17780@verge.net.au>
On 2014-12-12 at 12:28:42 +0100, Simon Horman <horms@verge.net.au> wrote:
> On Fri, Dec 12, 2014 at 10:21:11AM +0100, Tobias Klauser wrote:
> > This chip is present on older revisions of the DE2 development kit.
> >
> > Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
>
> I wonder if || COMPILE_TEST should also be added to allow extra build
> coverage. Is there a specific reason it won't compile more widely?
>
> Likewise for your smsc patch.
Good point. I don't think there's a reason for it not being compiled
more widely. Should I update my patches accordingly or send a separate
patch?
^ permalink raw reply
* Re: [netdev01] registration inconsistency
From: Jamal Hadi Salim @ 2014-12-12 13:12 UTC (permalink / raw)
To: Johannes Berg
Cc: netdev01, Brenda Butler, netdev@vger.kernel.org,
Richard Guy Briggs
In-Reply-To: <1418387022.2470.26.camel@sipsolutions.net>
On 12/12/14 07:23, Johannes Berg wrote:
> On Fri, 2014-12-12 at 06:42 -0500, Jamal Hadi Salim wrote:
>
>> For workshops, you should go ahead and invite people you want.
>> If you want us to give codes to some people (means either they dont
>> have to pay or get discounts) then ping bjb and/or myself.
>
> No no, I don't think any (many) people will need a discount.
>
>> I am not sure how we distinguish invited people vs not-invited. It
>> would be nice to be able to do so.
>> One way is to do what the IETF does; provide color coded badges?
>> Also:
>> Do you think we need to change the language on the web site
>> to avoid any confusion?
>
> I think the confusion is that the CFP and the website say the conference
> is going to be be 50% speakers and 50% invitation: "The netdev
> conference this year is structured to be 50/50 by-invitation and talk
> submission"
>
> Looking back at this, I think you meant that the *talks* were going to
> be 50/50 like that, but some people have contacted me about that they
> thought *attendance* was going to be like that. In fact I just glossed
> over it and until now thought the same!
>
> If I'm right that you meant *talks* then I think you should clarify that
> language and even send out a clarification as a reply to the CFP email.
>
I think i got it.
Either a reply or we fix the CFP on the website.
Ccing Richard.
cheers,
jamal
^ permalink raw reply
* Re: [netdev01] registration inconsistency
From: Johannes Berg @ 2014-12-12 13:19 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: netdev01, Brenda Butler, netdev@vger.kernel.org,
Richard Guy Briggs
In-Reply-To: <548AE9AF.90902@mojatatu.com>
On Fri, 2014-12-12 at 08:12 -0500, Jamal Hadi Salim wrote:
> > Looking back at this, I think you meant that the *talks* were going to
> > be 50/50 like that, but some people have contacted me about that they
> > thought *attendance* was going to be like that. In fact I just glossed
> > over it and until now thought the same!
> >
> > If I'm right that you meant *talks* then I think you should clarify that
> > language and even send out a clarification as a reply to the CFP email.
> >
>
> I think i got it.
> Either a reply or we fix the CFP on the website.
> Ccing Richard.
I think a reply message would be good so it lands with those people who
might have gotten the original and misinterpreted it as well. Your
call :)
johannes
^ permalink raw reply
* Re: [PATCH net-next RESEND] net: Do not call ndo_dflt_fdb_dump if ndo_fdb_dump is defined.
From: Hubert Sokolowski @ 2014-12-12 13:36 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: Hubert Sokolowski, Roopa Prabhu, netdev@vger.kernel.org,
Vlad Yasevich
In-Reply-To: <548AD781.5020004@mojatatu.com>
> On 12/12/14 06:38, Hubert Sokolowski wrote:
>>> On 12/11/14, 9:06 AM, Hubert Sokolowski wrote:
>
>> Please see how the ndo_dflt_fdb_add and del are called:
>> if (dev->netdev_ops->ndo_fdb_add)
>> err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
>> vid,
>> nlh->nlmsg_flags);
>> else
>> err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
>> nlh->nlmsg_flags);
>>
>
> Semantically add and dump are not the same.
> Add adds a specific entry.
> Dump not only dumps the fdb table but also the unicast and multicast
> addresses.
this is not true for 3.16 and before. Please see:
http://lxr.free-electrons.com/source/net/core/rtnetlink.c?v=3.16#L2545
It lets you fully manage the FDB table by overwriding fdb_add, del and dump
in the same way.
>
>
>> As it was suggested by Ronen I can modify the patch so the dflt callback
>> is always called for bridge devices if this is desirable. Either by calling
>> it when following expression is true:
>> (dev->priv_flags & IFF_BRIDGE_PORT)
>> or by modifying br_fdb_dump to call ndo_dflt_fdb_dump.
>>
>
> Are you saying the above is going to work? You need to TEST please.
yes, it works and it is not a rocket science :). we just need to agree
on the approach to use.
>
> It seems to me drivers which do this:
> ---
> .ndo_fdb_dump = my_fdb_dump,
>
> and then my_fdb_dump is:
> return ndo_dflt_fdb_dump(skb, ncb, netdev, filter_dev, idx);
>
> are broken because we always have to dump the uni/multicast
> addresses *unconditionally* and these drivers claim to be
> overriding the dumper but are in fact calling the default dumper.
> They are not filtering anything as you had stated.
> I wish Vlad (Cced) would show up and say something ;->
>
> IOW, fix all the broken driver to not do that.
These "broken" drivers were written before 3.17 when the unconditional call
to dflt_dump was introduced. Some drivers implement own dump and don't
call dflt_dump at all, some call dflt_dump depending on some condition.
You can also call dflt_dump inside, save the idx result and continue
with own dump resulting in both uc/mc and own entries returned to the user.
thanks,
Hubert
^ permalink raw reply
* Re: [PATCH net] net: ethernet: davicom: Allow to select DM9000 for nios2
From: Simon Horman @ 2014-12-12 13:58 UTC (permalink / raw)
To: Tobias Klauser; +Cc: netdev
In-Reply-To: <20141212124015.GH16916@distanz.ch>
On Fri, Dec 12, 2014 at 01:40:15PM +0100, Tobias Klauser wrote:
> On 2014-12-12 at 12:28:42 +0100, Simon Horman <horms@verge.net.au> wrote:
> > On Fri, Dec 12, 2014 at 10:21:11AM +0100, Tobias Klauser wrote:
> > > This chip is present on older revisions of the DE2 development kit.
> > >
> > > Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
> >
> > I wonder if || COMPILE_TEST should also be added to allow extra build
> > coverage. Is there a specific reason it won't compile more widely?
> >
> > Likewise for your smsc patch.
>
> Good point. I don't think there's a reason for it not being compiled
> more widely. Should I update my patches accordingly or send a separate
> patch?
I'm not the maintainer but a follow-up patch or patches seems reasonable to me.
^ permalink raw reply
* Re: [netdev01] registration inconsistency
From: Richard Guy Briggs @ 2014-12-12 14:01 UTC (permalink / raw)
To: Johannes Berg
Cc: Jamal Hadi Salim, netdev01, Brenda Butler, netdev@vger.kernel.org,
Richard Guy Briggs
In-Reply-To: <1418390391.2470.45.camel@sipsolutions.net>
On 14/12/12, Johannes Berg wrote:
> On Fri, 2014-12-12 at 08:12 -0500, Jamal Hadi Salim wrote:
>
> > > Looking back at this, I think you meant that the *talks* were going to
> > > be 50/50 like that, but some people have contacted me about that they
> > > thought *attendance* was going to be like that. In fact I just glossed
> > > over it and until now thought the same!
> > >
> > > If I'm right that you meant *talks* then I think you should clarify that
> > > language and even send out a clarification as a reply to the CFP email.
> >
> > I think i got it.
> > Either a reply or we fix the CFP on the website.
> > Ccing Richard.
>
> I think a reply message would be good so it lands with those people who
> might have gotten the original and misinterpreted it as well. Your
> call :)
I totally missed that as well, but agree it should be clarified with a reply
and a news item on the web site as well as a change to the wording on the web
site.
> johannes
slainte mhath, RGB
--
Richard Guy Briggs -- ~\ -- ~\ <hpv.tricolour.ca>
<www.TriColour.ca> -- \___ o \@ @ Ride yer bike!
Ottawa, ON, CANADA -- Lo_>__M__\\/\%__\\/\%
Vote! -- <greenparty.ca>_____GTVS6#790__(*)__(*)________(*)(*)_________________
^ permalink raw reply
* Re: [PATCH v2 0/6] net-PPP: Deletion of a few unnecessary checks
From: David Miller @ 2014-12-12 14:29 UTC (permalink / raw)
To: elfring
Cc: sergei.shtylyov, paulus, linux-ppp, netdev, eric.dumazet,
linux-kernel, kernel-janitors, julia.lawall
In-Reply-To: <548A92E2.8090304@users.sourceforge.net>
From: SF Markus Elfring <elfring@users.sourceforge.net>
Date: Fri, 12 Dec 2014 08:01:54 +0100
>> Generally speaking, it is advisable to not leave error pointers in data
>> structures, even if they are about to be free'd up in an error path anyways.
>>
>> Therefore I do not like some of the patches in this series.
>
> Can you give any more concrete feedback here?
I gave you very concrete feedback, I said exactly that I don't want
error pointers left in data structure members.
I cannot describe my requirements any more precisely than that.
^ permalink raw reply
* Re: [PATCH net-next RESEND] net: Do not call ndo_dflt_fdb_dump if ndo_fdb_dump is defined.
From: Jamal Hadi Salim @ 2014-12-12 14:35 UTC (permalink / raw)
To: Hubert Sokolowski; +Cc: Roopa Prabhu, netdev@vger.kernel.org, Vlad Yasevich
In-Reply-To: <4c22a6c452a73b3b77a9a9c8e7f76bcc.squirrel@poczta.wsisiz.edu.pl>
On 12/12/14 08:36, Hubert Sokolowski wrote:
>> On 12/12/14 06:38, Hubert Sokolowski wrote:
>>>> On 12/11/14, 9:06 AM, Hubert Sokolowski wrote:
>>
>>> Please see how the ndo_dflt_fdb_add and del are called:
>>> if (dev->netdev_ops->ndo_fdb_add)
>>> err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
>>> vid,
>>> nlh->nlmsg_flags);
>>> else
>>> err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
>>> nlh->nlmsg_flags);
>>>
>>
>> Semantically add and dump are not the same.
>> Add adds a specific entry.
>> Dump not only dumps the fdb table but also the unicast and multicast
>> addresses.
> this is not true for 3.16 and before. Please see:
> http://lxr.free-electrons.com/source/net/core/rtnetlink.c?v=3.16#L2545
> It lets you fully manage the FDB table by overwriding fdb_add, del and dump
> in the same way.
>
>
>
>>
>>
>>> As it was suggested by Ronen I can modify the patch so the dflt callback
>>> is always called for bridge devices if this is desirable. Either by calling
>>> it when following expression is true:
>>> (dev->priv_flags & IFF_BRIDGE_PORT)
>>> or by modifying br_fdb_dump to call ndo_dflt_fdb_dump.
>>>
>>
>> Are you saying the above is going to work? You need to TEST please.
> yes, it works and it is not a rocket science :). we just need to agree
> on the approach to use.
>
I am happy if this solves wont break
any of the use cases Vlad made me test and make sure work.
When i said "test" - I mean run the testcases outlined in the
commit log; if those work i dont see what the issue is.
cheers,
jamal
^ 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