* Re: sky2: only 10Mb/s
From: Stephen Hemminger @ 2011-10-17 15:56 UTC (permalink / raw)
To: Pavel Mateja; +Cc: netdev
In-Reply-To: <201110171434.50436.pavel@netsafe.cz>
On Mon, 17 Oct 2011 14:34:50 +0200
Pavel Mateja <pavel@netsafe.cz> wrote:
> Hi,
> I tested new kernel and I have found out I have only 10Mb/s link instead of
> 100Mb/s to my router.
> If I did the git bisect right it was caused by commit
> 4fb99cd6ac4fe6d03a334a6f4ebb2bbfc4b479ed which was submitted by you.
>
> My card is (lspci -v):
> 05:00.0 Ethernet controller: Marvell Technology Group Ltd. Yukon Optima
> 88E8059 [PCIe Gigabit Ethernet Controller with AVB] (rev 11)
> Subsystem: ASUSTeK Computer Inc. Device 8439
> Flags: bus master, fast devsel, latency 0, IRQ 80
> Memory at fe6fc000 (64-bit, non-prefetchable) [size=16K]
> I/O ports at b800 [size=256]
> Expansion ROM at fe6c0000 [disabled] [size=128K]
> Capabilities: [48] Power Management version 3
> Capabilities: [5c] MSI: Enable+ Count=1/1 Maskable- 64bit+
> Capabilities: [c0] Express Legacy Endpoint, MSI 00
> Capabilities: [100] Advanced Error Reporting
> Capabilities: [130] Device Serial Number a5-89-6d-ff-ff-30-cf-20
> Kernel driver in use: sky2
>
> I'm quite sure it's related to Yukon Optima because "Ethernet controller:
> Marvell Technology Group Ltd. 88E8056 PCI-E Gigabit Ethernet Controller" in my
> work computer has 100Mb/s with the same kernel and driver.
>
> I got no response on netdev@vger.kernel.org.
> Can you help me?
What is output of dmesg for sky2.
dmesg | grep sky2
The problem is related to PHY setup. Almost all of that is copied from the
vendor driver. It might take a few steps to fix because I don't think I
have one of those cards handy.
^ permalink raw reply
* Re: [net-next 2/6 v2] igb: Check if subordinate VFs are assigned to virtual machines
From: Joe Perches @ 2011-10-17 15:53 UTC (permalink / raw)
To: Jeff Kirsher
Cc: davem, Greg Rose, netdev, gospo, sassmann, Konrad Rzeszutek Wilk,
Christian Benvenuti, Sathya Perla, Dimitris Michailidis,
Jon Mason, James Smart
In-Reply-To: <1318854062-3628-3-git-send-email-jeffrey.t.kirsher@intel.com>
On Mon, 2011-10-17 at 05:20 -0700, Jeff Kirsher wrote:
> From: Greg Rose <gregory.v.rose@intel.com>
Trivia:
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
[]
> + if (old_vfs) {
> + dev_info(&pdev->dev, "%d pre-allocated VFs found - override "
> + "max_vfs setting of %d\n", old_vfs, max_vfs);
[]
> + dev_err(&pdev->dev, "Unable to allocate memory for VF "
> + "Data Storage\n");
The dev_err line isn't really necessary.
There is a generic allocation failure dump_stack.
Also, please don't split formats into multiple lines.
^ permalink raw reply
* [PATCH] NET: asix: fix ethtool -e for AX88178 USB dongle
From: Grant Grundler @ 2011-10-17 15:51 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-kernel, allan, Freddy Xin, Grant Grundler
"ethtool -e ethX" dumps EEPROM data. Patch sets EEPROM length for device.
Ethtool works alot better when the kernel believes the length is > 0.
From: Allan Chou <allan@asix.com.tw>
Signed-off-by: Grant Grundler <grundler@chromium.org>
---
drivers/net/usb/asix.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 66e5ccb..03a1621 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1399,6 +1399,9 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
int ret;
u8 buf[ETH_ALEN];
u32 phyid;
+ struct asix_data *data = (struct asix_data *)&dev->data;
+
+ data->eeprom_len = AX88772_EEPROM_LEN;
usbnet_get_endpoints(dev,intf);
--
1.7.2.3
^ permalink raw reply related
* [PATCH] iproute2: update CAN bitrate SJW help text
From: Oliver Hartkopp @ 2011-10-17 15:43 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Wolfgang Grandegger, Linux Netdev List, linux-can
The ip-tool from iproute2 already supports to pass a user defined SJW
value for the in-kernel bittiming calculation. This patch updates the
help text accordingly.
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
diff --git a/ip/iplink_can.c b/ip/iplink_can.c
index c8af4bc..00e7d98 100644
--- a/ip/iplink_can.c
+++ b/ip/iplink_can.c
@@ -23,7 +23,8 @@ static void usage(void)
{
fprintf(stderr,
"Usage: ip link set DEVICE type can\n"
- "\t[ bitrate BITRATE [ sample-point SAMPLE-POINT] ] | \n"
+ "\t[ bitrate BITRATE [ sample-point SAMPLE-POINT ] [ sjw SJW "
+ "] ] | \n"
"\t[ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1\n "
"\t phase-seg2 PHASE-SEG2 [ sjw SJW ] ]\n"
"\n"
^ permalink raw reply related
* Re: [PATCH v2 0/3] netdev/of/phy: MDIO bus multiplexer support.
From: David Daney @ 2011-10-17 15:41 UTC (permalink / raw)
To: Kumar Gala
Cc: Grant Likely, David Miller, devicetree-discuss, linux-kernel,
netdev
In-Reply-To: <C81814FF-4E56-4B28-8043-F874EE1D6B51@kernel.crashing.org>
On 10/17/2011 07:48 AM, Kumar Gala wrote:
>
> On Sep 29, 2011, at 7:32 PM, Grant Likely wrote:
>
>> On Thu, Sep 29, 2011 at 04:31:12PM -0400, David Miller wrote:
>>> From: David Daney<david.daney@cavium.com>
>>> Date: Tue, 27 Sep 2011 16:26:52 -0700
>>>
>>>> v2: Update bindings to use "reg" and "mdio-parent-bus" insutead of
>>>> "cell-index" and "parent-bus"
>>>
>>> Grant, when the final version of this patch set is ready how do
>>> you want to handle merging it in?
>>>
>>> I think it would be safe to merge this via your tree, since the
>>> changes made to existing network driver files are rather trivial and
>>> thus merge conflict friendly.
>>
>> Your tree or mine, I'm happy either way. Even if there were
>> conflicts, they would be trivial.
>>
>> Sure, I'll take care of merging it when I see an ack from you.
>>
>>> Actually, I feel like we've discussed this before :-)
>>
>> :)
>>
>> g.
>
> Any updates to these patches?
Not yet, so you didn't miss anything.
They are on my to-do list though
David Daney
^ permalink raw reply
* Re: [PATCH] smsc911x: Add regulator support
From: Mark Brown @ 2011-10-17 15:38 UTC (permalink / raw)
To: Robert MARKLUND; +Cc: netdev@vger.kernel.org, Steve Glendinning, Mathieu Poirer
In-Reply-To: <2B1D156D95AE9B4EAD379CB9E465FE7324AB09E0EE@EXDCVYMBSTM005.EQ1STM.local>
On Mon, Oct 17, 2011 at 05:28:08PM +0200, Robert MARKLUND wrote:
> > If we fail to grab a critical resource for the device like the power
> > supply then we should be failing passing the error back. As I keep
> > saying this is what all the other regulator consumers are doing.
> Most of the boards out there don't have any regulators for the chip(power is always on).
> So when we can't get the regulator, we assume that the power is already on.
> That's why it hasn't been implemented before.
> So adding this functionality will make all the other boards out there fail, to start the driver.
Clearly this issue is going to apply to every single user of the
regulator API which is one reason why it's insane to open code handling
of missing regulators in individual regulator consumer drivers. As I
keep saying you should unconditionally use the regulators and let the
regulator API facilities for stubbing itself out deal with this.
^ permalink raw reply
* RE: [PATCH] smsc911x: Add regulator support
From: Robert MARKLUND @ 2011-10-17 15:28 UTC (permalink / raw)
To: Mark Brown; +Cc: netdev@vger.kernel.org, Steve Glendinning, Mathieu Poirer
In-Reply-To: <20111017143358.GI5448@sirena.org.uk>
> -----Original Message-----
> From: Mark Brown [mailto:broonie@opensource.wolfsonmicro.com]
> Sent: den 17 oktober 2011 16:34
> To: Robert MARKLUND
> Cc: netdev@vger.kernel.org; Steve Glendinning; Mathieu Poirer
> Subject: Re: [PATCH] smsc911x: Add regulator support
>
> On Mon, Oct 17, 2011 at 04:13:47PM +0200, Robert MARKLUND wrote:
>
> > > You should fix your mail client to word wrap within paragraphs, I've
> > > reformatted it for legibility. Also leave a blank line between
> > > paragraphs for the same reason.
>
> > I have tried but it's not as easy as it sounds :)
> > Does it look better now ?
>
> Yes, thanks.
>
> > > No, you should do what all the other drivers do and actually pay
> > > attention to the errors. If we can't get power to the device that's a
> > > pretty serious problem and the driver ought to fail.
>
> > Then I don't understand the initial comment.
> > Can you please elaborate that one.
>
> If we fail to grab a critical resource for the device like the power
> supply then we should be failing passing the error back. As I keep
> saying this is what all the other regulator consumers are doing.
Most of the boards out there don't have any regulators for the chip(power is always on).
So when we can't get the regulator, we assume that the power is already on.
That's why it hasn't been implemented before.
So adding this functionality will make all the other boards out there fail, to start the driver.
/R
^ permalink raw reply
* Re: [PATCH] iproute2: Conforming to -D_FORTIFY_SOURCE=2 restrictions
From: Stephen Hemminger @ 2011-10-17 15:23 UTC (permalink / raw)
To: Bin Li; +Cc: netdev
In-Reply-To: <CAGBH1r6P_nmVhSQ7d9sj1qU_1VY7QssWm3ftS4mNcQjyAuCcqA@mail.gmail.com>
On Mon, 17 Oct 2011 15:35:35 +0800
Bin Li <libin.charles@gmail.com> wrote:
> (gdb) l
> 161 len = slen;
> 162 if (len > 0) {
> 163 if (len > max)
> 164 invarg("\"ALGOKEY\" makes buffer
> overflow\n", key);
> 165
> 166 strncpy(buf, key, len);
> 167 }
> 168 }
> 169
> 170 alg->alg_key_len = len * 8;
> (gdb) up
> #8 xfrm_state_modify (cmd=<optimized out>, flags=<optimized out>, argc=1,
> argv=0x7fffffffe370) at xfrm_state.c:406
> 406 xfrm_algo_parse((void *)&alg, type,
> name, key,
>
> the compiler passes zero to __builtin___strncpy_chk as the buffer size.
> xfrm_algo_parse is inlined into xfrm_state_modify.
I don't understand, looks like a compiler bug. Call strncpy with
0 length should not be possible since the check was 3 lines
before for len > 0.
^ permalink raw reply
* Re: [PATCH 1/1] ethtool: add ETHTOOL_{G,S}CHANNEL support.
From: Ben Hutchings @ 2011-10-17 15:20 UTC (permalink / raw)
To: Sucheta Chakraborty; +Cc: netdev, Dept_NX_Linux_NIC_Driver
In-Reply-To: <1317988730-4197-2-git-send-email-sucheta.chakraborty@qlogic.com>
On Fri, 2011-10-07 at 04:58 -0700, Sucheta Chakraborty wrote:
> Used to configure number of tx/ rx/ other channels.
> Reqd. man page changes are included.
[...]
Applied. Thanks and sorry for the delay.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH 2/2] bridge: allow forwarding some link local frames
From: Stephen Hemminger @ 2011-10-17 15:18 UTC (permalink / raw)
To: Ed Swierk; +Cc: David S. Miller, netdev
In-Reply-To: <CAF5U64AYRhZ1e0=-RhSemgaOnewTQSpAoRY2FUrFr252PG98Pw@mail.gmail.com>
On Mon, 17 Oct 2011 07:35:53 -0700
Ed Swierk <eswierk@bigswitch.com> wrote:
> Why is forwarding LLDP (01-80-C2-00-00-0E) frames forbidden? I'm
> testing LLDP in a virtual topology and need the bridge to forward
> them.
>
> If we're worried about standards, there is justification for allowing
> forwarding of LLDP frames. 802.1d-2005 specifies two classes of
> bridge, customer (C-VLAN) and provider (S-VLAN). Customer bridge is
> just new terminology for what was previously just called an
> 802.1d-compliant bridge, while provider bridge is a new class that
> transparently forwards certain control frames.
Because in current 802.1Q (2005) standard there explicit language
that LLDP should not be forwarded. In Section 7.5
Frames that carry control information to determine the active
topology and current extent of each VLAN, i.e., spanning tree
and GVRP BPDUs, and frames from other link constrained
protocols, such as EAPOL and LLDP, are not forwarded.
Permanently configured static entries in the filtering database
(8.2, 8.3, and 8.12) ensure that such frames are discarded by
the Forwarding Process (8.6).
> The only MAC addresses that are not supposed to be forwarded by either
> customer or provider bridges are:
>
> IEEE 802.3 Full Duplex PAUSE operation (01-80-C2-00-00-01)
> IEEE 802.3 Slow_Protocols_Multicast address (01-80-C2-00-00-02)
> IEEE 802.1X PAE address (01-80-C2-00-00-03)
> Provider Bridge Group Address (01-80-C2-00-00-08)
>
> Customer bridges are also not supposed to forward these addresses:
>
> Bridge Group Address (01-80-C2-00-00-00)
> Provider Bridge GVRP Address (01-80-C2-00-00-0D)
> IEEE 802.1AB Link Layer Discovery Protocol multicast address (01-80-C2-00-00-0E)
>
> My application requires a bridge between a pair of interfaces that
> forwards (at least) LLDP frames; call this a provider bridge if you
> care about standards conformance. It sounds like others require
> forwarding 802.1X PAE frames, which appears non-conformant in any
> case.
>
> Standards aside, given that the default behavior is safe and that
> /sys/class/net/brX/bridge/group_fwd_mask is unlikely to be modified by
> accident by a casual user, can we just remove the
> BR_GROUPFWD_RESTRICTED mask and allow users to forward whatever they
Since EAPOL is allowed, and there is a use case for LLDP, allowing
that is probably okay.
I would prefer not to let user break standards by default. You of course are
free to compile what ever you want
^ permalink raw reply
* Re: [PATCH] dev: use ifindex hash for dev_seq_ops
From: Stephen Hemminger @ 2011-10-17 15:12 UTC (permalink / raw)
To: Daniel Baluta
Cc: Eric Dumazet, Mihai Maruseac, davem, mirq-linux, therbert, jpirko,
netdev, linux-kernel, Mihai Maruseac
In-Reply-To: <CAEnQRZCWBhTy24WkWoC_wy11YuLxWQ3GWr3v1=JcGvprq4AtmA@mail.gmail.com>
On Mon, 17 Oct 2011 11:03:54 +0300
Daniel Baluta <dbaluta@ixiacom.com> wrote:
> > This assumes device ifindexes are contained in a small range
> > [N .. N + X]
> >
> > I understand this can help some benchmarks, but in real world this wont
> > help that much once ifindexes are 'fragmented' (If really this multi
> > thousand devices stuff is for real)
> >
> > Listen, we currently have 256 slots in the hash table.
> >
> > Can we try to make 'offset' something like (slot_number<<24) +
> > (position in hash chain [slot_number]), instead of (position in devices
> > global list)
>
>
> Eric, we can refine the idea of our first patch [1], where we recorded
> the (bucket, offset) pair. Stephen, do you agree with this?
>
>
> thanks,
> Daniel.
>
> [1] http://patchwork.ozlabs.org/patch/118331/
Using buckets is fine, my idea about ifindex was just to try and
preserve the order, but it doesn't matter.
^ permalink raw reply
* Re: [PATCH v2 0/3] netdev/of/phy: MDIO bus multiplexer support.
From: Kumar Gala @ 2011-10-17 14:48 UTC (permalink / raw)
To: Grant Likely
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
netdev-u79uwXL29TY76Z2rM5mHXA, David Miller
In-Reply-To: <20110930003214.GB12606-e0URQFbLeQY2iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
On Sep 29, 2011, at 7:32 PM, Grant Likely wrote:
> On Thu, Sep 29, 2011 at 04:31:12PM -0400, David Miller wrote:
>> From: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
>> Date: Tue, 27 Sep 2011 16:26:52 -0700
>>
>>> v2: Update bindings to use "reg" and "mdio-parent-bus" insutead of
>>> "cell-index" and "parent-bus"
>>
>> Grant, when the final version of this patch set is ready how do
>> you want to handle merging it in?
>>
>> I think it would be safe to merge this via your tree, since the
>> changes made to existing network driver files are rather trivial and
>> thus merge conflict friendly.
>
> Your tree or mine, I'm happy either way. Even if there were
> conflicts, they would be trivial.
>
> Sure, I'll take care of merging it when I see an ack from you.
>
>> Actually, I feel like we've discussed this before :-)
>
> :)
>
> g.
Any updates to these patches?
- k
^ permalink raw reply
* Re: [PATCH 2/2] bridge: allow forwarding some link local frames
From: Ed Swierk @ 2011-10-17 14:35 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David S. Miller, netdev
In-Reply-To: <20111004041509.292932641@vyatta.com>
Why is forwarding LLDP (01-80-C2-00-00-0E) frames forbidden? I'm
testing LLDP in a virtual topology and need the bridge to forward
them.
If we're worried about standards, there is justification for allowing
forwarding of LLDP frames. 802.1d-2005 specifies two classes of
bridge, customer (C-VLAN) and provider (S-VLAN). Customer bridge is
just new terminology for what was previously just called an
802.1d-compliant bridge, while provider bridge is a new class that
transparently forwards certain control frames.
The only MAC addresses that are not supposed to be forwarded by either
customer or provider bridges are:
IEEE 802.3 Full Duplex PAUSE operation (01-80-C2-00-00-01)
IEEE 802.3 Slow_Protocols_Multicast address (01-80-C2-00-00-02)
IEEE 802.1X PAE address (01-80-C2-00-00-03)
Provider Bridge Group Address (01-80-C2-00-00-08)
Customer bridges are also not supposed to forward these addresses:
Bridge Group Address (01-80-C2-00-00-00)
Provider Bridge GVRP Address (01-80-C2-00-00-0D)
IEEE 802.1AB Link Layer Discovery Protocol multicast address (01-80-C2-00-00-0E)
My application requires a bridge between a pair of interfaces that
forwards (at least) LLDP frames; call this a provider bridge if you
care about standards conformance. It sounds like others require
forwarding 802.1X PAE frames, which appears non-conformant in any
case.
Standards aside, given that the default behavior is safe and that
/sys/class/net/brX/bridge/group_fwd_mask is unlikely to be modified by
accident by a casual user, can we just remove the
BR_GROUPFWD_RESTRICTED mask and allow users to forward whatever they
want?
--Ed
^ permalink raw reply
* Re: [PATCH] smsc911x: Add regulator support
From: Mark Brown @ 2011-10-17 14:33 UTC (permalink / raw)
To: Robert MARKLUND; +Cc: netdev@vger.kernel.org, Steve Glendinning, Mathieu Poirer
In-Reply-To: <2B1D156D95AE9B4EAD379CB9E465FE7324AB09E052@EXDCVYMBSTM005.EQ1STM.local>
On Mon, Oct 17, 2011 at 04:13:47PM +0200, Robert MARKLUND wrote:
> > You should fix your mail client to word wrap within paragraphs, I've
> > reformatted it for legibility. Also leave a blank line between
> > paragraphs for the same reason.
> I have tried but it's not as easy as it sounds :)
> Does it look better now ?
Yes, thanks.
> > No, you should do what all the other drivers do and actually pay
> > attention to the errors. If we can't get power to the device that's a
> > pretty serious problem and the driver ought to fail.
> Then I don't understand the initial comment.
> Can you please elaborate that one.
If we fail to grab a critical resource for the device like the power
supply then we should be failing passing the error back. As I keep
saying this is what all the other regulator consumers are doing.
^ permalink raw reply
* RE: [PATCH] smsc911x: Add regulator support
From: Robert MARKLUND @ 2011-10-17 14:13 UTC (permalink / raw)
To: Mark Brown; +Cc: netdev@vger.kernel.org, Steve Glendinning, Mathieu Poirer
In-Reply-To: <20111017123614.GC27266@opensource.wolfsonmicro.com>
> -----Original Message-----
> From: Mark Brown [mailto:broonie@opensource.wolfsonmicro.com]
> Sent: den 17 oktober 2011 14:36
> To: Robert MARKLUND
> Cc: netdev@vger.kernel.org; Steve Glendinning; Mathieu Poirer
> Subject: Re: [PATCH] smsc911x: Add regulator support
>
> On Mon, Oct 17, 2011 at 01:30:06PM +0200, Robert MARKLUND wrote:
>
> You should fix your mail client to word wrap within paragraphs, I've
> reformatted it for legibility. Also leave a blank line between
> paragraphs for the same reason.
I have tried but it's not as easy as it sounds :)
Does it look better now ?
>
> > > No, this is broken - look at how other devices use the regulator API.
> > > The driver should just request and use the regulators unconditionally
> > > and let the stubbing and mapping facilities the API has deal with
> > > ensuring that they always succeed.
>
> > So what you mean is get them and use them and ignore all the return
> > codes, and let the FW take care of the error handling ?
>
> No, you should do what all the other drivers do and actually pay
> attention to the errors. If we can't get power to the device that's a
> pretty serious problem and the driver ought to fail.
Then I don't understand the initial comment.
Can you please elaborate that one.
>
> > > As a side note the use of "pdata" as a name for the driver internal data
> > > is really not helpful, pdata is traditionally the platform data passed
> > > in by the machine (which would be even more broken).
>
> > In the driver they have used this name for this structure throughout
> > the file I just followed that. Personally I think it will be more
> > confusing to change the name of this structure in just this new
> > function.
>
> I think someone should send a patch renaming the data throughout the
> entire driver, it's a terrible name for an embedded context.
I agree let this someone do it.
In the meanwhile isn't it best to keep the style that in the driver as of now.
/R
^ permalink raw reply
* [RFC PATCH 5/5] SUNRPC: pipefs per-net operations helper introduced
From: Stanislav Kinsbursky @ 2011-10-17 13:10 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
In-Reply-To: <20111017120629.4541.67395.stgit@localhost6.localdomain6>
During per-net operation pipes creation and destruction we have to make sure,
that pipefs sb exists for the whole creation/destruction procedure.
This is done by using special mutex which controls pipefs sb reference on network namespace context.
Helper consist of two parts: first of them (rpc_get_dentry_net) searches for
dentry with specified name and returns with mutex taken on success. When pipe
creation is completed, caller should release this mutex by rpc_put_dentry_net
call.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
include/linux/sunrpc/rpc_pipe_fs.h | 5 ++++
net/sunrpc/netns.h | 1 +
net/sunrpc/rpc_pipe.c | 41 ++++++++++++++++++++++++++++++++++++
net/sunrpc/sunrpc_syms.c | 1 +
4 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index 4a327ad..d48ff0b 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -55,6 +55,11 @@ enum {
extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
const unsigned char *dir_name);
+extern void rpc_pipefs_init_net(struct net *net);
+extern struct dentry *rpc_get_dentry_net(const struct net *net,
+ const unsigned char *dir_name);
+extern void rpc_put_dentry_net(const struct net *net, struct dentry *dentry);
+
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
struct rpc_clnt;
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index b384252..11d2f48 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -11,6 +11,7 @@ struct sunrpc_net {
struct cache_detail *ip_map_cache;
struct super_block *pipefs_sb;
+ struct mutex pipefs_sb_lock;
};
extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index a873f03..331be28 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1033,6 +1033,45 @@ struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
}
EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
+void rpc_pipefs_init_net(struct net *net)
+{
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+ mutex_init(&sn->pipefs_sb_lock);
+}
+
+/*
+ * This call will be used for per network namespace operations calls.
+ * Note: Function will be returned with pipefs_sb_lock taken if dentry was
+ * found. This lock have to be released by rpc_put_dentry_net() when all
+ * operations will be completed.
+ */
+struct dentry *rpc_get_dentry_net(const struct net *net,
+ const unsigned char *dir_name)
+{
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+ struct dentry *dentry = ERR_PTR(-ENOENT);
+
+ mutex_lock(&sn->pipefs_sb_lock);
+ if (sn->pipefs_sb) {
+ dentry = rpc_d_lookup_sb(sn->pipefs_sb, dir_name);
+ if (dentry)
+ return dentry;
+ }
+ mutex_unlock(&sn->pipefs_sb_lock);
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL_GPL(rpc_get_dentry_net);
+
+void rpc_put_dentry_net(const struct net *net, struct dentry *dentry)
+{
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+ dput(dentry);
+ mutex_unlock(&sn->pipefs_sb_lock);
+}
+EXPORT_SYMBOL_GPL(rpc_put_dentry_net);
+
static int
rpc_fill_super(struct super_block *sb, void *data, int silent)
{
@@ -1085,7 +1124,9 @@ void rpc_kill_sb(struct super_block *sb)
struct net *net = sb->s_fs_info;
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+ mutex_lock(&sn->pipefs_sb_lock);
sn->pipefs_sb = NULL;
+ mutex_unlock(&sn->pipefs_sb_lock);
put_net(net);
blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
RPC_PIPEFS_UMOUNT,
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 9d08091..880de8b 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -38,6 +38,7 @@ static __net_init int sunrpc_init_net(struct net *net)
if (err)
goto err_ipmap;
+ rpc_pipefs_init_net(net);
return 0;
err_ipmap:
^ permalink raw reply related
* [RFC PATCH 4/5] SUNRPC: put pipefs superblock link on network namespace
From: Stanislav Kinsbursky @ 2011-10-17 13:10 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
In-Reply-To: <20111017120629.4541.67395.stgit@localhost6.localdomain6>
We have modules (like, pNFS blocklayout module) which creates pipes on
rpc_pipefs. Thus we need per-net operations for them. To make it possible to
create piepes in per-net operations, we require super block. So we have to put
sb link on network namespace context. Note, that dont't hardly require to
create pipes in per-net operations. IOW, if pipefs wan't mounted yet, that no
sb link reference will peresent on network namespace. In this case we just
passing through pipe
creation. The pipe will be created druing pipefs mount notification.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
net/sunrpc/netns.h | 2 ++
net/sunrpc/rpc_pipe.c | 4 ++++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index d013bf2..b384252 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -9,6 +9,8 @@ struct cache_detail;
struct sunrpc_net {
struct proc_dir_entry *proc_net_rpc;
struct cache_detail *ip_map_cache;
+
+ struct super_block *pipefs_sb;
};
extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index a8a8812..a873f03 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1039,6 +1039,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
struct inode *inode;
struct dentry *root;
struct net *net = current->nsproxy->net_ns;
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
int err;
sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -1063,6 +1064,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
if (err)
goto err_depopulate;
sb->s_fs_info = get_net(net);
+ sn->pipefs_sb = sb;
return 0;
err_depopulate:
@@ -1081,7 +1083,9 @@ rpc_mount(struct file_system_type *fs_type,
void rpc_kill_sb(struct super_block *sb)
{
struct net *net = sb->s_fs_info;
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+ sn->pipefs_sb = NULL;
put_net(net);
blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
RPC_PIPEFS_UMOUNT,
^ permalink raw reply related
* [RFC PATCH 3/5] SUNRPC: pipefs dentry lookup helper introduced
From: Stanislav Kinsbursky @ 2011-10-17 13:10 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
In-Reply-To: <20111017120629.4541.67395.stgit@localhost6.localdomain6>
In all places, where pipefs dentries are created, only directory inode is
actually required to create new dentry. And all this directories has root
pipefs dentry as their parent. So we actually don't need this pipefs mount
point at all if some pipefs lookup method will be provided.
IOW, all we really need is just superblock and simple lookup method to find
root's dentry child dentry with appropriate name. And this patch introduces
this method.
Note, that no loking implemented in rpc_d_lookup_sb(). So it can be used only
in case of assurance, that pipefs superblock still exist. IOW, we can use this
method only in pipefs mount-umount notificators.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
include/linux/sunrpc/rpc_pipe_fs.h | 3 +++
net/sunrpc/rpc_pipe.c | 16 ++++++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index c1cdb2f..4a327ad 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -52,6 +52,9 @@ enum {
RPC_PIPEFS_UMOUNT,
};
+extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+ const unsigned char *dir_name);
+
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
struct rpc_clnt;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index c90a7e0..a8a8812 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1017,6 +1017,22 @@ static const struct rpc_filelist files[] = {
},
};
+/*
+ * This call can be used only in RPC pipefs mount notification hooks.
+ */
+struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+ const unsigned char *dir_name)
+{
+ struct qstr dir = {
+ .name = dir_name,
+ .len = strlen(dir_name),
+ .hash = full_name_hash(dir_name, strlen(dir_name)),
+ };
+
+ return d_lookup(sb->s_root, &dir);
+}
+EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
+
static int
rpc_fill_super(struct super_block *sb, void *data, int silent)
{
^ permalink raw reply related
* [RFC PATCH 2/5] SUNRPC: send notification events on pipefs sb creation and destruction
From: Stanislav Kinsbursky @ 2011-10-17 13:10 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
In-Reply-To: <20111017120629.4541.67395.stgit@localhost6.localdomain6>
It will be used to notify subscribers about pipefs superblock creation and
destruction.
Cubcriders have to create their dentries on passed superblock on mount event
and destroy otherwise.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
include/linux/sunrpc/rpc_pipe_fs.h | 8 ++++++++
net/sunrpc/rpc_pipe.c | 27 +++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index cf14db9..c1cdb2f 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -44,6 +44,14 @@ RPC_I(struct inode *inode)
return container_of(inode, struct rpc_inode, vfs_inode);
}
+extern int rpc_pipefs_notifier_register(struct notifier_block *);
+extern void rpc_pipefs_notifier_unregister(struct notifier_block *);
+
+enum {
+ RPC_PIPEFS_MOUNT,
+ RPC_PIPEFS_UMOUNT,
+};
+
extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
struct rpc_clnt;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 8322080..c90a7e0 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -28,6 +28,7 @@
#include <linux/sunrpc/rpc_pipe_fs.h>
#include <linux/sunrpc/cache.h>
#include <linux/nsproxy.h>
+#include <linux/notifier.h>
#include "netns.h"
@@ -41,6 +42,18 @@ static struct kmem_cache *rpc_inode_cachep __read_mostly;
#define RPC_UPCALL_TIMEOUT (30*HZ)
+static BLOCKING_NOTIFIER_HEAD(rpc_pipefs_notifier_list);
+
+int rpc_pipefs_notifier_register(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb);
+}
+
+void rpc_pipefs_notifier_unregister(struct notifier_block *nb)
+{
+ blocking_notifier_chain_unregister(&rpc_pipefs_notifier_list, nb);
+}
+
static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
void (*destroy_msg)(struct rpc_pipe_msg *), int err)
{
@@ -1010,6 +1023,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
struct inode *inode;
struct dentry *root;
struct net *net = current->nsproxy->net_ns;
+ int err;
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -1027,8 +1041,18 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
}
if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
return -ENOMEM;
+ err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+ RPC_PIPEFS_MOUNT,
+ sb);
+ if (err)
+ goto err_depopulate;
sb->s_fs_info = get_net(net);
return 0;
+
+err_depopulate:
+ /* TODO: check if we need to send RPC_PIPEFS_UMOUNT notification. */
+ __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
+ return err;
}
static struct dentry *
@@ -1043,6 +1067,9 @@ void rpc_kill_sb(struct super_block *sb)
struct net *net = sb->s_fs_info;
put_net(net);
+ blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+ RPC_PIPEFS_UMOUNT,
+ sb);
kill_litter_super(sb);
}
^ permalink raw reply related
* [RFC PATCH 1/5] SUNRPC: hold current network namespace while pipefs superblock is active
From: Stanislav Kinsbursky @ 2011-10-17 13:10 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
In-Reply-To: <20111017120629.4541.67395.stgit@localhost6.localdomain6>
We want to be sure that network namespace is still alive while we have pipefs
mounted.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
net/sunrpc/rpc_pipe.c | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index b181e34..8322080 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -27,6 +27,9 @@
#include <linux/workqueue.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
#include <linux/sunrpc/cache.h>
+#include <linux/nsproxy.h>
+
+#include "netns.h"
static struct vfsmount *rpc_mnt __read_mostly;
static int rpc_mount_count;
@@ -1006,6 +1009,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode;
struct dentry *root;
+ struct net *net = current->nsproxy->net_ns;
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -1023,6 +1027,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
}
if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
return -ENOMEM;
+ sb->s_fs_info = get_net(net);
return 0;
}
@@ -1033,11 +1038,19 @@ rpc_mount(struct file_system_type *fs_type,
return mount_single(fs_type, flags, data, rpc_fill_super);
}
+void rpc_kill_sb(struct super_block *sb)
+{
+ struct net *net = sb->s_fs_info;
+
+ put_net(net);
+ kill_litter_super(sb);
+}
+
static struct file_system_type rpc_pipe_fs_type = {
.owner = THIS_MODULE,
.name = "rpc_pipefs",
.mount = rpc_mount,
- .kill_sb = kill_litter_super,
+ .kill_sb = rpc_kill_sb,
};
static void
^ permalink raw reply related
* [RFC PATCH 0/5] SUNRPC: "RPC pipefs per network namespace" preparations
From: Stanislav Kinsbursky @ 2011-10-17 13:10 UTC (permalink / raw)
To: Trond.Myklebust
Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, bfields, davem,
devel
Hello to everyone.
RPC pipefs file system have to work per network namespace context is required
prior to any NFS modifications.
This is a way how to do it. I'll really appreciate for any comments.
There are several statements about how to make RPC pipefs working per network
namespace context.
Here they are:
1) RPC pipefs should be mounted per network namespace context.
2) RPC pipefs superblock should holds network namespace while active.
3) RPC pipefs lookup and readir should be perfomed in network namespace context
it was mounted. IOW, user-space process, working in another network namespace
context, should see RPC pipefs dentries from network namespace context this
mount-point was created (like it was done for sysfs).
These statement leads to some restrictions which we must follow during
implementation. Here are they:
1) RPC pipefs mount can't be performed in kernel context since new super block
will holds networks namespace reference and it's impossible to recognize, when
and how we have to release this mount point. IOW rpc_get_mount() and
rpc_put_mount() have to be removed.
2) RPC pipefs should provide some new helpers to lookup directory dentry for
those modules which creates pipes, because without RPC pipefs mount point
general lookup can't be performed.
3) These methods must garantee, that pipefs superblock will be active during
pipes creation and destruction.
So, here is the idea of making RPC pipefs works per network namespace context:
1) RPC pipefs superblock should holds network namespcae context while active.
2) RPC pipefs should send notification events on superblock creation and
destruction.
3) RPC pipefs should provide "lookup dentry by name" method for notification
subscribers.
4) RPC pipefs should place superblock reference on current network namespace
context on creation and remove it on destruction.
5) RPC pipefs should provide safe "lookup dentry by name" method for per-net
operations, which garantees, that superblock is active, while
per-net-operations are performing.
6) Client and cache directories creation and destruction should be performed
also on superblock creation and destruction notification events. Note: generic
creation (like now) can fail (if no superblock is not created yet).
7) Pipes creation and destruction should be performed on superblock creation
and destruction events. Also pipes operations should be performed during
per-net operation and in this case they could fail (due to the same reason as
in statement above).
This patch-set implements first 5 points and thus doesn't affects current RPC
pipefs logic.
The only problem about I'm not sure how to solve properly yet, is auth gss
pipes creations operations. Hoping for some help with it.
The following series consists of:
---
Stanislav Kinsbursky (5):
SUNRPC: hold current network namespace while pipefs superblock is active
SUNRPC: send notification events on pipefs sb creation and destruction
SUNRPC: pipefs dentry lookup helper introduced
SUNRPC: put pipefs superblock link on network namespace
SUNRPC: pipefs per-net operations helper introduced
include/linux/sunrpc/rpc_pipe_fs.h | 16 ++++++
net/sunrpc/netns.h | 3 +
net/sunrpc/rpc_pipe.c | 103 ++++++++++++++++++++++++++++++++++++
net/sunrpc/sunrpc_syms.c | 1
4 files changed, 122 insertions(+), 1 deletions(-)
--
Signature
^ permalink raw reply
* Re: [PATCH] smsc911x: Add regulator support
From: Mark Brown @ 2011-10-17 12:36 UTC (permalink / raw)
To: Robert MARKLUND; +Cc: netdev@vger.kernel.org, Steve Glendinning, Mathieu Poirer
In-Reply-To: <2B1D156D95AE9B4EAD379CB9E465FE7324AB09DE76@EXDCVYMBSTM005.EQ1STM.local>
On Mon, Oct 17, 2011 at 01:30:06PM +0200, Robert MARKLUND wrote:
You should fix your mail client to word wrap within paragraphs, I've
reformatted it for legibility. Also leave a blank line between
paragraphs for the same reason.
> > No, this is broken - look at how other devices use the regulator API.
> > The driver should just request and use the regulators unconditionally
> > and let the stubbing and mapping facilities the API has deal with
> > ensuring that they always succeed.
> So what you mean is get them and use them and ignore all the return
> codes, and let the FW take care of the error handling ?
No, you should do what all the other drivers do and actually pay
attention to the errors. If we can't get power to the device that's a
pretty serious problem and the driver ought to fail.
> > As a side note the use of "pdata" as a name for the driver internal data
> > is really not helpful, pdata is traditionally the platform data passed
> > in by the machine (which would be even more broken).
> In the driver they have used this name for this structure throughout
> the file I just followed that. Personally I think it will be more
> confusing to change the name of this structure in just this new
> function.
I think someone should send a patch renaming the data throughout the
entire driver, it's a terrible name for an embedded context.
^ permalink raw reply
* [net-next 6/6] ixgbe: change the eeprom version reported by ethtool
From: Jeff Kirsher @ 2011-10-17 12:21 UTC (permalink / raw)
To: davem; +Cc: Emil Tantilov, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318854062-3628-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
Use 32bit value starting at offset 0x2d for displaying the firmware
version in ethtool. This should work for all current ixgbe HW
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 3 ++-
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 13 +++++++------
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 ++++---
3 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 9e6635e..4881807 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -518,7 +518,8 @@ struct ixgbe_adapter {
u64 rsc_total_count;
u64 rsc_total_flush;
u32 wol;
- u16 eeprom_version;
+ u16 eeprom_verh;
+ u16 eeprom_verl;
u16 eeprom_cap;
int node;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 7acfce3..70d58c3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -889,21 +889,22 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
char firmware_version[32];
+ u32 nvm_track_id;
strncpy(drvinfo->driver, ixgbe_driver_name,
sizeof(drvinfo->driver) - 1);
strncpy(drvinfo->version, ixgbe_driver_version,
sizeof(drvinfo->version) - 1);
- snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d",
- (adapter->eeprom_version & 0xF000) >> 12,
- (adapter->eeprom_version & 0x0FF0) >> 4,
- adapter->eeprom_version & 0x000F);
+ nvm_track_id = (adapter->eeprom_verh << 16) |
+ adapter->eeprom_verl;
+ snprintf(firmware_version, sizeof(firmware_version), "0x%08x",
+ nvm_track_id);
strncpy(drvinfo->fw_version, firmware_version,
- sizeof(drvinfo->fw_version));
+ sizeof(drvinfo->fw_version) - 1);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
- sizeof(drvinfo->bus_info));
+ sizeof(drvinfo->bus_info) - 1);
drvinfo->n_stats = IXGBE_STATS_LEN;
drvinfo->testinfo_len = IXGBE_TEST_LEN;
drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index c92c3a7..31f4f53 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -8066,6 +8066,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
}
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+ /* save off EEPROM version number */
+ hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh);
+ hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl);
+
/* pick up the PCI bus settings for reporting later */
hw->mac.ops.get_bus_info(hw);
@@ -8115,9 +8119,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
"is required.\n");
}
- /* save off EEPROM version number */
- hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version);
-
/* reset the hardware with the new settings */
err = hw->mac.ops.start_hw(hw);
--
1.7.6.4
^ permalink raw reply related
* [net-next 5/6] ixgbe: add hardware timestamping support
From: Jeff Kirsher @ 2011-10-17 12:21 UTC (permalink / raw)
To: davem; +Cc: Jacob Keller, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318854062-3628-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
Enable hardware offloading of timestamps via the SO_TIMESTAMPING
functionality. Adds support for enabling the hardware cycle counter,
and enabling the SO_TIMESTAMPING method for extracting the hardware
timestamps through the skb.
In the initial version, the cyclecounter structure was not properly
converting the cycles into nanoseconds, due to an incorrectly
calculated incvalue. v3 fixed this issue by recalculating the math and
giving a proper right-shift value to the cycle counter
structure. However, the DMA clock which is used to generate the
cyclecounter register changes frequency based on the link speed. This
version recalculates the incvalue based on the link speed every time
the device changes link speed.
The cyclecounter has the potential to miss a wrap-around of the
systim register (this should occur no more often than every 35
seconds) unless some activity regarding the cycle counter occurs at
least once within this time. This version adds a cycle counter read
every time the watchdog task is run, which should occur at least once
within this timeframe. Any packets being timestamped will also count
as a read due to the call to timecompare_update.
This version fixes an issue regarding timecompare not updating
detected skew after the clock offset is changed due to ptpd or outside
influence from the OS. Now the skew detection is forced just before we
hand a timestamp up to the kernel stack
Signed-off-by: Jacob E Keller <jacob.e.keller@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe.h | 21 ++
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 445 ++++++++++++++++++++++++-
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 32 ++
3 files changed, 497 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 6c4d693..9e6635e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -36,6 +36,10 @@
#include <linux/aer.h>
#include <linux/if_vlan.h>
+#include <linux/clocksource.h>
+#include <linux/timecompare.h>
+#include <linux/net_tstamp.h>
+
#include "ixgbe_type.h"
#include "ixgbe_common.h"
#include "ixgbe_dcb.h"
@@ -103,6 +107,7 @@
#define IXGBE_TX_FLAGS_FSO (u32)(1 << 6)
#define IXGBE_TX_FLAGS_TXSW (u32)(1 << 7)
#define IXGBE_TX_FLAGS_MAPPED_AS_PAGE (u32)(1 << 8)
+#define IXGBE_TX_FLAGS_TSTAMP (u32)(1 << 9)
#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
#define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT 29
@@ -319,6 +324,16 @@ struct ixgbe_q_vector {
char name[IFNAMSIZ + 9];
};
+#define IXGBE_INCVAL_BASE_10GB 32
+#define IXGBE_INCVAL_BASE_1GB 320
+#define IXGBE_INCVAL_BASE_100 3200
+#define IXGBE_INCVAL_SHIFT_10GB 28
+#define IXGBE_INCVAL_SHIFT_1GB 24
+#define IXGBE_INCVAL_SHIFT_100 21
+#define IXGBE_INCVAL_DIVISOR 5
+#define IXGBE_INCVAL_SHIFT_82599 7
+#define IXGBE_INCPER_SHIFT_82599 24
+
/*
* microsecond values for various ITR rates shifted by 2 to fit itr register
* with the first 3 bits reserved 0
@@ -409,6 +424,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5)
#define IXGBE_FLAG2_RESET_REQUESTED (u32)(1 << 6)
#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7)
+#define IXGBE_FLAG2_CYCLECOUNTER_RUNNING (u32)(1 << 8)
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 bd_number;
@@ -464,6 +480,11 @@ struct ixgbe_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
+ struct cyclecounter cycles;
+ struct timecounter clock;
+ struct timecompare compare;
+ struct hwtstamp_config hwtstamp_config;
+
u32 test_icr;
struct ixgbe_ring test_tx_ring;
struct ixgbe_ring test_rx_ring;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index fb7d884..c92c3a7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -135,6 +135,220 @@ MODULE_VERSION(DRV_VERSION);
#define DEFAULT_DEBUG_LEVEL_SHIFT 3
+static cycle_t ixgbe_read_clock(const struct cyclecounter *tc)
+{
+ struct ixgbe_adapter *adapter =
+ container_of(tc, struct ixgbe_adapter, cycles);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 stamp = 0;
+
+
+ stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
+ stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
+
+ return stamp;
+}
+
+/**
+ * ixgbe_init_cyclecounter - initialize the systim cyclecounter
+ * @adapter: pointer to private adapter structure
+ *
+ * We need to call this function every time that the link goes up
+ * because the frequency of the DMA clock changes when the link
+ * speed changes.
+ */
+static void ixgbe_init_cyclecounter(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 incval = 0;
+
+ /*
+ * (re)initialize hardware cycle counter
+ * we keep this running just in case someone wants it
+ * enabled in the future. However, we disable the flag
+ * just in case so that no one tries to read during
+ * the process of initializing.
+ */
+ adapter->flags2 &= ~IXGBE_FLAG2_CYCLECOUNTER_RUNNING;
+
+ /*
+ * 82598EB hardware does not support timestamping,
+ * so we return after making sure the disable
+ * the cyclecounter.
+ */
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ return;
+
+
+ memset(&adapter->cycles, 0, sizeof(adapter->cycles));
+ adapter->cycles.read = ixgbe_read_clock;
+ adapter->cycles.mask = CLOCKSOURCE_MASK(64);
+ adapter->cycles.mult = 1;
+
+ /**
+ * Scale the NIC cycle counter by a large factor so that
+ * relatively small corrections to the frequency can be added
+ * or subtracted. The drawbacks of a large factor include
+ * (a) the clock register overflows more quickly, (b) the cycle
+ * counter structure must be able to convert the systim value
+ * to nanoseconds using only a multiplier and a right-shift,
+ * and (c) the value must fit within the timinca register space
+ * => math based on internal DMA clock rate and available bits
+ */
+ switch (adapter->link_speed) {
+ case IXGBE_LINK_SPEED_100_FULL:
+ incval = IXGBE_INCVAL_BASE_100;
+ incval <<= IXGBE_INCVAL_SHIFT_100;
+ incval /= IXGBE_INCVAL_DIVISOR;
+
+ adapter->cycles.shift = IXGBE_INCVAL_SHIFT_100;
+ break;
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ incval = IXGBE_INCVAL_BASE_1GB;
+ incval <<= IXGBE_INCVAL_SHIFT_1GB;
+ incval /= IXGBE_INCVAL_DIVISOR;
+
+ adapter->cycles.shift = IXGBE_INCVAL_SHIFT_1GB;
+ break;
+ case IXGBE_LINK_SPEED_10GB_FULL:
+ default:
+ incval = IXGBE_INCVAL_BASE_10GB;
+ incval <<= IXGBE_INCVAL_SHIFT_10GB;
+ incval /= IXGBE_INCVAL_DIVISOR;
+
+ adapter->cycles.shift = IXGBE_INCVAL_SHIFT_10GB;
+ break;
+ }
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, (u32)incval);
+ break;
+ case ixgbe_mac_82599EB:
+ incval >>= IXGBE_INCVAL_SHIFT_82599;
+ adapter->cycles.shift -= IXGBE_INCVAL_SHIFT_82599;
+ IXGBE_WRITE_REG(hw, IXGBE_TIMINCA,
+ (1 << IXGBE_INCPER_SHIFT_82599) |
+ (u32)incval);
+ break;
+ default:
+ /* other devices aren't supported */
+ return;
+ }
+
+ /* reset the system time registers */
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000);
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Enable the watchdog task to decect cycle counter overflow */
+ adapter->flags2 |= IXGBE_FLAG2_CYCLECOUNTER_RUNNING;
+
+ /* reset the ns time counter */
+ timecounter_init(&adapter->clock,
+ &adapter->cycles,
+ ktime_to_ns(ktime_get_real()));
+}
+
+/**
+ * ixgbe_systim_to_hwtstamp - convert system time value to hw timestamp
+ * @adapter: board private structure
+ * @shhwtstamps: timestamp structure to update
+ * @regval: unsigned 64bit system time value.
+ *
+ * We need to convert the system time value stored in the RX/TXSTMP registers
+ * into a hwtstamp which can be used by the upper level timestamping functions
+ */
+static void ixgbe_systim_to_hwtstamp(struct ixgbe_adapter *adapter,
+ struct skb_shared_hwtstamps *shhwtstamps,
+ u64 regval)
+{
+ u64 ns;
+
+ /* timestamps aren't valid if the cyclecounter isn't initialized */
+ if (!(adapter->flags2 & IXGBE_FLAG2_CYCLECOUNTER_RUNNING))
+ return;
+
+ ns = timecounter_cyc2time(&adapter->clock, regval);
+
+ /*
+ * force the timecompare structure to detect skew here in
+ * order to prevent the case where the wall clock has been
+ * adjusted by a factor which makes the previous skew
+ * invalid. this prevents us from giving invalid timestamps to
+ * the kernel stack.
+ */
+ timecompare_update(&adapter->compare, 0);
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ shhwtstamps->syststamp = timecompare_transform(&adapter->compare, ns);
+}
+
+/**
+ * ixgbe_tx_hwtstamp - utility function which checks for TX time stamp
+ * @q_vector: pointer to q_vector containing needed info
+ * @buffer: pointer to ixgbe_tx_buffer structure
+ *
+ * If we were asked to do hardware stamping and such a time stamp is
+ * available, then it must have been for this skb here because we only
+ * allow only one such packet into the queue.
+ */
+static void ixgbe_tx_hwtstamp(struct ixgbe_q_vector *q_vector,
+ struct ixgbe_tx_buffer *buffer_info)
+{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct skb_shared_hwtstamps shhwtstamps;
+ u64 regval = 0;
+
+ /* if skb does not support hw timestamp or TX stamp not valid exit */
+ if (likely(!(buffer_info->tx_flags & IXGBE_TX_FLAGS_TSTAMP)) ||
+ !(IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL) & IXGBE_TSYNCTXCTL_VALID))
+ return;
+
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32;
+
+ ixgbe_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
+ skb_tstamp_tx(buffer_info->skb, &shhwtstamps);
+}
+
+/**
+ * ixgbe_rx_hwtstamp - utility function which checks for RX time stamp
+ * @q_vector: pointer to q_vector containing needed info
+ * @skb: pointer to the skb
+ *
+ * If we were asked to do hardware stamping and such a time stamp is
+ * available, then it must have been for this skb here because we only
+ * allow only one such packet into the queue.
+ */
+static void ixgbe_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
+ struct sk_buff *skb)
+{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 regval = 0;
+
+ /*
+ * If this bit is set, then the RX registers contain the time stamp. No
+ * other packet will be time stamped until we read these registers, so
+ * read the registers to make them available again. Because only one
+ * packet can be time stamped at a time, we know that the register
+ * values must belong to this one here and therefore we don't need to
+ * compare any of the additional attributes stored for it.
+ *
+ * If nothing went wrong, then it should have a skb_shared_tx that we
+ * can turn into a skb_shared_hwtstamps.
+ */
+ if (!(IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL) & IXGBE_TSYNCRXCTL_VALID))
+ return;
+
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
+
+ ixgbe_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
+}
+
static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
{
if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
@@ -773,6 +987,9 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
tx_desc->wb.status = 0;
if (likely(tx_desc == eop_desc)) {
eop_desc = NULL;
+
+ ixgbe_tx_hwtstamp(q_vector, tx_buffer);
+
dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL;
@@ -1399,6 +1616,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (adapter->netdev->features & NETIF_F_RXHASH)
ixgbe_rx_hash(rx_desc, skb);
+ if (unlikely(staterr & IXGBE_RXDADV_STAT_TS))
+ ixgbe_rx_hwtstamp(q_vector, skb);
+
/* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len;
total_rx_packets++;
@@ -5841,6 +6061,24 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
}
/**
+ * ixgbe_check_cycle_overflow_subtask - read the clock every
+ * few seconds to prevent the timecounter from losing cycles
+ * due to cycle counter overflow.
+ * @adapter - pointer to the device adapter structure
+ */
+static void ixgbe_check_cycle_overflow_subtask(struct ixgbe_adapter *adapter)
+{
+ u64 ns;
+
+ if (!(adapter->flags2 & IXGBE_FLAG2_CYCLECOUNTER_RUNNING))
+ return;
+
+ /* read the cycle counter and update the clock skew. */
+ ns = timecounter_read(&adapter->clock);
+ timecompare_update(&adapter->compare, ns);
+}
+
+/**
* ixgbe_watchdog_update_link - update the link status
* @adapter - pointer to the device adapter structure
* @link_speed - pointer to a u32 to store the link_speed
@@ -5922,6 +6160,9 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
flow_rx = false;
break;
}
+
+ ixgbe_init_cyclecounter(adapter);
+
e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
(link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
"10 Gbps" :
@@ -6268,6 +6509,7 @@ static void ixgbe_service_task(struct work_struct *work)
ixgbe_watchdog_subtask(adapter);
ixgbe_fdir_reinit_subtask(adapter);
ixgbe_check_hang_subtask(adapter);
+ ixgbe_check_cycle_overflow_subtask(adapter);
ixgbe_service_event_complete(adapter);
}
@@ -6425,6 +6667,9 @@ static __le32 ixgbe_tx_cmd_type(u32 tx_flags)
if (tx_flags & IXGBE_TX_FLAGS_HW_VLAN)
cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_VLE);
+ if (tx_flags & IXGBE_TX_FLAGS_TSTAMP)
+ cmd_type |= cpu_to_le32(IXGBE_ADVTXD_MAC_TSTAMP);
+
/* set segmentation enable bits for TSO/FSO */
#ifdef IXGBE_FCOE
if ((tx_flags & IXGBE_TX_FLAGS_TSO) || (tx_flags & IXGBE_TX_FLAGS_FSO))
@@ -6800,6 +7045,11 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ tx_flags |= IXGBE_TX_FLAGS_TSTAMP;
+ }
+
#ifdef CONFIG_PCI_IOV
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
tx_flags |= IXGBE_TX_FLAGS_TXSW;
@@ -6952,11 +7202,187 @@ static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad,
return hw->phy.ops.write_reg(hw, addr, devad, value);
}
+/**
+ * ixgbe_hwtstamp_ioctl - control hardware time stamping
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ *
+ * Outgoing time stamping can be enabled and disabled. Play nice and
+ * disable it when requested, although it shouldn't case any overhead
+ * when no packet needs it. At most one packet in the queue may be
+ * marked for time stamping, otherwise it would be impossible to tell
+ * for sure to which packet the hardware time stamp belongs.
+ *
+ * Incoming time stamping has to be configured via the hardware
+ * filters. Not all combinations are supported, in particular event
+ * type has to be specified. Matching the kind of event packet is
+ * not supported, with the exception of "all V2 events regardless of
+ * level 2 or 4".
+ *
+ **/
+static int ixgbe_hwtstamp_ioctl(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct hwtstamp_config config;
+ u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
+ u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED;
+ u32 tsync_rx_mtrl = 0;
+ bool is_l4 = false;
+ bool is_l2 = false;
+ u32 regval;
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ tsync_tx_ctl = 0;
+ case HWTSTAMP_TX_ON:
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ tsync_rx_ctl = 0;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG;
+ is_l4 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
+ is_l4 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V2_SYNC_MSG;
+ is_l2 = true;
+ is_l4 = true;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V2_DELAY_REQ_MSG;
+ is_l2 = true;
+ is_l4 = true;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ is_l2 = true;
+ is_l4 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_ALL:
+ default:
+ /*
+ * register RXMTRL must be set, therefore it is not
+ * possible to time stamp both V1 Sync and Delay_Req messages
+ * and hardware does not support timestamping all packets
+ * => return error
+ */
+ return -ERANGE;
+ }
+
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ if (tsync_rx_ctl | tsync_tx_ctl)
+ return -ERANGE;
+ return 0;
+ }
+
+ /* define ethertype filter for timestamped packets */
+ if (is_l2)
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(3),
+ (IXGBE_ETQF_FILTER_EN | /* enable filter */
+ IXGBE_ETQF_1588 | /* enable timestamping */
+ ETH_P_1588)); /* 1588 eth protocol type */
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), 0);
+
+#define PTP_PORT 319
+ /* L4 Queue Filter[3]: filter by destination port and protocol */
+ if (is_l4) {
+ u32 ftqf = (IXGBE_FTQF_PROTOCOL_UDP /* UDP */
+ | IXGBE_FTQF_POOL_MASK_EN /* Pool not compared */
+ | IXGBE_FTQF_QUEUE_ENABLE);
+
+ ftqf |= ((IXGBE_FTQF_PROTOCOL_COMP_MASK /* protocol check */
+ & IXGBE_FTQF_DEST_PORT_MASK /* dest check */
+ & IXGBE_FTQF_SOURCE_PORT_MASK) /* source check */
+ << IXGBE_FTQF_5TUPLE_MASK_SHIFT);
+
+ IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(3),
+ (3 << IXGBE_IMIR_RX_QUEUE_SHIFT_82599 |
+ IXGBE_IMIR_SIZE_BP_82599));
+
+ /* enable port check */
+ IXGBE_WRITE_REG(hw, IXGBE_SDPQF(3),
+ (htons(PTP_PORT) |
+ htons(PTP_PORT) << 16));
+
+ IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), ftqf);
+
+ tsync_rx_mtrl |= PTP_PORT << 16;
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), 0);
+ }
+
+ /* enable/disable TX */
+ regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
+ regval &= ~IXGBE_TSYNCTXCTL_ENABLED;
+ regval |= tsync_tx_ctl;
+ IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval);
+
+ /* enable/disable RX */
+ regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+ regval &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK);
+ regval |= tsync_rx_ctl;
+ IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval);
+
+ /* define which PTP packets are time stamped */
+ IXGBE_WRITE_REG(hw, IXGBE_RXMTRL, tsync_rx_mtrl);
+
+ IXGBE_WRITE_FLUSH(hw);
+
+ adapter->hwtstamp_config = config;
+
+ /* clear TX/RX time stamp registers, just to be sure */
+ regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
+ regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+
static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ return ixgbe_hwtstamp_ioctl(netdev, req, cmd);
+ default:
+ return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
+ }
}
/**
@@ -7643,6 +8069,23 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
/* pick up the PCI bus settings for reporting later */
hw->mac.ops.get_bus_info(hw);
+ /* initialize the cycle counter */
+ ixgbe_init_cyclecounter(adapter);
+
+ /*
+ * Provide a timestamp synchronized against the system wall
+ * clock. NIC time stamp reading requires ~3us per sample,
+ * each sample was pretty stable even under load
+ * => only require 10 samples for each offset comparison.
+ */
+ if (adapter->flags2 & IXGBE_FLAG2_CYCLECOUNTER_RUNNING) {
+ memset(&adapter->compare, 0, sizeof(adapter->compare));
+ adapter->compare.source = &adapter->clock;
+ adapter->compare.target = ktime_get_real;
+ adapter->compare.num_samples = 10;
+ timecompare_update(&adapter->compare, 0);
+ }
+
/* print bus type/speed/width info */
e_dev_info("(PCI Express:%s:%s) %pM\n",
(hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 6c5cca8..8692672 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -1837,6 +1837,36 @@ enum {
#define IXGBE_RXDCTL_RLPML_EN 0x00008000
#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */
+#define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
+#define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */
+
+#define IXGBE_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
+#define IXGBE_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
+#define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00
+#define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02
+#define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
+#define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
+#define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */
+
+#define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF
+#define IXGBE_RXMTRL_V1_SYNC_MSG 0x00
+#define IXGBE_RXMTRL_V1_DELAY_REQ_MSG 0x01
+#define IXGBE_RXMTRL_V1_FOLLOWUP_MSG 0x02
+#define IXGBE_RXMTRL_V1_DELAY_RESP_MSG 0x03
+#define IXGBE_RXMTRL_V1_MGMT_MSG 0x04
+
+#define IXGBE_RXMTRL_V2_MSGID_MASK 0x0000FF00
+#define IXGBE_RXMTRL_V2_SYNC_MSG 0x0000
+#define IXGBE_RXMTRL_V2_DELAY_REQ_MSG 0x0100
+#define IXGBE_RXMTRL_V2_PDELAY_REQ_MSG 0x0200
+#define IXGBE_RXMTRL_V2_PDELAY_RESP_MSG 0x0300
+#define IXGBE_RXMTRL_V2_FOLLOWUP_MSG 0x0800
+#define IXGBE_RXMTRL_V2_DELAY_RESP_MSG 0x0900
+#define IXGBE_RXMTRL_V2_PDELAY_FOLLOWUP_MSG 0x0A00
+#define IXGBE_RXMTRL_V2_ANNOUNCE_MSG 0x0B00
+#define IXGBE_RXMTRL_V2_SIGNALLING_MSG 0x0C00
+#define IXGBE_RXMTRL_V2_MGMT_MSG 0x0D00
+
#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
#define IXGBE_FCTRL_UPE 0x00000200 /* Unicast Promiscuous Ena */
@@ -1966,6 +1996,7 @@ enum {
#define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */
#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
#define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */
+#define IXGBE_RXDADV_STAT_TS 0x00010000 /* IEEE1588 Time Stamp */
/* PSRTYPE bit definitions */
#define IXGBE_PSRTYPE_TCPHDR 0x00000010
@@ -2243,6 +2274,7 @@ struct ixgbe_adv_tx_context_desc {
/* Adv Transmit Descriptor Config Masks */
#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
+#define IXGBE_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 time stamp */
#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
--
1.7.6.4
^ permalink raw reply related
* [net-next 4/6] ixgbe: allow eeprom writes via ethtool
From: Jeff Kirsher @ 2011-10-17 12:21 UTC (permalink / raw)
To: davem; +Cc: Emil Tantilov, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318854062-3628-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
Implement support for ethtool -E
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c | 2 +
drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 71 ++++++++++++++++++++++
2 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index e02e911..ef2afef 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -1305,6 +1305,8 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
.init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eerd_generic,
+ .write = &ixgbe_write_eeprom_generic,
+ .write_buffer = &ixgbe_write_eeprom_buffer_bit_bang_generic,
.read_buffer = &ixgbe_read_eerd_buffer_generic,
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index e102ff6..7acfce3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -814,6 +814,76 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
return ret_val;
}
+static int ixgbe_set_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u16 *eeprom_buff;
+ void *ptr;
+ int max_len, first_word, last_word, ret_val = 0;
+ u16 i;
+
+ if (eeprom->len == 0)
+ return -EINVAL;
+
+ if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+ return -EINVAL;
+
+ max_len = hw->eeprom.word_size * 2;
+
+ first_word = eeprom->offset >> 1;
+ last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+ eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+ if (!eeprom_buff)
+ return -ENOMEM;
+
+ ptr = eeprom_buff;
+
+ if (eeprom->offset & 1) {
+ /*
+ * need read/modify/write of first changed EEPROM word
+ * only the second byte of the word is being modified
+ */
+ ret_val = hw->eeprom.ops.read(hw, first_word, &eeprom_buff[0]);
+ if (ret_val)
+ goto err;
+
+ ptr++;
+ }
+ if ((eeprom->offset + eeprom->len) & 1) {
+ /*
+ * need read/modify/write of last changed EEPROM word
+ * only the first byte of the word is being modified
+ */
+ ret_val = hw->eeprom.ops.read(hw, last_word,
+ &eeprom_buff[last_word - first_word]);
+ if (ret_val)
+ goto err;
+ }
+
+ /* Device's eeprom is always little-endian, word addressable */
+ for (i = 0; i < last_word - first_word + 1; i++)
+ le16_to_cpus(&eeprom_buff[i]);
+
+ memcpy(ptr, bytes, eeprom->len);
+
+ for (i = 0; i < last_word - first_word + 1; i++)
+ cpu_to_le16s(&eeprom_buff[i]);
+
+ ret_val = hw->eeprom.ops.write_buffer(hw, first_word,
+ last_word - first_word + 1,
+ eeprom_buff);
+
+ /* Update the checksum */
+ if (ret_val == 0)
+ hw->eeprom.ops.update_checksum(hw);
+
+err:
+ kfree(eeprom_buff);
+ return ret_val;
+}
+
static void ixgbe_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
@@ -2524,6 +2594,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_eeprom_len = ixgbe_get_eeprom_len,
.get_eeprom = ixgbe_get_eeprom,
+ .set_eeprom = ixgbe_set_eeprom,
.get_ringparam = ixgbe_get_ringparam,
.set_ringparam = ixgbe_set_ringparam,
.get_pauseparam = ixgbe_get_pauseparam,
--
1.7.6.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