PERFORCE change 138932 for review

Sam Leffler sam at FreeBSD.org
Sat Mar 29 15:34:02 PDT 2008


http://perforce.freebsd.org/chv.cgi?CH=138932

Change 138932 by sam at sam_ebb on 2008/03/29 22:33:43

	Checkpoint work:
	o split newstate method per opmode
	o fix ap mode
	o add wpa
	o add "enhanced security" (hidessid)
	o do all crypto on the host for now
	o include function name in diagnostic msgs

Affected files ...

.. //depot/projects/vap/sys/dev/wi/if_wavelan_ieee.h#5 edit
.. //depot/projects/vap/sys/dev/wi/if_wi.c#18 edit
.. //depot/projects/vap/sys/dev/wi/if_wivar.h#13 edit

Differences ...

==== //depot/projects/vap/sys/dev/wi/if_wavelan_ieee.h#5 (text+ko) ====

@@ -241,10 +241,13 @@
 #define WI_RID_CNFAUTHMODE	0xFC2A
 #define WI_RID_ROAMING_MODE	0xFC2D
 #define WI_RID_OWN_BEACON_INT	0xFC33 /* beacon xmit time for BSS creation */
+#define	WI_RID_ENH_SECURITY	0xFC43 /* enhanced security (AP mode) */
 #define WI_RID_CNF_DBM_ADJUST	0xFC46
 #define WI_RID_DBM_ADJUST	0xFC46 /* RSSI - WI_RID_DBM_ADJUST ~ dBm */
+#define	WI_RID_WPA_DATA		0xFC48 /* WPA IE */
 #define WI_RID_BASIC_RATE	0xFCB3
 #define WI_RID_SUPPORT_RATE	0xFCB4
+#define	WI_RID_WPA_HANDLING	0xFCBB /* WPA handling procedures */
 
 /*
  * Network parameters, dynamic configuration entities

==== //depot/projects/vap/sys/dev/wi/if_wi.c#18 (text+ko) ====

@@ -121,6 +121,8 @@
 		struct mbuf *m0);
 static int  wi_raw_xmit(struct ieee80211_node *, struct mbuf *,
 		const struct ieee80211_bpf_params *);
+static int  wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int);
+static int  wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state, int);
 static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
 		int subtype, int rssi, int noise, u_int32_t rstamp);
 static int  wi_reset(struct wi_softc *);
@@ -152,8 +154,6 @@
 static int  wi_read_rid(struct wi_softc *, int, void *, int *);
 static int  wi_write_rid(struct wi_softc *, int, void *, int);
 
-static int  wi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-
 static void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi);
 
 static void wi_scan_start(struct ieee80211com *);
@@ -394,6 +394,15 @@
 		 * monitor mode so this is irrelevant.
 		 */
 		ic->ic_caps |= IEEE80211_C_HOSTAP;
+		if (sc->sc_sta_firmware_ver >= 10603)
+			sc->sc_flags |= WI_FLAGS_HAS_ENHSECURITY;
+		if (sc->sc_sta_firmware_ver >= 10700) {
+			/*
+			 * 1.7.0+ have the necessary support for sta mode WPA.
+			 */
+			sc->sc_flags |= WI_FLAGS_HAS_WPASUPPORT;
+			ic->ic_caps |= IEEE80211_C_WPA;
+		}
 
 		sc->sc_ibss_port = WI_PORTTYPE_IBSS;
 		sc->sc_monitor_port = WI_PORTTYPE_APSILENT;
@@ -515,10 +524,6 @@
 	vap = &wvp->wv_vap;
 	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
 
-	wvp->wv_recv_mgmt = vap->iv_recv_mgmt;
-	vap->iv_recv_mgmt = wi_recv_mgmt;
-	wvp->wv_newstate = vap->iv_newstate;
-	vap->iv_newstate = wi_newstate;
 	wvp->wv_key_alloc = vap->iv_key_alloc;
 	vap->iv_key_alloc = wi_key_alloc;
 	vap->iv_max_aid = WI_MAX_AID;
@@ -526,15 +531,24 @@
 	switch (opmode) {
 	case IEEE80211_M_STA:
 		sc->sc_porttype = WI_PORTTYPE_BSS;
+		wvp->wv_newstate = vap->iv_newstate;
+		vap->iv_newstate = wi_newstate_sta;
+		/* need to filter mgt frames to avoid confusing state machine */
+		wvp->wv_recv_mgmt = vap->iv_recv_mgmt;
+		vap->iv_recv_mgmt = wi_recv_mgmt;
 		break;
 	case IEEE80211_M_IBSS:
 		sc->sc_porttype = sc->sc_ibss_port;
+		wvp->wv_newstate = vap->iv_newstate;
+		vap->iv_newstate = wi_newstate_sta;
 		break;
 	case IEEE80211_M_AHDEMO:
 		sc->sc_porttype = WI_PORTTYPE_ADHOC;
 		break;
 	case IEEE80211_M_HOSTAP:
 		sc->sc_porttype = WI_PORTTYPE_HOSTAP;
+		wvp->wv_newstate = vap->iv_newstate;
+		vap->iv_newstate = wi_newstate_hostap;
 		break;
 	case IEEE80211_M_MONITOR:
 		sc->sc_porttype = sc->sc_monitor_port;
@@ -799,13 +813,12 @@
 }
 
 static int
-wi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+wi_newstate_sta(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 {
 	struct ieee80211com *ic = vap->iv_ic;
 	struct ifnet *ifp = ic->ic_ifp;
 	struct ieee80211_node *bss;
 	struct wi_softc *sc = ifp->if_softc;
-	int error;
 
 	DPRINTF(("%s: %s -> %s\n", __func__,
 		ieee80211_state_name[vap->iv_state],
@@ -836,6 +849,17 @@
 		else
 			sc->sc_encryption = 0;
 
+		if ((sc->sc_flags & WI_FLAGS_HAS_WPASUPPORT) &&
+		    (vap->iv_flags & IEEE80211_F_WPA)) {
+			wi_write_val(sc, WI_RID_WPA_HANDLING, 1);
+			if (vap->iv_appie_wpa != NULL) {
+printf("%s: wpa ie %p %d\n", __func__, vap->iv_appie_wpa->ie_data, vap->iv_appie_wpa->ie_len); 
+				wi_write_rid(sc, WI_RID_WPA_DATA,
+				    vap->iv_appie_wpa->ie_data, 
+				    vap->iv_appie_wpa->ie_len); 
+			}
+		}
+
 		wi_enable(sc);		/* enable port */
 
 		/* Lucent firmware does not support the JOIN RID. */
@@ -850,57 +874,73 @@
 		}
 		WI_UNLOCK(sc);
 
-		/* NB: don't go through 802.11 layer, it'll send auth frame */
+		/*
+		 * NB: don't go through 802.11 layer, it'll send auth frame;
+		 * instead we drive the state machine from the link status
+		 * notification we get on association.
+		 */
 		vap->iv_state = nstate;
 		return EINPROGRESS;
 	}
+	return WI_VAP(vap)->wv_newstate(vap, nstate, arg);
+}
+
+static int
+wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
+{
+	struct ieee80211com *ic = vap->iv_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct ieee80211_node *bss;
+	struct wi_softc *sc = ifp->if_softc;
+	int error;
+
+	DPRINTF(("%s: %s -> %s\n", __func__,
+		ieee80211_state_name[vap->iv_state],
+		ieee80211_state_name[nstate]));
 
 	error = WI_VAP(vap)->wv_newstate(vap, nstate, arg);
+	if (error == 0 && nstate == IEEE80211_S_RUN) {
+		WI_LOCK(sc);
+		wi_init_locked(sc, WI_PORTTYPE_HOSTAP, 0, vap->iv_myaddr);
 
-	if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
-		WI_LOCK(sc);
-		if (vap->iv_opmode == IEEE80211_M_MONITOR)
-			wi_cmd(sc, WI_CMD_DEBUG | (WI_TEST_MONITOR << 8), 0, 0, 0);
-		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-			wi_init_locked(sc, WI_PORTTYPE_HOSTAP, 0, vap->iv_myaddr);
+		bss = vap->iv_bss;
+		wi_write_ssid(sc, WI_RID_OWN_SSID,
+		    bss->ni_essid, bss->ni_esslen);
+		wi_write_val(sc, WI_RID_OWN_CHNL,
+		    ieee80211_chan2ieee(ic, bss->ni_chan));
+		wi_write_val(sc, WI_RID_BASIC_RATE, 0x3);
+		wi_write_val(sc, WI_RID_SUPPORT_RATE, 0xf);
+		wi_write_txrate(sc, vap);
 
-			bss = vap->iv_bss;
-			wi_write_ssid(sc, WI_RID_OWN_SSID,
-			    bss->ni_essid, bss->ni_esslen);
-			wi_write_val(sc, WI_RID_OWN_CHNL,
-			    ieee80211_chan2ieee(ic, bss->ni_chan));
-			wi_write_val(sc, WI_RID_BASIC_RATE, 0x3);
-			wi_write_val(sc, WI_RID_SUPPORT_RATE, 0xf);
-			wi_write_txrate(sc, vap);
+		wi_write_val(sc, WI_RID_OWN_BEACON_INT, bss->ni_intval);
+		wi_write_val(sc, WI_RID_DTIM_PERIOD, vap->iv_dtim_period);
 
-			wi_write_val(sc, WI_RID_OWN_BEACON_INT, bss->ni_intval);
-			wi_write_val(sc, WI_RID_DTIM_PERIOD, vap->iv_dtim_period);
+		wi_write_val(sc, WI_RID_RTS_THRESH, vap->iv_rtsthreshold);
+		if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
+			wi_write_val(sc, WI_RID_FRAG_THRESH,
+			    vap->iv_fragthreshold);
 
-			wi_write_val(sc, WI_RID_RTS_THRESH, vap->iv_rtsthreshold);
-			if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
-				wi_write_val(sc, WI_RID_FRAG_THRESH,
-				    vap->iv_fragthreshold);
+		if ((sc->sc_flags & WI_FLAGS_HAS_ENHSECURITY) &&
+		    (vap->iv_flags & IEEE80211_F_HIDESSID)) {
+			/*
+			 * bit 0 means hide SSID in beacons,
+			 * bit 1 means don't respond to bcast probe req
+			 */
+			wi_write_val(sc, WI_RID_ENH_SECURITY, 0x3);
+		}
 
-			wi_write_val(sc, WI_RID_PROMISC, 0);
+		wi_write_val(sc, WI_RID_PROMISC, 0);
 
-			/* Configure WEP. */
-			if (ic->ic_caps & IEEE80211_C_WEP)
-				wi_write_wep(sc, vap);
-			else
-				sc->sc_encryption = 0;
+		/* Configure WEP. */
+		if (ic->ic_caps & IEEE80211_C_WEP)
+			wi_write_wep(sc, vap);
+		else
+			sc->sc_encryption = 0;
 
-			wi_enable(sc);		/* enable port */
-#if 0
-			if (sc->sc_firmware_type == WI_INTERSIL) {
-				wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
-				wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
-			}
-#endif
-		}
+		wi_enable(sc);		/* enable port */
 		WI_UNLOCK(sc);
-		return WI_VAP(vap)->wv_newstate(vap, nstate, arg);
 	}
-	return 0;
+	return error;
 }
 
 static void
@@ -1767,6 +1807,7 @@
 		break;
 
 	case WI_INTERSIL:
+		val = HOST_ENCRYPT | HOST_DECRYPT;
 		if (vap->iv_flags & IEEE80211_F_PRIVACY) {
 			/*
 			 * ONLY HWB3163 EVAL-CARD Firmware version
@@ -1783,17 +1824,9 @@
 			}
 			wi_write_val(sc, WI_RID_CNFAUTHMODE,
 			    vap->iv_bss->ni_authmode);
-			/* XXX should honor IEEE80211_F_DROPUNENC */
-			val = PRIVACY_INVOKED | EXCLUDE_UNENCRYPTED;
-			/*
-			 * Encryption firmware has a bug for HostAP mode.
-			 */
-			if (vap->iv_opmode == IEEE80211_M_HOSTAP)
-				val |= HOST_ENCRYPT;
+			val |= PRIVACY_INVOKED;
 		} else {
-			wi_write_val(sc, WI_RID_CNFAUTHMODE,
-			    IEEE80211_AUTH_OPEN);
-			val = HOST_ENCRYPT | HOST_DECRYPT;
+			wi_write_val(sc, WI_RID_CNFAUTHMODE, IEEE80211_AUTH_OPEN);
 		}
 		error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val);
 		if (error)
@@ -1860,7 +1893,8 @@
 		DELAY(1*1000);	/* 1ms */
 	}
 	if (i == 0) {
-		device_printf(sc->sc_dev, "wi_cmd: busy bit won't clear.\n" );
+		device_printf(sc->sc_dev, "%s: busy bit won't clear, cmd 0x%x\n",
+		   __func__, cmd);
 		sc->wi_gone = 1;
 		return(ETIMEDOUT);
 	}
@@ -1893,8 +1927,8 @@
 	}
 
 	if (i == WI_TIMEOUT) {
-		device_printf(sc->sc_dev,
-		    "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s);
+		device_printf(sc->sc_dev, "%s: timeout on cmd 0x%04x; "
+		    "event status 0x%04x\n", __func__, cmd, s);
 		if (s == 0xffff)
 			sc->wi_gone = 1;
 		return(ETIMEDOUT);
@@ -1915,8 +1949,8 @@
 		if ((status & WI_OFF_BUSY) == 0)
 			break;
 		if (i == WI_TIMEOUT) {
-			device_printf(sc->sc_dev, "timeout in wi_seek to %x/%x\n",
-			    id, off);
+			device_printf(sc->sc_dev, "%s: timeout, id %x off %x\n",
+			    __func__, id, off);
 			sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
 			if (status == 0xffff)
 				sc->wi_gone = 1;
@@ -1925,7 +1959,8 @@
 		DELAY(1);
 	}
 	if (status & WI_OFF_ERR) {
-		device_printf(sc->sc_dev, "failed in wi_seek to %x/%x\n", id, off);
+		device_printf(sc->sc_dev, "%s: error, id %x off %x\n",
+		    __func__, id, off);
 		sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
 		return EIO;
 	}
@@ -2009,8 +2044,8 @@
 	int i;
 
 	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
-		device_printf(sc->sc_dev, "failed to allocate %d bytes on NIC\n",
-		    len);
+		device_printf(sc->sc_dev, "%s: failed to allocate %d bytes on NIC\n",
+		    __func__, len);
 		return ENOMEM;
 	}
 
@@ -2020,7 +2055,7 @@
 		DELAY(1);
 	}
 	if (i == WI_TIMEOUT) {
-		device_printf(sc->sc_dev, "timeout in alloc\n");
+		device_printf(sc->sc_dev, "%s: timeout in alloc\n", __func__);
 		return ETIMEDOUT;
 	}
 	*idp = CSR_READ_2(sc, WI_ALLOC_FID);
@@ -2069,11 +2104,17 @@
 	ltbuf[1] = htole16(rid);
 
 	error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
-	if (error)
+	if (error) {
+		device_printf(sc->sc_dev, "%s: bap0 write failure, rid 0x%x\n",
+		    __func__, rid);
 		return error;
+	}
 	error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen);
-	if (error)
+	if (error) {
+		device_printf(sc->sc_dev, "%s: bap1 write failure, rid 0x%x\n",
+		    __func__, rid);
 		return error;
+	}
 
 	return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0);
 }

==== //depot/projects/vap/sys/dev/wi/if_wivar.h#13 (text+ko) ====

@@ -151,6 +151,8 @@
 /* maximum consecutive false change-of-BSSID indications */
 #define	WI_MAX_FALSE_SYNS		10	
 
+#define	WI_FLAGS_HAS_ENHSECURITY	0x0001
+#define	WI_FLAGS_HAS_WPASUPPORT		0x0002
 #define	WI_FLAGS_HAS_ROAMING		0x0020
 #define	WI_FLAGS_HAS_FRAGTHR		0x0200
 #define	WI_FLAGS_HAS_DBMADJUST		0x0400


More information about the p4-projects mailing list