Date: Mon, 25 Feb 2008 16:50:23 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 136174 for review Message-ID: <200802251650.m1PGoNGT096635@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=136174 Change 136174 by sam@sam_ebb on 2008/02/25 16:50:10 checkpoint bwi conversion Affected files ... .. //depot/projects/vap/sys/conf/files#17 edit .. //depot/projects/vap/sys/conf/options#11 edit .. //depot/projects/vap/sys/dev/bwi/bwimac.c#2 edit .. //depot/projects/vap/sys/dev/bwi/bwirf.c#2 edit .. //depot/projects/vap/sys/dev/bwi/if_bwi.c#2 edit .. //depot/projects/vap/sys/dev/bwi/if_bwivar.h#2 edit .. //depot/projects/vap/sys/modules/bwi/Makefile#2 edit Differences ... ==== //depot/projects/vap/sys/conf/files#17 (text+ko) ==== @@ -495,6 +495,11 @@ dev/bktr/bktr_os.c optional bktr pci dev/bktr/bktr_tuner.c optional bktr pci dev/bktr/msp34xx.c optional bktr pci +dev/bwi/if_bwi.c optional bwi +dev/bwi/if_bwi_pci.c optional bwi pci +dev/bwi/bwimac.c optional bwi +dev/bwi/bwiphy.c optional bwi +dev/bwi/bwirf.c optional bwi dev/buslogic/bt.c optional bt dev/buslogic/bt_eisa.c optional bt eisa dev/buslogic/bt_isa.c optional bt isa ==== //depot/projects/vap/sys/conf/options#11 (text+ko) ==== @@ -729,6 +729,10 @@ ATH_DIAGAPI opt_ath.h ATH_TX99_DIAG opt_ath.h +# options for the Broadcom wireless driver +BWI_DEBUG opt_bwi.h +BWI_DEBUG_VERBOSE opt_bwi.h + # dcons options DCONS_BUF_SIZE opt_dcons.h DCONS_POLL_HZ opt_dcons.h ==== //depot/projects/vap/sys/dev/bwi/bwimac.c#2 (text+ko) ==== @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" +#include "opt_bwi.h" #include <sys/param.h> #include <sys/endian.h> ==== //depot/projects/vap/sys/dev/bwi/bwirf.c#2 (text+ko) ==== @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" +#include "opt_bwi.h" #include <sys/param.h> #include <sys/endian.h> ==== //depot/projects/vap/sys/dev/bwi/if_bwi.c#2 (text+ko) ==== @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" +#include "opt_bwi.h" #include <sys/param.h> #include <sys/endian.h> @@ -93,6 +94,11 @@ uint8_t bssid[IEEE80211_ADDR_LEN]; } __packed; +static struct ieee80211vap *bwi_vap_create(struct ieee80211com *, + const char [IFNAMSIZ], int, int, int, + const uint8_t [IEEE80211_ADDR_LEN], + const uint8_t [IEEE80211_ADDR_LEN]); +static void bwi_vap_delete(struct ieee80211vap *); static void bwi_init(void *); static int bwi_ioctl(struct ifnet *, u_long, caddr_t); static void bwi_start(struct ifnet *); @@ -103,7 +109,7 @@ static void bwi_scan_start(struct ieee80211com *); static void bwi_set_channel(struct ieee80211com *); static void bwi_scan_end(struct ieee80211com *); -static int bwi_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void bwi_updateslot(struct ifnet *); static struct ieee80211_node *bwi_node_alloc(struct ieee80211_node_table *); static void bwi_newassoc(struct ieee80211_node *, int); @@ -115,11 +121,10 @@ static int bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *); static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *); static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *); -static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *, +static void bwi_rx_radiotap(struct ifnet *, struct mbuf *, struct bwi_rxbuf_hdr *, const void *, int, int); static void bwi_restart(void *, int); -static void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state); static void bwi_init_statechg(struct bwi_softc *, int); static void bwi_stop(struct bwi_softc *, int); static int bwi_newbuf(struct bwi_softc *, int, int); @@ -188,7 +193,6 @@ static void bwi_set_addr_filter(struct bwi_softc *, uint16_t, const uint8_t *); static void bwi_set_bssid(struct bwi_softc *, const uint8_t *); -static int bwi_set_chan(struct bwi_softc *, struct ieee80211_channel *); static void bwi_get_card_flags(struct bwi_softc *); static void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *); @@ -352,7 +356,8 @@ struct ifnet *ifp; struct bwi_mac *mac; struct bwi_phy *phy; - int i, error, bands; + int i, error; + uint8_t bands; BWI_LOCK_INIT(sc); @@ -365,6 +370,8 @@ device_get_nameunit(dev)); TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc); + callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0); + /* * Initialize sysctl variables */ @@ -372,8 +379,9 @@ sc->sc_led_idle = (2350 * hz) / 1000; sc->sc_led_blink = 1; sc->sc_txpwr_calib = 1; +#ifdef BWI_DEBUG sc->sc_debug = bwi_debug; - +#endif bwi_power_on(sc, 1); error = bwi_bbp_attach(sc); @@ -436,7 +444,7 @@ if (error) goto fail; - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); error = ENOSPC; @@ -446,34 +454,6 @@ /* set these up early for if_printf use */ if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0); - callout_init_mtx(&sc->sc_amrr_ch, &sc->sc_mtx, 0); - - /* - * Add sysctl nodes - */ - SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, - "fw_version", CTLFLAG_RD, &sc->sc_fw_version, 0, - "Firmware version"); - SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, - "led_idle", CTLFLAG_RW, &sc->sc_led_idle, 0, - "# ticks before LED enters idle state"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, - "led_blink", CTLFLAG_RW, &sc->sc_led_blink, 0, - "Allow LED to blink"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, - "txpwr_calib", CTLFLAG_RW, &sc->sc_txpwr_calib, 0, - "Enable software TX power calibration"); -#ifdef BWI_DEBUG - SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, - "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); -#endif - ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_init = bwi_init; @@ -484,11 +464,6 @@ ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); - /* Get locale */ - sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO), - BWI_SPROM_CARD_INFO_LOCALE); - DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale); - /* * Setup ratesets, phytype, channels and get MAC address */ @@ -520,45 +495,39 @@ } else { panic("unknown phymode %d\n", phy->phy_mode); } + + /* Get locale */ + sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO), + BWI_SPROM_CARD_INFO_LOCALE); + DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale); /* XXX use locale */ - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); ic->ic_ifp = ifp; ic->ic_caps = IEEE80211_C_SHSLOT | IEEE80211_C_SHPREAMBLE | IEEE80211_C_WPA | IEEE80211_C_MONITOR; - ic->ic_state = IEEE80211_S_INIT; ic->ic_opmode = IEEE80211_M_STA; - - ic->ic_updateslot = bwi_updateslot; - ieee80211_ifattach(ic); ic->ic_headroom = sizeof(struct bwi_txbuf_hdr); - ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* override default methods */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = bwi_newstate; + ic->ic_vap_create = bwi_vap_create; + ic->ic_vap_delete = bwi_vap_delete; + ic->ic_raw_xmit = bwi_raw_xmit; + ic->ic_updateslot = bwi_updateslot; + ic->ic_node_alloc = bwi_node_alloc; ic->ic_scan_start = bwi_scan_start; ic->ic_scan_end = bwi_scan_end; ic->ic_set_channel = bwi_set_channel; - ic->ic_node_alloc = bwi_node_alloc; - ic->ic_newassoc = bwi_newassoc; - ic->ic_raw_xmit = bwi_raw_xmit; - /* complete initialization */ - ieee80211_media_init(ic, bwi_media_change, ieee80211_media_status); - ieee80211_amrr_init(&sc->sc_amrr, ic, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); /* - * Attach radio tap + * Attach bpf. */ - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th)); sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t)); sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len); @@ -568,6 +537,30 @@ sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len); sc->sc_rx_th.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT); + /* + * Add sysctl nodes + */ + SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "fw_version", CTLFLAG_RD, &sc->sc_fw_version, 0, + "Firmware version"); + SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "led_idle", CTLFLAG_RW, &sc->sc_led_idle, 0, + "# ticks before LED enters idle state"); + SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "led_blink", CTLFLAG_RW, &sc->sc_led_blink, 0, + "Allow LED to blink"); + SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "txpwr_calib", CTLFLAG_RW, &sc->sc_txpwr_calib, 0, + "Enable software TX power calibration"); +#ifdef BWI_DEBUG + SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags"); +#endif if (bootverbose) ieee80211_announce(ic); @@ -588,7 +581,6 @@ BWI_UNLOCK(sc); callout_drain(&sc->sc_calib_ch); - callout_drain(&sc->sc_amrr_ch); ieee80211_ifdetach(&sc->sc_ic); for (i = 0; i < sc->sc_nmac; ++i) @@ -602,6 +594,54 @@ return (0); } +static struct ieee80211vap * +bwi_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct bwi_softc *sc = ic->ic_ifp->if_softc; + struct bwi_vap *bvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + bvp = (struct bwi_vap *) malloc(sizeof(struct bwi_vap), + M_80211_VAP, M_WAITOK | M_ZERO); + if (bvp == NULL) + return NULL; + vap = &bvp->bv_vap; + /* enable s/w bmiss handling for sta mode */ + ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + + /* override default methods */ + bvp->bv_newstate = vap->iv_newstate; + vap->iv_newstate = bwi_newstate; +#if 0 + vap->iv_update_beacon = bwi_beacon_update; +#endif + callout_init_mtx(&bvp->bv_amrr_ch, &sc->sc_mtx, 0); + ieee80211_amrr_init(&bvp->bv_amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); + + /* complete setup */ + ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +bwi_vap_delete(struct ieee80211vap *vap) +{ + struct bwi_vap *bvp = BWI_VAP(vap); + + callout_drain(&bvp->bv_amrr_ch); + ieee80211_vap_detach(vap); + free(bvp, M_80211_VAP); +} + void bwi_suspend(struct bwi_softc *sc) { @@ -1207,12 +1247,16 @@ mac = &sc->sc_mac[0]; error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL); - if (error) - goto back; - + if (error) { + if_printf(ifp, "%s: error %d on regwin switch\n", + __func__, error); + goto bad; + } error = bwi_mac_init(mac); - if (error) - goto back; + if (error) { + if_printf(ifp, "%s: error %d on MAC init\n", __func__, error); + goto bad; + } bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN); @@ -1237,7 +1281,7 @@ CSR_READ_4(sc, BWI_TXSTATUS1); } if (i == NRETRY) - if_printf(ifp, "can't drain TX status\n"); + if_printf(ifp, "%s: can't drain TX status\n", __func__); #undef NRETRY } @@ -1246,36 +1290,24 @@ /* Start MAC */ error = bwi_mac_start(mac); - if (error) - goto back; + if (error) { + if_printf(ifp, "%s: error %d starting MAC\n", __func__, error); + goto bad; + } /* Clear stop flag before enabling interrupt */ sc->sc_flags &= ~BWI_F_STOP; + ifp->if_drv_flags |= IFF_DRV_RUNNING; + /* Enable intrs */ bwi_enable_intrs(sc, BWI_INIT_INTRS); - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - if (statechg) { - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else { - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - } - } else { - /* XXX */ - if (ic->ic_state != IEEE80211_S_INIT) - bwi_set_channel(ic); - ieee80211_new_state(ic, ic->ic_state, -1); - } -back: - if (error) - bwi_stop(sc, 1); - else - bwi_start_locked(ifp); + ieee80211_start_all(ic); /* start all vap's */ + BWI_UNLOCK(sc); + return; +bad: + bwi_stop(sc, 1); BWI_UNLOCK(sc); } @@ -1285,6 +1317,8 @@ #define IS_RUNNING(ifp) \ ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) struct bwi_softc *sc = ifp->if_softc; + struct ieee80211com *ic = &sc->sc_ic; + struct ifreq *ifr = (struct ifreq *)req; int error = 0; BWI_LOCK(sc); @@ -1322,16 +1356,19 @@ bwi_stop(sc, 1); } break; + case SIOCADDMULTI: + case SIOCDELMULTI: + /* XXX */ + break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - error = ieee80211_ioctl(&sc->sc_ic, cmd, req); + error = ether_ioctl(ifp, cmd, req); break; } - if (error == ENETRESET) { - if (IS_RUNNING(ifp)) - bwi_init(sc); - error = 0; - } BWI_UNLOCK(sc); return error; @@ -1352,70 +1389,35 @@ bwi_start_locked(struct ifnet *ifp) { struct bwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct ieee80211_frame *wh; struct ieee80211_node *ni; - struct ether_header *eh; struct ieee80211_key *k; struct mbuf *m; int trans, idx; - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; trans = 0; idx = tbd->tbd_idx; while (tbd->tbd_buf[idx].tb_mbuf == NULL) { - IF_DEQUEUE(&ic->ic_mgtq, m); - if (m != NULL) { - ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; - m->m_pkthdr.rcvif = NULL; - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ + if (m == NULL) + break; - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ - if (m == NULL) - break; - - if (m->m_len < sizeof(*eh)) { - m = m_pullup(m, sizeof(*eh)); - if (m == NULL) { - ifp->if_oerrors++; - continue; - } - } - eh = mtod(m, struct ether_header *); - - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m); - ifp->if_oerrors++; - continue; - } - - /* TODO: PS */ - - ifp->if_opackets++; - BPF_MTAP(ifp, m); - - m = ieee80211_encap(ic, m, ni); - if (m == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; } - if (ic->ic_rawbpf != NULL) - bpf_mtap(ic->ic_rawbpf, m); - wh = mtod(m, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m); + k = ieee80211_crypto_encap(ni, m); if (k == NULL) { ieee80211_free_node(ni); m_freem(m); @@ -1437,6 +1439,8 @@ tbd->tbd_used++; idx = (idx + 1) % BWI_TX_NDESC; + ifp->if_opackets++; + if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; @@ -1459,8 +1463,7 @@ struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; int idx, error; - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { ieee80211_free_node(ni); m_freem(m); return ENETDOWN; @@ -1522,10 +1525,6 @@ BWI_ASSERT_LOCKED(sc); sc->sc_flags |= BWI_F_STOP; - if (statechg) - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - else - bwi_newstate_begin(sc, IEEE80211_S_INIT); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, @@ -1617,8 +1616,9 @@ i, txrx_intr_status[i]); if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) { - if_printf(ifp, "intr fatal TX/RX (%d) error 0x%08x\n", - i, txrx_intr_status[i]); + if_printf(ifp, + "%s: intr fatal TX/RX (%d) error 0x%08x\n", + __func__, i, txrx_intr_status[i]); txrx_error = 1; } } @@ -1637,7 +1637,7 @@ if (intr_status & BWI_INTR_PHY_TXERR) { if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) { - if_printf(ifp, "intr PHY TX error\n"); + if_printf(ifp, "%s: intr PHY TX error\n", __func__); taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task); BWI_UNLOCK(sc); return; @@ -1717,15 +1717,24 @@ static void bwi_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct bwi_softc *sc = ifp->if_softc; - int error; + struct bwi_softc *sc = ic->ic_ifp->if_softc; + const struct ieee80211_channel *c = ic->ic_curchan; + struct bwi_mac *mac; BWI_LOCK(sc); - error = bwi_set_chan(sc, ic->ic_curchan); - if (error) - if_printf(ifp, "can't set channel to %u\n", - ieee80211_chan2ieee(ic, ic->ic_curchan)); + KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, + ("current regwin type %d", sc->sc_cur_regwin->rw_type)); + mac = (struct bwi_mac *)sc->sc_cur_regwin; + bwi_rf_set_chan(mac, ieee80211_chan2ieee(ic, c), 0); + + /* + * Setup radio tap channel freq and flags + */ + sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = + htole16(c->ic_freq); + sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = + htole16(c->ic_flags & 0xffff); + BWI_UNLOCK(sc); } @@ -1734,42 +1743,37 @@ { } -static void -bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate) -{ - BWI_ASSERT_LOCKED(sc); - - callout_stop(&sc->sc_calib_ch); - callout_stop(&sc->sc_amrr_ch); - - bwi_led_newstate(sc, nstate); - - if (nstate == IEEE80211_S_INIT) - sc->sc_txpwrcb_type = BWI_TXPWR_INIT; -} - static int -bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { - struct ifnet *ifp = ic->ic_ifp; + struct bwi_vap *bvp = BWI_VAP(vap); + struct ifnet *ifp = vap->iv_ic->ic_ifp; struct bwi_softc *sc = ifp->if_softc; + const struct ieee80211_txparam *tp; struct bwi_mac *mac; struct ieee80211_node *ni; int error; BWI_LOCK(sc); - bwi_newstate_begin(sc, nstate); + callout_stop(&bvp->bv_amrr_ch); + callout_stop(&sc->sc_calib_ch); if (nstate == IEEE80211_S_INIT) + sc->sc_txpwrcb_type = BWI_TXPWR_INIT; + + bwi_led_newstate(sc, nstate); + + error = bvp->bv_newstate(vap, nstate, arg); + if (error != 0) goto back; - if (ic->ic_opmode == IEEE80211_M_MONITOR) { + if (vap->iv_opmode == IEEE80211_M_MONITOR) { /* Nothing to do */ } else if (nstate == IEEE80211_S_RUN) { - ni = ic->ic_bss; + ni = vap->iv_bss; - bwi_set_bssid(sc, ic->ic_bss->ni_bssid); + bwi_set_bssid(sc, vap->iv_bss->ni_bssid); KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, ("current regwin type %d", sc->sc_cur_regwin->rw_type)); @@ -1782,27 +1786,22 @@ #else sc->sc_txpwrcb_type = BWI_TXPWR_CALIB; #endif - - if (ic->ic_opmode == IEEE80211_M_STA) { + if (vap->iv_opmode == IEEE80211_M_STA) { /* fake a join to init the tx rate */ bwi_newassoc(ni, 1); } - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - /* start automatic rate control timer */ - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) - callout_reset(&sc->sc_amrr_ch, hz / 2, - bwi_amrr_timeout, sc); - } + /* start automatic rate control timer */ + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) + callout_reset(&bvp->bv_amrr_ch, hz / 2, + bwi_amrr_timeout, vap); + + callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc); } else { bwi_set_bssid(sc, bwi_zero_addr); } - back: - error = sc->sc_newstate(ic, nstate, arg); - - if (nstate == IEEE80211_S_RUN) - callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc); BWI_UNLOCK(sc); return error; @@ -1821,56 +1820,49 @@ static void bwi_newassoc(struct ieee80211_node *ni, int isnew) { - struct bwi_softc *sc = ni->ni_ic->ic_ifp->if_softc; + struct ieee80211vap *vap = ni->ni_vap; int i; - ieee80211_amrr_node_init(&sc->sc_amrr, &((struct bwi_node *)ni)->amn); + ieee80211_amrr_node_init(&BWI_VAP(vap)->bv_amrr, &BWI_NODE(ni)->amn); /* set rate to some reasonable initial value */ for (i = ni->ni_rates.rs_nrates - 1; i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; i--); - ni->ni_txrate = i; + ni->ni_txrate = i; } static void bwi_iter_func(void *arg, struct ieee80211_node *ni) { - struct bwi_softc *sc = arg; - struct bwi_node *bn = (struct bwi_node *)ni; + struct ieee80211vap *vap = arg; + struct bwi_node *bn = BWI_NODE(ni); - ieee80211_amrr_choose(&sc->sc_amrr, ni, &bn->amn); + ieee80211_amrr_choose(&BWI_VAP(vap)->bv_amrr, ni, &bn->amn); } static void bwi_amrr_timeout(void *arg) { - struct bwi_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = arg; + struct ieee80211com *ic = vap->iv_ic; + struct bwi_softc *sc = ic->ic_ifp->if_softc; BWI_ASSERT_LOCKED(sc); - if (ic->ic_opmode == IEEE80211_M_STA) - bwi_iter_func(sc, ic->ic_bss); + if (vap->iv_opmode == IEEE80211_M_STA) + bwi_iter_func(sc, vap->iv_bss); else - ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, sc); - callout_reset(&sc->sc_amrr_ch, hz / 2, bwi_amrr_timeout, sc); + ieee80211_iterate_nodes(&ic->ic_sta, bwi_iter_func, vap); + callout_reset(&BWI_VAP(vap)->bv_amrr_ch, hz / 2, bwi_amrr_timeout, vap); } static int bwi_media_change(struct ifnet *ifp) { -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct bwi_softc *sc = ifp->if_softc; - - BWI_LOCK(sc); - if (ieee80211_media_change(ifp) == ENETRESET && IS_RUNNING(ifp)) - bwi_init(ifp->if_softc); - BWI_UNLOCK(sc); - - return 0; -#undef IS_RUNNING + int error = ieee80211_media_change(ifp); + /* NB: only the fixed rate can change and that doesn't need a reset */ + return (error == ENETRESET ? 0 : error); } static int @@ -2649,42 +2641,6 @@ } static int -bwi_set_chan(struct bwi_softc *sc, struct ieee80211_channel *c) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct bwi_mac *mac; - uint16_t flags; - u_int chan; - - BWI_LOCK(sc); - - KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, - ("current regwin type %d", sc->sc_cur_regwin->rw_type)); - mac = (struct bwi_mac *)sc->sc_cur_regwin; - - chan = ieee80211_chan2ieee(ic, c); - - bwi_rf_set_chan(mac, chan, 0); - - /* - * Setup radio tap channel freq and flags - */ - if (IEEE80211_IS_CHAN_G(c)) - flags = IEEE80211_CHAN_G; - else - flags = IEEE80211_CHAN_B; - - sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = - htole16(c->ic_freq); - sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = - htole16(flags); - - BWI_UNLOCK(sc); - - return 0; -} - -static int bwi_rxeof(struct bwi_softc *sc, int end_idx) { struct bwi_ring_data *rd = &sc->sc_rx_rdata; @@ -2723,8 +2679,8 @@ buflen = le16toh(hdr->rxh_buflen); if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { - if_printf(ifp, "zero length data, hdr_extra %d\n", - hdr_extra); + if_printf(ifp, "%s: zero length data, hdr_extra %d\n", + __func__, hdr_extra); ifp->if_ierrors++; m_freem(m); goto next; @@ -2743,8 +2699,8 @@ rate = bwi_ds_plcp2rate(plcp); /* RX radio tap */ - if (sc->sc_drvbpf != NULL) - bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi); + if (bpf_peers_present(ifp->if_bpf)) + bwi_rx_radiotap(ifp, m, hdr, plcp, rate, rssi); m_adj(m, -IEEE80211_CRC_LEN); @@ -2752,10 +2708,13 @@ wh = mtod(m, struct ieee80211_frame_min *); ni = ieee80211_find_rxnode(ic, wh); - - type = ieee80211_input(ic, m, ni, rssi - BWI_NOISE_FLOOR, - BWI_NOISE_FLOOR, le16toh(hdr->rxh_tsf)); - ieee80211_free_node(ni); + if (ni != NULL) { + type = ieee80211_input(ni, m, rssi - BWI_NOISE_FLOOR, + BWI_NOISE_FLOOR, 0); + ieee80211_free_node(ni); + } else + type = ieee80211_input_all(ic, m, + rssi - BWI_NOISE_FLOOR, BWI_NOISE_FLOOR, 0); if (type == IEEE80211_FC0_TYPE_DATA) { rx_data = 1; sc->sc_rx_rate = rate; @@ -2887,8 +2846,8 @@ DELAY(1000); } if (i == NRETRY) { - if_printf(ifp, "wait for TX ring(%d) stable timed out\n", - ring_idx); + if_printf(ifp, "%s: wait for TX ring(%d) stable timed out\n", + __func__, ring_idx); } CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0); @@ -2901,7 +2860,8 @@ DELAY(1000); } if (i == NRETRY) - if_printf(ifp, "reset TX ring (%d) timed out\n", ring_idx); + if_printf(ifp, "%s: reset TX ring (%d) timed out\n", + __func__, ring_idx); #undef NRETRY @@ -3039,13 +2999,16 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, struct ieee80211_node *ni) { + struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = ic->ic_ifp; struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; struct bwi_mac *mac; struct bwi_txbuf_hdr *hdr; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; uint8_t rate, rate_fb; uint32_t mac_ctrl; uint16_t phy_ctrl; @@ -3069,9 +3032,14 @@ * Find TX rate */ bzero(tb->tb_rate_idx, sizeof(tb->tb_rate_idx)); + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; if (IEEE80211_IS_MULTICAST(wh->i_addr1)) - rate = rate_fb = ic->ic_mcast_rate; - else if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { + rate = rate_fb = tp->mcastrate; + else if (m->m_flags & M_EAPOL) + rate = rate_fb = tp->mgmtrate; + else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) + rate = rate_fb = tp->ucastrate; + else { rate = ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL; tb->tb_rate_idx[0] = ni->ni_txrate; @@ -3084,15 +3052,13 @@ rate_fb = rate; tb->tb_rate_idx[1] = tb->tb_rate_idx[0]; } - } else - rate = rate_fb = ic->ic_fixed_rate; - + } sc->sc_tx_rate = rate; /* * TX radio tap */ - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { sc->sc_tx_th.wt_flags = 0; if (wh->i_fc[1] & IEEE80211_FC1_WEP) sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; @@ -3103,7 +3069,7 @@ } sc->sc_tx_th.wt_rate = rate; - bpf_mtap2(sc->sc_drvbpf, &sc->sc_tx_th, sc->sc_tx_th_len, m); + bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m); } /* @@ -3111,7 +3077,7 @@ */ M_PREPEND(m, sizeof(*hdr), M_DONTWAIT); if (m == NULL) { - if_printf(ic->ic_ifp, "prepend TX header failed\n"); + if_printf(ifp, "%s: prepend TX header failed\n", __func__); return ENOBUFS; } hdr = mtod(m, struct bwi_txbuf_hdr *); @@ -3163,7 +3129,8 @@ error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m, bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); if (error && error != EFBIG) { - if_printf(ic->ic_ifp, "can't load TX buffer (1) %d\n", error); + if_printf(ifp, "%s: can't load TX buffer (1) %d\n", + __func__, error); goto back; } @@ -3172,7 +3139,8 @@ m_new = m_defrag(m, M_DONTWAIT); if (m_new == NULL) { - if_printf(ic->ic_ifp, "can't defrag TX buffer\n"); + if_printf(ifp, "%s: can't defrag TX buffer\n", + __func__); error = ENOBUFS; goto back; } else { @@ -3183,8 +3151,8 @@ >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802251650.m1PGoNGT096635>