Beispiel #1
0
int
iwl_tx_data(struct iwl_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
	struct iwl_ops *ops = &sc->ops;
	const struct ieee80211_txparam *tp;
	struct ieee80211vap *vap = ni->ni_vap;
	struct ieee80211com *ic = ni->ni_ic;
	struct iwl_node *wn = (void *)ni;
	struct iwl_tx_ring *ring;
	struct iwl_tx_desc *desc;
	struct iwl_tx_data *data;
	struct iwl_tx_cmd *cmd;
	struct iwl_cmd_data *tx;
	struct ieee80211_frame *wh;
	struct ieee80211_key *k = NULL;
	struct mbuf *m1;
	uint32_t flags;
	uint16_t qos;
	u_int hdrlen;
	bus_dma_segment_t *seg, segs[IWL_MAX_SCATTER];
	uint8_t tid, ridx, txant, type;
	int ac, i, totlen, error, pad, nsegs = 0, rate;
	struct iwl_vap *ivp = IWL_VAP(vap);

	IWL_LOCK_ASSERT(sc);

	wh = mtod(m, struct ieee80211_frame *);
	hdrlen = ieee80211_anyhdrsize(wh);
	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;

	/* Select EDCA Access Category and TX ring for this frame. */
	if (IEEE80211_QOS_HAS_SEQ(wh)) {
		qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
		tid = qos & IEEE80211_QOS_TID;
	} else {
		qos = 0;
		tid = 0;
	}

	if(ivp->ctx == IWL_RXON_PAN_CTX)
		ac = iwl_pan_ac_to_queue[M_WME_GETAC(m)];
	else
		ac = iwl_bss_ac_to_queue[M_WME_GETAC(m)];

	if (IEEE80211_QOS_HAS_SEQ(wh) &&
	    IEEE80211_AMPDU_RUNNING(&ni->ni_tx_ampdu[ac])) {
		struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[ac];

		ring = &sc->txq[*(int *)tap->txa_private];
		*(uint16_t *)wh->i_seq =
		    htole16(ni->ni_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT);
		ni->ni_txseqs[tid]++;
	} else 
		ring = &sc->txq[ac];

	desc = &ring->desc[ring->cur];
	data = &ring->data[ring->cur];

	/* Choose a TX rate index. */
	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
	if (type == IEEE80211_FC0_TYPE_MGT)
		rate = tp->mgmtrate;
	else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
		rate = tp->mcastrate;
	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
		rate = tp->ucastrate;
	else
		rate = ni->ni_txrate;

	ridx = ic->ic_rt->rateCodeToIndex[rate];

	/* Encrypt the frame if need be. */
	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
		/* Retrieve key for TX. */
		k = ieee80211_crypto_encap(ni, m);
		if (k == NULL) {
			m_freem(m);
			return ENOBUFS;
		}
		/* 802.11 header may have moved. */
		wh = mtod(m, struct ieee80211_frame *);
	}
Beispiel #2
0
static int
rtwn_tx_data(struct rtwn_softc *sc, struct ieee80211_node *ni,
    struct mbuf *m)
{
	const struct ieee80211_txparam *tp;
	struct ieee80211com *ic = &sc->sc_ic;
	struct ieee80211vap *vap = ni->ni_vap;
	struct ieee80211_key *k = NULL;
	struct ieee80211_channel *chan;
	struct ieee80211_frame *wh;
	struct rtwn_tx_desc_common *txd;
	struct rtwn_tx_buf buf;
	uint8_t rate, ridx, type;
	u_int cipher;
	int ismcast, maxretry;

	RTWN_ASSERT_LOCKED(sc);

	wh = mtod(m, struct ieee80211_frame *);
	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
	ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);

	chan = (ni->ni_chan != IEEE80211_CHAN_ANYC) ?
		ni->ni_chan : ic->ic_curchan;
	tp = &vap->iv_txparms[ieee80211_chan2mode(chan)];
	maxretry = tp->maxretry;

	/* Choose a TX rate index. */
	if (type == IEEE80211_FC0_TYPE_MGT)
		rate = tp->mgmtrate;
	else if (ismcast)
		rate = tp->mcastrate;
	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
		rate = tp->ucastrate;
	else if (m->m_flags & M_EAPOL)
		rate = tp->mgmtrate;
	else {
		if (sc->sc_ratectl == RTWN_RATECTL_NET80211) {
			/* XXX pass pktlen */
			(void) ieee80211_ratectl_rate(ni, NULL, 0);
			rate = ni->ni_txrate;
		} else {
			if (ni->ni_flags & IEEE80211_NODE_HT)
				rate = IEEE80211_RATE_MCS | 0x4; /* MCS4 */
			else if (ic->ic_curmode != IEEE80211_MODE_11B)
				rate = ridx2rate[RTWN_RIDX_OFDM36];
			else
				rate = ridx2rate[RTWN_RIDX_CCK55];
		}
	}

	ridx = rate2ridx(rate);

	cipher = IEEE80211_CIPHER_NONE;
	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
		k = ieee80211_crypto_encap(ni, m);
		if (k == NULL) {
			device_printf(sc->sc_dev,
			    "ieee80211_crypto_encap returns NULL.\n");
			return (ENOBUFS);
		}
		if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT))
			cipher = k->wk_cipher->ic_cipher;

		/* in case packet header moved, reset pointer */
		wh = mtod(m, struct ieee80211_frame *);
	}