Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Nov 2009 16:48:46 -0500
From:      Jeremy O'Brien <obrien654j@gmail.com>
To:        freebsd-hackers@freebsd.org
Subject:   Cisco Aironet MPI350 Fix
Message-ID:  <20091122214846.GA24357@minifree.wright.edu>

next in thread | raw e-mail | index | archive | help

--IS0zKkzwUGydFO0o
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

I have a Cisco Aironet MPI350 PCI card in my Thinkpad X31, and on a
fresh install of FreeBSD 8.0-RC3, the card did not work. Also, it caused
my system to freeze up for a few seconds about once a minute as the
driver spit out "an0: device timeout" messages so long as the interface
was up. I researched the issue, and found the following fix already in
dragonflybsd's tree:

http://gitweb.dragonflybsd.org/dragonfly.git/commit/7a2a04db44efafea257db883ae3eb5e4ebf2ece9

I modified the patch and applied it to FreeBSD's kernel (trivial), and
am happy to report that my card is now working flawlessly. Could someone
possibly review this patch and integrate it into the source tree so that
others may benefit from it as well?

The patch is based off of 8.0-RC3's code, but applies to the latest code
as well without modification.

Thank you,
Jeremy O'Brien

--IS0zKkzwUGydFO0o
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="mpi350_fix.diff"

diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c
index 5b4f13b..f08138d 100644
--- a/sys/dev/an/if_an.c
+++ b/sys/dev/an/if_an.c
@@ -2747,7 +2747,7 @@ an_start(struct ifnet *ifp)
 	struct mbuf		*m0 = NULL;
 	struct an_txframe_802_3	tx_frame_802_3;
 	struct ether_header	*eh;
-	int			id, idx, i;
+	int			id, idx, i, ready;
 	unsigned char		txcontrol;
 	struct an_card_tx_desc an_tx_desc;
 	u_int8_t		*buf;
@@ -2774,6 +2774,7 @@ an_start(struct ifnet *ifp)
 		return;
 	}
 
+	ready = 0;
 	idx = sc->an_rdata.an_tx_prod;
 
 	AN_LOCK(sc);
@@ -2781,6 +2782,7 @@ an_start(struct ifnet *ifp)
 		bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3));
 
 		while (sc->an_rdata.an_tx_ring[idx] == 0) {
+			ready = 1;
 			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
 			if (m0 == NULL)
 				break;
@@ -2803,7 +2805,7 @@ an_start(struct ifnet *ifp)
 				   tx_frame_802_3.an_tx_802_3_payload_len,
 				   (caddr_t)&sc->an_txbuf);
 
-			txcontrol = AN_TXCTL_8023;
+			txcontrol = AN_TXCTL_8023 | AN_TXCTL_HW(sc->mpi350);
 			/* write the txcontrol only */
 			an_write_data(sc, id, 0x08, (caddr_t)&txcontrol,
 				      sizeof(txcontrol));
@@ -2842,6 +2844,7 @@ an_start(struct ifnet *ifp)
 
 		while (sc->an_rdata.an_tx_empty ||
 		    idx != sc->an_rdata.an_tx_cons) {
+			ready = 1;
 			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
 			if (m0 == NULL) {
 				break;
@@ -2866,7 +2869,7 @@ an_start(struct ifnet *ifp)
 				   tx_frame_802_3.an_tx_802_3_payload_len,
 				   (caddr_t)&sc->an_txbuf);
 
-			txcontrol = AN_TXCTL_8023;
+			txcontrol = AN_TXCTL_8023 | AN_TXCTL_HW(sc->mpi350);
 			/* write the txcontrol only */
 			bcopy((caddr_t)&txcontrol, &buf[0x08],
 			      sizeof(txcontrol));
@@ -2888,7 +2891,7 @@ an_start(struct ifnet *ifp)
 			    tx_frame_802_3.an_tx_802_3_payload_len;
 			an_tx_desc.an_phys
 			    = sc->an_tx_buffer[idx].an_dma_paddr;
-			for (i = 0; i < sizeof(an_tx_desc) / 4 ; i++) {
+			for (i = sizeof(an_tx_desc) / 4 - 1; i >= 0; --i) {
 				CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET
 				    /* zero for now */
 				    + (0 * sizeof(an_tx_desc))
@@ -2919,7 +2922,7 @@ an_start(struct ifnet *ifp)
 	}
 	AN_UNLOCK(sc);
 
-	if (m0 != NULL)
+	if (!ready)
 		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 
 	sc->an_rdata.an_tx_prod = idx;
diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h
index 103572a..8f3d30a 100644
--- a/sys/dev/an/if_anreg.h
+++ b/sys/dev/an/if_anreg.h
@@ -394,13 +394,16 @@ struct an_txframe_802_3 {
 #define AN_PAYLOADTYPE_ETHER	0x0000
 #define AN_PAYLOADTYPE_LLC	0x0010
 
-#define AN_TXCTL_80211	\
-	(AN_TXCTL_TXOK_INTR|AN_TXCTL_TXERR_INTR|AN_HEADERTYPE_80211|	\
-	AN_PAYLOADTYPE_LLC|AN_TXCTL_NORELEASE)
+#define AN_TXCTL_80211		(AN_HEADERTYPE_80211|AN_PAYLOADTYPE_LLC)
 
-#define AN_TXCTL_8023	\
-	(AN_TXCTL_TXOK_INTR|AN_TXCTL_TXERR_INTR|AN_HEADERTYPE_8023|	\
-	AN_PAYLOADTYPE_ETHER|AN_TXCTL_NORELEASE)
+#define AN_TXCTL_8023		(AN_HEADERTYPE_8023|AN_PAYLOADTYPE_ETHER)
+
+/* 
+ * Additions to transmit control bits for MPI350
+ */
+
+#define AN_TXCTL_HW(x)		( x ? (AN_TXCTL_NORELEASE) : \
+	(AN_TXCTL_TXOK_INTR|AN_TXCTL_TXERR_INTR|AN_TXCTL_NORELEASE))
 
 #define AN_TXGAP_80211		0
 #define AN_TXGAP_8023		0

--IS0zKkzwUGydFO0o--



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