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[] = {
{
+ /* 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 */
.rxnfc_field = RXH_IP_SRC,
.cls_prot = NET_PROT_IP,
/* Set RX hash options
* 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 dpaa2_eth_priv *priv = netdev_priv(net_dev);
struct dpkg_profile_cfg cls_cfg;
struct dpni_rx_tc_dist_cfg dist_cfg;
+ u32 rx_hash_fields = 0;
u8 *dma_mem;
int i;
int err = 0;
if (!dpaa2_eth_hash_enabled(priv)) {
dev_dbg(dev, "Hashing support is not enabled\n");
- return 0;
+ return -EOPNOTSUPP;
}
memset(&cls_cfg, 0, sizeof(cls_cfg));
key->extract.from_hdr.field = hash_fields[i].cls_field;
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);
DPAA2_CLASSIFIER_DMA_SIZE, DMA_TO_DEVICE);
if (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_prep_key:
* the default hash key
*/
err = dpaa2_eth_set_hash(net_dev, DPAA2_RXH_DEFAULT);
- if (err)
+ if (err && err != -EOPNOTSUPP)
dev_err(dev, "Failed to configure hashing\n");
/* Configure handling of error frames */
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;
EXPORT_SYMBOL(dpaa2_phc_index);
.get_ethtool_stats = dpaa2_eth_get_ethtool_stats,
.get_strings = dpaa2_eth_get_strings,
.get_rxnfc = dpaa2_eth_get_rxnfc,
+ .set_rxnfc = dpaa2_eth_set_rxnfc,
.get_ts_info = dpaa2_eth_get_ts_info,
};