diff options
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_ipw.c | 58 | ||||
-rw-r--r-- | sys/dev/pci/if_ipwreg.h | 22 |
2 files changed, 78 insertions, 2 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; diff --git a/sys/dev/pci/if_ipwreg.h b/sys/dev/pci/if_ipwreg.h index 3db0a39f64c..f25f98ba3bf 100644 --- a/sys/dev/pci/if_ipwreg.h +++ b/sys/dev/pci/if_ipwreg.h @@ -1,4 +1,4 @@ -/* $Id: if_ipwreg.h,v 1.8 2004/12/05 19:39:22 damien Exp $ */ +/* $Id: if_ipwreg.h,v 1.9 2004/12/05 19:54:03 damien Exp $ */ /*- * Copyright (c) 2004 @@ -97,6 +97,8 @@ /* table1 offsets */ #define IPW_INFO_LOCK 480 +#define IPW_INFO_APS_CNT 604 +#define IPW_INFO_APS_BASE 608 #define IPW_INFO_CARD_DISABLED 628 #define IPW_INFO_CURRENT_CHANNEL 756 #define IPW_INFO_CURRENT_TX_RATE 768 @@ -252,6 +254,24 @@ struct ipw_configuration { u_int32_t ibss_chan; } __attribute__((__packed__)); +/* element in AP table */ +struct ipw_node { + u_int32_t reserved1[2]; + u_int8_t bssid[IEEE80211_ADDR_LEN]; + u_int8_t chan; + u_int8_t rates; + u_int16_t reserved2; + u_int16_t capinfo; + u_int16_t reserved3; + u_int16_t intval; + u_int8_t reserved4[28]; + u_int8_t essid[IEEE80211_NWID_LEN]; + u_int16_t reserved5; + u_int8_t esslen; + u_int8_t reserved6[7]; + u_int8_t rssi; +} __attribute__((__packed__)); + /* EEPROM = Electrically Erasable Programmable Read-Only Memory */ #define IPW_MEM_EEPROM_CTL 0x00300040 |