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>