All pastes #465735 Raw Edit

Unnamed

public text v1 · immutable
#465735 ·published 2007-04-30 15:26 UTC
rendered paste body
diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_80211_tx.c linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_80211_tx.c
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_80211_tx.c	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_80211_tx.c	2007-04-01 03:27:43.000000000 +0200
@@ -69,6 +69,9 @@
 	iface = netdev_priv(dev);
 	local = iface->local;

+	if (local->iw_mode == IW_MODE_MONITOR)
+		goto xmit;
+
 	if (skb->len < ETH_HLEN) {
 		printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb "
 		       "(len=%d)\n", dev->name, skb->len);
@@ -234,6 +237,7 @@
 		memcpy(skb_put(skb, ETH_ALEN), &hdr.addr4, ETH_ALEN);
 	}

+xmit:
 	iface->stats.tx_packets++;
 	iface->stats.tx_bytes += skb->len;

@@ -404,8 +408,6 @@
 	}

 	if (skb->len < 24) {
-		printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
-		       "(len=%d)\n", dev->name, skb->len);
 		ret = 0;
 		iface->stats.tx_dropped++;
 		goto fail;
diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_common.h linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_common.h
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_common.h	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_common.h	2007-04-01 03:32:50.000000000 +0200
@@ -255,6 +255,7 @@
 #define PRISM2_IOCTL_ADDMAC (SIOCIWFIRSTPRIV + 18)
 #define PRISM2_IOCTL_DELMAC (SIOCIWFIRSTPRIV + 20)
 #define PRISM2_IOCTL_KICKMAC (SIOCIWFIRSTPRIV + 22)
+#define PRISM2_IOCTL_DSSSTEST (SIOCIWFIRSTPRIV + 24)

 /* following are not in SIOCGIWPRIV list; check permission in the driver code
  */
diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_config.h linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_config.h
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_config.h	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_config.h	2007-04-01 03:27:43.000000000 +0200
@@ -47,4 +47,22 @@
  */
 /* #define PRISM2_NO_STATION_MODES */

+/* Enable setting txpower */
+#define RAW_TXPOWER_SETTING
+
+
+//PATCH:
+/* Convert TX power to and from dBm (which does not work, it's just a
+ * very rough estimate) */
+/* #define PRISM2_DBM_CONVERSION */
+
+//PATCH
+/* define what settings should be restored after card reset */
+#define PRISM2_RESTORE_POWER
+/* #define PRISM2_RESTORE_SENS */
+/* #define PRISM2_RESTORE_RETRY */
+/* #define PRISM2_RESTORE_RATE */
+
+#define RAW_TXPOWER_SETTING
+
 #endif /* HOSTAP_CONFIG_H */
diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap.h linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap.h
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap.h	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap.h	2007-04-01 03:27:43.000000000 +0200
@@ -54,6 +54,10 @@
 int prism2_wds_del(local_info_t *local, u8 *remote_addr,
 		   int rtnl_locked, int do_not_remove);

+int prism2_set_rate_from_local(struct net_device *dev);
+int prism2_set_power_from_local(struct net_device *dev);
+int prism2_set_sens_from_local(struct net_device *dev);
+int prism2_set_retry_from_local(struct net_device *dev);

 /* hostap_ap.c */

diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_hw.c linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_hw.c
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_hw.c	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_hw.c	2007-04-01 03:35:53.000000000 +0200
@@ -1006,6 +1006,65 @@
 	return fid;
 }

+static int prism2_monitor_enable(struct net_device *dev)
+{
+	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, 5)) {
+		printk(KERN_DEBUG "Port type setting for monitor mode "
+			"failed\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (hfa384x_cmd(dev, HFA384X_CMDCODE_TEST | (0x0a << 8),
+			     0, NULL, NULL)) {
+		printk(KERN_DEBUG "Could not enter testmode 0x0a\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
+			    HFA384X_WEPFLAGS_PRIVACYINVOKED |
+			    HFA384X_WEPFLAGS_HOSTENCRYPT |
+			    HFA384X_WEPFLAGS_HOSTDECRYPT)) {
+		printk(KERN_DEBUG "WEP flags setting failed\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, 1)) {
+		printk(KERN_DEBUG "Could not set promiscuous mode\n");
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int prism2_dssstest_enable(struct net_device *dev)
+{
+	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, 5)) {
+		printk(KERN_DEBUG "Port type setting for monitor mode "
+			"failed\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (hfa384x_cmd(dev, HFA384X_CMDCODE_TEST | (0x0e << 8),
+			     0xa010, NULL, NULL)) {
+		printk(KERN_DEBUG "Could not enter testmode 0x0a\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
+			    HFA384X_WEPFLAGS_PRIVACYINVOKED |
+			    HFA384X_WEPFLAGS_HOSTENCRYPT |
+			    HFA384X_WEPFLAGS_HOSTDECRYPT)) {
+		printk(KERN_DEBUG "WEP flags setting failed\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, 1)) {
+		printk(KERN_DEBUG "Could not set promiscuous mode\n");
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}

 static int prism2_reset_port(struct net_device *dev)
 {
@@ -1032,6 +1091,14 @@
 			       "port\n", dev->name);
 	}

+	if (local->iw_mode == IW_MODE_DSSSTEST)
+		/* force mode 0x0a after port 0 reset */
+		return prism2_dssstest_enable(dev);
+
+	if (local->iw_mode == IW_MODE_MONITOR)
+		/* force mode 0x0a after port 0 reset */
+		return prism2_monitor_enable(dev);
+
 	/* It looks like at least some STA firmware versions reset
 	 * fragmentation threshold back to 2346 after enable command. Restore
 	 * the configured value, if it differs from this default. */
@@ -1464,6 +1531,10 @@
 		return 1;
 	}

+	if (local->iw_mode == IW_MODE_MONITOR)
+		/* force mode 0x0a after port 0 reset */
+		prism2_monitor_enable(dev);
+
 	local->hw_ready = 1;
 	local->hw_reset_tries = 0;
 	local->hw_resetting = 0;
@@ -1490,6 +1561,7 @@

 static int prism2_hw_config(struct net_device *dev, int initial)
 {
+	int ret=0;
 	struct hostap_interface *iface;
 	local_info_t *local;

@@ -1512,11 +1584,32 @@
 	    (initial == 0 || (initial == 2 && local->num_dev_open > 0))) {
 		if (!local->dev_enabled)
 			prism2_callback(local, PRISM2_CALLBACK_ENABLE);
+	}
+
+	// PATCH: Set saved txpower, rate, sens & retry values after HW reset
+#ifdef PRISM2_RESTORE_POWER
+	prism2_set_power_from_local(dev);
+#endif
+
+#ifdef PRISM2_RESTORE_RATE
+	prism2_set_rate_from_local(dev);
+#endif
+
+#ifdef PRISM2_RESTORE_SENS
+	prism2_set_sens_from_local(dev);
+#endif
+
+#ifdef PRISM2_RESTORE_RETRY
+	prism2_set_retry_from_local(dev);
+#endif
+
+	if (!local->pri_only && !initial) {
 		local->dev_enabled = 1;
-		return prism2_hw_enable(dev, initial);
+		ret = prism2_hw_enable(dev, initial);
 	}

-	return 0;
+
+	return ret;
 }


@@ -3146,6 +3239,8 @@
 	local->func->hw_config = prism2_hw_config;
 	local->func->hw_reset = prism2_hw_reset;
 	local->func->hw_shutdown = prism2_hw_shutdown;
+	local->func->monitor_enable = prism2_monitor_enable;
+	local->func->dssstest_enable = prism2_dssstest_enable;
 	local->func->reset_port = prism2_reset_port;
 	local->func->schedule_reset = prism2_schedule_reset;
 #ifdef PRISM2_DOWNLOAD_SUPPORT
@@ -3198,6 +3293,18 @@
 	local->sram_type = -1;
 	local->scan_channel_mask = 0xffff;

+	// PATCH: set default txpower, rate, sens and retry
+
+    	local->txpower_type = PRISM2_TXPOWER_FIXED;
+     	local->txpower = 127;   /* minimal */
+     	local->tx_rate_control = HFA384X_RATES_1MBPS |
+            HFA384X_RATES_2MBPS | HFA384X_RATES_5MBPS |
+            HFA384X_RATES_11MBPS; /* auto */
+     	local->sensitivity = 1;
+     	local->manual_retry_count = 8;
+     	local->client_post_assoc_setup=0; /* a lock variable */
+
+
 	/* Initialize task queue structures */
 	INIT_WORK(&local->reset_queue, handle_reset_queue, local);
 	INIT_WORK(&local->set_multicast_list_queue,
@@ -3246,7 +3353,8 @@
 	local->tick_timer.expires = jiffies + 2 * HZ;
 	add_timer(&local->tick_timer);

-	INIT_LIST_HEAD(&local->bss_list);
+
+    INIT_LIST_HEAD(&local->bss_list);

 	hostap_setup_dev(dev, local, 1);
 	local->saved_eth_header_parse = dev->hard_header_parse;
diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_info.c linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_info.c
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_info.c	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_info.c	2007-04-01 03:27:43.000000000 +0200
@@ -449,6 +449,26 @@
 	if (connected || local->prev_linkstatus_connected)
 		wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
 	local->prev_linkstatus_connected = connected;
+
+	// PATCH: Set saved txpower, & retry after linkstatus change
+	    if (connected) {
+	#ifdef PRISM2_RESTORE_POWER
+	    prism2_set_power_from_local(local->dev);
+	#endif
+
+	#ifdef PRISM2_RESTORE_RETRY
+	 	prism2_set_retry_from_local(local->dev);
+	#endif
+	    }
+
+	/* note: setting rate or sens triggers a new de-and-association
+	I tried to work around this in version 0.1 of the psrrr patch.
+
+	However, in some cases, the new association would cancel the correctly
+	restored txpower, which is by far the most important value to be restored.
+	See version 0.1 for detail.
+
+	*/
 }


diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_ioctl.c linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_ioctl.c
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_ioctl.c	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_ioctl.c	2007-04-04 20:05:13.000000000 +0200
@@ -343,8 +343,12 @@
 		printk(KERN_WARNING "%s: TXRateControl/cnfSupportedRates "
 		       "setting to 0x%x failed\n",
 		       dev->name, local->tx_rate_control);
+	} else {
+		printk(KERN_DEBUG "%s: TX Rate set to 0x%x\n",
+		       dev->name, local->tx_rate_control);
 	}

+
 	/* Update TX rate configuration for all STAs based on new operational
 	 * rate set. */
 	hostap_update_rates(local);
@@ -352,6 +356,11 @@
 	return ret;
 }

+// PATCH: Global set rate function
+int prism2_set_rate_from_local(struct net_device *dev)
+{
+	return hostap_set_rate(dev);
+}

 static int prism2_ioctl_siwrate(struct net_device *dev,
 				struct iw_request_info *info,
@@ -486,11 +495,11 @@
 	if (sens->value < 1 || sens->value > 3)
 		return -EINVAL;

-	if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, sens->value) ||
-	    local->func->reset_port(dev))
-		return -EINVAL;
+	local->sensitivity = sens->value;
+
+	return prism2_set_sens_from_local(dev);
+

-	return 0;
 }

 static int prism2_ioctl_giwsens(struct net_device *dev,
@@ -1104,33 +1113,7 @@

 	printk(KERN_DEBUG "Enabling monitor mode\n");
 	hostap_monitor_set_type(local);
-
-	if (hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE,
-			    HFA384X_PORTTYPE_PSEUDO_IBSS)) {
-		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 */
-	if (hostap_set_word(dev, HFA384X_RID_CNFWEPFLAGS,
-			    HFA384X_WEPFLAGS_HOSTENCRYPT |
-			    HFA384X_WEPFLAGS_HOSTDECRYPT)) {
-		printk(KERN_DEBUG "WEP flags setting failed\n");
-		return -EOPNOTSUPP;
-	}
-
-	if (local->func->reset_port(dev) ||
-	    local->func->cmd(dev, HFA384X_CMDCODE_TEST |
-			     (HFA384X_TEST_MONITOR << 8),
-			     0, NULL, NULL)) {
-		printk(KERN_DEBUG "Setting monitor mode failed\n");
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
+	return local->func->reset_port(dev);
 }


@@ -1151,6 +1134,31 @@
 	return hostap_set_encryption(local);
 }

+static int hostap_dssstest_mode_enable(local_info_t *local)
+{
+	struct net_device *dev = local->dev;
+
+	printk(KERN_DEBUG "Enabling dssstest mode\n");
+	return local->func->reset_port(dev);
+}
+
+static int hostap_dssstest_mode_disable(local_info_t *local)
+{
+	struct net_device *dev = local->ddev;
+
+	if (dev == NULL)
+		return -1;
+
+	printk(KERN_DEBUG "%s: Disabling dssstest mode\n", dev->name);
+//	dev->type = ARPHRD_ETHER;
+//	dev->hard_header_parse = local->saved_eth_header_parse;
+	if (local->func->cmd(dev, HFA384X_CMDCODE_TEST |
+			     (HFA384X_TEST_STOP << 8),
+			     0, NULL, NULL))
+		return -1;
+//	return hostap_set_encryption(local);
+	return 0;
+}

 static int prism2_ioctl_siwmode(struct net_device *dev,
 				struct iw_request_info *info,
@@ -1165,7 +1173,7 @@

 	if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
 	    *mode != IW_MODE_MASTER && *mode != IW_MODE_REPEAT &&
-	    *mode != IW_MODE_MONITOR)
+	    *mode != IW_MODE_MONITOR && *mode != IW_MODE_DSSSTEST)
 		return -EOPNOTSUPP;

 #ifdef PRISM2_NO_STATION_MODES
@@ -1182,11 +1190,15 @@
 		return -EINVAL;
 	}

+	if (local->iw_mode == IW_MODE_DSSSTEST)
+		hostap_dssstest_mode_disable(local);
+
 	if (local->iw_mode == IW_MODE_MONITOR)
 		hostap_monitor_mode_disable(local);

 	if ((local->iw_mode == IW_MODE_ADHOC ||
-	     local->iw_mode == IW_MODE_MONITOR) && *mode == IW_MODE_MASTER) {
+	     local->iw_mode == IW_MODE_MONITOR ||
+	     local->iw_mode == IW_MODE_DSSSTEST) && *mode == IW_MODE_MASTER) {
 		/* There seems to be a firmware bug in at least STA f/w v1.5.6
 		 * that leaves beacon frames to use IBSS type when moving from
 		 * IBSS to Host AP mode. Doing double Port0 reset seems to be
@@ -1198,8 +1210,11 @@
 	       "%d -> %d\n", dev->name, local->iw_mode, *mode);
 	local->iw_mode = *mode;

+	if (local->iw_mode == IW_MODE_DSSSTEST)
+		return hostap_dssstest_mode_enable(local);
+
 	if (local->iw_mode == IW_MODE_MONITOR)
-		hostap_monitor_mode_enable(local);
+		return hostap_monitor_mode_enable(local);
 	else if (local->iw_mode == IW_MODE_MASTER && !local->host_encrypt &&
 		 !local->fw_encrypt_ok) {
 		printk(KERN_DEBUG "%s: defaulting to host-based encryption as "
@@ -1392,16 +1407,14 @@
 			local->manual_retry_count = -1;
 			local->tx_control &= ~HFA384X_TX_CTRL_ALT_RTRY;
 		} else {
-			if (hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
-					    rrq->value)) {
-				printk(KERN_DEBUG "%s: Alternate retry count "
-				       "setting to %d failed\n",
-				       dev->name, rrq->value);
+			local->manual_retry_count = rrq->value;
+			local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY;
+
+			if (prism2_set_retry_from_local(dev)) {
+				local->manual_retry_count = -1;
 				return -EOPNOTSUPP;
 			}

-			local->manual_retry_count = rrq->value;
-			local->tx_control |= HFA384X_TX_CTRL_ALT_RTRY;
 		}
 		return 0;
 	}
@@ -1498,6 +1511,8 @@
  * increasing dBm value should correspond to increasing TX power.
  */

+
+#ifdef PRISM2_DBM_CONVERSION
 static int prism2_txpower_hfa386x_to_dBm(u16 val)
 {
 	signed char tmp;
@@ -1526,6 +1541,8 @@

 	return (unsigned char) tmp;
 }
+#endif /* PRISM2_DBM_CONVERSION */
+
 #endif /* RAW_TXPOWER_SETTING */


@@ -1565,24 +1582,15 @@
 		       dev->name, ret ? "failed" : "OK");
 		local->txpower_type = PRISM2_TXPOWER_UNKNOWN;
 	}
-
 #ifdef RAW_TXPOWER_SETTING
-	if (!rrq->fixed && local->txpower_type != PRISM2_TXPOWER_AUTO) {
-		printk(KERN_DEBUG "Setting ALC on\n");
-		val = HFA384X_TEST_CFG_BIT_ALC;
-		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
-				 (HFA384X_TEST_CFG_BITS << 8), 1, &val, NULL);
-		local->txpower_type = PRISM2_TXPOWER_AUTO;
-		return 0;
-	}

-	if (local->txpower_type != PRISM2_TXPOWER_FIXED) {
-		printk(KERN_DEBUG "Setting ALC off\n");
-		val = HFA384X_TEST_CFG_BIT_ALC;
-		local->func->cmd(dev, HFA384X_CMDCODE_TEST |
-				 (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
-			local->txpower_type = PRISM2_TXPOWER_FIXED;
-	}
+// PATCH: Removed buggy/overengineered functions for setting txpower
+// they relied on local variables and hardware being in sync, which was
+// seldom true
+
+	local->txpower_type = rrq->fixed?
+		PRISM2_TXPOWER_FIXED:PRISM2_TXPOWER_AUTO;
+

 	if (rrq->flags == IW_TXPOW_DBM)
 		tmp = "dBm";
@@ -1590,23 +1598,40 @@
 		tmp = "mW";
 	else
 		tmp = "UNKNOWN";
-	printk(KERN_DEBUG "Setting TX power to %d %s\n", rrq->value, tmp);

 	if (rrq->flags != IW_TXPOW_DBM) {
 		printk("SIOCSIWTXPOW with mW is not supported; use dBm\n");
 		return -EOPNOTSUPP;
 	}
-
+// PATCH: crappy dBm concersion may be turned on/off
+#ifdef PRISM2_DBM_CONVERSION
+	local->txpower = prism2_txpower_dBm_to_hfa386x(rrq->value);
+#else
 	local->txpower = rrq->value;
-	val = prism2_txpower_dBm_to_hfa386x(local->txpower);
-	if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
-			     HFA386X_CR_MANUAL_TX_POWER, &val, NULL))
-		ret = -EOPNOTSUPP;
+#endif
+// PATCH: Use global function instead of setting locally
+
+	/* in client mode, setting power has no efect without reset */
+	if (local->iw_mode == IW_MODE_MASTER)
+		ret = prism2_set_power_from_local(dev);
+	else {
+#ifdef PRISM2_RESTORE_POWER
+		/* Disable and enable card */
+		local->func->hw_shutdown(dev, 1);
+		local->func->hw_config(dev, 0);
+		ret=0;
+		/* calls prism2_set_power_from_local() */
+#else
+		/* if a reset wouldn't set the txpower, do the original,
+		 even tho' it does not work well... */
+		ret = prism2_set_power_from_local(dev);
+#endif
+	}
+
 #else /* RAW_TXPOWER_SETTING */
 	if (rrq->fixed)
 		ret = -EOPNOTSUPP;
 #endif /* RAW_TXPOWER_SETTING */
-
 	return ret;
 }

@@ -1626,25 +1651,24 @@
 	rrq->disabled = 0;
 	rrq->fixed = 0;

-	if (local->txpower_type == PRISM2_TXPOWER_AUTO) {
-		if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF,
-				     HFA386X_CR_MANUAL_TX_POWER,
-				     NULL, &resp0) == 0) {
-			rrq->value = prism2_txpower_hfa386x_to_dBm(resp0);
-		} else {
-			/* Could not get real txpower; guess 15 dBm */
-			rrq->value = 15;
-		}
-	} else if (local->txpower_type == PRISM2_TXPOWER_OFF) {
-		rrq->value = 0;
-		rrq->disabled = 1;
-	} else if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
-		rrq->value = local->txpower;
-		rrq->fixed = 1;
+// PATCH: read the real values from HW, don't return contents of local
+// vars
+	if (local->func->cmd(dev, HFA384X_CMDCODE_READMIF,
+			     HFA386X_CR_MANUAL_TX_POWER,
+			     NULL, &resp0) == 0) {
+
+// PATCH: crappy dBm concersion may be turned on/off
+#ifdef PRISM2_DBM_CONVERSION
+		rrq->value = prism2_txpower_hfa386x_to_dBm(resp0);
+#else
+		rrq->value = resp0;
+#endif
+
 	} else {
-		printk("SIOCGIWTXPOW - unknown txpower_type=%d\n",
-		       local->txpower_type);
+		/* Could not get real txpower; guess 0 dBm */
+		rrq->value = 0;
 	}
+
 	return 0;
 #else /* RAW_TXPOWER_SETTING */
 	return -EOPNOTSUPP;
@@ -1736,7 +1760,6 @@
 	return -EOPNOTSUPP;
 }

-
 static inline int prism2_request_scan(struct net_device *dev)
 {
 	return -EOPNOTSUPP;
@@ -2132,6 +2155,8 @@
 static const struct iw_priv_args prism2_priv[] = {
 	{ PRISM2_IOCTL_MONITOR,
 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor" },
+	{ PRISM2_IOCTL_DSSSTEST,
+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dssstest" },
 	{ PRISM2_IOCTL_READMIF,
 	  IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
 	  IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "readmif" },
@@ -2959,6 +2984,32 @@
 }


+static int prism2_ioctl_priv_dssstest(struct net_device *dev, int *i)
+{
+	struct hostap_interface *iface;
+	local_info_t *local;
+	int ret = 0;
+	u32 mode;
+
+	iface = netdev_priv(dev);
+	local = iface->local;
+
+	if (*i == 0) {
+		/* Disable dssstest mode - old mode was not saved, so go to
+		 * Monitor mode */
+		mode = IW_MODE_MONITOR;
+		ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
+	} else if (*i == 1 && local->iw_mode == IW_MODE_MONITOR) {
+		mode = IW_MODE_DSSSTEST;
+		ret = prism2_ioctl_siwmode(dev, NULL, &mode, NULL);
+		hostap_dssstest_mode_enable(local);
+	} else
+		ret = -EINVAL;
+
+	return ret;
+}
+
+
 static int prism2_ioctl_priv_reset(struct net_device *dev, int *i)
 {
 	struct hostap_interface *iface;
@@ -4019,6 +4070,11 @@
 		else ret = prism2_ioctl_priv_monitor(dev, (int *) wrq->u.name);
 		break;

+	case PRISM2_IOCTL_DSSSTEST:
+		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
+		else ret = prism2_ioctl_priv_dssstest(dev, (int *) wrq->u.name);
+		break;
+
 	case PRISM2_IOCTL_RESET:
 		if (!capable(CAP_NET_ADMIN)) ret = -EPERM;
 		else ret = prism2_ioctl_priv_reset(dev, (int *) wrq->u.name);
@@ -4086,3 +4142,5 @@

 	return ret;
 }
+
+EXPORT_SYMBOL(prism2_set_rate_from_local);
diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_main.c linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_main.c
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_main.c	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_main.c	2007-04-01 03:27:43.000000000 +0200
@@ -332,7 +332,7 @@
 	if (local->iw_mode == IW_MODE_REPEAT)
 		return HFA384X_PORTTYPE_WDS;
 	if (local->iw_mode == IW_MODE_MONITOR)
-		return HFA384X_PORTTYPE_PSEUDO_IBSS;
+		return 5; /*HFA384X_PORTTYPE_PSEUDO_IBSS;*/
 	return HFA384X_PORTTYPE_HOSTAP;
 }

@@ -1090,6 +1090,69 @@
 }


+// PATCH: Global set txpower function
+
+int prism2_set_power_from_local(struct net_device *dev)
+{
+	int alc;
+	u16 val;
+        struct hostap_interface *iface = dev->priv;
+	local_info_t *local = iface->local;
+
+	/* set the ALC */
+	alc = local->txpower_type != PRISM2_TXPOWER_FIXED;
+	printk(KERN_DEBUG "%s: Setting ALC to %d\n", dev->name, alc);
+
+	val = HFA384X_TEST_CFG_BIT_ALC;
+	local->func->cmd(dev, HFA384X_CMDCODE_TEST |
+			 (HFA384X_TEST_CFG_BITS << 8), alc, &val, NULL);
+
+	/* if ALC is on, don't set the power */
+	if (alc) return 0;
+
+	/* set the txpower */
+	val = local->txpower;
+	printk(KERN_DEBUG "%s: Setting TX power to %d \n", dev->name, val);
+	if (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
+			     HFA386X_CR_MANUAL_TX_POWER, &val, NULL))
+		return  -EOPNOTSUPP;
+	else return 0;
+}
+
+// PATCH: Global set sensitivity function
+
+int prism2_set_sens_from_local(struct net_device *dev)
+{
+	struct hostap_interface *iface = dev->priv;
+	local_info_t *local = iface->local;
+
+	if (hostap_set_word(dev, HFA384X_RID_CNFSYSTEMSCALE, local->sensitivity)
+			|| local->func->reset_port(dev))
+		return -EINVAL;
+
+	printk(KERN_DEBUG "%s: sensitivity set to %d\n", dev->name, local->sensitivity);
+
+	return 0;
+}
+
+
+// PATCH: Global set retry function
+int prism2_set_retry_from_local(struct net_device *dev)
+{
+	int ret=0;
+	struct hostap_interface *iface = dev->priv;
+	local_info_t *local = iface->local;
+	ret = hostap_set_word(dev, HFA384X_RID_CNFALTRETRYCOUNT,
+			local->manual_retry_count);
+	if (ret)
+		printk(KERN_DEBUG "%s: Alternate retry count "
+		"setting to %d failed\n", dev->name, local->manual_retry_count);
+	else
+		printk(KERN_DEBUG "%s: Alternate retry count "
+			"set to %d\n", dev->name, local->manual_retry_count);
+	return ret;
+}
+
 struct proc_dir_entry *hostap_proc;

 static int __init hostap_init(void)
@@ -1137,5 +1200,9 @@
 EXPORT_SYMBOL(hostap_remove_interface);
 EXPORT_SYMBOL(prism2_update_comms_qual);

+EXPORT_SYMBOL(prism2_set_power_from_local);
+EXPORT_SYMBOL(prism2_set_sens_from_local);
+EXPORT_SYMBOL(prism2_set_retry_from_local);
+
 module_init(hostap_init);
 module_exit(hostap_exit);
diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_plx.c linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_plx.c
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_plx.c	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_plx.c	2007-04-01 03:27:43.000000000 +0200
@@ -100,6 +100,7 @@
 	{ 0xc250, 0x0002 } /* EMTAC A2424i */,
 	{ 0xd601, 0x0002 } /* Z-Com XI300 */,
 	{ 0xd601, 0x0005 } /* Zcomax XI-325H 200mW */,
+	{ 0xd601, 0x0010 } /* Zcomax XI-325H 100mW */,
 	{ 0, 0}
 };

diff -Naur linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_wlan.h linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_wlan.h
--- linux-source-2.6.17-orig/drivers/net/wireless/hostap/hostap_wlan.h	2006-10-01 18:42:46.000000000 +0200
+++ linux-source-2.6.17-rawtx/drivers/net/wireless/hostap/hostap_wlan.h	2007-04-01 03:42:22.000000000 +0200
@@ -13,6 +13,7 @@
 #define DEF_INTS -1, -1, -1, -1, -1, -1, -1
 #define GET_INT_PARM(var,idx) var[var[idx] < 0 ? 0 : idx]

+#define IW_MODE_DSSSTEST 7

 /* Specific skb->protocol value that indicates that the packet already contains
  * txdesc header.
@@ -575,6 +576,8 @@
 	int (*hw_config)(struct net_device *dev, int initial);
 	void (*hw_reset)(struct net_device *dev);
 	void (*hw_shutdown)(struct net_device *dev, int no_disable);
+	int (*monitor_enable)(struct net_device *dev);
+	int (*dssstest_enable)(struct net_device *dev);
 	int (*reset_port)(struct net_device *dev);
 	void (*schedule_reset)(local_info_t *local);
 	int (*download)(local_info_t *local,
@@ -698,6 +701,9 @@
 		PRISM2_TXPOWER_FIXED, PRISM2_TXPOWER_UNKNOWN
 	} txpower_type;
 	int txpower; /* if txpower_type == PRISM2_TXPOWER_FIXED */
+	int sensitivity;
+	int client_post_assoc_setup;
+

 	/* command queue for hfa384x_cmd(); protected with cmdlock */
 	struct list_head cmd_queue;