PERFORCE change 137892 for review

Sam Leffler sam at FreeBSD.org
Mon Mar 17 04:30:51 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=137892

Change 137892 by sam at 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
  * ------------------------------------------------


More information about the p4-projects mailing list