tp->timer_counter = tp->timer_multiplier;
        }
 
-       /* Heartbeat is only sent once every 2 seconds.  */
+       /* Heartbeat is only sent once every 2 seconds.
+        *
+        * The heartbeat is to tell the ASF firmware that the host
+        * driver is still alive.  In the event that the OS crashes,
+        * ASF needs to reset the hardware to free up the FIFO space
+        * that may be filled with rx packets destined for the host.
+        * If the FIFO is full, ASF will no longer function properly.
+        *
+        * Unintended resets have been reported on real time kernels
+        * where the timer doesn't run on time.  Netpoll will also have
+        * same problem.
+        *
+        * The new FWCMD_NICDRV_ALIVE3 command tells the ASF firmware
+        * to check the ring condition when the heartbeat is expiring
+        * before doing the reset.  This will prevent most unintended
+        * resets.
+        */
        if (!--tp->asf_counter) {
                if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
                        u32 val;
 
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
-                                     FWCMD_NICDRV_ALIVE2);
+                                     FWCMD_NICDRV_ALIVE3);
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
                        /* 5 seconds timeout */
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
 
 #define  FWCMD_NICDRV_FIX_DMAR          0x00000005
 #define  FWCMD_NICDRV_FIX_DMAW          0x00000006
 #define  FWCMD_NICDRV_ALIVE2            0x0000000d
+#define  FWCMD_NICDRV_ALIVE3            0x0000000e
 #define NIC_SRAM_FW_CMD_LEN_MBOX       0x00000b7c
 #define NIC_SRAM_FW_CMD_DATA_MBOX      0x00000b80
 #define NIC_SRAM_FW_ASF_STATUS_MBOX    0x00000c00