Netdev List
 help / color / mirror / Atom feed
* [PATCH] fealnx: Write outside array bounds
From: Roel Kluin @ 2009-07-24 11:49 UTC (permalink / raw)
  To: David S. Miller, netdev, Andrew Morton

phy_idx is checked to be < 4, but np->phys[] is 2 elements long

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
Or should the number of elements be increased?

diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 48385c4..100badd 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -584,7 +584,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
 	if (np->flags == HAS_MII_XCVR) {
 		int phy, phy_idx = 0;
 
-		for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
+		for (phy = 1; phy < 32 && phy_idx < 2; phy++) {
 			int mii_status = mdio_read(dev, phy, 1);
 
 			if (mii_status != 0xffff && mii_status != 0x0000) {

^ permalink raw reply related

* system hangs while executing 'rmmod ehea'
From: Pavan Naregundi @ 2009-07-24 11:43 UTC (permalink / raw)
  To: netdev; +Cc: HERING2, THEMANN, TKLEIN

Hi Everyone,

System hanged while executing "rmmod ehea" command as explained below,

This problem is seen on all the System P machines using ehea driver.

IBM eHEA ethernet device driver (Release EHEA_0101)
 
=================
mjs22lp5:~ # ifconfig 
eth2      Link encap:Ethernet  HWaddr 00:1A:64:45:89:04  
          inet addr:9.126.89.223  Bcast:9.126.89.255  Mask:255.255.255.0
          inet6 addr: fe80::21a:64ff:fe45:8904/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:430 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:51856342052 (49454.0 Mb)  TX bytes:72696983018 (69329.2 Mb)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:100 (100.0 b)  TX bytes:100 (100.0 b)

mjs22lp5:~ # ifdown eth2
    eth2      name: IBM Host Ethernet Adapter Port 0
mjs22lp5:~ # ifup eth2
    eth2      name: IBM Host Ethernet Adapter Port 0
mjs22lp5:~ # ifdown eth2
    eth2      name: IBM Host Ethernet Adapter Port 0
mjs22lp5:~ # dmesg 
ehea: eth2: Logical port down
ehea: eth2: Physical port up
ehea: External switch port is backup port
ehea: eth2: Logical port up: 1000Mbps Full Duplex
ehea: eth2: Physical port up
ehea: External switch port is backup port
irq: irq 775 on host null mapped to virtual irq 263
irq: irq 776 on host null mapped to virtual irq 264
ehea: eth2: Logical port down
ehea: eth2: Physical port up
ehea: External switch port is backup port
mjs22lp5:~ # rmmod ehea
SysRq : Entering xmon
cpu 0x0: Vector: 501 (Hardware Interrupt) at [c000000000f23b40]
    pc: c00000000000e538: .raw_local_irq_restore+0x78/0x8c
    lr: c0000000000144f8: .cpu_idle+0x118/0x1bc
    sp: c000000000f23dc0
   msr: 8000000000009032
  current = 0xc000000000e55450
  paca    = 0xc000000001002400
    pid   = 0, comm = swapper
enter ? for help
[c000000000f23dc0] c0000000000144f8 .cpu_idle+0x118/0x1bc (unreliable)
[c000000000f23e60] c000000000009eb0 .rest_init+0x94/0xc4
[c000000000f23ee0] c000000000840cd4 .start_kernel+0x444/0x468
[c000000000f23f90] c0000000000083ec .start_here_common+0x1c/0x30
0:mon> c
cpus stopped: 0-3
0:mon> c 1
1:mon> t
[c000000040457e30] c0000000000144f8 .cpu_idle+0x118/0x1bc (unreliable)
[c000000040457ed0] c0000000005d0614 .start_secondary+0x36c/0x3ac
[c000000040457f90] c0000000000082d4 .start_secondary_prolog+0x10/0x14
1:mon> c 3
3:mon> t
[c00000004045fe30] c0000000000144f8 .cpu_idle+0x118/0x1bc (unreliable)
[c00000004045fed0] c0000000005d0614 .start_secondary+0x36c/0x3ac
[c00000004045ff90] c0000000000082d4 .start_secondary_prolog+0x10/0x14
3:mon> c 2
2:mon> t
[c00000003c4f75e0] c0000000005191b8 .netif_napi_del+0x54/0xb0 (unreliable)
[c00000003c4f7680] c0000000005192cc .free_netdev+0xb8/0x14c
[c00000003c4f7720] d0000000010b0af4 .ehea_shutdown_single_port+0x74/0xa4 [ehea]
[c00000003c4f77b0] d0000000010ba870 .ehea_remove+0x60/0x130 [ehea]
[c00000003c4f7860] c0000000004fef98 .of_platform_device_remove+0x58/0x78
[c00000003c4f78f0] c00000000043c1b4 .__device_release_driver+0xc8/0x138
[c00000003c4f7990] c00000000043c310 .driver_detach+0xec/0x154
[c00000003c4f7a40] c00000000043ac90 .bus_remove_driver+0xd4/0x130
[c00000003c4f7ae0] c00000000043cc20 .driver_unregister+0xa0/0xc8
[c00000003c4f7b80] c0000000004ff160 .of_unregister_driver+0x2c/0x48
[c00000003c4f7c10] c00000000002b380 .ibmebus_unregister_driver+0x2c/0x48
[c00000003c4f7ca0] d0000000010ba790 .ehea_module_exit+0x4c/0xcc [ehea]
[c00000003c4f7d30] c0000000000dd0f8 .SyS_delete_module+0x21c/0x2c0
[c00000003c4f7e30] c000000000008534 syscall_exit+0x0/0x40
--- Exception: c01 (System Call) at 00000fff9fb6b3d0
SP (fffeccb0710) is in userspace
2:mon> e
cpu 0x2: Vector: 501 (Hardware Interrupt) at [c00000003c4f7360]
    pc: c00000000050e1f4: .kfree_skb+0xe4/0xf4
    lr: c0000000005191b8: .netif_napi_del+0x54/0xb0
    sp: c00000003c4f75e0
   msr: 8000000000009032
  current = 0xc00000003c303ac0
  paca    = 0xc000000001002800
    pid   = 3138, comm = rmmod
2:mon> r
R00 = c0000000005191b8   R07 = c000000040371fe0
R01 = c00000003c4f75e0   R08 = 0000000000000005
R02 = c000000000f161d0   R09 = c000000040568708
R03 = 0000000000000000   R10 = c000000040568228
R04 = c000000001493468   R11 = c000000040568708
R05 = c000000000e5e780   R12 = d0000000010bb6a8
R06 = c0000000404f3e00   R13 = c000000001002800
pc  = c00000000050e1f4 .kfree_skb+0xe4/0xf4
lr  = c0000000005191b8 .netif_napi_del+0x54/0xb0
msr = 8000000000009032   cr  = 44000822
ctr = c000000000519214   xer = 0000000020000020   trap =  501
2:mon> di %pc 20
c00000000050e1f4  eba1ffe8      ld      r29,-24(r1)
c00000000050e1f8  ebc1fff0      ld      r30,-16(r1)
c00000000050e1fc  ebe1fff8      ld      r31,-8(r1)
c00000000050e200  4e800020      blr
c00000000050e204  7c0802a6      mflr    r0
c00000000050e208  f8010010      std     r0,16(r1)
c00000000050e20c  fb41ffd0      std     r26,-48(r1)
c00000000050e210  fb61ffd8      std     r27,-40(r1)
c00000000050e214  fb81ffe0      std     r28,-32(r1)
c00000000050e218  fba1ffe8      std     r29,-24(r1)
c00000000050e21c  fbc1fff0      std     r30,-16(r1)
c00000000050e220  fbe1fff8      std     r31,-8(r1)
c00000000050e224  f821ff51      stdu    r1,-176(r1)
c00000000050e228  7c3f0b78      mr      r31,r1
c00000000050e22c  ebc2ca50      ld      r30,-13744(r2)
c00000000050e230  7c7d1b78      mr      r29,r3
c00000000050e234  7c9a2378      mr      r26,r4
c00000000050e238  60000000      nop
 ...
c00000000050e240  eb7d0010      ld      r27,16(r29)
c00000000050e244  2fbb0000      cmpdi   cr7,r27,0
c00000000050e248  419e0154      beq     cr7,c00000000050e39c    #
.skb_tstamp_tx+0x198/0x1c0
c00000000050e24c  7fa3eb78      mr      r3,r29
c00000000050e250  38800020      li      r4,32
c00000000050e254  4bfffc61      bl      c00000000050deb4        #
.skb_clone+0x0/0xdc
c00000000050e258  7c7c1b79      mr.     r28,r3
c00000000050e25c  41820140      beq     c00000000050e39c        #
.skb_tstamp_tx+0x198/0x1c0
c00000000050e260  2fba0000      cmpdi   cr7,r26,0
c00000000050e264  419e0024      beq     cr7,c00000000050e288    #
.skb_tstamp_tx+0x84/0x1c0
c00000000050e268  801c00d4      lwz     r0,212(r28)
c00000000050e26c  e97c00d8      ld      r11,216(r28)
c00000000050e270  e93a0000      ld      r9,0(r26)
2:mon> 
====================

# uname -a
Linux mjs22lp5 2.6.31-rc4-next-20090723 #1 SMP Thu Jul 23 14:37:21 IST 2009
ppc64 ppc64 ppc64 GNU/Linux



Steps to reproduce:
1. Say, eth0 which is using ehea 
2. ifdown eth0
3. ifup eth0
4. ifdown eth0
5. rmmod ehea        // This command should hang the system


^ permalink raw reply

* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Krishna Kumar2 @ 2009-07-24 10:31 UTC (permalink / raw)
  To: Herbert Xu; +Cc: davem, Jarek Poplawski, netdev
In-Reply-To: <20090724083749.GA23521@gondor.apana.org.au>

> Herbert Xu <herbert@gondor.apana.org.au> wrote on 07/24/2009 02:07:49 PM:
> On Fri, Jul 24, 2009 at 08:30:06AM +0000, Jarek Poplawski wrote:
> > On 20-07-2009 09:46, Krishna Kumar wrote:
> > > From: Krishna Kumar <krkumar2@in.ibm.com>
> > >
> > > This patch avoids calling __qdisc_run if the queue is stopped.
> > > This also lets us remove the queue_stopped check in dequeue_skb
> > > and in qdisc_restart.
> >
> > It was designed wrt. multiqueue handling mainly, were such a check
> > isn't enough at this place.
>
> Well multiqueue TX was designed so that each CPU could have its
> own queue.  While this isn't always the case due to resource
> constraints and legacy applications, we should optimise for the
> case where each CPU is using its own TX queue.
>
> Of course we should still maintain correctness should the unexpected
> occur.
>
> So while I agree with Krishna's patch in principle, someone needs to
> make sure that it still does the right thing (i.e., it doesn't
> introduce potential starvation) if one CPU transmits to someone
> else's queue.

Hi Herbert,

Assuming many CPU's share a queue, only one can xmit due to the
RUNNING bit. And after RUNNING bit is taken, no other cpu can
stop the queue. So the only change in the behavior with this
patch is that the xmit is terminated a little earlier compared
to the current code. In case of a stopped queue, the patch helps
a little bit more by removing one stopped check for each queue'd
skb, including those skbs that are added later while the current
xmit session (qdisc_run) is ongoing.

I hope I have addressed your concern?

Thanks,

- KK


^ permalink raw reply

* [PATCH] Add some function overview comments in tcp_input.c
From: Andi Kleen @ 2009-07-24  9:47 UTC (permalink / raw)
  To: davem, netdev

Add some function overview comments in tcp_input.c

Only partial so far. I didn't attempt to accurately comment
the SACK machinery and the congestion state machine. 

I also fixed the grammar in one or two other comments
(but still trying to keep the authentic "ANK language" @)

No code changes.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 net/ipv4/tcp_input.c |   47 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 6 deletions(-)

Index: linux-2.6.31-rc3-ak/net/ipv4/tcp_input.c
===================================================================
--- linux-2.6.31-rc3-ak.orig/net/ipv4/tcp_input.c
+++ linux-2.6.31-rc3-ak/net/ipv4/tcp_input.c
@@ -4,6 +4,7 @@
  *		interface as the means of communication with the user level.
  *
  *		Implementation of the Transmission Control Protocol(TCP).
+ *             This file handles packets coming in from the network.
  *
  * Authors:	Ross Biro
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -194,6 +195,8 @@ static inline int tcp_in_quickack_mode(c
 	return icsk->icsk_ack.quick && !icsk->icsk_ack.pingpong;
 }
 
+/* Explicit Congestion Notification handling. */
+
 static inline void TCP_ECN_queue_cwr(struct tcp_sock *tp)
 {
 	if (tp->ecn_flags & TCP_ECN_OK)
@@ -799,7 +802,9 @@ void tcp_update_metrics(struct sock *sk)
 	}
 }
 
-/* Numbers are taken from RFC3390.
+/* Set up initial congestion window for a socket.
+ *
+ * Numbers are taken from RFC3390.
  *
  * John Heffner states:
  *
@@ -992,6 +997,7 @@ static void tcp_skb_mark_lost(struct tcp
 	}
 }
 
+/* Update lost estimate. */
 static void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp,
 					    struct sk_buff *skb)
 {
@@ -2818,6 +2824,7 @@ static void tcp_try_to_open(struct sock
 	}
 }
 
+/* MTU probe failed. */
 static void tcp_mtup_probe_failed(struct sock *sk)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2826,6 +2833,7 @@ static void tcp_mtup_probe_failed(struct
 	icsk->icsk_mtup.probe_size = 0;
 }
 
+/* MTU probe succeeded: update the MSS. */
 static void tcp_mtup_probe_success(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -3115,6 +3123,7 @@ static void tcp_ack_no_tstamp(struct soc
 	tcp_valid_rtt_meas(sk, seq_rtt);
 }
 
+/* Update RTT estimate based on incoming ACKs. */
 static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
 				      const s32 seq_rtt)
 {
@@ -3126,6 +3135,7 @@ static inline void tcp_ack_update_rtt(st
 		tcp_ack_no_tstamp(sk, seq_rtt, flag);
 }
 
+/* Call the pluggable congestion avoidance algorithm */
 static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -3340,18 +3350,19 @@ static int tcp_clean_rtx_queue(struct so
 	return flag;
 }
 
+/* Reinitialize window probe timer after incoming ACKs. */
 static void tcp_ack_probe(struct sock *sk)
 {
 	const struct tcp_sock *tp = tcp_sk(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
 
-	/* Was it a usable window open? */
+	/* Was an usable window open? */
 
 	if (!after(TCP_SKB_CB(tcp_send_head(sk))->end_seq, tcp_wnd_end(tp))) {
 		icsk->icsk_backoff = 0;
 		inet_csk_clear_xmit_timer(sk, ICSK_TIME_PROBE0);
 		/* Socket must be waked up by subsequent tcp_data_snd_check().
-		 * This function is not for random using!
+		 * This function is not for casual usage!
 		 */
 	} else {
 		inet_csk_reset_xmit_timer(sk, ICSK_TIME_PROBE0,
@@ -3694,7 +3705,8 @@ old_ack:
 	return 0;
 }
 
-/* Look for tcp options. Normally only called on SYN and SYNACK packets.
+/* Slow path TCP options parser.
+ * Look for tcp options. Normally only called on SYN and SYNACK packets.
  * But, this can also be called on packets in the established flow when
  * the fast version below fails.
  */
@@ -3791,6 +3803,7 @@ void tcp_parse_options(struct sk_buff *s
 	}
 }
 
+/* Fast path time stamp parsing. */
 static int tcp_parse_aligned_timestamp(struct tcp_sock *tp, struct tcphdr *th)
 {
 	__be32 *ptr = (__be32 *)(th + 1);
@@ -4152,6 +4165,7 @@ static void tcp_sack_maybe_coalesce(stru
 	}
 }
 
+/* New out of order packet received. Process the SACKs. */
 static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -4195,7 +4209,6 @@ new_sack:
 }
 
 /* RCV.NXT advances, some SACKs should be eaten. */
-
 static void tcp_sack_remove(struct tcp_sock *tp)
 {
 	struct tcp_sack_block *sp = &tp->selective_acks[0];
@@ -4269,6 +4282,7 @@ static void tcp_ofo_queue(struct sock *s
 static int tcp_prune_ofo_queue(struct sock *sk);
 static int tcp_prune_queue(struct sock *sk);
 
+/* When the socket buffer is over limit try to free some memory. */
 static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size)
 {
 	if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
@@ -4288,6 +4302,10 @@ static inline int tcp_try_rmem_schedule(
 	return 0;
 }
 
+/* Queue incoming data on the socket and also do state changes.
+ * This also handles the fast path of directly pushing data to a
+ * receive process that is currently blocked in recvmsg.
+ */
 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcphdr *th = tcp_hdr(skb);
@@ -4503,6 +4521,7 @@ add_sack:
 	}
 }
 
+/* Collapse one SKB with the next to save memory in the OOO queue. */
 static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
 					struct sk_buff_head *list)
 {
@@ -4676,7 +4695,10 @@ static void tcp_collapse_ofo_queue(struc
 }
 
 /*
- * Purge the out-of-order queue.
+ * Purge the out-of-order queue. This is done under socket buffer memory pressure,
+ * and throws out-of-order data already received (but not queued to the
+ * process because it was out of order) away.
+ *
  * Return true if queue was pruned.
  */
 static int tcp_prune_ofo_queue(struct sock *sk)
@@ -4773,6 +4795,7 @@ void tcp_cwnd_application_limited(struct
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
+/* Should we increase the send buffer? */
 static int tcp_should_expand_sndbuf(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -4822,6 +4845,7 @@ static void tcp_new_space(struct sock *s
 	sk->sk_write_space(sk);
 }
 
+/* Check if we can signal users to queue more data */
 static void tcp_check_space(struct sock *sk)
 {
 	if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) {
@@ -4832,6 +4856,7 @@ static void tcp_check_space(struct sock
 	}
 }
 
+/* Check if sending data is needed, e.g. because the window opened up */
 static inline void tcp_data_snd_check(struct sock *sk)
 {
 	tcp_push_pending_frames(sk);
@@ -4973,6 +4998,9 @@ static void tcp_urg(struct sock *sk, str
 	}
 }
 
+/* Fast path copy to user space code. When the receiving process is currently
+ * blocked in a recvmsg call directly copy to user space.
+ */
 static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -5019,6 +5047,10 @@ static inline int tcp_checksum_complete_
 }
 
 #ifdef CONFIG_NET_DMA
+
+/* Attempt to copy data to user space using hardware accelerated
+ * copy engines.
+ */
 static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb,
 				  int hlen)
 {
@@ -5359,6 +5391,9 @@ discard:
 	return 0;
 }
 
+/* RFC793 receive state procedure for SYN-SENT sockets. This normally processes
+ * the SYN-ACK, but also handles a few odd cases.
+ */
 static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
 					 struct tcphdr *th, unsigned len)
 {

^ permalink raw reply

* [PATCH] net/bridge: use kobject_put to release kobject in br_add_if error path
From: Xiaotian Feng @ 2009-07-24  9:06 UTC (permalink / raw)
  To: davem, shemminger; +Cc: bridge, netdev, linux-kernel, Xiaotian Feng

kobject_init_and_add will alloc memory for kobj->name, so in br_add_if
error path, simply use kobject_del will not free memory for kobj->name.
Fix by using kobject_put instead, kobject_put will internally calls
kobject_del and frees memory for kobj->name.

Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
---
 net/bridge/br_if.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 8a96672..eb404dc 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -424,7 +424,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
 err2:
 	br_fdb_delete_by_port(br, p, 1);
 err1:
-	kobject_del(&p->kobj);
+	kobject_put(&p->kobj);
 err0:
 	dev_set_promiscuity(dev, -1);
 put_back:
-- 
1.6.2.5

^ permalink raw reply related

* Re: [net-next-2.6 PATCH 06/13] igb: move all multicast addresses into multicast table array
From: Jesper Dangaard Brouer @ 2009-07-24  8:57 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: David S. Miller, netdev, Jeff Kirsher, gospo
In-Reply-To: <20090724040853.30709.97954.stgit@localhost.localdomain>


On Thu, 23 Jul 2009, Jeff Kirsher wrote:

> From: Alexander Duyck <alexander.h.duyck@intel.com>
>
> This patch moves all of the multicast addresses out of the free Receive
> address registers and instead programs them all into the multicast table
> array.  As a result the multicast filtering may not be as precise, but it
> also greatly reduces the overhead for multicast addresses.

What do you mean by "the multicast filtering may not be as precise" ?

I'm planning to use these NICs for multicast traffic (both routing and 
monitoring).  Is there any precausing I need to be aware of?

Hilsen
   Jesper Brouer

--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------

^ permalink raw reply

* Re: ixgbe: panic in ixgbe_clean_rx_irq()
From: Jesper Dangaard Brouer @ 2009-07-24  8:41 UTC (permalink / raw)
  To: Waskiewicz Jr, Peter P; +Cc: netdev@vger.kernel.org
In-Reply-To: <1248362493.17215.45.camel@localhost.localdomain>

On Thu, 2009-07-23 at 17:21 +0200, Jesper Dangaard Brouer wrote:
> I'm going to run a test with a no-preempt kernel over night...

The no-preempt kernel has been stable for 17 hours, while running a four
times 10GbE pktgen load test (using 1024 bytes packets).

Kernel git version (git describe):
 v2.6.31-rc1-932-g8e321c4

Git ("git log e594e96..8e321c4 drivers/net/ixgbe") reports not changes
to the ixgbe driver between these two kernel versions.

-- 
Med venlig hilsen / Best regards
  Jesper Brouer
  ComX Networks A/S
  Linux Network developer
  Cand. Scient Datalog / MSc.
  Author of http://adsl-optimizer.dk
  LinkedIn: http://www.linkedin.com/in/brouer


^ permalink raw reply

* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Herbert Xu @ 2009-07-24  8:37 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: Krishna Kumar, davem, netdev
In-Reply-To: <20090724083006.GA5698@ff.dom.local>

On Fri, Jul 24, 2009 at 08:30:06AM +0000, Jarek Poplawski wrote:
> On 20-07-2009 09:46, Krishna Kumar wrote:
> > From: Krishna Kumar <krkumar2@in.ibm.com>
> > 
> > Driver sends an skb and stops the queue if no more space is
> > available on the device, and returns OK. When dev_queue_xmit
> > runs for the next skb, it enqueue's the skb & calls qdisc_run.
> > qdisc_run dequeue's the skb and finds the queue is stopped
> > after getting the HARD_LOCK_TX, and puts the skb back on
> > gso_skb (the next iteration fails faster at dequeue_skb).
> > 
> > This patch avoids calling __qdisc_run if the queue is stopped.
> > This also lets us remove the queue_stopped check in dequeue_skb
> > and in qdisc_restart.
> 
> It was designed wrt. multiqueue handling mainly, were such a check
> isn't enough at this place.

Well multiqueue TX was designed so that each CPU could have its
own queue.  While this isn't always the case due to resource
constraints and legacy applications, we should optimise for the
case where each CPU is using its own TX queue.

Of course we should still maintain correctness should the unexpected
occur.

So while I agree with Krishna's patch in principle, someone needs to
make sure that it still does the right thing (i.e., it doesn't
introduce potential starvation) if one CPU transmits to someone
else's queue.

Cheers,
-- 
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

* Re: [PATCH 1/1] IEEE80154: Add documentation to the IEEE80154 netlink and fakehard driver
From: Dmitry Eremin-Solenikov @ 2009-07-24  8:31 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1248281484-3064-1-git-send-email-dsilvers@digital-scurf.org>

Daniel Silverstone wrote:

> This adds some perfunctory documentation comments to the IEEE 802.15.4
> fakehard.c driver (Fake hard MAC) and the nl802154.h (outgoing netlink
> messages) header.
> 
> These comments are not necessarily complete, but they do reference the
> IEEE 802.15.4-2006 document where possible.
> 

Thank you, pulled in. Will push to davem soon.
In future please Cc either one of stack maintainers or linux-zigbee-devel
list.

Thank you!

-- 
With best wishes
Dmitry



^ permalink raw reply

* Re: [RFC] [PATCH] Don't run __qdisc_run() on a stopped TX queue
From: Jarek Poplawski @ 2009-07-24  8:30 UTC (permalink / raw)
  To: Krishna Kumar; +Cc: davem, herbert, netdev
In-Reply-To: <20090720074607.32463.23013.sendpatchset@localhost.localdomain>

On 20-07-2009 09:46, Krishna Kumar wrote:
> From: Krishna Kumar <krkumar2@in.ibm.com>
> 
> Driver sends an skb and stops the queue if no more space is
> available on the device, and returns OK. When dev_queue_xmit
> runs for the next skb, it enqueue's the skb & calls qdisc_run.
> qdisc_run dequeue's the skb and finds the queue is stopped
> after getting the HARD_LOCK_TX, and puts the skb back on
> gso_skb (the next iteration fails faster at dequeue_skb).
> 
> This patch avoids calling __qdisc_run if the queue is stopped.
> This also lets us remove the queue_stopped check in dequeue_skb
> and in qdisc_restart.

It was designed wrt. multiqueue handling mainly, were such a check
isn't enough at this place.

Jarek P.

> When the queue is re-enabled, it runs with
> one less queue_stopped() check for every skb on the queue (we
> still need to own the __QDISC_STATE_RUNNING bit to catch the
> stopped condition correctly since stopped cannot be set without
> holding this bit).
> 
> Results for 3 iteration testing for 1, 4, 8, 12 netperf sessions
> running for 1 minute each:
> 
> -----------------------------------------------------------------
> 	       System-X			         P6
> -----------------------------------------------------------------
> Size	ORG BW		NEW BW		ORG BW		NEW BW
> -----------------------------------------------------------------
> 16K	72183.05	74417.79	60775.76	63413.17
> 128K	69097.87	72447.12	61692.16	62251.07
> 256K	60456.21	61415.81	59694.03	61641.81
> -----------------------------------------------------------------
> 
> Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> ---
> 
>  include/net/pkt_sched.h |    9 +++++++--
>  net/sched/sch_generic.c |    9 ++-------
>  2 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff -ruNp org/include/net/pkt_sched.h new/include/net/pkt_sched.h
> --- org/include/net/pkt_sched.h	2009-06-22 11:40:31.000000000 +0530
> +++ new/include/net/pkt_sched.h	2009-07-20 13:09:18.000000000 +0530
> @@ -92,8 +92,13 @@ extern void __qdisc_run(struct Qdisc *q)
>  
>  static inline void qdisc_run(struct Qdisc *q)
>  {
> -	if (!test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
> -		__qdisc_run(q);
> +	if (!test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) {
> +		if (!netif_tx_queue_stopped(q->dev_queue))
> +			__qdisc_run(q);
> +		else
> +			/* driver will wake us up anyway, just clear */
> +			clear_bit(__QDISC_STATE_RUNNING, &q->state);
> +	}
>  }
>  
>  extern int tc_classify_compat(struct sk_buff *skb, struct tcf_proto *tp,
> diff -ruNp org/net/sched/sch_generic.c new/net/sched/sch_generic.c
> --- org/net/sched/sch_generic.c	2009-05-25 07:48:07.000000000 +0530
> +++ new/net/sched/sch_generic.c	2009-07-20 13:09:18.000000000 +0530
> @@ -56,12 +56,8 @@ static inline struct sk_buff *dequeue_sk
>  	struct sk_buff *skb = q->gso_skb;
>  
>  	if (unlikely(skb)) {
> -		struct net_device *dev = qdisc_dev(q);
> -		struct netdev_queue *txq;
> -
>  		/* check the reason of requeuing without tx lock first */
> -		txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
> -		if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))
> +		if (!netif_tx_queue_frozen(q->dev_queue))
>  			q->gso_skb = NULL;
>  		else
>  			skb = NULL;
> @@ -142,8 +138,7 @@ static inline int qdisc_restart(struct Q
>  	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
>  
>  	HARD_TX_LOCK(dev, txq, smp_processor_id());
> -	if (!netif_tx_queue_stopped(txq) &&
> -	    !netif_tx_queue_frozen(txq))
> +	if (!netif_tx_queue_frozen(txq))
>  		ret = dev_hard_start_xmit(skb, dev, txq);
>  	HARD_TX_UNLOCK(dev, txq);
>  
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* [PATCH net-next-2.6] bnx2x: Dont update vlan_features in bnx2x_set_tso()
From: Eric Dumazet @ 2009-07-24  7:21 UTC (permalink / raw)
  To: Michael Chan
  Cc: David Miller, ogerlitz@voltaire.com, kaber@trash.net,
	fubar@us.ibm.com, netdev@vger.kernel.org, Eilon Greenstein
In-Reply-To: <1248394379.13301.2.camel@HP1>

Michael Chan a écrit :
> On Thu, 2009-07-23 at 10:59 -0700, David Miller wrote:
>> From: Eric Dumazet <eric.dumazet@gmail.com>
>> Date: Thu, 23 Jul 2009 14:01:38 +0200
>>
>>> [PATCH net-next-2.6] bnx2: Update vlan_features
>>>
>>> In order to get full use of some advanced features of BNX2, we now need to
>>> fill dev->vlan_features.
>>>
>>> Patch successfully tested with vlan devices built on top of bonding.
>>> (bond0 : one bnx2 slave, one tg3 slave (not yet vlan_features enabled)
>>>
>>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>> Can I get some Broadcom ACKs for this?
>>
> I've reviewed and tested Eric's 2nd patch.  Thanks.
> 
> Acked-by: Michael Chan <mchan@broadcom.com>

Thanks

Based on Patrick feedback, I believe we can add this followup too

[PATCH net-next-2.6] bnx2x: Dont update vlan_features in bnx2x_set_tso()

Patrick said : "vlan_features doesn't need to be updated, the resulting
dev->features of the VLAN device is computed as the intersection of
dev->features and dev->vlan_features."

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---

diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index c4c42b3..a2de0cd 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -9349,17 +9349,9 @@ static int bnx2x_set_tso(struct net_device *dev, u32 data)
 	if (data) {
 		dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
 		dev->features |= NETIF_F_TSO6;
-#ifdef BCM_VLAN
-		dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
-		dev->vlan_features |= NETIF_F_TSO6;
-#endif
 	} else {
 		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
 		dev->features &= ~NETIF_F_TSO6;
-#ifdef BCM_VLAN
-		dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
-		dev->vlan_features &= ~NETIF_F_TSO6;
-#endif
 	}
 
 	return 0;

^ permalink raw reply related

* Re: [PATCH] IPVS: Add handling of incoming ICMPV6_PKT_TOOBIG messages
From: Eric Dumazet @ 2009-07-24  4:25 UTC (permalink / raw)
  To: Simon Horman; +Cc: lvs-devel, netdev, David Miller, Julius Volz, Rob Gallagher
In-Reply-To: <20090724024711.GA13280@verge.net.au>

Simon Horman a écrit :
> From: Julius Volz <julius.volz@gmail.com>
> 
> IPVS: Add handling of incoming ICMPV6_PKT_TOOBIG messages
> 
> Add handling of incoming ICMPv6 Packet Too Big messages. This message
> is received when a realserver sends a packet >PMTU to the client. The
> hop on this path with insufficient MTU will generate an ICMPv6 Packet
> Too Big message back to the VIP. The LVS server receives this message,
> but the call to the function handling this has been missing. Thus, IPVS
> fails to forward the message to the real server, which then does not
> adjust the path MTU. This patch adds the missing call to
> ip_vs_in_icmp_v6() in ip_vs_in() to handle this situation.
> 
> Thanks to Rob Gallagher from HEAnet for reporting this issue and for
> testing this patch in production (with direct routing mode).
> 
> Signed-off-by: Julius Volz <julius.volz@gmail.com>
> Tested-by: Rob Gallagher <robert.gallagher@heanet.ie>
> Signed-off-by: Simon Horman <horms@verge.net.au>
> 
> ---
>  net/netfilter/ipvs/ip_vs_core.c |   23 +++++++++++++++++------
>  1 files changed, 17 insertions(+), 6 deletions(-)
> 
> Dave, please consider applying this change.
> 
> I'm ok with it not going into 2.6.31 as I don't think that
> many people are affected by this problem.
> 
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index 8dddb17..5750800 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -1274,13 +1274,24 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
>  		return NF_ACCEPT;
>  	}
>  
> -	if (unlikely(iph.protocol == IPPROTO_ICMP)) {
> -		int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
> +#ifdef CONFIG_IP_VS_IPV6
> +	if (af == AF_INET6) {
> +		if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
> +			int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
>  
> -		if (related)
> -			return verdict;
> -		ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
> -	}
> +			if (related)
> +				return verdict;
> +			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
> +		}
> +	} else
> +#endif
> +		if (unlikely(iph.protocol == IPPROTO_ICMP)) {
> +			int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
> +
> +			if (related)
> +				return verdict;
> +			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
> +		}
>  
>  	/* Protocol supported? */
>  	pp = ip_vs_proto_get(iph.protocol);

I see no reference to ICMPV6_PKT_TOOBIG in this patch, so ChangeLog might be
misleading or uncomplete, since other ICMPV6 message types 
(ICMPV6_DEST_UNREACH/ICMPV6_TIME_EXCEED) will also be forwarded/handled ?



^ permalink raw reply

* [net-next-2.6 PATCH 13/13] igbvf: resolve "frees DMA memory with different size" warnings
From: Jeff Kirsher @ 2009-07-24  4:11 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This change resolves some warnings seen with DMA debugging enabled in which
we were mapping skb->data with size + NET_IP_ALIGN and unmapping it with
just size.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igbvf/netdev.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 2bc9d63..926c31b 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -149,7 +149,6 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
 		bufsz = adapter->rx_ps_hdr_size;
 	else
 		bufsz = adapter->rx_buffer_len;
-	bufsz += NET_IP_ALIGN;
 
 	while (cleaned_count--) {
 		rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
@@ -173,7 +172,7 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
 		}
 
 		if (!buffer_info->skb) {
-			skb = netdev_alloc_skb(netdev, bufsz);
+			skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN);
 			if (!skb) {
 				adapter->alloc_rx_buff_failed++;
 				goto no_buffers;
@@ -286,7 +285,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
 
 		if (!skb_shinfo(skb)->nr_frags) {
 			pci_unmap_single(pdev, buffer_info->dma,
-			                 adapter->rx_ps_hdr_size + NET_IP_ALIGN,
+			                 adapter->rx_ps_hdr_size,
 			                 PCI_DMA_FROMDEVICE);
 			skb_put(skb, hlen);
 		}


^ permalink raw reply related

* [net-next-2.6 PATCH 12/13] igb: initialize mailbox function pointers prior to phy init
From: Jeff Kirsher @ 2009-07-24  4:10 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

The igb driver is currently initializing the mailbox function pointers
after the phy.  This causes issues as the phy init will return from the
function early if there is no phy present.

To resolve this I have moved the function pointer init to a location prior
to the phy initialization so that serdes based adapters can also make use
of SR-IOV.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index dbbd72f..6158c0f 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -172,6 +172,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 		size = 14;
 	nvm->word_size = 1 << size;
 
+	/* if 82576 then initialize mailbox parameters */
+	if (mac->type == e1000_82576)
+		igb_init_mbx_params_pf(hw);
+
 	/* setup PHY parameters */
 	if (phy->media_type != e1000_media_type_copper) {
 		phy->type = e1000_phy_none;
@@ -221,10 +225,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 		return -E1000_ERR_PHY;
 	}
 
-	/* if 82576 then initialize mailbox parameters */
-	if (mac->type == e1000_82576)
-		igb_init_mbx_params_pf(hw);
-
 	return 0;
 }
 


^ permalink raw reply related

* [net-next-2.6 PATCH 11/13] igb: cleanup flow control configuration to make requested/current more clear
From: Jeff Kirsher @ 2009-07-24  4:10 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This patch cleans up the flow control configuration for igb to make it a
bit more readable in regards to what the requested and current modes are.
This should help with the maintainability of the current igb driver in
regards to flow control.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_hw.h    |    6 ++---
 drivers/net/igb/e1000_mac.c   |   50 +++++++++++++++++++++++------------------
 drivers/net/igb/e1000_phy.c   |    4 ++-
 drivers/net/igb/igb_ethtool.c |   34 ++++++++++++++++------------
 drivers/net/igb/igb_main.c    |    6 ++---
 5 files changed, 55 insertions(+), 45 deletions(-)

diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 0469e2e..119869b 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -137,7 +137,7 @@ enum e1000_rev_polarity {
 	e1000_rev_polarity_undefined = 0xFF
 };
 
-enum e1000_fc_type {
+enum e1000_fc_mode {
 	e1000_fc_none = 0,
 	e1000_fc_rx_pause,
 	e1000_fc_tx_pause,
@@ -429,8 +429,8 @@ struct e1000_fc_info {
 	u16 pause_time;     /* Flow control pause timer */
 	bool send_xon;      /* Flow control send XON */
 	bool strict_ieee;   /* Strict IEEE mode */
-	enum e1000_fc_type type; /* Type of flow control */
-	enum e1000_fc_type original_type;
+	enum e1000_fc_mode current_mode; /* Type of flow control */
+	enum e1000_fc_mode requested_mode;
 };
 
 struct e1000_mbx_operations {
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index a1e3da7..a0231cd 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -536,18 +536,24 @@ s32 igb_setup_link(struct e1000_hw *hw)
 	if (igb_check_reset_block(hw))
 		goto out;
 
-	ret_val = igb_set_default_fc(hw);
-	if (ret_val)
-		goto out;
+	/*
+	 * If requested flow control is set to default, set flow control
+	 * based on the EEPROM flow control settings.
+	 */
+	if (hw->fc.requested_mode == e1000_fc_default) {
+		ret_val = igb_set_default_fc(hw);
+		if (ret_val)
+			goto out;
+	}
 
 	/*
 	 * We want to save off the original Flow Control configuration just
 	 * in case we get disconnected and then reconnected into a different
 	 * hub or switch with different Flow Control capabilities.
 	 */
-	hw->fc.original_type = hw->fc.type;
+	hw->fc.current_mode = hw->fc.requested_mode;
 
-	hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.type);
+	hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
 
 	/* Call the necessary media_type subroutine to configure the link. */
 	ret_val = hw->mac.ops.setup_physical_interface(hw);
@@ -614,7 +620,7 @@ static s32 igb_set_fc_watermarks(struct e1000_hw *hw)
 	 * ability to transmit pause frames is not enabled, then these
 	 * registers will be set to 0.
 	 */
-	if (hw->fc.type & e1000_fc_tx_pause) {
+	if (hw->fc.current_mode & e1000_fc_tx_pause) {
 		/*
 		 * We need to set up the Receive Threshold high and low water
 		 * marks as well as (optionally) enabling the transmission of
@@ -661,12 +667,12 @@ static s32 igb_set_default_fc(struct e1000_hw *hw)
 	}
 
 	if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
-		hw->fc.type = e1000_fc_none;
+		hw->fc.requested_mode = e1000_fc_none;
 	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
 		 NVM_WORD0F_ASM_DIR)
-		hw->fc.type = e1000_fc_tx_pause;
+		hw->fc.requested_mode = e1000_fc_tx_pause;
 	else
-		hw->fc.type = e1000_fc_full;
+		hw->fc.requested_mode = e1000_fc_full;
 
 out:
 	return ret_val;
@@ -696,7 +702,7 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
 	 * receive flow control.
 	 *
 	 * The "Case" statement below enables/disable flow control
-	 * according to the "hw->fc.type" parameter.
+	 * according to the "hw->fc.current_mode" parameter.
 	 *
 	 * The possible values of the "fc" parameter are:
 	 *      0:  Flow control is completely disabled
@@ -707,9 +713,9 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
 	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
 	 *  other:  No other values should be possible at this point.
 	 */
-	hw_dbg("hw->fc.type = %u\n", hw->fc.type);
+	hw_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
 
-	switch (hw->fc.type) {
+	switch (hw->fc.current_mode) {
 	case e1000_fc_none:
 		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
 		break;
@@ -857,11 +863,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 			 * ONLY. Hence, we must now check to see if we need to
 			 * turn OFF  the TRANSMISSION of PAUSE frames.
 			 */
-			if (hw->fc.original_type == e1000_fc_full) {
-				hw->fc.type = e1000_fc_full;
+			if (hw->fc.requested_mode == e1000_fc_full) {
+				hw->fc.current_mode = e1000_fc_full;
 				hw_dbg("Flow Control = FULL.\r\n");
 			} else {
-				hw->fc.type = e1000_fc_rx_pause;
+				hw->fc.current_mode = e1000_fc_rx_pause;
 				hw_dbg("Flow Control = "
 				       "RX PAUSE frames only.\r\n");
 			}
@@ -878,7 +884,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			hw->fc.type = e1000_fc_tx_pause;
+			hw->fc.current_mode = e1000_fc_tx_pause;
 			hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
 		}
 		/*
@@ -893,7 +899,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			hw->fc.type = e1000_fc_rx_pause;
+			hw->fc.current_mode = e1000_fc_rx_pause;
 			hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
 		}
 		/*
@@ -917,13 +923,13 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 		 * be asked to delay transmission of packets than asking
 		 * our link partner to pause transmission of frames.
 		 */
-		else if ((hw->fc.original_type == e1000_fc_none ||
-			  hw->fc.original_type == e1000_fc_tx_pause) ||
+		else if ((hw->fc.requested_mode == e1000_fc_none ||
+			  hw->fc.requested_mode == e1000_fc_tx_pause) ||
 			 hw->fc.strict_ieee) {
-			hw->fc.type = e1000_fc_none;
+			hw->fc.current_mode = e1000_fc_none;
 			hw_dbg("Flow Control = NONE.\r\n");
 		} else {
-			hw->fc.type = e1000_fc_rx_pause;
+			hw->fc.current_mode = e1000_fc_rx_pause;
 			hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
 		}
 
@@ -939,7 +945,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 		}
 
 		if (duplex == HALF_DUPLEX)
-			hw->fc.type = e1000_fc_none;
+			hw->fc.current_mode = e1000_fc_none;
 
 		/*
 		 * Now we call a subroutine to actually force the MAC
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index f50fac2..c1f4da6 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -735,7 +735,7 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
 	 *  other:  No software override.  The flow control configuration
 	 *          in the EEPROM is used.
 	 */
-	switch (hw->fc.type) {
+	switch (hw->fc.current_mode) {
 	case e1000_fc_none:
 		/*
 		 * Flow control (RX & TX) is completely disabled by a
@@ -992,7 +992,7 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
 	u32 ctrl;
 
 	/* Turn off flow control when forcing speed/duplex */
-	hw->fc.type = e1000_fc_none;
+	hw->fc.current_mode = e1000_fc_none;
 
 	/* Force speed/duplex on the mac */
 	ctrl = rd32(E1000_CTRL);
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index df2d234..114ccab 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -194,6 +194,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 					     ADVERTISED_TP |
 					     ADVERTISED_Autoneg;
 		ecmd->advertising = hw->phy.autoneg_advertised;
+		if (adapter->fc_autoneg)
+			hw->fc.requested_mode = e1000_fc_default;
 	} else {
 		if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
 			clear_bit(__IGB_RESETTING, &adapter->state);
@@ -221,11 +223,11 @@ static void igb_get_pauseparam(struct net_device *netdev,
 	pause->autoneg =
 		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
 
-	if (hw->fc.type == e1000_fc_rx_pause)
+	if (hw->fc.current_mode == e1000_fc_rx_pause)
 		pause->rx_pause = 1;
-	else if (hw->fc.type == e1000_fc_tx_pause)
+	else if (hw->fc.current_mode == e1000_fc_tx_pause)
 		pause->tx_pause = 1;
-	else if (hw->fc.type == e1000_fc_full) {
+	else if (hw->fc.current_mode == e1000_fc_full) {
 		pause->rx_pause = 1;
 		pause->tx_pause = 1;
 	}
@@ -243,26 +245,28 @@ static int igb_set_pauseparam(struct net_device *netdev,
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
 		msleep(1);
 
-	if (pause->rx_pause && pause->tx_pause)
-		hw->fc.type = e1000_fc_full;
-	else if (pause->rx_pause && !pause->tx_pause)
-		hw->fc.type = e1000_fc_rx_pause;
-	else if (!pause->rx_pause && pause->tx_pause)
-		hw->fc.type = e1000_fc_tx_pause;
-	else if (!pause->rx_pause && !pause->tx_pause)
-		hw->fc.type = e1000_fc_none;
-
-	hw->fc.original_type = hw->fc.type;
-
 	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
+		hw->fc.requested_mode = e1000_fc_default;
 		if (netif_running(adapter->netdev)) {
 			igb_down(adapter);
 			igb_up(adapter);
 		} else
 			igb_reset(adapter);
-	} else
+	} else {
+		if (pause->rx_pause && pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_full;
+		else if (pause->rx_pause && !pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_rx_pause;
+		else if (!pause->rx_pause && pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_tx_pause;
+		else if (!pause->rx_pause && !pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_none;
+
+		hw->fc.current_mode = hw->fc.requested_mode;
+
 		retval = ((hw->phy.media_type == e1000_media_type_copper) ?
 			  igb_force_mac_fc(hw) : igb_setup_link(hw));
+	}
 
 	clear_bit(__IGB_RESETTING, &adapter->state);
 	return retval;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 12d8683..fb32735 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1130,7 +1130,7 @@ void igb_reset(struct igb_adapter *adapter)
 	}
 	fc->pause_time = 0xFFFF;
 	fc->send_xon = 1;
-	fc->type = fc->original_type;
+	fc->current_mode = fc->requested_mode;
 
 	/* disable receive for all VFs and wait one second */
 	if (adapter->vfs_allocated_count) {
@@ -1427,8 +1427,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 	hw->mac.autoneg = true;
 	hw->phy.autoneg_advertised = 0x2f;
 
-	hw->fc.original_type = e1000_fc_default;
-	hw->fc.type = e1000_fc_default;
+	hw->fc.requested_mode = e1000_fc_default;
+	hw->fc.current_mode = e1000_fc_default;
 
 	adapter->itr_setting = IGB_DEFAULT_ITR;
 	adapter->itr = IGB_START_ITR;


^ permalink raw reply related

* [net-next-2.6 PATCH 10/13] igb: use buffer_info->dma instead of shinfo->nr_frags to determine unmap
From: Jeff Kirsher @ 2009-07-24  4:10 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This change makes it so that we use buffer_info->dma instead of
shinfo->nr_frags to determine if we need to unmap a received skb.  By doing
this we can avoid a cache miss on small packets since the buffer_info
structure should already be prefetched.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/igb_main.c |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 2ffb51d..12d8683 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -4538,6 +4538,20 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
 	adapter->hw_csum_good++;
 }
 
+static inline u16 igb_get_hlen(struct igb_adapter *adapter,
+                               union e1000_adv_rx_desc *rx_desc)
+{
+	/* HW will not DMA in data larger than the given buffer, even if it
+	 * parses the (NFS, of course) header to be larger.  In that case, it
+	 * fills the header buffer and spills the rest into the page.
+	 */
+	u16 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
+	           E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+	if (hlen > adapter->rx_ps_hdr_size)
+		hlen = adapter->rx_ps_hdr_size;
+	return hlen;
+}
+
 static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
 				 int *work_done, int budget)
 {
@@ -4552,7 +4566,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
 	int cleaned_count = 0;
 	unsigned int total_bytes = 0, total_packets = 0;
 	unsigned int i;
-	u32 length, hlen, staterr;
+	u32 staterr;
+	u16 length;
 
 	i = rx_ring->next_to_clean;
 	buffer_info = &rx_ring->buffer_info[i];
@@ -4589,17 +4604,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
 			goto send_up;
 		}
 
-		/* HW will not DMA in data larger than the given buffer, even
-		 * if it parses the (NFS, of course) header to be larger.  In
-		 * that case, it fills the header buffer and spills the rest
-		 * into the page.
-		 */
-		hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
-		  E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
-		if (hlen > adapter->rx_ps_hdr_size)
-			hlen = adapter->rx_ps_hdr_size;
-
-		if (!skb_shinfo(skb)->nr_frags) {
+		if (buffer_info->dma) {
+			u16 hlen = igb_get_hlen(adapter, rx_desc);
 			pci_unmap_single(pdev, buffer_info->dma,
 					 adapter->rx_ps_hdr_size,
 					 PCI_DMA_FROMDEVICE);


^ permalink raw reply related

* [net-next-2.6 PATCH 09/13] igb: add support for 82576 mezzanine card
From: Jeff Kirsher @ 2009-07-24  4:09 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This patch adds support for a new 82576 mezzanine adapter.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |    1 +
 drivers/net/igb/e1000_hw.h    |    1 +
 drivers/net/igb/igb_main.c    |    1 +
 3 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 95360dc..dbbd72f 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -85,6 +85,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 	case E1000_DEV_ID_82576_FIBER:
 	case E1000_DEV_ID_82576_SERDES:
 	case E1000_DEV_ID_82576_QUAD_COPPER:
+	case E1000_DEV_ID_82576_SERDES_QUAD:
 		mac->type = e1000_82576;
 		break;
 	default:
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 83f9b4f..0469e2e 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -42,6 +42,7 @@ struct e1000_hw;
 #define E1000_DEV_ID_82576_SERDES             0x10E7
 #define E1000_DEV_ID_82576_QUAD_COPPER        0x10E8
 #define E1000_DEV_ID_82576_NS                 0x150A
+#define E1000_DEV_ID_82576_SERDES_QUAD        0x150D
 #define E1000_DEV_ID_82575EB_COPPER           0x10A7
 #define E1000_DEV_ID_82575EB_FIBER_SERDES     0x10A9
 #define E1000_DEV_ID_82575GB_QUAD_COPPER      0x10D6
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index e4f4526..2ffb51d 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -65,6 +65,7 @@ static struct pci_device_id igb_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },


^ permalink raw reply related

* [net-next-2.6 PATCH 08/13] igb: remove unused switch statement from igb_set_wol
From: Jeff Kirsher @ 2009-07-24  4:09 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

There is a switch statement in igb_set_wol that defaults to break and
doesn't actually do anything.  As such it should be removed.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/igb_ethtool.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index a9c37cb..df2d234 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -1836,7 +1836,6 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
 
 	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
 		return -EOPNOTSUPP;
@@ -1845,11 +1844,6 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 	    !device_can_wakeup(&adapter->pdev->dev))
 		return wol->wolopts ? -EOPNOTSUPP : 0;
 
-	switch (hw->device_id) {
-	default:
-		break;
-	}
-
 	/* these settings will always override what we currently have */
 	adapter->wol = 0;
 


^ permalink raw reply related

* [net-next-2.6 PATCH 07/13] igb: cleanup receive address register initialization
From: Jeff Kirsher @ 2009-07-24  4:09 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This update cleans up the receive address register initialization.  The
main purpose of this is to clean out some redundancy that was introduced
due to having multiple ways of setting the receive address registers.
Instead of having a specialized function to set one register and one to set
all of them it makes more sense to just go through the list calling the
function that is needed to set the individual registers.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |   39 ++++-----------------------------------
 drivers/net/igb/e1000_mac.c   |   25 +++++++++++++++++++++++++
 drivers/net/igb/e1000_mac.h   |    1 +
 3 files changed, 30 insertions(+), 35 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 5d2c2fb..95360dc 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -765,39 +765,6 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
 }
 
 /**
- *  igb_init_rx_addrs_82575 - Initialize receive address's
- *  @hw: pointer to the HW structure
- *  @rar_count: receive address registers
- *
- *  Setups the receive address registers by setting the base receive address
- *  register to the devices MAC address and clearing all the other receive
- *  address registers to 0.
- **/
-static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
-{
-	u32 i;
-	u8 addr[6] = {0,0,0,0,0,0};
-	/*
-	 * This function is essentially the same as that of
-	 * e1000_init_rx_addrs_generic. However it also takes care
-	 * of the special case where the register offset of the
-	 * second set of RARs begins elsewhere. This is implicitly taken care by
-	 * function e1000_rar_set_generic.
-	 */
-
-	hw_dbg("e1000_init_rx_addrs_82575");
-
-	/* Setup the receive address */
-	hw_dbg("Programming MAC Address into RAR[0]\n");
-	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
-
-	/* Zero out the other (rar_entry_count - 1) receive addresses */
-	hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
-	for (i = 1; i < rar_count; i++)
-	    hw->mac.ops.rar_set(hw, addr, i);
-}
-
-/**
  *  igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
  *  @hw: pointer to the HW structure
  *
@@ -889,7 +856,8 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
 	wr32(E1000_IMC, 0xffffffff);
 	icr = rd32(E1000_ICR);
 
-	igb_check_alt_mac_addr(hw);
+	/* Install any alternate MAC address into RAR0 */
+	ret_val = igb_check_alt_mac_addr(hw);
 
 	return ret_val;
 }
@@ -918,7 +886,8 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
 	igb_clear_vfta(hw);
 
 	/* Setup the receive address */
-	igb_init_rx_addrs_82575(hw, rar_count);
+	igb_init_rx_addrs(hw, rar_count);
+
 	/* Zero out the Multicast HASH table */
 	hw_dbg("Zeroing the MTA\n");
 	for (i = 0; i < mac->mta_reg_count; i++)
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 46e27e9..a1e3da7 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -104,6 +104,31 @@ static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
 }
 
 /**
+ *  igb_init_rx_addrs - Initialize receive address's
+ *  @hw: pointer to the HW structure
+ *  @rar_count: receive address registers
+ *
+ *  Setups the receive address registers by setting the base receive address
+ *  register to the devices MAC address and clearing all the other receive
+ *  address registers to 0.
+ **/
+void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
+{
+	u32 i;
+	u8 mac_addr[ETH_ALEN] = {0};
+
+	/* Setup the receive address */
+	hw_dbg("Programming MAC Address into RAR[0]\n");
+
+	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+	/* Zero out the other (rar_entry_count - 1) receive addresses */
+	hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
+	for (i = 1; i < rar_count; i++)
+		hw->mac.ops.rar_set(hw, mac_addr, i);
+}
+
+/**
  *  igb_vfta_set - enable or disable vlan in VLAN filter table
  *  @hw: pointer to the HW structure
  *  @vid: VLAN id to add or remove
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index f9ebfb3..7518af8 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -62,6 +62,7 @@ void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
 void igb_clear_vfta(struct e1000_hw *hw);
 s32  igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
 void igb_config_collision_dist(struct e1000_hw *hw);
+void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
 void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
 void igb_put_hw_semaphore(struct e1000_hw *hw);
 void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);


^ permalink raw reply related

* [net-next-2.6 PATCH 06/13] igb: move all multicast addresses into multicast table array
From: Jeff Kirsher @ 2009-07-24  4:08 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This patch moves all of the multicast addresses out of the free Receive
address registers and instead programs them all into the multicast table
array.  As a result the multicast filtering may not be as precise, but it
also greatly reduces the overhead for multicast addresses.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |   59 -----------------------------------------
 drivers/net/igb/e1000_82575.h |    1 -
 drivers/net/igb/e1000_hw.h    |    4 +++
 drivers/net/igb/e1000_mac.c   |   35 ++++++++++++++++++++++++
 drivers/net/igb/e1000_mac.h   |    2 +
 drivers/net/igb/igb_main.c    |   44 ++++++++++---------------------
 6 files changed, 56 insertions(+), 89 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index c4506bf..5d2c2fb 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -798,65 +798,6 @@ static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
 }
 
 /**
- *  igb_update_mc_addr_list - Update Multicast addresses
- *  @hw: pointer to the HW structure
- *  @mc_addr_list: array of multicast addresses to program
- *  @mc_addr_count: number of multicast addresses to program
- *  @rar_used_count: the first RAR register free to program
- *  @rar_count: total number of supported Receive Address Registers
- *
- *  Updates the Receive Address Registers and Multicast Table Array.
- *  The caller must have a packed mc_addr_list of multicast addresses.
- *  The parameter rar_count will usually be hw->mac.rar_entry_count
- *  unless there are workarounds that change this.
- **/
-void igb_update_mc_addr_list(struct e1000_hw *hw,
-                             u8 *mc_addr_list, u32 mc_addr_count,
-                             u32 rar_used_count, u32 rar_count)
-{
-	u32 hash_value;
-	u32 i;
-	u8 addr[6] = {0,0,0,0,0,0};
-	/*
-	 * This function is essentially the same as that of 
-	 * igb_update_mc_addr_list_generic. However it also takes care 
-	 * of the special case where the register offset of the 
-	 * second set of RARs begins elsewhere. This is implicitly taken care by 
-	 * function e1000_rar_set_generic.
-	 */
-
-	/*
-	 * Load the first set of multicast addresses into the exact
-	 * filters (RAR).  If there are not enough to fill the RAR
-	 * array, clear the filters.
-	 */
-	for (i = rar_used_count; i < rar_count; i++) {
-		if (mc_addr_count) {
-			igb_rar_set(hw, mc_addr_list, i);
-			mc_addr_count--;
-			mc_addr_list += ETH_ALEN;
-		} else {
-			igb_rar_set(hw, addr, i);
-		}
-	}
-
-	/* Clear the old settings from the MTA */
-	hw_dbg("Clearing MTA\n");
-	for (i = 0; i < hw->mac.mta_reg_count; i++) {
-		array_wr32(E1000_MTA, i, 0);
-		wrfl();
-	}
-
-	/* Load any remaining multicast addresses into the hash table. */
-	for (; mc_addr_count > 0; mc_addr_count--) {
-		hash_value = igb_hash_mc_addr(hw, mc_addr_list);
-		hw_dbg("Hash value = 0x%03X\n", hash_value);
-		igb_mta_set(hw, hash_value);
-		mc_addr_list += ETH_ALEN;
-	}
-}
-
-/**
  *  igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
  *  @hw: pointer to the HW structure
  *
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index b674417..8a1e659 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -28,7 +28,6 @@
 #ifndef _E1000_82575_H_
 #define _E1000_82575_H_
 
-void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
 extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
 extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
 
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index eb41f3b..83f9b4f 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -338,6 +338,10 @@ struct e1000_mac_info {
 	u16 ifs_ratio;
 	u16 ifs_step_size;
 	u16 mta_reg_count;
+
+	/* Maximum size of the MTA register table in all supported adapters */
+	#define MAX_MTA_REG 128
+	u32 mta_shadow[MAX_MTA_REG];
 	u16 rar_entry_count;
 
 	u8  forced_speed_duplex;
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 60343b5..46e27e9 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -261,6 +261,41 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
 }
 
 /**
+ *  igb_update_mc_addr_list - Update Multicast addresses
+ *  @hw: pointer to the HW structure
+ *  @mc_addr_list: array of multicast addresses to program
+ *  @mc_addr_count: number of multicast addresses to program
+ *
+ *  Updates entire Multicast Table Array.
+ *  The caller must have a packed mc_addr_list of multicast addresses.
+ **/
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+                             u8 *mc_addr_list, u32 mc_addr_count)
+{
+	u32 hash_value, hash_bit, hash_reg;
+	int i;
+
+	/* clear mta_shadow */
+	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
+
+	/* update mta_shadow from mc_addr_list */
+	for (i = 0; (u32) i < mc_addr_count; i++) {
+		hash_value = igb_hash_mc_addr(hw, mc_addr_list);
+
+		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+		hash_bit = hash_value & 0x1F;
+
+		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
+		mc_addr_list += (ETH_ALEN);
+	}
+
+	/* replace the entire MTA table */
+	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
+		array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
+	wrfl();
+}
+
+/**
  *  igb_hash_mc_addr - Generate a multicast hash value
  *  @hw: pointer to the HW structure
  *  @mc_addr: pointer to a multicast address
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index 1d690b4..f9ebfb3 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -51,6 +51,8 @@ s32  igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
 				       u16 *duplex);
 s32  igb_id_led_init(struct e1000_hw *hw);
 s32  igb_led_off(struct e1000_hw *hw);
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+	                     u8 *mc_addr_list, u32 mc_addr_count);
 s32  igb_setup_link(struct e1000_hw *hw);
 s32  igb_validate_mdi_setting(struct e1000_hw *hw);
 s32  igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 2cb5460..e4f4526 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -127,7 +127,7 @@ static void igb_restore_vlan(struct igb_adapter *);
 static void igb_ping_all_vfs(struct igb_adapter *);
 static void igb_msg_task(struct igb_adapter *);
 static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
-static void igb_set_mc_list_pools(struct igb_adapter *, int, u16);
+static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
 static void igb_vmm_control(struct igb_adapter *);
 static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
 static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
@@ -2535,7 +2535,6 @@ static void igb_set_multi(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	struct e1000_mac_info *mac = &hw->mac;
 	struct dev_mc_list *mc_ptr;
 	u8  *mta_list = NULL;
 	u32 rctl;
@@ -2558,13 +2557,18 @@ static void igb_set_multi(struct net_device *netdev)
 	}
 	wr32(E1000_RCTL, rctl);
 
-	if (netdev->mc_count) {
-		mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
-		if (!mta_list) {
-			dev_err(&adapter->pdev->dev,
-			        "failed to allocate multicast filter list\n");
-			return;
-		}
+	if (!netdev->mc_count) {
+		/* nothing to program, so clear mc list */
+		igb_update_mc_addr_list(hw, NULL, 0);
+		igb_restore_vf_multicasts(adapter);
+		return;
+	}
+
+	mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+	if (!mta_list) {
+		dev_err(&adapter->pdev->dev,
+		        "failed to allocate multicast filter list\n");
+		return;
 	}
 
 	/* The shared function expects a packed array of only addresses. */
@@ -2576,14 +2580,9 @@ static void igb_set_multi(struct net_device *netdev)
 		memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
 		mc_ptr = mc_ptr->next;
 	}
-	igb_update_mc_addr_list(hw, mta_list, i,
-	                        adapter->vfs_allocated_count + 1,
-	                        mac->rar_entry_count);
-
-	igb_set_mc_list_pools(adapter, i, mac->rar_entry_count);
-	igb_restore_vf_multicasts(adapter);
-
+	igb_update_mc_addr_list(hw, mta_list, i);
 	kfree(mta_list);
+	igb_restore_vf_multicasts(adapter);
 }
 
 /* Need to wait a few seconds after link up to get diagnostic information from
@@ -5468,19 +5467,6 @@ static void igb_io_resume(struct pci_dev *pdev)
 	igb_get_hw_control(adapter);
 }
 
-static void igb_set_mc_list_pools(struct igb_adapter *adapter,
-				  int entry_count, u16 total_rar_filters)
-{
-	struct e1000_hw *hw = &adapter->hw;
-	int i = adapter->vfs_allocated_count + 1;
-
-	if ((i + entry_count) < total_rar_filters)
-		total_rar_filters = i + entry_count;
-
-	for (; i < total_rar_filters; i++)
-		igb_set_rah_pool(hw, adapter->vfs_allocated_count, i);
-}
-
 static int igb_set_vf_mac(struct igb_adapter *adapter,
                           int vf, unsigned char *mac_addr)
 {


^ permalink raw reply related

* [net-next-2.6 PATCH 05/13] igb: add completion timeout workaround for 82575/82576
From: Jeff Kirsher @ 2009-07-24  4:08 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

The 82575 and 82576 hardware can both experience data corruption issues if
a pci-e completion arrives after the timeout value.  In order to avoid this
we need to increase the timeout value while pci-e master is disabled.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c   |   58 +++++++++++++++++++++++++++++++++++++++
 drivers/net/igb/e1000_defines.h |    8 +++++
 drivers/net/igb/e1000_hw.h      |    4 ++-
 drivers/net/igb/e1000_mac.c     |   14 ---------
 drivers/net/igb/e1000_regs.h    |    1 +
 drivers/net/igb/igb_main.c      |   28 +++++++++++++++++++
 6 files changed, 98 insertions(+), 15 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 606c25c..c4506bf 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -61,6 +61,7 @@ static void igb_release_swfw_sync_82575(struct e1000_hw *, u16);
 static bool igb_sgmii_active_82575(struct e1000_hw *);
 static s32  igb_reset_init_script_82575(struct e1000_hw *);
 static s32  igb_read_mac_addr_82575(struct e1000_hw *);
+static s32  igb_set_pcie_completion_timeout(struct e1000_hw *hw);
 
 static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 {
@@ -909,6 +910,12 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
 	if (ret_val)
 		hw_dbg("PCI-E Master disable polling has failed.\n");
 
+	/* set the completion timeout for interface */
+	ret_val = igb_set_pcie_completion_timeout(hw);
+	if (ret_val) {
+		hw_dbg("PCI-E Set completion timeout has failed.\n");
+	}
+
 	hw_dbg("Masking off all interrupts\n");
 	wr32(E1000_IMC, 0xffffffff);
 
@@ -1408,6 +1415,57 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
 }
 
 /**
+ *  igb_set_pcie_completion_timeout - set pci-e completion timeout
+ *  @hw: pointer to the HW structure
+ *
+ *  The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
+ *  however the hardware default for these parts is 500us to 1ms which is less
+ *  than the 10ms recommended by the pci-e spec.  To address this we need to
+ *  increase the value to either 10ms to 200ms for capability version 1 config,
+ *  or 16ms to 55ms for version 2.
+ **/
+static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw)
+{
+	u32 gcr = rd32(E1000_GCR);
+	s32 ret_val = 0;
+	u16 pcie_devctl2;
+
+	/* only take action if timeout value is defaulted to 0 */
+	if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
+		goto out;
+
+	/*
+	 * if capababilities version is type 1 we can write the
+	 * timeout of 10ms to 200ms through the GCR register
+	 */
+	if (!(gcr & E1000_GCR_CAP_VER2)) {
+		gcr |= E1000_GCR_CMPL_TMOUT_10ms;
+		goto out;
+	}
+
+	/*
+	 * for version 2 capabilities we need to write the config space
+	 * directly in order to set the completion timeout value for
+	 * 16ms to 55ms
+	 */
+	ret_val = igb_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+	                                &pcie_devctl2);
+	if (ret_val)
+		goto out;
+
+	pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
+
+	ret_val = igb_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+	                                 &pcie_devctl2);
+out:
+	/* disable completion timeout resend */
+	gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
+
+	wr32(E1000_GCR, gcr);
+	return ret_val;
+}
+
+/**
  *  igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
  *  @hw: pointer to the hardware struct
  *  @enable: state to enter, either enabled or disabled
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 3bda3db..c858293 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -435,6 +435,12 @@
 /* Flow Control */
 #define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
 
+/* PCI Express Control */
+#define E1000_GCR_CMPL_TMOUT_MASK       0x0000F000
+#define E1000_GCR_CMPL_TMOUT_10ms       0x00001000
+#define E1000_GCR_CMPL_TMOUT_RESEND     0x00010000
+#define E1000_GCR_CAP_VER2              0x00040000
+
 /* PHY Control Register */
 #define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
 #define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
@@ -569,9 +575,11 @@
 
 /* PCI/PCI-X/PCI-EX Config space */
 #define PCIE_LINK_STATUS             0x12
+#define PCIE_DEVICE_CONTROL2         0x28
 
 #define PCIE_LINK_WIDTH_MASK         0x3F0
 #define PCIE_LINK_WIDTH_SHIFT        4
+#define PCIE_DEVICE_CONTROL2_16ms    0x0005
 
 #define PHY_REVISION_MASK      0xFFFFFFF0
 #define MAX_PHY_REG_ADDRESS    0x1F  /* 5 bit address bus (0-0x1F) */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index f096ddd..eb41f3b 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -494,5 +494,7 @@ extern char *igb_get_hw_dev_name(struct e1000_hw *hw);
 #else
 #define hw_dbg(format, arg...)
 #endif
-
 #endif
+/* These functions must be implemented by drivers */
+s32  igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
+s32  igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 34f1a37..60343b5 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -37,20 +37,6 @@
 static s32 igb_set_default_fc(struct e1000_hw *hw);
 static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
 
-static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
-{
-	struct igb_adapter *adapter = hw->back;
-	u16 cap_offset;
-
-	cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
-	if (!cap_offset)
-		return -E1000_ERR_CONFIG;
-
-	pci_read_config_word(adapter->pdev, cap_offset + reg, value);
-
-	return 0;
-}
-
 /**
  *  igb_get_bus_info_pcie - Get PCIe bus information
  *  @hw: pointer to the HW structure
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index 6e59245..345d144 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -305,6 +305,7 @@ enum {
 #define E1000_CCMCTL      0x05B48 /* CCM Control Register */
 #define E1000_GIOCTL      0x05B44 /* GIO Analog Control Register */
 #define E1000_SCCTL       0x05B4C /* PCIc PLL Configuration Register */
+#define E1000_GCR         0x05B00 /* PCI-Ex Control */
 #define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
 #define E1000_SWSM      0x05B50 /* SW Semaphore */
 #define E1000_FWSM      0x05B54 /* FW Semaphore */
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 39b3b6a..2cb5460 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -5029,6 +5029,34 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 	}
 }
 
+s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+	struct igb_adapter *adapter = hw->back;
+	u16 cap_offset;
+
+	cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+	if (!cap_offset)
+		return -E1000_ERR_CONFIG;
+
+	pci_read_config_word(adapter->pdev, cap_offset + reg, value);
+
+	return 0;
+}
+
+s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+	struct igb_adapter *adapter = hw->back;
+	u16 cap_offset;
+
+	cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+	if (!cap_offset)
+		return -E1000_ERR_CONFIG;
+
+	pci_write_config_word(adapter->pdev, cap_offset + reg, *value);
+
+	return 0;
+}
+
 static void igb_vlan_rx_register(struct net_device *netdev,
 				 struct vlan_group *grp)
 {


^ permalink raw reply related

* [net-next-2.6 PATCH 04/13] igb: do not overwrite EEPROM LED settings
From: Jeff Kirsher @ 2009-07-24  4:08 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

The igb driver was overwritting the LED settings that were configured via
EEPROM.  This is not correct behavior as the LED settings are meant to be
configured by EEPROM and not changed.  This change removes the code that
was setting the LED behavior on the interface.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |    7 +------
 1 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index f946bed..606c25c 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1000,7 +1000,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
  **/
 static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
 {
-	u32 ctrl, led_ctrl;
+	u32 ctrl;
 	s32  ret_val;
 	bool link;
 
@@ -1015,11 +1015,6 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
 		break;
 	case e1000_phy_igp_3:
 		ret_val = igb_copper_link_setup_igp(hw);
-		/* Setup activity LED */
-		led_ctrl = rd32(E1000_LEDCTL);
-		led_ctrl &= IGP_ACTIVITY_LED_MASK;
-		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-		wr32(E1000_LEDCTL, led_ctrl);
 		break;
 	default:
 		ret_val = -E1000_ERR_PHY;


^ permalink raw reply related

* [net-next-2.6 PATCH 03/13] igb: change configure_pcs_link to void since it always returns 0
From: Jeff Kirsher @ 2009-07-24  4:07 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

Since igb_configure_pcs_link always returns 0 there isn't really much point
to checking for the result so it is best just to change this to a void so
we can properly ignore the return result.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index fa4a762..f946bed 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -53,7 +53,7 @@ static s32  igb_setup_fiber_serdes_link_82575(struct e1000_hw *);
 static s32  igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16);
 static void igb_clear_hw_cntrs_82575(struct e1000_hw *);
 static s32  igb_acquire_swfw_sync_82575(struct e1000_hw *, u16);
-static s32  igb_configure_pcs_link_82575(struct e1000_hw *);
+static void igb_configure_pcs_link_82575(struct e1000_hw *);
 static s32  igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *, u16 *,
 						 u16 *);
 static s32  igb_get_phy_id_82575(struct e1000_hw *);
@@ -1050,9 +1050,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
 		}
 	}
 
-	ret_val = igb_configure_pcs_link_82575(hw);
-	if (ret_val)
-		goto out;
+	igb_configure_pcs_link_82575(hw);
 
 	/*
 	 * Check link status. Wait up to 100 microseconds for link to become
@@ -1161,14 +1159,14 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
  *  independent interface (sgmii) is being used.  Configures the link
  *  for auto-negotiation or forces speed/duplex.
  **/
-static s32 igb_configure_pcs_link_82575(struct e1000_hw *hw)
+static void igb_configure_pcs_link_82575(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 reg = 0;
 
 	if (hw->phy.media_type != e1000_media_type_copper ||
 	    !(igb_sgmii_active_82575(hw)))
-		goto out;
+		return;
 
 	/* For SGMII, we need to issue a PCS autoneg restart */
 	reg = rd32(E1000_PCS_LCTL);
@@ -1211,9 +1209,6 @@ static s32 igb_configure_pcs_link_82575(struct e1000_hw *hw)
 		       reg);
 	}
 	wr32(E1000_PCS_LCTL, reg);
-
-out:
-	return 0;
 }
 
 /**


^ permalink raw reply related

* [net-next-2.6 PATCH 02/13] igb: make serdes power down available for 82575 in addition to 82576 parts
From: Jeff Kirsher @ 2009-07-24  4:07 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20090724040700.30709.31473.stgit@localhost.localdomain>

From: Alexander Duyck <alexander.h.duyck@intel.com>

There was a serdes power down workaround that was originally added for
82576 fiber.  However it has also been found that this workaround is needed
for serdes connections as well.  In addition it is also needed for 82575
serdes so we we need to remove the checks restricting it to 82576.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |    7 +------
 drivers/net/igb/e1000_82575.h |    5 +++++
 drivers/net/igb/e1000_mac.c   |   14 +++++++++++---
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index bd3efdb..fa4a762 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -866,8 +866,7 @@ void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
 {
 	u32 reg;
 
-	if (hw->mac.type != e1000_82576 ||
-	    hw->phy.media_type != e1000_media_type_internal_serdes)
+	if (hw->phy.media_type != e1000_media_type_internal_serdes)
 		return;
 
 	/* if the management interface is not enabled, then power down */
@@ -1228,10 +1227,6 @@ out:
 static bool igb_sgmii_active_82575(struct e1000_hw *hw)
 {
 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
-
-	if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
-		return false;
-
 	return dev_spec->sgmii_active;
 }
 
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index 0f16aba..b674417 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -32,6 +32,11 @@ void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
 extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
 extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
 
+#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
+                                     (ID_LED_DEF1_DEF2 <<  8) | \
+                                     (ID_LED_DEF1_DEF2 <<  4) | \
+                                     (ID_LED_OFF1_ON2))
+
 #define E1000_RAR_ENTRIES_82575   16
 #define E1000_RAR_ENTRIES_82576   24
 
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 37706d9..34f1a37 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -1064,9 +1064,17 @@ static s32 igb_valid_led_default(struct e1000_hw *hw, u16 *data)
 		goto out;
 	}
 
-	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
-		*data = ID_LED_DEFAULT;
-
+	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
+		switch(hw->phy.media_type) {
+		case e1000_media_type_internal_serdes:
+			*data = ID_LED_DEFAULT_82575_SERDES;
+			break;
+		case e1000_media_type_copper:
+		default:
+			*data = ID_LED_DEFAULT;
+			break;
+		}
+	}
 out:
 	return ret_val;
 }


^ permalink raw reply related

* [net-next-2.6 PATCH 01/13] igb: remove media type fiber as it is misleading
From: Jeff Kirsher @ 2009-07-24  4:07 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher

From: Alexander Duyck <alexander.h.duyck@intel.com>

The current igb driver only supports copper and serdes.  The fiber media
type is a holdover from earlier NICs as the current nics supported by igb
all use serdes when communicating over a fiber connection.  As a result we
can remove media type fiber without losing any functionality.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c |    3 +--
 drivers/net/igb/e1000_hw.h    |    3 +--
 drivers/net/igb/e1000_mac.c   |   37 +++++++++++--------------------------
 drivers/net/igb/igb_ethtool.c |   25 +++++++++----------------
 drivers/net/igb/igb_main.c    |   12 ------------
 5 files changed, 22 insertions(+), 58 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index ac28dd5..bd3efdb 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -867,8 +867,7 @@ void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
 	u32 reg;
 
 	if (hw->mac.type != e1000_82576 ||
-	    (hw->phy.media_type != e1000_media_type_fiber &&
-	     hw->phy.media_type != e1000_media_type_internal_serdes))
+	    hw->phy.media_type != e1000_media_type_internal_serdes)
 		return;
 
 	/* if the management interface is not enabled, then power down */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 68aac20..f096ddd 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -61,8 +61,7 @@ enum e1000_mac_type {
 enum e1000_media_type {
 	e1000_media_type_unknown = 0,
 	e1000_media_type_copper = 1,
-	e1000_media_type_fiber = 2,
-	e1000_media_type_internal_serdes = 3,
+	e1000_media_type_internal_serdes = 2,
 	e1000_num_media_types
 };
 
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 472f3f1..37706d9 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -713,8 +713,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 	 * configuration of the MAC to match the "fc" parameter.
 	 */
 	if (mac->autoneg_failed) {
-		if (hw->phy.media_type == e1000_media_type_fiber ||
-		    hw->phy.media_type == e1000_media_type_internal_serdes)
+		if (hw->phy.media_type == e1000_media_type_internal_serdes)
 			ret_val = igb_force_mac_fc(hw);
 	} else {
 		if (hw->phy.media_type == e1000_media_type_copper)
@@ -1161,22 +1160,16 @@ s32 igb_blink_led(struct e1000_hw *hw)
 	u32 ledctl_blink = 0;
 	u32 i;
 
-	if (hw->phy.media_type == e1000_media_type_fiber) {
-		/* always blink LED0 for PCI-E fiber */
-		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
-		     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
-	} else {
-		/*
-		 * set the blink bit for each LED that's "on" (0x0E)
-		 * in ledctl_mode2
-		 */
-		ledctl_blink = hw->mac.ledctl_mode2;
-		for (i = 0; i < 4; i++)
-			if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
-			    E1000_LEDCTL_MODE_LED_ON)
-				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
-						 (i * 8));
-	}
+	/*
+	 * set the blink bit for each LED that's "on" (0x0E)
+	 * in ledctl_mode2
+	 */
+	ledctl_blink = hw->mac.ledctl_mode2;
+	for (i = 0; i < 4; i++)
+		if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
+		    E1000_LEDCTL_MODE_LED_ON)
+			ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
+					 (i * 8));
 
 	wr32(E1000_LEDCTL, ledctl_blink);
 
@@ -1191,15 +1184,7 @@ s32 igb_blink_led(struct e1000_hw *hw)
  **/
 s32 igb_led_off(struct e1000_hw *hw)
 {
-	u32 ctrl;
-
 	switch (hw->phy.media_type) {
-	case e1000_media_type_fiber:
-		ctrl = rd32(E1000_CTRL);
-		ctrl |= E1000_CTRL_SWDPIN0;
-		ctrl |= E1000_CTRL_SWDPIO0;
-		wr32(E1000_CTRL, ctrl);
-		break;
 	case e1000_media_type_copper:
 		wr32(E1000_LEDCTL, hw->mac.ledctl_mode1);
 		break;
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 9598ac0..a9c37cb 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -168,8 +168,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 		ecmd->duplex = -1;
 	}
 
-	ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
-			 hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+	ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 	return 0;
 }
 
@@ -191,23 +190,18 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		hw->mac.autoneg = 1;
-		if (hw->phy.media_type == e1000_media_type_fiber)
-			hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full |
-						     ADVERTISED_FIBRE |
-						     ADVERTISED_Autoneg;
-		else
-			hw->phy.autoneg_advertised = ecmd->advertising |
-						     ADVERTISED_TP |
-						     ADVERTISED_Autoneg;
+		hw->phy.autoneg_advertised = ecmd->advertising |
+					     ADVERTISED_TP |
+					     ADVERTISED_Autoneg;
 		ecmd->advertising = hw->phy.autoneg_advertised;
-	} else
+	} else {
 		if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
 			clear_bit(__IGB_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
+	}
 
 	/* reset the link */
-
 	if (netif_running(adapter->netdev)) {
 		igb_down(adapter);
 		igb_up(adapter);
@@ -267,8 +261,8 @@ static int igb_set_pauseparam(struct net_device *netdev,
 		} else
 			igb_reset(adapter);
 	} else
-		retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
-			  igb_setup_link(hw) : igb_force_mac_fc(hw));
+		retval = ((hw->phy.media_type == e1000_media_type_copper) ?
+			  igb_force_mac_fc(hw) : igb_setup_link(hw));
 
 	clear_bit(__IGB_RESETTING, &adapter->state);
 	return retval;
@@ -1483,8 +1477,7 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	u32 reg;
 
-	if (hw->phy.media_type == e1000_media_type_fiber ||
-	    hw->phy.media_type == e1000_media_type_internal_serdes) {
+	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
 		reg = rd32(E1000_RCTL);
 		reg |= E1000_RCTL_LBM_TCVR;
 		wr32(E1000_RCTL, reg);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index adb09d3..39b3b6a 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -2618,10 +2618,6 @@ static bool igb_has_link(struct igb_adapter *adapter)
 			link_active = true;
 		}
 		break;
-	case e1000_media_type_fiber:
-		ret_val = hw->mac.ops.check_for_link(hw);
-		link_active = !!(rd32(E1000_STATUS) & E1000_STATUS_LU);
-		break;
 	case e1000_media_type_internal_serdes:
 		ret_val = hw->mac.ops.check_for_link(hw);
 		link_active = hw->mac.serdes_has_link;
@@ -5136,14 +5132,6 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
 
 	mac->autoneg = 0;
 
-	/* Fiber NICs only allow 1000 gbps Full duplex */
-	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		dev_err(&adapter->pdev->dev,
-			"Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
-	}
-
 	switch (spddplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		mac->forced_speed_duplex = ADVERTISE_10_HALF;


^ permalink raw reply related


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