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,
 };