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