Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Sep 2005 18:23:22 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 83793 for review
Message-ID:  <200509171823.j8HINMZ8048157@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=83793

Change 83793 by rwatson@rwatson_zoo on 2005/09/17 18:22:52

	Integrate netsmp branch from FreeBSD CVS.

Affected files ...

.. //depot/projects/netsmp/src/sys/dev/iwi/if_iwi.c#6 integrate
.. //depot/projects/netsmp/src/sys/dev/iwi/if_iwireg.h#3 integrate
.. //depot/projects/netsmp/src/sys/dev/iwi/if_iwivar.h#3 integrate

Differences ...

==== //depot/projects/netsmp/src/sys/dev/iwi/if_iwi.c#6 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 damien Exp $	*/
+/*	$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.16 2005/09/17 12:41:05 damien Exp $	*/
 
 /*-
  * Copyright (c) 2004, 2005
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 damien Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.16 2005/09/17 12:41:05 damien Exp $");
 
 /*-
  * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
@@ -121,6 +121,7 @@
 static int	iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
 static int	iwi_wme_update(struct ieee80211com *);
 static uint16_t	iwi_read_prom_word(struct iwi_softc *, uint8_t);
+static int	iwi_find_txnode(struct iwi_softc *, const uint8_t *);
 static void	iwi_fix_channel(struct ieee80211com *, struct mbuf *);
 static void	iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
 		    struct iwi_frame *);
@@ -130,7 +131,7 @@
 static void	iwi_intr(void *);
 static int	iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t, int);
 static int	iwi_tx_start(struct ifnet *, struct mbuf *,
-		    struct ieee80211_node *);
+		    struct ieee80211_node *, int);
 static void	iwi_start(struct ifnet *);
 static void	iwi_watchdog(struct ifnet *);
 static int	iwi_ioctl(struct ifnet *, u_long, caddr_t);
@@ -316,7 +317,6 @@
 	if (ifp == NULL) {
 		device_printf(dev, "can not if_alloc()\n");
 		goto fail;
-		return (ENOSPC);
 	}
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
@@ -337,6 +337,7 @@
 
 	/* set device capabilities */
 	ic->ic_caps =
+	    IEEE80211_C_IBSS |		/* IBSS mode supported */
 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
 	    IEEE80211_C_TXPMGT |	/* tx power management */
 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
@@ -463,11 +464,11 @@
 
 	iwi_free_firmware(sc);
 
-	if (ifp != NULL)
+	if (ifp != NULL) {
 		bpfdetach(ifp);
-	ieee80211_ifdetach(ic);
-	if (ifp != NULL)
+		ieee80211_ifdetach(ic);
 		if_free(ifp);
+	}
 
 	iwi_free_cmd_ring(sc, &sc->cmdq);
 	iwi_free_tx_ring(sc, &sc->txq[0]);
@@ -922,6 +923,7 @@
 		if (sc->flags & IWI_FLAG_SCANNING)
 			break;
 
+		sc->nsta = 0;	/* flush IBSS nodes */
 		ieee80211_node_table_reset(&ic->ic_scan);
 		ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
 		sc->flags |= IWI_FLAG_SCANNING;
@@ -1077,6 +1079,37 @@
 }
 
 /*
+ * This is only used for IBSS mode where the firmware expect an index to an
+ * internal node table instead of a destination address.
+ */
+static int
+iwi_find_txnode(struct iwi_softc *sc, const uint8_t *macaddr)
+{
+	struct iwi_node node;
+	int i;
+
+	for (i = 0; i < sc->nsta; i++)
+		if (IEEE80211_ADDR_EQ(sc->sta[i], macaddr))
+			return i;	/* already existing node */
+
+	if (i == IWI_MAX_NODE)
+		return -1;	/* no place left in neighbor table */
+
+	/* save this new node in our softc table */
+	IEEE80211_ADDR_COPY(sc->sta[i], macaddr);
+	sc->nsta = i;
+
+	/* write node information into NIC memory */
+	memset(&node, 0, sizeof node);
+	IEEE80211_ADDR_COPY(node.bssid, macaddr);
+
+	CSR_WRITE_REGION_1(sc, IWI_CSR_NODE_BASE + i * sizeof node,
+	    (uint8_t *)&node, sizeof node);
+
+	return i;
+}
+
+/*
  * XXX: Hack to set the current channel to the value advertised in beacons or
  * probe responses. Only used during AP detection.
  */
@@ -1436,41 +1469,38 @@
 }
 
 static int
-iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
+iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni,
+    int ac)
 {
 	struct iwi_softc *sc = ifp->if_softc;
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ieee80211_frame *wh;
 	struct ieee80211_key *k;
 	const struct chanAccParams *cap;
-	struct iwi_tx_ring *txq;
+	struct iwi_tx_ring *txq = &sc->txq[ac];
 	struct iwi_tx_data *data;
 	struct iwi_tx_desc *desc;
 	struct mbuf *mnew;
 	bus_dma_segment_t segs[IWI_MAX_NSEG];
-	int error, nsegs, hdrlen, ac, i, noack = 0;
+	int error, nsegs, hdrlen, i, station = 0, noack = 0;
 
 	wh = mtod(m0, struct ieee80211_frame *);
 
 	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
 		hdrlen = sizeof (struct ieee80211_qosframe);
-		ac = M_WME_GETAC(m0);
 		cap = &ic->ic_wme.wme_chanParams;
 		noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
-	} else {
+	} else
 		hdrlen = sizeof (struct ieee80211_frame);
-		ac = WME_AC_BE;
-	}
 
-	txq = &sc->txq[ac];
-	if (txq->queued >= IWI_TX_RING_COUNT - 4) {
-		/*
-		 * There is no place left in this ring.  Perhaps in 802.11e,
-		 * we should try to fallback to a lowest priority ring?
-		 */
-		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-		m_freem(m0);
-		return 0;
+	if (ic->ic_opmode == IEEE80211_M_IBSS) {
+		station = iwi_find_txnode(sc, wh->i_addr1);
+		if (station == -1) {
+			m_freem(m0);
+			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
+			return 0;
+		}
 	}
 
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
@@ -1534,6 +1564,7 @@
 
 	desc->hdr.type = IWI_HDR_TYPE_DATA;
 	desc->hdr.flags = IWI_HDR_FLAG_IRQ;
+	desc->station = station;
 	desc->cmd = IWI_DATA_CMD_TX;
 	desc->len = htole16(m0->m_pkthdr.len);
 	desc->flags = 0;
@@ -1583,6 +1614,7 @@
 	struct mbuf *m0;
 	struct ether_header *eh;
 	struct ieee80211_node *ni;
+	int ac;
 
 	IWI_LOCK(sc);
 
@@ -1597,31 +1629,50 @@
 			break;
 
 		if (m0->m_len < sizeof (struct ether_header) &&
-		    (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL)
+		    (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) {
+			ifp->if_oerrors++;
 			continue;
-
+		}
 		eh = mtod(m0, struct ether_header *);
 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
 		if (ni == NULL) {
 			m_freem(m0);
+			ifp->if_oerrors++;
 			continue;
 		}
+
+		/* classify mbuf so we can find which tx ring to use */
 		if (ieee80211_classify(ic, m0, ni) != 0) {
 			m_freem(m0);
+			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
 			continue;
 		}
+
+		/* no QoS encapsulation for EAPOL frames */
+		ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
+		    M_WME_GETAC(m0) : WME_AC_BE;
+
+		if (sc->txq[ac].queued > IWI_TX_RING_COUNT - 8) {
+			/* there is no place left in this ring */
+			IFQ_DRV_PREPEND(&ifp->if_snd, m0);
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+			break;
+		}
+
 		BPF_MTAP(ifp, m0);
 
 		m0 = ieee80211_encap(ic, m0, ni);
 		if (m0 == NULL) {
 			ieee80211_free_node(ni);
+			ifp->if_oerrors++;
 			continue;
 		}
 
 		if (ic->ic_rawbpf != NULL)
 			bpf_mtap(ic->ic_rawbpf, m0);
 
-		if (iwi_tx_start(ifp, m0, ni) != 0) {
+		if (iwi_tx_start(ifp, m0, ni, ac) != 0) {
 			ieee80211_free_node(ni);
 			ifp->if_oerrors++;
 			break;
@@ -2148,6 +2199,22 @@
 	if (error != 0)
 		return error;
 
+	/* if we have a desired ESSID, set it now */
+	if (ic->ic_des_esslen != 0) {
+#ifdef IWI_DEBUG
+		if (iwi_debug > 0) {
+			printf("Setting desired ESSID to ");
+			ieee80211_print_essid(ic->ic_des_essid,
+			    ic->ic_des_esslen);
+			printf("\n");
+		}
+#endif
+		error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_essid,
+		    ic->ic_des_esslen, 1);
+		if (error != 0)
+			return error;
+	}
+
 	data = htole32(arc4random());
 	DPRINTF(("Setting initialization vector to %u\n", le32toh(data)));
 	error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data, 0);
@@ -2201,7 +2268,8 @@
 	int i, count;
 
 	memset(&scan, 0, sizeof scan);
-	scan.type = IWI_SCAN_TYPE_BROADCAST;
+	scan.type = (ic->ic_des_esslen != 0) ? IWI_SCAN_TYPE_BDIRECTED :
+	    IWI_SCAN_TYPE_BROADCAST;
 	scan.dwelltime = htole16(sc->dwelltime);
 
 	p = scan.channels;

==== //depot/projects/netsmp/src/sys/dev/iwi/if_iwireg.h#3 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/dev/iwi/if_iwireg.h,v 1.4 2005/08/21 09:52:18 damien Exp $	*/
+/*	$FreeBSD: src/sys/dev/iwi/if_iwireg.h,v 1.5 2005/09/17 12:41:05 damien Exp $	*/
 
 /*-
  * Copyright (c) 2004, 2005
@@ -62,6 +62,7 @@
 #define IWI_CSR_RX_BASE		0x0500
 #define IWI_CSR_TABLE0_SIZE	0x0700
 #define IWI_CSR_TABLE0_BASE	0x0704
+#define IWI_CSR_NODE_BASE	0x0c0c 
 #define IWI_CSR_CMD_WIDX	0x0f80
 #define IWI_CSR_TX1_WIDX	0x0f84
 #define IWI_CSR_TX2_WIDX	0x0f88
@@ -269,6 +270,12 @@
 	uint8_t		data[120];
 } __packed;
 
+/* node information (IBSS) */
+struct iwi_node {
+	uint8_t	bssid[IEEE80211_ADDR_LEN];
+	uint8_t	reserved[2];
+} __packed;
+
 /* constants for 'mode' fields */
 #define IWI_MODE_11A	0
 #define IWI_MODE_11B	1
@@ -331,7 +338,9 @@
 struct iwi_scan {
 	uint8_t		type;
 #define IWI_SCAN_TYPE_PASSIVE	1
+#define IWI_SCAN_TYPE_DIRECTED	2
 #define IWI_SCAN_TYPE_BROADCAST	3
+#define IWI_SCAN_TYPE_BDIRECTED	4
 
 	uint16_t	dwelltime;
 	uint8_t		channels[54];
@@ -424,6 +433,10 @@
 #define CSR_WRITE_4(sc, reg, val)					\
 	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
 
+#define CSR_WRITE_REGION_1(sc, offset, datap, count)			\
+	bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset),	\
+	    (datap), (count))
+
 /*
  * indirect memory space access macros
  */

==== //depot/projects/netsmp/src/sys/dev/iwi/if_iwivar.h#3 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/dev/iwi/if_iwivar.h,v 1.5 2005/08/20 16:49:03 damien Exp $	*/
+/*	$FreeBSD: src/sys/dev/iwi/if_iwivar.h,v 1.6 2005/09/17 12:41:05 damien Exp $	*/
 
 /*-
  * Copyright (c) 2004, 2005
@@ -130,6 +130,10 @@
 	struct iwi_tx_ring	txq[WME_NUM_AC];
 	struct iwi_rx_ring	rxq;
 
+#define IWI_MAX_NODE	32
+	uint8_t			sta[IWI_MAX_NODE][IEEE80211_ADDR_LEN];
+	uint8_t			nsta;
+
 	struct resource		*irq;
 	struct resource		*mem;
 	bus_space_tag_t		sc_st;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509171823.j8HINMZ8048157>