* Re: [PATCH 2/6] [NET]: Take dev_base_lock when moving device name hash list entry
From: David Miller @ 2007-07-30 23:36 UTC (permalink / raw)
To: herbert; +Cc: netdev, kaber
In-Reply-To: <E1IDzLe-0000A4-00@gondolin.me.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 26 Jul 2007 17:09:30 +0800
> [NET]: Take dev_base_lock when moving device name hash list entry
>
> When we added name-based hashing the dev_base_lock was designated as the
> lock to take when changing the name hash list. Unfortunately, because
> it was a preexisting lock that just happened to be taken in the right
> spots we neglected to take it in dev_change_name.
>
> The race can affect calles of __dev_get_by_name that do so without taking
> the RTNL. They may end up walking down the wrong hash chain and end up
> missing the device that they're looking for.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Good catch, applied, thanks Herbert.
^ permalink raw reply
* Re: [PATCH 1/6] [NET]: Call uninit if necessary in register_netdevice
From: David Miller @ 2007-07-30 23:29 UTC (permalink / raw)
To: herbert; +Cc: netdev, kaber
In-Reply-To: <E1IDzLI-00009i-00@gondolin.me.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 26 Jul 2007 17:09:08 +0800
> [NET]: Call uninit if necessary in register_netdevice
>
> This patch makes register_netdevice call dev->uninit if the regsitration
> fails after dev->init has completed successfully. Very few drivers use
> the init/uninit calls but at least one (drivers/net/wan/sealevel.c) may
> leak without this change.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Looks great, applied.
^ permalink raw reply
* Re: [IPVS]: Use skb_forward_csum
From: David Miller @ 2007-07-30 23:25 UTC (permalink / raw)
To: herbert; +Cc: netdev, horms
In-Reply-To: <20070726085939.GA442@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 26 Jul 2007 16:59:39 +0800
> [IPVS]: Use skb_forward_csum
>
> As a path that forwards packets, IPVS should be using
> skb_forward_csum instead of directly setting ip_summed
> to CHECKSUM_NONE.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Patch applied, thanks Herbert.
^ permalink raw reply
* Re: [PATCH] pktgen - define and use pktgen_dbg,err,warn,info
From: David Miller @ 2007-07-30 23:05 UTC (permalink / raw)
To: joe; +Cc: Robert.Olsson, netdev
In-Reply-To: <1184800861.5863.54.camel@localhost>
From: Joe Perches <joe@perches.com>
Date: Wed, 18 Jul 2007 16:21:00 -0700
> On Wed, 2007-07-18 at 15:49 -0700, David Miller wrote:
> > From: Joe Perches <joe@perches.com>
> > Date: Wed, 18 Jul 2007 15:14:13 -0700
> >
> > > -#define VERSION "pktgen v2.68: Packet Generator for packet performance testing.\n"
> > > +#define PKTGEN_NAME "pktgen"
> > > +#define PKTGEN_VERSION "v2.68"
> > > +#define PKTGEN_DESC "Packet Generator for packet performance testing"
> > > +#define PKTGEN_FULLINFO PKTGEN_NAME " " PKTGEN_VERSION ": " PKTGEN_DESC ".\n"
> > ...
> >
> > > -static char version[] __initdata = VERSION;
> > > -
> >
> > Using PKTGEN_FULLINFO explicitly won't get that string into the
> > __initdata section as the version[] will, that's why people do it that
> > way with the explicit version[] array.
> >
> > Please put it back, assign PKTGEN_FULLINFO to it, and use it.
>
> Done. Here you are.
>
> fyi:
> pktgen_info(version) fails compile,
> pktgen_info("%s", version) works.
I still don't know about this patch. Instead of the simple
transformation:
- printk(foo);
+ printk(KERN_INFO foo);
we get this new macro, and the lines changes to use that macro.
It seems very over-engineered and adds ifdefs to a foo.c file
which is severly frowned upon.
I'm going to add the needed KERN_* to pktgen.c, that's just so
much nicer a way to handle this.
^ permalink raw reply
* Re: [PATCH RFC]: napi_struct V4
From: David Miller @ 2007-07-30 22:48 UTC (permalink / raw)
To: rdreier; +Cc: netdev, shemminger, jgarzik, hadi, rusty
In-Reply-To: <ada7ioiszk7.fsf@cisco.com>
From: Roland Dreier <rdreier@cisco.com>
Date: Mon, 30 Jul 2007 08:04:24 -0700
> IPoIB can cope but it really seems like an unfortunate feature of
> these changes that we can't do something like what we have today,
> which imposes no overhead unless an event actually lands in the race
> window.
It is not a feature of these changes.
These races exist in the current code, it is a bug fix.
^ permalink raw reply
* Re: [git patches] net driver fixes
From: Satyam Sharma @ 2007-07-30 22:57 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Andrew Morton, Linus Torvalds, netdev, LKML, Petko Manolov
In-Reply-To: <46AE6861.50004@garzik.org>
On Mon, 30 Jul 2007, Jeff Garzik wrote:
> true, we should just remove the dev==NULL check
Patch below:
[PATCH] nmclan_cs: Remove bogus (dev==NULL) check in mace_interrupt()
The (dev == NULL) check in drivers/net/pcmcia/nmclan_cs.c:mace_interrupt()
handler is always false, so let's remove it.
Signed-off-by: Satyam Sharma <satyam@infradead.org>
---
drivers/net/pcmcia/nmclan_cs.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 73da611..3446be9 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -1000,12 +1000,6 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
int status;
int IntrCnt = MACE_MAX_IR_ITERATIONS;
- if (dev == NULL) {
- DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
- irq);
- return IRQ_NONE;
- }
-
if (lp->tx_irq_disabled) {
printk(
(lp->tx_irq_disabled?
^ permalink raw reply related
* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: David Miller @ 2007-07-30 22:43 UTC (permalink / raw)
To: jeff
Cc: ossthema, netdev, raisch, themann, linux-kernel, linuxppc-dev,
meder, tklein, stefan.roscher, gallatin
In-Reply-To: <46AE0F36.8030605@garzik.org>
From: Jeff Garzik <jeff@garzik.org>
Date: Mon, 30 Jul 2007 12:17:58 -0400
> David, thoughts on merging? I'm not We could stick this into your tree
> or mine. Whether yours or mine, I would like to keep the driver and
> net-core patches together in the same git tree.
No objections and I'll stick it into my net-2.6.24 tree once I cut
that, I'll have the NAPI stuff in there too so I'll keep these two
merge nightmares out of your hair :-)
^ permalink raw reply
* Re: [git patches] net driver fixes
From: Jeff Garzik @ 2007-07-30 22:38 UTC (permalink / raw)
To: Satyam Sharma; +Cc: Andrew Morton, Linus Torvalds, netdev, LKML, Petko Manolov
In-Reply-To: <alpine.LFD.0.999.0707310349460.17287@enigma.security.iitk.ac.in>
true, we should just remove the dev==NULL check
^ permalink raw reply
* Re: [git patches] net driver fixes
From: Satyam Sharma @ 2007-07-30 22:36 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Andrew Morton, Linus Torvalds, netdev, LKML, Petko Manolov
In-Reply-To: <20070730212333.GA8049@havoc.gtf.org>
Hi Jeff,
On Mon, 30 Jul 2007, Jeff Garzik wrote:
> Fix a potential NULL pointer dereference in mace_interrupt() in drivers/net/pcmcia/nmclan_cs.c
This oops is _programmatically_ impossible (the only way it can occur
is if the kernel has gone bazooka already anyway ...)
[ BTW even if it were possible, we haven't fixed it still ...
note the use of the netdev_priv() before the (dev == NULL)
check in the function below ... ]
> diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
> index 73da611..997c2d0 100644
> --- a/drivers/net/pcmcia/nmclan_cs.c
> +++ b/drivers/net/pcmcia/nmclan_cs.c
> @@ -996,7 +996,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
> {
> struct net_device *dev = (struct net_device *) dev_id;
> mace_private *lp = netdev_priv(dev);
> - kio_addr_t ioaddr = dev->base_addr;
> + kio_addr_t ioaddr;
> int status;
> int IntrCnt = MACE_MAX_IR_ITERATIONS;
>
> @@ -1006,6 +1006,8 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
> return IRQ_NONE;
> }
>
> + ioaddr = dev->base_addr;
> +
> if (lp->tx_irq_disabled) {
> printk(
> (lp->tx_irq_disabled?
I suggest we should just get rid of the (bogus, always false) dev == NULL
check itself, instead.
Will submit patch, in a bit ...
> Fix a potential NULL pointer dereference in write_bulk_callback() in drivers/net/usb/pegasus.c
Ditto, for this. Impossible oops. And if it does occur, the kernel would
have gone irrevocably mad already ...
> diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
> index a05fd97..04cba6b 100644
> --- a/drivers/net/usb/pegasus.c
> +++ b/drivers/net/usb/pegasus.c
> @@ -768,11 +768,13 @@ done:
> static void write_bulk_callback(struct urb *urb)
> {
> pegasus_t *pegasus = urb->context;
> - struct net_device *net = pegasus->net;
> + struct net_device *net;
>
> if (!pegasus)
> return;
>
> + net = pegasus->net;
> +
> if (!netif_device_present(net) || !netif_running(net))
> return;
Again, the (!pegasus) check is bogus (always false) and should be removed
instead. I believe the maintainer (CC'ed here) already has a patch for
exactly that.
Satyam
^ permalink raw reply
* Re: forcedeth ?
From: Gabriel C @ 2007-07-30 22:00 UTC (permalink / raw)
To: Sasa Ostrouska; +Cc: linux-kernel, netdev
In-Reply-To: <dcf706c60707301301j21d3cf60n59a686c9abb5e5b3@mail.gmail.com>
Sasa Ostrouska wrote:
[ added netdev to CC ]
> Hi people,
>
> I'm using this on a x86-64 amd machine. During boot of the last
> 2.6.22.1 kernel I get this error:
>
> fb0: VESA VGA frame buffer device
> Linux agpgart interface v0.102 (c) Dave Jones
> Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
> 00:0c: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
> Marvell 88E1101: Registered new driver
> Marvell 88E1111: Registered new driver
> Marvell 88E1145: Registered new driver
> Fixed PHY: Registered new driver
> Device 'fixed@100:1' does not have a release() function, it is broken
> and must be fixed.
> WARNING: at drivers/base/core.c:107 device_release()
>
> Call Trace:
> [<ffffffff802f16c8>] kobject_cleanup+0x52/0x70
> [<ffffffff802f16e6>] kobject_release+0x0/0x9
> [<ffffffff802f237a>] kref_put+0x74/0x82
> [<ffffffff8035c0be>] fixed_mdio_register_device+0x1f3/0x229
> [<ffffffff805884f6>] fixed_init+0x1f/0x35
> [<ffffffff80216e2d>] flat_send_IPI_mask+0x0/0x4c
> [<ffffffff80570910>] kernel_init+0x16f/0x2d5
> [<ffffffff8020a458>] child_rip+0xa/0x12
> [<ffffffff8031763c>] acpi_ds_init_one_object+0x0/0x7f
> [<ffffffff805707a1>] kernel_init+0x0/0x2d5
> [<ffffffff8020a44e>] child_rip+0x0/0x12
>
> Device 'fixed@10:1' does not have a release() function, it is broken
> and must be fixed.
> WARNING: at drivers/base/core.c:107 device_release()
>
> Call Trace:
> [<ffffffff802f16c8>] kobject_cleanup+0x52/0x70
> [<ffffffff802f16e6>] kobject_release+0x0/0x9
> [<ffffffff802f237a>] kref_put+0x74/0x82
> [<ffffffff8035c0be>] fixed_mdio_register_device+0x1f3/0x229
> [<ffffffff80588507>] fixed_init+0x30/0x35
> [<ffffffff80216e2d>] flat_send_IPI_mask+0x0/0x4c
> [<ffffffff80570910>] kernel_init+0x16f/0x2d5
> [<ffffffff8020a458>] child_rip+0xa/0x12
> [<ffffffff8031763c>] acpi_ds_init_one_object+0x0/0x7f
> [<ffffffff805707a1>] kernel_init+0x0/0x2d5
> [<ffffffff8020a44e>] child_rip+0x0/0x12
>
> forcedeth.c: Reverse Engineered nForce ethernet driver. Version 0.60.
> ACPI: PCI Interrupt Link [LMAC] enabled at IRQ 23
> ACPI: PCI Interrupt 0000:00:07.0[A] -> Link [LMAC] -> GSI 23 (level,
> low) -> IRQ 23
> PCI: Setting latency timer of device 0000:00:07.0 to 64
> forcedeth: using HIGHDMA
> eth0: forcedeth.c: subsystem: 01849:03ef bound to 0000:00:07.0
> netconsole: not configured, aborting
> Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
> ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
> NFORCE-MCP61: IDE controller at PCI slot 0000:00:06.0
>
> If somebody needs some additional info please cc me.
I got an Oops in 22-git++ with the fixed one but I don't have forcedeth.
There is a patch for it http://lkml.org/lkml/2007/7/18/506.
>
> Best Regards
> Sasa Ostrouska
Regards,
Gabriel C
^ permalink raw reply
* [git patches] net driver fixes
From: Jeff Garzik @ 2007-07-30 21:23 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML
All are fixes except the two "S2IO: Remove ...from the driver" patches,
which remove two unused features, and a couple doc patches.
Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus
to receive the following updates:
MAINTAINERS | 4 +-
drivers/net/forcedeth.c | 36 ++-
drivers/net/gianfar_mii.c | 2 +-
drivers/net/gianfar_mii.h | 2 +-
drivers/net/lib8390.c | 46 +++
drivers/net/netxen/netxen_nic_main.c | 44 ++--
drivers/net/pcmcia/nmclan_cs.c | 4 +-
drivers/net/pcmcia/smc91c92_cs.c | 23 +-
drivers/net/s2io-regs.h | 5 +-
drivers/net/s2io.c | 542 ++++++++++------------------------
drivers/net/s2io.h | 11 +-
drivers/net/usb/pegasus.c | 4 +-
12 files changed, 279 insertions(+), 444 deletions(-)
Ayaz Abdulla (1):
forcedeth: mac address correct
Dhananjay Phadke (1):
netxen: drop redudant spinlock
Jarek Poplawski (1):
lib8390: comment on locking by Alan Cox
Komuro (1):
PATCH kernel 2.6.22] PCMCIA-NETDEV : modify smc91c92_cs.c to become SMP safe
Kumar Gala (1):
gfar: Fix modpost warning
Micah Gruber (2):
Fix a potential NULL pointer dereference in write_bulk_callback() in drivers/net/usb/pegasus.c
Fix a potential NULL pointer dereference in mace_interrupt() in drivers/net/pcmcia/nmclan_cs.c
Ramkrishna Vepa (3):
S2io: Mask spurious interrupts
S2io: Fix crash when resetting adapter
S2io: Increment received packet count correctly
Valerie Henson (1):
tulip: Remove tulip maintainer
Veena Parat (4):
S2IO: Removing 3 buffer mode support from the driver
S2IO: Removing MSI support from driver
S2IO: Checking for the return value of pci map function
S2IO: Implementing review comments from old patches
dhananjay@netxen.com (2):
netxen: re-init station address after h/w init
netxen: Fix interrupt handling for multiport adapters
diff --git a/MAINTAINERS b/MAINTAINERS
index babd00b..5c784be 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3674,11 +3674,9 @@ W: http://www.auk.cx/tms380tr/
S: Maintained
TULIP NETWORK DRIVER
-P: Valerie Henson
-M: val@nmt.edu
L: tulip-users@lists.sourceforge.net
W: http://sourceforge.net/projects/tulip/
-S: Maintained
+S: Orphan
TUN/TAP driver
P: Maxim Krasnyansky
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 661c747..51e1cb4 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -178,6 +178,7 @@
#define DEV_HAS_STATISTICS_V2 0x0800 /* device supports hw statistics version 2 */
#define DEV_HAS_TEST_EXTENDED 0x1000 /* device supports extended diagnostic test */
#define DEV_HAS_MGMT_UNIT 0x2000 /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR 0x4000 /* device supports correct mac address order */
enum {
NvRegIrqStatus = 0x000,
@@ -5172,7 +5173,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
/* check the workaround bit for correct mac address order */
txreg = readl(base + NvRegTransmitPoll);
- if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
+ if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
+ (id->driver_data & DEV_HAS_CORRECT_MACADDR)) {
/* mac address is already in correct order */
dev->dev_addr[0] = (np->orig_mac[0] >> 0) & 0xff;
dev->dev_addr[1] = (np->orig_mac[0] >> 8) & 0xff;
@@ -5500,67 +5502,67 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{0,},
};
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index ac3596f..100bf41 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -245,7 +245,7 @@ int __init gfar_mdio_init(void)
return driver_register(&gianfar_mdio_driver);
}
-void __exit gfar_mdio_exit(void)
+void gfar_mdio_exit(void)
{
driver_unregister(&gianfar_mdio_driver);
}
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
index 5d34004..b373091 100644
--- a/drivers/net/gianfar_mii.h
+++ b/drivers/net/gianfar_mii.h
@@ -42,5 +42,5 @@ struct gfar_mii {
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int __init gfar_mdio_init(void);
-void __exit gfar_mdio_exit(void);
+void gfar_mdio_exit(void);
#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index 721ee38..c429a50 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -143,6 +143,52 @@ static void __NS8390_init(struct net_device *dev, int startp);
* annoying the transmit function is called bh atomic. That places
* restrictions on the user context callers as disable_irq won't save
* them.
+ *
+ * Additional explanation of problems with locking by Alan Cox:
+ *
+ * "The author (me) didn't use spin_lock_irqsave because the slowness of the
+ * card means that approach caused horrible problems like losing serial data
+ * at 38400 baud on some chips. Rememeber many 8390 nics on PCI were ISA
+ * chips with FPGA front ends.
+ *
+ * Ok the logic behind the 8390 is very simple:
+ *
+ * Things to know
+ * - IRQ delivery is asynchronous to the PCI bus
+ * - Blocking the local CPU IRQ via spin locks was too slow
+ * - The chip has register windows needing locking work
+ *
+ * So the path was once (I say once as people appear to have changed it
+ * in the mean time and it now looks rather bogus if the changes to use
+ * disable_irq_nosync_irqsave are disabling the local IRQ)
+ *
+ *
+ * Take the page lock
+ * Mask the IRQ on chip
+ * Disable the IRQ (but not mask locally- someone seems to have
+ * broken this with the lock validator stuff)
+ * [This must be _nosync as the page lock may otherwise
+ * deadlock us]
+ * Drop the page lock and turn IRQs back on
+ *
+ * At this point an existing IRQ may still be running but we can't
+ * get a new one
+ *
+ * Take the lock (so we know the IRQ has terminated) but don't mask
+ * the IRQs on the processor
+ * Set irqlock [for debug]
+ *
+ * Transmit (slow as ****)
+ *
+ * re-enable the IRQ
+ *
+ *
+ * We have to use disable_irq because otherwise you will get delayed
+ * interrupts on the APIC bus deadlocking the transmit path.
+ *
+ * Quite hairy but the chip simply wasn't designed for SMP and you can't
+ * even ACK an interrupt without risking corrupting other parallel
+ * activities on the chip." [lkml, 25 Jul 2007]
*/
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 19e2fa9..08a62ac 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -335,7 +335,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ahw.pdev = pdev;
adapter->ahw.pci_func = pci_func_id;
spin_lock_init(&adapter->tx_lock);
- spin_lock_init(&adapter->lock);
/* remap phys address */
mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
@@ -895,8 +894,6 @@ static int netxen_nic_open(struct net_device *netdev)
/* Done here again so that even if phantom sw overwrote it,
* we set it */
- if (adapter->macaddr_set)
- adapter->macaddr_set(adapter, netdev->dev_addr);
if (adapter->init_port
&& adapter->init_port(adapter, adapter->portnum) != 0) {
del_timer_sync(&adapter->watchdog_timer);
@@ -904,6 +901,8 @@ static int netxen_nic_open(struct net_device *netdev)
netxen_nic_driver_name, adapter->portnum);
return -EIO;
}
+ if (adapter->macaddr_set)
+ adapter->macaddr_set(adapter, netdev->dev_addr);
netxen_nic_set_link_parameters(adapter);
@@ -930,6 +929,8 @@ static int netxen_nic_close(struct net_device *netdev)
netif_carrier_off(netdev);
netif_stop_queue(netdev);
+ netxen_nic_disable_int(adapter);
+
cmd_buff = adapter->cmd_buf_arr;
for (i = 0; i < adapter->max_tx_desc_count; i++) {
buffrag = cmd_buff->frag_array;
@@ -1226,15 +1227,12 @@ static void netxen_tx_timeout_task(struct work_struct *work)
{
struct netxen_adapter *adapter =
container_of(work, struct netxen_adapter, tx_timeout_task);
- unsigned long flags;
printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
netxen_nic_driver_name, adapter->netdev->name);
- spin_lock_irqsave(&adapter->lock, flags);
netxen_nic_close(adapter->netdev);
netxen_nic_open(adapter->netdev);
- spin_unlock_irqrestore(&adapter->lock, flags);
adapter->netdev->trans_start = jiffies;
netif_wake_queue(adapter->netdev);
}
@@ -1243,28 +1241,12 @@ static int
netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
{
u32 ret = 0;
- u32 our_int = 0;
DPRINTK(INFO, "Entered handle ISR\n");
adapter->stats.ints++;
- if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
- our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
- /* not our interrupt */
- if ((our_int & (0x80 << adapter->portnum)) == 0)
- return ret;
- }
-
netxen_nic_disable_int(adapter);
- if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
- /* claim interrupt */
- if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
- writel(our_int & ~((u32)(0x80 << adapter->portnum)),
- NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
- }
- }
-
if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
if (netif_rx_schedule_prep(netdev)) {
/*
@@ -1298,6 +1280,7 @@ irqreturn_t netxen_intr(int irq, void *data)
{
struct netxen_adapter *adapter;
struct net_device *netdev;
+ u32 our_int = 0;
if (unlikely(!irq)) {
return IRQ_NONE; /* Not our interrupt */
@@ -1305,7 +1288,22 @@ irqreturn_t netxen_intr(int irq, void *data)
adapter = (struct netxen_adapter *)data;
netdev = adapter->netdev;
- /* process our status queue (for all 4 ports) */
+
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+ /* not our interrupt */
+ if ((our_int & (0x80 << adapter->portnum)) == 0)
+ return IRQ_NONE;
+ }
+
+ if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
+ /* claim interrupt */
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ writel(our_int & ~((u32)(0x80 << adapter->portnum)),
+ NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+ }
+ }
+
if (netif_running(netdev))
netxen_handle_int(adapter, netdev);
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 73da611..997c2d0 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -996,7 +996,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
mace_private *lp = netdev_priv(dev);
- kio_addr_t ioaddr = dev->base_addr;
+ kio_addr_t ioaddr;
int status;
int IntrCnt = MACE_MAX_IR_ITERATIONS;
@@ -1006,6 +1006,8 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
+ ioaddr = dev->base_addr;
+
if (lp->tx_irq_disabled) {
printk(
(lp->tx_irq_disabled?
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 7912dbd..af6728c 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1368,6 +1368,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
kio_addr_t ioaddr = dev->base_addr;
u_short num_pages;
short time_out, ir;
+ unsigned long flags;
netif_stop_queue(dev);
@@ -1395,6 +1396,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* A packet is now waiting. */
smc->packets_waiting++;
+ spin_lock_irqsave(&smc->lock, flags);
SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */
/* need MC_RESET to keep the memory consistent. errata? */
@@ -1411,6 +1413,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Acknowledge the interrupt, send the packet. */
outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT);
smc_hardware_send_packet(dev); /* Send the packet now.. */
+ spin_unlock_irqrestore(&smc->lock, flags);
return 0;
}
}
@@ -1418,6 +1421,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Otherwise defer until the Tx-space-allocated interrupt. */
DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
+ spin_unlock_irqrestore(&smc->lock, flags);
return 0;
}
@@ -1523,6 +1527,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
irq, ioaddr);
+ spin_lock(&smc->lock);
smc->watchdog = 0;
saved_bank = inw(ioaddr + BANK_SELECT);
if ((saved_bank & 0xff00) != 0x3300) {
@@ -1620,6 +1625,7 @@ irq_done:
readb(smc->base+MEGAHERTZ_ISR);
}
#endif
+ spin_unlock(&smc->lock);
return IRQ_RETVAL(handled);
}
@@ -1902,6 +1908,9 @@ static void media_check(u_long arg)
kio_addr_t ioaddr = dev->base_addr;
u_short i, media, saved_bank;
u_short link;
+ unsigned long flags;
+
+ spin_lock_irqsave(&smc->lock, flags);
saved_bank = inw(ioaddr + BANK_SELECT);
@@ -1934,6 +1943,7 @@ static void media_check(u_long arg)
smc->media.expires = jiffies + HZ/100;
add_timer(&smc->media);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irqrestore(&smc->lock, flags);
return;
}
@@ -2007,6 +2017,7 @@ reschedule:
smc->media.expires = jiffies + HZ;
add_timer(&smc->media);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irqrestore(&smc->lock, flags);
}
static int smc_link_ok(struct net_device *dev)
@@ -2094,14 +2105,14 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
u16 saved_bank = inw(ioaddr + BANK_SELECT);
int ret;
- SMC_SELECT_BANK(3);
spin_lock_irq(&smc->lock);
+ SMC_SELECT_BANK(3);
if (smc->cfg & CFG_MII_SELECT)
ret = mii_ethtool_gset(&smc->mii_if, ecmd);
else
ret = smc_netdev_get_ecmd(dev, ecmd);
- spin_unlock_irq(&smc->lock);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irq(&smc->lock);
return ret;
}
@@ -2112,14 +2123,14 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
u16 saved_bank = inw(ioaddr + BANK_SELECT);
int ret;
- SMC_SELECT_BANK(3);
spin_lock_irq(&smc->lock);
+ SMC_SELECT_BANK(3);
if (smc->cfg & CFG_MII_SELECT)
ret = mii_ethtool_sset(&smc->mii_if, ecmd);
else
ret = smc_netdev_set_ecmd(dev, ecmd);
- spin_unlock_irq(&smc->lock);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irq(&smc->lock);
return ret;
}
@@ -2130,11 +2141,11 @@ static u32 smc_get_link(struct net_device *dev)
u16 saved_bank = inw(ioaddr + BANK_SELECT);
u32 ret;
- SMC_SELECT_BANK(3);
spin_lock_irq(&smc->lock);
+ SMC_SELECT_BANK(3);
ret = smc_link_ok(dev);
- spin_unlock_irq(&smc->lock);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irq(&smc->lock);
return ret;
}
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 4cb710b..cfa2679 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -747,10 +747,9 @@ struct XENA_dev_config {
#define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23)
#define MC_ERR_REG_SM_ERR BIT(31)
#define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\
- BIT(6) | BIT(7) | BIT(17) | BIT(19))
+ BIT(17) | BIT(19))
#define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\
- BIT(13) | BIT(14) | BIT(15) |\
- BIT(18) | BIT(20))
+ BIT(13) | BIT(18) | BIT(20))
u64 mc_err_mask;
u64 mc_err_alarm;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index afef6c0..2be0a0f 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -32,12 +32,12 @@
* rx_ring_sz: This defines the number of receive blocks each ring can have.
* This is also an array of size 8.
* rx_ring_mode: This defines the operation mode of all 8 rings. The valid
- * values are 1, 2 and 3.
+ * values are 1, 2.
* tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver.
* tx_fifo_len: This too is an array of 8. Each element defines the number of
* Tx descriptors that can be associated with each corresponding FIFO.
* intr_type: This defines the type of interrupt. The values can be 0(INTA),
- * 1(MSI), 2(MSI_X). Default value is '0(INTA)'
+ * 2(MSI_X). Default value is '0(INTA)'
* lro: Specifies whether to enable Large Receive Offload (LRO) or not.
* Possible values '1' for enable '0' for disable. Default is '0'
* lro_max_pkts: This parameter defines maximum number of packets can be
@@ -84,14 +84,14 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.23.1"
+#define DRV_VERSION "2.0.25.1"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
static char s2io_driver_version[] = DRV_VERSION;
-static int rxd_size[4] = {32,48,48,64};
-static int rxd_count[4] = {127,85,85,63};
+static int rxd_size[2] = {32,48};
+static int rxd_count[2] = {127,85};
static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
{
@@ -282,6 +282,7 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
("lro_flush_due_to_max_pkts"),
("lro_avg_aggr_pkts"),
("mem_alloc_fail_cnt"),
+ ("pci_map_fail_cnt"),
("watchdog_timer_cnt"),
("mem_allocated"),
("mem_freed"),
@@ -426,7 +427,7 @@ S2IO_PARM_INT(bimodal, 0);
S2IO_PARM_INT(l3l4hdr_size, 128);
/* Frequency of Rx desc syncs expressed as power of 2 */
S2IO_PARM_INT(rxsync_frequency, 3);
-/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
+/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
S2IO_PARM_INT(intr_type, 0);
/* Large receive offload feature */
S2IO_PARM_INT(lro, 0);
@@ -701,7 +702,7 @@ static int init_shared_mem(struct s2io_nic *nic)
(u64) tmp_p_addr_next;
}
}
- if (nic->rxd_mode >= RXD_MODE_3A) {
+ if (nic->rxd_mode == RXD_MODE_3B) {
/*
* Allocation of Storages for buffer addresses in 2BUFF mode
* and the buffers as well.
@@ -870,7 +871,7 @@ static void free_shared_mem(struct s2io_nic *nic)
}
}
- if (nic->rxd_mode >= RXD_MODE_3A) {
+ if (nic->rxd_mode == RXD_MODE_3B) {
/* Freeing buffer storage addresses in 2BUFF mode. */
for (i = 0; i < config->rx_ring_num; i++) {
blk_cnt = config->rx_cfg[i].num_rxd /
@@ -2233,44 +2234,6 @@ static void stop_nic(struct s2io_nic *nic)
writeq(val64, &bar0->adapter_control);
}
-static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
- sk_buff *skb)
-{
- struct net_device *dev = nic->dev;
- struct sk_buff *frag_list;
- void *tmp;
-
- /* Buffer-1 receives L3/L4 headers */
- ((struct RxD3*)rxdp)->Buffer1_ptr = pci_map_single
- (nic->pdev, skb->data, l3l4hdr_size + 4,
- PCI_DMA_FROMDEVICE);
-
- /* skb_shinfo(skb)->frag_list will have L4 data payload */
- skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
- if (skb_shinfo(skb)->frag_list == NULL) {
- nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
- DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
- return -ENOMEM ;
- }
- frag_list = skb_shinfo(skb)->frag_list;
- skb->truesize += frag_list->truesize;
- nic->mac_control.stats_info->sw_stat.mem_allocated
- += frag_list->truesize;
- frag_list->next = NULL;
- tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
- frag_list->data = tmp;
- skb_reset_tail_pointer(frag_list);
-
- /* Buffer-2 receives L4 data payload */
- ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
- frag_list->data, dev->mtu,
- PCI_DMA_FROMDEVICE);
- rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
- rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
-
- return SUCCESS;
-}
-
/**
* fill_rx_buffers - Allocates the Rx side skbs
* @nic: device private variable
@@ -2307,6 +2270,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
unsigned long flags;
struct RxD_t *first_rxdp = NULL;
u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
+ struct RxD1 *rxdp1;
+ struct RxD3 *rxdp3;
+ struct swStat *stats = &nic->mac_control.stats_info->sw_stat;
mac_control = &nic->mac_control;
config = &nic->config;
@@ -2359,7 +2325,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
(block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
}
if ((rxdp->Control_1 & RXD_OWN_XENA) &&
- ((nic->rxd_mode >= RXD_MODE_3A) &&
+ ((nic->rxd_mode == RXD_MODE_3B) &&
(rxdp->Control_2 & BIT(0)))) {
mac_control->rings[ring_no].rx_curr_put_info.
offset = off;
@@ -2370,10 +2336,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
if (nic->rxd_mode == RXD_MODE_1)
size += NET_IP_ALIGN;
- else if (nic->rxd_mode == RXD_MODE_3B)
- size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
else
- size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
+ size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
/* allocate skb */
skb = dev_alloc_skb(size);
@@ -2392,33 +2356,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
+= skb->truesize;
if (nic->rxd_mode == RXD_MODE_1) {
/* 1 buffer mode - normal operation mode */
+ rxdp1 = (struct RxD1*)rxdp;
memset(rxdp, 0, sizeof(struct RxD1));
skb_reserve(skb, NET_IP_ALIGN);
- ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single
+ rxdp1->Buffer0_ptr = pci_map_single
(nic->pdev, skb->data, size - NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp1->Buffer0_ptr == 0) ||
+ (rxdp1->Buffer0_ptr ==
+ DMA_ERROR_CODE))
+ goto pci_map_failed;
+
rxdp->Control_2 =
SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
- } else if (nic->rxd_mode >= RXD_MODE_3A) {
+ } else if (nic->rxd_mode == RXD_MODE_3B) {
/*
- * 2 or 3 buffer mode -
- * Both 2 buffer mode and 3 buffer mode provides 128
+ * 2 buffer mode -
+ * 2 buffer mode provides 128
* byte aligned receive buffers.
- *
- * 3 buffer mode provides header separation where in
- * skb->data will have L3/L4 headers where as
- * skb_shinfo(skb)->frag_list will have the L4 data
- * payload
*/
+ rxdp3 = (struct RxD3*)rxdp;
/* save buffer pointers to avoid frequent dma mapping */
- Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
- Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
+ Buffer0_ptr = rxdp3->Buffer0_ptr;
+ Buffer1_ptr = rxdp3->Buffer1_ptr;
memset(rxdp, 0, sizeof(struct RxD3));
/* restore the buffer pointers for dma sync*/
- ((struct RxD3*)rxdp)->Buffer0_ptr = Buffer0_ptr;
- ((struct RxD3*)rxdp)->Buffer1_ptr = Buffer1_ptr;
+ rxdp3->Buffer0_ptr = Buffer0_ptr;
+ rxdp3->Buffer1_ptr = Buffer1_ptr;
ba = &mac_control->rings[ring_no].ba[block_no][off];
skb_reserve(skb, BUF0_LEN);
@@ -2428,14 +2394,18 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
skb->data = (void *) (unsigned long)tmp;
skb_reset_tail_pointer(skb);
- if (!(((struct RxD3*)rxdp)->Buffer0_ptr))
- ((struct RxD3*)rxdp)->Buffer0_ptr =
+ if (!(rxdp3->Buffer0_ptr))
+ rxdp3->Buffer0_ptr =
pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
PCI_DMA_FROMDEVICE);
else
pci_dma_sync_single_for_device(nic->pdev,
- (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
+ (dma_addr_t) rxdp3->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
+ if( (rxdp3->Buffer0_ptr == 0) ||
+ (rxdp3->Buffer0_ptr == DMA_ERROR_CODE))
+ goto pci_map_failed;
+
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
if (nic->rxd_mode == RXD_MODE_3B) {
/* Two buffer mode */
@@ -2444,33 +2414,30 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
* Buffer2 will have L3/L4 header plus
* L4 payload
*/
- ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single
+ rxdp3->Buffer2_ptr = pci_map_single
(nic->pdev, skb->data, dev->mtu + 4,
PCI_DMA_FROMDEVICE);
- /* Buffer-1 will be dummy buffer. Not used */
- if (!(((struct RxD3*)rxdp)->Buffer1_ptr)) {
- ((struct RxD3*)rxdp)->Buffer1_ptr =
+ if( (rxdp3->Buffer2_ptr == 0) ||
+ (rxdp3->Buffer2_ptr == DMA_ERROR_CODE))
+ goto pci_map_failed;
+
+ rxdp3->Buffer1_ptr =
pci_map_single(nic->pdev,
ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp3->Buffer1_ptr == 0) ||
+ (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+ pci_unmap_single
+ (nic->pdev,
+ (dma_addr_t)skb->data,
+ dev->mtu + 4,
+ PCI_DMA_FROMDEVICE);
+ goto pci_map_failed;
}
rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
rxdp->Control_2 |= SET_BUFFER2_SIZE_3
(dev->mtu + 4);
- } else {
- /* 3 buffer mode */
- if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
- nic->mac_control.stats_info->sw_stat.\
- mem_freed += skb->truesize;
- dev_kfree_skb_irq(skb);
- if (first_rxdp) {
- wmb();
- first_rxdp->Control_1 |=
- RXD_OWN_XENA;
- }
- return -ENOMEM ;
- }
}
rxdp->Control_2 |= BIT(0);
}
@@ -2505,6 +2472,11 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
}
return SUCCESS;
+pci_map_failed:
+ stats->pci_map_fail_cnt++;
+ stats->mem_freed += skb->truesize;
+ dev_kfree_skb_irq(skb);
+ return -ENOMEM;
}
static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
@@ -2515,6 +2487,8 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
struct RxD_t *rxdp;
struct mac_info *mac_control;
struct buffAdd *ba;
+ struct RxD1 *rxdp1;
+ struct RxD3 *rxdp3;
mac_control = &sp->mac_control;
for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) {
@@ -2526,40 +2500,30 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
continue;
}
if (sp->rxd_mode == RXD_MODE_1) {
+ rxdp1 = (struct RxD1*)rxdp;
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD1*)rxdp)->Buffer0_ptr,
- dev->mtu +
- HEADER_ETHERNET_II_802_3_SIZE
- + HEADER_802_2_SIZE +
- HEADER_SNAP_SIZE,
- PCI_DMA_FROMDEVICE);
+ rxdp1->Buffer0_ptr,
+ dev->mtu +
+ HEADER_ETHERNET_II_802_3_SIZE
+ + HEADER_802_2_SIZE +
+ HEADER_SNAP_SIZE,
+ PCI_DMA_FROMDEVICE);
memset(rxdp, 0, sizeof(struct RxD1));
} else if(sp->rxd_mode == RXD_MODE_3B) {
+ rxdp3 = (struct RxD3*)rxdp;
ba = &mac_control->rings[ring_no].
ba[blk][j];
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer1_ptr,
- BUF1_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr,
- dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
- memset(rxdp, 0, sizeof(struct RxD3));
- } else {
- pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN,
+ rxdp3->Buffer0_ptr,
+ BUF0_LEN,
PCI_DMA_FROMDEVICE);
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer1_ptr,
- l3l4hdr_size + 4,
+ rxdp3->Buffer1_ptr,
+ BUF1_LEN,
PCI_DMA_FROMDEVICE);
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr, dev->mtu,
+ rxdp3->Buffer2_ptr,
+ dev->mtu + 4,
PCI_DMA_FROMDEVICE);
memset(rxdp, 0, sizeof(struct RxD3));
}
@@ -2756,6 +2720,8 @@ static void rx_intr_handler(struct ring_info *ring_data)
struct sk_buff *skb;
int pkt_cnt = 0;
int i;
+ struct RxD1* rxdp1;
+ struct RxD3* rxdp3;
spin_lock(&nic->rx_lock);
if (atomic_read(&nic->card_state) == CARD_DOWN) {
@@ -2796,32 +2762,23 @@ static void rx_intr_handler(struct ring_info *ring_data)
return;
}
if (nic->rxd_mode == RXD_MODE_1) {
+ rxdp1 = (struct RxD1*)rxdp;
pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD1*)rxdp)->Buffer0_ptr,
- dev->mtu +
- HEADER_ETHERNET_II_802_3_SIZE +
- HEADER_802_2_SIZE +
- HEADER_SNAP_SIZE,
- PCI_DMA_FROMDEVICE);
+ rxdp1->Buffer0_ptr,
+ dev->mtu +
+ HEADER_ETHERNET_II_802_3_SIZE +
+ HEADER_802_2_SIZE +
+ HEADER_SNAP_SIZE,
+ PCI_DMA_FROMDEVICE);
} else if (nic->rxd_mode == RXD_MODE_3B) {
+ rxdp3 = (struct RxD3*)rxdp;
pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr,
- BUF0_LEN, PCI_DMA_FROMDEVICE);
- pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr,
- dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
- } else {
- pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer1_ptr,
- l3l4hdr_size + 4,
- PCI_DMA_FROMDEVICE);
+ rxdp3->Buffer0_ptr,
+ BUF0_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr,
- dev->mtu, PCI_DMA_FROMDEVICE);
+ rxdp3->Buffer2_ptr,
+ dev->mtu + 4,
+ PCI_DMA_FROMDEVICE);
}
prefetch(skb->data);
rx_osm_handler(ring_data, rxdp);
@@ -3425,23 +3382,8 @@ static void s2io_reset(struct s2io_nic * sp)
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
- if (sp->device_type == XFRAME_II_DEVICE) {
- int ret;
- ret = pci_set_power_state(sp->pdev, 3);
- if (!ret)
- ret = pci_set_power_state(sp->pdev, 0);
- else {
- DBG_PRINT(ERR_DBG,"%s PME based SW_Reset failed!\n",
- __FUNCTION__);
- goto old_way;
- }
- msleep(20);
- goto new_way;
- }
-old_way:
val64 = SW_RESET_ALL;
writeq(val64, &bar0->sw_reset);
-new_way:
if (strstr(sp->product_name, "CX4")) {
msleep(750);
}
@@ -3731,56 +3673,6 @@ static void store_xmsi_data(struct s2io_nic *nic)
}
}
-int s2io_enable_msi(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- u16 msi_ctrl, msg_val;
- struct config_param *config = &nic->config;
- struct net_device *dev = nic->dev;
- u64 val64, tx_mat, rx_mat;
- int i, err;
-
- val64 = readq(&bar0->pic_control);
- val64 &= ~BIT(1);
- writeq(val64, &bar0->pic_control);
-
- err = pci_enable_msi(nic->pdev);
- if (err) {
- DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
- nic->dev->name);
- return err;
- }
-
- /*
- * Enable MSI and use MSI-1 in stead of the standard MSI-0
- * for interrupt handling.
- */
- pci_read_config_word(nic->pdev, 0x4c, &msg_val);
- msg_val ^= 0x1;
- pci_write_config_word(nic->pdev, 0x4c, msg_val);
- pci_read_config_word(nic->pdev, 0x4c, &msg_val);
-
- pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
- msi_ctrl |= 0x10;
- pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
-
- /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
- tx_mat = readq(&bar0->tx_mat0_n[0]);
- for (i=0; i<config->tx_fifo_num; i++) {
- tx_mat |= TX_MAT_SET(i, 1);
- }
- writeq(tx_mat, &bar0->tx_mat0_n[0]);
-
- rx_mat = readq(&bar0->rx_mat);
- for (i=0; i<config->rx_ring_num; i++) {
- rx_mat |= RX_MAT_SET(i, 1);
- }
- writeq(rx_mat, &bar0->rx_mat);
-
- dev->irq = nic->pdev->irq;
- return 0;
-}
-
static int s2io_enable_msi_x(struct s2io_nic *nic)
{
struct XENA_dev_config __iomem *bar0 = nic->bar0;
@@ -4001,6 +3893,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
struct mac_info *mac_control;
struct config_param *config;
int offload_type;
+ struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
mac_control = &sp->mac_control;
config = &sp->config;
@@ -4085,11 +3978,18 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
txdp->Buffer_Pointer = pci_map_single(sp->pdev,
sp->ufo_in_band_v,
sizeof(u64), PCI_DMA_TODEVICE);
+ if((txdp->Buffer_Pointer == 0) ||
+ (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+ goto pci_map_failed;
txdp++;
}
txdp->Buffer_Pointer = pci_map_single
(sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
+ if((txdp->Buffer_Pointer == 0) ||
+ (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+ goto pci_map_failed;
+
txdp->Host_Control = (unsigned long) skb;
txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
if (offload_type == SKB_GSO_UDP)
@@ -4146,6 +4046,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&sp->tx_lock, flags);
return 0;
+pci_map_failed:
+ stats->pci_map_fail_cnt++;
+ netif_stop_queue(dev);
+ stats->mem_freed += skb->truesize;
+ dev_kfree_skb(skb);
+ spin_unlock_irqrestore(&sp->tx_lock, flags);
+ return 0;
}
static void
@@ -4186,39 +4093,6 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n)
return 0;
}
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct s2io_nic *sp = dev->priv;
- int i;
- struct mac_info *mac_control;
- struct config_param *config;
-
- atomic_inc(&sp->isr_cnt);
- mac_control = &sp->mac_control;
- config = &sp->config;
- DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
-
- /* If Intr is because of Rx Traffic */
- for (i = 0; i < config->rx_ring_num; i++)
- rx_intr_handler(&mac_control->rings[i]);
-
- /* If Intr is because of Tx Traffic */
- for (i = 0; i < config->tx_fifo_num; i++)
- tx_intr_handler(&mac_control->fifos[i]);
-
- /*
- * If the Rx buffer count is below the panic threshold then
- * reallocate the buffers from the interrupt handler itself,
- * else schedule a tasklet to reallocate the buffers.
- */
- for (i = 0; i < config->rx_ring_num; i++)
- s2io_chk_rx_buffers(sp, i);
-
- atomic_dec(&sp->isr_cnt);
- return IRQ_HANDLED;
-}
-
static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
{
struct ring_info *ring = (struct ring_info *)dev_id;
@@ -4927,19 +4801,17 @@ static void s2io_ethtool_gringparam(struct net_device *dev,
ering->rx_max_pending = MAX_RX_DESC_1;
else if (sp->rxd_mode == RXD_MODE_3B)
ering->rx_max_pending = MAX_RX_DESC_2;
- else if (sp->rxd_mode == RXD_MODE_3A)
- ering->rx_max_pending = MAX_RX_DESC_3;
ering->tx_max_pending = MAX_TX_DESC;
- for (i = 0 ; i < sp->config.tx_fifo_num ; i++) {
+ for (i = 0 ; i < sp->config.tx_fifo_num ; i++)
tx_desc_count += sp->config.tx_cfg[i].fifo_len;
- }
+
DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
ering->tx_pending = tx_desc_count;
rx_desc_count = 0;
- for (i = 0 ; i < sp->config.rx_ring_num ; i++) {
+ for (i = 0 ; i < sp->config.rx_ring_num ; i++)
rx_desc_count += sp->config.rx_cfg[i].num_rxd;
- }
+
ering->rx_pending = rx_desc_count;
ering->rx_mini_max_pending = 0;
@@ -5923,6 +5795,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
else
tmp_stats[i++] = 0;
tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt;
tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt;
tmp_stats[i++] = stat_info->sw_stat.mem_allocated;
tmp_stats[i++] = stat_info->sw_stat.mem_freed;
@@ -6266,9 +6139,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
u64 *temp2, int size)
{
struct net_device *dev = sp->dev;
- struct sk_buff *frag_list;
+ struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) {
+ struct RxD1 *rxdp1 = (struct RxD1 *)rxdp;
/* allocate skb */
if (*skb) {
DBG_PRINT(INFO_DBG, "SKB is not NULL\n");
@@ -6277,7 +6151,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
* using same mapped address for the Rxd
* buffer pointer
*/
- ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0;
+ rxdp1->Buffer0_ptr = *temp0;
} else {
*skb = dev_alloc_skb(size);
if (!(*skb)) {
@@ -6294,18 +6168,23 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
* such it will be used for next rxd whose
* Host Control is NULL
*/
- ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0 =
+ rxdp1->Buffer0_ptr = *temp0 =
pci_map_single( sp->pdev, (*skb)->data,
size - NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp1->Buffer0_ptr == 0) ||
+ (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) {
+ goto memalloc_failed;
+ }
rxdp->Host_Control = (unsigned long) (*skb);
}
} else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) {
+ struct RxD3 *rxdp3 = (struct RxD3 *)rxdp;
/* Two buffer Mode */
if (*skb) {
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2;
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0;
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1;
+ rxdp3->Buffer2_ptr = *temp2;
+ rxdp3->Buffer0_ptr = *temp0;
+ rxdp3->Buffer1_ptr = *temp1;
} else {
*skb = dev_alloc_skb(size);
if (!(*skb)) {
@@ -6318,73 +6197,47 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
}
sp->mac_control.stats_info->sw_stat.mem_allocated
+= (*skb)->truesize;
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
+ rxdp3->Buffer2_ptr = *temp2 =
pci_map_single(sp->pdev, (*skb)->data,
dev->mtu + 4,
PCI_DMA_FROMDEVICE);
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
+ if( (rxdp3->Buffer2_ptr == 0) ||
+ (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) {
+ goto memalloc_failed;
+ }
+ rxdp3->Buffer0_ptr = *temp0 =
pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp3->Buffer0_ptr == 0) ||
+ (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) {
+ pci_unmap_single (sp->pdev,
+ (dma_addr_t)(*skb)->data,
+ dev->mtu + 4, PCI_DMA_FROMDEVICE);
+ goto memalloc_failed;
+ }
rxdp->Host_Control = (unsigned long) (*skb);
/* Buffer-1 will be dummy buffer not used */
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 =
+ rxdp3->Buffer1_ptr = *temp1 =
pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
- PCI_DMA_FROMDEVICE);
- }
- } else if ((rxdp->Host_Control == 0)) {
- /* Three buffer mode */
- if (*skb) {
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0;
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1;
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2;
- } else {
- *skb = dev_alloc_skb(size);
- if (!(*skb)) {
- DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
- DBG_PRINT(INFO_DBG, "memory to allocate ");
- DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n");
- sp->mac_control.stats_info->sw_stat. \
- mem_alloc_fail_cnt++;
- return -ENOMEM;
- }
- sp->mac_control.stats_info->sw_stat.mem_allocated
- += (*skb)->truesize;
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
- pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- /* Buffer-1 receives L3/L4 headers */
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 =
- pci_map_single( sp->pdev, (*skb)->data,
- l3l4hdr_size + 4,
PCI_DMA_FROMDEVICE);
- /*
- * skb_shinfo(skb)->frag_list will have L4
- * data payload
- */
- skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu +
- ALIGN_SIZE);
- if (skb_shinfo(*skb)->frag_list == NULL) {
- DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \
- failed\n ", dev->name);
- sp->mac_control.stats_info->sw_stat. \
- mem_alloc_fail_cnt++;
- return -ENOMEM ;
+ if( (rxdp3->Buffer1_ptr == 0) ||
+ (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+ pci_unmap_single (sp->pdev,
+ (dma_addr_t)(*skb)->data,
+ dev->mtu + 4, PCI_DMA_FROMDEVICE);
+ goto memalloc_failed;
}
- frag_list = skb_shinfo(*skb)->frag_list;
- frag_list->next = NULL;
- sp->mac_control.stats_info->sw_stat.mem_allocated
- += frag_list->truesize;
- /*
- * Buffer-2 receives L4 data payload
- */
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
- pci_map_single( sp->pdev, frag_list->data,
- dev->mtu, PCI_DMA_FROMDEVICE);
}
}
return 0;
+ memalloc_failed:
+ stats->pci_map_fail_cnt++;
+ stats->mem_freed += (*skb)->truesize;
+ dev_kfree_skb(*skb);
+ return -ENOMEM;
}
+
static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
int size)
{
@@ -6395,10 +6248,6 @@ static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4);
- } else {
- rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
- rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
- rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
}
}
@@ -6420,8 +6269,6 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp)
size += NET_IP_ALIGN;
else if (sp->rxd_mode == RXD_MODE_3B)
size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
- else
- size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
for (i = 0; i < config->rx_ring_num; i++) {
blk_cnt = config->rx_cfg[i].num_rxd /
@@ -6431,7 +6278,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp)
for (k = 0; k < rxd_count[sp->rxd_mode]; k++) {
rxdp = mac_control->rings[i].
rx_blocks[j].rxds[k].virt_addr;
- if(sp->rxd_mode >= RXD_MODE_3A)
+ if(sp->rxd_mode == RXD_MODE_3B)
ba = &mac_control->rings[i].ba[j][k];
if (set_rxd_buffer_pointer(sp, rxdp, ba,
&skb,(u64 *)&temp0_64,
@@ -6458,9 +6305,7 @@ static int s2io_add_isr(struct s2io_nic * sp)
struct net_device *dev = sp->dev;
int err = 0;
- if (sp->intr_type == MSI)
- ret = s2io_enable_msi(sp);
- else if (sp->intr_type == MSI_X)
+ if (sp->intr_type == MSI_X)
ret = s2io_enable_msi_x(sp);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
@@ -6471,16 +6316,6 @@ static int s2io_add_isr(struct s2io_nic * sp)
store_xmsi_data(sp);
/* After proper initialization of H/W, register ISR */
- if (sp->intr_type == MSI) {
- err = request_irq((int) sp->pdev->irq, s2io_msi_handle,
- IRQF_SHARED, sp->name, dev);
- if (err) {
- pci_disable_msi(sp->pdev);
- DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n",
- dev->name);
- return -1;
- }
- }
if (sp->intr_type == MSI_X) {
int i, msix_tx_cnt=0,msix_rx_cnt=0;
@@ -6567,14 +6402,6 @@ static void s2io_rem_isr(struct s2io_nic * sp)
pci_disable_msix(sp->pdev);
} else {
free_irq(sp->pdev->irq, dev);
- if (sp->intr_type == MSI) {
- u16 val;
-
- pci_disable_msi(sp->pdev);
- pci_read_config_word(sp->pdev, 0x4c, &val);
- val ^= 0x1;
- pci_write_config_word(sp->pdev, 0x4c, val);
- }
}
/* Waiting till all Interrupt handlers are complete */
cnt = 0;
@@ -6907,6 +6734,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
}
/* Updating statistics */
+ sp->stats.rx_packets++;
rxdp->Host_Control = 0;
if (sp->rxd_mode == RXD_MODE_1) {
int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
@@ -6914,7 +6742,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
sp->stats.rx_bytes += len;
skb_put(skb, len);
- } else if (sp->rxd_mode >= RXD_MODE_3A) {
+ } else if (sp->rxd_mode == RXD_MODE_3B) {
int get_block = ring_data->rx_curr_get_info.block_index;
int get_off = ring_data->rx_curr_get_info.offset;
int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2);
@@ -6924,18 +6752,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
struct buffAdd *ba = &ring_data->ba[get_block][get_off];
sp->stats.rx_bytes += buf0_len + buf2_len;
memcpy(buff, ba->ba_0, buf0_len);
-
- if (sp->rxd_mode == RXD_MODE_3A) {
- int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2);
-
- skb_put(skb, buf1_len);
- skb->len += buf2_len;
- skb->data_len += buf2_len;
- skb_put(skb_shinfo(skb)->frag_list, buf2_len);
- sp->stats.rx_bytes += buf1_len;
-
- } else
- skb_put(skb, buf2_len);
+ skb_put(skb, buf2_len);
}
if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!sp->lro) ||
@@ -7131,7 +6948,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
*dev_intr_type = INTA;
}
#else
- if (*dev_intr_type > MSI_X) {
+ if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
"Defaulting to INTA\n");
*dev_intr_type = INTA;
@@ -7145,10 +6962,10 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
*dev_intr_type = INTA;
}
- if (rx_ring_mode > 3) {
+ if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) {
DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n");
- DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n");
- rx_ring_mode = 3;
+ DBG_PRINT(ERR_DBG, "s2io: Defaulting to 1-buffer mode\n");
+ rx_ring_mode = 1;
}
return SUCCESS;
}
@@ -7240,28 +7057,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
pci_disable_device(pdev);
return -ENOMEM;
}
- if (dev_intr_type != MSI_X) {
- if (pci_request_regions(pdev, s2io_driver_name)) {
- DBG_PRINT(ERR_DBG, "Request Regions failed\n");
- pci_disable_device(pdev);
- return -ENODEV;
- }
- }
- else {
- if (!(request_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0), s2io_driver_name))) {
- DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n");
- pci_disable_device(pdev);
- return -ENODEV;
- }
- if (!(request_mem_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2), s2io_driver_name))) {
- DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n");
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- pci_disable_device(pdev);
- return -ENODEV;
- }
+ if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
+ DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret);
+ pci_disable_device(pdev);
+ return -ENODEV;
}
dev = alloc_etherdev(sizeof(struct s2io_nic));
@@ -7288,8 +7087,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
sp->rxd_mode = RXD_MODE_1;
if (rx_ring_mode == 2)
sp->rxd_mode = RXD_MODE_3B;
- if (rx_ring_mode == 3)
- sp->rxd_mode = RXD_MODE_3A;
sp->intr_type = dev_intr_type;
@@ -7565,10 +7362,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n",
dev->name);
break;
- case RXD_MODE_3A:
- DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n",
- dev->name);
- break;
}
if (napi)
@@ -7577,9 +7370,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
case INTA:
DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
break;
- case MSI:
- DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name);
- break;
case MSI_X:
DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
break;
@@ -7619,14 +7409,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
mem_alloc_failed:
free_shared_mem(sp);
pci_disable_device(pdev);
- if (dev_intr_type != MSI_X)
- pci_release_regions(pdev);
- else {
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- release_mem_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2));
- }
+ pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
@@ -7661,14 +7444,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
free_shared_mem(sp);
iounmap(sp->bar0);
iounmap(sp->bar1);
- if (sp->intr_type != MSI_X)
- pci_release_regions(pdev);
- else {
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- release_mem_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2));
- }
+ pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
pci_disable_device(pdev);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 3887fe6..92983ee 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -74,6 +74,10 @@ static int debug_level = ERR_DBG;
/* DEBUG message print. */
#define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args)
+#ifndef DMA_ERROR_CODE
+#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
+#endif
+
/* Protocol assist features of the NIC */
#define L3_CKSUM_OK 0xFFFF
#define L4_CKSUM_OK 0xFFFF
@@ -97,6 +101,7 @@ struct swStat {
unsigned long long num_aggregations;
/* Other statistics */
unsigned long long mem_alloc_fail_cnt;
+ unsigned long long pci_map_fail_cnt;
unsigned long long watchdog_timer_cnt;
unsigned long long mem_allocated;
unsigned long long mem_freed;
@@ -575,8 +580,7 @@ struct RxD_block {
#define SIZE_OF_BLOCK 4096
#define RXD_MODE_1 0 /* One Buffer mode */
-#define RXD_MODE_3A 1 /* Three Buffer mode */
-#define RXD_MODE_3B 2 /* Two Buffer mode */
+#define RXD_MODE_3B 1 /* Two Buffer mode */
/* Structure to hold virtual addresses of Buf0 and Buf1 in
* 2buf mode. */
@@ -876,7 +880,6 @@ struct s2io_nic {
u16 lro_max_aggr_per_sess;
#define INTA 0
-#define MSI 1
#define MSI_X 2
u8 intr_type;
@@ -1020,8 +1023,6 @@ static int s2io_poll(struct net_device *dev, int *budget);
static void s2io_init_pci(struct s2io_nic * sp);
static int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
static void s2io_alarm_handle(unsigned long data);
-static int s2io_enable_msi(struct s2io_nic *nic);
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id);
static irqreturn_t
s2io_msix_ring_handle(int irq, void *dev_id);
static irqreturn_t
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index a05fd97..04cba6b 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -768,11 +768,13 @@ done:
static void write_bulk_callback(struct urb *urb)
{
pegasus_t *pegasus = urb->context;
- struct net_device *net = pegasus->net;
+ struct net_device *net;
if (!pegasus)
return;
+ net = pegasus->net;
+
if (!netif_device_present(net) || !netif_running(net))
return;
^ permalink raw reply related
* Re: [PATCH V3 0/7] net/bonding: ADD IPoIB support for the bonding driver
From: Roland Dreier @ 2007-07-30 21:20 UTC (permalink / raw)
To: Moni Shoua; +Cc: davem, fubar, netdev, general
In-Reply-To: <46ADDB89.5030601@voltaire.com>
> 1. When bonding enslaves an IPoIB device the bonding neighbor holds a
> reference to a cleanup function in the IPoIB drives. This makes it unsafe to
> unload the IPoIB module if there are bonding neighbors in the air. So, to
> avoid this race one must unload bonding before unloading IPoIB.
I think we really want to resolve this somehow. Getting an oops by
doing "modprobe -r ipoib" isn't that friendly.
Also, what happened to the problem of having an address handle
belonging to the wrong device on bond failover? Did you figure out a
way to fix that one?
- R.
^ permalink raw reply
* Re: Proposed interface for per-packet mesh-ttl
From: Stephen Hemminger @ 2007-07-30 20:53 UTC (permalink / raw)
To: Javier Cardona; +Cc: Dan Williams, Christoph Hellwig, netdev
In-Reply-To: <445f43ac0707301337l2f7d62ebx6955a12cd89c6bd3@mail.gmail.com>
On Mon, 30 Jul 2007 13:37:20 -0700
"Javier Cardona" <javier@cozybit.com> wrote:
> Hi Stephen,
>
> On 7/27/07, Stephen Hemminger <shemminger@linux-foundation.org> wrote:
> > In this case perhaps you can have a table that maps skb->priority to
> > mesh ttl? priorty can already by handled by existing setsockopt calls,
> > and modified by netfilter and QoS managements.
>
> Thanks for the feedback. IMHO overloading the [SOL_SOCKET]
> SO_PRIORITY sockoption for something as different as changing the
> mesh-ttl is quite a stretch. But I admit that it meets the driver
> requirements of "never add sockopt" and "not [ab]use netfilter hooks".
> If that's acceptable to all, I'll modify the patch in that direction.
>
> Cheers,
>
> Javier
Take it as idea not a proscription. You can use TC rules to rewrite
the priority. It is kind of like how priority is being mapped to TOS already
in softmac. Alternatively, the TTL can be set with sockopt, but it is a IP so
it would need an IP ttl to mesh mapping. The fundamental thing is to try
and avoid topology specific options bleeding all the way up the socket layer,
especially since the network layer is involved and may need to multipath.
^ permalink raw reply
* RE: [PATCH] NET_DMA: remove unused dma_memcpy_to_kernel_iovec
From: Waskiewicz Jr, Peter P @ 2007-07-30 20:47 UTC (permalink / raw)
To: pravin, David Miller
Cc: Nelson, Shannon, netdev, viro, Leech, Christopher, andy.grover
In-Reply-To: <bab433300707300739s283bf15fp9d00235cf39fa08b@mail.gmail.com>
> On 7/26/07, David Miller <davem@davemloft.net> wrote:
> > From: Shannon Nelson <shannon.nelson@intel.com>
> > Date: Tue, 24 Jul 2007 17:36:06 -0700
> >
> > > (repost - original eaten by vger?)
> > >
> > > Al Viro pointed out that dma_memcpy_to_kernel_iovec() really was
> > > unreachable and thus unused. The code originally was there to
> > > support in-kernel dma needs, but since it remains unused,
> we'll pull it out.
> > >
> > > Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
> >
> > Applied, thanks Shannon.
>
> NET_DMA on kernel buffer is pretty useful in ndb, iSCSI
> target and initiators which uses kernel buffer to receive
> data. Are there any other issues with dma-memcpy on kernel
> buffers, if not then following patch makes
> dma_memcpy_to_kernel_iovec() reachable from tcp_recvmsg.
> I tested this patch and it work fine with unh iSCSI target.
>
>
> comments?
>
> --pravin.
Pravin,
Currently, NET_DMA only has one provider in the kernel, namely
TCP. As the driver stands now, I'd like to keep this function out since
it really wasn't being used before. Shannon has posted patches that
will hopefully make it into 2.6.24 that allow multiple clients to
request DMA channels, so things like iSCSI, ndb, UDP, and NFS can ask
for channels without depending on TCP. Once we get to that point, if we
see the need for the function, we can add it back.
We have tried getting iSCSI accelerated through NET_DMA already,
and didn't see the performance boost that made it worthwhile to do.
Once the multiple client channel patches are in, we can revisit that,
since it can be done "right."
Cheers,
-PJ Waskiewicz
^ permalink raw reply
* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: Andrew Gallatin @ 2007-07-30 20:32 UTC (permalink / raw)
To: Jan-Bernd Themann
Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
linux-ppc, Marcus Eder, Thomas Klein, Stefan Roscher,
David Miller, Jeff Garzik
In-Reply-To: <200707301724.33865.ossthema@de.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 2945 bytes --]
Jan-Bernd Themann wrote:
> Hi,
>
> this patch set contains the latest generic LRO code, a Kconfig / Makefile
> and an eHEA patch demonstrating how the "aggregate SKB" interface has to
> to be used.
> Drew, could you provide a patch for the myri10ge driver to show how the
> "receive in page" interface works?
Hi,
Thank you for the many fixes, and especially for the counters!
I was working on testing the myri10ge patch, and I ran into a few
problems. I've attached a patch to inet_lro.c to fix some of them,
and a patch to myri10ge.c to show how to use the page based
interface. Both patches are signed off by Andrew Gallatin
<gallatin@myri.com>
First, the LRO_MAX_PG_HLEN is still a problem. Minimally sized 60
byte frames still cause problems in lro_gen_skb due to skb->len
going negative. Fixed in the attached patch. It may be simpler
to just drop LRO_MAX_PG_HLEN to ETH_ZLEN, but I'm not sure if
that is enough. Are there "smart" NICs which might chop off padding
themselves?
Second, you still need to set skb->ip_summed = CHECKSUM_UNNECESSARY
when modified packets are flushed, else the stack will see bad
checksums for packets from CHECKSUM_COMPLETE drivers using the
skb interface. Fixed in the attached patch.
Third, for some reason I have yet to figure out, this version of the
patch takes a while to "ramp up", but only when the receiver MTU
is 9000 and the sender MTU is 1500. If the receiver MTU is also
1500, even a 10 second netperf easily shows line rate. I don't
see this with our LRO, and I'm so far at a loss to explain it.
Here is the first 3 seconds of output from a simple program
which diffs the interface counters once / sec.
Ipkts IBytes Opkts Obytes
rx MTU=9000:
0 0 0 0
72 99092 14 1102
105 158970 7 420
750324 1135987084 17804 1068240
814427 1233042478 18529 1111740
<....>
rx MTU=1500
0 0 0 0
441344 668180168 13132 788182
815938 1235328656 18716 1122960
817698 1237994772 18628 1117680
<.....>
Once it has ramped up, the bandwidth is fine, and there
doesn't seem to be much difference between setting the
receiver MTU to 1500 or 9000. But it takes a very long
netperf run to overcome the ramp up period.
Fourth, I did some traffic sniffing to try to figure out what's going
on above, and saw tcpdump complain about bad checksums. Have you tried
running tcpdump -s 65535 -vvv? Have you also seen bad checksums?
I seem to see this for both page- and skb-based versions of the driver.
Last, the pointer to the TCP header in __lro_proc_segment() in the
unaccelerated vlan hdr case needs to also be offset by vlan_hdr_len
from skb->data. I've fixed this in the attached patch.
Thanks,
Drew
[-- Attachment #2: inet_lro.diff --]
[-- Type: text/plain, Size: 665 bytes --]
--- linux-2.6.23-rc1.orig/net/ipv4/inet_lro.c 2007-07-30 13:10:49.000000000 -0400
+++ linux-2.6.23-rc1/net/ipv4/inet_lro.c 2007-07-30 15:17:51.000000000 -0400
@@ -126,6 +126,7 @@ static void lro_update_tcp_ip_header(str
htons(lro_desc->ip_tot_len) -
IP_HDR_LEN(iph), IPPROTO_TCP,
lro_desc->data_csum);
+ lro_desc->parent->ip_summed = CHECKSUM_UNNECESSARY;
}
static __wsum lro_tcp_data_csum(struct iphdr *iph, struct tcphdr *tcph, int len)
@@ -396,6 +397,9 @@ static struct sk_buff *lro_gen_skb(struc
if (!skb)
return NULL;
+ if (hlen > len)
+ hlen = len;
+
skb->len = len;
skb->data_len = len - hlen;
skb->truesize += true_size;
[-- Attachment #3: myri10ge_lro.diff --]
[-- Type: text/plain, Size: 6221 bytes --]
diff -urp a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
--- a/drivers/net/myri10ge/myri10ge.c 2007-07-24 15:57:12.000000000 -0400
+++ b/drivers/net/myri10ge/myri10ge.c 2007-07-30 16:12:06.000000000 -0400
@@ -48,6 +48,7 @@
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
+#include <linux/inet_lro.h>
#include <linux/ip.h>
#include <linux/inet.h>
#include <linux/in.h>
@@ -62,6 +63,8 @@
#include <linux/io.h>
#include <linux/log2.h>
#include <net/checksum.h>
+#include <net/ip.h>
+#include <net/tcp.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/processor.h>
@@ -89,6 +92,7 @@ MODULE_LICENSE("Dual BSD/GPL");
#define MYRI10GE_EEPROM_STRINGS_SIZE 256
#define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2)
+#define MYRI10GE_MAX_LRO_DESCRIPTORS 8
#define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff)
#define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff
@@ -151,6 +155,8 @@ struct myri10ge_rx_done {
dma_addr_t bus;
int cnt;
int idx;
+ struct net_lro_mgr lro_mgr;
+ struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS];
};
struct myri10ge_priv {
@@ -276,6 +282,14 @@ static int myri10ge_debug = -1; /* defau
module_param(myri10ge_debug, int, 0);
MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
+static int myri10ge_lro = 1;
+module_param(myri10ge_lro, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload\n");
+
+static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS;
+module_param(myri10ge_lro_max_pkts, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_lro, "Number of LRO packets to be aggregated\n");
+
static int myri10ge_fill_thresh = 256;
module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
@@ -1019,6 +1033,16 @@ myri10ge_rx_done(struct myri10ge_priv *m
remainder -= MYRI10GE_ALLOC_SIZE;
}
+ if (mgp->csum_flag && myri10ge_lro) {
+ rx_frags[0].page_offset += MXGEFW_PAD;
+ rx_frags[0].size -= MXGEFW_PAD;
+ len -= MXGEFW_PAD;
+ lro_receive_frags(&mgp->rx_done.lro_mgr, rx_frags,
+ len, bytes,
+ (void *)(unsigned long)csum, csum);
+ return 1;
+ }
+
hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN;
/* allocate an skb to attach the page(s) to. */
@@ -1137,6 +1161,9 @@ static inline void myri10ge_clean_rx_don
mgp->stats.rx_packets += rx_packets;
mgp->stats.rx_bytes += rx_bytes;
+ if (myri10ge_lro)
+ lro_flush_all(&rx_done->lro_mgr);
+
/* restock receive rings if needed */
if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh)
myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
@@ -1378,7 +1405,8 @@ static const char myri10ge_gstrings_stat
"dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
"dropped_unicast_filtered", "dropped_multicast_filtered",
"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
- "dropped_no_big_buffer"
+ "dropped_no_big_buffer", "LRO aggregated", "LRO flushed",
+ "LRO avg aggr", "LRO no_desc"
};
#define MYRI10GE_NET_STATS_LEN 21
@@ -1444,6 +1472,14 @@ myri10ge_get_ethtool_stats(struct net_de
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_overrun);
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_small_buffer);
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_no_big_buffer);
+ data[i++] = mgp->rx_done.lro_mgr.stats.aggregated;
+ data[i++] = mgp->rx_done.lro_mgr.stats.flushed;
+ if (mgp->rx_done.lro_mgr.stats.flushed)
+ data[i++] = mgp->rx_done.lro_mgr.stats.aggregated /
+ mgp->rx_done.lro_mgr.stats.flushed;
+ else
+ data[i++] = 0;
+ data[i++] = mgp->rx_done.lro_mgr.stats.no_desc;
}
static void myri10ge_set_msglevel(struct net_device *netdev, u32 value)
@@ -1717,10 +1753,69 @@ static void myri10ge_free_irq(struct myr
pci_disable_msi(pdev);
}
+static int
+myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
+ void **ip_hdr, void **tcpudp_hdr,
+ u64 * hdr_flags, void *priv)
+{
+ struct ethhdr *eh;
+ struct vlan_ethhdr *veh;
+ struct iphdr *iph;
+ u8 *va = page_address(frag->page) + frag->page_offset;
+ unsigned long ll_hlen;
+ __wsum csum = (__wsum) (unsigned long)priv;
+
+ /* find the mac header, aborting if not IPv4 */
+
+ eh = (struct ethhdr *)va;
+ *mac_hdr = eh;
+ ll_hlen = ETH_HLEN;
+ if (eh->h_proto != htons(ETH_P_IP)) {
+ if (eh->h_proto == htons(ETH_P_8021Q)) {
+ veh = (struct vlan_ethhdr *)va;
+ if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
+ return -1;
+
+ ll_hlen += VLAN_HLEN;
+
+ /*
+ * HW checksum starts ETH_HLEN bytes into
+ * frame, so we must subtract off the VLAN
+ * header's checksum before csum can be used
+ */
+ csum = csum_sub(csum, csum_partial(va + ETH_HLEN,
+ VLAN_HLEN, 0));
+ } else {
+ return -1;
+ }
+ }
+ *hdr_flags = LRO_IPV4;
+
+ iph = (struct iphdr *)(va + ll_hlen);
+ *ip_hdr = iph;
+ if (iph->protocol != IPPROTO_TCP)
+ return -1;
+ *hdr_flags |= LRO_TCP;
+ *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
+
+ /* verify the IP checksum */
+ if (unlikely(ip_fast_csum((u8 *) iph, iph->ihl)))
+ return -1;
+
+ /* verify the checksum */
+ if (unlikely(csum_tcpudp_magic(iph->saddr, iph->daddr,
+ ntohs(iph->tot_len) - (iph->ihl << 2),
+ IPPROTO_TCP, csum)))
+ return -1;
+
+ return 0;
+}
+
static int myri10ge_open(struct net_device *dev)
{
struct myri10ge_priv *mgp;
struct myri10ge_cmd cmd;
+ struct net_lro_mgr *lro_mgr;
int status, big_pow2;
mgp = netdev_priv(dev);
@@ -1852,6 +1947,17 @@ static int myri10ge_open(struct net_devi
mgp->link_state = htonl(~0U);
mgp->rdma_tags_available = 15;
+ lro_mgr = &mgp->rx_done.lro_mgr;
+ lro_mgr->dev = dev;
+ lro_mgr->features = LRO_F_NAPI;
+ lro_mgr->ip_summed = CHECKSUM_COMPLETE;
+ lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS;
+ lro_mgr->lro_arr = mgp->rx_done.lro_desc;
+ lro_mgr->get_frag_header = myri10ge_get_frag_header;
+ lro_mgr->max_aggr = myri10ge_lro_max_pkts;
+ if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
+ lro_mgr->max_aggr = MAX_SKB_FRAGS;
+
netif_poll_enable(mgp->dev); /* must happen prior to any irq */
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0);
^ permalink raw reply
* Re: Proposed interface for per-packet mesh-ttl
From: Javier Cardona @ 2007-07-30 20:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Dan Williams, Christoph Hellwig, netdev
In-Reply-To: <20070728073145.57155e03@oldman>
Hi Stephen,
On 7/27/07, Stephen Hemminger <shemminger@linux-foundation.org> wrote:
> In this case perhaps you can have a table that maps skb->priority to
> mesh ttl? priorty can already by handled by existing setsockopt calls,
> and modified by netfilter and QoS managements.
Thanks for the feedback. IMHO overloading the [SOL_SOCKET]
SO_PRIORITY sockoption for something as different as changing the
mesh-ttl is quite a stretch. But I admit that it meets the driver
requirements of "never add sockopt" and "not [ab]use netfilter hooks".
If that's acceptable to all, I'll modify the patch in that direction.
Cheers,
Javier
^ permalink raw reply
* [ofa-general] Re: [PATCH V3 7/7] net/bonding: Delay sending of gratuitous ARP to avoid failure
From: Jay Vosburgh @ 2007-07-30 20:29 UTC (permalink / raw)
To: Moni Shoua; +Cc: netdev, rdreier, davem, general
In-Reply-To: <46ADDFE6.9000609@voltaire.com>
Moni Shoua <monis@voltaire.com> wrote:
>Delay sending a gratuitous_arp when LINK_STATE_LINKWATCH_PENDING bit
>in dev->state field is on. This improves the chances for the arp packet to
>be transmitted.
Under what circumstances were you seeing problems that delaying
the gratuitous ARP until linkwatch is done improves things? Is this
really an IB thing, or did you experience problems here over regular
ethernet?
>Signed-off-by: Moni Shoua <monis@voltaire.com>
>---
> drivers/net/bonding/bond_main.c | 25 +++++++++++++++++++++----
> drivers/net/bonding/bonding.h | 1 +
> 2 files changed, 22 insertions(+), 4 deletions(-)
>
>Index: net-2.6/drivers/net/bonding/bond_main.c
>===================================================================
>--- net-2.6.orig/drivers/net/bonding/bond_main.c 2007-07-25 15:33:25.000000000 +0300
>+++ net-2.6/drivers/net/bonding/bond_main.c 2007-07-26 18:42:59.296296622 +0300
>@@ -1134,8 +1134,13 @@ void bond_change_active_slave(struct bon
> if (new_active && !bond->do_set_mac_addr)
> memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
> new_active->dev->addr_len);
>-
>- bond_send_gratuitous_arp(bond);
>+ if (bond->curr_active_slave &&
>+ test_bit(__LINK_STATE_LINKWATCH_PENDING, &bond->curr_active_slave->dev->state)){
>+ dprintk("delaying gratuitous arp on %s\n",bond->curr_active_slave->dev->name);
>+ bond->send_grat_arp=1;
>+ }else{
>+ bond_send_gratuitous_arp(bond);
>+ }
Style issues throughout the patch series: many lines are too
long, many things are all smashed together, e.g., "}else{" instead of
"} else {", "send_grat_arp=1" instead of "send_grat_arp = 1", and so on.
> }
> }
>
>@@ -2120,6 +2125,15 @@ void bond_mii_monitor(struct net_device
> * program could monitor the link itself if needed.
> */
>
>+ if (bond->send_grat_arp) {
>+ if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING, &bond->curr_active_slave->dev->state))
>+ dprintk("Needs to send gratuitous arp but not yet\n",__FUNCTION__);
>+ else {
>+ dprintk("sending delayed gratuitous arp on ond->curr_active_slave->dev->name\n");
>+ bond_send_gratuitous_arp(bond);
>+ bond->send_grat_arp=0;
>+ }
>+ }
> read_lock(&bond->curr_slave_lock);
> oldcurrent = bond->curr_active_slave;
> read_unlock(&bond->curr_slave_lock);
>@@ -2513,6 +2527,7 @@ static void bond_send_gratuitous_arp(str
> struct slave *slave = bond->curr_active_slave;
> struct vlan_entry *vlan;
> struct net_device *vlan_dev;
>+ int i;
>
> dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
> slave ? slave->dev->name : "NULL");
>@@ -2520,8 +2535,9 @@ static void bond_send_gratuitous_arp(str
> return;
>
> if (bond->master_ip) {
>- bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
>- bond->master_ip, 0);
>+ for (i=0;i<3;i++)
>+ bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
>+ bond->master_ip, 0);
> }
If you delay the grat ARP until linkwatch is done, why is it
also necessary to shotgun several ARPs instead of one? Why are the ARPs
sent for VLANs not also shotgunned in a similar fashion?
If shotgunning like this really is useful, would it not make
more sense to space them out a bit, e.g., over successive monitor
passes?
> list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
>@@ -4331,6 +4347,7 @@ static int bond_init(struct net_device *
> bond->current_arp_slave = NULL;
> bond->primary_slave = NULL;
> bond->dev = bond_dev;
>+ bond->send_grat_arp=0;
> INIT_LIST_HEAD(&bond->vlan_list);
>
> /* Initialize the device entry points */
>Index: net-2.6/drivers/net/bonding/bonding.h
>===================================================================
>--- net-2.6.orig/drivers/net/bonding/bonding.h 2007-07-25 15:20:10.000000000 +0300
>+++ net-2.6/drivers/net/bonding/bonding.h 2007-07-26 18:42:43.652087660 +0300
>@@ -203,6 +203,7 @@ struct bonding {
> struct vlan_group *vlgrp;
> struct packet_type arp_mon_pt;
> s8 do_set_mac_addr;
>+ int send_grat_arp;
This need not be a full int, and (this applies to
do_set_mac_addr, also) could probably be squeezed into gaps already
existing within the struct bonding somewhere.
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* [ofa-general] Re: [PATCH 2.6.23 1/2] Make the iw_cxgb3 module parameters writable.
From: Roland Dreier @ 2007-07-30 20:20 UTC (permalink / raw)
To: Steve Wise; +Cc: netdev, linux-kernel, general
In-Reply-To: <20070729201226.31659.85900.stgit@dell3.ogc.int>
ugh, missed these before my last merge...
anyway:
why do we want to parameters writable? a good changelog tells me
what, why and how, and this changelog just covered the "what". Also,
I assume you've checked that it's OK for these variables to change at
any time?
^ permalink raw reply
* Re: [NET] IOC3: Switch hw checksumming to ethtool configurable.
From: Jeff Garzik @ 2007-07-30 20:06 UTC (permalink / raw)
To: Ralf Baechle; +Cc: netdev, Andrew Morton, David S. Miller, Herbert Xu
In-Reply-To: <20070725113157.GA29416@linux-mips.org>
Ralf Baechle wrote:
> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
applied to #upstream (2.6.24)
> I've previously sent out this patch a long time ago. At that time I was
> told NETIF_F_IP_CSUM wouldn't make any sense without NETIF_F_SG. IOC3's
> S/G abilities are very limited; it can do upto three segments of which
> the first one is upto 104 bytes and part of the packet's TX ring entry,
> the second and 3rd ones can be anywhere in the 64-bit PCI address space
> but may not cross a 16kB page boundary. So setting NETIF_F_SG isn't
> really an option unless the IOC3 was going to linearize any packet it
> can't cope with itself.
>
> So the big question, does NETIF_F_IP_CSUM without NETIF_F_SG make sense?
Conventional wisdom has always been that NETIF_F_SG is required if
NETIF_F_*CSUM is present, and vice versa.
I admit I've not verified this in the past year or two.
Jeff
^ permalink raw reply
* Re: [PATCH] [drivers/net/cxgb3] removed several unneeded zero initilization
From: Jeff Garzik @ 2007-07-30 20:04 UTC (permalink / raw)
To: Denis Cheng; +Cc: linux-bugs, Andrew Morton, netdev, cr_quan
In-Reply-To: <11847434891556-git-send-email-crquan@gmail.com>
Denis Cheng wrote:
> Cc: linux-bugs@chelsio.com
> Signed-off-by: Denis Cheng <crquan@gmail.com>
> ---
> drivers/net/cxgb3/cxgb3_main.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
applied
^ permalink raw reply
* Re: [PATCH 0/4][RFC] lro: Generic Large Receive Offload for TCP traffic
From: Stephen Hemminger @ 2007-07-30 19:57 UTC (permalink / raw)
To: Andrew Gallatin
Cc: Linas Vepstas, Jan-Bernd Themann, netdev, Thomas Klein,
Jeff Garzik, Jan-Bernd Themann, linux-kernel, linux-ppc,
Christoph Raisch, Marcus Eder, Stefan Roscher, David Miller
In-Reply-To: <46AE232F.3080409@myri.com>
Could someone add this to:
http://linux-net.osdl.org Wiki?
^ permalink raw reply
* Re: [PATCH] [2.6.22] Fix a potential NULL pointer dereference in mace_interrupt() in drivers/net/pcmcia/nmclan_cs.c
From: Jeff Garzik @ 2007-07-30 19:59 UTC (permalink / raw)
To: Micah Gruber; +Cc: linux-kernel, netdev
In-Reply-To: <46A567A8.6050409@gmail.com>
Micah Gruber wrote:
> This patch fixes a potential null dereference bug where we dereference
> DEV before a null check. This patch simply moves the dereferencing after
> the null check.
>
> Signed-off-by: Micah Gruber <micah.gruber@gmail.com>
applied (git-am worked!)
^ permalink raw reply
* Re: [PATCH 2.6.22 1/3]S2io: Mask spurious interrupts
From: Jeff Garzik @ 2007-07-30 19:56 UTC (permalink / raw)
To: ram.vepa; +Cc: netdev
In-Reply-To: <1185417308.21141.33.camel@flash>
Ramkrishna Vepa wrote:
> - Mask single and double bit ETQ ecc errors to inhibit spurious interrupts.
>
> (Resending; Removed HTML sections in the patch)
>
> Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
applied 1-3
^ permalink raw reply
* Re: [PATCH 2.6.22 1/4]S2IO: Removing 3 buffer mode support from the driver
From: Jeff Garzik @ 2007-07-30 19:56 UTC (permalink / raw)
To: Veena Parat; +Cc: netdev, support
In-Reply-To: <Pine.GSO.4.10.10707230219300.2793-100000@guinness>
Veena Parat wrote:
> - Removed 3 buffer mode support from driver - unused feature
> - Incorporated Jeff Garzik's comments on elimination of inline typecasting
> - Code cleanup : Removed a few extra spaces
>
> Signed-off-by: Veena Parat <veena.parat@neterion.com>
applied 1-4
^ permalink raw reply
* Re: [PATCH] netxen: drop redudant spinlock
From: Jeff Garzik @ 2007-07-30 19:52 UTC (permalink / raw)
To: Dhananjay Phadke; +Cc: netdev
In-Reply-To: <Pine.LNX.4.64.0707272257090.27724@stellar.unminc.com>
Dhananjay Phadke wrote:
> Some leftover code that makes use of adapter->lock in tx_timeout function,
> which resets the interface under this lock. In close() when the workqueue
> is flushed, prints the warning about sleeping with interrupts disabled
> (when spinlock debug is enabled). The lock was required with private netxen
> IOCTLs, which were removed a while ago.
applied
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox