Date: Thu, 15 Sep 2005 22:51:52 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 83716 for review Message-ID: <200509152251.j8FMpqPx028690@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=83716 Change 83716 by sam@sam_ebb on 2005/09/15 22:51:17 checkpoint driver conversion Affected files ... .. //depot/projects/wifi/sys/dev/ipw/if_ipw.c#6 edit .. //depot/projects/wifi/sys/dev/iwi/if_iwi.c#8 edit .. //depot/projects/wifi/sys/dev/ral/if_ral.c#5 edit .. //depot/projects/wifi/sys/dev/ral/if_ralvar.h#3 edit .. //depot/projects/wifi/sys/dev/usb/if_ural.c#5 edit .. //depot/projects/wifi/sys/dev/usb/if_uralvar.h#3 edit .. //depot/projects/wifi/sys/dev/wi/if_wi.c#18 edit Differences ... ==== //depot/projects/wifi/sys/dev/ipw/if_ipw.c#6 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.7 2005/07/08 19:30:29 damien Exp $ */ +/* $FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.13 2005/08/20 15:03:41 damien Exp $ */ /*- * Copyright (c) 2004, 2005 @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.7 2005/07/08 19:30:29 damien Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.13 2005/08/20 15:03:41 damien Exp $"); /*- * Intel(R) PRO/Wireless 2100 MiniPCI driver @@ -130,9 +130,7 @@ static int ipw_config(struct ipw_softc *); static void ipw_init(void *); static void ipw_stop(void *); -#ifdef IPW_DEBUG static int ipw_sysctl_stats(SYSCTL_HANDLER_ARGS); -#endif static int ipw_sysctl_radio(SYSCTL_HANDLER_ARGS); static uint32_t ipw_read_table1(struct ipw_softc *, uint32_t); static void ipw_write_table1(struct ipw_softc *, uint32_t, uint32_t); @@ -289,8 +287,7 @@ /* set device capabilities */ ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT | - IEEE80211_C_PMGT | IEEE80211_C_IBSS | IEEE80211_C_MONITOR | - IEEE80211_C_WPA; + IEEE80211_C_PMGT | IEEE80211_C_IBSS | IEEE80211_C_MONITOR; /* read MAC address from EEPROM */ val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0); @@ -350,12 +347,10 @@ CTLTYPE_INT | CTLFLAG_RD, sc, 0, ipw_sysctl_radio, "I", "radio transmitter switch state (0=off, 1=on)"); -#ifdef IPW_DEBUG SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats", CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, ipw_sysctl_stats, "S", "statistics"); -#endif SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell", @@ -735,7 +730,7 @@ if (ifp->if_flags & IFF_UP) { ifp->if_init(ifp->if_softc); - if (ifp->if_flags & IFF_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) ifp->if_start(ifp); } @@ -758,7 +753,7 @@ return error; } - if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) + if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) ipw_init(sc); IPW_UNLOCK(sc); @@ -828,7 +823,6 @@ { struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ifp->if_softc; - struct ieee80211_node *ni; uint8_t macaddr[IEEE80211_ADDR_LEN]; uint32_t len; @@ -839,16 +833,18 @@ len = IEEE80211_ADDR_LEN; ipw_read_table2(sc, IPW_INFO_CURRENT_BSSID, macaddr, &len); +#if 0 ni = ieee80211_find_node(&ic->ic_scan, macaddr); if (ni == NULL) break; ieee80211_ref_node(ni); ieee80211_sta_join(ic, ni); - ieee80211_node_authorize(ic, ni); + ieee80211_node_authorize(ni); if (ic->ic_opmode == IEEE80211_M_STA) ieee80211_notify_node_join(ic, ni, 1); +#endif break; case IEEE80211_S_INIT: @@ -1204,7 +1200,7 @@ /* remember what the firmware has processed */ sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1; - ifp->if_flags &= ~IFF_OACTIVE; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ipw_start(ifp); } @@ -1480,7 +1476,7 @@ if (sc->txfree < 1 + IPW_MAX_NSEG) { IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_flags |= IFF_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } @@ -1523,7 +1519,6 @@ ipw_watchdog(struct ifnet *ifp) { struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; ifp->if_timer = 0; @@ -1537,8 +1532,6 @@ } ifp->if_timer = 1; } - - ieee80211_watchdog(ic); } static int @@ -1554,10 +1547,10 @@ switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_flags & IFF_RUNNING)) + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) ipw_init(sc); } else { - if (ifp->if_flags & IFF_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) ipw_stop(sc); } break; @@ -1586,8 +1579,8 @@ } if (error == ENETRESET) { - if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == - (IFF_UP | IFF_RUNNING)) + if ((ifp->if_flags & IFF_UP) && + (ifp->if_drv_flags & IFF_DRV_RUNNING)) ipw_init(sc); error = 0; } @@ -1933,8 +1926,8 @@ printf("\n"); } #endif - error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_essid, - ic->ic_des_esslen); + error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_ssid[0].ssid, + ic->ic_des_ssid[0].len); if (error != 0) return error; @@ -2007,7 +2000,7 @@ #endif if (ic->ic_opmode == IEEE80211_M_IBSS) { - data = htole32(ic->ic_lintval); + data = htole32(ic->ic_bintval); DPRINTF(("Setting beacon interval to %u\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_BEACON_INTERVAL, &data, sizeof data); @@ -2096,8 +2089,8 @@ goto fail; } - ifp->if_flags &= ~IFF_OACTIVE; - ifp->if_flags |= IFF_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; return; @@ -2125,12 +2118,11 @@ sc->sc_tx_timer = 0; ifp->if_timer = 0; - ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); ieee80211_new_state(ic, IEEE80211_S_INIT, -1); } -#ifdef IPW_DEBUG static int ipw_sysctl_stats(SYSCTL_HANDLER_ARGS) { @@ -2150,7 +2142,6 @@ return SYSCTL_OUT(req, buf, sizeof buf); } -#endif static int ipw_sysctl_radio(SYSCTL_HANDLER_ARGS) ==== //depot/projects/wifi/sys/dev/iwi/if_iwi.c#8 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.8 2005/07/10 00:17:04 sam Exp $ */ +/* $FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 damien Exp $ */ /*- * Copyright (c) 2004, 2005 @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.8 2005/07/10 00:17:04 sam Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 damien Exp $"); /*- * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver @@ -109,7 +109,7 @@ static void iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *); static void iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *); static int iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *, - int); + int, bus_addr_t, bus_addr_t); static void iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *); static void iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *); static int iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *, @@ -119,13 +119,14 @@ 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_wme_update(struct ieee80211com *); static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t); static void iwi_fix_channel(struct ieee80211com *, struct mbuf *); static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int, struct iwi_frame *); static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *); static void iwi_rx_intr(struct iwi_softc *); -static void iwi_tx_intr(struct iwi_softc *); +static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *); static void iwi_intr(void *); static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int); static int iwi_tx_start(struct ifnet *, struct mbuf *, @@ -145,9 +146,7 @@ static int iwi_auth_and_assoc(struct iwi_softc *); static void iwi_init(void *); static void iwi_stop(void *); -#ifdef IWI_DEBUG static int iwi_sysctl_stats(SYSCTL_HANDLER_ARGS); -#endif static int iwi_sysctl_radio(SYSCTL_HANDLER_ARGS); static int iwi_probe(device_t); @@ -281,8 +280,31 @@ goto fail; } - if (iwi_alloc_tx_ring(sc, &sc->txq, IWI_TX_RING_COUNT) != 0) { - device_printf(dev, "could not allocate Tx ring\n"); + error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_TX_RING_COUNT, + IWI_CSR_TX1_RIDX, IWI_CSR_TX1_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 1\n"); + goto fail; + } + + error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_TX_RING_COUNT, + IWI_CSR_TX2_RIDX, IWI_CSR_TX2_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 2\n"); + goto fail; + } + + error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_TX_RING_COUNT, + IWI_CSR_TX3_RIDX, IWI_CSR_TX3_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 3\n"); + goto fail; + } + + error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_TX_RING_COUNT, + IWI_CSR_TX4_RIDX, IWI_CSR_TX4_WIDX); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring 4\n"); goto fail; } @@ -309,13 +331,18 @@ IFQ_SET_READY(&ifp->if_snd); ic->ic_ifp = ifp; + 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 = IEEE80211_C_WPA | IEEE80211_C_PMGT | IEEE80211_C_TXPMGT | - IEEE80211_C_SHPREAMBLE | IEEE80211_C_MONITOR; + ic->ic_caps = + IEEE80211_C_MONITOR | /* monitor mode supported */ + IEEE80211_C_TXPMGT | /* tx power management */ + IEEE80211_C_SHPREAMBLE | /* short preamble supported */ + IEEE80211_C_WPA | /* 802.11i */ + IEEE80211_C_WME; /* 802.11e */ /* read MAC address from EEPROM */ val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0); @@ -390,12 +417,10 @@ CTLTYPE_INT | CTLFLAG_RD, sc, 0, iwi_sysctl_radio, "I", "radio transmitter switch state (0=off, 1=on)"); -#ifdef IWI_DEBUG SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats", CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, iwi_sysctl_stats, "S", "statistics"); -#endif SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell", @@ -447,7 +472,10 @@ if_free(ifp); iwi_free_cmd_ring(sc, &sc->cmdq); - iwi_free_tx_ring(sc, &sc->txq); + iwi_free_tx_ring(sc, &sc->txq[0]); + iwi_free_tx_ring(sc, &sc->txq[1]); + iwi_free_tx_ring(sc, &sc->txq[2]); + iwi_free_tx_ring(sc, &sc->txq[3]); iwi_free_rx_ring(sc, &sc->rxq); if (sc->irq != NULL) { @@ -533,13 +561,16 @@ } static int -iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count) +iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count, + bus_addr_t csr_ridx, bus_addr_t csr_widx) { int i, error; ring->count = count; ring->queued = 0; ring->cur = ring->next = 0; + ring->csr_ridx = csr_ridx; + ring->csr_widx = csr_widx; error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, count * IWI_TX_DESC_SIZE, 1, @@ -788,7 +819,7 @@ if (ifp->if_flags & IFF_UP) { ifp->if_init(ifp->if_softc); - if (ifp->if_flags & IFF_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) ifp->if_start(ifp); } @@ -811,7 +842,7 @@ return error; } - if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) + if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) iwi_init(sc); IWI_UNLOCK(sc); @@ -890,11 +921,15 @@ struct iwi_softc *sc = ifp->if_softc; switch (nstate) { + case IEEE80211_S_INIT: + sc->flags &= ~IWI_FLAG_SCANNING; + break; + case IEEE80211_S_SCAN: if (sc->flags & IWI_FLAG_SCANNING) break; - ieee80211_node_table_reset(&ic->ic_scan); + ieee80211_scan_flush(ic); ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN; sc->flags |= IWI_FLAG_SCANNING; iwi_scan(sc); @@ -907,17 +942,11 @@ case IEEE80211_S_RUN: if (ic->ic_opmode == IEEE80211_M_IBSS) ieee80211_new_state(ic, IEEE80211_S_AUTH, -1); - else if (ic->ic_opmode == IEEE80211_M_MONITOR) - iwi_set_chan(sc, ic->ic_curchan); return sc->sc_newstate(ic, nstate, IEEE80211_FC0_SUBTYPE_ASSOC_RESP); - case IEEE80211_S_ASSOC: - break; - - case IEEE80211_S_INIT: - sc->flags &= ~IWI_FLAG_SCANNING; + default: break; } @@ -926,6 +955,74 @@ } /* + * WME parameters coming from IEEE 802.11e specification. These values are + * already declared in ieee80211_proto.c, but they are static so they can't + * be reused here. + */ +static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = { + { 0, 3, 5, 7, 0 }, /* WME_AC_BE */ + { 0, 3, 5, 10, 0 }, /* WME_AC_BK */ + { 0, 2, 4, 5, 188 }, /* WME_AC_VI */ + { 0, 2, 3, 4, 102 } /* WME_AC_VO */ +}; + +static const struct wmeParams iwi_wme_ofdm_params[WME_NUM_AC] = { + { 0, 3, 4, 6, 0 }, /* WME_AC_BE */ + { 0, 3, 4, 10, 0 }, /* WME_AC_BK */ + { 0, 2, 3, 4, 94 }, /* WME_AC_VI */ + { 0, 2, 2, 3, 47 } /* WME_AC_VO */ +}; + +static int +iwi_wme_update(struct ieee80211com *ic) +{ +#define IWI_EXP2(v) htole16((1 << (v)) - 1) +#define IWI_USEC(v) htole16(IEEE80211_TXOP_TO_US(v)) + struct iwi_softc *sc = ic->ic_ifp->if_softc; + struct iwi_wme_params wme[3]; + const struct wmeParams *wmep; + int ac; + + /* + * We shall not override firmware default WME values if WME is not + * actually enabled. + */ + if (!(ic->ic_flags & IEEE80211_F_WME)) + return 0; + + for (ac = 0; ac < WME_NUM_AC; ac++) { + /* set WME values for current operating mode */ + wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; + wme[0].aifsn[ac] = wmep->wmep_aifsn; + wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin); + wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax); + wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit); + wme[0].acm[ac] = wmep->wmep_acm; + + /* set WME values for CCK modulation */ + wmep = &iwi_wme_cck_params[ac]; + wme[1].aifsn[ac] = wmep->wmep_aifsn; + wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin); + wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax); + wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit); + wme[1].acm[ac] = wmep->wmep_acm; + + /* set WME values for OFDM modulation */ + wmep = &iwi_wme_ofdm_params[ac]; + wme[2].aifsn[ac] = wmep->wmep_aifsn; + wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin); + wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax); + wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit); + wme[2].acm[ac] = wmep->wmep_acm; + } + + DPRINTF(("Setting WME parameters\n")); + return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, wme, sizeof wme, 1); +#undef IWI_USEC +#undef IWI_EXP2 +} + +/* * Read 16 bits at address 'addr' from the serial EEPROM. */ static uint16_t @@ -1128,7 +1225,7 @@ switch (auth->state) { case IWI_AUTHENTICATED: - ieee80211_node_authorize(ic, ic->ic_bss); + ieee80211_node_authorize(ic->ic_bss); ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1); break; @@ -1157,7 +1254,11 @@ break; case IWI_DEASSOCIATED: +#if 0 ieee80211_begin_scan(ic, 1); +#else + ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); +#endif break; default: @@ -1222,36 +1323,36 @@ } static void -iwi_tx_intr(struct iwi_softc *sc) +iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; struct iwi_tx_data *data; uint32_t hw; - hw = CSR_READ_4(sc, IWI_CSR_TX1_RIDX); + hw = CSR_READ_4(sc, txq->csr_ridx); - for (; sc->txq.next != hw;) { - data = &sc->txq.data[sc->txq.next]; + for (; txq->next != hw;) { + data = &txq->data[txq->next]; - bus_dmamap_sync(sc->txq.data_dmat, data->map, + bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->txq.data_dmat, data->map); + bus_dmamap_unload(txq->data_dmat, data->map); m_freem(data->m); data->m = NULL; ieee80211_free_node(data->ni); data->ni = NULL; - DPRINTFN(15, ("tx done idx=%u\n", sc->txq.next)); + DPRINTFN(15, ("tx done idx=%u\n", txq->next)); ifp->if_opackets++; - sc->txq.queued--; - sc->txq.next = (sc->txq.next + 1) % IWI_TX_RING_COUNT; + txq->queued--; + txq->next = (txq->next + 1) % IWI_TX_RING_COUNT; } sc->sc_tx_timer = 0; - ifp->if_flags &= ~IFF_OACTIVE; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; iwi_start(ifp); } @@ -1288,14 +1389,23 @@ iwi_stop(sc); } - if (r & IWI_INTR_RX_DONE) - iwi_rx_intr(sc); - if (r & IWI_INTR_CMD_DONE) wakeup(sc); if (r & IWI_INTR_TX1_DONE) - iwi_tx_intr(sc); + iwi_tx_intr(sc, &sc->txq[0]); + + if (r & IWI_INTR_TX2_DONE) + iwi_tx_intr(sc, &sc->txq[1]); + + if (r & IWI_INTR_TX3_DONE) + iwi_tx_intr(sc, &sc->txq[2]); + + if (r & IWI_INTR_TX4_DONE) + iwi_tx_intr(sc, &sc->txq[3]); + + if (r & IWI_INTR_RX_DONE) + iwi_rx_intr(sc); /* acknowledge interrupts */ CSR_WRITE_4(sc, IWI_CSR_INTR, r); @@ -1336,21 +1446,48 @@ { struct iwi_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_frame wh; + struct ieee80211_frame *wh; struct ieee80211_key *k; + const struct chanAccParams *cap; + struct iwi_tx_ring *txq; struct iwi_tx_data *data; struct iwi_tx_desc *desc; struct mbuf *mnew; bus_dma_segment_t segs[IWI_MAX_NSEG]; - int nsegs, error, i; + int error, nsegs, hdrlen, ac, i, noack = 0; + + wh = mtod(m0, struct ieee80211_frame *); + + if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) { + hdrlen = sizeof (struct ieee80211_qosframe); + ac = M_WME_GETAC(m0); + cap = &ic->ic_wme.wme_chanParams; + noack = cap->cap_wmeParams[ac].wmep_noackPolicy; + } else { + hdrlen = sizeof (struct ieee80211_frame); + ac = WME_AC_BE; + } + + txq = &sc->txq[ac]; + if (txq->queued >= IWI_TX_RING_COUNT - 4) { + /* + * There is no place left in this ring. Perhaps in 802.11e, + * we should try to fallback to a lowest priority ring? + */ + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + m_freem(m0); + return 0; + } - bcopy(mtod(m0, struct ieee80211_frame *), &wh, sizeof (struct ieee80211_frame)); - if (wh.i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_WEP) { k = ieee80211_crypto_encap(ic, 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 *); } if (sc->sc_drvbpf != NULL) { @@ -1363,13 +1500,14 @@ bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); } - data = &sc->txq.data[sc->txq.cur]; - desc = &sc->txq.desc[sc->txq.cur]; + data = &txq->data[txq->cur]; + desc = &txq->desc[txq->cur]; - /* trim IEEE802.11 header */ - m_adj(m0, sizeof (struct ieee80211_frame)); + /* save and trim IEEE802.11 header */ + m_copydata(m0, 0, hdrlen, (caddr_t)&desc->wh); + m_adj(m0, hdrlen); - error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, m0, segs, + error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0, segs, &nsegs, 0); if (error != 0 && error != EFBIG) { device_printf(sc->sc_dev, "could not map mbuf (error %d)\n", @@ -1387,7 +1525,7 @@ } m0 = mnew; - error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, + error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0, segs, &nsegs, 0); if (error != 0) { device_printf(sc->sc_dev, @@ -1404,15 +1542,15 @@ desc->hdr.flags = IWI_HDR_FLAG_IRQ; desc->cmd = IWI_DATA_CMD_TX; desc->len = htole16(m0->m_pkthdr.len); - memcpy(&desc->wh, &wh, sizeof (struct ieee80211_frame)); desc->flags = 0; + desc->xflags = 0; - if (!IEEE80211_IS_MULTICAST(wh.i_addr1)) + if (!noack && !IEEE80211_IS_MULTICAST(desc->wh.i_addr1)) desc->flags |= IWI_DATA_FLAG_NEED_ACK; #if 0 if (ic->ic_flags & IEEE80211_F_PRIVACY) { - wh.i_fc[1] |= IEEE80211_FC1_WEP; + desc->wh.i_fc[1] |= IEEE80211_FC1_WEP; desc->wep_txkey = ic->ic_crypto.cs_def_txkey; } else #endif @@ -1421,22 +1559,24 @@ if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) desc->flags |= IWI_DATA_FLAG_SHPREAMBLE; + if (desc->wh.i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) + desc->xflags |= IWI_DATA_XFLAG_QOS; + desc->nseg = htole32(nsegs); for (i = 0; i < nsegs; i++) { desc->seg_addr[i] = htole32(segs[i].ds_addr); desc->seg_len[i] = htole32(segs[i].ds_len); } - bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map, - BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE); - DPRINTFN(5, ("sending data frame idx=%u len=%u nseg=%u\n", sc->txq.cur, - desc->len, desc->nseg)); + DPRINTFN(5, ("sending data frame txq=%u idx=%u len=%u nseg=%u\n", + ac, txq->cur, desc->len, desc->nseg)); - sc->txq.queued++; - sc->txq.cur = (sc->txq.cur + 1) % IWI_TX_RING_COUNT; - CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur); + txq->queued++; + txq->cur = (txq->cur + 1) % IWI_TX_RING_COUNT; + CSR_WRITE_4(sc, txq->csr_widx, txq->cur); return 0; } @@ -1462,12 +1602,6 @@ if (m0 == NULL) break; - if (sc->txq.queued >= IWI_TX_RING_COUNT - 4) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_flags |= IFF_OACTIVE; - break; - } - if (m0->m_len < sizeof (struct ether_header) && (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) continue; @@ -1478,6 +1612,10 @@ m_freem(m0); continue; } + if (ieee80211_classify(ic, m0, ni) != 0) { + m_freem(m0); + continue; + } BPF_MTAP(ifp, m0); m0 = ieee80211_encap(ic, m0, ni); @@ -1506,7 +1644,6 @@ iwi_watchdog(struct ifnet *ifp) { struct iwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; IWI_LOCK(sc); @@ -1524,8 +1661,6 @@ ifp->if_timer = 1; } - ieee80211_watchdog(ic); - IWI_UNLOCK(sc); } @@ -1542,10 +1677,10 @@ switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_flags & IFF_RUNNING)) + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) iwi_init(sc); } else { - if (ifp->if_flags & IFF_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) iwi_stop(sc); } break; @@ -1574,8 +1709,9 @@ } if (error == ENETRESET) { - if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == - (IFF_UP | IFF_RUNNING)) + if ((ifp->if_flags & IFF_UP) && + (ifp->if_drv_flags & IFF_DRV_RUNNING) && + (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) iwi_init(sc); error = 0; } @@ -2102,6 +2238,7 @@ struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211_wme_info wme; struct iwi_configuration config; struct iwi_associate assoc; struct iwi_rateset rs; @@ -2148,6 +2285,23 @@ if (error != 0) return error; + if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) { + wme.wme_id = IEEE80211_ELEMID_VENDOR; + wme.wme_len = sizeof (struct ieee80211_wme_info) - 2; + wme.wme_oui[0] = 0x00; + wme.wme_oui[1] = 0x50; + wme.wme_oui[2] = 0xf2; + wme.wme_type = WME_OUI_TYPE; + wme.wme_subtype = WME_INFO_OUI_SUBTYPE; + wme.wme_version = WME_VERSION; + wme.wme_info = 0; + + DPRINTF(("Setting WME IE (len=%u)\n", wme.wme_len)); + error = iwi_cmd(sc, IWI_CMD_SET_WMEIE, &wme, sizeof wme, 1); + if (error != 0) + return error; + } + if (ic->ic_opt_ie != NULL) { DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len)); error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie, @@ -2168,8 +2322,10 @@ assoc.chan = ieee80211_chan2ieee(ic, ic->ic_bsschan); if (ni->ni_authmode == IEEE80211_AUTH_SHARED) assoc.auth = ic->ic_crypto.cs_def_txkey << 4 | IWI_AUTH_SHARED; + if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) + assoc.policy |= htole16(IWI_POLICY_WME); if (ic->ic_opt_ie != NULL) - assoc.policy |= htole16(IWI_POLICY_OPTIE); + assoc.policy |= htole16(IWI_POLICY_WPA); memcpy(assoc.tstamp, ni->ni_tstamp.data, 8); if (ic->ic_opmode == IEEE80211_M_IBSS) @@ -2240,21 +2396,21 @@ CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, sc->cmdq.count); CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur); - CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq[0].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq[0].count); + CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq[0].cur); - CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq[1].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq[1].count); + CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq[1].cur); - CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq[2].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq[2].count); + CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq[2].cur); - CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq.physaddr); - CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq.count); - CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq.cur); + CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq[3].physaddr); + CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq[3].count); + CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq[3].cur); for (i = 0; i < sc->rxq.count; i++) { data = &sc->rxq.data[i]; @@ -2275,13 +2431,14 @@ goto fail; } - if (ic->ic_opmode == IEEE80211_M_MONITOR) + 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 - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - ifp->if_flags &= ~IFF_OACTIVE; - ifp->if_flags |= IFF_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; return; @@ -2302,17 +2459,19 @@ /* reset rings */ iwi_reset_cmd_ring(sc, &sc->cmdq); - iwi_reset_tx_ring(sc, &sc->txq); + iwi_reset_tx_ring(sc, &sc->txq[0]); + iwi_reset_tx_ring(sc, &sc->txq[1]); + iwi_reset_tx_ring(sc, &sc->txq[2]); + iwi_reset_tx_ring(sc, &sc->txq[3]); iwi_reset_rx_ring(sc, &sc->rxq); sc->sc_tx_timer = 0; ifp->if_timer = 0; - ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); ieee80211_new_state(ic, IEEE80211_S_INIT, -1); } -#ifdef IWI_DEBUG static int iwi_sysctl_stats(SYSCTL_HANDLER_ARGS) { @@ -2329,7 +2488,6 @@ return SYSCTL_OUT(req, buf, sizeof buf); } -#endif static int iwi_sysctl_radio(SYSCTL_HANDLER_ARGS) ==== //depot/projects/wifi/sys/dev/ral/if_ral.c#5 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/ral/if_ral.c,v 1.10 2005/07/10 22:25:44 sam Exp $ */ +/* $FreeBSD: src/sys/dev/ral/if_ral.c,v 1.15 2005/08/21 14:16:19 damien Exp $ */ /*- * Copyright (c) 2005 @@ -18,7 +18,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.10 2005/07/10 22:25:44 sam Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.15 2005/08/21 14:16:19 damien Exp $"); /*- * Ralink Technology RT2500 chipset driver @@ -91,7 +91,6 @@ static struct ieee80211_node *ral_node_alloc( struct ieee80211_node_table *); static int ral_media_change(struct ifnet *); -static void ral_next_scan(void *); static void ral_iter_func(void *, struct ieee80211_node *); static void ral_update_rssadapt(void *); static int ral_newstate(struct ieee80211com *, @@ -105,7 +104,7 @@ static void ral_beacon_expire(struct ral_softc *); static void ral_wakeup_expire(struct ral_softc *); static void ral_intr(void *); -static int ral_ack_rate(int); +static int ral_ack_rate(struct ieee80211com *, int); static uint16_t ral_txtime(int, int, uint32_t); static uint8_t ral_plcp_signal(int); static void ral_setup_tx_desc(struct ral_softc *, @@ -350,7 +349,6 @@ mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); - callout_init(&sc->scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0); callout_init(&sc->rssadapt_ch, CALLOUT_MPSAFE); /* retrieve RT2560 rev. no */ @@ -533,7 +531,6 @@ struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; - callout_stop(&sc->scan_ch); callout_stop(&sc->rssadapt_ch); bpfdetach(ifp); @@ -921,27 +918,14 @@ if (error != ENETRESET) return error; - if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) + if ((ifp->if_flags & IFF_UP) && + (ifp->if_drv_flags & IFF_DRV_RUNNING)) ral_init(sc); return 0; } /* - * This function is called periodically (every 200ms) during scanning to - * switch from one channel to another. - */ -static void -ral_next_scan(void *arg) -{ - struct ral_softc *sc = arg; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509152251.j8FMpqPx028690>