Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 May 1999 16:59:25 -0400
From:      Brad Karp <karp@eecs.harvard.edu>
To:        freebsd-mobile@freebsd.org
Cc:        wpaul@ctr.columbia.edu
Subject:   if_wi Lucent WaveLAN driver: patches and power management
Message-ID:  <199905062059.QAA32433@dominator.eecs.harvard.edu>

next in thread | raw e-mail | index | archive | help
For anyone who's interested: Bill Paul's WaveLAN 802.11 PC-Card driver,
if_wi, was committed before I announced my own driver for this hardware. His
driver is not a port of the Linux driver, and so is not GPL'ed, and is less
gross, not having started from the nasty Lucent/Linux codebase.

I found a couple byte-order bugs in the if_wi driver, that caused coredumps
in the user-level configuration program wicontrol, and also resulted in
configuration information being improperly written to the card. I submitted
patches for these, and Bill's committed them to -current.

After those patches, I've verified that this driver works great with
WavePoint II base stations. (Bill had asked me to verify this, since I have
a base station and he does not.)

I'm still in denial over having produced my driver for naught, so in the
effort to contribute some shred, here's an enhancement to Bill's driver you
might all want: power management support!

In short: the WaveLAN PC-Card supports a protocol of alternating sleep/wake,
in the interest of saving power, at the expense of some increased receive
latency. To use this, you *must* use the card with a base station (the
protocol requires the base station's cooperation, and doesn't work in ad-hoc
mode), and you need WavePoint firmware 2.03 or newer, and WaveLAN PC-Card
firmware 2.00 or newer. (Lower revs, and the WaveLAN card will silently ignore
your request to do power management.)

Below are patches to add support for power management to Bill's driver. It
defaults to off; change it to on with "wicontrol -i wi0 -P 1".
You can also change the sleep interval. Longer means more power saving, but
worse worst-case receive latency. Shorter, vice-versa. The sleep interval
can be changed with "wicontrol -i wi0 -S <i>" (where i is an integer
number of milliseconds; 100 ms is the default).

Enjoy,
-Brad, karp@eecs.harvard.edu

--- wi.orig/usr/sbin/wicontrol/wicontrol.c	Wed May  5 11:13:18 1999
+++ wi/usr/sbin/wicontrol/wicontrol.c	Thu May  6 16:42:40 1999
@@ -308,6 +308,8 @@
 	{ WI_RID_RTS_THRESH, WI_WORDS, "RTS/CTS handshake threshold:\t\t"},
 	{ WI_RID_CREATE_IBSS, WI_BOOL, "Create IBSS:\t\t\t\t" },
 	{ WI_RID_SYSTEM_SCALE, WI_WORDS, "Access point density:\t\t\t" },
+	{ WI_RID_PM_ENABLED, WI_WORDS, "Power Mgmt (1=on, 0=off):\t\t" },
+	{ WI_RID_MAX_SLEEP, WI_WORDS, "Max sleep time:\t\t\t\t" },
 	{ 0, NULL }
 };
 
@@ -426,6 +428,8 @@
 	fprintf(stderr, "\t%s -i iface -m mac address\n", p);
 	fprintf(stderr, "\t%s -i iface -d max data length\n", p);
 	fprintf(stderr, "\t%s -i iface -r RTS threshold\n", p);
+	fprintf(stderr, "\t%s -i iface -P power mgmt\n", p);
+	fprintf(stderr, "\t%s -i iface -S max sleep duration\n", p);
 
 	exit(1);
 }
@@ -438,7 +442,7 @@
 	char			*iface = NULL;
 	char			*p = argv[0];
 
-	while((ch = getopt(argc, argv, "hoc:d:i:p:r:q:t:n:s:m:")) != -1) {
+	while((ch = getopt(argc, argv, "hoc:d:i:p:r:q:t:n:s:m:P:S:")) != -1) {
 		switch(ch) {
 		case 'o':
 			wi_dumpstats(iface);
@@ -481,6 +485,14 @@
 			break;
 		case 'q':
 			wi_setstr(iface, WI_RID_OWN_SSID, optarg);
+			exit(0);
+			break;
+		case 'S':
+		        wi_setword(iface, WI_RID_MAX_SLEEP, atoi(optarg));
+			exit(0);
+			break;
+		case 'P':
+		        wi_setword(iface, WI_RID_PM_ENABLED, atoi(optarg));
 			exit(0);
 			break;
 		case 'h':
--- wi.orig/sys/i386/isa/if_wi.c	Wed May  5 11:12:16 1999
+++ /sys/i386/isa/if_wi.c	Thu May  6 16:47:07 1999
@@ -323,12 +323,14 @@
 	    sizeof(WI_DEFAULT_IBSS) - 1);
 
 	sc->wi_portnum = WI_DEFAULT_PORT;
	sc->wi_ptype = WI_PORTTYPE_ADHOC;
 	sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
 	sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
 	sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
 	sc->wi_max_data_len = WI_DEFAULT_DATALEN;
 	sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
+	sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
+	sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
 
 	bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
 
@@ -953,6 +955,12 @@
 		bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
 		bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
 		break;
+	case WI_RID_PM_ENABLED:
+	        sc->wi_pm_enabled = wreq->wi_val[0];
+		break;
+	case WI_RID_MAX_SLEEP:
+	        sc->wi_max_sleep = wreq->wi_val[0];
+		break;
 	default:
 		break;
 	}
@@ -1087,6 +1095,12 @@
 
 	/* Access point density */
 	WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
+
+	/* Power Management Enabled */
+	WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
+
+	/* Power Management Max Sleep */
+	WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
 
 	/* Specify the IBSS name */
 	WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
--- wi.orig/sys/i386/isa/if_wireg.h	Wed May  5 11:12:21 1999
+++ /sys/i386/isa/if_wireg.h	Thu May  6 16:46:34 1999
@@ -73,6 +73,8 @@
 	u_int16_t		wi_ap_density;
 	u_int16_t		wi_tx_rate;
 	u_int16_t		wi_create_ibss;
+        u_int16_t               wi_pm_enabled;
+        u_int16_t               wi_max_sleep;
 	char			wi_node_name[32];
 	char			wi_net_name[32];
 	char			wi_ibss_name[32];
@@ -111,6 +113,10 @@
 
 #define WI_DEFAULT_IBSS		"FreeBSD IBSS"
 
+#define WI_DEFAULT_PM_ENABLED   0
+
+#define WI_DEFAULT_MAX_SLEEP    100
+
 /*
  * register space access macros
  */
@@ -461,7 +467,17 @@
 /*
  * Frame data size.
  */
#define WI_RID_MAX_DATALEN		0xFC07
+
+/*
+ * ESS power management enable
+ */
+#define WI_RID_PM_ENABLED       0xFC09
+
+/*
+ * ESS max PM sleep interval
+ */
+#define WI_RID_MAX_SLEEP        0xFC0C
 
 /*
  * Set our station name.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199905062059.QAA32433>