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