summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2005-03-12 13:23:31 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2005-03-12 13:23:31 +0000
commite2f3fef6ab7f8f6baf2b5b62c4adc1b84ce8bbac (patch)
treec5c5a78ab837fb8f075b38f27ac3ac7525d8e626 /sys/dev
parent46ca4a22cf421077167465274a38760e8f2e3f7b (diff)
retrieve scan results from net80211 instead of reading NIC internal memory.
this fixes a bug with multiple AP's.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_ipw.c80
-rw-r--r--sys/dev/pci/if_ipwreg.h20
2 files changed, 16 insertions, 84 deletions
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index d4b94eeafcc..ce89bf4ab16 100644
--- a/sys/dev/pci/if_ipw.c
+++ b/sys/dev/pci/if_ipw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ipw.c,v 1.42 2005/02/21 13:33:29 damien Exp $ */
+/* $OpenBSD: if_ipw.c,v 1.43 2005/03/12 13:23:30 damien Exp $ */
/*-
* Copyright (c) 2004, 2005
@@ -87,7 +87,6 @@ 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 *,
@@ -236,7 +235,7 @@ ipw_attach(struct device *parent, struct device *self, void *aux)
/* set device capabilities */
ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_MONITOR |
IEEE80211_C_PMGT | IEEE80211_C_TXPMGT | IEEE80211_C_WEP |
- IEEE80211_C_SHPREAMBLE;
+ IEEE80211_C_SHPREAMBLE | IEEE80211_C_SCANALL;
/* read MAC address from EEPROM */
val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0);
@@ -698,23 +697,23 @@ int
ipw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
{
struct ipw_softc *sc = ic->ic_softc;
- struct ieee80211_node *ni = ic->ic_bss;
+ struct ieee80211_node *ni;
+ u_int8_t macaddr[IEEE80211_ADDR_LEN];
u_int32_t len;
- u_int8_t val;
switch (nstate) {
case IEEE80211_S_RUN:
- len = IEEE80211_NWID_LEN;
- ipw_read_table2(sc, IPW_INFO_CURRENT_SSID, ni->ni_essid, &len);
- ni->ni_esslen = len;
-
- val = ipw_read_table1(sc, IPW_INFO_CURRENT_CHANNEL);
- ni->ni_chan = &ic->ic_channels[val];
-
DELAY(100); /* firmware needs a short delay here */
len = IEEE80211_ADDR_LEN;
- ipw_read_table2(sc, IPW_INFO_CURRENT_BSSID, ni->ni_bssid, &len);
+ ipw_read_table2(sc, IPW_INFO_CURRENT_BSSID, macaddr, &len);
+
+ ni = ieee80211_find_node(ic, macaddr);
+ if (ni == NULL)
+ break;
+
+ (*ic->ic_node_copy)(ic, ic->ic_bss, ni);
+ ieee80211_node_newstate(ni, IEEE80211_STA_BSS);
break;
case IEEE80211_S_INIT:
@@ -785,57 +784,6 @@ 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 *)&ap;
- 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;
@@ -874,10 +822,12 @@ ipw_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
/* don't leave run state on background scan */
if (ic->ic_state != IEEE80211_S_RUN)
ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+
+ ic->ic_flags |= IEEE80211_F_ASCAN;
break;
case IPW_STATE_SCAN_COMPLETE:
- ipw_scan_result(sc);
+ ic->ic_flags &= ~IEEE80211_F_ASCAN;
break;
case IPW_STATE_ASSOCIATION_LOST:
diff --git a/sys/dev/pci/if_ipwreg.h b/sys/dev/pci/if_ipwreg.h
index 9cda8b48ba3..a4dd1507c44 100644
--- a/sys/dev/pci/if_ipwreg.h
+++ b/sys/dev/pci/if_ipwreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ipwreg.h,v 1.11 2005/01/13 20:52:13 damien Exp $ */
+/* $OpenBSD: if_ipwreg.h,v 1.12 2005/03/12 13:23:30 damien Exp $ */
/*-
* Copyright (c) 2004, 2005
@@ -254,24 +254,6 @@ 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