aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mv643xx_eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r--drivers/net/mv643xx_eth.c110
1 files changed, 49 insertions, 61 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 40ae36b20c9d..c0998ef938e0 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -32,6 +32,8 @@
32 */ 32 */
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
35#include <linux/in.h>
36#include <linux/ip.h>
35#include <linux/tcp.h> 37#include <linux/tcp.h>
36#include <linux/udp.h> 38#include <linux/udp.h>
37#include <linux/etherdevice.h> 39#include <linux/etherdevice.h>
@@ -444,6 +446,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
444 netif_rx(skb); 446 netif_rx(skb);
445#endif 447#endif
446 } 448 }
449 dev->last_rx = jiffies;
447 } 450 }
448 451
449 return received_packets; 452 return received_packets;
@@ -461,7 +464,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
461 */ 464 */
462 465
463static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, 466static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
464 struct pt_regs *regs) 467 struct pt_regs *regs)
465{ 468{
466 struct net_device *dev = (struct net_device *)dev_id; 469 struct net_device *dev = (struct net_device *)dev_id;
467 struct mv643xx_private *mp = netdev_priv(dev); 470 struct mv643xx_private *mp = netdev_priv(dev);
@@ -1047,16 +1050,15 @@ static int mv643xx_poll(struct net_device *dev, int *budget)
1047 1050
1048static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) 1051static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
1049{ 1052{
1050 unsigned int frag; 1053 unsigned int frag;
1051 skb_frag_t *fragp; 1054 skb_frag_t *fragp;
1052
1053 for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
1054 fragp = &skb_shinfo(skb)->frags[frag];
1055 if (fragp->size <= 8 && fragp->page_offset & 0x7)
1056 return 1;
1057 1055
1058 } 1056 for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
1059 return 0; 1057 fragp = &skb_shinfo(skb)->frags[frag];
1058 if (fragp->size <= 8 && fragp->page_offset & 0x7)
1059 return 1;
1060 }
1061 return 0;
1060} 1062}
1061 1063
1062 1064
@@ -2137,26 +2139,26 @@ static void eth_port_set_multicast_list(struct net_device *dev)
2137 */ 2139 */
2138 if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) { 2140 if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) {
2139 for (table_index = 0; table_index <= 0xFC; table_index += 4) { 2141 for (table_index = 0; table_index <= 0xFC; table_index += 4) {
2140 /* Set all entries in DA filter special multicast 2142 /* Set all entries in DA filter special multicast
2141 * table (Ex_dFSMT) 2143 * table (Ex_dFSMT)
2142 * Set for ETH_Q0 for now 2144 * Set for ETH_Q0 for now
2143 * Bits 2145 * Bits
2144 * 0 Accept=1, Drop=0 2146 * 0 Accept=1, Drop=0
2145 * 3-1 Queue ETH_Q0=0 2147 * 3-1 Queue ETH_Q0=0
2146 * 7-4 Reserved = 0; 2148 * 7-4 Reserved = 0;
2147 */ 2149 */
2148 mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); 2150 mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
2149 2151
2150 /* Set all entries in DA filter other multicast 2152 /* Set all entries in DA filter other multicast
2151 * table (Ex_dFOMT) 2153 * table (Ex_dFOMT)
2152 * Set for ETH_Q0 for now 2154 * Set for ETH_Q0 for now
2153 * Bits 2155 * Bits
2154 * 0 Accept=1, Drop=0 2156 * 0 Accept=1, Drop=0
2155 * 3-1 Queue ETH_Q0=0 2157 * 3-1 Queue ETH_Q0=0
2156 * 7-4 Reserved = 0; 2158 * 7-4 Reserved = 0;
2157 */ 2159 */
2158 mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); 2160 mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
2159 } 2161 }
2160 return; 2162 return;
2161 } 2163 }
2162 2164
@@ -2617,7 +2619,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2617 struct eth_tx_desc *current_descriptor; 2619 struct eth_tx_desc *current_descriptor;
2618 struct eth_tx_desc *first_descriptor; 2620 struct eth_tx_desc *first_descriptor;
2619 u32 command; 2621 u32 command;
2620 unsigned long flags;
2621 2622
2622 /* Do not process Tx ring in case of Tx ring resource error */ 2623 /* Do not process Tx ring in case of Tx ring resource error */
2623 if (mp->tx_resource_err) 2624 if (mp->tx_resource_err)
@@ -2634,8 +2635,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2634 return ETH_ERROR; 2635 return ETH_ERROR;
2635 } 2636 }
2636 2637
2637 spin_lock_irqsave(&mp->lock, flags);
2638
2639 mp->tx_ring_skbs++; 2638 mp->tx_ring_skbs++;
2640 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); 2639 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
2641 2640
@@ -2685,15 +2684,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2685 mp->tx_resource_err = 1; 2684 mp->tx_resource_err = 1;
2686 mp->tx_curr_desc_q = tx_first_desc; 2685 mp->tx_curr_desc_q = tx_first_desc;
2687 2686
2688 spin_unlock_irqrestore(&mp->lock, flags);
2689
2690 return ETH_QUEUE_LAST_RESOURCE; 2687 return ETH_QUEUE_LAST_RESOURCE;
2691 } 2688 }
2692 2689
2693 mp->tx_curr_desc_q = tx_next_desc; 2690 mp->tx_curr_desc_q = tx_next_desc;
2694 2691
2695 spin_unlock_irqrestore(&mp->lock, flags);
2696
2697 return ETH_OK; 2692 return ETH_OK;
2698} 2693}
2699#else 2694#else
@@ -2704,14 +2699,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2704 int tx_desc_used; 2699 int tx_desc_used;
2705 struct eth_tx_desc *current_descriptor; 2700 struct eth_tx_desc *current_descriptor;
2706 unsigned int command_status; 2701 unsigned int command_status;
2707 unsigned long flags;
2708 2702
2709 /* Do not process Tx ring in case of Tx ring resource error */ 2703 /* Do not process Tx ring in case of Tx ring resource error */
2710 if (mp->tx_resource_err) 2704 if (mp->tx_resource_err)
2711 return ETH_QUEUE_FULL; 2705 return ETH_QUEUE_FULL;
2712 2706
2713 spin_lock_irqsave(&mp->lock, flags);
2714
2715 mp->tx_ring_skbs++; 2707 mp->tx_ring_skbs++;
2716 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); 2708 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
2717 2709
@@ -2742,12 +2734,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2742 /* Check for ring index overlap in the Tx desc ring */ 2734 /* Check for ring index overlap in the Tx desc ring */
2743 if (tx_desc_curr == tx_desc_used) { 2735 if (tx_desc_curr == tx_desc_used) {
2744 mp->tx_resource_err = 1; 2736 mp->tx_resource_err = 1;
2745
2746 spin_unlock_irqrestore(&mp->lock, flags);
2747 return ETH_QUEUE_LAST_RESOURCE; 2737 return ETH_QUEUE_LAST_RESOURCE;
2748 } 2738 }
2749 2739
2750 spin_unlock_irqrestore(&mp->lock, flags);
2751 return ETH_OK; 2740 return ETH_OK;
2752} 2741}
2753#endif 2742#endif
@@ -2898,8 +2887,10 @@ static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
2898 p_pkt_info->return_info = mp->rx_skb[rx_curr_desc]; 2887 p_pkt_info->return_info = mp->rx_skb[rx_curr_desc];
2899 p_pkt_info->l4i_chk = p_rx_desc->buf_size; 2888 p_pkt_info->l4i_chk = p_rx_desc->buf_size;
2900 2889
2901 /* Clean the return info field to indicate that the packet has been */ 2890 /*
2902 /* moved to the upper layers */ 2891 * Clean the return info field to indicate that the
2892 * packet has been moved to the upper layers
2893 */
2903 mp->rx_skb[rx_curr_desc] = NULL; 2894 mp->rx_skb[rx_curr_desc] = NULL;
2904 2895
2905 /* Update current index in data structure */ 2896 /* Update current index in data structure */
@@ -2980,7 +2971,7 @@ struct mv643xx_stats {
2980}; 2971};
2981 2972
2982#define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \ 2973#define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \
2983 offsetof(struct mv643xx_private, m) 2974 offsetof(struct mv643xx_private, m)
2984 2975
2985static const struct mv643xx_stats mv643xx_gstrings_stats[] = { 2976static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
2986 { "rx_packets", MV643XX_STAT(stats.rx_packets) }, 2977 { "rx_packets", MV643XX_STAT(stats.rx_packets) },
@@ -3131,9 +3122,8 @@ mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
3131 return 0; 3122 return 0;
3132} 3123}
3133 3124
3134static void 3125static void mv643xx_get_drvinfo(struct net_device *netdev,
3135mv643xx_get_drvinfo(struct net_device *netdev, 3126 struct ethtool_drvinfo *drvinfo)
3136 struct ethtool_drvinfo *drvinfo)
3137{ 3127{
3138 strncpy(drvinfo->driver, mv643xx_driver_name, 32); 3128 strncpy(drvinfo->driver, mv643xx_driver_name, 32);
3139 strncpy(drvinfo->version, mv643xx_driver_version, 32); 3129 strncpy(drvinfo->version, mv643xx_driver_version, 32);
@@ -3142,39 +3132,37 @@ mv643xx_get_drvinfo(struct net_device *netdev,
3142 drvinfo->n_stats = MV643XX_STATS_LEN; 3132 drvinfo->n_stats = MV643XX_STATS_LEN;
3143} 3133}
3144 3134
3145static int 3135static int mv643xx_get_stats_count(struct net_device *netdev)
3146mv643xx_get_stats_count(struct net_device *netdev)
3147{ 3136{
3148 return MV643XX_STATS_LEN; 3137 return MV643XX_STATS_LEN;
3149} 3138}
3150 3139
3151static void 3140static void mv643xx_get_ethtool_stats(struct net_device *netdev,
3152mv643xx_get_ethtool_stats(struct net_device *netdev, 3141 struct ethtool_stats *stats, uint64_t *data)
3153 struct ethtool_stats *stats, uint64_t *data)
3154{ 3142{
3155 struct mv643xx_private *mp = netdev->priv; 3143 struct mv643xx_private *mp = netdev->priv;
3156 int i; 3144 int i;
3157 3145
3158 eth_update_mib_counters(mp); 3146 eth_update_mib_counters(mp);
3159 3147
3160 for(i = 0; i < MV643XX_STATS_LEN; i++) { 3148 for (i = 0; i < MV643XX_STATS_LEN; i++) {
3161 char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset; 3149 char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset;
3162 data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == 3150 data[i] = (mv643xx_gstrings_stats[i].sizeof_stat ==
3163 sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p; 3151 sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
3164 } 3152 }
3165} 3153}
3166 3154
3167static void 3155static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
3168mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) 3156 uint8_t *data)
3169{ 3157{
3170 int i; 3158 int i;
3171 3159
3172 switch(stringset) { 3160 switch(stringset) {
3173 case ETH_SS_STATS: 3161 case ETH_SS_STATS:
3174 for (i=0; i < MV643XX_STATS_LEN; i++) { 3162 for (i=0; i < MV643XX_STATS_LEN; i++) {
3175 memcpy(data + i * ETH_GSTRING_LEN, 3163 memcpy(data + i * ETH_GSTRING_LEN,
3176 mv643xx_gstrings_stats[i].stat_string, 3164 mv643xx_gstrings_stats[i].stat_string,
3177 ETH_GSTRING_LEN); 3165 ETH_GSTRING_LEN);
3178 } 3166 }
3179 break; 3167 break;
3180 } 3168 }