xref: /freebsd/sys/dev/ixl/i40e_common.c (revision 71625ec9)
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 
34 #include "i40e_type.h"
35 #include "i40e_adminq.h"
36 #include "i40e_prototype.h"
37 #include "virtchnl.h"
38 
39 
40 /**
41  * i40e_set_mac_type - Sets MAC type
42  * @hw: pointer to the HW structure
43  *
44  * This function sets the mac type of the adapter based on the
45  * vendor ID and device ID stored in the hw structure.
46  **/
i40e_set_mac_type(struct i40e_hw * hw)47 enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
48 {
49 	enum i40e_status_code status = I40E_SUCCESS;
50 
51 	DEBUGFUNC("i40e_set_mac_type\n");
52 
53 	if (hw->vendor_id == I40E_INTEL_VENDOR_ID) {
54 		switch (hw->device_id) {
55 		case I40E_DEV_ID_SFP_XL710:
56 		case I40E_DEV_ID_QEMU:
57 		case I40E_DEV_ID_KX_B:
58 		case I40E_DEV_ID_KX_C:
59 		case I40E_DEV_ID_QSFP_A:
60 		case I40E_DEV_ID_QSFP_B:
61 		case I40E_DEV_ID_QSFP_C:
62 		case I40E_DEV_ID_10G_BASE_T:
63 		case I40E_DEV_ID_10G_BASE_T4:
64 		case I40E_DEV_ID_10G_BASE_T_BC:
65 		case I40E_DEV_ID_10G_B:
66 		case I40E_DEV_ID_10G_SFP:
67 		case I40E_DEV_ID_5G_BASE_T_BC:
68 		case I40E_DEV_ID_1G_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_PRIMARY_REQUESTS_PENDING:
199 		return "I40E_ERR_PRIMARY_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 	case I40E_PHY_TYPE_10GBASE_AOC:
1255 	case I40E_PHY_TYPE_25GBASE_AOC:
1256 	case I40E_PHY_TYPE_40GBASE_AOC:
1257 		media = I40E_MEDIA_TYPE_FIBER;
1258 		break;
1259 	case I40E_PHY_TYPE_100BASE_TX:
1260 	case I40E_PHY_TYPE_1000BASE_T:
1261 	case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
1262 	case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
1263 	case I40E_PHY_TYPE_10GBASE_T:
1264 		media = I40E_MEDIA_TYPE_BASET;
1265 		break;
1266 	case I40E_PHY_TYPE_10GBASE_CR1_CU:
1267 	case I40E_PHY_TYPE_40GBASE_CR4_CU:
1268 	case I40E_PHY_TYPE_10GBASE_CR1:
1269 	case I40E_PHY_TYPE_40GBASE_CR4:
1270 	case I40E_PHY_TYPE_10GBASE_SFPP_CU:
1271 	case I40E_PHY_TYPE_25GBASE_CR:
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	1000
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 mode = 0;
1567 	int i;
1568 
1569 	/* as per the documentation GPIO 22-29 are the LED
1570 	 * GPIO pins named LED0..LED7
1571 	 */
1572 	for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1573 		u32 gpio_val = i40e_led_is_mine(hw, i);
1574 
1575 		if (!gpio_val)
1576 			continue;
1577 
1578 
1579 		mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
1580 			I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT;
1581 		break;
1582 	}
1583 
1584 	return mode;
1585 }
1586 
1587 /**
1588  * i40e_led_set - set new on/off mode
1589  * @hw: pointer to the hw struct
1590  * @mode: 0=off, 0xf=on (else see manual for mode details)
1591  * @blink: TRUE if the LED should blink when on, FALSE if steady
1592  *
1593  * if this function is used to turn on the blink it should
1594  * be used to disable the blink when restoring the original state.
1595  **/
i40e_led_set(struct i40e_hw * hw,u32 mode,bool blink)1596 void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
1597 {
1598 	int i;
1599 
1600 	if (mode & ~I40E_LED_MODE_VALID) {
1601 		DEBUGOUT1("invalid mode passed in %X\n", mode);
1602 		return;
1603 	}
1604 
1605 	/* as per the documentation GPIO 22-29 are the LED
1606 	 * GPIO pins named LED0..LED7
1607 	 */
1608 	for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1609 		u32 gpio_val = i40e_led_is_mine(hw, i);
1610 
1611 		if (!gpio_val)
1612 			continue;
1613 
1614 
1615 		if (I40E_IS_X710TL_DEVICE(hw->device_id)) {
1616 			u32 pin_func = 0;
1617 
1618 			if (mode & I40E_FW_LED)
1619 				pin_func = I40E_PIN_FUNC_SDP;
1620 			else
1621 				pin_func = I40E_PIN_FUNC_LED;
1622 
1623 			gpio_val &= ~I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK;
1624 			gpio_val |= ((pin_func <<
1625 				     I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT) &
1626 				     I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK);
1627 		}
1628 		gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
1629 		/* this & is a bit of paranoia, but serves as a range check */
1630 		gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
1631 			     I40E_GLGEN_GPIO_CTL_LED_MODE_MASK);
1632 
1633 		if (blink)
1634 			gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
1635 		else
1636 			gpio_val &= ~BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
1637 
1638 		wr32(hw, I40E_GLGEN_GPIO_CTL(i), gpio_val);
1639 		break;
1640 	}
1641 }
1642 
1643 /* Admin command wrappers */
1644 
1645 /**
1646  * i40e_aq_get_phy_capabilities
1647  * @hw: pointer to the hw struct
1648  * @abilities: structure for PHY capabilities to be filled
1649  * @qualified_modules: report Qualified Modules
1650  * @report_init: report init capabilities (active are default)
1651  * @cmd_details: pointer to command details structure or NULL
1652  *
1653  * Returns the various PHY abilities supported on the Port.
1654  **/
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)1655 enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
1656 			bool qualified_modules, bool report_init,
1657 			struct i40e_aq_get_phy_abilities_resp *abilities,
1658 			struct i40e_asq_cmd_details *cmd_details)
1659 {
1660 	struct i40e_aq_desc desc;
1661 	enum i40e_status_code status;
1662 	u16 max_delay = I40E_MAX_PHY_TIMEOUT, total_delay = 0;
1663 	u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
1664 
1665 	if (!abilities)
1666 		return I40E_ERR_PARAM;
1667 
1668 	do {
1669 		i40e_fill_default_direct_cmd_desc(&desc,
1670 					       i40e_aqc_opc_get_phy_abilities);
1671 
1672 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
1673 		if (abilities_size > I40E_AQ_LARGE_BUF)
1674 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
1675 
1676 		if (qualified_modules)
1677 			desc.params.external.param0 |=
1678 			CPU_TO_LE32(I40E_AQ_PHY_REPORT_QUALIFIED_MODULES);
1679 
1680 		if (report_init)
1681 			desc.params.external.param0 |=
1682 			CPU_TO_LE32(I40E_AQ_PHY_REPORT_INITIAL_VALUES);
1683 
1684 		status = i40e_asq_send_command(hw, &desc, abilities,
1685 					       abilities_size, cmd_details);
1686 
1687 		switch (hw->aq.asq_last_status) {
1688 		case I40E_AQ_RC_EIO:
1689 			status = I40E_ERR_UNKNOWN_PHY;
1690 			break;
1691 		case I40E_AQ_RC_EAGAIN:
1692 			i40e_msec_delay(1);
1693 			total_delay++;
1694 			status = I40E_ERR_TIMEOUT;
1695 			break;
1696 		/* also covers I40E_AQ_RC_OK */
1697 		default:
1698 			break;
1699 		}
1700 
1701 	} while ((hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN) &&
1702 		(total_delay < max_delay));
1703 
1704 	if (status != I40E_SUCCESS)
1705 		return status;
1706 
1707 	if (report_init) {
1708 		if (hw->mac.type ==  I40E_MAC_XL710 &&
1709 		    hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
1710 		    hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
1711 			status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
1712 		} else {
1713 			hw->phy.phy_types = LE32_TO_CPU(abilities->phy_type);
1714 			hw->phy.phy_types |=
1715 					((u64)abilities->phy_type_ext << 32);
1716 		}
1717 	}
1718 
1719 	return status;
1720 }
1721 
1722 /**
1723  * i40e_aq_set_phy_config
1724  * @hw: pointer to the hw struct
1725  * @config: structure with PHY configuration to be set
1726  * @cmd_details: pointer to command details structure or NULL
1727  *
1728  * Set the various PHY configuration parameters
1729  * supported on the Port.One or more of the Set PHY config parameters may be
1730  * ignored in an MFP mode as the PF may not have the privilege to set some
1731  * of the PHY Config parameters. This status will be indicated by the
1732  * command response.
1733  **/
i40e_aq_set_phy_config(struct i40e_hw * hw,struct i40e_aq_set_phy_config * config,struct i40e_asq_cmd_details * cmd_details)1734 enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
1735 				struct i40e_aq_set_phy_config *config,
1736 				struct i40e_asq_cmd_details *cmd_details)
1737 {
1738 	struct i40e_aq_desc desc;
1739 	struct i40e_aq_set_phy_config *cmd =
1740 		(struct i40e_aq_set_phy_config *)&desc.params.raw;
1741 	enum i40e_status_code status;
1742 
1743 	if (!config)
1744 		return I40E_ERR_PARAM;
1745 
1746 	i40e_fill_default_direct_cmd_desc(&desc,
1747 					  i40e_aqc_opc_set_phy_config);
1748 
1749 	*cmd = *config;
1750 
1751 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1752 
1753 	return status;
1754 }
1755 
1756 /**
1757  * i40e_set_fc
1758  * @hw: pointer to the hw struct
1759  * @aq_failures: buffer to return AdminQ failure information
1760  * @atomic_restart: whether to enable atomic link restart
1761  *
1762  * Set the requested flow control mode using set_phy_config.
1763  **/
i40e_set_fc(struct i40e_hw * hw,u8 * aq_failures,bool atomic_restart)1764 enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
1765 				  bool atomic_restart)
1766 {
1767 	enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
1768 	struct i40e_aq_get_phy_abilities_resp abilities;
1769 	struct i40e_aq_set_phy_config config;
1770 	enum i40e_status_code status;
1771 	u8 pause_mask = 0x0;
1772 
1773 	*aq_failures = 0x0;
1774 
1775 	switch (fc_mode) {
1776 	case I40E_FC_FULL:
1777 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1778 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1779 		break;
1780 	case I40E_FC_RX_PAUSE:
1781 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1782 		break;
1783 	case I40E_FC_TX_PAUSE:
1784 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1785 		break;
1786 	default:
1787 		break;
1788 	}
1789 
1790 	/* Get the current phy config */
1791 	status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
1792 					      NULL);
1793 	if (status) {
1794 		*aq_failures |= I40E_SET_FC_AQ_FAIL_GET;
1795 		return status;
1796 	}
1797 
1798 	memset(&config, 0, sizeof(config));
1799 	/* clear the old pause settings */
1800 	config.abilities = abilities.abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
1801 			   ~(I40E_AQ_PHY_FLAG_PAUSE_RX);
1802 	/* set the new abilities */
1803 	config.abilities |= pause_mask;
1804 	/* If the abilities have changed, then set the new config */
1805 	if (config.abilities != abilities.abilities) {
1806 		/* Auto restart link so settings take effect */
1807 		if (atomic_restart)
1808 			config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
1809 		/* Copy over all the old settings */
1810 		config.phy_type = abilities.phy_type;
1811 		config.phy_type_ext = abilities.phy_type_ext;
1812 		config.link_speed = abilities.link_speed;
1813 		config.eee_capability = abilities.eee_capability;
1814 		config.eeer = abilities.eeer_val;
1815 		config.low_power_ctrl = abilities.d3_lpan;
1816 		config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
1817 				    I40E_AQ_PHY_FEC_CONFIG_MASK;
1818 		status = i40e_aq_set_phy_config(hw, &config, NULL);
1819 
1820 		if (status)
1821 			*aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
1822 	}
1823 	/* Update the link info */
1824 	status = i40e_update_link_info(hw);
1825 	if (status) {
1826 		/* Wait a little bit (on 40G cards it sometimes takes a really
1827 		 * long time for link to come back from the atomic reset)
1828 		 * and try once more
1829 		 */
1830 		i40e_msec_delay(1000);
1831 		status = i40e_update_link_info(hw);
1832 	}
1833 	if (status)
1834 		*aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
1835 
1836 	return status;
1837 }
1838 
1839 /**
1840  * i40e_aq_set_mac_config
1841  * @hw: pointer to the hw struct
1842  * @max_frame_size: Maximum Frame Size to be supported by the port
1843  * @crc_en: Tell HW to append a CRC to outgoing frames
1844  * @pacing: Pacing configurations
1845  * @auto_drop_blocking_packets: Tell HW to drop packets if TC queue is blocked
1846  * @cmd_details: pointer to command details structure or NULL
1847  *
1848  * Configure MAC settings for frame size, jumbo frame support and the
1849  * addition of a CRC by the hardware.
1850  **/
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)1851 enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw,
1852 				u16 max_frame_size,
1853 				bool crc_en, u16 pacing,
1854 				bool auto_drop_blocking_packets,
1855 				struct i40e_asq_cmd_details *cmd_details)
1856 {
1857 	struct i40e_aq_desc desc;
1858 	struct i40e_aq_set_mac_config *cmd =
1859 		(struct i40e_aq_set_mac_config *)&desc.params.raw;
1860 	enum i40e_status_code status;
1861 
1862 	if (max_frame_size == 0)
1863 		return I40E_ERR_PARAM;
1864 
1865 	i40e_fill_default_direct_cmd_desc(&desc,
1866 					  i40e_aqc_opc_set_mac_config);
1867 
1868 	cmd->max_frame_size = CPU_TO_LE16(max_frame_size);
1869 	cmd->params = ((u8)pacing & 0x0F) << 3;
1870 	if (crc_en)
1871 		cmd->params |= I40E_AQ_SET_MAC_CONFIG_CRC_EN;
1872 
1873 	if (auto_drop_blocking_packets) {
1874 		if (hw->flags & I40E_HW_FLAG_DROP_MODE)
1875 			cmd->params |=
1876 				I40E_AQ_SET_MAC_CONFIG_DROP_BLOCKING_PACKET_EN;
1877 		else
1878 			i40e_debug(hw, I40E_DEBUG_ALL,
1879 				   "This FW api version does not support drop mode.\n");
1880 	}
1881 
1882 #define I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD	0x7FFF
1883 	cmd->fc_refresh_threshold =
1884 		CPU_TO_LE16(I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD);
1885 
1886 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1887 
1888 	return status;
1889 }
1890 
1891 /**
1892  * i40e_aq_clear_pxe_mode
1893  * @hw: pointer to the hw struct
1894  * @cmd_details: pointer to command details structure or NULL
1895  *
1896  * Tell the firmware that the driver is taking over from PXE
1897  **/
i40e_aq_clear_pxe_mode(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)1898 enum i40e_status_code i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
1899 			struct i40e_asq_cmd_details *cmd_details)
1900 {
1901 	enum i40e_status_code status;
1902 	struct i40e_aq_desc desc;
1903 	struct i40e_aqc_clear_pxe *cmd =
1904 		(struct i40e_aqc_clear_pxe *)&desc.params.raw;
1905 
1906 	i40e_fill_default_direct_cmd_desc(&desc,
1907 					  i40e_aqc_opc_clear_pxe_mode);
1908 
1909 	cmd->rx_cnt = 0x2;
1910 
1911 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1912 
1913 	wr32(hw, I40E_GLLAN_RCTL_0, 0x1);
1914 
1915 	return status;
1916 }
1917 
1918 /**
1919  * i40e_aq_set_link_restart_an
1920  * @hw: pointer to the hw struct
1921  * @enable_link: if TRUE: enable link, if FALSE: disable link
1922  * @cmd_details: pointer to command details structure or NULL
1923  *
1924  * Sets up the link and restarts the Auto-Negotiation over the link.
1925  **/
i40e_aq_set_link_restart_an(struct i40e_hw * hw,bool enable_link,struct i40e_asq_cmd_details * cmd_details)1926 enum i40e_status_code i40e_aq_set_link_restart_an(struct i40e_hw *hw,
1927 		bool enable_link, struct i40e_asq_cmd_details *cmd_details)
1928 {
1929 	struct i40e_aq_desc desc;
1930 	struct i40e_aqc_set_link_restart_an *cmd =
1931 		(struct i40e_aqc_set_link_restart_an *)&desc.params.raw;
1932 	enum i40e_status_code status;
1933 
1934 	i40e_fill_default_direct_cmd_desc(&desc,
1935 					  i40e_aqc_opc_set_link_restart_an);
1936 
1937 	cmd->command = I40E_AQ_PHY_RESTART_AN;
1938 	if (enable_link)
1939 		cmd->command |= I40E_AQ_PHY_LINK_ENABLE;
1940 	else
1941 		cmd->command &= ~I40E_AQ_PHY_LINK_ENABLE;
1942 
1943 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1944 
1945 	return status;
1946 }
1947 
1948 /**
1949  * i40e_aq_get_link_info
1950  * @hw: pointer to the hw struct
1951  * @enable_lse: enable/disable LinkStatusEvent reporting
1952  * @link: pointer to link status structure - optional
1953  * @cmd_details: pointer to command details structure or NULL
1954  *
1955  * Returns the link status of the adapter.
1956  **/
i40e_aq_get_link_info(struct i40e_hw * hw,bool enable_lse,struct i40e_link_status * link,struct i40e_asq_cmd_details * cmd_details)1957 enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
1958 				bool enable_lse, struct i40e_link_status *link,
1959 				struct i40e_asq_cmd_details *cmd_details)
1960 {
1961 	struct i40e_aq_desc desc;
1962 	struct i40e_aqc_get_link_status *resp =
1963 		(struct i40e_aqc_get_link_status *)&desc.params.raw;
1964 	struct i40e_link_status *hw_link_info = &hw->phy.link_info;
1965 	enum i40e_status_code status;
1966 	bool tx_pause, rx_pause;
1967 	u16 command_flags;
1968 
1969 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
1970 
1971 	if (enable_lse)
1972 		command_flags = I40E_AQ_LSE_ENABLE;
1973 	else
1974 		command_flags = I40E_AQ_LSE_DISABLE;
1975 	resp->command_flags = CPU_TO_LE16(command_flags);
1976 
1977 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1978 
1979 	if (status != I40E_SUCCESS)
1980 		goto aq_get_link_info_exit;
1981 
1982 	/* save off old link status information */
1983 	i40e_memcpy(&hw->phy.link_info_old, hw_link_info,
1984 		    sizeof(*hw_link_info), I40E_NONDMA_TO_NONDMA);
1985 
1986 	/* update link status */
1987 	hw_link_info->phy_type = (enum i40e_aq_phy_type)resp->phy_type;
1988 	hw->phy.media_type = i40e_get_media_type(hw);
1989 	hw_link_info->link_speed = (enum i40e_aq_link_speed)resp->link_speed;
1990 	hw_link_info->link_info = resp->link_info;
1991 	hw_link_info->an_info = resp->an_info;
1992 	hw_link_info->fec_info = resp->config & (I40E_AQ_CONFIG_FEC_KR_ENA |
1993 						 I40E_AQ_CONFIG_FEC_RS_ENA);
1994 	hw_link_info->ext_info = resp->ext_info;
1995 	hw_link_info->loopback = resp->loopback & I40E_AQ_LOOPBACK_MASK;
1996 	hw_link_info->max_frame_size = LE16_TO_CPU(resp->max_frame_size);
1997 	hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
1998 
1999 	/* update fc info */
2000 	tx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_TX);
2001 	rx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_RX);
2002 	if (tx_pause & rx_pause)
2003 		hw->fc.current_mode = I40E_FC_FULL;
2004 	else if (tx_pause)
2005 		hw->fc.current_mode = I40E_FC_TX_PAUSE;
2006 	else if (rx_pause)
2007 		hw->fc.current_mode = I40E_FC_RX_PAUSE;
2008 	else
2009 		hw->fc.current_mode = I40E_FC_NONE;
2010 
2011 	if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
2012 		hw_link_info->crc_enable = TRUE;
2013 	else
2014 		hw_link_info->crc_enable = FALSE;
2015 
2016 	if (resp->command_flags & CPU_TO_LE16(I40E_AQ_LSE_IS_ENABLED))
2017 		hw_link_info->lse_enable = TRUE;
2018 	else
2019 		hw_link_info->lse_enable = FALSE;
2020 
2021 	if ((hw->mac.type == I40E_MAC_XL710) &&
2022 	    (hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
2023 	     hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
2024 		hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
2025 
2026 	/* 'Get Link Status' response data structure from X722 FW has
2027 	 * different format and does not contain this information
2028 	 */
2029 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE &&
2030 	    hw->mac.type != I40E_MAC_X722) {
2031 		__le32 tmp;
2032 
2033 		i40e_memcpy(&tmp, resp->link_type, sizeof(tmp),
2034 			    I40E_NONDMA_TO_NONDMA);
2035 		hw->phy.phy_types = LE32_TO_CPU(tmp);
2036 		hw->phy.phy_types |= ((u64)resp->link_type_ext << 32);
2037 	}
2038 
2039 	/* save link status information */
2040 	if (link)
2041 		i40e_memcpy(link, hw_link_info, sizeof(*hw_link_info),
2042 			    I40E_NONDMA_TO_NONDMA);
2043 
2044 	/* flag cleared so helper functions don't call AQ again */
2045 	hw->phy.get_link_info = FALSE;
2046 
2047 aq_get_link_info_exit:
2048 	return status;
2049 }
2050 
2051 /**
2052  * i40e_aq_set_phy_int_mask
2053  * @hw: pointer to the hw struct
2054  * @mask: interrupt mask to be set
2055  * @cmd_details: pointer to command details structure or NULL
2056  *
2057  * Set link interrupt mask.
2058  **/
i40e_aq_set_phy_int_mask(struct i40e_hw * hw,u16 mask,struct i40e_asq_cmd_details * cmd_details)2059 enum i40e_status_code i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
2060 				u16 mask,
2061 				struct i40e_asq_cmd_details *cmd_details)
2062 {
2063 	struct i40e_aq_desc desc;
2064 	struct i40e_aqc_set_phy_int_mask *cmd =
2065 		(struct i40e_aqc_set_phy_int_mask *)&desc.params.raw;
2066 	enum i40e_status_code status;
2067 
2068 	i40e_fill_default_direct_cmd_desc(&desc,
2069 					  i40e_aqc_opc_set_phy_int_mask);
2070 
2071 	cmd->event_mask = CPU_TO_LE16(mask);
2072 
2073 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2074 
2075 	return status;
2076 }
2077 
2078 /**
2079  * i40e_aq_get_local_advt_reg
2080  * @hw: pointer to the hw struct
2081  * @advt_reg: local AN advertisement register value
2082  * @cmd_details: pointer to command details structure or NULL
2083  *
2084  * Get the Local AN advertisement register value.
2085  **/
i40e_aq_get_local_advt_reg(struct i40e_hw * hw,u64 * advt_reg,struct i40e_asq_cmd_details * cmd_details)2086 enum i40e_status_code i40e_aq_get_local_advt_reg(struct i40e_hw *hw,
2087 				u64 *advt_reg,
2088 				struct i40e_asq_cmd_details *cmd_details)
2089 {
2090 	struct i40e_aq_desc desc;
2091 	struct i40e_aqc_an_advt_reg *resp =
2092 		(struct i40e_aqc_an_advt_reg *)&desc.params.raw;
2093 	enum i40e_status_code status;
2094 
2095 	i40e_fill_default_direct_cmd_desc(&desc,
2096 					  i40e_aqc_opc_get_local_advt_reg);
2097 
2098 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2099 
2100 	if (status != I40E_SUCCESS)
2101 		goto aq_get_local_advt_reg_exit;
2102 
2103 	*advt_reg = (u64)(LE16_TO_CPU(resp->local_an_reg1)) << 32;
2104 	*advt_reg |= LE32_TO_CPU(resp->local_an_reg0);
2105 
2106 aq_get_local_advt_reg_exit:
2107 	return status;
2108 }
2109 
2110 /**
2111  * i40e_aq_set_local_advt_reg
2112  * @hw: pointer to the hw struct
2113  * @advt_reg: local AN advertisement register value
2114  * @cmd_details: pointer to command details structure or NULL
2115  *
2116  * Get the Local AN advertisement register value.
2117  **/
i40e_aq_set_local_advt_reg(struct i40e_hw * hw,u64 advt_reg,struct i40e_asq_cmd_details * cmd_details)2118 enum i40e_status_code i40e_aq_set_local_advt_reg(struct i40e_hw *hw,
2119 				u64 advt_reg,
2120 				struct i40e_asq_cmd_details *cmd_details)
2121 {
2122 	struct i40e_aq_desc desc;
2123 	struct i40e_aqc_an_advt_reg *cmd =
2124 		(struct i40e_aqc_an_advt_reg *)&desc.params.raw;
2125 	enum i40e_status_code status;
2126 
2127 	i40e_fill_default_direct_cmd_desc(&desc,
2128 					  i40e_aqc_opc_get_local_advt_reg);
2129 
2130 	cmd->local_an_reg0 = CPU_TO_LE32(I40E_LO_DWORD(advt_reg));
2131 	cmd->local_an_reg1 = CPU_TO_LE16(I40E_HI_DWORD(advt_reg));
2132 
2133 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2134 
2135 	return status;
2136 }
2137 
2138 /**
2139  * i40e_aq_get_partner_advt
2140  * @hw: pointer to the hw struct
2141  * @advt_reg: AN partner advertisement register value
2142  * @cmd_details: pointer to command details structure or NULL
2143  *
2144  * Get the link partner AN advertisement register value.
2145  **/
i40e_aq_get_partner_advt(struct i40e_hw * hw,u64 * advt_reg,struct i40e_asq_cmd_details * cmd_details)2146 enum i40e_status_code i40e_aq_get_partner_advt(struct i40e_hw *hw,
2147 				u64 *advt_reg,
2148 				struct i40e_asq_cmd_details *cmd_details)
2149 {
2150 	struct i40e_aq_desc desc;
2151 	struct i40e_aqc_an_advt_reg *resp =
2152 		(struct i40e_aqc_an_advt_reg *)&desc.params.raw;
2153 	enum i40e_status_code status;
2154 
2155 	i40e_fill_default_direct_cmd_desc(&desc,
2156 					  i40e_aqc_opc_get_partner_advt);
2157 
2158 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2159 
2160 	if (status != I40E_SUCCESS)
2161 		goto aq_get_partner_advt_exit;
2162 
2163 	*advt_reg = (u64)(LE16_TO_CPU(resp->local_an_reg1)) << 32;
2164 	*advt_reg |= LE32_TO_CPU(resp->local_an_reg0);
2165 
2166 aq_get_partner_advt_exit:
2167 	return status;
2168 }
2169 
2170 /**
2171  * i40e_aq_set_lb_modes
2172  * @hw: pointer to the hw struct
2173  * @lb_modes: loopback mode to be set
2174  * @cmd_details: pointer to command details structure or NULL
2175  *
2176  * Sets loopback modes.
2177  **/
2178 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)2179 i40e_aq_set_lb_modes(struct i40e_hw *hw, u8 lb_level, u8 lb_type, u8 speed,
2180 		     struct i40e_asq_cmd_details *cmd_details)
2181 {
2182 	struct i40e_aq_desc desc;
2183 	struct i40e_aqc_set_lb_mode *cmd =
2184 		(struct i40e_aqc_set_lb_mode *)&desc.params.raw;
2185 	enum i40e_status_code status;
2186 
2187 	i40e_fill_default_direct_cmd_desc(&desc,
2188 					  i40e_aqc_opc_set_lb_modes);
2189 
2190 	cmd->lb_level = lb_level;
2191 	cmd->lb_type = lb_type;
2192 	cmd->speed = speed;
2193 	if (speed)
2194 		cmd->force_speed = 1;
2195 
2196 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2197 
2198 	return status;
2199 }
2200 
2201 /**
2202  * i40e_aq_set_phy_debug
2203  * @hw: pointer to the hw struct
2204  * @cmd_flags: debug command flags
2205  * @cmd_details: pointer to command details structure or NULL
2206  *
2207  * Reset the external PHY.
2208  **/
i40e_aq_set_phy_debug(struct i40e_hw * hw,u8 cmd_flags,struct i40e_asq_cmd_details * cmd_details)2209 enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
2210 				struct i40e_asq_cmd_details *cmd_details)
2211 {
2212 	struct i40e_aq_desc desc;
2213 	struct i40e_aqc_set_phy_debug *cmd =
2214 		(struct i40e_aqc_set_phy_debug *)&desc.params.raw;
2215 	enum i40e_status_code status;
2216 
2217 	i40e_fill_default_direct_cmd_desc(&desc,
2218 					  i40e_aqc_opc_set_phy_debug);
2219 
2220 	cmd->command_flags = cmd_flags;
2221 
2222 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2223 
2224 	return status;
2225 }
2226 
2227 /**
2228  * i40e_hw_ver_ge
2229  * @hw: pointer to the hw struct
2230  * @maj: api major value
2231  * @min: api minor value
2232  *
2233  * Assert whether current HW api version is greater/equal than provided.
2234  **/
i40e_hw_ver_ge(struct i40e_hw * hw,u16 maj,u16 min)2235 static bool i40e_hw_ver_ge(struct i40e_hw *hw, u16 maj, u16 min)
2236 {
2237 	if (hw->aq.api_maj_ver > maj ||
2238 	    (hw->aq.api_maj_ver == maj && hw->aq.api_min_ver >= min))
2239 		return TRUE;
2240 	return FALSE;
2241 }
2242 
2243 /**
2244  * i40e_aq_add_vsi
2245  * @hw: pointer to the hw struct
2246  * @vsi_ctx: pointer to a vsi context struct
2247  * @cmd_details: pointer to command details structure or NULL
2248  *
2249  * Add a VSI context to the hardware.
2250 **/
i40e_aq_add_vsi(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)2251 enum i40e_status_code i40e_aq_add_vsi(struct i40e_hw *hw,
2252 				struct i40e_vsi_context *vsi_ctx,
2253 				struct i40e_asq_cmd_details *cmd_details)
2254 {
2255 	struct i40e_aq_desc desc;
2256 	struct i40e_aqc_add_get_update_vsi *cmd =
2257 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2258 	struct i40e_aqc_add_get_update_vsi_completion *resp =
2259 		(struct i40e_aqc_add_get_update_vsi_completion *)
2260 		&desc.params.raw;
2261 	enum i40e_status_code status;
2262 
2263 	i40e_fill_default_direct_cmd_desc(&desc,
2264 					  i40e_aqc_opc_add_vsi);
2265 
2266 	cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->uplink_seid);
2267 	cmd->connection_type = vsi_ctx->connection_type;
2268 	cmd->vf_id = vsi_ctx->vf_num;
2269 	cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags);
2270 
2271 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2272 
2273 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2274 				       sizeof(vsi_ctx->info), cmd_details);
2275 
2276 	if (status != I40E_SUCCESS)
2277 		goto aq_add_vsi_exit;
2278 
2279 	vsi_ctx->seid = LE16_TO_CPU(resp->seid);
2280 	vsi_ctx->vsi_number = LE16_TO_CPU(resp->vsi_number);
2281 	vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
2282 	vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2283 
2284 aq_add_vsi_exit:
2285 	return status;
2286 }
2287 
2288 /**
2289  * i40e_aq_set_default_vsi
2290  * @hw: pointer to the hw struct
2291  * @seid: vsi number
2292  * @cmd_details: pointer to command details structure or NULL
2293  **/
i40e_aq_set_default_vsi(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)2294 enum i40e_status_code i40e_aq_set_default_vsi(struct i40e_hw *hw,
2295 				u16 seid,
2296 				struct i40e_asq_cmd_details *cmd_details)
2297 {
2298 	struct i40e_aq_desc desc;
2299 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2300 		(struct i40e_aqc_set_vsi_promiscuous_modes *)
2301 		&desc.params.raw;
2302 	enum i40e_status_code status;
2303 
2304 	i40e_fill_default_direct_cmd_desc(&desc,
2305 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2306 
2307 	cmd->promiscuous_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
2308 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
2309 	cmd->seid = CPU_TO_LE16(seid);
2310 
2311 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2312 
2313 	return status;
2314 }
2315 
2316 /**
2317  * i40e_aq_clear_default_vsi
2318  * @hw: pointer to the hw struct
2319  * @seid: vsi number
2320  * @cmd_details: pointer to command details structure or NULL
2321  **/
i40e_aq_clear_default_vsi(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)2322 enum i40e_status_code i40e_aq_clear_default_vsi(struct i40e_hw *hw,
2323 				u16 seid,
2324 				struct i40e_asq_cmd_details *cmd_details)
2325 {
2326 	struct i40e_aq_desc desc;
2327 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2328 		(struct i40e_aqc_set_vsi_promiscuous_modes *)
2329 		&desc.params.raw;
2330 	enum i40e_status_code status;
2331 
2332 	i40e_fill_default_direct_cmd_desc(&desc,
2333 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2334 
2335 	cmd->promiscuous_flags = CPU_TO_LE16(0);
2336 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
2337 	cmd->seid = CPU_TO_LE16(seid);
2338 
2339 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2340 
2341 	return status;
2342 }
2343 
2344 /**
2345  * i40e_aq_set_vsi_unicast_promiscuous
2346  * @hw: pointer to the hw struct
2347  * @seid: vsi number
2348  * @set: set unicast promiscuous enable/disable
2349  * @cmd_details: pointer to command details structure or NULL
2350  * @rx_only_promisc: flag to decide if egress traffic gets mirrored in promisc
2351  **/
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)2352 enum i40e_status_code i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
2353 				u16 seid, bool set,
2354 				struct i40e_asq_cmd_details *cmd_details,
2355 				bool rx_only_promisc)
2356 {
2357 	struct i40e_aq_desc desc;
2358 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2359 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2360 	enum i40e_status_code status;
2361 	u16 flags = 0;
2362 
2363 	i40e_fill_default_direct_cmd_desc(&desc,
2364 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2365 
2366 	if (set) {
2367 		flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2368 		if (rx_only_promisc && i40e_hw_ver_ge(hw, 1, 5))
2369 			flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
2370 	}
2371 
2372 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2373 
2374 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2375 	if (i40e_hw_ver_ge(hw, 1, 5))
2376 		cmd->valid_flags |=
2377 			CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
2378 
2379 	cmd->seid = CPU_TO_LE16(seid);
2380 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2381 
2382 	return status;
2383 }
2384 
2385 /**
2386  * i40e_aq_set_vsi_multicast_promiscuous
2387  * @hw: pointer to the hw struct
2388  * @seid: vsi number
2389  * @set: set multicast promiscuous enable/disable
2390  * @cmd_details: pointer to command details structure or NULL
2391  **/
i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw * hw,u16 seid,bool set,struct i40e_asq_cmd_details * cmd_details)2392 enum i40e_status_code i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
2393 				u16 seid, bool set, struct i40e_asq_cmd_details *cmd_details)
2394 {
2395 	struct i40e_aq_desc desc;
2396 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2397 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2398 	enum i40e_status_code status;
2399 	u16 flags = 0;
2400 
2401 	i40e_fill_default_direct_cmd_desc(&desc,
2402 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2403 
2404 	if (set)
2405 		flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2406 
2407 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2408 
2409 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2410 
2411 	cmd->seid = CPU_TO_LE16(seid);
2412 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2413 
2414 	return status;
2415 }
2416 
2417 /**
2418 * i40e_aq_set_vsi_full_promiscuous
2419 * @hw: pointer to the hw struct
2420 * @seid: VSI number
2421 * @set: set promiscuous enable/disable
2422 * @cmd_details: pointer to command details structure or NULL
2423 **/
i40e_aq_set_vsi_full_promiscuous(struct i40e_hw * hw,u16 seid,bool set,struct i40e_asq_cmd_details * cmd_details)2424 enum i40e_status_code i40e_aq_set_vsi_full_promiscuous(struct i40e_hw *hw,
2425 				u16 seid, bool set,
2426 				struct i40e_asq_cmd_details *cmd_details)
2427 {
2428 	struct i40e_aq_desc desc;
2429 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2430 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2431 	enum i40e_status_code status;
2432 	u16 flags = 0;
2433 
2434 	i40e_fill_default_direct_cmd_desc(&desc,
2435 		i40e_aqc_opc_set_vsi_promiscuous_modes);
2436 
2437 	if (set)
2438 		flags = I40E_AQC_SET_VSI_PROMISC_UNICAST   |
2439 			I40E_AQC_SET_VSI_PROMISC_MULTICAST |
2440 			I40E_AQC_SET_VSI_PROMISC_BROADCAST;
2441 
2442 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2443 
2444 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST   |
2445 				       I40E_AQC_SET_VSI_PROMISC_MULTICAST |
2446 				       I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2447 
2448 	cmd->seid = CPU_TO_LE16(seid);
2449 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2450 
2451 	return status;
2452 }
2453 
2454 /**
2455  * i40e_aq_set_vsi_mc_promisc_on_vlan
2456  * @hw: pointer to the hw struct
2457  * @seid: vsi number
2458  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2459  * @vid: The VLAN tag filter - capture any multicast packet with this VLAN tag
2460  * @cmd_details: pointer to command details structure or NULL
2461  **/
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)2462 enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
2463 				u16 seid, bool enable, u16 vid,
2464 				struct i40e_asq_cmd_details *cmd_details)
2465 {
2466 	struct i40e_aq_desc desc;
2467 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2468 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2469 	enum i40e_status_code status;
2470 	u16 flags = 0;
2471 
2472 	i40e_fill_default_direct_cmd_desc(&desc,
2473 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2474 
2475 	if (enable)
2476 		flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2477 
2478 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2479 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2480 	cmd->seid = CPU_TO_LE16(seid);
2481 	cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2482 
2483 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2484 
2485 	return status;
2486 }
2487 
2488 /**
2489  * i40e_aq_set_vsi_uc_promisc_on_vlan
2490  * @hw: pointer to the hw struct
2491  * @seid: vsi number
2492  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2493  * @vid: The VLAN tag filter - capture any unicast packet with this VLAN tag
2494  * @cmd_details: pointer to command details structure or NULL
2495  **/
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)2496 enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
2497 				u16 seid, bool enable, u16 vid,
2498 				struct i40e_asq_cmd_details *cmd_details)
2499 {
2500 	struct i40e_aq_desc desc;
2501 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2502 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2503 	enum i40e_status_code status;
2504 	u16 flags = 0;
2505 
2506 	i40e_fill_default_direct_cmd_desc(&desc,
2507 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2508 
2509 	if (enable) {
2510 		flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2511 		if (i40e_hw_ver_ge(hw, 1, 5))
2512 			flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
2513 	}
2514 
2515 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2516 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2517 	if (i40e_hw_ver_ge(hw, 1, 5))
2518 		cmd->valid_flags |=
2519 			CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
2520 	cmd->seid = CPU_TO_LE16(seid);
2521 	cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2522 
2523 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2524 
2525 	return status;
2526 }
2527 
2528 /**
2529  * i40e_aq_set_vsi_bc_promisc_on_vlan
2530  * @hw: pointer to the hw struct
2531  * @seid: vsi number
2532  * @enable: set broadcast promiscuous enable/disable for a given VLAN
2533  * @vid: The VLAN tag filter - capture any broadcast packet with this VLAN tag
2534  * @cmd_details: pointer to command details structure or NULL
2535  **/
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)2536 enum i40e_status_code i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
2537 				u16 seid, bool enable, u16 vid,
2538 				struct i40e_asq_cmd_details *cmd_details)
2539 {
2540 	struct i40e_aq_desc desc;
2541 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2542 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2543 	enum i40e_status_code status;
2544 	u16 flags = 0;
2545 
2546 	i40e_fill_default_direct_cmd_desc(&desc,
2547 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2548 
2549 	if (enable)
2550 		flags |= I40E_AQC_SET_VSI_PROMISC_BROADCAST;
2551 
2552 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2553 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2554 	cmd->seid = CPU_TO_LE16(seid);
2555 	cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2556 
2557 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2558 
2559 	return status;
2560 }
2561 
2562 /**
2563  * i40e_aq_set_vsi_broadcast
2564  * @hw: pointer to the hw struct
2565  * @seid: vsi number
2566  * @set_filter: TRUE to set filter, FALSE to clear filter
2567  * @cmd_details: pointer to command details structure or NULL
2568  *
2569  * Set or clear the broadcast promiscuous flag (filter) for a given VSI.
2570  **/
i40e_aq_set_vsi_broadcast(struct i40e_hw * hw,u16 seid,bool set_filter,struct i40e_asq_cmd_details * cmd_details)2571 enum i40e_status_code i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
2572 				u16 seid, bool set_filter,
2573 				struct i40e_asq_cmd_details *cmd_details)
2574 {
2575 	struct i40e_aq_desc desc;
2576 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2577 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2578 	enum i40e_status_code status;
2579 
2580 	i40e_fill_default_direct_cmd_desc(&desc,
2581 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2582 
2583 	if (set_filter)
2584 		cmd->promiscuous_flags
2585 			    |= CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2586 	else
2587 		cmd->promiscuous_flags
2588 			    &= CPU_TO_LE16(~I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2589 
2590 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2591 	cmd->seid = CPU_TO_LE16(seid);
2592 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2593 
2594 	return status;
2595 }
2596 
2597 /**
2598  * i40e_aq_set_vsi_vlan_promisc - control the VLAN promiscuous setting
2599  * @hw: pointer to the hw struct
2600  * @seid: vsi number
2601  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2602  * @cmd_details: pointer to command details structure or NULL
2603  **/
i40e_aq_set_vsi_vlan_promisc(struct i40e_hw * hw,u16 seid,bool enable,struct i40e_asq_cmd_details * cmd_details)2604 enum i40e_status_code i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
2605 				u16 seid, bool enable,
2606 				struct i40e_asq_cmd_details *cmd_details)
2607 {
2608 	struct i40e_aq_desc desc;
2609 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2610 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2611 	enum i40e_status_code status;
2612 	u16 flags = 0;
2613 
2614 	i40e_fill_default_direct_cmd_desc(&desc,
2615 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2616 	if (enable)
2617 		flags |= I40E_AQC_SET_VSI_PROMISC_VLAN;
2618 
2619 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2620 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_VLAN);
2621 	cmd->seid = CPU_TO_LE16(seid);
2622 
2623 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2624 
2625 	return status;
2626 }
2627 
2628 /**
2629  * i40e_aq_get_vsi_params - get VSI configuration info
2630  * @hw: pointer to the hw struct
2631  * @vsi_ctx: pointer to a vsi context struct
2632  * @cmd_details: pointer to command details structure or NULL
2633  **/
i40e_aq_get_vsi_params(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)2634 enum i40e_status_code i40e_aq_get_vsi_params(struct i40e_hw *hw,
2635 				struct i40e_vsi_context *vsi_ctx,
2636 				struct i40e_asq_cmd_details *cmd_details)
2637 {
2638 	struct i40e_aq_desc desc;
2639 	struct i40e_aqc_add_get_update_vsi *cmd =
2640 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2641 	struct i40e_aqc_add_get_update_vsi_completion *resp =
2642 		(struct i40e_aqc_add_get_update_vsi_completion *)
2643 		&desc.params.raw;
2644 	enum i40e_status_code status;
2645 
2646 	i40e_fill_default_direct_cmd_desc(&desc,
2647 					  i40e_aqc_opc_get_vsi_parameters);
2648 
2649 	cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->seid);
2650 
2651 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
2652 
2653 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2654 				    sizeof(vsi_ctx->info), NULL);
2655 
2656 	if (status != I40E_SUCCESS)
2657 		goto aq_get_vsi_params_exit;
2658 
2659 	vsi_ctx->seid = LE16_TO_CPU(resp->seid);
2660 	vsi_ctx->vsi_number = LE16_TO_CPU(resp->vsi_number);
2661 	vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
2662 	vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2663 
2664 aq_get_vsi_params_exit:
2665 	return status;
2666 }
2667 
2668 /**
2669  * i40e_aq_update_vsi_params
2670  * @hw: pointer to the hw struct
2671  * @vsi_ctx: pointer to a vsi context struct
2672  * @cmd_details: pointer to command details structure or NULL
2673  *
2674  * Update a VSI context.
2675  **/
i40e_aq_update_vsi_params(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)2676 enum i40e_status_code i40e_aq_update_vsi_params(struct i40e_hw *hw,
2677 				struct i40e_vsi_context *vsi_ctx,
2678 				struct i40e_asq_cmd_details *cmd_details)
2679 {
2680 	struct i40e_aq_desc desc;
2681 	struct i40e_aqc_add_get_update_vsi *cmd =
2682 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2683 	struct i40e_aqc_add_get_update_vsi_completion *resp =
2684 		(struct i40e_aqc_add_get_update_vsi_completion *)
2685 		&desc.params.raw;
2686 	enum i40e_status_code status;
2687 
2688 	i40e_fill_default_direct_cmd_desc(&desc,
2689 					  i40e_aqc_opc_update_vsi_parameters);
2690 	cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->seid);
2691 
2692 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2693 
2694 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2695 				       sizeof(vsi_ctx->info), cmd_details);
2696 
2697 	vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
2698 	vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2699 
2700 	return status;
2701 }
2702 
2703 /**
2704  * i40e_aq_get_switch_config
2705  * @hw: pointer to the hardware structure
2706  * @buf: pointer to the result buffer
2707  * @buf_size: length of input buffer
2708  * @start_seid: seid to start for the report, 0 == beginning
2709  * @cmd_details: pointer to command details structure or NULL
2710  *
2711  * Fill the buf with switch configuration returned from AdminQ command
2712  **/
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)2713 enum i40e_status_code i40e_aq_get_switch_config(struct i40e_hw *hw,
2714 				struct i40e_aqc_get_switch_config_resp *buf,
2715 				u16 buf_size, u16 *start_seid,
2716 				struct i40e_asq_cmd_details *cmd_details)
2717 {
2718 	struct i40e_aq_desc desc;
2719 	struct i40e_aqc_switch_seid *scfg =
2720 		(struct i40e_aqc_switch_seid *)&desc.params.raw;
2721 	enum i40e_status_code status;
2722 
2723 	i40e_fill_default_direct_cmd_desc(&desc,
2724 					  i40e_aqc_opc_get_switch_config);
2725 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
2726 	if (buf_size > I40E_AQ_LARGE_BUF)
2727 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
2728 	scfg->seid = CPU_TO_LE16(*start_seid);
2729 
2730 	status = i40e_asq_send_command(hw, &desc, buf, buf_size, cmd_details);
2731 	*start_seid = LE16_TO_CPU(scfg->seid);
2732 
2733 	return status;
2734 }
2735 
2736 /**
2737  * i40e_aq_set_switch_config
2738  * @hw: pointer to the hardware structure
2739  * @flags: bit flag values to set
2740  * @mode: cloud filter mode
2741  * @valid_flags: which bit flags to set
2742  * @cmd_details: pointer to command details structure or NULL
2743  *
2744  * Set switch configuration bits
2745  **/
i40e_aq_set_switch_config(struct i40e_hw * hw,u16 flags,u16 valid_flags,u8 mode,struct i40e_asq_cmd_details * cmd_details)2746 enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
2747 				u16 flags, u16 valid_flags, u8 mode,
2748 				struct i40e_asq_cmd_details *cmd_details)
2749 {
2750 	struct i40e_aq_desc desc;
2751 	struct i40e_aqc_set_switch_config *scfg =
2752 		(struct i40e_aqc_set_switch_config *)&desc.params.raw;
2753 	enum i40e_status_code status;
2754 
2755 	i40e_fill_default_direct_cmd_desc(&desc,
2756 					  i40e_aqc_opc_set_switch_config);
2757 	scfg->flags = CPU_TO_LE16(flags);
2758 	scfg->valid_flags = CPU_TO_LE16(valid_flags);
2759 	scfg->mode = mode;
2760 	if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
2761 		scfg->switch_tag = CPU_TO_LE16(hw->switch_tag);
2762 		scfg->first_tag = CPU_TO_LE16(hw->first_tag);
2763 		scfg->second_tag = CPU_TO_LE16(hw->second_tag);
2764 	}
2765 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2766 
2767 	return status;
2768 }
2769 
2770 /**
2771  * i40e_aq_get_firmware_version
2772  * @hw: pointer to the hw struct
2773  * @fw_major_version: firmware major version
2774  * @fw_minor_version: firmware minor version
2775  * @fw_build: firmware build number
2776  * @api_major_version: major queue version
2777  * @api_minor_version: minor queue version
2778  * @cmd_details: pointer to command details structure or NULL
2779  *
2780  * Get the firmware version from the admin queue commands
2781  **/
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)2782 enum i40e_status_code i40e_aq_get_firmware_version(struct i40e_hw *hw,
2783 				u16 *fw_major_version, u16 *fw_minor_version,
2784 				u32 *fw_build,
2785 				u16 *api_major_version, u16 *api_minor_version,
2786 				struct i40e_asq_cmd_details *cmd_details)
2787 {
2788 	struct i40e_aq_desc desc;
2789 	struct i40e_aqc_get_version *resp =
2790 		(struct i40e_aqc_get_version *)&desc.params.raw;
2791 	enum i40e_status_code status;
2792 
2793 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_version);
2794 
2795 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2796 
2797 	if (status == I40E_SUCCESS) {
2798 		if (fw_major_version != NULL)
2799 			*fw_major_version = LE16_TO_CPU(resp->fw_major);
2800 		if (fw_minor_version != NULL)
2801 			*fw_minor_version = LE16_TO_CPU(resp->fw_minor);
2802 		if (fw_build != NULL)
2803 			*fw_build = LE32_TO_CPU(resp->fw_build);
2804 		if (api_major_version != NULL)
2805 			*api_major_version = LE16_TO_CPU(resp->api_major);
2806 		if (api_minor_version != NULL)
2807 			*api_minor_version = LE16_TO_CPU(resp->api_minor);
2808 
2809 		/* A workaround to fix the API version in SW */
2810 		if (api_major_version && api_minor_version &&
2811 		    fw_major_version && fw_minor_version &&
2812 		    ((*api_major_version == 1) && (*api_minor_version == 1)) &&
2813 		    (((*fw_major_version == 4) && (*fw_minor_version >= 2)) ||
2814 		     (*fw_major_version > 4)))
2815 			*api_minor_version = 2;
2816 	}
2817 
2818 	return status;
2819 }
2820 
2821 /**
2822  * i40e_aq_send_driver_version
2823  * @hw: pointer to the hw struct
2824  * @dv: driver's major, minor version
2825  * @cmd_details: pointer to command details structure or NULL
2826  *
2827  * Send the driver version to the firmware
2828  **/
i40e_aq_send_driver_version(struct i40e_hw * hw,struct i40e_driver_version * dv,struct i40e_asq_cmd_details * cmd_details)2829 enum i40e_status_code i40e_aq_send_driver_version(struct i40e_hw *hw,
2830 				struct i40e_driver_version *dv,
2831 				struct i40e_asq_cmd_details *cmd_details)
2832 {
2833 	struct i40e_aq_desc desc;
2834 	struct i40e_aqc_driver_version *cmd =
2835 		(struct i40e_aqc_driver_version *)&desc.params.raw;
2836 	enum i40e_status_code status;
2837 	u16 len;
2838 
2839 	if (dv == NULL)
2840 		return I40E_ERR_PARAM;
2841 
2842 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_driver_version);
2843 
2844 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
2845 	cmd->driver_major_ver = dv->major_version;
2846 	cmd->driver_minor_ver = dv->minor_version;
2847 	cmd->driver_build_ver = dv->build_version;
2848 	cmd->driver_subbuild_ver = dv->subbuild_version;
2849 
2850 	len = 0;
2851 	while (len < sizeof(dv->driver_string) &&
2852 	       (dv->driver_string[len] < 0x80) &&
2853 	       dv->driver_string[len])
2854 		len++;
2855 	status = i40e_asq_send_command(hw, &desc, dv->driver_string,
2856 				       len, cmd_details);
2857 
2858 	return status;
2859 }
2860 
2861 /**
2862  * i40e_get_link_status - get status of the HW network link
2863  * @hw: pointer to the hw struct
2864  * @link_up: pointer to bool (TRUE/FALSE = linkup/linkdown)
2865  *
2866  * Variable link_up TRUE if link is up, FALSE if link is down.
2867  * The variable link_up is invalid if returned value of status != I40E_SUCCESS
2868  *
2869  * Side effect: LinkStatusEvent reporting becomes enabled
2870  **/
i40e_get_link_status(struct i40e_hw * hw,bool * link_up)2871 enum i40e_status_code i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
2872 {
2873 	enum i40e_status_code status = I40E_SUCCESS;
2874 
2875 	if (hw->phy.get_link_info) {
2876 		status = i40e_update_link_info(hw);
2877 
2878 		if (status != I40E_SUCCESS)
2879 			i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
2880 				   status);
2881 	}
2882 
2883 	*link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
2884 
2885 	return status;
2886 }
2887 
2888 /**
2889  * i40e_update_link_info - update status of the HW network link
2890  * @hw: pointer to the hw struct
2891  **/
i40e_update_link_info(struct i40e_hw * hw)2892 enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw)
2893 {
2894 	struct i40e_aq_get_phy_abilities_resp abilities;
2895 	enum i40e_status_code status = I40E_SUCCESS;
2896 
2897 	status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
2898 	if (status)
2899 		return status;
2900 
2901 	/* extra checking needed to ensure link info to user is timely */
2902 	if (((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) &&
2903 	     ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) ||
2904 	      !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) ||
2905 	    hw->mac.type == I40E_MAC_X722) {
2906 		status = i40e_aq_get_phy_capabilities(hw, FALSE,
2907 						      hw->mac.type ==
2908 						      I40E_MAC_X722,
2909 						      &abilities, NULL);
2910 		if (status)
2911 			return status;
2912 
2913 		if (abilities.fec_cfg_curr_mod_ext_info &
2914 		    I40E_AQ_ENABLE_FEC_AUTO)
2915 			hw->phy.link_info.req_fec_info =
2916 				(I40E_AQ_REQUEST_FEC_KR |
2917 				 I40E_AQ_REQUEST_FEC_RS);
2918 		else
2919 			hw->phy.link_info.req_fec_info =
2920 				abilities.fec_cfg_curr_mod_ext_info &
2921 				(I40E_AQ_REQUEST_FEC_KR |
2922 				 I40E_AQ_REQUEST_FEC_RS);
2923 
2924 		i40e_memcpy(hw->phy.link_info.module_type, &abilities.module_type,
2925 			sizeof(hw->phy.link_info.module_type), I40E_NONDMA_TO_NONDMA);
2926 	}
2927 	return status;
2928 }
2929 
2930 
2931 /**
2932  * i40e_get_link_speed
2933  * @hw: pointer to the hw struct
2934  *
2935  * Returns the link speed of the adapter.
2936  **/
i40e_get_link_speed(struct i40e_hw * hw)2937 enum i40e_aq_link_speed i40e_get_link_speed(struct i40e_hw *hw)
2938 {
2939 	enum i40e_aq_link_speed speed = I40E_LINK_SPEED_UNKNOWN;
2940 	enum i40e_status_code status = I40E_SUCCESS;
2941 
2942 	if (hw->phy.get_link_info) {
2943 		status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
2944 
2945 		if (status != I40E_SUCCESS)
2946 			goto i40e_link_speed_exit;
2947 	}
2948 
2949 	speed = hw->phy.link_info.link_speed;
2950 
2951 i40e_link_speed_exit:
2952 	return speed;
2953 }
2954 
2955 /**
2956  * i40e_aq_add_veb - Insert a VEB between the VSI and the MAC
2957  * @hw: pointer to the hw struct
2958  * @uplink_seid: the MAC or other gizmo SEID
2959  * @downlink_seid: the VSI SEID
2960  * @enabled_tc: bitmap of TCs to be enabled
2961  * @default_port: TRUE for default port VSI, FALSE for control port
2962  * @veb_seid: pointer to where to put the resulting VEB SEID
2963  * @enable_stats: TRUE to turn on VEB stats
2964  * @cmd_details: pointer to command details structure or NULL
2965  *
2966  * This asks the FW to add a VEB between the uplink and downlink
2967  * elements.  If the uplink SEID is 0, this will be a floating VEB.
2968  **/
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)2969 enum i40e_status_code i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
2970 				u16 downlink_seid, u8 enabled_tc,
2971 				bool default_port, u16 *veb_seid,
2972 				bool enable_stats,
2973 				struct i40e_asq_cmd_details *cmd_details)
2974 {
2975 	struct i40e_aq_desc desc;
2976 	struct i40e_aqc_add_veb *cmd =
2977 		(struct i40e_aqc_add_veb *)&desc.params.raw;
2978 	struct i40e_aqc_add_veb_completion *resp =
2979 		(struct i40e_aqc_add_veb_completion *)&desc.params.raw;
2980 	enum i40e_status_code status;
2981 	u16 veb_flags = 0;
2982 
2983 	/* SEIDs need to either both be set or both be 0 for floating VEB */
2984 	if (!!uplink_seid != !!downlink_seid)
2985 		return I40E_ERR_PARAM;
2986 
2987 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_veb);
2988 
2989 	cmd->uplink_seid = CPU_TO_LE16(uplink_seid);
2990 	cmd->downlink_seid = CPU_TO_LE16(downlink_seid);
2991 	cmd->enable_tcs = enabled_tc;
2992 	if (!uplink_seid)
2993 		veb_flags |= I40E_AQC_ADD_VEB_FLOATING;
2994 	if (default_port)
2995 		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT;
2996 	else
2997 		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;
2998 
2999 	/* reverse logic here: set the bitflag to disable the stats */
3000 	if (!enable_stats)
3001 		veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;
3002 
3003 	cmd->veb_flags = CPU_TO_LE16(veb_flags);
3004 
3005 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3006 
3007 	if (!status && veb_seid)
3008 		*veb_seid = LE16_TO_CPU(resp->veb_seid);
3009 
3010 	return status;
3011 }
3012 
3013 /**
3014  * i40e_aq_get_veb_parameters - Retrieve VEB parameters
3015  * @hw: pointer to the hw struct
3016  * @veb_seid: the SEID of the VEB to query
3017  * @switch_id: the uplink switch id
3018  * @floating: set to TRUE if the VEB is floating
3019  * @statistic_index: index of the stats counter block for this VEB
3020  * @vebs_used: number of VEB's used by function
3021  * @vebs_free: total VEB's not reserved by any function
3022  * @cmd_details: pointer to command details structure or NULL
3023  *
3024  * This retrieves the parameters for a particular VEB, specified by
3025  * uplink_seid, and returns them to the caller.
3026  **/
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)3027 enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw,
3028 				u16 veb_seid, u16 *switch_id,
3029 				bool *floating, u16 *statistic_index,
3030 				u16 *vebs_used, u16 *vebs_free,
3031 				struct i40e_asq_cmd_details *cmd_details)
3032 {
3033 	struct i40e_aq_desc desc;
3034 	struct i40e_aqc_get_veb_parameters_completion *cmd_resp =
3035 		(struct i40e_aqc_get_veb_parameters_completion *)
3036 		&desc.params.raw;
3037 	enum i40e_status_code status;
3038 
3039 	if (veb_seid == 0)
3040 		return I40E_ERR_PARAM;
3041 
3042 	i40e_fill_default_direct_cmd_desc(&desc,
3043 					  i40e_aqc_opc_get_veb_parameters);
3044 	cmd_resp->seid = CPU_TO_LE16(veb_seid);
3045 
3046 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3047 	if (status)
3048 		goto get_veb_exit;
3049 
3050 	if (switch_id)
3051 		*switch_id = LE16_TO_CPU(cmd_resp->switch_id);
3052 	if (statistic_index)
3053 		*statistic_index = LE16_TO_CPU(cmd_resp->statistic_index);
3054 	if (vebs_used)
3055 		*vebs_used = LE16_TO_CPU(cmd_resp->vebs_used);
3056 	if (vebs_free)
3057 		*vebs_free = LE16_TO_CPU(cmd_resp->vebs_free);
3058 	if (floating) {
3059 		u16 flags = LE16_TO_CPU(cmd_resp->veb_flags);
3060 
3061 		if (flags & I40E_AQC_ADD_VEB_FLOATING)
3062 			*floating = TRUE;
3063 		else
3064 			*floating = FALSE;
3065 	}
3066 
3067 get_veb_exit:
3068 	return status;
3069 }
3070 
3071 /**
3072  * i40e_aq_add_macvlan
3073  * @hw: pointer to the hw struct
3074  * @seid: VSI for the mac address
3075  * @mv_list: list of macvlans to be added
3076  * @count: length of the list
3077  * @cmd_details: pointer to command details structure or NULL
3078  *
3079  * Add MAC/VLAN addresses to the HW filtering
3080  **/
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)3081 enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
3082 			struct i40e_aqc_add_macvlan_element_data *mv_list,
3083 			u16 count, struct i40e_asq_cmd_details *cmd_details)
3084 {
3085 	struct i40e_aq_desc desc;
3086 	struct i40e_aqc_macvlan *cmd =
3087 		(struct i40e_aqc_macvlan *)&desc.params.raw;
3088 	enum i40e_status_code status;
3089 	u16 buf_size;
3090 	int i;
3091 
3092 	if (count == 0 || !mv_list || !hw)
3093 		return I40E_ERR_PARAM;
3094 
3095 	buf_size = count * sizeof(*mv_list);
3096 
3097 	/* prep the rest of the request */
3098 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
3099 	cmd->num_addresses = CPU_TO_LE16(count);
3100 	cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
3101 	cmd->seid[1] = 0;
3102 	cmd->seid[2] = 0;
3103 
3104 	for (i = 0; i < count; i++)
3105 		if (I40E_IS_MULTICAST(mv_list[i].mac_addr))
3106 			mv_list[i].flags |=
3107 			    CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
3108 
3109 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3110 	if (buf_size > I40E_AQ_LARGE_BUF)
3111 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3112 
3113 	status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
3114 				       cmd_details);
3115 
3116 	return status;
3117 }
3118 
3119 /**
3120  * i40e_aq_remove_macvlan
3121  * @hw: pointer to the hw struct
3122  * @seid: VSI for the mac address
3123  * @mv_list: list of macvlans to be removed
3124  * @count: length of the list
3125  * @cmd_details: pointer to command details structure or NULL
3126  *
3127  * Remove MAC/VLAN addresses from the HW filtering
3128  **/
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)3129 enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
3130 			struct i40e_aqc_remove_macvlan_element_data *mv_list,
3131 			u16 count, struct i40e_asq_cmd_details *cmd_details)
3132 {
3133 	struct i40e_aq_desc desc;
3134 	struct i40e_aqc_macvlan *cmd =
3135 		(struct i40e_aqc_macvlan *)&desc.params.raw;
3136 	enum i40e_status_code status;
3137 	u16 buf_size;
3138 
3139 	if (count == 0 || !mv_list || !hw)
3140 		return I40E_ERR_PARAM;
3141 
3142 	buf_size = count * sizeof(*mv_list);
3143 
3144 	/* prep the rest of the request */
3145 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
3146 	cmd->num_addresses = CPU_TO_LE16(count);
3147 	cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
3148 	cmd->seid[1] = 0;
3149 	cmd->seid[2] = 0;
3150 
3151 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3152 	if (buf_size > I40E_AQ_LARGE_BUF)
3153 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3154 
3155 	status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
3156 				       cmd_details);
3157 
3158 	return status;
3159 }
3160 
3161 /**
3162  * i40e_mirrorrule_op - Internal helper function to add/delete mirror rule
3163  * @hw: pointer to the hw struct
3164  * @opcode: AQ opcode for add or delete mirror rule
3165  * @sw_seid: Switch SEID (to which rule refers)
3166  * @rule_type: Rule Type (ingress/egress/VLAN)
3167  * @id: Destination VSI SEID or Rule ID
3168  * @count: length of the list
3169  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
3170  * @cmd_details: pointer to command details structure or NULL
3171  * @rule_id: Rule ID returned from FW
3172  * @rules_used: Number of rules used in internal switch
3173  * @rules_free: Number of rules free in internal switch
3174  *
3175  * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
3176  * VEBs/VEPA elements only
3177  **/
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)3178 static enum i40e_status_code i40e_mirrorrule_op(struct i40e_hw *hw,
3179 			u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
3180 			u16 count, __le16 *mr_list,
3181 			struct i40e_asq_cmd_details *cmd_details,
3182 			u16 *rule_id, u16 *rules_used, u16 *rules_free)
3183 {
3184 	struct i40e_aq_desc desc;
3185 	struct i40e_aqc_add_delete_mirror_rule *cmd =
3186 		(struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
3187 	struct i40e_aqc_add_delete_mirror_rule_completion *resp =
3188 	(struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
3189 	enum i40e_status_code status;
3190 	u16 buf_size;
3191 
3192 	buf_size = count * sizeof(*mr_list);
3193 
3194 	/* prep the rest of the request */
3195 	i40e_fill_default_direct_cmd_desc(&desc, opcode);
3196 	cmd->seid = CPU_TO_LE16(sw_seid);
3197 	cmd->rule_type = CPU_TO_LE16(rule_type &
3198 				     I40E_AQC_MIRROR_RULE_TYPE_MASK);
3199 	cmd->num_entries = CPU_TO_LE16(count);
3200 	/* Dest VSI for add, rule_id for delete */
3201 	cmd->destination = CPU_TO_LE16(id);
3202 	if (mr_list) {
3203 		desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
3204 						I40E_AQ_FLAG_RD));
3205 		if (buf_size > I40E_AQ_LARGE_BUF)
3206 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3207 	}
3208 
3209 	status = i40e_asq_send_command(hw, &desc, mr_list, buf_size,
3210 				       cmd_details);
3211 	if (status == I40E_SUCCESS ||
3212 	    hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) {
3213 		if (rule_id)
3214 			*rule_id = LE16_TO_CPU(resp->rule_id);
3215 		if (rules_used)
3216 			*rules_used = LE16_TO_CPU(resp->mirror_rules_used);
3217 		if (rules_free)
3218 			*rules_free = LE16_TO_CPU(resp->mirror_rules_free);
3219 	}
3220 	return status;
3221 }
3222 
3223 /**
3224  * i40e_aq_add_mirrorrule - add a mirror rule
3225  * @hw: pointer to the hw struct
3226  * @sw_seid: Switch SEID (to which rule refers)
3227  * @rule_type: Rule Type (ingress/egress/VLAN)
3228  * @dest_vsi: SEID of VSI to which packets will be mirrored
3229  * @count: length of the list
3230  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
3231  * @cmd_details: pointer to command details structure or NULL
3232  * @rule_id: Rule ID returned from FW
3233  * @rules_used: Number of rules used in internal switch
3234  * @rules_free: Number of rules free in internal switch
3235  *
3236  * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
3237  **/
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)3238 enum i40e_status_code i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
3239 			u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
3240 			struct i40e_asq_cmd_details *cmd_details,
3241 			u16 *rule_id, u16 *rules_used, u16 *rules_free)
3242 {
3243 	if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
3244 	    rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
3245 		if (count == 0 || !mr_list)
3246 			return I40E_ERR_PARAM;
3247 	}
3248 
3249 	return i40e_mirrorrule_op(hw, i40e_aqc_opc_add_mirror_rule, sw_seid,
3250 				  rule_type, dest_vsi, count, mr_list,
3251 				  cmd_details, rule_id, rules_used, rules_free);
3252 }
3253 
3254 /**
3255  * i40e_aq_delete_mirrorrule - delete a mirror rule
3256  * @hw: pointer to the hw struct
3257  * @sw_seid: Switch SEID (to which rule refers)
3258  * @rule_type: Rule Type (ingress/egress/VLAN)
3259  * @count: length of the list
3260  * @rule_id: Rule ID that is returned in the receive desc as part of
3261  *		add_mirrorrule.
3262  * @mr_list: list of mirrored VLAN IDs to be removed
3263  * @cmd_details: pointer to command details structure or NULL
3264  * @rules_used: Number of rules used in internal switch
3265  * @rules_free: Number of rules free in internal switch
3266  *
3267  * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
3268  **/
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)3269 enum i40e_status_code i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
3270 			u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
3271 			struct i40e_asq_cmd_details *cmd_details,
3272 			u16 *rules_used, u16 *rules_free)
3273 {
3274 	/* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
3275 	if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
3276 		/* count and mr_list shall be valid for rule_type INGRESS VLAN
3277 		 * mirroring. For other rule_type, count and rule_type should
3278 		 * not matter.
3279 		 */
3280 		if (count == 0 || !mr_list)
3281 			return I40E_ERR_PARAM;
3282 	}
3283 
3284 	return i40e_mirrorrule_op(hw, i40e_aqc_opc_delete_mirror_rule, sw_seid,
3285 				  rule_type, rule_id, count, mr_list,
3286 				  cmd_details, NULL, rules_used, rules_free);
3287 }
3288 
3289 /**
3290  * i40e_aq_add_vlan - Add VLAN ids to the HW filtering
3291  * @hw: pointer to the hw struct
3292  * @seid: VSI for the vlan filters
3293  * @v_list: list of vlan filters to be added
3294  * @count: length of the list
3295  * @cmd_details: pointer to command details structure or NULL
3296  **/
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)3297 enum i40e_status_code i40e_aq_add_vlan(struct i40e_hw *hw, u16 seid,
3298 			struct i40e_aqc_add_remove_vlan_element_data *v_list,
3299 			u8 count, struct i40e_asq_cmd_details *cmd_details)
3300 {
3301 	struct i40e_aq_desc desc;
3302 	struct i40e_aqc_macvlan *cmd =
3303 		(struct i40e_aqc_macvlan *)&desc.params.raw;
3304 	enum i40e_status_code status;
3305 	u16 buf_size;
3306 
3307 	if (count == 0 || !v_list || !hw)
3308 		return I40E_ERR_PARAM;
3309 
3310 	buf_size = count * sizeof(*v_list);
3311 
3312 	/* prep the rest of the request */
3313 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_vlan);
3314 	cmd->num_addresses = CPU_TO_LE16(count);
3315 	cmd->seid[0] = CPU_TO_LE16(seid | I40E_AQC_MACVLAN_CMD_SEID_VALID);
3316 	cmd->seid[1] = 0;
3317 	cmd->seid[2] = 0;
3318 
3319 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3320 	if (buf_size > I40E_AQ_LARGE_BUF)
3321 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3322 
3323 	status = i40e_asq_send_command(hw, &desc, v_list, buf_size,
3324 				       cmd_details);
3325 
3326 	return status;
3327 }
3328 
3329 /**
3330  * i40e_aq_remove_vlan - Remove VLANs from the HW filtering
3331  * @hw: pointer to the hw struct
3332  * @seid: VSI for the vlan filters
3333  * @v_list: list of macvlans to be removed
3334  * @count: length of the list
3335  * @cmd_details: pointer to command details structure or NULL
3336  **/
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)3337 enum i40e_status_code i40e_aq_remove_vlan(struct i40e_hw *hw, u16 seid,
3338 			struct i40e_aqc_add_remove_vlan_element_data *v_list,
3339 			u8 count, struct i40e_asq_cmd_details *cmd_details)
3340 {
3341 	struct i40e_aq_desc desc;
3342 	struct i40e_aqc_macvlan *cmd =
3343 		(struct i40e_aqc_macvlan *)&desc.params.raw;
3344 	enum i40e_status_code status;
3345 	u16 buf_size;
3346 
3347 	if (count == 0 || !v_list || !hw)
3348 		return I40E_ERR_PARAM;
3349 
3350 	buf_size = count * sizeof(*v_list);
3351 
3352 	/* prep the rest of the request */
3353 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_vlan);
3354 	cmd->num_addresses = CPU_TO_LE16(count);
3355 	cmd->seid[0] = CPU_TO_LE16(seid | I40E_AQC_MACVLAN_CMD_SEID_VALID);
3356 	cmd->seid[1] = 0;
3357 	cmd->seid[2] = 0;
3358 
3359 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3360 	if (buf_size > I40E_AQ_LARGE_BUF)
3361 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3362 
3363 	status = i40e_asq_send_command(hw, &desc, v_list, buf_size,
3364 				       cmd_details);
3365 
3366 	return status;
3367 }
3368 
3369 /**
3370  * i40e_aq_send_msg_to_vf
3371  * @hw: pointer to the hardware structure
3372  * @vfid: vf id to send msg
3373  * @v_opcode: opcodes for VF-PF communication
3374  * @v_retval: return error code
3375  * @msg: pointer to the msg buffer
3376  * @msglen: msg length
3377  * @cmd_details: pointer to command details
3378  *
3379  * send msg to vf
3380  **/
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)3381 enum i40e_status_code i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
3382 				u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
3383 				struct i40e_asq_cmd_details *cmd_details)
3384 {
3385 	struct i40e_aq_desc desc;
3386 	struct i40e_aqc_pf_vf_message *cmd =
3387 		(struct i40e_aqc_pf_vf_message *)&desc.params.raw;
3388 	enum i40e_status_code status;
3389 
3390 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_vf);
3391 	cmd->id = CPU_TO_LE32(vfid);
3392 	desc.cookie_high = CPU_TO_LE32(v_opcode);
3393 	desc.cookie_low = CPU_TO_LE32(v_retval);
3394 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
3395 	if (msglen) {
3396 		desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
3397 						I40E_AQ_FLAG_RD));
3398 		if (msglen > I40E_AQ_LARGE_BUF)
3399 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3400 		desc.datalen = CPU_TO_LE16(msglen);
3401 	}
3402 	status = i40e_asq_send_command(hw, &desc, msg, msglen, cmd_details);
3403 
3404 	return status;
3405 }
3406 
3407 /**
3408  * i40e_aq_debug_read_register
3409  * @hw: pointer to the hw struct
3410  * @reg_addr: register address
3411  * @reg_val: register value
3412  * @cmd_details: pointer to command details structure or NULL
3413  *
3414  * Read the register using the admin queue commands
3415  **/
i40e_aq_debug_read_register(struct i40e_hw * hw,u32 reg_addr,u64 * reg_val,struct i40e_asq_cmd_details * cmd_details)3416 enum i40e_status_code i40e_aq_debug_read_register(struct i40e_hw *hw,
3417 				u32 reg_addr, u64 *reg_val,
3418 				struct i40e_asq_cmd_details *cmd_details)
3419 {
3420 	struct i40e_aq_desc desc;
3421 	struct i40e_aqc_debug_reg_read_write *cmd_resp =
3422 		(struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3423 	enum i40e_status_code status;
3424 
3425 	if (reg_val == NULL)
3426 		return I40E_ERR_PARAM;
3427 
3428 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
3429 
3430 	cmd_resp->address = CPU_TO_LE32(reg_addr);
3431 
3432 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3433 
3434 	if (status == I40E_SUCCESS) {
3435 		*reg_val = ((u64)LE32_TO_CPU(cmd_resp->value_high) << 32) |
3436 			   (u64)LE32_TO_CPU(cmd_resp->value_low);
3437 	}
3438 
3439 	return status;
3440 }
3441 
3442 /**
3443  * i40e_aq_debug_write_register
3444  * @hw: pointer to the hw struct
3445  * @reg_addr: register address
3446  * @reg_val: register value
3447  * @cmd_details: pointer to command details structure or NULL
3448  *
3449  * Write to a register using the admin queue commands
3450  **/
i40e_aq_debug_write_register(struct i40e_hw * hw,u32 reg_addr,u64 reg_val,struct i40e_asq_cmd_details * cmd_details)3451 enum i40e_status_code i40e_aq_debug_write_register(struct i40e_hw *hw,
3452 				u32 reg_addr, u64 reg_val,
3453 				struct i40e_asq_cmd_details *cmd_details)
3454 {
3455 	struct i40e_aq_desc desc;
3456 	struct i40e_aqc_debug_reg_read_write *cmd =
3457 		(struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3458 	enum i40e_status_code status;
3459 
3460 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_write_reg);
3461 
3462 	cmd->address = CPU_TO_LE32(reg_addr);
3463 	cmd->value_high = CPU_TO_LE32((u32)(reg_val >> 32));
3464 	cmd->value_low = CPU_TO_LE32((u32)(reg_val & 0xFFFFFFFF));
3465 
3466 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3467 
3468 	return status;
3469 }
3470 
3471 /**
3472  * i40e_aq_request_resource
3473  * @hw: pointer to the hw struct
3474  * @resource: resource id
3475  * @access: access type
3476  * @sdp_number: resource number
3477  * @timeout: the maximum time in ms that the driver may hold the resource
3478  * @cmd_details: pointer to command details structure or NULL
3479  *
3480  * requests common resource using the admin queue commands
3481  **/
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)3482 enum i40e_status_code i40e_aq_request_resource(struct i40e_hw *hw,
3483 				enum i40e_aq_resources_ids resource,
3484 				enum i40e_aq_resource_access_type access,
3485 				u8 sdp_number, u64 *timeout,
3486 				struct i40e_asq_cmd_details *cmd_details)
3487 {
3488 	struct i40e_aq_desc desc;
3489 	struct i40e_aqc_request_resource *cmd_resp =
3490 		(struct i40e_aqc_request_resource *)&desc.params.raw;
3491 	enum i40e_status_code status;
3492 
3493 	DEBUGFUNC("i40e_aq_request_resource");
3494 
3495 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_request_resource);
3496 
3497 	cmd_resp->resource_id = CPU_TO_LE16(resource);
3498 	cmd_resp->access_type = CPU_TO_LE16(access);
3499 	cmd_resp->resource_number = CPU_TO_LE32(sdp_number);
3500 
3501 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3502 	/* The completion specifies the maximum time in ms that the driver
3503 	 * may hold the resource in the Timeout field.
3504 	 * If the resource is held by someone else, the command completes with
3505 	 * busy return value and the timeout field indicates the maximum time
3506 	 * the current owner of the resource has to free it.
3507 	 */
3508 	if (status == I40E_SUCCESS || hw->aq.asq_last_status == I40E_AQ_RC_EBUSY)
3509 		*timeout = LE32_TO_CPU(cmd_resp->timeout);
3510 
3511 	return status;
3512 }
3513 
3514 /**
3515  * i40e_aq_release_resource
3516  * @hw: pointer to the hw struct
3517  * @resource: resource id
3518  * @sdp_number: resource number
3519  * @cmd_details: pointer to command details structure or NULL
3520  *
3521  * release common resource using the admin queue commands
3522  **/
i40e_aq_release_resource(struct i40e_hw * hw,enum i40e_aq_resources_ids resource,u8 sdp_number,struct i40e_asq_cmd_details * cmd_details)3523 enum i40e_status_code i40e_aq_release_resource(struct i40e_hw *hw,
3524 				enum i40e_aq_resources_ids resource,
3525 				u8 sdp_number,
3526 				struct i40e_asq_cmd_details *cmd_details)
3527 {
3528 	struct i40e_aq_desc desc;
3529 	struct i40e_aqc_request_resource *cmd =
3530 		(struct i40e_aqc_request_resource *)&desc.params.raw;
3531 	enum i40e_status_code status;
3532 
3533 	DEBUGFUNC("i40e_aq_release_resource");
3534 
3535 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_release_resource);
3536 
3537 	cmd->resource_id = CPU_TO_LE16(resource);
3538 	cmd->resource_number = CPU_TO_LE32(sdp_number);
3539 
3540 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3541 
3542 	return status;
3543 }
3544 
3545 /**
3546  * i40e_aq_read_nvm
3547  * @hw: pointer to the hw struct
3548  * @module_pointer: module pointer location in words from the NVM beginning
3549  * @offset: byte offset from the module beginning
3550  * @length: length of the section to be read (in bytes from the offset)
3551  * @data: command buffer (size [bytes] = length)
3552  * @last_command: tells if this is the last command in a series
3553  * @cmd_details: pointer to command details structure or NULL
3554  *
3555  * Read the NVM using the admin queue commands
3556  **/
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)3557 enum i40e_status_code i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
3558 				u32 offset, u16 length, void *data,
3559 				bool last_command,
3560 				struct i40e_asq_cmd_details *cmd_details)
3561 {
3562 	struct i40e_aq_desc desc;
3563 	struct i40e_aqc_nvm_update *cmd =
3564 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
3565 	enum i40e_status_code status;
3566 
3567 	DEBUGFUNC("i40e_aq_read_nvm");
3568 
3569 	/* In offset the highest byte must be zeroed. */
3570 	if (offset & 0xFF000000) {
3571 		status = I40E_ERR_PARAM;
3572 		goto i40e_aq_read_nvm_exit;
3573 	}
3574 
3575 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_read);
3576 
3577 	/* If this is the last command in a series, set the proper flag. */
3578 	if (last_command)
3579 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3580 	cmd->module_pointer = module_pointer;
3581 	cmd->offset = CPU_TO_LE32(offset);
3582 	cmd->length = CPU_TO_LE16(length);
3583 
3584 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
3585 	if (length > I40E_AQ_LARGE_BUF)
3586 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3587 
3588 	status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
3589 
3590 i40e_aq_read_nvm_exit:
3591 	return status;
3592 }
3593 
3594 /**
3595  * i40e_aq_read_nvm_config - read an nvm config block
3596  * @hw: pointer to the hw struct
3597  * @cmd_flags: NVM access admin command bits
3598  * @field_id: field or feature id
3599  * @data: buffer for result
3600  * @buf_size: buffer size
3601  * @element_count: pointer to count of elements read by FW
3602  * @cmd_details: pointer to command details structure or NULL
3603  **/
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)3604 enum i40e_status_code i40e_aq_read_nvm_config(struct i40e_hw *hw,
3605 				u8 cmd_flags, u32 field_id, void *data,
3606 				u16 buf_size, u16 *element_count,
3607 				struct i40e_asq_cmd_details *cmd_details)
3608 {
3609 	struct i40e_aq_desc desc;
3610 	struct i40e_aqc_nvm_config_read *cmd =
3611 		(struct i40e_aqc_nvm_config_read *)&desc.params.raw;
3612 	enum i40e_status_code status;
3613 
3614 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_read);
3615 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF));
3616 	if (buf_size > I40E_AQ_LARGE_BUF)
3617 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3618 
3619 	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
3620 	cmd->element_id = CPU_TO_LE16((u16)(0xffff & field_id));
3621 	if (cmd_flags & I40E_AQ_ANVM_FEATURE_OR_IMMEDIATE_MASK)
3622 		cmd->element_id_msw = CPU_TO_LE16((u16)(field_id >> 16));
3623 	else
3624 		cmd->element_id_msw = 0;
3625 
3626 	status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
3627 
3628 	if (!status && element_count)
3629 		*element_count = LE16_TO_CPU(cmd->element_count);
3630 
3631 	return status;
3632 }
3633 
3634 /**
3635  * i40e_aq_write_nvm_config - write an nvm config block
3636  * @hw: pointer to the hw struct
3637  * @cmd_flags: NVM access admin command bits
3638  * @data: buffer for result
3639  * @buf_size: buffer size
3640  * @element_count: count of elements to be written
3641  * @cmd_details: pointer to command details structure or NULL
3642  **/
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)3643 enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw,
3644 				u8 cmd_flags, void *data, u16 buf_size,
3645 				u16 element_count,
3646 				struct i40e_asq_cmd_details *cmd_details)
3647 {
3648 	struct i40e_aq_desc desc;
3649 	struct i40e_aqc_nvm_config_write *cmd =
3650 		(struct i40e_aqc_nvm_config_write *)&desc.params.raw;
3651 	enum i40e_status_code status;
3652 
3653 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_write);
3654 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3655 	if (buf_size > I40E_AQ_LARGE_BUF)
3656 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3657 
3658 	cmd->element_count = CPU_TO_LE16(element_count);
3659 	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
3660 	status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
3661 
3662 	return status;
3663 }
3664 
3665 /**
3666  * i40e_aq_nvm_update_in_process
3667  * @hw: pointer to the hw struct
3668  * @update_flow_state: True indicates that update flow starts, FALSE that ends
3669  * @cmd_details: pointer to command details structure or NULL
3670  *
3671  * Indicate NVM update in process.
3672  **/
i40e_aq_nvm_update_in_process(struct i40e_hw * hw,bool update_flow_state,struct i40e_asq_cmd_details * cmd_details)3673 enum i40e_status_code i40e_aq_nvm_update_in_process(struct i40e_hw *hw,
3674 				bool update_flow_state,
3675 				struct i40e_asq_cmd_details *cmd_details)
3676 {
3677 	struct i40e_aq_desc desc;
3678 	struct i40e_aqc_nvm_update_in_process *cmd =
3679 		(struct i40e_aqc_nvm_update_in_process *)&desc.params.raw;
3680 	enum i40e_status_code status;
3681 
3682 	i40e_fill_default_direct_cmd_desc(&desc,
3683 					  i40e_aqc_opc_nvm_update_in_process);
3684 
3685 	cmd->command = I40E_AQ_UPDATE_FLOW_END;
3686 
3687 	if (update_flow_state)
3688 		cmd->command |= I40E_AQ_UPDATE_FLOW_START;
3689 
3690 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3691 
3692 	return status;
3693 }
3694 
3695 /**
3696  * i40e_aq_min_rollback_rev_update - triggers an ow after update
3697  * @hw: pointer to the hw struct
3698  * @mode: opt-in mode, 1b for single module update, 0b for bulk update
3699  * @module: module to be updated. Ignored if mode is 0b
3700  * @min_rrev: value of the new minimal version. Ignored if mode is 0b
3701  * @cmd_details: pointer to command details structure or NULL
3702  **/
3703 enum i40e_status_code
i40e_aq_min_rollback_rev_update(struct i40e_hw * hw,u8 mode,u8 module,u32 min_rrev,struct i40e_asq_cmd_details * cmd_details)3704 i40e_aq_min_rollback_rev_update(struct i40e_hw *hw, u8 mode, u8 module,
3705 				u32 min_rrev,
3706 				struct i40e_asq_cmd_details *cmd_details)
3707 {
3708 	struct i40e_aq_desc desc;
3709 	struct i40e_aqc_rollback_revision_update *cmd =
3710 		(struct i40e_aqc_rollback_revision_update *)&desc.params.raw;
3711 	enum i40e_status_code status;
3712 
3713 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rollback_revision_update);
3714 	cmd->optin_mode = mode;
3715 	cmd->module_selected = module;
3716 	cmd->min_rrev = min_rrev;
3717 
3718 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3719 
3720 	return status;
3721 }
3722 
3723 /**
3724  * i40e_aq_oem_post_update - triggers an OEM specific flow after update
3725  * @hw: pointer to the hw struct
3726  * @buff: buffer for result
3727  * @buff_size: buffer size
3728  * @cmd_details: pointer to command details structure or NULL
3729  **/
i40e_aq_oem_post_update(struct i40e_hw * hw,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)3730 enum i40e_status_code i40e_aq_oem_post_update(struct i40e_hw *hw,
3731 				void *buff, u16 buff_size,
3732 				struct i40e_asq_cmd_details *cmd_details)
3733 {
3734 	struct i40e_aq_desc desc;
3735 	enum i40e_status_code status;
3736 
3737 
3738 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_oem_post_update);
3739 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3740 	if (status && LE16_TO_CPU(desc.retval) == I40E_AQ_RC_ESRCH)
3741 		status = I40E_ERR_NOT_IMPLEMENTED;
3742 
3743 	return status;
3744 }
3745 
3746 /**
3747  * i40e_aq_erase_nvm
3748  * @hw: pointer to the hw struct
3749  * @module_pointer: module pointer location in words from the NVM beginning
3750  * @offset: offset in the module (expressed in 4 KB from module's beginning)
3751  * @length: length of the section to be erased (expressed in 4 KB)
3752  * @last_command: tells if this is the last command in a series
3753  * @cmd_details: pointer to command details structure or NULL
3754  *
3755  * Erase the NVM sector using the admin queue commands
3756  **/
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)3757 enum i40e_status_code i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
3758 				u32 offset, u16 length, bool last_command,
3759 				struct i40e_asq_cmd_details *cmd_details)
3760 {
3761 	struct i40e_aq_desc desc;
3762 	struct i40e_aqc_nvm_update *cmd =
3763 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
3764 	enum i40e_status_code status;
3765 
3766 	DEBUGFUNC("i40e_aq_erase_nvm");
3767 
3768 	/* In offset the highest byte must be zeroed. */
3769 	if (offset & 0xFF000000) {
3770 		status = I40E_ERR_PARAM;
3771 		goto i40e_aq_erase_nvm_exit;
3772 	}
3773 
3774 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_erase);
3775 
3776 	/* If this is the last command in a series, set the proper flag. */
3777 	if (last_command)
3778 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3779 	cmd->module_pointer = module_pointer;
3780 	cmd->offset = CPU_TO_LE32(offset);
3781 	cmd->length = CPU_TO_LE16(length);
3782 
3783 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3784 
3785 i40e_aq_erase_nvm_exit:
3786 	return status;
3787 }
3788 
3789 /**
3790  * i40e_parse_discover_capabilities
3791  * @hw: pointer to the hw struct
3792  * @buff: pointer to a buffer containing device/function capability records
3793  * @cap_count: number of capability records in the list
3794  * @list_type_opc: type of capabilities list to parse
3795  *
3796  * Parse the device/function capabilities list.
3797  **/
i40e_parse_discover_capabilities(struct i40e_hw * hw,void * buff,u32 cap_count,enum i40e_admin_queue_opc list_type_opc)3798 static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
3799 				     u32 cap_count,
3800 				     enum i40e_admin_queue_opc list_type_opc)
3801 {
3802 	struct i40e_aqc_list_capabilities_element_resp *cap;
3803 	u32 valid_functions, num_functions;
3804 	u32 number, logical_id, phys_id;
3805 	struct i40e_hw_capabilities *p;
3806 	enum i40e_status_code status;
3807 	u16 id, ocp_cfg_word0;
3808 	u8 major_rev;
3809 	u32 i = 0;
3810 
3811 	cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
3812 
3813 	if (list_type_opc == i40e_aqc_opc_list_dev_capabilities)
3814 		p = (struct i40e_hw_capabilities *)&hw->dev_caps;
3815 	else if (list_type_opc == i40e_aqc_opc_list_func_capabilities)
3816 		p = (struct i40e_hw_capabilities *)&hw->func_caps;
3817 	else
3818 		return;
3819 
3820 	for (i = 0; i < cap_count; i++, cap++) {
3821 		id = LE16_TO_CPU(cap->id);
3822 		number = LE32_TO_CPU(cap->number);
3823 		logical_id = LE32_TO_CPU(cap->logical_id);
3824 		phys_id = LE32_TO_CPU(cap->phys_id);
3825 		major_rev = cap->major_rev;
3826 
3827 		switch (id) {
3828 		case I40E_AQ_CAP_ID_SWITCH_MODE:
3829 			p->switch_mode = number;
3830 			i40e_debug(hw, I40E_DEBUG_INIT,
3831 				   "HW Capability: Switch mode = %d\n",
3832 				   p->switch_mode);
3833 			break;
3834 		case I40E_AQ_CAP_ID_MNG_MODE:
3835 			p->management_mode = number;
3836 			if (major_rev > 1) {
3837 				p->mng_protocols_over_mctp = logical_id;
3838 				i40e_debug(hw, I40E_DEBUG_INIT,
3839 					   "HW Capability: Protocols over MCTP = %d\n",
3840 					   p->mng_protocols_over_mctp);
3841 			} else {
3842 				p->mng_protocols_over_mctp = 0;
3843 			}
3844 			i40e_debug(hw, I40E_DEBUG_INIT,
3845 				   "HW Capability: Management Mode = %d\n",
3846 				   p->management_mode);
3847 			break;
3848 		case I40E_AQ_CAP_ID_NPAR_ACTIVE:
3849 			p->npar_enable = number;
3850 			i40e_debug(hw, I40E_DEBUG_INIT,
3851 				   "HW Capability: NPAR enable = %d\n",
3852 				   p->npar_enable);
3853 			break;
3854 		case I40E_AQ_CAP_ID_OS2BMC_CAP:
3855 			p->os2bmc = number;
3856 			i40e_debug(hw, I40E_DEBUG_INIT,
3857 				   "HW Capability: OS2BMC = %d\n", p->os2bmc);
3858 			break;
3859 		case I40E_AQ_CAP_ID_FUNCTIONS_VALID:
3860 			p->valid_functions = number;
3861 			i40e_debug(hw, I40E_DEBUG_INIT,
3862 				   "HW Capability: Valid Functions = %d\n",
3863 				   p->valid_functions);
3864 			break;
3865 		case I40E_AQ_CAP_ID_SRIOV:
3866 			if (number == 1)
3867 				p->sr_iov_1_1 = TRUE;
3868 			i40e_debug(hw, I40E_DEBUG_INIT,
3869 				   "HW Capability: SR-IOV = %d\n",
3870 				   p->sr_iov_1_1);
3871 			break;
3872 		case I40E_AQ_CAP_ID_VF:
3873 			p->num_vfs = number;
3874 			p->vf_base_id = logical_id;
3875 			i40e_debug(hw, I40E_DEBUG_INIT,
3876 				   "HW Capability: VF count = %d\n",
3877 				   p->num_vfs);
3878 			i40e_debug(hw, I40E_DEBUG_INIT,
3879 				   "HW Capability: VF base_id = %d\n",
3880 				   p->vf_base_id);
3881 			break;
3882 		case I40E_AQ_CAP_ID_VMDQ:
3883 			if (number == 1)
3884 				p->vmdq = TRUE;
3885 			i40e_debug(hw, I40E_DEBUG_INIT,
3886 				   "HW Capability: VMDQ = %d\n", p->vmdq);
3887 			break;
3888 		case I40E_AQ_CAP_ID_8021QBG:
3889 			if (number == 1)
3890 				p->evb_802_1_qbg = TRUE;
3891 			i40e_debug(hw, I40E_DEBUG_INIT,
3892 				   "HW Capability: 802.1Qbg = %d\n", number);
3893 			break;
3894 		case I40E_AQ_CAP_ID_8021QBR:
3895 			if (number == 1)
3896 				p->evb_802_1_qbh = TRUE;
3897 			i40e_debug(hw, I40E_DEBUG_INIT,
3898 				   "HW Capability: 802.1Qbh = %d\n", number);
3899 			break;
3900 		case I40E_AQ_CAP_ID_VSI:
3901 			p->num_vsis = number;
3902 			i40e_debug(hw, I40E_DEBUG_INIT,
3903 				   "HW Capability: VSI count = %d\n",
3904 				   p->num_vsis);
3905 			break;
3906 		case I40E_AQ_CAP_ID_DCB:
3907 			if (number == 1) {
3908 				p->dcb = TRUE;
3909 				p->enabled_tcmap = logical_id;
3910 				p->maxtc = phys_id;
3911 			}
3912 			i40e_debug(hw, I40E_DEBUG_INIT,
3913 				   "HW Capability: DCB = %d\n", p->dcb);
3914 			i40e_debug(hw, I40E_DEBUG_INIT,
3915 				   "HW Capability: TC Mapping = %d\n",
3916 				   logical_id);
3917 			i40e_debug(hw, I40E_DEBUG_INIT,
3918 				   "HW Capability: TC Max = %d\n", p->maxtc);
3919 			break;
3920 		case I40E_AQ_CAP_ID_FCOE:
3921 			if (number == 1)
3922 				p->fcoe = TRUE;
3923 			i40e_debug(hw, I40E_DEBUG_INIT,
3924 				   "HW Capability: FCOE = %d\n", p->fcoe);
3925 			break;
3926 		case I40E_AQ_CAP_ID_ISCSI:
3927 			if (number == 1)
3928 				p->iscsi = TRUE;
3929 			i40e_debug(hw, I40E_DEBUG_INIT,
3930 				   "HW Capability: iSCSI = %d\n", p->iscsi);
3931 			break;
3932 		case I40E_AQ_CAP_ID_RSS:
3933 			p->rss = TRUE;
3934 			p->rss_table_size = number;
3935 			p->rss_table_entry_width = logical_id;
3936 			i40e_debug(hw, I40E_DEBUG_INIT,
3937 				   "HW Capability: RSS = %d\n", p->rss);
3938 			i40e_debug(hw, I40E_DEBUG_INIT,
3939 				   "HW Capability: RSS table size = %d\n",
3940 				   p->rss_table_size);
3941 			i40e_debug(hw, I40E_DEBUG_INIT,
3942 				   "HW Capability: RSS table width = %d\n",
3943 				   p->rss_table_entry_width);
3944 			break;
3945 		case I40E_AQ_CAP_ID_RXQ:
3946 			p->num_rx_qp = number;
3947 			p->base_queue = phys_id;
3948 			i40e_debug(hw, I40E_DEBUG_INIT,
3949 				   "HW Capability: Rx QP = %d\n", number);
3950 			i40e_debug(hw, I40E_DEBUG_INIT,
3951 				   "HW Capability: base_queue = %d\n",
3952 				   p->base_queue);
3953 			break;
3954 		case I40E_AQ_CAP_ID_TXQ:
3955 			p->num_tx_qp = number;
3956 			p->base_queue = phys_id;
3957 			i40e_debug(hw, I40E_DEBUG_INIT,
3958 				   "HW Capability: Tx QP = %d\n", number);
3959 			i40e_debug(hw, I40E_DEBUG_INIT,
3960 				   "HW Capability: base_queue = %d\n",
3961 				   p->base_queue);
3962 			break;
3963 		case I40E_AQ_CAP_ID_MSIX:
3964 			p->num_msix_vectors = number;
3965 			i40e_debug(hw, I40E_DEBUG_INIT,
3966 				   "HW Capability: MSIX vector count = %d\n",
3967 				   p->num_msix_vectors);
3968 			break;
3969 		case I40E_AQ_CAP_ID_VF_MSIX:
3970 			p->num_msix_vectors_vf = number;
3971 			i40e_debug(hw, I40E_DEBUG_INIT,
3972 				   "HW Capability: MSIX VF vector count = %d\n",
3973 				   p->num_msix_vectors_vf);
3974 			break;
3975 		case I40E_AQ_CAP_ID_FLEX10:
3976 			if (major_rev == 1) {
3977 				if (number == 1) {
3978 					p->flex10_enable = TRUE;
3979 					p->flex10_capable = TRUE;
3980 				}
3981 			} else {
3982 				/* Capability revision >= 2 */
3983 				if (number & 1)
3984 					p->flex10_enable = TRUE;
3985 				if (number & 2)
3986 					p->flex10_capable = TRUE;
3987 			}
3988 			p->flex10_mode = logical_id;
3989 			p->flex10_status = phys_id;
3990 			i40e_debug(hw, I40E_DEBUG_INIT,
3991 				   "HW Capability: Flex10 mode = %d\n",
3992 				   p->flex10_mode);
3993 			i40e_debug(hw, I40E_DEBUG_INIT,
3994 				   "HW Capability: Flex10 status = %d\n",
3995 				   p->flex10_status);
3996 			break;
3997 		case I40E_AQ_CAP_ID_CEM:
3998 			if (number == 1)
3999 				p->mgmt_cem = TRUE;
4000 			i40e_debug(hw, I40E_DEBUG_INIT,
4001 				   "HW Capability: CEM = %d\n", p->mgmt_cem);
4002 			break;
4003 		case I40E_AQ_CAP_ID_IWARP:
4004 			if (number == 1)
4005 				p->iwarp = TRUE;
4006 			i40e_debug(hw, I40E_DEBUG_INIT,
4007 				   "HW Capability: iWARP = %d\n", p->iwarp);
4008 			break;
4009 		case I40E_AQ_CAP_ID_LED:
4010 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
4011 				p->led[phys_id] = TRUE;
4012 			i40e_debug(hw, I40E_DEBUG_INIT,
4013 				   "HW Capability: LED - PIN %d\n", phys_id);
4014 			break;
4015 		case I40E_AQ_CAP_ID_SDP:
4016 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
4017 				p->sdp[phys_id] = TRUE;
4018 			i40e_debug(hw, I40E_DEBUG_INIT,
4019 				   "HW Capability: SDP - PIN %d\n", phys_id);
4020 			break;
4021 		case I40E_AQ_CAP_ID_MDIO:
4022 			if (number == 1) {
4023 				p->mdio_port_num = phys_id;
4024 				p->mdio_port_mode = logical_id;
4025 			}
4026 			i40e_debug(hw, I40E_DEBUG_INIT,
4027 				   "HW Capability: MDIO port number = %d\n",
4028 				   p->mdio_port_num);
4029 			i40e_debug(hw, I40E_DEBUG_INIT,
4030 				   "HW Capability: MDIO port mode = %d\n",
4031 				   p->mdio_port_mode);
4032 			break;
4033 		case I40E_AQ_CAP_ID_1588:
4034 			if (number == 1)
4035 				p->ieee_1588 = TRUE;
4036 			i40e_debug(hw, I40E_DEBUG_INIT,
4037 				   "HW Capability: IEEE 1588 = %d\n",
4038 				   p->ieee_1588);
4039 			break;
4040 		case I40E_AQ_CAP_ID_FLOW_DIRECTOR:
4041 			p->fd = TRUE;
4042 			p->fd_filters_guaranteed = number;
4043 			p->fd_filters_best_effort = logical_id;
4044 			i40e_debug(hw, I40E_DEBUG_INIT,
4045 				   "HW Capability: Flow Director = 1\n");
4046 			i40e_debug(hw, I40E_DEBUG_INIT,
4047 				   "HW Capability: Guaranteed FD filters = %d\n",
4048 				   p->fd_filters_guaranteed);
4049 			break;
4050 		case I40E_AQ_CAP_ID_WSR_PROT:
4051 			p->wr_csr_prot = (u64)number;
4052 			p->wr_csr_prot |= (u64)logical_id << 32;
4053 			i40e_debug(hw, I40E_DEBUG_INIT,
4054 				   "HW Capability: wr_csr_prot = 0x%llX\n\n",
4055 				   (unsigned long long)(p->wr_csr_prot & 0xffff));
4056 			break;
4057 		case I40E_AQ_CAP_ID_DIS_UNUSED_PORTS:
4058 			p->dis_unused_ports = (bool)number;
4059 			i40e_debug(hw, I40E_DEBUG_INIT,
4060 				   "HW Capability: dis_unused_ports = %d\n\n",
4061 				   p->dis_unused_ports);
4062 			break;
4063 		case I40E_AQ_CAP_ID_NVM_MGMT:
4064 			if (number & I40E_NVM_MGMT_SEC_REV_DISABLED)
4065 				p->sec_rev_disabled = TRUE;
4066 			if (number & I40E_NVM_MGMT_UPDATE_DISABLED)
4067 				p->update_disabled = TRUE;
4068 			break;
4069 		case I40E_AQ_CAP_ID_WOL_AND_PROXY:
4070 			hw->num_wol_proxy_filters = (u16)number;
4071 			hw->wol_proxy_vsi_seid = (u16)logical_id;
4072 			p->apm_wol_support = phys_id & I40E_WOL_SUPPORT_MASK;
4073 			if (phys_id & I40E_ACPI_PROGRAMMING_METHOD_MASK)
4074 				p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_AQC_FPK;
4075 			else
4076 				p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_HW_FVL;
4077 			p->proxy_support = (phys_id & I40E_PROXY_SUPPORT_MASK) ? 1 : 0;
4078 			i40e_debug(hw, I40E_DEBUG_INIT,
4079 				   "HW Capability: WOL proxy filters = %d\n",
4080 				   hw->num_wol_proxy_filters);
4081 			break;
4082 		default:
4083 			break;
4084 		}
4085 	}
4086 
4087 	if (p->fcoe)
4088 		i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
4089 
4090 	/* Always disable FCoE if compiled without the I40E_FCOE_ENA flag */
4091 	p->fcoe = FALSE;
4092 
4093 	/* count the enabled ports (aka the "not disabled" ports) */
4094 	hw->num_ports = 0;
4095 	for (i = 0; i < 4; i++) {
4096 		u32 port_cfg_reg = I40E_PRTGEN_CNF + (4 * i);
4097 		u64 port_cfg = 0;
4098 
4099 		/* use AQ read to get the physical register offset instead
4100 		 * of the port relative offset
4101 		 */
4102 		i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
4103 		if (!(port_cfg & I40E_PRTGEN_CNF_PORT_DIS_MASK))
4104 			hw->num_ports++;
4105 	}
4106 
4107 	/* OCP cards case: if a mezz is removed the ethernet port is at
4108 	 * disabled state in PRTGEN_CNF register. Additional NVM read is
4109 	 * needed in order to check if we are dealing with OCP card.
4110 	 * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
4111 	 * physical ports results in wrong partition id calculation and thus
4112 	 * not supporting WoL.
4113 	 */
4114 	if (hw->mac.type == I40E_MAC_X722) {
4115 		if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) {
4116 			status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
4117 						  2 * I40E_SR_OCP_CFG_WORD0,
4118 						  sizeof(ocp_cfg_word0),
4119 						  &ocp_cfg_word0, TRUE, NULL);
4120 			if (status == I40E_SUCCESS &&
4121 			    (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
4122 				hw->num_ports = 4;
4123 			i40e_release_nvm(hw);
4124 		}
4125 	}
4126 
4127 	valid_functions = p->valid_functions;
4128 	num_functions = 0;
4129 	while (valid_functions) {
4130 		if (valid_functions & 1)
4131 			num_functions++;
4132 		valid_functions >>= 1;
4133 	}
4134 
4135 	/* partition id is 1-based, and functions are evenly spread
4136 	 * across the ports as partitions
4137 	 */
4138 	if (hw->num_ports != 0) {
4139 		hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
4140 		hw->num_partitions = num_functions / hw->num_ports;
4141 	}
4142 
4143 	/* additional HW specific goodies that might
4144 	 * someday be HW version specific
4145 	 */
4146 	p->rx_buf_chain_len = I40E_MAX_CHAINED_RX_BUFFERS;
4147 }
4148 
4149 /**
4150  * i40e_aq_discover_capabilities
4151  * @hw: pointer to the hw struct
4152  * @buff: a virtual buffer to hold the capabilities
4153  * @buff_size: Size of the virtual buffer
4154  * @data_size: Size of the returned data, or buff size needed if AQ err==ENOMEM
4155  * @list_type_opc: capabilities type to discover - pass in the command opcode
4156  * @cmd_details: pointer to command details structure or NULL
4157  *
4158  * Get the device capabilities descriptions from the firmware
4159  **/
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)4160 enum i40e_status_code i40e_aq_discover_capabilities(struct i40e_hw *hw,
4161 				void *buff, u16 buff_size, u16 *data_size,
4162 				enum i40e_admin_queue_opc list_type_opc,
4163 				struct i40e_asq_cmd_details *cmd_details)
4164 {
4165 	struct i40e_aqc_list_capabilites *cmd;
4166 	struct i40e_aq_desc desc;
4167 	enum i40e_status_code status = I40E_SUCCESS;
4168 
4169 	cmd = (struct i40e_aqc_list_capabilites *)&desc.params.raw;
4170 
4171 	if (list_type_opc != i40e_aqc_opc_list_func_capabilities &&
4172 		list_type_opc != i40e_aqc_opc_list_dev_capabilities) {
4173 		status = I40E_ERR_PARAM;
4174 		goto exit;
4175 	}
4176 
4177 	i40e_fill_default_direct_cmd_desc(&desc, list_type_opc);
4178 
4179 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4180 	if (buff_size > I40E_AQ_LARGE_BUF)
4181 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4182 
4183 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4184 	*data_size = LE16_TO_CPU(desc.datalen);
4185 
4186 	if (status)
4187 		goto exit;
4188 
4189 	i40e_parse_discover_capabilities(hw, buff, LE32_TO_CPU(cmd->count),
4190 					 list_type_opc);
4191 
4192 exit:
4193 	return status;
4194 }
4195 
4196 /**
4197  * i40e_aq_update_nvm
4198  * @hw: pointer to the hw struct
4199  * @module_pointer: module pointer location in words from the NVM beginning
4200  * @offset: byte offset from the module beginning
4201  * @length: length of the section to be written (in bytes from the offset)
4202  * @data: command buffer (size [bytes] = length)
4203  * @last_command: tells if this is the last command in a series
4204  * @preservation_flags: Preservation mode flags
4205  * @cmd_details: pointer to command details structure or NULL
4206  *
4207  * Update the NVM using the admin queue commands
4208  **/
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)4209 enum i40e_status_code i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
4210 				u32 offset, u16 length, void *data,
4211 				bool last_command, u8 preservation_flags,
4212 				struct i40e_asq_cmd_details *cmd_details)
4213 {
4214 	struct i40e_aq_desc desc;
4215 	struct i40e_aqc_nvm_update *cmd =
4216 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
4217 	enum i40e_status_code status;
4218 
4219 	DEBUGFUNC("i40e_aq_update_nvm");
4220 
4221 	/* In offset the highest byte must be zeroed. */
4222 	if (offset & 0xFF000000) {
4223 		status = I40E_ERR_PARAM;
4224 		goto i40e_aq_update_nvm_exit;
4225 	}
4226 
4227 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
4228 
4229 	/* If this is the last command in a series, set the proper flag. */
4230 	if (last_command)
4231 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
4232 	if (hw->mac.type == I40E_MAC_X722) {
4233 		if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_SELECTED)
4234 			cmd->command_flags |=
4235 				(I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED <<
4236 				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
4237 		else if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_ALL)
4238 			cmd->command_flags |=
4239 				(I40E_AQ_NVM_PRESERVATION_FLAGS_ALL <<
4240 				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
4241 	}
4242 	cmd->module_pointer = module_pointer;
4243 	cmd->offset = CPU_TO_LE32(offset);
4244 	cmd->length = CPU_TO_LE16(length);
4245 
4246 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4247 	if (length > I40E_AQ_LARGE_BUF)
4248 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4249 
4250 	status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
4251 
4252 i40e_aq_update_nvm_exit:
4253 	return status;
4254 }
4255 
4256 /**
4257  * i40e_aq_get_lldp_mib
4258  * @hw: pointer to the hw struct
4259  * @bridge_type: type of bridge requested
4260  * @mib_type: Local, Remote or both Local and Remote MIBs
4261  * @buff: pointer to a user supplied buffer to store the MIB block
4262  * @buff_size: size of the buffer (in bytes)
4263  * @local_len : length of the returned Local LLDP MIB
4264  * @remote_len: length of the returned Remote LLDP MIB
4265  * @cmd_details: pointer to command details structure or NULL
4266  *
4267  * Requests the complete LLDP MIB (entire packet).
4268  **/
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)4269 enum i40e_status_code i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
4270 				u8 mib_type, void *buff, u16 buff_size,
4271 				u16 *local_len, u16 *remote_len,
4272 				struct i40e_asq_cmd_details *cmd_details)
4273 {
4274 	struct i40e_aq_desc desc;
4275 	struct i40e_aqc_lldp_get_mib *cmd =
4276 		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
4277 	struct i40e_aqc_lldp_get_mib *resp =
4278 		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
4279 	enum i40e_status_code status;
4280 
4281 	if (buff_size == 0 || !buff)
4282 		return I40E_ERR_PARAM;
4283 
4284 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_get_mib);
4285 	/* Indirect Command */
4286 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4287 
4288 	cmd->type = mib_type & I40E_AQ_LLDP_MIB_TYPE_MASK;
4289 	cmd->type |= ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
4290 		       I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
4291 
4292 	desc.datalen = CPU_TO_LE16(buff_size);
4293 
4294 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4295 	if (buff_size > I40E_AQ_LARGE_BUF)
4296 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4297 
4298 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4299 	if (!status) {
4300 		if (local_len != NULL)
4301 			*local_len = LE16_TO_CPU(resp->local_len);
4302 		if (remote_len != NULL)
4303 			*remote_len = LE16_TO_CPU(resp->remote_len);
4304 	}
4305 
4306 	return status;
4307 }
4308 
4309  /**
4310  * i40e_aq_set_lldp_mib - Set the LLDP MIB
4311  * @hw: pointer to the hw struct
4312  * @mib_type: Local, Remote or both Local and Remote MIBs
4313  * @buff: pointer to a user supplied buffer to store the MIB block
4314  * @buff_size: size of the buffer (in bytes)
4315  * @cmd_details: pointer to command details structure or NULL
4316  *
4317  * Set the LLDP MIB.
4318  **/
i40e_aq_set_lldp_mib(struct i40e_hw * hw,u8 mib_type,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)4319 enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw,
4320 				u8 mib_type, void *buff, u16 buff_size,
4321 				struct i40e_asq_cmd_details *cmd_details)
4322 {
4323 	struct i40e_aq_desc desc;
4324 	struct i40e_aqc_lldp_set_local_mib *cmd =
4325 		(struct i40e_aqc_lldp_set_local_mib *)&desc.params.raw;
4326 	enum i40e_status_code status;
4327 
4328 	if (buff_size == 0 || !buff)
4329 		return I40E_ERR_PARAM;
4330 
4331 	i40e_fill_default_direct_cmd_desc(&desc,
4332 				i40e_aqc_opc_lldp_set_local_mib);
4333 	/* Indirect Command */
4334 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4335 	if (buff_size > I40E_AQ_LARGE_BUF)
4336 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4337 	desc.datalen = CPU_TO_LE16(buff_size);
4338 
4339 	cmd->type = mib_type;
4340 	cmd->length = CPU_TO_LE16(buff_size);
4341 	cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)buff));
4342 	cmd->address_low =  CPU_TO_LE32(I40E_LO_DWORD((u64)buff));
4343 
4344 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4345 	return status;
4346 }
4347 
4348 /**
4349  * i40e_aq_cfg_lldp_mib_change_event
4350  * @hw: pointer to the hw struct
4351  * @enable_update: Enable or Disable event posting
4352  * @cmd_details: pointer to command details structure or NULL
4353  *
4354  * Enable or Disable posting of an event on ARQ when LLDP MIB
4355  * associated with the interface changes
4356  **/
i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw * hw,bool enable_update,struct i40e_asq_cmd_details * cmd_details)4357 enum i40e_status_code i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
4358 				bool enable_update,
4359 				struct i40e_asq_cmd_details *cmd_details)
4360 {
4361 	struct i40e_aq_desc desc;
4362 	struct i40e_aqc_lldp_update_mib *cmd =
4363 		(struct i40e_aqc_lldp_update_mib *)&desc.params.raw;
4364 	enum i40e_status_code status;
4365 
4366 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_mib);
4367 
4368 	if (!enable_update)
4369 		cmd->command |= I40E_AQ_LLDP_MIB_UPDATE_DISABLE;
4370 
4371 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4372 
4373 	return status;
4374 }
4375 
4376 /**
4377  * i40e_aq_restore_lldp
4378  * @hw: pointer to the hw struct
4379  * @setting: pointer to factory setting variable or NULL
4380  * @restore: True if factory settings should be restored
4381  * @cmd_details: pointer to command details structure or NULL
4382  *
4383  * Restore LLDP Agent factory settings if @restore set to True. In other case
4384  * only returns factory setting in AQ response.
4385  **/
4386 enum i40e_status_code
i40e_aq_restore_lldp(struct i40e_hw * hw,u8 * setting,bool restore,struct i40e_asq_cmd_details * cmd_details)4387 i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
4388 		     struct i40e_asq_cmd_details *cmd_details)
4389 {
4390 	struct i40e_aq_desc desc;
4391 	struct i40e_aqc_lldp_restore *cmd =
4392 		(struct i40e_aqc_lldp_restore *)&desc.params.raw;
4393 	enum i40e_status_code status;
4394 
4395 	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) {
4396 		i40e_debug(hw, I40E_DEBUG_ALL,
4397 			   "Restore LLDP not supported by current FW version.\n");
4398 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
4399 	}
4400 
4401 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore);
4402 
4403 	if (restore)
4404 		cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE;
4405 
4406 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4407 
4408 	if (setting)
4409 		*setting = cmd->command & 1;
4410 
4411 	return status;
4412 }
4413 
4414 /**
4415  * i40e_aq_stop_lldp
4416  * @hw: pointer to the hw struct
4417  * @shutdown_agent: True if LLDP Agent needs to be Shutdown
4418  * @persist: True if stop of LLDP should be persistent across power cycles
4419  * @cmd_details: pointer to command details structure or NULL
4420  *
4421  * Stop or Shutdown the embedded LLDP Agent
4422  **/
i40e_aq_stop_lldp(struct i40e_hw * hw,bool shutdown_agent,bool persist,struct i40e_asq_cmd_details * cmd_details)4423 enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
4424 				bool persist,
4425 				struct i40e_asq_cmd_details *cmd_details)
4426 {
4427 	struct i40e_aq_desc desc;
4428 	struct i40e_aqc_lldp_stop *cmd =
4429 		(struct i40e_aqc_lldp_stop *)&desc.params.raw;
4430 	enum i40e_status_code status;
4431 
4432 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
4433 
4434 	if (shutdown_agent)
4435 		cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
4436 
4437 	if (persist) {
4438 		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
4439 			cmd->command |= I40E_AQ_LLDP_AGENT_STOP_PERSIST;
4440 		else
4441 			i40e_debug(hw, I40E_DEBUG_ALL,
4442 				   "Persistent Stop LLDP not supported by current FW version.\n");
4443 	}
4444 
4445 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4446 
4447 	return status;
4448 }
4449 
4450 /**
4451  * i40e_aq_start_lldp
4452  * @hw: pointer to the hw struct
4453  * @persist: True if start of LLDP should be persistent across power cycles
4454  * @cmd_details: pointer to command details structure or NULL
4455  *
4456  * Start the embedded LLDP Agent on all ports.
4457  **/
i40e_aq_start_lldp(struct i40e_hw * hw,bool persist,struct i40e_asq_cmd_details * cmd_details)4458 enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw,
4459 				bool persist,
4460 				struct i40e_asq_cmd_details *cmd_details)
4461 {
4462 	struct i40e_aq_desc desc;
4463 	struct i40e_aqc_lldp_start *cmd =
4464 		(struct i40e_aqc_lldp_start *)&desc.params.raw;
4465 	enum i40e_status_code status;
4466 
4467 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
4468 
4469 	cmd->command = I40E_AQ_LLDP_AGENT_START;
4470 
4471 	if (persist) {
4472 		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
4473 			cmd->command |= I40E_AQ_LLDP_AGENT_START_PERSIST;
4474 		else
4475 			i40e_debug(hw, I40E_DEBUG_ALL,
4476 				   "Persistent Start LLDP not supported by current FW version.\n");
4477 	}
4478 
4479 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4480 
4481 	return status;
4482 }
4483 
4484 /**
4485  * i40e_aq_set_dcb_parameters
4486  * @hw: pointer to the hw struct
4487  * @cmd_details: pointer to command details structure or NULL
4488  * @dcb_enable: True if DCB configuration needs to be applied
4489  *
4490  **/
4491 enum i40e_status_code
i40e_aq_set_dcb_parameters(struct i40e_hw * hw,bool dcb_enable,struct i40e_asq_cmd_details * cmd_details)4492 i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
4493 			   struct i40e_asq_cmd_details *cmd_details)
4494 {
4495 	struct i40e_aq_desc desc;
4496 	struct i40e_aqc_set_dcb_parameters *cmd =
4497 		(struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
4498 	enum i40e_status_code status;
4499 
4500 	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE))
4501 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
4502 
4503 	i40e_fill_default_direct_cmd_desc(&desc,
4504 					  i40e_aqc_opc_set_dcb_parameters);
4505 
4506 	if (dcb_enable) {
4507 		cmd->valid_flags = I40E_DCB_VALID;
4508 		cmd->command = I40E_AQ_DCB_SET_AGENT;
4509 	}
4510 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4511 
4512 	return status;
4513 }
4514 
4515 /**
4516  * i40e_aq_get_cee_dcb_config
4517  * @hw: pointer to the hw struct
4518  * @buff: response buffer that stores CEE operational configuration
4519  * @buff_size: size of the buffer passed
4520  * @cmd_details: pointer to command details structure or NULL
4521  *
4522  * Get CEE DCBX mode operational configuration from firmware
4523  **/
i40e_aq_get_cee_dcb_config(struct i40e_hw * hw,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)4524 enum i40e_status_code i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
4525 				void *buff, u16 buff_size,
4526 				struct i40e_asq_cmd_details *cmd_details)
4527 {
4528 	struct i40e_aq_desc desc;
4529 	enum i40e_status_code status;
4530 
4531 	if (buff_size == 0 || !buff)
4532 		return I40E_ERR_PARAM;
4533 
4534 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_cee_dcb_cfg);
4535 
4536 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4537 	status = i40e_asq_send_command(hw, &desc, (void *)buff, buff_size,
4538 				       cmd_details);
4539 
4540 	return status;
4541 }
4542 
4543 /**
4544  * i40e_aq_start_stop_dcbx - Start/Stop DCBx service in FW
4545  * @hw: pointer to the hw struct
4546  * @start_agent: True if DCBx Agent needs to be Started
4547  *				False if DCBx Agent needs to be Stopped
4548  * @cmd_details: pointer to command details structure or NULL
4549  *
4550  * Start/Stop the embedded dcbx Agent
4551  **/
i40e_aq_start_stop_dcbx(struct i40e_hw * hw,bool start_agent,struct i40e_asq_cmd_details * cmd_details)4552 enum i40e_status_code i40e_aq_start_stop_dcbx(struct i40e_hw *hw,
4553 				bool start_agent,
4554 				struct i40e_asq_cmd_details *cmd_details)
4555 {
4556 	struct i40e_aq_desc desc;
4557 	struct i40e_aqc_lldp_stop_start_specific_agent *cmd =
4558 		(struct i40e_aqc_lldp_stop_start_specific_agent *)
4559 				&desc.params.raw;
4560 	enum i40e_status_code status;
4561 
4562 	i40e_fill_default_direct_cmd_desc(&desc,
4563 				i40e_aqc_opc_lldp_stop_start_spec_agent);
4564 
4565 	if (start_agent)
4566 		cmd->command = I40E_AQC_START_SPECIFIC_AGENT_MASK;
4567 
4568 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4569 
4570 	return status;
4571 }
4572 
4573 /**
4574  * i40e_aq_add_udp_tunnel
4575  * @hw: pointer to the hw struct
4576  * @udp_port: the UDP port to add in Host byte order
4577  * @protocol_index: protocol index type
4578  * @filter_index: pointer to filter index
4579  * @cmd_details: pointer to command details structure or NULL
4580  *
4581  * Note: Firmware expects the udp_port value to be in Little Endian format,
4582  * and this function will call CPU_TO_LE16 to convert from Host byte order to
4583  * Little Endian order.
4584  **/
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)4585 enum i40e_status_code i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
4586 				u16 udp_port, u8 protocol_index,
4587 				u8 *filter_index,
4588 				struct i40e_asq_cmd_details *cmd_details)
4589 {
4590 	struct i40e_aq_desc desc;
4591 	struct i40e_aqc_add_udp_tunnel *cmd =
4592 		(struct i40e_aqc_add_udp_tunnel *)&desc.params.raw;
4593 	struct i40e_aqc_del_udp_tunnel_completion *resp =
4594 		(struct i40e_aqc_del_udp_tunnel_completion *)&desc.params.raw;
4595 	enum i40e_status_code status;
4596 
4597 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_udp_tunnel);
4598 
4599 	cmd->udp_port = CPU_TO_LE16(udp_port);
4600 	cmd->protocol_type = protocol_index;
4601 
4602 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4603 
4604 	if (!status && filter_index)
4605 		*filter_index = resp->index;
4606 
4607 	return status;
4608 }
4609 
4610 /**
4611  * i40e_aq_del_udp_tunnel
4612  * @hw: pointer to the hw struct
4613  * @index: filter index
4614  * @cmd_details: pointer to command details structure or NULL
4615  **/
i40e_aq_del_udp_tunnel(struct i40e_hw * hw,u8 index,struct i40e_asq_cmd_details * cmd_details)4616 enum i40e_status_code i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
4617 				struct i40e_asq_cmd_details *cmd_details)
4618 {
4619 	struct i40e_aq_desc desc;
4620 	struct i40e_aqc_remove_udp_tunnel *cmd =
4621 		(struct i40e_aqc_remove_udp_tunnel *)&desc.params.raw;
4622 	enum i40e_status_code status;
4623 
4624 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_del_udp_tunnel);
4625 
4626 	cmd->index = index;
4627 
4628 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4629 
4630 	return status;
4631 }
4632 
4633 /**
4634  * i40e_aq_get_switch_resource_alloc - command (0x0204) to get allocations
4635  * @hw: pointer to the hw struct
4636  * @num_entries: pointer to u8 to store the number of resource entries returned
4637  * @buf: pointer to a user supplied buffer.  This buffer must be large enough
4638  *        to store the resource information for all resource types.  Each
4639  *        resource type is a i40e_aqc_switch_resource_alloc_data structure.
4640  * @count: size, in bytes, of the buffer provided
4641  * @cmd_details: pointer to command details structure or NULL
4642  *
4643  * Query the resources allocated to a function.
4644  **/
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)4645 enum i40e_status_code i40e_aq_get_switch_resource_alloc(struct i40e_hw *hw,
4646 			u8 *num_entries,
4647 			struct i40e_aqc_switch_resource_alloc_element_resp *buf,
4648 			u16 count,
4649 			struct i40e_asq_cmd_details *cmd_details)
4650 {
4651 	struct i40e_aq_desc desc;
4652 	struct i40e_aqc_get_switch_resource_alloc *cmd_resp =
4653 		(struct i40e_aqc_get_switch_resource_alloc *)&desc.params.raw;
4654 	enum i40e_status_code status;
4655 	u16 length = count * sizeof(*buf);
4656 
4657 	i40e_fill_default_direct_cmd_desc(&desc,
4658 					i40e_aqc_opc_get_switch_resource_alloc);
4659 
4660 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4661 	if (length > I40E_AQ_LARGE_BUF)
4662 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4663 
4664 	status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
4665 
4666 	if (!status && num_entries)
4667 		*num_entries = cmd_resp->num_entries;
4668 
4669 	return status;
4670 }
4671 
4672 /**
4673  * i40e_aq_delete_element - Delete switch element
4674  * @hw: pointer to the hw struct
4675  * @seid: the SEID to delete from the switch
4676  * @cmd_details: pointer to command details structure or NULL
4677  *
4678  * This deletes a switch element from the switch.
4679  **/
i40e_aq_delete_element(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)4680 enum i40e_status_code i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
4681 				struct i40e_asq_cmd_details *cmd_details)
4682 {
4683 	struct i40e_aq_desc desc;
4684 	struct i40e_aqc_switch_seid *cmd =
4685 		(struct i40e_aqc_switch_seid *)&desc.params.raw;
4686 	enum i40e_status_code status;
4687 
4688 	if (seid == 0)
4689 		return I40E_ERR_PARAM;
4690 
4691 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_delete_element);
4692 
4693 	cmd->seid = CPU_TO_LE16(seid);
4694 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4695 
4696 	return status;
4697 }
4698 
4699 /**
4700  * i40e_aq_add_pvirt - Instantiate a Port Virtualizer on a port
4701  * @hw: pointer to the hw struct
4702  * @flags: component flags
4703  * @mac_seid: uplink seid (MAC SEID)
4704  * @vsi_seid: connected vsi seid
4705  * @ret_seid: seid of create pv component
4706  *
4707  * This instantiates an i40e port virtualizer with specified flags.
4708  * Depending on specified flags the port virtualizer can act as a
4709  * 802.1Qbr port virtualizer or a 802.1Qbg S-component.
4710  */
i40e_aq_add_pvirt(struct i40e_hw * hw,u16 flags,u16 mac_seid,u16 vsi_seid,u16 * ret_seid)4711 enum i40e_status_code i40e_aq_add_pvirt(struct i40e_hw *hw, u16 flags,
4712 				       u16 mac_seid, u16 vsi_seid,
4713 				       u16 *ret_seid)
4714 {
4715 	struct i40e_aq_desc desc;
4716 	struct i40e_aqc_add_update_pv *cmd =
4717 		(struct i40e_aqc_add_update_pv *)&desc.params.raw;
4718 	struct i40e_aqc_add_update_pv_completion *resp =
4719 		(struct i40e_aqc_add_update_pv_completion *)&desc.params.raw;
4720 	enum i40e_status_code status;
4721 
4722 	if (vsi_seid == 0)
4723 		return I40E_ERR_PARAM;
4724 
4725 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_pv);
4726 	cmd->command_flags = CPU_TO_LE16(flags);
4727 	cmd->uplink_seid = CPU_TO_LE16(mac_seid);
4728 	cmd->connected_seid = CPU_TO_LE16(vsi_seid);
4729 
4730 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
4731 	if (!status && ret_seid)
4732 		*ret_seid = LE16_TO_CPU(resp->pv_seid);
4733 
4734 	return status;
4735 }
4736 
4737 /**
4738  * i40e_aq_add_tag - Add an S/E-tag
4739  * @hw: pointer to the hw struct
4740  * @direct_to_queue: should s-tag direct flow to a specific queue
4741  * @vsi_seid: VSI SEID to use this tag
4742  * @tag: value of the tag
4743  * @queue_num: queue number, only valid is direct_to_queue is TRUE
4744  * @tags_used: return value, number of tags in use by this PF
4745  * @tags_free: return value, number of unallocated tags
4746  * @cmd_details: pointer to command details structure or NULL
4747  *
4748  * This associates an S- or E-tag to a VSI in the switch complex.  It returns
4749  * the number of tags allocated by the PF, and the number of unallocated
4750  * tags available.
4751  **/
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)4752 enum i40e_status_code i40e_aq_add_tag(struct i40e_hw *hw, bool direct_to_queue,
4753 				u16 vsi_seid, u16 tag, u16 queue_num,
4754 				u16 *tags_used, u16 *tags_free,
4755 				struct i40e_asq_cmd_details *cmd_details)
4756 {
4757 	struct i40e_aq_desc desc;
4758 	struct i40e_aqc_add_tag *cmd =
4759 		(struct i40e_aqc_add_tag *)&desc.params.raw;
4760 	struct i40e_aqc_add_remove_tag_completion *resp =
4761 		(struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
4762 	enum i40e_status_code status;
4763 
4764 	if (vsi_seid == 0)
4765 		return I40E_ERR_PARAM;
4766 
4767 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_tag);
4768 
4769 	cmd->seid = CPU_TO_LE16(vsi_seid);
4770 	cmd->tag = CPU_TO_LE16(tag);
4771 	if (direct_to_queue) {
4772 		cmd->flags = CPU_TO_LE16(I40E_AQC_ADD_TAG_FLAG_TO_QUEUE);
4773 		cmd->queue_number = CPU_TO_LE16(queue_num);
4774 	}
4775 
4776 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4777 
4778 	if (!status) {
4779 		if (tags_used != NULL)
4780 			*tags_used = LE16_TO_CPU(resp->tags_used);
4781 		if (tags_free != NULL)
4782 			*tags_free = LE16_TO_CPU(resp->tags_free);
4783 	}
4784 
4785 	return status;
4786 }
4787 
4788 /**
4789  * i40e_aq_remove_tag - Remove an S- or E-tag
4790  * @hw: pointer to the hw struct
4791  * @vsi_seid: VSI SEID this tag is associated with
4792  * @tag: value of the S-tag to delete
4793  * @tags_used: return value, number of tags in use by this PF
4794  * @tags_free: return value, number of unallocated tags
4795  * @cmd_details: pointer to command details structure or NULL
4796  *
4797  * This deletes an S- or E-tag from a VSI in the switch complex.  It returns
4798  * the number of tags allocated by the PF, and the number of unallocated
4799  * tags available.
4800  **/
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)4801 enum i40e_status_code i40e_aq_remove_tag(struct i40e_hw *hw, u16 vsi_seid,
4802 				u16 tag, u16 *tags_used, u16 *tags_free,
4803 				struct i40e_asq_cmd_details *cmd_details)
4804 {
4805 	struct i40e_aq_desc desc;
4806 	struct i40e_aqc_remove_tag *cmd =
4807 		(struct i40e_aqc_remove_tag *)&desc.params.raw;
4808 	struct i40e_aqc_add_remove_tag_completion *resp =
4809 		(struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
4810 	enum i40e_status_code status;
4811 
4812 	if (vsi_seid == 0)
4813 		return I40E_ERR_PARAM;
4814 
4815 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_tag);
4816 
4817 	cmd->seid = CPU_TO_LE16(vsi_seid);
4818 	cmd->tag = CPU_TO_LE16(tag);
4819 
4820 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4821 
4822 	if (!status) {
4823 		if (tags_used != NULL)
4824 			*tags_used = LE16_TO_CPU(resp->tags_used);
4825 		if (tags_free != NULL)
4826 			*tags_free = LE16_TO_CPU(resp->tags_free);
4827 	}
4828 
4829 	return status;
4830 }
4831 
4832 /**
4833  * i40e_aq_add_mcast_etag - Add a multicast E-tag
4834  * @hw: pointer to the hw struct
4835  * @pv_seid: Port Virtualizer of this SEID to associate E-tag with
4836  * @etag: value of E-tag to add
4837  * @num_tags_in_buf: number of unicast E-tags in indirect buffer
4838  * @buf: address of indirect buffer
4839  * @tags_used: return value, number of E-tags in use by this port
4840  * @tags_free: return value, number of unallocated M-tags
4841  * @cmd_details: pointer to command details structure or NULL
4842  *
4843  * This associates a multicast E-tag to a port virtualizer.  It will return
4844  * the number of tags allocated by the PF, and the number of unallocated
4845  * tags available.
4846  *
4847  * The indirect buffer pointed to by buf is a list of 2-byte E-tags,
4848  * num_tags_in_buf long.
4849  **/
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)4850 enum i40e_status_code i40e_aq_add_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
4851 				u16 etag, u8 num_tags_in_buf, void *buf,
4852 				u16 *tags_used, u16 *tags_free,
4853 				struct i40e_asq_cmd_details *cmd_details)
4854 {
4855 	struct i40e_aq_desc desc;
4856 	struct i40e_aqc_add_remove_mcast_etag *cmd =
4857 		(struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
4858 	struct i40e_aqc_add_remove_mcast_etag_completion *resp =
4859 	   (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
4860 	enum i40e_status_code status;
4861 	u16 length = sizeof(u16) * num_tags_in_buf;
4862 
4863 	if ((pv_seid == 0) || (buf == NULL) || (num_tags_in_buf == 0))
4864 		return I40E_ERR_PARAM;
4865 
4866 	i40e_fill_default_direct_cmd_desc(&desc,
4867 					  i40e_aqc_opc_add_multicast_etag);
4868 
4869 	cmd->pv_seid = CPU_TO_LE16(pv_seid);
4870 	cmd->etag = CPU_TO_LE16(etag);
4871 	cmd->num_unicast_etags = num_tags_in_buf;
4872 
4873 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4874 
4875 	status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
4876 
4877 	if (!status) {
4878 		if (tags_used != NULL)
4879 			*tags_used = LE16_TO_CPU(resp->mcast_etags_used);
4880 		if (tags_free != NULL)
4881 			*tags_free = LE16_TO_CPU(resp->mcast_etags_free);
4882 	}
4883 
4884 	return status;
4885 }
4886 
4887 /**
4888  * i40e_aq_remove_mcast_etag - Remove a multicast E-tag
4889  * @hw: pointer to the hw struct
4890  * @pv_seid: Port Virtualizer SEID this M-tag is associated with
4891  * @etag: value of the E-tag to remove
4892  * @tags_used: return value, number of tags in use by this port
4893  * @tags_free: return value, number of unallocated tags
4894  * @cmd_details: pointer to command details structure or NULL
4895  *
4896  * This deletes an E-tag from the port virtualizer.  It will return
4897  * the number of tags allocated by the port, and the number of unallocated
4898  * tags available.
4899  **/
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)4900 enum i40e_status_code i40e_aq_remove_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
4901 				u16 etag, u16 *tags_used, u16 *tags_free,
4902 				struct i40e_asq_cmd_details *cmd_details)
4903 {
4904 	struct i40e_aq_desc desc;
4905 	struct i40e_aqc_add_remove_mcast_etag *cmd =
4906 		(struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
4907 	struct i40e_aqc_add_remove_mcast_etag_completion *resp =
4908 	   (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
4909 	enum i40e_status_code status;
4910 
4911 
4912 	if (pv_seid == 0)
4913 		return I40E_ERR_PARAM;
4914 
4915 	i40e_fill_default_direct_cmd_desc(&desc,
4916 					  i40e_aqc_opc_remove_multicast_etag);
4917 
4918 	cmd->pv_seid = CPU_TO_LE16(pv_seid);
4919 	cmd->etag = CPU_TO_LE16(etag);
4920 
4921 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4922 
4923 	if (!status) {
4924 		if (tags_used != NULL)
4925 			*tags_used = LE16_TO_CPU(resp->mcast_etags_used);
4926 		if (tags_free != NULL)
4927 			*tags_free = LE16_TO_CPU(resp->mcast_etags_free);
4928 	}
4929 
4930 	return status;
4931 }
4932 
4933 /**
4934  * i40e_aq_update_tag - Update an S/E-tag
4935  * @hw: pointer to the hw struct
4936  * @vsi_seid: VSI SEID using this S-tag
4937  * @old_tag: old tag value
4938  * @new_tag: new tag value
4939  * @tags_used: return value, number of tags in use by this PF
4940  * @tags_free: return value, number of unallocated tags
4941  * @cmd_details: pointer to command details structure or NULL
4942  *
4943  * This updates the value of the tag currently attached to this VSI
4944  * in the switch complex.  It will return the number of tags allocated
4945  * by the PF, and the number of unallocated tags available.
4946  **/
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)4947 enum i40e_status_code i40e_aq_update_tag(struct i40e_hw *hw, u16 vsi_seid,
4948 				u16 old_tag, u16 new_tag, u16 *tags_used,
4949 				u16 *tags_free,
4950 				struct i40e_asq_cmd_details *cmd_details)
4951 {
4952 	struct i40e_aq_desc desc;
4953 	struct i40e_aqc_update_tag *cmd =
4954 		(struct i40e_aqc_update_tag *)&desc.params.raw;
4955 	struct i40e_aqc_update_tag_completion *resp =
4956 		(struct i40e_aqc_update_tag_completion *)&desc.params.raw;
4957 	enum i40e_status_code status;
4958 
4959 	if (vsi_seid == 0)
4960 		return I40E_ERR_PARAM;
4961 
4962 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_update_tag);
4963 
4964 	cmd->seid = CPU_TO_LE16(vsi_seid);
4965 	cmd->old_tag = CPU_TO_LE16(old_tag);
4966 	cmd->new_tag = CPU_TO_LE16(new_tag);
4967 
4968 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4969 
4970 	if (!status) {
4971 		if (tags_used != NULL)
4972 			*tags_used = LE16_TO_CPU(resp->tags_used);
4973 		if (tags_free != NULL)
4974 			*tags_free = LE16_TO_CPU(resp->tags_free);
4975 	}
4976 
4977 	return status;
4978 }
4979 
4980 /**
4981  * i40e_aq_dcb_ignore_pfc - Ignore PFC for given TCs
4982  * @hw: pointer to the hw struct
4983  * @tcmap: TC map for request/release any ignore PFC condition
4984  * @request: request or release ignore PFC condition
4985  * @tcmap_ret: return TCs for which PFC is currently ignored
4986  * @cmd_details: pointer to command details structure or NULL
4987  *
4988  * This sends out request/release to ignore PFC condition for a TC.
4989  * It will return the TCs for which PFC is currently ignored.
4990  **/
i40e_aq_dcb_ignore_pfc(struct i40e_hw * hw,u8 tcmap,bool request,u8 * tcmap_ret,struct i40e_asq_cmd_details * cmd_details)4991 enum i40e_status_code i40e_aq_dcb_ignore_pfc(struct i40e_hw *hw, u8 tcmap,
4992 				bool request, u8 *tcmap_ret,
4993 				struct i40e_asq_cmd_details *cmd_details)
4994 {
4995 	struct i40e_aq_desc desc;
4996 	struct i40e_aqc_pfc_ignore *cmd_resp =
4997 		(struct i40e_aqc_pfc_ignore *)&desc.params.raw;
4998 	enum i40e_status_code status;
4999 
5000 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_ignore_pfc);
5001 
5002 	if (request)
5003 		cmd_resp->command_flags = I40E_AQC_PFC_IGNORE_SET;
5004 
5005 	cmd_resp->tc_bitmap = tcmap;
5006 
5007 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5008 
5009 	if (!status) {
5010 		if (tcmap_ret != NULL)
5011 			*tcmap_ret = cmd_resp->tc_bitmap;
5012 	}
5013 
5014 	return status;
5015 }
5016 
5017 /**
5018  * i40e_aq_dcb_updated - DCB Updated Command
5019  * @hw: pointer to the hw struct
5020  * @cmd_details: pointer to command details structure or NULL
5021  *
5022  * When LLDP is handled in PF this command is used by the PF
5023  * to notify EMP that a DCB setting is modified.
5024  * When LLDP is handled in EMP this command is used by the PF
5025  * to notify EMP whenever one of the following parameters get
5026  * modified:
5027  *   - PFCLinkDelayAllowance in PRTDCB_GENC.PFCLDA
5028  *   - PCIRTT in PRTDCB_GENC.PCIRTT
5029  *   - Maximum Frame Size for non-FCoE TCs set by PRTDCB_TDPUC.MAX_TXFRAME.
5030  * EMP will return when the shared RPB settings have been
5031  * recomputed and modified. The retval field in the descriptor
5032  * will be set to 0 when RPB is modified.
5033  **/
i40e_aq_dcb_updated(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)5034 enum i40e_status_code i40e_aq_dcb_updated(struct i40e_hw *hw,
5035 				struct i40e_asq_cmd_details *cmd_details)
5036 {
5037 	struct i40e_aq_desc desc;
5038 	enum i40e_status_code status;
5039 
5040 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_updated);
5041 
5042 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5043 
5044 	return status;
5045 }
5046 
5047 /**
5048  * i40e_aq_add_statistics - Add a statistics block to a VLAN in a switch.
5049  * @hw: pointer to the hw struct
5050  * @seid: defines the SEID of the switch for which the stats are requested
5051  * @vlan_id: the VLAN ID for which the statistics are requested
5052  * @stat_index: index of the statistics counters block assigned to this VLAN
5053  * @cmd_details: pointer to command details structure or NULL
5054  *
5055  * XL710 supports 128 smonVlanStats counters.This command is used to
5056  * allocate a set of smonVlanStats counters to a specific VLAN in a specific
5057  * switch.
5058  **/
i40e_aq_add_statistics(struct i40e_hw * hw,u16 seid,u16 vlan_id,u16 * stat_index,struct i40e_asq_cmd_details * cmd_details)5059 enum i40e_status_code i40e_aq_add_statistics(struct i40e_hw *hw, u16 seid,
5060 				u16 vlan_id, u16 *stat_index,
5061 				struct i40e_asq_cmd_details *cmd_details)
5062 {
5063 	struct i40e_aq_desc desc;
5064 	struct i40e_aqc_add_remove_statistics *cmd_resp =
5065 		(struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
5066 	enum i40e_status_code status;
5067 
5068 	if ((seid == 0) || (stat_index == NULL))
5069 		return I40E_ERR_PARAM;
5070 
5071 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_statistics);
5072 
5073 	cmd_resp->seid = CPU_TO_LE16(seid);
5074 	cmd_resp->vlan = CPU_TO_LE16(vlan_id);
5075 
5076 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5077 
5078 	if (!status && stat_index)
5079 		*stat_index = LE16_TO_CPU(cmd_resp->stat_index);
5080 
5081 	return status;
5082 }
5083 
5084 /**
5085  * i40e_aq_remove_statistics - Remove a statistics block to a VLAN in a switch.
5086  * @hw: pointer to the hw struct
5087  * @seid: defines the SEID of the switch for which the stats are requested
5088  * @vlan_id: the VLAN ID for which the statistics are requested
5089  * @stat_index: index of the statistics counters block assigned to this VLAN
5090  * @cmd_details: pointer to command details structure or NULL
5091  *
5092  * XL710 supports 128 smonVlanStats counters.This command is used to
5093  * deallocate a set of smonVlanStats counters to a specific VLAN in a specific
5094  * switch.
5095  **/
i40e_aq_remove_statistics(struct i40e_hw * hw,u16 seid,u16 vlan_id,u16 stat_index,struct i40e_asq_cmd_details * cmd_details)5096 enum i40e_status_code i40e_aq_remove_statistics(struct i40e_hw *hw, u16 seid,
5097 				u16 vlan_id, u16 stat_index,
5098 				struct i40e_asq_cmd_details *cmd_details)
5099 {
5100 	struct i40e_aq_desc desc;
5101 	struct i40e_aqc_add_remove_statistics *cmd =
5102 		(struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
5103 	enum i40e_status_code status;
5104 
5105 	if (seid == 0)
5106 		return I40E_ERR_PARAM;
5107 
5108 	i40e_fill_default_direct_cmd_desc(&desc,
5109 					  i40e_aqc_opc_remove_statistics);
5110 
5111 	cmd->seid = CPU_TO_LE16(seid);
5112 	cmd->vlan  = CPU_TO_LE16(vlan_id);
5113 	cmd->stat_index = CPU_TO_LE16(stat_index);
5114 
5115 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5116 
5117 	return status;
5118 }
5119 
5120 /**
5121  * i40e_aq_set_port_parameters - set physical port parameters.
5122  * @hw: pointer to the hw struct
5123  * @bad_frame_vsi: defines the VSI to which bad frames are forwarded
5124  * @save_bad_pac: if set packets with errors are forwarded to the bad frames VSI
5125  * @pad_short_pac: if set transmit packets smaller than 60 bytes are padded
5126  * @double_vlan: if set double VLAN is enabled
5127  * @cmd_details: pointer to command details structure or NULL
5128  **/
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)5129 enum i40e_status_code i40e_aq_set_port_parameters(struct i40e_hw *hw,
5130 				u16 bad_frame_vsi, bool save_bad_pac,
5131 				bool pad_short_pac, bool double_vlan,
5132 				struct i40e_asq_cmd_details *cmd_details)
5133 {
5134 	struct i40e_aqc_set_port_parameters *cmd;
5135 	enum i40e_status_code status;
5136 	struct i40e_aq_desc desc;
5137 	u16 command_flags = 0;
5138 
5139 	cmd = (struct i40e_aqc_set_port_parameters *)&desc.params.raw;
5140 
5141 	i40e_fill_default_direct_cmd_desc(&desc,
5142 					  i40e_aqc_opc_set_port_parameters);
5143 
5144 	cmd->bad_frame_vsi = CPU_TO_LE16(bad_frame_vsi);
5145 	if (save_bad_pac)
5146 		command_flags |= I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS;
5147 	if (pad_short_pac)
5148 		command_flags |= I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS;
5149 	if (double_vlan)
5150 		command_flags |= I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA;
5151 	cmd->command_flags = CPU_TO_LE16(command_flags);
5152 
5153 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5154 
5155 	return status;
5156 }
5157 
5158 /**
5159  * i40e_aq_tx_sched_cmd - generic Tx scheduler AQ command handler
5160  * @hw: pointer to the hw struct
5161  * @seid: seid for the physical port/switching component/vsi
5162  * @buff: Indirect buffer to hold data parameters and response
5163  * @buff_size: Indirect buffer size
5164  * @opcode: Tx scheduler AQ command opcode
5165  * @cmd_details: pointer to command details structure or NULL
5166  *
5167  * Generic command handler for Tx scheduler AQ commands
5168  **/
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)5169 static enum i40e_status_code i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
5170 				void *buff, u16 buff_size,
5171 				 enum i40e_admin_queue_opc opcode,
5172 				struct i40e_asq_cmd_details *cmd_details)
5173 {
5174 	struct i40e_aq_desc desc;
5175 	struct i40e_aqc_tx_sched_ind *cmd =
5176 		(struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
5177 	enum i40e_status_code status;
5178 	bool cmd_param_flag = FALSE;
5179 
5180 	switch (opcode) {
5181 	case i40e_aqc_opc_configure_vsi_ets_sla_bw_limit:
5182 	case i40e_aqc_opc_configure_vsi_tc_bw:
5183 	case i40e_aqc_opc_enable_switching_comp_ets:
5184 	case i40e_aqc_opc_modify_switching_comp_ets:
5185 	case i40e_aqc_opc_disable_switching_comp_ets:
5186 	case i40e_aqc_opc_configure_switching_comp_ets_bw_limit:
5187 	case i40e_aqc_opc_configure_switching_comp_bw_config:
5188 		cmd_param_flag = TRUE;
5189 		break;
5190 	case i40e_aqc_opc_query_vsi_bw_config:
5191 	case i40e_aqc_opc_query_vsi_ets_sla_config:
5192 	case i40e_aqc_opc_query_switching_comp_ets_config:
5193 	case i40e_aqc_opc_query_port_ets_config:
5194 	case i40e_aqc_opc_query_switching_comp_bw_config:
5195 		cmd_param_flag = FALSE;
5196 		break;
5197 	default:
5198 		return I40E_ERR_PARAM;
5199 	}
5200 
5201 	i40e_fill_default_direct_cmd_desc(&desc, opcode);
5202 
5203 	/* Indirect command */
5204 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
5205 	if (cmd_param_flag)
5206 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
5207 	if (buff_size > I40E_AQ_LARGE_BUF)
5208 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5209 
5210 	desc.datalen = CPU_TO_LE16(buff_size);
5211 
5212 	cmd->vsi_seid = CPU_TO_LE16(seid);
5213 
5214 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5215 
5216 	return status;
5217 }
5218 
5219 /**
5220  * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
5221  * @hw: pointer to the hw struct
5222  * @seid: VSI seid
5223  * @credit: BW limit credits (0 = disabled)
5224  * @max_credit: Max BW limit credits
5225  * @cmd_details: pointer to command details structure or NULL
5226  **/
i40e_aq_config_vsi_bw_limit(struct i40e_hw * hw,u16 seid,u16 credit,u8 max_credit,struct i40e_asq_cmd_details * cmd_details)5227 enum i40e_status_code i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
5228 				u16 seid, u16 credit, u8 max_credit,
5229 				struct i40e_asq_cmd_details *cmd_details)
5230 {
5231 	struct i40e_aq_desc desc;
5232 	struct i40e_aqc_configure_vsi_bw_limit *cmd =
5233 		(struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
5234 	enum i40e_status_code status;
5235 
5236 	i40e_fill_default_direct_cmd_desc(&desc,
5237 					  i40e_aqc_opc_configure_vsi_bw_limit);
5238 
5239 	cmd->vsi_seid = CPU_TO_LE16(seid);
5240 	cmd->credit = CPU_TO_LE16(credit);
5241 	cmd->max_credit = max_credit;
5242 
5243 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5244 
5245 	return status;
5246 }
5247 
5248 /**
5249  * i40e_aq_config_switch_comp_bw_limit - Configure Switching component BW Limit
5250  * @hw: pointer to the hw struct
5251  * @seid: switching component seid
5252  * @credit: BW limit credits (0 = disabled)
5253  * @max_bw: Max BW limit credits
5254  * @cmd_details: pointer to command details structure or NULL
5255  **/
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)5256 enum i40e_status_code i40e_aq_config_switch_comp_bw_limit(struct i40e_hw *hw,
5257 				u16 seid, u16 credit, u8 max_bw,
5258 				struct i40e_asq_cmd_details *cmd_details)
5259 {
5260 	struct i40e_aq_desc desc;
5261 	struct i40e_aqc_configure_switching_comp_bw_limit *cmd =
5262 	  (struct i40e_aqc_configure_switching_comp_bw_limit *)&desc.params.raw;
5263 	enum i40e_status_code status;
5264 
5265 	i40e_fill_default_direct_cmd_desc(&desc,
5266 				i40e_aqc_opc_configure_switching_comp_bw_limit);
5267 
5268 	cmd->seid = CPU_TO_LE16(seid);
5269 	cmd->credit = CPU_TO_LE16(credit);
5270 	cmd->max_bw = max_bw;
5271 
5272 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5273 
5274 	return status;
5275 }
5276 
5277 /**
5278  * i40e_aq_config_vsi_ets_sla_bw_limit - Config VSI BW Limit per TC
5279  * @hw: pointer to the hw struct
5280  * @seid: VSI seid
5281  * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
5282  * @cmd_details: pointer to command details structure or NULL
5283  **/
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)5284 enum i40e_status_code i40e_aq_config_vsi_ets_sla_bw_limit(struct i40e_hw *hw,
5285 			u16 seid,
5286 			struct i40e_aqc_configure_vsi_ets_sla_bw_data *bw_data,
5287 			struct i40e_asq_cmd_details *cmd_details)
5288 {
5289 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5290 				    i40e_aqc_opc_configure_vsi_ets_sla_bw_limit,
5291 				    cmd_details);
5292 }
5293 
5294 /**
5295  * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
5296  * @hw: pointer to the hw struct
5297  * @seid: VSI seid
5298  * @bw_data: Buffer holding enabled TCs, relative TC BW limit/credits
5299  * @cmd_details: pointer to command details structure or NULL
5300  **/
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)5301 enum i40e_status_code i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
5302 			u16 seid,
5303 			struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
5304 			struct i40e_asq_cmd_details *cmd_details)
5305 {
5306 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5307 				    i40e_aqc_opc_configure_vsi_tc_bw,
5308 				    cmd_details);
5309 }
5310 
5311 /**
5312  * i40e_aq_config_switch_comp_ets_bw_limit - Config Switch comp BW Limit per TC
5313  * @hw: pointer to the hw struct
5314  * @seid: seid of the switching component
5315  * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
5316  * @cmd_details: pointer to command details structure or NULL
5317  **/
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)5318 enum i40e_status_code i40e_aq_config_switch_comp_ets_bw_limit(
5319 	struct i40e_hw *hw, u16 seid,
5320 	struct i40e_aqc_configure_switching_comp_ets_bw_limit_data *bw_data,
5321 	struct i40e_asq_cmd_details *cmd_details)
5322 {
5323 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5324 			    i40e_aqc_opc_configure_switching_comp_ets_bw_limit,
5325 			    cmd_details);
5326 }
5327 
5328 /**
5329  * i40e_aq_query_vsi_bw_config - Query VSI BW configuration
5330  * @hw: pointer to the hw struct
5331  * @seid: seid of the VSI
5332  * @bw_data: Buffer to hold VSI BW configuration
5333  * @cmd_details: pointer to command details structure or NULL
5334  **/
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)5335 enum i40e_status_code i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
5336 			u16 seid,
5337 			struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
5338 			struct i40e_asq_cmd_details *cmd_details)
5339 {
5340 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5341 				    i40e_aqc_opc_query_vsi_bw_config,
5342 				    cmd_details);
5343 }
5344 
5345 /**
5346  * i40e_aq_query_vsi_ets_sla_config - Query VSI BW configuration per TC
5347  * @hw: pointer to the hw struct
5348  * @seid: seid of the VSI
5349  * @bw_data: Buffer to hold VSI BW configuration per TC
5350  * @cmd_details: pointer to command details structure or NULL
5351  **/
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)5352 enum i40e_status_code i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
5353 			u16 seid,
5354 			struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
5355 			struct i40e_asq_cmd_details *cmd_details)
5356 {
5357 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5358 				    i40e_aqc_opc_query_vsi_ets_sla_config,
5359 				    cmd_details);
5360 }
5361 
5362 /**
5363  * i40e_aq_query_switch_comp_ets_config - Query Switch comp BW config per TC
5364  * @hw: pointer to the hw struct
5365  * @seid: seid of the switching component
5366  * @bw_data: Buffer to hold switching component's per TC BW config
5367  * @cmd_details: pointer to command details structure or NULL
5368  **/
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)5369 enum i40e_status_code i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
5370 		u16 seid,
5371 		struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
5372 		struct i40e_asq_cmd_details *cmd_details)
5373 {
5374 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5375 				   i40e_aqc_opc_query_switching_comp_ets_config,
5376 				   cmd_details);
5377 }
5378 
5379 /**
5380  * i40e_aq_query_port_ets_config - Query Physical Port ETS configuration
5381  * @hw: pointer to the hw struct
5382  * @seid: seid of the VSI or switching component connected to Physical Port
5383  * @bw_data: Buffer to hold current ETS configuration for the Physical Port
5384  * @cmd_details: pointer to command details structure or NULL
5385  **/
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)5386 enum i40e_status_code i40e_aq_query_port_ets_config(struct i40e_hw *hw,
5387 			u16 seid,
5388 			struct i40e_aqc_query_port_ets_config_resp *bw_data,
5389 			struct i40e_asq_cmd_details *cmd_details)
5390 {
5391 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5392 				    i40e_aqc_opc_query_port_ets_config,
5393 				    cmd_details);
5394 }
5395 
5396 /**
5397  * i40e_aq_query_switch_comp_bw_config - Query Switch comp BW configuration
5398  * @hw: pointer to the hw struct
5399  * @seid: seid of the switching component
5400  * @bw_data: Buffer to hold switching component's BW configuration
5401  * @cmd_details: pointer to command details structure or NULL
5402  **/
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)5403 enum i40e_status_code i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
5404 		u16 seid,
5405 		struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
5406 		struct i40e_asq_cmd_details *cmd_details)
5407 {
5408 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5409 				    i40e_aqc_opc_query_switching_comp_bw_config,
5410 				    cmd_details);
5411 }
5412 
5413 /**
5414  * i40e_validate_filter_settings
5415  * @hw: pointer to the hardware structure
5416  * @settings: Filter control settings
5417  *
5418  * Check and validate the filter control settings passed.
5419  * The function checks for the valid filter/context sizes being
5420  * passed for FCoE and PE.
5421  *
5422  * Returns I40E_SUCCESS if the values passed are valid and within
5423  * range else returns an error.
5424  **/
i40e_validate_filter_settings(struct i40e_hw * hw,struct i40e_filter_control_settings * settings)5425 static enum i40e_status_code i40e_validate_filter_settings(struct i40e_hw *hw,
5426 				struct i40e_filter_control_settings *settings)
5427 {
5428 	u32 fcoe_cntx_size, fcoe_filt_size;
5429 	u32 fcoe_fmax;
5430 
5431 	u32 val;
5432 
5433 	/* Validate FCoE settings passed */
5434 	switch (settings->fcoe_filt_num) {
5435 	case I40E_HASH_FILTER_SIZE_1K:
5436 	case I40E_HASH_FILTER_SIZE_2K:
5437 	case I40E_HASH_FILTER_SIZE_4K:
5438 	case I40E_HASH_FILTER_SIZE_8K:
5439 	case I40E_HASH_FILTER_SIZE_16K:
5440 	case I40E_HASH_FILTER_SIZE_32K:
5441 		fcoe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
5442 		fcoe_filt_size <<= (u32)settings->fcoe_filt_num;
5443 		break;
5444 	default:
5445 		return I40E_ERR_PARAM;
5446 	}
5447 
5448 	switch (settings->fcoe_cntx_num) {
5449 	case I40E_DMA_CNTX_SIZE_512:
5450 	case I40E_DMA_CNTX_SIZE_1K:
5451 	case I40E_DMA_CNTX_SIZE_2K:
5452 	case I40E_DMA_CNTX_SIZE_4K:
5453 		fcoe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
5454 		fcoe_cntx_size <<= (u32)settings->fcoe_cntx_num;
5455 		break;
5456 	default:
5457 		return I40E_ERR_PARAM;
5458 	}
5459 
5460 	/* Validate PE settings passed */
5461 	switch (settings->pe_filt_num) {
5462 	case I40E_HASH_FILTER_SIZE_1K:
5463 	case I40E_HASH_FILTER_SIZE_2K:
5464 	case I40E_HASH_FILTER_SIZE_4K:
5465 	case I40E_HASH_FILTER_SIZE_8K:
5466 	case I40E_HASH_FILTER_SIZE_16K:
5467 	case I40E_HASH_FILTER_SIZE_32K:
5468 	case I40E_HASH_FILTER_SIZE_64K:
5469 	case I40E_HASH_FILTER_SIZE_128K:
5470 	case I40E_HASH_FILTER_SIZE_256K:
5471 	case I40E_HASH_FILTER_SIZE_512K:
5472 	case I40E_HASH_FILTER_SIZE_1M:
5473 		break;
5474 	default:
5475 		return I40E_ERR_PARAM;
5476 	}
5477 
5478 	switch (settings->pe_cntx_num) {
5479 	case I40E_DMA_CNTX_SIZE_512:
5480 	case I40E_DMA_CNTX_SIZE_1K:
5481 	case I40E_DMA_CNTX_SIZE_2K:
5482 	case I40E_DMA_CNTX_SIZE_4K:
5483 	case I40E_DMA_CNTX_SIZE_8K:
5484 	case I40E_DMA_CNTX_SIZE_16K:
5485 	case I40E_DMA_CNTX_SIZE_32K:
5486 	case I40E_DMA_CNTX_SIZE_64K:
5487 	case I40E_DMA_CNTX_SIZE_128K:
5488 	case I40E_DMA_CNTX_SIZE_256K:
5489 		break;
5490 	default:
5491 		return I40E_ERR_PARAM;
5492 	}
5493 
5494 	/* FCHSIZE + FCDSIZE should not be greater than PMFCOEFMAX */
5495 	val = rd32(hw, I40E_GLHMC_FCOEFMAX);
5496 	fcoe_fmax = (val & I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK)
5497 		     >> I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT;
5498 	if (fcoe_filt_size + fcoe_cntx_size >  fcoe_fmax)
5499 		return I40E_ERR_INVALID_SIZE;
5500 
5501 	return I40E_SUCCESS;
5502 }
5503 
5504 /**
5505  * i40e_set_filter_control
5506  * @hw: pointer to the hardware structure
5507  * @settings: Filter control settings
5508  *
5509  * Set the Queue Filters for PE/FCoE and enable filters required
5510  * for a single PF. It is expected that these settings are programmed
5511  * at the driver initialization time.
5512  **/
i40e_set_filter_control(struct i40e_hw * hw,struct i40e_filter_control_settings * settings)5513 enum i40e_status_code i40e_set_filter_control(struct i40e_hw *hw,
5514 				struct i40e_filter_control_settings *settings)
5515 {
5516 	enum i40e_status_code ret = I40E_SUCCESS;
5517 	u32 hash_lut_size = 0;
5518 	u32 val;
5519 
5520 	if (!settings)
5521 		return I40E_ERR_PARAM;
5522 
5523 	/* Validate the input settings */
5524 	ret = i40e_validate_filter_settings(hw, settings);
5525 	if (ret)
5526 		return ret;
5527 
5528 	/* Read the PF Queue Filter control register */
5529 	val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
5530 
5531 	/* Program required PE hash buckets for the PF */
5532 	val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
5533 	val |= ((u32)settings->pe_filt_num << I40E_PFQF_CTL_0_PEHSIZE_SHIFT) &
5534 		I40E_PFQF_CTL_0_PEHSIZE_MASK;
5535 	/* Program required PE contexts for the PF */
5536 	val &= ~I40E_PFQF_CTL_0_PEDSIZE_MASK;
5537 	val |= ((u32)settings->pe_cntx_num << I40E_PFQF_CTL_0_PEDSIZE_SHIFT) &
5538 		I40E_PFQF_CTL_0_PEDSIZE_MASK;
5539 
5540 	/* Program required FCoE hash buckets for the PF */
5541 	val &= ~I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5542 	val |= ((u32)settings->fcoe_filt_num <<
5543 			I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT) &
5544 		I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5545 	/* Program required FCoE DDP contexts for the PF */
5546 	val &= ~I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5547 	val |= ((u32)settings->fcoe_cntx_num <<
5548 			I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT) &
5549 		I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5550 
5551 	/* Program Hash LUT size for the PF */
5552 	val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5553 	if (settings->hash_lut_size == I40E_HASH_LUT_SIZE_512)
5554 		hash_lut_size = 1;
5555 	val |= (hash_lut_size << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT) &
5556 		I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5557 
5558 	/* Enable FDIR, Ethertype and MACVLAN filters for PF and VFs */
5559 	if (settings->enable_fdir)
5560 		val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
5561 	if (settings->enable_ethtype)
5562 		val |= I40E_PFQF_CTL_0_ETYPE_ENA_MASK;
5563 	if (settings->enable_macvlan)
5564 		val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
5565 
5566 	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
5567 
5568 	return I40E_SUCCESS;
5569 }
5570 
5571 /**
5572  * i40e_aq_add_rem_control_packet_filter - Add or Remove Control Packet Filter
5573  * @hw: pointer to the hw struct
5574  * @mac_addr: MAC address to use in the filter
5575  * @ethtype: Ethertype to use in the filter
5576  * @flags: Flags that needs to be applied to the filter
5577  * @vsi_seid: seid of the control VSI
5578  * @queue: VSI queue number to send the packet to
5579  * @is_add: Add control packet filter if True else remove
5580  * @stats: Structure to hold information on control filter counts
5581  * @cmd_details: pointer to command details structure or NULL
5582  *
5583  * This command will Add or Remove control packet filter for a control VSI.
5584  * In return it will update the total number of perfect filter count in
5585  * the stats member.
5586  **/
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)5587 enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
5588 				u8 *mac_addr, u16 ethtype, u16 flags,
5589 				u16 vsi_seid, u16 queue, bool is_add,
5590 				struct i40e_control_filter_stats *stats,
5591 				struct i40e_asq_cmd_details *cmd_details)
5592 {
5593 	struct i40e_aq_desc desc;
5594 	struct i40e_aqc_add_remove_control_packet_filter *cmd =
5595 		(struct i40e_aqc_add_remove_control_packet_filter *)
5596 		&desc.params.raw;
5597 	struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
5598 		(struct i40e_aqc_add_remove_control_packet_filter_completion *)
5599 		&desc.params.raw;
5600 	enum i40e_status_code status;
5601 
5602 	if (vsi_seid == 0)
5603 		return I40E_ERR_PARAM;
5604 
5605 	if (is_add) {
5606 		i40e_fill_default_direct_cmd_desc(&desc,
5607 				i40e_aqc_opc_add_control_packet_filter);
5608 		cmd->queue = CPU_TO_LE16(queue);
5609 	} else {
5610 		i40e_fill_default_direct_cmd_desc(&desc,
5611 				i40e_aqc_opc_remove_control_packet_filter);
5612 	}
5613 
5614 	if (mac_addr)
5615 		i40e_memcpy(cmd->mac, mac_addr, ETH_ALEN,
5616 			    I40E_NONDMA_TO_NONDMA);
5617 
5618 	cmd->etype = CPU_TO_LE16(ethtype);
5619 	cmd->flags = CPU_TO_LE16(flags);
5620 	cmd->seid = CPU_TO_LE16(vsi_seid);
5621 
5622 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5623 
5624 	if (!status && stats) {
5625 		stats->mac_etype_used = LE16_TO_CPU(resp->mac_etype_used);
5626 		stats->etype_used = LE16_TO_CPU(resp->etype_used);
5627 		stats->mac_etype_free = LE16_TO_CPU(resp->mac_etype_free);
5628 		stats->etype_free = LE16_TO_CPU(resp->etype_free);
5629 	}
5630 
5631 	return status;
5632 }
5633 
5634 /**
5635  * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
5636  * @hw: pointer to the hw struct
5637  * @seid: VSI seid to add ethertype filter from
5638  **/
i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw * hw,u16 seid)5639 void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
5640 						    u16 seid)
5641 {
5642 #define I40E_FLOW_CONTROL_ETHTYPE 0x8808
5643 	u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
5644 		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
5645 		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
5646 	u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
5647 	enum i40e_status_code status;
5648 
5649 	status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
5650 						       seid, 0, TRUE, NULL,
5651 						       NULL);
5652 	if (status)
5653 		DEBUGOUT("Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
5654 }
5655 
5656 /**
5657  * i40e_fix_up_geneve_vni - adjust Geneve VNI for HW issue
5658  * @filters: list of cloud filters
5659  * @filter_count: length of list
5660  *
5661  * There's an issue in the device where the Geneve VNI layout needs
5662  * to be shifted 1 byte over from the VxLAN VNI
5663  **/
i40e_fix_up_geneve_vni(struct i40e_aqc_cloud_filters_element_data * filters,u8 filter_count)5664 static void i40e_fix_up_geneve_vni(
5665 	struct i40e_aqc_cloud_filters_element_data *filters,
5666 	u8 filter_count)
5667 {
5668 	struct i40e_aqc_cloud_filters_element_data *f = filters;
5669 	int i;
5670 
5671 	for (i = 0; i < filter_count; i++) {
5672 		u16 tnl_type;
5673 		u32 ti;
5674 
5675 		tnl_type = (LE16_TO_CPU(f[i].flags) &
5676 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5677 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5678 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5679 			ti = LE32_TO_CPU(f[i].tenant_id);
5680 			f[i].tenant_id = CPU_TO_LE32(ti << 8);
5681 		}
5682 	}
5683 }
5684 
5685 /**
5686  * i40e_aq_add_cloud_filters
5687  * @hw: pointer to the hardware structure
5688  * @seid: VSI seid to add cloud filters from
5689  * @filters: Buffer which contains the filters to be added
5690  * @filter_count: number of filters contained in the buffer
5691  *
5692  * Set the cloud filters for a given VSI.  The contents of the
5693  * i40e_aqc_cloud_filters_element_data are filled
5694  * in by the caller of the function.
5695  *
5696  **/
i40e_aq_add_cloud_filters(struct i40e_hw * hw,u16 seid,struct i40e_aqc_cloud_filters_element_data * filters,u8 filter_count)5697 enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
5698 	u16 seid,
5699 	struct i40e_aqc_cloud_filters_element_data *filters,
5700 	u8 filter_count)
5701 {
5702 	struct i40e_aq_desc desc;
5703 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5704 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5705 	enum i40e_status_code status;
5706 	u16 buff_len;
5707 
5708 	i40e_fill_default_direct_cmd_desc(&desc,
5709 					  i40e_aqc_opc_add_cloud_filters);
5710 
5711 	buff_len = filter_count * sizeof(*filters);
5712 	desc.datalen = CPU_TO_LE16(buff_len);
5713 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5714 	cmd->num_filters = filter_count;
5715 	cmd->seid = CPU_TO_LE16(seid);
5716 
5717 	i40e_fix_up_geneve_vni(filters, filter_count);
5718 
5719 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5720 
5721 	return status;
5722 }
5723 
5724 /**
5725  * i40e_aq_add_cloud_filters_bb
5726  * @hw: pointer to the hardware structure
5727  * @seid: VSI seid to add cloud filters from
5728  * @filters: Buffer which contains the filters in big buffer to be added
5729  * @filter_count: number of filters contained in the buffer
5730  *
5731  * Set the cloud filters for a given VSI.  The contents of the
5732  * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5733  * the function.
5734  *
5735  **/
5736 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)5737 i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5738 			     struct i40e_aqc_cloud_filters_element_bb *filters,
5739 			     u8 filter_count)
5740 {
5741 	struct i40e_aq_desc desc;
5742 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5743 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5744 	enum i40e_status_code status;
5745 	u16 buff_len;
5746 	int i;
5747 
5748 	i40e_fill_default_direct_cmd_desc(&desc,
5749 					  i40e_aqc_opc_add_cloud_filters);
5750 
5751 	buff_len = filter_count * sizeof(*filters);
5752 	desc.datalen = CPU_TO_LE16(buff_len);
5753 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5754 	cmd->num_filters = filter_count;
5755 	cmd->seid = CPU_TO_LE16(seid);
5756 	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5757 
5758 	for (i = 0; i < filter_count; i++) {
5759 		u16 tnl_type;
5760 		u32 ti;
5761 
5762 		tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5763 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5764 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5765 
5766 		/* Due to hardware eccentricities, the VNI for Geneve is shifted
5767 		 * one more byte further than normally used for Tenant ID in
5768 		 * other tunnel types.
5769 		 */
5770 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5771 			ti = LE32_TO_CPU(filters[i].element.tenant_id);
5772 			filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5773 		}
5774 	}
5775 
5776 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5777 
5778 	return status;
5779 }
5780 
5781 /**
5782  * i40e_aq_rem_cloud_filters
5783  * @hw: pointer to the hardware structure
5784  * @seid: VSI seid to remove cloud filters from
5785  * @filters: Buffer which contains the filters to be removed
5786  * @filter_count: number of filters contained in the buffer
5787  *
5788  * Remove the cloud filters for a given VSI.  The contents of the
5789  * i40e_aqc_cloud_filters_element_data are filled in by the caller
5790  * of the function.
5791  *
5792  **/
5793 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)5794 i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
5795 			  struct i40e_aqc_cloud_filters_element_data *filters,
5796 			  u8 filter_count)
5797 {
5798 	struct i40e_aq_desc desc;
5799 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5800 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5801 	enum i40e_status_code status;
5802 	u16 buff_len;
5803 
5804 	i40e_fill_default_direct_cmd_desc(&desc,
5805 					  i40e_aqc_opc_remove_cloud_filters);
5806 
5807 	buff_len = filter_count * sizeof(*filters);
5808 	desc.datalen = CPU_TO_LE16(buff_len);
5809 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5810 	cmd->num_filters = filter_count;
5811 	cmd->seid = CPU_TO_LE16(seid);
5812 
5813 	i40e_fix_up_geneve_vni(filters, filter_count);
5814 
5815 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5816 
5817 	return status;
5818 }
5819 
5820 /**
5821  * i40e_aq_rem_cloud_filters_bb
5822  * @hw: pointer to the hardware structure
5823  * @seid: VSI seid to remove cloud filters from
5824  * @filters: Buffer which contains the filters in big buffer to be removed
5825  * @filter_count: number of filters contained in the buffer
5826  *
5827  * Remove the big buffer cloud filters for a given VSI.  The contents of the
5828  * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5829  * function.
5830  *
5831  **/
5832 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)5833 i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5834 			     struct i40e_aqc_cloud_filters_element_bb *filters,
5835 			     u8 filter_count)
5836 {
5837 	struct i40e_aq_desc desc;
5838 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5839 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5840 	enum i40e_status_code status;
5841 	u16 buff_len;
5842 	int i;
5843 
5844 	i40e_fill_default_direct_cmd_desc(&desc,
5845 					  i40e_aqc_opc_remove_cloud_filters);
5846 
5847 	buff_len = filter_count * sizeof(*filters);
5848 	desc.datalen = CPU_TO_LE16(buff_len);
5849 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5850 	cmd->num_filters = filter_count;
5851 	cmd->seid = CPU_TO_LE16(seid);
5852 	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5853 
5854 	for (i = 0; i < filter_count; i++) {
5855 		u16 tnl_type;
5856 		u32 ti;
5857 
5858 		tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5859 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5860 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5861 
5862 		/* Due to hardware eccentricities, the VNI for Geneve is shifted
5863 		 * one more byte further than normally used for Tenant ID in
5864 		 * other tunnel types.
5865 		 */
5866 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5867 			ti = LE32_TO_CPU(filters[i].element.tenant_id);
5868 			filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5869 		}
5870 	}
5871 
5872 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5873 
5874 	return status;
5875 }
5876 
5877 /**
5878  * i40e_aq_replace_cloud_filters - Replace cloud filter command
5879  * @hw: pointer to the hw struct
5880  * @filters: pointer to the i40e_aqc_replace_cloud_filter_cmd struct
5881  * @cmd_buf: pointer to the i40e_aqc_replace_cloud_filter_cmd_buf struct
5882  *
5883  **/
5884 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)5885 i40e_status_code i40e_aq_replace_cloud_filters(struct i40e_hw *hw,
5886 	struct i40e_aqc_replace_cloud_filters_cmd *filters,
5887 	struct i40e_aqc_replace_cloud_filters_cmd_buf *cmd_buf)
5888 {
5889 	struct i40e_aq_desc desc;
5890 	struct i40e_aqc_replace_cloud_filters_cmd *cmd =
5891 		(struct i40e_aqc_replace_cloud_filters_cmd *)&desc.params.raw;
5892 	enum i40e_status_code status = I40E_SUCCESS;
5893 	int i = 0;
5894 
5895 	/* X722 doesn't support this command */
5896 	if (hw->mac.type == I40E_MAC_X722)
5897 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
5898 
5899 	/* need FW version greater than 6.00 */
5900 	if (hw->aq.fw_maj_ver < 6)
5901 		return I40E_NOT_SUPPORTED;
5902 
5903 	i40e_fill_default_direct_cmd_desc(&desc,
5904 					  i40e_aqc_opc_replace_cloud_filters);
5905 
5906 	desc.datalen = CPU_TO_LE16(32);
5907 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5908 	cmd->old_filter_type = filters->old_filter_type;
5909 	cmd->new_filter_type = filters->new_filter_type;
5910 	cmd->valid_flags = filters->valid_flags;
5911 	cmd->tr_bit = filters->tr_bit;
5912 	cmd->tr_bit2 = filters->tr_bit2;
5913 
5914 	status = i40e_asq_send_command(hw, &desc, cmd_buf,
5915 		sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf),  NULL);
5916 
5917 	/* for get cloud filters command */
5918 	for (i = 0; i < 32; i += 4) {
5919 		cmd_buf->filters[i / 4].filter_type = cmd_buf->data[i];
5920 		cmd_buf->filters[i / 4].input[0] = cmd_buf->data[i + 1];
5921 		cmd_buf->filters[i / 4].input[1] = cmd_buf->data[i + 2];
5922 		cmd_buf->filters[i / 4].input[2] = cmd_buf->data[i + 3];
5923 	}
5924 
5925 	return status;
5926 }
5927 
5928 
5929 /**
5930  * i40e_aq_alternate_write
5931  * @hw: pointer to the hardware structure
5932  * @reg_addr0: address of first dword to be read
5933  * @reg_val0: value to be written under 'reg_addr0'
5934  * @reg_addr1: address of second dword to be read
5935  * @reg_val1: value to be written under 'reg_addr1'
5936  *
5937  * Write one or two dwords to alternate structure. Fields are indicated
5938  * by 'reg_addr0' and 'reg_addr1' register numbers.
5939  *
5940  **/
i40e_aq_alternate_write(struct i40e_hw * hw,u32 reg_addr0,u32 reg_val0,u32 reg_addr1,u32 reg_val1)5941 enum i40e_status_code i40e_aq_alternate_write(struct i40e_hw *hw,
5942 				u32 reg_addr0, u32 reg_val0,
5943 				u32 reg_addr1, u32 reg_val1)
5944 {
5945 	struct i40e_aq_desc desc;
5946 	struct i40e_aqc_alternate_write *cmd_resp =
5947 		(struct i40e_aqc_alternate_write *)&desc.params.raw;
5948 	enum i40e_status_code status;
5949 
5950 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_write);
5951 	cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
5952 	cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
5953 	cmd_resp->data0 = CPU_TO_LE32(reg_val0);
5954 	cmd_resp->data1 = CPU_TO_LE32(reg_val1);
5955 
5956 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5957 
5958 	return status;
5959 }
5960 
5961 /**
5962  * i40e_aq_alternate_write_indirect
5963  * @hw: pointer to the hardware structure
5964  * @addr: address of a first register to be modified
5965  * @dw_count: number of alternate structure fields to write
5966  * @buffer: pointer to the command buffer
5967  *
5968  * Write 'dw_count' dwords from 'buffer' to alternate structure
5969  * starting at 'addr'.
5970  *
5971  **/
i40e_aq_alternate_write_indirect(struct i40e_hw * hw,u32 addr,u32 dw_count,void * buffer)5972 enum i40e_status_code i40e_aq_alternate_write_indirect(struct i40e_hw *hw,
5973 				u32 addr, u32 dw_count, void *buffer)
5974 {
5975 	struct i40e_aq_desc desc;
5976 	struct i40e_aqc_alternate_ind_write *cmd_resp =
5977 		(struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
5978 	enum i40e_status_code status;
5979 
5980 	if (buffer == NULL)
5981 		return I40E_ERR_PARAM;
5982 
5983 	/* Indirect command */
5984 	i40e_fill_default_direct_cmd_desc(&desc,
5985 					 i40e_aqc_opc_alternate_write_indirect);
5986 
5987 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
5988 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
5989 	if (dw_count > (I40E_AQ_LARGE_BUF/4))
5990 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5991 
5992 	cmd_resp->address = CPU_TO_LE32(addr);
5993 	cmd_resp->length = CPU_TO_LE32(dw_count);
5994 
5995 	status = i40e_asq_send_command(hw, &desc, buffer,
5996 				       I40E_LO_DWORD(4*dw_count), NULL);
5997 
5998 	return status;
5999 }
6000 
6001 /**
6002  * i40e_aq_alternate_read
6003  * @hw: pointer to the hardware structure
6004  * @reg_addr0: address of first dword to be read
6005  * @reg_val0: pointer for data read from 'reg_addr0'
6006  * @reg_addr1: address of second dword to be read
6007  * @reg_val1: pointer for data read from 'reg_addr1'
6008  *
6009  * Read one or two dwords from alternate structure. Fields are indicated
6010  * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
6011  * is not passed then only register at 'reg_addr0' is read.
6012  *
6013  **/
i40e_aq_alternate_read(struct i40e_hw * hw,u32 reg_addr0,u32 * reg_val0,u32 reg_addr1,u32 * reg_val1)6014 enum i40e_status_code i40e_aq_alternate_read(struct i40e_hw *hw,
6015 				u32 reg_addr0, u32 *reg_val0,
6016 				u32 reg_addr1, u32 *reg_val1)
6017 {
6018 	struct i40e_aq_desc desc;
6019 	struct i40e_aqc_alternate_write *cmd_resp =
6020 		(struct i40e_aqc_alternate_write *)&desc.params.raw;
6021 	enum i40e_status_code status;
6022 
6023 	if (reg_val0 == NULL)
6024 		return I40E_ERR_PARAM;
6025 
6026 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
6027 	cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
6028 	cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
6029 
6030 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6031 
6032 	if (status == I40E_SUCCESS) {
6033 		*reg_val0 = LE32_TO_CPU(cmd_resp->data0);
6034 
6035 		if (reg_val1 != NULL)
6036 			*reg_val1 = LE32_TO_CPU(cmd_resp->data1);
6037 	}
6038 
6039 	return status;
6040 }
6041 
6042 /**
6043  * i40e_aq_alternate_read_indirect
6044  * @hw: pointer to the hardware structure
6045  * @addr: address of the alternate structure field
6046  * @dw_count: number of alternate structure fields to read
6047  * @buffer: pointer to the command buffer
6048  *
6049  * Read 'dw_count' dwords from alternate structure starting at 'addr' and
6050  * place them in 'buffer'. The buffer should be allocated by caller.
6051  *
6052  **/
i40e_aq_alternate_read_indirect(struct i40e_hw * hw,u32 addr,u32 dw_count,void * buffer)6053 enum i40e_status_code i40e_aq_alternate_read_indirect(struct i40e_hw *hw,
6054 				u32 addr, u32 dw_count, void *buffer)
6055 {
6056 	struct i40e_aq_desc desc;
6057 	struct i40e_aqc_alternate_ind_write *cmd_resp =
6058 		(struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
6059 	enum i40e_status_code status;
6060 
6061 	if (buffer == NULL)
6062 		return I40E_ERR_PARAM;
6063 
6064 	/* Indirect command */
6065 	i40e_fill_default_direct_cmd_desc(&desc,
6066 		i40e_aqc_opc_alternate_read_indirect);
6067 
6068 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
6069 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
6070 	if (dw_count > (I40E_AQ_LARGE_BUF/4))
6071 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6072 
6073 	cmd_resp->address = CPU_TO_LE32(addr);
6074 	cmd_resp->length = CPU_TO_LE32(dw_count);
6075 
6076 	status = i40e_asq_send_command(hw, &desc, buffer,
6077 				       I40E_LO_DWORD(4*dw_count), NULL);
6078 
6079 	return status;
6080 }
6081 
6082 /**
6083  *  i40e_aq_alternate_clear
6084  *  @hw: pointer to the HW structure.
6085  *
6086  *  Clear the alternate structures of the port from which the function
6087  *  is called.
6088  *
6089  **/
i40e_aq_alternate_clear(struct i40e_hw * hw)6090 enum i40e_status_code i40e_aq_alternate_clear(struct i40e_hw *hw)
6091 {
6092 	struct i40e_aq_desc desc;
6093 	enum i40e_status_code status;
6094 
6095 	i40e_fill_default_direct_cmd_desc(&desc,
6096 					  i40e_aqc_opc_alternate_clear_port);
6097 
6098 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6099 
6100 	return status;
6101 }
6102 
6103 /**
6104  *  i40e_aq_alternate_write_done
6105  *  @hw: pointer to the HW structure.
6106  *  @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS
6107  *  @reset_needed: indicates the SW should trigger GLOBAL reset
6108  *
6109  *  Indicates to the FW that alternate structures have been changed.
6110  *
6111  **/
i40e_aq_alternate_write_done(struct i40e_hw * hw,u8 bios_mode,bool * reset_needed)6112 enum i40e_status_code i40e_aq_alternate_write_done(struct i40e_hw *hw,
6113 		u8 bios_mode, bool *reset_needed)
6114 {
6115 	struct i40e_aq_desc desc;
6116 	struct i40e_aqc_alternate_write_done *cmd =
6117 		(struct i40e_aqc_alternate_write_done *)&desc.params.raw;
6118 	enum i40e_status_code status;
6119 
6120 	if (reset_needed == NULL)
6121 		return I40E_ERR_PARAM;
6122 
6123 	i40e_fill_default_direct_cmd_desc(&desc,
6124 					  i40e_aqc_opc_alternate_write_done);
6125 
6126 	cmd->cmd_flags = CPU_TO_LE16(bios_mode);
6127 
6128 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6129 	if (!status && reset_needed)
6130 		*reset_needed = ((LE16_TO_CPU(cmd->cmd_flags) &
6131 				 I40E_AQ_ALTERNATE_RESET_NEEDED) != 0);
6132 
6133 	return status;
6134 }
6135 
6136 /**
6137  *  i40e_aq_set_oem_mode
6138  *  @hw: pointer to the HW structure.
6139  *  @oem_mode: the OEM mode to be used
6140  *
6141  *  Sets the device to a specific operating mode. Currently the only supported
6142  *  mode is no_clp, which causes FW to refrain from using Alternate RAM.
6143  *
6144  **/
i40e_aq_set_oem_mode(struct i40e_hw * hw,u8 oem_mode)6145 enum i40e_status_code i40e_aq_set_oem_mode(struct i40e_hw *hw,
6146 		u8 oem_mode)
6147 {
6148 	struct i40e_aq_desc desc;
6149 	struct i40e_aqc_alternate_write_done *cmd =
6150 		(struct i40e_aqc_alternate_write_done *)&desc.params.raw;
6151 	enum i40e_status_code status;
6152 
6153 	i40e_fill_default_direct_cmd_desc(&desc,
6154 					  i40e_aqc_opc_alternate_set_mode);
6155 
6156 	cmd->cmd_flags = CPU_TO_LE16(oem_mode);
6157 
6158 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6159 
6160 	return status;
6161 }
6162 
6163 /**
6164  * i40e_aq_resume_port_tx
6165  * @hw: pointer to the hardware structure
6166  * @cmd_details: pointer to command details structure or NULL
6167  *
6168  * Resume port's Tx traffic
6169  **/
i40e_aq_resume_port_tx(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)6170 enum i40e_status_code i40e_aq_resume_port_tx(struct i40e_hw *hw,
6171 				struct i40e_asq_cmd_details *cmd_details)
6172 {
6173 	struct i40e_aq_desc desc;
6174 	enum i40e_status_code status;
6175 
6176 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
6177 
6178 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
6179 
6180 	return status;
6181 }
6182 
6183 /**
6184  * i40e_set_pci_config_data - store PCI bus info
6185  * @hw: pointer to hardware structure
6186  * @link_status: the link status word from PCI config space
6187  *
6188  * Stores the PCI bus info (speed, width, type) within the i40e_hw structure
6189  **/
i40e_set_pci_config_data(struct i40e_hw * hw,u16 link_status)6190 void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
6191 {
6192 	hw->bus.type = i40e_bus_type_pci_express;
6193 
6194 	switch (link_status & I40E_PCI_LINK_WIDTH) {
6195 	case I40E_PCI_LINK_WIDTH_1:
6196 		hw->bus.width = i40e_bus_width_pcie_x1;
6197 		break;
6198 	case I40E_PCI_LINK_WIDTH_2:
6199 		hw->bus.width = i40e_bus_width_pcie_x2;
6200 		break;
6201 	case I40E_PCI_LINK_WIDTH_4:
6202 		hw->bus.width = i40e_bus_width_pcie_x4;
6203 		break;
6204 	case I40E_PCI_LINK_WIDTH_8:
6205 		hw->bus.width = i40e_bus_width_pcie_x8;
6206 		break;
6207 	default:
6208 		hw->bus.width = i40e_bus_width_unknown;
6209 		break;
6210 	}
6211 
6212 	switch (link_status & I40E_PCI_LINK_SPEED) {
6213 	case I40E_PCI_LINK_SPEED_2500:
6214 		hw->bus.speed = i40e_bus_speed_2500;
6215 		break;
6216 	case I40E_PCI_LINK_SPEED_5000:
6217 		hw->bus.speed = i40e_bus_speed_5000;
6218 		break;
6219 	case I40E_PCI_LINK_SPEED_8000:
6220 		hw->bus.speed = i40e_bus_speed_8000;
6221 		break;
6222 	default:
6223 		hw->bus.speed = i40e_bus_speed_unknown;
6224 		break;
6225 	}
6226 }
6227 
6228 /**
6229  * i40e_aq_debug_dump
6230  * @hw: pointer to the hardware structure
6231  * @cluster_id: specific cluster to dump
6232  * @table_id: table id within cluster
6233  * @start_index: index of line in the block to read
6234  * @buff_size: dump buffer size
6235  * @buff: dump buffer
6236  * @ret_buff_size: actual buffer size returned
6237  * @ret_next_table: next block to read
6238  * @ret_next_index: next index to read
6239  * @cmd_details: pointer to command details structure or NULL
6240  *
6241  * Dump internal FW/HW data for debug purposes.
6242  *
6243  **/
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)6244 enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
6245 				u8 table_id, u32 start_index, u16 buff_size,
6246 				void *buff, u16 *ret_buff_size,
6247 				u8 *ret_next_table, u32 *ret_next_index,
6248 				struct i40e_asq_cmd_details *cmd_details)
6249 {
6250 	struct i40e_aq_desc desc;
6251 	struct i40e_aqc_debug_dump_internals *cmd =
6252 		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6253 	struct i40e_aqc_debug_dump_internals *resp =
6254 		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6255 	enum i40e_status_code status;
6256 
6257 	if (buff_size == 0 || !buff)
6258 		return I40E_ERR_PARAM;
6259 
6260 	i40e_fill_default_direct_cmd_desc(&desc,
6261 					  i40e_aqc_opc_debug_dump_internals);
6262 	/* Indirect Command */
6263 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6264 	if (buff_size > I40E_AQ_LARGE_BUF)
6265 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6266 
6267 	cmd->cluster_id = cluster_id;
6268 	cmd->table_id = table_id;
6269 	cmd->idx = CPU_TO_LE32(start_index);
6270 
6271 	desc.datalen = CPU_TO_LE16(buff_size);
6272 
6273 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
6274 	if (!status) {
6275 		if (ret_buff_size != NULL)
6276 			*ret_buff_size = LE16_TO_CPU(desc.datalen);
6277 		if (ret_next_table != NULL)
6278 			*ret_next_table = resp->table_id;
6279 		if (ret_next_index != NULL)
6280 			*ret_next_index = LE32_TO_CPU(resp->idx);
6281 	}
6282 
6283 	return status;
6284 }
6285 
6286 
6287 /**
6288  * i40e_enable_eee
6289  * @hw: pointer to the hardware structure
6290  * @enable: state of Energy Efficient Ethernet mode to be set
6291  *
6292  * Enables or disables Energy Efficient Ethernet (EEE) mode
6293  * accordingly to @enable parameter.
6294  **/
i40e_enable_eee(struct i40e_hw * hw,bool enable)6295 enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable)
6296 {
6297 	struct i40e_aq_get_phy_abilities_resp abilities;
6298 	struct i40e_aq_set_phy_config config;
6299 	enum i40e_status_code status;
6300 	__le16 eee_capability;
6301 
6302 	/* Get initial PHY capabilities */
6303 	status = i40e_aq_get_phy_capabilities(hw, FALSE, TRUE, &abilities,
6304 					      NULL);
6305 	if (status)
6306 		goto err;
6307 
6308 	/* Check whether NIC configuration is compatible with Energy Efficient
6309 	 * Ethernet (EEE) mode.
6310 	 */
6311 	if (abilities.eee_capability == 0) {
6312 		status = I40E_ERR_CONFIG;
6313 		goto err;
6314 	}
6315 
6316 	/* Cache initial EEE capability */
6317 	eee_capability = abilities.eee_capability;
6318 
6319 	/* Get current configuration */
6320 	status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
6321 					      NULL);
6322 	if (status)
6323 		goto err;
6324 
6325 	/* Cache current configuration */
6326 	config.phy_type = abilities.phy_type;
6327 	config.phy_type_ext = abilities.phy_type_ext;
6328 	config.link_speed = abilities.link_speed;
6329 	config.abilities = abilities.abilities |
6330 			   I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
6331 	config.eeer = abilities.eeer_val;
6332 	config.low_power_ctrl = abilities.d3_lpan;
6333 	config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
6334 			    I40E_AQ_PHY_FEC_CONFIG_MASK;
6335 
6336 	/* Set desired EEE state */
6337 	if (enable) {
6338 		config.eee_capability = eee_capability;
6339 		config.eeer |= I40E_PRTPM_EEER_TX_LPI_EN_MASK;
6340 	} else {
6341 		config.eee_capability = 0;
6342 		config.eeer &= ~I40E_PRTPM_EEER_TX_LPI_EN_MASK;
6343 	}
6344 
6345 	/* Save modified config */
6346 	status = i40e_aq_set_phy_config(hw, &config, NULL);
6347 err:
6348 	return status;
6349 }
6350 
6351 /**
6352  * i40e_read_bw_from_alt_ram
6353  * @hw: pointer to the hardware structure
6354  * @max_bw: pointer for max_bw read
6355  * @min_bw: pointer for min_bw read
6356  * @min_valid: pointer for bool that is TRUE if min_bw is a valid value
6357  * @max_valid: pointer for bool that is TRUE if max_bw is a valid value
6358  *
6359  * Read bw from the alternate ram for the given pf
6360  **/
i40e_read_bw_from_alt_ram(struct i40e_hw * hw,u32 * max_bw,u32 * min_bw,bool * min_valid,bool * max_valid)6361 enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
6362 					u32 *max_bw, u32 *min_bw,
6363 					bool *min_valid, bool *max_valid)
6364 {
6365 	enum i40e_status_code status;
6366 	u32 max_bw_addr, min_bw_addr;
6367 
6368 	/* Calculate the address of the min/max bw registers */
6369 	max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
6370 		      I40E_ALT_STRUCT_MAX_BW_OFFSET +
6371 		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
6372 	min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
6373 		      I40E_ALT_STRUCT_MIN_BW_OFFSET +
6374 		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
6375 
6376 	/* Read the bandwidths from alt ram */
6377 	status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
6378 					min_bw_addr, min_bw);
6379 
6380 	if (*min_bw & I40E_ALT_BW_VALID_MASK)
6381 		*min_valid = TRUE;
6382 	else
6383 		*min_valid = FALSE;
6384 
6385 	if (*max_bw & I40E_ALT_BW_VALID_MASK)
6386 		*max_valid = TRUE;
6387 	else
6388 		*max_valid = FALSE;
6389 
6390 	return status;
6391 }
6392 
6393 /**
6394  * i40e_aq_configure_partition_bw
6395  * @hw: pointer to the hardware structure
6396  * @bw_data: Buffer holding valid pfs and bw limits
6397  * @cmd_details: pointer to command details
6398  *
6399  * Configure partitions guaranteed/max bw
6400  **/
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)6401 enum i40e_status_code i40e_aq_configure_partition_bw(struct i40e_hw *hw,
6402 			struct i40e_aqc_configure_partition_bw_data *bw_data,
6403 			struct i40e_asq_cmd_details *cmd_details)
6404 {
6405 	enum i40e_status_code status;
6406 	struct i40e_aq_desc desc;
6407 	u16 bwd_size = sizeof(*bw_data);
6408 
6409 	i40e_fill_default_direct_cmd_desc(&desc,
6410 				i40e_aqc_opc_configure_partition_bw);
6411 
6412 	/* Indirect command */
6413 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6414 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
6415 
6416 	desc.datalen = CPU_TO_LE16(bwd_size);
6417 
6418 	status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size, cmd_details);
6419 
6420 	return status;
6421 }
6422 
6423 /**
6424  * i40e_read_phy_register_clause22
6425  * @hw: pointer to the HW structure
6426  * @reg: register address in the page
6427  * @phy_addr: PHY address on MDIO interface
6428  * @value: PHY register value
6429  *
6430  * Reads specified PHY register value
6431  **/
i40e_read_phy_register_clause22(struct i40e_hw * hw,u16 reg,u8 phy_addr,u16 * value)6432 enum i40e_status_code i40e_read_phy_register_clause22(struct i40e_hw *hw,
6433 					u16 reg, u8 phy_addr, u16 *value)
6434 {
6435 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6436 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6437 	u32 command = 0;
6438 	u16 retry = 1000;
6439 
6440 	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6441 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6442 		  (I40E_MDIO_CLAUSE22_OPCODE_READ_MASK) |
6443 		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6444 		  (I40E_GLGEN_MSCA_MDICMD_MASK);
6445 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6446 	do {
6447 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6448 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6449 			status = I40E_SUCCESS;
6450 			break;
6451 		}
6452 		i40e_usec_delay(10);
6453 		retry--;
6454 	} while (retry);
6455 
6456 	if (status) {
6457 		i40e_debug(hw, I40E_DEBUG_PHY,
6458 			   "PHY: Can't write command to external PHY.\n");
6459 	} else {
6460 		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6461 		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6462 			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6463 	}
6464 
6465 	return status;
6466 }
6467 
6468 /**
6469  * i40e_write_phy_register_clause22
6470  * @hw: pointer to the HW structure
6471  * @reg: register address in the page
6472  * @phy_addr: PHY address on MDIO interface
6473  * @value: PHY register value
6474  *
6475  * Writes specified PHY register value
6476  **/
i40e_write_phy_register_clause22(struct i40e_hw * hw,u16 reg,u8 phy_addr,u16 value)6477 enum i40e_status_code i40e_write_phy_register_clause22(struct i40e_hw *hw,
6478 					u16 reg, u8 phy_addr, u16 value)
6479 {
6480 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6481 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6482 	u32 command  = 0;
6483 	u16 retry = 1000;
6484 
6485 	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6486 	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6487 
6488 	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6489 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6490 		  (I40E_MDIO_CLAUSE22_OPCODE_WRITE_MASK) |
6491 		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6492 		  (I40E_GLGEN_MSCA_MDICMD_MASK);
6493 
6494 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6495 	do {
6496 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6497 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6498 			status = I40E_SUCCESS;
6499 			break;
6500 		}
6501 		i40e_usec_delay(10);
6502 		retry--;
6503 	} while (retry);
6504 
6505 	return status;
6506 }
6507 
6508 /**
6509  * i40e_read_phy_register_clause45
6510  * @hw: pointer to the HW structure
6511  * @page: registers page number
6512  * @reg: register address in the page
6513  * @phy_addr: PHY address on MDIO interface
6514  * @value: PHY register value
6515  *
6516  * Reads specified PHY register value
6517  **/
i40e_read_phy_register_clause45(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 * value)6518 enum i40e_status_code i40e_read_phy_register_clause45(struct i40e_hw *hw,
6519 				u8 page, u16 reg, u8 phy_addr, u16 *value)
6520 {
6521 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6522 	u32 command  = 0;
6523 	u16 retry = 1000;
6524 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6525 
6526 	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6527 		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6528 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6529 		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6530 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6531 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6532 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6533 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6534 	do {
6535 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6536 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6537 			status = I40E_SUCCESS;
6538 			break;
6539 		}
6540 		i40e_usec_delay(10);
6541 		retry--;
6542 	} while (retry);
6543 
6544 	if (status) {
6545 		i40e_debug(hw, I40E_DEBUG_PHY,
6546 			   "PHY: Can't write command to external PHY.\n");
6547 		goto phy_read_end;
6548 	}
6549 
6550 	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6551 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6552 		  (I40E_MDIO_CLAUSE45_OPCODE_READ_MASK) |
6553 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6554 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6555 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6556 	status = I40E_ERR_TIMEOUT;
6557 	retry = 1000;
6558 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6559 	do {
6560 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6561 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6562 			status = I40E_SUCCESS;
6563 			break;
6564 		}
6565 		i40e_usec_delay(10);
6566 		retry--;
6567 	} while (retry);
6568 
6569 	if (!status) {
6570 		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6571 		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6572 			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6573 	} else {
6574 		i40e_debug(hw, I40E_DEBUG_PHY,
6575 			   "PHY: Can't read register value from external PHY.\n");
6576 	}
6577 
6578 phy_read_end:
6579 	return status;
6580 }
6581 
6582 /**
6583  * i40e_write_phy_register_clause45
6584  * @hw: pointer to the HW structure
6585  * @page: registers page number
6586  * @reg: register address in the page
6587  * @phy_addr: PHY address on MDIO interface
6588  * @value: PHY register value
6589  *
6590  * Writes value to specified PHY register
6591  **/
i40e_write_phy_register_clause45(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 value)6592 enum i40e_status_code i40e_write_phy_register_clause45(struct i40e_hw *hw,
6593 				u8 page, u16 reg, u8 phy_addr, u16 value)
6594 {
6595 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6596 	u32 command  = 0;
6597 	u16 retry = 1000;
6598 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6599 
6600 	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6601 		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6602 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6603 		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6604 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6605 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6606 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6607 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6608 	do {
6609 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6610 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6611 			status = I40E_SUCCESS;
6612 			break;
6613 		}
6614 		i40e_usec_delay(10);
6615 		retry--;
6616 	} while (retry);
6617 	if (status) {
6618 		i40e_debug(hw, I40E_DEBUG_PHY,
6619 			   "PHY: Can't write command to external PHY.\n");
6620 		goto phy_write_end;
6621 	}
6622 
6623 	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6624 	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6625 
6626 	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6627 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6628 		  (I40E_MDIO_CLAUSE45_OPCODE_WRITE_MASK) |
6629 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6630 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6631 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6632 	status = I40E_ERR_TIMEOUT;
6633 	retry = 1000;
6634 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6635 	do {
6636 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6637 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6638 			status = I40E_SUCCESS;
6639 			break;
6640 		}
6641 		i40e_usec_delay(10);
6642 		retry--;
6643 	} while (retry);
6644 
6645 phy_write_end:
6646 	return status;
6647 }
6648 
6649 /**
6650  * i40e_write_phy_register
6651  * @hw: pointer to the HW structure
6652  * @page: registers page number
6653  * @reg: register address in the page
6654  * @phy_addr: PHY address on MDIO interface
6655  * @value: PHY register value
6656  *
6657  * Writes value to specified PHY register
6658  **/
i40e_write_phy_register(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 value)6659 enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
6660 				u8 page, u16 reg, u8 phy_addr, u16 value)
6661 {
6662 	enum i40e_status_code status;
6663 
6664 	switch (hw->device_id) {
6665 	case I40E_DEV_ID_1G_BASE_T_X722:
6666 		status = i40e_write_phy_register_clause22(hw,
6667 			reg, phy_addr, value);
6668 		break;
6669 	case I40E_DEV_ID_10G_BASE_T:
6670 	case I40E_DEV_ID_10G_BASE_T4:
6671 	case I40E_DEV_ID_10G_BASE_T_BC:
6672 	case I40E_DEV_ID_5G_BASE_T_BC:
6673 	case I40E_DEV_ID_1G_BASE_T_BC:
6674 	case I40E_DEV_ID_10G_BASE_T_X722:
6675 	case I40E_DEV_ID_25G_B:
6676 	case I40E_DEV_ID_25G_SFP28:
6677 		status = i40e_write_phy_register_clause45(hw,
6678 			page, reg, phy_addr, value);
6679 		break;
6680 	default:
6681 		status = I40E_ERR_UNKNOWN_PHY;
6682 		break;
6683 	}
6684 
6685 	return status;
6686 }
6687 
6688 /**
6689  * i40e_read_phy_register
6690  * @hw: pointer to the HW structure
6691  * @page: registers page number
6692  * @reg: register address in the page
6693  * @phy_addr: PHY address on MDIO interface
6694  * @value: PHY register value
6695  *
6696  * Reads specified PHY register value
6697  **/
i40e_read_phy_register(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 * value)6698 enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
6699 				u8 page, u16 reg, u8 phy_addr, u16 *value)
6700 {
6701 	enum i40e_status_code status;
6702 
6703 	switch (hw->device_id) {
6704 	case I40E_DEV_ID_1G_BASE_T_X722:
6705 		status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
6706 							 value);
6707 		break;
6708 	case I40E_DEV_ID_10G_BASE_T:
6709 	case I40E_DEV_ID_10G_BASE_T4:
6710 	case I40E_DEV_ID_10G_BASE_T_BC:
6711 	case I40E_DEV_ID_5G_BASE_T_BC:
6712 	case I40E_DEV_ID_1G_BASE_T_BC:
6713 	case I40E_DEV_ID_10G_BASE_T_X722:
6714 	case I40E_DEV_ID_25G_B:
6715 	case I40E_DEV_ID_25G_SFP28:
6716 		status = i40e_read_phy_register_clause45(hw, page, reg,
6717 							 phy_addr, value);
6718 		break;
6719 	default:
6720 		status = I40E_ERR_UNKNOWN_PHY;
6721 		break;
6722 	}
6723 
6724 	return status;
6725 }
6726 
6727 /**
6728  * i40e_get_phy_address
6729  * @hw: pointer to the HW structure
6730  * @dev_num: PHY port num that address we want
6731  *
6732  * Gets PHY address for current port
6733  **/
i40e_get_phy_address(struct i40e_hw * hw,u8 dev_num)6734 u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
6735 {
6736 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6737 	u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
6738 
6739 	return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
6740 }
6741 
6742 /**
6743  * i40e_blink_phy_link_led
6744  * @hw: pointer to the HW structure
6745  * @time: time how long led will blinks in secs
6746  * @interval: gap between LED on and off in msecs
6747  *
6748  * Blinks PHY link LED
6749  **/
i40e_blink_phy_link_led(struct i40e_hw * hw,u32 time,u32 interval)6750 enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
6751 					      u32 time, u32 interval)
6752 {
6753 	enum i40e_status_code status = I40E_SUCCESS;
6754 	u32 i;
6755 	u16 led_ctl = 0;
6756 	u16 gpio_led_port;
6757 	u16 led_reg;
6758 	u16 led_addr = I40E_PHY_LED_PROV_REG_1;
6759 	u8 phy_addr = 0;
6760 	u8 port_num;
6761 
6762 	i = rd32(hw, I40E_PFGEN_PORTNUM);
6763 	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
6764 	phy_addr = i40e_get_phy_address(hw, port_num);
6765 
6766 	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6767 	     led_addr++) {
6768 		status = i40e_read_phy_register_clause45(hw,
6769 							 I40E_PHY_COM_REG_PAGE,
6770 							 led_addr, phy_addr,
6771 							 &led_reg);
6772 		if (status)
6773 			goto phy_blinking_end;
6774 		led_ctl = led_reg;
6775 		if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6776 			led_reg = 0;
6777 			status = i40e_write_phy_register_clause45(hw,
6778 							 I40E_PHY_COM_REG_PAGE,
6779 							 led_addr, phy_addr,
6780 							 led_reg);
6781 			if (status)
6782 				goto phy_blinking_end;
6783 			break;
6784 		}
6785 	}
6786 
6787 	if (time > 0 && interval > 0) {
6788 		for (i = 0; i < time * 1000; i += interval) {
6789 			status = i40e_read_phy_register_clause45(hw,
6790 						I40E_PHY_COM_REG_PAGE,
6791 						led_addr, phy_addr, &led_reg);
6792 			if (status)
6793 				goto restore_config;
6794 			if (led_reg & I40E_PHY_LED_MANUAL_ON)
6795 				led_reg = 0;
6796 			else
6797 				led_reg = I40E_PHY_LED_MANUAL_ON;
6798 			status = i40e_write_phy_register_clause45(hw,
6799 						I40E_PHY_COM_REG_PAGE,
6800 						led_addr, phy_addr, led_reg);
6801 			if (status)
6802 				goto restore_config;
6803 			i40e_msec_delay(interval);
6804 		}
6805 	}
6806 
6807 restore_config:
6808 	status = i40e_write_phy_register_clause45(hw,
6809 						  I40E_PHY_COM_REG_PAGE,
6810 						  led_addr, phy_addr, led_ctl);
6811 
6812 phy_blinking_end:
6813 	return status;
6814 }
6815 
6816 /**
6817  * i40e_led_get_reg - read LED register
6818  * @hw: pointer to the HW structure
6819  * @led_addr: LED register address
6820  * @reg_val: read register value
6821  **/
i40e_led_get_reg(struct i40e_hw * hw,u16 led_addr,u32 * reg_val)6822 enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
6823 				       u32 *reg_val)
6824 {
6825 	enum i40e_status_code status;
6826 	u8 phy_addr = 0;
6827 
6828 	*reg_val = 0;
6829 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6830 		status = i40e_aq_get_phy_register(hw,
6831 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6832 						I40E_PHY_COM_REG_PAGE, TRUE,
6833 						I40E_PHY_LED_PROV_REG_1,
6834 						reg_val, NULL);
6835 	} else {
6836 		phy_addr = i40e_get_phy_address(hw, hw->port);
6837 		status = i40e_read_phy_register_clause45(hw,
6838 							 I40E_PHY_COM_REG_PAGE,
6839 							 led_addr, phy_addr,
6840 							 (u16 *)reg_val);
6841 	}
6842 	return status;
6843 }
6844 
6845 /**
6846  * i40e_led_set_reg - write LED register
6847  * @hw: pointer to the HW structure
6848  * @led_addr: LED register address
6849  * @reg_val: register value to write
6850  **/
i40e_led_set_reg(struct i40e_hw * hw,u16 led_addr,u32 reg_val)6851 enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
6852 				       u32 reg_val)
6853 {
6854 	enum i40e_status_code status;
6855 	u8 phy_addr = 0;
6856 
6857 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6858 		status = i40e_aq_set_phy_register(hw,
6859 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6860 						I40E_PHY_COM_REG_PAGE, TRUE,
6861 						I40E_PHY_LED_PROV_REG_1,
6862 						reg_val, NULL);
6863 	} else {
6864 		phy_addr = i40e_get_phy_address(hw, hw->port);
6865 		status = i40e_write_phy_register_clause45(hw,
6866 							  I40E_PHY_COM_REG_PAGE,
6867 							  led_addr, phy_addr,
6868 							  (u16)reg_val);
6869 	}
6870 
6871 	return status;
6872 }
6873 
6874 /**
6875  * i40e_led_get_phy - return current on/off mode
6876  * @hw: pointer to the hw struct
6877  * @led_addr: address of led register to use
6878  * @val: original value of register to use
6879  *
6880  **/
i40e_led_get_phy(struct i40e_hw * hw,u16 * led_addr,u16 * val)6881 enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
6882 				       u16 *val)
6883 {
6884 	enum i40e_status_code status = I40E_SUCCESS;
6885 	u16 gpio_led_port;
6886 	u32 reg_val_aq;
6887 	u16 temp_addr;
6888 	u8 phy_addr = 0;
6889 	u16 reg_val;
6890 
6891 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6892 		status = i40e_aq_get_phy_register(hw,
6893 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6894 						I40E_PHY_COM_REG_PAGE, TRUE,
6895 						I40E_PHY_LED_PROV_REG_1,
6896 						&reg_val_aq, NULL);
6897 		if (status == I40E_SUCCESS)
6898 			*val = (u16)reg_val_aq;
6899 		return status;
6900 	}
6901 	temp_addr = I40E_PHY_LED_PROV_REG_1;
6902 	phy_addr = i40e_get_phy_address(hw, hw->port);
6903 	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6904 	     temp_addr++) {
6905 		status = i40e_read_phy_register_clause45(hw,
6906 							 I40E_PHY_COM_REG_PAGE,
6907 							 temp_addr, phy_addr,
6908 							 &reg_val);
6909 		if (status)
6910 			return status;
6911 		*val = reg_val;
6912 		if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
6913 			*led_addr = temp_addr;
6914 			break;
6915 		}
6916 	}
6917 	return status;
6918 }
6919 
6920 /**
6921  * i40e_led_set_phy
6922  * @hw: pointer to the HW structure
6923  * @on: TRUE or FALSE
6924  * @led_addr: address of led register to use
6925  * @mode: original val plus bit for set or ignore
6926  *
6927  * Set led's on or off when controlled by the PHY
6928  *
6929  **/
i40e_led_set_phy(struct i40e_hw * hw,bool on,u16 led_addr,u32 mode)6930 enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on,
6931 				       u16 led_addr, u32 mode)
6932 {
6933 	enum i40e_status_code status = I40E_SUCCESS;
6934 	u32 led_ctl = 0;
6935 	u32 led_reg = 0;
6936 
6937 	status = i40e_led_get_reg(hw, led_addr, &led_reg);
6938 	if (status)
6939 		return status;
6940 	led_ctl = led_reg;
6941 	if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6942 		led_reg = 0;
6943 		status = i40e_led_set_reg(hw, led_addr, led_reg);
6944 		if (status)
6945 			return status;
6946 	}
6947 	status = i40e_led_get_reg(hw, led_addr, &led_reg);
6948 	if (status)
6949 		goto restore_config;
6950 	if (on)
6951 		led_reg = I40E_PHY_LED_MANUAL_ON;
6952 	else
6953 		led_reg = 0;
6954 	status = i40e_led_set_reg(hw, led_addr, led_reg);
6955 	if (status)
6956 		goto restore_config;
6957 	if (mode & I40E_PHY_LED_MODE_ORIG) {
6958 		led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
6959 		status = i40e_led_set_reg(hw, led_addr, led_ctl);
6960 	}
6961 	return status;
6962 
6963 restore_config:
6964 	status = i40e_led_set_reg(hw, led_addr, led_ctl);
6965 	return status;
6966 }
6967 
6968 /**
6969  * i40e_get_phy_lpi_status - read LPI status from PHY or MAC register
6970  * @hw: pointer to the hw struct
6971  * @stat: pointer to structure with status of rx and tx lpi
6972  *
6973  * Read LPI state directly from external PHY register or from MAC
6974  * register, depending on device ID and current link speed.
6975  */
i40e_get_phy_lpi_status(struct i40e_hw * hw,struct i40e_hw_port_stats * stat)6976 enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
6977 					      struct i40e_hw_port_stats *stat)
6978 {
6979 	enum i40e_status_code ret = I40E_SUCCESS;
6980 	bool eee_mrvl_phy;
6981 	bool eee_bcm_phy;
6982 	u32 val;
6983 
6984 	stat->rx_lpi_status = 0;
6985 	stat->tx_lpi_status = 0;
6986 
6987 	eee_bcm_phy =
6988 		(hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
6989 		 hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
6990 		(hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB ||
6991 		 hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB);
6992 	eee_mrvl_phy =
6993 		hw->device_id == I40E_DEV_ID_1G_BASE_T_X722;
6994 
6995 	if (eee_bcm_phy || eee_mrvl_phy) {
6996 		// read Clause 45 PCS Status 1 register
6997 		ret = i40e_aq_get_phy_register(hw,
6998 					       I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6999 					       I40E_BCM_PHY_PCS_STATUS1_PAGE,
7000 					       TRUE,
7001 					       I40E_BCM_PHY_PCS_STATUS1_REG,
7002 					       &val, NULL);
7003 
7004 		if (ret != I40E_SUCCESS)
7005 			return ret;
7006 
7007 		stat->rx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_RX_LPI);
7008 		stat->tx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_TX_LPI);
7009 
7010 		return ret;
7011 	}
7012 
7013 	val = rd32(hw, I40E_PRTPM_EEE_STAT);
7014 	stat->rx_lpi_status = (val & I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK) >>
7015 			       I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT;
7016 	stat->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >>
7017 			       I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT;
7018 
7019 	return ret;
7020 }
7021 
7022 /**
7023  * i40e_get_lpi_counters - read LPI counters from EEE statistics
7024  * @hw: pointer to the hw struct
7025  * @tx_counter: pointer to memory for TX LPI counter
7026  * @rx_counter: pointer to memory for RX LPI counter
7027  * @is_clear:   returns TRUE if counters are clear after read
7028  *
7029  * Read Low Power Idle (LPI) mode counters from Energy Efficient
7030  * Ethernet (EEE) statistics.
7031  **/
i40e_get_lpi_counters(struct i40e_hw * hw,u32 * tx_counter,u32 * rx_counter,bool * is_clear)7032 enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw,
7033 					    u32 *tx_counter, u32 *rx_counter,
7034 					    bool *is_clear)
7035 {
7036 	/* only X710-T*L requires special handling of counters
7037 	 * for other devices we just read the MAC registers
7038 	 */
7039 	if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
7040 	     hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
7041 	     hw->phy.link_info.link_speed != I40E_LINK_SPEED_1GB) {
7042 		enum i40e_status_code retval;
7043 		u32 cmd_status;
7044 
7045 		*is_clear = FALSE;
7046 		retval = i40e_aq_run_phy_activity(hw,
7047 				I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7048 				I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT,
7049 				&cmd_status, tx_counter, rx_counter, NULL);
7050 
7051 		if (!retval && cmd_status != I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7052 			retval = I40E_ERR_ADMIN_QUEUE_ERROR;
7053 
7054 		return retval;
7055 	}
7056 
7057 	*is_clear = TRUE;
7058 	*tx_counter = rd32(hw, I40E_PRTPM_TLPIC);
7059 	*rx_counter = rd32(hw, I40E_PRTPM_RLPIC);
7060 
7061 	return I40E_SUCCESS;
7062 }
7063 
7064 /**
7065  * i40e_get_lpi_duration - read LPI time duration from EEE statistics
7066  * @hw: pointer to the hw struct
7067  * @stat: pointer to structure with status of rx and tx lpi
7068  * @tx_duration: pointer to memory for TX LPI time duration
7069  * @rx_duration: pointer to memory for RX LPI time duration
7070  *
7071  * Read Low Power Idle (LPI) mode time duration from Energy Efficient
7072  * Ethernet (EEE) statistics.
7073  */
i40e_get_lpi_duration(struct i40e_hw * hw,struct i40e_hw_port_stats * stat,u64 * tx_duration,u64 * rx_duration)7074 enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw,
7075 					    struct i40e_hw_port_stats *stat,
7076 					    u64 *tx_duration, u64 *rx_duration)
7077 {
7078 	u32 tx_time_dur, rx_time_dur;
7079 	enum i40e_status_code retval;
7080 	u32 cmd_status;
7081 
7082 	if (hw->device_id != I40E_DEV_ID_10G_BASE_T_BC &&
7083 	    hw->device_id != I40E_DEV_ID_5G_BASE_T_BC)
7084 		return I40E_ERR_NOT_IMPLEMENTED;
7085 
7086 	retval = i40e_aq_run_phy_activity
7087 		(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7088 		I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR,
7089 		&cmd_status, &tx_time_dur, &rx_time_dur, NULL);
7090 
7091 	if (retval)
7092 		return retval;
7093 	if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
7094 	    I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7095 		return I40E_ERR_ADMIN_QUEUE_ERROR;
7096 
7097 	if (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB &&
7098 	    !tx_time_dur && !rx_time_dur &&
7099 	    stat->tx_lpi_status && stat->rx_lpi_status) {
7100 		retval = i40e_aq_run_phy_activity
7101 			(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7102 			I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR,
7103 			&cmd_status,
7104 			&tx_time_dur, &rx_time_dur, NULL);
7105 
7106 		if (retval)
7107 			return retval;
7108 		if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
7109 		    I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7110 			return I40E_ERR_ADMIN_QUEUE_ERROR;
7111 		tx_time_dur = 0;
7112 		rx_time_dur = 0;
7113 	}
7114 
7115 	*tx_duration = tx_time_dur;
7116 	*rx_duration = rx_time_dur;
7117 
7118 	return retval;
7119 }
7120 
7121 /**
7122  * i40e_lpi_stat_update - update LPI counters with values relative to offset
7123  * @hw: pointer to the hw struct
7124  * @offset_loaded: flag indicating need of writing current value to offset
7125  * @tx_offset: pointer to offset of TX LPI counter
7126  * @tx_stat: pointer to value of TX LPI counter
7127  * @rx_offset: pointer to offset of RX LPI counter
7128  * @rx_stat: pointer to value of RX LPI counter
7129  *
7130  * Update Low Power Idle (LPI) mode counters while having regard to passed
7131  * offsets.
7132  **/
i40e_lpi_stat_update(struct i40e_hw * hw,bool offset_loaded,u64 * tx_offset,u64 * tx_stat,u64 * rx_offset,u64 * rx_stat)7133 enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw,
7134 					   bool offset_loaded, u64 *tx_offset,
7135 					   u64 *tx_stat, u64 *rx_offset,
7136 					   u64 *rx_stat)
7137 {
7138 	enum i40e_status_code retval;
7139 	u32 tx_counter, rx_counter;
7140 	bool is_clear;
7141 
7142 	retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter, &is_clear);
7143 	if (retval)
7144 		goto err;
7145 
7146 	if (is_clear) {
7147 		*tx_stat += tx_counter;
7148 		*rx_stat += rx_counter;
7149 	} else {
7150 		if (!offset_loaded) {
7151 			*tx_offset = tx_counter;
7152 			*rx_offset = rx_counter;
7153 		}
7154 
7155 		*tx_stat = (tx_counter >= *tx_offset) ?
7156 			(u32)(tx_counter - *tx_offset) :
7157 			(u32)((tx_counter + BIT_ULL(32)) - *tx_offset);
7158 		*rx_stat = (rx_counter >= *rx_offset) ?
7159 			(u32)(rx_counter - *rx_offset) :
7160 			(u32)((rx_counter + BIT_ULL(32)) - *rx_offset);
7161 	}
7162 err:
7163 	return retval;
7164 }
7165 
7166 /**
7167  * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
7168  * @hw: pointer to the hw struct
7169  * @reg_addr: register address
7170  * @reg_val: ptr to register value
7171  * @cmd_details: pointer to command details structure or NULL
7172  *
7173  * Use the firmware to read the Rx control register,
7174  * especially useful if the Rx unit is under heavy pressure
7175  **/
i40e_aq_rx_ctl_read_register(struct i40e_hw * hw,u32 reg_addr,u32 * reg_val,struct i40e_asq_cmd_details * cmd_details)7176 enum i40e_status_code i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
7177 				u32 reg_addr, u32 *reg_val,
7178 				struct i40e_asq_cmd_details *cmd_details)
7179 {
7180 	struct i40e_aq_desc desc;
7181 	struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
7182 		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7183 	enum i40e_status_code status;
7184 
7185 	if (reg_val == NULL)
7186 		return I40E_ERR_PARAM;
7187 
7188 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
7189 
7190 	cmd_resp->address = CPU_TO_LE32(reg_addr);
7191 
7192 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7193 
7194 	if (status == I40E_SUCCESS)
7195 		*reg_val = LE32_TO_CPU(cmd_resp->value);
7196 
7197 	return status;
7198 }
7199 
7200 /**
7201  * i40e_read_rx_ctl - read from an Rx control register
7202  * @hw: pointer to the hw struct
7203  * @reg_addr: register address
7204  **/
i40e_read_rx_ctl(struct i40e_hw * hw,u32 reg_addr)7205 u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
7206 {
7207 	enum i40e_status_code status = I40E_SUCCESS;
7208 	bool use_register;
7209 	int retry = 5;
7210 	u32 val = 0;
7211 
7212 	use_register = (((hw->aq.api_maj_ver == 1) &&
7213 			(hw->aq.api_min_ver < 5)) ||
7214 			(hw->mac.type == I40E_MAC_X722));
7215 	if (!use_register) {
7216 do_retry:
7217 		status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
7218 		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7219 			i40e_msec_delay(1);
7220 			retry--;
7221 			goto do_retry;
7222 		}
7223 	}
7224 
7225 	/* if the AQ access failed, try the old-fashioned way */
7226 	if (status || use_register)
7227 		val = rd32(hw, reg_addr);
7228 
7229 	return val;
7230 }
7231 
7232 /**
7233  * i40e_aq_rx_ctl_write_register
7234  * @hw: pointer to the hw struct
7235  * @reg_addr: register address
7236  * @reg_val: register value
7237  * @cmd_details: pointer to command details structure or NULL
7238  *
7239  * Use the firmware to write to an Rx control register,
7240  * especially useful if the Rx unit is under heavy pressure
7241  **/
i40e_aq_rx_ctl_write_register(struct i40e_hw * hw,u32 reg_addr,u32 reg_val,struct i40e_asq_cmd_details * cmd_details)7242 enum i40e_status_code i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
7243 				u32 reg_addr, u32 reg_val,
7244 				struct i40e_asq_cmd_details *cmd_details)
7245 {
7246 	struct i40e_aq_desc desc;
7247 	struct i40e_aqc_rx_ctl_reg_read_write *cmd =
7248 		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7249 	enum i40e_status_code status;
7250 
7251 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
7252 
7253 	cmd->address = CPU_TO_LE32(reg_addr);
7254 	cmd->value = CPU_TO_LE32(reg_val);
7255 
7256 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7257 
7258 	return status;
7259 }
7260 
7261 /**
7262  * i40e_write_rx_ctl - write to an Rx control register
7263  * @hw: pointer to the hw struct
7264  * @reg_addr: register address
7265  * @reg_val: register value
7266  **/
i40e_write_rx_ctl(struct i40e_hw * hw,u32 reg_addr,u32 reg_val)7267 void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
7268 {
7269 	enum i40e_status_code status = I40E_SUCCESS;
7270 	bool use_register;
7271 	int retry = 5;
7272 
7273 	use_register = (((hw->aq.api_maj_ver == 1) &&
7274 			(hw->aq.api_min_ver < 5)) ||
7275 			(hw->mac.type == I40E_MAC_X722));
7276 	if (!use_register) {
7277 do_retry:
7278 		status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
7279 						       reg_val, NULL);
7280 		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7281 			i40e_msec_delay(1);
7282 			retry--;
7283 			goto do_retry;
7284 		}
7285 	}
7286 
7287 	/* if the AQ access failed, try the old-fashioned way */
7288 	if (status || use_register)
7289 		wr32(hw, reg_addr, reg_val);
7290 }
7291 
7292 /**
7293  * i40e_mdio_if_number_selection - MDIO I/F number selection
7294  * @hw: pointer to the hw struct
7295  * @set_mdio: use MDIO I/F number specified by mdio_num
7296  * @mdio_num: MDIO I/F number
7297  * @cmd: pointer to PHY Register command structure
7298  **/
7299 static void
i40e_mdio_if_number_selection(struct i40e_hw * hw,bool set_mdio,u8 mdio_num,struct i40e_aqc_phy_register_access * cmd)7300 i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio, u8 mdio_num,
7301 			      struct i40e_aqc_phy_register_access *cmd)
7302 {
7303 	if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) {
7304 		if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED)
7305 			cmd->cmd_flags |=
7306 				I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER |
7307 				((mdio_num <<
7308 				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) &
7309 				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK);
7310 		else
7311 			i40e_debug(hw, I40E_DEBUG_PHY,
7312 				   "MDIO I/F number selection not supported by current FW version.\n");
7313 	}
7314 }
7315 
7316 /**
7317  * i40e_aq_set_phy_register_ext
7318  * @hw: pointer to the hw struct
7319  * @phy_select: select which phy should be accessed
7320  * @dev_addr: PHY device address
7321  * @page_change: enable auto page change
7322  * @set_mdio: use MDIO I/F number specified by mdio_num
7323  * @mdio_num: MDIO I/F number
7324  * @reg_addr: PHY register address
7325  * @reg_val: new register value
7326  * @cmd_details: pointer to command details structure or NULL
7327  *
7328  * Write the external PHY register.
7329  * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7330  * may use simple wrapper i40e_aq_set_phy_register.
7331  **/
7332 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)7333 i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
7334 			     u8 phy_select, u8 dev_addr, bool page_change,
7335 			     bool set_mdio, u8 mdio_num,
7336 			     u32 reg_addr, u32 reg_val,
7337 			     struct i40e_asq_cmd_details *cmd_details)
7338 {
7339 	struct i40e_aq_desc desc;
7340 	struct i40e_aqc_phy_register_access *cmd =
7341 		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
7342 	enum i40e_status_code status;
7343 
7344 	i40e_fill_default_direct_cmd_desc(&desc,
7345 					  i40e_aqc_opc_set_phy_register);
7346 
7347 	cmd->phy_interface = phy_select;
7348 	cmd->dev_addres = dev_addr;
7349 	cmd->reg_address = CPU_TO_LE32(reg_addr);
7350 	cmd->reg_value = CPU_TO_LE32(reg_val);
7351 
7352 	if (!page_change)
7353 		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7354 
7355 	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7356 
7357 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7358 
7359 	return status;
7360 }
7361 
7362 /**
7363  * i40e_aq_get_phy_register_ext
7364  * @hw: pointer to the hw struct
7365  * @phy_select: select which phy should be accessed
7366  * @dev_addr: PHY device address
7367  * @page_change: enable auto page change
7368  * @set_mdio: use MDIO I/F number specified by mdio_num
7369  * @mdio_num: MDIO I/F number
7370  * @reg_addr: PHY register address
7371  * @reg_val: read register value
7372  * @cmd_details: pointer to command details structure or NULL
7373  *
7374  * Read the external PHY register.
7375  * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7376  * may use simple wrapper i40e_aq_get_phy_register.
7377  **/
7378 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)7379 i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
7380 			     u8 phy_select, u8 dev_addr, bool page_change,
7381 			     bool set_mdio, u8 mdio_num,
7382 			     u32 reg_addr, u32 *reg_val,
7383 			     struct i40e_asq_cmd_details *cmd_details)
7384 {
7385 	struct i40e_aq_desc desc;
7386 	struct i40e_aqc_phy_register_access *cmd =
7387 		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
7388 	enum i40e_status_code status;
7389 
7390 	i40e_fill_default_direct_cmd_desc(&desc,
7391 					  i40e_aqc_opc_get_phy_register);
7392 
7393 	cmd->phy_interface = phy_select;
7394 	cmd->dev_addres = dev_addr;
7395 	cmd->reg_address = CPU_TO_LE32(reg_addr);
7396 
7397 	if (!page_change)
7398 		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7399 
7400 	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7401 
7402 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7403 	if (!status)
7404 		*reg_val = LE32_TO_CPU(cmd->reg_value);
7405 
7406 	return status;
7407 }
7408 
7409 /**
7410  * i40e_aq_run_phy_activity
7411  * @hw: pointer to the hw struct
7412  * @activity_id: ID of DNL activity to run
7413  * @dnl_opcode: opcode passed to DNL script
7414  * @cmd_status: pointer to memory to write return value of DNL script
7415  * @data0: pointer to memory for first 4 bytes of data returned by DNL script
7416  * @data1: pointer to memory for last 4 bytes of data returned by DNL script
7417  * @cmd_details: pointer to command details structure or NULL
7418  *
7419  * Run DNL admin command.
7420  **/
7421 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)7422 i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 dnl_opcode,
7423 			 u32 *cmd_status, u32 *data0, u32 *data1,
7424 			 struct i40e_asq_cmd_details *cmd_details)
7425 {
7426 	struct i40e_aqc_run_phy_activity *cmd;
7427 	enum i40e_status_code retval;
7428 	struct i40e_aq_desc desc;
7429 
7430 	cmd = (struct i40e_aqc_run_phy_activity *)&desc.params.raw;
7431 
7432 	if (!cmd_status || !data0 || !data1) {
7433 		retval = I40E_ERR_PARAM;
7434 		goto err;
7435 	}
7436 
7437 	i40e_fill_default_direct_cmd_desc(&desc,
7438 					  i40e_aqc_opc_run_phy_activity);
7439 
7440 	cmd->activity_id = CPU_TO_LE16(activity_id);
7441 	cmd->params.cmd.dnl_opcode = CPU_TO_LE32(dnl_opcode);
7442 
7443 	retval = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7444 	if (retval)
7445 		goto err;
7446 
7447 	*cmd_status = LE32_TO_CPU(cmd->params.resp.cmd_status);
7448 	*data0 = LE32_TO_CPU(cmd->params.resp.data0);
7449 	*data1 = LE32_TO_CPU(cmd->params.resp.data1);
7450 err:
7451 	return retval;
7452 }
7453 
7454 
7455 /**
7456  * i40e_aq_send_msg_to_pf
7457  * @hw: pointer to the hardware structure
7458  * @v_opcode: opcodes for VF-PF communication
7459  * @v_retval: return error code
7460  * @msg: pointer to the msg buffer
7461  * @msglen: msg length
7462  * @cmd_details: pointer to command details
7463  *
7464  * Send message to PF driver using admin queue. By default, this message
7465  * is sent asynchronously, i.e. i40e_asq_send_command() does not wait for
7466  * completion before returning.
7467  **/
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)7468 enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
7469 				enum virtchnl_ops v_opcode,
7470 				enum i40e_status_code v_retval,
7471 				u8 *msg, u16 msglen,
7472 				struct i40e_asq_cmd_details *cmd_details)
7473 {
7474 	struct i40e_aq_desc desc;
7475 	struct i40e_asq_cmd_details details;
7476 	enum i40e_status_code status;
7477 
7478 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf);
7479 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
7480 	desc.cookie_high = CPU_TO_LE32(v_opcode);
7481 	desc.cookie_low = CPU_TO_LE32(v_retval);
7482 	if (msglen) {
7483 		desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF
7484 						| I40E_AQ_FLAG_RD));
7485 		if (msglen > I40E_AQ_LARGE_BUF)
7486 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
7487 		desc.datalen = CPU_TO_LE16(msglen);
7488 	}
7489 	if (!cmd_details) {
7490 		i40e_memset(&details, 0, sizeof(details), I40E_NONDMA_MEM);
7491 		details.async = TRUE;
7492 		cmd_details = &details;
7493 	}
7494 	status = i40e_asq_send_command(hw, (struct i40e_aq_desc *)&desc, msg,
7495 				       msglen, cmd_details);
7496 	return status;
7497 }
7498 
7499 /**
7500  * i40e_vf_parse_hw_config
7501  * @hw: pointer to the hardware structure
7502  * @msg: pointer to the virtual channel VF resource structure
7503  *
7504  * Given a VF resource message from the PF, populate the hw struct
7505  * with appropriate information.
7506  **/
i40e_vf_parse_hw_config(struct i40e_hw * hw,struct virtchnl_vf_resource * msg)7507 void i40e_vf_parse_hw_config(struct i40e_hw *hw,
7508 			     struct virtchnl_vf_resource *msg)
7509 {
7510 	struct virtchnl_vsi_resource *vsi_res;
7511 	int i;
7512 
7513 	vsi_res = &msg->vsi_res[0];
7514 
7515 	hw->dev_caps.num_vsis = msg->num_vsis;
7516 	hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
7517 	hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
7518 	hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
7519 	hw->dev_caps.dcb = msg->vf_cap_flags &
7520 			   VIRTCHNL_VF_OFFLOAD_L2;
7521 	hw->dev_caps.iwarp = (msg->vf_cap_flags &
7522 			      VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
7523 	for (i = 0; i < msg->num_vsis; i++) {
7524 		if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
7525 			i40e_memcpy(hw->mac.perm_addr,
7526 				    vsi_res->default_mac_addr,
7527 				    ETH_ALEN,
7528 				    I40E_NONDMA_TO_NONDMA);
7529 			i40e_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
7530 				    ETH_ALEN,
7531 				    I40E_NONDMA_TO_NONDMA);
7532 		}
7533 		vsi_res++;
7534 	}
7535 }
7536 
7537 /**
7538  * i40e_vf_reset
7539  * @hw: pointer to the hardware structure
7540  *
7541  * Send a VF_RESET message to the PF. Does not wait for response from PF
7542  * as none will be forthcoming. Immediately after calling this function,
7543  * the admin queue should be shut down and (optionally) reinitialized.
7544  **/
i40e_vf_reset(struct i40e_hw * hw)7545 enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
7546 {
7547 	return i40e_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
7548 				      I40E_SUCCESS, NULL, 0, NULL);
7549 }
7550 
7551 /**
7552  * i40e_aq_set_arp_proxy_config
7553  * @hw: pointer to the HW structure
7554  * @proxy_config: pointer to proxy config command table struct
7555  * @cmd_details: pointer to command details
7556  *
7557  * Set ARP offload parameters from pre-populated
7558  * i40e_aqc_arp_proxy_data struct
7559  **/
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)7560 enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
7561 				struct i40e_aqc_arp_proxy_data *proxy_config,
7562 				struct i40e_asq_cmd_details *cmd_details)
7563 {
7564 	struct i40e_aq_desc desc;
7565 	enum i40e_status_code status;
7566 
7567 	if (!proxy_config)
7568 		return I40E_ERR_PARAM;
7569 
7570 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_proxy_config);
7571 
7572 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7573 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7574 	desc.params.external.addr_high =
7575 				  CPU_TO_LE32(I40E_HI_DWORD((u64)proxy_config));
7576 	desc.params.external.addr_low =
7577 				  CPU_TO_LE32(I40E_LO_DWORD((u64)proxy_config));
7578 	desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_arp_proxy_data));
7579 
7580 	status = i40e_asq_send_command(hw, &desc, proxy_config,
7581 				       sizeof(struct i40e_aqc_arp_proxy_data),
7582 				       cmd_details);
7583 
7584 	return status;
7585 }
7586 
7587 /**
7588  * i40e_aq_set_ns_proxy_table_entry
7589  * @hw: pointer to the HW structure
7590  * @ns_proxy_table_entry: pointer to NS table entry command struct
7591  * @cmd_details: pointer to command details
7592  *
7593  * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
7594  * from pre-populated i40e_aqc_ns_proxy_data struct
7595  **/
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)7596 enum i40e_status_code i40e_aq_set_ns_proxy_table_entry(struct i40e_hw *hw,
7597 			struct i40e_aqc_ns_proxy_data *ns_proxy_table_entry,
7598 			struct i40e_asq_cmd_details *cmd_details)
7599 {
7600 	struct i40e_aq_desc desc;
7601 	enum i40e_status_code status;
7602 
7603 	if (!ns_proxy_table_entry)
7604 		return I40E_ERR_PARAM;
7605 
7606 	i40e_fill_default_direct_cmd_desc(&desc,
7607 				i40e_aqc_opc_set_ns_proxy_table_entry);
7608 
7609 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7610 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7611 	desc.params.external.addr_high =
7612 		CPU_TO_LE32(I40E_HI_DWORD((u64)ns_proxy_table_entry));
7613 	desc.params.external.addr_low =
7614 		CPU_TO_LE32(I40E_LO_DWORD((u64)ns_proxy_table_entry));
7615 	desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_ns_proxy_data));
7616 
7617 	status = i40e_asq_send_command(hw, &desc, ns_proxy_table_entry,
7618 				       sizeof(struct i40e_aqc_ns_proxy_data),
7619 				       cmd_details);
7620 
7621 	return status;
7622 }
7623 
7624 /**
7625  * i40e_aq_set_clear_wol_filter
7626  * @hw: pointer to the hw struct
7627  * @filter_index: index of filter to modify (0-7)
7628  * @filter: buffer containing filter to be set
7629  * @set_filter: TRUE to set filter, FALSE to clear filter
7630  * @no_wol_tco: if TRUE, pass through packets cannot cause wake-up
7631  *		if FALSE, pass through packets may cause wake-up
7632  * @filter_valid: TRUE if filter action is valid
7633  * @no_wol_tco_valid: TRUE if no WoL in TCO traffic action valid
7634  * @cmd_details: pointer to command details structure or NULL
7635  *
7636  * Set or clear WoL filter for port attached to the PF
7637  **/
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)7638 enum i40e_status_code i40e_aq_set_clear_wol_filter(struct i40e_hw *hw,
7639 				u8 filter_index,
7640 				struct i40e_aqc_set_wol_filter_data *filter,
7641 				bool set_filter, bool no_wol_tco,
7642 				bool filter_valid, bool no_wol_tco_valid,
7643 				struct i40e_asq_cmd_details *cmd_details)
7644 {
7645 	struct i40e_aq_desc desc;
7646 	struct i40e_aqc_set_wol_filter *cmd =
7647 		(struct i40e_aqc_set_wol_filter *)&desc.params.raw;
7648 	enum i40e_status_code status;
7649 	u16 cmd_flags = 0;
7650 	u16 valid_flags = 0;
7651 	u16 buff_len = 0;
7652 
7653 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_wol_filter);
7654 
7655 	if (filter_index >= I40E_AQC_MAX_NUM_WOL_FILTERS)
7656 		return  I40E_ERR_PARAM;
7657 	cmd->filter_index = CPU_TO_LE16(filter_index);
7658 
7659 	if (set_filter) {
7660 		if (!filter)
7661 			return  I40E_ERR_PARAM;
7662 
7663 		cmd_flags |= I40E_AQC_SET_WOL_FILTER;
7664 		cmd_flags |= I40E_AQC_SET_WOL_FILTER_WOL_PRESERVE_ON_PFR;
7665 	}
7666 
7667 	if (no_wol_tco)
7668 		cmd_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_WOL;
7669 	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
7670 
7671 	if (filter_valid)
7672 		valid_flags |= I40E_AQC_SET_WOL_FILTER_ACTION_VALID;
7673 	if (no_wol_tco_valid)
7674 		valid_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
7675 	cmd->valid_flags = CPU_TO_LE16(valid_flags);
7676 
7677 	buff_len = sizeof(*filter);
7678 	desc.datalen = CPU_TO_LE16(buff_len);
7679 
7680 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7681 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7682 
7683 	cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)filter));
7684 	cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)filter));
7685 
7686 	status = i40e_asq_send_command(hw, &desc, filter,
7687 				       buff_len, cmd_details);
7688 
7689 	return status;
7690 }
7691 
7692 /**
7693  * i40e_aq_get_wake_event_reason
7694  * @hw: pointer to the hw struct
7695  * @wake_reason: return value, index of matching filter
7696  * @cmd_details: pointer to command details structure or NULL
7697  *
7698  * Get information for the reason of a Wake Up event
7699  **/
i40e_aq_get_wake_event_reason(struct i40e_hw * hw,u16 * wake_reason,struct i40e_asq_cmd_details * cmd_details)7700 enum i40e_status_code i40e_aq_get_wake_event_reason(struct i40e_hw *hw,
7701 				u16 *wake_reason,
7702 				struct i40e_asq_cmd_details *cmd_details)
7703 {
7704 	struct i40e_aq_desc desc;
7705 	struct i40e_aqc_get_wake_reason_completion *resp =
7706 		(struct i40e_aqc_get_wake_reason_completion *)&desc.params.raw;
7707 	enum i40e_status_code status;
7708 
7709 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_wake_reason);
7710 
7711 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7712 
7713 	if (status == I40E_SUCCESS)
7714 		*wake_reason = LE16_TO_CPU(resp->wake_reason);
7715 
7716 	return status;
7717 }
7718 
7719 /**
7720 * i40e_aq_clear_all_wol_filters
7721 * @hw: pointer to the hw struct
7722 * @cmd_details: pointer to command details structure or NULL
7723 *
7724 * Get information for the reason of a Wake Up event
7725 **/
i40e_aq_clear_all_wol_filters(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)7726 enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
7727 	struct i40e_asq_cmd_details *cmd_details)
7728 {
7729 	struct i40e_aq_desc desc;
7730 	enum i40e_status_code status;
7731 
7732 	i40e_fill_default_direct_cmd_desc(&desc,
7733 					  i40e_aqc_opc_clear_all_wol_filters);
7734 
7735 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7736 
7737 	return status;
7738 }
7739 
7740