Netdev List
 help / color / mirror / Atom feed
* [PATCH 04/10] net: cleanup vlan_features setting in register_netdev
From: Michał Mirosław @ 2011-07-14  0:10 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy
In-Reply-To: <cover.1310601401.git.mirq-linux@rere.qmqm.pl>

vlan_features contains features inherited from underlying device.
NETIF_SOFT_FEATURES are not inherited but belong to the vlan device
itself (ensured in vlan_dev_fix_features()).

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 net/core/dev.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 9ca1514..e57be02 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5488,12 +5488,9 @@ int register_netdevice(struct net_device *dev)
 		dev->features |= NETIF_F_NOCACHE_COPY;
 	}
 
-	/* Enable GSO, GRO and NETIF_F_HIGHDMA for vlans by default,
-	 * vlan_dev_fix_features() will do the features check,
-	 * so NETIF_F_HIGHDMA feature is enabled only if supported
-	 * by underlying device.
+	/* Make NETIF_F_HIGHDMA inheritable to VLAN devices.
 	 */
-	dev->vlan_features |= (NETIF_F_SOFT_FEATURES | NETIF_F_HIGHDMA);
+	dev->vlan_features |= NETIF_F_HIGHDMA;
 
 	ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev);
 	ret = notifier_to_errno(ret);
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH 02/10] net: m68k/nfeth: Remove wrong usage of dev->flags
From: Michał Mirosław @ 2011-07-14  0:10 UTC (permalink / raw)
  To: netdev; +Cc: Geert Uytterhoeven, linux-m68k
In-Reply-To: <cover.1310601401.git.mirq-linux@rere.qmqm.pl>

Remove wrong setting of dev->flags. NETIF_F_NO_CSUM maps to IFF_DEBUG
there, so looks like a mistake.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 arch/m68k/emu/nfeth.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
index 3c55312..c5748bb 100644
--- a/arch/m68k/emu/nfeth.c
+++ b/arch/m68k/emu/nfeth.c
@@ -205,7 +205,6 @@ static struct net_device * __init nfeth_probe(int unit)
 	dev->irq = nfEtherIRQ;
 	dev->netdev_ops = &nfeth_netdev_ops;
 
-	dev->flags |= NETIF_F_NO_CSUM;
 	memcpy(dev->dev_addr, mac, ETH_ALEN);
 
 	priv = netdev_priv(dev);
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH 01/10] net: sctp: fix checksum marking for outgoing packets
From: Michał Mirosław @ 2011-07-14  0:10 UTC (permalink / raw)
  To: netdev; +Cc: Vlad Yasevich, Sridhar Samudrala, linux-sctp
In-Reply-To: <cover.1310601401.git.mirq-linux@rere.qmqm.pl>

Packets to devices without NETIF_F_SCTP_CSUM (including NETIF_F_NO_CSUM)
should be properly checksummed because the packets can be diverted or
rerouted after construction. This still leaves packets diverted from
NETIF_F_SCTP_CSUM-enabled devices with broken checksums. Fixing this
needs implementing software offload fallback in networking core.

For users of sctp_checksum_disable, skb->ip_summed should be left as
CHECKSUM_NONE and not CHECKSUM_UNNECESSARY as per include/linux/skbuff.h.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 net/sctp/output.c |   19 ++++++++-----------
 1 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/net/sctp/output.c b/net/sctp/output.c
index b4f3cf0..08b3cea 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -500,23 +500,20 @@ int sctp_packet_transmit(struct sctp_packet *packet)
 	 * Note: Adler-32 is no longer applicable, as has been replaced
 	 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
 	 */
-	if (!sctp_checksum_disable &&
-	    !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
-		__u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
+	if (!sctp_checksum_disable) {
+		if (!(dst->dev->features & NETIF_F_SCTP_CSUM)) {
+			__u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
 
-		/* 3) Put the resultant value into the checksum field in the
-		 *    common header, and leave the rest of the bits unchanged.
-		 */
-		sh->checksum = sctp_end_cksum(crc32);
-	} else {
-		if (dst->dev->features & NETIF_F_SCTP_CSUM) {
+			/* 3) Put the resultant value into the checksum field in the
+			 *    common header, and leave the rest of the bits unchanged.
+			 */
+			sh->checksum = sctp_end_cksum(crc32);
+		} else {
 			/* no need to seed pseudo checksum for SCTP */
 			nskb->ip_summed = CHECKSUM_PARTIAL;
 			nskb->csum_start = (skb_transport_header(nskb) -
 			                    nskb->head);
 			nskb->csum_offset = offsetof(struct sctphdr, checksum);
-		} else {
-			nskb->ip_summed = CHECKSUM_UNNECESSARY;
 		}
 	}
 
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH 03/10] net: vlan: remove reduntant check in ndo_fix_features callback
From: Michał Mirosław @ 2011-07-14  0:10 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy
In-Reply-To: <cover.1310601401.git.mirq-linux@rere.qmqm.pl>

Use the fact that ORing with zero is a no-op.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 net/8021q/vlan_dev.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index d8f45ba..7f67f2e 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -593,8 +593,7 @@ static u32 vlan_dev_fix_features(struct net_device *dev, u32 features)
 	features &= real_dev->features;
 	features &= real_dev->vlan_features;
 
-	if (old_features & NETIF_F_SOFT_FEATURES)
-		features |= old_features & NETIF_F_SOFT_FEATURES;
+	features |= old_features & NETIF_F_SOFT_FEATURES;
 
 	if (dev_ethtool_get_rx_csum(real_dev))
 		features |= NETIF_F_RXCSUM;
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH 00/10] net: random cleanups
From: Michał Mirosław @ 2011-07-14  0:10 UTC (permalink / raw)
  To: netdev

This is a set of random cleanups accumulated while digging through the
network device drivers. Only patches that don't depend on removing
old ethtool ops are included here.

The series consists of patches that can be applied independently from
others from the set. The exception is patch #7 that depends on removing
NETIF_F_NO_CSUM references in patches 1, 2 and 5.

---

Michał Mirosław (10):
  net: sctp: fix checksum marking for outgoing packets
  net: m68k/nfeth: Remove wrong usage of dev->flags
  net: vlan: remove reduntant check in ndo_fix_features callback
  net: cleanup vlan_features setting in register_netdev
  net: Disable NOCACHE_COPY by default
  net: remove NETIF_F_ALL_TX_OFFLOADS
  net: remove NETIF_F_NO_CSUM feature
  net: unexport netdev_fix_features()
  net: remove /sys/class/net/*/features
  net: remove SK_ROUTE_CAPS from meta ematch

 arch/m68k/emu/nfeth.c                |    1 -
 drivers/ieee802154/fakehard.c        |    2 +-
 drivers/misc/sgi-xp/xpnet.c          |    2 +-
 drivers/net/bonding/bond_main.c      |    8 ++++----
 drivers/net/can/dev.c                |    2 +-
 drivers/net/can/slcan.c              |    2 +-
 drivers/net/dummy.c                  |    2 +-
 drivers/net/ifb.c                    |    2 +-
 drivers/net/loopback.c               |    2 +-
 drivers/net/veth.c                   |    2 +-
 include/linux/netdevice.h            |   10 +---------
 include/linux/skbuff.h               |    1 -
 include/linux/tc_ematch/tc_em_meta.h |    2 +-
 net/8021q/vlan_dev.c                 |   11 +++++++----
 net/bridge/br_device.c               |    4 ++--
 net/core/dev.c                       |   33 +++++++++------------------------
 net/core/ethtool.c                   |    2 +-
 net/core/net-sysfs.c                 |    2 --
 net/sched/em_meta.c                  |    7 -------
 net/sctp/output.c                    |   19 ++++++++-----------
 20 files changed, 41 insertions(+), 75 deletions(-)

-- 
1.7.5.4


^ permalink raw reply

* Re: [Bugme-new] [Bug 39252] New: [r8169] PPPoE connections don't work if a custom MAC address is assigned
From: Andrew Morton @ 2011-07-13 23:13 UTC (permalink / raw)
  To: netdev; +Cc: bugme-daemon, t.artem, Michal Ostrowski
In-Reply-To: <bug-39252-10286@https.bugzilla.kernel.org/>


(switched to email.  Please respond via emailed reply-to-all, not via the
bugzilla web interface).

On Tue, 12 Jul 2011 22:51:16 GMT
bugzilla-daemon@bugzilla.kernel.org wrote:

> https://bugzilla.kernel.org/show_bug.cgi?id=39252
> 
>            Summary: [r8169] PPPoE connections don't work if a custom MAC
>                     address is assigned
>            Product: Drivers
>            Version: 2.5
>     Kernel Version: 3.0
>           Platform: All
>         OS/Version: Linux
>               Tree: Mainline
>             Status: NEW
>           Severity: normal
>           Priority: P1
>          Component: Network
>         AssignedTo: drivers_network@kernel-bugs.osdl.org
>         ReportedBy: t.artem@mailcity.com
>         Regression: No
> 
> 
> Description of problem: if I assign a custom MAC address to my onboard NIC,
> then I cannot establish PPPoE connections, and even `pppoe -A` command doesn't
> return any PPPoE access concentrators.
> 
> 
> Version-Release number of selected component (if applicable): r8169 2.3LK-NAPI
> 
> 
> How reproducible: always
> 
> 
> Steps to Reproduce:
> 1. Boot
> 2. ifconfig eth0 hw ether MACADDRESS
> 3. Try to establish PPPoE connection using eth0
> 
> Actual results: PPPoE connection cannot be established, no network packets
> return
> 
> 
> Expected results: PPPoE connections working
> 
> 
> Additional info: if I put eth0 in the promiscuous mode, then PPPoE starts
> working.
> 
> Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express
> Gigabit Ethernet controller (rev 06)
>         Subsystem: ASUSTeK Computer Inc. Device 8432
>         Flags: bus master, fast devsel, latency 0, IRQ 47
>         I/O ports at e000 [size=256]
>         Memory at d0004000 (64-bit, prefetchable) [size=4K]
>         Memory at d0000000 (64-bit, prefetchable) [size=16K]
>         Capabilities: [40] Power Management version 3
>         Capabilities: [50] MSI: Enable+ Count=1/1 Maskable- 64bit+
>         Capabilities: [70] Express Endpoint, MSI 01
>         Capabilities: [b0] MSI-X: Enable- Count=4 Masked-
>         Capabilities: [d0] Vital Product Data
>         Capabilities: [100] Advanced Error Reporting
>         Capabilities: [140] Virtual Channel
>         Capabilities: [160] Device Serial Number 00-00-00-00-00-00-00-00
>         Kernel driver in use: r8169
>         Kernel modules: r8169
> 


^ permalink raw reply

* Re: [PATCH 0/3] ps3_gelic: Fix error paths when a tx dma fails
From: Geoff Levand @ 2011-07-13 22:31 UTC (permalink / raw)
  To: Andre Heider; +Cc: netdev, cbe-oss-dev
In-Reply-To: <1310501606-829-1-git-send-email-a.heider@gmail.com>

Hi Andre,

On 07/12/2011 01:13 PM, Andre Heider wrote:
> This series fixes a few bugs for the error paths once a tx dma request
> fails. Without these I either ran into BUG_ON, the device got killed,
> or the kernel crashed.

Thanks for preparing the fixes.  I added them to my ps3-linux
tree and did some quick tests which didn't show any problems.
I'll try to do some more through testing with them sometime
soon.

-Geoff


^ permalink raw reply

* Re: any way to let host act as TCP server OR client on same IP/port?
From: Chris Friesen @ 2011-07-13 22:28 UTC (permalink / raw)
  To: Rick Jones; +Cc: Eric Dumazet, netdev
In-Reply-To: <4E1E01BF.3040201@hp.com>

On 07/13/2011 02:36 PM, Rick Jones wrote:
>>>
>>> I was thinking the same thing, but it appears to not work under:
>>
>> <snip>
>>
>>> if (bind(listener,
>>> (struct sockaddr *)&me,
>>> sizeof(me))< 0) {
>>> perror("bind listener");
>>> exit(-1);
>>> }
>>>
>>> if (listen(listener,128)< 0) {
>>> perror("listen listener");
>>> exit(-1);
>>> }
>>>
>>> /* connect something to it */
>>> if (connect(client,(struct sockaddr *)&me,sizeof(me))< 0) {
>>> perror("connect client");
>>> exit(-1);
>>
>> In our case we don't need to actually be connected, just be listening
>> and ready to either accept() a connection or connect() to someone else.
>
> If one calls listen() against a socket, TCP connections can be
> established at any time, before the accept() calls are made. As for what
> might happen when one calls connect() on a listen socket when there are
> queued connections awaiting accept() I've no idea.

In Linux at least it appears that you aren't allowed to call listen() 
and then connect().  See below, however.

> If your application's sematics are OK with pending connections being
> dumped, and there is no issue with something else binding to IP,port and
> putting it into the LISTEN state, and if I've read between the lines of
> what you've written correctly, you could simply close() the listen
> socket and create a fresh socket with which to do the connect()?

Ah, of course.  It actually looks like a shutdown() might be sufficient 
to reset the state of the socket enough to allow me to then call 
connect() without needing to create a new socket and bind it.

I'll see what the application guys say.

Thanks,
Chris


-- 
Chris Friesen
Software Developer
GENBAND
chris.friesen@genband.com
www.genband.com

^ permalink raw reply

* Re: hypothetical vlan rx path question
From: Stephen Hemminger @ 2011-07-13 21:11 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, eric.dumazet, nicolas.2p.debian, andy, greearb,
	mirqus, bhutchings
In-Reply-To: <20110713204945.GA1833@minipsycho>

On Wed, 13 Jul 2011 22:49:46 +0200
Jiri Pirko <jpirko@redhat.com> wrote:

> Hi guys.
> 
> Consider following code taken from 8139cp.c
> 
> 
> static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
> 			      struct cp_desc *desc)
> {
> 	skb->protocol = eth_type_trans (skb, cp->dev);
> 
> 	cp->dev->stats.rx_packets++;
> 	cp->dev->stats.rx_bytes += skb->len;
> 
> #if CP_VLAN_TAG_USED
> 	if (cp->vlgrp && (desc->opts2 & cpu_to_le32(RxVlanTagged))) {
> 		vlan_hwaccel_receive_skb(skb, cp->vlgrp,
> 					 swab16(le32_to_cpu(desc->opts2) & 0xffff));
> 	} else
> #endif
> 		netif_receive_skb(skb);
> }
> 
> 
> Now my question is why the check for cp->vlgrp is needed here. Because
> in hypothetical case it might be possible to receive vlan packet as
> non-vlan packet (vlan tag would be lost).
> 
> This is present in many drivers.
> 
> How about to kill this check entirely and let the later code to deside
> what to do with the packet?
> 
> Thanks.
> 
> Jirka

All this is moot with new vlan model. It should always just put
tagged packet up.

I think all drivers with .ndo_vlan_rx_register need to be still converted.

^ permalink raw reply

* hypothetical vlan rx path question
From: Jiri Pirko @ 2011-07-13 20:49 UTC (permalink / raw)
  To: netdev
  Cc: davem, shemminger, eric.dumazet, nicolas.2p.debian, andy, greearb,
	mirqus, bhutchings

Hi guys.

Consider following code taken from 8139cp.c


static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
			      struct cp_desc *desc)
{
	skb->protocol = eth_type_trans (skb, cp->dev);

	cp->dev->stats.rx_packets++;
	cp->dev->stats.rx_bytes += skb->len;

#if CP_VLAN_TAG_USED
	if (cp->vlgrp && (desc->opts2 & cpu_to_le32(RxVlanTagged))) {
		vlan_hwaccel_receive_skb(skb, cp->vlgrp,
					 swab16(le32_to_cpu(desc->opts2) & 0xffff));
	} else
#endif
		netif_receive_skb(skb);
}


Now my question is why the check for cp->vlgrp is needed here. Because
in hypothetical case it might be possible to receive vlan packet as
non-vlan packet (vlan tag would be lost).

This is present in many drivers.

How about to kill this check entirely and let the later code to deside
what to do with the packet?

Thanks.

Jirka

^ permalink raw reply

* Re: any way to let host act as TCP server OR client on same IP/port?
From: Rick Jones @ 2011-07-13 20:36 UTC (permalink / raw)
  To: Chris Friesen; +Cc: Eric Dumazet, netdev
In-Reply-To: <4E1DEEF9.7040901@genband.com>

>>
>> I was thinking the same thing, but it appears to not work under:
>
> <snip>
>
>> if (bind(listener,
>> (struct sockaddr *)&me,
>> sizeof(me))<  0) {
>> perror("bind listener");
>> exit(-1);
>> }
>>
>> if (listen(listener,128)<  0) {
>> perror("listen listener");
>> exit(-1);
>> }
>>
>> /* connect something to it */
>> if (connect(client,(struct sockaddr *)&me,sizeof(me))<  0) {
>> perror("connect client");
>> exit(-1);
>
> In our case we don't need to actually be connected, just be listening
> and ready to either accept() a connection or connect() to someone else.

If one calls listen() against a socket, TCP connections can be 
established at any time, before the accept() calls are made.  As for 
what might happen when one calls connect() on a listen socket when there 
are queued connections awaiting accept() I've no idea.  Presumably they 
would follow the same path as if close() were called against the listen 
endpoint before they were accept()ed.  And if the listen endpoint is 
transitioned to CONNECTED then any subsequently arriving connection 
requests will likely elicit RSTs back to their senders.

If your application's sematics are OK with pending connections being 
dumped, and there is no issue with something else binding to IP,port and 
putting it into the LISTEN state, and if I've read between the lines of 
what you've written correctly, you could simply close() the listen 
socket and create a fresh socket with which to do the connect()?

I think it is only if you need both accepting new connections and 
calling connect() all in parallel that you need enhancements to the stack.

> However, even after removing the connect() call I get:
> "bind active: Address already in use"

Some of this behaviour may come from the "standards" (either formal or 
informal), and what they call for for error returns on the different 
calls under what conditions.

Historically, and not necessarily specific to any one stack, 
SO_REUSEADDR allows one to kill a server application, and restart it and 
get its LISTEN endpoint restarted even while there are old connections 
with IP,port as half the four-tuple (esp TIME_WAITs).  But SO_REUSEADDR 
won't allow the bind(IP,port) to succeed if there is another listen() 
endpoint bound to that IP,port.  That would be an ambiguity.  But, if 
the second endpoint to be bound to IP,port doesn't go listen(), there 
isn't an ambiguity.  This may be where the standards or historical 
expectations come-in if they "require" the bind() fail even if it isn't 
clear there will be a subsequent listen() call against that endpoint.

Presumably, as far as the TCP state machine goes, having one endpoint 
bound only to IP1,Port1 and in the LISTEN state and one simply bound to 
IP,port but not in LISTEN (presumably on its way to a connection 
establishment) is ok.  A arriving segment will hit the four-tuple if it 
exists, and only go to the two-tuple if is in LISTEN and the segment is 
a SYN and won't go to the non-listen two-tuple at all.  But at the API 
level the listen() and connect() calls need to be permitted/able to 
return EADDRINUSE (or something akin) when they then try to create a 
two/four-tuple (listen/connect) that is already in use.

FWIW, the listen() manpage on my Maverick system does list:

ERRORS
        EADDRINUSE
               Another socket is already listening on the same port.

suggesting that the "delay the failure until listen() on the same 
IP,port" is possible, but I don't know if that is vestigial manpage 
cruft or "real."  The manpage for connect() shows EADDRINUSE as well - 
again though I not sure if that is vestigial, so it may not accurately 
convey current stack intent.

> The TCP state machine shows a single connection going from LISTEN to
> SYN_SENT via a "send" operation in the application.  Presumably this
> would logically map to a sendto/sendmsg but according to the man page
> those don't support specifying addresses for connection-oriented
> sockets.  I tried it anyways and got no errors but the following trace
> shows that it's dying with SIGPIPE:
>
> bind(3, {sa_family=AF_INET, sin_port=htons(23456), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
> listen(3, 128)                          = 0
> sendto(3, "\1", 1, 0, {sa_family=AF_INET, sin_port=htons(9), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EPIPE (Broken pipe)
> --- {si_signo=SIGPIPE, si_code=SI_USER, si_pid=20609, si_uid=8382, si_value={int=2722689790, ptr=0x3ca248f2fe}} (Broken pipe) ---
> +++ killed by SIGPIPE +++

You might try a connect() call - since T/TCP (vs the even older than 
netperf, ttcp benchmark :) never caught-on, sendto() against a TCP 
endpoint is probably a no-go.

If I'm thinking of the same state machine diagram, the "send" is rather, 
well, generic and does not map directly to any API.

(I tried it very quick and dirty, with no joy)

If your application's sematics are OK with pending connections being 
dumped, and there is no issue with something else
rick

^ permalink raw reply

* Re: [PATCH net-next 4/7] tg3: Determine PCI function number in one place
From: Ben Hutchings @ 2011-07-13 20:13 UTC (permalink / raw)
  To: Matt Carlson; +Cc: davem, netdev
In-Reply-To: <1310585253-4817-5-git-send-email-mcarlson@broadcom.com>

On Wed, 2011-07-13 at 12:27 -0700, Matt Carlson wrote:
> tg3 devices will need to know exactly what function number they are so
> that they can communicate their status to the other functions.  In a KVM
> environment, the function number of a device presented by the kernel
> might not be the true function number, so an alternative method to
> determine the function number is needed.
> 
> This patch used to contain an implementation for the alternative method,
> but recently we discovered a hardware bug that renders it incorrect.
> While new method is not yet known, it is still useful to consolidate the
> code that determines the PCI function to one location and use the
> results throughout the code.
[...]

Having run into (and thankfully fixed) a similar problem in sfc, I
wonder whether it would always be worthwhile to ask the hypervisor
maintainers to keep function numbers stable when passing-through
physical functions.  Any driver using PCI_FUNC() is likely to be broken
by function number changes, and 'git grep' shows there are quite a few
of them.

Ben.

-- 
Ben Hutchings, Senior Software 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

* iproute2 for 3.0
From: Stephen Hemminger @ 2011-07-13 19:49 UTC (permalink / raw)
  To: netdev

If anyone has any patches for the 3.0 version of iproute2
now would be a good time to send them.

I still have to but my netem CLG and QFQ scheduler bits, but
there maybe other stuff that people have stashed in their distro
patch pile.

^ permalink raw reply

* [GIT] Networking
From: David Miller @ 2011-07-13 19:31 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


1) SLIP config ifdefs surround wrong bits of code, fix from
   Matvejchikov Ilya.

2) Natsemi does DMA unmaps using wrong length, fix from Jim Cromie.

3) Two SCTP fixes from Thomas Graf.  Do not deadlock on graceful
   shutdown when data chunks exist in the retransmit queue.  Also,
   if behave like TCP if receiver closes with data still queued up
   on receive by emitting an ABORT.

4) Fix use after free in HSO driver, from Octavian Purdila.

5) Natsemi module parms permissions are busted, from Jean Delvare.

6) Fix memory leak in XFRM state code, from Tushar Gohad.

7) Fix vulnerability in mac80211 TKIP replay handling, from Johannes
   Berg.

8) Several bluetooth fixes:
	Buffer overflow in l2cap from Dan Rosenberg
	HIDP disconnect deadlocks from Peter Hurley
	Incoming L2CAP regression fix from Gustavo F. Padovan
	Memory leak in hci_conn from Tomas Targownik

9) ath5k driver stores "ieee80211_hw" pointer in drvdata but then
   tries to use it as a "ath5k_softc" pointer, fix from Pavel roskin.

10) Fix deadlock in rfkill/sched_scan code of cfg80211 by using a new
    mutex, fix from Luciano Coelho.

Please pull, thanks a lot!

The following changes since commit 8d86e5f91440aa56a5df516bf58fe3883552ad56:

  Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc (2011-07-12 14:21:19 -0700)

are available in the git repository at:

  master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git master

Christian Lamparter (1):
      carl9170: add NEC WL300NU-AG usbid

Dan Rosenberg (1):
      Bluetooth: Prevent buffer overflow in l2cap config request

David S. Miller (2):
      net: Fix default in docs for tcp_orphan_retries.
      Merge branch 'for-davem' of git://git.kernel.org/.../linville/wireless-2.6

Greg Kroah-Hartman (1):
      hso: fix a use after free condition

Gustavo F. Padovan (1):
      Bluetooth: Fix regression with incoming L2CAP connections

Jean Delvare (1):
      net/natsemi: Fix module parameter permissions

Jim Cromie (1):
      natsemi: fix another dma-debug report

Johannes Berg (1):
      mac80211: fix TKIP replay vulnerability

John W. Linville (2):
      Merge branch 'master' of master.kernel.org:/.../padovan/bluetooth-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6 into for-davem

Luciano Coelho (2):
      cfg80211: fix deadlock with rfkill/sched_scan by adding new mutex
      mac80211: fix ie memory allocation for scheduled scans

Matvejchikov Ilya (1):
      slip: fix wrong SLIP6 ifdef-endif placing

Pavel Roskin (2):
      ath5k: fix incorrect use of drvdata in sysfs code
      ath5k: fix incorrect use of drvdata in PCI suspend/resume code

Peter Hurley (1):
      Bluetooth: Fix hidp disconnect deadlocks and lost wakeup

Rafał Miłecki (1):
      ssb: fix init regression of hostmode PCI core

Rajkumar Manoharan (1):
      ath9k: Fix tx throughput drops for AR9003 chips with AES encryption

Thomas Graf (2):
      sctp: Enforce retransmission limit during shutdown
      sctp: ABORT if receive, reassmbly, or reodering queue is not empty while closing socket

Tomas Targownik (1):
      Bluetooth: Fix memory leak under page timeouts

Tushar Gohad (1):
      XFRM: Fix memory leak in xfrm_state_update

Yoann DI-RUZZA (1):
      rtlwifi: rtl8192cu: Add new USB ID for Netgear WNA1000M

 Documentation/networking/ip-sysctl.txt      |    2 +-
 drivers/net/natsemi.c                       |    6 ++--
 drivers/net/slip.c                          |    2 +-
 drivers/net/usb/hso.c                       |    7 +++--
 drivers/net/wireless/ath/ath5k/pci.c        |    7 ++++-
 drivers/net/wireless/ath/ath5k/sysfs.c      |    9 +++++--
 drivers/net/wireless/ath/ath9k/xmit.c       |    3 +-
 drivers/net/wireless/ath/carl9170/usb.c     |    2 +
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.c |    1 +
 drivers/ssb/driver_pcicore.c                |   18 +++++++-------
 include/net/sctp/command.h                  |    1 +
 include/net/sctp/ulpevent.h                 |    2 +-
 net/bluetooth/hci_conn.c                    |    3 ++
 net/bluetooth/hidp/core.c                   |   18 +++++++++------
 net/bluetooth/hidp/hidp.h                   |    1 +
 net/bluetooth/l2cap_core.c                  |    5 ++-
 net/mac80211/scan.c                         |    3 +-
 net/mac80211/wpa.c                          |   16 +++++++++++--
 net/sctp/outqueue.c                         |   20 ++++++++++++++++-
 net/sctp/sm_sideeffect.c                    |   20 +++++++++++++++-
 net/sctp/sm_statefuns.c                     |   32 +++++++++++++++++++-------
 net/sctp/sm_statetable.c                    |    2 +-
 net/sctp/socket.c                           |   13 ++++++----
 net/sctp/ulpevent.c                         |   16 +++++++++++--
 net/wireless/core.c                         |   12 +++++++--
 net/wireless/core.h                         |    2 +
 net/wireless/nl80211.c                      |   24 +++++++++++++++-----
 net/wireless/scan.c                         |   10 ++++----
 net/xfrm/xfrm_state.c                       |    2 +
 29 files changed, 187 insertions(+), 72 deletions(-)



^ permalink raw reply

* [PATCH net-next 5/7] tg3: Create critical section around GPIO toggling
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

The code that performs the power source switching will need to consider
the status of the other devices before making any switches.  The status
updates and power source switching will need to be an atomic operation,
so a critical section will be needed.  This patch establishes the
critical section through a CPMU mutex.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |   63 +++++++++++++++++++++++++++++++++++++++++++---------
 drivers/net/tg3.h |    1 +
 2 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 6f1f36c..4137e4e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -608,7 +608,7 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
 static void tg3_ape_lock_init(struct tg3 *tp)
 {
 	int i;
-	u32 regbase;
+	u32 regbase, bit;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 		regbase = TG3_APE_LOCK_GRANT;
@@ -616,20 +616,34 @@ static void tg3_ape_lock_init(struct tg3 *tp)
 		regbase = TG3_APE_PER_LOCK_GRANT;
 
 	/* Make sure the driver hasn't any stale locks. */
-	for (i = 0; i < 8; i++)
+	for (i = 0; i < 8; i++) {
+		if (i == TG3_APE_LOCK_GPIO)
+			continue;
 		tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
+	}
+
+	/* Clear the correct bit of the GPIO lock too. */
+	if (!tp->pci_fn)
+		bit = APE_LOCK_GRANT_DRIVER;
+	else
+		bit = 1 << tp->pci_fn;
+
+	tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit);
 }
 
 static int tg3_ape_lock(struct tg3 *tp, int locknum)
 {
 	int i, off;
 	int ret = 0;
-	u32 status, req, gnt;
+	u32 status, req, gnt, bit;
 
 	if (!tg3_flag(tp, ENABLE_APE))
 		return 0;
 
 	switch (locknum) {
+	case TG3_APE_LOCK_GPIO:
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+			return 0;
 	case TG3_APE_LOCK_GRC:
 	case TG3_APE_LOCK_MEM:
 		break;
@@ -647,21 +661,24 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
 	off = 4 * locknum;
 
-	tg3_ape_write32(tp, req + off, APE_LOCK_REQ_DRIVER);
+	if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
+		bit = APE_LOCK_REQ_DRIVER;
+	else
+		bit = 1 << tp->pci_fn;
+
+	tg3_ape_write32(tp, req + off, bit);
 
 	/* Wait for up to 1 millisecond to acquire lock. */
 	for (i = 0; i < 100; i++) {
 		status = tg3_ape_read32(tp, gnt + off);
-		if (status == APE_LOCK_GRANT_DRIVER)
+		if (status == bit)
 			break;
 		udelay(10);
 	}
 
-	if (status != APE_LOCK_GRANT_DRIVER) {
+	if (status != bit) {
 		/* Revoke the lock request. */
-		tg3_ape_write32(tp, gnt + off,
-				APE_LOCK_GRANT_DRIVER);
-
+		tg3_ape_write32(tp, gnt + off, bit);
 		ret = -EBUSY;
 	}
 
@@ -670,12 +687,15 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
 
 static void tg3_ape_unlock(struct tg3 *tp, int locknum)
 {
-	u32 gnt;
+	u32 gnt, bit;
 
 	if (!tg3_flag(tp, ENABLE_APE))
 		return;
 
 	switch (locknum) {
+	case TG3_APE_LOCK_GPIO:
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+			return;
 	case TG3_APE_LOCK_GRC:
 	case TG3_APE_LOCK_MEM:
 		break;
@@ -688,7 +708,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
 	else
 		gnt = TG3_APE_PER_LOCK_GRANT;
 
-	tg3_ape_write32(tp, gnt + 4 * locknum, APE_LOCK_GRANT_DRIVER);
+	if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
+		bit = APE_LOCK_GRANT_DRIVER;
+	else
+		bit = 1 << tp->pci_fn;
+
+	tg3_ape_write32(tp, gnt + 4 * locknum, bit);
 }
 
 static void tg3_disable_ints(struct tg3 *tp)
@@ -2170,11 +2195,16 @@ out:
 static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
 {
 	if (!tg3_flag(tp, IS_NIC))
+		return;
+
+	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
 		return 0;
 
 	tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
 		    TG3_GRC_LCLCTL_PWRSW_DELAY);
 
+	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
+
 	return 0;
 }
 
@@ -2187,6 +2217,10 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
 		return;
 
+
+	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
+		return;
+
 	grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;
 
 	tw32_wait_f(GRC_LOCAL_CTRL,
@@ -2200,6 +2234,8 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
 	tw32_wait_f(GRC_LOCAL_CTRL,
 		    grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
 		    TG3_GRC_LCLCTL_PWRSW_DELAY);
+
+	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
 }
 
 static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
@@ -2207,6 +2243,9 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
 	if (!tg3_flag(tp, IS_NIC))
 		return;
 
+	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
+		return;
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
 		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
@@ -2277,6 +2316,8 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
 				    TG3_GRC_LCLCTL_PWRSW_DELAY);
 		}
 	}
+
+	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
 }
 
 static void tg3_frob_aux_power(struct tg3 *tp)
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index b4c003d..e444469 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2339,6 +2339,7 @@
 /* APE convenience enumerations. */
 #define TG3_APE_LOCK_GRC                1
 #define TG3_APE_LOCK_MEM                4
+#define TG3_APE_LOCK_GPIO               7
 
 #define TG3_EEPROM_SB_F1R2_MBA_OFF	0x10
 
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 6/7] tg3: Add function status reporting
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

This patch adds code to update the status of the function to a common
location to the critical section added in the previous patch.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |  111 +++++++++++++++++++++++++++++++++++++++++-----------
 drivers/net/tg3.h |    4 ++
 2 files changed, 91 insertions(+), 24 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4137e4e..0d1b0c0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2192,18 +2192,66 @@ out:
 	return 0;
 }
 
+#define TG3_GPIO_MSG_DRVR_PRES		 0x00000001
+#define TG3_GPIO_MSG_NEED_VAUX		 0x00000002
+#define TG3_GPIO_MSG_MASK		 (TG3_GPIO_MSG_DRVR_PRES | \
+					  TG3_GPIO_MSG_NEED_VAUX)
+#define TG3_GPIO_MSG_ALL_DRVR_PRES_MASK \
+	((TG3_GPIO_MSG_DRVR_PRES << 0) | \
+	 (TG3_GPIO_MSG_DRVR_PRES << 4) | \
+	 (TG3_GPIO_MSG_DRVR_PRES << 8) | \
+	 (TG3_GPIO_MSG_DRVR_PRES << 12))
+
+#define TG3_GPIO_MSG_ALL_NEED_VAUX_MASK \
+	((TG3_GPIO_MSG_NEED_VAUX << 0) | \
+	 (TG3_GPIO_MSG_NEED_VAUX << 4) | \
+	 (TG3_GPIO_MSG_NEED_VAUX << 8) | \
+	 (TG3_GPIO_MSG_NEED_VAUX << 12))
+
+static inline u32 tg3_set_function_status(struct tg3 *tp, u32 newstat)
+{
+	u32 status, shift;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+		status = tg3_ape_read32(tp, TG3_APE_GPIO_MSG);
+	else
+		status = tr32(TG3_CPMU_DRV_STATUS);
+
+	shift = TG3_APE_GPIO_MSG_SHIFT + 4 * tp->pci_fn;
+	status &= ~(TG3_GPIO_MSG_MASK << shift);
+	status |= (newstat << shift);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+		tg3_ape_write32(tp, TG3_APE_GPIO_MSG, status);
+	else
+		tw32(TG3_CPMU_DRV_STATUS, status);
+
+	return status >> TG3_APE_GPIO_MSG_SHIFT;
+}
+
 static inline int tg3_pwrsrc_switch_to_vmain(struct tg3 *tp)
 {
 	if (!tg3_flag(tp, IS_NIC))
-		return;
-
-	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
 		return 0;
 
-	tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
-		    TG3_GRC_LCLCTL_PWRSW_DELAY);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+		if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
+			return -EIO;
 
-	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
+		tg3_set_function_status(tp, TG3_GPIO_MSG_DRVR_PRES);
+
+		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
+			    TG3_GRC_LCLCTL_PWRSW_DELAY);
+
+		tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
+	} else {
+		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl,
+			    TG3_GRC_LCLCTL_PWRSW_DELAY);
+	}
 
 	return 0;
 }
@@ -2217,10 +2265,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
 		return;
 
-
-	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
-		return;
-
 	grc_local_ctrl = tp->grc_local_ctrl | GRC_LCLCTRL_GPIO_OE1;
 
 	tw32_wait_f(GRC_LOCAL_CTRL,
@@ -2234,8 +2278,6 @@ static void tg3_pwrsrc_die_with_vmain(struct tg3 *tp)
 	tw32_wait_f(GRC_LOCAL_CTRL,
 		    grc_local_ctrl | GRC_LCLCTRL_GPIO_OUTPUT1,
 		    TG3_GRC_LCLCTL_PWRSW_DELAY);
-
-	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
 }
 
 static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
@@ -2243,9 +2285,6 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
 	if (!tg3_flag(tp, IS_NIC))
 		return;
 
-	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
-		return;
-
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
 		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
@@ -2316,7 +2355,31 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
 				    TG3_GRC_LCLCTL_PWRSW_DELAY);
 		}
 	}
+}
+
+static void tg3_frob_aux_power_5717(struct tg3 *tp)
+{
+	u32 msg = 0;
+
+	/* Serialize power state transitions */
+	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
+		return;
+
+	if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) ||
+	    tg3_flag(tp, WOL_ENABLE))
+		msg = TG3_GPIO_MSG_NEED_VAUX;
+
+	msg = tg3_set_function_status(tp, msg);
+
+	if (msg & TG3_GPIO_MSG_ALL_DRVR_PRES_MASK)
+		goto done;
 
+	if (msg & TG3_GPIO_MSG_ALL_NEED_VAUX_MASK)
+		tg3_pwrsrc_switch_to_vaux(tp);
+	else
+		tg3_pwrsrc_die_with_vmain(tp);
+
+done:
 	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
 }
 
@@ -2326,15 +2389,17 @@ static void tg3_frob_aux_power(struct tg3 *tp)
 
 	/* The GPIOs do something completely different on 57765. */
 	if (!tg3_flag(tp, IS_NIC) ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		return;
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
-	    tp->pdev_peer != tp->pdev) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+		tg3_frob_aux_power_5717(tp);
+		return;
+	}
+
+	if (tp->pdev_peer && tp->pdev_peer != tp->pdev) {
 		struct net_device *dev_peer;
 
 		dev_peer = pci_get_drvdata(tp->pdev_peer);
@@ -13692,9 +13757,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	}
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)
 		tp->pdev_peer = tg3_find_peer(tp);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index e444469..6a43fc5 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1065,6 +1065,8 @@
 #define  RCVLSC_STATUS_ERROR_ATTN	 0x00000004
 /* 0x3408 --> 0x3600 unused */
 
+#define TG3_CPMU_DRV_STATUS		0x0000344c
+
 /* CPMU registers */
 #define TG3_CPMU_CTRL			0x00003600
 #define  CPMU_CTRL_LINK_IDLE_MODE	 0x00000200
@@ -2277,6 +2279,8 @@
 
 
 /* APE registers.  Accessible through BAR1 */
+#define TG3_APE_GPIO_MSG		0x0008
+#define TG3_APE_GPIO_MSG_SHIFT		4
 #define TG3_APE_EVENT			0x000c
 #define  APE_EVENT_1			 0x00000001
 #define TG3_APE_LOCK_REQ		0x002c
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 0/7] tg3: Formalize power source switching
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

These patches make power source switching a more formal and carefully controlled process.



^ permalink raw reply

* [PATCH net-next 4/7] tg3: Determine PCI function number in one place
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

tg3 devices will need to know exactly what function number they are so
that they can communicate their status to the other functions.  In a KVM
environment, the function number of a device presented by the kernel
might not be the true function number, so an alternative method to
determine the function number is needed.

This patch used to contain an implementation for the alternative method,
but recently we discovered a hardware bug that renders it incorrect.
While new method is not yet known, it is still useful to consolidate the
code that determines the PCI function to one location and use the
results throughout the code.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |   14 +++++++++++---
 drivers/net/tg3.h |    1 +
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5d4283e..6f1f36c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1170,7 +1170,7 @@ static int tg3_mdio_init(struct tg3 *tp)
 	if (tg3_flag(tp, 5717_PLUS)) {
 		u32 is_serdes;
 
-		tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1;
+		tp->phy_addr = tp->pci_fn + 1;
 
 		if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
 			is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
@@ -13951,6 +13951,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	val = tr32(MEMARB_MODE);
 	tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
 
+	if (tg3_flag(tp, PCIX_MODE)) {
+		pci_read_config_dword(tp->pdev,
+				      tp->pcix_cap + PCI_X_STATUS, &val);
+		tp->pci_fn = val & 0x7;
+	} else {
+		tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3;
+	}
+
 	/* Get eeprom hw config before calling tg3_set_power_state().
 	 * In particular, the TG3_FLAG_IS_NIC flag must be
 	 * determined before calling tg3_set_power_state() so that
@@ -14316,9 +14324,9 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
 		else
 			tg3_nvram_unlock(tp);
 	} else if (tg3_flag(tp, 5717_PLUS)) {
-		if (PCI_FUNC(tp->pdev->devfn) & 1)
+		if (tp->pci_fn & 1)
 			mac_offset = 0xcc;
-		if (PCI_FUNC(tp->pdev->devfn) > 1)
+		if (tp->pci_fn > 1)
 			mac_offset += 0x18c;
 	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
 		mac_offset = 0x10;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 5f250ae..b4c003d 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -3020,6 +3020,7 @@ struct tg3 {
 	u8				pci_cacheline_sz;
 	u8				pci_lat_timer;
 
+	int				pci_fn;
 	int				pm_cap;
 	int				msi_cap;
 	int				pcix_cap;
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 1/7] tg3: Detect APE enabled devs earlier
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

The following patch will require the driver to communicate with the APE
much sooner than before.  This patch make sure the APE registers are
memory mapped and that the ENABLE_APE bit is set before the first use.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |   52 +++++++++++++++++++++++++++++++---------------------
 1 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8211b9a..01d3a27 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -13446,10 +13446,15 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 	else
 		return;
 
-	if (!tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || vpd_vers)
+	if (vpd_vers)
 		goto done;
 
-	tg3_read_mgmtfw_ver(tp);
+	if (tg3_flag(tp, ENABLE_APE)) {
+		if (tg3_flag(tp, ENABLE_ASF))
+			tg3_read_dash_ver(tp);
+	} else if (tg3_flag(tp, ENABLE_ASF)) {
+		tg3_read_mgmtfw_ver(tp);
+	}
 
 done:
 	tp->fw_ver[TG3_VER_SIZE - 1] = 0;
@@ -13971,6 +13976,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 				 PCISTATE_ALLOW_APE_PSPACE_WR;
 		pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE,
 				       pci_state_reg);
+
+		tg3_ape_lock_init(tp);
 	}
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -15083,6 +15090,24 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 		goto err_out_free_dev;
 	}
 
+	if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+	    tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761E ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761SE ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
+	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720) {
+		tg3_flag_set(tp, ENABLE_APE);
+		tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
+		if (!tp->aperegs) {
+			dev_err(&pdev->dev,
+				"Cannot map APE registers, aborting\n");
+			err = -ENOMEM;
+			goto err_out_iounmap;
+		}
+	}
+
 	tp->rx_pending = TG3_DEF_RX_RING_PENDING;
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 
@@ -15095,7 +15120,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	if (err) {
 		dev_err(&pdev->dev,
 			"Problem fetching invariants of chip, aborting\n");
-		goto err_out_iounmap;
+		goto err_out_apeunmap;
 	}
 
 	/* The EPB bridge inside 5714, 5715, and 5780 and any
@@ -15124,7 +15149,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 			if (err < 0) {
 				dev_err(&pdev->dev, "Unable to obtain 64 bit "
 					"DMA for consistent allocations\n");
-				goto err_out_iounmap;
+				goto err_out_apeunmap;
 			}
 		}
 	}
@@ -15133,7 +15158,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 		if (err) {
 			dev_err(&pdev->dev,
 				"No usable DMA configuration, aborting\n");
-			goto err_out_iounmap;
+			goto err_out_apeunmap;
 		}
 	}
 
@@ -15198,22 +15223,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	if (err) {
 		dev_err(&pdev->dev,
 			"Could not obtain valid ethernet address, aborting\n");
-		goto err_out_iounmap;
-	}
-
-	if (tg3_flag(tp, ENABLE_APE)) {
-		tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
-		if (!tp->aperegs) {
-			dev_err(&pdev->dev,
-				"Cannot map APE registers, aborting\n");
-			err = -ENOMEM;
-			goto err_out_iounmap;
-		}
-
-		tg3_ape_lock_init(tp);
-
-		if (tg3_flag(tp, ENABLE_ASF))
-			tg3_read_dash_ver(tp);
+		goto err_out_apeunmap;
 	}
 
 	/*
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 2/7] tg3: Move power state transitions to init_one
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

The tg3 driver is going to require memory mapped register access much
sooner than before.  This patch makes sure the device is in the D0 power
state as soon as possible, and moves the code that enables the memory
arbiter outside tg3_get_eeprom_hw_cfg() where it can be more easily
monitored.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |   77 +++++++++++++++++++++++-----------------------------
 1 files changed, 34 insertions(+), 43 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 01d3a27..ecbc10f 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -12678,29 +12678,6 @@ static struct subsys_tbl_ent * __devinit tg3_lookup_by_subsys(struct tg3 *tp)
 static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
 {
 	u32 val;
-	u16 pmcsr;
-
-	/* On some early chips the SRAM cannot be accessed in D3hot state,
-	 * so need make sure we're in D0.
-	 */
-	pci_read_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, &pmcsr);
-	pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
-	pci_write_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, pmcsr);
-	msleep(1);
-
-	/* Make sure register accesses (indirect or otherwise)
-	 * will function correctly.
-	 */
-	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
-			       tp->misc_host_ctrl);
-
-	/* The memory arbiter has to be enabled in order for SRAM accesses
-	 * to succeed.  Normally on powerup the tg3 chip firmware will make
-	 * sure it is enabled, but other entities such as system netboot
-	 * code might disable it.
-	 */
-	val = tr32(MEMARB_MODE);
-	tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
 
 	tp->phy_id = TG3_PHY_ID_INVALID;
 	tp->led_ctrl = LED_CTRL_MODE_PHY_1;
@@ -13498,14 +13475,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	pci_cmd &= ~PCI_COMMAND_INVALIDATE;
 	pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
 
-	/* It is absolutely critical that TG3PCI_MISC_HOST_CTRL
-	 * has the register indirect write enable bit set before
-	 * we try to access any of the MMIO registers.  It is also
-	 * critical that the PCI-X hw workaround situation is decided
-	 * before that as well.
+	/* Important! -- Make sure register accesses are byteswapped
+	 * correctly.  Also, for those chips that require it, make
+	 * sure that indirect register accesses are enabled before
+	 * the first operation.
 	 */
 	pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
 			      &misc_ctrl_reg);
+	tp->misc_host_ctrl |= (misc_ctrl_reg &
+			       MISC_HOST_CTRL_CHIPREV);
+	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+			       tp->misc_host_ctrl);
 
 	tp->pci_chip_rev_id = (misc_ctrl_reg >>
 			       MISC_HOST_CTRL_CHIPREV_SHIFT);
@@ -13661,12 +13641,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 		} while (bridge);
 	}
 
-	/* Initialize misc host control in PCI block. */
-	tp->misc_host_ctrl |= (misc_ctrl_reg &
-			       MISC_HOST_CTRL_CHIPREV);
-	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
-			       tp->misc_host_ctrl);
-
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
@@ -13851,6 +13825,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 				      tp->pci_lat_timer);
 	}
 
+	/* Important! -- It is critical that the PCI-X hw workaround
+	 * situation is decided before the first MMIO register access.
+	 */
 	if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) {
 		/* 5700 BX chips need to have their TX producer index
 		 * mailboxes written twice to workaround a bug.
@@ -13957,6 +13934,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	      GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)))
 		tg3_flag_set(tp, SRAM_USE_CONFIG);
 
+	/* The memory arbiter has to be enabled in order for SRAM accesses
+	 * to succeed.  Normally on powerup the tg3 chip firmware will make
+	 * sure it is enabled, but other entities such as system netboot
+	 * code might disable it.
+	 */
+	val = tr32(MEMARB_MODE);
+	tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
+
 	/* Get eeprom hw config before calling tg3_set_power_state().
 	 * In particular, the TG3_FLAG_IS_NIC flag must be
 	 * determined before calling tg3_set_power_state() so that
@@ -13987,8 +13972,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	    tg3_flag(tp, 57765_PLUS))
 		tg3_flag_set(tp, CPMU_PRESENT);
 
-	/* Set up tp->grc_local_ctrl before calling tg3_power_up().
-	 * GPIO1 driven high will bring 5700's external PHY out of reset.
+	/* Set up tp->grc_local_ctrl before calling
+	 * tg3_pwrsrc_switch_to_vmain().  GPIO1 driven high
+	 * will bring 5700's external PHY out of reset.
 	 * It is also used as eeprom write protect on LOMs.
 	 */
 	tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
@@ -14017,12 +14003,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 					      GRC_LCLCTRL_GPIO_OUTPUT0;
 	}
 
-	/* Force the chip into D0. */
-	err = tg3_power_up(tp);
-	if (err) {
-		dev_err(&tp->pdev->dev, "Transition to D0 failed\n");
-		return err;
-	}
+	/* Switch out of Vaux if it is a NIC */
+	tg3_pwrsrc_switch_to_vmain(tp);
 
 	/* Derive initial jumbo mode from MTU assigned in
 	 * ether_setup() via the alloc_etherdev() call
@@ -15037,11 +15019,17 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 		goto err_out_free_res;
 	}
 
+	err = pci_set_power_state(pdev, PCI_D0);
+	if (err) {
+		dev_err(&pdev->dev, "Transition to D0 failed, aborting\n");
+		goto err_out_free_res;
+	}
+
 	dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS);
 	if (!dev) {
 		dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
-		goto err_out_free_res;
+		goto err_out_power_down;
 	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -15356,6 +15344,9 @@ err_out_iounmap:
 err_out_free_dev:
 	free_netdev(dev);
 
+err_out_power_down:
+	pci_set_power_state(pdev, PCI_D3hot);
+
 err_out_free_res:
 	pci_release_regions(pdev);
 
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 3/7] tg3: Check transitions to D0 power state
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

Currently pci_set_power_state() does not return useful return codes for
transitions to the D0 power state.  If a device refuses to go into D0,
the PCI layer issues a warning but returns success.

Entering into D0 is a requirement for correct operation of tg3 devices
though.  If the PCI layer should be changed to return an error code for
this type of failure, the tg3 driver would be interested in catching it
and reacting to it.  This patch makes the necessary modifications.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ecbc10f..5d4283e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2657,14 +2657,19 @@ static void tg3_enable_register_access(struct tg3 *tp)
 
 static int tg3_power_up(struct tg3 *tp)
 {
-	tg3_enable_register_access(tp);
+	int err;
 
-	pci_set_power_state(tp->pdev, PCI_D0);
+	tg3_enable_register_access(tp);
 
-	/* Switch out of Vaux if it is a NIC */
-	tg3_pwrsrc_switch_to_vmain(tp);
+	err = pci_set_power_state(tp->pdev, PCI_D0);
+	if (!err) {
+		/* Switch out of Vaux if it is a NIC */
+		tg3_pwrsrc_switch_to_vmain(tp);
+	} else {
+		netdev_err(tp->dev, "Transition to D0 failed\n");
+	}
 
-	return 0;
+	return err;
 }
 
 static int tg3_power_down_prepare(struct tg3 *tp)
@@ -11433,8 +11438,12 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
-		tg3_power_up(tp);
+	if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) &&
+	    tg3_power_up(tp)) {
+		etest->flags |= ETH_TEST_FL_FAILED;
+		memset(data, 1, sizeof(u64) * TG3_NUM_TEST);
+		return;
+	}
 
 	memset(data, 0, sizeof(u64) * TG3_NUM_TEST);
 
@@ -15571,10 +15580,8 @@ static pci_ers_result_t tg3_io_slot_reset(struct pci_dev *pdev)
 	}
 
 	err = tg3_power_up(tp);
-	if (err) {
-		netdev_err(netdev, "Failed to restore register access.\n");
+	if (err)
 		goto done;
-	}
 
 	rc = PCI_ERS_RESULT_RECOVERED;
 
-- 
1.7.3.4



^ permalink raw reply related

* [PATCH net-next 7/7] tg3: Match power source to driver state
From: Matt Carlson @ 2011-07-13 19:27 UTC (permalink / raw)
  To: davem; +Cc: netdev, mcarlson

Now that the driver state (and power source) is being more intensely
scrutinized, we need to make sure it is correct 100% of the time.  This
patch finds and fixes all dangling power state transitions.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
---
 drivers/net/tg3.c |   24 ++++++++++++++++--------
 1 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 0d1b0c0..a5ff82d 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -2357,7 +2357,7 @@ static void tg3_pwrsrc_switch_to_vaux(struct tg3 *tp)
 	}
 }
 
-static void tg3_frob_aux_power_5717(struct tg3 *tp)
+static void tg3_frob_aux_power_5717(struct tg3 *tp, bool wol_enable)
 {
 	u32 msg = 0;
 
@@ -2365,8 +2365,7 @@ static void tg3_frob_aux_power_5717(struct tg3 *tp)
 	if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
 		return;
 
-	if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) ||
-	    tg3_flag(tp, WOL_ENABLE))
+	if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || wol_enable)
 		msg = TG3_GPIO_MSG_NEED_VAUX;
 
 	msg = tg3_set_function_status(tp, msg);
@@ -2383,7 +2382,7 @@ done:
 	tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
 }
 
-static void tg3_frob_aux_power(struct tg3 *tp)
+static void tg3_frob_aux_power(struct tg3 *tp, bool include_wol)
 {
 	bool need_vaux = false;
 
@@ -2395,7 +2394,8 @@ static void tg3_frob_aux_power(struct tg3 *tp)
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
-		tg3_frob_aux_power_5717(tp);
+		tg3_frob_aux_power_5717(tp, include_wol ?
+					tg3_flag(tp, WOL_ENABLE) != 0 : 0);
 		return;
 	}
 
@@ -2411,13 +2411,14 @@ static void tg3_frob_aux_power(struct tg3 *tp)
 			if (tg3_flag(tp_peer, INIT_COMPLETE))
 				return;
 
-			if (tg3_flag(tp_peer, WOL_ENABLE) ||
+			if ((include_wol && tg3_flag(tp_peer, WOL_ENABLE)) ||
 			    tg3_flag(tp_peer, ENABLE_ASF))
 				need_vaux = true;
 		}
 	}
 
-	if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF))
+	if ((include_wol && tg3_flag(tp, WOL_ENABLE)) ||
+	    tg3_flag(tp, ENABLE_ASF))
 		need_vaux = true;
 
 	if (need_vaux)
@@ -3000,7 +3001,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
 	if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF))
 		tg3_power_down_phy(tp, do_low_power);
 
-	tg3_frob_aux_power(tp);
+	tg3_frob_aux_power(tp, true);
 
 	/* Workaround for unstable PLL clock */
 	if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
@@ -9556,6 +9557,8 @@ err_out2:
 
 err_out1:
 	tg3_ints_fini(tp);
+	tg3_frob_aux_power(tp, false);
+	pci_set_power_state(tp->pdev, PCI_D3hot);
 	return err;
 }
 
@@ -15400,6 +15403,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
 	pci_set_drvdata(pdev, dev);
 
+	if (tg3_flag(tp, 5717_PLUS)) {
+		/* Resume a low-power mode */
+		tg3_frob_aux_power(tp, false);
+	}
+
 	err = register_netdev(dev);
 	if (err) {
 		dev_err(&pdev->dev, "Cannot register net device, aborting\n");
-- 
1.7.3.4



^ permalink raw reply related

* Re: any way to let host act as TCP server OR client on same IP/port?
From: Chris Friesen @ 2011-07-13 19:16 UTC (permalink / raw)
  To: Rick Jones; +Cc: Eric Dumazet, netdev
In-Reply-To: <4E1DDE62.3080503@hp.com>

On 07/13/2011 12:05 PM, Rick Jones wrote:
> On 07/13/2011 10:52 AM, Eric Dumazet wrote:
>> Le mercredi 13 juillet 2011 à 10:30 -0600, Chris Friesen a écrit :
>>> I've been asked an interesting question about TCP. We have some people
>>> that want to set up a TCP socket that can listen for connections on a
>>> given IP/port, but also initiate connections from that same IP/port.
>>> (Only one at a time, of course.)
>>>
>>> The TCP state machine seems to allow this (moving from LISTEN to
>>> SYN_SENT) but it's not a normal transition.
>>>
>>> Is there any way to do this using the socket API?
>>>
>>> I thought up a hack whereby we could use NFQUEUE to detect an incoming
>>> SYN and delay it while we call listen() on the socket. Is there any
>>> better way to do this?
>>
>> Could you try SO_REUSEADDR, on both listener and connect attempt ?
> 
> I was thinking the same thing, but it appears to not work under:

<snip>

> if (bind(listener,
> (struct sockaddr *)&me,
> sizeof(me)) < 0) {
> perror("bind listener");
> exit(-1);
> }
> 
> if (listen(listener,128) < 0) {
> perror("listen listener");
> exit(-1);
> }
> 
> /* connect something to it */
> if (connect(client,(struct sockaddr *)&me,sizeof(me)) < 0) {
> perror("connect client");
> exit(-1);

In our case we don't need to actually be connected, just be listening
and ready to either accept() a connection or connect() to someone else.

However, even after removing the connect() call I get:
"bind active: Address already in use"


The TCP state machine shows a single connection going from LISTEN to
SYN_SENT via a "send" operation in the application.  Presumably this
would logically map to a sendto/sendmsg but according to the man page
those don't support specifying addresses for connection-oriented
sockets.  I tried it anyways and got no errors but the following trace
shows that it's dying with SIGPIPE:

bind(3, {sa_family=AF_INET, sin_port=htons(23456), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
listen(3, 128)                          = 0
sendto(3, "\1", 1, 0, {sa_family=AF_INET, sin_port=htons(9), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EPIPE (Broken pipe)
--- {si_signo=SIGPIPE, si_code=SI_USER, si_pid=20609, si_uid=8382, si_value={int=2722689790, ptr=0x3ca248f2fe}} (Broken pipe) ---
+++ killed by SIGPIPE +++


Chris



-- 
Chris Friesen
Software Developer
GENBAND
chris.friesen@genband.com
www.genband.com

^ permalink raw reply

* Re: any way to let host act as TCP server OR client on same IP/port?
From: Rick Jones @ 2011-07-13 18:05 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Chris Friesen, netdev
In-Reply-To: <1310579520.2509.17.camel@edumazet-laptop>

On 07/13/2011 10:52 AM, Eric Dumazet wrote:
> Le mercredi 13 juillet 2011 à 10:30 -0600, Chris Friesen a écrit :
>> I've been asked an interesting question about TCP.  We have some people
>> that want to set up a TCP socket that can listen for connections on a
>> given IP/port, but also initiate connections from that same IP/port.
>> (Only one at a time, of course.)
>>
>> The TCP state machine seems to allow this (moving from LISTEN to
>> SYN_SENT) but it's not a normal transition.
>>
>> Is there any way to do this using the socket API?
>>
>> I thought up a hack whereby we could use NFQUEUE to detect an incoming
>> SYN and delay it while we call listen() on the socket.  Is there any
>> better way to do this?
>
> Could you try SO_REUSEADDR, on both listener and connect attempt ?

I was thinking the same thing, but it appears to not work under:

raj@tardy:~$ uname -a
Linux tardy 2.6.35-30-generic #54-Ubuntu SMP Tue Jun 7 18:41:54 UTC 2011 
x86_64 GNU/Linux

raj@tardy:~$ ./both
bind active: Address already in use

(nor HP-UX 11.31)

unless I botched the test code somehow:

raj@tardy:~$ cat both.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>

int
main(int argc, char *argv[]) {

   struct sockaddr_in me,him;
   int on = 1;
   socklen_t  len;
   int  listener, active, client;


   if ((listener = socket(AF_INET,SOCK_STREAM,0)) < 0) {
     perror("socket listener");
     exit(-1);
   }

   if ((active = socket(AF_INET,SOCK_STREAM,0)) < 0) {
     perror("socket active");
     exit(-1);
   }

   if ((client = socket(AF_INET,SOCK_STREAM,0)) < 0) {
     perror("socket client");
     exit(-1);
   }

   /* setup the listen endpoint */
   memset(&me,0,sizeof(me));

   if (!inet_pton(AF_INET,"127.0.0.1",&(me.sin_addr.s_addr))) {
     perror("inet_pton me");
     exit(-1);
   }
   me.sin_port = htons(23456);
   me.sin_family = AF_INET;

   if (setsockopt(listener,
		 SOL_SOCKET,
		 SO_REUSEADDR,
		 (char *)&on ,
		 sizeof(on)) < 0) {
     perror("setsockopt SO_REUSEADDR listener");
     exit(-1);
   }

   if (bind(listener,
	   (struct sockaddr *)&me,
	   sizeof(me)) < 0) {
     perror("bind listener");
     exit(-1);
   }

   if (listen(listener,128) < 0) {
     perror("listen listener");
     exit(-1);
   }

   /* connect something to it */
   if (connect(client,(struct sockaddr *)&me,sizeof(me)) < 0) {
     perror("connect client");
     exit(-1);
   }

   /* now try to make an active connection from "me" */
   memset(&him,0,sizeof(him));

   if (!inet_pton(AF_INET,"127.0.0.1",&(him.sin_addr.s_addr))) {
     perror("inet_pton him");
     exit(-1);
   }

   him.sin_port = htons(9);  /* assume someone is listening on
					"discard"*/
   him.sin_family = AF_INET;

   if (setsockopt(active,
		 SOL_SOCKET,
		 SO_REUSEADDR,
		 (char *)&on ,
		 sizeof(on)) < 0) {
     perror("setsockopt SO_REUSEADDR active");
     exit(-1);
   }

   if (bind(active,
	   (struct sockaddr *)&me,
	   sizeof(me)) < 0) {
     perror("bind active");
     exit(-1);
   }

   if (connect(active,(struct sockaddr *)&him,sizeof(him)) < 0) {
     perror("connect active");
     exit(-1);
   }

   printf("Successfully created a listen endpoint and an active 
connection from the same IP/port pair\n");

}


rick jones

^ permalink raw reply

* Re: [PATCH 2/2] ipv4: Use universal hash for ARP.
From: Roland Dreier @ 2011-07-13 17:59 UTC (permalink / raw)
  To: David Miller; +Cc: johnwheffner, mj, netdev
In-Reply-To: <20110711.014845.1009062692530385177.davem@davemloft.net>

On Mon, Jul 11, 2011 at 1:48 AM, David Miller <davem@davemloft.net> wrote:
> +static inline u32 arp_hashfn(u32 key, const struct net_device *dev, u32 hash_rnd)
> +{
> +       u32 val = key ^ dev->ifindex;
> +
> +       return val * hash_rnd;
> +}

OK, I suggested this, and there's nothing obviously wrong with it.

But I would hope that someone actually vetted that this provides
enough variation between different hash_rnd values to avoid hash
chain attacks.

 - R.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox