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