Date: Sat, 29 Mar 2008 22:34:01 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 138932 for review Message-ID: <200803292234.m2TMY1BL092499@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=138932 Change 138932 by sam@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803292234.m2TMY1BL092499>