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 8ab870a2ad02..178348a258d2 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, |