Commit edad8d26 authored by Ioana Ciocoi Radulescu's avatar Ioana Ciocoi Radulescu Committed by David S. Miller

dpaa2-eth: Make Rx flow hash key configurable

Until now, the Rx flow hash key was a 5-tuple (IP src, IP dst,
IP nextproto, L4 src port, L4 dst port) fixed value that we
configured at probe.

Add support for configuring this hash key at runtime.
We support all standard header fields configurable through ethtool,
but cannot differentiate between flow types, so the same hash key
is applied regardless of protocol.

We also don't support the discard option.
Signed-off-by: default avatarIoana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 48c1699e
...@@ -2003,9 +2003,21 @@ static int setup_tx_flow(struct dpaa2_eth_priv *priv, ...@@ -2003,9 +2003,21 @@ static int setup_tx_flow(struct dpaa2_eth_priv *priv,
return 0; return 0;
} }
/* Hash key is a 5-tuple: IPsrc, IPdst, IPnextproto, L4src, L4dst */ /* Supported header fields for Rx hash distribution key */
static const struct dpaa2_eth_hash_fields hash_fields[] = { static const struct dpaa2_eth_hash_fields hash_fields[] = {
{ {
/* L2 header */
.rxnfc_field = RXH_L2DA,
.cls_prot = NET_PROT_ETH,
.cls_field = NH_FLD_ETH_DA,
.size = 6,
}, {
/* VLAN header */
.rxnfc_field = RXH_VLAN,
.cls_prot = NET_PROT_VLAN,
.cls_field = NH_FLD_VLAN_TCI,
.size = 2,
}, {
/* IP header */ /* IP header */
.rxnfc_field = RXH_IP_SRC, .rxnfc_field = RXH_IP_SRC,
.cls_prot = NET_PROT_IP, .cls_prot = NET_PROT_IP,
...@@ -2040,19 +2052,20 @@ static const struct dpaa2_eth_hash_fields hash_fields[] = { ...@@ -2040,19 +2052,20 @@ static const struct dpaa2_eth_hash_fields hash_fields[] = {
/* Set RX hash options /* Set RX hash options
* flags is a combination of RXH_ bits * flags is a combination of RXH_ bits
*/ */
static int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags) int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags)
{ {
struct device *dev = net_dev->dev.parent; struct device *dev = net_dev->dev.parent;
struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct dpkg_profile_cfg cls_cfg; struct dpkg_profile_cfg cls_cfg;
struct dpni_rx_tc_dist_cfg dist_cfg; struct dpni_rx_tc_dist_cfg dist_cfg;
u32 rx_hash_fields = 0;
u8 *dma_mem; u8 *dma_mem;
int i; int i;
int err = 0; int err = 0;
if (!dpaa2_eth_hash_enabled(priv)) { if (!dpaa2_eth_hash_enabled(priv)) {
dev_dbg(dev, "Hashing support is not enabled\n"); dev_dbg(dev, "Hashing support is not enabled\n");
return 0; return -EOPNOTSUPP;
} }
memset(&cls_cfg, 0, sizeof(cls_cfg)); memset(&cls_cfg, 0, sizeof(cls_cfg));
...@@ -2075,7 +2088,7 @@ static int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags) ...@@ -2075,7 +2088,7 @@ static int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags)
key->extract.from_hdr.field = hash_fields[i].cls_field; key->extract.from_hdr.field = hash_fields[i].cls_field;
cls_cfg.num_extracts++; cls_cfg.num_extracts++;
priv->rx_hash_fields |= hash_fields[i].rxnfc_field; rx_hash_fields |= hash_fields[i].rxnfc_field;
} }
dma_mem = kzalloc(DPAA2_CLASSIFIER_DMA_SIZE, GFP_KERNEL); dma_mem = kzalloc(DPAA2_CLASSIFIER_DMA_SIZE, GFP_KERNEL);
...@@ -2108,6 +2121,8 @@ static int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags) ...@@ -2108,6 +2121,8 @@ static int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags)
DPAA2_CLASSIFIER_DMA_SIZE, DMA_TO_DEVICE); DPAA2_CLASSIFIER_DMA_SIZE, DMA_TO_DEVICE);
if (err) if (err)
dev_err(dev, "dpni_set_rx_tc_dist() error %d\n", err); dev_err(dev, "dpni_set_rx_tc_dist() error %d\n", err);
else
priv->rx_hash_fields = rx_hash_fields;
err_dma_map: err_dma_map:
err_prep_key: err_prep_key:
...@@ -2141,7 +2156,7 @@ static int bind_dpni(struct dpaa2_eth_priv *priv) ...@@ -2141,7 +2156,7 @@ static int bind_dpni(struct dpaa2_eth_priv *priv)
* the default hash key * the default hash key
*/ */
err = dpaa2_eth_set_hash(net_dev, DPAA2_RXH_DEFAULT); err = dpaa2_eth_set_hash(net_dev, DPAA2_RXH_DEFAULT);
if (err) if (err && err != -EOPNOTSUPP)
dev_err(dev, "Failed to configure hashing\n"); dev_err(dev, "Failed to configure hashing\n");
/* Configure handling of error frames */ /* Configure handling of error frames */
......
...@@ -409,4 +409,6 @@ static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv) ...@@ -409,4 +409,6 @@ static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv)
return priv->dpni_attrs.num_queues; return priv->dpni_attrs.num_queues;
} }
int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags);
#endif /* __DPAA2_H */ #endif /* __DPAA2_H */
...@@ -247,6 +247,24 @@ static int dpaa2_eth_get_rxnfc(struct net_device *net_dev, ...@@ -247,6 +247,24 @@ static int dpaa2_eth_get_rxnfc(struct net_device *net_dev,
return 0; return 0;
} }
static int dpaa2_eth_set_rxnfc(struct net_device *net_dev,
struct ethtool_rxnfc *rxnfc)
{
int err = 0;
switch (rxnfc->cmd) {
case ETHTOOL_SRXFH:
if ((rxnfc->data & DPAA2_RXH_SUPPORTED) != rxnfc->data)
return -EOPNOTSUPP;
err = dpaa2_eth_set_hash(net_dev, rxnfc->data);
break;
default:
err = -EOPNOTSUPP;
}
return err;
}
int dpaa2_phc_index = -1; int dpaa2_phc_index = -1;
EXPORT_SYMBOL(dpaa2_phc_index); EXPORT_SYMBOL(dpaa2_phc_index);
...@@ -276,5 +294,6 @@ const struct ethtool_ops dpaa2_ethtool_ops = { ...@@ -276,5 +294,6 @@ const struct ethtool_ops dpaa2_ethtool_ops = {
.get_ethtool_stats = dpaa2_eth_get_ethtool_stats, .get_ethtool_stats = dpaa2_eth_get_ethtool_stats,
.get_strings = dpaa2_eth_get_strings, .get_strings = dpaa2_eth_get_strings,
.get_rxnfc = dpaa2_eth_get_rxnfc, .get_rxnfc = dpaa2_eth_get_rxnfc,
.set_rxnfc = dpaa2_eth_set_rxnfc,
.get_ts_info = dpaa2_eth_get_ts_info, .get_ts_info = dpaa2_eth_get_ts_info,
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment