Add 1us delay after reading event from event FIFO; sometimes the event
authormcb30 <mcb30>
Tue, 28 Mar 2006 14:50:04 +0000 (14:50 +0000)
committermcb30 <mcb30>
Tue, 28 Mar 2006 14:50:04 +0000 (14:50 +0000)
turns up there before the DMA is complete.

Ignore the start-of-day spurious timer firings.

src/drivers/net/etherfabric.c

index 6189d69..c1ad329 100644 (file)
@@ -945,6 +945,12 @@ static int mentormac_mdio_read ( struct efab_nic *efab, int phy_id,
 #define EF1_TX_ENGINE_EN_WIDTH 1
 #define EF1_RX_ENGINE_EN_LBN 18
 #define EF1_RX_ENGINE_EN_WIDTH 1
 #define EF1_TX_ENGINE_EN_WIDTH 1
 #define EF1_RX_ENGINE_EN_LBN 18
 #define EF1_RX_ENGINE_EN_WIDTH 1
+#define EF1_TURBO2_LBN 17
+#define EF1_TURBO2_WIDTH 1
+#define EF1_TURBO1_LBN 16
+#define EF1_TURBO1_WIDTH 1
+#define EF1_TURBO3_LBN 14
+#define EF1_TURBO3_WIDTH 1
 #define EF1_LB_RESET_LBN 3
 #define EF1_LB_RESET_WIDTH 1
 #define EF1_MAC_RESET_LBN 2
 #define EF1_LB_RESET_LBN 3
 #define EF1_LB_RESET_WIDTH 1
 #define EF1_MAC_RESET_LBN 2
@@ -1097,6 +1103,7 @@ static int mentormac_mdio_read ( struct efab_nic *efab, int phy_id,
 #define EF1_EV_CODE_WIDTH 8
 #define EF1_RX_EV_DECODE 0x01
 #define EF1_TX_EV_DECODE 0x02
 #define EF1_EV_CODE_WIDTH 8
 #define EF1_RX_EV_DECODE 0x01
 #define EF1_TX_EV_DECODE 0x02
+#define EF1_TIMER_EV_DECODE 0x0b
 #define EF1_DRV_GEN_EV_DECODE 0x0f
 
 /* Receive events */
 #define EF1_DRV_GEN_EV_DECODE 0x0f
 
 /* Receive events */
@@ -1245,6 +1252,9 @@ static int ef1002_init_nic ( struct efab_nic *efab ) {
        EFAB_SET_DWORD_FIELD ( reg, EF1_MASTER_EVENTS, 0 );
        EFAB_SET_DWORD_FIELD ( reg, EF1_TX_ENGINE_EN, 0 );
        EFAB_SET_DWORD_FIELD ( reg, EF1_RX_ENGINE_EN, 0 );
        EFAB_SET_DWORD_FIELD ( reg, EF1_MASTER_EVENTS, 0 );
        EFAB_SET_DWORD_FIELD ( reg, EF1_TX_ENGINE_EN, 0 );
        EFAB_SET_DWORD_FIELD ( reg, EF1_RX_ENGINE_EN, 0 );
+       EFAB_SET_DWORD_FIELD ( reg, EF1_TURBO2, 1 );
+       EFAB_SET_DWORD_FIELD ( reg, EF1_TURBO1, 1 );
+       EFAB_SET_DWORD_FIELD ( reg, EF1_TURBO3, 1 );
        EFAB_SET_DWORD_FIELD ( reg, EF1_CAM_ENABLE, 1 );
        ef1002_writel ( efab, &reg, EF1_CTR_GEN_STATUS0_REG );
        udelay ( 1000 );
        EFAB_SET_DWORD_FIELD ( reg, EF1_CAM_ENABLE, 1 );
        ef1002_writel ( efab, &reg, EF1_CTR_GEN_STATUS0_REG );
        udelay ( 1000 );
@@ -1379,6 +1389,7 @@ static void ef1002_build_rx_desc ( struct efab_nic *efab,
                                EF1_RX_KER_BUF_ADR,
                                virt_to_bus ( rx_buf->addr ) );
        ef1002_writel ( efab, &rxd.dword[0], EF1_RX_DESC_FIFO + 0 );
                                EF1_RX_KER_BUF_ADR,
                                virt_to_bus ( rx_buf->addr ) );
        ef1002_writel ( efab, &rxd.dword[0], EF1_RX_DESC_FIFO + 0 );
+       wmb();
        ef1002_writel ( efab, &rxd.dword[1], EF1_RX_DESC_FIFO + 4 );
        udelay ( 10 );
 }
        ef1002_writel ( efab, &rxd.dword[1], EF1_RX_DESC_FIFO + 4 );
        udelay ( 10 );
 }
@@ -1414,6 +1425,7 @@ static void ef1002_build_tx_desc ( struct efab_nic *efab,
 
        ef1002_writel ( efab, &txd.dword[0], EF1_TX_DESC_FIFO + 0 );
        ef1002_writel ( efab, &txd.dword[1], EF1_TX_DESC_FIFO + 4 );
 
        ef1002_writel ( efab, &txd.dword[0], EF1_TX_DESC_FIFO + 0 );
        ef1002_writel ( efab, &txd.dword[1], EF1_TX_DESC_FIFO + 4 );
+       wmb();
        ef1002_writel ( efab, &txd.dword[2], EF1_TX_DESC_FIFO + 8 );
        udelay ( 10 );
 }
        ef1002_writel ( efab, &txd.dword[2], EF1_TX_DESC_FIFO + 8 );
        udelay ( 10 );
 }
@@ -1461,6 +1473,13 @@ static int ef1002_fetch_event ( struct efab_nic *efab,
                /* RX len not available via event FIFO */
                event->rx_len = ETH_FRAME_LEN;
                break;
                /* RX len not available via event FIFO */
                event->rx_len = ETH_FRAME_LEN;
                break;
+       case EF1_TIMER_EV_DECODE:
+               /* These are safe to ignore.  We seem to get some at
+                * start of day, presumably due to the timers starting
+                * up with random contents.
+                */
+               event->type = EFAB_EV_NONE;
+               break;
        default:
                printf ( "Unknown event type %d\n", ev_code );
                event->type = EFAB_EV_NONE;
        default:
                printf ( "Unknown event type %d\n", ev_code );
                event->type = EFAB_EV_NONE;
@@ -2910,6 +2929,14 @@ static int etherfabric_poll ( struct nic *nic, int retrieve ) {
        if ( ! retrieve )
                return 1;
 
        if ( ! retrieve )
                return 1;
 
+       /* There seems to be a hardware race.  The event can show up
+        * on the event FIFO before the DMA has completed, so we
+        * insert a tiny delay.  If this proves unreliable, we should
+        * switch to using event DMA rather than the event FIFO, since
+        * event DMA ordering is guaranteed.
+        */
+       udelay ( 1 );
+
        /* Copy packet contents */
        nic->packetlen = rx_buf->len;
        memcpy ( nic->packet, rx_buf->addr, nic->packetlen );
        /* Copy packet contents */
        nic->packetlen = rx_buf->len;
        memcpy ( nic->packet, rx_buf->addr, nic->packetlen );