Netdev List
 help / color / mirror / Atom feed
* [net-next PATCH 2/3] qlge: Size RX buffers based on MTU (Add API).
From: Ron Mercer @ 2009-10-16 20:15 UTC (permalink / raw)
  To: davem; +Cc: netdev, ron.mercer
In-Reply-To: <1255724136-27264-1-git-send-email-ron.mercer@qlogic.com>

Change RX large buffer size based on MTU. If pages are larger
than the MTU the page is divided up into multiple chunks and passed to
the hardware.  When pages are smaller than MTU each RX buffer can
contain be comprised of up to 2 pages.

Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
 drivers/net/qlge/qlge_main.c |  124 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 124 insertions(+), 0 deletions(-)

diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 9eefb11..5c0dbda 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1025,6 +1025,11 @@ end:
 	return status;
 }
 
+static inline unsigned int ql_lbq_block_size(struct ql_adapter *qdev)
+{
+	return PAGE_SIZE << qdev->lbq_buf_order;
+}
+
 /* Get the next large buffer. */
 static struct bq_desc *ql_get_curr_lbuf(struct rx_ring *rx_ring)
 {
@@ -1036,6 +1041,28 @@ static struct bq_desc *ql_get_curr_lbuf(struct rx_ring *rx_ring)
 	return lbq_desc;
 }
 
+static struct bq_desc *ql_get_curr_lchunk(struct ql_adapter *qdev,
+		struct rx_ring *rx_ring)
+{
+	struct bq_desc *lbq_desc = ql_get_curr_lbuf(rx_ring);
+
+	pci_dma_sync_single_for_cpu(qdev->pdev,
+					pci_unmap_addr(lbq_desc, mapaddr),
+				    rx_ring->lbq_buf_size,
+					PCI_DMA_FROMDEVICE);
+
+	/* If it's the last chunk of our master page then
+	 * we unmap it.
+	 */
+	if ((lbq_desc->p.pg_chunk.offset + rx_ring->lbq_buf_size)
+					== ql_lbq_block_size(qdev))
+		pci_unmap_page(qdev->pdev,
+				lbq_desc->p.pg_chunk.map,
+				ql_lbq_block_size(qdev),
+				PCI_DMA_FROMDEVICE);
+	return lbq_desc;
+}
+
 /* Get the next small buffer. */
 static struct bq_desc *ql_get_curr_sbuf(struct rx_ring *rx_ring)
 {
@@ -1063,6 +1090,53 @@ static void ql_write_cq_idx(struct rx_ring *rx_ring)
 	ql_write_db_reg(rx_ring->cnsmr_idx, rx_ring->cnsmr_idx_db_reg);
 }
 
+static int ql_get_next_chunk(struct ql_adapter *qdev, struct rx_ring *rx_ring,
+						struct bq_desc *lbq_desc)
+{
+	if (!rx_ring->pg_chunk.page) {
+		u64 map;
+		rx_ring->pg_chunk.page = alloc_pages(__GFP_COLD | __GFP_COMP |
+						GFP_ATOMIC,
+						qdev->lbq_buf_order);
+		if (unlikely(!rx_ring->pg_chunk.page)) {
+			QPRINTK(qdev, DRV, ERR,
+				"page allocation failed.\n");
+			return -ENOMEM;
+		}
+		rx_ring->pg_chunk.offset = 0;
+		map = pci_map_page(qdev->pdev, rx_ring->pg_chunk.page,
+					0, ql_lbq_block_size(qdev),
+					PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(qdev->pdev, map)) {
+			__free_pages(rx_ring->pg_chunk.page,
+					qdev->lbq_buf_order);
+			QPRINTK(qdev, DRV, ERR,
+				"PCI mapping failed.\n");
+			return -ENOMEM;
+		}
+		rx_ring->pg_chunk.map = map;
+		rx_ring->pg_chunk.va = page_address(rx_ring->pg_chunk.page);
+	}
+
+	/* Copy the current master pg_chunk info
+	 * to the current descriptor.
+	 */
+	lbq_desc->p.pg_chunk = rx_ring->pg_chunk;
+
+	/* Adjust the master page chunk for next
+	 * buffer get.
+	 */
+	rx_ring->pg_chunk.offset += rx_ring->lbq_buf_size;
+	if (rx_ring->pg_chunk.offset == ql_lbq_block_size(qdev)) {
+		rx_ring->pg_chunk.page = NULL;
+		lbq_desc->p.pg_chunk.last_flag = 1;
+	} else {
+		rx_ring->pg_chunk.va += rx_ring->lbq_buf_size;
+		get_page(rx_ring->pg_chunk.page);
+		lbq_desc->p.pg_chunk.last_flag = 0;
+	}
+	return 0;
+}
 /* Process (refill) a large buffer queue. */
 static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 {
@@ -3592,6 +3666,56 @@ error_up:
 	return err;
 }
 
+static int ql_change_rx_buffers(struct ql_adapter *qdev)
+{
+	struct rx_ring *rx_ring;
+	int i, status;
+	u32 lbq_buf_len;
+
+	/* Wait for an oustanding reset to complete. */
+	if (!test_bit(QL_ADAPTER_UP, &qdev->flags)) {
+		int i = 3;
+		while (i-- && !test_bit(QL_ADAPTER_UP, &qdev->flags)) {
+			QPRINTK(qdev, IFUP, ERR,
+				 "Waiting for adapter UP...\n");
+			ssleep(1);
+		}
+
+		if (!i) {
+			QPRINTK(qdev, IFUP, ERR,
+			 "Timed out waiting for adapter UP\n");
+			return -ETIMEDOUT;
+		}
+	}
+
+	status = ql_adapter_down(qdev);
+	if (status)
+		goto error;
+
+	/* Get the new rx buffer size. */
+	lbq_buf_len = (qdev->ndev->mtu > 1500) ?
+		LARGE_BUFFER_MAX_SIZE : LARGE_BUFFER_MIN_SIZE;
+	qdev->lbq_buf_order = get_order(lbq_buf_len);
+
+	for (i = 0; i < qdev->rss_ring_count; i++) {
+		rx_ring = &qdev->rx_ring[i];
+		/* Set the new size. */
+		rx_ring->lbq_buf_size = lbq_buf_len;
+	}
+
+	status = ql_adapter_up(qdev);
+	if (status)
+		goto error;
+
+	return status;
+error:
+	QPRINTK(qdev, IFUP, ALERT,
+		"Driver up/down cycle failed, closing device.\n");
+	set_bit(QL_ADAPTER_UP, &qdev->flags);
+	dev_close(qdev->ndev);
+	return status;
+}
+
 static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
-- 
1.6.0.2


^ permalink raw reply related

* Re: Subject: [PATCH 2/6] bna: Brocade 10Gb Ethernet device driver
From: Ben Hutchings @ 2009-10-16 20:31 UTC (permalink / raw)
  To: Rasesh Mody; +Cc: netdev, amathur
In-Reply-To: <200910161824.n9GIOubY010138@blc-10-10.brocade.com>

On Fri, 2009-10-16 at 11:24 -0700, Rasesh Mody wrote:
> From: Rasesh Mody <rmody@brocade.com>
> 
> This is patch 2/6 which contains linux driver source for
> Brocade's BR1010/BR1020 10Gb CEE capable ethernet adapter.
> 
> We wish this patch to be considered for inclusion in 2.6.32
> 
> Signed-off-by: Rasesh Mody <rmody@brocade.com>
> ---
>  bfa_timer.c    |   97 ++
>  bfad_fwimg.c   |  102 ++
>  bna_fn.c       | 1991 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  bna_queue.c    |  496 ++++++++++++++
>  bnad_ethtool.c | 1101 +++++++++++++++++++++++++++++++
>  5 files changed, 3787 insertions(+)
> 
> diff -ruP linux-2.6.32-rc4-orig/drivers/net/bna/bfad_fwimg.c linux-2.6.32-rc4-mod/drivers/net/bna/bfad_fwimg.c
> --- linux-2.6.32-rc4-orig/drivers/net/bna/bfad_fwimg.c	1969-12-31 16:00:00.000000000 -0800
> +++ linux-2.6.32-rc4-mod/drivers/net/bna/bfad_fwimg.c	2009-10-16 10:30:53.222438000 -0700
> @@ -0,0 +1,102 @@
> +/*
> + * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
> + * All rights reserved
> + * www.brocade.com
> + *
> + * Linux network driver for Brocade Converged Network Adapter.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License (GPL) Version 2 as
> + * published by the Free Software Foundation
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + */
> +/*
> + * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
> + * All rights reserved
> + * www.brocade.com
> + *
> + * See LICENSE.bna for copyright and licensing details.
> + */

I suppose this second copyright banner refers to the firmware itself,
which you have correctly separated from the driver.  You should probably
remove it to avoid confusion.

> +/**
> + *  bfad_fwimg.c Linux driver PCI interface module.
> + */
> +#include <bfa_os_inc.h>
> +#include <defs/bfa_defs_version.h>
> +#include <defs/bfa_defs_pci.h>
> +#include <linux/errno.h>
> +#include <linux/sched.h>
> +#include <linux/init.h>
> +#include <linux/fs.h>
> +#include <asm/uaccess.h>
> +#include <asm/fcntl.h>
> +#include <linux/pci.h>
> +#include <linux/firmware.h>
> +#include <bfa_fwimg_priv.h>
> +
> +u32 bfi_image_ct_size;
> +u32 bfi_image_cb_size;
> +u32 *bfi_image_ct;
> +u32 *bfi_image_cb;
> +
> +
> +#define	BFAD_FW_FILE_CT	"ctfw.bin"
> +#define	BFAD_FW_FILE_CB	"cbfw.bin"
> +
> +u32 *
> +bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
> +			u32 *bfi_image_size, char *fw_name)
> +{
> +	const struct firmware *fw;
> +
> +	if (request_firmware(&fw, fw_name, &pdev->dev)) {
> +		printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
> +		goto error;
> +	}
> +
> +	*bfi_image = vmalloc(fw->size);
> +	if (NULL == *bfi_image) {
> +		printk(KERN_ALERT "Fail to allocate buffer for fw image "
> +			"size=%x!\n", (u32) fw->size);
> +		goto error;
> +	}
> +
> +	memcpy(*bfi_image, fw->data, fw->size);

This makes a completely pointless copy and then leaks the original
version.  Get rid of the copy and stash the struct firmware pointer to
be freed later.

[...]
> diff -ruP linux-2.6.32-rc4-orig/drivers/net/bna/bnad_ethtool.c linux-2.6.32-rc4-mod/drivers/net/bna/bnad_ethtool.c
> --- linux-2.6.32-rc4-orig/drivers/net/bna/bnad_ethtool.c	1969-12-31 16:00:00.000000000 -0800
> +++ linux-2.6.32-rc4-mod/drivers/net/bna/bnad_ethtool.c	2009-10-16 10:30:53.269441000 -0700
[...]
> +static int bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
> +{
> +	struct bnad *bnad = netdev_priv(netdev);
> +	struct bna_port_param port_param;
> +
> +	bnad_lock();
> +	spin_lock_irq(&bnad->priv_lock);
> +	bna_port_param_get(bnad->priv, &port_param);
> +	spin_unlock_irq(&bnad->priv_lock);
> +
> +	if (port_param.speed == BNA_LINK_SPEED_10Gbps) {
> +		cmd->supported = SUPPORTED_10000baseT_Full;
> +		cmd->advertising = ADVERTISED_10000baseT_Full;

10GBASE-R and twinax are not 10GBASE-T!

> +	}
> +
> +	if (port_param.autoneg) {
> +		cmd->supported |= SUPPORTED_Autoneg;
> +		cmd->advertising |= ADVERTISED_Autoneg;
> +		cmd->autoneg = AUTONEG_ENABLE;

But you don't support autonegotiation.

[...]
> +/* XXX use get_sset_count */
> +static int bnad_get_stats_count(struct net_device *netdev)
[...]

Yes, delete this function.

I didn't look further.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH] iputils: ping by mark
From: Rob Townley @ 2009-10-16 21:05 UTC (permalink / raw)
  To: hadi; +Cc: YOSHIFUJI Hideaki, netdev
In-Reply-To: <1255381558.5406.33.camel@dogo.mojatatu.com>

On Mon, Oct 12, 2009 at 4:05 PM, jamal <hadi@cyberus.ca> wrote:
>
> ping by mark, example to use firewall mark decimal 10
> (which hopefully maps to something meaningful with policy routing):
>
> ping -m 10 10.0.0.1
>
> cheers,
> jamal
>

Would this make it easier to ping multiple gateways so if one goes
down, it is taken almost out of the routing table until it comes back
up.

^ permalink raw reply

* Re: PATCH: Network Device Naming mechanism and policy
From: dann frazier @ 2009-10-16 21:40 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: Narendra_K, netdev, linux-hotplug, Matt_Domsch, Jordan_Hargrave,
	Charles_Rose
In-Reply-To: <1255707193.2869.12.camel@achroite>

On Fri, Oct 16, 2009 at 04:33:13PM +0100, Ben Hutchings wrote:
> On Fri, 2009-10-16 at 09:20 -0600, dann frazier wrote:
> > On Fri, Oct 16, 2009 at 07:32:50PM +0530, Narendra_K@Dell.com wrote:
> [...]
> > > And how would the regular file look like in terms of holding ifindex of
> > > the interface, which can be passed to libnetdevname.
> > 
> > I can't think of anything we need to store in the regular file. If we
> > have the kernel name for the device, we can look up the ifindex in
> > /sys. Correct me if I'm wrong, but storing it ourselves seems
> > redundant.
> 
> But the name of a netdev can change whereas its ifindex never does.
> Identifying netdevs by name would require additional work to update the
> links when a netdev is renamed and would still be prone to race
> conditions.  This is why Narendra and Matt were proposing to store the
> ifindex in the node all along...

Matt, Ben and I talked about a few other possibilities on IRC.
The one I like the most at the moment is an idea Ben had to creat
dummy files named after the ifindex. Then, use symlinks for the kernel
name and the various by-$property subdirectories. This means the KOBJ
events will need to expose the ifindex.

I'm a novice at net programming, but I'm told that ifindex is
the information apps ultimately require here.

-- 
dann frazier


^ permalink raw reply

* MAINTAINERS drivers/net cleanups?
From: Joe Perches @ 2009-10-16 21:52 UTC (permalink / raw)
  To: netdev

Ben Hutchings suggested adding a facility to
scripts/get_maintainer.pl to print the role of
each maintainer.  I added a bit more to print
statistics about the maintainers and "-by:" lines
from each git commit as well.

To see if it worked, I tested this script on
drivers/net:

$ for file in drivers/net/*.c ; do \
echo ; \
echo "------> $file" ; \
echo ; \
./scripts/get_maintainer.pl \
--git-since=5-years-ago \
--git-min-percent=0 -f --rolestats \
$file ; \
done

There are many people described as MAINTAINERS for
these files that have not had a single sign-off or
commit in git history.

That's 4+ years.

Here are the files, nominal maintainers, and the
sections of MAINTAINERS that could be dropped.

Should these individuals be removed from MAINTAINERS
and added to CREDITS if not already there?

------> drivers/net/3c505.c
------> drivers/net/eexpress.c
Philip Blundell <philb@gnu.org> (maintainer)

3C505 NETWORK DRIVER
M: Philip Blundell <philb@gnu.org>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/3c505*

ETHEREXPRESS-16 NETWORK DRIVER
M: Philip Blundell <philb@gnu.org>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/eexpress.*

------> drivers/net/8390.c
------> drivers/net/8390p.c
------> drivers/net/ax88796.c
------> drivers/net/lib8390.c
------> drivers/net/mac8390.c
------> drivers/net/zorro8390.c
Paul Gortmaker <p_gortmaker@yahoo.com> (maintainer)

8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
M: Paul Gortmaker <p_gortmaker@yahoo.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/*8390*
F: drivers/net/ax88796.c

------> drivers/net/acenic.c
Jes Sorensen <jes@trained-monkey.org> (maintainer)

ACENIC DRIVER
M: Jes Sorensen <jes@trained-monkey.org>
L: linux-acenic@sunsite.dk
S: Maintained
F: drivers/net/acenic*

------> drivers/net/b44.c
Gary Zambrano <zambrano@broadcom.com> (maintainer)

BROADCOM B44 10/100 ETHERNET DRIVER
M: Gary Zambrano <zambrano@broadcom.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/b44.*

------> drivers/net/eth16i.c
Mika Kuoppala <miku@iki.fi> (maintainer)

ETHERTEAM 16I DRIVER
M: Mika Kuoppala <miku@iki.fi>
S: Maintained
F: drivers/net/eth16i.c

------> drivers/net/hp100.c
Jaroslav Kysela <perex@perex.cz> (maintainer)

HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
M: Jaroslav Kysela <perex@perex.cz>
S: Maintained
F: drivers/net/hp100.*

------> drivers/net/ipg.c
Francois Romieu <romieu@fr.zoreil.com> (maintainer)
Sorbica Shieh <sorbica@icplus.com.tw> (maintainer)
Jesse Huang <jesse@icplus.com.tw> (maintainer)

IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER
M: Francois Romieu <romieu@fr.zoreil.com>
M: Sorbica Shieh <sorbica@icplus.com.tw>
M: Jesse Huang <jesse@icplus.com.tw>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ipg.c

------> drivers/net/macb.c
Haavard Skinnemoen <hskinnemoen@atmel.com> (maintainer)

ATMEL MACB ETHERNET DRIVER
M: Haavard Skinnemoen <hskinnemoen@atmel.com>
S: Supported
F: drivers/net/macb.*

------> drivers/net/natsemi.c
Tim Hockin <thockin@hockin.org> (maintainer)

NATSEMI ETHERNET DRIVER (DP8381x)
M: Tim Hockin <thockin@hockin.org>
S: Maintained
F: drivers/net/natsemi.c

------> drivers/net/ni5010.c
Jan-Pascal van Best <janpascal@vanbest.org> (maintainer)
Andreas Mohr <andi@lisas.de> (maintainer)

NI5010 NETWORK DRIVER
M: Jan-Pascal van Best <janpascal@vanbest.org>
M: Andreas Mohr <andi@lisas.de>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ni5010.*

------> drivers/net/pppoe.c
------> drivers/net/pppox.c
Michal Ostrowski <mostrows@earthlink.net> (maintainer)

PPP OVER ETHERNET
M: Michal Ostrowski <mostrows@earthlink.net>
S: Maintained
F: drivers/net/pppoe.c
F: drivers/net/pppox.c

------> drivers/net/skge.c
------> drivers/net/sky2.c
Stephen Hemminger <shemminger@linux-foundation.org> (maintainer)

SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
M: Stephen Hemminger <shemminger@linux-foundation.org>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/skge.*
F: drivers/net/sky2.*

------> drivers/net/sonic.c
Thomas Bogendoerfer <tsbogend@alpha.franken.de> (maintainer)

SONIC NETWORK DRIVER
M: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/sonic.*

------> drivers/net/spider_net.c
------> drivers/net/spider_net_ethtool.c
Ishizaki Kou <kou.ishizaki@toshiba.co.jp> (maintainer)
Jens Osterkamp <jens@de.ibm.com> (maintainer)

SPIDERNET NETWORK DRIVER for CELL
M: Ishizaki Kou <kou.ishizaki@toshiba.co.jp>
M: Jens Osterkamp <jens@de.ibm.com>
L: netdev@vger.kernel.org
S: Supported
F: Documentation/networking/spider_net.txt
F: drivers/net/spider_net*

------> drivers/net/starfire.c
Ion Badulescu <ionut@badula.org> (maintainer)

STARFIRE/DURALAN NETWORK DRIVER
M: Ion Badulescu <ionut@badula.org>
S: Odd Fixes
F: drivers/net/starfire*

------> drivers/net/tehuti.c
Alexander Indenbaum <baum@tehutinetworks.net> (maintainer)
Andy Gospodarek <andy@greyhouse.net> (maintainer)

TEHUTI ETHERNET DRIVER
M: Alexander Indenbaum <baum@tehutinetworks.net>
M: Andy Gospodarek <andy@greyhouse.net>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/tehuti*

------> drivers/net/tlan.c
Samuel Chessman <chessman@tux.org> (maintainer)

TLAN NETWORK DRIVER
M: Samuel Chessman <chessman@tux.org>
L: tlan-devel@lists.sourceforge.net (subscribers-only)
W: http://sourceforge.net/projects/tlan/
S: Maintained
F: Documentation/networking/tlan.txt
F: drivers/net/tlan.*

------> drivers/net/typhoon.c
David Dillow <dave@thedillows.org> (maintainer)

3CR990 NETWORK DRIVER
M: David Dillow <dave@thedillows.org>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/typhoon*




^ permalink raw reply

* Re: behaviour question for igb on nehalem box
From: Richard Scobie @ 2009-10-16 22:15 UTC (permalink / raw)
  To: Chris Friesen
  Cc: e1000-list, Linux Network Development list, Allan, Bruce W,
	Brandeburg, Jesse, Ronciak, John, Kirsher, Jeffrey T,
	gospo@redhat.com
In-Reply-To: <4AD4B9BB.3010209@nortel.com>

I'm have just put together a Nehalem system (1 x Xeon), 
2.6.30.8-64.fc11.x86_64, which has quad onboard 82576 and noticed during 
testing using just a single interface, that the RX queues on the other 3 
were receiving interrupts - observed in /proc/interrupts.

Is this normal behaviour?

Regards,

Richard

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference

^ permalink raw reply

* Re: [PATCH 2/2] page allocator: Direct reclaim should always obey watermarks
From: Mel Gorman @ 2009-10-16 22:32 UTC (permalink / raw)
  To: David Rientjes
  Cc: Andrew Morton, stable, Rafael J. Wysocki, David Miller, Frans Pop,
	reinette chatre, Kalle Valo, John W. Linville, Pekka Enberg,
	Bartlomiej Zolnierkiewicz, Karol Lewandowski, netdev,
	linux-kernel, linux-mm@kvack.org
In-Reply-To: <alpine.DEB.1.00.0910161204140.21328@chino.kir.corp.google.com>

On Fri, Oct 16, 2009 at 12:07:07PM -0700, David Rientjes wrote:
> On Fri, 16 Oct 2009, Mel Gorman wrote:
> 
> > ALLOC_NO_WATERMARKS should be cleared when trying to allocate from the
> > free-lists after a direct reclaim. If it's not, __GFP_NOFAIL allocations
> > from a process that is exiting can ignore watermarks. __GFP_NOFAIL is not
> > often used but the journal layer is one of those places. This is suspected of
> > causing an increase in the number of GFP_ATOMIC allocation failures reported.
> > 
> > Signed-off-by: Mel Gorman <mel@csn.ul.ie>
> > ---
> >  mm/page_alloc.c |    3 ++-
> >  1 files changed, 2 insertions(+), 1 deletions(-)
> > 
> > diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> > index dfa4362..a3e5fed 100644
> > --- a/mm/page_alloc.c
> > +++ b/mm/page_alloc.c
> > @@ -1860,7 +1860,8 @@ rebalance:
> >  	page = __alloc_pages_direct_reclaim(gfp_mask, order,
> >  					zonelist, high_zoneidx,
> >  					nodemask,
> > -					alloc_flags, preferred_zone,
> > +					alloc_flags & ~ALLOC_NO_WATERMARKS,
> > +					preferred_zone,
> >  					migratetype, &did_some_progress);
> >  	if (page)
> >  		goto got_pg;
> 
> I don't get it.  __alloc_pages_high_priority() will already loop 
> indefinitely if ALLOC_NO_WATERMARKS is set and its a __GFP_NOFAIL 
> allocation.  How do we even reach this code in such a condition?
> 

Frans, you reported that both patches in combination reduced the number
of failures. Was it in fact just the kswapd change that made the
difference?

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [E1000-devel] behaviour question for igb on nehalem box
From: Brandeburg, Jesse @ 2009-10-16 22:48 UTC (permalink / raw)
  To: Richard Scobie
  Cc: Chris Friesen, e1000-list, Linux Network Development list,
	Allan, Bruce W, Ronciak, John, Kirsher, Jeffrey T,
	gospo@redhat.com
In-Reply-To: <4AD8F089.9010602@sauce.co.nz>

On Fri, 16 Oct 2009, Richard Scobie wrote:
> I'm have just put together a Nehalem system (1 x Xeon), 
> 2.6.30.8-64.fc11.x86_64, which has quad onboard 82576 and noticed during 
> testing using just a single interface, that the RX queues on the other 3 
> were receiving interrupts - observed in /proc/interrupts.
> 
> Is this normal behaviour?

Hi Richard, 

This is normal, since we trigger an interrupt on every queue during our 
watchdog.  So if the interface is up it should be triggering an interrupt 
on every queue every two seconds.

This has (and will probably continue to be) necessary in order to pick up 
any straggler packets due to any (extremely rare, but expected to occur) 
missed interrupts that could happen when traffic is running.  It also is 
extremely useful if you're doing irq affinitization and/or debugging 
interrupts.

you can bring down the interfaces and they will stop interrupting.

Jesse

^ permalink raw reply

* RE: Subject: [PATCH 1/6] bna: Brocade 10Gb Ethernet device driver
From: Rasesh Mody @ 2009-10-16 23:19 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: netdev@vger.kernel.org, Akshay Mathur
In-Reply-To: <1255724406.2869.70.camel@achroite>

Hello Ben,

Thanks a lot for your comments. We will try to address the issues in the following submissions.

--Rasesh Mody
(Brocade Linux Driver Team)

-----Original Message-----
From: Ben Hutchings [mailto:bhutchings@solarflare.com]
Sent: Friday, October 16, 2009 1:20 PM
To: Rasesh Mody
Cc: netdev@vger.kernel.org; Akshay Mathur
Subject: Re: Subject: [PATCH 1/6] bna: Brocade 10Gb Ethernet device driver

On Fri, 2009-10-16 at 11:24 -0700, Rasesh Mody wrote:
> From: Rasesh Mody <rmody@brocade.com>
>
> This is patch 1/6 which contains linux driver source for
> Brocade's BR1010/BR1020 10Gb CEE capable ethernet adapter.
>
> We wish this patch to be considered for inclusion in 2.6.32

I think it's a bit late for that.

[...]
> +#ifdef NETIF_F_TSO
> +#include <net/checksum.h>
> +#endif

NETIF_F_TSO is always defined; remove the check.

[...]
> +#ifdef BNAD_NO_IP_ALIGN
> +#undef NET_IP_ALIGN
> +#define NET_IP_ALIGN 0
> +#endif

Don't redefine standard macros.  Define your own which is set to either
NET_IP_ALIGN or 0 as appropriate.

> +#define BNAD_TXQ_WI_NEEDED(_vectors) (((_vectors) + 3) >> 2)
> +
> +#define BNAD_RESET_Q(_bnad, _q, _unmap_q)                            \
> +do {                                                                 \
> +     if ((_q)->producer_index != (_q)->consumer_index) {      \
> +             DPRINTK(ERR, "Q producer index %u != ", (_q)->producer_index);      \
> +             DPRINTK(ERR, "consumer index %u\n", (_q)->consumer_index);      \
> +     }                                                               \
> +     BNA_ASSERT((_q)->producer_index == (_q)->consumer_index);      \
> +     if ((_unmap_q)->producer_index != (_unmap_q)->consumer_index) {      \
> +             DPRINTK(ERR, "UnmapQ producer index %u != ", (_unmap_q)->producer_index);      \
> +             DPRINTK(ERR, "consumer index %u\n", (_unmap_q)->consumer_index);      \
> +     }                                                               \
> +     BNA_ASSERT((_unmap_q)->producer_index == \
> +             (_unmap_q)->consumer_index);      \
> +     (_q)->producer_index = 0;       \
> +     (_q)->consumer_index = 0;       \
> +     (_unmap_q)->producer_index = 0; \
> +     (_unmap_q)->consumer_index = 0; \
> +     {       \
> +             u32 _ui;        \
> +             for (_ui = 0; _ui < (_unmap_q)->q_depth; _ui++)         \
> +                     BNA_ASSERT(!(_unmap_q)->unmap_array[_ui].skb);      \
> +     }       \
> +} while (0)

Is there any reason not to write this as a function?  It looks like an
infrequent control operation that shouldn't even be an inline function.

[...]
> +static const struct net_device_ops bnad_netdev_ops = {
> +     .ndo_open                               = bnad_open,
> +     .ndo_stop                               = bnad_stop,
> +     .ndo_start_xmit                 = bnad_start_xmit,
> +     .ndo_get_stats                  = bnad_get_stats,
> +#ifdef HAVE_SET_RX_MODE
> +     .ndo_set_rx_mode                = &bnad_set_rx_mode,
> +#endif

The HAVE_* macros are meant for use by out-of-tree drivers.  There is no
need to test them in in-tree code.

[...]
> +static int bnad_check_module_params(void)
> +{
> +     /* bnad_msix */
> +     if (bnad_msix && bnad_msix != 1)
> +             printk(KERN_WARNING "bna: bnad_msix should be 0 or 1, "
> +                 "%u is invalid, set bnad_msix to 1\n", bnad_msix);
> +
> +     /* bnad_small_large_rxbufs */
> +     if (bnad_small_large_rxbufs && bnad_small_large_rxbufs != 1)
> +             printk(KERN_WARNING "bna: bnad_small_large_rxbufs should be "
> +                 "0 or 1, %u is invalid, set bnad_small_large_rxbufs to 1\n",
> +                 bnad_small_large_rxbufs);
> +     if (bnad_small_large_rxbufs)
> +             bnad_rxqs_per_cq = 2;
> +     else
> +             bnad_rxqs_per_cq = 1;
> +
> +     /* bnad_rxqsets_used */
> +     if (bnad_rxqsets_used > BNAD_MAX_RXQS / bnad_rxqs_per_cq) {
> +             printk(KERN_ERR "bna: the maximum value for bnad_rxqsets_used "
> +                 "is %u, %u is invalid\n",
> +                 BNAD_MAX_RXQS / bnad_rxqs_per_cq, bnad_rxqsets_used);
> +             return -EINVAL;
> +     }

There is a cleaner way to validate and reject module parameter values
which is to define the parameters with module_param_call().

> +static void bnad_alloc_rxbufs(struct bnad_rxq_info *rxqinfo)
> +{
> +     u16 to_alloc, alloced, unmap_prod, wi_range;
> +     struct bnad_skb_unmap *unmap_array;
> +     struct bna_rxq_entry *rxent;
> +     struct sk_buff *skb;
> +     dma_addr_t dma_addr;
> +
> +     alloced = 0;
> +     to_alloc = BNA_QE_FREE_CNT(&rxqinfo->skb_unmap_q,
> +         rxqinfo->skb_unmap_q.q_depth);
> +
> +     unmap_array = rxqinfo->skb_unmap_q.unmap_array;
> +     unmap_prod = rxqinfo->skb_unmap_q.producer_index;
> +     BNA_RXQ_QPGE_PTR_GET(unmap_prod, &rxqinfo->rxq.q, rxent, wi_range);
> +     BNA_ASSERT(wi_range && wi_range <= rxqinfo->rxq.q.q_depth);
> +
> +     while (to_alloc--) {
> +             if (!wi_range) {
> +                     BNA_RXQ_QPGE_PTR_GET(unmap_prod, &rxqinfo->rxq.q,
> +                         rxent, wi_range);
> +                     BNA_ASSERT(wi_range &&
> +                         wi_range <= rxqinfo->rxq.q.q_depth);
> +             }
> +#ifdef BNAD_RXBUF_HEADROOM
> +             skb = netdev_alloc_skb(rxqinfo->bnad->netdev,
> +                 rxqinfo->rxq_config.buffer_size + NET_IP_ALIGN);
> +#else
> +             skb = alloc_skb(rxqinfo->rxq_config.buffer_size + NET_IP_ALIGN,
> +                 GFP_ATOMIC);
> +#endif

Why is this conditional?

[...]
> +static irqreturn_t bnad_msix_rx(int irq, void *data)
> +{
> +     struct bnad_cq_info *cqinfo = (struct bnad_cq_info *)data;
> +     struct bnad *bnad = cqinfo->bnad;
> +
> +             if (likely(netif_rx_schedule_prep(bnad->netdev,
> +                     &cqinfo->napi))) {
> +                     bnad_disable_rx_irq(bnad, cqinfo);
> +                     __netif_rx_schedule(bnad->netdev, &cqinfo->napi);
> +             }
> +
> +     return IRQ_HANDLED;
> +}

Indentation is wrong.

[...]
> +static irqreturn_t bnad_isr(int irq, void *data)
> +{
> +     struct net_device *netdev = data;
> +     struct bnad *bnad = netdev_priv(netdev);
> +     u32 intr_status;
> +
> +     spin_lock(&bnad->priv_lock);
> +     bna_intr_status_get(bnad->priv, &intr_status);
> +     spin_unlock(&bnad->priv_lock);
> +
> +     if (!intr_status)
> +             return IRQ_NONE;
> +
> +     DPRINTK(DEBUG, "port %u bnad_isr: 0x%x\n", bnad->bna_id, intr_status);
> +     if (BNA_IS_MBOX_ERR_INTR(intr_status)) {
> +             spin_lock(&bnad->priv_lock);
> +             bna_mbox_err_handler(bnad->priv, intr_status);
> +             spin_unlock(&bnad->priv_lock);
> +             if (BNA_IS_ERR_INTR(intr_status) ||
> +                 !BNA_IS_INTX_DATA_INTR(intr_status))
> +                     goto exit_isr;
> +     }
> +
> +     if (likely(netif_rx_schedule_prep(bnad->netdev,
> +         &bnad->cq_table[0].napi))) {
> +             bnad_disable_txrx_irqs(bnad);
> +             __netif_rx_schedule(bnad->netdev, &bnad->cq_table[0].napi);
> +     }

These functions don't exist any more!

[...]
> +static int bnad_request_txq_irq(struct bnad *bnad, uint txq_id)
> +{
> +     BNA_ASSERT(txq_id < bnad->txq_num);
> +     if (!(bnad->flags & BNAD_F_MSIX))
> +             return 0;
> +     DPRINTK(DEBUG, "port %u requests irq %u for TxQ %u in MSIX mode\n",
> +             bnad->bna_id, bnad->msix_table[txq_id].vector, txq_id);
> +     return request_irq(bnad->msix_table[txq_id].vector,
> +         (irq_handler_t)&bnad_msix_tx, 0, bnad->txq_table[txq_id].name,

Why are you casting this function pointer?  It has the right type
already, and if it didn't then casting wouldn't fix the matter.

> +         &bnad->txq_table[txq_id]);
> +}
> +
> +int bnad_request_cq_irq(struct bnad *bnad, uint cq_id)
> +{
> +     BNA_ASSERT(cq_id < bnad->cq_num);
> +     if (!(bnad->flags & BNAD_F_MSIX))
> +             return 0;
> +     DPRINTK(DEBUG, "port %u requests irq %u for CQ %u in MSIX mode\n",
> +             bnad->bna_id,
> +             bnad->msix_table[bnad->txq_num + cq_id].vector, cq_id);
> +     return request_irq(bnad->msix_table[bnad->txq_num + cq_id].vector,
> +         (irq_handler_t)&bnad_msix_rx, 0, bnad->cq_table[cq_id].name,

Same here.

[...]
> +static void bnad_link_up_cb(void *arg, u8 status)
> +{
> +     struct bnad *bnad = (struct bnad *)arg;
> +     struct net_device *netdev = bnad->netdev;
> +
> +     DPRINTK(INFO, "%s bnad_link_up_cb\n", netdev->name);
> +     if (netif_running(netdev)) {
> +             if (!netif_carrier_ok(netdev) &&
> +                 !test_bit(BNAD_DISABLED, &bnad->state)) {
> +                             printk(KERN_INFO "%s link up\n", netdev->name);
> +                     netif_carrier_on(netdev);
> +                     netif_wake_queue(netdev);
> +                     bnad->stats.netif_queue_wakeup++;
> +             }
> +     }
> +}
> +
> +static void bnad_link_down_cb(void *arg, u8 status)
> +{
> +     struct bnad *bnad = (struct bnad *)arg;
> +     struct net_device *netdev = bnad->netdev;
> +
> +     DPRINTK(INFO, "%s bnad_link_down_cb\n", netdev->name);
> +     if (netif_running(netdev)) {
> +             if (netif_carrier_ok(netdev)) {
> +                     printk(KERN_INFO "%s link down\n", netdev->name);
> +                     netif_carrier_off(netdev);
> +                     netif_stop_queue(netdev);
> +                     bnad->stats.netif_queue_stop++;
> +             }
> +     }
> +}

There is no need to wake/stop the TX queues here; the netdev core
understands that TX queues must be stopped while the link is down.

[...]
> +static void bnad_detach(struct bnad *bnad)
> +{
[...]
> +     /* Wait to make sure Tx and Rx are stopped. */
> +     msleep(1000);
> +     bnad_free_txrx_irqs(bnad);
> +     bnad_sync_mbox_irq(bnad);
> +
> +             bnad_napi_disable(bnad);
> +             bnad_napi_uninit(bnad);
> +
> +     /* Delete the stats timer after synchronize with mbox irq. */
> +     del_timer_sync(&bnad->stats_timer);
> +             netif_tx_disable(bnad->netdev);
> +             netif_carrier_off(bnad->netdev);
> +}

Some incorrect indentation here.

[...]
> +void bnad_rxib_init(struct bnad *bnad, uint cq_id, uint ib_id)
> +{
[...]
> +#if 1
> +     ib_config->control_flags = BNA_IB_CF_INT_ENABLE |
> +         BNA_IB_CF_MASTER_ENABLE;
> +#else
> +     ib_config->control_flags = BNA_IB_CF_INT_ENABLE |
> +         BNA_IB_CF_INTER_PKT_ENABLE | BNA_IB_CF_MASTER_ENABLE;
> +     ib_config->interpkt_count = bnad->rx_interpkt_count;
> +     ib_config->interpkt_timer = bnad->rx_interpkt_timeo;
> +#endif

If you always want to use the first version (#if 1) then get rid of the
second version.

[...]
> +/* Note: bnad_cleanup doesn't not free irqs and queues. */

A double negative can mean a positive, but this is ambiguous.  Either
change the comment to say clearly that it does free irqs and queues, or
remove the comment since the code is clear enough.

> +static void bnad_cleanup(struct bnad *bnad)
> +{
> +     kfree(bnad->rit);
> +     bnad->rit = NULL;
> +     kfree(bnad->txf_table);
> +     bnad->txf_table = NULL;
> +     kfree(bnad->rxf_table);
> +     bnad->rxf_table = NULL;
> +
> +     bnad_free_ibs(bnad);
> +     bnad_free_queues(bnad);
> +}
[...]
> +int bnad_open_locked(struct net_device *netdev)
> +{
> +     struct bnad *bnad = netdev_priv(netdev);
> +     uint i;
> +     int err;
> +
> +     ASSERT_RTNL();
> +     DPRINTK(WARNING, "%s open\n", netdev->name);
> +
> +     if (BNAD_NOT_READY(bnad)) {
> +             DPRINTK(WARNING, "%s is not ready yet (0x%lx)\n",
> +                     netdev->name, bnad->state);
> +             return 0;
> +     }
> +
> +     if (!test_bit(BNAD_DISABLED, &bnad->state)) {
> +             DPRINTK(WARNING, "%s is already opened (0x%lx)\n",
> +                     netdev->name, bnad->state);
> +
> +             return 0;
> +     }

Why are you returning 0 in these error cases?

[...]
> +int bnad_open(struct net_device *netdev)
> +{
> +     struct bnad *bnad = netdev_priv(netdev);
> +     int error = 0;
> +
> +     bnad_lock();
> +     if (!test_bit(BNAD_PORT_DISABLED, &bnad->state))
> +             error = bnad_open_locked(netdev);
> +     bnad_unlock();
> +     return error;
> +}
> +
> +int bnad_stop(struct net_device *netdev)
> +{
> +     int error = 0;
> +
> +     bnad_lock();
> +     error = bnad_stop_locked(netdev);
> +     bnad_unlock();
> +     return error;
> +}

Given that bnad_lock() and bnad_unlock() are defined as doing nothing,
you should merge these with the functions they call.

[...]
> +static int bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
> +{
> +#ifdef NETIF_F_TSO
> +     int err;
> +
> +#ifdef SKB_GSO_TCPV4
> +     /* SKB_GSO_TCPV4 and SKB_GSO_TCPV6 is defined since 2.6.18. */

So there is no need to test for it. :-)

[...]
> +int bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)

Return type must be netdev_tx_t.

[...]
> +static void bnad_set_rx_mode(struct net_device *netdev)
> +{
> +     bnad_lock();
> +     bnad_set_rx_mode_locked(netdev);
> +     bnad_unlock();
> +}
[...]
> +static int bnad_set_mac_address(struct net_device *netdev, void *addr)
> +{
> +     int err = 0;
> +
> +     bnad_lock();
> +     err = bnad_set_mac_address_locked(netdev, addr);
> +     bnad_unlock();
> +     return err;
> +
> +}

Can also be merged with the functions they call.

[...]
> +static int bnad_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
> +{
> +     return -EOPNOTSUPP;
> +}

You don't need to define an ioctl() operation at all.

[...]
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +static void bnad_netpoll(struct net_device *netdev)
> +{
> +     struct bnad *bnad = netdev_priv(netdev);
> +
> +     DPRINTK(INFO, "%s bnad_netpoll\n", netdev->name);
> +     disable_irq(bnad->pcidev->irq);
> +     bnad_isr(bnad->pcidev->irq, netdev);
> +     enable_irq(bnad->pcidev->irq);
> +}
> +#endif

This doesn't look like it will work when the hardware is configured for
MSI-X.

[...]
> +static void bnad_stats_timeo(unsigned long data)
> +{
> +     struct bnad *bnad = (struct bnad *)data;
> +     int i;
> +     struct bnad_rxq_info *rxqinfo;
> +
> +     spin_lock_irq(&bnad->priv_lock);
> +     bna_stats_get(bnad->priv);
> +     spin_unlock_irq(&bnad->priv_lock);
> +
> +     if (bnad->rx_dyn_coalesce_on) {
> +             u8 cls_timer;
> +             struct bnad_cq_info *cq;
> +             for (i = 0; i < bnad->cq_num; i++) {
> +                     cq = &bnad->cq_table[i];
> +
> +                     if ((cq->pkt_rate.small_pkt_cnt == 0)
> +                         && (cq->pkt_rate.large_pkt_cnt == 0))
> +                             continue;
> +
> +                             cls_timer = bna_calc_coalescing_timer(
> +                             bnad->priv, &cq->pkt_rate);
> +
> +                     /*For NAPI version, coalescing timer need to stored*/
> +                     cq->rx_coalescing_timeo = cls_timer;

I can't parse this comment.

[...]
> +static int bnad_priv_init(struct bnad *bnad)
> +{
> +     dma_addr_t dma_addr;
> +     struct bna_dma_addr bna_dma_addr;
> +     char inst_name[16];
> +     int err, i;
> +     struct bfa_pcidev_s pcidev_info;
> +     u32 intr_mask;
> +
> +     DPRINTK(DEBUG, "port %u bnad_priv_init\n", bnad->bna_id);
> +
> +     if (bnad_msix)
> +             bnad->flags |= BNAD_F_MSIX;
> +     bnad_q_num_init(bnad, bnad_rxqsets_used);
> +
> +     bnad->work_flags = 0;
> +     INIT_WORK(&bnad->work, bnad_work);
> +
> +     init_timer(&bnad->stats_timer);
> +     bnad->stats_timer.function = &bnad_stats_timeo;
> +     bnad->stats_timer.data = (unsigned long)bnad;
[...]
> +     init_timer(&bnad->ioc_timer);
> +     bnad->ioc_timer.function = &bnad_ioc_timeout;
> +     bnad->ioc_timer.data = (unsigned long)bnad;

Each of these groups of three statements can be written as one call to
setup_timer().

> +     mod_timer(&bnad->ioc_timer, jiffies + HZ * BNA_IOC_TIMER_FREQ / 1000);

It would be clearer to write the timeout as jiffies +
msecs_to_jiffies(BNA_IOC_TIMER_FREQ).  Also, given that
BNA_IOC_TIMER_FREQ is the *period* of the timer, maybe it should be
called BNA_IOC_TIMER_PERIOD.

> +static int __devinit
> +bnad_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *pcidev_id)
> +{
> +     int err, using_dac;
> +     struct net_device *netdev;
> +     struct bnad *bnad;
> +     unsigned long mmio_start, mmio_len;
> +     static u32 bna_id;
> +
> +     DPRINTK(INFO, "bnad_pci_probe(0x%p, 0x%p)\n", pcidev, pcidev_id);
> +
> +     DPRINTK(DEBUG, "PCI func %d\n", PCI_FUNC(pcidev->devfn));
> +     if (!bfad_get_firmware_buf(pcidev)) {
> +             printk(KERN_WARNING "Failed to load Firmware Image!\n");
> +             return 0;

You *must* return an error code here.

[...]
> +     netdev->netdev_ops = &bnad_netdev_ops;
> +     netdev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
> +#ifdef NETIF_F_IPV6_CSUM
> +     netdev->features |= NETIF_F_IPV6_CSUM;
> +#endif
> +#ifdef NETIF_F_TSO
> +     netdev->features |= NETIF_F_TSO;
> +#endif
> +#ifdef NETIF_F_TSO6
> +     netdev->features |= NETIF_F_TSO6;
> +#endif
> +#ifdef NETIF_F_LRO
> +     netdev->features |= NETIF_F_LRO;
> +#endif
> +#ifdef BNAD_VLAN_FEATURES
> +     netdev->vlan_features = netdev->features;
> +#endif

Get rid of these macro conditions.

> +     if (using_dac)
> +             netdev->features |= NETIF_F_HIGHDMA;
> +     netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
> +         NETIF_F_HW_VLAN_FILTER;
> +
> +     netdev->mem_start = mmio_start;
> +     netdev->mem_end = mmio_start + mmio_len - 1;
> +
> +     bnad_set_ethtool_ops(netdev);
> +
> +     bnad->bna_id = bna_id;
> +     err = bnad_priv_init(bnad);
> +     if (err) {
> +             printk(KERN_ERR "port %u init failed: %d\n", bnad->bna_id, err);
> +             goto unmap_bar0;
> +     }
> +
> +     BNA_ASSERT(netdev->addr_len == ETH_ALEN);
> +#ifdef ETHTOOL_GPERMADDR
> +     memcpy(netdev->perm_addr, bnad->perm_addr, netdev->addr_len);
> +#endif

Just put the address in netdev->perm_addr in the first place, and don't
test ETHTOOL_GPERMADDR.

[...]
> +static void __devexit bnad_pci_remove(struct pci_dev *pcidev)
> +{
> +     struct net_device *netdev = pci_get_drvdata(pcidev);
> +     struct bnad *bnad;
> +
> +     DPRINTK(INFO, "%s bnad_pci_remove\n", netdev->name);
> +     if (!netdev)
> +             return;

Surely this would indicate a bug?

[...]
> diff -ruP linux-2.6.32-rc4-orig/drivers/net/bna/bnad.h linux-2.6.32-rc4-mod/drivers/net/bna/bnad.h
> --- linux-2.6.32-rc4-orig/drivers/net/bna/bnad.h        1969-12-31 16:00:00.000000000 -0800
> +++ linux-2.6.32-rc4-mod/drivers/net/bna/bnad.h 2009-10-16 10:30:53.075436000 -0700
[...]
> +#if !defined(CONFIG_INET_LRO) && !defined(CONFIG_INET_LRO_MODULE)
> +#include <net/ip.h>
> +#include <net/tcp.h>
> +#else
> +#include <linux/inet_lro.h>
> +#endif
> +
> +#include "bnad_compat.h"
> +
> +#if !defined(CONFIG_INET_LRO) && !defined(CONFIG_INET_LRO_MODULE)
> +#include "inet_lro.h"
> +#endif

What is this?  You want to use your own copy of inet_lro?

You should really be using GRO instead (which is a lot easier).

[...]
> +#define bnad_lock()
> +#define bnad_unlock()

What's the point of this?

[...]
> +struct bnad {
[...]
> +     struct net_device_stats net_stats;

You don't need this; use the stats in struct net_device.

[...]
> +     unsigned char perm_addr[ETH_ALEN];

Use the perm_addr in struct net_device.

> +     u32 pci_saved_config[16];
[...]

You don't need this; the PCI core saves config registers in struct
pci_dev.

You should rebase this against net-next-2.6 and run
scripts/checkpatch.pl over it before resubmitting.

Ben.

--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH 2/2] page allocator: Direct reclaim should always obey watermarks
From: Frans Pop @ 2009-10-16 23:28 UTC (permalink / raw)
  To: Mel Gorman
  Cc: David Rientjes, Andrew Morton, stable, Rafael J. Wysocki,
	David Miller, reinette chatre, Kalle Valo, John W. Linville,
	Pekka Enberg, Bartlomiej Zolnierkiewicz, Karol Lewandowski,
	netdev, linux-kernel, linux-mm@kvack.org
In-Reply-To: <20091016223237.GE32397@csn.ul.ie>

On Saturday 17 October 2009, Mel Gorman wrote:
> Frans, you reported that both patches in combination reduced the number
> of failures. Was it in fact just the kswapd change that made the
> difference?

I will retest both patches (as I already mailed you privately yesterday), 
but not today. The improvement with the combination was real, but I'm not 
sure which patch is the reason. I think the second, but I need to verify.

I've done another 30 boots or so today, mainly in the "akpm" merge, and 
I've found new patterns that will help me nail down the regression. But 
ATM I can't see straight anymore, so it will have to wait until tomorrow.

I'd suggest to delay merging any patches for now. There are still too many 
open ends.

Cheers,
FJP

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [Fwd: [PATCH] [NIU] VLAN does not work with niu driver]
From: David Miller @ 2009-10-17  0:40 UTC (permalink / raw)
  To: Joyce.Yu; +Cc: netdev
In-Reply-To: <4AD89D9A.7090405@Sun.COM>

From: Joyce Yu <Joyce.Yu@Sun.COM>
Date: Fri, 16 Oct 2009 09:21:46 -0700

> 
> Can this patch be accepted and integrated to the main tree?

Well, what happened to all of those page fragment modifications?

They all of a sudden are no longer necessary?  Why?

I'm not going to apply this patch until you start explaining
why these things are being done, or not done.  And you must
add some more text to your commit messages so that you explain
your change sufficiently.

Thank you.

^ permalink raw reply

* Re: [net-next PATCH 0/3] qlge: Size RX buffers based on MTU.
From: David Miller @ 2009-10-17  0:51 UTC (permalink / raw)
  To: ron.mercer; +Cc: netdev
In-Reply-To: <1255724136-27264-1-git-send-email-ron.mercer@qlogic.com>

From: Ron Mercer <ron.mercer@qlogic.com>
Date: Fri, 16 Oct 2009 13:15:33 -0700

> These patches are interdependent.

No, Ron, they are absolutely not.

Apply the first patch, and that breaks the build because
you've removed LARGE_BUFFER_SIZE but it's still referenced
in qlge_main.c, and there are tons of other breakages too.

Don't send me garbage like this and then claim it's a set
of independent patches.  A trivial build test would have
shown otherwise, but you obviously didn't do that.

This is completely rediculious:

  CC [M]  drivers/net/qlge/qlge_main.o
drivers/net/qlge/qlge_main.c: In function ‘ql_update_lbq’:
drivers/net/qlge/qlge_main.c:1081: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1085: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1086: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1093: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1098: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1099: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c: In function ‘ql_build_rx_skb’:
drivers/net/qlge/qlge_main.c:1491: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1496: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1518: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1524: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1584: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:1590: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c: In function ‘ql_free_lbq_buffers’:
drivers/net/qlge/qlge_main.c:2313: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:2319: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c:2320: error: ‘union <anonymous>’ has no member named ‘lbq_page’
drivers/net/qlge/qlge_main.c: In function ‘ql_configure_rings’:
drivers/net/qlge/qlge_main.c:3546: error: ‘LARGE_BUFFER_SIZE’ undeclared (first use in this function)
drivers/net/qlge/qlge_main.c:3546: error: (Each undeclared identifier is reported only once
drivers/net/qlge/qlge_main.c:3546: error: for each function it appears in.)
make[3]: *** [drivers/net/qlge/qlge_main.o] Error 1
make[2]: *** [drivers/net/qlge] Error 2
make[1]: *** [drivers/net] Error 2
make: *** [drivers] Error 2
make: *** Waiting for unfinished jobs....

^ permalink raw reply

* Re: [Pv-drivers] [PATCH -next] vmxnet3: use dev_dbg, fix build for CONFIG_BLOCK=n
From: David Miller @ 2009-10-17  0:54 UTC (permalink / raw)
  To: bhavesh; +Cc: randy.dunlap, sfr, pv-drivers, netdev, linux-kernel, linux-next
In-Reply-To: <8B1F619C9F5F454E81D90D3C161698D7017DD56435@EXCH-MBX-3.vmware.com>

From: Bhavesh Davda <bhavesh@vmware.com>
Date: Thu, 15 Oct 2009 15:35:02 -0700

> Who ever compiles with CONFIG_BLOCK=n? Just kidding...

Who ever uses block layer debugging facilities in a networking
driver?

> Thanks again for making this change! Ship it!
> 
> Signed-off-by: Bhavesh Davda <bhavesh@vmware.com>

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCH NEXT 1/7] netxen; update version to 4.0.56
From: David Miller @ 2009-10-17  0:56 UTC (permalink / raw)
  To: dhananjay; +Cc: netdev
In-Reply-To: <1255673353-31797-2-git-send-email-dhananjay@netxen.com>

From: Dhananjay Phadke <dhananjay@netxen.com>
Date: Thu, 15 Oct 2009 23:09:07 -0700

> Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>

This doesn't make any sense at all.

You should update the driver version _AFTER_ your set
of changes, not before.

I have never in my entire life seen someone bump the
driver version before the actual changes.

Please respin this properly, thanks.

^ permalink raw reply

* Re: [PATCH net-next-2.6] be2net: Add support for next generation of BladeEngine device.
From: David Miller @ 2009-10-17  1:02 UTC (permalink / raw)
  To: ajitk; +Cc: netdev
In-Reply-To: <20091015045654.GA26219@serverengines.com>

From: Ajit Khaparde <ajitk@serverengines.com>
Date: Thu, 15 Oct 2009 10:27:13 +0530

> Add new PCI ids to support next generation of BladeEngine device.
> 
> Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>

Applied.

^ permalink raw reply

* RE: [PATCH NEXT 1/7] netxen; update version to 4.0.56
From: Dhananjay Phadke @ 2009-10-17  1:15 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20091016.175621.76312736.davem@davemloft.net>

Alright, this was really marker for earlier patch series.

But I will re-spin to even higher rev, use it as marker everything upto this patch series.

Thanks,
Dhananjay

-----Original Message-----
From: David Miller [mailto:davem@davemloft.net] 
Sent: Friday, October 16, 2009 5:56 PM
To: Dhananjay Phadke
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH NEXT 1/7] netxen; update version to 4.0.56

From: Dhananjay Phadke <dhananjay@netxen.com>
Date: Thu, 15 Oct 2009 23:09:07 -0700

> Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>

This doesn't make any sense at all.

You should update the driver version _AFTER_ your set
of changes, not before.

I have never in my entire life seen someone bump the
driver version before the actual changes.

Please respin this properly, thanks.

^ permalink raw reply

* [PATCH NEXT v2 0/7] netxen: changes for future chip revisions
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev

Update patch series for initial support for next chip revision.
The version is updated 4.0.62 to include all patches in this
series.

Please apply to net-next-2.6 tree.

Thanks,
	Dhananjay



^ permalink raw reply

* [PATCH NEXT v2 2/7] netxen: 128 memory controller support
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, Amit Kumar Salecha, Amit Kumar Salecha
In-Reply-To: <1255744212-28074-1-git-send-email-dhananjay@netxen.com>

From: Amit Kumar Salecha <amit@qlogic.com>

Future revisions of the chip have 128 bit memory
transactions. Require drivers to implement rmw
in case of sub-128 bit accesses by driver. This
is mostly used by diagnostic tools.

Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic_hdr.h |    8 ++++-
 drivers/net/netxen/netxen_nic_hw.c  |   55 +++++++++++++++++++++++++++++-----
 2 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 3461350..d40fe33 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -678,10 +678,14 @@ enum {
 #define MIU_TEST_AGT_ADDR_HI		(0x08)
 #define MIU_TEST_AGT_WRDATA_LO		(0x10)
 #define MIU_TEST_AGT_WRDATA_HI		(0x14)
-#define MIU_TEST_AGT_WRDATA(i)		(0x10+(4*(i)))
+#define MIU_TEST_AGT_WRDATA_UPPER_LO	(0x20)
+#define MIU_TEST_AGT_WRDATA_UPPER_HI	(0x24)
+#define MIU_TEST_AGT_WRDATA(i)		(0x10+(0x10*((i)>>1))+(4*((i)&1)))
 #define MIU_TEST_AGT_RDDATA_LO		(0x18)
 #define MIU_TEST_AGT_RDDATA_HI		(0x1c)
-#define MIU_TEST_AGT_RDDATA(i)		(0x18+(4*(i)))
+#define MIU_TEST_AGT_RDDATA_UPPER_LO	(0x28)
+#define MIU_TEST_AGT_RDDATA_UPPER_HI	(0x2c)
+#define MIU_TEST_AGT_RDDATA(i)		(0x18+(0x10*((i)>>1))+(4*((i)&1)))
 
 #define MIU_TEST_AGT_ADDR_MASK		0xfffffff8
 #define MIU_TEST_AGT_UPPER_ADDR(off)	(0)
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index d067bee..52a2f2d 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1569,8 +1569,9 @@ static int
 netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 		u64 off, u64 data)
 {
-	int j, ret;
+	int i, j, ret;
 	u32 temp, off8;
+	u64 stride;
 	void __iomem *mem_crb;
 
 	/* Only 64-bit aligned access */
@@ -1597,14 +1598,45 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 	return -EIO;
 
 correct:
-	off8 = off & MIU_TEST_AGT_ADDR_MASK;
+	stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
+
+	off8 = off & ~(stride-1);
 
 	spin_lock(&adapter->ahw.mem_lock);
 
 	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
 	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
-	writel(data & 0xffffffff, mem_crb + MIU_TEST_AGT_WRDATA_LO);
-	writel((data >> 32) & 0xffffffff, mem_crb + MIU_TEST_AGT_WRDATA_HI);
+
+	i = 0;
+	if (stride == 16) {
+		writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
+		writel((TA_CTL_START | TA_CTL_ENABLE),
+				(mem_crb + TEST_AGT_CTRL));
+
+		for (j = 0; j < MAX_CTL_CHECK; j++) {
+			temp = readl(mem_crb + TEST_AGT_CTRL);
+			if ((temp & TA_CTL_BUSY) == 0)
+				break;
+		}
+
+		if (j >= MAX_CTL_CHECK) {
+			ret = -EIO;
+			goto done;
+		}
+
+		i = (off & 0xf) ? 0 : 2;
+		writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)),
+				mem_crb + MIU_TEST_AGT_WRDATA(i));
+		writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)),
+				mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+		i = (off & 0xf) ? 2 : 0;
+	}
+
+	writel(data & 0xffffffff,
+			mem_crb + MIU_TEST_AGT_WRDATA(i));
+	writel((data >> 32) & 0xffffffff,
+			mem_crb + MIU_TEST_AGT_WRDATA(i+1));
+
 	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
 	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
 			(mem_crb + TEST_AGT_CTRL));
@@ -1623,6 +1655,7 @@ correct:
 	} else
 		ret = 0;
 
+done:
 	spin_unlock(&adapter->ahw.mem_lock);
 
 	return ret;
@@ -1634,7 +1667,7 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 {
 	int j, ret;
 	u32 temp, off8;
-	u64 val;
+	u64 val, stride;
 	void __iomem *mem_crb;
 
 	/* Only 64-bit aligned access */
@@ -1663,7 +1696,9 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 	return -EIO;
 
 correct:
-	off8 = off & MIU_TEST_AGT_ADDR_MASK;
+	stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
+
+	off8 = off & ~(stride-1);
 
 	spin_lock(&adapter->ahw.mem_lock);
 
@@ -1684,9 +1719,13 @@ correct:
 					"failed to read through agent\n");
 		ret = -EIO;
 	} else {
-		temp = readl(mem_crb + MIU_TEST_AGT_RDDATA_HI);
+		off8 = MIU_TEST_AGT_RDDATA_LO;
+		if ((stride == 16) && (off & 0xf))
+			off8 = MIU_TEST_AGT_RDDATA_UPPER_LO;
+
+		temp = readl(mem_crb + off8 + 4);
 		val = (u64)temp << 32;
-		val |= readl(mem_crb + MIU_TEST_AGT_RDDATA_LO);
+		val |= readl(mem_crb + off8);
 		*data = val;
 		ret = 0;
 	}
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT v2 3/7] netxen: reset sequence changes
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, Amit Kumar Salecha, Amit Kumar Salecha
In-Reply-To: <1255744212-28074-1-git-send-email-dhananjay@netxen.com>

From: Amit Kumar Salecha <amit@qlogic.com>

Future revisions need different chip reset sequence
and firmware initialization.

Also clean up some never used debug code.

Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |    2 +-
 drivers/net/netxen/netxen_nic_init.c |   41 +++++++++++----------------------
 drivers/net/netxen/netxen_nic_main.c |    2 +-
 3 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index a608e25..db28f8a 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1270,7 +1270,7 @@ int netxen_load_firmware(struct netxen_adapter *adapter);
 int netxen_need_fw_reset(struct netxen_adapter *adapter);
 void netxen_request_firmware(struct netxen_adapter *adapter);
 void netxen_release_firmware(struct netxen_adapter *adapter);
-int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
+int netxen_pinit_from_rom(struct netxen_adapter *adapter);
 
 int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
 int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 83387c7..a524844 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -437,7 +437,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
 #define NETXEN_BOARDNUM 		0x400c
 #define NETXEN_CHIPNUM			0x4010
 
-int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
+int netxen_pinit_from_rom(struct netxen_adapter *adapter)
 {
 	int addr, val;
 	int i, n, init_delay = 0;
@@ -450,21 +450,6 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 	NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
 	netxen_rom_unlock(adapter);
 
-	if (verbose) {
-		if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)
-			printk("P2 ROM board type: 0x%08x\n", val);
-		else
-			printk("Could not read board type\n");
-		if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0)
-			printk("P2 ROM board  num: 0x%08x\n", val);
-		else
-			printk("Could not read board number\n");
-		if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0)
-			printk("P2 ROM chip   num: 0x%08x\n", val);
-		else
-			printk("Could not read chip number\n");
-	}
-
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
 		if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
 			(n != 0xcafecafe) ||
@@ -486,11 +471,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 		n &= ~0x80000000;
 	}
 
-	if (n < 1024) {
-		if (verbose)
-			printk(KERN_DEBUG "%s: %d CRB init values found"
-			       " in ROM.\n", netxen_nic_driver_name, n);
-	} else {
+	if (n >= 1024) {
 		printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not"
 		       " initialized.\n", __func__, n);
 		return -EIO;
@@ -502,6 +483,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 				netxen_nic_driver_name);
 		return -ENOMEM;
 	}
+
 	for (i = 0; i < n; i++) {
 		if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
 		netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
@@ -512,11 +494,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 		buf[i].addr = addr;
 		buf[i].data = val;
 
-		if (verbose)
-			printk(KERN_DEBUG "%s: PCI:     0x%08x == 0x%08x\n",
-				netxen_nic_driver_name,
-				(u32)netxen_decode_crb_addr(addr), val);
 	}
+
 	for (i = 0; i < n; i++) {
 
 		off = netxen_decode_crb_addr(buf[i].addr);
@@ -526,6 +505,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 			continue;
 		}
 		off += NETXEN_PCI_CRBSPACE;
+
+		if (off & 1)
+			continue;
+
 		/* skipping cold reboot MAGIC */
 		if (off == NETXEN_CAM_RAM(0x1fc))
 			continue;
@@ -542,7 +525,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 				continue;
 			if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
 				continue;
-			if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
+			if (off == (NETXEN_CRB_PEG_NET_1 + 0x18) &&
+				!NX_IS_REVISION_P3P(adapter->ahw.revision_id))
 				buf[i].data = 0x1020;
 			/* skip the function enable register */
 			if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION))
@@ -751,7 +735,10 @@ netxen_load_firmware(struct netxen_adapter *adapter)
 	}
 	msleep(1);
 
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
+		NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x18, 0x1020);
+		NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001e);
+	} else if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
 	else {
 		NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 5bc8520..2d772dd 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -810,7 +810,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
 
 	if (first_boot != 0x55555555) {
 		NXWR32(adapter, CRB_CMDPEG_STATE, 0);
-		netxen_pinit_from_rom(adapter, 0);
+		netxen_pinit_from_rom(adapter);
 		msleep(1);
 	}
 
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT v2 6/7] netxen: sysfs control for auto firmware recovery
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, Narender Kumar
In-Reply-To: <1255744212-28074-1-git-send-email-dhananjay@netxen.com>

From: Narender Kumar <narender.kumar@qlogic.com>

Firmware hang detection and recovery (reset) need to
be disabled for diagnostic tools, which can run
some disruptive tests.

This adds a driver level control to turn off this
feature by diag tools.

Signed-off-by: Narender Kumar <narender.kumar@qlogic.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |    3 ++
 drivers/net/netxen/netxen_nic_main.c |   50 +++++++++++++++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index db28f8a..fa7511e 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1044,6 +1044,9 @@ typedef struct {
 #define LINKEVENT_LINKSPEED_MBPS	0
 #define LINKEVENT_LINKSPEED_ENCODED	1
 
+#define AUTO_FW_RESET_ENABLED	0xEF10AF12
+#define AUTO_FW_RESET_DISABLED	0xDCBAAF12
+
 /* firmware response header:
  *	63:58 - message type
  *	57:56 - owner
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 30d9afe..1071f09 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -52,6 +52,8 @@ static int use_msi = 1;
 
 static int use_msi_x = 1;
 
+static unsigned long auto_fw_reset = AUTO_FW_RESET_ENABLED;
+
 /* Local functions to NetXen NIC driver */
 static int __devinit netxen_nic_probe(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
@@ -2264,7 +2266,8 @@ netxen_check_health(struct netxen_adapter *adapter)
 	dev_info(&netdev->dev, "firmware hang detected\n");
 
 detach:
-	if (!test_and_set_bit(__NX_RESETTING, &adapter->state))
+	if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) &&
+			!test_and_set_bit(__NX_RESETTING, &adapter->state))
 		netxen_schedule_work(adapter, netxen_detach_work, 0);
 	return 1;
 }
@@ -2496,6 +2499,41 @@ static struct bin_attribute bin_attr_mem = {
 	.write = netxen_sysfs_write_mem,
 };
 
+static ssize_t
+netxen_store_auto_fw_reset(struct module_attribute *mattr,
+		struct module *mod, const char *buf, size_t count)
+
+{
+	unsigned long new;
+
+	if (strict_strtoul(buf, 16, &new))
+		return -EINVAL;
+
+	if ((new == AUTO_FW_RESET_ENABLED) || (new == AUTO_FW_RESET_DISABLED)) {
+		auto_fw_reset = new;
+		return count;
+	}
+
+	return -EINVAL;
+}
+
+static ssize_t
+netxen_show_auto_fw_reset(struct module_attribute *mattr,
+		struct module *mod, char *buf)
+
+{
+	if (auto_fw_reset == AUTO_FW_RESET_ENABLED)
+		return sprintf(buf, "enabled\n");
+	else
+		return sprintf(buf, "disabled\n");
+}
+
+static struct module_attribute mod_attr_fw_reset = {
+	.attr = {.name = "auto_fw_reset", .mode = (S_IRUGO | S_IWUSR)},
+	.show = netxen_show_auto_fw_reset,
+	.store = netxen_store_auto_fw_reset,
+};
+
 static void
 netxen_create_sysfs_entries(struct netxen_adapter *adapter)
 {
@@ -2700,6 +2738,8 @@ static struct pci_driver netxen_driver = {
 
 static int __init netxen_init_module(void)
 {
+	struct module *mod = THIS_MODULE;
+
 	printk(KERN_INFO "%s\n", netxen_nic_driver_string);
 
 #ifdef CONFIG_INET
@@ -2707,6 +2747,10 @@ static int __init netxen_init_module(void)
 	register_inetaddr_notifier(&netxen_inetaddr_cb);
 #endif
 
+	if (sysfs_create_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr))
+		printk(KERN_ERR "%s: Failed to create auto_fw_reset "
+				"sysfs entry.", netxen_nic_driver_name);
+
 	return pci_register_driver(&netxen_driver);
 }
 
@@ -2714,6 +2758,10 @@ module_init(netxen_init_module);
 
 static void __exit netxen_exit_module(void)
 {
+	struct module *mod = THIS_MODULE;
+
+	sysfs_remove_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr);
+
 	pci_unregister_driver(&netxen_driver);
 
 #ifdef CONFIG_INET
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT v2 1/7] netxen: defines for next revision
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, Amit Kumar Salecha, Amit Kumar Salecha
In-Reply-To: <1255744212-28074-1-git-send-email-dhananjay@netxen.com>

From: Amit Kumar Salecha <amit@qlogic.com>

Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 1bdb8f4..a608e25 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -117,9 +117,11 @@
 #define NX_P3_B0		0x40
 #define NX_P3_B1		0x41
 #define NX_P3_B2		0x42
+#define NX_P3P_A0		0x50
 
 #define NX_IS_REVISION_P2(REVISION)     (REVISION <= NX_P2_C1)
 #define NX_IS_REVISION_P3(REVISION)     (REVISION >= NX_P3_A0)
+#define NX_IS_REVISION_P3P(REVISION)     (REVISION >= NX_P3P_A0)
 
 #define FIRST_PAGE_GROUP_START	0
 #define FIRST_PAGE_GROUP_END	0x100000
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT v2 4/7] netxen: onchip memory access change
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev, Amit Kumar Salecha
In-Reply-To: <1255744212-28074-1-git-send-email-dhananjay@netxen.com>

From: Amit Kumar Salecha <amit@netxen.com>

Add support for different windowing scheme for on chip
memory in future chip revisions. This is required by
diagnostic tools.

Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic_hdr.h  |    3 +++
 drivers/net/netxen/netxen_nic_hw.c   |   17 +++++++++--------
 drivers/net/netxen/netxen_nic_main.c |    6 +++++-
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index d40fe33..7386a7c 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -867,6 +867,9 @@ enum {
 		(PCIX_SN_WINDOW_F0 + (0x20 * (func))) :\
 		(PCIX_SN_WINDOW_F4 + (0x10 * ((func)-4))))
 
+#define PCIX_OCM_WINDOW		(0x10800)
+#define PCIX_OCM_WINDOW_REG(func)	(PCIX_OCM_WINDOW + 0x20 * (func))
+
 #define PCIX_TARGET_STATUS	(0x10118)
 #define PCIX_TARGET_STATUS_F1	(0x10160)
 #define PCIX_TARGET_STATUS_F2	(0x10164)
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 52a2f2d..a633246 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -31,6 +31,7 @@
 #define MASK(n) ((1ULL<<(n))-1)
 #define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
 #define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
+#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
 #define MS_WIN(addr) (addr & 0x0ffc0000)
 
 #define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
@@ -1338,7 +1339,7 @@ static int
 netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 		u64 addr, u32 *start)
 {
-	u32 win_read, window;
+	u32 window;
 	struct pci_dev *pdev = adapter->pdev;
 
 	if ((addr & 0x00ff800) == 0xff800) {
@@ -1347,14 +1348,14 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 		return -EIO;
 	}
 
-	window = OCM_WIN(addr);
+	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id))
+		window = OCM_WIN_P3P(addr);
+	else
+		window = OCM_WIN(addr);
+
 	writel(window, adapter->ahw.ocm_win_crb);
-	win_read = readl(adapter->ahw.ocm_win_crb);
-	if ((win_read >> 7) != window) {
-		if (printk_ratelimit())
-			dev_warn(&pdev->dev, "failed to set OCM window\n");
-		return -EIO;
-	}
+	/* read back to flush */
+	readl(adapter->ahw.ocm_win_crb);
 
 	adapter->ahw.ocm_win = window;
 	*start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 2d772dd..30d9afe 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -649,7 +649,11 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 	adapter->ahw.pci_base1 = mem_ptr1;
 	adapter->ahw.pci_base2 = mem_ptr2;
 
-	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
+		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
+			NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func)));
+
+	} else if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
 		adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter,
 			NETXEN_PCIX_PS_REG(PCIE_MN_WINDOW_REG(pci_func)));
 	}
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT v2 5/7] netxen: fix error codes in for tools access
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <1255744212-28074-1-git-send-email-dhananjay@netxen.com>

Use -EIO or -EINVAL as error codes, these can get passed up
to applications (tools).

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic_hw.c   |   49 +++++++++++++++++----------------
 drivers/net/netxen/netxen_nic_init.c |    6 ++++
 2 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index a633246..e43cbbd 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -332,7 +332,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
 		if (done == 1)
 			break;
 		if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT)
-			return -1;
+			return -EIO;
 		msleep(1);
 	}
 
@@ -1083,7 +1083,7 @@ netxen_nic_pci_set_crbwindow_128M(struct netxen_adapter *adapter,
 }
 
 /*
- * Return -1 if off is not valid,
+ * Returns < 0 if off is not valid,
  *	 1 if window access is needed. 'off' is set to offset from
  *	   CRB space in 128M pci map
  *	 0 if no window access is needed. 'off' is set to 2M addr
@@ -1096,7 +1096,7 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
 
 
 	if (*off >= NETXEN_CRB_MAX)
-		return -1;
+		return -EINVAL;
 
 	if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) {
 		*off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
@@ -1105,7 +1105,7 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
 	}
 
 	if (*off < NETXEN_PCI_CRBSPACE)
-		return -1;
+		return -EINVAL;
 
 	*off -= NETXEN_PCI_CRBSPACE;
 
@@ -1220,25 +1220,26 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
 
 	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
 
-	if (rv == -1) {
-		printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
-				__func__, off);
-		dump_stack();
-		return -1;
+	if (rv == 0) {
+		writel(data, (void __iomem *)off);
+		return 0;
 	}
 
-	if (rv == 1) {
+	if (rv > 0) {
+		/* indirect access */
 		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
 		crb_win_lock(adapter);
 		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
 		writel(data, (void __iomem *)off);
 		crb_win_unlock(adapter);
 		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
-	} else
-		writel(data, (void __iomem *)off);
-
+		return 0;
+	}
 
-	return 0;
+	dev_err(&adapter->pdev->dev,
+			"%s: invalid offset: 0x%016lx\n", __func__, off);
+	dump_stack();
+	return -EIO;
 }
 
 static u32
@@ -1250,24 +1251,24 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
 
 	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
 
-	if (rv == -1) {
-		printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
-				__func__, off);
-		dump_stack();
-		return -1;
-	}
+	if (rv == 0)
+		return readl((void __iomem *)off);
 
-	if (rv == 1) {
+	if (rv > 0) {
+		/* indirect access */
 		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
 		crb_win_lock(adapter);
 		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
 		data = readl((void __iomem *)off);
 		crb_win_unlock(adapter);
 		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
-	} else
-		data = readl((void __iomem *)off);
+		return data;
+	}
 
-	return data;
+	dev_err(&adapter->pdev->dev,
+			"%s: invalid offset: 0x%016lx\n", __func__, off);
+	dump_stack();
+	return -1;
 }
 
 /* window 1 registers only */
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index a524844..d8c4b70 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -832,6 +832,12 @@ void netxen_request_firmware(struct netxen_adapter *adapter)
 		goto request_fw;
 	}
 
+	if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) {
+		/* No file firmware for the time being */
+		fw_type = NX_FLASH_ROMIMAGE;
+		goto done;
+	}
+
 	fw_type = netxen_p3_has_mn(adapter) ?
 		NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE;
 
-- 
1.6.0.2


^ permalink raw reply related

* [PATCH NEXT v2 7/7] netxen; update version to 4.0.62
From: Dhananjay Phadke @ 2009-10-17  1:50 UTC (permalink / raw)
  To: davem; +Cc: netdev
In-Reply-To: <1255744212-28074-1-git-send-email-dhananjay@netxen.com>

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index fa7511e..e98cfa6 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -53,8 +53,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 50
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.50"
+#define _NETXEN_NIC_LINUX_SUBVERSION 62
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.62"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
-- 
1.6.0.2


^ permalink raw reply related

* Re: [net-next PATCH 0/3] qlge: Size RX buffers based on MTU.
From: Ron Mercer @ 2009-10-17  2:22 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20091016.175142.52482970.davem@davemloft.net>

On Fri, Oct 16, 2009 at 05:51:42PM -0700, David Miller wrote:
> From: Ron Mercer <ron.mercer@qlogic.com>
> Date: Fri, 16 Oct 2009 13:15:33 -0700
> 
> > These patches are interdependent.
> 
> No, Ron, they are absolutely not.
> 
> Apply the first patch, and that breaks the build because
> you've removed LARGE_BUFFER_SIZE but it's still referenced
> in qlge_main.c, and there are tons of other breakages too.
> 
> Don't send me garbage like this and then claim it's a set
> of independent patches.  A trivial build test would have
> shown otherwise, but you obviously didn't do that.
> 
> This is completely rediculious:

Hi Dave,

Sorry for the confusion.  I said they were 'interdependent' patches, meaning
"depending on each other".  I was trying to break this up to
make it easier to review.  Shall I send it as a single patch?

Thanks,
Ron



^ permalink raw reply


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