2005-02-24 04:13:31

by David Gibson

[permalink] [raw]
Subject: [0/14] Orinoco driver updates

Jeff, please apply:

Here's a big stack of patches that make a significant step forward on
the long overdue orinoco driver merge. Still quite a long way to go,
but it's something. This patch stack is againt Linus' vanilla +
Viro's big iomap cleanup patch, as requested.

The first 9 patches make only trivial or cosmetic behavioural changes:
1/14 orinoco-carrier
Use netif_carrier_*() macros instead of homegrown
'connected' variable.

2/14 orinoco-printks
Update various printk()s and other cosmetic strings

3/14 orinoco-delays
Use mdelay() and ssleep() instead of outdated ways of
delaying.

4/14 orinoco-free-orinocodev
Introduce free_orinocodev() function, to reduce noise
in future diffs.

5/14 orinoco-cleanup-hermes
Assorted cleanups to low-level hardware access code

6/14 orinoco-pci-updates
Cleanup to initialization code for the PCI based
orinoco devices.

7/14 orinoco-modparm
Use modern module_parm macros for orinoco module.

8/14 orinoco-pccard-cleanups
Cleanup to PCMCIA initialization code

9/14 orinoco-void-ethersnap
Trivial change to is_ethersnap() function to reduce
future diff noise.

The next 4 patches start to intoduce real new functionality and
bug fixes:
10/14 orinoco-no-ibss-any
Disallow IBSS mode if no ESSID is set (too many
firmwares break, otherwise)

11/14 orinoco-late-tx-wake
Delay waking the Tx queue, fixes problems on a number
of firwmares

12/14 orinoco-wep-updates
Various updates to WEP setup code

13/14 orinoco-update-firmware-detection
Updates and bugfixes to firmware detection logic

And the final one, is another trivial one:
14/14 orinoco-is-now-0.14alpha2
Update version and changelog to reflect the above
patches.

--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson


2005-02-24 04:13:44

by David Gibson

[permalink] [raw]
Subject: [1/14] Orinoco driver updates - use netif_carrier_*()

Removes the orinoco driver's custom and dodgy "connected" variable
used to track whether or not we're associated with an AP. Replaces it
instead with netif_carrier_ok() settings.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-01-13 09:48:55.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-10 14:22:32.179826024 +1100
@@ -784,7 +784,7 @@
return 1;
}

- if (! priv->connected) {
+ if (! netif_carrier_ok(dev)) {
/* Oops, the firmware hasn't established a connection,
silently drop the packet (this seems to be the
safest approach). */
@@ -1269,6 +1269,7 @@
case HERMES_INQ_LINKSTATUS: {
struct hermes_linkstatus linkstatus;
u16 newstatus;
+ int connected;

if (len != sizeof(linkstatus)) {
printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
@@ -1280,15 +1281,14 @@
len / 2);
newstatus = le16_to_cpu(linkstatus.linkstatus);

- if ( (newstatus == HERMES_LINKSTATUS_CONNECTED)
- || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
- || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE) )
- priv->connected = 1;
- else if ( (newstatus == HERMES_LINKSTATUS_NOT_CONNECTED)
- || (newstatus == HERMES_LINKSTATUS_DISCONNECTED)
- || (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE)
- || (newstatus == HERMES_LINKSTATUS_ASSOC_FAILED) )
- priv->connected = 0;
+ connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
+ || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
+ || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
+
+ if (connected)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);

if (newstatus != priv->last_linkstatus)
print_linkstatus(dev, newstatus);
@@ -1366,8 +1366,8 @@
}

/* firmware will have to reassociate */
+ netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
- priv->connected = 0;

return 0;
}
@@ -1878,7 +1878,7 @@

priv->hw_unavailable++;
priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
- priv->connected = 0;
+ netif_carrier_off(dev);

orinoco_unlock(priv, &flags);

@@ -2388,8 +2388,8 @@
* hardware */
INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);

+ netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
- priv->connected = 0;

return dev;

Index: working-2.6/drivers/net/wireless/orinoco.h
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.h 2004-10-29 13:16:58.000000000 +1000
+++ working-2.6/drivers/net/wireless/orinoco.h 2005-02-10 14:22:32.179826024 +1100
@@ -42,7 +42,6 @@
/* driver state */
int open;
u16 last_linkstatus;
- int connected;

/* Net device stuff */
struct net_device *ndev;


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:15:52

by David Gibson

[permalink] [raw]
Subject: [3/14] Orinoco driver updates - use mdelay()/ssleep() more

Use mdelay() or ssleep() instead of various silly more complicated
ways of delaying in the orinoco driver.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco_pci.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_pci.c 2005-01-12 15:13:18.819073992 +1100
+++ working-2.6/drivers/net/wireless/orinoco_pci.c 2005-01-12 15:15:33.137654464 +1100
@@ -151,19 +151,11 @@

/* Assert the reset until the card notice */
hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
- timeout = jiffies + (HERMES_PCI_COR_ONT * HZ / 1000);
- while(time_before(jiffies, timeout)) {
- mdelay(1);
- }
- //mdelay(HERMES_PCI_COR_ONT);
+ mdelay(HERMES_PCI_COR_ONT);

/* Give time for the card to recover from this hard effort */
hermes_write_regn(hw, PCI_COR, 0x0000);
- timeout = jiffies + (HERMES_PCI_COR_OFFT * HZ / 1000);
- while(time_before(jiffies, timeout)) {
- mdelay(1);
- }
- //mdelay(HERMES_PCI_COR_OFFT);
+ mdelay(HERMES_PCI_COR_OFFT);

/* The card is ready when it's no longer busy */
timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000);
Index: working-2.6/drivers/net/wireless/orinoco_plx.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_plx.c 2005-01-12 15:13:18.821073688 +1100
+++ working-2.6/drivers/net/wireless/orinoco_plx.c 2005-01-12 15:15:33.138654312 +1100
@@ -356,8 +356,7 @@
static void __exit orinoco_plx_exit(void)
{
pci_unregister_driver(&orinoco_plx_driver);
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ);
+ ssleep(1);
}

module_init(orinoco_plx_init);
Index: working-2.6/drivers/net/wireless/orinoco_tmd.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_tmd.c 2005-01-12 15:13:18.820073840 +1100
+++ working-2.6/drivers/net/wireless/orinoco_tmd.c 2005-01-12 15:16:05.897674184 +1100
@@ -225,8 +225,7 @@
static void __exit orinoco_tmd_exit(void)
{
pci_unregister_driver(&orinoco_tmd_driver);
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ);
+ ssleep(1);
}

module_init(orinoco_tmd_init);


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:15:51

by David Gibson

[permalink] [raw]
Subject: [4/14] Orinoco driver updates - add free_orinocodev()

Introduce a free_orinocodev() function into the orinoco driver, used
by the hardware type/initialization modules to free the device
structure in preference to directly calling free_netdev(). At the
moment free_orinocodev() just calls free_netdev(). Future merges will
make it clean up internal scanning state, so merging this now will
reduce the diff noise.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.h
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.h 2005-02-18 12:04:03.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco.h 2005-02-18 12:04:03.000000000 +1100
@@ -107,6 +107,7 @@

extern struct net_device *alloc_orinocodev(int sizeof_card,
int (*hard_reset)(struct orinoco_private *));
+extern void free_orinocodev(struct net_device *dev);
extern int __orinoco_up(struct net_device *dev);
extern int __orinoco_down(struct net_device *dev);
extern int orinoco_stop(struct net_device *dev);
Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-18 12:04:03.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-18 13:03:51.846593520 +1100
@@ -2398,6 +2398,11 @@

}

+void free_orinocodev(struct net_device *dev)
+{
+ free_netdev(dev);
+}
+
/********************************************************************/
/* Wireless extensions */
/********************************************************************/
@@ -4131,6 +4136,7 @@
/********************************************************************/

EXPORT_SYMBOL(alloc_orinocodev);
+EXPORT_SYMBOL(free_orinocodev);

EXPORT_SYMBOL(__orinoco_up);
EXPORT_SYMBOL(__orinoco_down);
Index: working-2.6/drivers/net/wireless/orinoco_cs.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_cs.c 2005-02-18 12:04:03.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco_cs.c 2005-02-18 12:04:03.000000000 +1100
@@ -235,7 +235,7 @@
dev);
unregister_netdev(dev);
}
- free_netdev(dev);
+ free_orinocodev(dev);
} /* orinoco_cs_detach */

/*
Index: working-2.6/drivers/net/wireless/orinoco_pci.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_pci.c 2005-02-18 12:04:03.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco_pci.c 2005-02-18 12:04:03.000000000 +1100
@@ -254,7 +254,7 @@
if (dev->irq)
free_irq(dev->irq, dev);

- free_netdev(dev);
+ free_orinocodev(dev);
}

if (pci_ioaddr)
@@ -279,7 +279,7 @@
iounmap(priv->hw.iobase);

pci_set_drvdata(pdev, NULL);
- free_netdev(dev);
+ free_orinocodev(dev);

pci_disable_device(pdev);
}
Index: working-2.6/drivers/net/wireless/orinoco_plx.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_plx.c 2005-02-18 12:04:03.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco_plx.c 2005-02-18 12:04:03.000000000 +1100
@@ -279,7 +279,7 @@
fail:
free_irq(dev->irq, dev);
fail_irq:
- free_netdev(dev);
+ free_orinocodev(dev);
fail_alloc:
pci_iounmap(pdev, mem);
fail_map:
@@ -304,7 +304,7 @@

pci_set_drvdata(pdev, NULL);

- free_netdev(dev);
+ free_orinocodev(dev);

release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));

Index: working-2.6/drivers/net/wireless/orinoco_tmd.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_tmd.c 2005-02-18 12:04:03.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco_tmd.c 2005-02-18 12:04:03.000000000 +1100
@@ -164,7 +164,7 @@
out4:
pci_iounmap(pdev, mem);
out3:
- free_netdev(dev);
+ free_orinocodev(dev);
out2:
release_region(pccard_ioaddr, pccard_iolen);
out:
@@ -188,7 +188,7 @@

pci_set_drvdata(pdev, NULL);

- free_netdev(dev);
+ free_orinocodev(dev);

release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));

Index: working-2.6/drivers/net/wireless/airport.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/airport.c 2005-02-18 12:04:03.000000000 +1100
+++ working-2.6/drivers/net/wireless/airport.c 2005-02-18 12:04:03.000000000 +1100
@@ -149,7 +149,7 @@
ssleep(1);

macio_set_drvdata(mdev, NULL);
- free_netdev(dev);
+ free_orinocodev(dev);

return 0;
}
@@ -211,7 +211,7 @@

if (macio_request_resource(mdev, 0, "airport")) {
printk(KERN_ERR PFX "can't request IO resource !\n");
- free_netdev(dev);
+ free_orinocodev(dev);
return -EBUSY;
}


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:20:32

by David Gibson

[permalink] [raw]
Subject: [10/14] Orinoco driver updates - prohibit IBSS with no ESSID

Remove has_ibss_any flag and never set the CREATEIBSS RID when the
ESSID is empty. Too many firmware break if we do.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-24 14:50:50.125529816 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-24 14:50:53.166067584 +1100
@@ -1580,21 +1580,26 @@
}

if (priv->has_ibss) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFCREATEIBSS,
- priv->createibss);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", dev->name, err);
- return err;
- }
+ u16 createibss;

- if ((strlen(priv->desired_essid) == 0) && (priv->createibss)
- && (!priv->has_ibss_any)) {
+ if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
printk(KERN_WARNING "%s: This firmware requires an "
"ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
/* With wvlan_cs, in this case, we would crash.
* hopefully, this driver will behave better...
* Jean II */
+ createibss = 0;
+ } else {
+ createibss = priv->createibss;
+ }
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFCREATEIBSS,
+ createibss);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+ dev->name, err);
+ return err;
}
}

@@ -2073,7 +2078,6 @@
priv->has_preamble = 0;
priv->has_port3 = 1;
priv->has_ibss = 1;
- priv->has_ibss_any = 0;
priv->has_wep = 0;
priv->has_big_wep = 0;

@@ -2089,7 +2093,6 @@
firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;

priv->has_ibss = (firmver >= 0x60006);
- priv->has_ibss_any = (firmver >= 0x60010);
priv->has_wep = (firmver >= 0x40020);
priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
Gold cards from the others? */
Index: working-2.6/drivers/net/wireless/orinoco.h
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.h 2005-02-24 14:50:46.549073520 +1100
+++ working-2.6/drivers/net/wireless/orinoco.h 2005-02-24 14:50:53.167067432 +1100
@@ -57,7 +57,7 @@
#define FIRMWARE_TYPE_AGERE 1
#define FIRMWARE_TYPE_INTERSIL 2
#define FIRMWARE_TYPE_SYMBOL 3
- int has_ibss, has_port3, has_ibss_any, ibss_port;
+ int has_ibss, has_port3, ibss_port;
int has_wep, has_big_wep;
int has_mwo;
int has_pm;

--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:20:33

by David Gibson

[permalink] [raw]
Subject: [9/14] Orinoco driver updates - update is_ethersnap()

Make the is_ethersnap() function take a void * rather than a pointer
to the internal header structure. This makes more logical sense and
reduces dependencies between different parts of the code.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-24 14:50:48.426788064 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-24 14:50:50.125529816 +1100
@@ -966,15 +966,17 @@

/* Does the frame have a SNAP header indicating it should be
* de-encapsulated to Ethernet-II? */
-static inline int is_ethersnap(struct header_struct *hdr)
+static inline int is_ethersnap(void *_hdr)
{
+ u8 *hdr = _hdr;
+
/* We de-encapsulate all packets which, a) have SNAP headers
* (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
* and where b) the OUI of the SNAP header is 00:00:00 or
* 00:00:f8 - we need both because different APs appear to use
* different OUIs for some reason */
- return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0)
- && ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );
+ return (memcmp(hdr, &encaps_hdr, 5) == 0)
+ && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
}

static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,

--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:25:19

by David Gibson

[permalink] [raw]
Subject: [6/14] Orinoco driver updates - cleanup PCI initialization

Update the initialization code in the various PCI incarnations of the
orinoco driver. This applies similar initialization and shutdown
cleanups to the orinoco_pci, orinoco_plx and orinoco_tmd drivers. It
also adds COR reset support to the orinoco_plx and orinoco_tmd
drivers, improves PCI power management support in the orinoco_pci
driver and adds a couple of extra supported cards to the ID tables.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco_pci.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_pci.c 2005-01-12 15:47:48.215477920 +1100
+++ working-2.6/drivers/net/wireless/orinoco_pci.c 2005-01-12 16:10:57.324301280 +1100
@@ -129,6 +129,11 @@
#define HERMES_PCI_COR_OFFT (500) /* ms */
#define HERMES_PCI_COR_BUSYT (500) /* ms */

+/* Orinoco PCI specific data */
+struct orinoco_pci_card {
+ void __iomem *pci_ioaddr;
+};
+
/*
* Do a soft reset of the PCI card using the Configuration Option Register
* We need this to get going...
@@ -164,8 +169,9 @@
mdelay(1);
reg = hermes_read_regn(hw, CMD);
}
- /* Did we timeout ? */
- if(time_after_eq(jiffies, timeout)) {
+
+ /* Still busy? */
+ if (reg & HERMES_CMD_BUSY) {
printk(KERN_ERR PFX "Busy timeout\n");
return -ETIMEDOUT;
}
@@ -184,6 +190,7 @@
u16 __iomem *pci_ioaddr = NULL;
unsigned long pci_iolen;
struct orinoco_private *priv = NULL;
+ struct orinoco_pci_card *card;
struct net_device *dev = NULL;

err = pci_enable_device(pdev);
@@ -192,24 +199,31 @@
return err;
}

+ err = pci_request_regions(pdev, DRIVER_NAME);
+ if (err != 0) {
+ printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+ goto fail_resources;
+ }
+
/* Resource 0 is mapped to the hermes registers */
pci_iorange = pci_resource_start(pdev, 0);
pci_iolen = pci_resource_len(pdev, 0);
pci_ioaddr = ioremap(pci_iorange, pci_iolen);
- if (! pci_iorange) {
+ if (!pci_iorange) {
printk(KERN_ERR PFX "Cannot remap hardware registers\n");
- goto fail;
+ goto fail_map;
}

/* Allocate network device */
- dev = alloc_orinocodev(0, NULL);
+ dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset);
if (! dev) {
err = -ENOMEM;
- goto fail;
+ goto fail_alloc;
}

priv = netdev_priv(dev);
- dev->base_addr = (unsigned long) pci_ioaddr;
+ card = priv->card;
+ card->pci_ioaddr = pci_ioaddr;
dev->mem_start = pci_iorange;
dev->mem_end = pci_iorange + pci_iolen - 1;
SET_MODULE_OWNER(dev);
@@ -226,14 +240,14 @@
if (err) {
printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
err = -EBUSY;
- goto fail;
+ goto fail_irq;
}
dev->irq = pdev->irq;

/* Perform a COR reset to start the card */
- if(orinoco_pci_cor_reset(priv) != 0) {
+ err = orinoco_pci_cor_reset(priv);
+ if (err) {
printk(KERN_ERR PFX "Initial reset failed\n");
- err = -ETIMEDOUT;
goto fail;
}

@@ -250,16 +264,19 @@
return 0;

fail:
- if (dev) {
- if (dev->irq)
- free_irq(dev->irq, dev);
+ free_irq(pdev->irq, dev);

- free_orinocodev(dev);
- }
+ fail_irq:
+ pci_set_drvdata(pdev, NULL);
+ free_orinocodev(dev);
+
+ fail_alloc:
+ iounmap(pci_ioaddr);

- if (pci_ioaddr)
- iounmap(pci_ioaddr);
+ fail_map:
+ pci_release_regions(pdev);

+ fail_resources:
pci_disable_device(pdev);

return err;
@@ -269,18 +286,14 @@
{
struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_pci_card *card = priv->card;

unregister_netdev(dev);
-
- if (dev->irq)
- free_irq(dev->irq, dev);
-
- if (priv->hw.iobase)
- iounmap(priv->hw.iobase);
-
+ free_irq(dev->irq, dev);
pci_set_drvdata(pdev, NULL);
free_orinocodev(dev);
-
+ iounmap(card->pci_ioaddr);
+ pci_release_regions(pdev);
pci_disable_device(pdev);
}

@@ -312,6 +325,9 @@

orinoco_unlock(priv, &flags);

+ pci_save_state(pdev);
+ pci_set_power_state(pdev, 3);
+
return 0;
}

@@ -324,6 +340,9 @@

printk(KERN_DEBUG "%s: Orinoco-PCI waking up\n", dev->name);

+ pci_set_power_state(pdev, 0);
+ pci_restore_state(pdev);
+
err = orinoco_reinit_firmware(dev);
if (err) {
printk(KERN_ERR "%s: Error %d re-initializing firmware on orinoco_pci_resume()\n",
@@ -354,6 +373,8 @@
{0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
/* Intersil Prism 2.5 */
{0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
+ /* Samsung MagicLAN SWL-2210P */
+ {0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID,},
{0,},
};

Index: working-2.6/drivers/net/wireless/orinoco_plx.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_plx.c 2005-01-12 15:47:48.216477768 +1100
+++ working-2.6/drivers/net/wireless/orinoco_plx.c 2004-11-05 14:20:30.000000000 +1100
@@ -142,26 +142,68 @@
#include "hermes.h"
#include "orinoco.h"

-#define COR_OFFSET (0x3e0/2) /* COR attribute offset of Prism2 PC card */
+#define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */
#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+#define COR_RESET (0x80) /* reset bit in the COR register */
+#define PLX_RESET_TIME (500) /* milliseconds */

#define PLX_INTCSR 0x4c /* Interrupt Control & Status Register */
#define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */

-static const u16 cis_magic[] = {
- 0x0001, 0x0003, 0x0000, 0x0000, 0x00ff, 0x0017, 0x0004, 0x0067
+static const u8 cis_magic[] = {
+ 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
};

+/* Orinoco PLX specific data */
+struct orinoco_plx_card {
+ void __iomem *attr_mem;
+};
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ */
+static int orinoco_plx_cor_reset(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ struct orinoco_plx_card *card = priv->card;
+ u8 __iomem *attr_mem = card->attr_mem;
+ unsigned long timeout;
+ u16 reg;
+
+ writeb(COR_VALUE | COR_RESET, attr_mem + COR_OFFSET);
+ mdelay(1);
+
+ writeb(COR_VALUE, attr_mem + COR_OFFSET);
+ mdelay(1);
+
+ /* Just in case, wait more until the card is no longer busy */
+ timeout = jiffies + (PLX_RESET_TIME * HZ / 1000);
+ reg = hermes_read_regn(hw, CMD);
+ while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+ mdelay(1);
+ reg = hermes_read_regn(hw, CMD);
+ }
+
+ /* Did we timeout ? */
+ if (reg & HERMES_CMD_BUSY) {
+ printk(KERN_ERR PFX "Busy timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+
static int orinoco_plx_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int err = 0;
- u16 __iomem *attr_mem = NULL;
- u32 reg, addr;
+ u8 __iomem *attr_mem = NULL;
+ u32 csr_reg, plx_addr;
struct orinoco_private *priv = NULL;
+ struct orinoco_plx_card *card;
unsigned long pccard_ioaddr = 0;
unsigned long pccard_iolen = 0;
- u16 magic[8];
struct net_device *dev = NULL;
void __iomem *mem;
int i;
@@ -169,78 +211,38 @@
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR PFX "Cannot enable PCI device\n");
- return -EIO;
+ return err;
}

- /* Resource 2 is mapped to the PCMCIA space */
- attr_mem = ioremap(pci_resource_start(pdev, 2), PAGE_SIZE);
- if (!attr_mem)
+ err = pci_request_regions(pdev, DRIVER_NAME);
+ if (err != 0) {
+ printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
goto fail_resources;
-
- printk(KERN_DEBUG PFX "CIS: ");
- for (i = 0; i < 16; i++) {
- printk("%02X:", readw(attr_mem+i));
}
- printk("\n");
-
- /* Verify whether PC card is present */
- /* FIXME: we probably need to be smarted about this */
- memcpy_fromio(magic, attr_mem, 16);
- if (memcmp(magic, cis_magic, 16) != 0) {
- printk(KERN_ERR PFX "The CIS value of Prism2 PC "
- "card is unexpected\n");
- err = -EIO;
- iounmap(attr_mem);
- goto fail_resources;
- }
-
- /* PCMCIA COR is the first byte following CIS: this write should
- * enable I/O mode and select level-triggered interrupts */
- writew(COR_VALUE, attr_mem + COR_OFFSET);
- mdelay(1);
- reg = readw(attr_mem + COR_OFFSET);
- iounmap(attr_mem);

- if (reg != COR_VALUE) {
- printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n", reg);
- goto fail_resources;
- }
+ /* Resource 1 is mapped to PLX-specific registers */
+ plx_addr = pci_resource_start(pdev, 1);

- /* bjoern: We need to tell the card to enable interrupts, in
- case the serial eprom didn't do this already. See the
- PLX9052 data book, p8-1 and 8-24 for reference. */
- addr = pci_resource_start(pdev, 1);
- reg = inl(addr+PLX_INTCSR);
- if (reg & PLX_INTCSR_INTEN)
- printk(KERN_DEBUG PFX "Local Interrupt already enabled\n");
- else {
- reg |= PLX_INTCSR_INTEN;
- outl(reg, addr+PLX_INTCSR);
- reg = inl(addr+PLX_INTCSR);
- if(!(reg & PLX_INTCSR_INTEN)) {
- printk(KERN_ERR PFX "Couldn't enable Local Interrupts\n");
- goto fail_resources;
- }
+ /* Resource 2 is mapped to the PCMCIA attribute memory */
+ attr_mem = ioremap(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+ if (!attr_mem) {
+ printk(KERN_ERR PFX "Cannot remap PCMCIA space\n");
+ goto fail_map_attr;
}

/* Resource 3 is mapped to the PCMCIA I/O address space */
pccard_ioaddr = pci_resource_start(pdev, 3);
pccard_iolen = pci_resource_len(pdev, 3);
- if (! request_region(pccard_ioaddr, pccard_iolen, DRIVER_NAME)) {
- printk(KERN_ERR PFX "I/O resource 0x%lx @ 0x%lx busy\n",
- pccard_iolen, pccard_ioaddr);
- err = -EBUSY;
- goto fail_resources;
- }

mem = pci_iomap(pdev, 3, 0);
if (!mem) {
err = -ENOMEM;
- goto fail_map;
+ goto fail_map_io;
}

/* Allocate network device */
- dev = alloc_orinocodev(0, NULL);
+ dev = alloc_orinocodev(sizeof(*card), orinoco_plx_cor_reset);
if (!dev) {
printk(KERN_ERR PFX "Cannot allocate network device\n");
err = -ENOMEM;
@@ -248,6 +250,8 @@
}

priv = netdev_priv(dev);
+ card = priv->card;
+ card->attr_mem = attr_mem;
dev->base_addr = pccard_ioaddr;
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -268,6 +272,43 @@
}
dev->irq = pdev->irq;

+ /* bjoern: We need to tell the card to enable interrupts, in
+ case the serial eprom didn't do this already. See the
+ PLX9052 data book, p8-1 and 8-24 for reference. */
+ csr_reg = inl(plx_addr + PLX_INTCSR);
+ if (!(csr_reg & PLX_INTCSR_INTEN)) {
+ csr_reg |= PLX_INTCSR_INTEN;
+ outl(csr_reg, plx_addr + PLX_INTCSR);
+ csr_reg = inl(plx_addr + PLX_INTCSR);
+ if (!(csr_reg & PLX_INTCSR_INTEN)) {
+ printk(KERN_ERR PFX "Cannot enable interrupts\n");
+ goto fail;
+ }
+ }
+
+ err = orinoco_plx_cor_reset(priv);
+ if (err) {
+ printk(KERN_ERR PFX "Initial reset failed\n");
+ goto fail;
+ }
+
+ printk(KERN_DEBUG PFX "CIS: ");
+ for (i = 0; i < 16; i++) {
+ printk("%02X:", readb(attr_mem + 2*i));
+ }
+ printk("\n");
+
+ /* Verify whether a supported PC card is present */
+ /* FIXME: we probably need to be smarted about this */
+ for (i = 0; i < sizeof(cis_magic); i++) {
+ if (cis_magic[i] != readb(attr_mem +2*i)) {
+ printk(KERN_ERR PFX "The CIS value of Prism2 PC "
+ "card is unexpected\n");
+ err = -EIO;
+ goto fail;
+ }
+ }
+
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "Cannot register network device\n");
@@ -277,13 +318,21 @@
return 0;

fail:
- free_irq(dev->irq, dev);
+ free_irq(pdev->irq, dev);
+
fail_irq:
+ pci_set_drvdata(pdev, NULL);
free_orinocodev(dev);
+
fail_alloc:
pci_iounmap(pdev, mem);
- fail_map:
- release_region(pccard_ioaddr, pccard_iolen);
+
+ fail_map_io:
+ iounmap(attr_mem);
+
+ fail_map_attr:
+ pci_release_regions(pdev);
+
fail_resources:
pci_disable_device(pdev);

@@ -294,20 +343,18 @@
{
struct net_device *dev = pci_get_drvdata(pdev);
struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_plx_card *card = priv->card;
+ u8 __iomem *attr_mem = card->attr_mem;

- unregister_netdev(dev);
-
- if (dev->irq)
- free_irq(dev->irq, dev);
+ BUG_ON(! dev);

- pci_iounmap(pdev, priv->hw.iobase);
-
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
pci_set_drvdata(pdev, NULL);
-
free_orinocodev(dev);
-
- release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
-
+ pci_iounmap(pdev, priv->hw.iobase);
+ iounmap(attr_mem);
+ pci_release_regions(pdev);
pci_disable_device(pdev);
}

Index: working-2.6/drivers/net/wireless/orinoco_tmd.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_tmd.c 2005-01-12 15:47:48.216477768 +1100
+++ working-2.6/drivers/net/wireless/orinoco_tmd.c 2004-11-05 14:37:35.000000000 +1100
@@ -79,59 +79,89 @@
#include "orinoco.h"

#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+#define COR_RESET (0x80) /* reset bit in the COR register */
+#define TMD_RESET_TIME (500) /* milliseconds */
+
+/* Orinoco TMD specific data */
+struct orinoco_tmd_card {
+ u32 tmd_io;
+};
+
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ */
+static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ struct orinoco_tmd_card *card = priv->card;
+ u32 addr = card->tmd_io;
+ unsigned long timeout;
+ u16 reg;
+
+ outb(COR_VALUE | COR_RESET, addr);
+ mdelay(1);
+
+ outb(COR_VALUE, addr);
+ mdelay(1);
+
+ /* Just in case, wait more until the card is no longer busy */
+ timeout = jiffies + (TMD_RESET_TIME * HZ / 1000);
+ reg = hermes_read_regn(hw, CMD);
+ while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+ mdelay(1);
+ reg = hermes_read_regn(hw, CMD);
+ }
+
+ /* Did we timeout ? */
+ if (reg & HERMES_CMD_BUSY) {
+ printk(KERN_ERR PFX "Busy timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+

static int orinoco_tmd_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int err = 0;
- u32 reg, addr;
struct orinoco_private *priv = NULL;
- unsigned long pccard_ioaddr = 0;
- unsigned long pccard_iolen = 0;
+ struct orinoco_tmd_card *card;
struct net_device *dev = NULL;
void __iomem *mem;

err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR PFX "Cannot enable PCI device\n");
- return -EIO;
+ return err;
}

- printk(KERN_DEBUG PFX "TMD setup\n");
- pccard_ioaddr = pci_resource_start(pdev, 2);
- pccard_iolen = pci_resource_len(pdev, 2);
- if (! request_region(pccard_ioaddr, pccard_iolen, DRIVER_NAME)) {
- printk(KERN_ERR PFX "I/O resource at 0x%lx len 0x%lx busy\n",
- pccard_ioaddr, pccard_iolen);
- err = -EBUSY;
- goto out;
+ err = pci_request_regions(pdev, DRIVER_NAME);
+ if (err != 0) {
+ printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+ goto fail_resources;
}
- addr = pci_resource_start(pdev, 1);
- outb(COR_VALUE, addr);
- mdelay(1);
- reg = inb(addr);
- if (reg != COR_VALUE) {
- printk(KERN_ERR PFX "Error setting TMD COR values %x should be %x\n", reg, COR_VALUE);
- err = -EIO;
- goto out2;
+
+ mem = pci_iomap(pdev, 2, 0);
+ if (! mem) {
+ err = -ENOMEM;
+ goto fail_iomap;
}

/* Allocate network device */
- dev = alloc_orinocodev(0, NULL);
+ dev = alloc_orinocodev(sizeof(*card), orinoco_tmd_cor_reset);
if (! dev) {
printk(KERN_ERR PFX "Cannot allocate network device\n");
err = -ENOMEM;
- goto out2;
- }
-
- mem = pci_iomap(pdev, 2, 0);
- if (!mem) {
- err = -ENOMEM;
- goto out3;
+ goto fail_alloc;
}

priv = netdev_priv(dev);
- dev->base_addr = pccard_ioaddr;
+ card = priv->card;
+ card->tmd_io = pci_resource_start(pdev, 1);
+ dev->base_addr = pci_resource_start(pdev, 2);
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);

@@ -140,36 +170,46 @@

printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD device "
"at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
- pccard_ioaddr);
+ dev->base_addr);

err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
if (err) {
printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
err = -EBUSY;
- goto out4;
+ goto fail_irq;
}
dev->irq = pdev->irq;

+ err = orinoco_tmd_cor_reset(priv);
+ if (err) {
+ printk(KERN_ERR PFX "Initial reset failed\n");
+ goto fail;
+ }
+
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "Cannot register network device\n");
- goto out5;
+ goto fail;
}

return 0;

-out5:
- free_irq(dev->irq, dev);
-out4:
- pci_iounmap(pdev, mem);
-out3:
+ fail:
+ free_irq(pdev->irq, dev);
+
+ fail_irq:
+ pci_set_drvdata(pdev, NULL);
free_orinocodev(dev);
-out2:
- release_region(pccard_ioaddr, pccard_iolen);
-out:
+
+ fail_alloc:
+ pci_iounmap(pdev, mem);
+
+ fail_iomap:
+ pci_release_regions(pdev);
+
+ fail_resources:
pci_disable_device(pdev);
- printk(KERN_DEBUG PFX "init_one(), FAIL!\n");

return err;
}
@@ -177,21 +217,16 @@
static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_private *priv = dev->priv;

- unregister_netdev(dev);
-
- if (dev->irq)
- free_irq(dev->irq, dev);
-
- pci_iounmap(pdev, priv->hw.iobase);
+ BUG_ON(! dev);

+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
pci_set_drvdata(pdev, NULL);
-
free_orinocodev(dev);
-
- release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
-
+ pci_iounmap(pdev, priv->hw.iobase);
+ pci_release_regions(pdev);
pci_disable_device(pdev);
}



--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:25:39

by David Gibson

[permalink] [raw]
Subject: [14/14] Orinoco driver updates - update version and changelog

Previous patches have brought the in-kernel orinoco driver roughly to
parity with version 0.14alpha2 from out-of-tree. Update the version
number and changelog accordingly.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-24 14:50:59.879047056 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-24 14:51:02.388665536 +1100
@@ -393,6 +393,29 @@
* in the rx_dropped statistics.
* o Provided a module parameter to suppress linkstatus messages.
*
+ * v0.13e -> v0.14alpha1 - 30 Sep 2003 - David Gibson
+ * o Replaced priv->connected logic with netif_carrier_on/off()
+ * calls.
+ * o Remove has_ibss_any and never set the CREATEIBSS RID when
+ * the ESSID is empty. Too many firmwares break if we do.
+ * o 2.6 merges: Replace pdev->slot_name with pci_name(), remove
+ * __devinitdata from PCI ID tables, use free_netdev().
+ * o Enabled shared-key authentication for Agere firmware (from
+ * Robert J. Moore <Robert.J.Moore AT allanbank.com>
+ * o Move netif_wake_queue() (back) to the Tx completion from the
+ * ALLOC event. This seems to prevent/mitigate the rolling
+ * error -110 problems at least on some Intersil firmwares.
+ * Theoretically reduces performance, but I can't measure it.
+ * Patch from Andrew Tridgell <tridge AT samba.org>
+ *
+ * v0.14alpha1 -> v0.14alpha2 - 20 Oct 2003 - David Gibson
+ * o Correctly turn off shared-key authentication when requested
+ * (bugfix from Robert J. Moore).
+ * o Correct airport sleep interfaces for current 2.6 kernels.
+ * o Add code for key change without disabling/enabling the MAC
+ * port. This is supposed to allow 802.1x to work sanely, but
+ * doesn't seem to yet.
+ *
* TODO
* o New wireless extensions API (patch from Moustafa
* Youssef, updated by Jim Carter and Pavel Roskin).
Index: working-2.6/drivers/net/wireless/orinoco.h
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.h 2005-02-24 14:50:59.879047056 +1100
+++ working-2.6/drivers/net/wireless/orinoco.h 2005-02-24 14:51:02.389665384 +1100
@@ -7,7 +7,7 @@
#ifndef _ORINOCO_H
#define _ORINOCO_H

-#define DRIVER_VERSION "0.13e"
+#define DRIVER_VERSION "0.14alpha2"

#include <linux/types.h>
#include <linux/spinlock.h>

--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:30:12

by David Gibson

[permalink] [raw]
Subject: [13/14] Orinoco driver updates - update firmware detection

Update firmware detection code. This will now reliably detect
Intersil firmwares past verison 1.x, a serious flaw in the previous
code. It cleans up the code, and reduces the size of the private
structure by using single bits for the various firmware feature flags.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-24 14:50:57.300439064 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-24 14:50:59.879047056 +1100
@@ -2047,39 +2047,54 @@
/* Initialization */
/********************************************************************/

-struct sta_id {
+struct comp_id {
u16 id, variant, major, minor;
} __attribute__ ((packed));

-static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id)
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
{
- /* FIXME: this is fundamentally broken */
- unsigned int firmver = ((u32)sta_id->major << 16) | sta_id->minor;
-
- if (sta_id->variant == 1)
+ if (nic_id->id < 0x8000)
return FIRMWARE_TYPE_AGERE;
- else if ((sta_id->variant == 2) &&
- ((firmver == 0x10001) || (firmver == 0x20001)))
+ else if (nic_id->id == 0x8000 && nic_id->major == 0)
return FIRMWARE_TYPE_SYMBOL;
else
return FIRMWARE_TYPE_INTERSIL;
}

-static void determine_firmware(struct net_device *dev)
+/* Set priv->firmware type, determine firmware properties */
+static int determine_firmware(struct net_device *dev)
{
struct orinoco_private *priv = netdev_priv(dev);
hermes_t *hw = &priv->hw;
int err;
- struct sta_id sta_id;
+ struct comp_id nic_id, sta_id;
unsigned int firmver;
char tmp[SYMBOL_MAX_VER_LEN+1];

+ /* Get the hardware version */
+ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
+ dev->name, err);
+ return err;
+ }
+
+ le16_to_cpus(&nic_id.id);
+ le16_to_cpus(&nic_id.variant);
+ le16_to_cpus(&nic_id.major);
+ le16_to_cpus(&nic_id.minor);
+ printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
+ dev->name, nic_id.id, nic_id.variant,
+ nic_id.major, nic_id.minor);
+
+ priv->firmware_type = determine_firmware_type(&nic_id);
+
/* Get the firmware version */
err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
if (err) {
- printk(KERN_WARNING "%s: Error %d reading firmware info. Wildly guessing capabilities...\n",
+ printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
dev->name, err);
- memset(&sta_id, 0, sizeof(sta_id));
+ return err;
}

le16_to_cpus(&sta_id.id);
@@ -2090,8 +2105,23 @@
dev->name, sta_id.id, sta_id.variant,
sta_id.major, sta_id.minor);

- if (! priv->firmware_type)
- priv->firmware_type = determine_firmware_type(dev, &sta_id);
+ switch (sta_id.id) {
+ case 0x15:
+ printk(KERN_ERR "%s: Primary firmware is active\n",
+ dev->name);
+ return -ENODEV;
+ case 0x14b:
+ printk(KERN_ERR "%s: Tertiary firmware is active\n",
+ dev->name);
+ return -ENODEV;
+ case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
+ case 0x21: /* Symbol Spectrum24 Trilogy */
+ break;
+ default:
+ printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
+ dev->name);
+ break;
+ }

/* Default capabilities */
priv->has_sensitivity = 1;
@@ -2107,9 +2137,8 @@
case FIRMWARE_TYPE_AGERE:
/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
- printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
- "version %d.%02d\n", dev->name,
- sta_id.major, sta_id.minor);
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);

firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;

@@ -2152,14 +2181,15 @@
tmp[SYMBOL_MAX_VER_LEN] = '\0';
}

- printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
- "version [%s] (parsing to %X)\n", dev->name,
- tmp, firmver);
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Symbol %s", tmp);

priv->has_ibss = (firmver >= 0x20000);
priv->has_wep = (firmver >= 0x15012);
priv->has_big_wep = (firmver >= 0x20000);
- priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
+ priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
+ (firmver >= 0x29000 && firmver < 0x30000) ||
+ firmver >= 0x31000;
priv->has_preamble = (firmver >= 0x20000);
priv->ibss_port = 4;
/* Tested with Intel firmware : 0x20015 => Jean II */
@@ -2171,9 +2201,9 @@
* different and less well tested */
/* D-Link MAC : 00:40:05:* */
/* Addtron MAC : 00:90:D1:* */
- printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
- "version %d.%d.%d\n", dev->name,
- sta_id.major, sta_id.minor, sta_id.variant);
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
+ sta_id.variant);

firmver = ((unsigned long)sta_id.major << 16) |
((unsigned long)sta_id.minor << 8) | sta_id.variant;
@@ -2191,9 +2221,11 @@
priv->ibss_port = 1;
}
break;
- default:
- break;
}
+ printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
+ priv->fw_name);
+
+ return 0;
}

static int orinoco_init(struct net_device *dev)
@@ -2219,7 +2251,12 @@
goto out;
}

- determine_firmware(dev);
+ err = determine_firmware(dev);
+ if (err != 0) {
+ printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+ dev->name);
+ goto out;
+ }

if (priv->has_port3)
printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
Index: working-2.6/drivers/net/wireless/orinoco.h
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.h 2005-02-24 14:50:53.167067432 +1100
+++ working-2.6/drivers/net/wireless/orinoco.h 2005-02-24 14:50:59.879047056 +1100
@@ -30,6 +30,12 @@
char data[ORINOCO_MAX_KEY_SIZE];
} __attribute__ ((packed));

+typedef enum {
+ FIRMWARE_TYPE_AGERE,
+ FIRMWARE_TYPE_INTERSIL,
+ FIRMWARE_TYPE_SYMBOL
+} fwtype_t;
+
struct orinoco_private {
void *card; /* Pointer to card dependent structure */
int (*hard_reset)(struct orinoco_private *);
@@ -53,19 +59,22 @@
u16 txfid;

/* Capabilities of the hardware/firmware */
- int firmware_type;
-#define FIRMWARE_TYPE_AGERE 1
-#define FIRMWARE_TYPE_INTERSIL 2
-#define FIRMWARE_TYPE_SYMBOL 3
- int has_ibss, has_port3, ibss_port;
- int has_wep, has_big_wep;
- int has_mwo;
- int has_pm;
- int has_preamble;
- int has_sensitivity;
+ fwtype_t firmware_type;
+ char fw_name[32];
+ int ibss_port;
int nicbuf_size;
u16 channel_mask;
- int broken_disableport;
+
+ /* Boolean capabilities */
+ unsigned int has_ibss:1;
+ unsigned int has_port3:1;
+ unsigned int has_wep:1;
+ unsigned int has_big_wep:1;
+ unsigned int has_mwo:1;
+ unsigned int has_pm:1;
+ unsigned int has_preamble:1;
+ unsigned int has_sensitivity:1;
+ unsigned int broken_disableport:1;

/* Configuration paramaters */
u32 iw_mode;
Index: working-2.6/drivers/net/wireless/orinoco_pci.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_pci.c 2005-02-24 14:50:47.830878656 +1100
+++ working-2.6/drivers/net/wireless/orinoco_pci.c 2005-02-24 14:50:59.880046904 +1100
@@ -251,10 +251,6 @@
goto fail;
}

- /* Override the normal firmware detection - the Prism 2.5 PCI
- * cards look like Lucent firmware but are actually Intersil */
- priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
-
err = register_netdev(dev);
if (err) {
printk(KERN_ERR PFX "Failed to register net device\n");

--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:30:35

by David Gibson

[permalink] [raw]
Subject: [11/14] Orinoco driver updates - delay Tx wake

Delay netif_wake_queue() until the packet has actually been
transmitted, rather than just when the firmware has copied it into its
internal buffers. This seems to prevent problems on some Intersil
firmware versions (I suspect the problems were caused by the
firmware's buffers filling up).

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-18 12:48:30.523655896 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-18 12:58:09.407652152 +1100
@@ -901,8 +901,6 @@
printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
dev->name, fid);
return;
- } else {
- netif_wake_queue(dev);
}

hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
@@ -915,6 +913,8 @@

stats->tx_packets++;

+ netif_wake_queue(dev);
+
hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
}

@@ -941,6 +941,7 @@

stats->tx_errors++;

+ netif_wake_queue(dev);
hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
}


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:30:36

by David Gibson

[permalink] [raw]
Subject: [12/14] Orinoco driver updates - WEP updates

Updates to the WEP configuration code. This adds support for shared
key authentication on Agere firmwares. It also adds support (in some
cases) for changing the WEP keys without disabling the MAC port (thus
triggering a reassociation by the firmware). This is needed by 802.1x
implementations, although it's not clear if the code so far is
sufficient to allow working 802.1x.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-24 14:50:55.904651256 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-24 14:50:57.300439064 +1100
@@ -1437,55 +1437,46 @@
return err;
}

-static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
+/* Change the WEP keys and/or the current keys. Can be called
+ * either from __orinoco_hw_setup_wep() or directly from
+ * orinoco_ioctl_setiwencode(). In the later case the association
+ * with the AP is not broken (if the firmware can handle it),
+ * which is needed for 802.1x implementations. */
+static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
{
hermes_t *hw = &priv->hw;
int err = 0;
- int master_wep_flag;
- int auth_flag;

switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
- if (priv->wep_on) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFTXKEY_AGERE,
- priv->tx_key);
- if (err)
- return err;
-
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFWEPKEYS_AGERE,
- &priv->keys);
- if (err)
- return err;
- }
+ case FIRMWARE_TYPE_AGERE:
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFWEPKEYS_AGERE,
+ &priv->keys);
+ if (err)
+ return err;
err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFWEPENABLED_AGERE,
- priv->wep_on);
+ HERMES_RID_CNFTXKEY_AGERE,
+ priv->tx_key);
if (err)
return err;
break;
-
- case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
- case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
- master_wep_flag = 0; /* Off */
- if (priv->wep_on) {
+ case FIRMWARE_TYPE_INTERSIL:
+ case FIRMWARE_TYPE_SYMBOL:
+ {
int keylen;
int i;

- /* Fudge around firmware weirdness */
+ /* Force uniform key length to work around firmware bugs */
keylen = le16_to_cpu(priv->keys[priv->tx_key].len);

+ if (keylen > LARGE_KEY_SIZE) {
+ printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
+ priv->ndev->name, priv->tx_key, keylen);
+ return -E2BIG;
+ }
+
/* Write all 4 keys */
for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
-/* int keylen = le16_to_cpu(priv->keys[i].len); */
-
- if (keylen > LARGE_KEY_SIZE) {
- printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
- priv->ndev->name, i, keylen);
- return -E2BIG;
- }
-
err = hermes_write_ltv(hw, USER_BAP,
HERMES_RID_CNFDEFAULTKEY0 + i,
HERMES_BYTES_TO_RECLEN(keylen),
@@ -1500,27 +1491,63 @@
priv->tx_key);
if (err)
return err;
-
- if (priv->wep_restrict) {
- auth_flag = 2;
- master_wep_flag = 3;
- } else {
- /* Authentication is where Intersil and Symbol
- * firmware differ... */
- auth_flag = 1;
- if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
- master_wep_flag = 3; /* Symbol */
- else
- master_wep_flag = 1; /* Intersil */
- }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ int master_wep_flag;
+ int auth_flag;

+ if (priv->wep_on)
+ __orinoco_hw_setup_wepkeys(priv);
+
+ if (priv->wep_restrict)
+ auth_flag = HERMES_AUTH_SHARED_KEY;
+ else
+ auth_flag = HERMES_AUTH_OPEN;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
+ if (priv->wep_on) {
+ /* Enable the shared-key authentication. */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFAUTHENTICATION_AGERE,
+ auth_flag);
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPENABLED_AGERE,
+ priv->wep_on);
+ if (err)
+ return err;
+ break;
+
+ case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
+ case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
+ if (priv->wep_on) {
+ if (priv->wep_restrict ||
+ (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
+ master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
+ HERMES_WEP_EXCL_UNENCRYPTED;
+ else
+ master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;

err = hermes_write_wordrec(hw, USER_BAP,
HERMES_RID_CNFAUTHENTICATION,
auth_flag);
if (err)
return err;
- }
+ } else
+ master_wep_flag = 0;
+
+ if (priv->iw_mode == IW_MODE_MONITOR)
+ master_wep_flag |= HERMES_WEP_HOST_DECRYPT;

/* Master WEP setting : on/off */
err = hermes_write_wordrec(hw, USER_BAP,
@@ -1530,13 +1557,6 @@
return err;

break;
-
- default:
- if (priv->wep_on) {
- printk(KERN_ERR "%s: WEP enabled, although not supported!\n",
- priv->ndev->name);
- return -EINVAL;
- }
}

return 0;
@@ -2702,11 +2722,17 @@
int err = 0;
char keybuf[ORINOCO_MAX_KEY_SIZE];
unsigned long flags;
-
+
+ if (! priv->has_wep)
+ return -EOPNOTSUPP;
+
if (erq->pointer) {
- /* We actually have a key to set */
- if ( (erq->length < SMALL_KEY_SIZE) || (erq->length > ORINOCO_MAX_KEY_SIZE) )
- return -EINVAL;
+ /* We actually have a key to set - check its length */
+ if (erq->length > LARGE_KEY_SIZE)
+ return -E2BIG;
+
+ if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
+ return -E2BIG;

if (copy_from_user(keybuf, erq->pointer, erq->length))
return -EFAULT;
@@ -2714,19 +2740,8 @@

if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;
-
+
if (erq->pointer) {
- if (erq->length > ORINOCO_MAX_KEY_SIZE) {
- err = -E2BIG;
- goto out;
- }
-
- if ( (erq->length > LARGE_KEY_SIZE)
- || ( ! priv->has_big_wep && (erq->length > SMALL_KEY_SIZE)) ) {
- err = -EINVAL;
- goto out;
- }
-
if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
index = priv->tx_key;

@@ -2737,7 +2752,7 @@
xlen = SMALL_KEY_SIZE;
} else
xlen = 0;
-
+
/* Switch on WEP if off */
if ((!enable) && (xlen > 0)) {
setindex = index;
@@ -2761,10 +2776,9 @@
setindex = index;
}
}
-
+
if (erq->flags & IW_ENCODE_DISABLED)
enable = 0;
- /* Only for Prism2 & Symbol cards (so far) - Jean II */
if (erq->flags & IW_ENCODE_OPEN)
restricted = 0;
if (erq->flags & IW_ENCODE_RESTRICTED)
@@ -2777,6 +2791,15 @@
memcpy(priv->keys[index].data, keybuf, erq->length);
}
priv->tx_key = setindex;
+
+ /* Try fast key change if connected and only keys are changed */
+ if (priv->wep_on && enable && (priv->wep_restrict == restricted) &&
+ netif_carrier_ok(dev)) {
+ err = __orinoco_hw_setup_wepkeys(priv);
+ /* No need to commit if successful */
+ goto out;
+ }
+
priv->wep_on = enable;
priv->wep_restrict = restricted;

@@ -2794,6 +2817,9 @@
char keybuf[ORINOCO_MAX_KEY_SIZE];
unsigned long flags;

+ if (! priv->has_wep)
+ return -EOPNOTSUPP;
+
if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;

@@ -2804,23 +2830,18 @@
if (! priv->wep_on)
erq->flags |= IW_ENCODE_DISABLED;
erq->flags |= index + 1;
-
- /* Only for symbol cards - Jean II */
- if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
- if(priv->wep_restrict)
- erq->flags |= IW_ENCODE_RESTRICTED;
- else
- erq->flags |= IW_ENCODE_OPEN;
- }
+
+ if (priv->wep_restrict)
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ else
+ erq->flags |= IW_ENCODE_OPEN;

xlen = le16_to_cpu(priv->keys[index].len);

erq->length = xlen;

- if (erq->pointer) {
- memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
- }
-
+ memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
+
orinoco_unlock(priv, &flags);

if (erq->pointer) {
@@ -3626,22 +3647,12 @@
break;

case SIOCSIWENCODE:
- if (! priv->has_wep) {
- err = -EOPNOTSUPP;
- break;
- }
-
err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding);
if (! err)
changed = 1;
break;

case SIOCGIWENCODE:
- if (! priv->has_wep) {
- err = -EOPNOTSUPP;
- break;
- }
-
if (! capable(CAP_NET_ADMIN)) {
err = -EPERM;
break;

--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:20:32

by David Gibson

[permalink] [raw]
Subject: [8/14] Orinoco driver updates - PCMCIA initialization cleanups

Cleanup the various bits of initialization code for PCMCIA / PC-Card
orinoco devices. This includes one important bugfix where we could
fail to take the lock in some circumstances.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco_cs.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_cs.c 2005-02-18 12:04:03.157157240 +1100
+++ working-2.6/drivers/net/wireless/orinoco_cs.c 2005-02-18 12:11:49.000000000 +1100
@@ -57,8 +57,8 @@
/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
* don't have any CIS entry for it. This workaround it... */
static int ignore_cis_vcc; /* = 0 */
-
module_param(ignore_cis_vcc, int, 0);
+MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");

/********************************************************************/
/* Magic constants */
@@ -128,6 +128,7 @@
if (err)
return err;

+ msleep(100);
clear_bit(0, &card->hard_reset_in_progress);

return 0;
@@ -166,9 +167,10 @@
link->priv = dev;

/* Interrupt setup */
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = NULL;
+ link->irq.Handler = orinoco_interrupt;
+ link->irq.Instance = dev;

/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
@@ -184,6 +186,7 @@
dev_list = link;

client_reg.dev_info = &dev_info;
+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
@@ -309,8 +312,8 @@
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
cistpl_cftable_entry_t dflt = { .index = 0 };

- if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
- pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
+ if ( (pcmcia_get_tuple_data(handle, &tuple) != 0)
+ || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0))
goto next_entry;

if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
@@ -349,8 +352,7 @@
dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;

/* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
+ link->conf.Attributes |= CONF_ENABLE_IRQ;

/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
@@ -402,14 +404,7 @@
* a handler to the interrupt, unless the 'Handler' member of
* the irq structure is initialized.
*/
- if (link->conf.Attributes & CONF_ENABLE_IRQ) {
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = orinoco_interrupt;
- link->irq.Instance = dev;
-
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
- }
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));

/* We initialize the hermes structure before completing PCMCIA
* configuration just in case the interrupt handler gets
@@ -434,8 +429,6 @@
SET_MODULE_OWNER(dev);
card->node.major = card->node.minor = 0;

- /* register_netdev will give us an ethX name */
- dev->name[0] = '\0';
SET_NETDEV_DEV(dev, &handle_to_dev(handle));
/* Tell the stack we exist */
if (register_netdev(dev) != 0) {
@@ -458,8 +451,7 @@
if (link->conf.Vpp1)
printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
link->conf.Vpp1 % 10);
- if (link->conf.Attributes & CONF_ENABLE_IRQ)
- printk(", irq %d", link->irq.AssignedIRQ);
+ printk(", irq %d", link->irq.AssignedIRQ);
if (link->io.NumPorts1)
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1);
@@ -525,12 +517,12 @@
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
- orinoco_lock(priv, &flags);
+ unsigned long flags;

+ spin_lock_irqsave(&priv->lock, flags);
netif_device_detach(dev);
priv->hw_unavailable++;
-
- orinoco_unlock(priv, &flags);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
break;


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:43:14

by Jeff Garzik

[permalink] [raw]
Subject: Re: [7/14] Orinoco driver updates - use modern module_parm()

David Gibson wrote:
> Add descrptions to module parameters in the orinoco driver, and also
> add permissions to allow them to be exported in sysfs.
>
> Signed-off-by: David Gibson <[email protected]>
>
> Index: working-2.6/drivers/net/wireless/orinoco.c
> ===================================================================
> --- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-10 13:19:14.000000000 +1100
> +++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-10 13:24:03.000000000 +1100
> @@ -461,12 +461,14 @@
> /* Level of debugging. Used in the macros in orinoco.h */
> #ifdef ORINOCO_DEBUG
> int orinoco_debug = ORINOCO_DEBUG;
> -module_param(orinoco_debug, int, 0);
> +module_param(orinoco_debug, int, 0644);
> +MODULE_PARM_DESC(orinoco_debug, "Debug level");
> EXPORT_SYMBOL(orinoco_debug);
> #endif

eventually it would be nice to support netif_msg_*

Jeff



2005-02-24 04:43:18

by Jeff Garzik

[permalink] [raw]
Subject: Re: [6/14] Orinoco driver updates - cleanup PCI initialization

FYI, pci_set_drvdata() needs to be one of the last functions called
during PCI ->probe().

Jeff



2005-02-24 04:48:14

by Jeff Garzik

[permalink] [raw]
Subject: Re: [14/14] Orinoco driver updates - update version and changelog

applied patches 1-14 to netdev-2.6. We'll let it sit there for a bit,
for testing and such. (netdev-2.6 gets auto-propagated to -mm)

Thanks for your patience and perserverance.

Jeff



2005-02-24 04:43:20

by David Gibson

[permalink] [raw]
Subject: [5/14] Orinoco driver updates - cleanup low-level code

Apply some cleanups to the low-level orinoco handling code in
hermes.[ch]. This cleans up some error handling code, corrects an
error code to something more accurate, and also increases a timeout
value. This last can (when the hardware plays up) cause long delays
with spinlocks held, which is bad, but is rather less prone to
prematurely giving up, which has the unfortunate habit of fatally
confusing the hardware in other ways :-/.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/hermes.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/hermes.c 2005-01-12 15:22:34.263633584 +1100
+++ working-2.6/drivers/net/wireless/hermes.c 2004-11-05 13:59:07.000000000 +1100
@@ -383,12 +383,17 @@
reg = hermes_read_reg(hw, oreg);
}

- if (reg & HERMES_OFFSET_BUSY) {
- return -ETIMEDOUT;
- }
+ if (reg != offset) {
+ printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
+ "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
+ (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
+ reg, id, offset);
+
+ if (reg & HERMES_OFFSET_BUSY) {
+ return -ETIMEDOUT;
+ }

- if (reg & HERMES_OFFSET_ERR) {
- return -EIO;
+ return -EIO; /* error or wrong offset */
}

return 0;
@@ -476,7 +481,7 @@
rlength = hermes_read_reg(hw, dreg);

if (! rlength)
- return -ENOENT;
+ return -ENODATA;

rtype = hermes_read_reg(hw, dreg);

Index: working-2.6/drivers/net/wireless/hermes.h
===================================================================
--- working-2.6.orig/drivers/net/wireless/hermes.h 2005-01-12 11:13:41.000000000 +1100
+++ working-2.6/drivers/net/wireless/hermes.h 2004-11-05 13:53:55.000000000 +1100
@@ -340,7 +340,7 @@
#ifdef __KERNEL__

/* Timeouts */
-#define HERMES_BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
+#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */

/* Basic control structure */
typedef struct hermes {

--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:43:19

by David Gibson

[permalink] [raw]
Subject: [2/14] Orinoco driver updates - update printk()s

Reformats printk()s, comments, labels and other cosmetic strings in
the orinoco driver. Also moves, removes, and adds ratelimiting in
some places. Behavioural changes are trivial/cosmetic only. This
reduces the cosmetic/trivial differences between the current kernel
version, and the CVS version of the driver; one small step towards
full merge.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/hermes.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/hermes.c 2005-02-10 14:47:39.572667480 +1100
+++ working-2.6/drivers/net/wireless/hermes.c 2005-02-10 14:47:41.293405888 +1100
@@ -48,6 +48,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/net.h>
#include <asm/errno.h>

#include "hermes.h"
@@ -232,13 +233,16 @@
err = hermes_issue_cmd(hw, cmd, parm0);
if (err) {
if (! hermes_present(hw)) {
- printk(KERN_WARNING "hermes @ %p: "
- "Card removed while issuing command.\n",
- hw->iobase);
+ if (net_ratelimit())
+ printk(KERN_WARNING "hermes @ %p: "
+ "Card removed while issuing command "
+ "0x%04x.\n", hw->iobase, cmd);
err = -ENODEV;
} else
- printk(KERN_ERR "hermes @ %p: Error %d issuing command.\n",
- hw->iobase, err);
+ if (net_ratelimit())
+ printk(KERN_ERR "hermes @ %p: "
+ "Error %d issuing command 0x%04x.\n",
+ hw->iobase, err, cmd);
goto out;
}

@@ -251,17 +255,16 @@
}

if (! hermes_present(hw)) {
- printk(KERN_WARNING "hermes @ %p: "
- "Card removed while waiting for command completion.\n",
- hw->iobase);
+ printk(KERN_WARNING "hermes @ %p: Card removed "
+ "while waiting for command 0x%04x completion.\n",
+ hw->iobase, cmd);
err = -ENODEV;
goto out;
}

if (! (reg & HERMES_EV_CMD)) {
- printk(KERN_ERR "hermes @ %p: "
- "Timeout waiting for command completion.\n",
- hw->iobase);
+ printk(KERN_ERR "hermes @ %p: Timeout waiting for "
+ "command 0x%04x completion.\n", hw->iobase, cmd);
err = -ETIMEDOUT;
goto out;
}
@@ -481,14 +484,13 @@
*length = rlength;

if (rtype != rid)
- printk(KERN_WARNING "hermes @ %p: "
- "hermes_read_ltv(): rid (0x%04x) does not match type (0x%04x)\n",
- hw->iobase, rid, rtype);
+ printk(KERN_WARNING "hermes @ %p: %s(): "
+ "rid (0x%04x) does not match type (0x%04x)\n",
+ hw->iobase, __FUNCTION__, rid, rtype);
if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
printk(KERN_WARNING "hermes @ %p: "
"Truncating LTV record from %d to %d bytes. "
- "(rid=0x%04x, len=0x%04x)\n",
- hw->iobase,
+ "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);

nwords = min((unsigned)rlength - 1, bufsize / 2);
Index: working-2.6/drivers/net/wireless/orinoco_pci.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_pci.c 2005-02-10 14:47:39.573667328 +1100
+++ working-2.6/drivers/net/wireless/orinoco_pci.c 2005-02-10 14:47:41.294405736 +1100
@@ -151,24 +151,18 @@

/* Assert the reset until the card notice */
hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
- printk(KERN_NOTICE "Reset done");
timeout = jiffies + (HERMES_PCI_COR_ONT * HZ / 1000);
while(time_before(jiffies, timeout)) {
- printk(".");
mdelay(1);
}
- printk(";\n");
//mdelay(HERMES_PCI_COR_ONT);

/* Give time for the card to recover from this hard effort */
hermes_write_regn(hw, PCI_COR, 0x0000);
- printk(KERN_NOTICE "Clear Reset");
timeout = jiffies + (HERMES_PCI_COR_OFFT * HZ / 1000);
while(time_before(jiffies, timeout)) {
- printk(".");
mdelay(1);
}
- printk(";\n");
//mdelay(HERMES_PCI_COR_OFFT);

/* The card is ready when it's no longer busy */
@@ -183,7 +177,6 @@
printk(KERN_ERR PFX "Busy timeout\n");
return -ETIMEDOUT;
}
- printk(KERN_NOTICE "pci_cor : reg = 0x%X - %lX - %lX\n", reg, timeout, jiffies);

return 0;
}
@@ -202,15 +195,19 @@
struct net_device *dev = NULL;

err = pci_enable_device(pdev);
- if (err)
- return -EIO;
+ if (err) {
+ printk(KERN_ERR PFX "Cannot enable PCI device\n");
+ return err;
+ }

/* Resource 0 is mapped to the hermes registers */
pci_iorange = pci_resource_start(pdev, 0);
pci_iolen = pci_resource_len(pdev, 0);
pci_ioaddr = ioremap(pci_iorange, pci_iolen);
- if (! pci_iorange)
+ if (! pci_iorange) {
+ printk(KERN_ERR PFX "Cannot remap hardware registers\n");
goto fail;
+ }

/* Allocate network device */
dev = alloc_orinocodev(0, NULL);
@@ -226,18 +223,16 @@
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);

- printk(KERN_DEBUG PFX
- "Detected Orinoco/Prism2 PCI device at %s, mem:0x%lX to 0x%lX -> 0x%p, irq:%d\n",
- pci_name(pdev), dev->mem_start, dev->mem_end, pci_ioaddr, pdev->irq);
-
hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING);
pci_set_drvdata(pdev, dev);

+ printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n",
+ pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq);
+
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
if (err) {
- printk(KERN_ERR PFX "Error allocating IRQ %d.\n",
- pdev->irq);
+ printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
err = -EBUSY;
goto fail;
}
@@ -245,7 +240,7 @@

/* Perform a COR reset to start the card */
if(orinoco_pci_cor_reset(priv) != 0) {
- printk(KERN_ERR "%s: Failed to start the card\n", dev->name);
+ printk(KERN_ERR PFX "Initial reset failed\n");
err = -ETIMEDOUT;
goto fail;
}
@@ -256,7 +251,7 @@

err = register_netdev(dev);
if (err) {
- printk(KERN_ERR "%s: Failed to register net device\n", dev->name);
+ printk(KERN_ERR PFX "Failed to register net device\n");
goto fail;
}

Index: working-2.6/drivers/net/wireless/orinoco.h
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.h 2005-02-10 14:47:40.526522472 +1100
+++ working-2.6/drivers/net/wireless/orinoco.h 2005-02-10 14:47:41.294405736 +1100
@@ -126,7 +126,7 @@
{
spin_lock_irqsave(&priv->lock, *flags);
if (priv->hw_unavailable) {
- printk(KERN_DEBUG "orinoco_lock() called with hw_unavailable (dev=%p)\n",
+ DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n",
priv->ndev);
spin_unlock_irqrestore(&priv->lock, *flags);
return -EBUSY;
Index: working-2.6/drivers/net/wireless/orinoco_tmd.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_tmd.c 2005-02-10 14:47:39.574667176 +1100
+++ working-2.6/drivers/net/wireless/orinoco_tmd.c 2005-02-10 14:47:41.295405584 +1100
@@ -92,8 +92,10 @@
void __iomem *mem;

err = pci_enable_device(pdev);
- if (err)
+ if (err) {
+ printk(KERN_ERR PFX "Cannot enable PCI device\n");
return -EIO;
+ }

printk(KERN_DEBUG PFX "TMD setup\n");
pccard_ioaddr = pci_resource_start(pdev, 2);
@@ -117,6 +119,7 @@
/* Allocate network device */
dev = alloc_orinocodev(0, NULL);
if (! dev) {
+ printk(KERN_ERR PFX "Cannot allocate network device\n");
err = -ENOMEM;
goto out2;
}
@@ -132,26 +135,27 @@
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);

+ hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
+ pci_set_drvdata(pdev, dev);
+
printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD device "
"at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
pccard_ioaddr);

- hermes_struct_init(&(priv->hw), mem, HERMES_16BIT_REGSPACING);
- pci_set_drvdata(pdev, dev);
-
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
if (err) {
- printk(KERN_ERR PFX "Error allocating IRQ %d.\n",
- pdev->irq);
+ printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
err = -EBUSY;
goto out4;
}
dev->irq = pdev->irq;

err = register_netdev(dev);
- if (err)
+ if (err) {
+ printk(KERN_ERR PFX "Cannot register network device\n");
goto out5;
+ }

return 0;

Index: working-2.6/drivers/net/wireless/orinoco_cs.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_cs.c 2005-02-10 14:47:39.573667328 +1100
+++ working-2.6/drivers/net/wireless/orinoco_cs.c 2005-02-10 14:47:41.295405584 +1100
@@ -391,7 +391,7 @@
last_ret = pcmcia_get_next_tuple(handle, &tuple);
if (last_ret == CS_NO_MORE_ITEMS) {
printk(KERN_ERR PFX "GetNextTuple(): No matching "
- "CIS configuration, maybe you need the "
+ "CIS configuration. Maybe you need the "
"ignore_cis_vcc=1 parameter.\n");
goto cs_failed;
}
Index: working-2.6/drivers/net/wireless/airport.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/airport.c 2005-02-10 14:47:39.571667632 +1100
+++ working-2.6/drivers/net/wireless/airport.c 2005-02-10 14:47:41.295405584 +1100
@@ -28,7 +28,6 @@
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
-#include <linux/delay.h>

#include <asm/io.h>
#include <asm/system.h>
@@ -194,14 +193,14 @@
hermes_t *hw;

if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
- printk(KERN_ERR PFX "wrong interrupt/addresses in OF tree\n");
+ printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
return -ENODEV;
}

/* Allocate space for private device-specific data */
dev = alloc_orinocodev(sizeof(*card), airport_hard_reset);
if (! dev) {
- printk(KERN_ERR PFX "can't allocate device datas\n");
+ printk(KERN_ERR PFX "Cannot allocate network device\n");
return -ENODEV;
}
priv = netdev_priv(dev);
@@ -224,11 +223,11 @@
/* Setup interrupts & base address */
dev->irq = macio_irq(mdev, 0);
phys_addr = macio_resource_start(mdev, 0); /* Physical address */
- printk(KERN_DEBUG PFX "Airport at physical address %lx\n", phys_addr);
+ printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
dev->base_addr = phys_addr;
card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
if (!card->vaddr) {
- printk(PFX "ioremap() failed\n");
+ printk(KERN_ERR PFX "ioremap() failed\n");
goto failed;
}

@@ -241,7 +240,7 @@
/* Reset it before we get the interrupt */
hermes_init(hw);

- if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", dev)) {
+ if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
goto failed;
}
@@ -252,7 +251,7 @@
printk(KERN_ERR PFX "register_netdev() failed\n");
goto failed;
}
- printk(KERN_DEBUG PFX "card registered for interface %s\n", dev->name);
+ printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
card->ndev_registered = 1;
return 0;
failed:
Index: working-2.6/drivers/net/wireless/orinoco_plx.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_plx.c 2005-02-10 14:47:39.574667176 +1100
+++ working-2.6/drivers/net/wireless/orinoco_plx.c 2005-02-10 14:47:41.296405432 +1100
@@ -167,15 +167,17 @@
int i;

err = pci_enable_device(pdev);
- if (err)
+ if (err) {
+ printk(KERN_ERR PFX "Cannot enable PCI device\n");
return -EIO;
+ }

/* Resource 2 is mapped to the PCMCIA space */
attr_mem = ioremap(pci_resource_start(pdev, 2), PAGE_SIZE);
if (!attr_mem)
- goto out;
+ goto fail_resources;

- printk(KERN_DEBUG "orinoco_plx: CIS: ");
+ printk(KERN_DEBUG PFX "CIS: ");
for (i = 0; i < 16; i++) {
printk("%02X:", readw(attr_mem+i));
}
@@ -185,10 +187,11 @@
/* FIXME: we probably need to be smarted about this */
memcpy_fromio(magic, attr_mem, 16);
if (memcmp(magic, cis_magic, 16) != 0) {
- printk(KERN_ERR "orinoco_plx: The CIS value of Prism2 PC card is invalid.\n");
+ printk(KERN_ERR PFX "The CIS value of Prism2 PC "
+ "card is unexpected\n");
err = -EIO;
iounmap(attr_mem);
- goto out;
+ goto fail_resources;
}

/* PCMCIA COR is the first byte following CIS: this write should
@@ -199,8 +202,8 @@
iounmap(attr_mem);

if (reg != COR_VALUE) {
- printk(KERN_ERR "orinoco_plx: Error setting COR value (reg=%x)\n", reg);
- goto out;
+ printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n", reg);
+ goto fail_resources;
}

/* bjoern: We need to tell the card to enable interrupts, in
@@ -209,40 +212,39 @@
addr = pci_resource_start(pdev, 1);
reg = inl(addr+PLX_INTCSR);
if (reg & PLX_INTCSR_INTEN)
- printk(KERN_DEBUG "orinoco_plx: "
- "Local Interrupt already enabled\n");
+ printk(KERN_DEBUG PFX "Local Interrupt already enabled\n");
else {
reg |= PLX_INTCSR_INTEN;
outl(reg, addr+PLX_INTCSR);
reg = inl(addr+PLX_INTCSR);
if(!(reg & PLX_INTCSR_INTEN)) {
- printk(KERN_ERR "orinoco_plx: "
- "Couldn't enable Local Interrupts\n");
- goto out;
+ printk(KERN_ERR PFX "Couldn't enable Local Interrupts\n");
+ goto fail_resources;
}
}

- /* and 3 to the PCMCIA slot I/O address space */
+ /* Resource 3 is mapped to the PCMCIA I/O address space */
pccard_ioaddr = pci_resource_start(pdev, 3);
pccard_iolen = pci_resource_len(pdev, 3);
if (! request_region(pccard_ioaddr, pccard_iolen, DRIVER_NAME)) {
- printk(KERN_ERR "orinoco_plx: I/O resource 0x%lx @ 0x%lx busy\n",
+ printk(KERN_ERR PFX "I/O resource 0x%lx @ 0x%lx busy\n",
pccard_iolen, pccard_ioaddr);
err = -EBUSY;
- goto out;
+ goto fail_resources;
}

mem = pci_iomap(pdev, 3, 0);
if (!mem) {
err = -ENOMEM;
- goto out1;
+ goto fail_map;
}

/* Allocate network device */
dev = alloc_orinocodev(0, NULL);
if (!dev) {
+ printk(KERN_ERR PFX "Cannot allocate network device\n");
err = -ENOMEM;
- goto out2;
+ goto fail_alloc;
}

priv = netdev_priv(dev);
@@ -250,39 +252,41 @@
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);

+ hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
+ pci_set_drvdata(pdev, dev);
+
printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device "
"at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
pccard_ioaddr);

- hermes_struct_init(&(priv->hw), mem, HERMES_16BIT_REGSPACING);
- pci_set_drvdata(pdev, dev);
-
err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
dev->name, dev);
if (err) {
- printk(KERN_ERR PFX "Error allocating IRQ %d.\n", pdev->irq);
+ printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
err = -EBUSY;
- goto out3;
+ goto fail_irq;
}
dev->irq = pdev->irq;

err = register_netdev(dev);
- if (err)
- goto out4;
+ if (err) {
+ printk(KERN_ERR PFX "Cannot register network device\n");
+ goto fail;
+ }

return 0;

-out4:
+ fail:
free_irq(dev->irq, dev);
-out3:
+ fail_irq:
free_netdev(dev);
-out2:
+ fail_alloc:
pci_iounmap(pdev, mem);
-out1:
+ fail_map:
release_region(pccard_ioaddr, pccard_iolen);
-out:
+ fail_resources:
pci_disable_device(pdev);
- printk(KERN_DEBUG PFX "init_one(), FAIL!\n");
+
return err;
}

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-10 14:47:40.525522624 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-10 14:47:41.298405128 +1100
@@ -805,8 +805,9 @@
desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
if (err) {
- printk(KERN_ERR "%s: Error %d writing Tx descriptor to BAP\n",
- dev->name, err);
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d writing Tx descriptor "
+ "to BAP\n", dev->name, err);
stats->tx_errors++;
goto fail;
}
@@ -836,8 +837,9 @@
err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
txfid, HERMES_802_3_OFFSET);
if (err) {
- printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
- dev->name, err);
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d writing packet "
+ "header to BAP\n", dev->name, err);
stats->tx_errors++;
goto fail;
}
@@ -1297,8 +1299,8 @@
}
break;
default:
- printk(KERN_DEBUG "%s: Unknown information frame received "
- "(type %04x).\n", dev->name, type);
+ printk(KERN_DEBUG "%s: Unknown information frame received: "
+ "type 0x%04x, length %d\n", dev->name, type, len);
/* We don't actually do anything about it */
break;
}
@@ -1307,7 +1309,7 @@
static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
{
if (net_ratelimit())
- printk(KERN_WARNING "%s: Information frame lost.\n", dev->name);
+ printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
}

/********************************************************************/
@@ -1785,7 +1787,8 @@
}

if (p)
- printk(KERN_WARNING "Multicast list is longer than mc_count\n");
+ printk(KERN_WARNING "%s: Multicast list is "
+ "longer than mc_count\n", dev->name);

err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
@@ -2053,7 +2056,7 @@
le16_to_cpus(&sta_id.variant);
le16_to_cpus(&sta_id.major);
le16_to_cpus(&sta_id.minor);
- printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
+ printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
dev->name, sta_id.id, sta_id.variant,
sta_id.major, sta_id.minor);

@@ -3045,8 +3048,9 @@
priv->mwo_robust = 0;
else {
if (frq->fixed)
- printk(KERN_WARNING "%s: Fixed fragmentation not \
-supported on this firmware. Using MWO robust instead.\n", dev->name);
+ printk(KERN_WARNING "%s: Fixed fragmentation is "
+ "not supported on this firmware. "
+ "Using MWO robust instead.\n", dev->name);
priv->mwo_robust = 1;
}
} else {
@@ -3518,7 +3522,7 @@
}
/* Copy stats */
/* In theory, we should disable irqs while copying the stats
- * because the rx path migh update it in the middle...
+ * because the rx path might update it in the middle...
* Bah, who care ? - Jean II */
memcpy(&spy_stat, priv->spy_stat,
sizeof(struct iw_quality) * IW_MAX_SPY);


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 04:43:19

by David Gibson

[permalink] [raw]
Subject: [7/14] Orinoco driver updates - use modern module_parm()

Add descrptions to module parameters in the orinoco driver, and also
add permissions to allow them to be exported in sysfs.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco.c 2005-02-10 13:19:14.000000000 +1100
+++ working-2.6/drivers/net/wireless/orinoco.c 2005-02-10 13:24:03.000000000 +1100
@@ -461,12 +461,14 @@
/* Level of debugging. Used in the macros in orinoco.h */
#ifdef ORINOCO_DEBUG
int orinoco_debug = ORINOCO_DEBUG;
-module_param(orinoco_debug, int, 0);
+module_param(orinoco_debug, int, 0644);
+MODULE_PARM_DESC(orinoco_debug, "Debug level");
EXPORT_SYMBOL(orinoco_debug);
#endif

static int suppress_linkstatus; /* = 0 */
-module_param(suppress_linkstatus, bool, 0);
+module_param(suppress_linkstatus, bool, 0644);
+MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");

/********************************************************************/
/* Compile time configuration and compatibility stuff */


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-24 06:55:31

by Dominik Brodowski

[permalink] [raw]
Subject: Re: [8/14] Orinoco driver updates - PCMCIA initialization cleanups

> @@ -184,6 +186,7 @@
> dev_list = link;
>
> client_reg.dev_info = &dev_info;
> + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;

That's not needed any longer for 2.6.

Dominik

2005-02-24 07:40:30

by Jeff Garzik

[permalink] [raw]
Subject: Re: [8/14] Orinoco driver updates - PCMCIA initialization cleanups

Dominik Brodowski wrote:
>>@@ -184,6 +186,7 @@
>> dev_list = link;
>>
>> client_reg.dev_info = &dev_info;
>>+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
>
>
> That's not needed any longer for 2.6.

So who wants to send the incremental update patch? :)

Jeff



2005-02-25 05:03:55

by David Gibson

[permalink] [raw]
Subject: Re: [Orinoco-devel] Re: [6/14] Orinoco driver updates - cleanup PCI initialization

On Wed, Feb 23, 2005 at 11:35:05PM -0500, Jeff Garzik wrote:
> FYI, pci_set_drvdata() needs to be one of the last functions called
> during PCI ->probe().

Ok, here's a patch to correct that (applies on top of the other stack,
obviously):

As Jeff Garzik has pointed out, pci_set_drvdata() belongs right at the
end of PCI initialization. Correct this in the various PCI based
orinoco drivers.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco_plx.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_plx.c 2005-02-25 15:47:53.011419192 +1100
+++ working-2.6/drivers/net/wireless/orinoco_plx.c 2005-02-25 15:45:13.000000000 +1100
@@ -257,7 +257,6 @@
SET_NETDEV_DEV(dev, &pdev->dev);

hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
- pci_set_drvdata(pdev, dev);

printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device "
"at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
@@ -315,6 +314,8 @@
goto fail;
}

+ pci_set_drvdata(pdev, dev);
+
return 0;

fail:
Index: working-2.6/drivers/net/wireless/orinoco_pci.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_pci.c 2005-02-25 15:47:53.282378000 +1100
+++ working-2.6/drivers/net/wireless/orinoco_pci.c 2005-02-25 15:44:50.000000000 +1100
@@ -230,7 +230,6 @@
SET_NETDEV_DEV(dev, &pdev->dev);

hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING);
- pci_set_drvdata(pdev, dev);

printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n",
pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq);
@@ -257,6 +256,8 @@
goto fail;
}

+ pci_set_drvdata(pdev, dev);
+
return 0;

fail:
Index: working-2.6/drivers/net/wireless/orinoco_tmd.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_tmd.c 2005-02-25 15:47:53.011419192 +1100
+++ working-2.6/drivers/net/wireless/orinoco_tmd.c 2005-02-25 15:45:33.000000000 +1100
@@ -166,7 +166,6 @@
SET_NETDEV_DEV(dev, &pdev->dev);

hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
- pci_set_drvdata(pdev, dev);

printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD device "
"at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
@@ -193,6 +192,8 @@
goto fail;
}

+ pci_set_drvdata(pdev, dev);
+
return 0;

fail:


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-25 05:03:43

by David Gibson

[permalink] [raw]
Subject: Re: [Orinoco-devel] Re: [8/14] Orinoco driver updates - PCMCIA initialization cleanups

On Thu, Feb 24, 2005 at 02:29:05AM -0500, Jeff Garzik wrote:
> Dominik Brodowski wrote:
> >>@@ -184,6 +186,7 @@
> >> dev_list = link;
> >>
> >> client_reg.dev_info = &dev_info;
> >>+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
> >
> >
> >That's not needed any longer for 2.6.
>
> So who wants to send the incremental update patch? :)

Guess I will. See below.

Any particular reason the field and associated constants haven't been
exunged from the tree, since they're no longer used?

The client_reg.Attributes field is no longer used. Don't bother
setting it.

Signed-off-by: David Gibson <[email protected]>

Index: working-2.6/drivers/net/wireless/orinoco_cs.c
===================================================================
--- working-2.6.orig/drivers/net/wireless/orinoco_cs.c 2005-02-25 15:47:53.098405968 +1100
+++ working-2.6/drivers/net/wireless/orinoco_cs.c 2005-02-25 15:52:56.000000000 +1100
@@ -186,7 +186,6 @@
dev_list = link;

client_reg.dev_info = &dev_info;
- client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |


--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist. NOT _the_ _other_ _way_
| _around_!
http://www.ozlabs.org/people/dgibson

2005-02-25 07:02:30

by Dominik Brodowski

[permalink] [raw]
Subject: Re: [Orinoco-devel] Re: [8/14] Orinoco driver updates - PCMCIA initialization cleanups

On Fri, Feb 25, 2005 at 04:03:10PM +1100, David Gibson wrote:
> On Thu, Feb 24, 2005 at 02:29:05AM -0500, Jeff Garzik wrote:
> > Dominik Brodowski wrote:
> > >>@@ -184,6 +186,7 @@
> > >> dev_list = link;
> > >>
> > >> client_reg.dev_info = &dev_info;
> > >>+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
> > >
> > >
> > >That's not needed any longer for 2.6.
> >
> > So who wants to send the incremental update patch? :)
>
> Guess I will. See below.
>
> Any particular reason the field and associated constants haven't been
> exunged from the tree, since they're no longer used?

To keep external drivers compiling -- it'll be removed soon, though.

Dominik