bnxt_filter.c revision 6b3e017e
1/*-
2 *   BSD LICENSE
3 *
4 *   Copyright(c) Broadcom Limited.
5 *   All rights reserved.
6 *
7 *   Redistribution and use in source and binary forms, with or without
8 *   modification, are permitted provided that the following conditions
9 *   are met:
10 *
11 *     * Redistributions of source code must retain the above copyright
12 *       notice, this list of conditions and the following disclaimer.
13 *     * Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *     * Neither the name of Broadcom Corporation nor the names of its
18 *       contributors may be used to endorse or promote products derived
19 *       from this software without specific prior written permission.
20 *
21 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/queue.h>
35
36#include <rte_log.h>
37#include <rte_malloc.h>
38
39#include "bnxt.h"
40#include "bnxt_filter.h"
41#include "bnxt_hwrm.h"
42#include "bnxt_vnic.h"
43#include "hsi_struct_def_dpdk.h"
44
45/*
46 * Filter Functions
47 */
48
49struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
50{
51	struct bnxt_filter_info *filter;
52
53	/* Find the 1st unused filter from the free_filter_list pool*/
54	filter = STAILQ_FIRST(&bp->free_filter_list);
55	if (!filter) {
56		RTE_LOG(ERR, PMD, "No more free filter resources\n");
57		return NULL;
58	}
59	STAILQ_REMOVE_HEAD(&bp->free_filter_list, next);
60
61	/* Default to L2 MAC Addr filter */
62	filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
63	filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
64			HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
65	memcpy(filter->l2_addr, bp->eth_dev->data->mac_addrs->addr_bytes,
66	       ETHER_ADDR_LEN);
67	memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
68	return filter;
69}
70
71void bnxt_init_filters(struct bnxt *bp)
72{
73	struct bnxt_filter_info *filter;
74	int i, max_filters;
75
76	if (BNXT_PF(bp)) {
77		struct bnxt_pf_info *pf = &bp->pf;
78
79		max_filters = pf->max_l2_ctx;
80	} else {
81		struct bnxt_vf_info *vf = &bp->vf;
82
83		max_filters = vf->max_l2_ctx;
84	}
85	STAILQ_INIT(&bp->free_filter_list);
86	for (i = 0; i < max_filters; i++) {
87		filter = &bp->filter_info[i];
88		filter->fw_l2_filter_id = -1;
89		STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
90	}
91}
92
93void bnxt_free_all_filters(struct bnxt *bp)
94{
95	struct bnxt_vnic_info *vnic;
96	struct bnxt_filter_info *filter, *temp_filter;
97	int i;
98
99	for (i = 0; i < MAX_FF_POOLS; i++) {
100		STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
101			filter = STAILQ_FIRST(&vnic->filter);
102			while (filter) {
103				temp_filter = STAILQ_NEXT(filter, next);
104				STAILQ_REMOVE(&vnic->filter, filter,
105					      bnxt_filter_info, next);
106				STAILQ_INSERT_TAIL(&bp->free_filter_list,
107						   filter, next);
108				filter = temp_filter;
109			}
110			STAILQ_INIT(&vnic->filter);
111		}
112	}
113}
114
115void bnxt_free_filter_mem(struct bnxt *bp)
116{
117	struct bnxt_filter_info *filter;
118	uint16_t max_filters, i;
119	int rc = 0;
120
121	if (bp->filter_info == NULL)
122		return;
123
124	/* Ensure that all filters are freed */
125	if (BNXT_PF(bp)) {
126		struct bnxt_pf_info *pf = &bp->pf;
127
128		max_filters = pf->max_l2_ctx;
129	} else {
130		struct bnxt_vf_info *vf = &bp->vf;
131
132		max_filters = vf->max_l2_ctx;
133	}
134	for (i = 0; i < max_filters; i++) {
135		filter = &bp->filter_info[i];
136		if (filter->fw_l2_filter_id != ((uint64_t)-1)) {
137			RTE_LOG(ERR, PMD, "HWRM filter is not freed??\n");
138			/* Call HWRM to try to free filter again */
139			rc = bnxt_hwrm_clear_filter(bp, filter);
140			if (rc)
141				RTE_LOG(ERR, PMD,
142				       "HWRM filter cannot be freed rc = %d\n",
143					rc);
144		}
145		filter->fw_l2_filter_id = -1;
146	}
147	STAILQ_INIT(&bp->free_filter_list);
148
149	rte_free(bp->filter_info);
150	bp->filter_info = NULL;
151}
152
153int bnxt_alloc_filter_mem(struct bnxt *bp)
154{
155	struct bnxt_filter_info *filter_mem;
156	uint16_t max_filters;
157
158	if (BNXT_PF(bp)) {
159		struct bnxt_pf_info *pf = &bp->pf;
160
161		max_filters = pf->max_l2_ctx;
162	} else {
163		struct bnxt_vf_info *vf = &bp->vf;
164
165		max_filters = vf->max_l2_ctx;
166	}
167	/* Allocate memory for VNIC pool and filter pool */
168	filter_mem = rte_zmalloc("bnxt_filter_info",
169				 max_filters * sizeof(struct bnxt_filter_info),
170				 0);
171	if (filter_mem == NULL) {
172		RTE_LOG(ERR, PMD, "Failed to alloc memory for %d filters",
173			max_filters);
174		return -ENOMEM;
175	}
176	bp->filter_info = filter_mem;
177	return 0;
178}
179