Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2014-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <sys/queue.h>
7 : :
8 : : #include <rte_byteorder.h>
9 : : #include <rte_log.h>
10 : : #include <rte_malloc.h>
11 : : #include <rte_flow.h>
12 : : #include <rte_flow_driver.h>
13 : : #include <rte_tailq.h>
14 : :
15 : : #include "bnxt.h"
16 : : #include "bnxt_filter.h"
17 : : #include "bnxt_hwrm.h"
18 : : #include "bnxt_vnic.h"
19 : : #include "hsi_struct_def_dpdk.h"
20 : :
21 : : /*
22 : : * Filter Functions
23 : : */
24 : :
25 : 0 : struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
26 : : {
27 : : struct bnxt_filter_info *filter;
28 : :
29 : 0 : filter = bnxt_get_unused_filter(bp);
30 [ # # ]: 0 : if (!filter) {
31 : 0 : PMD_DRV_LOG(ERR, "No more free filter resources\n");
32 : 0 : return NULL;
33 : : }
34 : :
35 : 0 : filter->mac_index = INVALID_MAC_INDEX;
36 : : /* Default to L2 MAC Addr filter */
37 : 0 : filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
38 : 0 : filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
39 : : HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
40 : 0 : memcpy(filter->l2_addr, bp->mac_addr, RTE_ETHER_ADDR_LEN);
41 : 0 : memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
42 : :
43 : 0 : return filter;
44 : : }
45 : :
46 : 0 : struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
47 : : {
48 : : struct bnxt_filter_info *filter;
49 : :
50 : 0 : filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
51 [ # # ]: 0 : if (!filter) {
52 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc memory for VF %hu filters\n",
53 : : vf);
54 : 0 : return NULL;
55 : : }
56 : :
57 : 0 : filter->fw_l2_filter_id = UINT64_MAX;
58 : 0 : STAILQ_INSERT_TAIL(&bp->pf->vf_info[vf].filter, filter, next);
59 : 0 : return filter;
60 : : }
61 : :
62 : : static void bnxt_init_filters(struct bnxt *bp)
63 : : {
64 : : struct bnxt_filter_info *filter;
65 : : int i, max_filters;
66 : :
67 : 0 : max_filters = bp->max_l2_ctx;
68 : 0 : STAILQ_INIT(&bp->free_filter_list);
69 [ # # ]: 0 : for (i = 0; i < max_filters; i++) {
70 : 0 : filter = &bp->filter_info[i];
71 : 0 : filter->fw_l2_filter_id = UINT64_MAX;
72 : 0 : filter->fw_em_filter_id = UINT64_MAX;
73 : 0 : filter->fw_ntuple_filter_id = UINT64_MAX;
74 : 0 : STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
75 : : }
76 : : }
77 : :
78 : 0 : void bnxt_free_all_filters(struct bnxt *bp)
79 : : {
80 : : struct bnxt_vnic_info *vnic;
81 : : struct bnxt_filter_info *filter, *temp_filter;
82 : : unsigned int i;
83 : :
84 [ # # ]: 0 : for (i = 0; i < bp->pf->max_vfs; i++) {
85 [ # # ]: 0 : STAILQ_FOREACH(filter, &bp->pf->vf_info[i].filter, next) {
86 : 0 : bnxt_hwrm_clear_l2_filter(bp, filter);
87 : : }
88 : : }
89 : :
90 [ # # ]: 0 : if (bp->vnic_info == NULL)
91 : : return;
92 : :
93 [ # # ]: 0 : for (i = 0; i < bp->nr_vnics; i++) {
94 : 0 : vnic = &bp->vnic_info[i];
95 : 0 : filter = STAILQ_FIRST(&vnic->filter);
96 [ # # ]: 0 : while (filter) {
97 : 0 : temp_filter = STAILQ_NEXT(filter, next);
98 [ # # # # : 0 : STAILQ_REMOVE(&vnic->filter, filter,
# # # # ]
99 : : bnxt_filter_info, next);
100 : 0 : STAILQ_INSERT_TAIL(&bp->free_filter_list,
101 : : filter, next);
102 [ # # ]: 0 : if (filter->vnic)
103 : 0 : filter->vnic = NULL;
104 : : filter = temp_filter;
105 : : }
106 : 0 : STAILQ_INIT(&vnic->filter);
107 : : }
108 : :
109 : : }
110 : :
111 : 0 : void bnxt_free_filter_mem(struct bnxt *bp)
112 : : {
113 : : struct bnxt_filter_info *filter;
114 : : uint16_t max_filters, i;
115 : : int rc = 0;
116 : :
117 [ # # ]: 0 : if (bp->filter_info == NULL)
118 : : return;
119 : :
120 : : /* Ensure that all filters are freed */
121 : 0 : max_filters = bp->max_l2_ctx;
122 [ # # ]: 0 : for (i = 0; i < max_filters; i++) {
123 : 0 : filter = &bp->filter_info[i];
124 [ # # ]: 0 : if (filter->fw_ntuple_filter_id != ((uint64_t)-1) &&
125 [ # # ]: 0 : filter->filter_type == HWRM_CFA_NTUPLE_FILTER) {
126 : : /* Call HWRM to try to free filter again */
127 : 0 : rc = bnxt_hwrm_clear_ntuple_filter(bp, filter);
128 [ # # ]: 0 : if (rc)
129 : 0 : PMD_DRV_LOG(ERR,
130 : : "Cannot free ntuple filter: %d\n",
131 : : rc);
132 : : }
133 : 0 : filter->fw_ntuple_filter_id = UINT64_MAX;
134 : :
135 [ # # ]: 0 : if (filter->fw_l2_filter_id != ((uint64_t)-1) &&
136 [ # # ]: 0 : filter->filter_type == HWRM_CFA_L2_FILTER) {
137 : 0 : PMD_DRV_LOG(DEBUG, "L2 filter is not free\n");
138 : : /* Call HWRM to try to free filter again */
139 : 0 : rc = bnxt_hwrm_clear_l2_filter(bp, filter);
140 [ # # ]: 0 : if (rc)
141 : 0 : PMD_DRV_LOG(ERR,
142 : : "Cannot free L2 filter: %d\n",
143 : : rc);
144 : : }
145 : 0 : filter->fw_l2_filter_id = UINT64_MAX;
146 : :
147 : : }
148 : 0 : STAILQ_INIT(&bp->free_filter_list);
149 : :
150 : 0 : rte_free(bp->filter_info);
151 : 0 : bp->filter_info = NULL;
152 : :
153 [ # # ]: 0 : for (i = 0; i < bp->pf->max_vfs; i++) {
154 [ # # ]: 0 : STAILQ_FOREACH(filter, &bp->pf->vf_info[i].filter, next) {
155 : 0 : rte_free(filter);
156 [ # # # # : 0 : STAILQ_REMOVE(&bp->pf->vf_info[i].filter, filter,
# # # # ]
157 : : bnxt_filter_info, next);
158 : : }
159 : : }
160 : : }
161 : :
162 : 0 : int bnxt_alloc_filter_mem(struct bnxt *bp)
163 : : {
164 : : struct bnxt_filter_info *filter_mem;
165 : : uint16_t max_filters;
166 : :
167 : 0 : max_filters = bp->max_l2_ctx;
168 : : /* Allocate memory for VNIC pool and filter pool */
169 : 0 : filter_mem = rte_zmalloc("bnxt_filter_info",
170 : : max_filters * sizeof(struct bnxt_filter_info),
171 : : 0);
172 [ # # ]: 0 : if (filter_mem == NULL) {
173 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc memory for %d filters",
174 : : max_filters);
175 : 0 : return -ENOMEM;
176 : : }
177 : 0 : bp->filter_info = filter_mem;
178 : : bnxt_init_filters(bp);
179 : : return 0;
180 : : }
181 : :
182 : 0 : struct bnxt_filter_info *bnxt_get_unused_filter(struct bnxt *bp)
183 : : {
184 : : struct bnxt_filter_info *filter;
185 : :
186 : : /* Find the 1st unused filter from the free_filter_list pool*/
187 : 0 : filter = STAILQ_FIRST(&bp->free_filter_list);
188 [ # # ]: 0 : if (!filter) {
189 : 0 : PMD_DRV_LOG(ERR, "No more free filter resources\n");
190 : 0 : return NULL;
191 : : }
192 [ # # ]: 0 : STAILQ_REMOVE_HEAD(&bp->free_filter_list, next);
193 : :
194 : : return filter;
195 : : }
196 : :
197 : 0 : void bnxt_free_filter(struct bnxt *bp, struct bnxt_filter_info *filter)
198 : : {
199 : : memset(filter, 0, sizeof(*filter));
200 : 0 : filter->mac_index = INVALID_MAC_INDEX;
201 : 0 : filter->fw_l2_filter_id = UINT64_MAX;
202 : 0 : filter->fw_ntuple_filter_id = UINT64_MAX;
203 : 0 : filter->fw_em_filter_id = UINT64_MAX;
204 : 0 : STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
205 : 0 : }
|