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