Skip to content

Commit

Permalink
vxge: enable rxhash
Browse files Browse the repository at this point in the history
Enable RSS hashing and add ability to pass up the adapter calculated rx
hash up the network stack (if feature is available).  Add the ability to
enable/disable feature via ethtool, which requires that the adapter is
not running at the time.  Other miscellaneous cleanups and fixes
required to get RSS working.

Signed-off-by: Jon Mason <jon.mason@exar.com>
Signed-off-by: Ram Vepa <ram.vepa@exar.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jon Mason authored and David S. Miller committed Nov 11, 2010
1 parent 0c6202b commit 47f01db
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 63 deletions.
2 changes: 2 additions & 0 deletions drivers/net/vxge/vxge-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3204,6 +3204,8 @@ enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
0, &data0, &data1);
if (status != VXGE_HW_OK)
goto exit;

data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
Expand Down
12 changes: 6 additions & 6 deletions drivers/net/vxge/vxge-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1413,12 +1413,12 @@ enum vxge_hw_rth_algoritms {
* See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get().
*/
struct vxge_hw_rth_hash_types {
u8 hash_type_tcpipv4_en;
u8 hash_type_ipv4_en;
u8 hash_type_tcpipv6_en;
u8 hash_type_ipv6_en;
u8 hash_type_tcpipv6ex_en;
u8 hash_type_ipv6ex_en;
u8 hash_type_tcpipv4_en:1,
hash_type_ipv4_en:1,
hash_type_tcpipv6_en:1,
hash_type_ipv6_en:1,
hash_type_tcpipv6ex_en:1,
hash_type_ipv6ex_en:1;
};

void vxge_hw_device_debug_set(
Expand Down
35 changes: 35 additions & 0 deletions drivers/net/vxge/vxge-ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,40 @@ static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
}
}

static int vxge_set_flags(struct net_device *dev, u32 data)
{
struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
enum vxge_hw_status status;

if (data & ~ETH_FLAG_RXHASH)
return -EOPNOTSUPP;

if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
return 0;

if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING))
return -EINVAL;

vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH);

/* Enabling RTH requires some of the logic in vxge_device_register and a
* vpath reset. Due to these restrictions, only allow modification
* while the interface is down.
*/
status = vxge_reset_all_vpaths(vdev);
if (status != VXGE_HW_OK) {
vdev->devh->config.rth_en = !vdev->devh->config.rth_en;
return -EFAULT;
}

if (vdev->devh->config.rth_en)
dev->features |= NETIF_F_RXHASH;
else
dev->features &= ~NETIF_F_RXHASH;

return 0;
}

static const struct ethtool_ops vxge_ethtool_ops = {
.get_settings = vxge_ethtool_gset,
.set_settings = vxge_ethtool_sset,
Expand All @@ -1140,6 +1174,7 @@ static const struct ethtool_ops vxge_ethtool_ops = {
.phys_id = vxge_ethtool_idnic,
.get_sset_count = vxge_ethtool_get_sset_count,
.get_ethtool_stats = vxge_get_ethtool_stats,
.set_flags = vxge_set_flags,
};

void vxge_initialize_ethtool_ops(struct net_device *ndev)
Expand Down
54 changes: 34 additions & 20 deletions drivers/net/vxge/vxge-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,13 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
else
skb_checksum_none_assert(skb);

/* rth_hash_type and rth_it_hit are non-zero regardless of
* whether rss is enabled. Only the rth_value is zero/non-zero
* if rss is disabled/enabled, so key off of that.
*/
if (ext_info.rth_value)
skb->rxhash = ext_info.rth_value;

vxge_rx_complete(ring, skb, ext_info.vlan,
pkt_length, &ext_info);

Expand Down Expand Up @@ -1689,15 +1696,6 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
mtable[index] = index % vdev->no_of_vpath;
}

/* Fill RTH hash types */
hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4;
hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4;
hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6;
hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6;
hash_types.hash_type_tcpipv6ex_en =
vdev->config.rth_hash_type_tcpipv6ex;
hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex;

/* set indirection table, bucket-to-vpath mapping */
status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles,
vdev->no_of_vpath,
Expand All @@ -1710,12 +1708,21 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
return status;
}

/* Fill RTH hash types */
hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4;
hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4;
hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6;
hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6;
hash_types.hash_type_tcpipv6ex_en =
vdev->config.rth_hash_type_tcpipv6ex;
hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex;

/*
* Because the itable_set() method uses the active_table field
* for the target virtual path the RTH config should be updated
* for all VPATHs. The h/w only uses the lowest numbered VPATH
* when steering frames.
*/
* Because the itable_set() method uses the active_table field
* for the target virtual path the RTH config should be updated
* for all VPATHs. The h/w only uses the lowest numbered VPATH
* when steering frames.
*/
for (index = 0; index < vdev->no_of_vpath; index++) {
status = vxge_hw_vpath_rts_rth_set(
vdev->vpaths[index].handle,
Expand Down Expand Up @@ -2598,6 +2605,8 @@ vxge_open(struct net_device *dev)
goto out2;
}
}
printk(KERN_INFO "%s: Receive Hashing Offload %s\n", dev->name,
hldev->config.rth_en ? "enabled" : "disabled");

for (i = 0; i < vdev->no_of_vpath; i++) {
vpath = &vdev->vpaths[i];
Expand Down Expand Up @@ -3178,6 +3187,11 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,

vxge_initialize_ethtool_ops(ndev);

if (vdev->config.rth_steering != NO_STEERING) {
ndev->features |= NETIF_F_RXHASH;
hldev->config.rth_en = VXGE_HW_RTH_ENABLE;
}

/* Allocate memory for vpath */
vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
no_of_vpath, GFP_KERNEL);
Expand Down Expand Up @@ -4163,12 +4177,12 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
ll_config->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
ll_config->addr_learn_en = addr_learn_en;
ll_config->rth_algorithm = RTH_ALG_JENKINS;
ll_config->rth_hash_type_tcpipv4 = VXGE_HW_RING_HASH_TYPE_TCP_IPV4;
ll_config->rth_hash_type_ipv4 = VXGE_HW_RING_HASH_TYPE_NONE;
ll_config->rth_hash_type_tcpipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
ll_config->rth_hash_type_ipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
ll_config->rth_hash_type_tcpipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
ll_config->rth_hash_type_ipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
ll_config->rth_hash_type_tcpipv4 = 1;
ll_config->rth_hash_type_ipv4 = 0;
ll_config->rth_hash_type_tcpipv6 = 0;
ll_config->rth_hash_type_ipv6 = 0;
ll_config->rth_hash_type_tcpipv6ex = 0;
ll_config->rth_hash_type_ipv6ex = 0;
ll_config->rth_bkt_sz = RTH_BUCKET_SIZE;
ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
Expand Down
18 changes: 9 additions & 9 deletions drivers/net/vxge/vxge-main.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,15 @@ struct vxge_config {

int addr_learn_en;

int rth_steering;
int rth_algorithm;
int rth_hash_type_tcpipv4;
int rth_hash_type_ipv4;
int rth_hash_type_tcpipv6;
int rth_hash_type_ipv6;
int rth_hash_type_tcpipv6ex;
int rth_hash_type_ipv6ex;
int rth_bkt_sz;
u32 rth_steering:2,
rth_algorithm:2,
rth_hash_type_tcpipv4:1,
rth_hash_type_ipv4:1,
rth_hash_type_tcpipv6:1,
rth_hash_type_ipv6:1,
rth_hash_type_tcpipv6ex:1,
rth_hash_type_ipv6ex:1,
rth_bkt_sz:8;
int rth_jhash_golden_ratio;
int tx_steering_type;
int fifo_indicate_max_pkts;
Expand Down
28 changes: 0 additions & 28 deletions drivers/net/vxge/vxge-traffic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1904,34 +1904,6 @@ enum vxge_hw_ring_tcode {
VXGE_HW_RING_T_CODE_MULTI_ERR = 0xF
};

/**
* enum enum vxge_hw_ring_hash_type - RTH hash types
* @VXGE_HW_RING_HASH_TYPE_NONE: No Hash
* @VXGE_HW_RING_HASH_TYPE_TCP_IPV4: TCP IPv4
* @VXGE_HW_RING_HASH_TYPE_UDP_IPV4: UDP IPv4
* @VXGE_HW_RING_HASH_TYPE_IPV4: IPv4
* @VXGE_HW_RING_HASH_TYPE_TCP_IPV6: TCP IPv6
* @VXGE_HW_RING_HASH_TYPE_UDP_IPV6: UDP IPv6
* @VXGE_HW_RING_HASH_TYPE_IPV6: IPv6
* @VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX: TCP IPv6 extension
* @VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX: UDP IPv6 extension
* @VXGE_HW_RING_HASH_TYPE_IPV6_EX: IPv6 extension
*
* RTH hash types
*/
enum vxge_hw_ring_hash_type {
VXGE_HW_RING_HASH_TYPE_NONE = 0x0,
VXGE_HW_RING_HASH_TYPE_TCP_IPV4 = 0x1,
VXGE_HW_RING_HASH_TYPE_UDP_IPV4 = 0x2,
VXGE_HW_RING_HASH_TYPE_IPV4 = 0x3,
VXGE_HW_RING_HASH_TYPE_TCP_IPV6 = 0x4,
VXGE_HW_RING_HASH_TYPE_UDP_IPV6 = 0x5,
VXGE_HW_RING_HASH_TYPE_IPV6 = 0x6,
VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX = 0x7,
VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX = 0x8,
VXGE_HW_RING_HASH_TYPE_IPV6_EX = 0x9
};

enum vxge_hw_status vxge_hw_ring_rxd_reserve(
struct __vxge_hw_ring *ring_handle,
void **rxdh);
Expand Down

0 comments on commit 47f01db

Please sign in to comment.