Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2023 Intel Corporation
3 : : */
4 : :
5 : : #include <rte_log.h>
6 : : #include "idpf_common_device.h"
7 : : #include "idpf_common_virtchnl.h"
8 : :
9 : : static void
10 : : idpf_reset_pf(struct idpf_hw *hw)
11 : : {
12 : : uint32_t reg;
13 : :
14 : 0 : reg = IDPF_READ_REG(hw, PFGEN_CTRL);
15 : 0 : IDPF_WRITE_REG(hw, PFGEN_CTRL, (reg | PFGEN_CTRL_PFSWR));
16 : : }
17 : :
18 : : #define IDPF_RESET_WAIT_CNT 100
19 : :
20 : : static int
21 : 0 : idpf_check_pf_reset_done(struct idpf_hw *hw)
22 : : {
23 : : uint32_t reg;
24 : : int i;
25 : :
26 [ # # ]: 0 : for (i = 0; i < IDPF_RESET_WAIT_CNT; i++) {
27 : 0 : reg = IDPF_READ_REG(hw, PFGEN_RSTAT);
28 [ # # # # ]: 0 : if (reg != 0xFFFFFFFF && (reg & PFGEN_RSTAT_PFR_STATE_M))
29 : : return 0;
30 : : rte_delay_ms(1000);
31 : : }
32 : :
33 : 0 : DRV_LOG(ERR, "IDPF reset timeout");
34 : 0 : return -EBUSY;
35 : : }
36 : :
37 : : static int
38 : 0 : idpf_check_vf_reset_done(struct idpf_hw *hw)
39 : : {
40 : : uint32_t reg;
41 : : int i;
42 : :
43 [ # # ]: 0 : for (i = 0; i < IDPF_RESET_WAIT_CNT; i++) {
44 : 0 : reg = IDPF_READ_REG(hw, VFGEN_RSTAT);
45 [ # # # # ]: 0 : if (reg != 0xFFFFFFFF && (reg & VFGEN_RSTAT_VFR_STATE_M))
46 : : return 0;
47 : : rte_delay_ms(1000);
48 : : }
49 : :
50 : 0 : DRV_LOG(ERR, "VF reset timeout");
51 : 0 : return -EBUSY;
52 : : }
53 : :
54 : : #define IDPF_CTLQ_NUM 2
55 : :
56 : : struct idpf_ctlq_create_info pf_ctlq_info[IDPF_CTLQ_NUM] = {
57 : : {
58 : : .type = IDPF_CTLQ_TYPE_MAILBOX_TX,
59 : : .id = IDPF_CTLQ_ID,
60 : : .len = IDPF_CTLQ_LEN,
61 : : .buf_size = IDPF_DFLT_MBX_BUF_SIZE,
62 : : .reg = {
63 : : .head = PF_FW_ATQH,
64 : : .tail = PF_FW_ATQT,
65 : : .len = PF_FW_ATQLEN,
66 : : .bah = PF_FW_ATQBAH,
67 : : .bal = PF_FW_ATQBAL,
68 : : .len_mask = PF_FW_ATQLEN_ATQLEN_M,
69 : : .len_ena_mask = PF_FW_ATQLEN_ATQENABLE_M,
70 : : .head_mask = PF_FW_ATQH_ATQH_M,
71 : : }
72 : : },
73 : : {
74 : : .type = IDPF_CTLQ_TYPE_MAILBOX_RX,
75 : : .id = IDPF_CTLQ_ID,
76 : : .len = IDPF_CTLQ_LEN,
77 : : .buf_size = IDPF_DFLT_MBX_BUF_SIZE,
78 : : .reg = {
79 : : .head = PF_FW_ARQH,
80 : : .tail = PF_FW_ARQT,
81 : : .len = PF_FW_ARQLEN,
82 : : .bah = PF_FW_ARQBAH,
83 : : .bal = PF_FW_ARQBAL,
84 : : .len_mask = PF_FW_ARQLEN_ARQLEN_M,
85 : : .len_ena_mask = PF_FW_ARQLEN_ARQENABLE_M,
86 : : .head_mask = PF_FW_ARQH_ARQH_M,
87 : : }
88 : : }
89 : : };
90 : :
91 : : struct idpf_ctlq_create_info vf_ctlq_info[IDPF_CTLQ_NUM] = {
92 : : {
93 : : .type = IDPF_CTLQ_TYPE_MAILBOX_TX,
94 : : .id = IDPF_CTLQ_ID,
95 : : .len = IDPF_CTLQ_LEN,
96 : : .buf_size = IDPF_DFLT_MBX_BUF_SIZE,
97 : : .reg = {
98 : : .head = VF_ATQH,
99 : : .tail = VF_ATQT,
100 : : .len = VF_ATQLEN,
101 : : .bah = VF_ATQBAH,
102 : : .bal = VF_ATQBAL,
103 : : .len_mask = VF_ATQLEN_ATQLEN_M,
104 : : .len_ena_mask = VF_ATQLEN_ATQENABLE_M,
105 : : .head_mask = VF_ATQH_ATQH_M,
106 : : }
107 : : },
108 : : {
109 : : .type = IDPF_CTLQ_TYPE_MAILBOX_RX,
110 : : .id = IDPF_CTLQ_ID,
111 : : .len = IDPF_CTLQ_LEN,
112 : : .buf_size = IDPF_DFLT_MBX_BUF_SIZE,
113 : : .reg = {
114 : : .head = VF_ARQH,
115 : : .tail = VF_ARQT,
116 : : .len = VF_ARQLEN,
117 : : .bah = VF_ARQBAH,
118 : : .bal = VF_ARQBAL,
119 : : .len_mask = VF_ARQLEN_ARQLEN_M,
120 : : .len_ena_mask = VF_ARQLEN_ARQENABLE_M,
121 : : .head_mask = VF_ARQH_ARQH_M,
122 : : }
123 : : }
124 : : };
125 : :
126 : : static int
127 : 0 : idpf_init_mbx(struct idpf_hw *hw)
128 : : {
129 : : struct idpf_ctlq_info *ctlq;
130 : : int ret = 0;
131 : :
132 [ # # ]: 0 : if (hw->device_id == IDPF_DEV_ID_SRIOV)
133 : 0 : ret = idpf_ctlq_init(hw, IDPF_CTLQ_NUM, vf_ctlq_info);
134 : : else
135 : 0 : ret = idpf_ctlq_init(hw, IDPF_CTLQ_NUM, pf_ctlq_info);
136 [ # # ]: 0 : if (ret != 0)
137 : : return ret;
138 : :
139 [ # # ]: 0 : LIST_FOR_EACH_ENTRY_SAFE(ctlq, NULL, &hw->cq_list_head,
140 : : struct idpf_ctlq_info, cq_list) {
141 [ # # ]: 0 : if (ctlq->q_id == IDPF_CTLQ_ID &&
142 : : ctlq->cq_type == IDPF_CTLQ_TYPE_MAILBOX_TX)
143 : 0 : hw->asq = ctlq;
144 [ # # ]: 0 : if (ctlq->q_id == IDPF_CTLQ_ID &&
145 : : ctlq->cq_type == IDPF_CTLQ_TYPE_MAILBOX_RX)
146 : 0 : hw->arq = ctlq;
147 : : }
148 : :
149 [ # # # # ]: 0 : if (hw->asq == NULL || hw->arq == NULL) {
150 : 0 : idpf_ctlq_deinit(hw);
151 : : ret = -ENOENT;
152 : : }
153 : :
154 : : return ret;
155 : : }
156 : :
157 : : static int
158 : 0 : idpf_get_pkt_type(struct idpf_adapter *adapter)
159 : : {
160 : : struct virtchnl2_get_ptype_info *ptype_info;
161 : : uint16_t ptype_offset, i, j;
162 : : uint16_t ptype_recvd = 0;
163 : : int ret;
164 : :
165 : 0 : ret = idpf_vc_ptype_info_query(adapter);
166 [ # # ]: 0 : if (ret != 0) {
167 : 0 : DRV_LOG(ERR, "Fail to query packet type information");
168 : 0 : return ret;
169 : : }
170 : :
171 : 0 : ptype_info = rte_zmalloc("ptype_info", IDPF_DFLT_MBX_BUF_SIZE, 0);
172 [ # # ]: 0 : if (ptype_info == NULL)
173 : : return -ENOMEM;
174 : :
175 [ # # ]: 0 : while (ptype_recvd < IDPF_MAX_PKT_TYPE) {
176 : 0 : ret = idpf_vc_one_msg_read(adapter, VIRTCHNL2_OP_GET_PTYPE_INFO,
177 : : IDPF_DFLT_MBX_BUF_SIZE, (uint8_t *)ptype_info);
178 [ # # ]: 0 : if (ret != 0) {
179 : 0 : DRV_LOG(ERR, "Fail to get packet type information");
180 : 0 : goto free_ptype_info;
181 : : }
182 : :
183 : 0 : ptype_recvd += ptype_info->num_ptypes;
184 : : ptype_offset = sizeof(struct virtchnl2_get_ptype_info) -
185 : : sizeof(struct virtchnl2_ptype);
186 : :
187 [ # # ]: 0 : for (i = 0; i < rte_cpu_to_le_16(ptype_info->num_ptypes); i++) {
188 : : bool is_inner = false, is_ip = false;
189 : : struct virtchnl2_ptype *ptype;
190 : : uint32_t proto_hdr = 0;
191 : :
192 : 0 : ptype = (struct virtchnl2_ptype *)
193 : : ((uint8_t *)ptype_info + ptype_offset);
194 [ # # ]: 0 : ptype_offset += IDPF_GET_PTYPE_SIZE(ptype);
195 [ # # ]: 0 : if (ptype_offset > IDPF_DFLT_MBX_BUF_SIZE) {
196 : : ret = -EINVAL;
197 : 0 : goto free_ptype_info;
198 : : }
199 : :
200 [ # # ]: 0 : if (rte_cpu_to_le_16(ptype->ptype_id_10) == 0xFFFF)
201 : 0 : goto free_ptype_info;
202 : :
203 [ # # ]: 0 : for (j = 0; j < ptype->proto_id_count; j++) {
204 [ # # # # : 0 : switch (rte_cpu_to_le_16(ptype->proto_id[j])) {
# # # # #
# # # # #
# # # # #
# ]
205 : 0 : case VIRTCHNL2_PROTO_HDR_GRE:
206 : : case VIRTCHNL2_PROTO_HDR_VXLAN:
207 : 0 : proto_hdr &= ~RTE_PTYPE_L4_MASK;
208 : 0 : proto_hdr |= RTE_PTYPE_TUNNEL_GRENAT;
209 : : is_inner = true;
210 : 0 : break;
211 : 0 : case VIRTCHNL2_PROTO_HDR_MAC:
212 [ # # ]: 0 : if (is_inner) {
213 : 0 : proto_hdr &= ~RTE_PTYPE_INNER_L2_MASK;
214 : 0 : proto_hdr |= RTE_PTYPE_INNER_L2_ETHER;
215 : : } else {
216 : 0 : proto_hdr &= ~RTE_PTYPE_L2_MASK;
217 : 0 : proto_hdr |= RTE_PTYPE_L2_ETHER;
218 : : }
219 : : break;
220 : 0 : case VIRTCHNL2_PROTO_HDR_VLAN:
221 [ # # ]: 0 : if (is_inner) {
222 : 0 : proto_hdr &= ~RTE_PTYPE_INNER_L2_MASK;
223 : 0 : proto_hdr |= RTE_PTYPE_INNER_L2_ETHER_VLAN;
224 : : }
225 : : break;
226 : 0 : case VIRTCHNL2_PROTO_HDR_PTP:
227 : 0 : proto_hdr &= ~RTE_PTYPE_L2_MASK;
228 : 0 : proto_hdr |= RTE_PTYPE_L2_ETHER_TIMESYNC;
229 : 0 : break;
230 : 0 : case VIRTCHNL2_PROTO_HDR_LLDP:
231 : 0 : proto_hdr &= ~RTE_PTYPE_L2_MASK;
232 : 0 : proto_hdr |= RTE_PTYPE_L2_ETHER_LLDP;
233 : 0 : break;
234 : 0 : case VIRTCHNL2_PROTO_HDR_ARP:
235 : 0 : proto_hdr &= ~RTE_PTYPE_L2_MASK;
236 : 0 : proto_hdr |= RTE_PTYPE_L2_ETHER_ARP;
237 : 0 : break;
238 : 0 : case VIRTCHNL2_PROTO_HDR_PPPOE:
239 : 0 : proto_hdr &= ~RTE_PTYPE_L2_MASK;
240 : 0 : proto_hdr |= RTE_PTYPE_L2_ETHER_PPPOE;
241 : 0 : break;
242 : 0 : case VIRTCHNL2_PROTO_HDR_IPV4:
243 [ # # ]: 0 : if (!is_ip) {
244 : 0 : proto_hdr |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
245 : : is_ip = true;
246 : : } else {
247 : 0 : proto_hdr |= RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN |
248 : : RTE_PTYPE_TUNNEL_IP;
249 : : is_inner = true;
250 : : }
251 : : break;
252 : 0 : case VIRTCHNL2_PROTO_HDR_IPV6:
253 [ # # ]: 0 : if (!is_ip) {
254 : 0 : proto_hdr |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
255 : : is_ip = true;
256 : : } else {
257 : 0 : proto_hdr |= RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN |
258 : : RTE_PTYPE_TUNNEL_IP;
259 : : is_inner = true;
260 : : }
261 : : break;
262 : 0 : case VIRTCHNL2_PROTO_HDR_IPV4_FRAG:
263 : : case VIRTCHNL2_PROTO_HDR_IPV6_FRAG:
264 [ # # ]: 0 : if (is_inner)
265 : 0 : proto_hdr |= RTE_PTYPE_INNER_L4_FRAG;
266 : : else
267 : 0 : proto_hdr |= RTE_PTYPE_L4_FRAG;
268 : : break;
269 : 0 : case VIRTCHNL2_PROTO_HDR_UDP:
270 [ # # ]: 0 : if (is_inner)
271 : 0 : proto_hdr |= RTE_PTYPE_INNER_L4_UDP;
272 : : else
273 : 0 : proto_hdr |= RTE_PTYPE_L4_UDP;
274 : : break;
275 : 0 : case VIRTCHNL2_PROTO_HDR_TCP:
276 [ # # ]: 0 : if (is_inner)
277 : 0 : proto_hdr |= RTE_PTYPE_INNER_L4_TCP;
278 : : else
279 : 0 : proto_hdr |= RTE_PTYPE_L4_TCP;
280 : : break;
281 : 0 : case VIRTCHNL2_PROTO_HDR_SCTP:
282 [ # # ]: 0 : if (is_inner)
283 : 0 : proto_hdr |= RTE_PTYPE_INNER_L4_SCTP;
284 : : else
285 : 0 : proto_hdr |= RTE_PTYPE_L4_SCTP;
286 : : break;
287 : 0 : case VIRTCHNL2_PROTO_HDR_ICMP:
288 [ # # ]: 0 : if (is_inner)
289 : 0 : proto_hdr |= RTE_PTYPE_INNER_L4_ICMP;
290 : : else
291 : 0 : proto_hdr |= RTE_PTYPE_L4_ICMP;
292 : : break;
293 : 0 : case VIRTCHNL2_PROTO_HDR_ICMPV6:
294 [ # # ]: 0 : if (is_inner)
295 : 0 : proto_hdr |= RTE_PTYPE_INNER_L4_ICMP;
296 : : else
297 : 0 : proto_hdr |= RTE_PTYPE_L4_ICMP;
298 : : break;
299 : 0 : case VIRTCHNL2_PROTO_HDR_L2TPV2:
300 : : case VIRTCHNL2_PROTO_HDR_L2TPV2_CONTROL:
301 : : case VIRTCHNL2_PROTO_HDR_L2TPV3:
302 : : is_inner = true;
303 : 0 : proto_hdr |= RTE_PTYPE_TUNNEL_L2TP;
304 : 0 : break;
305 : 0 : case VIRTCHNL2_PROTO_HDR_NVGRE:
306 : : is_inner = true;
307 : 0 : proto_hdr |= RTE_PTYPE_TUNNEL_NVGRE;
308 : 0 : break;
309 : 0 : case VIRTCHNL2_PROTO_HDR_GTPC_TEID:
310 : : is_inner = true;
311 : 0 : proto_hdr |= RTE_PTYPE_TUNNEL_GTPC;
312 : 0 : break;
313 : 0 : case VIRTCHNL2_PROTO_HDR_GTPU:
314 : : case VIRTCHNL2_PROTO_HDR_GTPU_UL:
315 : : case VIRTCHNL2_PROTO_HDR_GTPU_DL:
316 : : is_inner = true;
317 : 0 : proto_hdr |= RTE_PTYPE_TUNNEL_GTPU;
318 : 0 : break;
319 : 0 : case VIRTCHNL2_PROTO_HDR_PAY:
320 : : case VIRTCHNL2_PROTO_HDR_IPV6_EH:
321 : : case VIRTCHNL2_PROTO_HDR_PRE_MAC:
322 : : case VIRTCHNL2_PROTO_HDR_POST_MAC:
323 : : case VIRTCHNL2_PROTO_HDR_ETHERTYPE:
324 : : case VIRTCHNL2_PROTO_HDR_SVLAN:
325 : : case VIRTCHNL2_PROTO_HDR_CVLAN:
326 : : case VIRTCHNL2_PROTO_HDR_MPLS:
327 : : case VIRTCHNL2_PROTO_HDR_MMPLS:
328 : : case VIRTCHNL2_PROTO_HDR_CTRL:
329 : : case VIRTCHNL2_PROTO_HDR_ECP:
330 : : case VIRTCHNL2_PROTO_HDR_EAPOL:
331 : : case VIRTCHNL2_PROTO_HDR_PPPOD:
332 : : case VIRTCHNL2_PROTO_HDR_IGMP:
333 : : case VIRTCHNL2_PROTO_HDR_AH:
334 : : case VIRTCHNL2_PROTO_HDR_ESP:
335 : : case VIRTCHNL2_PROTO_HDR_IKE:
336 : : case VIRTCHNL2_PROTO_HDR_NATT_KEEP:
337 : : case VIRTCHNL2_PROTO_HDR_GTP:
338 : : case VIRTCHNL2_PROTO_HDR_GTP_EH:
339 : : case VIRTCHNL2_PROTO_HDR_GTPCV2:
340 : : case VIRTCHNL2_PROTO_HDR_ECPRI:
341 : : case VIRTCHNL2_PROTO_HDR_VRRP:
342 : : case VIRTCHNL2_PROTO_HDR_OSPF:
343 : : case VIRTCHNL2_PROTO_HDR_TUN:
344 : : case VIRTCHNL2_PROTO_HDR_VXLAN_GPE:
345 : : case VIRTCHNL2_PROTO_HDR_GENEVE:
346 : : case VIRTCHNL2_PROTO_HDR_NSH:
347 : : case VIRTCHNL2_PROTO_HDR_QUIC:
348 : : case VIRTCHNL2_PROTO_HDR_PFCP:
349 : : case VIRTCHNL2_PROTO_HDR_PFCP_NODE:
350 : : case VIRTCHNL2_PROTO_HDR_PFCP_SESSION:
351 : : case VIRTCHNL2_PROTO_HDR_RTP:
352 : : case VIRTCHNL2_PROTO_HDR_NO_PROTO:
353 : : default:
354 : 0 : continue;
355 : : }
356 : 0 : adapter->ptype_tbl[ptype->ptype_id_10] = proto_hdr;
357 : : }
358 : : }
359 : : }
360 : :
361 : 0 : free_ptype_info:
362 : 0 : rte_free(ptype_info);
363 : : clear_cmd(adapter);
364 : 0 : return ret;
365 : : }
366 : :
367 : : int
368 : 0 : idpf_adapter_init(struct idpf_adapter *adapter)
369 : : {
370 : 0 : struct idpf_hw *hw = &adapter->hw;
371 : : int ret;
372 : :
373 [ # # ]: 0 : if (hw->device_id == IDPF_DEV_ID_SRIOV) {
374 : 0 : ret = idpf_check_vf_reset_done(hw);
375 : : } else {
376 : : idpf_reset_pf(hw);
377 : 0 : ret = idpf_check_pf_reset_done(hw);
378 : : }
379 [ # # ]: 0 : if (ret != 0) {
380 : 0 : DRV_LOG(ERR, "IDPF is still resetting");
381 : 0 : goto err_check_reset;
382 : : }
383 : :
384 : 0 : ret = idpf_init_mbx(hw);
385 [ # # ]: 0 : if (ret != 0) {
386 : 0 : DRV_LOG(ERR, "Failed to init mailbox");
387 : 0 : goto err_check_reset;
388 : : }
389 : :
390 : 0 : adapter->mbx_resp = rte_zmalloc("idpf_adapter_mbx_resp",
391 : : IDPF_DFLT_MBX_BUF_SIZE, 0);
392 [ # # ]: 0 : if (adapter->mbx_resp == NULL) {
393 : 0 : DRV_LOG(ERR, "Failed to allocate idpf_adapter_mbx_resp memory");
394 : : ret = -ENOMEM;
395 : 0 : goto err_mbx_resp;
396 : : }
397 : :
398 : 0 : ret = idpf_vc_api_version_check(adapter);
399 [ # # ]: 0 : if (ret != 0) {
400 : 0 : DRV_LOG(ERR, "Failed to check api version");
401 : 0 : goto err_check_api;
402 : : }
403 : :
404 : 0 : ret = idpf_vc_caps_get(adapter);
405 [ # # ]: 0 : if (ret != 0) {
406 : 0 : DRV_LOG(ERR, "Failed to get capabilities");
407 : 0 : goto err_check_api;
408 : : }
409 : :
410 : 0 : ret = idpf_get_pkt_type(adapter);
411 [ # # ]: 0 : if (ret != 0) {
412 : 0 : DRV_LOG(ERR, "Failed to set ptype table");
413 : 0 : goto err_check_api;
414 : : }
415 : :
416 : : return 0;
417 : :
418 : 0 : err_check_api:
419 : 0 : rte_free(adapter->mbx_resp);
420 : 0 : adapter->mbx_resp = NULL;
421 : 0 : err_mbx_resp:
422 : 0 : idpf_ctlq_deinit(hw);
423 : : err_check_reset:
424 : : return ret;
425 : : }
426 : :
427 : : int
428 : 0 : idpf_adapter_deinit(struct idpf_adapter *adapter)
429 : : {
430 : 0 : struct idpf_hw *hw = &adapter->hw;
431 : :
432 : 0 : idpf_ctlq_deinit(hw);
433 : 0 : rte_free(adapter->mbx_resp);
434 : 0 : adapter->mbx_resp = NULL;
435 : :
436 : 0 : return 0;
437 : : }
438 : :
439 : : int
440 : 0 : idpf_vport_init(struct idpf_vport *vport,
441 : : struct virtchnl2_create_vport *create_vport_info,
442 : : void *dev_data)
443 : : {
444 : : struct virtchnl2_create_vport *vport_info;
445 : : int i, type, ret;
446 : :
447 : 0 : ret = idpf_vc_vport_create(vport, create_vport_info);
448 [ # # ]: 0 : if (ret != 0) {
449 : 0 : DRV_LOG(ERR, "Failed to create vport.");
450 : 0 : goto err_create_vport;
451 : : }
452 : :
453 : : vport_info = &(vport->vport_info.info);
454 : 0 : vport->vport_id = vport_info->vport_id;
455 : 0 : vport->txq_model = vport_info->txq_model;
456 : 0 : vport->rxq_model = vport_info->rxq_model;
457 : 0 : vport->num_tx_q = vport_info->num_tx_q;
458 : 0 : vport->num_tx_complq = vport_info->num_tx_complq;
459 : 0 : vport->num_rx_q = vport_info->num_rx_q;
460 : 0 : vport->num_rx_bufq = vport_info->num_rx_bufq;
461 : 0 : vport->max_mtu = vport_info->max_mtu;
462 : 0 : rte_memcpy(vport->default_mac_addr,
463 [ # # ]: 0 : vport_info->default_mac_addr, ETH_ALEN);
464 : 0 : vport->rss_algorithm = vport_info->rss_algorithm;
465 : 0 : vport->rss_key_size = RTE_MIN(IDPF_RSS_KEY_LEN,
466 : : vport_info->rss_key_size);
467 : 0 : vport->rss_lut_size = vport_info->rss_lut_size;
468 : :
469 [ # # ]: 0 : for (i = 0; i < vport_info->chunks.num_chunks; i++) {
470 : 0 : type = vport_info->chunks.chunks[i].type;
471 [ # # # # : 0 : switch (type) {
# ]
472 : 0 : case VIRTCHNL2_QUEUE_TYPE_TX:
473 : 0 : vport->chunks_info.tx_start_qid =
474 : 0 : vport_info->chunks.chunks[i].start_queue_id;
475 : 0 : vport->chunks_info.tx_qtail_start =
476 : 0 : vport_info->chunks.chunks[i].qtail_reg_start;
477 : 0 : vport->chunks_info.tx_qtail_spacing =
478 : 0 : vport_info->chunks.chunks[i].qtail_reg_spacing;
479 : 0 : break;
480 : 0 : case VIRTCHNL2_QUEUE_TYPE_RX:
481 : 0 : vport->chunks_info.rx_start_qid =
482 : 0 : vport_info->chunks.chunks[i].start_queue_id;
483 : 0 : vport->chunks_info.rx_qtail_start =
484 : 0 : vport_info->chunks.chunks[i].qtail_reg_start;
485 : 0 : vport->chunks_info.rx_qtail_spacing =
486 : 0 : vport_info->chunks.chunks[i].qtail_reg_spacing;
487 : 0 : break;
488 : 0 : case VIRTCHNL2_QUEUE_TYPE_TX_COMPLETION:
489 : 0 : vport->chunks_info.tx_compl_start_qid =
490 : 0 : vport_info->chunks.chunks[i].start_queue_id;
491 : 0 : vport->chunks_info.tx_compl_qtail_start =
492 : 0 : vport_info->chunks.chunks[i].qtail_reg_start;
493 : 0 : vport->chunks_info.tx_compl_qtail_spacing =
494 : 0 : vport_info->chunks.chunks[i].qtail_reg_spacing;
495 : 0 : break;
496 : 0 : case VIRTCHNL2_QUEUE_TYPE_RX_BUFFER:
497 : 0 : vport->chunks_info.rx_buf_start_qid =
498 : 0 : vport_info->chunks.chunks[i].start_queue_id;
499 : 0 : vport->chunks_info.rx_buf_qtail_start =
500 : 0 : vport_info->chunks.chunks[i].qtail_reg_start;
501 : 0 : vport->chunks_info.rx_buf_qtail_spacing =
502 : 0 : vport_info->chunks.chunks[i].qtail_reg_spacing;
503 : 0 : break;
504 : 0 : default:
505 : 0 : DRV_LOG(ERR, "Unsupported queue type");
506 : 0 : break;
507 : : }
508 : : }
509 : :
510 : 0 : vport->dev_data = dev_data;
511 : :
512 : 0 : vport->rss_key = rte_zmalloc("rss_key",
513 : 0 : vport->rss_key_size, 0);
514 [ # # ]: 0 : if (vport->rss_key == NULL) {
515 : 0 : DRV_LOG(ERR, "Failed to allocate RSS key");
516 : : ret = -ENOMEM;
517 : 0 : goto err_rss_key;
518 : : }
519 : :
520 : 0 : vport->rss_lut = rte_zmalloc("rss_lut",
521 : 0 : sizeof(uint32_t) * vport->rss_lut_size, 0);
522 [ # # ]: 0 : if (vport->rss_lut == NULL) {
523 : 0 : DRV_LOG(ERR, "Failed to allocate RSS lut");
524 : : ret = -ENOMEM;
525 : 0 : goto err_rss_lut;
526 : : }
527 : :
528 : : /* recv_vectors is used for VIRTCHNL2_OP_ALLOC_VECTORS response,
529 : : * reserve maximum size for it now, may need optimization in future.
530 : : */
531 : 0 : vport->recv_vectors = rte_zmalloc("recv_vectors", IDPF_DFLT_MBX_BUF_SIZE, 0);
532 [ # # ]: 0 : if (vport->recv_vectors == NULL) {
533 : 0 : DRV_LOG(ERR, "Failed to allocate recv_vectors");
534 : : ret = -ENOMEM;
535 : 0 : goto err_recv_vec;
536 : : }
537 : :
538 : : return 0;
539 : :
540 : : err_recv_vec:
541 : 0 : rte_free(vport->rss_lut);
542 : 0 : vport->rss_lut = NULL;
543 : 0 : err_rss_lut:
544 : 0 : vport->dev_data = NULL;
545 : 0 : rte_free(vport->rss_key);
546 : 0 : vport->rss_key = NULL;
547 : 0 : err_rss_key:
548 : 0 : idpf_vc_vport_destroy(vport);
549 : : err_create_vport:
550 : : return ret;
551 : : }
552 : : int
553 : 0 : idpf_vport_deinit(struct idpf_vport *vport)
554 : : {
555 : 0 : rte_free(vport->recv_vectors);
556 : 0 : vport->recv_vectors = NULL;
557 : 0 : rte_free(vport->rss_lut);
558 : 0 : vport->rss_lut = NULL;
559 : :
560 : 0 : rte_free(vport->rss_key);
561 : 0 : vport->rss_key = NULL;
562 : :
563 : 0 : vport->dev_data = NULL;
564 : :
565 : 0 : idpf_vc_vport_destroy(vport);
566 : :
567 : 0 : return 0;
568 : : }
569 : : int
570 : 0 : idpf_vport_rss_config(struct idpf_vport *vport)
571 : : {
572 : : int ret;
573 : :
574 : 0 : ret = idpf_vc_rss_key_set(vport);
575 [ # # ]: 0 : if (ret != 0) {
576 : 0 : DRV_LOG(ERR, "Failed to configure RSS key");
577 : 0 : return ret;
578 : : }
579 : :
580 : 0 : ret = idpf_vc_rss_lut_set(vport);
581 [ # # ]: 0 : if (ret != 0) {
582 : 0 : DRV_LOG(ERR, "Failed to configure RSS lut");
583 : 0 : return ret;
584 : : }
585 : :
586 : 0 : ret = idpf_vc_rss_hash_set(vport);
587 [ # # ]: 0 : if (ret != 0) {
588 : 0 : DRV_LOG(ERR, "Failed to configure RSS hash");
589 : 0 : return ret;
590 : : }
591 : :
592 : : return ret;
593 : : }
594 : :
595 : : int
596 : 0 : idpf_vport_irq_map_config(struct idpf_vport *vport, uint16_t nb_rx_queues)
597 : : {
598 : 0 : struct idpf_adapter *adapter = vport->adapter;
599 : : struct virtchnl2_queue_vector *qv_map;
600 : : struct idpf_hw *hw = &adapter->hw;
601 : : uint32_t dynctl_val, itrn_val;
602 : : uint32_t dynctl_reg_start;
603 : : uint32_t itrn_reg_start;
604 : : uint16_t i;
605 : : int ret;
606 : :
607 : 0 : qv_map = rte_zmalloc("qv_map",
608 : : nb_rx_queues *
609 : : sizeof(struct virtchnl2_queue_vector), 0);
610 [ # # ]: 0 : if (qv_map == NULL) {
611 : 0 : DRV_LOG(ERR, "Failed to allocate %d queue-vector map",
612 : : nb_rx_queues);
613 : : ret = -ENOMEM;
614 : 0 : goto qv_map_alloc_err;
615 : : }
616 : :
617 : : /* Rx interrupt disabled, Map interrupt only for writeback */
618 : :
619 : : /* The capability flags adapter->caps.other_caps should be
620 : : * compared with bit VIRTCHNL2_CAP_WB_ON_ITR here. The if
621 : : * condition should be updated when the FW can return the
622 : : * correct flag bits.
623 : : */
624 : 0 : dynctl_reg_start =
625 : 0 : vport->recv_vectors->vchunks.vchunks->dynctl_reg_start;
626 : 0 : itrn_reg_start =
627 : : vport->recv_vectors->vchunks.vchunks->itrn_reg_start;
628 : 0 : dynctl_val = IDPF_READ_REG(hw, dynctl_reg_start);
629 : 0 : DRV_LOG(DEBUG, "Value of dynctl_reg_start is 0x%x", dynctl_val);
630 : 0 : itrn_val = IDPF_READ_REG(hw, itrn_reg_start);
631 : 0 : DRV_LOG(DEBUG, "Value of itrn_reg_start is 0x%x", itrn_val);
632 : : /* Force write-backs by setting WB_ON_ITR bit in DYN_CTL
633 : : * register. WB_ON_ITR and INTENA are mutually exclusive
634 : : * bits. Setting WB_ON_ITR bits means TX and RX Descs
635 : : * are written back based on ITR expiration irrespective
636 : : * of INTENA setting.
637 : : */
638 : : /* TBD: need to tune INTERVAL value for better performance. */
639 [ # # ]: 0 : itrn_val = (itrn_val == 0) ? IDPF_DFLT_INTERVAL : itrn_val;
640 : 0 : dynctl_val = VIRTCHNL2_ITR_IDX_0 <<
641 : : PF_GLINT_DYN_CTL_ITR_INDX_S |
642 : : PF_GLINT_DYN_CTL_WB_ON_ITR_M |
643 : 0 : itrn_val << PF_GLINT_DYN_CTL_INTERVAL_S;
644 : 0 : IDPF_WRITE_REG(hw, dynctl_reg_start, dynctl_val);
645 : :
646 [ # # ]: 0 : for (i = 0; i < nb_rx_queues; i++) {
647 : : /* map all queues to the same vector */
648 : 0 : qv_map[i].queue_id = vport->chunks_info.rx_start_qid + i;
649 : 0 : qv_map[i].vector_id =
650 : 0 : vport->recv_vectors->vchunks.vchunks->start_vector_id;
651 : : }
652 : 0 : vport->qv_map = qv_map;
653 : :
654 : 0 : ret = idpf_vc_irq_map_unmap_config(vport, nb_rx_queues, true);
655 [ # # ]: 0 : if (ret != 0) {
656 : 0 : DRV_LOG(ERR, "config interrupt mapping failed");
657 : 0 : goto config_irq_map_err;
658 : : }
659 : :
660 : : return 0;
661 : :
662 : : config_irq_map_err:
663 : 0 : rte_free(vport->qv_map);
664 : 0 : vport->qv_map = NULL;
665 : :
666 : : qv_map_alloc_err:
667 : : return ret;
668 : : }
669 : :
670 : : int
671 : 0 : idpf_vport_irq_map_config_by_qids(struct idpf_vport *vport, uint32_t *qids, uint16_t nb_rx_queues)
672 : : {
673 : 0 : struct idpf_adapter *adapter = vport->adapter;
674 : : struct virtchnl2_queue_vector *qv_map;
675 : : struct idpf_hw *hw = &adapter->hw;
676 : : uint32_t dynctl_val, itrn_val;
677 : : uint32_t dynctl_reg_start;
678 : : uint32_t itrn_reg_start;
679 : : uint16_t i;
680 : : int ret;
681 : :
682 : 0 : qv_map = rte_zmalloc("qv_map",
683 : : nb_rx_queues *
684 : : sizeof(struct virtchnl2_queue_vector), 0);
685 [ # # ]: 0 : if (qv_map == NULL) {
686 : 0 : DRV_LOG(ERR, "Failed to allocate %d queue-vector map",
687 : : nb_rx_queues);
688 : : ret = -ENOMEM;
689 : 0 : goto qv_map_alloc_err;
690 : : }
691 : :
692 : : /* Rx interrupt disabled, Map interrupt only for writeback */
693 : :
694 : : /* The capability flags adapter->caps.other_caps should be
695 : : * compared with bit VIRTCHNL2_CAP_WB_ON_ITR here. The if
696 : : * condition should be updated when the FW can return the
697 : : * correct flag bits.
698 : : */
699 : 0 : dynctl_reg_start =
700 : 0 : vport->recv_vectors->vchunks.vchunks->dynctl_reg_start;
701 : 0 : itrn_reg_start =
702 : : vport->recv_vectors->vchunks.vchunks->itrn_reg_start;
703 : 0 : dynctl_val = IDPF_READ_REG(hw, dynctl_reg_start);
704 : 0 : DRV_LOG(DEBUG, "Value of dynctl_reg_start is 0x%x", dynctl_val);
705 : 0 : itrn_val = IDPF_READ_REG(hw, itrn_reg_start);
706 : 0 : DRV_LOG(DEBUG, "Value of itrn_reg_start is 0x%x", itrn_val);
707 : : /* Force write-backs by setting WB_ON_ITR bit in DYN_CTL
708 : : * register. WB_ON_ITR and INTENA are mutually exclusive
709 : : * bits. Setting WB_ON_ITR bits means TX and RX Descs
710 : : * are written back based on ITR expiration irrespective
711 : : * of INTENA setting.
712 : : */
713 : : /* TBD: need to tune INTERVAL value for better performance. */
714 [ # # ]: 0 : itrn_val = (itrn_val == 0) ? IDPF_DFLT_INTERVAL : itrn_val;
715 : 0 : dynctl_val = VIRTCHNL2_ITR_IDX_0 <<
716 : : PF_GLINT_DYN_CTL_ITR_INDX_S |
717 : : PF_GLINT_DYN_CTL_WB_ON_ITR_M |
718 : 0 : itrn_val << PF_GLINT_DYN_CTL_INTERVAL_S;
719 : 0 : IDPF_WRITE_REG(hw, dynctl_reg_start, dynctl_val);
720 : :
721 [ # # ]: 0 : for (i = 0; i < nb_rx_queues; i++) {
722 : : /* map all queues to the same vector */
723 : 0 : qv_map[i].queue_id = qids[i];
724 : 0 : qv_map[i].vector_id =
725 : 0 : vport->recv_vectors->vchunks.vchunks->start_vector_id;
726 : : }
727 : 0 : vport->qv_map = qv_map;
728 : :
729 : 0 : ret = idpf_vc_irq_map_unmap_config(vport, nb_rx_queues, true);
730 [ # # ]: 0 : if (ret != 0) {
731 : 0 : DRV_LOG(ERR, "config interrupt mapping failed");
732 : 0 : goto config_irq_map_err;
733 : : }
734 : :
735 : : return 0;
736 : :
737 : : config_irq_map_err:
738 : 0 : rte_free(vport->qv_map);
739 : 0 : vport->qv_map = NULL;
740 : :
741 : : qv_map_alloc_err:
742 : : return ret;
743 : : }
744 : :
745 : : int
746 : 0 : idpf_vport_irq_unmap_config(struct idpf_vport *vport, uint16_t nb_rx_queues)
747 : : {
748 : 0 : idpf_vc_irq_map_unmap_config(vport, nb_rx_queues, false);
749 : :
750 : 0 : rte_free(vport->qv_map);
751 : 0 : vport->qv_map = NULL;
752 : :
753 : 0 : return 0;
754 : : }
755 : :
756 : : int
757 : 0 : idpf_vport_info_init(struct idpf_vport *vport,
758 : : struct virtchnl2_create_vport *vport_info)
759 : : {
760 : 0 : struct idpf_adapter *adapter = vport->adapter;
761 : :
762 : 0 : vport_info->vport_type = rte_cpu_to_le_16(VIRTCHNL2_VPORT_TYPE_DEFAULT);
763 [ # # ]: 0 : if (!adapter->is_tx_singleq) {
764 : 0 : vport_info->txq_model =
765 : : rte_cpu_to_le_16(VIRTCHNL2_QUEUE_MODEL_SPLIT);
766 : 0 : vport_info->num_tx_q =
767 : : rte_cpu_to_le_16(IDPF_DEFAULT_TXQ_NUM);
768 : 0 : vport_info->num_tx_complq =
769 : : rte_cpu_to_le_16(IDPF_DEFAULT_TXQ_NUM * IDPF_TX_COMPLQ_PER_GRP);
770 : : } else {
771 : 0 : vport_info->txq_model =
772 : : rte_cpu_to_le_16(VIRTCHNL2_QUEUE_MODEL_SINGLE);
773 : 0 : vport_info->num_tx_q = rte_cpu_to_le_16(IDPF_DEFAULT_TXQ_NUM);
774 : 0 : vport_info->num_tx_complq = 0;
775 : : }
776 [ # # ]: 0 : if (!adapter->is_rx_singleq) {
777 : 0 : vport_info->rxq_model =
778 : : rte_cpu_to_le_16(VIRTCHNL2_QUEUE_MODEL_SPLIT);
779 : 0 : vport_info->num_rx_q = rte_cpu_to_le_16(IDPF_DEFAULT_RXQ_NUM);
780 : 0 : vport_info->num_rx_bufq =
781 : : rte_cpu_to_le_16(IDPF_DEFAULT_RXQ_NUM * IDPF_RX_BUFQ_PER_GRP);
782 : : } else {
783 : 0 : vport_info->rxq_model =
784 : : rte_cpu_to_le_16(VIRTCHNL2_QUEUE_MODEL_SINGLE);
785 : 0 : vport_info->num_rx_q = rte_cpu_to_le_16(IDPF_DEFAULT_RXQ_NUM);
786 : 0 : vport_info->num_rx_bufq = 0;
787 : : }
788 : :
789 : 0 : return 0;
790 : : }
791 : :
792 : : void
793 : 0 : idpf_vport_stats_update(struct virtchnl2_vport_stats *oes, struct virtchnl2_vport_stats *nes)
794 : : {
795 : 0 : nes->rx_bytes = nes->rx_bytes - oes->rx_bytes;
796 : 0 : nes->rx_unicast = nes->rx_unicast - oes->rx_unicast;
797 : 0 : nes->rx_multicast = nes->rx_multicast - oes->rx_multicast;
798 : 0 : nes->rx_broadcast = nes->rx_broadcast - oes->rx_broadcast;
799 : 0 : nes->rx_errors = nes->rx_errors - oes->rx_errors;
800 : 0 : nes->rx_discards = nes->rx_discards - oes->rx_discards;
801 : 0 : nes->tx_bytes = nes->tx_bytes - oes->tx_bytes;
802 : 0 : nes->tx_unicast = nes->tx_unicast - oes->tx_unicast;
803 : 0 : nes->tx_multicast = nes->tx_multicast - oes->tx_multicast;
804 : 0 : nes->tx_broadcast = nes->tx_broadcast - oes->tx_broadcast;
805 : 0 : nes->tx_errors = nes->tx_errors - oes->tx_errors;
806 : 0 : nes->tx_discards = nes->tx_discards - oes->tx_discards;
807 : 0 : }
808 : :
809 [ - + ]: 235 : RTE_LOG_REGISTER_SUFFIX(idpf_common_logtype, common, NOTICE);
|