]> git.proxmox.com Git - ceph.git/blame - ceph/src/dpdk/drivers/net/i40e/base/i40e_common.c
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / dpdk / drivers / net / i40e / base / i40e_common.c
CommitLineData
7c673cae
FG
1/*******************************************************************************
2
3Copyright (c) 2013 - 2015, Intel Corporation
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, 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
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30POSSIBILITY OF SUCH DAMAGE.
31
32***************************************************************************/
33
34#include "i40e_type.h"
35#include "i40e_adminq.h"
36#include "i40e_prototype.h"
37#include "i40e_virtchnl.h"
38
39
40/**
41 * i40e_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#if defined(INTEGRATED_VF) || defined(VF_DRIVER)
48enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
49#else
50STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
51#endif
52{
53 enum i40e_status_code status = I40E_SUCCESS;
54
55 DEBUGFUNC("i40e_set_mac_type\n");
56
57 if (hw->vendor_id == I40E_INTEL_VENDOR_ID) {
58 switch (hw->device_id) {
59 case I40E_DEV_ID_SFP_XL710:
60 case I40E_DEV_ID_QEMU:
61 case I40E_DEV_ID_KX_B:
62 case I40E_DEV_ID_KX_C:
63 case I40E_DEV_ID_QSFP_A:
64 case I40E_DEV_ID_QSFP_B:
65 case I40E_DEV_ID_QSFP_C:
66 case I40E_DEV_ID_10G_BASE_T:
67 case I40E_DEV_ID_10G_BASE_T4:
68 case I40E_DEV_ID_20G_KR2:
69 case I40E_DEV_ID_20G_KR2_A:
70 case I40E_DEV_ID_25G_B:
71 case I40E_DEV_ID_25G_SFP28:
72 hw->mac.type = I40E_MAC_XL710;
73 break;
74#ifdef X722_SUPPORT
75#ifdef X722_A0_SUPPORT
76 case I40E_DEV_ID_X722_A0:
77#endif
78 case I40E_DEV_ID_KX_X722:
79 case I40E_DEV_ID_QSFP_X722:
80 case I40E_DEV_ID_SFP_X722:
81 case I40E_DEV_ID_1G_BASE_T_X722:
82 case I40E_DEV_ID_10G_BASE_T_X722:
83 case I40E_DEV_ID_SFP_I_X722:
84 hw->mac.type = I40E_MAC_X722;
85 break;
86#endif
87#ifdef X722_SUPPORT
88#if defined(INTEGRATED_VF) || defined(VF_DRIVER)
89 case I40E_DEV_ID_X722_VF:
90 case I40E_DEV_ID_X722_VF_HV:
91#ifdef X722_A0_SUPPORT
92 case I40E_DEV_ID_X722_A0_VF:
93#endif
94 hw->mac.type = I40E_MAC_X722_VF;
95 break;
96#endif /* INTEGRATED_VF || VF_DRIVER */
97#endif /* X722_SUPPORT */
98#if defined(INTEGRATED_VF) || defined(VF_DRIVER)
99 case I40E_DEV_ID_VF:
100 case I40E_DEV_ID_VF_HV:
101 hw->mac.type = I40E_MAC_VF;
102 break;
103#endif
104 default:
105 hw->mac.type = I40E_MAC_GENERIC;
106 break;
107 }
108 } else {
109 status = I40E_ERR_DEVICE_NOT_SUPPORTED;
110 }
111
112 DEBUGOUT2("i40e_set_mac_type found mac: %d, returns: %d\n",
113 hw->mac.type, status);
114 return status;
115}
116
117#ifndef I40E_NDIS_SUPPORT
118/**
119 * i40e_aq_str - convert AQ err code to a string
120 * @hw: pointer to the HW structure
121 * @aq_err: the AQ error code to convert
122 **/
123const char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err)
124{
125 switch (aq_err) {
126 case I40E_AQ_RC_OK:
127 return "OK";
128 case I40E_AQ_RC_EPERM:
129 return "I40E_AQ_RC_EPERM";
130 case I40E_AQ_RC_ENOENT:
131 return "I40E_AQ_RC_ENOENT";
132 case I40E_AQ_RC_ESRCH:
133 return "I40E_AQ_RC_ESRCH";
134 case I40E_AQ_RC_EINTR:
135 return "I40E_AQ_RC_EINTR";
136 case I40E_AQ_RC_EIO:
137 return "I40E_AQ_RC_EIO";
138 case I40E_AQ_RC_ENXIO:
139 return "I40E_AQ_RC_ENXIO";
140 case I40E_AQ_RC_E2BIG:
141 return "I40E_AQ_RC_E2BIG";
142 case I40E_AQ_RC_EAGAIN:
143 return "I40E_AQ_RC_EAGAIN";
144 case I40E_AQ_RC_ENOMEM:
145 return "I40E_AQ_RC_ENOMEM";
146 case I40E_AQ_RC_EACCES:
147 return "I40E_AQ_RC_EACCES";
148 case I40E_AQ_RC_EFAULT:
149 return "I40E_AQ_RC_EFAULT";
150 case I40E_AQ_RC_EBUSY:
151 return "I40E_AQ_RC_EBUSY";
152 case I40E_AQ_RC_EEXIST:
153 return "I40E_AQ_RC_EEXIST";
154 case I40E_AQ_RC_EINVAL:
155 return "I40E_AQ_RC_EINVAL";
156 case I40E_AQ_RC_ENOTTY:
157 return "I40E_AQ_RC_ENOTTY";
158 case I40E_AQ_RC_ENOSPC:
159 return "I40E_AQ_RC_ENOSPC";
160 case I40E_AQ_RC_ENOSYS:
161 return "I40E_AQ_RC_ENOSYS";
162 case I40E_AQ_RC_ERANGE:
163 return "I40E_AQ_RC_ERANGE";
164 case I40E_AQ_RC_EFLUSHED:
165 return "I40E_AQ_RC_EFLUSHED";
166 case I40E_AQ_RC_BAD_ADDR:
167 return "I40E_AQ_RC_BAD_ADDR";
168 case I40E_AQ_RC_EMODE:
169 return "I40E_AQ_RC_EMODE";
170 case I40E_AQ_RC_EFBIG:
171 return "I40E_AQ_RC_EFBIG";
172 }
173
174 snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
175 return hw->err_str;
176}
177
178/**
179 * i40e_stat_str - convert status err code to a string
180 * @hw: pointer to the HW structure
181 * @stat_err: the status error code to convert
182 **/
183const char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err)
184{
185 switch (stat_err) {
186 case I40E_SUCCESS:
187 return "OK";
188 case I40E_ERR_NVM:
189 return "I40E_ERR_NVM";
190 case I40E_ERR_NVM_CHECKSUM:
191 return "I40E_ERR_NVM_CHECKSUM";
192 case I40E_ERR_PHY:
193 return "I40E_ERR_PHY";
194 case I40E_ERR_CONFIG:
195 return "I40E_ERR_CONFIG";
196 case I40E_ERR_PARAM:
197 return "I40E_ERR_PARAM";
198 case I40E_ERR_MAC_TYPE:
199 return "I40E_ERR_MAC_TYPE";
200 case I40E_ERR_UNKNOWN_PHY:
201 return "I40E_ERR_UNKNOWN_PHY";
202 case I40E_ERR_LINK_SETUP:
203 return "I40E_ERR_LINK_SETUP";
204 case I40E_ERR_ADAPTER_STOPPED:
205 return "I40E_ERR_ADAPTER_STOPPED";
206 case I40E_ERR_INVALID_MAC_ADDR:
207 return "I40E_ERR_INVALID_MAC_ADDR";
208 case I40E_ERR_DEVICE_NOT_SUPPORTED:
209 return "I40E_ERR_DEVICE_NOT_SUPPORTED";
210 case I40E_ERR_MASTER_REQUESTS_PENDING:
211 return "I40E_ERR_MASTER_REQUESTS_PENDING";
212 case I40E_ERR_INVALID_LINK_SETTINGS:
213 return "I40E_ERR_INVALID_LINK_SETTINGS";
214 case I40E_ERR_AUTONEG_NOT_COMPLETE:
215 return "I40E_ERR_AUTONEG_NOT_COMPLETE";
216 case I40E_ERR_RESET_FAILED:
217 return "I40E_ERR_RESET_FAILED";
218 case I40E_ERR_SWFW_SYNC:
219 return "I40E_ERR_SWFW_SYNC";
220 case I40E_ERR_NO_AVAILABLE_VSI:
221 return "I40E_ERR_NO_AVAILABLE_VSI";
222 case I40E_ERR_NO_MEMORY:
223 return "I40E_ERR_NO_MEMORY";
224 case I40E_ERR_BAD_PTR:
225 return "I40E_ERR_BAD_PTR";
226 case I40E_ERR_RING_FULL:
227 return "I40E_ERR_RING_FULL";
228 case I40E_ERR_INVALID_PD_ID:
229 return "I40E_ERR_INVALID_PD_ID";
230 case I40E_ERR_INVALID_QP_ID:
231 return "I40E_ERR_INVALID_QP_ID";
232 case I40E_ERR_INVALID_CQ_ID:
233 return "I40E_ERR_INVALID_CQ_ID";
234 case I40E_ERR_INVALID_CEQ_ID:
235 return "I40E_ERR_INVALID_CEQ_ID";
236 case I40E_ERR_INVALID_AEQ_ID:
237 return "I40E_ERR_INVALID_AEQ_ID";
238 case I40E_ERR_INVALID_SIZE:
239 return "I40E_ERR_INVALID_SIZE";
240 case I40E_ERR_INVALID_ARP_INDEX:
241 return "I40E_ERR_INVALID_ARP_INDEX";
242 case I40E_ERR_INVALID_FPM_FUNC_ID:
243 return "I40E_ERR_INVALID_FPM_FUNC_ID";
244 case I40E_ERR_QP_INVALID_MSG_SIZE:
245 return "I40E_ERR_QP_INVALID_MSG_SIZE";
246 case I40E_ERR_QP_TOOMANY_WRS_POSTED:
247 return "I40E_ERR_QP_TOOMANY_WRS_POSTED";
248 case I40E_ERR_INVALID_FRAG_COUNT:
249 return "I40E_ERR_INVALID_FRAG_COUNT";
250 case I40E_ERR_QUEUE_EMPTY:
251 return "I40E_ERR_QUEUE_EMPTY";
252 case I40E_ERR_INVALID_ALIGNMENT:
253 return "I40E_ERR_INVALID_ALIGNMENT";
254 case I40E_ERR_FLUSHED_QUEUE:
255 return "I40E_ERR_FLUSHED_QUEUE";
256 case I40E_ERR_INVALID_PUSH_PAGE_INDEX:
257 return "I40E_ERR_INVALID_PUSH_PAGE_INDEX";
258 case I40E_ERR_INVALID_IMM_DATA_SIZE:
259 return "I40E_ERR_INVALID_IMM_DATA_SIZE";
260 case I40E_ERR_TIMEOUT:
261 return "I40E_ERR_TIMEOUT";
262 case I40E_ERR_OPCODE_MISMATCH:
263 return "I40E_ERR_OPCODE_MISMATCH";
264 case I40E_ERR_CQP_COMPL_ERROR:
265 return "I40E_ERR_CQP_COMPL_ERROR";
266 case I40E_ERR_INVALID_VF_ID:
267 return "I40E_ERR_INVALID_VF_ID";
268 case I40E_ERR_INVALID_HMCFN_ID:
269 return "I40E_ERR_INVALID_HMCFN_ID";
270 case I40E_ERR_BACKING_PAGE_ERROR:
271 return "I40E_ERR_BACKING_PAGE_ERROR";
272 case I40E_ERR_NO_PBLCHUNKS_AVAILABLE:
273 return "I40E_ERR_NO_PBLCHUNKS_AVAILABLE";
274 case I40E_ERR_INVALID_PBLE_INDEX:
275 return "I40E_ERR_INVALID_PBLE_INDEX";
276 case I40E_ERR_INVALID_SD_INDEX:
277 return "I40E_ERR_INVALID_SD_INDEX";
278 case I40E_ERR_INVALID_PAGE_DESC_INDEX:
279 return "I40E_ERR_INVALID_PAGE_DESC_INDEX";
280 case I40E_ERR_INVALID_SD_TYPE:
281 return "I40E_ERR_INVALID_SD_TYPE";
282 case I40E_ERR_MEMCPY_FAILED:
283 return "I40E_ERR_MEMCPY_FAILED";
284 case I40E_ERR_INVALID_HMC_OBJ_INDEX:
285 return "I40E_ERR_INVALID_HMC_OBJ_INDEX";
286 case I40E_ERR_INVALID_HMC_OBJ_COUNT:
287 return "I40E_ERR_INVALID_HMC_OBJ_COUNT";
288 case I40E_ERR_INVALID_SRQ_ARM_LIMIT:
289 return "I40E_ERR_INVALID_SRQ_ARM_LIMIT";
290 case I40E_ERR_SRQ_ENABLED:
291 return "I40E_ERR_SRQ_ENABLED";
292 case I40E_ERR_ADMIN_QUEUE_ERROR:
293 return "I40E_ERR_ADMIN_QUEUE_ERROR";
294 case I40E_ERR_ADMIN_QUEUE_TIMEOUT:
295 return "I40E_ERR_ADMIN_QUEUE_TIMEOUT";
296 case I40E_ERR_BUF_TOO_SHORT:
297 return "I40E_ERR_BUF_TOO_SHORT";
298 case I40E_ERR_ADMIN_QUEUE_FULL:
299 return "I40E_ERR_ADMIN_QUEUE_FULL";
300 case I40E_ERR_ADMIN_QUEUE_NO_WORK:
301 return "I40E_ERR_ADMIN_QUEUE_NO_WORK";
302 case I40E_ERR_BAD_IWARP_CQE:
303 return "I40E_ERR_BAD_IWARP_CQE";
304 case I40E_ERR_NVM_BLANK_MODE:
305 return "I40E_ERR_NVM_BLANK_MODE";
306 case I40E_ERR_NOT_IMPLEMENTED:
307 return "I40E_ERR_NOT_IMPLEMENTED";
308 case I40E_ERR_PE_DOORBELL_NOT_ENABLED:
309 return "I40E_ERR_PE_DOORBELL_NOT_ENABLED";
310 case I40E_ERR_DIAG_TEST_FAILED:
311 return "I40E_ERR_DIAG_TEST_FAILED";
312 case I40E_ERR_NOT_READY:
313 return "I40E_ERR_NOT_READY";
314 case I40E_NOT_SUPPORTED:
315 return "I40E_NOT_SUPPORTED";
316 case I40E_ERR_FIRMWARE_API_VERSION:
317 return "I40E_ERR_FIRMWARE_API_VERSION";
318 }
319
320 snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
321 return hw->err_str;
322}
323
324#endif /* I40E_NDIS_SUPPORT */
325/**
326 * i40e_debug_aq
327 * @hw: debug mask related to admin queue
328 * @mask: debug mask
329 * @desc: pointer to admin queue descriptor
330 * @buffer: pointer to command buffer
331 * @buf_len: max length of buffer
332 *
333 * Dumps debug log about adminq command with descriptor contents.
334 **/
335void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
336 void *buffer, u16 buf_len)
337{
338 struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
339 u16 len = LE16_TO_CPU(aq_desc->datalen);
340 u8 *buf = (u8 *)buffer;
341 u16 i = 0;
342
343 if ((!(mask & hw->debug_mask)) || (desc == NULL))
344 return;
345
346 i40e_debug(hw, mask,
347 "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
348 LE16_TO_CPU(aq_desc->opcode),
349 LE16_TO_CPU(aq_desc->flags),
350 LE16_TO_CPU(aq_desc->datalen),
351 LE16_TO_CPU(aq_desc->retval));
352 i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
353 LE32_TO_CPU(aq_desc->cookie_high),
354 LE32_TO_CPU(aq_desc->cookie_low));
355 i40e_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n",
356 LE32_TO_CPU(aq_desc->params.internal.param0),
357 LE32_TO_CPU(aq_desc->params.internal.param1));
358 i40e_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n",
359 LE32_TO_CPU(aq_desc->params.external.addr_high),
360 LE32_TO_CPU(aq_desc->params.external.addr_low));
361
362 if ((buffer != NULL) && (aq_desc->datalen != 0)) {
363 i40e_debug(hw, mask, "AQ CMD Buffer:\n");
364 if (buf_len < len)
365 len = buf_len;
366 /* write the full 16-byte chunks */
367 for (i = 0; i < (len - 16); i += 16)
368 i40e_debug(hw, mask,
369 "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
370 i, buf[i], buf[i+1], buf[i+2], buf[i+3],
371 buf[i+4], buf[i+5], buf[i+6], buf[i+7],
372 buf[i+8], buf[i+9], buf[i+10], buf[i+11],
373 buf[i+12], buf[i+13], buf[i+14], buf[i+15]);
374 /* the most we could have left is 16 bytes, pad with zeros */
375 if (i < len) {
376 char d_buf[16];
377 int j, i_sav;
378
379 i_sav = i;
380 memset(d_buf, 0, sizeof(d_buf));
381 for (j = 0; i < len; j++, i++)
382 d_buf[j] = buf[i];
383 i40e_debug(hw, mask,
384 "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
385 i_sav, d_buf[0], d_buf[1], d_buf[2], d_buf[3],
386 d_buf[4], d_buf[5], d_buf[6], d_buf[7],
387 d_buf[8], d_buf[9], d_buf[10], d_buf[11],
388 d_buf[12], d_buf[13], d_buf[14], d_buf[15]);
389 }
390 }
391}
392
393/**
394 * i40e_check_asq_alive
395 * @hw: pointer to the hw struct
396 *
397 * Returns true if Queue is enabled else false.
398 **/
399bool i40e_check_asq_alive(struct i40e_hw *hw)
400{
401 if (hw->aq.asq.len)
402#ifdef PF_DRIVER
403#ifdef INTEGRATED_VF
404 if (!i40e_is_vf(hw))
405 return !!(rd32(hw, hw->aq.asq.len) &
406 I40E_PF_ATQLEN_ATQENABLE_MASK);
407#else
408 return !!(rd32(hw, hw->aq.asq.len) &
409 I40E_PF_ATQLEN_ATQENABLE_MASK);
410#endif /* INTEGRATED_VF */
411#endif /* PF_DRIVER */
412#ifdef VF_DRIVER
413#ifdef INTEGRATED_VF
414 if (i40e_is_vf(hw))
415 return !!(rd32(hw, hw->aq.asq.len) &
416 I40E_VF_ATQLEN1_ATQENABLE_MASK);
417#else
418 return !!(rd32(hw, hw->aq.asq.len) &
419 I40E_VF_ATQLEN1_ATQENABLE_MASK);
420#endif /* INTEGRATED_VF */
421#endif /* VF_DRIVER */
422 return false;
423}
424
425/**
426 * i40e_aq_queue_shutdown
427 * @hw: pointer to the hw struct
428 * @unloading: is the driver unloading itself
429 *
430 * Tell the Firmware that we're shutting down the AdminQ and whether
431 * or not the driver is unloading as well.
432 **/
433enum i40e_status_code i40e_aq_queue_shutdown(struct i40e_hw *hw,
434 bool unloading)
435{
436 struct i40e_aq_desc desc;
437 struct i40e_aqc_queue_shutdown *cmd =
438 (struct i40e_aqc_queue_shutdown *)&desc.params.raw;
439 enum i40e_status_code status;
440
441 i40e_fill_default_direct_cmd_desc(&desc,
442 i40e_aqc_opc_queue_shutdown);
443
444 if (unloading)
445 cmd->driver_unloading = CPU_TO_LE32(I40E_AQ_DRIVER_UNLOADING);
446 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
447
448 return status;
449}
450#ifdef X722_SUPPORT
451
452/**
453 * i40e_aq_get_set_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 * @set: set true to set the table, false to get the table
460 *
461 * Internal function to get or set RSS look up table
462 **/
463STATIC enum i40e_status_code i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
464 u16 vsi_id, bool pf_lut,
465 u8 *lut, u16 lut_size,
466 bool set)
467{
468 enum i40e_status_code status;
469 struct i40e_aq_desc desc;
470 struct i40e_aqc_get_set_rss_lut *cmd_resp =
471 (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw;
472
473 if (set)
474 i40e_fill_default_direct_cmd_desc(&desc,
475 i40e_aqc_opc_set_rss_lut);
476 else
477 i40e_fill_default_direct_cmd_desc(&desc,
478 i40e_aqc_opc_get_rss_lut);
479
480 /* Indirect command */
481 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
482 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
483
484 cmd_resp->vsi_id =
485 CPU_TO_LE16((u16)((vsi_id <<
486 I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
487 I40E_AQC_SET_RSS_LUT_VSI_ID_MASK));
488 cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_LUT_VSI_VALID);
489
490 if (pf_lut)
491 cmd_resp->flags |= CPU_TO_LE16((u16)
492 ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
493 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
494 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
495 else
496 cmd_resp->flags |= CPU_TO_LE16((u16)
497 ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
498 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
499 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
500
501 status = i40e_asq_send_command(hw, &desc, lut, lut_size, NULL);
502
503 return status;
504}
505
506/**
507 * i40e_aq_get_rss_lut
508 * @hw: pointer to the hardware structure
509 * @vsi_id: vsi fw index
510 * @pf_lut: for PF table set true, for VSI table set false
511 * @lut: pointer to the lut buffer provided by the caller
512 * @lut_size: size of the lut buffer
513 *
514 * get the RSS lookup table, PF or VSI type
515 **/
516enum i40e_status_code i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
517 bool pf_lut, u8 *lut, u16 lut_size)
518{
519 return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
520 false);
521}
522
523/**
524 * i40e_aq_set_rss_lut
525 * @hw: pointer to the hardware structure
526 * @vsi_id: vsi fw index
527 * @pf_lut: for PF table set true, for VSI table set false
528 * @lut: pointer to the lut buffer provided by the caller
529 * @lut_size: size of the lut buffer
530 *
531 * set the RSS lookup table, PF or VSI type
532 **/
533enum i40e_status_code i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
534 bool pf_lut, u8 *lut, u16 lut_size)
535{
536 return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
537}
538
539/**
540 * i40e_aq_get_set_rss_key
541 * @hw: pointer to the hw struct
542 * @vsi_id: vsi fw index
543 * @key: pointer to key info struct
544 * @set: set true to set the key, false to get the key
545 *
546 * get the RSS key per VSI
547 **/
548STATIC enum i40e_status_code i40e_aq_get_set_rss_key(struct i40e_hw *hw,
549 u16 vsi_id,
550 struct i40e_aqc_get_set_rss_key_data *key,
551 bool set)
552{
553 enum i40e_status_code status;
554 struct i40e_aq_desc desc;
555 struct i40e_aqc_get_set_rss_key *cmd_resp =
556 (struct i40e_aqc_get_set_rss_key *)&desc.params.raw;
557 u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data);
558
559 if (set)
560 i40e_fill_default_direct_cmd_desc(&desc,
561 i40e_aqc_opc_set_rss_key);
562 else
563 i40e_fill_default_direct_cmd_desc(&desc,
564 i40e_aqc_opc_get_rss_key);
565
566 /* Indirect command */
567 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
568 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
569
570 cmd_resp->vsi_id =
571 CPU_TO_LE16((u16)((vsi_id <<
572 I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
573 I40E_AQC_SET_RSS_KEY_VSI_ID_MASK));
574 cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_KEY_VSI_VALID);
575
576 status = i40e_asq_send_command(hw, &desc, key, key_size, NULL);
577
578 return status;
579}
580
581/**
582 * i40e_aq_get_rss_key
583 * @hw: pointer to the hw struct
584 * @vsi_id: vsi fw index
585 * @key: pointer to key info struct
586 *
587 **/
588enum i40e_status_code i40e_aq_get_rss_key(struct i40e_hw *hw,
589 u16 vsi_id,
590 struct i40e_aqc_get_set_rss_key_data *key)
591{
592 return i40e_aq_get_set_rss_key(hw, vsi_id, key, false);
593}
594
595/**
596 * i40e_aq_set_rss_key
597 * @hw: pointer to the hw struct
598 * @vsi_id: vsi fw index
599 * @key: pointer to key info struct
600 *
601 * set the RSS key per VSI
602 **/
603enum i40e_status_code i40e_aq_set_rss_key(struct i40e_hw *hw,
604 u16 vsi_id,
605 struct i40e_aqc_get_set_rss_key_data *key)
606{
607 return i40e_aq_get_set_rss_key(hw, vsi_id, key, true);
608}
609#endif /* X722_SUPPORT */
610
611/* The i40e_ptype_lookup table is used to convert from the 8-bit ptype in the
612 * hardware to a bit-field that can be used by SW to more easily determine the
613 * packet type.
614 *
615 * Macros are used to shorten the table lines and make this table human
616 * readable.
617 *
618 * We store the PTYPE in the top byte of the bit field - this is just so that
619 * we can check that the table doesn't have a row missing, as the index into
620 * the table should be the PTYPE.
621 *
622 * Typical work flow:
623 *
624 * IF NOT i40e_ptype_lookup[ptype].known
625 * THEN
626 * Packet is unknown
627 * ELSE IF i40e_ptype_lookup[ptype].outer_ip == I40E_RX_PTYPE_OUTER_IP
628 * Use the rest of the fields to look at the tunnels, inner protocols, etc
629 * ELSE
630 * Use the enum i40e_rx_l2_ptype to decode the packet type
631 * ENDIF
632 */
633
634/* macro to make the table lines short */
635#define I40E_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\
636 { PTYPE, \
637 1, \
638 I40E_RX_PTYPE_OUTER_##OUTER_IP, \
639 I40E_RX_PTYPE_OUTER_##OUTER_IP_VER, \
640 I40E_RX_PTYPE_##OUTER_FRAG, \
641 I40E_RX_PTYPE_TUNNEL_##T, \
642 I40E_RX_PTYPE_TUNNEL_END_##TE, \
643 I40E_RX_PTYPE_##TEF, \
644 I40E_RX_PTYPE_INNER_PROT_##I, \
645 I40E_RX_PTYPE_PAYLOAD_LAYER_##PL }
646
647#define I40E_PTT_UNUSED_ENTRY(PTYPE) \
648 { PTYPE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
649
650/* shorter macros makes the table fit but are terse */
651#define I40E_RX_PTYPE_NOF I40E_RX_PTYPE_NOT_FRAG
652#define I40E_RX_PTYPE_FRG I40E_RX_PTYPE_FRAG
653#define I40E_RX_PTYPE_INNER_PROT_TS I40E_RX_PTYPE_INNER_PROT_TIMESYNC
654
655/* Lookup table mapping the HW PTYPE to the bit field for decoding */
656struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {
657 /* L2 Packet types */
658 I40E_PTT_UNUSED_ENTRY(0),
659 I40E_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
660 I40E_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, TS, PAY2),
661 I40E_PTT(3, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
662 I40E_PTT_UNUSED_ENTRY(4),
663 I40E_PTT_UNUSED_ENTRY(5),
664 I40E_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
665 I40E_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
666 I40E_PTT_UNUSED_ENTRY(8),
667 I40E_PTT_UNUSED_ENTRY(9),
668 I40E_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
669 I40E_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
670 I40E_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
671 I40E_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
672 I40E_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
673 I40E_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
674 I40E_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
675 I40E_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
676 I40E_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
677 I40E_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
678 I40E_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
679 I40E_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
680
681 /* Non Tunneled IPv4 */
682 I40E_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
683 I40E_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
684 I40E_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4),
685 I40E_PTT_UNUSED_ENTRY(25),
686 I40E_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4),
687 I40E_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
688 I40E_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
689
690 /* IPv4 --> IPv4 */
691 I40E_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
692 I40E_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
693 I40E_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
694 I40E_PTT_UNUSED_ENTRY(32),
695 I40E_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
696 I40E_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
697 I40E_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
698
699 /* IPv4 --> IPv6 */
700 I40E_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
701 I40E_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
702 I40E_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
703 I40E_PTT_UNUSED_ENTRY(39),
704 I40E_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
705 I40E_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
706 I40E_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
707
708 /* IPv4 --> GRE/NAT */
709 I40E_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
710
711 /* IPv4 --> GRE/NAT --> IPv4 */
712 I40E_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
713 I40E_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
714 I40E_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
715 I40E_PTT_UNUSED_ENTRY(47),
716 I40E_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
717 I40E_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
718 I40E_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
719
720 /* IPv4 --> GRE/NAT --> IPv6 */
721 I40E_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
722 I40E_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
723 I40E_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
724 I40E_PTT_UNUSED_ENTRY(54),
725 I40E_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
726 I40E_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
727 I40E_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
728
729 /* IPv4 --> GRE/NAT --> MAC */
730 I40E_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
731
732 /* IPv4 --> GRE/NAT --> MAC --> IPv4 */
733 I40E_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
734 I40E_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
735 I40E_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
736 I40E_PTT_UNUSED_ENTRY(62),
737 I40E_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
738 I40E_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
739 I40E_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
740
741 /* IPv4 --> GRE/NAT -> MAC --> IPv6 */
742 I40E_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
743 I40E_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
744 I40E_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
745 I40E_PTT_UNUSED_ENTRY(69),
746 I40E_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
747 I40E_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
748 I40E_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
749
750 /* IPv4 --> GRE/NAT --> MAC/VLAN */
751 I40E_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
752
753 /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
754 I40E_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
755 I40E_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
756 I40E_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
757 I40E_PTT_UNUSED_ENTRY(77),
758 I40E_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
759 I40E_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
760 I40E_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
761
762 /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
763 I40E_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
764 I40E_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
765 I40E_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
766 I40E_PTT_UNUSED_ENTRY(84),
767 I40E_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
768 I40E_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
769 I40E_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
770
771 /* Non Tunneled IPv6 */
772 I40E_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
773 I40E_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
774 I40E_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4),
775 I40E_PTT_UNUSED_ENTRY(91),
776 I40E_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4),
777 I40E_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
778 I40E_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
779
780 /* IPv6 --> IPv4 */
781 I40E_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
782 I40E_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
783 I40E_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
784 I40E_PTT_UNUSED_ENTRY(98),
785 I40E_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
786 I40E_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
787 I40E_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
788
789 /* IPv6 --> IPv6 */
790 I40E_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
791 I40E_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
792 I40E_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
793 I40E_PTT_UNUSED_ENTRY(105),
794 I40E_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
795 I40E_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
796 I40E_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
797
798 /* IPv6 --> GRE/NAT */
799 I40E_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
800
801 /* IPv6 --> GRE/NAT -> IPv4 */
802 I40E_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
803 I40E_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
804 I40E_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
805 I40E_PTT_UNUSED_ENTRY(113),
806 I40E_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
807 I40E_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
808 I40E_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
809
810 /* IPv6 --> GRE/NAT -> IPv6 */
811 I40E_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
812 I40E_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
813 I40E_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
814 I40E_PTT_UNUSED_ENTRY(120),
815 I40E_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
816 I40E_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
817 I40E_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
818
819 /* IPv6 --> GRE/NAT -> MAC */
820 I40E_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
821
822 /* IPv6 --> GRE/NAT -> MAC -> IPv4 */
823 I40E_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
824 I40E_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
825 I40E_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
826 I40E_PTT_UNUSED_ENTRY(128),
827 I40E_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
828 I40E_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
829 I40E_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
830
831 /* IPv6 --> GRE/NAT -> MAC -> IPv6 */
832 I40E_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
833 I40E_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
834 I40E_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
835 I40E_PTT_UNUSED_ENTRY(135),
836 I40E_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
837 I40E_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
838 I40E_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
839
840 /* IPv6 --> GRE/NAT -> MAC/VLAN */
841 I40E_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
842
843 /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
844 I40E_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
845 I40E_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
846 I40E_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
847 I40E_PTT_UNUSED_ENTRY(143),
848 I40E_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
849 I40E_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
850 I40E_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
851
852 /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
853 I40E_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
854 I40E_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
855 I40E_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
856 I40E_PTT_UNUSED_ENTRY(150),
857 I40E_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
858 I40E_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
859 I40E_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
860
861 /* unused entries */
862 I40E_PTT_UNUSED_ENTRY(154),
863 I40E_PTT_UNUSED_ENTRY(155),
864 I40E_PTT_UNUSED_ENTRY(156),
865 I40E_PTT_UNUSED_ENTRY(157),
866 I40E_PTT_UNUSED_ENTRY(158),
867 I40E_PTT_UNUSED_ENTRY(159),
868
869 I40E_PTT_UNUSED_ENTRY(160),
870 I40E_PTT_UNUSED_ENTRY(161),
871 I40E_PTT_UNUSED_ENTRY(162),
872 I40E_PTT_UNUSED_ENTRY(163),
873 I40E_PTT_UNUSED_ENTRY(164),
874 I40E_PTT_UNUSED_ENTRY(165),
875 I40E_PTT_UNUSED_ENTRY(166),
876 I40E_PTT_UNUSED_ENTRY(167),
877 I40E_PTT_UNUSED_ENTRY(168),
878 I40E_PTT_UNUSED_ENTRY(169),
879
880 I40E_PTT_UNUSED_ENTRY(170),
881 I40E_PTT_UNUSED_ENTRY(171),
882 I40E_PTT_UNUSED_ENTRY(172),
883 I40E_PTT_UNUSED_ENTRY(173),
884 I40E_PTT_UNUSED_ENTRY(174),
885 I40E_PTT_UNUSED_ENTRY(175),
886 I40E_PTT_UNUSED_ENTRY(176),
887 I40E_PTT_UNUSED_ENTRY(177),
888 I40E_PTT_UNUSED_ENTRY(178),
889 I40E_PTT_UNUSED_ENTRY(179),
890
891 I40E_PTT_UNUSED_ENTRY(180),
892 I40E_PTT_UNUSED_ENTRY(181),
893 I40E_PTT_UNUSED_ENTRY(182),
894 I40E_PTT_UNUSED_ENTRY(183),
895 I40E_PTT_UNUSED_ENTRY(184),
896 I40E_PTT_UNUSED_ENTRY(185),
897 I40E_PTT_UNUSED_ENTRY(186),
898 I40E_PTT_UNUSED_ENTRY(187),
899 I40E_PTT_UNUSED_ENTRY(188),
900 I40E_PTT_UNUSED_ENTRY(189),
901
902 I40E_PTT_UNUSED_ENTRY(190),
903 I40E_PTT_UNUSED_ENTRY(191),
904 I40E_PTT_UNUSED_ENTRY(192),
905 I40E_PTT_UNUSED_ENTRY(193),
906 I40E_PTT_UNUSED_ENTRY(194),
907 I40E_PTT_UNUSED_ENTRY(195),
908 I40E_PTT_UNUSED_ENTRY(196),
909 I40E_PTT_UNUSED_ENTRY(197),
910 I40E_PTT_UNUSED_ENTRY(198),
911 I40E_PTT_UNUSED_ENTRY(199),
912
913 I40E_PTT_UNUSED_ENTRY(200),
914 I40E_PTT_UNUSED_ENTRY(201),
915 I40E_PTT_UNUSED_ENTRY(202),
916 I40E_PTT_UNUSED_ENTRY(203),
917 I40E_PTT_UNUSED_ENTRY(204),
918 I40E_PTT_UNUSED_ENTRY(205),
919 I40E_PTT_UNUSED_ENTRY(206),
920 I40E_PTT_UNUSED_ENTRY(207),
921 I40E_PTT_UNUSED_ENTRY(208),
922 I40E_PTT_UNUSED_ENTRY(209),
923
924 I40E_PTT_UNUSED_ENTRY(210),
925 I40E_PTT_UNUSED_ENTRY(211),
926 I40E_PTT_UNUSED_ENTRY(212),
927 I40E_PTT_UNUSED_ENTRY(213),
928 I40E_PTT_UNUSED_ENTRY(214),
929 I40E_PTT_UNUSED_ENTRY(215),
930 I40E_PTT_UNUSED_ENTRY(216),
931 I40E_PTT_UNUSED_ENTRY(217),
932 I40E_PTT_UNUSED_ENTRY(218),
933 I40E_PTT_UNUSED_ENTRY(219),
934
935 I40E_PTT_UNUSED_ENTRY(220),
936 I40E_PTT_UNUSED_ENTRY(221),
937 I40E_PTT_UNUSED_ENTRY(222),
938 I40E_PTT_UNUSED_ENTRY(223),
939 I40E_PTT_UNUSED_ENTRY(224),
940 I40E_PTT_UNUSED_ENTRY(225),
941 I40E_PTT_UNUSED_ENTRY(226),
942 I40E_PTT_UNUSED_ENTRY(227),
943 I40E_PTT_UNUSED_ENTRY(228),
944 I40E_PTT_UNUSED_ENTRY(229),
945
946 I40E_PTT_UNUSED_ENTRY(230),
947 I40E_PTT_UNUSED_ENTRY(231),
948 I40E_PTT_UNUSED_ENTRY(232),
949 I40E_PTT_UNUSED_ENTRY(233),
950 I40E_PTT_UNUSED_ENTRY(234),
951 I40E_PTT_UNUSED_ENTRY(235),
952 I40E_PTT_UNUSED_ENTRY(236),
953 I40E_PTT_UNUSED_ENTRY(237),
954 I40E_PTT_UNUSED_ENTRY(238),
955 I40E_PTT_UNUSED_ENTRY(239),
956
957 I40E_PTT_UNUSED_ENTRY(240),
958 I40E_PTT_UNUSED_ENTRY(241),
959 I40E_PTT_UNUSED_ENTRY(242),
960 I40E_PTT_UNUSED_ENTRY(243),
961 I40E_PTT_UNUSED_ENTRY(244),
962 I40E_PTT_UNUSED_ENTRY(245),
963 I40E_PTT_UNUSED_ENTRY(246),
964 I40E_PTT_UNUSED_ENTRY(247),
965 I40E_PTT_UNUSED_ENTRY(248),
966 I40E_PTT_UNUSED_ENTRY(249),
967
968 I40E_PTT_UNUSED_ENTRY(250),
969 I40E_PTT_UNUSED_ENTRY(251),
970 I40E_PTT_UNUSED_ENTRY(252),
971 I40E_PTT_UNUSED_ENTRY(253),
972 I40E_PTT_UNUSED_ENTRY(254),
973 I40E_PTT_UNUSED_ENTRY(255)
974};
975
976
977/**
978 * i40e_validate_mac_addr - Validate unicast MAC address
979 * @mac_addr: pointer to MAC address
980 *
981 * Tests a MAC address to ensure it is a valid Individual Address
982 **/
983enum i40e_status_code i40e_validate_mac_addr(u8 *mac_addr)
984{
985 enum i40e_status_code status = I40E_SUCCESS;
986
987 DEBUGFUNC("i40e_validate_mac_addr");
988
989 /* Broadcast addresses ARE multicast addresses
990 * Make sure it is not a multicast address
991 * Reject the zero address
992 */
993 if (I40E_IS_MULTICAST(mac_addr) ||
994 (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
995 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0))
996 status = I40E_ERR_INVALID_MAC_ADDR;
997
998 return status;
999}
1000#ifdef PF_DRIVER
1001
1002/**
1003 * i40e_init_shared_code - Initialize the shared code
1004 * @hw: pointer to hardware structure
1005 *
1006 * This assigns the MAC type and PHY code and inits the NVM.
1007 * Does not touch the hardware. This function must be called prior to any
1008 * other function in the shared code. The i40e_hw structure should be
1009 * memset to 0 prior to calling this function. The following fields in
1010 * hw structure should be filled in prior to calling this function:
1011 * hw_addr, back, device_id, vendor_id, subsystem_device_id,
1012 * subsystem_vendor_id, and revision_id
1013 **/
1014enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw)
1015{
1016 enum i40e_status_code status = I40E_SUCCESS;
1017 u32 port, ari, func_rid;
1018
1019 DEBUGFUNC("i40e_init_shared_code");
1020
1021 i40e_set_mac_type(hw);
1022
1023 switch (hw->mac.type) {
1024 case I40E_MAC_XL710:
1025#ifdef X722_SUPPORT
1026 case I40E_MAC_X722:
1027#endif
1028 break;
1029 default:
1030 return I40E_ERR_DEVICE_NOT_SUPPORTED;
1031 }
1032
1033 hw->phy.get_link_info = true;
1034
1035 /* Determine port number and PF number*/
1036 port = (rd32(hw, I40E_PFGEN_PORTNUM) & I40E_PFGEN_PORTNUM_PORT_NUM_MASK)
1037 >> I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
1038 hw->port = (u8)port;
1039 ari = (rd32(hw, I40E_GLPCI_CAPSUP) & I40E_GLPCI_CAPSUP_ARI_EN_MASK) >>
1040 I40E_GLPCI_CAPSUP_ARI_EN_SHIFT;
1041 func_rid = rd32(hw, I40E_PF_FUNC_RID);
1042 if (ari)
1043 hw->pf_id = (u8)(func_rid & 0xff);
1044 else
1045 hw->pf_id = (u8)(func_rid & 0x7);
1046
1047#ifdef X722_SUPPORT
1048 if (hw->mac.type == I40E_MAC_X722)
1049 hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE;
1050
1051#endif
1052 status = i40e_init_nvm(hw);
1053 return status;
1054}
1055
1056/**
1057 * i40e_aq_mac_address_read - Retrieve the MAC addresses
1058 * @hw: pointer to the hw struct
1059 * @flags: a return indicator of what addresses were added to the addr store
1060 * @addrs: the requestor's mac addr store
1061 * @cmd_details: pointer to command details structure or NULL
1062 **/
1063STATIC enum i40e_status_code i40e_aq_mac_address_read(struct i40e_hw *hw,
1064 u16 *flags,
1065 struct i40e_aqc_mac_address_read_data *addrs,
1066 struct i40e_asq_cmd_details *cmd_details)
1067{
1068 struct i40e_aq_desc desc;
1069 struct i40e_aqc_mac_address_read *cmd_data =
1070 (struct i40e_aqc_mac_address_read *)&desc.params.raw;
1071 enum i40e_status_code status;
1072
1073 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_mac_address_read);
1074 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
1075
1076 status = i40e_asq_send_command(hw, &desc, addrs,
1077 sizeof(*addrs), cmd_details);
1078 *flags = LE16_TO_CPU(cmd_data->command_flags);
1079
1080 return status;
1081}
1082
1083/**
1084 * i40e_aq_mac_address_write - Change the MAC addresses
1085 * @hw: pointer to the hw struct
1086 * @flags: indicates which MAC to be written
1087 * @mac_addr: address to write
1088 * @cmd_details: pointer to command details structure or NULL
1089 **/
1090enum i40e_status_code i40e_aq_mac_address_write(struct i40e_hw *hw,
1091 u16 flags, u8 *mac_addr,
1092 struct i40e_asq_cmd_details *cmd_details)
1093{
1094 struct i40e_aq_desc desc;
1095 struct i40e_aqc_mac_address_write *cmd_data =
1096 (struct i40e_aqc_mac_address_write *)&desc.params.raw;
1097 enum i40e_status_code status;
1098
1099 i40e_fill_default_direct_cmd_desc(&desc,
1100 i40e_aqc_opc_mac_address_write);
1101 cmd_data->command_flags = CPU_TO_LE16(flags);
1102 cmd_data->mac_sah = CPU_TO_LE16((u16)mac_addr[0] << 8 | mac_addr[1]);
1103 cmd_data->mac_sal = CPU_TO_LE32(((u32)mac_addr[2] << 24) |
1104 ((u32)mac_addr[3] << 16) |
1105 ((u32)mac_addr[4] << 8) |
1106 mac_addr[5]);
1107
1108 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1109
1110 return status;
1111}
1112
1113/**
1114 * i40e_get_mac_addr - get MAC address
1115 * @hw: pointer to the HW structure
1116 * @mac_addr: pointer to MAC address
1117 *
1118 * Reads the adapter's MAC address from register
1119 **/
1120enum i40e_status_code i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
1121{
1122 struct i40e_aqc_mac_address_read_data addrs;
1123 enum i40e_status_code status;
1124 u16 flags = 0;
1125
1126 status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
1127
1128 if (flags & I40E_AQC_LAN_ADDR_VALID)
1129 memcpy(mac_addr, &addrs.pf_lan_mac, sizeof(addrs.pf_lan_mac));
1130
1131 return status;
1132}
1133
1134/**
1135 * i40e_get_port_mac_addr - get Port MAC address
1136 * @hw: pointer to the HW structure
1137 * @mac_addr: pointer to Port MAC address
1138 *
1139 * Reads the adapter's Port MAC address
1140 **/
1141enum i40e_status_code i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
1142{
1143 struct i40e_aqc_mac_address_read_data addrs;
1144 enum i40e_status_code status;
1145 u16 flags = 0;
1146
1147 status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
1148 if (status)
1149 return status;
1150
1151 if (flags & I40E_AQC_PORT_ADDR_VALID)
1152 memcpy(mac_addr, &addrs.port_mac, sizeof(addrs.port_mac));
1153 else
1154 status = I40E_ERR_INVALID_MAC_ADDR;
1155
1156 return status;
1157}
1158
1159/**
1160 * i40e_pre_tx_queue_cfg - pre tx queue configure
1161 * @hw: pointer to the HW structure
1162 * @queue: target pf queue index
1163 * @enable: state change request
1164 *
1165 * Handles hw requirement to indicate intention to enable
1166 * or disable target queue.
1167 **/
1168void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
1169{
1170 u32 abs_queue_idx = hw->func_caps.base_queue + queue;
1171 u32 reg_block = 0;
1172 u32 reg_val;
1173
1174 if (abs_queue_idx >= 128) {
1175 reg_block = abs_queue_idx / 128;
1176 abs_queue_idx %= 128;
1177 }
1178
1179 reg_val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
1180 reg_val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
1181 reg_val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
1182
1183 if (enable)
1184 reg_val |= I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK;
1185 else
1186 reg_val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
1187
1188 wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val);
1189}
1190
1191/**
1192 * i40e_get_san_mac_addr - get SAN MAC address
1193 * @hw: pointer to the HW structure
1194 * @mac_addr: pointer to SAN MAC address
1195 *
1196 * Reads the adapter's SAN MAC address from NVM
1197 **/
1198enum i40e_status_code i40e_get_san_mac_addr(struct i40e_hw *hw,
1199 u8 *mac_addr)
1200{
1201 struct i40e_aqc_mac_address_read_data addrs;
1202 enum i40e_status_code status;
1203 u16 flags = 0;
1204
1205 status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
1206 if (status)
1207 return status;
1208
1209 if (flags & I40E_AQC_SAN_ADDR_VALID)
1210 memcpy(mac_addr, &addrs.pf_san_mac, sizeof(addrs.pf_san_mac));
1211 else
1212 status = I40E_ERR_INVALID_MAC_ADDR;
1213
1214 return status;
1215}
1216
1217/**
1218 * i40e_read_pba_string - Reads part number string from EEPROM
1219 * @hw: pointer to hardware structure
1220 * @pba_num: stores the part number string from the EEPROM
1221 * @pba_num_size: part number string buffer length
1222 *
1223 * Reads the part number string from the EEPROM.
1224 **/
1225enum i40e_status_code i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
1226 u32 pba_num_size)
1227{
1228 enum i40e_status_code status = I40E_SUCCESS;
1229 u16 pba_word = 0;
1230 u16 pba_size = 0;
1231 u16 pba_ptr = 0;
1232 u16 i = 0;
1233
1234 status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
1235 if ((status != I40E_SUCCESS) || (pba_word != 0xFAFA)) {
1236 DEBUGOUT("Failed to read PBA flags or flag is invalid.\n");
1237 return status;
1238 }
1239
1240 status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr);
1241 if (status != I40E_SUCCESS) {
1242 DEBUGOUT("Failed to read PBA Block pointer.\n");
1243 return status;
1244 }
1245
1246 status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
1247 if (status != I40E_SUCCESS) {
1248 DEBUGOUT("Failed to read PBA Block size.\n");
1249 return status;
1250 }
1251
1252 /* Subtract one to get PBA word count (PBA Size word is included in
1253 * total size)
1254 */
1255 pba_size--;
1256 if (pba_num_size < (((u32)pba_size * 2) + 1)) {
1257 DEBUGOUT("Buffer to small for PBA data.\n");
1258 return I40E_ERR_PARAM;
1259 }
1260
1261 for (i = 0; i < pba_size; i++) {
1262 status = i40e_read_nvm_word(hw, (pba_ptr + 1) + i, &pba_word);
1263 if (status != I40E_SUCCESS) {
1264 DEBUGOUT1("Failed to read PBA Block word %d.\n", i);
1265 return status;
1266 }
1267
1268 pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
1269 pba_num[(i * 2) + 1] = pba_word & 0xFF;
1270 }
1271 pba_num[(pba_size * 2)] = '\0';
1272
1273 return status;
1274}
1275
1276/**
1277 * i40e_get_media_type - Gets media type
1278 * @hw: pointer to the hardware structure
1279 **/
1280STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
1281{
1282 enum i40e_media_type media;
1283
1284 switch (hw->phy.link_info.phy_type) {
1285 case I40E_PHY_TYPE_10GBASE_SR:
1286 case I40E_PHY_TYPE_10GBASE_LR:
1287 case I40E_PHY_TYPE_1000BASE_SX:
1288 case I40E_PHY_TYPE_1000BASE_LX:
1289 case I40E_PHY_TYPE_40GBASE_SR4:
1290 case I40E_PHY_TYPE_40GBASE_LR4:
1291 media = I40E_MEDIA_TYPE_FIBER;
1292 break;
1293 case I40E_PHY_TYPE_100BASE_TX:
1294 case I40E_PHY_TYPE_1000BASE_T:
1295 case I40E_PHY_TYPE_10GBASE_T:
1296 media = I40E_MEDIA_TYPE_BASET;
1297 break;
1298 case I40E_PHY_TYPE_10GBASE_CR1_CU:
1299 case I40E_PHY_TYPE_40GBASE_CR4_CU:
1300 case I40E_PHY_TYPE_10GBASE_CR1:
1301 case I40E_PHY_TYPE_40GBASE_CR4:
1302 case I40E_PHY_TYPE_10GBASE_SFPP_CU:
1303 case I40E_PHY_TYPE_40GBASE_AOC:
1304 case I40E_PHY_TYPE_10GBASE_AOC:
1305 media = I40E_MEDIA_TYPE_DA;
1306 break;
1307 case I40E_PHY_TYPE_1000BASE_KX:
1308 case I40E_PHY_TYPE_10GBASE_KX4:
1309 case I40E_PHY_TYPE_10GBASE_KR:
1310 case I40E_PHY_TYPE_40GBASE_KR4:
1311 case I40E_PHY_TYPE_20GBASE_KR2:
1312 media = I40E_MEDIA_TYPE_BACKPLANE;
1313 break;
1314 case I40E_PHY_TYPE_SGMII:
1315 case I40E_PHY_TYPE_XAUI:
1316 case I40E_PHY_TYPE_XFI:
1317 case I40E_PHY_TYPE_XLAUI:
1318 case I40E_PHY_TYPE_XLPPI:
1319 default:
1320 media = I40E_MEDIA_TYPE_UNKNOWN;
1321 break;
1322 }
1323
1324 return media;
1325}
1326
1327#define I40E_PF_RESET_WAIT_COUNT 200
1328/**
1329 * i40e_pf_reset - Reset the PF
1330 * @hw: pointer to the hardware structure
1331 *
1332 * Assuming someone else has triggered a global reset,
1333 * assure the global reset is complete and then reset the PF
1334 **/
1335enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
1336{
1337 u32 cnt = 0;
1338 u32 cnt1 = 0;
1339 u32 reg = 0;
1340 u32 grst_del;
1341
1342 /* Poll for Global Reset steady state in case of recent GRST.
1343 * The grst delay value is in 100ms units, and we'll wait a
1344 * couple counts longer to be sure we don't just miss the end.
1345 */
1346 grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
1347 I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
1348 I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
1349
1350 grst_del = grst_del * 20;
1351
1352 for (cnt = 0; cnt < grst_del; cnt++) {
1353 reg = rd32(hw, I40E_GLGEN_RSTAT);
1354 if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
1355 break;
1356 i40e_msec_delay(100);
1357 }
1358 if (reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
1359 DEBUGOUT("Global reset polling failed to complete.\n");
1360 return I40E_ERR_RESET_FAILED;
1361 }
1362
1363 /* Now Wait for the FW to be ready */
1364 for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) {
1365 reg = rd32(hw, I40E_GLNVM_ULD);
1366 reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1367 I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK);
1368 if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1369 I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK)) {
1370 DEBUGOUT1("Core and Global modules ready %d\n", cnt1);
1371 break;
1372 }
1373 i40e_msec_delay(10);
1374 }
1375 if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1376 I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) {
1377 DEBUGOUT("wait for FW Reset complete timedout\n");
1378 DEBUGOUT1("I40E_GLNVM_ULD = 0x%x\n", reg);
1379 return I40E_ERR_RESET_FAILED;
1380 }
1381
1382 /* If there was a Global Reset in progress when we got here,
1383 * we don't need to do the PF Reset
1384 */
1385 if (!cnt) {
1386 reg = rd32(hw, I40E_PFGEN_CTRL);
1387 wr32(hw, I40E_PFGEN_CTRL,
1388 (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
1389 for (cnt = 0; cnt < I40E_PF_RESET_WAIT_COUNT; cnt++) {
1390 reg = rd32(hw, I40E_PFGEN_CTRL);
1391 if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
1392 break;
1393 i40e_msec_delay(1);
1394 }
1395 if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
1396 DEBUGOUT("PF reset polling failed to complete.\n");
1397 return I40E_ERR_RESET_FAILED;
1398 }
1399 }
1400
1401 i40e_clear_pxe_mode(hw);
1402
1403
1404 return I40E_SUCCESS;
1405}
1406
1407/**
1408 * i40e_clear_hw - clear out any left over hw state
1409 * @hw: pointer to the hw struct
1410 *
1411 * Clear queues and interrupts, typically called at init time,
1412 * but after the capabilities have been found so we know how many
1413 * queues and msix vectors have been allocated.
1414 **/
1415void i40e_clear_hw(struct i40e_hw *hw)
1416{
1417 u32 num_queues, base_queue;
1418 u32 num_pf_int;
1419 u32 num_vf_int;
1420 u32 num_vfs;
1421 u32 i, j;
1422 u32 val;
1423 u32 eol = 0x7ff;
1424
1425 /* get number of interrupts, queues, and vfs */
1426 val = rd32(hw, I40E_GLPCI_CNF2);
1427 num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
1428 I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
1429 num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >>
1430 I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT;
1431
1432 val = rd32(hw, I40E_PFLAN_QALLOC);
1433 base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >>
1434 I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
1435 j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
1436 I40E_PFLAN_QALLOC_LASTQ_SHIFT;
1437 if (val & I40E_PFLAN_QALLOC_VALID_MASK)
1438 num_queues = (j - base_queue) + 1;
1439 else
1440 num_queues = 0;
1441
1442 val = rd32(hw, I40E_PF_VT_PFALLOC);
1443 i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >>
1444 I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
1445 j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
1446 I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
1447 if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
1448 num_vfs = (j - i) + 1;
1449 else
1450 num_vfs = 0;
1451
1452 /* stop all the interrupts */
1453 wr32(hw, I40E_PFINT_ICR0_ENA, 0);
1454 val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
1455 for (i = 0; i < num_pf_int - 2; i++)
1456 wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
1457
1458 /* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
1459 val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
1460 wr32(hw, I40E_PFINT_LNKLST0, val);
1461 for (i = 0; i < num_pf_int - 2; i++)
1462 wr32(hw, I40E_PFINT_LNKLSTN(i), val);
1463 val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
1464 for (i = 0; i < num_vfs; i++)
1465 wr32(hw, I40E_VPINT_LNKLST0(i), val);
1466 for (i = 0; i < num_vf_int - 2; i++)
1467 wr32(hw, I40E_VPINT_LNKLSTN(i), val);
1468
1469 /* warn the HW of the coming Tx disables */
1470 for (i = 0; i < num_queues; i++) {
1471 u32 abs_queue_idx = base_queue + i;
1472 u32 reg_block = 0;
1473
1474 if (abs_queue_idx >= 128) {
1475 reg_block = abs_queue_idx / 128;
1476 abs_queue_idx %= 128;
1477 }
1478
1479 val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
1480 val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
1481 val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
1482 val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
1483
1484 wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), val);
1485 }
1486 i40e_usec_delay(400);
1487
1488 /* stop all the queues */
1489 for (i = 0; i < num_queues; i++) {
1490 wr32(hw, I40E_QINT_TQCTL(i), 0);
1491 wr32(hw, I40E_QTX_ENA(i), 0);
1492 wr32(hw, I40E_QINT_RQCTL(i), 0);
1493 wr32(hw, I40E_QRX_ENA(i), 0);
1494 }
1495
1496 /* short wait for all queue disables to settle */
1497 i40e_usec_delay(50);
1498}
1499
1500/**
1501 * i40e_clear_pxe_mode - clear pxe operations mode
1502 * @hw: pointer to the hw struct
1503 *
1504 * Make sure all PXE mode settings are cleared, including things
1505 * like descriptor fetch/write-back mode.
1506 **/
1507void i40e_clear_pxe_mode(struct i40e_hw *hw)
1508{
1509 if (i40e_check_asq_alive(hw))
1510 i40e_aq_clear_pxe_mode(hw, NULL);
1511}
1512
1513/**
1514 * i40e_led_is_mine - helper to find matching led
1515 * @hw: pointer to the hw struct
1516 * @idx: index into GPIO registers
1517 *
1518 * returns: 0 if no match, otherwise the value of the GPIO_CTL register
1519 */
1520static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
1521{
1522 u32 gpio_val = 0;
1523 u32 port;
1524
1525 if (!hw->func_caps.led[idx])
1526 return 0;
1527
1528 gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx));
1529 port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >>
1530 I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT;
1531
1532 /* if PRT_NUM_NA is 1 then this LED is not port specific, OR
1533 * if it is not our port then ignore
1534 */
1535 if ((gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK) ||
1536 (port != hw->port))
1537 return 0;
1538
1539 return gpio_val;
1540}
1541
1542#define I40E_COMBINED_ACTIVITY 0xA
1543#define I40E_FILTER_ACTIVITY 0xE
1544#define I40E_LINK_ACTIVITY 0xC
1545#define I40E_MAC_ACTIVITY 0xD
1546#define I40E_LED0 22
1547
1548/**
1549 * i40e_led_get - return current on/off mode
1550 * @hw: pointer to the hw struct
1551 *
1552 * The value returned is the 'mode' field as defined in the
1553 * GPIO register definitions: 0x0 = off, 0xf = on, and other
1554 * values are variations of possible behaviors relating to
1555 * blink, link, and wire.
1556 **/
1557u32 i40e_led_get(struct i40e_hw *hw)
1558{
1559 u32 current_mode = 0;
1560 u32 mode = 0;
1561 int i;
1562
1563 /* as per the documentation GPIO 22-29 are the LED
1564 * GPIO pins named LED0..LED7
1565 */
1566 for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1567 u32 gpio_val = i40e_led_is_mine(hw, i);
1568
1569 if (!gpio_val)
1570 continue;
1571
1572 /* ignore gpio LED src mode entries related to the activity
1573 * LEDs
1574 */
1575 current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
1576 >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
1577 switch (current_mode) {
1578 case I40E_COMBINED_ACTIVITY:
1579 case I40E_FILTER_ACTIVITY:
1580 case I40E_MAC_ACTIVITY:
1581 continue;
1582 default:
1583 break;
1584 }
1585
1586 mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
1587 I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT;
1588 break;
1589 }
1590
1591 return mode;
1592}
1593
1594/**
1595 * i40e_led_set - set new on/off mode
1596 * @hw: pointer to the hw struct
1597 * @mode: 0=off, 0xf=on (else see manual for mode details)
1598 * @blink: true if the LED should blink when on, false if steady
1599 *
1600 * if this function is used to turn on the blink it should
1601 * be used to disable the blink when restoring the original state.
1602 **/
1603void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
1604{
1605 u32 current_mode = 0;
1606 int i;
1607
1608 if (mode & 0xfffffff0)
1609 DEBUGOUT1("invalid mode passed in %X\n", mode);
1610
1611 /* as per the documentation GPIO 22-29 are the LED
1612 * GPIO pins named LED0..LED7
1613 */
1614 for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1615 u32 gpio_val = i40e_led_is_mine(hw, i);
1616
1617 if (!gpio_val)
1618 continue;
1619
1620 /* ignore gpio LED src mode entries related to the activity
1621 * LEDs
1622 */
1623 current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
1624 >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
1625 switch (current_mode) {
1626 case I40E_COMBINED_ACTIVITY:
1627 case I40E_FILTER_ACTIVITY:
1628 case I40E_MAC_ACTIVITY:
1629 continue;
1630 default:
1631 break;
1632 }
1633
1634 gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
1635 /* this & is a bit of paranoia, but serves as a range check */
1636 gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
1637 I40E_GLGEN_GPIO_CTL_LED_MODE_MASK);
1638
1639 if (mode == I40E_LINK_ACTIVITY)
1640 blink = false;
1641
1642 if (blink)
1643 gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
1644 else
1645 gpio_val &= ~BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
1646
1647 wr32(hw, I40E_GLGEN_GPIO_CTL(i), gpio_val);
1648 break;
1649 }
1650}
1651
1652/* Admin command wrappers */
1653
1654/**
1655 * i40e_aq_get_phy_capabilities
1656 * @hw: pointer to the hw struct
1657 * @abilities: structure for PHY capabilities to be filled
1658 * @qualified_modules: report Qualified Modules
1659 * @report_init: report init capabilities (active are default)
1660 * @cmd_details: pointer to command details structure or NULL
1661 *
1662 * Returns the various PHY abilities supported on the Port.
1663 **/
1664enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
1665 bool qualified_modules, bool report_init,
1666 struct i40e_aq_get_phy_abilities_resp *abilities,
1667 struct i40e_asq_cmd_details *cmd_details)
1668{
1669 struct i40e_aq_desc desc;
1670 enum i40e_status_code status;
1671 u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
1672
1673 if (!abilities)
1674 return I40E_ERR_PARAM;
1675
1676 i40e_fill_default_direct_cmd_desc(&desc,
1677 i40e_aqc_opc_get_phy_abilities);
1678
1679 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
1680 if (abilities_size > I40E_AQ_LARGE_BUF)
1681 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
1682
1683 if (qualified_modules)
1684 desc.params.external.param0 |=
1685 CPU_TO_LE32(I40E_AQ_PHY_REPORT_QUALIFIED_MODULES);
1686
1687 if (report_init)
1688 desc.params.external.param0 |=
1689 CPU_TO_LE32(I40E_AQ_PHY_REPORT_INITIAL_VALUES);
1690
1691 status = i40e_asq_send_command(hw, &desc, abilities, abilities_size,
1692 cmd_details);
1693
1694 if (hw->aq.asq_last_status == I40E_AQ_RC_EIO)
1695 status = I40E_ERR_UNKNOWN_PHY;
1696
1697 if (report_init) {
1698 hw->phy.phy_types = LE32_TO_CPU(abilities->phy_type);
1699 hw->phy.phy_types |= ((u64)abilities->phy_type_ext << 32);
1700 }
1701
1702 return status;
1703}
1704
1705/**
1706 * i40e_aq_set_phy_config
1707 * @hw: pointer to the hw struct
1708 * @config: structure with PHY configuration to be set
1709 * @cmd_details: pointer to command details structure or NULL
1710 *
1711 * Set the various PHY configuration parameters
1712 * supported on the Port.One or more of the Set PHY config parameters may be
1713 * ignored in an MFP mode as the PF may not have the privilege to set some
1714 * of the PHY Config parameters. This status will be indicated by the
1715 * command response.
1716 **/
1717enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
1718 struct i40e_aq_set_phy_config *config,
1719 struct i40e_asq_cmd_details *cmd_details)
1720{
1721 struct i40e_aq_desc desc;
1722 struct i40e_aq_set_phy_config *cmd =
1723 (struct i40e_aq_set_phy_config *)&desc.params.raw;
1724 enum i40e_status_code status;
1725
1726 if (!config)
1727 return I40E_ERR_PARAM;
1728
1729 i40e_fill_default_direct_cmd_desc(&desc,
1730 i40e_aqc_opc_set_phy_config);
1731
1732 *cmd = *config;
1733
1734 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1735
1736 return status;
1737}
1738
1739/**
1740 * i40e_set_fc
1741 * @hw: pointer to the hw struct
1742 *
1743 * Set the requested flow control mode using set_phy_config.
1744 **/
1745enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
1746 bool atomic_restart)
1747{
1748 enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
1749 struct i40e_aq_get_phy_abilities_resp abilities;
1750 struct i40e_aq_set_phy_config config;
1751 enum i40e_status_code status;
1752 u8 pause_mask = 0x0;
1753
1754 *aq_failures = 0x0;
1755
1756 switch (fc_mode) {
1757 case I40E_FC_FULL:
1758 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1759 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1760 break;
1761 case I40E_FC_RX_PAUSE:
1762 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1763 break;
1764 case I40E_FC_TX_PAUSE:
1765 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1766 break;
1767 default:
1768 break;
1769 }
1770
1771 /* Get the current phy config */
1772 status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
1773 NULL);
1774 if (status) {
1775 *aq_failures |= I40E_SET_FC_AQ_FAIL_GET;
1776 return status;
1777 }
1778
1779 memset(&config, 0, sizeof(config));
1780 /* clear the old pause settings */
1781 config.abilities = abilities.abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
1782 ~(I40E_AQ_PHY_FLAG_PAUSE_RX);
1783 /* set the new abilities */
1784 config.abilities |= pause_mask;
1785 /* If the abilities have changed, then set the new config */
1786 if (config.abilities != abilities.abilities) {
1787 /* Auto restart link so settings take effect */
1788 if (atomic_restart)
1789 config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
1790 /* Copy over all the old settings */
1791 config.phy_type = abilities.phy_type;
1792 config.link_speed = abilities.link_speed;
1793 config.eee_capability = abilities.eee_capability;
1794 config.eeer = abilities.eeer_val;
1795 config.low_power_ctrl = abilities.d3_lpan;
1796 status = i40e_aq_set_phy_config(hw, &config, NULL);
1797
1798 if (status)
1799 *aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
1800 }
1801 /* Update the link info */
1802 status = i40e_update_link_info(hw);
1803 if (status) {
1804 /* Wait a little bit (on 40G cards it sometimes takes a really
1805 * long time for link to come back from the atomic reset)
1806 * and try once more
1807 */
1808 i40e_msec_delay(1000);
1809 status = i40e_update_link_info(hw);
1810 }
1811 if (status)
1812 *aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
1813
1814 return status;
1815}
1816
1817/**
1818 * i40e_aq_set_mac_config
1819 * @hw: pointer to the hw struct
1820 * @max_frame_size: Maximum Frame Size to be supported by the port
1821 * @crc_en: Tell HW to append a CRC to outgoing frames
1822 * @pacing: Pacing configurations
1823 * @cmd_details: pointer to command details structure or NULL
1824 *
1825 * Configure MAC settings for frame size, jumbo frame support and the
1826 * addition of a CRC by the hardware.
1827 **/
1828enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw,
1829 u16 max_frame_size,
1830 bool crc_en, u16 pacing,
1831 struct i40e_asq_cmd_details *cmd_details)
1832{
1833 struct i40e_aq_desc desc;
1834 struct i40e_aq_set_mac_config *cmd =
1835 (struct i40e_aq_set_mac_config *)&desc.params.raw;
1836 enum i40e_status_code status;
1837
1838 if (max_frame_size == 0)
1839 return I40E_ERR_PARAM;
1840
1841 i40e_fill_default_direct_cmd_desc(&desc,
1842 i40e_aqc_opc_set_mac_config);
1843
1844 cmd->max_frame_size = CPU_TO_LE16(max_frame_size);
1845 cmd->params = ((u8)pacing & 0x0F) << 3;
1846 if (crc_en)
1847 cmd->params |= I40E_AQ_SET_MAC_CONFIG_CRC_EN;
1848
1849 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1850
1851 return status;
1852}
1853
1854/**
1855 * i40e_aq_clear_pxe_mode
1856 * @hw: pointer to the hw struct
1857 * @cmd_details: pointer to command details structure or NULL
1858 *
1859 * Tell the firmware that the driver is taking over from PXE
1860 **/
1861enum i40e_status_code i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
1862 struct i40e_asq_cmd_details *cmd_details)
1863{
1864 enum i40e_status_code status;
1865 struct i40e_aq_desc desc;
1866 struct i40e_aqc_clear_pxe *cmd =
1867 (struct i40e_aqc_clear_pxe *)&desc.params.raw;
1868
1869 i40e_fill_default_direct_cmd_desc(&desc,
1870 i40e_aqc_opc_clear_pxe_mode);
1871
1872 cmd->rx_cnt = 0x2;
1873
1874 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1875
1876 wr32(hw, I40E_GLLAN_RCTL_0, 0x1);
1877
1878 return status;
1879}
1880
1881/**
1882 * i40e_aq_set_link_restart_an
1883 * @hw: pointer to the hw struct
1884 * @enable_link: if true: enable link, if false: disable link
1885 * @cmd_details: pointer to command details structure or NULL
1886 *
1887 * Sets up the link and restarts the Auto-Negotiation over the link.
1888 **/
1889enum i40e_status_code i40e_aq_set_link_restart_an(struct i40e_hw *hw,
1890 bool enable_link, struct i40e_asq_cmd_details *cmd_details)
1891{
1892 struct i40e_aq_desc desc;
1893 struct i40e_aqc_set_link_restart_an *cmd =
1894 (struct i40e_aqc_set_link_restart_an *)&desc.params.raw;
1895 enum i40e_status_code status;
1896
1897 i40e_fill_default_direct_cmd_desc(&desc,
1898 i40e_aqc_opc_set_link_restart_an);
1899
1900 cmd->command = I40E_AQ_PHY_RESTART_AN;
1901 if (enable_link)
1902 cmd->command |= I40E_AQ_PHY_LINK_ENABLE;
1903 else
1904 cmd->command &= ~I40E_AQ_PHY_LINK_ENABLE;
1905
1906 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1907
1908 return status;
1909}
1910
1911/**
1912 * i40e_aq_get_link_info
1913 * @hw: pointer to the hw struct
1914 * @enable_lse: enable/disable LinkStatusEvent reporting
1915 * @link: pointer to link status structure - optional
1916 * @cmd_details: pointer to command details structure or NULL
1917 *
1918 * Returns the link status of the adapter.
1919 **/
1920enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
1921 bool enable_lse, struct i40e_link_status *link,
1922 struct i40e_asq_cmd_details *cmd_details)
1923{
1924 struct i40e_aq_desc desc;
1925 struct i40e_aqc_get_link_status *resp =
1926 (struct i40e_aqc_get_link_status *)&desc.params.raw;
1927 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
1928 enum i40e_status_code status;
1929 bool tx_pause, rx_pause;
1930 u16 command_flags;
1931
1932 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
1933
1934 if (enable_lse)
1935 command_flags = I40E_AQ_LSE_ENABLE;
1936 else
1937 command_flags = I40E_AQ_LSE_DISABLE;
1938 resp->command_flags = CPU_TO_LE16(command_flags);
1939
1940 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1941
1942 if (status != I40E_SUCCESS)
1943 goto aq_get_link_info_exit;
1944
1945 /* save off old link status information */
1946 i40e_memcpy(&hw->phy.link_info_old, hw_link_info,
1947 sizeof(*hw_link_info), I40E_NONDMA_TO_NONDMA);
1948
1949 /* update link status */
1950 hw_link_info->phy_type = (enum i40e_aq_phy_type)resp->phy_type;
1951 hw->phy.media_type = i40e_get_media_type(hw);
1952 hw_link_info->link_speed = (enum i40e_aq_link_speed)resp->link_speed;
1953 hw_link_info->link_info = resp->link_info;
1954 hw_link_info->an_info = resp->an_info;
1955 hw_link_info->ext_info = resp->ext_info;
1956 hw_link_info->loopback = resp->loopback;
1957 hw_link_info->max_frame_size = LE16_TO_CPU(resp->max_frame_size);
1958 hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
1959
1960 /* update fc info */
1961 tx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_TX);
1962 rx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_RX);
1963 if (tx_pause & rx_pause)
1964 hw->fc.current_mode = I40E_FC_FULL;
1965 else if (tx_pause)
1966 hw->fc.current_mode = I40E_FC_TX_PAUSE;
1967 else if (rx_pause)
1968 hw->fc.current_mode = I40E_FC_RX_PAUSE;
1969 else
1970 hw->fc.current_mode = I40E_FC_NONE;
1971
1972 if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
1973 hw_link_info->crc_enable = true;
1974 else
1975 hw_link_info->crc_enable = false;
1976
1977 if (resp->command_flags & CPU_TO_LE16(I40E_AQ_LSE_ENABLE))
1978 hw_link_info->lse_enable = true;
1979 else
1980 hw_link_info->lse_enable = false;
1981
1982 if ((hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
1983 hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
1984 hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
1985
1986 /* save link status information */
1987 if (link)
1988 i40e_memcpy(link, hw_link_info, sizeof(*hw_link_info),
1989 I40E_NONDMA_TO_NONDMA);
1990
1991 /* flag cleared so helper functions don't call AQ again */
1992 hw->phy.get_link_info = false;
1993
1994aq_get_link_info_exit:
1995 return status;
1996}
1997
1998/**
1999 * i40e_aq_set_phy_int_mask
2000 * @hw: pointer to the hw struct
2001 * @mask: interrupt mask to be set
2002 * @cmd_details: pointer to command details structure or NULL
2003 *
2004 * Set link interrupt mask.
2005 **/
2006enum i40e_status_code i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
2007 u16 mask,
2008 struct i40e_asq_cmd_details *cmd_details)
2009{
2010 struct i40e_aq_desc desc;
2011 struct i40e_aqc_set_phy_int_mask *cmd =
2012 (struct i40e_aqc_set_phy_int_mask *)&desc.params.raw;
2013 enum i40e_status_code status;
2014
2015 i40e_fill_default_direct_cmd_desc(&desc,
2016 i40e_aqc_opc_set_phy_int_mask);
2017
2018 cmd->event_mask = CPU_TO_LE16(mask);
2019
2020 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2021
2022 return status;
2023}
2024
2025/**
2026 * i40e_aq_get_local_advt_reg
2027 * @hw: pointer to the hw struct
2028 * @advt_reg: local AN advertisement register value
2029 * @cmd_details: pointer to command details structure or NULL
2030 *
2031 * Get the Local AN advertisement register value.
2032 **/
2033enum i40e_status_code i40e_aq_get_local_advt_reg(struct i40e_hw *hw,
2034 u64 *advt_reg,
2035 struct i40e_asq_cmd_details *cmd_details)
2036{
2037 struct i40e_aq_desc desc;
2038 struct i40e_aqc_an_advt_reg *resp =
2039 (struct i40e_aqc_an_advt_reg *)&desc.params.raw;
2040 enum i40e_status_code status;
2041
2042 i40e_fill_default_direct_cmd_desc(&desc,
2043 i40e_aqc_opc_get_local_advt_reg);
2044
2045 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2046
2047 if (status != I40E_SUCCESS)
2048 goto aq_get_local_advt_reg_exit;
2049
2050 *advt_reg = (u64)(LE16_TO_CPU(resp->local_an_reg1)) << 32;
2051 *advt_reg |= LE32_TO_CPU(resp->local_an_reg0);
2052
2053aq_get_local_advt_reg_exit:
2054 return status;
2055}
2056
2057/**
2058 * i40e_aq_set_local_advt_reg
2059 * @hw: pointer to the hw struct
2060 * @advt_reg: local AN advertisement register value
2061 * @cmd_details: pointer to command details structure or NULL
2062 *
2063 * Get the Local AN advertisement register value.
2064 **/
2065enum i40e_status_code i40e_aq_set_local_advt_reg(struct i40e_hw *hw,
2066 u64 advt_reg,
2067 struct i40e_asq_cmd_details *cmd_details)
2068{
2069 struct i40e_aq_desc desc;
2070 struct i40e_aqc_an_advt_reg *cmd =
2071 (struct i40e_aqc_an_advt_reg *)&desc.params.raw;
2072 enum i40e_status_code status;
2073
2074 i40e_fill_default_direct_cmd_desc(&desc,
2075 i40e_aqc_opc_get_local_advt_reg);
2076
2077 cmd->local_an_reg0 = CPU_TO_LE32(I40E_LO_DWORD(advt_reg));
2078 cmd->local_an_reg1 = CPU_TO_LE16(I40E_HI_DWORD(advt_reg));
2079
2080 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2081
2082 return status;
2083}
2084
2085/**
2086 * i40e_aq_get_partner_advt
2087 * @hw: pointer to the hw struct
2088 * @advt_reg: AN partner advertisement register value
2089 * @cmd_details: pointer to command details structure or NULL
2090 *
2091 * Get the link partner AN advertisement register value.
2092 **/
2093enum i40e_status_code i40e_aq_get_partner_advt(struct i40e_hw *hw,
2094 u64 *advt_reg,
2095 struct i40e_asq_cmd_details *cmd_details)
2096{
2097 struct i40e_aq_desc desc;
2098 struct i40e_aqc_an_advt_reg *resp =
2099 (struct i40e_aqc_an_advt_reg *)&desc.params.raw;
2100 enum i40e_status_code status;
2101
2102 i40e_fill_default_direct_cmd_desc(&desc,
2103 i40e_aqc_opc_get_partner_advt);
2104
2105 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2106
2107 if (status != I40E_SUCCESS)
2108 goto aq_get_partner_advt_exit;
2109
2110 *advt_reg = (u64)(LE16_TO_CPU(resp->local_an_reg1)) << 32;
2111 *advt_reg |= LE32_TO_CPU(resp->local_an_reg0);
2112
2113aq_get_partner_advt_exit:
2114 return status;
2115}
2116
2117/**
2118 * i40e_aq_set_lb_modes
2119 * @hw: pointer to the hw struct
2120 * @lb_modes: loopback mode to be set
2121 * @cmd_details: pointer to command details structure or NULL
2122 *
2123 * Sets loopback modes.
2124 **/
2125enum i40e_status_code i40e_aq_set_lb_modes(struct i40e_hw *hw,
2126 u16 lb_modes,
2127 struct i40e_asq_cmd_details *cmd_details)
2128{
2129 struct i40e_aq_desc desc;
2130 struct i40e_aqc_set_lb_mode *cmd =
2131 (struct i40e_aqc_set_lb_mode *)&desc.params.raw;
2132 enum i40e_status_code status;
2133
2134 i40e_fill_default_direct_cmd_desc(&desc,
2135 i40e_aqc_opc_set_lb_modes);
2136
2137 cmd->lb_mode = CPU_TO_LE16(lb_modes);
2138
2139 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2140
2141 return status;
2142}
2143
2144/**
2145 * i40e_aq_set_phy_debug
2146 * @hw: pointer to the hw struct
2147 * @cmd_flags: debug command flags
2148 * @cmd_details: pointer to command details structure or NULL
2149 *
2150 * Reset the external PHY.
2151 **/
2152enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
2153 struct i40e_asq_cmd_details *cmd_details)
2154{
2155 struct i40e_aq_desc desc;
2156 struct i40e_aqc_set_phy_debug *cmd =
2157 (struct i40e_aqc_set_phy_debug *)&desc.params.raw;
2158 enum i40e_status_code status;
2159
2160 i40e_fill_default_direct_cmd_desc(&desc,
2161 i40e_aqc_opc_set_phy_debug);
2162
2163 cmd->command_flags = cmd_flags;
2164
2165 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2166
2167 return status;
2168}
2169
2170/**
2171 * i40e_aq_add_vsi
2172 * @hw: pointer to the hw struct
2173 * @vsi_ctx: pointer to a vsi context struct
2174 * @cmd_details: pointer to command details structure or NULL
2175 *
2176 * Add a VSI context to the hardware.
2177**/
2178enum i40e_status_code i40e_aq_add_vsi(struct i40e_hw *hw,
2179 struct i40e_vsi_context *vsi_ctx,
2180 struct i40e_asq_cmd_details *cmd_details)
2181{
2182 struct i40e_aq_desc desc;
2183 struct i40e_aqc_add_get_update_vsi *cmd =
2184 (struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2185 struct i40e_aqc_add_get_update_vsi_completion *resp =
2186 (struct i40e_aqc_add_get_update_vsi_completion *)
2187 &desc.params.raw;
2188 enum i40e_status_code status;
2189
2190 i40e_fill_default_direct_cmd_desc(&desc,
2191 i40e_aqc_opc_add_vsi);
2192
2193 cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->uplink_seid);
2194 cmd->connection_type = vsi_ctx->connection_type;
2195 cmd->vf_id = vsi_ctx->vf_num;
2196 cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags);
2197
2198 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2199
2200 status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2201 sizeof(vsi_ctx->info), cmd_details);
2202
2203 if (status != I40E_SUCCESS)
2204 goto aq_add_vsi_exit;
2205
2206 vsi_ctx->seid = LE16_TO_CPU(resp->seid);
2207 vsi_ctx->vsi_number = LE16_TO_CPU(resp->vsi_number);
2208 vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
2209 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2210
2211aq_add_vsi_exit:
2212 return status;
2213}
2214
2215/**
2216 * i40e_aq_set_default_vsi
2217 * @hw: pointer to the hw struct
2218 * @seid: vsi number
2219 * @cmd_details: pointer to command details structure or NULL
2220 **/
2221enum i40e_status_code i40e_aq_set_default_vsi(struct i40e_hw *hw,
2222 u16 seid,
2223 struct i40e_asq_cmd_details *cmd_details)
2224{
2225 struct i40e_aq_desc desc;
2226 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2227 (struct i40e_aqc_set_vsi_promiscuous_modes *)
2228 &desc.params.raw;
2229 enum i40e_status_code status;
2230
2231 i40e_fill_default_direct_cmd_desc(&desc,
2232 i40e_aqc_opc_set_vsi_promiscuous_modes);
2233
2234 cmd->promiscuous_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
2235 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
2236 cmd->seid = CPU_TO_LE16(seid);
2237
2238 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2239
2240 return status;
2241}
2242
2243/**
2244 * i40e_aq_clear_default_vsi
2245 * @hw: pointer to the hw struct
2246 * @seid: vsi number
2247 * @cmd_details: pointer to command details structure or NULL
2248 **/
2249enum i40e_status_code i40e_aq_clear_default_vsi(struct i40e_hw *hw,
2250 u16 seid,
2251 struct i40e_asq_cmd_details *cmd_details)
2252{
2253 struct i40e_aq_desc desc;
2254 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2255 (struct i40e_aqc_set_vsi_promiscuous_modes *)
2256 &desc.params.raw;
2257 enum i40e_status_code status;
2258
2259 i40e_fill_default_direct_cmd_desc(&desc,
2260 i40e_aqc_opc_set_vsi_promiscuous_modes);
2261
2262 cmd->promiscuous_flags = CPU_TO_LE16(0);
2263 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
2264 cmd->seid = CPU_TO_LE16(seid);
2265
2266 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2267
2268 return status;
2269}
2270
2271/**
2272 * i40e_aq_set_vsi_unicast_promiscuous
2273 * @hw: pointer to the hw struct
2274 * @seid: vsi number
2275 * @set: set unicast promiscuous enable/disable
2276 * @cmd_details: pointer to command details structure or NULL
2277 * @rx_only_promisc: flag to decide if egress traffic gets mirrored in promisc
2278 **/
2279enum i40e_status_code i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
2280 u16 seid, bool set,
2281 struct i40e_asq_cmd_details *cmd_details,
2282 bool rx_only_promisc)
2283{
2284 struct i40e_aq_desc desc;
2285 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2286 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2287 enum i40e_status_code status;
2288 u16 flags = 0;
2289
2290 i40e_fill_default_direct_cmd_desc(&desc,
2291 i40e_aqc_opc_set_vsi_promiscuous_modes);
2292
2293 if (set) {
2294 flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2295 if (rx_only_promisc &&
2296 (((hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver >= 5)) ||
2297 (hw->aq.api_maj_ver > 1)))
2298 flags |= I40E_AQC_SET_VSI_PROMISC_TX;
2299 }
2300
2301 cmd->promiscuous_flags = CPU_TO_LE16(flags);
2302
2303 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2304 if (((hw->aq.api_maj_ver >= 1) && (hw->aq.api_min_ver >= 5)) ||
2305 (hw->aq.api_maj_ver > 1))
2306 cmd->valid_flags |= CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_TX);
2307
2308 cmd->seid = CPU_TO_LE16(seid);
2309 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2310
2311 return status;
2312}
2313
2314/**
2315 * i40e_aq_set_vsi_multicast_promiscuous
2316 * @hw: pointer to the hw struct
2317 * @seid: vsi number
2318 * @set: set multicast promiscuous enable/disable
2319 * @cmd_details: pointer to command details structure or NULL
2320 **/
2321enum i40e_status_code i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
2322 u16 seid, bool set, struct i40e_asq_cmd_details *cmd_details)
2323{
2324 struct i40e_aq_desc desc;
2325 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2326 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2327 enum i40e_status_code status;
2328 u16 flags = 0;
2329
2330 i40e_fill_default_direct_cmd_desc(&desc,
2331 i40e_aqc_opc_set_vsi_promiscuous_modes);
2332
2333 if (set)
2334 flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2335
2336 cmd->promiscuous_flags = CPU_TO_LE16(flags);
2337
2338 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2339
2340 cmd->seid = CPU_TO_LE16(seid);
2341 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2342
2343 return status;
2344}
2345
2346/**
2347 * i40e_aq_set_vsi_mc_promisc_on_vlan
2348 * @hw: pointer to the hw struct
2349 * @seid: vsi number
2350 * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2351 * @vid: The VLAN tag filter - capture any multicast packet with this VLAN tag
2352 * @cmd_details: pointer to command details structure or NULL
2353 **/
2354enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
2355 u16 seid, bool enable, u16 vid,
2356 struct i40e_asq_cmd_details *cmd_details)
2357{
2358 struct i40e_aq_desc desc;
2359 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2360 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2361 enum i40e_status_code status;
2362 u16 flags = 0;
2363
2364 i40e_fill_default_direct_cmd_desc(&desc,
2365 i40e_aqc_opc_set_vsi_promiscuous_modes);
2366
2367 if (enable)
2368 flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2369
2370 cmd->promiscuous_flags = CPU_TO_LE16(flags);
2371 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2372 cmd->seid = CPU_TO_LE16(seid);
2373 cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2374
2375 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2376
2377 return status;
2378}
2379
2380/**
2381 * i40e_aq_set_vsi_uc_promisc_on_vlan
2382 * @hw: pointer to the hw struct
2383 * @seid: vsi number
2384 * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2385 * @vid: The VLAN tag filter - capture any unicast packet with this VLAN tag
2386 * @cmd_details: pointer to command details structure or NULL
2387 **/
2388enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
2389 u16 seid, bool enable, u16 vid,
2390 struct i40e_asq_cmd_details *cmd_details)
2391{
2392 struct i40e_aq_desc desc;
2393 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2394 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2395 enum i40e_status_code status;
2396 u16 flags = 0;
2397
2398 i40e_fill_default_direct_cmd_desc(&desc,
2399 i40e_aqc_opc_set_vsi_promiscuous_modes);
2400
2401 if (enable)
2402 flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2403
2404 cmd->promiscuous_flags = CPU_TO_LE16(flags);
2405 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2406 cmd->seid = CPU_TO_LE16(seid);
2407 cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2408
2409 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2410
2411 return status;
2412}
2413
2414/**
2415 * i40e_aq_set_vsi_broadcast
2416 * @hw: pointer to the hw struct
2417 * @seid: vsi number
2418 * @set_filter: true to set filter, false to clear filter
2419 * @cmd_details: pointer to command details structure or NULL
2420 *
2421 * Set or clear the broadcast promiscuous flag (filter) for a given VSI.
2422 **/
2423enum i40e_status_code i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
2424 u16 seid, bool set_filter,
2425 struct i40e_asq_cmd_details *cmd_details)
2426{
2427 struct i40e_aq_desc desc;
2428 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2429 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2430 enum i40e_status_code status;
2431
2432 i40e_fill_default_direct_cmd_desc(&desc,
2433 i40e_aqc_opc_set_vsi_promiscuous_modes);
2434
2435 if (set_filter)
2436 cmd->promiscuous_flags
2437 |= CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2438 else
2439 cmd->promiscuous_flags
2440 &= CPU_TO_LE16(~I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2441
2442 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2443 cmd->seid = CPU_TO_LE16(seid);
2444 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2445
2446 return status;
2447}
2448
2449/**
2450 * i40e_aq_set_vsi_vlan_promisc - control the VLAN promiscuous setting
2451 * @hw: pointer to the hw struct
2452 * @seid: vsi number
2453 * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2454 * @cmd_details: pointer to command details structure or NULL
2455 **/
2456enum i40e_status_code i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
2457 u16 seid, bool enable,
2458 struct i40e_asq_cmd_details *cmd_details)
2459{
2460 struct i40e_aq_desc desc;
2461 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2462 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2463 enum i40e_status_code status;
2464 u16 flags = 0;
2465
2466 i40e_fill_default_direct_cmd_desc(&desc,
2467 i40e_aqc_opc_set_vsi_promiscuous_modes);
2468 if (enable)
2469 flags |= I40E_AQC_SET_VSI_PROMISC_VLAN;
2470
2471 cmd->promiscuous_flags = CPU_TO_LE16(flags);
2472 cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_VLAN);
2473 cmd->seid = CPU_TO_LE16(seid);
2474
2475 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2476
2477 return status;
2478}
2479
2480/**
2481 * i40e_get_vsi_params - get VSI configuration info
2482 * @hw: pointer to the hw struct
2483 * @vsi_ctx: pointer to a vsi context struct
2484 * @cmd_details: pointer to command details structure or NULL
2485 **/
2486enum i40e_status_code i40e_aq_get_vsi_params(struct i40e_hw *hw,
2487 struct i40e_vsi_context *vsi_ctx,
2488 struct i40e_asq_cmd_details *cmd_details)
2489{
2490 struct i40e_aq_desc desc;
2491 struct i40e_aqc_add_get_update_vsi *cmd =
2492 (struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2493 struct i40e_aqc_add_get_update_vsi_completion *resp =
2494 (struct i40e_aqc_add_get_update_vsi_completion *)
2495 &desc.params.raw;
2496 enum i40e_status_code status;
2497
2498 UNREFERENCED_1PARAMETER(cmd_details);
2499 i40e_fill_default_direct_cmd_desc(&desc,
2500 i40e_aqc_opc_get_vsi_parameters);
2501
2502 cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->seid);
2503
2504 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
2505
2506 status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2507 sizeof(vsi_ctx->info), NULL);
2508
2509 if (status != I40E_SUCCESS)
2510 goto aq_get_vsi_params_exit;
2511
2512 vsi_ctx->seid = LE16_TO_CPU(resp->seid);
2513 vsi_ctx->vsi_number = LE16_TO_CPU(resp->vsi_number);
2514 vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
2515 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2516
2517aq_get_vsi_params_exit:
2518 return status;
2519}
2520
2521/**
2522 * i40e_aq_update_vsi_params
2523 * @hw: pointer to the hw struct
2524 * @vsi_ctx: pointer to a vsi context struct
2525 * @cmd_details: pointer to command details structure or NULL
2526 *
2527 * Update a VSI context.
2528 **/
2529enum i40e_status_code i40e_aq_update_vsi_params(struct i40e_hw *hw,
2530 struct i40e_vsi_context *vsi_ctx,
2531 struct i40e_asq_cmd_details *cmd_details)
2532{
2533 struct i40e_aq_desc desc;
2534 struct i40e_aqc_add_get_update_vsi *cmd =
2535 (struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2536 struct i40e_aqc_add_get_update_vsi_completion *resp =
2537 (struct i40e_aqc_add_get_update_vsi_completion *)
2538 &desc.params.raw;
2539 enum i40e_status_code status;
2540
2541 i40e_fill_default_direct_cmd_desc(&desc,
2542 i40e_aqc_opc_update_vsi_parameters);
2543 cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->seid);
2544
2545 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2546
2547 status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2548 sizeof(vsi_ctx->info), cmd_details);
2549
2550 vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
2551 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2552
2553 return status;
2554}
2555
2556/**
2557 * i40e_aq_get_switch_config
2558 * @hw: pointer to the hardware structure
2559 * @buf: pointer to the result buffer
2560 * @buf_size: length of input buffer
2561 * @start_seid: seid to start for the report, 0 == beginning
2562 * @cmd_details: pointer to command details structure or NULL
2563 *
2564 * Fill the buf with switch configuration returned from AdminQ command
2565 **/
2566enum i40e_status_code i40e_aq_get_switch_config(struct i40e_hw *hw,
2567 struct i40e_aqc_get_switch_config_resp *buf,
2568 u16 buf_size, u16 *start_seid,
2569 struct i40e_asq_cmd_details *cmd_details)
2570{
2571 struct i40e_aq_desc desc;
2572 struct i40e_aqc_switch_seid *scfg =
2573 (struct i40e_aqc_switch_seid *)&desc.params.raw;
2574 enum i40e_status_code status;
2575
2576 i40e_fill_default_direct_cmd_desc(&desc,
2577 i40e_aqc_opc_get_switch_config);
2578 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
2579 if (buf_size > I40E_AQ_LARGE_BUF)
2580 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
2581 scfg->seid = CPU_TO_LE16(*start_seid);
2582
2583 status = i40e_asq_send_command(hw, &desc, buf, buf_size, cmd_details);
2584 *start_seid = LE16_TO_CPU(scfg->seid);
2585
2586 return status;
2587}
2588
2589/**
2590 * i40e_aq_set_switch_config
2591 * @hw: pointer to the hardware structure
2592 * @flags: bit flag values to set
2593 * @valid_flags: which bit flags to set
2594 * @cmd_details: pointer to command details structure or NULL
2595 *
2596 * Set switch configuration bits
2597 **/
2598enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
2599 u16 flags, u16 valid_flags,
2600 struct i40e_asq_cmd_details *cmd_details)
2601{
2602 struct i40e_aq_desc desc;
2603 struct i40e_aqc_set_switch_config *scfg =
2604 (struct i40e_aqc_set_switch_config *)&desc.params.raw;
2605 enum i40e_status_code status;
2606
2607 i40e_fill_default_direct_cmd_desc(&desc,
2608 i40e_aqc_opc_set_switch_config);
2609 scfg->flags = CPU_TO_LE16(flags);
2610 scfg->valid_flags = CPU_TO_LE16(valid_flags);
2611
2612 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2613
2614 return status;
2615}
2616
2617/**
2618 * i40e_aq_get_firmware_version
2619 * @hw: pointer to the hw struct
2620 * @fw_major_version: firmware major version
2621 * @fw_minor_version: firmware minor version
2622 * @fw_build: firmware build number
2623 * @api_major_version: major queue version
2624 * @api_minor_version: minor queue version
2625 * @cmd_details: pointer to command details structure or NULL
2626 *
2627 * Get the firmware version from the admin queue commands
2628 **/
2629enum i40e_status_code i40e_aq_get_firmware_version(struct i40e_hw *hw,
2630 u16 *fw_major_version, u16 *fw_minor_version,
2631 u32 *fw_build,
2632 u16 *api_major_version, u16 *api_minor_version,
2633 struct i40e_asq_cmd_details *cmd_details)
2634{
2635 struct i40e_aq_desc desc;
2636 struct i40e_aqc_get_version *resp =
2637 (struct i40e_aqc_get_version *)&desc.params.raw;
2638 enum i40e_status_code status;
2639
2640 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_version);
2641
2642 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2643
2644 if (status == I40E_SUCCESS) {
2645 if (fw_major_version != NULL)
2646 *fw_major_version = LE16_TO_CPU(resp->fw_major);
2647 if (fw_minor_version != NULL)
2648 *fw_minor_version = LE16_TO_CPU(resp->fw_minor);
2649 if (fw_build != NULL)
2650 *fw_build = LE32_TO_CPU(resp->fw_build);
2651 if (api_major_version != NULL)
2652 *api_major_version = LE16_TO_CPU(resp->api_major);
2653 if (api_minor_version != NULL)
2654 *api_minor_version = LE16_TO_CPU(resp->api_minor);
2655
2656 /* A workaround to fix the API version in SW */
2657 if (api_major_version && api_minor_version &&
2658 fw_major_version && fw_minor_version &&
2659 ((*api_major_version == 1) && (*api_minor_version == 1)) &&
2660 (((*fw_major_version == 4) && (*fw_minor_version >= 2)) ||
2661 (*fw_major_version > 4)))
2662 *api_minor_version = 2;
2663 }
2664
2665 return status;
2666}
2667
2668/**
2669 * i40e_aq_send_driver_version
2670 * @hw: pointer to the hw struct
2671 * @dv: driver's major, minor version
2672 * @cmd_details: pointer to command details structure or NULL
2673 *
2674 * Send the driver version to the firmware
2675 **/
2676enum i40e_status_code i40e_aq_send_driver_version(struct i40e_hw *hw,
2677 struct i40e_driver_version *dv,
2678 struct i40e_asq_cmd_details *cmd_details)
2679{
2680 struct i40e_aq_desc desc;
2681 struct i40e_aqc_driver_version *cmd =
2682 (struct i40e_aqc_driver_version *)&desc.params.raw;
2683 enum i40e_status_code status;
2684 u16 len;
2685
2686 if (dv == NULL)
2687 return I40E_ERR_PARAM;
2688
2689 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_driver_version);
2690
2691 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
2692 cmd->driver_major_ver = dv->major_version;
2693 cmd->driver_minor_ver = dv->minor_version;
2694 cmd->driver_build_ver = dv->build_version;
2695 cmd->driver_subbuild_ver = dv->subbuild_version;
2696
2697 len = 0;
2698 while (len < sizeof(dv->driver_string) &&
2699 (dv->driver_string[len] < 0x80) &&
2700 dv->driver_string[len])
2701 len++;
2702 status = i40e_asq_send_command(hw, &desc, dv->driver_string,
2703 len, cmd_details);
2704
2705 return status;
2706}
2707
2708/**
2709 * i40e_get_link_status - get status of the HW network link
2710 * @hw: pointer to the hw struct
2711 * @link_up: pointer to bool (true/false = linkup/linkdown)
2712 *
2713 * Variable link_up true if link is up, false if link is down.
2714 * The variable link_up is invalid if returned value of status != I40E_SUCCESS
2715 *
2716 * Side effect: LinkStatusEvent reporting becomes enabled
2717 **/
2718enum i40e_status_code i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
2719{
2720 enum i40e_status_code status = I40E_SUCCESS;
2721
2722 if (hw->phy.get_link_info) {
2723 status = i40e_update_link_info(hw);
2724
2725 if (status != I40E_SUCCESS)
2726 i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
2727 status);
2728 }
2729
2730 *link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
2731
2732 return status;
2733}
2734
2735/**
2736 * i40e_updatelink_status - update status of the HW network link
2737 * @hw: pointer to the hw struct
2738 **/
2739enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw)
2740{
2741 struct i40e_aq_get_phy_abilities_resp abilities;
2742 enum i40e_status_code status = I40E_SUCCESS;
2743
2744 status = i40e_aq_get_link_info(hw, true, NULL, NULL);
2745 if (status)
2746 return status;
2747
2748 if (hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) {
2749 status = i40e_aq_get_phy_capabilities(hw, false, false,
2750 &abilities, NULL);
2751 if (status)
2752 return status;
2753
2754 memcpy(hw->phy.link_info.module_type, &abilities.module_type,
2755 sizeof(hw->phy.link_info.module_type));
2756 }
2757 return status;
2758}
2759
2760
2761/**
2762 * i40e_get_link_speed
2763 * @hw: pointer to the hw struct
2764 *
2765 * Returns the link speed of the adapter.
2766 **/
2767enum i40e_aq_link_speed i40e_get_link_speed(struct i40e_hw *hw)
2768{
2769 enum i40e_aq_link_speed speed = I40E_LINK_SPEED_UNKNOWN;
2770 enum i40e_status_code status = I40E_SUCCESS;
2771
2772 if (hw->phy.get_link_info) {
2773 status = i40e_aq_get_link_info(hw, true, NULL, NULL);
2774
2775 if (status != I40E_SUCCESS)
2776 goto i40e_link_speed_exit;
2777 }
2778
2779 speed = hw->phy.link_info.link_speed;
2780
2781i40e_link_speed_exit:
2782 return speed;
2783}
2784
2785/**
2786 * i40e_aq_add_veb - Insert a VEB between the VSI and the MAC
2787 * @hw: pointer to the hw struct
2788 * @uplink_seid: the MAC or other gizmo SEID
2789 * @downlink_seid: the VSI SEID
2790 * @enabled_tc: bitmap of TCs to be enabled
2791 * @default_port: true for default port VSI, false for control port
2792 * @veb_seid: pointer to where to put the resulting VEB SEID
2793 * @enable_stats: true to turn on VEB stats
2794 * @cmd_details: pointer to command details structure or NULL
2795 *
2796 * This asks the FW to add a VEB between the uplink and downlink
2797 * elements. If the uplink SEID is 0, this will be a floating VEB.
2798 **/
2799enum i40e_status_code i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
2800 u16 downlink_seid, u8 enabled_tc,
2801 bool default_port, u16 *veb_seid,
2802 bool enable_stats,
2803 struct i40e_asq_cmd_details *cmd_details)
2804{
2805 struct i40e_aq_desc desc;
2806 struct i40e_aqc_add_veb *cmd =
2807 (struct i40e_aqc_add_veb *)&desc.params.raw;
2808 struct i40e_aqc_add_veb_completion *resp =
2809 (struct i40e_aqc_add_veb_completion *)&desc.params.raw;
2810 enum i40e_status_code status;
2811 u16 veb_flags = 0;
2812
2813 /* SEIDs need to either both be set or both be 0 for floating VEB */
2814 if (!!uplink_seid != !!downlink_seid)
2815 return I40E_ERR_PARAM;
2816
2817 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_veb);
2818
2819 cmd->uplink_seid = CPU_TO_LE16(uplink_seid);
2820 cmd->downlink_seid = CPU_TO_LE16(downlink_seid);
2821 cmd->enable_tcs = enabled_tc;
2822 if (!uplink_seid)
2823 veb_flags |= I40E_AQC_ADD_VEB_FLOATING;
2824 if (default_port)
2825 veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT;
2826 else
2827 veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;
2828
2829 /* reverse logic here: set the bitflag to disable the stats */
2830 if (!enable_stats)
2831 veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;
2832
2833 cmd->veb_flags = CPU_TO_LE16(veb_flags);
2834
2835 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2836
2837 if (!status && veb_seid)
2838 *veb_seid = LE16_TO_CPU(resp->veb_seid);
2839
2840 return status;
2841}
2842
2843/**
2844 * i40e_aq_get_veb_parameters - Retrieve VEB parameters
2845 * @hw: pointer to the hw struct
2846 * @veb_seid: the SEID of the VEB to query
2847 * @switch_id: the uplink switch id
2848 * @floating: set to true if the VEB is floating
2849 * @statistic_index: index of the stats counter block for this VEB
2850 * @vebs_used: number of VEB's used by function
2851 * @vebs_free: total VEB's not reserved by any function
2852 * @cmd_details: pointer to command details structure or NULL
2853 *
2854 * This retrieves the parameters for a particular VEB, specified by
2855 * uplink_seid, and returns them to the caller.
2856 **/
2857enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw,
2858 u16 veb_seid, u16 *switch_id,
2859 bool *floating, u16 *statistic_index,
2860 u16 *vebs_used, u16 *vebs_free,
2861 struct i40e_asq_cmd_details *cmd_details)
2862{
2863 struct i40e_aq_desc desc;
2864 struct i40e_aqc_get_veb_parameters_completion *cmd_resp =
2865 (struct i40e_aqc_get_veb_parameters_completion *)
2866 &desc.params.raw;
2867 enum i40e_status_code status;
2868
2869 if (veb_seid == 0)
2870 return I40E_ERR_PARAM;
2871
2872 i40e_fill_default_direct_cmd_desc(&desc,
2873 i40e_aqc_opc_get_veb_parameters);
2874 cmd_resp->seid = CPU_TO_LE16(veb_seid);
2875
2876 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2877 if (status)
2878 goto get_veb_exit;
2879
2880 if (switch_id)
2881 *switch_id = LE16_TO_CPU(cmd_resp->switch_id);
2882 if (statistic_index)
2883 *statistic_index = LE16_TO_CPU(cmd_resp->statistic_index);
2884 if (vebs_used)
2885 *vebs_used = LE16_TO_CPU(cmd_resp->vebs_used);
2886 if (vebs_free)
2887 *vebs_free = LE16_TO_CPU(cmd_resp->vebs_free);
2888 if (floating) {
2889 u16 flags = LE16_TO_CPU(cmd_resp->veb_flags);
2890
2891 if (flags & I40E_AQC_ADD_VEB_FLOATING)
2892 *floating = true;
2893 else
2894 *floating = false;
2895 }
2896
2897get_veb_exit:
2898 return status;
2899}
2900
2901/**
2902 * i40e_aq_add_macvlan
2903 * @hw: pointer to the hw struct
2904 * @seid: VSI for the mac address
2905 * @mv_list: list of macvlans to be added
2906 * @count: length of the list
2907 * @cmd_details: pointer to command details structure or NULL
2908 *
2909 * Add MAC/VLAN addresses to the HW filtering
2910 **/
2911enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
2912 struct i40e_aqc_add_macvlan_element_data *mv_list,
2913 u16 count, struct i40e_asq_cmd_details *cmd_details)
2914{
2915 struct i40e_aq_desc desc;
2916 struct i40e_aqc_macvlan *cmd =
2917 (struct i40e_aqc_macvlan *)&desc.params.raw;
2918 enum i40e_status_code status;
2919 u16 buf_size;
2920 int i;
2921
2922 if (count == 0 || !mv_list || !hw)
2923 return I40E_ERR_PARAM;
2924
2925 buf_size = count * sizeof(*mv_list);
2926
2927 /* prep the rest of the request */
2928 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
2929 cmd->num_addresses = CPU_TO_LE16(count);
2930 cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
2931 cmd->seid[1] = 0;
2932 cmd->seid[2] = 0;
2933
2934 for (i = 0; i < count; i++)
2935 if (I40E_IS_MULTICAST(mv_list[i].mac_addr))
2936 mv_list[i].flags |=
2937 CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
2938
2939 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2940 if (buf_size > I40E_AQ_LARGE_BUF)
2941 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
2942
2943 status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
2944 cmd_details);
2945
2946 return status;
2947}
2948
2949/**
2950 * i40e_aq_remove_macvlan
2951 * @hw: pointer to the hw struct
2952 * @seid: VSI for the mac address
2953 * @mv_list: list of macvlans to be removed
2954 * @count: length of the list
2955 * @cmd_details: pointer to command details structure or NULL
2956 *
2957 * Remove MAC/VLAN addresses from the HW filtering
2958 **/
2959enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
2960 struct i40e_aqc_remove_macvlan_element_data *mv_list,
2961 u16 count, struct i40e_asq_cmd_details *cmd_details)
2962{
2963 struct i40e_aq_desc desc;
2964 struct i40e_aqc_macvlan *cmd =
2965 (struct i40e_aqc_macvlan *)&desc.params.raw;
2966 enum i40e_status_code status;
2967 u16 buf_size;
2968
2969 if (count == 0 || !mv_list || !hw)
2970 return I40E_ERR_PARAM;
2971
2972 buf_size = count * sizeof(*mv_list);
2973
2974 /* prep the rest of the request */
2975 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
2976 cmd->num_addresses = CPU_TO_LE16(count);
2977 cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
2978 cmd->seid[1] = 0;
2979 cmd->seid[2] = 0;
2980
2981 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2982 if (buf_size > I40E_AQ_LARGE_BUF)
2983 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
2984
2985 status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
2986 cmd_details);
2987
2988 return status;
2989}
2990
2991/**
2992 * i40e_mirrorrule_op - Internal helper function to add/delete mirror rule
2993 * @hw: pointer to the hw struct
2994 * @opcode: AQ opcode for add or delete mirror rule
2995 * @sw_seid: Switch SEID (to which rule refers)
2996 * @rule_type: Rule Type (ingress/egress/VLAN)
2997 * @id: Destination VSI SEID or Rule ID
2998 * @count: length of the list
2999 * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
3000 * @cmd_details: pointer to command details structure or NULL
3001 * @rule_id: Rule ID returned from FW
3002 * @rule_used: Number of rules used in internal switch
3003 * @rule_free: Number of rules free in internal switch
3004 *
3005 * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
3006 * VEBs/VEPA elements only
3007 **/
3008static enum i40e_status_code i40e_mirrorrule_op(struct i40e_hw *hw,
3009 u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
3010 u16 count, __le16 *mr_list,
3011 struct i40e_asq_cmd_details *cmd_details,
3012 u16 *rule_id, u16 *rules_used, u16 *rules_free)
3013{
3014 struct i40e_aq_desc desc;
3015 struct i40e_aqc_add_delete_mirror_rule *cmd =
3016 (struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
3017 struct i40e_aqc_add_delete_mirror_rule_completion *resp =
3018 (struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
3019 enum i40e_status_code status;
3020 u16 buf_size;
3021
3022 buf_size = count * sizeof(*mr_list);
3023
3024 /* prep the rest of the request */
3025 i40e_fill_default_direct_cmd_desc(&desc, opcode);
3026 cmd->seid = CPU_TO_LE16(sw_seid);
3027 cmd->rule_type = CPU_TO_LE16(rule_type &
3028 I40E_AQC_MIRROR_RULE_TYPE_MASK);
3029 cmd->num_entries = CPU_TO_LE16(count);
3030 /* Dest VSI for add, rule_id for delete */
3031 cmd->destination = CPU_TO_LE16(id);
3032 if (mr_list) {
3033 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
3034 I40E_AQ_FLAG_RD));
3035 if (buf_size > I40E_AQ_LARGE_BUF)
3036 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3037 }
3038
3039 status = i40e_asq_send_command(hw, &desc, mr_list, buf_size,
3040 cmd_details);
3041 if (status == I40E_SUCCESS ||
3042 hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) {
3043 if (rule_id)
3044 *rule_id = LE16_TO_CPU(resp->rule_id);
3045 if (rules_used)
3046 *rules_used = LE16_TO_CPU(resp->mirror_rules_used);
3047 if (rules_free)
3048 *rules_free = LE16_TO_CPU(resp->mirror_rules_free);
3049 }
3050 return status;
3051}
3052
3053/**
3054 * i40e_aq_add_mirrorrule - add a mirror rule
3055 * @hw: pointer to the hw struct
3056 * @sw_seid: Switch SEID (to which rule refers)
3057 * @rule_type: Rule Type (ingress/egress/VLAN)
3058 * @dest_vsi: SEID of VSI to which packets will be mirrored
3059 * @count: length of the list
3060 * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
3061 * @cmd_details: pointer to command details structure or NULL
3062 * @rule_id: Rule ID returned from FW
3063 * @rule_used: Number of rules used in internal switch
3064 * @rule_free: Number of rules free in internal switch
3065 *
3066 * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
3067 **/
3068enum i40e_status_code i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
3069 u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
3070 struct i40e_asq_cmd_details *cmd_details,
3071 u16 *rule_id, u16 *rules_used, u16 *rules_free)
3072{
3073 if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
3074 rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
3075 if (count == 0 || !mr_list)
3076 return I40E_ERR_PARAM;
3077 }
3078
3079 return i40e_mirrorrule_op(hw, i40e_aqc_opc_add_mirror_rule, sw_seid,
3080 rule_type, dest_vsi, count, mr_list,
3081 cmd_details, rule_id, rules_used, rules_free);
3082}
3083
3084/**
3085 * i40e_aq_delete_mirrorrule - delete a mirror rule
3086 * @hw: pointer to the hw struct
3087 * @sw_seid: Switch SEID (to which rule refers)
3088 * @rule_type: Rule Type (ingress/egress/VLAN)
3089 * @count: length of the list
3090 * @rule_id: Rule ID that is returned in the receive desc as part of
3091 * add_mirrorrule.
3092 * @mr_list: list of mirrored VLAN IDs to be removed
3093 * @cmd_details: pointer to command details structure or NULL
3094 * @rule_used: Number of rules used in internal switch
3095 * @rule_free: Number of rules free in internal switch
3096 *
3097 * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
3098 **/
3099enum i40e_status_code i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
3100 u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
3101 struct i40e_asq_cmd_details *cmd_details,
3102 u16 *rules_used, u16 *rules_free)
3103{
3104 /* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
3105 if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
3106 /* count and mr_list shall be valid for rule_type INGRESS VLAN
3107 * mirroring. For other rule_type, count and rule_type should
3108 * not matter.
3109 */
3110 if (count == 0 || !mr_list)
3111 return I40E_ERR_PARAM;
3112 }
3113
3114 return i40e_mirrorrule_op(hw, i40e_aqc_opc_delete_mirror_rule, sw_seid,
3115 rule_type, rule_id, count, mr_list,
3116 cmd_details, NULL, rules_used, rules_free);
3117}
3118
3119/**
3120 * i40e_aq_add_vlan - Add VLAN ids to the HW filtering
3121 * @hw: pointer to the hw struct
3122 * @seid: VSI for the vlan filters
3123 * @v_list: list of vlan filters to be added
3124 * @count: length of the list
3125 * @cmd_details: pointer to command details structure or NULL
3126 **/
3127enum i40e_status_code i40e_aq_add_vlan(struct i40e_hw *hw, u16 seid,
3128 struct i40e_aqc_add_remove_vlan_element_data *v_list,
3129 u8 count, struct i40e_asq_cmd_details *cmd_details)
3130{
3131 struct i40e_aq_desc desc;
3132 struct i40e_aqc_macvlan *cmd =
3133 (struct i40e_aqc_macvlan *)&desc.params.raw;
3134 enum i40e_status_code status;
3135 u16 buf_size;
3136
3137 if (count == 0 || !v_list || !hw)
3138 return I40E_ERR_PARAM;
3139
3140 buf_size = count * sizeof(*v_list);
3141
3142 /* prep the rest of the request */
3143 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_vlan);
3144 cmd->num_addresses = CPU_TO_LE16(count);
3145 cmd->seid[0] = CPU_TO_LE16(seid | I40E_AQC_MACVLAN_CMD_SEID_VALID);
3146 cmd->seid[1] = 0;
3147 cmd->seid[2] = 0;
3148
3149 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3150 if (buf_size > I40E_AQ_LARGE_BUF)
3151 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3152
3153 status = i40e_asq_send_command(hw, &desc, v_list, buf_size,
3154 cmd_details);
3155
3156 return status;
3157}
3158
3159/**
3160 * i40e_aq_remove_vlan - Remove VLANs from the HW filtering
3161 * @hw: pointer to the hw struct
3162 * @seid: VSI for the vlan filters
3163 * @v_list: list of macvlans to be removed
3164 * @count: length of the list
3165 * @cmd_details: pointer to command details structure or NULL
3166 **/
3167enum i40e_status_code i40e_aq_remove_vlan(struct i40e_hw *hw, u16 seid,
3168 struct i40e_aqc_add_remove_vlan_element_data *v_list,
3169 u8 count, struct i40e_asq_cmd_details *cmd_details)
3170{
3171 struct i40e_aq_desc desc;
3172 struct i40e_aqc_macvlan *cmd =
3173 (struct i40e_aqc_macvlan *)&desc.params.raw;
3174 enum i40e_status_code status;
3175 u16 buf_size;
3176
3177 if (count == 0 || !v_list || !hw)
3178 return I40E_ERR_PARAM;
3179
3180 buf_size = count * sizeof(*v_list);
3181
3182 /* prep the rest of the request */
3183 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_vlan);
3184 cmd->num_addresses = CPU_TO_LE16(count);
3185 cmd->seid[0] = CPU_TO_LE16(seid | I40E_AQC_MACVLAN_CMD_SEID_VALID);
3186 cmd->seid[1] = 0;
3187 cmd->seid[2] = 0;
3188
3189 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3190 if (buf_size > I40E_AQ_LARGE_BUF)
3191 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3192
3193 status = i40e_asq_send_command(hw, &desc, v_list, buf_size,
3194 cmd_details);
3195
3196 return status;
3197}
3198
3199/**
3200 * i40e_aq_send_msg_to_vf
3201 * @hw: pointer to the hardware structure
3202 * @vfid: vf id to send msg
3203 * @v_opcode: opcodes for VF-PF communication
3204 * @v_retval: return error code
3205 * @msg: pointer to the msg buffer
3206 * @msglen: msg length
3207 * @cmd_details: pointer to command details
3208 *
3209 * send msg to vf
3210 **/
3211enum i40e_status_code i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
3212 u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
3213 struct i40e_asq_cmd_details *cmd_details)
3214{
3215 struct i40e_aq_desc desc;
3216 struct i40e_aqc_pf_vf_message *cmd =
3217 (struct i40e_aqc_pf_vf_message *)&desc.params.raw;
3218 enum i40e_status_code status;
3219
3220 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_vf);
3221 cmd->id = CPU_TO_LE32(vfid);
3222 desc.cookie_high = CPU_TO_LE32(v_opcode);
3223 desc.cookie_low = CPU_TO_LE32(v_retval);
3224 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
3225 if (msglen) {
3226 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
3227 I40E_AQ_FLAG_RD));
3228 if (msglen > I40E_AQ_LARGE_BUF)
3229 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3230 desc.datalen = CPU_TO_LE16(msglen);
3231 }
3232 status = i40e_asq_send_command(hw, &desc, msg, msglen, cmd_details);
3233
3234 return status;
3235}
3236
3237/**
3238 * i40e_aq_debug_read_register
3239 * @hw: pointer to the hw struct
3240 * @reg_addr: register address
3241 * @reg_val: register value
3242 * @cmd_details: pointer to command details structure or NULL
3243 *
3244 * Read the register using the admin queue commands
3245 **/
3246enum i40e_status_code i40e_aq_debug_read_register(struct i40e_hw *hw,
3247 u32 reg_addr, u64 *reg_val,
3248 struct i40e_asq_cmd_details *cmd_details)
3249{
3250 struct i40e_aq_desc desc;
3251 struct i40e_aqc_debug_reg_read_write *cmd_resp =
3252 (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3253 enum i40e_status_code status;
3254
3255 if (reg_val == NULL)
3256 return I40E_ERR_PARAM;
3257
3258 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
3259
3260 cmd_resp->address = CPU_TO_LE32(reg_addr);
3261
3262 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3263
3264 if (status == I40E_SUCCESS) {
3265 *reg_val = ((u64)LE32_TO_CPU(cmd_resp->value_high) << 32) |
3266 (u64)LE32_TO_CPU(cmd_resp->value_low);
3267 }
3268
3269 return status;
3270}
3271
3272/**
3273 * i40e_aq_debug_write_register
3274 * @hw: pointer to the hw struct
3275 * @reg_addr: register address
3276 * @reg_val: register value
3277 * @cmd_details: pointer to command details structure or NULL
3278 *
3279 * Write to a register using the admin queue commands
3280 **/
3281enum i40e_status_code i40e_aq_debug_write_register(struct i40e_hw *hw,
3282 u32 reg_addr, u64 reg_val,
3283 struct i40e_asq_cmd_details *cmd_details)
3284{
3285 struct i40e_aq_desc desc;
3286 struct i40e_aqc_debug_reg_read_write *cmd =
3287 (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3288 enum i40e_status_code status;
3289
3290 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_write_reg);
3291
3292 cmd->address = CPU_TO_LE32(reg_addr);
3293 cmd->value_high = CPU_TO_LE32((u32)(reg_val >> 32));
3294 cmd->value_low = CPU_TO_LE32((u32)(reg_val & 0xFFFFFFFF));
3295
3296 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3297
3298 return status;
3299}
3300
3301/**
3302 * i40e_aq_request_resource
3303 * @hw: pointer to the hw struct
3304 * @resource: resource id
3305 * @access: access type
3306 * @sdp_number: resource number
3307 * @timeout: the maximum time in ms that the driver may hold the resource
3308 * @cmd_details: pointer to command details structure or NULL
3309 *
3310 * requests common resource using the admin queue commands
3311 **/
3312enum i40e_status_code i40e_aq_request_resource(struct i40e_hw *hw,
3313 enum i40e_aq_resources_ids resource,
3314 enum i40e_aq_resource_access_type access,
3315 u8 sdp_number, u64 *timeout,
3316 struct i40e_asq_cmd_details *cmd_details)
3317{
3318 struct i40e_aq_desc desc;
3319 struct i40e_aqc_request_resource *cmd_resp =
3320 (struct i40e_aqc_request_resource *)&desc.params.raw;
3321 enum i40e_status_code status;
3322
3323 DEBUGFUNC("i40e_aq_request_resource");
3324
3325 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_request_resource);
3326
3327 cmd_resp->resource_id = CPU_TO_LE16(resource);
3328 cmd_resp->access_type = CPU_TO_LE16(access);
3329 cmd_resp->resource_number = CPU_TO_LE32(sdp_number);
3330
3331 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3332 /* The completion specifies the maximum time in ms that the driver
3333 * may hold the resource in the Timeout field.
3334 * If the resource is held by someone else, the command completes with
3335 * busy return value and the timeout field indicates the maximum time
3336 * the current owner of the resource has to free it.
3337 */
3338 if (status == I40E_SUCCESS || hw->aq.asq_last_status == I40E_AQ_RC_EBUSY)
3339 *timeout = LE32_TO_CPU(cmd_resp->timeout);
3340
3341 return status;
3342}
3343
3344/**
3345 * i40e_aq_release_resource
3346 * @hw: pointer to the hw struct
3347 * @resource: resource id
3348 * @sdp_number: resource number
3349 * @cmd_details: pointer to command details structure or NULL
3350 *
3351 * release common resource using the admin queue commands
3352 **/
3353enum i40e_status_code i40e_aq_release_resource(struct i40e_hw *hw,
3354 enum i40e_aq_resources_ids resource,
3355 u8 sdp_number,
3356 struct i40e_asq_cmd_details *cmd_details)
3357{
3358 struct i40e_aq_desc desc;
3359 struct i40e_aqc_request_resource *cmd =
3360 (struct i40e_aqc_request_resource *)&desc.params.raw;
3361 enum i40e_status_code status;
3362
3363 DEBUGFUNC("i40e_aq_release_resource");
3364
3365 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_release_resource);
3366
3367 cmd->resource_id = CPU_TO_LE16(resource);
3368 cmd->resource_number = CPU_TO_LE32(sdp_number);
3369
3370 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3371
3372 return status;
3373}
3374
3375/**
3376 * i40e_aq_read_nvm
3377 * @hw: pointer to the hw struct
3378 * @module_pointer: module pointer location in words from the NVM beginning
3379 * @offset: byte offset from the module beginning
3380 * @length: length of the section to be read (in bytes from the offset)
3381 * @data: command buffer (size [bytes] = length)
3382 * @last_command: tells if this is the last command in a series
3383 * @cmd_details: pointer to command details structure or NULL
3384 *
3385 * Read the NVM using the admin queue commands
3386 **/
3387enum i40e_status_code i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
3388 u32 offset, u16 length, void *data,
3389 bool last_command,
3390 struct i40e_asq_cmd_details *cmd_details)
3391{
3392 struct i40e_aq_desc desc;
3393 struct i40e_aqc_nvm_update *cmd =
3394 (struct i40e_aqc_nvm_update *)&desc.params.raw;
3395 enum i40e_status_code status;
3396
3397 DEBUGFUNC("i40e_aq_read_nvm");
3398
3399 /* In offset the highest byte must be zeroed. */
3400 if (offset & 0xFF000000) {
3401 status = I40E_ERR_PARAM;
3402 goto i40e_aq_read_nvm_exit;
3403 }
3404
3405 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_read);
3406
3407 /* If this is the last command in a series, set the proper flag. */
3408 if (last_command)
3409 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3410 cmd->module_pointer = module_pointer;
3411 cmd->offset = CPU_TO_LE32(offset);
3412 cmd->length = CPU_TO_LE16(length);
3413
3414 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
3415 if (length > I40E_AQ_LARGE_BUF)
3416 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3417
3418 status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
3419
3420i40e_aq_read_nvm_exit:
3421 return status;
3422}
3423
3424/**
3425 * i40e_aq_read_nvm_config - read an nvm config block
3426 * @hw: pointer to the hw struct
3427 * @cmd_flags: NVM access admin command bits
3428 * @field_id: field or feature id
3429 * @data: buffer for result
3430 * @buf_size: buffer size
3431 * @element_count: pointer to count of elements read by FW
3432 * @cmd_details: pointer to command details structure or NULL
3433 **/
3434enum i40e_status_code i40e_aq_read_nvm_config(struct i40e_hw *hw,
3435 u8 cmd_flags, u32 field_id, void *data,
3436 u16 buf_size, u16 *element_count,
3437 struct i40e_asq_cmd_details *cmd_details)
3438{
3439 struct i40e_aq_desc desc;
3440 struct i40e_aqc_nvm_config_read *cmd =
3441 (struct i40e_aqc_nvm_config_read *)&desc.params.raw;
3442 enum i40e_status_code status;
3443
3444 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_read);
3445 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF));
3446 if (buf_size > I40E_AQ_LARGE_BUF)
3447 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3448
3449 cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
3450 cmd->element_id = CPU_TO_LE16((u16)(0xffff & field_id));
3451 if (cmd_flags & I40E_AQ_ANVM_FEATURE_OR_IMMEDIATE_MASK)
3452 cmd->element_id_msw = CPU_TO_LE16((u16)(field_id >> 16));
3453 else
3454 cmd->element_id_msw = 0;
3455
3456 status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
3457
3458 if (!status && element_count)
3459 *element_count = LE16_TO_CPU(cmd->element_count);
3460
3461 return status;
3462}
3463
3464/**
3465 * i40e_aq_write_nvm_config - write an nvm config block
3466 * @hw: pointer to the hw struct
3467 * @cmd_flags: NVM access admin command bits
3468 * @data: buffer for result
3469 * @buf_size: buffer size
3470 * @element_count: count of elements to be written
3471 * @cmd_details: pointer to command details structure or NULL
3472 **/
3473enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw,
3474 u8 cmd_flags, void *data, u16 buf_size,
3475 u16 element_count,
3476 struct i40e_asq_cmd_details *cmd_details)
3477{
3478 struct i40e_aq_desc desc;
3479 struct i40e_aqc_nvm_config_write *cmd =
3480 (struct i40e_aqc_nvm_config_write *)&desc.params.raw;
3481 enum i40e_status_code status;
3482
3483 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_write);
3484 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3485 if (buf_size > I40E_AQ_LARGE_BUF)
3486 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3487
3488 cmd->element_count = CPU_TO_LE16(element_count);
3489 cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
3490 status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
3491
3492 return status;
3493}
3494
3495/**
3496 * i40e_aq_oem_post_update - triggers an OEM specific flow after update
3497 * @hw: pointer to the hw struct
3498 * @cmd_details: pointer to command details structure or NULL
3499 **/
3500enum i40e_status_code i40e_aq_oem_post_update(struct i40e_hw *hw,
3501 void *buff, u16 buff_size,
3502 struct i40e_asq_cmd_details *cmd_details)
3503{
3504 struct i40e_aq_desc desc;
3505 enum i40e_status_code status;
3506
3507 UNREFERENCED_2PARAMETER(buff, buff_size);
3508
3509 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_oem_post_update);
3510 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3511 if (status && LE16_TO_CPU(desc.retval) == I40E_AQ_RC_ESRCH)
3512 status = I40E_ERR_NOT_IMPLEMENTED;
3513
3514 return status;
3515}
3516
3517/**
3518 * i40e_aq_erase_nvm
3519 * @hw: pointer to the hw struct
3520 * @module_pointer: module pointer location in words from the NVM beginning
3521 * @offset: offset in the module (expressed in 4 KB from module's beginning)
3522 * @length: length of the section to be erased (expressed in 4 KB)
3523 * @last_command: tells if this is the last command in a series
3524 * @cmd_details: pointer to command details structure or NULL
3525 *
3526 * Erase the NVM sector using the admin queue commands
3527 **/
3528enum i40e_status_code i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
3529 u32 offset, u16 length, bool last_command,
3530 struct i40e_asq_cmd_details *cmd_details)
3531{
3532 struct i40e_aq_desc desc;
3533 struct i40e_aqc_nvm_update *cmd =
3534 (struct i40e_aqc_nvm_update *)&desc.params.raw;
3535 enum i40e_status_code status;
3536
3537 DEBUGFUNC("i40e_aq_erase_nvm");
3538
3539 /* In offset the highest byte must be zeroed. */
3540 if (offset & 0xFF000000) {
3541 status = I40E_ERR_PARAM;
3542 goto i40e_aq_erase_nvm_exit;
3543 }
3544
3545 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_erase);
3546
3547 /* If this is the last command in a series, set the proper flag. */
3548 if (last_command)
3549 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3550 cmd->module_pointer = module_pointer;
3551 cmd->offset = CPU_TO_LE32(offset);
3552 cmd->length = CPU_TO_LE16(length);
3553
3554 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3555
3556i40e_aq_erase_nvm_exit:
3557 return status;
3558}
3559
3560/**
3561 * i40e_parse_discover_capabilities
3562 * @hw: pointer to the hw struct
3563 * @buff: pointer to a buffer containing device/function capability records
3564 * @cap_count: number of capability records in the list
3565 * @list_type_opc: type of capabilities list to parse
3566 *
3567 * Parse the device/function capabilities list.
3568 **/
3569STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
3570 u32 cap_count,
3571 enum i40e_admin_queue_opc list_type_opc)
3572{
3573 struct i40e_aqc_list_capabilities_element_resp *cap;
3574 u32 valid_functions, num_functions;
3575 u32 number, logical_id, phys_id;
3576 struct i40e_hw_capabilities *p;
3577 u8 major_rev;
3578 u32 i = 0;
3579 u16 id;
3580
3581 cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
3582
3583 if (list_type_opc == i40e_aqc_opc_list_dev_capabilities)
3584 p = (struct i40e_hw_capabilities *)&hw->dev_caps;
3585 else if (list_type_opc == i40e_aqc_opc_list_func_capabilities)
3586 p = (struct i40e_hw_capabilities *)&hw->func_caps;
3587 else
3588 return;
3589
3590 for (i = 0; i < cap_count; i++, cap++) {
3591 id = LE16_TO_CPU(cap->id);
3592 number = LE32_TO_CPU(cap->number);
3593 logical_id = LE32_TO_CPU(cap->logical_id);
3594 phys_id = LE32_TO_CPU(cap->phys_id);
3595 major_rev = cap->major_rev;
3596
3597 switch (id) {
3598 case I40E_AQ_CAP_ID_SWITCH_MODE:
3599 p->switch_mode = number;
3600 i40e_debug(hw, I40E_DEBUG_INIT,
3601 "HW Capability: Switch mode = %d\n",
3602 p->switch_mode);
3603 break;
3604 case I40E_AQ_CAP_ID_MNG_MODE:
3605 p->management_mode = number;
3606 i40e_debug(hw, I40E_DEBUG_INIT,
3607 "HW Capability: Management Mode = %d\n",
3608 p->management_mode);
3609 break;
3610 case I40E_AQ_CAP_ID_NPAR_ACTIVE:
3611 p->npar_enable = number;
3612 i40e_debug(hw, I40E_DEBUG_INIT,
3613 "HW Capability: NPAR enable = %d\n",
3614 p->npar_enable);
3615 break;
3616 case I40E_AQ_CAP_ID_OS2BMC_CAP:
3617 p->os2bmc = number;
3618 i40e_debug(hw, I40E_DEBUG_INIT,
3619 "HW Capability: OS2BMC = %d\n", p->os2bmc);
3620 break;
3621 case I40E_AQ_CAP_ID_FUNCTIONS_VALID:
3622 p->valid_functions = number;
3623 i40e_debug(hw, I40E_DEBUG_INIT,
3624 "HW Capability: Valid Functions = %d\n",
3625 p->valid_functions);
3626 break;
3627 case I40E_AQ_CAP_ID_SRIOV:
3628 if (number == 1)
3629 p->sr_iov_1_1 = true;
3630 i40e_debug(hw, I40E_DEBUG_INIT,
3631 "HW Capability: SR-IOV = %d\n",
3632 p->sr_iov_1_1);
3633 break;
3634 case I40E_AQ_CAP_ID_VF:
3635 p->num_vfs = number;
3636 p->vf_base_id = logical_id;
3637 i40e_debug(hw, I40E_DEBUG_INIT,
3638 "HW Capability: VF count = %d\n",
3639 p->num_vfs);
3640 i40e_debug(hw, I40E_DEBUG_INIT,
3641 "HW Capability: VF base_id = %d\n",
3642 p->vf_base_id);
3643 break;
3644 case I40E_AQ_CAP_ID_VMDQ:
3645 if (number == 1)
3646 p->vmdq = true;
3647 i40e_debug(hw, I40E_DEBUG_INIT,
3648 "HW Capability: VMDQ = %d\n", p->vmdq);
3649 break;
3650 case I40E_AQ_CAP_ID_8021QBG:
3651 if (number == 1)
3652 p->evb_802_1_qbg = true;
3653 i40e_debug(hw, I40E_DEBUG_INIT,
3654 "HW Capability: 802.1Qbg = %d\n", number);
3655 break;
3656 case I40E_AQ_CAP_ID_8021QBR:
3657 if (number == 1)
3658 p->evb_802_1_qbh = true;
3659 i40e_debug(hw, I40E_DEBUG_INIT,
3660 "HW Capability: 802.1Qbh = %d\n", number);
3661 break;
3662 case I40E_AQ_CAP_ID_VSI:
3663 p->num_vsis = number;
3664 i40e_debug(hw, I40E_DEBUG_INIT,
3665 "HW Capability: VSI count = %d\n",
3666 p->num_vsis);
3667 break;
3668 case I40E_AQ_CAP_ID_DCB:
3669 if (number == 1) {
3670 p->dcb = true;
3671 p->enabled_tcmap = logical_id;
3672 p->maxtc = phys_id;
3673 }
3674 i40e_debug(hw, I40E_DEBUG_INIT,
3675 "HW Capability: DCB = %d\n", p->dcb);
3676 i40e_debug(hw, I40E_DEBUG_INIT,
3677 "HW Capability: TC Mapping = %d\n",
3678 logical_id);
3679 i40e_debug(hw, I40E_DEBUG_INIT,
3680 "HW Capability: TC Max = %d\n", p->maxtc);
3681 break;
3682 case I40E_AQ_CAP_ID_FCOE:
3683 if (number == 1)
3684 p->fcoe = true;
3685 i40e_debug(hw, I40E_DEBUG_INIT,
3686 "HW Capability: FCOE = %d\n", p->fcoe);
3687 break;
3688 case I40E_AQ_CAP_ID_ISCSI:
3689 if (number == 1)
3690 p->iscsi = true;
3691 i40e_debug(hw, I40E_DEBUG_INIT,
3692 "HW Capability: iSCSI = %d\n", p->iscsi);
3693 break;
3694 case I40E_AQ_CAP_ID_RSS:
3695 p->rss = true;
3696 p->rss_table_size = number;
3697 p->rss_table_entry_width = logical_id;
3698 i40e_debug(hw, I40E_DEBUG_INIT,
3699 "HW Capability: RSS = %d\n", p->rss);
3700 i40e_debug(hw, I40E_DEBUG_INIT,
3701 "HW Capability: RSS table size = %d\n",
3702 p->rss_table_size);
3703 i40e_debug(hw, I40E_DEBUG_INIT,
3704 "HW Capability: RSS table width = %d\n",
3705 p->rss_table_entry_width);
3706 break;
3707 case I40E_AQ_CAP_ID_RXQ:
3708 p->num_rx_qp = number;
3709 p->base_queue = phys_id;
3710 i40e_debug(hw, I40E_DEBUG_INIT,
3711 "HW Capability: Rx QP = %d\n", number);
3712 i40e_debug(hw, I40E_DEBUG_INIT,
3713 "HW Capability: base_queue = %d\n",
3714 p->base_queue);
3715 break;
3716 case I40E_AQ_CAP_ID_TXQ:
3717 p->num_tx_qp = number;
3718 p->base_queue = phys_id;
3719 i40e_debug(hw, I40E_DEBUG_INIT,
3720 "HW Capability: Tx QP = %d\n", number);
3721 i40e_debug(hw, I40E_DEBUG_INIT,
3722 "HW Capability: base_queue = %d\n",
3723 p->base_queue);
3724 break;
3725 case I40E_AQ_CAP_ID_MSIX:
3726 p->num_msix_vectors = number;
3727 i40e_debug(hw, I40E_DEBUG_INIT,
3728 "HW Capability: MSIX vector count = %d\n",
3729 p->num_msix_vectors);
3730 break;
3731 case I40E_AQ_CAP_ID_VF_MSIX:
3732 p->num_msix_vectors_vf = number;
3733 i40e_debug(hw, I40E_DEBUG_INIT,
3734 "HW Capability: MSIX VF vector count = %d\n",
3735 p->num_msix_vectors_vf);
3736 break;
3737 case I40E_AQ_CAP_ID_FLEX10:
3738 if (major_rev == 1) {
3739 if (number == 1) {
3740 p->flex10_enable = true;
3741 p->flex10_capable = true;
3742 }
3743 } else {
3744 /* Capability revision >= 2 */
3745 if (number & 1)
3746 p->flex10_enable = true;
3747 if (number & 2)
3748 p->flex10_capable = true;
3749 }
3750 p->flex10_mode = logical_id;
3751 p->flex10_status = phys_id;
3752 i40e_debug(hw, I40E_DEBUG_INIT,
3753 "HW Capability: Flex10 mode = %d\n",
3754 p->flex10_mode);
3755 i40e_debug(hw, I40E_DEBUG_INIT,
3756 "HW Capability: Flex10 status = %d\n",
3757 p->flex10_status);
3758 break;
3759 case I40E_AQ_CAP_ID_CEM:
3760 if (number == 1)
3761 p->mgmt_cem = true;
3762 i40e_debug(hw, I40E_DEBUG_INIT,
3763 "HW Capability: CEM = %d\n", p->mgmt_cem);
3764 break;
3765 case I40E_AQ_CAP_ID_IWARP:
3766 if (number == 1)
3767 p->iwarp = true;
3768 i40e_debug(hw, I40E_DEBUG_INIT,
3769 "HW Capability: iWARP = %d\n", p->iwarp);
3770 break;
3771 case I40E_AQ_CAP_ID_LED:
3772 if (phys_id < I40E_HW_CAP_MAX_GPIO)
3773 p->led[phys_id] = true;
3774 i40e_debug(hw, I40E_DEBUG_INIT,
3775 "HW Capability: LED - PIN %d\n", phys_id);
3776 break;
3777 case I40E_AQ_CAP_ID_SDP:
3778 if (phys_id < I40E_HW_CAP_MAX_GPIO)
3779 p->sdp[phys_id] = true;
3780 i40e_debug(hw, I40E_DEBUG_INIT,
3781 "HW Capability: SDP - PIN %d\n", phys_id);
3782 break;
3783 case I40E_AQ_CAP_ID_MDIO:
3784 if (number == 1) {
3785 p->mdio_port_num = phys_id;
3786 p->mdio_port_mode = logical_id;
3787 }
3788 i40e_debug(hw, I40E_DEBUG_INIT,
3789 "HW Capability: MDIO port number = %d\n",
3790 p->mdio_port_num);
3791 i40e_debug(hw, I40E_DEBUG_INIT,
3792 "HW Capability: MDIO port mode = %d\n",
3793 p->mdio_port_mode);
3794 break;
3795 case I40E_AQ_CAP_ID_1588:
3796 if (number == 1)
3797 p->ieee_1588 = true;
3798 i40e_debug(hw, I40E_DEBUG_INIT,
3799 "HW Capability: IEEE 1588 = %d\n",
3800 p->ieee_1588);
3801 break;
3802 case I40E_AQ_CAP_ID_FLOW_DIRECTOR:
3803 p->fd = true;
3804 p->fd_filters_guaranteed = number;
3805 p->fd_filters_best_effort = logical_id;
3806 i40e_debug(hw, I40E_DEBUG_INIT,
3807 "HW Capability: Flow Director = 1\n");
3808 i40e_debug(hw, I40E_DEBUG_INIT,
3809 "HW Capability: Guaranteed FD filters = %d\n",
3810 p->fd_filters_guaranteed);
3811 break;
3812 case I40E_AQ_CAP_ID_WSR_PROT:
3813 p->wr_csr_prot = (u64)number;
3814 p->wr_csr_prot |= (u64)logical_id << 32;
3815 i40e_debug(hw, I40E_DEBUG_INIT,
3816 "HW Capability: wr_csr_prot = 0x%llX\n\n",
3817 (p->wr_csr_prot & 0xffff));
3818 break;
3819 case I40E_AQ_CAP_ID_NVM_MGMT:
3820 if (number & I40E_NVM_MGMT_SEC_REV_DISABLED)
3821 p->sec_rev_disabled = true;
3822 if (number & I40E_NVM_MGMT_UPDATE_DISABLED)
3823 p->update_disabled = true;
3824 break;
3825#ifdef X722_SUPPORT
3826 case I40E_AQ_CAP_ID_WOL_AND_PROXY:
3827 hw->num_wol_proxy_filters = (u16)number;
3828 hw->wol_proxy_vsi_seid = (u16)logical_id;
3829 p->apm_wol_support = phys_id & I40E_WOL_SUPPORT_MASK;
3830 if (phys_id & I40E_ACPI_PROGRAMMING_METHOD_MASK)
3831 p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_AQC_FPK;
3832 else
3833 p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_HW_FVL;
3834 p->proxy_support = (phys_id & I40E_PROXY_SUPPORT_MASK) ? 1 : 0;
3835 p->proxy_support = p->proxy_support;
3836 i40e_debug(hw, I40E_DEBUG_INIT,
3837 "HW Capability: WOL proxy filters = %d\n",
3838 hw->num_wol_proxy_filters);
3839 break;
3840#endif
3841 default:
3842 break;
3843 }
3844 }
3845
3846 if (p->fcoe)
3847 i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
3848
3849 /* Always disable FCoE if compiled without the I40E_FCOE_ENA flag */
3850 p->fcoe = false;
3851
3852 /* count the enabled ports (aka the "not disabled" ports) */
3853 hw->num_ports = 0;
3854 for (i = 0; i < 4; i++) {
3855 u32 port_cfg_reg = I40E_PRTGEN_CNF + (4 * i);
3856 u64 port_cfg = 0;
3857
3858 /* use AQ read to get the physical register offset instead
3859 * of the port relative offset
3860 */
3861 i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
3862 if (!(port_cfg & I40E_PRTGEN_CNF_PORT_DIS_MASK))
3863 hw->num_ports++;
3864 }
3865
3866 valid_functions = p->valid_functions;
3867 num_functions = 0;
3868 while (valid_functions) {
3869 if (valid_functions & 1)
3870 num_functions++;
3871 valid_functions >>= 1;
3872 }
3873
3874 /* partition id is 1-based, and functions are evenly spread
3875 * across the ports as partitions
3876 */
3877 hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
3878 hw->num_partitions = num_functions / hw->num_ports;
3879
3880 /* additional HW specific goodies that might
3881 * someday be HW version specific
3882 */
3883 p->rx_buf_chain_len = I40E_MAX_CHAINED_RX_BUFFERS;
3884}
3885
3886/**
3887 * i40e_aq_discover_capabilities
3888 * @hw: pointer to the hw struct
3889 * @buff: a virtual buffer to hold the capabilities
3890 * @buff_size: Size of the virtual buffer
3891 * @data_size: Size of the returned data, or buff size needed if AQ err==ENOMEM
3892 * @list_type_opc: capabilities type to discover - pass in the command opcode
3893 * @cmd_details: pointer to command details structure or NULL
3894 *
3895 * Get the device capabilities descriptions from the firmware
3896 **/
3897enum i40e_status_code i40e_aq_discover_capabilities(struct i40e_hw *hw,
3898 void *buff, u16 buff_size, u16 *data_size,
3899 enum i40e_admin_queue_opc list_type_opc,
3900 struct i40e_asq_cmd_details *cmd_details)
3901{
3902 struct i40e_aqc_list_capabilites *cmd;
3903 struct i40e_aq_desc desc;
3904 enum i40e_status_code status = I40E_SUCCESS;
3905
3906 cmd = (struct i40e_aqc_list_capabilites *)&desc.params.raw;
3907
3908 if (list_type_opc != i40e_aqc_opc_list_func_capabilities &&
3909 list_type_opc != i40e_aqc_opc_list_dev_capabilities) {
3910 status = I40E_ERR_PARAM;
3911 goto exit;
3912 }
3913
3914 i40e_fill_default_direct_cmd_desc(&desc, list_type_opc);
3915
3916 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
3917 if (buff_size > I40E_AQ_LARGE_BUF)
3918 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3919
3920 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
3921 *data_size = LE16_TO_CPU(desc.datalen);
3922
3923 if (status)
3924 goto exit;
3925
3926 i40e_parse_discover_capabilities(hw, buff, LE32_TO_CPU(cmd->count),
3927 list_type_opc);
3928
3929exit:
3930 return status;
3931}
3932
3933/**
3934 * i40e_aq_update_nvm
3935 * @hw: pointer to the hw struct
3936 * @module_pointer: module pointer location in words from the NVM beginning
3937 * @offset: byte offset from the module beginning
3938 * @length: length of the section to be written (in bytes from the offset)
3939 * @data: command buffer (size [bytes] = length)
3940 * @last_command: tells if this is the last command in a series
3941 * @cmd_details: pointer to command details structure or NULL
3942 *
3943 * Update the NVM using the admin queue commands
3944 **/
3945enum i40e_status_code i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
3946 u32 offset, u16 length, void *data,
3947 bool last_command,
3948 struct i40e_asq_cmd_details *cmd_details)
3949{
3950 struct i40e_aq_desc desc;
3951 struct i40e_aqc_nvm_update *cmd =
3952 (struct i40e_aqc_nvm_update *)&desc.params.raw;
3953 enum i40e_status_code status;
3954
3955 DEBUGFUNC("i40e_aq_update_nvm");
3956
3957 /* In offset the highest byte must be zeroed. */
3958 if (offset & 0xFF000000) {
3959 status = I40E_ERR_PARAM;
3960 goto i40e_aq_update_nvm_exit;
3961 }
3962
3963 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
3964
3965 /* If this is the last command in a series, set the proper flag. */
3966 if (last_command)
3967 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3968 cmd->module_pointer = module_pointer;
3969 cmd->offset = CPU_TO_LE32(offset);
3970 cmd->length = CPU_TO_LE16(length);
3971
3972 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3973 if (length > I40E_AQ_LARGE_BUF)
3974 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3975
3976 status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
3977
3978i40e_aq_update_nvm_exit:
3979 return status;
3980}
3981
3982/**
3983 * i40e_aq_get_lldp_mib
3984 * @hw: pointer to the hw struct
3985 * @bridge_type: type of bridge requested
3986 * @mib_type: Local, Remote or both Local and Remote MIBs
3987 * @buff: pointer to a user supplied buffer to store the MIB block
3988 * @buff_size: size of the buffer (in bytes)
3989 * @local_len : length of the returned Local LLDP MIB
3990 * @remote_len: length of the returned Remote LLDP MIB
3991 * @cmd_details: pointer to command details structure or NULL
3992 *
3993 * Requests the complete LLDP MIB (entire packet).
3994 **/
3995enum i40e_status_code i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
3996 u8 mib_type, void *buff, u16 buff_size,
3997 u16 *local_len, u16 *remote_len,
3998 struct i40e_asq_cmd_details *cmd_details)
3999{
4000 struct i40e_aq_desc desc;
4001 struct i40e_aqc_lldp_get_mib *cmd =
4002 (struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
4003 struct i40e_aqc_lldp_get_mib *resp =
4004 (struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
4005 enum i40e_status_code status;
4006
4007 if (buff_size == 0 || !buff)
4008 return I40E_ERR_PARAM;
4009
4010 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_get_mib);
4011 /* Indirect Command */
4012 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4013
4014 cmd->type = mib_type & I40E_AQ_LLDP_MIB_TYPE_MASK;
4015 cmd->type |= ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
4016 I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
4017
4018 desc.datalen = CPU_TO_LE16(buff_size);
4019
4020 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4021 if (buff_size > I40E_AQ_LARGE_BUF)
4022 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4023
4024 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4025 if (!status) {
4026 if (local_len != NULL)
4027 *local_len = LE16_TO_CPU(resp->local_len);
4028 if (remote_len != NULL)
4029 *remote_len = LE16_TO_CPU(resp->remote_len);
4030 }
4031
4032 return status;
4033}
4034
4035 /**
4036 * i40e_aq_set_lldp_mib - Set the LLDP MIB
4037 * @hw: pointer to the hw struct
4038 * @mib_type: Local, Remote or both Local and Remote MIBs
4039 * @buff: pointer to a user supplied buffer to store the MIB block
4040 * @buff_size: size of the buffer (in bytes)
4041 * @cmd_details: pointer to command details structure or NULL
4042 *
4043 * Set the LLDP MIB.
4044 **/
4045enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw,
4046 u8 mib_type, void *buff, u16 buff_size,
4047 struct i40e_asq_cmd_details *cmd_details)
4048{
4049 struct i40e_aq_desc desc;
4050 struct i40e_aqc_lldp_set_local_mib *cmd =
4051 (struct i40e_aqc_lldp_set_local_mib *)&desc.params.raw;
4052 enum i40e_status_code status;
4053
4054 if (buff_size == 0 || !buff)
4055 return I40E_ERR_PARAM;
4056
4057 i40e_fill_default_direct_cmd_desc(&desc,
4058 i40e_aqc_opc_lldp_set_local_mib);
4059 /* Indirect Command */
4060 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4061 if (buff_size > I40E_AQ_LARGE_BUF)
4062 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4063 desc.datalen = CPU_TO_LE16(buff_size);
4064
4065 cmd->type = mib_type;
4066 cmd->length = CPU_TO_LE16(buff_size);
4067 cmd->address_high = CPU_TO_LE32(I40E_HI_WORD((u64)buff));
4068 cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)buff));
4069
4070 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4071 return status;
4072}
4073
4074/**
4075 * i40e_aq_cfg_lldp_mib_change_event
4076 * @hw: pointer to the hw struct
4077 * @enable_update: Enable or Disable event posting
4078 * @cmd_details: pointer to command details structure or NULL
4079 *
4080 * Enable or Disable posting of an event on ARQ when LLDP MIB
4081 * associated with the interface changes
4082 **/
4083enum i40e_status_code i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
4084 bool enable_update,
4085 struct i40e_asq_cmd_details *cmd_details)
4086{
4087 struct i40e_aq_desc desc;
4088 struct i40e_aqc_lldp_update_mib *cmd =
4089 (struct i40e_aqc_lldp_update_mib *)&desc.params.raw;
4090 enum i40e_status_code status;
4091
4092 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_mib);
4093
4094 if (!enable_update)
4095 cmd->command |= I40E_AQ_LLDP_MIB_UPDATE_DISABLE;
4096
4097 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4098
4099 return status;
4100}
4101
4102/**
4103 * i40e_aq_add_lldp_tlv
4104 * @hw: pointer to the hw struct
4105 * @bridge_type: type of bridge
4106 * @buff: buffer with TLV to add
4107 * @buff_size: length of the buffer
4108 * @tlv_len: length of the TLV to be added
4109 * @mib_len: length of the LLDP MIB returned in response
4110 * @cmd_details: pointer to command details structure or NULL
4111 *
4112 * Add the specified TLV to LLDP Local MIB for the given bridge type,
4113 * it is responsibility of the caller to make sure that the TLV is not
4114 * already present in the LLDPDU.
4115 * In return firmware will write the complete LLDP MIB with the newly
4116 * added TLV in the response buffer.
4117 **/
4118enum i40e_status_code i40e_aq_add_lldp_tlv(struct i40e_hw *hw, u8 bridge_type,
4119 void *buff, u16 buff_size, u16 tlv_len,
4120 u16 *mib_len,
4121 struct i40e_asq_cmd_details *cmd_details)
4122{
4123 struct i40e_aq_desc desc;
4124 struct i40e_aqc_lldp_add_tlv *cmd =
4125 (struct i40e_aqc_lldp_add_tlv *)&desc.params.raw;
4126 enum i40e_status_code status;
4127
4128 if (buff_size == 0 || !buff || tlv_len == 0)
4129 return I40E_ERR_PARAM;
4130
4131 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_add_tlv);
4132
4133 /* Indirect Command */
4134 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4135 if (buff_size > I40E_AQ_LARGE_BUF)
4136 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4137 desc.datalen = CPU_TO_LE16(buff_size);
4138
4139 cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
4140 I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
4141 cmd->len = CPU_TO_LE16(tlv_len);
4142
4143 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4144 if (!status) {
4145 if (mib_len != NULL)
4146 *mib_len = LE16_TO_CPU(desc.datalen);
4147 }
4148
4149 return status;
4150}
4151
4152/**
4153 * i40e_aq_update_lldp_tlv
4154 * @hw: pointer to the hw struct
4155 * @bridge_type: type of bridge
4156 * @buff: buffer with TLV to update
4157 * @buff_size: size of the buffer holding original and updated TLVs
4158 * @old_len: Length of the Original TLV
4159 * @new_len: Length of the Updated TLV
4160 * @offset: offset of the updated TLV in the buff
4161 * @mib_len: length of the returned LLDP MIB
4162 * @cmd_details: pointer to command details structure or NULL
4163 *
4164 * Update the specified TLV to the LLDP Local MIB for the given bridge type.
4165 * Firmware will place the complete LLDP MIB in response buffer with the
4166 * updated TLV.
4167 **/
4168enum i40e_status_code i40e_aq_update_lldp_tlv(struct i40e_hw *hw,
4169 u8 bridge_type, void *buff, u16 buff_size,
4170 u16 old_len, u16 new_len, u16 offset,
4171 u16 *mib_len,
4172 struct i40e_asq_cmd_details *cmd_details)
4173{
4174 struct i40e_aq_desc desc;
4175 struct i40e_aqc_lldp_update_tlv *cmd =
4176 (struct i40e_aqc_lldp_update_tlv *)&desc.params.raw;
4177 enum i40e_status_code status;
4178
4179 if (buff_size == 0 || !buff || offset == 0 ||
4180 old_len == 0 || new_len == 0)
4181 return I40E_ERR_PARAM;
4182
4183 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_tlv);
4184
4185 /* Indirect Command */
4186 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4187 if (buff_size > I40E_AQ_LARGE_BUF)
4188 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4189 desc.datalen = CPU_TO_LE16(buff_size);
4190
4191 cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
4192 I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
4193 cmd->old_len = CPU_TO_LE16(old_len);
4194 cmd->new_offset = CPU_TO_LE16(offset);
4195 cmd->new_len = CPU_TO_LE16(new_len);
4196
4197 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4198 if (!status) {
4199 if (mib_len != NULL)
4200 *mib_len = LE16_TO_CPU(desc.datalen);
4201 }
4202
4203 return status;
4204}
4205
4206/**
4207 * i40e_aq_delete_lldp_tlv
4208 * @hw: pointer to the hw struct
4209 * @bridge_type: type of bridge
4210 * @buff: pointer to a user supplied buffer that has the TLV
4211 * @buff_size: length of the buffer
4212 * @tlv_len: length of the TLV to be deleted
4213 * @mib_len: length of the returned LLDP MIB
4214 * @cmd_details: pointer to command details structure or NULL
4215 *
4216 * Delete the specified TLV from LLDP Local MIB for the given bridge type.
4217 * The firmware places the entire LLDP MIB in the response buffer.
4218 **/
4219enum i40e_status_code i40e_aq_delete_lldp_tlv(struct i40e_hw *hw,
4220 u8 bridge_type, void *buff, u16 buff_size,
4221 u16 tlv_len, u16 *mib_len,
4222 struct i40e_asq_cmd_details *cmd_details)
4223{
4224 struct i40e_aq_desc desc;
4225 struct i40e_aqc_lldp_add_tlv *cmd =
4226 (struct i40e_aqc_lldp_add_tlv *)&desc.params.raw;
4227 enum i40e_status_code status;
4228
4229 if (buff_size == 0 || !buff)
4230 return I40E_ERR_PARAM;
4231
4232 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_delete_tlv);
4233
4234 /* Indirect Command */
4235 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4236 if (buff_size > I40E_AQ_LARGE_BUF)
4237 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4238 desc.datalen = CPU_TO_LE16(buff_size);
4239 cmd->len = CPU_TO_LE16(tlv_len);
4240 cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
4241 I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
4242
4243 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4244 if (!status) {
4245 if (mib_len != NULL)
4246 *mib_len = LE16_TO_CPU(desc.datalen);
4247 }
4248
4249 return status;
4250}
4251
4252/**
4253 * i40e_aq_stop_lldp
4254 * @hw: pointer to the hw struct
4255 * @shutdown_agent: True if LLDP Agent needs to be Shutdown
4256 * @cmd_details: pointer to command details structure or NULL
4257 *
4258 * Stop or Shutdown the embedded LLDP Agent
4259 **/
4260enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
4261 struct i40e_asq_cmd_details *cmd_details)
4262{
4263 struct i40e_aq_desc desc;
4264 struct i40e_aqc_lldp_stop *cmd =
4265 (struct i40e_aqc_lldp_stop *)&desc.params.raw;
4266 enum i40e_status_code status;
4267
4268 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
4269
4270 if (shutdown_agent)
4271 cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
4272
4273 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4274
4275 return status;
4276}
4277
4278/**
4279 * i40e_aq_start_lldp
4280 * @hw: pointer to the hw struct
4281 * @cmd_details: pointer to command details structure or NULL
4282 *
4283 * Start the embedded LLDP Agent on all ports.
4284 **/
4285enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw,
4286 struct i40e_asq_cmd_details *cmd_details)
4287{
4288 struct i40e_aq_desc desc;
4289 struct i40e_aqc_lldp_start *cmd =
4290 (struct i40e_aqc_lldp_start *)&desc.params.raw;
4291 enum i40e_status_code status;
4292
4293 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
4294
4295 cmd->command = I40E_AQ_LLDP_AGENT_START;
4296
4297 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4298
4299 return status;
4300}
4301
4302/**
4303 * i40e_aq_get_cee_dcb_config
4304 * @hw: pointer to the hw struct
4305 * @buff: response buffer that stores CEE operational configuration
4306 * @buff_size: size of the buffer passed
4307 * @cmd_details: pointer to command details structure or NULL
4308 *
4309 * Get CEE DCBX mode operational configuration from firmware
4310 **/
4311enum i40e_status_code i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
4312 void *buff, u16 buff_size,
4313 struct i40e_asq_cmd_details *cmd_details)
4314{
4315 struct i40e_aq_desc desc;
4316 enum i40e_status_code status;
4317
4318 if (buff_size == 0 || !buff)
4319 return I40E_ERR_PARAM;
4320
4321 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_cee_dcb_cfg);
4322
4323 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4324 status = i40e_asq_send_command(hw, &desc, (void *)buff, buff_size,
4325 cmd_details);
4326
4327 return status;
4328}
4329
4330/**
4331 * i40e_aq_start_stop_dcbx - Start/Stop DCBx service in FW
4332 * @hw: pointer to the hw struct
4333 * @start_agent: True if DCBx Agent needs to be Started
4334 * False if DCBx Agent needs to be Stopped
4335 * @cmd_details: pointer to command details structure or NULL
4336 *
4337 * Start/Stop the embedded dcbx Agent
4338 **/
4339enum i40e_status_code i40e_aq_start_stop_dcbx(struct i40e_hw *hw,
4340 bool start_agent,
4341 struct i40e_asq_cmd_details *cmd_details)
4342{
4343 struct i40e_aq_desc desc;
4344 struct i40e_aqc_lldp_stop_start_specific_agent *cmd =
4345 (struct i40e_aqc_lldp_stop_start_specific_agent *)
4346 &desc.params.raw;
4347 enum i40e_status_code status;
4348
4349 i40e_fill_default_direct_cmd_desc(&desc,
4350 i40e_aqc_opc_lldp_stop_start_spec_agent);
4351
4352 if (start_agent)
4353 cmd->command = I40E_AQC_START_SPECIFIC_AGENT_MASK;
4354
4355 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4356
4357 return status;
4358}
4359
4360/**
4361 * i40e_aq_add_udp_tunnel
4362 * @hw: pointer to the hw struct
4363 * @udp_port: the UDP port to add
4364 * @header_len: length of the tunneling header length in DWords
4365 * @protocol_index: protocol index type
4366 * @filter_index: pointer to filter index
4367 * @cmd_details: pointer to command details structure or NULL
4368 **/
4369enum i40e_status_code i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
4370 u16 udp_port, u8 protocol_index,
4371 u8 *filter_index,
4372 struct i40e_asq_cmd_details *cmd_details)
4373{
4374 struct i40e_aq_desc desc;
4375 struct i40e_aqc_add_udp_tunnel *cmd =
4376 (struct i40e_aqc_add_udp_tunnel *)&desc.params.raw;
4377 struct i40e_aqc_del_udp_tunnel_completion *resp =
4378 (struct i40e_aqc_del_udp_tunnel_completion *)&desc.params.raw;
4379 enum i40e_status_code status;
4380
4381 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_udp_tunnel);
4382
4383 cmd->udp_port = CPU_TO_LE16(udp_port);
4384 cmd->protocol_type = protocol_index;
4385
4386 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4387
4388 if (!status && filter_index)
4389 *filter_index = resp->index;
4390
4391 return status;
4392}
4393
4394/**
4395 * i40e_aq_del_udp_tunnel
4396 * @hw: pointer to the hw struct
4397 * @index: filter index
4398 * @cmd_details: pointer to command details structure or NULL
4399 **/
4400enum i40e_status_code i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
4401 struct i40e_asq_cmd_details *cmd_details)
4402{
4403 struct i40e_aq_desc desc;
4404 struct i40e_aqc_remove_udp_tunnel *cmd =
4405 (struct i40e_aqc_remove_udp_tunnel *)&desc.params.raw;
4406 enum i40e_status_code status;
4407
4408 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_del_udp_tunnel);
4409
4410 cmd->index = index;
4411
4412 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4413
4414 return status;
4415}
4416
4417/**
4418 * i40e_aq_get_switch_resource_alloc (0x0204)
4419 * @hw: pointer to the hw struct
4420 * @num_entries: pointer to u8 to store the number of resource entries returned
4421 * @buf: pointer to a user supplied buffer. This buffer must be large enough
4422 * to store the resource information for all resource types. Each
4423 * resource type is a i40e_aqc_switch_resource_alloc_data structure.
4424 * @count: size, in bytes, of the buffer provided
4425 * @cmd_details: pointer to command details structure or NULL
4426 *
4427 * Query the resources allocated to a function.
4428 **/
4429enum i40e_status_code i40e_aq_get_switch_resource_alloc(struct i40e_hw *hw,
4430 u8 *num_entries,
4431 struct i40e_aqc_switch_resource_alloc_element_resp *buf,
4432 u16 count,
4433 struct i40e_asq_cmd_details *cmd_details)
4434{
4435 struct i40e_aq_desc desc;
4436 struct i40e_aqc_get_switch_resource_alloc *cmd_resp =
4437 (struct i40e_aqc_get_switch_resource_alloc *)&desc.params.raw;
4438 enum i40e_status_code status;
4439 u16 length = count * sizeof(*buf);
4440
4441 i40e_fill_default_direct_cmd_desc(&desc,
4442 i40e_aqc_opc_get_switch_resource_alloc);
4443
4444 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4445 if (length > I40E_AQ_LARGE_BUF)
4446 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4447
4448 status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
4449
4450 if (!status && num_entries)
4451 *num_entries = cmd_resp->num_entries;
4452
4453 return status;
4454}
4455
4456/**
4457 * i40e_aq_delete_element - Delete switch element
4458 * @hw: pointer to the hw struct
4459 * @seid: the SEID to delete from the switch
4460 * @cmd_details: pointer to command details structure or NULL
4461 *
4462 * This deletes a switch element from the switch.
4463 **/
4464enum i40e_status_code i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
4465 struct i40e_asq_cmd_details *cmd_details)
4466{
4467 struct i40e_aq_desc desc;
4468 struct i40e_aqc_switch_seid *cmd =
4469 (struct i40e_aqc_switch_seid *)&desc.params.raw;
4470 enum i40e_status_code status;
4471
4472 if (seid == 0)
4473 return I40E_ERR_PARAM;
4474
4475 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_delete_element);
4476
4477 cmd->seid = CPU_TO_LE16(seid);
4478
4479 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4480
4481 return status;
4482}
4483
4484/**
4485 * i40e_aq_add_pvirt - Instantiate a Port Virtualizer on a port
4486 * @hw: pointer to the hw struct
4487 * @flags: component flags
4488 * @mac_seid: uplink seid (MAC SEID)
4489 * @vsi_seid: connected vsi seid
4490 * @ret_seid: seid of create pv component
4491 *
4492 * This instantiates an i40e port virtualizer with specified flags.
4493 * Depending on specified flags the port virtualizer can act as a
4494 * 802.1Qbr port virtualizer or a 802.1Qbg S-component.
4495 */
4496enum i40e_status_code i40e_aq_add_pvirt(struct i40e_hw *hw, u16 flags,
4497 u16 mac_seid, u16 vsi_seid,
4498 u16 *ret_seid)
4499{
4500 struct i40e_aq_desc desc;
4501 struct i40e_aqc_add_update_pv *cmd =
4502 (struct i40e_aqc_add_update_pv *)&desc.params.raw;
4503 struct i40e_aqc_add_update_pv_completion *resp =
4504 (struct i40e_aqc_add_update_pv_completion *)&desc.params.raw;
4505 enum i40e_status_code status;
4506
4507 if (vsi_seid == 0)
4508 return I40E_ERR_PARAM;
4509
4510 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_pv);
4511 cmd->command_flags = CPU_TO_LE16(flags);
4512 cmd->uplink_seid = CPU_TO_LE16(mac_seid);
4513 cmd->connected_seid = CPU_TO_LE16(vsi_seid);
4514
4515 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
4516 if (!status && ret_seid)
4517 *ret_seid = LE16_TO_CPU(resp->pv_seid);
4518
4519 return status;
4520}
4521
4522/**
4523 * i40e_aq_add_tag - Add an S/E-tag
4524 * @hw: pointer to the hw struct
4525 * @direct_to_queue: should s-tag direct flow to a specific queue
4526 * @vsi_seid: VSI SEID to use this tag
4527 * @tag: value of the tag
4528 * @queue_num: queue number, only valid is direct_to_queue is true
4529 * @tags_used: return value, number of tags in use by this PF
4530 * @tags_free: return value, number of unallocated tags
4531 * @cmd_details: pointer to command details structure or NULL
4532 *
4533 * This associates an S- or E-tag to a VSI in the switch complex. It returns
4534 * the number of tags allocated by the PF, and the number of unallocated
4535 * tags available.
4536 **/
4537enum i40e_status_code i40e_aq_add_tag(struct i40e_hw *hw, bool direct_to_queue,
4538 u16 vsi_seid, u16 tag, u16 queue_num,
4539 u16 *tags_used, u16 *tags_free,
4540 struct i40e_asq_cmd_details *cmd_details)
4541{
4542 struct i40e_aq_desc desc;
4543 struct i40e_aqc_add_tag *cmd =
4544 (struct i40e_aqc_add_tag *)&desc.params.raw;
4545 struct i40e_aqc_add_remove_tag_completion *resp =
4546 (struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
4547 enum i40e_status_code status;
4548
4549 if (vsi_seid == 0)
4550 return I40E_ERR_PARAM;
4551
4552 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_tag);
4553
4554 cmd->seid = CPU_TO_LE16(vsi_seid);
4555 cmd->tag = CPU_TO_LE16(tag);
4556 if (direct_to_queue) {
4557 cmd->flags = CPU_TO_LE16(I40E_AQC_ADD_TAG_FLAG_TO_QUEUE);
4558 cmd->queue_number = CPU_TO_LE16(queue_num);
4559 }
4560
4561 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4562
4563 if (!status) {
4564 if (tags_used != NULL)
4565 *tags_used = LE16_TO_CPU(resp->tags_used);
4566 if (tags_free != NULL)
4567 *tags_free = LE16_TO_CPU(resp->tags_free);
4568 }
4569
4570 return status;
4571}
4572
4573/**
4574 * i40e_aq_remove_tag - Remove an S- or E-tag
4575 * @hw: pointer to the hw struct
4576 * @vsi_seid: VSI SEID this tag is associated with
4577 * @tag: value of the S-tag to delete
4578 * @tags_used: return value, number of tags in use by this PF
4579 * @tags_free: return value, number of unallocated tags
4580 * @cmd_details: pointer to command details structure or NULL
4581 *
4582 * This deletes an S- or E-tag from a VSI in the switch complex. It returns
4583 * the number of tags allocated by the PF, and the number of unallocated
4584 * tags available.
4585 **/
4586enum i40e_status_code i40e_aq_remove_tag(struct i40e_hw *hw, u16 vsi_seid,
4587 u16 tag, u16 *tags_used, u16 *tags_free,
4588 struct i40e_asq_cmd_details *cmd_details)
4589{
4590 struct i40e_aq_desc desc;
4591 struct i40e_aqc_remove_tag *cmd =
4592 (struct i40e_aqc_remove_tag *)&desc.params.raw;
4593 struct i40e_aqc_add_remove_tag_completion *resp =
4594 (struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
4595 enum i40e_status_code status;
4596
4597 if (vsi_seid == 0)
4598 return I40E_ERR_PARAM;
4599
4600 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_tag);
4601
4602 cmd->seid = CPU_TO_LE16(vsi_seid);
4603 cmd->tag = CPU_TO_LE16(tag);
4604
4605 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4606
4607 if (!status) {
4608 if (tags_used != NULL)
4609 *tags_used = LE16_TO_CPU(resp->tags_used);
4610 if (tags_free != NULL)
4611 *tags_free = LE16_TO_CPU(resp->tags_free);
4612 }
4613
4614 return status;
4615}
4616
4617/**
4618 * i40e_aq_add_mcast_etag - Add a multicast E-tag
4619 * @hw: pointer to the hw struct
4620 * @pv_seid: Port Virtualizer of this SEID to associate E-tag with
4621 * @etag: value of E-tag to add
4622 * @num_tags_in_buf: number of unicast E-tags in indirect buffer
4623 * @buf: address of indirect buffer
4624 * @tags_used: return value, number of E-tags in use by this port
4625 * @tags_free: return value, number of unallocated M-tags
4626 * @cmd_details: pointer to command details structure or NULL
4627 *
4628 * This associates a multicast E-tag to a port virtualizer. It will return
4629 * the number of tags allocated by the PF, and the number of unallocated
4630 * tags available.
4631 *
4632 * The indirect buffer pointed to by buf is a list of 2-byte E-tags,
4633 * num_tags_in_buf long.
4634 **/
4635enum i40e_status_code i40e_aq_add_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
4636 u16 etag, u8 num_tags_in_buf, void *buf,
4637 u16 *tags_used, u16 *tags_free,
4638 struct i40e_asq_cmd_details *cmd_details)
4639{
4640 struct i40e_aq_desc desc;
4641 struct i40e_aqc_add_remove_mcast_etag *cmd =
4642 (struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
4643 struct i40e_aqc_add_remove_mcast_etag_completion *resp =
4644 (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
4645 enum i40e_status_code status;
4646 u16 length = sizeof(u16) * num_tags_in_buf;
4647
4648 if ((pv_seid == 0) || (buf == NULL) || (num_tags_in_buf == 0))
4649 return I40E_ERR_PARAM;
4650
4651 i40e_fill_default_direct_cmd_desc(&desc,
4652 i40e_aqc_opc_add_multicast_etag);
4653
4654 cmd->pv_seid = CPU_TO_LE16(pv_seid);
4655 cmd->etag = CPU_TO_LE16(etag);
4656 cmd->num_unicast_etags = num_tags_in_buf;
4657
4658 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4659 if (length > I40E_AQ_LARGE_BUF)
4660 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4661
4662 status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
4663
4664 if (!status) {
4665 if (tags_used != NULL)
4666 *tags_used = LE16_TO_CPU(resp->mcast_etags_used);
4667 if (tags_free != NULL)
4668 *tags_free = LE16_TO_CPU(resp->mcast_etags_free);
4669 }
4670
4671 return status;
4672}
4673
4674/**
4675 * i40e_aq_remove_mcast_etag - Remove a multicast E-tag
4676 * @hw: pointer to the hw struct
4677 * @pv_seid: Port Virtualizer SEID this M-tag is associated with
4678 * @etag: value of the E-tag to remove
4679 * @tags_used: return value, number of tags in use by this port
4680 * @tags_free: return value, number of unallocated tags
4681 * @cmd_details: pointer to command details structure or NULL
4682 *
4683 * This deletes an E-tag from the port virtualizer. It will return
4684 * the number of tags allocated by the port, and the number of unallocated
4685 * tags available.
4686 **/
4687enum i40e_status_code i40e_aq_remove_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
4688 u16 etag, u16 *tags_used, u16 *tags_free,
4689 struct i40e_asq_cmd_details *cmd_details)
4690{
4691 struct i40e_aq_desc desc;
4692 struct i40e_aqc_add_remove_mcast_etag *cmd =
4693 (struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
4694 struct i40e_aqc_add_remove_mcast_etag_completion *resp =
4695 (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
4696 enum i40e_status_code status;
4697
4698
4699 if (pv_seid == 0)
4700 return I40E_ERR_PARAM;
4701
4702 i40e_fill_default_direct_cmd_desc(&desc,
4703 i40e_aqc_opc_remove_multicast_etag);
4704
4705 cmd->pv_seid = CPU_TO_LE16(pv_seid);
4706 cmd->etag = CPU_TO_LE16(etag);
4707
4708 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4709
4710 if (!status) {
4711 if (tags_used != NULL)
4712 *tags_used = LE16_TO_CPU(resp->mcast_etags_used);
4713 if (tags_free != NULL)
4714 *tags_free = LE16_TO_CPU(resp->mcast_etags_free);
4715 }
4716
4717 return status;
4718}
4719
4720/**
4721 * i40e_aq_update_tag - Update an S/E-tag
4722 * @hw: pointer to the hw struct
4723 * @vsi_seid: VSI SEID using this S-tag
4724 * @old_tag: old tag value
4725 * @new_tag: new tag value
4726 * @tags_used: return value, number of tags in use by this PF
4727 * @tags_free: return value, number of unallocated tags
4728 * @cmd_details: pointer to command details structure or NULL
4729 *
4730 * This updates the value of the tag currently attached to this VSI
4731 * in the switch complex. It will return the number of tags allocated
4732 * by the PF, and the number of unallocated tags available.
4733 **/
4734enum i40e_status_code i40e_aq_update_tag(struct i40e_hw *hw, u16 vsi_seid,
4735 u16 old_tag, u16 new_tag, u16 *tags_used,
4736 u16 *tags_free,
4737 struct i40e_asq_cmd_details *cmd_details)
4738{
4739 struct i40e_aq_desc desc;
4740 struct i40e_aqc_update_tag *cmd =
4741 (struct i40e_aqc_update_tag *)&desc.params.raw;
4742 struct i40e_aqc_update_tag_completion *resp =
4743 (struct i40e_aqc_update_tag_completion *)&desc.params.raw;
4744 enum i40e_status_code status;
4745
4746 if (vsi_seid == 0)
4747 return I40E_ERR_PARAM;
4748
4749 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_update_tag);
4750
4751 cmd->seid = CPU_TO_LE16(vsi_seid);
4752 cmd->old_tag = CPU_TO_LE16(old_tag);
4753 cmd->new_tag = CPU_TO_LE16(new_tag);
4754
4755 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4756
4757 if (!status) {
4758 if (tags_used != NULL)
4759 *tags_used = LE16_TO_CPU(resp->tags_used);
4760 if (tags_free != NULL)
4761 *tags_free = LE16_TO_CPU(resp->tags_free);
4762 }
4763
4764 return status;
4765}
4766
4767/**
4768 * i40e_aq_dcb_ignore_pfc - Ignore PFC for given TCs
4769 * @hw: pointer to the hw struct
4770 * @tcmap: TC map for request/release any ignore PFC condition
4771 * @request: request or release ignore PFC condition
4772 * @tcmap_ret: return TCs for which PFC is currently ignored
4773 * @cmd_details: pointer to command details structure or NULL
4774 *
4775 * This sends out request/release to ignore PFC condition for a TC.
4776 * It will return the TCs for which PFC is currently ignored.
4777 **/
4778enum i40e_status_code i40e_aq_dcb_ignore_pfc(struct i40e_hw *hw, u8 tcmap,
4779 bool request, u8 *tcmap_ret,
4780 struct i40e_asq_cmd_details *cmd_details)
4781{
4782 struct i40e_aq_desc desc;
4783 struct i40e_aqc_pfc_ignore *cmd_resp =
4784 (struct i40e_aqc_pfc_ignore *)&desc.params.raw;
4785 enum i40e_status_code status;
4786
4787 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_ignore_pfc);
4788
4789 if (request)
4790 cmd_resp->command_flags = I40E_AQC_PFC_IGNORE_SET;
4791
4792 cmd_resp->tc_bitmap = tcmap;
4793
4794 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4795
4796 if (!status) {
4797 if (tcmap_ret != NULL)
4798 *tcmap_ret = cmd_resp->tc_bitmap;
4799 }
4800
4801 return status;
4802}
4803
4804/**
4805 * i40e_aq_dcb_updated - DCB Updated Command
4806 * @hw: pointer to the hw struct
4807 * @cmd_details: pointer to command details structure or NULL
4808 *
4809 * When LLDP is handled in PF this command is used by the PF
4810 * to notify EMP that a DCB setting is modified.
4811 * When LLDP is handled in EMP this command is used by the PF
4812 * to notify EMP whenever one of the following parameters get
4813 * modified:
4814 * - PFCLinkDelayAllowance in PRTDCB_GENC.PFCLDA
4815 * - PCIRTT in PRTDCB_GENC.PCIRTT
4816 * - Maximum Frame Size for non-FCoE TCs set by PRTDCB_TDPUC.MAX_TXFRAME.
4817 * EMP will return when the shared RPB settings have been
4818 * recomputed and modified. The retval field in the descriptor
4819 * will be set to 0 when RPB is modified.
4820 **/
4821enum i40e_status_code i40e_aq_dcb_updated(struct i40e_hw *hw,
4822 struct i40e_asq_cmd_details *cmd_details)
4823{
4824 struct i40e_aq_desc desc;
4825 enum i40e_status_code status;
4826
4827 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_updated);
4828
4829 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4830
4831 return status;
4832}
4833
4834/**
4835 * i40e_aq_add_statistics - Add a statistics block to a VLAN in a switch.
4836 * @hw: pointer to the hw struct
4837 * @seid: defines the SEID of the switch for which the stats are requested
4838 * @vlan_id: the VLAN ID for which the statistics are requested
4839 * @stat_index: index of the statistics counters block assigned to this VLAN
4840 * @cmd_details: pointer to command details structure or NULL
4841 *
4842 * XL710 supports 128 smonVlanStats counters.This command is used to
4843 * allocate a set of smonVlanStats counters to a specific VLAN in a specific
4844 * switch.
4845 **/
4846enum i40e_status_code i40e_aq_add_statistics(struct i40e_hw *hw, u16 seid,
4847 u16 vlan_id, u16 *stat_index,
4848 struct i40e_asq_cmd_details *cmd_details)
4849{
4850 struct i40e_aq_desc desc;
4851 struct i40e_aqc_add_remove_statistics *cmd_resp =
4852 (struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
4853 enum i40e_status_code status;
4854
4855 if ((seid == 0) || (stat_index == NULL))
4856 return I40E_ERR_PARAM;
4857
4858 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_statistics);
4859
4860 cmd_resp->seid = CPU_TO_LE16(seid);
4861 cmd_resp->vlan = CPU_TO_LE16(vlan_id);
4862
4863 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4864
4865 if (!status && stat_index)
4866 *stat_index = LE16_TO_CPU(cmd_resp->stat_index);
4867
4868 return status;
4869}
4870
4871/**
4872 * i40e_aq_remove_statistics - Remove a statistics block to a VLAN in a switch.
4873 * @hw: pointer to the hw struct
4874 * @seid: defines the SEID of the switch for which the stats are requested
4875 * @vlan_id: the VLAN ID for which the statistics are requested
4876 * @stat_index: index of the statistics counters block assigned to this VLAN
4877 * @cmd_details: pointer to command details structure or NULL
4878 *
4879 * XL710 supports 128 smonVlanStats counters.This command is used to
4880 * deallocate a set of smonVlanStats counters to a specific VLAN in a specific
4881 * switch.
4882 **/
4883enum i40e_status_code i40e_aq_remove_statistics(struct i40e_hw *hw, u16 seid,
4884 u16 vlan_id, u16 stat_index,
4885 struct i40e_asq_cmd_details *cmd_details)
4886{
4887 struct i40e_aq_desc desc;
4888 struct i40e_aqc_add_remove_statistics *cmd =
4889 (struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
4890 enum i40e_status_code status;
4891
4892 if (seid == 0)
4893 return I40E_ERR_PARAM;
4894
4895 i40e_fill_default_direct_cmd_desc(&desc,
4896 i40e_aqc_opc_remove_statistics);
4897
4898 cmd->seid = CPU_TO_LE16(seid);
4899 cmd->vlan = CPU_TO_LE16(vlan_id);
4900 cmd->stat_index = CPU_TO_LE16(stat_index);
4901
4902 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4903
4904 return status;
4905}
4906
4907/**
4908 * i40e_aq_set_port_parameters - set physical port parameters.
4909 * @hw: pointer to the hw struct
4910 * @bad_frame_vsi: defines the VSI to which bad frames are forwarded
4911 * @save_bad_pac: if set packets with errors are forwarded to the bad frames VSI
4912 * @pad_short_pac: if set transmit packets smaller than 60 bytes are padded
4913 * @double_vlan: if set double VLAN is enabled
4914 * @cmd_details: pointer to command details structure or NULL
4915 **/
4916enum i40e_status_code i40e_aq_set_port_parameters(struct i40e_hw *hw,
4917 u16 bad_frame_vsi, bool save_bad_pac,
4918 bool pad_short_pac, bool double_vlan,
4919 struct i40e_asq_cmd_details *cmd_details)
4920{
4921 struct i40e_aqc_set_port_parameters *cmd;
4922 enum i40e_status_code status;
4923 struct i40e_aq_desc desc;
4924 u16 command_flags = 0;
4925
4926 cmd = (struct i40e_aqc_set_port_parameters *)&desc.params.raw;
4927
4928 i40e_fill_default_direct_cmd_desc(&desc,
4929 i40e_aqc_opc_set_port_parameters);
4930
4931 cmd->bad_frame_vsi = CPU_TO_LE16(bad_frame_vsi);
4932 if (save_bad_pac)
4933 command_flags |= I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS;
4934 if (pad_short_pac)
4935 command_flags |= I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS;
4936 if (double_vlan)
4937 command_flags |= I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA;
4938 cmd->command_flags = CPU_TO_LE16(command_flags);
4939
4940 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4941
4942 return status;
4943}
4944
4945/**
4946 * i40e_aq_tx_sched_cmd - generic Tx scheduler AQ command handler
4947 * @hw: pointer to the hw struct
4948 * @seid: seid for the physical port/switching component/vsi
4949 * @buff: Indirect buffer to hold data parameters and response
4950 * @buff_size: Indirect buffer size
4951 * @opcode: Tx scheduler AQ command opcode
4952 * @cmd_details: pointer to command details structure or NULL
4953 *
4954 * Generic command handler for Tx scheduler AQ commands
4955 **/
4956static enum i40e_status_code i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
4957 void *buff, u16 buff_size,
4958 enum i40e_admin_queue_opc opcode,
4959 struct i40e_asq_cmd_details *cmd_details)
4960{
4961 struct i40e_aq_desc desc;
4962 struct i40e_aqc_tx_sched_ind *cmd =
4963 (struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
4964 enum i40e_status_code status;
4965 bool cmd_param_flag = false;
4966
4967 switch (opcode) {
4968 case i40e_aqc_opc_configure_vsi_ets_sla_bw_limit:
4969 case i40e_aqc_opc_configure_vsi_tc_bw:
4970 case i40e_aqc_opc_enable_switching_comp_ets:
4971 case i40e_aqc_opc_modify_switching_comp_ets:
4972 case i40e_aqc_opc_disable_switching_comp_ets:
4973 case i40e_aqc_opc_configure_switching_comp_ets_bw_limit:
4974 case i40e_aqc_opc_configure_switching_comp_bw_config:
4975 cmd_param_flag = true;
4976 break;
4977 case i40e_aqc_opc_query_vsi_bw_config:
4978 case i40e_aqc_opc_query_vsi_ets_sla_config:
4979 case i40e_aqc_opc_query_switching_comp_ets_config:
4980 case i40e_aqc_opc_query_port_ets_config:
4981 case i40e_aqc_opc_query_switching_comp_bw_config:
4982 cmd_param_flag = false;
4983 break;
4984 default:
4985 return I40E_ERR_PARAM;
4986 }
4987
4988 i40e_fill_default_direct_cmd_desc(&desc, opcode);
4989
4990 /* Indirect command */
4991 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4992 if (cmd_param_flag)
4993 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
4994 if (buff_size > I40E_AQ_LARGE_BUF)
4995 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4996
4997 desc.datalen = CPU_TO_LE16(buff_size);
4998
4999 cmd->vsi_seid = CPU_TO_LE16(seid);
5000
5001 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5002
5003 return status;
5004}
5005
5006/**
5007 * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
5008 * @hw: pointer to the hw struct
5009 * @seid: VSI seid
5010 * @credit: BW limit credits (0 = disabled)
5011 * @max_credit: Max BW limit credits
5012 * @cmd_details: pointer to command details structure or NULL
5013 **/
5014enum i40e_status_code i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
5015 u16 seid, u16 credit, u8 max_credit,
5016 struct i40e_asq_cmd_details *cmd_details)
5017{
5018 struct i40e_aq_desc desc;
5019 struct i40e_aqc_configure_vsi_bw_limit *cmd =
5020 (struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
5021 enum i40e_status_code status;
5022
5023 i40e_fill_default_direct_cmd_desc(&desc,
5024 i40e_aqc_opc_configure_vsi_bw_limit);
5025
5026 cmd->vsi_seid = CPU_TO_LE16(seid);
5027 cmd->credit = CPU_TO_LE16(credit);
5028 cmd->max_credit = max_credit;
5029
5030 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5031
5032 return status;
5033}
5034
5035/**
5036 * i40e_aq_config_switch_comp_bw_limit - Configure Switching component BW Limit
5037 * @hw: pointer to the hw struct
5038 * @seid: switching component seid
5039 * @credit: BW limit credits (0 = disabled)
5040 * @max_bw: Max BW limit credits
5041 * @cmd_details: pointer to command details structure or NULL
5042 **/
5043enum i40e_status_code i40e_aq_config_switch_comp_bw_limit(struct i40e_hw *hw,
5044 u16 seid, u16 credit, u8 max_bw,
5045 struct i40e_asq_cmd_details *cmd_details)
5046{
5047 struct i40e_aq_desc desc;
5048 struct i40e_aqc_configure_switching_comp_bw_limit *cmd =
5049 (struct i40e_aqc_configure_switching_comp_bw_limit *)&desc.params.raw;
5050 enum i40e_status_code status;
5051
5052 i40e_fill_default_direct_cmd_desc(&desc,
5053 i40e_aqc_opc_configure_switching_comp_bw_limit);
5054
5055 cmd->seid = CPU_TO_LE16(seid);
5056 cmd->credit = CPU_TO_LE16(credit);
5057 cmd->max_bw = max_bw;
5058
5059 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5060
5061 return status;
5062}
5063
5064/**
5065 * i40e_aq_config_vsi_ets_sla_bw_limit - Config VSI BW Limit per TC
5066 * @hw: pointer to the hw struct
5067 * @seid: VSI seid
5068 * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
5069 * @cmd_details: pointer to command details structure or NULL
5070 **/
5071enum i40e_status_code i40e_aq_config_vsi_ets_sla_bw_limit(struct i40e_hw *hw,
5072 u16 seid,
5073 struct i40e_aqc_configure_vsi_ets_sla_bw_data *bw_data,
5074 struct i40e_asq_cmd_details *cmd_details)
5075{
5076 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5077 i40e_aqc_opc_configure_vsi_ets_sla_bw_limit,
5078 cmd_details);
5079}
5080
5081/**
5082 * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
5083 * @hw: pointer to the hw struct
5084 * @seid: VSI seid
5085 * @bw_data: Buffer holding enabled TCs, relative TC BW limit/credits
5086 * @cmd_details: pointer to command details structure or NULL
5087 **/
5088enum i40e_status_code i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
5089 u16 seid,
5090 struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
5091 struct i40e_asq_cmd_details *cmd_details)
5092{
5093 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5094 i40e_aqc_opc_configure_vsi_tc_bw,
5095 cmd_details);
5096}
5097
5098/**
5099 * i40e_aq_config_switch_comp_ets - Enable/Disable/Modify ETS on the port
5100 * @hw: pointer to the hw struct
5101 * @seid: seid of the switching component connected to Physical Port
5102 * @ets_data: Buffer holding ETS parameters
5103 * @cmd_details: pointer to command details structure or NULL
5104 **/
5105enum i40e_status_code i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
5106 u16 seid,
5107 struct i40e_aqc_configure_switching_comp_ets_data *ets_data,
5108 enum i40e_admin_queue_opc opcode,
5109 struct i40e_asq_cmd_details *cmd_details)
5110{
5111 return i40e_aq_tx_sched_cmd(hw, seid, (void *)ets_data,
5112 sizeof(*ets_data), opcode, cmd_details);
5113}
5114
5115/**
5116 * i40e_aq_config_switch_comp_bw_config - Config Switch comp BW Alloc per TC
5117 * @hw: pointer to the hw struct
5118 * @seid: seid of the switching component
5119 * @bw_data: Buffer holding enabled TCs, relative/absolute TC BW limit/credits
5120 * @cmd_details: pointer to command details structure or NULL
5121 **/
5122enum i40e_status_code i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
5123 u16 seid,
5124 struct i40e_aqc_configure_switching_comp_bw_config_data *bw_data,
5125 struct i40e_asq_cmd_details *cmd_details)
5126{
5127 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5128 i40e_aqc_opc_configure_switching_comp_bw_config,
5129 cmd_details);
5130}
5131
5132/**
5133 * i40e_aq_config_switch_comp_ets_bw_limit - Config Switch comp BW Limit per TC
5134 * @hw: pointer to the hw struct
5135 * @seid: seid of the switching component
5136 * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
5137 * @cmd_details: pointer to command details structure or NULL
5138 **/
5139enum i40e_status_code i40e_aq_config_switch_comp_ets_bw_limit(
5140 struct i40e_hw *hw, u16 seid,
5141 struct i40e_aqc_configure_switching_comp_ets_bw_limit_data *bw_data,
5142 struct i40e_asq_cmd_details *cmd_details)
5143{
5144 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5145 i40e_aqc_opc_configure_switching_comp_ets_bw_limit,
5146 cmd_details);
5147}
5148
5149/**
5150 * i40e_aq_query_vsi_bw_config - Query VSI BW configuration
5151 * @hw: pointer to the hw struct
5152 * @seid: seid of the VSI
5153 * @bw_data: Buffer to hold VSI BW configuration
5154 * @cmd_details: pointer to command details structure or NULL
5155 **/
5156enum i40e_status_code i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
5157 u16 seid,
5158 struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
5159 struct i40e_asq_cmd_details *cmd_details)
5160{
5161 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5162 i40e_aqc_opc_query_vsi_bw_config,
5163 cmd_details);
5164}
5165
5166/**
5167 * i40e_aq_query_vsi_ets_sla_config - Query VSI BW configuration per TC
5168 * @hw: pointer to the hw struct
5169 * @seid: seid of the VSI
5170 * @bw_data: Buffer to hold VSI BW configuration per TC
5171 * @cmd_details: pointer to command details structure or NULL
5172 **/
5173enum i40e_status_code i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
5174 u16 seid,
5175 struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
5176 struct i40e_asq_cmd_details *cmd_details)
5177{
5178 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5179 i40e_aqc_opc_query_vsi_ets_sla_config,
5180 cmd_details);
5181}
5182
5183/**
5184 * i40e_aq_query_switch_comp_ets_config - Query Switch comp BW config per TC
5185 * @hw: pointer to the hw struct
5186 * @seid: seid of the switching component
5187 * @bw_data: Buffer to hold switching component's per TC BW config
5188 * @cmd_details: pointer to command details structure or NULL
5189 **/
5190enum i40e_status_code i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
5191 u16 seid,
5192 struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
5193 struct i40e_asq_cmd_details *cmd_details)
5194{
5195 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5196 i40e_aqc_opc_query_switching_comp_ets_config,
5197 cmd_details);
5198}
5199
5200/**
5201 * i40e_aq_query_port_ets_config - Query Physical Port ETS configuration
5202 * @hw: pointer to the hw struct
5203 * @seid: seid of the VSI or switching component connected to Physical Port
5204 * @bw_data: Buffer to hold current ETS configuration for the Physical Port
5205 * @cmd_details: pointer to command details structure or NULL
5206 **/
5207enum i40e_status_code i40e_aq_query_port_ets_config(struct i40e_hw *hw,
5208 u16 seid,
5209 struct i40e_aqc_query_port_ets_config_resp *bw_data,
5210 struct i40e_asq_cmd_details *cmd_details)
5211{
5212 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5213 i40e_aqc_opc_query_port_ets_config,
5214 cmd_details);
5215}
5216
5217/**
5218 * i40e_aq_query_switch_comp_bw_config - Query Switch comp BW configuration
5219 * @hw: pointer to the hw struct
5220 * @seid: seid of the switching component
5221 * @bw_data: Buffer to hold switching component's BW configuration
5222 * @cmd_details: pointer to command details structure or NULL
5223 **/
5224enum i40e_status_code i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
5225 u16 seid,
5226 struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
5227 struct i40e_asq_cmd_details *cmd_details)
5228{
5229 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5230 i40e_aqc_opc_query_switching_comp_bw_config,
5231 cmd_details);
5232}
5233
5234/**
5235 * i40e_validate_filter_settings
5236 * @hw: pointer to the hardware structure
5237 * @settings: Filter control settings
5238 *
5239 * Check and validate the filter control settings passed.
5240 * The function checks for the valid filter/context sizes being
5241 * passed for FCoE and PE.
5242 *
5243 * Returns I40E_SUCCESS if the values passed are valid and within
5244 * range else returns an error.
5245 **/
5246STATIC enum i40e_status_code i40e_validate_filter_settings(struct i40e_hw *hw,
5247 struct i40e_filter_control_settings *settings)
5248{
5249 u32 fcoe_cntx_size, fcoe_filt_size;
5250 u32 pe_cntx_size, pe_filt_size;
5251 u32 fcoe_fmax;
5252
5253 u32 val;
5254
5255 /* Validate FCoE settings passed */
5256 switch (settings->fcoe_filt_num) {
5257 case I40E_HASH_FILTER_SIZE_1K:
5258 case I40E_HASH_FILTER_SIZE_2K:
5259 case I40E_HASH_FILTER_SIZE_4K:
5260 case I40E_HASH_FILTER_SIZE_8K:
5261 case I40E_HASH_FILTER_SIZE_16K:
5262 case I40E_HASH_FILTER_SIZE_32K:
5263 fcoe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
5264 fcoe_filt_size <<= (u32)settings->fcoe_filt_num;
5265 break;
5266 default:
5267 return I40E_ERR_PARAM;
5268 }
5269
5270 switch (settings->fcoe_cntx_num) {
5271 case I40E_DMA_CNTX_SIZE_512:
5272 case I40E_DMA_CNTX_SIZE_1K:
5273 case I40E_DMA_CNTX_SIZE_2K:
5274 case I40E_DMA_CNTX_SIZE_4K:
5275 fcoe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
5276 fcoe_cntx_size <<= (u32)settings->fcoe_cntx_num;
5277 break;
5278 default:
5279 return I40E_ERR_PARAM;
5280 }
5281
5282 /* Validate PE settings passed */
5283 switch (settings->pe_filt_num) {
5284 case I40E_HASH_FILTER_SIZE_1K:
5285 case I40E_HASH_FILTER_SIZE_2K:
5286 case I40E_HASH_FILTER_SIZE_4K:
5287 case I40E_HASH_FILTER_SIZE_8K:
5288 case I40E_HASH_FILTER_SIZE_16K:
5289 case I40E_HASH_FILTER_SIZE_32K:
5290 case I40E_HASH_FILTER_SIZE_64K:
5291 case I40E_HASH_FILTER_SIZE_128K:
5292 case I40E_HASH_FILTER_SIZE_256K:
5293 case I40E_HASH_FILTER_SIZE_512K:
5294 case I40E_HASH_FILTER_SIZE_1M:
5295 pe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
5296 pe_filt_size <<= (u32)settings->pe_filt_num;
5297 break;
5298 default:
5299 return I40E_ERR_PARAM;
5300 }
5301
5302 switch (settings->pe_cntx_num) {
5303 case I40E_DMA_CNTX_SIZE_512:
5304 case I40E_DMA_CNTX_SIZE_1K:
5305 case I40E_DMA_CNTX_SIZE_2K:
5306 case I40E_DMA_CNTX_SIZE_4K:
5307 case I40E_DMA_CNTX_SIZE_8K:
5308 case I40E_DMA_CNTX_SIZE_16K:
5309 case I40E_DMA_CNTX_SIZE_32K:
5310 case I40E_DMA_CNTX_SIZE_64K:
5311 case I40E_DMA_CNTX_SIZE_128K:
5312 case I40E_DMA_CNTX_SIZE_256K:
5313 pe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
5314 pe_cntx_size <<= (u32)settings->pe_cntx_num;
5315 break;
5316 default:
5317 return I40E_ERR_PARAM;
5318 }
5319
5320 /* FCHSIZE + FCDSIZE should not be greater than PMFCOEFMAX */
5321 val = rd32(hw, I40E_GLHMC_FCOEFMAX);
5322 fcoe_fmax = (val & I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK)
5323 >> I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT;
5324 if (fcoe_filt_size + fcoe_cntx_size > fcoe_fmax)
5325 return I40E_ERR_INVALID_SIZE;
5326
5327 return I40E_SUCCESS;
5328}
5329
5330/**
5331 * i40e_set_filter_control
5332 * @hw: pointer to the hardware structure
5333 * @settings: Filter control settings
5334 *
5335 * Set the Queue Filters for PE/FCoE and enable filters required
5336 * for a single PF. It is expected that these settings are programmed
5337 * at the driver initialization time.
5338 **/
5339enum i40e_status_code i40e_set_filter_control(struct i40e_hw *hw,
5340 struct i40e_filter_control_settings *settings)
5341{
5342 enum i40e_status_code ret = I40E_SUCCESS;
5343 u32 hash_lut_size = 0;
5344 u32 val;
5345
5346 if (!settings)
5347 return I40E_ERR_PARAM;
5348
5349 /* Validate the input settings */
5350 ret = i40e_validate_filter_settings(hw, settings);
5351 if (ret)
5352 return ret;
5353
5354 /* Read the PF Queue Filter control register */
5355 val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
5356
5357 /* Program required PE hash buckets for the PF */
5358 val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
5359 val |= ((u32)settings->pe_filt_num << I40E_PFQF_CTL_0_PEHSIZE_SHIFT) &
5360 I40E_PFQF_CTL_0_PEHSIZE_MASK;
5361 /* Program required PE contexts for the PF */
5362 val &= ~I40E_PFQF_CTL_0_PEDSIZE_MASK;
5363 val |= ((u32)settings->pe_cntx_num << I40E_PFQF_CTL_0_PEDSIZE_SHIFT) &
5364 I40E_PFQF_CTL_0_PEDSIZE_MASK;
5365
5366 /* Program required FCoE hash buckets for the PF */
5367 val &= ~I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5368 val |= ((u32)settings->fcoe_filt_num <<
5369 I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT) &
5370 I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5371 /* Program required FCoE DDP contexts for the PF */
5372 val &= ~I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5373 val |= ((u32)settings->fcoe_cntx_num <<
5374 I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT) &
5375 I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5376
5377 /* Program Hash LUT size for the PF */
5378 val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5379 if (settings->hash_lut_size == I40E_HASH_LUT_SIZE_512)
5380 hash_lut_size = 1;
5381 val |= (hash_lut_size << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT) &
5382 I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5383
5384 /* Enable FDIR, Ethertype and MACVLAN filters for PF and VFs */
5385 if (settings->enable_fdir)
5386 val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
5387 if (settings->enable_ethtype)
5388 val |= I40E_PFQF_CTL_0_ETYPE_ENA_MASK;
5389 if (settings->enable_macvlan)
5390 val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
5391
5392 i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
5393
5394 return I40E_SUCCESS;
5395}
5396
5397/**
5398 * i40e_aq_add_rem_control_packet_filter - Add or Remove Control Packet Filter
5399 * @hw: pointer to the hw struct
5400 * @mac_addr: MAC address to use in the filter
5401 * @ethtype: Ethertype to use in the filter
5402 * @flags: Flags that needs to be applied to the filter
5403 * @vsi_seid: seid of the control VSI
5404 * @queue: VSI queue number to send the packet to
5405 * @is_add: Add control packet filter if True else remove
5406 * @stats: Structure to hold information on control filter counts
5407 * @cmd_details: pointer to command details structure or NULL
5408 *
5409 * This command will Add or Remove control packet filter for a control VSI.
5410 * In return it will update the total number of perfect filter count in
5411 * the stats member.
5412 **/
5413enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
5414 u8 *mac_addr, u16 ethtype, u16 flags,
5415 u16 vsi_seid, u16 queue, bool is_add,
5416 struct i40e_control_filter_stats *stats,
5417 struct i40e_asq_cmd_details *cmd_details)
5418{
5419 struct i40e_aq_desc desc;
5420 struct i40e_aqc_add_remove_control_packet_filter *cmd =
5421 (struct i40e_aqc_add_remove_control_packet_filter *)
5422 &desc.params.raw;
5423 struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
5424 (struct i40e_aqc_add_remove_control_packet_filter_completion *)
5425 &desc.params.raw;
5426 enum i40e_status_code status;
5427
5428 if (vsi_seid == 0)
5429 return I40E_ERR_PARAM;
5430
5431 if (is_add) {
5432 i40e_fill_default_direct_cmd_desc(&desc,
5433 i40e_aqc_opc_add_control_packet_filter);
5434 cmd->queue = CPU_TO_LE16(queue);
5435 } else {
5436 i40e_fill_default_direct_cmd_desc(&desc,
5437 i40e_aqc_opc_remove_control_packet_filter);
5438 }
5439
5440 if (mac_addr)
5441 i40e_memcpy(cmd->mac, mac_addr, I40E_ETH_LENGTH_OF_ADDRESS,
5442 I40E_NONDMA_TO_NONDMA);
5443
5444 cmd->etype = CPU_TO_LE16(ethtype);
5445 cmd->flags = CPU_TO_LE16(flags);
5446 cmd->seid = CPU_TO_LE16(vsi_seid);
5447
5448 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5449
5450 if (!status && stats) {
5451 stats->mac_etype_used = LE16_TO_CPU(resp->mac_etype_used);
5452 stats->etype_used = LE16_TO_CPU(resp->etype_used);
5453 stats->mac_etype_free = LE16_TO_CPU(resp->mac_etype_free);
5454 stats->etype_free = LE16_TO_CPU(resp->etype_free);
5455 }
5456
5457 return status;
5458}
5459
5460/**
5461 * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
5462 * @hw: pointer to the hw struct
5463 * @seid: VSI seid to add ethertype filter from
5464 **/
5465#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
5466void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
5467 u16 seid)
5468{
5469 u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
5470 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
5471 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
5472 u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
5473 enum i40e_status_code status;
5474
5475 status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
5476 seid, 0, true, NULL,
5477 NULL);
5478 if (status)
5479 DEBUGOUT("Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
5480}
5481
5482/**
5483 * i40e_fix_up_geneve_vni - adjust Geneve VNI for HW issue
5484 * @filters: list of cloud filters
5485 * @filter_count: length of list
5486 *
5487 * There's an issue in the device where the Geneve VNI layout needs
5488 * to be shifted 1 byte over from the VxLAN VNI
5489 **/
5490STATIC void i40e_fix_up_geneve_vni(
5491 struct i40e_aqc_add_remove_cloud_filters_element_data *filters,
5492 u8 filter_count)
5493{
5494 struct i40e_aqc_add_remove_cloud_filters_element_data *f = filters;
5495 int i;
5496
5497 for (i = 0; i < filter_count; i++) {
5498 u16 tnl_type;
5499 u32 ti;
5500
5501 tnl_type = (LE16_TO_CPU(f[i].flags) &
5502 I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5503 I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5504 if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5505 ti = LE32_TO_CPU(f[i].tenant_id);
5506 f[i].tenant_id = CPU_TO_LE32(ti << 8);
5507 }
5508 }
5509}
5510
5511/**
5512 * i40e_aq_add_cloud_filters
5513 * @hw: pointer to the hardware structure
5514 * @seid: VSI seid to add cloud filters from
5515 * @filters: Buffer which contains the filters to be added
5516 * @filter_count: number of filters contained in the buffer
5517 *
5518 * Set the cloud filters for a given VSI. The contents of the
5519 * i40e_aqc_add_remove_cloud_filters_element_data are filled
5520 * in by the caller of the function.
5521 *
5522 **/
5523enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
5524 u16 seid,
5525 struct i40e_aqc_add_remove_cloud_filters_element_data *filters,
5526 u8 filter_count)
5527{
5528 struct i40e_aq_desc desc;
5529 struct i40e_aqc_add_remove_cloud_filters *cmd =
5530 (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5531 enum i40e_status_code status;
5532 u16 buff_len;
5533
5534 i40e_fill_default_direct_cmd_desc(&desc,
5535 i40e_aqc_opc_add_cloud_filters);
5536
5537 buff_len = filter_count * sizeof(*filters);
5538 desc.datalen = CPU_TO_LE16(buff_len);
5539 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5540 cmd->num_filters = filter_count;
5541 cmd->seid = CPU_TO_LE16(seid);
5542
5543 i40e_fix_up_geneve_vni(filters, filter_count);
5544
5545 status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5546
5547 return status;
5548}
5549
5550/**
5551 * i40e_aq_remove_cloud_filters
5552 * @hw: pointer to the hardware structure
5553 * @seid: VSI seid to remove cloud filters from
5554 * @filters: Buffer which contains the filters to be removed
5555 * @filter_count: number of filters contained in the buffer
5556 *
5557 * Remove the cloud filters for a given VSI. The contents of the
5558 * i40e_aqc_add_remove_cloud_filters_element_data are filled
5559 * in by the caller of the function.
5560 *
5561 **/
5562enum i40e_status_code i40e_aq_remove_cloud_filters(struct i40e_hw *hw,
5563 u16 seid,
5564 struct i40e_aqc_add_remove_cloud_filters_element_data *filters,
5565 u8 filter_count)
5566{
5567 struct i40e_aq_desc desc;
5568 struct i40e_aqc_add_remove_cloud_filters *cmd =
5569 (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5570 enum i40e_status_code status;
5571 u16 buff_len;
5572
5573 i40e_fill_default_direct_cmd_desc(&desc,
5574 i40e_aqc_opc_remove_cloud_filters);
5575
5576 buff_len = filter_count * sizeof(*filters);
5577 desc.datalen = CPU_TO_LE16(buff_len);
5578 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5579 cmd->num_filters = filter_count;
5580 cmd->seid = CPU_TO_LE16(seid);
5581
5582 i40e_fix_up_geneve_vni(filters, filter_count);
5583
5584 status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5585
5586 return status;
5587}
5588
5589/**
5590 * i40e_aq_alternate_write
5591 * @hw: pointer to the hardware structure
5592 * @reg_addr0: address of first dword to be read
5593 * @reg_val0: value to be written under 'reg_addr0'
5594 * @reg_addr1: address of second dword to be read
5595 * @reg_val1: value to be written under 'reg_addr1'
5596 *
5597 * Write one or two dwords to alternate structure. Fields are indicated
5598 * by 'reg_addr0' and 'reg_addr1' register numbers.
5599 *
5600 **/
5601enum i40e_status_code i40e_aq_alternate_write(struct i40e_hw *hw,
5602 u32 reg_addr0, u32 reg_val0,
5603 u32 reg_addr1, u32 reg_val1)
5604{
5605 struct i40e_aq_desc desc;
5606 struct i40e_aqc_alternate_write *cmd_resp =
5607 (struct i40e_aqc_alternate_write *)&desc.params.raw;
5608 enum i40e_status_code status;
5609
5610 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_write);
5611 cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
5612 cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
5613 cmd_resp->data0 = CPU_TO_LE32(reg_val0);
5614 cmd_resp->data1 = CPU_TO_LE32(reg_val1);
5615
5616 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5617
5618 return status;
5619}
5620
5621/**
5622 * i40e_aq_alternate_write_indirect
5623 * @hw: pointer to the hardware structure
5624 * @addr: address of a first register to be modified
5625 * @dw_count: number of alternate structure fields to write
5626 * @buffer: pointer to the command buffer
5627 *
5628 * Write 'dw_count' dwords from 'buffer' to alternate structure
5629 * starting at 'addr'.
5630 *
5631 **/
5632enum i40e_status_code i40e_aq_alternate_write_indirect(struct i40e_hw *hw,
5633 u32 addr, u32 dw_count, void *buffer)
5634{
5635 struct i40e_aq_desc desc;
5636 struct i40e_aqc_alternate_ind_write *cmd_resp =
5637 (struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
5638 enum i40e_status_code status;
5639
5640 if (buffer == NULL)
5641 return I40E_ERR_PARAM;
5642
5643 /* Indirect command */
5644 i40e_fill_default_direct_cmd_desc(&desc,
5645 i40e_aqc_opc_alternate_write_indirect);
5646
5647 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
5648 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
5649 if (dw_count > (I40E_AQ_LARGE_BUF/4))
5650 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5651
5652 cmd_resp->address = CPU_TO_LE32(addr);
5653 cmd_resp->length = CPU_TO_LE32(dw_count);
5654
5655 status = i40e_asq_send_command(hw, &desc, buffer,
5656 I40E_LO_DWORD(4*dw_count), NULL);
5657
5658 return status;
5659}
5660
5661/**
5662 * i40e_aq_alternate_read
5663 * @hw: pointer to the hardware structure
5664 * @reg_addr0: address of first dword to be read
5665 * @reg_val0: pointer for data read from 'reg_addr0'
5666 * @reg_addr1: address of second dword to be read
5667 * @reg_val1: pointer for data read from 'reg_addr1'
5668 *
5669 * Read one or two dwords from alternate structure. Fields are indicated
5670 * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
5671 * is not passed then only register at 'reg_addr0' is read.
5672 *
5673 **/
5674enum i40e_status_code i40e_aq_alternate_read(struct i40e_hw *hw,
5675 u32 reg_addr0, u32 *reg_val0,
5676 u32 reg_addr1, u32 *reg_val1)
5677{
5678 struct i40e_aq_desc desc;
5679 struct i40e_aqc_alternate_write *cmd_resp =
5680 (struct i40e_aqc_alternate_write *)&desc.params.raw;
5681 enum i40e_status_code status;
5682
5683 if (reg_val0 == NULL)
5684 return I40E_ERR_PARAM;
5685
5686 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
5687 cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
5688 cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
5689
5690 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5691
5692 if (status == I40E_SUCCESS) {
5693 *reg_val0 = LE32_TO_CPU(cmd_resp->data0);
5694
5695 if (reg_val1 != NULL)
5696 *reg_val1 = LE32_TO_CPU(cmd_resp->data1);
5697 }
5698
5699 return status;
5700}
5701
5702/**
5703 * i40e_aq_alternate_read_indirect
5704 * @hw: pointer to the hardware structure
5705 * @addr: address of the alternate structure field
5706 * @dw_count: number of alternate structure fields to read
5707 * @buffer: pointer to the command buffer
5708 *
5709 * Read 'dw_count' dwords from alternate structure starting at 'addr' and
5710 * place them in 'buffer'. The buffer should be allocated by caller.
5711 *
5712 **/
5713enum i40e_status_code i40e_aq_alternate_read_indirect(struct i40e_hw *hw,
5714 u32 addr, u32 dw_count, void *buffer)
5715{
5716 struct i40e_aq_desc desc;
5717 struct i40e_aqc_alternate_ind_write *cmd_resp =
5718 (struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
5719 enum i40e_status_code status;
5720
5721 if (buffer == NULL)
5722 return I40E_ERR_PARAM;
5723
5724 /* Indirect command */
5725 i40e_fill_default_direct_cmd_desc(&desc,
5726 i40e_aqc_opc_alternate_read_indirect);
5727
5728 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
5729 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
5730 if (dw_count > (I40E_AQ_LARGE_BUF/4))
5731 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5732
5733 cmd_resp->address = CPU_TO_LE32(addr);
5734 cmd_resp->length = CPU_TO_LE32(dw_count);
5735
5736 status = i40e_asq_send_command(hw, &desc, buffer,
5737 I40E_LO_DWORD(4*dw_count), NULL);
5738
5739 return status;
5740}
5741
5742/**
5743 * i40e_aq_alternate_clear
5744 * @hw: pointer to the HW structure.
5745 *
5746 * Clear the alternate structures of the port from which the function
5747 * is called.
5748 *
5749 **/
5750enum i40e_status_code i40e_aq_alternate_clear(struct i40e_hw *hw)
5751{
5752 struct i40e_aq_desc desc;
5753 enum i40e_status_code status;
5754
5755 i40e_fill_default_direct_cmd_desc(&desc,
5756 i40e_aqc_opc_alternate_clear_port);
5757
5758 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5759
5760 return status;
5761}
5762
5763/**
5764 * i40e_aq_alternate_write_done
5765 * @hw: pointer to the HW structure.
5766 * @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS
5767 * @reset_needed: indicates the SW should trigger GLOBAL reset
5768 *
5769 * Indicates to the FW that alternate structures have been changed.
5770 *
5771 **/
5772enum i40e_status_code i40e_aq_alternate_write_done(struct i40e_hw *hw,
5773 u8 bios_mode, bool *reset_needed)
5774{
5775 struct i40e_aq_desc desc;
5776 struct i40e_aqc_alternate_write_done *cmd =
5777 (struct i40e_aqc_alternate_write_done *)&desc.params.raw;
5778 enum i40e_status_code status;
5779
5780 if (reset_needed == NULL)
5781 return I40E_ERR_PARAM;
5782
5783 i40e_fill_default_direct_cmd_desc(&desc,
5784 i40e_aqc_opc_alternate_write_done);
5785
5786 cmd->cmd_flags = CPU_TO_LE16(bios_mode);
5787
5788 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5789 if (!status && reset_needed)
5790 *reset_needed = ((LE16_TO_CPU(cmd->cmd_flags) &
5791 I40E_AQ_ALTERNATE_RESET_NEEDED) != 0);
5792
5793 return status;
5794}
5795
5796/**
5797 * i40e_aq_set_oem_mode
5798 * @hw: pointer to the HW structure.
5799 * @oem_mode: the OEM mode to be used
5800 *
5801 * Sets the device to a specific operating mode. Currently the only supported
5802 * mode is no_clp, which causes FW to refrain from using Alternate RAM.
5803 *
5804 **/
5805enum i40e_status_code i40e_aq_set_oem_mode(struct i40e_hw *hw,
5806 u8 oem_mode)
5807{
5808 struct i40e_aq_desc desc;
5809 struct i40e_aqc_alternate_write_done *cmd =
5810 (struct i40e_aqc_alternate_write_done *)&desc.params.raw;
5811 enum i40e_status_code status;
5812
5813 i40e_fill_default_direct_cmd_desc(&desc,
5814 i40e_aqc_opc_alternate_set_mode);
5815
5816 cmd->cmd_flags = CPU_TO_LE16(oem_mode);
5817
5818 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5819
5820 return status;
5821}
5822
5823/**
5824 * i40e_aq_resume_port_tx
5825 * @hw: pointer to the hardware structure
5826 * @cmd_details: pointer to command details structure or NULL
5827 *
5828 * Resume port's Tx traffic
5829 **/
5830enum i40e_status_code i40e_aq_resume_port_tx(struct i40e_hw *hw,
5831 struct i40e_asq_cmd_details *cmd_details)
5832{
5833 struct i40e_aq_desc desc;
5834 enum i40e_status_code status;
5835
5836 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
5837
5838 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5839
5840 return status;
5841}
5842
5843/**
5844 * i40e_set_pci_config_data - store PCI bus info
5845 * @hw: pointer to hardware structure
5846 * @link_status: the link status word from PCI config space
5847 *
5848 * Stores the PCI bus info (speed, width, type) within the i40e_hw structure
5849 **/
5850void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
5851{
5852 hw->bus.type = i40e_bus_type_pci_express;
5853
5854 switch (link_status & I40E_PCI_LINK_WIDTH) {
5855 case I40E_PCI_LINK_WIDTH_1:
5856 hw->bus.width = i40e_bus_width_pcie_x1;
5857 break;
5858 case I40E_PCI_LINK_WIDTH_2:
5859 hw->bus.width = i40e_bus_width_pcie_x2;
5860 break;
5861 case I40E_PCI_LINK_WIDTH_4:
5862 hw->bus.width = i40e_bus_width_pcie_x4;
5863 break;
5864 case I40E_PCI_LINK_WIDTH_8:
5865 hw->bus.width = i40e_bus_width_pcie_x8;
5866 break;
5867 default:
5868 hw->bus.width = i40e_bus_width_unknown;
5869 break;
5870 }
5871
5872 switch (link_status & I40E_PCI_LINK_SPEED) {
5873 case I40E_PCI_LINK_SPEED_2500:
5874 hw->bus.speed = i40e_bus_speed_2500;
5875 break;
5876 case I40E_PCI_LINK_SPEED_5000:
5877 hw->bus.speed = i40e_bus_speed_5000;
5878 break;
5879 case I40E_PCI_LINK_SPEED_8000:
5880 hw->bus.speed = i40e_bus_speed_8000;
5881 break;
5882 default:
5883 hw->bus.speed = i40e_bus_speed_unknown;
5884 break;
5885 }
5886}
5887
5888/**
5889 * i40e_aq_debug_dump
5890 * @hw: pointer to the hardware structure
5891 * @cluster_id: specific cluster to dump
5892 * @table_id: table id within cluster
5893 * @start_index: index of line in the block to read
5894 * @buff_size: dump buffer size
5895 * @buff: dump buffer
5896 * @ret_buff_size: actual buffer size returned
5897 * @ret_next_table: next block to read
5898 * @ret_next_index: next index to read
5899 *
5900 * Dump internal FW/HW data for debug purposes.
5901 *
5902 **/
5903enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
5904 u8 table_id, u32 start_index, u16 buff_size,
5905 void *buff, u16 *ret_buff_size,
5906 u8 *ret_next_table, u32 *ret_next_index,
5907 struct i40e_asq_cmd_details *cmd_details)
5908{
5909 struct i40e_aq_desc desc;
5910 struct i40e_aqc_debug_dump_internals *cmd =
5911 (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
5912 struct i40e_aqc_debug_dump_internals *resp =
5913 (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
5914 enum i40e_status_code status;
5915
5916 if (buff_size == 0 || !buff)
5917 return I40E_ERR_PARAM;
5918
5919 i40e_fill_default_direct_cmd_desc(&desc,
5920 i40e_aqc_opc_debug_dump_internals);
5921 /* Indirect Command */
5922 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
5923 if (buff_size > I40E_AQ_LARGE_BUF)
5924 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5925
5926 cmd->cluster_id = cluster_id;
5927 cmd->table_id = table_id;
5928 cmd->idx = CPU_TO_LE32(start_index);
5929
5930 desc.datalen = CPU_TO_LE16(buff_size);
5931
5932 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5933 if (!status) {
5934 if (ret_buff_size != NULL)
5935 *ret_buff_size = LE16_TO_CPU(desc.datalen);
5936 if (ret_next_table != NULL)
5937 *ret_next_table = resp->table_id;
5938 if (ret_next_index != NULL)
5939 *ret_next_index = LE32_TO_CPU(resp->idx);
5940 }
5941
5942 return status;
5943}
5944
5945/**
5946 * i40e_read_bw_from_alt_ram
5947 * @hw: pointer to the hardware structure
5948 * @max_bw: pointer for max_bw read
5949 * @min_bw: pointer for min_bw read
5950 * @min_valid: pointer for bool that is true if min_bw is a valid value
5951 * @max_valid: pointer for bool that is true if max_bw is a valid value
5952 *
5953 * Read bw from the alternate ram for the given pf
5954 **/
5955enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
5956 u32 *max_bw, u32 *min_bw,
5957 bool *min_valid, bool *max_valid)
5958{
5959 enum i40e_status_code status;
5960 u32 max_bw_addr, min_bw_addr;
5961
5962 /* Calculate the address of the min/max bw registers */
5963 max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
5964 I40E_ALT_STRUCT_MAX_BW_OFFSET +
5965 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
5966 min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
5967 I40E_ALT_STRUCT_MIN_BW_OFFSET +
5968 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
5969
5970 /* Read the bandwidths from alt ram */
5971 status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
5972 min_bw_addr, min_bw);
5973
5974 if (*min_bw & I40E_ALT_BW_VALID_MASK)
5975 *min_valid = true;
5976 else
5977 *min_valid = false;
5978
5979 if (*max_bw & I40E_ALT_BW_VALID_MASK)
5980 *max_valid = true;
5981 else
5982 *max_valid = false;
5983
5984 return status;
5985}
5986
5987/**
5988 * i40e_aq_configure_partition_bw
5989 * @hw: pointer to the hardware structure
5990 * @bw_data: Buffer holding valid pfs and bw limits
5991 * @cmd_details: pointer to command details
5992 *
5993 * Configure partitions guaranteed/max bw
5994 **/
5995enum i40e_status_code i40e_aq_configure_partition_bw(struct i40e_hw *hw,
5996 struct i40e_aqc_configure_partition_bw_data *bw_data,
5997 struct i40e_asq_cmd_details *cmd_details)
5998{
5999 enum i40e_status_code status;
6000 struct i40e_aq_desc desc;
6001 u16 bwd_size = sizeof(*bw_data);
6002
6003 i40e_fill_default_direct_cmd_desc(&desc,
6004 i40e_aqc_opc_configure_partition_bw);
6005
6006 /* Indirect command */
6007 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6008 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
6009
6010 if (bwd_size > I40E_AQ_LARGE_BUF)
6011 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6012
6013 desc.datalen = CPU_TO_LE16(bwd_size);
6014
6015 status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size, cmd_details);
6016
6017 return status;
6018}
6019
6020/**
6021 * i40e_read_phy_register
6022 * @hw: pointer to the HW structure
6023 * @page: registers page number
6024 * @reg: register address in the page
6025 * @phy_adr: PHY address on MDIO interface
6026 * @value: PHY register value
6027 *
6028 * Reads specified PHY register value
6029 **/
6030enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
6031 u8 page, u16 reg, u8 phy_addr,
6032 u16 *value)
6033{
6034 enum i40e_status_code status = I40E_ERR_TIMEOUT;
6035 u32 command = 0;
6036 u16 retry = 1000;
6037 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6038
6039 command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6040 (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6041 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6042 (I40E_MDIO_OPCODE_ADDRESS) |
6043 (I40E_MDIO_STCODE) |
6044 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6045 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6046 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6047 do {
6048 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6049 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6050 status = I40E_SUCCESS;
6051 break;
6052 }
6053 i40e_usec_delay(10);
6054 retry--;
6055 } while (retry);
6056
6057 if (status) {
6058 i40e_debug(hw, I40E_DEBUG_PHY,
6059 "PHY: Can't write command to external PHY.\n");
6060 goto phy_read_end;
6061 }
6062
6063 command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6064 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6065 (I40E_MDIO_OPCODE_READ) |
6066 (I40E_MDIO_STCODE) |
6067 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6068 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6069 status = I40E_ERR_TIMEOUT;
6070 retry = 1000;
6071 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6072 do {
6073 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6074 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6075 status = I40E_SUCCESS;
6076 break;
6077 }
6078 i40e_usec_delay(10);
6079 retry--;
6080 } while (retry);
6081
6082 if (!status) {
6083 command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6084 *value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6085 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6086 } else {
6087 i40e_debug(hw, I40E_DEBUG_PHY,
6088 "PHY: Can't read register value from external PHY.\n");
6089 }
6090
6091phy_read_end:
6092 return status;
6093}
6094
6095/**
6096 * i40e_write_phy_register
6097 * @hw: pointer to the HW structure
6098 * @page: registers page number
6099 * @reg: register address in the page
6100 * @phy_adr: PHY address on MDIO interface
6101 * @value: PHY register value
6102 *
6103 * Writes value to specified PHY register
6104 **/
6105enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
6106 u8 page, u16 reg, u8 phy_addr,
6107 u16 value)
6108{
6109 enum i40e_status_code status = I40E_ERR_TIMEOUT;
6110 u32 command = 0;
6111 u16 retry = 1000;
6112 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6113
6114 command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6115 (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6116 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6117 (I40E_MDIO_OPCODE_ADDRESS) |
6118 (I40E_MDIO_STCODE) |
6119 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6120 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6121 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6122 do {
6123 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6124 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6125 status = I40E_SUCCESS;
6126 break;
6127 }
6128 i40e_usec_delay(10);
6129 retry--;
6130 } while (retry);
6131 if (status) {
6132 i40e_debug(hw, I40E_DEBUG_PHY,
6133 "PHY: Can't write command to external PHY.\n");
6134 goto phy_write_end;
6135 }
6136
6137 command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6138 wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6139
6140 command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6141 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6142 (I40E_MDIO_OPCODE_WRITE) |
6143 (I40E_MDIO_STCODE) |
6144 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6145 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6146 status = I40E_ERR_TIMEOUT;
6147 retry = 1000;
6148 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6149 do {
6150 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6151 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6152 status = I40E_SUCCESS;
6153 break;
6154 }
6155 i40e_usec_delay(10);
6156 retry--;
6157 } while (retry);
6158
6159phy_write_end:
6160 return status;
6161}
6162
6163/**
6164 * i40e_get_phy_address
6165 * @hw: pointer to the HW structure
6166 * @dev_num: PHY port num that address we want
6167 * @phy_addr: Returned PHY address
6168 *
6169 * Gets PHY address for current port
6170 **/
6171u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
6172{
6173 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6174 u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
6175
6176 return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
6177}
6178
6179/**
6180 * i40e_blink_phy_led
6181 * @hw: pointer to the HW structure
6182 * @time: time how long led will blinks in secs
6183 * @interval: gap between LED on and off in msecs
6184 *
6185 * Blinks PHY link LED
6186 **/
6187enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
6188 u32 time, u32 interval)
6189{
6190 enum i40e_status_code status = I40E_SUCCESS;
6191 u32 i;
6192 u16 led_ctl = 0;
6193 u16 gpio_led_port;
6194 u16 led_reg;
6195 u16 led_addr = I40E_PHY_LED_PROV_REG_1;
6196 u8 phy_addr = 0;
6197 u8 port_num;
6198
6199 i = rd32(hw, I40E_PFGEN_PORTNUM);
6200 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
6201 phy_addr = i40e_get_phy_address(hw, port_num);
6202
6203 for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6204 led_addr++) {
6205 status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
6206 led_addr, phy_addr, &led_reg);
6207 if (status)
6208 goto phy_blinking_end;
6209 led_ctl = led_reg;
6210 if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6211 led_reg = 0;
6212 status = i40e_write_phy_register(hw,
6213 I40E_PHY_COM_REG_PAGE,
6214 led_addr, phy_addr,
6215 led_reg);
6216 if (status)
6217 goto phy_blinking_end;
6218 break;
6219 }
6220 }
6221
6222 if (time > 0 && interval > 0) {
6223 for (i = 0; i < time * 1000; i += interval) {
6224 status = i40e_read_phy_register(hw,
6225 I40E_PHY_COM_REG_PAGE,
6226 led_addr, phy_addr,
6227 &led_reg);
6228 if (status)
6229 goto restore_config;
6230 if (led_reg & I40E_PHY_LED_MANUAL_ON)
6231 led_reg = 0;
6232 else
6233 led_reg = I40E_PHY_LED_MANUAL_ON;
6234 status = i40e_write_phy_register(hw,
6235 I40E_PHY_COM_REG_PAGE,
6236 led_addr, phy_addr,
6237 led_reg);
6238 if (status)
6239 goto restore_config;
6240 i40e_msec_delay(interval);
6241 }
6242 }
6243
6244restore_config:
6245 status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
6246 phy_addr, led_ctl);
6247
6248phy_blinking_end:
6249 return status;
6250}
6251
6252/**
6253 * i40e_led_get_phy - return current on/off mode
6254 * @hw: pointer to the hw struct
6255 * @led_addr: address of led register to use
6256 * @val: original value of register to use
6257 *
6258 **/
6259enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
6260 u16 *val)
6261{
6262 enum i40e_status_code status = I40E_SUCCESS;
6263 u16 gpio_led_port;
6264 u8 phy_addr = 0;
6265 u16 reg_val;
6266 u16 temp_addr;
6267 u8 port_num;
6268 u32 i;
6269
6270 temp_addr = I40E_PHY_LED_PROV_REG_1;
6271 i = rd32(hw, I40E_PFGEN_PORTNUM);
6272 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
6273 phy_addr = i40e_get_phy_address(hw, port_num);
6274
6275 for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6276 temp_addr++) {
6277 status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
6278 temp_addr, phy_addr, &reg_val);
6279 if (status)
6280 return status;
6281 *val = reg_val;
6282 if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
6283 *led_addr = temp_addr;
6284 break;
6285 }
6286 }
6287 return status;
6288}
6289
6290/**
6291 * i40e_led_set_phy
6292 * @hw: pointer to the HW structure
6293 * @on: true or false
6294 * @mode: original val plus bit for set or ignore
6295 * Set led's on or off when controlled by the PHY
6296 *
6297 **/
6298enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on,
6299 u16 led_addr, u32 mode)
6300{
6301 enum i40e_status_code status = I40E_SUCCESS;
6302 u16 led_ctl = 0;
6303 u16 led_reg = 0;
6304 u8 phy_addr = 0;
6305 u8 port_num;
6306 u32 i;
6307
6308 i = rd32(hw, I40E_PFGEN_PORTNUM);
6309 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
6310 phy_addr = i40e_get_phy_address(hw, port_num);
6311
6312 status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
6313 phy_addr, &led_reg);
6314 if (status)
6315 return status;
6316 led_ctl = led_reg;
6317 if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6318 led_reg = 0;
6319 status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE,
6320 led_addr, phy_addr, led_reg);
6321 if (status)
6322 return status;
6323 }
6324 status = i40e_read_phy_register(hw, I40E_PHY_COM_REG_PAGE,
6325 led_addr, phy_addr, &led_reg);
6326 if (status)
6327 goto restore_config;
6328 if (on)
6329 led_reg = I40E_PHY_LED_MANUAL_ON;
6330 else
6331 led_reg = 0;
6332 status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE,
6333 led_addr, phy_addr, led_reg);
6334 if (status)
6335 goto restore_config;
6336 if (mode & I40E_PHY_LED_MODE_ORIG) {
6337 led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
6338 status = i40e_write_phy_register(hw,
6339 I40E_PHY_COM_REG_PAGE,
6340 led_addr, phy_addr, led_ctl);
6341 }
6342 return status;
6343restore_config:
6344 status = i40e_write_phy_register(hw, I40E_PHY_COM_REG_PAGE, led_addr,
6345 phy_addr, led_ctl);
6346 return status;
6347}
6348#endif /* PF_DRIVER */
6349
6350/**
6351 * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
6352 * @hw: pointer to the hw struct
6353 * @reg_addr: register address
6354 * @reg_val: ptr to register value
6355 * @cmd_details: pointer to command details structure or NULL
6356 *
6357 * Use the firmware to read the Rx control register,
6358 * especially useful if the Rx unit is under heavy pressure
6359 **/
6360enum i40e_status_code i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
6361 u32 reg_addr, u32 *reg_val,
6362 struct i40e_asq_cmd_details *cmd_details)
6363{
6364 struct i40e_aq_desc desc;
6365 struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
6366 (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
6367 enum i40e_status_code status;
6368
6369 if (reg_val == NULL)
6370 return I40E_ERR_PARAM;
6371
6372 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
6373
6374 cmd_resp->address = CPU_TO_LE32(reg_addr);
6375
6376 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
6377
6378 if (status == I40E_SUCCESS)
6379 *reg_val = LE32_TO_CPU(cmd_resp->value);
6380
6381 return status;
6382}
6383
6384/**
6385 * i40e_read_rx_ctl - read from an Rx control register
6386 * @hw: pointer to the hw struct
6387 * @reg_addr: register address
6388 **/
6389u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
6390{
6391 enum i40e_status_code status = I40E_SUCCESS;
6392 bool use_register;
6393 int retry = 5;
6394 u32 val = 0;
6395
6396 use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
6397 if (!use_register) {
6398do_retry:
6399 status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
6400 if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
6401 i40e_msec_delay(1);
6402 retry--;
6403 goto do_retry;
6404 }
6405 }
6406
6407 /* if the AQ access failed, try the old-fashioned way */
6408 if (status || use_register)
6409 val = rd32(hw, reg_addr);
6410
6411 return val;
6412}
6413
6414/**
6415 * i40e_aq_rx_ctl_write_register
6416 * @hw: pointer to the hw struct
6417 * @reg_addr: register address
6418 * @reg_val: register value
6419 * @cmd_details: pointer to command details structure or NULL
6420 *
6421 * Use the firmware to write to an Rx control register,
6422 * especially useful if the Rx unit is under heavy pressure
6423 **/
6424enum i40e_status_code i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
6425 u32 reg_addr, u32 reg_val,
6426 struct i40e_asq_cmd_details *cmd_details)
6427{
6428 struct i40e_aq_desc desc;
6429 struct i40e_aqc_rx_ctl_reg_read_write *cmd =
6430 (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
6431 enum i40e_status_code status;
6432
6433 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
6434
6435 cmd->address = CPU_TO_LE32(reg_addr);
6436 cmd->value = CPU_TO_LE32(reg_val);
6437
6438 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
6439
6440 return status;
6441}
6442
6443/**
6444 * i40e_write_rx_ctl - write to an Rx control register
6445 * @hw: pointer to the hw struct
6446 * @reg_addr: register address
6447 * @reg_val: register value
6448 **/
6449void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
6450{
6451 enum i40e_status_code status = I40E_SUCCESS;
6452 bool use_register;
6453 int retry = 5;
6454
6455 use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
6456 if (!use_register) {
6457do_retry:
6458 status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
6459 reg_val, NULL);
6460 if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
6461 i40e_msec_delay(1);
6462 retry--;
6463 goto do_retry;
6464 }
6465 }
6466
6467 /* if the AQ access failed, try the old-fashioned way */
6468 if (status || use_register)
6469 wr32(hw, reg_addr, reg_val);
6470}
6471#ifdef VF_DRIVER
6472
6473/**
6474 * i40e_aq_send_msg_to_pf
6475 * @hw: pointer to the hardware structure
6476 * @v_opcode: opcodes for VF-PF communication
6477 * @v_retval: return error code
6478 * @msg: pointer to the msg buffer
6479 * @msglen: msg length
6480 * @cmd_details: pointer to command details
6481 *
6482 * Send message to PF driver using admin queue. By default, this message
6483 * is sent asynchronously, i.e. i40e_asq_send_command() does not wait for
6484 * completion before returning.
6485 **/
6486enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
6487 enum i40e_virtchnl_ops v_opcode,
6488 enum i40e_status_code v_retval,
6489 u8 *msg, u16 msglen,
6490 struct i40e_asq_cmd_details *cmd_details)
6491{
6492 struct i40e_aq_desc desc;
6493 struct i40e_asq_cmd_details details;
6494 enum i40e_status_code status;
6495
6496 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf);
6497 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
6498 desc.cookie_high = CPU_TO_LE32(v_opcode);
6499 desc.cookie_low = CPU_TO_LE32(v_retval);
6500 if (msglen) {
6501 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF
6502 | I40E_AQ_FLAG_RD));
6503 if (msglen > I40E_AQ_LARGE_BUF)
6504 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6505 desc.datalen = CPU_TO_LE16(msglen);
6506 }
6507 if (!cmd_details) {
6508 i40e_memset(&details, 0, sizeof(details), I40E_NONDMA_MEM);
6509 details.async = true;
6510 cmd_details = &details;
6511 }
6512 status = i40e_asq_send_command(hw, (struct i40e_aq_desc *)&desc, msg,
6513 msglen, cmd_details);
6514 return status;
6515}
6516
6517/**
6518 * i40e_vf_parse_hw_config
6519 * @hw: pointer to the hardware structure
6520 * @msg: pointer to the virtual channel VF resource structure
6521 *
6522 * Given a VF resource message from the PF, populate the hw struct
6523 * with appropriate information.
6524 **/
6525void i40e_vf_parse_hw_config(struct i40e_hw *hw,
6526 struct i40e_virtchnl_vf_resource *msg)
6527{
6528 struct i40e_virtchnl_vsi_resource *vsi_res;
6529 int i;
6530
6531 vsi_res = &msg->vsi_res[0];
6532
6533 hw->dev_caps.num_vsis = msg->num_vsis;
6534 hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
6535 hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
6536 hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
6537 hw->dev_caps.dcb = msg->vf_offload_flags &
6538 I40E_VIRTCHNL_VF_OFFLOAD_L2;
6539 hw->dev_caps.fcoe = (msg->vf_offload_flags &
6540 I40E_VIRTCHNL_VF_OFFLOAD_FCOE) ? 1 : 0;
6541 hw->dev_caps.iwarp = (msg->vf_offload_flags &
6542 I40E_VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
6543 for (i = 0; i < msg->num_vsis; i++) {
6544 if (vsi_res->vsi_type == I40E_VSI_SRIOV) {
6545 i40e_memcpy(hw->mac.perm_addr,
6546 vsi_res->default_mac_addr,
6547 I40E_ETH_LENGTH_OF_ADDRESS,
6548 I40E_NONDMA_TO_NONDMA);
6549 i40e_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
6550 I40E_ETH_LENGTH_OF_ADDRESS,
6551 I40E_NONDMA_TO_NONDMA);
6552 }
6553 vsi_res++;
6554 }
6555}
6556
6557/**
6558 * i40e_vf_reset
6559 * @hw: pointer to the hardware structure
6560 *
6561 * Send a VF_RESET message to the PF. Does not wait for response from PF
6562 * as none will be forthcoming. Immediately after calling this function,
6563 * the admin queue should be shut down and (optionally) reinitialized.
6564 **/
6565enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
6566{
6567 return i40e_aq_send_msg_to_pf(hw, I40E_VIRTCHNL_OP_RESET_VF,
6568 I40E_SUCCESS, NULL, 0, NULL);
6569}
6570#endif /* VF_DRIVER */
6571#ifdef X722_SUPPORT
6572
6573/**
6574 * i40e_aq_set_arp_proxy_config
6575 * @hw: pointer to the HW structure
6576 * @proxy_config - pointer to proxy config command table struct
6577 * @cmd_details: pointer to command details
6578 *
6579 * Set ARP offload parameters from pre-populated
6580 * i40e_aqc_arp_proxy_data struct
6581 **/
6582enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
6583 struct i40e_aqc_arp_proxy_data *proxy_config,
6584 struct i40e_asq_cmd_details *cmd_details)
6585{
6586 struct i40e_aq_desc desc;
6587 enum i40e_status_code status;
6588
6589 if (!proxy_config)
6590 return I40E_ERR_PARAM;
6591
6592 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_proxy_config);
6593
6594 desc.params.external.addr_high =
6595 CPU_TO_LE32(I40E_HI_DWORD((u64)proxy_config));
6596 desc.params.external.addr_low =
6597 CPU_TO_LE32(I40E_LO_DWORD((u64)proxy_config));
6598
6599 status = i40e_asq_send_command(hw, &desc, proxy_config,
6600 sizeof(struct i40e_aqc_arp_proxy_data),
6601 cmd_details);
6602
6603 return status;
6604}
6605
6606/**
6607 * i40e_aq_opc_set_ns_proxy_table_entry
6608 * @hw: pointer to the HW structure
6609 * @ns_proxy_table_entry: pointer to NS table entry command struct
6610 * @cmd_details: pointer to command details
6611 *
6612 * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
6613 * from pre-populated i40e_aqc_ns_proxy_data struct
6614 **/
6615enum i40e_status_code i40e_aq_set_ns_proxy_table_entry(struct i40e_hw *hw,
6616 struct i40e_aqc_ns_proxy_data *ns_proxy_table_entry,
6617 struct i40e_asq_cmd_details *cmd_details)
6618{
6619 struct i40e_aq_desc desc;
6620 enum i40e_status_code status;
6621
6622 if (!ns_proxy_table_entry)
6623 return I40E_ERR_PARAM;
6624
6625 i40e_fill_default_direct_cmd_desc(&desc,
6626 i40e_aqc_opc_set_ns_proxy_table_entry);
6627
6628 desc.params.external.addr_high =
6629 CPU_TO_LE32(I40E_HI_DWORD((u64)ns_proxy_table_entry));
6630 desc.params.external.addr_low =
6631 CPU_TO_LE32(I40E_LO_DWORD((u64)ns_proxy_table_entry));
6632
6633 status = i40e_asq_send_command(hw, &desc, ns_proxy_table_entry,
6634 sizeof(struct i40e_aqc_ns_proxy_data),
6635 cmd_details);
6636
6637 return status;
6638}
6639
6640/**
6641 * i40e_aq_set_clear_wol_filter
6642 * @hw: pointer to the hw struct
6643 * @filter_index: index of filter to modify (0-7)
6644 * @filter: buffer containing filter to be set
6645 * @set_filter: true to set filter, false to clear filter
6646 * @no_wol_tco: if true, pass through packets cannot cause wake-up
6647 * if false, pass through packets may cause wake-up
6648 * @filter_valid: true if filter action is valid
6649 * @no_wol_tco_valid: true if no WoL in TCO traffic action valid
6650 * @cmd_details: pointer to command details structure or NULL
6651 *
6652 * Set or clear WoL filter for port attached to the PF
6653 **/
6654enum i40e_status_code i40e_aq_set_clear_wol_filter(struct i40e_hw *hw,
6655 u8 filter_index,
6656 struct i40e_aqc_set_wol_filter_data *filter,
6657 bool set_filter, bool no_wol_tco,
6658 bool filter_valid, bool no_wol_tco_valid,
6659 struct i40e_asq_cmd_details *cmd_details)
6660{
6661 struct i40e_aq_desc desc;
6662 struct i40e_aqc_set_wol_filter *cmd =
6663 (struct i40e_aqc_set_wol_filter *)&desc.params.raw;
6664 enum i40e_status_code status;
6665 u16 cmd_flags = 0;
6666 u16 valid_flags = 0;
6667 u16 buff_len = 0;
6668
6669 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_wol_filter);
6670
6671 if (filter_index >= I40E_AQC_MAX_NUM_WOL_FILTERS)
6672 return I40E_ERR_PARAM;
6673 cmd->filter_index = CPU_TO_LE16(filter_index);
6674
6675 if (set_filter) {
6676 if (!filter)
6677 return I40E_ERR_PARAM;
6678 cmd_flags |= I40E_AQC_SET_WOL_FILTER;
6679 buff_len = sizeof(*filter);
6680 }
6681 if (no_wol_tco)
6682 cmd_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_WOL;
6683 cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
6684
6685 if (filter_valid)
6686 valid_flags |= I40E_AQC_SET_WOL_FILTER_ACTION_VALID;
6687 if (no_wol_tco_valid)
6688 valid_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
6689 cmd->valid_flags = CPU_TO_LE16(valid_flags);
6690
6691 cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)filter));
6692 cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)filter));
6693
6694 status = i40e_asq_send_command(hw, &desc, filter,
6695 buff_len, cmd_details);
6696
6697 return status;
6698}
6699
6700/**
6701 * i40e_aq_get_wake_event_reason
6702 * @hw: pointer to the hw struct
6703 * @wake_reason: return value, index of matching filter
6704 * @cmd_details: pointer to command details structure or NULL
6705 *
6706 * Get information for the reason of a Wake Up event
6707 **/
6708enum i40e_status_code i40e_aq_get_wake_event_reason(struct i40e_hw *hw,
6709 u16 *wake_reason,
6710 struct i40e_asq_cmd_details *cmd_details)
6711{
6712 struct i40e_aq_desc desc;
6713 struct i40e_aqc_get_wake_reason_completion *resp =
6714 (struct i40e_aqc_get_wake_reason_completion *)&desc.params.raw;
6715 enum i40e_status_code status;
6716
6717 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_wake_reason);
6718
6719 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
6720
6721 if (status == I40E_SUCCESS)
6722 *wake_reason = LE16_TO_CPU(resp->wake_reason);
6723
6724 return status;
6725}
6726
6727#endif /* X722_SUPPORT */