Module Name:    src
Committed By:   christos
Date:           Sun May  2 02:06:15 UTC 2010

Modified Files:
        src/sys/dev/pci: if_iwn.c

Log Message:
Replace iwn_tx from rev. 1.39 with a port of the current OpenBSD version.
Remove superfluous call to bpf_detach.
Add comments regarding porting issues and add a couple of cosmetic changes
that reduce the diffs to the OpenBSD version. From Sverre Froyen


To generate a diff of this commit:
cvs rdiff -u -r1.43 -r1.44 src/sys/dev/pci/if_iwn.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_iwn.c
diff -u src/sys/dev/pci/if_iwn.c:1.43 src/sys/dev/pci/if_iwn.c:1.44
--- src/sys/dev/pci/if_iwn.c:1.43	Wed Apr 28 11:56:24 2010
+++ src/sys/dev/pci/if_iwn.c	Sat May  1 22:06:15 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_iwn.c,v 1.43 2010/04/28 15:56:24 christos Exp $	*/
+/*	$NetBSD: if_iwn.c,v 1.44 2010/05/02 02:06:15 christos Exp $	*/
 /*	$OpenBSD: if_iwn.c,v 1.88 2010/04/10 08:37:36 damien Exp $	*/
 
 /*-
@@ -22,7 +22,7 @@
  * adapters.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.43 2010/04/28 15:56:24 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.44 2010/05/02 02:06:15 christos Exp $");
 
 #define IWN_USE_RBUF	/* Use local storage for RX */
 #undef IWN_HWCRYPTO	/* XXX does not even compile yet */
@@ -638,13 +638,17 @@
 #endif
 	iwn_radiotap_attach(sc);
 
-	/* timeout_set replaced by callout_init and callout_setfunc, above. */
+	/*
+	 * XXX for NetBSD, OpenBSD timeout_set replaced by
+	 * callout_init and callout_setfunc, above.
+	*/
 
 	if (pmf_device_register(self, NULL, iwn_resume))
 		pmf_class_network_register(self, ifp);
 	else
 		aprint_error_dev(self, "couldn't establish power handler\n");
 
+	/* XXX NetBSD add call to ieee80211_announce for dmesg. */
 	ieee80211_announce(ic);
 
 	return;
@@ -844,10 +848,6 @@
 	sysmon_envsys_destroy(sc->sc_sme);
 #endif
 
-	/* XXX verify that this is needed */
-	if (ifp != NULL)
-		bpf_detach(ifp);
-
 	ieee80211_ifdetach(&sc->sc_ic);
 	if_detach(ifp);
 
@@ -1153,6 +1153,7 @@
 	if (error != 0)
 		goto fail;
 
+	/* XXX Presumably needed because of missing BUS_DMA_ZERO, above. */
 	memset(dma->vaddr, 0, size);
 	bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
 
@@ -1651,6 +1652,7 @@
 	DPRINTF(("calib version=%u pa type=%u voltage=%u\n",
 	    hdr.version, hdr.pa_type, le16toh(hdr.volt)));
 	sc->calib_ver = hdr.version;
+
 	if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
 		/* Compute temperature offset. */
 		iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
@@ -1830,12 +1832,14 @@
 
 	switch (nstate) {
 	case IEEE80211_S_SCAN:
+		/* XXX Do not abort a running scan. */
 		if (sc->sc_flags & IWN_FLAG_SCANNING) {
 			aprint_error_dev(sc->sc_dev,
 			    "scan request while scanning ignored\n");
 			break;
 		}
 
+		/* XXX Not sure if call and flags are needed. */
 		ieee80211_node_table_reset(&ic->ic_scan);
 		ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
 		sc->sc_flags |= IWN_FLAG_SCANNING;
@@ -1954,9 +1958,6 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = ic->ic_ifp;
 	struct iwn_rx_ring *ring = &sc->rxq;
-#if 0
-	struct iwn_rbuf *rbuf;
-#endif
 	struct ieee80211_frame *wh;
 	struct ieee80211_node *ni;
 	struct mbuf *m, *m1;
@@ -2059,8 +2060,12 @@
 	wh = mtod(m, struct ieee80211_frame *);
 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
 
+	/* XXX OpenBSD adds decryption here (see also comments in iwn_tx). */
+	/* NetBSD does decryption in ieee80211_input. */
+
 	rssi = hal->get_rssi(stat);
 
+	/* XXX Added for NetBSD: scans never stop without it */
 	if (ic->ic_state == IEEE80211_S_SCAN)
 		iwn_fix_channel(ic, m);
 
@@ -2616,7 +2621,7 @@
 		tmp = le32toh(tmp);
 		if (tmp == 0xffffffff)	/* Shouldn't happen. */
 			tmp = 0;
-		else if (tmp & 0xc0000) /* Workaround a HW bug. */
+		else if (tmp & 0xc0000)	/* Workaround a HW bug. */
 			tmp |= 0x8000;
 		r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
 		r2 = 0;	/* Unused. */
@@ -2754,8 +2759,6 @@
 }
 #endif
 
-#if 0
-/* XXX figure out why this (new OpenBSD) version does not work (on NetBSD! */
 static int
 iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
 {
@@ -2782,10 +2785,10 @@
 	int hdrlen2;
 
 	wh = mtod(m, struct ieee80211_frame *);
-	hdrlen2 = ieee80211_hdrsize(wh);
+	hdrlen = ieee80211_anyhdrsize(wh);
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 
-	hdrlen = (IEEE80211_QOS_HAS_SEQ(wh)) ?
+	hdrlen2 = (IEEE80211_QOS_HAS_SEQ(wh)) ?
 	    sizeof (struct ieee80211_qosframe) :
 	    sizeof (struct ieee80211_frame);
 
@@ -2793,19 +2796,14 @@
 	    aprint_error_dev(sc->sc_dev, "hdrlen error (%d != %d)\n",
 		hdrlen, hdrlen2);
 
+	/* XXX OpenBSD sets a different tid when using QOS */
 	tid = 0;
-
-	/* Encrypt the frame if need be. */
-	/* XXX Should this be after bpf_mtap2 call, below (see OpenBSD code)? */
-	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
-		k = ieee80211_crypto_encap(ic, ni, m);
-		if (k == NULL) {
-			m_freem(m);
-			return ENOBUFS;
-		}
-		/* Packet header may have moved, reset our local pointer. */
-		wh = mtod(m, struct ieee80211_frame *);
+	if (IEEE80211_QOS_HAS_SEQ(wh)) {
+		cap = &ic->ic_wme.wme_chanParams;
+		noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
 	}
+	else
+		noack = 0;
 
 	ring = &sc->txq[ac];
 	desc = &ring->desc[ring->cur];
@@ -2822,273 +2820,23 @@
 		ridx = wn->ridx[ni->ni_txrate];
 	rinfo = &iwn_rates[ridx];
 
-	if (sc->sc_drvbpf != NULL) {
-		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
-
-		tap->wt_flags = 0;
-		tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
-		tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
-		tap->wt_rate = rinfo->rate;
-		tap->wt_hwqueue = ac;
-		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
-			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
-
-		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
-	}
-
-	totlen = m->m_pkthdr.len;
-
-	/* Prepare TX firmware command. */
-	cmd = &ring->cmd[ring->cur];
-	cmd->code = IWN_CMD_TX_DATA;
-	cmd->flags = 0;
-	cmd->qid = ring->qid;
-	cmd->idx = ring->cur;
-
-	tx = (struct iwn_cmd_data *)cmd->data;
-	/* NB: No need to clear tx, all fields are reinitialized here. */
-	tx->scratch = 0;	/* clear "scratch" area */
-
-	if (IEEE80211_QOS_HAS_SEQ(wh)) {
-		cap = &ic->ic_wme.wme_chanParams;
-		noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
-	}
-	else
-		noack = 0;
-
-	flags = 0;
-	if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-		/* Unicast frame with an ACK expected. */
-			flags |= IWN_TX_NEED_ACK;
-	}
-
-	if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
-		flags |= IWN_TX_MORE_FRAG;	/* Cannot happen yet. */
-
-	/* Check if frame must be protected using RTS/CTS or CTS-to-self. */
-	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-		/* NB: Group frames are sent using CCK in 802.11b/g. */
-		if (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
-			flags |= IWN_TX_NEED_RTS;
-		} else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
-		    ridx >= IWN_RIDX_OFDM6) {
-			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
-				flags |= IWN_TX_NEED_CTS;
-			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
-				flags |= IWN_TX_NEED_RTS;
-		}
-		if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
-			if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
-				/* 5000 autoselects RTS/CTS or CTS-to-self. */
-				flags &= ~(IWN_TX_NEED_RTS | IWN_TX_NEED_CTS);
-				flags |= IWN_TX_NEED_PROTECTION;
-			} else
-				flags |= IWN_TX_FULL_TXOP;
-		}
-	}
-
-	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
-	    type != IEEE80211_FC0_TYPE_DATA)
-		tx->id = hal->broadcast_id;
-	else
-		tx->id = wn->id;
-
-	if (type == IEEE80211_FC0_TYPE_MGT) {
-		uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
-
-#ifndef IEEE80211_STA_ONLY
-		/* Tell HW to set timestamp in probe responses. */
-		if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
-			flags |= IWN_TX_INSERT_TSTAMP;
-#endif
-		if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
-		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
-			tx->timeout = htole16(3);
-		else
-			tx->timeout = htole16(2);
-	} else
-		tx->timeout = htole16(0);
-
-	if (hdrlen & 3) {
-		/* First segment length must be a multiple of 4. */
-		flags |= IWN_TX_NEED_PADDING;
-		pad = 4 - (hdrlen & 3);
-	} else
-		pad = 0;
-
-	tx->len = htole16(totlen);
-	tx->tid = tid;
-	tx->rts_ntries = 60;
-	tx->data_ntries = 15;
-	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
-	tx->plcp = rinfo->plcp;
-	tx->rflags = rinfo->flags;
-	if (tx->id == hal->broadcast_id) {
-		/* Group or management frame. */
-		tx->linkq = 0;
-		/* XXX Alternate between antenna A and B? */
-		txant = IWN_LSB(sc->txchainmask);
-		tx->rflags |= IWN_RFLAG_ANT(txant);
-	} else {
-		tx->linkq = ni->ni_rates.rs_nrates - ni->ni_txrate - 1;
-		flags |= IWN_TX_LINKQ;	/* enable MRR */
-	}
-	/* Set physical address of "scratch area". */
-	tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
-	tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
-
-	/* Copy 802.11 header in TX command. */
-	memcpy((uint8_t *)(tx + 1), wh, hdrlen);
-
-	tx->flags = htole32(flags);
-
-	error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
-	    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
-	if (error != 0) {
-		if (error != EFBIG) {
-			aprint_error_dev(sc->sc_dev,
-			    "can't map mbuf (error %d)\n", error);
-			m_freem(m);
-			return error;
-		}
-		/* Too many DMA segments, linearize mbuf. */
-		MGETHDR(m1, M_DONTWAIT, MT_DATA);
-		if (m1 == NULL) {
-			m_freem(m);
-			return ENOBUFS;
-		}
-		if (m->m_pkthdr.len > MHLEN) {
-			MCLGET(m1, M_DONTWAIT);
-			if (!(m1->m_flags & M_EXT)) {
-				m_freem(m);
-				m_freem(m1);
-				return ENOBUFS;
-			}
-		}
-		m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, char *));
-		m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
-		m_freem(m);
-		m = m1;
-
-		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
-		    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
-		if (error != 0) {
-			aprint_error_dev(sc->sc_dev,
-			    "can't map mbuf (error %d)\n", error);
-			m_freem(m);
-			return error;
-		}
-	}
-
-	data->m = m;
-	data->ni = ni;
-
-	DPRINTFN(4, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
-	    ring->qid, ring->cur, m->m_pkthdr.len, data->map->dm_nsegs));
-
-	/* Fill TX descriptor. */
-	desc->nsegs = 1 + data->map->dm_nsegs;
-	/* First DMA segment is used by the TX command. */
-	desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
-	desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_paddr) |
-	    (4 + sizeof (*tx) + hdrlen + pad) << 4);
-	/* Other DMA segments are for data payload. */
-	seg = data->map->dm_segs;
-	for (i = 1; i <= data->map->dm_nsegs; i++) {
-		desc->segs[i].addr = htole32(IWN_LOADDR(seg->ds_addr));
-		desc->segs[i].len  = htole16(IWN_HIADDR(seg->ds_addr) |
-		    seg->ds_len << 4);
-		seg++;
-	}
-
-	bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
-	    BUS_DMASYNC_PREWRITE);
-	bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
-	    (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
-	    sizeof (*cmd), BUS_DMASYNC_PREWRITE);
-	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
-	    (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
-	    sizeof (*desc), BUS_DMASYNC_PREWRITE);
-
-#ifdef notyet
-	/* Update TX scheduler. */
-	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
-#endif
-
-	/* Kick TX ring. */
-	ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
-	IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
-
-	/* Mark TX ring as full if we reach a certain threshold. */
-	if (++ring->queued > IWN_TX_RING_HIMARK)
-		sc->qfullmsk |= 1 << ring->qid;
-
-	return 0;
-}
-#else
-/* This version is from the old NetBSD driver port */
-static int
-iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
-{
-	const struct iwn_hal *hal = sc->sc_hal;
-	struct ieee80211com *ic = &sc->sc_ic;
-	struct iwn_node *wn = (void *)ni;
-	struct iwn_tx_ring *ring;
-	struct iwn_tx_desc *desc;
-	struct iwn_tx_data *data;
-	struct iwn_tx_cmd *cmd;
-	struct iwn_cmd_data *tx;
-	const struct iwn_rate *rinfo;
-	struct ieee80211_frame *wh;
-	struct ieee80211_key *k = NULL;
-	const struct chanAccParams *cap;
-	struct mbuf *m1;
-	uint32_t flags;
-	u_int hdrlen;
-	bus_dma_segment_t *seg;
-	uint8_t ridx, txant, type;
-	int i, totlen, error, pad, noack;
-
-	wh = mtod(m, struct ieee80211_frame *);
-	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
-
-	/* JAF XXX two lines above were not in wpi. check we don't duplicate this */
-
-	if (IEEE80211_QOS_HAS_SEQ(wh)) {
-		hdrlen = sizeof (struct ieee80211_qosframe);
-		cap = &ic->ic_wme.wme_chanParams;
-		noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
-	} else {
-		hdrlen = sizeof (struct ieee80211_frame);
-		noack = 0;
-	}
-	
+	/* Encrypt the frame if need be. */
+	/*
+	 * XXX For now, NetBSD swaps the encryption and bpf sections
+	 * in order to match old code and other drivers. Tests with
+	 * tcpdump indicates that the order is irrelevant, however,
+	 * as bpf produces unencrypted data for both ordering choices.
+	 */
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 		k = ieee80211_crypto_encap(ic, ni, m);
 		if (k == NULL) {
 			m_freem(m);
 			return ENOBUFS;
 		}
-		/* packet header may have moved, reset our local pointer */
+		/* Packet header may have moved, reset our local pointer. */
 		wh = mtod(m, struct ieee80211_frame *);
 	}
-
-	ring = &sc->txq[ac];
-	desc = &ring->desc[ring->cur];
-	data = &ring->data[ring->cur];
-
-	/* Choose a TX rate index. */
-	if (type == IEEE80211_FC0_TYPE_MGT) {
-		/* mgmt frames are sent at the lowest available bit-rate */
-		ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
-		    IWN_RIDX_OFDM6 : IWN_RIDX_CCK1;
-	} else {
-		if (ic->ic_fixed_rate != -1) {
-			ridx = sc->fixed_ridx;
-		} else
-			ridx = wn->ridx[ni->ni_txrate];
-	}
-	rinfo = &iwn_rates[ridx];
+	totlen = m->m_pkthdr.len;
 
 	if (sc->sc_drvbpf != NULL) {
 		struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
@@ -3104,26 +2852,6 @@
 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
 	}
 
-	totlen = m->m_pkthdr.len;
-
-	/* Encrypt the frame if need be. */
-#ifdef IEEE80211_FC1_PROTECTED
-	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
-		/* Retrieve key for TX. */
-		k = ieee80211_get_txkey(ic, wh, ni);
-		if (k->k_cipher != IEEE80211_CIPHER_CCMP) {
-			/* Do software encryption. */
-			if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
-				return ENOBUFS;
-			/* 802.11 header may have moved. */
-			wh = mtod(m, struct ieee80211_frame *);
-			totlen = m->m_pkthdr.len;
-
-		} else	/* HW appends CCMP MIC. */
-			totlen += IEEE80211_CCMP_HDRLEN;
-	}
-#endif
-
 	/* Prepare TX firmware command. */
 	cmd = &ring->cmd[ring->cur];
 	cmd->code = IWN_CMD_TX_DATA;
@@ -3136,17 +2864,19 @@
 	tx->scratch = 0;	/* clear "scratch" area */
 
 	flags = 0;
-	if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-		flags |= IWN_TX_NEED_ACK;
-	} else if (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold)
-		flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		/* Unicast frame, check if an ACK is expected. */
+		if (!noack)
+			flags |= IWN_TX_NEED_ACK;
+	}
 
 #ifdef notyet
+	/* XXX NetBSD does not define IEEE80211_FC0_SUBTYPE_BAR */
 	if ((wh->i_fc[0] &
 	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
 	    (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR))
 		flags |= IWN_TX_IMM_BA;		/* Cannot happen yet. */
-#endif
+#endif          
 
 	if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
 		flags |= IWN_TX_MORE_FRAG;	/* Cannot happen yet. */
@@ -3184,18 +2914,17 @@
 
 #ifndef IEEE80211_STA_ONLY
 		/* Tell HW to set timestamp in probe responses. */
-		if ((subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) ||
-		    (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ))
+		/* XXX NetBSD rev 1.11 added probe requests here but */
+		/* probe requests do not take timestamps (from Bergamini). */
+		if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
 			flags |= IWN_TX_INSERT_TSTAMP;
 #endif
+		/* XXX NetBSD rev 1.11 and 1.20 added AUTH/DAUTH and RTS/CTS */
+		/* changes here. These are not needed (from Bergamini). */
 		if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
-		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ||
-		    subtype == IEEE80211_FC0_SUBTYPE_AUTH ||
-		    subtype == IEEE80211_FC0_SUBTYPE_DEAUTH) {
-			flags &= ~IWN_TX_NEED_RTS;
-			flags |= IWN_TX_NEED_CTS;
+		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
 			tx->timeout = htole16(3);
-		} else
+		else
 			tx->timeout = htole16(2);
 	} else
 		tx->timeout = htole16(0);
@@ -3207,19 +2936,8 @@
 	} else
 		pad = 0;
 
-#if 0
-	if (type == IEEE80211_FC0_TYPE_CTL) {
-		uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
-
-		/* tell h/w to set timestamp in probe responses */
-		if (subtype == 0x0080) /* linux says this is "back request" */
-			/* linux says (1 << 6) is IMM_BA_RSP_MASK */
-			flags |= (IWN_TX_NEED_ACK | (1 << 6));
-	}
-#endif
-
 	tx->len = htole16(totlen);
-	tx->tid = 0/* tid */;
+	tx->tid = tid;
 	tx->rts_ntries = 60;
 	tx->data_ntries = 15;
 	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
@@ -3240,51 +2958,23 @@
 	tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
 
 	/* Copy 802.11 header in TX command. */
+	/* XXX NetBSD changed this in rev 1.20 */
 	memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
 
 	/* Trim 802.11 header. */
-	m_adj(m, hdrlen);    
-	tx->security = 0;    
-
-#ifdef notyet
-	if (k != NULL && k->k_cipher == IEEE80211_CIPHER_CCMP) {
-		/* Trim 802.11 header and prepend CCMP IV. */
-		m_adj(m, hdrlen - IEEE80211_CCMP_HDRLEN);
-		ivp = mtod(m, uint8_t *);
-		k->k_tsc++;
-		ivp[0] = k->k_tsc;
-		ivp[1] = k->k_tsc >> 8;
-		ivp[2] = 0;
-		ivp[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;
-		ivp[4] = k->k_tsc >> 16;
-		ivp[5] = k->k_tsc >> 24;
-		ivp[6] = k->k_tsc >> 32;
-		ivp[7] = k->k_tsc >> 40;
-
-		tx->security = IWN_CIPHER_CCMP;
-		/* XXX flags |= IWN_TX_AMPDU_CCMP; */
-		memcpy(tx->key, k->k_key, k->k_len);
-
-		/* TX scheduler includes CCMP MIC len w/5000 Series. */
-		if (sc->hw_type != IWN_HW_REV_TYPE_4965)
-			totlen += IEEE80211_CCMP_MICLEN;
-	} else {
-		/* Trim 802.11 header. */
-		m_adj(m, hdrlen);
-		tx->security = 0;
-	}
-#endif
+	m_adj(m, hdrlen);
+	tx->security = 0;
 	tx->flags = htole32(flags);
 
 	error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
-	    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
-	if (error != 0 && error != EFBIG) {
-		aprint_error_dev(sc->sc_dev,
-		    "can't map mbuf (error %d)\n", error);
-		m_freem(m);
-		return error;
-	}
+	    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
 	if (error != 0) {
+		if (error != EFBIG) {
+			aprint_error_dev(sc->sc_dev,
+			    "can't map mbuf (error %d)\n", error);
+			m_freem(m);
+			return error;
+		}
 		/* Too many DMA segments, linearize mbuf. */
 		MGETHDR(m1, M_DONTWAIT, MT_DATA);
 		if (m1 == NULL) {
@@ -3305,7 +2995,7 @@
 		m = m1;
 
 		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
-		    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
+		    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
 		if (error != 0) {
 			aprint_error_dev(sc->sc_dev,
 			    "can't map mbuf (error %d)\n", error);
@@ -3346,7 +3036,7 @@
 
 #ifdef notyet
 	/* Update TX scheduler. */
-	sc->sc_hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
+	hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
 #endif
 
 	/* Kick TX ring. */
@@ -3359,7 +3049,6 @@
 
 	return 0;
 }
-#endif
 
 static void
 iwn_start(struct ifnet *ifp)
@@ -3481,6 +3170,7 @@
 #endif
 		/* FALLTHROUGH */
 	case SIOCSIFFLAGS:
+		/* XXX Added as it is in every NetBSD driver */
 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
 			break;
 		if (ifp->if_flags & IFF_UP) {
@@ -4119,8 +3809,9 @@
 	for (i = 0; i < 3; i++)
 		if (val - calib->rssi[i] > 15 * 20)
 			sc->chainmask &= ~(1 << i);
-		DPRINTF(("RX chains mask: theoretical=0x%x, actual=0x%x\n",
-		    sc->rxchainmask, sc->chainmask));
+	DPRINTF(("RX chains mask: theoretical=0x%x, actual=0x%x\n",
+	    sc->rxchainmask, sc->chainmask));
+
 	/* If none of the TX antennas are connected, keep at least one. */
 	if ((sc->chainmask & sc->txchainmask) == 0)
 		sc->chainmask |= IWN_LSB(sc->txchainmask);
@@ -4907,7 +4598,7 @@
 }
 #endif
 
-/* XXX Added for NetBSD */
+/* XXX Added for NetBSD (copied from rev 1.39). */
 
 static int
 iwn_wme_update(struct ieee80211com *ic)
@@ -6110,6 +5801,15 @@
 #endif
 }
 
+/*
+ * XXX MCLGETI alternative
+ *
+ * With IWN_USE_RBUF defined it uses the rbuf cache for receive buffers
+ * as long as there are available free buffers then it uses MEXTMALLOC.,
+ * Without IWN_USE_RBUF defined it uses MEXTMALLOC exclusively.
+ * The MCLGET4K code is used for testing an alternative mbuf cache.
+ */
+
 static struct mbuf *
 MCLGETIalt(struct iwn_softc *sc, int how,
     struct ifnet *ifp __unused, u_int size)

Reply via email to