Module Name:    src
Committed By:   dyoung
Date:           Sun Sep 13 22:07:34 UTC 2009

Modified Files:
        src/sys/dev/ic: atw.c atwvar.h

Log Message:
Experimental support for fragmentation and RTS/CTS.

Delete unused atw_voodoo and constants.

Export Tx/Rx statistics with evcnt(9).

Correct the Short Inter-Frame Space (SIFS) that we write to ADM8211's
registers; I do not recall if that corrected the SIFS that I observed
"on the air."  Use the constant IEEE80211_DUR_DS_EIFS to configure
the ADM8211's EIFS, instead of writing the same "magic" number,
0x64, that my reference driver wrote.

Do not clear OACTIVE in atw_init(), because atw_stop() cleared it
previously by calling atw_txdrain().

Use the net80211 short-preamble flag and instead of ATW_SHPREAMBLE.

Add an ADM8211 workaround from the reference driver, atw_workaround1(),
but don't compile it right now.

In at_intr(), don't stop processing the interrupt status after
restarting the receive ring, but process Tx interrupt status.  If
a packet's Tx lifetime is exceeded, reinitialize the device to get
packets moving again.  If the Tx FIFO underflows, restart the
transmitter, not the receiver!

Avoid losing synchronization with the Rx ring by replicating one
of Charles Hannum's fixes to rtw(4) here: receiving a management
packet may, as a side-effect, reset the Rx ring, so refer to the
softc's Rx ring pointer, sc_rxptr, every time through the loop in
atw_rxintr(), instead of refering to a pointer on the stack, i.

Re-synchronize DMA after reading the OWN bit on an Rx/Tx descriptor.
XXX This needs more work.

Reset sc_tx_timer as Tx descriptors are reclaimed from the device.

Shorten staircases in atw_watchdog().

Remove from softc an unused member, sc_intr_ack.


To generate a diff of this commit:
cvs rdiff -u -r1.144 -r1.145 src/sys/dev/ic/atw.c
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/ic/atwvar.h

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/ic/atw.c
diff -u src/sys/dev/ic/atw.c:1.144 src/sys/dev/ic/atw.c:1.145
--- src/sys/dev/ic/atw.c:1.144	Sat Sep  5 14:19:30 2009
+++ src/sys/dev/ic/atw.c	Sun Sep 13 22:07:34 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: atw.c,v 1.144 2009/09/05 14:19:30 tsutsui Exp $  */
+/*	$NetBSD: atw.c,v 1.145 2009/09/13 22:07:34 dyoung Exp $  */
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atw.c,v 1.144 2009/09/05 14:19:30 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atw.c,v 1.145 2009/09/13 22:07:34 dyoung Exp $");
 
 #include "bpfilter.h"
 
@@ -48,6 +48,7 @@
 #include <sys/ioctl.h>
 #include <sys/errno.h>
 #include <sys/device.h>
+#include <sys/kauth.h>
 #include <sys/time.h>
 #include <lib/libkern/libkern.h>
 
@@ -131,10 +132,6 @@
 
 #define ATW_REFSLAVE	/* slavishly do what the reference driver does */
 
-#define	VOODOO_DUR_11_ROUNDING		0x01 /* necessary */
-#define	VOODOO_DUR_2_4_SPECIALCASE	0x02 /* NOT necessary */
-int atw_voodoo = VOODOO_DUR_11_ROUNDING;
-
 int atw_pseudo_milli = 1;
 int atw_magic_delay1 = 100 * 1000;
 int atw_magic_delay2 = 100 * 1000;
@@ -211,7 +208,7 @@
 /* Interrupt handlers */
 void	atw_linkintr(struct atw_softc *, u_int32_t);
 void	atw_rxintr(struct atw_softc *);
-void	atw_txintr(struct atw_softc *);
+void	atw_txintr(struct atw_softc *, uint32_t);
 
 /* 802.11 state machine */
 static int	atw_newstate(struct ieee80211com *, enum ieee80211_state, int);
@@ -718,7 +715,7 @@
 	 * before this point releases all resources that may have been
 	 * allocated.
 	 */
-	sc->sc_flags |= ATWF_ATTACHED /* | ATWF_RTSCTS */;
+	sc->sc_flags |= ATWF_ATTACHED;
 
 	ATW_DPRINTF((" SROM MAC %04x%04x%04x",
 	    htole16(sc->sc_srom[ATW_SR_MAC00]),
@@ -1158,10 +1155,10 @@
 	 * Go figure.
 	 */
 	ifst = __SHIFTIN(IEEE80211_DUR_DS_SLOT, ATW_IFST_SLOT_MASK) |
-	      __SHIFTIN(22 * 5 /* IEEE80211_DUR_DS_SIFS */ /* # of 22 MHz cycles */,
+	      __SHIFTIN(22 * 10 /* IEEE80211_DUR_DS_SIFS */ /* # of 22 MHz cycles */,
 	             ATW_IFST_SIFS_MASK) |
 	      __SHIFTIN(IEEE80211_DUR_DS_DIFS, ATW_IFST_DIFS_MASK) |
-	      __SHIFTIN(0x64 /* IEEE80211_DUR_DS_EIFS */, ATW_IFST_EIFS_MASK);
+	      __SHIFTIN(IEEE80211_DUR_DS_EIFS, ATW_IFST_EIFS_MASK);
 
 	ATW_WRITE(sc, ATW_IFST, ifst);
 }
@@ -1436,7 +1433,6 @@
 	 * Note that the interface is now running.
 	 */
 	ifp->if_flags |= IFF_RUNNING;
-	ifp->if_flags &= ~IFF_OACTIVE;
 
 	/* send no beacons, yet. */
 	atw_start_beacon(sc, 0);
@@ -1447,7 +1443,7 @@
 		error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
  out:
 	if (error) {
-		ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+		ifp->if_flags &= ~IFF_RUNNING;
 		sc->sc_tx_timer = 0;
 		ifp->if_timer = 0;
 		printf("%s: interface not running\n", device_xname(sc->sc_dev));
@@ -2368,7 +2364,7 @@
 	/* TBD use ni_capinfo */
 
 	capinfo = 0;
-	if (sc->sc_flags & ATWF_SHORT_PREAMBLE)
+	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
 		capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 	if (ic->ic_flags & IEEE80211_F_PRIVACY)
 		capinfo |= IEEE80211_CAPINFO_PRIVACY;
@@ -2677,8 +2673,7 @@
 	/*
 	 * Mark the interface down and cancel the watchdog timer.
 	 */
-	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-	sc->sc_tx_timer = 0;
+	ifp->if_flags &= ~IFF_RUNNING;
 	ifp->if_timer = 0;
 
 	if (disable) {
@@ -2777,6 +2772,30 @@
 	return true;
 }
 
+#if 0
+static void
+atw_workaround1(struct atw_softc *sc)
+{
+	uint32_t test1;
+
+	test1 = ATW_READ(sc, ATW_TEST1);
+
+	sc->sc_misc_ev.ev_count++;
+
+	if ((test1 & ATW_TEST1_RXPKT1IN) != 0) {
+		sc->sc_rxpkt1in_ev.ev_count++;
+		return;
+	}
+	if (__SHIFTOUT(test1, ATW_TEST1_RRA_MASK) ==
+	    __SHIFTOUT(test1, ATW_TEST1_RWA_MASK)) {
+		sc->sc_rxamatch_ev.ev_count++;
+		return;
+	}
+	sc->sc_workaround1_ev.ev_count++;
+	(void)atw_init(&sc->sc_if);
+}
+#endif
+
 int
 atw_intr(void *arg)
 {
@@ -2863,17 +2882,17 @@
 				    device_xname(sc->sc_dev));
 				/* Get the receive process going again. */
 				ATW_WRITE(sc, ATW_RDR, 0x1);
-				break;
 			}
 		}
 
 		if (txstatus) {
 			/* Sweep up transmit descriptors. */
-			atw_txintr(sc);
+			atw_txintr(sc, txstatus);
 
 			if (txstatus & ATW_INTR_TLT) {
 				DPRINTF(sc, ("%s: tx lifetime exceeded\n",
 				    device_xname(sc->sc_dev)));
+				(void)atw_init(&sc->sc_if);
 			}
 
 			if (txstatus & ATW_INTR_TRT) {
@@ -2903,7 +2922,7 @@
 				 */
 				ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
 				DELAY(atw_nar_delay);
-				ATW_WRITE(sc, ATW_RDR, 0x1);
+				ATW_WRITE(sc, ATW_TDR, 0x1);
 				/* XXX Log every Nth underrun from
 				 * XXX now on?
 				 */
@@ -3073,7 +3092,7 @@
 	int i, len, rate, rate0;
 	u_int32_t rssi, ctlrssi;
 
-	for (i = sc->sc_rxptr;; i = ATW_NEXTRX(i)) {
+	for (i = sc->sc_rxptr;; i = sc->sc_rxptr) {
 		rxs = &sc->sc_rxsoft[i];
 
 		ATW_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
@@ -3082,8 +3101,12 @@
 		ctlrssi = le32toh(sc->sc_rxdescs[i].ar_ctlrssi);
 		rate0 = __SHIFTOUT(rxstat, ATW_RXSTAT_RXDR_MASK);
 
-		if (rxstat & ATW_RXSTAT_OWN)
-			break; /* We have processed all receive buffers. */
+		if (rxstat & ATW_RXSTAT_OWN) {
+			ATW_CDRXSYNC(sc, i, BUS_DMASYNC_PREREAD);
+			break;
+		}
+
+		sc->sc_rxptr = ATW_NEXTRX(i);
 
 		DPRINTF3(sc,
 		    ("%s: rx stat %08x ctlrssi %08x buf1 %08x buf2 %08x\n",
@@ -3224,9 +3247,6 @@
 		ieee80211_input(ic, m, ni, (int)rssi, 0);
 		ieee80211_free_node(ni);
 	}
-
-	/* Update the receive pointer. */
-	sc->sc_rxptr = i;
 }
 
 /*
@@ -3235,7 +3255,7 @@
  *	Helper; handle transmit interrupts.
  */
 void
-atw_txintr(struct atw_softc *sc)
+atw_txintr(struct atw_softc *sc, uint32_t status)
 {
 	static char txstat_buf[sizeof("ffffffff<>" ATW_TXSTAT_FMT)];
 	struct ifnet *ifp = &sc->sc_if;
@@ -3273,17 +3293,20 @@
 				if (i == txs->txs_lastdesc)
 					break;
 			}
+			ATW_CDTXSYNC(sc, txs->txs_firstdesc,
+			    txs->txs_ndescs - 1, BUS_DMASYNC_PREREAD);
 		}
 #endif
 
 		txstat = le32toh(sc->sc_txdescs[txs->txs_lastdesc].at_stat);
-		if (txstat & ATW_TXSTAT_OWN)
+		if (txstat & ATW_TXSTAT_OWN) {
+			ATW_CDTXSYNC(sc, txs->txs_lastdesc, 1,
+			    BUS_DMASYNC_PREREAD);
 			break;
+		}
 
 		SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
 
-		sc->sc_txfree += txs->txs_ndescs;
-
 		bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
 		    0, txs->txs_dmamap->dm_mapsize,
 		    BUS_DMASYNC_POSTWRITE);
@@ -3291,10 +3314,11 @@
 		m_freem(txs->txs_mbuf);
 		txs->txs_mbuf = NULL;
 
+		sc->sc_txfree += txs->txs_ndescs;
 		SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
 
-		KASSERT(!(SIMPLEQ_EMPTY(&sc->sc_txfreeq) ||
-		        sc->sc_txfree == 0));
+		KASSERT(!SIMPLEQ_EMPTY(&sc->sc_txfreeq) && sc->sc_txfree != 0);
+		sc->sc_tx_timer = 0;
 		ifp->if_flags &= ~IFF_OACTIVE;
 
 		if ((ifp->if_flags & IFF_DEBUG) != 0 &&
@@ -3306,20 +3330,21 @@
 			    __SHIFTOUT(txstat, ATW_TXSTAT_ARC_MASK));
 		}
 
+		sc->sc_xmit_ev.ev_count++;
+
 		/*
 		 * Check for errors and collisions.
 		 */
 		if (txstat & ATW_TXSTAT_TUF)
-			sc->sc_stats.ts_tx_tuf++;
+			sc->sc_tuf_ev.ev_count++;
 		if (txstat & ATW_TXSTAT_TLT)
-			sc->sc_stats.ts_tx_tlt++;
+			sc->sc_tlt_ev.ev_count++;
 		if (txstat & ATW_TXSTAT_TRT)
-			sc->sc_stats.ts_tx_trt++;
+			sc->sc_trt_ev.ev_count++;
 		if (txstat & ATW_TXSTAT_TRO)
-			sc->sc_stats.ts_tx_tro++;
-		if (txstat & ATW_TXSTAT_SOFBR) {
-			sc->sc_stats.ts_tx_sofbr++;
-		}
+			sc->sc_tro_ev.ev_count++;
+		if (txstat & ATW_TXSTAT_SOFBR)
+			sc->sc_sofbr_ev.ev_count++;
 
 		if ((txstat & ATW_TXSTAT_ES) == 0)
 			ifp->if_collisions +=
@@ -3330,14 +3355,7 @@
 		ifp->if_opackets++;
 	}
 
-	/*
-	 * If there are no more pending transmissions, cancel the watchdog
-	 * timer.
-	 */
-	if (txs == NULL) {
-		KASSERT((ifp->if_flags & IFF_OACTIVE) == 0);
-		sc->sc_tx_timer = 0;
-	}
+	KASSERT(txs != NULL || (ifp->if_flags & IFF_OACTIVE) == 0);
 }
 
 /*
@@ -3355,18 +3373,14 @@
 	if (ATW_IS_ENABLED(sc) == 0)
 		return;
 
-	if (sc->sc_rescan_timer) {
-		if (--sc->sc_rescan_timer == 0)
-			(void)ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
-	}
-	if (sc->sc_tx_timer) {
-		if (--sc->sc_tx_timer == 0 &&
-		    !SIMPLEQ_EMPTY(&sc->sc_txdirtyq)) {
-			printf("%s: transmit timeout\n", ifp->if_xname);
-			ifp->if_oerrors++;
-			(void)atw_init(ifp);
-			atw_start(ifp);
-		}
+	if (sc->sc_rescan_timer != 0 && --sc->sc_rescan_timer == 0)
+		(void)ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+	if (sc->sc_tx_timer != 0 && --sc->sc_tx_timer == 0 &&
+	    !SIMPLEQ_EMPTY(&sc->sc_txdirtyq)) {
+		printf("%s: transmit timeout\n", ifp->if_xname);
+		ifp->if_oerrors++;
+		(void)atw_init(ifp);
+		atw_start(ifp);
 	}
 	if (sc->sc_tx_timer != 0 || sc->sc_rescan_timer != 0)
 		ifp->if_timer = 1;
@@ -3382,6 +3396,18 @@
 	evcnt_detach(&sc->sc_crc32e_ev);
 	evcnt_detach(&sc->sc_crc16e_ev);
 	evcnt_detach(&sc->sc_recv_ev);
+
+	evcnt_detach(&sc->sc_tuf_ev);
+	evcnt_detach(&sc->sc_tro_ev);
+	evcnt_detach(&sc->sc_trt_ev);
+	evcnt_detach(&sc->sc_tlt_ev);
+	evcnt_detach(&sc->sc_sofbr_ev);
+	evcnt_detach(&sc->sc_xmit_ev);
+
+	evcnt_detach(&sc->sc_rxpkt1in_ev);
+	evcnt_detach(&sc->sc_rxamatch_ev);
+	evcnt_detach(&sc->sc_workaround1_ev);
+	evcnt_detach(&sc->sc_misc_ev);
 }
 
 static void
@@ -3399,6 +3425,28 @@
 	    &sc->sc_recv_ev, sc->sc_if.if_xname, "PLCP SFD error");
 	evcnt_attach_dynamic(&sc->sc_sige_ev, EVCNT_TYPE_MISC,
 	    &sc->sc_recv_ev, sc->sc_if.if_xname, "PLCP Signal Field error");
+
+	evcnt_attach_dynamic(&sc->sc_xmit_ev, EVCNT_TYPE_MISC,
+	    NULL, sc->sc_if.if_xname, "xmit");
+	evcnt_attach_dynamic(&sc->sc_tuf_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_xmit_ev, sc->sc_if.if_xname, "transmit underflow");
+	evcnt_attach_dynamic(&sc->sc_tro_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_xmit_ev, sc->sc_if.if_xname, "transmit overrun");
+	evcnt_attach_dynamic(&sc->sc_trt_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_xmit_ev, sc->sc_if.if_xname, "retry count exceeded");
+	evcnt_attach_dynamic(&sc->sc_tlt_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_xmit_ev, sc->sc_if.if_xname, "lifetime exceeded");
+	evcnt_attach_dynamic(&sc->sc_sofbr_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_xmit_ev, sc->sc_if.if_xname, "packet size mismatch");
+
+	evcnt_attach_dynamic(&sc->sc_misc_ev, EVCNT_TYPE_MISC,
+	    NULL, sc->sc_if.if_xname, "misc");
+	evcnt_attach_dynamic(&sc->sc_workaround1_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_misc_ev, sc->sc_if.if_xname, "workaround #1");
+	evcnt_attach_dynamic(&sc->sc_rxamatch_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_misc_ev, sc->sc_if.if_xname, "rra equals rwa");
+	evcnt_attach_dynamic(&sc->sc_rxpkt1in_ev, EVCNT_TYPE_MISC,
+	    &sc->sc_misc_ev, sc->sc_if.if_xname, "rxpkt1in set");
 }
 
 #ifdef ATW_DEBUG
@@ -3441,6 +3489,7 @@
 	struct ieee80211_frame_min *whm;
 	struct ieee80211_frame *wh;
 	struct atw_frame *hh;
+	uint16_t hdrctl;
 	struct mbuf *m0, *m;
 	struct atw_txsoft *txs, *last_txs;
 	struct atw_txdesc *txd;
@@ -3472,6 +3521,8 @@
 	while ((txs = SIMPLEQ_FIRST(&sc->sc_txfreeq)) != NULL &&
 	       sc->sc_txfree != 0) {
 
+		hdrctl = htole16(ATW_HDRCTL_UNKNOWN1);
+
 		/*
 		 * Grab a packet off the management queue, if it
 		 * is not empty. Otherwise, from the data queue.
@@ -3515,6 +3566,14 @@
 			ifp->if_oerrors++;
 			break;
 		}
+#if 0
+		if (IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+		    m0->m_pkthdr.len > ic->ic_fragthreshold)
+			hdrctl |= htole16(ATW_HDRCTL_MORE_FRAG);
+#endif
+
+		if (m0->m_pkthdr.len + IEEE80211_CRC_LEN >= ic->ic_rtsthreshold)
+			hdrctl |= htole16(ATW_HDRCTL_RTSCTS);
 
 		if (ieee80211_compute_duration(whm, k, m0->m_pkthdr.len,
 		    ic->ic_flags, ic->ic_fragthreshold, rate,
@@ -3593,12 +3652,20 @@
 		hh->atw_paylen = htole16(m0->m_pkthdr.len -
 		    sizeof(struct atw_frame));
 
-		hh->atw_fragthr = htole16(ic->ic_fragthreshold);
+		/* never fragment multicast frames */
+		if (IEEE80211_IS_MULTICAST(hh->atw_dst))
+			hh->atw_fragthr = htole16(IEEE80211_FRAG_MAX);
+		else {
+			if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+			    (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
+				hdrctl |= htole16(ATW_HDRCTL_SHORT_PREAMBLE);
+			hh->atw_fragthr = htole16(ic->ic_fragthreshold);
+		}
+
 		hh->atw_rtylmt = 3;
-		hh->atw_hdrctl = htole16(ATW_HDRCTL_UNKNOWN1);
 #if 0
 		if (do_encrypt) {
-			hh->atw_hdrctl |= htole16(ATW_HDRCTL_WEP);
+			hdrctl |= htole16(ATW_HDRCTL_WEP);
 			hh->atw_keyid = ic->ic_def_txkey;
 		}
 #endif
@@ -3612,15 +3679,9 @@
 		hh->atw_head_dur = htole16(txs->txs_d0.d_rts_dur);
 		hh->atw_tail_dur = htole16(txs->txs_dn.d_rts_dur);
 
-		/* never fragment multicast frames */
-		if (IEEE80211_IS_MULTICAST(hh->atw_dst)) {
-			hh->atw_fragthr = htole16(ic->ic_fragthreshold);
-		} else if (sc->sc_flags & ATWF_RTSCTS) {
-			hh->atw_hdrctl |= htole16(ATW_HDRCTL_RTSCTS);
-		}
-
+		hh->atw_hdrctl = hdrctl;
+		hh->atw_fragnum = npkt << 4;
 #ifdef ATW_DEBUG
-		hh->atw_fragnum = 0;
 
 		if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
 			printf("%s: dst = %s, rate = 0x%02x, "
@@ -3833,6 +3894,7 @@
 atw_ioctl(struct ifnet *ifp, u_long cmd, void *data)
 {
 	struct atw_softc *sc = ifp->if_softc;
+	struct ieee80211req *ireq;
 	int s, error = 0;
 
 	/* XXX monkey see, monkey do. comes from wi_ioctl. */
@@ -3866,6 +3928,22 @@
 			error = 0;
 		}
 		break;
+	case SIOCS80211:
+		ireq = data;
+		if (ireq->i_type == IEEE80211_IOC_FRAGTHRESHOLD) {
+			if ((error = kauth_authorize_network(curlwp->l_cred,
+			    KAUTH_NETWORK_INTERFACE,
+			    KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp,
+			    (void *)cmd, NULL) != 0))
+				break;
+			if (!(IEEE80211_FRAG_MIN <= ireq->i_val &&
+			      ireq->i_val <= IEEE80211_FRAG_MAX))
+				error = EINVAL;
+			else
+				sc->sc_ic.ic_fragthreshold = ireq->i_val;
+			break;
+		}
+		/*FALLTHROUGH*/
 	default:
 		error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
 		if (error == ENETRESET || error == ERESTART) {

Index: src/sys/dev/ic/atwvar.h
diff -u src/sys/dev/ic/atwvar.h:1.31 src/sys/dev/ic/atwvar.h:1.32
--- src/sys/dev/ic/atwvar.h:1.31	Tue May 12 14:25:17 2009
+++ src/sys/dev/ic/atwvar.h	Sun Sep 13 22:07:34 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: atwvar.h,v 1.31 2009/05/12 14:25:17 cegger Exp $	*/
+/*	$NetBSD: atwvar.h,v 1.32 2009/09/13 22:07:34 dyoung Exp $	*/
 
 /*
  * Copyright (c) 2003, 2004 The NetBSD Foundation, Inc.  All rights reserved.
@@ -36,17 +36,6 @@
 #include <sys/time.h>
 
 /*
- * Some misc. statics, useful for debugging.
- */
-struct atw_stats {
-	u_long		ts_tx_tuf;	/* transmit underflow errors */
-	u_long		ts_tx_tro;	/* transmit jabber timeouts */
-	u_long		ts_tx_trt;	/* retry count exceeded */
-	u_long		ts_tx_tlt;	/* lifetime exceeded */
-	u_long		ts_tx_sofbr;	/* packet size mismatch */
-};
-
-/*
  * Transmit descriptor list size.  This is arbitrary, but allocate
  * enough descriptors for 64 pending transmissions and 16 segments
  * per packet.  Since a descriptor holds 2 buffer addresses, that's
@@ -192,8 +181,6 @@
 	struct ieee80211_node	*(*sc_node_alloc)(struct ieee80211_node_table*);
 	void			(*sc_node_free)(struct ieee80211_node *);
 
-	struct atw_stats sc_stats;	/* debugging stats */
-
 	int			sc_tx_timer;
 	int			sc_rescan_timer;
 
@@ -252,9 +239,6 @@
 	u_int32_t	sc_txint_mask;	/* mask of Tx interrupts we want */
 	u_int32_t	sc_linkint_mask;/* link-state interrupts mask */
 
-	/* interrupt acknowledge hook */
-	void (*sc_intr_ack)(struct atw_softc *);
-
 	enum atw_rftype		sc_rftype;
 	enum atw_bbptype	sc_bbptype;
 	u_int32_t	sc_synctl_rd;
@@ -275,6 +259,18 @@
 	uint8_t		sc_rf3000_options1;
 	uint8_t		sc_rf3000_options2;
 
+	struct evcnt	sc_misc_ev;
+	struct evcnt	sc_workaround1_ev;
+	struct evcnt	sc_rxamatch_ev;
+	struct evcnt	sc_rxpkt1in_ev;
+
+	struct evcnt	sc_xmit_ev;
+	struct evcnt	sc_tuf_ev;	/* transmit underflow errors */
+	struct evcnt	sc_tro_ev;	/* transmit overrun */
+	struct evcnt	sc_trt_ev;	/* retry count exceeded */
+	struct evcnt	sc_tlt_ev;	/* lifetime exceeded */
+	struct evcnt	sc_sofbr_ev;	/* packet size mismatch */
+
 	struct evcnt	sc_recv_ev;
 	struct evcnt	sc_crc16e_ev;
 	struct evcnt	sc_crc32e_ev;
@@ -345,9 +341,13 @@
 #define atw_ihdr	u.s2.ihdr
 
 #define ATW_HDRCTL_SHORT_PREAMBLE	__BIT(0)	/* use short preamble */
+#define ATW_HDRCTL_MORE_FRAG		__BIT(1)	/* ??? from Linux */
+#define ATW_HDRCTL_MORE_DATA		__BIT(2)	/* ??? from Linux */
+#define ATW_HDRCTL_FRAG_NUM		__BIT(3)	/* ??? from Linux */
 #define ATW_HDRCTL_RTSCTS		__BIT(4)	/* send RTS */
 #define ATW_HDRCTL_WEP			__BIT(5)
-#define ATW_HDRCTL_UNKNOWN1		__BIT(15) /* MAC adds FCS? */
+/* MAC adds FCS?  Linux calls this "enable extended header" */
+#define ATW_HDRCTL_UNKNOWN1		__BIT(15)
 #define ATW_HDRCTL_UNKNOWN2		__BIT(8)
 
 #define ATW_FRAGTHR_FRAGTHR_MASK	__BITS(0, 11)
@@ -358,10 +358,9 @@
 #define	ATWF_MRM		0x00000002	/* memory read multi okay */
 #define	ATWF_MWI		0x00000004	/* memory write inval okay */
 #define	ATWF_SHORT_PREAMBLE	0x00000008	/* short preamble enabled */
-#define	ATWF_RTSCTS		0x00000010	/* RTS/CTS enabled */
-#define	ATWF_ATTACHED		0x00000020	/* attach has succeeded */
-#define	ATWF_ENABLED		0x00000040	/* chip is enabled */
-#define	ATWF_WEP_SRAM_VALID	0x00000080	/* SRAM matches s/w state */
+#define	ATWF_ATTACHED		0x00000010	/* attach has succeeded */
+#define	ATWF_ENABLED		0x00000020	/* chip is enabled */
+#define	ATWF_WEP_SRAM_VALID	0x00000040	/* SRAM matches s/w state */
 
 #define	ATW_IS_ENABLED(sc)	((sc)->sc_flags & ATWF_ENABLED)
 

Reply via email to