1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2014-2018 Broadcom
8 #include <rte_byteorder.h>
10 #include <rte_malloc.h>
12 #include <rte_flow_driver.h>
13 #include <rte_tailq.h>
16 #include "bnxt_filter.h"
17 #include "bnxt_hwrm.h"
18 #include "bnxt_vnic.h"
19 #include "hsi_struct_def_dpdk.h"
25 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
27 struct bnxt_filter_info *filter;
29 /* Find the 1st unused filter from the free_filter_list pool*/
30 filter = STAILQ_FIRST(&bp->free_filter_list);
32 PMD_DRV_LOG(ERR, "No more free filter resources\n");
35 STAILQ_REMOVE_HEAD(&bp->free_filter_list, next);
37 filter->mac_index = INVALID_MAC_INDEX;
38 /* Default to L2 MAC Addr filter */
39 filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
40 filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
41 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
42 memcpy(filter->l2_addr, bp->mac_addr, RTE_ETHER_ADDR_LEN);
43 memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
44 /* bump up the reference count of filter */
49 struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
51 struct bnxt_filter_info *filter;
53 filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
55 PMD_DRV_LOG(ERR, "Failed to alloc memory for VF %hu filters\n",
60 filter->fw_l2_filter_id = UINT64_MAX;
61 STAILQ_INSERT_TAIL(&bp->pf.vf_info[vf].filter, filter, next);
65 static void bnxt_init_filters(struct bnxt *bp)
67 struct bnxt_filter_info *filter;
70 max_filters = bp->max_l2_ctx;
71 STAILQ_INIT(&bp->free_filter_list);
72 for (i = 0; i < max_filters; i++) {
73 filter = &bp->filter_info[i];
74 filter->fw_l2_filter_id = UINT64_MAX;
75 filter->fw_em_filter_id = UINT64_MAX;
76 filter->fw_ntuple_filter_id = UINT64_MAX;
77 STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
81 void bnxt_free_all_filters(struct bnxt *bp)
83 struct bnxt_vnic_info *vnic;
84 struct bnxt_filter_info *filter, *temp_filter;
87 for (i = 0; i < bp->nr_vnics; i++) {
88 vnic = &bp->vnic_info[i];
89 filter = STAILQ_FIRST(&vnic->filter);
91 temp_filter = STAILQ_NEXT(filter, next);
92 STAILQ_REMOVE(&vnic->filter, filter,
93 bnxt_filter_info, next);
94 STAILQ_INSERT_TAIL(&bp->free_filter_list,
98 STAILQ_INIT(&vnic->filter);
101 for (i = 0; i < bp->pf.max_vfs; i++) {
102 STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
103 bnxt_hwrm_clear_l2_filter(bp, filter);
108 void bnxt_free_filter_mem(struct bnxt *bp)
110 struct bnxt_filter_info *filter;
111 uint16_t max_filters, i;
114 if (bp->filter_info == NULL)
117 /* Ensure that all filters are freed */
118 max_filters = bp->max_l2_ctx;
119 for (i = 0; i < max_filters; i++) {
120 filter = &bp->filter_info[i];
121 if (filter->fw_ntuple_filter_id != ((uint64_t)-1) &&
122 filter->filter_type == HWRM_CFA_NTUPLE_FILTER) {
123 /* Call HWRM to try to free filter again */
124 rc = bnxt_hwrm_clear_ntuple_filter(bp, filter);
127 "Cannot free ntuple filter: %d\n",
130 filter->fw_ntuple_filter_id = UINT64_MAX;
132 if (filter->fw_l2_filter_id != ((uint64_t)-1) &&
133 filter->filter_type == HWRM_CFA_L2_FILTER) {
134 PMD_DRV_LOG(DEBUG, "L2 filter is not free\n");
135 /* Call HWRM to try to free filter again */
136 rc = bnxt_hwrm_clear_l2_filter(bp, filter);
139 "Cannot free L2 filter: %d\n",
142 filter->fw_l2_filter_id = UINT64_MAX;
145 STAILQ_INIT(&bp->free_filter_list);
147 rte_free(bp->filter_info);
148 bp->filter_info = NULL;
150 for (i = 0; i < bp->pf.max_vfs; i++) {
151 STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
153 STAILQ_REMOVE(&bp->pf.vf_info[i].filter, filter,
154 bnxt_filter_info, next);
159 int bnxt_alloc_filter_mem(struct bnxt *bp)
161 struct bnxt_filter_info *filter_mem;
162 uint16_t max_filters;
164 max_filters = bp->max_l2_ctx;
165 /* Allocate memory for VNIC pool and filter pool */
166 filter_mem = rte_zmalloc("bnxt_filter_info",
167 max_filters * sizeof(struct bnxt_filter_info),
169 if (filter_mem == NULL) {
170 PMD_DRV_LOG(ERR, "Failed to alloc memory for %d filters",
174 bp->filter_info = filter_mem;
175 bnxt_init_filters(bp);
179 struct bnxt_filter_info *bnxt_get_unused_filter(struct bnxt *bp)
181 struct bnxt_filter_info *filter;
183 /* Find the 1st unused filter from the free_filter_list pool*/
184 filter = STAILQ_FIRST(&bp->free_filter_list);
186 PMD_DRV_LOG(ERR, "No more free filter resources\n");
189 STAILQ_REMOVE_HEAD(&bp->free_filter_list, next);
194 void bnxt_free_filter(struct bnxt *bp, struct bnxt_filter_info *filter)
196 memset(filter, 0, sizeof(*filter));
197 filter->mac_index = INVALID_MAC_INDEX;
198 filter->fw_l2_filter_id = UINT64_MAX;
199 filter->fw_ntuple_filter_id = UINT64_MAX;
200 filter->fw_em_filter_id = UINT64_MAX;
201 STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);