Missed Orinoco patch

Jean Tourrilhes jt at bougret.hpl.hp.com
Thu Nov 15 12:43:14 EST 2001


	Hi Dave,

	You seem to have missed an Orinoco patch I sent a couple of
weeks ago. It adds support for Wireless Extension 12. Maybe it's in
your todo list, but I wanted to make sure...
	Patch re-attached...

	Jean

-------------- next part --------------
diff -u -p -r wireless.11b/hermes.h wireless/hermes.h
--- wireless.11b/hermes.h	Fri Oct  5 18:36:04 2001
+++ wireless/hermes.h	Mon Oct  8 22:26:36 2001
@@ -149,6 +149,12 @@
 #define		HERMES_MONITOR_DISABLE		(0x000f)
 
 /*
+ * Inquire RIDs
+ */
+#define		HERMES_RID_TALLIES		(0xF100)
+#define		HERMES_RID_SCAN			(0xF101)
+
+/*
  * Configuration RIDs
  */
 
@@ -311,6 +317,15 @@ static inline int hermes_disable_port(he
 
 	return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), 
 				 0, &resp);
+}
+
+/* Initiate an INQUIRE command : most likely Tallies or Scan.
+ * The result will come later as an information frame in __dldwd_ev_info() */
+int hermes_inquire(hermes_t *hw, uint16_t rid)
+{
+	hermes_response_t resp;
+	
+	return hermes_docmd_wait(hw, HERMES_CMD_INQ, rid, &resp);
 }
 
 #define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 )
diff -u -p -r wireless.11b/orinoco.c wireless/orinoco.c
--- wireless.11b/orinoco.c	Fri Oct  5 18:36:04 2001
+++ wireless/orinoco.c	Tue Oct  9 01:04:14 2001
@@ -222,6 +222,10 @@
  *	o Inserted some missing acknowledgements/info into the Changelog.
  *	o Fixed some bugs in the normalisation of signel level reporting.
  *
+ * v0.08a -> v0.08b - ???? - Jean II
+ *	o Update to Wireless 12 -> private ioctl + avg qual stats
+ *	o Get discard stats through an INQUIRE request
+ *
  * TODO - Jean II
  *	o inline functions (lots of candidate, need to reorder code)
  *	o Test PrismII/Symbol cards & firmware versions
@@ -275,6 +279,13 @@ MODULE_PARM(dldwd_debug, "i");
 int use_old_encaps = 0;
 MODULE_PARM(use_old_encaps, "i");
 
+/* Wireless Extension Backward compatibility - Jean II
+ * If the new wireless device private ioctl range is not defined,
+ * default to standard device private ioctl range */
+#ifndef SIOCIWFIRSTPRIV
+#define SIOCIWFIRSTPRIV	SIOCDEVPRIVATE
+#endif /* SIOCIWFIRSTPRIV */
+
 #define SYMBOL_MAX_VER_LEN	(14)
 
 const long channel_frequency[] = {
@@ -335,6 +346,35 @@ struct dldwd_frame_hdr {
 	uint16_t ethertype __PACKED__;
 };
 
+/* Grabbed from wvlan_hcf.h - Thanks Lucent... - Jean II
+ * This are the accumulated tallies since the last tallies INQUIRE command */
+struct dldwd_tallies_frame {
+  uint16_t	TxUnicastFrames;
+  uint16_t	TxMulticastFrames;
+  uint16_t	TxFragments;
+  uint16_t	TxUnicastOctets;
+  uint16_t	TxMulticastOctets;
+  uint16_t	TxDeferredTransmissions;
+  uint16_t	TxSingleRetryFrames;
+  uint16_t	TxMultipleRetryFrames;
+  uint16_t	TxRetryLimitExceeded;
+  uint16_t	TxDiscards;
+  uint16_t	RxUnicastFrames;
+  uint16_t	RxMulticastFrames;
+  uint16_t	RxFragments;
+  uint16_t	RxUnicastOctets;
+  uint16_t	RxMulticastOctets;
+  uint16_t	RxFCSErrors;
+  uint16_t	RxDiscards_NoBuffer;
+  uint16_t	TxDiscardsWrongSA;
+  uint16_t	RxWEPUndecryptable;
+  uint16_t	RxMsgInMsgFragments;
+  uint16_t	RxMsgInBadMsgFragments;
+  /* Those last are probably not available in very old firmwares */
+  uint16_t	RxDiscards_WEPICVError;
+  uint16_t	RxDiscards_WEPExcluded;
+};
+
 #define P8023_OFFSET		(sizeof(hermes_frame_desc_t) + \
 				sizeof(struct p80211_hdr))
 #define ENCAPS_OVERHEAD		(sizeof(struct p8022_hdr) + 2)
@@ -1088,9 +1128,79 @@ static void __dldwd_ev_infdrop(dldwd_pri
 
 static void __dldwd_ev_info(dldwd_priv_t *priv, hermes_t *hw)
 {
-	DEBUG(3, "%s: Information frame received.\n", priv->ndev.name);
-	/* We don't actually do anything about it - we assume the MAC
-	   controller can deal with it */
+	struct net_device *dev = &priv->ndev;
+	uint16_t infofid;
+	uint16_t info[2];
+	int err;
+
+	/* This is an answer to an INQUIRE command that we did earlier.
+	 * The controller return to us a pseudo frame containing
+	 * the information we have asked - Jean II */
+
+	infofid = hermes_read_regn(hw, INFOFID);
+	DEBUG(3, "__dldwd_ev_info(): INFOFID=0x%04x\n", infofid);
+
+	/* Read the info frame header - don't try too hard */
+	err = hermes_bap_pread(hw, IRQ_BAP, info, sizeof(info),
+			       infofid, 0);
+	if (err) {
+		if (err == -EIO)
+			DEBUG(1, "%s: EIO reading info frame.\n", dev->name);
+		else
+			printk(KERN_ERR "%s: error %d reading info frame. "
+			       "Frame dropped.\n", dev->name, err);
+		return;
+	}
+
+	/* The header is composed as follows :
+	 * info[0] -> size of the frame
+	 * info[1] -> RID of the INQUIRE command
+	 */
+	switch(le16_to_cpu(info[1])) {
+	case HERMES_RID_TALLIES:
+		{
+		struct dldwd_tallies_frame tallies;
+		struct iw_statistics *wstats = &priv->wstats;
+		int len = le16_to_cpu(info[0]) - 1;
+
+		if(len > (sizeof(struct dldwd_tallies_frame) / 2)) {
+			DEBUG(1, "%s: tallies frame too long.\n", dev->name);
+			len = sizeof(struct dldwd_tallies_frame) / 2;
+		}
+
+		/* Read directly the data (no seek) */
+		hermes_read_words(hw, HERMES_DATA1, (void *) &tallies, len);
+
+		/* Increment our various counters */
+		/* wstats->discard.nwid - no wrong BSSID stuff */
+		wstats->discard.code +=
+			le16_to_cpu(tallies.RxWEPUndecryptable);
+		if(len == (sizeof(struct dldwd_tallies_frame) / 2))
+			wstats->discard.code += 
+				le16_to_cpu(tallies.RxDiscards_WEPICVError) +
+				le16_to_cpu(tallies.RxDiscards_WEPExcluded);
+		wstats->discard.misc +=
+			le16_to_cpu(tallies.TxDiscardsWrongSA);
+#if WIRELESS_EXT > 11
+		wstats->discard.fragment +=
+			le16_to_cpu(tallies.RxMsgInBadMsgFragments);
+		wstats->discard.retries +=
+			le16_to_cpu(tallies.TxRetryLimitExceeded);
+		/* wstats->miss.beacon - no match */
+#if ORINOCO_DEBUG > 3
+		/* Hack for debugging - should not be taken as an example */
+		wstats->discard.nwid += le16_to_cpu(tallies.TxUnicastFrames);
+		wstats->miss.beacon += le16_to_cpu(tallies.RxUnicastFrames);
+#endif
+#endif /* WIRELESS_EXT > 11 */
+		}
+		break;
+	default:
+		DEBUG(3, "%s: Unknown information frame received.\n",
+		      priv->ndev.name);
+		/* We don't actually do anything about it */
+		break;
+	}
 }
 
 static void __dldwd_ev_rx(dldwd_priv_t *priv, hermes_t *hw)
@@ -1627,6 +1737,11 @@ dldwd_get_wireless_stats(struct net_devi
 		wstats->qual.updated = 7;
 	}
 
+	/* We can't really wait for the tallies inquiry command to
+	 * complete, so we just use the previous results and trigger
+	 * a new tallies inquiry command for next time - Jean II */
+	err = hermes_inquire(hw, HERMES_RID_TALLIES);
+
 	dldwd_unlock(priv);
 
 	if (err)
@@ -1894,10 +2009,21 @@ static int dldwd_ioctl_getiwrange(struct
 		range.max_qual.qual = 0;
 		range.max_qual.level = 0;
 		range.max_qual.noise = 0;
+#if WIRELESS_EXT > 11
+		range.avg_qual.qual = 0;
+		range.avg_qual.level = 0;
+		range.avg_qual.noise = 0;
+#endif /* WIRELESS_EXT > 11 */
 	} else {
 		range.max_qual.qual = 0x8b - 0x2f;
 		range.max_qual.level = 0x2f - 0x95 - 1;
 		range.max_qual.noise = 0x2f - 0x95 - 1;
+#if WIRELESS_EXT > 11
+		/* Need to get better values */
+		range.avg_qual.qual = 0x24;
+		range.avg_qual.level = 0xC2;
+		range.avg_qual.noise = 0x9E;
+#endif /* WIRELESS_EXT > 11 */
 	}
 
 	err = dldwd_hw_get_bitratelist(priv, &numrates,
@@ -3043,26 +3169,26 @@ dldwd_ioctl(struct net_device *dev, stru
 		DEBUG(1, "%s: SIOCGIWPRIV\n", dev->name);
 		if (wrq->u.data.pointer) {
 			struct iw_priv_args privtab[] = {
-				{ SIOCDEVPRIVATE + 0x0, 0, 0, "force_reset" },
-				{ SIOCDEVPRIVATE + 0x1, 0, 0, "card_reset" },
-				{ SIOCDEVPRIVATE + 0x2,
+				{ SIOCIWFIRSTPRIV + 0x2,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 				  0, "set_port3" },
-				{ SIOCDEVPRIVATE + 0x3, 0,
+				{ SIOCIWFIRSTPRIV + 0x3, 0,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 				  "get_port3" },
-				{ SIOCDEVPRIVATE + 0x4,
+				{ SIOCIWFIRSTPRIV + 0x4,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 				  0, "set_preamble" },
-				{ SIOCDEVPRIVATE + 0x5, 0,
+				{ SIOCIWFIRSTPRIV + 0x5, 0,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 				  "get_preamble" },
-				{ SIOCDEVPRIVATE + 0x6,
+				{ SIOCIWFIRSTPRIV + 0x6,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 				  0, "set_ibssport" },
-				{ SIOCDEVPRIVATE + 0x7, 0,
+				{ SIOCIWFIRSTPRIV + 0x7, 0,
 				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-				  "get_ibssport" }
+				  "get_ibssport" },
+				{ SIOCIWFIRSTPRIV + 0xC, 0, 0, "force_reset" },
+				{ SIOCIWFIRSTPRIV + 0xE, 0, 0, "cor_reset" },
 			};
 
 			err = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab));
@@ -3075,8 +3201,8 @@ dldwd_ioctl(struct net_device *dev, stru
 		}
 		break;
 	       
-	case SIOCDEVPRIVATE + 0x0: /* force_reset */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x0 (force_reset)\n",
+	case SIOCIWFIRSTPRIV + 0xC: /* force_reset */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0xC (force_reset)\n",
 		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
@@ -3087,22 +3213,22 @@ dldwd_ioctl(struct net_device *dev, stru
 		dldwd_reset(priv);
 		break;
 
-	case SIOCDEVPRIVATE + 0x1: /* card_reset */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x1 (card_reset)\n",
+	case SIOCIWFIRSTPRIV + 0xE: /* cor_reset */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0xE (card_reset)\n",
 		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
 			break;
 		}
 		
-		printk(KERN_DEBUG "%s: Forcing card reset!\n", dev->name);
+		printk(KERN_DEBUG "%s: Forcing COR reset!\n", dev->name);
 		if(priv->card_reset_handler != NULL)
 			priv->card_reset_handler(priv);
 		dldwd_reset(priv);
 		break;
 
-	case SIOCDEVPRIVATE + 0x2: /* set_port3 */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x2 (set_port3)\n",
+	case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x2 (set_port3)\n",
 		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
@@ -3114,14 +3240,14 @@ dldwd_ioctl(struct net_device *dev, stru
 			changed = 1;
 		break;
 
-	case SIOCDEVPRIVATE + 0x3: /* get_port3 */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x3 (get_port3)\n",
+	case SIOCIWFIRSTPRIV + 0x3: /* get_port3 */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x3 (get_port3)\n",
 		      dev->name);
 		err = dldwd_ioctl_getport3(dev, wrq);
 		break;
 
-	case SIOCDEVPRIVATE + 0x4: /* set_preamble */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x4 (set_preamble)\n",
+	case SIOCIWFIRSTPRIV + 0x4: /* set_preamble */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x4 (set_preamble)\n",
 		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
@@ -3147,8 +3273,8 @@ dldwd_ioctl(struct net_device *dev, stru
 			err = -EOPNOTSUPP;
 		break;
 
-	case SIOCDEVPRIVATE + 0x5: /* get_preamble */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x5 (get_preamble)\n",
+	case SIOCIWFIRSTPRIV + 0x5: /* get_preamble */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x5 (get_preamble)\n",
 		      dev->name);
 		if(priv->has_preamble) {
 			int *val = (int *)wrq->u.name;
@@ -3159,8 +3285,8 @@ dldwd_ioctl(struct net_device *dev, stru
 		} else
 			err = -EOPNOTSUPP;
 		break;
-	case SIOCDEVPRIVATE + 0x6: /* set_ibssport */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x6 (set_ibssport)\n",
+	case SIOCIWFIRSTPRIV + 0x6: /* set_ibssport */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x6 (set_ibssport)\n",
 		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
@@ -3172,8 +3298,8 @@ dldwd_ioctl(struct net_device *dev, stru
 			changed = 1;
 		break;
 
-	case SIOCDEVPRIVATE + 0x7: /* get_ibssport */
-		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x7 (get_ibssport)\n",
+	case SIOCIWFIRSTPRIV + 0x7: /* get_ibssport */
+		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x7 (get_ibssport)\n",
 		      dev->name);
 		err = dldwd_ioctl_getibssport(dev, wrq);
 		break;


More information about the wireless mailing list