Question about kern/85886: [an] an0: timeouts with Cisco 350 minipci

Max Belov max_belov at yahoo.com
Fri Mar 27 12:16:38 PDT 2009


Hi All,

I've recently installed FreeBSD 7.1-RELEASE on the old ThinkPad T41 and I've found that the problem reported in the kern/85886 still exists. I was able to find a fix for this bug in the DragonFly BSD (http://www.mail-archive.com/bugs@crater.dragonflybsd.org/msg03677.html). I've merged the fix with the AiroNet driver which is distributed with Free BSD and so far it is working like a charm. I don't know if anybody planning to fix it, or it just was forgotten. Here is the fix which I'm using merged with the code from 7.1-RELEASE. It would be nice to merge it with the trunk if it was forgotten: 

--- an.orig/if_anreg.h    2008-11-25 02:59:29.000000000 +0000
+++ an/if_anreg.h    2009-03-22 00:02:50.000000000 +0000
@@ -394,14 +394,17 @@
 #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_8023    \
-    (AN_TXCTL_TXOK_INTR|AN_TXCTL_TXERR_INTR|AN_HEADERTYPE_8023|    \
-    AN_PAYLOADTYPE_ETHER|AN_TXCTL_NORELEASE)
+#define AN_TXCTL_80211         (AN_HEADERTYPE_80211|AN_PAYLOADTYPE_LLC)
 
+#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
 
 

--- an.orig/if_an.c    2008-11-25 02:59:29.000000000 +0000
+++ an/if_an.c    2009-03-22 00:02:50.000000000 +0000
@@ -2631,7 +2631,7 @@
     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;
@@ -2658,12 +2658,14 @@
         return;
     }
 
+    ready = 0;
     idx = sc->an_rdata.an_tx_prod;
 
     if (!sc->mpi350) {
         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;
@@ -2686,7 +2688,7 @@
                    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));
@@ -2725,6 +2727,7 @@
 
         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;
@@ -2749,7 +2752,7 @@
                    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));
@@ -2771,7 +2774,7 @@
                 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))
@@ -2801,7 +2804,7 @@
         CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
     }
 
-    if (m0 != NULL)
+    if (!ready)
         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 
     sc->an_rdata.an_tx_prod = idx;


      



More information about the freebsd-bugs mailing list