diff options
Diffstat (limited to 'drivers/net/vxge/vxge-main.c')
| -rw-r--r-- | drivers/net/vxge/vxge-main.c | 159 | 
1 files changed, 61 insertions, 98 deletions
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 8ab870a2ad0..178348a258d 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -43,7 +43,9 @@  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/bitops.h>  #include <linux/if_vlan.h> +#include <linux/interrupt.h>  #include <linux/pci.h>  #include <linux/slab.h>  #include <linux/tcp.h> @@ -295,23 +297,22 @@ 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",  		ring->ndev->name, __func__, __LINE__, skb->protocol); -	if (ring->vlgrp && ext_info->vlan && -		(ring->vlan_tag_strip == -			VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE)) -		vlan_gro_receive(ring->napi_p, ring->vlgrp, -				ext_info->vlan, skb); -	else -		napi_gro_receive(ring->napi_p, skb); +	if (ext_info->vlan && +	    ring->vlan_tag_strip == VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) +		__vlan_hwaccel_put_tag(skb, ext_info->vlan); +	napi_gro_receive(ring->napi_p, skb);  	vxge_debug_entryexit(VXGE_TRACE,  		"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__); @@ -591,8 +592,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 +631,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 +682,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 +696,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 +1075,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 +1197,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 +1239,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;  			} @@ -1488,15 +1487,11 @@ vxge_restore_vpath_vid_table(struct vxge_vpath *vpath)  	struct vxgedev *vdev = vpath->vdev;  	u16 vid; -	if (vdev->vlgrp && vpath->is_open) { +	if (!vpath->is_open) +		return status; -		for (vid = 0; vid < VLAN_N_VID; vid++) { -			if (!vlan_group_get_device(vdev->vlgrp, vid)) -				continue; -			/* Add these vlan to the vid table */ -			status = vxge_hw_vpath_vid_add(vpath->handle, vid); -		} -	} +	for_each_set_bit(vid, vdev->active_vlans, VLAN_N_VID) +		status = vxge_hw_vpath_vid_add(vpath->handle, vid);  	return status;  } @@ -2629,11 +2624,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 +2653,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 +3124,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; @@ -3275,60 +3297,6 @@ static void vxge_tx_watchdog(struct net_device *dev)  }  /** - * vxge_vlan_rx_register - * @dev: net device pointer. - * @grp: vlan group - * - * Vlan group registration - */ -static void -vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) -{ -	struct vxgedev *vdev; -	struct vxge_vpath *vpath; -	int vp; -	u64 vid; -	enum vxge_hw_status status; -	int i; - -	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); - -	vdev = netdev_priv(dev); - -	vpath = &vdev->vpaths[0]; -	if ((NULL == grp) && (vpath->is_open)) { -		/* Get the first vlan */ -		status = vxge_hw_vpath_vid_get(vpath->handle, &vid); - -		while (status == VXGE_HW_OK) { - -			/* Delete this vlan from the vid table */ -			for (vp = 0; vp < vdev->no_of_vpath; vp++) { -				vpath = &vdev->vpaths[vp]; -				if (!vpath->is_open) -					continue; - -				vxge_hw_vpath_vid_delete(vpath->handle, vid); -			} - -			/* Get the next vlan to be deleted */ -			vpath = &vdev->vpaths[0]; -			status = vxge_hw_vpath_vid_get(vpath->handle, &vid); -		} -	} - -	vdev->vlgrp = grp; - -	for (i = 0; i < vdev->no_of_vpath; i++) { -		if (vdev->vpaths[i].is_configured) -			vdev->vpaths[i].ring.vlgrp = grp; -	} - -	vxge_debug_entryexit(VXGE_TRACE, -		"%s:%d  Exiting...", __func__, __LINE__); -} - -/**   * vxge_vlan_rx_add_vid   * @dev: net device pointer.   * @vid: vid @@ -3338,12 +3306,10 @@ vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)  static void  vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)  { -	struct vxgedev *vdev; +	struct vxgedev *vdev = netdev_priv(dev);  	struct vxge_vpath *vpath;  	int vp_id; -	vdev = netdev_priv(dev); -  	/* Add these vlan to the vid table */  	for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {  		vpath = &vdev->vpaths[vp_id]; @@ -3351,6 +3317,7 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)  			continue;  		vxge_hw_vpath_vid_add(vpath->handle, vid);  	} +	set_bit(vid, vdev->active_vlans);  }  /** @@ -3363,16 +3330,12 @@ vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)  static void  vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)  { -	struct vxgedev *vdev; +	struct vxgedev *vdev = netdev_priv(dev);  	struct vxge_vpath *vpath;  	int vp_id;  	vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__); -	vdev = netdev_priv(dev); - -	vlan_group_set_device(vdev->vlgrp, vid, NULL); -  	/* Delete this vlan from the vid table */  	for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {  		vpath = &vdev->vpaths[vp_id]; @@ -3382,6 +3345,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)  	}  	vxge_debug_entryexit(VXGE_TRACE,  		"%s:%d  Exiting...", __func__, __LINE__); +	clear_bit(vid, vdev->active_vlans);  }  static const struct net_device_ops vxge_netdev_ops = { @@ -3396,7 +3360,6 @@ static const struct net_device_ops vxge_netdev_ops = {  	.ndo_change_mtu         = vxge_change_mtu,  	.ndo_fix_features	= vxge_fix_features,  	.ndo_set_features	= vxge_set_features, -	.ndo_vlan_rx_register   = vxge_vlan_rx_register,  	.ndo_vlan_rx_kill_vid   = vxge_vlan_rx_kill_vid,  	.ndo_vlan_rx_add_vid	= vxge_vlan_rx_add_vid,  	.ndo_tx_timeout         = vxge_tx_watchdog,  |