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 **/
48enum 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 **/
111const 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 **/
171const 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 **/
324void 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 **/
395bool 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 **/
416enum 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 **/
445static 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 **/
498enum 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 **/
515enum 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 **/
530static 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 **/
570enum 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 **/
585enum 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 */
637struct 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 **/
964enum 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 **/
994enum 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 **/
1048static 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 **/
1075enum 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 **/
1105enum 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 **/
1127enum 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 **/
1155void 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 **/
1186enum 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 **/
1241static 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 **/
1301static 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 **/
1327enum 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 **/
1415void 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 **/
1507void 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 */
1520static 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 **/
1564u32 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 **/
1611void 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 **/
1685enum 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 **/
1764enum 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 **/
1794enum 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 **/
1881enum 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 **/
1928enum 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 **/
1956enum 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 **/
1987enum 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
2074aq_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 **/
2086enum 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 **/
2113enum 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
2133aq_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 **/
2145enum 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 **/
2173enum 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
2193aq_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 **/
2205enum i40e_status_code
2206i40e_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 **/
2236enum 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**/
2262enum 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
2295aq_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 **/
2305enum 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 **/
2333enum 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 **/
2363enum 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 **/
2405enum 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**/
2437enum 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 **/
2475enum 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 **/
2509enum 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 **/
2543enum 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 **/
2578enum 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 **/
2611enum 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 **/
2641enum 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
2671aq_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 **/
2683enum 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 **/
2720enum 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 **/
2753enum 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 **/
2789enum 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 **/
2836enum 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 **/
2878enum 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 **/
2899enum 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 **/
2941enum 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
2955i40e_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 **/
2973enum 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 **/
3031enum 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
3071get_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 **/
3085enum 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 **/
3133enum 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 **/
3182static 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 **/
3242enum 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 **/
3273enum 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 **/
3301enum 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 **/
3341enum 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 **/
3385enum 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 **/
3420enum 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 **/
3455enum 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 **/
3486enum 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 **/
3527enum 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 **/
3561enum 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
3594i40e_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 **/
3608enum 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 **/
3647enum 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 **/
3676enum 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 **/
3703enum 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
3731i40e_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 **/
3744static 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	/* count the enabled ports (aka the "not disabled" ports) */
4034	hw->num_ports = 0;
4035	for (i = 0; i < 4; i++) {
4036		u32 port_cfg_reg = I40E_PRTGEN_CNF + (4 * i);
4037		u64 port_cfg = 0;
4038
4039		/* use AQ read to get the physical register offset instead
4040		 * of the port relative offset
4041		 */
4042		i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
4043		if (!(port_cfg & I40E_PRTGEN_CNF_PORT_DIS_MASK))
4044			hw->num_ports++;
4045	}
4046
4047	/* OCP cards case: if a mezz is removed the ethernet port is at
4048	 * disabled state in PRTGEN_CNF register. Additional NVM read is
4049	 * needed in order to check if we are dealing with OCP card.
4050	 * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
4051	 * physical ports results in wrong partition id calculation and thus
4052	 * not supporting WoL.
4053	 */
4054	if (hw->mac.type == I40E_MAC_X722) {
4055		if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) {
4056			status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
4057						  2 * I40E_SR_OCP_CFG_WORD0,
4058						  sizeof(ocp_cfg_word0),
4059						  &ocp_cfg_word0, TRUE, NULL);
4060			if (status == I40E_SUCCESS &&
4061			    (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
4062				hw->num_ports = 4;
4063			i40e_release_nvm(hw);
4064		}
4065	}
4066
4067	valid_functions = p->valid_functions;
4068	num_functions = 0;
4069	while (valid_functions) {
4070		if (valid_functions & 1)
4071			num_functions++;
4072		valid_functions >>= 1;
4073	}
4074
4075	/* partition id is 1-based, and functions are evenly spread
4076	 * across the ports as partitions
4077	 */
4078	if (hw->num_ports != 0) {
4079		hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
4080		hw->num_partitions = num_functions / hw->num_ports;
4081	}
4082
4083	/* additional HW specific goodies that might
4084	 * someday be HW version specific
4085	 */
4086	p->rx_buf_chain_len = I40E_MAX_CHAINED_RX_BUFFERS;
4087}
4088
4089/**
4090 * i40e_aq_discover_capabilities
4091 * @hw: pointer to the hw struct
4092 * @buff: a virtual buffer to hold the capabilities
4093 * @buff_size: Size of the virtual buffer
4094 * @data_size: Size of the returned data, or buff size needed if AQ err==ENOMEM
4095 * @list_type_opc: capabilities type to discover - pass in the command opcode
4096 * @cmd_details: pointer to command details structure or NULL
4097 *
4098 * Get the device capabilities descriptions from the firmware
4099 **/
4100enum i40e_status_code i40e_aq_discover_capabilities(struct i40e_hw *hw,
4101				void *buff, u16 buff_size, u16 *data_size,
4102				enum i40e_admin_queue_opc list_type_opc,
4103				struct i40e_asq_cmd_details *cmd_details)
4104{
4105	struct i40e_aqc_list_capabilites *cmd;
4106	struct i40e_aq_desc desc;
4107	enum i40e_status_code status = I40E_SUCCESS;
4108
4109	cmd = (struct i40e_aqc_list_capabilites *)&desc.params.raw;
4110
4111	if (list_type_opc != i40e_aqc_opc_list_func_capabilities &&
4112		list_type_opc != i40e_aqc_opc_list_dev_capabilities) {
4113		status = I40E_ERR_PARAM;
4114		goto exit;
4115	}
4116
4117	i40e_fill_default_direct_cmd_desc(&desc, list_type_opc);
4118
4119	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4120	if (buff_size > I40E_AQ_LARGE_BUF)
4121		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4122
4123	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4124	*data_size = LE16_TO_CPU(desc.datalen);
4125
4126	if (status)
4127		goto exit;
4128
4129	i40e_parse_discover_capabilities(hw, buff, LE32_TO_CPU(cmd->count),
4130					 list_type_opc);
4131
4132exit:
4133	return status;
4134}
4135
4136/**
4137 * i40e_aq_update_nvm
4138 * @hw: pointer to the hw struct
4139 * @module_pointer: module pointer location in words from the NVM beginning
4140 * @offset: byte offset from the module beginning
4141 * @length: length of the section to be written (in bytes from the offset)
4142 * @data: command buffer (size [bytes] = length)
4143 * @last_command: tells if this is the last command in a series
4144 * @preservation_flags: Preservation mode flags
4145 * @cmd_details: pointer to command details structure or NULL
4146 *
4147 * Update the NVM using the admin queue commands
4148 **/
4149enum i40e_status_code i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
4150				u32 offset, u16 length, void *data,
4151				bool last_command, u8 preservation_flags,
4152				struct i40e_asq_cmd_details *cmd_details)
4153{
4154	struct i40e_aq_desc desc;
4155	struct i40e_aqc_nvm_update *cmd =
4156		(struct i40e_aqc_nvm_update *)&desc.params.raw;
4157	enum i40e_status_code status;
4158
4159	DEBUGFUNC("i40e_aq_update_nvm");
4160
4161	/* In offset the highest byte must be zeroed. */
4162	if (offset & 0xFF000000) {
4163		status = I40E_ERR_PARAM;
4164		goto i40e_aq_update_nvm_exit;
4165	}
4166
4167	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
4168
4169	/* If this is the last command in a series, set the proper flag. */
4170	if (last_command)
4171		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
4172	if (hw->mac.type == I40E_MAC_X722) {
4173		if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_SELECTED)
4174			cmd->command_flags |=
4175				(I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED <<
4176				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
4177		else if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_ALL)
4178			cmd->command_flags |=
4179				(I40E_AQ_NVM_PRESERVATION_FLAGS_ALL <<
4180				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
4181	}
4182	cmd->module_pointer = module_pointer;
4183	cmd->offset = CPU_TO_LE32(offset);
4184	cmd->length = CPU_TO_LE16(length);
4185
4186	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4187	if (length > I40E_AQ_LARGE_BUF)
4188		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4189
4190	status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
4191
4192i40e_aq_update_nvm_exit:
4193	return status;
4194}
4195
4196/**
4197 * i40e_aq_nvm_progress
4198 * @hw: pointer to the hw struct
4199 * @progress: pointer to progress returned from AQ
4200 * @cmd_details: pointer to command details structure or NULL
4201 *
4202 * Gets progress of flash rearrangement process
4203 **/
4204enum i40e_status_code i40e_aq_nvm_progress(struct i40e_hw *hw, u8 *progress,
4205				struct i40e_asq_cmd_details *cmd_details)
4206{
4207	enum i40e_status_code status;
4208	struct i40e_aq_desc desc;
4209
4210	DEBUGFUNC("i40e_aq_nvm_progress");
4211
4212	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_progress);
4213	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4214	*progress = desc.params.raw[0];
4215	return status;
4216}
4217
4218/**
4219 * i40e_aq_get_lldp_mib
4220 * @hw: pointer to the hw struct
4221 * @bridge_type: type of bridge requested
4222 * @mib_type: Local, Remote or both Local and Remote MIBs
4223 * @buff: pointer to a user supplied buffer to store the MIB block
4224 * @buff_size: size of the buffer (in bytes)
4225 * @local_len : length of the returned Local LLDP MIB
4226 * @remote_len: length of the returned Remote LLDP MIB
4227 * @cmd_details: pointer to command details structure or NULL
4228 *
4229 * Requests the complete LLDP MIB (entire packet).
4230 **/
4231enum i40e_status_code i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
4232				u8 mib_type, void *buff, u16 buff_size,
4233				u16 *local_len, u16 *remote_len,
4234				struct i40e_asq_cmd_details *cmd_details)
4235{
4236	struct i40e_aq_desc desc;
4237	struct i40e_aqc_lldp_get_mib *cmd =
4238		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
4239	struct i40e_aqc_lldp_get_mib *resp =
4240		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
4241	enum i40e_status_code status;
4242
4243	if (buff_size == 0 || !buff)
4244		return I40E_ERR_PARAM;
4245
4246	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_get_mib);
4247	/* Indirect Command */
4248	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4249
4250	cmd->type = mib_type & I40E_AQ_LLDP_MIB_TYPE_MASK;
4251	cmd->type |= ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
4252		       I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
4253
4254	desc.datalen = CPU_TO_LE16(buff_size);
4255
4256	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4257	if (buff_size > I40E_AQ_LARGE_BUF)
4258		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4259
4260	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4261	if (!status) {
4262		if (local_len != NULL)
4263			*local_len = LE16_TO_CPU(resp->local_len);
4264		if (remote_len != NULL)
4265			*remote_len = LE16_TO_CPU(resp->remote_len);
4266	}
4267
4268	return status;
4269}
4270
4271 /**
4272 * i40e_aq_set_lldp_mib - Set the LLDP MIB
4273 * @hw: pointer to the hw struct
4274 * @mib_type: Local, Remote or both Local and Remote MIBs
4275 * @buff: pointer to a user supplied buffer to store the MIB block
4276 * @buff_size: size of the buffer (in bytes)
4277 * @cmd_details: pointer to command details structure or NULL
4278 *
4279 * Set the LLDP MIB.
4280 **/
4281enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw,
4282				u8 mib_type, void *buff, u16 buff_size,
4283				struct i40e_asq_cmd_details *cmd_details)
4284{
4285	struct i40e_aq_desc desc;
4286	struct i40e_aqc_lldp_set_local_mib *cmd =
4287		(struct i40e_aqc_lldp_set_local_mib *)&desc.params.raw;
4288	enum i40e_status_code status;
4289
4290	if (buff_size == 0 || !buff)
4291		return I40E_ERR_PARAM;
4292
4293	i40e_fill_default_direct_cmd_desc(&desc,
4294				i40e_aqc_opc_lldp_set_local_mib);
4295	/* Indirect Command */
4296	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4297	if (buff_size > I40E_AQ_LARGE_BUF)
4298		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4299	desc.datalen = CPU_TO_LE16(buff_size);
4300
4301	cmd->type = mib_type;
4302	cmd->length = CPU_TO_LE16(buff_size);
4303	cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)buff));
4304	cmd->address_low =  CPU_TO_LE32(I40E_LO_DWORD((u64)buff));
4305
4306	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4307	return status;
4308}
4309
4310/**
4311 * i40e_aq_cfg_lldp_mib_change_event
4312 * @hw: pointer to the hw struct
4313 * @enable_update: Enable or Disable event posting
4314 * @cmd_details: pointer to command details structure or NULL
4315 *
4316 * Enable or Disable posting of an event on ARQ when LLDP MIB
4317 * associated with the interface changes
4318 **/
4319enum i40e_status_code i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
4320				bool enable_update,
4321				struct i40e_asq_cmd_details *cmd_details)
4322{
4323	struct i40e_aq_desc desc;
4324	struct i40e_aqc_lldp_update_mib *cmd =
4325		(struct i40e_aqc_lldp_update_mib *)&desc.params.raw;
4326	enum i40e_status_code status;
4327
4328	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_mib);
4329
4330	if (!enable_update)
4331		cmd->command |= I40E_AQ_LLDP_MIB_UPDATE_DISABLE;
4332
4333	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4334
4335	return status;
4336}
4337
4338/**
4339 * i40e_aq_restore_lldp
4340 * @hw: pointer to the hw struct
4341 * @setting: pointer to factory setting variable or NULL
4342 * @restore: True if factory settings should be restored
4343 * @cmd_details: pointer to command details structure or NULL
4344 *
4345 * Restore LLDP Agent factory settings if @restore set to True. In other case
4346 * only returns factory setting in AQ response.
4347 **/
4348enum i40e_status_code
4349i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
4350		     struct i40e_asq_cmd_details *cmd_details)
4351{
4352	struct i40e_aq_desc desc;
4353	struct i40e_aqc_lldp_restore *cmd =
4354		(struct i40e_aqc_lldp_restore *)&desc.params.raw;
4355	enum i40e_status_code status;
4356
4357	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) {
4358		i40e_debug(hw, I40E_DEBUG_ALL,
4359			   "Restore LLDP not supported by current FW version.\n");
4360		return I40E_ERR_DEVICE_NOT_SUPPORTED;
4361	}
4362
4363	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore);
4364
4365	if (restore)
4366		cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE;
4367
4368	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4369
4370	if (setting)
4371		*setting = cmd->command & 1;
4372
4373	return status;
4374}
4375
4376/**
4377 * i40e_aq_stop_lldp
4378 * @hw: pointer to the hw struct
4379 * @shutdown_agent: True if LLDP Agent needs to be Shutdown
4380 * @persist: True if stop of LLDP should be persistent across power cycles
4381 * @cmd_details: pointer to command details structure or NULL
4382 *
4383 * Stop or Shutdown the embedded LLDP Agent
4384 **/
4385enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
4386				bool persist,
4387				struct i40e_asq_cmd_details *cmd_details)
4388{
4389	struct i40e_aq_desc desc;
4390	struct i40e_aqc_lldp_stop *cmd =
4391		(struct i40e_aqc_lldp_stop *)&desc.params.raw;
4392	enum i40e_status_code status;
4393
4394	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
4395
4396	if (shutdown_agent)
4397		cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
4398
4399	if (persist) {
4400		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
4401			cmd->command |= I40E_AQ_LLDP_AGENT_STOP_PERSIST;
4402		else
4403			i40e_debug(hw, I40E_DEBUG_ALL,
4404				   "Persistent Stop LLDP not supported by current FW version.\n");
4405	}
4406
4407	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4408
4409	return status;
4410}
4411
4412/**
4413 * i40e_aq_start_lldp
4414 * @hw: pointer to the hw struct
4415 * @persist: True if start of LLDP should be persistent across power cycles
4416 * @cmd_details: pointer to command details structure or NULL
4417 *
4418 * Start the embedded LLDP Agent on all ports.
4419 **/
4420enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw,
4421				bool persist,
4422				struct i40e_asq_cmd_details *cmd_details)
4423{
4424	struct i40e_aq_desc desc;
4425	struct i40e_aqc_lldp_start *cmd =
4426		(struct i40e_aqc_lldp_start *)&desc.params.raw;
4427	enum i40e_status_code status;
4428
4429	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
4430
4431	cmd->command = I40E_AQ_LLDP_AGENT_START;
4432
4433	if (persist) {
4434		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
4435			cmd->command |= I40E_AQ_LLDP_AGENT_START_PERSIST;
4436		else
4437			i40e_debug(hw, I40E_DEBUG_ALL,
4438				   "Persistent Start LLDP not supported by current FW version.\n");
4439	}
4440
4441	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4442
4443	return status;
4444}
4445
4446/**
4447 * i40e_aq_set_dcb_parameters
4448 * @hw: pointer to the hw struct
4449 * @cmd_details: pointer to command details structure or NULL
4450 * @dcb_enable: True if DCB configuration needs to be applied
4451 *
4452 **/
4453enum i40e_status_code
4454i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
4455			   struct i40e_asq_cmd_details *cmd_details)
4456{
4457	struct i40e_aq_desc desc;
4458	struct i40e_aqc_set_dcb_parameters *cmd =
4459		(struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
4460	enum i40e_status_code status;
4461
4462	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE))
4463		return I40E_ERR_DEVICE_NOT_SUPPORTED;
4464
4465	i40e_fill_default_direct_cmd_desc(&desc,
4466					  i40e_aqc_opc_set_dcb_parameters);
4467
4468	if (dcb_enable) {
4469		cmd->valid_flags = I40E_DCB_VALID;
4470		cmd->command = I40E_AQ_DCB_SET_AGENT;
4471	}
4472	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4473
4474	return status;
4475}
4476
4477/**
4478 * i40e_aq_get_cee_dcb_config
4479 * @hw: pointer to the hw struct
4480 * @buff: response buffer that stores CEE operational configuration
4481 * @buff_size: size of the buffer passed
4482 * @cmd_details: pointer to command details structure or NULL
4483 *
4484 * Get CEE DCBX mode operational configuration from firmware
4485 **/
4486enum i40e_status_code i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
4487				void *buff, u16 buff_size,
4488				struct i40e_asq_cmd_details *cmd_details)
4489{
4490	struct i40e_aq_desc desc;
4491	enum i40e_status_code status;
4492
4493	if (buff_size == 0 || !buff)
4494		return I40E_ERR_PARAM;
4495
4496	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_cee_dcb_cfg);
4497
4498	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4499	status = i40e_asq_send_command(hw, &desc, (void *)buff, buff_size,
4500				       cmd_details);
4501
4502	return status;
4503}
4504
4505/**
4506 * i40e_aq_start_stop_dcbx - Start/Stop DCBx service in FW
4507 * @hw: pointer to the hw struct
4508 * @start_agent: True if DCBx Agent needs to be Started
4509 *				False if DCBx Agent needs to be Stopped
4510 * @cmd_details: pointer to command details structure or NULL
4511 *
4512 * Start/Stop the embedded dcbx Agent
4513 **/
4514enum i40e_status_code i40e_aq_start_stop_dcbx(struct i40e_hw *hw,
4515				bool start_agent,
4516				struct i40e_asq_cmd_details *cmd_details)
4517{
4518	struct i40e_aq_desc desc;
4519	struct i40e_aqc_lldp_stop_start_specific_agent *cmd =
4520		(struct i40e_aqc_lldp_stop_start_specific_agent *)
4521				&desc.params.raw;
4522	enum i40e_status_code status;
4523
4524	i40e_fill_default_direct_cmd_desc(&desc,
4525				i40e_aqc_opc_lldp_stop_start_spec_agent);
4526
4527	if (start_agent)
4528		cmd->command = I40E_AQC_START_SPECIFIC_AGENT_MASK;
4529
4530	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4531
4532	return status;
4533}
4534
4535/**
4536 * i40e_aq_add_udp_tunnel
4537 * @hw: pointer to the hw struct
4538 * @udp_port: the UDP port to add in Host byte order
4539 * @protocol_index: protocol index type
4540 * @filter_index: pointer to filter index
4541 * @cmd_details: pointer to command details structure or NULL
4542 *
4543 * Note: Firmware expects the udp_port value to be in Little Endian format,
4544 * and this function will call CPU_TO_LE16 to convert from Host byte order to
4545 * Little Endian order.
4546 **/
4547enum i40e_status_code i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
4548				u16 udp_port, u8 protocol_index,
4549				u8 *filter_index,
4550				struct i40e_asq_cmd_details *cmd_details)
4551{
4552	struct i40e_aq_desc desc;
4553	struct i40e_aqc_add_udp_tunnel *cmd =
4554		(struct i40e_aqc_add_udp_tunnel *)&desc.params.raw;
4555	struct i40e_aqc_del_udp_tunnel_completion *resp =
4556		(struct i40e_aqc_del_udp_tunnel_completion *)&desc.params.raw;
4557	enum i40e_status_code status;
4558
4559	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_udp_tunnel);
4560
4561	cmd->udp_port = CPU_TO_LE16(udp_port);
4562	cmd->protocol_type = protocol_index;
4563
4564	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4565
4566	if (!status && filter_index)
4567		*filter_index = resp->index;
4568
4569	return status;
4570}
4571
4572/**
4573 * i40e_aq_del_udp_tunnel
4574 * @hw: pointer to the hw struct
4575 * @index: filter index
4576 * @cmd_details: pointer to command details structure or NULL
4577 **/
4578enum i40e_status_code i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
4579				struct i40e_asq_cmd_details *cmd_details)
4580{
4581	struct i40e_aq_desc desc;
4582	struct i40e_aqc_remove_udp_tunnel *cmd =
4583		(struct i40e_aqc_remove_udp_tunnel *)&desc.params.raw;
4584	enum i40e_status_code status;
4585
4586	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_del_udp_tunnel);
4587
4588	cmd->index = index;
4589
4590	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4591
4592	return status;
4593}
4594
4595/**
4596 * i40e_aq_get_switch_resource_alloc (0x0204)
4597 * @hw: pointer to the hw struct
4598 * @num_entries: pointer to u8 to store the number of resource entries returned
4599 * @buf: pointer to a user supplied buffer.  This buffer must be large enough
4600 *        to store the resource information for all resource types.  Each
4601 *        resource type is a i40e_aqc_switch_resource_alloc_data structure.
4602 * @count: size, in bytes, of the buffer provided
4603 * @cmd_details: pointer to command details structure or NULL
4604 *
4605 * Query the resources allocated to a function.
4606 **/
4607enum i40e_status_code i40e_aq_get_switch_resource_alloc(struct i40e_hw *hw,
4608			u8 *num_entries,
4609			struct i40e_aqc_switch_resource_alloc_element_resp *buf,
4610			u16 count,
4611			struct i40e_asq_cmd_details *cmd_details)
4612{
4613	struct i40e_aq_desc desc;
4614	struct i40e_aqc_get_switch_resource_alloc *cmd_resp =
4615		(struct i40e_aqc_get_switch_resource_alloc *)&desc.params.raw;
4616	enum i40e_status_code status;
4617	u16 length = count * sizeof(*buf);
4618
4619	i40e_fill_default_direct_cmd_desc(&desc,
4620					i40e_aqc_opc_get_switch_resource_alloc);
4621
4622	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4623	if (length > I40E_AQ_LARGE_BUF)
4624		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4625
4626	status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
4627
4628	if (!status && num_entries)
4629		*num_entries = cmd_resp->num_entries;
4630
4631	return status;
4632}
4633
4634/**
4635 * i40e_aq_delete_element - Delete switch element
4636 * @hw: pointer to the hw struct
4637 * @seid: the SEID to delete from the switch
4638 * @cmd_details: pointer to command details structure or NULL
4639 *
4640 * This deletes a switch element from the switch.
4641 **/
4642enum i40e_status_code i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
4643				struct i40e_asq_cmd_details *cmd_details)
4644{
4645	struct i40e_aq_desc desc;
4646	struct i40e_aqc_switch_seid *cmd =
4647		(struct i40e_aqc_switch_seid *)&desc.params.raw;
4648	enum i40e_status_code status;
4649
4650	if (seid == 0)
4651		return I40E_ERR_PARAM;
4652
4653	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_delete_element);
4654
4655	cmd->seid = CPU_TO_LE16(seid);
4656	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4657
4658	return status;
4659}
4660
4661/**
4662 * i40e_aq_add_pvirt - Instantiate a Port Virtualizer on a port
4663 * @hw: pointer to the hw struct
4664 * @flags: component flags
4665 * @mac_seid: uplink seid (MAC SEID)
4666 * @vsi_seid: connected vsi seid
4667 * @ret_seid: seid of create pv component
4668 *
4669 * This instantiates an i40e port virtualizer with specified flags.
4670 * Depending on specified flags the port virtualizer can act as a
4671 * 802.1Qbr port virtualizer or a 802.1Qbg S-component.
4672 */
4673enum i40e_status_code i40e_aq_add_pvirt(struct i40e_hw *hw, u16 flags,
4674				       u16 mac_seid, u16 vsi_seid,
4675				       u16 *ret_seid)
4676{
4677	struct i40e_aq_desc desc;
4678	struct i40e_aqc_add_update_pv *cmd =
4679		(struct i40e_aqc_add_update_pv *)&desc.params.raw;
4680	struct i40e_aqc_add_update_pv_completion *resp =
4681		(struct i40e_aqc_add_update_pv_completion *)&desc.params.raw;
4682	enum i40e_status_code status;
4683
4684	if (vsi_seid == 0)
4685		return I40E_ERR_PARAM;
4686
4687	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_pv);
4688	cmd->command_flags = CPU_TO_LE16(flags);
4689	cmd->uplink_seid = CPU_TO_LE16(mac_seid);
4690	cmd->connected_seid = CPU_TO_LE16(vsi_seid);
4691
4692	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
4693	if (!status && ret_seid)
4694		*ret_seid = LE16_TO_CPU(resp->pv_seid);
4695
4696	return status;
4697}
4698
4699/**
4700 * i40e_aq_add_tag - Add an S/E-tag
4701 * @hw: pointer to the hw struct
4702 * @direct_to_queue: should s-tag direct flow to a specific queue
4703 * @vsi_seid: VSI SEID to use this tag
4704 * @tag: value of the tag
4705 * @queue_num: queue number, only valid is direct_to_queue is TRUE
4706 * @tags_used: return value, number of tags in use by this PF
4707 * @tags_free: return value, number of unallocated tags
4708 * @cmd_details: pointer to command details structure or NULL
4709 *
4710 * This associates an S- or E-tag to a VSI in the switch complex.  It returns
4711 * the number of tags allocated by the PF, and the number of unallocated
4712 * tags available.
4713 **/
4714enum i40e_status_code i40e_aq_add_tag(struct i40e_hw *hw, bool direct_to_queue,
4715				u16 vsi_seid, u16 tag, u16 queue_num,
4716				u16 *tags_used, u16 *tags_free,
4717				struct i40e_asq_cmd_details *cmd_details)
4718{
4719	struct i40e_aq_desc desc;
4720	struct i40e_aqc_add_tag *cmd =
4721		(struct i40e_aqc_add_tag *)&desc.params.raw;
4722	struct i40e_aqc_add_remove_tag_completion *resp =
4723		(struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
4724	enum i40e_status_code status;
4725
4726	if (vsi_seid == 0)
4727		return I40E_ERR_PARAM;
4728
4729	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_tag);
4730
4731	cmd->seid = CPU_TO_LE16(vsi_seid);
4732	cmd->tag = CPU_TO_LE16(tag);
4733	if (direct_to_queue) {
4734		cmd->flags = CPU_TO_LE16(I40E_AQC_ADD_TAG_FLAG_TO_QUEUE);
4735		cmd->queue_number = CPU_TO_LE16(queue_num);
4736	}
4737
4738	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4739
4740	if (!status) {
4741		if (tags_used != NULL)
4742			*tags_used = LE16_TO_CPU(resp->tags_used);
4743		if (tags_free != NULL)
4744			*tags_free = LE16_TO_CPU(resp->tags_free);
4745	}
4746
4747	return status;
4748}
4749
4750/**
4751 * i40e_aq_remove_tag - Remove an S- or E-tag
4752 * @hw: pointer to the hw struct
4753 * @vsi_seid: VSI SEID this tag is associated with
4754 * @tag: value of the S-tag to delete
4755 * @tags_used: return value, number of tags in use by this PF
4756 * @tags_free: return value, number of unallocated tags
4757 * @cmd_details: pointer to command details structure or NULL
4758 *
4759 * This deletes an S- or E-tag from a VSI in the switch complex.  It returns
4760 * the number of tags allocated by the PF, and the number of unallocated
4761 * tags available.
4762 **/
4763enum i40e_status_code i40e_aq_remove_tag(struct i40e_hw *hw, u16 vsi_seid,
4764				u16 tag, u16 *tags_used, u16 *tags_free,
4765				struct i40e_asq_cmd_details *cmd_details)
4766{
4767	struct i40e_aq_desc desc;
4768	struct i40e_aqc_remove_tag *cmd =
4769		(struct i40e_aqc_remove_tag *)&desc.params.raw;
4770	struct i40e_aqc_add_remove_tag_completion *resp =
4771		(struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
4772	enum i40e_status_code status;
4773
4774	if (vsi_seid == 0)
4775		return I40E_ERR_PARAM;
4776
4777	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_tag);
4778
4779	cmd->seid = CPU_TO_LE16(vsi_seid);
4780	cmd->tag = CPU_TO_LE16(tag);
4781
4782	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4783
4784	if (!status) {
4785		if (tags_used != NULL)
4786			*tags_used = LE16_TO_CPU(resp->tags_used);
4787		if (tags_free != NULL)
4788			*tags_free = LE16_TO_CPU(resp->tags_free);
4789	}
4790
4791	return status;
4792}
4793
4794/**
4795 * i40e_aq_add_mcast_etag - Add a multicast E-tag
4796 * @hw: pointer to the hw struct
4797 * @pv_seid: Port Virtualizer of this SEID to associate E-tag with
4798 * @etag: value of E-tag to add
4799 * @num_tags_in_buf: number of unicast E-tags in indirect buffer
4800 * @buf: address of indirect buffer
4801 * @tags_used: return value, number of E-tags in use by this port
4802 * @tags_free: return value, number of unallocated M-tags
4803 * @cmd_details: pointer to command details structure or NULL
4804 *
4805 * This associates a multicast E-tag to a port virtualizer.  It will return
4806 * the number of tags allocated by the PF, and the number of unallocated
4807 * tags available.
4808 *
4809 * The indirect buffer pointed to by buf is a list of 2-byte E-tags,
4810 * num_tags_in_buf long.
4811 **/
4812enum i40e_status_code i40e_aq_add_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
4813				u16 etag, u8 num_tags_in_buf, void *buf,
4814				u16 *tags_used, u16 *tags_free,
4815				struct i40e_asq_cmd_details *cmd_details)
4816{
4817	struct i40e_aq_desc desc;
4818	struct i40e_aqc_add_remove_mcast_etag *cmd =
4819		(struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
4820	struct i40e_aqc_add_remove_mcast_etag_completion *resp =
4821	   (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
4822	enum i40e_status_code status;
4823	u16 length = sizeof(u16) * num_tags_in_buf;
4824
4825	if ((pv_seid == 0) || (buf == NULL) || (num_tags_in_buf == 0))
4826		return I40E_ERR_PARAM;
4827
4828	i40e_fill_default_direct_cmd_desc(&desc,
4829					  i40e_aqc_opc_add_multicast_etag);
4830
4831	cmd->pv_seid = CPU_TO_LE16(pv_seid);
4832	cmd->etag = CPU_TO_LE16(etag);
4833	cmd->num_unicast_etags = num_tags_in_buf;
4834
4835	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4836
4837	status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
4838
4839	if (!status) {
4840		if (tags_used != NULL)
4841			*tags_used = LE16_TO_CPU(resp->mcast_etags_used);
4842		if (tags_free != NULL)
4843			*tags_free = LE16_TO_CPU(resp->mcast_etags_free);
4844	}
4845
4846	return status;
4847}
4848
4849/**
4850 * i40e_aq_remove_mcast_etag - Remove a multicast E-tag
4851 * @hw: pointer to the hw struct
4852 * @pv_seid: Port Virtualizer SEID this M-tag is associated with
4853 * @etag: value of the E-tag to remove
4854 * @tags_used: return value, number of tags in use by this port
4855 * @tags_free: return value, number of unallocated tags
4856 * @cmd_details: pointer to command details structure or NULL
4857 *
4858 * This deletes an E-tag from the port virtualizer.  It will return
4859 * the number of tags allocated by the port, and the number of unallocated
4860 * tags available.
4861 **/
4862enum i40e_status_code i40e_aq_remove_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
4863				u16 etag, u16 *tags_used, u16 *tags_free,
4864				struct i40e_asq_cmd_details *cmd_details)
4865{
4866	struct i40e_aq_desc desc;
4867	struct i40e_aqc_add_remove_mcast_etag *cmd =
4868		(struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
4869	struct i40e_aqc_add_remove_mcast_etag_completion *resp =
4870	   (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
4871	enum i40e_status_code status;
4872
4873
4874	if (pv_seid == 0)
4875		return I40E_ERR_PARAM;
4876
4877	i40e_fill_default_direct_cmd_desc(&desc,
4878					  i40e_aqc_opc_remove_multicast_etag);
4879
4880	cmd->pv_seid = CPU_TO_LE16(pv_seid);
4881	cmd->etag = CPU_TO_LE16(etag);
4882
4883	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4884
4885	if (!status) {
4886		if (tags_used != NULL)
4887			*tags_used = LE16_TO_CPU(resp->mcast_etags_used);
4888		if (tags_free != NULL)
4889			*tags_free = LE16_TO_CPU(resp->mcast_etags_free);
4890	}
4891
4892	return status;
4893}
4894
4895/**
4896 * i40e_aq_update_tag - Update an S/E-tag
4897 * @hw: pointer to the hw struct
4898 * @vsi_seid: VSI SEID using this S-tag
4899 * @old_tag: old tag value
4900 * @new_tag: new tag value
4901 * @tags_used: return value, number of tags in use by this PF
4902 * @tags_free: return value, number of unallocated tags
4903 * @cmd_details: pointer to command details structure or NULL
4904 *
4905 * This updates the value of the tag currently attached to this VSI
4906 * in the switch complex.  It will return the number of tags allocated
4907 * by the PF, and the number of unallocated tags available.
4908 **/
4909enum i40e_status_code i40e_aq_update_tag(struct i40e_hw *hw, u16 vsi_seid,
4910				u16 old_tag, u16 new_tag, u16 *tags_used,
4911				u16 *tags_free,
4912				struct i40e_asq_cmd_details *cmd_details)
4913{
4914	struct i40e_aq_desc desc;
4915	struct i40e_aqc_update_tag *cmd =
4916		(struct i40e_aqc_update_tag *)&desc.params.raw;
4917	struct i40e_aqc_update_tag_completion *resp =
4918		(struct i40e_aqc_update_tag_completion *)&desc.params.raw;
4919	enum i40e_status_code status;
4920
4921	if (vsi_seid == 0)
4922		return I40E_ERR_PARAM;
4923
4924	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_update_tag);
4925
4926	cmd->seid = CPU_TO_LE16(vsi_seid);
4927	cmd->old_tag = CPU_TO_LE16(old_tag);
4928	cmd->new_tag = CPU_TO_LE16(new_tag);
4929
4930	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4931
4932	if (!status) {
4933		if (tags_used != NULL)
4934			*tags_used = LE16_TO_CPU(resp->tags_used);
4935		if (tags_free != NULL)
4936			*tags_free = LE16_TO_CPU(resp->tags_free);
4937	}
4938
4939	return status;
4940}
4941
4942/**
4943 * i40e_aq_dcb_ignore_pfc - Ignore PFC for given TCs
4944 * @hw: pointer to the hw struct
4945 * @tcmap: TC map for request/release any ignore PFC condition
4946 * @request: request or release ignore PFC condition
4947 * @tcmap_ret: return TCs for which PFC is currently ignored
4948 * @cmd_details: pointer to command details structure or NULL
4949 *
4950 * This sends out request/release to ignore PFC condition for a TC.
4951 * It will return the TCs for which PFC is currently ignored.
4952 **/
4953enum i40e_status_code i40e_aq_dcb_ignore_pfc(struct i40e_hw *hw, u8 tcmap,
4954				bool request, u8 *tcmap_ret,
4955				struct i40e_asq_cmd_details *cmd_details)
4956{
4957	struct i40e_aq_desc desc;
4958	struct i40e_aqc_pfc_ignore *cmd_resp =
4959		(struct i40e_aqc_pfc_ignore *)&desc.params.raw;
4960	enum i40e_status_code status;
4961
4962	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_ignore_pfc);
4963
4964	if (request)
4965		cmd_resp->command_flags = I40E_AQC_PFC_IGNORE_SET;
4966
4967	cmd_resp->tc_bitmap = tcmap;
4968
4969	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4970
4971	if (!status) {
4972		if (tcmap_ret != NULL)
4973			*tcmap_ret = cmd_resp->tc_bitmap;
4974	}
4975
4976	return status;
4977}
4978
4979/**
4980 * i40e_aq_dcb_updated - DCB Updated Command
4981 * @hw: pointer to the hw struct
4982 * @cmd_details: pointer to command details structure or NULL
4983 *
4984 * When LLDP is handled in PF this command is used by the PF
4985 * to notify EMP that a DCB setting is modified.
4986 * When LLDP is handled in EMP this command is used by the PF
4987 * to notify EMP whenever one of the following parameters get
4988 * modified:
4989 *   - PFCLinkDelayAllowance in PRTDCB_GENC.PFCLDA
4990 *   - PCIRTT in PRTDCB_GENC.PCIRTT
4991 *   - Maximum Frame Size for non-FCoE TCs set by PRTDCB_TDPUC.MAX_TXFRAME.
4992 * EMP will return when the shared RPB settings have been
4993 * recomputed and modified. The retval field in the descriptor
4994 * will be set to 0 when RPB is modified.
4995 **/
4996enum i40e_status_code i40e_aq_dcb_updated(struct i40e_hw *hw,
4997				struct i40e_asq_cmd_details *cmd_details)
4998{
4999	struct i40e_aq_desc desc;
5000	enum i40e_status_code status;
5001
5002	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_updated);
5003
5004	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5005
5006	return status;
5007}
5008
5009/**
5010 * i40e_aq_add_statistics - Add a statistics block to a VLAN in a switch.
5011 * @hw: pointer to the hw struct
5012 * @seid: defines the SEID of the switch for which the stats are requested
5013 * @vlan_id: the VLAN ID for which the statistics are requested
5014 * @stat_index: index of the statistics counters block assigned to this VLAN
5015 * @cmd_details: pointer to command details structure or NULL
5016 *
5017 * XL710 supports 128 smonVlanStats counters.This command is used to
5018 * allocate a set of smonVlanStats counters to a specific VLAN in a specific
5019 * switch.
5020 **/
5021enum i40e_status_code i40e_aq_add_statistics(struct i40e_hw *hw, u16 seid,
5022				u16 vlan_id, u16 *stat_index,
5023				struct i40e_asq_cmd_details *cmd_details)
5024{
5025	struct i40e_aq_desc desc;
5026	struct i40e_aqc_add_remove_statistics *cmd_resp =
5027		(struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
5028	enum i40e_status_code status;
5029
5030	if ((seid == 0) || (stat_index == NULL))
5031		return I40E_ERR_PARAM;
5032
5033	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_statistics);
5034
5035	cmd_resp->seid = CPU_TO_LE16(seid);
5036	cmd_resp->vlan = CPU_TO_LE16(vlan_id);
5037
5038	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5039
5040	if (!status && stat_index)
5041		*stat_index = LE16_TO_CPU(cmd_resp->stat_index);
5042
5043	return status;
5044}
5045
5046/**
5047 * i40e_aq_remove_statistics - Remove a statistics block to a VLAN in a switch.
5048 * @hw: pointer to the hw struct
5049 * @seid: defines the SEID of the switch for which the stats are requested
5050 * @vlan_id: the VLAN ID for which the statistics are requested
5051 * @stat_index: index of the statistics counters block assigned to this VLAN
5052 * @cmd_details: pointer to command details structure or NULL
5053 *
5054 * XL710 supports 128 smonVlanStats counters.This command is used to
5055 * deallocate a set of smonVlanStats counters to a specific VLAN in a specific
5056 * switch.
5057 **/
5058enum i40e_status_code i40e_aq_remove_statistics(struct i40e_hw *hw, u16 seid,
5059				u16 vlan_id, u16 stat_index,
5060				struct i40e_asq_cmd_details *cmd_details)
5061{
5062	struct i40e_aq_desc desc;
5063	struct i40e_aqc_add_remove_statistics *cmd =
5064		(struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
5065	enum i40e_status_code status;
5066
5067	if (seid == 0)
5068		return I40E_ERR_PARAM;
5069
5070	i40e_fill_default_direct_cmd_desc(&desc,
5071					  i40e_aqc_opc_remove_statistics);
5072
5073	cmd->seid = CPU_TO_LE16(seid);
5074	cmd->vlan  = CPU_TO_LE16(vlan_id);
5075	cmd->stat_index = CPU_TO_LE16(stat_index);
5076
5077	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5078
5079	return status;
5080}
5081
5082/**
5083 * i40e_aq_set_port_parameters - set physical port parameters.
5084 * @hw: pointer to the hw struct
5085 * @bad_frame_vsi: defines the VSI to which bad frames are forwarded
5086 * @save_bad_pac: if set packets with errors are forwarded to the bad frames VSI
5087 * @pad_short_pac: if set transmit packets smaller than 60 bytes are padded
5088 * @double_vlan: if set double VLAN is enabled
5089 * @cmd_details: pointer to command details structure or NULL
5090 **/
5091enum i40e_status_code i40e_aq_set_port_parameters(struct i40e_hw *hw,
5092				u16 bad_frame_vsi, bool save_bad_pac,
5093				bool pad_short_pac, bool double_vlan,
5094				struct i40e_asq_cmd_details *cmd_details)
5095{
5096	struct i40e_aqc_set_port_parameters *cmd;
5097	enum i40e_status_code status;
5098	struct i40e_aq_desc desc;
5099	u16 command_flags = 0;
5100
5101	cmd = (struct i40e_aqc_set_port_parameters *)&desc.params.raw;
5102
5103	i40e_fill_default_direct_cmd_desc(&desc,
5104					  i40e_aqc_opc_set_port_parameters);
5105
5106	cmd->bad_frame_vsi = CPU_TO_LE16(bad_frame_vsi);
5107	if (save_bad_pac)
5108		command_flags |= I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS;
5109	if (pad_short_pac)
5110		command_flags |= I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS;
5111	if (double_vlan)
5112		command_flags |= I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA;
5113	cmd->command_flags = CPU_TO_LE16(command_flags);
5114
5115	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5116
5117	return status;
5118}
5119
5120/**
5121 * i40e_aq_tx_sched_cmd - generic Tx scheduler AQ command handler
5122 * @hw: pointer to the hw struct
5123 * @seid: seid for the physical port/switching component/vsi
5124 * @buff: Indirect buffer to hold data parameters and response
5125 * @buff_size: Indirect buffer size
5126 * @opcode: Tx scheduler AQ command opcode
5127 * @cmd_details: pointer to command details structure or NULL
5128 *
5129 * Generic command handler for Tx scheduler AQ commands
5130 **/
5131static enum i40e_status_code i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
5132				void *buff, u16 buff_size,
5133				 enum i40e_admin_queue_opc opcode,
5134				struct i40e_asq_cmd_details *cmd_details)
5135{
5136	struct i40e_aq_desc desc;
5137	struct i40e_aqc_tx_sched_ind *cmd =
5138		(struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
5139	enum i40e_status_code status;
5140	bool cmd_param_flag = FALSE;
5141
5142	switch (opcode) {
5143	case i40e_aqc_opc_configure_vsi_ets_sla_bw_limit:
5144	case i40e_aqc_opc_configure_vsi_tc_bw:
5145	case i40e_aqc_opc_enable_switching_comp_ets:
5146	case i40e_aqc_opc_modify_switching_comp_ets:
5147	case i40e_aqc_opc_disable_switching_comp_ets:
5148	case i40e_aqc_opc_configure_switching_comp_ets_bw_limit:
5149	case i40e_aqc_opc_configure_switching_comp_bw_config:
5150		cmd_param_flag = TRUE;
5151		break;
5152	case i40e_aqc_opc_query_vsi_bw_config:
5153	case i40e_aqc_opc_query_vsi_ets_sla_config:
5154	case i40e_aqc_opc_query_switching_comp_ets_config:
5155	case i40e_aqc_opc_query_port_ets_config:
5156	case i40e_aqc_opc_query_switching_comp_bw_config:
5157		cmd_param_flag = FALSE;
5158		break;
5159	default:
5160		return I40E_ERR_PARAM;
5161	}
5162
5163	i40e_fill_default_direct_cmd_desc(&desc, opcode);
5164
5165	/* Indirect command */
5166	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
5167	if (cmd_param_flag)
5168		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
5169	if (buff_size > I40E_AQ_LARGE_BUF)
5170		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5171
5172	desc.datalen = CPU_TO_LE16(buff_size);
5173
5174	cmd->vsi_seid = CPU_TO_LE16(seid);
5175
5176	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5177
5178	return status;
5179}
5180
5181/**
5182 * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
5183 * @hw: pointer to the hw struct
5184 * @seid: VSI seid
5185 * @credit: BW limit credits (0 = disabled)
5186 * @max_credit: Max BW limit credits
5187 * @cmd_details: pointer to command details structure or NULL
5188 **/
5189enum i40e_status_code i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
5190				u16 seid, u16 credit, u8 max_credit,
5191				struct i40e_asq_cmd_details *cmd_details)
5192{
5193	struct i40e_aq_desc desc;
5194	struct i40e_aqc_configure_vsi_bw_limit *cmd =
5195		(struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
5196	enum i40e_status_code status;
5197
5198	i40e_fill_default_direct_cmd_desc(&desc,
5199					  i40e_aqc_opc_configure_vsi_bw_limit);
5200
5201	cmd->vsi_seid = CPU_TO_LE16(seid);
5202	cmd->credit = CPU_TO_LE16(credit);
5203	cmd->max_credit = max_credit;
5204
5205	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5206
5207	return status;
5208}
5209
5210/**
5211 * i40e_aq_config_switch_comp_bw_limit - Configure Switching component BW Limit
5212 * @hw: pointer to the hw struct
5213 * @seid: switching component seid
5214 * @credit: BW limit credits (0 = disabled)
5215 * @max_bw: Max BW limit credits
5216 * @cmd_details: pointer to command details structure or NULL
5217 **/
5218enum i40e_status_code i40e_aq_config_switch_comp_bw_limit(struct i40e_hw *hw,
5219				u16 seid, u16 credit, u8 max_bw,
5220				struct i40e_asq_cmd_details *cmd_details)
5221{
5222	struct i40e_aq_desc desc;
5223	struct i40e_aqc_configure_switching_comp_bw_limit *cmd =
5224	  (struct i40e_aqc_configure_switching_comp_bw_limit *)&desc.params.raw;
5225	enum i40e_status_code status;
5226
5227	i40e_fill_default_direct_cmd_desc(&desc,
5228				i40e_aqc_opc_configure_switching_comp_bw_limit);
5229
5230	cmd->seid = CPU_TO_LE16(seid);
5231	cmd->credit = CPU_TO_LE16(credit);
5232	cmd->max_bw = max_bw;
5233
5234	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5235
5236	return status;
5237}
5238
5239/**
5240 * i40e_aq_config_vsi_ets_sla_bw_limit - Config VSI BW Limit per TC
5241 * @hw: pointer to the hw struct
5242 * @seid: VSI seid
5243 * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
5244 * @cmd_details: pointer to command details structure or NULL
5245 **/
5246enum i40e_status_code i40e_aq_config_vsi_ets_sla_bw_limit(struct i40e_hw *hw,
5247			u16 seid,
5248			struct i40e_aqc_configure_vsi_ets_sla_bw_data *bw_data,
5249			struct i40e_asq_cmd_details *cmd_details)
5250{
5251	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5252				    i40e_aqc_opc_configure_vsi_ets_sla_bw_limit,
5253				    cmd_details);
5254}
5255
5256/**
5257 * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
5258 * @hw: pointer to the hw struct
5259 * @seid: VSI seid
5260 * @bw_data: Buffer holding enabled TCs, relative TC BW limit/credits
5261 * @cmd_details: pointer to command details structure or NULL
5262 **/
5263enum i40e_status_code i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
5264			u16 seid,
5265			struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
5266			struct i40e_asq_cmd_details *cmd_details)
5267{
5268	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5269				    i40e_aqc_opc_configure_vsi_tc_bw,
5270				    cmd_details);
5271}
5272
5273/**
5274 * i40e_aq_config_switch_comp_ets_bw_limit - Config Switch comp BW Limit per TC
5275 * @hw: pointer to the hw struct
5276 * @seid: seid of the switching component
5277 * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
5278 * @cmd_details: pointer to command details structure or NULL
5279 **/
5280enum i40e_status_code i40e_aq_config_switch_comp_ets_bw_limit(
5281	struct i40e_hw *hw, u16 seid,
5282	struct i40e_aqc_configure_switching_comp_ets_bw_limit_data *bw_data,
5283	struct i40e_asq_cmd_details *cmd_details)
5284{
5285	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5286			    i40e_aqc_opc_configure_switching_comp_ets_bw_limit,
5287			    cmd_details);
5288}
5289
5290/**
5291 * i40e_aq_query_vsi_bw_config - Query VSI BW configuration
5292 * @hw: pointer to the hw struct
5293 * @seid: seid of the VSI
5294 * @bw_data: Buffer to hold VSI BW configuration
5295 * @cmd_details: pointer to command details structure or NULL
5296 **/
5297enum i40e_status_code i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
5298			u16 seid,
5299			struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
5300			struct i40e_asq_cmd_details *cmd_details)
5301{
5302	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5303				    i40e_aqc_opc_query_vsi_bw_config,
5304				    cmd_details);
5305}
5306
5307/**
5308 * i40e_aq_query_vsi_ets_sla_config - Query VSI BW configuration per TC
5309 * @hw: pointer to the hw struct
5310 * @seid: seid of the VSI
5311 * @bw_data: Buffer to hold VSI BW configuration per TC
5312 * @cmd_details: pointer to command details structure or NULL
5313 **/
5314enum i40e_status_code i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
5315			u16 seid,
5316			struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
5317			struct i40e_asq_cmd_details *cmd_details)
5318{
5319	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5320				    i40e_aqc_opc_query_vsi_ets_sla_config,
5321				    cmd_details);
5322}
5323
5324/**
5325 * i40e_aq_query_switch_comp_ets_config - Query Switch comp BW config per TC
5326 * @hw: pointer to the hw struct
5327 * @seid: seid of the switching component
5328 * @bw_data: Buffer to hold switching component's per TC BW config
5329 * @cmd_details: pointer to command details structure or NULL
5330 **/
5331enum i40e_status_code i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
5332		u16 seid,
5333		struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
5334		struct i40e_asq_cmd_details *cmd_details)
5335{
5336	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5337				   i40e_aqc_opc_query_switching_comp_ets_config,
5338				   cmd_details);
5339}
5340
5341/**
5342 * i40e_aq_query_port_ets_config - Query Physical Port ETS configuration
5343 * @hw: pointer to the hw struct
5344 * @seid: seid of the VSI or switching component connected to Physical Port
5345 * @bw_data: Buffer to hold current ETS configuration for the Physical Port
5346 * @cmd_details: pointer to command details structure or NULL
5347 **/
5348enum i40e_status_code i40e_aq_query_port_ets_config(struct i40e_hw *hw,
5349			u16 seid,
5350			struct i40e_aqc_query_port_ets_config_resp *bw_data,
5351			struct i40e_asq_cmd_details *cmd_details)
5352{
5353	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5354				    i40e_aqc_opc_query_port_ets_config,
5355				    cmd_details);
5356}
5357
5358/**
5359 * i40e_aq_query_switch_comp_bw_config - Query Switch comp BW configuration
5360 * @hw: pointer to the hw struct
5361 * @seid: seid of the switching component
5362 * @bw_data: Buffer to hold switching component's BW configuration
5363 * @cmd_details: pointer to command details structure or NULL
5364 **/
5365enum i40e_status_code i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
5366		u16 seid,
5367		struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
5368		struct i40e_asq_cmd_details *cmd_details)
5369{
5370	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
5371				    i40e_aqc_opc_query_switching_comp_bw_config,
5372				    cmd_details);
5373}
5374
5375/**
5376 * i40e_validate_filter_settings
5377 * @hw: pointer to the hardware structure
5378 * @settings: Filter control settings
5379 *
5380 * Check and validate the filter control settings passed.
5381 * The function checks for the valid filter/context sizes being
5382 * passed for FCoE and PE.
5383 *
5384 * Returns I40E_SUCCESS if the values passed are valid and within
5385 * range else returns an error.
5386 **/
5387static enum i40e_status_code i40e_validate_filter_settings(struct i40e_hw *hw,
5388				struct i40e_filter_control_settings *settings)
5389{
5390	u32 fcoe_cntx_size, fcoe_filt_size;
5391	u32 pe_cntx_size, pe_filt_size;
5392	u32 fcoe_fmax;
5393
5394	u32 val;
5395
5396	/* Validate FCoE settings passed */
5397	switch (settings->fcoe_filt_num) {
5398	case I40E_HASH_FILTER_SIZE_1K:
5399	case I40E_HASH_FILTER_SIZE_2K:
5400	case I40E_HASH_FILTER_SIZE_4K:
5401	case I40E_HASH_FILTER_SIZE_8K:
5402	case I40E_HASH_FILTER_SIZE_16K:
5403	case I40E_HASH_FILTER_SIZE_32K:
5404		fcoe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
5405		fcoe_filt_size <<= (u32)settings->fcoe_filt_num;
5406		break;
5407	default:
5408		return I40E_ERR_PARAM;
5409	}
5410
5411	switch (settings->fcoe_cntx_num) {
5412	case I40E_DMA_CNTX_SIZE_512:
5413	case I40E_DMA_CNTX_SIZE_1K:
5414	case I40E_DMA_CNTX_SIZE_2K:
5415	case I40E_DMA_CNTX_SIZE_4K:
5416		fcoe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
5417		fcoe_cntx_size <<= (u32)settings->fcoe_cntx_num;
5418		break;
5419	default:
5420		return I40E_ERR_PARAM;
5421	}
5422
5423	/* Validate PE settings passed */
5424	switch (settings->pe_filt_num) {
5425	case I40E_HASH_FILTER_SIZE_1K:
5426	case I40E_HASH_FILTER_SIZE_2K:
5427	case I40E_HASH_FILTER_SIZE_4K:
5428	case I40E_HASH_FILTER_SIZE_8K:
5429	case I40E_HASH_FILTER_SIZE_16K:
5430	case I40E_HASH_FILTER_SIZE_32K:
5431	case I40E_HASH_FILTER_SIZE_64K:
5432	case I40E_HASH_FILTER_SIZE_128K:
5433	case I40E_HASH_FILTER_SIZE_256K:
5434	case I40E_HASH_FILTER_SIZE_512K:
5435	case I40E_HASH_FILTER_SIZE_1M:
5436		pe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
5437		pe_filt_size <<= (u32)settings->pe_filt_num;
5438		break;
5439	default:
5440		return I40E_ERR_PARAM;
5441	}
5442
5443	switch (settings->pe_cntx_num) {
5444	case I40E_DMA_CNTX_SIZE_512:
5445	case I40E_DMA_CNTX_SIZE_1K:
5446	case I40E_DMA_CNTX_SIZE_2K:
5447	case I40E_DMA_CNTX_SIZE_4K:
5448	case I40E_DMA_CNTX_SIZE_8K:
5449	case I40E_DMA_CNTX_SIZE_16K:
5450	case I40E_DMA_CNTX_SIZE_32K:
5451	case I40E_DMA_CNTX_SIZE_64K:
5452	case I40E_DMA_CNTX_SIZE_128K:
5453	case I40E_DMA_CNTX_SIZE_256K:
5454		pe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
5455		pe_cntx_size <<= (u32)settings->pe_cntx_num;
5456		break;
5457	default:
5458		return I40E_ERR_PARAM;
5459	}
5460
5461	/* FCHSIZE + FCDSIZE should not be greater than PMFCOEFMAX */
5462	val = rd32(hw, I40E_GLHMC_FCOEFMAX);
5463	fcoe_fmax = (val & I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK)
5464		     >> I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT;
5465	if (fcoe_filt_size + fcoe_cntx_size >  fcoe_fmax)
5466		return I40E_ERR_INVALID_SIZE;
5467
5468	return I40E_SUCCESS;
5469}
5470
5471/**
5472 * i40e_set_filter_control
5473 * @hw: pointer to the hardware structure
5474 * @settings: Filter control settings
5475 *
5476 * Set the Queue Filters for PE/FCoE and enable filters required
5477 * for a single PF. It is expected that these settings are programmed
5478 * at the driver initialization time.
5479 **/
5480enum i40e_status_code i40e_set_filter_control(struct i40e_hw *hw,
5481				struct i40e_filter_control_settings *settings)
5482{
5483	enum i40e_status_code ret = I40E_SUCCESS;
5484	u32 hash_lut_size = 0;
5485	u32 val;
5486
5487	if (!settings)
5488		return I40E_ERR_PARAM;
5489
5490	/* Validate the input settings */
5491	ret = i40e_validate_filter_settings(hw, settings);
5492	if (ret)
5493		return ret;
5494
5495	/* Read the PF Queue Filter control register */
5496	val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
5497
5498	/* Program required PE hash buckets for the PF */
5499	val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
5500	val |= ((u32)settings->pe_filt_num << I40E_PFQF_CTL_0_PEHSIZE_SHIFT) &
5501		I40E_PFQF_CTL_0_PEHSIZE_MASK;
5502	/* Program required PE contexts for the PF */
5503	val &= ~I40E_PFQF_CTL_0_PEDSIZE_MASK;
5504	val |= ((u32)settings->pe_cntx_num << I40E_PFQF_CTL_0_PEDSIZE_SHIFT) &
5505		I40E_PFQF_CTL_0_PEDSIZE_MASK;
5506
5507	/* Program required FCoE hash buckets for the PF */
5508	val &= ~I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5509	val |= ((u32)settings->fcoe_filt_num <<
5510			I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT) &
5511		I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
5512	/* Program required FCoE DDP contexts for the PF */
5513	val &= ~I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5514	val |= ((u32)settings->fcoe_cntx_num <<
5515			I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT) &
5516		I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
5517
5518	/* Program Hash LUT size for the PF */
5519	val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5520	if (settings->hash_lut_size == I40E_HASH_LUT_SIZE_512)
5521		hash_lut_size = 1;
5522	val |= (hash_lut_size << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT) &
5523		I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
5524
5525	/* Enable FDIR, Ethertype and MACVLAN filters for PF and VFs */
5526	if (settings->enable_fdir)
5527		val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
5528	if (settings->enable_ethtype)
5529		val |= I40E_PFQF_CTL_0_ETYPE_ENA_MASK;
5530	if (settings->enable_macvlan)
5531		val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
5532
5533	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
5534
5535	return I40E_SUCCESS;
5536}
5537
5538/**
5539 * i40e_aq_add_rem_control_packet_filter - Add or Remove Control Packet Filter
5540 * @hw: pointer to the hw struct
5541 * @mac_addr: MAC address to use in the filter
5542 * @ethtype: Ethertype to use in the filter
5543 * @flags: Flags that needs to be applied to the filter
5544 * @vsi_seid: seid of the control VSI
5545 * @queue: VSI queue number to send the packet to
5546 * @is_add: Add control packet filter if True else remove
5547 * @stats: Structure to hold information on control filter counts
5548 * @cmd_details: pointer to command details structure or NULL
5549 *
5550 * This command will Add or Remove control packet filter for a control VSI.
5551 * In return it will update the total number of perfect filter count in
5552 * the stats member.
5553 **/
5554enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
5555				u8 *mac_addr, u16 ethtype, u16 flags,
5556				u16 vsi_seid, u16 queue, bool is_add,
5557				struct i40e_control_filter_stats *stats,
5558				struct i40e_asq_cmd_details *cmd_details)
5559{
5560	struct i40e_aq_desc desc;
5561	struct i40e_aqc_add_remove_control_packet_filter *cmd =
5562		(struct i40e_aqc_add_remove_control_packet_filter *)
5563		&desc.params.raw;
5564	struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
5565		(struct i40e_aqc_add_remove_control_packet_filter_completion *)
5566		&desc.params.raw;
5567	enum i40e_status_code status;
5568
5569	if (vsi_seid == 0)
5570		return I40E_ERR_PARAM;
5571
5572	if (is_add) {
5573		i40e_fill_default_direct_cmd_desc(&desc,
5574				i40e_aqc_opc_add_control_packet_filter);
5575		cmd->queue = CPU_TO_LE16(queue);
5576	} else {
5577		i40e_fill_default_direct_cmd_desc(&desc,
5578				i40e_aqc_opc_remove_control_packet_filter);
5579	}
5580
5581	if (mac_addr)
5582		i40e_memcpy(cmd->mac, mac_addr, ETH_ALEN,
5583			    I40E_NONDMA_TO_NONDMA);
5584
5585	cmd->etype = CPU_TO_LE16(ethtype);
5586	cmd->flags = CPU_TO_LE16(flags);
5587	cmd->seid = CPU_TO_LE16(vsi_seid);
5588
5589	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5590
5591	if (!status && stats) {
5592		stats->mac_etype_used = LE16_TO_CPU(resp->mac_etype_used);
5593		stats->etype_used = LE16_TO_CPU(resp->etype_used);
5594		stats->mac_etype_free = LE16_TO_CPU(resp->mac_etype_free);
5595		stats->etype_free = LE16_TO_CPU(resp->etype_free);
5596	}
5597
5598	return status;
5599}
5600
5601/**
5602 * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
5603 * @hw: pointer to the hw struct
5604 * @seid: VSI seid to add ethertype filter from
5605 **/
5606void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
5607						    u16 seid)
5608{
5609#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
5610	u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
5611		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
5612		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
5613	u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
5614	enum i40e_status_code status;
5615
5616	status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
5617						       seid, 0, TRUE, NULL,
5618						       NULL);
5619	if (status)
5620		DEBUGOUT("Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
5621}
5622
5623/**
5624 * i40e_fix_up_geneve_vni - adjust Geneve VNI for HW issue
5625 * @filters: list of cloud filters
5626 * @filter_count: length of list
5627 *
5628 * There's an issue in the device where the Geneve VNI layout needs
5629 * to be shifted 1 byte over from the VxLAN VNI
5630 **/
5631static void i40e_fix_up_geneve_vni(
5632	struct i40e_aqc_cloud_filters_element_data *filters,
5633	u8 filter_count)
5634{
5635	struct i40e_aqc_cloud_filters_element_data *f = filters;
5636	int i;
5637
5638	for (i = 0; i < filter_count; i++) {
5639		u16 tnl_type;
5640		u32 ti;
5641
5642		tnl_type = (LE16_TO_CPU(f[i].flags) &
5643			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5644			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5645		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5646			ti = LE32_TO_CPU(f[i].tenant_id);
5647			f[i].tenant_id = CPU_TO_LE32(ti << 8);
5648		}
5649	}
5650}
5651
5652/**
5653 * i40e_aq_add_cloud_filters
5654 * @hw: pointer to the hardware structure
5655 * @seid: VSI seid to add cloud filters from
5656 * @filters: Buffer which contains the filters to be added
5657 * @filter_count: number of filters contained in the buffer
5658 *
5659 * Set the cloud filters for a given VSI.  The contents of the
5660 * i40e_aqc_cloud_filters_element_data are filled
5661 * in by the caller of the function.
5662 *
5663 **/
5664enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
5665	u16 seid,
5666	struct i40e_aqc_cloud_filters_element_data *filters,
5667	u8 filter_count)
5668{
5669	struct i40e_aq_desc desc;
5670	struct i40e_aqc_add_remove_cloud_filters *cmd =
5671	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5672	enum i40e_status_code status;
5673	u16 buff_len;
5674
5675	i40e_fill_default_direct_cmd_desc(&desc,
5676					  i40e_aqc_opc_add_cloud_filters);
5677
5678	buff_len = filter_count * sizeof(*filters);
5679	desc.datalen = CPU_TO_LE16(buff_len);
5680	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5681	cmd->num_filters = filter_count;
5682	cmd->seid = CPU_TO_LE16(seid);
5683
5684	i40e_fix_up_geneve_vni(filters, filter_count);
5685
5686	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5687
5688	return status;
5689}
5690
5691/**
5692 * i40e_aq_add_cloud_filters_bb
5693 * @hw: pointer to the hardware structure
5694 * @seid: VSI seid to add cloud filters from
5695 * @filters: Buffer which contains the filters in big buffer to be added
5696 * @filter_count: number of filters contained in the buffer
5697 *
5698 * Set the cloud filters for a given VSI.  The contents of the
5699 * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5700 * the function.
5701 *
5702 **/
5703enum i40e_status_code
5704i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5705			     struct i40e_aqc_cloud_filters_element_bb *filters,
5706			     u8 filter_count)
5707{
5708	struct i40e_aq_desc desc;
5709	struct i40e_aqc_add_remove_cloud_filters *cmd =
5710	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5711	enum i40e_status_code status;
5712	u16 buff_len;
5713	int i;
5714
5715	i40e_fill_default_direct_cmd_desc(&desc,
5716					  i40e_aqc_opc_add_cloud_filters);
5717
5718	buff_len = filter_count * sizeof(*filters);
5719	desc.datalen = CPU_TO_LE16(buff_len);
5720	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5721	cmd->num_filters = filter_count;
5722	cmd->seid = CPU_TO_LE16(seid);
5723	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5724
5725	for (i = 0; i < filter_count; i++) {
5726		u16 tnl_type;
5727		u32 ti;
5728
5729		tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5730			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5731			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5732
5733		/* Due to hardware eccentricities, the VNI for Geneve is shifted
5734		 * one more byte further than normally used for Tenant ID in
5735		 * other tunnel types.
5736		 */
5737		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5738			ti = LE32_TO_CPU(filters[i].element.tenant_id);
5739			filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5740		}
5741	}
5742
5743	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5744
5745	return status;
5746}
5747
5748/**
5749 * i40e_aq_rem_cloud_filters
5750 * @hw: pointer to the hardware structure
5751 * @seid: VSI seid to remove cloud filters from
5752 * @filters: Buffer which contains the filters to be removed
5753 * @filter_count: number of filters contained in the buffer
5754 *
5755 * Remove the cloud filters for a given VSI.  The contents of the
5756 * i40e_aqc_cloud_filters_element_data are filled in by the caller
5757 * of the function.
5758 *
5759 **/
5760enum i40e_status_code
5761i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
5762			  struct i40e_aqc_cloud_filters_element_data *filters,
5763			  u8 filter_count)
5764{
5765	struct i40e_aq_desc desc;
5766	struct i40e_aqc_add_remove_cloud_filters *cmd =
5767	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5768	enum i40e_status_code status;
5769	u16 buff_len;
5770
5771	i40e_fill_default_direct_cmd_desc(&desc,
5772					  i40e_aqc_opc_remove_cloud_filters);
5773
5774	buff_len = filter_count * sizeof(*filters);
5775	desc.datalen = CPU_TO_LE16(buff_len);
5776	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5777	cmd->num_filters = filter_count;
5778	cmd->seid = CPU_TO_LE16(seid);
5779
5780	i40e_fix_up_geneve_vni(filters, filter_count);
5781
5782	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5783
5784	return status;
5785}
5786
5787/**
5788 * i40e_aq_rem_cloud_filters_bb
5789 * @hw: pointer to the hardware structure
5790 * @seid: VSI seid to remove cloud filters from
5791 * @filters: Buffer which contains the filters in big buffer to be removed
5792 * @filter_count: number of filters contained in the buffer
5793 *
5794 * Remove the big buffer cloud filters for a given VSI.  The contents of the
5795 * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5796 * function.
5797 *
5798 **/
5799enum i40e_status_code
5800i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5801			     struct i40e_aqc_cloud_filters_element_bb *filters,
5802			     u8 filter_count)
5803{
5804	struct i40e_aq_desc desc;
5805	struct i40e_aqc_add_remove_cloud_filters *cmd =
5806	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5807	enum i40e_status_code status;
5808	u16 buff_len;
5809	int i;
5810
5811	i40e_fill_default_direct_cmd_desc(&desc,
5812					  i40e_aqc_opc_remove_cloud_filters);
5813
5814	buff_len = filter_count * sizeof(*filters);
5815	desc.datalen = CPU_TO_LE16(buff_len);
5816	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5817	cmd->num_filters = filter_count;
5818	cmd->seid = CPU_TO_LE16(seid);
5819	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5820
5821	for (i = 0; i < filter_count; i++) {
5822		u16 tnl_type;
5823		u32 ti;
5824
5825		tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5826			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5827			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5828
5829		/* Due to hardware eccentricities, the VNI for Geneve is shifted
5830		 * one more byte further than normally used for Tenant ID in
5831		 * other tunnel types.
5832		 */
5833		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5834			ti = LE32_TO_CPU(filters[i].element.tenant_id);
5835			filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5836		}
5837	}
5838
5839	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5840
5841	return status;
5842}
5843
5844/**
5845 * i40e_aq_replace_cloud_filters - Replace cloud filter command
5846 * @hw: pointer to the hw struct
5847 * @filters: pointer to the i40e_aqc_replace_cloud_filter_cmd struct
5848 * @cmd_buf: pointer to the i40e_aqc_replace_cloud_filter_cmd_buf struct
5849 *
5850 **/
5851enum
5852i40e_status_code i40e_aq_replace_cloud_filters(struct i40e_hw *hw,
5853	struct i40e_aqc_replace_cloud_filters_cmd *filters,
5854	struct i40e_aqc_replace_cloud_filters_cmd_buf *cmd_buf)
5855{
5856	struct i40e_aq_desc desc;
5857	struct i40e_aqc_replace_cloud_filters_cmd *cmd =
5858		(struct i40e_aqc_replace_cloud_filters_cmd *)&desc.params.raw;
5859	enum i40e_status_code status = I40E_SUCCESS;
5860	int i = 0;
5861
5862	/* X722 doesn't support this command */
5863	if (hw->mac.type == I40E_MAC_X722)
5864		return I40E_ERR_DEVICE_NOT_SUPPORTED;
5865
5866	/* need FW version greater than 6.00 */
5867	if (hw->aq.fw_maj_ver < 6)
5868		return I40E_NOT_SUPPORTED;
5869
5870	i40e_fill_default_direct_cmd_desc(&desc,
5871					  i40e_aqc_opc_replace_cloud_filters);
5872
5873	desc.datalen = CPU_TO_LE16(32);
5874	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5875	cmd->old_filter_type = filters->old_filter_type;
5876	cmd->new_filter_type = filters->new_filter_type;
5877	cmd->valid_flags = filters->valid_flags;
5878	cmd->tr_bit = filters->tr_bit;
5879	cmd->tr_bit2 = filters->tr_bit2;
5880
5881	status = i40e_asq_send_command(hw, &desc, cmd_buf,
5882		sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf),  NULL);
5883
5884	/* for get cloud filters command */
5885	for (i = 0; i < 32; i += 4) {
5886		cmd_buf->filters[i / 4].filter_type = cmd_buf->data[i];
5887		cmd_buf->filters[i / 4].input[0] = cmd_buf->data[i + 1];
5888		cmd_buf->filters[i / 4].input[1] = cmd_buf->data[i + 2];
5889		cmd_buf->filters[i / 4].input[2] = cmd_buf->data[i + 3];
5890	}
5891
5892	return status;
5893}
5894
5895
5896/**
5897 * i40e_aq_alternate_write
5898 * @hw: pointer to the hardware structure
5899 * @reg_addr0: address of first dword to be read
5900 * @reg_val0: value to be written under 'reg_addr0'
5901 * @reg_addr1: address of second dword to be read
5902 * @reg_val1: value to be written under 'reg_addr1'
5903 *
5904 * Write one or two dwords to alternate structure. Fields are indicated
5905 * by 'reg_addr0' and 'reg_addr1' register numbers.
5906 *
5907 **/
5908enum i40e_status_code i40e_aq_alternate_write(struct i40e_hw *hw,
5909				u32 reg_addr0, u32 reg_val0,
5910				u32 reg_addr1, u32 reg_val1)
5911{
5912	struct i40e_aq_desc desc;
5913	struct i40e_aqc_alternate_write *cmd_resp =
5914		(struct i40e_aqc_alternate_write *)&desc.params.raw;
5915	enum i40e_status_code status;
5916
5917	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_write);
5918	cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
5919	cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
5920	cmd_resp->data0 = CPU_TO_LE32(reg_val0);
5921	cmd_resp->data1 = CPU_TO_LE32(reg_val1);
5922
5923	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5924
5925	return status;
5926}
5927
5928/**
5929 * i40e_aq_alternate_write_indirect
5930 * @hw: pointer to the hardware structure
5931 * @addr: address of a first register to be modified
5932 * @dw_count: number of alternate structure fields to write
5933 * @buffer: pointer to the command buffer
5934 *
5935 * Write 'dw_count' dwords from 'buffer' to alternate structure
5936 * starting at 'addr'.
5937 *
5938 **/
5939enum i40e_status_code i40e_aq_alternate_write_indirect(struct i40e_hw *hw,
5940				u32 addr, u32 dw_count, void *buffer)
5941{
5942	struct i40e_aq_desc desc;
5943	struct i40e_aqc_alternate_ind_write *cmd_resp =
5944		(struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
5945	enum i40e_status_code status;
5946
5947	if (buffer == NULL)
5948		return I40E_ERR_PARAM;
5949
5950	/* Indirect command */
5951	i40e_fill_default_direct_cmd_desc(&desc,
5952					 i40e_aqc_opc_alternate_write_indirect);
5953
5954	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
5955	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
5956	if (dw_count > (I40E_AQ_LARGE_BUF/4))
5957		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
5958
5959	cmd_resp->address = CPU_TO_LE32(addr);
5960	cmd_resp->length = CPU_TO_LE32(dw_count);
5961
5962	status = i40e_asq_send_command(hw, &desc, buffer,
5963				       I40E_LO_DWORD(4*dw_count), NULL);
5964
5965	return status;
5966}
5967
5968/**
5969 * i40e_aq_alternate_read
5970 * @hw: pointer to the hardware structure
5971 * @reg_addr0: address of first dword to be read
5972 * @reg_val0: pointer for data read from 'reg_addr0'
5973 * @reg_addr1: address of second dword to be read
5974 * @reg_val1: pointer for data read from 'reg_addr1'
5975 *
5976 * Read one or two dwords from alternate structure. Fields are indicated
5977 * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
5978 * is not passed then only register at 'reg_addr0' is read.
5979 *
5980 **/
5981enum i40e_status_code i40e_aq_alternate_read(struct i40e_hw *hw,
5982				u32 reg_addr0, u32 *reg_val0,
5983				u32 reg_addr1, u32 *reg_val1)
5984{
5985	struct i40e_aq_desc desc;
5986	struct i40e_aqc_alternate_write *cmd_resp =
5987		(struct i40e_aqc_alternate_write *)&desc.params.raw;
5988	enum i40e_status_code status;
5989
5990	if (reg_val0 == NULL)
5991		return I40E_ERR_PARAM;
5992
5993	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
5994	cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
5995	cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
5996
5997	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
5998
5999	if (status == I40E_SUCCESS) {
6000		*reg_val0 = LE32_TO_CPU(cmd_resp->data0);
6001
6002		if (reg_val1 != NULL)
6003			*reg_val1 = LE32_TO_CPU(cmd_resp->data1);
6004	}
6005
6006	return status;
6007}
6008
6009/**
6010 * i40e_aq_alternate_read_indirect
6011 * @hw: pointer to the hardware structure
6012 * @addr: address of the alternate structure field
6013 * @dw_count: number of alternate structure fields to read
6014 * @buffer: pointer to the command buffer
6015 *
6016 * Read 'dw_count' dwords from alternate structure starting at 'addr' and
6017 * place them in 'buffer'. The buffer should be allocated by caller.
6018 *
6019 **/
6020enum i40e_status_code i40e_aq_alternate_read_indirect(struct i40e_hw *hw,
6021				u32 addr, u32 dw_count, void *buffer)
6022{
6023	struct i40e_aq_desc desc;
6024	struct i40e_aqc_alternate_ind_write *cmd_resp =
6025		(struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
6026	enum i40e_status_code status;
6027
6028	if (buffer == NULL)
6029		return I40E_ERR_PARAM;
6030
6031	/* Indirect command */
6032	i40e_fill_default_direct_cmd_desc(&desc,
6033		i40e_aqc_opc_alternate_read_indirect);
6034
6035	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
6036	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
6037	if (dw_count > (I40E_AQ_LARGE_BUF/4))
6038		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6039
6040	cmd_resp->address = CPU_TO_LE32(addr);
6041	cmd_resp->length = CPU_TO_LE32(dw_count);
6042
6043	status = i40e_asq_send_command(hw, &desc, buffer,
6044				       I40E_LO_DWORD(4*dw_count), NULL);
6045
6046	return status;
6047}
6048
6049/**
6050 *  i40e_aq_alternate_clear
6051 *  @hw: pointer to the HW structure.
6052 *
6053 *  Clear the alternate structures of the port from which the function
6054 *  is called.
6055 *
6056 **/
6057enum i40e_status_code i40e_aq_alternate_clear(struct i40e_hw *hw)
6058{
6059	struct i40e_aq_desc desc;
6060	enum i40e_status_code status;
6061
6062	i40e_fill_default_direct_cmd_desc(&desc,
6063					  i40e_aqc_opc_alternate_clear_port);
6064
6065	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6066
6067	return status;
6068}
6069
6070/**
6071 *  i40e_aq_alternate_write_done
6072 *  @hw: pointer to the HW structure.
6073 *  @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS
6074 *  @reset_needed: indicates the SW should trigger GLOBAL reset
6075 *
6076 *  Indicates to the FW that alternate structures have been changed.
6077 *
6078 **/
6079enum i40e_status_code i40e_aq_alternate_write_done(struct i40e_hw *hw,
6080		u8 bios_mode, bool *reset_needed)
6081{
6082	struct i40e_aq_desc desc;
6083	struct i40e_aqc_alternate_write_done *cmd =
6084		(struct i40e_aqc_alternate_write_done *)&desc.params.raw;
6085	enum i40e_status_code status;
6086
6087	if (reset_needed == NULL)
6088		return I40E_ERR_PARAM;
6089
6090	i40e_fill_default_direct_cmd_desc(&desc,
6091					  i40e_aqc_opc_alternate_write_done);
6092
6093	cmd->cmd_flags = CPU_TO_LE16(bios_mode);
6094
6095	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6096	if (!status && reset_needed)
6097		*reset_needed = ((LE16_TO_CPU(cmd->cmd_flags) &
6098				 I40E_AQ_ALTERNATE_RESET_NEEDED) != 0);
6099
6100	return status;
6101}
6102
6103/**
6104 *  i40e_aq_set_oem_mode
6105 *  @hw: pointer to the HW structure.
6106 *  @oem_mode: the OEM mode to be used
6107 *
6108 *  Sets the device to a specific operating mode. Currently the only supported
6109 *  mode is no_clp, which causes FW to refrain from using Alternate RAM.
6110 *
6111 **/
6112enum i40e_status_code i40e_aq_set_oem_mode(struct i40e_hw *hw,
6113		u8 oem_mode)
6114{
6115	struct i40e_aq_desc desc;
6116	struct i40e_aqc_alternate_write_done *cmd =
6117		(struct i40e_aqc_alternate_write_done *)&desc.params.raw;
6118	enum i40e_status_code status;
6119
6120	i40e_fill_default_direct_cmd_desc(&desc,
6121					  i40e_aqc_opc_alternate_set_mode);
6122
6123	cmd->cmd_flags = CPU_TO_LE16(oem_mode);
6124
6125	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6126
6127	return status;
6128}
6129
6130/**
6131 * i40e_aq_resume_port_tx
6132 * @hw: pointer to the hardware structure
6133 * @cmd_details: pointer to command details structure or NULL
6134 *
6135 * Resume port's Tx traffic
6136 **/
6137enum i40e_status_code i40e_aq_resume_port_tx(struct i40e_hw *hw,
6138				struct i40e_asq_cmd_details *cmd_details)
6139{
6140	struct i40e_aq_desc desc;
6141	enum i40e_status_code status;
6142
6143	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
6144
6145	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
6146
6147	return status;
6148}
6149
6150/**
6151 * i40e_set_pci_config_data - store PCI bus info
6152 * @hw: pointer to hardware structure
6153 * @link_status: the link status word from PCI config space
6154 *
6155 * Stores the PCI bus info (speed, width, type) within the i40e_hw structure
6156 **/
6157void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
6158{
6159	hw->bus.type = i40e_bus_type_pci_express;
6160
6161	switch (link_status & I40E_PCI_LINK_WIDTH) {
6162	case I40E_PCI_LINK_WIDTH_1:
6163		hw->bus.width = i40e_bus_width_pcie_x1;
6164		break;
6165	case I40E_PCI_LINK_WIDTH_2:
6166		hw->bus.width = i40e_bus_width_pcie_x2;
6167		break;
6168	case I40E_PCI_LINK_WIDTH_4:
6169		hw->bus.width = i40e_bus_width_pcie_x4;
6170		break;
6171	case I40E_PCI_LINK_WIDTH_8:
6172		hw->bus.width = i40e_bus_width_pcie_x8;
6173		break;
6174	default:
6175		hw->bus.width = i40e_bus_width_unknown;
6176		break;
6177	}
6178
6179	switch (link_status & I40E_PCI_LINK_SPEED) {
6180	case I40E_PCI_LINK_SPEED_2500:
6181		hw->bus.speed = i40e_bus_speed_2500;
6182		break;
6183	case I40E_PCI_LINK_SPEED_5000:
6184		hw->bus.speed = i40e_bus_speed_5000;
6185		break;
6186	case I40E_PCI_LINK_SPEED_8000:
6187		hw->bus.speed = i40e_bus_speed_8000;
6188		break;
6189	default:
6190		hw->bus.speed = i40e_bus_speed_unknown;
6191		break;
6192	}
6193}
6194
6195/**
6196 * i40e_aq_debug_dump
6197 * @hw: pointer to the hardware structure
6198 * @cluster_id: specific cluster to dump
6199 * @table_id: table id within cluster
6200 * @start_index: index of line in the block to read
6201 * @buff_size: dump buffer size
6202 * @buff: dump buffer
6203 * @ret_buff_size: actual buffer size returned
6204 * @ret_next_table: next block to read
6205 * @ret_next_index: next index to read
6206 * @cmd_details: pointer to command details structure or NULL
6207 *
6208 * Dump internal FW/HW data for debug purposes.
6209 *
6210 **/
6211enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
6212				u8 table_id, u32 start_index, u16 buff_size,
6213				void *buff, u16 *ret_buff_size,
6214				u8 *ret_next_table, u32 *ret_next_index,
6215				struct i40e_asq_cmd_details *cmd_details)
6216{
6217	struct i40e_aq_desc desc;
6218	struct i40e_aqc_debug_dump_internals *cmd =
6219		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6220	struct i40e_aqc_debug_dump_internals *resp =
6221		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6222	enum i40e_status_code status;
6223
6224	if (buff_size == 0 || !buff)
6225		return I40E_ERR_PARAM;
6226
6227	i40e_fill_default_direct_cmd_desc(&desc,
6228					  i40e_aqc_opc_debug_dump_internals);
6229	/* Indirect Command */
6230	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6231	if (buff_size > I40E_AQ_LARGE_BUF)
6232		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6233
6234	cmd->cluster_id = cluster_id;
6235	cmd->table_id = table_id;
6236	cmd->idx = CPU_TO_LE32(start_index);
6237
6238	desc.datalen = CPU_TO_LE16(buff_size);
6239
6240	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
6241	if (!status) {
6242		if (ret_buff_size != NULL)
6243			*ret_buff_size = LE16_TO_CPU(desc.datalen);
6244		if (ret_next_table != NULL)
6245			*ret_next_table = resp->table_id;
6246		if (ret_next_index != NULL)
6247			*ret_next_index = LE32_TO_CPU(resp->idx);
6248	}
6249
6250	return status;
6251}
6252
6253
6254/**
6255 * i40e_enable_eee
6256 * @hw: pointer to the hardware structure
6257 * @enable: state of Energy Efficient Ethernet mode to be set
6258 *
6259 * Enables or disables Energy Efficient Ethernet (EEE) mode
6260 * accordingly to @enable parameter.
6261 **/
6262enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable)
6263{
6264	struct i40e_aq_get_phy_abilities_resp abilities;
6265	struct i40e_aq_set_phy_config config;
6266	enum i40e_status_code status;
6267	__le16 eee_capability;
6268
6269	/* Get initial PHY capabilities */
6270	status = i40e_aq_get_phy_capabilities(hw, FALSE, TRUE, &abilities,
6271					      NULL);
6272	if (status)
6273		goto err;
6274
6275	/* Check whether NIC configuration is compatible with Energy Efficient
6276	 * Ethernet (EEE) mode.
6277	 */
6278	if (abilities.eee_capability == 0) {
6279		status = I40E_ERR_CONFIG;
6280		goto err;
6281	}
6282
6283	/* Cache initial EEE capability */
6284	eee_capability = abilities.eee_capability;
6285
6286	/* Get current configuration */
6287	status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
6288					      NULL);
6289	if (status)
6290		goto err;
6291
6292	/* Cache current configuration */
6293	config.phy_type = abilities.phy_type;
6294	config.phy_type_ext = abilities.phy_type_ext;
6295	config.link_speed = abilities.link_speed;
6296	config.abilities = abilities.abilities |
6297			   I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
6298	config.eeer = abilities.eeer_val;
6299	config.low_power_ctrl = abilities.d3_lpan;
6300	config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
6301			    I40E_AQ_PHY_FEC_CONFIG_MASK;
6302
6303	/* Set desired EEE state */
6304	if (enable) {
6305		config.eee_capability = eee_capability;
6306		config.eeer |= I40E_PRTPM_EEER_TX_LPI_EN_MASK;
6307	} else {
6308		config.eee_capability = 0;
6309		config.eeer &= ~I40E_PRTPM_EEER_TX_LPI_EN_MASK;
6310	}
6311
6312	/* Save modified config */
6313	status = i40e_aq_set_phy_config(hw, &config, NULL);
6314err:
6315	return status;
6316}
6317
6318/**
6319 * i40e_read_bw_from_alt_ram
6320 * @hw: pointer to the hardware structure
6321 * @max_bw: pointer for max_bw read
6322 * @min_bw: pointer for min_bw read
6323 * @min_valid: pointer for bool that is TRUE if min_bw is a valid value
6324 * @max_valid: pointer for bool that is TRUE if max_bw is a valid value
6325 *
6326 * Read bw from the alternate ram for the given pf
6327 **/
6328enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
6329					u32 *max_bw, u32 *min_bw,
6330					bool *min_valid, bool *max_valid)
6331{
6332	enum i40e_status_code status;
6333	u32 max_bw_addr, min_bw_addr;
6334
6335	/* Calculate the address of the min/max bw registers */
6336	max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
6337		      I40E_ALT_STRUCT_MAX_BW_OFFSET +
6338		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
6339	min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
6340		      I40E_ALT_STRUCT_MIN_BW_OFFSET +
6341		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
6342
6343	/* Read the bandwidths from alt ram */
6344	status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
6345					min_bw_addr, min_bw);
6346
6347	if (*min_bw & I40E_ALT_BW_VALID_MASK)
6348		*min_valid = TRUE;
6349	else
6350		*min_valid = FALSE;
6351
6352	if (*max_bw & I40E_ALT_BW_VALID_MASK)
6353		*max_valid = TRUE;
6354	else
6355		*max_valid = FALSE;
6356
6357	return status;
6358}
6359
6360/**
6361 * i40e_aq_configure_partition_bw
6362 * @hw: pointer to the hardware structure
6363 * @bw_data: Buffer holding valid pfs and bw limits
6364 * @cmd_details: pointer to command details
6365 *
6366 * Configure partitions guaranteed/max bw
6367 **/
6368enum i40e_status_code i40e_aq_configure_partition_bw(struct i40e_hw *hw,
6369			struct i40e_aqc_configure_partition_bw_data *bw_data,
6370			struct i40e_asq_cmd_details *cmd_details)
6371{
6372	enum i40e_status_code status;
6373	struct i40e_aq_desc desc;
6374	u16 bwd_size = sizeof(*bw_data);
6375
6376	i40e_fill_default_direct_cmd_desc(&desc,
6377				i40e_aqc_opc_configure_partition_bw);
6378
6379	/* Indirect command */
6380	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6381	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
6382
6383	desc.datalen = CPU_TO_LE16(bwd_size);
6384
6385	status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size, cmd_details);
6386
6387	return status;
6388}
6389
6390/**
6391 * i40e_read_phy_register_clause22
6392 * @hw: pointer to the HW structure
6393 * @reg: register address in the page
6394 * @phy_addr: PHY address on MDIO interface
6395 * @value: PHY register value
6396 *
6397 * Reads specified PHY register value
6398 **/
6399enum i40e_status_code i40e_read_phy_register_clause22(struct i40e_hw *hw,
6400					u16 reg, u8 phy_addr, u16 *value)
6401{
6402	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6403	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6404	u32 command = 0;
6405	u16 retry = 1000;
6406
6407	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6408		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6409		  (I40E_MDIO_CLAUSE22_OPCODE_READ_MASK) |
6410		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6411		  (I40E_GLGEN_MSCA_MDICMD_MASK);
6412	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6413	do {
6414		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6415		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6416			status = I40E_SUCCESS;
6417			break;
6418		}
6419		i40e_usec_delay(10);
6420		retry--;
6421	} while (retry);
6422
6423	if (status) {
6424		i40e_debug(hw, I40E_DEBUG_PHY,
6425			   "PHY: Can't write command to external PHY.\n");
6426	} else {
6427		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6428		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6429			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6430	}
6431
6432	return status;
6433}
6434
6435/**
6436 * i40e_write_phy_register_clause22
6437 * @hw: pointer to the HW structure
6438 * @reg: register address in the page
6439 * @phy_addr: PHY address on MDIO interface
6440 * @value: PHY register value
6441 *
6442 * Writes specified PHY register value
6443 **/
6444enum i40e_status_code i40e_write_phy_register_clause22(struct i40e_hw *hw,
6445					u16 reg, u8 phy_addr, u16 value)
6446{
6447	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6448	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6449	u32 command  = 0;
6450	u16 retry = 1000;
6451
6452	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6453	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6454
6455	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6456		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6457		  (I40E_MDIO_CLAUSE22_OPCODE_WRITE_MASK) |
6458		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6459		  (I40E_GLGEN_MSCA_MDICMD_MASK);
6460
6461	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6462	do {
6463		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6464		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6465			status = I40E_SUCCESS;
6466			break;
6467		}
6468		i40e_usec_delay(10);
6469		retry--;
6470	} while (retry);
6471
6472	return status;
6473}
6474
6475/**
6476 * i40e_read_phy_register_clause45
6477 * @hw: pointer to the HW structure
6478 * @page: registers page number
6479 * @reg: register address in the page
6480 * @phy_addr: PHY address on MDIO interface
6481 * @value: PHY register value
6482 *
6483 * Reads specified PHY register value
6484 **/
6485enum i40e_status_code i40e_read_phy_register_clause45(struct i40e_hw *hw,
6486				u8 page, u16 reg, u8 phy_addr, u16 *value)
6487{
6488	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6489	u32 command  = 0;
6490	u16 retry = 1000;
6491	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6492
6493	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6494		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6495		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6496		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6497		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6498		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6499		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6500	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6501	do {
6502		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6503		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6504			status = I40E_SUCCESS;
6505			break;
6506		}
6507		i40e_usec_delay(10);
6508		retry--;
6509	} while (retry);
6510
6511	if (status) {
6512		i40e_debug(hw, I40E_DEBUG_PHY,
6513			   "PHY: Can't write command to external PHY.\n");
6514		goto phy_read_end;
6515	}
6516
6517	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6518		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6519		  (I40E_MDIO_CLAUSE45_OPCODE_READ_MASK) |
6520		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6521		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6522		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6523	status = I40E_ERR_TIMEOUT;
6524	retry = 1000;
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		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6538		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6539			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6540	} else {
6541		i40e_debug(hw, I40E_DEBUG_PHY,
6542			   "PHY: Can't read register value from external PHY.\n");
6543	}
6544
6545phy_read_end:
6546	return status;
6547}
6548
6549/**
6550 * i40e_write_phy_register_clause45
6551 * @hw: pointer to the HW structure
6552 * @page: registers page number
6553 * @reg: register address in the page
6554 * @phy_addr: PHY address on MDIO interface
6555 * @value: PHY register value
6556 *
6557 * Writes value to specified PHY register
6558 **/
6559enum i40e_status_code i40e_write_phy_register_clause45(struct i40e_hw *hw,
6560				u8 page, u16 reg, u8 phy_addr, u16 value)
6561{
6562	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6563	u32 command  = 0;
6564	u16 retry = 1000;
6565	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6566
6567	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
6568		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6569		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6570		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6571		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6572		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6573		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6574	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6575	do {
6576		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6577		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6578			status = I40E_SUCCESS;
6579			break;
6580		}
6581		i40e_usec_delay(10);
6582		retry--;
6583	} while (retry);
6584	if (status) {
6585		i40e_debug(hw, I40E_DEBUG_PHY,
6586			   "PHY: Can't write command to external PHY.\n");
6587		goto phy_write_end;
6588	}
6589
6590	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6591	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6592
6593	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6594		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6595		  (I40E_MDIO_CLAUSE45_OPCODE_WRITE_MASK) |
6596		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
6597		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
6598		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
6599	status = I40E_ERR_TIMEOUT;
6600	retry = 1000;
6601	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6602	do {
6603		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6604		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6605			status = I40E_SUCCESS;
6606			break;
6607		}
6608		i40e_usec_delay(10);
6609		retry--;
6610	} while (retry);
6611
6612phy_write_end:
6613	return status;
6614}
6615
6616/**
6617 * i40e_write_phy_register
6618 * @hw: pointer to the HW structure
6619 * @page: registers page number
6620 * @reg: register address in the page
6621 * @phy_addr: PHY address on MDIO interface
6622 * @value: PHY register value
6623 *
6624 * Writes value to specified PHY register
6625 **/
6626enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
6627				u8 page, u16 reg, u8 phy_addr, u16 value)
6628{
6629	enum i40e_status_code status;
6630
6631	switch (hw->device_id) {
6632	case I40E_DEV_ID_1G_BASE_T_X722:
6633		status = i40e_write_phy_register_clause22(hw,
6634			reg, phy_addr, value);
6635		break;
6636	case I40E_DEV_ID_10G_BASE_T:
6637	case I40E_DEV_ID_10G_BASE_T4:
6638	case I40E_DEV_ID_10G_BASE_T_BC:
6639	case I40E_DEV_ID_5G_BASE_T_BC:
6640	case I40E_DEV_ID_10G_BASE_T_X722:
6641	case I40E_DEV_ID_25G_B:
6642	case I40E_DEV_ID_25G_SFP28:
6643		status = i40e_write_phy_register_clause45(hw,
6644			page, reg, phy_addr, value);
6645		break;
6646	default:
6647		status = I40E_ERR_UNKNOWN_PHY;
6648		break;
6649	}
6650
6651	return status;
6652}
6653
6654/**
6655 * i40e_read_phy_register
6656 * @hw: pointer to the HW structure
6657 * @page: registers page number
6658 * @reg: register address in the page
6659 * @phy_addr: PHY address on MDIO interface
6660 * @value: PHY register value
6661 *
6662 * Reads specified PHY register value
6663 **/
6664enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
6665				u8 page, u16 reg, u8 phy_addr, u16 *value)
6666{
6667	enum i40e_status_code status;
6668
6669	switch (hw->device_id) {
6670	case I40E_DEV_ID_1G_BASE_T_X722:
6671		status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
6672							 value);
6673		break;
6674	case I40E_DEV_ID_10G_BASE_T:
6675	case I40E_DEV_ID_10G_BASE_T4:
6676	case I40E_DEV_ID_10G_BASE_T_BC:
6677	case I40E_DEV_ID_5G_BASE_T_BC:
6678	case I40E_DEV_ID_10G_BASE_T_X722:
6679	case I40E_DEV_ID_25G_B:
6680	case I40E_DEV_ID_25G_SFP28:
6681		status = i40e_read_phy_register_clause45(hw, page, reg,
6682							 phy_addr, value);
6683		break;
6684	default:
6685		status = I40E_ERR_UNKNOWN_PHY;
6686		break;
6687	}
6688
6689	return status;
6690}
6691
6692/**
6693 * i40e_get_phy_address
6694 * @hw: pointer to the HW structure
6695 * @dev_num: PHY port num that address we want
6696 *
6697 * Gets PHY address for current port
6698 **/
6699u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
6700{
6701	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6702	u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
6703
6704	return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
6705}
6706
6707/**
6708 * i40e_blink_phy_led
6709 * @hw: pointer to the HW structure
6710 * @time: time how long led will blinks in secs
6711 * @interval: gap between LED on and off in msecs
6712 *
6713 * Blinks PHY link LED
6714 **/
6715enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
6716					      u32 time, u32 interval)
6717{
6718	enum i40e_status_code status = I40E_SUCCESS;
6719	u32 i;
6720	u16 led_ctl = 0;
6721	u16 gpio_led_port;
6722	u16 led_reg;
6723	u16 led_addr = I40E_PHY_LED_PROV_REG_1;
6724	u8 phy_addr = 0;
6725	u8 port_num;
6726
6727	i = rd32(hw, I40E_PFGEN_PORTNUM);
6728	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
6729	phy_addr = i40e_get_phy_address(hw, port_num);
6730
6731	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6732	     led_addr++) {
6733		status = i40e_read_phy_register_clause45(hw,
6734							 I40E_PHY_COM_REG_PAGE,
6735							 led_addr, phy_addr,
6736							 &led_reg);
6737		if (status)
6738			goto phy_blinking_end;
6739		led_ctl = led_reg;
6740		if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6741			led_reg = 0;
6742			status = i40e_write_phy_register_clause45(hw,
6743							 I40E_PHY_COM_REG_PAGE,
6744							 led_addr, phy_addr,
6745							 led_reg);
6746			if (status)
6747				goto phy_blinking_end;
6748			break;
6749		}
6750	}
6751
6752	if (time > 0 && interval > 0) {
6753		for (i = 0; i < time * 1000; i += interval) {
6754			status = i40e_read_phy_register_clause45(hw,
6755						I40E_PHY_COM_REG_PAGE,
6756						led_addr, phy_addr, &led_reg);
6757			if (status)
6758				goto restore_config;
6759			if (led_reg & I40E_PHY_LED_MANUAL_ON)
6760				led_reg = 0;
6761			else
6762				led_reg = I40E_PHY_LED_MANUAL_ON;
6763			status = i40e_write_phy_register_clause45(hw,
6764						I40E_PHY_COM_REG_PAGE,
6765						led_addr, phy_addr, led_reg);
6766			if (status)
6767				goto restore_config;
6768			i40e_msec_delay(interval);
6769		}
6770	}
6771
6772restore_config:
6773	status = i40e_write_phy_register_clause45(hw,
6774						  I40E_PHY_COM_REG_PAGE,
6775						  led_addr, phy_addr, led_ctl);
6776
6777phy_blinking_end:
6778	return status;
6779}
6780
6781/**
6782 * i40e_led_get_reg - read LED register
6783 * @hw: pointer to the HW structure
6784 * @led_addr: LED register address
6785 * @reg_val: read register value
6786 **/
6787enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
6788				       u32 *reg_val)
6789{
6790	enum i40e_status_code status;
6791	u8 phy_addr = 0;
6792
6793	*reg_val = 0;
6794	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6795		status = i40e_aq_get_phy_register(hw,
6796						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6797						I40E_PHY_COM_REG_PAGE, TRUE,
6798						I40E_PHY_LED_PROV_REG_1,
6799						reg_val, NULL);
6800	} else {
6801		phy_addr = i40e_get_phy_address(hw, hw->port);
6802		status = i40e_read_phy_register_clause45(hw,
6803							 I40E_PHY_COM_REG_PAGE,
6804							 led_addr, phy_addr,
6805							 (u16 *)reg_val);
6806	}
6807	return status;
6808}
6809
6810/**
6811 * i40e_led_set_reg - write LED register
6812 * @hw: pointer to the HW structure
6813 * @led_addr: LED register address
6814 * @reg_val: register value to write
6815 **/
6816enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
6817				       u32 reg_val)
6818{
6819	enum i40e_status_code status;
6820	u8 phy_addr = 0;
6821
6822	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6823		status = i40e_aq_set_phy_register(hw,
6824						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6825						I40E_PHY_COM_REG_PAGE, TRUE,
6826						I40E_PHY_LED_PROV_REG_1,
6827						reg_val, NULL);
6828	} else {
6829		phy_addr = i40e_get_phy_address(hw, hw->port);
6830		status = i40e_write_phy_register_clause45(hw,
6831							  I40E_PHY_COM_REG_PAGE,
6832							  led_addr, phy_addr,
6833							  (u16)reg_val);
6834	}
6835
6836	return status;
6837}
6838
6839/**
6840 * i40e_led_get_phy - return current on/off mode
6841 * @hw: pointer to the hw struct
6842 * @led_addr: address of led register to use
6843 * @val: original value of register to use
6844 *
6845 **/
6846enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
6847				       u16 *val)
6848{
6849	enum i40e_status_code status = I40E_SUCCESS;
6850	u16 gpio_led_port;
6851	u32 reg_val_aq;
6852	u16 temp_addr;
6853	u8 phy_addr = 0;
6854	u16 reg_val;
6855
6856	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6857		status = i40e_aq_get_phy_register(hw,
6858						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6859						I40E_PHY_COM_REG_PAGE, TRUE,
6860						I40E_PHY_LED_PROV_REG_1,
6861						&reg_val_aq, NULL);
6862		if (status == I40E_SUCCESS)
6863			*val = (u16)reg_val_aq;
6864		return status;
6865	}
6866	temp_addr = I40E_PHY_LED_PROV_REG_1;
6867	phy_addr = i40e_get_phy_address(hw, hw->port);
6868	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
6869	     temp_addr++) {
6870		status = i40e_read_phy_register_clause45(hw,
6871							 I40E_PHY_COM_REG_PAGE,
6872							 temp_addr, phy_addr,
6873							 &reg_val);
6874		if (status)
6875			return status;
6876		*val = reg_val;
6877		if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
6878			*led_addr = temp_addr;
6879			break;
6880		}
6881	}
6882	return status;
6883}
6884
6885/**
6886 * i40e_led_set_phy
6887 * @hw: pointer to the HW structure
6888 * @on: TRUE or FALSE
6889 * @led_addr: address of led register to use
6890 * @mode: original val plus bit for set or ignore
6891 *
6892 * Set led's on or off when controlled by the PHY
6893 *
6894 **/
6895enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on,
6896				       u16 led_addr, u32 mode)
6897{
6898	enum i40e_status_code status = I40E_SUCCESS;
6899	u32 led_ctl = 0;
6900	u32 led_reg = 0;
6901
6902	status = i40e_led_get_reg(hw, led_addr, &led_reg);
6903	if (status)
6904		return status;
6905	led_ctl = led_reg;
6906	if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
6907		led_reg = 0;
6908		status = i40e_led_set_reg(hw, led_addr, led_reg);
6909		if (status)
6910			return status;
6911	}
6912	status = i40e_led_get_reg(hw, led_addr, &led_reg);
6913	if (status)
6914		goto restore_config;
6915	if (on)
6916		led_reg = I40E_PHY_LED_MANUAL_ON;
6917	else
6918		led_reg = 0;
6919	status = i40e_led_set_reg(hw, led_addr, led_reg);
6920	if (status)
6921		goto restore_config;
6922	if (mode & I40E_PHY_LED_MODE_ORIG) {
6923		led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
6924		status = i40e_led_set_reg(hw, led_addr, led_ctl);
6925	}
6926	return status;
6927
6928restore_config:
6929	status = i40e_led_set_reg(hw, led_addr, led_ctl);
6930	return status;
6931}
6932
6933/**
6934 * i40e_get_phy_lpi_status - read LPI status from PHY or MAC register
6935 * @hw: pointer to the hw struct
6936 * @stat: pointer to structure with status of rx and tx lpi
6937 *
6938 * Read LPI state directly from external PHY register or from MAC
6939 * register, depending on device ID and current link speed.
6940 */
6941enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
6942					      struct i40e_hw_port_stats *stat)
6943{
6944	enum i40e_status_code ret = I40E_SUCCESS;
6945	u32 val;
6946
6947	stat->rx_lpi_status = 0;
6948	stat->tx_lpi_status = 0;
6949
6950	if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
6951	     hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
6952	    (hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB ||
6953	     hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB)) {
6954		ret = i40e_aq_get_phy_register(hw,
6955					       I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6956					       I40E_BCM_PHY_PCS_STATUS1_PAGE,
6957					       TRUE,
6958					       I40E_BCM_PHY_PCS_STATUS1_REG,
6959					       &val, NULL);
6960
6961		if (ret != I40E_SUCCESS)
6962			return ret;
6963
6964		stat->rx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_RX_LPI);
6965		stat->tx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_TX_LPI);
6966
6967		return ret;
6968	}
6969
6970	val = rd32(hw, I40E_PRTPM_EEE_STAT);
6971	stat->rx_lpi_status = (val & I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK) >>
6972			       I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT;
6973	stat->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >>
6974			       I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT;
6975
6976	return ret;
6977}
6978
6979/**
6980 * i40e_get_lpi_counters - read LPI counters from EEE statistics
6981 * @hw: pointer to the hw struct
6982 * @tx_counter: pointer to memory for TX LPI counter
6983 * @rx_counter: pointer to memory for RX LPI counter
6984 * @is_clear:   returns TRUE if counters are clear after read
6985 *
6986 * Read Low Power Idle (LPI) mode counters from Energy Efficient
6987 * Ethernet (EEE) statistics.
6988 **/
6989enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw,
6990					    u32 *tx_counter, u32 *rx_counter,
6991					    bool *is_clear)
6992{
6993	/* only X710-T*L requires special handling of counters
6994	 * for other devices we just read the MAC registers
6995	 */
6996	if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
6997	     hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
6998	     hw->phy.link_info.link_speed != I40E_LINK_SPEED_1GB) {
6999		enum i40e_status_code retval;
7000		u32 cmd_status;
7001
7002		*is_clear = FALSE;
7003		retval = i40e_aq_run_phy_activity(hw,
7004				I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7005				I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT,
7006				&cmd_status, tx_counter, rx_counter, NULL);
7007
7008		if (!retval && cmd_status != I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7009			retval = I40E_ERR_ADMIN_QUEUE_ERROR;
7010
7011		return retval;
7012	}
7013
7014	*is_clear = TRUE;
7015	*tx_counter = rd32(hw, I40E_PRTPM_TLPIC);
7016	*rx_counter = rd32(hw, I40E_PRTPM_RLPIC);
7017
7018	return I40E_SUCCESS;
7019}
7020
7021/**
7022 * i40e_get_lpi_duration - read LPI time duration from EEE statistics
7023 * @hw: pointer to the hw struct
7024 * @stat: pointer to structure with status of rx and tx lpi
7025 * @tx_duration: pointer to memory for TX LPI time duration
7026 * @rx_duration: pointer to memory for RX LPI time duration
7027 *
7028 * Read Low Power Idle (LPI) mode time duration from Energy Efficient
7029 * Ethernet (EEE) statistics.
7030 */
7031enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw,
7032					    struct i40e_hw_port_stats *stat,
7033					    u64 *tx_duration, u64 *rx_duration)
7034{
7035	u32 tx_time_dur, rx_time_dur;
7036	enum i40e_status_code retval;
7037	u32 cmd_status;
7038
7039	if (hw->device_id != I40E_DEV_ID_10G_BASE_T_BC &&
7040	    hw->device_id != I40E_DEV_ID_5G_BASE_T_BC)
7041		return I40E_ERR_NOT_IMPLEMENTED;
7042
7043	retval = i40e_aq_run_phy_activity
7044		(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7045		I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR,
7046		&cmd_status, &tx_time_dur, &rx_time_dur, NULL);
7047
7048	if (retval)
7049		return retval;
7050	if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
7051	    I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7052		return I40E_ERR_ADMIN_QUEUE_ERROR;
7053
7054	if (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB &&
7055	    !tx_time_dur && !rx_time_dur &&
7056	    stat->tx_lpi_status && stat->rx_lpi_status) {
7057		retval = i40e_aq_run_phy_activity
7058			(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
7059			I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR,
7060			&cmd_status,
7061			&tx_time_dur, &rx_time_dur, NULL);
7062
7063		if (retval)
7064			return retval;
7065		if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
7066		    I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
7067			return I40E_ERR_ADMIN_QUEUE_ERROR;
7068		tx_time_dur = 0;
7069		rx_time_dur = 0;
7070	}
7071
7072	*tx_duration = tx_time_dur;
7073	*rx_duration = rx_time_dur;
7074
7075	return retval;
7076}
7077
7078/**
7079 * i40e_lpi_stat_update - update LPI counters with values relative to offset
7080 * @hw: pointer to the hw struct
7081 * @offset_loaded: flag indicating need of writing current value to offset
7082 * @tx_offset: pointer to offset of TX LPI counter
7083 * @tx_stat: pointer to value of TX LPI counter
7084 * @rx_offset: pointer to offset of RX LPI counter
7085 * @rx_stat: pointer to value of RX LPI counter
7086 *
7087 * Update Low Power Idle (LPI) mode counters while having regard to passed
7088 * offsets.
7089 **/
7090enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw,
7091					   bool offset_loaded, u64 *tx_offset,
7092					   u64 *tx_stat, u64 *rx_offset,
7093					   u64 *rx_stat)
7094{
7095	enum i40e_status_code retval;
7096	u32 tx_counter, rx_counter;
7097	bool is_clear;
7098
7099	retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter, &is_clear);
7100	if (retval)
7101		goto err;
7102
7103	if (is_clear) {
7104		*tx_stat += tx_counter;
7105		*rx_stat += rx_counter;
7106	} else {
7107		if (!offset_loaded) {
7108			*tx_offset = tx_counter;
7109			*rx_offset = rx_counter;
7110		}
7111
7112		*tx_stat = (tx_counter >= *tx_offset) ?
7113			(u32)(tx_counter - *tx_offset) :
7114			(u32)((tx_counter + BIT_ULL(32)) - *tx_offset);
7115		*rx_stat = (rx_counter >= *rx_offset) ?
7116			(u32)(rx_counter - *rx_offset) :
7117			(u32)((rx_counter + BIT_ULL(32)) - *rx_offset);
7118	}
7119err:
7120	return retval;
7121}
7122
7123/**
7124 * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
7125 * @hw: pointer to the hw struct
7126 * @reg_addr: register address
7127 * @reg_val: ptr to register value
7128 * @cmd_details: pointer to command details structure or NULL
7129 *
7130 * Use the firmware to read the Rx control register,
7131 * especially useful if the Rx unit is under heavy pressure
7132 **/
7133enum i40e_status_code i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
7134				u32 reg_addr, u32 *reg_val,
7135				struct i40e_asq_cmd_details *cmd_details)
7136{
7137	struct i40e_aq_desc desc;
7138	struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
7139		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7140	enum i40e_status_code status;
7141
7142	if (reg_val == NULL)
7143		return I40E_ERR_PARAM;
7144
7145	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
7146
7147	cmd_resp->address = CPU_TO_LE32(reg_addr);
7148
7149	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7150
7151	if (status == I40E_SUCCESS)
7152		*reg_val = LE32_TO_CPU(cmd_resp->value);
7153
7154	return status;
7155}
7156
7157/**
7158 * i40e_read_rx_ctl - read from an Rx control register
7159 * @hw: pointer to the hw struct
7160 * @reg_addr: register address
7161 **/
7162u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
7163{
7164	enum i40e_status_code status = I40E_SUCCESS;
7165	bool use_register;
7166	int retry = 5;
7167	u32 val = 0;
7168
7169	use_register = (((hw->aq.api_maj_ver == 1) &&
7170			(hw->aq.api_min_ver < 5)) ||
7171			(hw->mac.type == I40E_MAC_X722));
7172	if (!use_register) {
7173do_retry:
7174		status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
7175		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7176			i40e_msec_delay(1);
7177			retry--;
7178			goto do_retry;
7179		}
7180	}
7181
7182	/* if the AQ access failed, try the old-fashioned way */
7183	if (status || use_register)
7184		val = rd32(hw, reg_addr);
7185
7186	return val;
7187}
7188
7189/**
7190 * i40e_aq_rx_ctl_write_register
7191 * @hw: pointer to the hw struct
7192 * @reg_addr: register address
7193 * @reg_val: register value
7194 * @cmd_details: pointer to command details structure or NULL
7195 *
7196 * Use the firmware to write to an Rx control register,
7197 * especially useful if the Rx unit is under heavy pressure
7198 **/
7199enum i40e_status_code i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
7200				u32 reg_addr, u32 reg_val,
7201				struct i40e_asq_cmd_details *cmd_details)
7202{
7203	struct i40e_aq_desc desc;
7204	struct i40e_aqc_rx_ctl_reg_read_write *cmd =
7205		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7206	enum i40e_status_code status;
7207
7208	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
7209
7210	cmd->address = CPU_TO_LE32(reg_addr);
7211	cmd->value = CPU_TO_LE32(reg_val);
7212
7213	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7214
7215	return status;
7216}
7217
7218/**
7219 * i40e_write_rx_ctl - write to an Rx control register
7220 * @hw: pointer to the hw struct
7221 * @reg_addr: register address
7222 * @reg_val: register value
7223 **/
7224void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
7225{
7226	enum i40e_status_code status = I40E_SUCCESS;
7227	bool use_register;
7228	int retry = 5;
7229
7230	use_register = (((hw->aq.api_maj_ver == 1) &&
7231			(hw->aq.api_min_ver < 5)) ||
7232			(hw->mac.type == I40E_MAC_X722));
7233	if (!use_register) {
7234do_retry:
7235		status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
7236						       reg_val, NULL);
7237		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7238			i40e_msec_delay(1);
7239			retry--;
7240			goto do_retry;
7241		}
7242	}
7243
7244	/* if the AQ access failed, try the old-fashioned way */
7245	if (status || use_register)
7246		wr32(hw, reg_addr, reg_val);
7247}
7248
7249/**
7250 * i40e_mdio_if_number_selection - MDIO I/F number selection
7251 * @hw: pointer to the hw struct
7252 * @set_mdio: use MDIO I/F number specified by mdio_num
7253 * @mdio_num: MDIO I/F number
7254 * @cmd: pointer to PHY Register command structure
7255 **/
7256static void
7257i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio, u8 mdio_num,
7258			      struct i40e_aqc_phy_register_access *cmd)
7259{
7260	if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) {
7261		if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED)
7262			cmd->cmd_flags |=
7263				I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER |
7264				((mdio_num <<
7265				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) &
7266				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK);
7267		else
7268			i40e_debug(hw, I40E_DEBUG_PHY,
7269				   "MDIO I/F number selection not supported by current FW version.\n");
7270	}
7271}
7272
7273/**
7274 * i40e_aq_set_phy_register_ext
7275 * @hw: pointer to the hw struct
7276 * @phy_select: select which phy should be accessed
7277 * @dev_addr: PHY device address
7278 * @page_change: enable auto page change
7279 * @set_mdio: use MDIO I/F number specified by mdio_num
7280 * @mdio_num: MDIO I/F number
7281 * @reg_addr: PHY register address
7282 * @reg_val: new register value
7283 * @cmd_details: pointer to command details structure or NULL
7284 *
7285 * Write the external PHY register.
7286 * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7287 * may use simple wrapper i40e_aq_set_phy_register.
7288 **/
7289enum i40e_status_code
7290i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
7291			     u8 phy_select, u8 dev_addr, bool page_change,
7292			     bool set_mdio, u8 mdio_num,
7293			     u32 reg_addr, u32 reg_val,
7294			     struct i40e_asq_cmd_details *cmd_details)
7295{
7296	struct i40e_aq_desc desc;
7297	struct i40e_aqc_phy_register_access *cmd =
7298		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
7299	enum i40e_status_code status;
7300
7301	i40e_fill_default_direct_cmd_desc(&desc,
7302					  i40e_aqc_opc_set_phy_register);
7303
7304	cmd->phy_interface = phy_select;
7305	cmd->dev_addres = dev_addr;
7306	cmd->reg_address = CPU_TO_LE32(reg_addr);
7307	cmd->reg_value = CPU_TO_LE32(reg_val);
7308
7309	if (!page_change)
7310		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7311
7312	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7313
7314	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7315
7316	return status;
7317}
7318
7319/**
7320 * i40e_aq_get_phy_register_ext
7321 * @hw: pointer to the hw struct
7322 * @phy_select: select which phy should be accessed
7323 * @dev_addr: PHY device address
7324 * @page_change: enable auto page change
7325 * @set_mdio: use MDIO I/F number specified by mdio_num
7326 * @mdio_num: MDIO I/F number
7327 * @reg_addr: PHY register address
7328 * @reg_val: read register value
7329 * @cmd_details: pointer to command details structure or NULL
7330 *
7331 * Read the external PHY register.
7332 * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7333 * may use simple wrapper i40e_aq_get_phy_register.
7334 **/
7335enum i40e_status_code
7336i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
7337			     u8 phy_select, u8 dev_addr, bool page_change,
7338			     bool set_mdio, u8 mdio_num,
7339			     u32 reg_addr, u32 *reg_val,
7340			     struct i40e_asq_cmd_details *cmd_details)
7341{
7342	struct i40e_aq_desc desc;
7343	struct i40e_aqc_phy_register_access *cmd =
7344		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
7345	enum i40e_status_code status;
7346
7347	i40e_fill_default_direct_cmd_desc(&desc,
7348					  i40e_aqc_opc_get_phy_register);
7349
7350	cmd->phy_interface = phy_select;
7351	cmd->dev_addres = dev_addr;
7352	cmd->reg_address = CPU_TO_LE32(reg_addr);
7353
7354	if (!page_change)
7355		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7356
7357	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7358
7359	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7360	if (!status)
7361		*reg_val = LE32_TO_CPU(cmd->reg_value);
7362
7363	return status;
7364}
7365
7366/**
7367 * i40e_aq_run_phy_activity
7368 * @hw: pointer to the hw struct
7369 * @activity_id: ID of DNL activity to run
7370 * @dnl_opcode: opcode passed to DNL script
7371 * @cmd_status: pointer to memory to write return value of DNL script
7372 * @data0: pointer to memory for first 4 bytes of data returned by DNL script
7373 * @data1: pointer to memory for last 4 bytes of data returned by DNL script
7374 * @cmd_details: pointer to command details structure or NULL
7375 *
7376 * Run DNL admin command.
7377 **/
7378enum i40e_status_code
7379i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 dnl_opcode,
7380			 u32 *cmd_status, u32 *data0, u32 *data1,
7381			 struct i40e_asq_cmd_details *cmd_details)
7382{
7383	struct i40e_aqc_run_phy_activity *cmd;
7384	enum i40e_status_code retval;
7385	struct i40e_aq_desc desc;
7386
7387	cmd = (struct i40e_aqc_run_phy_activity *)&desc.params.raw;
7388
7389	if (!cmd_status || !data0 || !data1) {
7390		retval = I40E_ERR_PARAM;
7391		goto err;
7392	}
7393
7394	i40e_fill_default_direct_cmd_desc(&desc,
7395					  i40e_aqc_opc_run_phy_activity);
7396
7397	cmd->activity_id = CPU_TO_LE16(activity_id);
7398	cmd->params.cmd.dnl_opcode = CPU_TO_LE32(dnl_opcode);
7399
7400	retval = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7401	if (retval)
7402		goto err;
7403
7404	*cmd_status = LE32_TO_CPU(cmd->params.resp.cmd_status);
7405	*data0 = LE32_TO_CPU(cmd->params.resp.data0);
7406	*data1 = LE32_TO_CPU(cmd->params.resp.data1);
7407err:
7408	return retval;
7409}
7410
7411
7412/**
7413 * i40e_aq_send_msg_to_pf
7414 * @hw: pointer to the hardware structure
7415 * @v_opcode: opcodes for VF-PF communication
7416 * @v_retval: return error code
7417 * @msg: pointer to the msg buffer
7418 * @msglen: msg length
7419 * @cmd_details: pointer to command details
7420 *
7421 * Send message to PF driver using admin queue. By default, this message
7422 * is sent asynchronously, i.e. i40e_asq_send_command() does not wait for
7423 * completion before returning.
7424 **/
7425enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
7426				enum virtchnl_ops v_opcode,
7427				enum i40e_status_code v_retval,
7428				u8 *msg, u16 msglen,
7429				struct i40e_asq_cmd_details *cmd_details)
7430{
7431	struct i40e_aq_desc desc;
7432	struct i40e_asq_cmd_details details;
7433	enum i40e_status_code status;
7434
7435	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf);
7436	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
7437	desc.cookie_high = CPU_TO_LE32(v_opcode);
7438	desc.cookie_low = CPU_TO_LE32(v_retval);
7439	if (msglen) {
7440		desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF
7441						| I40E_AQ_FLAG_RD));
7442		if (msglen > I40E_AQ_LARGE_BUF)
7443			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
7444		desc.datalen = CPU_TO_LE16(msglen);
7445	}
7446	if (!cmd_details) {
7447		i40e_memset(&details, 0, sizeof(details), I40E_NONDMA_MEM);
7448		details.async = TRUE;
7449		cmd_details = &details;
7450	}
7451	status = i40e_asq_send_command(hw, (struct i40e_aq_desc *)&desc, msg,
7452				       msglen, cmd_details);
7453	return status;
7454}
7455
7456/**
7457 * i40e_vf_parse_hw_config
7458 * @hw: pointer to the hardware structure
7459 * @msg: pointer to the virtual channel VF resource structure
7460 *
7461 * Given a VF resource message from the PF, populate the hw struct
7462 * with appropriate information.
7463 **/
7464void i40e_vf_parse_hw_config(struct i40e_hw *hw,
7465			     struct virtchnl_vf_resource *msg)
7466{
7467	struct virtchnl_vsi_resource *vsi_res;
7468	int i;
7469
7470	vsi_res = &msg->vsi_res[0];
7471
7472	hw->dev_caps.num_vsis = msg->num_vsis;
7473	hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
7474	hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
7475	hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
7476	hw->dev_caps.dcb = msg->vf_cap_flags &
7477			   VIRTCHNL_VF_OFFLOAD_L2;
7478	hw->dev_caps.iwarp = (msg->vf_cap_flags &
7479			      VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
7480	for (i = 0; i < msg->num_vsis; i++) {
7481		if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
7482			i40e_memcpy(hw->mac.perm_addr,
7483				    vsi_res->default_mac_addr,
7484				    ETH_ALEN,
7485				    I40E_NONDMA_TO_NONDMA);
7486			i40e_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
7487				    ETH_ALEN,
7488				    I40E_NONDMA_TO_NONDMA);
7489		}
7490		vsi_res++;
7491	}
7492}
7493
7494/**
7495 * i40e_vf_reset
7496 * @hw: pointer to the hardware structure
7497 *
7498 * Send a VF_RESET message to the PF. Does not wait for response from PF
7499 * as none will be forthcoming. Immediately after calling this function,
7500 * the admin queue should be shut down and (optionally) reinitialized.
7501 **/
7502enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
7503{
7504	return i40e_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
7505				      I40E_SUCCESS, NULL, 0, NULL);
7506}
7507
7508/**
7509 * i40e_aq_set_arp_proxy_config
7510 * @hw: pointer to the HW structure
7511 * @proxy_config: pointer to proxy config command table struct
7512 * @cmd_details: pointer to command details
7513 *
7514 * Set ARP offload parameters from pre-populated
7515 * i40e_aqc_arp_proxy_data struct
7516 **/
7517enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
7518				struct i40e_aqc_arp_proxy_data *proxy_config,
7519				struct i40e_asq_cmd_details *cmd_details)
7520{
7521	struct i40e_aq_desc desc;
7522	enum i40e_status_code status;
7523
7524	if (!proxy_config)
7525		return I40E_ERR_PARAM;
7526
7527	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_proxy_config);
7528
7529	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7530	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7531	desc.params.external.addr_high =
7532				  CPU_TO_LE32(I40E_HI_DWORD((u64)proxy_config));
7533	desc.params.external.addr_low =
7534				  CPU_TO_LE32(I40E_LO_DWORD((u64)proxy_config));
7535	desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_arp_proxy_data));
7536
7537	status = i40e_asq_send_command(hw, &desc, proxy_config,
7538				       sizeof(struct i40e_aqc_arp_proxy_data),
7539				       cmd_details);
7540
7541	return status;
7542}
7543
7544/**
7545 * i40e_aq_opc_set_ns_proxy_table_entry
7546 * @hw: pointer to the HW structure
7547 * @ns_proxy_table_entry: pointer to NS table entry command struct
7548 * @cmd_details: pointer to command details
7549 *
7550 * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
7551 * from pre-populated i40e_aqc_ns_proxy_data struct
7552 **/
7553enum i40e_status_code i40e_aq_set_ns_proxy_table_entry(struct i40e_hw *hw,
7554			struct i40e_aqc_ns_proxy_data *ns_proxy_table_entry,
7555			struct i40e_asq_cmd_details *cmd_details)
7556{
7557	struct i40e_aq_desc desc;
7558	enum i40e_status_code status;
7559
7560	if (!ns_proxy_table_entry)
7561		return I40E_ERR_PARAM;
7562
7563	i40e_fill_default_direct_cmd_desc(&desc,
7564				i40e_aqc_opc_set_ns_proxy_table_entry);
7565
7566	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7567	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7568	desc.params.external.addr_high =
7569		CPU_TO_LE32(I40E_HI_DWORD((u64)ns_proxy_table_entry));
7570	desc.params.external.addr_low =
7571		CPU_TO_LE32(I40E_LO_DWORD((u64)ns_proxy_table_entry));
7572	desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_ns_proxy_data));
7573
7574	status = i40e_asq_send_command(hw, &desc, ns_proxy_table_entry,
7575				       sizeof(struct i40e_aqc_ns_proxy_data),
7576				       cmd_details);
7577
7578	return status;
7579}
7580
7581/**
7582 * i40e_aq_set_clear_wol_filter
7583 * @hw: pointer to the hw struct
7584 * @filter_index: index of filter to modify (0-7)
7585 * @filter: buffer containing filter to be set
7586 * @set_filter: TRUE to set filter, FALSE to clear filter
7587 * @no_wol_tco: if TRUE, pass through packets cannot cause wake-up
7588 *		if FALSE, pass through packets may cause wake-up
7589 * @filter_valid: TRUE if filter action is valid
7590 * @no_wol_tco_valid: TRUE if no WoL in TCO traffic action valid
7591 * @cmd_details: pointer to command details structure or NULL
7592 *
7593 * Set or clear WoL filter for port attached to the PF
7594 **/
7595enum i40e_status_code i40e_aq_set_clear_wol_filter(struct i40e_hw *hw,
7596				u8 filter_index,
7597				struct i40e_aqc_set_wol_filter_data *filter,
7598				bool set_filter, bool no_wol_tco,
7599				bool filter_valid, bool no_wol_tco_valid,
7600				struct i40e_asq_cmd_details *cmd_details)
7601{
7602	struct i40e_aq_desc desc;
7603	struct i40e_aqc_set_wol_filter *cmd =
7604		(struct i40e_aqc_set_wol_filter *)&desc.params.raw;
7605	enum i40e_status_code status;
7606	u16 cmd_flags = 0;
7607	u16 valid_flags = 0;
7608	u16 buff_len = 0;
7609
7610	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_wol_filter);
7611
7612	if (filter_index >= I40E_AQC_MAX_NUM_WOL_FILTERS)
7613		return  I40E_ERR_PARAM;
7614	cmd->filter_index = CPU_TO_LE16(filter_index);
7615
7616	if (set_filter) {
7617		if (!filter)
7618			return  I40E_ERR_PARAM;
7619
7620		cmd_flags |= I40E_AQC_SET_WOL_FILTER;
7621		cmd_flags |= I40E_AQC_SET_WOL_FILTER_WOL_PRESERVE_ON_PFR;
7622	}
7623
7624	if (no_wol_tco)
7625		cmd_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_WOL;
7626	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
7627
7628	if (filter_valid)
7629		valid_flags |= I40E_AQC_SET_WOL_FILTER_ACTION_VALID;
7630	if (no_wol_tco_valid)
7631		valid_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
7632	cmd->valid_flags = CPU_TO_LE16(valid_flags);
7633
7634	buff_len = sizeof(*filter);
7635	desc.datalen = CPU_TO_LE16(buff_len);
7636
7637	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7638	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7639
7640	cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)filter));
7641	cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)filter));
7642
7643	status = i40e_asq_send_command(hw, &desc, filter,
7644				       buff_len, cmd_details);
7645
7646	return status;
7647}
7648
7649/**
7650 * i40e_aq_get_wake_event_reason
7651 * @hw: pointer to the hw struct
7652 * @wake_reason: return value, index of matching filter
7653 * @cmd_details: pointer to command details structure or NULL
7654 *
7655 * Get information for the reason of a Wake Up event
7656 **/
7657enum i40e_status_code i40e_aq_get_wake_event_reason(struct i40e_hw *hw,
7658				u16 *wake_reason,
7659				struct i40e_asq_cmd_details *cmd_details)
7660{
7661	struct i40e_aq_desc desc;
7662	struct i40e_aqc_get_wake_reason_completion *resp =
7663		(struct i40e_aqc_get_wake_reason_completion *)&desc.params.raw;
7664	enum i40e_status_code status;
7665
7666	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_wake_reason);
7667
7668	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7669
7670	if (status == I40E_SUCCESS)
7671		*wake_reason = LE16_TO_CPU(resp->wake_reason);
7672
7673	return status;
7674}
7675
7676/**
7677* i40e_aq_clear_all_wol_filters
7678* @hw: pointer to the hw struct
7679* @cmd_details: pointer to command details structure or NULL
7680*
7681* Get information for the reason of a Wake Up event
7682**/
7683enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
7684	struct i40e_asq_cmd_details *cmd_details)
7685{
7686	struct i40e_aq_desc desc;
7687	enum i40e_status_code status;
7688
7689	i40e_fill_default_direct_cmd_desc(&desc,
7690					  i40e_aqc_opc_clear_all_wol_filters);
7691
7692	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7693
7694	return status;
7695}
7696
7697