diff options
Diffstat (limited to 'sys/dev/pci/if_ipw.c')
-rw-r--r-- | sys/dev/pci/if_ipw.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c index ccf77ce3f72..3a0784b7eea 100644 --- a/sys/dev/pci/if_ipw.c +++ b/sys/dev/pci/if_ipw.c @@ -1,4 +1,4 @@ -/* $Id: if_ipw.c,v 1.31 2004/12/05 19:39:22 damien Exp $ */ +/* $Id: if_ipw.c,v 1.32 2004/12/05 19:54:03 damien Exp $ */ /*- * Copyright (c) 2004 @@ -86,6 +86,7 @@ int ipw_media_change(struct ifnet *); void ipw_media_status(struct ifnet *, struct ifmediareq *); int ipw_newstate(struct ieee80211com *, enum ieee80211_state, int); u_int16_t ipw_read_prom_word(struct ipw_softc *, u_int8_t); +void ipw_scan_result(struct ipw_softc *); void ipw_command_intr(struct ipw_softc *, struct ipw_soft_buf *); void ipw_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); void ipw_data_intr(struct ipw_softc *, struct ipw_status *, @@ -735,6 +736,57 @@ ipw_read_prom_word(struct ipw_softc *sc, u_int8_t addr) } void +ipw_scan_result(struct ipw_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211_node *ni; + u_int32_t i, cnt, off; + struct ipw_node ap; + + /* flush previously seen access points */ + ieee80211_free_allnodes(ic); + + cnt = ipw_read_table1(sc, IPW_INFO_APS_CNT); + off = ipw_read_table1(sc, IPW_INFO_APS_BASE); + + DPRINTF(("Found %u APs\n", cnt)); + + for (i = 0; i < cnt; i++) { + ipw_read_mem_1(sc, off, (u_int8_t *)&ap, sizeof ap); + off += sizeof ap; + +#ifdef IPW_DEBUG + if (ipw_debug >= 2) { + u_char *p = (u_char *)≈ + int j; + + printf("AP%u\n", i); + for (j = 0; j < sizeof ap; j++) + printf("%02x", *p++); + printf("\n"); + } +#endif + + ni = ieee80211_lookup_node(ic, ap.bssid, + &ic->ic_channels[ap.chan]); + if (ni != NULL) + continue; + + ni = ieee80211_alloc_node(ic, ap.bssid); + if (ni == NULL) + return; + + IEEE80211_ADDR_COPY(ni->ni_bssid, ap.bssid); + ni->ni_rssi = ap.rssi; + ni->ni_intval = letoh16(ap.intval); + ni->ni_capinfo = letoh16(ap.capinfo); + ni->ni_chan = &ic->ic_channels[ap.chan]; + ni->ni_esslen = ap.esslen; + bcopy(ap.essid, ni->ni_essid, IEEE80211_NWID_LEN); + } +} + +void ipw_command_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) { struct ipw_cmd *cmd; @@ -775,6 +827,10 @@ ipw_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); break; + case IPW_STATE_SCAN_COMPLETE: + ipw_scan_result(sc); + break; + case IPW_STATE_ASSOCIATION_LOST: ieee80211_new_state(ic, IEEE80211_S_INIT, -1); break; |