DBGPR("-->xgbe_free_ring_resources\n");
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                xgbe_free_ring(pdata, channel->tx_ring);
                xgbe_free_ring(pdata, channel->rx_ring);
        }
        DBGPR("<--xgbe_free_ring_resources\n");
 }
 
+static void *xgbe_alloc_node(size_t size, int node)
+{
+       void *mem;
+
+       mem = kzalloc_node(size, GFP_KERNEL, node);
+       if (!mem)
+               mem = kzalloc(size, GFP_KERNEL);
+
+       return mem;
+}
+
+static void *xgbe_dma_alloc_node(struct device *dev, size_t size,
+                                dma_addr_t *dma, int node)
+{
+       void *mem;
+       int cur_node = dev_to_node(dev);
+
+       set_dev_node(dev, node);
+       mem = dma_alloc_coherent(dev, size, dma, GFP_KERNEL);
+       set_dev_node(dev, cur_node);
+
+       if (!mem)
+               mem = dma_alloc_coherent(dev, size, dma, GFP_KERNEL);
+
+       return mem;
+}
+
 static int xgbe_init_ring(struct xgbe_prv_data *pdata,
                          struct xgbe_ring *ring, unsigned int rdesc_count)
 {
-       DBGPR("-->xgbe_init_ring\n");
+       size_t size;
 
        if (!ring)
                return 0;
 
        /* Descriptors */
+       size = rdesc_count * sizeof(struct xgbe_ring_desc);
+
        ring->rdesc_count = rdesc_count;
-       ring->rdesc = dma_alloc_coherent(pdata->dev,
-                                        (sizeof(struct xgbe_ring_desc) *
-                                         rdesc_count), &ring->rdesc_dma,
-                                        GFP_KERNEL);
+       ring->rdesc = xgbe_dma_alloc_node(pdata->dev, size, &ring->rdesc_dma,
+                                         ring->node);
        if (!ring->rdesc)
                return -ENOMEM;
 
        /* Descriptor information */
-       ring->rdata = kcalloc(rdesc_count, sizeof(struct xgbe_ring_data),
-                             GFP_KERNEL);
+       size = rdesc_count * sizeof(struct xgbe_ring_data);
+
+       ring->rdata = xgbe_alloc_node(size, ring->node);
        if (!ring->rdata)
                return -ENOMEM;
 
        netif_dbg(pdata, drv, pdata->netdev,
-                 "rdesc=%p, rdesc_dma=%pad, rdata=%p\n",
-                 ring->rdesc, &ring->rdesc_dma, ring->rdata);
-
-       DBGPR("<--xgbe_init_ring\n");
+                 "rdesc=%p, rdesc_dma=%pad, rdata=%p, node=%d\n",
+                 ring->rdesc, &ring->rdesc_dma, ring->rdata, ring->node);
 
        return 0;
 }
        unsigned int i;
        int ret;
 
-       DBGPR("-->xgbe_alloc_ring_resources\n");
-
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                netif_dbg(pdata, drv, pdata->netdev, "%s - Tx ring:\n",
                          channel->name);
 
                }
        }
 
-       DBGPR("<--xgbe_alloc_ring_resources\n");
-
        return 0;
 
 err_ring:
 }
 
 static int xgbe_alloc_pages(struct xgbe_prv_data *pdata,
-                           struct xgbe_page_alloc *pa, gfp_t gfp, int order)
+                           struct xgbe_page_alloc *pa, int alloc_order,
+                           int node)
 {
        struct page *pages = NULL;
        dma_addr_t pages_dma;
-       int ret;
+       gfp_t gfp;
+       int order, ret;
+
+again:
+       order = alloc_order;
 
        /* Try to obtain pages, decreasing order if necessary */
-       gfp |= __GFP_COLD | __GFP_COMP | __GFP_NOWARN;
+       gfp = GFP_ATOMIC | __GFP_COLD | __GFP_COMP | __GFP_NOWARN;
        while (order >= 0) {
-               pages = alloc_pages(gfp, order);
+               pages = alloc_pages_node(node, gfp, order);
                if (pages)
                        break;
 
                order--;
        }
+
+       /* If we couldn't get local pages, try getting from anywhere */
+       if (!pages && (node != NUMA_NO_NODE)) {
+               node = NUMA_NO_NODE;
+               goto again;
+       }
+
        if (!pages)
                return -ENOMEM;
 
        int ret;
 
        if (!ring->rx_hdr_pa.pages) {
-               ret = xgbe_alloc_pages(pdata, &ring->rx_hdr_pa, GFP_ATOMIC, 0);
+               ret = xgbe_alloc_pages(pdata, &ring->rx_hdr_pa, 0, ring->node);
                if (ret)
                        return ret;
        }
 
        if (!ring->rx_buf_pa.pages) {
-               ret = xgbe_alloc_pages(pdata, &ring->rx_buf_pa, GFP_ATOMIC,
-                                      PAGE_ALLOC_COSTLY_ORDER);
+               ret = xgbe_alloc_pages(pdata, &ring->rx_buf_pa,
+                                      PAGE_ALLOC_COSTLY_ORDER, ring->node);
                if (ret)
                        return ret;
        }
 
        DBGPR("-->xgbe_wrapper_tx_descriptor_init\n");
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                ring = channel->tx_ring;
                if (!ring)
                        break;
 
        DBGPR("-->xgbe_wrapper_rx_descriptor_init\n");
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                ring = channel->rx_ring;
                if (!ring)
                        break;
 
 
 static int xgbe_config_pblx8(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++)
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_CR, PBLX8,
+       for (i = 0; i < pdata->channel_count; i++)
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_CR, PBLX8,
                                       pdata->pblx8);
 
        return 0;
 
 static int xgbe_get_tx_pbl_val(struct xgbe_prv_data *pdata)
 {
-       return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_TCR, PBL);
+       return XGMAC_DMA_IOREAD_BITS(pdata->channel[0], DMA_CH_TCR, PBL);
 }
 
 static int xgbe_config_tx_pbl_val(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->tx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->tx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, PBL,
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_TCR, PBL,
                                       pdata->tx_pbl);
        }
 
 
 static int xgbe_get_rx_pbl_val(struct xgbe_prv_data *pdata)
 {
-       return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_RCR, PBL);
+       return XGMAC_DMA_IOREAD_BITS(pdata->channel[0], DMA_CH_RCR, PBL);
 }
 
 static int xgbe_config_rx_pbl_val(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, PBL,
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_RCR, PBL,
                                       pdata->rx_pbl);
        }
 
 
 static int xgbe_config_osp_mode(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->tx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->tx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, OSP,
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_TCR, OSP,
                                       pdata->tx_osp_mode);
        }
 
 
 static int xgbe_config_rx_coalesce(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RIWT, RWT,
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_RIWT, RWT,
                                       pdata->rx_riwt);
        }
 
 
 static void xgbe_config_rx_buffer_size(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, RBSZ,
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_RCR, RBSZ,
                                       pdata->rx_buf_size);
        }
 }
 
 static void xgbe_config_tso_mode(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->tx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->tx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, TSE, 1);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_TCR, TSE, 1);
        }
 }
 
 static void xgbe_config_sph_mode(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_CR, SPH, 1);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_CR, SPH, 1);
        }
 
        XGMAC_IOWRITE_BITS(pdata, MAC_RCR, HDSMS, XGBE_SPH_HDSMS_SIZE);
                XGMAC_IOWRITE_BITS(pdata, DMA_MR, INTM,
                                   pdata->channel_irq_mode);
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
+
                /* Clear all the interrupts which are set */
                dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR);
                XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr);
 
 static void xgbe_enable_tx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
        /* Enable each Tx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->tx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->tx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_TCR, ST, 1);
        }
 
        /* Enable each Tx queue */
 
 static void xgbe_disable_tx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
        /* Prepare for Tx DMA channel stop */
                XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN, 0);
 
        /* Disable each Tx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->tx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->tx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_TCR, ST, 0);
        }
 }
 
 
 static void xgbe_enable_rx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int reg_val, i;
 
        /* Enable each Rx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_RCR, SR, 1);
        }
 
        /* Enable each Rx queue */
 
 static void xgbe_disable_rx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
        /* Disable MAC Rx */
        XGMAC_IOWRITE(pdata, MAC_RQC0R, 0);
 
        /* Disable each Rx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_RCR, SR, 0);
        }
 }
 
 static void xgbe_powerup_tx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
        /* Enable each Tx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->tx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->tx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_TCR, ST, 1);
        }
 
        /* Enable MAC Tx */
 
 static void xgbe_powerdown_tx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
        /* Prepare for Tx DMA channel stop */
        XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
 
        /* Disable each Tx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->tx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->tx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_TCR, ST, 0);
        }
 }
 
 static void xgbe_powerup_rx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
        /* Enable each Rx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_RCR, SR, 1);
        }
 }
 
 static void xgbe_powerdown_rx(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
        /* Disable each Rx DMA channel */
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               if (!channel->rx_ring)
+       for (i = 0; i < pdata->channel_count; i++) {
+               if (!pdata->channel[i]->rx_ring)
                        break;
 
-               XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0);
+               XGMAC_DMA_IOWRITE_BITS(pdata->channel[i], DMA_CH_RCR, SR, 0);
        }
 }
 
 
 static int xgbe_all_poll(struct napi_struct *, int);
 static void xgbe_stop(struct xgbe_prv_data *);
 
-static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
+static void *xgbe_alloc_node(size_t size, int node)
 {
-       struct xgbe_channel *channel_mem, *channel;
-       struct xgbe_ring *tx_ring, *rx_ring;
-       unsigned int count, i;
-       int ret = -ENOMEM;
+       void *mem;
 
-       count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
+       mem = kzalloc_node(size, GFP_KERNEL, node);
+       if (!mem)
+               mem = kzalloc(size, GFP_KERNEL);
+
+       return mem;
+}
+
+static void xgbe_free_channels(struct xgbe_prv_data *pdata)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(pdata->channel); i++) {
+               if (!pdata->channel[i])
+                       continue;
+
+               kfree(pdata->channel[i]->rx_ring);
+               kfree(pdata->channel[i]->tx_ring);
+               kfree(pdata->channel[i]);
+
+               pdata->channel[i] = NULL;
+       }
 
-       channel_mem = kcalloc(count, sizeof(struct xgbe_channel), GFP_KERNEL);
-       if (!channel_mem)
-               goto err_channel;
+       pdata->channel_count = 0;
+}
+
+static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
+{
+       struct xgbe_channel *channel;
+       struct xgbe_ring *ring;
+       unsigned int count, i;
+       int node;
 
-       tx_ring = kcalloc(pdata->tx_ring_count, sizeof(struct xgbe_ring),
-                         GFP_KERNEL);
-       if (!tx_ring)
-               goto err_tx_ring;
+       node = dev_to_node(pdata->dev);
 
-       rx_ring = kcalloc(pdata->rx_ring_count, sizeof(struct xgbe_ring),
-                         GFP_KERNEL);
-       if (!rx_ring)
-               goto err_rx_ring;
+       count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
+       for (i = 0; i < count; i++) {
+               channel = xgbe_alloc_node(sizeof(*channel), node);
+               if (!channel)
+                       goto err_mem;
+               pdata->channel[i] = channel;
 
-       for (i = 0, channel = channel_mem; i < count; i++, channel++) {
                snprintf(channel->name, sizeof(channel->name), "channel-%u", i);
                channel->pdata = pdata;
                channel->queue_index = i;
                channel->dma_regs = pdata->xgmac_regs + DMA_CH_BASE +
                                    (DMA_CH_INC * i);
+               channel->node = node;
 
                if (pdata->per_channel_irq)
                        channel->dma_irq = pdata->channel_irq[i];
 
                if (i < pdata->tx_ring_count) {
-                       spin_lock_init(&tx_ring->lock);
-                       channel->tx_ring = tx_ring++;
+                       ring = xgbe_alloc_node(sizeof(*ring), node);
+                       if (!ring)
+                               goto err_mem;
+
+                       spin_lock_init(&ring->lock);
+                       ring->node = node;
+
+                       channel->tx_ring = ring;
                }
 
                if (i < pdata->rx_ring_count) {
-                       spin_lock_init(&rx_ring->lock);
-                       channel->rx_ring = rx_ring++;
+                       ring = xgbe_alloc_node(sizeof(*ring), node);
+                       if (!ring)
+                               goto err_mem;
+
+                       spin_lock_init(&ring->lock);
+                       ring->node = node;
+
+                       channel->rx_ring = ring;
                }
 
+               netif_dbg(pdata, drv, pdata->netdev,
+                         "%s: node=%d\n", channel->name, node);
+
                netif_dbg(pdata, drv, pdata->netdev,
                          "%s: dma_regs=%p, dma_irq=%d, tx=%p, rx=%p\n",
                          channel->name, channel->dma_regs, channel->dma_irq,
                          channel->tx_ring, channel->rx_ring);
        }
 
-       pdata->channel = channel_mem;
        pdata->channel_count = count;
 
        return 0;
 
-err_rx_ring:
-       kfree(tx_ring);
-
-err_tx_ring:
-       kfree(channel_mem);
-
-err_channel:
-       return ret;
-}
-
-static void xgbe_free_channels(struct xgbe_prv_data *pdata)
-{
-       if (!pdata->channel)
-               return;
-
-       kfree(pdata->channel->rx_ring);
-       kfree(pdata->channel->tx_ring);
-       kfree(pdata->channel);
+err_mem:
+       xgbe_free_channels(pdata);
 
-       pdata->channel = NULL;
-       pdata->channel_count = 0;
+       return -ENOMEM;
 }
 
 static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring)
 
 static void xgbe_enable_rx_tx_ints(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++)
-               xgbe_enable_rx_tx_int(pdata, channel);
+       for (i = 0; i < pdata->channel_count; i++)
+               xgbe_enable_rx_tx_int(pdata, pdata->channel[i]);
 }
 
 static void xgbe_disable_rx_tx_int(struct xgbe_prv_data *pdata,
 
 static void xgbe_disable_rx_tx_ints(struct xgbe_prv_data *pdata)
 {
-       struct xgbe_channel *channel;
        unsigned int i;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++)
-               xgbe_disable_rx_tx_int(pdata, channel);
+       for (i = 0; i < pdata->channel_count; i++)
+               xgbe_disable_rx_tx_int(pdata, pdata->channel[i]);
 }
 
 static bool xgbe_ecc_sec(struct xgbe_prv_data *pdata, unsigned long *period,
                if (!(dma_isr & (1 << i)))
                        continue;
 
-               channel = pdata->channel + i;
+               channel = pdata->channel[i];
 
                dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR);
                netif_dbg(pdata, intr, pdata->netdev, "DMA_CH%u_ISR=%#010x\n",
        setup_timer(&pdata->service_timer, xgbe_service_timer,
                    (unsigned long)pdata);
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                if (!channel->tx_ring)
                        break;
 
 
        del_timer_sync(&pdata->service_timer);
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                if (!channel->tx_ring)
                        break;
 
        unsigned int i;
 
        if (pdata->per_channel_irq) {
-               channel = pdata->channel;
-               for (i = 0; i < pdata->channel_count; i++, channel++) {
+               for (i = 0; i < pdata->channel_count; i++) {
+                       channel = pdata->channel[i];
                        if (add)
                                netif_napi_add(pdata->netdev, &channel->napi,
                                               xgbe_one_poll, NAPI_POLL_WEIGHT);
        unsigned int i;
 
        if (pdata->per_channel_irq) {
-               channel = pdata->channel;
-               for (i = 0; i < pdata->channel_count; i++, channel++) {
+               for (i = 0; i < pdata->channel_count; i++) {
+                       channel = pdata->channel[i];
                        napi_disable(&channel->napi);
 
                        if (del)
        if (!pdata->per_channel_irq)
                return 0;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                snprintf(channel->dma_irq_name,
                         sizeof(channel->dma_irq_name) - 1,
                         "%s-TxRx-%u", netdev_name(netdev),
 
 err_dma_irq:
        /* Using an unsigned int, 'i' will go to UINT_MAX and exit */
-       for (i--, channel--; i < pdata->channel_count; i--, channel--)
+       for (i--; i < pdata->channel_count; i--) {
+               channel = pdata->channel[i];
+
                devm_free_irq(pdata->dev, channel->dma_irq, channel);
+       }
 
        if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
                devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);
        if (!pdata->per_channel_irq)
                return;
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++)
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                devm_free_irq(pdata->dev, channel->dma_irq, channel);
+       }
 }
 
 void xgbe_init_tx_coalesce(struct xgbe_prv_data *pdata)
 static void xgbe_free_tx_data(struct xgbe_prv_data *pdata)
 {
        struct xgbe_desc_if *desc_if = &pdata->desc_if;
-       struct xgbe_channel *channel;
        struct xgbe_ring *ring;
        struct xgbe_ring_data *rdata;
        unsigned int i, j;
 
        DBGPR("-->xgbe_free_tx_data\n");
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               ring = channel->tx_ring;
+       for (i = 0; i < pdata->channel_count; i++) {
+               ring = pdata->channel[i]->tx_ring;
                if (!ring)
                        break;
 
 static void xgbe_free_rx_data(struct xgbe_prv_data *pdata)
 {
        struct xgbe_desc_if *desc_if = &pdata->desc_if;
-       struct xgbe_channel *channel;
        struct xgbe_ring *ring;
        struct xgbe_ring_data *rdata;
        unsigned int i, j;
 
        DBGPR("-->xgbe_free_rx_data\n");
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
-               ring = channel->rx_ring;
+       for (i = 0; i < pdata->channel_count; i++) {
+               ring = pdata->channel[i]->rx_ring;
                if (!ring)
                        break;
 
 
        hw_if->exit(pdata);
 
-       channel = pdata->channel;
-       for (i = 0; i < pdata->channel_count; i++, channel++) {
+       for (i = 0; i < pdata->channel_count; i++) {
+               channel = pdata->channel[i];
                if (!channel->tx_ring)
                        continue;
 
 
        DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len);
 
-       channel = pdata->channel + skb->queue_mapping;
+       channel = pdata->channel[skb->queue_mapping];
        txq = netdev_get_tx_queue(netdev, channel->queue_index);
        ring = channel->tx_ring;
        packet = &ring->packet_data;
        DBGPR("-->xgbe_poll_controller\n");
 
        if (pdata->per_channel_irq) {
-               channel = pdata->channel;
-               for (i = 0; i < pdata->channel_count; i++, channel++)
+               for (i = 0; i < pdata->channel_count; i++) {
+                       channel = pdata->channel[i];
                        xgbe_dma_isr(channel->dma_irq, channel);
+               }
        } else {
                disable_irq(pdata->dev_irq);
                xgbe_isr(pdata->dev_irq, pdata);
        do {
                last_processed = processed;
 
-               channel = pdata->channel;
-               for (i = 0; i < pdata->channel_count; i++, channel++) {
+               for (i = 0; i < pdata->channel_count; i++) {
+                       channel = pdata->channel[i];
+
                        /* Cleanup Tx ring first */
                        xgbe_tx_poll(channel);
 
 
        /* Page allocation for RX buffers */
        struct xgbe_page_alloc rx_hdr_pa;
        struct xgbe_page_alloc rx_buf_pa;
+       int node;
 
        /* Ring index values
         *  cur   - Tx: index of descriptor to be used for current transfer
 
        struct xgbe_ring *tx_ring;
        struct xgbe_ring *rx_ring;
+
+       int node;
 } ____cacheline_aligned;
 
 enum xgbe_state {
        struct timer_list service_timer;
 
        /* Rings for Tx/Rx on a DMA channel */
-       struct xgbe_channel *channel;
+       struct xgbe_channel *channel[XGBE_MAX_DMA_CHANNELS];
        unsigned int tx_max_channel_count;
        unsigned int rx_max_channel_count;
        unsigned int channel_count;