Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Sep 2005 22:51:52 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 83716 for review
Message-ID:  <200509152251.j8FMpqPx028690@repoman.freebsd.org>

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

Change 83716 by sam@sam_ebb on 2005/09/15 22:51:17

	checkpoint driver conversion

Affected files ...

.. //depot/projects/wifi/sys/dev/ipw/if_ipw.c#6 edit
.. //depot/projects/wifi/sys/dev/iwi/if_iwi.c#8 edit
.. //depot/projects/wifi/sys/dev/ral/if_ral.c#5 edit
.. //depot/projects/wifi/sys/dev/ral/if_ralvar.h#3 edit
.. //depot/projects/wifi/sys/dev/usb/if_ural.c#5 edit
.. //depot/projects/wifi/sys/dev/usb/if_uralvar.h#3 edit
.. //depot/projects/wifi/sys/dev/wi/if_wi.c#18 edit

Differences ...

==== //depot/projects/wifi/sys/dev/ipw/if_ipw.c#6 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.7 2005/07/08 19:30:29 damien Exp $	*/
+/*	$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.13 2005/08/20 15:03:41 damien Exp $	*/
 
 /*-
  * Copyright (c) 2004, 2005
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.7 2005/07/08 19:30:29 damien Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ipw/if_ipw.c,v 1.13 2005/08/20 15:03:41 damien Exp $");
 
 /*-
  * Intel(R) PRO/Wireless 2100 MiniPCI driver
@@ -130,9 +130,7 @@
 static int	ipw_config(struct ipw_softc *);
 static void	ipw_init(void *);
 static void	ipw_stop(void *);
-#ifdef IPW_DEBUG
 static int	ipw_sysctl_stats(SYSCTL_HANDLER_ARGS);
-#endif
 static int	ipw_sysctl_radio(SYSCTL_HANDLER_ARGS);
 static uint32_t	ipw_read_table1(struct ipw_softc *, uint32_t);
 static void	ipw_write_table1(struct ipw_softc *, uint32_t, uint32_t);
@@ -289,8 +287,7 @@
 
 	/* set device capabilities */
 	ic->ic_caps = IEEE80211_C_SHPREAMBLE | IEEE80211_C_TXPMGT |
-	    IEEE80211_C_PMGT | IEEE80211_C_IBSS | IEEE80211_C_MONITOR |
-	    IEEE80211_C_WPA;
+	    IEEE80211_C_PMGT | IEEE80211_C_IBSS | IEEE80211_C_MONITOR;
 
 	/* read MAC address from EEPROM */
 	val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0);
@@ -350,12 +347,10 @@
 	    CTLTYPE_INT | CTLFLAG_RD, sc, 0, ipw_sysctl_radio, "I",
 	    "radio transmitter switch state (0=off, 1=on)");
 
-#ifdef IPW_DEBUG
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats",
 	    CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, ipw_sysctl_stats, "S",
 	    "statistics");
-#endif
 
 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell",
@@ -735,7 +730,7 @@
 
 	if (ifp->if_flags & IFF_UP) {
 		ifp->if_init(ifp->if_softc);
-		if (ifp->if_flags & IFF_RUNNING)
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 			ifp->if_start(ifp);
 	}
 
@@ -758,7 +753,7 @@
 		return error;
 	}
 
-	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
+	if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
 		ipw_init(sc);
 
 	IPW_UNLOCK(sc);
@@ -828,7 +823,6 @@
 {
 	struct ifnet *ifp = ic->ic_ifp;
 	struct ipw_softc *sc = ifp->if_softc;
-	struct ieee80211_node *ni;
 	uint8_t macaddr[IEEE80211_ADDR_LEN];
 	uint32_t len;
 
@@ -839,16 +833,18 @@
 		len = IEEE80211_ADDR_LEN;
 		ipw_read_table2(sc, IPW_INFO_CURRENT_BSSID, macaddr, &len);
 
+#if 0
 		ni = ieee80211_find_node(&ic->ic_scan, macaddr);
 		if (ni == NULL)
 			break;
 
 		ieee80211_ref_node(ni);
 		ieee80211_sta_join(ic, ni);
-		ieee80211_node_authorize(ic, ni);
+		ieee80211_node_authorize(ni);
 
 		if (ic->ic_opmode == IEEE80211_M_STA)
 			ieee80211_notify_node_join(ic, ni, 1);
+#endif
 		break;
 
 	case IEEE80211_S_INIT:
@@ -1204,7 +1200,7 @@
 	/* remember what the firmware has processed */
 	sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1;
 
-	ifp->if_flags &= ~IFF_OACTIVE;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	ipw_start(ifp);
 }
 
@@ -1480,7 +1476,7 @@
 
 		if (sc->txfree < 1 + IPW_MAX_NSEG) {
 			IFQ_DRV_PREPEND(&ifp->if_snd, m0);
-			ifp->if_flags |= IFF_OACTIVE;
+			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 			break;
 		}
 
@@ -1523,7 +1519,6 @@
 ipw_watchdog(struct ifnet *ifp)
 {
 	struct ipw_softc *sc = ifp->if_softc;
-	struct ieee80211com *ic = &sc->sc_ic;
 
 	ifp->if_timer = 0;
 
@@ -1537,8 +1532,6 @@
 		}
 		ifp->if_timer = 1;
 	}
-
-	ieee80211_watchdog(ic);
 }
 
 static int
@@ -1554,10 +1547,10 @@
 	switch (cmd) {
 	case SIOCSIFFLAGS:
 		if (ifp->if_flags & IFF_UP) {
-			if (!(ifp->if_flags & IFF_RUNNING))
+			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 				ipw_init(sc);
 		} else {
-			if (ifp->if_flags & IFF_RUNNING)
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 				ipw_stop(sc);
 		}
 		break;
@@ -1586,8 +1579,8 @@
 	}
 
 	if (error == ENETRESET) {
-		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
-		    (IFF_UP | IFF_RUNNING))
+		if ((ifp->if_flags & IFF_UP) &&
+		    (ifp->if_drv_flags & IFF_DRV_RUNNING))
 			ipw_init(sc);
 		error = 0;
 	}
@@ -1933,8 +1926,8 @@
 		printf("\n");
 	}
 #endif
-	error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_essid,
-	    ic->ic_des_esslen);
+	error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_ssid[0].ssid,
+	    ic->ic_des_ssid[0].len);
 	if (error != 0)
 		return error;
 
@@ -2007,7 +2000,7 @@
 #endif
 
 	if (ic->ic_opmode == IEEE80211_M_IBSS) {
-		data = htole32(ic->ic_lintval);
+		data = htole32(ic->ic_bintval);
 		DPRINTF(("Setting beacon interval to %u\n", le32toh(data)));
 		error = ipw_cmd(sc, IPW_CMD_SET_BEACON_INTERVAL, &data,
 		    sizeof data);
@@ -2096,8 +2089,8 @@
 		goto fail;
 	}
 
-	ifp->if_flags &= ~IFF_OACTIVE;
-	ifp->if_flags |= IFF_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 
 	return;
 
@@ -2125,12 +2118,11 @@
 
 	sc->sc_tx_timer = 0;
 	ifp->if_timer = 0;
-	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 }
 
-#ifdef IPW_DEBUG
 static int
 ipw_sysctl_stats(SYSCTL_HANDLER_ARGS)
 {
@@ -2150,7 +2142,6 @@
 
 	return SYSCTL_OUT(req, buf, sizeof buf);
 }
-#endif
 
 static int
 ipw_sysctl_radio(SYSCTL_HANDLER_ARGS)

==== //depot/projects/wifi/sys/dev/iwi/if_iwi.c#8 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.8 2005/07/10 00:17:04 sam Exp $	*/
+/*	$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 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.8 2005/07/10 00:17:04 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.15 2005/08/21 09:52:18 damien Exp $");
 
 /*-
  * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
@@ -109,7 +109,7 @@
 static void	iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
 static void	iwi_free_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
 static int	iwi_alloc_tx_ring(struct iwi_softc *, struct iwi_tx_ring *,
-		    int);
+		    int, bus_addr_t, bus_addr_t);
 static void	iwi_reset_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
 static void	iwi_free_tx_ring(struct iwi_softc *, struct iwi_tx_ring *);
 static int	iwi_alloc_rx_ring(struct iwi_softc *, struct iwi_rx_ring *,
@@ -119,13 +119,14 @@
 static int	iwi_media_change(struct ifnet *);
 static void	iwi_media_status(struct ifnet *, struct ifmediareq *);
 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 void	iwi_fix_channel(struct ieee80211com *, struct mbuf *);
 static void	iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int,
 		    struct iwi_frame *);
 static void	iwi_notification_intr(struct iwi_softc *, struct iwi_notif *);
 static void	iwi_rx_intr(struct iwi_softc *);
-static void	iwi_tx_intr(struct iwi_softc *);
+static void	iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *);
 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 *,
@@ -145,9 +146,7 @@
 static int	iwi_auth_and_assoc(struct iwi_softc *);
 static void	iwi_init(void *);
 static void	iwi_stop(void *);
-#ifdef IWI_DEBUG
 static int	iwi_sysctl_stats(SYSCTL_HANDLER_ARGS);
-#endif
 static int	iwi_sysctl_radio(SYSCTL_HANDLER_ARGS);
 
 static int iwi_probe(device_t);
@@ -281,8 +280,31 @@
 		goto fail;
 	}
 
-	if (iwi_alloc_tx_ring(sc, &sc->txq, IWI_TX_RING_COUNT) != 0) {
-		device_printf(dev, "could not allocate Tx ring\n");
+	error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_TX_RING_COUNT,
+	    IWI_CSR_TX1_RIDX, IWI_CSR_TX1_WIDX);
+	if (error != 0) {
+		device_printf(dev, "could not allocate Tx ring 1\n");
+		goto fail;
+	}
+
+	error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_TX_RING_COUNT,
+	    IWI_CSR_TX2_RIDX, IWI_CSR_TX2_WIDX);
+	if (error != 0) {
+		device_printf(dev, "could not allocate Tx ring 2\n");
+		goto fail;
+	}
+
+	error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_TX_RING_COUNT,
+	    IWI_CSR_TX3_RIDX, IWI_CSR_TX3_WIDX);
+	if (error != 0) {
+		device_printf(dev, "could not allocate Tx ring 3\n");
+		goto fail;
+	}
+
+	error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_TX_RING_COUNT,
+	    IWI_CSR_TX4_RIDX, IWI_CSR_TX4_WIDX);
+	if (error != 0) {
+		device_printf(dev, "could not allocate Tx ring 4\n");
 		goto fail;
 	}
 
@@ -309,13 +331,18 @@
 	IFQ_SET_READY(&ifp->if_snd);
 
 	ic->ic_ifp = ifp;
+	ic->ic_wme.wme_update = iwi_wme_update;
 	ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
 	ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
 	ic->ic_state = IEEE80211_S_INIT;
 
 	/* set device capabilities */
-	ic->ic_caps = IEEE80211_C_WPA | IEEE80211_C_PMGT | IEEE80211_C_TXPMGT |
-	    IEEE80211_C_SHPREAMBLE | IEEE80211_C_MONITOR;
+	ic->ic_caps =
+	    IEEE80211_C_MONITOR |	/* monitor mode supported */
+	    IEEE80211_C_TXPMGT |	/* tx power management */
+	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
+	    IEEE80211_C_WPA |		/* 802.11i */
+	    IEEE80211_C_WME;		/* 802.11e */
 
 	/* read MAC address from EEPROM */
 	val = iwi_read_prom_word(sc, IWI_EEPROM_MAC + 0);
@@ -390,12 +417,10 @@
 	    CTLTYPE_INT | CTLFLAG_RD, sc, 0, iwi_sysctl_radio, "I",
 	    "radio transmitter switch state (0=off, 1=on)");
 
-#ifdef IWI_DEBUG
 	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats",
 	    CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, iwi_sysctl_stats, "S",
 	    "statistics");
-#endif
 
 	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell",
@@ -447,7 +472,10 @@
 		if_free(ifp);
 
 	iwi_free_cmd_ring(sc, &sc->cmdq);
-	iwi_free_tx_ring(sc, &sc->txq);
+	iwi_free_tx_ring(sc, &sc->txq[0]);
+	iwi_free_tx_ring(sc, &sc->txq[1]);
+	iwi_free_tx_ring(sc, &sc->txq[2]);
+	iwi_free_tx_ring(sc, &sc->txq[3]);
 	iwi_free_rx_ring(sc, &sc->rxq);
 
 	if (sc->irq != NULL) {
@@ -533,13 +561,16 @@
 }
 
 static int
-iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count)
+iwi_alloc_tx_ring(struct iwi_softc *sc, struct iwi_tx_ring *ring, int count,
+    bus_addr_t csr_ridx, bus_addr_t csr_widx)
 {
 	int i, error;
 
 	ring->count = count;
 	ring->queued = 0;
 	ring->cur = ring->next = 0;
+	ring->csr_ridx = csr_ridx;
+	ring->csr_widx = csr_widx;
 
 	error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT,
 	    BUS_SPACE_MAXADDR, NULL, NULL, count * IWI_TX_DESC_SIZE, 1,
@@ -788,7 +819,7 @@
 
 	if (ifp->if_flags & IFF_UP) {
 		ifp->if_init(ifp->if_softc);
-		if (ifp->if_flags & IFF_RUNNING)
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 			ifp->if_start(ifp);
 	}
 
@@ -811,7 +842,7 @@
 		return error;
 	}
 
-	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
+	if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
 		iwi_init(sc);
 
 	IWI_UNLOCK(sc);
@@ -890,11 +921,15 @@
 	struct iwi_softc *sc = ifp->if_softc;
 
 	switch (nstate) {
+	case IEEE80211_S_INIT:
+		sc->flags &= ~IWI_FLAG_SCANNING;
+		break;
+
 	case IEEE80211_S_SCAN:
 		if (sc->flags & IWI_FLAG_SCANNING)
 			break;
 
-		ieee80211_node_table_reset(&ic->ic_scan);
+		ieee80211_scan_flush(ic);
 		ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
 		sc->flags |= IWI_FLAG_SCANNING;
 		iwi_scan(sc);
@@ -907,17 +942,11 @@
 	case IEEE80211_S_RUN:
 		if (ic->ic_opmode == IEEE80211_M_IBSS)
 			ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
-		else if (ic->ic_opmode == IEEE80211_M_MONITOR)
-			iwi_set_chan(sc, ic->ic_curchan);
 
 		return sc->sc_newstate(ic, nstate,
 		    IEEE80211_FC0_SUBTYPE_ASSOC_RESP);
 
-	case IEEE80211_S_ASSOC:
-		break;
-
-	case IEEE80211_S_INIT:
-		sc->flags &= ~IWI_FLAG_SCANNING;
+	default:
 		break;
 	}
 
@@ -926,6 +955,74 @@
 }
 
 /*
+ * WME parameters coming from IEEE 802.11e specification.  These values are
+ * already declared in ieee80211_proto.c, but they are static so they can't
+ * be reused here.
+ */
+static const struct wmeParams iwi_wme_cck_params[WME_NUM_AC] = {
+	{ 0, 3, 5,  7,   0 },	/* WME_AC_BE */
+	{ 0, 3, 5, 10,   0 },	/* WME_AC_BK */
+	{ 0, 2, 4,  5, 188 },	/* WME_AC_VI */
+	{ 0, 2, 3,  4, 102 }	/* WME_AC_VO */
+};
+
+static const struct wmeParams iwi_wme_ofdm_params[WME_NUM_AC] = {
+	{ 0, 3, 4,  6,   0 },	/* WME_AC_BE */
+	{ 0, 3, 4, 10,   0 },	/* WME_AC_BK */
+	{ 0, 2, 3,  4,  94 },	/* WME_AC_VI */
+	{ 0, 2, 2,  3,  47 }	/* WME_AC_VO */
+};
+
+static int
+iwi_wme_update(struct ieee80211com *ic)
+{
+#define IWI_EXP2(v)	htole16((1 << (v)) - 1)
+#define IWI_USEC(v)	htole16(IEEE80211_TXOP_TO_US(v))
+	struct iwi_softc *sc = ic->ic_ifp->if_softc;
+	struct iwi_wme_params wme[3];
+	const struct wmeParams *wmep;
+	int ac;
+
+	/*
+	 * We shall not override firmware default WME values if WME is not
+	 * actually enabled.
+	 */
+	if (!(ic->ic_flags & IEEE80211_F_WME))
+		return 0;
+
+	for (ac = 0; ac < WME_NUM_AC; ac++) {
+		/* set WME values for current operating mode */
+		wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
+		wme[0].aifsn[ac] = wmep->wmep_aifsn;
+		wme[0].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+		wme[0].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+		wme[0].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+		wme[0].acm[ac]   = wmep->wmep_acm;
+
+		/* set WME values for CCK modulation */
+		wmep = &iwi_wme_cck_params[ac];
+		wme[1].aifsn[ac] = wmep->wmep_aifsn;
+		wme[1].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+		wme[1].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+		wme[1].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+		wme[1].acm[ac]   = wmep->wmep_acm;
+
+		/* set WME values for OFDM modulation */
+		wmep = &iwi_wme_ofdm_params[ac];
+		wme[2].aifsn[ac] = wmep->wmep_aifsn;
+		wme[2].cwmin[ac] = IWI_EXP2(wmep->wmep_logcwmin);
+		wme[2].cwmax[ac] = IWI_EXP2(wmep->wmep_logcwmax);
+		wme[2].burst[ac] = IWI_USEC(wmep->wmep_txopLimit);
+		wme[2].acm[ac]   = wmep->wmep_acm;
+	}
+
+	DPRINTF(("Setting WME parameters\n"));
+	return iwi_cmd(sc, IWI_CMD_SET_WME_PARAMS, wme, sizeof wme, 1);
+#undef IWI_USEC
+#undef IWI_EXP2
+}
+
+/*
  * Read 16 bits at address 'addr' from the serial EEPROM.
  */
 static uint16_t
@@ -1128,7 +1225,7 @@
 
 		switch (auth->state) {
 		case IWI_AUTHENTICATED:
-			ieee80211_node_authorize(ic, ic->ic_bss);
+			ieee80211_node_authorize(ic->ic_bss);
 			ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
 			break;
 
@@ -1157,7 +1254,11 @@
 			break;
 
 		case IWI_DEASSOCIATED:
+#if 0
 			ieee80211_begin_scan(ic, 1);
+#else
+			ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
+#endif
 			break;
 
 		default:
@@ -1222,36 +1323,36 @@
 }
 
 static void
-iwi_tx_intr(struct iwi_softc *sc)
+iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq)
 {
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = ic->ic_ifp;
 	struct iwi_tx_data *data;
 	uint32_t hw;
 
-	hw = CSR_READ_4(sc, IWI_CSR_TX1_RIDX);
+	hw = CSR_READ_4(sc, txq->csr_ridx);
 
-	for (; sc->txq.next != hw;) {
-		data = &sc->txq.data[sc->txq.next];
+	for (; txq->next != hw;) {
+		data = &txq->data[txq->next];
 
-		bus_dmamap_sync(sc->txq.data_dmat, data->map,
+		bus_dmamap_sync(txq->data_dmat, data->map,
 		    BUS_DMASYNC_POSTWRITE);
-		bus_dmamap_unload(sc->txq.data_dmat, data->map);
+		bus_dmamap_unload(txq->data_dmat, data->map);
 		m_freem(data->m);
 		data->m = NULL;
 		ieee80211_free_node(data->ni);
 		data->ni = NULL;
 
-		DPRINTFN(15, ("tx done idx=%u\n", sc->txq.next));
+		DPRINTFN(15, ("tx done idx=%u\n", txq->next));
 
 		ifp->if_opackets++;
 
-		sc->txq.queued--;
-		sc->txq.next = (sc->txq.next + 1) % IWI_TX_RING_COUNT;
+		txq->queued--;
+		txq->next = (txq->next + 1) % IWI_TX_RING_COUNT;
 	}
 
 	sc->sc_tx_timer = 0;
-	ifp->if_flags &= ~IFF_OACTIVE;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	iwi_start(ifp);
 }
 
@@ -1288,14 +1389,23 @@
 		iwi_stop(sc);
 	}
 
-	if (r & IWI_INTR_RX_DONE)
-		iwi_rx_intr(sc);
-
 	if (r & IWI_INTR_CMD_DONE)
 		wakeup(sc);
 
 	if (r & IWI_INTR_TX1_DONE)
-		iwi_tx_intr(sc);
+		iwi_tx_intr(sc, &sc->txq[0]);
+
+	if (r & IWI_INTR_TX2_DONE)
+		iwi_tx_intr(sc, &sc->txq[1]);
+
+	if (r & IWI_INTR_TX3_DONE)
+		iwi_tx_intr(sc, &sc->txq[2]);
+
+	if (r & IWI_INTR_TX4_DONE)
+		iwi_tx_intr(sc, &sc->txq[3]);
+
+	if (r & IWI_INTR_RX_DONE)
+		iwi_rx_intr(sc);
 
 	/* acknowledge interrupts */
 	CSR_WRITE_4(sc, IWI_CSR_INTR, r);
@@ -1336,21 +1446,48 @@
 {
 	struct iwi_softc *sc = ifp->if_softc;
 	struct ieee80211com *ic = &sc->sc_ic;
-	struct ieee80211_frame wh;
+	struct ieee80211_frame *wh;
 	struct ieee80211_key *k;
+	const struct chanAccParams *cap;
+	struct iwi_tx_ring *txq;
 	struct iwi_tx_data *data;
 	struct iwi_tx_desc *desc;
 	struct mbuf *mnew;
 	bus_dma_segment_t segs[IWI_MAX_NSEG];
-	int nsegs, error, i;
+	int error, nsegs, hdrlen, ac, i, 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 {
+		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;
+	}
 
-	bcopy(mtod(m0, struct ieee80211_frame *), &wh, sizeof (struct ieee80211_frame));
-	if (wh.i_fc[1] & IEEE80211_FC1_WEP) {
+	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 		k = ieee80211_crypto_encap(ic, ni, m0);
 		if (k == NULL) {
 			m_freem(m0);
 			return ENOBUFS;
 		}
+
+		/* packet header may have moved, reset our local pointer */
+		wh = mtod(m0, struct ieee80211_frame *);
 	}
 
 	if (sc->sc_drvbpf != NULL) {
@@ -1363,13 +1500,14 @@
 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
 	}
 
-	data = &sc->txq.data[sc->txq.cur];
-	desc = &sc->txq.desc[sc->txq.cur];
+	data = &txq->data[txq->cur];
+	desc = &txq->desc[txq->cur];
 
-	/* trim IEEE802.11 header */
-	m_adj(m0, sizeof (struct ieee80211_frame));
+	/* save and trim IEEE802.11 header */
+	m_copydata(m0, 0, hdrlen, (caddr_t)&desc->wh);
+	m_adj(m0, hdrlen);
 
-	error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, m0, segs,
+	error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0, segs,
 	    &nsegs, 0);
 	if (error != 0 && error != EFBIG) {
 		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
@@ -1387,7 +1525,7 @@
 		}
 		m0 = mnew;
 
-		error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map,
+		error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map,
 		    m0, segs, &nsegs, 0);
 		if (error != 0) {
 			device_printf(sc->sc_dev,
@@ -1404,15 +1542,15 @@
 	desc->hdr.flags = IWI_HDR_FLAG_IRQ;
 	desc->cmd = IWI_DATA_CMD_TX;
 	desc->len = htole16(m0->m_pkthdr.len);
-	memcpy(&desc->wh, &wh, sizeof (struct ieee80211_frame));
 	desc->flags = 0;
+	desc->xflags = 0;
 
-	if (!IEEE80211_IS_MULTICAST(wh.i_addr1))
+	if (!noack && !IEEE80211_IS_MULTICAST(desc->wh.i_addr1))
 		desc->flags |= IWI_DATA_FLAG_NEED_ACK;
 
 #if 0
 	if (ic->ic_flags & IEEE80211_F_PRIVACY) {
-		wh.i_fc[1] |= IEEE80211_FC1_WEP;
+		desc->wh.i_fc[1] |= IEEE80211_FC1_WEP;
 		desc->wep_txkey = ic->ic_crypto.cs_def_txkey;
 	} else
 #endif
@@ -1421,22 +1559,24 @@
 	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
 		desc->flags |= IWI_DATA_FLAG_SHPREAMBLE;
 
+	if (desc->wh.i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS)
+		desc->xflags |= IWI_DATA_XFLAG_QOS;
+
 	desc->nseg = htole32(nsegs);
 	for (i = 0; i < nsegs; i++) {
 		desc->seg_addr[i] = htole32(segs[i].ds_addr);
 		desc->seg_len[i]  = htole32(segs[i].ds_len);
 	}
 
-	bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_PREWRITE);
-	bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_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);
 
-	DPRINTFN(5, ("sending data frame idx=%u len=%u nseg=%u\n", sc->txq.cur,
-	    desc->len, desc->nseg));
+	DPRINTFN(5, ("sending data frame txq=%u idx=%u len=%u nseg=%u\n",
+	    ac, txq->cur, desc->len, desc->nseg));
 
-	sc->txq.queued++;
-	sc->txq.cur = (sc->txq.cur + 1) % IWI_TX_RING_COUNT;
-	CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur);
+	txq->queued++;
+	txq->cur = (txq->cur + 1) % IWI_TX_RING_COUNT;
+	CSR_WRITE_4(sc, txq->csr_widx, txq->cur);
 
 	return 0;
 }
@@ -1462,12 +1602,6 @@
 		if (m0 == NULL)
 			break;
 
-		if (sc->txq.queued >= IWI_TX_RING_COUNT - 4) {
-			IFQ_DRV_PREPEND(&ifp->if_snd, m0);
-			ifp->if_flags |= IFF_OACTIVE;
-			break;
-		}
-
 		if (m0->m_len < sizeof (struct ether_header) &&
 		    (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL)
 			continue;
@@ -1478,6 +1612,10 @@
 			m_freem(m0);
 			continue;
 		}
+		if (ieee80211_classify(ic, m0, ni) != 0) {
+			m_freem(m0);
+			continue;
+		}
 		BPF_MTAP(ifp, m0);
 
 		m0 = ieee80211_encap(ic, m0, ni);
@@ -1506,7 +1644,6 @@
 iwi_watchdog(struct ifnet *ifp)
 {
 	struct iwi_softc *sc = ifp->if_softc;
-	struct ieee80211com *ic = &sc->sc_ic;
 
 	IWI_LOCK(sc);
 
@@ -1524,8 +1661,6 @@
 		ifp->if_timer = 1;
 	}
 
-	ieee80211_watchdog(ic);
-
 	IWI_UNLOCK(sc);
 }
 
@@ -1542,10 +1677,10 @@
 	switch (cmd) {
 	case SIOCSIFFLAGS:
 		if (ifp->if_flags & IFF_UP) {
-			if (!(ifp->if_flags & IFF_RUNNING))
+			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 				iwi_init(sc);
 		} else {
-			if (ifp->if_flags & IFF_RUNNING)
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 				iwi_stop(sc);
 		}
 		break;
@@ -1574,8 +1709,9 @@
 	}
 
 	if (error == ENETRESET) {
-		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
-		    (IFF_UP | IFF_RUNNING))
+		if ((ifp->if_flags & IFF_UP) &&
+		    (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
+		    (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
 			iwi_init(sc);
 		error = 0;
 	}
@@ -2102,6 +2238,7 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = ic->ic_ifp;
 	struct ieee80211_node *ni = ic->ic_bss;
+	struct ieee80211_wme_info wme;
 	struct iwi_configuration config;
 	struct iwi_associate assoc;
 	struct iwi_rateset rs;
@@ -2148,6 +2285,23 @@
 	if (error != 0)
 		return error;
 
+	if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) {
+		wme.wme_id = IEEE80211_ELEMID_VENDOR;
+		wme.wme_len = sizeof (struct ieee80211_wme_info) - 2;
+		wme.wme_oui[0] = 0x00;
+		wme.wme_oui[1] = 0x50;
+		wme.wme_oui[2] = 0xf2;
+		wme.wme_type = WME_OUI_TYPE;
+		wme.wme_subtype = WME_INFO_OUI_SUBTYPE;
+		wme.wme_version = WME_VERSION;
+		wme.wme_info = 0;
+
+		DPRINTF(("Setting WME IE (len=%u)\n", wme.wme_len));
+		error = iwi_cmd(sc, IWI_CMD_SET_WMEIE, &wme, sizeof wme, 1);
+		if (error != 0)
+			return error;
+	}
+
 	if (ic->ic_opt_ie != NULL) {
 		DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len));
 		error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie,
@@ -2168,8 +2322,10 @@
 	assoc.chan = ieee80211_chan2ieee(ic, ic->ic_bsschan);
 	if (ni->ni_authmode == IEEE80211_AUTH_SHARED)
 		assoc.auth = ic->ic_crypto.cs_def_txkey << 4 | IWI_AUTH_SHARED;
+	if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
+		assoc.policy |= htole16(IWI_POLICY_WME);
 	if (ic->ic_opt_ie != NULL)
-		assoc.policy |= htole16(IWI_POLICY_OPTIE);
+		assoc.policy |= htole16(IWI_POLICY_WPA);
 	memcpy(assoc.tstamp, ni->ni_tstamp.data, 8);
 
 	if (ic->ic_opmode == IEEE80211_M_IBSS)
@@ -2240,21 +2396,21 @@
 	CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, sc->cmdq.count);
 	CSR_WRITE_4(sc, IWI_CSR_CMD_WIDX, sc->cmdq.cur);
 
-	CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq.physaddr);
-	CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq.count);
-	CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq.cur);
+	CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->txq[0].physaddr);
+	CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, sc->txq[0].count);
+	CSR_WRITE_4(sc, IWI_CSR_TX1_WIDX, sc->txq[0].cur);
 
-	CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq.physaddr);
-	CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq.count);
-	CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq.cur);
+	CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->txq[1].physaddr);
+	CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, sc->txq[1].count);
+	CSR_WRITE_4(sc, IWI_CSR_TX2_WIDX, sc->txq[1].cur);
 
-	CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq.physaddr);
-	CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq.count);
-	CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq.cur);
+	CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->txq[2].physaddr);
+	CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, sc->txq[2].count);
+	CSR_WRITE_4(sc, IWI_CSR_TX3_WIDX, sc->txq[2].cur);
 
-	CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq.physaddr);
-	CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq.count);
-	CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq.cur);
+	CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->txq[3].physaddr);
+	CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, sc->txq[3].count);
+	CSR_WRITE_4(sc, IWI_CSR_TX4_WIDX, sc->txq[3].cur);
 
 	for (i = 0; i < sc->rxq.count; i++) {
 		data = &sc->rxq.data[i];
@@ -2275,13 +2431,14 @@
 		goto fail;
 	}
 
-	if (ic->ic_opmode == IEEE80211_M_MONITOR)
+	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+		if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
+			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+	} else
 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
-	else
-		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
 
-	ifp->if_flags &= ~IFF_OACTIVE;
-	ifp->if_flags |= IFF_RUNNING;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 
 	return;
 
@@ -2302,17 +2459,19 @@
 
 	/* reset rings */
 	iwi_reset_cmd_ring(sc, &sc->cmdq);
-	iwi_reset_tx_ring(sc, &sc->txq);
+	iwi_reset_tx_ring(sc, &sc->txq[0]);
+	iwi_reset_tx_ring(sc, &sc->txq[1]);
+	iwi_reset_tx_ring(sc, &sc->txq[2]);
+	iwi_reset_tx_ring(sc, &sc->txq[3]);
 	iwi_reset_rx_ring(sc, &sc->rxq);
 
 	sc->sc_tx_timer = 0;
 	ifp->if_timer = 0;
-	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 }
 
-#ifdef IWI_DEBUG
 static int
 iwi_sysctl_stats(SYSCTL_HANDLER_ARGS)
 {
@@ -2329,7 +2488,6 @@
 
 	return SYSCTL_OUT(req, buf, sizeof buf);
 }
-#endif
 
 static int
 iwi_sysctl_radio(SYSCTL_HANDLER_ARGS)

==== //depot/projects/wifi/sys/dev/ral/if_ral.c#5 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.10 2005/07/10 22:25:44 sam Exp $	*/
+/*	$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.15 2005/08/21 14:16:19 damien Exp $	*/
 
 /*-
  * Copyright (c) 2005
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.10 2005/07/10 22:25:44 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.15 2005/08/21 14:16:19 damien Exp $");
 
 /*-
  * Ralink Technology RT2500 chipset driver
@@ -91,7 +91,6 @@
 static struct		ieee80211_node *ral_node_alloc(
 			    struct ieee80211_node_table *);
 static int		ral_media_change(struct ifnet *);
-static void		ral_next_scan(void *);
 static void		ral_iter_func(void *, struct ieee80211_node *);
 static void		ral_update_rssadapt(void *);
 static int		ral_newstate(struct ieee80211com *,
@@ -105,7 +104,7 @@
 static void		ral_beacon_expire(struct ral_softc *);
 static void		ral_wakeup_expire(struct ral_softc *);
 static void		ral_intr(void *);
-static int		ral_ack_rate(int);
+static int		ral_ack_rate(struct ieee80211com *, int);
 static uint16_t		ral_txtime(int, int, uint32_t);
 static uint8_t		ral_plcp_signal(int);
 static void		ral_setup_tx_desc(struct ral_softc *,
@@ -350,7 +349,6 @@
 	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
 	    MTX_DEF | MTX_RECURSE);
 
-	callout_init(&sc->scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
 	callout_init(&sc->rssadapt_ch, CALLOUT_MPSAFE);
 
 	/* retrieve RT2560 rev. no */
@@ -533,7 +531,6 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = ic->ic_ifp;
 
-	callout_stop(&sc->scan_ch);
 	callout_stop(&sc->rssadapt_ch);
 
 	bpfdetach(ifp);
@@ -921,27 +918,14 @@
 	if (error != ENETRESET)
 		return error;
 
-	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
+	if ((ifp->if_flags & IFF_UP) &&
+	    (ifp->if_drv_flags & IFF_DRV_RUNNING))
 		ral_init(sc);
 
 	return 0;
 }
 
 /*
- * This function is called periodically (every 200ms) during scanning to
- * switch from one channel to another.
- */
-static void
-ral_next_scan(void *arg)
-{
-	struct ral_softc *sc = arg;

>>> TRUNCATED FOR MAIL (1000 lines) <<<



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