Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/ral/rt2661.c
Show First 20 Lines • Show All 1,355 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static int | static int | ||||
rt2661_sendprot(struct rt2661_softc *sc, int ac, | rt2661_sendprot(struct rt2661_softc *sc, int ac, | ||||
const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) | const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) | ||||
{ | { | ||||
struct ieee80211com *ic = ni->ni_ic; | struct ieee80211com *ic = ni->ni_ic; | ||||
struct rt2661_tx_ring *txq = &sc->txq[ac]; | struct rt2661_tx_ring *txq = &sc->txq[ac]; | ||||
const struct ieee80211_frame *wh; | |||||
struct rt2661_tx_desc *desc; | struct rt2661_tx_desc *desc; | ||||
struct rt2661_tx_data *data; | struct rt2661_tx_data *data; | ||||
struct mbuf *mprot; | struct mbuf *mprot; | ||||
int protrate, ackrate, pktlen, flags, isshort, error; | int protrate, flags, error; | ||||
uint16_t dur; | |||||
bus_dma_segment_t segs[RT2661_MAX_SCATTER]; | bus_dma_segment_t segs[RT2661_MAX_SCATTER]; | ||||
int nsegs; | int nsegs; | ||||
KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, | mprot = ieee80211_alloc_prot(ni, m, rate, prot); | ||||
("protection %d", prot)); | |||||
wh = mtod(m, const struct ieee80211_frame *); | |||||
pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; | |||||
protrate = ieee80211_ctl_rate(ic->ic_rt, rate); | |||||
ackrate = ieee80211_ack_rate(ic->ic_rt, rate); | |||||
isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; | |||||
dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) | |||||
+ ieee80211_ack_duration(ic->ic_rt, rate, isshort); | |||||
flags = RT2661_TX_MORE_FRAG; | |||||
if (prot == IEEE80211_PROT_RTSCTS) { | |||||
/* NB: CTS is the same size as an ACK */ | |||||
dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort); | |||||
flags |= RT2661_TX_NEED_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) { | if (mprot == NULL) { | ||||
/* XXX stat + msg */ | if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1); | ||||
device_printf(sc->sc_dev, | |||||
"could not allocate mbuf for protection mode %d\n", prot); | |||||
return ENOBUFS; | return ENOBUFS; | ||||
} | } | ||||
data = &txq->data[txq->cur]; | data = &txq->data[txq->cur]; | ||||
desc = &txq->desc[txq->cur]; | desc = &txq->desc[txq->cur]; | ||||
error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, mprot, segs, | error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, mprot, segs, | ||||
&nsegs, 0); | &nsegs, 0); | ||||
if (error != 0) { | if (error != 0) { | ||||
device_printf(sc->sc_dev, | device_printf(sc->sc_dev, | ||||
"could not map mbuf (error %d)\n", error); | "could not map mbuf (error %d)\n", error); | ||||
m_freem(mprot); | m_freem(mprot); | ||||
return error; | return error; | ||||
} | } | ||||
data->m = mprot; | data->m = mprot; | ||||
data->ni = ieee80211_ref_node(ni); | data->ni = ieee80211_ref_node(ni); | ||||
/* ctl frames are not taken into account for amrr */ | /* ctl frames are not taken into account for amrr */ | ||||
data->rix = IEEE80211_FIXED_RATE_NONE; | data->rix = IEEE80211_FIXED_RATE_NONE; | ||||
protrate = ieee80211_ctl_rate(ic->ic_rt, rate); | |||||
flags = RT2661_TX_MORE_FRAG; | |||||
if (prot == IEEE80211_PROT_RTSCTS) | |||||
flags |= RT2661_TX_NEED_ACK; | |||||
rt2661_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, | rt2661_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, | ||||
protrate, segs, 1, ac); | protrate, segs, 1, ac); | ||||
bus_dmamap_sync(txq->data_dmat, data->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); | bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE); | ||||
txq->queued++; | txq->queued++; | ||||
▲ Show 20 Lines • Show All 1,372 Lines • Show Last 20 Lines |