diff -ruN --exclude='*.o' --exclude='*~' --exclude='*.ver' hostap.old2/driver/modules/hostap_hw.c hostap/driver/modules/hostap_hw.c
--- hostap.old2/driver/modules/hostap_hw.c	Sun Sep  8 13:50:00 2002
+++ hostap/driver/modules/hostap_hw.c	Sun Sep  8 14:37:12 2002
@@ -2298,8 +2298,7 @@
 	stats = hostap_get_stats(dev);
 
 	len = prism2_rx_80211(dev, rxdesc, PRISM2_RX_MONITOR, NULL, 0,
-			      local->monitor_type == PRISM2_MONITOR_PRISM ?
-			      1 : 0, NULL);
+			      local->arphrd_prism, NULL);
 	stats->rx_packets++;
 	stats->rx_bytes += len;
 }
@@ -2506,11 +2505,15 @@
 	if (macport != 0) {
 #ifdef PRISM2_MONITOR
 		if (macport == 7) {
+#ifdef PRISM2_HOSTAPD
+			monitor_rx(local->apdev, rxdesc);
+#else /* PRISM2_HOSTAPD */
 			monitor_rx(dev, rxdesc);
+#endif /* PRISM2_HOSTAPD */
 		} else {
-#else
+#else /* PRISM2_MONITOR */
 		{
-#endif
+#endif /* PRISM2_MONITOR */
 			if (!local->is_promisc)
 				printk(KERN_DEBUG "RX: Unknown MACPort %d\n",
 				       macport);
@@ -2539,7 +2542,7 @@
 		 * processing */
 		if (type == WLAN_FC_TYPE_MGMT) {
 			prism2_rx_80211(local->apdev, rxdesc, PRISM2_RX_MGMT,
-					NULL, 0, 0, NULL);
+					NULL, 0, local->arphrd_prism, NULL);
 			local->apdevstats.rx_packets++;
 			local->apdevstats.rx_bytes += 24 + len;
 			goto rx_exit;
@@ -2894,7 +2897,8 @@
 				/* Send IEEE 802.1X frames to the user space
 				 * daemon for processing */
 				prism2_rx_80211(local->apdev, rxdesc,
-						PRISM2_RX_MGMT, NULL, 0, 0,
+						PRISM2_RX_MGMT, NULL, 0,
+						local->arphrd_prism,
 						local->bus_m1_buf);
 				local->apdevstats.rx_packets++;
 				local->apdevstats.rx_bytes += 24 + len;
@@ -3984,7 +3988,9 @@
 #ifdef PRISM2_DOWNLOAD_SUPPORT
 	local->func->download = prism2_download;
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
+#if defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR)
 	local->func->rx_80211 = prism2_rx_80211;
+#endif
 
 	local->disable_on_close = disable_on_close;
 	local->mtu = mtu;
diff -ruN --exclude='*.o' --exclude='*~' --exclude='*.ver' hostap.old2/driver/modules/hostap_ioctl.c hostap/driver/modules/hostap_ioctl.c
--- hostap.old2/driver/modules/hostap_ioctl.c	Sun Sep  1 13:28:28 2002
+++ hostap/driver/modules/hostap_ioctl.c	Sun Sep  8 15:07:04 2002
@@ -879,22 +879,81 @@
 {
 	local_info_t *local = (local_info_t *) dev->priv;
 
-#ifdef PRISM2_NO_STATIONS_MODES
-	if (*mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT)
-		return -EOPNOTSUPP;
-#else /* PRISM2_NO_STATIONS_MODES */
 	if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
-	    *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT)
+	    *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT &&
+	    *mode != IW_MODE_MONITOR)
+		return -EOPNOTSUPP;
+
+#ifdef PRISM2_NO_STATIONS_MODES
+	if (*mode == IW_MODE_ADHOC || *mode != IW_MODE_INFRA)
 		return -EOPNOTSUPP;
 #endif /* PRISM2_NO_STATIONS_MODES */
 
+#ifndef PRISM2_MONITOR
+	if (*mode == IW_MODE_MONITOR)
+		return -EOPNOTSUPP;
+#endif /* PRISM2_MONITOR */
+
 	if (*mode == local->iw_mode)
 		return 0;
 
-	printk(KERN_DEBUG "prism2: %s: operating mode changed "
+#ifdef PRISM2_MONITOR
+	if (local->iw_mode == IW_MODE_MONITOR) {
+		printk(KERN_DEBUG "%s: Disabling monitor mode\n", dev->name);
+		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
+			    (HFA384X_TEST_STOP << 8),
+			    0, NULL, NULL);
+		hostap_set_encryption(local);
+#ifndef PRISM2_HOSTAPD
+		dev->type = ARPHRD_ETHER;
+		dev->hard_header_parse = local->saved_eth_header_parse;
+#endif /* PRISM2_HOSTAPD */
+	}
+#endif /* PRISM2_MONITOR */
+
+	printk(KERN_DEBUG "%s: operating mode changed "
 	       "%d -> %d\n", dev->name, local->iw_mode, *mode);
+
 	local->iw_mode = *mode;
 
+#ifdef PRISM2_MONITOR
+	if (local->iw_mode == IW_MODE_MONITOR) {
+		int ret;
+
+		printk(KERN_DEBUG "%s: Enabling monitor mode\n", dev->name);
+#ifndef PRISM2_HOSTAPD
+		if (local->arphrd_prism) {
+			dev->type = ARPHRD_IEEE80211_PRISM;
+			dev->hard_header_parse =
+				hostap_80211_prism_header_parse;
+		} else {
+			dev->type = ARPHRD_IEEE80211;
+			dev->hard_header_parse =
+				hostap_80211_header_parse;
+		}
+#endif /* PRISM2_HOSTAPD */
+		ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
+				      HFA384X_PORTTYPE_PSEUDO_IBSS);
+		if (ret) {
+			printk(KERN_DEBUG "Port type setting for monitor mode "
+			       "failed\n");
+			return -EOPNOTSUPP;
+		}
+		ret = hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
+				      HFA384X_WEPFLAGS_HOSTENCRYPT |
+				      HFA384X_WEPFLAGS_HOSTDECRYPT);
+		if (ret) {
+			printk(KERN_DEBUG "WEP flags setting failed\n");
+			return -EOPNOTSUPP;
+		}
+		local->func->reset_port(dev);
+		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
+			    (HFA384X_TEST_MONITOR << 8),
+			    0, NULL, NULL);
+		return 0;
+	}
+#endif /* PRISM2_MONITOR */
+
 	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
 			    hostap_get_porttype(local)))
 		return -EOPNOTSUPP;
@@ -1562,10 +1621,6 @@
 
 #if WIRELESS_EXT > 8
 static const struct iw_priv_args prism2_priv[] = {
-#ifdef PRISM2_MONITOR
-	{ PRISM2_IOCTL_MONITOR,
-	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor" },
-#endif /* PRISM2_MONITOR */
 	{ PRISM2_IOCTL_READMIF,
 	  IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
 	  IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "readmif" },
@@ -1714,6 +1769,12 @@
 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ieee_802_1x" },
 	{ PRISM2_PARAM_IEEE_802_1X,
 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getieee_802_1x" },
+#if defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR)
+	{ PRISM2_PARAM_ARPHRD_PRISM,
+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "arphrd_prism" },
+	{ PRISM2_PARAM_ARPHRD_PRISM,
+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getarphrd_prism" },
+#endif /* defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR) */
 #endif /* PRISM2_USE_WE_SUB_IOCTLS */
 #endif /* WIRELESS_EXT >= 12 */
 };
@@ -1932,6 +1993,38 @@
 		local->ieee_802_1x = value;
 		break;
 
+#if defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR)
+	case PRISM2_PARAM_ARPHRD_PRISM:
+		if (value) {
+#ifdef PRISM2_HOSTAPD
+			local->apdev->type = ARPHRD_IEEE80211_PRISM;
+			local->apdev->hard_header_parse =
+				hostap_80211_prism_header_parse;
+#else /* PRISM2_HOSTAPD */
+			if (local->iw_mode == IW_MODE_MONITOR) {
+				dev->type = ARPHRD_IEEE80211_PRISM;
+				dev->hard_header_parse =
+					hostap_80211_prism_header_parse;
+			}
+#endif /* PRISM2_HOSTAPD */
+			local->arphrd_prism = 1;
+		} else {
+#ifdef PRISM2_HOSTAPD
+			local->apdev->type = ARPHRD_IEEE80211;
+			local->apdev->hard_header_parse =
+				hostap_80211_header_parse;
+#else /* PRISM2_HOSTAPD */
+			if (local->iw_mode == IW_MODE_MONITOR) {
+				dev->type = ARPHRD_IEEE80211;
+				dev->hard_header_parse =
+					hostap_80211_header_parse;
+			}
+#endif /* PRISM2_HOSTAPD */
+			local->arphrd_prism = 0;
+		}
+		break;
+#endif /* defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR) */
+
 	default:
 		printk(KERN_DEBUG "%s: prism2_param: unknown param %d\n",
 		       dev->name, param);
@@ -2073,6 +2166,12 @@
 		*param = local->ieee_802_1x;
 		break;
 
+#if defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR)
+	case PRISM2_PARAM_ARPHRD_PRISM:
+		*param = local->arphrd_prism;
+		break;
+#endif /* defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR) */
+
 	default:
 		printk(KERN_DEBUG "%s: get_prism2_param: unknown param %d\n",
 		       dev->name, *param);
@@ -2118,74 +2217,6 @@
 }
 
 
-#ifdef PRISM2_MONITOR
-static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i)
-{
-	local_info_t *local = (local_info_t *) dev->priv;
-	int ret = 0;
-
-	if (*i == 0) {
-		printk(KERN_DEBUG "Disabling monitor mode\n");
-		dev->type = ARPHRD_ETHER;
-		dev->hard_header_parse = local->saved_eth_header_parse;
-		local->monitor_type = PRISM2_MONITOR_OFF;
-		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
-			    (HFA384X_TEST_STOP << 8),
-			    0, NULL, NULL);
-		ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
-				      hostap_get_porttype(local));
-		hostap_set_encryption(local);
-		local->func->reset_port(dev);
-	} else if (*i == 1) {
-		/* netlink socket mode is not supported anymore since it did
-		 * not separate different devices from each other and was not
-		 * best method for delivering large amount of packets to
-		 * user space */
-		ret = -EOPNOTSUPP;
-	} else if (*i == 2 || *i == 3) {
-		printk(KERN_DEBUG "Enabling monitor mode(%i)\n", *i);
-		switch (*i) {
-		case 2:
-			dev->type = ARPHRD_IEEE80211;
-			dev->hard_header_parse = hostap_80211_header_parse;
-			local->monitor_type = PRISM2_MONITOR_80211;
-			break;
-		case 3:
-			dev->type = ARPHRD_IEEE80211_PRISM;
-			dev->hard_header_parse =
-				hostap_80211_prism_header_parse;
-			local->monitor_type = PRISM2_MONITOR_PRISM;
-			break;
-		}
-		ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
-				      HFA384X_PORTTYPE_PSEUDO_IBSS);
-		if (ret) {
-			printk(KERN_DEBUG "Port type setting for monitor mode "
-			       "failed\n");
-			return -EOPNOTSUPP;
-		}
-		/* Host decrypt is needed to get the IV and ICV fields;
-		 * however, monitor mode seems to remove WEP flag from frame
-		 * control field */
-		ret = hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
-				      HFA384X_WEPFLAGS_HOSTENCRYPT |
-				      HFA384X_WEPFLAGS_HOSTDECRYPT);
-		if (ret) {
-			printk(KERN_DEBUG "WEP flags setting failed\n");
-			return -EOPNOTSUPP;
-		}
-		local->func->reset_port(dev);
-		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
-			    (HFA384X_TEST_MONITOR << 8),
-			    0, NULL, NULL);
-	} else
-		ret = -EINVAL;
-
-	return ret;
-}
-#endif /* PRISM2_MONITOR */
-
-
 static int prism2_ioctl_priv_reset(struct net_device *dev, int *i)
 {
 	local_info_t *local = (local_info_t *) dev->priv;
@@ -2950,13 +2981,6 @@
 		else ret = prism2_ioctl_priv_inquire(dev, (int *) wrq->u.name);
 		break;
 
-#ifdef PRISM2_MONITOR
-	case PRISM2_IOCTL_MONITOR:
-		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
-		else ret = prism2_ioctl_priv_monitor(dev, (int *) wrq->u.name);
-		break;
-#endif /* PRISM2_MONITOR */
-
 	case PRISM2_IOCTL_RESET:
 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
 		else ret = prism2_ioctl_priv_reset(dev, (int *) wrq->u.name);
diff -ruN --exclude='*.o' --exclude='*~' --exclude='*.ver' hostap.old2/driver/modules/hostap_wlan.h hostap/driver/modules/hostap_wlan.h
--- hostap.old2/driver/modules/hostap_wlan.h	Sun Sep  8 13:50:00 2002
+++ hostap/driver/modules/hostap_wlan.h	Sun Sep  8 15:03:28 2002
@@ -794,7 +794,8 @@
 	PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20,
 	PRISM2_PARAM_HOST_ROAMING = 21,
 	PRISM2_PARAM_BCRX_STA_KEY = 22,
-	PRISM2_PARAM_IEEE_802_1X = 23
+	PRISM2_PARAM_IEEE_802_1X = 23,
+	PRISM2_PARAM_ARPHRD_PRISM = 24
 };
 
 
@@ -986,10 +987,12 @@
 	int (*download)(local_info_t *local,
 			struct prism2_download_param *param);
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
+#if defined(PRISM2_MONITOR) || defined(PRISM2_HOSTAPD)
 	int (*rx_80211)(struct net_device *dev,
 			struct hfa384x_rx_frame *rxdesc,
 			int type, char *extra, int extra_len,
 			int prism_header, char *buf);
+#endif /* defined(PRISM2_MONITOR) || defined(PRISM2_HOSTAPD) */
 };
 
 struct local_info {
@@ -1079,13 +1082,13 @@
 #endif /* WIRELESS_EXT > 13 */
 #endif /* WIRELESS_EXT */
 #ifdef PRISM2_MONITOR
-	enum {
-		PRISM2_MONITOR_OFF, PRISM2_MONITOR_80211, PRISM2_MONITOR_PRISM
-	} monitor_type;
 	int (*saved_eth_header_parse)(struct sk_buff *skb,
 				      unsigned char *haddr);
 	int monitor_allow_fcserr;
 #endif /* PRISM2_MONITOR */
+#if defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR)
+	int arphrd_prism;
+#endif /* defined(PRISM2_HOSTAPD) || defined(PRISM2_MONITOR) */
 #ifdef PRISM2_HOSTAPD
 	struct net_device *apdev;
 	struct net_device_stats apdevstats;
@@ -1197,6 +1200,12 @@
 #ifndef IW_MODE_REPEAT
 #define IW_MODE_REPEAT 4
 #endif
+#ifndef IW_MODE_SECOND
+#define IW_MODE_SECOND 5
+#endif
+#ifndef IW_MODE_MONITOR
+#define IW_MODE_MONITOR 6
+#endif
 
 #ifndef PRISM2_NO_DEBUG
 

