mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
vxge: enable rxhash
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>
This commit is contained in:
parent
0c6202b327
commit
47f01db44b
@ -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_ACTION_READ_ENTRY,
|
||||||
VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
|
VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
|
||||||
0, &data0, &data1);
|
0, &data0, &data1);
|
||||||
|
if (status != VXGE_HW_OK)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
|
data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
|
||||||
VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
|
VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
|
||||||
|
@ -1413,12 +1413,12 @@ enum vxge_hw_rth_algoritms {
|
|||||||
* See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get().
|
* See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get().
|
||||||
*/
|
*/
|
||||||
struct vxge_hw_rth_hash_types {
|
struct vxge_hw_rth_hash_types {
|
||||||
u8 hash_type_tcpipv4_en;
|
u8 hash_type_tcpipv4_en:1,
|
||||||
u8 hash_type_ipv4_en;
|
hash_type_ipv4_en:1,
|
||||||
u8 hash_type_tcpipv6_en;
|
hash_type_tcpipv6_en:1,
|
||||||
u8 hash_type_ipv6_en;
|
hash_type_ipv6_en:1,
|
||||||
u8 hash_type_tcpipv6ex_en;
|
hash_type_tcpipv6ex_en:1,
|
||||||
u8 hash_type_ipv6ex_en;
|
hash_type_ipv6ex_en:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
void vxge_hw_device_debug_set(
|
void vxge_hw_device_debug_set(
|
||||||
|
@ -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 = {
|
static const struct ethtool_ops vxge_ethtool_ops = {
|
||||||
.get_settings = vxge_ethtool_gset,
|
.get_settings = vxge_ethtool_gset,
|
||||||
.set_settings = vxge_ethtool_sset,
|
.set_settings = vxge_ethtool_sset,
|
||||||
@ -1140,6 +1174,7 @@ static const struct ethtool_ops vxge_ethtool_ops = {
|
|||||||
.phys_id = vxge_ethtool_idnic,
|
.phys_id = vxge_ethtool_idnic,
|
||||||
.get_sset_count = vxge_ethtool_get_sset_count,
|
.get_sset_count = vxge_ethtool_get_sset_count,
|
||||||
.get_ethtool_stats = vxge_get_ethtool_stats,
|
.get_ethtool_stats = vxge_get_ethtool_stats,
|
||||||
|
.set_flags = vxge_set_flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
void vxge_initialize_ethtool_ops(struct net_device *ndev)
|
void vxge_initialize_ethtool_ops(struct net_device *ndev)
|
||||||
|
@ -513,6 +513,13 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
|
|||||||
else
|
else
|
||||||
skb_checksum_none_assert(skb);
|
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,
|
vxge_rx_complete(ring, skb, ext_info.vlan,
|
||||||
pkt_length, &ext_info);
|
pkt_length, &ext_info);
|
||||||
|
|
||||||
@ -1689,15 +1696,6 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
|
|||||||
mtable[index] = index % vdev->no_of_vpath;
|
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 */
|
/* set indirection table, bucket-to-vpath mapping */
|
||||||
status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles,
|
status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles,
|
||||||
vdev->no_of_vpath,
|
vdev->no_of_vpath,
|
||||||
@ -1710,12 +1708,21 @@ static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
|
|||||||
return status;
|
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
|
* Because the itable_set() method uses the active_table field
|
||||||
* for the target virtual path the RTH config should be updated
|
* for the target virtual path the RTH config should be updated
|
||||||
* for all VPATHs. The h/w only uses the lowest numbered VPATH
|
* for all VPATHs. The h/w only uses the lowest numbered VPATH
|
||||||
* when steering frames.
|
* when steering frames.
|
||||||
*/
|
*/
|
||||||
for (index = 0; index < vdev->no_of_vpath; index++) {
|
for (index = 0; index < vdev->no_of_vpath; index++) {
|
||||||
status = vxge_hw_vpath_rts_rth_set(
|
status = vxge_hw_vpath_rts_rth_set(
|
||||||
vdev->vpaths[index].handle,
|
vdev->vpaths[index].handle,
|
||||||
@ -2598,6 +2605,8 @@ vxge_open(struct net_device *dev)
|
|||||||
goto out2;
|
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++) {
|
for (i = 0; i < vdev->no_of_vpath; i++) {
|
||||||
vpath = &vdev->vpaths[i];
|
vpath = &vdev->vpaths[i];
|
||||||
@ -3178,6 +3187,11 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
|
|||||||
|
|
||||||
vxge_initialize_ethtool_ops(ndev);
|
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 */
|
/* Allocate memory for vpath */
|
||||||
vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
|
vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
|
||||||
no_of_vpath, GFP_KERNEL);
|
no_of_vpath, GFP_KERNEL);
|
||||||
@ -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->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
|
||||||
ll_config->addr_learn_en = addr_learn_en;
|
ll_config->addr_learn_en = addr_learn_en;
|
||||||
ll_config->rth_algorithm = RTH_ALG_JENKINS;
|
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_tcpipv4 = 1;
|
||||||
ll_config->rth_hash_type_ipv4 = VXGE_HW_RING_HASH_TYPE_NONE;
|
ll_config->rth_hash_type_ipv4 = 0;
|
||||||
ll_config->rth_hash_type_tcpipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
|
ll_config->rth_hash_type_tcpipv6 = 0;
|
||||||
ll_config->rth_hash_type_ipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
|
ll_config->rth_hash_type_ipv6 = 0;
|
||||||
ll_config->rth_hash_type_tcpipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
|
ll_config->rth_hash_type_tcpipv6ex = 0;
|
||||||
ll_config->rth_hash_type_ipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
|
ll_config->rth_hash_type_ipv6ex = 0;
|
||||||
ll_config->rth_bkt_sz = RTH_BUCKET_SIZE;
|
ll_config->rth_bkt_sz = RTH_BUCKET_SIZE;
|
||||||
ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
|
ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
|
||||||
ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
|
ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
|
||||||
|
@ -145,15 +145,15 @@ struct vxge_config {
|
|||||||
|
|
||||||
int addr_learn_en;
|
int addr_learn_en;
|
||||||
|
|
||||||
int rth_steering;
|
u32 rth_steering:2,
|
||||||
int rth_algorithm;
|
rth_algorithm:2,
|
||||||
int rth_hash_type_tcpipv4;
|
rth_hash_type_tcpipv4:1,
|
||||||
int rth_hash_type_ipv4;
|
rth_hash_type_ipv4:1,
|
||||||
int rth_hash_type_tcpipv6;
|
rth_hash_type_tcpipv6:1,
|
||||||
int rth_hash_type_ipv6;
|
rth_hash_type_ipv6:1,
|
||||||
int rth_hash_type_tcpipv6ex;
|
rth_hash_type_tcpipv6ex:1,
|
||||||
int rth_hash_type_ipv6ex;
|
rth_hash_type_ipv6ex:1,
|
||||||
int rth_bkt_sz;
|
rth_bkt_sz:8;
|
||||||
int rth_jhash_golden_ratio;
|
int rth_jhash_golden_ratio;
|
||||||
int tx_steering_type;
|
int tx_steering_type;
|
||||||
int fifo_indicate_max_pkts;
|
int fifo_indicate_max_pkts;
|
||||||
|
@ -1904,34 +1904,6 @@ enum vxge_hw_ring_tcode {
|
|||||||
VXGE_HW_RING_T_CODE_MULTI_ERR = 0xF
|
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(
|
enum vxge_hw_status vxge_hw_ring_rxd_reserve(
|
||||||
struct __vxge_hw_ring *ring_handle,
|
struct __vxge_hw_ring *ring_handle,
|
||||||
void **rxdh);
|
void **rxdh);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user