net/octeontx2: support GRE key parsing
[dpdk.git] / drivers / net / octeontx2 / otx2_flow_parse.c
index 1940cc6..6670c1a 100644 (file)
@@ -389,6 +389,7 @@ int
 otx2_flow_parse_ld(struct otx2_parse_state *pst)
 {
        char hw_mask[NPC_MAX_EXTRACT_DATA_LEN];
+       uint32_t gre_key_mask = 0xffffffff;
        struct otx2_flow_item_info info;
        int lid, lt, lflags;
        int rc;
@@ -450,6 +451,12 @@ otx2_flow_parse_ld(struct otx2_parse_state *pst)
                info.def_mask = &rte_flow_item_gre_mask;
                info.len = sizeof(struct rte_flow_item_gre);
                break;
+       case RTE_FLOW_ITEM_TYPE_GRE_KEY:
+               lt = NPC_LT_LD_GRE;
+               info.def_mask = &gre_key_mask;
+               info.len = sizeof(gre_key_mask);
+               info.hw_hdr_len = 4;
+               break;
        case RTE_FLOW_ITEM_TYPE_NVGRE:
                lt = NPC_LT_LD_GRE;
                lflags = NPC_F_GRE_NVGRE;
@@ -517,6 +524,13 @@ otx2_flow_parse_lc(struct otx2_parse_state *pst)
                info.def_mask = &rte_flow_item_arp_eth_ipv4_mask;
                info.len = sizeof(struct rte_flow_item_arp_eth_ipv4);
                break;
+       case RTE_FLOW_ITEM_TYPE_IPV6_EXT:
+               lid = NPC_LID_LC;
+               lt = NPC_LT_LC_IP6_EXT;
+               info.def_mask = &rte_flow_item_ipv6_ext_mask;
+               info.len = sizeof(struct rte_flow_item_ipv6_ext);
+               info.hw_hdr_len = 40;
+               break;
        default:
                /* No match at this layer */
                return 0;
@@ -751,15 +765,17 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
        const struct rte_flow_action_count *act_count;
        const struct rte_flow_action_mark *act_mark;
        const struct rte_flow_action_queue *act_q;
+       const struct rte_flow_action_vf *vf_act;
        const char *errmsg = NULL;
        int sel_act, req_act = 0;
-       uint16_t pf_func;
+       uint16_t pf_func, vf_id;
        int errcode = 0;
        int mark = 0;
        int rq = 0;
 
        /* Initialize actions */
        flow->ctr_id = NPC_COUNTER_NONE;
+       pf_func = otx2_pfvf_func(hw->pf, hw->vf);
 
        for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
                otx2_npc_dbg("Action type = %d", actions->type);
@@ -807,6 +823,27 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
                        req_act |= OTX2_FLOW_ACT_DROP;
                        break;
 
+               case RTE_FLOW_ACTION_TYPE_PF:
+                       req_act |= OTX2_FLOW_ACT_PF;
+                       pf_func &= (0xfc00);
+                       break;
+
+               case RTE_FLOW_ACTION_TYPE_VF:
+                       vf_act = (const struct rte_flow_action_vf *)
+                               actions->conf;
+                       req_act |= OTX2_FLOW_ACT_VF;
+                       if (vf_act->original == 0) {
+                               vf_id = (vf_act->id & RVU_PFVF_FUNC_MASK) + 1;
+                               if (vf_id  >= hw->maxvf) {
+                                       errmsg = "invalid vf specified";
+                                       errcode = EINVAL;
+                                       goto err_exit;
+                               }
+                               pf_func &= (0xfc00);
+                               pf_func = (pf_func | vf_id);
+                       }
+                       break;
+
                case RTE_FLOW_ACTION_TYPE_QUEUE:
                        /* Applicable only to ingress flow */
                        act_q = (const struct rte_flow_action_queue *)
@@ -902,7 +939,11 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
        }
 
        /* Set NIX_RX_ACTIONOP */
-       if (req_act & OTX2_FLOW_ACT_DROP) {
+       if (req_act & (OTX2_FLOW_ACT_PF | OTX2_FLOW_ACT_VF)) {
+               flow->npc_action = NIX_RX_ACTIONOP_UCAST;
+               if (req_act & OTX2_FLOW_ACT_QUEUE)
+                       flow->npc_action |= (uint64_t)rq << 20;
+       } else if (req_act & OTX2_FLOW_ACT_DROP) {
                flow->npc_action = NIX_RX_ACTIONOP_DROP;
        } else if (req_act & OTX2_FLOW_ACT_QUEUE) {
                flow->npc_action = NIX_RX_ACTIONOP_UCAST;
@@ -946,7 +987,6 @@ otx2_flow_parse_actions(struct rte_eth_dev *dev,
 
 set_pf_func:
        /* Ideally AF must ensure that correct pf_func is set */
-       pf_func = otx2_pfvf_func(hw->pf, hw->vf);
        flow->npc_action |= (uint64_t)pf_func << 4;
 
        return 0;