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