xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/intel/i40e/i40e_common.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright(c) 2013 - 2018 Intel Corporation. */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include "i40e.h"
5*4882a593Smuzhiyun #include "i40e_type.h"
6*4882a593Smuzhiyun #include "i40e_adminq.h"
7*4882a593Smuzhiyun #include "i40e_prototype.h"
8*4882a593Smuzhiyun #include <linux/avf/virtchnl.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun /**
11*4882a593Smuzhiyun  * i40e_set_mac_type - Sets MAC type
12*4882a593Smuzhiyun  * @hw: pointer to the HW structure
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * This function sets the mac type of the adapter based on the
15*4882a593Smuzhiyun  * vendor ID and device ID stored in the hw structure.
16*4882a593Smuzhiyun  **/
i40e_set_mac_type(struct i40e_hw * hw)17*4882a593Smuzhiyun i40e_status i40e_set_mac_type(struct i40e_hw *hw)
18*4882a593Smuzhiyun {
19*4882a593Smuzhiyun 	i40e_status status = 0;
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun 	if (hw->vendor_id == PCI_VENDOR_ID_INTEL) {
22*4882a593Smuzhiyun 		switch (hw->device_id) {
23*4882a593Smuzhiyun 		case I40E_DEV_ID_SFP_XL710:
24*4882a593Smuzhiyun 		case I40E_DEV_ID_QEMU:
25*4882a593Smuzhiyun 		case I40E_DEV_ID_KX_B:
26*4882a593Smuzhiyun 		case I40E_DEV_ID_KX_C:
27*4882a593Smuzhiyun 		case I40E_DEV_ID_QSFP_A:
28*4882a593Smuzhiyun 		case I40E_DEV_ID_QSFP_B:
29*4882a593Smuzhiyun 		case I40E_DEV_ID_QSFP_C:
30*4882a593Smuzhiyun 		case I40E_DEV_ID_5G_BASE_T_BC:
31*4882a593Smuzhiyun 		case I40E_DEV_ID_10G_BASE_T:
32*4882a593Smuzhiyun 		case I40E_DEV_ID_10G_BASE_T4:
33*4882a593Smuzhiyun 		case I40E_DEV_ID_10G_BASE_T_BC:
34*4882a593Smuzhiyun 		case I40E_DEV_ID_10G_B:
35*4882a593Smuzhiyun 		case I40E_DEV_ID_10G_SFP:
36*4882a593Smuzhiyun 		case I40E_DEV_ID_20G_KR2:
37*4882a593Smuzhiyun 		case I40E_DEV_ID_20G_KR2_A:
38*4882a593Smuzhiyun 		case I40E_DEV_ID_25G_B:
39*4882a593Smuzhiyun 		case I40E_DEV_ID_25G_SFP28:
40*4882a593Smuzhiyun 		case I40E_DEV_ID_X710_N3000:
41*4882a593Smuzhiyun 		case I40E_DEV_ID_XXV710_N3000:
42*4882a593Smuzhiyun 			hw->mac.type = I40E_MAC_XL710;
43*4882a593Smuzhiyun 			break;
44*4882a593Smuzhiyun 		case I40E_DEV_ID_KX_X722:
45*4882a593Smuzhiyun 		case I40E_DEV_ID_QSFP_X722:
46*4882a593Smuzhiyun 		case I40E_DEV_ID_SFP_X722:
47*4882a593Smuzhiyun 		case I40E_DEV_ID_1G_BASE_T_X722:
48*4882a593Smuzhiyun 		case I40E_DEV_ID_10G_BASE_T_X722:
49*4882a593Smuzhiyun 		case I40E_DEV_ID_SFP_I_X722:
50*4882a593Smuzhiyun 			hw->mac.type = I40E_MAC_X722;
51*4882a593Smuzhiyun 			break;
52*4882a593Smuzhiyun 		default:
53*4882a593Smuzhiyun 			hw->mac.type = I40E_MAC_GENERIC;
54*4882a593Smuzhiyun 			break;
55*4882a593Smuzhiyun 		}
56*4882a593Smuzhiyun 	} else {
57*4882a593Smuzhiyun 		status = I40E_ERR_DEVICE_NOT_SUPPORTED;
58*4882a593Smuzhiyun 	}
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	hw_dbg(hw, "i40e_set_mac_type found mac: %d, returns: %d\n",
61*4882a593Smuzhiyun 		  hw->mac.type, status);
62*4882a593Smuzhiyun 	return status;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun  * i40e_aq_str - convert AQ err code to a string
67*4882a593Smuzhiyun  * @hw: pointer to the HW structure
68*4882a593Smuzhiyun  * @aq_err: the AQ error code to convert
69*4882a593Smuzhiyun  **/
i40e_aq_str(struct i40e_hw * hw,enum i40e_admin_queue_err aq_err)70*4882a593Smuzhiyun const char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	switch (aq_err) {
73*4882a593Smuzhiyun 	case I40E_AQ_RC_OK:
74*4882a593Smuzhiyun 		return "OK";
75*4882a593Smuzhiyun 	case I40E_AQ_RC_EPERM:
76*4882a593Smuzhiyun 		return "I40E_AQ_RC_EPERM";
77*4882a593Smuzhiyun 	case I40E_AQ_RC_ENOENT:
78*4882a593Smuzhiyun 		return "I40E_AQ_RC_ENOENT";
79*4882a593Smuzhiyun 	case I40E_AQ_RC_ESRCH:
80*4882a593Smuzhiyun 		return "I40E_AQ_RC_ESRCH";
81*4882a593Smuzhiyun 	case I40E_AQ_RC_EINTR:
82*4882a593Smuzhiyun 		return "I40E_AQ_RC_EINTR";
83*4882a593Smuzhiyun 	case I40E_AQ_RC_EIO:
84*4882a593Smuzhiyun 		return "I40E_AQ_RC_EIO";
85*4882a593Smuzhiyun 	case I40E_AQ_RC_ENXIO:
86*4882a593Smuzhiyun 		return "I40E_AQ_RC_ENXIO";
87*4882a593Smuzhiyun 	case I40E_AQ_RC_E2BIG:
88*4882a593Smuzhiyun 		return "I40E_AQ_RC_E2BIG";
89*4882a593Smuzhiyun 	case I40E_AQ_RC_EAGAIN:
90*4882a593Smuzhiyun 		return "I40E_AQ_RC_EAGAIN";
91*4882a593Smuzhiyun 	case I40E_AQ_RC_ENOMEM:
92*4882a593Smuzhiyun 		return "I40E_AQ_RC_ENOMEM";
93*4882a593Smuzhiyun 	case I40E_AQ_RC_EACCES:
94*4882a593Smuzhiyun 		return "I40E_AQ_RC_EACCES";
95*4882a593Smuzhiyun 	case I40E_AQ_RC_EFAULT:
96*4882a593Smuzhiyun 		return "I40E_AQ_RC_EFAULT";
97*4882a593Smuzhiyun 	case I40E_AQ_RC_EBUSY:
98*4882a593Smuzhiyun 		return "I40E_AQ_RC_EBUSY";
99*4882a593Smuzhiyun 	case I40E_AQ_RC_EEXIST:
100*4882a593Smuzhiyun 		return "I40E_AQ_RC_EEXIST";
101*4882a593Smuzhiyun 	case I40E_AQ_RC_EINVAL:
102*4882a593Smuzhiyun 		return "I40E_AQ_RC_EINVAL";
103*4882a593Smuzhiyun 	case I40E_AQ_RC_ENOTTY:
104*4882a593Smuzhiyun 		return "I40E_AQ_RC_ENOTTY";
105*4882a593Smuzhiyun 	case I40E_AQ_RC_ENOSPC:
106*4882a593Smuzhiyun 		return "I40E_AQ_RC_ENOSPC";
107*4882a593Smuzhiyun 	case I40E_AQ_RC_ENOSYS:
108*4882a593Smuzhiyun 		return "I40E_AQ_RC_ENOSYS";
109*4882a593Smuzhiyun 	case I40E_AQ_RC_ERANGE:
110*4882a593Smuzhiyun 		return "I40E_AQ_RC_ERANGE";
111*4882a593Smuzhiyun 	case I40E_AQ_RC_EFLUSHED:
112*4882a593Smuzhiyun 		return "I40E_AQ_RC_EFLUSHED";
113*4882a593Smuzhiyun 	case I40E_AQ_RC_BAD_ADDR:
114*4882a593Smuzhiyun 		return "I40E_AQ_RC_BAD_ADDR";
115*4882a593Smuzhiyun 	case I40E_AQ_RC_EMODE:
116*4882a593Smuzhiyun 		return "I40E_AQ_RC_EMODE";
117*4882a593Smuzhiyun 	case I40E_AQ_RC_EFBIG:
118*4882a593Smuzhiyun 		return "I40E_AQ_RC_EFBIG";
119*4882a593Smuzhiyun 	}
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
122*4882a593Smuzhiyun 	return hw->err_str;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun /**
126*4882a593Smuzhiyun  * i40e_stat_str - convert status err code to a string
127*4882a593Smuzhiyun  * @hw: pointer to the HW structure
128*4882a593Smuzhiyun  * @stat_err: the status error code to convert
129*4882a593Smuzhiyun  **/
i40e_stat_str(struct i40e_hw * hw,i40e_status stat_err)130*4882a593Smuzhiyun const char *i40e_stat_str(struct i40e_hw *hw, i40e_status stat_err)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun 	switch (stat_err) {
133*4882a593Smuzhiyun 	case 0:
134*4882a593Smuzhiyun 		return "OK";
135*4882a593Smuzhiyun 	case I40E_ERR_NVM:
136*4882a593Smuzhiyun 		return "I40E_ERR_NVM";
137*4882a593Smuzhiyun 	case I40E_ERR_NVM_CHECKSUM:
138*4882a593Smuzhiyun 		return "I40E_ERR_NVM_CHECKSUM";
139*4882a593Smuzhiyun 	case I40E_ERR_PHY:
140*4882a593Smuzhiyun 		return "I40E_ERR_PHY";
141*4882a593Smuzhiyun 	case I40E_ERR_CONFIG:
142*4882a593Smuzhiyun 		return "I40E_ERR_CONFIG";
143*4882a593Smuzhiyun 	case I40E_ERR_PARAM:
144*4882a593Smuzhiyun 		return "I40E_ERR_PARAM";
145*4882a593Smuzhiyun 	case I40E_ERR_MAC_TYPE:
146*4882a593Smuzhiyun 		return "I40E_ERR_MAC_TYPE";
147*4882a593Smuzhiyun 	case I40E_ERR_UNKNOWN_PHY:
148*4882a593Smuzhiyun 		return "I40E_ERR_UNKNOWN_PHY";
149*4882a593Smuzhiyun 	case I40E_ERR_LINK_SETUP:
150*4882a593Smuzhiyun 		return "I40E_ERR_LINK_SETUP";
151*4882a593Smuzhiyun 	case I40E_ERR_ADAPTER_STOPPED:
152*4882a593Smuzhiyun 		return "I40E_ERR_ADAPTER_STOPPED";
153*4882a593Smuzhiyun 	case I40E_ERR_INVALID_MAC_ADDR:
154*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_MAC_ADDR";
155*4882a593Smuzhiyun 	case I40E_ERR_DEVICE_NOT_SUPPORTED:
156*4882a593Smuzhiyun 		return "I40E_ERR_DEVICE_NOT_SUPPORTED";
157*4882a593Smuzhiyun 	case I40E_ERR_MASTER_REQUESTS_PENDING:
158*4882a593Smuzhiyun 		return "I40E_ERR_MASTER_REQUESTS_PENDING";
159*4882a593Smuzhiyun 	case I40E_ERR_INVALID_LINK_SETTINGS:
160*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_LINK_SETTINGS";
161*4882a593Smuzhiyun 	case I40E_ERR_AUTONEG_NOT_COMPLETE:
162*4882a593Smuzhiyun 		return "I40E_ERR_AUTONEG_NOT_COMPLETE";
163*4882a593Smuzhiyun 	case I40E_ERR_RESET_FAILED:
164*4882a593Smuzhiyun 		return "I40E_ERR_RESET_FAILED";
165*4882a593Smuzhiyun 	case I40E_ERR_SWFW_SYNC:
166*4882a593Smuzhiyun 		return "I40E_ERR_SWFW_SYNC";
167*4882a593Smuzhiyun 	case I40E_ERR_NO_AVAILABLE_VSI:
168*4882a593Smuzhiyun 		return "I40E_ERR_NO_AVAILABLE_VSI";
169*4882a593Smuzhiyun 	case I40E_ERR_NO_MEMORY:
170*4882a593Smuzhiyun 		return "I40E_ERR_NO_MEMORY";
171*4882a593Smuzhiyun 	case I40E_ERR_BAD_PTR:
172*4882a593Smuzhiyun 		return "I40E_ERR_BAD_PTR";
173*4882a593Smuzhiyun 	case I40E_ERR_RING_FULL:
174*4882a593Smuzhiyun 		return "I40E_ERR_RING_FULL";
175*4882a593Smuzhiyun 	case I40E_ERR_INVALID_PD_ID:
176*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_PD_ID";
177*4882a593Smuzhiyun 	case I40E_ERR_INVALID_QP_ID:
178*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_QP_ID";
179*4882a593Smuzhiyun 	case I40E_ERR_INVALID_CQ_ID:
180*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_CQ_ID";
181*4882a593Smuzhiyun 	case I40E_ERR_INVALID_CEQ_ID:
182*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_CEQ_ID";
183*4882a593Smuzhiyun 	case I40E_ERR_INVALID_AEQ_ID:
184*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_AEQ_ID";
185*4882a593Smuzhiyun 	case I40E_ERR_INVALID_SIZE:
186*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_SIZE";
187*4882a593Smuzhiyun 	case I40E_ERR_INVALID_ARP_INDEX:
188*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_ARP_INDEX";
189*4882a593Smuzhiyun 	case I40E_ERR_INVALID_FPM_FUNC_ID:
190*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_FPM_FUNC_ID";
191*4882a593Smuzhiyun 	case I40E_ERR_QP_INVALID_MSG_SIZE:
192*4882a593Smuzhiyun 		return "I40E_ERR_QP_INVALID_MSG_SIZE";
193*4882a593Smuzhiyun 	case I40E_ERR_QP_TOOMANY_WRS_POSTED:
194*4882a593Smuzhiyun 		return "I40E_ERR_QP_TOOMANY_WRS_POSTED";
195*4882a593Smuzhiyun 	case I40E_ERR_INVALID_FRAG_COUNT:
196*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_FRAG_COUNT";
197*4882a593Smuzhiyun 	case I40E_ERR_QUEUE_EMPTY:
198*4882a593Smuzhiyun 		return "I40E_ERR_QUEUE_EMPTY";
199*4882a593Smuzhiyun 	case I40E_ERR_INVALID_ALIGNMENT:
200*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_ALIGNMENT";
201*4882a593Smuzhiyun 	case I40E_ERR_FLUSHED_QUEUE:
202*4882a593Smuzhiyun 		return "I40E_ERR_FLUSHED_QUEUE";
203*4882a593Smuzhiyun 	case I40E_ERR_INVALID_PUSH_PAGE_INDEX:
204*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_PUSH_PAGE_INDEX";
205*4882a593Smuzhiyun 	case I40E_ERR_INVALID_IMM_DATA_SIZE:
206*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_IMM_DATA_SIZE";
207*4882a593Smuzhiyun 	case I40E_ERR_TIMEOUT:
208*4882a593Smuzhiyun 		return "I40E_ERR_TIMEOUT";
209*4882a593Smuzhiyun 	case I40E_ERR_OPCODE_MISMATCH:
210*4882a593Smuzhiyun 		return "I40E_ERR_OPCODE_MISMATCH";
211*4882a593Smuzhiyun 	case I40E_ERR_CQP_COMPL_ERROR:
212*4882a593Smuzhiyun 		return "I40E_ERR_CQP_COMPL_ERROR";
213*4882a593Smuzhiyun 	case I40E_ERR_INVALID_VF_ID:
214*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_VF_ID";
215*4882a593Smuzhiyun 	case I40E_ERR_INVALID_HMCFN_ID:
216*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_HMCFN_ID";
217*4882a593Smuzhiyun 	case I40E_ERR_BACKING_PAGE_ERROR:
218*4882a593Smuzhiyun 		return "I40E_ERR_BACKING_PAGE_ERROR";
219*4882a593Smuzhiyun 	case I40E_ERR_NO_PBLCHUNKS_AVAILABLE:
220*4882a593Smuzhiyun 		return "I40E_ERR_NO_PBLCHUNKS_AVAILABLE";
221*4882a593Smuzhiyun 	case I40E_ERR_INVALID_PBLE_INDEX:
222*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_PBLE_INDEX";
223*4882a593Smuzhiyun 	case I40E_ERR_INVALID_SD_INDEX:
224*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_SD_INDEX";
225*4882a593Smuzhiyun 	case I40E_ERR_INVALID_PAGE_DESC_INDEX:
226*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_PAGE_DESC_INDEX";
227*4882a593Smuzhiyun 	case I40E_ERR_INVALID_SD_TYPE:
228*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_SD_TYPE";
229*4882a593Smuzhiyun 	case I40E_ERR_MEMCPY_FAILED:
230*4882a593Smuzhiyun 		return "I40E_ERR_MEMCPY_FAILED";
231*4882a593Smuzhiyun 	case I40E_ERR_INVALID_HMC_OBJ_INDEX:
232*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_HMC_OBJ_INDEX";
233*4882a593Smuzhiyun 	case I40E_ERR_INVALID_HMC_OBJ_COUNT:
234*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_HMC_OBJ_COUNT";
235*4882a593Smuzhiyun 	case I40E_ERR_INVALID_SRQ_ARM_LIMIT:
236*4882a593Smuzhiyun 		return "I40E_ERR_INVALID_SRQ_ARM_LIMIT";
237*4882a593Smuzhiyun 	case I40E_ERR_SRQ_ENABLED:
238*4882a593Smuzhiyun 		return "I40E_ERR_SRQ_ENABLED";
239*4882a593Smuzhiyun 	case I40E_ERR_ADMIN_QUEUE_ERROR:
240*4882a593Smuzhiyun 		return "I40E_ERR_ADMIN_QUEUE_ERROR";
241*4882a593Smuzhiyun 	case I40E_ERR_ADMIN_QUEUE_TIMEOUT:
242*4882a593Smuzhiyun 		return "I40E_ERR_ADMIN_QUEUE_TIMEOUT";
243*4882a593Smuzhiyun 	case I40E_ERR_BUF_TOO_SHORT:
244*4882a593Smuzhiyun 		return "I40E_ERR_BUF_TOO_SHORT";
245*4882a593Smuzhiyun 	case I40E_ERR_ADMIN_QUEUE_FULL:
246*4882a593Smuzhiyun 		return "I40E_ERR_ADMIN_QUEUE_FULL";
247*4882a593Smuzhiyun 	case I40E_ERR_ADMIN_QUEUE_NO_WORK:
248*4882a593Smuzhiyun 		return "I40E_ERR_ADMIN_QUEUE_NO_WORK";
249*4882a593Smuzhiyun 	case I40E_ERR_BAD_IWARP_CQE:
250*4882a593Smuzhiyun 		return "I40E_ERR_BAD_IWARP_CQE";
251*4882a593Smuzhiyun 	case I40E_ERR_NVM_BLANK_MODE:
252*4882a593Smuzhiyun 		return "I40E_ERR_NVM_BLANK_MODE";
253*4882a593Smuzhiyun 	case I40E_ERR_NOT_IMPLEMENTED:
254*4882a593Smuzhiyun 		return "I40E_ERR_NOT_IMPLEMENTED";
255*4882a593Smuzhiyun 	case I40E_ERR_PE_DOORBELL_NOT_ENABLED:
256*4882a593Smuzhiyun 		return "I40E_ERR_PE_DOORBELL_NOT_ENABLED";
257*4882a593Smuzhiyun 	case I40E_ERR_DIAG_TEST_FAILED:
258*4882a593Smuzhiyun 		return "I40E_ERR_DIAG_TEST_FAILED";
259*4882a593Smuzhiyun 	case I40E_ERR_NOT_READY:
260*4882a593Smuzhiyun 		return "I40E_ERR_NOT_READY";
261*4882a593Smuzhiyun 	case I40E_NOT_SUPPORTED:
262*4882a593Smuzhiyun 		return "I40E_NOT_SUPPORTED";
263*4882a593Smuzhiyun 	case I40E_ERR_FIRMWARE_API_VERSION:
264*4882a593Smuzhiyun 		return "I40E_ERR_FIRMWARE_API_VERSION";
265*4882a593Smuzhiyun 	case I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
266*4882a593Smuzhiyun 		return "I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
267*4882a593Smuzhiyun 	}
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
270*4882a593Smuzhiyun 	return hw->err_str;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun /**
274*4882a593Smuzhiyun  * i40e_debug_aq
275*4882a593Smuzhiyun  * @hw: debug mask related to admin queue
276*4882a593Smuzhiyun  * @mask: debug mask
277*4882a593Smuzhiyun  * @desc: pointer to admin queue descriptor
278*4882a593Smuzhiyun  * @buffer: pointer to command buffer
279*4882a593Smuzhiyun  * @buf_len: max length of buffer
280*4882a593Smuzhiyun  *
281*4882a593Smuzhiyun  * Dumps debug log about adminq command with descriptor contents.
282*4882a593Smuzhiyun  **/
i40e_debug_aq(struct i40e_hw * hw,enum i40e_debug_mask mask,void * desc,void * buffer,u16 buf_len)283*4882a593Smuzhiyun void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
284*4882a593Smuzhiyun 		   void *buffer, u16 buf_len)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun 	struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
287*4882a593Smuzhiyun 	u32 effective_mask = hw->debug_mask & mask;
288*4882a593Smuzhiyun 	char prefix[27];
289*4882a593Smuzhiyun 	u16 len;
290*4882a593Smuzhiyun 	u8 *buf = (u8 *)buffer;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	if (!effective_mask || !desc)
293*4882a593Smuzhiyun 		return;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	len = le16_to_cpu(aq_desc->datalen);
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
298*4882a593Smuzhiyun 		   "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
299*4882a593Smuzhiyun 		   le16_to_cpu(aq_desc->opcode),
300*4882a593Smuzhiyun 		   le16_to_cpu(aq_desc->flags),
301*4882a593Smuzhiyun 		   le16_to_cpu(aq_desc->datalen),
302*4882a593Smuzhiyun 		   le16_to_cpu(aq_desc->retval));
303*4882a593Smuzhiyun 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
304*4882a593Smuzhiyun 		   "\tcookie (h,l) 0x%08X 0x%08X\n",
305*4882a593Smuzhiyun 		   le32_to_cpu(aq_desc->cookie_high),
306*4882a593Smuzhiyun 		   le32_to_cpu(aq_desc->cookie_low));
307*4882a593Smuzhiyun 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
308*4882a593Smuzhiyun 		   "\tparam (0,1)  0x%08X 0x%08X\n",
309*4882a593Smuzhiyun 		   le32_to_cpu(aq_desc->params.internal.param0),
310*4882a593Smuzhiyun 		   le32_to_cpu(aq_desc->params.internal.param1));
311*4882a593Smuzhiyun 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
312*4882a593Smuzhiyun 		   "\taddr (h,l)   0x%08X 0x%08X\n",
313*4882a593Smuzhiyun 		   le32_to_cpu(aq_desc->params.external.addr_high),
314*4882a593Smuzhiyun 		   le32_to_cpu(aq_desc->params.external.addr_low));
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	if (buffer && buf_len != 0 && len != 0 &&
317*4882a593Smuzhiyun 	    (effective_mask & I40E_DEBUG_AQ_DESC_BUFFER)) {
318*4882a593Smuzhiyun 		i40e_debug(hw, mask, "AQ CMD Buffer:\n");
319*4882a593Smuzhiyun 		if (buf_len < len)
320*4882a593Smuzhiyun 			len = buf_len;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 		snprintf(prefix, sizeof(prefix),
323*4882a593Smuzhiyun 			 "i40e %02x:%02x.%x: \t0x",
324*4882a593Smuzhiyun 			 hw->bus.bus_id,
325*4882a593Smuzhiyun 			 hw->bus.device,
326*4882a593Smuzhiyun 			 hw->bus.func);
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 		print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET,
329*4882a593Smuzhiyun 			       16, 1, buf, len, false);
330*4882a593Smuzhiyun 	}
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun /**
334*4882a593Smuzhiyun  * i40e_check_asq_alive
335*4882a593Smuzhiyun  * @hw: pointer to the hw struct
336*4882a593Smuzhiyun  *
337*4882a593Smuzhiyun  * Returns true if Queue is enabled else false.
338*4882a593Smuzhiyun  **/
i40e_check_asq_alive(struct i40e_hw * hw)339*4882a593Smuzhiyun bool i40e_check_asq_alive(struct i40e_hw *hw)
340*4882a593Smuzhiyun {
341*4882a593Smuzhiyun 	if (hw->aq.asq.len)
342*4882a593Smuzhiyun 		return !!(rd32(hw, hw->aq.asq.len) &
343*4882a593Smuzhiyun 			  I40E_PF_ATQLEN_ATQENABLE_MASK);
344*4882a593Smuzhiyun 	else
345*4882a593Smuzhiyun 		return false;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun /**
349*4882a593Smuzhiyun  * i40e_aq_queue_shutdown
350*4882a593Smuzhiyun  * @hw: pointer to the hw struct
351*4882a593Smuzhiyun  * @unloading: is the driver unloading itself
352*4882a593Smuzhiyun  *
353*4882a593Smuzhiyun  * Tell the Firmware that we're shutting down the AdminQ and whether
354*4882a593Smuzhiyun  * or not the driver is unloading as well.
355*4882a593Smuzhiyun  **/
i40e_aq_queue_shutdown(struct i40e_hw * hw,bool unloading)356*4882a593Smuzhiyun i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
357*4882a593Smuzhiyun 					     bool unloading)
358*4882a593Smuzhiyun {
359*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
360*4882a593Smuzhiyun 	struct i40e_aqc_queue_shutdown *cmd =
361*4882a593Smuzhiyun 		(struct i40e_aqc_queue_shutdown *)&desc.params.raw;
362*4882a593Smuzhiyun 	i40e_status status;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
365*4882a593Smuzhiyun 					  i40e_aqc_opc_queue_shutdown);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	if (unloading)
368*4882a593Smuzhiyun 		cmd->driver_unloading = cpu_to_le32(I40E_AQ_DRIVER_UNLOADING);
369*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	return status;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun /**
375*4882a593Smuzhiyun  * i40e_aq_get_set_rss_lut
376*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
377*4882a593Smuzhiyun  * @vsi_id: vsi fw index
378*4882a593Smuzhiyun  * @pf_lut: for PF table set true, for VSI table set false
379*4882a593Smuzhiyun  * @lut: pointer to the lut buffer provided by the caller
380*4882a593Smuzhiyun  * @lut_size: size of the lut buffer
381*4882a593Smuzhiyun  * @set: set true to set the table, false to get the table
382*4882a593Smuzhiyun  *
383*4882a593Smuzhiyun  * Internal function to get or set RSS look up table
384*4882a593Smuzhiyun  **/
i40e_aq_get_set_rss_lut(struct i40e_hw * hw,u16 vsi_id,bool pf_lut,u8 * lut,u16 lut_size,bool set)385*4882a593Smuzhiyun static i40e_status i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
386*4882a593Smuzhiyun 					   u16 vsi_id, bool pf_lut,
387*4882a593Smuzhiyun 					   u8 *lut, u16 lut_size,
388*4882a593Smuzhiyun 					   bool set)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	i40e_status status;
391*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
392*4882a593Smuzhiyun 	struct i40e_aqc_get_set_rss_lut *cmd_resp =
393*4882a593Smuzhiyun 		   (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw;
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	if (set)
396*4882a593Smuzhiyun 		i40e_fill_default_direct_cmd_desc(&desc,
397*4882a593Smuzhiyun 						  i40e_aqc_opc_set_rss_lut);
398*4882a593Smuzhiyun 	else
399*4882a593Smuzhiyun 		i40e_fill_default_direct_cmd_desc(&desc,
400*4882a593Smuzhiyun 						  i40e_aqc_opc_get_rss_lut);
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	/* Indirect command */
403*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
404*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	cmd_resp->vsi_id =
407*4882a593Smuzhiyun 			cpu_to_le16((u16)((vsi_id <<
408*4882a593Smuzhiyun 					  I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
409*4882a593Smuzhiyun 					  I40E_AQC_SET_RSS_LUT_VSI_ID_MASK));
410*4882a593Smuzhiyun 	cmd_resp->vsi_id |= cpu_to_le16((u16)I40E_AQC_SET_RSS_LUT_VSI_VALID);
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (pf_lut)
413*4882a593Smuzhiyun 		cmd_resp->flags |= cpu_to_le16((u16)
414*4882a593Smuzhiyun 					((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
415*4882a593Smuzhiyun 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
416*4882a593Smuzhiyun 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
417*4882a593Smuzhiyun 	else
418*4882a593Smuzhiyun 		cmd_resp->flags |= cpu_to_le16((u16)
419*4882a593Smuzhiyun 					((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
420*4882a593Smuzhiyun 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
421*4882a593Smuzhiyun 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, lut, lut_size, NULL);
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	return status;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun /**
429*4882a593Smuzhiyun  * i40e_aq_get_rss_lut
430*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
431*4882a593Smuzhiyun  * @vsi_id: vsi fw index
432*4882a593Smuzhiyun  * @pf_lut: for PF table set true, for VSI table set false
433*4882a593Smuzhiyun  * @lut: pointer to the lut buffer provided by the caller
434*4882a593Smuzhiyun  * @lut_size: size of the lut buffer
435*4882a593Smuzhiyun  *
436*4882a593Smuzhiyun  * get the RSS lookup table, PF or VSI type
437*4882a593Smuzhiyun  **/
i40e_aq_get_rss_lut(struct i40e_hw * hw,u16 vsi_id,bool pf_lut,u8 * lut,u16 lut_size)438*4882a593Smuzhiyun i40e_status i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
439*4882a593Smuzhiyun 				bool pf_lut, u8 *lut, u16 lut_size)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun 	return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
442*4882a593Smuzhiyun 				       false);
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun /**
446*4882a593Smuzhiyun  * i40e_aq_set_rss_lut
447*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
448*4882a593Smuzhiyun  * @vsi_id: vsi fw index
449*4882a593Smuzhiyun  * @pf_lut: for PF table set true, for VSI table set false
450*4882a593Smuzhiyun  * @lut: pointer to the lut buffer provided by the caller
451*4882a593Smuzhiyun  * @lut_size: size of the lut buffer
452*4882a593Smuzhiyun  *
453*4882a593Smuzhiyun  * set the RSS lookup table, PF or VSI type
454*4882a593Smuzhiyun  **/
i40e_aq_set_rss_lut(struct i40e_hw * hw,u16 vsi_id,bool pf_lut,u8 * lut,u16 lut_size)455*4882a593Smuzhiyun i40e_status i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
456*4882a593Smuzhiyun 				bool pf_lut, u8 *lut, u16 lut_size)
457*4882a593Smuzhiyun {
458*4882a593Smuzhiyun 	return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun /**
462*4882a593Smuzhiyun  * i40e_aq_get_set_rss_key
463*4882a593Smuzhiyun  * @hw: pointer to the hw struct
464*4882a593Smuzhiyun  * @vsi_id: vsi fw index
465*4882a593Smuzhiyun  * @key: pointer to key info struct
466*4882a593Smuzhiyun  * @set: set true to set the key, false to get the key
467*4882a593Smuzhiyun  *
468*4882a593Smuzhiyun  * get the RSS key per VSI
469*4882a593Smuzhiyun  **/
i40e_aq_get_set_rss_key(struct i40e_hw * hw,u16 vsi_id,struct i40e_aqc_get_set_rss_key_data * key,bool set)470*4882a593Smuzhiyun static i40e_status i40e_aq_get_set_rss_key(struct i40e_hw *hw,
471*4882a593Smuzhiyun 				      u16 vsi_id,
472*4882a593Smuzhiyun 				      struct i40e_aqc_get_set_rss_key_data *key,
473*4882a593Smuzhiyun 				      bool set)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	i40e_status status;
476*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
477*4882a593Smuzhiyun 	struct i40e_aqc_get_set_rss_key *cmd_resp =
478*4882a593Smuzhiyun 			(struct i40e_aqc_get_set_rss_key *)&desc.params.raw;
479*4882a593Smuzhiyun 	u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data);
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	if (set)
482*4882a593Smuzhiyun 		i40e_fill_default_direct_cmd_desc(&desc,
483*4882a593Smuzhiyun 						  i40e_aqc_opc_set_rss_key);
484*4882a593Smuzhiyun 	else
485*4882a593Smuzhiyun 		i40e_fill_default_direct_cmd_desc(&desc,
486*4882a593Smuzhiyun 						  i40e_aqc_opc_get_rss_key);
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	/* Indirect command */
489*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
490*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	cmd_resp->vsi_id =
493*4882a593Smuzhiyun 			cpu_to_le16((u16)((vsi_id <<
494*4882a593Smuzhiyun 					  I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
495*4882a593Smuzhiyun 					  I40E_AQC_SET_RSS_KEY_VSI_ID_MASK));
496*4882a593Smuzhiyun 	cmd_resp->vsi_id |= cpu_to_le16((u16)I40E_AQC_SET_RSS_KEY_VSI_VALID);
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, key, key_size, NULL);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	return status;
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun /**
504*4882a593Smuzhiyun  * i40e_aq_get_rss_key
505*4882a593Smuzhiyun  * @hw: pointer to the hw struct
506*4882a593Smuzhiyun  * @vsi_id: vsi fw index
507*4882a593Smuzhiyun  * @key: pointer to key info struct
508*4882a593Smuzhiyun  *
509*4882a593Smuzhiyun  **/
i40e_aq_get_rss_key(struct i40e_hw * hw,u16 vsi_id,struct i40e_aqc_get_set_rss_key_data * key)510*4882a593Smuzhiyun i40e_status i40e_aq_get_rss_key(struct i40e_hw *hw,
511*4882a593Smuzhiyun 				u16 vsi_id,
512*4882a593Smuzhiyun 				struct i40e_aqc_get_set_rss_key_data *key)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun 	return i40e_aq_get_set_rss_key(hw, vsi_id, key, false);
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun /**
518*4882a593Smuzhiyun  * i40e_aq_set_rss_key
519*4882a593Smuzhiyun  * @hw: pointer to the hw struct
520*4882a593Smuzhiyun  * @vsi_id: vsi fw index
521*4882a593Smuzhiyun  * @key: pointer to key info struct
522*4882a593Smuzhiyun  *
523*4882a593Smuzhiyun  * set the RSS key per VSI
524*4882a593Smuzhiyun  **/
i40e_aq_set_rss_key(struct i40e_hw * hw,u16 vsi_id,struct i40e_aqc_get_set_rss_key_data * key)525*4882a593Smuzhiyun i40e_status i40e_aq_set_rss_key(struct i40e_hw *hw,
526*4882a593Smuzhiyun 				u16 vsi_id,
527*4882a593Smuzhiyun 				struct i40e_aqc_get_set_rss_key_data *key)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun 	return i40e_aq_get_set_rss_key(hw, vsi_id, key, true);
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun /* The i40e_ptype_lookup table is used to convert from the 8-bit ptype in the
533*4882a593Smuzhiyun  * hardware to a bit-field that can be used by SW to more easily determine the
534*4882a593Smuzhiyun  * packet type.
535*4882a593Smuzhiyun  *
536*4882a593Smuzhiyun  * Macros are used to shorten the table lines and make this table human
537*4882a593Smuzhiyun  * readable.
538*4882a593Smuzhiyun  *
539*4882a593Smuzhiyun  * We store the PTYPE in the top byte of the bit field - this is just so that
540*4882a593Smuzhiyun  * we can check that the table doesn't have a row missing, as the index into
541*4882a593Smuzhiyun  * the table should be the PTYPE.
542*4882a593Smuzhiyun  *
543*4882a593Smuzhiyun  * Typical work flow:
544*4882a593Smuzhiyun  *
545*4882a593Smuzhiyun  * IF NOT i40e_ptype_lookup[ptype].known
546*4882a593Smuzhiyun  * THEN
547*4882a593Smuzhiyun  *      Packet is unknown
548*4882a593Smuzhiyun  * ELSE IF i40e_ptype_lookup[ptype].outer_ip == I40E_RX_PTYPE_OUTER_IP
549*4882a593Smuzhiyun  *      Use the rest of the fields to look at the tunnels, inner protocols, etc
550*4882a593Smuzhiyun  * ELSE
551*4882a593Smuzhiyun  *      Use the enum i40e_rx_l2_ptype to decode the packet type
552*4882a593Smuzhiyun  * ENDIF
553*4882a593Smuzhiyun  */
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun /* macro to make the table lines short */
556*4882a593Smuzhiyun #define I40E_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\
557*4882a593Smuzhiyun 	{	PTYPE, \
558*4882a593Smuzhiyun 		1, \
559*4882a593Smuzhiyun 		I40E_RX_PTYPE_OUTER_##OUTER_IP, \
560*4882a593Smuzhiyun 		I40E_RX_PTYPE_OUTER_##OUTER_IP_VER, \
561*4882a593Smuzhiyun 		I40E_RX_PTYPE_##OUTER_FRAG, \
562*4882a593Smuzhiyun 		I40E_RX_PTYPE_TUNNEL_##T, \
563*4882a593Smuzhiyun 		I40E_RX_PTYPE_TUNNEL_END_##TE, \
564*4882a593Smuzhiyun 		I40E_RX_PTYPE_##TEF, \
565*4882a593Smuzhiyun 		I40E_RX_PTYPE_INNER_PROT_##I, \
566*4882a593Smuzhiyun 		I40E_RX_PTYPE_PAYLOAD_LAYER_##PL }
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun #define I40E_PTT_UNUSED_ENTRY(PTYPE) \
569*4882a593Smuzhiyun 		{ PTYPE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun /* shorter macros makes the table fit but are terse */
572*4882a593Smuzhiyun #define I40E_RX_PTYPE_NOF		I40E_RX_PTYPE_NOT_FRAG
573*4882a593Smuzhiyun #define I40E_RX_PTYPE_FRG		I40E_RX_PTYPE_FRAG
574*4882a593Smuzhiyun #define I40E_RX_PTYPE_INNER_PROT_TS	I40E_RX_PTYPE_INNER_PROT_TIMESYNC
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun /* Lookup table mapping the HW PTYPE to the bit field for decoding */
577*4882a593Smuzhiyun struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {
578*4882a593Smuzhiyun 	/* L2 Packet types */
579*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(0),
580*4882a593Smuzhiyun 	I40E_PTT(1,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
581*4882a593Smuzhiyun 	I40E_PTT(2,  L2, NONE, NOF, NONE, NONE, NOF, TS,   PAY2),
582*4882a593Smuzhiyun 	I40E_PTT(3,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
583*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(4),
584*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(5),
585*4882a593Smuzhiyun 	I40E_PTT(6,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
586*4882a593Smuzhiyun 	I40E_PTT(7,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
587*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(8),
588*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(9),
589*4882a593Smuzhiyun 	I40E_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
590*4882a593Smuzhiyun 	I40E_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
591*4882a593Smuzhiyun 	I40E_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
592*4882a593Smuzhiyun 	I40E_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
593*4882a593Smuzhiyun 	I40E_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
594*4882a593Smuzhiyun 	I40E_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
595*4882a593Smuzhiyun 	I40E_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
596*4882a593Smuzhiyun 	I40E_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
597*4882a593Smuzhiyun 	I40E_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
598*4882a593Smuzhiyun 	I40E_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
599*4882a593Smuzhiyun 	I40E_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
600*4882a593Smuzhiyun 	I40E_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	/* Non Tunneled IPv4 */
603*4882a593Smuzhiyun 	I40E_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
604*4882a593Smuzhiyun 	I40E_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
605*4882a593Smuzhiyun 	I40E_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP,  PAY4),
606*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(25),
607*4882a593Smuzhiyun 	I40E_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP,  PAY4),
608*4882a593Smuzhiyun 	I40E_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
609*4882a593Smuzhiyun 	I40E_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	/* IPv4 --> IPv4 */
612*4882a593Smuzhiyun 	I40E_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
613*4882a593Smuzhiyun 	I40E_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
614*4882a593Smuzhiyun 	I40E_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP,  PAY4),
615*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(32),
616*4882a593Smuzhiyun 	I40E_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP,  PAY4),
617*4882a593Smuzhiyun 	I40E_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
618*4882a593Smuzhiyun 	I40E_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 	/* IPv4 --> IPv6 */
621*4882a593Smuzhiyun 	I40E_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
622*4882a593Smuzhiyun 	I40E_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
623*4882a593Smuzhiyun 	I40E_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP,  PAY4),
624*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(39),
625*4882a593Smuzhiyun 	I40E_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP,  PAY4),
626*4882a593Smuzhiyun 	I40E_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
627*4882a593Smuzhiyun 	I40E_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	/* IPv4 --> GRE/NAT */
630*4882a593Smuzhiyun 	I40E_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	/* IPv4 --> GRE/NAT --> IPv4 */
633*4882a593Smuzhiyun 	I40E_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
634*4882a593Smuzhiyun 	I40E_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
635*4882a593Smuzhiyun 	I40E_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP,  PAY4),
636*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(47),
637*4882a593Smuzhiyun 	I40E_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP,  PAY4),
638*4882a593Smuzhiyun 	I40E_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
639*4882a593Smuzhiyun 	I40E_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 	/* IPv4 --> GRE/NAT --> IPv6 */
642*4882a593Smuzhiyun 	I40E_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
643*4882a593Smuzhiyun 	I40E_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
644*4882a593Smuzhiyun 	I40E_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP,  PAY4),
645*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(54),
646*4882a593Smuzhiyun 	I40E_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP,  PAY4),
647*4882a593Smuzhiyun 	I40E_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
648*4882a593Smuzhiyun 	I40E_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 	/* IPv4 --> GRE/NAT --> MAC */
651*4882a593Smuzhiyun 	I40E_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	/* IPv4 --> GRE/NAT --> MAC --> IPv4 */
654*4882a593Smuzhiyun 	I40E_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
655*4882a593Smuzhiyun 	I40E_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
656*4882a593Smuzhiyun 	I40E_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP,  PAY4),
657*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(62),
658*4882a593Smuzhiyun 	I40E_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP,  PAY4),
659*4882a593Smuzhiyun 	I40E_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
660*4882a593Smuzhiyun 	I40E_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	/* IPv4 --> GRE/NAT -> MAC --> IPv6 */
663*4882a593Smuzhiyun 	I40E_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
664*4882a593Smuzhiyun 	I40E_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
665*4882a593Smuzhiyun 	I40E_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP,  PAY4),
666*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(69),
667*4882a593Smuzhiyun 	I40E_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP,  PAY4),
668*4882a593Smuzhiyun 	I40E_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
669*4882a593Smuzhiyun 	I40E_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
670*4882a593Smuzhiyun 
671*4882a593Smuzhiyun 	/* IPv4 --> GRE/NAT --> MAC/VLAN */
672*4882a593Smuzhiyun 	I40E_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	/* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
675*4882a593Smuzhiyun 	I40E_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
676*4882a593Smuzhiyun 	I40E_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
677*4882a593Smuzhiyun 	I40E_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP,  PAY4),
678*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(77),
679*4882a593Smuzhiyun 	I40E_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP,  PAY4),
680*4882a593Smuzhiyun 	I40E_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
681*4882a593Smuzhiyun 	I40E_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	/* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
684*4882a593Smuzhiyun 	I40E_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
685*4882a593Smuzhiyun 	I40E_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
686*4882a593Smuzhiyun 	I40E_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP,  PAY4),
687*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(84),
688*4882a593Smuzhiyun 	I40E_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP,  PAY4),
689*4882a593Smuzhiyun 	I40E_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
690*4882a593Smuzhiyun 	I40E_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun 	/* Non Tunneled IPv6 */
693*4882a593Smuzhiyun 	I40E_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
694*4882a593Smuzhiyun 	I40E_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
695*4882a593Smuzhiyun 	I40E_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY4),
696*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(91),
697*4882a593Smuzhiyun 	I40E_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),
698*4882a593Smuzhiyun 	I40E_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
699*4882a593Smuzhiyun 	I40E_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	/* IPv6 --> IPv4 */
702*4882a593Smuzhiyun 	I40E_PTT(95,  IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
703*4882a593Smuzhiyun 	I40E_PTT(96,  IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
704*4882a593Smuzhiyun 	I40E_PTT(97,  IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP,  PAY4),
705*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(98),
706*4882a593Smuzhiyun 	I40E_PTT(99,  IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP,  PAY4),
707*4882a593Smuzhiyun 	I40E_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
708*4882a593Smuzhiyun 	I40E_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	/* IPv6 --> IPv6 */
711*4882a593Smuzhiyun 	I40E_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
712*4882a593Smuzhiyun 	I40E_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
713*4882a593Smuzhiyun 	I40E_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP,  PAY4),
714*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(105),
715*4882a593Smuzhiyun 	I40E_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP,  PAY4),
716*4882a593Smuzhiyun 	I40E_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
717*4882a593Smuzhiyun 	I40E_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT */
720*4882a593Smuzhiyun 	I40E_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
721*4882a593Smuzhiyun 
722*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> IPv4 */
723*4882a593Smuzhiyun 	I40E_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
724*4882a593Smuzhiyun 	I40E_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
725*4882a593Smuzhiyun 	I40E_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP,  PAY4),
726*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(113),
727*4882a593Smuzhiyun 	I40E_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP,  PAY4),
728*4882a593Smuzhiyun 	I40E_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
729*4882a593Smuzhiyun 	I40E_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> IPv6 */
732*4882a593Smuzhiyun 	I40E_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
733*4882a593Smuzhiyun 	I40E_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
734*4882a593Smuzhiyun 	I40E_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP,  PAY4),
735*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(120),
736*4882a593Smuzhiyun 	I40E_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP,  PAY4),
737*4882a593Smuzhiyun 	I40E_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
738*4882a593Smuzhiyun 	I40E_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> MAC */
741*4882a593Smuzhiyun 	I40E_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> MAC -> IPv4 */
744*4882a593Smuzhiyun 	I40E_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
745*4882a593Smuzhiyun 	I40E_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
746*4882a593Smuzhiyun 	I40E_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP,  PAY4),
747*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(128),
748*4882a593Smuzhiyun 	I40E_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP,  PAY4),
749*4882a593Smuzhiyun 	I40E_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
750*4882a593Smuzhiyun 	I40E_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> MAC -> IPv6 */
753*4882a593Smuzhiyun 	I40E_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
754*4882a593Smuzhiyun 	I40E_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
755*4882a593Smuzhiyun 	I40E_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP,  PAY4),
756*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(135),
757*4882a593Smuzhiyun 	I40E_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP,  PAY4),
758*4882a593Smuzhiyun 	I40E_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
759*4882a593Smuzhiyun 	I40E_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> MAC/VLAN */
762*4882a593Smuzhiyun 	I40E_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
765*4882a593Smuzhiyun 	I40E_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
766*4882a593Smuzhiyun 	I40E_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
767*4882a593Smuzhiyun 	I40E_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP,  PAY4),
768*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(143),
769*4882a593Smuzhiyun 	I40E_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP,  PAY4),
770*4882a593Smuzhiyun 	I40E_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
771*4882a593Smuzhiyun 	I40E_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun 	/* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
774*4882a593Smuzhiyun 	I40E_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
775*4882a593Smuzhiyun 	I40E_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
776*4882a593Smuzhiyun 	I40E_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP,  PAY4),
777*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(150),
778*4882a593Smuzhiyun 	I40E_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP,  PAY4),
779*4882a593Smuzhiyun 	I40E_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
780*4882a593Smuzhiyun 	I40E_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	/* unused entries */
783*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(154),
784*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(155),
785*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(156),
786*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(157),
787*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(158),
788*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(159),
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(160),
791*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(161),
792*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(162),
793*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(163),
794*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(164),
795*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(165),
796*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(166),
797*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(167),
798*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(168),
799*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(169),
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(170),
802*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(171),
803*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(172),
804*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(173),
805*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(174),
806*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(175),
807*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(176),
808*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(177),
809*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(178),
810*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(179),
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(180),
813*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(181),
814*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(182),
815*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(183),
816*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(184),
817*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(185),
818*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(186),
819*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(187),
820*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(188),
821*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(189),
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(190),
824*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(191),
825*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(192),
826*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(193),
827*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(194),
828*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(195),
829*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(196),
830*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(197),
831*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(198),
832*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(199),
833*4882a593Smuzhiyun 
834*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(200),
835*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(201),
836*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(202),
837*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(203),
838*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(204),
839*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(205),
840*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(206),
841*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(207),
842*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(208),
843*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(209),
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(210),
846*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(211),
847*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(212),
848*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(213),
849*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(214),
850*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(215),
851*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(216),
852*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(217),
853*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(218),
854*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(219),
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(220),
857*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(221),
858*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(222),
859*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(223),
860*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(224),
861*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(225),
862*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(226),
863*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(227),
864*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(228),
865*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(229),
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(230),
868*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(231),
869*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(232),
870*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(233),
871*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(234),
872*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(235),
873*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(236),
874*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(237),
875*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(238),
876*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(239),
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(240),
879*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(241),
880*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(242),
881*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(243),
882*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(244),
883*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(245),
884*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(246),
885*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(247),
886*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(248),
887*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(249),
888*4882a593Smuzhiyun 
889*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(250),
890*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(251),
891*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(252),
892*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(253),
893*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(254),
894*4882a593Smuzhiyun 	I40E_PTT_UNUSED_ENTRY(255)
895*4882a593Smuzhiyun };
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun /**
898*4882a593Smuzhiyun  * i40e_init_shared_code - Initialize the shared code
899*4882a593Smuzhiyun  * @hw: pointer to hardware structure
900*4882a593Smuzhiyun  *
901*4882a593Smuzhiyun  * This assigns the MAC type and PHY code and inits the NVM.
902*4882a593Smuzhiyun  * Does not touch the hardware. This function must be called prior to any
903*4882a593Smuzhiyun  * other function in the shared code. The i40e_hw structure should be
904*4882a593Smuzhiyun  * memset to 0 prior to calling this function.  The following fields in
905*4882a593Smuzhiyun  * hw structure should be filled in prior to calling this function:
906*4882a593Smuzhiyun  * hw_addr, back, device_id, vendor_id, subsystem_device_id,
907*4882a593Smuzhiyun  * subsystem_vendor_id, and revision_id
908*4882a593Smuzhiyun  **/
i40e_init_shared_code(struct i40e_hw * hw)909*4882a593Smuzhiyun i40e_status i40e_init_shared_code(struct i40e_hw *hw)
910*4882a593Smuzhiyun {
911*4882a593Smuzhiyun 	i40e_status status = 0;
912*4882a593Smuzhiyun 	u32 port, ari, func_rid;
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun 	i40e_set_mac_type(hw);
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 	switch (hw->mac.type) {
917*4882a593Smuzhiyun 	case I40E_MAC_XL710:
918*4882a593Smuzhiyun 	case I40E_MAC_X722:
919*4882a593Smuzhiyun 		break;
920*4882a593Smuzhiyun 	default:
921*4882a593Smuzhiyun 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
922*4882a593Smuzhiyun 	}
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun 	hw->phy.get_link_info = true;
925*4882a593Smuzhiyun 
926*4882a593Smuzhiyun 	/* Determine port number and PF number*/
927*4882a593Smuzhiyun 	port = (rd32(hw, I40E_PFGEN_PORTNUM) & I40E_PFGEN_PORTNUM_PORT_NUM_MASK)
928*4882a593Smuzhiyun 					   >> I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
929*4882a593Smuzhiyun 	hw->port = (u8)port;
930*4882a593Smuzhiyun 	ari = (rd32(hw, I40E_GLPCI_CAPSUP) & I40E_GLPCI_CAPSUP_ARI_EN_MASK) >>
931*4882a593Smuzhiyun 						 I40E_GLPCI_CAPSUP_ARI_EN_SHIFT;
932*4882a593Smuzhiyun 	func_rid = rd32(hw, I40E_PF_FUNC_RID);
933*4882a593Smuzhiyun 	if (ari)
934*4882a593Smuzhiyun 		hw->pf_id = (u8)(func_rid & 0xff);
935*4882a593Smuzhiyun 	else
936*4882a593Smuzhiyun 		hw->pf_id = (u8)(func_rid & 0x7);
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 	status = i40e_init_nvm(hw);
939*4882a593Smuzhiyun 	return status;
940*4882a593Smuzhiyun }
941*4882a593Smuzhiyun 
942*4882a593Smuzhiyun /**
943*4882a593Smuzhiyun  * i40e_aq_mac_address_read - Retrieve the MAC addresses
944*4882a593Smuzhiyun  * @hw: pointer to the hw struct
945*4882a593Smuzhiyun  * @flags: a return indicator of what addresses were added to the addr store
946*4882a593Smuzhiyun  * @addrs: the requestor's mac addr store
947*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
948*4882a593Smuzhiyun  **/
i40e_aq_mac_address_read(struct i40e_hw * hw,u16 * flags,struct i40e_aqc_mac_address_read_data * addrs,struct i40e_asq_cmd_details * cmd_details)949*4882a593Smuzhiyun static i40e_status i40e_aq_mac_address_read(struct i40e_hw *hw,
950*4882a593Smuzhiyun 				   u16 *flags,
951*4882a593Smuzhiyun 				   struct i40e_aqc_mac_address_read_data *addrs,
952*4882a593Smuzhiyun 				   struct i40e_asq_cmd_details *cmd_details)
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
955*4882a593Smuzhiyun 	struct i40e_aqc_mac_address_read *cmd_data =
956*4882a593Smuzhiyun 		(struct i40e_aqc_mac_address_read *)&desc.params.raw;
957*4882a593Smuzhiyun 	i40e_status status;
958*4882a593Smuzhiyun 
959*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_mac_address_read);
960*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF);
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, addrs,
963*4882a593Smuzhiyun 				       sizeof(*addrs), cmd_details);
964*4882a593Smuzhiyun 	*flags = le16_to_cpu(cmd_data->command_flags);
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun 	return status;
967*4882a593Smuzhiyun }
968*4882a593Smuzhiyun 
969*4882a593Smuzhiyun /**
970*4882a593Smuzhiyun  * i40e_aq_mac_address_write - Change the MAC addresses
971*4882a593Smuzhiyun  * @hw: pointer to the hw struct
972*4882a593Smuzhiyun  * @flags: indicates which MAC to be written
973*4882a593Smuzhiyun  * @mac_addr: address to write
974*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
975*4882a593Smuzhiyun  **/
i40e_aq_mac_address_write(struct i40e_hw * hw,u16 flags,u8 * mac_addr,struct i40e_asq_cmd_details * cmd_details)976*4882a593Smuzhiyun i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
977*4882a593Smuzhiyun 				    u16 flags, u8 *mac_addr,
978*4882a593Smuzhiyun 				    struct i40e_asq_cmd_details *cmd_details)
979*4882a593Smuzhiyun {
980*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
981*4882a593Smuzhiyun 	struct i40e_aqc_mac_address_write *cmd_data =
982*4882a593Smuzhiyun 		(struct i40e_aqc_mac_address_write *)&desc.params.raw;
983*4882a593Smuzhiyun 	i40e_status status;
984*4882a593Smuzhiyun 
985*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
986*4882a593Smuzhiyun 					  i40e_aqc_opc_mac_address_write);
987*4882a593Smuzhiyun 	cmd_data->command_flags = cpu_to_le16(flags);
988*4882a593Smuzhiyun 	cmd_data->mac_sah = cpu_to_le16((u16)mac_addr[0] << 8 | mac_addr[1]);
989*4882a593Smuzhiyun 	cmd_data->mac_sal = cpu_to_le32(((u32)mac_addr[2] << 24) |
990*4882a593Smuzhiyun 					((u32)mac_addr[3] << 16) |
991*4882a593Smuzhiyun 					((u32)mac_addr[4] << 8) |
992*4882a593Smuzhiyun 					mac_addr[5]);
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 	return status;
997*4882a593Smuzhiyun }
998*4882a593Smuzhiyun 
999*4882a593Smuzhiyun /**
1000*4882a593Smuzhiyun  * i40e_get_mac_addr - get MAC address
1001*4882a593Smuzhiyun  * @hw: pointer to the HW structure
1002*4882a593Smuzhiyun  * @mac_addr: pointer to MAC address
1003*4882a593Smuzhiyun  *
1004*4882a593Smuzhiyun  * Reads the adapter's MAC address from register
1005*4882a593Smuzhiyun  **/
i40e_get_mac_addr(struct i40e_hw * hw,u8 * mac_addr)1006*4882a593Smuzhiyun i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
1007*4882a593Smuzhiyun {
1008*4882a593Smuzhiyun 	struct i40e_aqc_mac_address_read_data addrs;
1009*4882a593Smuzhiyun 	i40e_status status;
1010*4882a593Smuzhiyun 	u16 flags = 0;
1011*4882a593Smuzhiyun 
1012*4882a593Smuzhiyun 	status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	if (flags & I40E_AQC_LAN_ADDR_VALID)
1015*4882a593Smuzhiyun 		ether_addr_copy(mac_addr, addrs.pf_lan_mac);
1016*4882a593Smuzhiyun 
1017*4882a593Smuzhiyun 	return status;
1018*4882a593Smuzhiyun }
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun /**
1021*4882a593Smuzhiyun  * i40e_get_port_mac_addr - get Port MAC address
1022*4882a593Smuzhiyun  * @hw: pointer to the HW structure
1023*4882a593Smuzhiyun  * @mac_addr: pointer to Port MAC address
1024*4882a593Smuzhiyun  *
1025*4882a593Smuzhiyun  * Reads the adapter's Port MAC address
1026*4882a593Smuzhiyun  **/
i40e_get_port_mac_addr(struct i40e_hw * hw,u8 * mac_addr)1027*4882a593Smuzhiyun i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
1028*4882a593Smuzhiyun {
1029*4882a593Smuzhiyun 	struct i40e_aqc_mac_address_read_data addrs;
1030*4882a593Smuzhiyun 	i40e_status status;
1031*4882a593Smuzhiyun 	u16 flags = 0;
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun 	status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
1034*4882a593Smuzhiyun 	if (status)
1035*4882a593Smuzhiyun 		return status;
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun 	if (flags & I40E_AQC_PORT_ADDR_VALID)
1038*4882a593Smuzhiyun 		ether_addr_copy(mac_addr, addrs.port_mac);
1039*4882a593Smuzhiyun 	else
1040*4882a593Smuzhiyun 		status = I40E_ERR_INVALID_MAC_ADDR;
1041*4882a593Smuzhiyun 
1042*4882a593Smuzhiyun 	return status;
1043*4882a593Smuzhiyun }
1044*4882a593Smuzhiyun 
1045*4882a593Smuzhiyun /**
1046*4882a593Smuzhiyun  * i40e_pre_tx_queue_cfg - pre tx queue configure
1047*4882a593Smuzhiyun  * @hw: pointer to the HW structure
1048*4882a593Smuzhiyun  * @queue: target PF queue index
1049*4882a593Smuzhiyun  * @enable: state change request
1050*4882a593Smuzhiyun  *
1051*4882a593Smuzhiyun  * Handles hw requirement to indicate intention to enable
1052*4882a593Smuzhiyun  * or disable target queue.
1053*4882a593Smuzhiyun  **/
i40e_pre_tx_queue_cfg(struct i40e_hw * hw,u32 queue,bool enable)1054*4882a593Smuzhiyun void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
1055*4882a593Smuzhiyun {
1056*4882a593Smuzhiyun 	u32 abs_queue_idx = hw->func_caps.base_queue + queue;
1057*4882a593Smuzhiyun 	u32 reg_block = 0;
1058*4882a593Smuzhiyun 	u32 reg_val;
1059*4882a593Smuzhiyun 
1060*4882a593Smuzhiyun 	if (abs_queue_idx >= 128) {
1061*4882a593Smuzhiyun 		reg_block = abs_queue_idx / 128;
1062*4882a593Smuzhiyun 		abs_queue_idx %= 128;
1063*4882a593Smuzhiyun 	}
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun 	reg_val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
1066*4882a593Smuzhiyun 	reg_val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
1067*4882a593Smuzhiyun 	reg_val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun 	if (enable)
1070*4882a593Smuzhiyun 		reg_val |= I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK;
1071*4882a593Smuzhiyun 	else
1072*4882a593Smuzhiyun 		reg_val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun 	wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val);
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun 
1077*4882a593Smuzhiyun /**
1078*4882a593Smuzhiyun  *  i40e_read_pba_string - Reads part number string from EEPROM
1079*4882a593Smuzhiyun  *  @hw: pointer to hardware structure
1080*4882a593Smuzhiyun  *  @pba_num: stores the part number string from the EEPROM
1081*4882a593Smuzhiyun  *  @pba_num_size: part number string buffer length
1082*4882a593Smuzhiyun  *
1083*4882a593Smuzhiyun  *  Reads the part number string from the EEPROM.
1084*4882a593Smuzhiyun  **/
i40e_read_pba_string(struct i40e_hw * hw,u8 * pba_num,u32 pba_num_size)1085*4882a593Smuzhiyun i40e_status i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
1086*4882a593Smuzhiyun 				 u32 pba_num_size)
1087*4882a593Smuzhiyun {
1088*4882a593Smuzhiyun 	i40e_status status = 0;
1089*4882a593Smuzhiyun 	u16 pba_word = 0;
1090*4882a593Smuzhiyun 	u16 pba_size = 0;
1091*4882a593Smuzhiyun 	u16 pba_ptr = 0;
1092*4882a593Smuzhiyun 	u16 i = 0;
1093*4882a593Smuzhiyun 
1094*4882a593Smuzhiyun 	status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
1095*4882a593Smuzhiyun 	if (status || (pba_word != 0xFAFA)) {
1096*4882a593Smuzhiyun 		hw_dbg(hw, "Failed to read PBA flags or flag is invalid.\n");
1097*4882a593Smuzhiyun 		return status;
1098*4882a593Smuzhiyun 	}
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun 	status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr);
1101*4882a593Smuzhiyun 	if (status) {
1102*4882a593Smuzhiyun 		hw_dbg(hw, "Failed to read PBA Block pointer.\n");
1103*4882a593Smuzhiyun 		return status;
1104*4882a593Smuzhiyun 	}
1105*4882a593Smuzhiyun 
1106*4882a593Smuzhiyun 	status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
1107*4882a593Smuzhiyun 	if (status) {
1108*4882a593Smuzhiyun 		hw_dbg(hw, "Failed to read PBA Block size.\n");
1109*4882a593Smuzhiyun 		return status;
1110*4882a593Smuzhiyun 	}
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun 	/* Subtract one to get PBA word count (PBA Size word is included in
1113*4882a593Smuzhiyun 	 * total size)
1114*4882a593Smuzhiyun 	 */
1115*4882a593Smuzhiyun 	pba_size--;
1116*4882a593Smuzhiyun 	if (pba_num_size < (((u32)pba_size * 2) + 1)) {
1117*4882a593Smuzhiyun 		hw_dbg(hw, "Buffer too small for PBA data.\n");
1118*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
1119*4882a593Smuzhiyun 	}
1120*4882a593Smuzhiyun 
1121*4882a593Smuzhiyun 	for (i = 0; i < pba_size; i++) {
1122*4882a593Smuzhiyun 		status = i40e_read_nvm_word(hw, (pba_ptr + 1) + i, &pba_word);
1123*4882a593Smuzhiyun 		if (status) {
1124*4882a593Smuzhiyun 			hw_dbg(hw, "Failed to read PBA Block word %d.\n", i);
1125*4882a593Smuzhiyun 			return status;
1126*4882a593Smuzhiyun 		}
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun 		pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
1129*4882a593Smuzhiyun 		pba_num[(i * 2) + 1] = pba_word & 0xFF;
1130*4882a593Smuzhiyun 	}
1131*4882a593Smuzhiyun 	pba_num[(pba_size * 2)] = '\0';
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	return status;
1134*4882a593Smuzhiyun }
1135*4882a593Smuzhiyun 
1136*4882a593Smuzhiyun /**
1137*4882a593Smuzhiyun  * i40e_get_media_type - Gets media type
1138*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
1139*4882a593Smuzhiyun  **/
i40e_get_media_type(struct i40e_hw * hw)1140*4882a593Smuzhiyun static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
1141*4882a593Smuzhiyun {
1142*4882a593Smuzhiyun 	enum i40e_media_type media;
1143*4882a593Smuzhiyun 
1144*4882a593Smuzhiyun 	switch (hw->phy.link_info.phy_type) {
1145*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_SR:
1146*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_LR:
1147*4882a593Smuzhiyun 	case I40E_PHY_TYPE_1000BASE_SX:
1148*4882a593Smuzhiyun 	case I40E_PHY_TYPE_1000BASE_LX:
1149*4882a593Smuzhiyun 	case I40E_PHY_TYPE_40GBASE_SR4:
1150*4882a593Smuzhiyun 	case I40E_PHY_TYPE_40GBASE_LR4:
1151*4882a593Smuzhiyun 	case I40E_PHY_TYPE_25GBASE_LR:
1152*4882a593Smuzhiyun 	case I40E_PHY_TYPE_25GBASE_SR:
1153*4882a593Smuzhiyun 		media = I40E_MEDIA_TYPE_FIBER;
1154*4882a593Smuzhiyun 		break;
1155*4882a593Smuzhiyun 	case I40E_PHY_TYPE_100BASE_TX:
1156*4882a593Smuzhiyun 	case I40E_PHY_TYPE_1000BASE_T:
1157*4882a593Smuzhiyun 	case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
1158*4882a593Smuzhiyun 	case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
1159*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_T:
1160*4882a593Smuzhiyun 		media = I40E_MEDIA_TYPE_BASET;
1161*4882a593Smuzhiyun 		break;
1162*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_CR1_CU:
1163*4882a593Smuzhiyun 	case I40E_PHY_TYPE_40GBASE_CR4_CU:
1164*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_CR1:
1165*4882a593Smuzhiyun 	case I40E_PHY_TYPE_40GBASE_CR4:
1166*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_SFPP_CU:
1167*4882a593Smuzhiyun 	case I40E_PHY_TYPE_40GBASE_AOC:
1168*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_AOC:
1169*4882a593Smuzhiyun 	case I40E_PHY_TYPE_25GBASE_CR:
1170*4882a593Smuzhiyun 	case I40E_PHY_TYPE_25GBASE_AOC:
1171*4882a593Smuzhiyun 	case I40E_PHY_TYPE_25GBASE_ACC:
1172*4882a593Smuzhiyun 		media = I40E_MEDIA_TYPE_DA;
1173*4882a593Smuzhiyun 		break;
1174*4882a593Smuzhiyun 	case I40E_PHY_TYPE_1000BASE_KX:
1175*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_KX4:
1176*4882a593Smuzhiyun 	case I40E_PHY_TYPE_10GBASE_KR:
1177*4882a593Smuzhiyun 	case I40E_PHY_TYPE_40GBASE_KR4:
1178*4882a593Smuzhiyun 	case I40E_PHY_TYPE_20GBASE_KR2:
1179*4882a593Smuzhiyun 	case I40E_PHY_TYPE_25GBASE_KR:
1180*4882a593Smuzhiyun 		media = I40E_MEDIA_TYPE_BACKPLANE;
1181*4882a593Smuzhiyun 		break;
1182*4882a593Smuzhiyun 	case I40E_PHY_TYPE_SGMII:
1183*4882a593Smuzhiyun 	case I40E_PHY_TYPE_XAUI:
1184*4882a593Smuzhiyun 	case I40E_PHY_TYPE_XFI:
1185*4882a593Smuzhiyun 	case I40E_PHY_TYPE_XLAUI:
1186*4882a593Smuzhiyun 	case I40E_PHY_TYPE_XLPPI:
1187*4882a593Smuzhiyun 	default:
1188*4882a593Smuzhiyun 		media = I40E_MEDIA_TYPE_UNKNOWN;
1189*4882a593Smuzhiyun 		break;
1190*4882a593Smuzhiyun 	}
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 	return media;
1193*4882a593Smuzhiyun }
1194*4882a593Smuzhiyun 
1195*4882a593Smuzhiyun /**
1196*4882a593Smuzhiyun  * i40e_poll_globr - Poll for Global Reset completion
1197*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
1198*4882a593Smuzhiyun  * @retry_limit: how many times to retry before failure
1199*4882a593Smuzhiyun  **/
i40e_poll_globr(struct i40e_hw * hw,u32 retry_limit)1200*4882a593Smuzhiyun static i40e_status i40e_poll_globr(struct i40e_hw *hw,
1201*4882a593Smuzhiyun 				   u32 retry_limit)
1202*4882a593Smuzhiyun {
1203*4882a593Smuzhiyun 	u32 cnt, reg = 0;
1204*4882a593Smuzhiyun 
1205*4882a593Smuzhiyun 	for (cnt = 0; cnt < retry_limit; cnt++) {
1206*4882a593Smuzhiyun 		reg = rd32(hw, I40E_GLGEN_RSTAT);
1207*4882a593Smuzhiyun 		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
1208*4882a593Smuzhiyun 			return 0;
1209*4882a593Smuzhiyun 		msleep(100);
1210*4882a593Smuzhiyun 	}
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 	hw_dbg(hw, "Global reset failed.\n");
1213*4882a593Smuzhiyun 	hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg);
1214*4882a593Smuzhiyun 
1215*4882a593Smuzhiyun 	return I40E_ERR_RESET_FAILED;
1216*4882a593Smuzhiyun }
1217*4882a593Smuzhiyun 
1218*4882a593Smuzhiyun #define I40E_PF_RESET_WAIT_COUNT_A0	200
1219*4882a593Smuzhiyun #define I40E_PF_RESET_WAIT_COUNT	200
1220*4882a593Smuzhiyun /**
1221*4882a593Smuzhiyun  * i40e_pf_reset - Reset the PF
1222*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
1223*4882a593Smuzhiyun  *
1224*4882a593Smuzhiyun  * Assuming someone else has triggered a global reset,
1225*4882a593Smuzhiyun  * assure the global reset is complete and then reset the PF
1226*4882a593Smuzhiyun  **/
i40e_pf_reset(struct i40e_hw * hw)1227*4882a593Smuzhiyun i40e_status i40e_pf_reset(struct i40e_hw *hw)
1228*4882a593Smuzhiyun {
1229*4882a593Smuzhiyun 	u32 cnt = 0;
1230*4882a593Smuzhiyun 	u32 cnt1 = 0;
1231*4882a593Smuzhiyun 	u32 reg = 0;
1232*4882a593Smuzhiyun 	u32 grst_del;
1233*4882a593Smuzhiyun 
1234*4882a593Smuzhiyun 	/* Poll for Global Reset steady state in case of recent GRST.
1235*4882a593Smuzhiyun 	 * The grst delay value is in 100ms units, and we'll wait a
1236*4882a593Smuzhiyun 	 * couple counts longer to be sure we don't just miss the end.
1237*4882a593Smuzhiyun 	 */
1238*4882a593Smuzhiyun 	grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
1239*4882a593Smuzhiyun 		    I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
1240*4882a593Smuzhiyun 		    I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
1241*4882a593Smuzhiyun 
1242*4882a593Smuzhiyun 	/* It can take upto 15 secs for GRST steady state.
1243*4882a593Smuzhiyun 	 * Bump it to 16 secs max to be safe.
1244*4882a593Smuzhiyun 	 */
1245*4882a593Smuzhiyun 	grst_del = grst_del * 20;
1246*4882a593Smuzhiyun 
1247*4882a593Smuzhiyun 	for (cnt = 0; cnt < grst_del; cnt++) {
1248*4882a593Smuzhiyun 		reg = rd32(hw, I40E_GLGEN_RSTAT);
1249*4882a593Smuzhiyun 		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
1250*4882a593Smuzhiyun 			break;
1251*4882a593Smuzhiyun 		msleep(100);
1252*4882a593Smuzhiyun 	}
1253*4882a593Smuzhiyun 	if (reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
1254*4882a593Smuzhiyun 		hw_dbg(hw, "Global reset polling failed to complete.\n");
1255*4882a593Smuzhiyun 		return I40E_ERR_RESET_FAILED;
1256*4882a593Smuzhiyun 	}
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun 	/* Now Wait for the FW to be ready */
1259*4882a593Smuzhiyun 	for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) {
1260*4882a593Smuzhiyun 		reg = rd32(hw, I40E_GLNVM_ULD);
1261*4882a593Smuzhiyun 		reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1262*4882a593Smuzhiyun 			I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK);
1263*4882a593Smuzhiyun 		if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1264*4882a593Smuzhiyun 			    I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK)) {
1265*4882a593Smuzhiyun 			hw_dbg(hw, "Core and Global modules ready %d\n", cnt1);
1266*4882a593Smuzhiyun 			break;
1267*4882a593Smuzhiyun 		}
1268*4882a593Smuzhiyun 		usleep_range(10000, 20000);
1269*4882a593Smuzhiyun 	}
1270*4882a593Smuzhiyun 	if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1271*4882a593Smuzhiyun 		     I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) {
1272*4882a593Smuzhiyun 		hw_dbg(hw, "wait for FW Reset complete timedout\n");
1273*4882a593Smuzhiyun 		hw_dbg(hw, "I40E_GLNVM_ULD = 0x%x\n", reg);
1274*4882a593Smuzhiyun 		return I40E_ERR_RESET_FAILED;
1275*4882a593Smuzhiyun 	}
1276*4882a593Smuzhiyun 
1277*4882a593Smuzhiyun 	/* If there was a Global Reset in progress when we got here,
1278*4882a593Smuzhiyun 	 * we don't need to do the PF Reset
1279*4882a593Smuzhiyun 	 */
1280*4882a593Smuzhiyun 	if (!cnt) {
1281*4882a593Smuzhiyun 		u32 reg2 = 0;
1282*4882a593Smuzhiyun 		if (hw->revision_id == 0)
1283*4882a593Smuzhiyun 			cnt = I40E_PF_RESET_WAIT_COUNT_A0;
1284*4882a593Smuzhiyun 		else
1285*4882a593Smuzhiyun 			cnt = I40E_PF_RESET_WAIT_COUNT;
1286*4882a593Smuzhiyun 		reg = rd32(hw, I40E_PFGEN_CTRL);
1287*4882a593Smuzhiyun 		wr32(hw, I40E_PFGEN_CTRL,
1288*4882a593Smuzhiyun 		     (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
1289*4882a593Smuzhiyun 		for (; cnt; cnt--) {
1290*4882a593Smuzhiyun 			reg = rd32(hw, I40E_PFGEN_CTRL);
1291*4882a593Smuzhiyun 			if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
1292*4882a593Smuzhiyun 				break;
1293*4882a593Smuzhiyun 			reg2 = rd32(hw, I40E_GLGEN_RSTAT);
1294*4882a593Smuzhiyun 			if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK)
1295*4882a593Smuzhiyun 				break;
1296*4882a593Smuzhiyun 			usleep_range(1000, 2000);
1297*4882a593Smuzhiyun 		}
1298*4882a593Smuzhiyun 		if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
1299*4882a593Smuzhiyun 			if (i40e_poll_globr(hw, grst_del))
1300*4882a593Smuzhiyun 				return I40E_ERR_RESET_FAILED;
1301*4882a593Smuzhiyun 		} else if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
1302*4882a593Smuzhiyun 			hw_dbg(hw, "PF reset polling failed to complete.\n");
1303*4882a593Smuzhiyun 			return I40E_ERR_RESET_FAILED;
1304*4882a593Smuzhiyun 		}
1305*4882a593Smuzhiyun 	}
1306*4882a593Smuzhiyun 
1307*4882a593Smuzhiyun 	i40e_clear_pxe_mode(hw);
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun 	return 0;
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun 
1312*4882a593Smuzhiyun /**
1313*4882a593Smuzhiyun  * i40e_clear_hw - clear out any left over hw state
1314*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1315*4882a593Smuzhiyun  *
1316*4882a593Smuzhiyun  * Clear queues and interrupts, typically called at init time,
1317*4882a593Smuzhiyun  * but after the capabilities have been found so we know how many
1318*4882a593Smuzhiyun  * queues and msix vectors have been allocated.
1319*4882a593Smuzhiyun  **/
i40e_clear_hw(struct i40e_hw * hw)1320*4882a593Smuzhiyun void i40e_clear_hw(struct i40e_hw *hw)
1321*4882a593Smuzhiyun {
1322*4882a593Smuzhiyun 	u32 num_queues, base_queue;
1323*4882a593Smuzhiyun 	u32 num_pf_int;
1324*4882a593Smuzhiyun 	u32 num_vf_int;
1325*4882a593Smuzhiyun 	u32 num_vfs;
1326*4882a593Smuzhiyun 	u32 i, j;
1327*4882a593Smuzhiyun 	u32 val;
1328*4882a593Smuzhiyun 	u32 eol = 0x7ff;
1329*4882a593Smuzhiyun 
1330*4882a593Smuzhiyun 	/* get number of interrupts, queues, and VFs */
1331*4882a593Smuzhiyun 	val = rd32(hw, I40E_GLPCI_CNF2);
1332*4882a593Smuzhiyun 	num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
1333*4882a593Smuzhiyun 		     I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
1334*4882a593Smuzhiyun 	num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >>
1335*4882a593Smuzhiyun 		     I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT;
1336*4882a593Smuzhiyun 
1337*4882a593Smuzhiyun 	val = rd32(hw, I40E_PFLAN_QALLOC);
1338*4882a593Smuzhiyun 	base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >>
1339*4882a593Smuzhiyun 		     I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
1340*4882a593Smuzhiyun 	j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
1341*4882a593Smuzhiyun 	    I40E_PFLAN_QALLOC_LASTQ_SHIFT;
1342*4882a593Smuzhiyun 	if (val & I40E_PFLAN_QALLOC_VALID_MASK)
1343*4882a593Smuzhiyun 		num_queues = (j - base_queue) + 1;
1344*4882a593Smuzhiyun 	else
1345*4882a593Smuzhiyun 		num_queues = 0;
1346*4882a593Smuzhiyun 
1347*4882a593Smuzhiyun 	val = rd32(hw, I40E_PF_VT_PFALLOC);
1348*4882a593Smuzhiyun 	i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >>
1349*4882a593Smuzhiyun 	    I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
1350*4882a593Smuzhiyun 	j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
1351*4882a593Smuzhiyun 	    I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
1352*4882a593Smuzhiyun 	if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
1353*4882a593Smuzhiyun 		num_vfs = (j - i) + 1;
1354*4882a593Smuzhiyun 	else
1355*4882a593Smuzhiyun 		num_vfs = 0;
1356*4882a593Smuzhiyun 
1357*4882a593Smuzhiyun 	/* stop all the interrupts */
1358*4882a593Smuzhiyun 	wr32(hw, I40E_PFINT_ICR0_ENA, 0);
1359*4882a593Smuzhiyun 	val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
1360*4882a593Smuzhiyun 	for (i = 0; i < num_pf_int - 2; i++)
1361*4882a593Smuzhiyun 		wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
1362*4882a593Smuzhiyun 
1363*4882a593Smuzhiyun 	/* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
1364*4882a593Smuzhiyun 	val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
1365*4882a593Smuzhiyun 	wr32(hw, I40E_PFINT_LNKLST0, val);
1366*4882a593Smuzhiyun 	for (i = 0; i < num_pf_int - 2; i++)
1367*4882a593Smuzhiyun 		wr32(hw, I40E_PFINT_LNKLSTN(i), val);
1368*4882a593Smuzhiyun 	val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
1369*4882a593Smuzhiyun 	for (i = 0; i < num_vfs; i++)
1370*4882a593Smuzhiyun 		wr32(hw, I40E_VPINT_LNKLST0(i), val);
1371*4882a593Smuzhiyun 	for (i = 0; i < num_vf_int - 2; i++)
1372*4882a593Smuzhiyun 		wr32(hw, I40E_VPINT_LNKLSTN(i), val);
1373*4882a593Smuzhiyun 
1374*4882a593Smuzhiyun 	/* warn the HW of the coming Tx disables */
1375*4882a593Smuzhiyun 	for (i = 0; i < num_queues; i++) {
1376*4882a593Smuzhiyun 		u32 abs_queue_idx = base_queue + i;
1377*4882a593Smuzhiyun 		u32 reg_block = 0;
1378*4882a593Smuzhiyun 
1379*4882a593Smuzhiyun 		if (abs_queue_idx >= 128) {
1380*4882a593Smuzhiyun 			reg_block = abs_queue_idx / 128;
1381*4882a593Smuzhiyun 			abs_queue_idx %= 128;
1382*4882a593Smuzhiyun 		}
1383*4882a593Smuzhiyun 
1384*4882a593Smuzhiyun 		val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
1385*4882a593Smuzhiyun 		val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
1386*4882a593Smuzhiyun 		val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
1387*4882a593Smuzhiyun 		val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
1388*4882a593Smuzhiyun 
1389*4882a593Smuzhiyun 		wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), val);
1390*4882a593Smuzhiyun 	}
1391*4882a593Smuzhiyun 	udelay(400);
1392*4882a593Smuzhiyun 
1393*4882a593Smuzhiyun 	/* stop all the queues */
1394*4882a593Smuzhiyun 	for (i = 0; i < num_queues; i++) {
1395*4882a593Smuzhiyun 		wr32(hw, I40E_QINT_TQCTL(i), 0);
1396*4882a593Smuzhiyun 		wr32(hw, I40E_QTX_ENA(i), 0);
1397*4882a593Smuzhiyun 		wr32(hw, I40E_QINT_RQCTL(i), 0);
1398*4882a593Smuzhiyun 		wr32(hw, I40E_QRX_ENA(i), 0);
1399*4882a593Smuzhiyun 	}
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun 	/* short wait for all queue disables to settle */
1402*4882a593Smuzhiyun 	udelay(50);
1403*4882a593Smuzhiyun }
1404*4882a593Smuzhiyun 
1405*4882a593Smuzhiyun /**
1406*4882a593Smuzhiyun  * i40e_clear_pxe_mode - clear pxe operations mode
1407*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1408*4882a593Smuzhiyun  *
1409*4882a593Smuzhiyun  * Make sure all PXE mode settings are cleared, including things
1410*4882a593Smuzhiyun  * like descriptor fetch/write-back mode.
1411*4882a593Smuzhiyun  **/
i40e_clear_pxe_mode(struct i40e_hw * hw)1412*4882a593Smuzhiyun void i40e_clear_pxe_mode(struct i40e_hw *hw)
1413*4882a593Smuzhiyun {
1414*4882a593Smuzhiyun 	u32 reg;
1415*4882a593Smuzhiyun 
1416*4882a593Smuzhiyun 	if (i40e_check_asq_alive(hw))
1417*4882a593Smuzhiyun 		i40e_aq_clear_pxe_mode(hw, NULL);
1418*4882a593Smuzhiyun 
1419*4882a593Smuzhiyun 	/* Clear single descriptor fetch/write-back mode */
1420*4882a593Smuzhiyun 	reg = rd32(hw, I40E_GLLAN_RCTL_0);
1421*4882a593Smuzhiyun 
1422*4882a593Smuzhiyun 	if (hw->revision_id == 0) {
1423*4882a593Smuzhiyun 		/* As a work around clear PXE_MODE instead of setting it */
1424*4882a593Smuzhiyun 		wr32(hw, I40E_GLLAN_RCTL_0, (reg & (~I40E_GLLAN_RCTL_0_PXE_MODE_MASK)));
1425*4882a593Smuzhiyun 	} else {
1426*4882a593Smuzhiyun 		wr32(hw, I40E_GLLAN_RCTL_0, (reg | I40E_GLLAN_RCTL_0_PXE_MODE_MASK));
1427*4882a593Smuzhiyun 	}
1428*4882a593Smuzhiyun }
1429*4882a593Smuzhiyun 
1430*4882a593Smuzhiyun /**
1431*4882a593Smuzhiyun  * i40e_led_is_mine - helper to find matching led
1432*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1433*4882a593Smuzhiyun  * @idx: index into GPIO registers
1434*4882a593Smuzhiyun  *
1435*4882a593Smuzhiyun  * returns: 0 if no match, otherwise the value of the GPIO_CTL register
1436*4882a593Smuzhiyun  */
i40e_led_is_mine(struct i40e_hw * hw,int idx)1437*4882a593Smuzhiyun static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
1438*4882a593Smuzhiyun {
1439*4882a593Smuzhiyun 	u32 gpio_val = 0;
1440*4882a593Smuzhiyun 	u32 port;
1441*4882a593Smuzhiyun 
1442*4882a593Smuzhiyun 	if (!I40E_IS_X710TL_DEVICE(hw->device_id) &&
1443*4882a593Smuzhiyun 	    !hw->func_caps.led[idx])
1444*4882a593Smuzhiyun 		return 0;
1445*4882a593Smuzhiyun 	gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx));
1446*4882a593Smuzhiyun 	port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >>
1447*4882a593Smuzhiyun 		I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT;
1448*4882a593Smuzhiyun 
1449*4882a593Smuzhiyun 	/* if PRT_NUM_NA is 1 then this LED is not port specific, OR
1450*4882a593Smuzhiyun 	 * if it is not our port then ignore
1451*4882a593Smuzhiyun 	 */
1452*4882a593Smuzhiyun 	if ((gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK) ||
1453*4882a593Smuzhiyun 	    (port != hw->port))
1454*4882a593Smuzhiyun 		return 0;
1455*4882a593Smuzhiyun 
1456*4882a593Smuzhiyun 	return gpio_val;
1457*4882a593Smuzhiyun }
1458*4882a593Smuzhiyun 
1459*4882a593Smuzhiyun #define I40E_FW_LED BIT(4)
1460*4882a593Smuzhiyun #define I40E_LED_MODE_VALID (I40E_GLGEN_GPIO_CTL_LED_MODE_MASK >> \
1461*4882a593Smuzhiyun 			     I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
1462*4882a593Smuzhiyun 
1463*4882a593Smuzhiyun #define I40E_LED0 22
1464*4882a593Smuzhiyun 
1465*4882a593Smuzhiyun #define I40E_PIN_FUNC_SDP 0x0
1466*4882a593Smuzhiyun #define I40E_PIN_FUNC_LED 0x1
1467*4882a593Smuzhiyun 
1468*4882a593Smuzhiyun /**
1469*4882a593Smuzhiyun  * i40e_led_get - return current on/off mode
1470*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1471*4882a593Smuzhiyun  *
1472*4882a593Smuzhiyun  * The value returned is the 'mode' field as defined in the
1473*4882a593Smuzhiyun  * GPIO register definitions: 0x0 = off, 0xf = on, and other
1474*4882a593Smuzhiyun  * values are variations of possible behaviors relating to
1475*4882a593Smuzhiyun  * blink, link, and wire.
1476*4882a593Smuzhiyun  **/
i40e_led_get(struct i40e_hw * hw)1477*4882a593Smuzhiyun u32 i40e_led_get(struct i40e_hw *hw)
1478*4882a593Smuzhiyun {
1479*4882a593Smuzhiyun 	u32 mode = 0;
1480*4882a593Smuzhiyun 	int i;
1481*4882a593Smuzhiyun 
1482*4882a593Smuzhiyun 	/* as per the documentation GPIO 22-29 are the LED
1483*4882a593Smuzhiyun 	 * GPIO pins named LED0..LED7
1484*4882a593Smuzhiyun 	 */
1485*4882a593Smuzhiyun 	for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1486*4882a593Smuzhiyun 		u32 gpio_val = i40e_led_is_mine(hw, i);
1487*4882a593Smuzhiyun 
1488*4882a593Smuzhiyun 		if (!gpio_val)
1489*4882a593Smuzhiyun 			continue;
1490*4882a593Smuzhiyun 
1491*4882a593Smuzhiyun 		mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
1492*4882a593Smuzhiyun 			I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT;
1493*4882a593Smuzhiyun 		break;
1494*4882a593Smuzhiyun 	}
1495*4882a593Smuzhiyun 
1496*4882a593Smuzhiyun 	return mode;
1497*4882a593Smuzhiyun }
1498*4882a593Smuzhiyun 
1499*4882a593Smuzhiyun /**
1500*4882a593Smuzhiyun  * i40e_led_set - set new on/off mode
1501*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1502*4882a593Smuzhiyun  * @mode: 0=off, 0xf=on (else see manual for mode details)
1503*4882a593Smuzhiyun  * @blink: true if the LED should blink when on, false if steady
1504*4882a593Smuzhiyun  *
1505*4882a593Smuzhiyun  * if this function is used to turn on the blink it should
1506*4882a593Smuzhiyun  * be used to disable the blink when restoring the original state.
1507*4882a593Smuzhiyun  **/
i40e_led_set(struct i40e_hw * hw,u32 mode,bool blink)1508*4882a593Smuzhiyun void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
1509*4882a593Smuzhiyun {
1510*4882a593Smuzhiyun 	int i;
1511*4882a593Smuzhiyun 
1512*4882a593Smuzhiyun 	if (mode & ~I40E_LED_MODE_VALID) {
1513*4882a593Smuzhiyun 		hw_dbg(hw, "invalid mode passed in %X\n", mode);
1514*4882a593Smuzhiyun 		return;
1515*4882a593Smuzhiyun 	}
1516*4882a593Smuzhiyun 
1517*4882a593Smuzhiyun 	/* as per the documentation GPIO 22-29 are the LED
1518*4882a593Smuzhiyun 	 * GPIO pins named LED0..LED7
1519*4882a593Smuzhiyun 	 */
1520*4882a593Smuzhiyun 	for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1521*4882a593Smuzhiyun 		u32 gpio_val = i40e_led_is_mine(hw, i);
1522*4882a593Smuzhiyun 
1523*4882a593Smuzhiyun 		if (!gpio_val)
1524*4882a593Smuzhiyun 			continue;
1525*4882a593Smuzhiyun 
1526*4882a593Smuzhiyun 		if (I40E_IS_X710TL_DEVICE(hw->device_id)) {
1527*4882a593Smuzhiyun 			u32 pin_func = 0;
1528*4882a593Smuzhiyun 
1529*4882a593Smuzhiyun 			if (mode & I40E_FW_LED)
1530*4882a593Smuzhiyun 				pin_func = I40E_PIN_FUNC_SDP;
1531*4882a593Smuzhiyun 			else
1532*4882a593Smuzhiyun 				pin_func = I40E_PIN_FUNC_LED;
1533*4882a593Smuzhiyun 
1534*4882a593Smuzhiyun 			gpio_val &= ~I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK;
1535*4882a593Smuzhiyun 			gpio_val |= ((pin_func <<
1536*4882a593Smuzhiyun 				     I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT) &
1537*4882a593Smuzhiyun 				     I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK);
1538*4882a593Smuzhiyun 		}
1539*4882a593Smuzhiyun 		gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
1540*4882a593Smuzhiyun 		/* this & is a bit of paranoia, but serves as a range check */
1541*4882a593Smuzhiyun 		gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
1542*4882a593Smuzhiyun 			     I40E_GLGEN_GPIO_CTL_LED_MODE_MASK);
1543*4882a593Smuzhiyun 
1544*4882a593Smuzhiyun 		if (blink)
1545*4882a593Smuzhiyun 			gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
1546*4882a593Smuzhiyun 		else
1547*4882a593Smuzhiyun 			gpio_val &= ~BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
1548*4882a593Smuzhiyun 
1549*4882a593Smuzhiyun 		wr32(hw, I40E_GLGEN_GPIO_CTL(i), gpio_val);
1550*4882a593Smuzhiyun 		break;
1551*4882a593Smuzhiyun 	}
1552*4882a593Smuzhiyun }
1553*4882a593Smuzhiyun 
1554*4882a593Smuzhiyun /* Admin command wrappers */
1555*4882a593Smuzhiyun 
1556*4882a593Smuzhiyun /**
1557*4882a593Smuzhiyun  * i40e_aq_get_phy_capabilities
1558*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1559*4882a593Smuzhiyun  * @abilities: structure for PHY capabilities to be filled
1560*4882a593Smuzhiyun  * @qualified_modules: report Qualified Modules
1561*4882a593Smuzhiyun  * @report_init: report init capabilities (active are default)
1562*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1563*4882a593Smuzhiyun  *
1564*4882a593Smuzhiyun  * Returns the various PHY abilities supported on the Port.
1565*4882a593Smuzhiyun  **/
i40e_aq_get_phy_capabilities(struct i40e_hw * hw,bool qualified_modules,bool report_init,struct i40e_aq_get_phy_abilities_resp * abilities,struct i40e_asq_cmd_details * cmd_details)1566*4882a593Smuzhiyun i40e_status i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
1567*4882a593Smuzhiyun 			bool qualified_modules, bool report_init,
1568*4882a593Smuzhiyun 			struct i40e_aq_get_phy_abilities_resp *abilities,
1569*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details)
1570*4882a593Smuzhiyun {
1571*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1572*4882a593Smuzhiyun 	i40e_status status;
1573*4882a593Smuzhiyun 	u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
1574*4882a593Smuzhiyun 	u16 max_delay = I40E_MAX_PHY_TIMEOUT, total_delay = 0;
1575*4882a593Smuzhiyun 
1576*4882a593Smuzhiyun 	if (!abilities)
1577*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
1578*4882a593Smuzhiyun 
1579*4882a593Smuzhiyun 	do {
1580*4882a593Smuzhiyun 		i40e_fill_default_direct_cmd_desc(&desc,
1581*4882a593Smuzhiyun 					       i40e_aqc_opc_get_phy_abilities);
1582*4882a593Smuzhiyun 
1583*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
1584*4882a593Smuzhiyun 		if (abilities_size > I40E_AQ_LARGE_BUF)
1585*4882a593Smuzhiyun 			desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
1586*4882a593Smuzhiyun 
1587*4882a593Smuzhiyun 		if (qualified_modules)
1588*4882a593Smuzhiyun 			desc.params.external.param0 |=
1589*4882a593Smuzhiyun 			cpu_to_le32(I40E_AQ_PHY_REPORT_QUALIFIED_MODULES);
1590*4882a593Smuzhiyun 
1591*4882a593Smuzhiyun 		if (report_init)
1592*4882a593Smuzhiyun 			desc.params.external.param0 |=
1593*4882a593Smuzhiyun 			cpu_to_le32(I40E_AQ_PHY_REPORT_INITIAL_VALUES);
1594*4882a593Smuzhiyun 
1595*4882a593Smuzhiyun 		status = i40e_asq_send_command(hw, &desc, abilities,
1596*4882a593Smuzhiyun 					       abilities_size, cmd_details);
1597*4882a593Smuzhiyun 
1598*4882a593Smuzhiyun 		switch (hw->aq.asq_last_status) {
1599*4882a593Smuzhiyun 		case I40E_AQ_RC_EIO:
1600*4882a593Smuzhiyun 			status = I40E_ERR_UNKNOWN_PHY;
1601*4882a593Smuzhiyun 			break;
1602*4882a593Smuzhiyun 		case I40E_AQ_RC_EAGAIN:
1603*4882a593Smuzhiyun 			usleep_range(1000, 2000);
1604*4882a593Smuzhiyun 			total_delay++;
1605*4882a593Smuzhiyun 			status = I40E_ERR_TIMEOUT;
1606*4882a593Smuzhiyun 			break;
1607*4882a593Smuzhiyun 		/* also covers I40E_AQ_RC_OK */
1608*4882a593Smuzhiyun 		default:
1609*4882a593Smuzhiyun 			break;
1610*4882a593Smuzhiyun 		}
1611*4882a593Smuzhiyun 
1612*4882a593Smuzhiyun 	} while ((hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN) &&
1613*4882a593Smuzhiyun 		(total_delay < max_delay));
1614*4882a593Smuzhiyun 
1615*4882a593Smuzhiyun 	if (status)
1616*4882a593Smuzhiyun 		return status;
1617*4882a593Smuzhiyun 
1618*4882a593Smuzhiyun 	if (report_init) {
1619*4882a593Smuzhiyun 		if (hw->mac.type ==  I40E_MAC_XL710 &&
1620*4882a593Smuzhiyun 		    hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
1621*4882a593Smuzhiyun 		    hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
1622*4882a593Smuzhiyun 			status = i40e_aq_get_link_info(hw, true, NULL, NULL);
1623*4882a593Smuzhiyun 		} else {
1624*4882a593Smuzhiyun 			hw->phy.phy_types = le32_to_cpu(abilities->phy_type);
1625*4882a593Smuzhiyun 			hw->phy.phy_types |=
1626*4882a593Smuzhiyun 					((u64)abilities->phy_type_ext << 32);
1627*4882a593Smuzhiyun 		}
1628*4882a593Smuzhiyun 	}
1629*4882a593Smuzhiyun 
1630*4882a593Smuzhiyun 	return status;
1631*4882a593Smuzhiyun }
1632*4882a593Smuzhiyun 
1633*4882a593Smuzhiyun /**
1634*4882a593Smuzhiyun  * i40e_aq_set_phy_config
1635*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1636*4882a593Smuzhiyun  * @config: structure with PHY configuration to be set
1637*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1638*4882a593Smuzhiyun  *
1639*4882a593Smuzhiyun  * Set the various PHY configuration parameters
1640*4882a593Smuzhiyun  * supported on the Port.One or more of the Set PHY config parameters may be
1641*4882a593Smuzhiyun  * ignored in an MFP mode as the PF may not have the privilege to set some
1642*4882a593Smuzhiyun  * of the PHY Config parameters. This status will be indicated by the
1643*4882a593Smuzhiyun  * command response.
1644*4882a593Smuzhiyun  **/
i40e_aq_set_phy_config(struct i40e_hw * hw,struct i40e_aq_set_phy_config * config,struct i40e_asq_cmd_details * cmd_details)1645*4882a593Smuzhiyun enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
1646*4882a593Smuzhiyun 				struct i40e_aq_set_phy_config *config,
1647*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
1648*4882a593Smuzhiyun {
1649*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1650*4882a593Smuzhiyun 	struct i40e_aq_set_phy_config *cmd =
1651*4882a593Smuzhiyun 			(struct i40e_aq_set_phy_config *)&desc.params.raw;
1652*4882a593Smuzhiyun 	enum i40e_status_code status;
1653*4882a593Smuzhiyun 
1654*4882a593Smuzhiyun 	if (!config)
1655*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
1656*4882a593Smuzhiyun 
1657*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
1658*4882a593Smuzhiyun 					  i40e_aqc_opc_set_phy_config);
1659*4882a593Smuzhiyun 
1660*4882a593Smuzhiyun 	*cmd = *config;
1661*4882a593Smuzhiyun 
1662*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1663*4882a593Smuzhiyun 
1664*4882a593Smuzhiyun 	return status;
1665*4882a593Smuzhiyun }
1666*4882a593Smuzhiyun 
1667*4882a593Smuzhiyun static noinline_for_stack enum i40e_status_code
i40e_set_fc_status(struct i40e_hw * hw,struct i40e_aq_get_phy_abilities_resp * abilities,bool atomic_restart)1668*4882a593Smuzhiyun i40e_set_fc_status(struct i40e_hw *hw,
1669*4882a593Smuzhiyun 		   struct i40e_aq_get_phy_abilities_resp *abilities,
1670*4882a593Smuzhiyun 		   bool atomic_restart)
1671*4882a593Smuzhiyun {
1672*4882a593Smuzhiyun 	struct i40e_aq_set_phy_config config;
1673*4882a593Smuzhiyun 	enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
1674*4882a593Smuzhiyun 	u8 pause_mask = 0x0;
1675*4882a593Smuzhiyun 
1676*4882a593Smuzhiyun 	switch (fc_mode) {
1677*4882a593Smuzhiyun 	case I40E_FC_FULL:
1678*4882a593Smuzhiyun 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1679*4882a593Smuzhiyun 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1680*4882a593Smuzhiyun 		break;
1681*4882a593Smuzhiyun 	case I40E_FC_RX_PAUSE:
1682*4882a593Smuzhiyun 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1683*4882a593Smuzhiyun 		break;
1684*4882a593Smuzhiyun 	case I40E_FC_TX_PAUSE:
1685*4882a593Smuzhiyun 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1686*4882a593Smuzhiyun 		break;
1687*4882a593Smuzhiyun 	default:
1688*4882a593Smuzhiyun 		break;
1689*4882a593Smuzhiyun 	}
1690*4882a593Smuzhiyun 
1691*4882a593Smuzhiyun 	memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
1692*4882a593Smuzhiyun 	/* clear the old pause settings */
1693*4882a593Smuzhiyun 	config.abilities = abilities->abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
1694*4882a593Smuzhiyun 			   ~(I40E_AQ_PHY_FLAG_PAUSE_RX);
1695*4882a593Smuzhiyun 	/* set the new abilities */
1696*4882a593Smuzhiyun 	config.abilities |= pause_mask;
1697*4882a593Smuzhiyun 	/* If the abilities have changed, then set the new config */
1698*4882a593Smuzhiyun 	if (config.abilities == abilities->abilities)
1699*4882a593Smuzhiyun 		return 0;
1700*4882a593Smuzhiyun 
1701*4882a593Smuzhiyun 	/* Auto restart link so settings take effect */
1702*4882a593Smuzhiyun 	if (atomic_restart)
1703*4882a593Smuzhiyun 		config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
1704*4882a593Smuzhiyun 	/* Copy over all the old settings */
1705*4882a593Smuzhiyun 	config.phy_type = abilities->phy_type;
1706*4882a593Smuzhiyun 	config.phy_type_ext = abilities->phy_type_ext;
1707*4882a593Smuzhiyun 	config.link_speed = abilities->link_speed;
1708*4882a593Smuzhiyun 	config.eee_capability = abilities->eee_capability;
1709*4882a593Smuzhiyun 	config.eeer = abilities->eeer_val;
1710*4882a593Smuzhiyun 	config.low_power_ctrl = abilities->d3_lpan;
1711*4882a593Smuzhiyun 	config.fec_config = abilities->fec_cfg_curr_mod_ext_info &
1712*4882a593Smuzhiyun 			    I40E_AQ_PHY_FEC_CONFIG_MASK;
1713*4882a593Smuzhiyun 
1714*4882a593Smuzhiyun 	return i40e_aq_set_phy_config(hw, &config, NULL);
1715*4882a593Smuzhiyun }
1716*4882a593Smuzhiyun 
1717*4882a593Smuzhiyun /**
1718*4882a593Smuzhiyun  * i40e_set_fc
1719*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1720*4882a593Smuzhiyun  * @aq_failures: buffer to return AdminQ failure information
1721*4882a593Smuzhiyun  * @atomic_restart: whether to enable atomic link restart
1722*4882a593Smuzhiyun  *
1723*4882a593Smuzhiyun  * Set the requested flow control mode using set_phy_config.
1724*4882a593Smuzhiyun  **/
i40e_set_fc(struct i40e_hw * hw,u8 * aq_failures,bool atomic_restart)1725*4882a593Smuzhiyun enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
1726*4882a593Smuzhiyun 				  bool atomic_restart)
1727*4882a593Smuzhiyun {
1728*4882a593Smuzhiyun 	struct i40e_aq_get_phy_abilities_resp abilities;
1729*4882a593Smuzhiyun 	enum i40e_status_code status;
1730*4882a593Smuzhiyun 
1731*4882a593Smuzhiyun 	*aq_failures = 0x0;
1732*4882a593Smuzhiyun 
1733*4882a593Smuzhiyun 	/* Get the current phy config */
1734*4882a593Smuzhiyun 	status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
1735*4882a593Smuzhiyun 					      NULL);
1736*4882a593Smuzhiyun 	if (status) {
1737*4882a593Smuzhiyun 		*aq_failures |= I40E_SET_FC_AQ_FAIL_GET;
1738*4882a593Smuzhiyun 		return status;
1739*4882a593Smuzhiyun 	}
1740*4882a593Smuzhiyun 
1741*4882a593Smuzhiyun 	status = i40e_set_fc_status(hw, &abilities, atomic_restart);
1742*4882a593Smuzhiyun 	if (status)
1743*4882a593Smuzhiyun 		*aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
1744*4882a593Smuzhiyun 
1745*4882a593Smuzhiyun 	/* Update the link info */
1746*4882a593Smuzhiyun 	status = i40e_update_link_info(hw);
1747*4882a593Smuzhiyun 	if (status) {
1748*4882a593Smuzhiyun 		/* Wait a little bit (on 40G cards it sometimes takes a really
1749*4882a593Smuzhiyun 		 * long time for link to come back from the atomic reset)
1750*4882a593Smuzhiyun 		 * and try once more
1751*4882a593Smuzhiyun 		 */
1752*4882a593Smuzhiyun 		msleep(1000);
1753*4882a593Smuzhiyun 		status = i40e_update_link_info(hw);
1754*4882a593Smuzhiyun 	}
1755*4882a593Smuzhiyun 	if (status)
1756*4882a593Smuzhiyun 		*aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
1757*4882a593Smuzhiyun 
1758*4882a593Smuzhiyun 	return status;
1759*4882a593Smuzhiyun }
1760*4882a593Smuzhiyun 
1761*4882a593Smuzhiyun /**
1762*4882a593Smuzhiyun  * i40e_aq_clear_pxe_mode
1763*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1764*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1765*4882a593Smuzhiyun  *
1766*4882a593Smuzhiyun  * Tell the firmware that the driver is taking over from PXE
1767*4882a593Smuzhiyun  **/
i40e_aq_clear_pxe_mode(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)1768*4882a593Smuzhiyun i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
1769*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
1770*4882a593Smuzhiyun {
1771*4882a593Smuzhiyun 	i40e_status status;
1772*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1773*4882a593Smuzhiyun 	struct i40e_aqc_clear_pxe *cmd =
1774*4882a593Smuzhiyun 		(struct i40e_aqc_clear_pxe *)&desc.params.raw;
1775*4882a593Smuzhiyun 
1776*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
1777*4882a593Smuzhiyun 					  i40e_aqc_opc_clear_pxe_mode);
1778*4882a593Smuzhiyun 
1779*4882a593Smuzhiyun 	cmd->rx_cnt = 0x2;
1780*4882a593Smuzhiyun 
1781*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1782*4882a593Smuzhiyun 
1783*4882a593Smuzhiyun 	wr32(hw, I40E_GLLAN_RCTL_0, 0x1);
1784*4882a593Smuzhiyun 
1785*4882a593Smuzhiyun 	return status;
1786*4882a593Smuzhiyun }
1787*4882a593Smuzhiyun 
1788*4882a593Smuzhiyun /**
1789*4882a593Smuzhiyun  * i40e_aq_set_link_restart_an
1790*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1791*4882a593Smuzhiyun  * @enable_link: if true: enable link, if false: disable link
1792*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1793*4882a593Smuzhiyun  *
1794*4882a593Smuzhiyun  * Sets up the link and restarts the Auto-Negotiation over the link.
1795*4882a593Smuzhiyun  **/
i40e_aq_set_link_restart_an(struct i40e_hw * hw,bool enable_link,struct i40e_asq_cmd_details * cmd_details)1796*4882a593Smuzhiyun i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
1797*4882a593Smuzhiyun 					bool enable_link,
1798*4882a593Smuzhiyun 					struct i40e_asq_cmd_details *cmd_details)
1799*4882a593Smuzhiyun {
1800*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1801*4882a593Smuzhiyun 	struct i40e_aqc_set_link_restart_an *cmd =
1802*4882a593Smuzhiyun 		(struct i40e_aqc_set_link_restart_an *)&desc.params.raw;
1803*4882a593Smuzhiyun 	i40e_status status;
1804*4882a593Smuzhiyun 
1805*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
1806*4882a593Smuzhiyun 					  i40e_aqc_opc_set_link_restart_an);
1807*4882a593Smuzhiyun 
1808*4882a593Smuzhiyun 	cmd->command = I40E_AQ_PHY_RESTART_AN;
1809*4882a593Smuzhiyun 	if (enable_link)
1810*4882a593Smuzhiyun 		cmd->command |= I40E_AQ_PHY_LINK_ENABLE;
1811*4882a593Smuzhiyun 	else
1812*4882a593Smuzhiyun 		cmd->command &= ~I40E_AQ_PHY_LINK_ENABLE;
1813*4882a593Smuzhiyun 
1814*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1815*4882a593Smuzhiyun 
1816*4882a593Smuzhiyun 	return status;
1817*4882a593Smuzhiyun }
1818*4882a593Smuzhiyun 
1819*4882a593Smuzhiyun /**
1820*4882a593Smuzhiyun  * i40e_aq_get_link_info
1821*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1822*4882a593Smuzhiyun  * @enable_lse: enable/disable LinkStatusEvent reporting
1823*4882a593Smuzhiyun  * @link: pointer to link status structure - optional
1824*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1825*4882a593Smuzhiyun  *
1826*4882a593Smuzhiyun  * Returns the link status of the adapter.
1827*4882a593Smuzhiyun  **/
i40e_aq_get_link_info(struct i40e_hw * hw,bool enable_lse,struct i40e_link_status * link,struct i40e_asq_cmd_details * cmd_details)1828*4882a593Smuzhiyun i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
1829*4882a593Smuzhiyun 				bool enable_lse, struct i40e_link_status *link,
1830*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
1831*4882a593Smuzhiyun {
1832*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1833*4882a593Smuzhiyun 	struct i40e_aqc_get_link_status *resp =
1834*4882a593Smuzhiyun 		(struct i40e_aqc_get_link_status *)&desc.params.raw;
1835*4882a593Smuzhiyun 	struct i40e_link_status *hw_link_info = &hw->phy.link_info;
1836*4882a593Smuzhiyun 	i40e_status status;
1837*4882a593Smuzhiyun 	bool tx_pause, rx_pause;
1838*4882a593Smuzhiyun 	u16 command_flags;
1839*4882a593Smuzhiyun 
1840*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
1841*4882a593Smuzhiyun 
1842*4882a593Smuzhiyun 	if (enable_lse)
1843*4882a593Smuzhiyun 		command_flags = I40E_AQ_LSE_ENABLE;
1844*4882a593Smuzhiyun 	else
1845*4882a593Smuzhiyun 		command_flags = I40E_AQ_LSE_DISABLE;
1846*4882a593Smuzhiyun 	resp->command_flags = cpu_to_le16(command_flags);
1847*4882a593Smuzhiyun 
1848*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1849*4882a593Smuzhiyun 
1850*4882a593Smuzhiyun 	if (status)
1851*4882a593Smuzhiyun 		goto aq_get_link_info_exit;
1852*4882a593Smuzhiyun 
1853*4882a593Smuzhiyun 	/* save off old link status information */
1854*4882a593Smuzhiyun 	hw->phy.link_info_old = *hw_link_info;
1855*4882a593Smuzhiyun 
1856*4882a593Smuzhiyun 	/* update link status */
1857*4882a593Smuzhiyun 	hw_link_info->phy_type = (enum i40e_aq_phy_type)resp->phy_type;
1858*4882a593Smuzhiyun 	hw->phy.media_type = i40e_get_media_type(hw);
1859*4882a593Smuzhiyun 	hw_link_info->link_speed = (enum i40e_aq_link_speed)resp->link_speed;
1860*4882a593Smuzhiyun 	hw_link_info->link_info = resp->link_info;
1861*4882a593Smuzhiyun 	hw_link_info->an_info = resp->an_info;
1862*4882a593Smuzhiyun 	hw_link_info->fec_info = resp->config & (I40E_AQ_CONFIG_FEC_KR_ENA |
1863*4882a593Smuzhiyun 						 I40E_AQ_CONFIG_FEC_RS_ENA);
1864*4882a593Smuzhiyun 	hw_link_info->ext_info = resp->ext_info;
1865*4882a593Smuzhiyun 	hw_link_info->loopback = resp->loopback & I40E_AQ_LOOPBACK_MASK;
1866*4882a593Smuzhiyun 	hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size);
1867*4882a593Smuzhiyun 	hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
1868*4882a593Smuzhiyun 
1869*4882a593Smuzhiyun 	/* update fc info */
1870*4882a593Smuzhiyun 	tx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_TX);
1871*4882a593Smuzhiyun 	rx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_RX);
1872*4882a593Smuzhiyun 	if (tx_pause & rx_pause)
1873*4882a593Smuzhiyun 		hw->fc.current_mode = I40E_FC_FULL;
1874*4882a593Smuzhiyun 	else if (tx_pause)
1875*4882a593Smuzhiyun 		hw->fc.current_mode = I40E_FC_TX_PAUSE;
1876*4882a593Smuzhiyun 	else if (rx_pause)
1877*4882a593Smuzhiyun 		hw->fc.current_mode = I40E_FC_RX_PAUSE;
1878*4882a593Smuzhiyun 	else
1879*4882a593Smuzhiyun 		hw->fc.current_mode = I40E_FC_NONE;
1880*4882a593Smuzhiyun 
1881*4882a593Smuzhiyun 	if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
1882*4882a593Smuzhiyun 		hw_link_info->crc_enable = true;
1883*4882a593Smuzhiyun 	else
1884*4882a593Smuzhiyun 		hw_link_info->crc_enable = false;
1885*4882a593Smuzhiyun 
1886*4882a593Smuzhiyun 	if (resp->command_flags & cpu_to_le16(I40E_AQ_LSE_IS_ENABLED))
1887*4882a593Smuzhiyun 		hw_link_info->lse_enable = true;
1888*4882a593Smuzhiyun 	else
1889*4882a593Smuzhiyun 		hw_link_info->lse_enable = false;
1890*4882a593Smuzhiyun 
1891*4882a593Smuzhiyun 	if ((hw->mac.type == I40E_MAC_XL710) &&
1892*4882a593Smuzhiyun 	    (hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
1893*4882a593Smuzhiyun 	     hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
1894*4882a593Smuzhiyun 		hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
1895*4882a593Smuzhiyun 
1896*4882a593Smuzhiyun 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE &&
1897*4882a593Smuzhiyun 	    hw->mac.type != I40E_MAC_X722) {
1898*4882a593Smuzhiyun 		__le32 tmp;
1899*4882a593Smuzhiyun 
1900*4882a593Smuzhiyun 		memcpy(&tmp, resp->link_type, sizeof(tmp));
1901*4882a593Smuzhiyun 		hw->phy.phy_types = le32_to_cpu(tmp);
1902*4882a593Smuzhiyun 		hw->phy.phy_types |= ((u64)resp->link_type_ext << 32);
1903*4882a593Smuzhiyun 	}
1904*4882a593Smuzhiyun 
1905*4882a593Smuzhiyun 	/* save link status information */
1906*4882a593Smuzhiyun 	if (link)
1907*4882a593Smuzhiyun 		*link = *hw_link_info;
1908*4882a593Smuzhiyun 
1909*4882a593Smuzhiyun 	/* flag cleared so helper functions don't call AQ again */
1910*4882a593Smuzhiyun 	hw->phy.get_link_info = false;
1911*4882a593Smuzhiyun 
1912*4882a593Smuzhiyun aq_get_link_info_exit:
1913*4882a593Smuzhiyun 	return status;
1914*4882a593Smuzhiyun }
1915*4882a593Smuzhiyun 
1916*4882a593Smuzhiyun /**
1917*4882a593Smuzhiyun  * i40e_aq_set_phy_int_mask
1918*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1919*4882a593Smuzhiyun  * @mask: interrupt mask to be set
1920*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1921*4882a593Smuzhiyun  *
1922*4882a593Smuzhiyun  * Set link interrupt mask.
1923*4882a593Smuzhiyun  **/
i40e_aq_set_phy_int_mask(struct i40e_hw * hw,u16 mask,struct i40e_asq_cmd_details * cmd_details)1924*4882a593Smuzhiyun i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
1925*4882a593Smuzhiyun 				     u16 mask,
1926*4882a593Smuzhiyun 				     struct i40e_asq_cmd_details *cmd_details)
1927*4882a593Smuzhiyun {
1928*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1929*4882a593Smuzhiyun 	struct i40e_aqc_set_phy_int_mask *cmd =
1930*4882a593Smuzhiyun 		(struct i40e_aqc_set_phy_int_mask *)&desc.params.raw;
1931*4882a593Smuzhiyun 	i40e_status status;
1932*4882a593Smuzhiyun 
1933*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
1934*4882a593Smuzhiyun 					  i40e_aqc_opc_set_phy_int_mask);
1935*4882a593Smuzhiyun 
1936*4882a593Smuzhiyun 	cmd->event_mask = cpu_to_le16(mask);
1937*4882a593Smuzhiyun 
1938*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1939*4882a593Smuzhiyun 
1940*4882a593Smuzhiyun 	return status;
1941*4882a593Smuzhiyun }
1942*4882a593Smuzhiyun 
1943*4882a593Smuzhiyun /**
1944*4882a593Smuzhiyun  * i40e_aq_set_phy_debug
1945*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1946*4882a593Smuzhiyun  * @cmd_flags: debug command flags
1947*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1948*4882a593Smuzhiyun  *
1949*4882a593Smuzhiyun  * Reset the external PHY.
1950*4882a593Smuzhiyun  **/
i40e_aq_set_phy_debug(struct i40e_hw * hw,u8 cmd_flags,struct i40e_asq_cmd_details * cmd_details)1951*4882a593Smuzhiyun i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
1952*4882a593Smuzhiyun 				  struct i40e_asq_cmd_details *cmd_details)
1953*4882a593Smuzhiyun {
1954*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1955*4882a593Smuzhiyun 	struct i40e_aqc_set_phy_debug *cmd =
1956*4882a593Smuzhiyun 		(struct i40e_aqc_set_phy_debug *)&desc.params.raw;
1957*4882a593Smuzhiyun 	i40e_status status;
1958*4882a593Smuzhiyun 
1959*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
1960*4882a593Smuzhiyun 					  i40e_aqc_opc_set_phy_debug);
1961*4882a593Smuzhiyun 
1962*4882a593Smuzhiyun 	cmd->command_flags = cmd_flags;
1963*4882a593Smuzhiyun 
1964*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1965*4882a593Smuzhiyun 
1966*4882a593Smuzhiyun 	return status;
1967*4882a593Smuzhiyun }
1968*4882a593Smuzhiyun 
1969*4882a593Smuzhiyun /**
1970*4882a593Smuzhiyun  * i40e_is_aq_api_ver_ge
1971*4882a593Smuzhiyun  * @aq: pointer to AdminQ info containing HW API version to compare
1972*4882a593Smuzhiyun  * @maj: API major value
1973*4882a593Smuzhiyun  * @min: API minor value
1974*4882a593Smuzhiyun  *
1975*4882a593Smuzhiyun  * Assert whether current HW API version is greater/equal than provided.
1976*4882a593Smuzhiyun  **/
i40e_is_aq_api_ver_ge(struct i40e_adminq_info * aq,u16 maj,u16 min)1977*4882a593Smuzhiyun static bool i40e_is_aq_api_ver_ge(struct i40e_adminq_info *aq, u16 maj,
1978*4882a593Smuzhiyun 				  u16 min)
1979*4882a593Smuzhiyun {
1980*4882a593Smuzhiyun 	return (aq->api_maj_ver > maj ||
1981*4882a593Smuzhiyun 		(aq->api_maj_ver == maj && aq->api_min_ver >= min));
1982*4882a593Smuzhiyun }
1983*4882a593Smuzhiyun 
1984*4882a593Smuzhiyun /**
1985*4882a593Smuzhiyun  * i40e_aq_add_vsi
1986*4882a593Smuzhiyun  * @hw: pointer to the hw struct
1987*4882a593Smuzhiyun  * @vsi_ctx: pointer to a vsi context struct
1988*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
1989*4882a593Smuzhiyun  *
1990*4882a593Smuzhiyun  * Add a VSI context to the hardware.
1991*4882a593Smuzhiyun **/
i40e_aq_add_vsi(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)1992*4882a593Smuzhiyun i40e_status i40e_aq_add_vsi(struct i40e_hw *hw,
1993*4882a593Smuzhiyun 				struct i40e_vsi_context *vsi_ctx,
1994*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
1995*4882a593Smuzhiyun {
1996*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
1997*4882a593Smuzhiyun 	struct i40e_aqc_add_get_update_vsi *cmd =
1998*4882a593Smuzhiyun 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
1999*4882a593Smuzhiyun 	struct i40e_aqc_add_get_update_vsi_completion *resp =
2000*4882a593Smuzhiyun 		(struct i40e_aqc_add_get_update_vsi_completion *)
2001*4882a593Smuzhiyun 		&desc.params.raw;
2002*4882a593Smuzhiyun 	i40e_status status;
2003*4882a593Smuzhiyun 
2004*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2005*4882a593Smuzhiyun 					  i40e_aqc_opc_add_vsi);
2006*4882a593Smuzhiyun 
2007*4882a593Smuzhiyun 	cmd->uplink_seid = cpu_to_le16(vsi_ctx->uplink_seid);
2008*4882a593Smuzhiyun 	cmd->connection_type = vsi_ctx->connection_type;
2009*4882a593Smuzhiyun 	cmd->vf_id = vsi_ctx->vf_num;
2010*4882a593Smuzhiyun 	cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
2011*4882a593Smuzhiyun 
2012*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2013*4882a593Smuzhiyun 
2014*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2015*4882a593Smuzhiyun 				    sizeof(vsi_ctx->info), cmd_details);
2016*4882a593Smuzhiyun 
2017*4882a593Smuzhiyun 	if (status)
2018*4882a593Smuzhiyun 		goto aq_add_vsi_exit;
2019*4882a593Smuzhiyun 
2020*4882a593Smuzhiyun 	vsi_ctx->seid = le16_to_cpu(resp->seid);
2021*4882a593Smuzhiyun 	vsi_ctx->vsi_number = le16_to_cpu(resp->vsi_number);
2022*4882a593Smuzhiyun 	vsi_ctx->vsis_allocated = le16_to_cpu(resp->vsi_used);
2023*4882a593Smuzhiyun 	vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
2024*4882a593Smuzhiyun 
2025*4882a593Smuzhiyun aq_add_vsi_exit:
2026*4882a593Smuzhiyun 	return status;
2027*4882a593Smuzhiyun }
2028*4882a593Smuzhiyun 
2029*4882a593Smuzhiyun /**
2030*4882a593Smuzhiyun  * i40e_aq_set_default_vsi
2031*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2032*4882a593Smuzhiyun  * @seid: vsi number
2033*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2034*4882a593Smuzhiyun  **/
i40e_aq_set_default_vsi(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)2035*4882a593Smuzhiyun i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw,
2036*4882a593Smuzhiyun 				    u16 seid,
2037*4882a593Smuzhiyun 				    struct i40e_asq_cmd_details *cmd_details)
2038*4882a593Smuzhiyun {
2039*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2040*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2041*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)
2042*4882a593Smuzhiyun 		&desc.params.raw;
2043*4882a593Smuzhiyun 	i40e_status status;
2044*4882a593Smuzhiyun 
2045*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2046*4882a593Smuzhiyun 					  i40e_aqc_opc_set_vsi_promiscuous_modes);
2047*4882a593Smuzhiyun 
2048*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
2049*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
2050*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2051*4882a593Smuzhiyun 
2052*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2053*4882a593Smuzhiyun 
2054*4882a593Smuzhiyun 	return status;
2055*4882a593Smuzhiyun }
2056*4882a593Smuzhiyun 
2057*4882a593Smuzhiyun /**
2058*4882a593Smuzhiyun  * i40e_aq_clear_default_vsi
2059*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2060*4882a593Smuzhiyun  * @seid: vsi number
2061*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2062*4882a593Smuzhiyun  **/
i40e_aq_clear_default_vsi(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)2063*4882a593Smuzhiyun i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw,
2064*4882a593Smuzhiyun 				      u16 seid,
2065*4882a593Smuzhiyun 				      struct i40e_asq_cmd_details *cmd_details)
2066*4882a593Smuzhiyun {
2067*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2068*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2069*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)
2070*4882a593Smuzhiyun 		&desc.params.raw;
2071*4882a593Smuzhiyun 	i40e_status status;
2072*4882a593Smuzhiyun 
2073*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2074*4882a593Smuzhiyun 					  i40e_aqc_opc_set_vsi_promiscuous_modes);
2075*4882a593Smuzhiyun 
2076*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(0);
2077*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
2078*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2079*4882a593Smuzhiyun 
2080*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2081*4882a593Smuzhiyun 
2082*4882a593Smuzhiyun 	return status;
2083*4882a593Smuzhiyun }
2084*4882a593Smuzhiyun 
2085*4882a593Smuzhiyun /**
2086*4882a593Smuzhiyun  * i40e_aq_set_vsi_unicast_promiscuous
2087*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2088*4882a593Smuzhiyun  * @seid: vsi number
2089*4882a593Smuzhiyun  * @set: set unicast promiscuous enable/disable
2090*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2091*4882a593Smuzhiyun  * @rx_only_promisc: flag to decide if egress traffic gets mirrored in promisc
2092*4882a593Smuzhiyun  **/
i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw * hw,u16 seid,bool set,struct i40e_asq_cmd_details * cmd_details,bool rx_only_promisc)2093*4882a593Smuzhiyun i40e_status i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
2094*4882a593Smuzhiyun 				u16 seid, bool set,
2095*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details,
2096*4882a593Smuzhiyun 				bool rx_only_promisc)
2097*4882a593Smuzhiyun {
2098*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2099*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2100*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2101*4882a593Smuzhiyun 	i40e_status status;
2102*4882a593Smuzhiyun 	u16 flags = 0;
2103*4882a593Smuzhiyun 
2104*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2105*4882a593Smuzhiyun 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2106*4882a593Smuzhiyun 
2107*4882a593Smuzhiyun 	if (set) {
2108*4882a593Smuzhiyun 		flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2109*4882a593Smuzhiyun 		if (rx_only_promisc && i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
2110*4882a593Smuzhiyun 			flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
2111*4882a593Smuzhiyun 	}
2112*4882a593Smuzhiyun 
2113*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(flags);
2114*4882a593Smuzhiyun 
2115*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2116*4882a593Smuzhiyun 	if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
2117*4882a593Smuzhiyun 		cmd->valid_flags |=
2118*4882a593Smuzhiyun 			cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
2119*4882a593Smuzhiyun 
2120*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2121*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2122*4882a593Smuzhiyun 
2123*4882a593Smuzhiyun 	return status;
2124*4882a593Smuzhiyun }
2125*4882a593Smuzhiyun 
2126*4882a593Smuzhiyun /**
2127*4882a593Smuzhiyun  * i40e_aq_set_vsi_multicast_promiscuous
2128*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2129*4882a593Smuzhiyun  * @seid: vsi number
2130*4882a593Smuzhiyun  * @set: set multicast promiscuous enable/disable
2131*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2132*4882a593Smuzhiyun  **/
i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw * hw,u16 seid,bool set,struct i40e_asq_cmd_details * cmd_details)2133*4882a593Smuzhiyun i40e_status i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
2134*4882a593Smuzhiyun 				u16 seid, bool set, struct i40e_asq_cmd_details *cmd_details)
2135*4882a593Smuzhiyun {
2136*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2137*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2138*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2139*4882a593Smuzhiyun 	i40e_status status;
2140*4882a593Smuzhiyun 	u16 flags = 0;
2141*4882a593Smuzhiyun 
2142*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2143*4882a593Smuzhiyun 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2144*4882a593Smuzhiyun 
2145*4882a593Smuzhiyun 	if (set)
2146*4882a593Smuzhiyun 		flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2147*4882a593Smuzhiyun 
2148*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(flags);
2149*4882a593Smuzhiyun 
2150*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2151*4882a593Smuzhiyun 
2152*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2153*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2154*4882a593Smuzhiyun 
2155*4882a593Smuzhiyun 	return status;
2156*4882a593Smuzhiyun }
2157*4882a593Smuzhiyun 
2158*4882a593Smuzhiyun /**
2159*4882a593Smuzhiyun  * i40e_aq_set_vsi_mc_promisc_on_vlan
2160*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2161*4882a593Smuzhiyun  * @seid: vsi number
2162*4882a593Smuzhiyun  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2163*4882a593Smuzhiyun  * @vid: The VLAN tag filter - capture any multicast packet with this VLAN tag
2164*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2165*4882a593Smuzhiyun  **/
i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw * hw,u16 seid,bool enable,u16 vid,struct i40e_asq_cmd_details * cmd_details)2166*4882a593Smuzhiyun enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
2167*4882a593Smuzhiyun 							 u16 seid, bool enable,
2168*4882a593Smuzhiyun 							 u16 vid,
2169*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2170*4882a593Smuzhiyun {
2171*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2172*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2173*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2174*4882a593Smuzhiyun 	enum i40e_status_code status;
2175*4882a593Smuzhiyun 	u16 flags = 0;
2176*4882a593Smuzhiyun 
2177*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2178*4882a593Smuzhiyun 					  i40e_aqc_opc_set_vsi_promiscuous_modes);
2179*4882a593Smuzhiyun 
2180*4882a593Smuzhiyun 	if (enable)
2181*4882a593Smuzhiyun 		flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2182*4882a593Smuzhiyun 
2183*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(flags);
2184*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2185*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2186*4882a593Smuzhiyun 	cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2187*4882a593Smuzhiyun 
2188*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2189*4882a593Smuzhiyun 
2190*4882a593Smuzhiyun 	return status;
2191*4882a593Smuzhiyun }
2192*4882a593Smuzhiyun 
2193*4882a593Smuzhiyun /**
2194*4882a593Smuzhiyun  * i40e_aq_set_vsi_uc_promisc_on_vlan
2195*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2196*4882a593Smuzhiyun  * @seid: vsi number
2197*4882a593Smuzhiyun  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2198*4882a593Smuzhiyun  * @vid: The VLAN tag filter - capture any unicast packet with this VLAN tag
2199*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2200*4882a593Smuzhiyun  **/
i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw * hw,u16 seid,bool enable,u16 vid,struct i40e_asq_cmd_details * cmd_details)2201*4882a593Smuzhiyun enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
2202*4882a593Smuzhiyun 							 u16 seid, bool enable,
2203*4882a593Smuzhiyun 							 u16 vid,
2204*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2205*4882a593Smuzhiyun {
2206*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2207*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2208*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2209*4882a593Smuzhiyun 	enum i40e_status_code status;
2210*4882a593Smuzhiyun 	u16 flags = 0;
2211*4882a593Smuzhiyun 
2212*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2213*4882a593Smuzhiyun 					  i40e_aqc_opc_set_vsi_promiscuous_modes);
2214*4882a593Smuzhiyun 
2215*4882a593Smuzhiyun 	if (enable) {
2216*4882a593Smuzhiyun 		flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2217*4882a593Smuzhiyun 		if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
2218*4882a593Smuzhiyun 			flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
2219*4882a593Smuzhiyun 	}
2220*4882a593Smuzhiyun 
2221*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(flags);
2222*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2223*4882a593Smuzhiyun 	if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
2224*4882a593Smuzhiyun 		cmd->valid_flags |=
2225*4882a593Smuzhiyun 			cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
2226*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2227*4882a593Smuzhiyun 	cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2228*4882a593Smuzhiyun 
2229*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2230*4882a593Smuzhiyun 
2231*4882a593Smuzhiyun 	return status;
2232*4882a593Smuzhiyun }
2233*4882a593Smuzhiyun 
2234*4882a593Smuzhiyun /**
2235*4882a593Smuzhiyun  * i40e_aq_set_vsi_bc_promisc_on_vlan
2236*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2237*4882a593Smuzhiyun  * @seid: vsi number
2238*4882a593Smuzhiyun  * @enable: set broadcast promiscuous enable/disable for a given VLAN
2239*4882a593Smuzhiyun  * @vid: The VLAN tag filter - capture any broadcast packet with this VLAN tag
2240*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2241*4882a593Smuzhiyun  **/
i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw * hw,u16 seid,bool enable,u16 vid,struct i40e_asq_cmd_details * cmd_details)2242*4882a593Smuzhiyun i40e_status i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
2243*4882a593Smuzhiyun 				u16 seid, bool enable, u16 vid,
2244*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2245*4882a593Smuzhiyun {
2246*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2247*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2248*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2249*4882a593Smuzhiyun 	i40e_status status;
2250*4882a593Smuzhiyun 	u16 flags = 0;
2251*4882a593Smuzhiyun 
2252*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2253*4882a593Smuzhiyun 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2254*4882a593Smuzhiyun 
2255*4882a593Smuzhiyun 	if (enable)
2256*4882a593Smuzhiyun 		flags |= I40E_AQC_SET_VSI_PROMISC_BROADCAST;
2257*4882a593Smuzhiyun 
2258*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(flags);
2259*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2260*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2261*4882a593Smuzhiyun 	cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2262*4882a593Smuzhiyun 
2263*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2264*4882a593Smuzhiyun 
2265*4882a593Smuzhiyun 	return status;
2266*4882a593Smuzhiyun }
2267*4882a593Smuzhiyun 
2268*4882a593Smuzhiyun /**
2269*4882a593Smuzhiyun  * i40e_aq_set_vsi_broadcast
2270*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2271*4882a593Smuzhiyun  * @seid: vsi number
2272*4882a593Smuzhiyun  * @set_filter: true to set filter, false to clear filter
2273*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2274*4882a593Smuzhiyun  *
2275*4882a593Smuzhiyun  * Set or clear the broadcast promiscuous flag (filter) for a given VSI.
2276*4882a593Smuzhiyun  **/
i40e_aq_set_vsi_broadcast(struct i40e_hw * hw,u16 seid,bool set_filter,struct i40e_asq_cmd_details * cmd_details)2277*4882a593Smuzhiyun i40e_status i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
2278*4882a593Smuzhiyun 				u16 seid, bool set_filter,
2279*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2280*4882a593Smuzhiyun {
2281*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2282*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2283*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2284*4882a593Smuzhiyun 	i40e_status status;
2285*4882a593Smuzhiyun 
2286*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2287*4882a593Smuzhiyun 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2288*4882a593Smuzhiyun 
2289*4882a593Smuzhiyun 	if (set_filter)
2290*4882a593Smuzhiyun 		cmd->promiscuous_flags
2291*4882a593Smuzhiyun 			    |= cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2292*4882a593Smuzhiyun 	else
2293*4882a593Smuzhiyun 		cmd->promiscuous_flags
2294*4882a593Smuzhiyun 			    &= cpu_to_le16(~I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2295*4882a593Smuzhiyun 
2296*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2297*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2298*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2299*4882a593Smuzhiyun 
2300*4882a593Smuzhiyun 	return status;
2301*4882a593Smuzhiyun }
2302*4882a593Smuzhiyun 
2303*4882a593Smuzhiyun /**
2304*4882a593Smuzhiyun  * i40e_aq_set_vsi_vlan_promisc - control the VLAN promiscuous setting
2305*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2306*4882a593Smuzhiyun  * @seid: vsi number
2307*4882a593Smuzhiyun  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2308*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2309*4882a593Smuzhiyun  **/
i40e_aq_set_vsi_vlan_promisc(struct i40e_hw * hw,u16 seid,bool enable,struct i40e_asq_cmd_details * cmd_details)2310*4882a593Smuzhiyun i40e_status i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
2311*4882a593Smuzhiyun 				       u16 seid, bool enable,
2312*4882a593Smuzhiyun 				       struct i40e_asq_cmd_details *cmd_details)
2313*4882a593Smuzhiyun {
2314*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2315*4882a593Smuzhiyun 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2316*4882a593Smuzhiyun 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2317*4882a593Smuzhiyun 	i40e_status status;
2318*4882a593Smuzhiyun 	u16 flags = 0;
2319*4882a593Smuzhiyun 
2320*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2321*4882a593Smuzhiyun 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2322*4882a593Smuzhiyun 	if (enable)
2323*4882a593Smuzhiyun 		flags |= I40E_AQC_SET_VSI_PROMISC_VLAN;
2324*4882a593Smuzhiyun 
2325*4882a593Smuzhiyun 	cmd->promiscuous_flags = cpu_to_le16(flags);
2326*4882a593Smuzhiyun 	cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_VLAN);
2327*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
2328*4882a593Smuzhiyun 
2329*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2330*4882a593Smuzhiyun 
2331*4882a593Smuzhiyun 	return status;
2332*4882a593Smuzhiyun }
2333*4882a593Smuzhiyun 
2334*4882a593Smuzhiyun /**
2335*4882a593Smuzhiyun  * i40e_get_vsi_params - get VSI configuration info
2336*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2337*4882a593Smuzhiyun  * @vsi_ctx: pointer to a vsi context struct
2338*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2339*4882a593Smuzhiyun  **/
i40e_aq_get_vsi_params(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)2340*4882a593Smuzhiyun i40e_status i40e_aq_get_vsi_params(struct i40e_hw *hw,
2341*4882a593Smuzhiyun 				struct i40e_vsi_context *vsi_ctx,
2342*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2343*4882a593Smuzhiyun {
2344*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2345*4882a593Smuzhiyun 	struct i40e_aqc_add_get_update_vsi *cmd =
2346*4882a593Smuzhiyun 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2347*4882a593Smuzhiyun 	struct i40e_aqc_add_get_update_vsi_completion *resp =
2348*4882a593Smuzhiyun 		(struct i40e_aqc_add_get_update_vsi_completion *)
2349*4882a593Smuzhiyun 		&desc.params.raw;
2350*4882a593Smuzhiyun 	i40e_status status;
2351*4882a593Smuzhiyun 
2352*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2353*4882a593Smuzhiyun 					  i40e_aqc_opc_get_vsi_parameters);
2354*4882a593Smuzhiyun 
2355*4882a593Smuzhiyun 	cmd->uplink_seid = cpu_to_le16(vsi_ctx->seid);
2356*4882a593Smuzhiyun 
2357*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
2358*4882a593Smuzhiyun 
2359*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2360*4882a593Smuzhiyun 				    sizeof(vsi_ctx->info), NULL);
2361*4882a593Smuzhiyun 
2362*4882a593Smuzhiyun 	if (status)
2363*4882a593Smuzhiyun 		goto aq_get_vsi_params_exit;
2364*4882a593Smuzhiyun 
2365*4882a593Smuzhiyun 	vsi_ctx->seid = le16_to_cpu(resp->seid);
2366*4882a593Smuzhiyun 	vsi_ctx->vsi_number = le16_to_cpu(resp->vsi_number);
2367*4882a593Smuzhiyun 	vsi_ctx->vsis_allocated = le16_to_cpu(resp->vsi_used);
2368*4882a593Smuzhiyun 	vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
2369*4882a593Smuzhiyun 
2370*4882a593Smuzhiyun aq_get_vsi_params_exit:
2371*4882a593Smuzhiyun 	return status;
2372*4882a593Smuzhiyun }
2373*4882a593Smuzhiyun 
2374*4882a593Smuzhiyun /**
2375*4882a593Smuzhiyun  * i40e_aq_update_vsi_params
2376*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2377*4882a593Smuzhiyun  * @vsi_ctx: pointer to a vsi context struct
2378*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2379*4882a593Smuzhiyun  *
2380*4882a593Smuzhiyun  * Update a VSI context.
2381*4882a593Smuzhiyun  **/
i40e_aq_update_vsi_params(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)2382*4882a593Smuzhiyun i40e_status i40e_aq_update_vsi_params(struct i40e_hw *hw,
2383*4882a593Smuzhiyun 				struct i40e_vsi_context *vsi_ctx,
2384*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2385*4882a593Smuzhiyun {
2386*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2387*4882a593Smuzhiyun 	struct i40e_aqc_add_get_update_vsi *cmd =
2388*4882a593Smuzhiyun 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2389*4882a593Smuzhiyun 	struct i40e_aqc_add_get_update_vsi_completion *resp =
2390*4882a593Smuzhiyun 		(struct i40e_aqc_add_get_update_vsi_completion *)
2391*4882a593Smuzhiyun 		&desc.params.raw;
2392*4882a593Smuzhiyun 	i40e_status status;
2393*4882a593Smuzhiyun 
2394*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2395*4882a593Smuzhiyun 					  i40e_aqc_opc_update_vsi_parameters);
2396*4882a593Smuzhiyun 	cmd->uplink_seid = cpu_to_le16(vsi_ctx->seid);
2397*4882a593Smuzhiyun 
2398*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2399*4882a593Smuzhiyun 
2400*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2401*4882a593Smuzhiyun 				    sizeof(vsi_ctx->info), cmd_details);
2402*4882a593Smuzhiyun 
2403*4882a593Smuzhiyun 	vsi_ctx->vsis_allocated = le16_to_cpu(resp->vsi_used);
2404*4882a593Smuzhiyun 	vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
2405*4882a593Smuzhiyun 
2406*4882a593Smuzhiyun 	return status;
2407*4882a593Smuzhiyun }
2408*4882a593Smuzhiyun 
2409*4882a593Smuzhiyun /**
2410*4882a593Smuzhiyun  * i40e_aq_get_switch_config
2411*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
2412*4882a593Smuzhiyun  * @buf: pointer to the result buffer
2413*4882a593Smuzhiyun  * @buf_size: length of input buffer
2414*4882a593Smuzhiyun  * @start_seid: seid to start for the report, 0 == beginning
2415*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2416*4882a593Smuzhiyun  *
2417*4882a593Smuzhiyun  * Fill the buf with switch configuration returned from AdminQ command
2418*4882a593Smuzhiyun  **/
i40e_aq_get_switch_config(struct i40e_hw * hw,struct i40e_aqc_get_switch_config_resp * buf,u16 buf_size,u16 * start_seid,struct i40e_asq_cmd_details * cmd_details)2419*4882a593Smuzhiyun i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
2420*4882a593Smuzhiyun 				struct i40e_aqc_get_switch_config_resp *buf,
2421*4882a593Smuzhiyun 				u16 buf_size, u16 *start_seid,
2422*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2423*4882a593Smuzhiyun {
2424*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2425*4882a593Smuzhiyun 	struct i40e_aqc_switch_seid *scfg =
2426*4882a593Smuzhiyun 		(struct i40e_aqc_switch_seid *)&desc.params.raw;
2427*4882a593Smuzhiyun 	i40e_status status;
2428*4882a593Smuzhiyun 
2429*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2430*4882a593Smuzhiyun 					  i40e_aqc_opc_get_switch_config);
2431*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
2432*4882a593Smuzhiyun 	if (buf_size > I40E_AQ_LARGE_BUF)
2433*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2434*4882a593Smuzhiyun 	scfg->seid = cpu_to_le16(*start_seid);
2435*4882a593Smuzhiyun 
2436*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, buf, buf_size, cmd_details);
2437*4882a593Smuzhiyun 	*start_seid = le16_to_cpu(scfg->seid);
2438*4882a593Smuzhiyun 
2439*4882a593Smuzhiyun 	return status;
2440*4882a593Smuzhiyun }
2441*4882a593Smuzhiyun 
2442*4882a593Smuzhiyun /**
2443*4882a593Smuzhiyun  * i40e_aq_set_switch_config
2444*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
2445*4882a593Smuzhiyun  * @flags: bit flag values to set
2446*4882a593Smuzhiyun  * @mode: cloud filter mode
2447*4882a593Smuzhiyun  * @valid_flags: which bit flags to set
2448*4882a593Smuzhiyun  * @mode: cloud filter mode
2449*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2450*4882a593Smuzhiyun  *
2451*4882a593Smuzhiyun  * Set switch configuration bits
2452*4882a593Smuzhiyun  **/
i40e_aq_set_switch_config(struct i40e_hw * hw,u16 flags,u16 valid_flags,u8 mode,struct i40e_asq_cmd_details * cmd_details)2453*4882a593Smuzhiyun enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
2454*4882a593Smuzhiyun 						u16 flags,
2455*4882a593Smuzhiyun 						u16 valid_flags, u8 mode,
2456*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2457*4882a593Smuzhiyun {
2458*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2459*4882a593Smuzhiyun 	struct i40e_aqc_set_switch_config *scfg =
2460*4882a593Smuzhiyun 		(struct i40e_aqc_set_switch_config *)&desc.params.raw;
2461*4882a593Smuzhiyun 	enum i40e_status_code status;
2462*4882a593Smuzhiyun 
2463*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2464*4882a593Smuzhiyun 					  i40e_aqc_opc_set_switch_config);
2465*4882a593Smuzhiyun 	scfg->flags = cpu_to_le16(flags);
2466*4882a593Smuzhiyun 	scfg->valid_flags = cpu_to_le16(valid_flags);
2467*4882a593Smuzhiyun 	scfg->mode = mode;
2468*4882a593Smuzhiyun 	if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
2469*4882a593Smuzhiyun 		scfg->switch_tag = cpu_to_le16(hw->switch_tag);
2470*4882a593Smuzhiyun 		scfg->first_tag = cpu_to_le16(hw->first_tag);
2471*4882a593Smuzhiyun 		scfg->second_tag = cpu_to_le16(hw->second_tag);
2472*4882a593Smuzhiyun 	}
2473*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 	return status;
2476*4882a593Smuzhiyun }
2477*4882a593Smuzhiyun 
2478*4882a593Smuzhiyun /**
2479*4882a593Smuzhiyun  * i40e_aq_get_firmware_version
2480*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2481*4882a593Smuzhiyun  * @fw_major_version: firmware major version
2482*4882a593Smuzhiyun  * @fw_minor_version: firmware minor version
2483*4882a593Smuzhiyun  * @fw_build: firmware build number
2484*4882a593Smuzhiyun  * @api_major_version: major queue version
2485*4882a593Smuzhiyun  * @api_minor_version: minor queue version
2486*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2487*4882a593Smuzhiyun  *
2488*4882a593Smuzhiyun  * Get the firmware version from the admin queue commands
2489*4882a593Smuzhiyun  **/
i40e_aq_get_firmware_version(struct i40e_hw * hw,u16 * fw_major_version,u16 * fw_minor_version,u32 * fw_build,u16 * api_major_version,u16 * api_minor_version,struct i40e_asq_cmd_details * cmd_details)2490*4882a593Smuzhiyun i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
2491*4882a593Smuzhiyun 				u16 *fw_major_version, u16 *fw_minor_version,
2492*4882a593Smuzhiyun 				u32 *fw_build,
2493*4882a593Smuzhiyun 				u16 *api_major_version, u16 *api_minor_version,
2494*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2495*4882a593Smuzhiyun {
2496*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2497*4882a593Smuzhiyun 	struct i40e_aqc_get_version *resp =
2498*4882a593Smuzhiyun 		(struct i40e_aqc_get_version *)&desc.params.raw;
2499*4882a593Smuzhiyun 	i40e_status status;
2500*4882a593Smuzhiyun 
2501*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_version);
2502*4882a593Smuzhiyun 
2503*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2504*4882a593Smuzhiyun 
2505*4882a593Smuzhiyun 	if (!status) {
2506*4882a593Smuzhiyun 		if (fw_major_version)
2507*4882a593Smuzhiyun 			*fw_major_version = le16_to_cpu(resp->fw_major);
2508*4882a593Smuzhiyun 		if (fw_minor_version)
2509*4882a593Smuzhiyun 			*fw_minor_version = le16_to_cpu(resp->fw_minor);
2510*4882a593Smuzhiyun 		if (fw_build)
2511*4882a593Smuzhiyun 			*fw_build = le32_to_cpu(resp->fw_build);
2512*4882a593Smuzhiyun 		if (api_major_version)
2513*4882a593Smuzhiyun 			*api_major_version = le16_to_cpu(resp->api_major);
2514*4882a593Smuzhiyun 		if (api_minor_version)
2515*4882a593Smuzhiyun 			*api_minor_version = le16_to_cpu(resp->api_minor);
2516*4882a593Smuzhiyun 	}
2517*4882a593Smuzhiyun 
2518*4882a593Smuzhiyun 	return status;
2519*4882a593Smuzhiyun }
2520*4882a593Smuzhiyun 
2521*4882a593Smuzhiyun /**
2522*4882a593Smuzhiyun  * i40e_aq_send_driver_version
2523*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2524*4882a593Smuzhiyun  * @dv: driver's major, minor version
2525*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2526*4882a593Smuzhiyun  *
2527*4882a593Smuzhiyun  * Send the driver version to the firmware
2528*4882a593Smuzhiyun  **/
i40e_aq_send_driver_version(struct i40e_hw * hw,struct i40e_driver_version * dv,struct i40e_asq_cmd_details * cmd_details)2529*4882a593Smuzhiyun i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
2530*4882a593Smuzhiyun 				struct i40e_driver_version *dv,
2531*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2532*4882a593Smuzhiyun {
2533*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2534*4882a593Smuzhiyun 	struct i40e_aqc_driver_version *cmd =
2535*4882a593Smuzhiyun 		(struct i40e_aqc_driver_version *)&desc.params.raw;
2536*4882a593Smuzhiyun 	i40e_status status;
2537*4882a593Smuzhiyun 	u16 len;
2538*4882a593Smuzhiyun 
2539*4882a593Smuzhiyun 	if (dv == NULL)
2540*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
2541*4882a593Smuzhiyun 
2542*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_driver_version);
2543*4882a593Smuzhiyun 
2544*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
2545*4882a593Smuzhiyun 	cmd->driver_major_ver = dv->major_version;
2546*4882a593Smuzhiyun 	cmd->driver_minor_ver = dv->minor_version;
2547*4882a593Smuzhiyun 	cmd->driver_build_ver = dv->build_version;
2548*4882a593Smuzhiyun 	cmd->driver_subbuild_ver = dv->subbuild_version;
2549*4882a593Smuzhiyun 
2550*4882a593Smuzhiyun 	len = 0;
2551*4882a593Smuzhiyun 	while (len < sizeof(dv->driver_string) &&
2552*4882a593Smuzhiyun 	       (dv->driver_string[len] < 0x80) &&
2553*4882a593Smuzhiyun 	       dv->driver_string[len])
2554*4882a593Smuzhiyun 		len++;
2555*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, dv->driver_string,
2556*4882a593Smuzhiyun 				       len, cmd_details);
2557*4882a593Smuzhiyun 
2558*4882a593Smuzhiyun 	return status;
2559*4882a593Smuzhiyun }
2560*4882a593Smuzhiyun 
2561*4882a593Smuzhiyun /**
2562*4882a593Smuzhiyun  * i40e_get_link_status - get status of the HW network link
2563*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2564*4882a593Smuzhiyun  * @link_up: pointer to bool (true/false = linkup/linkdown)
2565*4882a593Smuzhiyun  *
2566*4882a593Smuzhiyun  * Variable link_up true if link is up, false if link is down.
2567*4882a593Smuzhiyun  * The variable link_up is invalid if returned value of status != 0
2568*4882a593Smuzhiyun  *
2569*4882a593Smuzhiyun  * Side effect: LinkStatusEvent reporting becomes enabled
2570*4882a593Smuzhiyun  **/
i40e_get_link_status(struct i40e_hw * hw,bool * link_up)2571*4882a593Smuzhiyun i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
2572*4882a593Smuzhiyun {
2573*4882a593Smuzhiyun 	i40e_status status = 0;
2574*4882a593Smuzhiyun 
2575*4882a593Smuzhiyun 	if (hw->phy.get_link_info) {
2576*4882a593Smuzhiyun 		status = i40e_update_link_info(hw);
2577*4882a593Smuzhiyun 
2578*4882a593Smuzhiyun 		if (status)
2579*4882a593Smuzhiyun 			i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
2580*4882a593Smuzhiyun 				   status);
2581*4882a593Smuzhiyun 	}
2582*4882a593Smuzhiyun 
2583*4882a593Smuzhiyun 	*link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
2584*4882a593Smuzhiyun 
2585*4882a593Smuzhiyun 	return status;
2586*4882a593Smuzhiyun }
2587*4882a593Smuzhiyun 
2588*4882a593Smuzhiyun /**
2589*4882a593Smuzhiyun  * i40e_updatelink_status - update status of the HW network link
2590*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2591*4882a593Smuzhiyun  **/
i40e_update_link_info(struct i40e_hw * hw)2592*4882a593Smuzhiyun noinline_for_stack i40e_status i40e_update_link_info(struct i40e_hw *hw)
2593*4882a593Smuzhiyun {
2594*4882a593Smuzhiyun 	struct i40e_aq_get_phy_abilities_resp abilities;
2595*4882a593Smuzhiyun 	i40e_status status = 0;
2596*4882a593Smuzhiyun 
2597*4882a593Smuzhiyun 	status = i40e_aq_get_link_info(hw, true, NULL, NULL);
2598*4882a593Smuzhiyun 	if (status)
2599*4882a593Smuzhiyun 		return status;
2600*4882a593Smuzhiyun 
2601*4882a593Smuzhiyun 	/* extra checking needed to ensure link info to user is timely */
2602*4882a593Smuzhiyun 	if ((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) &&
2603*4882a593Smuzhiyun 	    ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) ||
2604*4882a593Smuzhiyun 	     !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) {
2605*4882a593Smuzhiyun 		status = i40e_aq_get_phy_capabilities(hw, false, false,
2606*4882a593Smuzhiyun 						      &abilities, NULL);
2607*4882a593Smuzhiyun 		if (status)
2608*4882a593Smuzhiyun 			return status;
2609*4882a593Smuzhiyun 
2610*4882a593Smuzhiyun 		if (abilities.fec_cfg_curr_mod_ext_info &
2611*4882a593Smuzhiyun 		    I40E_AQ_ENABLE_FEC_AUTO)
2612*4882a593Smuzhiyun 			hw->phy.link_info.req_fec_info =
2613*4882a593Smuzhiyun 				(I40E_AQ_REQUEST_FEC_KR |
2614*4882a593Smuzhiyun 				 I40E_AQ_REQUEST_FEC_RS);
2615*4882a593Smuzhiyun 		else
2616*4882a593Smuzhiyun 			hw->phy.link_info.req_fec_info =
2617*4882a593Smuzhiyun 				abilities.fec_cfg_curr_mod_ext_info &
2618*4882a593Smuzhiyun 				(I40E_AQ_REQUEST_FEC_KR |
2619*4882a593Smuzhiyun 				 I40E_AQ_REQUEST_FEC_RS);
2620*4882a593Smuzhiyun 
2621*4882a593Smuzhiyun 		memcpy(hw->phy.link_info.module_type, &abilities.module_type,
2622*4882a593Smuzhiyun 		       sizeof(hw->phy.link_info.module_type));
2623*4882a593Smuzhiyun 	}
2624*4882a593Smuzhiyun 
2625*4882a593Smuzhiyun 	return status;
2626*4882a593Smuzhiyun }
2627*4882a593Smuzhiyun 
2628*4882a593Smuzhiyun /**
2629*4882a593Smuzhiyun  * i40e_aq_add_veb - Insert a VEB between the VSI and the MAC
2630*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2631*4882a593Smuzhiyun  * @uplink_seid: the MAC or other gizmo SEID
2632*4882a593Smuzhiyun  * @downlink_seid: the VSI SEID
2633*4882a593Smuzhiyun  * @enabled_tc: bitmap of TCs to be enabled
2634*4882a593Smuzhiyun  * @default_port: true for default port VSI, false for control port
2635*4882a593Smuzhiyun  * @veb_seid: pointer to where to put the resulting VEB SEID
2636*4882a593Smuzhiyun  * @enable_stats: true to turn on VEB stats
2637*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2638*4882a593Smuzhiyun  *
2639*4882a593Smuzhiyun  * This asks the FW to add a VEB between the uplink and downlink
2640*4882a593Smuzhiyun  * elements.  If the uplink SEID is 0, this will be a floating VEB.
2641*4882a593Smuzhiyun  **/
i40e_aq_add_veb(struct i40e_hw * hw,u16 uplink_seid,u16 downlink_seid,u8 enabled_tc,bool default_port,u16 * veb_seid,bool enable_stats,struct i40e_asq_cmd_details * cmd_details)2642*4882a593Smuzhiyun i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
2643*4882a593Smuzhiyun 				u16 downlink_seid, u8 enabled_tc,
2644*4882a593Smuzhiyun 				bool default_port, u16 *veb_seid,
2645*4882a593Smuzhiyun 				bool enable_stats,
2646*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2647*4882a593Smuzhiyun {
2648*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2649*4882a593Smuzhiyun 	struct i40e_aqc_add_veb *cmd =
2650*4882a593Smuzhiyun 		(struct i40e_aqc_add_veb *)&desc.params.raw;
2651*4882a593Smuzhiyun 	struct i40e_aqc_add_veb_completion *resp =
2652*4882a593Smuzhiyun 		(struct i40e_aqc_add_veb_completion *)&desc.params.raw;
2653*4882a593Smuzhiyun 	i40e_status status;
2654*4882a593Smuzhiyun 	u16 veb_flags = 0;
2655*4882a593Smuzhiyun 
2656*4882a593Smuzhiyun 	/* SEIDs need to either both be set or both be 0 for floating VEB */
2657*4882a593Smuzhiyun 	if (!!uplink_seid != !!downlink_seid)
2658*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
2659*4882a593Smuzhiyun 
2660*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_veb);
2661*4882a593Smuzhiyun 
2662*4882a593Smuzhiyun 	cmd->uplink_seid = cpu_to_le16(uplink_seid);
2663*4882a593Smuzhiyun 	cmd->downlink_seid = cpu_to_le16(downlink_seid);
2664*4882a593Smuzhiyun 	cmd->enable_tcs = enabled_tc;
2665*4882a593Smuzhiyun 	if (!uplink_seid)
2666*4882a593Smuzhiyun 		veb_flags |= I40E_AQC_ADD_VEB_FLOATING;
2667*4882a593Smuzhiyun 	if (default_port)
2668*4882a593Smuzhiyun 		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT;
2669*4882a593Smuzhiyun 	else
2670*4882a593Smuzhiyun 		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;
2671*4882a593Smuzhiyun 
2672*4882a593Smuzhiyun 	/* reverse logic here: set the bitflag to disable the stats */
2673*4882a593Smuzhiyun 	if (!enable_stats)
2674*4882a593Smuzhiyun 		veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;
2675*4882a593Smuzhiyun 
2676*4882a593Smuzhiyun 	cmd->veb_flags = cpu_to_le16(veb_flags);
2677*4882a593Smuzhiyun 
2678*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2679*4882a593Smuzhiyun 
2680*4882a593Smuzhiyun 	if (!status && veb_seid)
2681*4882a593Smuzhiyun 		*veb_seid = le16_to_cpu(resp->veb_seid);
2682*4882a593Smuzhiyun 
2683*4882a593Smuzhiyun 	return status;
2684*4882a593Smuzhiyun }
2685*4882a593Smuzhiyun 
2686*4882a593Smuzhiyun /**
2687*4882a593Smuzhiyun  * i40e_aq_get_veb_parameters - Retrieve VEB parameters
2688*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2689*4882a593Smuzhiyun  * @veb_seid: the SEID of the VEB to query
2690*4882a593Smuzhiyun  * @switch_id: the uplink switch id
2691*4882a593Smuzhiyun  * @floating: set to true if the VEB is floating
2692*4882a593Smuzhiyun  * @statistic_index: index of the stats counter block for this VEB
2693*4882a593Smuzhiyun  * @vebs_used: number of VEB's used by function
2694*4882a593Smuzhiyun  * @vebs_free: total VEB's not reserved by any function
2695*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2696*4882a593Smuzhiyun  *
2697*4882a593Smuzhiyun  * This retrieves the parameters for a particular VEB, specified by
2698*4882a593Smuzhiyun  * uplink_seid, and returns them to the caller.
2699*4882a593Smuzhiyun  **/
i40e_aq_get_veb_parameters(struct i40e_hw * hw,u16 veb_seid,u16 * switch_id,bool * floating,u16 * statistic_index,u16 * vebs_used,u16 * vebs_free,struct i40e_asq_cmd_details * cmd_details)2700*4882a593Smuzhiyun i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw,
2701*4882a593Smuzhiyun 				u16 veb_seid, u16 *switch_id,
2702*4882a593Smuzhiyun 				bool *floating, u16 *statistic_index,
2703*4882a593Smuzhiyun 				u16 *vebs_used, u16 *vebs_free,
2704*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2705*4882a593Smuzhiyun {
2706*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2707*4882a593Smuzhiyun 	struct i40e_aqc_get_veb_parameters_completion *cmd_resp =
2708*4882a593Smuzhiyun 		(struct i40e_aqc_get_veb_parameters_completion *)
2709*4882a593Smuzhiyun 		&desc.params.raw;
2710*4882a593Smuzhiyun 	i40e_status status;
2711*4882a593Smuzhiyun 
2712*4882a593Smuzhiyun 	if (veb_seid == 0)
2713*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
2714*4882a593Smuzhiyun 
2715*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
2716*4882a593Smuzhiyun 					  i40e_aqc_opc_get_veb_parameters);
2717*4882a593Smuzhiyun 	cmd_resp->seid = cpu_to_le16(veb_seid);
2718*4882a593Smuzhiyun 
2719*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2720*4882a593Smuzhiyun 	if (status)
2721*4882a593Smuzhiyun 		goto get_veb_exit;
2722*4882a593Smuzhiyun 
2723*4882a593Smuzhiyun 	if (switch_id)
2724*4882a593Smuzhiyun 		*switch_id = le16_to_cpu(cmd_resp->switch_id);
2725*4882a593Smuzhiyun 	if (statistic_index)
2726*4882a593Smuzhiyun 		*statistic_index = le16_to_cpu(cmd_resp->statistic_index);
2727*4882a593Smuzhiyun 	if (vebs_used)
2728*4882a593Smuzhiyun 		*vebs_used = le16_to_cpu(cmd_resp->vebs_used);
2729*4882a593Smuzhiyun 	if (vebs_free)
2730*4882a593Smuzhiyun 		*vebs_free = le16_to_cpu(cmd_resp->vebs_free);
2731*4882a593Smuzhiyun 	if (floating) {
2732*4882a593Smuzhiyun 		u16 flags = le16_to_cpu(cmd_resp->veb_flags);
2733*4882a593Smuzhiyun 
2734*4882a593Smuzhiyun 		if (flags & I40E_AQC_ADD_VEB_FLOATING)
2735*4882a593Smuzhiyun 			*floating = true;
2736*4882a593Smuzhiyun 		else
2737*4882a593Smuzhiyun 			*floating = false;
2738*4882a593Smuzhiyun 	}
2739*4882a593Smuzhiyun 
2740*4882a593Smuzhiyun get_veb_exit:
2741*4882a593Smuzhiyun 	return status;
2742*4882a593Smuzhiyun }
2743*4882a593Smuzhiyun 
2744*4882a593Smuzhiyun /**
2745*4882a593Smuzhiyun  * i40e_aq_add_macvlan
2746*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2747*4882a593Smuzhiyun  * @seid: VSI for the mac address
2748*4882a593Smuzhiyun  * @mv_list: list of macvlans to be added
2749*4882a593Smuzhiyun  * @count: length of the list
2750*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2751*4882a593Smuzhiyun  *
2752*4882a593Smuzhiyun  * Add MAC/VLAN addresses to the HW filtering
2753*4882a593Smuzhiyun  **/
i40e_aq_add_macvlan(struct i40e_hw * hw,u16 seid,struct i40e_aqc_add_macvlan_element_data * mv_list,u16 count,struct i40e_asq_cmd_details * cmd_details)2754*4882a593Smuzhiyun i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
2755*4882a593Smuzhiyun 			struct i40e_aqc_add_macvlan_element_data *mv_list,
2756*4882a593Smuzhiyun 			u16 count, struct i40e_asq_cmd_details *cmd_details)
2757*4882a593Smuzhiyun {
2758*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2759*4882a593Smuzhiyun 	struct i40e_aqc_macvlan *cmd =
2760*4882a593Smuzhiyun 		(struct i40e_aqc_macvlan *)&desc.params.raw;
2761*4882a593Smuzhiyun 	i40e_status status;
2762*4882a593Smuzhiyun 	u16 buf_size;
2763*4882a593Smuzhiyun 	int i;
2764*4882a593Smuzhiyun 
2765*4882a593Smuzhiyun 	if (count == 0 || !mv_list || !hw)
2766*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
2767*4882a593Smuzhiyun 
2768*4882a593Smuzhiyun 	buf_size = count * sizeof(*mv_list);
2769*4882a593Smuzhiyun 
2770*4882a593Smuzhiyun 	/* prep the rest of the request */
2771*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
2772*4882a593Smuzhiyun 	cmd->num_addresses = cpu_to_le16(count);
2773*4882a593Smuzhiyun 	cmd->seid[0] = cpu_to_le16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
2774*4882a593Smuzhiyun 	cmd->seid[1] = 0;
2775*4882a593Smuzhiyun 	cmd->seid[2] = 0;
2776*4882a593Smuzhiyun 
2777*4882a593Smuzhiyun 	for (i = 0; i < count; i++)
2778*4882a593Smuzhiyun 		if (is_multicast_ether_addr(mv_list[i].mac_addr))
2779*4882a593Smuzhiyun 			mv_list[i].flags |=
2780*4882a593Smuzhiyun 			       cpu_to_le16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
2781*4882a593Smuzhiyun 
2782*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2783*4882a593Smuzhiyun 	if (buf_size > I40E_AQ_LARGE_BUF)
2784*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2785*4882a593Smuzhiyun 
2786*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
2787*4882a593Smuzhiyun 				       cmd_details);
2788*4882a593Smuzhiyun 
2789*4882a593Smuzhiyun 	return status;
2790*4882a593Smuzhiyun }
2791*4882a593Smuzhiyun 
2792*4882a593Smuzhiyun /**
2793*4882a593Smuzhiyun  * i40e_aq_remove_macvlan
2794*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2795*4882a593Smuzhiyun  * @seid: VSI for the mac address
2796*4882a593Smuzhiyun  * @mv_list: list of macvlans to be removed
2797*4882a593Smuzhiyun  * @count: length of the list
2798*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2799*4882a593Smuzhiyun  *
2800*4882a593Smuzhiyun  * Remove MAC/VLAN addresses from the HW filtering
2801*4882a593Smuzhiyun  **/
i40e_aq_remove_macvlan(struct i40e_hw * hw,u16 seid,struct i40e_aqc_remove_macvlan_element_data * mv_list,u16 count,struct i40e_asq_cmd_details * cmd_details)2802*4882a593Smuzhiyun i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
2803*4882a593Smuzhiyun 			struct i40e_aqc_remove_macvlan_element_data *mv_list,
2804*4882a593Smuzhiyun 			u16 count, struct i40e_asq_cmd_details *cmd_details)
2805*4882a593Smuzhiyun {
2806*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2807*4882a593Smuzhiyun 	struct i40e_aqc_macvlan *cmd =
2808*4882a593Smuzhiyun 		(struct i40e_aqc_macvlan *)&desc.params.raw;
2809*4882a593Smuzhiyun 	i40e_status status;
2810*4882a593Smuzhiyun 	u16 buf_size;
2811*4882a593Smuzhiyun 
2812*4882a593Smuzhiyun 	if (count == 0 || !mv_list || !hw)
2813*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
2814*4882a593Smuzhiyun 
2815*4882a593Smuzhiyun 	buf_size = count * sizeof(*mv_list);
2816*4882a593Smuzhiyun 
2817*4882a593Smuzhiyun 	/* prep the rest of the request */
2818*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
2819*4882a593Smuzhiyun 	cmd->num_addresses = cpu_to_le16(count);
2820*4882a593Smuzhiyun 	cmd->seid[0] = cpu_to_le16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
2821*4882a593Smuzhiyun 	cmd->seid[1] = 0;
2822*4882a593Smuzhiyun 	cmd->seid[2] = 0;
2823*4882a593Smuzhiyun 
2824*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2825*4882a593Smuzhiyun 	if (buf_size > I40E_AQ_LARGE_BUF)
2826*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2827*4882a593Smuzhiyun 
2828*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
2829*4882a593Smuzhiyun 				       cmd_details);
2830*4882a593Smuzhiyun 
2831*4882a593Smuzhiyun 	return status;
2832*4882a593Smuzhiyun }
2833*4882a593Smuzhiyun 
2834*4882a593Smuzhiyun /**
2835*4882a593Smuzhiyun  * i40e_mirrorrule_op - Internal helper function to add/delete mirror rule
2836*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2837*4882a593Smuzhiyun  * @opcode: AQ opcode for add or delete mirror rule
2838*4882a593Smuzhiyun  * @sw_seid: Switch SEID (to which rule refers)
2839*4882a593Smuzhiyun  * @rule_type: Rule Type (ingress/egress/VLAN)
2840*4882a593Smuzhiyun  * @id: Destination VSI SEID or Rule ID
2841*4882a593Smuzhiyun  * @count: length of the list
2842*4882a593Smuzhiyun  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
2843*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2844*4882a593Smuzhiyun  * @rule_id: Rule ID returned from FW
2845*4882a593Smuzhiyun  * @rules_used: Number of rules used in internal switch
2846*4882a593Smuzhiyun  * @rules_free: Number of rules free in internal switch
2847*4882a593Smuzhiyun  *
2848*4882a593Smuzhiyun  * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
2849*4882a593Smuzhiyun  * VEBs/VEPA elements only
2850*4882a593Smuzhiyun  **/
i40e_mirrorrule_op(struct i40e_hw * hw,u16 opcode,u16 sw_seid,u16 rule_type,u16 id,u16 count,__le16 * mr_list,struct i40e_asq_cmd_details * cmd_details,u16 * rule_id,u16 * rules_used,u16 * rules_free)2851*4882a593Smuzhiyun static i40e_status i40e_mirrorrule_op(struct i40e_hw *hw,
2852*4882a593Smuzhiyun 				u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
2853*4882a593Smuzhiyun 				u16 count, __le16 *mr_list,
2854*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details,
2855*4882a593Smuzhiyun 				u16 *rule_id, u16 *rules_used, u16 *rules_free)
2856*4882a593Smuzhiyun {
2857*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2858*4882a593Smuzhiyun 	struct i40e_aqc_add_delete_mirror_rule *cmd =
2859*4882a593Smuzhiyun 		(struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
2860*4882a593Smuzhiyun 	struct i40e_aqc_add_delete_mirror_rule_completion *resp =
2861*4882a593Smuzhiyun 	(struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
2862*4882a593Smuzhiyun 	i40e_status status;
2863*4882a593Smuzhiyun 	u16 buf_size;
2864*4882a593Smuzhiyun 
2865*4882a593Smuzhiyun 	buf_size = count * sizeof(*mr_list);
2866*4882a593Smuzhiyun 
2867*4882a593Smuzhiyun 	/* prep the rest of the request */
2868*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, opcode);
2869*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(sw_seid);
2870*4882a593Smuzhiyun 	cmd->rule_type = cpu_to_le16(rule_type &
2871*4882a593Smuzhiyun 				     I40E_AQC_MIRROR_RULE_TYPE_MASK);
2872*4882a593Smuzhiyun 	cmd->num_entries = cpu_to_le16(count);
2873*4882a593Smuzhiyun 	/* Dest VSI for add, rule_id for delete */
2874*4882a593Smuzhiyun 	cmd->destination = cpu_to_le16(id);
2875*4882a593Smuzhiyun 	if (mr_list) {
2876*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF |
2877*4882a593Smuzhiyun 						I40E_AQ_FLAG_RD));
2878*4882a593Smuzhiyun 		if (buf_size > I40E_AQ_LARGE_BUF)
2879*4882a593Smuzhiyun 			desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2880*4882a593Smuzhiyun 	}
2881*4882a593Smuzhiyun 
2882*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, mr_list, buf_size,
2883*4882a593Smuzhiyun 				       cmd_details);
2884*4882a593Smuzhiyun 	if (!status ||
2885*4882a593Smuzhiyun 	    hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) {
2886*4882a593Smuzhiyun 		if (rule_id)
2887*4882a593Smuzhiyun 			*rule_id = le16_to_cpu(resp->rule_id);
2888*4882a593Smuzhiyun 		if (rules_used)
2889*4882a593Smuzhiyun 			*rules_used = le16_to_cpu(resp->mirror_rules_used);
2890*4882a593Smuzhiyun 		if (rules_free)
2891*4882a593Smuzhiyun 			*rules_free = le16_to_cpu(resp->mirror_rules_free);
2892*4882a593Smuzhiyun 	}
2893*4882a593Smuzhiyun 	return status;
2894*4882a593Smuzhiyun }
2895*4882a593Smuzhiyun 
2896*4882a593Smuzhiyun /**
2897*4882a593Smuzhiyun  * i40e_aq_add_mirrorrule - add a mirror rule
2898*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2899*4882a593Smuzhiyun  * @sw_seid: Switch SEID (to which rule refers)
2900*4882a593Smuzhiyun  * @rule_type: Rule Type (ingress/egress/VLAN)
2901*4882a593Smuzhiyun  * @dest_vsi: SEID of VSI to which packets will be mirrored
2902*4882a593Smuzhiyun  * @count: length of the list
2903*4882a593Smuzhiyun  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
2904*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2905*4882a593Smuzhiyun  * @rule_id: Rule ID returned from FW
2906*4882a593Smuzhiyun  * @rules_used: Number of rules used in internal switch
2907*4882a593Smuzhiyun  * @rules_free: Number of rules free in internal switch
2908*4882a593Smuzhiyun  *
2909*4882a593Smuzhiyun  * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
2910*4882a593Smuzhiyun  **/
i40e_aq_add_mirrorrule(struct i40e_hw * hw,u16 sw_seid,u16 rule_type,u16 dest_vsi,u16 count,__le16 * mr_list,struct i40e_asq_cmd_details * cmd_details,u16 * rule_id,u16 * rules_used,u16 * rules_free)2911*4882a593Smuzhiyun i40e_status i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
2912*4882a593Smuzhiyun 			u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
2913*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details,
2914*4882a593Smuzhiyun 			u16 *rule_id, u16 *rules_used, u16 *rules_free)
2915*4882a593Smuzhiyun {
2916*4882a593Smuzhiyun 	if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
2917*4882a593Smuzhiyun 	    rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
2918*4882a593Smuzhiyun 		if (count == 0 || !mr_list)
2919*4882a593Smuzhiyun 			return I40E_ERR_PARAM;
2920*4882a593Smuzhiyun 	}
2921*4882a593Smuzhiyun 
2922*4882a593Smuzhiyun 	return i40e_mirrorrule_op(hw, i40e_aqc_opc_add_mirror_rule, sw_seid,
2923*4882a593Smuzhiyun 				  rule_type, dest_vsi, count, mr_list,
2924*4882a593Smuzhiyun 				  cmd_details, rule_id, rules_used, rules_free);
2925*4882a593Smuzhiyun }
2926*4882a593Smuzhiyun 
2927*4882a593Smuzhiyun /**
2928*4882a593Smuzhiyun  * i40e_aq_delete_mirrorrule - delete a mirror rule
2929*4882a593Smuzhiyun  * @hw: pointer to the hw struct
2930*4882a593Smuzhiyun  * @sw_seid: Switch SEID (to which rule refers)
2931*4882a593Smuzhiyun  * @rule_type: Rule Type (ingress/egress/VLAN)
2932*4882a593Smuzhiyun  * @count: length of the list
2933*4882a593Smuzhiyun  * @rule_id: Rule ID that is returned in the receive desc as part of
2934*4882a593Smuzhiyun  *		add_mirrorrule.
2935*4882a593Smuzhiyun  * @mr_list: list of mirrored VLAN IDs to be removed
2936*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
2937*4882a593Smuzhiyun  * @rules_used: Number of rules used in internal switch
2938*4882a593Smuzhiyun  * @rules_free: Number of rules free in internal switch
2939*4882a593Smuzhiyun  *
2940*4882a593Smuzhiyun  * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
2941*4882a593Smuzhiyun  **/
i40e_aq_delete_mirrorrule(struct i40e_hw * hw,u16 sw_seid,u16 rule_type,u16 rule_id,u16 count,__le16 * mr_list,struct i40e_asq_cmd_details * cmd_details,u16 * rules_used,u16 * rules_free)2942*4882a593Smuzhiyun i40e_status i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
2943*4882a593Smuzhiyun 			u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
2944*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details,
2945*4882a593Smuzhiyun 			u16 *rules_used, u16 *rules_free)
2946*4882a593Smuzhiyun {
2947*4882a593Smuzhiyun 	/* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
2948*4882a593Smuzhiyun 	if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
2949*4882a593Smuzhiyun 		/* count and mr_list shall be valid for rule_type INGRESS VLAN
2950*4882a593Smuzhiyun 		 * mirroring. For other rule_type, count and rule_type should
2951*4882a593Smuzhiyun 		 * not matter.
2952*4882a593Smuzhiyun 		 */
2953*4882a593Smuzhiyun 		if (count == 0 || !mr_list)
2954*4882a593Smuzhiyun 			return I40E_ERR_PARAM;
2955*4882a593Smuzhiyun 	}
2956*4882a593Smuzhiyun 
2957*4882a593Smuzhiyun 	return i40e_mirrorrule_op(hw, i40e_aqc_opc_delete_mirror_rule, sw_seid,
2958*4882a593Smuzhiyun 				  rule_type, rule_id, count, mr_list,
2959*4882a593Smuzhiyun 				  cmd_details, NULL, rules_used, rules_free);
2960*4882a593Smuzhiyun }
2961*4882a593Smuzhiyun 
2962*4882a593Smuzhiyun /**
2963*4882a593Smuzhiyun  * i40e_aq_send_msg_to_vf
2964*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
2965*4882a593Smuzhiyun  * @vfid: VF id to send msg
2966*4882a593Smuzhiyun  * @v_opcode: opcodes for VF-PF communication
2967*4882a593Smuzhiyun  * @v_retval: return error code
2968*4882a593Smuzhiyun  * @msg: pointer to the msg buffer
2969*4882a593Smuzhiyun  * @msglen: msg length
2970*4882a593Smuzhiyun  * @cmd_details: pointer to command details
2971*4882a593Smuzhiyun  *
2972*4882a593Smuzhiyun  * send msg to vf
2973*4882a593Smuzhiyun  **/
i40e_aq_send_msg_to_vf(struct i40e_hw * hw,u16 vfid,u32 v_opcode,u32 v_retval,u8 * msg,u16 msglen,struct i40e_asq_cmd_details * cmd_details)2974*4882a593Smuzhiyun i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
2975*4882a593Smuzhiyun 				u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
2976*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
2977*4882a593Smuzhiyun {
2978*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
2979*4882a593Smuzhiyun 	struct i40e_aqc_pf_vf_message *cmd =
2980*4882a593Smuzhiyun 		(struct i40e_aqc_pf_vf_message *)&desc.params.raw;
2981*4882a593Smuzhiyun 	i40e_status status;
2982*4882a593Smuzhiyun 
2983*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_vf);
2984*4882a593Smuzhiyun 	cmd->id = cpu_to_le32(vfid);
2985*4882a593Smuzhiyun 	desc.cookie_high = cpu_to_le32(v_opcode);
2986*4882a593Smuzhiyun 	desc.cookie_low = cpu_to_le32(v_retval);
2987*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_SI);
2988*4882a593Smuzhiyun 	if (msglen) {
2989*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF |
2990*4882a593Smuzhiyun 						I40E_AQ_FLAG_RD));
2991*4882a593Smuzhiyun 		if (msglen > I40E_AQ_LARGE_BUF)
2992*4882a593Smuzhiyun 			desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2993*4882a593Smuzhiyun 		desc.datalen = cpu_to_le16(msglen);
2994*4882a593Smuzhiyun 	}
2995*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, msg, msglen, cmd_details);
2996*4882a593Smuzhiyun 
2997*4882a593Smuzhiyun 	return status;
2998*4882a593Smuzhiyun }
2999*4882a593Smuzhiyun 
3000*4882a593Smuzhiyun /**
3001*4882a593Smuzhiyun  * i40e_aq_debug_read_register
3002*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3003*4882a593Smuzhiyun  * @reg_addr: register address
3004*4882a593Smuzhiyun  * @reg_val: register value
3005*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3006*4882a593Smuzhiyun  *
3007*4882a593Smuzhiyun  * Read the register using the admin queue commands
3008*4882a593Smuzhiyun  **/
i40e_aq_debug_read_register(struct i40e_hw * hw,u32 reg_addr,u64 * reg_val,struct i40e_asq_cmd_details * cmd_details)3009*4882a593Smuzhiyun i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
3010*4882a593Smuzhiyun 				u32 reg_addr, u64 *reg_val,
3011*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3012*4882a593Smuzhiyun {
3013*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3014*4882a593Smuzhiyun 	struct i40e_aqc_debug_reg_read_write *cmd_resp =
3015*4882a593Smuzhiyun 		(struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3016*4882a593Smuzhiyun 	i40e_status status;
3017*4882a593Smuzhiyun 
3018*4882a593Smuzhiyun 	if (reg_val == NULL)
3019*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
3020*4882a593Smuzhiyun 
3021*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
3022*4882a593Smuzhiyun 
3023*4882a593Smuzhiyun 	cmd_resp->address = cpu_to_le32(reg_addr);
3024*4882a593Smuzhiyun 
3025*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3026*4882a593Smuzhiyun 
3027*4882a593Smuzhiyun 	if (!status) {
3028*4882a593Smuzhiyun 		*reg_val = ((u64)le32_to_cpu(cmd_resp->value_high) << 32) |
3029*4882a593Smuzhiyun 			   (u64)le32_to_cpu(cmd_resp->value_low);
3030*4882a593Smuzhiyun 	}
3031*4882a593Smuzhiyun 
3032*4882a593Smuzhiyun 	return status;
3033*4882a593Smuzhiyun }
3034*4882a593Smuzhiyun 
3035*4882a593Smuzhiyun /**
3036*4882a593Smuzhiyun  * i40e_aq_debug_write_register
3037*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3038*4882a593Smuzhiyun  * @reg_addr: register address
3039*4882a593Smuzhiyun  * @reg_val: register value
3040*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3041*4882a593Smuzhiyun  *
3042*4882a593Smuzhiyun  * Write to a register using the admin queue commands
3043*4882a593Smuzhiyun  **/
i40e_aq_debug_write_register(struct i40e_hw * hw,u32 reg_addr,u64 reg_val,struct i40e_asq_cmd_details * cmd_details)3044*4882a593Smuzhiyun i40e_status i40e_aq_debug_write_register(struct i40e_hw *hw,
3045*4882a593Smuzhiyun 					u32 reg_addr, u64 reg_val,
3046*4882a593Smuzhiyun 					struct i40e_asq_cmd_details *cmd_details)
3047*4882a593Smuzhiyun {
3048*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3049*4882a593Smuzhiyun 	struct i40e_aqc_debug_reg_read_write *cmd =
3050*4882a593Smuzhiyun 		(struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3051*4882a593Smuzhiyun 	i40e_status status;
3052*4882a593Smuzhiyun 
3053*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_write_reg);
3054*4882a593Smuzhiyun 
3055*4882a593Smuzhiyun 	cmd->address = cpu_to_le32(reg_addr);
3056*4882a593Smuzhiyun 	cmd->value_high = cpu_to_le32((u32)(reg_val >> 32));
3057*4882a593Smuzhiyun 	cmd->value_low = cpu_to_le32((u32)(reg_val & 0xFFFFFFFF));
3058*4882a593Smuzhiyun 
3059*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3060*4882a593Smuzhiyun 
3061*4882a593Smuzhiyun 	return status;
3062*4882a593Smuzhiyun }
3063*4882a593Smuzhiyun 
3064*4882a593Smuzhiyun /**
3065*4882a593Smuzhiyun  * i40e_aq_request_resource
3066*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3067*4882a593Smuzhiyun  * @resource: resource id
3068*4882a593Smuzhiyun  * @access: access type
3069*4882a593Smuzhiyun  * @sdp_number: resource number
3070*4882a593Smuzhiyun  * @timeout: the maximum time in ms that the driver may hold the resource
3071*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3072*4882a593Smuzhiyun  *
3073*4882a593Smuzhiyun  * requests common resource using the admin queue commands
3074*4882a593Smuzhiyun  **/
i40e_aq_request_resource(struct i40e_hw * hw,enum i40e_aq_resources_ids resource,enum i40e_aq_resource_access_type access,u8 sdp_number,u64 * timeout,struct i40e_asq_cmd_details * cmd_details)3075*4882a593Smuzhiyun i40e_status i40e_aq_request_resource(struct i40e_hw *hw,
3076*4882a593Smuzhiyun 				enum i40e_aq_resources_ids resource,
3077*4882a593Smuzhiyun 				enum i40e_aq_resource_access_type access,
3078*4882a593Smuzhiyun 				u8 sdp_number, u64 *timeout,
3079*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3080*4882a593Smuzhiyun {
3081*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3082*4882a593Smuzhiyun 	struct i40e_aqc_request_resource *cmd_resp =
3083*4882a593Smuzhiyun 		(struct i40e_aqc_request_resource *)&desc.params.raw;
3084*4882a593Smuzhiyun 	i40e_status status;
3085*4882a593Smuzhiyun 
3086*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_request_resource);
3087*4882a593Smuzhiyun 
3088*4882a593Smuzhiyun 	cmd_resp->resource_id = cpu_to_le16(resource);
3089*4882a593Smuzhiyun 	cmd_resp->access_type = cpu_to_le16(access);
3090*4882a593Smuzhiyun 	cmd_resp->resource_number = cpu_to_le32(sdp_number);
3091*4882a593Smuzhiyun 
3092*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3093*4882a593Smuzhiyun 	/* The completion specifies the maximum time in ms that the driver
3094*4882a593Smuzhiyun 	 * may hold the resource in the Timeout field.
3095*4882a593Smuzhiyun 	 * If the resource is held by someone else, the command completes with
3096*4882a593Smuzhiyun 	 * busy return value and the timeout field indicates the maximum time
3097*4882a593Smuzhiyun 	 * the current owner of the resource has to free it.
3098*4882a593Smuzhiyun 	 */
3099*4882a593Smuzhiyun 	if (!status || hw->aq.asq_last_status == I40E_AQ_RC_EBUSY)
3100*4882a593Smuzhiyun 		*timeout = le32_to_cpu(cmd_resp->timeout);
3101*4882a593Smuzhiyun 
3102*4882a593Smuzhiyun 	return status;
3103*4882a593Smuzhiyun }
3104*4882a593Smuzhiyun 
3105*4882a593Smuzhiyun /**
3106*4882a593Smuzhiyun  * i40e_aq_release_resource
3107*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3108*4882a593Smuzhiyun  * @resource: resource id
3109*4882a593Smuzhiyun  * @sdp_number: resource number
3110*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3111*4882a593Smuzhiyun  *
3112*4882a593Smuzhiyun  * release common resource using the admin queue commands
3113*4882a593Smuzhiyun  **/
i40e_aq_release_resource(struct i40e_hw * hw,enum i40e_aq_resources_ids resource,u8 sdp_number,struct i40e_asq_cmd_details * cmd_details)3114*4882a593Smuzhiyun i40e_status i40e_aq_release_resource(struct i40e_hw *hw,
3115*4882a593Smuzhiyun 				enum i40e_aq_resources_ids resource,
3116*4882a593Smuzhiyun 				u8 sdp_number,
3117*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3118*4882a593Smuzhiyun {
3119*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3120*4882a593Smuzhiyun 	struct i40e_aqc_request_resource *cmd =
3121*4882a593Smuzhiyun 		(struct i40e_aqc_request_resource *)&desc.params.raw;
3122*4882a593Smuzhiyun 	i40e_status status;
3123*4882a593Smuzhiyun 
3124*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_release_resource);
3125*4882a593Smuzhiyun 
3126*4882a593Smuzhiyun 	cmd->resource_id = cpu_to_le16(resource);
3127*4882a593Smuzhiyun 	cmd->resource_number = cpu_to_le32(sdp_number);
3128*4882a593Smuzhiyun 
3129*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3130*4882a593Smuzhiyun 
3131*4882a593Smuzhiyun 	return status;
3132*4882a593Smuzhiyun }
3133*4882a593Smuzhiyun 
3134*4882a593Smuzhiyun /**
3135*4882a593Smuzhiyun  * i40e_aq_read_nvm
3136*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3137*4882a593Smuzhiyun  * @module_pointer: module pointer location in words from the NVM beginning
3138*4882a593Smuzhiyun  * @offset: byte offset from the module beginning
3139*4882a593Smuzhiyun  * @length: length of the section to be read (in bytes from the offset)
3140*4882a593Smuzhiyun  * @data: command buffer (size [bytes] = length)
3141*4882a593Smuzhiyun  * @last_command: tells if this is the last command in a series
3142*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3143*4882a593Smuzhiyun  *
3144*4882a593Smuzhiyun  * Read the NVM using the admin queue commands
3145*4882a593Smuzhiyun  **/
i40e_aq_read_nvm(struct i40e_hw * hw,u8 module_pointer,u32 offset,u16 length,void * data,bool last_command,struct i40e_asq_cmd_details * cmd_details)3146*4882a593Smuzhiyun i40e_status i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
3147*4882a593Smuzhiyun 				u32 offset, u16 length, void *data,
3148*4882a593Smuzhiyun 				bool last_command,
3149*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3150*4882a593Smuzhiyun {
3151*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3152*4882a593Smuzhiyun 	struct i40e_aqc_nvm_update *cmd =
3153*4882a593Smuzhiyun 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
3154*4882a593Smuzhiyun 	i40e_status status;
3155*4882a593Smuzhiyun 
3156*4882a593Smuzhiyun 	/* In offset the highest byte must be zeroed. */
3157*4882a593Smuzhiyun 	if (offset & 0xFF000000) {
3158*4882a593Smuzhiyun 		status = I40E_ERR_PARAM;
3159*4882a593Smuzhiyun 		goto i40e_aq_read_nvm_exit;
3160*4882a593Smuzhiyun 	}
3161*4882a593Smuzhiyun 
3162*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_read);
3163*4882a593Smuzhiyun 
3164*4882a593Smuzhiyun 	/* If this is the last command in a series, set the proper flag. */
3165*4882a593Smuzhiyun 	if (last_command)
3166*4882a593Smuzhiyun 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3167*4882a593Smuzhiyun 	cmd->module_pointer = module_pointer;
3168*4882a593Smuzhiyun 	cmd->offset = cpu_to_le32(offset);
3169*4882a593Smuzhiyun 	cmd->length = cpu_to_le16(length);
3170*4882a593Smuzhiyun 
3171*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3172*4882a593Smuzhiyun 	if (length > I40E_AQ_LARGE_BUF)
3173*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3174*4882a593Smuzhiyun 
3175*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
3176*4882a593Smuzhiyun 
3177*4882a593Smuzhiyun i40e_aq_read_nvm_exit:
3178*4882a593Smuzhiyun 	return status;
3179*4882a593Smuzhiyun }
3180*4882a593Smuzhiyun 
3181*4882a593Smuzhiyun /**
3182*4882a593Smuzhiyun  * i40e_aq_erase_nvm
3183*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3184*4882a593Smuzhiyun  * @module_pointer: module pointer location in words from the NVM beginning
3185*4882a593Smuzhiyun  * @offset: offset in the module (expressed in 4 KB from module's beginning)
3186*4882a593Smuzhiyun  * @length: length of the section to be erased (expressed in 4 KB)
3187*4882a593Smuzhiyun  * @last_command: tells if this is the last command in a series
3188*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3189*4882a593Smuzhiyun  *
3190*4882a593Smuzhiyun  * Erase the NVM sector using the admin queue commands
3191*4882a593Smuzhiyun  **/
i40e_aq_erase_nvm(struct i40e_hw * hw,u8 module_pointer,u32 offset,u16 length,bool last_command,struct i40e_asq_cmd_details * cmd_details)3192*4882a593Smuzhiyun i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
3193*4882a593Smuzhiyun 			      u32 offset, u16 length, bool last_command,
3194*4882a593Smuzhiyun 			      struct i40e_asq_cmd_details *cmd_details)
3195*4882a593Smuzhiyun {
3196*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3197*4882a593Smuzhiyun 	struct i40e_aqc_nvm_update *cmd =
3198*4882a593Smuzhiyun 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
3199*4882a593Smuzhiyun 	i40e_status status;
3200*4882a593Smuzhiyun 
3201*4882a593Smuzhiyun 	/* In offset the highest byte must be zeroed. */
3202*4882a593Smuzhiyun 	if (offset & 0xFF000000) {
3203*4882a593Smuzhiyun 		status = I40E_ERR_PARAM;
3204*4882a593Smuzhiyun 		goto i40e_aq_erase_nvm_exit;
3205*4882a593Smuzhiyun 	}
3206*4882a593Smuzhiyun 
3207*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_erase);
3208*4882a593Smuzhiyun 
3209*4882a593Smuzhiyun 	/* If this is the last command in a series, set the proper flag. */
3210*4882a593Smuzhiyun 	if (last_command)
3211*4882a593Smuzhiyun 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3212*4882a593Smuzhiyun 	cmd->module_pointer = module_pointer;
3213*4882a593Smuzhiyun 	cmd->offset = cpu_to_le32(offset);
3214*4882a593Smuzhiyun 	cmd->length = cpu_to_le16(length);
3215*4882a593Smuzhiyun 
3216*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3217*4882a593Smuzhiyun 
3218*4882a593Smuzhiyun i40e_aq_erase_nvm_exit:
3219*4882a593Smuzhiyun 	return status;
3220*4882a593Smuzhiyun }
3221*4882a593Smuzhiyun 
3222*4882a593Smuzhiyun /**
3223*4882a593Smuzhiyun  * i40e_parse_discover_capabilities
3224*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3225*4882a593Smuzhiyun  * @buff: pointer to a buffer containing device/function capability records
3226*4882a593Smuzhiyun  * @cap_count: number of capability records in the list
3227*4882a593Smuzhiyun  * @list_type_opc: type of capabilities list to parse
3228*4882a593Smuzhiyun  *
3229*4882a593Smuzhiyun  * Parse the device/function capabilities list.
3230*4882a593Smuzhiyun  **/
i40e_parse_discover_capabilities(struct i40e_hw * hw,void * buff,u32 cap_count,enum i40e_admin_queue_opc list_type_opc)3231*4882a593Smuzhiyun static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
3232*4882a593Smuzhiyun 				     u32 cap_count,
3233*4882a593Smuzhiyun 				     enum i40e_admin_queue_opc list_type_opc)
3234*4882a593Smuzhiyun {
3235*4882a593Smuzhiyun 	struct i40e_aqc_list_capabilities_element_resp *cap;
3236*4882a593Smuzhiyun 	u32 valid_functions, num_functions;
3237*4882a593Smuzhiyun 	u32 number, logical_id, phys_id;
3238*4882a593Smuzhiyun 	struct i40e_hw_capabilities *p;
3239*4882a593Smuzhiyun 	u16 id, ocp_cfg_word0;
3240*4882a593Smuzhiyun 	i40e_status status;
3241*4882a593Smuzhiyun 	u8 major_rev;
3242*4882a593Smuzhiyun 	u32 i = 0;
3243*4882a593Smuzhiyun 
3244*4882a593Smuzhiyun 	cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
3245*4882a593Smuzhiyun 
3246*4882a593Smuzhiyun 	if (list_type_opc == i40e_aqc_opc_list_dev_capabilities)
3247*4882a593Smuzhiyun 		p = &hw->dev_caps;
3248*4882a593Smuzhiyun 	else if (list_type_opc == i40e_aqc_opc_list_func_capabilities)
3249*4882a593Smuzhiyun 		p = &hw->func_caps;
3250*4882a593Smuzhiyun 	else
3251*4882a593Smuzhiyun 		return;
3252*4882a593Smuzhiyun 
3253*4882a593Smuzhiyun 	for (i = 0; i < cap_count; i++, cap++) {
3254*4882a593Smuzhiyun 		id = le16_to_cpu(cap->id);
3255*4882a593Smuzhiyun 		number = le32_to_cpu(cap->number);
3256*4882a593Smuzhiyun 		logical_id = le32_to_cpu(cap->logical_id);
3257*4882a593Smuzhiyun 		phys_id = le32_to_cpu(cap->phys_id);
3258*4882a593Smuzhiyun 		major_rev = cap->major_rev;
3259*4882a593Smuzhiyun 
3260*4882a593Smuzhiyun 		switch (id) {
3261*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_SWITCH_MODE:
3262*4882a593Smuzhiyun 			p->switch_mode = number;
3263*4882a593Smuzhiyun 			break;
3264*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_MNG_MODE:
3265*4882a593Smuzhiyun 			p->management_mode = number;
3266*4882a593Smuzhiyun 			if (major_rev > 1) {
3267*4882a593Smuzhiyun 				p->mng_protocols_over_mctp = logical_id;
3268*4882a593Smuzhiyun 				i40e_debug(hw, I40E_DEBUG_INIT,
3269*4882a593Smuzhiyun 					   "HW Capability: Protocols over MCTP = %d\n",
3270*4882a593Smuzhiyun 					   p->mng_protocols_over_mctp);
3271*4882a593Smuzhiyun 			} else {
3272*4882a593Smuzhiyun 				p->mng_protocols_over_mctp = 0;
3273*4882a593Smuzhiyun 			}
3274*4882a593Smuzhiyun 			break;
3275*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_NPAR_ACTIVE:
3276*4882a593Smuzhiyun 			p->npar_enable = number;
3277*4882a593Smuzhiyun 			break;
3278*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_OS2BMC_CAP:
3279*4882a593Smuzhiyun 			p->os2bmc = number;
3280*4882a593Smuzhiyun 			break;
3281*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_FUNCTIONS_VALID:
3282*4882a593Smuzhiyun 			p->valid_functions = number;
3283*4882a593Smuzhiyun 			break;
3284*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_SRIOV:
3285*4882a593Smuzhiyun 			if (number == 1)
3286*4882a593Smuzhiyun 				p->sr_iov_1_1 = true;
3287*4882a593Smuzhiyun 			break;
3288*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_VF:
3289*4882a593Smuzhiyun 			p->num_vfs = number;
3290*4882a593Smuzhiyun 			p->vf_base_id = logical_id;
3291*4882a593Smuzhiyun 			break;
3292*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_VMDQ:
3293*4882a593Smuzhiyun 			if (number == 1)
3294*4882a593Smuzhiyun 				p->vmdq = true;
3295*4882a593Smuzhiyun 			break;
3296*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_8021QBG:
3297*4882a593Smuzhiyun 			if (number == 1)
3298*4882a593Smuzhiyun 				p->evb_802_1_qbg = true;
3299*4882a593Smuzhiyun 			break;
3300*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_8021QBR:
3301*4882a593Smuzhiyun 			if (number == 1)
3302*4882a593Smuzhiyun 				p->evb_802_1_qbh = true;
3303*4882a593Smuzhiyun 			break;
3304*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_VSI:
3305*4882a593Smuzhiyun 			p->num_vsis = number;
3306*4882a593Smuzhiyun 			break;
3307*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_DCB:
3308*4882a593Smuzhiyun 			if (number == 1) {
3309*4882a593Smuzhiyun 				p->dcb = true;
3310*4882a593Smuzhiyun 				p->enabled_tcmap = logical_id;
3311*4882a593Smuzhiyun 				p->maxtc = phys_id;
3312*4882a593Smuzhiyun 			}
3313*4882a593Smuzhiyun 			break;
3314*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_FCOE:
3315*4882a593Smuzhiyun 			if (number == 1)
3316*4882a593Smuzhiyun 				p->fcoe = true;
3317*4882a593Smuzhiyun 			break;
3318*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_ISCSI:
3319*4882a593Smuzhiyun 			if (number == 1)
3320*4882a593Smuzhiyun 				p->iscsi = true;
3321*4882a593Smuzhiyun 			break;
3322*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_RSS:
3323*4882a593Smuzhiyun 			p->rss = true;
3324*4882a593Smuzhiyun 			p->rss_table_size = number;
3325*4882a593Smuzhiyun 			p->rss_table_entry_width = logical_id;
3326*4882a593Smuzhiyun 			break;
3327*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_RXQ:
3328*4882a593Smuzhiyun 			p->num_rx_qp = number;
3329*4882a593Smuzhiyun 			p->base_queue = phys_id;
3330*4882a593Smuzhiyun 			break;
3331*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_TXQ:
3332*4882a593Smuzhiyun 			p->num_tx_qp = number;
3333*4882a593Smuzhiyun 			p->base_queue = phys_id;
3334*4882a593Smuzhiyun 			break;
3335*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_MSIX:
3336*4882a593Smuzhiyun 			p->num_msix_vectors = number;
3337*4882a593Smuzhiyun 			i40e_debug(hw, I40E_DEBUG_INIT,
3338*4882a593Smuzhiyun 				   "HW Capability: MSIX vector count = %d\n",
3339*4882a593Smuzhiyun 				   p->num_msix_vectors);
3340*4882a593Smuzhiyun 			break;
3341*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_VF_MSIX:
3342*4882a593Smuzhiyun 			p->num_msix_vectors_vf = number;
3343*4882a593Smuzhiyun 			break;
3344*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_FLEX10:
3345*4882a593Smuzhiyun 			if (major_rev == 1) {
3346*4882a593Smuzhiyun 				if (number == 1) {
3347*4882a593Smuzhiyun 					p->flex10_enable = true;
3348*4882a593Smuzhiyun 					p->flex10_capable = true;
3349*4882a593Smuzhiyun 				}
3350*4882a593Smuzhiyun 			} else {
3351*4882a593Smuzhiyun 				/* Capability revision >= 2 */
3352*4882a593Smuzhiyun 				if (number & 1)
3353*4882a593Smuzhiyun 					p->flex10_enable = true;
3354*4882a593Smuzhiyun 				if (number & 2)
3355*4882a593Smuzhiyun 					p->flex10_capable = true;
3356*4882a593Smuzhiyun 			}
3357*4882a593Smuzhiyun 			p->flex10_mode = logical_id;
3358*4882a593Smuzhiyun 			p->flex10_status = phys_id;
3359*4882a593Smuzhiyun 			break;
3360*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_CEM:
3361*4882a593Smuzhiyun 			if (number == 1)
3362*4882a593Smuzhiyun 				p->mgmt_cem = true;
3363*4882a593Smuzhiyun 			break;
3364*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_IWARP:
3365*4882a593Smuzhiyun 			if (number == 1)
3366*4882a593Smuzhiyun 				p->iwarp = true;
3367*4882a593Smuzhiyun 			break;
3368*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_LED:
3369*4882a593Smuzhiyun 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
3370*4882a593Smuzhiyun 				p->led[phys_id] = true;
3371*4882a593Smuzhiyun 			break;
3372*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_SDP:
3373*4882a593Smuzhiyun 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
3374*4882a593Smuzhiyun 				p->sdp[phys_id] = true;
3375*4882a593Smuzhiyun 			break;
3376*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_MDIO:
3377*4882a593Smuzhiyun 			if (number == 1) {
3378*4882a593Smuzhiyun 				p->mdio_port_num = phys_id;
3379*4882a593Smuzhiyun 				p->mdio_port_mode = logical_id;
3380*4882a593Smuzhiyun 			}
3381*4882a593Smuzhiyun 			break;
3382*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_1588:
3383*4882a593Smuzhiyun 			if (number == 1)
3384*4882a593Smuzhiyun 				p->ieee_1588 = true;
3385*4882a593Smuzhiyun 			break;
3386*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_FLOW_DIRECTOR:
3387*4882a593Smuzhiyun 			p->fd = true;
3388*4882a593Smuzhiyun 			p->fd_filters_guaranteed = number;
3389*4882a593Smuzhiyun 			p->fd_filters_best_effort = logical_id;
3390*4882a593Smuzhiyun 			break;
3391*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_WSR_PROT:
3392*4882a593Smuzhiyun 			p->wr_csr_prot = (u64)number;
3393*4882a593Smuzhiyun 			p->wr_csr_prot |= (u64)logical_id << 32;
3394*4882a593Smuzhiyun 			break;
3395*4882a593Smuzhiyun 		case I40E_AQ_CAP_ID_NVM_MGMT:
3396*4882a593Smuzhiyun 			if (number & I40E_NVM_MGMT_SEC_REV_DISABLED)
3397*4882a593Smuzhiyun 				p->sec_rev_disabled = true;
3398*4882a593Smuzhiyun 			if (number & I40E_NVM_MGMT_UPDATE_DISABLED)
3399*4882a593Smuzhiyun 				p->update_disabled = true;
3400*4882a593Smuzhiyun 			break;
3401*4882a593Smuzhiyun 		default:
3402*4882a593Smuzhiyun 			break;
3403*4882a593Smuzhiyun 		}
3404*4882a593Smuzhiyun 	}
3405*4882a593Smuzhiyun 
3406*4882a593Smuzhiyun 	if (p->fcoe)
3407*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
3408*4882a593Smuzhiyun 
3409*4882a593Smuzhiyun 	/* Software override ensuring FCoE is disabled if npar or mfp
3410*4882a593Smuzhiyun 	 * mode because it is not supported in these modes.
3411*4882a593Smuzhiyun 	 */
3412*4882a593Smuzhiyun 	if (p->npar_enable || p->flex10_enable)
3413*4882a593Smuzhiyun 		p->fcoe = false;
3414*4882a593Smuzhiyun 
3415*4882a593Smuzhiyun 	/* count the enabled ports (aka the "not disabled" ports) */
3416*4882a593Smuzhiyun 	hw->num_ports = 0;
3417*4882a593Smuzhiyun 	for (i = 0; i < 4; i++) {
3418*4882a593Smuzhiyun 		u32 port_cfg_reg = I40E_PRTGEN_CNF + (4 * i);
3419*4882a593Smuzhiyun 		u64 port_cfg = 0;
3420*4882a593Smuzhiyun 
3421*4882a593Smuzhiyun 		/* use AQ read to get the physical register offset instead
3422*4882a593Smuzhiyun 		 * of the port relative offset
3423*4882a593Smuzhiyun 		 */
3424*4882a593Smuzhiyun 		i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
3425*4882a593Smuzhiyun 		if (!(port_cfg & I40E_PRTGEN_CNF_PORT_DIS_MASK))
3426*4882a593Smuzhiyun 			hw->num_ports++;
3427*4882a593Smuzhiyun 	}
3428*4882a593Smuzhiyun 
3429*4882a593Smuzhiyun 	/* OCP cards case: if a mezz is removed the Ethernet port is at
3430*4882a593Smuzhiyun 	 * disabled state in PRTGEN_CNF register. Additional NVM read is
3431*4882a593Smuzhiyun 	 * needed in order to check if we are dealing with OCP card.
3432*4882a593Smuzhiyun 	 * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
3433*4882a593Smuzhiyun 	 * physical ports results in wrong partition id calculation and thus
3434*4882a593Smuzhiyun 	 * not supporting WoL.
3435*4882a593Smuzhiyun 	 */
3436*4882a593Smuzhiyun 	if (hw->mac.type == I40E_MAC_X722) {
3437*4882a593Smuzhiyun 		if (!i40e_acquire_nvm(hw, I40E_RESOURCE_READ)) {
3438*4882a593Smuzhiyun 			status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
3439*4882a593Smuzhiyun 						  2 * I40E_SR_OCP_CFG_WORD0,
3440*4882a593Smuzhiyun 						  sizeof(ocp_cfg_word0),
3441*4882a593Smuzhiyun 						  &ocp_cfg_word0, true, NULL);
3442*4882a593Smuzhiyun 			if (!status &&
3443*4882a593Smuzhiyun 			    (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
3444*4882a593Smuzhiyun 				hw->num_ports = 4;
3445*4882a593Smuzhiyun 			i40e_release_nvm(hw);
3446*4882a593Smuzhiyun 		}
3447*4882a593Smuzhiyun 	}
3448*4882a593Smuzhiyun 
3449*4882a593Smuzhiyun 	valid_functions = p->valid_functions;
3450*4882a593Smuzhiyun 	num_functions = 0;
3451*4882a593Smuzhiyun 	while (valid_functions) {
3452*4882a593Smuzhiyun 		if (valid_functions & 1)
3453*4882a593Smuzhiyun 			num_functions++;
3454*4882a593Smuzhiyun 		valid_functions >>= 1;
3455*4882a593Smuzhiyun 	}
3456*4882a593Smuzhiyun 
3457*4882a593Smuzhiyun 	/* partition id is 1-based, and functions are evenly spread
3458*4882a593Smuzhiyun 	 * across the ports as partitions
3459*4882a593Smuzhiyun 	 */
3460*4882a593Smuzhiyun 	if (hw->num_ports != 0) {
3461*4882a593Smuzhiyun 		hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
3462*4882a593Smuzhiyun 		hw->num_partitions = num_functions / hw->num_ports;
3463*4882a593Smuzhiyun 	}
3464*4882a593Smuzhiyun 
3465*4882a593Smuzhiyun 	/* additional HW specific goodies that might
3466*4882a593Smuzhiyun 	 * someday be HW version specific
3467*4882a593Smuzhiyun 	 */
3468*4882a593Smuzhiyun 	p->rx_buf_chain_len = I40E_MAX_CHAINED_RX_BUFFERS;
3469*4882a593Smuzhiyun }
3470*4882a593Smuzhiyun 
3471*4882a593Smuzhiyun /**
3472*4882a593Smuzhiyun  * i40e_aq_discover_capabilities
3473*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3474*4882a593Smuzhiyun  * @buff: a virtual buffer to hold the capabilities
3475*4882a593Smuzhiyun  * @buff_size: Size of the virtual buffer
3476*4882a593Smuzhiyun  * @data_size: Size of the returned data, or buff size needed if AQ err==ENOMEM
3477*4882a593Smuzhiyun  * @list_type_opc: capabilities type to discover - pass in the command opcode
3478*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3479*4882a593Smuzhiyun  *
3480*4882a593Smuzhiyun  * Get the device capabilities descriptions from the firmware
3481*4882a593Smuzhiyun  **/
i40e_aq_discover_capabilities(struct i40e_hw * hw,void * buff,u16 buff_size,u16 * data_size,enum i40e_admin_queue_opc list_type_opc,struct i40e_asq_cmd_details * cmd_details)3482*4882a593Smuzhiyun i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
3483*4882a593Smuzhiyun 				void *buff, u16 buff_size, u16 *data_size,
3484*4882a593Smuzhiyun 				enum i40e_admin_queue_opc list_type_opc,
3485*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3486*4882a593Smuzhiyun {
3487*4882a593Smuzhiyun 	struct i40e_aqc_list_capabilites *cmd;
3488*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3489*4882a593Smuzhiyun 	i40e_status status = 0;
3490*4882a593Smuzhiyun 
3491*4882a593Smuzhiyun 	cmd = (struct i40e_aqc_list_capabilites *)&desc.params.raw;
3492*4882a593Smuzhiyun 
3493*4882a593Smuzhiyun 	if (list_type_opc != i40e_aqc_opc_list_func_capabilities &&
3494*4882a593Smuzhiyun 		list_type_opc != i40e_aqc_opc_list_dev_capabilities) {
3495*4882a593Smuzhiyun 		status = I40E_ERR_PARAM;
3496*4882a593Smuzhiyun 		goto exit;
3497*4882a593Smuzhiyun 	}
3498*4882a593Smuzhiyun 
3499*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, list_type_opc);
3500*4882a593Smuzhiyun 
3501*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3502*4882a593Smuzhiyun 	if (buff_size > I40E_AQ_LARGE_BUF)
3503*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3504*4882a593Smuzhiyun 
3505*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
3506*4882a593Smuzhiyun 	*data_size = le16_to_cpu(desc.datalen);
3507*4882a593Smuzhiyun 
3508*4882a593Smuzhiyun 	if (status)
3509*4882a593Smuzhiyun 		goto exit;
3510*4882a593Smuzhiyun 
3511*4882a593Smuzhiyun 	i40e_parse_discover_capabilities(hw, buff, le32_to_cpu(cmd->count),
3512*4882a593Smuzhiyun 					 list_type_opc);
3513*4882a593Smuzhiyun 
3514*4882a593Smuzhiyun exit:
3515*4882a593Smuzhiyun 	return status;
3516*4882a593Smuzhiyun }
3517*4882a593Smuzhiyun 
3518*4882a593Smuzhiyun /**
3519*4882a593Smuzhiyun  * i40e_aq_update_nvm
3520*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3521*4882a593Smuzhiyun  * @module_pointer: module pointer location in words from the NVM beginning
3522*4882a593Smuzhiyun  * @offset: byte offset from the module beginning
3523*4882a593Smuzhiyun  * @length: length of the section to be written (in bytes from the offset)
3524*4882a593Smuzhiyun  * @data: command buffer (size [bytes] = length)
3525*4882a593Smuzhiyun  * @last_command: tells if this is the last command in a series
3526*4882a593Smuzhiyun  * @preservation_flags: Preservation mode flags
3527*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3528*4882a593Smuzhiyun  *
3529*4882a593Smuzhiyun  * Update the NVM using the admin queue commands
3530*4882a593Smuzhiyun  **/
i40e_aq_update_nvm(struct i40e_hw * hw,u8 module_pointer,u32 offset,u16 length,void * data,bool last_command,u8 preservation_flags,struct i40e_asq_cmd_details * cmd_details)3531*4882a593Smuzhiyun i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
3532*4882a593Smuzhiyun 			       u32 offset, u16 length, void *data,
3533*4882a593Smuzhiyun 				bool last_command, u8 preservation_flags,
3534*4882a593Smuzhiyun 			       struct i40e_asq_cmd_details *cmd_details)
3535*4882a593Smuzhiyun {
3536*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3537*4882a593Smuzhiyun 	struct i40e_aqc_nvm_update *cmd =
3538*4882a593Smuzhiyun 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
3539*4882a593Smuzhiyun 	i40e_status status;
3540*4882a593Smuzhiyun 
3541*4882a593Smuzhiyun 	/* In offset the highest byte must be zeroed. */
3542*4882a593Smuzhiyun 	if (offset & 0xFF000000) {
3543*4882a593Smuzhiyun 		status = I40E_ERR_PARAM;
3544*4882a593Smuzhiyun 		goto i40e_aq_update_nvm_exit;
3545*4882a593Smuzhiyun 	}
3546*4882a593Smuzhiyun 
3547*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
3548*4882a593Smuzhiyun 
3549*4882a593Smuzhiyun 	/* If this is the last command in a series, set the proper flag. */
3550*4882a593Smuzhiyun 	if (last_command)
3551*4882a593Smuzhiyun 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3552*4882a593Smuzhiyun 	if (hw->mac.type == I40E_MAC_X722) {
3553*4882a593Smuzhiyun 		if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_SELECTED)
3554*4882a593Smuzhiyun 			cmd->command_flags |=
3555*4882a593Smuzhiyun 				(I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED <<
3556*4882a593Smuzhiyun 				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
3557*4882a593Smuzhiyun 		else if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_ALL)
3558*4882a593Smuzhiyun 			cmd->command_flags |=
3559*4882a593Smuzhiyun 				(I40E_AQ_NVM_PRESERVATION_FLAGS_ALL <<
3560*4882a593Smuzhiyun 				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
3561*4882a593Smuzhiyun 	}
3562*4882a593Smuzhiyun 	cmd->module_pointer = module_pointer;
3563*4882a593Smuzhiyun 	cmd->offset = cpu_to_le32(offset);
3564*4882a593Smuzhiyun 	cmd->length = cpu_to_le16(length);
3565*4882a593Smuzhiyun 
3566*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3567*4882a593Smuzhiyun 	if (length > I40E_AQ_LARGE_BUF)
3568*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3569*4882a593Smuzhiyun 
3570*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
3571*4882a593Smuzhiyun 
3572*4882a593Smuzhiyun i40e_aq_update_nvm_exit:
3573*4882a593Smuzhiyun 	return status;
3574*4882a593Smuzhiyun }
3575*4882a593Smuzhiyun 
3576*4882a593Smuzhiyun /**
3577*4882a593Smuzhiyun  * i40e_aq_rearrange_nvm
3578*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3579*4882a593Smuzhiyun  * @rearrange_nvm: defines direction of rearrangement
3580*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3581*4882a593Smuzhiyun  *
3582*4882a593Smuzhiyun  * Rearrange NVM structure, available only for transition FW
3583*4882a593Smuzhiyun  **/
i40e_aq_rearrange_nvm(struct i40e_hw * hw,u8 rearrange_nvm,struct i40e_asq_cmd_details * cmd_details)3584*4882a593Smuzhiyun i40e_status i40e_aq_rearrange_nvm(struct i40e_hw *hw,
3585*4882a593Smuzhiyun 				  u8 rearrange_nvm,
3586*4882a593Smuzhiyun 				  struct i40e_asq_cmd_details *cmd_details)
3587*4882a593Smuzhiyun {
3588*4882a593Smuzhiyun 	struct i40e_aqc_nvm_update *cmd;
3589*4882a593Smuzhiyun 	i40e_status status;
3590*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3591*4882a593Smuzhiyun 
3592*4882a593Smuzhiyun 	cmd = (struct i40e_aqc_nvm_update *)&desc.params.raw;
3593*4882a593Smuzhiyun 
3594*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
3595*4882a593Smuzhiyun 
3596*4882a593Smuzhiyun 	rearrange_nvm &= (I40E_AQ_NVM_REARRANGE_TO_FLAT |
3597*4882a593Smuzhiyun 			 I40E_AQ_NVM_REARRANGE_TO_STRUCT);
3598*4882a593Smuzhiyun 
3599*4882a593Smuzhiyun 	if (!rearrange_nvm) {
3600*4882a593Smuzhiyun 		status = I40E_ERR_PARAM;
3601*4882a593Smuzhiyun 		goto i40e_aq_rearrange_nvm_exit;
3602*4882a593Smuzhiyun 	}
3603*4882a593Smuzhiyun 
3604*4882a593Smuzhiyun 	cmd->command_flags |= rearrange_nvm;
3605*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3606*4882a593Smuzhiyun 
3607*4882a593Smuzhiyun i40e_aq_rearrange_nvm_exit:
3608*4882a593Smuzhiyun 	return status;
3609*4882a593Smuzhiyun }
3610*4882a593Smuzhiyun 
3611*4882a593Smuzhiyun /**
3612*4882a593Smuzhiyun  * i40e_aq_get_lldp_mib
3613*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3614*4882a593Smuzhiyun  * @bridge_type: type of bridge requested
3615*4882a593Smuzhiyun  * @mib_type: Local, Remote or both Local and Remote MIBs
3616*4882a593Smuzhiyun  * @buff: pointer to a user supplied buffer to store the MIB block
3617*4882a593Smuzhiyun  * @buff_size: size of the buffer (in bytes)
3618*4882a593Smuzhiyun  * @local_len : length of the returned Local LLDP MIB
3619*4882a593Smuzhiyun  * @remote_len: length of the returned Remote LLDP MIB
3620*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3621*4882a593Smuzhiyun  *
3622*4882a593Smuzhiyun  * Requests the complete LLDP MIB (entire packet).
3623*4882a593Smuzhiyun  **/
i40e_aq_get_lldp_mib(struct i40e_hw * hw,u8 bridge_type,u8 mib_type,void * buff,u16 buff_size,u16 * local_len,u16 * remote_len,struct i40e_asq_cmd_details * cmd_details)3624*4882a593Smuzhiyun i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
3625*4882a593Smuzhiyun 				u8 mib_type, void *buff, u16 buff_size,
3626*4882a593Smuzhiyun 				u16 *local_len, u16 *remote_len,
3627*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3628*4882a593Smuzhiyun {
3629*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3630*4882a593Smuzhiyun 	struct i40e_aqc_lldp_get_mib *cmd =
3631*4882a593Smuzhiyun 		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
3632*4882a593Smuzhiyun 	struct i40e_aqc_lldp_get_mib *resp =
3633*4882a593Smuzhiyun 		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
3634*4882a593Smuzhiyun 	i40e_status status;
3635*4882a593Smuzhiyun 
3636*4882a593Smuzhiyun 	if (buff_size == 0 || !buff)
3637*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
3638*4882a593Smuzhiyun 
3639*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_get_mib);
3640*4882a593Smuzhiyun 	/* Indirect Command */
3641*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3642*4882a593Smuzhiyun 
3643*4882a593Smuzhiyun 	cmd->type = mib_type & I40E_AQ_LLDP_MIB_TYPE_MASK;
3644*4882a593Smuzhiyun 	cmd->type |= ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
3645*4882a593Smuzhiyun 		       I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
3646*4882a593Smuzhiyun 
3647*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_size);
3648*4882a593Smuzhiyun 
3649*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3650*4882a593Smuzhiyun 	if (buff_size > I40E_AQ_LARGE_BUF)
3651*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3652*4882a593Smuzhiyun 
3653*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
3654*4882a593Smuzhiyun 	if (!status) {
3655*4882a593Smuzhiyun 		if (local_len != NULL)
3656*4882a593Smuzhiyun 			*local_len = le16_to_cpu(resp->local_len);
3657*4882a593Smuzhiyun 		if (remote_len != NULL)
3658*4882a593Smuzhiyun 			*remote_len = le16_to_cpu(resp->remote_len);
3659*4882a593Smuzhiyun 	}
3660*4882a593Smuzhiyun 
3661*4882a593Smuzhiyun 	return status;
3662*4882a593Smuzhiyun }
3663*4882a593Smuzhiyun 
3664*4882a593Smuzhiyun /**
3665*4882a593Smuzhiyun  * i40e_aq_cfg_lldp_mib_change_event
3666*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3667*4882a593Smuzhiyun  * @enable_update: Enable or Disable event posting
3668*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3669*4882a593Smuzhiyun  *
3670*4882a593Smuzhiyun  * Enable or Disable posting of an event on ARQ when LLDP MIB
3671*4882a593Smuzhiyun  * associated with the interface changes
3672*4882a593Smuzhiyun  **/
i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw * hw,bool enable_update,struct i40e_asq_cmd_details * cmd_details)3673*4882a593Smuzhiyun i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
3674*4882a593Smuzhiyun 				bool enable_update,
3675*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3676*4882a593Smuzhiyun {
3677*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3678*4882a593Smuzhiyun 	struct i40e_aqc_lldp_update_mib *cmd =
3679*4882a593Smuzhiyun 		(struct i40e_aqc_lldp_update_mib *)&desc.params.raw;
3680*4882a593Smuzhiyun 	i40e_status status;
3681*4882a593Smuzhiyun 
3682*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_mib);
3683*4882a593Smuzhiyun 
3684*4882a593Smuzhiyun 	if (!enable_update)
3685*4882a593Smuzhiyun 		cmd->command |= I40E_AQ_LLDP_MIB_UPDATE_DISABLE;
3686*4882a593Smuzhiyun 
3687*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3688*4882a593Smuzhiyun 
3689*4882a593Smuzhiyun 	return status;
3690*4882a593Smuzhiyun }
3691*4882a593Smuzhiyun 
3692*4882a593Smuzhiyun /**
3693*4882a593Smuzhiyun  * i40e_aq_restore_lldp
3694*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3695*4882a593Smuzhiyun  * @setting: pointer to factory setting variable or NULL
3696*4882a593Smuzhiyun  * @restore: True if factory settings should be restored
3697*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3698*4882a593Smuzhiyun  *
3699*4882a593Smuzhiyun  * Restore LLDP Agent factory settings if @restore set to True. In other case
3700*4882a593Smuzhiyun  * only returns factory setting in AQ response.
3701*4882a593Smuzhiyun  **/
3702*4882a593Smuzhiyun enum i40e_status_code
i40e_aq_restore_lldp(struct i40e_hw * hw,u8 * setting,bool restore,struct i40e_asq_cmd_details * cmd_details)3703*4882a593Smuzhiyun i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
3704*4882a593Smuzhiyun 		     struct i40e_asq_cmd_details *cmd_details)
3705*4882a593Smuzhiyun {
3706*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3707*4882a593Smuzhiyun 	struct i40e_aqc_lldp_restore *cmd =
3708*4882a593Smuzhiyun 		(struct i40e_aqc_lldp_restore *)&desc.params.raw;
3709*4882a593Smuzhiyun 	i40e_status status;
3710*4882a593Smuzhiyun 
3711*4882a593Smuzhiyun 	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) {
3712*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_ALL,
3713*4882a593Smuzhiyun 			   "Restore LLDP not supported by current FW version.\n");
3714*4882a593Smuzhiyun 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
3715*4882a593Smuzhiyun 	}
3716*4882a593Smuzhiyun 
3717*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore);
3718*4882a593Smuzhiyun 
3719*4882a593Smuzhiyun 	if (restore)
3720*4882a593Smuzhiyun 		cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE;
3721*4882a593Smuzhiyun 
3722*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3723*4882a593Smuzhiyun 
3724*4882a593Smuzhiyun 	if (setting)
3725*4882a593Smuzhiyun 		*setting = cmd->command & 1;
3726*4882a593Smuzhiyun 
3727*4882a593Smuzhiyun 	return status;
3728*4882a593Smuzhiyun }
3729*4882a593Smuzhiyun 
3730*4882a593Smuzhiyun /**
3731*4882a593Smuzhiyun  * i40e_aq_stop_lldp
3732*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3733*4882a593Smuzhiyun  * @shutdown_agent: True if LLDP Agent needs to be Shutdown
3734*4882a593Smuzhiyun  * @persist: True if stop of LLDP should be persistent across power cycles
3735*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3736*4882a593Smuzhiyun  *
3737*4882a593Smuzhiyun  * Stop or Shutdown the embedded LLDP Agent
3738*4882a593Smuzhiyun  **/
i40e_aq_stop_lldp(struct i40e_hw * hw,bool shutdown_agent,bool persist,struct i40e_asq_cmd_details * cmd_details)3739*4882a593Smuzhiyun i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
3740*4882a593Smuzhiyun 				bool persist,
3741*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3742*4882a593Smuzhiyun {
3743*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3744*4882a593Smuzhiyun 	struct i40e_aqc_lldp_stop *cmd =
3745*4882a593Smuzhiyun 		(struct i40e_aqc_lldp_stop *)&desc.params.raw;
3746*4882a593Smuzhiyun 	i40e_status status;
3747*4882a593Smuzhiyun 
3748*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
3749*4882a593Smuzhiyun 
3750*4882a593Smuzhiyun 	if (shutdown_agent)
3751*4882a593Smuzhiyun 		cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
3752*4882a593Smuzhiyun 
3753*4882a593Smuzhiyun 	if (persist) {
3754*4882a593Smuzhiyun 		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
3755*4882a593Smuzhiyun 			cmd->command |= I40E_AQ_LLDP_AGENT_STOP_PERSIST;
3756*4882a593Smuzhiyun 		else
3757*4882a593Smuzhiyun 			i40e_debug(hw, I40E_DEBUG_ALL,
3758*4882a593Smuzhiyun 				   "Persistent Stop LLDP not supported by current FW version.\n");
3759*4882a593Smuzhiyun 	}
3760*4882a593Smuzhiyun 
3761*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3762*4882a593Smuzhiyun 
3763*4882a593Smuzhiyun 	return status;
3764*4882a593Smuzhiyun }
3765*4882a593Smuzhiyun 
3766*4882a593Smuzhiyun /**
3767*4882a593Smuzhiyun  * i40e_aq_start_lldp
3768*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3769*4882a593Smuzhiyun  * @persist: True if start of LLDP should be persistent across power cycles
3770*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3771*4882a593Smuzhiyun  *
3772*4882a593Smuzhiyun  * Start the embedded LLDP Agent on all ports.
3773*4882a593Smuzhiyun  **/
i40e_aq_start_lldp(struct i40e_hw * hw,bool persist,struct i40e_asq_cmd_details * cmd_details)3774*4882a593Smuzhiyun i40e_status i40e_aq_start_lldp(struct i40e_hw *hw, bool persist,
3775*4882a593Smuzhiyun 			       struct i40e_asq_cmd_details *cmd_details)
3776*4882a593Smuzhiyun {
3777*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3778*4882a593Smuzhiyun 	struct i40e_aqc_lldp_start *cmd =
3779*4882a593Smuzhiyun 		(struct i40e_aqc_lldp_start *)&desc.params.raw;
3780*4882a593Smuzhiyun 	i40e_status status;
3781*4882a593Smuzhiyun 
3782*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
3783*4882a593Smuzhiyun 
3784*4882a593Smuzhiyun 	cmd->command = I40E_AQ_LLDP_AGENT_START;
3785*4882a593Smuzhiyun 
3786*4882a593Smuzhiyun 	if (persist) {
3787*4882a593Smuzhiyun 		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
3788*4882a593Smuzhiyun 			cmd->command |= I40E_AQ_LLDP_AGENT_START_PERSIST;
3789*4882a593Smuzhiyun 		else
3790*4882a593Smuzhiyun 			i40e_debug(hw, I40E_DEBUG_ALL,
3791*4882a593Smuzhiyun 				   "Persistent Start LLDP not supported by current FW version.\n");
3792*4882a593Smuzhiyun 	}
3793*4882a593Smuzhiyun 
3794*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3795*4882a593Smuzhiyun 
3796*4882a593Smuzhiyun 	return status;
3797*4882a593Smuzhiyun }
3798*4882a593Smuzhiyun 
3799*4882a593Smuzhiyun /**
3800*4882a593Smuzhiyun  * i40e_aq_set_dcb_parameters
3801*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3802*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3803*4882a593Smuzhiyun  * @dcb_enable: True if DCB configuration needs to be applied
3804*4882a593Smuzhiyun  *
3805*4882a593Smuzhiyun  **/
3806*4882a593Smuzhiyun enum i40e_status_code
i40e_aq_set_dcb_parameters(struct i40e_hw * hw,bool dcb_enable,struct i40e_asq_cmd_details * cmd_details)3807*4882a593Smuzhiyun i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
3808*4882a593Smuzhiyun 			   struct i40e_asq_cmd_details *cmd_details)
3809*4882a593Smuzhiyun {
3810*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3811*4882a593Smuzhiyun 	struct i40e_aqc_set_dcb_parameters *cmd =
3812*4882a593Smuzhiyun 		(struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
3813*4882a593Smuzhiyun 	i40e_status status;
3814*4882a593Smuzhiyun 
3815*4882a593Smuzhiyun 	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE))
3816*4882a593Smuzhiyun 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
3817*4882a593Smuzhiyun 
3818*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
3819*4882a593Smuzhiyun 					  i40e_aqc_opc_set_dcb_parameters);
3820*4882a593Smuzhiyun 
3821*4882a593Smuzhiyun 	if (dcb_enable) {
3822*4882a593Smuzhiyun 		cmd->valid_flags = I40E_DCB_VALID;
3823*4882a593Smuzhiyun 		cmd->command = I40E_AQ_DCB_SET_AGENT;
3824*4882a593Smuzhiyun 	}
3825*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3826*4882a593Smuzhiyun 
3827*4882a593Smuzhiyun 	return status;
3828*4882a593Smuzhiyun }
3829*4882a593Smuzhiyun 
3830*4882a593Smuzhiyun /**
3831*4882a593Smuzhiyun  * i40e_aq_get_cee_dcb_config
3832*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3833*4882a593Smuzhiyun  * @buff: response buffer that stores CEE operational configuration
3834*4882a593Smuzhiyun  * @buff_size: size of the buffer passed
3835*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3836*4882a593Smuzhiyun  *
3837*4882a593Smuzhiyun  * Get CEE DCBX mode operational configuration from firmware
3838*4882a593Smuzhiyun  **/
i40e_aq_get_cee_dcb_config(struct i40e_hw * hw,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)3839*4882a593Smuzhiyun i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
3840*4882a593Smuzhiyun 				       void *buff, u16 buff_size,
3841*4882a593Smuzhiyun 				       struct i40e_asq_cmd_details *cmd_details)
3842*4882a593Smuzhiyun {
3843*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3844*4882a593Smuzhiyun 	i40e_status status;
3845*4882a593Smuzhiyun 
3846*4882a593Smuzhiyun 	if (buff_size == 0 || !buff)
3847*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
3848*4882a593Smuzhiyun 
3849*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_cee_dcb_cfg);
3850*4882a593Smuzhiyun 
3851*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3852*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, (void *)buff, buff_size,
3853*4882a593Smuzhiyun 				       cmd_details);
3854*4882a593Smuzhiyun 
3855*4882a593Smuzhiyun 	return status;
3856*4882a593Smuzhiyun }
3857*4882a593Smuzhiyun 
3858*4882a593Smuzhiyun /**
3859*4882a593Smuzhiyun  * i40e_aq_add_udp_tunnel
3860*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3861*4882a593Smuzhiyun  * @udp_port: the UDP port to add in Host byte order
3862*4882a593Smuzhiyun  * @protocol_index: protocol index type
3863*4882a593Smuzhiyun  * @filter_index: pointer to filter index
3864*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3865*4882a593Smuzhiyun  *
3866*4882a593Smuzhiyun  * Note: Firmware expects the udp_port value to be in Little Endian format,
3867*4882a593Smuzhiyun  * and this function will call cpu_to_le16 to convert from Host byte order to
3868*4882a593Smuzhiyun  * Little Endian order.
3869*4882a593Smuzhiyun  **/
i40e_aq_add_udp_tunnel(struct i40e_hw * hw,u16 udp_port,u8 protocol_index,u8 * filter_index,struct i40e_asq_cmd_details * cmd_details)3870*4882a593Smuzhiyun i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
3871*4882a593Smuzhiyun 				u16 udp_port, u8 protocol_index,
3872*4882a593Smuzhiyun 				u8 *filter_index,
3873*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3874*4882a593Smuzhiyun {
3875*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3876*4882a593Smuzhiyun 	struct i40e_aqc_add_udp_tunnel *cmd =
3877*4882a593Smuzhiyun 		(struct i40e_aqc_add_udp_tunnel *)&desc.params.raw;
3878*4882a593Smuzhiyun 	struct i40e_aqc_del_udp_tunnel_completion *resp =
3879*4882a593Smuzhiyun 		(struct i40e_aqc_del_udp_tunnel_completion *)&desc.params.raw;
3880*4882a593Smuzhiyun 	i40e_status status;
3881*4882a593Smuzhiyun 
3882*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_udp_tunnel);
3883*4882a593Smuzhiyun 
3884*4882a593Smuzhiyun 	cmd->udp_port = cpu_to_le16(udp_port);
3885*4882a593Smuzhiyun 	cmd->protocol_type = protocol_index;
3886*4882a593Smuzhiyun 
3887*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3888*4882a593Smuzhiyun 
3889*4882a593Smuzhiyun 	if (!status && filter_index)
3890*4882a593Smuzhiyun 		*filter_index = resp->index;
3891*4882a593Smuzhiyun 
3892*4882a593Smuzhiyun 	return status;
3893*4882a593Smuzhiyun }
3894*4882a593Smuzhiyun 
3895*4882a593Smuzhiyun /**
3896*4882a593Smuzhiyun  * i40e_aq_del_udp_tunnel
3897*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3898*4882a593Smuzhiyun  * @index: filter index
3899*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3900*4882a593Smuzhiyun  **/
i40e_aq_del_udp_tunnel(struct i40e_hw * hw,u8 index,struct i40e_asq_cmd_details * cmd_details)3901*4882a593Smuzhiyun i40e_status i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
3902*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3903*4882a593Smuzhiyun {
3904*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3905*4882a593Smuzhiyun 	struct i40e_aqc_remove_udp_tunnel *cmd =
3906*4882a593Smuzhiyun 		(struct i40e_aqc_remove_udp_tunnel *)&desc.params.raw;
3907*4882a593Smuzhiyun 	i40e_status status;
3908*4882a593Smuzhiyun 
3909*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_del_udp_tunnel);
3910*4882a593Smuzhiyun 
3911*4882a593Smuzhiyun 	cmd->index = index;
3912*4882a593Smuzhiyun 
3913*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3914*4882a593Smuzhiyun 
3915*4882a593Smuzhiyun 	return status;
3916*4882a593Smuzhiyun }
3917*4882a593Smuzhiyun 
3918*4882a593Smuzhiyun /**
3919*4882a593Smuzhiyun  * i40e_aq_delete_element - Delete switch element
3920*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3921*4882a593Smuzhiyun  * @seid: the SEID to delete from the switch
3922*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3923*4882a593Smuzhiyun  *
3924*4882a593Smuzhiyun  * This deletes a switch element from the switch.
3925*4882a593Smuzhiyun  **/
i40e_aq_delete_element(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)3926*4882a593Smuzhiyun i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
3927*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3928*4882a593Smuzhiyun {
3929*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3930*4882a593Smuzhiyun 	struct i40e_aqc_switch_seid *cmd =
3931*4882a593Smuzhiyun 		(struct i40e_aqc_switch_seid *)&desc.params.raw;
3932*4882a593Smuzhiyun 	i40e_status status;
3933*4882a593Smuzhiyun 
3934*4882a593Smuzhiyun 	if (seid == 0)
3935*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
3936*4882a593Smuzhiyun 
3937*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_delete_element);
3938*4882a593Smuzhiyun 
3939*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
3940*4882a593Smuzhiyun 
3941*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3942*4882a593Smuzhiyun 
3943*4882a593Smuzhiyun 	return status;
3944*4882a593Smuzhiyun }
3945*4882a593Smuzhiyun 
3946*4882a593Smuzhiyun /**
3947*4882a593Smuzhiyun  * i40e_aq_dcb_updated - DCB Updated Command
3948*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3949*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3950*4882a593Smuzhiyun  *
3951*4882a593Smuzhiyun  * EMP will return when the shared RPB settings have been
3952*4882a593Smuzhiyun  * recomputed and modified. The retval field in the descriptor
3953*4882a593Smuzhiyun  * will be set to 0 when RPB is modified.
3954*4882a593Smuzhiyun  **/
i40e_aq_dcb_updated(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)3955*4882a593Smuzhiyun i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
3956*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3957*4882a593Smuzhiyun {
3958*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3959*4882a593Smuzhiyun 	i40e_status status;
3960*4882a593Smuzhiyun 
3961*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_updated);
3962*4882a593Smuzhiyun 
3963*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3964*4882a593Smuzhiyun 
3965*4882a593Smuzhiyun 	return status;
3966*4882a593Smuzhiyun }
3967*4882a593Smuzhiyun 
3968*4882a593Smuzhiyun /**
3969*4882a593Smuzhiyun  * i40e_aq_tx_sched_cmd - generic Tx scheduler AQ command handler
3970*4882a593Smuzhiyun  * @hw: pointer to the hw struct
3971*4882a593Smuzhiyun  * @seid: seid for the physical port/switching component/vsi
3972*4882a593Smuzhiyun  * @buff: Indirect buffer to hold data parameters and response
3973*4882a593Smuzhiyun  * @buff_size: Indirect buffer size
3974*4882a593Smuzhiyun  * @opcode: Tx scheduler AQ command opcode
3975*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
3976*4882a593Smuzhiyun  *
3977*4882a593Smuzhiyun  * Generic command handler for Tx scheduler AQ commands
3978*4882a593Smuzhiyun  **/
i40e_aq_tx_sched_cmd(struct i40e_hw * hw,u16 seid,void * buff,u16 buff_size,enum i40e_admin_queue_opc opcode,struct i40e_asq_cmd_details * cmd_details)3979*4882a593Smuzhiyun static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
3980*4882a593Smuzhiyun 				void *buff, u16 buff_size,
3981*4882a593Smuzhiyun 				 enum i40e_admin_queue_opc opcode,
3982*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
3983*4882a593Smuzhiyun {
3984*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
3985*4882a593Smuzhiyun 	struct i40e_aqc_tx_sched_ind *cmd =
3986*4882a593Smuzhiyun 		(struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
3987*4882a593Smuzhiyun 	i40e_status status;
3988*4882a593Smuzhiyun 	bool cmd_param_flag = false;
3989*4882a593Smuzhiyun 
3990*4882a593Smuzhiyun 	switch (opcode) {
3991*4882a593Smuzhiyun 	case i40e_aqc_opc_configure_vsi_ets_sla_bw_limit:
3992*4882a593Smuzhiyun 	case i40e_aqc_opc_configure_vsi_tc_bw:
3993*4882a593Smuzhiyun 	case i40e_aqc_opc_enable_switching_comp_ets:
3994*4882a593Smuzhiyun 	case i40e_aqc_opc_modify_switching_comp_ets:
3995*4882a593Smuzhiyun 	case i40e_aqc_opc_disable_switching_comp_ets:
3996*4882a593Smuzhiyun 	case i40e_aqc_opc_configure_switching_comp_ets_bw_limit:
3997*4882a593Smuzhiyun 	case i40e_aqc_opc_configure_switching_comp_bw_config:
3998*4882a593Smuzhiyun 		cmd_param_flag = true;
3999*4882a593Smuzhiyun 		break;
4000*4882a593Smuzhiyun 	case i40e_aqc_opc_query_vsi_bw_config:
4001*4882a593Smuzhiyun 	case i40e_aqc_opc_query_vsi_ets_sla_config:
4002*4882a593Smuzhiyun 	case i40e_aqc_opc_query_switching_comp_ets_config:
4003*4882a593Smuzhiyun 	case i40e_aqc_opc_query_port_ets_config:
4004*4882a593Smuzhiyun 	case i40e_aqc_opc_query_switching_comp_bw_config:
4005*4882a593Smuzhiyun 		cmd_param_flag = false;
4006*4882a593Smuzhiyun 		break;
4007*4882a593Smuzhiyun 	default:
4008*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4009*4882a593Smuzhiyun 	}
4010*4882a593Smuzhiyun 
4011*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, opcode);
4012*4882a593Smuzhiyun 
4013*4882a593Smuzhiyun 	/* Indirect command */
4014*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
4015*4882a593Smuzhiyun 	if (cmd_param_flag)
4016*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
4017*4882a593Smuzhiyun 	if (buff_size > I40E_AQ_LARGE_BUF)
4018*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
4019*4882a593Smuzhiyun 
4020*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_size);
4021*4882a593Smuzhiyun 
4022*4882a593Smuzhiyun 	cmd->vsi_seid = cpu_to_le16(seid);
4023*4882a593Smuzhiyun 
4024*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4025*4882a593Smuzhiyun 
4026*4882a593Smuzhiyun 	return status;
4027*4882a593Smuzhiyun }
4028*4882a593Smuzhiyun 
4029*4882a593Smuzhiyun /**
4030*4882a593Smuzhiyun  * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
4031*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4032*4882a593Smuzhiyun  * @seid: VSI seid
4033*4882a593Smuzhiyun  * @credit: BW limit credits (0 = disabled)
4034*4882a593Smuzhiyun  * @max_credit: Max BW limit credits
4035*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4036*4882a593Smuzhiyun  **/
i40e_aq_config_vsi_bw_limit(struct i40e_hw * hw,u16 seid,u16 credit,u8 max_credit,struct i40e_asq_cmd_details * cmd_details)4037*4882a593Smuzhiyun i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
4038*4882a593Smuzhiyun 				u16 seid, u16 credit, u8 max_credit,
4039*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
4040*4882a593Smuzhiyun {
4041*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
4042*4882a593Smuzhiyun 	struct i40e_aqc_configure_vsi_bw_limit *cmd =
4043*4882a593Smuzhiyun 		(struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
4044*4882a593Smuzhiyun 	i40e_status status;
4045*4882a593Smuzhiyun 
4046*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
4047*4882a593Smuzhiyun 					  i40e_aqc_opc_configure_vsi_bw_limit);
4048*4882a593Smuzhiyun 
4049*4882a593Smuzhiyun 	cmd->vsi_seid = cpu_to_le16(seid);
4050*4882a593Smuzhiyun 	cmd->credit = cpu_to_le16(credit);
4051*4882a593Smuzhiyun 	cmd->max_credit = max_credit;
4052*4882a593Smuzhiyun 
4053*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4054*4882a593Smuzhiyun 
4055*4882a593Smuzhiyun 	return status;
4056*4882a593Smuzhiyun }
4057*4882a593Smuzhiyun 
4058*4882a593Smuzhiyun /**
4059*4882a593Smuzhiyun  * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
4060*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4061*4882a593Smuzhiyun  * @seid: VSI seid
4062*4882a593Smuzhiyun  * @bw_data: Buffer holding enabled TCs, relative TC BW limit/credits
4063*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4064*4882a593Smuzhiyun  **/
i40e_aq_config_vsi_tc_bw(struct i40e_hw * hw,u16 seid,struct i40e_aqc_configure_vsi_tc_bw_data * bw_data,struct i40e_asq_cmd_details * cmd_details)4065*4882a593Smuzhiyun i40e_status i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
4066*4882a593Smuzhiyun 			u16 seid,
4067*4882a593Smuzhiyun 			struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
4068*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details)
4069*4882a593Smuzhiyun {
4070*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
4071*4882a593Smuzhiyun 				    i40e_aqc_opc_configure_vsi_tc_bw,
4072*4882a593Smuzhiyun 				    cmd_details);
4073*4882a593Smuzhiyun }
4074*4882a593Smuzhiyun 
4075*4882a593Smuzhiyun /**
4076*4882a593Smuzhiyun  * i40e_aq_config_switch_comp_ets - Enable/Disable/Modify ETS on the port
4077*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4078*4882a593Smuzhiyun  * @seid: seid of the switching component connected to Physical Port
4079*4882a593Smuzhiyun  * @ets_data: Buffer holding ETS parameters
4080*4882a593Smuzhiyun  * @opcode: Tx scheduler AQ command opcode
4081*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4082*4882a593Smuzhiyun  **/
i40e_aq_config_switch_comp_ets(struct i40e_hw * hw,u16 seid,struct i40e_aqc_configure_switching_comp_ets_data * ets_data,enum i40e_admin_queue_opc opcode,struct i40e_asq_cmd_details * cmd_details)4083*4882a593Smuzhiyun i40e_status i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
4084*4882a593Smuzhiyun 		u16 seid,
4085*4882a593Smuzhiyun 		struct i40e_aqc_configure_switching_comp_ets_data *ets_data,
4086*4882a593Smuzhiyun 		enum i40e_admin_queue_opc opcode,
4087*4882a593Smuzhiyun 		struct i40e_asq_cmd_details *cmd_details)
4088*4882a593Smuzhiyun {
4089*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)ets_data,
4090*4882a593Smuzhiyun 				    sizeof(*ets_data), opcode, cmd_details);
4091*4882a593Smuzhiyun }
4092*4882a593Smuzhiyun 
4093*4882a593Smuzhiyun /**
4094*4882a593Smuzhiyun  * i40e_aq_config_switch_comp_bw_config - Config Switch comp BW Alloc per TC
4095*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4096*4882a593Smuzhiyun  * @seid: seid of the switching component
4097*4882a593Smuzhiyun  * @bw_data: Buffer holding enabled TCs, relative/absolute TC BW limit/credits
4098*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4099*4882a593Smuzhiyun  **/
i40e_aq_config_switch_comp_bw_config(struct i40e_hw * hw,u16 seid,struct i40e_aqc_configure_switching_comp_bw_config_data * bw_data,struct i40e_asq_cmd_details * cmd_details)4100*4882a593Smuzhiyun i40e_status i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
4101*4882a593Smuzhiyun 	u16 seid,
4102*4882a593Smuzhiyun 	struct i40e_aqc_configure_switching_comp_bw_config_data *bw_data,
4103*4882a593Smuzhiyun 	struct i40e_asq_cmd_details *cmd_details)
4104*4882a593Smuzhiyun {
4105*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
4106*4882a593Smuzhiyun 			    i40e_aqc_opc_configure_switching_comp_bw_config,
4107*4882a593Smuzhiyun 			    cmd_details);
4108*4882a593Smuzhiyun }
4109*4882a593Smuzhiyun 
4110*4882a593Smuzhiyun /**
4111*4882a593Smuzhiyun  * i40e_aq_query_vsi_bw_config - Query VSI BW configuration
4112*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4113*4882a593Smuzhiyun  * @seid: seid of the VSI
4114*4882a593Smuzhiyun  * @bw_data: Buffer to hold VSI BW configuration
4115*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4116*4882a593Smuzhiyun  **/
i40e_aq_query_vsi_bw_config(struct i40e_hw * hw,u16 seid,struct i40e_aqc_query_vsi_bw_config_resp * bw_data,struct i40e_asq_cmd_details * cmd_details)4117*4882a593Smuzhiyun i40e_status i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
4118*4882a593Smuzhiyun 			u16 seid,
4119*4882a593Smuzhiyun 			struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
4120*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details)
4121*4882a593Smuzhiyun {
4122*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
4123*4882a593Smuzhiyun 				    i40e_aqc_opc_query_vsi_bw_config,
4124*4882a593Smuzhiyun 				    cmd_details);
4125*4882a593Smuzhiyun }
4126*4882a593Smuzhiyun 
4127*4882a593Smuzhiyun /**
4128*4882a593Smuzhiyun  * i40e_aq_query_vsi_ets_sla_config - Query VSI BW configuration per TC
4129*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4130*4882a593Smuzhiyun  * @seid: seid of the VSI
4131*4882a593Smuzhiyun  * @bw_data: Buffer to hold VSI BW configuration per TC
4132*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4133*4882a593Smuzhiyun  **/
i40e_aq_query_vsi_ets_sla_config(struct i40e_hw * hw,u16 seid,struct i40e_aqc_query_vsi_ets_sla_config_resp * bw_data,struct i40e_asq_cmd_details * cmd_details)4134*4882a593Smuzhiyun i40e_status i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
4135*4882a593Smuzhiyun 			u16 seid,
4136*4882a593Smuzhiyun 			struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
4137*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details)
4138*4882a593Smuzhiyun {
4139*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
4140*4882a593Smuzhiyun 				    i40e_aqc_opc_query_vsi_ets_sla_config,
4141*4882a593Smuzhiyun 				    cmd_details);
4142*4882a593Smuzhiyun }
4143*4882a593Smuzhiyun 
4144*4882a593Smuzhiyun /**
4145*4882a593Smuzhiyun  * i40e_aq_query_switch_comp_ets_config - Query Switch comp BW config per TC
4146*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4147*4882a593Smuzhiyun  * @seid: seid of the switching component
4148*4882a593Smuzhiyun  * @bw_data: Buffer to hold switching component's per TC BW config
4149*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4150*4882a593Smuzhiyun  **/
i40e_aq_query_switch_comp_ets_config(struct i40e_hw * hw,u16 seid,struct i40e_aqc_query_switching_comp_ets_config_resp * bw_data,struct i40e_asq_cmd_details * cmd_details)4151*4882a593Smuzhiyun i40e_status i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
4152*4882a593Smuzhiyun 		u16 seid,
4153*4882a593Smuzhiyun 		struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
4154*4882a593Smuzhiyun 		struct i40e_asq_cmd_details *cmd_details)
4155*4882a593Smuzhiyun {
4156*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
4157*4882a593Smuzhiyun 				   i40e_aqc_opc_query_switching_comp_ets_config,
4158*4882a593Smuzhiyun 				   cmd_details);
4159*4882a593Smuzhiyun }
4160*4882a593Smuzhiyun 
4161*4882a593Smuzhiyun /**
4162*4882a593Smuzhiyun  * i40e_aq_query_port_ets_config - Query Physical Port ETS configuration
4163*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4164*4882a593Smuzhiyun  * @seid: seid of the VSI or switching component connected to Physical Port
4165*4882a593Smuzhiyun  * @bw_data: Buffer to hold current ETS configuration for the Physical Port
4166*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4167*4882a593Smuzhiyun  **/
i40e_aq_query_port_ets_config(struct i40e_hw * hw,u16 seid,struct i40e_aqc_query_port_ets_config_resp * bw_data,struct i40e_asq_cmd_details * cmd_details)4168*4882a593Smuzhiyun i40e_status i40e_aq_query_port_ets_config(struct i40e_hw *hw,
4169*4882a593Smuzhiyun 			u16 seid,
4170*4882a593Smuzhiyun 			struct i40e_aqc_query_port_ets_config_resp *bw_data,
4171*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details)
4172*4882a593Smuzhiyun {
4173*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
4174*4882a593Smuzhiyun 				    i40e_aqc_opc_query_port_ets_config,
4175*4882a593Smuzhiyun 				    cmd_details);
4176*4882a593Smuzhiyun }
4177*4882a593Smuzhiyun 
4178*4882a593Smuzhiyun /**
4179*4882a593Smuzhiyun  * i40e_aq_query_switch_comp_bw_config - Query Switch comp BW configuration
4180*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4181*4882a593Smuzhiyun  * @seid: seid of the switching component
4182*4882a593Smuzhiyun  * @bw_data: Buffer to hold switching component's BW configuration
4183*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4184*4882a593Smuzhiyun  **/
i40e_aq_query_switch_comp_bw_config(struct i40e_hw * hw,u16 seid,struct i40e_aqc_query_switching_comp_bw_config_resp * bw_data,struct i40e_asq_cmd_details * cmd_details)4185*4882a593Smuzhiyun i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
4186*4882a593Smuzhiyun 		u16 seid,
4187*4882a593Smuzhiyun 		struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
4188*4882a593Smuzhiyun 		struct i40e_asq_cmd_details *cmd_details)
4189*4882a593Smuzhiyun {
4190*4882a593Smuzhiyun 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
4191*4882a593Smuzhiyun 				    i40e_aqc_opc_query_switching_comp_bw_config,
4192*4882a593Smuzhiyun 				    cmd_details);
4193*4882a593Smuzhiyun }
4194*4882a593Smuzhiyun 
4195*4882a593Smuzhiyun /**
4196*4882a593Smuzhiyun  * i40e_validate_filter_settings
4197*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
4198*4882a593Smuzhiyun  * @settings: Filter control settings
4199*4882a593Smuzhiyun  *
4200*4882a593Smuzhiyun  * Check and validate the filter control settings passed.
4201*4882a593Smuzhiyun  * The function checks for the valid filter/context sizes being
4202*4882a593Smuzhiyun  * passed for FCoE and PE.
4203*4882a593Smuzhiyun  *
4204*4882a593Smuzhiyun  * Returns 0 if the values passed are valid and within
4205*4882a593Smuzhiyun  * range else returns an error.
4206*4882a593Smuzhiyun  **/
i40e_validate_filter_settings(struct i40e_hw * hw,struct i40e_filter_control_settings * settings)4207*4882a593Smuzhiyun static i40e_status i40e_validate_filter_settings(struct i40e_hw *hw,
4208*4882a593Smuzhiyun 				struct i40e_filter_control_settings *settings)
4209*4882a593Smuzhiyun {
4210*4882a593Smuzhiyun 	u32 fcoe_cntx_size, fcoe_filt_size;
4211*4882a593Smuzhiyun 	u32 pe_cntx_size, pe_filt_size;
4212*4882a593Smuzhiyun 	u32 fcoe_fmax;
4213*4882a593Smuzhiyun 	u32 val;
4214*4882a593Smuzhiyun 
4215*4882a593Smuzhiyun 	/* Validate FCoE settings passed */
4216*4882a593Smuzhiyun 	switch (settings->fcoe_filt_num) {
4217*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_1K:
4218*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_2K:
4219*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_4K:
4220*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_8K:
4221*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_16K:
4222*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_32K:
4223*4882a593Smuzhiyun 		fcoe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
4224*4882a593Smuzhiyun 		fcoe_filt_size <<= (u32)settings->fcoe_filt_num;
4225*4882a593Smuzhiyun 		break;
4226*4882a593Smuzhiyun 	default:
4227*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4228*4882a593Smuzhiyun 	}
4229*4882a593Smuzhiyun 
4230*4882a593Smuzhiyun 	switch (settings->fcoe_cntx_num) {
4231*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_512:
4232*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_1K:
4233*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_2K:
4234*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_4K:
4235*4882a593Smuzhiyun 		fcoe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
4236*4882a593Smuzhiyun 		fcoe_cntx_size <<= (u32)settings->fcoe_cntx_num;
4237*4882a593Smuzhiyun 		break;
4238*4882a593Smuzhiyun 	default:
4239*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4240*4882a593Smuzhiyun 	}
4241*4882a593Smuzhiyun 
4242*4882a593Smuzhiyun 	/* Validate PE settings passed */
4243*4882a593Smuzhiyun 	switch (settings->pe_filt_num) {
4244*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_1K:
4245*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_2K:
4246*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_4K:
4247*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_8K:
4248*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_16K:
4249*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_32K:
4250*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_64K:
4251*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_128K:
4252*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_256K:
4253*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_512K:
4254*4882a593Smuzhiyun 	case I40E_HASH_FILTER_SIZE_1M:
4255*4882a593Smuzhiyun 		pe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
4256*4882a593Smuzhiyun 		pe_filt_size <<= (u32)settings->pe_filt_num;
4257*4882a593Smuzhiyun 		break;
4258*4882a593Smuzhiyun 	default:
4259*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4260*4882a593Smuzhiyun 	}
4261*4882a593Smuzhiyun 
4262*4882a593Smuzhiyun 	switch (settings->pe_cntx_num) {
4263*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_512:
4264*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_1K:
4265*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_2K:
4266*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_4K:
4267*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_8K:
4268*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_16K:
4269*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_32K:
4270*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_64K:
4271*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_128K:
4272*4882a593Smuzhiyun 	case I40E_DMA_CNTX_SIZE_256K:
4273*4882a593Smuzhiyun 		pe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
4274*4882a593Smuzhiyun 		pe_cntx_size <<= (u32)settings->pe_cntx_num;
4275*4882a593Smuzhiyun 		break;
4276*4882a593Smuzhiyun 	default:
4277*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4278*4882a593Smuzhiyun 	}
4279*4882a593Smuzhiyun 
4280*4882a593Smuzhiyun 	/* FCHSIZE + FCDSIZE should not be greater than PMFCOEFMAX */
4281*4882a593Smuzhiyun 	val = rd32(hw, I40E_GLHMC_FCOEFMAX);
4282*4882a593Smuzhiyun 	fcoe_fmax = (val & I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK)
4283*4882a593Smuzhiyun 		     >> I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT;
4284*4882a593Smuzhiyun 	if (fcoe_filt_size + fcoe_cntx_size >  fcoe_fmax)
4285*4882a593Smuzhiyun 		return I40E_ERR_INVALID_SIZE;
4286*4882a593Smuzhiyun 
4287*4882a593Smuzhiyun 	return 0;
4288*4882a593Smuzhiyun }
4289*4882a593Smuzhiyun 
4290*4882a593Smuzhiyun /**
4291*4882a593Smuzhiyun  * i40e_set_filter_control
4292*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
4293*4882a593Smuzhiyun  * @settings: Filter control settings
4294*4882a593Smuzhiyun  *
4295*4882a593Smuzhiyun  * Set the Queue Filters for PE/FCoE and enable filters required
4296*4882a593Smuzhiyun  * for a single PF. It is expected that these settings are programmed
4297*4882a593Smuzhiyun  * at the driver initialization time.
4298*4882a593Smuzhiyun  **/
i40e_set_filter_control(struct i40e_hw * hw,struct i40e_filter_control_settings * settings)4299*4882a593Smuzhiyun i40e_status i40e_set_filter_control(struct i40e_hw *hw,
4300*4882a593Smuzhiyun 				struct i40e_filter_control_settings *settings)
4301*4882a593Smuzhiyun {
4302*4882a593Smuzhiyun 	i40e_status ret = 0;
4303*4882a593Smuzhiyun 	u32 hash_lut_size = 0;
4304*4882a593Smuzhiyun 	u32 val;
4305*4882a593Smuzhiyun 
4306*4882a593Smuzhiyun 	if (!settings)
4307*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4308*4882a593Smuzhiyun 
4309*4882a593Smuzhiyun 	/* Validate the input settings */
4310*4882a593Smuzhiyun 	ret = i40e_validate_filter_settings(hw, settings);
4311*4882a593Smuzhiyun 	if (ret)
4312*4882a593Smuzhiyun 		return ret;
4313*4882a593Smuzhiyun 
4314*4882a593Smuzhiyun 	/* Read the PF Queue Filter control register */
4315*4882a593Smuzhiyun 	val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
4316*4882a593Smuzhiyun 
4317*4882a593Smuzhiyun 	/* Program required PE hash buckets for the PF */
4318*4882a593Smuzhiyun 	val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
4319*4882a593Smuzhiyun 	val |= ((u32)settings->pe_filt_num << I40E_PFQF_CTL_0_PEHSIZE_SHIFT) &
4320*4882a593Smuzhiyun 		I40E_PFQF_CTL_0_PEHSIZE_MASK;
4321*4882a593Smuzhiyun 	/* Program required PE contexts for the PF */
4322*4882a593Smuzhiyun 	val &= ~I40E_PFQF_CTL_0_PEDSIZE_MASK;
4323*4882a593Smuzhiyun 	val |= ((u32)settings->pe_cntx_num << I40E_PFQF_CTL_0_PEDSIZE_SHIFT) &
4324*4882a593Smuzhiyun 		I40E_PFQF_CTL_0_PEDSIZE_MASK;
4325*4882a593Smuzhiyun 
4326*4882a593Smuzhiyun 	/* Program required FCoE hash buckets for the PF */
4327*4882a593Smuzhiyun 	val &= ~I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
4328*4882a593Smuzhiyun 	val |= ((u32)settings->fcoe_filt_num <<
4329*4882a593Smuzhiyun 			I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT) &
4330*4882a593Smuzhiyun 		I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
4331*4882a593Smuzhiyun 	/* Program required FCoE DDP contexts for the PF */
4332*4882a593Smuzhiyun 	val &= ~I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
4333*4882a593Smuzhiyun 	val |= ((u32)settings->fcoe_cntx_num <<
4334*4882a593Smuzhiyun 			I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT) &
4335*4882a593Smuzhiyun 		I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
4336*4882a593Smuzhiyun 
4337*4882a593Smuzhiyun 	/* Program Hash LUT size for the PF */
4338*4882a593Smuzhiyun 	val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
4339*4882a593Smuzhiyun 	if (settings->hash_lut_size == I40E_HASH_LUT_SIZE_512)
4340*4882a593Smuzhiyun 		hash_lut_size = 1;
4341*4882a593Smuzhiyun 	val |= (hash_lut_size << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT) &
4342*4882a593Smuzhiyun 		I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
4343*4882a593Smuzhiyun 
4344*4882a593Smuzhiyun 	/* Enable FDIR, Ethertype and MACVLAN filters for PF and VFs */
4345*4882a593Smuzhiyun 	if (settings->enable_fdir)
4346*4882a593Smuzhiyun 		val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
4347*4882a593Smuzhiyun 	if (settings->enable_ethtype)
4348*4882a593Smuzhiyun 		val |= I40E_PFQF_CTL_0_ETYPE_ENA_MASK;
4349*4882a593Smuzhiyun 	if (settings->enable_macvlan)
4350*4882a593Smuzhiyun 		val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
4351*4882a593Smuzhiyun 
4352*4882a593Smuzhiyun 	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
4353*4882a593Smuzhiyun 
4354*4882a593Smuzhiyun 	return 0;
4355*4882a593Smuzhiyun }
4356*4882a593Smuzhiyun 
4357*4882a593Smuzhiyun /**
4358*4882a593Smuzhiyun  * i40e_aq_add_rem_control_packet_filter - Add or Remove Control Packet Filter
4359*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4360*4882a593Smuzhiyun  * @mac_addr: MAC address to use in the filter
4361*4882a593Smuzhiyun  * @ethtype: Ethertype to use in the filter
4362*4882a593Smuzhiyun  * @flags: Flags that needs to be applied to the filter
4363*4882a593Smuzhiyun  * @vsi_seid: seid of the control VSI
4364*4882a593Smuzhiyun  * @queue: VSI queue number to send the packet to
4365*4882a593Smuzhiyun  * @is_add: Add control packet filter if True else remove
4366*4882a593Smuzhiyun  * @stats: Structure to hold information on control filter counts
4367*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4368*4882a593Smuzhiyun  *
4369*4882a593Smuzhiyun  * This command will Add or Remove control packet filter for a control VSI.
4370*4882a593Smuzhiyun  * In return it will update the total number of perfect filter count in
4371*4882a593Smuzhiyun  * the stats member.
4372*4882a593Smuzhiyun  **/
i40e_aq_add_rem_control_packet_filter(struct i40e_hw * hw,u8 * mac_addr,u16 ethtype,u16 flags,u16 vsi_seid,u16 queue,bool is_add,struct i40e_control_filter_stats * stats,struct i40e_asq_cmd_details * cmd_details)4373*4882a593Smuzhiyun i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
4374*4882a593Smuzhiyun 				u8 *mac_addr, u16 ethtype, u16 flags,
4375*4882a593Smuzhiyun 				u16 vsi_seid, u16 queue, bool is_add,
4376*4882a593Smuzhiyun 				struct i40e_control_filter_stats *stats,
4377*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
4378*4882a593Smuzhiyun {
4379*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
4380*4882a593Smuzhiyun 	struct i40e_aqc_add_remove_control_packet_filter *cmd =
4381*4882a593Smuzhiyun 		(struct i40e_aqc_add_remove_control_packet_filter *)
4382*4882a593Smuzhiyun 		&desc.params.raw;
4383*4882a593Smuzhiyun 	struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
4384*4882a593Smuzhiyun 		(struct i40e_aqc_add_remove_control_packet_filter_completion *)
4385*4882a593Smuzhiyun 		&desc.params.raw;
4386*4882a593Smuzhiyun 	i40e_status status;
4387*4882a593Smuzhiyun 
4388*4882a593Smuzhiyun 	if (vsi_seid == 0)
4389*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4390*4882a593Smuzhiyun 
4391*4882a593Smuzhiyun 	if (is_add) {
4392*4882a593Smuzhiyun 		i40e_fill_default_direct_cmd_desc(&desc,
4393*4882a593Smuzhiyun 				i40e_aqc_opc_add_control_packet_filter);
4394*4882a593Smuzhiyun 		cmd->queue = cpu_to_le16(queue);
4395*4882a593Smuzhiyun 	} else {
4396*4882a593Smuzhiyun 		i40e_fill_default_direct_cmd_desc(&desc,
4397*4882a593Smuzhiyun 				i40e_aqc_opc_remove_control_packet_filter);
4398*4882a593Smuzhiyun 	}
4399*4882a593Smuzhiyun 
4400*4882a593Smuzhiyun 	if (mac_addr)
4401*4882a593Smuzhiyun 		ether_addr_copy(cmd->mac, mac_addr);
4402*4882a593Smuzhiyun 
4403*4882a593Smuzhiyun 	cmd->etype = cpu_to_le16(ethtype);
4404*4882a593Smuzhiyun 	cmd->flags = cpu_to_le16(flags);
4405*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(vsi_seid);
4406*4882a593Smuzhiyun 
4407*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4408*4882a593Smuzhiyun 
4409*4882a593Smuzhiyun 	if (!status && stats) {
4410*4882a593Smuzhiyun 		stats->mac_etype_used = le16_to_cpu(resp->mac_etype_used);
4411*4882a593Smuzhiyun 		stats->etype_used = le16_to_cpu(resp->etype_used);
4412*4882a593Smuzhiyun 		stats->mac_etype_free = le16_to_cpu(resp->mac_etype_free);
4413*4882a593Smuzhiyun 		stats->etype_free = le16_to_cpu(resp->etype_free);
4414*4882a593Smuzhiyun 	}
4415*4882a593Smuzhiyun 
4416*4882a593Smuzhiyun 	return status;
4417*4882a593Smuzhiyun }
4418*4882a593Smuzhiyun 
4419*4882a593Smuzhiyun /**
4420*4882a593Smuzhiyun  * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
4421*4882a593Smuzhiyun  * @hw: pointer to the hw struct
4422*4882a593Smuzhiyun  * @seid: VSI seid to add ethertype filter from
4423*4882a593Smuzhiyun  **/
i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw * hw,u16 seid)4424*4882a593Smuzhiyun void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
4425*4882a593Smuzhiyun 						    u16 seid)
4426*4882a593Smuzhiyun {
4427*4882a593Smuzhiyun #define I40E_FLOW_CONTROL_ETHTYPE 0x8808
4428*4882a593Smuzhiyun 	u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
4429*4882a593Smuzhiyun 		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
4430*4882a593Smuzhiyun 		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
4431*4882a593Smuzhiyun 	u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
4432*4882a593Smuzhiyun 	i40e_status status;
4433*4882a593Smuzhiyun 
4434*4882a593Smuzhiyun 	status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
4435*4882a593Smuzhiyun 						       seid, 0, true, NULL,
4436*4882a593Smuzhiyun 						       NULL);
4437*4882a593Smuzhiyun 	if (status)
4438*4882a593Smuzhiyun 		hw_dbg(hw, "Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
4439*4882a593Smuzhiyun }
4440*4882a593Smuzhiyun 
4441*4882a593Smuzhiyun /**
4442*4882a593Smuzhiyun  * i40e_aq_alternate_read
4443*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
4444*4882a593Smuzhiyun  * @reg_addr0: address of first dword to be read
4445*4882a593Smuzhiyun  * @reg_val0: pointer for data read from 'reg_addr0'
4446*4882a593Smuzhiyun  * @reg_addr1: address of second dword to be read
4447*4882a593Smuzhiyun  * @reg_val1: pointer for data read from 'reg_addr1'
4448*4882a593Smuzhiyun  *
4449*4882a593Smuzhiyun  * Read one or two dwords from alternate structure. Fields are indicated
4450*4882a593Smuzhiyun  * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
4451*4882a593Smuzhiyun  * is not passed then only register at 'reg_addr0' is read.
4452*4882a593Smuzhiyun  *
4453*4882a593Smuzhiyun  **/
i40e_aq_alternate_read(struct i40e_hw * hw,u32 reg_addr0,u32 * reg_val0,u32 reg_addr1,u32 * reg_val1)4454*4882a593Smuzhiyun static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
4455*4882a593Smuzhiyun 					  u32 reg_addr0, u32 *reg_val0,
4456*4882a593Smuzhiyun 					  u32 reg_addr1, u32 *reg_val1)
4457*4882a593Smuzhiyun {
4458*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
4459*4882a593Smuzhiyun 	struct i40e_aqc_alternate_write *cmd_resp =
4460*4882a593Smuzhiyun 		(struct i40e_aqc_alternate_write *)&desc.params.raw;
4461*4882a593Smuzhiyun 	i40e_status status;
4462*4882a593Smuzhiyun 
4463*4882a593Smuzhiyun 	if (!reg_val0)
4464*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4465*4882a593Smuzhiyun 
4466*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
4467*4882a593Smuzhiyun 	cmd_resp->address0 = cpu_to_le32(reg_addr0);
4468*4882a593Smuzhiyun 	cmd_resp->address1 = cpu_to_le32(reg_addr1);
4469*4882a593Smuzhiyun 
4470*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
4471*4882a593Smuzhiyun 
4472*4882a593Smuzhiyun 	if (!status) {
4473*4882a593Smuzhiyun 		*reg_val0 = le32_to_cpu(cmd_resp->data0);
4474*4882a593Smuzhiyun 
4475*4882a593Smuzhiyun 		if (reg_val1)
4476*4882a593Smuzhiyun 			*reg_val1 = le32_to_cpu(cmd_resp->data1);
4477*4882a593Smuzhiyun 	}
4478*4882a593Smuzhiyun 
4479*4882a593Smuzhiyun 	return status;
4480*4882a593Smuzhiyun }
4481*4882a593Smuzhiyun 
4482*4882a593Smuzhiyun /**
4483*4882a593Smuzhiyun  * i40e_aq_resume_port_tx
4484*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
4485*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4486*4882a593Smuzhiyun  *
4487*4882a593Smuzhiyun  * Resume port's Tx traffic
4488*4882a593Smuzhiyun  **/
i40e_aq_resume_port_tx(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)4489*4882a593Smuzhiyun i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
4490*4882a593Smuzhiyun 				   struct i40e_asq_cmd_details *cmd_details)
4491*4882a593Smuzhiyun {
4492*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
4493*4882a593Smuzhiyun 	i40e_status status;
4494*4882a593Smuzhiyun 
4495*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
4496*4882a593Smuzhiyun 
4497*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4498*4882a593Smuzhiyun 
4499*4882a593Smuzhiyun 	return status;
4500*4882a593Smuzhiyun }
4501*4882a593Smuzhiyun 
4502*4882a593Smuzhiyun /**
4503*4882a593Smuzhiyun  * i40e_set_pci_config_data - store PCI bus info
4504*4882a593Smuzhiyun  * @hw: pointer to hardware structure
4505*4882a593Smuzhiyun  * @link_status: the link status word from PCI config space
4506*4882a593Smuzhiyun  *
4507*4882a593Smuzhiyun  * Stores the PCI bus info (speed, width, type) within the i40e_hw structure
4508*4882a593Smuzhiyun  **/
i40e_set_pci_config_data(struct i40e_hw * hw,u16 link_status)4509*4882a593Smuzhiyun void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
4510*4882a593Smuzhiyun {
4511*4882a593Smuzhiyun 	hw->bus.type = i40e_bus_type_pci_express;
4512*4882a593Smuzhiyun 
4513*4882a593Smuzhiyun 	switch (link_status & PCI_EXP_LNKSTA_NLW) {
4514*4882a593Smuzhiyun 	case PCI_EXP_LNKSTA_NLW_X1:
4515*4882a593Smuzhiyun 		hw->bus.width = i40e_bus_width_pcie_x1;
4516*4882a593Smuzhiyun 		break;
4517*4882a593Smuzhiyun 	case PCI_EXP_LNKSTA_NLW_X2:
4518*4882a593Smuzhiyun 		hw->bus.width = i40e_bus_width_pcie_x2;
4519*4882a593Smuzhiyun 		break;
4520*4882a593Smuzhiyun 	case PCI_EXP_LNKSTA_NLW_X4:
4521*4882a593Smuzhiyun 		hw->bus.width = i40e_bus_width_pcie_x4;
4522*4882a593Smuzhiyun 		break;
4523*4882a593Smuzhiyun 	case PCI_EXP_LNKSTA_NLW_X8:
4524*4882a593Smuzhiyun 		hw->bus.width = i40e_bus_width_pcie_x8;
4525*4882a593Smuzhiyun 		break;
4526*4882a593Smuzhiyun 	default:
4527*4882a593Smuzhiyun 		hw->bus.width = i40e_bus_width_unknown;
4528*4882a593Smuzhiyun 		break;
4529*4882a593Smuzhiyun 	}
4530*4882a593Smuzhiyun 
4531*4882a593Smuzhiyun 	switch (link_status & PCI_EXP_LNKSTA_CLS) {
4532*4882a593Smuzhiyun 	case PCI_EXP_LNKSTA_CLS_2_5GB:
4533*4882a593Smuzhiyun 		hw->bus.speed = i40e_bus_speed_2500;
4534*4882a593Smuzhiyun 		break;
4535*4882a593Smuzhiyun 	case PCI_EXP_LNKSTA_CLS_5_0GB:
4536*4882a593Smuzhiyun 		hw->bus.speed = i40e_bus_speed_5000;
4537*4882a593Smuzhiyun 		break;
4538*4882a593Smuzhiyun 	case PCI_EXP_LNKSTA_CLS_8_0GB:
4539*4882a593Smuzhiyun 		hw->bus.speed = i40e_bus_speed_8000;
4540*4882a593Smuzhiyun 		break;
4541*4882a593Smuzhiyun 	default:
4542*4882a593Smuzhiyun 		hw->bus.speed = i40e_bus_speed_unknown;
4543*4882a593Smuzhiyun 		break;
4544*4882a593Smuzhiyun 	}
4545*4882a593Smuzhiyun }
4546*4882a593Smuzhiyun 
4547*4882a593Smuzhiyun /**
4548*4882a593Smuzhiyun  * i40e_aq_debug_dump
4549*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
4550*4882a593Smuzhiyun  * @cluster_id: specific cluster to dump
4551*4882a593Smuzhiyun  * @table_id: table id within cluster
4552*4882a593Smuzhiyun  * @start_index: index of line in the block to read
4553*4882a593Smuzhiyun  * @buff_size: dump buffer size
4554*4882a593Smuzhiyun  * @buff: dump buffer
4555*4882a593Smuzhiyun  * @ret_buff_size: actual buffer size returned
4556*4882a593Smuzhiyun  * @ret_next_table: next block to read
4557*4882a593Smuzhiyun  * @ret_next_index: next index to read
4558*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
4559*4882a593Smuzhiyun  *
4560*4882a593Smuzhiyun  * Dump internal FW/HW data for debug purposes.
4561*4882a593Smuzhiyun  *
4562*4882a593Smuzhiyun  **/
i40e_aq_debug_dump(struct i40e_hw * hw,u8 cluster_id,u8 table_id,u32 start_index,u16 buff_size,void * buff,u16 * ret_buff_size,u8 * ret_next_table,u32 * ret_next_index,struct i40e_asq_cmd_details * cmd_details)4563*4882a593Smuzhiyun i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
4564*4882a593Smuzhiyun 			       u8 table_id, u32 start_index, u16 buff_size,
4565*4882a593Smuzhiyun 			       void *buff, u16 *ret_buff_size,
4566*4882a593Smuzhiyun 			       u8 *ret_next_table, u32 *ret_next_index,
4567*4882a593Smuzhiyun 			       struct i40e_asq_cmd_details *cmd_details)
4568*4882a593Smuzhiyun {
4569*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
4570*4882a593Smuzhiyun 	struct i40e_aqc_debug_dump_internals *cmd =
4571*4882a593Smuzhiyun 		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
4572*4882a593Smuzhiyun 	struct i40e_aqc_debug_dump_internals *resp =
4573*4882a593Smuzhiyun 		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
4574*4882a593Smuzhiyun 	i40e_status status;
4575*4882a593Smuzhiyun 
4576*4882a593Smuzhiyun 	if (buff_size == 0 || !buff)
4577*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
4578*4882a593Smuzhiyun 
4579*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
4580*4882a593Smuzhiyun 					  i40e_aqc_opc_debug_dump_internals);
4581*4882a593Smuzhiyun 	/* Indirect Command */
4582*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
4583*4882a593Smuzhiyun 	if (buff_size > I40E_AQ_LARGE_BUF)
4584*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
4585*4882a593Smuzhiyun 
4586*4882a593Smuzhiyun 	cmd->cluster_id = cluster_id;
4587*4882a593Smuzhiyun 	cmd->table_id = table_id;
4588*4882a593Smuzhiyun 	cmd->idx = cpu_to_le32(start_index);
4589*4882a593Smuzhiyun 
4590*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_size);
4591*4882a593Smuzhiyun 
4592*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4593*4882a593Smuzhiyun 	if (!status) {
4594*4882a593Smuzhiyun 		if (ret_buff_size)
4595*4882a593Smuzhiyun 			*ret_buff_size = le16_to_cpu(desc.datalen);
4596*4882a593Smuzhiyun 		if (ret_next_table)
4597*4882a593Smuzhiyun 			*ret_next_table = resp->table_id;
4598*4882a593Smuzhiyun 		if (ret_next_index)
4599*4882a593Smuzhiyun 			*ret_next_index = le32_to_cpu(resp->idx);
4600*4882a593Smuzhiyun 	}
4601*4882a593Smuzhiyun 
4602*4882a593Smuzhiyun 	return status;
4603*4882a593Smuzhiyun }
4604*4882a593Smuzhiyun 
4605*4882a593Smuzhiyun /**
4606*4882a593Smuzhiyun  * i40e_read_bw_from_alt_ram
4607*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
4608*4882a593Smuzhiyun  * @max_bw: pointer for max_bw read
4609*4882a593Smuzhiyun  * @min_bw: pointer for min_bw read
4610*4882a593Smuzhiyun  * @min_valid: pointer for bool that is true if min_bw is a valid value
4611*4882a593Smuzhiyun  * @max_valid: pointer for bool that is true if max_bw is a valid value
4612*4882a593Smuzhiyun  *
4613*4882a593Smuzhiyun  * Read bw from the alternate ram for the given pf
4614*4882a593Smuzhiyun  **/
i40e_read_bw_from_alt_ram(struct i40e_hw * hw,u32 * max_bw,u32 * min_bw,bool * min_valid,bool * max_valid)4615*4882a593Smuzhiyun i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
4616*4882a593Smuzhiyun 				      u32 *max_bw, u32 *min_bw,
4617*4882a593Smuzhiyun 				      bool *min_valid, bool *max_valid)
4618*4882a593Smuzhiyun {
4619*4882a593Smuzhiyun 	i40e_status status;
4620*4882a593Smuzhiyun 	u32 max_bw_addr, min_bw_addr;
4621*4882a593Smuzhiyun 
4622*4882a593Smuzhiyun 	/* Calculate the address of the min/max bw registers */
4623*4882a593Smuzhiyun 	max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
4624*4882a593Smuzhiyun 		      I40E_ALT_STRUCT_MAX_BW_OFFSET +
4625*4882a593Smuzhiyun 		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
4626*4882a593Smuzhiyun 	min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
4627*4882a593Smuzhiyun 		      I40E_ALT_STRUCT_MIN_BW_OFFSET +
4628*4882a593Smuzhiyun 		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
4629*4882a593Smuzhiyun 
4630*4882a593Smuzhiyun 	/* Read the bandwidths from alt ram */
4631*4882a593Smuzhiyun 	status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
4632*4882a593Smuzhiyun 					min_bw_addr, min_bw);
4633*4882a593Smuzhiyun 
4634*4882a593Smuzhiyun 	if (*min_bw & I40E_ALT_BW_VALID_MASK)
4635*4882a593Smuzhiyun 		*min_valid = true;
4636*4882a593Smuzhiyun 	else
4637*4882a593Smuzhiyun 		*min_valid = false;
4638*4882a593Smuzhiyun 
4639*4882a593Smuzhiyun 	if (*max_bw & I40E_ALT_BW_VALID_MASK)
4640*4882a593Smuzhiyun 		*max_valid = true;
4641*4882a593Smuzhiyun 	else
4642*4882a593Smuzhiyun 		*max_valid = false;
4643*4882a593Smuzhiyun 
4644*4882a593Smuzhiyun 	return status;
4645*4882a593Smuzhiyun }
4646*4882a593Smuzhiyun 
4647*4882a593Smuzhiyun /**
4648*4882a593Smuzhiyun  * i40e_aq_configure_partition_bw
4649*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
4650*4882a593Smuzhiyun  * @bw_data: Buffer holding valid pfs and bw limits
4651*4882a593Smuzhiyun  * @cmd_details: pointer to command details
4652*4882a593Smuzhiyun  *
4653*4882a593Smuzhiyun  * Configure partitions guaranteed/max bw
4654*4882a593Smuzhiyun  **/
i40e_aq_configure_partition_bw(struct i40e_hw * hw,struct i40e_aqc_configure_partition_bw_data * bw_data,struct i40e_asq_cmd_details * cmd_details)4655*4882a593Smuzhiyun i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
4656*4882a593Smuzhiyun 			struct i40e_aqc_configure_partition_bw_data *bw_data,
4657*4882a593Smuzhiyun 			struct i40e_asq_cmd_details *cmd_details)
4658*4882a593Smuzhiyun {
4659*4882a593Smuzhiyun 	i40e_status status;
4660*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
4661*4882a593Smuzhiyun 	u16 bwd_size = sizeof(*bw_data);
4662*4882a593Smuzhiyun 
4663*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
4664*4882a593Smuzhiyun 					  i40e_aqc_opc_configure_partition_bw);
4665*4882a593Smuzhiyun 
4666*4882a593Smuzhiyun 	/* Indirect command */
4667*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
4668*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
4669*4882a593Smuzhiyun 
4670*4882a593Smuzhiyun 	if (bwd_size > I40E_AQ_LARGE_BUF)
4671*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
4672*4882a593Smuzhiyun 
4673*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(bwd_size);
4674*4882a593Smuzhiyun 
4675*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size,
4676*4882a593Smuzhiyun 				       cmd_details);
4677*4882a593Smuzhiyun 
4678*4882a593Smuzhiyun 	return status;
4679*4882a593Smuzhiyun }
4680*4882a593Smuzhiyun 
4681*4882a593Smuzhiyun /**
4682*4882a593Smuzhiyun  * i40e_read_phy_register_clause22
4683*4882a593Smuzhiyun  * @hw: pointer to the HW structure
4684*4882a593Smuzhiyun  * @reg: register address in the page
4685*4882a593Smuzhiyun  * @phy_addr: PHY address on MDIO interface
4686*4882a593Smuzhiyun  * @value: PHY register value
4687*4882a593Smuzhiyun  *
4688*4882a593Smuzhiyun  * Reads specified PHY register value
4689*4882a593Smuzhiyun  **/
i40e_read_phy_register_clause22(struct i40e_hw * hw,u16 reg,u8 phy_addr,u16 * value)4690*4882a593Smuzhiyun i40e_status i40e_read_phy_register_clause22(struct i40e_hw *hw,
4691*4882a593Smuzhiyun 					    u16 reg, u8 phy_addr, u16 *value)
4692*4882a593Smuzhiyun {
4693*4882a593Smuzhiyun 	i40e_status status = I40E_ERR_TIMEOUT;
4694*4882a593Smuzhiyun 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
4695*4882a593Smuzhiyun 	u32 command = 0;
4696*4882a593Smuzhiyun 	u16 retry = 1000;
4697*4882a593Smuzhiyun 
4698*4882a593Smuzhiyun 	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4699*4882a593Smuzhiyun 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4700*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE22_OPCODE_READ_MASK) |
4701*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
4702*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDICMD_MASK);
4703*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4704*4882a593Smuzhiyun 	do {
4705*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4706*4882a593Smuzhiyun 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4707*4882a593Smuzhiyun 			status = 0;
4708*4882a593Smuzhiyun 			break;
4709*4882a593Smuzhiyun 		}
4710*4882a593Smuzhiyun 		udelay(10);
4711*4882a593Smuzhiyun 		retry--;
4712*4882a593Smuzhiyun 	} while (retry);
4713*4882a593Smuzhiyun 
4714*4882a593Smuzhiyun 	if (status) {
4715*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_PHY,
4716*4882a593Smuzhiyun 			   "PHY: Can't write command to external PHY.\n");
4717*4882a593Smuzhiyun 	} else {
4718*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
4719*4882a593Smuzhiyun 		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
4720*4882a593Smuzhiyun 			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
4721*4882a593Smuzhiyun 	}
4722*4882a593Smuzhiyun 
4723*4882a593Smuzhiyun 	return status;
4724*4882a593Smuzhiyun }
4725*4882a593Smuzhiyun 
4726*4882a593Smuzhiyun /**
4727*4882a593Smuzhiyun  * i40e_write_phy_register_clause22
4728*4882a593Smuzhiyun  * @hw: pointer to the HW structure
4729*4882a593Smuzhiyun  * @reg: register address in the page
4730*4882a593Smuzhiyun  * @phy_addr: PHY address on MDIO interface
4731*4882a593Smuzhiyun  * @value: PHY register value
4732*4882a593Smuzhiyun  *
4733*4882a593Smuzhiyun  * Writes specified PHY register value
4734*4882a593Smuzhiyun  **/
i40e_write_phy_register_clause22(struct i40e_hw * hw,u16 reg,u8 phy_addr,u16 value)4735*4882a593Smuzhiyun i40e_status i40e_write_phy_register_clause22(struct i40e_hw *hw,
4736*4882a593Smuzhiyun 					     u16 reg, u8 phy_addr, u16 value)
4737*4882a593Smuzhiyun {
4738*4882a593Smuzhiyun 	i40e_status status = I40E_ERR_TIMEOUT;
4739*4882a593Smuzhiyun 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
4740*4882a593Smuzhiyun 	u32 command  = 0;
4741*4882a593Smuzhiyun 	u16 retry = 1000;
4742*4882a593Smuzhiyun 
4743*4882a593Smuzhiyun 	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
4744*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
4745*4882a593Smuzhiyun 
4746*4882a593Smuzhiyun 	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4747*4882a593Smuzhiyun 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4748*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE22_OPCODE_WRITE_MASK) |
4749*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
4750*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDICMD_MASK);
4751*4882a593Smuzhiyun 
4752*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4753*4882a593Smuzhiyun 	do {
4754*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4755*4882a593Smuzhiyun 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4756*4882a593Smuzhiyun 			status = 0;
4757*4882a593Smuzhiyun 			break;
4758*4882a593Smuzhiyun 		}
4759*4882a593Smuzhiyun 		udelay(10);
4760*4882a593Smuzhiyun 		retry--;
4761*4882a593Smuzhiyun 	} while (retry);
4762*4882a593Smuzhiyun 
4763*4882a593Smuzhiyun 	return status;
4764*4882a593Smuzhiyun }
4765*4882a593Smuzhiyun 
4766*4882a593Smuzhiyun /**
4767*4882a593Smuzhiyun  * i40e_read_phy_register_clause45
4768*4882a593Smuzhiyun  * @hw: pointer to the HW structure
4769*4882a593Smuzhiyun  * @page: registers page number
4770*4882a593Smuzhiyun  * @reg: register address in the page
4771*4882a593Smuzhiyun  * @phy_addr: PHY address on MDIO interface
4772*4882a593Smuzhiyun  * @value: PHY register value
4773*4882a593Smuzhiyun  *
4774*4882a593Smuzhiyun  * Reads specified PHY register value
4775*4882a593Smuzhiyun  **/
i40e_read_phy_register_clause45(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 * value)4776*4882a593Smuzhiyun i40e_status i40e_read_phy_register_clause45(struct i40e_hw *hw,
4777*4882a593Smuzhiyun 				u8 page, u16 reg, u8 phy_addr, u16 *value)
4778*4882a593Smuzhiyun {
4779*4882a593Smuzhiyun 	i40e_status status = I40E_ERR_TIMEOUT;
4780*4882a593Smuzhiyun 	u32 command = 0;
4781*4882a593Smuzhiyun 	u16 retry = 1000;
4782*4882a593Smuzhiyun 	u8 port_num = hw->func_caps.mdio_port_num;
4783*4882a593Smuzhiyun 
4784*4882a593Smuzhiyun 	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
4785*4882a593Smuzhiyun 		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4786*4882a593Smuzhiyun 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4787*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
4788*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
4789*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
4790*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4791*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4792*4882a593Smuzhiyun 	do {
4793*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4794*4882a593Smuzhiyun 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4795*4882a593Smuzhiyun 			status = 0;
4796*4882a593Smuzhiyun 			break;
4797*4882a593Smuzhiyun 		}
4798*4882a593Smuzhiyun 		usleep_range(10, 20);
4799*4882a593Smuzhiyun 		retry--;
4800*4882a593Smuzhiyun 	} while (retry);
4801*4882a593Smuzhiyun 
4802*4882a593Smuzhiyun 	if (status) {
4803*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_PHY,
4804*4882a593Smuzhiyun 			   "PHY: Can't write command to external PHY.\n");
4805*4882a593Smuzhiyun 		goto phy_read_end;
4806*4882a593Smuzhiyun 	}
4807*4882a593Smuzhiyun 
4808*4882a593Smuzhiyun 	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4809*4882a593Smuzhiyun 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4810*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_OPCODE_READ_MASK) |
4811*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
4812*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
4813*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4814*4882a593Smuzhiyun 	status = I40E_ERR_TIMEOUT;
4815*4882a593Smuzhiyun 	retry = 1000;
4816*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4817*4882a593Smuzhiyun 	do {
4818*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4819*4882a593Smuzhiyun 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4820*4882a593Smuzhiyun 			status = 0;
4821*4882a593Smuzhiyun 			break;
4822*4882a593Smuzhiyun 		}
4823*4882a593Smuzhiyun 		usleep_range(10, 20);
4824*4882a593Smuzhiyun 		retry--;
4825*4882a593Smuzhiyun 	} while (retry);
4826*4882a593Smuzhiyun 
4827*4882a593Smuzhiyun 	if (!status) {
4828*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
4829*4882a593Smuzhiyun 		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
4830*4882a593Smuzhiyun 			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
4831*4882a593Smuzhiyun 	} else {
4832*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_PHY,
4833*4882a593Smuzhiyun 			   "PHY: Can't read register value from external PHY.\n");
4834*4882a593Smuzhiyun 	}
4835*4882a593Smuzhiyun 
4836*4882a593Smuzhiyun phy_read_end:
4837*4882a593Smuzhiyun 	return status;
4838*4882a593Smuzhiyun }
4839*4882a593Smuzhiyun 
4840*4882a593Smuzhiyun /**
4841*4882a593Smuzhiyun  * i40e_write_phy_register_clause45
4842*4882a593Smuzhiyun  * @hw: pointer to the HW structure
4843*4882a593Smuzhiyun  * @page: registers page number
4844*4882a593Smuzhiyun  * @reg: register address in the page
4845*4882a593Smuzhiyun  * @phy_addr: PHY address on MDIO interface
4846*4882a593Smuzhiyun  * @value: PHY register value
4847*4882a593Smuzhiyun  *
4848*4882a593Smuzhiyun  * Writes value to specified PHY register
4849*4882a593Smuzhiyun  **/
i40e_write_phy_register_clause45(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 value)4850*4882a593Smuzhiyun i40e_status i40e_write_phy_register_clause45(struct i40e_hw *hw,
4851*4882a593Smuzhiyun 				u8 page, u16 reg, u8 phy_addr, u16 value)
4852*4882a593Smuzhiyun {
4853*4882a593Smuzhiyun 	i40e_status status = I40E_ERR_TIMEOUT;
4854*4882a593Smuzhiyun 	u32 command = 0;
4855*4882a593Smuzhiyun 	u16 retry = 1000;
4856*4882a593Smuzhiyun 	u8 port_num = hw->func_caps.mdio_port_num;
4857*4882a593Smuzhiyun 
4858*4882a593Smuzhiyun 	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
4859*4882a593Smuzhiyun 		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4860*4882a593Smuzhiyun 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4861*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
4862*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
4863*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
4864*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4865*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4866*4882a593Smuzhiyun 	do {
4867*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4868*4882a593Smuzhiyun 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4869*4882a593Smuzhiyun 			status = 0;
4870*4882a593Smuzhiyun 			break;
4871*4882a593Smuzhiyun 		}
4872*4882a593Smuzhiyun 		usleep_range(10, 20);
4873*4882a593Smuzhiyun 		retry--;
4874*4882a593Smuzhiyun 	} while (retry);
4875*4882a593Smuzhiyun 	if (status) {
4876*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_PHY,
4877*4882a593Smuzhiyun 			   "PHY: Can't write command to external PHY.\n");
4878*4882a593Smuzhiyun 		goto phy_write_end;
4879*4882a593Smuzhiyun 	}
4880*4882a593Smuzhiyun 
4881*4882a593Smuzhiyun 	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
4882*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
4883*4882a593Smuzhiyun 
4884*4882a593Smuzhiyun 	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4885*4882a593Smuzhiyun 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4886*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_OPCODE_WRITE_MASK) |
4887*4882a593Smuzhiyun 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
4888*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
4889*4882a593Smuzhiyun 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4890*4882a593Smuzhiyun 	status = I40E_ERR_TIMEOUT;
4891*4882a593Smuzhiyun 	retry = 1000;
4892*4882a593Smuzhiyun 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4893*4882a593Smuzhiyun 	do {
4894*4882a593Smuzhiyun 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4895*4882a593Smuzhiyun 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4896*4882a593Smuzhiyun 			status = 0;
4897*4882a593Smuzhiyun 			break;
4898*4882a593Smuzhiyun 		}
4899*4882a593Smuzhiyun 		usleep_range(10, 20);
4900*4882a593Smuzhiyun 		retry--;
4901*4882a593Smuzhiyun 	} while (retry);
4902*4882a593Smuzhiyun 
4903*4882a593Smuzhiyun phy_write_end:
4904*4882a593Smuzhiyun 	return status;
4905*4882a593Smuzhiyun }
4906*4882a593Smuzhiyun 
4907*4882a593Smuzhiyun /**
4908*4882a593Smuzhiyun  * i40e_write_phy_register
4909*4882a593Smuzhiyun  * @hw: pointer to the HW structure
4910*4882a593Smuzhiyun  * @page: registers page number
4911*4882a593Smuzhiyun  * @reg: register address in the page
4912*4882a593Smuzhiyun  * @phy_addr: PHY address on MDIO interface
4913*4882a593Smuzhiyun  * @value: PHY register value
4914*4882a593Smuzhiyun  *
4915*4882a593Smuzhiyun  * Writes value to specified PHY register
4916*4882a593Smuzhiyun  **/
i40e_write_phy_register(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 value)4917*4882a593Smuzhiyun i40e_status i40e_write_phy_register(struct i40e_hw *hw,
4918*4882a593Smuzhiyun 				    u8 page, u16 reg, u8 phy_addr, u16 value)
4919*4882a593Smuzhiyun {
4920*4882a593Smuzhiyun 	i40e_status status;
4921*4882a593Smuzhiyun 
4922*4882a593Smuzhiyun 	switch (hw->device_id) {
4923*4882a593Smuzhiyun 	case I40E_DEV_ID_1G_BASE_T_X722:
4924*4882a593Smuzhiyun 		status = i40e_write_phy_register_clause22(hw, reg, phy_addr,
4925*4882a593Smuzhiyun 							  value);
4926*4882a593Smuzhiyun 		break;
4927*4882a593Smuzhiyun 	case I40E_DEV_ID_5G_BASE_T_BC:
4928*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T:
4929*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T4:
4930*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T_BC:
4931*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T_X722:
4932*4882a593Smuzhiyun 	case I40E_DEV_ID_25G_B:
4933*4882a593Smuzhiyun 	case I40E_DEV_ID_25G_SFP28:
4934*4882a593Smuzhiyun 		status = i40e_write_phy_register_clause45(hw, page, reg,
4935*4882a593Smuzhiyun 							  phy_addr, value);
4936*4882a593Smuzhiyun 		break;
4937*4882a593Smuzhiyun 	default:
4938*4882a593Smuzhiyun 		status = I40E_ERR_UNKNOWN_PHY;
4939*4882a593Smuzhiyun 		break;
4940*4882a593Smuzhiyun 	}
4941*4882a593Smuzhiyun 
4942*4882a593Smuzhiyun 	return status;
4943*4882a593Smuzhiyun }
4944*4882a593Smuzhiyun 
4945*4882a593Smuzhiyun /**
4946*4882a593Smuzhiyun  * i40e_read_phy_register
4947*4882a593Smuzhiyun  * @hw: pointer to the HW structure
4948*4882a593Smuzhiyun  * @page: registers page number
4949*4882a593Smuzhiyun  * @reg: register address in the page
4950*4882a593Smuzhiyun  * @phy_addr: PHY address on MDIO interface
4951*4882a593Smuzhiyun  * @value: PHY register value
4952*4882a593Smuzhiyun  *
4953*4882a593Smuzhiyun  * Reads specified PHY register value
4954*4882a593Smuzhiyun  **/
i40e_read_phy_register(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 * value)4955*4882a593Smuzhiyun i40e_status i40e_read_phy_register(struct i40e_hw *hw,
4956*4882a593Smuzhiyun 				   u8 page, u16 reg, u8 phy_addr, u16 *value)
4957*4882a593Smuzhiyun {
4958*4882a593Smuzhiyun 	i40e_status status;
4959*4882a593Smuzhiyun 
4960*4882a593Smuzhiyun 	switch (hw->device_id) {
4961*4882a593Smuzhiyun 	case I40E_DEV_ID_1G_BASE_T_X722:
4962*4882a593Smuzhiyun 		status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
4963*4882a593Smuzhiyun 							 value);
4964*4882a593Smuzhiyun 		break;
4965*4882a593Smuzhiyun 	case I40E_DEV_ID_5G_BASE_T_BC:
4966*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T:
4967*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T4:
4968*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T_BC:
4969*4882a593Smuzhiyun 	case I40E_DEV_ID_10G_BASE_T_X722:
4970*4882a593Smuzhiyun 	case I40E_DEV_ID_25G_B:
4971*4882a593Smuzhiyun 	case I40E_DEV_ID_25G_SFP28:
4972*4882a593Smuzhiyun 		status = i40e_read_phy_register_clause45(hw, page, reg,
4973*4882a593Smuzhiyun 							 phy_addr, value);
4974*4882a593Smuzhiyun 		break;
4975*4882a593Smuzhiyun 	default:
4976*4882a593Smuzhiyun 		status = I40E_ERR_UNKNOWN_PHY;
4977*4882a593Smuzhiyun 		break;
4978*4882a593Smuzhiyun 	}
4979*4882a593Smuzhiyun 
4980*4882a593Smuzhiyun 	return status;
4981*4882a593Smuzhiyun }
4982*4882a593Smuzhiyun 
4983*4882a593Smuzhiyun /**
4984*4882a593Smuzhiyun  * i40e_get_phy_address
4985*4882a593Smuzhiyun  * @hw: pointer to the HW structure
4986*4882a593Smuzhiyun  * @dev_num: PHY port num that address we want
4987*4882a593Smuzhiyun  *
4988*4882a593Smuzhiyun  * Gets PHY address for current port
4989*4882a593Smuzhiyun  **/
i40e_get_phy_address(struct i40e_hw * hw,u8 dev_num)4990*4882a593Smuzhiyun u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
4991*4882a593Smuzhiyun {
4992*4882a593Smuzhiyun 	u8 port_num = hw->func_caps.mdio_port_num;
4993*4882a593Smuzhiyun 	u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
4994*4882a593Smuzhiyun 
4995*4882a593Smuzhiyun 	return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
4996*4882a593Smuzhiyun }
4997*4882a593Smuzhiyun 
4998*4882a593Smuzhiyun /**
4999*4882a593Smuzhiyun  * i40e_blink_phy_led
5000*4882a593Smuzhiyun  * @hw: pointer to the HW structure
5001*4882a593Smuzhiyun  * @time: time how long led will blinks in secs
5002*4882a593Smuzhiyun  * @interval: gap between LED on and off in msecs
5003*4882a593Smuzhiyun  *
5004*4882a593Smuzhiyun  * Blinks PHY link LED
5005*4882a593Smuzhiyun  **/
i40e_blink_phy_link_led(struct i40e_hw * hw,u32 time,u32 interval)5006*4882a593Smuzhiyun i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
5007*4882a593Smuzhiyun 				    u32 time, u32 interval)
5008*4882a593Smuzhiyun {
5009*4882a593Smuzhiyun 	i40e_status status = 0;
5010*4882a593Smuzhiyun 	u32 i;
5011*4882a593Smuzhiyun 	u16 led_ctl;
5012*4882a593Smuzhiyun 	u16 gpio_led_port;
5013*4882a593Smuzhiyun 	u16 led_reg;
5014*4882a593Smuzhiyun 	u16 led_addr = I40E_PHY_LED_PROV_REG_1;
5015*4882a593Smuzhiyun 	u8 phy_addr = 0;
5016*4882a593Smuzhiyun 	u8 port_num;
5017*4882a593Smuzhiyun 
5018*4882a593Smuzhiyun 	i = rd32(hw, I40E_PFGEN_PORTNUM);
5019*4882a593Smuzhiyun 	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
5020*4882a593Smuzhiyun 	phy_addr = i40e_get_phy_address(hw, port_num);
5021*4882a593Smuzhiyun 
5022*4882a593Smuzhiyun 	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
5023*4882a593Smuzhiyun 	     led_addr++) {
5024*4882a593Smuzhiyun 		status = i40e_read_phy_register_clause45(hw,
5025*4882a593Smuzhiyun 							 I40E_PHY_COM_REG_PAGE,
5026*4882a593Smuzhiyun 							 led_addr, phy_addr,
5027*4882a593Smuzhiyun 							 &led_reg);
5028*4882a593Smuzhiyun 		if (status)
5029*4882a593Smuzhiyun 			goto phy_blinking_end;
5030*4882a593Smuzhiyun 		led_ctl = led_reg;
5031*4882a593Smuzhiyun 		if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
5032*4882a593Smuzhiyun 			led_reg = 0;
5033*4882a593Smuzhiyun 			status = i40e_write_phy_register_clause45(hw,
5034*4882a593Smuzhiyun 							 I40E_PHY_COM_REG_PAGE,
5035*4882a593Smuzhiyun 							 led_addr, phy_addr,
5036*4882a593Smuzhiyun 							 led_reg);
5037*4882a593Smuzhiyun 			if (status)
5038*4882a593Smuzhiyun 				goto phy_blinking_end;
5039*4882a593Smuzhiyun 			break;
5040*4882a593Smuzhiyun 		}
5041*4882a593Smuzhiyun 	}
5042*4882a593Smuzhiyun 
5043*4882a593Smuzhiyun 	if (time > 0 && interval > 0) {
5044*4882a593Smuzhiyun 		for (i = 0; i < time * 1000; i += interval) {
5045*4882a593Smuzhiyun 			status = i40e_read_phy_register_clause45(hw,
5046*4882a593Smuzhiyun 						I40E_PHY_COM_REG_PAGE,
5047*4882a593Smuzhiyun 						led_addr, phy_addr, &led_reg);
5048*4882a593Smuzhiyun 			if (status)
5049*4882a593Smuzhiyun 				goto restore_config;
5050*4882a593Smuzhiyun 			if (led_reg & I40E_PHY_LED_MANUAL_ON)
5051*4882a593Smuzhiyun 				led_reg = 0;
5052*4882a593Smuzhiyun 			else
5053*4882a593Smuzhiyun 				led_reg = I40E_PHY_LED_MANUAL_ON;
5054*4882a593Smuzhiyun 			status = i40e_write_phy_register_clause45(hw,
5055*4882a593Smuzhiyun 						I40E_PHY_COM_REG_PAGE,
5056*4882a593Smuzhiyun 						led_addr, phy_addr, led_reg);
5057*4882a593Smuzhiyun 			if (status)
5058*4882a593Smuzhiyun 				goto restore_config;
5059*4882a593Smuzhiyun 			msleep(interval);
5060*4882a593Smuzhiyun 		}
5061*4882a593Smuzhiyun 	}
5062*4882a593Smuzhiyun 
5063*4882a593Smuzhiyun restore_config:
5064*4882a593Smuzhiyun 	status = i40e_write_phy_register_clause45(hw,
5065*4882a593Smuzhiyun 						  I40E_PHY_COM_REG_PAGE,
5066*4882a593Smuzhiyun 						  led_addr, phy_addr, led_ctl);
5067*4882a593Smuzhiyun 
5068*4882a593Smuzhiyun phy_blinking_end:
5069*4882a593Smuzhiyun 	return status;
5070*4882a593Smuzhiyun }
5071*4882a593Smuzhiyun 
5072*4882a593Smuzhiyun /**
5073*4882a593Smuzhiyun  * i40e_led_get_reg - read LED register
5074*4882a593Smuzhiyun  * @hw: pointer to the HW structure
5075*4882a593Smuzhiyun  * @led_addr: LED register address
5076*4882a593Smuzhiyun  * @reg_val: read register value
5077*4882a593Smuzhiyun  **/
i40e_led_get_reg(struct i40e_hw * hw,u16 led_addr,u32 * reg_val)5078*4882a593Smuzhiyun static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
5079*4882a593Smuzhiyun 					      u32 *reg_val)
5080*4882a593Smuzhiyun {
5081*4882a593Smuzhiyun 	enum i40e_status_code status;
5082*4882a593Smuzhiyun 	u8 phy_addr = 0;
5083*4882a593Smuzhiyun 	u8 port_num;
5084*4882a593Smuzhiyun 	u32 i;
5085*4882a593Smuzhiyun 
5086*4882a593Smuzhiyun 	*reg_val = 0;
5087*4882a593Smuzhiyun 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
5088*4882a593Smuzhiyun 		status =
5089*4882a593Smuzhiyun 		       i40e_aq_get_phy_register(hw,
5090*4882a593Smuzhiyun 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
5091*4882a593Smuzhiyun 						I40E_PHY_COM_REG_PAGE, true,
5092*4882a593Smuzhiyun 						I40E_PHY_LED_PROV_REG_1,
5093*4882a593Smuzhiyun 						reg_val, NULL);
5094*4882a593Smuzhiyun 	} else {
5095*4882a593Smuzhiyun 		i = rd32(hw, I40E_PFGEN_PORTNUM);
5096*4882a593Smuzhiyun 		port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
5097*4882a593Smuzhiyun 		phy_addr = i40e_get_phy_address(hw, port_num);
5098*4882a593Smuzhiyun 		status = i40e_read_phy_register_clause45(hw,
5099*4882a593Smuzhiyun 							 I40E_PHY_COM_REG_PAGE,
5100*4882a593Smuzhiyun 							 led_addr, phy_addr,
5101*4882a593Smuzhiyun 							 (u16 *)reg_val);
5102*4882a593Smuzhiyun 	}
5103*4882a593Smuzhiyun 	return status;
5104*4882a593Smuzhiyun }
5105*4882a593Smuzhiyun 
5106*4882a593Smuzhiyun /**
5107*4882a593Smuzhiyun  * i40e_led_set_reg - write LED register
5108*4882a593Smuzhiyun  * @hw: pointer to the HW structure
5109*4882a593Smuzhiyun  * @led_addr: LED register address
5110*4882a593Smuzhiyun  * @reg_val: register value to write
5111*4882a593Smuzhiyun  **/
i40e_led_set_reg(struct i40e_hw * hw,u16 led_addr,u32 reg_val)5112*4882a593Smuzhiyun static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
5113*4882a593Smuzhiyun 					      u32 reg_val)
5114*4882a593Smuzhiyun {
5115*4882a593Smuzhiyun 	enum i40e_status_code status;
5116*4882a593Smuzhiyun 	u8 phy_addr = 0;
5117*4882a593Smuzhiyun 	u8 port_num;
5118*4882a593Smuzhiyun 	u32 i;
5119*4882a593Smuzhiyun 
5120*4882a593Smuzhiyun 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
5121*4882a593Smuzhiyun 		status =
5122*4882a593Smuzhiyun 		       i40e_aq_set_phy_register(hw,
5123*4882a593Smuzhiyun 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
5124*4882a593Smuzhiyun 						I40E_PHY_COM_REG_PAGE, true,
5125*4882a593Smuzhiyun 						I40E_PHY_LED_PROV_REG_1,
5126*4882a593Smuzhiyun 						reg_val, NULL);
5127*4882a593Smuzhiyun 	} else {
5128*4882a593Smuzhiyun 		i = rd32(hw, I40E_PFGEN_PORTNUM);
5129*4882a593Smuzhiyun 		port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
5130*4882a593Smuzhiyun 		phy_addr = i40e_get_phy_address(hw, port_num);
5131*4882a593Smuzhiyun 		status = i40e_write_phy_register_clause45(hw,
5132*4882a593Smuzhiyun 							  I40E_PHY_COM_REG_PAGE,
5133*4882a593Smuzhiyun 							  led_addr, phy_addr,
5134*4882a593Smuzhiyun 							  (u16)reg_val);
5135*4882a593Smuzhiyun 	}
5136*4882a593Smuzhiyun 
5137*4882a593Smuzhiyun 	return status;
5138*4882a593Smuzhiyun }
5139*4882a593Smuzhiyun 
5140*4882a593Smuzhiyun /**
5141*4882a593Smuzhiyun  * i40e_led_get_phy - return current on/off mode
5142*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5143*4882a593Smuzhiyun  * @led_addr: address of led register to use
5144*4882a593Smuzhiyun  * @val: original value of register to use
5145*4882a593Smuzhiyun  *
5146*4882a593Smuzhiyun  **/
i40e_led_get_phy(struct i40e_hw * hw,u16 * led_addr,u16 * val)5147*4882a593Smuzhiyun i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
5148*4882a593Smuzhiyun 			     u16 *val)
5149*4882a593Smuzhiyun {
5150*4882a593Smuzhiyun 	i40e_status status = 0;
5151*4882a593Smuzhiyun 	u16 gpio_led_port;
5152*4882a593Smuzhiyun 	u8 phy_addr = 0;
5153*4882a593Smuzhiyun 	u16 reg_val;
5154*4882a593Smuzhiyun 	u16 temp_addr;
5155*4882a593Smuzhiyun 	u8 port_num;
5156*4882a593Smuzhiyun 	u32 i;
5157*4882a593Smuzhiyun 	u32 reg_val_aq;
5158*4882a593Smuzhiyun 
5159*4882a593Smuzhiyun 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
5160*4882a593Smuzhiyun 		status =
5161*4882a593Smuzhiyun 		      i40e_aq_get_phy_register(hw,
5162*4882a593Smuzhiyun 					       I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
5163*4882a593Smuzhiyun 					       I40E_PHY_COM_REG_PAGE, true,
5164*4882a593Smuzhiyun 					       I40E_PHY_LED_PROV_REG_1,
5165*4882a593Smuzhiyun 					       &reg_val_aq, NULL);
5166*4882a593Smuzhiyun 		if (status == I40E_SUCCESS)
5167*4882a593Smuzhiyun 			*val = (u16)reg_val_aq;
5168*4882a593Smuzhiyun 		return status;
5169*4882a593Smuzhiyun 	}
5170*4882a593Smuzhiyun 	temp_addr = I40E_PHY_LED_PROV_REG_1;
5171*4882a593Smuzhiyun 	i = rd32(hw, I40E_PFGEN_PORTNUM);
5172*4882a593Smuzhiyun 	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
5173*4882a593Smuzhiyun 	phy_addr = i40e_get_phy_address(hw, port_num);
5174*4882a593Smuzhiyun 
5175*4882a593Smuzhiyun 	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
5176*4882a593Smuzhiyun 	     temp_addr++) {
5177*4882a593Smuzhiyun 		status = i40e_read_phy_register_clause45(hw,
5178*4882a593Smuzhiyun 							 I40E_PHY_COM_REG_PAGE,
5179*4882a593Smuzhiyun 							 temp_addr, phy_addr,
5180*4882a593Smuzhiyun 							 &reg_val);
5181*4882a593Smuzhiyun 		if (status)
5182*4882a593Smuzhiyun 			return status;
5183*4882a593Smuzhiyun 		*val = reg_val;
5184*4882a593Smuzhiyun 		if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
5185*4882a593Smuzhiyun 			*led_addr = temp_addr;
5186*4882a593Smuzhiyun 			break;
5187*4882a593Smuzhiyun 		}
5188*4882a593Smuzhiyun 	}
5189*4882a593Smuzhiyun 	return status;
5190*4882a593Smuzhiyun }
5191*4882a593Smuzhiyun 
5192*4882a593Smuzhiyun /**
5193*4882a593Smuzhiyun  * i40e_led_set_phy
5194*4882a593Smuzhiyun  * @hw: pointer to the HW structure
5195*4882a593Smuzhiyun  * @on: true or false
5196*4882a593Smuzhiyun  * @led_addr: address of led register to use
5197*4882a593Smuzhiyun  * @mode: original val plus bit for set or ignore
5198*4882a593Smuzhiyun  *
5199*4882a593Smuzhiyun  * Set led's on or off when controlled by the PHY
5200*4882a593Smuzhiyun  *
5201*4882a593Smuzhiyun  **/
i40e_led_set_phy(struct i40e_hw * hw,bool on,u16 led_addr,u32 mode)5202*4882a593Smuzhiyun i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
5203*4882a593Smuzhiyun 			     u16 led_addr, u32 mode)
5204*4882a593Smuzhiyun {
5205*4882a593Smuzhiyun 	i40e_status status = 0;
5206*4882a593Smuzhiyun 	u32 led_ctl = 0;
5207*4882a593Smuzhiyun 	u32 led_reg = 0;
5208*4882a593Smuzhiyun 
5209*4882a593Smuzhiyun 	status = i40e_led_get_reg(hw, led_addr, &led_reg);
5210*4882a593Smuzhiyun 	if (status)
5211*4882a593Smuzhiyun 		return status;
5212*4882a593Smuzhiyun 	led_ctl = led_reg;
5213*4882a593Smuzhiyun 	if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
5214*4882a593Smuzhiyun 		led_reg = 0;
5215*4882a593Smuzhiyun 		status = i40e_led_set_reg(hw, led_addr, led_reg);
5216*4882a593Smuzhiyun 		if (status)
5217*4882a593Smuzhiyun 			return status;
5218*4882a593Smuzhiyun 	}
5219*4882a593Smuzhiyun 	status = i40e_led_get_reg(hw, led_addr, &led_reg);
5220*4882a593Smuzhiyun 	if (status)
5221*4882a593Smuzhiyun 		goto restore_config;
5222*4882a593Smuzhiyun 	if (on)
5223*4882a593Smuzhiyun 		led_reg = I40E_PHY_LED_MANUAL_ON;
5224*4882a593Smuzhiyun 	else
5225*4882a593Smuzhiyun 		led_reg = 0;
5226*4882a593Smuzhiyun 
5227*4882a593Smuzhiyun 	status = i40e_led_set_reg(hw, led_addr, led_reg);
5228*4882a593Smuzhiyun 	if (status)
5229*4882a593Smuzhiyun 		goto restore_config;
5230*4882a593Smuzhiyun 	if (mode & I40E_PHY_LED_MODE_ORIG) {
5231*4882a593Smuzhiyun 		led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
5232*4882a593Smuzhiyun 		status = i40e_led_set_reg(hw, led_addr, led_ctl);
5233*4882a593Smuzhiyun 	}
5234*4882a593Smuzhiyun 	return status;
5235*4882a593Smuzhiyun 
5236*4882a593Smuzhiyun restore_config:
5237*4882a593Smuzhiyun 	status = i40e_led_set_reg(hw, led_addr, led_ctl);
5238*4882a593Smuzhiyun 	return status;
5239*4882a593Smuzhiyun }
5240*4882a593Smuzhiyun 
5241*4882a593Smuzhiyun /**
5242*4882a593Smuzhiyun  * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
5243*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5244*4882a593Smuzhiyun  * @reg_addr: register address
5245*4882a593Smuzhiyun  * @reg_val: ptr to register value
5246*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
5247*4882a593Smuzhiyun  *
5248*4882a593Smuzhiyun  * Use the firmware to read the Rx control register,
5249*4882a593Smuzhiyun  * especially useful if the Rx unit is under heavy pressure
5250*4882a593Smuzhiyun  **/
i40e_aq_rx_ctl_read_register(struct i40e_hw * hw,u32 reg_addr,u32 * reg_val,struct i40e_asq_cmd_details * cmd_details)5251*4882a593Smuzhiyun i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
5252*4882a593Smuzhiyun 				u32 reg_addr, u32 *reg_val,
5253*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
5254*4882a593Smuzhiyun {
5255*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5256*4882a593Smuzhiyun 	struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
5257*4882a593Smuzhiyun 		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
5258*4882a593Smuzhiyun 	i40e_status status;
5259*4882a593Smuzhiyun 
5260*4882a593Smuzhiyun 	if (!reg_val)
5261*4882a593Smuzhiyun 		return I40E_ERR_PARAM;
5262*4882a593Smuzhiyun 
5263*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
5264*4882a593Smuzhiyun 
5265*4882a593Smuzhiyun 	cmd_resp->address = cpu_to_le32(reg_addr);
5266*4882a593Smuzhiyun 
5267*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5268*4882a593Smuzhiyun 
5269*4882a593Smuzhiyun 	if (status == 0)
5270*4882a593Smuzhiyun 		*reg_val = le32_to_cpu(cmd_resp->value);
5271*4882a593Smuzhiyun 
5272*4882a593Smuzhiyun 	return status;
5273*4882a593Smuzhiyun }
5274*4882a593Smuzhiyun 
5275*4882a593Smuzhiyun /**
5276*4882a593Smuzhiyun  * i40e_read_rx_ctl - read from an Rx control register
5277*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5278*4882a593Smuzhiyun  * @reg_addr: register address
5279*4882a593Smuzhiyun  **/
i40e_read_rx_ctl(struct i40e_hw * hw,u32 reg_addr)5280*4882a593Smuzhiyun u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
5281*4882a593Smuzhiyun {
5282*4882a593Smuzhiyun 	i40e_status status = 0;
5283*4882a593Smuzhiyun 	bool use_register;
5284*4882a593Smuzhiyun 	int retry = 5;
5285*4882a593Smuzhiyun 	u32 val = 0;
5286*4882a593Smuzhiyun 
5287*4882a593Smuzhiyun 	use_register = (((hw->aq.api_maj_ver == 1) &&
5288*4882a593Smuzhiyun 			(hw->aq.api_min_ver < 5)) ||
5289*4882a593Smuzhiyun 			(hw->mac.type == I40E_MAC_X722));
5290*4882a593Smuzhiyun 	if (!use_register) {
5291*4882a593Smuzhiyun do_retry:
5292*4882a593Smuzhiyun 		status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
5293*4882a593Smuzhiyun 		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
5294*4882a593Smuzhiyun 			usleep_range(1000, 2000);
5295*4882a593Smuzhiyun 			retry--;
5296*4882a593Smuzhiyun 			goto do_retry;
5297*4882a593Smuzhiyun 		}
5298*4882a593Smuzhiyun 	}
5299*4882a593Smuzhiyun 
5300*4882a593Smuzhiyun 	/* if the AQ access failed, try the old-fashioned way */
5301*4882a593Smuzhiyun 	if (status || use_register)
5302*4882a593Smuzhiyun 		val = rd32(hw, reg_addr);
5303*4882a593Smuzhiyun 
5304*4882a593Smuzhiyun 	return val;
5305*4882a593Smuzhiyun }
5306*4882a593Smuzhiyun 
5307*4882a593Smuzhiyun /**
5308*4882a593Smuzhiyun  * i40e_aq_rx_ctl_write_register
5309*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5310*4882a593Smuzhiyun  * @reg_addr: register address
5311*4882a593Smuzhiyun  * @reg_val: register value
5312*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
5313*4882a593Smuzhiyun  *
5314*4882a593Smuzhiyun  * Use the firmware to write to an Rx control register,
5315*4882a593Smuzhiyun  * especially useful if the Rx unit is under heavy pressure
5316*4882a593Smuzhiyun  **/
i40e_aq_rx_ctl_write_register(struct i40e_hw * hw,u32 reg_addr,u32 reg_val,struct i40e_asq_cmd_details * cmd_details)5317*4882a593Smuzhiyun i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
5318*4882a593Smuzhiyun 				u32 reg_addr, u32 reg_val,
5319*4882a593Smuzhiyun 				struct i40e_asq_cmd_details *cmd_details)
5320*4882a593Smuzhiyun {
5321*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5322*4882a593Smuzhiyun 	struct i40e_aqc_rx_ctl_reg_read_write *cmd =
5323*4882a593Smuzhiyun 		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
5324*4882a593Smuzhiyun 	i40e_status status;
5325*4882a593Smuzhiyun 
5326*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
5327*4882a593Smuzhiyun 
5328*4882a593Smuzhiyun 	cmd->address = cpu_to_le32(reg_addr);
5329*4882a593Smuzhiyun 	cmd->value = cpu_to_le32(reg_val);
5330*4882a593Smuzhiyun 
5331*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5332*4882a593Smuzhiyun 
5333*4882a593Smuzhiyun 	return status;
5334*4882a593Smuzhiyun }
5335*4882a593Smuzhiyun 
5336*4882a593Smuzhiyun /**
5337*4882a593Smuzhiyun  * i40e_write_rx_ctl - write to an Rx control register
5338*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5339*4882a593Smuzhiyun  * @reg_addr: register address
5340*4882a593Smuzhiyun  * @reg_val: register value
5341*4882a593Smuzhiyun  **/
i40e_write_rx_ctl(struct i40e_hw * hw,u32 reg_addr,u32 reg_val)5342*4882a593Smuzhiyun void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
5343*4882a593Smuzhiyun {
5344*4882a593Smuzhiyun 	i40e_status status = 0;
5345*4882a593Smuzhiyun 	bool use_register;
5346*4882a593Smuzhiyun 	int retry = 5;
5347*4882a593Smuzhiyun 
5348*4882a593Smuzhiyun 	use_register = (((hw->aq.api_maj_ver == 1) &&
5349*4882a593Smuzhiyun 			(hw->aq.api_min_ver < 5)) ||
5350*4882a593Smuzhiyun 			(hw->mac.type == I40E_MAC_X722));
5351*4882a593Smuzhiyun 	if (!use_register) {
5352*4882a593Smuzhiyun do_retry:
5353*4882a593Smuzhiyun 		status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
5354*4882a593Smuzhiyun 						       reg_val, NULL);
5355*4882a593Smuzhiyun 		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
5356*4882a593Smuzhiyun 			usleep_range(1000, 2000);
5357*4882a593Smuzhiyun 			retry--;
5358*4882a593Smuzhiyun 			goto do_retry;
5359*4882a593Smuzhiyun 		}
5360*4882a593Smuzhiyun 	}
5361*4882a593Smuzhiyun 
5362*4882a593Smuzhiyun 	/* if the AQ access failed, try the old-fashioned way */
5363*4882a593Smuzhiyun 	if (status || use_register)
5364*4882a593Smuzhiyun 		wr32(hw, reg_addr, reg_val);
5365*4882a593Smuzhiyun }
5366*4882a593Smuzhiyun 
5367*4882a593Smuzhiyun /**
5368*4882a593Smuzhiyun  * i40e_mdio_if_number_selection - MDIO I/F number selection
5369*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5370*4882a593Smuzhiyun  * @set_mdio: use MDIO I/F number specified by mdio_num
5371*4882a593Smuzhiyun  * @mdio_num: MDIO I/F number
5372*4882a593Smuzhiyun  * @cmd: pointer to PHY Register command structure
5373*4882a593Smuzhiyun  **/
i40e_mdio_if_number_selection(struct i40e_hw * hw,bool set_mdio,u8 mdio_num,struct i40e_aqc_phy_register_access * cmd)5374*4882a593Smuzhiyun static void i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio,
5375*4882a593Smuzhiyun 					  u8 mdio_num,
5376*4882a593Smuzhiyun 					  struct i40e_aqc_phy_register_access *cmd)
5377*4882a593Smuzhiyun {
5378*4882a593Smuzhiyun 	if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) {
5379*4882a593Smuzhiyun 		if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED)
5380*4882a593Smuzhiyun 			cmd->cmd_flags |=
5381*4882a593Smuzhiyun 				I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER |
5382*4882a593Smuzhiyun 				((mdio_num <<
5383*4882a593Smuzhiyun 				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) &
5384*4882a593Smuzhiyun 				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK);
5385*4882a593Smuzhiyun 		else
5386*4882a593Smuzhiyun 			i40e_debug(hw, I40E_DEBUG_PHY,
5387*4882a593Smuzhiyun 				   "MDIO I/F number selection not supported by current FW version.\n");
5388*4882a593Smuzhiyun 	}
5389*4882a593Smuzhiyun }
5390*4882a593Smuzhiyun 
5391*4882a593Smuzhiyun /**
5392*4882a593Smuzhiyun  * i40e_aq_set_phy_register_ext
5393*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5394*4882a593Smuzhiyun  * @phy_select: select which phy should be accessed
5395*4882a593Smuzhiyun  * @dev_addr: PHY device address
5396*4882a593Smuzhiyun  * @page_change: flag to indicate if phy page should be updated
5397*4882a593Smuzhiyun  * @set_mdio: use MDIO I/F number specified by mdio_num
5398*4882a593Smuzhiyun  * @mdio_num: MDIO I/F number
5399*4882a593Smuzhiyun  * @reg_addr: PHY register address
5400*4882a593Smuzhiyun  * @reg_val: new register value
5401*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
5402*4882a593Smuzhiyun  *
5403*4882a593Smuzhiyun  * Write the external PHY register.
5404*4882a593Smuzhiyun  * NOTE: In common cases MDIO I/F number should not be changed, thats why you
5405*4882a593Smuzhiyun  * may use simple wrapper i40e_aq_set_phy_register.
5406*4882a593Smuzhiyun  **/
i40e_aq_set_phy_register_ext(struct i40e_hw * hw,u8 phy_select,u8 dev_addr,bool page_change,bool set_mdio,u8 mdio_num,u32 reg_addr,u32 reg_val,struct i40e_asq_cmd_details * cmd_details)5407*4882a593Smuzhiyun enum i40e_status_code i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
5408*4882a593Smuzhiyun 			     u8 phy_select, u8 dev_addr, bool page_change,
5409*4882a593Smuzhiyun 			     bool set_mdio, u8 mdio_num,
5410*4882a593Smuzhiyun 			     u32 reg_addr, u32 reg_val,
5411*4882a593Smuzhiyun 			     struct i40e_asq_cmd_details *cmd_details)
5412*4882a593Smuzhiyun {
5413*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5414*4882a593Smuzhiyun 	struct i40e_aqc_phy_register_access *cmd =
5415*4882a593Smuzhiyun 		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
5416*4882a593Smuzhiyun 	i40e_status status;
5417*4882a593Smuzhiyun 
5418*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
5419*4882a593Smuzhiyun 					  i40e_aqc_opc_set_phy_register);
5420*4882a593Smuzhiyun 
5421*4882a593Smuzhiyun 	cmd->phy_interface = phy_select;
5422*4882a593Smuzhiyun 	cmd->dev_address = dev_addr;
5423*4882a593Smuzhiyun 	cmd->reg_address = cpu_to_le32(reg_addr);
5424*4882a593Smuzhiyun 	cmd->reg_value = cpu_to_le32(reg_val);
5425*4882a593Smuzhiyun 
5426*4882a593Smuzhiyun 	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
5427*4882a593Smuzhiyun 
5428*4882a593Smuzhiyun 	if (!page_change)
5429*4882a593Smuzhiyun 		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
5430*4882a593Smuzhiyun 
5431*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5432*4882a593Smuzhiyun 
5433*4882a593Smuzhiyun 	return status;
5434*4882a593Smuzhiyun }
5435*4882a593Smuzhiyun 
5436*4882a593Smuzhiyun /**
5437*4882a593Smuzhiyun  * i40e_aq_get_phy_register_ext
5438*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5439*4882a593Smuzhiyun  * @phy_select: select which phy should be accessed
5440*4882a593Smuzhiyun  * @dev_addr: PHY device address
5441*4882a593Smuzhiyun  * @page_change: flag to indicate if phy page should be updated
5442*4882a593Smuzhiyun  * @set_mdio: use MDIO I/F number specified by mdio_num
5443*4882a593Smuzhiyun  * @mdio_num: MDIO I/F number
5444*4882a593Smuzhiyun  * @reg_addr: PHY register address
5445*4882a593Smuzhiyun  * @reg_val: read register value
5446*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
5447*4882a593Smuzhiyun  *
5448*4882a593Smuzhiyun  * Read the external PHY register.
5449*4882a593Smuzhiyun  * NOTE: In common cases MDIO I/F number should not be changed, thats why you
5450*4882a593Smuzhiyun  * may use simple wrapper i40e_aq_get_phy_register.
5451*4882a593Smuzhiyun  **/
i40e_aq_get_phy_register_ext(struct i40e_hw * hw,u8 phy_select,u8 dev_addr,bool page_change,bool set_mdio,u8 mdio_num,u32 reg_addr,u32 * reg_val,struct i40e_asq_cmd_details * cmd_details)5452*4882a593Smuzhiyun enum i40e_status_code i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
5453*4882a593Smuzhiyun 			     u8 phy_select, u8 dev_addr, bool page_change,
5454*4882a593Smuzhiyun 			     bool set_mdio, u8 mdio_num,
5455*4882a593Smuzhiyun 			     u32 reg_addr, u32 *reg_val,
5456*4882a593Smuzhiyun 			     struct i40e_asq_cmd_details *cmd_details)
5457*4882a593Smuzhiyun {
5458*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5459*4882a593Smuzhiyun 	struct i40e_aqc_phy_register_access *cmd =
5460*4882a593Smuzhiyun 		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
5461*4882a593Smuzhiyun 	i40e_status status;
5462*4882a593Smuzhiyun 
5463*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
5464*4882a593Smuzhiyun 					  i40e_aqc_opc_get_phy_register);
5465*4882a593Smuzhiyun 
5466*4882a593Smuzhiyun 	cmd->phy_interface = phy_select;
5467*4882a593Smuzhiyun 	cmd->dev_address = dev_addr;
5468*4882a593Smuzhiyun 	cmd->reg_address = cpu_to_le32(reg_addr);
5469*4882a593Smuzhiyun 
5470*4882a593Smuzhiyun 	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
5471*4882a593Smuzhiyun 
5472*4882a593Smuzhiyun 	if (!page_change)
5473*4882a593Smuzhiyun 		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
5474*4882a593Smuzhiyun 
5475*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5476*4882a593Smuzhiyun 	if (!status)
5477*4882a593Smuzhiyun 		*reg_val = le32_to_cpu(cmd->reg_value);
5478*4882a593Smuzhiyun 
5479*4882a593Smuzhiyun 	return status;
5480*4882a593Smuzhiyun }
5481*4882a593Smuzhiyun 
5482*4882a593Smuzhiyun /**
5483*4882a593Smuzhiyun  * i40e_aq_write_ddp - Write dynamic device personalization (ddp)
5484*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5485*4882a593Smuzhiyun  * @buff: command buffer (size in bytes = buff_size)
5486*4882a593Smuzhiyun  * @buff_size: buffer size in bytes
5487*4882a593Smuzhiyun  * @track_id: package tracking id
5488*4882a593Smuzhiyun  * @error_offset: returns error offset
5489*4882a593Smuzhiyun  * @error_info: returns error information
5490*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
5491*4882a593Smuzhiyun  **/
5492*4882a593Smuzhiyun enum
i40e_aq_write_ddp(struct i40e_hw * hw,void * buff,u16 buff_size,u32 track_id,u32 * error_offset,u32 * error_info,struct i40e_asq_cmd_details * cmd_details)5493*4882a593Smuzhiyun i40e_status_code i40e_aq_write_ddp(struct i40e_hw *hw, void *buff,
5494*4882a593Smuzhiyun 				   u16 buff_size, u32 track_id,
5495*4882a593Smuzhiyun 				   u32 *error_offset, u32 *error_info,
5496*4882a593Smuzhiyun 				   struct i40e_asq_cmd_details *cmd_details)
5497*4882a593Smuzhiyun {
5498*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5499*4882a593Smuzhiyun 	struct i40e_aqc_write_personalization_profile *cmd =
5500*4882a593Smuzhiyun 		(struct i40e_aqc_write_personalization_profile *)
5501*4882a593Smuzhiyun 		&desc.params.raw;
5502*4882a593Smuzhiyun 	struct i40e_aqc_write_ddp_resp *resp;
5503*4882a593Smuzhiyun 	i40e_status status;
5504*4882a593Smuzhiyun 
5505*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
5506*4882a593Smuzhiyun 					  i40e_aqc_opc_write_personalization_profile);
5507*4882a593Smuzhiyun 
5508*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
5509*4882a593Smuzhiyun 	if (buff_size > I40E_AQ_LARGE_BUF)
5510*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
5511*4882a593Smuzhiyun 
5512*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_size);
5513*4882a593Smuzhiyun 
5514*4882a593Smuzhiyun 	cmd->profile_track_id = cpu_to_le32(track_id);
5515*4882a593Smuzhiyun 
5516*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5517*4882a593Smuzhiyun 	if (!status) {
5518*4882a593Smuzhiyun 		resp = (struct i40e_aqc_write_ddp_resp *)&desc.params.raw;
5519*4882a593Smuzhiyun 		if (error_offset)
5520*4882a593Smuzhiyun 			*error_offset = le32_to_cpu(resp->error_offset);
5521*4882a593Smuzhiyun 		if (error_info)
5522*4882a593Smuzhiyun 			*error_info = le32_to_cpu(resp->error_info);
5523*4882a593Smuzhiyun 	}
5524*4882a593Smuzhiyun 
5525*4882a593Smuzhiyun 	return status;
5526*4882a593Smuzhiyun }
5527*4882a593Smuzhiyun 
5528*4882a593Smuzhiyun /**
5529*4882a593Smuzhiyun  * i40e_aq_get_ddp_list - Read dynamic device personalization (ddp)
5530*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5531*4882a593Smuzhiyun  * @buff: command buffer (size in bytes = buff_size)
5532*4882a593Smuzhiyun  * @buff_size: buffer size in bytes
5533*4882a593Smuzhiyun  * @flags: AdminQ command flags
5534*4882a593Smuzhiyun  * @cmd_details: pointer to command details structure or NULL
5535*4882a593Smuzhiyun  **/
5536*4882a593Smuzhiyun enum
i40e_aq_get_ddp_list(struct i40e_hw * hw,void * buff,u16 buff_size,u8 flags,struct i40e_asq_cmd_details * cmd_details)5537*4882a593Smuzhiyun i40e_status_code i40e_aq_get_ddp_list(struct i40e_hw *hw, void *buff,
5538*4882a593Smuzhiyun 				      u16 buff_size, u8 flags,
5539*4882a593Smuzhiyun 				      struct i40e_asq_cmd_details *cmd_details)
5540*4882a593Smuzhiyun {
5541*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5542*4882a593Smuzhiyun 	struct i40e_aqc_get_applied_profiles *cmd =
5543*4882a593Smuzhiyun 		(struct i40e_aqc_get_applied_profiles *)&desc.params.raw;
5544*4882a593Smuzhiyun 	i40e_status status;
5545*4882a593Smuzhiyun 
5546*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
5547*4882a593Smuzhiyun 					  i40e_aqc_opc_get_personalization_profile_list);
5548*4882a593Smuzhiyun 
5549*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
5550*4882a593Smuzhiyun 	if (buff_size > I40E_AQ_LARGE_BUF)
5551*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
5552*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_size);
5553*4882a593Smuzhiyun 
5554*4882a593Smuzhiyun 	cmd->flags = flags;
5555*4882a593Smuzhiyun 
5556*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5557*4882a593Smuzhiyun 
5558*4882a593Smuzhiyun 	return status;
5559*4882a593Smuzhiyun }
5560*4882a593Smuzhiyun 
5561*4882a593Smuzhiyun /**
5562*4882a593Smuzhiyun  * i40e_find_segment_in_package
5563*4882a593Smuzhiyun  * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
5564*4882a593Smuzhiyun  * @pkg_hdr: pointer to the package header to be searched
5565*4882a593Smuzhiyun  *
5566*4882a593Smuzhiyun  * This function searches a package file for a particular segment type. On
5567*4882a593Smuzhiyun  * success it returns a pointer to the segment header, otherwise it will
5568*4882a593Smuzhiyun  * return NULL.
5569*4882a593Smuzhiyun  **/
5570*4882a593Smuzhiyun struct i40e_generic_seg_header *
i40e_find_segment_in_package(u32 segment_type,struct i40e_package_header * pkg_hdr)5571*4882a593Smuzhiyun i40e_find_segment_in_package(u32 segment_type,
5572*4882a593Smuzhiyun 			     struct i40e_package_header *pkg_hdr)
5573*4882a593Smuzhiyun {
5574*4882a593Smuzhiyun 	struct i40e_generic_seg_header *segment;
5575*4882a593Smuzhiyun 	u32 i;
5576*4882a593Smuzhiyun 
5577*4882a593Smuzhiyun 	/* Search all package segments for the requested segment type */
5578*4882a593Smuzhiyun 	for (i = 0; i < pkg_hdr->segment_count; i++) {
5579*4882a593Smuzhiyun 		segment =
5580*4882a593Smuzhiyun 			(struct i40e_generic_seg_header *)((u8 *)pkg_hdr +
5581*4882a593Smuzhiyun 			 pkg_hdr->segment_offset[i]);
5582*4882a593Smuzhiyun 
5583*4882a593Smuzhiyun 		if (segment->type == segment_type)
5584*4882a593Smuzhiyun 			return segment;
5585*4882a593Smuzhiyun 	}
5586*4882a593Smuzhiyun 
5587*4882a593Smuzhiyun 	return NULL;
5588*4882a593Smuzhiyun }
5589*4882a593Smuzhiyun 
5590*4882a593Smuzhiyun /* Get section table in profile */
5591*4882a593Smuzhiyun #define I40E_SECTION_TABLE(profile, sec_tbl)				\
5592*4882a593Smuzhiyun 	do {								\
5593*4882a593Smuzhiyun 		struct i40e_profile_segment *p = (profile);		\
5594*4882a593Smuzhiyun 		u32 count;						\
5595*4882a593Smuzhiyun 		u32 *nvm;						\
5596*4882a593Smuzhiyun 		count = p->device_table_count;				\
5597*4882a593Smuzhiyun 		nvm = (u32 *)&p->device_table[count];			\
5598*4882a593Smuzhiyun 		sec_tbl = (struct i40e_section_table *)&nvm[nvm[0] + 1]; \
5599*4882a593Smuzhiyun 	} while (0)
5600*4882a593Smuzhiyun 
5601*4882a593Smuzhiyun /* Get section header in profile */
5602*4882a593Smuzhiyun #define I40E_SECTION_HEADER(profile, offset)				\
5603*4882a593Smuzhiyun 	(struct i40e_profile_section_header *)((u8 *)(profile) + (offset))
5604*4882a593Smuzhiyun 
5605*4882a593Smuzhiyun /**
5606*4882a593Smuzhiyun  * i40e_find_section_in_profile
5607*4882a593Smuzhiyun  * @section_type: the section type to search for (i.e., SECTION_TYPE_NOTE)
5608*4882a593Smuzhiyun  * @profile: pointer to the i40e segment header to be searched
5609*4882a593Smuzhiyun  *
5610*4882a593Smuzhiyun  * This function searches i40e segment for a particular section type. On
5611*4882a593Smuzhiyun  * success it returns a pointer to the section header, otherwise it will
5612*4882a593Smuzhiyun  * return NULL.
5613*4882a593Smuzhiyun  **/
5614*4882a593Smuzhiyun struct i40e_profile_section_header *
i40e_find_section_in_profile(u32 section_type,struct i40e_profile_segment * profile)5615*4882a593Smuzhiyun i40e_find_section_in_profile(u32 section_type,
5616*4882a593Smuzhiyun 			     struct i40e_profile_segment *profile)
5617*4882a593Smuzhiyun {
5618*4882a593Smuzhiyun 	struct i40e_profile_section_header *sec;
5619*4882a593Smuzhiyun 	struct i40e_section_table *sec_tbl;
5620*4882a593Smuzhiyun 	u32 sec_off;
5621*4882a593Smuzhiyun 	u32 i;
5622*4882a593Smuzhiyun 
5623*4882a593Smuzhiyun 	if (profile->header.type != SEGMENT_TYPE_I40E)
5624*4882a593Smuzhiyun 		return NULL;
5625*4882a593Smuzhiyun 
5626*4882a593Smuzhiyun 	I40E_SECTION_TABLE(profile, sec_tbl);
5627*4882a593Smuzhiyun 
5628*4882a593Smuzhiyun 	for (i = 0; i < sec_tbl->section_count; i++) {
5629*4882a593Smuzhiyun 		sec_off = sec_tbl->section_offset[i];
5630*4882a593Smuzhiyun 		sec = I40E_SECTION_HEADER(profile, sec_off);
5631*4882a593Smuzhiyun 		if (sec->section.type == section_type)
5632*4882a593Smuzhiyun 			return sec;
5633*4882a593Smuzhiyun 	}
5634*4882a593Smuzhiyun 
5635*4882a593Smuzhiyun 	return NULL;
5636*4882a593Smuzhiyun }
5637*4882a593Smuzhiyun 
5638*4882a593Smuzhiyun /**
5639*4882a593Smuzhiyun  * i40e_ddp_exec_aq_section - Execute generic AQ for DDP
5640*4882a593Smuzhiyun  * @hw: pointer to the hw struct
5641*4882a593Smuzhiyun  * @aq: command buffer containing all data to execute AQ
5642*4882a593Smuzhiyun  **/
5643*4882a593Smuzhiyun static enum
i40e_ddp_exec_aq_section(struct i40e_hw * hw,struct i40e_profile_aq_section * aq)5644*4882a593Smuzhiyun i40e_status_code i40e_ddp_exec_aq_section(struct i40e_hw *hw,
5645*4882a593Smuzhiyun 					  struct i40e_profile_aq_section *aq)
5646*4882a593Smuzhiyun {
5647*4882a593Smuzhiyun 	i40e_status status;
5648*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5649*4882a593Smuzhiyun 	u8 *msg = NULL;
5650*4882a593Smuzhiyun 	u16 msglen;
5651*4882a593Smuzhiyun 
5652*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc, aq->opcode);
5653*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16(aq->flags);
5654*4882a593Smuzhiyun 	memcpy(desc.params.raw, aq->param, sizeof(desc.params.raw));
5655*4882a593Smuzhiyun 
5656*4882a593Smuzhiyun 	msglen = aq->datalen;
5657*4882a593Smuzhiyun 	if (msglen) {
5658*4882a593Smuzhiyun 		desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF |
5659*4882a593Smuzhiyun 						I40E_AQ_FLAG_RD));
5660*4882a593Smuzhiyun 		if (msglen > I40E_AQ_LARGE_BUF)
5661*4882a593Smuzhiyun 			desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
5662*4882a593Smuzhiyun 		desc.datalen = cpu_to_le16(msglen);
5663*4882a593Smuzhiyun 		msg = &aq->data[0];
5664*4882a593Smuzhiyun 	}
5665*4882a593Smuzhiyun 
5666*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, msg, msglen, NULL);
5667*4882a593Smuzhiyun 
5668*4882a593Smuzhiyun 	if (status) {
5669*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_PACKAGE,
5670*4882a593Smuzhiyun 			   "unable to exec DDP AQ opcode %u, error %d\n",
5671*4882a593Smuzhiyun 			   aq->opcode, status);
5672*4882a593Smuzhiyun 		return status;
5673*4882a593Smuzhiyun 	}
5674*4882a593Smuzhiyun 
5675*4882a593Smuzhiyun 	/* copy returned desc to aq_buf */
5676*4882a593Smuzhiyun 	memcpy(aq->param, desc.params.raw, sizeof(desc.params.raw));
5677*4882a593Smuzhiyun 
5678*4882a593Smuzhiyun 	return 0;
5679*4882a593Smuzhiyun }
5680*4882a593Smuzhiyun 
5681*4882a593Smuzhiyun /**
5682*4882a593Smuzhiyun  * i40e_validate_profile
5683*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
5684*4882a593Smuzhiyun  * @profile: pointer to the profile segment of the package to be validated
5685*4882a593Smuzhiyun  * @track_id: package tracking id
5686*4882a593Smuzhiyun  * @rollback: flag if the profile is for rollback.
5687*4882a593Smuzhiyun  *
5688*4882a593Smuzhiyun  * Validates supported devices and profile's sections.
5689*4882a593Smuzhiyun  */
5690*4882a593Smuzhiyun static enum i40e_status_code
i40e_validate_profile(struct i40e_hw * hw,struct i40e_profile_segment * profile,u32 track_id,bool rollback)5691*4882a593Smuzhiyun i40e_validate_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
5692*4882a593Smuzhiyun 		      u32 track_id, bool rollback)
5693*4882a593Smuzhiyun {
5694*4882a593Smuzhiyun 	struct i40e_profile_section_header *sec = NULL;
5695*4882a593Smuzhiyun 	i40e_status status = 0;
5696*4882a593Smuzhiyun 	struct i40e_section_table *sec_tbl;
5697*4882a593Smuzhiyun 	u32 vendor_dev_id;
5698*4882a593Smuzhiyun 	u32 dev_cnt;
5699*4882a593Smuzhiyun 	u32 sec_off;
5700*4882a593Smuzhiyun 	u32 i;
5701*4882a593Smuzhiyun 
5702*4882a593Smuzhiyun 	if (track_id == I40E_DDP_TRACKID_INVALID) {
5703*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_PACKAGE, "Invalid track_id\n");
5704*4882a593Smuzhiyun 		return I40E_NOT_SUPPORTED;
5705*4882a593Smuzhiyun 	}
5706*4882a593Smuzhiyun 
5707*4882a593Smuzhiyun 	dev_cnt = profile->device_table_count;
5708*4882a593Smuzhiyun 	for (i = 0; i < dev_cnt; i++) {
5709*4882a593Smuzhiyun 		vendor_dev_id = profile->device_table[i].vendor_dev_id;
5710*4882a593Smuzhiyun 		if ((vendor_dev_id >> 16) == PCI_VENDOR_ID_INTEL &&
5711*4882a593Smuzhiyun 		    hw->device_id == (vendor_dev_id & 0xFFFF))
5712*4882a593Smuzhiyun 			break;
5713*4882a593Smuzhiyun 	}
5714*4882a593Smuzhiyun 	if (dev_cnt && i == dev_cnt) {
5715*4882a593Smuzhiyun 		i40e_debug(hw, I40E_DEBUG_PACKAGE,
5716*4882a593Smuzhiyun 			   "Device doesn't support DDP\n");
5717*4882a593Smuzhiyun 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
5718*4882a593Smuzhiyun 	}
5719*4882a593Smuzhiyun 
5720*4882a593Smuzhiyun 	I40E_SECTION_TABLE(profile, sec_tbl);
5721*4882a593Smuzhiyun 
5722*4882a593Smuzhiyun 	/* Validate sections types */
5723*4882a593Smuzhiyun 	for (i = 0; i < sec_tbl->section_count; i++) {
5724*4882a593Smuzhiyun 		sec_off = sec_tbl->section_offset[i];
5725*4882a593Smuzhiyun 		sec = I40E_SECTION_HEADER(profile, sec_off);
5726*4882a593Smuzhiyun 		if (rollback) {
5727*4882a593Smuzhiyun 			if (sec->section.type == SECTION_TYPE_MMIO ||
5728*4882a593Smuzhiyun 			    sec->section.type == SECTION_TYPE_AQ ||
5729*4882a593Smuzhiyun 			    sec->section.type == SECTION_TYPE_RB_AQ) {
5730*4882a593Smuzhiyun 				i40e_debug(hw, I40E_DEBUG_PACKAGE,
5731*4882a593Smuzhiyun 					   "Not a roll-back package\n");
5732*4882a593Smuzhiyun 				return I40E_NOT_SUPPORTED;
5733*4882a593Smuzhiyun 			}
5734*4882a593Smuzhiyun 		} else {
5735*4882a593Smuzhiyun 			if (sec->section.type == SECTION_TYPE_RB_AQ ||
5736*4882a593Smuzhiyun 			    sec->section.type == SECTION_TYPE_RB_MMIO) {
5737*4882a593Smuzhiyun 				i40e_debug(hw, I40E_DEBUG_PACKAGE,
5738*4882a593Smuzhiyun 					   "Not an original package\n");
5739*4882a593Smuzhiyun 				return I40E_NOT_SUPPORTED;
5740*4882a593Smuzhiyun 			}
5741*4882a593Smuzhiyun 		}
5742*4882a593Smuzhiyun 	}
5743*4882a593Smuzhiyun 
5744*4882a593Smuzhiyun 	return status;
5745*4882a593Smuzhiyun }
5746*4882a593Smuzhiyun 
5747*4882a593Smuzhiyun /**
5748*4882a593Smuzhiyun  * i40e_write_profile
5749*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
5750*4882a593Smuzhiyun  * @profile: pointer to the profile segment of the package to be downloaded
5751*4882a593Smuzhiyun  * @track_id: package tracking id
5752*4882a593Smuzhiyun  *
5753*4882a593Smuzhiyun  * Handles the download of a complete package.
5754*4882a593Smuzhiyun  */
5755*4882a593Smuzhiyun enum i40e_status_code
i40e_write_profile(struct i40e_hw * hw,struct i40e_profile_segment * profile,u32 track_id)5756*4882a593Smuzhiyun i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
5757*4882a593Smuzhiyun 		   u32 track_id)
5758*4882a593Smuzhiyun {
5759*4882a593Smuzhiyun 	i40e_status status = 0;
5760*4882a593Smuzhiyun 	struct i40e_section_table *sec_tbl;
5761*4882a593Smuzhiyun 	struct i40e_profile_section_header *sec = NULL;
5762*4882a593Smuzhiyun 	struct i40e_profile_aq_section *ddp_aq;
5763*4882a593Smuzhiyun 	u32 section_size = 0;
5764*4882a593Smuzhiyun 	u32 offset = 0, info = 0;
5765*4882a593Smuzhiyun 	u32 sec_off;
5766*4882a593Smuzhiyun 	u32 i;
5767*4882a593Smuzhiyun 
5768*4882a593Smuzhiyun 	status = i40e_validate_profile(hw, profile, track_id, false);
5769*4882a593Smuzhiyun 	if (status)
5770*4882a593Smuzhiyun 		return status;
5771*4882a593Smuzhiyun 
5772*4882a593Smuzhiyun 	I40E_SECTION_TABLE(profile, sec_tbl);
5773*4882a593Smuzhiyun 
5774*4882a593Smuzhiyun 	for (i = 0; i < sec_tbl->section_count; i++) {
5775*4882a593Smuzhiyun 		sec_off = sec_tbl->section_offset[i];
5776*4882a593Smuzhiyun 		sec = I40E_SECTION_HEADER(profile, sec_off);
5777*4882a593Smuzhiyun 		/* Process generic admin command */
5778*4882a593Smuzhiyun 		if (sec->section.type == SECTION_TYPE_AQ) {
5779*4882a593Smuzhiyun 			ddp_aq = (struct i40e_profile_aq_section *)&sec[1];
5780*4882a593Smuzhiyun 			status = i40e_ddp_exec_aq_section(hw, ddp_aq);
5781*4882a593Smuzhiyun 			if (status) {
5782*4882a593Smuzhiyun 				i40e_debug(hw, I40E_DEBUG_PACKAGE,
5783*4882a593Smuzhiyun 					   "Failed to execute aq: section %d, opcode %u\n",
5784*4882a593Smuzhiyun 					   i, ddp_aq->opcode);
5785*4882a593Smuzhiyun 				break;
5786*4882a593Smuzhiyun 			}
5787*4882a593Smuzhiyun 			sec->section.type = SECTION_TYPE_RB_AQ;
5788*4882a593Smuzhiyun 		}
5789*4882a593Smuzhiyun 
5790*4882a593Smuzhiyun 		/* Skip any non-mmio sections */
5791*4882a593Smuzhiyun 		if (sec->section.type != SECTION_TYPE_MMIO)
5792*4882a593Smuzhiyun 			continue;
5793*4882a593Smuzhiyun 
5794*4882a593Smuzhiyun 		section_size = sec->section.size +
5795*4882a593Smuzhiyun 			sizeof(struct i40e_profile_section_header);
5796*4882a593Smuzhiyun 
5797*4882a593Smuzhiyun 		/* Write MMIO section */
5798*4882a593Smuzhiyun 		status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
5799*4882a593Smuzhiyun 					   track_id, &offset, &info, NULL);
5800*4882a593Smuzhiyun 		if (status) {
5801*4882a593Smuzhiyun 			i40e_debug(hw, I40E_DEBUG_PACKAGE,
5802*4882a593Smuzhiyun 				   "Failed to write profile: section %d, offset %d, info %d\n",
5803*4882a593Smuzhiyun 				   i, offset, info);
5804*4882a593Smuzhiyun 			break;
5805*4882a593Smuzhiyun 		}
5806*4882a593Smuzhiyun 	}
5807*4882a593Smuzhiyun 	return status;
5808*4882a593Smuzhiyun }
5809*4882a593Smuzhiyun 
5810*4882a593Smuzhiyun /**
5811*4882a593Smuzhiyun  * i40e_rollback_profile
5812*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
5813*4882a593Smuzhiyun  * @profile: pointer to the profile segment of the package to be removed
5814*4882a593Smuzhiyun  * @track_id: package tracking id
5815*4882a593Smuzhiyun  *
5816*4882a593Smuzhiyun  * Rolls back previously loaded package.
5817*4882a593Smuzhiyun  */
5818*4882a593Smuzhiyun enum i40e_status_code
i40e_rollback_profile(struct i40e_hw * hw,struct i40e_profile_segment * profile,u32 track_id)5819*4882a593Smuzhiyun i40e_rollback_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
5820*4882a593Smuzhiyun 		      u32 track_id)
5821*4882a593Smuzhiyun {
5822*4882a593Smuzhiyun 	struct i40e_profile_section_header *sec = NULL;
5823*4882a593Smuzhiyun 	i40e_status status = 0;
5824*4882a593Smuzhiyun 	struct i40e_section_table *sec_tbl;
5825*4882a593Smuzhiyun 	u32 offset = 0, info = 0;
5826*4882a593Smuzhiyun 	u32 section_size = 0;
5827*4882a593Smuzhiyun 	u32 sec_off;
5828*4882a593Smuzhiyun 	int i;
5829*4882a593Smuzhiyun 
5830*4882a593Smuzhiyun 	status = i40e_validate_profile(hw, profile, track_id, true);
5831*4882a593Smuzhiyun 	if (status)
5832*4882a593Smuzhiyun 		return status;
5833*4882a593Smuzhiyun 
5834*4882a593Smuzhiyun 	I40E_SECTION_TABLE(profile, sec_tbl);
5835*4882a593Smuzhiyun 
5836*4882a593Smuzhiyun 	/* For rollback write sections in reverse */
5837*4882a593Smuzhiyun 	for (i = sec_tbl->section_count - 1; i >= 0; i--) {
5838*4882a593Smuzhiyun 		sec_off = sec_tbl->section_offset[i];
5839*4882a593Smuzhiyun 		sec = I40E_SECTION_HEADER(profile, sec_off);
5840*4882a593Smuzhiyun 
5841*4882a593Smuzhiyun 		/* Skip any non-rollback sections */
5842*4882a593Smuzhiyun 		if (sec->section.type != SECTION_TYPE_RB_MMIO)
5843*4882a593Smuzhiyun 			continue;
5844*4882a593Smuzhiyun 
5845*4882a593Smuzhiyun 		section_size = sec->section.size +
5846*4882a593Smuzhiyun 			sizeof(struct i40e_profile_section_header);
5847*4882a593Smuzhiyun 
5848*4882a593Smuzhiyun 		/* Write roll-back MMIO section */
5849*4882a593Smuzhiyun 		status = i40e_aq_write_ddp(hw, (void *)sec, (u16)section_size,
5850*4882a593Smuzhiyun 					   track_id, &offset, &info, NULL);
5851*4882a593Smuzhiyun 		if (status) {
5852*4882a593Smuzhiyun 			i40e_debug(hw, I40E_DEBUG_PACKAGE,
5853*4882a593Smuzhiyun 				   "Failed to write profile: section %d, offset %d, info %d\n",
5854*4882a593Smuzhiyun 				   i, offset, info);
5855*4882a593Smuzhiyun 			break;
5856*4882a593Smuzhiyun 		}
5857*4882a593Smuzhiyun 	}
5858*4882a593Smuzhiyun 	return status;
5859*4882a593Smuzhiyun }
5860*4882a593Smuzhiyun 
5861*4882a593Smuzhiyun /**
5862*4882a593Smuzhiyun  * i40e_add_pinfo_to_list
5863*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
5864*4882a593Smuzhiyun  * @profile: pointer to the profile segment of the package
5865*4882a593Smuzhiyun  * @profile_info_sec: buffer for information section
5866*4882a593Smuzhiyun  * @track_id: package tracking id
5867*4882a593Smuzhiyun  *
5868*4882a593Smuzhiyun  * Register a profile to the list of loaded profiles.
5869*4882a593Smuzhiyun  */
5870*4882a593Smuzhiyun enum i40e_status_code
i40e_add_pinfo_to_list(struct i40e_hw * hw,struct i40e_profile_segment * profile,u8 * profile_info_sec,u32 track_id)5871*4882a593Smuzhiyun i40e_add_pinfo_to_list(struct i40e_hw *hw,
5872*4882a593Smuzhiyun 		       struct i40e_profile_segment *profile,
5873*4882a593Smuzhiyun 		       u8 *profile_info_sec, u32 track_id)
5874*4882a593Smuzhiyun {
5875*4882a593Smuzhiyun 	i40e_status status = 0;
5876*4882a593Smuzhiyun 	struct i40e_profile_section_header *sec = NULL;
5877*4882a593Smuzhiyun 	struct i40e_profile_info *pinfo;
5878*4882a593Smuzhiyun 	u32 offset = 0, info = 0;
5879*4882a593Smuzhiyun 
5880*4882a593Smuzhiyun 	sec = (struct i40e_profile_section_header *)profile_info_sec;
5881*4882a593Smuzhiyun 	sec->tbl_size = 1;
5882*4882a593Smuzhiyun 	sec->data_end = sizeof(struct i40e_profile_section_header) +
5883*4882a593Smuzhiyun 			sizeof(struct i40e_profile_info);
5884*4882a593Smuzhiyun 	sec->section.type = SECTION_TYPE_INFO;
5885*4882a593Smuzhiyun 	sec->section.offset = sizeof(struct i40e_profile_section_header);
5886*4882a593Smuzhiyun 	sec->section.size = sizeof(struct i40e_profile_info);
5887*4882a593Smuzhiyun 	pinfo = (struct i40e_profile_info *)(profile_info_sec +
5888*4882a593Smuzhiyun 					     sec->section.offset);
5889*4882a593Smuzhiyun 	pinfo->track_id = track_id;
5890*4882a593Smuzhiyun 	pinfo->version = profile->version;
5891*4882a593Smuzhiyun 	pinfo->op = I40E_DDP_ADD_TRACKID;
5892*4882a593Smuzhiyun 	memcpy(pinfo->name, profile->name, I40E_DDP_NAME_SIZE);
5893*4882a593Smuzhiyun 
5894*4882a593Smuzhiyun 	status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
5895*4882a593Smuzhiyun 				   track_id, &offset, &info, NULL);
5896*4882a593Smuzhiyun 
5897*4882a593Smuzhiyun 	return status;
5898*4882a593Smuzhiyun }
5899*4882a593Smuzhiyun 
5900*4882a593Smuzhiyun /**
5901*4882a593Smuzhiyun  * i40e_aq_add_cloud_filters
5902*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
5903*4882a593Smuzhiyun  * @seid: VSI seid to add cloud filters from
5904*4882a593Smuzhiyun  * @filters: Buffer which contains the filters to be added
5905*4882a593Smuzhiyun  * @filter_count: number of filters contained in the buffer
5906*4882a593Smuzhiyun  *
5907*4882a593Smuzhiyun  * Set the cloud filters for a given VSI.  The contents of the
5908*4882a593Smuzhiyun  * i40e_aqc_cloud_filters_element_data are filled in by the caller
5909*4882a593Smuzhiyun  * of the function.
5910*4882a593Smuzhiyun  *
5911*4882a593Smuzhiyun  **/
5912*4882a593Smuzhiyun enum i40e_status_code
i40e_aq_add_cloud_filters(struct i40e_hw * hw,u16 seid,struct i40e_aqc_cloud_filters_element_data * filters,u8 filter_count)5913*4882a593Smuzhiyun i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
5914*4882a593Smuzhiyun 			  struct i40e_aqc_cloud_filters_element_data *filters,
5915*4882a593Smuzhiyun 			  u8 filter_count)
5916*4882a593Smuzhiyun {
5917*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5918*4882a593Smuzhiyun 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5919*4882a593Smuzhiyun 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5920*4882a593Smuzhiyun 	enum i40e_status_code status;
5921*4882a593Smuzhiyun 	u16 buff_len;
5922*4882a593Smuzhiyun 
5923*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
5924*4882a593Smuzhiyun 					  i40e_aqc_opc_add_cloud_filters);
5925*4882a593Smuzhiyun 
5926*4882a593Smuzhiyun 	buff_len = filter_count * sizeof(*filters);
5927*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_len);
5928*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5929*4882a593Smuzhiyun 	cmd->num_filters = filter_count;
5930*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
5931*4882a593Smuzhiyun 
5932*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5933*4882a593Smuzhiyun 
5934*4882a593Smuzhiyun 	return status;
5935*4882a593Smuzhiyun }
5936*4882a593Smuzhiyun 
5937*4882a593Smuzhiyun /**
5938*4882a593Smuzhiyun  * i40e_aq_add_cloud_filters_bb
5939*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
5940*4882a593Smuzhiyun  * @seid: VSI seid to add cloud filters from
5941*4882a593Smuzhiyun  * @filters: Buffer which contains the filters in big buffer to be added
5942*4882a593Smuzhiyun  * @filter_count: number of filters contained in the buffer
5943*4882a593Smuzhiyun  *
5944*4882a593Smuzhiyun  * Set the big buffer cloud filters for a given VSI.  The contents of the
5945*4882a593Smuzhiyun  * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5946*4882a593Smuzhiyun  * function.
5947*4882a593Smuzhiyun  *
5948*4882a593Smuzhiyun  **/
5949*4882a593Smuzhiyun enum i40e_status_code
i40e_aq_add_cloud_filters_bb(struct i40e_hw * hw,u16 seid,struct i40e_aqc_cloud_filters_element_bb * filters,u8 filter_count)5950*4882a593Smuzhiyun i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5951*4882a593Smuzhiyun 			     struct i40e_aqc_cloud_filters_element_bb *filters,
5952*4882a593Smuzhiyun 			     u8 filter_count)
5953*4882a593Smuzhiyun {
5954*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
5955*4882a593Smuzhiyun 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5956*4882a593Smuzhiyun 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5957*4882a593Smuzhiyun 	i40e_status status;
5958*4882a593Smuzhiyun 	u16 buff_len;
5959*4882a593Smuzhiyun 	int i;
5960*4882a593Smuzhiyun 
5961*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
5962*4882a593Smuzhiyun 					  i40e_aqc_opc_add_cloud_filters);
5963*4882a593Smuzhiyun 
5964*4882a593Smuzhiyun 	buff_len = filter_count * sizeof(*filters);
5965*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_len);
5966*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5967*4882a593Smuzhiyun 	cmd->num_filters = filter_count;
5968*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
5969*4882a593Smuzhiyun 	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5970*4882a593Smuzhiyun 
5971*4882a593Smuzhiyun 	for (i = 0; i < filter_count; i++) {
5972*4882a593Smuzhiyun 		u16 tnl_type;
5973*4882a593Smuzhiyun 		u32 ti;
5974*4882a593Smuzhiyun 
5975*4882a593Smuzhiyun 		tnl_type = (le16_to_cpu(filters[i].element.flags) &
5976*4882a593Smuzhiyun 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5977*4882a593Smuzhiyun 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5978*4882a593Smuzhiyun 
5979*4882a593Smuzhiyun 		/* Due to hardware eccentricities, the VNI for Geneve is shifted
5980*4882a593Smuzhiyun 		 * one more byte further than normally used for Tenant ID in
5981*4882a593Smuzhiyun 		 * other tunnel types.
5982*4882a593Smuzhiyun 		 */
5983*4882a593Smuzhiyun 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5984*4882a593Smuzhiyun 			ti = le32_to_cpu(filters[i].element.tenant_id);
5985*4882a593Smuzhiyun 			filters[i].element.tenant_id = cpu_to_le32(ti << 8);
5986*4882a593Smuzhiyun 		}
5987*4882a593Smuzhiyun 	}
5988*4882a593Smuzhiyun 
5989*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5990*4882a593Smuzhiyun 
5991*4882a593Smuzhiyun 	return status;
5992*4882a593Smuzhiyun }
5993*4882a593Smuzhiyun 
5994*4882a593Smuzhiyun /**
5995*4882a593Smuzhiyun  * i40e_aq_rem_cloud_filters
5996*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
5997*4882a593Smuzhiyun  * @seid: VSI seid to remove cloud filters from
5998*4882a593Smuzhiyun  * @filters: Buffer which contains the filters to be removed
5999*4882a593Smuzhiyun  * @filter_count: number of filters contained in the buffer
6000*4882a593Smuzhiyun  *
6001*4882a593Smuzhiyun  * Remove the cloud filters for a given VSI.  The contents of the
6002*4882a593Smuzhiyun  * i40e_aqc_cloud_filters_element_data are filled in by the caller
6003*4882a593Smuzhiyun  * of the function.
6004*4882a593Smuzhiyun  *
6005*4882a593Smuzhiyun  **/
6006*4882a593Smuzhiyun enum i40e_status_code
i40e_aq_rem_cloud_filters(struct i40e_hw * hw,u16 seid,struct i40e_aqc_cloud_filters_element_data * filters,u8 filter_count)6007*4882a593Smuzhiyun i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
6008*4882a593Smuzhiyun 			  struct i40e_aqc_cloud_filters_element_data *filters,
6009*4882a593Smuzhiyun 			  u8 filter_count)
6010*4882a593Smuzhiyun {
6011*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
6012*4882a593Smuzhiyun 	struct i40e_aqc_add_remove_cloud_filters *cmd =
6013*4882a593Smuzhiyun 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
6014*4882a593Smuzhiyun 	enum i40e_status_code status;
6015*4882a593Smuzhiyun 	u16 buff_len;
6016*4882a593Smuzhiyun 
6017*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
6018*4882a593Smuzhiyun 					  i40e_aqc_opc_remove_cloud_filters);
6019*4882a593Smuzhiyun 
6020*4882a593Smuzhiyun 	buff_len = filter_count * sizeof(*filters);
6021*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_len);
6022*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
6023*4882a593Smuzhiyun 	cmd->num_filters = filter_count;
6024*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
6025*4882a593Smuzhiyun 
6026*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
6027*4882a593Smuzhiyun 
6028*4882a593Smuzhiyun 	return status;
6029*4882a593Smuzhiyun }
6030*4882a593Smuzhiyun 
6031*4882a593Smuzhiyun /**
6032*4882a593Smuzhiyun  * i40e_aq_rem_cloud_filters_bb
6033*4882a593Smuzhiyun  * @hw: pointer to the hardware structure
6034*4882a593Smuzhiyun  * @seid: VSI seid to remove cloud filters from
6035*4882a593Smuzhiyun  * @filters: Buffer which contains the filters in big buffer to be removed
6036*4882a593Smuzhiyun  * @filter_count: number of filters contained in the buffer
6037*4882a593Smuzhiyun  *
6038*4882a593Smuzhiyun  * Remove the big buffer cloud filters for a given VSI.  The contents of the
6039*4882a593Smuzhiyun  * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
6040*4882a593Smuzhiyun  * function.
6041*4882a593Smuzhiyun  *
6042*4882a593Smuzhiyun  **/
6043*4882a593Smuzhiyun enum i40e_status_code
i40e_aq_rem_cloud_filters_bb(struct i40e_hw * hw,u16 seid,struct i40e_aqc_cloud_filters_element_bb * filters,u8 filter_count)6044*4882a593Smuzhiyun i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
6045*4882a593Smuzhiyun 			     struct i40e_aqc_cloud_filters_element_bb *filters,
6046*4882a593Smuzhiyun 			     u8 filter_count)
6047*4882a593Smuzhiyun {
6048*4882a593Smuzhiyun 	struct i40e_aq_desc desc;
6049*4882a593Smuzhiyun 	struct i40e_aqc_add_remove_cloud_filters *cmd =
6050*4882a593Smuzhiyun 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
6051*4882a593Smuzhiyun 	i40e_status status;
6052*4882a593Smuzhiyun 	u16 buff_len;
6053*4882a593Smuzhiyun 	int i;
6054*4882a593Smuzhiyun 
6055*4882a593Smuzhiyun 	i40e_fill_default_direct_cmd_desc(&desc,
6056*4882a593Smuzhiyun 					  i40e_aqc_opc_remove_cloud_filters);
6057*4882a593Smuzhiyun 
6058*4882a593Smuzhiyun 	buff_len = filter_count * sizeof(*filters);
6059*4882a593Smuzhiyun 	desc.datalen = cpu_to_le16(buff_len);
6060*4882a593Smuzhiyun 	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
6061*4882a593Smuzhiyun 	cmd->num_filters = filter_count;
6062*4882a593Smuzhiyun 	cmd->seid = cpu_to_le16(seid);
6063*4882a593Smuzhiyun 	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
6064*4882a593Smuzhiyun 
6065*4882a593Smuzhiyun 	for (i = 0; i < filter_count; i++) {
6066*4882a593Smuzhiyun 		u16 tnl_type;
6067*4882a593Smuzhiyun 		u32 ti;
6068*4882a593Smuzhiyun 
6069*4882a593Smuzhiyun 		tnl_type = (le16_to_cpu(filters[i].element.flags) &
6070*4882a593Smuzhiyun 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
6071*4882a593Smuzhiyun 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
6072*4882a593Smuzhiyun 
6073*4882a593Smuzhiyun 		/* Due to hardware eccentricities, the VNI for Geneve is shifted
6074*4882a593Smuzhiyun 		 * one more byte further than normally used for Tenant ID in
6075*4882a593Smuzhiyun 		 * other tunnel types.
6076*4882a593Smuzhiyun 		 */
6077*4882a593Smuzhiyun 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
6078*4882a593Smuzhiyun 			ti = le32_to_cpu(filters[i].element.tenant_id);
6079*4882a593Smuzhiyun 			filters[i].element.tenant_id = cpu_to_le32(ti << 8);
6080*4882a593Smuzhiyun 		}
6081*4882a593Smuzhiyun 	}
6082*4882a593Smuzhiyun 
6083*4882a593Smuzhiyun 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
6084*4882a593Smuzhiyun 
6085*4882a593Smuzhiyun 	return status;
6086*4882a593Smuzhiyun }
6087