* Re: [net-next 0/6][pull request] Intel Wired LAN Driver Updates
From: David Miller @ 2012-09-17 16:44 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: matthew.vick, netdev, gospo, sassmann
In-Reply-To: <1347873709-2190-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Mon, 17 Sep 2012 02:21:43 -0700
> The following are changes since commit ba01dfe18241bf89b058fd8a60218b218ad2bb30:
> Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
> and are available in the git repository at:
> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master
>
> Matthew Vick (6):
> igb: Tidy up wrapping for CONFIG_IGB_PTP.
> igb: Update PTP function names/variables and locations.
> igb: Correct PTP support query from ethtool.
> igb: Store the MAC address in the name in the PTP struct.
> igb: Prevent dropped Tx timestamps via work items and interrupts.
> igb: Add 1588 support to I210/I211.
Pulled, thanks for fixing this up.
^ permalink raw reply
* RE: [net] e1000: Small packets may get corrupted during padding by HW
From: Dave, Tushar N @ 2012-09-17 16:39 UTC (permalink / raw)
To: David Miller
Cc: Fastabend, John R, mirqus@gmail.com, Kirsher, Jeffrey T,
netdev@vger.kernel.org, gospo@redhat.com, sassmann@redhat.com
In-Reply-To: <20120917.123113.458101376016589070.davem@davemloft.net>
>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
>On Behalf Of David Miller
>Sent: Monday, September 17, 2012 9:31 AM
>To: Dave, Tushar N
>Cc: Fastabend, John R; mirqus@gmail.com; Kirsher, Jeffrey T;
>netdev@vger.kernel.org; gospo@redhat.com; sassmann@redhat.com
>Subject: Re: [net] e1000: Small packets may get corrupted during padding
>by HW
>
>From: "Dave, Tushar N" <tushar.n.dave@intel.com>
>Date: Mon, 17 Sep 2012 07:33:12 +0000
>
>> No because it is quite normal to have packet < ETH_ZLEN. e.g. ARP
>packets.
>
>You're optimizing for ARP packets? You're kidding right?
ARP packet was just an example. I should have thought of better example.
^ permalink raw reply
* Re: [net] e1000: Small packets may get corrupted during padding by HW
From: David Miller @ 2012-09-17 16:31 UTC (permalink / raw)
To: tushar.n.dave
Cc: john.r.fastabend, mirqus, jeffrey.t.kirsher, netdev, gospo,
sassmann
In-Reply-To: <061C8A8601E8EE4CA8D8FD6990CEA89130DC3631@ORSMSX102.amr.corp.intel.com>
From: "Dave, Tushar N" <tushar.n.dave@intel.com>
Date: Mon, 17 Sep 2012 07:33:12 +0000
> No because it is quite normal to have packet < ETH_ZLEN. e.g. ARP packets.
You're optimizing for ARP packets? You're kidding right?
^ permalink raw reply
* Re: [PATCH] ncm: allow for NULL terminations
From: Alan Cox @ 2012-09-17 16:31 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev
In-Reply-To: <1347896724.2685.2.camel@bwh-desktop.uk.solarflarecom.com>
On Mon, 17 Sep 2012 16:45:24 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:
> On Mon, 2012-09-17 at 11:58 +0100, Alan Cox wrote:
> > From: Alan Cox <alan@linux.intel.com>
> >
> > The strings are passed to snprintf so must be null terminated. It seems the
> > copy length is incorrectly set.
>
> Please use strlcpy() instead. (I thought someone had already gone round
> the get_drvinfo implementations and fixed them to do that, actually.)
There are still plenty of them. I'm just noting they are one out. I'm
doing a first pass over a whole pile of stuff so if you'd prefer it in a
different form treat it as a note to the maintainer than their code is
buggy as I probably won't be back round to it for a couple of months
judging by the size of the audit pile I'm working down.
Alan
^ permalink raw reply
* Re: interrupt coalescing and CSUM offload
From: Stephen Hemminger @ 2012-09-17 16:18 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: netdev
In-Reply-To: <OFF8862166.946F925C-ONC1257A7A.00386AD8-C1257A7A.0042C1CF@transmode.se>
On Sat, 15 Sep 2012 14:09:09 +0200
Joakim Tjernlund <joakim.tjernlund@transmode.se> wrote:
> Stephen Hemminger <shemminger@vyatta.com> wrote on 2012/09/14 18:32:52:
> >
> > On Fri, 14 Sep 2012 16:35:13 +0200
> > Joakim Tjernlund <joakim.tjernlund@transmode.se> wrote:
> >
> > >
> > > I am adding interrupt coalescing to the ucc_geth driver. Unfortunately
> > > there is only support for RX interrupt coalescing.
> > > I wonder if there is any way "simulate" TX interrupt coalescing?
> > >
> > > I am also looking at adding HWCSUM support but this device can only do
> > > IP header CSUM offload. This doesn't seem to be an option in Linux?
> > > As I understand it, one must do CSUM offload for the whole frame, both
> > > IP header and TCP/UDP csums?
> > >
> > > Jocke
> >
> > There are a few drivers that turn off TX interrupt completely.
> > They cleanup TX buffers on next send and have a timer to cleanup
>
> Only on send? Currently ucc_geth does TX free in napi(where RX is processed too).
> It would be nice if one could indicate to the drivers xmit() if there
> are more frames to be sent. Then xmit() could choose not to turn on TX irq for
> preceding frames.
> > as well. This has performance benefits, but it does cause issues
> > with local flow control (the freeing of skb is used to rate
> > limit local traffic).
>
> Was my reasoning correct w.r.t CSUM?
>
I header checksum is useless to Linux. The IP header is so short that
it is already in the CPU cache and costs nothing to compute or check.
The only checksuming that matters is the data (TCP or UDP).
^ permalink raw reply
* Re: [RFC] tcp: use order-3 pages in tcp_sendmsg()
From: David Miller @ 2012-09-17 16:12 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <1347868144.26523.71.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 17 Sep 2012 09:49:04 +0200
> 2) Use order-3 pages (or order-0 pages if page size is >= 32768)
We could do with an audit to make sure drivers (and the stack in
general) can handle SKB frags of length > PAGE_SIZE.
I have no idea whether such problems might actually exist, but
I can say it's a case that gets not so much testing.
^ permalink raw reply
* Re: [patch net] sky2: fix rx filter setup on link up
From: Stephen Hemminger @ 2012-09-17 16:12 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev, davem, mlindner, linux-kernel
In-Reply-To: <1347894617-13614-1-git-send-email-jiri@resnulli.us>
On Mon, 17 Sep 2012 17:10:17 +0200
Jiri Pirko <jiri@resnulli.us> wrote:
> In my case I have following problem. sky2_set_multicast() sets registers
> GM_MC_ADDR_H[1-4] correctly to:
> 0000 0800 0001 0410
> However, when adapter gets link and sky2_link_up() is called, the values
> are for some reason different:
> 0000 0800 0016 0410
Rather than papering over the problem, it would be better to
trace back what is setting those registers and fix that code.
> This in my case prevents iface to be able to receive packets with dst mac
> 01:80:C2:00:00:02 (LACPDU dst mac), which I set up previously by
> SIOCADDMULTI.
>
> So remember computed rx_filter data and write it to GM_MC_ADDR_H[1-4] on
> link_up.
>
Please do some more root cause analysis. Just save/restoring the
registers is just a temporary workaround.
^ permalink raw reply
* D-Link DGE-530T and r8169.c
From: James R. Hay @ 2012-09-17 15:51 UTC (permalink / raw)
To: romieu, nic_swsd; +Cc: netdev
Good morning,
It appears that D-Link has changed the ID of the DGE-530T NIC from
1186:4300: to 1186:4302: which means the RTL8169 driver in the linux
kernel does not recognize newer DGE-530T cards.
At link 199 of r8169.c is the following:
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 },
While I changed the 0x4300 to 0x4302 and recompiled the kernel to get the
driver to recognize the card I believe that the appropriate fix would be
to add the following line immediately after:
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 },
Since I only have the one machine here on which to test this driver I am
hoping that any further testing needed can be done by someone so that this
can make its way inte the kernel source code.
Jim.
James R. Hay jrhay@HayA.QC.CA
Hay-Net Networks http://www.hay-net.net
P.O. Box 46051
Pointe Claire, QC
H9R 5R4
^ permalink raw reply
* Re: [PATCH] ncm: allow for NULL terminations
From: Ben Hutchings @ 2012-09-17 15:45 UTC (permalink / raw)
To: Alan Cox; +Cc: netdev
In-Reply-To: <20120917105853.30298.29234.stgit@localhost.localdomain>
On Mon, 2012-09-17 at 11:58 +0100, Alan Cox wrote:
> From: Alan Cox <alan@linux.intel.com>
>
> The strings are passed to snprintf so must be null terminated. It seems the
> copy length is incorrectly set.
Please use strlcpy() instead. (I thought someone had already gone round
the get_drvinfo implementations and fixed them to do that, actually.)
Ben.
> Signed-off-by: Alan Cox <alan@linux.intel.com>
> ---
>
> drivers/net/usb/cdc_ncm.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
> index 4cd582a..af8cce7 100644
> --- a/drivers/net/usb/cdc_ncm.c
> +++ b/drivers/net/usb/cdc_ncm.c
> @@ -145,10 +145,10 @@ cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
> {
> struct usbnet *dev = netdev_priv(net);
>
> - strncpy(info->driver, dev->driver_name, sizeof(info->driver));
> - strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
> + strncpy(info->driver, dev->driver_name, sizeof(info->driver) - 1);
> + strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
> strncpy(info->fw_version, dev->driver_info->description,
> - sizeof(info->fw_version));
> + sizeof(info->fw_version) - 1);
> usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
> }
>
>
--
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
* Possible networking regression in 3.6.0
From: Chris Clayton @ 2012-09-17 15:44 UTC (permalink / raw)
To: netdev
Hi,
I'm having a problem with networking. I'm running Windows XP as a KVM
guest on a laptop running kernel 3.6.0-rc6. The identical configuration
works fine with kernels 3.5.4 and 3.4.11 (and has done so, largely
unchanged, since since KVM was introduced in 2.6.<whatever>.)
The configuration is:
XP guest: 192.168.200.1 (gateway 192.168.200.254)
tap0: 192.168.200.254
host: 192.168.0.40 (gateway 192.168.0.1)
router: 192.168.0.1
The script that starts up the firewall includes the following commands:
# Load the connection-sharing for qemu/kvm guests
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
...
# allow traffic to and from the qemu/kvm virtual networks
NETS="200 201"
for net in $NETS; do
iptables -A INPUT -s 192.168.$net.0/24 -j ACCEPT
iptables -A OUTPUT -d 192.168.$net.0/24 -j ACCEPT
done
...
The network-related modules that are loaded are:
$ lsmod
Module Size Used by
tun 12412 0
xt_state 891 1
iptable_filter 852 1
ipt_MASQUERADE 1222 1
iptable_nat 3087 1
nf_nat 10901 2 ipt_MASQUERADE,iptable_nat
nf_conntrack_ipv4 4942 4 nf_nat,iptable_nat
nf_defrag_ipv4 815 1 nf_conntrack_ipv4
nf_conntrack 37644 5
ipt_MASQUERADE,nf_nat,xt_state,iptable_nat,nf_conntrack_ipv4
...
r8169 47159 0
From the host I can successfully ping the guest, tap0 and the router as
you would expect, but from the guest, although I can ping the host and
tap0, I cannot ping the router. In practice, this means I have no
internet access from the guest. As I say, this configuration works
perfectly under 3.5.x and 3.4.x kernels.
I'll do a coarse-grained "bisect" of Linus' 3.6 release candidates and
report back, but does anyone have any prime-suspect patches that may be
at the cause of this problem?
Let me know if there are any other diagnostics I can provide. Also, as
I'm not subscribed to netdev, please cc me to any reply.
Thanks,
Chris
^ permalink raw reply
* Re: Regarding group_forward_mask in bridge in 3.4 kernel
From: John Fastabend @ 2012-09-17 15:24 UTC (permalink / raw)
To: Ajith Adapa; +Cc: netdev, Stephen Hemminger
In-Reply-To: <CADAe=++yAm3t-ZqMKy9h-Rda5=pOYQD2-cKUd3S1VKmBZQfT9A@mail.gmail.com>
On 9/17/2012 7:43 AM, Ajith Adapa wrote:
> Hi,
>
> I am trying to enable group_fwd_mask in bridge by giving the below
> command so that it can forward provider bpdu's whose destination
> address is 01-80-C2-00-00-08.
>
> echo 8 > /sys/class/net/vpc1_br/bridge/group_fwd_mask
>
wrong value see the logic you quoted use 1 << 8
echo 256 > /sys/class/net/...
Your example fwds non-TPMR addresses 01-80-c2-00-00-03.
[...]
> Am I giving wrong value for group_fwd_mask ??
Yep wrong value.
> I tried other values but seems only 8 and 0 is accepted.
The logic makes an attempt to restrict forwarding by masking 0x4007u,
catching many known control protocols.
See commit for details,
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=515853ccecc6987dfb8ed809dd8bf8900286f29e
.John
^ permalink raw reply
* Re: NULL deref in bnx2 / crashes ? ( was: netconsole leads to stalled CPU task )
From: Cong Wang @ 2012-09-17 15:17 UTC (permalink / raw)
To: Sylvain Munaut; +Cc: Eric Dumazet, netdev
In-Reply-To: <CAF6-1L4VaG4JAK0kYYizMvhBcaUM5x3uatA7JpzZqzcJ+fmGww@mail.gmail.com>
On 09/17/2012 06:57 PM, Sylvain Munaut wrote:
> Hi,
>
>>> Anyway, I think Eric is right, the bug may be in other place. I am wondering
>>> if the attached patch could help? It seems in netpoll tx path, we miss the
>>> chance of calling ->ndo_select_queue().
>>>
>>> Please give it a try.
>>
>> This fixes the NULL deref as well. I applied your patch over vanilla
>> 3.6-rc5 (so without eric's patch) and I can load netconsole without it
>> crashing directly.
>>
>> I will try to put a bit of load on the machine and see how it behaves,
>> if it solves the hung cpu tasks as well.
>
> So far so good, the machine is still alive and well after 3 days with
> netconsole enabled.
>
Great!
Thanks a lot for testing, Sylvain! I will post the patch tomorrow, as I
need some sleep now. :)
^ permalink raw reply
* [patch net] sky2: fix rx filter setup on link up
From: Jiri Pirko @ 2012-09-17 15:10 UTC (permalink / raw)
To: netdev; +Cc: davem, mlindner, shemminger, linux-kernel
In my case I have following problem. sky2_set_multicast() sets registers
GM_MC_ADDR_H[1-4] correctly to:
0000 0800 0001 0410
However, when adapter gets link and sky2_link_up() is called, the values
are for some reason different:
0000 0800 0016 0410
This in my case prevents iface to be able to receive packets with dst mac
01:80:C2:00:00:02 (LACPDU dst mac), which I set up previously by
SIOCADDMULTI.
So remember computed rx_filter data and write it to GM_MC_ADDR_H[1-4] on
link_up.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
---
drivers/net/ethernet/marvell/sky2.c | 30 ++++++++++++++++++++++--------
drivers/net/ethernet/marvell/sky2.h | 2 ++
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 2b0748d..5293ff4 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -2186,6 +2186,8 @@ static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
}
}
+static void sky2_write_rx_filter(struct sky2_port *sky2, u8 *filter);
+
static void sky2_link_up(struct sky2_port *sky2)
{
struct sky2_hw *hw = sky2->hw;
@@ -2211,6 +2213,9 @@ static void sky2_link_up(struct sky2_port *sky2)
sky2_write8(hw, SK_REG(port, LNK_LED_REG),
LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
+ /* Refresh RX filter */
+ sky2_write_rx_filter(sky2, sky2->rx_filter);
+
netif_info(sky2, link, sky2->netdev,
"Link is up at %d Mbps, %s duplex, flow control %s\n",
sky2->speed,
@@ -3849,6 +3854,21 @@ static inline void sky2_add_filter(u8 filter[8], const u8 *addr)
filter[bit >> 3] |= 1 << (bit & 7);
}
+static void sky2_write_rx_filter(struct sky2_port *sky2, u8 *filter)
+{
+ struct sky2_hw *hw = sky2->hw;
+ unsigned port = sky2->port;
+
+ gma_write16(hw, port, GM_MC_ADDR_H1,
+ (u16) filter[0] | ((u16) filter[1] << 8));
+ gma_write16(hw, port, GM_MC_ADDR_H2,
+ (u16) filter[2] | ((u16) filter[3] << 8));
+ gma_write16(hw, port, GM_MC_ADDR_H3,
+ (u16) filter[4] | ((u16) filter[5] << 8));
+ gma_write16(hw, port, GM_MC_ADDR_H4,
+ (u16) filter[6] | ((u16) filter[7] << 8));
+}
+
static void sky2_set_multicast(struct net_device *dev)
{
struct sky2_port *sky2 = netdev_priv(dev);
@@ -3882,14 +3902,8 @@ static void sky2_set_multicast(struct net_device *dev)
sky2_add_filter(filter, ha->addr);
}
- gma_write16(hw, port, GM_MC_ADDR_H1,
- (u16) filter[0] | ((u16) filter[1] << 8));
- gma_write16(hw, port, GM_MC_ADDR_H2,
- (u16) filter[2] | ((u16) filter[3] << 8));
- gma_write16(hw, port, GM_MC_ADDR_H3,
- (u16) filter[4] | ((u16) filter[5] << 8));
- gma_write16(hw, port, GM_MC_ADDR_H4,
- (u16) filter[6] | ((u16) filter[7] << 8));
+ sky2_write_rx_filter(sky2, filter);
+ memcpy(sky2->rx_filter, filter, sizeof(sky2->rx_filter));
gma_write16(hw, port, GM_RX_CTRL, reg);
}
diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h
index 615ac63..513c266 100644
--- a/drivers/net/ethernet/marvell/sky2.h
+++ b/drivers/net/ethernet/marvell/sky2.h
@@ -2272,6 +2272,8 @@ struct sky2_port {
#ifdef CONFIG_SKY2_DEBUG
struct dentry *debugfs;
#endif
+
+ u8 rx_filter[8];
};
struct sky2_hw {
--
1.7.11.4
^ permalink raw reply related
* Re: [RFT] sky2: fix status length check on older chips
From: Ivan Minev @ 2012-09-17 14:20 UTC (permalink / raw)
To: netdev
In-Reply-To: <20120427135514.48b03ce8@nehalam.linuxnetplumber.net>
Still vlan don't work and have rx lenght errors chipset:88E8072 rev 10
^ permalink raw reply
* Regarding group_forward_mask in bridge in 3.4 kernel
From: Ajith Adapa @ 2012-09-17 14:43 UTC (permalink / raw)
To: netdev; +Cc: Stephen Hemminger
Hi,
I am trying to enable group_fwd_mask in bridge by giving the below
command so that it can forward provider bpdu's whose destination
address is 01-80-C2-00-00-08.
echo 8 > /sys/class/net/vpc1_br/bridge/group_fwd_mask
But still the provider BPDU's are dropped by the bridge. After some
debugging I have found that logic in br_input.c has some issue
switch (dest[5]) {
case 0x00: /* Bridge Group Address */
/* If STP is turned off,
then must forward to keep loop detection */
if (p->br->stp_enabled == BR_NO_STP)
goto forward;
break;
case 0x01: /* IEEE MAC (Pause) */
goto drop;
default:
/* Allow selective forwarding for most other
protocols */
if (p->br->group_fwd_mask & (1u << dest[5]))
goto forward;
}
In my case dest[5] is 8 and p->br->group_fwd_mask is 8. The default
case is triggered but the expression in if condition
is always ZERO as a result BPDU is not forwarded.
Am I giving wrong value for group_fwd_mask ?? I tried other values but
seems only 8 and 0 is accepted.
Regards,
Ajith
^ permalink raw reply
* Re: [PATCH] Xen backend support for paged out grant targets V4.
From: Konrad Rzeszutek Wilk @ 2012-09-17 13:32 UTC (permalink / raw)
To: Andres Lagar-Cavilla, davem
Cc: Ian Campbell, Andres Lagar-Cavilla, xen-devel, David Vrabel,
David Miller, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org
In-Reply-To: <5B5132A4-93B2-41D0-B1A6-048810565DB5@gridcentric.ca>
> >> Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
> >
> > Acked-by: Ian Campbell <ian.campbell@citrix.com>
> >
> > Since this is more about grant tables than netback this should probably
> > go via Konrad rather than Dave, is that OK with you Dave?
>
> If that is the case hopefully Konrad can deal with the two typos? Otherwise happy to re-spin the patch.
Sure. Just waiting for an Ack from David.
^ permalink raw reply
* Warning! Your mailbox is almost full.
From: Webmail Account Upgrade @ 2012-09-17 13:07 UTC (permalink / raw)
You have exceeded your email limit quota of 450MB. You need to upgrade
your email limit quota to 2GB within the next 48 hours. Use the below
web link to upgrade your email account:
click link below:
http://www.formchamp.com/goform.php?id=38467
Thank you for using our email.
Copyright ©2012 Email Helpdesk Centre.
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
^ permalink raw reply
* Re: [RFC PATCH 3/3] usbnet: support runtime PM triggered by link change
From: Ming Lei @ 2012-09-17 13:07 UTC (permalink / raw)
To: Oliver Neukum
Cc: David S. Miller, Greg Kroah-Hartman, Fink Dmitry, Rafael Wysocki,
Alan Stern, netdev, linux-usb
In-Reply-To: <3287943.Bzm0t1oGWG@linux-lqwf.site>
On Mon, Sep 17, 2012 at 4:50 PM, Oliver Neukum <oneukum@suse.de> wrote:
> On Sunday 16 September 2012 01:48:19 Ming Lei wrote:
>
>
>> +void usbnet_link_updated(struct usbnet *dev)
>> +{
>> + complete(&dev->link_update_completion);
>> +}
>> +EXPORT_SYMBOL_GPL(usbnet_link_updated);
>
> Isn't that a bit too trivial to get the _GPL version?
OK, will use the non GPL version.
>
>> +#define usbnet_link_suspend(dev) do { \
>> + dev_dbg(&dev->intf->dev, "%s:link suspend", __func__); \
>> + usb_autopm_put_interface_async(dev->intf); \
>> +} while(0)
>> +
>> +#define usbnet_link_resume(dev) do { \
>> + dev_dbg(&dev->intf->dev, "%s:link resume", __func__); \
>> + usb_autopm_get_interface_async(dev->intf); \
>> +} while(0)
>
> Why macros?
Just for easy debug by dumping the caller function name.
>
>
> [..]
>> +/* called by usbnet_open */
>> +static void enable_link_runtime_pm(struct usbnet *dev)
>> +{
>> + dev->link_rpm_enabled = 1;
>> +
>> + if (!dev->link_remote_wakeup) {
>> + dev->old_autosuspend_delay =
>> + dev->udev->dev.power.autosuspend_delay;
>> + pm_runtime_set_autosuspend_delay(&dev->udev->dev, 1);
>
> This is a problem. Suppose the user changes the autosuspend timeout.
> You cannot assume that the old value remains valid.
Good catch, I will fix it in -v1 by reading again the timeout value in
disable_link_runtime_pm().
>> + }
>> +
>> + if (!netif_carrier_ok(dev->net)) {
>> + dev->link_open_suspend = 1;
>> + usbnet_link_suspend(dev);
>> + }
>> +}
>
>> +static void update_link_state(struct usbnet *dev)
>> +{
>> + char *buf = NULL;
>> + unsigned pipe = 0;
>> + unsigned maxp;
>> + int ret, act_len, timeout;
>> + struct urb urb;
>> +
>> + pipe = usb_rcvintpipe(dev->udev,
>> + dev->status->desc.bEndpointAddress
>> + & USB_ENDPOINT_NUMBER_MASK);
>> + maxp = usb_maxpacket(dev->udev, pipe, 0);
>> +
>> + /*
>> + * Take default timeout as 2 times of period.
>> + * It is observed that asix device can update its link
>> + * state duing one period(128ms). Low level driver can set
>> + * its default update link time in bind() callback.
>> + */
>> + if (!dev->link_update_timeout) {
>> + timeout = max((int) dev->status->desc.bInterval,
>> + (dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
>> + timeout = 1 << timeout;
>> + if (dev->udev->speed == USB_SPEED_HIGH)
>> + timeout /= 8;
>> + if (timeout < 128)
>> + timeout = 128;
>> + } else
>> + timeout = dev->link_update_timeout;
>> +
>> + buf = kmalloc(maxp, GFP_KERNEL);
>> + if (!buf)
>> + return;
>> +
>> + dev_dbg(&dev->intf->dev, "%s: timeout %dms\n", __func__, timeout);
>> + ret = usb_interrupt_msg(dev->udev, pipe, buf, maxp,
>> + &act_len, timeout);
>> + if (!ret) {
>> + urb.status = 0;
>> + urb.actual_length = act_len;
>> + urb.transfer_buffer = buf;
>> + urb.transfer_buffer_length = maxp;
>> + dev->driver_info->status(dev, &urb);
>> + if (dev->driver_info->flags &
>> + FLAG_LINK_UPDATE_BY_DRIVER)
>> + wait_for_completion(&dev->link_update_completion);
>
> If a driver calls usbnet_link_updated() from the same workqueue this
> will deadlock.
Good catch, I will fix it in -v1 by using system_freezable_wq.
>
>> + dev_dbg(&dev->intf->dev, "%s: link updated\n", __func__);
>> + } else
>> + dev_dbg(&dev->intf->dev, "%s: link update failed %d\n",
>> + __func__, ret);
>> + kfree(buf);
>> +}
>
> [..]
>> @@ -795,6 +977,9 @@ int usbnet_open (struct net_device *net)
>> if (retval < 0)
>> goto done_manage_power_error;
>> usb_autopm_put_interface(dev->intf);
>> + } else {
>> + if (need_link_runtime_pm(dev))
>> + enable_link_runtime_pm(dev);
>> }
>> return retval;
>>
>> @@ -1489,6 +1674,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
>> if (dev->driver_info->flags & FLAG_LINK_INTR)
>> usbnet_link_change(dev, 0, 0);
>>
>> + init_link_rpm(dev);
>> +
>> return 0;
>>
>> out4:
>> @@ -1538,6 +1725,9 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
>> * wake the device
>> */
>> netif_device_attach (dev->net);
>> +
>> + if (PMSG_IS_AUTO(message))
>> + start_link_detect(dev);
>
> What happens if the device is autosuspended, then the system is suspended
> and the work is executed while the suspension is underway?
IMO we can avoid the problem by scheduling 'link_detect_work' on the
workqueue of 'system_freezable_wq', which will be introduced in -v1.
>
>> }
>> return 0;
>> }
>> @@ -1552,8 +1742,10 @@ int usbnet_resume (struct usb_interface *intf)
>>
>> if (!--dev->suspend_count) {
>> /* resume interrupt URBs */
>> - if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags))
>> - usb_submit_urb(dev->interrupt, GFP_NOIO);
>> + if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags)) {
>> + if (!dev->link_checking)
>
> That is impossible. If the device is resumed the interrupt URB must
> be restarted in every case (if it exists).
The interrupt URB will be submitted later in link_detect_work() under
the situation of being resumed by link detect work.
> You cannot assume that its only function is checking the link state.
> And it introduces a race with the workqueue.
Looks no race because usbnet_resume() will be run in workqueue
task context under the situation of being resumed by link detect work.
Thanks,
--
Ming Lei
^ permalink raw reply
* Re: [RFC PATCH 3/3] usbnet: support runtime PM triggered by link change
From: Greg Kroah-Hartman @ 2012-09-17 11:15 UTC (permalink / raw)
To: David Laight
Cc: Oliver Neukum, Ming Lei, David S. Miller, Fink Dmitry,
Rafael Wysocki, Alan Stern, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B6FF0-CgBM+Bx2aUAnGFn1LkZF6NBPR1lH4CV8@public.gmane.org>
On Mon, Sep 17, 2012 at 10:02:27AM +0100, David Laight wrote:
> > > +void usbnet_link_updated(struct usbnet *dev)
> > > +{
> > > + complete(&dev->link_update_completion);
> > > +}
> > > +EXPORT_SYMBOL_GPL(usbnet_link_updated);
> >
> > Isn't that a bit too trivial to get the _GPL version?
>
> Particularly if the usb infrastructure (that I presume this
> is part of) might be reasonably usable by non-gpl drivers.
It can not be, and has not been able to, for quite a number of years now
(since the 2.6.15 kernel release or so I think.) So this should not be
an issue.
greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: NULL deref in bnx2 / crashes ? ( was: netconsole leads to stalled CPU task )
From: Sylvain Munaut @ 2012-09-17 10:57 UTC (permalink / raw)
To: Cong Wang; +Cc: Eric Dumazet, netdev
In-Reply-To: <CAF6-1L42ZLSm4SMRSoz6ZwDKRpfRhwQmN3R5D7kjmjqRLn=2xg@mail.gmail.com>
Hi,
>> Anyway, I think Eric is right, the bug may be in other place. I am wondering
>> if the attached patch could help? It seems in netpoll tx path, we miss the
>> chance of calling ->ndo_select_queue().
>>
>> Please give it a try.
>
> This fixes the NULL deref as well. I applied your patch over vanilla
> 3.6-rc5 (so without eric's patch) and I can load netconsole without it
> crashing directly.
>
> I will try to put a bit of load on the machine and see how it behaves,
> if it solves the hung cpu tasks as well.
So far so good, the machine is still alive and well after 3 days with
netconsole enabled.
Cheers,
Sylvain
^ permalink raw reply
* [PATCH] ncm: allow for NULL terminations
From: Alan Cox @ 2012-09-17 10:58 UTC (permalink / raw)
To: netdev
From: Alan Cox <alan@linux.intel.com>
The strings are passed to snprintf so must be null terminated. It seems the
copy length is incorrectly set.
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/net/usb/cdc_ncm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 4cd582a..af8cce7 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -145,10 +145,10 @@ cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
{
struct usbnet *dev = netdev_priv(net);
- strncpy(info->driver, dev->driver_name, sizeof(info->driver));
- strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
+ strncpy(info->driver, dev->driver_name, sizeof(info->driver) - 1);
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
strncpy(info->fw_version, dev->driver_info->description,
- sizeof(info->fw_version));
+ sizeof(info->fw_version) - 1);
usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
}
^ permalink raw reply related
* [PATCH] af_unux: old_cred is surplus
From: Alan Cox @ 2012-09-17 10:52 UTC (permalink / raw)
To: netdev
From: Alan Cox <alan@linux.intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
net/unix/af_unix.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 8a84ab6..5b5c876 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -441,7 +441,7 @@ static int unix_release_sock(struct sock *sk, int embrion)
/* ---- Socket is dead now and most probably destroyed ---- */
/*
- * Fixme: BSD difference: In BSD all sockets connected to use get
+ * Fixme: BSD difference: In BSD all sockets connected to us get
* ECONNRESET and we die on the spot. In Linux we behave
* like files and pipes do and wait for the last
* dereference.
@@ -481,7 +481,6 @@ static int unix_listen(struct socket *sock, int backlog)
struct sock *sk = sock->sk;
struct unix_sock *u = unix_sk(sk);
struct pid *old_pid = NULL;
- const struct cred *old_cred = NULL;
err = -EOPNOTSUPP;
if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
@@ -503,8 +502,6 @@ static int unix_listen(struct socket *sock, int backlog)
out_unlock:
unix_state_unlock(sk);
put_pid(old_pid);
- if (old_cred)
- put_cred(old_cred);
out:
return err;
}
^ permalink raw reply related
* Re: [PATCH] Xen backend support for paged out grant targets V4.
From: Andres Lagar-Cavilla @ 2012-09-17 9:29 UTC (permalink / raw)
To: Ian Campbell
Cc: Andres Lagar-Cavilla, xen-devel, Konrad Rzeszutek Wilk,
David Vrabel, David Miller, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org
In-Reply-To: <1347869865.14977.15.camel@zakaz.uk.xensource.com>
On Sep 17, 2012, at 4:17 AM, Ian Campbell wrote:
> (I think I forgot to hit send on this on Friday, sorry. Also
> s/xen.lists.org/lists.xen.org in the CC line…)
I'm on a roll here…
>
> On Fri, 2012-09-14 at 15:26 +0100, Andres Lagar-Cavilla wrote:
>> Since Xen-4.2, hvm domains may have portions of their memory paged out. When a
>> foreign domain (such as dom0) attempts to map these frames, the map will
>> initially fail. The hypervisor returns a suitable errno, and kicks an
>> asynchronous page-in operation carried out by a helper. The foreign domain is
>> expected to retry the mapping operation until it eventually succeeds. The
>> foreign domain is not put to sleep because itself could be the one running the
>> pager assist (typical scenario for dom0).
>>
>> This patch adds support for this mechanism for backend drivers using grant
>> mapping and copying operations. Specifically, this covers the blkback and
>> gntdev drivers (which map foregin grants), and the netback driver (which copies
>
> foreign
>
>> foreign grants).
>>
>> * Add a retry method for grants that fail with GNTST_eagain (i.e. because the
>> target foregin frame is paged out).
>
> foreign
>
>> * Insert hooks with appropriate wrappers in the aforementioned drivers.
>>
>> The retry loop is only invoked if the grant operation status is GNTST_eagain.
>> It guarantees to leave a new status code different from GNTST_eagain. Any other
>> status code results in identical code execution as before.
>>
>> The retry loop performs 256 attempts with increasing time intervals through a
>> 32 second period. It uses msleep to yield while waiting for the next retry.
> [...]
>> Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>
>
> Since this is more about grant tables than netback this should probably
> go via Konrad rather than Dave, is that OK with you Dave?
If that is the case hopefully Konrad can deal with the two typos? Otherwise happy to re-spin the patch.
Thanks!
Andres
>
> (there's one more typo below)
>
>> ---
>> drivers/net/xen-netback/netback.c | 11 ++------
>> drivers/xen/grant-table.c | 53 ++++++++++++++++++++++++++++++++++++
>> drivers/xen/xenbus/xenbus_client.c | 6 ++--
>> include/xen/grant_table.h | 12 ++++++++
>> 4 files changed, 70 insertions(+), 12 deletions(-)
> [...]
>> diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
>> index 11e27c3..da9386e 100644
>> --- a/include/xen/grant_table.h
>> +++ b/include/xen/grant_table.h
>> @@ -189,4 +189,16 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
>> int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
>> struct page **pages, unsigned int count, bool clear_pte);
>>
>> +/* Perform a batch of grant map/copy operations. Retry every batch slot
>> + * for which the hypervisor returns GNTST_eagain. This is typically due
>> + * to paged out target frames.
>> + *
>> + * Will retry for 1, 2, ... 255 ms, i.e. 256 times during 32 seconds.
>> + *
>> + * Return value in each iand every status field of the batch guaranteed
>
> and
>
>> + * to not be GNTST_eagain.
>> + */
>> +void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count);
>> +void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count);
>> +
>> #endif /* __ASM_GNTTAB_H__ */
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [net-next 6/6] igb: Add 1588 support to I210/I211.
From: Jeff Kirsher @ 2012-09-17 9:21 UTC (permalink / raw)
To: davem; +Cc: Matthew Vick, netdev, gospo, sassmann, Richard Cochran,
Jeff Kirsher
In-Reply-To: <1347873709-2190-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Matthew Vick <matthew.vick@intel.com>
Previously I210/I211 followed the same code flow as 82580/I350 for 1588.
However, since the register sets have changed, we must update the
implementation to accommodate the register changes.
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Matthew Vick <matthew.vick@intel.com>
Acked-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/igb/e1000_defines.h | 3 +
drivers/net/ethernet/intel/igb/igb_ptp.c | 216 +++++++++++++++++++------
2 files changed, 174 insertions(+), 45 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 0b27e8f..cae3070 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -322,6 +322,9 @@
#define E1000_FCRTC_RTH_COAL_SHIFT 4
#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision */
+/* Timestamp in Rx buffer */
+#define E1000_RXPBS_CFG_TS_EN 0x80000000
+
/* SerDes Control */
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index d57060c..e13ba1d 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -121,6 +121,41 @@ static cycle_t igb_ptp_read_82580(const struct cyclecounter *cc)
return val;
}
+/*
+ * SYSTIM read access for I210/I211
+ */
+
+static void igb_ptp_read_i210(struct igb_adapter *adapter, struct timespec *ts)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 sec, nsec, jk;
+
+ /*
+ * The timestamp latches on lowest register read. For I210/I211, the
+ * lowest register is SYSTIMR. Since we only need to provide nanosecond
+ * resolution, we can ignore it.
+ */
+ jk = rd32(E1000_SYSTIMR);
+ nsec = rd32(E1000_SYSTIML);
+ sec = rd32(E1000_SYSTIMH);
+
+ ts->tv_sec = sec;
+ ts->tv_nsec = nsec;
+}
+
+static void igb_ptp_write_i210(struct igb_adapter *adapter,
+ const struct timespec *ts)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ /*
+ * Writing the SYSTIMR register is not necessary as it only provides
+ * sub-nanosecond resolution.
+ */
+ wr32(E1000_SYSTIML, ts->tv_nsec);
+ wr32(E1000_SYSTIMH, ts->tv_sec);
+}
+
/**
* igb_ptp_systim_to_hwtstamp - convert system time value to hw timestamp
* @adapter: board private structure
@@ -146,24 +181,28 @@ static void igb_ptp_systim_to_hwtstamp(struct igb_adapter *adapter,
u64 ns;
switch (adapter->hw.mac.type) {
+ case e1000_82576:
+ case e1000_82580:
+ case e1000_i350:
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+
+ ns = timecounter_cyc2time(&adapter->tc, systim);
+
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+ memset(hwtstamps, 0, sizeof(*hwtstamps));
+ hwtstamps->hwtstamp = ns_to_ktime(ns);
+ break;
case e1000_i210:
case e1000_i211:
- case e1000_i350:
- case e1000_82580:
- case e1000_82576:
+ memset(hwtstamps, 0, sizeof(*hwtstamps));
+ /* Upper 32 bits contain s, lower 32 bits contain ns. */
+ hwtstamps->hwtstamp = ktime_set(systim >> 32,
+ systim & 0xFFFFFFFF);
break;
default:
- return;
+ break;
}
-
- spin_lock_irqsave(&adapter->tmreg_lock, flags);
-
- ns = timecounter_cyc2time(&adapter->tc, systim);
-
- spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
-
- memset(hwtstamps, 0, sizeof(*hwtstamps));
- hwtstamps->hwtstamp = ns_to_ktime(ns);
}
/*
@@ -225,7 +264,7 @@ static int igb_ptp_adjfreq_82580(struct ptp_clock_info *ptp, s32 ppb)
return 0;
}
-static int igb_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+static int igb_ptp_adjtime_82576(struct ptp_clock_info *ptp, s64 delta)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
@@ -243,7 +282,26 @@ static int igb_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
return 0;
}
-static int igb_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+static int igb_ptp_adjtime_i210(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
+ ptp_caps);
+ unsigned long flags;
+ struct timespec now, then = ns_to_timespec(delta);
+
+ spin_lock_irqsave(&igb->tmreg_lock, flags);
+
+ igb_ptp_read_i210(igb, &now);
+ now = timespec_add(now, then);
+ igb_ptp_write_i210(igb, (const struct timespec *)&now);
+
+ spin_unlock_irqrestore(&igb->tmreg_lock, flags);
+
+ return 0;
+}
+
+static int igb_ptp_gettime_82576(struct ptp_clock_info *ptp,
+ struct timespec *ts)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
@@ -263,8 +321,24 @@ static int igb_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
return 0;
}
-static int igb_ptp_settime(struct ptp_clock_info *ptp,
- const struct timespec *ts)
+static int igb_ptp_gettime_i210(struct ptp_clock_info *ptp,
+ struct timespec *ts)
+{
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
+ ptp_caps);
+ unsigned long flags;
+
+ spin_lock_irqsave(&igb->tmreg_lock, flags);
+
+ igb_ptp_read_i210(igb, ts);
+
+ spin_unlock_irqrestore(&igb->tmreg_lock, flags);
+
+ return 0;
+}
+
+static int igb_ptp_settime_82576(struct ptp_clock_info *ptp,
+ const struct timespec *ts)
{
struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
ptp_caps);
@@ -283,6 +357,22 @@ static int igb_ptp_settime(struct ptp_clock_info *ptp,
return 0;
}
+static int igb_ptp_settime_i210(struct ptp_clock_info *ptp,
+ const struct timespec *ts)
+{
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
+ ptp_caps);
+ unsigned long flags;
+
+ spin_lock_irqsave(&igb->tmreg_lock, flags);
+
+ igb_ptp_write_i210(igb, ts);
+
+ spin_unlock_irqrestore(&igb->tmreg_lock, flags);
+
+ return 0;
+}
+
static int igb_ptp_enable(struct ptp_clock_info *ptp,
struct ptp_clock_request *rq, int on)
{
@@ -320,7 +410,7 @@ static void igb_ptp_overflow_check(struct work_struct *work)
container_of(work, struct igb_adapter, ptp_overflow_work.work);
struct timespec ts;
- igb_ptp_gettime(&igb->ptp_caps, &ts);
+ igb->ptp_caps.gettime(&igb->ptp_caps, &ts);
pr_debug("igb overflow check at %ld.%09lu\n", ts.tv_sec, ts.tv_nsec);
@@ -506,6 +596,13 @@ int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
if ((hw->mac.type >= e1000_82580) && tsync_rx_ctl) {
tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
+
+ if ((hw->mac.type == e1000_i210) ||
+ (hw->mac.type == e1000_i211)) {
+ regval = rd32(E1000_RXPBS);
+ regval |= E1000_RXPBS_CFG_TS_EN;
+ wr32(E1000_RXPBS, regval);
+ }
}
/* enable/disable TX */
@@ -556,7 +653,9 @@ int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
wrfl();
/* clear TX/RX time stamp registers, just to be sure */
+ regval = rd32(E1000_TXSTMPL);
regval = rd32(E1000_TXSTMPH);
+ regval = rd32(E1000_RXSTMPL);
regval = rd32(E1000_RXSTMPH);
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
@@ -569,19 +668,35 @@ void igb_ptp_init(struct igb_adapter *adapter)
struct net_device *netdev = adapter->netdev;
switch (hw->mac.type) {
- case e1000_i210:
- case e1000_i211:
- case e1000_i350:
+ case e1000_82576:
+ snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
+ adapter->ptp_caps.owner = THIS_MODULE;
+ adapter->ptp_caps.max_adj = 1000000000;
+ adapter->ptp_caps.n_ext_ts = 0;
+ adapter->ptp_caps.pps = 0;
+ adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82576;
+ adapter->ptp_caps.adjtime = igb_ptp_adjtime_82576;
+ adapter->ptp_caps.gettime = igb_ptp_gettime_82576;
+ adapter->ptp_caps.settime = igb_ptp_settime_82576;
+ adapter->ptp_caps.enable = igb_ptp_enable;
+ adapter->cc.read = igb_ptp_read_82576;
+ adapter->cc.mask = CLOCKSOURCE_MASK(64);
+ adapter->cc.mult = 1;
+ adapter->cc.shift = IGB_82576_TSYNC_SHIFT;
+ /* Dial the nominal frequency. */
+ wr32(E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576);
+ break;
case e1000_82580:
+ case e1000_i350:
snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
adapter->ptp_caps.owner = THIS_MODULE;
adapter->ptp_caps.max_adj = 62499999;
adapter->ptp_caps.n_ext_ts = 0;
adapter->ptp_caps.pps = 0;
adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580;
- adapter->ptp_caps.adjtime = igb_ptp_adjtime;
- adapter->ptp_caps.gettime = igb_ptp_gettime;
- adapter->ptp_caps.settime = igb_ptp_settime;
+ adapter->ptp_caps.adjtime = igb_ptp_adjtime_82576;
+ adapter->ptp_caps.gettime = igb_ptp_gettime_82576;
+ adapter->ptp_caps.settime = igb_ptp_settime_82576;
adapter->ptp_caps.enable = igb_ptp_enable;
adapter->cc.read = igb_ptp_read_82580;
adapter->cc.mask = CLOCKSOURCE_MASK(IGB_NBITS_82580);
@@ -590,23 +705,20 @@ void igb_ptp_init(struct igb_adapter *adapter)
/* Enable the timer functions by clearing bit 31. */
wr32(E1000_TSAUXC, 0x0);
break;
- case e1000_82576:
+ case e1000_i210:
+ case e1000_i211:
snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
adapter->ptp_caps.owner = THIS_MODULE;
- adapter->ptp_caps.max_adj = 1000000000;
+ adapter->ptp_caps.max_adj = 62499999;
adapter->ptp_caps.n_ext_ts = 0;
adapter->ptp_caps.pps = 0;
- adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82576;
- adapter->ptp_caps.adjtime = igb_ptp_adjtime;
- adapter->ptp_caps.gettime = igb_ptp_gettime;
- adapter->ptp_caps.settime = igb_ptp_settime;
+ adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82580;
+ adapter->ptp_caps.adjtime = igb_ptp_adjtime_i210;
+ adapter->ptp_caps.gettime = igb_ptp_gettime_i210;
+ adapter->ptp_caps.settime = igb_ptp_settime_i210;
adapter->ptp_caps.enable = igb_ptp_enable;
- adapter->cc.read = igb_ptp_read_82576;
- adapter->cc.mask = CLOCKSOURCE_MASK(64);
- adapter->cc.mult = 1;
- adapter->cc.shift = IGB_82576_TSYNC_SHIFT;
- /* Dial the nominal frequency. */
- wr32(E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576);
+ /* Enable the timer functions by clearing bit 31. */
+ wr32(E1000_TSAUXC, 0x0);
break;
default:
adapter->ptp_clock = NULL;
@@ -615,17 +727,24 @@ void igb_ptp_init(struct igb_adapter *adapter)
wrfl();
- timecounter_init(&adapter->tc, &adapter->cc,
- ktime_to_ns(ktime_get_real()));
+ spin_lock_init(&adapter->tmreg_lock);
+ INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
- INIT_DELAYED_WORK(&adapter->ptp_overflow_work, igb_ptp_overflow_check);
+ /* Initialize the clock and overflow work for devices that need it. */
+ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) {
+ struct timespec ts = ktime_to_timespec(ktime_get_real());
- spin_lock_init(&adapter->tmreg_lock);
+ igb_ptp_settime_i210(&adapter->ptp_caps, &ts);
+ } else {
+ timecounter_init(&adapter->tc, &adapter->cc,
+ ktime_to_ns(ktime_get_real()));
- INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
+ INIT_DELAYED_WORK(&adapter->ptp_overflow_work,
+ igb_ptp_overflow_check);
- schedule_delayed_work(&adapter->ptp_overflow_work,
- IGB_SYSTIM_OVERFLOW_PERIOD);
+ schedule_delayed_work(&adapter->ptp_overflow_work,
+ IGB_SYSTIM_OVERFLOW_PERIOD);
+ }
/* Initialize the time sync interrupts for devices that support it. */
if (hw->mac.type >= e1000_82580) {
@@ -708,6 +827,13 @@ void igb_ptp_reset(struct igb_adapter *adapter)
return;
}
- timecounter_init(&adapter->tc, &adapter->cc,
- ktime_to_ns(ktime_get_real()));
+ /* Re-initialize the timer. */
+ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) {
+ struct timespec ts = ktime_to_timespec(ktime_get_real());
+
+ igb_ptp_settime_i210(&adapter->ptp_caps, &ts);
+ } else {
+ timecounter_init(&adapter->tc, &adapter->cc,
+ ktime_to_ns(ktime_get_real()));
+ }
}
--
1.7.11.4
^ permalink raw reply related
* [net-next 5/6] igb: Prevent dropped Tx timestamps via work items and interrupts.
From: Jeff Kirsher @ 2012-09-17 9:21 UTC (permalink / raw)
To: davem; +Cc: Matthew Vick, netdev, gospo, sassmann, Richard Cochran,
Jeff Kirsher
In-Reply-To: <1347873709-2190-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Matthew Vick <matthew.vick@intel.com>
In rare circumstances, it's possible a descriptor writeback will occur
before a timestamped Tx packet will go out on the wire, leading to the
driver believing the hardware failed to timestamp the packet. Schedule a
work item for 82576 and use the available time sync interrupt registers
on 82580 and above to account for this.
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Matthew Vick <matthew.vick@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/igb/e1000_defines.h | 5 ++
drivers/net/ethernet/intel/igb/e1000_regs.h | 2 +
drivers/net/ethernet/intel/igb/igb.h | 8 +-
drivers/net/ethernet/intel/igb/igb_main.c | 61 +++++++++++++--
drivers/net/ethernet/intel/igb/igb_ptp.c | 102 +++++++++++++++++++++----
5 files changed, 153 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index ec7e4fe..0b27e8f 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -360,6 +360,7 @@
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
+#define E1000_ICR_TS 0x00080000 /* Time Sync Interrupt */
#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
@@ -399,6 +400,7 @@
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
+#define E1000_IMS_TS E1000_ICR_TS /* Time Sync Interrupt */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
@@ -510,6 +512,9 @@
#define E1000_TIMINCA_16NS_SHIFT 24
+#define E1000_TSICR_TXTS 0x00000002
+#define E1000_TSIM_TXTS 0x00000002
+
#define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */
#define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */
#define E1000_MDICNFG_PHY_MASK 0x03E00000
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 28394be..faec840 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -91,6 +91,8 @@
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
+#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
+#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
/* Filtering Registers */
#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 7973469..43c8e29 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -381,6 +381,8 @@ struct igb_adapter {
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
struct delayed_work ptp_overflow_work;
+ struct work_struct ptp_tx_work;
+ struct sk_buff *ptp_tx_skb;
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
@@ -394,6 +396,7 @@ struct igb_adapter {
#define IGB_FLAG_QUAD_PORT_A (1 << 2)
#define IGB_FLAG_QUEUE_PAIRS (1 << 3)
#define IGB_FLAG_DMAC (1 << 4)
+#define IGB_FLAG_PTP (1 << 5)
/* DMA Coalescing defines */
#define IGB_MIN_TXPBSIZE 20408
@@ -440,8 +443,9 @@ extern void igb_set_fw_version(struct igb_adapter *);
#ifdef CONFIG_IGB_PTP
extern void igb_ptp_init(struct igb_adapter *adapter);
extern void igb_ptp_stop(struct igb_adapter *adapter);
-extern void igb_ptp_tx_hwtstamp(struct igb_q_vector *q_vector,
- struct igb_tx_buffer *buffer_info);
+extern void igb_ptp_reset(struct igb_adapter *adapter);
+extern void igb_ptp_tx_work(struct work_struct *work);
+extern void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter);
extern void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector,
union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb);
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 6e39f0c..19d7666 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1751,6 +1751,11 @@ void igb_reset(struct igb_adapter *adapter)
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
+#ifdef CONFIG_IGB_PTP
+ /* Re-enable PTP, where applicable. */
+ igb_ptp_reset(adapter);
+#endif /* CONFIG_IGB_PTP */
+
igb_get_phy_info(hw);
}
@@ -4234,7 +4239,7 @@ static __le32 igb_tx_cmd_type(u32 tx_flags)
#ifdef CONFIG_IGB_PTP
/* set timestamp bit if present */
- if (tx_flags & IGB_TX_FLAGS_TSTAMP)
+ if (unlikely(tx_flags & IGB_TX_FLAGS_TSTAMP))
cmd_type |= cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP);
#endif /* CONFIG_IGB_PTP */
@@ -4445,6 +4450,9 @@ static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, const u16 size)
netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
struct igb_ring *tx_ring)
{
+#ifdef CONFIG_IGB_PTP
+ struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
+#endif /* CONFIG_IGB_PTP */
struct igb_tx_buffer *first;
int tso;
u32 tx_flags = 0;
@@ -4468,9 +4476,14 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
first->gso_segs = 1;
#ifdef CONFIG_IGB_PTP
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+ !(adapter->ptp_tx_skb))) {
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
tx_flags |= IGB_TX_FLAGS_TSTAMP;
+
+ adapter->ptp_tx_skb = skb_get(skb);
+ if (adapter->hw.mac.type == e1000_82576)
+ schedule_work(&adapter->ptp_tx_work);
}
#endif /* CONFIG_IGB_PTP */
@@ -4859,6 +4872,19 @@ static irqreturn_t igb_msix_other(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
+#ifdef CONFIG_IGB_PTP
+ if (icr & E1000_ICR_TS) {
+ u32 tsicr = rd32(E1000_TSICR);
+
+ if (tsicr & E1000_TSICR_TXTS) {
+ /* acknowledge the interrupt */
+ wr32(E1000_TSICR, E1000_TSICR_TXTS);
+ /* retrieve hardware timestamp */
+ schedule_work(&adapter->ptp_tx_work);
+ }
+ }
+#endif /* CONFIG_IGB_PTP */
+
wr32(E1000_EIMS, adapter->eims_other);
return IRQ_HANDLED;
@@ -5650,6 +5676,19 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
+#ifdef CONFIG_IGB_PTP
+ if (icr & E1000_ICR_TS) {
+ u32 tsicr = rd32(E1000_TSICR);
+
+ if (tsicr & E1000_TSICR_TXTS) {
+ /* acknowledge the interrupt */
+ wr32(E1000_TSICR, E1000_TSICR_TXTS);
+ /* retrieve hardware timestamp */
+ schedule_work(&adapter->ptp_tx_work);
+ }
+ }
+#endif /* CONFIG_IGB_PTP */
+
napi_schedule(&q_vector->napi);
return IRQ_HANDLED;
@@ -5691,6 +5730,19 @@ static irqreturn_t igb_intr(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
+#ifdef CONFIG_IGB_PTP
+ if (icr & E1000_ICR_TS) {
+ u32 tsicr = rd32(E1000_TSICR);
+
+ if (tsicr & E1000_TSICR_TXTS) {
+ /* acknowledge the interrupt */
+ wr32(E1000_TSICR, E1000_TSICR_TXTS);
+ /* retrieve hardware timestamp */
+ schedule_work(&adapter->ptp_tx_work);
+ }
+ }
+#endif /* CONFIG_IGB_PTP */
+
napi_schedule(&q_vector->napi);
return IRQ_HANDLED;
@@ -5794,11 +5846,6 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
total_bytes += tx_buffer->bytecount;
total_packets += tx_buffer->gso_segs;
-#ifdef CONFIG_IGB_PTP
- /* retrieve hardware timestamp */
- igb_ptp_tx_hwtstamp(q_vector, tx_buffer);
-#endif /* CONFIG_IGB_PTP */
-
/* free the skb */
dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index e69555f..d57060c 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -289,6 +289,31 @@ static int igb_ptp_enable(struct ptp_clock_info *ptp,
return -EOPNOTSUPP;
}
+/**
+ * igb_ptp_tx_work
+ * @work: pointer to work struct
+ *
+ * This work function polls the TSYNCTXCTL valid bit to determine when a
+ * timestamp has been taken for the current stored skb.
+ */
+void igb_ptp_tx_work(struct work_struct *work)
+{
+ struct igb_adapter *adapter = container_of(work, struct igb_adapter,
+ ptp_tx_work);
+ struct e1000_hw *hw = &adapter->hw;
+ u32 tsynctxctl;
+
+ if (!adapter->ptp_tx_skb)
+ return;
+
+ tsynctxctl = rd32(E1000_TSYNCTXCTL);
+ if (tsynctxctl & E1000_TSYNCTXCTL_VALID)
+ igb_ptp_tx_hwtstamp(adapter);
+ else
+ /* reschedule to check later */
+ schedule_work(&adapter->ptp_tx_work);
+}
+
static void igb_ptp_overflow_check(struct work_struct *work)
{
struct igb_adapter *igb =
@@ -305,31 +330,25 @@ static void igb_ptp_overflow_check(struct work_struct *work)
/**
* igb_ptp_tx_hwtstamp - utility function which checks for TX time stamp
- * @q_vector: pointer to q_vector containing needed info
- * @buffer: pointer to igb_tx_buffer structure
+ * @adapter: Board private 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.
*/
-void igb_ptp_tx_hwtstamp(struct igb_q_vector *q_vector,
- struct igb_tx_buffer *buffer_info)
+void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
{
- struct igb_adapter *adapter = q_vector->adapter;
struct e1000_hw *hw = &adapter->hw;
struct skb_shared_hwtstamps shhwtstamps;
u64 regval;
- /* if skb does not support hw timestamp or TX stamp not valid exit */
- if (likely(!(buffer_info->tx_flags & IGB_TX_FLAGS_TSTAMP)) ||
- !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
- return;
-
regval = rd32(E1000_TXSTMPL);
regval |= (u64)rd32(E1000_TXSTMPH) << 32;
igb_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
- skb_tstamp_tx(buffer_info->skb, &shhwtstamps);
+ skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
+ dev_kfree_skb_any(adapter->ptp_tx_skb);
+ adapter->ptp_tx_skb = NULL;
}
void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector,
@@ -603,16 +622,26 @@ void igb_ptp_init(struct igb_adapter *adapter)
spin_lock_init(&adapter->tmreg_lock);
+ INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work);
+
schedule_delayed_work(&adapter->ptp_overflow_work,
IGB_SYSTIM_OVERFLOW_PERIOD);
+ /* Initialize the time sync interrupts for devices that support it. */
+ if (hw->mac.type >= e1000_82580) {
+ wr32(E1000_TSIM, E1000_TSIM_TXTS);
+ wr32(E1000_IMS, E1000_IMS_TS);
+ }
+
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps);
if (IS_ERR(adapter->ptp_clock)) {
adapter->ptp_clock = NULL;
dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n");
- } else
+ } else {
dev_info(&adapter->pdev->dev, "added PHC on %s\n",
adapter->netdev->name);
+ adapter->flags |= IGB_FLAG_PTP;
+ }
}
/**
@@ -624,20 +653,61 @@ void igb_ptp_init(struct igb_adapter *adapter)
void igb_ptp_stop(struct igb_adapter *adapter)
{
switch (adapter->hw.mac.type) {
- case e1000_i211:
- case e1000_i210:
- case e1000_i350:
- case e1000_82580:
case e1000_82576:
+ case e1000_82580:
+ case e1000_i350:
cancel_delayed_work_sync(&adapter->ptp_overflow_work);
break;
+ case e1000_i210:
+ case e1000_i211:
+ /* No delayed work to cancel. */
+ break;
default:
return;
}
+ cancel_work_sync(&adapter->ptp_tx_work);
+
if (adapter->ptp_clock) {
ptp_clock_unregister(adapter->ptp_clock);
dev_info(&adapter->pdev->dev, "removed PHC on %s\n",
adapter->netdev->name);
+ adapter->flags &= ~IGB_FLAG_PTP;
}
}
+
+/**
+ * igb_ptp_reset - Re-enable the adapter for PTP following a reset.
+ * @adapter: Board private structure.
+ *
+ * This function handles the reset work required to re-enable the PTP device.
+ **/
+void igb_ptp_reset(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (!(adapter->flags & IGB_FLAG_PTP))
+ return;
+
+ switch (adapter->hw.mac.type) {
+ case e1000_82576:
+ /* Dial the nominal frequency. */
+ wr32(E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576);
+ break;
+ case e1000_82580:
+ case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
+ /* Enable the timer functions and interrupts. */
+ wr32(E1000_TSAUXC, 0x0);
+ wr32(E1000_TSIM, E1000_TSIM_TXTS);
+ wr32(E1000_IMS, E1000_IMS_TS);
+ break;
+ default:
+ /* No work to do. */
+ return;
+ }
+
+ timecounter_init(&adapter->tc, &adapter->cc,
+ ktime_to_ns(ktime_get_real()));
+}
--
1.7.11.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