PERFORCE change 112405 for review
Kip Macy
kmacy at FreeBSD.org
Mon Jan 1 15:42:43 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=112405
Change 112405 by kmacy at 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;
+}
More information about the p4-projects
mailing list