--- orinoco.h.orig	Thu Sep 12 22:58:40 2002
+++ orinoco.h	Mon Sep 30 13:13:04 2002
@@ -60,6 +60,7 @@
 	int has_pm;
 	int has_preamble;
 	int has_sensitivity;
+	int has_fastkey;
 	int nicbuf_size;
 	int broken_cor_reset;
 	u16 channel_mask;
--- orinoco.c.orig	Thu Sep 12 22:58:40 2002
+++ orinoco.c	Wed Oct  2 11:30:04 2002
@@ -500,7 +500,7 @@
 static int __orinoco_program_rids(struct orinoco_private *priv);
 
 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
-static int __orinoco_hw_setup_wep(struct orinoco_private *priv);
+static int __orinoco_hw_setup_wep(struct orinoco_private *priv, int fastkey);
 static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]);
 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
 				char buf[IW_ESSID_MAX_SIZE+1]);
@@ -821,7 +821,7 @@
 
 	/* Set up encryption */
 	if (priv->has_wep) {
-		err = __orinoco_hw_setup_wep(priv);
+		err = __orinoco_hw_setup_wep(priv, 0);
 		if (err) {
 			printk(KERN_ERR "%s: Error %d activating WEP\n",
 			       dev->name, err);
@@ -1000,15 +1000,27 @@
 }
 
 
-static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
+static int __orinoco_hw_setup_wep(struct orinoco_private *priv, int fastkey)
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	int	master_wep_flag;
 	int	auth_flag;
+	u16	wep_enabled;
 
+	if (fastkey && priv->has_fastkey == 0)
+		return -EAGAIN;
+	
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
+		if (fastkey) {
+			err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPENABLED_AGERE,
+						  &wep_enabled);
+			if (wep_enabled != priv->wep_on) {
+				return -EAGAIN;
+			}
+		}
+
 		if (priv->wep_on) {
 			err = hermes_write_wordrec(hw, USER_BAP,
 						   HERMES_RID_CNFTXKEY_AGERE,
@@ -1022,11 +1034,13 @@
 			if (err)
 				return err;
 		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFWEPENABLED_AGERE,
-					   priv->wep_on);
-		if (err)
-			return err;
+
+		if (!fastkey) {
+			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 */
@@ -1728,6 +1742,7 @@
 	priv->has_wep = 0;
 	priv->has_big_wep = 0;
 	priv->broken_cor_reset = 0;
+	priv->has_fastkey = 0;
 
 	/* Determine capabilities from the firmware version */
 	switch (priv->firmware_type) {
@@ -1748,6 +1763,7 @@
 		priv->has_mwo = (firmver >= 0x60000);
 		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
 		priv->ibss_port = 1;
+		priv->has_fastkey = (firmver >= 0x60000);
 
 		/* FIXME: Which firmware really do have a broken reset */
 		priv->broken_cor_reset = (firmver < 0x60000);
@@ -3449,10 +3465,20 @@
 			err = -EOPNOTSUPP;
 			break;
 		}
-
+		
 		err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding);
-		if (! err)
-			changed = 1;
+		if (! err && netif_running(dev)) {
+			/* Try fastkeying.  If fastkeying is not not
+			 *  available or supported, we allow the
+			 *  orinoco_reconfigure() to run below.  */
+			orinoco_lock(priv, &flags);
+			err = __orinoco_hw_setup_wep(priv, 1);
+			orinoco_unlock(priv, &flags);
+			if (err == -EAGAIN) {
+				changed = 1;
+				err = 0;
+			}
+		}
 		break;
 
 	case SIOCGIWENCODE:
