* [patch 09/10] bcm43xx: fix pctl slowclock limit calculation
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff; +Cc: linville, netdev, akpm, mb
From: Michael Buesch <mb@bu3sch.de>
This fixes coverity bug:
http://marc.theaimsgroup.com/?l=linux-netdev&m=114417628413880&w=2
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/wireless/bcm43xx/bcm43xx_power.c | 115 ++++++++++-------
drivers/net/wireless/bcm43xx/bcm43xx_power.h | 9 +
2 files changed, 77 insertions(+), 47 deletions(-)
diff -puN drivers/net/wireless/bcm43xx/bcm43xx_power.c~bcm43xx-fix-pctl-slowclock-limit-calculation drivers/net/wireless/bcm43xx/bcm43xx_power.c
--- devel/drivers/net/wireless/bcm43xx/bcm43xx_power.c~bcm43xx-fix-pctl-slowclock-limit-calculation 2006-04-12 18:12:22.000000000 -0700
+++ devel-akpm/drivers/net/wireless/bcm43xx/bcm43xx_power.c 2006-04-12 18:12:22.000000000 -0700
@@ -35,77 +35,101 @@
#include "bcm43xx_main.h"
+/* Get the Slow Clock Source */
+static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm)
+{
+ u32 tmp;
+ int err;
+
+ assert(bcm->current_core == &bcm->core_chipcommon);
+ if (bcm->current_core->rev < 6) {
+ if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA ||
+ bcm->bustype == BCM43xx_BUSTYPE_SB)
+ return BCM43xx_PCTL_CLKSRC_XTALOS;
+ if (bcm->bustype == BCM43xx_BUSTYPE_PCI) {
+ err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
+ assert(!err);
+ if (tmp & 0x10)
+ return BCM43xx_PCTL_CLKSRC_PCI;
+ return BCM43xx_PCTL_CLKSRC_XTALOS;
+ }
+ }
+ if (bcm->current_core->rev < 10) {
+ tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
+ tmp &= 0x7;
+ if (tmp == 0)
+ return BCM43xx_PCTL_CLKSRC_LOPWROS;
+ if (tmp == 1)
+ return BCM43xx_PCTL_CLKSRC_XTALOS;
+ if (tmp == 2)
+ return BCM43xx_PCTL_CLKSRC_PCI;
+ }
+
+ return BCM43xx_PCTL_CLKSRC_XTALOS;
+}
+
/* Get max/min slowclock frequency
* as described in http://bcm-specs.sipsolutions.net/PowerControl
*/
static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
int get_max)
{
- int limit = 0;
+ int limit;
+ int clocksrc;
int divisor;
- int selection;
- int err;
u32 tmp;
- struct bcm43xx_coreinfo *old_core;
- if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
- goto out;
- old_core = bcm->current_core;
- err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
- if (err)
- goto out;
+ assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL);
+ assert(bcm->current_core == &bcm->core_chipcommon);
+ clocksrc = bcm43xx_pctl_get_slowclksrc(bcm);
if (bcm->current_core->rev < 6) {
- if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) ||
- (bcm->bustype == BCM43xx_BUSTYPE_SB)) {
- selection = 1;
+ switch (clocksrc) {
+ case BCM43xx_PCTL_CLKSRC_PCI:
+ divisor = 64;
+ break;
+ case BCM43xx_PCTL_CLKSRC_XTALOS:
divisor = 32;
- } else {
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
- if (err) {
- printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n");
- goto out_switchback;
- }
- if (tmp & 0x10) {
- /* PCI */
- selection = 2;
- divisor = 64;
- } else {
- /* XTAL */
- selection = 1;
- divisor = 32;
- }
+ break;
+ default:
+ assert(0);
+ divisor = 1;
}
} else if (bcm->current_core->rev < 10) {
- selection = (tmp & 0x07);
- if (selection) {
+ switch (clocksrc) {
+ case BCM43xx_PCTL_CLKSRC_LOPWROS:
+ divisor = 1;
+ break;
+ case BCM43xx_PCTL_CLKSRC_XTALOS:
+ case BCM43xx_PCTL_CLKSRC_PCI:
tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
- divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
- } else
+ divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
+ divisor *= 4;
+ break;
+ default:
+ assert(0);
divisor = 1;
+ }
} else {
tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL);
- divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
- selection = 1;
+ divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
+ divisor *= 4;
}
-
- switch (selection) {
- case 0:
- /* LPO */
+
+ switch (clocksrc) {
+ case BCM43xx_PCTL_CLKSRC_LOPWROS:
if (get_max)
limit = 43000;
else
limit = 25000;
break;
- case 1:
- /* XTAL */
+ case BCM43xx_PCTL_CLKSRC_XTALOS:
if (get_max)
limit = 20200000;
else
limit = 19800000;
break;
- case 2:
- /* PCI */
+ case BCM43xx_PCTL_CLKSRC_PCI:
if (get_max)
limit = 34000000;
else
@@ -113,17 +137,14 @@ static int bcm43xx_pctl_clockfreqlimit(s
break;
default:
assert(0);
+ limit = 0;
}
limit /= divisor;
-out_switchback:
- err = bcm43xx_switch_core(bcm, old_core);
- assert(err == 0);
-
-out:
return limit;
}
+
/* init power control
* as described in http://bcm-specs.sipsolutions.net/PowerControl
*/
diff -puN drivers/net/wireless/bcm43xx/bcm43xx_power.h~bcm43xx-fix-pctl-slowclock-limit-calculation drivers/net/wireless/bcm43xx/bcm43xx_power.h
--- devel/drivers/net/wireless/bcm43xx/bcm43xx_power.h~bcm43xx-fix-pctl-slowclock-limit-calculation 2006-04-12 18:12:22.000000000 -0700
+++ devel-akpm/drivers/net/wireless/bcm43xx/bcm43xx_power.h 2006-04-12 18:12:22.000000000 -0700
@@ -33,6 +33,15 @@
#include <linux/types.h>
+/* Clock sources */
+enum {
+ /* PCI clock */
+ BCM43xx_PCTL_CLKSRC_PCI,
+ /* Crystal slow clock oscillator */
+ BCM43xx_PCTL_CLKSRC_XTALOS,
+ /* Low power oscillator */
+ BCM43xx_PCTL_CLKSRC_LOPWROS,
+};
struct bcm43xx_private;
_
^ permalink raw reply
* [patch 07/10] forcedeth: suggested cleanups
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff; +Cc: linville, netdev, akpm, ioe-lkml, manfred
From: Ingo Oeser <ioe-lkml@rameria.de>
general:
- endian annotation of the ring descriptors
nv_getlen():
- use htons() instead of __constant_htons()
to improvde readability and let the compiler constant fold it.
nv_rx_process():
- use a real for() loop in processing instead of goto and break
- consolidate rx_errors increment
- count detected rx_length_errors
Signed-off-by: Ingo Oeser <ioe-lkml@rameria.de>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/forcedeth.c | 59 ++++++++++++++++----------------------
1 files changed, 26 insertions(+), 33 deletions(-)
diff -puN drivers/net/forcedeth.c~forcedeth-suggested-cleanups drivers/net/forcedeth.c
--- devel/drivers/net/forcedeth.c~forcedeth-suggested-cleanups 2006-04-10 23:21:26.000000000 -0700
+++ devel-akpm/drivers/net/forcedeth.c 2006-04-10 23:21:26.000000000 -0700
@@ -328,17 +328,18 @@ enum {
NvRegMSIXIrqStatus = 0x3f0,
};
-/* Big endian: should work, but is untested */
+/* Big endian: should work, but is untested.
+ * So give arch maintainers a hint here. -ioe */
struct ring_desc {
- u32 PacketBuffer;
- u32 FlagLen;
+ __le32 PacketBuffer;
+ __le32 FlagLen;
};
struct ring_desc_ex {
- u32 PacketBufferHigh;
- u32 PacketBufferLow;
- u32 TxVlan;
- u32 FlagLen;
+ __le32 PacketBufferHigh;
+ __le32 PacketBufferLow;
+ __le32 TxVlan;
+ __le32 FlagLen;
};
typedef union _ring_type {
@@ -1403,7 +1404,7 @@ static int nv_getlen(struct net_device *
int protolen; /* length as stored in the proto field */
/* 1) calculate len according to header */
- if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == __constant_htons(ETH_P_8021Q)) {
+ if (((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) {
protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto );
hdrlen = VLAN_HLEN;
} else {
@@ -1453,12 +1454,10 @@ static void nv_rx_process(struct net_dev
u32 vlanflags = 0;
- for (;;) {
+ for (; np->cur_rx - np->refill_rx < RX_RING; np->cur_rx++) {
struct sk_buff *skb;
int len;
int i;
- if (np->cur_rx - np->refill_rx >= RX_RING)
- break; /* we scanned the whole ring - do not continue */
i = np->cur_rx % RX_RING;
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
@@ -1498,33 +1497,29 @@ static void nv_rx_process(struct net_dev
/* look at what we actually got: */
if (np->desc_ver == DESC_VER_1) {
if (!(Flags & NV_RX_DESCRIPTORVALID))
- goto next_pkt;
+ continue;
if (Flags & NV_RX_ERROR) {
if (Flags & NV_RX_MISSEDFRAME) {
np->stats.rx_missed_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
+ goto error_pkt;
}
if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
- np->stats.rx_errors++;
- goto next_pkt;
+ goto error_pkt;
}
if (Flags & NV_RX_CRCERR) {
np->stats.rx_crc_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
+ goto error_pkt;
}
if (Flags & NV_RX_OVERFLOW) {
np->stats.rx_over_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
+ goto error_pkt;
}
if (Flags & NV_RX_ERROR4) {
len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
if (len < 0) {
- np->stats.rx_errors++;
- goto next_pkt;
+ np->stats.rx_length_errors++;
+ goto error_pkt;
}
}
/* framing errors are soft errors. */
@@ -1536,28 +1531,25 @@ static void nv_rx_process(struct net_dev
}
} else {
if (!(Flags & NV_RX2_DESCRIPTORVALID))
- goto next_pkt;
+ continue;
if (Flags & NV_RX2_ERROR) {
if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) {
- np->stats.rx_errors++;
- goto next_pkt;
+ goto error_pkt;
}
if (Flags & NV_RX2_CRCERR) {
np->stats.rx_crc_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
+ goto error_pkt;
}
if (Flags & NV_RX2_OVERFLOW) {
np->stats.rx_over_errors++;
- np->stats.rx_errors++;
- goto next_pkt;
+ goto error_pkt;
}
if (Flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, np->rx_skbuff[i]->data, len);
if (len < 0) {
- np->stats.rx_errors++;
- goto next_pkt;
+ np->stats.rx_length_errors++;
+ goto error_pkt;
}
}
/* framing errors are soft errors */
@@ -1593,8 +1585,9 @@ static void nv_rx_process(struct net_dev
dev->last_rx = jiffies;
np->stats.rx_packets++;
np->stats.rx_bytes += len;
-next_pkt:
- np->cur_rx++;
+ continue;
+error_pkt:
+ np->stats.rx_errors++;
}
}
_
^ permalink raw reply
* [patch 06/10] e100: disable interrupts at boot
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff
Cc: linville, netdev, akpm, bjorn.helgaas, jeffrey.t.kirsher,
jesse.brandeburg, john.ronciak, nils.rennebarth, stern
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
Apparently the Intel PRO/100 device enables interrupts on reset. Unless
firmware explicitly disables PRO/100 interrupts, we can get a flood of
interrupts when a driver attaches to an unrelated device that happens to
share the PRO/100 IRQ.
This should resolve this "irq 11: nobody cared" bug report:
http://bugzilla.kernel.org/show_bug.cgi?id=5918
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: John Ronciak <john.ronciak@intel.com>
Cc: <stern@rowland.harvard.edu>
Cc: <nils.rennebarth@packetalarm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/pci/quirks.c | 57 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+)
diff -puN drivers/pci/quirks.c~e100-disable-interrupts-at-boot drivers/pci/quirks.c
--- devel/drivers/pci/quirks.c~e100-disable-interrupts-at-boot 2006-04-14 23:41:34.000000000 -0700
+++ devel-akpm/drivers/pci/quirks.c 2006-04-14 23:41:34.000000000 -0700
@@ -1374,6 +1374,63 @@ static void __devinit quirk_netmos(struc
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
+static void __devinit quirk_e100_interrupt(struct pci_dev *dev)
+{
+ u16 command;
+ u32 bar;
+ u8 __iomem *csr;
+ u8 cmd_hi;
+
+ switch (dev->device) {
+ /* PCI IDs taken from drivers/net/e100.c */
+ case 0x1029:
+ case 0x1030 ... 0x1034:
+ case 0x1038 ... 0x103E:
+ case 0x1050 ... 0x1057:
+ case 0x1059:
+ case 0x1064 ... 0x106B:
+ case 0x1091 ... 0x1095:
+ case 0x1209:
+ case 0x1229:
+ case 0x2449:
+ case 0x2459:
+ case 0x245D:
+ case 0x27DC:
+ break;
+ default:
+ return;
+ }
+
+ /*
+ * Some firmware hands off the e100 with interrupts enabled,
+ * which can cause a flood of interrupts if packets are
+ * received before the driver attaches to the device. So
+ * disable all e100 interrupts here. The driver will
+ * re-enable them when it's ready.
+ */
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar);
+
+ if (!(command & PCI_COMMAND_MEMORY) || !bar)
+ return;
+
+ csr = ioremap(bar, 8);
+ if (!csr) {
+ printk(KERN_WARNING "PCI: Can't map %s e100 registers\n",
+ pci_name(dev));
+ return;
+ }
+
+ cmd_hi = readb(csr + 3);
+ if (cmd_hi == 0) {
+ printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts "
+ "enabled, disabling\n", pci_name(dev));
+ writeb(1, csr + 3);
+ }
+
+ iounmap(csr);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
{
_
^ permalink raw reply
* [patch 08/10] bcm43xx: sysfs code cleanup
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff; +Cc: linville, netdev, akpm, mb, greg
From: Michael Buesch <mb@bu3sch.de>
This cleans up the bcm43xx sysfs code and makes it compliant with the
unwritten sysfs rules (at least I hope so).
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Cc: Jeff Garzik <jeff@garzik.org>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/wireless/bcm43xx/bcm43xx.h | 17 ++
drivers/net/wireless/bcm43xx/bcm43xx_main.c | 1
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 115 +++++++++--------
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h | 16 --
4 files changed, 82 insertions(+), 67 deletions(-)
diff -puN drivers/net/wireless/bcm43xx/bcm43xx.h~bcm43xx-sysfs-code-cleanup drivers/net/wireless/bcm43xx/bcm43xx.h
--- devel/drivers/net/wireless/bcm43xx/bcm43xx.h~bcm43xx-sysfs-code-cleanup 2006-04-12 18:11:12.000000000 -0700
+++ devel-akpm/drivers/net/wireless/bcm43xx/bcm43xx.h 2006-04-12 18:11:12.000000000 -0700
@@ -15,7 +15,6 @@
#include "bcm43xx_debugfs.h"
#include "bcm43xx_leds.h"
-#include "bcm43xx_sysfs.h"
#define PFX KBUILD_MODNAME ": "
@@ -638,8 +637,6 @@ struct bcm43xx_key {
};
struct bcm43xx_private {
- struct bcm43xx_sysfs sysfs;
-
struct ieee80211_device *ieee;
struct ieee80211softmac_device *softmac;
@@ -772,6 +769,20 @@ struct bcm43xx_private * bcm43xx_priv(st
return ieee80211softmac_priv(dev);
}
+struct device;
+
+static inline
+struct bcm43xx_private * dev_to_bcm(struct device *dev)
+{
+ struct net_device *net_dev;
+ struct bcm43xx_private *bcm;
+
+ net_dev = dev_get_drvdata(dev);
+ bcm = bcm43xx_priv(net_dev);
+
+ return bcm;
+}
+
/* Helper function, which returns a boolean.
* TRUE, if PIO is used; FALSE, if DMA is used.
diff -puN drivers/net/wireless/bcm43xx/bcm43xx_main.c~bcm43xx-sysfs-code-cleanup drivers/net/wireless/bcm43xx/bcm43xx_main.c
--- devel/drivers/net/wireless/bcm43xx/bcm43xx_main.c~bcm43xx-sysfs-code-cleanup 2006-04-12 18:11:12.000000000 -0700
+++ devel-akpm/drivers/net/wireless/bcm43xx/bcm43xx_main.c 2006-04-12 18:11:12.000000000 -0700
@@ -52,6 +52,7 @@
#include "bcm43xx_wx.h"
#include "bcm43xx_ethtool.h"
#include "bcm43xx_xmit.h"
+#include "bcm43xx_sysfs.h"
MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
diff -puN drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c~bcm43xx-sysfs-code-cleanup drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
--- devel/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c~bcm43xx-sysfs-code-cleanup 2006-04-12 18:11:12.000000000 -0700
+++ devel-akpm/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c 2006-04-12 18:11:12.000000000 -0700
@@ -71,14 +71,46 @@ static int get_boolean(const char *buf,
return -EINVAL;
}
+static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
+{
+ int i, pos = 0;
+
+ for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
+ pos += snprintf(buf + pos, buf_len - pos - 1,
+ "%04X", swab16(sprom[i]) & 0xFFFF);
+ }
+ pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
+
+ return pos + 1;
+}
+
+static int hex2sprom(u16 *sprom, const char *dump, size_t len)
+{
+ char tmp[5] = { 0 };
+ int cnt = 0;
+ unsigned long parsed;
+
+ if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
+ return -EINVAL;
+
+ while (cnt < BCM43xx_SPROM_SIZE) {
+ memcpy(tmp, dump, 4);
+ dump += 4;
+ parsed = simple_strtoul(tmp, NULL, 16);
+ sprom[cnt++] = swab16((u16)parsed);
+ }
+
+ return 0;
+}
+
static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
+ struct bcm43xx_private *bcm = dev_to_bcm(dev);
u16 *sprom;
unsigned long flags;
- int i, err;
+ int err;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
@@ -91,55 +123,53 @@ static ssize_t bcm43xx_attr_sprom_show(s
bcm43xx_lock_mmio(bcm, flags);
assert(bcm->initialized);
err = bcm43xx_sprom_read(bcm, sprom);
- if (!err) {
- for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
- buf[i * 2] = sprom[i] & 0x00FF;
- buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8;
- }
- }
+ if (!err)
+ err = sprom2hex(sprom, buf, PAGE_SIZE);
bcm43xx_unlock_mmio(bcm, flags);
kfree(sprom);
- return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16);
+ return err;
}
static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
+ struct bcm43xx_private *bcm = dev_to_bcm(dev);
u16 *sprom;
unsigned long flags;
- int i, err;
+ int err;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (count != BCM43xx_SPROM_SIZE * sizeof(u16))
- return -EINVAL;
sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
GFP_KERNEL);
if (!sprom)
return -ENOMEM;
- for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
- sprom[i] = buf[i * 2] & 0xFF;
- sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8;
- }
+ err = hex2sprom(sprom, buf, count);
+ if (err)
+ goto out_kfree;
bcm43xx_lock_mmio(bcm, flags);
assert(bcm->initialized);
err = bcm43xx_sprom_write(bcm, sprom);
bcm43xx_unlock_mmio(bcm, flags);
+out_kfree:
kfree(sprom);
return err ? err : count;
}
+static DEVICE_ATTR(sprom, 0600,
+ bcm43xx_attr_sprom_show,
+ bcm43xx_attr_sprom_store);
+
static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
+ struct bcm43xx_private *bcm = dev_to_bcm(dev);
unsigned long flags;
int err;
ssize_t count = 0;
@@ -175,7 +205,7 @@ static ssize_t bcm43xx_attr_interfmode_s
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
+ struct bcm43xx_private *bcm = dev_to_bcm(dev);
unsigned long flags;
int err;
int mode;
@@ -215,11 +245,15 @@ static ssize_t bcm43xx_attr_interfmode_s
return err ? err : count;
}
+static DEVICE_ATTR(interference, 0644,
+ bcm43xx_attr_interfmode_show,
+ bcm43xx_attr_interfmode_store);
+
static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
+ struct bcm43xx_private *bcm = dev_to_bcm(dev);
unsigned long flags;
int err;
ssize_t count;
@@ -245,7 +279,7 @@ static ssize_t bcm43xx_attr_preamble_sto
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
+ struct bcm43xx_private *bcm = dev_to_bcm(dev);
unsigned long flags;
int err;
int value;
@@ -267,56 +301,41 @@ static ssize_t bcm43xx_attr_preamble_sto
return err ? err : count;
}
+static DEVICE_ATTR(shortpreamble, 0644,
+ bcm43xx_attr_preamble_show,
+ bcm43xx_attr_preamble_store);
+
int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
{
struct device *dev = &bcm->pci_dev->dev;
- struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
int err;
assert(bcm->initialized);
- sysfs->attr_sprom.attr.name = "sprom";
- sysfs->attr_sprom.attr.owner = THIS_MODULE;
- sysfs->attr_sprom.attr.mode = 0600;
- sysfs->attr_sprom.show = bcm43xx_attr_sprom_show;
- sysfs->attr_sprom.store = bcm43xx_attr_sprom_store;
- err = device_create_file(dev, &sysfs->attr_sprom);
+ err = device_create_file(dev, &dev_attr_sprom);
if (err)
goto out;
-
- sysfs->attr_interfmode.attr.name = "interference";
- sysfs->attr_interfmode.attr.owner = THIS_MODULE;
- sysfs->attr_interfmode.attr.mode = 0600;
- sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show;
- sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store;
- err = device_create_file(dev, &sysfs->attr_interfmode);
+ err = device_create_file(dev, &dev_attr_interference);
if (err)
goto err_remove_sprom;
-
- sysfs->attr_preamble.attr.name = "shortpreamble";
- sysfs->attr_preamble.attr.owner = THIS_MODULE;
- sysfs->attr_preamble.attr.mode = 0600;
- sysfs->attr_preamble.show = bcm43xx_attr_preamble_show;
- sysfs->attr_preamble.store = bcm43xx_attr_preamble_store;
- err = device_create_file(dev, &sysfs->attr_preamble);
+ err = device_create_file(dev, &dev_attr_shortpreamble);
if (err)
goto err_remove_interfmode;
out:
return err;
err_remove_interfmode:
- device_remove_file(dev, &sysfs->attr_interfmode);
+ device_remove_file(dev, &dev_attr_interference);
err_remove_sprom:
- device_remove_file(dev, &sysfs->attr_sprom);
+ device_remove_file(dev, &dev_attr_sprom);
goto out;
}
void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
{
struct device *dev = &bcm->pci_dev->dev;
- struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
- device_remove_file(dev, &sysfs->attr_preamble);
- device_remove_file(dev, &sysfs->attr_interfmode);
- device_remove_file(dev, &sysfs->attr_sprom);
+ device_remove_file(dev, &dev_attr_shortpreamble);
+ device_remove_file(dev, &dev_attr_interference);
+ device_remove_file(dev, &dev_attr_sprom);
}
diff -puN drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h~bcm43xx-sysfs-code-cleanup drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
--- devel/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h~bcm43xx-sysfs-code-cleanup 2006-04-12 18:11:12.000000000 -0700
+++ devel-akpm/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h 2006-04-12 18:11:12.000000000 -0700
@@ -1,22 +1,6 @@
#ifndef BCM43xx_SYSFS_H_
#define BCM43xx_SYSFS_H_
-#include <linux/device.h>
-
-
-struct bcm43xx_sysfs {
- struct device_attribute attr_sprom;
- struct device_attribute attr_interfmode;
- struct device_attribute attr_preamble;
-};
-
-#define devattr_to_bcm(attr, attr_name) ({ \
- struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p; \
- __s = container_of((attr), struct bcm43xx_sysfs, attr_name); \
- __p = container_of(__s, struct bcm43xx_private, sysfs); \
- __p; \
- })
-
struct bcm43xx_private;
int bcm43xx_sysfs_register(struct bcm43xx_private *bcm);
_
^ permalink raw reply
* [patch 10/10] e1000: fix media_type <-> phy_type thinko
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff; +Cc: linville, netdev, akpm, willy, jesse.brandeburg, john.ronciak
From: Willy TARREAU <willy@w.ods.org>
Recent patch cb764326dff0ee51aca0d450e1a292de65661055 introduced a thinko
in e1000_main.c : e1000_media_type_copper is compared to hw.phy_type
instead of hw.media_type. Original patch proposed by Jesse Brandeburg was
correct, but what has been merged is not.
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: "Ronciak, John" <john.ronciak@intel.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/e1000/e1000_main.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -puN drivers/net/e1000/e1000_main.c~e1000-fix-media_type-phy_type-thinko drivers/net/e1000/e1000_main.c
--- devel/drivers/net/e1000/e1000_main.c~e1000-fix-media_type-phy_type-thinko 2006-04-17 21:42:32.000000000 -0700
+++ devel-akpm/drivers/net/e1000/e1000_main.c 2006-04-17 21:43:30.000000000 -0700
@@ -4195,7 +4195,7 @@ e1000_mii_ioctl(struct net_device *netde
spin_unlock_irqrestore(&adapter->stats_lock, flags);
return -EIO;
}
- if (adapter->hw.phy_type == e1000_media_type_copper) {
+ if (adapter->hw.media_type == e1000_media_type_copper) {
switch (data->reg_num) {
case PHY_CTRL:
if (mii_reg & MII_CR_POWER_DOWN)
_
^ permalink raw reply
* [patch 05/10] e1000: prevent statistics from getting garbled during reset
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff
Cc: linville, netdev, akpm, linas, jeffrey.t.kirsher,
jesse.brandeburg, john.ronciak
From: Linas Vepstas <linas@austin.ibm.com>
If a PCI bus error/fault triggers a PCI bus reset, attempts to get the
ethernet packet count statistics from the hardware will fail, returning
garbage data upstream. This patch skips statistics data collection if the
PCI device is not on the bus.
This patch presumes that an earlier patch,
[PATCH] PCI Error Recovery: e1000 network device driver
has already been applied.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: John Ronciak <john.ronciak@intel.com>
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/e1000/e1000_main.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletion(-)
diff -puN drivers/net/e1000/e1000_main.c~e1000-prevent-statistics-from-getting-garbled-during-reset drivers/net/e1000/e1000_main.c
--- devel/drivers/net/e1000/e1000_main.c~e1000-prevent-statistics-from-getting-garbled-during-reset 2006-04-14 23:41:34.000000000 -0700
+++ devel-akpm/drivers/net/e1000/e1000_main.c 2006-04-14 23:41:34.000000000 -0700
@@ -3082,14 +3082,20 @@ void
e1000_update_stats(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
unsigned long flags;
uint16_t phy_tmp;
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
- /* Prevent stats update while adapter is being reset */
+ /*
+ * Prevent stats update while adapter is being reset, or if the pci
+ * connection is down.
+ */
if (adapter->link_speed == 0)
return;
+ if (pdev->error_state && pdev->error_state != pci_channel_io_normal)
+ return;
spin_lock_irqsave(&adapter->stats_lock, flags);
_
^ permalink raw reply
* [patch 04/10] PCI Error Recovery: e100 network device driver
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff; +Cc: linville, netdev, akpm, linas, jesse.brandeburg
From: linas@austin.ibm.com (Linas Vepstas)
Various PCI bus errors can be signaled by newer PCI controllers. This
patch adds the PCI error recovery callbacks to the intel ethernet e100
device driver. The patch has been tested, and appears to work well.
Signed-off-by: Linas Vepstas <linas@linas.org>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/e100.c | 75 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 75 insertions(+)
diff -puN drivers/net/e100.c~pci-error-recovery-e100-network-device-driver drivers/net/e100.c
--- devel/drivers/net/e100.c~pci-error-recovery-e100-network-device-driver 2006-04-10 23:21:20.000000000 -0700
+++ devel-akpm/drivers/net/e100.c 2006-04-10 23:21:20.000000000 -0700
@@ -2726,6 +2726,80 @@ static void e100_shutdown(struct pci_dev
DPRINTK(PROBE,ERR, "Error enabling wake\n");
}
+/* ------------------ PCI Error Recovery infrastructure -------------- */
+/**
+ * e100_io_error_detected - called when PCI error is detected.
+ * @pdev: Pointer to PCI device
+ * @state: The current pci conneection state
+ */
+static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+
+ /* Similar to calling e100_down(), but avoids adpater I/O. */
+ netdev->stop(netdev);
+
+ /* Detach; put netif into state similar to hotplug unplug. */
+ netif_poll_enable(netdev);
+ netif_device_detach(netdev);
+
+ /* Request a slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * e100_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch.
+ */
+static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct nic *nic = netdev_priv(netdev);
+
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ /* Only one device per card can do a reset */
+ if (0 != PCI_FUNC(pdev->devfn))
+ return PCI_ERS_RESULT_RECOVERED;
+ e100_hw_reset(nic);
+ e100_phy_init(nic);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * e100_io_resume - resume normal operations
+ * @pdev: Pointer to PCI device
+ *
+ * Resume normal operations after an error recovery
+ * sequence has been completed.
+ */
+static void e100_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct nic *nic = netdev_priv(netdev);
+
+ /* ack any pending wake events, disable PME */
+ pci_enable_wake(pdev, 0, 0);
+
+ netif_device_attach(netdev);
+ if (netif_running(netdev)) {
+ e100_open(netdev);
+ mod_timer(&nic->watchdog, jiffies);
+ }
+}
+
+static struct pci_error_handlers e100_err_handler = {
+ .error_detected = e100_io_error_detected,
+ .slot_reset = e100_io_slot_reset,
+ .resume = e100_io_resume,
+};
static struct pci_driver e100_driver = {
.name = DRV_NAME,
@@ -2737,6 +2811,7 @@ static struct pci_driver e100_driver = {
.resume = e100_resume,
#endif
.shutdown = e100_shutdown,
+ .err_handler = &e100_err_handler,
};
static int __init e100_init_module(void)
_
^ permalink raw reply
* [patch 03/10] PCI Error Recovery: e1000 network device driver
From: akpm @ 2006-04-19 4:04 UTC (permalink / raw)
To: jeff; +Cc: linville, netdev, akpm, linas, jesse.brandeburg
From: Linas Vepstas <linas@linas.org>
Various PCI bus errors can be signaled by newer PCI controllers. This
patch adds the PCI error recovery callbacks to the intel gigabit ethernet
e1000 device driver. The patch has been tested, and appears to work well.
[akpm@osdl.org: minor cleanups]
Signed-off-by: Linas Vepstas <linas@linas.org>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/e1000/e1000_main.c | 116 ++++++++++++++++++++++++++++++-
1 files changed, 115 insertions(+), 1 deletion(-)
diff -puN drivers/net/e1000/e1000_main.c~pci-error-recovery-e1000-network-device-driver drivers/net/e1000/e1000_main.c
--- devel/drivers/net/e1000/e1000_main.c~pci-error-recovery-e1000-network-device-driver 2006-04-14 23:41:33.000000000 -0700
+++ devel-akpm/drivers/net/e1000/e1000_main.c 2006-04-14 23:41:33.000000000 -0700
@@ -227,6 +227,16 @@ static int e1000_resume(struct pci_dev *
static void e1000_netpoll (struct net_device *netdev);
#endif
+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state);
+static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
+static void e1000_io_resume(struct pci_dev *pdev);
+
+static struct pci_error_handlers e1000_err_handler = {
+ .error_detected = e1000_io_error_detected,
+ .slot_reset = e1000_io_slot_reset,
+ .resume = e1000_io_resume,
+};
static struct pci_driver e1000_driver = {
.name = e1000_driver_name,
@@ -236,8 +246,9 @@ static struct pci_driver e1000_driver =
/* Power Managment Hooks */
#ifdef CONFIG_PM
.suspend = e1000_suspend,
- .resume = e1000_resume
+ .resume = e1000_resume,
#endif
+ .err_handler = &e1000_err_handler,
};
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
@@ -3076,6 +3087,10 @@ e1000_update_stats(struct e1000_adapter
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
+ /* Prevent stats update while adapter is being reset */
+ if (adapter->link_speed == 0)
+ return;
+
spin_lock_irqsave(&adapter->stats_lock, flags);
/* these counters are modified from e1000_adjust_tbi_stats,
@@ -4626,4 +4641,103 @@ e1000_netpoll(struct net_device *netdev)
}
#endif
+/**
+ * e1000_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci conneection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev->priv;
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ e1000_down(adapter);
+
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * e1000_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev->priv;
+
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "e1000: Cannot re-enable PCI device after "
+ "reset.\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, 3, 0);
+ pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+
+ /* Perform card reset only on one instance of the card */
+ if (PCI_FUNC (pdev->devfn) != 0)
+ return PCI_ERS_RESULT_RECOVERED;
+
+ e1000_reset(adapter);
+ E1000_WRITE_REG(&adapter->hw, WUS, ~0);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * e1000_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the e1000_resume routine.
+ */
+static void e1000_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev->priv;
+ uint32_t manc, swsm;
+
+ if (netif_running(netdev)) {
+ if (e1000_up(adapter)) {
+ printk(KERN_ERR "e1000: can't bring device back up "
+ "after reset\n");
+ return;
+ }
+ }
+
+ netif_device_attach(netdev);
+
+ if (adapter->hw.mac_type >= e1000_82540 &&
+ adapter->hw.media_type == e1000_media_type_copper) {
+ manc = E1000_READ_REG(&adapter->hw, MANC);
+ manc &= ~(E1000_MANC_ARP_EN);
+ E1000_WRITE_REG(&adapter->hw, MANC, manc);
+ }
+
+ switch (adapter->hw.mac_type) {
+ case e1000_82573:
+ swsm = E1000_READ_REG(&adapter->hw, SWSM);
+ E1000_WRITE_REG(&adapter->hw, SWSM, swsm | E1000_SWSM_DRV_LOAD);
+ break;
+ default:
+ break;
+ }
+
+ if (netif_running(netdev))
+ mod_timer(&adapter->watchdog_timer, jiffies);
+}
+
/* e1000_main.c */
_
^ permalink raw reply
* [patch 01/10] tulip: NatSemi DP83840A PHY fix
From: akpm @ 2006-04-19 4:03 UTC (permalink / raw)
To: jeff; +Cc: linville, netdev, akpm, T-Bone, grundler, jgarzik, varenet
From: Thibaut VARENE <T-Bone@parisc-linux.org>
Fix a problem with Tulip 21142 HP branded PCI cards (PN#: B5509-66001),
which feature a NatSemi DP83840A PHY.
Without that patch, it is impossible to properly initialize the card's PHY,
and it's thus impossible to monitor/configure it.
It's a timing/posting problem, and it is solved exactly the same way Grant
fixed it elsewhere already.
Signed-off-by: Thibaut VARENE <varenet@parisc-linux.org>
Cc: Jeff Garzik <jgarzik@pobox.com>
Acked-by: Grant Grundler <grundler@parisc-linux.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
drivers/net/tulip/media.c | 18 +++++++++++++++++-
1 files changed, 17 insertions(+), 1 deletion(-)
diff -puN drivers/net/tulip/media.c~tulip-natsemi-dp83840a-phy-fix drivers/net/tulip/media.c
--- devel/drivers/net/tulip/media.c~tulip-natsemi-dp83840a-phy-fix 2006-04-10 23:21:18.000000000 -0700
+++ devel-akpm/drivers/net/tulip/media.c 2006-04-10 23:21:18.000000000 -0700
@@ -261,11 +261,27 @@ void tulip_select_media(struct net_devic
u16 *reset_sequence = &((u16*)(p+3))[init_length];
int reset_length = p[2 + init_length*2];
misc_info = reset_sequence + reset_length;
- if (startup)
+ if (startup) {
+ int timeout = 10; /* max 1 ms */
for (i = 0; i < reset_length; i++)
iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
+
+ /* flush posted writes */
+ ioread32(ioaddr + CSR15);
+
+ /* Sect 3.10.3 in DP83840A.pdf (p39) */
+ udelay(500);
+
+ /* Section 4.2 in DP83840A.pdf (p43) */
+ /* and IEEE 802.3 "22.2.4.1.1 Reset" */
+ while (timeout-- &&
+ (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
+ udelay(100);
+ }
for (i = 0; i < init_length; i++)
iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
+
+ ioread32(ioaddr + CSR15); /* flush posted writes */
} else {
u8 *init_sequence = p + 2;
u8 *reset_sequence = p + 3 + init_length;
_
^ permalink raw reply
* Re: [PATCH] ip_route_input panic fix
From: David S. Miller @ 2006-04-19 3:53 UTC (permalink / raw)
To: kuznet; +Cc: herbert, shemminger, netdev
In-Reply-To: <20060418235222.GA20504@ms2.inr.ac.ru>
From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Date: Wed, 19 Apr 2006 03:52:22 +0400
> Actually, this weird case in inet_get_route() is the only place, where
> a dummy skb is used and it is needed mostly to resolve multicast routes.
> In this case this fake skb really passes through all the engine, even
> delivered to user space in some sense, and when the route is resolved,
> the same skb is submitted to netlink socket. I remember, Dave found
> something very bad about this and this even deserved a place in TODO list,
> but franky speaking I did not understand what is so wrong with this trick.
Problem there is via rt_fill_info(). When multicast route cannot be
found by ipmr, it tries to use this netlink SKB to send out a probe.
ipmr_get_route() is the trouble maker. If ipmr_cache_find() cannot
find an entry, it tries to use the netlink SKB to send out an ipv4
packet, completely mangling it, via ipmr_cache_unresolved().
Even worse it may even free the skb on us, or queue it to
mroute_socket.
It is pure disaster, this entire code path.
^ permalink raw reply
* Re: [PATCH 0/4]: Fix several errors in extension header handling.
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-04-19 2:17 UTC (permalink / raw)
To: netdev
In-Reply-To: <20060418.144914.24796175.davem@davemloft.net>
In article <20060418.144914.24796175.davem@davemloft.net> (at Tue, 18 Apr 2006 14:49:14 -0700 (PDT)), "David S. Miller" <davem@davemloft.net> says:
> All applied, and I agree with pushing 1-3 into -stable,
> please send it.
Done. Thanks.
--yoshfuji
^ permalink raw reply
* Re: [PATCH] ip_route_input panic fix
From: Alexey Kuznetsov @ 2006-04-19 0:59 UTC (permalink / raw)
To: herbert, shemminger, davem, netdev
Hello!
> There is also the ARP code which passes an ARP packet through that
> would get dereferenced as an IP packet. Granted this shouldn't crash
> because nh is set properly.
And point to something which is not an IP header. So, iph->protocol
is something funny. :-)
It is plain luck that this never happens, ARP packets
with multicast addresses are filtered out.
Mess, I agree.
> But we really should make up our mind as to whether the routing key
> comes from the arguments to ip_route_input (src/dst/...) or the skb.
>
> Using both is just asking for trouble.
Well, both sets are present only for use the same function in ARP.
So, arguments. skb can be even preserved, but it should not be used
for anything but debugging or for hints, when we should not create
cache entry.
BTW, I cannot figure out what ip_check_mc tries to do with protocol
(which is __u16 by some reason). If it creates cache entry, protocol
is not checked. Funny.
Alexey
^ permalink raw reply
* Re: [PATCH 2.6.16-rc5] S2io: Receive packet classification and steering mechanisms
From: Andi Kleen @ 2006-04-19 0:59 UTC (permalink / raw)
To: ravinandan.arakali; +Cc: jgarzik, netdev
In-Reply-To: <MAEEKMLDLDFEGKHNIJHIAEIGCDAA.ravinandan.arakali@neterion.com>
On Wednesday 19 April 2006 02:38, Ravinandan Arakali wrote:
> configuration: A mask(specified using loadable parameter rth_fn_and_mask)
> can be used to select a subset of TCP/UDP tuple for hash calculation.
> eg. To mask source port for TCP/IPv4 configuration,
> # insmod s2io.ko rx_steering_type=2 rth_fn_and_mask=0x0101
> LSB specifies RTH function type and MSB the mask. A full description
> is provided at the beginning of s2io.c
I don't think it's a good idea to introduce such weird and hard to understand
module parameters for this. I would be better to define a generic
internal kernel interface between stack and driver. Perhaps starting
with a standard netlink interface for this might be a good start
until the stack learns how to use this on its own.
> 3. MAC address-based:
> Done based on destination MAC address of packet. Xframe can be
> configured with multiple unicast MAC addresses.
>
> configuration: Load-time parameters multi_mac_cnt and multi_macs
> can be used to specify no. of MAC addresses and list of unicast
> addresses.
> eg. insmod s2io.ko rx_steering_type=8 multi_mac_cnt=3
> multi_macs=00:0c:fc:00:00:22, 00:0c:fc:00:01:22, 00:0c:fc:00:02:22
> Packets received with default destination MAC address will be steered to
> ring0. Packets with destination MAC addresses specified by multi_macs are
> steered to ring1, ring2... respectively.
The obvious way to do this nicely would be to allow to define multiple
virtual interfaces where the mac addresses can be set using the usual ioctls.
-Andi
^ permalink raw reply
* Re: [PATCH] ip_route_input panic fix
From: Alexey Kuznetsov @ 2006-04-19 1:00 UTC (permalink / raw)
To: herbert, shemminger, davem, netdev
Hello!
> There is also the ARP code which passes an ARP packet through that
> would get dereferenced as an IP packet. Granted this shouldn't crash
> because nh is set properly.
And points to something which is not an IP header. So, iph->protocol
is something funny. :-)
It is plain luck that this never happens, ARP packets
with multicast addresses are filtered out.
Mess, I agree.
> But we really should make up our mind as to whether the routing key
> comes from the arguments to ip_route_input (src/dst/...) or the skb.
>
> Using both is just asking for trouble.
Well, both sets are present only for use the same function in ARP.
So, arguments. Actually, skb can be preserved, but it should not be used
for anything but debugging or for hints, when we should not create
cache entry.
BTW, I cannot figure out what ip_check_mc() tries to do with protocol
(which is __u16 by some reason). If it creates cache entry, protocol
is not checked. Funny.
Alexey
^ permalink raw reply
* RE: [PATCH 2.6.16-rc5] S2io: Receive packet classification and steering mechanisms
From: Ravinandan Arakali @ 2006-04-19 0:38 UTC (permalink / raw)
To: jgarzik, netdev
In-Reply-To: <MAEEKMLDLDFEGKHNIJHICENMCCAA.ravinandan.arakali@neterion.com>
Hi Jeff,
Any comments on the below patch ?
Thanks,
Ravi
-----Original Message-----
From: Ravinandan Arakali [mailto:Ravinandan.Arakali@neterion.com]
Sent: Friday, March 10, 2006 12:32 PM
To: jgarzik@pobox.com; netdev@vger.kernel.org
Cc: raghavendra.koushik@neterion.com; ravinandan.arakali@neterion.com;
leonid.grossman@neterion.com; rapuru.sriram@neterion.com;
ananda.raju@neterion.com; alicia.pena@neterion.com;
sivakumar.subramani@neterion.com
Subject: [PATCH 2.6.16-rc5] S2io: Receive packet classification and
steering mechanisms
Hi,
Attached below is a patch to several receive packet classification
and steering mechanisms for Xframe NIC hw channels. Current Xframe ASIC
supports one hardware channel per CPU, up to 8 channels. This number
will increase in the next ASIC release. A channel could be attached to a
specific MSI-X vector (with an independent interrupt moderation scheme),
which in turn can be bound to a CPU.
Follow-up patches will provide some enhancements for the default tcp
workload balancing across hw channels, as well as an optional hw channel
interface. The interface is intended to be very generic (not specific to
Xframe hardware).
The following mechanisms are supported in this patch:
Note: The steering type can be specified at load time with
parameter rx_steering_type. Values supported are 1(port based),
2(RTH), 4(SPDM), 8(MAC addr based).
1. RTH(Receive traffic hashing):
Steering is based on socket tuple (or a subset) and the popular Jenkins
hash is used for RTH. This lets the receive processing to be spanned out
to multiple CPUs, thus reducing single CPU bottleneck on Rx path.
Hash-based steering can be used when it is desired to balance an
unlimited number or TCP sessions across multiple CPUs but the exact
mapping between a particular session and a particular cpu is not
important.
configuration: A mask(specified using loadable parameter rth_fn_and_mask)
can be used to select a subset of TCP/UDP tuple for hash calculation.
eg. To mask source port for TCP/IPv4 configuration,
# insmod s2io.ko rx_steering_type=2 rth_fn_and_mask=0x0101
LSB specifies RTH function type and MSB the mask. A full description
is provided at the beginning of s2io.c
2. port based:
Steering is done based on source/destination TCP/UDP port number.
configuration: Interface used is netlink sockets. Can specify port
number(s), TCP/UDP type, source/destination port.
3. MAC address-based:
Done based on destination MAC address of packet. Xframe can be
configured with multiple unicast MAC addresses.
configuration: Load-time parameters multi_mac_cnt and multi_macs
can be used to specify no. of MAC addresses and list of unicast
addresses.
eg. insmod s2io.ko rx_steering_type=8 multi_mac_cnt=3
multi_macs=00:0c:fc:00:00:22, 00:0c:fc:00:01:22, 00:0c:fc:00:02:22
Packets received with default destination MAC address will be steered to
ring0. Packets with destination MAC addresses specified by multi_macs are
steered to ring1, ring2... respectively.
4. SPDM (Socket Pair Direct Match).
Steering is based on exact socket tuple (or a subset) match.
SPDM steering can be used when the exact mapping between a particular
session and a particular cpu is desired.
configuration: Interface used is netlink sockets. Can specify
socket tuple values. If any of the values(say source port) needs
to be "don't care", specify 0xFFFF.
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@neterion.com>
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com>
---
^ permalink raw reply
* Re: [PATCH] ip_route_input panic fix
From: Herbert Xu @ 2006-04-19 0:17 UTC (permalink / raw)
To: Alexey Kuznetsov; +Cc: Stephen Hemminger, davem, netdev
In-Reply-To: <20060418235222.GA20504@ms2.inr.ac.ru>
On Wed, Apr 19, 2006 at 03:52:22AM +0400, Alexey Kuznetsov wrote:
>
> Actually, this weird case in inet_get_route() is the only place, where
There is also the ARP code which passes an ARP packet through that
would get dereferenced as an IP packet. Granted this shouldn't crash
because nh is set properly.
But we really should make up our mind as to whether the routing key
comes from the arguments to ip_route_input (src/dst/...) or the skb.
Using both is just asking for trouble.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH] softmac: report SIOCGIWAP event upon association
From: Daniel Drake @ 2006-04-19 0:02 UTC (permalink / raw)
To: johannes; +Cc: softmac-dev, netdev
wpa_supplicant requires some notification when association has completed, and
this is the way to do it.
Before this patch, wpa_supplicant just times out when trying to associate,
even though the association completed successfully in the background. This was
reported at
http://www.mail-archive.com/bcm43xx-dev@lists.berlios.de/msg00959.html
After this patch, wpa_supplicant works for me. I have tested connecting to a
WEP network.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
--- linux/net/ieee80211/softmac/ieee80211softmac_assoc.c.orig 2006-04-16 23:55:23.000000000 +0100
+++ linux/net/ieee80211/softmac/ieee80211softmac_assoc.c 2006-04-19 01:08:40.000000000 +0100
@@ -282,6 +282,8 @@ ieee80211softmac_associated(struct ieee8
struct ieee80211_assoc_response * resp,
struct ieee80211softmac_network *net)
{
+ union iwreq_data wrqu;
+
mac->associnfo.associating = 0;
mac->associated = 1;
if (mac->set_bssid_filter)
@@ -290,6 +292,10 @@ ieee80211softmac_associated(struct ieee8
netif_carrier_on(mac->dev);
mac->association_id = le16_to_cpup(&resp->aid);
+
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(wrqu.ap_addr.sa_data, net->bssid, ETH_ALEN);
+ wireless_send_event(mac->dev, SIOCGIWAP, &wrqu, NULL);
}
/* received frame handling functions */
^ permalink raw reply
* Re: [RFC: 2.6 patch] net/netlink/: possible cleanups
From: Philip Craig @ 2006-04-19 0:02 UTC (permalink / raw)
To: David S. Miller; +Cc: bunk, netdev, linux-kernel
In-Reply-To: <20060413.132603.94193712.davem@davemloft.net>
On 04/14/2006 06:26 AM, David S. Miller wrote:
> These interfaces were added so that new users of netlink could
> write their code more easily.
>
> Unused does not equate to "comment out or delete".
Does a GENETLINK Kconfig option make sense (possibly dependant on
EMBEDDED)? I'm unsure whether these interfaces are going to be used
in core networking code that can't be disabled anyway.
^ permalink raw reply
* Re: [PATCH] ip_route_input panic fix
From: Alexey Kuznetsov @ 2006-04-18 23:52 UTC (permalink / raw)
To: Herbert Xu; +Cc: Stephen Hemminger, davem, netdev
In-Reply-To: <E1FVk6q-0000Tf-00@gondolin.me.apana.org.au>
Hello!
> Looking at this again, the root of this problem is the IGMPv3
> patch which started using the skb->nh.iph->protocol as a key.
No, root is that this fake skb was not properly initialized.
It should, it should be a good real IP skb.
> In fact I'm unsure as to whether all the other users of ip_route_input
> is safe as it is regarding the protocol.
ip_route_input takes skb as an argument exactly because it needs nothing
but skb and there is always an skb, when we "input".
ip_route_output would be happy to take an skb as well,
but unfortuntely it happens before we have an skb.
I do not see anything scary here: agree, when skb->nh happens to be undefined,
such skb would crash almost any place in IP stack. :-)
Actually, this weird case in inet_get_route() is the only place, where
a dummy skb is used and it is needed mostly to resolve multicast routes.
In this case this fake skb really passes through all the engine, even
delivered to user space in some sense, and when the route is resolved,
the same skb is submitted to netlink socket. I remember, Dave found
something very bad about this and this even deserved a place in TODO list,
but franky speaking I did not understand what is so wrong with this trick.
Alexey
^ permalink raw reply
* Re: [TCP]: Fix truesize underflow
From: Herbert Xu @ 2006-04-18 23:27 UTC (permalink / raw)
To: David S. Miller
Cc: bb, kernel, nipsy, jesse.brandeburg, jrlundgren, cat, djani22,
yoseph.basri, mykleb, olel, michal, chris, netdev,
jesse.brandeburg, ak, jgarzik
In-Reply-To: <20060418.132256.110004342.davem@davemloft.net>
On Tue, Apr 18, 2006 at 01:22:56PM -0700, David S. Miller wrote:
>
> I think it is deserving of some run time assertions, else these bugs
> will elude us continually. Luckily there are only a few places that
> would need the run time assertion checks on skb->truesize, and I'll
> try to spend a few cycles on implementing this soon.
Yes indeed. One place that comes to mind would be tcp_trim_head just
before we munge truesize.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [patch] Re: r8169 locks up in 2.6.16.5
From: Francois Romieu @ 2006-04-18 23:04 UTC (permalink / raw)
To: Thomas A. Oehser; +Cc: netdev
In-Reply-To: <20060418004358.GA8967@jupiter.toms.net>
Thomas A. Oehser <tom@toms.net> :
[...]
> It is actually about a 30GB transfer, it was just after the first
> 170Mb that it failed. The command in question is just a simple
> "nc -l -p 12345|buffer|cpio -iumdB", and the sender may well be
> able to generate the data faster than the receiving disk can save
> it, as the sender is a raid-1 mirror and the receiver is a raid-5
> array, I would expect the raid-5 write penalty and the raid-1 read
> speed to make it have to block for most of the transfer. It didn't
> take long to get that far- um, I think only 2 or 3 minutes before
> it locked up.
The r8169 offers 48 kb of Rx fifo. 170 Mb in 2~3 minutes is under 2 Mb/s.
Even if the traffic is very bursty, something seems to stall the PCI bus.
I'm a bit surprized.
Anyway, can you give the patch below a try and tell if it changes
something ? If so, an updated output of 'ethtool -S' would be welcome.
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 0ad3310..f9da390 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -256,10 +256,11 @@ enum RTL8169_register_content {
RxOK = 0x01,
/* RxStatusDesc */
- RxRES = 0x00200000,
- RxCRC = 0x00080000,
- RxRUNT = 0x00100000,
- RxRWT = 0x00400000,
+ RxFOVF = (1 << 23),
+ RxRWT = (1 << 22),
+ RxRES = (1 << 21),
+ RxRUNT = (1 << 20),
+ RxCRC = (1 << 19),
/* ChipCmdBits */
CmdReset = 0x10,
@@ -2435,6 +2436,10 @@ rtl8169_rx_interrupt(struct net_device *
tp->stats.rx_length_errors++;
if (status & RxCRC)
tp->stats.rx_crc_errors++;
+ if (status & RxFOVF) {
+ rtl8169_schedule_work(dev, rtl8169_reset_task);
+ tp->stats.rx_fifo_errors++;
+ }
rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
} else {
struct sk_buff *skb = tp->Rx_skbuff[entry];
^ permalink raw reply related
* Re: [PATCH] ip_route_input panic fix
From: Herbert Xu @ 2006-04-18 22:08 UTC (permalink / raw)
To: David S. Miller; +Cc: shemminger, netdev
In-Reply-To: <20060418.145416.114278524.davem@davemloft.net>
On Tue, Apr 18, 2006 at 02:54:16PM -0700, David S. Miller wrote:
>
> There are other areas of the packet which are interpreted in various
> ways. For example, the martian source handling will dump the MAC
> directly from skb->mac.raw into the kernel logs.
That's scary. I think this stuff needs an audit.
> The output path is so much cleaner, because things like the protocol
> are filled out in the struct flowi so there is no need to be parsing
> the SKB in any way.
Absolutely. I think we should put Stephen's patch in ASAP. Once the
immediate problem is gone we can take our time and make the input path
more like the output.
At the end of this I'd like to see the skb argument from ip_route_input
replaced by a dst_entry.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] ip_route_input panic fix
From: David S. Miller @ 2006-04-18 21:54 UTC (permalink / raw)
To: herbert; +Cc: shemminger, netdev
In-Reply-To: <E1FVk6q-0000Tf-00@gondolin.me.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 18 Apr 2006 16:54:48 +1000
> Looking at this again, the root of this problem is the IGMPv3
> patch which started using the skb->nh.iph->protocol as a key.
>
> So what we really should do is make the protocol an explicit parameter
> to the ip_route_input function. This will make it clear to all the
> users which include some pretty weird cases that the protocol is needed.
>
> In fact I'm unsure as to whether all the other users of ip_route_input
> is safe as it is regarding the protocol.
There are other areas of the packet which are interpreted in various
ways. For example, the martian source handling will dump the MAC
directly from skb->mac.raw into the kernel logs.
The output path is so much cleaner, because things like the protocol
are filled out in the struct flowi so there is no need to be parsing
the SKB in any way.
^ permalink raw reply
* Re: [PATCH 0/4]: Fix several errors in extension header handling.
From: David S. Miller @ 2006-04-18 21:49 UTC (permalink / raw)
To: yoshfuji; +Cc: netdev
In-Reply-To: <20060419.002045.85775401.yoshfuji@linux-ipv6.org>
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Date: Wed, 19 Apr 2006 00:20:45 +0900 (JST)
> Following changesets fix several errors in extension header handling.
> I'd propose to push them (except 4/4, maybe) to -stable.
>
> [PATCH 1/4] [IPV6]: Ensure to have hop-by-hop options in our header of &sk_buff.
> [PATCH 2/4] [IPV6] XFRM: Don't use old copy of pointer after pskb_may_pull().
> [PATCH 3/4] [IPV6] XFRM: Fix decoding session with preceding extension header(s).
> [PATCH 4/4] [IPV6]: Clean up hop-by-hop options handler.
All applied, and I agree with pushing 1-3 into -stable,
please send it.
^ permalink raw reply
* Re: [RFC PATCH 1/8] pcmcia: add new ID to pcnet_cs
From: Jeff Garzik @ 2006-04-18 20:35 UTC (permalink / raw)
To: Dominik Brodowski; +Cc: netdev
In-Reply-To: <20060418201522.GA32341@isilmar.linta.de>
Dominik Brodowski wrote:
> Please review these patches which I inted to push upstream for 2.6.17 soon.
> Thanks,
> Dominik
>
> Subject: [PATCH] pcmcia: add new ID to pcnet_cs
>
> This adds a new ID to pcnet_cs, as noted by Kuro Moji.
>
> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
ACK, thanks for CC'ing netdev
Jeff
^ 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