diff options
Diffstat (limited to 'drivers/net/vxge/vxge-main.c')
-rw-r--r-- | drivers/net/vxge/vxge-main.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 8ab870a..15d878b 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -44,6 +44,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/if_vlan.h> +#include <linux/interrupt.h> #include <linux/pci.h> #include <linux/slab.h> #include <linux/tcp.h> @@ -295,11 +296,13 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan, skb_record_rx_queue(skb, ring->driver_id); skb->protocol = eth_type_trans(skb, ring->ndev); + u64_stats_update_begin(&ring->stats.syncp); ring->stats.rx_frms++; ring->stats.rx_bytes += pkt_length; if (skb->pkt_type == PACKET_MULTICAST) ring->stats.rx_mcast++; + u64_stats_update_end(&ring->stats.syncp); vxge_debug_rx(VXGE_TRACE, "%s: %s:%d skb protocol = %d", @@ -591,8 +594,10 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr, vxge_hw_fifo_txdl_free(fifo_hw, dtr); /* Updating the statistics block */ + u64_stats_update_begin(&fifo->stats.syncp); fifo->stats.tx_frms++; fifo->stats.tx_bytes += skb->len; + u64_stats_update_end(&fifo->stats.syncp); *done_skb++ = skb; @@ -628,7 +633,7 @@ static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb) ip = ip_hdr(skb); - if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) { + if (!ip_is_fragment(ip)) { th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); @@ -679,8 +684,7 @@ static int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac) new_mac_entry->state = mac->state; vpath->mac_addr_cnt++; - /* Is this a multicast address */ - if (0x01 & mac->macaddr[0]) + if (is_multicast_ether_addr(mac->macaddr)) vpath->mcast_addr_cnt++; return TRUE; @@ -694,7 +698,7 @@ vxge_add_mac_addr(struct vxgedev *vdev, struct macInfo *mac) struct vxge_vpath *vpath; enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode; - if (0x01 & mac->macaddr[0]) /* multicast address */ + if (is_multicast_ether_addr(mac->macaddr)) duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE; else duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE; @@ -1073,8 +1077,7 @@ static int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac) kfree((struct vxge_mac_addrs *)entry); vpath->mac_addr_cnt--; - /* Is this a multicast address */ - if (0x01 & mac->macaddr[0]) + if (is_multicast_ether_addr(mac->macaddr)) vpath->mcast_addr_cnt--; return TRUE; } @@ -1196,8 +1199,7 @@ static void vxge_set_multicast(struct net_device *dev) mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); - /* Is this a multicast address */ - if (0x01 & mac_info.macaddr[0]) { + if (is_multicast_ether_addr(mac_info.macaddr)) { for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) { @@ -1239,8 +1241,7 @@ _set_all_mcast: mac_address = (u8 *)&mac_entry->macaddr; memcpy(mac_info.macaddr, mac_address, ETH_ALEN); - /* Is this a multicast address */ - if (0x01 & mac_info.macaddr[0]) + if (is_multicast_ether_addr(mac_info.macaddr)) break; } @@ -2629,11 +2630,16 @@ static void vxge_poll_vp_lockup(unsigned long data) struct vxge_vpath *vpath; struct vxge_ring *ring; int i; + unsigned long rx_frms; for (i = 0; i < vdev->no_of_vpath; i++) { ring = &vdev->vpaths[i].ring; + + /* Truncated to machine word size number of frames */ + rx_frms = ACCESS_ONCE(ring->stats.rx_frms); + /* Did this vpath received any packets */ - if (ring->stats.prev_rx_frms == ring->stats.rx_frms) { + if (ring->stats.prev_rx_frms == rx_frms) { status = vxge_hw_vpath_check_leak(ring->handle); /* Did it received any packets last time */ @@ -2653,7 +2659,7 @@ static void vxge_poll_vp_lockup(unsigned long data) } } } - ring->stats.prev_rx_frms = ring->stats.rx_frms; + ring->stats.prev_rx_frms = rx_frms; ring->last_status = status; } @@ -3124,14 +3130,36 @@ vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) /* net_stats already zeroed by caller */ for (k = 0; k < vdev->no_of_vpath; k++) { - net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms; - net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes; - net_stats->rx_errors += vdev->vpaths[k].ring.stats.rx_errors; - net_stats->multicast += vdev->vpaths[k].ring.stats.rx_mcast; - net_stats->rx_dropped += vdev->vpaths[k].ring.stats.rx_dropped; - net_stats->tx_packets += vdev->vpaths[k].fifo.stats.tx_frms; - net_stats->tx_bytes += vdev->vpaths[k].fifo.stats.tx_bytes; - net_stats->tx_errors += vdev->vpaths[k].fifo.stats.tx_errors; + struct vxge_ring_stats *rxstats = &vdev->vpaths[k].ring.stats; + struct vxge_fifo_stats *txstats = &vdev->vpaths[k].fifo.stats; + unsigned int start; + u64 packets, bytes, multicast; + + do { + start = u64_stats_fetch_begin(&rxstats->syncp); + + packets = rxstats->rx_frms; + multicast = rxstats->rx_mcast; + bytes = rxstats->rx_bytes; + } while (u64_stats_fetch_retry(&rxstats->syncp, start)); + + net_stats->rx_packets += packets; + net_stats->rx_bytes += bytes; + net_stats->multicast += multicast; + + net_stats->rx_errors += rxstats->rx_errors; + net_stats->rx_dropped += rxstats->rx_dropped; + + do { + start = u64_stats_fetch_begin(&txstats->syncp); + + packets = txstats->tx_frms; + bytes = txstats->tx_bytes; + } while (u64_stats_fetch_retry(&txstats->syncp, start)); + + net_stats->tx_packets += packets; + net_stats->tx_bytes += bytes; + net_stats->tx_errors += txstats->tx_errors; } return net_stats; |