Date: Tue, 8 Jan 2008 20:45:17 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 132808 for review Message-ID: <200801082045.m08KjHtT013055@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=132808 Change 132808 by sam@sam_ebb on 2008/01/08 20:44:38 blindly convert some legacy drivers: compile-tested only and likely wrong; need to understand the best way to handle legacy drivers (e.g. w/ common support in net80211) Affected files ... .. //depot/projects/vap/sys/dev/ipw/if_ipw.c#5 edit .. //depot/projects/vap/sys/dev/ipw/if_ipwvar.h#5 edit .. //depot/projects/vap/sys/dev/iwi/if_iwi.c#9 edit .. //depot/projects/vap/sys/dev/iwi/if_iwivar.h#7 edit .. //depot/projects/vap/sys/dev/ral/if_ralrate.c#3 edit .. //depot/projects/vap/sys/dev/ral/if_ralrate.h#3 edit .. //depot/projects/vap/sys/dev/ral/rt2560.c#3 edit .. //depot/projects/vap/sys/dev/ral/rt2560var.h#3 edit .. //depot/projects/vap/sys/dev/ral/rt2661.c#3 edit .. //depot/projects/vap/sys/dev/ral/rt2661var.h#3 edit .. //depot/projects/vap/sys/dev/usb/if_rum.c#3 edit .. //depot/projects/vap/sys/dev/usb/if_rumvar.h#3 edit .. //depot/projects/vap/sys/dev/usb/if_ural.c#5 edit .. //depot/projects/vap/sys/dev/usb/if_uralvar.h#5 edit .. //depot/projects/vap/sys/dev/usb/if_zyd.c#3 edit .. //depot/projects/vap/sys/dev/usb/if_zydreg.h#3 edit .. //depot/projects/vap/sys/dev/wpi/if_wpi.c#3 edit .. //depot/projects/vap/sys/dev/wpi/if_wpivar.h#3 edit Differences ... ==== //depot/projects/vap/sys/dev/ipw/if_ipw.c#5 (text+ko) ==== @@ -107,11 +107,14 @@ { 0, 0, NULL } }; +static struct ieee80211vap *ipw_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN]); +static void ipw_vap_delete(struct ieee80211vap *); static int ipw_dma_alloc(struct ipw_softc *); static void ipw_release(struct ipw_softc *); -static int ipw_media_change(struct ifnet *); static void ipw_media_status(struct ifnet *, struct ifmediareq *); -static int ipw_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int); static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t); static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *); static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); @@ -163,8 +166,9 @@ static void ipw_scan_start(struct ieee80211com *); static void ipw_scan_end(struct ieee80211com *); static void ipw_set_channel(struct ieee80211com *); -static void ipw_scan_curchan(struct ieee80211com *, unsigned long maxdwell); -static void ipw_scan_mindwell(struct ieee80211com *); +static void ipw_scan_curchan(struct ieee80211_scan_state *, + unsigned long maxdwell); +static void ipw_scan_mindwell(struct ieee80211_scan_state *); static int ipw_probe(device_t); static int ipw_attach(device_t); @@ -293,8 +297,6 @@ ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_DS; - ic->ic_opmode = IEEE80211_M_STA; - ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ ic->ic_caps = IEEE80211_C_IBSS /* IBSS mode supported */ @@ -333,17 +335,15 @@ sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH; ieee80211_ifattach(ic); - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = ipw_newstate; - ieee80211_media_init(ic, ipw_media_change, ipw_media_status); - ic->ic_scan_start = ipw_scan_start; ic->ic_scan_end = ipw_scan_end; ic->ic_set_channel = ipw_set_channel; ic->ic_scan_curchan = ipw_scan_curchan; ic->ic_scan_mindwell = ipw_scan_mindwell; + ic->ic_vap_create = ipw_vap_create; + ic->ic_vap_delete = ipw_vap_delete; + bpfattach2(ifp, DLT_IEEE802_11_RADIO, sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), &sc->sc_drvbpf); @@ -359,8 +359,6 @@ /* * Add a few sysctl knobs. */ - sc->dwelltime = 100; - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "radio", CTLTYPE_INT | CTLFLAG_RD, sc, 0, ipw_sysctl_radio, "I", @@ -371,11 +369,6 @@ CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, ipw_sysctl_stats, "S", "statistics"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell", - CTLFLAG_RW, &sc->dwelltime, 0, - "channel dwell time (ms) for AP/station scanning"); - /* * Hook our interrupt after all initialization is complete. */ @@ -437,6 +430,41 @@ return 0; } +static struct ieee80211vap * +ipw_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN]) +{ + struct ipw_vap *ivp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (ivp == NULL) + return NULL; + vap = &ivp->vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); + /* override with driver methods */ + ivp->newstate = vap->iv_newstate; + vap->iv_newstate = ipw_newstate; + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +ipw_vap_delete(struct ieee80211vap *vap) +{ + struct ipw_vap *ivp = IPW_VAP(vap); + + ieee80211_vap_detach(vap); + free(ivp, M_80211_VAP); +} + static int ipw_dma_alloc(struct ipw_softc *sc) { @@ -767,26 +795,6 @@ } static int -ipw_media_change(struct ifnet *ifp) -{ - struct ipw_softc *sc = ifp->if_softc; - int error; - IPW_LOCK_DECL; - - IPW_LOCK(sc); - error = ieee80211_media_change(ifp); - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) - ipw_init_locked(sc, 0); - error = 0; - } - IPW_UNLOCK(sc); - - return (error); -} - -static int ipw_cvtrate(int ipwrate) { switch (ipwrate) { @@ -805,47 +813,26 @@ static void ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr) { - struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int rate; + struct ieee80211vap *vap = ifp->if_softc; + struct ieee80211com *ic = vap->iv_ic; + struct ipw_softc *sc = ic->ic_ifp->if_softc; - imr->ifm_status = IFM_AVALID; - imr->ifm_active = IFM_IEEE80211; - if (ic->ic_state == IEEE80211_S_RUN) - imr->ifm_status |= IFM_ACTIVE; - /* read current transmission rate from adapter */ - rate = ipw_cvtrate(ipw_read_table1(sc, IPW_INFO_CURRENT_TX_RATE) & 0xf); - imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B); - - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - break; - - case IEEE80211_M_IBSS: - imr->ifm_active |= IFM_IEEE80211_IBSS; - break; - - case IEEE80211_M_MONITOR: - imr->ifm_active |= IFM_IEEE80211_MONITOR; - break; - - case IEEE80211_M_AHDEMO: - case IEEE80211_M_HOSTAP: - case IEEE80211_M_WDS: - /* should not get there */ - break; - } + vap->iv_bss->ni_txrate = ipw_cvtrate( + ipw_read_table1(sc, IPW_INFO_CURRENT_TX_RATE) & 0xf); + ieee80211_media_status(ifp, imr); } static int -ipw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct ipw_vap *ivp = IPW_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ifp->if_softc; DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, - ieee80211_state_name[ic->ic_state], + ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate], sc->flags)); switch (nstate) { @@ -859,7 +846,7 @@ * AUTH -> RUN transition and we want to do nothing. * This is all totally bogus and needs to be redone. */ - if (ic->ic_state == IEEE80211_S_SCAN) + if (vap->iv_state == IEEE80211_S_SCAN) taskqueue_enqueue_fast(taskqueue_fast, &sc->sc_assoc_task); } @@ -880,7 +867,7 @@ * If we are not transitioning from AUTH the resend the * association request. */ - if (ic->ic_state != IEEE80211_S_AUTH) + if (vap->iv_state != IEEE80211_S_AUTH) taskqueue_enqueue_fast(taskqueue_fast, &sc->sc_assoc_task); break; @@ -888,7 +875,7 @@ default: break; } - return (*sc->sc_newstate)(ic, nstate, arg); + return ivp->newstate(vap, nstate, arg); } /* @@ -967,8 +954,9 @@ static void ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) { -#define IEEESTATE(ic) ieee80211_state_name[ic->ic_state] +#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state] struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t state; bus_dmamap_sync(sc->rxbuf_dmat, sbuf->map, BUS_DMASYNC_POSTREAD); @@ -978,19 +966,19 @@ switch (state) { case IPW_STATE_ASSOCIATED: DPRINTFN(2, ("Association succeeded (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); + IEEESTATE(vap), sc->flags)); sc->flags |= IPW_FLAG_ASSOCIATED; /* XXX suppress state change in case the fw auto-associates */ - if (ic->ic_state != IEEE80211_S_ASSOC) { + if (vap->iv_state != IEEE80211_S_ASSOC) { DPRINTF(("Unexpected association (state %u)\n", - ic->ic_state)); + vap->iv_state)); } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + ieee80211_new_state(vap, IEEE80211_S_RUN, -1); break; case IPW_STATE_SCANNING: DPRINTFN(3, ("Scanning (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); + IEEESTATE(vap), sc->flags)); /* * NB: Check driver state for association on assoc * loss as the firmware will immediately start to @@ -1014,9 +1002,9 @@ break; } DPRINTFN(3, ("Scan complete (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); + IEEESTATE(vap), sc->flags)); if (sc->flags & IPW_FLAG_SCANNING) { - ieee80211_scan_done(ic); + ieee80211_scan_done(vap); sc->flags &= ~IPW_FLAG_SCANNING; sc->sc_scan_timer = 0; } @@ -1024,27 +1012,27 @@ case IPW_STATE_ASSOCIATION_LOST: DPRINTFN(2, ("Association lost (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); + IEEESTATE(vap), sc->flags)); sc->flags &= ~IPW_FLAG_ASSOCIATED; - if (ic->ic_state == IEEE80211_S_RUN) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); + if (vap->iv_state == IEEE80211_S_RUN) + ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); break; case IPW_STATE_DISABLED: DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); + IEEESTATE(vap), sc->flags)); break; case IPW_STATE_RADIO_DISABLED: DPRINTFN(2, ("Radio off (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); - ic->ic_ifp->if_flags &= ~IFF_UP; + IEEESTATE(vap), sc->flags)); + vap->iv_ifp->if_flags &= ~IFF_UP; /* XXX */ ipw_stop_locked(sc); break; default: DPRINTFN(2, ("%s: unhandled state %u %s flags 0x%x\n", - __func__, state, IEEESTATE(ic), sc->flags)); + __func__, state, IEEESTATE(vap), sc->flags)); break; } #undef IEEESTATE @@ -1089,6 +1077,7 @@ subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) return; + /* XXX use ieee80211_parse_beacon */ frm = (uint8_t *)(wh + 1); efrm = mtod(m, uint8_t *) + m->m_len; @@ -1119,7 +1108,6 @@ struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; struct mbuf *mnew, *m; - struct ieee80211_frame *wh; struct ieee80211_node *ni; bus_addr_t physaddr; int error; @@ -1191,15 +1179,13 @@ if (sc->flags & IPW_FLAG_SCANNING) ipw_fix_channel(sc, m); - wh = mtod(m, struct ieee80211_frame *); IPW_UNLOCK(sc); - ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); - - /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, status->rssi, -95/*XXX*/, 0); - - /* node is no longer needed */ - ieee80211_free_node(ni); + ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); + if (ni != NULL) { + (void) ieee80211_input(ni, m, status->rssi, -95, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, status->rssi, -95, 0); IPW_LOCK(sc); bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE); @@ -1209,6 +1195,7 @@ ipw_rx_intr(struct ipw_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ipw_status *status; struct ipw_soft_bd *sbd; struct ipw_soft_buf *sbuf; @@ -1243,10 +1230,10 @@ case IPW_STATUS_CODE_NOTIFICATION: DPRINTFN(2, ("notification status, len %u flags 0x%x\n", le32toh(status->len), status->flags)); - if (ic->ic_state == IEEE80211_S_AUTH) { + if (vap->iv_state == IEEE80211_S_AUTH) { /* XXX assume auth notification */ - ieee80211_node_authorize(ic->ic_bss); - ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1); + ieee80211_node_authorize(vap->iv_bss); + ieee80211_new_state(vap, IEEE80211_S_ASSOC, -1); } break; @@ -1528,12 +1515,11 @@ wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; } - /* packet header may have moved, reset our local pointer */ wh = mtod(m0, struct ieee80211_frame *); } @@ -1675,54 +1661,31 @@ ipw_start_locked(struct ifnet *ifp) { struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct mbuf *m0; - struct ether_header *eh; struct ieee80211_node *ni; + struct mbuf *m; IPW_LOCK_ASSERT(sc); - if (ic->ic_state != IEEE80211_S_RUN) - return; - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) break; - if (sc->txfree < 1 + IPW_MAX_NSEG) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); + IFQ_DRV_PREPEND(&ifp->if_snd, m); ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } - - if (m0->m_len < sizeof (struct ether_header) && - (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) - continue; - - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - continue; - } - BPF_MTAP(ifp, m0); - - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { ieee80211_free_node(ni); continue; } - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (ipw_tx_start(ifp, m0, ni) != 0) { + if (ipw_tx_start(ifp, m, ni) != 0) { ieee80211_free_node(ni); ifp->if_oerrors++; break; } - /* start watchdog timer */ sc->sc_tx_timer = 5; } @@ -1750,7 +1713,7 @@ DPRINTFN(3, ("Scan timeout\n")); /* End the scan */ if (sc->flags & IPW_FLAG_SCANNING) { - ieee80211_scan_done(ic); + ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); sc->flags &= ~IPW_FLAG_SCANNING; } } @@ -1763,7 +1726,6 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; int error = 0; IPW_LOCK_DECL; @@ -1781,15 +1743,7 @@ break; default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) - ipw_init_locked(sc, 0); - error = 0; + error = ether_ioctl(ifp, cmd, data); } IPW_UNLOCK(sc); @@ -2011,12 +1965,13 @@ ipw_setwepkeys(struct ipw_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ipw_wep_key wepkey; struct ieee80211_key *wk; int error, i; for (i = 0; i < IEEE80211_WEP_NKID; i++) { - wk = &ic->ic_crypto.cs_nw_keys[i]; + wk = &vap->iv_nw_keys[i]; if (wk->wk_cipher == NULL || wk->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) @@ -2182,6 +2137,7 @@ ipw_config(struct ipw_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ifnet *ifp = ic->ic_ifp; struct ipw_security security; struct ipw_configuration config; @@ -2221,9 +2177,9 @@ if (ic->ic_opmode == IEEE80211_M_MONITOR) return ipw_enable(sc); - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - DPRINTF(("Setting MAC address to %6D\n", ic->ic_myaddr, ":")); - error = ipw_cmd(sc, IPW_CMD_SET_MAC_ADDRESS, ic->ic_myaddr, + IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp)); + DPRINTF(("Setting MAC address to %6D\n", vap->iv_myaddr, ":")); + error = ipw_cmd(sc, IPW_CMD_SET_MAC_ADDRESS, vap->iv_myaddr, IEEE80211_ADDR_LEN); if (error != 0) return error; @@ -2274,19 +2230,19 @@ return error; } - data = htole32(ic->ic_rtsthreshold); + data = htole32(vap->iv_rtsthreshold); DPRINTF(("Setting RTS threshold to %u\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_RTS_THRESHOLD, &data, sizeof data); if (error != 0) return error; - data = htole32(ic->ic_fragthreshold); + data = htole32(vap->iv_fragthreshold); DPRINTF(("Setting frag threshold to %u\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_FRAG_THRESHOLD, &data, sizeof data); if (error != 0) return error; - error = ipw_setssid(sc, ic->ic_des_ssid[0].ssid, ic->ic_des_ssid[0].len); + error = ipw_setssid(sc, vap->iv_des_ssid[0].ssid, vap->iv_des_ssid[0].len); if (error != 0) return error; @@ -2294,17 +2250,17 @@ if (error != 0) return error; - if (ic->ic_flags & IEEE80211_F_DESBSSID) { - DPRINTF(("Setting desired BSSID to %6D\n", ic->ic_des_bssid, + if (vap->iv_flags & IEEE80211_F_DESBSSID) { + DPRINTF(("Setting desired BSSID to %6D\n", vap->iv_des_bssid, ":")); error = ipw_cmd(sc, IPW_CMD_SET_DESIRED_BSSID, - ic->ic_des_bssid, IEEE80211_ADDR_LEN); + vap->iv_des_bssid, IEEE80211_ADDR_LEN); if (error != 0) return error; } memset(&security, 0, sizeof security); - security.authmode = (ic->ic_bss->ni_authmode == IEEE80211_AUTH_SHARED) ? + security.authmode = (vap->iv_bss->ni_authmode == IEEE80211_AUTH_SHARED) ? IPW_AUTH_SHARED : IPW_AUTH_OPEN; security.ciphers = htole32(IPW_CIPHER_NONE); DPRINTF(("Setting authmode to %u\n", security.authmode)); @@ -2313,13 +2269,13 @@ if (error != 0) return error; - if (ic->ic_flags & IEEE80211_F_PRIVACY) { + if (vap->iv_flags & IEEE80211_F_PRIVACY) { error = ipw_setwepkeys(sc); if (error != 0) return error; - if (ic->ic_crypto.cs_def_txkey != IEEE80211_KEYIX_NONE) { - data = htole32(ic->ic_crypto.cs_def_txkey); + if (vap->iv_def_txkey != IEEE80211_KEYIX_NONE) { + data = htole32(vap->iv_def_txkey); DPRINTF(("Setting wep tx key index to %u\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY_INDEX, &data, @@ -2329,14 +2285,15 @@ } } - data = htole32((ic->ic_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0); + data = htole32((vap->iv_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0); DPRINTF(("Setting wep flags to 0x%x\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_WEP_FLAGS, &data, sizeof data); if (error != 0) return error; - if (ic->ic_opt_ie != NULL) { - error = ipw_setwpaie(sc, ic->ic_opt_ie, ic->ic_opt_ie_len); + if (vap->iv_appie_assocreq != NULL) { + struct ieee80211_appie *ie = vap->iv_appie_assocreq; + error = ipw_setwpaie(sc, ie->ie_data, ie->ie_len); if (error != 0) return error; } @@ -2376,7 +2333,8 @@ ipw_auth_and_assoc(struct ipw_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211_node *ni = vap->iv_bss; struct ipw_security security; uint32_t data; int error; @@ -2395,13 +2353,13 @@ if (error != 0) return (error); - if (ic->ic_flags & IEEE80211_F_PRIVACY) { + if (vap->iv_flags & IEEE80211_F_PRIVACY) { error = ipw_setwepkeys(sc); if (error != 0) return error; - if (ic->ic_crypto.cs_def_txkey != IEEE80211_KEYIX_NONE) { - data = htole32(ic->ic_crypto.cs_def_txkey); + if (vap->iv_def_txkey != IEEE80211_KEYIX_NONE) { + data = htole32(vap->iv_def_txkey); DPRINTF(("Setting wep tx key index to %u\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY_INDEX, &data, @@ -2411,7 +2369,7 @@ } } - data = htole32((ic->ic_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0); + data = htole32((vap->iv_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0); DPRINTF(("Setting wep flags to 0x%x\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_WEP_FLAGS, &data, sizeof data); if (error != 0) @@ -2425,8 +2383,9 @@ if (error != 0) return (error); - if (ic->ic_opt_ie != NULL) { - error = ipw_setwpaie(sc, ic->ic_opt_ie, ic->ic_opt_ie_len); + if (vap->iv_appie_assocreq != NULL) { + struct ieee80211_appie *ie = vap->iv_appie_assocreq; + error = ipw_setwpaie(sc, ie->ie_data, ie->ie_len); if (error != 0) return error; } @@ -2462,7 +2421,8 @@ ipw_disassociate(struct ipw_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211_node *ni = vap->iv_bss; DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); @@ -2507,6 +2467,7 @@ ipw_init_locked(struct ipw_softc *sc, int force) { struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ifnet *ifp = ic->ic_ifp; const struct firmware *fp; const struct ipw_firmware_hdr *hdr; @@ -2516,7 +2477,7 @@ IPW_LOCK_ASSERT(sc); DPRINTF(("%s: state %s flags 0x%x\n", __func__, - ieee80211_state_name[ic->ic_state], sc->flags)); + ieee80211_state_name[vap->iv_state], sc->flags)); /* * Avoid re-entrant calls. We need to release the mutex in ipw_init() @@ -2631,22 +2592,13 @@ goto fail1; } - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - /* - * NB: When restarting the adapter clock the state - * machine regardless of the roaming mode; otherwise - * we need to notify user apps so they can manually - * get us going again. - */ - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL || force) - ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; + /* XXX force handling */ + ieee80211_start_all(ic); /* start all vap's */ + sc->flags &=~ IPW_FLAG_INIT_LOCKED; return; @@ -2677,8 +2629,6 @@ IPW_LOCK_ASSERT(sc); - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - callout_stop(&sc->sc_wdtimer); ipw_stop_master(sc); @@ -2816,13 +2766,13 @@ } static void -ipw_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) +ipw_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { /* NB: all channels are scanned at once */ } static void -ipw_scan_mindwell(struct ieee80211com *ic) +ipw_scan_mindwell(struct ieee80211_scan_state *ss) { /* NB: don't try to abort scan; wait for firmware to finish */ } ==== //depot/projects/vap/sys/dev/ipw/if_ipwvar.h#5 (text+ko) ==== @@ -76,11 +76,17 @@ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_CHANNEL)) +struct ipw_vap { + struct ieee80211vap vap; + + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define IPW_VAP(vap) ((struct ipw_vap *)(vap)) + struct ipw_softc { struct ifnet *sc_ifp; struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); device_t sc_dev; struct mtx sc_mtx; @@ -152,22 +158,12 @@ uint32_t rxcur; int txfree; - int dwelltime; - struct bpf_if *sc_drvbpf; - union { - struct ipw_rx_radiotap_header th; - uint8_t pad[64]; - } sc_rxtapu; -#define sc_rxtap sc_rxtapu.th + struct ipw_rx_radiotap_header sc_rxtap; int sc_rxtap_len; - union { - struct ipw_tx_radiotap_header th; - uint8_t pad[64]; - } sc_txtapu; -#define sc_txtap sc_txtapu.th + struct ipw_tx_radiotap_header sc_txtap; int sc_txtap_len; }; ==== //depot/projects/vap/sys/dev/iwi/if_iwi.c#9 (text+ko) ==== @@ -73,6 +73,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_input.h> #include <net80211/ieee80211_regdomain.h> #include <netinet/in.h> @@ -120,6 +121,10 @@ { 0, 0, NULL } }; +static struct ieee80211vap *iwi_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN]); +static void iwi_vap_delete(struct ieee80211vap *); static void iwi_dma_map_addr(void *, bus_dma_segment_t *, int, int); static int iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *, int); @@ -135,9 +140,8 @@ static void iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *); static struct ieee80211_node *iwi_node_alloc(struct ieee80211_node_table *); static void iwi_node_free(struct ieee80211_node *); -static int iwi_media_change(struct ifnet *); static void iwi_media_status(struct ifnet *, struct ifmediareq *); -static int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int iwi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void iwi_wme_init(struct iwi_softc *); static int iwi_wme_setparams(struct iwi_softc *); static int iwi_wme_update(struct ieee80211com *); @@ -168,16 +172,16 @@ static void iwi_scan_end(struct ieee80211com *); static void iwi_scanabort(void *, int); static void iwi_set_channel(struct ieee80211com *); -static void iwi_scan_curchan(struct ieee80211com *, unsigned long maxdwell); +static void iwi_scan_curchan(struct ieee80211_scan_state *, unsigned long maxdwell); #if 0 static void iwi_scan_allchan(struct ieee80211com *, unsigned long maxdwell); #endif -static void iwi_scan_mindwell(struct ieee80211com *); -static void iwi_assoc(struct ieee80211com *ic); -static void iwi_disassoc(struct ieee80211com *); +static void iwi_scan_mindwell(struct ieee80211_scan_state *); +static void iwi_assoc(struct ieee80211vap *); +static void iwi_disassoc(struct ieee80211vap *); static void iwi_ops(void *, int); static int iwi_queue_cmd(struct iwi_softc *, int); -static int iwi_auth_and_assoc(struct iwi_softc *); +static int iwi_auth_and_assoc(struct iwi_softc *, struct ieee80211vap *); static int iwi_disassociate(struct iwi_softc *, int quiet); static void iwi_init(void *); static void iwi_init_locked(void *, int); @@ -258,7 +262,8 @@ struct ifnet *ifp; struct ieee80211com *ic = &sc->sc_ic; uint16_t val; - int i, error, bands; + int i, error; + uint8_t bands; sc->sc_dev = dev; @@ -267,7 +272,6 @@ sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx); -#if __FreeBSD_version >= 700000 sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT | M_ZERO, taskqueue_thread_enqueue, &sc->sc_tq); taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", @@ -276,16 +280,7 @@ taskqueue_thread_enqueue, &sc->sc_tq2); taskqueue_start_threads(&sc->sc_tq2, 1, PI_NET, "%s taskq2", device_get_nameunit(dev)); -#else - sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT | M_ZERO, - taskqueue_thread_enqueue, &sc->sc_tq, &sc->sc_tqproc); - kproc_create(taskqueue_thread_loop, &sc->sc_tq, &sc->sc_tqproc, - 0, 0, "%s taskq", device_get_nameunit(dev)); - sc->sc_tq2 = taskqueue_create("iwi_taskq2", M_NOWAIT | M_ZERO, - taskqueue_thread_enqueue, &sc->sc_tq2, &sc->sc_tqproc); - kproc_create(taskqueue_thread_loop, &sc->sc_tq2, &sc->sc_tqproc, - 0, 0, "%s taskq2", device_get_nameunit(dev)); -#endif + TASK_INIT(&sc->sc_radiontask, 0, iwi_radio_on, sc); TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc); TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc); @@ -370,10 +365,7 @@ ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); - ic->ic_wme.wme_update = iwi_wme_update; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ ic->ic_caps = @@ -402,10 +394,9 @@ setbit(&bands, IEEE80211_MODE_11G); if (pci_get_device(dev) >= 0x4223) setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); - ic->ic_bmissthreshold = 10; /* override default */ /* override default methods */ ic->ic_node_alloc = iwi_node_alloc; sc->sc_node_free = ic->ic_node_free; @@ -415,11 +406,10 @@ ic->ic_set_channel = iwi_set_channel; ic->ic_scan_curchan = iwi_scan_curchan; ic->ic_scan_mindwell = iwi_scan_mindwell; + ic->ic_wme.wme_update = iwi_wme_update; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = iwi_newstate; - ieee80211_media_init(ic, iwi_media_change, iwi_media_status); + ic->ic_vap_create = iwi_vap_create; + ic->ic_vap_delete = iwi_vap_delete; bpfattach2(ifp, DLT_IEEE802_11_RADIO, sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), @@ -505,6 +495,42 @@ return 0; } +static struct ieee80211vap * +iwi_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN]) +{ + struct iwi_vap *ivp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + ivp = (struct iwi_vap *) malloc(sizeof(struct iwi_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (ivp == NULL) + return NULL; + vap = &ivp->iwi_vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); + vap->iv_bmissthreshold = 10; /* override default */ + /* override with driver methods */ + ivp->iwi_newstate = vap->iv_newstate; + vap->iv_newstate = iwi_newstate; + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, iwi_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +iwi_vap_delete(struct ieee80211vap *vap) +{ + struct iwi_vap *ivp = IWI_VAP(vap); + + ieee80211_vap_detach(vap); + free(ivp, M_80211_VAP); +} + static void iwi_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) { @@ -882,25 +908,6 @@ sc->sc_node_free(ni); } -static int -iwi_media_change(struct ifnet *ifp) -{ - struct iwi_softc *sc = ifp->if_softc; - int error; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - - error = ieee80211_media_change(ifp); - if (error == ENETRESET && - (ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - iwi_init_locked(sc, 0); - >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200801082045.m08KjHtT013055>