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