string: factorize skip_spaces and export it to be generally available
[safe/jmp/linux-2.6] / drivers / net / mv643xx_eth.c
index e1f7706..1405a17 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/types.h>
 #include <linux/inet_lro.h>
 #include <asm/system.h>
+#include <linux/list.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
 static char mv643xx_eth_driver_version[] = "1.4";
@@ -88,7 +89,24 @@ static char mv643xx_eth_driver_version[] = "1.4";
 #define MAC_ADDR_LOW                   0x0014
 #define MAC_ADDR_HIGH                  0x0018
 #define SDMA_CONFIG                    0x001c
+#define  TX_BURST_SIZE_16_64BIT                0x01000000
+#define  TX_BURST_SIZE_4_64BIT         0x00800000
+#define  BLM_TX_NO_SWAP                        0x00000020
+#define  BLM_RX_NO_SWAP                        0x00000010
+#define  RX_BURST_SIZE_16_64BIT                0x00000008
+#define  RX_BURST_SIZE_4_64BIT         0x00000004
 #define PORT_SERIAL_CONTROL            0x003c
+#define  SET_MII_SPEED_TO_100          0x01000000
+#define  SET_GMII_SPEED_TO_1000                0x00800000
+#define  SET_FULL_DUPLEX_MODE          0x00200000
+#define  MAX_RX_PACKET_9700BYTE                0x000a0000
+#define  DISABLE_AUTO_NEG_SPEED_GMII   0x00002000
+#define  DO_NOT_FORCE_LINK_FAIL                0x00000400
+#define  SERIAL_PORT_CONTROL_RESERVED  0x00000200
+#define  DISABLE_AUTO_NEG_FOR_FLOW_CTRL        0x00000008
+#define  DISABLE_AUTO_NEG_FOR_DUPLEX   0x00000004
+#define  FORCE_LINK_PASS               0x00000002
+#define  SERIAL_PORT_ENABLE            0x00000001
 #define PORT_STATUS                    0x0044
 #define  TX_FIFO_EMPTY                 0x00000400
 #define  TX_IN_PROGRESS                        0x00000080
@@ -106,7 +124,9 @@ static char mv643xx_eth_driver_version[] = "1.4";
 #define TX_BW_BURST                    0x005c
 #define INT_CAUSE                      0x0060
 #define  INT_TX_END                    0x07f80000
+#define  INT_TX_END_0                  0x00080000
 #define  INT_RX                                0x000003fc
+#define  INT_RX_0                      0x00000004
 #define  INT_EXT                       0x00000002
 #define INT_CAUSE_EXT                  0x0064
 #define  INT_EXT_LINK_PHY              0x00110000
@@ -135,15 +155,8 @@ static char mv643xx_eth_driver_version[] = "1.4";
 
 
 /*
- * SDMA configuration register.
+ * SDMA configuration register default value.
  */
-#define RX_BURST_SIZE_4_64BIT          (2 << 1)
-#define RX_BURST_SIZE_16_64BIT         (4 << 1)
-#define BLM_RX_NO_SWAP                 (1 << 4)
-#define BLM_TX_NO_SWAP                 (1 << 5)
-#define TX_BURST_SIZE_4_64BIT          (2 << 22)
-#define TX_BURST_SIZE_16_64BIT         (4 << 22)
-
 #if defined(__BIG_ENDIAN)
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE         \
                (RX_BURST_SIZE_4_64BIT  |       \
@@ -160,22 +173,11 @@ static char mv643xx_eth_driver_version[] = "1.4";
 
 
 /*
- * Port serial control register.
+ * Misc definitions.
  */
-#define SET_MII_SPEED_TO_100                   (1 << 24)
-#define SET_GMII_SPEED_TO_1000                 (1 << 23)
-#define SET_FULL_DUPLEX_MODE                   (1 << 21)
-#define MAX_RX_PACKET_9700BYTE                 (5 << 17)
-#define DISABLE_AUTO_NEG_SPEED_GMII            (1 << 13)
-#define DO_NOT_FORCE_LINK_FAIL                 (1 << 10)
-#define SERIAL_PORT_CONTROL_RESERVED           (1 << 9)
-#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL         (1 << 3)
-#define DISABLE_AUTO_NEG_FOR_DUPLEX            (1 << 2)
-#define FORCE_LINK_PASS                                (1 << 1)
-#define SERIAL_PORT_ENABLE                     (1 << 0)
-
-#define DEFAULT_RX_QUEUE_SIZE          128
-#define DEFAULT_TX_QUEUE_SIZE          256
+#define DEFAULT_RX_QUEUE_SIZE  128
+#define DEFAULT_TX_QUEUE_SIZE  256
+#define SKB_DMA_REALIGN                ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES)
 
 
 /*
@@ -393,12 +395,13 @@ struct mv643xx_eth_private {
        struct work_struct tx_timeout_task;
 
        struct napi_struct napi;
+       u32 int_mask;
+       u8 oom;
        u8 work_link;
        u8 work_tx;
        u8 work_tx_end;
        u8 work_rx;
        u8 work_rx_refill;
-       u8 work_rx_oom;
 
        int skb_size;
        struct sk_buff_head rx_recycle;
@@ -569,7 +572,7 @@ static int rxq_process(struct rx_queue *rxq, int budget)
                if (rxq->rx_curr_desc == rxq->rx_ring_size)
                        rxq->rx_curr_desc = 0;
 
-               dma_unmap_single(NULL, rx_desc->buf_ptr,
+               dma_unmap_single(mp->dev->dev.parent, rx_desc->buf_ptr,
                                 rx_desc->buf_size, DMA_FROM_DEVICE);
                rxq->rx_desc_count--;
                rx++;
@@ -651,23 +654,20 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
        refilled = 0;
        while (refilled < budget && rxq->rx_desc_count < rxq->rx_ring_size) {
                struct sk_buff *skb;
-               int unaligned;
                int rx;
                struct rx_desc *rx_desc;
 
                skb = __skb_dequeue(&mp->rx_recycle);
                if (skb == NULL)
-                       skb = dev_alloc_skb(mp->skb_size +
-                                           dma_get_cache_alignment() - 1);
+                       skb = dev_alloc_skb(mp->skb_size);
 
                if (skb == NULL) {
-                       mp->work_rx_oom |= 1 << rxq->index;
+                       mp->oom = 1;
                        goto oom;
                }
 
-               unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
-               if (unaligned)
-                       skb_reserve(skb, dma_get_cache_alignment() - unaligned);
+               if (SKB_DMA_REALIGN)
+                       skb_reserve(skb, SKB_DMA_REALIGN);
 
                refilled++;
                rxq->rx_desc_count++;
@@ -678,8 +678,9 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
 
                rx_desc = rxq->rx_desc_area + rx;
 
-               rx_desc->buf_ptr = dma_map_single(NULL, skb->data,
-                                       mp->skb_size, DMA_FROM_DEVICE);
+               rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent,
+                                                 skb->data, mp->skb_size,
+                                                 DMA_FROM_DEVICE);
                rx_desc->buf_size = mp->skb_size;
                rxq->rx_skb[rx] = skb;
                wmb();
@@ -718,6 +719,7 @@ static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
 
 static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
 {
+       struct mv643xx_eth_private *mp = txq_to_mp(txq);
        int nr_frags = skb_shinfo(skb)->nr_frags;
        int frag;
 
@@ -746,10 +748,10 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
 
                desc->l4i_chk = 0;
                desc->byte_cnt = this_frag->size;
-               desc->buf_ptr = dma_map_page(NULL, this_frag->page,
-                                               this_frag->page_offset,
-                                               this_frag->size,
-                                               DMA_TO_DEVICE);
+               desc->buf_ptr = dma_map_page(mp->dev->dev.parent,
+                                            this_frag->page,
+                                            this_frag->page_offset,
+                                            this_frag->size, DMA_TO_DEVICE);
        }
 }
 
@@ -826,7 +828,8 @@ no_csum:
 
        desc->l4i_chk = l4i_chk;
        desc->byte_cnt = length;
-       desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
+       desc->buf_ptr = dma_map_single(mp->dev->dev.parent, skb->data,
+                                      length, DMA_TO_DEVICE);
 
        __skb_queue_tail(&txq->tx_skb, skb);
 
@@ -846,7 +849,7 @@ no_csum:
        return 0;
 }
 
-static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
        int queue;
@@ -956,18 +959,17 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
                }
 
                if (cmd_sts & TX_FIRST_DESC) {
-                       dma_unmap_single(NULL, desc->buf_ptr,
+                       dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr,
                                         desc->byte_cnt, DMA_TO_DEVICE);
                } else {
-                       dma_unmap_page(NULL, desc->buf_ptr,
+                       dma_unmap_page(mp->dev->dev.parent, desc->buf_ptr,
                                       desc->byte_cnt, DMA_TO_DEVICE);
                }
 
                if (skb != NULL) {
                        if (skb_queue_len(&mp->rx_recycle) <
                                        mp->rx_ring_size &&
-                           skb_recycle_check(skb, mp->skb_size +
-                                       dma_get_cache_alignment() - 1))
+                           skb_recycle_check(skb, mp->skb_size))
                                __skb_queue_head(&mp->rx_recycle, skb);
                        else
                                dev_kfree_skb(skb);
@@ -1064,40 +1066,6 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)
        }
 }
 
-static void txq_set_wrr(struct tx_queue *txq, int weight)
-{
-       struct mv643xx_eth_private *mp = txq_to_mp(txq);
-       int off;
-       u32 val;
-
-       /*
-        * Turn off fixed priority mode.
-        */
-       off = 0;
-       switch (mp->shared->tx_bw_control) {
-       case TX_BW_CONTROL_OLD_LAYOUT:
-               off = TXQ_FIX_PRIO_CONF;
-               break;
-       case TX_BW_CONTROL_NEW_LAYOUT:
-               off = TXQ_FIX_PRIO_CONF_MOVED;
-               break;
-       }
-
-       if (off) {
-               val = rdlp(mp, off);
-               val &= ~(1 << txq->index);
-               wrlp(mp, off, val);
-
-               /*
-                * Configure WRR weight for this queue.
-                */
-
-               val = rdlp(mp, off);
-               val = (val & ~0xff) | (weight & 0xff);
-               wrlp(mp, TXQ_BW_WRR_CONF(txq->index), val);
-       }
-}
-
 
 /* mii management interface *************************************************/
 static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
@@ -1255,7 +1223,6 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
 
        spin_lock_bh(&mp->mib_counters_lock);
        p->good_octets_received += mib_read(mp, 0x00);
-       p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
        p->bad_octets_received += mib_read(mp, 0x08);
        p->internal_mac_transmit_err += mib_read(mp, 0x0c);
        p->good_frames_received += mib_read(mp, 0x10);
@@ -1269,7 +1236,6 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
        p->frames_512_to_1023_octets += mib_read(mp, 0x30);
        p->frames_1024_to_max_octets += mib_read(mp, 0x34);
        p->good_octets_sent += mib_read(mp, 0x38);
-       p->good_octets_sent += (u64)mib_read(mp, 0x3c) << 32;
        p->good_frames_sent += mib_read(mp, 0x40);
        p->excessive_collision += mib_read(mp, 0x44);
        p->multicast_frames_sent += mib_read(mp, 0x48);
@@ -1722,20 +1688,20 @@ static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr)
 
 static u32 uc_addr_filter_mask(struct net_device *dev)
 {
-       struct dev_addr_list *uc_ptr;
+       struct netdev_hw_addr *ha;
        u32 nibbles;
 
        if (dev->flags & IFF_PROMISC)
                return 0;
 
        nibbles = 1 << (dev->dev_addr[5] & 0x0f);
-       for (uc_ptr = dev->uc_list; uc_ptr != NULL; uc_ptr = uc_ptr->next) {
-               if (memcmp(dev->dev_addr, uc_ptr->da_addr, 5))
+       list_for_each_entry(ha, &dev->uc.list, list) {
+               if (memcmp(dev->dev_addr, ha->addr, 5))
                        return 0;
-               if ((dev->dev_addr[5] ^ uc_ptr->da_addr[5]) & 0xf0)
+               if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0)
                        return 0;
 
-               nibbles |= 1 << (uc_ptr->da_addr[5] & 0x0f);
+               nibbles |= 1 << (ha->addr[5] & 0x0f);
        }
 
        return nibbles;
@@ -1750,12 +1716,12 @@ static void mv643xx_eth_program_unicast_filter(struct net_device *dev)
 
        uc_addr_set(mp, dev->dev_addr);
 
-       port_config = rdlp(mp, PORT_CONFIG);
+       port_config = rdlp(mp, PORT_CONFIG) & ~UNICAST_PROMISCUOUS_MODE;
+
        nibbles = uc_addr_filter_mask(dev);
        if (!nibbles) {
                port_config |= UNICAST_PROMISCUOUS_MODE;
-               wrlp(mp, PORT_CONFIG, port_config);
-               return;
+               nibbles = 0xffff;
        }
 
        for (i = 0; i < 16; i += 4) {
@@ -1776,7 +1742,6 @@ static void mv643xx_eth_program_unicast_filter(struct net_device *dev)
                wrl(mp, off, v);
        }
 
-       port_config &= ~UNICAST_PROMISCUOUS_MODE;
        wrlp(mp, PORT_CONFIG, port_config);
 }
 
@@ -1809,7 +1774,6 @@ static void mv643xx_eth_program_multicast_filter(struct net_device *dev)
        if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
                int port_num;
                u32 accept;
-               int i;
 
 oom:
                port_num = mp->port_num;
@@ -1863,6 +1827,9 @@ static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr)
 {
        struct sockaddr *sa = addr;
 
+       if (!is_valid_ether_addr(sa->sa_data))
+               return -EINVAL;
+
        memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
 
        netif_addr_lock_bh(dev);
@@ -1896,9 +1863,9 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
                                                mp->rx_desc_sram_size);
                rxq->rx_desc_dma = mp->rx_desc_sram_addr;
        } else {
-               rxq->rx_desc_area = dma_alloc_coherent(NULL, size,
-                                                       &rxq->rx_desc_dma,
-                                                       GFP_KERNEL);
+               rxq->rx_desc_area = dma_alloc_coherent(mp->dev->dev.parent,
+                                                      size, &rxq->rx_desc_dma,
+                                                      GFP_KERNEL);
        }
 
        if (rxq->rx_desc_area == NULL) {
@@ -1949,7 +1916,7 @@ out_free:
        if (index == 0 && size <= mp->rx_desc_sram_size)
                iounmap(rxq->rx_desc_area);
        else
-               dma_free_coherent(NULL, size,
+               dma_free_coherent(mp->dev->dev.parent, size,
                                  rxq->rx_desc_area,
                                  rxq->rx_desc_dma);
 
@@ -1981,7 +1948,7 @@ static void rxq_deinit(struct rx_queue *rxq)
            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,
+               dma_free_coherent(mp->dev->dev.parent, rxq->rx_desc_area_size,
                                  rxq->rx_desc_area, rxq->rx_desc_dma);
 
        kfree(rxq->rx_skb);
@@ -2009,9 +1976,9 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
                                                mp->tx_desc_sram_size);
                txq->tx_desc_dma = mp->tx_desc_sram_addr;
        } else {
-               txq->tx_desc_area = dma_alloc_coherent(NULL, size,
-                                                       &txq->tx_desc_dma,
-                                                       GFP_KERNEL);
+               txq->tx_desc_area = dma_alloc_coherent(mp->dev->dev.parent,
+                                                      size, &txq->tx_desc_dma,
+                                                      GFP_KERNEL);
        }
 
        if (txq->tx_desc_area == NULL) {
@@ -2055,7 +2022,7 @@ static void txq_deinit(struct tx_queue *txq)
            txq->tx_desc_area_size <= mp->tx_desc_sram_size)
                iounmap(txq->tx_desc_area);
        else
-               dma_free_coherent(NULL, txq->tx_desc_area_size,
+               dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size,
                                  txq->tx_desc_area, txq->tx_desc_dma);
 }
 
@@ -2066,15 +2033,16 @@ static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)
        u32 int_cause;
        u32 int_cause_ext;
 
-       int_cause = rdlp(mp, INT_CAUSE) & (INT_TX_END | INT_RX | INT_EXT);
+       int_cause = rdlp(mp, INT_CAUSE) & mp->int_mask;
        if (int_cause == 0)
                return 0;
 
        int_cause_ext = 0;
-       if (int_cause & INT_EXT)
+       if (int_cause & INT_EXT) {
+               int_cause &= ~INT_EXT;
                int_cause_ext = rdlp(mp, INT_CAUSE_EXT);
+       }
 
-       int_cause &= INT_TX_END | INT_RX;
        if (int_cause) {
                wrlp(mp, INT_CAUSE, ~int_cause);
                mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) &
@@ -2167,8 +2135,10 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
 
        mp = container_of(napi, struct mv643xx_eth_private, napi);
 
-       mp->work_rx_refill |= mp->work_rx_oom;
-       mp->work_rx_oom = 0;
+       if (unlikely(mp->oom)) {
+               mp->oom = 0;
+               del_timer(&mp->rx_oom);
+       }
 
        work_done = 0;
        while (work_done < budget) {
@@ -2179,11 +2149,14 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
                if (mp->work_link) {
                        mp->work_link = 0;
                        handle_link_event(mp);
+                       work_done++;
                        continue;
                }
 
-               queue_mask = mp->work_tx | mp->work_tx_end |
-                               mp->work_rx | mp->work_rx_refill;
+               queue_mask = mp->work_tx | mp->work_tx_end | mp->work_rx;
+               if (likely(!mp->oom))
+                       queue_mask |= mp->work_rx_refill;
+
                if (!queue_mask) {
                        if (mv643xx_eth_collect_events(mp))
                                continue;
@@ -2204,7 +2177,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
                        txq_maybe_wake(mp->txq + queue);
                } else if (mp->work_rx & queue_mask) {
                        work_done += rxq_process(mp->rxq + queue, work_tbd);
-               } else if (mp->work_rx_refill & queue_mask) {
+               } else if (!mp->oom && (mp->work_rx_refill & queue_mask)) {
                        work_done += rxq_refill(mp->rxq + queue, work_tbd);
                } else {
                        BUG();
@@ -2212,10 +2185,10 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
        }
 
        if (work_done < budget) {
-               if (mp->work_rx_oom)
+               if (mp->oom)
                        mod_timer(&mp->rx_oom, jiffies + (HZ / 10));
                napi_complete(napi);
-               wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+               wrlp(mp, INT_MASK, mp->int_mask);
        }
 
        return work_done;
@@ -2274,8 +2247,6 @@ static void port_start(struct mv643xx_eth_private *mp)
                pscr |= FORCE_LINK_PASS;
        wrlp(mp, PORT_SERIAL_CONTROL, pscr);
 
-       wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
-
        /*
         * Configure TX path and queues.
         */
@@ -2289,11 +2260,6 @@ static void port_start(struct mv643xx_eth_private *mp)
        }
 
        /*
-        * Add configured unicast address to address filter table.
-        */
-       mv643xx_eth_program_unicast_filter(mp->dev);
-
-       /*
         * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast
         * frames to RX queue #0, and include the pseudo-header when
         * calculating receive checksums.
@@ -2306,6 +2272,11 @@ static void port_start(struct mv643xx_eth_private *mp)
        wrlp(mp, PORT_CONFIG_EXT, 0x00000000);
 
        /*
+        * Add configured unicast addresses to address filter table.
+        */
+       mv643xx_eth_program_unicast_filter(mp->dev);
+
+       /*
         * Enable the receive queues.
         */
        for (i = 0; i < mp->rxq_count; i++) {
@@ -2338,6 +2309,14 @@ static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
         * size field are ignored by the hardware.
         */
        mp->skb_size = (skb_size + 7) & ~7;
+
+       /*
+        * If NET_SKB_PAD is smaller than a cache line,
+        * netdev_alloc_skb() will cause skb->data to be misaligned
+        * to a cache line boundary.  If this is the case, include
+        * some extra space to allow re-aligning the data area.
+        */
+       mp->skb_size += SKB_DMA_REALIGN;
 }
 
 static int mv643xx_eth_open(struct net_device *dev)
@@ -2363,6 +2342,8 @@ static int mv643xx_eth_open(struct net_device *dev)
 
        skb_queue_head_init(&mp->rx_recycle);
 
+       mp->int_mask = INT_EXT;
+
        for (i = 0; i < mp->rxq_count; i++) {
                err = rxq_init(mp, i);
                if (err) {
@@ -2372,9 +2353,10 @@ static int mv643xx_eth_open(struct net_device *dev)
                }
 
                rxq_refill(mp->rxq + i, INT_MAX);
+               mp->int_mask |= INT_RX_0 << i;
        }
 
-       if (mp->work_rx_oom) {
+       if (mp->oom) {
                mp->rx_oom.expires = jiffies + (HZ / 10);
                add_timer(&mp->rx_oom);
        }
@@ -2386,12 +2368,13 @@ static int mv643xx_eth_open(struct net_device *dev)
                                txq_deinit(mp->txq + i);
                        goto out_free;
                }
+               mp->int_mask |= INT_TX_END_0 << i;
        }
 
        port_start(mp);
 
        wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
-       wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+       wrlp(mp, INT_MASK, mp->int_mask);
 
        return 0;
 
@@ -2535,7 +2518,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
 
        mv643xx_eth_irq(dev->irq, dev);
 
-       wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+       wrlp(mp, INT_MASK, mp->int_mask);
 }
 #endif
 
@@ -2957,6 +2940,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 
        netif_carrier_off(dev);
 
+       wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
+
        set_rx_coal(mp, 250);
        set_tx_coal(mp, 0);