* Re: [PATCH net-next v4 2/2] bonding: Simplify the xmit function for modes that use xmit_hash
From: Mahesh Bandewar @ 2014-09-24 0:14 UTC (permalink / raw)
To: Nikolay Aleksandrov
Cc: Jay Vosburgh, Veaceslav Falico, Andy Gospodarek, David Miller,
netdev, Eric Dumazet, Maciej Zenczykowski
In-Reply-To: <54212F51.4080707@redhat.com>
On Tue, Sep 23, 2014 at 1:29 AM, Nikolay Aleksandrov <nikolay@redhat.com> wrote:
> On 23/09/14 07:13, Mahesh Bandewar wrote:
>>
>> On Sun, Sep 21, 2014 at 4:07 AM, Nikolay Aleksandrov <nikolay@redhat.com>
>> wrote:
>>>
>>> On 09/20/2014 10:04 PM, Mahesh Bandewar wrote:
>>>>
>>>> On Sat, Sep 20, 2014 at 3:19 AM, Nikolay Aleksandrov
>>>> <nikolay@redhat.com> wrote:
>>>>>
>>>>> On 09/20/2014 02:09 AM, Mahesh Bandewar wrote:
>>>>>>
>>>>>> On Fri, Sep 19, 2014 at 4:06 AM, Nikolay Aleksandrov
>>>>>> <nikolay@redhat.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 09/19/2014 12:00 PM, Nikolay Aleksandrov wrote:
>>>>>>>>
>>>>>>>> On 09/18/2014 11:53 PM, Mahesh Bandewar wrote:
>>>>>>>>>
>>>>>>>>> Earlier change to use usable slave array for TLB mode had an
>>>>>>>>> additional
>>>>>>>>> performance advantage. So extending the same logic to all other
>>>>>>>>> modes
>>>>>>>>> that use xmit-hash for slave selection (viz 802.3AD, and XOR
>>>>>>>>> modes).
>>>>>>>>> Also consolidating this with the earlier TLB change.
>>>>>>>>>
>>>>>>>>> The main idea is to build the usable slaves array in the control
>>>>>>>>> path
>>>>>>>>> and use that array for slave selection during xmit operation.
>>>>>>>>>
>>>>>>>>> Measured performance in a setup with a bond of 4x1G NICs with 200
>>>>>>>>> instances of netperf for the modes involved (3ad, xor, tlb)
>>>>>>>>> cmd: netperf -t TCP_RR -H <TargetHost> -l 60 -s 5
>>>>>>>>>
>>>>>>>>> Mode TPS-Before TPS-After
>>>>>>>>>
>>>>>>>>> 802.3ad : 468,694 493,101
>>>>>>>>> TLB (lb=0): 392,583 392,965
>>>>>>>>> XOR : 475,696 484,517
>>>>>>>>>
>>>>>>>>> Signed-off-by: Mahesh Bandewar <maheshb@google.com>
>>>>>>>>> ---
>>>>>>>>> v1:
>>>>>>>>> (a) If bond_update_slave_arr() fails to allocate memory, it will
>>>>>>>>> overwrite
>>>>>>>>> the slave that need to be removed.
>>>>>>>>> (b) Freeing of array will assign NULL (to handle bond->down to
>>>>>>>>> bond->up
>>>>>>>>> transition gracefully.
>>>>>>>>> (c) Change from pr_debug() to pr_err() if
>>>>>>>>> bond_update_slave_arr() returns
>>>>>>>>> failure.
>>>>>>>>> (d) XOR: bond_update_slave_arr() will consider mii-mon, arp-mon
>>>>>>>>> cases and
>>>>>>>>> will populate the array even if these parameters are not
>>>>>>>>> used.
>>>>>>>>> (e) 3AD: Should handle the ad_agg_selection_logic correctly.
>>>>>>>>> v2:
>>>>>>>>> (a) Removed rcu_read_{un}lock() calls from array manipulation
>>>>>>>>> code.
>>>>>>>>> (b) Slave link-events now refresh array for all these modes.
>>>>>>>>> (c) Moved free-array call from bond_close() to bond_uninit().
>>>>>>>>> v3:
>>>>>>>>> (a) Fixed null pointer dereference.
>>>>>>>>> (b) Removed bond->lock lockdep dependency.
>>>>>>>>> v4:
>>>>>>>>> (a) Made to changes to comply with Nikolay's locking changes
>>>>>>>>> (b) Added a work-queue to refresh slave-array when RTNL is not
>>>>>>>>> held
>>>>>>>>> (c) Array refresh happens ONLY with RTNL now.
>>>>>>>>> (d) alloc changed from GFP_ATOMIC to GFP_KERNEL
>>>>>>>>>
>>>>>>> <<<snip>>>
>>>>>>>>>
>>>>>>>>> @@ -3839,6 +4003,7 @@ static void bond_uninit(struct net_device
>>>>>>>>> *bond_dev)
>>>>>>>>> struct bonding *bond = netdev_priv(bond_dev);
>>>>>>>>> struct list_head *iter;
>>>>>>>>> struct slave *slave;
>>>>>>>>> + struct bond_up_slave *arr;
>>>>>>>>>
>>>>>>>>> bond_netpoll_cleanup(bond_dev);
>>>>>>>>>
>>>>>>>>> @@ -3847,6 +4012,12 @@ static void bond_uninit(struct net_device
>>>>>>>>> *bond_dev)
>>>>>>>>> __bond_release_one(bond_dev, slave->dev, true);
>>>>>>>>> netdev_info(bond_dev, "Released all slaves\n");
>>>>>>>>>
>>>>>>> Sorry but I just spotted a major problem, bond_3ad_unbind_slave()
>>>>>>> (called
>>>>>>> from __bond_release_one) calls ad_agg_selection_logic() which can
>>>>>>> re-arm
>>>>>>> the slave_arr work after it's supposed to be stopped here (i.e. the
>>>>>>> bond
>>>>>>> device has been closed so all works should've been stopped) so we
>>>>>>> might
>>>>>>> leak memory and access freed memory after all since it'll keep
>>>>>>> re-scheduling itself until it can acquire rtnl which is after the
>>>>>>> bond
>>>>>>> device has been destroyed.
>>>>>>>
>>>>>> This should not be a problem. ndo_close (bond_close()) is called
>>>>>> before ndo_uninit(bond_uninit()), so the work-queues get cancelled
>>>>>> there so if rearm tries to schedule some work after queue gets
>>>>>> cancelled, it can't do much and wont harm anything.
>>>>>> Hence there wont be any arrays built once it's free-ed completely and
>>>>>> therefore no memory leak. I addded some instrumentation and tried
>>>>>> following sequence -
>>>>>>
>>>>>> # modprobe bonding mode=4
>>>>>> # ip link set bond0 up
>>>>>> # [Add ip]
>>>>>> # [Add default route]
>>>>>> # ifenslave bond0 eth0 eth1 eth2 eth3
>>>>>> ....
>>>>>> [Run some backgound traffic. I used netperf.]
>>>>>>
>>>>>> # ip link bond0 down
>>>>>>
>>>>>> I did not see anything "bad" happening. Did your trial produced
>>>>>> something unpleasant?
>>>>>>
>>>>> The test you've done is irrelevant to the situation that I described
>>>>> because ndo_uninit() is called when the device is being destroyed.
>>>>> Moreover
>>>>> the case I told you about would require to have an active aggregator
>>>>> and an
>>>>> inactive one (i.e. so agg selection logic will get called), here is the
>>>>> result:
>>>>> [ 428.916586] bond1 (unregistering): Removing an active aggregator
>>>>> [ 428.916589] Failed to build slave-array.
>>>>> [ 428.916849] bond1 (unregistering): Releasing active interface eth1
>>>>> [ 428.920342] bond1 (unregistering): Released all slaves
>>>>> [ 428.923043] Failed to update slave array from WT
>>>>> [ 428.924098] Failed to update slave array from WT
>>>>> [ 428.925125] Failed to update slave array from WT
>>>>> [ 428.926120] Failed to update slave array from WT
>>>>> [ 428.927096] Failed to update slave array from WT
>>>>> [ 428.928101] Failed to update slave array from WT
>>>>> [ 428.929120] Failed to update slave array from WT
>>>>> [ 428.930086] BUG: unable to handle kernel NULL pointer dereference at
>>>>> (null)
>>>>> [ 428.930644] IP: [<ffffffff810aa37b>] __queue_work+0x7b/0x350
>>>>> [ 428.930946] PGD 0
>>>>> [ 428.931053] Oops: 0000 [#1] SMP
>>>>> [ 428.931053] Modules linked in: sfc ptp pps_core mdio i2c_algo_bit
>>>>> mtd
>>>>> bonding(O) snd_hda_codec_generic joydev crct10dif_pclmul crc32_pclmul
>>>>> i2c_piix4 ppdev crc32c_intel ghash_clmulni_intel parport_pc
>>>>> snd_hda_intel
>>>>> snd_hda_controller snd_hda_codec snd_hwdep snd_pcm snd_timer
>>>>> 9pnet_virtio
>>>>> snd 9pnet pcspkr parport i2ccore serio_raw virtio_console
>>>>> virtio_balloon
>>>>> pvpanic soundcore virtio_blk virtio_net ata_generic floppy pata_acpi
>>>>> virtio_pci virtio_ring virtio
>>>>> [ 428.935022] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O
>>>>> 3.17.0-rc4+ #30
>>>>> [ 428.935022] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
>>>>> [ 428.935022] task: ffffffff81c1b460 ti: ffffffff81c00000 task.ti:
>>>>> ffffffff81c00000
>>>>> [ 428.935022] RIP: 0010:[<ffffffff810aa37b>] [<ffffffff810aa37b>]
>>>>> __queue_work+0x7b/0x350
>>>>> [ 428.935022] RSP: 0018:ffff88005f003e28 EFLAGS: 00010086
>>>>> [ 428.935022] RAX: ffff88005c05c800 RBX: 0000000000000000 RCX:
>>>>> 0000000000000000
>>>>> [ 428.935022] RDX: 0000000000000000 RSI: 0000000000000006 RDI:
>>>>> ffff88005a4fbd58
>>>>> [ 428.935022] RBP: ffff88005f003e60 R08: 0000000000000046 R09:
>>>>> ffffffff8225abc2
>>>>> [ 428.935022] R10: 0000000000000004 R11: 0000000000000005 R12:
>>>>> ffff88005a4fbd58
>>>>> [ 428.935022] R13: 0000000000000008 R14: ffff88004b211800 R15:
>>>>> 00000000000102f0
>>>>> [ 428.935022] FS: 0000000000000000(0000) GS:ffff88005f000000(0000)
>>>>> knlGS:0000000000000000
>>>>> [ 428.935022] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>>>>> [ 428.935022] CR2: 0000000000000000 CR3: 000000004abde000 CR4:
>>>>> 00000000000406f0
>>>>> [ 428.935022] Stack:
>>>>> [ 428.935022] 0a19522f72b12222 0000000081c1b460 ffffffff8225abc0
>>>>> ffff88005a4fbd78
>>>>> [ 428.935022] 0000000000000101 ffffffff810aa650 ffff88005a4fbd58
>>>>> ffff88005f003e70
>>>>> [ 428.935022] ffffffff810aa668 ffff88005f003ea8 ffffffff810f3536
>>>>> ffffffff8225abc0
>>>>> [ 428.935022] Call Trace:
>>>>> [ 428.935022] <IRQ>
>>>>> [ 428.935022]
>>>>> [ 428.935022] [<ffffffff810aa650>] ? __queue_work+0x350/0x350
>>>>> [ 428.935022] [<ffffffff810aa668>] delayed_work_timer_fn+0x18/0x20
>>>>> [ 428.935022] [<ffffffff810f3536>] call_timer_fn+0x36/0x120
>>>>> [ 428.935022] [<ffffffff810aa650>] ? __queue_work+0x350/0x350
>>>>> [ 428.935022] [<ffffffff810f38f5>] run_timer_softirq+0x1a5/0x320
>>>>> [ 428.935022] [<ffffffff81096dc5>] __do_softirq+0xf5/0x2b0
>>>>> [ 428.935022] [<ffffffff810971fd>] irq_exit+0xbd/0xd0
>>>>> [ 428.935022] [<ffffffff8173b715>] smp_apic_timer_interrupt+0x45/0x60
>>>>> [ 428.935022] [<ffffffff8173981d>] apic_timer_interrupt+0x6d/0x80
>>>>> [ 428.935022] <EOI>
>>>>> [ 428.935022]
>>>>> [ 428.935022] [<ffffffff810581c6>] ? native_safe_halt+0x6/0x10
>>>>> [ 428.935022] [<ffffffff8101f36f>] default_idle+0x1f/0xe0
>>>>> [ 428.935022] [<ffffffff8101fd8f>] arch_cpu_idle+0xf/0x20
>>>>> [ 428.935022] [<ffffffff810d25dd>] cpu_startup_entry+0x38d/0x3c0
>>>>> [ 428.935022] [<ffffffff81722927>] rest_init+0x87/0x90
>>>>> [ 428.935022] [<ffffffff81d3510e>] start_kernel+0x482/0x4a3
>>>>> [ 428.935022] [<ffffffff81d34a85>] ? set_init_arg+0x53/0x53
>>>>> [ 428.935022] [<ffffffff81d34120>] ? early_idt_handlers+0x120/0x120
>>>>> [ 428.935022] [<ffffffff81d345ee>]
>>>>> x86_64_start_reservations+0x2a/0x2c
>>>>> [ 428.935022] [<ffffffff81d3473d>] x86_64_start_kernel+0x14d/0x170
>>>>> [ 428.935022] Code: 84 bb 01 00 00 a8 02 0f 85 eb 00 00 00 48 63 45 d4
>>>>> 49
>>>>> 8b 9e 08 01 00 00 48 03 1c c5 60 fa d0 81 4c 89 e7 e8 18 f5 ff ff 48 85
>>>>> c0
>>>>> <48> 8b 3b 0f 84 7c 01 00 00 48 39 c7 0f 84 73 01 00 00 48 89 c7
>>>>> [ 428.935022] RIP [<ffffffff810aa37b>] __queue_work+0x7b/0x350
>>>>> [ 428.935022] RSP <ffff88005f003e28>
>>>>> [ 428.935022] CR2: 0000000000000000
>>>>>
>>>>> This is because it keeps trying to re-schedule even though the
>>>>> interface's
>>>>> memory has been freed.
>>>>>
>>>> Hmm, how do we handle this?
>>>>
>>> This is tricky and what concerns me more is that people might make this
>>> mistake again in the future. It's easy to unknowingly make use of a
>>> function that re-schedules this from the wrong place.
>>> What I just noticed is that for all 3ad cases you could pull the
>>> scheduling
>>> in the bond_3ad_state_machine_handler() function.
>>> The call sites of ad_agg_selection_logic() are:
>>> - 3ad unbind slave (no need to schedule here as __bond_release_one would
>>> rebuild the array anyhow)
>>> - bond_3ad_state_machine_handler() <- here's where the schedule should
>>> happen as this gets stopped first when the bond is closed and can't get
>>> restarted unless it's opened again.
>>> - ad_port_selection_logic() <- this is called from
>>> bond_3ad_state_machine_handler() only, so this case will be handled as
>>> well.
>>>
>>> The other 2 functions that you convert - ad_enable/disable_collecting are
>>> used only from ad_mux_machine() which is only called in
>>> bond_3ad_state_machine_handler().
>>>
>>> So basically you can pull all rebuild schedules in their common caller -
>>> bond_3ad_state_machine_handler(), just make a flag to note that a rebuild
>>> is needed probably something similar to should_notify_rtnl.
>>> This way you can remove the scheduling from the various 3ad functions
>>> that
>>> may get used and will have it only in 1 place which is more easily
>>> controlled.
>>>
>> Well, I was just trying to avoid using flags to pass state from one to
>> another function so that we can update the array at one place. This
>> might introduce some bug so I was keeping it simple and build it only
>> when the condition requires it to build it. However I do not see how
>> this will fix the issue that you have seen, or would it? If so how?
>>
> You don't have to pass state between functions, you just have to collect the
> return values from them in the single caller and see if scheduling an update
> is required in the end. Obviously I haven't tested this fix, but the
> reasoning behind it goes like this:
> The usual device destruction goes like: 1. ndo_close() 2. ndo_uninit()... So
> when bond_close() is executed the 3ad workqueue will get stopped first, and
> then the slave_update workqueue will get stopped (note - the order is
> important, since the only place where the slave_update workqueue gets
> scheduled to run is from the 3ad workqueue function). So when we reach
> bond_uninit() there's no way for the 3ad workqueue function to run and we're
> 100% sure that the slave_update workqueue has been canceled as well.
> The reason for this is because the 3ad workqueue function is started in
> bond_open() which obviously can't run without rtnl held, which is why the
> other workqueue functions also are stopped in the same manner.
> So basically, the idea is that you have only 1 place from which you can
> schedule the slave_update array and we can guarantee that it cannot get
> called once the bond device has been closed (bond_close()). You must not do
> a slave array update schedule in bond_3ad_unbind_slave, but that is okay
> because the slave array will get updated by __bond_release_one() anyhow.
>
I try doing this in 3ad_state_machine().
>>> Of course, the alternative would be once again - convert
>>> bond_3ad_state_machine_handler() to RTNL, but that has its own set of
>>> problems.
>>>
>> It's convoluted, let's keep it simple for now :)
>>
>>>>> While testing this I spotted another issue as well - Failed to build
>>>>> slave_arr message has been printed too many times because you print it
>>>>> in
>>>>> 3ad mode when there's no active aggregator
>>>>> (bond_3ad_get_active_agg_info
>>>>> check in bond_update_slave_arr) which leads to re-scheduling which also
>>>>> lead to a deadlock.
>>>>>
>>>> I think this can be corrected with pr_ratelimited() call.
>>>>
>>> IMO it shouldn't print anything if it couldn't rebuild the array due to
>>> missing active aggregator as that's not an error condition. It should
>>> though probably clean out the slave array because transmission shouldn't
>>> be
>>> possible without an active aggregator in 3ad.
>>>
>> Sure missing active aggregator is not an error but free-ing the slave
>> array silently would be bad either. At least we would see something in
>> the messages about "something" went wrong.
>
> Nothing has went wrong, not having an active aggregator is a normal state
> that can happen and in fact could be the state while the bond device is
> configured. It is not advisable to spit out errors in such case as there has
> been no error condition to begin with. Dealing with failed active aggregator
> and notifying the user of it and so on is the job of the 3ad code, not of
> the slave_update mechanism.
> One more thing you really should make sure that we don't xmit when there's
> no active aggregator, it doesn't make sense otherwise and it is actually the
> current behaviour (check bond_3ad_xmit_xor(), first thing it does is try to
> obtain active aggregator and if it fails - it drops the packet, the error
> condition there has been marked as netdev_dbg() so it can be enabled only
> per request of the user and isn't printed normally).
> Moreover it's really a bad idea to reschedule the slave array rebuilding if
> there's no active aggregator because it may be the case we don't have it for
> a long time and it will cause constant rtnl acquire/release cycles.
>
alright. I'll update the code to make sure that active agg not being
present does not trigger error. However malloc failure is still an
error.
>>>
>>>
>>>
>
^ permalink raw reply
* Re: linux-next: build warning after merge of the net tree
From: Stephen Rothwell @ 2014-09-24 0:36 UTC (permalink / raw)
To: Michal Marek
Cc: Randy Dunlap, David Miller, netdev, linux-next, linux-kernel,
linux-kbuild, Linus
In-Reply-To: <20140924072306.799005a3@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 3034 bytes --]
Hi all,
On Wed, 24 Sep 2014 07:23:06 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> On Tue, 23 Sep 2014 16:59:59 +0200 Michal Marek <mmarek@suse.cz> wrote:
> >
> > On 2014-09-18 02:35, Randy Dunlap wrote:
> > > On 09/17/14 17:32, Stephen Rothwell wrote:
> > >> Hi all,
> > >>
> > >> After merging the net tree, today's linux-next build (powerpc
> > >> ppc64_defconfig) produced these warnings:
> > >>
> > >> warning: (PPC_CELL_NATIVE && BLUESTONE && CANYONLANDS && GLACIER && EIGER && 440EPX && 440GRX && 440GX && 460SX && 405EX) selects IBM_EMAC_RGMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >> warning: (PPC_CELL_NATIVE && CANYONLANDS && GLACIER && 440EP && 440EPX && 440GRX && 440GP && 440GX && 460SX && 405GP) selects IBM_EMAC_ZMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >> warning: (PPC_CELL_NATIVE && 440GX && 460EX && 460SX && APM821xx) selects IBM_EMAC_TAH which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >> warning: (PPC_CELL_NATIVE && AKEBONO && 440EPX && 440GRX && 440GX && 440SPe && 460EX && 460SX && APM821xx && 405EX) selects IBM_EMAC_EMAC4 which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >> warning: (PPC_CELL_NATIVE && CANYONLANDS && GLACIER && 440EP && 440EPX && 440GRX && 440GP && 440GX && 460SX && 405GP) selects IBM_EMAC_ZMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >> warning: (PPC_CELL_NATIVE && BLUESTONE && CANYONLANDS && GLACIER && EIGER && 440EPX && 440GRX && 440GX && 460SX && 405EX) selects IBM_EMAC_RGMII which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >> warning: (PPC_CELL_NATIVE && 440GX && 460EX && 460SX && APM821xx) selects IBM_EMAC_TAH which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >> warning: (PPC_CELL_NATIVE && AKEBONO && 440EPX && 440GRX && 440GX && 440SPe && 460EX && 460SX && APM821xx && 405EX) selects IBM_EMAC_EMAC4 which has unmet direct dependencies (NETDEVICES && ETHERNET && NET_VENDOR_IBM)
> > >>
> > >
> > > I have looked into these and don't see why there is a problem.
> > > Any help would be appreciated.
> >
> > This is a side effect of 5d6be6a5 ("scsi_netlink : Make SCSI_NETLINK
> > dependent on NET instead of selecting NET"). Previously, SCSI_FC_ATTRS
> > would select SCSI_NETLINK which would select CONFIG_NET. The above
> > warnings are just a tip of the iceberg, the more serious issue is that
> > ppc64_defconfig is lacking networking support. This is the downside of
> > savedefconfig, because the 'select' implications can disappear over
> > time. Looks like more defconfigs are affected by this:
>
> And since 5d6be6a5 is now in Linus' tree, we need Michal's 5 patches
> (at least) to be sent to Linus ASAP ...
I have put those 5 patches in my fixes tree for today ...
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [PATCH net-next] net : optimize skb_release_data()
From: Eric Dumazet @ 2014-09-24 1:39 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
Cache skb_shinfo(skb) in a variable to avoid computing it multiple
times.
Reorganize the tests to remove one indentation level.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/core/skbuff.c | 43 ++++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 06a8feb10099..d4fdc649112c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -491,32 +491,33 @@ static void skb_free_head(struct sk_buff *skb)
static void skb_release_data(struct sk_buff *skb)
{
- if (!skb->cloned ||
- !atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1,
- &skb_shinfo(skb)->dataref)) {
- if (skb_shinfo(skb)->nr_frags) {
- int i;
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
- skb_frag_unref(skb, i);
- }
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
+ int i;
- /*
- * If skb buf is from userspace, we need to notify the caller
- * the lower device DMA has done;
- */
- if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
- struct ubuf_info *uarg;
+ if (skb->cloned &&
+ atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1,
+ &shinfo->dataref))
+ return;
- uarg = skb_shinfo(skb)->destructor_arg;
- if (uarg->callback)
- uarg->callback(uarg, true);
- }
+ for (i = 0; i < shinfo->nr_frags; i++)
+ __skb_frag_unref(&shinfo->frags[i]);
- if (skb_has_frag_list(skb))
- skb_drop_fraglist(skb);
+ /*
+ * If skb buf is from userspace, we need to notify the caller
+ * the lower device DMA has done;
+ */
+ if (shinfo->tx_flags & SKBTX_DEV_ZEROCOPY) {
+ struct ubuf_info *uarg;
- skb_free_head(skb);
+ uarg = shinfo->destructor_arg;
+ if (uarg->callback)
+ uarg->callback(uarg, true);
}
+
+ if (shinfo->frag_list)
+ kfree_skb_list(shinfo->frag_list);
+
+ skb_free_head(skb);
}
/*
^ permalink raw reply related
* Re: linux-next: build warning after merge of the net tree
From: David Miller @ 2014-09-24 1:58 UTC (permalink / raw)
To: sfr
Cc: mmarek, rdunlap, netdev, linux-next, linux-kernel, linux-kbuild,
torvalds
In-Reply-To: <20140924072306.799005a3@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Wed, 24 Sep 2014 07:23:06 +1000
> Dave, this is a bit slack of you since I reported that problem a week
> ago in the net tree and yet it has not been completely fixed before you
> asked Linus to pull your tree :-(
There were build failures I saw due to some misbalanced select/depends
issues which I fixed in:
commit df568d8e5250bf24e38c69ad4374baf0f8d279ba
Author: David S. Miller <davem@davemloft.net>
Date: Mon Sep 22 13:14:33 2014 -0400
scsi: Use 'depends' with LIBFC instead of 'select'.
which went in yesterday. I thought that would resolve all of your
problems.
Believe me, it is a tragic surprise that several defconfigs absolutely
depended upon this broken usage of select in the scsi layer, to of all
things make CONFIG_NET=y implicit.
I'll do my best to sort this out, but I hope that this short term pain
is worth it in the end.
Thanks for your understanding.
^ permalink raw reply
* [PATCH v1 0/5] Add 10GbE support to APM X-Gene SoC ethernet driver
From: Iyappan Subramanian @ 2014-09-24 3:51 UTC (permalink / raw)
To: davem, netdev, devicetree; +Cc: kchudgar, patches, Iyappan Subramanian
Adding 10GbE support to APM X-Gene SoC ethernet driver.
v1:
* Initial version
---
Iyappan Subramanian (5):
MAINTAINERS: Update APM X-Gene section
Documentation: dts: Update section header for APM X-Gene
dtb: Add 10GbE node to APM X-Gene SoC device tree
drivers: net: xgene: Add 10GbE support
drivers: net: xgene: Add 10GbE ethtool support
.../devicetree/bindings/net/apm-xgene-enet.txt | 4 +-
MAINTAINERS | 1 -
arch/arm64/boot/dts/apm-mustang.dts | 4 +
arch/arm64/boot/dts/apm-storm.dtsi | 24 +++
drivers/net/ethernet/apm/xgene/Makefile | 3 +-
.../net/ethernet/apm/xgene/xgene_enet_ethtool.c | 24 ++-
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 123 ++++++++------
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 31 ++--
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 87 +++++++---
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 24 ++-
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 187 +++++++++++++++++++++
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | 64 +++++++
12 files changed, 473 insertions(+), 103 deletions(-)
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
--
1.9.1
^ permalink raw reply
* [PATCH v1 1/5] MAINTAINERS: Update APM X-Gene section
From: Iyappan Subramanian @ 2014-09-24 3:51 UTC (permalink / raw)
To: davem, netdev, devicetree; +Cc: kchudgar, patches, Iyappan Subramanian
In-Reply-To: <1411530688-2939-1-git-send-email-isubramanian@apm.com>
Update APM X-Gene ethernet driver maintainers list.
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
---
MAINTAINERS | 1 -
1 file changed, 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index b4e23ac..74d202a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -722,7 +722,6 @@ F: net/appletalk/
APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
M: Iyappan Subramanian <isubramanian@apm.com>
M: Keyur Chudgar <kchudgar@apm.com>
-M: Ravi Patel <rapatel@apm.com>
S: Supported
F: drivers/net/ethernet/apm/xgene/
F: Documentation/devicetree/bindings/net/apm-xgene-enet.txt
--
1.9.1
^ permalink raw reply related
* [PATCH v1 2/5] Documentation: dts: Update section header for APM X-Gene
From: Iyappan Subramanian @ 2014-09-24 3:51 UTC (permalink / raw)
To: davem, netdev, devicetree; +Cc: kchudgar, patches, Iyappan Subramanian
In-Reply-To: <1411530688-2939-1-git-send-email-isubramanian@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
---
Documentation/devicetree/bindings/net/apm-xgene-enet.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
index ebcad25..60a7857 100644
--- a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
+++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt
@@ -3,7 +3,7 @@ APM X-Gene SoC Ethernet nodes
Ethernet nodes are defined to describe on-chip ethernet interfaces in
APM X-Gene SoC.
-Required properties:
+Required properties for all the ethernet interfaces:
- compatible: Should be "apm,xgene-enet"
- reg: Address and length of the register set for the device. It contains the
information of registers in the same order as described by reg-names
@@ -15,6 +15,8 @@ Required properties:
- clocks: Reference to the clock entry.
- local-mac-address: MAC address assigned to this device
- phy-connection-type: Interface type between ethernet device and PHY device
+
+Required properties for ethernet interfaces that has external PHY:
- phy-handle: Reference to a PHY node connected to this device
- mdio: Device tree subnode with the following required properties:
--
1.9.1
^ permalink raw reply related
* [PATCH v1 3/5] dtb: Add 10GbE node to APM X-Gene SoC device tree
From: Iyappan Subramanian @ 2014-09-24 3:51 UTC (permalink / raw)
To: davem, netdev, devicetree; +Cc: kchudgar, patches, Iyappan Subramanian
In-Reply-To: <1411530688-2939-1-git-send-email-isubramanian@apm.com>
Added 10GbE interface and clock nodes.
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
---
arch/arm64/boot/dts/apm-mustang.dts | 4 ++++
arch/arm64/boot/dts/apm-storm.dtsi | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts
index b2f5622..2ae782b 100644
--- a/arch/arm64/boot/dts/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm-mustang.dts
@@ -32,3 +32,7 @@
&menet {
status = "ok";
};
+
+&xgenet {
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index c0aceef..ae814ef 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -176,6 +176,16 @@
clock-output-names = "menetclk";
};
+ xge0clk: xge0clk@1f61c000 {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clocks = <&socplldiv2 0>;
+ reg = <0x0 0x1f61c000 0x0 0x1000>;
+ reg-names = "csr-reg";
+ csr-mask = <0x3>;
+ clock-output-names = "xge0clk";
+ };
+
sataphy1clk: sataphy1clk@1f21c000 {
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
@@ -421,5 +431,19 @@
};
};
+
+ xgenet: ethernet@1f610000 {
+ compatible = "apm,xgene-enet";
+ status = "disabled";
+ reg = <0x0 0x1f610000 0x0 0xd100>,
+ <0x0 0x1f600000 0x0 0X400>,
+ <0x0 0x18000000 0x0 0X200>;
+ reg-names = "enet_csr", "ring_csr", "ring_cmd";
+ interrupts = <0x0 0x60 0x4>;
+ dma-coherent;
+ clocks = <&xge0clk 0>;
+ local-mac-address = [00 01 73 00 00 04];
+ phy-connection-type = "xgmii";
+ };
};
};
--
1.9.1
^ permalink raw reply related
* [PATCH v1 4/5] drivers: net: xgene: Add 10GbE support
From: Iyappan Subramanian @ 2014-09-24 3:51 UTC (permalink / raw)
To: davem, netdev, devicetree; +Cc: kchudgar, patches, Iyappan Subramanian
In-Reply-To: <1411530688-2939-1-git-send-email-isubramanian@apm.com>
Adding 10GbE support to APM X-Gene SoC ethernet driver.
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
---
drivers/net/ethernet/apm/xgene/Makefile | 3 +-
drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 123 +++++++-------
drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 31 ++--
drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 87 +++++++---
drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 24 ++-
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 187 ++++++++++++++++++++++
drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h | 64 ++++++++
7 files changed, 422 insertions(+), 97 deletions(-)
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
create mode 100644 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
diff --git a/drivers/net/ethernet/apm/xgene/Makefile b/drivers/net/ethernet/apm/xgene/Makefile
index c643e8a..589b352 100644
--- a/drivers/net/ethernet/apm/xgene/Makefile
+++ b/drivers/net/ethernet/apm/xgene/Makefile
@@ -2,5 +2,6 @@
# Makefile for APM X-Gene Ethernet Driver.
#
-xgene-enet-objs := xgene_enet_hw.o xgene_enet_main.o xgene_enet_ethtool.o
+xgene-enet-objs := xgene_enet_hw.o xgene_enet_xgmac.o \
+ xgene_enet_main.o xgene_enet_ethtool.o
obj-$(CONFIG_NET_XGENE) += xgene-enet.o
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index 812d8d6..2795367 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -217,8 +217,7 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
}
}
-static void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata,
- u32 offset, u32 val)
+void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata, u32 offset, u32 val)
{
void __iomem *addr = pdata->eth_csr_addr + offset;
@@ -244,7 +243,7 @@ static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *pdata,
static void xgene_enet_wr_mcx_csr(struct xgene_enet_pdata *pdata,
u32 offset, u32 val)
{
- void __iomem *addr = pdata->mcx_mac_csr_addr + offset;
+ void __iomem *addr = pdata->mac_csr_addr + offset;
iowrite32(val, addr);
}
@@ -272,23 +271,21 @@ static bool xgene_enet_wr_indirect(void __iomem *addr, void __iomem *wr,
return true;
}
-static void xgene_enet_wr_mcx_mac(struct xgene_enet_pdata *pdata,
- u32 wr_addr, u32 wr_data)
+void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata, u32 wr_addr, u32 wr_data)
{
void __iomem *addr, *wr, *cmd, *cmd_done;
- addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
- wr = pdata->mcx_mac_addr + MAC_WRITE_REG_OFFSET;
- cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
- cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+ addr = pdata->mac_addr + MAC_ADDR_REG_OFFSET;
+ wr = pdata->mac_addr + MAC_WRITE_REG_OFFSET;
+ cmd = pdata->mac_addr + MAC_COMMAND_REG_OFFSET;
+ cmd_done = pdata->mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
if (!xgene_enet_wr_indirect(addr, wr, cmd, cmd_done, wr_addr, wr_data))
netdev_err(pdata->ndev, "MCX mac write failed, addr: %04x\n",
wr_addr);
}
-static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,
- u32 offset, u32 *val)
+void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata, u32 offset, u32 *val)
{
void __iomem *addr = pdata->eth_csr_addr + offset;
@@ -306,7 +303,7 @@ static void xgene_enet_rd_diag_csr(struct xgene_enet_pdata *pdata,
static void xgene_enet_rd_mcx_csr(struct xgene_enet_pdata *pdata,
u32 offset, u32 *val)
{
- void __iomem *addr = pdata->mcx_mac_csr_addr + offset;
+ void __iomem *addr = pdata->mac_csr_addr + offset;
*val = ioread32(addr);
}
@@ -334,15 +331,15 @@ static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd,
return true;
}
-static void xgene_enet_rd_mcx_mac(struct xgene_enet_pdata *pdata,
- u32 rd_addr, u32 *rd_data)
+void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
+ u32 rd_addr, u32 *rd_data)
{
void __iomem *addr, *rd, *cmd, *cmd_done;
- addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET;
- rd = pdata->mcx_mac_addr + MAC_READ_REG_OFFSET;
- cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET;
- cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
+ addr = pdata->mac_addr + MAC_ADDR_REG_OFFSET;
+ rd = pdata->mac_addr + MAC_READ_REG_OFFSET;
+ cmd = pdata->mac_addr + MAC_COMMAND_REG_OFFSET;
+ cmd_done = pdata->mac_addr + MAC_COMMAND_DONE_REG_OFFSET;
if (!xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data))
netdev_err(pdata->ndev, "MCX mac read failed, addr: %04x\n",
@@ -358,13 +355,13 @@ static int xgene_mii_phy_write(struct xgene_enet_pdata *pdata, int phy_id,
PHY_ADDR_SET(&addr, phy_id);
REG_ADDR_SET(&addr, reg);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
+ xgene_enet_wr_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
PHY_CONTROL_SET(&wr_data, data);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONTROL_ADDR, wr_data);
+ xgene_enet_wr_mac(pdata, MII_MGMT_CONTROL_ADDR, wr_data);
do {
usleep_range(5, 10);
- xgene_enet_rd_mcx_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
+ xgene_enet_rd_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
} while ((done & BUSY_MASK) && wait--);
if (done & BUSY_MASK) {
@@ -384,11 +381,11 @@ static int xgene_mii_phy_read(struct xgene_enet_pdata *pdata,
PHY_ADDR_SET(&addr, phy_id);
REG_ADDR_SET(&addr, reg);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_COMMAND_ADDR, READ_CYCLE_MASK);
+ xgene_enet_wr_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr);
+ xgene_enet_wr_mac(pdata, MII_MGMT_COMMAND_ADDR, READ_CYCLE_MASK);
do {
usleep_range(5, 10);
- xgene_enet_rd_mcx_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
+ xgene_enet_rd_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done);
} while ((done & BUSY_MASK) && wait--);
if (done & BUSY_MASK) {
@@ -396,8 +393,8 @@ static int xgene_mii_phy_read(struct xgene_enet_pdata *pdata,
return -EBUSY;
}
- xgene_enet_rd_mcx_mac(pdata, MII_MGMT_STATUS_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_COMMAND_ADDR, 0);
+ xgene_enet_rd_mac(pdata, MII_MGMT_STATUS_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MII_MGMT_COMMAND_ADDR, 0);
return data;
}
@@ -412,11 +409,11 @@ void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16);
addr1 |= pdata->phy_addr & 0xFFFF;
- xgene_enet_wr_mcx_mac(pdata, STATION_ADDR0_ADDR, addr0);
- xgene_enet_wr_mcx_mac(pdata, STATION_ADDR1_ADDR, addr1);
+ xgene_enet_wr_mac(pdata, STATION_ADDR0_ADDR, addr0);
+ xgene_enet_wr_mac(pdata, STATION_ADDR1_ADDR, addr1);
}
-static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
+int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
{
struct net_device *ndev = pdata->ndev;
u32 data;
@@ -438,11 +435,11 @@ static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata)
void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
{
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, 0);
}
-void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
+void xgene_gmac_init(struct xgene_enet_pdata *pdata)
{
u32 value, mc2;
u32 intf_ctl, rgmii;
@@ -452,11 +449,11 @@ void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, &icm0);
xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, &icm2);
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_2_ADDR, &mc2);
- xgene_enet_rd_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, &intf_ctl);
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_2_ADDR, &mc2);
+ xgene_enet_rd_mac(pdata, INTERFACE_CONTROL_ADDR, &intf_ctl);
xgene_enet_rd_csr(pdata, RGMII_REG_0_ADDR, &rgmii);
- switch (speed) {
+ switch (pdata->phy_speed) {
case SPEED_10:
ENET_INTERFACE_MODE2_SET(&mc2, 1);
CFG_MACMODE_SET(&icm0, 0);
@@ -481,15 +478,15 @@ void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
}
mc2 |= FULL_DUPLEX2;
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
- xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
+ xgene_enet_wr_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
xgene_gmac_set_mac_addr(pdata);
/* Adjust MDC clock frequency */
- xgene_enet_rd_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, &value);
+ xgene_enet_rd_mac(pdata, MII_MGMT_CONFIG_ADDR, &value);
MGMT_CLOCK_SEL_SET(&value, 7);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, value);
+ xgene_enet_wr_mac(pdata, MII_MGMT_CONFIG_ADDR, value);
/* Enable drop if bufpool not available */
xgene_enet_rd_csr(pdata, RSIF_CONFIG_REG_ADDR, &value);
@@ -515,10 +512,8 @@ void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed)
xgene_enet_wr_csr(pdata, CFG_BYPASS_ADDR, RESUME_TX);
}
-static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata)
+void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata, u32 val)
{
- u32 val = 0xffffffff;
-
xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQASSOC_ADDR, val);
xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPQASSOC_ADDR, val);
xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEWQASSOC_ADDR, val);
@@ -548,32 +543,32 @@ void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN);
}
void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN);
}
void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN);
}
void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata)
{
u32 data;
- xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data);
- xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
+ xgene_enet_rd_mac(pdata, MAC_CONFIG_1_ADDR, &data);
+ xgene_enet_wr_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN);
}
void xgene_enet_reset(struct xgene_enet_pdata *pdata)
@@ -584,16 +579,16 @@ void xgene_enet_reset(struct xgene_enet_pdata *pdata)
clk_disable_unprepare(pdata->clk);
clk_prepare_enable(pdata->clk);
xgene_enet_ecc_init(pdata);
- xgene_enet_config_ring_if_assoc(pdata);
+ xgene_enet_config_ring_if_assoc(pdata, 0xffffffff);
/* Enable auto-incr for scanning */
- xgene_enet_rd_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, &val);
+ xgene_enet_rd_mac(pdata, MII_MGMT_CONFIG_ADDR, &val);
val |= SCAN_AUTO_INCR;
MGMT_CLOCK_SEL_SET(&val, 1);
- xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val);
+ xgene_enet_wr_mac(pdata, MII_MGMT_CONFIG_ADDR, val);
}
-void xgene_gport_shutdown(struct xgene_enet_pdata *pdata)
+void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
{
clk_disable_unprepare(pdata->clk);
}
@@ -627,10 +622,10 @@ static void xgene_enet_adjust_link(struct net_device *ndev)
if (phydev->link) {
if (pdata->phy_speed != phydev->speed) {
- xgene_gmac_init(pdata, phydev->speed);
+ pdata->phy_speed = phydev->speed;
+ xgene_gmac_init(pdata);
xgene_gmac_rx_enable(pdata);
xgene_gmac_tx_enable(pdata);
- pdata->phy_speed = phydev->speed;
phy_print_status(phydev);
}
} else {
@@ -726,3 +721,19 @@ void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata)
mdiobus_free(pdata->mdio_bus);
pdata->mdio_bus = NULL;
}
+
+struct xgene_mac_ops xgene_gmac_ops = {
+ .init = xgene_gmac_init,
+ .reset = xgene_gmac_reset,
+ .rx_enable = xgene_gmac_rx_enable,
+ .tx_enable = xgene_gmac_tx_enable,
+ .rx_disable = xgene_gmac_rx_disable,
+ .tx_disable = xgene_gmac_tx_disable,
+ .set_mac_addr = xgene_gmac_set_mac_addr,
+};
+
+struct xgene_port_ops xgene_gport_ops = {
+ .reset = xgene_enet_reset,
+ .cle_bypass = xgene_enet_cle_bypass,
+ .shutdown = xgene_enet_shutdown,
+};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 371e7a5..1187de0 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -42,6 +42,11 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
return (val & GENMASK(end, start)) >> start;
}
+enum xgene_enet_ring_manager {
+ RM0,
+ RM3 = 3
+};
+
#define CSR_RING_ID 0x0008
#define OVERWRITE BIT(31)
#define IS_BUFFER_POOL BIT(20)
@@ -52,7 +57,6 @@ static inline u32 xgene_get_bits(u32 val, u32 start, u32 end)
#define CSR_RING_WR_BASE 0x0070
#define NUM_RING_CONFIG 5
#define BUFPOOL_MODE 3
-#define RM3 3
#define INC_DEC_CMD_ADDR 0x002c
#define UDP_HDR_SIZE 2
#define BUF_LEN_CODE_2K 0x5000
@@ -318,20 +322,21 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
struct xgene_enet_pdata *pdata,
enum xgene_enet_err_code status);
-void xgene_enet_reset(struct xgene_enet_pdata *priv);
-void xgene_gmac_reset(struct xgene_enet_pdata *priv);
-void xgene_gmac_init(struct xgene_enet_pdata *priv, int speed);
-void xgene_gmac_tx_enable(struct xgene_enet_pdata *priv);
-void xgene_gmac_rx_enable(struct xgene_enet_pdata *priv);
-void xgene_gmac_tx_disable(struct xgene_enet_pdata *priv);
-void xgene_gmac_rx_disable(struct xgene_enet_pdata *priv);
-void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata);
-void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata,
- u32 dst_ring_num, u16 bufpool_id);
-void xgene_gport_shutdown(struct xgene_enet_pdata *priv);
-void xgene_gmac_get_tx_stats(struct xgene_enet_pdata *pdata);
+void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata,
+ u32 offset, u32 val);
+void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata,
+ u32 offset, u32 *val);
+void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata,
+ u32 wr_addr, u32 wr_data);
+void xgene_enet_rd_mac(struct xgene_enet_pdata *pdata,
+ u32 rd_addr, u32 *rd_data);
+int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata);
+void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata, u32 val);
int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata);
void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata);
+extern struct xgene_mac_ops xgene_gmac_ops;
+extern struct xgene_port_ops xgene_gport_ops;
+
#endif /* __XGENE_ENET_HW_H__ */
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index e4222af..090bbcd 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -21,6 +21,7 @@
#include "xgene_enet_main.h"
#include "xgene_enet_hw.h"
+#include "xgene_enet_xgmac.h"
static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
{
@@ -390,7 +391,7 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
}
}
- return budget;
+ return count;
}
static int xgene_enet_napi(struct napi_struct *napi, const int budget)
@@ -413,7 +414,7 @@ static void xgene_enet_timeout(struct net_device *ndev)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
- xgene_gmac_reset(pdata);
+ pdata->mac_ops->reset(pdata);
}
static int xgene_enet_register_irq(struct net_device *ndev)
@@ -445,18 +446,21 @@ static void xgene_enet_free_irq(struct net_device *ndev)
static int xgene_enet_open(struct net_device *ndev)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
+ struct xgene_mac_ops *mac_ops = pdata->mac_ops;
int ret;
- xgene_gmac_tx_enable(pdata);
- xgene_gmac_rx_enable(pdata);
+ mac_ops->tx_enable(pdata);
+ mac_ops->rx_enable(pdata);
ret = xgene_enet_register_irq(ndev);
if (ret)
return ret;
napi_enable(&pdata->rx_ring->napi);
- if (pdata->phy_dev)
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
phy_start(pdata->phy_dev);
+ else
+ schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF);
netif_start_queue(ndev);
@@ -466,18 +470,21 @@ static int xgene_enet_open(struct net_device *ndev)
static int xgene_enet_close(struct net_device *ndev)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
+ struct xgene_mac_ops *mac_ops = pdata->mac_ops;
netif_stop_queue(ndev);
- if (pdata->phy_dev)
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
phy_stop(pdata->phy_dev);
+ else
+ cancel_delayed_work_sync(&pdata->link_work);
napi_disable(&pdata->rx_ring->napi);
xgene_enet_free_irq(ndev);
xgene_enet_process_ring(pdata->rx_ring, -1);
- xgene_gmac_tx_disable(pdata);
- xgene_gmac_rx_disable(pdata);
+ mac_ops->tx_disable(pdata);
+ mac_ops->rx_disable(pdata);
return 0;
}
@@ -613,7 +620,6 @@ static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring(
ring->cmd_base = pdata->ring_cmd_addr + (ring->num << 6);
ring->cmd = ring->cmd_base + INC_DEC_CMD_ADDR;
- pdata->rm = RM3;
ring = xgene_enet_setup_ring(ring);
netdev_dbg(ndev, "ring info: num=%d size=%d id=%d slots=%d\n",
ring->num, ring->size, ring->id, ring->slots);
@@ -724,7 +730,7 @@ static int xgene_enet_set_mac_address(struct net_device *ndev, void *addr)
ret = eth_mac_addr(ndev, addr);
if (ret)
return ret;
- xgene_gmac_set_mac_addr(pdata);
+ pdata->mac_ops->set_mac_addr(pdata);
return ret;
}
@@ -803,8 +809,13 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
pdata->phy_mode = of_get_phy_mode(pdev->dev.of_node);
if (pdata->phy_mode < 0) {
- dev_err(dev, "Incorrect phy-connection-type in DTS\n");
- return -EINVAL;
+ dev_err(dev, "Unable to get phy-connection-type\n");
+ return pdata->phy_mode;
+ }
+ if (pdata->phy_mode != PHY_INTERFACE_MODE_RGMII &&
+ pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
+ dev_err(dev, "Incorrect phy-connection-type specified\n");
+ return -ENODEV;
}
pdata->clk = devm_clk_get(&pdev->dev, NULL);
@@ -819,12 +830,19 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET;
pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET;
pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET;
- pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET;
- pdata->mcx_stats_addr = base_addr + BLOCK_ETH_STATS_OFFSET;
- pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET;
pdata->rx_buff_cnt = NUM_PKT_BUF;
- return ret;
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
+ pdata->mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET;
+ pdata->mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET;
+ pdata->rm = RM3;
+ } else {
+ pdata->mac_addr = base_addr + BLOCK_AXG_MAC_OFFSET;
+ pdata->mac_csr_addr = base_addr + BLOCK_AXG_MAC_CSR_OFFSET;
+ pdata->rm = RM0;
+ }
+
+ return 0;
}
static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
@@ -834,8 +852,7 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
u16 dst_ring_num;
int ret;
- xgene_gmac_tx_disable(pdata);
- xgene_gmac_rx_disable(pdata);
+ pdata->port_ops->reset(pdata);
ret = xgene_enet_create_desc_rings(ndev);
if (ret) {
@@ -853,11 +870,26 @@ static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata)
}
dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring);
- xgene_enet_cle_bypass(pdata, dst_ring_num, buf_pool->id);
+ pdata->port_ops->cle_bypass(pdata, dst_ring_num, buf_pool->id);
+ pdata->mac_ops->init(pdata);
return ret;
}
+static void xgene_enet_setup_ops(struct xgene_enet_pdata *pdata)
+{
+ switch (pdata->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ pdata->mac_ops = &xgene_gmac_ops;
+ pdata->port_ops = &xgene_gport_ops;
+ break;
+ default:
+ pdata->mac_ops = &xgene_xgmac_ops;
+ pdata->port_ops = &xgene_xgport_ops;
+ break;
+ }
+}
+
static int xgene_enet_probe(struct platform_device *pdev)
{
struct net_device *ndev;
@@ -886,8 +918,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
if (ret)
goto err;
- xgene_enet_reset(pdata);
- xgene_gmac_init(pdata, SPEED_1000);
+ xgene_enet_setup_ops(pdata);
ret = register_netdev(ndev);
if (ret) {
@@ -907,7 +938,10 @@ static int xgene_enet_probe(struct platform_device *pdev)
napi = &pdata->rx_ring->napi;
netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT);
- ret = xgene_enet_mdio_config(pdata);
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
+ ret = xgene_enet_mdio_config(pdata);
+ else
+ INIT_DELAYED_WORK(&pdata->link_work, xgene_enet_link_state);
return ret;
err:
@@ -918,19 +952,21 @@ err:
static int xgene_enet_remove(struct platform_device *pdev)
{
struct xgene_enet_pdata *pdata;
+ struct xgene_mac_ops *mac_ops;
struct net_device *ndev;
pdata = platform_get_drvdata(pdev);
+ mac_ops = pdata->mac_ops;
ndev = pdata->ndev;
- xgene_gmac_rx_disable(pdata);
- xgene_gmac_tx_disable(pdata);
+ mac_ops->rx_disable(pdata);
+ mac_ops->tx_disable(pdata);
netif_napi_del(&pdata->rx_ring->napi);
xgene_enet_mdio_remove(pdata);
xgene_enet_delete_desc_rings(pdata);
unregister_netdev(ndev);
- xgene_gport_shutdown(pdata);
+ pdata->port_ops->shutdown(pdata);
free_netdev(ndev);
return 0;
@@ -956,5 +992,6 @@ module_platform_driver(xgene_enet_driver);
MODULE_DESCRIPTION("APM X-Gene SoC Ethernet driver");
MODULE_VERSION(XGENE_DRV_VERSION);
+MODULE_AUTHOR("Iyappan Subramanian <isubramanian@apm.com>");
MODULE_AUTHOR("Keyur Chudgar <kchudgar@apm.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 0815866..567ca6e 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -68,6 +68,23 @@ struct xgene_enet_desc_ring {
};
};
+struct xgene_mac_ops {
+ void (*init)(struct xgene_enet_pdata *pdata);
+ void (*reset)(struct xgene_enet_pdata *pdata);
+ void (*tx_enable)(struct xgene_enet_pdata *pdata);
+ void (*rx_enable)(struct xgene_enet_pdata *pdata);
+ void (*tx_disable)(struct xgene_enet_pdata *pdata);
+ void (*rx_disable)(struct xgene_enet_pdata *pdata);
+ void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
+};
+
+struct xgene_port_ops {
+ void (*reset)(struct xgene_enet_pdata *pdata);
+ void (*cle_bypass)(struct xgene_enet_pdata *pdata,
+ u32 dst_ring_num, u16 bufpool_id);
+ void (*shutdown)(struct xgene_enet_pdata *pdata);
+};
+
/* ethernet private data */
struct xgene_enet_pdata {
struct net_device *ndev;
@@ -87,9 +104,9 @@ struct xgene_enet_pdata {
void __iomem *eth_csr_addr;
void __iomem *eth_ring_if_addr;
void __iomem *eth_diag_csr_addr;
- void __iomem *mcx_mac_addr;
+ void __iomem *mac_addr;
void __iomem *mcx_stats_addr;
- void __iomem *mcx_mac_csr_addr;
+ void __iomem *mac_csr_addr;
void __iomem *base_addr;
void __iomem *ring_csr_addr;
void __iomem *ring_cmd_addr;
@@ -98,6 +115,9 @@ struct xgene_enet_pdata {
u32 speed;
u16 rm;
struct rtnl_link_stats64 stats;
+ struct xgene_mac_ops *mac_ops;
+ struct xgene_port_ops *port_ops;
+ struct delayed_work link_work;
};
/* Set the specified value into a bit-field defined by its starting position
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
new file mode 100644
index 0000000..219bb7e
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -0,0 +1,187 @@
+/* Applied Micro X-Gene SoC Ethernet Driver
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Authors: Iyappan Subramanian <isubramanian@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "xgene_enet_main.h"
+#include "xgene_enet_hw.h"
+#include "xgene_enet_xgmac.h"
+
+static void xgene_xgmac_reset(struct xgene_enet_pdata *pdata)
+{
+ xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_0, HSTMACRST);
+ xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_0, 0);
+}
+
+static void xgene_xgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
+{
+ u32 addr0, addr1;
+ u8 *dev_addr = pdata->ndev->dev_addr;
+
+ addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
+ (dev_addr[1] << 8) | dev_addr[0];
+ addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16);
+
+ xgene_enet_wr_mac(pdata, HSTMACADR_LSW_ADDR, addr0);
+ xgene_enet_wr_mac(pdata, HSTMACADR_MSW_ADDR, addr1);
+}
+
+static u32 xgene_enet_link_status(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_csr(pdata, XG_LINK_STATUS_ADDR, &data);
+
+ return data;
+}
+
+static void xgene_xgmac_init(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_xgmac_reset(pdata);
+
+ xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+ data |= HSTPPEN;
+ data &= ~HSTLENCHK;
+ xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
+
+ xgene_enet_wr_mac(pdata, HSTMAXFRAME_LENGTH_ADDR, 0x06000600);
+ xgene_xgmac_set_mac_addr(pdata);
+
+ xgene_enet_rd_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, &data);
+ data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
+ xgene_enet_wr_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, data);
+
+ xgene_enet_wr_csr(pdata, XG_CFG_BYPASS_ADDR, RESUME_TX);
+ xgene_enet_wr_csr(pdata, XGENET_RX_DV_GATE_REG_0_ADDR, 0);
+ xgene_enet_rd_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, &data);
+ data |= BIT(12);
+ xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_ADDR, data);
+ xgene_enet_wr_csr(pdata, XG_ENET_SPARE_CFG_REG_1_ADDR, 0x82);
+}
+
+static void xgene_xgmac_rx_enable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+ xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data | HSTRFEN);
+}
+
+static void xgene_xgmac_tx_enable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+ xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data | HSTTFEN);
+}
+
+static void xgene_xgmac_rx_disable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+ xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTRFEN);
+}
+
+static void xgene_xgmac_tx_disable(struct xgene_enet_pdata *pdata)
+{
+ u32 data;
+
+ xgene_enet_rd_mac(pdata, AXGMAC_CONFIG_1, &data);
+ xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data & ~HSTTFEN);
+}
+
+static void xgene_enet_reset(struct xgene_enet_pdata *pdata)
+{
+ clk_prepare_enable(pdata->clk);
+ clk_disable_unprepare(pdata->clk);
+ clk_prepare_enable(pdata->clk);
+
+ xgene_enet_ecc_init(pdata);
+ xgene_enet_config_ring_if_assoc(pdata, 0);
+}
+
+static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata,
+ u32 dst_ring_num, u16 bufpool_id)
+{
+ u32 cb, fpsel;
+
+ xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG0_ADDR, &cb);
+ cb |= CFG_CLE_BYPASS_EN0;
+ CFG_CLE_IP_PROTOCOL0_SET(&cb, 3);
+ xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG0_ADDR, cb);
+
+ fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20;
+ xgene_enet_rd_csr(pdata, XCLE_BYPASS_REG1_ADDR, &cb);
+ CFG_CLE_DSTQID0_SET(&cb, dst_ring_num);
+ CFG_CLE_FPSEL0_SET(&cb, fpsel);
+ xgene_enet_wr_csr(pdata, XCLE_BYPASS_REG1_ADDR, cb);
+}
+
+static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata)
+{
+ clk_disable_unprepare(pdata->clk);
+}
+
+void xgene_enet_link_state(struct work_struct *work)
+{
+ struct xgene_enet_pdata *pdata = container_of(to_delayed_work(work),
+ struct xgene_enet_pdata, link_work);
+ struct net_device *ndev = pdata->ndev;
+ u32 link_status, poll_interval;
+
+ link_status = xgene_enet_link_status(pdata);
+ if (link_status) {
+ if (!netif_carrier_ok(ndev)) {
+ netif_carrier_on(ndev);
+ xgene_xgmac_init(pdata);
+ xgene_xgmac_rx_enable(pdata);
+ xgene_xgmac_tx_enable(pdata);
+ netdev_info(ndev, "Link is Up - 10Gbps\n");
+ }
+ poll_interval = PHY_POLL_LINK_ON;
+ } else {
+ if (netif_carrier_ok(ndev)) {
+ xgene_xgmac_rx_disable(pdata);
+ xgene_xgmac_tx_disable(pdata);
+ netif_carrier_off(ndev);
+ netdev_info(ndev, "Link is Down\n");
+ }
+ poll_interval = PHY_POLL_LINK_OFF;
+ }
+
+ schedule_delayed_work(&pdata->link_work, poll_interval);
+}
+
+struct xgene_mac_ops xgene_xgmac_ops = {
+ .init = xgene_xgmac_init,
+ .reset = xgene_xgmac_reset,
+ .rx_enable = xgene_xgmac_rx_enable,
+ .tx_enable = xgene_xgmac_tx_enable,
+ .rx_disable = xgene_xgmac_rx_disable,
+ .tx_disable = xgene_xgmac_tx_disable,
+ .set_mac_addr = xgene_xgmac_set_mac_addr,
+};
+
+struct xgene_port_ops xgene_xgport_ops = {
+ .reset = xgene_enet_reset,
+ .cle_bypass = xgene_enet_xgcle_bypass,
+ .shutdown = xgene_enet_shutdown,
+};
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
new file mode 100644
index 0000000..b6cc0fe
--- /dev/null
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -0,0 +1,64 @@
+/* Applied Micro X-Gene SoC Ethernet Driver
+ *
+ * Copyright (c) 2014, Applied Micro Circuits Corporation
+ * Authors: Iyappan Subramanian <isubramanian@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __XGENE_ENET_XGMAC_H__
+#define __XGENE_ENET_XGMAC_H__
+
+#define BLOCK_AXG_MAC_OFFSET 0x0800
+#define BLOCK_AXG_MAC_CSR_OFFSET 0x2000
+
+#define AXGMAC_CONFIG_0 0x0000
+#define AXGMAC_CONFIG_1 0x0004
+#define HSTMACRST BIT(31)
+#define HSTTCTLEN BIT(31)
+#define HSTTFEN BIT(30)
+#define HSTRCTLEN BIT(29)
+#define HSTRFEN BIT(28)
+#define HSTPPEN BIT(7)
+#define HSTDRPLT64 BIT(5)
+#define HSTLENCHK BIT(3)
+#define HSTMACADR_LSW_ADDR 0x0010
+#define HSTMACADR_MSW_ADDR 0x0014
+#define HSTMAXFRAME_LENGTH_ADDR 0x0020
+
+#define XGENET_SRST_ADDR 0x0000
+#define XGENET_CLKEN_ADDR 0x0008
+#define CSR_CLK BIT(0)
+#define XGENET_CLK BIT(1)
+#define CSR_RST BIT(0)
+#define XGENET_RST BIT(1)
+
+#define XG_RSIF_CONFIG_REG_ADDR 0x00a0
+#define XCLE_BYPASS_REG0_ADDR 0x0160
+#define XCLE_BYPASS_REG1_ADDR 0x0164
+#define XG_CFG_BYPASS_ADDR 0x0204
+#define XG_LINK_STATUS_ADDR 0x0228
+#define XG_ENET_SPARE_CFG_REG_ADDR 0x040c
+#define XG_ENET_SPARE_CFG_REG_1_ADDR 0x0410
+#define XGENET_RX_DV_GATE_REG_0_ADDR 0x0804
+
+#define PHY_POLL_LINK_ON (10 * HZ)
+#define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5)
+
+void xgene_enet_link_state(struct work_struct *work);
+extern struct xgene_mac_ops xgene_xgmac_ops;
+extern struct xgene_port_ops xgene_xgport_ops;
+
+#endif /* __XGENE_ENET_XGMAC_H__ */
--
1.9.1
^ permalink raw reply related
* [PATCH v1 5/5] drivers: net: xgene: Add 10GbE ethtool support
From: Iyappan Subramanian @ 2014-09-24 3:51 UTC (permalink / raw)
To: davem, netdev, devicetree; +Cc: kchudgar, patches, Iyappan Subramanian
In-Reply-To: <1411530688-2939-1-git-send-email-isubramanian@apm.com>
Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
---
.../net/ethernet/apm/xgene/xgene_enet_ethtool.c | 24 ++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
index 63f2aa5..88849a0 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
@@ -58,11 +58,24 @@ static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
{
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct phy_device *phydev = pdata->phy_dev;
+ int ret = 0;
+
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
+ if (phydev == NULL)
+ return -ENODEV;
+
+ ret = phy_ethtool_gset(phydev, cmd);
+ } else {
+ cmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE;
+ cmd->advertising = cmd->supported;
+ ethtool_cmd_speed_set(cmd, SPEED_10000);
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_FIBRE;
+ cmd->transceiver = XCVR_EXTERNAL;
+ cmd->autoneg = AUTONEG_DISABLE;
+ }
- if (phydev == NULL)
- return -ENODEV;
-
- return phy_ethtool_gset(phydev, cmd);
+ return ret;
}
static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
@@ -70,6 +83,9 @@ static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
struct xgene_enet_pdata *pdata = netdev_priv(ndev);
struct phy_device *phydev = pdata->phy_dev;
+ if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII)
+ return -EINVAL;
+
if (phydev == NULL)
return -ENODEV;
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 1/5] rhashtable: Remove gfp_flags from insert and remove functions
From: Eric W. Biederman @ 2014-09-24 4:11 UTC (permalink / raw)
To: Thomas Graf
Cc: Eric Dumazet, davem, paulmck, john.r.fastabend, kaber, netdev,
linux-kernel
In-Reply-To: <20140915124937.GB21541@casper.infradead.org>
Thomas Graf <tgraf@suug.ch> writes:
> On 09/15/14 at 05:35am, Eric Dumazet wrote:
>> On Mon, 2014-09-15 at 14:18 +0200, Thomas Graf wrote:
>> > As the expansion/shrinking is moved to a worker thread, no allocations
>> > will be performed anymore.
>> >
>>
>> You meant : no GFP_ATOMIC allocations ?
>>
>> I would rephrase using something like :
>>
>> Because hash resizes are potentially time consuming, they'll be
>> performed in process context where GFP_KERNEL allocations are preferred.
>
> I meant to say no allocations in insert/remove anymore but your wording
> is even clearer. I'll update it.
>
>> > - tbl = kzalloc(size, flags);
>> > + tbl = kzalloc(size, GFP_KERNEL);
>>
>> Add __GFP_NOWARN, as you fallback to vzalloc ?
>
> Good point.
It needs to be both __GFP_NOWARN and __GFP_NORETRY.
Otherwise the system will kick in the OOM killer before it falls back to
vzalloc. Which I can't imagine anyone wanting.
Look at the history of alloc_fdmem in fs/file.c for the real world
reasoning.
Eric
^ permalink raw reply
* Re: [PATCH/RFC repost 3/8] odp-util: formatting of datapath select group action
From: Simon Horman @ 2014-09-24 4:55 UTC (permalink / raw)
To: Thomas Graf; +Cc: dev, netdev, Pravin Shelar, Jesse Gross
In-Reply-To: <20140919134449.GA8257@casper.infradead.org>
On Fri, Sep 19, 2014 at 02:44:49PM +0100, Thomas Graf wrote:
> On 09/18/14 at 10:55am, Simon Horman wrote:
> > Allow formatting of select group action. This is used
> > when pretty-printing datapath flows. Subsequent patches
> > will add support for the select group action to the datapath
> > and ovs-vswtichd.
> >
> > Signed-off-by: Simon Horman <simon.horman@netronome.com>
> > ---
> > lib/odp-util.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 67 insertions(+)
> >
> > diff --git a/lib/odp-util.c b/lib/odp-util.c
> > index 77b456f..4c8dd39 100644
> > --- a/lib/odp-util.c
> > +++ b/lib/odp-util.c
> > @@ -182,6 +182,71 @@ format_odp_sample_action(struct ds *ds, const struct nlattr *attr)
> > ds_put_format(ds, "))");
> > }
> >
> > +static bool
> > +format_odp_bucket(struct ds *ds, const struct nlattr *attr)
> > +{
> > + static const struct nl_policy ovs_sample_policy[] = {
>
> Not that it would matter much but you might want to rename that to
> ovs_bucket_policy[]. Same below.
Thanks, I renamed all the new instances of ovs_sample_policy
(which I cut and pasted from the implementation of sample actions).
^ permalink raw reply
* Re: [ethtool PATCH 1/1] ethtool: Support cpsw ale-table registers in -d
From: Mugunthan V N @ 2014-09-24 5:32 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, davem
In-Reply-To: <1411340326.20019.32.camel@decadent.org.uk>
On Monday 22 September 2014 04:28 AM, Ben Hutchings wrote:
> Sorry I didn't respond to this earlier.
>
> On Wed, 2014-07-23 at 14:59 +0530, Mugunthan V N wrote:
> [...]
>> --- /dev/null
>> +++ b/cpsw.c
> [...]
>> +static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
>> + u32 value)
>> +{
>> + int idx;
>> +
>> + value &= BITMASK(bits);
>> + idx = start / 32;
>> + start -= idx * 32;
>> + idx = 2 - idx; /* flip */
>> + ale_entry[idx] &= ~(BITMASK(bits) << start);
>> + ale_entry[idx] |= (value << start);
>> +}
>> +
>> +#define DEFINE_ALE_FIELD(name, start, bits) \
>> +static inline int cpsw_ale_get_##name(u32 *ale_entry) \
>> +{ \
>> + return cpsw_ale_get_field(ale_entry, start, bits); \
>> +} \
>> +static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
>> +{ \
>> + cpsw_ale_set_field(ale_entry, start, bits, value); \
>> +}
>
> The setter functions are unused.
Will fis this in next version
>
> [...]
>> +int cpsw_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
>> +{
>> + u32 *reg = (u8 *)regs->data;
>> + u32 len = regs->len / 3;
>> + int i;
>> +
>> + fprintf(stdout, "cpsw hw version %d.%d (%d)\n",
>> + CPSW_MAJOR_VERSION(regs->version),
>> + CPSW_MINOR_VERSION(regs->version),
>> + CPSW_RTL_VERSION(regs->version));
> [...]
>
> There needs to be a version check here. Some future version of the
> hardware or driver may introduce an incompatible dump format.
>
Will check the hardware version in v2.
Regards
Mugunthan V N
^ permalink raw reply
* Re: [PATCH/RFC repost 5/8] datapath: Move last_action() helper to datapath.h
From: Simon Horman @ 2014-09-24 6:00 UTC (permalink / raw)
To: Thomas Graf; +Cc: dev, netdev, Pravin Shelar, Jesse Gross
In-Reply-To: <20140919140638.GC8257@casper.infradead.org>
On Fri, Sep 19, 2014 at 03:06:38PM +0100, Thomas Graf wrote:
> On 09/18/14 at 10:55am, Simon Horman wrote:
> > diff --git a/datapath/datapath.h b/datapath/datapath.h
> > index c5d3c86..74a15e6 100644
> > --- a/datapath/datapath.h
> > +++ b/datapath/datapath.h
> > @@ -209,4 +209,9 @@ do { \
> > if (net_ratelimit()) \
> > pr_info("netlink: " fmt, ##__VA_ARGS__); \
> > } while (0)
> > +
> > +static inline bool last_action(const struct nlattr *a, int rem)
> > +{
> > + return a->nla_len == rem;
> > +}
> > #endif /* datapath.h */
>
> Can we rename & move this to <net/netlink.h> instead?
Sure, how about nla_is_last()?
^ permalink raw reply
* Re: [PATCH/RFC repost 4/8] datapath: execution of select group action
From: Simon Horman @ 2014-09-24 6:01 UTC (permalink / raw)
To: Thomas Graf; +Cc: dev, netdev, Pravin Shelar, Jesse Gross
In-Reply-To: <20140919140527.GB8257@casper.infradead.org>
On Fri, Sep 19, 2014 at 03:05:27PM +0100, Thomas Graf wrote:
> On 09/18/14 at 10:55am, Simon Horman wrote:
> > +const struct nlattr *bucket_actions(const struct nlattr *attr)
> > +{
> > + const struct nlattr *a;
> > + int rem;
> > +
> > + for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
> > + a = nla_next(a, &rem)) {
> > + if (nla_type(a) == OVS_BUCKET_ATTR_ACTIONS) {
> > + return a;
> > + }
> > + }
> > +
> > + return NULL;
> > +}
>
> This is identical to nla_find(). I realize this is not the only
> example but I think we should stop replicating existing Netlink
> functionality and add missing pieces to lib/nlattr.c.
Thanks. For starters I have removed bucket_actions() and replaced
its usage with a call to nla_find().
> > +static u16 bucket_weight(const struct nlattr *attr)
> > +{
> > + const struct nlattr *weight;
> > +
> > + /* validate_and_copy_bucket() ensures that the first
> > + * attribute is OVS_BUCKET_ATTR_WEIGHT */
> > + weight = nla_data(attr);
> > + BUG_ON(nla_type(weight) != OVS_BUCKET_ATTR_WEIGHT);
> > + return nla_get_u16(weight);
> > +}
> > +
> > +static int select_group(struct datapath *dp, struct sk_buff *skb,
> > + const struct nlattr *attr)
> > +{
> > + const struct nlattr *best_bucket = NULL;
> > + const struct nlattr *acts_list;
> > + const struct nlattr *bucket;
> > + struct sk_buff *sample_skb;
> > + u32 best_score = 0;
> > + u32 basis;
> > + u32 i = 0;
> > + int rem;
> > +
> > + basis = skb_get_hash(skb);
> > +
> > + /* Only possible type of attributes is OVS_SELECT_GROUP_ATTR_BUCKET */
> > + for (bucket = nla_data(attr), rem = nla_len(attr); rem > 0;
> > + bucket = nla_next(bucket, &rem)) {
> > + uint16_t weight = bucket_weight(bucket);
>
> I think we should validate only once when we copy then assume it is
> correct.
That is the intention of this code, is it doing something else?
I think there is some scope to store the bucket in a more efficient
form for execution. But I'm not sure that any other actions
receive such treatment. So I postponed inventing that wheel.
> > + // XXX: This hashing seems expensive
> > + u32 score = (jhash_1word(i, basis) & 0xffff) * weight;
>
> Maybe just calculate a weighted distribution table pointing to the
> buckets which you index with 8 bits of the hash.
Nice idea. I think that would work out quite well.
The main question for me would be where to store such a table,
which comes back to my remark above about more storing a more
efficient efficient form of the action.
> > + if (score >= best_score) {
> > + best_bucket = bucket;
> > + best_score = score;
> > + }
> > + i++;
> > + }
> > +
> > + acts_list = bucket_actions(best_bucket);
> > +
> > + /* A select group action is always the final action so
> > + * there is no need to clone the skb in case of side effects.
> > + * Instead just take a reference to it which will be released
> > + * by do_execute_actions(). */
> > + skb_get(skb);
> > +
> > + return do_execute_actions(dp, skb, nla_data(acts_list),
> > + nla_len(acts_list));
>
> Do we need a recursion limit here?
I believe that is already handled by the depth check that occurs
when the actions are copied.
^ permalink raw reply
* Re: [PATCH] net: stmmac: fix stmmac_pci_probe failed when CONFIG_HAVE_CLK is selected
From: Giuseppe CAVALLARO @ 2014-09-24 6:09 UTC (permalink / raw)
To: Kweh, Hock Leong, David Miller
Cc: rayagond@vayavyalabs.com, vbridgers2013@gmail.com, wens@csie.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Ong, Boon Leong, tobias.johannes.klausmann@mni.thm.de
In-Reply-To: <F54AEECA5E2B9541821D670476DAE19C2B7EAF23@PGSMSX102.gar.corp.intel.com>
On 9/23/2014 9:03 AM, Kweh, Hock Leong wrote:
>> -----Original Message-----
>> From: Giuseppe CAVALLARO [mailto:peppe.cavallaro@st.com]
>> Sent: Tuesday, September 23, 2014 2:10 PM
>>
>> the logic is: the priv->stmmac_clk must be always provided from the platform
>> then we have two cases:
>>
>> 1) if priv->plat->clk_csr is also passed then it will be adopt in the
>> mdio functions to program the Reg4[5:2]
>> This was required in the past IIRC on SPEAr platforms.
>>
>> 2) if priv->plat->clk_csr is not passed from the platform then the
>> priv->clk_csr will be set according to the priv->stmmac_clk
>> and always used in the mdio part.
>>
>> So IIUC now you are asking for not passing the priv->stmmac_clk and warning
>> this event w/o failing. Why you cannot pass this clock?
>>
>> peppe
>
>
> Hi peppe,
>
> Appreciate for the explanation. Just to clarify that I am not asking not to pass in the priv->stmmac_clk.
> In fact, the fix will fail at case 2 if driver cannot obtain the priv->stmmac_clk, but just not the case 1.
> For case 1, seem like it does not require the stmmac_clk then I think it should be OK not to fail it when
> driver did not get stmmac_clk but have the clk_csr set.
ok we can do that but this clock is also managed when the iface is down.
Maybe it could be convenient to manage it for power consumption.
What do you think?
> Anyway, I can change the fix by adding the clock registration APIs being call at the stmmac_pci.c probe there before
> calling stmmac_dvr_probe. By doing this, it created a dependency to the pci driver that must have CONFIG_HAVE_CLK
> to be turned on. Besides, I would need you guys to provide me information on other platforms about what is the best
> value to set? Can I just set to zero since the stmmac_pci driver is always using the priv->plat->clk_csr?
>
>
> Regards,
> Wilson
>
>
>
^ permalink raw reply
* [PATCH] net: fec: remove memory copy for rx path
From: Fugang Duan @ 2014-09-24 6:05 UTC (permalink / raw)
To: b20596, davem; +Cc: netdev, shawn.guo, bhutchings, b38611
Re-allocate skb instead of memory copy skb data in rx path to improve
enet rx performance.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/net/ethernet/freescale/fec_main.c | 90 +++++++++++++++--------------
1 files changed, 47 insertions(+), 43 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 2b16ead..1fc8e52 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1322,6 +1322,28 @@ fec_enet_tx(struct net_device *ndev)
return;
}
+static int
+fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff *skb)
+{
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int off;
+
+ off = ((unsigned long)skb->data) & fep->rx_align;
+ if (off)
+ skb_reserve(skb, fep->rx_align + 1 - off);
+
+ bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
+ FEC_ENET_RX_FRSIZE - fep->rx_align,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
+ if (net_ratelimit())
+ netdev_err(ndev, "Rx DMA memory map failed\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
/* During a receive, the cur_rx points to the current incoming buffer.
* When we update through the ring, if the next incoming buffer has
* not been given to the system, we just set the empty indicator,
@@ -1336,7 +1358,8 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
struct fec_enet_priv_rx_q *rxq;
struct bufdesc *bdp;
unsigned short status;
- struct sk_buff *skb;
+ struct sk_buff *skb_new = NULL;
+ struct sk_buff *skb_cur;
ushort pkt_len;
__u8 *data;
int pkt_received = 0;
@@ -1402,9 +1425,10 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
index = fec_enet_get_bd_index(rxq->rx_bd_base, bdp, fep);
data = rxq->rx_skbuff[index]->data;
- dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr,
- FEC_ENET_RX_FRSIZE - fep->rx_align,
- DMA_FROM_DEVICE);
+ skb_cur = rxq->rx_skbuff[index];
+ dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
+ FEC_ENET_RX_FRSIZE - fep->rx_align,
+ DMA_FROM_DEVICE);
if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
swap_buffer(data, pkt_len);
@@ -1427,57 +1451,50 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
vlan_packet_rcvd = true;
}
- /* This does 16 byte alignment, exactly what we need.
- * The packet length includes FCS, but we don't want to
- * include that when passing upstream as it messes up
- * bridging applications.
- */
- skb = netdev_alloc_skb(ndev, pkt_len - 4 + NET_IP_ALIGN);
+ skb_new = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
- if (unlikely(!skb)) {
+ if (unlikely(!skb_new)) {
ndev->stats.rx_dropped++;
} else {
- int payload_offset = (2 * ETH_ALEN);
- skb_reserve(skb, NET_IP_ALIGN);
- skb_put(skb, pkt_len - 4); /* Make room */
+ skb_put(skb_cur, pkt_len - 4); /* Make room */
/* Extract the frame data without the VLAN header. */
- skb_copy_to_linear_data(skb, data, (2 * ETH_ALEN));
- if (vlan_packet_rcvd)
- payload_offset = (2 * ETH_ALEN) + VLAN_HLEN;
- skb_copy_to_linear_data_offset(skb, (2 * ETH_ALEN),
- data + payload_offset,
- pkt_len - 4 - (2 * ETH_ALEN));
+ if (vlan_packet_rcvd) {
+ skb_copy_to_linear_data_offset(skb_cur, VLAN_HLEN,
+ data, (2 * ETH_ALEN));
+ skb_pull(skb_cur, VLAN_HLEN);
+ }
- skb->protocol = eth_type_trans(skb, ndev);
+ skb_cur->protocol = eth_type_trans(skb_cur, ndev);
/* Get receive timestamp from the skb */
if (fep->hwts_rx_en && fep->bufdesc_ex)
fec_enet_hwtstamp(fep, ebdp->ts,
- skb_hwtstamps(skb));
+ skb_hwtstamps(skb_cur));
if (fep->bufdesc_ex &&
(fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
if (!(ebdp->cbd_esc & FLAG_RX_CSUM_ERROR)) {
/* don't check it */
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb_cur->ip_summed = CHECKSUM_UNNECESSARY;
} else {
- skb_checksum_none_assert(skb);
+ skb_checksum_none_assert(skb_cur);
}
}
/* Handle received VLAN packets */
if (vlan_packet_rcvd)
- __vlan_hwaccel_put_tag(skb,
+ __vlan_hwaccel_put_tag(skb_cur,
htons(ETH_P_8021Q),
vlan_tag);
- napi_gro_receive(&fep->napi, skb);
+ napi_gro_receive(&fep->napi, skb_cur);
}
- dma_sync_single_for_device(&fep->pdev->dev, bdp->cbd_bufaddr,
- FEC_ENET_RX_FRSIZE - fep->rx_align,
- DMA_FROM_DEVICE);
+ /* set the new skb */
+ rxq->rx_skbuff[index] = skb_new;
+ fec_enet_new_rxbdp(ndev, bdp, skb_new);
+
rx_processing_done:
/* Clear the status flags for this buffer */
status &= ~BD_ENET_RX_STATS;
@@ -2553,33 +2570,20 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
struct sk_buff *skb;
struct bufdesc *bdp;
struct fec_enet_priv_rx_q *rxq;
- unsigned int off;
rxq = fep->rx_queue[queue];
bdp = rxq->rx_bd_base;
for (i = 0; i < rxq->rx_ring_size; i++) {
- dma_addr_t addr;
-
skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
if (!skb)
goto err_alloc;
- off = ((unsigned long)skb->data) & fep->rx_align;
- if (off)
- skb_reserve(skb, fep->rx_align + 1 - off);
-
- addr = dma_map_single(&fep->pdev->dev, skb->data,
- FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE);
-
- if (dma_mapping_error(&fep->pdev->dev, addr)) {
+ if (fec_enet_new_rxbdp(ndev, bdp, skb)) {
dev_kfree_skb(skb);
- if (net_ratelimit())
- netdev_err(ndev, "Rx DMA memory map failed\n");
goto err_alloc;
}
rxq->rx_skbuff[i] = skb;
- bdp->cbd_bufaddr = addr;
bdp->cbd_sc = BD_ENET_RX_EMPTY;
if (fep->bufdesc_ex) {
--
1.7.8
^ permalink raw reply related
* [PATCH] usb: gadget: f_rndis: fix usb_interface_descriptor for rndis
From: Heiko Schocher @ 2014-09-24 6:48 UTC (permalink / raw)
To: linux-usb-u79uwXL29TY76Z2rM5mHXA
Cc: Heiko Schocher, Felipe Balbi, Greg Kroah-Hartman,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Oliver Neukum,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-api-u79uwXL29TY76Z2rM5mHXA,
Andrzej Pietrasiewicz, Michal Nazarewicz, Kyungmin Park,
Dan Carpenter, Macpaul Lin
use the values for RNDIS over Ethernet as defined in
http://www.usb.org/developers/defined_class
(search for RDNIS):
- baseclass: 0xef (miscellaneous)
- subclass: 0x04
- protocol: 0x01
with this setings the file in Documentation/usb/linux.inf is
obsolete.
Signed-off-by: Heiko Schocher <hs-ynQEQJNshbs@public.gmane.org>
---
Cc: Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org>
Cc: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Oliver Neukum <oliver-Q6YOFhsQ4GZ7tPAFqOLdPg@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Andrzej Pietrasiewicz <andrzej.p-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Cc: Michal Nazarewicz <mina86-deATy8a+UHjQT0dZR+AlfA@public.gmane.org>
Cc: Kyungmin Park <kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Cc: Dan Carpenter <dan.carpenter-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
Cc: Macpaul Lin <macpaul-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Tested with the "USB Compliance test suite which runs Windows", see:
http://www.usb.org/developers/tools/usb20_tools/#usb20cv
drivers/net/usb/cdc_ether.c | 6 +++---
drivers/usb/core/generic.c | 6 +++---
drivers/usb/gadget/function/f_rndis.c | 6 +++---
include/uapi/linux/usb/cdc.h | 3 +++
4 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 2a32d91..9c216c2 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -35,9 +35,9 @@
static int is_rndis(struct usb_interface_descriptor *desc)
{
- return (desc->bInterfaceClass == USB_CLASS_COMM &&
- desc->bInterfaceSubClass == 2 &&
- desc->bInterfaceProtocol == 0xff);
+ return (desc->bInterfaceClass == USB_CLASS_MISC &&
+ desc->bInterfaceSubClass == USB_CDC_SUBCLASS_RNDIS &&
+ desc->bInterfaceProtocol == USB_CDC_RNDIS_PROTO_ETH);
}
static int is_activesync(struct usb_interface_descriptor *desc)
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 358ca8d..a2a4e05 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -28,9 +28,9 @@ static inline const char *plural(int n)
static int is_rndis(struct usb_interface_descriptor *desc)
{
- return desc->bInterfaceClass == USB_CLASS_COMM
- && desc->bInterfaceSubClass == 2
- && desc->bInterfaceProtocol == 0xff;
+ return desc->bInterfaceClass == USB_CLASS_MISC
+ && desc->bInterfaceSubClass == USB_CDC_SUBCLASS_RNDIS
+ && desc->bInterfaceProtocol == USB_CDC_RNDIS_PROTO_ETH;
}
static int is_activesync(struct usb_interface_descriptor *desc)
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c
index ddb09dc..cc06046 100644
--- a/drivers/usb/gadget/function/f_rndis.c
+++ b/drivers/usb/gadget/function/f_rndis.c
@@ -117,9 +117,9 @@ static struct usb_interface_descriptor rndis_control_intf = {
/* .bInterfaceNumber = DYNAMIC */
/* status endpoint is optional; this could be patched later */
.bNumEndpoints = 1,
- .bInterfaceClass = USB_CLASS_COMM,
- .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
- .bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR,
+ .bInterfaceClass = USB_CLASS_MISC,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_RNDIS,
+ .bInterfaceProtocol = USB_CDC_RNDIS_PROTO_ETH,
/* .iInterface = DYNAMIC */
};
diff --git a/include/uapi/linux/usb/cdc.h b/include/uapi/linux/usb/cdc.h
index b6a9cdd..8e8fc85 100644
--- a/include/uapi/linux/usb/cdc.h
+++ b/include/uapi/linux/usb/cdc.h
@@ -12,6 +12,7 @@
#include <linux/types.h>
#define USB_CDC_SUBCLASS_ACM 0x02
+#define USB_CDC_SUBCLASS_RNDIS 0x04
#define USB_CDC_SUBCLASS_ETHERNET 0x06
#define USB_CDC_SUBCLASS_WHCM 0x08
#define USB_CDC_SUBCLASS_DMM 0x09
@@ -31,6 +32,8 @@
#define USB_CDC_ACM_PROTO_AT_CDMA 6
#define USB_CDC_ACM_PROTO_VENDOR 0xff
+#define USB_CDC_RNDIS_PROTO_ETH 1
+
#define USB_CDC_PROTO_EEM 7
#define USB_CDC_NCM_PROTO_NTB 1
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next] bluetooth: Convert bt_<level> logging functions to return void
From: Marcel Holtmann @ 2014-09-24 7:40 UTC (permalink / raw)
To: Joe Perches
Cc: Gustavo F. Padovan, Johan Hedberg, David S. Miller,
BlueZ development, Network Development, linux-kernel
In-Reply-To: <1411409861.2952.57.camel@joe-AO725>
Hi Joe,
> No caller or macro uses the return value so make all
> the functions return void.
>
> Signed-off-by: Joe Perches <joe@perches.com>
> ---
> This change is associated to a desire to eventually
> change printk to return void.
>
> include/net/bluetooth/bluetooth.h | 4 ++--
> net/bluetooth/lib.c | 14 ++++----------
> 2 files changed, 6 insertions(+), 12 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* patch "isdn: i4l: Remove ASYNC_CTS_FLOW" added to tty tree
From: gregkh @ 2014-09-24 4:20 UTC (permalink / raw)
To: peter, gregkh, isdn, netdev
This is a note to let you know that I've just added the patch titled
isdn: i4l: Remove ASYNC_CTS_FLOW
to my tty git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
in the tty-next branch.
The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)
The patch will also be merged in the next major kernel release
during the merge window.
If you have any questions about this process, please let me know.
>From 317c1360200059a7a8a832294a58409c73b784bf Mon Sep 17 00:00:00 2001
From: Peter Hurley <peter@hurleysoftware.com>
Date: Wed, 10 Sep 2014 15:06:25 -0400
Subject: isdn: i4l: Remove ASYNC_CTS_FLOW
ISDN4Linux always enables CTS flow control and does not use the
tty_port_cts_enabled() helper function; remove ASYNC_CTS_FLOW
state enable/disable.
cc: Karsten Keil <isdn@linux-pingi.de>
cc: <netdev@vger.kernel.org>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/isdn/i4l/isdn_tty.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 3c5f2491a16f..bc912611fe09 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1043,11 +1043,6 @@ isdn_tty_change_speed(modem_info *info)
if (!(cflag & PARODD))
cval |= UART_LCR_EPAR;
- /* CTS flow control flag and modem status interrupts */
- if (cflag & CRTSCTS) {
- port->flags |= ASYNC_CTS_FLOW;
- } else
- port->flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
port->flags &= ~ASYNC_CHECK_CD;
else {
--
2.1.0
^ permalink raw reply related
* Re: [PATCH v2] net/netfilter/x_tables.c: use __seq_open_private()
From: Rob Jones @ 2014-09-24 8:14 UTC (permalink / raw)
To: Pablo Neira Ayuso, Ben Hutchings
Cc: davem, coreteam, netdev, linux-kernel, linux-kernel, netfilter,
netfilter-devel
In-Reply-To: <20140923214021.GA4206@salvia>
On 23/09/14 22:40, Pablo Neira Ayuso wrote:
> On Tue, Sep 23, 2014 at 06:46:27PM +0100, Ben Hutchings wrote:
>> On Tue, 2014-09-23 at 18:05 +0100, Rob Jones wrote:
>>> Reduce boilerplate code by using __seq_open_private() instead of seq_open()
>>> in xt_match_open() and xt_target_open().
>>>
>>> Signed-off-by: Rob Jones <rob.jones@codethink.co.uk>
>>> ---
>>>
>>> This patch uses an existing variant of seq_open() to reduce the kernel code
>>> size.
>>>
>>> The only significant variation from the pre-existing code is the fact that
>>> __seq_open_private() calls kzalloc() rather than kmalloc(), which could
>>> conceivably have an impact on timing.
>>>
>>> This version 2 incorporates a minor initialisation simplification (resulting
>>> from kzalloc() being used) requested by netfilter-devel@vger.kernel.org
>> [...]
>>> --- a/net/netfilter/x_tables.c
>>> +++ b/net/netfilter/x_tables.c
>>> @@ -1080,7 +1080,6 @@ static void *xt_mttg_seq_start(struct seq_file *seq, loff_t *pos,
>>> struct nf_mttg_trav *trav = seq->private;
>>> unsigned int j;
>>>
>>> - trav->class = MTTG_TRAV_INIT;
>>> for (j = 0; j < *pos; ++j)
>>> if (xt_mttg_seq_next(seq, NULL, NULL, is_target) == NULL)
>>> return NULL;
>> [...]
>>
>> I'm fairly sure this simplification is wrong, as xt_mttg_seq_start() is
>> potentially called multiple times on the same file handle.
Well spotted Ben.
>
> Right. I'm going to take v1 of this patch instead, sorry for the
> inconvenience Rob.
No problem at all. It gave me something to do on the train home last
night :-)
--
Rob Jones
Codethink Ltd
mailto:rob.jones@codethink.co.uk
tel:+44 161 236 5575
^ permalink raw reply
* Re: [PATCH/RFC repost 4/8] datapath: execution of select group action
From: Thomas Graf @ 2014-09-24 8:19 UTC (permalink / raw)
To: Simon Horman; +Cc: dev, netdev, Pravin Shelar, Jesse Gross
In-Reply-To: <20140924060107.GC13314@vergenet.net>
On 09/24/14 at 03:01pm, Simon Horman wrote:
> > > + /* Only possible type of attributes is OVS_SELECT_GROUP_ATTR_BUCKET */
> > > + for (bucket = nla_data(attr), rem = nla_len(attr); rem > 0;
> > > + bucket = nla_next(bucket, &rem)) {
> > > + uint16_t weight = bucket_weight(bucket);
> >
> > I think we should validate only once when we copy then assume it is
> > correct.
> That is the intention of this code, is it doing something else?
I must have treated the BUG_ON as validation when I wrote that
comment ;-)
> Nice idea. I think that would work out quite well.
>
> The main question for me would be where to store such a table,
> which comes back to my remark above about more storing a more
> efficient efficient form of the action.
I had the same issue when working on zone support for the
conntrack action that is in the works. It needs to keep a ref to
a ct template which is registered with the conntrack engine. I
ended up converting the Netlink attributes to a struct and storing
that in an attribute in sf_acts then converting it back.
You can find the WIP code in the following branch:
https://github.com/tgraf/ovs/tree/nat
datapath: Use central function to free sw_flow_actions
RFC: Add support for connection tracking.
datapath: Add zone support
> > Do we need a recursion limit here?
>
> I believe that is already handled by the depth check that occurs
> when the actions are copied.
Right, I can see it now. Thanks.
^ permalink raw reply
* Re: [PATCH/RFC repost 5/8] datapath: Move last_action() helper to datapath.h
From: Thomas Graf @ 2014-09-24 8:20 UTC (permalink / raw)
To: Simon Horman; +Cc: dev-yBygre7rU0TnMu66kgdUjQ, netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20140924060013.GB13314-IxS8c3vjKQDk1uMJSBkQmQ@public.gmane.org>
On 09/24/14 at 03:00pm, Simon Horman wrote:
> On Fri, Sep 19, 2014 at 03:06:38PM +0100, Thomas Graf wrote:
> > Can we rename & move this to <net/netlink.h> instead?
>
> Sure, how about nla_is_last()?
Sounds great
^ permalink raw reply
* [PATCH 1/4] staging: et131x: Use ether_addr_copy when copying ethernet addresses
From: Mark Einon @ 2014-09-24 8:54 UTC (permalink / raw)
To: gregkh; +Cc: devel, angus, netdev, linux-kernel, joe, Mark Einon, davem
In-Reply-To: <1411506437.29268.13.camel@joe-AO725>
Reported-by: Joe Perches <joe@perches.com>
Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
drivers/staging/et131x/et131x.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index 4b2ae49..b976c75 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -3188,15 +3188,13 @@ static void et131x_hwaddr_init(struct et131x_adapter *adapter)
* working with so we need to copy the current
* address into the permanent address
*/
- memcpy(adapter->rom_addr,
- adapter->addr, ETH_ALEN);
+ ether_addr_copy(adapter->rom_addr, adapter->addr);
} else {
/* We do not have an override address, so set the
* current address to the permanent address and add
* it to the device
*/
- memcpy(adapter->addr,
- adapter->rom_addr, ETH_ALEN);
+ ether_addr_copy(adapter->addr, adapter->rom_addr);
}
}
@@ -4048,7 +4046,7 @@ static void et131x_multicast(struct net_device *netdev)
netdev_for_each_mc_addr(ha, netdev) {
if (i == NIC_MAX_MCAST_LIST)
break;
- memcpy(adapter->multicast_list[i++], ha->addr, ETH_ALEN);
+ ether_addr_copy(adapter->multicast_list[i++], ha->addr);
}
adapter->multicast_addr_count = i;
@@ -4178,7 +4176,7 @@ static int et131x_change_mtu(struct net_device *netdev, int new_mtu)
et131x_init_send(adapter);
et131x_hwaddr_init(adapter);
- memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN);
+ ether_addr_copy(netdev->dev_addr, adapter->addr);
/* Init the device with the new settings */
et131x_adapter_setup(adapter);
@@ -4296,7 +4294,7 @@ static int et131x_pci_setup(struct pci_dev *pdev,
netif_napi_add(netdev, &adapter->napi, et131x_poll, 64);
/* Copy address into the net_device struct */
- memcpy(netdev->dev_addr, adapter->addr, ETH_ALEN);
+ ether_addr_copy(netdev->dev_addr, adapter->addr);
rc = -ENOMEM;
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/4] staging: et131x: Cat some lines less than 80 columns
From: Mark Einon @ 2014-09-24 8:54 UTC (permalink / raw)
To: gregkh; +Cc: devel, angus, netdev, linux-kernel, joe, Mark Einon, davem
In-Reply-To: <1411548882-10639-1-git-send-email-mark.einon@gmail.com>
Some split lines are less than 80 chars if rejoined, so rejoin them.
Reported-by: Joe Perches <joe@perches.com>
Signed-off-by: Mark Einon <mark.einon@gmail.com>
---
drivers/staging/et131x/et131x.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c
index b976c75..f5459ec 100644
--- a/drivers/staging/et131x/et131x.c
+++ b/drivers/staging/et131x/et131x.c
@@ -3389,7 +3389,8 @@ static void et131x_adjust_link(struct net_device *netdev)
et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
®ister18);
et131x_mii_write(adapter, phydev->addr,
- PHY_MPHY_CONTROL_REG, register18 | 0x4);
+ PHY_MPHY_CONTROL_REG,
+ register18 | 0x4);
et131x_mii_write(adapter, phydev->addr, PHY_INDEX_REG,
register18 | 0x8402);
et131x_mii_write(adapter, phydev->addr, PHY_DATA_REG,
@@ -3422,7 +3423,8 @@ static void et131x_adjust_link(struct net_device *netdev)
et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG,
®ister18);
et131x_mii_write(adapter, phydev->addr,
- PHY_MPHY_CONTROL_REG, register18 | 0x4);
+ PHY_MPHY_CONTROL_REG,
+ register18 | 0x4);
et131x_mii_write(adapter, phydev->addr,
PHY_INDEX_REG, register18 | 0x8402);
et131x_mii_write(adapter, phydev->addr,
@@ -3746,8 +3748,7 @@ static irqreturn_t et131x_isr(int irq, void *dev_id)
*/
/* TRAP();*/
- dev_warn(&adapter->pdev->dev,
- "RxDMA_ERR interrupt, error %x\n",
+ dev_warn(&adapter->pdev->dev, "RxDMA_ERR interrupt, error %x\n",
readl(&iomem->txmac.tx_test));
}
@@ -3773,8 +3774,7 @@ static irqreturn_t et131x_isr(int irq, void *dev_id)
* occur. In a nutshell, the whole Tx path will have to be reset
* and re-configured afterwards.
*/
- dev_warn(&adapter->pdev->dev,
- "TXMAC interrupt, error 0x%08x\n",
+ dev_warn(&adapter->pdev->dev, "TXMAC interrupt, error 0x%08x\n",
err);
/* If we are debugging, we want to see this error, otherwise we
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox