int i;
 
        priv->rfs_entries_max[STMMAC_RFS_T_VLAN] = 8;
+       priv->rfs_entries_max[STMMAC_RFS_T_LLDP] = 1;
+       priv->rfs_entries_max[STMMAC_RFS_T_1588] = 1;
 
        for (i = 0; i < STMMAC_RFS_T_MAX; i++)
                priv->rfs_entries_total += priv->rfs_entries_max[i];
        return 0;
 }
 
+#define ETHER_TYPE_FULL_MASK   cpu_to_be16(~0)
+
 static int tc_add_basic_flow(struct stmmac_priv *priv,
                             struct flow_cls_offload *cls,
                             struct stmmac_flow_entry *entry)
                return -EINVAL;
 
        flow_rule_match_basic(rule, &match);
+
        entry->ip_proto = match.key->ip_proto;
        return 0;
 }
        return 0;
 }
 
+static int tc_add_ethtype_flow(struct stmmac_priv *priv,
+                              struct flow_cls_offload *cls)
+{
+       struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false);
+       struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
+       struct flow_dissector *dissector = rule->match.dissector;
+       int tc = tc_classid_to_hwtc(priv->dev, cls->classid);
+       struct flow_match_basic match;
+
+       if (!entry) {
+               entry = tc_find_rfs(priv, cls, true);
+               if (!entry)
+                       return -ENOENT;
+       }
+
+       /* Nothing to do here */
+       if (!dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_BASIC))
+               return -EINVAL;
+
+       if (tc < 0) {
+               netdev_err(priv->dev, "Invalid traffic class\n");
+               return -EINVAL;
+       }
+
+       flow_rule_match_basic(rule, &match);
+
+       if (match.mask->n_proto) {
+               u16 etype = ntohs(match.key->n_proto);
+
+               if (match.mask->n_proto != ETHER_TYPE_FULL_MASK) {
+                       netdev_err(priv->dev, "Only full mask is supported for EthType filter");
+                       return -EINVAL;
+               }
+               switch (etype) {
+               case ETH_P_LLDP:
+                       if (priv->rfs_entries_cnt[STMMAC_RFS_T_LLDP] >=
+                           priv->rfs_entries_max[STMMAC_RFS_T_LLDP])
+                               return -ENOENT;
+
+                       entry->type = STMMAC_RFS_T_LLDP;
+                       priv->rfs_entries_cnt[STMMAC_RFS_T_LLDP]++;
+
+                       stmmac_rx_queue_routing(priv, priv->hw,
+                                               PACKET_DCBCPQ, tc);
+                       break;
+               case ETH_P_1588:
+                       if (priv->rfs_entries_cnt[STMMAC_RFS_T_1588] >=
+                           priv->rfs_entries_max[STMMAC_RFS_T_1588])
+                               return -ENOENT;
+
+                       entry->type = STMMAC_RFS_T_1588;
+                       priv->rfs_entries_cnt[STMMAC_RFS_T_1588]++;
+
+                       stmmac_rx_queue_routing(priv, priv->hw,
+                                               PACKET_PTPQ, tc);
+                       break;
+               default:
+                       netdev_err(priv->dev, "EthType(0x%x) is not supported", etype);
+                       return -EINVAL;
+               }
+
+               entry->in_use = true;
+               entry->cookie = cls->cookie;
+               entry->tc = tc;
+               entry->etype = etype;
+
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int tc_del_ethtype_flow(struct stmmac_priv *priv,
+                              struct flow_cls_offload *cls)
+{
+       struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false);
+
+       if (!entry || !entry->in_use ||
+           entry->type < STMMAC_RFS_T_LLDP ||
+           entry->type > STMMAC_RFS_T_1588)
+               return -ENOENT;
+
+       switch (entry->etype) {
+       case ETH_P_LLDP:
+               stmmac_rx_queue_routing(priv, priv->hw,
+                                       PACKET_DCBCPQ, 0);
+               priv->rfs_entries_cnt[STMMAC_RFS_T_LLDP]--;
+               break;
+       case ETH_P_1588:
+               stmmac_rx_queue_routing(priv, priv->hw,
+                                       PACKET_PTPQ, 0);
+               priv->rfs_entries_cnt[STMMAC_RFS_T_1588]--;
+               break;
+       default:
+               netdev_err(priv->dev, "EthType(0x%x) is not supported",
+                          entry->etype);
+               return -EINVAL;
+       }
+
+       entry->in_use = false;
+       entry->cookie = 0;
+       entry->tc = 0;
+       entry->etype = 0;
+       entry->type = 0;
+
+       return 0;
+}
+
 static int tc_add_flow_cls(struct stmmac_priv *priv,
                           struct flow_cls_offload *cls)
 {
        if (!ret)
                return ret;
 
+       ret = tc_add_ethtype_flow(priv, cls);
+       if (!ret)
+               return ret;
+
        return tc_add_vlan_flow(priv, cls);
 }
 
        if (!ret)
                return ret;
 
+       ret = tc_del_ethtype_flow(priv, cls);
+       if (!ret)
+               return ret;
+
        return tc_del_vlan_flow(priv, cls);
 }