Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] dev: use ifindex hash for dev_seq_ops
From: Mihai Maruseac @ 2011-10-12  9:59 UTC (permalink / raw)
  To: Mihai Maruseac
  Cc: dbaluta, mmaruseac, davem@davemloft.net, eric.dumazet@gmail.com,
	mirq-linux@rere.qmqm.pl, therbert@google.com, jpirko@redhat.com,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1318413446-22258-1-git-send-email-mmaruseac@ixiacom.com>

On Wed, 2011-10-12 at 02:57 -0700, Mihai Maruseac wrote:
> Instead of using the dev->next chain and trying to resync at each call to
> dev_seq_start, use the ifindex, keeping the last index in seq->private field.

Please consider only my last patch email, the first one was missing
Signed-off-by line.

Thanks,
Mihai

^ permalink raw reply

* [PATCH] dev: use ifindex hash for dev_seq_ops
From: Mihai Maruseac @ 2011-10-12  9:57 UTC (permalink / raw)
  To: davem
  Cc: eric.dumazet, mirq-linux, therbert, jpirko, netdev, linux-kernel,
	dbaluta, Mihai Maruseac
In-Reply-To: <1318000849-2531-1-git-send-email-mmaruseac@ixiacom.com>

Instead of using the dev->next chain and trying to resync at each call to
dev_seq_start, use the ifindex, keeping the last index in seq->private field.

Tests revealed the following results for ifconfig > /dev/null
	* 1000 interfaces:
		* 0.114s without patch
		* 0.089s with patch
	* 3000 interfaces:
		* 0.489s without patch
		* 0.110s with patch
	* 5000 interfaces:
		* 1.363s without patch
		* 0.250s with patch
	* 128000 interfaces (other setup):
		* ~100s without patch
		* ~30s with patch

Signed-off-by: Mihai Maruseac <mmaruseac@ixiacom.com>
---
 net/core/dev.c |   53 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 70ecb86..3ca0df8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4041,6 +4041,35 @@ static int dev_ifconf(struct net *net, char __user *arg)
 }
 
 #ifdef CONFIG_PROC_FS
+
+struct dev_iter_state {
+	struct seq_net_private p;
+	int ifindex;
+};
+
+static inline struct net_device *next_dev(struct seq_file *seq, loff_t *pos)
+{
+	struct dev_iter_state *state = seq->private;
+	struct net *net = seq_file_net(seq);
+	struct net_device *dev = NULL;
+	loff_t off;
+
+	++*pos;
+	dev = dev_get_by_index_rcu(net, state->ifindex);
+	state->ifindex++;
+	if (likely(dev))
+		return dev;
+
+	off = 1;
+	for_each_netdev_rcu(net, dev)
+		if (off++ == *pos) {
+			state->ifindex = dev->ifindex + 1;
+			return dev;
+		}
+
+	return NULL;
+}
+
 /*
  *	This is invoked by the /proc filesystem handler to display a device
  *	in detail.
@@ -4048,33 +4077,15 @@ static int dev_ifconf(struct net *net, char __user *arg)
 void *dev_seq_start(struct seq_file *seq, loff_t *pos)
 	__acquires(RCU)
 {
-	struct net *net = seq_file_net(seq);
-	loff_t off;
-	struct net_device *dev;
-
 	rcu_read_lock();
 	if (!*pos)
 		return SEQ_START_TOKEN;
-
-	off = 1;
-	for_each_netdev_rcu(net, dev)
-		if (off++ == *pos)
-			return dev;
-
-	return NULL;
+	return next_dev(seq, pos);
 }
 
 void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	struct net_device *dev = v;
-
-	if (v == SEQ_START_TOKEN)
-		dev = first_net_device_rcu(seq_file_net(seq));
-	else
-		dev = next_net_device_rcu(dev);
-
-	++*pos;
-	return dev;
+	return next_dev(seq, pos);
 }
 
 void dev_seq_stop(struct seq_file *seq, void *v)
@@ -4173,7 +4184,7 @@ static const struct seq_operations dev_seq_ops = {
 static int dev_seq_open(struct inode *inode, struct file *file)
 {
 	return seq_open_net(inode, file, &dev_seq_ops,
-			    sizeof(struct seq_net_private));
+			    sizeof(struct dev_iter_state));
 }
 
 static const struct file_operations dev_seq_fops = {
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH] dev: use ifindex hash for dev_seq_ops
From: Mihai Maruseac @ 2011-10-12  9:49 UTC (permalink / raw)
  To: davem
  Cc: eric.dumazet, mirq-linux, therbert, jpirko, netdev, linux-kernel,
	dbaluta, Mihai Maruseac
In-Reply-To: <1318000849-2531-1-git-send-email-mmaruseac@ixiacom.com>

Instead of using the dev->next chain and trying to resync at each call to
dev_seq_start, use the ifindex, keeping the last index in seq->private field.

Tests revealed the following results for ifconfig > /dev/null
	* 1000 interfaces:
		* 0.114s without patch
		* 0.089s with patch
	* 3000 interfaces:
		* 0.489s without patch
		* 0.110s with patch
	* 5000 interfaces:
		* 1.363s without patch
		* 0.250s with patch
	* 128000 interfaces (other setup):
		* ~100s without patch
		* ~30s with patch
---
 net/core/dev.c |   53 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 70ecb86..3ca0df8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4041,6 +4041,35 @@ static int dev_ifconf(struct net *net, char __user *arg)
 }
 
 #ifdef CONFIG_PROC_FS
+
+struct dev_iter_state {
+	struct seq_net_private p;
+	int ifindex;
+};
+
+static inline struct net_device* next_dev(struct seq_file *seq, loff_t *pos)
+{
+	struct dev_iter_state *state = seq->private;
+	struct net *net = seq_file_net(seq);
+	struct net_device *dev = NULL;
+	loff_t off;
+
+	++*pos;
+	dev = dev_get_by_index_rcu(net, state->ifindex);
+	state->ifindex++;
+	if (likely(dev))
+		return dev;
+
+	off = 1;
+	for_each_netdev_rcu(net, dev)
+		if (off++ == *pos) {
+			state->ifindex = dev->ifindex + 1;
+			return dev;
+		}
+
+	return NULL;
+}
+
 /*
  *	This is invoked by the /proc filesystem handler to display a device
  *	in detail.
@@ -4048,33 +4077,15 @@ static int dev_ifconf(struct net *net, char __user *arg)
 void *dev_seq_start(struct seq_file *seq, loff_t *pos)
 	__acquires(RCU)
 {
-	struct net *net = seq_file_net(seq);
-	loff_t off;
-	struct net_device *dev;
-
 	rcu_read_lock();
 	if (!*pos)
 		return SEQ_START_TOKEN;
-
-	off = 1;
-	for_each_netdev_rcu(net, dev)
-		if (off++ == *pos)
-			return dev;
-
-	return NULL;
+	return next_dev(seq, pos);
 }
 
 void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-	struct net_device *dev = v;
-
-	if (v == SEQ_START_TOKEN)
-		dev = first_net_device_rcu(seq_file_net(seq));
-	else
-		dev = next_net_device_rcu(dev);
-
-	++*pos;
-	return dev;
+	return next_dev(seq, pos);
 }
 
 void dev_seq_stop(struct seq_file *seq, void *v)
@@ -4173,7 +4184,7 @@ static const struct seq_operations dev_seq_ops = {
 static int dev_seq_open(struct inode *inode, struct file *file)
 {
 	return seq_open_net(inode, file, &dev_seq_ops,
-			    sizeof(struct seq_net_private));
+			    sizeof(struct dev_iter_state));
 }
 
 static const struct file_operations dev_seq_fops = {
-- 
1.7.4.1

^ permalink raw reply related

* [patch net-2.6] tg3: negate USE_PHYLIB flag check
From: Jiri Pirko @ 2011-10-12  9:00 UTC (permalink / raw)
  To: netdev; +Cc: davem, eric.dumazet, mcarlson, mchan

USE_PHYLIB flag in tg3_remove_one() is being checked incorrectly. This
results tg3_phy_fini->phy_disconnect is never called and when tg3 module
is removed.

In my case this resulted in panics in phy_state_machine calling function
phydev->adjust_link.

So correct this check.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 drivers/net/tg3.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4a1374d..c11a2b8 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -15577,7 +15577,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
 
 		cancel_work_sync(&tp->reset_task);
 
-		if (!tg3_flag(tp, USE_PHYLIB)) {
+		if (tg3_flag(tp, USE_PHYLIB)) {
 			tg3_phy_fini(tp);
 			tg3_mdio_fini(tp);
 		}
-- 
1.7.6.2

^ permalink raw reply related

* Re: about phonet pipe controller
From: Rémi Denis-Courmont @ 2011-10-12  7:58 UTC (permalink / raw)
  To: ext Hemant-vilas RAMDASI; +Cc: Srinidhi KASAGAR, netdev@vger.kernel.org
In-Reply-To: <81C3A93C17462B4BBD7E272753C105791EAACAE76F@EXDCVYMBSTM005.EQ1STM.local>

Le Mercredi 12 Octobre 2011 09:25:01 ext Hemant-vilas RAMDASI a écrit :
> You have mentioned in the
> "a015f6f: Phonet: kill the ST-Ericsson pipe controller Kconfig",
> that "Support for manually enabling the pipe flow is removed as it
> did not work properly, does not fit well with the socket API, and
> I am not aware of any use at the moment.."
> 
> On STE U8500 modem, you must first create pipe in disabled state, then do
> local link configuration (does't work when pipe is enabled) & then enable
> pipe.

The Kconfig option broke support for existing hardware (Nokia N900 as a USB 
gadget) and userspace (namely the oFono ISI driver). We cannot expect 
distributions to provide two different kernel builds for different flavors of ISI 
modems.

> Because of this connect() cannot be used anymore and it needs to be modified
> to reintroduce pipe-controller functionality again.

As far as I can tell, that code NEVER worked properly. Not only the use of a 
build-time option is inappropriate, but the code did not deal with a number of 
new corner cases that it introduced.

> Do you have any suggestions?

I'm sorry but I don't really get where you're trying to get. The code had more 
bugs than I could fix by myself, especially when I don't have the hardware and 
the specification.

-- 
Rémi Denis-Courmont
http://www.remlab.net/

^ permalink raw reply

* about phonet pipe controller
From: Hemant-vilas RAMDASI @ 2011-10-12  7:25 UTC (permalink / raw)
  To: remi.denis-courmont@nokia.com; +Cc: Srinidhi KASAGAR, netdev@vger.kernel.org

Hi Remi,

You have mentioned in the
"a015f6f: Phonet: kill the ST-Ericsson pipe controller Kconfig",
that "Support for manually enabling the pipe flow is removed as it
did not work properly, does not fit well with the socket API, and
I am not aware of any use at the moment.."

On STE U8500 modem, you must first create pipe in disabled state, then do
local link configuration (does't work when pipe is enabled) & then enable pipe.

Because of this connect() cannot be used anymore and it needs to be modified to
reintroduce pipe-controller functionality again.

Do you have any suggestions?

Regards,
Hemant Ramdasi

^ permalink raw reply

* Re: [RFC PATCH net 1/2] [BUGFIX] bonding: use local function pointer of bond->recv_probe in bond_handle_frame
From: HAYASAKA Mitsuo @ 2011-10-12  7:04 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Américo Wang, Jay Vosburgh, Andy Gospodarek, netdev,
	linux-kernel, yrl.pp-manager.tt
In-Reply-To: <1318339433.2538.25.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>

Hi Eric,

Thank you for your comment.

(2011/10/11 22:23), Eric Dumazet wrote:
> Le mardi 11 octobre 2011 à 22:02 +0900, HAYASAKA Mitsuo a écrit :
>> Hi WANG Cong
>>
>> Thank you for your comments.
>>
>> (2011/10/07 22:24), Américo Wang wrote:
>>> On Fri, Oct 7, 2011 at 8:49 PM, Mitsuo Hayasaka
>>> <mitsuo.hayasaka.hu@hitachi.com> wrote:
>>>> The bond->recv_probe is called in bond_handle_frame() when
>>>> a packet is received, but bond_close() sets it to NULL. So,
>>>> a panic occurs when both functions work in parallel.
>>>>
>>>> Why this happen:
>>>> After null pointer check of bond->recv_probe, an sk_buff is
>>>> duplicated and bond->recv_probe is called in bond_handle_frame.
>>>> So, a panic occurs when bond_close() is called between the
>>>> check and call of bond->recv_probe.
>>>>
>>>> Patch:
>>>> This patch uses a local function pointer of bond->recv_probe
>>>> in bond_handle_frame(). So, it can avoid the null pointer
>>>> dereference.
>>>>
>>>
>>> Hmm, I don't doubt it can fix the problem, I am wondering if
>>> bond->recv_probe should be protected by bond->lock...
>>
>> Indeed, in general any resources should be protected from the asynchronous
>> workers.
>>
>> At first, I thought it should be handled with lock protection, as well.
>> However, I guess that using bond->lock on this kind of hot-path may
>> introduces unnecessary overhead. In addition, this code works well
>> without the strict lock protection. So, I think this change is the
>> right way to fix it.
> 
> Maybe, but then ACCESS_ONCE() is needed to prevent compiler to
> 'optimize' the temporary variable.
> 
> Or use rcu_dereference() to make the whole thing really safe and self
> documented.
> 
I agreed.
I'd like to send the patch with ACCESS_ONCE(), again.

Thanks.

^ permalink raw reply

* Re: [net-next 1/5] stmmac: add CHAINED descriptor mode support
From: Giuseppe CAVALLARO @ 2011-10-12  6:37 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, rayagond
In-Reply-To: <20111011.154203.569015025155780686.davem@davemloft.net>

On 10/11/2011 9:42 PM, David Miller wrote:
> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Tue, 11 Oct 2011 09:30:42 +0200
> 
>> From: Rayagond Kokatanur <rayagond@vayavyalabs.com>
>>
>> This patch enhances the STMMAC driver to support CHAINED mode of
>> descriptor (useful also on validation side).
>>
>> STMMAC supports DMA descriptor to operate both in dual buffer(RING)
>> and linked-list(CHAINED) mode. In RING mode (default) each descriptor
>> points to two data buffer pointers whereas in CHAINED mode they point
>> to only one data buffer pointer.
>>
>> In CHAINED mode each descriptor will have pointer to next descriptor in
>> the list, hence creating the explicit chaining in the descriptor itself,
>> whereas such explicit chaining is not possible in RING mode.
>>
>> Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>
>> Hacked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> 
> These ifdefs added all over the place in the foo.c files are terrible.
> 
> Abstract out the differences between RING and CHAINED mode into helper
> inline routines which live in some foo.h header file, that way you won't
> need any ifdefs in the driver foo.c files.

Hello David

I'll rework the patch and send all these updates to the mailing list
again (as V2).

Peppe

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

* Re: ixgbe: fixup hard dependencies on supporting 8 traffic classes
From: John Fastabend @ 2011-10-12  6:58 UTC (permalink / raw)
  To: Dan Carpenter, Kirsher, Jeffrey T
  Cc: e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org
In-Reply-To: <20111012063555.GA23359@elgon.mountain>

On 10/11/2011 11:35 PM, Dan Carpenter wrote:
> Hello John Fastabend,
> 
> This is a semi-automatic email about new static checker warnings.
> 
> The patch 32701dc2e616: "ixgbe: fixup hard dependencies on supporting
> 8 traffic classes" from Sep 27, 2011, leads to the following Smatch
> complaint:
> 
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +3366 ixgbe_configure_dcb()
> 	 error: we previously assumed 'adapter->ixgbe_ieee_ets' could be null (see line 3357)
> 
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
>   3356	
>   3357			if (adapter->ixgbe_ieee_ets) {
>                             ^^^^^^^^^^^^^^^^^^^^^^^
> Null check.
> 
>   3358				struct ieee_ets *ets = adapter->ixgbe_ieee_ets;
>   3359				int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
>   3360	
>   3361				ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame);
>   3362			}
>   3363	
>   3364			if (adapter->ixgbe_ieee_pfc) {
>   3365				struct ieee_pfc *pfc = adapter->ixgbe_ieee_pfc;
>   3366				u8 *prio_tc = adapter->ixgbe_ieee_ets->prio_tc;
>                                               ^^^^^^^^^^^^^^^^^^^^^^^^^
> New dereference.
> 
>   3367	
>   3368				ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en,
> 
> regards,
> dan carpenter
> 

Actually both structures ixgbe_ieee_ets and ixgbe_ieee_pfc get initialized
at the same time. So no null dereference will occur. That said this snippit
should be fixed.

I'll send a patch to JeffK. Thanks for the catch Dan.

.John

^ permalink raw reply

* Re: ixgbe: fixup hard dependencies on supporting 8 traffic classes
From: Dan Carpenter @ 2011-10-12  6:35 UTC (permalink / raw)
  To: john.r.fastabend; +Cc: e1000-devel, netdev

Hello John Fastabend,

This is a semi-automatic email about new static checker warnings.

The patch 32701dc2e616: "ixgbe: fixup hard dependencies on supporting
8 traffic classes" from Sep 27, 2011, leads to the following Smatch
complaint:

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +3366 ixgbe_configure_dcb()
	 error: we previously assumed 'adapter->ixgbe_ieee_ets' could be null (see line 3357)

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
  3356	
  3357			if (adapter->ixgbe_ieee_ets) {
                            ^^^^^^^^^^^^^^^^^^^^^^^
Null check.

  3358				struct ieee_ets *ets = adapter->ixgbe_ieee_ets;
  3359				int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
  3360	
  3361				ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame);
  3362			}
  3363	
  3364			if (adapter->ixgbe_ieee_pfc) {
  3365				struct ieee_pfc *pfc = adapter->ixgbe_ieee_pfc;
  3366				u8 *prio_tc = adapter->ixgbe_ieee_ets->prio_tc;
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^
New dereference.

  3367	
  3368				ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en,

regards,
dan carpenter


------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a
definitive record of customers, application performance, security
threats, fraudulent activity and more. Splunk takes this data and makes
sense of it. Business sense. IT sense. Common sense.
http://p.sf.net/sfu/splunk-d2d-oct
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* Re: [PATCH v3] net-netlink: Add a new attribute to expose TOS values via netlink
From: Eric Dumazet @ 2011-10-12  4:31 UTC (permalink / raw)
  To: MuraliRaja Muniraju
  Cc: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, linux-kernel, netdev
In-Reply-To: <CAP3iWTQXHwzw-qUYVfT--uNv4pNZnu0ROJnF7B1VLeZBbrfdqw@mail.gmail.com>

Le mardi 11 octobre 2011 à 21:16 -0700, MuraliRaja Muniraju a écrit :
> Eric,
>      I think it would be useful to expose the values this way.
>      I shall make the changes to add TCLASS for ipv6 in the description.
> 
>      Regarding the TIME_WAIT state, I think it would be better of not
> exposing the values because there would hardly be anything to transmit
> during this time.
> 

My remark had nothing to do with your patch actually :

We dont store TOS/TCLASS on TIME_WAIT sockets, so you cannot report
value in inet_diag.

But we do send packets on behalf of TIME_WAIT sockets ;)

Think about ACK messages. They probably are sent with a 0 TOS/TCLASS
field... I am not sure its a problem or not.

^ permalink raw reply

* Re: [PATCH v3] net-netlink: Add a new attribute to expose TOS values via netlink
From: MuraliRaja Muniraju @ 2011-10-12  4:16 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Patrick McHardy, linux-kernel, netdev
In-Reply-To: <1318387734.3686.2.camel@edumazet-laptop>

Eric,
     I think it would be useful to expose the values this way.
     I shall make the changes to add TCLASS for ipv6 in the description.

     Regarding the TIME_WAIT state, I think it would be better of not
exposing the values because there would hardly be anything to transmit
during this time.

Thanks,
Murali

On Tue, Oct 11, 2011 at 7:48 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le mardi 11 octobre 2011 à 18:28 -0700, Muraliraja Muniraju a écrit :
>> From: Murali Raja <muralira@google.com>
>>
>> This patch exposes the tos value for the TCP sockets when the TOS flag
>> is requested in the ext_flags for the inet_diag request. This would mainly be
>> used to expose TOS values for both for TCP and UDP sockets. Currently it is
>> supported for TCP. When netlink support for UDP would be added the support
>> to expose the TOS values would alse be done.
>>
>
> You could mention TCLASS support for IPv6
>
>> Signed-off-by: Murali Raja <muralira@google.com>
>> ---
>> Changelog since v2:
>> - Adding support for IPV6 class and using right API's
>> Changelog since v1:
>> - Removing reserved field
>>
>>  include/linux/inet_diag.h |    9 ++++++++-
>>  net/ipv4/inet_diag.c      |    5 +++++
>>  2 files changed, 13 insertions(+), 1 deletions(-)
>>
>> diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
>> index bc8c490..e36093d 100644
>> --- a/include/linux/inet_diag.h
>> +++ b/include/linux/inet_diag.h
>> @@ -97,9 +97,10 @@ enum {
>>       INET_DIAG_INFO,
>>       INET_DIAG_VEGASINFO,
>>       INET_DIAG_CONG,
>> +     INET_DIAG_TOS,
>>  };
>>
>> -#define INET_DIAG_MAX INET_DIAG_CONG
>> +#define INET_DIAG_MAX INET_DIAG_TOS
>>
>>
>>  /* INET_DIAG_MEM */
>> @@ -120,6 +121,12 @@ struct tcpvegas_info {
>>       __u32   tcpv_minrtt;
>>  };
>>
>> +/* INET_DIAG_TOS */
>> +
>> +struct inet_diag_tos {
>> +     __u8    idiag_tos;
>> +};
>
> Are you sure its still needed ?
>
> I am now wondering what is done in TIME_WAIT state.
>
>
>



-- 
Thanks,
Murali

^ permalink raw reply

* Re: [PATCH] bonding: L2L3 xmit doesn't support IPv6
From: Eric Dumazet @ 2011-10-12  4:06 UTC (permalink / raw)
  To: Yinglin Sun; +Cc: Andy Gospodarek, Jay Vosburgh, netdev, John Eaglesham
In-Reply-To: <CAN17JHVsgRqkOgeJ0+vvQe3kN1W0ue0vKHa3uebFHa9oH2ngXA@mail.gmail.com>

Le mardi 11 octobre 2011 à 20:39 -0700, Yinglin Sun a écrit :
> On Tue, Oct 11, 2011 at 7:51 PM, Andy Gospodarek <andy@greyhouse.net> wrote:
> >
> >        if (skb->protocol == htons(ETH_P_IP)) {
> > +               struct iphdr *iph = ip_hdr(skb);
> > +               __be16 *layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
> >                if (!ip_is_fragment(iph) &&
> >                    (iph->protocol == IPPROTO_TCP ||
> >                     iph->protocol == IPPROTO_UDP)) {
> > @@ -3398,7 +3407,18 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
> >                }
> >                return (layer4_xor ^
> >                        ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
> > -
> > +       } else if (skb->protocol == htons(ETH_P_IPV6)) {
> > +               struct ipv6hdr *ipv6h = ipv6_hdr(skb);
> > +               __be16 *layer4hdrv6 = (__be16 *)((u8 *)ipv6h + sizeof(*ipv6h));
> > +               if (ipv6h->nexthdr == IPPROTO_TCP || ipv6h->nexthdr == IPPROTO_UDP) {
> 
> Does this work if this is a fragmentation packet? and if
> ipv6h->nexthdr is not IPPROTO_TCP/IPPROTO_UDP, it doesn't mean this is
> not TCP/UDP packet. We need to go through the extension header chain
> and look at the last one. It's likely there are some other extension
> headers before L4 header.
> 

Its a best effort.

If first header is not IPPROTO_TCP/UDP, I am not sure its wise to spend
time in hope to find layer4 info (missing anyway in fragments)

By the way I see no bound checking on SKB head : malicious packet could
make bond_xmit_hash_policy_l34() access unitialized memory.

We have same 'fastpath' in __skb_get_rxhash()

^ permalink raw reply

* [PATCH] flexcan: fix flood of irq's after error condition triggered
From: Reuben Dowle @ 2011-10-12  3:41 UTC (permalink / raw)
  To: netdev

On my i.MX28 development kit board, I am able to use the flexcan module without problems, until I introduce a bus error by disconnecting the cable. As soon as this is done, the cpu usage goes to 100% percent due to the irq handler being called constantly.

It seems this error can be traced to the irq handler not clearing the irq flags. The flexcan driver is enabling several interrupts, but only clearing one of them.

>From the user manual:

25.6.8 Error and Status Register (HW_CAN_ESR)
This register reflects various error conditions, some general status of the device and it is
the source of four interrupts to the ARM. The reported error conditions are those that
occurred since the last time the ARM read this register. The ARM read action clears bits.
Bits are status bits. Most bits in this register are read-only, except TWRN_INT, RWRN_INT,
BOFF_INT, WAK_INT and ERR_INT, which are interrupt flags that can be cleared by
writing 1 to them (writing 0 has no effect).

This is ambiguous. It says that reading clears the bits, but then says that some of the bits can be cleared by writing 1 to them. In practice it seems that all the ones listed above as being able to be cleared by writing 1 to them MUST be cleared by writing 1 to them.

Signed-off-by: Reuben Dowle <reuben.dowle@navico.com>
---
 drivers/net/can/flexcan.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 1767811..9bcc2e2 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -553,7 +553,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 
        reg_iflag1 = readl(&regs->iflag1);
        reg_esr = readl(&regs->esr);
-       writel(FLEXCAN_ESR_ERR_INT, &regs->esr);        /* ACK err IRQ */
+       writel(reg_esr & (FLEXCAN_ESR_TWRN_INT|FLEXCAN_ESR_RWRN_INT|FLEXCAN_ESR_BOFF_INT|FLEXCAN_ESR_ERR_INT), &regs->esr);     /* ACK err IRQ */
 
        /*
         * schedule NAPI in case of:

^ permalink raw reply related

* Re: [PATCH] bonding: L2L3 xmit doesn't support IPv6
From: Yinglin Sun @ 2011-10-12  3:39 UTC (permalink / raw)
  To: Andy Gospodarek; +Cc: Jay Vosburgh, netdev, John Eaglesham
In-Reply-To: <20111012025137.GB20605@gospo.rdu.redhat.com>

On Tue, Oct 11, 2011 at 7:51 PM, Andy Gospodarek <andy@greyhouse.net> wrote:
> On Tue, Oct 11, 2011 at 08:58:59AM -0700, Jay Vosburgh wrote:
>> Andy Gospodarek <andy@greyhouse.net> wrote:
> [...]
>> >
>> >There have been some attempts to add support for ipv6 hashing this in
>> >the past, but none have been committed.  The best one I had seen was one
>> >that did some extensive testing one a wide variety of ipv6 traffic and
>> >it showed nice traffic distribution.  I'm not sure if it was ever posted
>> >upstream, so I will see if I can dig it up.
>> >
>> >Can you quantify how traffic was distributed with this algorithm?
>>
>>       As I recall, the IPv6 issues had to do with the "layer3+4" hash,
>> because the IPv6 TCP or UDP port numbers can be harder to get at than in
>> IPv4 (which typically has a fixed size header).  The above is just for
>> layer 2, so it only hits the IPv6 addresses, which don't move around.
>>
>>       That said, I believe that many IPv6 addresses are derived from
>> the MAC address, the autoconf addresses in particular, so s6_addr32[3]
>> may not show a lot more variation than just the MAC address.  I don't
>> know for sure though, since I haven't tested it.
>>
>>       I don't recall seeing the patch you mention, Andy, that checks
>> ipv6 traffic; can you post it?
>>
>
> I found the patch, cleaned it up, and compile tested it against
> net-next.  I traded some emails with John Eaglesham (cc'd) earlier this
> year and though he planned to post it, I never followed up.
>
> His comments about this patch were as follows:
>
> "I've attached my patch for IPv6 transmit hashing for the nic bonding
> driver.
>
> "The algorithm I chose is based on 273,913 IPv6 client addresses I
> gathered from webservers and ran through a test program that implemented
> several algorithms. This algorithm provided the most even distribution
> while using the fewest instructions.
>
> "I've tested this on 2.6.39-rc4 and a similar patch to 2.6.18 (from
> RHEL5 5.4.3) and it has performed as expected in both cases.
>
> "Please let me know if you have any comments, otherwise I suppose the
> next step is to propose the patch to LKML."
>
> I would suggest we use this.  John or I could write an official
> changelog and post this in it's own thread if it looks good to others.
>
> ---
>  drivers/net/bonding/bond_main.c |   30 +++++++++++++++++++++++++-----
>  1 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 6191e63..335cb67 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -3368,11 +3368,20 @@ static struct notifier_block bond_inetaddr_notifier = {
>  static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
>  {
>        struct ethhdr *data = (struct ethhdr *)skb->data;
> -       struct iphdr *iph = ip_hdr(skb);
>
>        if (skb->protocol == htons(ETH_P_IP)) {
> +               struct iphdr *iph = ip_hdr(skb);
>                return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
>                        (data->h_dest[5] ^ data->h_source[5])) % count;
> +       } else if (skb->protocol == htons(ETH_P_IPV6)) {
> +               struct ipv6hdr *ipv6h = ipv6_hdr(skb);
> +               u32 v6hash = (
> +                       (ipv6h->saddr.s6_addr32[1] ^ ipv6h->daddr.s6_addr32[1]) ^
> +                       (ipv6h->saddr.s6_addr32[2] ^ ipv6h->daddr.s6_addr32[2]) ^
> +                       (ipv6h->saddr.s6_addr32[3] ^ ipv6h->daddr.s6_addr32[3])
> +               );
> +               v6hash = (v6hash >> 16) ^ (v6hash >> 8) ^ v6hash;
> +               return (v6hash ^ data->h_dest[5] ^ data->h_source[5]) % count;
>        }
>
>        return (data->h_dest[5] ^ data->h_source[5]) % count;
> @@ -3386,11 +3395,11 @@ static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count)
>  static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
>  {
>        struct ethhdr *data = (struct ethhdr *)skb->data;
> -       struct iphdr *iph = ip_hdr(skb);
> -       __be16 *layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
> -       int layer4_xor = 0;
> +       u32 layer4_xor = 0;
>
>        if (skb->protocol == htons(ETH_P_IP)) {
> +               struct iphdr *iph = ip_hdr(skb);
> +               __be16 *layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
>                if (!ip_is_fragment(iph) &&
>                    (iph->protocol == IPPROTO_TCP ||
>                     iph->protocol == IPPROTO_UDP)) {
> @@ -3398,7 +3407,18 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count)
>                }
>                return (layer4_xor ^
>                        ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
> -
> +       } else if (skb->protocol == htons(ETH_P_IPV6)) {
> +               struct ipv6hdr *ipv6h = ipv6_hdr(skb);
> +               __be16 *layer4hdrv6 = (__be16 *)((u8 *)ipv6h + sizeof(*ipv6h));
> +               if (ipv6h->nexthdr == IPPROTO_TCP || ipv6h->nexthdr == IPPROTO_UDP) {

Does this work if this is a fragmentation packet? and if
ipv6h->nexthdr is not IPPROTO_TCP/IPPROTO_UDP, it doesn't mean this is
not TCP/UDP packet. We need to go through the extension header chain
and look at the last one. It's likely there are some other extension
headers before L4 header.

Yinglin

> +                       layer4_xor = (*layer4hdrv6 ^ *(layer4hdrv6 + 1));
> +               }
> +               layer4_xor ^= (
> +                       (ipv6h->saddr.s6_addr32[1] ^ ipv6h->daddr.s6_addr32[1]) ^
> +                       (ipv6h->saddr.s6_addr32[2] ^ ipv6h->daddr.s6_addr32[2]) ^
> +                       (ipv6h->saddr.s6_addr32[3] ^ ipv6h->daddr.s6_addr32[3])
> +               );
> +               return ((layer4_xor >> 16) ^ (layer4_xor >> 8) ^ layer4_xor) % count;
>        }
>
>        return (data->h_dest[5] ^ data->h_source[5]) % count;
> --
> 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

* [net-next 12/12] igb: Version bump.
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Carolyn Wyborny, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Carolyn Wyborny <carolyn.wyborny@intel.com>

This change updates the driver version to 3.2.10.

Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 6fdf2e0..8ba0889 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -57,8 +57,8 @@
 #include "igb.h"
 
 #define MAJ 3
-#define MIN 0
-#define BUILD 6
+#define MIN 2
+#define BUILD 10
 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
 __stringify(BUILD) "-k"
 char igb_driver_name[] = "igb";
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 09/12] igb: fix static function warnings reported by sparse
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Emil Tantilov, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Emil Tantilov <emil.s.tantilov@intel.com>

igb_update/validate_nvm_checksum_with_offset() should be static.
Also removes unneeded protypes for the above functions.

Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by:  Aaron Brown  <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/e1000_82575.c |    9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index c0857bd..3771bd2 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -66,10 +66,6 @@ static s32  igb_set_pcie_completion_timeout(struct e1000_hw *hw);
 static s32  igb_reset_mdicnfg_82580(struct e1000_hw *hw);
 static s32  igb_validate_nvm_checksum_82580(struct e1000_hw *hw);
 static s32  igb_update_nvm_checksum_82580(struct e1000_hw *hw);
-static s32  igb_update_nvm_checksum_with_offset(struct e1000_hw *hw,
-						u16 offset);
-static s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw,
-						u16 offset);
 static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw);
 static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw);
 static const u16 e1000_82580_rxpbs_table[] =
@@ -1820,7 +1816,8 @@ u16 igb_rxpbs_adjust_82580(u32 data)
  *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
  *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
  **/
-s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
+static s32 igb_validate_nvm_checksum_with_offset(struct e1000_hw *hw,
+						 u16 offset)
 {
 	s32 ret_val = 0;
 	u16 checksum = 0;
@@ -1855,7 +1852,7 @@ out:
  *  up to the checksum.  Then calculates the EEPROM checksum and writes the
  *  value to the EEPROM.
  **/
-s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
+static s32 igb_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 offset)
 {
 	s32 ret_val;
 	u16 checksum = 0;
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 11/12] igb: Loopback funtionality supports for i350 devices
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Akeem G. Abodunrin, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: "Akeem G. Abodunrin" <akeem.g.abodunrin@intel.com>

This patch adds VMDq loopback pf support for i350 devices. The patch is
necessary since the register that enabled loopback was moved and renamed
from DTXSWC to TXSWC.

Signed-off-by: "Akeem G. Abodunrin" <akeem.g.abodunrin@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/e1000_82575.c |   29 ++++++++++++++++++++-----
 drivers/net/ethernet/intel/igb/e1000_regs.h  |    1 +
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 3771bd2..6580cea 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -1580,14 +1580,31 @@ void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
  **/
 void igb_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
 {
-	u32 dtxswc = rd32(E1000_DTXSWC);
+	u32 dtxswc;
+
+	switch (hw->mac.type) {
+	case e1000_82576:
+		dtxswc = rd32(E1000_DTXSWC);
+		if (enable)
+			dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+		else
+			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+		wr32(E1000_DTXSWC, dtxswc);
+		break;
+	case e1000_i350:
+		dtxswc = rd32(E1000_TXSWC);
+		if (enable)
+			dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+		else
+			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+		wr32(E1000_TXSWC, dtxswc);
+		break;
+	default:
+		/* Currently no other hardware supports loopback */
+		break;
+	}
 
-	if (enable)
-		dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
-	else
-		dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
 
-	wr32(E1000_DTXSWC, dtxswc);
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 0990f6d..0a860bc 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -318,6 +318,7 @@
 #define E1000_RPLOLR    0x05AF0 /* Replication Offload - RW */
 #define E1000_UTA       0x0A000 /* Unicast Table Array - RW */
 #define E1000_IOVTCL    0x05BBC /* IOV Control Register */
+#define E1000_TXSWC     0x05ACC /* Tx Switch Control */
 /* These act per VF so an array friendly macro is used */
 #define E1000_P2VMAILBOX(_n)   (0x00C00 + (4 * (_n)))
 #define E1000_VMBMEM(_n)       (0x00800 + (64 * (_n)))
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 07/12] igb: Drop unnecessary write of E1000_IMS from igb_msix_other
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Since we mask interrupts in EIMS not in IMS there is no need to re-enable
mask bits in that register.  As such we can remove the write to IMS from
the end of igb_msix_other.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by:  Aaron Brown  <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index ff4a335..43caf84 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -4696,12 +4696,6 @@ static irqreturn_t igb_msix_other(int irq, void *data)
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
-	if (adapter->vfs_allocated_count)
-		wr32(E1000_IMS, E1000_IMS_LSC |
-				E1000_IMS_VMMB |
-				E1000_IMS_DOUTSYNC);
-	else
-		wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC);
 	wr32(E1000_EIMS, adapter->eims_other);
 
 	return IRQ_HANDLED;
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 10/12] igb: move DMA Coalescing feature code into separate function.
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Jacob Sowles, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Jacob Sowles <jacob.r.sowles@intel.com>

DMA Coalescing code needs to be executed during reset, if enabled.  Moved
code to separate function and added a call to it in igb_reset.

Signed-off-by: Jacob Sowles <jacob.r.sowles@intel.com>
Tested-by:  Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |   66 +++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 7c6e526..6fdf2e0 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6907,4 +6907,70 @@ static void igb_vmm_control(struct igb_adapter *adapter)
 	}
 }
 
+static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 dmac_thr;
+	u16 hwm;
+
+	if (hw->mac.type > e1000_82580) {
+		if (adapter->flags & IGB_FLAG_DMAC) {
+			u32 reg;
+
+			/* force threshold to 0. */
+			wr32(E1000_DMCTXTH, 0);
+
+			/*
+			 * DMA Coalescing high water mark needs to be higher
+			 * than the RX threshold. set hwm to PBA -  2 * max
+			 * frame size
+			 */
+			hwm = pba - (2 * adapter->max_frame_size);
+			reg = rd32(E1000_DMACR);
+			reg &= ~E1000_DMACR_DMACTHR_MASK;
+			dmac_thr = pba - 4;
+
+			reg |= ((dmac_thr << E1000_DMACR_DMACTHR_SHIFT)
+				& E1000_DMACR_DMACTHR_MASK);
+
+			/* transition to L0x or L1 if available..*/
+			reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
+
+			/* watchdog timer= +-1000 usec in 32usec intervals */
+			reg |= (1000 >> 5);
+			wr32(E1000_DMACR, reg);
+
+			/*
+			 * no lower threshold to disable
+			 * coalescing(smart fifb)-UTRESH=0
+			 */
+			wr32(E1000_DMCRTRH, 0);
+			wr32(E1000_FCRTC, hwm);
+
+			reg = (IGB_DMCTLX_DCFLUSH_DIS | 0x4);
+
+			wr32(E1000_DMCTLX, reg);
+
+			/*
+			 * free space in tx packet buffer to wake from
+			 * DMA coal
+			 */
+			wr32(E1000_DMCTXTH, (IGB_MIN_TXPBSIZE -
+			     (IGB_TX_BUF_4096 + adapter->max_frame_size)) >> 6);
+
+			/*
+			 * make low power state decision controlled
+			 * by DMA coal
+			 */
+			reg = rd32(E1000_PCIEMISC);
+			reg &= ~E1000_PCIEMISC_LX_DECISION;
+			wr32(E1000_PCIEMISC, reg);
+		} /* endif adapter->dmac is not disabled */
+	} else if (hw->mac.type == e1000_82580) {
+		u32 reg = rd32(E1000_PCIEMISC);
+		wr32(E1000_PCIEMISC, reg & ~E1000_PCIEMISC_LX_DECISION);
+		wr32(E1000_DMACR, 0);
+	}
+}
+
 /* igb_main.c */
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 06/12] igb: Fix features that are currently 82580 only and should also be i350
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

This change allows support for per packet timesync and global device reset
on the i350 adapter.  These features were supported on both 82580 and i350
however it looks like several checks where not updated and as such the i350
support was not enabled.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by:  Aaron Brown  <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |   15 ++++++---------
 1 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 29ec64f..ff4a335 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -563,7 +563,7 @@ static cycle_t igb_read_clock(const struct cyclecounter *tc)
 	 * the lowest register is SYSTIMR instead of SYSTIML.  However we never
 	 * adjusted TIMINCA so SYSTIMR will just read as all 0s so ignore it.
 	 */
-	if (hw->mac.type == e1000_82580) {
+	if (hw->mac.type >= e1000_82580) {
 		stamp = rd32(E1000_SYSTIMR) >> 8;
 		shift = IGB_82580_TSYNC_SHIFT;
 	}
@@ -1320,7 +1320,7 @@ static void igb_irq_enable(struct igb_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 
 	if (adapter->msix_entries) {
-		u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC;
+		u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_DRSTA;
 		u32 regval = rd32(E1000_EIAC);
 		wr32(E1000_EIAC, regval | adapter->eims_enable_mask);
 		regval = rd32(E1000_EIAM);
@@ -1330,9 +1330,6 @@ static void igb_irq_enable(struct igb_adapter *adapter)
 			wr32(E1000_MBVFIMR, 0xFF);
 			ims |= E1000_IMS_VMMB;
 		}
-		if (adapter->hw.mac.type == e1000_82580)
-			ims |= E1000_IMS_DRSTA;
-
 		wr32(E1000_IMS, ims);
 	} else {
 		wr32(E1000_IMS, IMS_ENABLE_MASK |
@@ -3042,7 +3039,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
 	srrctl |= (PAGE_SIZE / 2) >> E1000_SRRCTL_BSIZEPKT_SHIFT;
 #endif
 	srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
-	if (hw->mac.type == e1000_82580)
+	if (hw->mac.type >= e1000_82580)
 		srrctl |= E1000_SRRCTL_TIMESTAMP;
 	/* Only set Drop Enable if we are supporting multiple queues */
 	if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1)
@@ -4393,7 +4390,7 @@ static void igb_tx_timeout(struct net_device *netdev)
 	/* Do the reset outside of interrupt context */
 	adapter->tx_timeout_count++;
 
-	if (hw->mac.type == e1000_82580)
+	if (hw->mac.type >= e1000_82580)
 		hw->dev_spec._82575.global_device_reset = true;
 
 	schedule_work(&adapter->reset_task);
@@ -5511,7 +5508,7 @@ static void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
 	 * The 82580 starts with 1ns at bit 0 in RX/TXSTMPL, shift this up to
 	 * 24 to match clock shift we setup earlier.
 	 */
-	if (adapter->hw.mac.type == e1000_82580)
+	if (adapter->hw.mac.type >= e1000_82580)
 		regval <<= IGB_82580_TSYNC_SHIFT;
 
 	ns = timecounter_cyc2time(&adapter->clock, regval);
@@ -6206,7 +6203,7 @@ static int igb_hwtstamp_ioctl(struct net_device *netdev,
 	 * timestamped, so enable timestamping in all packets as
 	 * long as one rx filter was configured.
 	 */
-	if ((hw->mac.type == e1000_82580) && tsync_rx_ctl) {
+	if ((hw->mac.type >= e1000_82580) && tsync_rx_ctl) {
 		tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
 		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
 	}
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 08/12] igb: Add workaround for byte swapped VLAN on i350 local traffic
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

On i350 when traffic is looped back from a VF to the PF the value is byte
swapped from the normal format.  In order to address this we need to add a
flag indicating that the ring will need to byte swap the loopback packets
prior to processing them.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by:  Aaron Brown  <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/e1000_defines.h |    1 +
 drivers/net/ethernet/intel/igb/igb.h           |    1 +
 drivers/net/ethernet/intel/igb/igb_main.c      |   29 +++++++++++++++++++-----
 3 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 68558be..f5fc572 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -85,6 +85,7 @@
 #define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
 #define E1000_RXD_STAT_TS       0x10000 /* Pkt was time stamped */
 
+#define E1000_RXDEXT_STATERR_LB    0x00040000
 #define E1000_RXDEXT_STATERR_CE    0x01000000
 #define E1000_RXDEXT_STATERR_SE    0x02000000
 #define E1000_RXDEXT_STATERR_SEQ   0x04000000
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 5def94c..e6e770d 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -243,6 +243,7 @@ struct igb_ring {
 
 enum e1000_ring_flags_t {
 	IGB_RING_FLAG_RX_SCTP_CSUM,
+	IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
 	IGB_RING_FLAG_TX_CTX_IDX,
 	IGB_RING_FLAG_TX_DETECT_HANG
 };
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 43caf84..7c6e526 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -712,6 +712,11 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
 		/* set flag indicating ring supports SCTP checksum offload */
 		if (adapter->hw.mac.type >= e1000_82576)
 			set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags);
+
+		/* On i350, loopback VLAN packets have the tag byte-swapped. */
+		if (adapter->hw.mac.type == e1000_i350)
+			set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags);
+
 		adapter->rx_ring[i] = ring;
 	}
 
@@ -5794,6 +5799,23 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector,
 
 	igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
 }
+
+static void igb_rx_vlan(struct igb_ring *ring,
+			union e1000_adv_rx_desc *rx_desc,
+			struct sk_buff *skb)
+{
+	if (igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
+		u16 vid;
+		if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) &&
+		    test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags))
+			vid = be16_to_cpu(rx_desc->wb.upper.vlan);
+		else
+			vid = le16_to_cpu(rx_desc->wb.upper.vlan);
+
+		__vlan_hwaccel_put_tag(skb, vid);
+	}
+}
+
 static inline u16 igb_get_hlen(union e1000_adv_rx_desc *rx_desc)
 {
 	/* HW will not DMA in data larger than the given buffer, even if it
@@ -5890,12 +5912,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, int budget)
 		igb_rx_hwtstamp(q_vector, rx_desc, skb);
 		igb_rx_hash(rx_ring, rx_desc, skb);
 		igb_rx_checksum(rx_ring, rx_desc, skb);
-
-		if (igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
-			u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan);
-
-			__vlan_hwaccel_put_tag(skb, vid);
-		}
+		igb_rx_vlan(rx_ring, rx_desc, skb);
 
 		total_bytes += skb->len;
 		total_packets++;
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 03/12] ixgbe: Correct check for change in FCoE priority
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Mark Rustad, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Mark Rustad <mark.d.rustad@intel.com>

Correct a check for change in FCoE priority when IEEE mode DCB is in use.
In IEEE mode a different function has to be used to get the FCoE priority
mask. Also, the check for the mask assumed that only one priority was set.
In case there should be more than one, check just the bit.

These changes help avoid link flapping issues that can come up when IEEE
DCB is in use.

Signed-off-by: Mark Rustad <mark.d.rustad@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index be66bb6..3631d63 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -318,7 +318,15 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
 			      .selector = DCB_APP_IDTYPE_ETHTYPE,
 			      .protocol = ETH_P_FCOE,
 			     };
-	u8 up = dcb_getapp(netdev, &app);
+	u8 up;
+
+	/* In IEEE mode, use the IEEE Ethertype selector value */
+	if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) {
+		app.selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE;
+		up = dcb_ieee_getapp_mask(netdev, &app);
+	} else {
+		up = dcb_getapp(netdev, &app);
+	}
 #endif
 
 	/* Fail command if not in CEE mode */
@@ -331,7 +339,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
 		return DCB_NO_HW_CHG;
 
 #ifdef IXGBE_FCOE
-	if (up && (up != (1 << adapter->fcoe.up)))
+	if (up && !(up & (1 << adapter->fcoe.up)))
 		adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
 
 	/*
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 04/12] igb: avoid unnecessarily creating a local copy of the q_vector
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

This is mostly a drop of unnecessary pointer defines for q_vector when we
don't have issues with line width and don't have multiple references to
the pointer.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by:  Aaron Brown  <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |   46 ++++++++++------------------
 1 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index b3a2e3d..2768c35 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1270,11 +1270,9 @@ static void igb_free_irq(struct igb_adapter *adapter)
 
 		free_irq(adapter->msix_entries[vector++].vector, adapter);
 
-		for (i = 0; i < adapter->num_q_vectors; i++) {
-			struct igb_q_vector *q_vector = adapter->q_vector[i];
+		for (i = 0; i < adapter->num_q_vectors; i++)
 			free_irq(adapter->msix_entries[vector++].vector,
-			         q_vector);
-		}
+				 adapter->q_vector[i]);
 	} else {
 		free_irq(adapter->pdev->irq, adapter);
 	}
@@ -1476,10 +1474,9 @@ int igb_up(struct igb_adapter *adapter)
 
 	clear_bit(__IGB_DOWN, &adapter->state);
 
-	for (i = 0; i < adapter->num_q_vectors; i++) {
-		struct igb_q_vector *q_vector = adapter->q_vector[i];
-		napi_enable(&q_vector->napi);
-	}
+	for (i = 0; i < adapter->num_q_vectors; i++)
+		napi_enable(&(adapter->q_vector[i]->napi));
+
 	if (adapter->msix_entries)
 		igb_configure_msix(adapter);
 	else
@@ -1531,10 +1528,8 @@ void igb_down(struct igb_adapter *adapter)
 	wrfl();
 	msleep(10);
 
-	for (i = 0; i < adapter->num_q_vectors; i++) {
-		struct igb_q_vector *q_vector = adapter->q_vector[i];
-		napi_disable(&q_vector->napi);
-	}
+	for (i = 0; i < adapter->num_q_vectors; i++)
+		napi_disable(&(adapter->q_vector[i]->napi));
 
 	igb_irq_disable(adapter);
 
@@ -2497,10 +2492,8 @@ static int igb_open(struct net_device *netdev)
 	/* From here on the code is the same as igb_up() */
 	clear_bit(__IGB_DOWN, &adapter->state);
 
-	for (i = 0; i < adapter->num_q_vectors; i++) {
-		struct igb_q_vector *q_vector = adapter->q_vector[i];
-		napi_enable(&q_vector->napi);
-	}
+	for (i = 0; i < adapter->num_q_vectors; i++)
+		napi_enable(&(adapter->q_vector[i]->napi));
 
 	/* Clear any pending interrupts. */
 	rd32(E1000_ICR);
@@ -3699,10 +3692,8 @@ static void igb_watchdog_task(struct work_struct *work)
 	/* Cause software interrupt to ensure rx ring is cleaned */
 	if (adapter->msix_entries) {
 		u32 eics = 0;
-		for (i = 0; i < adapter->num_q_vectors; i++) {
-			struct igb_q_vector *q_vector = adapter->q_vector[i];
-			eics |= q_vector->eims_value;
-		}
+		for (i = 0; i < adapter->num_q_vectors; i++)
+			eics |= adapter->q_vector[i]->eims_value;
 		wr32(E1000_EICS, eics);
 	} else {
 		wr32(E1000_ICS, E1000_ICS_RXDMT0);
@@ -6601,18 +6592,15 @@ static void igb_netpoll(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	struct igb_q_vector *q_vector;
 	int i;
 
-	if (!adapter->msix_entries) {
-		struct igb_q_vector *q_vector = adapter->q_vector[0];
-		igb_irq_disable(adapter);
-		napi_schedule(&q_vector->napi);
-		return;
-	}
-
 	for (i = 0; i < adapter->num_q_vectors; i++) {
-		struct igb_q_vector *q_vector = adapter->q_vector[i];
-		wr32(E1000_EIMC, q_vector->eims_value);
+		q_vector = adapter->q_vector[i];
+		if (adapter->msix_entries)
+			wr32(E1000_EIMC, q_vector->eims_value);
+		else
+			igb_irq_disable(adapter);
 		napi_schedule(&q_vector->napi);
 	}
 }
-- 
1.7.6.4

^ permalink raw reply related

* [net-next 05/12] igb: Make certain one vector is always assigned in igb_request_irq
From: Jeff Kirsher @ 2011-10-12  3:38 UTC (permalink / raw)
  To: davem; +Cc: Alexander Duyck, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1318390708-12232-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

This change makes certain that one interrupt is always initialized in
igb_request_irq.  In addition we drop the use of adapter->pdev and
instead just call pdev since we made a local copy of the pointer earlier in
the function.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by:  Aaron Brown  <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 2768c35..29ec64f 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1215,7 +1215,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
 			goto request_done;
 		/* fall back to MSI */
 		igb_clear_interrupt_scheme(adapter);
-		if (!pci_enable_msi(adapter->pdev))
+		if (!pci_enable_msi(pdev))
 			adapter->flags |= IGB_FLAG_HAS_MSI;
 		igb_free_all_tx_resources(adapter);
 		igb_free_all_rx_resources(adapter);
@@ -1237,12 +1237,12 @@ static int igb_request_irq(struct igb_adapter *adapter)
 		}
 		igb_setup_all_tx_resources(adapter);
 		igb_setup_all_rx_resources(adapter);
-	} else {
-		igb_assign_vector(adapter->q_vector[0], 0);
 	}
 
+	igb_assign_vector(adapter->q_vector[0], 0);
+
 	if (adapter->flags & IGB_FLAG_HAS_MSI) {
-		err = request_irq(adapter->pdev->irq, igb_intr_msi, 0,
+		err = request_irq(pdev->irq, igb_intr_msi, 0,
 				  netdev->name, adapter);
 		if (!err)
 			goto request_done;
@@ -1252,11 +1252,11 @@ static int igb_request_irq(struct igb_adapter *adapter)
 		adapter->flags &= ~IGB_FLAG_HAS_MSI;
 	}
 
-	err = request_irq(adapter->pdev->irq, igb_intr, IRQF_SHARED,
+	err = request_irq(pdev->irq, igb_intr, IRQF_SHARED,
 			  netdev->name, adapter);
 
 	if (err)
-		dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n",
+		dev_err(&pdev->dev, "Error %d getting interrupt\n",
 			err);
 
 request_done:
-- 
1.7.6.4

^ 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