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