From owner-p4-projects@FreeBSD.ORG Mon Mar 17 04:30:51 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 30B661065672; Mon, 17 Mar 2008 04:30:51 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DF797106566B for ; Mon, 17 Mar 2008 04:30:50 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id DF92A8FC16 for ; Mon, 17 Mar 2008 04:30:50 +0000 (UTC) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m2H4Uodo008983 for ; Mon, 17 Mar 2008 04:30:50 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m2H4UoUg008981 for perforce@freebsd.org; Mon, 17 Mar 2008 04:30:50 GMT (envelope-from sam@freebsd.org) Date: Mon, 17 Mar 2008 04:30:50 GMT Message-Id: <200803170430.m2H4UoUg008981@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 137892 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Mar 2008 04:30:51 -0000 http://perforce.freebsd.org/chv.cgi?CH=137892 Change 137892 by sam@sam_ebb on 2008/03/17 04:29:52 o implement protection o use common phy routines Note: untested Affected files ... .. //depot/projects/vap/sys/dev/ral/rt2560.c#19 edit .. //depot/projects/vap/sys/dev/ral/rt2560var.h#11 edit Differences ... ==== //depot/projects/vap/sys/dev/ral/rt2560.c#19 (text) ==== @@ -120,11 +120,9 @@ static void rt2560_beacon_update(struct ieee80211vap *, int item); static void rt2560_beacon_expire(struct rt2560_softc *); static void rt2560_wakeup_expire(struct rt2560_softc *); -static uint8_t rt2560_rxrate(struct rt2560_rx_desc *); static void rt2560_scan_start(struct ieee80211com *); static void rt2560_scan_end(struct ieee80211com *); static void rt2560_set_channel(struct ieee80211com *); -static uint8_t rt2560_plcp_signal(int); static void rt2560_setup_tx_desc(struct rt2560_softc *, struct rt2560_tx_desc *, uint32_t, int, int, int, bus_addr_t); @@ -132,8 +130,6 @@ struct ieee80211_node *); static int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); -static struct mbuf *rt2560_get_rts(struct rt2560_softc *, - struct ieee80211_frame *, uint16_t); static int rt2560_tx_data(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); static void rt2560_start(struct ifnet *); @@ -1272,7 +1268,8 @@ tap->wr_tsf = htole64(((uint64_t)tsf_hi << 32) | tsf_lo); tap->wr_flags = 0; - tap->wr_rate = rt2560_rxrate(desc); + tap->wr_rate = ieee80211_plcp2rate(desc->rate, + le32toh(desc->flags) & RT2560_RX_OFDM); tap->wr_antenna = sc->rx_ant; tap->wr_antsignal = RT2560_RSSI(sc, desc->rssi); @@ -1466,62 +1463,6 @@ #define RT2560_TXRX_TURNAROUND 10 /* us */ -/* - * This function is only used by the Rx radiotap code. - */ -static uint8_t -rt2560_rxrate(struct rt2560_rx_desc *desc) -{ - if (le32toh(desc->flags) & RT2560_RX_OFDM) { - /* reverse function of rt2560_plcp_signal */ - switch (desc->rate) { - case 0xb: return 12; - case 0xf: return 18; - case 0xa: return 24; - case 0xe: return 36; - case 0x9: return 48; - case 0xd: return 72; - case 0x8: return 96; - case 0xc: return 108; - } - } else { - if (desc->rate == 10) - return 2; - if (desc->rate == 20) - return 4; - if (desc->rate == 55) - return 11; - if (desc->rate == 110) - return 22; - } - return 2; /* should not get there */ -} - -static uint8_t -rt2560_plcp_signal(int rate) -{ - switch (rate) { - /* CCK rates (returned values are device-dependent) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* unsupported rates (should not get there) */ - default: return 0xff; - } -} - static void rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr) @@ -1540,11 +1481,11 @@ RT2560_LOGCWMAX(8)); /* setup PLCP fields */ - desc->plcp_signal = rt2560_plcp_signal(rate); + desc->plcp_signal = ieee80211_rate2plcp(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; - if (ieee80211_rate2phytype(sc->sc_currates, rate) == IEEE80211_T_OFDM) { + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { desc->flags |= htole32(RT2560_TX_OFDM); plcp_length = len & 0xfff; @@ -1689,7 +1630,7 @@ if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2560_TX_ACK; - dur = ieee80211_ack_duration(sc->sc_currates, + dur = ieee80211_ack_duration(sc->sc_rates, rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); @@ -1720,6 +1661,75 @@ } static int +rt2560_sendprot(struct rt2560_softc *sc, + const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) +{ + struct ieee80211com *ic = ni->ni_ic; + const struct ieee80211_frame *wh; + struct rt2560_tx_desc *desc; + struct rt2560_tx_data *data; + struct mbuf *mprot; + int protrate, ackrate, pktlen, flags, isshort, error; + uint16_t dur; + bus_dma_segment_t segs[RT2560_MAX_SCATTER]; + int nsegs; + + KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, + ("protection %d", prot)); + + wh = mtod(m, const struct ieee80211_frame *); + pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + + protrate = ieee80211_ctl_rate(sc->sc_rates, rate); + ackrate = ieee80211_ack_rate(sc->sc_rates, rate); + + isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; + dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); + + ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags = RT2560_TX_MORE_FRAG; + if (prot == IEEE80211_PROT_RTSCTS) { + /* NB: CTS is the same size as an ACK */ + dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags |= RT2560_TX_ACK; + mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); + } else { + mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); + } + if (mprot == NULL) { + /* XXX stat + msg */ + return ENOBUFS; + } + + desc = &sc->txq.desc[sc->txq.cur_encrypt]; + data = &sc->txq.data[sc->txq.cur_encrypt]; + + error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, + mprot, segs, &nsegs, 0); + if (error != 0) { + device_printf(sc->sc_dev, + "could not map mbuf (error %d)\n", error); + m_freem(mprot); + return error; + } + + data->m = mprot; + data->ni = ieee80211_ref_node(ni); + /* ctl frames are not taken into account for rssadapt */ + data->rix = IEEE80211_FIXED_RATE_NONE; + + rt2560_setup_tx_desc(sc, desc, flags, mprot->m_pkthdr.len, protrate, 1, + segs->ds_addr); + + bus_dmamap_sync(sc->txq.data_dmat, data->map, + BUS_DMASYNC_PREWRITE); + + sc->txq.queued++; + sc->txq.cur_encrypt = (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT; + + return 0; +} + +static int rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { @@ -1742,6 +1752,21 @@ return EINVAL; } + flags = 0; + if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) + flags |= RT2560_TX_ACK; + if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { + error = rt2560_sendprot(sc, m0, ni, + params->ibp_flags & IEEE80211_BPF_RTS ? + IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, + rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; + } + error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0, segs, &nsegs, 0); if (error != 0) { @@ -1766,10 +1791,6 @@ data->m = m0; data->ni = ni; - flags = 0; - if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) - flags |= RT2560_TX_ACK; - /* XXX need to setup descriptor ourself */ rt2560_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate, (params->ibp_flags & IEEE80211_BPF_CRYPTO) != 0, @@ -1790,37 +1811,6 @@ return 0; } -/* - * Build a RTS control frame. - */ -static struct mbuf * -rt2560_get_rts(struct rt2560_softc *sc, struct ieee80211_frame *wh, - uint16_t dur) -{ - struct ieee80211_frame_rts *rts; - struct mbuf *m; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - sc->sc_ic.ic_stats.is_tx_nobuf++; - device_printf(sc->sc_dev, "could not allocate RTS frame\n"); - return NULL; - } - - rts = mtod(m, struct ieee80211_frame_rts *); - - rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | - IEEE80211_FC0_SUBTYPE_RTS; - rts->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(uint16_t *)rts->i_dur = htole16(dur); - IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1); - IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2); - - m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts); - - return m; -} - static int rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) @@ -1837,7 +1827,7 @@ struct mbuf *mnew; bus_dma_segment_t segs[RT2560_MAX_SCATTER]; uint16_t dur; - uint32_t flags = 0; + uint32_t flags; int nsegs, rate, error; wh = mtod(m0, struct ieee80211_frame *); @@ -1871,68 +1861,22 @@ wh = mtod(m0, struct ieee80211_frame *); } - /* - * IEEE Std 802.11-1999, pp 82: "A STA shall use an RTS/CTS exchange - * for directed frames only when the length of the MPDU is greater - * than the length threshold indicated by [...]" ic_rtsthreshold. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - m0->m_pkthdr.len > vap->iv_rtsthreshold) { - struct mbuf *m; - uint16_t dur; - int rtsrate; - - rtsrate = ieee80211_ack_rate(sc->sc_currates, rate); - dur = ieee80211_compute_duration(sc->sc_currates, - m0->m_pkthdr.len + IEEE80211_CRC_LEN, - rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); - /* NB: assumes ACK and CTS are the same size */ - dur += ieee80211_ack_duration(sc->sc_currates, - rtsrate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); - dur += ieee80211_ack_duration(sc->sc_currates, - rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); - - m = rt2560_get_rts(sc, wh, dur); - - desc = &sc->txq.desc[sc->txq.cur_encrypt]; - data = &sc->txq.data[sc->txq.cur_encrypt]; - - error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, - m, segs, &nsegs, 0); - if (error != 0) { - device_printf(sc->sc_dev, - "could not map mbuf (error %d)\n", error); - m_freem(m); - m_freem(m0); - return error; + flags = 0; + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + int prot = IEEE80211_PROT_NONE; + if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) + prot = IEEE80211_PROT_RTSCTS; + else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) + prot = ic->ic_protmode; + if (prot != IEEE80211_PROT_NONE) { + error = rt2560_sendprot(sc, m0, ni, prot, rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; } - - /* avoid multiple free() of the same node for each fragment */ - ieee80211_ref_node(ni); - - data->m = m; - data->ni = ni; - - /* RTS frames are not taken into account for rssadapt */ - data->rix = IEEE80211_FIXED_RATE_NONE; - - rt2560_setup_tx_desc(sc, desc, RT2560_TX_ACK | - RT2560_TX_MORE_FRAG, m->m_pkthdr.len, rtsrate, 1, - segs->ds_addr); - - bus_dmamap_sync(sc->txq.data_dmat, data->map, - BUS_DMASYNC_PREWRITE); - - sc->txq.queued++; - sc->txq.cur_encrypt = - (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT; - - /* - * IEEE Std 802.11-1999: when an RTS/CTS exchange is used, the - * asynchronous data frame shall be transmitted after the CTS - * frame and a SIFS period. - */ - flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; } data = &sc->txq.data[sc->txq.cur_encrypt]; @@ -1993,7 +1937,7 @@ if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2560_TX_ACK; - dur = ieee80211_ack_duration(sc->sc_currates, + dur = ieee80211_ack_duration(sc->sc_rates, rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); } @@ -2025,12 +1969,6 @@ RAL_LOCK(sc); - /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - RAL_UNLOCK(sc); - return; - } - for (;;) { IFQ_DRV_DEQUEUE(&ifp->if_snd, m); if (m == NULL) @@ -2207,7 +2145,7 @@ chan = ieee80211_chan2ieee(ic, c); KASSERT(chan != 0 && chan != IEEE80211_CHAN_ANY, ("chan 0x%x", chan)); - sc->sc_currates = ieee80211_get_ratetable(c); + sc->sc_rates = ieee80211_get_ratetable(c); if (IEEE80211_IS_CHAN_2GHZ(c)) power = min(sc->txpow[chan - 1], 31); ==== //depot/projects/vap/sys/dev/ral/rt2560var.h#11 (text) ==== @@ -125,7 +125,7 @@ int sc_invalid; int sc_debug; - const struct ieee80211_rate_table *sc_currates; + const struct ieee80211_rate_table *sc_rates; /* * The same in both up to here * ------------------------------------------------