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$*/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 */
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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
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 **/
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 **/
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
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 */
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 **/
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 fcoe_fmax;
5431
5432 u32 val;
5433
5434 /* Validate FCoE settings passed */
5435 switch (settings->fcoe_filt_num) {
5436 case I40E_HASH_FILTER_SIZE_1K:
5437 case I40E_HASH_FILTER_SIZE_2K:
5438 case I40E_HASH_FILTER_SIZE_4K:
5439 case I40E_HASH_FILTER_SIZE_8K:
5440 case I40E_HASH_FILTER_SIZE_16K:
5441 case I40E_HASH_FILTER_SIZE_32K:
5442 fcoe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
5443 fcoe_filt_size <<= (u32)settings->fcoe_filt_num;
5444 break;
5445 default:
5446 return I40E_ERR_PARAM;
5447 }
5448
5449 switch (settings->fcoe_cntx_num) {
5450 case I40E_DMA_CNTX_SIZE_512:
5451 case I40E_DMA_CNTX_SIZE_1K:
5452 case I40E_DMA_CNTX_SIZE_2K:
5453 case I40E_DMA_CNTX_SIZE_4K:
5454 fcoe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
5455 fcoe_cntx_size <<= (u32)settings->fcoe_cntx_num;
5456 break;
5457 default:
5458 return I40E_ERR_PARAM;
5459 }
5460
5461 /* Validate PE settings passed */
5462 switch (settings->pe_filt_num) {
5463 case I40E_HASH_FILTER_SIZE_1K:
5464 case I40E_HASH_FILTER_SIZE_2K:
5465 case I40E_HASH_FILTER_SIZE_4K:
5466 case I40E_HASH_FILTER_SIZE_8K:
5467 case I40E_HASH_FILTER_SIZE_16K:
5468 case I40E_HASH_FILTER_SIZE_32K:
5469 case I40E_HASH_FILTER_SIZE_64K:
5470 case I40E_HASH_FILTER_SIZE_128K:
5471 case I40E_HASH_FILTER_SIZE_256K:
5472 case I40E_HASH_FILTER_SIZE_512K:
5473 case I40E_HASH_FILTER_SIZE_1M:
5474 break;
5475 default:
5476 return I40E_ERR_PARAM;
5477 }
5478
5479 switch (settings->pe_cntx_num) {
5480 case I40E_DMA_CNTX_SIZE_512:
5481 case I40E_DMA_CNTX_SIZE_1K:
5482 case I40E_DMA_CNTX_SIZE_2K:
5483 case I40E_DMA_CNTX_SIZE_4K:
5484 case I40E_DMA_CNTX_SIZE_8K:
5485 case I40E_DMA_CNTX_SIZE_16K:
5486 case I40E_DMA_CNTX_SIZE_32K:
5487 case I40E_DMA_CNTX_SIZE_64K:
5488 case I40E_DMA_CNTX_SIZE_128K:
5489 case I40E_DMA_CNTX_SIZE_256K:
5490 break;
5491 default:
5492 return I40E_ERR_PARAM;
5493 }
5494
5495 /* FCHSIZE + FCDSIZE should not be greater than PMFCOEFMAX */
5496 val = rd32(hw, I40E_GLHMC_FCOEFMAX);
5497 fcoe_fmax = (val & I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK)
5498 >> I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT;
5499 if (fcoe_filt_size + fcoe_cntx_size > fcoe_fmax)
5500 return I40E_ERR_INVALID_SIZE;
5501
5502 return I40E_SUCCESS;
5503 }
5504
5505 /**
5506 * i40e_set_filter_control
5507 * @hw: pointer to the hardware structure
5508 * @settings: Filter control settings
5509 *
5510 * Set the Queue Filters for PE/FCoE and enable filters required
5511 * for a single PF. It is expected that these settings are programmed
5512 * at the driver initialization time.
5513 **/
5514 enum i40e_status_code i40e_set_filter_control(struct i40e_hw *hw,
5515 struct i40e_filter_control_settings *settings)
5516 {
5517 enum i40e_status_code ret = I40E_SUCCESS;
5518 u32 hash_lut_size = 0;
5519 u32 val;
5520
5521 if (!settings)
5522 return I40E_ERR_PARAM;
5523
5524 /* Validate the input settings */
5525 ret = i40e_validate_filter_settings(hw, settings);
5526 if (ret)
5527 return ret;
5528
5529 /* Read the PF Queue Filter control register */
5530 val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
5531
5532 /* Program required PE hash buckets for the PF */
5533 val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
5534 val |= ((u32)settings->pe_filt_num << I40E_PFQF_CTL_0_PEHSIZE_SHIFT) &
5535 I40E_PFQF_CTL_0_PEHSIZE_MASK;
5536 /* Program required PE contexts for the PF */
5537 val &= ~I40E_PFQF_CTL_0_PEDSIZE_MASK;
5538 val |= ((u32)settings->pe_cntx_num << I40E_PFQF_CTL_0_PEDSIZE_SHIFT) &
5539 I40E_PFQF_CTL_0_PEDSIZE_MASK;
5540
5541 /* Program required FCoE hash buckets for the PF */
5542 val &= ~I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5543 val |= ((u32)settings->fcoe_filt_num <<
5544 I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT) &
5545 I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5546 /* Program required FCoE DDP contexts for the PF */
5547 val &= ~I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5548 val |= ((u32)settings->fcoe_cntx_num <<
5549 I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT) &
5550 I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5551
5552 /* Program Hash LUT size for the PF */
5553 val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5554 if (settings->hash_lut_size == I40E_HASH_LUT_SIZE_512)
5555 hash_lut_size = 1;
5556 val |= (hash_lut_size << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT) &
5557 I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5558
5559 /* Enable FDIR, Ethertype and MACVLAN filters for PF and VFs */
5560 if (settings->enable_fdir)
5561 val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
5562 if (settings->enable_ethtype)
5563 val |= I40E_PFQF_CTL_0_ETYPE_ENA_MASK;
5564 if (settings->enable_macvlan)
5565 val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
5566
5567 i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
5568
5569 return I40E_SUCCESS;
5570 }
5571
5572 /**
5573 * i40e_aq_add_rem_control_packet_filter - Add or Remove Control Packet Filter
5574 * @hw: pointer to the hw struct
5575 * @mac_addr: MAC address to use in the filter
5576 * @ethtype: Ethertype to use in the filter
5577 * @flags: Flags that needs to be applied to the filter
5578 * @vsi_seid: seid of the control VSI
5579 * @queue: VSI queue number to send the packet to
5580 * @is_add: Add control packet filter if True else remove
5581 * @stats: Structure to hold information on control filter counts
5582 * @cmd_details: pointer to command details structure or NULL
5583 *
5584 * This command will Add or Remove control packet filter for a control VSI.
5585 * In return it will update the total number of perfect filter count in
5586 * the stats member.
5587 **/
5588 enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
5589 u8 *mac_addr, u16 ethtype, u16 flags,
5590 u16 vsi_seid, u16 queue, bool is_add,
5591 struct i40e_control_filter_stats *stats,
5592 struct i40e_asq_cmd_details *cmd_details)
5593 {
5594 struct i40e_aq_desc desc;
5595 struct i40e_aqc_add_remove_control_packet_filter *cmd =
5596 (struct i40e_aqc_add_remove_control_packet_filter *)
5597 &desc.params.raw;
5598 struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
5599 (struct i40e_aqc_add_remove_control_packet_filter_completion *)
5600 &desc.params.raw;
5601 enum i40e_status_code status;
5602
5603 if (vsi_seid == 0)
5604 return I40E_ERR_PARAM;
5605
5606 if (is_add) {
5607 i40e_fill_default_direct_cmd_desc(&desc,
5608 i40e_aqc_opc_add_control_packet_filter);
5609 cmd->queue = CPU_TO_LE16(queue);
5610 } else {
5611 i40e_fill_default_direct_cmd_desc(&desc,
5612 i40e_aqc_opc_remove_control_packet_filter);
5613 }
5614
5615 if (mac_addr)
5616 i40e_memcpy(cmd->mac, mac_addr, ETH_ALEN,
5617 I40E_NONDMA_TO_NONDMA);
5618
5619 cmd->etype = CPU_TO_LE16(ethtype);
5620 cmd->flags = CPU_TO_LE16(flags);
5621 cmd->seid = CPU_TO_LE16(vsi_seid);
5622
5623 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5624
5625 if (!status && stats) {
5626 stats->mac_etype_used = LE16_TO_CPU(resp->mac_etype_used);
5627 stats->etype_used = LE16_TO_CPU(resp->etype_used);
5628 stats->mac_etype_free = LE16_TO_CPU(resp->mac_etype_free);
5629 stats->etype_free = LE16_TO_CPU(resp->etype_free);
5630 }
5631
5632 return status;
5633 }
5634
5635 /**
5636 * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
5637 * @hw: pointer to the hw struct
5638 * @seid: VSI seid to add ethertype filter from
5639 **/
5640 void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
5641 u16 seid)
5642 {
5643 #define I40E_FLOW_CONTROL_ETHTYPE 0x8808
5644 u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
5645 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
5646 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
5647 u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
5648 enum i40e_status_code status;
5649
5650 status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
5651 seid, 0, TRUE, NULL,
5652 NULL);
5653 if (status)
5654 DEBUGOUT("Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
5655 }
5656
5657 /**
5658 * i40e_fix_up_geneve_vni - adjust Geneve VNI for HW issue
5659 * @filters: list of cloud filters
5660 * @filter_count: length of list
5661 *
5662 * There's an issue in the device where the Geneve VNI layout needs
5663 * to be shifted 1 byte over from the VxLAN VNI
5664 **/
5665 static void i40e_fix_up_geneve_vni(
5666 struct i40e_aqc_cloud_filters_element_data *filters,
5667 u8 filter_count)
5668 {
5669 struct i40e_aqc_cloud_filters_element_data *f = filters;
5670 int i;
5671
5672 for (i = 0; i < filter_count; i++) {
5673 u16 tnl_type;
5674 u32 ti;
5675
5676 tnl_type = (LE16_TO_CPU(f[i].flags) &
5677 I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5678 I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5679 if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5680 ti = LE32_TO_CPU(f[i].tenant_id);
5681 f[i].tenant_id = CPU_TO_LE32(ti << 8);
5682 }
5683 }
5684 }
5685
5686 /**
5687 * i40e_aq_add_cloud_filters
5688 * @hw: pointer to the hardware structure
5689 * @seid: VSI seid to add cloud filters from
5690 * @filters: Buffer which contains the filters to be added
5691 * @filter_count: number of filters contained in the buffer
5692 *
5693 * Set the cloud filters for a given VSI. The contents of the
5694 * i40e_aqc_cloud_filters_element_data are filled
5695 * in by the caller of the function.
5696 *
5697 **/
5698 enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
5699 u16 seid,
5700 struct i40e_aqc_cloud_filters_element_data *filters,
5701 u8 filter_count)
5702 {
5703 struct i40e_aq_desc desc;
5704 struct i40e_aqc_add_remove_cloud_filters *cmd =
5705 (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5706 enum i40e_status_code status;
5707 u16 buff_len;
5708
5709 i40e_fill_default_direct_cmd_desc(&desc,
5710 i40e_aqc_opc_add_cloud_filters);
5711
5712 buff_len = filter_count * sizeof(*filters);
5713 desc.datalen = CPU_TO_LE16(buff_len);
5714 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5715 cmd->num_filters = filter_count;
5716 cmd->seid = CPU_TO_LE16(seid);
5717
5718 i40e_fix_up_geneve_vni(filters, filter_count);
5719
5720 status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5721
5722 return status;
5723 }
5724
5725 /**
5726 * i40e_aq_add_cloud_filters_bb
5727 * @hw: pointer to the hardware structure
5728 * @seid: VSI seid to add cloud filters from
5729 * @filters: Buffer which contains the filters in big buffer to be added
5730 * @filter_count: number of filters contained in the buffer
5731 *
5732 * Set the cloud filters for a given VSI. The contents of the
5733 * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5734 * the function.
5735 *
5736 **/
5737 enum i40e_status_code
5738 i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5739 struct i40e_aqc_cloud_filters_element_bb *filters,
5740 u8 filter_count)
5741 {
5742 struct i40e_aq_desc desc;
5743 struct i40e_aqc_add_remove_cloud_filters *cmd =
5744 (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5745 enum i40e_status_code status;
5746 u16 buff_len;
5747 int i;
5748
5749 i40e_fill_default_direct_cmd_desc(&desc,
5750 i40e_aqc_opc_add_cloud_filters);
5751
5752 buff_len = filter_count * sizeof(*filters);
5753 desc.datalen = CPU_TO_LE16(buff_len);
5754 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5755 cmd->num_filters = filter_count;
5756 cmd->seid = CPU_TO_LE16(seid);
5757 cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5758
5759 for (i = 0; i < filter_count; i++) {
5760 u16 tnl_type;
5761 u32 ti;
5762
5763 tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5764 I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5765 I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5766
5767 /* Due to hardware eccentricities, the VNI for Geneve is shifted
5768 * one more byte further than normally used for Tenant ID in
5769 * other tunnel types.
5770 */
5771 if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5772 ti = LE32_TO_CPU(filters[i].element.tenant_id);
5773 filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5774 }
5775 }
5776
5777 status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5778
5779 return status;
5780 }
5781
5782 /**
5783 * i40e_aq_rem_cloud_filters
5784 * @hw: pointer to the hardware structure
5785 * @seid: VSI seid to remove cloud filters from
5786 * @filters: Buffer which contains the filters to be removed
5787 * @filter_count: number of filters contained in the buffer
5788 *
5789 * Remove the cloud filters for a given VSI. The contents of the
5790 * i40e_aqc_cloud_filters_element_data are filled in by the caller
5791 * of the function.
5792 *
5793 **/
5794 enum i40e_status_code
5795 i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
5796 struct i40e_aqc_cloud_filters_element_data *filters,
5797 u8 filter_count)
5798 {
5799 struct i40e_aq_desc desc;
5800 struct i40e_aqc_add_remove_cloud_filters *cmd =
5801 (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5802 enum i40e_status_code status;
5803 u16 buff_len;
5804
5805 i40e_fill_default_direct_cmd_desc(&desc,
5806 i40e_aqc_opc_remove_cloud_filters);
5807
5808 buff_len = filter_count * sizeof(*filters);
5809 desc.datalen = CPU_TO_LE16(buff_len);
5810 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5811 cmd->num_filters = filter_count;
5812 cmd->seid = CPU_TO_LE16(seid);
5813
5814 i40e_fix_up_geneve_vni(filters, filter_count);
5815
5816 status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5817
5818 return status;
5819 }
5820
5821 /**
5822 * i40e_aq_rem_cloud_filters_bb
5823 * @hw: pointer to the hardware structure
5824 * @seid: VSI seid to remove cloud filters from
5825 * @filters: Buffer which contains the filters in big buffer to be removed
5826 * @filter_count: number of filters contained in the buffer
5827 *
5828 * Remove the big buffer cloud filters for a given VSI. The contents of the
5829 * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5830 * function.
5831 *
5832 **/
5833 enum i40e_status_code
5834 i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5835 struct i40e_aqc_cloud_filters_element_bb *filters,
5836 u8 filter_count)
5837 {
5838 struct i40e_aq_desc desc;
5839 struct i40e_aqc_add_remove_cloud_filters *cmd =
5840 (struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5841 enum i40e_status_code status;
5842 u16 buff_len;
5843 int i;
5844
5845 i40e_fill_default_direct_cmd_desc(&desc,
5846 i40e_aqc_opc_remove_cloud_filters);
5847
5848 buff_len = filter_count * sizeof(*filters);
5849 desc.datalen = CPU_TO_LE16(buff_len);
5850 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5851 cmd->num_filters = filter_count;
5852 cmd->seid = CPU_TO_LE16(seid);
5853 cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5854
5855 for (i = 0; i < filter_count; i++) {
5856 u16 tnl_type;
5857 u32 ti;
5858
5859 tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5860 I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5861 I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5862
5863 /* Due to hardware eccentricities, the VNI for Geneve is shifted
5864 * one more byte further than normally used for Tenant ID in
5865 * other tunnel types.
5866 */
5867 if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5868 ti = LE32_TO_CPU(filters[i].element.tenant_id);
5869 filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5870 }
5871 }
5872
5873 status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5874
5875 return status;
5876 }
5877
5878 /**
5879 * i40e_aq_replace_cloud_filters - Replace cloud filter command
5880 * @hw: pointer to the hw struct
5881 * @filters: pointer to the i40e_aqc_replace_cloud_filter_cmd struct
5882 * @cmd_buf: pointer to the i40e_aqc_replace_cloud_filter_cmd_buf struct
5883 *
5884 **/
5885 enum
5886 i40e_status_code i40e_aq_replace_cloud_filters(struct i40e_hw *hw,
5887 struct i40e_aqc_replace_cloud_filters_cmd *filters,
5888 struct i40e_aqc_replace_cloud_filters_cmd_buf *cmd_buf)
5889 {
5890 struct i40e_aq_desc desc;
5891 struct i40e_aqc_replace_cloud_filters_cmd *cmd =
5892 (struct i40e_aqc_replace_cloud_filters_cmd *)&desc.params.raw;
5893 enum i40e_status_code status = I40E_SUCCESS;
5894 int i = 0;
5895
5896 /* X722 doesn't support this command */
5897 if (hw->mac.type == I40E_MAC_X722)
5898 return I40E_ERR_DEVICE_NOT_SUPPORTED;
5899
5900 /* need FW version greater than 6.00 */
5901 if (hw->aq.fw_maj_ver < 6)
5902 return I40E_NOT_SUPPORTED;
5903
5904 i40e_fill_default_direct_cmd_desc(&desc,
5905 i40e_aqc_opc_replace_cloud_filters);
5906
5907 desc.datalen = CPU_TO_LE16(32);
5908 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5909 cmd->old_filter_type = filters->old_filter_type;
5910 cmd->new_filter_type = filters->new_filter_type;
5911 cmd->valid_flags = filters->valid_flags;
5912 cmd->tr_bit = filters->tr_bit;
5913 cmd->tr_bit2 = filters->tr_bit2;
5914
5915 status = i40e_asq_send_command(hw, &desc, cmd_buf,
5916 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf), NULL);
5917
5918 /* for get cloud filters command */
5919 for (i = 0; i < 32; i += 4) {
5920 cmd_buf->filters[i / 4].filter_type = cmd_buf->data[i];
5921 cmd_buf->filters[i / 4].input[0] = cmd_buf->data[i + 1];
5922 cmd_buf->filters[i / 4].input[1] = cmd_buf->data[i + 2];
5923 cmd_buf->filters[i / 4].input[2] = cmd_buf->data[i + 3];
5924 }
5925
5926 return status;
5927 }
5928
5929
5930 /**
5931 * i40e_aq_alternate_write
5932 * @hw: pointer to the hardware structure
5933 * @reg_addr0: address of first dword to be read
5934 * @reg_val0: value to be written under 'reg_addr0'
5935 * @reg_addr1: address of second dword to be read
5936 * @reg_val1: value to be written under 'reg_addr1'
5937 *
5938 * Write one or two dwords to alternate structure. Fields are indicated
5939 * by 'reg_addr0' and 'reg_addr1' register numbers.
5940 *
5941 **/
5942 enum i40e_status_code i40e_aq_alternate_write(struct i40e_hw *hw,
5943 u32 reg_addr0, u32 reg_val0,
5944 u32 reg_addr1, u32 reg_val1)
5945 {
5946 struct i40e_aq_desc desc;
5947 struct i40e_aqc_alternate_write *cmd_resp =
5948 (struct i40e_aqc_alternate_write *)&desc.params.raw;
5949 enum i40e_status_code status;
5950
5951 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_write);
5952 cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
5953 cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
5954 cmd_resp->data0 = CPU_TO_LE32(reg_val0);
5955 cmd_resp->data1 = CPU_TO_LE32(reg_val1);
5956
5957 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5958
5959 return status;
5960 }
5961
5962 /**
5963 * i40e_aq_alternate_write_indirect
5964 * @hw: pointer to the hardware structure
5965 * @addr: address of a first register to be modified
5966 * @dw_count: number of alternate structure fields to write
5967 * @buffer: pointer to the command buffer
5968 *
5969 * Write 'dw_count' dwords from 'buffer' to alternate structure
5970 * starting at 'addr'.
5971 *
5972 **/
5973 enum i40e_status_code i40e_aq_alternate_write_indirect(struct i40e_hw *hw,
5974 u32 addr, u32 dw_count, void *buffer)
5975 {
5976 struct i40e_aq_desc desc;
5977 struct i40e_aqc_alternate_ind_write *cmd_resp =
5978 (struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
5979 enum i40e_status_code status;
5980
5981 if (buffer == NULL)
5982 return I40E_ERR_PARAM;
5983
5984 /* Indirect command */
5985 i40e_fill_default_direct_cmd_desc(&desc,
5986 i40e_aqc_opc_alternate_write_indirect);
5987
5988 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
5989 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
5990 if (dw_count > (I40E_AQ_LARGE_BUF/4))
5991 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5992
5993 cmd_resp->address = CPU_TO_LE32(addr);
5994 cmd_resp->length = CPU_TO_LE32(dw_count);
5995
5996 status = i40e_asq_send_command(hw, &desc, buffer,
5997 I40E_LO_DWORD(4*dw_count), NULL);
5998
5999 return status;
6000 }
6001
6002 /**
6003 * i40e_aq_alternate_read
6004 * @hw: pointer to the hardware structure
6005 * @reg_addr0: address of first dword to be read
6006 * @reg_val0: pointer for data read from 'reg_addr0'
6007 * @reg_addr1: address of second dword to be read
6008 * @reg_val1: pointer for data read from 'reg_addr1'
6009 *
6010 * Read one or two dwords from alternate structure. Fields are indicated
6011 * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
6012 * is not passed then only register at 'reg_addr0' is read.
6013 *
6014 **/
6015 enum i40e_status_code i40e_aq_alternate_read(struct i40e_hw *hw,
6016 u32 reg_addr0, u32 *reg_val0,
6017 u32 reg_addr1, u32 *reg_val1)
6018 {
6019 struct i40e_aq_desc desc;
6020 struct i40e_aqc_alternate_write *cmd_resp =
6021 (struct i40e_aqc_alternate_write *)&desc.params.raw;
6022 enum i40e_status_code status;
6023
6024 if (reg_val0 == NULL)
6025 return I40E_ERR_PARAM;
6026
6027 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
6028 cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
6029 cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
6030
6031 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6032
6033 if (status == I40E_SUCCESS) {
6034 *reg_val0 = LE32_TO_CPU(cmd_resp->data0);
6035
6036 if (reg_val1 != NULL)
6037 *reg_val1 = LE32_TO_CPU(cmd_resp->data1);
6038 }
6039
6040 return status;
6041 }
6042
6043 /**
6044 * i40e_aq_alternate_read_indirect
6045 * @hw: pointer to the hardware structure
6046 * @addr: address of the alternate structure field
6047 * @dw_count: number of alternate structure fields to read
6048 * @buffer: pointer to the command buffer
6049 *
6050 * Read 'dw_count' dwords from alternate structure starting at 'addr' and
6051 * place them in 'buffer'. The buffer should be allocated by caller.
6052 *
6053 **/
6054 enum i40e_status_code i40e_aq_alternate_read_indirect(struct i40e_hw *hw,
6055 u32 addr, u32 dw_count, void *buffer)
6056 {
6057 struct i40e_aq_desc desc;
6058 struct i40e_aqc_alternate_ind_write *cmd_resp =
6059 (struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
6060 enum i40e_status_code status;
6061
6062 if (buffer == NULL)
6063 return I40E_ERR_PARAM;
6064
6065 /* Indirect command */
6066 i40e_fill_default_direct_cmd_desc(&desc,
6067 i40e_aqc_opc_alternate_read_indirect);
6068
6069 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
6070 desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
6071 if (dw_count > (I40E_AQ_LARGE_BUF/4))
6072 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6073
6074 cmd_resp->address = CPU_TO_LE32(addr);
6075 cmd_resp->length = CPU_TO_LE32(dw_count);
6076
6077 status = i40e_asq_send_command(hw, &desc, buffer,
6078 I40E_LO_DWORD(4*dw_count), NULL);
6079
6080 return status;
6081 }
6082
6083 /**
6084 * i40e_aq_alternate_clear
6085 * @hw: pointer to the HW structure.
6086 *
6087 * Clear the alternate structures of the port from which the function
6088 * is called.
6089 *
6090 **/
6091 enum i40e_status_code i40e_aq_alternate_clear(struct i40e_hw *hw)
6092 {
6093 struct i40e_aq_desc desc;
6094 enum i40e_status_code status;
6095
6096 i40e_fill_default_direct_cmd_desc(&desc,
6097 i40e_aqc_opc_alternate_clear_port);
6098
6099 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6100
6101 return status;
6102 }
6103
6104 /**
6105 * i40e_aq_alternate_write_done
6106 * @hw: pointer to the HW structure.
6107 * @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS
6108 * @reset_needed: indicates the SW should trigger GLOBAL reset
6109 *
6110 * Indicates to the FW that alternate structures have been changed.
6111 *
6112 **/
6113 enum i40e_status_code i40e_aq_alternate_write_done(struct i40e_hw *hw,
6114 u8 bios_mode, bool *reset_needed)
6115 {
6116 struct i40e_aq_desc desc;
6117 struct i40e_aqc_alternate_write_done *cmd =
6118 (struct i40e_aqc_alternate_write_done *)&desc.params.raw;
6119 enum i40e_status_code status;
6120
6121 if (reset_needed == NULL)
6122 return I40E_ERR_PARAM;
6123
6124 i40e_fill_default_direct_cmd_desc(&desc,
6125 i40e_aqc_opc_alternate_write_done);
6126
6127 cmd->cmd_flags = CPU_TO_LE16(bios_mode);
6128
6129 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6130 if (!status && reset_needed)
6131 *reset_needed = ((LE16_TO_CPU(cmd->cmd_flags) &
6132 I40E_AQ_ALTERNATE_RESET_NEEDED) != 0);
6133
6134 return status;
6135 }
6136
6137 /**
6138 * i40e_aq_set_oem_mode
6139 * @hw: pointer to the HW structure.
6140 * @oem_mode: the OEM mode to be used
6141 *
6142 * Sets the device to a specific operating mode. Currently the only supported
6143 * mode is no_clp, which causes FW to refrain from using Alternate RAM.
6144 *
6145 **/
6146 enum i40e_status_code i40e_aq_set_oem_mode(struct i40e_hw *hw,
6147 u8 oem_mode)
6148 {
6149 struct i40e_aq_desc desc;
6150 struct i40e_aqc_alternate_write_done *cmd =
6151 (struct i40e_aqc_alternate_write_done *)&desc.params.raw;
6152 enum i40e_status_code status;
6153
6154 i40e_fill_default_direct_cmd_desc(&desc,
6155 i40e_aqc_opc_alternate_set_mode);
6156
6157 cmd->cmd_flags = CPU_TO_LE16(oem_mode);
6158
6159 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6160
6161 return status;
6162 }
6163
6164 /**
6165 * i40e_aq_resume_port_tx
6166 * @hw: pointer to the hardware structure
6167 * @cmd_details: pointer to command details structure or NULL
6168 *
6169 * Resume port's Tx traffic
6170 **/
6171 enum i40e_status_code i40e_aq_resume_port_tx(struct i40e_hw *hw,
6172 struct i40e_asq_cmd_details *cmd_details)
6173 {
6174 struct i40e_aq_desc desc;
6175 enum i40e_status_code status;
6176
6177 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
6178
6179 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
6180
6181 return status;
6182 }
6183
6184 /**
6185 * i40e_set_pci_config_data - store PCI bus info
6186 * @hw: pointer to hardware structure
6187 * @link_status: the link status word from PCI config space
6188 *
6189 * Stores the PCI bus info (speed, width, type) within the i40e_hw structure
6190 **/
6191 void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
6192 {
6193 hw->bus.type = i40e_bus_type_pci_express;
6194
6195 switch (link_status & I40E_PCI_LINK_WIDTH) {
6196 case I40E_PCI_LINK_WIDTH_1:
6197 hw->bus.width = i40e_bus_width_pcie_x1;
6198 break;
6199 case I40E_PCI_LINK_WIDTH_2:
6200 hw->bus.width = i40e_bus_width_pcie_x2;
6201 break;
6202 case I40E_PCI_LINK_WIDTH_4:
6203 hw->bus.width = i40e_bus_width_pcie_x4;
6204 break;
6205 case I40E_PCI_LINK_WIDTH_8:
6206 hw->bus.width = i40e_bus_width_pcie_x8;
6207 break;
6208 default:
6209 hw->bus.width = i40e_bus_width_unknown;
6210 break;
6211 }
6212
6213 switch (link_status & I40E_PCI_LINK_SPEED) {
6214 case I40E_PCI_LINK_SPEED_2500:
6215 hw->bus.speed = i40e_bus_speed_2500;
6216 break;
6217 case I40E_PCI_LINK_SPEED_5000:
6218 hw->bus.speed = i40e_bus_speed_5000;
6219 break;
6220 case I40E_PCI_LINK_SPEED_8000:
6221 hw->bus.speed = i40e_bus_speed_8000;
6222 break;
6223 default:
6224 hw->bus.speed = i40e_bus_speed_unknown;
6225 break;
6226 }
6227 }
6228
6229 /**
6230 * i40e_aq_debug_dump
6231 * @hw: pointer to the hardware structure
6232 * @cluster_id: specific cluster to dump
6233 * @table_id: table id within cluster
6234 * @start_index: index of line in the block to read
6235 * @buff_size: dump buffer size
6236 * @buff: dump buffer
6237 * @ret_buff_size: actual buffer size returned
6238 * @ret_next_table: next block to read
6239 * @ret_next_index: next index to read
6240 * @cmd_details: pointer to command details structure or NULL
6241 *
6242 * Dump internal FW/HW data for debug purposes.
6243 *
6244 **/
6245 enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
6246 u8 table_id, u32 start_index, u16 buff_size,
6247 void *buff, u16 *ret_buff_size,
6248 u8 *ret_next_table, u32 *ret_next_index,
6249 struct i40e_asq_cmd_details *cmd_details)
6250 {
6251 struct i40e_aq_desc desc;
6252 struct i40e_aqc_debug_dump_internals *cmd =
6253 (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6254 struct i40e_aqc_debug_dump_internals *resp =
6255 (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6256 enum i40e_status_code status;
6257
6258 if (buff_size == 0 || !buff)
6259 return I40E_ERR_PARAM;
6260
6261 i40e_fill_default_direct_cmd_desc(&desc,
6262 i40e_aqc_opc_debug_dump_internals);
6263 /* Indirect Command */
6264 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6265 if (buff_size > I40E_AQ_LARGE_BUF)
6266 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6267
6268 cmd->cluster_id = cluster_id;
6269 cmd->table_id = table_id;
6270 cmd->idx = CPU_TO_LE32(start_index);
6271
6272 desc.datalen = CPU_TO_LE16(buff_size);
6273
6274 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
6275 if (!status) {
6276 if (ret_buff_size != NULL)
6277 *ret_buff_size = LE16_TO_CPU(desc.datalen);
6278 if (ret_next_table != NULL)
6279 *ret_next_table = resp->table_id;
6280 if (ret_next_index != NULL)
6281 *ret_next_index = LE32_TO_CPU(resp->idx);
6282 }
6283
6284 return status;
6285 }
6286
6287
6288 /**
6289 * i40e_enable_eee
6290 * @hw: pointer to the hardware structure
6291 * @enable: state of Energy Efficient Ethernet mode to be set
6292 *
6293 * Enables or disables Energy Efficient Ethernet (EEE) mode
6294 * accordingly to @enable parameter.
6295 **/
6296 enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable)
6297 {
6298 struct i40e_aq_get_phy_abilities_resp abilities;
6299 struct i40e_aq_set_phy_config config;
6300 enum i40e_status_code status;
6301 __le16 eee_capability;
6302
6303 /* Get initial PHY capabilities */
6304 status = i40e_aq_get_phy_capabilities(hw, FALSE, TRUE, &abilities,
6305 NULL);
6306 if (status)
6307 goto err;
6308
6309 /* Check whether NIC configuration is compatible with Energy Efficient
6310 * Ethernet (EEE) mode.
6311 */
6312 if (abilities.eee_capability == 0) {
6313 status = I40E_ERR_CONFIG;
6314 goto err;
6315 }
6316
6317 /* Cache initial EEE capability */
6318 eee_capability = abilities.eee_capability;
6319
6320 /* Get current configuration */
6321 status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
6322 NULL);
6323 if (status)
6324 goto err;
6325
6326 /* Cache current configuration */
6327 config.phy_type = abilities.phy_type;
6328 config.phy_type_ext = abilities.phy_type_ext;
6329 config.link_speed = abilities.link_speed;
6330 config.abilities = abilities.abilities |
6331 I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
6332 config.eeer = abilities.eeer_val;
6333 config.low_power_ctrl = abilities.d3_lpan;
6334 config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
6335 I40E_AQ_PHY_FEC_CONFIG_MASK;
6336
6337 /* Set desired EEE state */
6338 if (enable) {
6339 config.eee_capability = eee_capability;
6340 config.eeer |= I40E_PRTPM_EEER_TX_LPI_EN_MASK;
6341 } else {
6342 config.eee_capability = 0;
6343 config.eeer &= ~I40E_PRTPM_EEER_TX_LPI_EN_MASK;
6344 }
6345
6346 /* Save modified config */
6347 status = i40e_aq_set_phy_config(hw, &config, NULL);
6348 err:
6349 return status;
6350 }
6351
6352 /**
6353 * i40e_read_bw_from_alt_ram
6354 * @hw: pointer to the hardware structure
6355 * @max_bw: pointer for max_bw read
6356 * @min_bw: pointer for min_bw read
6357 * @min_valid: pointer for bool that is TRUE if min_bw is a valid value
6358 * @max_valid: pointer for bool that is TRUE if max_bw is a valid value
6359 *
6360 * Read bw from the alternate ram for the given pf
6361 **/
6362 enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
6363 u32 *max_bw, u32 *min_bw,
6364 bool *min_valid, bool *max_valid)
6365 {
6366 enum i40e_status_code status;
6367 u32 max_bw_addr, min_bw_addr;
6368
6369 /* Calculate the address of the min/max bw registers */
6370 max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
6371 I40E_ALT_STRUCT_MAX_BW_OFFSET +
6372 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
6373 min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
6374 I40E_ALT_STRUCT_MIN_BW_OFFSET +
6375 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
6376
6377 /* Read the bandwidths from alt ram */
6378 status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
6379 min_bw_addr, min_bw);
6380
6381 if (*min_bw & I40E_ALT_BW_VALID_MASK)
6382 *min_valid = TRUE;
6383 else
6384 *min_valid = FALSE;
6385
6386 if (*max_bw & I40E_ALT_BW_VALID_MASK)
6387 *max_valid = TRUE;
6388 else
6389 *max_valid = FALSE;
6390
6391 return status;
6392 }
6393
6394 /**
6395 * i40e_aq_configure_partition_bw
6396 * @hw: pointer to the hardware structure
6397 * @bw_data: Buffer holding valid pfs and bw limits
6398 * @cmd_details: pointer to command details
6399 *
6400 * Configure partitions guaranteed/max bw
6401 **/
6402 enum i40e_status_code i40e_aq_configure_partition_bw(struct i40e_hw *hw,
6403 struct i40e_aqc_configure_partition_bw_data *bw_data,
6404 struct i40e_asq_cmd_details *cmd_details)
6405 {
6406 enum i40e_status_code status;
6407 struct i40e_aq_desc desc;
6408 u16 bwd_size = sizeof(*bw_data);
6409
6410 i40e_fill_default_direct_cmd_desc(&desc,
6411 i40e_aqc_opc_configure_partition_bw);
6412
6413 /* Indirect command */
6414 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6415 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
6416
6417 desc.datalen = CPU_TO_LE16(bwd_size);
6418
6419 status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size, cmd_details);
6420
6421 return status;
6422 }
6423
6424 /**
6425 * i40e_read_phy_register_clause22
6426 * @hw: pointer to the HW structure
6427 * @reg: register address in the page
6428 * @phy_addr: PHY address on MDIO interface
6429 * @value: PHY register value
6430 *
6431 * Reads specified PHY register value
6432 **/
6433 enum i40e_status_code i40e_read_phy_register_clause22(struct i40e_hw *hw,
6434 u16 reg, u8 phy_addr, u16 *value)
6435 {
6436 enum i40e_status_code status = I40E_ERR_TIMEOUT;
6437 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6438 u32 command = 0;
6439 u16 retry = 1000;
6440
6441 command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6442 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6443 (I40E_MDIO_CLAUSE22_OPCODE_READ_MASK) |
6444 (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6445 (I40E_GLGEN_MSCA_MDICMD_MASK);
6446 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6447 do {
6448 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6449 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6450 status = I40E_SUCCESS;
6451 break;
6452 }
6453 i40e_usec_delay(10);
6454 retry--;
6455 } while (retry);
6456
6457 if (status) {
6458 i40e_debug(hw, I40E_DEBUG_PHY,
6459 "PHY: Can't write command to external PHY.\n");
6460 } else {
6461 command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6462 *value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6463 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6464 }
6465
6466 return status;
6467 }
6468
6469 /**
6470 * i40e_write_phy_register_clause22
6471 * @hw: pointer to the HW structure
6472 * @reg: register address in the page
6473 * @phy_addr: PHY address on MDIO interface
6474 * @value: PHY register value
6475 *
6476 * Writes specified PHY register value
6477 **/
6478 enum i40e_status_code i40e_write_phy_register_clause22(struct i40e_hw *hw,
6479 u16 reg, u8 phy_addr, u16 value)
6480 {
6481 enum i40e_status_code status = I40E_ERR_TIMEOUT;
6482 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6483 u32 command = 0;
6484 u16 retry = 1000;
6485
6486 command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6487 wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6488
6489 command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6490 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6491 (I40E_MDIO_CLAUSE22_OPCODE_WRITE_MASK) |
6492 (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6493 (I40E_GLGEN_MSCA_MDICMD_MASK);
6494
6495 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6496 do {
6497 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6498 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6499 status = I40E_SUCCESS;
6500 break;
6501 }
6502 i40e_usec_delay(10);
6503 retry--;
6504 } while (retry);
6505
6506 return status;
6507 }
6508
6509 /**
6510 * i40e_read_phy_register_clause45
6511 * @hw: pointer to the HW structure
6512 * @page: registers page number
6513 * @reg: register address in the page
6514 * @phy_addr: PHY address on MDIO interface
6515 * @value: PHY register value
6516 *
6517 * Reads specified PHY register value
6518 **/
6519 enum i40e_status_code i40e_read_phy_register_clause45(struct i40e_hw *hw,
6520 u8 page, u16 reg, u8 phy_addr, u16 *value)
6521 {
6522 enum i40e_status_code status = I40E_ERR_TIMEOUT;
6523 u32 command = 0;
6524 u16 retry = 1000;
6525 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6526
6527 command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6528 (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6529 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6530 (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6531 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6532 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6533 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6534 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6535 do {
6536 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6537 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6538 status = I40E_SUCCESS;
6539 break;
6540 }
6541 i40e_usec_delay(10);
6542 retry--;
6543 } while (retry);
6544
6545 if (status) {
6546 i40e_debug(hw, I40E_DEBUG_PHY,
6547 "PHY: Can't write command to external PHY.\n");
6548 goto phy_read_end;
6549 }
6550
6551 command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6552 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6553 (I40E_MDIO_CLAUSE45_OPCODE_READ_MASK) |
6554 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6555 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6556 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6557 status = I40E_ERR_TIMEOUT;
6558 retry = 1000;
6559 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6560 do {
6561 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6562 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6563 status = I40E_SUCCESS;
6564 break;
6565 }
6566 i40e_usec_delay(10);
6567 retry--;
6568 } while (retry);
6569
6570 if (!status) {
6571 command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6572 *value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6573 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6574 } else {
6575 i40e_debug(hw, I40E_DEBUG_PHY,
6576 "PHY: Can't read register value from external PHY.\n");
6577 }
6578
6579 phy_read_end:
6580 return status;
6581 }
6582
6583 /**
6584 * i40e_write_phy_register_clause45
6585 * @hw: pointer to the HW structure
6586 * @page: registers page number
6587 * @reg: register address in the page
6588 * @phy_addr: PHY address on MDIO interface
6589 * @value: PHY register value
6590 *
6591 * Writes value to specified PHY register
6592 **/
6593 enum i40e_status_code i40e_write_phy_register_clause45(struct i40e_hw *hw,
6594 u8 page, u16 reg, u8 phy_addr, u16 value)
6595 {
6596 enum i40e_status_code status = I40E_ERR_TIMEOUT;
6597 u32 command = 0;
6598 u16 retry = 1000;
6599 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6600
6601 command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6602 (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6603 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6604 (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6605 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6606 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6607 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6608 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6609 do {
6610 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6611 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6612 status = I40E_SUCCESS;
6613 break;
6614 }
6615 i40e_usec_delay(10);
6616 retry--;
6617 } while (retry);
6618 if (status) {
6619 i40e_debug(hw, I40E_DEBUG_PHY,
6620 "PHY: Can't write command to external PHY.\n");
6621 goto phy_write_end;
6622 }
6623
6624 command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6625 wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6626
6627 command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6628 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6629 (I40E_MDIO_CLAUSE45_OPCODE_WRITE_MASK) |
6630 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6631 (I40E_GLGEN_MSCA_MDICMD_MASK) |
6632 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6633 status = I40E_ERR_TIMEOUT;
6634 retry = 1000;
6635 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6636 do {
6637 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6638 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6639 status = I40E_SUCCESS;
6640 break;
6641 }
6642 i40e_usec_delay(10);
6643 retry--;
6644 } while (retry);
6645
6646 phy_write_end:
6647 return status;
6648 }
6649
6650 /**
6651 * i40e_write_phy_register
6652 * @hw: pointer to the HW structure
6653 * @page: registers page number
6654 * @reg: register address in the page
6655 * @phy_addr: PHY address on MDIO interface
6656 * @value: PHY register value
6657 *
6658 * Writes value to specified PHY register
6659 **/
6660 enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
6661 u8 page, u16 reg, u8 phy_addr, u16 value)
6662 {
6663 enum i40e_status_code status;
6664
6665 switch (hw->device_id) {
6666 case I40E_DEV_ID_1G_BASE_T_X722:
6667 status = i40e_write_phy_register_clause22(hw,
6668 reg, phy_addr, value);
6669 break;
6670 case I40E_DEV_ID_10G_BASE_T:
6671 case I40E_DEV_ID_10G_BASE_T4:
6672 case I40E_DEV_ID_10G_BASE_T_BC:
6673 case I40E_DEV_ID_5G_BASE_T_BC:
6674 case I40E_DEV_ID_1G_BASE_T_BC:
6675 case I40E_DEV_ID_10G_BASE_T_X722:
6676 case I40E_DEV_ID_25G_B:
6677 case I40E_DEV_ID_25G_SFP28:
6678 status = i40e_write_phy_register_clause45(hw,
6679 page, reg, phy_addr, value);
6680 break;
6681 default:
6682 status = I40E_ERR_UNKNOWN_PHY;
6683 break;
6684 }
6685
6686 return status;
6687 }
6688
6689 /**
6690 * i40e_read_phy_register
6691 * @hw: pointer to the HW structure
6692 * @page: registers page number
6693 * @reg: register address in the page
6694 * @phy_addr: PHY address on MDIO interface
6695 * @value: PHY register value
6696 *
6697 * Reads specified PHY register value
6698 **/
6699 enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
6700 u8 page, u16 reg, u8 phy_addr, u16 *value)
6701 {
6702 enum i40e_status_code status;
6703
6704 switch (hw->device_id) {
6705 case I40E_DEV_ID_1G_BASE_T_X722:
6706 status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
6707 value);
6708 break;
6709 case I40E_DEV_ID_10G_BASE_T:
6710 case I40E_DEV_ID_10G_BASE_T4:
6711 case I40E_DEV_ID_10G_BASE_T_BC:
6712 case I40E_DEV_ID_5G_BASE_T_BC:
6713 case I40E_DEV_ID_1G_BASE_T_BC:
6714 case I40E_DEV_ID_10G_BASE_T_X722:
6715 case I40E_DEV_ID_25G_B:
6716 case I40E_DEV_ID_25G_SFP28:
6717 status = i40e_read_phy_register_clause45(hw, page, reg,
6718 phy_addr, value);
6719 break;
6720 default:
6721 status = I40E_ERR_UNKNOWN_PHY;
6722 break;
6723 }
6724
6725 return status;
6726 }
6727
6728 /**
6729 * i40e_get_phy_address
6730 * @hw: pointer to the HW structure
6731 * @dev_num: PHY port num that address we want
6732 *
6733 * Gets PHY address for current port
6734 **/
6735 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
6736 {
6737 u8 port_num = (u8)hw->func_caps.mdio_port_num;
6738 u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
6739
6740 return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
6741 }
6742
6743 /**
6744 * i40e_blink_phy_link_led
6745 * @hw: pointer to the HW structure
6746 * @time: time how long led will blinks in secs
6747 * @interval: gap between LED on and off in msecs
6748 *
6749 * Blinks PHY link LED
6750 **/
6751 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
6752 u32 time, u32 interval)
6753 {
6754 enum i40e_status_code status = I40E_SUCCESS;
6755 u32 i;
6756 u16 led_ctl = 0;
6757 u16 gpio_led_port;
6758 u16 led_reg;
6759 u16 led_addr = I40E_PHY_LED_PROV_REG_1;
6760 u8 phy_addr = 0;
6761 u8 port_num;
6762
6763 i = rd32(hw, I40E_PFGEN_PORTNUM);
6764 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
6765 phy_addr = i40e_get_phy_address(hw, port_num);
6766
6767 for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6768 led_addr++) {
6769 status = i40e_read_phy_register_clause45(hw,
6770 I40E_PHY_COM_REG_PAGE,
6771 led_addr, phy_addr,
6772 &led_reg);
6773 if (status)
6774 goto phy_blinking_end;
6775 led_ctl = led_reg;
6776 if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6777 led_reg = 0;
6778 status = i40e_write_phy_register_clause45(hw,
6779 I40E_PHY_COM_REG_PAGE,
6780 led_addr, phy_addr,
6781 led_reg);
6782 if (status)
6783 goto phy_blinking_end;
6784 break;
6785 }
6786 }
6787
6788 if (time > 0 && interval > 0) {
6789 for (i = 0; i < time * 1000; i += interval) {
6790 status = i40e_read_phy_register_clause45(hw,
6791 I40E_PHY_COM_REG_PAGE,
6792 led_addr, phy_addr, &led_reg);
6793 if (status)
6794 goto restore_config;
6795 if (led_reg & I40E_PHY_LED_MANUAL_ON)
6796 led_reg = 0;
6797 else
6798 led_reg = I40E_PHY_LED_MANUAL_ON;
6799 status = i40e_write_phy_register_clause45(hw,
6800 I40E_PHY_COM_REG_PAGE,
6801 led_addr, phy_addr, led_reg);
6802 if (status)
6803 goto restore_config;
6804 i40e_msec_delay(interval);
6805 }
6806 }
6807
6808 restore_config:
6809 status = i40e_write_phy_register_clause45(hw,
6810 I40E_PHY_COM_REG_PAGE,
6811 led_addr, phy_addr, led_ctl);
6812
6813 phy_blinking_end:
6814 return status;
6815 }
6816
6817 /**
6818 * i40e_led_get_reg - read LED register
6819 * @hw: pointer to the HW structure
6820 * @led_addr: LED register address
6821 * @reg_val: read register value
6822 **/
6823 enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
6824 u32 *reg_val)
6825 {
6826 enum i40e_status_code status;
6827 u8 phy_addr = 0;
6828
6829 *reg_val = 0;
6830 if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6831 status = i40e_aq_get_phy_register(hw,
6832 I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6833 I40E_PHY_COM_REG_PAGE, TRUE,
6834 I40E_PHY_LED_PROV_REG_1,
6835 reg_val, NULL);
6836 } else {
6837 phy_addr = i40e_get_phy_address(hw, hw->port);
6838 status = i40e_read_phy_register_clause45(hw,
6839 I40E_PHY_COM_REG_PAGE,
6840 led_addr, phy_addr,
6841 (u16 *)reg_val);
6842 }
6843 return status;
6844 }
6845
6846 /**
6847 * i40e_led_set_reg - write LED register
6848 * @hw: pointer to the HW structure
6849 * @led_addr: LED register address
6850 * @reg_val: register value to write
6851 **/
6852 enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
6853 u32 reg_val)
6854 {
6855 enum i40e_status_code status;
6856 u8 phy_addr = 0;
6857
6858 if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6859 status = i40e_aq_set_phy_register(hw,
6860 I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6861 I40E_PHY_COM_REG_PAGE, TRUE,
6862 I40E_PHY_LED_PROV_REG_1,
6863 reg_val, NULL);
6864 } else {
6865 phy_addr = i40e_get_phy_address(hw, hw->port);
6866 status = i40e_write_phy_register_clause45(hw,
6867 I40E_PHY_COM_REG_PAGE,
6868 led_addr, phy_addr,
6869 (u16)reg_val);
6870 }
6871
6872 return status;
6873 }
6874
6875 /**
6876 * i40e_led_get_phy - return current on/off mode
6877 * @hw: pointer to the hw struct
6878 * @led_addr: address of led register to use
6879 * @val: original value of register to use
6880 *
6881 **/
6882 enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
6883 u16 *val)
6884 {
6885 enum i40e_status_code status = I40E_SUCCESS;
6886 u16 gpio_led_port;
6887 u32 reg_val_aq;
6888 u16 temp_addr;
6889 u8 phy_addr = 0;
6890 u16 reg_val;
6891
6892 if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6893 status = i40e_aq_get_phy_register(hw,
6894 I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6895 I40E_PHY_COM_REG_PAGE, TRUE,
6896 I40E_PHY_LED_PROV_REG_1,
6897 ®_val_aq, NULL);
6898 if (status == I40E_SUCCESS)
6899 *val = (u16)reg_val_aq;
6900 return status;
6901 }
6902 temp_addr = I40E_PHY_LED_PROV_REG_1;
6903 phy_addr = i40e_get_phy_address(hw, hw->port);
6904 for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6905 temp_addr++) {
6906 status = i40e_read_phy_register_clause45(hw,
6907 I40E_PHY_COM_REG_PAGE,
6908 temp_addr, phy_addr,
6909 ®_val);
6910 if (status)
6911 return status;
6912 *val = reg_val;
6913 if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
6914 *led_addr = temp_addr;
6915 break;
6916 }
6917 }
6918 return status;
6919 }
6920
6921 /**
6922 * i40e_led_set_phy
6923 * @hw: pointer to the HW structure
6924 * @on: TRUE or FALSE
6925 * @led_addr: address of led register to use
6926 * @mode: original val plus bit for set or ignore
6927 *
6928 * Set led's on or off when controlled by the PHY
6929 *
6930 **/
6931 enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on,
6932 u16 led_addr, u32 mode)
6933 {
6934 enum i40e_status_code status = I40E_SUCCESS;
6935 u32 led_ctl = 0;
6936 u32 led_reg = 0;
6937
6938 status = i40e_led_get_reg(hw, led_addr, &led_reg);
6939 if (status)
6940 return status;
6941 led_ctl = led_reg;
6942 if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6943 led_reg = 0;
6944 status = i40e_led_set_reg(hw, led_addr, led_reg);
6945 if (status)
6946 return status;
6947 }
6948 status = i40e_led_get_reg(hw, led_addr, &led_reg);
6949 if (status)
6950 goto restore_config;
6951 if (on)
6952 led_reg = I40E_PHY_LED_MANUAL_ON;
6953 else
6954 led_reg = 0;
6955 status = i40e_led_set_reg(hw, led_addr, led_reg);
6956 if (status)
6957 goto restore_config;
6958 if (mode & I40E_PHY_LED_MODE_ORIG) {
6959 led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
6960 status = i40e_led_set_reg(hw, led_addr, led_ctl);
6961 }
6962 return status;
6963
6964 restore_config:
6965 status = i40e_led_set_reg(hw, led_addr, led_ctl);
6966 return status;
6967 }
6968
6969 /**
6970 * i40e_get_phy_lpi_status - read LPI status from PHY or MAC register
6971 * @hw: pointer to the hw struct
6972 * @stat: pointer to structure with status of rx and tx lpi
6973 *
6974 * Read LPI state directly from external PHY register or from MAC
6975 * register, depending on device ID and current link speed.
6976 */
6977 enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
6978 struct i40e_hw_port_stats *stat)
6979 {
6980 enum i40e_status_code ret = I40E_SUCCESS;
6981 bool eee_mrvl_phy;
6982 bool eee_bcm_phy;
6983 u32 val;
6984
6985 stat->rx_lpi_status = 0;
6986 stat->tx_lpi_status = 0;
6987
6988 eee_bcm_phy =
6989 (hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
6990 hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
6991 (hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB ||
6992 hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB);
6993 eee_mrvl_phy =
6994 hw->device_id == I40E_DEV_ID_1G_BASE_T_X722;
6995
6996 if (eee_bcm_phy || eee_mrvl_phy) {
6997 // read Clause 45 PCS Status 1 register
6998 ret = i40e_aq_get_phy_register(hw,
6999 I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
7000 I40E_BCM_PHY_PCS_STATUS1_PAGE,
7001 TRUE,
7002 I40E_BCM_PHY_PCS_STATUS1_REG,
7003 &val, NULL);
7004
7005 if (ret != I40E_SUCCESS)
7006 return ret;
7007
7008 stat->rx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_RX_LPI);
7009 stat->tx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_TX_LPI);
7010
7011 return ret;
7012 }
7013
7014 val = rd32(hw, I40E_PRTPM_EEE_STAT);
7015 stat->rx_lpi_status = (val & I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK) >>
7016 I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT;
7017 stat->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >>
7018 I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT;
7019
7020 return ret;
7021 }
7022
7023 /**
7024 * i40e_get_lpi_counters - read LPI counters from EEE statistics
7025 * @hw: pointer to the hw struct
7026 * @tx_counter: pointer to memory for TX LPI counter
7027 * @rx_counter: pointer to memory for RX LPI counter
7028 * @is_clear: returns TRUE if counters are clear after read
7029 *
7030 * Read Low Power Idle (LPI) mode counters from Energy Efficient
7031 * Ethernet (EEE) statistics.
7032 **/
7033 enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw,
7034 u32 *tx_counter, u32 *rx_counter,
7035 bool *is_clear)
7036 {
7037 /* only X710-T*L requires special handling of counters
7038 * for other devices we just read the MAC registers
7039 */
7040 if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
7041 hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
7042 hw->phy.link_info.link_speed != I40E_LINK_SPEED_1GB) {
7043 enum i40e_status_code retval;
7044 u32 cmd_status;
7045
7046 *is_clear = FALSE;
7047 retval = i40e_aq_run_phy_activity(hw,
7048 I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7049 I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT,
7050 &cmd_status, tx_counter, rx_counter, NULL);
7051
7052 if (!retval && cmd_status != I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7053 retval = I40E_ERR_ADMIN_QUEUE_ERROR;
7054
7055 return retval;
7056 }
7057
7058 *is_clear = TRUE;
7059 *tx_counter = rd32(hw, I40E_PRTPM_TLPIC);
7060 *rx_counter = rd32(hw, I40E_PRTPM_RLPIC);
7061
7062 return I40E_SUCCESS;
7063 }
7064
7065 /**
7066 * i40e_get_lpi_duration - read LPI time duration from EEE statistics
7067 * @hw: pointer to the hw struct
7068 * @stat: pointer to structure with status of rx and tx lpi
7069 * @tx_duration: pointer to memory for TX LPI time duration
7070 * @rx_duration: pointer to memory for RX LPI time duration
7071 *
7072 * Read Low Power Idle (LPI) mode time duration from Energy Efficient
7073 * Ethernet (EEE) statistics.
7074 */
7075 enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw,
7076 struct i40e_hw_port_stats *stat,
7077 u64 *tx_duration, u64 *rx_duration)
7078 {
7079 u32 tx_time_dur, rx_time_dur;
7080 enum i40e_status_code retval;
7081 u32 cmd_status;
7082
7083 if (hw->device_id != I40E_DEV_ID_10G_BASE_T_BC &&
7084 hw->device_id != I40E_DEV_ID_5G_BASE_T_BC)
7085 return I40E_ERR_NOT_IMPLEMENTED;
7086
7087 retval = i40e_aq_run_phy_activity
7088 (hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7089 I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR,
7090 &cmd_status, &tx_time_dur, &rx_time_dur, NULL);
7091
7092 if (retval)
7093 return retval;
7094 if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
7095 I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7096 return I40E_ERR_ADMIN_QUEUE_ERROR;
7097
7098 if (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB &&
7099 !tx_time_dur && !rx_time_dur &&
7100 stat->tx_lpi_status && stat->rx_lpi_status) {
7101 retval = i40e_aq_run_phy_activity
7102 (hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7103 I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR,
7104 &cmd_status,
7105 &tx_time_dur, &rx_time_dur, NULL);
7106
7107 if (retval)
7108 return retval;
7109 if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
7110 I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7111 return I40E_ERR_ADMIN_QUEUE_ERROR;
7112 tx_time_dur = 0;
7113 rx_time_dur = 0;
7114 }
7115
7116 *tx_duration = tx_time_dur;
7117 *rx_duration = rx_time_dur;
7118
7119 return retval;
7120 }
7121
7122 /**
7123 * i40e_lpi_stat_update - update LPI counters with values relative to offset
7124 * @hw: pointer to the hw struct
7125 * @offset_loaded: flag indicating need of writing current value to offset
7126 * @tx_offset: pointer to offset of TX LPI counter
7127 * @tx_stat: pointer to value of TX LPI counter
7128 * @rx_offset: pointer to offset of RX LPI counter
7129 * @rx_stat: pointer to value of RX LPI counter
7130 *
7131 * Update Low Power Idle (LPI) mode counters while having regard to passed
7132 * offsets.
7133 **/
7134 enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw,
7135 bool offset_loaded, u64 *tx_offset,
7136 u64 *tx_stat, u64 *rx_offset,
7137 u64 *rx_stat)
7138 {
7139 enum i40e_status_code retval;
7140 u32 tx_counter, rx_counter;
7141 bool is_clear;
7142
7143 retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter, &is_clear);
7144 if (retval)
7145 goto err;
7146
7147 if (is_clear) {
7148 *tx_stat += tx_counter;
7149 *rx_stat += rx_counter;
7150 } else {
7151 if (!offset_loaded) {
7152 *tx_offset = tx_counter;
7153 *rx_offset = rx_counter;
7154 }
7155
7156 *tx_stat = (tx_counter >= *tx_offset) ?
7157 (u32)(tx_counter - *tx_offset) :
7158 (u32)((tx_counter + BIT_ULL(32)) - *tx_offset);
7159 *rx_stat = (rx_counter >= *rx_offset) ?
7160 (u32)(rx_counter - *rx_offset) :
7161 (u32)((rx_counter + BIT_ULL(32)) - *rx_offset);
7162 }
7163 err:
7164 return retval;
7165 }
7166
7167 /**
7168 * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
7169 * @hw: pointer to the hw struct
7170 * @reg_addr: register address
7171 * @reg_val: ptr to register value
7172 * @cmd_details: pointer to command details structure or NULL
7173 *
7174 * Use the firmware to read the Rx control register,
7175 * especially useful if the Rx unit is under heavy pressure
7176 **/
7177 enum i40e_status_code i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
7178 u32 reg_addr, u32 *reg_val,
7179 struct i40e_asq_cmd_details *cmd_details)
7180 {
7181 struct i40e_aq_desc desc;
7182 struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
7183 (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7184 enum i40e_status_code status;
7185
7186 if (reg_val == NULL)
7187 return I40E_ERR_PARAM;
7188
7189 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
7190
7191 cmd_resp->address = CPU_TO_LE32(reg_addr);
7192
7193 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7194
7195 if (status == I40E_SUCCESS)
7196 *reg_val = LE32_TO_CPU(cmd_resp->value);
7197
7198 return status;
7199 }
7200
7201 /**
7202 * i40e_read_rx_ctl - read from an Rx control register
7203 * @hw: pointer to the hw struct
7204 * @reg_addr: register address
7205 **/
7206 u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
7207 {
7208 enum i40e_status_code status = I40E_SUCCESS;
7209 bool use_register;
7210 int retry = 5;
7211 u32 val = 0;
7212
7213 use_register = (((hw->aq.api_maj_ver == 1) &&
7214 (hw->aq.api_min_ver < 5)) ||
7215 (hw->mac.type == I40E_MAC_X722));
7216 if (!use_register) {
7217 do_retry:
7218 status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
7219 if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7220 i40e_msec_delay(1);
7221 retry--;
7222 goto do_retry;
7223 }
7224 }
7225
7226 /* if the AQ access failed, try the old-fashioned way */
7227 if (status || use_register)
7228 val = rd32(hw, reg_addr);
7229
7230 return val;
7231 }
7232
7233 /**
7234 * i40e_aq_rx_ctl_write_register
7235 * @hw: pointer to the hw struct
7236 * @reg_addr: register address
7237 * @reg_val: register value
7238 * @cmd_details: pointer to command details structure or NULL
7239 *
7240 * Use the firmware to write to an Rx control register,
7241 * especially useful if the Rx unit is under heavy pressure
7242 **/
7243 enum i40e_status_code i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
7244 u32 reg_addr, u32 reg_val,
7245 struct i40e_asq_cmd_details *cmd_details)
7246 {
7247 struct i40e_aq_desc desc;
7248 struct i40e_aqc_rx_ctl_reg_read_write *cmd =
7249 (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7250 enum i40e_status_code status;
7251
7252 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
7253
7254 cmd->address = CPU_TO_LE32(reg_addr);
7255 cmd->value = CPU_TO_LE32(reg_val);
7256
7257 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7258
7259 return status;
7260 }
7261
7262 /**
7263 * i40e_write_rx_ctl - write to an Rx control register
7264 * @hw: pointer to the hw struct
7265 * @reg_addr: register address
7266 * @reg_val: register value
7267 **/
7268 void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
7269 {
7270 enum i40e_status_code status = I40E_SUCCESS;
7271 bool use_register;
7272 int retry = 5;
7273
7274 use_register = (((hw->aq.api_maj_ver == 1) &&
7275 (hw->aq.api_min_ver < 5)) ||
7276 (hw->mac.type == I40E_MAC_X722));
7277 if (!use_register) {
7278 do_retry:
7279 status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
7280 reg_val, NULL);
7281 if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7282 i40e_msec_delay(1);
7283 retry--;
7284 goto do_retry;
7285 }
7286 }
7287
7288 /* if the AQ access failed, try the old-fashioned way */
7289 if (status || use_register)
7290 wr32(hw, reg_addr, reg_val);
7291 }
7292
7293 /**
7294 * i40e_mdio_if_number_selection - MDIO I/F number selection
7295 * @hw: pointer to the hw struct
7296 * @set_mdio: use MDIO I/F number specified by mdio_num
7297 * @mdio_num: MDIO I/F number
7298 * @cmd: pointer to PHY Register command structure
7299 **/
7300 static void
7301 i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio, u8 mdio_num,
7302 struct i40e_aqc_phy_register_access *cmd)
7303 {
7304 if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) {
7305 if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED)
7306 cmd->cmd_flags |=
7307 I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER |
7308 ((mdio_num <<
7309 I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) &
7310 I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK);
7311 else
7312 i40e_debug(hw, I40E_DEBUG_PHY,
7313 "MDIO I/F number selection not supported by current FW version.\n");
7314 }
7315 }
7316
7317 /**
7318 * i40e_aq_set_phy_register_ext
7319 * @hw: pointer to the hw struct
7320 * @phy_select: select which phy should be accessed
7321 * @dev_addr: PHY device address
7322 * @page_change: enable auto page change
7323 * @set_mdio: use MDIO I/F number specified by mdio_num
7324 * @mdio_num: MDIO I/F number
7325 * @reg_addr: PHY register address
7326 * @reg_val: new register value
7327 * @cmd_details: pointer to command details structure or NULL
7328 *
7329 * Write the external PHY register.
7330 * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7331 * may use simple wrapper i40e_aq_set_phy_register.
7332 **/
7333 enum i40e_status_code
7334 i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
7335 u8 phy_select, u8 dev_addr, bool page_change,
7336 bool set_mdio, u8 mdio_num,
7337 u32 reg_addr, u32 reg_val,
7338 struct i40e_asq_cmd_details *cmd_details)
7339 {
7340 struct i40e_aq_desc desc;
7341 struct i40e_aqc_phy_register_access *cmd =
7342 (struct i40e_aqc_phy_register_access *)&desc.params.raw;
7343 enum i40e_status_code status;
7344
7345 i40e_fill_default_direct_cmd_desc(&desc,
7346 i40e_aqc_opc_set_phy_register);
7347
7348 cmd->phy_interface = phy_select;
7349 cmd->dev_addres = dev_addr;
7350 cmd->reg_address = CPU_TO_LE32(reg_addr);
7351 cmd->reg_value = CPU_TO_LE32(reg_val);
7352
7353 if (!page_change)
7354 cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7355
7356 i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7357
7358 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7359
7360 return status;
7361 }
7362
7363 /**
7364 * i40e_aq_get_phy_register_ext
7365 * @hw: pointer to the hw struct
7366 * @phy_select: select which phy should be accessed
7367 * @dev_addr: PHY device address
7368 * @page_change: enable auto page change
7369 * @set_mdio: use MDIO I/F number specified by mdio_num
7370 * @mdio_num: MDIO I/F number
7371 * @reg_addr: PHY register address
7372 * @reg_val: read register value
7373 * @cmd_details: pointer to command details structure or NULL
7374 *
7375 * Read the external PHY register.
7376 * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7377 * may use simple wrapper i40e_aq_get_phy_register.
7378 **/
7379 enum i40e_status_code
7380 i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
7381 u8 phy_select, u8 dev_addr, bool page_change,
7382 bool set_mdio, u8 mdio_num,
7383 u32 reg_addr, u32 *reg_val,
7384 struct i40e_asq_cmd_details *cmd_details)
7385 {
7386 struct i40e_aq_desc desc;
7387 struct i40e_aqc_phy_register_access *cmd =
7388 (struct i40e_aqc_phy_register_access *)&desc.params.raw;
7389 enum i40e_status_code status;
7390
7391 i40e_fill_default_direct_cmd_desc(&desc,
7392 i40e_aqc_opc_get_phy_register);
7393
7394 cmd->phy_interface = phy_select;
7395 cmd->dev_addres = dev_addr;
7396 cmd->reg_address = CPU_TO_LE32(reg_addr);
7397
7398 if (!page_change)
7399 cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7400
7401 i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7402
7403 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7404 if (!status)
7405 *reg_val = LE32_TO_CPU(cmd->reg_value);
7406
7407 return status;
7408 }
7409
7410 /**
7411 * i40e_aq_run_phy_activity
7412 * @hw: pointer to the hw struct
7413 * @activity_id: ID of DNL activity to run
7414 * @dnl_opcode: opcode passed to DNL script
7415 * @cmd_status: pointer to memory to write return value of DNL script
7416 * @data0: pointer to memory for first 4 bytes of data returned by DNL script
7417 * @data1: pointer to memory for last 4 bytes of data returned by DNL script
7418 * @cmd_details: pointer to command details structure or NULL
7419 *
7420 * Run DNL admin command.
7421 **/
7422 enum i40e_status_code
7423 i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 dnl_opcode,
7424 u32 *cmd_status, u32 *data0, u32 *data1,
7425 struct i40e_asq_cmd_details *cmd_details)
7426 {
7427 struct i40e_aqc_run_phy_activity *cmd;
7428 enum i40e_status_code retval;
7429 struct i40e_aq_desc desc;
7430
7431 cmd = (struct i40e_aqc_run_phy_activity *)&desc.params.raw;
7432
7433 if (!cmd_status || !data0 || !data1) {
7434 retval = I40E_ERR_PARAM;
7435 goto err;
7436 }
7437
7438 i40e_fill_default_direct_cmd_desc(&desc,
7439 i40e_aqc_opc_run_phy_activity);
7440
7441 cmd->activity_id = CPU_TO_LE16(activity_id);
7442 cmd->params.cmd.dnl_opcode = CPU_TO_LE32(dnl_opcode);
7443
7444 retval = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7445 if (retval)
7446 goto err;
7447
7448 *cmd_status = LE32_TO_CPU(cmd->params.resp.cmd_status);
7449 *data0 = LE32_TO_CPU(cmd->params.resp.data0);
7450 *data1 = LE32_TO_CPU(cmd->params.resp.data1);
7451 err:
7452 return retval;
7453 }
7454
7455
7456 /**
7457 * i40e_aq_send_msg_to_pf
7458 * @hw: pointer to the hardware structure
7459 * @v_opcode: opcodes for VF-PF communication
7460 * @v_retval: return error code
7461 * @msg: pointer to the msg buffer
7462 * @msglen: msg length
7463 * @cmd_details: pointer to command details
7464 *
7465 * Send message to PF driver using admin queue. By default, this message
7466 * is sent asynchronously, i.e. i40e_asq_send_command() does not wait for
7467 * completion before returning.
7468 **/
7469 enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
7470 enum virtchnl_ops v_opcode,
7471 enum i40e_status_code v_retval,
7472 u8 *msg, u16 msglen,
7473 struct i40e_asq_cmd_details *cmd_details)
7474 {
7475 struct i40e_aq_desc desc;
7476 struct i40e_asq_cmd_details details;
7477 enum i40e_status_code status;
7478
7479 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf);
7480 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
7481 desc.cookie_high = CPU_TO_LE32(v_opcode);
7482 desc.cookie_low = CPU_TO_LE32(v_retval);
7483 if (msglen) {
7484 desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF
7485 | I40E_AQ_FLAG_RD));
7486 if (msglen > I40E_AQ_LARGE_BUF)
7487 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
7488 desc.datalen = CPU_TO_LE16(msglen);
7489 }
7490 if (!cmd_details) {
7491 i40e_memset(&details, 0, sizeof(details), I40E_NONDMA_MEM);
7492 details.async = TRUE;
7493 cmd_details = &details;
7494 }
7495 status = i40e_asq_send_command(hw, (struct i40e_aq_desc *)&desc, msg,
7496 msglen, cmd_details);
7497 return status;
7498 }
7499
7500 /**
7501 * i40e_vf_parse_hw_config
7502 * @hw: pointer to the hardware structure
7503 * @msg: pointer to the virtual channel VF resource structure
7504 *
7505 * Given a VF resource message from the PF, populate the hw struct
7506 * with appropriate information.
7507 **/
7508 void i40e_vf_parse_hw_config(struct i40e_hw *hw,
7509 struct virtchnl_vf_resource *msg)
7510 {
7511 struct virtchnl_vsi_resource *vsi_res;
7512 int i;
7513
7514 vsi_res = &msg->vsi_res[0];
7515
7516 hw->dev_caps.num_vsis = msg->num_vsis;
7517 hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
7518 hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
7519 hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
7520 hw->dev_caps.dcb = msg->vf_cap_flags &
7521 VIRTCHNL_VF_OFFLOAD_L2;
7522 hw->dev_caps.iwarp = (msg->vf_cap_flags &
7523 VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
7524 for (i = 0; i < msg->num_vsis; i++) {
7525 if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
7526 i40e_memcpy(hw->mac.perm_addr,
7527 vsi_res->default_mac_addr,
7528 ETH_ALEN,
7529 I40E_NONDMA_TO_NONDMA);
7530 i40e_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
7531 ETH_ALEN,
7532 I40E_NONDMA_TO_NONDMA);
7533 }
7534 vsi_res++;
7535 }
7536 }
7537
7538 /**
7539 * i40e_vf_reset
7540 * @hw: pointer to the hardware structure
7541 *
7542 * Send a VF_RESET message to the PF. Does not wait for response from PF
7543 * as none will be forthcoming. Immediately after calling this function,
7544 * the admin queue should be shut down and (optionally) reinitialized.
7545 **/
7546 enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
7547 {
7548 return i40e_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
7549 I40E_SUCCESS, NULL, 0, NULL);
7550 }
7551
7552 /**
7553 * i40e_aq_set_arp_proxy_config
7554 * @hw: pointer to the HW structure
7555 * @proxy_config: pointer to proxy config command table struct
7556 * @cmd_details: pointer to command details
7557 *
7558 * Set ARP offload parameters from pre-populated
7559 * i40e_aqc_arp_proxy_data struct
7560 **/
7561 enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
7562 struct i40e_aqc_arp_proxy_data *proxy_config,
7563 struct i40e_asq_cmd_details *cmd_details)
7564 {
7565 struct i40e_aq_desc desc;
7566 enum i40e_status_code status;
7567
7568 if (!proxy_config)
7569 return I40E_ERR_PARAM;
7570
7571 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_proxy_config);
7572
7573 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7574 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7575 desc.params.external.addr_high =
7576 CPU_TO_LE32(I40E_HI_DWORD((u64)proxy_config));
7577 desc.params.external.addr_low =
7578 CPU_TO_LE32(I40E_LO_DWORD((u64)proxy_config));
7579 desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_arp_proxy_data));
7580
7581 status = i40e_asq_send_command(hw, &desc, proxy_config,
7582 sizeof(struct i40e_aqc_arp_proxy_data),
7583 cmd_details);
7584
7585 return status;
7586 }
7587
7588 /**
7589 * i40e_aq_set_ns_proxy_table_entry
7590 * @hw: pointer to the HW structure
7591 * @ns_proxy_table_entry: pointer to NS table entry command struct
7592 * @cmd_details: pointer to command details
7593 *
7594 * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
7595 * from pre-populated i40e_aqc_ns_proxy_data struct
7596 **/
7597 enum i40e_status_code i40e_aq_set_ns_proxy_table_entry(struct i40e_hw *hw,
7598 struct i40e_aqc_ns_proxy_data *ns_proxy_table_entry,
7599 struct i40e_asq_cmd_details *cmd_details)
7600 {
7601 struct i40e_aq_desc desc;
7602 enum i40e_status_code status;
7603
7604 if (!ns_proxy_table_entry)
7605 return I40E_ERR_PARAM;
7606
7607 i40e_fill_default_direct_cmd_desc(&desc,
7608 i40e_aqc_opc_set_ns_proxy_table_entry);
7609
7610 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7611 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7612 desc.params.external.addr_high =
7613 CPU_TO_LE32(I40E_HI_DWORD((u64)ns_proxy_table_entry));
7614 desc.params.external.addr_low =
7615 CPU_TO_LE32(I40E_LO_DWORD((u64)ns_proxy_table_entry));
7616 desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_ns_proxy_data));
7617
7618 status = i40e_asq_send_command(hw, &desc, ns_proxy_table_entry,
7619 sizeof(struct i40e_aqc_ns_proxy_data),
7620 cmd_details);
7621
7622 return status;
7623 }
7624
7625 /**
7626 * i40e_aq_set_clear_wol_filter
7627 * @hw: pointer to the hw struct
7628 * @filter_index: index of filter to modify (0-7)
7629 * @filter: buffer containing filter to be set
7630 * @set_filter: TRUE to set filter, FALSE to clear filter
7631 * @no_wol_tco: if TRUE, pass through packets cannot cause wake-up
7632 * if FALSE, pass through packets may cause wake-up
7633 * @filter_valid: TRUE if filter action is valid
7634 * @no_wol_tco_valid: TRUE if no WoL in TCO traffic action valid
7635 * @cmd_details: pointer to command details structure or NULL
7636 *
7637 * Set or clear WoL filter for port attached to the PF
7638 **/
7639 enum i40e_status_code i40e_aq_set_clear_wol_filter(struct i40e_hw *hw,
7640 u8 filter_index,
7641 struct i40e_aqc_set_wol_filter_data *filter,
7642 bool set_filter, bool no_wol_tco,
7643 bool filter_valid, bool no_wol_tco_valid,
7644 struct i40e_asq_cmd_details *cmd_details)
7645 {
7646 struct i40e_aq_desc desc;
7647 struct i40e_aqc_set_wol_filter *cmd =
7648 (struct i40e_aqc_set_wol_filter *)&desc.params.raw;
7649 enum i40e_status_code status;
7650 u16 cmd_flags = 0;
7651 u16 valid_flags = 0;
7652 u16 buff_len = 0;
7653
7654 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_wol_filter);
7655
7656 if (filter_index >= I40E_AQC_MAX_NUM_WOL_FILTERS)
7657 return I40E_ERR_PARAM;
7658 cmd->filter_index = CPU_TO_LE16(filter_index);
7659
7660 if (set_filter) {
7661 if (!filter)
7662 return I40E_ERR_PARAM;
7663
7664 cmd_flags |= I40E_AQC_SET_WOL_FILTER;
7665 cmd_flags |= I40E_AQC_SET_WOL_FILTER_WOL_PRESERVE_ON_PFR;
7666 }
7667
7668 if (no_wol_tco)
7669 cmd_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_WOL;
7670 cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
7671
7672 if (filter_valid)
7673 valid_flags |= I40E_AQC_SET_WOL_FILTER_ACTION_VALID;
7674 if (no_wol_tco_valid)
7675 valid_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
7676 cmd->valid_flags = CPU_TO_LE16(valid_flags);
7677
7678 buff_len = sizeof(*filter);
7679 desc.datalen = CPU_TO_LE16(buff_len);
7680
7681 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7682 desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7683
7684 cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)filter));
7685 cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)filter));
7686
7687 status = i40e_asq_send_command(hw, &desc, filter,
7688 buff_len, cmd_details);
7689
7690 return status;
7691 }
7692
7693 /**
7694 * i40e_aq_get_wake_event_reason
7695 * @hw: pointer to the hw struct
7696 * @wake_reason: return value, index of matching filter
7697 * @cmd_details: pointer to command details structure or NULL
7698 *
7699 * Get information for the reason of a Wake Up event
7700 **/
7701 enum i40e_status_code i40e_aq_get_wake_event_reason(struct i40e_hw *hw,
7702 u16 *wake_reason,
7703 struct i40e_asq_cmd_details *cmd_details)
7704 {
7705 struct i40e_aq_desc desc;
7706 struct i40e_aqc_get_wake_reason_completion *resp =
7707 (struct i40e_aqc_get_wake_reason_completion *)&desc.params.raw;
7708 enum i40e_status_code status;
7709
7710 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_wake_reason);
7711
7712 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7713
7714 if (status == I40E_SUCCESS)
7715 *wake_reason = LE16_TO_CPU(resp->wake_reason);
7716
7717 return status;
7718 }
7719
7720 /**
7721 * i40e_aq_clear_all_wol_filters
7722 * @hw: pointer to the hw struct
7723 * @cmd_details: pointer to command details structure or NULL
7724 *
7725 * Get information for the reason of a Wake Up event
7726 **/
7727 enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
7728 struct i40e_asq_cmd_details *cmd_details)
7729 {
7730 struct i40e_aq_desc desc;
7731 enum i40e_status_code status;
7732
7733 i40e_fill_default_direct_cmd_desc(&desc,
7734 i40e_aqc_opc_clear_all_wol_filters);
7735
7736 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7737
7738 return status;
7739 }
7740
Cache object: 3f9e5ef41e96e8f9f4a7c98690c6d745
|