mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
        mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
 
-       /* Set L4 offset */
-       mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
-                                 sizeof(struct iphdr) - 4,
+       /* Set L3 offset */
+       mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, -4,
                                  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
        mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
        mvpp2_prs_sram_ri_update(&pe, ri, ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);
 static int mvpp2_prs_etype_init(struct mvpp2 *priv)
 {
        struct mvpp2_prs_entry pe;
-       int tid;
+       int tid, ihl;
 
        /* Ethertype: PPPoE */
        tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
                                MVPP2_PRS_RI_UDF3_MASK);
        mvpp2_prs_hw_write(priv, &pe);
 
-       /* Ethertype: IPv4 without options */
-       tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
-                                       MVPP2_PE_LAST_FREE_TID);
-       if (tid < 0)
-               return tid;
-
-       memset(&pe, 0, sizeof(pe));
-       mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
-       pe.index = tid;
-
-       mvpp2_prs_match_etype(&pe, 0, ETH_P_IP);
-       mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
-                                    MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
-                                    MVPP2_PRS_IPV4_HEAD_MASK |
-                                    MVPP2_PRS_IPV4_IHL_MASK);
-
-       mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
-       mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
-                                MVPP2_PRS_RI_L3_PROTO_MASK);
-       /* goto ipv4 dest-address (skip eth_type + IP-header-size - 4) */
-       mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN +
-                                sizeof(struct iphdr) - 4,
-                                MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
-       /* Set L3 offset */
-       mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,
-                                 MVPP2_ETH_TYPE_LEN,
-                                 MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
-
-       /* Update shadow table and hw entry */
-       mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
-       priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
-       priv->prs_shadow[pe.index].finish = false;
-       mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP4,
-                               MVPP2_PRS_RI_L3_PROTO_MASK);
-       mvpp2_prs_hw_write(priv, &pe);
-
-       /* Ethertype: IPv4 with options */
-       tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
-                                       MVPP2_PE_LAST_FREE_TID);
-       if (tid < 0)
-               return tid;
-
-       pe.index = tid;
+       /* Ethertype: IPv4 with header length >= 5 */
+       for (ihl = MVPP2_PRS_IPV4_IHL_MIN; ihl <= MVPP2_PRS_IPV4_IHL_MAX; ihl++) {
+               tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
+                                               MVPP2_PE_LAST_FREE_TID);
+               if (tid < 0)
+                       return tid;
 
-       mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
-                                    MVPP2_PRS_IPV4_HEAD,
-                                    MVPP2_PRS_IPV4_HEAD_MASK);
+               memset(&pe, 0, sizeof(pe));
+               mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);
+               pe.index = tid;
 
-       /* Clear ri before updating */
-       pe.sram[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
-       pe.sram[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
-       mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT,
-                                MVPP2_PRS_RI_L3_PROTO_MASK);
+               mvpp2_prs_match_etype(&pe, 0, ETH_P_IP);
+               mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
+                                            MVPP2_PRS_IPV4_HEAD | ihl,
+                                            MVPP2_PRS_IPV4_HEAD_MASK |
+                                            MVPP2_PRS_IPV4_IHL_MASK);
+
+               mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);
+               mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,
+                                        MVPP2_PRS_RI_L3_PROTO_MASK);
+               /* goto ipv4 dst-address (skip eth_type + IP-header-size - 4) */
+               mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN +
+                                        sizeof(struct iphdr) - 4,
+                                        MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
+               /* Set L4 offset */
+               mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
+                                         MVPP2_ETH_TYPE_LEN + (ihl * 4),
+                                         MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
 
-       /* Update shadow table and hw entry */
-       mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
-       priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
-       priv->prs_shadow[pe.index].finish = false;
-       mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP4_OPT,
-                               MVPP2_PRS_RI_L3_PROTO_MASK);
-       mvpp2_prs_hw_write(priv, &pe);
+               /* Update shadow table and hw entry */
+               mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);
+               priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;
+               priv->prs_shadow[pe.index].finish = false;
+               mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP4,
+                                       MVPP2_PRS_RI_L3_PROTO_MASK);
+               mvpp2_prs_hw_write(priv, &pe);
+       }
 
        /* Ethertype: IPv6 without options */
        tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
        pe.index = tid;
 
        mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,
-                                    MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
+                                    MVPP2_PRS_IPV4_HEAD |
+                                    MVPP2_PRS_IPV4_IHL_MIN,
                                     MVPP2_PRS_IPV4_HEAD_MASK |
                                     MVPP2_PRS_IPV4_IHL_MASK);
 
        mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
        mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
 
-       /* Set L4 offset */
-       mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,
-                                 sizeof(struct iphdr) - 4,
+       /* Set L3 offset */
+       mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, -4,
                                  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
        mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
        mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,