Imported Upstream version 16.11
[deb_dpdk.git] / drivers / net / bnxt / bnxt_filter.c
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
49 struct 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
71 void 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
93 void 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
115 void 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
153 int 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 }