#define TX_BW_MTU(p)                   (0x0458 + ((p) << 10))
 #define TX_BW_BURST(p)                 (0x045c + ((p) << 10))
 #define INT_CAUSE(p)                   (0x0460 + ((p) << 10))
+#define  INT_TX_END                    0x07f80000
 #define  INT_RX                                0x0007fbfc
 #define  INT_EXT                       0x00000002
 #define INT_CAUSE_EXT(p)               (0x0464 + ((p) << 10))
                netif_rx_complete(mp->dev, napi);
                wrl(mp, INT_CAUSE(mp->port_num), 0);
                wrl(mp, INT_CAUSE_EXT(mp->port_num), 0);
-               wrl(mp, INT_MASK(mp->port_num), INT_RX | INT_EXT);
+               wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
        }
 
        return rx;
        struct mv643xx_eth_private *mp = netdev_priv(dev);
        u32 int_cause;
        u32 int_cause_ext;
+       u32 txq_active;
 
-       int_cause = rdl(mp, INT_CAUSE(mp->port_num)) & (INT_RX | INT_EXT);
+       int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &
+                       (INT_TX_END | INT_RX | INT_EXT);
        if (int_cause == 0)
                return IRQ_NONE;
 
        }
 #endif
 
+       txq_active = rdl(mp, TXQ_COMMAND(mp->port_num));
+
        /*
         * TxBuffer or TxError set for any of the 8 queues?
         */
                for (i = 0; i < 8; i++)
                        if (mp->txq_mask & (1 << i))
                                txq_reclaim(mp->txq + i, 0);
+       }
 
-               __txq_maybe_wake(mp->txq + mp->txq_primary);
+       /*
+        * Any TxEnd interrupts?
+        */
+       if (int_cause & INT_TX_END) {
+               int i;
+
+               wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_TX_END));
+               for (i = 0; i < 8; i++) {
+                       struct tx_queue *txq = mp->txq + i;
+                       if (txq->tx_desc_count && !((txq_active >> i) & 1))
+                               txq_enable(txq);
+               }
+       }
+
+       /*
+        * Enough space again in the primary TX queue for a full packet?
+        */
+       if (int_cause_ext & INT_EXT_TX) {
+               struct tx_queue *txq = mp->txq + mp->txq_primary;
+               __txq_maybe_wake(txq);
        }
 
        return IRQ_HANDLED;
        wrl(mp, INT_MASK_EXT(mp->port_num),
            INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);
 
-       wrl(mp, INT_MASK(mp->port_num), INT_RX | INT_EXT);
+       wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
 
        return 0;
 
 
        mv643xx_eth_irq(dev->irq, dev);
 
-       wrl(mp, INT_MASK(mp->port_num), INT_RX | INT_CAUSE_EXT);
+       wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_CAUSE_EXT);
 }
 #endif