Date: Mon, 1 Jan 2007 23:42:42 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 112405 for review Message-ID: <200701012342.l01Nggu3031208@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=112405 Change 112405 by kmacy@kmacy_serendipity:sam_wifi on 2007/01/01 23:42:28 - add in basic scanning hooks so that we don't blow up if wlan_scan_sta is loaded - add ioctl's to bypass net80211 to fetch the scanning results for ifconfig - scanning now appears to work Affected files ... .. //depot/projects/wifi/sys/dev/wi/if_wi.c#24 edit Differences ... ==== //depot/projects/wifi/sys/dev/wi/if_wi.c#24 (text+ko) ==== @@ -118,7 +118,7 @@ struct mbuf *m0); static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static int wi_reset(struct wi_softc *); +static int wi_reset(struct ifnet *); static void wi_watchdog(void *); static int wi_ioctl(struct ifnet *, u_long, caddr_t); static int wi_media_change(struct ifnet *); @@ -164,6 +164,14 @@ const void *, int); static int wi_symbol_set_hcr(struct wi_softc *, int); +static void wi_scan_start(struct ieee80211com *); +static void wi_scan_end(struct ieee80211com *); +static void wi_set_channel(struct ieee80211com *); +static void wi_update_slot(struct ifnet *); +static struct ieee80211_node *wi_node_alloc(struct ieee80211_node_table *); +static int wi_ioctl_get(struct ifnet *ifp, u_long command, caddr_t data); +static int wi_ioctl_set(struct ifnet *ifp, u_long command, caddr_t data); + static __inline int wi_write_val(struct wi_softc *sc, int rid, u_int16_t val) { @@ -253,6 +261,7 @@ int error; ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp->if_softc = sc; if (ifp == NULL) { device_printf(dev, "can not if_alloc\n"); wi_free(dev); @@ -279,7 +288,7 @@ sc->sc_firmware_type = WI_NOTYPE; sc->wi_cmd_count = 500; /* Reset the NIC. */ - if (wi_reset(sc) != 0) + if (wi_reset(ifp) != 0) return ENXIO; /* XXX */ /* @@ -308,7 +317,6 @@ /* Read NIC identification */ wi_read_nicid(sc); - ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = wi_ioctl; @@ -494,6 +502,14 @@ ic->ic_crypto.cs_key_alloc = wi_key_alloc; ic->ic_newstate = wi_newstate; ic->ic_raw_xmit = wi_raw_xmit; + + ic->ic_scan_start = wi_scan_start; + ic->ic_scan_end = wi_scan_end; + ic->ic_set_channel = wi_set_channel; + ic->ic_node_alloc = wi_node_alloc; + ic->ic_updateslot = wi_update_slot; + ic->ic_reset = wi_reset; + ieee80211_media_init(ic, wi_media_change, wi_media_status); #if NBPFILTER > 0 @@ -665,7 +681,7 @@ if ((wasenabled = sc->sc_enabled)) wi_stop(ifp, 1); - wi_reset(sc); + wi_reset(ifp); /* common 802.11 configuration */ ic->ic_flags &= ~IEEE80211_F_IBSSON; @@ -1137,9 +1153,9 @@ } static int -wi_reset(struct wi_softc *sc) +wi_reset(struct ifnet *ifp) { - struct ifnet *ifp = sc->sc_ifp; + struct wi_softc *sc = ifp->if_softc; #define WI_INIT_TRIES 3 int i; int error = 0; @@ -1212,8 +1228,6 @@ struct wi_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; struct ifreq *ifr = (struct ifreq *)data; - struct ieee80211req *ireq; - u_int8_t nodename[IEEE80211_NWID_LEN]; int error = 0; struct thread *td = curthread; struct wi_req wreq; @@ -1294,47 +1308,147 @@ WI_UNLOCK(sc); break; case SIOCG80211: - ireq = (struct ieee80211req *) data; - if (ireq->i_type == IEEE80211_IOC_STATIONNAME) { - ireq->i_len = sc->sc_nodelen + 1; - error = copyout(sc->sc_nodename, ireq->i_data, - ireq->i_len); + error = wi_ioctl_get(ifp, cmd, data); + break; + case SIOCS80211: + error = priv_check(td, PRIV_NET80211_MANAGE); + if (error) + break; + error = wi_ioctl_set(ifp, cmd, data); + + + break; + default: + error = ieee80211_ioctl(ic, cmd, data); + WI_LOCK(sc); + if (error == ENETRESET) { + if (sc->sc_enabled) + wi_init(sc); /* XXX no error return */ + error = 0; + } + WI_UNLOCK(sc); + break; + } + return (error); +} + +static int +wi_ioctl_get(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + int error, i, len; + struct wi_softc *sc; + struct ieee80211req *ireq; + struct ieee80211com *ic; + struct wi_apinfo *ap; + struct ieee80211req_scan_result *sr, *bsr; + char *cp; + uint16_t *bssid; + sc = ifp->if_softc; + ic = &sc->sc_ic; + ireq = (struct ieee80211req *) data; + + switch (ireq->i_type) { + case IEEE80211_IOC_SCAN_RESULTS: + sr = bsr = malloc(ireq->i_len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (sr == NULL) { + error = ENOMEM; break; } - goto ioctl_common; - case SIOCS80211: - ireq = (struct ieee80211req *) data; - if (ireq->i_type == IEEE80211_IOC_STATIONNAME) { - error = priv_check(td, PRIV_NET80211_MANAGE); - if (error) + len = 0; + for (i = 0; i < sc->sc_naps; i++) { + ap = &sc->sc_aps[i]; + if (len + sizeof(*sr) + ap->namelen > ireq->i_len) break; - if (ireq->i_val != 0 || - ireq->i_len > IEEE80211_NWID_LEN) { - error = EINVAL; + bssid = (uint16_t *)&ap->bssid; + /* Lucent firmware will return empty records */ + if (bssid[0] == 0 && bssid[1] == 0 && bssid[2] == 0) break; - } - memset(nodename, 0, IEEE80211_NWID_LEN); - error = copyin(ireq->i_data, nodename, ireq->i_len); - if (error) - break; - WI_LOCK(sc); - if (sc->sc_enabled) { - error = wi_write_ssid(sc, WI_RID_NODENAME, - nodename, ireq->i_len); - } - if (error == 0) { - memcpy(sc->sc_nodename, nodename, - IEEE80211_NWID_LEN); - sc->sc_nodelen = ireq->i_len; - } - WI_UNLOCK(sc); + + sr->isr_rssi = ap->signal; + sr->isr_freq = ieee80211_ieee2mhz(ap->channel, + IEEE80211_CHAN_B); + sr->isr_intval = ap->interval; + sr->isr_rates[0] = ap->rate; + sr->isr_nrates = 1; + sr->isr_ssid_len = ap->namelen; + sr->isr_ie_len = 0; + sr->isr_capinfo = ap->capinfo; /* XXX */ + sr->isr_noise = ap->noise; /* XXX */ + bcopy(ap->bssid, sr->isr_bssid, sizeof(sr->isr_bssid)); + cp = (char *)sr + sizeof(*sr); + bcopy(ap->name, cp, sr->isr_ssid_len); + cp += sr->isr_ssid_len; + sr->isr_len = roundup(sizeof(*sr) + sr->isr_ssid_len, + sizeof(uint32_t)); + len += sr->isr_len; + } + ireq->i_len = len; + error = copyout(bsr, ireq->i_data, len); + free(bsr, M_DEVBUF); + break; + case IEEE80211_IOC_STATIONNAME: + ireq->i_len = sc->sc_nodelen + 1; + error = copyout(sc->sc_nodename, ireq->i_data, + ireq->i_len); + break; + default: + error = ieee80211_ioctl(ic, cmd, data); + WI_LOCK(sc); + if (error == ENETRESET) { + if (sc->sc_enabled) + wi_init(sc); /* XXX no error return */ + error = 0; + } + WI_UNLOCK(sc); + + break; + } + + return (error); +} + +static int +wi_ioctl_set(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + int error; + struct wi_softc *sc; + struct ieee80211req *ireq; + u_int8_t nodename[IEEE80211_NWID_LEN]; + + sc = ifp->if_softc; + ireq = (struct ieee80211req *) data; + switch (ireq->i_type) { + case IEEE80211_IOC_SCAN_REQ: + WI_LOCK(sc); + error = wi_scan_ap(sc, 0x3fff, 0x000f); + WI_UNLOCK(sc); + break; + case IEEE80211_IOC_STATIONNAME: + if (ireq->i_val != 0 || + ireq->i_len > IEEE80211_NWID_LEN) { + error = EINVAL; break; } - goto ioctl_common; + memset(nodename, 0, IEEE80211_NWID_LEN); + error = copyin(ireq->i_data, nodename, ireq->i_len); + if (error) + break; + WI_LOCK(sc); + if (sc->sc_enabled) { + error = wi_write_ssid(sc, WI_RID_NODENAME, + nodename, ireq->i_len); + } + if (error == 0) { + memcpy(sc->sc_nodename, nodename, + IEEE80211_NWID_LEN); + sc->sc_nodelen = ireq->i_len; + } + WI_UNLOCK(sc); + + break; default: - ioctl_common: + error = ieee80211_ioctl(&sc->sc_ic, cmd, data); WI_LOCK(sc); - error = ieee80211_ioctl(ic, cmd, data); if (error == ENETRESET) { if (sc->sc_enabled) wi_init(sc); /* XXX no error return */ @@ -1343,9 +1457,21 @@ WI_UNLOCK(sc); break; } + return (error); } +static struct ieee80211_node * +wi_node_alloc(struct ieee80211_node_table *nt) +{ + struct wi_node *rn; + + rn = malloc(sizeof (struct wi_node), M_80211_NODE, + M_NOWAIT | M_ZERO); + + return (rn != NULL) ? &rn->ni : NULL; +} + static int wi_media_change(struct ifnet *ifp) { @@ -3376,3 +3502,37 @@ tsleep(sc, PWAIT, "wiinit", 1); return 0; } + +/* + * This function can be called by ieee80211_set_shortslottime(). Refer to + * IEEE Std 802.11-1999 pp. 85 to know how these values are computed. + */ +static void +wi_update_slot(struct ifnet *ifp) +{ + DPRINTF(("wi update slot unimplemented\n")); +} + +static void +wi_set_channel(struct ieee80211com *ic) +{ + return; +} + +static void +wi_scan_start(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct wi_softc *sc = ifp->if_softc; + + WI_LOCK(sc); + wi_scan_ap(sc, 0x3fff, 0x000f); + WI_UNLOCK(sc); + +} + +static void +wi_scan_end(struct ieee80211com *ic) +{ + return; +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701012342.l01Nggu3031208>