]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/iavf/base/iavf_common.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / iavf / base / iavf_common.c
1 /*******************************************************************************
2
3 Copyright (c) 2013 - 2015, Intel Corporation
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31
32 ***************************************************************************/
33
34 #include "iavf_type.h"
35 #include "iavf_adminq.h"
36 #include "iavf_prototype.h"
37 #include "virtchnl.h"
38
39
40 /**
41 * iavf_set_mac_type - Sets MAC type
42 * @hw: pointer to the HW structure
43 *
44 * This function sets the mac type of the adapter based on the
45 * vendor ID and device ID stored in the hw structure.
46 **/
47 enum iavf_status_code iavf_set_mac_type(struct iavf_hw *hw)
48 {
49 enum iavf_status_code status = IAVF_SUCCESS;
50
51 DEBUGFUNC("iavf_set_mac_type\n");
52
53 if (hw->vendor_id == IAVF_INTEL_VENDOR_ID) {
54 switch (hw->device_id) {
55 /* TODO: remove undefined device ID now, need to think how to
56 * remove them in share code
57 */
58 case IAVF_DEV_ID_ADAPTIVE_VF:
59 hw->mac.type = IAVF_MAC_VF;
60 break;
61 default:
62 hw->mac.type = IAVF_MAC_GENERIC;
63 break;
64 }
65 } else {
66 status = IAVF_ERR_DEVICE_NOT_SUPPORTED;
67 }
68
69 DEBUGOUT2("iavf_set_mac_type found mac: %d, returns: %d\n",
70 hw->mac.type, status);
71 return status;
72 }
73
74 /**
75 * iavf_aq_str - convert AQ err code to a string
76 * @hw: pointer to the HW structure
77 * @aq_err: the AQ error code to convert
78 **/
79 const char *iavf_aq_str(struct iavf_hw *hw, enum iavf_admin_queue_err aq_err)
80 {
81 switch (aq_err) {
82 case IAVF_AQ_RC_OK:
83 return "OK";
84 case IAVF_AQ_RC_EPERM:
85 return "IAVF_AQ_RC_EPERM";
86 case IAVF_AQ_RC_ENOENT:
87 return "IAVF_AQ_RC_ENOENT";
88 case IAVF_AQ_RC_ESRCH:
89 return "IAVF_AQ_RC_ESRCH";
90 case IAVF_AQ_RC_EINTR:
91 return "IAVF_AQ_RC_EINTR";
92 case IAVF_AQ_RC_EIO:
93 return "IAVF_AQ_RC_EIO";
94 case IAVF_AQ_RC_ENXIO:
95 return "IAVF_AQ_RC_ENXIO";
96 case IAVF_AQ_RC_E2BIG:
97 return "IAVF_AQ_RC_E2BIG";
98 case IAVF_AQ_RC_EAGAIN:
99 return "IAVF_AQ_RC_EAGAIN";
100 case IAVF_AQ_RC_ENOMEM:
101 return "IAVF_AQ_RC_ENOMEM";
102 case IAVF_AQ_RC_EACCES:
103 return "IAVF_AQ_RC_EACCES";
104 case IAVF_AQ_RC_EFAULT:
105 return "IAVF_AQ_RC_EFAULT";
106 case IAVF_AQ_RC_EBUSY:
107 return "IAVF_AQ_RC_EBUSY";
108 case IAVF_AQ_RC_EEXIST:
109 return "IAVF_AQ_RC_EEXIST";
110 case IAVF_AQ_RC_EINVAL:
111 return "IAVF_AQ_RC_EINVAL";
112 case IAVF_AQ_RC_ENOTTY:
113 return "IAVF_AQ_RC_ENOTTY";
114 case IAVF_AQ_RC_ENOSPC:
115 return "IAVF_AQ_RC_ENOSPC";
116 case IAVF_AQ_RC_ENOSYS:
117 return "IAVF_AQ_RC_ENOSYS";
118 case IAVF_AQ_RC_ERANGE:
119 return "IAVF_AQ_RC_ERANGE";
120 case IAVF_AQ_RC_EFLUSHED:
121 return "IAVF_AQ_RC_EFLUSHED";
122 case IAVF_AQ_RC_BAD_ADDR:
123 return "IAVF_AQ_RC_BAD_ADDR";
124 case IAVF_AQ_RC_EMODE:
125 return "IAVF_AQ_RC_EMODE";
126 case IAVF_AQ_RC_EFBIG:
127 return "IAVF_AQ_RC_EFBIG";
128 }
129
130 snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
131 return hw->err_str;
132 }
133
134 /**
135 * iavf_stat_str - convert status err code to a string
136 * @hw: pointer to the HW structure
137 * @stat_err: the status error code to convert
138 **/
139 const char *iavf_stat_str(struct iavf_hw *hw, enum iavf_status_code stat_err)
140 {
141 switch (stat_err) {
142 case IAVF_SUCCESS:
143 return "OK";
144 case IAVF_ERR_NVM:
145 return "IAVF_ERR_NVM";
146 case IAVF_ERR_NVM_CHECKSUM:
147 return "IAVF_ERR_NVM_CHECKSUM";
148 case IAVF_ERR_PHY:
149 return "IAVF_ERR_PHY";
150 case IAVF_ERR_CONFIG:
151 return "IAVF_ERR_CONFIG";
152 case IAVF_ERR_PARAM:
153 return "IAVF_ERR_PARAM";
154 case IAVF_ERR_MAC_TYPE:
155 return "IAVF_ERR_MAC_TYPE";
156 case IAVF_ERR_UNKNOWN_PHY:
157 return "IAVF_ERR_UNKNOWN_PHY";
158 case IAVF_ERR_LINK_SETUP:
159 return "IAVF_ERR_LINK_SETUP";
160 case IAVF_ERR_ADAPTER_STOPPED:
161 return "IAVF_ERR_ADAPTER_STOPPED";
162 case IAVF_ERR_INVALID_MAC_ADDR:
163 return "IAVF_ERR_INVALID_MAC_ADDR";
164 case IAVF_ERR_DEVICE_NOT_SUPPORTED:
165 return "IAVF_ERR_DEVICE_NOT_SUPPORTED";
166 case IAVF_ERR_MASTER_REQUESTS_PENDING:
167 return "IAVF_ERR_MASTER_REQUESTS_PENDING";
168 case IAVF_ERR_INVALID_LINK_SETTINGS:
169 return "IAVF_ERR_INVALID_LINK_SETTINGS";
170 case IAVF_ERR_AUTONEG_NOT_COMPLETE:
171 return "IAVF_ERR_AUTONEG_NOT_COMPLETE";
172 case IAVF_ERR_RESET_FAILED:
173 return "IAVF_ERR_RESET_FAILED";
174 case IAVF_ERR_SWFW_SYNC:
175 return "IAVF_ERR_SWFW_SYNC";
176 case IAVF_ERR_NO_AVAILABLE_VSI:
177 return "IAVF_ERR_NO_AVAILABLE_VSI";
178 case IAVF_ERR_NO_MEMORY:
179 return "IAVF_ERR_NO_MEMORY";
180 case IAVF_ERR_BAD_PTR:
181 return "IAVF_ERR_BAD_PTR";
182 case IAVF_ERR_RING_FULL:
183 return "IAVF_ERR_RING_FULL";
184 case IAVF_ERR_INVALID_PD_ID:
185 return "IAVF_ERR_INVALID_PD_ID";
186 case IAVF_ERR_INVALID_QP_ID:
187 return "IAVF_ERR_INVALID_QP_ID";
188 case IAVF_ERR_INVALID_CQ_ID:
189 return "IAVF_ERR_INVALID_CQ_ID";
190 case IAVF_ERR_INVALID_CEQ_ID:
191 return "IAVF_ERR_INVALID_CEQ_ID";
192 case IAVF_ERR_INVALID_AEQ_ID:
193 return "IAVF_ERR_INVALID_AEQ_ID";
194 case IAVF_ERR_INVALID_SIZE:
195 return "IAVF_ERR_INVALID_SIZE";
196 case IAVF_ERR_INVALID_ARP_INDEX:
197 return "IAVF_ERR_INVALID_ARP_INDEX";
198 case IAVF_ERR_INVALID_FPM_FUNC_ID:
199 return "IAVF_ERR_INVALID_FPM_FUNC_ID";
200 case IAVF_ERR_QP_INVALID_MSG_SIZE:
201 return "IAVF_ERR_QP_INVALID_MSG_SIZE";
202 case IAVF_ERR_QP_TOOMANY_WRS_POSTED:
203 return "IAVF_ERR_QP_TOOMANY_WRS_POSTED";
204 case IAVF_ERR_INVALID_FRAG_COUNT:
205 return "IAVF_ERR_INVALID_FRAG_COUNT";
206 case IAVF_ERR_QUEUE_EMPTY:
207 return "IAVF_ERR_QUEUE_EMPTY";
208 case IAVF_ERR_INVALID_ALIGNMENT:
209 return "IAVF_ERR_INVALID_ALIGNMENT";
210 case IAVF_ERR_FLUSHED_QUEUE:
211 return "IAVF_ERR_FLUSHED_QUEUE";
212 case IAVF_ERR_INVALID_PUSH_PAGE_INDEX:
213 return "IAVF_ERR_INVALID_PUSH_PAGE_INDEX";
214 case IAVF_ERR_INVALID_IMM_DATA_SIZE:
215 return "IAVF_ERR_INVALID_IMM_DATA_SIZE";
216 case IAVF_ERR_TIMEOUT:
217 return "IAVF_ERR_TIMEOUT";
218 case IAVF_ERR_OPCODE_MISMATCH:
219 return "IAVF_ERR_OPCODE_MISMATCH";
220 case IAVF_ERR_CQP_COMPL_ERROR:
221 return "IAVF_ERR_CQP_COMPL_ERROR";
222 case IAVF_ERR_INVALID_VF_ID:
223 return "IAVF_ERR_INVALID_VF_ID";
224 case IAVF_ERR_INVALID_HMCFN_ID:
225 return "IAVF_ERR_INVALID_HMCFN_ID";
226 case IAVF_ERR_BACKING_PAGE_ERROR:
227 return "IAVF_ERR_BACKING_PAGE_ERROR";
228 case IAVF_ERR_NO_PBLCHUNKS_AVAILABLE:
229 return "IAVF_ERR_NO_PBLCHUNKS_AVAILABLE";
230 case IAVF_ERR_INVALID_PBLE_INDEX:
231 return "IAVF_ERR_INVALID_PBLE_INDEX";
232 case IAVF_ERR_INVALID_SD_INDEX:
233 return "IAVF_ERR_INVALID_SD_INDEX";
234 case IAVF_ERR_INVALID_PAGE_DESC_INDEX:
235 return "IAVF_ERR_INVALID_PAGE_DESC_INDEX";
236 case IAVF_ERR_INVALID_SD_TYPE:
237 return "IAVF_ERR_INVALID_SD_TYPE";
238 case IAVF_ERR_MEMCPY_FAILED:
239 return "IAVF_ERR_MEMCPY_FAILED";
240 case IAVF_ERR_INVALID_HMC_OBJ_INDEX:
241 return "IAVF_ERR_INVALID_HMC_OBJ_INDEX";
242 case IAVF_ERR_INVALID_HMC_OBJ_COUNT:
243 return "IAVF_ERR_INVALID_HMC_OBJ_COUNT";
244 case IAVF_ERR_INVALID_SRQ_ARM_LIMIT:
245 return "IAVF_ERR_INVALID_SRQ_ARM_LIMIT";
246 case IAVF_ERR_SRQ_ENABLED:
247 return "IAVF_ERR_SRQ_ENABLED";
248 case IAVF_ERR_ADMIN_QUEUE_ERROR:
249 return "IAVF_ERR_ADMIN_QUEUE_ERROR";
250 case IAVF_ERR_ADMIN_QUEUE_TIMEOUT:
251 return "IAVF_ERR_ADMIN_QUEUE_TIMEOUT";
252 case IAVF_ERR_BUF_TOO_SHORT:
253 return "IAVF_ERR_BUF_TOO_SHORT";
254 case IAVF_ERR_ADMIN_QUEUE_FULL:
255 return "IAVF_ERR_ADMIN_QUEUE_FULL";
256 case IAVF_ERR_ADMIN_QUEUE_NO_WORK:
257 return "IAVF_ERR_ADMIN_QUEUE_NO_WORK";
258 case IAVF_ERR_BAD_IWARP_CQE:
259 return "IAVF_ERR_BAD_IWARP_CQE";
260 case IAVF_ERR_NVM_BLANK_MODE:
261 return "IAVF_ERR_NVM_BLANK_MODE";
262 case IAVF_ERR_NOT_IMPLEMENTED:
263 return "IAVF_ERR_NOT_IMPLEMENTED";
264 case IAVF_ERR_PE_DOORBELL_NOT_ENABLED:
265 return "IAVF_ERR_PE_DOORBELL_NOT_ENABLED";
266 case IAVF_ERR_DIAG_TEST_FAILED:
267 return "IAVF_ERR_DIAG_TEST_FAILED";
268 case IAVF_ERR_NOT_READY:
269 return "IAVF_ERR_NOT_READY";
270 case IAVF_NOT_SUPPORTED:
271 return "IAVF_NOT_SUPPORTED";
272 case IAVF_ERR_FIRMWARE_API_VERSION:
273 return "IAVF_ERR_FIRMWARE_API_VERSION";
274 case IAVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
275 return "IAVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
276 }
277
278 snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
279 return hw->err_str;
280 }
281
282 /**
283 * iavf_debug_aq
284 * @hw: debug mask related to admin queue
285 * @mask: debug mask
286 * @desc: pointer to admin queue descriptor
287 * @buffer: pointer to command buffer
288 * @buf_len: max length of buffer
289 *
290 * Dumps debug log about adminq command with descriptor contents.
291 **/
292 void iavf_debug_aq(struct iavf_hw *hw, enum iavf_debug_mask mask, void *desc,
293 void *buffer, u16 buf_len)
294 {
295 struct iavf_aq_desc *aq_desc = (struct iavf_aq_desc *)desc;
296 u8 *buf = (u8 *)buffer;
297 u16 len;
298 u16 i = 0;
299
300 if ((!(mask & hw->debug_mask)) || (desc == NULL))
301 return;
302
303 len = LE16_TO_CPU(aq_desc->datalen);
304
305 iavf_debug(hw, mask,
306 "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
307 LE16_TO_CPU(aq_desc->opcode),
308 LE16_TO_CPU(aq_desc->flags),
309 LE16_TO_CPU(aq_desc->datalen),
310 LE16_TO_CPU(aq_desc->retval));
311 iavf_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
312 LE32_TO_CPU(aq_desc->cookie_high),
313 LE32_TO_CPU(aq_desc->cookie_low));
314 iavf_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n",
315 LE32_TO_CPU(aq_desc->params.internal.param0),
316 LE32_TO_CPU(aq_desc->params.internal.param1));
317 iavf_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n",
318 LE32_TO_CPU(aq_desc->params.external.addr_high),
319 LE32_TO_CPU(aq_desc->params.external.addr_low));
320
321 if ((buffer != NULL) && (aq_desc->datalen != 0)) {
322 iavf_debug(hw, mask, "AQ CMD Buffer:\n");
323 if (buf_len < len)
324 len = buf_len;
325 /* write the full 16-byte chunks */
326 for (i = 0; i < (len - 16); i += 16)
327 iavf_debug(hw, mask,
328 "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
329 i, buf[i], buf[i+1], buf[i+2], buf[i+3],
330 buf[i+4], buf[i+5], buf[i+6], buf[i+7],
331 buf[i+8], buf[i+9], buf[i+10], buf[i+11],
332 buf[i+12], buf[i+13], buf[i+14], buf[i+15]);
333 /* the most we could have left is 16 bytes, pad with zeros */
334 if (i < len) {
335 char d_buf[16];
336 int j, i_sav;
337
338 i_sav = i;
339 memset(d_buf, 0, sizeof(d_buf));
340 for (j = 0; i < len; j++, i++)
341 d_buf[j] = buf[i];
342 iavf_debug(hw, mask,
343 "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
344 i_sav, d_buf[0], d_buf[1], d_buf[2], d_buf[3],
345 d_buf[4], d_buf[5], d_buf[6], d_buf[7],
346 d_buf[8], d_buf[9], d_buf[10], d_buf[11],
347 d_buf[12], d_buf[13], d_buf[14], d_buf[15]);
348 }
349 }
350 }
351
352 /**
353 * iavf_check_asq_alive
354 * @hw: pointer to the hw struct
355 *
356 * Returns true if Queue is enabled else false.
357 **/
358 bool iavf_check_asq_alive(struct iavf_hw *hw)
359 {
360 if (hw->aq.asq.len)
361 #ifdef INTEGRATED_VF
362 if (iavf_is_vf(hw))
363 return !!(rd32(hw, hw->aq.asq.len) &
364 IAVF_ATQLEN1_ATQENABLE_MASK);
365 #else
366 return !!(rd32(hw, hw->aq.asq.len) &
367 IAVF_ATQLEN1_ATQENABLE_MASK);
368 #endif /* INTEGRATED_VF */
369 return false;
370 }
371
372 /**
373 * iavf_aq_queue_shutdown
374 * @hw: pointer to the hw struct
375 * @unloading: is the driver unloading itself
376 *
377 * Tell the Firmware that we're shutting down the AdminQ and whether
378 * or not the driver is unloading as well.
379 **/
380 enum iavf_status_code iavf_aq_queue_shutdown(struct iavf_hw *hw,
381 bool unloading)
382 {
383 struct iavf_aq_desc desc;
384 struct iavf_aqc_queue_shutdown *cmd =
385 (struct iavf_aqc_queue_shutdown *)&desc.params.raw;
386 enum iavf_status_code status;
387
388 iavf_fill_default_direct_cmd_desc(&desc,
389 iavf_aqc_opc_queue_shutdown);
390
391 if (unloading)
392 cmd->driver_unloading = CPU_TO_LE32(IAVF_AQ_DRIVER_UNLOADING);
393 status = iavf_asq_send_command(hw, &desc, NULL, 0, NULL);
394
395 return status;
396 }
397
398 /**
399 * iavf_aq_get_set_rss_lut
400 * @hw: pointer to the hardware structure
401 * @vsi_id: vsi fw index
402 * @pf_lut: for PF table set true, for VSI table set false
403 * @lut: pointer to the lut buffer provided by the caller
404 * @lut_size: size of the lut buffer
405 * @set: set true to set the table, false to get the table
406 *
407 * Internal function to get or set RSS look up table
408 **/
409 STATIC enum iavf_status_code iavf_aq_get_set_rss_lut(struct iavf_hw *hw,
410 u16 vsi_id, bool pf_lut,
411 u8 *lut, u16 lut_size,
412 bool set)
413 {
414 enum iavf_status_code status;
415 struct iavf_aq_desc desc;
416 struct iavf_aqc_get_set_rss_lut *cmd_resp =
417 (struct iavf_aqc_get_set_rss_lut *)&desc.params.raw;
418
419 if (set)
420 iavf_fill_default_direct_cmd_desc(&desc,
421 iavf_aqc_opc_set_rss_lut);
422 else
423 iavf_fill_default_direct_cmd_desc(&desc,
424 iavf_aqc_opc_get_rss_lut);
425
426 /* Indirect command */
427 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_BUF);
428 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_RD);
429
430 cmd_resp->vsi_id =
431 CPU_TO_LE16((u16)((vsi_id <<
432 IAVF_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
433 IAVF_AQC_SET_RSS_LUT_VSI_ID_MASK));
434 cmd_resp->vsi_id |= CPU_TO_LE16((u16)IAVF_AQC_SET_RSS_LUT_VSI_VALID);
435
436 if (pf_lut)
437 cmd_resp->flags |= CPU_TO_LE16((u16)
438 ((IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
439 IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
440 IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
441 else
442 cmd_resp->flags |= CPU_TO_LE16((u16)
443 ((IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
444 IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
445 IAVF_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
446
447 status = iavf_asq_send_command(hw, &desc, lut, lut_size, NULL);
448
449 return status;
450 }
451
452 /**
453 * iavf_aq_get_rss_lut
454 * @hw: pointer to the hardware structure
455 * @vsi_id: vsi fw index
456 * @pf_lut: for PF table set true, for VSI table set false
457 * @lut: pointer to the lut buffer provided by the caller
458 * @lut_size: size of the lut buffer
459 *
460 * get the RSS lookup table, PF or VSI type
461 **/
462 enum iavf_status_code iavf_aq_get_rss_lut(struct iavf_hw *hw, u16 vsi_id,
463 bool pf_lut, u8 *lut, u16 lut_size)
464 {
465 return iavf_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
466 false);
467 }
468
469 /**
470 * iavf_aq_set_rss_lut
471 * @hw: pointer to the hardware structure
472 * @vsi_id: vsi fw index
473 * @pf_lut: for PF table set true, for VSI table set false
474 * @lut: pointer to the lut buffer provided by the caller
475 * @lut_size: size of the lut buffer
476 *
477 * set the RSS lookup table, PF or VSI type
478 **/
479 enum iavf_status_code iavf_aq_set_rss_lut(struct iavf_hw *hw, u16 vsi_id,
480 bool pf_lut, u8 *lut, u16 lut_size)
481 {
482 return iavf_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
483 }
484
485 /**
486 * iavf_aq_get_set_rss_key
487 * @hw: pointer to the hw struct
488 * @vsi_id: vsi fw index
489 * @key: pointer to key info struct
490 * @set: set true to set the key, false to get the key
491 *
492 * get the RSS key per VSI
493 **/
494 STATIC enum iavf_status_code iavf_aq_get_set_rss_key(struct iavf_hw *hw,
495 u16 vsi_id,
496 struct iavf_aqc_get_set_rss_key_data *key,
497 bool set)
498 {
499 enum iavf_status_code status;
500 struct iavf_aq_desc desc;
501 struct iavf_aqc_get_set_rss_key *cmd_resp =
502 (struct iavf_aqc_get_set_rss_key *)&desc.params.raw;
503 u16 key_size = sizeof(struct iavf_aqc_get_set_rss_key_data);
504
505 if (set)
506 iavf_fill_default_direct_cmd_desc(&desc,
507 iavf_aqc_opc_set_rss_key);
508 else
509 iavf_fill_default_direct_cmd_desc(&desc,
510 iavf_aqc_opc_get_rss_key);
511
512 /* Indirect command */
513 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_BUF);
514 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_RD);
515
516 cmd_resp->vsi_id =
517 CPU_TO_LE16((u16)((vsi_id <<
518 IAVF_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
519 IAVF_AQC_SET_RSS_KEY_VSI_ID_MASK));
520 cmd_resp->vsi_id |= CPU_TO_LE16((u16)IAVF_AQC_SET_RSS_KEY_VSI_VALID);
521
522 status = iavf_asq_send_command(hw, &desc, key, key_size, NULL);
523
524 return status;
525 }
526
527 /**
528 * iavf_aq_get_rss_key
529 * @hw: pointer to the hw struct
530 * @vsi_id: vsi fw index
531 * @key: pointer to key info struct
532 *
533 **/
534 enum iavf_status_code iavf_aq_get_rss_key(struct iavf_hw *hw,
535 u16 vsi_id,
536 struct iavf_aqc_get_set_rss_key_data *key)
537 {
538 return iavf_aq_get_set_rss_key(hw, vsi_id, key, false);
539 }
540
541 /**
542 * iavf_aq_set_rss_key
543 * @hw: pointer to the hw struct
544 * @vsi_id: vsi fw index
545 * @key: pointer to key info struct
546 *
547 * set the RSS key per VSI
548 **/
549 enum iavf_status_code iavf_aq_set_rss_key(struct iavf_hw *hw,
550 u16 vsi_id,
551 struct iavf_aqc_get_set_rss_key_data *key)
552 {
553 return iavf_aq_get_set_rss_key(hw, vsi_id, key, true);
554 }
555
556 /* The iavf_ptype_lookup table is used to convert from the 8-bit ptype in the
557 * hardware to a bit-field that can be used by SW to more easily determine the
558 * packet type.
559 *
560 * Macros are used to shorten the table lines and make this table human
561 * readable.
562 *
563 * We store the PTYPE in the top byte of the bit field - this is just so that
564 * we can check that the table doesn't have a row missing, as the index into
565 * the table should be the PTYPE.
566 *
567 * Typical work flow:
568 *
569 * IF NOT iavf_ptype_lookup[ptype].known
570 * THEN
571 * Packet is unknown
572 * ELSE IF iavf_ptype_lookup[ptype].outer_ip == IAVF_RX_PTYPE_OUTER_IP
573 * Use the rest of the fields to look at the tunnels, inner protocols, etc
574 * ELSE
575 * Use the enum iavf_rx_l2_ptype to decode the packet type
576 * ENDIF
577 */
578
579 /* macro to make the table lines short */
580 #define IAVF_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\
581 { PTYPE, \
582 1, \
583 IAVF_RX_PTYPE_OUTER_##OUTER_IP, \
584 IAVF_RX_PTYPE_OUTER_##OUTER_IP_VER, \
585 IAVF_RX_PTYPE_##OUTER_FRAG, \
586 IAVF_RX_PTYPE_TUNNEL_##T, \
587 IAVF_RX_PTYPE_TUNNEL_END_##TE, \
588 IAVF_RX_PTYPE_##TEF, \
589 IAVF_RX_PTYPE_INNER_PROT_##I, \
590 IAVF_RX_PTYPE_PAYLOAD_LAYER_##PL }
591
592 #define IAVF_PTT_UNUSED_ENTRY(PTYPE) \
593 { PTYPE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
594
595 /* shorter macros makes the table fit but are terse */
596 #define IAVF_RX_PTYPE_NOF IAVF_RX_PTYPE_NOT_FRAG
597 #define IAVF_RX_PTYPE_FRG IAVF_RX_PTYPE_FRAG
598 #define IAVF_RX_PTYPE_INNER_PROT_TS IAVF_RX_PTYPE_INNER_PROT_TIMESYNC
599
600 /* Lookup table mapping the HW PTYPE to the bit field for decoding */
601 struct iavf_rx_ptype_decoded iavf_ptype_lookup[] = {
602 /* L2 Packet types */
603 IAVF_PTT_UNUSED_ENTRY(0),
604 IAVF_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
605 IAVF_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, TS, PAY2),
606 IAVF_PTT(3, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
607 IAVF_PTT_UNUSED_ENTRY(4),
608 IAVF_PTT_UNUSED_ENTRY(5),
609 IAVF_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
610 IAVF_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
611 IAVF_PTT_UNUSED_ENTRY(8),
612 IAVF_PTT_UNUSED_ENTRY(9),
613 IAVF_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
614 IAVF_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
615 IAVF_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
616 IAVF_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
617 IAVF_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
618 IAVF_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
619 IAVF_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
620 IAVF_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
621 IAVF_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
622 IAVF_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
623 IAVF_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
624 IAVF_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
625
626 /* Non Tunneled IPv4 */
627 IAVF_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
628 IAVF_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
629 IAVF_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4),
630 IAVF_PTT_UNUSED_ENTRY(25),
631 IAVF_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4),
632 IAVF_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
633 IAVF_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
634
635 /* IPv4 --> IPv4 */
636 IAVF_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
637 IAVF_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
638 IAVF_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
639 IAVF_PTT_UNUSED_ENTRY(32),
640 IAVF_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
641 IAVF_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
642 IAVF_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
643
644 /* IPv4 --> IPv6 */
645 IAVF_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
646 IAVF_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
647 IAVF_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
648 IAVF_PTT_UNUSED_ENTRY(39),
649 IAVF_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
650 IAVF_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
651 IAVF_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
652
653 /* IPv4 --> GRE/NAT */
654 IAVF_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
655
656 /* IPv4 --> GRE/NAT --> IPv4 */
657 IAVF_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
658 IAVF_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
659 IAVF_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
660 IAVF_PTT_UNUSED_ENTRY(47),
661 IAVF_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
662 IAVF_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
663 IAVF_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
664
665 /* IPv4 --> GRE/NAT --> IPv6 */
666 IAVF_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
667 IAVF_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
668 IAVF_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
669 IAVF_PTT_UNUSED_ENTRY(54),
670 IAVF_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
671 IAVF_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
672 IAVF_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
673
674 /* IPv4 --> GRE/NAT --> MAC */
675 IAVF_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
676
677 /* IPv4 --> GRE/NAT --> MAC --> IPv4 */
678 IAVF_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
679 IAVF_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
680 IAVF_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
681 IAVF_PTT_UNUSED_ENTRY(62),
682 IAVF_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
683 IAVF_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
684 IAVF_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
685
686 /* IPv4 --> GRE/NAT -> MAC --> IPv6 */
687 IAVF_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
688 IAVF_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
689 IAVF_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
690 IAVF_PTT_UNUSED_ENTRY(69),
691 IAVF_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
692 IAVF_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
693 IAVF_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
694
695 /* IPv4 --> GRE/NAT --> MAC/VLAN */
696 IAVF_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
697
698 /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
699 IAVF_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
700 IAVF_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
701 IAVF_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
702 IAVF_PTT_UNUSED_ENTRY(77),
703 IAVF_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
704 IAVF_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
705 IAVF_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
706
707 /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
708 IAVF_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
709 IAVF_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
710 IAVF_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
711 IAVF_PTT_UNUSED_ENTRY(84),
712 IAVF_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
713 IAVF_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
714 IAVF_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
715
716 /* Non Tunneled IPv6 */
717 IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
718 IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
719 IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4),
720 IAVF_PTT_UNUSED_ENTRY(91),
721 IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4),
722 IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
723 IAVF_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
724
725 /* IPv6 --> IPv4 */
726 IAVF_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
727 IAVF_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
728 IAVF_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
729 IAVF_PTT_UNUSED_ENTRY(98),
730 IAVF_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
731 IAVF_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
732 IAVF_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
733
734 /* IPv6 --> IPv6 */
735 IAVF_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
736 IAVF_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
737 IAVF_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
738 IAVF_PTT_UNUSED_ENTRY(105),
739 IAVF_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
740 IAVF_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
741 IAVF_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
742
743 /* IPv6 --> GRE/NAT */
744 IAVF_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
745
746 /* IPv6 --> GRE/NAT -> IPv4 */
747 IAVF_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
748 IAVF_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
749 IAVF_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
750 IAVF_PTT_UNUSED_ENTRY(113),
751 IAVF_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
752 IAVF_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
753 IAVF_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
754
755 /* IPv6 --> GRE/NAT -> IPv6 */
756 IAVF_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
757 IAVF_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
758 IAVF_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
759 IAVF_PTT_UNUSED_ENTRY(120),
760 IAVF_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
761 IAVF_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
762 IAVF_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
763
764 /* IPv6 --> GRE/NAT -> MAC */
765 IAVF_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
766
767 /* IPv6 --> GRE/NAT -> MAC -> IPv4 */
768 IAVF_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
769 IAVF_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
770 IAVF_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
771 IAVF_PTT_UNUSED_ENTRY(128),
772 IAVF_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
773 IAVF_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
774 IAVF_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
775
776 /* IPv6 --> GRE/NAT -> MAC -> IPv6 */
777 IAVF_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
778 IAVF_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
779 IAVF_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
780 IAVF_PTT_UNUSED_ENTRY(135),
781 IAVF_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
782 IAVF_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
783 IAVF_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
784
785 /* IPv6 --> GRE/NAT -> MAC/VLAN */
786 IAVF_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
787
788 /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
789 IAVF_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
790 IAVF_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
791 IAVF_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
792 IAVF_PTT_UNUSED_ENTRY(143),
793 IAVF_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
794 IAVF_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
795 IAVF_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
796
797 /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
798 IAVF_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
799 IAVF_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
800 IAVF_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
801 IAVF_PTT_UNUSED_ENTRY(150),
802 IAVF_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
803 IAVF_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
804 IAVF_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
805
806 /* unused entries */
807 IAVF_PTT_UNUSED_ENTRY(154),
808 IAVF_PTT_UNUSED_ENTRY(155),
809 IAVF_PTT_UNUSED_ENTRY(156),
810 IAVF_PTT_UNUSED_ENTRY(157),
811 IAVF_PTT_UNUSED_ENTRY(158),
812 IAVF_PTT_UNUSED_ENTRY(159),
813
814 IAVF_PTT_UNUSED_ENTRY(160),
815 IAVF_PTT_UNUSED_ENTRY(161),
816 IAVF_PTT_UNUSED_ENTRY(162),
817 IAVF_PTT_UNUSED_ENTRY(163),
818 IAVF_PTT_UNUSED_ENTRY(164),
819 IAVF_PTT_UNUSED_ENTRY(165),
820 IAVF_PTT_UNUSED_ENTRY(166),
821 IAVF_PTT_UNUSED_ENTRY(167),
822 IAVF_PTT_UNUSED_ENTRY(168),
823 IAVF_PTT_UNUSED_ENTRY(169),
824
825 IAVF_PTT_UNUSED_ENTRY(170),
826 IAVF_PTT_UNUSED_ENTRY(171),
827 IAVF_PTT_UNUSED_ENTRY(172),
828 IAVF_PTT_UNUSED_ENTRY(173),
829 IAVF_PTT_UNUSED_ENTRY(174),
830 IAVF_PTT_UNUSED_ENTRY(175),
831 IAVF_PTT_UNUSED_ENTRY(176),
832 IAVF_PTT_UNUSED_ENTRY(177),
833 IAVF_PTT_UNUSED_ENTRY(178),
834 IAVF_PTT_UNUSED_ENTRY(179),
835
836 IAVF_PTT_UNUSED_ENTRY(180),
837 IAVF_PTT_UNUSED_ENTRY(181),
838 IAVF_PTT_UNUSED_ENTRY(182),
839 IAVF_PTT_UNUSED_ENTRY(183),
840 IAVF_PTT_UNUSED_ENTRY(184),
841 IAVF_PTT_UNUSED_ENTRY(185),
842 IAVF_PTT_UNUSED_ENTRY(186),
843 IAVF_PTT_UNUSED_ENTRY(187),
844 IAVF_PTT_UNUSED_ENTRY(188),
845 IAVF_PTT_UNUSED_ENTRY(189),
846
847 IAVF_PTT_UNUSED_ENTRY(190),
848 IAVF_PTT_UNUSED_ENTRY(191),
849 IAVF_PTT_UNUSED_ENTRY(192),
850 IAVF_PTT_UNUSED_ENTRY(193),
851 IAVF_PTT_UNUSED_ENTRY(194),
852 IAVF_PTT_UNUSED_ENTRY(195),
853 IAVF_PTT_UNUSED_ENTRY(196),
854 IAVF_PTT_UNUSED_ENTRY(197),
855 IAVF_PTT_UNUSED_ENTRY(198),
856 IAVF_PTT_UNUSED_ENTRY(199),
857
858 IAVF_PTT_UNUSED_ENTRY(200),
859 IAVF_PTT_UNUSED_ENTRY(201),
860 IAVF_PTT_UNUSED_ENTRY(202),
861 IAVF_PTT_UNUSED_ENTRY(203),
862 IAVF_PTT_UNUSED_ENTRY(204),
863 IAVF_PTT_UNUSED_ENTRY(205),
864 IAVF_PTT_UNUSED_ENTRY(206),
865 IAVF_PTT_UNUSED_ENTRY(207),
866 IAVF_PTT_UNUSED_ENTRY(208),
867 IAVF_PTT_UNUSED_ENTRY(209),
868
869 IAVF_PTT_UNUSED_ENTRY(210),
870 IAVF_PTT_UNUSED_ENTRY(211),
871 IAVF_PTT_UNUSED_ENTRY(212),
872 IAVF_PTT_UNUSED_ENTRY(213),
873 IAVF_PTT_UNUSED_ENTRY(214),
874 IAVF_PTT_UNUSED_ENTRY(215),
875 IAVF_PTT_UNUSED_ENTRY(216),
876 IAVF_PTT_UNUSED_ENTRY(217),
877 IAVF_PTT_UNUSED_ENTRY(218),
878 IAVF_PTT_UNUSED_ENTRY(219),
879
880 IAVF_PTT_UNUSED_ENTRY(220),
881 IAVF_PTT_UNUSED_ENTRY(221),
882 IAVF_PTT_UNUSED_ENTRY(222),
883 IAVF_PTT_UNUSED_ENTRY(223),
884 IAVF_PTT_UNUSED_ENTRY(224),
885 IAVF_PTT_UNUSED_ENTRY(225),
886 IAVF_PTT_UNUSED_ENTRY(226),
887 IAVF_PTT_UNUSED_ENTRY(227),
888 IAVF_PTT_UNUSED_ENTRY(228),
889 IAVF_PTT_UNUSED_ENTRY(229),
890
891 IAVF_PTT_UNUSED_ENTRY(230),
892 IAVF_PTT_UNUSED_ENTRY(231),
893 IAVF_PTT_UNUSED_ENTRY(232),
894 IAVF_PTT_UNUSED_ENTRY(233),
895 IAVF_PTT_UNUSED_ENTRY(234),
896 IAVF_PTT_UNUSED_ENTRY(235),
897 IAVF_PTT_UNUSED_ENTRY(236),
898 IAVF_PTT_UNUSED_ENTRY(237),
899 IAVF_PTT_UNUSED_ENTRY(238),
900 IAVF_PTT_UNUSED_ENTRY(239),
901
902 IAVF_PTT_UNUSED_ENTRY(240),
903 IAVF_PTT_UNUSED_ENTRY(241),
904 IAVF_PTT_UNUSED_ENTRY(242),
905 IAVF_PTT_UNUSED_ENTRY(243),
906 IAVF_PTT_UNUSED_ENTRY(244),
907 IAVF_PTT_UNUSED_ENTRY(245),
908 IAVF_PTT_UNUSED_ENTRY(246),
909 IAVF_PTT_UNUSED_ENTRY(247),
910 IAVF_PTT_UNUSED_ENTRY(248),
911 IAVF_PTT_UNUSED_ENTRY(249),
912
913 IAVF_PTT_UNUSED_ENTRY(250),
914 IAVF_PTT_UNUSED_ENTRY(251),
915 IAVF_PTT_UNUSED_ENTRY(252),
916 IAVF_PTT_UNUSED_ENTRY(253),
917 IAVF_PTT_UNUSED_ENTRY(254),
918 IAVF_PTT_UNUSED_ENTRY(255)
919 };
920
921
922 /**
923 * iavf_validate_mac_addr - Validate unicast MAC address
924 * @mac_addr: pointer to MAC address
925 *
926 * Tests a MAC address to ensure it is a valid Individual Address
927 **/
928 enum iavf_status_code iavf_validate_mac_addr(u8 *mac_addr)
929 {
930 enum iavf_status_code status = IAVF_SUCCESS;
931
932 DEBUGFUNC("iavf_validate_mac_addr");
933
934 /* Broadcast addresses ARE multicast addresses
935 * Make sure it is not a multicast address
936 * Reject the zero address
937 */
938 if (IAVF_IS_MULTICAST(mac_addr) ||
939 (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
940 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0))
941 status = IAVF_ERR_INVALID_MAC_ADDR;
942
943 return status;
944 }
945
946 /**
947 * iavf_aq_rx_ctl_read_register - use FW to read from an Rx control register
948 * @hw: pointer to the hw struct
949 * @reg_addr: register address
950 * @reg_val: ptr to register value
951 * @cmd_details: pointer to command details structure or NULL
952 *
953 * Use the firmware to read the Rx control register,
954 * especially useful if the Rx unit is under heavy pressure
955 **/
956 enum iavf_status_code iavf_aq_rx_ctl_read_register(struct iavf_hw *hw,
957 u32 reg_addr, u32 *reg_val,
958 struct iavf_asq_cmd_details *cmd_details)
959 {
960 struct iavf_aq_desc desc;
961 struct iavf_aqc_rx_ctl_reg_read_write *cmd_resp =
962 (struct iavf_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
963 enum iavf_status_code status;
964
965 if (reg_val == NULL)
966 return IAVF_ERR_PARAM;
967
968 iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_rx_ctl_reg_read);
969
970 cmd_resp->address = CPU_TO_LE32(reg_addr);
971
972 status = iavf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
973
974 if (status == IAVF_SUCCESS)
975 *reg_val = LE32_TO_CPU(cmd_resp->value);
976
977 return status;
978 }
979
980 /**
981 * iavf_read_rx_ctl - read from an Rx control register
982 * @hw: pointer to the hw struct
983 * @reg_addr: register address
984 **/
985 u32 iavf_read_rx_ctl(struct iavf_hw *hw, u32 reg_addr)
986 {
987 enum iavf_status_code status = IAVF_SUCCESS;
988 bool use_register;
989 int retry = 5;
990 u32 val = 0;
991
992 use_register = (((hw->aq.api_maj_ver == 1) &&
993 (hw->aq.api_min_ver < 5)) ||
994 (hw->mac.type == IAVF_MAC_X722));
995 if (!use_register) {
996 do_retry:
997 status = iavf_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
998 if (hw->aq.asq_last_status == IAVF_AQ_RC_EAGAIN && retry) {
999 iavf_msec_delay(1);
1000 retry--;
1001 goto do_retry;
1002 }
1003 }
1004
1005 /* if the AQ access failed, try the old-fashioned way */
1006 if (status || use_register)
1007 val = rd32(hw, reg_addr);
1008
1009 return val;
1010 }
1011
1012 /**
1013 * iavf_aq_rx_ctl_write_register
1014 * @hw: pointer to the hw struct
1015 * @reg_addr: register address
1016 * @reg_val: register value
1017 * @cmd_details: pointer to command details structure or NULL
1018 *
1019 * Use the firmware to write to an Rx control register,
1020 * especially useful if the Rx unit is under heavy pressure
1021 **/
1022 enum iavf_status_code iavf_aq_rx_ctl_write_register(struct iavf_hw *hw,
1023 u32 reg_addr, u32 reg_val,
1024 struct iavf_asq_cmd_details *cmd_details)
1025 {
1026 struct iavf_aq_desc desc;
1027 struct iavf_aqc_rx_ctl_reg_read_write *cmd =
1028 (struct iavf_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
1029 enum iavf_status_code status;
1030
1031 iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_rx_ctl_reg_write);
1032
1033 cmd->address = CPU_TO_LE32(reg_addr);
1034 cmd->value = CPU_TO_LE32(reg_val);
1035
1036 status = iavf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1037
1038 return status;
1039 }
1040
1041 /**
1042 * iavf_write_rx_ctl - write to an Rx control register
1043 * @hw: pointer to the hw struct
1044 * @reg_addr: register address
1045 * @reg_val: register value
1046 **/
1047 void iavf_write_rx_ctl(struct iavf_hw *hw, u32 reg_addr, u32 reg_val)
1048 {
1049 enum iavf_status_code status = IAVF_SUCCESS;
1050 bool use_register;
1051 int retry = 5;
1052
1053 use_register = (((hw->aq.api_maj_ver == 1) &&
1054 (hw->aq.api_min_ver < 5)) ||
1055 (hw->mac.type == IAVF_MAC_X722));
1056 if (!use_register) {
1057 do_retry:
1058 status = iavf_aq_rx_ctl_write_register(hw, reg_addr,
1059 reg_val, NULL);
1060 if (hw->aq.asq_last_status == IAVF_AQ_RC_EAGAIN && retry) {
1061 iavf_msec_delay(1);
1062 retry--;
1063 goto do_retry;
1064 }
1065 }
1066
1067 /* if the AQ access failed, try the old-fashioned way */
1068 if (status || use_register)
1069 wr32(hw, reg_addr, reg_val);
1070 }
1071
1072 /**
1073 * iavf_aq_set_phy_register
1074 * @hw: pointer to the hw struct
1075 * @phy_select: select which phy should be accessed
1076 * @dev_addr: PHY device address
1077 * @reg_addr: PHY register address
1078 * @reg_val: new register value
1079 * @cmd_details: pointer to command details structure or NULL
1080 *
1081 * Write the external PHY register.
1082 **/
1083 enum iavf_status_code iavf_aq_set_phy_register(struct iavf_hw *hw,
1084 u8 phy_select, u8 dev_addr,
1085 u32 reg_addr, u32 reg_val,
1086 struct iavf_asq_cmd_details *cmd_details)
1087 {
1088 struct iavf_aq_desc desc;
1089 struct iavf_aqc_phy_register_access *cmd =
1090 (struct iavf_aqc_phy_register_access *)&desc.params.raw;
1091 enum iavf_status_code status;
1092
1093 iavf_fill_default_direct_cmd_desc(&desc,
1094 iavf_aqc_opc_set_phy_register);
1095
1096 cmd->phy_interface = phy_select;
1097 cmd->dev_addres = dev_addr;
1098 cmd->reg_address = CPU_TO_LE32(reg_addr);
1099 cmd->reg_value = CPU_TO_LE32(reg_val);
1100
1101 status = iavf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1102
1103 return status;
1104 }
1105
1106 /**
1107 * iavf_aq_get_phy_register
1108 * @hw: pointer to the hw struct
1109 * @phy_select: select which phy should be accessed
1110 * @dev_addr: PHY device address
1111 * @reg_addr: PHY register address
1112 * @reg_val: read register value
1113 * @cmd_details: pointer to command details structure or NULL
1114 *
1115 * Read the external PHY register.
1116 **/
1117 enum iavf_status_code iavf_aq_get_phy_register(struct iavf_hw *hw,
1118 u8 phy_select, u8 dev_addr,
1119 u32 reg_addr, u32 *reg_val,
1120 struct iavf_asq_cmd_details *cmd_details)
1121 {
1122 struct iavf_aq_desc desc;
1123 struct iavf_aqc_phy_register_access *cmd =
1124 (struct iavf_aqc_phy_register_access *)&desc.params.raw;
1125 enum iavf_status_code status;
1126
1127 iavf_fill_default_direct_cmd_desc(&desc,
1128 iavf_aqc_opc_get_phy_register);
1129
1130 cmd->phy_interface = phy_select;
1131 cmd->dev_addres = dev_addr;
1132 cmd->reg_address = CPU_TO_LE32(reg_addr);
1133
1134 status = iavf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1135 if (!status)
1136 *reg_val = LE32_TO_CPU(cmd->reg_value);
1137
1138 return status;
1139 }
1140
1141
1142 /**
1143 * iavf_aq_send_msg_to_pf
1144 * @hw: pointer to the hardware structure
1145 * @v_opcode: opcodes for VF-PF communication
1146 * @v_retval: return error code
1147 * @msg: pointer to the msg buffer
1148 * @msglen: msg length
1149 * @cmd_details: pointer to command details
1150 *
1151 * Send message to PF driver using admin queue. By default, this message
1152 * is sent asynchronously, i.e. iavf_asq_send_command() does not wait for
1153 * completion before returning.
1154 **/
1155 enum iavf_status_code iavf_aq_send_msg_to_pf(struct iavf_hw *hw,
1156 enum virtchnl_ops v_opcode,
1157 enum iavf_status_code v_retval,
1158 u8 *msg, u16 msglen,
1159 struct iavf_asq_cmd_details *cmd_details)
1160 {
1161 struct iavf_aq_desc desc;
1162 struct iavf_asq_cmd_details details;
1163 enum iavf_status_code status;
1164
1165 iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_send_msg_to_pf);
1166 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_SI);
1167 desc.cookie_high = CPU_TO_LE32(v_opcode);
1168 desc.cookie_low = CPU_TO_LE32(v_retval);
1169 if (msglen) {
1170 desc.flags |= CPU_TO_LE16((u16)(IAVF_AQ_FLAG_BUF
1171 | IAVF_AQ_FLAG_RD));
1172 if (msglen > IAVF_AQ_LARGE_BUF)
1173 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_LB);
1174 desc.datalen = CPU_TO_LE16(msglen);
1175 }
1176 if (!cmd_details) {
1177 iavf_memset(&details, 0, sizeof(details), IAVF_NONDMA_MEM);
1178 details.async = true;
1179 cmd_details = &details;
1180 }
1181 status = iavf_asq_send_command(hw, (struct iavf_aq_desc *)&desc, msg,
1182 msglen, cmd_details);
1183 return status;
1184 }
1185
1186 /**
1187 * iavf_parse_hw_config
1188 * @hw: pointer to the hardware structure
1189 * @msg: pointer to the virtual channel VF resource structure
1190 *
1191 * Given a VF resource message from the PF, populate the hw struct
1192 * with appropriate information.
1193 **/
1194 void iavf_parse_hw_config(struct iavf_hw *hw,
1195 struct virtchnl_vf_resource *msg)
1196 {
1197 struct virtchnl_vsi_resource *vsi_res;
1198 int i;
1199
1200 vsi_res = &msg->vsi_res[0];
1201
1202 hw->dev_caps.num_vsis = msg->num_vsis;
1203 hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
1204 hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
1205 hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
1206 hw->dev_caps.dcb = msg->vf_cap_flags &
1207 VIRTCHNL_VF_OFFLOAD_L2;
1208 hw->dev_caps.iwarp = (msg->vf_cap_flags &
1209 VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
1210 for (i = 0; i < msg->num_vsis; i++) {
1211 if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
1212 iavf_memcpy(hw->mac.perm_addr,
1213 vsi_res->default_mac_addr,
1214 ETH_ALEN,
1215 IAVF_NONDMA_TO_NONDMA);
1216 iavf_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
1217 ETH_ALEN,
1218 IAVF_NONDMA_TO_NONDMA);
1219 }
1220 vsi_res++;
1221 }
1222 }
1223
1224 /**
1225 * iavf_reset
1226 * @hw: pointer to the hardware structure
1227 *
1228 * Send a VF_RESET message to the PF. Does not wait for response from PF
1229 * as none will be forthcoming. Immediately after calling this function,
1230 * the admin queue should be shut down and (optionally) reinitialized.
1231 **/
1232 enum iavf_status_code iavf_reset(struct iavf_hw *hw)
1233 {
1234 return iavf_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
1235 IAVF_SUCCESS, NULL, 0, NULL);
1236 }
1237
1238 /**
1239 * iavf_aq_set_arp_proxy_config
1240 * @hw: pointer to the HW structure
1241 * @proxy_config: pointer to proxy config command table struct
1242 * @cmd_details: pointer to command details
1243 *
1244 * Set ARP offload parameters from pre-populated
1245 * iavf_aqc_arp_proxy_data struct
1246 **/
1247 enum iavf_status_code iavf_aq_set_arp_proxy_config(struct iavf_hw *hw,
1248 struct iavf_aqc_arp_proxy_data *proxy_config,
1249 struct iavf_asq_cmd_details *cmd_details)
1250 {
1251 struct iavf_aq_desc desc;
1252 enum iavf_status_code status;
1253
1254 if (!proxy_config)
1255 return IAVF_ERR_PARAM;
1256
1257 iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_set_proxy_config);
1258
1259 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_BUF);
1260 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_RD);
1261 desc.params.external.addr_high =
1262 CPU_TO_LE32(IAVF_HI_DWORD((u64)proxy_config));
1263 desc.params.external.addr_low =
1264 CPU_TO_LE32(IAVF_LO_DWORD((u64)proxy_config));
1265 desc.datalen = CPU_TO_LE16(sizeof(struct iavf_aqc_arp_proxy_data));
1266
1267 status = iavf_asq_send_command(hw, &desc, proxy_config,
1268 sizeof(struct iavf_aqc_arp_proxy_data),
1269 cmd_details);
1270
1271 return status;
1272 }
1273
1274 /**
1275 * iavf_aq_opc_set_ns_proxy_table_entry
1276 * @hw: pointer to the HW structure
1277 * @ns_proxy_table_entry: pointer to NS table entry command struct
1278 * @cmd_details: pointer to command details
1279 *
1280 * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
1281 * from pre-populated iavf_aqc_ns_proxy_data struct
1282 **/
1283 enum iavf_status_code iavf_aq_set_ns_proxy_table_entry(struct iavf_hw *hw,
1284 struct iavf_aqc_ns_proxy_data *ns_proxy_table_entry,
1285 struct iavf_asq_cmd_details *cmd_details)
1286 {
1287 struct iavf_aq_desc desc;
1288 enum iavf_status_code status;
1289
1290 if (!ns_proxy_table_entry)
1291 return IAVF_ERR_PARAM;
1292
1293 iavf_fill_default_direct_cmd_desc(&desc,
1294 iavf_aqc_opc_set_ns_proxy_table_entry);
1295
1296 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_BUF);
1297 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_RD);
1298 desc.params.external.addr_high =
1299 CPU_TO_LE32(IAVF_HI_DWORD((u64)ns_proxy_table_entry));
1300 desc.params.external.addr_low =
1301 CPU_TO_LE32(IAVF_LO_DWORD((u64)ns_proxy_table_entry));
1302 desc.datalen = CPU_TO_LE16(sizeof(struct iavf_aqc_ns_proxy_data));
1303
1304 status = iavf_asq_send_command(hw, &desc, ns_proxy_table_entry,
1305 sizeof(struct iavf_aqc_ns_proxy_data),
1306 cmd_details);
1307
1308 return status;
1309 }
1310
1311 /**
1312 * iavf_aq_set_clear_wol_filter
1313 * @hw: pointer to the hw struct
1314 * @filter_index: index of filter to modify (0-7)
1315 * @filter: buffer containing filter to be set
1316 * @set_filter: true to set filter, false to clear filter
1317 * @no_wol_tco: if true, pass through packets cannot cause wake-up
1318 * if false, pass through packets may cause wake-up
1319 * @filter_valid: true if filter action is valid
1320 * @no_wol_tco_valid: true if no WoL in TCO traffic action valid
1321 * @cmd_details: pointer to command details structure or NULL
1322 *
1323 * Set or clear WoL filter for port attached to the PF
1324 **/
1325 enum iavf_status_code iavf_aq_set_clear_wol_filter(struct iavf_hw *hw,
1326 u8 filter_index,
1327 struct iavf_aqc_set_wol_filter_data *filter,
1328 bool set_filter, bool no_wol_tco,
1329 bool filter_valid, bool no_wol_tco_valid,
1330 struct iavf_asq_cmd_details *cmd_details)
1331 {
1332 struct iavf_aq_desc desc;
1333 struct iavf_aqc_set_wol_filter *cmd =
1334 (struct iavf_aqc_set_wol_filter *)&desc.params.raw;
1335 enum iavf_status_code status;
1336 u16 cmd_flags = 0;
1337 u16 valid_flags = 0;
1338 u16 buff_len = 0;
1339
1340 iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_set_wol_filter);
1341
1342 if (filter_index >= IAVF_AQC_MAX_NUM_WOL_FILTERS)
1343 return IAVF_ERR_PARAM;
1344 cmd->filter_index = CPU_TO_LE16(filter_index);
1345
1346 if (set_filter) {
1347 if (!filter)
1348 return IAVF_ERR_PARAM;
1349
1350 cmd_flags |= IAVF_AQC_SET_WOL_FILTER;
1351 cmd_flags |= IAVF_AQC_SET_WOL_FILTER_WOL_PRESERVE_ON_PFR;
1352 }
1353
1354 if (no_wol_tco)
1355 cmd_flags |= IAVF_AQC_SET_WOL_FILTER_NO_TCO_WOL;
1356 cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
1357
1358 if (filter_valid)
1359 valid_flags |= IAVF_AQC_SET_WOL_FILTER_ACTION_VALID;
1360 if (no_wol_tco_valid)
1361 valid_flags |= IAVF_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
1362 cmd->valid_flags = CPU_TO_LE16(valid_flags);
1363
1364 buff_len = sizeof(*filter);
1365 desc.datalen = CPU_TO_LE16(buff_len);
1366
1367 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_BUF);
1368 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_RD);
1369
1370 cmd->address_high = CPU_TO_LE32(IAVF_HI_DWORD((u64)filter));
1371 cmd->address_low = CPU_TO_LE32(IAVF_LO_DWORD((u64)filter));
1372
1373 status = iavf_asq_send_command(hw, &desc, filter,
1374 buff_len, cmd_details);
1375
1376 return status;
1377 }
1378
1379 /**
1380 * iavf_aq_get_wake_event_reason
1381 * @hw: pointer to the hw struct
1382 * @wake_reason: return value, index of matching filter
1383 * @cmd_details: pointer to command details structure or NULL
1384 *
1385 * Get information for the reason of a Wake Up event
1386 **/
1387 enum iavf_status_code iavf_aq_get_wake_event_reason(struct iavf_hw *hw,
1388 u16 *wake_reason,
1389 struct iavf_asq_cmd_details *cmd_details)
1390 {
1391 struct iavf_aq_desc desc;
1392 struct iavf_aqc_get_wake_reason_completion *resp =
1393 (struct iavf_aqc_get_wake_reason_completion *)&desc.params.raw;
1394 enum iavf_status_code status;
1395
1396 iavf_fill_default_direct_cmd_desc(&desc, iavf_aqc_opc_get_wake_reason);
1397
1398 status = iavf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1399
1400 if (status == IAVF_SUCCESS)
1401 *wake_reason = LE16_TO_CPU(resp->wake_reason);
1402
1403 return status;
1404 }
1405
1406 /**
1407 * iavf_aq_clear_all_wol_filters
1408 * @hw: pointer to the hw struct
1409 * @cmd_details: pointer to command details structure or NULL
1410 *
1411 * Get information for the reason of a Wake Up event
1412 **/
1413 enum iavf_status_code iavf_aq_clear_all_wol_filters(struct iavf_hw *hw,
1414 struct iavf_asq_cmd_details *cmd_details)
1415 {
1416 struct iavf_aq_desc desc;
1417 enum iavf_status_code status;
1418
1419 iavf_fill_default_direct_cmd_desc(&desc,
1420 iavf_aqc_opc_clear_all_wol_filters);
1421
1422 status = iavf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1423
1424 return status;
1425 }
1426
1427 /**
1428 * iavf_aq_write_ddp - Write dynamic device personalization (ddp)
1429 * @hw: pointer to the hw struct
1430 * @buff: command buffer (size in bytes = buff_size)
1431 * @buff_size: buffer size in bytes
1432 * @track_id: package tracking id
1433 * @error_offset: returns error offset
1434 * @error_info: returns error information
1435 * @cmd_details: pointer to command details structure or NULL
1436 **/
1437 enum
1438 iavf_status_code iavf_aq_write_ddp(struct iavf_hw *hw, void *buff,
1439 u16 buff_size, u32 track_id,
1440 u32 *error_offset, u32 *error_info,
1441 struct iavf_asq_cmd_details *cmd_details)
1442 {
1443 struct iavf_aq_desc desc;
1444 struct iavf_aqc_write_personalization_profile *cmd =
1445 (struct iavf_aqc_write_personalization_profile *)
1446 &desc.params.raw;
1447 struct iavf_aqc_write_ddp_resp *resp;
1448 enum iavf_status_code status;
1449
1450 iavf_fill_default_direct_cmd_desc(&desc,
1451 iavf_aqc_opc_write_personalization_profile);
1452
1453 desc.flags |= CPU_TO_LE16(IAVF_AQ_FLAG_BUF | IAVF_AQ_FLAG_RD);
1454 if (buff_size > IAVF_AQ_LARGE_BUF)
1455 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_LB);
1456
1457 desc.datalen = CPU_TO_LE16(buff_size);
1458
1459 cmd->profile_track_id = CPU_TO_LE32(track_id);
1460
1461 status = iavf_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
1462 if (!status) {
1463 resp = (struct iavf_aqc_write_ddp_resp *)&desc.params.raw;
1464 if (error_offset)
1465 *error_offset = LE32_TO_CPU(resp->error_offset);
1466 if (error_info)
1467 *error_info = LE32_TO_CPU(resp->error_info);
1468 }
1469
1470 return status;
1471 }
1472
1473 /**
1474 * iavf_aq_get_ddp_list - Read dynamic device personalization (ddp)
1475 * @hw: pointer to the hw struct
1476 * @buff: command buffer (size in bytes = buff_size)
1477 * @buff_size: buffer size in bytes
1478 * @flags: AdminQ command flags
1479 * @cmd_details: pointer to command details structure or NULL
1480 **/
1481 enum
1482 iavf_status_code iavf_aq_get_ddp_list(struct iavf_hw *hw, void *buff,
1483 u16 buff_size, u8 flags,
1484 struct iavf_asq_cmd_details *cmd_details)
1485 {
1486 struct iavf_aq_desc desc;
1487 struct iavf_aqc_get_applied_profiles *cmd =
1488 (struct iavf_aqc_get_applied_profiles *)&desc.params.raw;
1489 enum iavf_status_code status;
1490
1491 iavf_fill_default_direct_cmd_desc(&desc,
1492 iavf_aqc_opc_get_personalization_profile_list);
1493
1494 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_BUF);
1495 if (buff_size > IAVF_AQ_LARGE_BUF)
1496 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_LB);
1497 desc.datalen = CPU_TO_LE16(buff_size);
1498
1499 cmd->flags = flags;
1500
1501 status = iavf_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
1502
1503 return status;
1504 }
1505
1506 /**
1507 * iavf_find_segment_in_package
1508 * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_IAVF)
1509 * @pkg_hdr: pointer to the package header to be searched
1510 *
1511 * This function searches a package file for a particular segment type. On
1512 * success it returns a pointer to the segment header, otherwise it will
1513 * return NULL.
1514 **/
1515 struct iavf_generic_seg_header *
1516 iavf_find_segment_in_package(u32 segment_type,
1517 struct iavf_package_header *pkg_hdr)
1518 {
1519 struct iavf_generic_seg_header *segment;
1520 u32 i;
1521
1522 /* Search all package segments for the requested segment type */
1523 for (i = 0; i < pkg_hdr->segment_count; i++) {
1524 segment =
1525 (struct iavf_generic_seg_header *)((u8 *)pkg_hdr +
1526 pkg_hdr->segment_offset[i]);
1527
1528 if (segment->type == segment_type)
1529 return segment;
1530 }
1531
1532 return NULL;
1533 }
1534
1535 /* Get section table in profile */
1536 #define IAVF_SECTION_TABLE(profile, sec_tbl) \
1537 do { \
1538 struct iavf_profile_segment *p = (profile); \
1539 u32 count; \
1540 u32 *nvm; \
1541 count = p->device_table_count; \
1542 nvm = (u32 *)&p->device_table[count]; \
1543 sec_tbl = (struct iavf_section_table *)&nvm[nvm[0] + 1]; \
1544 } while (0)
1545
1546 /* Get section header in profile */
1547 #define IAVF_SECTION_HEADER(profile, offset) \
1548 (struct iavf_profile_section_header *)((u8 *)(profile) + (offset))
1549
1550 /**
1551 * iavf_find_section_in_profile
1552 * @section_type: the section type to search for (i.e., SECTION_TYPE_NOTE)
1553 * @profile: pointer to the iavf segment header to be searched
1554 *
1555 * This function searches iavf segment for a particular section type. On
1556 * success it returns a pointer to the section header, otherwise it will
1557 * return NULL.
1558 **/
1559 struct iavf_profile_section_header *
1560 iavf_find_section_in_profile(u32 section_type,
1561 struct iavf_profile_segment *profile)
1562 {
1563 struct iavf_profile_section_header *sec;
1564 struct iavf_section_table *sec_tbl;
1565 u32 sec_off;
1566 u32 i;
1567
1568 if (profile->header.type != SEGMENT_TYPE_IAVF)
1569 return NULL;
1570
1571 IAVF_SECTION_TABLE(profile, sec_tbl);
1572
1573 for (i = 0; i < sec_tbl->section_count; i++) {
1574 sec_off = sec_tbl->section_offset[i];
1575 sec = IAVF_SECTION_HEADER(profile, sec_off);
1576 if (sec->section.type == section_type)
1577 return sec;
1578 }
1579
1580 return NULL;
1581 }
1582
1583 /**
1584 * iavf_ddp_exec_aq_section - Execute generic AQ for DDP
1585 * @hw: pointer to the hw struct
1586 * @aq: command buffer containing all data to execute AQ
1587 **/
1588 STATIC enum
1589 iavf_status_code iavf_ddp_exec_aq_section(struct iavf_hw *hw,
1590 struct iavf_profile_aq_section *aq)
1591 {
1592 enum iavf_status_code status;
1593 struct iavf_aq_desc desc;
1594 u8 *msg = NULL;
1595 u16 msglen;
1596
1597 iavf_fill_default_direct_cmd_desc(&desc, aq->opcode);
1598 desc.flags |= CPU_TO_LE16(aq->flags);
1599 iavf_memcpy(desc.params.raw, aq->param, sizeof(desc.params.raw),
1600 IAVF_NONDMA_TO_NONDMA);
1601
1602 msglen = aq->datalen;
1603 if (msglen) {
1604 desc.flags |= CPU_TO_LE16((u16)(IAVF_AQ_FLAG_BUF |
1605 IAVF_AQ_FLAG_RD));
1606 if (msglen > IAVF_AQ_LARGE_BUF)
1607 desc.flags |= CPU_TO_LE16((u16)IAVF_AQ_FLAG_LB);
1608 desc.datalen = CPU_TO_LE16(msglen);
1609 msg = &aq->data[0];
1610 }
1611
1612 status = iavf_asq_send_command(hw, &desc, msg, msglen, NULL);
1613
1614 if (status != IAVF_SUCCESS) {
1615 iavf_debug(hw, IAVF_DEBUG_PACKAGE,
1616 "unable to exec DDP AQ opcode %u, error %d\n",
1617 aq->opcode, status);
1618 return status;
1619 }
1620
1621 /* copy returned desc to aq_buf */
1622 iavf_memcpy(aq->param, desc.params.raw, sizeof(desc.params.raw),
1623 IAVF_NONDMA_TO_NONDMA);
1624
1625 return IAVF_SUCCESS;
1626 }
1627
1628 /**
1629 * iavf_validate_profile
1630 * @hw: pointer to the hardware structure
1631 * @profile: pointer to the profile segment of the package to be validated
1632 * @track_id: package tracking id
1633 * @rollback: flag if the profile is for rollback.
1634 *
1635 * Validates supported devices and profile's sections.
1636 */
1637 STATIC enum iavf_status_code
1638 iavf_validate_profile(struct iavf_hw *hw, struct iavf_profile_segment *profile,
1639 u32 track_id, bool rollback)
1640 {
1641 struct iavf_profile_section_header *sec = NULL;
1642 enum iavf_status_code status = IAVF_SUCCESS;
1643 struct iavf_section_table *sec_tbl;
1644 u32 vendor_dev_id;
1645 u32 dev_cnt;
1646 u32 sec_off;
1647 u32 i;
1648
1649 if (track_id == IAVF_DDP_TRACKID_INVALID) {
1650 iavf_debug(hw, IAVF_DEBUG_PACKAGE, "Invalid track_id\n");
1651 return IAVF_NOT_SUPPORTED;
1652 }
1653
1654 dev_cnt = profile->device_table_count;
1655 for (i = 0; i < dev_cnt; i++) {
1656 vendor_dev_id = profile->device_table[i].vendor_dev_id;
1657 if ((vendor_dev_id >> 16) == IAVF_INTEL_VENDOR_ID &&
1658 hw->device_id == (vendor_dev_id & 0xFFFF))
1659 break;
1660 }
1661 if (dev_cnt && (i == dev_cnt)) {
1662 iavf_debug(hw, IAVF_DEBUG_PACKAGE,
1663 "Device doesn't support DDP\n");
1664 return IAVF_ERR_DEVICE_NOT_SUPPORTED;
1665 }
1666
1667 IAVF_SECTION_TABLE(profile, sec_tbl);
1668
1669 /* Validate sections types */
1670 for (i = 0; i < sec_tbl->section_count; i++) {
1671 sec_off = sec_tbl->section_offset[i];
1672 sec = IAVF_SECTION_HEADER(profile, sec_off);
1673 if (rollback) {
1674 if (sec->section.type == SECTION_TYPE_MMIO ||
1675 sec->section.type == SECTION_TYPE_AQ ||
1676 sec->section.type == SECTION_TYPE_RB_AQ) {
1677 iavf_debug(hw, IAVF_DEBUG_PACKAGE,
1678 "Not a roll-back package\n");
1679 return IAVF_NOT_SUPPORTED;
1680 }
1681 } else {
1682 if (sec->section.type == SECTION_TYPE_RB_AQ ||
1683 sec->section.type == SECTION_TYPE_RB_MMIO) {
1684 iavf_debug(hw, IAVF_DEBUG_PACKAGE,
1685 "Not an original package\n");
1686 return IAVF_NOT_SUPPORTED;
1687 }
1688 }
1689 }
1690
1691 return status;
1692 }
1693
1694 /**
1695 * iavf_write_profile
1696 * @hw: pointer to the hardware structure
1697 * @profile: pointer to the profile segment of the package to be downloaded
1698 * @track_id: package tracking id
1699 *
1700 * Handles the download of a complete package.
1701 */
1702 enum iavf_status_code
1703 iavf_write_profile(struct iavf_hw *hw, struct iavf_profile_segment *profile,
1704 u32 track_id)
1705 {
1706 enum iavf_status_code status = IAVF_SUCCESS;
1707 struct iavf_section_table *sec_tbl;
1708 struct iavf_profile_section_header *sec = NULL;
1709 struct iavf_profile_aq_section *ddp_aq;
1710 u32 section_size = 0;
1711 u32 offset = 0, info = 0;
1712 u32 sec_off;
1713 u32 i;
1714
1715 status = iavf_validate_profile(hw, profile, track_id, false);
1716 if (status)
1717 return status;
1718
1719 IAVF_SECTION_TABLE(profile, sec_tbl);
1720
1721 for (i = 0; i < sec_tbl->section_count; i++) {
1722 sec_off = sec_tbl->section_offset[i];
1723 sec = IAVF_SECTION_HEADER(profile, sec_off);
1724 /* Process generic admin command */
1725 if (sec->section.type == SECTION_TYPE_AQ) {
1726 ddp_aq = (struct iavf_profile_aq_section *)&sec[1];
1727 status = iavf_ddp_exec_aq_section(hw, ddp_aq);
1728 if (status) {
1729 iavf_debug(hw, IAVF_DEBUG_PACKAGE,
1730 "Failed to execute aq: section %d, opcode %u\n",
1731 i, ddp_aq->opcode);
1732 break;
1733 }
1734 sec->section.type = SECTION_TYPE_RB_AQ;
1735 }
1736
1737 /* Skip any non-mmio sections */
1738 if (sec->section.type != SECTION_TYPE_MMIO)
1739 continue;
1740
1741 section_size = sec->section.size +
1742 sizeof(struct iavf_profile_section_header);
1743
1744 /* Write MMIO section */
1745 status = iavf_aq_write_ddp(hw, (void *)sec, (u16)section_size,
1746 track_id, &offset, &info, NULL);
1747 if (status) {
1748 iavf_debug(hw, IAVF_DEBUG_PACKAGE,
1749 "Failed to write profile: section %d, offset %d, info %d\n",
1750 i, offset, info);
1751 break;
1752 }
1753 }
1754 return status;
1755 }
1756
1757 /**
1758 * iavf_rollback_profile
1759 * @hw: pointer to the hardware structure
1760 * @profile: pointer to the profile segment of the package to be removed
1761 * @track_id: package tracking id
1762 *
1763 * Rolls back previously loaded package.
1764 */
1765 enum iavf_status_code
1766 iavf_rollback_profile(struct iavf_hw *hw, struct iavf_profile_segment *profile,
1767 u32 track_id)
1768 {
1769 struct iavf_profile_section_header *sec = NULL;
1770 enum iavf_status_code status = IAVF_SUCCESS;
1771 struct iavf_section_table *sec_tbl;
1772 u32 offset = 0, info = 0;
1773 u32 section_size = 0;
1774 u32 sec_off;
1775 int i;
1776
1777 status = iavf_validate_profile(hw, profile, track_id, true);
1778 if (status)
1779 return status;
1780
1781 IAVF_SECTION_TABLE(profile, sec_tbl);
1782
1783 /* For rollback write sections in reverse */
1784 for (i = sec_tbl->section_count - 1; i >= 0; i--) {
1785 sec_off = sec_tbl->section_offset[i];
1786 sec = IAVF_SECTION_HEADER(profile, sec_off);
1787
1788 /* Skip any non-rollback sections */
1789 if (sec->section.type != SECTION_TYPE_RB_MMIO)
1790 continue;
1791
1792 section_size = sec->section.size +
1793 sizeof(struct iavf_profile_section_header);
1794
1795 /* Write roll-back MMIO section */
1796 status = iavf_aq_write_ddp(hw, (void *)sec, (u16)section_size,
1797 track_id, &offset, &info, NULL);
1798 if (status) {
1799 iavf_debug(hw, IAVF_DEBUG_PACKAGE,
1800 "Failed to write profile: section %d, offset %d, info %d\n",
1801 i, offset, info);
1802 break;
1803 }
1804 }
1805 return status;
1806 }
1807
1808 /**
1809 * iavf_add_pinfo_to_list
1810 * @hw: pointer to the hardware structure
1811 * @profile: pointer to the profile segment of the package
1812 * @profile_info_sec: buffer for information section
1813 * @track_id: package tracking id
1814 *
1815 * Register a profile to the list of loaded profiles.
1816 */
1817 enum iavf_status_code
1818 iavf_add_pinfo_to_list(struct iavf_hw *hw,
1819 struct iavf_profile_segment *profile,
1820 u8 *profile_info_sec, u32 track_id)
1821 {
1822 enum iavf_status_code status = IAVF_SUCCESS;
1823 struct iavf_profile_section_header *sec = NULL;
1824 struct iavf_profile_info *pinfo;
1825 u32 offset = 0, info = 0;
1826
1827 sec = (struct iavf_profile_section_header *)profile_info_sec;
1828 sec->tbl_size = 1;
1829 sec->data_end = sizeof(struct iavf_profile_section_header) +
1830 sizeof(struct iavf_profile_info);
1831 sec->section.type = SECTION_TYPE_INFO;
1832 sec->section.offset = sizeof(struct iavf_profile_section_header);
1833 sec->section.size = sizeof(struct iavf_profile_info);
1834 pinfo = (struct iavf_profile_info *)(profile_info_sec +
1835 sec->section.offset);
1836 pinfo->track_id = track_id;
1837 pinfo->version = profile->version;
1838 pinfo->op = IAVF_DDP_ADD_TRACKID;
1839 iavf_memcpy(pinfo->name, profile->name, IAVF_DDP_NAME_SIZE,
1840 IAVF_NONDMA_TO_NONDMA);
1841
1842 status = iavf_aq_write_ddp(hw, (void *)sec, sec->data_end,
1843 track_id, &offset, &info, NULL);
1844 return status;
1845 }