net/bnxt: use hashing for flow template match
[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 calculate the class matcher hash */
10 static uint32_t
11 ulp_matcher_class_hash_calculate(uint64_t hi_sig, uint64_t lo_sig)
12 {
13         uint64_t hash;
14
15         hi_sig |= ((hi_sig % BNXT_ULP_CLASS_HID_HIGH_PRIME) <<
16                    BNXT_ULP_CLASS_HID_SHFTL);
17         lo_sig |= ((lo_sig % BNXT_ULP_CLASS_HID_LOW_PRIME) <<
18                    (BNXT_ULP_CLASS_HID_SHFTL + 2));
19         hash = hi_sig ^ lo_sig;
20         hash = (hash >> BNXT_ULP_CLASS_HID_SHFTR) & BNXT_ULP_CLASS_HID_MASK;
21         return (uint32_t)hash;
22 }
23
24 /* Utility function to calculate the action matcher hash */
25 static uint32_t
26 ulp_matcher_action_hash_calculate(uint64_t hi_sig)
27 {
28         uint64_t hash;
29
30         hi_sig |= ((hi_sig % BNXT_ULP_ACT_HID_HIGH_PRIME) <<
31                    BNXT_ULP_ACT_HID_SHFTL);
32         hash = hi_sig;
33         hash = (hash >> BNXT_ULP_ACT_HID_SHFTR) & BNXT_ULP_ACT_HID_MASK;
34         return (uint32_t)hash;
35 }
36
37 /* Utility function to mask the computed and internal proto headers. */
38 static void
39 ulp_matcher_hdr_fields_normalize(struct ulp_rte_hdr_bitmap *hdr1,
40                                  struct ulp_rte_hdr_bitmap *hdr2)
41 {
42         /* copy the contents first */
43         rte_memcpy(hdr2, hdr1, sizeof(struct ulp_rte_hdr_bitmap));
44
45         /* reset the computed fields */
46         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_SVIF);
47         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_OO_VLAN);
48         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_OI_VLAN);
49         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_IO_VLAN);
50         ULP_BITMAP_RESET(hdr2->bits, BNXT_ULP_HDR_BIT_II_VLAN);
51 }
52
53 /*
54  * Function to handle the matching of RTE Flows and validating
55  * the pattern masks against the flow templates.
56  */
57 int32_t
58 ulp_matcher_pattern_match(struct ulp_rte_parser_params *params,
59                           uint32_t *class_id)
60 {
61         struct ulp_rte_hdr_bitmap hdr_bitmap_masked;
62         struct bnxt_ulp_class_match_info *class_match;
63         uint32_t class_hid;
64         uint8_t vf_to_vf;
65         uint16_t tmpl_id;
66
67         /* Remove the hdr bit maps that are internal or computed */
68         ulp_matcher_hdr_fields_normalize(&params->hdr_bitmap,
69                                          &hdr_bitmap_masked);
70
71         /* determine vf to vf flow */
72         if (params->dir == ULP_DIR_EGRESS &&
73             ULP_BITMAP_ISSET(params->act_bitmap.bits,
74                              BNXT_ULP_ACTION_BIT_VNIC)) {
75                 vf_to_vf = 1;
76         } else {
77                 vf_to_vf = 0;
78         }
79
80         /* calculate the hash of the given flow */
81         class_hid = ulp_matcher_class_hash_calculate(hdr_bitmap_masked.bits,
82                                                      params->fld_bitmap.bits);
83
84         /* validate the calculate hash values */
85         if (class_hid >= BNXT_ULP_CLASS_SIG_TBL_MAX_SZ)
86                 goto error;
87         tmpl_id = ulp_class_sig_tbl[class_hid];
88         if (!tmpl_id)
89                 goto error;
90
91         class_match = &ulp_class_match_list[tmpl_id];
92         if (ULP_BITMAP_CMP(&hdr_bitmap_masked, &class_match->hdr_sig)) {
93                 BNXT_TF_DBG(DEBUG, "Proto Header does not match\n");
94                 goto error;
95         }
96         if (ULP_BITMAP_CMP(&params->fld_bitmap, &class_match->field_sig)) {
97                 BNXT_TF_DBG(DEBUG, "Field signature does not match\n");
98                 goto error;
99         }
100         if (vf_to_vf != class_match->act_vnic) {
101                 BNXT_TF_DBG(DEBUG, "Vnic Match failed\n");
102                 goto error;
103         }
104         BNXT_TF_DBG(DEBUG, "Found matching pattern template %d\n",
105                     class_match->class_tid);
106         *class_id = class_match->class_tid;
107         return BNXT_TF_RC_SUCCESS;
108
109 error:
110         BNXT_TF_DBG(DEBUG, "Did not find any matching template\n");
111         *class_id = 0;
112         return BNXT_TF_RC_ERROR;
113 }
114
115 /*
116  * Function to handle the matching of RTE Flows and validating
117  * the action against the flow templates.
118  */
119 int32_t
120 ulp_matcher_action_match(struct ulp_rte_parser_params *params,
121                          uint32_t *act_id)
122 {
123         uint32_t act_hid;
124         uint16_t tmpl_id;
125         struct bnxt_ulp_act_match_info *act_match;
126
127         /* calculate the hash of the given flow action */
128         act_hid = ulp_matcher_action_hash_calculate(params->act_bitmap.bits);
129
130         /* validate the calculate hash values */
131         if (act_hid >= BNXT_ULP_ACT_SIG_TBL_MAX_SZ)
132                 goto error;
133         tmpl_id = ulp_act_sig_tbl[act_hid];
134         if (!tmpl_id)
135                 goto error;
136
137         act_match = &ulp_act_match_list[tmpl_id];
138         if (ULP_BITMAP_CMP(&params->act_bitmap, &act_match->act_sig)) {
139                 BNXT_TF_DBG(DEBUG, "Action Header does not match\n");
140                 goto error;
141         }
142         *act_id = act_match->act_tid;
143         BNXT_TF_DBG(DEBUG, "Found matching action template %u\n", *act_id);
144         return BNXT_TF_RC_SUCCESS;
145
146 error:
147         BNXT_TF_DBG(DEBUG, "Did not find any matching action template\n");
148         *act_id = 0;
149         return BNXT_TF_RC_ERROR;
150 }