4 * Copyright(c) 2014-2015 Broadcom Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
36 #include <rte_memzone.h>
37 #include <rte_malloc.h>
40 #include "bnxt_vnic.h"
41 #include "hsi_struct_def_dpdk.h"
47 static void prandom_bytes(void *dest_ptr
, size_t len
)
49 char *dest
= (char *)dest_ptr
;
59 memcpy(dest
, &rb
, len
);
66 void bnxt_init_vnics(struct bnxt
*bp
)
68 struct bnxt_vnic_info
*vnic
;
73 struct bnxt_pf_info
*pf
= &bp
->pf
;
75 max_vnics
= pf
->max_vnics
;
77 struct bnxt_vf_info
*vf
= &bp
->vf
;
79 max_vnics
= vf
->max_vnics
;
81 STAILQ_INIT(&bp
->free_vnic_list
);
82 for (i
= 0; i
< max_vnics
; i
++) {
83 vnic
= &bp
->vnic_info
[i
];
84 vnic
->fw_vnic_id
= (uint16_t)HWRM_NA_SIGNATURE
;
85 vnic
->fw_rss_cos_lb_ctx
= (uint16_t)HWRM_NA_SIGNATURE
;
86 vnic
->ctx_is_rss_cos_lb
= HW_CONTEXT_NONE
;
88 for (j
= 0; j
< MAX_QUEUES_PER_VNIC
; j
++)
89 vnic
->fw_grp_ids
[j
] = (uint16_t)HWRM_NA_SIGNATURE
;
91 prandom_bytes(vnic
->rss_hash_key
, HW_HASH_KEY_SIZE
);
92 STAILQ_INIT(&vnic
->filter
);
93 STAILQ_INSERT_TAIL(&bp
->free_vnic_list
, vnic
, next
);
95 for (i
= 0; i
< MAX_FF_POOLS
; i
++)
96 STAILQ_INIT(&bp
->ff_pool
[i
]);
99 int bnxt_free_vnic(struct bnxt
*bp
, struct bnxt_vnic_info
*vnic
,
102 struct bnxt_vnic_info
*temp
;
104 temp
= STAILQ_FIRST(&bp
->ff_pool
[pool
]);
107 STAILQ_REMOVE(&bp
->ff_pool
[pool
], vnic
,
108 bnxt_vnic_info
, next
);
109 vnic
->fw_vnic_id
= (uint16_t)HWRM_NA_SIGNATURE
;
110 STAILQ_INSERT_TAIL(&bp
->free_vnic_list
, vnic
,
114 temp
= STAILQ_NEXT(temp
, next
);
116 RTE_LOG(ERR
, PMD
, "VNIC %p is not found in pool[%d]\n", vnic
, pool
);
120 struct bnxt_vnic_info
*bnxt_alloc_vnic(struct bnxt
*bp
)
122 struct bnxt_vnic_info
*vnic
;
124 /* Find the 1st unused vnic from the free_vnic_list pool*/
125 vnic
= STAILQ_FIRST(&bp
->free_vnic_list
);
127 RTE_LOG(ERR
, PMD
, "No more free VNIC resources\n");
130 STAILQ_REMOVE_HEAD(&bp
->free_vnic_list
, next
);
134 void bnxt_free_all_vnics(struct bnxt
*bp
)
136 struct bnxt_vnic_info
*temp
, *next
;
139 for (i
= 0; i
< MAX_FF_POOLS
; i
++) {
140 temp
= STAILQ_FIRST(&bp
->ff_pool
[i
]);
142 next
= STAILQ_NEXT(temp
, next
);
143 STAILQ_REMOVE(&bp
->ff_pool
[i
], temp
, bnxt_vnic_info
,
145 STAILQ_INSERT_TAIL(&bp
->free_vnic_list
, temp
, next
);
151 void bnxt_free_vnic_attributes(struct bnxt
*bp
)
153 struct bnxt_vnic_info
*vnic
;
155 STAILQ_FOREACH(vnic
, &bp
->free_vnic_list
, next
) {
156 if (vnic
->rss_table
) {
157 /* 'Unreserve' the rss_table */
160 vnic
->rss_table
= NULL
;
163 if (vnic
->rss_hash_key
) {
164 /* 'Unreserve' the rss_hash_key */
167 vnic
->rss_hash_key
= NULL
;
172 int bnxt_alloc_vnic_attributes(struct bnxt
*bp
)
174 struct bnxt_vnic_info
*vnic
;
175 struct rte_pci_device
*pdev
= bp
->pdev
;
176 const struct rte_memzone
*mz
;
177 char mz_name
[RTE_MEMZONE_NAMESIZE
];
178 uint32_t entry_length
= RTE_CACHE_LINE_ROUNDUP(
179 HW_HASH_INDEX_SIZE
* sizeof(*vnic
->rss_table
) +
185 struct bnxt_pf_info
*pf
= &bp
->pf
;
187 max_vnics
= pf
->max_vnics
;
189 struct bnxt_vf_info
*vf
= &bp
->vf
;
191 max_vnics
= vf
->max_vnics
;
193 snprintf(mz_name
, RTE_MEMZONE_NAMESIZE
,
194 "bnxt_%04x:%02x:%02x:%02x_vnicattr", pdev
->addr
.domain
,
195 pdev
->addr
.bus
, pdev
->addr
.devid
, pdev
->addr
.function
);
196 mz_name
[RTE_MEMZONE_NAMESIZE
- 1] = 0;
197 mz
= rte_memzone_lookup(mz_name
);
199 mz
= rte_memzone_reserve(mz_name
,
200 entry_length
* max_vnics
,
203 RTE_MEMZONE_SIZE_HINT_ONLY
);
208 for (i
= 0; i
< max_vnics
; i
++) {
209 vnic
= &bp
->vnic_info
[i
];
211 /* Allocate rss table and hash key */
213 (void *)((char *)mz
->addr
+ (entry_length
* i
));
214 memset(vnic
->rss_table
, -1, entry_length
);
216 vnic
->rss_table_dma_addr
= mz
->phys_addr
+ (entry_length
* i
);
217 vnic
->rss_hash_key
= (void *)((char *)vnic
->rss_table
+
218 HW_HASH_INDEX_SIZE
* sizeof(*vnic
->rss_table
));
220 vnic
->rss_hash_key_dma_addr
= vnic
->rss_table_dma_addr
+
221 HW_HASH_INDEX_SIZE
* sizeof(*vnic
->rss_table
);
227 void bnxt_free_vnic_mem(struct bnxt
*bp
)
229 struct bnxt_vnic_info
*vnic
;
230 uint16_t max_vnics
, i
;
232 if (bp
->vnic_info
== NULL
)
236 struct bnxt_pf_info
*pf
= &bp
->pf
;
238 max_vnics
= pf
->max_vnics
;
240 struct bnxt_vf_info
*vf
= &bp
->vf
;
242 max_vnics
= vf
->max_vnics
;
244 for (i
= 0; i
< max_vnics
; i
++) {
245 vnic
= &bp
->vnic_info
[i
];
246 if (vnic
->fw_vnic_id
!= (uint16_t)HWRM_NA_SIGNATURE
) {
247 RTE_LOG(ERR
, PMD
, "VNIC is not freed yet!\n");
248 /* TODO Call HWRM to free VNIC */
252 rte_free(bp
->vnic_info
);
253 bp
->vnic_info
= NULL
;
256 int bnxt_alloc_vnic_mem(struct bnxt
*bp
)
258 struct bnxt_vnic_info
*vnic_mem
;
262 struct bnxt_pf_info
*pf
= &bp
->pf
;
264 max_vnics
= pf
->max_vnics
;
266 struct bnxt_vf_info
*vf
= &bp
->vf
;
268 max_vnics
= vf
->max_vnics
;
270 /* Allocate memory for VNIC pool and filter pool */
271 vnic_mem
= rte_zmalloc("bnxt_vnic_info",
272 max_vnics
* sizeof(struct bnxt_vnic_info
), 0);
273 if (vnic_mem
== NULL
) {
274 RTE_LOG(ERR
, PMD
, "Failed to alloc memory for %d VNICs",
278 bp
->vnic_info
= vnic_mem
;