Fixup for latest Symbol firmware in orinoco_cs...
Jean Tourrilhes
jt at bougret.hpl.hp.com
Tue Oct 2 12:40:07 EST 2001
Hi,
Somebody provided me a 3Com card with the latest Symbol
firmware, so I took the opportunity to get it to work with orinoco_cs
and fix the firware detection for those cards.
Bottom line : card works fine, but no power management in
latest firmware. IBSS with a Orinoco is a bit weird, but IBSS between
two Symbol cards works ok.
David : can you process this patch ? It's tested and ready...
Jean
-------------- next part --------------
diff -u -p -r linux/drivers/net/wireless.10/hermes.h linux/drivers/net/wireless/hermes.h
--- linux/drivers/net/wireless.10/hermes.h Fri Sep 28 22:58:35 2001
+++ linux/drivers/net/wireless/hermes.h Tue Oct 2 01:09:52 2001
@@ -50,6 +50,7 @@
#define HERMES_FRAME_LEN_MAX (2304)
#define HERMES_MAX_MULTICAST (16)
#define HERMES_MAGIC (0x7d1f)
+#define HERMES_SYMBOL_MAX_VER (14)
/*
* Hermes register offsets
@@ -202,8 +203,7 @@
#define HERMES_RID_WEP_AVAIL (0xfd4f)
#define HERMES_RID_CURRENT_CHANNEL (0xfdc1)
#define HERMES_RID_DATARATES (0xfdc6)
-#define HERMES_RID_SYMBOL_PRIMARY_VER (0xfd03)
-#define HERMES_RID_SYMBOL_SECONDARY_VER (0xfd21)
+#define HERMES_RID_SYMBOL_SECONDARY_VER (0xfd24)
#define HERMES_RID_SYMBOL_KEY_LENGTH (0xfc2B)
/*
diff -u -p -r linux/drivers/net/wireless.10/orinoco.c linux/drivers/net/wireless/orinoco.c
--- linux/drivers/net/wireless.10/orinoco.c Fri Sep 28 22:58:35 2001
+++ linux/drivers/net/wireless/orinoco.c Tue Oct 2 02:04:15 2001
@@ -190,6 +190,14 @@
* Rx path, but don't make as much noise about it.
* o Firmware detection cleanups.
*
+ * v0.07 -> v0.07a - 1/10/2001 - Jean II
+ * o Add code to read Symbol firmware revision, inspired by latest code
+ * in Spectrum24 by Lee John Keyser-Allen - Thanks Lee !
+ * o Thanks to Jared Valentine <hidden at xmission.com> for "providing" me
+ * a 3Com card with a recent firmware, fill out Symbol firmware
+ * capabilities of latest rev (2.20), as well as older Symbol cards.
+ * o Disable Power Management in newer Symbol firmware, the API
+ * has changed (documentation needed).
*
* TODO - Jean II
* o inline functions (lot's of candidate, need to reorder code)
@@ -1286,7 +1294,7 @@ static void determine_firmware(struct ne
if (sta_id.vendor == 1) {
/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
- ELSE, Meloc, HP, IBM, Dell 1150 */
+ 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);
@@ -1303,7 +1311,7 @@ static void determine_firmware(struct ne
priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
Gold cards from the others? */
priv->has_mwo = (firmver >= 0x60000);
- priv->has_pm = (firmver >= 0x40020);
+ priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
priv->has_preamble = 0;
priv->ibss_port = 1;
/* Tested with Lucent firmware :
@@ -1314,27 +1322,59 @@ static void determine_firmware(struct ne
/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
/* Intel MAC : 00:02:B3:* */
/* 3Com MAC : 00:50:DA:* */
+ union symbol_sta_id {
+ char raw[HERMES_SYMBOL_MAX_VER];
+ char string[HERMES_SYMBOL_MAX_VER + 1];
+ } symbol_sta_id;
+
+ /* Get the Symbol firmware version */
+ err = HERMES_READ_RECORD(hw, USER_BAP,
+ HERMES_RID_SYMBOL_SECONDARY_VER,
+ &(symbol_sta_id.raw));
+ if (err) {
+ printk(KERN_WARNING "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
+ dev->name, err);
+ firmver = 0;
+ symbol_sta_id.string[0] = '\0';
+ } else {
+ /* The firmware revision is a string, the format is
+ * something like : "V2.20-01".
+ * Quick and dirty parsing... - Jean II
+ */
+ firmver = ((symbol_sta_id.raw[1] - '0') << 16)
+ | ((symbol_sta_id.raw[3] - '0') << 12)
+ | ((symbol_sta_id.raw[4] - '0') << 8)
+ | ((symbol_sta_id.raw[6] - '0') << 4)
+ | (symbol_sta_id.raw[7] - '0');
+
+ symbol_sta_id.string[HERMES_SYMBOL_MAX_VER] = '\0';
+ }
+
printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
- "(unknown version)\n", dev->name);
+ "version [%s] (parsing to %X)\n", dev->name,
+ symbol_sta_id.string, firmver);
- /* FIXME : we need to get Symbol firmware revision.
- * I tried to use SYMBOL_***ARY_VER, but it didn't
- * returned anything proper... */
priv->firmware_type = FIRMWARE_TYPE_SYMBOL;
priv->tx_rate_ctrl = 0xF; /* 11 Mb/s auto */
priv->need_card_reset = 1;
priv->broken_reset = 0;
priv->broken_allocate = 1;
priv->has_port3 = 1;
- priv->has_ibss = 1; /* FIXME */
- priv->has_wep = 1; /* FIXME */
- priv->has_big_wep = 1; /* RID_SYMBOL_KEY_LENGTH */
+ priv->has_ibss = (firmver >= 0x20000);
+ priv->has_wep = (firmver >= 0x15012);
+ priv->has_big_wep = (firmver >= 0x20000);
priv->has_mwo = 0;
- priv->has_pm = 1; /* FIXME */
- priv->has_preamble = 0; /* FIXME */
+ priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
+ priv->has_preamble = (firmver >= 0x20000);
priv->ibss_port = 4;
- /* Tested with Intel firmware : v15 => Jean II */
+ /* Tested with Intel firmware : 0x20015 => Jean II */
+ /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
} else {
+ /* D-Link, Linksys, Adtron, ZoomAir, and many others...
+ * Samsung, Compaq 100/200 and Proxim are slightly
+ * 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.%02d\n", dev->name,
sta_id.major, sta_id.minor);
diff -u -p -r linux/drivers/net/wireless.10/orinoco.h linux/drivers/net/wireless/orinoco.h
--- linux/drivers/net/wireless.10/orinoco.h Fri Sep 28 22:58:49 2001
+++ linux/drivers/net/wireless/orinoco.h Tue Oct 2 01:12:19 2001
@@ -25,7 +25,7 @@
#define DLDWD_MACPORT 0
#define IRQ_LOOP_MAX 10
#define TX_NICBUF_SIZE 2048
-#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Intel firmware */
+#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
#define MAX_KEYS 4
#define MAX_KEY_SIZE 14
#define LARGE_KEY_SIZE 13
@@ -110,7 +110,7 @@ extern struct list_head dldwd_instances;
#ifdef ORINOCO_DEBUG
extern int dldwd_debug;
-#define DEBUG(n, args...) if (dldwd_debug>(n)) printk(KERN_DEBUG args)
+#define DEBUG(n, args...) do { if (dldwd_debug>(n)) printk(KERN_DEBUG args); } while(0)
#define DEBUGMORE(n, args...) do { if (dldwd_debug>(n)) printk(args); } while (0)
#else
#define DEBUG(n, args...) do { } while (0)
More information about the wireless
mailing list