]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/mv643xx_eth.c
[PATCH] wireless/atmel: fix setting TX key only in ENCODEEXT
[linux-2.6-omap-h63xx.git] / drivers / net / mv643xx_eth.c
index 6118ea799a6550c74f8c29a09c1a0bb78666c533..c0998ef938e0042b3eb45aa4b9e460ec1531b919 100644 (file)
@@ -32,6 +32,8 @@
  */
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/etherdevice.h>
 #define WRAP                   HW_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
 #define RX_SKB_SIZE            ((dev->mtu + WRAP + 7) & ~0x7)
 
-#define INT_CAUSE_UNMASK_ALL           0x0007ffff
-#define INT_CAUSE_UNMASK_ALL_EXT       0x0011ffff
-#define INT_CAUSE_MASK_ALL             0x00000000
-#define INT_CAUSE_MASK_ALL_EXT         0x00000000
+#define INT_UNMASK_ALL                 0x0007ffff
+#define INT_UNMASK_ALL_EXT             0x0011ffff
+#define INT_MASK_ALL                   0x00000000
+#define INT_MASK_ALL_EXT               0x00000000
 #define INT_CAUSE_CHECK_BITS           INT_CAUSE_UNMASK_ALL
 #define INT_CAUSE_CHECK_BITS_EXT       INT_CAUSE_UNMASK_ALL_EXT
 
@@ -205,7 +207,7 @@ static void mv643xx_eth_rx_task(void *data)
        else {
                /* Return interrupts */
                mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(mp->port_num),
-                                                       INT_CAUSE_UNMASK_ALL);
+                                                       INT_UNMASK_ALL);
        }
 #endif
 }
@@ -444,6 +446,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
                        netif_rx(skb);
 #endif
                }
+               dev->last_rx = jiffies;
        }
 
        return received_packets;
@@ -461,7 +464,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
  */
 
 static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
-                                                       struct pt_regs *regs)
+                                               struct pt_regs *regs)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct mv643xx_private *mp = netdev_priv(dev);
@@ -470,12 +473,12 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
 
        /* Read interrupt cause registers */
        eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) &
-                                               INT_CAUSE_UNMASK_ALL;
+                                               INT_UNMASK_ALL;
 
        if (eth_int_cause & BIT1)
                eth_int_cause_ext = mv_read(
                        MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
-                                               INT_CAUSE_UNMASK_ALL_EXT;
+                                               INT_UNMASK_ALL_EXT;
 
 #ifdef MV643XX_NAPI
        if (!(eth_int_cause & 0x0007fffd)) {
@@ -500,11 +503,10 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
        } else {
                if (netif_rx_schedule_prep(dev)) {
                        /* Mask all the interrupts */
-                       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
-                       mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG
-                                                               (port_num), 0);
-                       /* ensure previous writes have taken effect */
-                       mv_read(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num));
+                       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+                                                               INT_MASK_ALL);
+                       /* wait for previous write to complete */
+                       mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
                        __netif_rx_schedule(dev);
                }
 #else
@@ -517,9 +519,9 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
                 * with skb's.
                 */
 #ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
-               /* Unmask all interrupts on ethernet port */
+               /* Mask all interrupts on ethernet port */
                mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-                                                       INT_CAUSE_MASK_ALL);
+                                                       INT_MASK_ALL);
                /* wait for previous write to take effect */
                mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
 
@@ -857,11 +859,10 @@ static int mv643xx_eth_open(struct net_device *dev)
 
        /* Unmask phy and link status changes interrupts */
        mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-                                               INT_CAUSE_UNMASK_ALL_EXT);
+                                               INT_UNMASK_ALL_EXT);
 
        /* Unmask RX buffer and TX end interrupt */
-       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-                                               INT_CAUSE_UNMASK_ALL);
+       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL);
        return 0;
 
 out_free_tx_skb:
@@ -950,13 +951,9 @@ static int mv643xx_eth_stop(struct net_device *dev)
        struct mv643xx_private *mp = netdev_priv(dev);
        unsigned int port_num = mp->port_num;
 
-       /* Mask RX buffer and TX end interrupt */
-       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
-
-       /* Mask phy and link status changes interrupts */
-       mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0);
-
-       /* ensure previous writes have taken effect */
+       /* Mask all interrupts on ethernet port */
+       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL);
+       /* wait for previous write to complete */
        mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
 
 #ifdef MV643XX_NAPI
@@ -1040,9 +1037,7 @@ static int mv643xx_poll(struct net_device *dev, int *budget)
                mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
                mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
                mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-                                               INT_CAUSE_UNMASK_ALL);
-               mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-                                               INT_CAUSE_UNMASK_ALL_EXT);
+                                               INT_UNMASK_ALL);
        }
 
        return done ? 0 : 1;
@@ -1055,16 +1050,15 @@ static int mv643xx_poll(struct net_device *dev, int *budget)
 
 static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
 {
-        unsigned int frag;
-        skb_frag_t *fragp;
-
-        for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
-                fragp = &skb_shinfo(skb)->frags[frag];
-                if (fragp->size <= 8 && fragp->page_offset & 0x7)
-                        return 1;
+       unsigned int frag;
+       skb_frag_t *fragp;
 
-        }
-        return 0;
+       for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+               fragp = &skb_shinfo(skb)->frags[frag];
+               if (fragp->size <= 8 && fragp->page_offset & 0x7)
+                       return 1;
+       }
+       return 0;
 }
 
 
@@ -1307,39 +1301,18 @@ static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static inline void mv643xx_enable_irq(struct mv643xx_private *mp)
-{
-       int port_num = mp->port_num;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mp->lock, flags);
-       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-                                       INT_CAUSE_UNMASK_ALL);
-       mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-                                       INT_CAUSE_UNMASK_ALL_EXT);
-       spin_unlock_irqrestore(&mp->lock, flags);
-}
-
-static inline void mv643xx_disable_irq(struct mv643xx_private *mp)
-{
-       int port_num = mp->port_num;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mp->lock, flags);
-       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-                                       INT_CAUSE_MASK_ALL);
-       mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-                                       INT_CAUSE_MASK_ALL_EXT);
-       spin_unlock_irqrestore(&mp->lock, flags);
-}
-
 static void mv643xx_netpoll(struct net_device *netdev)
 {
        struct mv643xx_private *mp = netdev_priv(netdev);
+       int port_num = mp->port_num;
+
+       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL);
+       /* wait for previous write to complete */
+       mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
 
-       mv643xx_disable_irq(mp);
        mv643xx_eth_int_handler(netdev->irq, netdev, NULL);
-       mv643xx_enable_irq(mp);
+
+       mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL);
 }
 #endif
 
@@ -2166,26 +2139,26 @@ static void eth_port_set_multicast_list(struct net_device *dev)
         */
        if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) {
                for (table_index = 0; table_index <= 0xFC; table_index += 4) {
-                        /* Set all entries in DA filter special multicast
-                         * table (Ex_dFSMT)
-                         * Set for ETH_Q0 for now
-                         * Bits
-                         * 0     Accept=1, Drop=0
-                         * 3-1  Queue   ETH_Q0=0
-                         * 7-4  Reserved = 0;
-                         */
-                        mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
-
-                        /* Set all entries in DA filter other multicast
-                         * table (Ex_dFOMT)
-                         * Set for ETH_Q0 for now
-                         * Bits
-                         * 0     Accept=1, Drop=0
-                         * 3-1  Queue   ETH_Q0=0
-                         * 7-4  Reserved = 0;
-                         */
-                        mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
-               }
+                       /* Set all entries in DA filter special multicast
+                        * table (Ex_dFSMT)
+                        * Set for ETH_Q0 for now
+                        * Bits
+                        * 0      Accept=1, Drop=0
+                        * 3-1  Queue    ETH_Q0=0
+                        * 7-4  Reserved = 0;
+                        */
+                       mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+
+                       /* Set all entries in DA filter other multicast
+                        * table (Ex_dFOMT)
+                        * Set for ETH_Q0 for now
+                        * Bits
+                        * 0      Accept=1, Drop=0
+                        * 3-1  Queue    ETH_Q0=0
+                        * 7-4  Reserved = 0;
+                        */
+                       mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+               }
                return;
        }
 
@@ -2646,7 +2619,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
        struct eth_tx_desc *current_descriptor;
        struct eth_tx_desc *first_descriptor;
        u32 command;
-       unsigned long flags;
 
        /* Do not process Tx ring in case of Tx ring resource error */
        if (mp->tx_resource_err)
@@ -2663,8 +2635,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
                return ETH_ERROR;
        }
 
-       spin_lock_irqsave(&mp->lock, flags);
-
        mp->tx_ring_skbs++;
        BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
 
@@ -2714,15 +2684,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
                mp->tx_resource_err = 1;
                mp->tx_curr_desc_q = tx_first_desc;
 
-               spin_unlock_irqrestore(&mp->lock, flags);
-
                return ETH_QUEUE_LAST_RESOURCE;
        }
 
        mp->tx_curr_desc_q = tx_next_desc;
 
-       spin_unlock_irqrestore(&mp->lock, flags);
-
        return ETH_OK;
 }
 #else
@@ -2733,14 +2699,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
        int tx_desc_used;
        struct eth_tx_desc *current_descriptor;
        unsigned int command_status;
-       unsigned long flags;
 
        /* Do not process Tx ring in case of Tx ring resource error */
        if (mp->tx_resource_err)
                return ETH_QUEUE_FULL;
 
-       spin_lock_irqsave(&mp->lock, flags);
-
        mp->tx_ring_skbs++;
        BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
 
@@ -2771,12 +2734,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
        /* Check for ring index overlap in the Tx desc ring */
        if (tx_desc_curr == tx_desc_used) {
                mp->tx_resource_err = 1;
-
-               spin_unlock_irqrestore(&mp->lock, flags);
                return ETH_QUEUE_LAST_RESOURCE;
        }
 
-       spin_unlock_irqrestore(&mp->lock, flags);
        return ETH_OK;
 }
 #endif
@@ -2927,8 +2887,10 @@ static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
        p_pkt_info->return_info = mp->rx_skb[rx_curr_desc];
        p_pkt_info->l4i_chk = p_rx_desc->buf_size;
 
-       /* Clean the return info field to indicate that the packet has been */
-       /* moved to the upper layers                                        */
+       /*
+        * Clean the return info field to indicate that the
+        * packet has been moved to the upper layers
+        */
        mp->rx_skb[rx_curr_desc] = NULL;
 
        /* Update current index in data structure */
@@ -3009,7 +2971,7 @@ struct mv643xx_stats {
 };
 
 #define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \
-                     offsetof(struct mv643xx_private, m)
+                                       offsetof(struct mv643xx_private, m)
 
 static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
        { "rx_packets", MV643XX_STAT(stats.rx_packets) },
@@ -3160,9 +3122,8 @@ mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
        return 0;
 }
 
-static void
-mv643xx_get_drvinfo(struct net_device *netdev,
-                       struct ethtool_drvinfo *drvinfo)
+static void mv643xx_get_drvinfo(struct net_device *netdev,
+                               struct ethtool_drvinfo *drvinfo)
 {
        strncpy(drvinfo->driver,  mv643xx_driver_name, 32);
        strncpy(drvinfo->version, mv643xx_driver_version, 32);
@@ -3171,39 +3132,37 @@ mv643xx_get_drvinfo(struct net_device *netdev,
        drvinfo->n_stats = MV643XX_STATS_LEN;
 }
 
-static int 
-mv643xx_get_stats_count(struct net_device *netdev)
+static int mv643xx_get_stats_count(struct net_device *netdev)
 {
        return MV643XX_STATS_LEN;
 }
 
-static void 
-mv643xx_get_ethtool_stats(struct net_device *netdev, 
-               struct ethtool_stats *stats, uint64_t *data)
+static void mv643xx_get_ethtool_stats(struct net_device *netdev,
+                               struct ethtool_stats *stats, uint64_t *data)
 {
        struct mv643xx_private *mp = netdev->priv;
        int i;
 
        eth_update_mib_counters(mp);
 
-       for(i = 0; i < MV643XX_STATS_LEN; i++) {
+       for (i = 0; i < MV643XX_STATS_LEN; i++) {
                char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset;     
-               data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == 
+               data[i] = (mv643xx_gstrings_stats[i].sizeof_stat ==
                        sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
        }
 }
 
-static void 
-mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
+static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
+                               uint8_t *data)
 {
        int i;
 
        switch(stringset) {
        case ETH_SS_STATS:
                for (i=0; i < MV643XX_STATS_LEN; i++) {
-                       memcpy(data + i * ETH_GSTRING_LEN, 
-                       mv643xx_gstrings_stats[i].stat_string,
-                       ETH_GSTRING_LEN);
+                       memcpy(data + i * ETH_GSTRING_LEN,
+                                       mv643xx_gstrings_stats[i].stat_string,
+                                       ETH_GSTRING_LEN);
                }
                break;
        }