#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_RX                                0x00000804
+#define  INT_RX                                0x0007fbfc
 #define  INT_EXT                       0x00000002
 #define INT_CAUSE_EXT(p)               (0x0464 + ((p) << 10))
 #define  INT_EXT_LINK                  0x00100000
 #define INT_MASK(p)                    (0x0468 + ((p) << 10))
 #define INT_MASK_EXT(p)                        (0x046c + ((p) << 10))
 #define TX_FIFO_URGENT_THRESHOLD(p)    (0x0474 + ((p) << 10))
-#define RXQ_CURRENT_DESC_PTR(p)                (0x060c + ((p) << 10))
+#define RXQ_CURRENT_DESC_PTR(p, q)     (0x060c + ((p) << 10) + ((q) << 4))
 #define RXQ_COMMAND(p)                 (0x0680 + ((p) << 10))
 #define TXQ_CURRENT_DESC_PTR(p)                (0x06c0 + ((p) << 10))
 #define TXQ_BW_TOKENS(p)               (0x0700 + ((p) << 10))
 };
 
 struct rx_queue {
+       int index;
+
        int rx_ring_size;
 
        int rx_desc_count;
        int default_rx_ring_size;
        unsigned long rx_desc_sram_addr;
        int rx_desc_sram_size;
+       u8 rxq_mask;
+       int rxq_primary;
        struct napi_struct napi;
-       struct rx_queue rxq[1];
+       struct rx_queue rxq[8];
 
        /*
         * TX state.
 /* rxq/txq helper functions *************************************************/
 static struct mv643xx_eth_private *rxq_to_mp(struct rx_queue *rxq)
 {
-       return container_of(rxq, struct mv643xx_eth_private, rxq[0]);
+       return container_of(rxq, struct mv643xx_eth_private, rxq[rxq->index]);
 }
 
 static struct mv643xx_eth_private *txq_to_mp(struct tx_queue *txq)
 static void rxq_enable(struct rx_queue *rxq)
 {
        struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
-       wrl(mp, RXQ_COMMAND(mp->port_num), 1);
+       wrl(mp, RXQ_COMMAND(mp->port_num), 1 << rxq->index);
 }
 
 static void rxq_disable(struct rx_queue *rxq)
 {
        struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
-       u8 mask = 1;
+       u8 mask = 1 << rxq->index;
 
        wrl(mp, RXQ_COMMAND(mp->port_num), mask << 8);
        while (rdl(mp, RXQ_COMMAND(mp->port_num)) & mask)
 {
        struct mv643xx_eth_private *mp;
        int rx;
+       int i;
 
        mp = container_of(napi, struct mv643xx_eth_private, napi);
 
        }
 #endif
 
-       rx = rxq_process(mp->rxq, budget);
+       rx = 0;
+       for (i = 7; rx < budget && i >= 0; i--)
+               if (mp->rxq_mask & (1 << i))
+                       rx += rxq_process(mp->rxq + i, budget - rx);
 
        if (rx < budget) {
                netif_rx_complete(mp->dev, napi);
 
 
 /* rx/tx queue initialisation ***********************************************/
-static int rxq_init(struct mv643xx_eth_private *mp)
+static int rxq_init(struct mv643xx_eth_private *mp, int index)
 {
-       struct rx_queue *rxq = mp->rxq;
+       struct rx_queue *rxq = mp->rxq + index;
        struct rx_desc *rx_desc;
        int size;
        int i;
 
+       rxq->index = index;
+
        rxq->rx_ring_size = mp->default_rx_ring_size;
 
        rxq->rx_desc_count = 0;
 
        size = rxq->rx_ring_size * sizeof(struct rx_desc);
 
-       if (size <= mp->rx_desc_sram_size) {
+       if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size) {
                rxq->rx_desc_area = ioremap(mp->rx_desc_sram_addr,
                                                mp->rx_desc_sram_size);
                rxq->rx_desc_dma = mp->rx_desc_sram_addr;
 
 
 out_free:
-       if (size <= mp->rx_desc_sram_size)
+       if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size)
                iounmap(rxq->rx_desc_area);
        else
                dma_free_coherent(NULL, size,
                           rxq->rx_desc_count);
        }
 
-       if (rxq->rx_desc_area_size <= mp->rx_desc_sram_size)
+       if (rxq->index == mp->rxq_primary &&
+           rxq->rx_desc_area_size <= mp->rx_desc_sram_size)
                iounmap(rxq->rx_desc_area);
        else
                dma_free_coherent(NULL, rxq->rx_desc_area_size,
                }
        }
 
+       /*
+        * RxBuffer or RxError set for any of the 8 queues?
+        */
 #ifdef MV643XX_ETH_NAPI
        if (int_cause & INT_RX) {
                wrl(mp, INT_MASK(mp->port_num), 0x00000000);
                netif_rx_schedule(dev, &mp->napi);
        }
 #else
-       if (int_cause & INT_RX)
-               rxq_process(mp->rxq, INT_MAX);
+       if (int_cause & INT_RX) {
+               int i;
+
+               for (i = 7; i >= 0; i--)
+                       if (mp->rxq_mask & (1 << i))
+                               rxq_process(mp->rxq + i, INT_MAX);
+       }
 #endif
 
        if (int_cause_ext & INT_EXT_TX) {
        wrl(mp, PORT_CONFIG_EXT(mp->port_num), 0x00000000);
 
        /*
-        * Enable the receive queue.
+        * Enable the receive queues.
         */
-       for (i = 0; i < 1; i++) {
-               struct rx_queue *rxq = mp->rxq;
-               int off = RXQ_CURRENT_DESC_PTR(mp->port_num);
+       for (i = 0; i < 8; i++) {
+               struct rx_queue *rxq = mp->rxq + i;
+               int off = RXQ_CURRENT_DESC_PTR(mp->port_num, i);
                u32 addr;
 
+               if ((mp->rxq_mask & (1 << i)) == 0)
+                       continue;
+
                addr = (u32)rxq->rx_desc_dma;
                addr += rxq->rx_curr_desc * sizeof(struct rx_desc);
                wrl(mp, off, addr);
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
        int err;
+       int i;
 
        wrl(mp, INT_CAUSE(mp->port_num), 0);
        wrl(mp, INT_CAUSE_EXT(mp->port_num), 0);
 
        init_mac_tables(mp);
 
-       err = rxq_init(mp);
-       if (err)
-               goto out;
-       rxq_refill(mp->rxq);
+       for (i = 0; i < 8; i++) {
+               if ((mp->rxq_mask & (1 << i)) == 0)
+                       continue;
+
+               err = rxq_init(mp, i);
+               if (err) {
+                       while (--i >= 0)
+                               if (mp->rxq_mask & (1 << i))
+                                       rxq_deinit(mp->rxq + i);
+                       goto out;
+               }
+
+               rxq_refill(mp->rxq + i);
+       }
 
        err = txq_init(mp);
        if (err)
 
 
 out_free:
-       rxq_deinit(mp->rxq);
+       for (i = 0; i < 8; i++)
+               if (mp->rxq_mask & (1 << i))
+                       rxq_deinit(mp->rxq + i);
 out:
        free_irq(dev->irq, dev);
 
 static void port_reset(struct mv643xx_eth_private *mp)
 {
        unsigned int data;
+       int i;
 
+       for (i = 0; i < 8; i++) {
+               if (mp->rxq_mask & (1 << i))
+                       rxq_disable(mp->rxq + i);
+       }
        txq_disable(mp->txq);
-       rxq_disable(mp->rxq);
        while (!(rdl(mp, PORT_STATUS(mp->port_num)) & TX_FIFO_EMPTY))
                udelay(10);
 
 static int mv643xx_eth_stop(struct net_device *dev)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
+       int i;
 
        wrl(mp, INT_MASK(mp->port_num), 0x00000000);
        rdl(mp, INT_MASK(mp->port_num));
        port_reset(mp);
        mib_counters_update(mp);
 
+       for (i = 0; i < 8; i++) {
+               if (mp->rxq_mask & (1 << i))
+                       rxq_deinit(mp->rxq + i);
+       }
        txq_deinit(mp->txq);
-       rxq_deinit(mp->rxq);
 
        return 0;
 }
        mp->rx_desc_sram_addr = pd->rx_sram_addr;
        mp->rx_desc_sram_size = pd->rx_sram_size;
 
+       if (pd->rx_queue_mask)
+               mp->rxq_mask = pd->rx_queue_mask;
+       else
+               mp->rxq_mask = 0x01;
+       mp->rxq_primary = fls(mp->rxq_mask) - 1;
+
        mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
        if (pd->tx_queue_size)
                mp->default_tx_ring_size = pd->tx_queue_size;