net/bnxt: match flow API items with flow template patterns
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_matcher.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include "ulp_matcher.h"
7 #include "ulp_utils.h"
8
9 /* Utility function to check if bitmap is zero */
10 static inline
11 int ulp_field_mask_is_zero(uint8_t *bitmap, uint32_t size)
12 {
13         while (size-- > 0) {
14                 if (*bitmap != 0)
15                         return 0;
16                 bitmap++;
17         }
18         return 1;
19 }
20
21 /* Utility function to check if bitmap is all ones */
22 static inline int
23 ulp_field_mask_is_ones(uint8_t *bitmap, uint32_t size)
24 {
25         while (size-- > 0) {
26                 if (*bitmap != 0xFF)
27                         return 0;
28                 bitmap++;
29         }
30         return 1;
31 }
32
33 /* Utility function to check if bitmap is non zero */
34 static inline int
35 ulp_field_mask_notzero(uint8_t *bitmap, uint32_t size)
36 {
37         while (size-- > 0) {
38                 if (*bitmap != 0)
39                         return 1;
40                 bitmap++;
41         }
42         return 0;
43 }
44
45 /* Utility function to mask the computed and internal proto headers. */
46 static void
47 ulp_matcher_hdr_fields_normalize(struct ulp_rte_hdr_bitmap *hdr1,
48                                  struct ulp_rte_hdr_bitmap *hdr2)
49 {
50         /* copy the contents first */
51         rte_memcpy(hdr2, hdr1, sizeof(struct ulp_rte_hdr_bitmap));
52
53         /* reset the computed fields */
54         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_SVIF);
55         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_OO_VLAN);
56         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_OI_VLAN);
57         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_IO_VLAN);
58         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_II_VLAN);
59         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_O_L3);
60         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_O_L4);
61         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_I_L3);
62         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_I_L4);
63 }
64
65 /*
66  * Function to handle the matching of RTE Flows and validating
67  * the pattern masks against the flow templates.
68  */
69 int32_t
70 ulp_matcher_pattern_match(enum ulp_direction_type   dir,
71                           struct ulp_rte_hdr_bitmap *hdr_bitmap,
72                           struct ulp_rte_hdr_field  *hdr_field,
73                           struct ulp_rte_act_bitmap *act_bitmap,
74                           uint32_t                  *class_id)
75 {
76         struct bnxt_ulp_header_match_info       *sel_hdr_match;
77         uint32_t                                hdr_num, idx, jdx;
78         uint32_t                                match = 0;
79         struct ulp_rte_hdr_bitmap               hdr_bitmap_masked;
80         uint32_t                                start_idx;
81         struct ulp_rte_hdr_field                *m_field;
82         struct bnxt_ulp_matcher_field_info      *sf;
83
84         /* Select the ingress or egress template to match against */
85         if (dir == ULP_DIR_INGRESS) {
86                 sel_hdr_match = ulp_ingress_hdr_match_list;
87                 hdr_num = BNXT_ULP_INGRESS_HDR_MATCH_SZ;
88         } else {
89                 sel_hdr_match = ulp_egress_hdr_match_list;
90                 hdr_num = BNXT_ULP_EGRESS_HDR_MATCH_SZ;
91         }
92
93         /* Remove the hdr bit maps that are internal or computed */
94         ulp_matcher_hdr_fields_normalize(hdr_bitmap, &hdr_bitmap_masked);
95
96         /* Loop through the list of class templates to find the match */
97         for (idx = 0; idx < hdr_num; idx++, sel_hdr_match++) {
98                 if (ULP_BITSET_CMP(&sel_hdr_match->hdr_bitmap,
99                                    &hdr_bitmap_masked)) {
100                         /* no match found */
101                         BNXT_TF_DBG(DEBUG, "Pattern Match failed template=%d\n",
102                                     idx);
103                         continue;
104                 }
105                 match = ULP_BITMAP_ISSET(act_bitmap->bits,
106                                          BNXT_ULP_ACTION_BIT_VNIC);
107                 if (match != sel_hdr_match->act_vnic) {
108                         /* no match found */
109                         BNXT_TF_DBG(DEBUG, "Vnic Match failed template=%d\n",
110                                     idx);
111                         continue;
112                 } else {
113                         match = 1;
114                 }
115
116                 /* Found a matching hdr bitmap, match the fields next */
117                 start_idx = sel_hdr_match->start_idx;
118                 for (jdx = 0; jdx < sel_hdr_match->num_entries; jdx++) {
119                         m_field = &hdr_field[jdx + BNXT_ULP_HDR_FIELD_LAST - 1];
120                         sf = &ulp_field_match[start_idx + jdx];
121                         switch (sf->mask_opcode) {
122                         case BNXT_ULP_FMF_MASK_ANY:
123                                 match &= ulp_field_mask_is_zero(m_field->mask,
124                                                                 m_field->size);
125                                 break;
126                         case BNXT_ULP_FMF_MASK_EXACT:
127                                 match &= ulp_field_mask_is_ones(m_field->mask,
128                                                                 m_field->size);
129                                 break;
130                         case BNXT_ULP_FMF_MASK_WILDCARD:
131                                 match &= ulp_field_mask_notzero(m_field->mask,
132                                                                 m_field->size);
133                                 break;
134                         case BNXT_ULP_FMF_MASK_IGNORE:
135                         default:
136                                 break;
137                         }
138                         if (!match)
139                                 break;
140                 }
141                 if (match) {
142                         BNXT_TF_DBG(DEBUG,
143                                     "Found matching pattern template %d\n",
144                                     sel_hdr_match->class_tmpl_id);
145                         *class_id = sel_hdr_match->class_tmpl_id;
146                         return BNXT_TF_RC_SUCCESS;
147                 }
148         }
149         BNXT_TF_DBG(DEBUG, "Did not find any matching template\n");
150         *class_id = 0;
151         return BNXT_TF_RC_ERROR;
152 }