Netdev List
 help / color / mirror / Atom feed
* [PATCH 3/3] atl1e: Remove non-implementation of ethtool set_msglevel() operation
From: Ben Hutchings @ 2009-12-02  5:10 UTC (permalink / raw)
  To: David Miller; +Cc: Jie Yang, netdev

Unimplemented operations should not silently fail.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/net/atl1e/atl1e_ethtool.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index bb15c51..a76006c 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -140,10 +140,6 @@ static u32 atl1e_get_msglevel(struct net_device *netdev)
 #endif
 }
 
-static void atl1e_set_msglevel(struct net_device *netdev, u32 data)
-{
-}
-
 static int atl1e_get_regs_len(struct net_device *netdev)
 {
 	return AT_REGS_LEN * sizeof(u32);
@@ -382,7 +378,6 @@ static const struct ethtool_ops atl1e_ethtool_ops = {
 	.get_wol                = atl1e_get_wol,
 	.set_wol                = atl1e_set_wol,
 	.get_msglevel           = atl1e_get_msglevel,
-	.set_msglevel           = atl1e_set_msglevel,
 	.nway_reset             = atl1e_nway_reset,
 	.get_link               = ethtool_op_get_link,
 	.get_eeprom_len         = atl1e_get_eeprom_len,
-- 
1.6.5.3



^ permalink raw reply related

* [PATCH 2/3] atl1e: Remove redundant definitions of ethtool operations
From: Ben Hutchings @ 2009-12-02  5:10 UTC (permalink / raw)
  To: David Miller; +Cc: Jie Yang, netdev

These functions provide the default behaviour and do not need to be
set in struct ethtool_ops.

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/net/atl1e/atl1e_ethtool.c |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index b0fb725..bb15c51 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -131,11 +131,6 @@ static int atl1e_set_settings(struct net_device *netdev,
 	return 0;
 }
 
-static u32 atl1e_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
 static u32 atl1e_get_msglevel(struct net_device *netdev)
 {
 #ifdef DBG
@@ -393,13 +388,8 @@ static const struct ethtool_ops atl1e_ethtool_ops = {
 	.get_eeprom_len         = atl1e_get_eeprom_len,
 	.get_eeprom             = atl1e_get_eeprom,
 	.set_eeprom             = atl1e_set_eeprom,
-	.get_tx_csum            = atl1e_get_tx_csum,
 	.set_tx_csum            = ethtool_op_set_tx_hw_csum,
-	.get_sg                 = ethtool_op_get_sg,
 	.set_sg                 = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
-	.get_tso                = ethtool_op_get_tso,
-#endif
 	.set_tso                = ethtool_op_set_tso,
 };
 
-- 
1.6.5.3




^ permalink raw reply related

* [PATCH 1/3] atl1e: Allow TX checksum offload and TSO to be disabled and reenabled
From: Ben Hutchings @ 2009-12-02  5:09 UTC (permalink / raw)
  To: David Miller; +Cc: Jie Yang, netdev

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
I have no reason for thinking these hardware features may be buggy, but
it is usual practice to allow them to be disabled.

Ben.

 drivers/net/atl1e/atl1e_ethtool.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index 60edb9f..b0fb725 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -394,11 +394,13 @@ static const struct ethtool_ops atl1e_ethtool_ops = {
 	.get_eeprom             = atl1e_get_eeprom,
 	.set_eeprom             = atl1e_set_eeprom,
 	.get_tx_csum            = atl1e_get_tx_csum,
+	.set_tx_csum            = ethtool_op_set_tx_hw_csum,
 	.get_sg                 = ethtool_op_get_sg,
 	.set_sg                 = ethtool_op_set_sg,
 #ifdef NETIF_F_TSO
 	.get_tso                = ethtool_op_get_tso,
 #endif
+	.set_tso                = ethtool_op_set_tso,
 };
 
 void atl1e_set_ethtool_ops(struct net_device *netdev)
-- 
1.6.5.3




^ permalink raw reply related

* Re: SO_BINDTODEVICE and IP_TRANSPARENT (TPROXY)
From: Eric Dumazet @ 2009-12-02  4:56 UTC (permalink / raw)
  To: Ashwani Wason; +Cc: netdev, tproxy
In-Reply-To: <fd1a5ee40912011718r60487ce0obd88c2fbdb55fa15@mail.gmail.com>

Ashwani Wason a écrit :
> After debugging a bit into how nf_tproxy_get_sock_v4() looks up a
> listener for foreign connections using __inet_lookup_listener() and
> compute_score() I found that the problem was happening because of the
> way I had the TPROXY rules setup. Those rules work if the proxy has a
> single listening socket for INADDR_ANY. If multiple listening sockets
> must be used, one for each local address, which is the case for using
> SO_BINDTODEVICE then the TPROXY rules must also be "fully qualified"
> (with interface name [-i] and IP address thereof [--on-ip]). So the
> rules in my example change as follows...
> 
> Instead of using:
> 
>> iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 4002
> 
> Use:
> 
> iptables -t mangle -A PREROUTING *-i eth0* -p tcp --dport 80 -j TPROXY
> --tproxy-mark 0x1/0x1 *--on-ip 192.168.0.65* --on-port 4002
> iptables -t mangle -A PREROUTING *-i eth1* -p tcp --dport 80 -j TPROXY
> --tproxy-mark 0x1/0x1 *--on-ip 192.168.1.65* --on-port 4002
> 
> With these rules the listening socket was looked up correctly and the
> sk_bound_dev_if of the socket was honored.
> 
> - Ashwani
> 
> PS: Sorry to anyone (Jamal) who already spent any time on this.
> PPS: Copying the tproxy list in case someone else is looking for this
> stuff in the future.

Thanks a lot for sharing your discoveries :)


^ permalink raw reply

* Re: [WARNING] Network-related warnings with 2.6.31.6
From: Eric Dumazet @ 2009-12-02  4:52 UTC (permalink / raw)
  To: Chris Rankin; +Cc: linux-kernel, netdev
In-Reply-To: <43332.67750.qm@web52904.mail.re2.yahoo.com>

Chris Rankin a écrit :
> Hi,
> 
> I've just noticed these warnings in my dmesg log, and have no idea what might have triggered them. e1000 related, perhaps?
> 
> Cheers,
> Chris
> 
> ------------[ cut here ]------------
> WARNING: at /home/chris/LINUX/linux-2.6.31/net/core/stream.c:202 inet_csk_destroy_sock+0x77/0xd3()
> Hardware name: Precision WorkStation 650    
> Modules linked in: tun snd_seq_oss snd_seq_midi snd_seq_dummy fuse nfsd lockd auth_rpcgss exportfs sunrpc autofs4 af_packet ipt_LOG nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_LOG nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 p4_clockmod speedstep_lib binfmt_misc dm_mirror dm_region_hash dm_log dm_mod uinput snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_event snd_seq_midi_emul snd_emu10k1 snd_ac97_codec snd_usb_audio ac97_bus snd_seq snd_pcm snd_usb_lib snd_rawmidi snd_seq_device snd_timer firewire_ohci ppdev uvcvideo floppy firewire_core snd_page_alloc snd_util_mem snd_hwdep parport_pc pwc psmouse videodev parport v4l1_compat crc_itu_t pcspkr snd sg i2c_i801 serio_raw soundcore dcdbas ext3 jbd mbcache sr_mod cdrom sd_mod pata_acpi sata_sil uhci_hcd ata_piix libata scsi_mod ehci_hcd e1000 usbcore thermal button radeon intel_agp ttm drm agpgart i2c_algo_bit cfbcopyarea cfbimgblt
>  cfbfillrect [last unloaded: processor]
> Pid: 32056, comm: rpm Not tainted 2.6.31.6 #1
> Call Trace:
>  [<c1023ba8>] ? warn_slowpath_common+0x5d/0x70
>  [<c1023bc6>] ? warn_slowpath_null+0xb/0xd
>  [<c11871ca>] ? inet_csk_destroy_sock+0x77/0xd3
>  [<c119188f>] ? tcp_rcv_state_process+0x81f/0x9e8
>  [<c11966c3>] ? tcp_v4_do_rcv+0x128/0x16d
>  [<c1196b0d>] ? tcp_v4_rcv+0x405/0x640
>  [<c118003e>] ? ip_local_deliver_finish+0xf3/0x1ab
>  [<c117fcd9>] ? ip_rcv_finish+0x2a9/0x2cf
>  [<c117fa30>] ? ip_rcv_finish+0x0/0x2cf
>  [<c116b7c5>] ? netif_receive_skb+0x261/0x281
>  [<f8527bfc>] ? e1000_clean_rx_irq+0x31c/0x3c3 [e1000]
>  [<f852a6fa>] ? e1000_clean+0x2a7/0x3f5 [e1000]
>  [<c11c783c>] ? _spin_unlock_irqrestore+0xe/0x21
>  [<c10354c0>] ? hrtimer_run_pending+0xd/0xa5
>  [<c11c769b>] ? _spin_lock_irq+0xe/0x24
>  [<c116bce5>] ? net_rx_action+0x57/0xfd
>  [<c1027ea3>] ? __do_softirq+0x7a/0xe3
>  [<c1027e29>] ? __do_softirq+0x0/0xe3
>  <IRQ>  [<c1027c3c>] ? irq_exit+0x29/0x63
>  [<c1004320>] ? do_IRQ+0x7c/0x8d
>  [<c1002f29>] ? common_interrupt+0x29/0x30
> ---[ end trace e643d9455a26ccf3 ]---
> ------------[ cut here ]------------
> WARNING: at /home/chris/LINUX/linux-2.6.31/net/ipv4/af_inet.c:151 inet_sock_destruct+0xd8/0x138()
> Hardware name: Precision WorkStation 650    
> Modules linked in: tun snd_seq_oss snd_seq_midi snd_seq_dummy fuse nfsd lockd auth_rpcgss exportfs sunrpc autofs4 af_packet ipt_LOG nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_LOG nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 p4_clockmod speedstep_lib binfmt_misc dm_mirror dm_region_hash dm_log dm_mod uinput snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_event snd_seq_midi_emul snd_emu10k1 snd_ac97_codec snd_usb_audio ac97_bus snd_seq snd_pcm snd_usb_lib snd_rawmidi snd_seq_device snd_timer firewire_ohci ppdev uvcvideo floppy firewire_core snd_page_alloc snd_util_mem snd_hwdep parport_pc pwc psmouse videodev parport v4l1_compat crc_itu_t pcspkr snd sg i2c_i801 serio_raw soundcore dcdbas ext3 jbd mbcache sr_mod cdrom sd_mod pata_acpi sata_sil uhci_hcd ata_piix libata scsi_mod ehci_hcd e1000 usbcore thermal button radeon intel_agp ttm drm agpgart i2c_algo_bit cfbcopyarea cfbimgblt
>  cfbfillrect [last unloaded: processor]
> Pid: 32056, comm: rpm Tainted: G        W  2.6.31.6 #1
> Call Trace:
>  [<c1023ba8>] ? warn_slowpath_common+0x5d/0x70
>  [<c1023bc6>] ? warn_slowpath_null+0xb/0xd
>  [<c11a1414>] ? inet_sock_destruct+0xd8/0x138
>  [<c1163243>] ? __sk_free+0x10/0xa2
>  [<c1196b4a>] ? tcp_v4_rcv+0x442/0x640
>  [<c118003e>] ? ip_local_deliver_finish+0xf3/0x1ab
>  [<c117fcd9>] ? ip_rcv_finish+0x2a9/0x2cf
>  [<c117fa30>] ? ip_rcv_finish+0x0/0x2cf
>  [<c116b7c5>] ? netif_receive_skb+0x261/0x281
>  [<f8527bfc>] ? e1000_clean_rx_irq+0x31c/0x3c3 [e1000]
>  [<f852a6fa>] ? e1000_clean+0x2a7/0x3f5 [e1000]
>  [<c11c783c>] ? _spin_unlock_irqrestore+0xe/0x21
>  [<c10354c0>] ? hrtimer_run_pending+0xd/0xa5
>  [<c11c769b>] ? _spin_lock_irq+0xe/0x24
>  [<c116bce5>] ? net_rx_action+0x57/0xfd
>  [<c1027ea3>] ? __do_softirq+0x7a/0xe3
>  [<c1027e29>] ? __do_softirq+0x0/0xe3
>  <IRQ>  [<c1027c3c>] ? irq_exit+0x29/0x63
>  [<c1004320>] ? do_IRQ+0x7c/0x8d
>  [<c1002f29>] ? common_interrupt+0x29/0x30
> ---[ end trace e643d9455a26ccf4 ]---
> ------------[ cut here ]------------
> WARNING: at /home/chris/LINUX/linux-2.6.31/net/ipv4/af_inet.c:154 inet_sock_destruct+0x11e/0x138()
> Hardware name: Precision WorkStation 650    
> Modules linked in: tun snd_seq_oss snd_seq_midi snd_seq_dummy fuse nfsd lockd auth_rpcgss exportfs sunrpc autofs4 af_packet ipt_LOG nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_LOG nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 p4_clockmod speedstep_lib binfmt_misc dm_mirror dm_region_hash dm_log dm_mod uinput snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_event snd_seq_midi_emul snd_emu10k1 snd_ac97_codec snd_usb_audio ac97_bus snd_seq snd_pcm snd_usb_lib snd_rawmidi snd_seq_device snd_timer firewire_ohci ppdev uvcvideo floppy firewire_core snd_page_alloc snd_util_mem snd_hwdep parport_pc pwc psmouse videodev parport v4l1_compat crc_itu_t pcspkr snd sg i2c_i801 serio_raw soundcore dcdbas ext3 jbd mbcache sr_mod cdrom sd_mod pata_acpi sata_sil uhci_hcd ata_piix libata scsi_mod ehci_hcd e1000 usbcore thermal button radeon intel_agp ttm drm agpgart i2c_algo_bit cfbcopyarea cfbimgblt
>  cfbfillrect [last unloaded: processor]
> Pid: 32056, comm: rpm Tainted: G        W  2.6.31.6 #1
> Call Trace:
>  [<c1023ba8>] ? warn_slowpath_common+0x5d/0x70
>  [<c1023bc6>] ? warn_slowpath_null+0xb/0xd
>  [<c11a145a>] ? inet_sock_destruct+0x11e/0x138
>  [<c1163243>] ? __sk_free+0x10/0xa2
>  [<c1196b4a>] ? tcp_v4_rcv+0x442/0x640
>  [<c118003e>] ? ip_local_deliver_finish+0xf3/0x1ab
>  [<c117fcd9>] ? ip_rcv_finish+0x2a9/0x2cf
>  [<c117fa30>] ? ip_rcv_finish+0x0/0x2cf
>  [<c116b7c5>] ? netif_receive_skb+0x261/0x281
>  [<f8527bfc>] ? e1000_clean_rx_irq+0x31c/0x3c3 [e1000]
>  [<f852a6fa>] ? e1000_clean+0x2a7/0x3f5 [e1000]
>  [<c11c783c>] ? _spin_unlock_irqrestore+0xe/0x21
>  [<c10354c0>] ? hrtimer_run_pending+0xd/0xa5
>  [<c11c769b>] ? _spin_lock_irq+0xe/0x24
>  [<c116bce5>] ? net_rx_action+0x57/0xfd
>  [<c1027ea3>] ? __do_softirq+0x7a/0xe3
>  [<c1027e29>] ? __do_softirq+0x0/0xe3
>  <IRQ>  [<c1027c3c>] ? irq_exit+0x29/0x63
>  [<c1004320>] ? do_IRQ+0x7c/0x8d
>  [<c1002f29>] ? common_interrupt+0x29/0x30
> ---[ end trace e643d9455a26ccf5 ]---
> 
> 
> 


Hmm, one other sk_forward_alloc corruption I guess...

I fixed one corruption but this is only about UDP sockets used by SUNRPC,
while your traces seems to point a TCP problem.


This is a note to let you know that we have just queued up the patch titled

    Subject: net: fix sk_forward_alloc corruption

to the 2.6.31-stable tree.  Its filename is

    net-fix-sk_forward_alloc-corruption.patch

A git repo of this tree can be found at 
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary


From 4432366eece70b6cf72a7e862945ea8c9e576e3d Mon Sep 17 00:00:00 2001
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 15 Nov 2009 20:50:00 -0800
Subject: net: fix sk_forward_alloc corruption

From: Eric Dumazet <eric.dumazet@gmail.com>

[ Upstream commit: 9d410c796067686b1e032d54ce475b7055537138 ]

On UDP sockets, we must call skb_free_datagram() with socket locked,
or risk sk_forward_alloc corruption. This requirement is not respected
in SUNRPC.

Add a convenient helper, skb_free_datagram_locked() and use it in SUNRPC

Reported-by: Francis Moreau <francis.moro@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 include/linux/skbuff.h |    2 ++
 net/core/datagram.c    |   10 +++++++++-
 net/ipv4/udp.c         |    4 +---
 net/ipv6/udp.c         |    4 +---
 net/sunrpc/svcsock.c   |   10 +++++-----
 5 files changed, 18 insertions(+), 12 deletions(-)

--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1761,6 +1761,8 @@ extern int	       skb_copy_datagram_cons
 						     int to_offset,
 						     int size);
 extern void	       skb_free_datagram(struct sock *sk, struct sk_buff *skb);
+extern void	       skb_free_datagram_locked(struct sock *sk,
+						struct sk_buff *skb);
 extern int	       skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
 					 unsigned int flags);
 extern __wsum	       skb_checksum(const struct sk_buff *skb, int offset,
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -223,6 +223,15 @@ void skb_free_datagram(struct sock *sk, 
 	consume_skb(skb);
 	sk_mem_reclaim_partial(sk);
 }
+EXPORT_SYMBOL(skb_free_datagram);
+
+void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
+{
+	lock_sock(sk);
+	skb_free_datagram(sk, skb);
+	release_sock(sk);
+}
+EXPORT_SYMBOL(skb_free_datagram_locked);
 
 /**
  *	skb_kill_datagram - Free a datagram skbuff forcibly
@@ -749,5 +758,4 @@ unsigned int datagram_poll(struct file *
 EXPORT_SYMBOL(datagram_poll);
 EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
 EXPORT_SYMBOL(skb_copy_datagram_iovec);
-EXPORT_SYMBOL(skb_free_datagram);
 EXPORT_SYMBOL(skb_recv_datagram);
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -987,9 +987,7 @@ try_again:
 		err = ulen;
 
 out_free:
-	lock_sock(sk);
-	skb_free_datagram(sk, skb);
-	release_sock(sk);
+	skb_free_datagram_locked(sk, skb);
 out:
 	return err;
 
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -288,9 +288,7 @@ try_again:
 		err = ulen;
 
 out_free:
-	lock_sock(sk);
-	skb_free_datagram(sk, skb);
-	release_sock(sk);
+	skb_free_datagram_locked(sk, skb);
 out:
 	return err;
 
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -110,7 +110,7 @@ static void svc_release_skb(struct svc_r
 		rqstp->rq_xprt_ctxt = NULL;
 
 		dprintk("svc: service %p, releasing skb %p\n", rqstp, skb);
-		skb_free_datagram(svsk->sk_sk, skb);
+		skb_free_datagram_locked(svsk->sk_sk, skb);
 	}
 }
 
@@ -537,7 +537,7 @@ static int svc_udp_recvfrom(struct svc_r
 			printk("rpcsvc: received unknown control message:"
 			       "%d/%d\n",
 			       cmh->cmsg_level, cmh->cmsg_type);
-		skb_free_datagram(svsk->sk_sk, skb);
+		skb_free_datagram_locked(svsk->sk_sk, skb);
 		return 0;
 	}
 	svc_udp_get_dest_address(rqstp, cmh);
@@ -548,18 +548,18 @@ static int svc_udp_recvfrom(struct svc_r
 		if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) {
 			local_bh_enable();
 			/* checksum error */
-			skb_free_datagram(svsk->sk_sk, skb);
+			skb_free_datagram_locked(svsk->sk_sk, skb);
 			return 0;
 		}
 		local_bh_enable();
-		skb_free_datagram(svsk->sk_sk, skb);
+		skb_free_datagram_locked(svsk->sk_sk, skb);
 	} else {
 		/* we can use it in-place */
 		rqstp->rq_arg.head[0].iov_base = skb->data +
 			sizeof(struct udphdr);
 		rqstp->rq_arg.head[0].iov_len = len;
 		if (skb_checksum_complete(skb)) {
-			skb_free_datagram(svsk->sk_sk, skb);
+			skb_free_datagram_locked(svsk->sk_sk, skb);
 			return 0;
 		}
 		rqstp->rq_xprt_ctxt = skb;

^ permalink raw reply

* [PATCH net-next]atl1e:disable NETIF_F_TSO6 for hardware limit
From: jie.yang @ 2009-12-02  3:18 UTC (permalink / raw)
  To: davem; +Cc: ben, 558426, netdev, linux-kernel, Jie Yang

From: Jie Yang <jie.yang@atheros.com>

For hardware limit to support TSOV6, just disable this feature
Signed-off-by: Jie Yang <jie.yang@atheros.com>
---

 drivers/net/atl1e/atl1e_main.c |   36 ------------------------------------
 1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index ad17e74..08f8c09 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1664,41 +1664,6 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter,
 			}
 			return 0;
 		}
-
-		if (offload_type & SKB_GSO_TCPV6) {
-			real_len = (((unsigned char *)ipv6_hdr(skb) - skb->data)
-					+ ntohs(ipv6_hdr(skb)->payload_len));
-			if (real_len < skb->len)
-				pskb_trim(skb, real_len);
-
-			/* check payload == 0 byte ? */
-			hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
-			if (unlikely(skb->len == hdr_len)) {
-				/* only xsum need */
-				dev_warn(&pdev->dev,
-					"IPV6 tso with zero data??\n");
-				goto check_sum;
-			} else {
-				tcp_hdr(skb)->check = ~csum_ipv6_magic(
-						&ipv6_hdr(skb)->saddr,
-						&ipv6_hdr(skb)->daddr,
-						0, IPPROTO_TCP, 0);
-				tpd->word3 |= 1 << TPD_IP_VERSION_SHIFT;
-				hdr_len >>= 1;
-				tpd->word3 |= (hdr_len & TPD_V6_IPHLLO_MASK) <<
-					TPD_V6_IPHLLO_SHIFT;
-				tpd->word3 |= ((hdr_len >> 3) &
-					TPD_V6_IPHLHI_MASK) <<
-					TPD_V6_IPHLHI_SHIFT;
-				tpd->word3 |= (tcp_hdrlen(skb) >> 2 &
-					TPD_TCPHDRLEN_MASK) <<
-					TPD_TCPHDRLEN_SHIFT;
-				tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
-					TPD_MSS_MASK) << TPD_MSS_SHIFT;
-					tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
-			}
-		}
-		return 0;
 	}
 
 check_sum:
@@ -2287,7 +2252,6 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
 		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 	netdev->features |= NETIF_F_LLTX;
 	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
 
 	return 0;
 }

^ permalink raw reply related

* RE: TSOv6 broken in atl1e
From: Jie Yang @ 2009-12-02  2:24 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: 558426@bugs.debian.org, netdev
In-Reply-To: <1259637579.3709.196.camel@localhost>

On Tuesday, December 01, 2009 11:20 AM
Ben Hutchings <ben@decadent.org.uk> wrote:


>
> I received a bug report <http://bugs.debian.org/558426> that
> shows atl1e corrupting IPv6 packets.  I have reproduced this
> on an Eee PC 901 and found that it is linked to TSO.  The
> most obvious thing wrong with the driver code is that it
> calculates the super-packet length incorrectly.
> However, fixing that:
>
> --- a/drivers/net/atl1e/atl1e_main.c
> +++ b/drivers/net/atl1e/atl1e_main.c
> @@ -1667,6 +1667,7 @@ static int atl1e_tso_csum(struct
> atl1e_adapter *adapter,
>
>               if (offload_type & SKB_GSO_TCPV6) {
>                       real_len = (((unsigned char
> *)ipv6_hdr(skb) - skb->data)
> +                                     + sizeof(struct ipv6hdr)
>                                       +
> ntohs(ipv6_hdr(skb)->payload_len));
>                       if (real_len < skb->len)
>                               pskb_trim(skb, real_len);
> --- END ---
>
> does not solve the problem.  Presumably this function is not
> constructing correct DMA descriptors for TSOv6.
>
> Please fix this, or I will submit a patch to remove this
> feature from the driver.
>

ou, there is hareware limit to support TSOv6, just disable it.

Best wishes
jie

^ permalink raw reply

* Wiki for networking drivers
From: Luis R. Rodriguez @ 2009-12-02  2:03 UTC (permalink / raw)
  To: netdev

Curious if there was a place I can add documentation for Atheros
Ethernet drivers just as we have extensive documentation for 802.11
drivers here:

http://wireless.kernel.org/en/users/Drivers/Atheros

Please CC me as I'm not subscribed.

  Luis

^ permalink raw reply

* [net-next-2.6 PATCH 9/9] e1000e: Use sizeof struct rather than pointer in e1000_get_eeprom()
From: Jeff Kirsher @ 2009-12-02  1:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Roel Kluin, Jeff Kirsher
In-Reply-To: <20091202015250.592.56893.stgit@localhost.localdomain>

From: Roel Kluin <roel.kluin@gmail.com>

Don't use the sizeof the pointer to clear the result

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ethtool.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index b6243ca..0aa50c2 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -535,7 +535,8 @@ static int e1000_get_eeprom(struct net_device *netdev,
 
 	if (ret_val) {
 		/* a read error occurred, throw away the result */
-		memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
+		memset(eeprom_buff, 0xff, sizeof(u16) *
+		       (last_word - first_word + 1));
 	} else {
 		/* Device's eeprom is always little-endian, word addressable */
 		for (i = 0; i < last_word - first_word + 1; i++)


^ permalink raw reply related

* [net-next-2.6 PATCH 8/9] e1000e: PHY type cleanups in e1000e_check_downshift()
From: Jeff Kirsher @ 2009-12-02  1:53 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher
In-Reply-To: <20091202015250.592.56893.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

Remove the case for 82577 because it does not support the ability to check
for downshift.  Add case for e1000_phy_bm which can do this.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/phy.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 3e5940a..0c69649 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -1525,8 +1525,8 @@ s32 e1000e_check_downshift(struct e1000_hw *hw)
 	switch (phy->type) {
 	case e1000_phy_m88:
 	case e1000_phy_gg82563:
+	case e1000_phy_bm:
 	case e1000_phy_82578:
-	case e1000_phy_82577:
 		offset	= M88E1000_PHY_SPEC_STATUS;
 		mask	= M88E1000_PSSR_DOWNSHIFT;
 		break;


^ permalink raw reply related

* [net-next-2.6 PATCH 7/9] e1000e: add debug messages
From: Jeff Kirsher @ 2009-12-02  1:53 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher

From: Bruce Allan <bruce.w.allan@intel.com>

Add some helpful debug messages.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ich8lan.c |    4 +++-
 drivers/net/e1000e/phy.c     |   26 ++++++++++++++++++++------
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 1ce2bf9..6efb77f 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -314,8 +314,10 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
 		phy->ops.write_reg = e1000e_write_phy_reg_bm;
 		phy->ops.read_reg  = e1000e_read_phy_reg_bm;
 		ret_val = e1000e_determine_phy_address(hw);
-		if (ret_val)
+		if (ret_val) {
+			e_dbg("Cannot determine PHY addr. Erroring out\n");
 			return ret_val;
+		}
 	}
 
 	phy->id = 0;
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 1bc09b2..3e5940a 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -2472,7 +2472,7 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 	/* Gig must be disabled for MDIO accesses to page 800 */
 	if ((hw->mac.type == e1000_pchlan) &&
 	   (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
-		e_dbg("Attempting to access page 800 while gig enabled\n");
+		e_dbg("Attempting to access page 800 while gig enabled.\n");
 
 	/* All operations in this function are phy address 1 */
 	hw->phy.addr = 1;
@@ -2482,20 +2482,26 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
 
 	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not read PHY page 769\n");
 		goto out;
+	}
 
 	/* First clear bit 4 to avoid a power state change */
 	phy_reg &= ~(BM_WUC_HOST_WU_BIT);
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not clear PHY page 769 bit 4\n");
 		goto out;
+	}
 
 	/* Write bit 2 = 1, and clear bit 4 to 769_17 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
 	                                    phy_reg | BM_WUC_ENABLE_BIT);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not write PHY page 769 bit 2\n");
 		goto out;
+	}
 
 	/* Select page 800 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
@@ -2503,8 +2509,10 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 
 	/* Write the page 800 offset value using opcode 0x11 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not write address opcode to page 800\n");
 		goto out;
+	}
 
 	if (read) {
 	        /* Read the page 800 value using opcode 0x12 */
@@ -2516,8 +2524,10 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 						    *data);
 	}
 
-	if (ret_val)
+	if (ret_val) {
+		e_dbg("Could not access data value from page 800\n");
 		goto out;
+	}
 
 	/*
 	 * Restore 769_17.2 to its original value
@@ -2528,6 +2538,10 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 
 	/* Clear 769_17.2 */
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+	if (ret_val) {
+		e_dbg("Could not clear PHY page 769 bit 2\n");
+		goto out;
+	}
 
 out:
 	return ret_val;


^ permalink raw reply related

* [net-next-2.6 PATCH 6/9] e1000e: comment corrections
From: Jeff Kirsher @ 2009-12-02  1:51 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher
In-Reply-To: <20091202014931.519.25024.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/82571.c   |    2 +-
 drivers/net/e1000e/ich8lan.c |    5 ++---
 drivers/net/e1000e/lib.c     |    5 +----
 drivers/net/e1000e/phy.c     |   14 +++++++-------
 4 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 227f3d0..f6f3a22 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1551,7 +1551,7 @@ bool e1000e_get_laa_state_82571(struct e1000_hw *hw)
  *  @hw: pointer to the HW structure
  *  @state: enable/disable locally administered address
  *
- *  Enable/Disable the current locally administers address state.
+ *  Enable/Disable the current locally administered address state.
  **/
 void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state)
 {
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index fbbc6dd..1ce2bf9 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -1747,7 +1747,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 	if (hsfsts.hsf_status.flcinprog == 0) {
 		/*
 		 * There is no cycle running at present,
-		 * so we can start a cycle
+		 * so we can start a cycle.
 		 * Begin by setting Flash Cycle Done.
 		 */
 		hsfsts.hsf_status.flcdone = 1;
@@ -1755,7 +1755,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 		ret_val = 0;
 	} else {
 		/*
-		 * otherwise poll for sometime so the current
+		 * Otherwise poll for sometime so the current
 		 * cycle has a chance to end before giving up.
 		 */
 		for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
@@ -2645,7 +2645,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 		ctrl |= E1000_CTRL_PHY_RST;
 	}
 	ret_val = e1000_acquire_swflag_ich8lan(hw);
-	/* Whether or not the swflag was acquired, we need to reset the part */
 	e_dbg("Issuing a global reset to ich8lan\n");
 	ew32(CTRL, (ctrl | E1000_CTRL_RST));
 	msleep(20);
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index e3976ea..a86c175 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -1086,7 +1086,6 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		 *   1   |    1    |   0   |    0    | e1000_fc_none
 		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
 		 *
-		 *
 		 * Are both PAUSE bits set to 1?  If so, this implies
 		 * Symmetric Flow Control is enabled at both ends.  The
 		 * ASM_DIR bits are irrelevant per the spec.
@@ -1124,7 +1123,6 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
 		 *-------|---------|-------|---------|--------------------
 		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-		 *
 		 */
 		else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
 			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
@@ -1140,7 +1138,6 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
 		 *-------|---------|-------|---------|--------------------
 		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
-		 *
 		 */
 		else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
 			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
@@ -2363,7 +2360,7 @@ static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
 }
 
 /**
- *  e1000_mng_host_if_write - Writes to the manageability host interface
+ *  e1000_mng_host_if_write - Write to the manageability host interface
  *  @hw: pointer to the HW structure
  *  @buffer: pointer to the host interface buffer
  *  @length: size of the buffer
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 140b23b..1bc09b2 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -153,10 +153,10 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw)
 			goto out;
 
 		/*
-		 * If the PHY ID is still unknown, we may have an 82577i
-		 * without link.  We will try again after setting Slow
-		 * MDIC mode. No harm in trying again in this case since
-		 * the PHY ID is unknown at this point anyway
+		 * If the PHY ID is still unknown, we may have an 82577
+		 * without link.  We will try again after setting Slow MDIC
+		 * mode. No harm in trying again in this case since the PHY
+		 * ID is unknown at this point anyway.
 		 */
 		ret_val = phy->ops.acquire(hw);
 		if (ret_val)
@@ -1744,7 +1744,7 @@ out:
  *  The automatic gain control (agc) normalizes the amplitude of the
  *  received signal, adjusting for the attenuation produced by the
  *  cable.  By reading the AGC registers, which represent the
- *  combination of course and fine gain value, the value can be put
+ *  combination of coarse and fine gain value, the value can be put
  *  into a lookup table to obtain the approximate cable length
  *  for each channel.
  **/
@@ -1769,7 +1769,7 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
 
 		/*
 		 * Getting bits 15:9, which represent the combination of
-		 * course and fine gain values.  The result is a number
+		 * coarse and fine gain values.  The result is a number
 		 * that can be put into the lookup table to obtain the
 		 * approximate cable length.
 		 */
@@ -2511,7 +2511,7 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 		ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
 		                                   data);
 	} else {
-	        /* Read the page 800 value using opcode 0x12 */
+	        /* Write the page 800 value using opcode 0x12 */
 		ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
 						    *data);
 	}


^ permalink raw reply related

* [net-next-2.6 PATCH 5/9] e1000e: enable new 82567V-3 device
From: Jeff Kirsher @ 2009-12-02  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher
In-Reply-To: <20091202014931.519.25024.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

This new PCI device ID is for a new combination of MAC and PHY both of
which already have supporting code in the driver, just not yet in this
combination.  During validation of the device, an intermittent issue was
discovered with waking it from a suspended state which can be resolved with
the pre-existing workaround to disable gigabit speed prior to suspending.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/hw.h      |    1 +
 drivers/net/e1000e/ich8lan.c |    1 +
 drivers/net/e1000e/netdev.c  |    1 +
 3 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index e0addf3..41609d5 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -356,6 +356,7 @@ enum e1e_registers {
 #define E1000_DEV_ID_80003ES2LAN_COPPER_SPT	0x10BA
 #define E1000_DEV_ID_80003ES2LAN_SERDES_SPT	0x10BB
 
+#define E1000_DEV_ID_ICH8_82567V_3		0x1501
 #define E1000_DEV_ID_ICH8_IGP_M_AMT		0x1049
 #define E1000_DEV_ID_ICH8_IGP_AMT		0x104A
 #define E1000_DEV_ID_ICH8_IGP_C			0x104B
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 9c38955..fbbc6dd 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -3204,6 +3204,7 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
 	u32 phy_ctrl;
 
 	switch (hw->mac.type) {
+	case e1000_ich8lan:
 	case e1000_ich9lan:
 	case e1000_ich10lan:
 	case e1000_pchlan:
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index ab4db52..d57880e 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -5342,6 +5342,7 @@ static struct pci_device_id e1000_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
 
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },


^ permalink raw reply related

* [net-next-2.6 PATCH 4/9] e1000e: ensure the link state is correct for serdes links
From: Jeff Kirsher @ 2009-12-02  1:49 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher

From: Bruce Allan <bruce.w.allan@intel.com>

This patch ensures that the link state (as reported in
mac->serdes_has_link) will transition to false when autoneg fails to
complete but valid codewords were detected.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/82571.c |   76 ++++++++++++++++++++++++++++----------------
 1 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 26ea5d5..227f3d0 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1356,8 +1356,20 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
  *  e1000_check_for_serdes_link_82571 - Check for link (Serdes)
  *  @hw: pointer to the HW structure
  *
- *  Checks for link up on the hardware.  If link is not up and we have
- *  a signal, then we need to force link up.
+ *  Reports the link state as up or down.
+ *
+ *  If autonegotiation is supported by the link partner, the link state is
+ *  determined by the result of autonegotiation. This is the most likely case.
+ *  If autonegotiation is not supported by the link partner, and the link
+ *  has a valid signal, force the link up.
+ *
+ *  The link state is represented internally here by 4 states:
+ *
+ *  1) down
+ *  2) autoneg_progress
+ *  3) autoneg_complete (the link sucessfully autonegotiated)
+ *  4) forced_up (the link has been forced up, it did not autonegotiate)
+ *
  **/
 static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
 {
@@ -1383,6 +1395,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
 				 */
 				mac->serdes_link_state =
 				    e1000_serdes_link_autoneg_progress;
+				mac->serdes_has_link = false;
 				e_dbg("AN_UP     -> AN_PROG\n");
 			}
 		break;
@@ -1397,57 +1410,64 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
 			if (rxcw & E1000_RXCW_C) {
 				/* Enable autoneg, and unforce link up */
 				ew32(TXCW, mac->txcw);
-				ew32(CTRL,
-				    (ctrl & ~E1000_CTRL_SLU));
+				ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 				mac->serdes_link_state =
 				    e1000_serdes_link_autoneg_progress;
+				mac->serdes_has_link = false;
 				e_dbg("FORCED_UP -> AN_PROG\n");
 			}
 			break;
 
 		case e1000_serdes_link_autoneg_progress:
-			/*
-			 * If the LU bit is set in the STATUS register,
-			 * autoneg has completed sucessfully. If not,
-			 * try foring the link because the far end may be
-			 * available but not capable of autonegotiation.
-			 */
-			if (status & E1000_STATUS_LU)  {
-				mac->serdes_link_state =
-				    e1000_serdes_link_autoneg_complete;
-				e_dbg("AN_PROG   -> AN_UP\n");
+			if (rxcw & E1000_RXCW_C) {
+				/*
+				 * We received /C/ ordered sets, meaning the
+				 * link partner has autonegotiated, and we can
+				 * trust the Link Up (LU) status bit.
+				 */
+				if (status & E1000_STATUS_LU) {
+					mac->serdes_link_state =
+					    e1000_serdes_link_autoneg_complete;
+					e_dbg("AN_PROG   -> AN_UP\n");
+					mac->serdes_has_link = true;
+				} else {
+					/* Autoneg completed, but failed. */
+					mac->serdes_link_state =
+					    e1000_serdes_link_down;
+					e_dbg("AN_PROG   -> DOWN\n");
+				}
 			} else {
 				/*
-				 * Disable autoneg, force link up and
-				 * full duplex, and change state to forced
+				 * The link partner did not autoneg.
+				 * Force link up and full duplex, and change
+				 * state to forced.
 				 */
-				ew32(TXCW,
-				    (mac->txcw & ~E1000_TXCW_ANE));
+				ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
 				ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
 				ew32(CTRL, ctrl);
 
 				/* Configure Flow Control after link up. */
-				ret_val =
-				    e1000e_config_fc_after_link_up(hw);
+				ret_val = e1000e_config_fc_after_link_up(hw);
 				if (ret_val) {
 					e_dbg("Error config flow control\n");
 					break;
 				}
 				mac->serdes_link_state =
 				    e1000_serdes_link_forced_up;
+				mac->serdes_has_link = true;
 				e_dbg("AN_PROG   -> FORCED_UP\n");
 			}
-			mac->serdes_has_link = true;
 			break;
 
 		case e1000_serdes_link_down:
 		default:
-			/* The link was down but the receiver has now gained
+			/*
+			 * The link was down but the receiver has now gained
 			 * valid sync, so lets see if we can bring the link
-			 * up. */
+			 * up.
+			 */
 			ew32(TXCW, mac->txcw);
-			ew32(CTRL,
-			    (ctrl & ~E1000_CTRL_SLU));
+			ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 			mac->serdes_link_state =
 			    e1000_serdes_link_autoneg_progress;
 			e_dbg("DOWN      -> AN_PROG\n");
@@ -1460,9 +1480,9 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
 			e_dbg("ANYSTATE  -> DOWN\n");
 		} else {
 			/*
-			 * We have sync, and can tolerate one
-			 * invalid (IV) codeword before declaring
-			 * link down, so reread to look again
+			 * We have sync, and can tolerate one invalid (IV)
+			 * codeword before declaring link down, so reread
+			 * to look again.
 			 */
 			udelay(10);
 			rxcw = er32(RXCW);


^ permalink raw reply related

* [net-next-2.6 PATCH 3/9] e1000e: provide family-specific PHY power up/down operations
From: Jeff Kirsher @ 2009-12-02  1:47 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher
In-Reply-To: <20091202014641.396.57708.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

The different families (80003es2lan, 8257x, ICHx/PCH) supported by the
driver each have their own conditions when the PHY can be powered down.
This patch rewrites the PHY power up/down code to fit with the family-
specific style used in the driver.  All pre-existing calls to power up or
down the PHY remain untouched.  A new call to power down the PHY when
removing the driver when the interface is down replaces the current call
to reset the PHY in order to reduce power consumption.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/82571.c   |   26 ++++++++++++++++++++++
 drivers/net/e1000e/e1000.h   |    2 ++
 drivers/net/e1000e/es2lan.c  |   21 ++++++++++++++++++
 drivers/net/e1000e/hw.h      |    2 ++
 drivers/net/e1000e/ich8lan.c |   23 +++++++++++++++++++
 drivers/net/e1000e/netdev.c  |   50 +++++++++---------------------------------
 drivers/net/e1000e/phy.c     |   37 +++++++++++++++++++++++++++++++
 7 files changed, 122 insertions(+), 39 deletions(-)

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 8ea3ed7..26ea5d5 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -69,6 +69,7 @@ static void e1000_clear_vfta_82571(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
 static s32 e1000_led_on_82574(struct e1000_hw *hw);
 static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
+static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
 
 /**
  *  e1000_init_phy_params_82571 - Init PHY func ptrs.
@@ -88,6 +89,9 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
 	phy->autoneg_mask		 = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 	phy->reset_delay_us		 = 100;
 
+	phy->ops.power_up		 = e1000_power_up_phy_copper;
+	phy->ops.power_down		 = e1000_power_down_phy_copper_82571;
+
 	switch (hw->mac.type) {
 	case e1000_82571:
 	case e1000_82572:
@@ -1601,6 +1605,28 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
 }
 
 /**
+ * e1000_power_down_phy_copper_82571 - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	struct e1000_mac_info *mac = &hw->mac;
+
+	if (!(phy->ops.check_reset_block))
+		return;
+
+	/* If the management interface is not enabled, then power down */
+	if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw)))
+		e1000_power_down_phy_copper(hw);
+
+	return;
+}
+
+/**
  *  e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters
  *  @hw: pointer to the HW structure
  *
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 4c08752..c4e861f 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -568,6 +568,8 @@ extern s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset,
 extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 			       u32 usec_interval, bool *success);
 extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
+extern void e1000_power_up_phy_copper(struct e1000_hw *hw);
+extern void e1000_power_down_phy_copper(struct e1000_hw *hw);
 extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000e_check_downshift(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 3f435c1..c7bc657 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -114,6 +114,7 @@ static s32  e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
                                             u16 *data);
 static s32  e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
                                              u16 data);
+static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw);
 
 /**
  *  e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs.
@@ -127,6 +128,9 @@ static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw)
 	if (hw->phy.media_type != e1000_media_type_copper) {
 		phy->type	= e1000_phy_none;
 		return 0;
+	} else {
+		phy->ops.power_up = e1000_power_up_phy_copper;
+		phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan;
 	}
 
 	phy->addr		= 1;
@@ -1303,6 +1307,23 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
 }
 
 /**
+ * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw)
+{
+	/* If the management interface is not enabled, then power down */
+	if (!(hw->mac.ops.check_mng_mode(hw) ||
+	      hw->phy.ops.check_reset_block(hw)))
+		e1000_power_down_phy_copper(hw);
+
+	return;
+}
+
+/**
  *  e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters
  *  @hw: pointer to the HW structure
  *
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 6c3d55f..e0addf3 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -774,6 +774,8 @@ struct e1000_phy_operations {
 	s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
 	s32  (*write_reg)(struct e1000_hw *, u32, u16);
 	s32  (*write_reg_locked)(struct e1000_hw *, u32, u16);
+	void (*power_up)(struct e1000_hw *);
+	void (*power_down)(struct e1000_hw *);
 };
 
 /* Function pointers for the NVM. */
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 7530fc5..9c38955 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -217,6 +217,7 @@ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
 static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
 static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
 static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
+static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw);
 static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
 static s32  e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
 
@@ -266,6 +267,8 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 	phy->ops.set_d3_lplu_state    = e1000_set_lplu_state_pchlan;
 	phy->ops.write_reg            = e1000_write_phy_reg_hv;
 	phy->ops.write_reg_locked     = e1000_write_phy_reg_hv_locked;
+	phy->ops.power_up             = e1000_power_up_phy_copper;
+	phy->ops.power_down           = e1000_power_down_phy_copper_ich8lan;
 	phy->autoneg_mask             = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
 	phy->id = e1000_phy_unknown;
@@ -299,6 +302,9 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
 	phy->addr			= 1;
 	phy->reset_delay_us		= 100;
 
+	phy->ops.power_up               = e1000_power_up_phy_copper;
+	phy->ops.power_down             = e1000_power_down_phy_copper_ich8lan;
+
 	/*
 	 * We may need to do this twice - once for IGP and if that fails,
 	 * we'll set BM func pointers and try again
@@ -3392,6 +3398,23 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
 }
 
 /**
+ * e1000_power_down_phy_copper_ich8lan - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw)
+{
+	/* If the management interface is not enabled, then power down */
+	if (!(hw->mac.ops.check_mng_mode(hw) ||
+	      hw->phy.ops.check_reset_block(hw)))
+		e1000_power_down_phy_copper(hw);
+
+	return;
+}
+
+/**
  *  e1000_clear_hw_cntrs_ich8lan - Clear statistical counters
  *  @hw: pointer to the HW structure
  *
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 2381cb7..ab4db52 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2641,18 +2641,8 @@ static void e1000_configure(struct e1000_adapter *adapter)
  **/
 void e1000e_power_up_phy(struct e1000_adapter *adapter)
 {
-	u16 mii_reg = 0;
-
-	/* Just clear the power down bit to wake the phy back up */
-	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
-		/*
-		 * According to the manual, the phy will retain its
-		 * settings across a power-down/up cycle
-		 */
-		e1e_rphy(&adapter->hw, PHY_CONTROL, &mii_reg);
-		mii_reg &= ~MII_CR_POWER_DOWN;
-		e1e_wphy(&adapter->hw, PHY_CONTROL, mii_reg);
-	}
+	if (adapter->hw.phy.ops.power_up)
+		adapter->hw.phy.ops.power_up(&adapter->hw);
 
 	adapter->hw.mac.ops.setup_link(&adapter->hw);
 }
@@ -2660,35 +2650,17 @@ void e1000e_power_up_phy(struct e1000_adapter *adapter)
 /**
  * e1000_power_down_phy - Power down the PHY
  *
- * Power down the PHY so no link is implied when interface is down
- * The PHY cannot be powered down is management or WoL is active
+ * Power down the PHY so no link is implied when interface is down.
+ * The PHY cannot be powered down if management or WoL is active.
  */
 static void e1000_power_down_phy(struct e1000_adapter *adapter)
 {
-	struct e1000_hw *hw = &adapter->hw;
-	u16 mii_reg;
-
 	/* WoL is enabled */
 	if (adapter->wol)
 		return;
 
-	/* non-copper PHY? */
-	if (adapter->hw.phy.media_type != e1000_media_type_copper)
-		return;
-
-	/* reset is blocked because of a SoL/IDER session */
-	if (e1000e_check_mng_mode(hw) || e1000_check_reset_block(hw))
-		return;
-
-	/* manageability (AMT) is enabled */
-	if (er32(MANC) & E1000_MANC_SMBUS_EN)
-		return;
-
-	/* power down the PHY */
-	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
-	mii_reg |= MII_CR_POWER_DOWN;
-	e1e_wphy(hw, PHY_CONTROL, mii_reg);
-	mdelay(1);
+	if (adapter->hw.phy.ops.power_down)
+		adapter->hw.phy.ops.power_down(&adapter->hw);
 }
 
 /**
@@ -5294,17 +5266,17 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 	cancel_work_sync(&adapter->print_hang_task);
 	flush_scheduled_work();
 
+	if (!(netdev->flags & IFF_UP))
+		e1000_power_down_phy(adapter);
+
+	unregister_netdev(netdev);
+
 	/*
 	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant.
 	 */
 	e1000_release_hw_control(adapter);
 
-	unregister_netdev(netdev);
-
-	if (!e1000_check_reset_block(&adapter->hw))
-		e1000_phy_hw_reset(&adapter->hw);
-
 	e1000e_reset_interrupt_capability(adapter);
 	kfree(adapter->tx_ring);
 	kfree(adapter->rx_ring);
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 9ce4997..140b23b 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -2534,6 +2534,43 @@ out:
 }
 
 /**
+ * e1000_power_up_phy_copper - Restore copper link in case of PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, restore the link to previous
+ * settings.
+ **/
+void e1000_power_up_phy_copper(struct e1000_hw *hw)
+{
+	u16 mii_reg = 0;
+
+	/* The PHY will retain its settings across a power down/up cycle */
+	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
+	mii_reg &= ~MII_CR_POWER_DOWN;
+	e1e_wphy(hw, PHY_CONTROL, mii_reg);
+}
+
+/**
+ * e1000_power_down_phy_copper - Restore copper link in case of PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, restore the link to previous
+ * settings.
+ **/
+void e1000_power_down_phy_copper(struct e1000_hw *hw)
+{
+	u16 mii_reg = 0;
+
+	/* The PHY will retain its settings across a power down/up cycle */
+	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
+	mii_reg |= MII_CR_POWER_DOWN;
+	e1e_wphy(hw, PHY_CONTROL, mii_reg);
+	msleep(1);
+}
+
+/**
  *  e1000e_commit_phy - Soft PHY reset
  *  @hw: pointer to the HW structure
  *


^ permalink raw reply related

* [net-next-2.6 PATCH 2/9] e1000e: guard against buffer overflow in cable length tables
From: Jeff Kirsher @ 2009-12-02  1:47 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher
In-Reply-To: <20091202014641.396.57708.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/es2lan.c |   17 +++++++++++++----
 drivers/net/e1000e/phy.c    |   14 +++++++++++---
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 3ff932f..3f435c1 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -99,6 +99,8 @@
  */
 static const u16 e1000_gg82563_cable_length_table[] =
 	 { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF };
+#define GG82563_CABLE_LENGTH_TABLE_SIZE \
+		ARRAY_SIZE(e1000_gg82563_cable_length_table)
 
 static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw);
 static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
@@ -694,20 +696,27 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val;
+	s32 ret_val = 0;
 	u16 phy_data, index;
 
 	ret_val = e1e_rphy(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);
 	if (ret_val)
-		return ret_val;
+		goto out;
 
 	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
+
+	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) {
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+	}
+
 	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
-	phy->max_cable_length = e1000_gg82563_cable_length_table[index+5];
+	phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
-	return 0;
+out:
+	return ret_val;
 }
 
 /**
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 5cd01c6..9ce4997 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -44,6 +44,8 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
 /* Cable length tables */
 static const u16 e1000_m88_cable_length_table[] =
 	{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
+#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
+		ARRAY_SIZE(e1000_m88_cable_length_table)
 
 static const u16 e1000_igp_2_cable_length_table[] =
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
@@ -1717,15 +1719,21 @@ s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
 	if (ret_val)
-		return ret_val;
+		goto out;
 
 	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-		M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+	        M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+	}
+
 	phy->min_cable_length = e1000_m88_cable_length_table[index];
-	phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
+out:
 	return ret_val;
 }
 


^ permalink raw reply related

* [net-next-2.6 PATCH 1/9] e1000e: provide family-specific functions to manage VLAN filter arrays
From: Jeff Kirsher @ 2009-12-02  1:46 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher

From: Bruce Allan <bruce.w.allan@intel.com>

The two MAC-families that have VLAN filter table register arrays manage
each a bit differently from one another, so provide family-specific
functions for managing the register arrays and function pointers to access
the appropriate function.  Also make sure attempts to access these
register arrays are not done on parts not supporting that feature.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/82571.c  |    9 ++++++---
 drivers/net/e1000e/e1000.h  |    4 ++--
 drivers/net/e1000e/es2lan.c |    4 +++-
 drivers/net/e1000e/hw.h     |    2 ++
 drivers/net/e1000e/lib.c    |   21 +++++++++++++++++++--
 drivers/net/e1000e/netdev.c |   21 +++++++++++++--------
 6 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 62bbc6e..8ea3ed7 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -65,6 +65,7 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
 static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
 static s32 e1000_setup_link_82571(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
+static void e1000_clear_vfta_82571(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
 static s32 e1000_led_on_82574(struct e1000_hw *hw);
 static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
@@ -949,7 +950,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
 
 	/* Disabling VLAN filtering */
 	e_dbg("Initializing the IEEE VLAN\n");
-	e1000e_clear_vfta(hw);
+	mac->ops.clear_vfta(hw);
 
 	/* Setup the receive address. */
 	/*
@@ -1128,13 +1129,13 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
 }
 
 /**
- *  e1000e_clear_vfta - Clear VLAN filter table
+ *  e1000_clear_vfta_82571 - Clear VLAN filter table
  *  @hw: pointer to the HW structure
  *
  *  Clears the register array which contains the VLAN filter table by
  *  setting all the values to 0.
  **/
-void e1000e_clear_vfta(struct e1000_hw *hw)
+static void e1000_clear_vfta_82571(struct e1000_hw *hw)
 {
 	u32 offset;
 	u32 vfta_value = 0;
@@ -1656,6 +1657,8 @@ static struct e1000_mac_operations e82571_mac_ops = {
 	/* .led_on: mac type dependent */
 	.led_off		= e1000e_led_off_generic,
 	.update_mc_addr_list	= e1000_update_mc_addr_list_82571,
+	.write_vfta		= e1000_write_vfta_generic,
+	.clear_vfta		= e1000_clear_vfta_82571,
 	.reset_hw		= e1000_reset_hw_82571,
 	.init_hw		= e1000_init_hw_82571,
 	.setup_link		= e1000_setup_link_82571,
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 3102d73..4c08752 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -509,7 +509,7 @@ extern s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw);
 extern s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw);
 extern s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
 extern s32 e1000e_setup_link(struct e1000_hw *hw);
-extern void e1000e_clear_vfta(struct e1000_hw *hw);
+extern void e1000_clear_vfta_generic(struct e1000_hw *hw);
 extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
 extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
 					       u8 *mc_addr_list,
@@ -525,7 +525,7 @@ extern void e1000e_config_collision_dist(struct e1000_hw *hw);
 extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
 extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
 extern s32 e1000e_blink_led(struct e1000_hw *hw);
-extern void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
+extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
 extern void e1000e_reset_adaptive(struct e1000_hw *hw);
 extern void e1000e_update_adaptive(struct e1000_hw *hw);
 
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index e505798..3ff932f 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -807,7 +807,7 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
 
 	/* Disabling VLAN filtering */
 	e_dbg("Initializing the IEEE VLAN\n");
-	e1000e_clear_vfta(hw);
+	mac->ops.clear_vfta(hw);
 
 	/* Setup the receive address. */
 	e1000e_init_rx_addrs(hw, mac->rar_entry_count);
@@ -1350,6 +1350,8 @@ static struct e1000_mac_operations es2_mac_ops = {
 	.led_on			= e1000e_led_on_generic,
 	.led_off		= e1000e_led_off_generic,
 	.update_mc_addr_list	= e1000e_update_mc_addr_list_generic,
+	.write_vfta		= e1000_write_vfta_generic,
+	.clear_vfta		= e1000_clear_vfta_generic,
 	.reset_hw		= e1000_reset_hw_80003es2lan,
 	.init_hw		= e1000_init_hw_80003es2lan,
 	.setup_link		= e1000e_setup_link,
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 426155c..6c3d55f 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -741,6 +741,7 @@ struct e1000_mac_operations {
 	s32  (*check_for_link)(struct e1000_hw *);
 	s32  (*cleanup_led)(struct e1000_hw *);
 	void (*clear_hw_cntrs)(struct e1000_hw *);
+	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
 	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
@@ -751,6 +752,7 @@ struct e1000_mac_operations {
 	s32  (*setup_link)(struct e1000_hw *);
 	s32  (*setup_physical_interface)(struct e1000_hw *);
 	s32  (*setup_led)(struct e1000_hw *);
+	void (*write_vfta)(struct e1000_hw *, u32, u32);
 };
 
 /* Function pointers for the PHY. */
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index f690a10..e3976ea 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -82,7 +82,24 @@ s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
 }
 
 /**
- *  e1000e_write_vfta - Write value to VLAN filter table
+ *  e1000_clear_vfta_generic - Clear VLAN filter table
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the register array which contains the VLAN filter table by
+ *  setting all the values to 0.
+ **/
+void e1000_clear_vfta_generic(struct e1000_hw *hw)
+{
+	u32 offset;
+
+	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
+		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
+		e1e_flush();
+	}
+}
+
+/**
+ *  e1000_write_vfta_generic - Write value to VLAN filter table
  *  @hw: pointer to the HW structure
  *  @offset: register offset in VLAN filter table
  *  @value: register value written to VLAN filter table
@@ -90,7 +107,7 @@ s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
  *  Writes value at the given offset in the register array which stores
  *  the VLAN filter table.
  **/
-void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
 {
 	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
 	e1e_flush();
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index e546b4e..2381cb7 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2031,11 +2031,14 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
 	    (vid == adapter->mng_vlan_id))
 		return;
+
 	/* add VID to filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
-	vfta |= (1 << (vid & 0x1F));
-	e1000e_write_vfta(hw, index, vfta);
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		index = (vid >> 5) & 0x7F;
+		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
+		vfta |= (1 << (vid & 0x1F));
+		hw->mac.ops.write_vfta(hw, index, vfta);
+	}
 }
 
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -2060,10 +2063,12 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 	}
 
 	/* remove VID from filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
-	vfta &= ~(1 << (vid & 0x1F));
-	e1000e_write_vfta(hw, index, vfta);
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		index = (vid >> 5) & 0x7F;
+		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
+		vfta &= ~(1 << (vid & 0x1F));
+		hw->mac.ops.write_vfta(hw, index, vfta);
+	}
 }
 
 static void e1000_update_mng_vlan(struct e1000_adapter *adapter)


^ permalink raw reply related

* [net-next-2.6 PATCH 1/9] e1000e: provide family-specific functions to manage VLAN filter arrays
From: Jeff Kirsher @ 2009-12-02  1:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Bruce Allan, Jeff Kirsher

From: Bruce Allan <bruce.w.allan@intel.com>

The two MAC-families that have VLAN filter table register arrays manage
each a bit differently from one another, so provide family-specific
functions for managing the register arrays and function pointers to access
the appropriate function.  Also make sure attempts to access these
register arrays are not done on parts not supporting that feature.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/82571.c  |    9 ++++++---
 drivers/net/e1000e/e1000.h  |    4 ++--
 drivers/net/e1000e/es2lan.c |    4 +++-
 drivers/net/e1000e/hw.h     |    2 ++
 drivers/net/e1000e/lib.c    |   21 +++++++++++++++++++--
 drivers/net/e1000e/netdev.c |   21 +++++++++++++--------
 6 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 62bbc6e..8ea3ed7 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -65,6 +65,7 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
 static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
 static s32 e1000_setup_link_82571(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
+static void e1000_clear_vfta_82571(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
 static s32 e1000_led_on_82574(struct e1000_hw *hw);
 static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
@@ -949,7 +950,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
 
 	/* Disabling VLAN filtering */
 	e_dbg("Initializing the IEEE VLAN\n");
-	e1000e_clear_vfta(hw);
+	mac->ops.clear_vfta(hw);
 
 	/* Setup the receive address. */
 	/*
@@ -1128,13 +1129,13 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
 }
 
 /**
- *  e1000e_clear_vfta - Clear VLAN filter table
+ *  e1000_clear_vfta_82571 - Clear VLAN filter table
  *  @hw: pointer to the HW structure
  *
  *  Clears the register array which contains the VLAN filter table by
  *  setting all the values to 0.
  **/
-void e1000e_clear_vfta(struct e1000_hw *hw)
+static void e1000_clear_vfta_82571(struct e1000_hw *hw)
 {
 	u32 offset;
 	u32 vfta_value = 0;
@@ -1656,6 +1657,8 @@ static struct e1000_mac_operations e82571_mac_ops = {
 	/* .led_on: mac type dependent */
 	.led_off		= e1000e_led_off_generic,
 	.update_mc_addr_list	= e1000_update_mc_addr_list_82571,
+	.write_vfta		= e1000_write_vfta_generic,
+	.clear_vfta		= e1000_clear_vfta_82571,
 	.reset_hw		= e1000_reset_hw_82571,
 	.init_hw		= e1000_init_hw_82571,
 	.setup_link		= e1000_setup_link_82571,
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 3102d73..4c08752 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -509,7 +509,7 @@ extern s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw);
 extern s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw);
 extern s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
 extern s32 e1000e_setup_link(struct e1000_hw *hw);
-extern void e1000e_clear_vfta(struct e1000_hw *hw);
+extern void e1000_clear_vfta_generic(struct e1000_hw *hw);
 extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
 extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
 					       u8 *mc_addr_list,
@@ -525,7 +525,7 @@ extern void e1000e_config_collision_dist(struct e1000_hw *hw);
 extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
 extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
 extern s32 e1000e_blink_led(struct e1000_hw *hw);
-extern void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
+extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
 extern void e1000e_reset_adaptive(struct e1000_hw *hw);
 extern void e1000e_update_adaptive(struct e1000_hw *hw);
 
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index e505798..3ff932f 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -807,7 +807,7 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
 
 	/* Disabling VLAN filtering */
 	e_dbg("Initializing the IEEE VLAN\n");
-	e1000e_clear_vfta(hw);
+	mac->ops.clear_vfta(hw);
 
 	/* Setup the receive address. */
 	e1000e_init_rx_addrs(hw, mac->rar_entry_count);
@@ -1350,6 +1350,8 @@ static struct e1000_mac_operations es2_mac_ops = {
 	.led_on			= e1000e_led_on_generic,
 	.led_off		= e1000e_led_off_generic,
 	.update_mc_addr_list	= e1000e_update_mc_addr_list_generic,
+	.write_vfta		= e1000_write_vfta_generic,
+	.clear_vfta		= e1000_clear_vfta_generic,
 	.reset_hw		= e1000_reset_hw_80003es2lan,
 	.init_hw		= e1000_init_hw_80003es2lan,
 	.setup_link		= e1000e_setup_link,
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 426155c..6c3d55f 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -741,6 +741,7 @@ struct e1000_mac_operations {
 	s32  (*check_for_link)(struct e1000_hw *);
 	s32  (*cleanup_led)(struct e1000_hw *);
 	void (*clear_hw_cntrs)(struct e1000_hw *);
+	void (*clear_vfta)(struct e1000_hw *);
 	s32  (*get_bus_info)(struct e1000_hw *);
 	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
@@ -751,6 +752,7 @@ struct e1000_mac_operations {
 	s32  (*setup_link)(struct e1000_hw *);
 	s32  (*setup_physical_interface)(struct e1000_hw *);
 	s32  (*setup_led)(struct e1000_hw *);
+	void (*write_vfta)(struct e1000_hw *, u32, u32);
 };
 
 /* Function pointers for the PHY. */
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index f690a10..e3976ea 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -82,7 +82,24 @@ s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
 }
 
 /**
- *  e1000e_write_vfta - Write value to VLAN filter table
+ *  e1000_clear_vfta_generic - Clear VLAN filter table
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the register array which contains the VLAN filter table by
+ *  setting all the values to 0.
+ **/
+void e1000_clear_vfta_generic(struct e1000_hw *hw)
+{
+	u32 offset;
+
+	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
+		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
+		e1e_flush();
+	}
+}
+
+/**
+ *  e1000_write_vfta_generic - Write value to VLAN filter table
  *  @hw: pointer to the HW structure
  *  @offset: register offset in VLAN filter table
  *  @value: register value written to VLAN filter table
@@ -90,7 +107,7 @@ s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
  *  Writes value at the given offset in the register array which stores
  *  the VLAN filter table.
  **/
-void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
 {
 	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
 	e1e_flush();
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index e546b4e..2381cb7 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2031,11 +2031,14 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
 	    (vid == adapter->mng_vlan_id))
 		return;
+
 	/* add VID to filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
-	vfta |= (1 << (vid & 0x1F));
-	e1000e_write_vfta(hw, index, vfta);
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		index = (vid >> 5) & 0x7F;
+		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
+		vfta |= (1 << (vid & 0x1F));
+		hw->mac.ops.write_vfta(hw, index, vfta);
+	}
 }
 
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -2060,10 +2063,12 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 	}
 
 	/* remove VID from filter table */
-	index = (vid >> 5) & 0x7F;
-	vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
-	vfta &= ~(1 << (vid & 0x1F));
-	e1000e_write_vfta(hw, index, vfta);
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		index = (vid >> 5) & 0x7F;
+		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
+		vfta &= ~(1 << (vid & 0x1F));
+		hw->mac.ops.write_vfta(hw, index, vfta);
+	}
 }
 
 static void e1000_update_mng_vlan(struct e1000_adapter *adapter)


^ permalink raw reply related

* Re: SO_BINDTODEVICE and IP_TRANSPARENT (TPROXY)
From: Ashwani Wason @ 2009-12-02  1:18 UTC (permalink / raw)
  To: netdev; +Cc: tproxy
In-Reply-To: <fd1a5ee40911301515y7d5e9f8fq62ff3e28b747c308@mail.gmail.com>

After debugging a bit into how nf_tproxy_get_sock_v4() looks up a
listener for foreign connections using __inet_lookup_listener() and
compute_score() I found that the problem was happening because of the
way I had the TPROXY rules setup. Those rules work if the proxy has a
single listening socket for INADDR_ANY. If multiple listening sockets
must be used, one for each local address, which is the case for using
SO_BINDTODEVICE then the TPROXY rules must also be "fully qualified"
(with interface name [-i] and IP address thereof [--on-ip]). So the
rules in my example change as follows...

Instead of using:

> iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 4002

Use:

iptables -t mangle -A PREROUTING *-i eth0* -p tcp --dport 80 -j TPROXY
--tproxy-mark 0x1/0x1 *--on-ip 192.168.0.65* --on-port 4002
iptables -t mangle -A PREROUTING *-i eth1* -p tcp --dport 80 -j TPROXY
--tproxy-mark 0x1/0x1 *--on-ip 192.168.1.65* --on-port 4002

With these rules the listening socket was looked up correctly and the
sk_bound_dev_if of the socket was honored.

- Ashwani

PS: Sorry to anyone (Jamal) who already spent any time on this.
PPS: Copying the tproxy list in case someone else is looking for this
stuff in the future.


On Mon, Nov 30, 2009 at 3:15 PM, Ashwani Wason <ashwas@gmail.com> wrote:
> It appears that SO_BINDTODEVICE is not working when used along with
> IP_TRANSPARENT of TPROXY. The use case is for a transparent proxy that
> has to handle clients with overlapping IP addresses coming in on
> different interfaces (VLANs or physical). Each such interface has a
> unique next hop gateway.
>
> Setup: Kernel 2.6.30.9 built with required TPROXY configuration. A
> system with three interfaces, eth0 (192.168.0.65/24), eth0.1
> (10.0.7.65/16), and eth1 (192.168.1.65/24), each with its own default
> router and a fairly standard set of TPROXY rules:
>
> default via 192.168.1.62 dev eth1
> default via 192.168.0.62 dev eth0
> default via 10.0.0.9 dev eth0.1
>
> iptables -t mangle -N DIVERT
> iptables -t mangle -A DIVERT -j MARK --set-mark 1
> iptables -t mangle -A DIVERT -j ACCEPT
> iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
> iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY
> --tproxy-mark 0x1/0x1 --on-port 4002
>
> ip rule add fwmark 1 iif eth0 lookup 101
> ip rule add fwmark 1 iif eth1 lookup 101
>
> ip route add local 0.0.0.0/0 dev lo table 101
>
> Additional information:
>
> * The proxy has a separate listening socket for each interface.
>
> * On each listening socket the proxy sets the IP_TRANSPARENT option.
> It also sets the SO_BINDTODEVICE option (on each socket) to the
> associated interface. (I have experimented with the ordering of these
> options and setting one before the other has no change in behavior.)
>
> * The proxy works perfectly fine in "transparent mode" when
> SO_BINDTODEVICE is not used.
>
> * The proxy works perfectly fine in "explicit mode" when
> SO_BINDTODEVICE *is used*.
>
> Now my test is very simple with the expectation that when a SYN comes
> in on, say, interface eth0 then the SYN/ACK must go out back on that
> interface to the MAC address of the designated next hop router. That
> does not seem to happen however. The SYN/ACK is not being sent out at
> all, from any interface. It seems that either the SYN or the SYN/ACK
> is being eaten up somewhere. No one 'netstat -s' seems to be updated
> either. (Since even 'netstat -ant' does not show the TCP connection
> state, I suspect that the SYN is being eaten up.)
>
> When I reconfigure the proxy to be in explicit mode, i.e. not set the
> IP_TRANSPARENT option, and have the clients connect directly to the IP
> address and port of the proxy then the system works as expected, i.e.
> the SYN/ACK (and all subsequent packets) go out on the associated
> interface.
>
> Thank you,
> Ashwani
>

^ permalink raw reply

* Re: [PATCH] crypto: gmac - Add RFC4543 wrapper for GCM
From: Herbert Xu @ 2009-12-02  0:53 UTC (permalink / raw)
  To: David Miller; +Cc: tobias, netdev, linux-crypto
In-Reply-To: <20091201.155141.147973233.davem@davemloft.net>

On Tue, Dec 01, 2009 at 03:51:41PM -0800, David Miller wrote:
> From: Tobias Brunner <tobias@strongswan.org>
> Date: Tue, 01 Dec 2009 17:49:28 +0100
> 
> > This patch adds the RFC4543 (GMAC) wrapper for GCM similar to the
> > existing RFC4106 wrapper. The main differences between GCM and GMAC are
> > the contents of the AAD and that the plaintext is empty for the latter.
> > 
> > Signed-off-by: Tobias Brunner <tobias@strongswan.org>
> 
> Herbert, you got this one?

Sure I'll pick it up.

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* [WARNING] Network-related warnings with 2.6.31.6
From: Chris Rankin @ 2009-12-02  0:34 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev

Hi,

I've just noticed these warnings in my dmesg log, and have no idea what might have triggered them. e1000 related, perhaps?

Cheers,
Chris

------------[ cut here ]------------
WARNING: at /home/chris/LINUX/linux-2.6.31/net/core/stream.c:202 inet_csk_destroy_sock+0x77/0xd3()
Hardware name: Precision WorkStation 650    
Modules linked in: tun snd_seq_oss snd_seq_midi snd_seq_dummy fuse nfsd lockd auth_rpcgss exportfs sunrpc autofs4 af_packet ipt_LOG nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_LOG nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 p4_clockmod speedstep_lib binfmt_misc dm_mirror dm_region_hash dm_log dm_mod uinput snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_event snd_seq_midi_emul snd_emu10k1 snd_ac97_codec snd_usb_audio ac97_bus snd_seq snd_pcm snd_usb_lib snd_rawmidi snd_seq_device snd_timer firewire_ohci ppdev uvcvideo floppy firewire_core snd_page_alloc snd_util_mem snd_hwdep parport_pc pwc psmouse videodev parport v4l1_compat crc_itu_t pcspkr snd sg i2c_i801 serio_raw soundcore dcdbas ext3 jbd mbcache sr_mod cdrom sd_mo
 d pata_acpi sata_sil uhci_hcd ata_piix libata scsi_mod ehci_hcd e1000 usbcore thermal button radeon intel_agp ttm drm agpgart i2c_algo_bit cfbcopyarea cfbimgblt
 cfbfillrect [last unloaded: processor]
Pid: 32056, comm: rpm Not tainted 2.6.31.6 #1
Call Trace:
 [<c1023ba8>] ? warn_slowpath_common+0x5d/0x70
 [<c1023bc6>] ? warn_slowpath_null+0xb/0xd
 [<c11871ca>] ? inet_csk_destroy_sock+0x77/0xd3
 [<c119188f>] ? tcp_rcv_state_process+0x81f/0x9e8
 [<c11966c3>] ? tcp_v4_do_rcv+0x128/0x16d
 [<c1196b0d>] ? tcp_v4_rcv+0x405/0x640
 [<c118003e>] ? ip_local_deliver_finish+0xf3/0x1ab
 [<c117fcd9>] ? ip_rcv_finish+0x2a9/0x2cf
 [<c117fa30>] ? ip_rcv_finish+0x0/0x2cf
 [<c116b7c5>] ? netif_receive_skb+0x261/0x281
 [<f8527bfc>] ? e1000_clean_rx_irq+0x31c/0x3c3 [e1000]
 [<f852a6fa>] ? e1000_clean+0x2a7/0x3f5 [e1000]
 [<c11c783c>] ? _spin_unlock_irqrestore+0xe/0x21
 [<c10354c0>] ? hrtimer_run_pending+0xd/0xa5
 [<c11c769b>] ? _spin_lock_irq+0xe/0x24
 [<c116bce5>] ? net_rx_action+0x57/0xfd
 [<c1027ea3>] ? __do_softirq+0x7a/0xe3
 [<c1027e29>] ? __do_softirq+0x0/0xe3
 <IRQ>  [<c1027c3c>] ? irq_exit+0x29/0x63
 [<c1004320>] ? do_IRQ+0x7c/0x8d
 [<c1002f29>] ? common_interrupt+0x29/0x30
---[ end trace e643d9455a26ccf3 ]---
------------[ cut here ]------------
WARNING: at /home/chris/LINUX/linux-2.6.31/net/ipv4/af_inet.c:151 inet_sock_destruct+0xd8/0x138()
Hardware name: Precision WorkStation 650    
Modules linked in: tun snd_seq_oss snd_seq_midi snd_seq_dummy fuse nfsd lockd auth_rpcgss exportfs sunrpc autofs4 af_packet ipt_LOG nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_LOG nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 p4_clockmod speedstep_lib binfmt_misc dm_mirror dm_region_hash dm_log dm_mod uinput snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_event snd_seq_midi_emul snd_emu10k1 snd_ac97_codec snd_usb_audio ac97_bus snd_seq snd_pcm snd_usb_lib snd_rawmidi snd_seq_device snd_timer firewire_ohci ppdev uvcvideo floppy firewire_core snd_page_alloc snd_util_mem snd_hwdep parport_pc pwc psmouse videodev parport v4l1_compat crc_itu_t pcspkr snd sg i2c_i801 serio_raw soundcore dcdbas ext3 jbd mbcache sr_mod cdrom sd_mo
 d pata_acpi sata_sil uhci_hcd ata_piix libata scsi_mod ehci_hcd e1000 usbcore thermal button radeon intel_agp ttm drm agpgart i2c_algo_bit cfbcopyarea cfbimgblt
 cfbfillrect [last unloaded: processor]
Pid: 32056, comm: rpm Tainted: G        W  2.6.31.6 #1
Call Trace:
 [<c1023ba8>] ? warn_slowpath_common+0x5d/0x70
 [<c1023bc6>] ? warn_slowpath_null+0xb/0xd
 [<c11a1414>] ? inet_sock_destruct+0xd8/0x138
 [<c1163243>] ? __sk_free+0x10/0xa2
 [<c1196b4a>] ? tcp_v4_rcv+0x442/0x640
 [<c118003e>] ? ip_local_deliver_finish+0xf3/0x1ab
 [<c117fcd9>] ? ip_rcv_finish+0x2a9/0x2cf
 [<c117fa30>] ? ip_rcv_finish+0x0/0x2cf
 [<c116b7c5>] ? netif_receive_skb+0x261/0x281
 [<f8527bfc>] ? e1000_clean_rx_irq+0x31c/0x3c3 [e1000]
 [<f852a6fa>] ? e1000_clean+0x2a7/0x3f5 [e1000]
 [<c11c783c>] ? _spin_unlock_irqrestore+0xe/0x21
 [<c10354c0>] ? hrtimer_run_pending+0xd/0xa5
 [<c11c769b>] ? _spin_lock_irq+0xe/0x24
 [<c116bce5>] ? net_rx_action+0x57/0xfd
 [<c1027ea3>] ? __do_softirq+0x7a/0xe3
 [<c1027e29>] ? __do_softirq+0x0/0xe3
 <IRQ>  [<c1027c3c>] ? irq_exit+0x29/0x63
 [<c1004320>] ? do_IRQ+0x7c/0x8d
 [<c1002f29>] ? common_interrupt+0x29/0x30
---[ end trace e643d9455a26ccf4 ]---
------------[ cut here ]------------
WARNING: at /home/chris/LINUX/linux-2.6.31/net/ipv4/af_inet.c:154 inet_sock_destruct+0x11e/0x138()
Hardware name: Precision WorkStation 650    
Modules linked in: tun snd_seq_oss snd_seq_midi snd_seq_dummy fuse nfsd lockd auth_rpcgss exportfs sunrpc autofs4 af_packet ipt_LOG nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_LOG nf_conntrack_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables x_tables ipv6 p4_clockmod speedstep_lib binfmt_misc dm_mirror dm_region_hash dm_log dm_mod uinput snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_event snd_seq_midi_emul snd_emu10k1 snd_ac97_codec snd_usb_audio ac97_bus snd_seq snd_pcm snd_usb_lib snd_rawmidi snd_seq_device snd_timer firewire_ohci ppdev uvcvideo floppy firewire_core snd_page_alloc snd_util_mem snd_hwdep parport_pc pwc psmouse videodev parport v4l1_compat crc_itu_t pcspkr snd sg i2c_i801 serio_raw soundcore dcdbas ext3 jbd mbcache sr_mod cdrom sd_mo
 d pata_acpi sata_sil uhci_hcd ata_piix libata scsi_mod ehci_hcd e1000 usbcore thermal button radeon intel_agp ttm drm agpgart i2c_algo_bit cfbcopyarea cfbimgblt
 cfbfillrect [last unloaded: processor]
Pid: 32056, comm: rpm Tainted: G        W  2.6.31.6 #1
Call Trace:
 [<c1023ba8>] ? warn_slowpath_common+0x5d/0x70
 [<c1023bc6>] ? warn_slowpath_null+0xb/0xd
 [<c11a145a>] ? inet_sock_destruct+0x11e/0x138
 [<c1163243>] ? __sk_free+0x10/0xa2
 [<c1196b4a>] ? tcp_v4_rcv+0x442/0x640
 [<c118003e>] ? ip_local_deliver_finish+0xf3/0x1ab
 [<c117fcd9>] ? ip_rcv_finish+0x2a9/0x2cf
 [<c117fa30>] ? ip_rcv_finish+0x0/0x2cf
 [<c116b7c5>] ? netif_receive_skb+0x261/0x281
 [<f8527bfc>] ? e1000_clean_rx_irq+0x31c/0x3c3 [e1000]
 [<f852a6fa>] ? e1000_clean+0x2a7/0x3f5 [e1000]
 [<c11c783c>] ? _spin_unlock_irqrestore+0xe/0x21
 [<c10354c0>] ? hrtimer_run_pending+0xd/0xa5
 [<c11c769b>] ? _spin_lock_irq+0xe/0x24
 [<c116bce5>] ? net_rx_action+0x57/0xfd
 [<c1027ea3>] ? __do_softirq+0x7a/0xe3
 [<c1027e29>] ? __do_softirq+0x0/0xe3
 <IRQ>  [<c1027c3c>] ? irq_exit+0x29/0x63
 [<c1004320>] ? do_IRQ+0x7c/0x8d
 [<c1002f29>] ? common_interrupt+0x29/0x30
---[ end trace e643d9455a26ccf5 ]---



      

^ permalink raw reply

* Key change for TCP_MD5
From: Xiaochun Lu @ 2009-12-02  0:27 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

Hi, ALL

This is regarding to TCP-MD5 option [RFC2385].  In current
implementation, only one md5 password is saved in the kernel and it
brings in the problem for changing key:  Changing key in the middle of
tcp session will break the session unless new md5 password is updated
at both ends at the same time (there is no window for key change).
Does anybody know any patches currently exist to address this issue? I
know rfc4808 is targeting to solve this issue. Does there any plan to
implement rfc4808 for linux?

Best Regards!


Shawn Lu

^ permalink raw reply

* Re: Request for help with iproute2 bugs.
From: Stephen Hemminger @ 2009-12-02  0:20 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Andreas Henriksson, netdev
In-Reply-To: <4B0A6C0D.9030402@trash.net>

On Mon, 23 Nov 2009 12:03:41 +0100
Patrick McHardy <kaber@trash.net> wrote:

> Andreas Henriksson wrote:
> > http://bugs.debian.org/532727
> >   iproute: "tc filter add ... protocol ip fw" broken?
> > 
> 
> This one is caused by a regression in iproute2. The attached patch
> should fix it.

applied


-- 

^ permalink raw reply

* Re: [PATCH] iproute2: use -fPIC in lib/
From: Stephen Hemminger @ 2009-12-02  0:18 UTC (permalink / raw)
  To: Andreas Henriksson; +Cc: netdev, Dmitry Baryshev
In-Reply-To: <20091123100352.GA14356@amd64.fatal.se>

On Mon, 23 Nov 2009 11:03:52 +0100
Andreas Henriksson <andreas@fatal.se> wrote:

> The static libnetlink.a library is exposed to other users in Debian via the
> "iproute-dev" package. Apparently people are interested in using it in their
> shared libraries and would like to see the code be position independent.
> 
> Patch below makes the code under lib/ build with -fPIC.
> 
> See http://bugs.debian.org/547602
> 
> Signed-off-by: Andreas Henriksson <andreas@fatal.se>
> 
> ---
> 
> Resending patch since no comments has been received and it has not
> appeared in the iproute git repository.
> 
> 
> diff --git a/lib/Makefile b/lib/Makefile
> index bc270bf..da2f0fc 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -1,3 +1,4 @@
> +CFLAGS += -fPIC
>  
>  UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
>  

ok applied

-- 

^ permalink raw reply

* Re: [PATCH] iproute: "ip mroute show" doesn't show all output interfaces
From: Stephen Hemminger @ 2009-12-02  0:16 UTC (permalink / raw)
  To: Andreas Henriksson; +Cc: netdev, Mark Borst
In-Reply-To: <20091123095231.GA14210@amd64.fatal.se>

On Mon, 23 Nov 2009 10:52:31 +0100
Andreas Henriksson <andreas@fatal.se> wrote:

> From: Mark Borst <mark@borst.org>
> 
> The command "ip mroute show" will only show the first Oif. 
> 
> mark@flappie:~$ ip mroute show
> (192.168.1.1, 224.0.0.123)       Iif: _rename    Oifs: eth1 
> 
> mark@flappie:~$ cat /proc/net/ip_mr_cache 
> Group    Origin   Iif     Pkts    Bytes    Wrong Oifs
> 7B0000E0 0101A8C0 2          0        0        0  0:1    1:1  
> 
> This shows 2 Oifs here. However, ipmroute.c, function read_mroute_list(), uses sscanf() with a %s mask for oiflist, which stops after the first whitespace (i.e. after Oif 0:1). The patch below fixes this to read until the newline (though I'm not sure whether this is the proper way to fix it).
> 
> After this patch:
> mark@flappie:~/iproute-20090324/ip$ ./ip mroute show
> (192.168.1.1, 224.0.0.123)       Iif: _rename    Oifs: eth1 eth0 
> 
> 
> This patch originally submitted as http://bugs.debian.org/550097
> 
> Signed-off-by: Andreas Henriksson <andreas@fatal.se>

Applied with small modification, sscanf... %u%[^\n] would not
skip leading whitespace like the original %u%s but adding a blank
in the format will correct that.

-- 

^ 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