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