xref: /freebsd/sys/dev/ixl/i40e_common.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
161ae650dSJack F Vogel /******************************************************************************
261ae650dSJack F Vogel 
3f4cc2d17SEric Joyner   Copyright (c) 2013-2018, Intel Corporation
461ae650dSJack F Vogel   All rights reserved.
561ae650dSJack F Vogel 
661ae650dSJack F Vogel   Redistribution and use in source and binary forms, with or without
761ae650dSJack F Vogel   modification, are permitted provided that the following conditions are met:
861ae650dSJack F Vogel 
961ae650dSJack F Vogel    1. Redistributions of source code must retain the above copyright notice,
1061ae650dSJack F Vogel       this list of conditions and the following disclaimer.
1161ae650dSJack F Vogel 
1261ae650dSJack F Vogel    2. Redistributions in binary form must reproduce the above copyright
1361ae650dSJack F Vogel       notice, this list of conditions and the following disclaimer in the
1461ae650dSJack F Vogel       documentation and/or other materials provided with the distribution.
1561ae650dSJack F Vogel 
1661ae650dSJack F Vogel    3. Neither the name of the Intel Corporation nor the names of its
1761ae650dSJack F Vogel       contributors may be used to endorse or promote products derived from
1861ae650dSJack F Vogel       this software without specific prior written permission.
1961ae650dSJack F Vogel 
2061ae650dSJack F Vogel   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2161ae650dSJack F Vogel   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2261ae650dSJack F Vogel   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2361ae650dSJack F Vogel   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2461ae650dSJack F Vogel   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2561ae650dSJack F Vogel   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2661ae650dSJack F Vogel   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2761ae650dSJack F Vogel   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2861ae650dSJack F Vogel   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2961ae650dSJack F Vogel   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3061ae650dSJack F Vogel   POSSIBILITY OF SUCH DAMAGE.
3161ae650dSJack F Vogel 
3261ae650dSJack F Vogel ******************************************************************************/
3361ae650dSJack F Vogel 
3461ae650dSJack F Vogel #include "i40e_type.h"
3561ae650dSJack F Vogel #include "i40e_adminq.h"
3661ae650dSJack F Vogel #include "i40e_prototype.h"
37ceebc2f3SEric Joyner #include "virtchnl.h"
3861ae650dSJack F Vogel 
39b6c8f260SJack F Vogel 
4061ae650dSJack F Vogel /**
4161ae650dSJack F Vogel  * i40e_set_mac_type - Sets MAC type
4261ae650dSJack F Vogel  * @hw: pointer to the HW structure
4361ae650dSJack F Vogel  *
4461ae650dSJack F Vogel  * This function sets the mac type of the adapter based on the
4561ae650dSJack F Vogel  * vendor ID and device ID stored in the hw structure.
4661ae650dSJack F Vogel  **/
i40e_set_mac_type(struct i40e_hw * hw)4761ae650dSJack F Vogel enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
4861ae650dSJack F Vogel {
4961ae650dSJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
5061ae650dSJack F Vogel 
5161ae650dSJack F Vogel 	DEBUGFUNC("i40e_set_mac_type\n");
5261ae650dSJack F Vogel 
5361ae650dSJack F Vogel 	if (hw->vendor_id == I40E_INTEL_VENDOR_ID) {
5461ae650dSJack F Vogel 		switch (hw->device_id) {
5561ae650dSJack F Vogel 		case I40E_DEV_ID_SFP_XL710:
5661ae650dSJack F Vogel 		case I40E_DEV_ID_QEMU:
5761ae650dSJack F Vogel 		case I40E_DEV_ID_KX_B:
5861ae650dSJack F Vogel 		case I40E_DEV_ID_KX_C:
5961ae650dSJack F Vogel 		case I40E_DEV_ID_QSFP_A:
6061ae650dSJack F Vogel 		case I40E_DEV_ID_QSFP_B:
6161ae650dSJack F Vogel 		case I40E_DEV_ID_QSFP_C:
6261ae650dSJack F Vogel 		case I40E_DEV_ID_10G_BASE_T:
63be771cdaSJack F Vogel 		case I40E_DEV_ID_10G_BASE_T4:
642984a8ddSEric Joyner 		case I40E_DEV_ID_10G_BASE_T_BC:
652984a8ddSEric Joyner 		case I40E_DEV_ID_10G_B:
662984a8ddSEric Joyner 		case I40E_DEV_ID_10G_SFP:
672984a8ddSEric Joyner 		case I40E_DEV_ID_5G_BASE_T_BC:
68*b7b40e4aSKrzysztof Galazka 		case I40E_DEV_ID_1G_BASE_T_BC:
69b6c8f260SJack F Vogel 		case I40E_DEV_ID_20G_KR2:
70be771cdaSJack F Vogel 		case I40E_DEV_ID_20G_KR2_A:
714294f337SSean Bruno 		case I40E_DEV_ID_25G_B:
724294f337SSean Bruno 		case I40E_DEV_ID_25G_SFP28:
73b4a7ce06SEric Joyner 		case I40E_DEV_ID_X710_N3000:
74b4a7ce06SEric Joyner 		case I40E_DEV_ID_XXV710_N3000:
7561ae650dSJack F Vogel 			hw->mac.type = I40E_MAC_XL710;
7661ae650dSJack F Vogel 			break;
774294f337SSean Bruno 		case I40E_DEV_ID_KX_X722:
784294f337SSean Bruno 		case I40E_DEV_ID_QSFP_X722:
794294f337SSean Bruno 		case I40E_DEV_ID_SFP_X722:
804294f337SSean Bruno 		case I40E_DEV_ID_1G_BASE_T_X722:
814294f337SSean Bruno 		case I40E_DEV_ID_10G_BASE_T_X722:
824294f337SSean Bruno 		case I40E_DEV_ID_SFP_I_X722:
834294f337SSean Bruno 			hw->mac.type = I40E_MAC_X722;
844294f337SSean Bruno 			break;
854294f337SSean Bruno 		case I40E_DEV_ID_X722_VF:
864294f337SSean Bruno 			hw->mac.type = I40E_MAC_X722_VF;
874294f337SSean Bruno 			break;
8861ae650dSJack F Vogel 		case I40E_DEV_ID_VF:
8961ae650dSJack F Vogel 		case I40E_DEV_ID_VF_HV:
90ceebc2f3SEric Joyner 		case I40E_DEV_ID_ADAPTIVE_VF:
9161ae650dSJack F Vogel 			hw->mac.type = I40E_MAC_VF;
9261ae650dSJack F Vogel 			break;
9361ae650dSJack F Vogel 		default:
9461ae650dSJack F Vogel 			hw->mac.type = I40E_MAC_GENERIC;
9561ae650dSJack F Vogel 			break;
9661ae650dSJack F Vogel 		}
9761ae650dSJack F Vogel 	} else {
9861ae650dSJack F Vogel 		status = I40E_ERR_DEVICE_NOT_SUPPORTED;
9961ae650dSJack F Vogel 	}
10061ae650dSJack F Vogel 
10161ae650dSJack F Vogel 	DEBUGOUT2("i40e_set_mac_type found mac: %d, returns: %d\n",
10261ae650dSJack F Vogel 		  hw->mac.type, status);
10361ae650dSJack F Vogel 	return status;
10461ae650dSJack F Vogel }
10561ae650dSJack F Vogel 
10661ae650dSJack F Vogel /**
107be771cdaSJack F Vogel  * i40e_aq_str - convert AQ err code to a string
108be771cdaSJack F Vogel  * @hw: pointer to the HW structure
109be771cdaSJack F Vogel  * @aq_err: the AQ error code to convert
110be771cdaSJack F Vogel  **/
i40e_aq_str(struct i40e_hw * hw,enum i40e_admin_queue_err aq_err)111ac83ea83SEric Joyner const char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err)
112be771cdaSJack F Vogel {
113be771cdaSJack F Vogel 	switch (aq_err) {
114be771cdaSJack F Vogel 	case I40E_AQ_RC_OK:
115be771cdaSJack F Vogel 		return "OK";
116be771cdaSJack F Vogel 	case I40E_AQ_RC_EPERM:
117be771cdaSJack F Vogel 		return "I40E_AQ_RC_EPERM";
118be771cdaSJack F Vogel 	case I40E_AQ_RC_ENOENT:
119be771cdaSJack F Vogel 		return "I40E_AQ_RC_ENOENT";
120be771cdaSJack F Vogel 	case I40E_AQ_RC_ESRCH:
121be771cdaSJack F Vogel 		return "I40E_AQ_RC_ESRCH";
122be771cdaSJack F Vogel 	case I40E_AQ_RC_EINTR:
123be771cdaSJack F Vogel 		return "I40E_AQ_RC_EINTR";
124be771cdaSJack F Vogel 	case I40E_AQ_RC_EIO:
125be771cdaSJack F Vogel 		return "I40E_AQ_RC_EIO";
126be771cdaSJack F Vogel 	case I40E_AQ_RC_ENXIO:
127be771cdaSJack F Vogel 		return "I40E_AQ_RC_ENXIO";
128be771cdaSJack F Vogel 	case I40E_AQ_RC_E2BIG:
129be771cdaSJack F Vogel 		return "I40E_AQ_RC_E2BIG";
130be771cdaSJack F Vogel 	case I40E_AQ_RC_EAGAIN:
131be771cdaSJack F Vogel 		return "I40E_AQ_RC_EAGAIN";
132be771cdaSJack F Vogel 	case I40E_AQ_RC_ENOMEM:
133be771cdaSJack F Vogel 		return "I40E_AQ_RC_ENOMEM";
134be771cdaSJack F Vogel 	case I40E_AQ_RC_EACCES:
135be771cdaSJack F Vogel 		return "I40E_AQ_RC_EACCES";
136be771cdaSJack F Vogel 	case I40E_AQ_RC_EFAULT:
137be771cdaSJack F Vogel 		return "I40E_AQ_RC_EFAULT";
138be771cdaSJack F Vogel 	case I40E_AQ_RC_EBUSY:
139be771cdaSJack F Vogel 		return "I40E_AQ_RC_EBUSY";
140be771cdaSJack F Vogel 	case I40E_AQ_RC_EEXIST:
141be771cdaSJack F Vogel 		return "I40E_AQ_RC_EEXIST";
142be771cdaSJack F Vogel 	case I40E_AQ_RC_EINVAL:
143be771cdaSJack F Vogel 		return "I40E_AQ_RC_EINVAL";
144be771cdaSJack F Vogel 	case I40E_AQ_RC_ENOTTY:
145be771cdaSJack F Vogel 		return "I40E_AQ_RC_ENOTTY";
146be771cdaSJack F Vogel 	case I40E_AQ_RC_ENOSPC:
147be771cdaSJack F Vogel 		return "I40E_AQ_RC_ENOSPC";
148be771cdaSJack F Vogel 	case I40E_AQ_RC_ENOSYS:
149be771cdaSJack F Vogel 		return "I40E_AQ_RC_ENOSYS";
150be771cdaSJack F Vogel 	case I40E_AQ_RC_ERANGE:
151be771cdaSJack F Vogel 		return "I40E_AQ_RC_ERANGE";
152be771cdaSJack F Vogel 	case I40E_AQ_RC_EFLUSHED:
153be771cdaSJack F Vogel 		return "I40E_AQ_RC_EFLUSHED";
154be771cdaSJack F Vogel 	case I40E_AQ_RC_BAD_ADDR:
155be771cdaSJack F Vogel 		return "I40E_AQ_RC_BAD_ADDR";
156be771cdaSJack F Vogel 	case I40E_AQ_RC_EMODE:
157be771cdaSJack F Vogel 		return "I40E_AQ_RC_EMODE";
158be771cdaSJack F Vogel 	case I40E_AQ_RC_EFBIG:
159be771cdaSJack F Vogel 		return "I40E_AQ_RC_EFBIG";
160be771cdaSJack F Vogel 	}
161be771cdaSJack F Vogel 
162be771cdaSJack F Vogel 	snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
163be771cdaSJack F Vogel 	return hw->err_str;
164be771cdaSJack F Vogel }
165be771cdaSJack F Vogel 
166be771cdaSJack F Vogel /**
167be771cdaSJack F Vogel  * i40e_stat_str - convert status err code to a string
168be771cdaSJack F Vogel  * @hw: pointer to the HW structure
169be771cdaSJack F Vogel  * @stat_err: the status error code to convert
170be771cdaSJack F Vogel  **/
i40e_stat_str(struct i40e_hw * hw,enum i40e_status_code stat_err)171ac83ea83SEric Joyner const char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err)
172be771cdaSJack F Vogel {
173be771cdaSJack F Vogel 	switch (stat_err) {
174be771cdaSJack F Vogel 	case I40E_SUCCESS:
175be771cdaSJack F Vogel 		return "OK";
176be771cdaSJack F Vogel 	case I40E_ERR_NVM:
177be771cdaSJack F Vogel 		return "I40E_ERR_NVM";
178be771cdaSJack F Vogel 	case I40E_ERR_NVM_CHECKSUM:
179be771cdaSJack F Vogel 		return "I40E_ERR_NVM_CHECKSUM";
180be771cdaSJack F Vogel 	case I40E_ERR_PHY:
181be771cdaSJack F Vogel 		return "I40E_ERR_PHY";
182be771cdaSJack F Vogel 	case I40E_ERR_CONFIG:
183be771cdaSJack F Vogel 		return "I40E_ERR_CONFIG";
184be771cdaSJack F Vogel 	case I40E_ERR_PARAM:
185be771cdaSJack F Vogel 		return "I40E_ERR_PARAM";
186be771cdaSJack F Vogel 	case I40E_ERR_MAC_TYPE:
187be771cdaSJack F Vogel 		return "I40E_ERR_MAC_TYPE";
188be771cdaSJack F Vogel 	case I40E_ERR_UNKNOWN_PHY:
189be771cdaSJack F Vogel 		return "I40E_ERR_UNKNOWN_PHY";
190be771cdaSJack F Vogel 	case I40E_ERR_LINK_SETUP:
191be771cdaSJack F Vogel 		return "I40E_ERR_LINK_SETUP";
192be771cdaSJack F Vogel 	case I40E_ERR_ADAPTER_STOPPED:
193be771cdaSJack F Vogel 		return "I40E_ERR_ADAPTER_STOPPED";
194be771cdaSJack F Vogel 	case I40E_ERR_INVALID_MAC_ADDR:
195be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_MAC_ADDR";
196be771cdaSJack F Vogel 	case I40E_ERR_DEVICE_NOT_SUPPORTED:
197be771cdaSJack F Vogel 		return "I40E_ERR_DEVICE_NOT_SUPPORTED";
198*b7b40e4aSKrzysztof Galazka 	case I40E_ERR_PRIMARY_REQUESTS_PENDING:
199*b7b40e4aSKrzysztof Galazka 		return "I40E_ERR_PRIMARY_REQUESTS_PENDING";
200be771cdaSJack F Vogel 	case I40E_ERR_INVALID_LINK_SETTINGS:
201be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_LINK_SETTINGS";
202be771cdaSJack F Vogel 	case I40E_ERR_AUTONEG_NOT_COMPLETE:
203be771cdaSJack F Vogel 		return "I40E_ERR_AUTONEG_NOT_COMPLETE";
204be771cdaSJack F Vogel 	case I40E_ERR_RESET_FAILED:
205be771cdaSJack F Vogel 		return "I40E_ERR_RESET_FAILED";
206be771cdaSJack F Vogel 	case I40E_ERR_SWFW_SYNC:
207be771cdaSJack F Vogel 		return "I40E_ERR_SWFW_SYNC";
208be771cdaSJack F Vogel 	case I40E_ERR_NO_AVAILABLE_VSI:
209be771cdaSJack F Vogel 		return "I40E_ERR_NO_AVAILABLE_VSI";
210be771cdaSJack F Vogel 	case I40E_ERR_NO_MEMORY:
211be771cdaSJack F Vogel 		return "I40E_ERR_NO_MEMORY";
212be771cdaSJack F Vogel 	case I40E_ERR_BAD_PTR:
213be771cdaSJack F Vogel 		return "I40E_ERR_BAD_PTR";
214be771cdaSJack F Vogel 	case I40E_ERR_RING_FULL:
215be771cdaSJack F Vogel 		return "I40E_ERR_RING_FULL";
216be771cdaSJack F Vogel 	case I40E_ERR_INVALID_PD_ID:
217be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_PD_ID";
218be771cdaSJack F Vogel 	case I40E_ERR_INVALID_QP_ID:
219be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_QP_ID";
220be771cdaSJack F Vogel 	case I40E_ERR_INVALID_CQ_ID:
221be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_CQ_ID";
222be771cdaSJack F Vogel 	case I40E_ERR_INVALID_CEQ_ID:
223be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_CEQ_ID";
224be771cdaSJack F Vogel 	case I40E_ERR_INVALID_AEQ_ID:
225be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_AEQ_ID";
226be771cdaSJack F Vogel 	case I40E_ERR_INVALID_SIZE:
227be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_SIZE";
228be771cdaSJack F Vogel 	case I40E_ERR_INVALID_ARP_INDEX:
229be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_ARP_INDEX";
230be771cdaSJack F Vogel 	case I40E_ERR_INVALID_FPM_FUNC_ID:
231be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_FPM_FUNC_ID";
232be771cdaSJack F Vogel 	case I40E_ERR_QP_INVALID_MSG_SIZE:
233be771cdaSJack F Vogel 		return "I40E_ERR_QP_INVALID_MSG_SIZE";
234be771cdaSJack F Vogel 	case I40E_ERR_QP_TOOMANY_WRS_POSTED:
235be771cdaSJack F Vogel 		return "I40E_ERR_QP_TOOMANY_WRS_POSTED";
236be771cdaSJack F Vogel 	case I40E_ERR_INVALID_FRAG_COUNT:
237be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_FRAG_COUNT";
238be771cdaSJack F Vogel 	case I40E_ERR_QUEUE_EMPTY:
239be771cdaSJack F Vogel 		return "I40E_ERR_QUEUE_EMPTY";
240be771cdaSJack F Vogel 	case I40E_ERR_INVALID_ALIGNMENT:
241be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_ALIGNMENT";
242be771cdaSJack F Vogel 	case I40E_ERR_FLUSHED_QUEUE:
243be771cdaSJack F Vogel 		return "I40E_ERR_FLUSHED_QUEUE";
244be771cdaSJack F Vogel 	case I40E_ERR_INVALID_PUSH_PAGE_INDEX:
245be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_PUSH_PAGE_INDEX";
246be771cdaSJack F Vogel 	case I40E_ERR_INVALID_IMM_DATA_SIZE:
247be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_IMM_DATA_SIZE";
248be771cdaSJack F Vogel 	case I40E_ERR_TIMEOUT:
249be771cdaSJack F Vogel 		return "I40E_ERR_TIMEOUT";
250be771cdaSJack F Vogel 	case I40E_ERR_OPCODE_MISMATCH:
251be771cdaSJack F Vogel 		return "I40E_ERR_OPCODE_MISMATCH";
252be771cdaSJack F Vogel 	case I40E_ERR_CQP_COMPL_ERROR:
253be771cdaSJack F Vogel 		return "I40E_ERR_CQP_COMPL_ERROR";
254be771cdaSJack F Vogel 	case I40E_ERR_INVALID_VF_ID:
255be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_VF_ID";
256be771cdaSJack F Vogel 	case I40E_ERR_INVALID_HMCFN_ID:
257be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_HMCFN_ID";
258be771cdaSJack F Vogel 	case I40E_ERR_BACKING_PAGE_ERROR:
259be771cdaSJack F Vogel 		return "I40E_ERR_BACKING_PAGE_ERROR";
260be771cdaSJack F Vogel 	case I40E_ERR_NO_PBLCHUNKS_AVAILABLE:
261be771cdaSJack F Vogel 		return "I40E_ERR_NO_PBLCHUNKS_AVAILABLE";
262be771cdaSJack F Vogel 	case I40E_ERR_INVALID_PBLE_INDEX:
263be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_PBLE_INDEX";
264be771cdaSJack F Vogel 	case I40E_ERR_INVALID_SD_INDEX:
265be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_SD_INDEX";
266be771cdaSJack F Vogel 	case I40E_ERR_INVALID_PAGE_DESC_INDEX:
267be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_PAGE_DESC_INDEX";
268be771cdaSJack F Vogel 	case I40E_ERR_INVALID_SD_TYPE:
269be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_SD_TYPE";
270be771cdaSJack F Vogel 	case I40E_ERR_MEMCPY_FAILED:
271be771cdaSJack F Vogel 		return "I40E_ERR_MEMCPY_FAILED";
272be771cdaSJack F Vogel 	case I40E_ERR_INVALID_HMC_OBJ_INDEX:
273be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_HMC_OBJ_INDEX";
274be771cdaSJack F Vogel 	case I40E_ERR_INVALID_HMC_OBJ_COUNT:
275be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_HMC_OBJ_COUNT";
276be771cdaSJack F Vogel 	case I40E_ERR_INVALID_SRQ_ARM_LIMIT:
277be771cdaSJack F Vogel 		return "I40E_ERR_INVALID_SRQ_ARM_LIMIT";
278be771cdaSJack F Vogel 	case I40E_ERR_SRQ_ENABLED:
279be771cdaSJack F Vogel 		return "I40E_ERR_SRQ_ENABLED";
280be771cdaSJack F Vogel 	case I40E_ERR_ADMIN_QUEUE_ERROR:
281be771cdaSJack F Vogel 		return "I40E_ERR_ADMIN_QUEUE_ERROR";
282be771cdaSJack F Vogel 	case I40E_ERR_ADMIN_QUEUE_TIMEOUT:
283be771cdaSJack F Vogel 		return "I40E_ERR_ADMIN_QUEUE_TIMEOUT";
284be771cdaSJack F Vogel 	case I40E_ERR_BUF_TOO_SHORT:
285be771cdaSJack F Vogel 		return "I40E_ERR_BUF_TOO_SHORT";
286be771cdaSJack F Vogel 	case I40E_ERR_ADMIN_QUEUE_FULL:
287be771cdaSJack F Vogel 		return "I40E_ERR_ADMIN_QUEUE_FULL";
288be771cdaSJack F Vogel 	case I40E_ERR_ADMIN_QUEUE_NO_WORK:
289be771cdaSJack F Vogel 		return "I40E_ERR_ADMIN_QUEUE_NO_WORK";
290be771cdaSJack F Vogel 	case I40E_ERR_BAD_IWARP_CQE:
291be771cdaSJack F Vogel 		return "I40E_ERR_BAD_IWARP_CQE";
292be771cdaSJack F Vogel 	case I40E_ERR_NVM_BLANK_MODE:
293be771cdaSJack F Vogel 		return "I40E_ERR_NVM_BLANK_MODE";
294be771cdaSJack F Vogel 	case I40E_ERR_NOT_IMPLEMENTED:
295be771cdaSJack F Vogel 		return "I40E_ERR_NOT_IMPLEMENTED";
296be771cdaSJack F Vogel 	case I40E_ERR_PE_DOORBELL_NOT_ENABLED:
297be771cdaSJack F Vogel 		return "I40E_ERR_PE_DOORBELL_NOT_ENABLED";
298be771cdaSJack F Vogel 	case I40E_ERR_DIAG_TEST_FAILED:
299be771cdaSJack F Vogel 		return "I40E_ERR_DIAG_TEST_FAILED";
300be771cdaSJack F Vogel 	case I40E_ERR_NOT_READY:
301be771cdaSJack F Vogel 		return "I40E_ERR_NOT_READY";
302be771cdaSJack F Vogel 	case I40E_NOT_SUPPORTED:
303be771cdaSJack F Vogel 		return "I40E_NOT_SUPPORTED";
304be771cdaSJack F Vogel 	case I40E_ERR_FIRMWARE_API_VERSION:
305be771cdaSJack F Vogel 		return "I40E_ERR_FIRMWARE_API_VERSION";
306ceebc2f3SEric Joyner 	case I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
307ceebc2f3SEric Joyner 		return "I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
308be771cdaSJack F Vogel 	}
309be771cdaSJack F Vogel 
310be771cdaSJack F Vogel 	snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
311be771cdaSJack F Vogel 	return hw->err_str;
312be771cdaSJack F Vogel }
313be771cdaSJack F Vogel 
314be771cdaSJack F Vogel /**
31561ae650dSJack F Vogel  * i40e_debug_aq
31661ae650dSJack F Vogel  * @hw: debug mask related to admin queue
31761ae650dSJack F Vogel  * @mask: debug mask
31861ae650dSJack F Vogel  * @desc: pointer to admin queue descriptor
31961ae650dSJack F Vogel  * @buffer: pointer to command buffer
32061ae650dSJack F Vogel  * @buf_len: max length of buffer
32161ae650dSJack F Vogel  *
32261ae650dSJack F Vogel  * Dumps debug log about adminq command with descriptor contents.
32361ae650dSJack F Vogel  **/
i40e_debug_aq(struct i40e_hw * hw,enum i40e_debug_mask mask,void * desc,void * buffer,u16 buf_len)32461ae650dSJack F Vogel void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
32561ae650dSJack F Vogel 		   void *buffer, u16 buf_len)
32661ae650dSJack F Vogel {
32761ae650dSJack F Vogel 	struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
328b4a7ce06SEric Joyner 	u32 effective_mask = hw->debug_mask & mask;
329f247dc25SJack F Vogel 	u8 *buf = (u8 *)buffer;
330ceebc2f3SEric Joyner 	u16 len;
331b4a7ce06SEric Joyner 	u16 i;
33261ae650dSJack F Vogel 
333b4a7ce06SEric Joyner 	if (!effective_mask || !desc)
33461ae650dSJack F Vogel 		return;
33561ae650dSJack F Vogel 
336ceebc2f3SEric Joyner 	len = LE16_TO_CPU(aq_desc->datalen);
337ceebc2f3SEric Joyner 
338b4a7ce06SEric Joyner 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
33961ae650dSJack F Vogel 		   "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
340f247dc25SJack F Vogel 		   LE16_TO_CPU(aq_desc->opcode),
341f247dc25SJack F Vogel 		   LE16_TO_CPU(aq_desc->flags),
342f247dc25SJack F Vogel 		   LE16_TO_CPU(aq_desc->datalen),
343f247dc25SJack F Vogel 		   LE16_TO_CPU(aq_desc->retval));
344b4a7ce06SEric Joyner 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
345b4a7ce06SEric Joyner 		   "\tcookie (h,l) 0x%08X 0x%08X\n",
346f247dc25SJack F Vogel 		   LE32_TO_CPU(aq_desc->cookie_high),
347f247dc25SJack F Vogel 		   LE32_TO_CPU(aq_desc->cookie_low));
348b4a7ce06SEric Joyner 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
349b4a7ce06SEric Joyner 		   "\tparam (0,1)  0x%08X 0x%08X\n",
350f247dc25SJack F Vogel 		   LE32_TO_CPU(aq_desc->params.internal.param0),
351f247dc25SJack F Vogel 		   LE32_TO_CPU(aq_desc->params.internal.param1));
352b4a7ce06SEric Joyner 	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
353b4a7ce06SEric Joyner 		   "\taddr (h,l)   0x%08X 0x%08X\n",
354f247dc25SJack F Vogel 		   LE32_TO_CPU(aq_desc->params.external.addr_high),
355f247dc25SJack F Vogel 		   LE32_TO_CPU(aq_desc->params.external.addr_low));
35661ae650dSJack F Vogel 
357b4a7ce06SEric Joyner 	if (buffer && (buf_len != 0) && (len != 0) &&
358b4a7ce06SEric Joyner 	    (effective_mask & I40E_DEBUG_AQ_DESC_BUFFER)) {
35961ae650dSJack F Vogel 		i40e_debug(hw, mask, "AQ CMD Buffer:\n");
36061ae650dSJack F Vogel 		if (buf_len < len)
36161ae650dSJack F Vogel 			len = buf_len;
362f247dc25SJack F Vogel 		/* write the full 16-byte chunks */
363f247dc25SJack F Vogel 		for (i = 0; i < (len - 16); i += 16)
36461ae650dSJack F Vogel 			i40e_debug(hw, mask,
365f247dc25SJack F Vogel 				   "\t0x%04X  %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
366f247dc25SJack F Vogel 				   i, buf[i], buf[i+1], buf[i+2], buf[i+3],
367f247dc25SJack F Vogel 				   buf[i+4], buf[i+5], buf[i+6], buf[i+7],
368f247dc25SJack F Vogel 				   buf[i+8], buf[i+9], buf[i+10], buf[i+11],
369f247dc25SJack F Vogel 				   buf[i+12], buf[i+13], buf[i+14], buf[i+15]);
370a48d00d2SEric Joyner 		/* the most we could have left is 16 bytes, pad with zeros */
371f247dc25SJack F Vogel 		if (i < len) {
372a48d00d2SEric Joyner 			char d_buf[16];
3734294f337SSean Bruno 			int j, i_sav;
374f247dc25SJack F Vogel 
3754294f337SSean Bruno 			i_sav = i;
376f247dc25SJack F Vogel 			memset(d_buf, 0, sizeof(d_buf));
377a48d00d2SEric Joyner 			for (j = 0; i < len; j++, i++)
378a48d00d2SEric Joyner 				d_buf[j] = buf[i];
379a48d00d2SEric Joyner 			i40e_debug(hw, mask,
380a48d00d2SEric Joyner 				   "\t0x%04X  %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
3814294f337SSean Bruno 				   i_sav, d_buf[0], d_buf[1], d_buf[2], d_buf[3],
382a48d00d2SEric Joyner 				   d_buf[4], d_buf[5], d_buf[6], d_buf[7],
383a48d00d2SEric Joyner 				   d_buf[8], d_buf[9], d_buf[10], d_buf[11],
384a48d00d2SEric Joyner 				   d_buf[12], d_buf[13], d_buf[14], d_buf[15]);
38561ae650dSJack F Vogel 		}
38661ae650dSJack F Vogel 	}
38761ae650dSJack F Vogel }
38861ae650dSJack F Vogel 
38961ae650dSJack F Vogel /**
39061ae650dSJack F Vogel  * i40e_check_asq_alive
39161ae650dSJack F Vogel  * @hw: pointer to the hw struct
39261ae650dSJack F Vogel  *
39361ae650dSJack F Vogel  * Returns TRUE if Queue is enabled else FALSE.
39461ae650dSJack F Vogel  **/
i40e_check_asq_alive(struct i40e_hw * hw)39561ae650dSJack F Vogel bool i40e_check_asq_alive(struct i40e_hw *hw)
39661ae650dSJack F Vogel {
397f1b0e659SLi-Wen Hsu 	if (hw->aq.asq.len) {
398be771cdaSJack F Vogel 		if (!i40e_is_vf(hw))
399be771cdaSJack F Vogel 			return !!(rd32(hw, hw->aq.asq.len) &
400be771cdaSJack F Vogel 				I40E_PF_ATQLEN_ATQENABLE_MASK);
401f1b0e659SLi-Wen Hsu 		else
402be771cdaSJack F Vogel 			return !!(rd32(hw, hw->aq.asq.len) &
403be771cdaSJack F Vogel 				I40E_VF_ATQLEN1_ATQENABLE_MASK);
404f1b0e659SLi-Wen Hsu 	}
40561ae650dSJack F Vogel 	return FALSE;
40661ae650dSJack F Vogel }
40761ae650dSJack F Vogel 
40861ae650dSJack F Vogel /**
40961ae650dSJack F Vogel  * i40e_aq_queue_shutdown
41061ae650dSJack F Vogel  * @hw: pointer to the hw struct
41161ae650dSJack F Vogel  * @unloading: is the driver unloading itself
41261ae650dSJack F Vogel  *
41361ae650dSJack F Vogel  * Tell the Firmware that we're shutting down the AdminQ and whether
41461ae650dSJack F Vogel  * or not the driver is unloading as well.
41561ae650dSJack F Vogel  **/
i40e_aq_queue_shutdown(struct i40e_hw * hw,bool unloading)41661ae650dSJack F Vogel enum i40e_status_code i40e_aq_queue_shutdown(struct i40e_hw *hw,
41761ae650dSJack F Vogel 					     bool unloading)
41861ae650dSJack F Vogel {
41961ae650dSJack F Vogel 	struct i40e_aq_desc desc;
42061ae650dSJack F Vogel 	struct i40e_aqc_queue_shutdown *cmd =
42161ae650dSJack F Vogel 		(struct i40e_aqc_queue_shutdown *)&desc.params.raw;
42261ae650dSJack F Vogel 	enum i40e_status_code status;
42361ae650dSJack F Vogel 
42461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
42561ae650dSJack F Vogel 					  i40e_aqc_opc_queue_shutdown);
42661ae650dSJack F Vogel 
42761ae650dSJack F Vogel 	if (unloading)
42861ae650dSJack F Vogel 		cmd->driver_unloading = CPU_TO_LE32(I40E_AQ_DRIVER_UNLOADING);
42961ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
43061ae650dSJack F Vogel 
43161ae650dSJack F Vogel 	return status;
43261ae650dSJack F Vogel }
43361ae650dSJack F Vogel 
4344294f337SSean Bruno /**
4354294f337SSean Bruno  * i40e_aq_get_set_rss_lut
4364294f337SSean Bruno  * @hw: pointer to the hardware structure
4374294f337SSean Bruno  * @vsi_id: vsi fw index
4384294f337SSean Bruno  * @pf_lut: for PF table set TRUE, for VSI table set FALSE
4394294f337SSean Bruno  * @lut: pointer to the lut buffer provided by the caller
4404294f337SSean Bruno  * @lut_size: size of the lut buffer
4414294f337SSean Bruno  * @set: set TRUE to set the table, FALSE to get the table
4424294f337SSean Bruno  *
4434294f337SSean Bruno  * Internal function to get or set RSS look up table
4444294f337SSean Bruno  **/
i40e_aq_get_set_rss_lut(struct i40e_hw * hw,u16 vsi_id,bool pf_lut,u8 * lut,u16 lut_size,bool set)4454294f337SSean Bruno static enum i40e_status_code i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
4464294f337SSean Bruno 						     u16 vsi_id, bool pf_lut,
4474294f337SSean Bruno 						     u8 *lut, u16 lut_size,
4484294f337SSean Bruno 						     bool set)
4494294f337SSean Bruno {
4504294f337SSean Bruno 	enum i40e_status_code status;
4514294f337SSean Bruno 	struct i40e_aq_desc desc;
4524294f337SSean Bruno 	struct i40e_aqc_get_set_rss_lut *cmd_resp =
4534294f337SSean Bruno 		   (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw;
4544294f337SSean Bruno 
4554294f337SSean Bruno 	if (set)
4564294f337SSean Bruno 		i40e_fill_default_direct_cmd_desc(&desc,
4574294f337SSean Bruno 						  i40e_aqc_opc_set_rss_lut);
4584294f337SSean Bruno 	else
4594294f337SSean Bruno 		i40e_fill_default_direct_cmd_desc(&desc,
4604294f337SSean Bruno 						  i40e_aqc_opc_get_rss_lut);
4614294f337SSean Bruno 
4624294f337SSean Bruno 	/* Indirect command */
4634294f337SSean Bruno 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4644294f337SSean Bruno 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
4654294f337SSean Bruno 
4664294f337SSean Bruno 	cmd_resp->vsi_id =
4674294f337SSean Bruno 			CPU_TO_LE16((u16)((vsi_id <<
4684294f337SSean Bruno 					  I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
4694294f337SSean Bruno 					  I40E_AQC_SET_RSS_LUT_VSI_ID_MASK));
4704294f337SSean Bruno 	cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_LUT_VSI_VALID);
4714294f337SSean Bruno 
4724294f337SSean Bruno 	if (pf_lut)
4734294f337SSean Bruno 		cmd_resp->flags |= CPU_TO_LE16((u16)
4744294f337SSean Bruno 					((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
4754294f337SSean Bruno 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
4764294f337SSean Bruno 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
4774294f337SSean Bruno 	else
4784294f337SSean Bruno 		cmd_resp->flags |= CPU_TO_LE16((u16)
4794294f337SSean Bruno 					((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
4804294f337SSean Bruno 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
4814294f337SSean Bruno 					I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
4824294f337SSean Bruno 
4834294f337SSean Bruno 	status = i40e_asq_send_command(hw, &desc, lut, lut_size, NULL);
4844294f337SSean Bruno 
4854294f337SSean Bruno 	return status;
4864294f337SSean Bruno }
4874294f337SSean Bruno 
4884294f337SSean Bruno /**
4894294f337SSean Bruno  * i40e_aq_get_rss_lut
4904294f337SSean Bruno  * @hw: pointer to the hardware structure
4914294f337SSean Bruno  * @vsi_id: vsi fw index
4924294f337SSean Bruno  * @pf_lut: for PF table set TRUE, for VSI table set FALSE
4934294f337SSean Bruno  * @lut: pointer to the lut buffer provided by the caller
4944294f337SSean Bruno  * @lut_size: size of the lut buffer
4954294f337SSean Bruno  *
4964294f337SSean Bruno  * get the RSS lookup table, PF or VSI type
4974294f337SSean Bruno  **/
i40e_aq_get_rss_lut(struct i40e_hw * hw,u16 vsi_id,bool pf_lut,u8 * lut,u16 lut_size)4984294f337SSean Bruno enum i40e_status_code i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
4994294f337SSean Bruno 					  bool pf_lut, u8 *lut, u16 lut_size)
5004294f337SSean Bruno {
5014294f337SSean Bruno 	return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
5024294f337SSean Bruno 				       FALSE);
5034294f337SSean Bruno }
5044294f337SSean Bruno 
5054294f337SSean Bruno /**
5064294f337SSean Bruno  * i40e_aq_set_rss_lut
5074294f337SSean Bruno  * @hw: pointer to the hardware structure
5084294f337SSean Bruno  * @vsi_id: vsi fw index
5094294f337SSean Bruno  * @pf_lut: for PF table set TRUE, for VSI table set FALSE
5104294f337SSean Bruno  * @lut: pointer to the lut buffer provided by the caller
5114294f337SSean Bruno  * @lut_size: size of the lut buffer
5124294f337SSean Bruno  *
5134294f337SSean Bruno  * set the RSS lookup table, PF or VSI type
5144294f337SSean Bruno  **/
i40e_aq_set_rss_lut(struct i40e_hw * hw,u16 vsi_id,bool pf_lut,u8 * lut,u16 lut_size)5154294f337SSean Bruno enum i40e_status_code i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
5164294f337SSean Bruno 					  bool pf_lut, u8 *lut, u16 lut_size)
5174294f337SSean Bruno {
5184294f337SSean Bruno 	return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, TRUE);
5194294f337SSean Bruno }
5204294f337SSean Bruno 
5214294f337SSean Bruno /**
5224294f337SSean Bruno  * i40e_aq_get_set_rss_key
5234294f337SSean Bruno  * @hw: pointer to the hw struct
5244294f337SSean Bruno  * @vsi_id: vsi fw index
5254294f337SSean Bruno  * @key: pointer to key info struct
5264294f337SSean Bruno  * @set: set TRUE to set the key, FALSE to get the key
5274294f337SSean Bruno  *
5284294f337SSean Bruno  * get the RSS key per VSI
5294294f337SSean Bruno  **/
i40e_aq_get_set_rss_key(struct i40e_hw * hw,u16 vsi_id,struct i40e_aqc_get_set_rss_key_data * key,bool set)5304294f337SSean Bruno static enum i40e_status_code i40e_aq_get_set_rss_key(struct i40e_hw *hw,
5314294f337SSean Bruno 				      u16 vsi_id,
5324294f337SSean Bruno 				      struct i40e_aqc_get_set_rss_key_data *key,
5334294f337SSean Bruno 				      bool set)
5344294f337SSean Bruno {
5354294f337SSean Bruno 	enum i40e_status_code status;
5364294f337SSean Bruno 	struct i40e_aq_desc desc;
5374294f337SSean Bruno 	struct i40e_aqc_get_set_rss_key *cmd_resp =
5384294f337SSean Bruno 			(struct i40e_aqc_get_set_rss_key *)&desc.params.raw;
5394294f337SSean Bruno 	u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data);
5404294f337SSean Bruno 
5414294f337SSean Bruno 	if (set)
5424294f337SSean Bruno 		i40e_fill_default_direct_cmd_desc(&desc,
5434294f337SSean Bruno 						  i40e_aqc_opc_set_rss_key);
5444294f337SSean Bruno 	else
5454294f337SSean Bruno 		i40e_fill_default_direct_cmd_desc(&desc,
5464294f337SSean Bruno 						  i40e_aqc_opc_get_rss_key);
5474294f337SSean Bruno 
5484294f337SSean Bruno 	/* Indirect command */
5494294f337SSean Bruno 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
5504294f337SSean Bruno 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
5514294f337SSean Bruno 
5524294f337SSean Bruno 	cmd_resp->vsi_id =
5534294f337SSean Bruno 			CPU_TO_LE16((u16)((vsi_id <<
5544294f337SSean Bruno 					  I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
5554294f337SSean Bruno 					  I40E_AQC_SET_RSS_KEY_VSI_ID_MASK));
5564294f337SSean Bruno 	cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_KEY_VSI_VALID);
5574294f337SSean Bruno 
5584294f337SSean Bruno 	status = i40e_asq_send_command(hw, &desc, key, key_size, NULL);
5594294f337SSean Bruno 
5604294f337SSean Bruno 	return status;
5614294f337SSean Bruno }
5624294f337SSean Bruno 
5634294f337SSean Bruno /**
5644294f337SSean Bruno  * i40e_aq_get_rss_key
5654294f337SSean Bruno  * @hw: pointer to the hw struct
5664294f337SSean Bruno  * @vsi_id: vsi fw index
5674294f337SSean Bruno  * @key: pointer to key info struct
5684294f337SSean Bruno  *
5694294f337SSean Bruno  **/
i40e_aq_get_rss_key(struct i40e_hw * hw,u16 vsi_id,struct i40e_aqc_get_set_rss_key_data * key)5704294f337SSean Bruno enum i40e_status_code i40e_aq_get_rss_key(struct i40e_hw *hw,
5714294f337SSean Bruno 				      u16 vsi_id,
5724294f337SSean Bruno 				      struct i40e_aqc_get_set_rss_key_data *key)
5734294f337SSean Bruno {
5744294f337SSean Bruno 	return i40e_aq_get_set_rss_key(hw, vsi_id, key, FALSE);
5754294f337SSean Bruno }
5764294f337SSean Bruno 
5774294f337SSean Bruno /**
5784294f337SSean Bruno  * i40e_aq_set_rss_key
5794294f337SSean Bruno  * @hw: pointer to the hw struct
5804294f337SSean Bruno  * @vsi_id: vsi fw index
5814294f337SSean Bruno  * @key: pointer to key info struct
5824294f337SSean Bruno  *
5834294f337SSean Bruno  * set the RSS key per VSI
5844294f337SSean Bruno  **/
i40e_aq_set_rss_key(struct i40e_hw * hw,u16 vsi_id,struct i40e_aqc_get_set_rss_key_data * key)5854294f337SSean Bruno enum i40e_status_code i40e_aq_set_rss_key(struct i40e_hw *hw,
5864294f337SSean Bruno 				      u16 vsi_id,
5874294f337SSean Bruno 				      struct i40e_aqc_get_set_rss_key_data *key)
5884294f337SSean Bruno {
5894294f337SSean Bruno 	return i40e_aq_get_set_rss_key(hw, vsi_id, key, TRUE);
5904294f337SSean Bruno }
5914294f337SSean Bruno 
59261ae650dSJack F Vogel /* The i40e_ptype_lookup table is used to convert from the 8-bit ptype in the
59361ae650dSJack F Vogel  * hardware to a bit-field that can be used by SW to more easily determine the
59461ae650dSJack F Vogel  * packet type.
59561ae650dSJack F Vogel  *
59661ae650dSJack F Vogel  * Macros are used to shorten the table lines and make this table human
59761ae650dSJack F Vogel  * readable.
59861ae650dSJack F Vogel  *
59961ae650dSJack F Vogel  * We store the PTYPE in the top byte of the bit field - this is just so that
60061ae650dSJack F Vogel  * we can check that the table doesn't have a row missing, as the index into
60161ae650dSJack F Vogel  * the table should be the PTYPE.
60261ae650dSJack F Vogel  *
60361ae650dSJack F Vogel  * Typical work flow:
60461ae650dSJack F Vogel  *
60561ae650dSJack F Vogel  * IF NOT i40e_ptype_lookup[ptype].known
60661ae650dSJack F Vogel  * THEN
60761ae650dSJack F Vogel  *      Packet is unknown
60861ae650dSJack F Vogel  * ELSE IF i40e_ptype_lookup[ptype].outer_ip == I40E_RX_PTYPE_OUTER_IP
60961ae650dSJack F Vogel  *      Use the rest of the fields to look at the tunnels, inner protocols, etc
61061ae650dSJack F Vogel  * ELSE
61161ae650dSJack F Vogel  *      Use the enum i40e_rx_l2_ptype to decode the packet type
61261ae650dSJack F Vogel  * ENDIF
61361ae650dSJack F Vogel  */
61461ae650dSJack F Vogel 
61561ae650dSJack F Vogel /* macro to make the table lines short */
61661ae650dSJack F Vogel #define I40E_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\
61761ae650dSJack F Vogel 	{	PTYPE, \
61861ae650dSJack F Vogel 		1, \
61961ae650dSJack F Vogel 		I40E_RX_PTYPE_OUTER_##OUTER_IP, \
62061ae650dSJack F Vogel 		I40E_RX_PTYPE_OUTER_##OUTER_IP_VER, \
62161ae650dSJack F Vogel 		I40E_RX_PTYPE_##OUTER_FRAG, \
62261ae650dSJack F Vogel 		I40E_RX_PTYPE_TUNNEL_##T, \
62361ae650dSJack F Vogel 		I40E_RX_PTYPE_TUNNEL_END_##TE, \
62461ae650dSJack F Vogel 		I40E_RX_PTYPE_##TEF, \
62561ae650dSJack F Vogel 		I40E_RX_PTYPE_INNER_PROT_##I, \
62661ae650dSJack F Vogel 		I40E_RX_PTYPE_PAYLOAD_LAYER_##PL }
62761ae650dSJack F Vogel 
62861ae650dSJack F Vogel #define I40E_PTT_UNUSED_ENTRY(PTYPE) \
62961ae650dSJack F Vogel 		{ PTYPE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
63061ae650dSJack F Vogel 
63161ae650dSJack F Vogel /* shorter macros makes the table fit but are terse */
63261ae650dSJack F Vogel #define I40E_RX_PTYPE_NOF		I40E_RX_PTYPE_NOT_FRAG
63361ae650dSJack F Vogel #define I40E_RX_PTYPE_FRG		I40E_RX_PTYPE_FRAG
63461ae650dSJack F Vogel #define I40E_RX_PTYPE_INNER_PROT_TS	I40E_RX_PTYPE_INNER_PROT_TIMESYNC
63561ae650dSJack F Vogel 
63661ae650dSJack F Vogel /* Lookup table mapping the HW PTYPE to the bit field for decoding */
63761ae650dSJack F Vogel struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {
63861ae650dSJack F Vogel 	/* L2 Packet types */
63961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(0),
64061ae650dSJack F Vogel 	I40E_PTT(1,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
64161ae650dSJack F Vogel 	I40E_PTT(2,  L2, NONE, NOF, NONE, NONE, NOF, TS,   PAY2),
64261ae650dSJack F Vogel 	I40E_PTT(3,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
64361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(4),
64461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(5),
64561ae650dSJack F Vogel 	I40E_PTT(6,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
64661ae650dSJack F Vogel 	I40E_PTT(7,  L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
64761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(8),
64861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(9),
64961ae650dSJack F Vogel 	I40E_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
65061ae650dSJack F Vogel 	I40E_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
65161ae650dSJack F Vogel 	I40E_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65261ae650dSJack F Vogel 	I40E_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65361ae650dSJack F Vogel 	I40E_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65461ae650dSJack F Vogel 	I40E_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65561ae650dSJack F Vogel 	I40E_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65661ae650dSJack F Vogel 	I40E_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65761ae650dSJack F Vogel 	I40E_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65861ae650dSJack F Vogel 	I40E_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
65961ae650dSJack F Vogel 	I40E_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
66061ae650dSJack F Vogel 	I40E_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
66161ae650dSJack F Vogel 
66261ae650dSJack F Vogel 	/* Non Tunneled IPv4 */
66361ae650dSJack F Vogel 	I40E_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
66461ae650dSJack F Vogel 	I40E_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
66561ae650dSJack F Vogel 	I40E_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP,  PAY4),
66661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(25),
66761ae650dSJack F Vogel 	I40E_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP,  PAY4),
66861ae650dSJack F Vogel 	I40E_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
66961ae650dSJack F Vogel 	I40E_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
67061ae650dSJack F Vogel 
67161ae650dSJack F Vogel 	/* IPv4 --> IPv4 */
67261ae650dSJack F Vogel 	I40E_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
67361ae650dSJack F Vogel 	I40E_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
67461ae650dSJack F Vogel 	I40E_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP,  PAY4),
67561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(32),
67661ae650dSJack F Vogel 	I40E_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP,  PAY4),
67761ae650dSJack F Vogel 	I40E_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
67861ae650dSJack F Vogel 	I40E_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
67961ae650dSJack F Vogel 
68061ae650dSJack F Vogel 	/* IPv4 --> IPv6 */
68161ae650dSJack F Vogel 	I40E_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
68261ae650dSJack F Vogel 	I40E_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
68361ae650dSJack F Vogel 	I40E_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP,  PAY4),
68461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(39),
68561ae650dSJack F Vogel 	I40E_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP,  PAY4),
68661ae650dSJack F Vogel 	I40E_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
68761ae650dSJack F Vogel 	I40E_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
68861ae650dSJack F Vogel 
68961ae650dSJack F Vogel 	/* IPv4 --> GRE/NAT */
69061ae650dSJack F Vogel 	I40E_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
69161ae650dSJack F Vogel 
69261ae650dSJack F Vogel 	/* IPv4 --> GRE/NAT --> IPv4 */
69361ae650dSJack F Vogel 	I40E_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
69461ae650dSJack F Vogel 	I40E_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
69561ae650dSJack F Vogel 	I40E_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP,  PAY4),
69661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(47),
69761ae650dSJack F Vogel 	I40E_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP,  PAY4),
69861ae650dSJack F Vogel 	I40E_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
69961ae650dSJack F Vogel 	I40E_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
70061ae650dSJack F Vogel 
70161ae650dSJack F Vogel 	/* IPv4 --> GRE/NAT --> IPv6 */
70261ae650dSJack F Vogel 	I40E_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
70361ae650dSJack F Vogel 	I40E_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
70461ae650dSJack F Vogel 	I40E_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP,  PAY4),
70561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(54),
70661ae650dSJack F Vogel 	I40E_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP,  PAY4),
70761ae650dSJack F Vogel 	I40E_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
70861ae650dSJack F Vogel 	I40E_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
70961ae650dSJack F Vogel 
71061ae650dSJack F Vogel 	/* IPv4 --> GRE/NAT --> MAC */
71161ae650dSJack F Vogel 	I40E_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
71261ae650dSJack F Vogel 
71361ae650dSJack F Vogel 	/* IPv4 --> GRE/NAT --> MAC --> IPv4 */
71461ae650dSJack F Vogel 	I40E_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
71561ae650dSJack F Vogel 	I40E_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
71661ae650dSJack F Vogel 	I40E_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP,  PAY4),
71761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(62),
71861ae650dSJack F Vogel 	I40E_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP,  PAY4),
71961ae650dSJack F Vogel 	I40E_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
72061ae650dSJack F Vogel 	I40E_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
72161ae650dSJack F Vogel 
72261ae650dSJack F Vogel 	/* IPv4 --> GRE/NAT -> MAC --> IPv6 */
72361ae650dSJack F Vogel 	I40E_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
72461ae650dSJack F Vogel 	I40E_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
72561ae650dSJack F Vogel 	I40E_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP,  PAY4),
72661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(69),
72761ae650dSJack F Vogel 	I40E_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP,  PAY4),
72861ae650dSJack F Vogel 	I40E_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
72961ae650dSJack F Vogel 	I40E_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
73061ae650dSJack F Vogel 
73161ae650dSJack F Vogel 	/* IPv4 --> GRE/NAT --> MAC/VLAN */
73261ae650dSJack F Vogel 	I40E_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
73361ae650dSJack F Vogel 
73461ae650dSJack F Vogel 	/* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
73561ae650dSJack F Vogel 	I40E_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
73661ae650dSJack F Vogel 	I40E_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
73761ae650dSJack F Vogel 	I40E_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP,  PAY4),
73861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(77),
73961ae650dSJack F Vogel 	I40E_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP,  PAY4),
74061ae650dSJack F Vogel 	I40E_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
74161ae650dSJack F Vogel 	I40E_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
74261ae650dSJack F Vogel 
74361ae650dSJack F Vogel 	/* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
74461ae650dSJack F Vogel 	I40E_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
74561ae650dSJack F Vogel 	I40E_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
74661ae650dSJack F Vogel 	I40E_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP,  PAY4),
74761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(84),
74861ae650dSJack F Vogel 	I40E_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP,  PAY4),
74961ae650dSJack F Vogel 	I40E_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
75061ae650dSJack F Vogel 	I40E_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
75161ae650dSJack F Vogel 
75261ae650dSJack F Vogel 	/* Non Tunneled IPv6 */
75361ae650dSJack F Vogel 	I40E_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
75461ae650dSJack F Vogel 	I40E_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
7554294f337SSean Bruno 	I40E_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP,  PAY4),
75661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(91),
75761ae650dSJack F Vogel 	I40E_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP,  PAY4),
75861ae650dSJack F Vogel 	I40E_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
75961ae650dSJack F Vogel 	I40E_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
76061ae650dSJack F Vogel 
76161ae650dSJack F Vogel 	/* IPv6 --> IPv4 */
76261ae650dSJack F Vogel 	I40E_PTT(95,  IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
76361ae650dSJack F Vogel 	I40E_PTT(96,  IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
76461ae650dSJack F Vogel 	I40E_PTT(97,  IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP,  PAY4),
76561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(98),
76661ae650dSJack F Vogel 	I40E_PTT(99,  IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP,  PAY4),
76761ae650dSJack F Vogel 	I40E_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
76861ae650dSJack F Vogel 	I40E_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
76961ae650dSJack F Vogel 
77061ae650dSJack F Vogel 	/* IPv6 --> IPv6 */
77161ae650dSJack F Vogel 	I40E_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
77261ae650dSJack F Vogel 	I40E_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
77361ae650dSJack F Vogel 	I40E_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP,  PAY4),
77461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(105),
77561ae650dSJack F Vogel 	I40E_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP,  PAY4),
77661ae650dSJack F Vogel 	I40E_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
77761ae650dSJack F Vogel 	I40E_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
77861ae650dSJack F Vogel 
77961ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT */
78061ae650dSJack F Vogel 	I40E_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
78161ae650dSJack F Vogel 
78261ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> IPv4 */
78361ae650dSJack F Vogel 	I40E_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
78461ae650dSJack F Vogel 	I40E_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
78561ae650dSJack F Vogel 	I40E_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP,  PAY4),
78661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(113),
78761ae650dSJack F Vogel 	I40E_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP,  PAY4),
78861ae650dSJack F Vogel 	I40E_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
78961ae650dSJack F Vogel 	I40E_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
79061ae650dSJack F Vogel 
79161ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> IPv6 */
79261ae650dSJack F Vogel 	I40E_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
79361ae650dSJack F Vogel 	I40E_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
79461ae650dSJack F Vogel 	I40E_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP,  PAY4),
79561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(120),
79661ae650dSJack F Vogel 	I40E_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP,  PAY4),
79761ae650dSJack F Vogel 	I40E_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
79861ae650dSJack F Vogel 	I40E_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
79961ae650dSJack F Vogel 
80061ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> MAC */
80161ae650dSJack F Vogel 	I40E_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
80261ae650dSJack F Vogel 
80361ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> MAC -> IPv4 */
80461ae650dSJack F Vogel 	I40E_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
80561ae650dSJack F Vogel 	I40E_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
80661ae650dSJack F Vogel 	I40E_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP,  PAY4),
80761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(128),
80861ae650dSJack F Vogel 	I40E_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP,  PAY4),
80961ae650dSJack F Vogel 	I40E_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
81061ae650dSJack F Vogel 	I40E_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
81161ae650dSJack F Vogel 
81261ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> MAC -> IPv6 */
81361ae650dSJack F Vogel 	I40E_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
81461ae650dSJack F Vogel 	I40E_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
81561ae650dSJack F Vogel 	I40E_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP,  PAY4),
81661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(135),
81761ae650dSJack F Vogel 	I40E_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP,  PAY4),
81861ae650dSJack F Vogel 	I40E_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
81961ae650dSJack F Vogel 	I40E_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
82061ae650dSJack F Vogel 
82161ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> MAC/VLAN */
82261ae650dSJack F Vogel 	I40E_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
82361ae650dSJack F Vogel 
82461ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
82561ae650dSJack F Vogel 	I40E_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
82661ae650dSJack F Vogel 	I40E_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
82761ae650dSJack F Vogel 	I40E_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP,  PAY4),
82861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(143),
82961ae650dSJack F Vogel 	I40E_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP,  PAY4),
83061ae650dSJack F Vogel 	I40E_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
83161ae650dSJack F Vogel 	I40E_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
83261ae650dSJack F Vogel 
83361ae650dSJack F Vogel 	/* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
83461ae650dSJack F Vogel 	I40E_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
83561ae650dSJack F Vogel 	I40E_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
83661ae650dSJack F Vogel 	I40E_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP,  PAY4),
83761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(150),
83861ae650dSJack F Vogel 	I40E_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP,  PAY4),
83961ae650dSJack F Vogel 	I40E_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
84061ae650dSJack F Vogel 	I40E_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
84161ae650dSJack F Vogel 
84261ae650dSJack F Vogel 	/* unused entries */
84361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(154),
84461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(155),
84561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(156),
84661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(157),
84761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(158),
84861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(159),
84961ae650dSJack F Vogel 
85061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(160),
85161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(161),
85261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(162),
85361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(163),
85461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(164),
85561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(165),
85661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(166),
85761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(167),
85861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(168),
85961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(169),
86061ae650dSJack F Vogel 
86161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(170),
86261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(171),
86361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(172),
86461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(173),
86561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(174),
86661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(175),
86761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(176),
86861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(177),
86961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(178),
87061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(179),
87161ae650dSJack F Vogel 
87261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(180),
87361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(181),
87461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(182),
87561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(183),
87661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(184),
87761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(185),
87861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(186),
87961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(187),
88061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(188),
88161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(189),
88261ae650dSJack F Vogel 
88361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(190),
88461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(191),
88561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(192),
88661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(193),
88761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(194),
88861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(195),
88961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(196),
89061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(197),
89161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(198),
89261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(199),
89361ae650dSJack F Vogel 
89461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(200),
89561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(201),
89661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(202),
89761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(203),
89861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(204),
89961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(205),
90061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(206),
90161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(207),
90261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(208),
90361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(209),
90461ae650dSJack F Vogel 
90561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(210),
90661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(211),
90761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(212),
90861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(213),
90961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(214),
91061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(215),
91161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(216),
91261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(217),
91361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(218),
91461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(219),
91561ae650dSJack F Vogel 
91661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(220),
91761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(221),
91861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(222),
91961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(223),
92061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(224),
92161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(225),
92261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(226),
92361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(227),
92461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(228),
92561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(229),
92661ae650dSJack F Vogel 
92761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(230),
92861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(231),
92961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(232),
93061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(233),
93161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(234),
93261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(235),
93361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(236),
93461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(237),
93561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(238),
93661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(239),
93761ae650dSJack F Vogel 
93861ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(240),
93961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(241),
94061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(242),
94161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(243),
94261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(244),
94361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(245),
94461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(246),
94561ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(247),
94661ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(248),
94761ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(249),
94861ae650dSJack F Vogel 
94961ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(250),
95061ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(251),
95161ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(252),
95261ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(253),
95361ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(254),
95461ae650dSJack F Vogel 	I40E_PTT_UNUSED_ENTRY(255)
95561ae650dSJack F Vogel };
95661ae650dSJack F Vogel 
95761ae650dSJack F Vogel 
95861ae650dSJack F Vogel /**
959f247dc25SJack F Vogel  * i40e_validate_mac_addr - Validate unicast MAC address
960f247dc25SJack F Vogel  * @mac_addr: pointer to MAC address
961f247dc25SJack F Vogel  *
962f247dc25SJack F Vogel  * Tests a MAC address to ensure it is a valid Individual Address
963f247dc25SJack F Vogel  **/
i40e_validate_mac_addr(u8 * mac_addr)964f247dc25SJack F Vogel enum i40e_status_code i40e_validate_mac_addr(u8 *mac_addr)
965f247dc25SJack F Vogel {
966f247dc25SJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
967f247dc25SJack F Vogel 
968f247dc25SJack F Vogel 	DEBUGFUNC("i40e_validate_mac_addr");
969f247dc25SJack F Vogel 
970f247dc25SJack F Vogel 	/* Broadcast addresses ARE multicast addresses
971f247dc25SJack F Vogel 	 * Make sure it is not a multicast address
972f247dc25SJack F Vogel 	 * Reject the zero address
973f247dc25SJack F Vogel 	 */
974f247dc25SJack F Vogel 	if (I40E_IS_MULTICAST(mac_addr) ||
975f247dc25SJack F Vogel 	    (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
976f247dc25SJack F Vogel 	      mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0))
977f247dc25SJack F Vogel 		status = I40E_ERR_INVALID_MAC_ADDR;
978f247dc25SJack F Vogel 
979f247dc25SJack F Vogel 	return status;
980f247dc25SJack F Vogel }
981f247dc25SJack F Vogel 
982f247dc25SJack F Vogel /**
98361ae650dSJack F Vogel  * i40e_init_shared_code - Initialize the shared code
98461ae650dSJack F Vogel  * @hw: pointer to hardware structure
98561ae650dSJack F Vogel  *
98661ae650dSJack F Vogel  * This assigns the MAC type and PHY code and inits the NVM.
98761ae650dSJack F Vogel  * Does not touch the hardware. This function must be called prior to any
98861ae650dSJack F Vogel  * other function in the shared code. The i40e_hw structure should be
98961ae650dSJack F Vogel  * memset to 0 prior to calling this function.  The following fields in
99061ae650dSJack F Vogel  * hw structure should be filled in prior to calling this function:
99161ae650dSJack F Vogel  * hw_addr, back, device_id, vendor_id, subsystem_device_id,
99261ae650dSJack F Vogel  * subsystem_vendor_id, and revision_id
99361ae650dSJack F Vogel  **/
i40e_init_shared_code(struct i40e_hw * hw)99461ae650dSJack F Vogel enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw)
99561ae650dSJack F Vogel {
99661ae650dSJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
997f247dc25SJack F Vogel 	u32 port, ari, func_rid;
99861ae650dSJack F Vogel 
99961ae650dSJack F Vogel 	DEBUGFUNC("i40e_init_shared_code");
100061ae650dSJack F Vogel 
100161ae650dSJack F Vogel 	i40e_set_mac_type(hw);
100261ae650dSJack F Vogel 
100361ae650dSJack F Vogel 	switch (hw->mac.type) {
100461ae650dSJack F Vogel 	case I40E_MAC_XL710:
10054294f337SSean Bruno 	case I40E_MAC_X722:
100661ae650dSJack F Vogel 		break;
100761ae650dSJack F Vogel 	default:
100861ae650dSJack F Vogel 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
100961ae650dSJack F Vogel 	}
101061ae650dSJack F Vogel 
101161ae650dSJack F Vogel 	hw->phy.get_link_info = TRUE;
101261ae650dSJack F Vogel 
1013f247dc25SJack F Vogel 	/* Determine port number and PF number*/
1014f247dc25SJack F Vogel 	port = (rd32(hw, I40E_PFGEN_PORTNUM) & I40E_PFGEN_PORTNUM_PORT_NUM_MASK)
1015f247dc25SJack F Vogel 					   >> I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
1016f247dc25SJack F Vogel 	hw->port = (u8)port;
1017f247dc25SJack F Vogel 	ari = (rd32(hw, I40E_GLPCI_CAPSUP) & I40E_GLPCI_CAPSUP_ARI_EN_MASK) >>
1018f247dc25SJack F Vogel 						 I40E_GLPCI_CAPSUP_ARI_EN_SHIFT;
1019f247dc25SJack F Vogel 	func_rid = rd32(hw, I40E_PF_FUNC_RID);
1020f247dc25SJack F Vogel 	if (ari)
1021f247dc25SJack F Vogel 		hw->pf_id = (u8)(func_rid & 0xff);
102261ae650dSJack F Vogel 	else
1023f247dc25SJack F Vogel 		hw->pf_id = (u8)(func_rid & 0x7);
102461ae650dSJack F Vogel 
1025b4a7ce06SEric Joyner 	/* NVMUpdate features structure initialization */
1026b4a7ce06SEric Joyner 	hw->nvmupd_features.major = I40E_NVMUPD_FEATURES_API_VER_MAJOR;
1027b4a7ce06SEric Joyner 	hw->nvmupd_features.minor = I40E_NVMUPD_FEATURES_API_VER_MINOR;
1028b4a7ce06SEric Joyner 	hw->nvmupd_features.size = sizeof(hw->nvmupd_features);
1029b4a7ce06SEric Joyner 	i40e_memset(hw->nvmupd_features.features, 0x0,
1030b4a7ce06SEric Joyner 		    I40E_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN *
1031b4a7ce06SEric Joyner 		    sizeof(*hw->nvmupd_features.features),
1032b4a7ce06SEric Joyner 		    I40E_NONDMA_MEM);
1033b4a7ce06SEric Joyner 
1034b4a7ce06SEric Joyner 	/* No features supported at the moment */
1035b4a7ce06SEric Joyner 	hw->nvmupd_features.features[0] = 0;
10364294f337SSean Bruno 
103761ae650dSJack F Vogel 	status = i40e_init_nvm(hw);
103861ae650dSJack F Vogel 	return status;
103961ae650dSJack F Vogel }
104061ae650dSJack F Vogel 
104161ae650dSJack F Vogel /**
104261ae650dSJack F Vogel  * i40e_aq_mac_address_read - Retrieve the MAC addresses
104361ae650dSJack F Vogel  * @hw: pointer to the hw struct
104461ae650dSJack F Vogel  * @flags: a return indicator of what addresses were added to the addr store
104561ae650dSJack F Vogel  * @addrs: the requestor's mac addr store
104661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
104761ae650dSJack F Vogel  **/
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)104861ae650dSJack F Vogel static enum i40e_status_code i40e_aq_mac_address_read(struct i40e_hw *hw,
104961ae650dSJack F Vogel 				   u16 *flags,
105061ae650dSJack F Vogel 				   struct i40e_aqc_mac_address_read_data *addrs,
105161ae650dSJack F Vogel 				   struct i40e_asq_cmd_details *cmd_details)
105261ae650dSJack F Vogel {
105361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
105461ae650dSJack F Vogel 	struct i40e_aqc_mac_address_read *cmd_data =
105561ae650dSJack F Vogel 		(struct i40e_aqc_mac_address_read *)&desc.params.raw;
105661ae650dSJack F Vogel 	enum i40e_status_code status;
105761ae650dSJack F Vogel 
105861ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_mac_address_read);
105961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
106061ae650dSJack F Vogel 
106161ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, addrs,
106261ae650dSJack F Vogel 				       sizeof(*addrs), cmd_details);
106361ae650dSJack F Vogel 	*flags = LE16_TO_CPU(cmd_data->command_flags);
106461ae650dSJack F Vogel 
106561ae650dSJack F Vogel 	return status;
106661ae650dSJack F Vogel }
106761ae650dSJack F Vogel 
106861ae650dSJack F Vogel /**
106961ae650dSJack F Vogel  * i40e_aq_mac_address_write - Change the MAC addresses
107061ae650dSJack F Vogel  * @hw: pointer to the hw struct
107161ae650dSJack F Vogel  * @flags: indicates which MAC to be written
107261ae650dSJack F Vogel  * @mac_addr: address to write
107361ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
107461ae650dSJack F Vogel  **/
i40e_aq_mac_address_write(struct i40e_hw * hw,u16 flags,u8 * mac_addr,struct i40e_asq_cmd_details * cmd_details)107561ae650dSJack F Vogel enum i40e_status_code i40e_aq_mac_address_write(struct i40e_hw *hw,
107661ae650dSJack F Vogel 				    u16 flags, u8 *mac_addr,
107761ae650dSJack F Vogel 				    struct i40e_asq_cmd_details *cmd_details)
107861ae650dSJack F Vogel {
107961ae650dSJack F Vogel 	struct i40e_aq_desc desc;
108061ae650dSJack F Vogel 	struct i40e_aqc_mac_address_write *cmd_data =
108161ae650dSJack F Vogel 		(struct i40e_aqc_mac_address_write *)&desc.params.raw;
108261ae650dSJack F Vogel 	enum i40e_status_code status;
108361ae650dSJack F Vogel 
108461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
108561ae650dSJack F Vogel 					  i40e_aqc_opc_mac_address_write);
108661ae650dSJack F Vogel 	cmd_data->command_flags = CPU_TO_LE16(flags);
108761ae650dSJack F Vogel 	cmd_data->mac_sah = CPU_TO_LE16((u16)mac_addr[0] << 8 | mac_addr[1]);
108861ae650dSJack F Vogel 	cmd_data->mac_sal = CPU_TO_LE32(((u32)mac_addr[2] << 24) |
108961ae650dSJack F Vogel 					((u32)mac_addr[3] << 16) |
109061ae650dSJack F Vogel 					((u32)mac_addr[4] << 8) |
109161ae650dSJack F Vogel 					mac_addr[5]);
109261ae650dSJack F Vogel 
109361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
109461ae650dSJack F Vogel 
109561ae650dSJack F Vogel 	return status;
109661ae650dSJack F Vogel }
109761ae650dSJack F Vogel 
109861ae650dSJack F Vogel /**
109961ae650dSJack F Vogel  * i40e_get_mac_addr - get MAC address
110061ae650dSJack F Vogel  * @hw: pointer to the HW structure
110161ae650dSJack F Vogel  * @mac_addr: pointer to MAC address
110261ae650dSJack F Vogel  *
110361ae650dSJack F Vogel  * Reads the adapter's MAC address from register
110461ae650dSJack F Vogel  **/
i40e_get_mac_addr(struct i40e_hw * hw,u8 * mac_addr)110561ae650dSJack F Vogel enum i40e_status_code i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
110661ae650dSJack F Vogel {
110761ae650dSJack F Vogel 	struct i40e_aqc_mac_address_read_data addrs;
110861ae650dSJack F Vogel 	enum i40e_status_code status;
110961ae650dSJack F Vogel 	u16 flags = 0;
111061ae650dSJack F Vogel 
111161ae650dSJack F Vogel 	status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
111261ae650dSJack F Vogel 
111361ae650dSJack F Vogel 	if (flags & I40E_AQC_LAN_ADDR_VALID)
1114cb6b8299SEric Joyner 		i40e_memcpy(mac_addr, &addrs.pf_lan_mac, sizeof(addrs.pf_lan_mac),
1115cb6b8299SEric Joyner 			I40E_NONDMA_TO_NONDMA);
111661ae650dSJack F Vogel 
111761ae650dSJack F Vogel 	return status;
111861ae650dSJack F Vogel }
111961ae650dSJack F Vogel 
112061ae650dSJack F Vogel /**
112161ae650dSJack F Vogel  * i40e_get_port_mac_addr - get Port MAC address
112261ae650dSJack F Vogel  * @hw: pointer to the HW structure
112361ae650dSJack F Vogel  * @mac_addr: pointer to Port MAC address
112461ae650dSJack F Vogel  *
112561ae650dSJack F Vogel  * Reads the adapter's Port MAC address
112661ae650dSJack F Vogel  **/
i40e_get_port_mac_addr(struct i40e_hw * hw,u8 * mac_addr)112761ae650dSJack F Vogel enum i40e_status_code i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
112861ae650dSJack F Vogel {
112961ae650dSJack F Vogel 	struct i40e_aqc_mac_address_read_data addrs;
113061ae650dSJack F Vogel 	enum i40e_status_code status;
113161ae650dSJack F Vogel 	u16 flags = 0;
113261ae650dSJack F Vogel 
113361ae650dSJack F Vogel 	status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
113461ae650dSJack F Vogel 	if (status)
113561ae650dSJack F Vogel 		return status;
113661ae650dSJack F Vogel 
113761ae650dSJack F Vogel 	if (flags & I40E_AQC_PORT_ADDR_VALID)
1138cb6b8299SEric Joyner 		i40e_memcpy(mac_addr, &addrs.port_mac, sizeof(addrs.port_mac),
1139cb6b8299SEric Joyner 			I40E_NONDMA_TO_NONDMA);
114061ae650dSJack F Vogel 	else
114161ae650dSJack F Vogel 		status = I40E_ERR_INVALID_MAC_ADDR;
114261ae650dSJack F Vogel 
114361ae650dSJack F Vogel 	return status;
114461ae650dSJack F Vogel }
114561ae650dSJack F Vogel 
114661ae650dSJack F Vogel /**
114761ae650dSJack F Vogel  * i40e_pre_tx_queue_cfg - pre tx queue configure
114861ae650dSJack F Vogel  * @hw: pointer to the HW structure
114961ae650dSJack F Vogel  * @queue: target pf queue index
115061ae650dSJack F Vogel  * @enable: state change request
115161ae650dSJack F Vogel  *
115261ae650dSJack F Vogel  * Handles hw requirement to indicate intention to enable
115361ae650dSJack F Vogel  * or disable target queue.
115461ae650dSJack F Vogel  **/
i40e_pre_tx_queue_cfg(struct i40e_hw * hw,u32 queue,bool enable)115561ae650dSJack F Vogel void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
115661ae650dSJack F Vogel {
115761ae650dSJack F Vogel 	u32 abs_queue_idx = hw->func_caps.base_queue + queue;
115861ae650dSJack F Vogel 	u32 reg_block = 0;
115961ae650dSJack F Vogel 	u32 reg_val;
116061ae650dSJack F Vogel 
116161ae650dSJack F Vogel 	if (abs_queue_idx >= 128) {
116261ae650dSJack F Vogel 		reg_block = abs_queue_idx / 128;
116361ae650dSJack F Vogel 		abs_queue_idx %= 128;
116461ae650dSJack F Vogel 	}
116561ae650dSJack F Vogel 
116661ae650dSJack F Vogel 	reg_val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
116761ae650dSJack F Vogel 	reg_val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
116861ae650dSJack F Vogel 	reg_val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
116961ae650dSJack F Vogel 
117061ae650dSJack F Vogel 	if (enable)
117161ae650dSJack F Vogel 		reg_val |= I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK;
117261ae650dSJack F Vogel 	else
117361ae650dSJack F Vogel 		reg_val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
117461ae650dSJack F Vogel 
117561ae650dSJack F Vogel 	wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val);
117661ae650dSJack F Vogel }
117761ae650dSJack F Vogel 
117861ae650dSJack F Vogel /**
1179f247dc25SJack F Vogel  *  i40e_read_pba_string - Reads part number string from EEPROM
1180f247dc25SJack F Vogel  *  @hw: pointer to hardware structure
1181f247dc25SJack F Vogel  *  @pba_num: stores the part number string from the EEPROM
1182f247dc25SJack F Vogel  *  @pba_num_size: part number string buffer length
118361ae650dSJack F Vogel  *
1184f247dc25SJack F Vogel  *  Reads the part number string from the EEPROM.
118561ae650dSJack F Vogel  **/
i40e_read_pba_string(struct i40e_hw * hw,u8 * pba_num,u32 pba_num_size)1186f247dc25SJack F Vogel enum i40e_status_code i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
1187f247dc25SJack F Vogel 					    u32 pba_num_size)
118861ae650dSJack F Vogel {
118961ae650dSJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
1190f247dc25SJack F Vogel 	u16 pba_word = 0;
1191f247dc25SJack F Vogel 	u16 pba_size = 0;
1192f247dc25SJack F Vogel 	u16 pba_ptr = 0;
1193f247dc25SJack F Vogel 	u16 i = 0;
119461ae650dSJack F Vogel 
1195f247dc25SJack F Vogel 	status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
1196f247dc25SJack F Vogel 	if ((status != I40E_SUCCESS) || (pba_word != 0xFAFA)) {
1197f247dc25SJack F Vogel 		DEBUGOUT("Failed to read PBA flags or flag is invalid.\n");
1198f247dc25SJack F Vogel 		return status;
1199f247dc25SJack F Vogel 	}
120061ae650dSJack F Vogel 
1201f247dc25SJack F Vogel 	status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr);
1202f247dc25SJack F Vogel 	if (status != I40E_SUCCESS) {
1203f247dc25SJack F Vogel 		DEBUGOUT("Failed to read PBA Block pointer.\n");
1204f247dc25SJack F Vogel 		return status;
1205f247dc25SJack F Vogel 	}
1206f247dc25SJack F Vogel 
1207f247dc25SJack F Vogel 	status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
1208f247dc25SJack F Vogel 	if (status != I40E_SUCCESS) {
1209f247dc25SJack F Vogel 		DEBUGOUT("Failed to read PBA Block size.\n");
1210f247dc25SJack F Vogel 		return status;
1211f247dc25SJack F Vogel 	}
1212f247dc25SJack F Vogel 
1213f247dc25SJack F Vogel 	/* Subtract one to get PBA word count (PBA Size word is included in
1214f247dc25SJack F Vogel 	 * total size)
121561ae650dSJack F Vogel 	 */
1216f247dc25SJack F Vogel 	pba_size--;
1217f247dc25SJack F Vogel 	if (pba_num_size < (((u32)pba_size * 2) + 1)) {
1218f247dc25SJack F Vogel 		DEBUGOUT("Buffer to small for PBA data.\n");
1219f247dc25SJack F Vogel 		return I40E_ERR_PARAM;
1220f247dc25SJack F Vogel 	}
1221f247dc25SJack F Vogel 
1222f247dc25SJack F Vogel 	for (i = 0; i < pba_size; i++) {
1223f247dc25SJack F Vogel 		status = i40e_read_nvm_word(hw, (pba_ptr + 1) + i, &pba_word);
1224f247dc25SJack F Vogel 		if (status != I40E_SUCCESS) {
1225f247dc25SJack F Vogel 			DEBUGOUT1("Failed to read PBA Block word %d.\n", i);
1226f247dc25SJack F Vogel 			return status;
1227f247dc25SJack F Vogel 		}
1228f247dc25SJack F Vogel 
1229f247dc25SJack F Vogel 		pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
1230f247dc25SJack F Vogel 		pba_num[(i * 2) + 1] = pba_word & 0xFF;
1231f247dc25SJack F Vogel 	}
1232f247dc25SJack F Vogel 	pba_num[(pba_size * 2)] = '\0';
123361ae650dSJack F Vogel 
123461ae650dSJack F Vogel 	return status;
123561ae650dSJack F Vogel }
123661ae650dSJack F Vogel 
123761ae650dSJack F Vogel /**
123861ae650dSJack F Vogel  * i40e_get_media_type - Gets media type
123961ae650dSJack F Vogel  * @hw: pointer to the hardware structure
124061ae650dSJack F Vogel  **/
i40e_get_media_type(struct i40e_hw * hw)124161ae650dSJack F Vogel static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
124261ae650dSJack F Vogel {
124361ae650dSJack F Vogel 	enum i40e_media_type media;
124461ae650dSJack F Vogel 
124561ae650dSJack F Vogel 	switch (hw->phy.link_info.phy_type) {
124661ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_SR:
124761ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_LR:
124861ae650dSJack F Vogel 	case I40E_PHY_TYPE_1000BASE_SX:
124961ae650dSJack F Vogel 	case I40E_PHY_TYPE_1000BASE_LX:
125061ae650dSJack F Vogel 	case I40E_PHY_TYPE_40GBASE_SR4:
125161ae650dSJack F Vogel 	case I40E_PHY_TYPE_40GBASE_LR4:
1252cb6b8299SEric Joyner 	case I40E_PHY_TYPE_25GBASE_LR:
1253cb6b8299SEric Joyner 	case I40E_PHY_TYPE_25GBASE_SR:
1254abf77452SKrzysztof Galazka 	case I40E_PHY_TYPE_10GBASE_AOC:
1255abf77452SKrzysztof Galazka 	case I40E_PHY_TYPE_25GBASE_AOC:
1256abf77452SKrzysztof Galazka 	case I40E_PHY_TYPE_40GBASE_AOC:
125761ae650dSJack F Vogel 		media = I40E_MEDIA_TYPE_FIBER;
125861ae650dSJack F Vogel 		break;
125961ae650dSJack F Vogel 	case I40E_PHY_TYPE_100BASE_TX:
126061ae650dSJack F Vogel 	case I40E_PHY_TYPE_1000BASE_T:
1261abf77452SKrzysztof Galazka 	case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS:
1262abf77452SKrzysztof Galazka 	case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS:
126361ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_T:
126461ae650dSJack F Vogel 		media = I40E_MEDIA_TYPE_BASET;
126561ae650dSJack F Vogel 		break;
126661ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_CR1_CU:
126761ae650dSJack F Vogel 	case I40E_PHY_TYPE_40GBASE_CR4_CU:
126861ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_CR1:
126961ae650dSJack F Vogel 	case I40E_PHY_TYPE_40GBASE_CR4:
127061ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_SFPP_CU:
1271cb6b8299SEric Joyner 	case I40E_PHY_TYPE_25GBASE_CR:
1272ceebc2f3SEric Joyner 	case I40E_PHY_TYPE_25GBASE_ACC:
127361ae650dSJack F Vogel 		media = I40E_MEDIA_TYPE_DA;
127461ae650dSJack F Vogel 		break;
127561ae650dSJack F Vogel 	case I40E_PHY_TYPE_1000BASE_KX:
127661ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_KX4:
127761ae650dSJack F Vogel 	case I40E_PHY_TYPE_10GBASE_KR:
127861ae650dSJack F Vogel 	case I40E_PHY_TYPE_40GBASE_KR4:
1279b6c8f260SJack F Vogel 	case I40E_PHY_TYPE_20GBASE_KR2:
1280cb6b8299SEric Joyner 	case I40E_PHY_TYPE_25GBASE_KR:
128161ae650dSJack F Vogel 		media = I40E_MEDIA_TYPE_BACKPLANE;
128261ae650dSJack F Vogel 		break;
128361ae650dSJack F Vogel 	case I40E_PHY_TYPE_SGMII:
128461ae650dSJack F Vogel 	case I40E_PHY_TYPE_XAUI:
128561ae650dSJack F Vogel 	case I40E_PHY_TYPE_XFI:
128661ae650dSJack F Vogel 	case I40E_PHY_TYPE_XLAUI:
128761ae650dSJack F Vogel 	case I40E_PHY_TYPE_XLPPI:
128861ae650dSJack F Vogel 	default:
128961ae650dSJack F Vogel 		media = I40E_MEDIA_TYPE_UNKNOWN;
129061ae650dSJack F Vogel 		break;
129161ae650dSJack F Vogel 	}
129261ae650dSJack F Vogel 
129361ae650dSJack F Vogel 	return media;
129461ae650dSJack F Vogel }
129561ae650dSJack F Vogel 
1296b4a7ce06SEric Joyner /**
1297b4a7ce06SEric Joyner  * i40e_poll_globr - Poll for Global Reset completion
1298b4a7ce06SEric Joyner  * @hw: pointer to the hardware structure
1299b4a7ce06SEric Joyner  * @retry_limit: how many times to retry before failure
1300b4a7ce06SEric Joyner  **/
i40e_poll_globr(struct i40e_hw * hw,u32 retry_limit)1301b4a7ce06SEric Joyner static enum i40e_status_code i40e_poll_globr(struct i40e_hw *hw,
1302b4a7ce06SEric Joyner 					     u32 retry_limit)
1303b4a7ce06SEric Joyner {
1304b4a7ce06SEric Joyner 	u32 cnt, reg = 0;
1305b4a7ce06SEric Joyner 
1306b4a7ce06SEric Joyner 	for (cnt = 0; cnt < retry_limit; cnt++) {
1307b4a7ce06SEric Joyner 		reg = rd32(hw, I40E_GLGEN_RSTAT);
1308b4a7ce06SEric Joyner 		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
1309b4a7ce06SEric Joyner 			return I40E_SUCCESS;
1310b4a7ce06SEric Joyner 		i40e_msec_delay(100);
1311b4a7ce06SEric Joyner 	}
1312b4a7ce06SEric Joyner 
1313b4a7ce06SEric Joyner 	DEBUGOUT("Global reset failed.\n");
1314b4a7ce06SEric Joyner 	DEBUGOUT1("I40E_GLGEN_RSTAT = 0x%x\n", reg);
1315b4a7ce06SEric Joyner 
1316b4a7ce06SEric Joyner 	return I40E_ERR_RESET_FAILED;
1317b4a7ce06SEric Joyner }
1318b4a7ce06SEric Joyner 
1319abf77452SKrzysztof Galazka #define I40E_PF_RESET_WAIT_COUNT	1000
132061ae650dSJack F Vogel /**
132161ae650dSJack F Vogel  * i40e_pf_reset - Reset the PF
132261ae650dSJack F Vogel  * @hw: pointer to the hardware structure
132361ae650dSJack F Vogel  *
132461ae650dSJack F Vogel  * Assuming someone else has triggered a global reset,
132561ae650dSJack F Vogel  * assure the global reset is complete and then reset the PF
132661ae650dSJack F Vogel  **/
i40e_pf_reset(struct i40e_hw * hw)132761ae650dSJack F Vogel enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
132861ae650dSJack F Vogel {
132961ae650dSJack F Vogel 	u32 cnt = 0;
133061ae650dSJack F Vogel 	u32 cnt1 = 0;
133161ae650dSJack F Vogel 	u32 reg = 0;
133261ae650dSJack F Vogel 	u32 grst_del;
133361ae650dSJack F Vogel 
133461ae650dSJack F Vogel 	/* Poll for Global Reset steady state in case of recent GRST.
133561ae650dSJack F Vogel 	 * The grst delay value is in 100ms units, and we'll wait a
133661ae650dSJack F Vogel 	 * couple counts longer to be sure we don't just miss the end.
133761ae650dSJack F Vogel 	 */
1338f247dc25SJack F Vogel 	grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
1339f247dc25SJack F Vogel 			I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
1340f247dc25SJack F Vogel 			I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
13416d011ad5SEric Joyner 
1342b4a7ce06SEric Joyner 	grst_del = min(grst_del * 20, 160U);
13436d011ad5SEric Joyner 
13446d011ad5SEric Joyner 	for (cnt = 0; cnt < grst_del; cnt++) {
134561ae650dSJack F Vogel 		reg = rd32(hw, I40E_GLGEN_RSTAT);
134661ae650dSJack F Vogel 		if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
134761ae650dSJack F Vogel 			break;
134861ae650dSJack F Vogel 		i40e_msec_delay(100);
134961ae650dSJack F Vogel 	}
135061ae650dSJack F Vogel 	if (reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
135161ae650dSJack F Vogel 		DEBUGOUT("Global reset polling failed to complete.\n");
135261ae650dSJack F Vogel 		return I40E_ERR_RESET_FAILED;
135361ae650dSJack F Vogel 	}
135461ae650dSJack F Vogel 
135561ae650dSJack F Vogel 	/* Now Wait for the FW to be ready */
135661ae650dSJack F Vogel 	for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) {
135761ae650dSJack F Vogel 		reg = rd32(hw, I40E_GLNVM_ULD);
135861ae650dSJack F Vogel 		reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
135961ae650dSJack F Vogel 			I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK);
136061ae650dSJack F Vogel 		if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
136161ae650dSJack F Vogel 			    I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK)) {
136261ae650dSJack F Vogel 			DEBUGOUT1("Core and Global modules ready %d\n", cnt1);
136361ae650dSJack F Vogel 			break;
136461ae650dSJack F Vogel 		}
136561ae650dSJack F Vogel 		i40e_msec_delay(10);
136661ae650dSJack F Vogel 	}
136761ae650dSJack F Vogel 	if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
136861ae650dSJack F Vogel 		     I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) {
136961ae650dSJack F Vogel 		DEBUGOUT("wait for FW Reset complete timedout\n");
137061ae650dSJack F Vogel 		DEBUGOUT1("I40E_GLNVM_ULD = 0x%x\n", reg);
137161ae650dSJack F Vogel 		return I40E_ERR_RESET_FAILED;
137261ae650dSJack F Vogel 	}
137361ae650dSJack F Vogel 
137461ae650dSJack F Vogel 	/* If there was a Global Reset in progress when we got here,
137561ae650dSJack F Vogel 	 * we don't need to do the PF Reset
137661ae650dSJack F Vogel 	 */
137761ae650dSJack F Vogel 	if (!cnt) {
1378ceebc2f3SEric Joyner 		u32 reg2 = 0;
1379ceebc2f3SEric Joyner 
138061ae650dSJack F Vogel 		reg = rd32(hw, I40E_PFGEN_CTRL);
138161ae650dSJack F Vogel 		wr32(hw, I40E_PFGEN_CTRL,
138261ae650dSJack F Vogel 		     (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
138361ae650dSJack F Vogel 		for (cnt = 0; cnt < I40E_PF_RESET_WAIT_COUNT; cnt++) {
138461ae650dSJack F Vogel 			reg = rd32(hw, I40E_PFGEN_CTRL);
138561ae650dSJack F Vogel 			if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
138661ae650dSJack F Vogel 				break;
1387ceebc2f3SEric Joyner 			reg2 = rd32(hw, I40E_GLGEN_RSTAT);
1388b4a7ce06SEric Joyner 			if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK)
1389b4a7ce06SEric Joyner 				break;
139061ae650dSJack F Vogel 			i40e_msec_delay(1);
139161ae650dSJack F Vogel 		}
1392b4a7ce06SEric Joyner 		if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
1393b4a7ce06SEric Joyner 			if (i40e_poll_globr(hw, grst_del) != I40E_SUCCESS)
1394b4a7ce06SEric Joyner 				return I40E_ERR_RESET_FAILED;
1395b4a7ce06SEric Joyner 		} else if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
139661ae650dSJack F Vogel 			DEBUGOUT("PF reset polling failed to complete.\n");
139761ae650dSJack F Vogel 			return I40E_ERR_RESET_FAILED;
139861ae650dSJack F Vogel 		}
139961ae650dSJack F Vogel 	}
140061ae650dSJack F Vogel 
140161ae650dSJack F Vogel 	i40e_clear_pxe_mode(hw);
140261ae650dSJack F Vogel 
140361ae650dSJack F Vogel 
140461ae650dSJack F Vogel 	return I40E_SUCCESS;
140561ae650dSJack F Vogel }
140661ae650dSJack F Vogel 
140761ae650dSJack F Vogel /**
140861ae650dSJack F Vogel  * i40e_clear_hw - clear out any left over hw state
140961ae650dSJack F Vogel  * @hw: pointer to the hw struct
141061ae650dSJack F Vogel  *
141161ae650dSJack F Vogel  * Clear queues and interrupts, typically called at init time,
141261ae650dSJack F Vogel  * but after the capabilities have been found so we know how many
141361ae650dSJack F Vogel  * queues and msix vectors have been allocated.
141461ae650dSJack F Vogel  **/
i40e_clear_hw(struct i40e_hw * hw)141561ae650dSJack F Vogel void i40e_clear_hw(struct i40e_hw *hw)
141661ae650dSJack F Vogel {
141761ae650dSJack F Vogel 	u32 num_queues, base_queue;
141861ae650dSJack F Vogel 	u32 num_pf_int;
141961ae650dSJack F Vogel 	u32 num_vf_int;
142061ae650dSJack F Vogel 	u32 num_vfs;
142161ae650dSJack F Vogel 	u32 i, j;
142261ae650dSJack F Vogel 	u32 val;
142361ae650dSJack F Vogel 	u32 eol = 0x7ff;
142461ae650dSJack F Vogel 
142561ae650dSJack F Vogel 	/* get number of interrupts, queues, and vfs */
142661ae650dSJack F Vogel 	val = rd32(hw, I40E_GLPCI_CNF2);
142761ae650dSJack F Vogel 	num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
142861ae650dSJack F Vogel 			I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
142961ae650dSJack F Vogel 	num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >>
143061ae650dSJack F Vogel 			I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT;
143161ae650dSJack F Vogel 
143261ae650dSJack F Vogel 	val = rd32(hw, I40E_PFLAN_QALLOC);
143361ae650dSJack F Vogel 	base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >>
143461ae650dSJack F Vogel 			I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
143561ae650dSJack F Vogel 	j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
143661ae650dSJack F Vogel 			I40E_PFLAN_QALLOC_LASTQ_SHIFT;
143761ae650dSJack F Vogel 	if (val & I40E_PFLAN_QALLOC_VALID_MASK)
143861ae650dSJack F Vogel 		num_queues = (j - base_queue) + 1;
143961ae650dSJack F Vogel 	else
144061ae650dSJack F Vogel 		num_queues = 0;
144161ae650dSJack F Vogel 
144261ae650dSJack F Vogel 	val = rd32(hw, I40E_PF_VT_PFALLOC);
144361ae650dSJack F Vogel 	i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >>
144461ae650dSJack F Vogel 			I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
144561ae650dSJack F Vogel 	j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
144661ae650dSJack F Vogel 			I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
144761ae650dSJack F Vogel 	if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
144861ae650dSJack F Vogel 		num_vfs = (j - i) + 1;
144961ae650dSJack F Vogel 	else
145061ae650dSJack F Vogel 		num_vfs = 0;
145161ae650dSJack F Vogel 
145261ae650dSJack F Vogel 	/* stop all the interrupts */
145361ae650dSJack F Vogel 	wr32(hw, I40E_PFINT_ICR0_ENA, 0);
145461ae650dSJack F Vogel 	val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
145561ae650dSJack F Vogel 	for (i = 0; i < num_pf_int - 2; i++)
145661ae650dSJack F Vogel 		wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
145761ae650dSJack F Vogel 
145861ae650dSJack F Vogel 	/* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
145961ae650dSJack F Vogel 	val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
146061ae650dSJack F Vogel 	wr32(hw, I40E_PFINT_LNKLST0, val);
146161ae650dSJack F Vogel 	for (i = 0; i < num_pf_int - 2; i++)
146261ae650dSJack F Vogel 		wr32(hw, I40E_PFINT_LNKLSTN(i), val);
146361ae650dSJack F Vogel 	val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
146461ae650dSJack F Vogel 	for (i = 0; i < num_vfs; i++)
146561ae650dSJack F Vogel 		wr32(hw, I40E_VPINT_LNKLST0(i), val);
146661ae650dSJack F Vogel 	for (i = 0; i < num_vf_int - 2; i++)
146761ae650dSJack F Vogel 		wr32(hw, I40E_VPINT_LNKLSTN(i), val);
146861ae650dSJack F Vogel 
146961ae650dSJack F Vogel 	/* warn the HW of the coming Tx disables */
147061ae650dSJack F Vogel 	for (i = 0; i < num_queues; i++) {
147161ae650dSJack F Vogel 		u32 abs_queue_idx = base_queue + i;
147261ae650dSJack F Vogel 		u32 reg_block = 0;
147361ae650dSJack F Vogel 
147461ae650dSJack F Vogel 		if (abs_queue_idx >= 128) {
147561ae650dSJack F Vogel 			reg_block = abs_queue_idx / 128;
147661ae650dSJack F Vogel 			abs_queue_idx %= 128;
147761ae650dSJack F Vogel 		}
147861ae650dSJack F Vogel 
147961ae650dSJack F Vogel 		val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
148061ae650dSJack F Vogel 		val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
148161ae650dSJack F Vogel 		val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
148261ae650dSJack F Vogel 		val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
148361ae650dSJack F Vogel 
148461ae650dSJack F Vogel 		wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), val);
148561ae650dSJack F Vogel 	}
148661ae650dSJack F Vogel 	i40e_usec_delay(400);
148761ae650dSJack F Vogel 
148861ae650dSJack F Vogel 	/* stop all the queues */
148961ae650dSJack F Vogel 	for (i = 0; i < num_queues; i++) {
149061ae650dSJack F Vogel 		wr32(hw, I40E_QINT_TQCTL(i), 0);
149161ae650dSJack F Vogel 		wr32(hw, I40E_QTX_ENA(i), 0);
149261ae650dSJack F Vogel 		wr32(hw, I40E_QINT_RQCTL(i), 0);
149361ae650dSJack F Vogel 		wr32(hw, I40E_QRX_ENA(i), 0);
149461ae650dSJack F Vogel 	}
149561ae650dSJack F Vogel 
149661ae650dSJack F Vogel 	/* short wait for all queue disables to settle */
149761ae650dSJack F Vogel 	i40e_usec_delay(50);
149861ae650dSJack F Vogel }
149961ae650dSJack F Vogel 
150061ae650dSJack F Vogel /**
150161ae650dSJack F Vogel  * i40e_clear_pxe_mode - clear pxe operations mode
150261ae650dSJack F Vogel  * @hw: pointer to the hw struct
150361ae650dSJack F Vogel  *
150461ae650dSJack F Vogel  * Make sure all PXE mode settings are cleared, including things
150561ae650dSJack F Vogel  * like descriptor fetch/write-back mode.
150661ae650dSJack F Vogel  **/
i40e_clear_pxe_mode(struct i40e_hw * hw)150761ae650dSJack F Vogel void i40e_clear_pxe_mode(struct i40e_hw *hw)
150861ae650dSJack F Vogel {
150961ae650dSJack F Vogel 	if (i40e_check_asq_alive(hw))
151061ae650dSJack F Vogel 		i40e_aq_clear_pxe_mode(hw, NULL);
151161ae650dSJack F Vogel }
151261ae650dSJack F Vogel 
151361ae650dSJack F Vogel /**
151461ae650dSJack F Vogel  * i40e_led_is_mine - helper to find matching led
151561ae650dSJack F Vogel  * @hw: pointer to the hw struct
151661ae650dSJack F Vogel  * @idx: index into GPIO registers
151761ae650dSJack F Vogel  *
151861ae650dSJack F Vogel  * returns: 0 if no match, otherwise the value of the GPIO_CTL register
151961ae650dSJack F Vogel  */
i40e_led_is_mine(struct i40e_hw * hw,int idx)152061ae650dSJack F Vogel static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
152161ae650dSJack F Vogel {
152261ae650dSJack F Vogel 	u32 gpio_val = 0;
152361ae650dSJack F Vogel 	u32 port;
152461ae650dSJack F Vogel 
15252984a8ddSEric Joyner 	if (!I40E_IS_X710TL_DEVICE(hw->device_id) &&
15262984a8ddSEric Joyner 	    !hw->func_caps.led[idx])
152761ae650dSJack F Vogel 		return 0;
152861ae650dSJack F Vogel 	gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx));
152961ae650dSJack F Vogel 	port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >>
153061ae650dSJack F Vogel 		I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT;
153161ae650dSJack F Vogel 
153261ae650dSJack F Vogel 	/* if PRT_NUM_NA is 1 then this LED is not port specific, OR
153361ae650dSJack F Vogel 	 * if it is not our port then ignore
153461ae650dSJack F Vogel 	 */
153561ae650dSJack F Vogel 	if ((gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK) ||
153661ae650dSJack F Vogel 	    (port != hw->port))
153761ae650dSJack F Vogel 		return 0;
153861ae650dSJack F Vogel 
153961ae650dSJack F Vogel 	return gpio_val;
154061ae650dSJack F Vogel }
154161ae650dSJack F Vogel 
1542f247dc25SJack F Vogel #define I40E_COMBINED_ACTIVITY 0xA
1543f247dc25SJack F Vogel #define I40E_FILTER_ACTIVITY 0xE
154461ae650dSJack F Vogel #define I40E_LINK_ACTIVITY 0xC
1545f247dc25SJack F Vogel #define I40E_MAC_ACTIVITY 0xD
1546b4a7ce06SEric Joyner #define I40E_FW_LED BIT(4)
1547b4a7ce06SEric Joyner #define I40E_LED_MODE_VALID (I40E_GLGEN_GPIO_CTL_LED_MODE_MASK >> \
1548b4a7ce06SEric Joyner 			     I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT)
1549b4a7ce06SEric Joyner 
1550f247dc25SJack F Vogel #define I40E_LED0 22
155161ae650dSJack F Vogel 
1552b4a7ce06SEric Joyner #define I40E_PIN_FUNC_SDP 0x0
1553b4a7ce06SEric Joyner #define I40E_PIN_FUNC_LED 0x1
1554b4a7ce06SEric Joyner 
155561ae650dSJack F Vogel /**
155661ae650dSJack F Vogel  * i40e_led_get - return current on/off mode
155761ae650dSJack F Vogel  * @hw: pointer to the hw struct
155861ae650dSJack F Vogel  *
155961ae650dSJack F Vogel  * The value returned is the 'mode' field as defined in the
156061ae650dSJack F Vogel  * GPIO register definitions: 0x0 = off, 0xf = on, and other
156161ae650dSJack F Vogel  * values are variations of possible behaviors relating to
156261ae650dSJack F Vogel  * blink, link, and wire.
156361ae650dSJack F Vogel  **/
i40e_led_get(struct i40e_hw * hw)156461ae650dSJack F Vogel u32 i40e_led_get(struct i40e_hw *hw)
156561ae650dSJack F Vogel {
156661ae650dSJack F Vogel 	u32 mode = 0;
156761ae650dSJack F Vogel 	int i;
156861ae650dSJack F Vogel 
156961ae650dSJack F Vogel 	/* as per the documentation GPIO 22-29 are the LED
157061ae650dSJack F Vogel 	 * GPIO pins named LED0..LED7
157161ae650dSJack F Vogel 	 */
157261ae650dSJack F Vogel 	for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
157361ae650dSJack F Vogel 		u32 gpio_val = i40e_led_is_mine(hw, i);
157461ae650dSJack F Vogel 
157561ae650dSJack F Vogel 		if (!gpio_val)
157661ae650dSJack F Vogel 			continue;
157761ae650dSJack F Vogel 
1578f247dc25SJack F Vogel 
157961ae650dSJack F Vogel 		mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
158061ae650dSJack F Vogel 			I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT;
158161ae650dSJack F Vogel 		break;
158261ae650dSJack F Vogel 	}
158361ae650dSJack F Vogel 
158461ae650dSJack F Vogel 	return mode;
158561ae650dSJack F Vogel }
158661ae650dSJack F Vogel 
158761ae650dSJack F Vogel /**
158861ae650dSJack F Vogel  * i40e_led_set - set new on/off mode
158961ae650dSJack F Vogel  * @hw: pointer to the hw struct
159061ae650dSJack F Vogel  * @mode: 0=off, 0xf=on (else see manual for mode details)
159161ae650dSJack F Vogel  * @blink: TRUE if the LED should blink when on, FALSE if steady
159261ae650dSJack F Vogel  *
159361ae650dSJack F Vogel  * if this function is used to turn on the blink it should
159461ae650dSJack F Vogel  * be used to disable the blink when restoring the original state.
159561ae650dSJack F Vogel  **/
i40e_led_set(struct i40e_hw * hw,u32 mode,bool blink)159661ae650dSJack F Vogel void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
159761ae650dSJack F Vogel {
159861ae650dSJack F Vogel 	int i;
159961ae650dSJack F Vogel 
1600b4a7ce06SEric Joyner 	if (mode & ~I40E_LED_MODE_VALID) {
160161ae650dSJack F Vogel 		DEBUGOUT1("invalid mode passed in %X\n", mode);
1602b4a7ce06SEric Joyner 		return;
1603b4a7ce06SEric Joyner 	}
160461ae650dSJack F Vogel 
160561ae650dSJack F Vogel 	/* as per the documentation GPIO 22-29 are the LED
160661ae650dSJack F Vogel 	 * GPIO pins named LED0..LED7
160761ae650dSJack F Vogel 	 */
160861ae650dSJack F Vogel 	for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
160961ae650dSJack F Vogel 		u32 gpio_val = i40e_led_is_mine(hw, i);
161061ae650dSJack F Vogel 
161161ae650dSJack F Vogel 		if (!gpio_val)
161261ae650dSJack F Vogel 			continue;
161361ae650dSJack F Vogel 
1614f247dc25SJack F Vogel 
16152984a8ddSEric Joyner 		if (I40E_IS_X710TL_DEVICE(hw->device_id)) {
16162984a8ddSEric Joyner 			u32 pin_func = 0;
16172984a8ddSEric Joyner 
16182984a8ddSEric Joyner 			if (mode & I40E_FW_LED)
16192984a8ddSEric Joyner 				pin_func = I40E_PIN_FUNC_SDP;
16202984a8ddSEric Joyner 			else
16212984a8ddSEric Joyner 				pin_func = I40E_PIN_FUNC_LED;
16222984a8ddSEric Joyner 
16232984a8ddSEric Joyner 			gpio_val &= ~I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK;
16242984a8ddSEric Joyner 			gpio_val |= ((pin_func <<
16252984a8ddSEric Joyner 				     I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT) &
16262984a8ddSEric Joyner 				     I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK);
16272984a8ddSEric Joyner 		}
162861ae650dSJack F Vogel 		gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
162961ae650dSJack F Vogel 		/* this & is a bit of paranoia, but serves as a range check */
163061ae650dSJack F Vogel 		gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
163161ae650dSJack F Vogel 			     I40E_GLGEN_GPIO_CTL_LED_MODE_MASK);
163261ae650dSJack F Vogel 
1633f247dc25SJack F Vogel 		if (blink)
1634be771cdaSJack F Vogel 			gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
1635f247dc25SJack F Vogel 		else
1636be771cdaSJack F Vogel 			gpio_val &= ~BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
163761ae650dSJack F Vogel 
163861ae650dSJack F Vogel 		wr32(hw, I40E_GLGEN_GPIO_CTL(i), gpio_val);
163961ae650dSJack F Vogel 		break;
164061ae650dSJack F Vogel 	}
164161ae650dSJack F Vogel }
164261ae650dSJack F Vogel 
164361ae650dSJack F Vogel /* Admin command wrappers */
164461ae650dSJack F Vogel 
164561ae650dSJack F Vogel /**
164661ae650dSJack F Vogel  * i40e_aq_get_phy_capabilities
164761ae650dSJack F Vogel  * @hw: pointer to the hw struct
164861ae650dSJack F Vogel  * @abilities: structure for PHY capabilities to be filled
164961ae650dSJack F Vogel  * @qualified_modules: report Qualified Modules
165061ae650dSJack F Vogel  * @report_init: report init capabilities (active are default)
165161ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
165261ae650dSJack F Vogel  *
165361ae650dSJack F Vogel  * Returns the various PHY abilities supported on the Port.
165461ae650dSJack F Vogel  **/
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)165561ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
165661ae650dSJack F Vogel 			bool qualified_modules, bool report_init,
165761ae650dSJack F Vogel 			struct i40e_aq_get_phy_abilities_resp *abilities,
165861ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
165961ae650dSJack F Vogel {
166061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
166161ae650dSJack F Vogel 	enum i40e_status_code status;
1662ceebc2f3SEric Joyner 	u16 max_delay = I40E_MAX_PHY_TIMEOUT, total_delay = 0;
166361ae650dSJack F Vogel 	u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
166461ae650dSJack F Vogel 
166561ae650dSJack F Vogel 	if (!abilities)
166661ae650dSJack F Vogel 		return I40E_ERR_PARAM;
166761ae650dSJack F Vogel 
1668ceebc2f3SEric Joyner 	do {
166961ae650dSJack F Vogel 		i40e_fill_default_direct_cmd_desc(&desc,
167061ae650dSJack F Vogel 					       i40e_aqc_opc_get_phy_abilities);
167161ae650dSJack F Vogel 
167261ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
167361ae650dSJack F Vogel 		if (abilities_size > I40E_AQ_LARGE_BUF)
167461ae650dSJack F Vogel 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
167561ae650dSJack F Vogel 
167661ae650dSJack F Vogel 		if (qualified_modules)
167761ae650dSJack F Vogel 			desc.params.external.param0 |=
167861ae650dSJack F Vogel 			CPU_TO_LE32(I40E_AQ_PHY_REPORT_QUALIFIED_MODULES);
167961ae650dSJack F Vogel 
168061ae650dSJack F Vogel 		if (report_init)
168161ae650dSJack F Vogel 			desc.params.external.param0 |=
168261ae650dSJack F Vogel 			CPU_TO_LE32(I40E_AQ_PHY_REPORT_INITIAL_VALUES);
168361ae650dSJack F Vogel 
1684ceebc2f3SEric Joyner 		status = i40e_asq_send_command(hw, &desc, abilities,
1685ceebc2f3SEric Joyner 					       abilities_size, cmd_details);
168661ae650dSJack F Vogel 
1687b4a7ce06SEric Joyner 		switch (hw->aq.asq_last_status) {
1688b4a7ce06SEric Joyner 		case I40E_AQ_RC_EIO:
168961ae650dSJack F Vogel 			status = I40E_ERR_UNKNOWN_PHY;
1690ceebc2f3SEric Joyner 			break;
1691b4a7ce06SEric Joyner 		case I40E_AQ_RC_EAGAIN:
1692ceebc2f3SEric Joyner 			i40e_msec_delay(1);
1693ceebc2f3SEric Joyner 			total_delay++;
1694ceebc2f3SEric Joyner 			status = I40E_ERR_TIMEOUT;
1695b4a7ce06SEric Joyner 			break;
1696b4a7ce06SEric Joyner 		/* also covers I40E_AQ_RC_OK */
1697b4a7ce06SEric Joyner 		default:
1698b4a7ce06SEric Joyner 			break;
1699ceebc2f3SEric Joyner 		}
1700b4a7ce06SEric Joyner 
1701b4a7ce06SEric Joyner 	} while ((hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN) &&
1702ceebc2f3SEric Joyner 		(total_delay < max_delay));
1703ceebc2f3SEric Joyner 
1704ceebc2f3SEric Joyner 	if (status != I40E_SUCCESS)
1705ceebc2f3SEric Joyner 		return status;
170661ae650dSJack F Vogel 
17074294f337SSean Bruno 	if (report_init) {
1708ceebc2f3SEric Joyner 		if (hw->mac.type ==  I40E_MAC_XL710 &&
1709ceebc2f3SEric Joyner 		    hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
1710ceebc2f3SEric Joyner 		    hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
1711ceebc2f3SEric Joyner 			status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
1712ceebc2f3SEric Joyner 		} else {
1713ac83ea83SEric Joyner 			hw->phy.phy_types = LE32_TO_CPU(abilities->phy_type);
1714ceebc2f3SEric Joyner 			hw->phy.phy_types |=
1715ceebc2f3SEric Joyner 					((u64)abilities->phy_type_ext << 32);
1716ceebc2f3SEric Joyner 		}
17174294f337SSean Bruno 	}
1718ac83ea83SEric Joyner 
171961ae650dSJack F Vogel 	return status;
172061ae650dSJack F Vogel }
172161ae650dSJack F Vogel 
172261ae650dSJack F Vogel /**
172361ae650dSJack F Vogel  * i40e_aq_set_phy_config
172461ae650dSJack F Vogel  * @hw: pointer to the hw struct
172561ae650dSJack F Vogel  * @config: structure with PHY configuration to be set
172661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
172761ae650dSJack F Vogel  *
172861ae650dSJack F Vogel  * Set the various PHY configuration parameters
172961ae650dSJack F Vogel  * supported on the Port.One or more of the Set PHY config parameters may be
173061ae650dSJack F Vogel  * ignored in an MFP mode as the PF may not have the privilege to set some
173161ae650dSJack F Vogel  * of the PHY Config parameters. This status will be indicated by the
173261ae650dSJack F Vogel  * command response.
173361ae650dSJack F Vogel  **/
i40e_aq_set_phy_config(struct i40e_hw * hw,struct i40e_aq_set_phy_config * config,struct i40e_asq_cmd_details * cmd_details)173461ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
173561ae650dSJack F Vogel 				struct i40e_aq_set_phy_config *config,
173661ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
173761ae650dSJack F Vogel {
173861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
173961ae650dSJack F Vogel 	struct i40e_aq_set_phy_config *cmd =
174061ae650dSJack F Vogel 		(struct i40e_aq_set_phy_config *)&desc.params.raw;
174161ae650dSJack F Vogel 	enum i40e_status_code status;
174261ae650dSJack F Vogel 
174361ae650dSJack F Vogel 	if (!config)
174461ae650dSJack F Vogel 		return I40E_ERR_PARAM;
174561ae650dSJack F Vogel 
174661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
174761ae650dSJack F Vogel 					  i40e_aqc_opc_set_phy_config);
174861ae650dSJack F Vogel 
174961ae650dSJack F Vogel 	*cmd = *config;
175061ae650dSJack F Vogel 
175161ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
175261ae650dSJack F Vogel 
175361ae650dSJack F Vogel 	return status;
175461ae650dSJack F Vogel }
175561ae650dSJack F Vogel 
175661ae650dSJack F Vogel /**
175761ae650dSJack F Vogel  * i40e_set_fc
175861ae650dSJack F Vogel  * @hw: pointer to the hw struct
1759ceebc2f3SEric Joyner  * @aq_failures: buffer to return AdminQ failure information
1760ceebc2f3SEric Joyner  * @atomic_restart: whether to enable atomic link restart
176161ae650dSJack F Vogel  *
176261ae650dSJack F Vogel  * Set the requested flow control mode using set_phy_config.
176361ae650dSJack F Vogel  **/
i40e_set_fc(struct i40e_hw * hw,u8 * aq_failures,bool atomic_restart)176461ae650dSJack F Vogel enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
176561ae650dSJack F Vogel 				  bool atomic_restart)
176661ae650dSJack F Vogel {
176761ae650dSJack F Vogel 	enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
176861ae650dSJack F Vogel 	struct i40e_aq_get_phy_abilities_resp abilities;
176961ae650dSJack F Vogel 	struct i40e_aq_set_phy_config config;
177061ae650dSJack F Vogel 	enum i40e_status_code status;
177161ae650dSJack F Vogel 	u8 pause_mask = 0x0;
177261ae650dSJack F Vogel 
177361ae650dSJack F Vogel 	*aq_failures = 0x0;
177461ae650dSJack F Vogel 
177561ae650dSJack F Vogel 	switch (fc_mode) {
177661ae650dSJack F Vogel 	case I40E_FC_FULL:
177761ae650dSJack F Vogel 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
177861ae650dSJack F Vogel 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
177961ae650dSJack F Vogel 		break;
178061ae650dSJack F Vogel 	case I40E_FC_RX_PAUSE:
178161ae650dSJack F Vogel 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
178261ae650dSJack F Vogel 		break;
178361ae650dSJack F Vogel 	case I40E_FC_TX_PAUSE:
178461ae650dSJack F Vogel 		pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
178561ae650dSJack F Vogel 		break;
178661ae650dSJack F Vogel 	default:
178761ae650dSJack F Vogel 		break;
178861ae650dSJack F Vogel 	}
178961ae650dSJack F Vogel 
179061ae650dSJack F Vogel 	/* Get the current phy config */
179161ae650dSJack F Vogel 	status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
179261ae650dSJack F Vogel 					      NULL);
179361ae650dSJack F Vogel 	if (status) {
179461ae650dSJack F Vogel 		*aq_failures |= I40E_SET_FC_AQ_FAIL_GET;
179561ae650dSJack F Vogel 		return status;
179661ae650dSJack F Vogel 	}
179761ae650dSJack F Vogel 
1798f247dc25SJack F Vogel 	memset(&config, 0, sizeof(config));
179961ae650dSJack F Vogel 	/* clear the old pause settings */
180061ae650dSJack F Vogel 	config.abilities = abilities.abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
180161ae650dSJack F Vogel 			   ~(I40E_AQ_PHY_FLAG_PAUSE_RX);
180261ae650dSJack F Vogel 	/* set the new abilities */
180361ae650dSJack F Vogel 	config.abilities |= pause_mask;
180461ae650dSJack F Vogel 	/* If the abilities have changed, then set the new config */
180561ae650dSJack F Vogel 	if (config.abilities != abilities.abilities) {
180661ae650dSJack F Vogel 		/* Auto restart link so settings take effect */
180761ae650dSJack F Vogel 		if (atomic_restart)
180861ae650dSJack F Vogel 			config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
180961ae650dSJack F Vogel 		/* Copy over all the old settings */
181061ae650dSJack F Vogel 		config.phy_type = abilities.phy_type;
1811cb6b8299SEric Joyner 		config.phy_type_ext = abilities.phy_type_ext;
181261ae650dSJack F Vogel 		config.link_speed = abilities.link_speed;
181361ae650dSJack F Vogel 		config.eee_capability = abilities.eee_capability;
181461ae650dSJack F Vogel 		config.eeer = abilities.eeer_val;
181561ae650dSJack F Vogel 		config.low_power_ctrl = abilities.d3_lpan;
1816cb6b8299SEric Joyner 		config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
1817cb6b8299SEric Joyner 				    I40E_AQ_PHY_FEC_CONFIG_MASK;
181861ae650dSJack F Vogel 		status = i40e_aq_set_phy_config(hw, &config, NULL);
181961ae650dSJack F Vogel 
182061ae650dSJack F Vogel 		if (status)
182161ae650dSJack F Vogel 			*aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
182261ae650dSJack F Vogel 	}
182361ae650dSJack F Vogel 	/* Update the link info */
1824be771cdaSJack F Vogel 	status = i40e_update_link_info(hw);
182561ae650dSJack F Vogel 	if (status) {
182661ae650dSJack F Vogel 		/* Wait a little bit (on 40G cards it sometimes takes a really
182761ae650dSJack F Vogel 		 * long time for link to come back from the atomic reset)
182861ae650dSJack F Vogel 		 * and try once more
182961ae650dSJack F Vogel 		 */
183061ae650dSJack F Vogel 		i40e_msec_delay(1000);
1831be771cdaSJack F Vogel 		status = i40e_update_link_info(hw);
183261ae650dSJack F Vogel 	}
183361ae650dSJack F Vogel 	if (status)
183461ae650dSJack F Vogel 		*aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
183561ae650dSJack F Vogel 
183661ae650dSJack F Vogel 	return status;
183761ae650dSJack F Vogel }
183861ae650dSJack F Vogel 
183961ae650dSJack F Vogel /**
184061ae650dSJack F Vogel  * i40e_aq_set_mac_config
184161ae650dSJack F Vogel  * @hw: pointer to the hw struct
184261ae650dSJack F Vogel  * @max_frame_size: Maximum Frame Size to be supported by the port
184361ae650dSJack F Vogel  * @crc_en: Tell HW to append a CRC to outgoing frames
184461ae650dSJack F Vogel  * @pacing: Pacing configurations
1845b4a7ce06SEric Joyner  * @auto_drop_blocking_packets: Tell HW to drop packets if TC queue is blocked
184661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
184761ae650dSJack F Vogel  *
184861ae650dSJack F Vogel  * Configure MAC settings for frame size, jumbo frame support and the
184961ae650dSJack F Vogel  * addition of a CRC by the hardware.
185061ae650dSJack F Vogel  **/
i40e_aq_set_mac_config(struct i40e_hw * hw,u16 max_frame_size,bool crc_en,u16 pacing,bool auto_drop_blocking_packets,struct i40e_asq_cmd_details * cmd_details)185161ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw,
185261ae650dSJack F Vogel 				u16 max_frame_size,
185361ae650dSJack F Vogel 				bool crc_en, u16 pacing,
1854b4a7ce06SEric Joyner 				bool auto_drop_blocking_packets,
185561ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
185661ae650dSJack F Vogel {
185761ae650dSJack F Vogel 	struct i40e_aq_desc desc;
185861ae650dSJack F Vogel 	struct i40e_aq_set_mac_config *cmd =
185961ae650dSJack F Vogel 		(struct i40e_aq_set_mac_config *)&desc.params.raw;
186061ae650dSJack F Vogel 	enum i40e_status_code status;
186161ae650dSJack F Vogel 
186261ae650dSJack F Vogel 	if (max_frame_size == 0)
186361ae650dSJack F Vogel 		return I40E_ERR_PARAM;
186461ae650dSJack F Vogel 
186561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
186661ae650dSJack F Vogel 					  i40e_aqc_opc_set_mac_config);
186761ae650dSJack F Vogel 
186861ae650dSJack F Vogel 	cmd->max_frame_size = CPU_TO_LE16(max_frame_size);
186961ae650dSJack F Vogel 	cmd->params = ((u8)pacing & 0x0F) << 3;
187061ae650dSJack F Vogel 	if (crc_en)
187161ae650dSJack F Vogel 		cmd->params |= I40E_AQ_SET_MAC_CONFIG_CRC_EN;
187261ae650dSJack F Vogel 
1873b4a7ce06SEric Joyner 	if (auto_drop_blocking_packets) {
1874b4a7ce06SEric Joyner 		if (hw->flags & I40E_HW_FLAG_DROP_MODE)
1875b4a7ce06SEric Joyner 			cmd->params |=
1876b4a7ce06SEric Joyner 				I40E_AQ_SET_MAC_CONFIG_DROP_BLOCKING_PACKET_EN;
1877b4a7ce06SEric Joyner 		else
1878b4a7ce06SEric Joyner 			i40e_debug(hw, I40E_DEBUG_ALL,
1879b4a7ce06SEric Joyner 				   "This FW api version does not support drop mode.\n");
1880b4a7ce06SEric Joyner 	}
1881b4a7ce06SEric Joyner 
1882b4a7ce06SEric Joyner #define I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD	0x7FFF
1883b4a7ce06SEric Joyner 	cmd->fc_refresh_threshold =
1884b4a7ce06SEric Joyner 		CPU_TO_LE16(I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD);
1885b4a7ce06SEric Joyner 
188661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
188761ae650dSJack F Vogel 
188861ae650dSJack F Vogel 	return status;
188961ae650dSJack F Vogel }
189061ae650dSJack F Vogel 
189161ae650dSJack F Vogel /**
189261ae650dSJack F Vogel  * i40e_aq_clear_pxe_mode
189361ae650dSJack F Vogel  * @hw: pointer to the hw struct
189461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
189561ae650dSJack F Vogel  *
189661ae650dSJack F Vogel  * Tell the firmware that the driver is taking over from PXE
189761ae650dSJack F Vogel  **/
i40e_aq_clear_pxe_mode(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)189861ae650dSJack F Vogel enum i40e_status_code i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
189961ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
190061ae650dSJack F Vogel {
190161ae650dSJack F Vogel 	enum i40e_status_code status;
190261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
190361ae650dSJack F Vogel 	struct i40e_aqc_clear_pxe *cmd =
190461ae650dSJack F Vogel 		(struct i40e_aqc_clear_pxe *)&desc.params.raw;
190561ae650dSJack F Vogel 
190661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
190761ae650dSJack F Vogel 					  i40e_aqc_opc_clear_pxe_mode);
190861ae650dSJack F Vogel 
190961ae650dSJack F Vogel 	cmd->rx_cnt = 0x2;
191061ae650dSJack F Vogel 
191161ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
191261ae650dSJack F Vogel 
191361ae650dSJack F Vogel 	wr32(hw, I40E_GLLAN_RCTL_0, 0x1);
191461ae650dSJack F Vogel 
191561ae650dSJack F Vogel 	return status;
191661ae650dSJack F Vogel }
191761ae650dSJack F Vogel 
191861ae650dSJack F Vogel /**
191961ae650dSJack F Vogel  * i40e_aq_set_link_restart_an
192061ae650dSJack F Vogel  * @hw: pointer to the hw struct
192161ae650dSJack F Vogel  * @enable_link: if TRUE: enable link, if FALSE: disable link
192261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
192361ae650dSJack F Vogel  *
192461ae650dSJack F Vogel  * Sets up the link and restarts the Auto-Negotiation over the link.
192561ae650dSJack F Vogel  **/
i40e_aq_set_link_restart_an(struct i40e_hw * hw,bool enable_link,struct i40e_asq_cmd_details * cmd_details)192661ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_link_restart_an(struct i40e_hw *hw,
192761ae650dSJack F Vogel 		bool enable_link, struct i40e_asq_cmd_details *cmd_details)
192861ae650dSJack F Vogel {
192961ae650dSJack F Vogel 	struct i40e_aq_desc desc;
193061ae650dSJack F Vogel 	struct i40e_aqc_set_link_restart_an *cmd =
193161ae650dSJack F Vogel 		(struct i40e_aqc_set_link_restart_an *)&desc.params.raw;
193261ae650dSJack F Vogel 	enum i40e_status_code status;
193361ae650dSJack F Vogel 
193461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
193561ae650dSJack F Vogel 					  i40e_aqc_opc_set_link_restart_an);
193661ae650dSJack F Vogel 
193761ae650dSJack F Vogel 	cmd->command = I40E_AQ_PHY_RESTART_AN;
193861ae650dSJack F Vogel 	if (enable_link)
193961ae650dSJack F Vogel 		cmd->command |= I40E_AQ_PHY_LINK_ENABLE;
194061ae650dSJack F Vogel 	else
194161ae650dSJack F Vogel 		cmd->command &= ~I40E_AQ_PHY_LINK_ENABLE;
194261ae650dSJack F Vogel 
194361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
194461ae650dSJack F Vogel 
194561ae650dSJack F Vogel 	return status;
194661ae650dSJack F Vogel }
194761ae650dSJack F Vogel 
194861ae650dSJack F Vogel /**
194961ae650dSJack F Vogel  * i40e_aq_get_link_info
195061ae650dSJack F Vogel  * @hw: pointer to the hw struct
195161ae650dSJack F Vogel  * @enable_lse: enable/disable LinkStatusEvent reporting
195261ae650dSJack F Vogel  * @link: pointer to link status structure - optional
195361ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
195461ae650dSJack F Vogel  *
195561ae650dSJack F Vogel  * Returns the link status of the adapter.
195661ae650dSJack F Vogel  **/
i40e_aq_get_link_info(struct i40e_hw * hw,bool enable_lse,struct i40e_link_status * link,struct i40e_asq_cmd_details * cmd_details)195761ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw,
195861ae650dSJack F Vogel 				bool enable_lse, struct i40e_link_status *link,
195961ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
196061ae650dSJack F Vogel {
196161ae650dSJack F Vogel 	struct i40e_aq_desc desc;
196261ae650dSJack F Vogel 	struct i40e_aqc_get_link_status *resp =
196361ae650dSJack F Vogel 		(struct i40e_aqc_get_link_status *)&desc.params.raw;
196461ae650dSJack F Vogel 	struct i40e_link_status *hw_link_info = &hw->phy.link_info;
196561ae650dSJack F Vogel 	enum i40e_status_code status;
196661ae650dSJack F Vogel 	bool tx_pause, rx_pause;
196761ae650dSJack F Vogel 	u16 command_flags;
196861ae650dSJack F Vogel 
196961ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
197061ae650dSJack F Vogel 
197161ae650dSJack F Vogel 	if (enable_lse)
197261ae650dSJack F Vogel 		command_flags = I40E_AQ_LSE_ENABLE;
197361ae650dSJack F Vogel 	else
197461ae650dSJack F Vogel 		command_flags = I40E_AQ_LSE_DISABLE;
197561ae650dSJack F Vogel 	resp->command_flags = CPU_TO_LE16(command_flags);
197661ae650dSJack F Vogel 
197761ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
197861ae650dSJack F Vogel 
197961ae650dSJack F Vogel 	if (status != I40E_SUCCESS)
198061ae650dSJack F Vogel 		goto aq_get_link_info_exit;
198161ae650dSJack F Vogel 
198261ae650dSJack F Vogel 	/* save off old link status information */
198361ae650dSJack F Vogel 	i40e_memcpy(&hw->phy.link_info_old, hw_link_info,
1984f247dc25SJack F Vogel 		    sizeof(*hw_link_info), I40E_NONDMA_TO_NONDMA);
198561ae650dSJack F Vogel 
198661ae650dSJack F Vogel 	/* update link status */
198761ae650dSJack F Vogel 	hw_link_info->phy_type = (enum i40e_aq_phy_type)resp->phy_type;
198861ae650dSJack F Vogel 	hw->phy.media_type = i40e_get_media_type(hw);
198961ae650dSJack F Vogel 	hw_link_info->link_speed = (enum i40e_aq_link_speed)resp->link_speed;
199061ae650dSJack F Vogel 	hw_link_info->link_info = resp->link_info;
199161ae650dSJack F Vogel 	hw_link_info->an_info = resp->an_info;
1992cb6b8299SEric Joyner 	hw_link_info->fec_info = resp->config & (I40E_AQ_CONFIG_FEC_KR_ENA |
1993cb6b8299SEric Joyner 						 I40E_AQ_CONFIG_FEC_RS_ENA);
199461ae650dSJack F Vogel 	hw_link_info->ext_info = resp->ext_info;
1995ceebc2f3SEric Joyner 	hw_link_info->loopback = resp->loopback & I40E_AQ_LOOPBACK_MASK;
199661ae650dSJack F Vogel 	hw_link_info->max_frame_size = LE16_TO_CPU(resp->max_frame_size);
199761ae650dSJack F Vogel 	hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
199861ae650dSJack F Vogel 
199961ae650dSJack F Vogel 	/* update fc info */
200061ae650dSJack F Vogel 	tx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_TX);
200161ae650dSJack F Vogel 	rx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_RX);
200261ae650dSJack F Vogel 	if (tx_pause & rx_pause)
200361ae650dSJack F Vogel 		hw->fc.current_mode = I40E_FC_FULL;
200461ae650dSJack F Vogel 	else if (tx_pause)
200561ae650dSJack F Vogel 		hw->fc.current_mode = I40E_FC_TX_PAUSE;
200661ae650dSJack F Vogel 	else if (rx_pause)
200761ae650dSJack F Vogel 		hw->fc.current_mode = I40E_FC_RX_PAUSE;
200861ae650dSJack F Vogel 	else
200961ae650dSJack F Vogel 		hw->fc.current_mode = I40E_FC_NONE;
201061ae650dSJack F Vogel 
201161ae650dSJack F Vogel 	if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
201261ae650dSJack F Vogel 		hw_link_info->crc_enable = TRUE;
201361ae650dSJack F Vogel 	else
201461ae650dSJack F Vogel 		hw_link_info->crc_enable = FALSE;
201561ae650dSJack F Vogel 
2016cb6b8299SEric Joyner 	if (resp->command_flags & CPU_TO_LE16(I40E_AQ_LSE_IS_ENABLED))
201761ae650dSJack F Vogel 		hw_link_info->lse_enable = TRUE;
201861ae650dSJack F Vogel 	else
201961ae650dSJack F Vogel 		hw_link_info->lse_enable = FALSE;
202061ae650dSJack F Vogel 
2021cb6b8299SEric Joyner 	if ((hw->mac.type == I40E_MAC_XL710) &&
2022cb6b8299SEric Joyner 	    (hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
2023b6c8f260SJack F Vogel 	     hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
2024b6c8f260SJack F Vogel 		hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
2025b6c8f260SJack F Vogel 
2026abf77452SKrzysztof Galazka 	/* 'Get Link Status' response data structure from X722 FW has
2027abf77452SKrzysztof Galazka 	 * different format and does not contain this information
2028abf77452SKrzysztof Galazka 	 */
2029b4a7ce06SEric Joyner 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE &&
2030b4a7ce06SEric Joyner 	    hw->mac.type != I40E_MAC_X722) {
2031ceebc2f3SEric Joyner 		__le32 tmp;
2032ceebc2f3SEric Joyner 
2033ceebc2f3SEric Joyner 		i40e_memcpy(&tmp, resp->link_type, sizeof(tmp),
2034ceebc2f3SEric Joyner 			    I40E_NONDMA_TO_NONDMA);
2035ceebc2f3SEric Joyner 		hw->phy.phy_types = LE32_TO_CPU(tmp);
2036ceebc2f3SEric Joyner 		hw->phy.phy_types |= ((u64)resp->link_type_ext << 32);
2037ceebc2f3SEric Joyner 	}
2038ceebc2f3SEric Joyner 
203961ae650dSJack F Vogel 	/* save link status information */
204061ae650dSJack F Vogel 	if (link)
2041f247dc25SJack F Vogel 		i40e_memcpy(link, hw_link_info, sizeof(*hw_link_info),
204261ae650dSJack F Vogel 			    I40E_NONDMA_TO_NONDMA);
204361ae650dSJack F Vogel 
204461ae650dSJack F Vogel 	/* flag cleared so helper functions don't call AQ again */
204561ae650dSJack F Vogel 	hw->phy.get_link_info = FALSE;
204661ae650dSJack F Vogel 
204761ae650dSJack F Vogel aq_get_link_info_exit:
204861ae650dSJack F Vogel 	return status;
204961ae650dSJack F Vogel }
205061ae650dSJack F Vogel 
205161ae650dSJack F Vogel /**
205261ae650dSJack F Vogel  * i40e_aq_set_phy_int_mask
205361ae650dSJack F Vogel  * @hw: pointer to the hw struct
205461ae650dSJack F Vogel  * @mask: interrupt mask to be set
205561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
205661ae650dSJack F Vogel  *
205761ae650dSJack F Vogel  * Set link interrupt mask.
205861ae650dSJack F Vogel  **/
i40e_aq_set_phy_int_mask(struct i40e_hw * hw,u16 mask,struct i40e_asq_cmd_details * cmd_details)205961ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
206061ae650dSJack F Vogel 				u16 mask,
206161ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
206261ae650dSJack F Vogel {
206361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
206461ae650dSJack F Vogel 	struct i40e_aqc_set_phy_int_mask *cmd =
206561ae650dSJack F Vogel 		(struct i40e_aqc_set_phy_int_mask *)&desc.params.raw;
206661ae650dSJack F Vogel 	enum i40e_status_code status;
206761ae650dSJack F Vogel 
206861ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
206961ae650dSJack F Vogel 					  i40e_aqc_opc_set_phy_int_mask);
207061ae650dSJack F Vogel 
207161ae650dSJack F Vogel 	cmd->event_mask = CPU_TO_LE16(mask);
207261ae650dSJack F Vogel 
207361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
207461ae650dSJack F Vogel 
207561ae650dSJack F Vogel 	return status;
207661ae650dSJack F Vogel }
207761ae650dSJack F Vogel 
207861ae650dSJack F Vogel /**
207961ae650dSJack F Vogel  * i40e_aq_get_local_advt_reg
208061ae650dSJack F Vogel  * @hw: pointer to the hw struct
208161ae650dSJack F Vogel  * @advt_reg: local AN advertisement register value
208261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
208361ae650dSJack F Vogel  *
208461ae650dSJack F Vogel  * Get the Local AN advertisement register value.
208561ae650dSJack F Vogel  **/
i40e_aq_get_local_advt_reg(struct i40e_hw * hw,u64 * advt_reg,struct i40e_asq_cmd_details * cmd_details)208661ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_local_advt_reg(struct i40e_hw *hw,
208761ae650dSJack F Vogel 				u64 *advt_reg,
208861ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
208961ae650dSJack F Vogel {
209061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
209161ae650dSJack F Vogel 	struct i40e_aqc_an_advt_reg *resp =
209261ae650dSJack F Vogel 		(struct i40e_aqc_an_advt_reg *)&desc.params.raw;
209361ae650dSJack F Vogel 	enum i40e_status_code status;
209461ae650dSJack F Vogel 
209561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
209661ae650dSJack F Vogel 					  i40e_aqc_opc_get_local_advt_reg);
209761ae650dSJack F Vogel 
209861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
209961ae650dSJack F Vogel 
210061ae650dSJack F Vogel 	if (status != I40E_SUCCESS)
210161ae650dSJack F Vogel 		goto aq_get_local_advt_reg_exit;
210261ae650dSJack F Vogel 
210361ae650dSJack F Vogel 	*advt_reg = (u64)(LE16_TO_CPU(resp->local_an_reg1)) << 32;
210461ae650dSJack F Vogel 	*advt_reg |= LE32_TO_CPU(resp->local_an_reg0);
210561ae650dSJack F Vogel 
210661ae650dSJack F Vogel aq_get_local_advt_reg_exit:
210761ae650dSJack F Vogel 	return status;
210861ae650dSJack F Vogel }
210961ae650dSJack F Vogel 
211061ae650dSJack F Vogel /**
211161ae650dSJack F Vogel  * i40e_aq_set_local_advt_reg
211261ae650dSJack F Vogel  * @hw: pointer to the hw struct
211361ae650dSJack F Vogel  * @advt_reg: local AN advertisement register value
211461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
211561ae650dSJack F Vogel  *
211661ae650dSJack F Vogel  * Get the Local AN advertisement register value.
211761ae650dSJack F Vogel  **/
i40e_aq_set_local_advt_reg(struct i40e_hw * hw,u64 advt_reg,struct i40e_asq_cmd_details * cmd_details)211861ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_local_advt_reg(struct i40e_hw *hw,
211961ae650dSJack F Vogel 				u64 advt_reg,
212061ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
212161ae650dSJack F Vogel {
212261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
212361ae650dSJack F Vogel 	struct i40e_aqc_an_advt_reg *cmd =
212461ae650dSJack F Vogel 		(struct i40e_aqc_an_advt_reg *)&desc.params.raw;
212561ae650dSJack F Vogel 	enum i40e_status_code status;
212661ae650dSJack F Vogel 
212761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
212861ae650dSJack F Vogel 					  i40e_aqc_opc_get_local_advt_reg);
212961ae650dSJack F Vogel 
213061ae650dSJack F Vogel 	cmd->local_an_reg0 = CPU_TO_LE32(I40E_LO_DWORD(advt_reg));
213161ae650dSJack F Vogel 	cmd->local_an_reg1 = CPU_TO_LE16(I40E_HI_DWORD(advt_reg));
213261ae650dSJack F Vogel 
213361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
213461ae650dSJack F Vogel 
213561ae650dSJack F Vogel 	return status;
213661ae650dSJack F Vogel }
213761ae650dSJack F Vogel 
213861ae650dSJack F Vogel /**
213961ae650dSJack F Vogel  * i40e_aq_get_partner_advt
214061ae650dSJack F Vogel  * @hw: pointer to the hw struct
214161ae650dSJack F Vogel  * @advt_reg: AN partner advertisement register value
214261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
214361ae650dSJack F Vogel  *
214461ae650dSJack F Vogel  * Get the link partner AN advertisement register value.
214561ae650dSJack F Vogel  **/
i40e_aq_get_partner_advt(struct i40e_hw * hw,u64 * advt_reg,struct i40e_asq_cmd_details * cmd_details)214661ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_partner_advt(struct i40e_hw *hw,
214761ae650dSJack F Vogel 				u64 *advt_reg,
214861ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
214961ae650dSJack F Vogel {
215061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
215161ae650dSJack F Vogel 	struct i40e_aqc_an_advt_reg *resp =
215261ae650dSJack F Vogel 		(struct i40e_aqc_an_advt_reg *)&desc.params.raw;
215361ae650dSJack F Vogel 	enum i40e_status_code status;
215461ae650dSJack F Vogel 
215561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
215661ae650dSJack F Vogel 					  i40e_aqc_opc_get_partner_advt);
215761ae650dSJack F Vogel 
215861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
215961ae650dSJack F Vogel 
216061ae650dSJack F Vogel 	if (status != I40E_SUCCESS)
216161ae650dSJack F Vogel 		goto aq_get_partner_advt_exit;
216261ae650dSJack F Vogel 
216361ae650dSJack F Vogel 	*advt_reg = (u64)(LE16_TO_CPU(resp->local_an_reg1)) << 32;
216461ae650dSJack F Vogel 	*advt_reg |= LE32_TO_CPU(resp->local_an_reg0);
216561ae650dSJack F Vogel 
216661ae650dSJack F Vogel aq_get_partner_advt_exit:
216761ae650dSJack F Vogel 	return status;
216861ae650dSJack F Vogel }
216961ae650dSJack F Vogel 
217061ae650dSJack F Vogel /**
217161ae650dSJack F Vogel  * i40e_aq_set_lb_modes
217261ae650dSJack F Vogel  * @hw: pointer to the hw struct
217361ae650dSJack F Vogel  * @lb_modes: loopback mode to be set
217461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
217561ae650dSJack F Vogel  *
217661ae650dSJack F Vogel  * Sets loopback modes.
217761ae650dSJack F Vogel  **/
2178ceebc2f3SEric Joyner enum i40e_status_code
i40e_aq_set_lb_modes(struct i40e_hw * hw,u8 lb_level,u8 lb_type,u8 speed,struct i40e_asq_cmd_details * cmd_details)2179ceebc2f3SEric Joyner i40e_aq_set_lb_modes(struct i40e_hw *hw, u8 lb_level, u8 lb_type, u8 speed,
218061ae650dSJack F Vogel 		     struct i40e_asq_cmd_details *cmd_details)
218161ae650dSJack F Vogel {
218261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
218361ae650dSJack F Vogel 	struct i40e_aqc_set_lb_mode *cmd =
218461ae650dSJack F Vogel 		(struct i40e_aqc_set_lb_mode *)&desc.params.raw;
218561ae650dSJack F Vogel 	enum i40e_status_code status;
218661ae650dSJack F Vogel 
218761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
218861ae650dSJack F Vogel 					  i40e_aqc_opc_set_lb_modes);
218961ae650dSJack F Vogel 
2190ceebc2f3SEric Joyner 	cmd->lb_level = lb_level;
2191ceebc2f3SEric Joyner 	cmd->lb_type = lb_type;
2192ceebc2f3SEric Joyner 	cmd->speed = speed;
2193ceebc2f3SEric Joyner 	if (speed)
2194ceebc2f3SEric Joyner 		cmd->force_speed = 1;
219561ae650dSJack F Vogel 
219661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
219761ae650dSJack F Vogel 
219861ae650dSJack F Vogel 	return status;
219961ae650dSJack F Vogel }
220061ae650dSJack F Vogel 
220161ae650dSJack F Vogel /**
220261ae650dSJack F Vogel  * i40e_aq_set_phy_debug
220361ae650dSJack F Vogel  * @hw: pointer to the hw struct
220461ae650dSJack F Vogel  * @cmd_flags: debug command flags
220561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
220661ae650dSJack F Vogel  *
220761ae650dSJack F Vogel  * Reset the external PHY.
220861ae650dSJack F Vogel  **/
i40e_aq_set_phy_debug(struct i40e_hw * hw,u8 cmd_flags,struct i40e_asq_cmd_details * cmd_details)220961ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
221061ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
221161ae650dSJack F Vogel {
221261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
221361ae650dSJack F Vogel 	struct i40e_aqc_set_phy_debug *cmd =
221461ae650dSJack F Vogel 		(struct i40e_aqc_set_phy_debug *)&desc.params.raw;
221561ae650dSJack F Vogel 	enum i40e_status_code status;
221661ae650dSJack F Vogel 
221761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
221861ae650dSJack F Vogel 					  i40e_aqc_opc_set_phy_debug);
221961ae650dSJack F Vogel 
222061ae650dSJack F Vogel 	cmd->command_flags = cmd_flags;
222161ae650dSJack F Vogel 
222261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
222361ae650dSJack F Vogel 
222461ae650dSJack F Vogel 	return status;
222561ae650dSJack F Vogel }
222661ae650dSJack F Vogel 
222761ae650dSJack F Vogel /**
2228abf77452SKrzysztof Galazka  * i40e_hw_ver_ge
2229abf77452SKrzysztof Galazka  * @hw: pointer to the hw struct
2230abf77452SKrzysztof Galazka  * @maj: api major value
2231abf77452SKrzysztof Galazka  * @min: api minor value
2232abf77452SKrzysztof Galazka  *
2233abf77452SKrzysztof Galazka  * Assert whether current HW api version is greater/equal than provided.
2234abf77452SKrzysztof Galazka  **/
i40e_hw_ver_ge(struct i40e_hw * hw,u16 maj,u16 min)2235abf77452SKrzysztof Galazka static bool i40e_hw_ver_ge(struct i40e_hw *hw, u16 maj, u16 min)
2236abf77452SKrzysztof Galazka {
2237abf77452SKrzysztof Galazka 	if (hw->aq.api_maj_ver > maj ||
2238abf77452SKrzysztof Galazka 	    (hw->aq.api_maj_ver == maj && hw->aq.api_min_ver >= min))
2239abf77452SKrzysztof Galazka 		return TRUE;
2240abf77452SKrzysztof Galazka 	return FALSE;
2241abf77452SKrzysztof Galazka }
2242abf77452SKrzysztof Galazka 
2243abf77452SKrzysztof Galazka /**
224461ae650dSJack F Vogel  * i40e_aq_add_vsi
224561ae650dSJack F Vogel  * @hw: pointer to the hw struct
224661ae650dSJack F Vogel  * @vsi_ctx: pointer to a vsi context struct
224761ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
224861ae650dSJack F Vogel  *
224961ae650dSJack F Vogel  * Add a VSI context to the hardware.
225061ae650dSJack F Vogel **/
i40e_aq_add_vsi(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)225161ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_vsi(struct i40e_hw *hw,
225261ae650dSJack F Vogel 				struct i40e_vsi_context *vsi_ctx,
225361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
225461ae650dSJack F Vogel {
225561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
225661ae650dSJack F Vogel 	struct i40e_aqc_add_get_update_vsi *cmd =
225761ae650dSJack F Vogel 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
225861ae650dSJack F Vogel 	struct i40e_aqc_add_get_update_vsi_completion *resp =
225961ae650dSJack F Vogel 		(struct i40e_aqc_add_get_update_vsi_completion *)
226061ae650dSJack F Vogel 		&desc.params.raw;
226161ae650dSJack F Vogel 	enum i40e_status_code status;
226261ae650dSJack F Vogel 
226361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
226461ae650dSJack F Vogel 					  i40e_aqc_opc_add_vsi);
226561ae650dSJack F Vogel 
226661ae650dSJack F Vogel 	cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->uplink_seid);
226761ae650dSJack F Vogel 	cmd->connection_type = vsi_ctx->connection_type;
226861ae650dSJack F Vogel 	cmd->vf_id = vsi_ctx->vf_num;
226961ae650dSJack F Vogel 	cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags);
227061ae650dSJack F Vogel 
227161ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
227261ae650dSJack F Vogel 
227361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
227461ae650dSJack F Vogel 				       sizeof(vsi_ctx->info), cmd_details);
227561ae650dSJack F Vogel 
227661ae650dSJack F Vogel 	if (status != I40E_SUCCESS)
227761ae650dSJack F Vogel 		goto aq_add_vsi_exit;
227861ae650dSJack F Vogel 
227961ae650dSJack F Vogel 	vsi_ctx->seid = LE16_TO_CPU(resp->seid);
228061ae650dSJack F Vogel 	vsi_ctx->vsi_number = LE16_TO_CPU(resp->vsi_number);
228161ae650dSJack F Vogel 	vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
228261ae650dSJack F Vogel 	vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
228361ae650dSJack F Vogel 
228461ae650dSJack F Vogel aq_add_vsi_exit:
228561ae650dSJack F Vogel 	return status;
228661ae650dSJack F Vogel }
228761ae650dSJack F Vogel 
228861ae650dSJack F Vogel /**
228961ae650dSJack F Vogel  * i40e_aq_set_default_vsi
229061ae650dSJack F Vogel  * @hw: pointer to the hw struct
229161ae650dSJack F Vogel  * @seid: vsi number
229261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
229361ae650dSJack F Vogel  **/
i40e_aq_set_default_vsi(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)229461ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_default_vsi(struct i40e_hw *hw,
229561ae650dSJack F Vogel 				u16 seid,
229661ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
229761ae650dSJack F Vogel {
229861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
229961ae650dSJack F Vogel 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
230061ae650dSJack F Vogel 		(struct i40e_aqc_set_vsi_promiscuous_modes *)
230161ae650dSJack F Vogel 		&desc.params.raw;
230261ae650dSJack F Vogel 	enum i40e_status_code status;
230361ae650dSJack F Vogel 
230461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
230561ae650dSJack F Vogel 					i40e_aqc_opc_set_vsi_promiscuous_modes);
230661ae650dSJack F Vogel 
230761ae650dSJack F Vogel 	cmd->promiscuous_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
230861ae650dSJack F Vogel 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
230961ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
231061ae650dSJack F Vogel 
231161ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
231261ae650dSJack F Vogel 
231361ae650dSJack F Vogel 	return status;
231461ae650dSJack F Vogel }
231561ae650dSJack F Vogel 
231661ae650dSJack F Vogel /**
23174294f337SSean Bruno  * i40e_aq_clear_default_vsi
23184294f337SSean Bruno  * @hw: pointer to the hw struct
23194294f337SSean Bruno  * @seid: vsi number
23204294f337SSean Bruno  * @cmd_details: pointer to command details structure or NULL
23214294f337SSean Bruno  **/
i40e_aq_clear_default_vsi(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)23224294f337SSean Bruno enum i40e_status_code i40e_aq_clear_default_vsi(struct i40e_hw *hw,
23234294f337SSean Bruno 				u16 seid,
23244294f337SSean Bruno 				struct i40e_asq_cmd_details *cmd_details)
23254294f337SSean Bruno {
23264294f337SSean Bruno 	struct i40e_aq_desc desc;
23274294f337SSean Bruno 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
23284294f337SSean Bruno 		(struct i40e_aqc_set_vsi_promiscuous_modes *)
23294294f337SSean Bruno 		&desc.params.raw;
23304294f337SSean Bruno 	enum i40e_status_code status;
23314294f337SSean Bruno 
23324294f337SSean Bruno 	i40e_fill_default_direct_cmd_desc(&desc,
23334294f337SSean Bruno 					i40e_aqc_opc_set_vsi_promiscuous_modes);
23344294f337SSean Bruno 
23354294f337SSean Bruno 	cmd->promiscuous_flags = CPU_TO_LE16(0);
23364294f337SSean Bruno 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_DEFAULT);
23374294f337SSean Bruno 	cmd->seid = CPU_TO_LE16(seid);
23384294f337SSean Bruno 
23394294f337SSean Bruno 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
23404294f337SSean Bruno 
23414294f337SSean Bruno 	return status;
23424294f337SSean Bruno }
23434294f337SSean Bruno 
23444294f337SSean Bruno /**
234561ae650dSJack F Vogel  * i40e_aq_set_vsi_unicast_promiscuous
234661ae650dSJack F Vogel  * @hw: pointer to the hw struct
234761ae650dSJack F Vogel  * @seid: vsi number
234861ae650dSJack F Vogel  * @set: set unicast promiscuous enable/disable
234961ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
23504294f337SSean Bruno  * @rx_only_promisc: flag to decide if egress traffic gets mirrored in promisc
235161ae650dSJack F Vogel  **/
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)235261ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
235361ae650dSJack F Vogel 				u16 seid, bool set,
23544294f337SSean Bruno 				struct i40e_asq_cmd_details *cmd_details,
23554294f337SSean Bruno 				bool rx_only_promisc)
235661ae650dSJack F Vogel {
235761ae650dSJack F Vogel 	struct i40e_aq_desc desc;
235861ae650dSJack F Vogel 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
235961ae650dSJack F Vogel 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
236061ae650dSJack F Vogel 	enum i40e_status_code status;
236161ae650dSJack F Vogel 	u16 flags = 0;
236261ae650dSJack F Vogel 
236361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
236461ae650dSJack F Vogel 					i40e_aqc_opc_set_vsi_promiscuous_modes);
236561ae650dSJack F Vogel 
23666d011ad5SEric Joyner 	if (set) {
236761ae650dSJack F Vogel 		flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2368abf77452SKrzysztof Galazka 		if (rx_only_promisc && i40e_hw_ver_ge(hw, 1, 5))
2369abf77452SKrzysztof Galazka 			flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
23706d011ad5SEric Joyner 	}
237161ae650dSJack F Vogel 
237261ae650dSJack F Vogel 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
237361ae650dSJack F Vogel 
237461ae650dSJack F Vogel 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2375abf77452SKrzysztof Galazka 	if (i40e_hw_ver_ge(hw, 1, 5))
2376abf77452SKrzysztof Galazka 		cmd->valid_flags |=
2377abf77452SKrzysztof Galazka 			CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
237861ae650dSJack F Vogel 
237961ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
238061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
238161ae650dSJack F Vogel 
238261ae650dSJack F Vogel 	return status;
238361ae650dSJack F Vogel }
238461ae650dSJack F Vogel 
238561ae650dSJack F Vogel /**
238661ae650dSJack F Vogel  * i40e_aq_set_vsi_multicast_promiscuous
238761ae650dSJack F Vogel  * @hw: pointer to the hw struct
238861ae650dSJack F Vogel  * @seid: vsi number
238961ae650dSJack F Vogel  * @set: set multicast promiscuous enable/disable
239061ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
239161ae650dSJack F Vogel  **/
i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw * hw,u16 seid,bool set,struct i40e_asq_cmd_details * cmd_details)239261ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
239361ae650dSJack F Vogel 				u16 seid, bool set, struct i40e_asq_cmd_details *cmd_details)
239461ae650dSJack F Vogel {
239561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
239661ae650dSJack F Vogel 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
239761ae650dSJack F Vogel 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
239861ae650dSJack F Vogel 	enum i40e_status_code status;
239961ae650dSJack F Vogel 	u16 flags = 0;
240061ae650dSJack F Vogel 
240161ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
240261ae650dSJack F Vogel 					i40e_aqc_opc_set_vsi_promiscuous_modes);
240361ae650dSJack F Vogel 
240461ae650dSJack F Vogel 	if (set)
240561ae650dSJack F Vogel 		flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
240661ae650dSJack F Vogel 
240761ae650dSJack F Vogel 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
240861ae650dSJack F Vogel 
240961ae650dSJack F Vogel 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
241061ae650dSJack F Vogel 
241161ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
241261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
241361ae650dSJack F Vogel 
241461ae650dSJack F Vogel 	return status;
241561ae650dSJack F Vogel }
241661ae650dSJack F Vogel 
241761ae650dSJack F Vogel /**
2418cb6b8299SEric Joyner * i40e_aq_set_vsi_full_promiscuous
2419cb6b8299SEric Joyner * @hw: pointer to the hw struct
2420cb6b8299SEric Joyner * @seid: VSI number
2421cb6b8299SEric Joyner * @set: set promiscuous enable/disable
2422cb6b8299SEric Joyner * @cmd_details: pointer to command details structure or NULL
2423cb6b8299SEric Joyner **/
i40e_aq_set_vsi_full_promiscuous(struct i40e_hw * hw,u16 seid,bool set,struct i40e_asq_cmd_details * cmd_details)2424cb6b8299SEric Joyner enum i40e_status_code i40e_aq_set_vsi_full_promiscuous(struct i40e_hw *hw,
2425cb6b8299SEric Joyner 				u16 seid, bool set,
2426cb6b8299SEric Joyner 				struct i40e_asq_cmd_details *cmd_details)
2427cb6b8299SEric Joyner {
2428cb6b8299SEric Joyner 	struct i40e_aq_desc desc;
2429cb6b8299SEric Joyner 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2430cb6b8299SEric Joyner 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2431cb6b8299SEric Joyner 	enum i40e_status_code status;
2432cb6b8299SEric Joyner 	u16 flags = 0;
2433cb6b8299SEric Joyner 
2434cb6b8299SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
2435cb6b8299SEric Joyner 		i40e_aqc_opc_set_vsi_promiscuous_modes);
2436cb6b8299SEric Joyner 
2437cb6b8299SEric Joyner 	if (set)
2438cb6b8299SEric Joyner 		flags = I40E_AQC_SET_VSI_PROMISC_UNICAST   |
2439cb6b8299SEric Joyner 			I40E_AQC_SET_VSI_PROMISC_MULTICAST |
2440cb6b8299SEric Joyner 			I40E_AQC_SET_VSI_PROMISC_BROADCAST;
2441cb6b8299SEric Joyner 
2442cb6b8299SEric Joyner 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2443cb6b8299SEric Joyner 
2444cb6b8299SEric Joyner 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST   |
2445cb6b8299SEric Joyner 				       I40E_AQC_SET_VSI_PROMISC_MULTICAST |
2446cb6b8299SEric Joyner 				       I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2447cb6b8299SEric Joyner 
2448cb6b8299SEric Joyner 	cmd->seid = CPU_TO_LE16(seid);
2449cb6b8299SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2450cb6b8299SEric Joyner 
2451cb6b8299SEric Joyner 	return status;
2452cb6b8299SEric Joyner }
2453cb6b8299SEric Joyner 
2454cb6b8299SEric Joyner /**
2455be771cdaSJack F Vogel  * i40e_aq_set_vsi_mc_promisc_on_vlan
2456be771cdaSJack F Vogel  * @hw: pointer to the hw struct
2457be771cdaSJack F Vogel  * @seid: vsi number
2458be771cdaSJack F Vogel  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2459be771cdaSJack F Vogel  * @vid: The VLAN tag filter - capture any multicast packet with this VLAN tag
2460be771cdaSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
2461be771cdaSJack F Vogel  **/
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)2462be771cdaSJack F Vogel enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
2463be771cdaSJack F Vogel 				u16 seid, bool enable, u16 vid,
2464be771cdaSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
2465be771cdaSJack F Vogel {
2466be771cdaSJack F Vogel 	struct i40e_aq_desc desc;
2467be771cdaSJack F Vogel 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2468be771cdaSJack F Vogel 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2469be771cdaSJack F Vogel 	enum i40e_status_code status;
2470be771cdaSJack F Vogel 	u16 flags = 0;
2471be771cdaSJack F Vogel 
2472be771cdaSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
2473be771cdaSJack F Vogel 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2474be771cdaSJack F Vogel 
2475be771cdaSJack F Vogel 	if (enable)
2476be771cdaSJack F Vogel 		flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2477be771cdaSJack F Vogel 
2478be771cdaSJack F Vogel 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2479be771cdaSJack F Vogel 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2480be771cdaSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
2481be771cdaSJack F Vogel 	cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2482be771cdaSJack F Vogel 
2483be771cdaSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2484be771cdaSJack F Vogel 
2485be771cdaSJack F Vogel 	return status;
2486be771cdaSJack F Vogel }
2487be771cdaSJack F Vogel 
2488be771cdaSJack F Vogel /**
2489be771cdaSJack F Vogel  * i40e_aq_set_vsi_uc_promisc_on_vlan
2490be771cdaSJack F Vogel  * @hw: pointer to the hw struct
2491be771cdaSJack F Vogel  * @seid: vsi number
2492be771cdaSJack F Vogel  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2493be771cdaSJack F Vogel  * @vid: The VLAN tag filter - capture any unicast packet with this VLAN tag
2494be771cdaSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
2495be771cdaSJack F Vogel  **/
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)2496be771cdaSJack F Vogel enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
2497be771cdaSJack F Vogel 				u16 seid, bool enable, u16 vid,
2498be771cdaSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
2499be771cdaSJack F Vogel {
2500be771cdaSJack F Vogel 	struct i40e_aq_desc desc;
2501be771cdaSJack F Vogel 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2502be771cdaSJack F Vogel 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2503be771cdaSJack F Vogel 	enum i40e_status_code status;
2504be771cdaSJack F Vogel 	u16 flags = 0;
2505be771cdaSJack F Vogel 
2506be771cdaSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
2507be771cdaSJack F Vogel 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2508be771cdaSJack F Vogel 
2509abf77452SKrzysztof Galazka 	if (enable) {
2510be771cdaSJack F Vogel 		flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2511abf77452SKrzysztof Galazka 		if (i40e_hw_ver_ge(hw, 1, 5))
2512abf77452SKrzysztof Galazka 			flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
2513abf77452SKrzysztof Galazka 	}
2514be771cdaSJack F Vogel 
2515be771cdaSJack F Vogel 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2516be771cdaSJack F Vogel 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2517abf77452SKrzysztof Galazka 	if (i40e_hw_ver_ge(hw, 1, 5))
2518abf77452SKrzysztof Galazka 		cmd->valid_flags |=
2519abf77452SKrzysztof Galazka 			CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
2520be771cdaSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
2521be771cdaSJack F Vogel 	cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2522be771cdaSJack F Vogel 
2523be771cdaSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2524be771cdaSJack F Vogel 
2525be771cdaSJack F Vogel 	return status;
2526be771cdaSJack F Vogel }
2527be771cdaSJack F Vogel 
2528be771cdaSJack F Vogel /**
2529cb6b8299SEric Joyner  * i40e_aq_set_vsi_bc_promisc_on_vlan
2530cb6b8299SEric Joyner  * @hw: pointer to the hw struct
2531cb6b8299SEric Joyner  * @seid: vsi number
2532cb6b8299SEric Joyner  * @enable: set broadcast promiscuous enable/disable for a given VLAN
2533cb6b8299SEric Joyner  * @vid: The VLAN tag filter - capture any broadcast packet with this VLAN tag
2534cb6b8299SEric Joyner  * @cmd_details: pointer to command details structure or NULL
2535cb6b8299SEric Joyner  **/
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)2536cb6b8299SEric Joyner enum i40e_status_code i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
2537cb6b8299SEric Joyner 				u16 seid, bool enable, u16 vid,
2538cb6b8299SEric Joyner 				struct i40e_asq_cmd_details *cmd_details)
2539cb6b8299SEric Joyner {
2540cb6b8299SEric Joyner 	struct i40e_aq_desc desc;
2541cb6b8299SEric Joyner 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2542cb6b8299SEric Joyner 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2543cb6b8299SEric Joyner 	enum i40e_status_code status;
2544cb6b8299SEric Joyner 	u16 flags = 0;
2545cb6b8299SEric Joyner 
2546cb6b8299SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
2547cb6b8299SEric Joyner 					i40e_aqc_opc_set_vsi_promiscuous_modes);
2548cb6b8299SEric Joyner 
2549cb6b8299SEric Joyner 	if (enable)
2550cb6b8299SEric Joyner 		flags |= I40E_AQC_SET_VSI_PROMISC_BROADCAST;
2551cb6b8299SEric Joyner 
2552cb6b8299SEric Joyner 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
2553cb6b8299SEric Joyner 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2554cb6b8299SEric Joyner 	cmd->seid = CPU_TO_LE16(seid);
2555cb6b8299SEric Joyner 	cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2556cb6b8299SEric Joyner 
2557cb6b8299SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2558cb6b8299SEric Joyner 
2559cb6b8299SEric Joyner 	return status;
2560cb6b8299SEric Joyner }
2561cb6b8299SEric Joyner 
2562cb6b8299SEric Joyner /**
256361ae650dSJack F Vogel  * i40e_aq_set_vsi_broadcast
256461ae650dSJack F Vogel  * @hw: pointer to the hw struct
256561ae650dSJack F Vogel  * @seid: vsi number
256661ae650dSJack F Vogel  * @set_filter: TRUE to set filter, FALSE to clear filter
256761ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
256861ae650dSJack F Vogel  *
256961ae650dSJack F Vogel  * Set or clear the broadcast promiscuous flag (filter) for a given VSI.
257061ae650dSJack F Vogel  **/
i40e_aq_set_vsi_broadcast(struct i40e_hw * hw,u16 seid,bool set_filter,struct i40e_asq_cmd_details * cmd_details)257161ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
257261ae650dSJack F Vogel 				u16 seid, bool set_filter,
257361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
257461ae650dSJack F Vogel {
257561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
257661ae650dSJack F Vogel 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
257761ae650dSJack F Vogel 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
257861ae650dSJack F Vogel 	enum i40e_status_code status;
257961ae650dSJack F Vogel 
258061ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
258161ae650dSJack F Vogel 					i40e_aqc_opc_set_vsi_promiscuous_modes);
258261ae650dSJack F Vogel 
258361ae650dSJack F Vogel 	if (set_filter)
258461ae650dSJack F Vogel 		cmd->promiscuous_flags
258561ae650dSJack F Vogel 			    |= CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
258661ae650dSJack F Vogel 	else
258761ae650dSJack F Vogel 		cmd->promiscuous_flags
258861ae650dSJack F Vogel 			    &= CPU_TO_LE16(~I40E_AQC_SET_VSI_PROMISC_BROADCAST);
258961ae650dSJack F Vogel 
259061ae650dSJack F Vogel 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
259161ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
259261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
259361ae650dSJack F Vogel 
259461ae650dSJack F Vogel 	return status;
259561ae650dSJack F Vogel }
259661ae650dSJack F Vogel 
259761ae650dSJack F Vogel /**
25981d767a8eSEric Joyner  * i40e_aq_set_vsi_vlan_promisc - control the VLAN promiscuous setting
25991d767a8eSEric Joyner  * @hw: pointer to the hw struct
26001d767a8eSEric Joyner  * @seid: vsi number
26011d767a8eSEric Joyner  * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
26021d767a8eSEric Joyner  * @cmd_details: pointer to command details structure or NULL
26031d767a8eSEric Joyner  **/
i40e_aq_set_vsi_vlan_promisc(struct i40e_hw * hw,u16 seid,bool enable,struct i40e_asq_cmd_details * cmd_details)26041d767a8eSEric Joyner enum i40e_status_code i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
26051d767a8eSEric Joyner 				u16 seid, bool enable,
26061d767a8eSEric Joyner 				struct i40e_asq_cmd_details *cmd_details)
26071d767a8eSEric Joyner {
26081d767a8eSEric Joyner 	struct i40e_aq_desc desc;
26091d767a8eSEric Joyner 	struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
26101d767a8eSEric Joyner 		(struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
26111d767a8eSEric Joyner 	enum i40e_status_code status;
26121d767a8eSEric Joyner 	u16 flags = 0;
26131d767a8eSEric Joyner 
26141d767a8eSEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
26151d767a8eSEric Joyner 					i40e_aqc_opc_set_vsi_promiscuous_modes);
26161d767a8eSEric Joyner 	if (enable)
26171d767a8eSEric Joyner 		flags |= I40E_AQC_SET_VSI_PROMISC_VLAN;
26181d767a8eSEric Joyner 
26191d767a8eSEric Joyner 	cmd->promiscuous_flags = CPU_TO_LE16(flags);
26201d767a8eSEric Joyner 	cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_VLAN);
26211d767a8eSEric Joyner 	cmd->seid = CPU_TO_LE16(seid);
26221d767a8eSEric Joyner 
26231d767a8eSEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
26241d767a8eSEric Joyner 
26251d767a8eSEric Joyner 	return status;
26261d767a8eSEric Joyner }
26271d767a8eSEric Joyner 
26281d767a8eSEric Joyner /**
2629abf77452SKrzysztof Galazka  * i40e_aq_get_vsi_params - get VSI configuration info
263061ae650dSJack F Vogel  * @hw: pointer to the hw struct
263161ae650dSJack F Vogel  * @vsi_ctx: pointer to a vsi context struct
263261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
263361ae650dSJack F Vogel  **/
i40e_aq_get_vsi_params(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)263461ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_vsi_params(struct i40e_hw *hw,
263561ae650dSJack F Vogel 				struct i40e_vsi_context *vsi_ctx,
263661ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
263761ae650dSJack F Vogel {
263861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
263961ae650dSJack F Vogel 	struct i40e_aqc_add_get_update_vsi *cmd =
264061ae650dSJack F Vogel 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
264161ae650dSJack F Vogel 	struct i40e_aqc_add_get_update_vsi_completion *resp =
264261ae650dSJack F Vogel 		(struct i40e_aqc_add_get_update_vsi_completion *)
264361ae650dSJack F Vogel 		&desc.params.raw;
264461ae650dSJack F Vogel 	enum i40e_status_code status;
264561ae650dSJack F Vogel 
264661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
264761ae650dSJack F Vogel 					  i40e_aqc_opc_get_vsi_parameters);
264861ae650dSJack F Vogel 
264961ae650dSJack F Vogel 	cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->seid);
265061ae650dSJack F Vogel 
265161ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
265261ae650dSJack F Vogel 
265361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
265461ae650dSJack F Vogel 				    sizeof(vsi_ctx->info), NULL);
265561ae650dSJack F Vogel 
265661ae650dSJack F Vogel 	if (status != I40E_SUCCESS)
265761ae650dSJack F Vogel 		goto aq_get_vsi_params_exit;
265861ae650dSJack F Vogel 
265961ae650dSJack F Vogel 	vsi_ctx->seid = LE16_TO_CPU(resp->seid);
266061ae650dSJack F Vogel 	vsi_ctx->vsi_number = LE16_TO_CPU(resp->vsi_number);
266161ae650dSJack F Vogel 	vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
266261ae650dSJack F Vogel 	vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
266361ae650dSJack F Vogel 
266461ae650dSJack F Vogel aq_get_vsi_params_exit:
266561ae650dSJack F Vogel 	return status;
266661ae650dSJack F Vogel }
266761ae650dSJack F Vogel 
266861ae650dSJack F Vogel /**
266961ae650dSJack F Vogel  * i40e_aq_update_vsi_params
267061ae650dSJack F Vogel  * @hw: pointer to the hw struct
267161ae650dSJack F Vogel  * @vsi_ctx: pointer to a vsi context struct
267261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
267361ae650dSJack F Vogel  *
267461ae650dSJack F Vogel  * Update a VSI context.
267561ae650dSJack F Vogel  **/
i40e_aq_update_vsi_params(struct i40e_hw * hw,struct i40e_vsi_context * vsi_ctx,struct i40e_asq_cmd_details * cmd_details)267661ae650dSJack F Vogel enum i40e_status_code i40e_aq_update_vsi_params(struct i40e_hw *hw,
267761ae650dSJack F Vogel 				struct i40e_vsi_context *vsi_ctx,
267861ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
267961ae650dSJack F Vogel {
268061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
268161ae650dSJack F Vogel 	struct i40e_aqc_add_get_update_vsi *cmd =
268261ae650dSJack F Vogel 		(struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
2683d4683565SEric Joyner 	struct i40e_aqc_add_get_update_vsi_completion *resp =
2684d4683565SEric Joyner 		(struct i40e_aqc_add_get_update_vsi_completion *)
2685d4683565SEric Joyner 		&desc.params.raw;
268661ae650dSJack F Vogel 	enum i40e_status_code status;
268761ae650dSJack F Vogel 
268861ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
268961ae650dSJack F Vogel 					  i40e_aqc_opc_update_vsi_parameters);
269061ae650dSJack F Vogel 	cmd->uplink_seid = CPU_TO_LE16(vsi_ctx->seid);
269161ae650dSJack F Vogel 
269261ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
269361ae650dSJack F Vogel 
269461ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
269561ae650dSJack F Vogel 				       sizeof(vsi_ctx->info), cmd_details);
269661ae650dSJack F Vogel 
2697d4683565SEric Joyner 	vsi_ctx->vsis_allocated = LE16_TO_CPU(resp->vsi_used);
2698d4683565SEric Joyner 	vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2699d4683565SEric Joyner 
270061ae650dSJack F Vogel 	return status;
270161ae650dSJack F Vogel }
270261ae650dSJack F Vogel 
270361ae650dSJack F Vogel /**
270461ae650dSJack F Vogel  * i40e_aq_get_switch_config
270561ae650dSJack F Vogel  * @hw: pointer to the hardware structure
270661ae650dSJack F Vogel  * @buf: pointer to the result buffer
270761ae650dSJack F Vogel  * @buf_size: length of input buffer
270861ae650dSJack F Vogel  * @start_seid: seid to start for the report, 0 == beginning
270961ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
271061ae650dSJack F Vogel  *
271161ae650dSJack F Vogel  * Fill the buf with switch configuration returned from AdminQ command
271261ae650dSJack F Vogel  **/
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)271361ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_switch_config(struct i40e_hw *hw,
271461ae650dSJack F Vogel 				struct i40e_aqc_get_switch_config_resp *buf,
271561ae650dSJack F Vogel 				u16 buf_size, u16 *start_seid,
271661ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
271761ae650dSJack F Vogel {
271861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
271961ae650dSJack F Vogel 	struct i40e_aqc_switch_seid *scfg =
272061ae650dSJack F Vogel 		(struct i40e_aqc_switch_seid *)&desc.params.raw;
272161ae650dSJack F Vogel 	enum i40e_status_code status;
272261ae650dSJack F Vogel 
272361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
272461ae650dSJack F Vogel 					  i40e_aqc_opc_get_switch_config);
272561ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
272661ae650dSJack F Vogel 	if (buf_size > I40E_AQ_LARGE_BUF)
272761ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
272861ae650dSJack F Vogel 	scfg->seid = CPU_TO_LE16(*start_seid);
272961ae650dSJack F Vogel 
273061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buf, buf_size, cmd_details);
273161ae650dSJack F Vogel 	*start_seid = LE16_TO_CPU(scfg->seid);
273261ae650dSJack F Vogel 
273361ae650dSJack F Vogel 	return status;
273461ae650dSJack F Vogel }
273561ae650dSJack F Vogel 
273661ae650dSJack F Vogel /**
27371d767a8eSEric Joyner  * i40e_aq_set_switch_config
27381d767a8eSEric Joyner  * @hw: pointer to the hardware structure
27391d767a8eSEric Joyner  * @flags: bit flag values to set
2740ceebc2f3SEric Joyner  * @mode: cloud filter mode
27411d767a8eSEric Joyner  * @valid_flags: which bit flags to set
27421d767a8eSEric Joyner  * @cmd_details: pointer to command details structure or NULL
27431d767a8eSEric Joyner  *
27441d767a8eSEric Joyner  * Set switch configuration bits
27451d767a8eSEric Joyner  **/
i40e_aq_set_switch_config(struct i40e_hw * hw,u16 flags,u16 valid_flags,u8 mode,struct i40e_asq_cmd_details * cmd_details)27461d767a8eSEric Joyner enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
2747ceebc2f3SEric Joyner 				u16 flags, u16 valid_flags, u8 mode,
27481d767a8eSEric Joyner 				struct i40e_asq_cmd_details *cmd_details)
27491d767a8eSEric Joyner {
27501d767a8eSEric Joyner 	struct i40e_aq_desc desc;
27511d767a8eSEric Joyner 	struct i40e_aqc_set_switch_config *scfg =
27521d767a8eSEric Joyner 		(struct i40e_aqc_set_switch_config *)&desc.params.raw;
27531d767a8eSEric Joyner 	enum i40e_status_code status;
27541d767a8eSEric Joyner 
27551d767a8eSEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
27561d767a8eSEric Joyner 					  i40e_aqc_opc_set_switch_config);
27571d767a8eSEric Joyner 	scfg->flags = CPU_TO_LE16(flags);
27581d767a8eSEric Joyner 	scfg->valid_flags = CPU_TO_LE16(valid_flags);
2759ceebc2f3SEric Joyner 	scfg->mode = mode;
2760ceebc2f3SEric Joyner 	if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
2761ceebc2f3SEric Joyner 		scfg->switch_tag = CPU_TO_LE16(hw->switch_tag);
2762ceebc2f3SEric Joyner 		scfg->first_tag = CPU_TO_LE16(hw->first_tag);
2763ceebc2f3SEric Joyner 		scfg->second_tag = CPU_TO_LE16(hw->second_tag);
2764ceebc2f3SEric Joyner 	}
27651d767a8eSEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
27661d767a8eSEric Joyner 
27671d767a8eSEric Joyner 	return status;
27681d767a8eSEric Joyner }
27691d767a8eSEric Joyner 
27701d767a8eSEric Joyner /**
277161ae650dSJack F Vogel  * i40e_aq_get_firmware_version
277261ae650dSJack F Vogel  * @hw: pointer to the hw struct
277361ae650dSJack F Vogel  * @fw_major_version: firmware major version
277461ae650dSJack F Vogel  * @fw_minor_version: firmware minor version
2775f247dc25SJack F Vogel  * @fw_build: firmware build number
277661ae650dSJack F Vogel  * @api_major_version: major queue version
277761ae650dSJack F Vogel  * @api_minor_version: minor queue version
277861ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
277961ae650dSJack F Vogel  *
278061ae650dSJack F Vogel  * Get the firmware version from the admin queue commands
278161ae650dSJack F Vogel  **/
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)278261ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_firmware_version(struct i40e_hw *hw,
278361ae650dSJack F Vogel 				u16 *fw_major_version, u16 *fw_minor_version,
2784f247dc25SJack F Vogel 				u32 *fw_build,
278561ae650dSJack F Vogel 				u16 *api_major_version, u16 *api_minor_version,
278661ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
278761ae650dSJack F Vogel {
278861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
278961ae650dSJack F Vogel 	struct i40e_aqc_get_version *resp =
279061ae650dSJack F Vogel 		(struct i40e_aqc_get_version *)&desc.params.raw;
279161ae650dSJack F Vogel 	enum i40e_status_code status;
279261ae650dSJack F Vogel 
279361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_version);
279461ae650dSJack F Vogel 
279561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
279661ae650dSJack F Vogel 
279761ae650dSJack F Vogel 	if (status == I40E_SUCCESS) {
279861ae650dSJack F Vogel 		if (fw_major_version != NULL)
279961ae650dSJack F Vogel 			*fw_major_version = LE16_TO_CPU(resp->fw_major);
280061ae650dSJack F Vogel 		if (fw_minor_version != NULL)
280161ae650dSJack F Vogel 			*fw_minor_version = LE16_TO_CPU(resp->fw_minor);
2802f247dc25SJack F Vogel 		if (fw_build != NULL)
2803f247dc25SJack F Vogel 			*fw_build = LE32_TO_CPU(resp->fw_build);
280461ae650dSJack F Vogel 		if (api_major_version != NULL)
280561ae650dSJack F Vogel 			*api_major_version = LE16_TO_CPU(resp->api_major);
280661ae650dSJack F Vogel 		if (api_minor_version != NULL)
280761ae650dSJack F Vogel 			*api_minor_version = LE16_TO_CPU(resp->api_minor);
280861ae650dSJack F Vogel 
280961ae650dSJack F Vogel 		/* A workaround to fix the API version in SW */
281061ae650dSJack F Vogel 		if (api_major_version && api_minor_version &&
281161ae650dSJack F Vogel 		    fw_major_version && fw_minor_version &&
281261ae650dSJack F Vogel 		    ((*api_major_version == 1) && (*api_minor_version == 1)) &&
281361ae650dSJack F Vogel 		    (((*fw_major_version == 4) && (*fw_minor_version >= 2)) ||
281461ae650dSJack F Vogel 		     (*fw_major_version > 4)))
281561ae650dSJack F Vogel 			*api_minor_version = 2;
281661ae650dSJack F Vogel 	}
281761ae650dSJack F Vogel 
281861ae650dSJack F Vogel 	return status;
281961ae650dSJack F Vogel }
282061ae650dSJack F Vogel 
282161ae650dSJack F Vogel /**
282261ae650dSJack F Vogel  * i40e_aq_send_driver_version
282361ae650dSJack F Vogel  * @hw: pointer to the hw struct
282461ae650dSJack F Vogel  * @dv: driver's major, minor version
282561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
282661ae650dSJack F Vogel  *
282761ae650dSJack F Vogel  * Send the driver version to the firmware
282861ae650dSJack F Vogel  **/
i40e_aq_send_driver_version(struct i40e_hw * hw,struct i40e_driver_version * dv,struct i40e_asq_cmd_details * cmd_details)282961ae650dSJack F Vogel enum i40e_status_code i40e_aq_send_driver_version(struct i40e_hw *hw,
283061ae650dSJack F Vogel 				struct i40e_driver_version *dv,
283161ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
283261ae650dSJack F Vogel {
283361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
283461ae650dSJack F Vogel 	struct i40e_aqc_driver_version *cmd =
283561ae650dSJack F Vogel 		(struct i40e_aqc_driver_version *)&desc.params.raw;
283661ae650dSJack F Vogel 	enum i40e_status_code status;
283761ae650dSJack F Vogel 	u16 len;
283861ae650dSJack F Vogel 
283961ae650dSJack F Vogel 	if (dv == NULL)
284061ae650dSJack F Vogel 		return I40E_ERR_PARAM;
284161ae650dSJack F Vogel 
284261ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_driver_version);
284361ae650dSJack F Vogel 
2844f247dc25SJack F Vogel 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
284561ae650dSJack F Vogel 	cmd->driver_major_ver = dv->major_version;
284661ae650dSJack F Vogel 	cmd->driver_minor_ver = dv->minor_version;
284761ae650dSJack F Vogel 	cmd->driver_build_ver = dv->build_version;
284861ae650dSJack F Vogel 	cmd->driver_subbuild_ver = dv->subbuild_version;
284961ae650dSJack F Vogel 
285061ae650dSJack F Vogel 	len = 0;
285161ae650dSJack F Vogel 	while (len < sizeof(dv->driver_string) &&
285261ae650dSJack F Vogel 	       (dv->driver_string[len] < 0x80) &&
285361ae650dSJack F Vogel 	       dv->driver_string[len])
285461ae650dSJack F Vogel 		len++;
285561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, dv->driver_string,
285661ae650dSJack F Vogel 				       len, cmd_details);
285761ae650dSJack F Vogel 
285861ae650dSJack F Vogel 	return status;
285961ae650dSJack F Vogel }
286061ae650dSJack F Vogel 
286161ae650dSJack F Vogel /**
286261ae650dSJack F Vogel  * i40e_get_link_status - get status of the HW network link
286361ae650dSJack F Vogel  * @hw: pointer to the hw struct
2864be771cdaSJack F Vogel  * @link_up: pointer to bool (TRUE/FALSE = linkup/linkdown)
286561ae650dSJack F Vogel  *
2866be771cdaSJack F Vogel  * Variable link_up TRUE if link is up, FALSE if link is down.
2867be771cdaSJack F Vogel  * The variable link_up is invalid if returned value of status != I40E_SUCCESS
286861ae650dSJack F Vogel  *
286961ae650dSJack F Vogel  * Side effect: LinkStatusEvent reporting becomes enabled
287061ae650dSJack F Vogel  **/
i40e_get_link_status(struct i40e_hw * hw,bool * link_up)2871be771cdaSJack F Vogel enum i40e_status_code i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
287261ae650dSJack F Vogel {
287361ae650dSJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
287461ae650dSJack F Vogel 
287561ae650dSJack F Vogel 	if (hw->phy.get_link_info) {
2876be771cdaSJack F Vogel 		status = i40e_update_link_info(hw);
287761ae650dSJack F Vogel 
287861ae650dSJack F Vogel 		if (status != I40E_SUCCESS)
2879be771cdaSJack F Vogel 			i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
2880be771cdaSJack F Vogel 				   status);
288161ae650dSJack F Vogel 	}
288261ae650dSJack F Vogel 
2883be771cdaSJack F Vogel 	*link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
288461ae650dSJack F Vogel 
2885be771cdaSJack F Vogel 	return status;
288661ae650dSJack F Vogel }
288761ae650dSJack F Vogel 
288861ae650dSJack F Vogel /**
2889abf77452SKrzysztof Galazka  * i40e_update_link_info - update status of the HW network link
2890be771cdaSJack F Vogel  * @hw: pointer to the hw struct
2891be771cdaSJack F Vogel  **/
i40e_update_link_info(struct i40e_hw * hw)2892be771cdaSJack F Vogel enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw)
2893be771cdaSJack F Vogel {
2894be771cdaSJack F Vogel 	struct i40e_aq_get_phy_abilities_resp abilities;
2895be771cdaSJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
2896be771cdaSJack F Vogel 
2897be771cdaSJack F Vogel 	status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
2898be771cdaSJack F Vogel 	if (status)
2899be771cdaSJack F Vogel 		return status;
2900be771cdaSJack F Vogel 
2901cb6b8299SEric Joyner 	/* extra checking needed to ensure link info to user is timely */
2902abf77452SKrzysztof Galazka 	if (((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) &&
2903cb6b8299SEric Joyner 	     ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) ||
2904abf77452SKrzysztof Galazka 	      !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) ||
2905abf77452SKrzysztof Galazka 	    hw->mac.type == I40E_MAC_X722) {
2906abf77452SKrzysztof Galazka 		status = i40e_aq_get_phy_capabilities(hw, FALSE,
2907abf77452SKrzysztof Galazka 						      hw->mac.type ==
2908abf77452SKrzysztof Galazka 						      I40E_MAC_X722,
2909fdb6f38aSEric Joyner 						      &abilities, NULL);
2910be771cdaSJack F Vogel 		if (status)
2911be771cdaSJack F Vogel 			return status;
2912be771cdaSJack F Vogel 
2913b4a7ce06SEric Joyner 		if (abilities.fec_cfg_curr_mod_ext_info &
2914b4a7ce06SEric Joyner 		    I40E_AQ_ENABLE_FEC_AUTO)
2915b4a7ce06SEric Joyner 			hw->phy.link_info.req_fec_info =
2916b4a7ce06SEric Joyner 				(I40E_AQ_REQUEST_FEC_KR |
2917b4a7ce06SEric Joyner 				 I40E_AQ_REQUEST_FEC_RS);
2918b4a7ce06SEric Joyner 		else
2919ceebc2f3SEric Joyner 			hw->phy.link_info.req_fec_info =
2920ceebc2f3SEric Joyner 				abilities.fec_cfg_curr_mod_ext_info &
2921b4a7ce06SEric Joyner 				(I40E_AQ_REQUEST_FEC_KR |
2922b4a7ce06SEric Joyner 				 I40E_AQ_REQUEST_FEC_RS);
2923ceebc2f3SEric Joyner 
2924cb6b8299SEric Joyner 		i40e_memcpy(hw->phy.link_info.module_type, &abilities.module_type,
2925cb6b8299SEric Joyner 			sizeof(hw->phy.link_info.module_type), I40E_NONDMA_TO_NONDMA);
2926fdb6f38aSEric Joyner 	}
2927be771cdaSJack F Vogel 	return status;
2928be771cdaSJack F Vogel }
2929be771cdaSJack F Vogel 
2930be771cdaSJack F Vogel 
2931be771cdaSJack F Vogel /**
293261ae650dSJack F Vogel  * i40e_get_link_speed
293361ae650dSJack F Vogel  * @hw: pointer to the hw struct
293461ae650dSJack F Vogel  *
293561ae650dSJack F Vogel  * Returns the link speed of the adapter.
293661ae650dSJack F Vogel  **/
i40e_get_link_speed(struct i40e_hw * hw)293761ae650dSJack F Vogel enum i40e_aq_link_speed i40e_get_link_speed(struct i40e_hw *hw)
293861ae650dSJack F Vogel {
293961ae650dSJack F Vogel 	enum i40e_aq_link_speed speed = I40E_LINK_SPEED_UNKNOWN;
294061ae650dSJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
294161ae650dSJack F Vogel 
294261ae650dSJack F Vogel 	if (hw->phy.get_link_info) {
294361ae650dSJack F Vogel 		status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
294461ae650dSJack F Vogel 
294561ae650dSJack F Vogel 		if (status != I40E_SUCCESS)
294661ae650dSJack F Vogel 			goto i40e_link_speed_exit;
294761ae650dSJack F Vogel 	}
294861ae650dSJack F Vogel 
294961ae650dSJack F Vogel 	speed = hw->phy.link_info.link_speed;
295061ae650dSJack F Vogel 
295161ae650dSJack F Vogel i40e_link_speed_exit:
295261ae650dSJack F Vogel 	return speed;
295361ae650dSJack F Vogel }
295461ae650dSJack F Vogel 
295561ae650dSJack F Vogel /**
295661ae650dSJack F Vogel  * i40e_aq_add_veb - Insert a VEB between the VSI and the MAC
295761ae650dSJack F Vogel  * @hw: pointer to the hw struct
295861ae650dSJack F Vogel  * @uplink_seid: the MAC or other gizmo SEID
295961ae650dSJack F Vogel  * @downlink_seid: the VSI SEID
296061ae650dSJack F Vogel  * @enabled_tc: bitmap of TCs to be enabled
296161ae650dSJack F Vogel  * @default_port: TRUE for default port VSI, FALSE for control port
296261ae650dSJack F Vogel  * @veb_seid: pointer to where to put the resulting VEB SEID
29631d767a8eSEric Joyner  * @enable_stats: TRUE to turn on VEB stats
296461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
296561ae650dSJack F Vogel  *
296661ae650dSJack F Vogel  * This asks the FW to add a VEB between the uplink and downlink
296761ae650dSJack F Vogel  * elements.  If the uplink SEID is 0, this will be a floating VEB.
296861ae650dSJack F Vogel  **/
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)296961ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
297061ae650dSJack F Vogel 				u16 downlink_seid, u8 enabled_tc,
29711d767a8eSEric Joyner 				bool default_port, u16 *veb_seid,
29721d767a8eSEric Joyner 				bool enable_stats,
297361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
297461ae650dSJack F Vogel {
297561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
297661ae650dSJack F Vogel 	struct i40e_aqc_add_veb *cmd =
297761ae650dSJack F Vogel 		(struct i40e_aqc_add_veb *)&desc.params.raw;
297861ae650dSJack F Vogel 	struct i40e_aqc_add_veb_completion *resp =
297961ae650dSJack F Vogel 		(struct i40e_aqc_add_veb_completion *)&desc.params.raw;
298061ae650dSJack F Vogel 	enum i40e_status_code status;
298161ae650dSJack F Vogel 	u16 veb_flags = 0;
298261ae650dSJack F Vogel 
298361ae650dSJack F Vogel 	/* SEIDs need to either both be set or both be 0 for floating VEB */
298461ae650dSJack F Vogel 	if (!!uplink_seid != !!downlink_seid)
298561ae650dSJack F Vogel 		return I40E_ERR_PARAM;
298661ae650dSJack F Vogel 
298761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_veb);
298861ae650dSJack F Vogel 
298961ae650dSJack F Vogel 	cmd->uplink_seid = CPU_TO_LE16(uplink_seid);
299061ae650dSJack F Vogel 	cmd->downlink_seid = CPU_TO_LE16(downlink_seid);
299161ae650dSJack F Vogel 	cmd->enable_tcs = enabled_tc;
299261ae650dSJack F Vogel 	if (!uplink_seid)
299361ae650dSJack F Vogel 		veb_flags |= I40E_AQC_ADD_VEB_FLOATING;
299461ae650dSJack F Vogel 	if (default_port)
299561ae650dSJack F Vogel 		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT;
299661ae650dSJack F Vogel 	else
299761ae650dSJack F Vogel 		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;
299861ae650dSJack F Vogel 
29991d767a8eSEric Joyner 	/* reverse logic here: set the bitflag to disable the stats */
30001d767a8eSEric Joyner 	if (!enable_stats)
30011d767a8eSEric Joyner 		veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;
300261ae650dSJack F Vogel 
300361ae650dSJack F Vogel 	cmd->veb_flags = CPU_TO_LE16(veb_flags);
300461ae650dSJack F Vogel 
300561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
300661ae650dSJack F Vogel 
300761ae650dSJack F Vogel 	if (!status && veb_seid)
300861ae650dSJack F Vogel 		*veb_seid = LE16_TO_CPU(resp->veb_seid);
300961ae650dSJack F Vogel 
301061ae650dSJack F Vogel 	return status;
301161ae650dSJack F Vogel }
301261ae650dSJack F Vogel 
301361ae650dSJack F Vogel /**
301461ae650dSJack F Vogel  * i40e_aq_get_veb_parameters - Retrieve VEB parameters
301561ae650dSJack F Vogel  * @hw: pointer to the hw struct
301661ae650dSJack F Vogel  * @veb_seid: the SEID of the VEB to query
301761ae650dSJack F Vogel  * @switch_id: the uplink switch id
301861ae650dSJack F Vogel  * @floating: set to TRUE if the VEB is floating
301961ae650dSJack F Vogel  * @statistic_index: index of the stats counter block for this VEB
302061ae650dSJack F Vogel  * @vebs_used: number of VEB's used by function
302161ae650dSJack F Vogel  * @vebs_free: total VEB's not reserved by any function
302261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
302361ae650dSJack F Vogel  *
302461ae650dSJack F Vogel  * This retrieves the parameters for a particular VEB, specified by
302561ae650dSJack F Vogel  * uplink_seid, and returns them to the caller.
302661ae650dSJack F Vogel  **/
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)302761ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw,
302861ae650dSJack F Vogel 				u16 veb_seid, u16 *switch_id,
302961ae650dSJack F Vogel 				bool *floating, u16 *statistic_index,
303061ae650dSJack F Vogel 				u16 *vebs_used, u16 *vebs_free,
303161ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
303261ae650dSJack F Vogel {
303361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
303461ae650dSJack F Vogel 	struct i40e_aqc_get_veb_parameters_completion *cmd_resp =
303561ae650dSJack F Vogel 		(struct i40e_aqc_get_veb_parameters_completion *)
303661ae650dSJack F Vogel 		&desc.params.raw;
303761ae650dSJack F Vogel 	enum i40e_status_code status;
303861ae650dSJack F Vogel 
303961ae650dSJack F Vogel 	if (veb_seid == 0)
304061ae650dSJack F Vogel 		return I40E_ERR_PARAM;
304161ae650dSJack F Vogel 
304261ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
304361ae650dSJack F Vogel 					  i40e_aqc_opc_get_veb_parameters);
304461ae650dSJack F Vogel 	cmd_resp->seid = CPU_TO_LE16(veb_seid);
304561ae650dSJack F Vogel 
304661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
304761ae650dSJack F Vogel 	if (status)
304861ae650dSJack F Vogel 		goto get_veb_exit;
304961ae650dSJack F Vogel 
305061ae650dSJack F Vogel 	if (switch_id)
305161ae650dSJack F Vogel 		*switch_id = LE16_TO_CPU(cmd_resp->switch_id);
305261ae650dSJack F Vogel 	if (statistic_index)
305361ae650dSJack F Vogel 		*statistic_index = LE16_TO_CPU(cmd_resp->statistic_index);
305461ae650dSJack F Vogel 	if (vebs_used)
305561ae650dSJack F Vogel 		*vebs_used = LE16_TO_CPU(cmd_resp->vebs_used);
305661ae650dSJack F Vogel 	if (vebs_free)
305761ae650dSJack F Vogel 		*vebs_free = LE16_TO_CPU(cmd_resp->vebs_free);
305861ae650dSJack F Vogel 	if (floating) {
305961ae650dSJack F Vogel 		u16 flags = LE16_TO_CPU(cmd_resp->veb_flags);
3060be771cdaSJack F Vogel 
306161ae650dSJack F Vogel 		if (flags & I40E_AQC_ADD_VEB_FLOATING)
306261ae650dSJack F Vogel 			*floating = TRUE;
306361ae650dSJack F Vogel 		else
306461ae650dSJack F Vogel 			*floating = FALSE;
306561ae650dSJack F Vogel 	}
306661ae650dSJack F Vogel 
306761ae650dSJack F Vogel get_veb_exit:
306861ae650dSJack F Vogel 	return status;
306961ae650dSJack F Vogel }
307061ae650dSJack F Vogel 
307161ae650dSJack F Vogel /**
307261ae650dSJack F Vogel  * i40e_aq_add_macvlan
307361ae650dSJack F Vogel  * @hw: pointer to the hw struct
307461ae650dSJack F Vogel  * @seid: VSI for the mac address
307561ae650dSJack F Vogel  * @mv_list: list of macvlans to be added
307661ae650dSJack F Vogel  * @count: length of the list
307761ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
307861ae650dSJack F Vogel  *
307961ae650dSJack F Vogel  * Add MAC/VLAN addresses to the HW filtering
308061ae650dSJack F Vogel  **/
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)308161ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
308261ae650dSJack F Vogel 			struct i40e_aqc_add_macvlan_element_data *mv_list,
308361ae650dSJack F Vogel 			u16 count, struct i40e_asq_cmd_details *cmd_details)
308461ae650dSJack F Vogel {
308561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
308661ae650dSJack F Vogel 	struct i40e_aqc_macvlan *cmd =
308761ae650dSJack F Vogel 		(struct i40e_aqc_macvlan *)&desc.params.raw;
308861ae650dSJack F Vogel 	enum i40e_status_code status;
308961ae650dSJack F Vogel 	u16 buf_size;
309095bb0504SEric Joyner 	int i;
309161ae650dSJack F Vogel 
309261ae650dSJack F Vogel 	if (count == 0 || !mv_list || !hw)
309361ae650dSJack F Vogel 		return I40E_ERR_PARAM;
309461ae650dSJack F Vogel 
3095f247dc25SJack F Vogel 	buf_size = count * sizeof(*mv_list);
309661ae650dSJack F Vogel 
309761ae650dSJack F Vogel 	/* prep the rest of the request */
309861ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
309961ae650dSJack F Vogel 	cmd->num_addresses = CPU_TO_LE16(count);
310061ae650dSJack F Vogel 	cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
310161ae650dSJack F Vogel 	cmd->seid[1] = 0;
310261ae650dSJack F Vogel 	cmd->seid[2] = 0;
310361ae650dSJack F Vogel 
310495bb0504SEric Joyner 	for (i = 0; i < count; i++)
310595bb0504SEric Joyner 		if (I40E_IS_MULTICAST(mv_list[i].mac_addr))
31061d767a8eSEric Joyner 			mv_list[i].flags |=
31071d767a8eSEric Joyner 			    CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
310895bb0504SEric Joyner 
310961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
311061ae650dSJack F Vogel 	if (buf_size > I40E_AQ_LARGE_BUF)
311161ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
311261ae650dSJack F Vogel 
311361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
311461ae650dSJack F Vogel 				       cmd_details);
311561ae650dSJack F Vogel 
311661ae650dSJack F Vogel 	return status;
311761ae650dSJack F Vogel }
311861ae650dSJack F Vogel 
311961ae650dSJack F Vogel /**
312061ae650dSJack F Vogel  * i40e_aq_remove_macvlan
312161ae650dSJack F Vogel  * @hw: pointer to the hw struct
312261ae650dSJack F Vogel  * @seid: VSI for the mac address
312361ae650dSJack F Vogel  * @mv_list: list of macvlans to be removed
312461ae650dSJack F Vogel  * @count: length of the list
312561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
312661ae650dSJack F Vogel  *
312761ae650dSJack F Vogel  * Remove MAC/VLAN addresses from the HW filtering
312861ae650dSJack F Vogel  **/
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)312961ae650dSJack F Vogel enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
313061ae650dSJack F Vogel 			struct i40e_aqc_remove_macvlan_element_data *mv_list,
313161ae650dSJack F Vogel 			u16 count, struct i40e_asq_cmd_details *cmd_details)
313261ae650dSJack F Vogel {
313361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
313461ae650dSJack F Vogel 	struct i40e_aqc_macvlan *cmd =
313561ae650dSJack F Vogel 		(struct i40e_aqc_macvlan *)&desc.params.raw;
313661ae650dSJack F Vogel 	enum i40e_status_code status;
313761ae650dSJack F Vogel 	u16 buf_size;
313861ae650dSJack F Vogel 
313961ae650dSJack F Vogel 	if (count == 0 || !mv_list || !hw)
314061ae650dSJack F Vogel 		return I40E_ERR_PARAM;
314161ae650dSJack F Vogel 
3142f247dc25SJack F Vogel 	buf_size = count * sizeof(*mv_list);
314361ae650dSJack F Vogel 
314461ae650dSJack F Vogel 	/* prep the rest of the request */
314561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
314661ae650dSJack F Vogel 	cmd->num_addresses = CPU_TO_LE16(count);
314761ae650dSJack F Vogel 	cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
314861ae650dSJack F Vogel 	cmd->seid[1] = 0;
314961ae650dSJack F Vogel 	cmd->seid[2] = 0;
315061ae650dSJack F Vogel 
315161ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
315261ae650dSJack F Vogel 	if (buf_size > I40E_AQ_LARGE_BUF)
315361ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
315461ae650dSJack F Vogel 
315561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
315661ae650dSJack F Vogel 				       cmd_details);
315761ae650dSJack F Vogel 
315861ae650dSJack F Vogel 	return status;
315961ae650dSJack F Vogel }
316061ae650dSJack F Vogel 
316161ae650dSJack F Vogel /**
31621d767a8eSEric Joyner  * i40e_mirrorrule_op - Internal helper function to add/delete mirror rule
31631d767a8eSEric Joyner  * @hw: pointer to the hw struct
31641d767a8eSEric Joyner  * @opcode: AQ opcode for add or delete mirror rule
31651d767a8eSEric Joyner  * @sw_seid: Switch SEID (to which rule refers)
31661d767a8eSEric Joyner  * @rule_type: Rule Type (ingress/egress/VLAN)
31671d767a8eSEric Joyner  * @id: Destination VSI SEID or Rule ID
31681d767a8eSEric Joyner  * @count: length of the list
31691d767a8eSEric Joyner  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
31701d767a8eSEric Joyner  * @cmd_details: pointer to command details structure or NULL
31711d767a8eSEric Joyner  * @rule_id: Rule ID returned from FW
3172ceebc2f3SEric Joyner  * @rules_used: Number of rules used in internal switch
3173ceebc2f3SEric Joyner  * @rules_free: Number of rules free in internal switch
31741d767a8eSEric Joyner  *
31751d767a8eSEric Joyner  * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
31761d767a8eSEric Joyner  * VEBs/VEPA elements only
31771d767a8eSEric Joyner  **/
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)31781d767a8eSEric Joyner static enum i40e_status_code i40e_mirrorrule_op(struct i40e_hw *hw,
31791d767a8eSEric Joyner 			u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
31801d767a8eSEric Joyner 			u16 count, __le16 *mr_list,
31811d767a8eSEric Joyner 			struct i40e_asq_cmd_details *cmd_details,
31821d767a8eSEric Joyner 			u16 *rule_id, u16 *rules_used, u16 *rules_free)
31831d767a8eSEric Joyner {
31841d767a8eSEric Joyner 	struct i40e_aq_desc desc;
31851d767a8eSEric Joyner 	struct i40e_aqc_add_delete_mirror_rule *cmd =
31861d767a8eSEric Joyner 		(struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
31871d767a8eSEric Joyner 	struct i40e_aqc_add_delete_mirror_rule_completion *resp =
31881d767a8eSEric Joyner 	(struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
31891d767a8eSEric Joyner 	enum i40e_status_code status;
31901d767a8eSEric Joyner 	u16 buf_size;
31911d767a8eSEric Joyner 
31921d767a8eSEric Joyner 	buf_size = count * sizeof(*mr_list);
31931d767a8eSEric Joyner 
31941d767a8eSEric Joyner 	/* prep the rest of the request */
31951d767a8eSEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc, opcode);
31961d767a8eSEric Joyner 	cmd->seid = CPU_TO_LE16(sw_seid);
31971d767a8eSEric Joyner 	cmd->rule_type = CPU_TO_LE16(rule_type &
31981d767a8eSEric Joyner 				     I40E_AQC_MIRROR_RULE_TYPE_MASK);
31991d767a8eSEric Joyner 	cmd->num_entries = CPU_TO_LE16(count);
32001d767a8eSEric Joyner 	/* Dest VSI for add, rule_id for delete */
32011d767a8eSEric Joyner 	cmd->destination = CPU_TO_LE16(id);
32021d767a8eSEric Joyner 	if (mr_list) {
32031d767a8eSEric Joyner 		desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
32041d767a8eSEric Joyner 						I40E_AQ_FLAG_RD));
32051d767a8eSEric Joyner 		if (buf_size > I40E_AQ_LARGE_BUF)
32061d767a8eSEric Joyner 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
32071d767a8eSEric Joyner 	}
32081d767a8eSEric Joyner 
32091d767a8eSEric Joyner 	status = i40e_asq_send_command(hw, &desc, mr_list, buf_size,
32101d767a8eSEric Joyner 				       cmd_details);
32111d767a8eSEric Joyner 	if (status == I40E_SUCCESS ||
32121d767a8eSEric Joyner 	    hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) {
32131d767a8eSEric Joyner 		if (rule_id)
32141d767a8eSEric Joyner 			*rule_id = LE16_TO_CPU(resp->rule_id);
32151d767a8eSEric Joyner 		if (rules_used)
32161d767a8eSEric Joyner 			*rules_used = LE16_TO_CPU(resp->mirror_rules_used);
32171d767a8eSEric Joyner 		if (rules_free)
32181d767a8eSEric Joyner 			*rules_free = LE16_TO_CPU(resp->mirror_rules_free);
32191d767a8eSEric Joyner 	}
32201d767a8eSEric Joyner 	return status;
32211d767a8eSEric Joyner }
32221d767a8eSEric Joyner 
32231d767a8eSEric Joyner /**
32241d767a8eSEric Joyner  * i40e_aq_add_mirrorrule - add a mirror rule
32251d767a8eSEric Joyner  * @hw: pointer to the hw struct
32261d767a8eSEric Joyner  * @sw_seid: Switch SEID (to which rule refers)
32271d767a8eSEric Joyner  * @rule_type: Rule Type (ingress/egress/VLAN)
32281d767a8eSEric Joyner  * @dest_vsi: SEID of VSI to which packets will be mirrored
32291d767a8eSEric Joyner  * @count: length of the list
32301d767a8eSEric Joyner  * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
32311d767a8eSEric Joyner  * @cmd_details: pointer to command details structure or NULL
32321d767a8eSEric Joyner  * @rule_id: Rule ID returned from FW
3233ceebc2f3SEric Joyner  * @rules_used: Number of rules used in internal switch
3234ceebc2f3SEric Joyner  * @rules_free: Number of rules free in internal switch
32351d767a8eSEric Joyner  *
32361d767a8eSEric Joyner  * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
32371d767a8eSEric Joyner  **/
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)32381d767a8eSEric Joyner enum i40e_status_code i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
32391d767a8eSEric Joyner 			u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
32401d767a8eSEric Joyner 			struct i40e_asq_cmd_details *cmd_details,
32411d767a8eSEric Joyner 			u16 *rule_id, u16 *rules_used, u16 *rules_free)
32421d767a8eSEric Joyner {
32431d767a8eSEric Joyner 	if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
32441d767a8eSEric Joyner 	    rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
32451d767a8eSEric Joyner 		if (count == 0 || !mr_list)
32461d767a8eSEric Joyner 			return I40E_ERR_PARAM;
32471d767a8eSEric Joyner 	}
32481d767a8eSEric Joyner 
32491d767a8eSEric Joyner 	return i40e_mirrorrule_op(hw, i40e_aqc_opc_add_mirror_rule, sw_seid,
32501d767a8eSEric Joyner 				  rule_type, dest_vsi, count, mr_list,
32511d767a8eSEric Joyner 				  cmd_details, rule_id, rules_used, rules_free);
32521d767a8eSEric Joyner }
32531d767a8eSEric Joyner 
32541d767a8eSEric Joyner /**
32551d767a8eSEric Joyner  * i40e_aq_delete_mirrorrule - delete a mirror rule
32561d767a8eSEric Joyner  * @hw: pointer to the hw struct
32571d767a8eSEric Joyner  * @sw_seid: Switch SEID (to which rule refers)
32581d767a8eSEric Joyner  * @rule_type: Rule Type (ingress/egress/VLAN)
32591d767a8eSEric Joyner  * @count: length of the list
32601d767a8eSEric Joyner  * @rule_id: Rule ID that is returned in the receive desc as part of
32611d767a8eSEric Joyner  *		add_mirrorrule.
32621d767a8eSEric Joyner  * @mr_list: list of mirrored VLAN IDs to be removed
32631d767a8eSEric Joyner  * @cmd_details: pointer to command details structure or NULL
3264ceebc2f3SEric Joyner  * @rules_used: Number of rules used in internal switch
3265ceebc2f3SEric Joyner  * @rules_free: Number of rules free in internal switch
32661d767a8eSEric Joyner  *
32671d767a8eSEric Joyner  * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
32681d767a8eSEric Joyner  **/
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)32691d767a8eSEric Joyner enum i40e_status_code i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
32701d767a8eSEric Joyner 			u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
32711d767a8eSEric Joyner 			struct i40e_asq_cmd_details *cmd_details,
32721d767a8eSEric Joyner 			u16 *rules_used, u16 *rules_free)
32731d767a8eSEric Joyner {
32741d767a8eSEric Joyner 	/* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
32754294f337SSean Bruno 	if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
32761d767a8eSEric Joyner 		/* count and mr_list shall be valid for rule_type INGRESS VLAN
32771d767a8eSEric Joyner 		 * mirroring. For other rule_type, count and rule_type should
32781d767a8eSEric Joyner 		 * not matter.
32791d767a8eSEric Joyner 		 */
32801d767a8eSEric Joyner 		if (count == 0 || !mr_list)
32811d767a8eSEric Joyner 			return I40E_ERR_PARAM;
32821d767a8eSEric Joyner 	}
32831d767a8eSEric Joyner 
32841d767a8eSEric Joyner 	return i40e_mirrorrule_op(hw, i40e_aqc_opc_delete_mirror_rule, sw_seid,
32851d767a8eSEric Joyner 				  rule_type, rule_id, count, mr_list,
32861d767a8eSEric Joyner 				  cmd_details, NULL, rules_used, rules_free);
32871d767a8eSEric Joyner }
32881d767a8eSEric Joyner 
32891d767a8eSEric Joyner /**
329061ae650dSJack F Vogel  * i40e_aq_add_vlan - Add VLAN ids to the HW filtering
329161ae650dSJack F Vogel  * @hw: pointer to the hw struct
329261ae650dSJack F Vogel  * @seid: VSI for the vlan filters
329361ae650dSJack F Vogel  * @v_list: list of vlan filters to be added
329461ae650dSJack F Vogel  * @count: length of the list
329561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
329661ae650dSJack F Vogel  **/
i40e_aq_add_vlan(struct i40e_hw * hw,u16 seid,struct i40e_aqc_add_remove_vlan_element_data * v_list,u8 count,struct i40e_asq_cmd_details * cmd_details)329761ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_vlan(struct i40e_hw *hw, u16 seid,
329861ae650dSJack F Vogel 			struct i40e_aqc_add_remove_vlan_element_data *v_list,
329961ae650dSJack F Vogel 			u8 count, struct i40e_asq_cmd_details *cmd_details)
330061ae650dSJack F Vogel {
330161ae650dSJack F Vogel 	struct i40e_aq_desc desc;
330261ae650dSJack F Vogel 	struct i40e_aqc_macvlan *cmd =
330361ae650dSJack F Vogel 		(struct i40e_aqc_macvlan *)&desc.params.raw;
330461ae650dSJack F Vogel 	enum i40e_status_code status;
330561ae650dSJack F Vogel 	u16 buf_size;
330661ae650dSJack F Vogel 
330761ae650dSJack F Vogel 	if (count == 0 || !v_list || !hw)
330861ae650dSJack F Vogel 		return I40E_ERR_PARAM;
330961ae650dSJack F Vogel 
3310f247dc25SJack F Vogel 	buf_size = count * sizeof(*v_list);
331161ae650dSJack F Vogel 
331261ae650dSJack F Vogel 	/* prep the rest of the request */
331361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_vlan);
331461ae650dSJack F Vogel 	cmd->num_addresses = CPU_TO_LE16(count);
331561ae650dSJack F Vogel 	cmd->seid[0] = CPU_TO_LE16(seid | I40E_AQC_MACVLAN_CMD_SEID_VALID);
331661ae650dSJack F Vogel 	cmd->seid[1] = 0;
331761ae650dSJack F Vogel 	cmd->seid[2] = 0;
331861ae650dSJack F Vogel 
331961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
332061ae650dSJack F Vogel 	if (buf_size > I40E_AQ_LARGE_BUF)
332161ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
332261ae650dSJack F Vogel 
332361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, v_list, buf_size,
332461ae650dSJack F Vogel 				       cmd_details);
332561ae650dSJack F Vogel 
332661ae650dSJack F Vogel 	return status;
332761ae650dSJack F Vogel }
332861ae650dSJack F Vogel 
332961ae650dSJack F Vogel /**
333061ae650dSJack F Vogel  * i40e_aq_remove_vlan - Remove VLANs from the HW filtering
333161ae650dSJack F Vogel  * @hw: pointer to the hw struct
333261ae650dSJack F Vogel  * @seid: VSI for the vlan filters
333361ae650dSJack F Vogel  * @v_list: list of macvlans to be removed
333461ae650dSJack F Vogel  * @count: length of the list
333561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
333661ae650dSJack F Vogel  **/
i40e_aq_remove_vlan(struct i40e_hw * hw,u16 seid,struct i40e_aqc_add_remove_vlan_element_data * v_list,u8 count,struct i40e_asq_cmd_details * cmd_details)333761ae650dSJack F Vogel enum i40e_status_code i40e_aq_remove_vlan(struct i40e_hw *hw, u16 seid,
333861ae650dSJack F Vogel 			struct i40e_aqc_add_remove_vlan_element_data *v_list,
333961ae650dSJack F Vogel 			u8 count, struct i40e_asq_cmd_details *cmd_details)
334061ae650dSJack F Vogel {
334161ae650dSJack F Vogel 	struct i40e_aq_desc desc;
334261ae650dSJack F Vogel 	struct i40e_aqc_macvlan *cmd =
334361ae650dSJack F Vogel 		(struct i40e_aqc_macvlan *)&desc.params.raw;
334461ae650dSJack F Vogel 	enum i40e_status_code status;
334561ae650dSJack F Vogel 	u16 buf_size;
334661ae650dSJack F Vogel 
334761ae650dSJack F Vogel 	if (count == 0 || !v_list || !hw)
334861ae650dSJack F Vogel 		return I40E_ERR_PARAM;
334961ae650dSJack F Vogel 
3350f247dc25SJack F Vogel 	buf_size = count * sizeof(*v_list);
335161ae650dSJack F Vogel 
335261ae650dSJack F Vogel 	/* prep the rest of the request */
335361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_vlan);
335461ae650dSJack F Vogel 	cmd->num_addresses = CPU_TO_LE16(count);
335561ae650dSJack F Vogel 	cmd->seid[0] = CPU_TO_LE16(seid | I40E_AQC_MACVLAN_CMD_SEID_VALID);
335661ae650dSJack F Vogel 	cmd->seid[1] = 0;
335761ae650dSJack F Vogel 	cmd->seid[2] = 0;
335861ae650dSJack F Vogel 
335961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
336061ae650dSJack F Vogel 	if (buf_size > I40E_AQ_LARGE_BUF)
336161ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
336261ae650dSJack F Vogel 
336361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, v_list, buf_size,
336461ae650dSJack F Vogel 				       cmd_details);
336561ae650dSJack F Vogel 
336661ae650dSJack F Vogel 	return status;
336761ae650dSJack F Vogel }
336861ae650dSJack F Vogel 
336961ae650dSJack F Vogel /**
337061ae650dSJack F Vogel  * i40e_aq_send_msg_to_vf
337161ae650dSJack F Vogel  * @hw: pointer to the hardware structure
337261ae650dSJack F Vogel  * @vfid: vf id to send msg
337361ae650dSJack F Vogel  * @v_opcode: opcodes for VF-PF communication
337461ae650dSJack F Vogel  * @v_retval: return error code
337561ae650dSJack F Vogel  * @msg: pointer to the msg buffer
337661ae650dSJack F Vogel  * @msglen: msg length
337761ae650dSJack F Vogel  * @cmd_details: pointer to command details
337861ae650dSJack F Vogel  *
337961ae650dSJack F Vogel  * send msg to vf
338061ae650dSJack F Vogel  **/
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)338161ae650dSJack F Vogel enum i40e_status_code i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
338261ae650dSJack F Vogel 				u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
338361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
338461ae650dSJack F Vogel {
338561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
338661ae650dSJack F Vogel 	struct i40e_aqc_pf_vf_message *cmd =
338761ae650dSJack F Vogel 		(struct i40e_aqc_pf_vf_message *)&desc.params.raw;
338861ae650dSJack F Vogel 	enum i40e_status_code status;
338961ae650dSJack F Vogel 
339061ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_vf);
339161ae650dSJack F Vogel 	cmd->id = CPU_TO_LE32(vfid);
339261ae650dSJack F Vogel 	desc.cookie_high = CPU_TO_LE32(v_opcode);
339361ae650dSJack F Vogel 	desc.cookie_low = CPU_TO_LE32(v_retval);
339461ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
339561ae650dSJack F Vogel 	if (msglen) {
339661ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF |
339761ae650dSJack F Vogel 						I40E_AQ_FLAG_RD));
339861ae650dSJack F Vogel 		if (msglen > I40E_AQ_LARGE_BUF)
339961ae650dSJack F Vogel 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
340061ae650dSJack F Vogel 		desc.datalen = CPU_TO_LE16(msglen);
340161ae650dSJack F Vogel 	}
340261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, msg, msglen, cmd_details);
340361ae650dSJack F Vogel 
340461ae650dSJack F Vogel 	return status;
340561ae650dSJack F Vogel }
340661ae650dSJack F Vogel 
340761ae650dSJack F Vogel /**
3408f247dc25SJack F Vogel  * i40e_aq_debug_read_register
3409f247dc25SJack F Vogel  * @hw: pointer to the hw struct
3410f247dc25SJack F Vogel  * @reg_addr: register address
3411f247dc25SJack F Vogel  * @reg_val: register value
3412f247dc25SJack F Vogel  * @cmd_details: pointer to command details structure or NULL
3413f247dc25SJack F Vogel  *
3414f247dc25SJack F Vogel  * Read the register using the admin queue commands
3415f247dc25SJack F Vogel  **/
i40e_aq_debug_read_register(struct i40e_hw * hw,u32 reg_addr,u64 * reg_val,struct i40e_asq_cmd_details * cmd_details)3416f247dc25SJack F Vogel enum i40e_status_code i40e_aq_debug_read_register(struct i40e_hw *hw,
3417f247dc25SJack F Vogel 				u32 reg_addr, u64 *reg_val,
3418f247dc25SJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
3419f247dc25SJack F Vogel {
3420f247dc25SJack F Vogel 	struct i40e_aq_desc desc;
3421f247dc25SJack F Vogel 	struct i40e_aqc_debug_reg_read_write *cmd_resp =
3422f247dc25SJack F Vogel 		(struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3423f247dc25SJack F Vogel 	enum i40e_status_code status;
3424f247dc25SJack F Vogel 
3425f247dc25SJack F Vogel 	if (reg_val == NULL)
3426f247dc25SJack F Vogel 		return I40E_ERR_PARAM;
3427f247dc25SJack F Vogel 
3428f247dc25SJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
3429f247dc25SJack F Vogel 
3430f247dc25SJack F Vogel 	cmd_resp->address = CPU_TO_LE32(reg_addr);
3431f247dc25SJack F Vogel 
3432f247dc25SJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3433f247dc25SJack F Vogel 
3434f247dc25SJack F Vogel 	if (status == I40E_SUCCESS) {
3435f247dc25SJack F Vogel 		*reg_val = ((u64)LE32_TO_CPU(cmd_resp->value_high) << 32) |
3436f247dc25SJack F Vogel 			   (u64)LE32_TO_CPU(cmd_resp->value_low);
3437f247dc25SJack F Vogel 	}
3438f247dc25SJack F Vogel 
3439f247dc25SJack F Vogel 	return status;
3440f247dc25SJack F Vogel }
3441f247dc25SJack F Vogel 
3442f247dc25SJack F Vogel /**
344361ae650dSJack F Vogel  * i40e_aq_debug_write_register
344461ae650dSJack F Vogel  * @hw: pointer to the hw struct
344561ae650dSJack F Vogel  * @reg_addr: register address
344661ae650dSJack F Vogel  * @reg_val: register value
344761ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
344861ae650dSJack F Vogel  *
344961ae650dSJack F Vogel  * Write to a register using the admin queue commands
345061ae650dSJack F Vogel  **/
i40e_aq_debug_write_register(struct i40e_hw * hw,u32 reg_addr,u64 reg_val,struct i40e_asq_cmd_details * cmd_details)345161ae650dSJack F Vogel enum i40e_status_code i40e_aq_debug_write_register(struct i40e_hw *hw,
345261ae650dSJack F Vogel 				u32 reg_addr, u64 reg_val,
345361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
345461ae650dSJack F Vogel {
345561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
345661ae650dSJack F Vogel 	struct i40e_aqc_debug_reg_read_write *cmd =
345761ae650dSJack F Vogel 		(struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
345861ae650dSJack F Vogel 	enum i40e_status_code status;
345961ae650dSJack F Vogel 
346061ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_write_reg);
346161ae650dSJack F Vogel 
346261ae650dSJack F Vogel 	cmd->address = CPU_TO_LE32(reg_addr);
346361ae650dSJack F Vogel 	cmd->value_high = CPU_TO_LE32((u32)(reg_val >> 32));
346461ae650dSJack F Vogel 	cmd->value_low = CPU_TO_LE32((u32)(reg_val & 0xFFFFFFFF));
346561ae650dSJack F Vogel 
346661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
346761ae650dSJack F Vogel 
346861ae650dSJack F Vogel 	return status;
346961ae650dSJack F Vogel }
347061ae650dSJack F Vogel 
347161ae650dSJack F Vogel /**
347261ae650dSJack F Vogel  * i40e_aq_request_resource
347361ae650dSJack F Vogel  * @hw: pointer to the hw struct
347461ae650dSJack F Vogel  * @resource: resource id
347561ae650dSJack F Vogel  * @access: access type
347661ae650dSJack F Vogel  * @sdp_number: resource number
347761ae650dSJack F Vogel  * @timeout: the maximum time in ms that the driver may hold the resource
347861ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
347961ae650dSJack F Vogel  *
348061ae650dSJack F Vogel  * requests common resource using the admin queue commands
348161ae650dSJack F Vogel  **/
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)348261ae650dSJack F Vogel enum i40e_status_code i40e_aq_request_resource(struct i40e_hw *hw,
348361ae650dSJack F Vogel 				enum i40e_aq_resources_ids resource,
348461ae650dSJack F Vogel 				enum i40e_aq_resource_access_type access,
348561ae650dSJack F Vogel 				u8 sdp_number, u64 *timeout,
348661ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
348761ae650dSJack F Vogel {
348861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
348961ae650dSJack F Vogel 	struct i40e_aqc_request_resource *cmd_resp =
349061ae650dSJack F Vogel 		(struct i40e_aqc_request_resource *)&desc.params.raw;
349161ae650dSJack F Vogel 	enum i40e_status_code status;
349261ae650dSJack F Vogel 
349361ae650dSJack F Vogel 	DEBUGFUNC("i40e_aq_request_resource");
349461ae650dSJack F Vogel 
349561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_request_resource);
349661ae650dSJack F Vogel 
349761ae650dSJack F Vogel 	cmd_resp->resource_id = CPU_TO_LE16(resource);
349861ae650dSJack F Vogel 	cmd_resp->access_type = CPU_TO_LE16(access);
349961ae650dSJack F Vogel 	cmd_resp->resource_number = CPU_TO_LE32(sdp_number);
350061ae650dSJack F Vogel 
350161ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
350261ae650dSJack F Vogel 	/* The completion specifies the maximum time in ms that the driver
350361ae650dSJack F Vogel 	 * may hold the resource in the Timeout field.
350461ae650dSJack F Vogel 	 * If the resource is held by someone else, the command completes with
350561ae650dSJack F Vogel 	 * busy return value and the timeout field indicates the maximum time
350661ae650dSJack F Vogel 	 * the current owner of the resource has to free it.
350761ae650dSJack F Vogel 	 */
350861ae650dSJack F Vogel 	if (status == I40E_SUCCESS || hw->aq.asq_last_status == I40E_AQ_RC_EBUSY)
350961ae650dSJack F Vogel 		*timeout = LE32_TO_CPU(cmd_resp->timeout);
351061ae650dSJack F Vogel 
351161ae650dSJack F Vogel 	return status;
351261ae650dSJack F Vogel }
351361ae650dSJack F Vogel 
351461ae650dSJack F Vogel /**
351561ae650dSJack F Vogel  * i40e_aq_release_resource
351661ae650dSJack F Vogel  * @hw: pointer to the hw struct
351761ae650dSJack F Vogel  * @resource: resource id
351861ae650dSJack F Vogel  * @sdp_number: resource number
351961ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
352061ae650dSJack F Vogel  *
352161ae650dSJack F Vogel  * release common resource using the admin queue commands
352261ae650dSJack F Vogel  **/
i40e_aq_release_resource(struct i40e_hw * hw,enum i40e_aq_resources_ids resource,u8 sdp_number,struct i40e_asq_cmd_details * cmd_details)352361ae650dSJack F Vogel enum i40e_status_code i40e_aq_release_resource(struct i40e_hw *hw,
352461ae650dSJack F Vogel 				enum i40e_aq_resources_ids resource,
352561ae650dSJack F Vogel 				u8 sdp_number,
352661ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
352761ae650dSJack F Vogel {
352861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
352961ae650dSJack F Vogel 	struct i40e_aqc_request_resource *cmd =
353061ae650dSJack F Vogel 		(struct i40e_aqc_request_resource *)&desc.params.raw;
353161ae650dSJack F Vogel 	enum i40e_status_code status;
353261ae650dSJack F Vogel 
353361ae650dSJack F Vogel 	DEBUGFUNC("i40e_aq_release_resource");
353461ae650dSJack F Vogel 
353561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_release_resource);
353661ae650dSJack F Vogel 
353761ae650dSJack F Vogel 	cmd->resource_id = CPU_TO_LE16(resource);
353861ae650dSJack F Vogel 	cmd->resource_number = CPU_TO_LE32(sdp_number);
353961ae650dSJack F Vogel 
354061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
354161ae650dSJack F Vogel 
354261ae650dSJack F Vogel 	return status;
354361ae650dSJack F Vogel }
354461ae650dSJack F Vogel 
354561ae650dSJack F Vogel /**
354661ae650dSJack F Vogel  * i40e_aq_read_nvm
354761ae650dSJack F Vogel  * @hw: pointer to the hw struct
354861ae650dSJack F Vogel  * @module_pointer: module pointer location in words from the NVM beginning
354961ae650dSJack F Vogel  * @offset: byte offset from the module beginning
355061ae650dSJack F Vogel  * @length: length of the section to be read (in bytes from the offset)
355161ae650dSJack F Vogel  * @data: command buffer (size [bytes] = length)
355261ae650dSJack F Vogel  * @last_command: tells if this is the last command in a series
355361ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
355461ae650dSJack F Vogel  *
355561ae650dSJack F Vogel  * Read the NVM using the admin queue commands
355661ae650dSJack F Vogel  **/
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)355761ae650dSJack F Vogel enum i40e_status_code i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
355861ae650dSJack F Vogel 				u32 offset, u16 length, void *data,
355961ae650dSJack F Vogel 				bool last_command,
356061ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
356161ae650dSJack F Vogel {
356261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
356361ae650dSJack F Vogel 	struct i40e_aqc_nvm_update *cmd =
356461ae650dSJack F Vogel 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
356561ae650dSJack F Vogel 	enum i40e_status_code status;
356661ae650dSJack F Vogel 
356761ae650dSJack F Vogel 	DEBUGFUNC("i40e_aq_read_nvm");
356861ae650dSJack F Vogel 
356961ae650dSJack F Vogel 	/* In offset the highest byte must be zeroed. */
357061ae650dSJack F Vogel 	if (offset & 0xFF000000) {
357161ae650dSJack F Vogel 		status = I40E_ERR_PARAM;
357261ae650dSJack F Vogel 		goto i40e_aq_read_nvm_exit;
357361ae650dSJack F Vogel 	}
357461ae650dSJack F Vogel 
357561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_read);
357661ae650dSJack F Vogel 
357761ae650dSJack F Vogel 	/* If this is the last command in a series, set the proper flag. */
357861ae650dSJack F Vogel 	if (last_command)
357961ae650dSJack F Vogel 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
358061ae650dSJack F Vogel 	cmd->module_pointer = module_pointer;
358161ae650dSJack F Vogel 	cmd->offset = CPU_TO_LE32(offset);
358261ae650dSJack F Vogel 	cmd->length = CPU_TO_LE16(length);
358361ae650dSJack F Vogel 
358461ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
358561ae650dSJack F Vogel 	if (length > I40E_AQ_LARGE_BUF)
358661ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
358761ae650dSJack F Vogel 
358861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
358961ae650dSJack F Vogel 
359061ae650dSJack F Vogel i40e_aq_read_nvm_exit:
359161ae650dSJack F Vogel 	return status;
359261ae650dSJack F Vogel }
359361ae650dSJack F Vogel 
359461ae650dSJack F Vogel /**
3595f247dc25SJack F Vogel  * i40e_aq_read_nvm_config - read an nvm config block
3596f247dc25SJack F Vogel  * @hw: pointer to the hw struct
3597f247dc25SJack F Vogel  * @cmd_flags: NVM access admin command bits
3598f247dc25SJack F Vogel  * @field_id: field or feature id
3599f247dc25SJack F Vogel  * @data: buffer for result
3600f247dc25SJack F Vogel  * @buf_size: buffer size
3601f247dc25SJack F Vogel  * @element_count: pointer to count of elements read by FW
3602f247dc25SJack F Vogel  * @cmd_details: pointer to command details structure or NULL
3603f247dc25SJack F Vogel  **/
i40e_aq_read_nvm_config(struct i40e_hw * hw,u8 cmd_flags,u32 field_id,void * data,u16 buf_size,u16 * element_count,struct i40e_asq_cmd_details * cmd_details)3604f247dc25SJack F Vogel enum i40e_status_code i40e_aq_read_nvm_config(struct i40e_hw *hw,
3605f247dc25SJack F Vogel 				u8 cmd_flags, u32 field_id, void *data,
3606f247dc25SJack F Vogel 				u16 buf_size, u16 *element_count,
3607f247dc25SJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
3608f247dc25SJack F Vogel {
3609f247dc25SJack F Vogel 	struct i40e_aq_desc desc;
3610f247dc25SJack F Vogel 	struct i40e_aqc_nvm_config_read *cmd =
3611f247dc25SJack F Vogel 		(struct i40e_aqc_nvm_config_read *)&desc.params.raw;
3612f247dc25SJack F Vogel 	enum i40e_status_code status;
3613f247dc25SJack F Vogel 
3614f247dc25SJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_read);
3615f247dc25SJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF));
3616f247dc25SJack F Vogel 	if (buf_size > I40E_AQ_LARGE_BUF)
3617f247dc25SJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3618f247dc25SJack F Vogel 
3619f247dc25SJack F Vogel 	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
3620f247dc25SJack F Vogel 	cmd->element_id = CPU_TO_LE16((u16)(0xffff & field_id));
3621f247dc25SJack F Vogel 	if (cmd_flags & I40E_AQ_ANVM_FEATURE_OR_IMMEDIATE_MASK)
3622f247dc25SJack F Vogel 		cmd->element_id_msw = CPU_TO_LE16((u16)(field_id >> 16));
3623f247dc25SJack F Vogel 	else
3624f247dc25SJack F Vogel 		cmd->element_id_msw = 0;
3625f247dc25SJack F Vogel 
3626f247dc25SJack F Vogel 	status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
3627f247dc25SJack F Vogel 
3628f247dc25SJack F Vogel 	if (!status && element_count)
3629f247dc25SJack F Vogel 		*element_count = LE16_TO_CPU(cmd->element_count);
3630f247dc25SJack F Vogel 
3631f247dc25SJack F Vogel 	return status;
3632f247dc25SJack F Vogel }
3633f247dc25SJack F Vogel 
3634f247dc25SJack F Vogel /**
3635f247dc25SJack F Vogel  * i40e_aq_write_nvm_config - write an nvm config block
3636f247dc25SJack F Vogel  * @hw: pointer to the hw struct
3637f247dc25SJack F Vogel  * @cmd_flags: NVM access admin command bits
3638f247dc25SJack F Vogel  * @data: buffer for result
3639f247dc25SJack F Vogel  * @buf_size: buffer size
3640f247dc25SJack F Vogel  * @element_count: count of elements to be written
3641f247dc25SJack F Vogel  * @cmd_details: pointer to command details structure or NULL
3642f247dc25SJack F Vogel  **/
i40e_aq_write_nvm_config(struct i40e_hw * hw,u8 cmd_flags,void * data,u16 buf_size,u16 element_count,struct i40e_asq_cmd_details * cmd_details)3643f247dc25SJack F Vogel enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw,
3644f247dc25SJack F Vogel 				u8 cmd_flags, void *data, u16 buf_size,
3645f247dc25SJack F Vogel 				u16 element_count,
3646f247dc25SJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
3647f247dc25SJack F Vogel {
3648f247dc25SJack F Vogel 	struct i40e_aq_desc desc;
3649f247dc25SJack F Vogel 	struct i40e_aqc_nvm_config_write *cmd =
3650f247dc25SJack F Vogel 		(struct i40e_aqc_nvm_config_write *)&desc.params.raw;
3651f247dc25SJack F Vogel 	enum i40e_status_code status;
3652f247dc25SJack F Vogel 
3653f247dc25SJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_config_write);
3654f247dc25SJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3655f247dc25SJack F Vogel 	if (buf_size > I40E_AQ_LARGE_BUF)
3656f247dc25SJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
3657f247dc25SJack F Vogel 
3658f247dc25SJack F Vogel 	cmd->element_count = CPU_TO_LE16(element_count);
3659f247dc25SJack F Vogel 	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
3660f247dc25SJack F Vogel 	status = i40e_asq_send_command(hw, &desc, data, buf_size, cmd_details);
3661f247dc25SJack F Vogel 
3662f247dc25SJack F Vogel 	return status;
3663f247dc25SJack F Vogel }
3664f247dc25SJack F Vogel 
3665f247dc25SJack F Vogel /**
3666abf77452SKrzysztof Galazka  * i40e_aq_nvm_update_in_process
3667abf77452SKrzysztof Galazka  * @hw: pointer to the hw struct
3668abf77452SKrzysztof Galazka  * @update_flow_state: True indicates that update flow starts, FALSE that ends
3669abf77452SKrzysztof Galazka  * @cmd_details: pointer to command details structure or NULL
3670abf77452SKrzysztof Galazka  *
3671abf77452SKrzysztof Galazka  * Indicate NVM update in process.
3672abf77452SKrzysztof Galazka  **/
i40e_aq_nvm_update_in_process(struct i40e_hw * hw,bool update_flow_state,struct i40e_asq_cmd_details * cmd_details)3673abf77452SKrzysztof Galazka enum i40e_status_code i40e_aq_nvm_update_in_process(struct i40e_hw *hw,
3674abf77452SKrzysztof Galazka 				bool update_flow_state,
3675abf77452SKrzysztof Galazka 				struct i40e_asq_cmd_details *cmd_details)
3676abf77452SKrzysztof Galazka {
3677abf77452SKrzysztof Galazka 	struct i40e_aq_desc desc;
3678abf77452SKrzysztof Galazka 	struct i40e_aqc_nvm_update_in_process *cmd =
3679abf77452SKrzysztof Galazka 		(struct i40e_aqc_nvm_update_in_process *)&desc.params.raw;
3680abf77452SKrzysztof Galazka 	enum i40e_status_code status;
3681abf77452SKrzysztof Galazka 
3682abf77452SKrzysztof Galazka 	i40e_fill_default_direct_cmd_desc(&desc,
3683abf77452SKrzysztof Galazka 					  i40e_aqc_opc_nvm_update_in_process);
3684abf77452SKrzysztof Galazka 
3685abf77452SKrzysztof Galazka 	cmd->command = I40E_AQ_UPDATE_FLOW_END;
3686abf77452SKrzysztof Galazka 
3687abf77452SKrzysztof Galazka 	if (update_flow_state)
3688abf77452SKrzysztof Galazka 		cmd->command |= I40E_AQ_UPDATE_FLOW_START;
3689abf77452SKrzysztof Galazka 
3690abf77452SKrzysztof Galazka 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3691abf77452SKrzysztof Galazka 
3692abf77452SKrzysztof Galazka 	return status;
3693abf77452SKrzysztof Galazka }
3694abf77452SKrzysztof Galazka 
3695abf77452SKrzysztof Galazka /**
3696abf77452SKrzysztof Galazka  * i40e_aq_min_rollback_rev_update - triggers an ow after update
3697abf77452SKrzysztof Galazka  * @hw: pointer to the hw struct
3698abf77452SKrzysztof Galazka  * @mode: opt-in mode, 1b for single module update, 0b for bulk update
3699abf77452SKrzysztof Galazka  * @module: module to be updated. Ignored if mode is 0b
3700abf77452SKrzysztof Galazka  * @min_rrev: value of the new minimal version. Ignored if mode is 0b
3701abf77452SKrzysztof Galazka  * @cmd_details: pointer to command details structure or NULL
3702abf77452SKrzysztof Galazka  **/
3703abf77452SKrzysztof Galazka enum i40e_status_code
i40e_aq_min_rollback_rev_update(struct i40e_hw * hw,u8 mode,u8 module,u32 min_rrev,struct i40e_asq_cmd_details * cmd_details)3704abf77452SKrzysztof Galazka i40e_aq_min_rollback_rev_update(struct i40e_hw *hw, u8 mode, u8 module,
3705abf77452SKrzysztof Galazka 				u32 min_rrev,
3706abf77452SKrzysztof Galazka 				struct i40e_asq_cmd_details *cmd_details)
3707abf77452SKrzysztof Galazka {
3708abf77452SKrzysztof Galazka 	struct i40e_aq_desc desc;
3709abf77452SKrzysztof Galazka 	struct i40e_aqc_rollback_revision_update *cmd =
3710abf77452SKrzysztof Galazka 		(struct i40e_aqc_rollback_revision_update *)&desc.params.raw;
3711abf77452SKrzysztof Galazka 	enum i40e_status_code status;
3712abf77452SKrzysztof Galazka 
3713abf77452SKrzysztof Galazka 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rollback_revision_update);
3714abf77452SKrzysztof Galazka 	cmd->optin_mode = mode;
3715abf77452SKrzysztof Galazka 	cmd->module_selected = module;
3716abf77452SKrzysztof Galazka 	cmd->min_rrev = min_rrev;
3717abf77452SKrzysztof Galazka 
3718abf77452SKrzysztof Galazka 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3719abf77452SKrzysztof Galazka 
3720abf77452SKrzysztof Galazka 	return status;
3721abf77452SKrzysztof Galazka }
3722abf77452SKrzysztof Galazka 
3723abf77452SKrzysztof Galazka /**
3724be771cdaSJack F Vogel  * i40e_aq_oem_post_update - triggers an OEM specific flow after update
3725be771cdaSJack F Vogel  * @hw: pointer to the hw struct
3726ceebc2f3SEric Joyner  * @buff: buffer for result
3727ceebc2f3SEric Joyner  * @buff_size: buffer size
3728be771cdaSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
3729be771cdaSJack F Vogel  **/
i40e_aq_oem_post_update(struct i40e_hw * hw,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)3730be771cdaSJack F Vogel enum i40e_status_code i40e_aq_oem_post_update(struct i40e_hw *hw,
3731be771cdaSJack F Vogel 				void *buff, u16 buff_size,
3732be771cdaSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
3733be771cdaSJack F Vogel {
3734be771cdaSJack F Vogel 	struct i40e_aq_desc desc;
3735be771cdaSJack F Vogel 	enum i40e_status_code status;
3736be771cdaSJack F Vogel 
3737be771cdaSJack F Vogel 
3738be771cdaSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_oem_post_update);
3739be771cdaSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3740be771cdaSJack F Vogel 	if (status && LE16_TO_CPU(desc.retval) == I40E_AQ_RC_ESRCH)
3741be771cdaSJack F Vogel 		status = I40E_ERR_NOT_IMPLEMENTED;
3742be771cdaSJack F Vogel 
3743be771cdaSJack F Vogel 	return status;
3744be771cdaSJack F Vogel }
3745be771cdaSJack F Vogel 
3746be771cdaSJack F Vogel /**
374761ae650dSJack F Vogel  * i40e_aq_erase_nvm
374861ae650dSJack F Vogel  * @hw: pointer to the hw struct
374961ae650dSJack F Vogel  * @module_pointer: module pointer location in words from the NVM beginning
375061ae650dSJack F Vogel  * @offset: offset in the module (expressed in 4 KB from module's beginning)
375161ae650dSJack F Vogel  * @length: length of the section to be erased (expressed in 4 KB)
375261ae650dSJack F Vogel  * @last_command: tells if this is the last command in a series
375361ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
375461ae650dSJack F Vogel  *
375561ae650dSJack F Vogel  * Erase the NVM sector using the admin queue commands
375661ae650dSJack F Vogel  **/
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)375761ae650dSJack F Vogel enum i40e_status_code i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
375861ae650dSJack F Vogel 				u32 offset, u16 length, bool last_command,
375961ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
376061ae650dSJack F Vogel {
376161ae650dSJack F Vogel 	struct i40e_aq_desc desc;
376261ae650dSJack F Vogel 	struct i40e_aqc_nvm_update *cmd =
376361ae650dSJack F Vogel 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
376461ae650dSJack F Vogel 	enum i40e_status_code status;
376561ae650dSJack F Vogel 
376661ae650dSJack F Vogel 	DEBUGFUNC("i40e_aq_erase_nvm");
376761ae650dSJack F Vogel 
376861ae650dSJack F Vogel 	/* In offset the highest byte must be zeroed. */
376961ae650dSJack F Vogel 	if (offset & 0xFF000000) {
377061ae650dSJack F Vogel 		status = I40E_ERR_PARAM;
377161ae650dSJack F Vogel 		goto i40e_aq_erase_nvm_exit;
377261ae650dSJack F Vogel 	}
377361ae650dSJack F Vogel 
377461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_erase);
377561ae650dSJack F Vogel 
377661ae650dSJack F Vogel 	/* If this is the last command in a series, set the proper flag. */
377761ae650dSJack F Vogel 	if (last_command)
377861ae650dSJack F Vogel 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
377961ae650dSJack F Vogel 	cmd->module_pointer = module_pointer;
378061ae650dSJack F Vogel 	cmd->offset = CPU_TO_LE32(offset);
378161ae650dSJack F Vogel 	cmd->length = CPU_TO_LE16(length);
378261ae650dSJack F Vogel 
378361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
378461ae650dSJack F Vogel 
378561ae650dSJack F Vogel i40e_aq_erase_nvm_exit:
378661ae650dSJack F Vogel 	return status;
378761ae650dSJack F Vogel }
378861ae650dSJack F Vogel 
378961ae650dSJack F Vogel /**
379061ae650dSJack F Vogel  * i40e_parse_discover_capabilities
379161ae650dSJack F Vogel  * @hw: pointer to the hw struct
379261ae650dSJack F Vogel  * @buff: pointer to a buffer containing device/function capability records
379361ae650dSJack F Vogel  * @cap_count: number of capability records in the list
379461ae650dSJack F Vogel  * @list_type_opc: type of capabilities list to parse
379561ae650dSJack F Vogel  *
379661ae650dSJack F Vogel  * Parse the device/function capabilities list.
379761ae650dSJack F Vogel  **/
i40e_parse_discover_capabilities(struct i40e_hw * hw,void * buff,u32 cap_count,enum i40e_admin_queue_opc list_type_opc)379861ae650dSJack F Vogel static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
379961ae650dSJack F Vogel 				     u32 cap_count,
380061ae650dSJack F Vogel 				     enum i40e_admin_queue_opc list_type_opc)
380161ae650dSJack F Vogel {
380261ae650dSJack F Vogel 	struct i40e_aqc_list_capabilities_element_resp *cap;
3803f247dc25SJack F Vogel 	u32 valid_functions, num_functions;
380461ae650dSJack F Vogel 	u32 number, logical_id, phys_id;
380561ae650dSJack F Vogel 	struct i40e_hw_capabilities *p;
3806ceebc2f3SEric Joyner 	enum i40e_status_code status;
3807ceebc2f3SEric Joyner 	u16 id, ocp_cfg_word0;
3808be771cdaSJack F Vogel 	u8 major_rev;
380961ae650dSJack F Vogel 	u32 i = 0;
381061ae650dSJack F Vogel 
381161ae650dSJack F Vogel 	cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
381261ae650dSJack F Vogel 
381361ae650dSJack F Vogel 	if (list_type_opc == i40e_aqc_opc_list_dev_capabilities)
381461ae650dSJack F Vogel 		p = (struct i40e_hw_capabilities *)&hw->dev_caps;
381561ae650dSJack F Vogel 	else if (list_type_opc == i40e_aqc_opc_list_func_capabilities)
381661ae650dSJack F Vogel 		p = (struct i40e_hw_capabilities *)&hw->func_caps;
381761ae650dSJack F Vogel 	else
381861ae650dSJack F Vogel 		return;
381961ae650dSJack F Vogel 
382061ae650dSJack F Vogel 	for (i = 0; i < cap_count; i++, cap++) {
382161ae650dSJack F Vogel 		id = LE16_TO_CPU(cap->id);
382261ae650dSJack F Vogel 		number = LE32_TO_CPU(cap->number);
382361ae650dSJack F Vogel 		logical_id = LE32_TO_CPU(cap->logical_id);
382461ae650dSJack F Vogel 		phys_id = LE32_TO_CPU(cap->phys_id);
3825be771cdaSJack F Vogel 		major_rev = cap->major_rev;
382661ae650dSJack F Vogel 
382761ae650dSJack F Vogel 		switch (id) {
38287f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_SWITCH_MODE:
382961ae650dSJack F Vogel 			p->switch_mode = number;
38306d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38316d011ad5SEric Joyner 				   "HW Capability: Switch mode = %d\n",
38326d011ad5SEric Joyner 				   p->switch_mode);
383361ae650dSJack F Vogel 			break;
38347f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_MNG_MODE:
383561ae650dSJack F Vogel 			p->management_mode = number;
3836cb6b8299SEric Joyner 			if (major_rev > 1) {
3837cb6b8299SEric Joyner 				p->mng_protocols_over_mctp = logical_id;
3838cb6b8299SEric Joyner 				i40e_debug(hw, I40E_DEBUG_INIT,
3839cb6b8299SEric Joyner 					   "HW Capability: Protocols over MCTP = %d\n",
3840cb6b8299SEric Joyner 					   p->mng_protocols_over_mctp);
3841cb6b8299SEric Joyner 			} else {
3842cb6b8299SEric Joyner 				p->mng_protocols_over_mctp = 0;
3843cb6b8299SEric Joyner 			}
38446d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38456d011ad5SEric Joyner 				   "HW Capability: Management Mode = %d\n",
38466d011ad5SEric Joyner 				   p->management_mode);
384761ae650dSJack F Vogel 			break;
38487f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_NPAR_ACTIVE:
384961ae650dSJack F Vogel 			p->npar_enable = number;
38506d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38516d011ad5SEric Joyner 				   "HW Capability: NPAR enable = %d\n",
38526d011ad5SEric Joyner 				   p->npar_enable);
385361ae650dSJack F Vogel 			break;
38547f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_OS2BMC_CAP:
385561ae650dSJack F Vogel 			p->os2bmc = number;
38566d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38576d011ad5SEric Joyner 				   "HW Capability: OS2BMC = %d\n", p->os2bmc);
385861ae650dSJack F Vogel 			break;
38597f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_FUNCTIONS_VALID:
386061ae650dSJack F Vogel 			p->valid_functions = number;
38616d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38626d011ad5SEric Joyner 				   "HW Capability: Valid Functions = %d\n",
38636d011ad5SEric Joyner 				   p->valid_functions);
386461ae650dSJack F Vogel 			break;
38657f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_SRIOV:
386661ae650dSJack F Vogel 			if (number == 1)
386761ae650dSJack F Vogel 				p->sr_iov_1_1 = TRUE;
38686d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38696d011ad5SEric Joyner 				   "HW Capability: SR-IOV = %d\n",
38706d011ad5SEric Joyner 				   p->sr_iov_1_1);
387161ae650dSJack F Vogel 			break;
38727f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_VF:
387361ae650dSJack F Vogel 			p->num_vfs = number;
387461ae650dSJack F Vogel 			p->vf_base_id = logical_id;
38756d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38766d011ad5SEric Joyner 				   "HW Capability: VF count = %d\n",
38776d011ad5SEric Joyner 				   p->num_vfs);
38786d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38796d011ad5SEric Joyner 				   "HW Capability: VF base_id = %d\n",
38806d011ad5SEric Joyner 				   p->vf_base_id);
388161ae650dSJack F Vogel 			break;
38827f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_VMDQ:
388361ae650dSJack F Vogel 			if (number == 1)
388461ae650dSJack F Vogel 				p->vmdq = TRUE;
38856d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38866d011ad5SEric Joyner 				   "HW Capability: VMDQ = %d\n", p->vmdq);
388761ae650dSJack F Vogel 			break;
38887f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_8021QBG:
388961ae650dSJack F Vogel 			if (number == 1)
389061ae650dSJack F Vogel 				p->evb_802_1_qbg = TRUE;
38916d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38926d011ad5SEric Joyner 				   "HW Capability: 802.1Qbg = %d\n", number);
389361ae650dSJack F Vogel 			break;
38947f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_8021QBR:
389561ae650dSJack F Vogel 			if (number == 1)
389661ae650dSJack F Vogel 				p->evb_802_1_qbh = TRUE;
38976d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
38986d011ad5SEric Joyner 				   "HW Capability: 802.1Qbh = %d\n", number);
389961ae650dSJack F Vogel 			break;
39007f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_VSI:
390161ae650dSJack F Vogel 			p->num_vsis = number;
39026d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39036d011ad5SEric Joyner 				   "HW Capability: VSI count = %d\n",
39046d011ad5SEric Joyner 				   p->num_vsis);
390561ae650dSJack F Vogel 			break;
39067f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_DCB:
390761ae650dSJack F Vogel 			if (number == 1) {
390861ae650dSJack F Vogel 				p->dcb = TRUE;
390961ae650dSJack F Vogel 				p->enabled_tcmap = logical_id;
391061ae650dSJack F Vogel 				p->maxtc = phys_id;
391161ae650dSJack F Vogel 			}
39126d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39136d011ad5SEric Joyner 				   "HW Capability: DCB = %d\n", p->dcb);
39146d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39156d011ad5SEric Joyner 				   "HW Capability: TC Mapping = %d\n",
39166d011ad5SEric Joyner 				   logical_id);
39176d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39186d011ad5SEric Joyner 				   "HW Capability: TC Max = %d\n", p->maxtc);
391961ae650dSJack F Vogel 			break;
39207f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_FCOE:
392161ae650dSJack F Vogel 			if (number == 1)
392261ae650dSJack F Vogel 				p->fcoe = TRUE;
39236d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39246d011ad5SEric Joyner 				   "HW Capability: FCOE = %d\n", p->fcoe);
392561ae650dSJack F Vogel 			break;
39267f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_ISCSI:
3927f247dc25SJack F Vogel 			if (number == 1)
3928f247dc25SJack F Vogel 				p->iscsi = TRUE;
39296d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39306d011ad5SEric Joyner 				   "HW Capability: iSCSI = %d\n", p->iscsi);
3931f247dc25SJack F Vogel 			break;
39327f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_RSS:
393361ae650dSJack F Vogel 			p->rss = TRUE;
393461ae650dSJack F Vogel 			p->rss_table_size = number;
393561ae650dSJack F Vogel 			p->rss_table_entry_width = logical_id;
39366d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39376d011ad5SEric Joyner 				   "HW Capability: RSS = %d\n", p->rss);
39386d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39396d011ad5SEric Joyner 				   "HW Capability: RSS table size = %d\n",
39406d011ad5SEric Joyner 				   p->rss_table_size);
39416d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39426d011ad5SEric Joyner 				   "HW Capability: RSS table width = %d\n",
39436d011ad5SEric Joyner 				   p->rss_table_entry_width);
394461ae650dSJack F Vogel 			break;
39457f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_RXQ:
394661ae650dSJack F Vogel 			p->num_rx_qp = number;
394761ae650dSJack F Vogel 			p->base_queue = phys_id;
39486d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39496d011ad5SEric Joyner 				   "HW Capability: Rx QP = %d\n", number);
39506d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39516d011ad5SEric Joyner 				   "HW Capability: base_queue = %d\n",
39526d011ad5SEric Joyner 				   p->base_queue);
395361ae650dSJack F Vogel 			break;
39547f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_TXQ:
395561ae650dSJack F Vogel 			p->num_tx_qp = number;
395661ae650dSJack F Vogel 			p->base_queue = phys_id;
39576d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39586d011ad5SEric Joyner 				   "HW Capability: Tx QP = %d\n", number);
39596d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39606d011ad5SEric Joyner 				   "HW Capability: base_queue = %d\n",
39616d011ad5SEric Joyner 				   p->base_queue);
396261ae650dSJack F Vogel 			break;
39637f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_MSIX:
396461ae650dSJack F Vogel 			p->num_msix_vectors = number;
39656d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39666d011ad5SEric Joyner 				   "HW Capability: MSIX vector count = %d\n",
3967d4683565SEric Joyner 				   p->num_msix_vectors);
396861ae650dSJack F Vogel 			break;
39697f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_VF_MSIX:
397061ae650dSJack F Vogel 			p->num_msix_vectors_vf = number;
39716d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39726d011ad5SEric Joyner 				   "HW Capability: MSIX VF vector count = %d\n",
39736d011ad5SEric Joyner 				   p->num_msix_vectors_vf);
397461ae650dSJack F Vogel 			break;
39757f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_FLEX10:
3976be771cdaSJack F Vogel 			if (major_rev == 1) {
3977be771cdaSJack F Vogel 				if (number == 1) {
3978be771cdaSJack F Vogel 					p->flex10_enable = TRUE;
3979be771cdaSJack F Vogel 					p->flex10_capable = TRUE;
3980be771cdaSJack F Vogel 				}
3981be771cdaSJack F Vogel 			} else {
3982be771cdaSJack F Vogel 				/* Capability revision >= 2 */
3983be771cdaSJack F Vogel 				if (number & 1)
3984be771cdaSJack F Vogel 					p->flex10_enable = TRUE;
3985be771cdaSJack F Vogel 				if (number & 2)
3986be771cdaSJack F Vogel 					p->flex10_capable = TRUE;
3987be771cdaSJack F Vogel 			}
3988be771cdaSJack F Vogel 			p->flex10_mode = logical_id;
3989be771cdaSJack F Vogel 			p->flex10_status = phys_id;
39906d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39916d011ad5SEric Joyner 				   "HW Capability: Flex10 mode = %d\n",
39926d011ad5SEric Joyner 				   p->flex10_mode);
39936d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
39946d011ad5SEric Joyner 				   "HW Capability: Flex10 status = %d\n",
39956d011ad5SEric Joyner 				   p->flex10_status);
399661ae650dSJack F Vogel 			break;
39977f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_CEM:
399861ae650dSJack F Vogel 			if (number == 1)
399961ae650dSJack F Vogel 				p->mgmt_cem = TRUE;
40006d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40016d011ad5SEric Joyner 				   "HW Capability: CEM = %d\n", p->mgmt_cem);
400261ae650dSJack F Vogel 			break;
40037f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_IWARP:
400461ae650dSJack F Vogel 			if (number == 1)
400561ae650dSJack F Vogel 				p->iwarp = TRUE;
40066d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40076d011ad5SEric Joyner 				   "HW Capability: iWARP = %d\n", p->iwarp);
400861ae650dSJack F Vogel 			break;
40097f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_LED:
401061ae650dSJack F Vogel 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
401161ae650dSJack F Vogel 				p->led[phys_id] = TRUE;
40126d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40136d011ad5SEric Joyner 				   "HW Capability: LED - PIN %d\n", phys_id);
401461ae650dSJack F Vogel 			break;
40157f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_SDP:
401661ae650dSJack F Vogel 			if (phys_id < I40E_HW_CAP_MAX_GPIO)
401761ae650dSJack F Vogel 				p->sdp[phys_id] = TRUE;
40186d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40196d011ad5SEric Joyner 				   "HW Capability: SDP - PIN %d\n", phys_id);
402061ae650dSJack F Vogel 			break;
40217f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_MDIO:
402261ae650dSJack F Vogel 			if (number == 1) {
402361ae650dSJack F Vogel 				p->mdio_port_num = phys_id;
402461ae650dSJack F Vogel 				p->mdio_port_mode = logical_id;
402561ae650dSJack F Vogel 			}
40266d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40276d011ad5SEric Joyner 				   "HW Capability: MDIO port number = %d\n",
40286d011ad5SEric Joyner 				   p->mdio_port_num);
40296d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40306d011ad5SEric Joyner 				   "HW Capability: MDIO port mode = %d\n",
40316d011ad5SEric Joyner 				   p->mdio_port_mode);
403261ae650dSJack F Vogel 			break;
40337f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_1588:
403461ae650dSJack F Vogel 			if (number == 1)
403561ae650dSJack F Vogel 				p->ieee_1588 = TRUE;
40366d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40376d011ad5SEric Joyner 				   "HW Capability: IEEE 1588 = %d\n",
40386d011ad5SEric Joyner 				   p->ieee_1588);
403961ae650dSJack F Vogel 			break;
40407f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_FLOW_DIRECTOR:
404161ae650dSJack F Vogel 			p->fd = TRUE;
404261ae650dSJack F Vogel 			p->fd_filters_guaranteed = number;
404361ae650dSJack F Vogel 			p->fd_filters_best_effort = logical_id;
40446d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40456d011ad5SEric Joyner 				   "HW Capability: Flow Director = 1\n");
40466d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40476d011ad5SEric Joyner 				   "HW Capability: Guaranteed FD filters = %d\n",
40486d011ad5SEric Joyner 				   p->fd_filters_guaranteed);
404961ae650dSJack F Vogel 			break;
40507f70bec6SEric Joyner 		case I40E_AQ_CAP_ID_WSR_PROT:
4051be771cdaSJack F Vogel 			p->wr_csr_prot = (u64)number;
4052be771cdaSJack F Vogel 			p->wr_csr_prot |= (u64)logical_id << 32;
40536d011ad5SEric Joyner 			i40e_debug(hw, I40E_DEBUG_INIT,
40546d011ad5SEric Joyner 				   "HW Capability: wr_csr_prot = 0x%llX\n\n",
4055abf77452SKrzysztof Galazka 				   (unsigned long long)(p->wr_csr_prot & 0xffff));
4056abf77452SKrzysztof Galazka 			break;
4057abf77452SKrzysztof Galazka 		case I40E_AQ_CAP_ID_DIS_UNUSED_PORTS:
4058abf77452SKrzysztof Galazka 			p->dis_unused_ports = (bool)number;
4059abf77452SKrzysztof Galazka 			i40e_debug(hw, I40E_DEBUG_INIT,
4060abf77452SKrzysztof Galazka 				   "HW Capability: dis_unused_ports = %d\n\n",
4061abf77452SKrzysztof Galazka 				   p->dis_unused_ports);
4062be771cdaSJack F Vogel 			break;
40634294f337SSean Bruno 		case I40E_AQ_CAP_ID_NVM_MGMT:
40644294f337SSean Bruno 			if (number & I40E_NVM_MGMT_SEC_REV_DISABLED)
40654294f337SSean Bruno 				p->sec_rev_disabled = TRUE;
40664294f337SSean Bruno 			if (number & I40E_NVM_MGMT_UPDATE_DISABLED)
40674294f337SSean Bruno 				p->update_disabled = TRUE;
40684294f337SSean Bruno 			break;
40694294f337SSean Bruno 		case I40E_AQ_CAP_ID_WOL_AND_PROXY:
40704294f337SSean Bruno 			hw->num_wol_proxy_filters = (u16)number;
40714294f337SSean Bruno 			hw->wol_proxy_vsi_seid = (u16)logical_id;
40724294f337SSean Bruno 			p->apm_wol_support = phys_id & I40E_WOL_SUPPORT_MASK;
40734294f337SSean Bruno 			if (phys_id & I40E_ACPI_PROGRAMMING_METHOD_MASK)
40744294f337SSean Bruno 				p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_AQC_FPK;
40754294f337SSean Bruno 			else
40764294f337SSean Bruno 				p->acpi_prog_method = I40E_ACPI_PROGRAMMING_METHOD_HW_FVL;
40774294f337SSean Bruno 			p->proxy_support = (phys_id & I40E_PROXY_SUPPORT_MASK) ? 1 : 0;
40784294f337SSean Bruno 			i40e_debug(hw, I40E_DEBUG_INIT,
40794294f337SSean Bruno 				   "HW Capability: WOL proxy filters = %d\n",
40804294f337SSean Bruno 				   hw->num_wol_proxy_filters);
40814294f337SSean Bruno 			break;
408261ae650dSJack F Vogel 		default:
408361ae650dSJack F Vogel 			break;
408461ae650dSJack F Vogel 		}
408561ae650dSJack F Vogel 	}
408661ae650dSJack F Vogel 
4087be771cdaSJack F Vogel 	if (p->fcoe)
4088be771cdaSJack F Vogel 		i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
4089be771cdaSJack F Vogel 
4090f247dc25SJack F Vogel 	/* Always disable FCoE if compiled without the I40E_FCOE_ENA flag */
409161ae650dSJack F Vogel 	p->fcoe = FALSE;
409261ae650dSJack F Vogel 
4093f247dc25SJack F Vogel 	/* count the enabled ports (aka the "not disabled" ports) */
4094f247dc25SJack F Vogel 	hw->num_ports = 0;
4095f247dc25SJack F Vogel 	for (i = 0; i < 4; i++) {
4096f247dc25SJack F Vogel 		u32 port_cfg_reg = I40E_PRTGEN_CNF + (4 * i);
4097f247dc25SJack F Vogel 		u64 port_cfg = 0;
4098f247dc25SJack F Vogel 
4099f247dc25SJack F Vogel 		/* use AQ read to get the physical register offset instead
4100f247dc25SJack F Vogel 		 * of the port relative offset
4101f247dc25SJack F Vogel 		 */
4102f247dc25SJack F Vogel 		i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
4103f247dc25SJack F Vogel 		if (!(port_cfg & I40E_PRTGEN_CNF_PORT_DIS_MASK))
4104f247dc25SJack F Vogel 			hw->num_ports++;
4105f247dc25SJack F Vogel 	}
4106f247dc25SJack F Vogel 
4107ceebc2f3SEric Joyner 	/* OCP cards case: if a mezz is removed the ethernet port is at
4108ceebc2f3SEric Joyner 	 * disabled state in PRTGEN_CNF register. Additional NVM read is
4109ceebc2f3SEric Joyner 	 * needed in order to check if we are dealing with OCP card.
4110ceebc2f3SEric Joyner 	 * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
4111ceebc2f3SEric Joyner 	 * physical ports results in wrong partition id calculation and thus
4112ceebc2f3SEric Joyner 	 * not supporting WoL.
4113ceebc2f3SEric Joyner 	 */
4114ceebc2f3SEric Joyner 	if (hw->mac.type == I40E_MAC_X722) {
4115ceebc2f3SEric Joyner 		if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) {
4116ceebc2f3SEric Joyner 			status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
4117ceebc2f3SEric Joyner 						  2 * I40E_SR_OCP_CFG_WORD0,
4118ceebc2f3SEric Joyner 						  sizeof(ocp_cfg_word0),
4119ceebc2f3SEric Joyner 						  &ocp_cfg_word0, TRUE, NULL);
4120ceebc2f3SEric Joyner 			if (status == I40E_SUCCESS &&
4121ceebc2f3SEric Joyner 			    (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
4122ceebc2f3SEric Joyner 				hw->num_ports = 4;
4123ceebc2f3SEric Joyner 			i40e_release_nvm(hw);
4124ceebc2f3SEric Joyner 		}
4125ceebc2f3SEric Joyner 	}
4126ceebc2f3SEric Joyner 
4127f247dc25SJack F Vogel 	valid_functions = p->valid_functions;
4128f247dc25SJack F Vogel 	num_functions = 0;
4129f247dc25SJack F Vogel 	while (valid_functions) {
4130f247dc25SJack F Vogel 		if (valid_functions & 1)
4131f247dc25SJack F Vogel 			num_functions++;
4132f247dc25SJack F Vogel 		valid_functions >>= 1;
4133f247dc25SJack F Vogel 	}
4134f247dc25SJack F Vogel 
4135f247dc25SJack F Vogel 	/* partition id is 1-based, and functions are evenly spread
4136f247dc25SJack F Vogel 	 * across the ports as partitions
4137f247dc25SJack F Vogel 	 */
4138cb6b8299SEric Joyner 	if (hw->num_ports != 0) {
4139f247dc25SJack F Vogel 		hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
4140f247dc25SJack F Vogel 		hw->num_partitions = num_functions / hw->num_ports;
4141cb6b8299SEric Joyner 	}
4142f247dc25SJack F Vogel 
414361ae650dSJack F Vogel 	/* additional HW specific goodies that might
414461ae650dSJack F Vogel 	 * someday be HW version specific
414561ae650dSJack F Vogel 	 */
414661ae650dSJack F Vogel 	p->rx_buf_chain_len = I40E_MAX_CHAINED_RX_BUFFERS;
414761ae650dSJack F Vogel }
414861ae650dSJack F Vogel 
414961ae650dSJack F Vogel /**
415061ae650dSJack F Vogel  * i40e_aq_discover_capabilities
415161ae650dSJack F Vogel  * @hw: pointer to the hw struct
415261ae650dSJack F Vogel  * @buff: a virtual buffer to hold the capabilities
415361ae650dSJack F Vogel  * @buff_size: Size of the virtual buffer
415461ae650dSJack F Vogel  * @data_size: Size of the returned data, or buff size needed if AQ err==ENOMEM
415561ae650dSJack F Vogel  * @list_type_opc: capabilities type to discover - pass in the command opcode
415661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
415761ae650dSJack F Vogel  *
415861ae650dSJack F Vogel  * Get the device capabilities descriptions from the firmware
415961ae650dSJack F Vogel  **/
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)416061ae650dSJack F Vogel enum i40e_status_code i40e_aq_discover_capabilities(struct i40e_hw *hw,
416161ae650dSJack F Vogel 				void *buff, u16 buff_size, u16 *data_size,
416261ae650dSJack F Vogel 				enum i40e_admin_queue_opc list_type_opc,
416361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
416461ae650dSJack F Vogel {
416561ae650dSJack F Vogel 	struct i40e_aqc_list_capabilites *cmd;
416661ae650dSJack F Vogel 	struct i40e_aq_desc desc;
416761ae650dSJack F Vogel 	enum i40e_status_code status = I40E_SUCCESS;
416861ae650dSJack F Vogel 
416961ae650dSJack F Vogel 	cmd = (struct i40e_aqc_list_capabilites *)&desc.params.raw;
417061ae650dSJack F Vogel 
417161ae650dSJack F Vogel 	if (list_type_opc != i40e_aqc_opc_list_func_capabilities &&
417261ae650dSJack F Vogel 		list_type_opc != i40e_aqc_opc_list_dev_capabilities) {
417361ae650dSJack F Vogel 		status = I40E_ERR_PARAM;
417461ae650dSJack F Vogel 		goto exit;
417561ae650dSJack F Vogel 	}
417661ae650dSJack F Vogel 
417761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, list_type_opc);
417861ae650dSJack F Vogel 
417961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
418061ae650dSJack F Vogel 	if (buff_size > I40E_AQ_LARGE_BUF)
418161ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
418261ae650dSJack F Vogel 
418361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
418461ae650dSJack F Vogel 	*data_size = LE16_TO_CPU(desc.datalen);
418561ae650dSJack F Vogel 
418661ae650dSJack F Vogel 	if (status)
418761ae650dSJack F Vogel 		goto exit;
418861ae650dSJack F Vogel 
418961ae650dSJack F Vogel 	i40e_parse_discover_capabilities(hw, buff, LE32_TO_CPU(cmd->count),
419061ae650dSJack F Vogel 					 list_type_opc);
419161ae650dSJack F Vogel 
419261ae650dSJack F Vogel exit:
419361ae650dSJack F Vogel 	return status;
419461ae650dSJack F Vogel }
419561ae650dSJack F Vogel 
419661ae650dSJack F Vogel /**
419761ae650dSJack F Vogel  * i40e_aq_update_nvm
419861ae650dSJack F Vogel  * @hw: pointer to the hw struct
419961ae650dSJack F Vogel  * @module_pointer: module pointer location in words from the NVM beginning
420061ae650dSJack F Vogel  * @offset: byte offset from the module beginning
420161ae650dSJack F Vogel  * @length: length of the section to be written (in bytes from the offset)
420261ae650dSJack F Vogel  * @data: command buffer (size [bytes] = length)
420361ae650dSJack F Vogel  * @last_command: tells if this is the last command in a series
4204ceebc2f3SEric Joyner  * @preservation_flags: Preservation mode flags
420561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
420661ae650dSJack F Vogel  *
420761ae650dSJack F Vogel  * Update the NVM using the admin queue commands
420861ae650dSJack F Vogel  **/
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)420961ae650dSJack F Vogel enum i40e_status_code i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
421061ae650dSJack F Vogel 				u32 offset, u16 length, void *data,
4211ceebc2f3SEric Joyner 				bool last_command, u8 preservation_flags,
421261ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
421361ae650dSJack F Vogel {
421461ae650dSJack F Vogel 	struct i40e_aq_desc desc;
421561ae650dSJack F Vogel 	struct i40e_aqc_nvm_update *cmd =
421661ae650dSJack F Vogel 		(struct i40e_aqc_nvm_update *)&desc.params.raw;
421761ae650dSJack F Vogel 	enum i40e_status_code status;
421861ae650dSJack F Vogel 
421961ae650dSJack F Vogel 	DEBUGFUNC("i40e_aq_update_nvm");
422061ae650dSJack F Vogel 
422161ae650dSJack F Vogel 	/* In offset the highest byte must be zeroed. */
422261ae650dSJack F Vogel 	if (offset & 0xFF000000) {
422361ae650dSJack F Vogel 		status = I40E_ERR_PARAM;
422461ae650dSJack F Vogel 		goto i40e_aq_update_nvm_exit;
422561ae650dSJack F Vogel 	}
422661ae650dSJack F Vogel 
422761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
422861ae650dSJack F Vogel 
422961ae650dSJack F Vogel 	/* If this is the last command in a series, set the proper flag. */
423061ae650dSJack F Vogel 	if (last_command)
423161ae650dSJack F Vogel 		cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
4232ceebc2f3SEric Joyner 	if (hw->mac.type == I40E_MAC_X722) {
4233ceebc2f3SEric Joyner 		if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_SELECTED)
4234ceebc2f3SEric Joyner 			cmd->command_flags |=
4235ceebc2f3SEric Joyner 				(I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED <<
4236ceebc2f3SEric Joyner 				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
4237ceebc2f3SEric Joyner 		else if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_ALL)
4238ceebc2f3SEric Joyner 			cmd->command_flags |=
4239ceebc2f3SEric Joyner 				(I40E_AQ_NVM_PRESERVATION_FLAGS_ALL <<
4240ceebc2f3SEric Joyner 				 I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
4241ceebc2f3SEric Joyner 	}
424261ae650dSJack F Vogel 	cmd->module_pointer = module_pointer;
424361ae650dSJack F Vogel 	cmd->offset = CPU_TO_LE32(offset);
424461ae650dSJack F Vogel 	cmd->length = CPU_TO_LE16(length);
424561ae650dSJack F Vogel 
424661ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
424761ae650dSJack F Vogel 	if (length > I40E_AQ_LARGE_BUF)
424861ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
424961ae650dSJack F Vogel 
425061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
425161ae650dSJack F Vogel 
425261ae650dSJack F Vogel i40e_aq_update_nvm_exit:
425361ae650dSJack F Vogel 	return status;
425461ae650dSJack F Vogel }
425561ae650dSJack F Vogel 
425661ae650dSJack F Vogel /**
425761ae650dSJack F Vogel  * i40e_aq_get_lldp_mib
425861ae650dSJack F Vogel  * @hw: pointer to the hw struct
425961ae650dSJack F Vogel  * @bridge_type: type of bridge requested
426061ae650dSJack F Vogel  * @mib_type: Local, Remote or both Local and Remote MIBs
426161ae650dSJack F Vogel  * @buff: pointer to a user supplied buffer to store the MIB block
426261ae650dSJack F Vogel  * @buff_size: size of the buffer (in bytes)
426361ae650dSJack F Vogel  * @local_len : length of the returned Local LLDP MIB
426461ae650dSJack F Vogel  * @remote_len: length of the returned Remote LLDP MIB
426561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
426661ae650dSJack F Vogel  *
426761ae650dSJack F Vogel  * Requests the complete LLDP MIB (entire packet).
426861ae650dSJack F Vogel  **/
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)426961ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
427061ae650dSJack F Vogel 				u8 mib_type, void *buff, u16 buff_size,
427161ae650dSJack F Vogel 				u16 *local_len, u16 *remote_len,
427261ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
427361ae650dSJack F Vogel {
427461ae650dSJack F Vogel 	struct i40e_aq_desc desc;
427561ae650dSJack F Vogel 	struct i40e_aqc_lldp_get_mib *cmd =
427661ae650dSJack F Vogel 		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
427761ae650dSJack F Vogel 	struct i40e_aqc_lldp_get_mib *resp =
427861ae650dSJack F Vogel 		(struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
427961ae650dSJack F Vogel 	enum i40e_status_code status;
428061ae650dSJack F Vogel 
428161ae650dSJack F Vogel 	if (buff_size == 0 || !buff)
428261ae650dSJack F Vogel 		return I40E_ERR_PARAM;
428361ae650dSJack F Vogel 
428461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_get_mib);
428561ae650dSJack F Vogel 	/* Indirect Command */
428661ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
428761ae650dSJack F Vogel 
428861ae650dSJack F Vogel 	cmd->type = mib_type & I40E_AQ_LLDP_MIB_TYPE_MASK;
428961ae650dSJack F Vogel 	cmd->type |= ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
429061ae650dSJack F Vogel 		       I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
429161ae650dSJack F Vogel 
429261ae650dSJack F Vogel 	desc.datalen = CPU_TO_LE16(buff_size);
429361ae650dSJack F Vogel 
429461ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
429561ae650dSJack F Vogel 	if (buff_size > I40E_AQ_LARGE_BUF)
429661ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
429761ae650dSJack F Vogel 
429861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
429961ae650dSJack F Vogel 	if (!status) {
430061ae650dSJack F Vogel 		if (local_len != NULL)
430161ae650dSJack F Vogel 			*local_len = LE16_TO_CPU(resp->local_len);
430261ae650dSJack F Vogel 		if (remote_len != NULL)
430361ae650dSJack F Vogel 			*remote_len = LE16_TO_CPU(resp->remote_len);
430461ae650dSJack F Vogel 	}
430561ae650dSJack F Vogel 
430661ae650dSJack F Vogel 	return status;
430761ae650dSJack F Vogel }
430861ae650dSJack F Vogel 
430961ae650dSJack F Vogel  /**
4310f247dc25SJack F Vogel  * i40e_aq_set_lldp_mib - Set the LLDP MIB
4311f247dc25SJack F Vogel  * @hw: pointer to the hw struct
4312f247dc25SJack F Vogel  * @mib_type: Local, Remote or both Local and Remote MIBs
4313f247dc25SJack F Vogel  * @buff: pointer to a user supplied buffer to store the MIB block
4314f247dc25SJack F Vogel  * @buff_size: size of the buffer (in bytes)
4315f247dc25SJack F Vogel  * @cmd_details: pointer to command details structure or NULL
4316f247dc25SJack F Vogel  *
4317f247dc25SJack F Vogel  * Set the LLDP MIB.
4318f247dc25SJack F Vogel  **/
i40e_aq_set_lldp_mib(struct i40e_hw * hw,u8 mib_type,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)4319f247dc25SJack F Vogel enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw,
4320f247dc25SJack F Vogel 				u8 mib_type, void *buff, u16 buff_size,
4321f247dc25SJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
4322f247dc25SJack F Vogel {
4323f247dc25SJack F Vogel 	struct i40e_aq_desc desc;
4324f247dc25SJack F Vogel 	struct i40e_aqc_lldp_set_local_mib *cmd =
4325f247dc25SJack F Vogel 		(struct i40e_aqc_lldp_set_local_mib *)&desc.params.raw;
4326f247dc25SJack F Vogel 	enum i40e_status_code status;
4327f247dc25SJack F Vogel 
4328f247dc25SJack F Vogel 	if (buff_size == 0 || !buff)
4329f247dc25SJack F Vogel 		return I40E_ERR_PARAM;
4330f247dc25SJack F Vogel 
4331f247dc25SJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
4332f247dc25SJack F Vogel 				i40e_aqc_opc_lldp_set_local_mib);
4333f247dc25SJack F Vogel 	/* Indirect Command */
4334f247dc25SJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
4335f247dc25SJack F Vogel 	if (buff_size > I40E_AQ_LARGE_BUF)
4336f247dc25SJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
4337f247dc25SJack F Vogel 	desc.datalen = CPU_TO_LE16(buff_size);
4338f247dc25SJack F Vogel 
4339f247dc25SJack F Vogel 	cmd->type = mib_type;
4340f247dc25SJack F Vogel 	cmd->length = CPU_TO_LE16(buff_size);
4341b4a7ce06SEric Joyner 	cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)buff));
4342f247dc25SJack F Vogel 	cmd->address_low =  CPU_TO_LE32(I40E_LO_DWORD((u64)buff));
4343f247dc25SJack F Vogel 
4344f247dc25SJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4345f247dc25SJack F Vogel 	return status;
4346f247dc25SJack F Vogel }
4347f247dc25SJack F Vogel 
4348f247dc25SJack F Vogel /**
434961ae650dSJack F Vogel  * i40e_aq_cfg_lldp_mib_change_event
435061ae650dSJack F Vogel  * @hw: pointer to the hw struct
435161ae650dSJack F Vogel  * @enable_update: Enable or Disable event posting
435261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
435361ae650dSJack F Vogel  *
435461ae650dSJack F Vogel  * Enable or Disable posting of an event on ARQ when LLDP MIB
435561ae650dSJack F Vogel  * associated with the interface changes
435661ae650dSJack F Vogel  **/
i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw * hw,bool enable_update,struct i40e_asq_cmd_details * cmd_details)435761ae650dSJack F Vogel enum i40e_status_code i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
435861ae650dSJack F Vogel 				bool enable_update,
435961ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
436061ae650dSJack F Vogel {
436161ae650dSJack F Vogel 	struct i40e_aq_desc desc;
436261ae650dSJack F Vogel 	struct i40e_aqc_lldp_update_mib *cmd =
436361ae650dSJack F Vogel 		(struct i40e_aqc_lldp_update_mib *)&desc.params.raw;
436461ae650dSJack F Vogel 	enum i40e_status_code status;
436561ae650dSJack F Vogel 
436661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_mib);
436761ae650dSJack F Vogel 
436861ae650dSJack F Vogel 	if (!enable_update)
436961ae650dSJack F Vogel 		cmd->command |= I40E_AQ_LLDP_MIB_UPDATE_DISABLE;
437061ae650dSJack F Vogel 
437161ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
437261ae650dSJack F Vogel 
437361ae650dSJack F Vogel 	return status;
437461ae650dSJack F Vogel }
437561ae650dSJack F Vogel 
437661ae650dSJack F Vogel /**
4377b4a7ce06SEric Joyner  * i40e_aq_restore_lldp
437861ae650dSJack F Vogel  * @hw: pointer to the hw struct
4379b4a7ce06SEric Joyner  * @setting: pointer to factory setting variable or NULL
4380b4a7ce06SEric Joyner  * @restore: True if factory settings should be restored
438161ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
438261ae650dSJack F Vogel  *
4383b4a7ce06SEric Joyner  * Restore LLDP Agent factory settings if @restore set to True. In other case
4384b4a7ce06SEric Joyner  * only returns factory setting in AQ response.
438561ae650dSJack F Vogel  **/
4386b4a7ce06SEric Joyner enum i40e_status_code
i40e_aq_restore_lldp(struct i40e_hw * hw,u8 * setting,bool restore,struct i40e_asq_cmd_details * cmd_details)4387b4a7ce06SEric Joyner i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore,
438861ae650dSJack F Vogel 		     struct i40e_asq_cmd_details *cmd_details)
438961ae650dSJack F Vogel {
439061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
4391b4a7ce06SEric Joyner 	struct i40e_aqc_lldp_restore *cmd =
4392b4a7ce06SEric Joyner 		(struct i40e_aqc_lldp_restore *)&desc.params.raw;
439361ae650dSJack F Vogel 	enum i40e_status_code status;
439461ae650dSJack F Vogel 
4395b4a7ce06SEric Joyner 	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) {
4396b4a7ce06SEric Joyner 		i40e_debug(hw, I40E_DEBUG_ALL,
4397b4a7ce06SEric Joyner 			   "Restore LLDP not supported by current FW version.\n");
4398b4a7ce06SEric Joyner 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
439961ae650dSJack F Vogel 	}
440061ae650dSJack F Vogel 
4401b4a7ce06SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore);
440261ae650dSJack F Vogel 
4403b4a7ce06SEric Joyner 	if (restore)
4404b4a7ce06SEric Joyner 		cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE;
440561ae650dSJack F Vogel 
4406b4a7ce06SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
440761ae650dSJack F Vogel 
4408b4a7ce06SEric Joyner 	if (setting)
4409b4a7ce06SEric Joyner 		*setting = cmd->command & 1;
441061ae650dSJack F Vogel 
441161ae650dSJack F Vogel 	return status;
441261ae650dSJack F Vogel }
441361ae650dSJack F Vogel 
441461ae650dSJack F Vogel /**
441561ae650dSJack F Vogel  * i40e_aq_stop_lldp
441661ae650dSJack F Vogel  * @hw: pointer to the hw struct
441761ae650dSJack F Vogel  * @shutdown_agent: True if LLDP Agent needs to be Shutdown
4418b4a7ce06SEric Joyner  * @persist: True if stop of LLDP should be persistent across power cycles
441961ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
442061ae650dSJack F Vogel  *
442161ae650dSJack F Vogel  * Stop or Shutdown the embedded LLDP Agent
442261ae650dSJack F Vogel  **/
i40e_aq_stop_lldp(struct i40e_hw * hw,bool shutdown_agent,bool persist,struct i40e_asq_cmd_details * cmd_details)442361ae650dSJack F Vogel enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
4424b4a7ce06SEric Joyner 				bool persist,
442561ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
442661ae650dSJack F Vogel {
442761ae650dSJack F Vogel 	struct i40e_aq_desc desc;
442861ae650dSJack F Vogel 	struct i40e_aqc_lldp_stop *cmd =
442961ae650dSJack F Vogel 		(struct i40e_aqc_lldp_stop *)&desc.params.raw;
443061ae650dSJack F Vogel 	enum i40e_status_code status;
443161ae650dSJack F Vogel 
443261ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
443361ae650dSJack F Vogel 
443461ae650dSJack F Vogel 	if (shutdown_agent)
443561ae650dSJack F Vogel 		cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
443661ae650dSJack F Vogel 
4437b4a7ce06SEric Joyner 	if (persist) {
4438b4a7ce06SEric Joyner 		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
4439b4a7ce06SEric Joyner 			cmd->command |= I40E_AQ_LLDP_AGENT_STOP_PERSIST;
4440b4a7ce06SEric Joyner 		else
4441b4a7ce06SEric Joyner 			i40e_debug(hw, I40E_DEBUG_ALL,
4442b4a7ce06SEric Joyner 				   "Persistent Stop LLDP not supported by current FW version.\n");
4443b4a7ce06SEric Joyner 	}
4444b4a7ce06SEric Joyner 
444561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
444661ae650dSJack F Vogel 
444761ae650dSJack F Vogel 	return status;
444861ae650dSJack F Vogel }
444961ae650dSJack F Vogel 
445061ae650dSJack F Vogel /**
445161ae650dSJack F Vogel  * i40e_aq_start_lldp
445261ae650dSJack F Vogel  * @hw: pointer to the hw struct
4453b4a7ce06SEric Joyner  * @persist: True if start of LLDP should be persistent across power cycles
445461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
445561ae650dSJack F Vogel  *
445661ae650dSJack F Vogel  * Start the embedded LLDP Agent on all ports.
445761ae650dSJack F Vogel  **/
i40e_aq_start_lldp(struct i40e_hw * hw,bool persist,struct i40e_asq_cmd_details * cmd_details)445861ae650dSJack F Vogel enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw,
4459b4a7ce06SEric Joyner 				bool persist,
446061ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
446161ae650dSJack F Vogel {
446261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
446361ae650dSJack F Vogel 	struct i40e_aqc_lldp_start *cmd =
446461ae650dSJack F Vogel 		(struct i40e_aqc_lldp_start *)&desc.params.raw;
446561ae650dSJack F Vogel 	enum i40e_status_code status;
446661ae650dSJack F Vogel 
446761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
446861ae650dSJack F Vogel 
446961ae650dSJack F Vogel 	cmd->command = I40E_AQ_LLDP_AGENT_START;
4470b4a7ce06SEric Joyner 
4471b4a7ce06SEric Joyner 	if (persist) {
4472b4a7ce06SEric Joyner 		if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)
4473b4a7ce06SEric Joyner 			cmd->command |= I40E_AQ_LLDP_AGENT_START_PERSIST;
4474b4a7ce06SEric Joyner 		else
4475b4a7ce06SEric Joyner 			i40e_debug(hw, I40E_DEBUG_ALL,
4476b4a7ce06SEric Joyner 				   "Persistent Start LLDP not supported by current FW version.\n");
4477b4a7ce06SEric Joyner 	}
4478b4a7ce06SEric Joyner 
4479ceebc2f3SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
448061ae650dSJack F Vogel 
4481ceebc2f3SEric Joyner 	return status;
4482ceebc2f3SEric Joyner }
4483ceebc2f3SEric Joyner 
4484ceebc2f3SEric Joyner /**
4485ceebc2f3SEric Joyner  * i40e_aq_set_dcb_parameters
4486ceebc2f3SEric Joyner  * @hw: pointer to the hw struct
4487ceebc2f3SEric Joyner  * @cmd_details: pointer to command details structure or NULL
4488ceebc2f3SEric Joyner  * @dcb_enable: True if DCB configuration needs to be applied
4489ceebc2f3SEric Joyner  *
4490ceebc2f3SEric Joyner  **/
4491ceebc2f3SEric Joyner enum i40e_status_code
i40e_aq_set_dcb_parameters(struct i40e_hw * hw,bool dcb_enable,struct i40e_asq_cmd_details * cmd_details)4492ceebc2f3SEric Joyner i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable,
4493ceebc2f3SEric Joyner 			   struct i40e_asq_cmd_details *cmd_details)
4494ceebc2f3SEric Joyner {
4495ceebc2f3SEric Joyner 	struct i40e_aq_desc desc;
4496ceebc2f3SEric Joyner 	struct i40e_aqc_set_dcb_parameters *cmd =
4497ceebc2f3SEric Joyner 		(struct i40e_aqc_set_dcb_parameters *)&desc.params.raw;
4498ceebc2f3SEric Joyner 	enum i40e_status_code status;
4499ceebc2f3SEric Joyner 
4500b4a7ce06SEric Joyner 	if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE))
4501ceebc2f3SEric Joyner 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
4502ceebc2f3SEric Joyner 
4503ceebc2f3SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
4504ceebc2f3SEric Joyner 					  i40e_aqc_opc_set_dcb_parameters);
4505ceebc2f3SEric Joyner 
4506ceebc2f3SEric Joyner 	if (dcb_enable) {
4507ceebc2f3SEric Joyner 		cmd->valid_flags = I40E_DCB_VALID;
4508ceebc2f3SEric Joyner 		cmd->command = I40E_AQ_DCB_SET_AGENT;
4509ceebc2f3SEric Joyner 	}
451061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
451161ae650dSJack F Vogel 
451261ae650dSJack F Vogel 	return status;
451361ae650dSJack F Vogel }
451461ae650dSJack F Vogel 
451561ae650dSJack F Vogel /**
4516f247dc25SJack F Vogel  * i40e_aq_get_cee_dcb_config
4517f247dc25SJack F Vogel  * @hw: pointer to the hw struct
4518f247dc25SJack F Vogel  * @buff: response buffer that stores CEE operational configuration
4519f247dc25SJack F Vogel  * @buff_size: size of the buffer passed
4520f247dc25SJack F Vogel  * @cmd_details: pointer to command details structure or NULL
4521f247dc25SJack F Vogel  *
4522f247dc25SJack F Vogel  * Get CEE DCBX mode operational configuration from firmware
4523f247dc25SJack F Vogel  **/
i40e_aq_get_cee_dcb_config(struct i40e_hw * hw,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)4524f247dc25SJack F Vogel enum i40e_status_code i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
4525f247dc25SJack F Vogel 				void *buff, u16 buff_size,
4526f247dc25SJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
4527f247dc25SJack F Vogel {
4528f247dc25SJack F Vogel 	struct i40e_aq_desc desc;
4529f247dc25SJack F Vogel 	enum i40e_status_code status;
4530f247dc25SJack F Vogel 
4531f247dc25SJack F Vogel 	if (buff_size == 0 || !buff)
4532f247dc25SJack F Vogel 		return I40E_ERR_PARAM;
4533f247dc25SJack F Vogel 
4534f247dc25SJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_cee_dcb_cfg);
4535f247dc25SJack F Vogel 
4536f247dc25SJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
4537f247dc25SJack F Vogel 	status = i40e_asq_send_command(hw, &desc, (void *)buff, buff_size,
4538f247dc25SJack F Vogel 				       cmd_details);
4539f247dc25SJack F Vogel 
4540f247dc25SJack F Vogel 	return status;
4541f247dc25SJack F Vogel }
4542f247dc25SJack F Vogel 
4543f247dc25SJack F Vogel /**
4544f247dc25SJack F Vogel  * i40e_aq_start_stop_dcbx - Start/Stop DCBx service in FW
4545f247dc25SJack F Vogel  * @hw: pointer to the hw struct
4546f247dc25SJack F Vogel  * @start_agent: True if DCBx Agent needs to be Started
4547f247dc25SJack F Vogel  *				False if DCBx Agent needs to be Stopped
4548f247dc25SJack F Vogel  * @cmd_details: pointer to command details structure or NULL
4549f247dc25SJack F Vogel  *
4550f247dc25SJack F Vogel  * Start/Stop the embedded dcbx Agent
4551f247dc25SJack F Vogel  **/
i40e_aq_start_stop_dcbx(struct i40e_hw * hw,bool start_agent,struct i40e_asq_cmd_details * cmd_details)4552f247dc25SJack F Vogel enum i40e_status_code i40e_aq_start_stop_dcbx(struct i40e_hw *hw,
4553f247dc25SJack F Vogel 				bool start_agent,
4554f247dc25SJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
4555f247dc25SJack F Vogel {
4556f247dc25SJack F Vogel 	struct i40e_aq_desc desc;
4557f247dc25SJack F Vogel 	struct i40e_aqc_lldp_stop_start_specific_agent *cmd =
4558f247dc25SJack F Vogel 		(struct i40e_aqc_lldp_stop_start_specific_agent *)
4559f247dc25SJack F Vogel 				&desc.params.raw;
4560f247dc25SJack F Vogel 	enum i40e_status_code status;
4561f247dc25SJack F Vogel 
4562f247dc25SJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
4563f247dc25SJack F Vogel 				i40e_aqc_opc_lldp_stop_start_spec_agent);
4564f247dc25SJack F Vogel 
4565f247dc25SJack F Vogel 	if (start_agent)
4566f247dc25SJack F Vogel 		cmd->command = I40E_AQC_START_SPECIFIC_AGENT_MASK;
4567f247dc25SJack F Vogel 
4568f247dc25SJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4569f247dc25SJack F Vogel 
4570f247dc25SJack F Vogel 	return status;
4571f247dc25SJack F Vogel }
4572f247dc25SJack F Vogel 
4573f247dc25SJack F Vogel /**
457461ae650dSJack F Vogel  * i40e_aq_add_udp_tunnel
457561ae650dSJack F Vogel  * @hw: pointer to the hw struct
4576cb6b8299SEric Joyner  * @udp_port: the UDP port to add in Host byte order
457761ae650dSJack F Vogel  * @protocol_index: protocol index type
457861ae650dSJack F Vogel  * @filter_index: pointer to filter index
457961ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
4580cb6b8299SEric Joyner  *
4581cb6b8299SEric Joyner  * Note: Firmware expects the udp_port value to be in Little Endian format,
4582cb6b8299SEric Joyner  * and this function will call CPU_TO_LE16 to convert from Host byte order to
4583cb6b8299SEric Joyner  * Little Endian order.
458461ae650dSJack F Vogel  **/
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)458561ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
458661ae650dSJack F Vogel 				u16 udp_port, u8 protocol_index,
458761ae650dSJack F Vogel 				u8 *filter_index,
458861ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
458961ae650dSJack F Vogel {
459061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
459161ae650dSJack F Vogel 	struct i40e_aqc_add_udp_tunnel *cmd =
459261ae650dSJack F Vogel 		(struct i40e_aqc_add_udp_tunnel *)&desc.params.raw;
459361ae650dSJack F Vogel 	struct i40e_aqc_del_udp_tunnel_completion *resp =
459461ae650dSJack F Vogel 		(struct i40e_aqc_del_udp_tunnel_completion *)&desc.params.raw;
459561ae650dSJack F Vogel 	enum i40e_status_code status;
459661ae650dSJack F Vogel 
459761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_udp_tunnel);
459861ae650dSJack F Vogel 
459961ae650dSJack F Vogel 	cmd->udp_port = CPU_TO_LE16(udp_port);
460061ae650dSJack F Vogel 	cmd->protocol_type = protocol_index;
460161ae650dSJack F Vogel 
460261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
460361ae650dSJack F Vogel 
4604f247dc25SJack F Vogel 	if (!status && filter_index)
460561ae650dSJack F Vogel 		*filter_index = resp->index;
460661ae650dSJack F Vogel 
460761ae650dSJack F Vogel 	return status;
460861ae650dSJack F Vogel }
460961ae650dSJack F Vogel 
461061ae650dSJack F Vogel /**
461161ae650dSJack F Vogel  * i40e_aq_del_udp_tunnel
461261ae650dSJack F Vogel  * @hw: pointer to the hw struct
461361ae650dSJack F Vogel  * @index: filter index
461461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
461561ae650dSJack F Vogel  **/
i40e_aq_del_udp_tunnel(struct i40e_hw * hw,u8 index,struct i40e_asq_cmd_details * cmd_details)461661ae650dSJack F Vogel enum i40e_status_code i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
461761ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
461861ae650dSJack F Vogel {
461961ae650dSJack F Vogel 	struct i40e_aq_desc desc;
462061ae650dSJack F Vogel 	struct i40e_aqc_remove_udp_tunnel *cmd =
462161ae650dSJack F Vogel 		(struct i40e_aqc_remove_udp_tunnel *)&desc.params.raw;
462261ae650dSJack F Vogel 	enum i40e_status_code status;
462361ae650dSJack F Vogel 
462461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_del_udp_tunnel);
462561ae650dSJack F Vogel 
462661ae650dSJack F Vogel 	cmd->index = index;
462761ae650dSJack F Vogel 
462861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
462961ae650dSJack F Vogel 
463061ae650dSJack F Vogel 	return status;
463161ae650dSJack F Vogel }
463261ae650dSJack F Vogel 
463361ae650dSJack F Vogel /**
4634abf77452SKrzysztof Galazka  * i40e_aq_get_switch_resource_alloc - command (0x0204) to get allocations
463561ae650dSJack F Vogel  * @hw: pointer to the hw struct
463661ae650dSJack F Vogel  * @num_entries: pointer to u8 to store the number of resource entries returned
463761ae650dSJack F Vogel  * @buf: pointer to a user supplied buffer.  This buffer must be large enough
463861ae650dSJack F Vogel  *        to store the resource information for all resource types.  Each
463961ae650dSJack F Vogel  *        resource type is a i40e_aqc_switch_resource_alloc_data structure.
464061ae650dSJack F Vogel  * @count: size, in bytes, of the buffer provided
464161ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
464261ae650dSJack F Vogel  *
464361ae650dSJack F Vogel  * Query the resources allocated to a function.
464461ae650dSJack F Vogel  **/
i40e_aq_get_switch_resource_alloc(struct i40e_hw * hw,u8 * num_entries,struct i40e_aqc_switch_resource_alloc_element_resp * buf,u16 count,struct i40e_asq_cmd_details * cmd_details)464561ae650dSJack F Vogel enum i40e_status_code i40e_aq_get_switch_resource_alloc(struct i40e_hw *hw,
464661ae650dSJack F Vogel 			u8 *num_entries,
464761ae650dSJack F Vogel 			struct i40e_aqc_switch_resource_alloc_element_resp *buf,
464861ae650dSJack F Vogel 			u16 count,
464961ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
465061ae650dSJack F Vogel {
465161ae650dSJack F Vogel 	struct i40e_aq_desc desc;
465261ae650dSJack F Vogel 	struct i40e_aqc_get_switch_resource_alloc *cmd_resp =
465361ae650dSJack F Vogel 		(struct i40e_aqc_get_switch_resource_alloc *)&desc.params.raw;
465461ae650dSJack F Vogel 	enum i40e_status_code status;
4655f247dc25SJack F Vogel 	u16 length = count * sizeof(*buf);
465661ae650dSJack F Vogel 
465761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
465861ae650dSJack F Vogel 					i40e_aqc_opc_get_switch_resource_alloc);
465961ae650dSJack F Vogel 
466061ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
466161ae650dSJack F Vogel 	if (length > I40E_AQ_LARGE_BUF)
466261ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
466361ae650dSJack F Vogel 
466461ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
466561ae650dSJack F Vogel 
4666f247dc25SJack F Vogel 	if (!status && num_entries)
466761ae650dSJack F Vogel 		*num_entries = cmd_resp->num_entries;
466861ae650dSJack F Vogel 
466961ae650dSJack F Vogel 	return status;
467061ae650dSJack F Vogel }
467161ae650dSJack F Vogel 
467261ae650dSJack F Vogel /**
467361ae650dSJack F Vogel  * i40e_aq_delete_element - Delete switch element
467461ae650dSJack F Vogel  * @hw: pointer to the hw struct
467561ae650dSJack F Vogel  * @seid: the SEID to delete from the switch
467661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
467761ae650dSJack F Vogel  *
467861ae650dSJack F Vogel  * This deletes a switch element from the switch.
467961ae650dSJack F Vogel  **/
i40e_aq_delete_element(struct i40e_hw * hw,u16 seid,struct i40e_asq_cmd_details * cmd_details)468061ae650dSJack F Vogel enum i40e_status_code i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
468161ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
468261ae650dSJack F Vogel {
468361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
468461ae650dSJack F Vogel 	struct i40e_aqc_switch_seid *cmd =
468561ae650dSJack F Vogel 		(struct i40e_aqc_switch_seid *)&desc.params.raw;
468661ae650dSJack F Vogel 	enum i40e_status_code status;
468761ae650dSJack F Vogel 
468861ae650dSJack F Vogel 	if (seid == 0)
468961ae650dSJack F Vogel 		return I40E_ERR_PARAM;
469061ae650dSJack F Vogel 
469161ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_delete_element);
469261ae650dSJack F Vogel 
469361ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
469461ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
469561ae650dSJack F Vogel 
469661ae650dSJack F Vogel 	return status;
469761ae650dSJack F Vogel }
469861ae650dSJack F Vogel 
469961ae650dSJack F Vogel /**
4700d4683565SEric Joyner  * i40e_aq_add_pvirt - Instantiate a Port Virtualizer on a port
470161ae650dSJack F Vogel  * @hw: pointer to the hw struct
470261ae650dSJack F Vogel  * @flags: component flags
470361ae650dSJack F Vogel  * @mac_seid: uplink seid (MAC SEID)
470461ae650dSJack F Vogel  * @vsi_seid: connected vsi seid
470561ae650dSJack F Vogel  * @ret_seid: seid of create pv component
470661ae650dSJack F Vogel  *
470761ae650dSJack F Vogel  * This instantiates an i40e port virtualizer with specified flags.
470861ae650dSJack F Vogel  * Depending on specified flags the port virtualizer can act as a
470961ae650dSJack F Vogel  * 802.1Qbr port virtualizer or a 802.1Qbg S-component.
471061ae650dSJack F Vogel  */
i40e_aq_add_pvirt(struct i40e_hw * hw,u16 flags,u16 mac_seid,u16 vsi_seid,u16 * ret_seid)471161ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_pvirt(struct i40e_hw *hw, u16 flags,
471261ae650dSJack F Vogel 				       u16 mac_seid, u16 vsi_seid,
471361ae650dSJack F Vogel 				       u16 *ret_seid)
471461ae650dSJack F Vogel {
471561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
471661ae650dSJack F Vogel 	struct i40e_aqc_add_update_pv *cmd =
471761ae650dSJack F Vogel 		(struct i40e_aqc_add_update_pv *)&desc.params.raw;
471861ae650dSJack F Vogel 	struct i40e_aqc_add_update_pv_completion *resp =
471961ae650dSJack F Vogel 		(struct i40e_aqc_add_update_pv_completion *)&desc.params.raw;
472061ae650dSJack F Vogel 	enum i40e_status_code status;
472161ae650dSJack F Vogel 
472261ae650dSJack F Vogel 	if (vsi_seid == 0)
472361ae650dSJack F Vogel 		return I40E_ERR_PARAM;
472461ae650dSJack F Vogel 
472561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_pv);
472661ae650dSJack F Vogel 	cmd->command_flags = CPU_TO_LE16(flags);
472761ae650dSJack F Vogel 	cmd->uplink_seid = CPU_TO_LE16(mac_seid);
472861ae650dSJack F Vogel 	cmd->connected_seid = CPU_TO_LE16(vsi_seid);
472961ae650dSJack F Vogel 
473061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
473161ae650dSJack F Vogel 	if (!status && ret_seid)
473261ae650dSJack F Vogel 		*ret_seid = LE16_TO_CPU(resp->pv_seid);
473361ae650dSJack F Vogel 
473461ae650dSJack F Vogel 	return status;
473561ae650dSJack F Vogel }
473661ae650dSJack F Vogel 
473761ae650dSJack F Vogel /**
473861ae650dSJack F Vogel  * i40e_aq_add_tag - Add an S/E-tag
473961ae650dSJack F Vogel  * @hw: pointer to the hw struct
474061ae650dSJack F Vogel  * @direct_to_queue: should s-tag direct flow to a specific queue
474161ae650dSJack F Vogel  * @vsi_seid: VSI SEID to use this tag
474261ae650dSJack F Vogel  * @tag: value of the tag
474361ae650dSJack F Vogel  * @queue_num: queue number, only valid is direct_to_queue is TRUE
474461ae650dSJack F Vogel  * @tags_used: return value, number of tags in use by this PF
474561ae650dSJack F Vogel  * @tags_free: return value, number of unallocated tags
474661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
474761ae650dSJack F Vogel  *
474861ae650dSJack F Vogel  * This associates an S- or E-tag to a VSI in the switch complex.  It returns
474961ae650dSJack F Vogel  * the number of tags allocated by the PF, and the number of unallocated
475061ae650dSJack F Vogel  * tags available.
475161ae650dSJack F Vogel  **/
i40e_aq_add_tag(struct i40e_hw * hw,bool direct_to_queue,u16 vsi_seid,u16 tag,u16 queue_num,u16 * tags_used,u16 * tags_free,struct i40e_asq_cmd_details * cmd_details)475261ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_tag(struct i40e_hw *hw, bool direct_to_queue,
475361ae650dSJack F Vogel 				u16 vsi_seid, u16 tag, u16 queue_num,
475461ae650dSJack F Vogel 				u16 *tags_used, u16 *tags_free,
475561ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
475661ae650dSJack F Vogel {
475761ae650dSJack F Vogel 	struct i40e_aq_desc desc;
475861ae650dSJack F Vogel 	struct i40e_aqc_add_tag *cmd =
475961ae650dSJack F Vogel 		(struct i40e_aqc_add_tag *)&desc.params.raw;
476061ae650dSJack F Vogel 	struct i40e_aqc_add_remove_tag_completion *resp =
476161ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
476261ae650dSJack F Vogel 	enum i40e_status_code status;
476361ae650dSJack F Vogel 
476461ae650dSJack F Vogel 	if (vsi_seid == 0)
476561ae650dSJack F Vogel 		return I40E_ERR_PARAM;
476661ae650dSJack F Vogel 
476761ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_tag);
476861ae650dSJack F Vogel 
476961ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(vsi_seid);
477061ae650dSJack F Vogel 	cmd->tag = CPU_TO_LE16(tag);
477161ae650dSJack F Vogel 	if (direct_to_queue) {
477261ae650dSJack F Vogel 		cmd->flags = CPU_TO_LE16(I40E_AQC_ADD_TAG_FLAG_TO_QUEUE);
477361ae650dSJack F Vogel 		cmd->queue_number = CPU_TO_LE16(queue_num);
477461ae650dSJack F Vogel 	}
477561ae650dSJack F Vogel 
477661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
477761ae650dSJack F Vogel 
477861ae650dSJack F Vogel 	if (!status) {
477961ae650dSJack F Vogel 		if (tags_used != NULL)
478061ae650dSJack F Vogel 			*tags_used = LE16_TO_CPU(resp->tags_used);
478161ae650dSJack F Vogel 		if (tags_free != NULL)
478261ae650dSJack F Vogel 			*tags_free = LE16_TO_CPU(resp->tags_free);
478361ae650dSJack F Vogel 	}
478461ae650dSJack F Vogel 
478561ae650dSJack F Vogel 	return status;
478661ae650dSJack F Vogel }
478761ae650dSJack F Vogel 
478861ae650dSJack F Vogel /**
478961ae650dSJack F Vogel  * i40e_aq_remove_tag - Remove an S- or E-tag
479061ae650dSJack F Vogel  * @hw: pointer to the hw struct
479161ae650dSJack F Vogel  * @vsi_seid: VSI SEID this tag is associated with
479261ae650dSJack F Vogel  * @tag: value of the S-tag to delete
479361ae650dSJack F Vogel  * @tags_used: return value, number of tags in use by this PF
479461ae650dSJack F Vogel  * @tags_free: return value, number of unallocated tags
479561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
479661ae650dSJack F Vogel  *
479761ae650dSJack F Vogel  * This deletes an S- or E-tag from a VSI in the switch complex.  It returns
479861ae650dSJack F Vogel  * the number of tags allocated by the PF, and the number of unallocated
479961ae650dSJack F Vogel  * tags available.
480061ae650dSJack F Vogel  **/
i40e_aq_remove_tag(struct i40e_hw * hw,u16 vsi_seid,u16 tag,u16 * tags_used,u16 * tags_free,struct i40e_asq_cmd_details * cmd_details)480161ae650dSJack F Vogel enum i40e_status_code i40e_aq_remove_tag(struct i40e_hw *hw, u16 vsi_seid,
480261ae650dSJack F Vogel 				u16 tag, u16 *tags_used, u16 *tags_free,
480361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
480461ae650dSJack F Vogel {
480561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
480661ae650dSJack F Vogel 	struct i40e_aqc_remove_tag *cmd =
480761ae650dSJack F Vogel 		(struct i40e_aqc_remove_tag *)&desc.params.raw;
480861ae650dSJack F Vogel 	struct i40e_aqc_add_remove_tag_completion *resp =
480961ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_tag_completion *)&desc.params.raw;
481061ae650dSJack F Vogel 	enum i40e_status_code status;
481161ae650dSJack F Vogel 
481261ae650dSJack F Vogel 	if (vsi_seid == 0)
481361ae650dSJack F Vogel 		return I40E_ERR_PARAM;
481461ae650dSJack F Vogel 
481561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_tag);
481661ae650dSJack F Vogel 
481761ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(vsi_seid);
481861ae650dSJack F Vogel 	cmd->tag = CPU_TO_LE16(tag);
481961ae650dSJack F Vogel 
482061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
482161ae650dSJack F Vogel 
482261ae650dSJack F Vogel 	if (!status) {
482361ae650dSJack F Vogel 		if (tags_used != NULL)
482461ae650dSJack F Vogel 			*tags_used = LE16_TO_CPU(resp->tags_used);
482561ae650dSJack F Vogel 		if (tags_free != NULL)
482661ae650dSJack F Vogel 			*tags_free = LE16_TO_CPU(resp->tags_free);
482761ae650dSJack F Vogel 	}
482861ae650dSJack F Vogel 
482961ae650dSJack F Vogel 	return status;
483061ae650dSJack F Vogel }
483161ae650dSJack F Vogel 
483261ae650dSJack F Vogel /**
483361ae650dSJack F Vogel  * i40e_aq_add_mcast_etag - Add a multicast E-tag
483461ae650dSJack F Vogel  * @hw: pointer to the hw struct
483561ae650dSJack F Vogel  * @pv_seid: Port Virtualizer of this SEID to associate E-tag with
483661ae650dSJack F Vogel  * @etag: value of E-tag to add
483761ae650dSJack F Vogel  * @num_tags_in_buf: number of unicast E-tags in indirect buffer
483861ae650dSJack F Vogel  * @buf: address of indirect buffer
483961ae650dSJack F Vogel  * @tags_used: return value, number of E-tags in use by this port
484061ae650dSJack F Vogel  * @tags_free: return value, number of unallocated M-tags
484161ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
484261ae650dSJack F Vogel  *
484361ae650dSJack F Vogel  * This associates a multicast E-tag to a port virtualizer.  It will return
484461ae650dSJack F Vogel  * the number of tags allocated by the PF, and the number of unallocated
484561ae650dSJack F Vogel  * tags available.
484661ae650dSJack F Vogel  *
484761ae650dSJack F Vogel  * The indirect buffer pointed to by buf is a list of 2-byte E-tags,
484861ae650dSJack F Vogel  * num_tags_in_buf long.
484961ae650dSJack F Vogel  **/
i40e_aq_add_mcast_etag(struct i40e_hw * hw,u16 pv_seid,u16 etag,u8 num_tags_in_buf,void * buf,u16 * tags_used,u16 * tags_free,struct i40e_asq_cmd_details * cmd_details)485061ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
485161ae650dSJack F Vogel 				u16 etag, u8 num_tags_in_buf, void *buf,
485261ae650dSJack F Vogel 				u16 *tags_used, u16 *tags_free,
485361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
485461ae650dSJack F Vogel {
485561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
485661ae650dSJack F Vogel 	struct i40e_aqc_add_remove_mcast_etag *cmd =
485761ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
485861ae650dSJack F Vogel 	struct i40e_aqc_add_remove_mcast_etag_completion *resp =
485961ae650dSJack F Vogel 	   (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
486061ae650dSJack F Vogel 	enum i40e_status_code status;
486161ae650dSJack F Vogel 	u16 length = sizeof(u16) * num_tags_in_buf;
486261ae650dSJack F Vogel 
486361ae650dSJack F Vogel 	if ((pv_seid == 0) || (buf == NULL) || (num_tags_in_buf == 0))
486461ae650dSJack F Vogel 		return I40E_ERR_PARAM;
486561ae650dSJack F Vogel 
486661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
486761ae650dSJack F Vogel 					  i40e_aqc_opc_add_multicast_etag);
486861ae650dSJack F Vogel 
486961ae650dSJack F Vogel 	cmd->pv_seid = CPU_TO_LE16(pv_seid);
487061ae650dSJack F Vogel 	cmd->etag = CPU_TO_LE16(etag);
487161ae650dSJack F Vogel 	cmd->num_unicast_etags = num_tags_in_buf;
487261ae650dSJack F Vogel 
487361ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
487461ae650dSJack F Vogel 
487561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details);
487661ae650dSJack F Vogel 
487761ae650dSJack F Vogel 	if (!status) {
487861ae650dSJack F Vogel 		if (tags_used != NULL)
487961ae650dSJack F Vogel 			*tags_used = LE16_TO_CPU(resp->mcast_etags_used);
488061ae650dSJack F Vogel 		if (tags_free != NULL)
488161ae650dSJack F Vogel 			*tags_free = LE16_TO_CPU(resp->mcast_etags_free);
488261ae650dSJack F Vogel 	}
488361ae650dSJack F Vogel 
488461ae650dSJack F Vogel 	return status;
488561ae650dSJack F Vogel }
488661ae650dSJack F Vogel 
488761ae650dSJack F Vogel /**
488861ae650dSJack F Vogel  * i40e_aq_remove_mcast_etag - Remove a multicast E-tag
488961ae650dSJack F Vogel  * @hw: pointer to the hw struct
489061ae650dSJack F Vogel  * @pv_seid: Port Virtualizer SEID this M-tag is associated with
489161ae650dSJack F Vogel  * @etag: value of the E-tag to remove
489261ae650dSJack F Vogel  * @tags_used: return value, number of tags in use by this port
489361ae650dSJack F Vogel  * @tags_free: return value, number of unallocated tags
489461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
489561ae650dSJack F Vogel  *
489661ae650dSJack F Vogel  * This deletes an E-tag from the port virtualizer.  It will return
489761ae650dSJack F Vogel  * the number of tags allocated by the port, and the number of unallocated
489861ae650dSJack F Vogel  * tags available.
489961ae650dSJack F Vogel  **/
i40e_aq_remove_mcast_etag(struct i40e_hw * hw,u16 pv_seid,u16 etag,u16 * tags_used,u16 * tags_free,struct i40e_asq_cmd_details * cmd_details)490061ae650dSJack F Vogel enum i40e_status_code i40e_aq_remove_mcast_etag(struct i40e_hw *hw, u16 pv_seid,
490161ae650dSJack F Vogel 				u16 etag, u16 *tags_used, u16 *tags_free,
490261ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
490361ae650dSJack F Vogel {
490461ae650dSJack F Vogel 	struct i40e_aq_desc desc;
490561ae650dSJack F Vogel 	struct i40e_aqc_add_remove_mcast_etag *cmd =
490661ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_mcast_etag *)&desc.params.raw;
490761ae650dSJack F Vogel 	struct i40e_aqc_add_remove_mcast_etag_completion *resp =
490861ae650dSJack F Vogel 	   (struct i40e_aqc_add_remove_mcast_etag_completion *)&desc.params.raw;
490961ae650dSJack F Vogel 	enum i40e_status_code status;
491061ae650dSJack F Vogel 
491161ae650dSJack F Vogel 
491261ae650dSJack F Vogel 	if (pv_seid == 0)
491361ae650dSJack F Vogel 		return I40E_ERR_PARAM;
491461ae650dSJack F Vogel 
491561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
491661ae650dSJack F Vogel 					  i40e_aqc_opc_remove_multicast_etag);
491761ae650dSJack F Vogel 
491861ae650dSJack F Vogel 	cmd->pv_seid = CPU_TO_LE16(pv_seid);
491961ae650dSJack F Vogel 	cmd->etag = CPU_TO_LE16(etag);
492061ae650dSJack F Vogel 
492161ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
492261ae650dSJack F Vogel 
492361ae650dSJack F Vogel 	if (!status) {
492461ae650dSJack F Vogel 		if (tags_used != NULL)
492561ae650dSJack F Vogel 			*tags_used = LE16_TO_CPU(resp->mcast_etags_used);
492661ae650dSJack F Vogel 		if (tags_free != NULL)
492761ae650dSJack F Vogel 			*tags_free = LE16_TO_CPU(resp->mcast_etags_free);
492861ae650dSJack F Vogel 	}
492961ae650dSJack F Vogel 
493061ae650dSJack F Vogel 	return status;
493161ae650dSJack F Vogel }
493261ae650dSJack F Vogel 
493361ae650dSJack F Vogel /**
493461ae650dSJack F Vogel  * i40e_aq_update_tag - Update an S/E-tag
493561ae650dSJack F Vogel  * @hw: pointer to the hw struct
493661ae650dSJack F Vogel  * @vsi_seid: VSI SEID using this S-tag
493761ae650dSJack F Vogel  * @old_tag: old tag value
493861ae650dSJack F Vogel  * @new_tag: new tag value
493961ae650dSJack F Vogel  * @tags_used: return value, number of tags in use by this PF
494061ae650dSJack F Vogel  * @tags_free: return value, number of unallocated tags
494161ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
494261ae650dSJack F Vogel  *
494361ae650dSJack F Vogel  * This updates the value of the tag currently attached to this VSI
494461ae650dSJack F Vogel  * in the switch complex.  It will return the number of tags allocated
494561ae650dSJack F Vogel  * by the PF, and the number of unallocated tags available.
494661ae650dSJack F Vogel  **/
i40e_aq_update_tag(struct i40e_hw * hw,u16 vsi_seid,u16 old_tag,u16 new_tag,u16 * tags_used,u16 * tags_free,struct i40e_asq_cmd_details * cmd_details)494761ae650dSJack F Vogel enum i40e_status_code i40e_aq_update_tag(struct i40e_hw *hw, u16 vsi_seid,
494861ae650dSJack F Vogel 				u16 old_tag, u16 new_tag, u16 *tags_used,
494961ae650dSJack F Vogel 				u16 *tags_free,
495061ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
495161ae650dSJack F Vogel {
495261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
495361ae650dSJack F Vogel 	struct i40e_aqc_update_tag *cmd =
495461ae650dSJack F Vogel 		(struct i40e_aqc_update_tag *)&desc.params.raw;
495561ae650dSJack F Vogel 	struct i40e_aqc_update_tag_completion *resp =
495661ae650dSJack F Vogel 		(struct i40e_aqc_update_tag_completion *)&desc.params.raw;
495761ae650dSJack F Vogel 	enum i40e_status_code status;
495861ae650dSJack F Vogel 
495961ae650dSJack F Vogel 	if (vsi_seid == 0)
496061ae650dSJack F Vogel 		return I40E_ERR_PARAM;
496161ae650dSJack F Vogel 
496261ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_update_tag);
496361ae650dSJack F Vogel 
496461ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(vsi_seid);
496561ae650dSJack F Vogel 	cmd->old_tag = CPU_TO_LE16(old_tag);
496661ae650dSJack F Vogel 	cmd->new_tag = CPU_TO_LE16(new_tag);
496761ae650dSJack F Vogel 
496861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
496961ae650dSJack F Vogel 
497061ae650dSJack F Vogel 	if (!status) {
497161ae650dSJack F Vogel 		if (tags_used != NULL)
497261ae650dSJack F Vogel 			*tags_used = LE16_TO_CPU(resp->tags_used);
497361ae650dSJack F Vogel 		if (tags_free != NULL)
497461ae650dSJack F Vogel 			*tags_free = LE16_TO_CPU(resp->tags_free);
497561ae650dSJack F Vogel 	}
497661ae650dSJack F Vogel 
497761ae650dSJack F Vogel 	return status;
497861ae650dSJack F Vogel }
497961ae650dSJack F Vogel 
498061ae650dSJack F Vogel /**
498161ae650dSJack F Vogel  * i40e_aq_dcb_ignore_pfc - Ignore PFC for given TCs
498261ae650dSJack F Vogel  * @hw: pointer to the hw struct
498361ae650dSJack F Vogel  * @tcmap: TC map for request/release any ignore PFC condition
498461ae650dSJack F Vogel  * @request: request or release ignore PFC condition
498561ae650dSJack F Vogel  * @tcmap_ret: return TCs for which PFC is currently ignored
498661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
498761ae650dSJack F Vogel  *
498861ae650dSJack F Vogel  * This sends out request/release to ignore PFC condition for a TC.
498961ae650dSJack F Vogel  * It will return the TCs for which PFC is currently ignored.
499061ae650dSJack F Vogel  **/
i40e_aq_dcb_ignore_pfc(struct i40e_hw * hw,u8 tcmap,bool request,u8 * tcmap_ret,struct i40e_asq_cmd_details * cmd_details)499161ae650dSJack F Vogel enum i40e_status_code i40e_aq_dcb_ignore_pfc(struct i40e_hw *hw, u8 tcmap,
499261ae650dSJack F Vogel 				bool request, u8 *tcmap_ret,
499361ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
499461ae650dSJack F Vogel {
499561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
499661ae650dSJack F Vogel 	struct i40e_aqc_pfc_ignore *cmd_resp =
499761ae650dSJack F Vogel 		(struct i40e_aqc_pfc_ignore *)&desc.params.raw;
499861ae650dSJack F Vogel 	enum i40e_status_code status;
499961ae650dSJack F Vogel 
500061ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_ignore_pfc);
500161ae650dSJack F Vogel 
500261ae650dSJack F Vogel 	if (request)
500361ae650dSJack F Vogel 		cmd_resp->command_flags = I40E_AQC_PFC_IGNORE_SET;
500461ae650dSJack F Vogel 
500561ae650dSJack F Vogel 	cmd_resp->tc_bitmap = tcmap;
500661ae650dSJack F Vogel 
500761ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
500861ae650dSJack F Vogel 
500961ae650dSJack F Vogel 	if (!status) {
501061ae650dSJack F Vogel 		if (tcmap_ret != NULL)
501161ae650dSJack F Vogel 			*tcmap_ret = cmd_resp->tc_bitmap;
501261ae650dSJack F Vogel 	}
501361ae650dSJack F Vogel 
501461ae650dSJack F Vogel 	return status;
501561ae650dSJack F Vogel }
501661ae650dSJack F Vogel 
501761ae650dSJack F Vogel /**
501861ae650dSJack F Vogel  * i40e_aq_dcb_updated - DCB Updated Command
501961ae650dSJack F Vogel  * @hw: pointer to the hw struct
502061ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
502161ae650dSJack F Vogel  *
502261ae650dSJack F Vogel  * When LLDP is handled in PF this command is used by the PF
502361ae650dSJack F Vogel  * to notify EMP that a DCB setting is modified.
502461ae650dSJack F Vogel  * When LLDP is handled in EMP this command is used by the PF
502561ae650dSJack F Vogel  * to notify EMP whenever one of the following parameters get
502661ae650dSJack F Vogel  * modified:
502761ae650dSJack F Vogel  *   - PFCLinkDelayAllowance in PRTDCB_GENC.PFCLDA
502861ae650dSJack F Vogel  *   - PCIRTT in PRTDCB_GENC.PCIRTT
502961ae650dSJack F Vogel  *   - Maximum Frame Size for non-FCoE TCs set by PRTDCB_TDPUC.MAX_TXFRAME.
503061ae650dSJack F Vogel  * EMP will return when the shared RPB settings have been
503161ae650dSJack F Vogel  * recomputed and modified. The retval field in the descriptor
503261ae650dSJack F Vogel  * will be set to 0 when RPB is modified.
503361ae650dSJack F Vogel  **/
i40e_aq_dcb_updated(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)503461ae650dSJack F Vogel enum i40e_status_code i40e_aq_dcb_updated(struct i40e_hw *hw,
503561ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
503661ae650dSJack F Vogel {
503761ae650dSJack F Vogel 	struct i40e_aq_desc desc;
503861ae650dSJack F Vogel 	enum i40e_status_code status;
503961ae650dSJack F Vogel 
504061ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_updated);
504161ae650dSJack F Vogel 
504261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
504361ae650dSJack F Vogel 
504461ae650dSJack F Vogel 	return status;
504561ae650dSJack F Vogel }
504661ae650dSJack F Vogel 
504761ae650dSJack F Vogel /**
504861ae650dSJack F Vogel  * i40e_aq_add_statistics - Add a statistics block to a VLAN in a switch.
504961ae650dSJack F Vogel  * @hw: pointer to the hw struct
505061ae650dSJack F Vogel  * @seid: defines the SEID of the switch for which the stats are requested
505161ae650dSJack F Vogel  * @vlan_id: the VLAN ID for which the statistics are requested
505261ae650dSJack F Vogel  * @stat_index: index of the statistics counters block assigned to this VLAN
505361ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
505461ae650dSJack F Vogel  *
505561ae650dSJack F Vogel  * XL710 supports 128 smonVlanStats counters.This command is used to
505661ae650dSJack F Vogel  * allocate a set of smonVlanStats counters to a specific VLAN in a specific
505761ae650dSJack F Vogel  * switch.
505861ae650dSJack F Vogel  **/
i40e_aq_add_statistics(struct i40e_hw * hw,u16 seid,u16 vlan_id,u16 * stat_index,struct i40e_asq_cmd_details * cmd_details)505961ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_statistics(struct i40e_hw *hw, u16 seid,
506061ae650dSJack F Vogel 				u16 vlan_id, u16 *stat_index,
506161ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
506261ae650dSJack F Vogel {
506361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
506461ae650dSJack F Vogel 	struct i40e_aqc_add_remove_statistics *cmd_resp =
506561ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
506661ae650dSJack F Vogel 	enum i40e_status_code status;
506761ae650dSJack F Vogel 
506861ae650dSJack F Vogel 	if ((seid == 0) || (stat_index == NULL))
506961ae650dSJack F Vogel 		return I40E_ERR_PARAM;
507061ae650dSJack F Vogel 
507161ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_statistics);
507261ae650dSJack F Vogel 
507361ae650dSJack F Vogel 	cmd_resp->seid = CPU_TO_LE16(seid);
507461ae650dSJack F Vogel 	cmd_resp->vlan = CPU_TO_LE16(vlan_id);
507561ae650dSJack F Vogel 
507661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
507761ae650dSJack F Vogel 
5078f247dc25SJack F Vogel 	if (!status && stat_index)
507961ae650dSJack F Vogel 		*stat_index = LE16_TO_CPU(cmd_resp->stat_index);
508061ae650dSJack F Vogel 
508161ae650dSJack F Vogel 	return status;
508261ae650dSJack F Vogel }
508361ae650dSJack F Vogel 
508461ae650dSJack F Vogel /**
508561ae650dSJack F Vogel  * i40e_aq_remove_statistics - Remove a statistics block to a VLAN in a switch.
508661ae650dSJack F Vogel  * @hw: pointer to the hw struct
508761ae650dSJack F Vogel  * @seid: defines the SEID of the switch for which the stats are requested
508861ae650dSJack F Vogel  * @vlan_id: the VLAN ID for which the statistics are requested
508961ae650dSJack F Vogel  * @stat_index: index of the statistics counters block assigned to this VLAN
509061ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
509161ae650dSJack F Vogel  *
509261ae650dSJack F Vogel  * XL710 supports 128 smonVlanStats counters.This command is used to
509361ae650dSJack F Vogel  * deallocate a set of smonVlanStats counters to a specific VLAN in a specific
509461ae650dSJack F Vogel  * switch.
509561ae650dSJack F Vogel  **/
i40e_aq_remove_statistics(struct i40e_hw * hw,u16 seid,u16 vlan_id,u16 stat_index,struct i40e_asq_cmd_details * cmd_details)509661ae650dSJack F Vogel enum i40e_status_code i40e_aq_remove_statistics(struct i40e_hw *hw, u16 seid,
509761ae650dSJack F Vogel 				u16 vlan_id, u16 stat_index,
509861ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
509961ae650dSJack F Vogel {
510061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
510161ae650dSJack F Vogel 	struct i40e_aqc_add_remove_statistics *cmd =
510261ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_statistics *)&desc.params.raw;
510361ae650dSJack F Vogel 	enum i40e_status_code status;
510461ae650dSJack F Vogel 
510561ae650dSJack F Vogel 	if (seid == 0)
510661ae650dSJack F Vogel 		return I40E_ERR_PARAM;
510761ae650dSJack F Vogel 
510861ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
510961ae650dSJack F Vogel 					  i40e_aqc_opc_remove_statistics);
511061ae650dSJack F Vogel 
511161ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
511261ae650dSJack F Vogel 	cmd->vlan  = CPU_TO_LE16(vlan_id);
511361ae650dSJack F Vogel 	cmd->stat_index = CPU_TO_LE16(stat_index);
511461ae650dSJack F Vogel 
511561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
511661ae650dSJack F Vogel 
511761ae650dSJack F Vogel 	return status;
511861ae650dSJack F Vogel }
511961ae650dSJack F Vogel 
512061ae650dSJack F Vogel /**
512161ae650dSJack F Vogel  * i40e_aq_set_port_parameters - set physical port parameters.
512261ae650dSJack F Vogel  * @hw: pointer to the hw struct
512361ae650dSJack F Vogel  * @bad_frame_vsi: defines the VSI to which bad frames are forwarded
512461ae650dSJack F Vogel  * @save_bad_pac: if set packets with errors are forwarded to the bad frames VSI
512561ae650dSJack F Vogel  * @pad_short_pac: if set transmit packets smaller than 60 bytes are padded
512661ae650dSJack F Vogel  * @double_vlan: if set double VLAN is enabled
512761ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
512861ae650dSJack F Vogel  **/
i40e_aq_set_port_parameters(struct i40e_hw * hw,u16 bad_frame_vsi,bool save_bad_pac,bool pad_short_pac,bool double_vlan,struct i40e_asq_cmd_details * cmd_details)512961ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_port_parameters(struct i40e_hw *hw,
513061ae650dSJack F Vogel 				u16 bad_frame_vsi, bool save_bad_pac,
513161ae650dSJack F Vogel 				bool pad_short_pac, bool double_vlan,
513261ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
513361ae650dSJack F Vogel {
513461ae650dSJack F Vogel 	struct i40e_aqc_set_port_parameters *cmd;
513561ae650dSJack F Vogel 	enum i40e_status_code status;
513661ae650dSJack F Vogel 	struct i40e_aq_desc desc;
513761ae650dSJack F Vogel 	u16 command_flags = 0;
513861ae650dSJack F Vogel 
513961ae650dSJack F Vogel 	cmd = (struct i40e_aqc_set_port_parameters *)&desc.params.raw;
514061ae650dSJack F Vogel 
514161ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
514261ae650dSJack F Vogel 					  i40e_aqc_opc_set_port_parameters);
514361ae650dSJack F Vogel 
514461ae650dSJack F Vogel 	cmd->bad_frame_vsi = CPU_TO_LE16(bad_frame_vsi);
514561ae650dSJack F Vogel 	if (save_bad_pac)
514661ae650dSJack F Vogel 		command_flags |= I40E_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS;
514761ae650dSJack F Vogel 	if (pad_short_pac)
514861ae650dSJack F Vogel 		command_flags |= I40E_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS;
514961ae650dSJack F Vogel 	if (double_vlan)
515061ae650dSJack F Vogel 		command_flags |= I40E_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA;
515161ae650dSJack F Vogel 	cmd->command_flags = CPU_TO_LE16(command_flags);
515261ae650dSJack F Vogel 
515361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
515461ae650dSJack F Vogel 
515561ae650dSJack F Vogel 	return status;
515661ae650dSJack F Vogel }
515761ae650dSJack F Vogel 
515861ae650dSJack F Vogel /**
515961ae650dSJack F Vogel  * i40e_aq_tx_sched_cmd - generic Tx scheduler AQ command handler
516061ae650dSJack F Vogel  * @hw: pointer to the hw struct
516161ae650dSJack F Vogel  * @seid: seid for the physical port/switching component/vsi
516261ae650dSJack F Vogel  * @buff: Indirect buffer to hold data parameters and response
516361ae650dSJack F Vogel  * @buff_size: Indirect buffer size
516461ae650dSJack F Vogel  * @opcode: Tx scheduler AQ command opcode
516561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
516661ae650dSJack F Vogel  *
516761ae650dSJack F Vogel  * Generic command handler for Tx scheduler AQ commands
516861ae650dSJack F Vogel  **/
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)516961ae650dSJack F Vogel static enum i40e_status_code i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
517061ae650dSJack F Vogel 				void *buff, u16 buff_size,
517161ae650dSJack F Vogel 				 enum i40e_admin_queue_opc opcode,
517261ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
517361ae650dSJack F Vogel {
517461ae650dSJack F Vogel 	struct i40e_aq_desc desc;
517561ae650dSJack F Vogel 	struct i40e_aqc_tx_sched_ind *cmd =
517661ae650dSJack F Vogel 		(struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
517761ae650dSJack F Vogel 	enum i40e_status_code status;
517861ae650dSJack F Vogel 	bool cmd_param_flag = FALSE;
517961ae650dSJack F Vogel 
518061ae650dSJack F Vogel 	switch (opcode) {
518161ae650dSJack F Vogel 	case i40e_aqc_opc_configure_vsi_ets_sla_bw_limit:
518261ae650dSJack F Vogel 	case i40e_aqc_opc_configure_vsi_tc_bw:
518361ae650dSJack F Vogel 	case i40e_aqc_opc_enable_switching_comp_ets:
518461ae650dSJack F Vogel 	case i40e_aqc_opc_modify_switching_comp_ets:
518561ae650dSJack F Vogel 	case i40e_aqc_opc_disable_switching_comp_ets:
518661ae650dSJack F Vogel 	case i40e_aqc_opc_configure_switching_comp_ets_bw_limit:
518761ae650dSJack F Vogel 	case i40e_aqc_opc_configure_switching_comp_bw_config:
518861ae650dSJack F Vogel 		cmd_param_flag = TRUE;
518961ae650dSJack F Vogel 		break;
519061ae650dSJack F Vogel 	case i40e_aqc_opc_query_vsi_bw_config:
519161ae650dSJack F Vogel 	case i40e_aqc_opc_query_vsi_ets_sla_config:
519261ae650dSJack F Vogel 	case i40e_aqc_opc_query_switching_comp_ets_config:
519361ae650dSJack F Vogel 	case i40e_aqc_opc_query_port_ets_config:
519461ae650dSJack F Vogel 	case i40e_aqc_opc_query_switching_comp_bw_config:
519561ae650dSJack F Vogel 		cmd_param_flag = FALSE;
519661ae650dSJack F Vogel 		break;
519761ae650dSJack F Vogel 	default:
519861ae650dSJack F Vogel 		return I40E_ERR_PARAM;
519961ae650dSJack F Vogel 	}
520061ae650dSJack F Vogel 
520161ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, opcode);
520261ae650dSJack F Vogel 
520361ae650dSJack F Vogel 	/* Indirect command */
520461ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
520561ae650dSJack F Vogel 	if (cmd_param_flag)
520661ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
520761ae650dSJack F Vogel 	if (buff_size > I40E_AQ_LARGE_BUF)
520861ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
520961ae650dSJack F Vogel 
521061ae650dSJack F Vogel 	desc.datalen = CPU_TO_LE16(buff_size);
521161ae650dSJack F Vogel 
521261ae650dSJack F Vogel 	cmd->vsi_seid = CPU_TO_LE16(seid);
521361ae650dSJack F Vogel 
521461ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
521561ae650dSJack F Vogel 
521661ae650dSJack F Vogel 	return status;
521761ae650dSJack F Vogel }
521861ae650dSJack F Vogel 
521961ae650dSJack F Vogel /**
522061ae650dSJack F Vogel  * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
522161ae650dSJack F Vogel  * @hw: pointer to the hw struct
522261ae650dSJack F Vogel  * @seid: VSI seid
522361ae650dSJack F Vogel  * @credit: BW limit credits (0 = disabled)
522461ae650dSJack F Vogel  * @max_credit: Max BW limit credits
522561ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
522661ae650dSJack F Vogel  **/
i40e_aq_config_vsi_bw_limit(struct i40e_hw * hw,u16 seid,u16 credit,u8 max_credit,struct i40e_asq_cmd_details * cmd_details)522761ae650dSJack F Vogel enum i40e_status_code i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
522861ae650dSJack F Vogel 				u16 seid, u16 credit, u8 max_credit,
522961ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
523061ae650dSJack F Vogel {
523161ae650dSJack F Vogel 	struct i40e_aq_desc desc;
523261ae650dSJack F Vogel 	struct i40e_aqc_configure_vsi_bw_limit *cmd =
523361ae650dSJack F Vogel 		(struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
523461ae650dSJack F Vogel 	enum i40e_status_code status;
523561ae650dSJack F Vogel 
523661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
523761ae650dSJack F Vogel 					  i40e_aqc_opc_configure_vsi_bw_limit);
523861ae650dSJack F Vogel 
523961ae650dSJack F Vogel 	cmd->vsi_seid = CPU_TO_LE16(seid);
524061ae650dSJack F Vogel 	cmd->credit = CPU_TO_LE16(credit);
524161ae650dSJack F Vogel 	cmd->max_credit = max_credit;
524261ae650dSJack F Vogel 
524361ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
524461ae650dSJack F Vogel 
524561ae650dSJack F Vogel 	return status;
524661ae650dSJack F Vogel }
524761ae650dSJack F Vogel 
524861ae650dSJack F Vogel /**
524961ae650dSJack F Vogel  * i40e_aq_config_switch_comp_bw_limit - Configure Switching component BW Limit
525061ae650dSJack F Vogel  * @hw: pointer to the hw struct
525161ae650dSJack F Vogel  * @seid: switching component seid
525261ae650dSJack F Vogel  * @credit: BW limit credits (0 = disabled)
525361ae650dSJack F Vogel  * @max_bw: Max BW limit credits
525461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
525561ae650dSJack F Vogel  **/
i40e_aq_config_switch_comp_bw_limit(struct i40e_hw * hw,u16 seid,u16 credit,u8 max_bw,struct i40e_asq_cmd_details * cmd_details)525661ae650dSJack F Vogel enum i40e_status_code i40e_aq_config_switch_comp_bw_limit(struct i40e_hw *hw,
525761ae650dSJack F Vogel 				u16 seid, u16 credit, u8 max_bw,
525861ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
525961ae650dSJack F Vogel {
526061ae650dSJack F Vogel 	struct i40e_aq_desc desc;
526161ae650dSJack F Vogel 	struct i40e_aqc_configure_switching_comp_bw_limit *cmd =
526261ae650dSJack F Vogel 	  (struct i40e_aqc_configure_switching_comp_bw_limit *)&desc.params.raw;
526361ae650dSJack F Vogel 	enum i40e_status_code status;
526461ae650dSJack F Vogel 
526561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
526661ae650dSJack F Vogel 				i40e_aqc_opc_configure_switching_comp_bw_limit);
526761ae650dSJack F Vogel 
526861ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
526961ae650dSJack F Vogel 	cmd->credit = CPU_TO_LE16(credit);
527061ae650dSJack F Vogel 	cmd->max_bw = max_bw;
527161ae650dSJack F Vogel 
527261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
527361ae650dSJack F Vogel 
527461ae650dSJack F Vogel 	return status;
527561ae650dSJack F Vogel }
527661ae650dSJack F Vogel 
527761ae650dSJack F Vogel /**
527861ae650dSJack F Vogel  * i40e_aq_config_vsi_ets_sla_bw_limit - Config VSI BW Limit per TC
527961ae650dSJack F Vogel  * @hw: pointer to the hw struct
528061ae650dSJack F Vogel  * @seid: VSI seid
528161ae650dSJack F Vogel  * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
528261ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
528361ae650dSJack F Vogel  **/
i40e_aq_config_vsi_ets_sla_bw_limit(struct i40e_hw * hw,u16 seid,struct i40e_aqc_configure_vsi_ets_sla_bw_data * bw_data,struct i40e_asq_cmd_details * cmd_details)528461ae650dSJack F Vogel enum i40e_status_code i40e_aq_config_vsi_ets_sla_bw_limit(struct i40e_hw *hw,
528561ae650dSJack F Vogel 			u16 seid,
528661ae650dSJack F Vogel 			struct i40e_aqc_configure_vsi_ets_sla_bw_data *bw_data,
528761ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
528861ae650dSJack F Vogel {
528961ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
529061ae650dSJack F Vogel 				    i40e_aqc_opc_configure_vsi_ets_sla_bw_limit,
529161ae650dSJack F Vogel 				    cmd_details);
529261ae650dSJack F Vogel }
529361ae650dSJack F Vogel 
529461ae650dSJack F Vogel /**
529561ae650dSJack F Vogel  * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
529661ae650dSJack F Vogel  * @hw: pointer to the hw struct
529761ae650dSJack F Vogel  * @seid: VSI seid
529861ae650dSJack F Vogel  * @bw_data: Buffer holding enabled TCs, relative TC BW limit/credits
529961ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
530061ae650dSJack F Vogel  **/
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)530161ae650dSJack F Vogel enum i40e_status_code i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
530261ae650dSJack F Vogel 			u16 seid,
530361ae650dSJack F Vogel 			struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
530461ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
530561ae650dSJack F Vogel {
530661ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
530761ae650dSJack F Vogel 				    i40e_aqc_opc_configure_vsi_tc_bw,
530861ae650dSJack F Vogel 				    cmd_details);
530961ae650dSJack F Vogel }
531061ae650dSJack F Vogel 
531161ae650dSJack F Vogel /**
531261ae650dSJack F Vogel  * i40e_aq_config_switch_comp_ets_bw_limit - Config Switch comp BW Limit per TC
531361ae650dSJack F Vogel  * @hw: pointer to the hw struct
531461ae650dSJack F Vogel  * @seid: seid of the switching component
531561ae650dSJack F Vogel  * @bw_data: Buffer holding enabled TCs, per TC BW limit/credits
531661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
531761ae650dSJack F Vogel  **/
i40e_aq_config_switch_comp_ets_bw_limit(struct i40e_hw * hw,u16 seid,struct i40e_aqc_configure_switching_comp_ets_bw_limit_data * bw_data,struct i40e_asq_cmd_details * cmd_details)531861ae650dSJack F Vogel enum i40e_status_code i40e_aq_config_switch_comp_ets_bw_limit(
531961ae650dSJack F Vogel 	struct i40e_hw *hw, u16 seid,
532061ae650dSJack F Vogel 	struct i40e_aqc_configure_switching_comp_ets_bw_limit_data *bw_data,
532161ae650dSJack F Vogel 	struct i40e_asq_cmd_details *cmd_details)
532261ae650dSJack F Vogel {
532361ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
532461ae650dSJack F Vogel 			    i40e_aqc_opc_configure_switching_comp_ets_bw_limit,
532561ae650dSJack F Vogel 			    cmd_details);
532661ae650dSJack F Vogel }
532761ae650dSJack F Vogel 
532861ae650dSJack F Vogel /**
532961ae650dSJack F Vogel  * i40e_aq_query_vsi_bw_config - Query VSI BW configuration
533061ae650dSJack F Vogel  * @hw: pointer to the hw struct
533161ae650dSJack F Vogel  * @seid: seid of the VSI
533261ae650dSJack F Vogel  * @bw_data: Buffer to hold VSI BW configuration
533361ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
533461ae650dSJack F Vogel  **/
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)533561ae650dSJack F Vogel enum i40e_status_code i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
533661ae650dSJack F Vogel 			u16 seid,
533761ae650dSJack F Vogel 			struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
533861ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
533961ae650dSJack F Vogel {
534061ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
534161ae650dSJack F Vogel 				    i40e_aqc_opc_query_vsi_bw_config,
534261ae650dSJack F Vogel 				    cmd_details);
534361ae650dSJack F Vogel }
534461ae650dSJack F Vogel 
534561ae650dSJack F Vogel /**
534661ae650dSJack F Vogel  * i40e_aq_query_vsi_ets_sla_config - Query VSI BW configuration per TC
534761ae650dSJack F Vogel  * @hw: pointer to the hw struct
534861ae650dSJack F Vogel  * @seid: seid of the VSI
534961ae650dSJack F Vogel  * @bw_data: Buffer to hold VSI BW configuration per TC
535061ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
535161ae650dSJack F Vogel  **/
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)535261ae650dSJack F Vogel enum i40e_status_code i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
535361ae650dSJack F Vogel 			u16 seid,
535461ae650dSJack F Vogel 			struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
535561ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
535661ae650dSJack F Vogel {
535761ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
535861ae650dSJack F Vogel 				    i40e_aqc_opc_query_vsi_ets_sla_config,
535961ae650dSJack F Vogel 				    cmd_details);
536061ae650dSJack F Vogel }
536161ae650dSJack F Vogel 
536261ae650dSJack F Vogel /**
536361ae650dSJack F Vogel  * i40e_aq_query_switch_comp_ets_config - Query Switch comp BW config per TC
536461ae650dSJack F Vogel  * @hw: pointer to the hw struct
536561ae650dSJack F Vogel  * @seid: seid of the switching component
536661ae650dSJack F Vogel  * @bw_data: Buffer to hold switching component's per TC BW config
536761ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
536861ae650dSJack F Vogel  **/
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)536961ae650dSJack F Vogel enum i40e_status_code i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
537061ae650dSJack F Vogel 		u16 seid,
537161ae650dSJack F Vogel 		struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
537261ae650dSJack F Vogel 		struct i40e_asq_cmd_details *cmd_details)
537361ae650dSJack F Vogel {
537461ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
537561ae650dSJack F Vogel 				   i40e_aqc_opc_query_switching_comp_ets_config,
537661ae650dSJack F Vogel 				   cmd_details);
537761ae650dSJack F Vogel }
537861ae650dSJack F Vogel 
537961ae650dSJack F Vogel /**
538061ae650dSJack F Vogel  * i40e_aq_query_port_ets_config - Query Physical Port ETS configuration
538161ae650dSJack F Vogel  * @hw: pointer to the hw struct
538261ae650dSJack F Vogel  * @seid: seid of the VSI or switching component connected to Physical Port
538361ae650dSJack F Vogel  * @bw_data: Buffer to hold current ETS configuration for the Physical Port
538461ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
538561ae650dSJack F Vogel  **/
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)538661ae650dSJack F Vogel enum i40e_status_code i40e_aq_query_port_ets_config(struct i40e_hw *hw,
538761ae650dSJack F Vogel 			u16 seid,
538861ae650dSJack F Vogel 			struct i40e_aqc_query_port_ets_config_resp *bw_data,
538961ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
539061ae650dSJack F Vogel {
539161ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
539261ae650dSJack F Vogel 				    i40e_aqc_opc_query_port_ets_config,
539361ae650dSJack F Vogel 				    cmd_details);
539461ae650dSJack F Vogel }
539561ae650dSJack F Vogel 
539661ae650dSJack F Vogel /**
539761ae650dSJack F Vogel  * i40e_aq_query_switch_comp_bw_config - Query Switch comp BW configuration
539861ae650dSJack F Vogel  * @hw: pointer to the hw struct
539961ae650dSJack F Vogel  * @seid: seid of the switching component
540061ae650dSJack F Vogel  * @bw_data: Buffer to hold switching component's BW configuration
540161ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
540261ae650dSJack F Vogel  **/
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)540361ae650dSJack F Vogel enum i40e_status_code i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
540461ae650dSJack F Vogel 		u16 seid,
540561ae650dSJack F Vogel 		struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
540661ae650dSJack F Vogel 		struct i40e_asq_cmd_details *cmd_details)
540761ae650dSJack F Vogel {
540861ae650dSJack F Vogel 	return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
540961ae650dSJack F Vogel 				    i40e_aqc_opc_query_switching_comp_bw_config,
541061ae650dSJack F Vogel 				    cmd_details);
541161ae650dSJack F Vogel }
541261ae650dSJack F Vogel 
541361ae650dSJack F Vogel /**
541461ae650dSJack F Vogel  * i40e_validate_filter_settings
541561ae650dSJack F Vogel  * @hw: pointer to the hardware structure
541661ae650dSJack F Vogel  * @settings: Filter control settings
541761ae650dSJack F Vogel  *
541861ae650dSJack F Vogel  * Check and validate the filter control settings passed.
541961ae650dSJack F Vogel  * The function checks for the valid filter/context sizes being
542061ae650dSJack F Vogel  * passed for FCoE and PE.
542161ae650dSJack F Vogel  *
542261ae650dSJack F Vogel  * Returns I40E_SUCCESS if the values passed are valid and within
542361ae650dSJack F Vogel  * range else returns an error.
542461ae650dSJack F Vogel  **/
i40e_validate_filter_settings(struct i40e_hw * hw,struct i40e_filter_control_settings * settings)542561ae650dSJack F Vogel static enum i40e_status_code i40e_validate_filter_settings(struct i40e_hw *hw,
542661ae650dSJack F Vogel 				struct i40e_filter_control_settings *settings)
542761ae650dSJack F Vogel {
542861ae650dSJack F Vogel 	u32 fcoe_cntx_size, fcoe_filt_size;
542961ae650dSJack F Vogel 	u32 fcoe_fmax;
543061ae650dSJack F Vogel 
543161ae650dSJack F Vogel 	u32 val;
543261ae650dSJack F Vogel 
543361ae650dSJack F Vogel 	/* Validate FCoE settings passed */
543461ae650dSJack F Vogel 	switch (settings->fcoe_filt_num) {
543561ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_1K:
543661ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_2K:
543761ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_4K:
543861ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_8K:
543961ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_16K:
544061ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_32K:
544161ae650dSJack F Vogel 		fcoe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
544261ae650dSJack F Vogel 		fcoe_filt_size <<= (u32)settings->fcoe_filt_num;
544361ae650dSJack F Vogel 		break;
544461ae650dSJack F Vogel 	default:
544561ae650dSJack F Vogel 		return I40E_ERR_PARAM;
544661ae650dSJack F Vogel 	}
544761ae650dSJack F Vogel 
544861ae650dSJack F Vogel 	switch (settings->fcoe_cntx_num) {
544961ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_512:
545061ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_1K:
545161ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_2K:
545261ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_4K:
545361ae650dSJack F Vogel 		fcoe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
545461ae650dSJack F Vogel 		fcoe_cntx_size <<= (u32)settings->fcoe_cntx_num;
545561ae650dSJack F Vogel 		break;
545661ae650dSJack F Vogel 	default:
545761ae650dSJack F Vogel 		return I40E_ERR_PARAM;
545861ae650dSJack F Vogel 	}
545961ae650dSJack F Vogel 
546061ae650dSJack F Vogel 	/* Validate PE settings passed */
546161ae650dSJack F Vogel 	switch (settings->pe_filt_num) {
546261ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_1K:
546361ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_2K:
546461ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_4K:
546561ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_8K:
546661ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_16K:
546761ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_32K:
546861ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_64K:
546961ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_128K:
547061ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_256K:
547161ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_512K:
547261ae650dSJack F Vogel 	case I40E_HASH_FILTER_SIZE_1M:
547361ae650dSJack F Vogel 		break;
547461ae650dSJack F Vogel 	default:
547561ae650dSJack F Vogel 		return I40E_ERR_PARAM;
547661ae650dSJack F Vogel 	}
547761ae650dSJack F Vogel 
547861ae650dSJack F Vogel 	switch (settings->pe_cntx_num) {
547961ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_512:
548061ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_1K:
548161ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_2K:
548261ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_4K:
548361ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_8K:
548461ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_16K:
548561ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_32K:
548661ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_64K:
548761ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_128K:
548861ae650dSJack F Vogel 	case I40E_DMA_CNTX_SIZE_256K:
548961ae650dSJack F Vogel 		break;
549061ae650dSJack F Vogel 	default:
549161ae650dSJack F Vogel 		return I40E_ERR_PARAM;
549261ae650dSJack F Vogel 	}
549361ae650dSJack F Vogel 
549461ae650dSJack F Vogel 	/* FCHSIZE + FCDSIZE should not be greater than PMFCOEFMAX */
549561ae650dSJack F Vogel 	val = rd32(hw, I40E_GLHMC_FCOEFMAX);
549661ae650dSJack F Vogel 	fcoe_fmax = (val & I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK)
549761ae650dSJack F Vogel 		     >> I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT;
549861ae650dSJack F Vogel 	if (fcoe_filt_size + fcoe_cntx_size >  fcoe_fmax)
549961ae650dSJack F Vogel 		return I40E_ERR_INVALID_SIZE;
550061ae650dSJack F Vogel 
550161ae650dSJack F Vogel 	return I40E_SUCCESS;
550261ae650dSJack F Vogel }
550361ae650dSJack F Vogel 
550461ae650dSJack F Vogel /**
550561ae650dSJack F Vogel  * i40e_set_filter_control
550661ae650dSJack F Vogel  * @hw: pointer to the hardware structure
550761ae650dSJack F Vogel  * @settings: Filter control settings
550861ae650dSJack F Vogel  *
550961ae650dSJack F Vogel  * Set the Queue Filters for PE/FCoE and enable filters required
551061ae650dSJack F Vogel  * for a single PF. It is expected that these settings are programmed
551161ae650dSJack F Vogel  * at the driver initialization time.
551261ae650dSJack F Vogel  **/
i40e_set_filter_control(struct i40e_hw * hw,struct i40e_filter_control_settings * settings)551361ae650dSJack F Vogel enum i40e_status_code i40e_set_filter_control(struct i40e_hw *hw,
551461ae650dSJack F Vogel 				struct i40e_filter_control_settings *settings)
551561ae650dSJack F Vogel {
551661ae650dSJack F Vogel 	enum i40e_status_code ret = I40E_SUCCESS;
551761ae650dSJack F Vogel 	u32 hash_lut_size = 0;
551861ae650dSJack F Vogel 	u32 val;
551961ae650dSJack F Vogel 
552061ae650dSJack F Vogel 	if (!settings)
552161ae650dSJack F Vogel 		return I40E_ERR_PARAM;
552261ae650dSJack F Vogel 
552361ae650dSJack F Vogel 	/* Validate the input settings */
552461ae650dSJack F Vogel 	ret = i40e_validate_filter_settings(hw, settings);
552561ae650dSJack F Vogel 	if (ret)
552661ae650dSJack F Vogel 		return ret;
552761ae650dSJack F Vogel 
552861ae650dSJack F Vogel 	/* Read the PF Queue Filter control register */
5529d4683565SEric Joyner 	val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
553061ae650dSJack F Vogel 
553161ae650dSJack F Vogel 	/* Program required PE hash buckets for the PF */
553261ae650dSJack F Vogel 	val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
553361ae650dSJack F Vogel 	val |= ((u32)settings->pe_filt_num << I40E_PFQF_CTL_0_PEHSIZE_SHIFT) &
553461ae650dSJack F Vogel 		I40E_PFQF_CTL_0_PEHSIZE_MASK;
553561ae650dSJack F Vogel 	/* Program required PE contexts for the PF */
553661ae650dSJack F Vogel 	val &= ~I40E_PFQF_CTL_0_PEDSIZE_MASK;
553761ae650dSJack F Vogel 	val |= ((u32)settings->pe_cntx_num << I40E_PFQF_CTL_0_PEDSIZE_SHIFT) &
553861ae650dSJack F Vogel 		I40E_PFQF_CTL_0_PEDSIZE_MASK;
553961ae650dSJack F Vogel 
554061ae650dSJack F Vogel 	/* Program required FCoE hash buckets for the PF */
554161ae650dSJack F Vogel 	val &= ~I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
554261ae650dSJack F Vogel 	val |= ((u32)settings->fcoe_filt_num <<
554361ae650dSJack F Vogel 			I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT) &
554461ae650dSJack F Vogel 		I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
554561ae650dSJack F Vogel 	/* Program required FCoE DDP contexts for the PF */
554661ae650dSJack F Vogel 	val &= ~I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
554761ae650dSJack F Vogel 	val |= ((u32)settings->fcoe_cntx_num <<
554861ae650dSJack F Vogel 			I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT) &
554961ae650dSJack F Vogel 		I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
555061ae650dSJack F Vogel 
555161ae650dSJack F Vogel 	/* Program Hash LUT size for the PF */
555261ae650dSJack F Vogel 	val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
555361ae650dSJack F Vogel 	if (settings->hash_lut_size == I40E_HASH_LUT_SIZE_512)
555461ae650dSJack F Vogel 		hash_lut_size = 1;
555561ae650dSJack F Vogel 	val |= (hash_lut_size << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT) &
555661ae650dSJack F Vogel 		I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
555761ae650dSJack F Vogel 
555861ae650dSJack F Vogel 	/* Enable FDIR, Ethertype and MACVLAN filters for PF and VFs */
555961ae650dSJack F Vogel 	if (settings->enable_fdir)
556061ae650dSJack F Vogel 		val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
556161ae650dSJack F Vogel 	if (settings->enable_ethtype)
556261ae650dSJack F Vogel 		val |= I40E_PFQF_CTL_0_ETYPE_ENA_MASK;
556361ae650dSJack F Vogel 	if (settings->enable_macvlan)
556461ae650dSJack F Vogel 		val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
556561ae650dSJack F Vogel 
5566d4683565SEric Joyner 	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
556761ae650dSJack F Vogel 
556861ae650dSJack F Vogel 	return I40E_SUCCESS;
556961ae650dSJack F Vogel }
557061ae650dSJack F Vogel 
557161ae650dSJack F Vogel /**
557261ae650dSJack F Vogel  * i40e_aq_add_rem_control_packet_filter - Add or Remove Control Packet Filter
557361ae650dSJack F Vogel  * @hw: pointer to the hw struct
557461ae650dSJack F Vogel  * @mac_addr: MAC address to use in the filter
557561ae650dSJack F Vogel  * @ethtype: Ethertype to use in the filter
557661ae650dSJack F Vogel  * @flags: Flags that needs to be applied to the filter
557761ae650dSJack F Vogel  * @vsi_seid: seid of the control VSI
557861ae650dSJack F Vogel  * @queue: VSI queue number to send the packet to
557961ae650dSJack F Vogel  * @is_add: Add control packet filter if True else remove
558061ae650dSJack F Vogel  * @stats: Structure to hold information on control filter counts
558161ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
558261ae650dSJack F Vogel  *
558361ae650dSJack F Vogel  * This command will Add or Remove control packet filter for a control VSI.
558461ae650dSJack F Vogel  * In return it will update the total number of perfect filter count in
558561ae650dSJack F Vogel  * the stats member.
558661ae650dSJack F Vogel  **/
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)558761ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
558861ae650dSJack F Vogel 				u8 *mac_addr, u16 ethtype, u16 flags,
558961ae650dSJack F Vogel 				u16 vsi_seid, u16 queue, bool is_add,
559061ae650dSJack F Vogel 				struct i40e_control_filter_stats *stats,
559161ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
559261ae650dSJack F Vogel {
559361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
559461ae650dSJack F Vogel 	struct i40e_aqc_add_remove_control_packet_filter *cmd =
559561ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_control_packet_filter *)
559661ae650dSJack F Vogel 		&desc.params.raw;
559761ae650dSJack F Vogel 	struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
559861ae650dSJack F Vogel 		(struct i40e_aqc_add_remove_control_packet_filter_completion *)
559961ae650dSJack F Vogel 		&desc.params.raw;
560061ae650dSJack F Vogel 	enum i40e_status_code status;
560161ae650dSJack F Vogel 
560261ae650dSJack F Vogel 	if (vsi_seid == 0)
560361ae650dSJack F Vogel 		return I40E_ERR_PARAM;
560461ae650dSJack F Vogel 
560561ae650dSJack F Vogel 	if (is_add) {
560661ae650dSJack F Vogel 		i40e_fill_default_direct_cmd_desc(&desc,
560761ae650dSJack F Vogel 				i40e_aqc_opc_add_control_packet_filter);
560861ae650dSJack F Vogel 		cmd->queue = CPU_TO_LE16(queue);
560961ae650dSJack F Vogel 	} else {
561061ae650dSJack F Vogel 		i40e_fill_default_direct_cmd_desc(&desc,
561161ae650dSJack F Vogel 				i40e_aqc_opc_remove_control_packet_filter);
561261ae650dSJack F Vogel 	}
561361ae650dSJack F Vogel 
561461ae650dSJack F Vogel 	if (mac_addr)
5615ceebc2f3SEric Joyner 		i40e_memcpy(cmd->mac, mac_addr, ETH_ALEN,
561661ae650dSJack F Vogel 			    I40E_NONDMA_TO_NONDMA);
561761ae650dSJack F Vogel 
561861ae650dSJack F Vogel 	cmd->etype = CPU_TO_LE16(ethtype);
561961ae650dSJack F Vogel 	cmd->flags = CPU_TO_LE16(flags);
562061ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(vsi_seid);
562161ae650dSJack F Vogel 
562261ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
562361ae650dSJack F Vogel 
562461ae650dSJack F Vogel 	if (!status && stats) {
562561ae650dSJack F Vogel 		stats->mac_etype_used = LE16_TO_CPU(resp->mac_etype_used);
562661ae650dSJack F Vogel 		stats->etype_used = LE16_TO_CPU(resp->etype_used);
562761ae650dSJack F Vogel 		stats->mac_etype_free = LE16_TO_CPU(resp->mac_etype_free);
562861ae650dSJack F Vogel 		stats->etype_free = LE16_TO_CPU(resp->etype_free);
562961ae650dSJack F Vogel 	}
563061ae650dSJack F Vogel 
563161ae650dSJack F Vogel 	return status;
563261ae650dSJack F Vogel }
563361ae650dSJack F Vogel 
563461ae650dSJack F Vogel /**
5635223d846dSEric Joyner  * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
5636223d846dSEric Joyner  * @hw: pointer to the hw struct
5637223d846dSEric Joyner  * @seid: VSI seid to add ethertype filter from
5638223d846dSEric Joyner  **/
i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw * hw,u16 seid)5639223d846dSEric Joyner void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
5640223d846dSEric Joyner 						    u16 seid)
5641223d846dSEric Joyner {
5642ceebc2f3SEric Joyner #define I40E_FLOW_CONTROL_ETHTYPE 0x8808
5643223d846dSEric Joyner 	u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
5644223d846dSEric Joyner 		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
5645223d846dSEric Joyner 		   I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
5646223d846dSEric Joyner 	u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
5647223d846dSEric Joyner 	enum i40e_status_code status;
5648223d846dSEric Joyner 
5649223d846dSEric Joyner 	status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
5650223d846dSEric Joyner 						       seid, 0, TRUE, NULL,
5651223d846dSEric Joyner 						       NULL);
5652223d846dSEric Joyner 	if (status)
5653223d846dSEric Joyner 		DEBUGOUT("Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
5654223d846dSEric Joyner }
5655223d846dSEric Joyner 
5656223d846dSEric Joyner /**
56574294f337SSean Bruno  * i40e_fix_up_geneve_vni - adjust Geneve VNI for HW issue
56584294f337SSean Bruno  * @filters: list of cloud filters
56594294f337SSean Bruno  * @filter_count: length of list
56604294f337SSean Bruno  *
56614294f337SSean Bruno  * There's an issue in the device where the Geneve VNI layout needs
56624294f337SSean Bruno  * to be shifted 1 byte over from the VxLAN VNI
56634294f337SSean Bruno  **/
i40e_fix_up_geneve_vni(struct i40e_aqc_cloud_filters_element_data * filters,u8 filter_count)56644294f337SSean Bruno static void i40e_fix_up_geneve_vni(
5665b4a7ce06SEric Joyner 	struct i40e_aqc_cloud_filters_element_data *filters,
56664294f337SSean Bruno 	u8 filter_count)
56674294f337SSean Bruno {
5668b4a7ce06SEric Joyner 	struct i40e_aqc_cloud_filters_element_data *f = filters;
56694294f337SSean Bruno 	int i;
56704294f337SSean Bruno 
56714294f337SSean Bruno 	for (i = 0; i < filter_count; i++) {
56724294f337SSean Bruno 		u16 tnl_type;
56734294f337SSean Bruno 		u32 ti;
56744294f337SSean Bruno 
56754294f337SSean Bruno 		tnl_type = (LE16_TO_CPU(f[i].flags) &
56764294f337SSean Bruno 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
56774294f337SSean Bruno 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
56784294f337SSean Bruno 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
56794294f337SSean Bruno 			ti = LE32_TO_CPU(f[i].tenant_id);
56804294f337SSean Bruno 			f[i].tenant_id = CPU_TO_LE32(ti << 8);
56814294f337SSean Bruno 		}
56824294f337SSean Bruno 	}
56834294f337SSean Bruno }
56844294f337SSean Bruno 
56854294f337SSean Bruno /**
568661ae650dSJack F Vogel  * i40e_aq_add_cloud_filters
568761ae650dSJack F Vogel  * @hw: pointer to the hardware structure
568861ae650dSJack F Vogel  * @seid: VSI seid to add cloud filters from
568961ae650dSJack F Vogel  * @filters: Buffer which contains the filters to be added
569061ae650dSJack F Vogel  * @filter_count: number of filters contained in the buffer
569161ae650dSJack F Vogel  *
569261ae650dSJack F Vogel  * Set the cloud filters for a given VSI.  The contents of the
5693b4a7ce06SEric Joyner  * i40e_aqc_cloud_filters_element_data are filled
569461ae650dSJack F Vogel  * in by the caller of the function.
569561ae650dSJack F Vogel  *
569661ae650dSJack F Vogel  **/
i40e_aq_add_cloud_filters(struct i40e_hw * hw,u16 seid,struct i40e_aqc_cloud_filters_element_data * filters,u8 filter_count)569761ae650dSJack F Vogel enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw,
569861ae650dSJack F Vogel 	u16 seid,
5699b4a7ce06SEric Joyner 	struct i40e_aqc_cloud_filters_element_data *filters,
570061ae650dSJack F Vogel 	u8 filter_count)
570161ae650dSJack F Vogel {
570261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
570361ae650dSJack F Vogel 	struct i40e_aqc_add_remove_cloud_filters *cmd =
570461ae650dSJack F Vogel 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
570561ae650dSJack F Vogel 	enum i40e_status_code status;
57064294f337SSean Bruno 	u16 buff_len;
570761ae650dSJack F Vogel 
570861ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
570961ae650dSJack F Vogel 					  i40e_aqc_opc_add_cloud_filters);
571061ae650dSJack F Vogel 
5711f247dc25SJack F Vogel 	buff_len = filter_count * sizeof(*filters);
571261ae650dSJack F Vogel 	desc.datalen = CPU_TO_LE16(buff_len);
571361ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
571461ae650dSJack F Vogel 	cmd->num_filters = filter_count;
571561ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
571661ae650dSJack F Vogel 
57174294f337SSean Bruno 	i40e_fix_up_geneve_vni(filters, filter_count);
57184294f337SSean Bruno 
571961ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
572061ae650dSJack F Vogel 
572161ae650dSJack F Vogel 	return status;
572261ae650dSJack F Vogel }
572361ae650dSJack F Vogel 
572461ae650dSJack F Vogel /**
5725b4a7ce06SEric Joyner  * i40e_aq_add_cloud_filters_bb
5726b4a7ce06SEric Joyner  * @hw: pointer to the hardware structure
5727b4a7ce06SEric Joyner  * @seid: VSI seid to add cloud filters from
5728b4a7ce06SEric Joyner  * @filters: Buffer which contains the filters in big buffer to be added
5729b4a7ce06SEric Joyner  * @filter_count: number of filters contained in the buffer
5730b4a7ce06SEric Joyner  *
5731b4a7ce06SEric Joyner  * Set the cloud filters for a given VSI.  The contents of the
5732b4a7ce06SEric Joyner  * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5733b4a7ce06SEric Joyner  * the function.
5734b4a7ce06SEric Joyner  *
5735b4a7ce06SEric Joyner  **/
5736b4a7ce06SEric Joyner 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)5737b4a7ce06SEric Joyner i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5738b4a7ce06SEric Joyner 			     struct i40e_aqc_cloud_filters_element_bb *filters,
5739b4a7ce06SEric Joyner 			     u8 filter_count)
5740b4a7ce06SEric Joyner {
5741b4a7ce06SEric Joyner 	struct i40e_aq_desc desc;
5742b4a7ce06SEric Joyner 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5743b4a7ce06SEric Joyner 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5744b4a7ce06SEric Joyner 	enum i40e_status_code status;
5745b4a7ce06SEric Joyner 	u16 buff_len;
5746b4a7ce06SEric Joyner 	int i;
5747b4a7ce06SEric Joyner 
5748b4a7ce06SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
5749b4a7ce06SEric Joyner 					  i40e_aqc_opc_add_cloud_filters);
5750b4a7ce06SEric Joyner 
5751b4a7ce06SEric Joyner 	buff_len = filter_count * sizeof(*filters);
5752b4a7ce06SEric Joyner 	desc.datalen = CPU_TO_LE16(buff_len);
5753b4a7ce06SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5754b4a7ce06SEric Joyner 	cmd->num_filters = filter_count;
5755b4a7ce06SEric Joyner 	cmd->seid = CPU_TO_LE16(seid);
5756b4a7ce06SEric Joyner 	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5757b4a7ce06SEric Joyner 
5758b4a7ce06SEric Joyner 	for (i = 0; i < filter_count; i++) {
5759b4a7ce06SEric Joyner 		u16 tnl_type;
5760b4a7ce06SEric Joyner 		u32 ti;
5761b4a7ce06SEric Joyner 
5762b4a7ce06SEric Joyner 		tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5763b4a7ce06SEric Joyner 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5764b4a7ce06SEric Joyner 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5765b4a7ce06SEric Joyner 
5766b4a7ce06SEric Joyner 		/* Due to hardware eccentricities, the VNI for Geneve is shifted
5767b4a7ce06SEric Joyner 		 * one more byte further than normally used for Tenant ID in
5768b4a7ce06SEric Joyner 		 * other tunnel types.
5769b4a7ce06SEric Joyner 		 */
5770b4a7ce06SEric Joyner 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5771b4a7ce06SEric Joyner 			ti = LE32_TO_CPU(filters[i].element.tenant_id);
5772b4a7ce06SEric Joyner 			filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5773b4a7ce06SEric Joyner 		}
5774b4a7ce06SEric Joyner 	}
5775b4a7ce06SEric Joyner 
5776b4a7ce06SEric Joyner 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5777b4a7ce06SEric Joyner 
5778b4a7ce06SEric Joyner 	return status;
5779b4a7ce06SEric Joyner }
5780b4a7ce06SEric Joyner 
5781b4a7ce06SEric Joyner /**
5782b4a7ce06SEric Joyner  * i40e_aq_rem_cloud_filters
578361ae650dSJack F Vogel  * @hw: pointer to the hardware structure
578461ae650dSJack F Vogel  * @seid: VSI seid to remove cloud filters from
578561ae650dSJack F Vogel  * @filters: Buffer which contains the filters to be removed
578661ae650dSJack F Vogel  * @filter_count: number of filters contained in the buffer
578761ae650dSJack F Vogel  *
578861ae650dSJack F Vogel  * Remove the cloud filters for a given VSI.  The contents of the
5789b4a7ce06SEric Joyner  * i40e_aqc_cloud_filters_element_data are filled in by the caller
5790b4a7ce06SEric Joyner  * of the function.
579161ae650dSJack F Vogel  *
579261ae650dSJack F Vogel  **/
5793b4a7ce06SEric Joyner 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)5794b4a7ce06SEric Joyner i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
5795b4a7ce06SEric Joyner 			  struct i40e_aqc_cloud_filters_element_data *filters,
579661ae650dSJack F Vogel 			  u8 filter_count)
579761ae650dSJack F Vogel {
579861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
579961ae650dSJack F Vogel 	struct i40e_aqc_add_remove_cloud_filters *cmd =
580061ae650dSJack F Vogel 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
580161ae650dSJack F Vogel 	enum i40e_status_code status;
580261ae650dSJack F Vogel 	u16 buff_len;
580361ae650dSJack F Vogel 
580461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
580561ae650dSJack F Vogel 					  i40e_aqc_opc_remove_cloud_filters);
580661ae650dSJack F Vogel 
5807f247dc25SJack F Vogel 	buff_len = filter_count * sizeof(*filters);
580861ae650dSJack F Vogel 	desc.datalen = CPU_TO_LE16(buff_len);
580961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
581061ae650dSJack F Vogel 	cmd->num_filters = filter_count;
581161ae650dSJack F Vogel 	cmd->seid = CPU_TO_LE16(seid);
581261ae650dSJack F Vogel 
58134294f337SSean Bruno 	i40e_fix_up_geneve_vni(filters, filter_count);
58144294f337SSean Bruno 
581561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
581661ae650dSJack F Vogel 
581761ae650dSJack F Vogel 	return status;
581861ae650dSJack F Vogel }
581961ae650dSJack F Vogel 
582061ae650dSJack F Vogel /**
5821b4a7ce06SEric Joyner  * i40e_aq_rem_cloud_filters_bb
5822b4a7ce06SEric Joyner  * @hw: pointer to the hardware structure
5823b4a7ce06SEric Joyner  * @seid: VSI seid to remove cloud filters from
5824b4a7ce06SEric Joyner  * @filters: Buffer which contains the filters in big buffer to be removed
5825b4a7ce06SEric Joyner  * @filter_count: number of filters contained in the buffer
5826b4a7ce06SEric Joyner  *
5827b4a7ce06SEric Joyner  * Remove the big buffer cloud filters for a given VSI.  The contents of the
5828b4a7ce06SEric Joyner  * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the
5829b4a7ce06SEric Joyner  * function.
5830b4a7ce06SEric Joyner  *
5831b4a7ce06SEric Joyner  **/
5832b4a7ce06SEric Joyner 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)5833b4a7ce06SEric Joyner i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
5834b4a7ce06SEric Joyner 			     struct i40e_aqc_cloud_filters_element_bb *filters,
5835b4a7ce06SEric Joyner 			     u8 filter_count)
5836b4a7ce06SEric Joyner {
5837b4a7ce06SEric Joyner 	struct i40e_aq_desc desc;
5838b4a7ce06SEric Joyner 	struct i40e_aqc_add_remove_cloud_filters *cmd =
5839b4a7ce06SEric Joyner 	(struct i40e_aqc_add_remove_cloud_filters *)&desc.params.raw;
5840b4a7ce06SEric Joyner 	enum i40e_status_code status;
5841b4a7ce06SEric Joyner 	u16 buff_len;
5842b4a7ce06SEric Joyner 	int i;
5843b4a7ce06SEric Joyner 
5844b4a7ce06SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
5845b4a7ce06SEric Joyner 					  i40e_aqc_opc_remove_cloud_filters);
5846b4a7ce06SEric Joyner 
5847b4a7ce06SEric Joyner 	buff_len = filter_count * sizeof(*filters);
5848b4a7ce06SEric Joyner 	desc.datalen = CPU_TO_LE16(buff_len);
5849b4a7ce06SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5850b4a7ce06SEric Joyner 	cmd->num_filters = filter_count;
5851b4a7ce06SEric Joyner 	cmd->seid = CPU_TO_LE16(seid);
5852b4a7ce06SEric Joyner 	cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB;
5853b4a7ce06SEric Joyner 
5854b4a7ce06SEric Joyner 	for (i = 0; i < filter_count; i++) {
5855b4a7ce06SEric Joyner 		u16 tnl_type;
5856b4a7ce06SEric Joyner 		u32 ti;
5857b4a7ce06SEric Joyner 
5858b4a7ce06SEric Joyner 		tnl_type = (LE16_TO_CPU(filters[i].element.flags) &
5859b4a7ce06SEric Joyner 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >>
5860b4a7ce06SEric Joyner 			   I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT;
5861b4a7ce06SEric Joyner 
5862b4a7ce06SEric Joyner 		/* Due to hardware eccentricities, the VNI for Geneve is shifted
5863b4a7ce06SEric Joyner 		 * one more byte further than normally used for Tenant ID in
5864b4a7ce06SEric Joyner 		 * other tunnel types.
5865b4a7ce06SEric Joyner 		 */
5866b4a7ce06SEric Joyner 		if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) {
5867b4a7ce06SEric Joyner 			ti = LE32_TO_CPU(filters[i].element.tenant_id);
5868b4a7ce06SEric Joyner 			filters[i].element.tenant_id = CPU_TO_LE32(ti << 8);
5869b4a7ce06SEric Joyner 		}
5870b4a7ce06SEric Joyner 	}
5871b4a7ce06SEric Joyner 
5872b4a7ce06SEric Joyner 	status = i40e_asq_send_command(hw, &desc, filters, buff_len, NULL);
5873b4a7ce06SEric Joyner 
5874b4a7ce06SEric Joyner 	return status;
5875b4a7ce06SEric Joyner }
5876b4a7ce06SEric Joyner 
5877b4a7ce06SEric Joyner /**
5878b4a7ce06SEric Joyner  * i40e_aq_replace_cloud_filters - Replace cloud filter command
5879b4a7ce06SEric Joyner  * @hw: pointer to the hw struct
5880b4a7ce06SEric Joyner  * @filters: pointer to the i40e_aqc_replace_cloud_filter_cmd struct
5881b4a7ce06SEric Joyner  * @cmd_buf: pointer to the i40e_aqc_replace_cloud_filter_cmd_buf struct
5882b4a7ce06SEric Joyner  *
5883b4a7ce06SEric Joyner  **/
5884b4a7ce06SEric Joyner enum
i40e_aq_replace_cloud_filters(struct i40e_hw * hw,struct i40e_aqc_replace_cloud_filters_cmd * filters,struct i40e_aqc_replace_cloud_filters_cmd_buf * cmd_buf)5885b4a7ce06SEric Joyner i40e_status_code i40e_aq_replace_cloud_filters(struct i40e_hw *hw,
5886b4a7ce06SEric Joyner 	struct i40e_aqc_replace_cloud_filters_cmd *filters,
5887b4a7ce06SEric Joyner 	struct i40e_aqc_replace_cloud_filters_cmd_buf *cmd_buf)
5888b4a7ce06SEric Joyner {
5889b4a7ce06SEric Joyner 	struct i40e_aq_desc desc;
5890b4a7ce06SEric Joyner 	struct i40e_aqc_replace_cloud_filters_cmd *cmd =
5891b4a7ce06SEric Joyner 		(struct i40e_aqc_replace_cloud_filters_cmd *)&desc.params.raw;
5892b4a7ce06SEric Joyner 	enum i40e_status_code status = I40E_SUCCESS;
5893b4a7ce06SEric Joyner 	int i = 0;
5894b4a7ce06SEric Joyner 
5895b4a7ce06SEric Joyner 	/* X722 doesn't support this command */
5896b4a7ce06SEric Joyner 	if (hw->mac.type == I40E_MAC_X722)
5897b4a7ce06SEric Joyner 		return I40E_ERR_DEVICE_NOT_SUPPORTED;
5898b4a7ce06SEric Joyner 
5899b4a7ce06SEric Joyner 	/* need FW version greater than 6.00 */
5900b4a7ce06SEric Joyner 	if (hw->aq.fw_maj_ver < 6)
5901b4a7ce06SEric Joyner 		return I40E_NOT_SUPPORTED;
5902b4a7ce06SEric Joyner 
5903b4a7ce06SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
5904b4a7ce06SEric Joyner 					  i40e_aqc_opc_replace_cloud_filters);
5905b4a7ce06SEric Joyner 
5906b4a7ce06SEric Joyner 	desc.datalen = CPU_TO_LE16(32);
5907b4a7ce06SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
5908b4a7ce06SEric Joyner 	cmd->old_filter_type = filters->old_filter_type;
5909b4a7ce06SEric Joyner 	cmd->new_filter_type = filters->new_filter_type;
5910b4a7ce06SEric Joyner 	cmd->valid_flags = filters->valid_flags;
5911b4a7ce06SEric Joyner 	cmd->tr_bit = filters->tr_bit;
5912b4a7ce06SEric Joyner 	cmd->tr_bit2 = filters->tr_bit2;
5913b4a7ce06SEric Joyner 
5914b4a7ce06SEric Joyner 	status = i40e_asq_send_command(hw, &desc, cmd_buf,
5915b4a7ce06SEric Joyner 		sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf),  NULL);
5916b4a7ce06SEric Joyner 
5917b4a7ce06SEric Joyner 	/* for get cloud filters command */
5918b4a7ce06SEric Joyner 	for (i = 0; i < 32; i += 4) {
5919b4a7ce06SEric Joyner 		cmd_buf->filters[i / 4].filter_type = cmd_buf->data[i];
5920b4a7ce06SEric Joyner 		cmd_buf->filters[i / 4].input[0] = cmd_buf->data[i + 1];
5921b4a7ce06SEric Joyner 		cmd_buf->filters[i / 4].input[1] = cmd_buf->data[i + 2];
5922b4a7ce06SEric Joyner 		cmd_buf->filters[i / 4].input[2] = cmd_buf->data[i + 3];
5923b4a7ce06SEric Joyner 	}
5924b4a7ce06SEric Joyner 
5925b4a7ce06SEric Joyner 	return status;
5926b4a7ce06SEric Joyner }
5927b4a7ce06SEric Joyner 
5928b4a7ce06SEric Joyner 
5929b4a7ce06SEric Joyner /**
593061ae650dSJack F Vogel  * i40e_aq_alternate_write
593161ae650dSJack F Vogel  * @hw: pointer to the hardware structure
593261ae650dSJack F Vogel  * @reg_addr0: address of first dword to be read
593361ae650dSJack F Vogel  * @reg_val0: value to be written under 'reg_addr0'
593461ae650dSJack F Vogel  * @reg_addr1: address of second dword to be read
593561ae650dSJack F Vogel  * @reg_val1: value to be written under 'reg_addr1'
593661ae650dSJack F Vogel  *
593761ae650dSJack F Vogel  * Write one or two dwords to alternate structure. Fields are indicated
593861ae650dSJack F Vogel  * by 'reg_addr0' and 'reg_addr1' register numbers.
593961ae650dSJack F Vogel  *
594061ae650dSJack F Vogel  **/
i40e_aq_alternate_write(struct i40e_hw * hw,u32 reg_addr0,u32 reg_val0,u32 reg_addr1,u32 reg_val1)594161ae650dSJack F Vogel enum i40e_status_code i40e_aq_alternate_write(struct i40e_hw *hw,
594261ae650dSJack F Vogel 				u32 reg_addr0, u32 reg_val0,
594361ae650dSJack F Vogel 				u32 reg_addr1, u32 reg_val1)
594461ae650dSJack F Vogel {
594561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
594661ae650dSJack F Vogel 	struct i40e_aqc_alternate_write *cmd_resp =
594761ae650dSJack F Vogel 		(struct i40e_aqc_alternate_write *)&desc.params.raw;
594861ae650dSJack F Vogel 	enum i40e_status_code status;
594961ae650dSJack F Vogel 
595061ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_write);
595161ae650dSJack F Vogel 	cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
595261ae650dSJack F Vogel 	cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
595361ae650dSJack F Vogel 	cmd_resp->data0 = CPU_TO_LE32(reg_val0);
595461ae650dSJack F Vogel 	cmd_resp->data1 = CPU_TO_LE32(reg_val1);
595561ae650dSJack F Vogel 
595661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
595761ae650dSJack F Vogel 
595861ae650dSJack F Vogel 	return status;
595961ae650dSJack F Vogel }
596061ae650dSJack F Vogel 
596161ae650dSJack F Vogel /**
596261ae650dSJack F Vogel  * i40e_aq_alternate_write_indirect
596361ae650dSJack F Vogel  * @hw: pointer to the hardware structure
596461ae650dSJack F Vogel  * @addr: address of a first register to be modified
596561ae650dSJack F Vogel  * @dw_count: number of alternate structure fields to write
596661ae650dSJack F Vogel  * @buffer: pointer to the command buffer
596761ae650dSJack F Vogel  *
596861ae650dSJack F Vogel  * Write 'dw_count' dwords from 'buffer' to alternate structure
596961ae650dSJack F Vogel  * starting at 'addr'.
597061ae650dSJack F Vogel  *
597161ae650dSJack F Vogel  **/
i40e_aq_alternate_write_indirect(struct i40e_hw * hw,u32 addr,u32 dw_count,void * buffer)597261ae650dSJack F Vogel enum i40e_status_code i40e_aq_alternate_write_indirect(struct i40e_hw *hw,
597361ae650dSJack F Vogel 				u32 addr, u32 dw_count, void *buffer)
597461ae650dSJack F Vogel {
597561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
597661ae650dSJack F Vogel 	struct i40e_aqc_alternate_ind_write *cmd_resp =
597761ae650dSJack F Vogel 		(struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
597861ae650dSJack F Vogel 	enum i40e_status_code status;
597961ae650dSJack F Vogel 
598061ae650dSJack F Vogel 	if (buffer == NULL)
598161ae650dSJack F Vogel 		return I40E_ERR_PARAM;
598261ae650dSJack F Vogel 
598361ae650dSJack F Vogel 	/* Indirect command */
598461ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
598561ae650dSJack F Vogel 					 i40e_aqc_opc_alternate_write_indirect);
598661ae650dSJack F Vogel 
598761ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
598861ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
598961ae650dSJack F Vogel 	if (dw_count > (I40E_AQ_LARGE_BUF/4))
599061ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
599161ae650dSJack F Vogel 
599261ae650dSJack F Vogel 	cmd_resp->address = CPU_TO_LE32(addr);
599361ae650dSJack F Vogel 	cmd_resp->length = CPU_TO_LE32(dw_count);
599461ae650dSJack F Vogel 
599561ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buffer,
599661ae650dSJack F Vogel 				       I40E_LO_DWORD(4*dw_count), NULL);
599761ae650dSJack F Vogel 
599861ae650dSJack F Vogel 	return status;
599961ae650dSJack F Vogel }
600061ae650dSJack F Vogel 
600161ae650dSJack F Vogel /**
600261ae650dSJack F Vogel  * i40e_aq_alternate_read
600361ae650dSJack F Vogel  * @hw: pointer to the hardware structure
600461ae650dSJack F Vogel  * @reg_addr0: address of first dword to be read
600561ae650dSJack F Vogel  * @reg_val0: pointer for data read from 'reg_addr0'
600661ae650dSJack F Vogel  * @reg_addr1: address of second dword to be read
600761ae650dSJack F Vogel  * @reg_val1: pointer for data read from 'reg_addr1'
600861ae650dSJack F Vogel  *
600961ae650dSJack F Vogel  * Read one or two dwords from alternate structure. Fields are indicated
601061ae650dSJack F Vogel  * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
601161ae650dSJack F Vogel  * is not passed then only register at 'reg_addr0' is read.
601261ae650dSJack F Vogel  *
601361ae650dSJack F Vogel  **/
i40e_aq_alternate_read(struct i40e_hw * hw,u32 reg_addr0,u32 * reg_val0,u32 reg_addr1,u32 * reg_val1)601461ae650dSJack F Vogel enum i40e_status_code i40e_aq_alternate_read(struct i40e_hw *hw,
601561ae650dSJack F Vogel 				u32 reg_addr0, u32 *reg_val0,
601661ae650dSJack F Vogel 				u32 reg_addr1, u32 *reg_val1)
601761ae650dSJack F Vogel {
601861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
601961ae650dSJack F Vogel 	struct i40e_aqc_alternate_write *cmd_resp =
602061ae650dSJack F Vogel 		(struct i40e_aqc_alternate_write *)&desc.params.raw;
602161ae650dSJack F Vogel 	enum i40e_status_code status;
602261ae650dSJack F Vogel 
602361ae650dSJack F Vogel 	if (reg_val0 == NULL)
602461ae650dSJack F Vogel 		return I40E_ERR_PARAM;
602561ae650dSJack F Vogel 
602661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
602761ae650dSJack F Vogel 	cmd_resp->address0 = CPU_TO_LE32(reg_addr0);
602861ae650dSJack F Vogel 	cmd_resp->address1 = CPU_TO_LE32(reg_addr1);
602961ae650dSJack F Vogel 
603061ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
603161ae650dSJack F Vogel 
603261ae650dSJack F Vogel 	if (status == I40E_SUCCESS) {
603361ae650dSJack F Vogel 		*reg_val0 = LE32_TO_CPU(cmd_resp->data0);
603461ae650dSJack F Vogel 
603561ae650dSJack F Vogel 		if (reg_val1 != NULL)
603661ae650dSJack F Vogel 			*reg_val1 = LE32_TO_CPU(cmd_resp->data1);
603761ae650dSJack F Vogel 	}
603861ae650dSJack F Vogel 
603961ae650dSJack F Vogel 	return status;
604061ae650dSJack F Vogel }
604161ae650dSJack F Vogel 
604261ae650dSJack F Vogel /**
604361ae650dSJack F Vogel  * i40e_aq_alternate_read_indirect
604461ae650dSJack F Vogel  * @hw: pointer to the hardware structure
604561ae650dSJack F Vogel  * @addr: address of the alternate structure field
604661ae650dSJack F Vogel  * @dw_count: number of alternate structure fields to read
604761ae650dSJack F Vogel  * @buffer: pointer to the command buffer
604861ae650dSJack F Vogel  *
604961ae650dSJack F Vogel  * Read 'dw_count' dwords from alternate structure starting at 'addr' and
605061ae650dSJack F Vogel  * place them in 'buffer'. The buffer should be allocated by caller.
605161ae650dSJack F Vogel  *
605261ae650dSJack F Vogel  **/
i40e_aq_alternate_read_indirect(struct i40e_hw * hw,u32 addr,u32 dw_count,void * buffer)605361ae650dSJack F Vogel enum i40e_status_code i40e_aq_alternate_read_indirect(struct i40e_hw *hw,
605461ae650dSJack F Vogel 				u32 addr, u32 dw_count, void *buffer)
605561ae650dSJack F Vogel {
605661ae650dSJack F Vogel 	struct i40e_aq_desc desc;
605761ae650dSJack F Vogel 	struct i40e_aqc_alternate_ind_write *cmd_resp =
605861ae650dSJack F Vogel 		(struct i40e_aqc_alternate_ind_write *)&desc.params.raw;
605961ae650dSJack F Vogel 	enum i40e_status_code status;
606061ae650dSJack F Vogel 
606161ae650dSJack F Vogel 	if (buffer == NULL)
606261ae650dSJack F Vogel 		return I40E_ERR_PARAM;
606361ae650dSJack F Vogel 
606461ae650dSJack F Vogel 	/* Indirect command */
606561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
606661ae650dSJack F Vogel 		i40e_aqc_opc_alternate_read_indirect);
606761ae650dSJack F Vogel 
606861ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_RD);
606961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16(I40E_AQ_FLAG_BUF);
607061ae650dSJack F Vogel 	if (dw_count > (I40E_AQ_LARGE_BUF/4))
607161ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
607261ae650dSJack F Vogel 
607361ae650dSJack F Vogel 	cmd_resp->address = CPU_TO_LE32(addr);
607461ae650dSJack F Vogel 	cmd_resp->length = CPU_TO_LE32(dw_count);
607561ae650dSJack F Vogel 
607661ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buffer,
607761ae650dSJack F Vogel 				       I40E_LO_DWORD(4*dw_count), NULL);
607861ae650dSJack F Vogel 
607961ae650dSJack F Vogel 	return status;
608061ae650dSJack F Vogel }
608161ae650dSJack F Vogel 
608261ae650dSJack F Vogel /**
608361ae650dSJack F Vogel  *  i40e_aq_alternate_clear
608461ae650dSJack F Vogel  *  @hw: pointer to the HW structure.
608561ae650dSJack F Vogel  *
608661ae650dSJack F Vogel  *  Clear the alternate structures of the port from which the function
608761ae650dSJack F Vogel  *  is called.
608861ae650dSJack F Vogel  *
608961ae650dSJack F Vogel  **/
i40e_aq_alternate_clear(struct i40e_hw * hw)609061ae650dSJack F Vogel enum i40e_status_code i40e_aq_alternate_clear(struct i40e_hw *hw)
609161ae650dSJack F Vogel {
609261ae650dSJack F Vogel 	struct i40e_aq_desc desc;
609361ae650dSJack F Vogel 	enum i40e_status_code status;
609461ae650dSJack F Vogel 
609561ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
609661ae650dSJack F Vogel 					  i40e_aqc_opc_alternate_clear_port);
609761ae650dSJack F Vogel 
609861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
609961ae650dSJack F Vogel 
610061ae650dSJack F Vogel 	return status;
610161ae650dSJack F Vogel }
610261ae650dSJack F Vogel 
610361ae650dSJack F Vogel /**
610461ae650dSJack F Vogel  *  i40e_aq_alternate_write_done
610561ae650dSJack F Vogel  *  @hw: pointer to the HW structure.
610661ae650dSJack F Vogel  *  @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS
610761ae650dSJack F Vogel  *  @reset_needed: indicates the SW should trigger GLOBAL reset
610861ae650dSJack F Vogel  *
610961ae650dSJack F Vogel  *  Indicates to the FW that alternate structures have been changed.
611061ae650dSJack F Vogel  *
611161ae650dSJack F Vogel  **/
i40e_aq_alternate_write_done(struct i40e_hw * hw,u8 bios_mode,bool * reset_needed)611261ae650dSJack F Vogel enum i40e_status_code i40e_aq_alternate_write_done(struct i40e_hw *hw,
611361ae650dSJack F Vogel 		u8 bios_mode, bool *reset_needed)
611461ae650dSJack F Vogel {
611561ae650dSJack F Vogel 	struct i40e_aq_desc desc;
611661ae650dSJack F Vogel 	struct i40e_aqc_alternate_write_done *cmd =
611761ae650dSJack F Vogel 		(struct i40e_aqc_alternate_write_done *)&desc.params.raw;
611861ae650dSJack F Vogel 	enum i40e_status_code status;
611961ae650dSJack F Vogel 
612061ae650dSJack F Vogel 	if (reset_needed == NULL)
612161ae650dSJack F Vogel 		return I40E_ERR_PARAM;
612261ae650dSJack F Vogel 
612361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
612461ae650dSJack F Vogel 					  i40e_aqc_opc_alternate_write_done);
612561ae650dSJack F Vogel 
612661ae650dSJack F Vogel 	cmd->cmd_flags = CPU_TO_LE16(bios_mode);
612761ae650dSJack F Vogel 
612861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
6129f247dc25SJack F Vogel 	if (!status && reset_needed)
613061ae650dSJack F Vogel 		*reset_needed = ((LE16_TO_CPU(cmd->cmd_flags) &
613161ae650dSJack F Vogel 				 I40E_AQ_ALTERNATE_RESET_NEEDED) != 0);
613261ae650dSJack F Vogel 
613361ae650dSJack F Vogel 	return status;
613461ae650dSJack F Vogel }
613561ae650dSJack F Vogel 
613661ae650dSJack F Vogel /**
613761ae650dSJack F Vogel  *  i40e_aq_set_oem_mode
613861ae650dSJack F Vogel  *  @hw: pointer to the HW structure.
613961ae650dSJack F Vogel  *  @oem_mode: the OEM mode to be used
614061ae650dSJack F Vogel  *
614161ae650dSJack F Vogel  *  Sets the device to a specific operating mode. Currently the only supported
614261ae650dSJack F Vogel  *  mode is no_clp, which causes FW to refrain from using Alternate RAM.
614361ae650dSJack F Vogel  *
614461ae650dSJack F Vogel  **/
i40e_aq_set_oem_mode(struct i40e_hw * hw,u8 oem_mode)614561ae650dSJack F Vogel enum i40e_status_code i40e_aq_set_oem_mode(struct i40e_hw *hw,
614661ae650dSJack F Vogel 		u8 oem_mode)
614761ae650dSJack F Vogel {
614861ae650dSJack F Vogel 	struct i40e_aq_desc desc;
614961ae650dSJack F Vogel 	struct i40e_aqc_alternate_write_done *cmd =
615061ae650dSJack F Vogel 		(struct i40e_aqc_alternate_write_done *)&desc.params.raw;
615161ae650dSJack F Vogel 	enum i40e_status_code status;
615261ae650dSJack F Vogel 
615361ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
615461ae650dSJack F Vogel 					  i40e_aqc_opc_alternate_set_mode);
615561ae650dSJack F Vogel 
615661ae650dSJack F Vogel 	cmd->cmd_flags = CPU_TO_LE16(oem_mode);
615761ae650dSJack F Vogel 
615861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
615961ae650dSJack F Vogel 
616061ae650dSJack F Vogel 	return status;
616161ae650dSJack F Vogel }
616261ae650dSJack F Vogel 
616361ae650dSJack F Vogel /**
616461ae650dSJack F Vogel  * i40e_aq_resume_port_tx
616561ae650dSJack F Vogel  * @hw: pointer to the hardware structure
616661ae650dSJack F Vogel  * @cmd_details: pointer to command details structure or NULL
616761ae650dSJack F Vogel  *
616861ae650dSJack F Vogel  * Resume port's Tx traffic
616961ae650dSJack F Vogel  **/
i40e_aq_resume_port_tx(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)617061ae650dSJack F Vogel enum i40e_status_code i40e_aq_resume_port_tx(struct i40e_hw *hw,
617161ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
617261ae650dSJack F Vogel {
617361ae650dSJack F Vogel 	struct i40e_aq_desc desc;
617461ae650dSJack F Vogel 	enum i40e_status_code status;
617561ae650dSJack F Vogel 
617661ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
617761ae650dSJack F Vogel 
617861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
617961ae650dSJack F Vogel 
618061ae650dSJack F Vogel 	return status;
618161ae650dSJack F Vogel }
618261ae650dSJack F Vogel 
618361ae650dSJack F Vogel /**
618461ae650dSJack F Vogel  * i40e_set_pci_config_data - store PCI bus info
618561ae650dSJack F Vogel  * @hw: pointer to hardware structure
618661ae650dSJack F Vogel  * @link_status: the link status word from PCI config space
618761ae650dSJack F Vogel  *
618861ae650dSJack F Vogel  * Stores the PCI bus info (speed, width, type) within the i40e_hw structure
618961ae650dSJack F Vogel  **/
i40e_set_pci_config_data(struct i40e_hw * hw,u16 link_status)619061ae650dSJack F Vogel void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
619161ae650dSJack F Vogel {
619261ae650dSJack F Vogel 	hw->bus.type = i40e_bus_type_pci_express;
619361ae650dSJack F Vogel 
619461ae650dSJack F Vogel 	switch (link_status & I40E_PCI_LINK_WIDTH) {
619561ae650dSJack F Vogel 	case I40E_PCI_LINK_WIDTH_1:
619661ae650dSJack F Vogel 		hw->bus.width = i40e_bus_width_pcie_x1;
619761ae650dSJack F Vogel 		break;
619861ae650dSJack F Vogel 	case I40E_PCI_LINK_WIDTH_2:
619961ae650dSJack F Vogel 		hw->bus.width = i40e_bus_width_pcie_x2;
620061ae650dSJack F Vogel 		break;
620161ae650dSJack F Vogel 	case I40E_PCI_LINK_WIDTH_4:
620261ae650dSJack F Vogel 		hw->bus.width = i40e_bus_width_pcie_x4;
620361ae650dSJack F Vogel 		break;
620461ae650dSJack F Vogel 	case I40E_PCI_LINK_WIDTH_8:
620561ae650dSJack F Vogel 		hw->bus.width = i40e_bus_width_pcie_x8;
620661ae650dSJack F Vogel 		break;
620761ae650dSJack F Vogel 	default:
620861ae650dSJack F Vogel 		hw->bus.width = i40e_bus_width_unknown;
620961ae650dSJack F Vogel 		break;
621061ae650dSJack F Vogel 	}
621161ae650dSJack F Vogel 
621261ae650dSJack F Vogel 	switch (link_status & I40E_PCI_LINK_SPEED) {
621361ae650dSJack F Vogel 	case I40E_PCI_LINK_SPEED_2500:
621461ae650dSJack F Vogel 		hw->bus.speed = i40e_bus_speed_2500;
621561ae650dSJack F Vogel 		break;
621661ae650dSJack F Vogel 	case I40E_PCI_LINK_SPEED_5000:
621761ae650dSJack F Vogel 		hw->bus.speed = i40e_bus_speed_5000;
621861ae650dSJack F Vogel 		break;
621961ae650dSJack F Vogel 	case I40E_PCI_LINK_SPEED_8000:
622061ae650dSJack F Vogel 		hw->bus.speed = i40e_bus_speed_8000;
622161ae650dSJack F Vogel 		break;
622261ae650dSJack F Vogel 	default:
622361ae650dSJack F Vogel 		hw->bus.speed = i40e_bus_speed_unknown;
622461ae650dSJack F Vogel 		break;
622561ae650dSJack F Vogel 	}
622661ae650dSJack F Vogel }
622761ae650dSJack F Vogel 
622861ae650dSJack F Vogel /**
6229be771cdaSJack F Vogel  * i40e_aq_debug_dump
6230be771cdaSJack F Vogel  * @hw: pointer to the hardware structure
6231be771cdaSJack F Vogel  * @cluster_id: specific cluster to dump
6232be771cdaSJack F Vogel  * @table_id: table id within cluster
6233be771cdaSJack F Vogel  * @start_index: index of line in the block to read
6234be771cdaSJack F Vogel  * @buff_size: dump buffer size
6235be771cdaSJack F Vogel  * @buff: dump buffer
6236be771cdaSJack F Vogel  * @ret_buff_size: actual buffer size returned
6237be771cdaSJack F Vogel  * @ret_next_table: next block to read
6238be771cdaSJack F Vogel  * @ret_next_index: next index to read
6239ceebc2f3SEric Joyner  * @cmd_details: pointer to command details structure or NULL
6240be771cdaSJack F Vogel  *
6241be771cdaSJack F Vogel  * Dump internal FW/HW data for debug purposes.
6242be771cdaSJack F Vogel  *
6243be771cdaSJack F Vogel  **/
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)6244be771cdaSJack F Vogel enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
6245be771cdaSJack F Vogel 				u8 table_id, u32 start_index, u16 buff_size,
6246be771cdaSJack F Vogel 				void *buff, u16 *ret_buff_size,
6247be771cdaSJack F Vogel 				u8 *ret_next_table, u32 *ret_next_index,
6248be771cdaSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
6249be771cdaSJack F Vogel {
6250be771cdaSJack F Vogel 	struct i40e_aq_desc desc;
6251be771cdaSJack F Vogel 	struct i40e_aqc_debug_dump_internals *cmd =
6252be771cdaSJack F Vogel 		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6253be771cdaSJack F Vogel 	struct i40e_aqc_debug_dump_internals *resp =
6254be771cdaSJack F Vogel 		(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
6255be771cdaSJack F Vogel 	enum i40e_status_code status;
6256be771cdaSJack F Vogel 
6257be771cdaSJack F Vogel 	if (buff_size == 0 || !buff)
6258be771cdaSJack F Vogel 		return I40E_ERR_PARAM;
6259be771cdaSJack F Vogel 
6260be771cdaSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
6261be771cdaSJack F Vogel 					  i40e_aqc_opc_debug_dump_internals);
6262be771cdaSJack F Vogel 	/* Indirect Command */
6263be771cdaSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
6264be771cdaSJack F Vogel 	if (buff_size > I40E_AQ_LARGE_BUF)
6265be771cdaSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
6266be771cdaSJack F Vogel 
6267be771cdaSJack F Vogel 	cmd->cluster_id = cluster_id;
6268be771cdaSJack F Vogel 	cmd->table_id = table_id;
6269be771cdaSJack F Vogel 	cmd->idx = CPU_TO_LE32(start_index);
6270be771cdaSJack F Vogel 
6271be771cdaSJack F Vogel 	desc.datalen = CPU_TO_LE16(buff_size);
6272be771cdaSJack F Vogel 
6273be771cdaSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
6274be771cdaSJack F Vogel 	if (!status) {
6275be771cdaSJack F Vogel 		if (ret_buff_size != NULL)
6276be771cdaSJack F Vogel 			*ret_buff_size = LE16_TO_CPU(desc.datalen);
6277be771cdaSJack F Vogel 		if (ret_next_table != NULL)
6278be771cdaSJack F Vogel 			*ret_next_table = resp->table_id;
6279be771cdaSJack F Vogel 		if (ret_next_index != NULL)
6280be771cdaSJack F Vogel 			*ret_next_index = LE32_TO_CPU(resp->idx);
6281be771cdaSJack F Vogel 	}
6282be771cdaSJack F Vogel 
6283be771cdaSJack F Vogel 	return status;
6284be771cdaSJack F Vogel }
6285be771cdaSJack F Vogel 
62862984a8ddSEric Joyner 
62872984a8ddSEric Joyner /**
62882984a8ddSEric Joyner  * i40e_enable_eee
62892984a8ddSEric Joyner  * @hw: pointer to the hardware structure
62902984a8ddSEric Joyner  * @enable: state of Energy Efficient Ethernet mode to be set
62912984a8ddSEric Joyner  *
62922984a8ddSEric Joyner  * Enables or disables Energy Efficient Ethernet (EEE) mode
62932984a8ddSEric Joyner  * accordingly to @enable parameter.
62942984a8ddSEric Joyner  **/
i40e_enable_eee(struct i40e_hw * hw,bool enable)62952984a8ddSEric Joyner enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable)
62962984a8ddSEric Joyner {
62972984a8ddSEric Joyner 	struct i40e_aq_get_phy_abilities_resp abilities;
62982984a8ddSEric Joyner 	struct i40e_aq_set_phy_config config;
62992984a8ddSEric Joyner 	enum i40e_status_code status;
63002984a8ddSEric Joyner 	__le16 eee_capability;
63012984a8ddSEric Joyner 
63022984a8ddSEric Joyner 	/* Get initial PHY capabilities */
63032984a8ddSEric Joyner 	status = i40e_aq_get_phy_capabilities(hw, FALSE, TRUE, &abilities,
63042984a8ddSEric Joyner 					      NULL);
63052984a8ddSEric Joyner 	if (status)
63062984a8ddSEric Joyner 		goto err;
63072984a8ddSEric Joyner 
63082984a8ddSEric Joyner 	/* Check whether NIC configuration is compatible with Energy Efficient
63092984a8ddSEric Joyner 	 * Ethernet (EEE) mode.
63102984a8ddSEric Joyner 	 */
63112984a8ddSEric Joyner 	if (abilities.eee_capability == 0) {
63122984a8ddSEric Joyner 		status = I40E_ERR_CONFIG;
63132984a8ddSEric Joyner 		goto err;
63142984a8ddSEric Joyner 	}
63152984a8ddSEric Joyner 
63162984a8ddSEric Joyner 	/* Cache initial EEE capability */
63172984a8ddSEric Joyner 	eee_capability = abilities.eee_capability;
63182984a8ddSEric Joyner 
63192984a8ddSEric Joyner 	/* Get current configuration */
63202984a8ddSEric Joyner 	status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
63212984a8ddSEric Joyner 					      NULL);
63222984a8ddSEric Joyner 	if (status)
63232984a8ddSEric Joyner 		goto err;
63242984a8ddSEric Joyner 
63252984a8ddSEric Joyner 	/* Cache current configuration */
63262984a8ddSEric Joyner 	config.phy_type = abilities.phy_type;
63272984a8ddSEric Joyner 	config.phy_type_ext = abilities.phy_type_ext;
63282984a8ddSEric Joyner 	config.link_speed = abilities.link_speed;
63292984a8ddSEric Joyner 	config.abilities = abilities.abilities |
63302984a8ddSEric Joyner 			   I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
63312984a8ddSEric Joyner 	config.eeer = abilities.eeer_val;
63322984a8ddSEric Joyner 	config.low_power_ctrl = abilities.d3_lpan;
63332984a8ddSEric Joyner 	config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
63342984a8ddSEric Joyner 			    I40E_AQ_PHY_FEC_CONFIG_MASK;
63352984a8ddSEric Joyner 
63362984a8ddSEric Joyner 	/* Set desired EEE state */
63372984a8ddSEric Joyner 	if (enable) {
63382984a8ddSEric Joyner 		config.eee_capability = eee_capability;
63392984a8ddSEric Joyner 		config.eeer |= I40E_PRTPM_EEER_TX_LPI_EN_MASK;
63402984a8ddSEric Joyner 	} else {
63412984a8ddSEric Joyner 		config.eee_capability = 0;
63422984a8ddSEric Joyner 		config.eeer &= ~I40E_PRTPM_EEER_TX_LPI_EN_MASK;
63432984a8ddSEric Joyner 	}
63442984a8ddSEric Joyner 
63452984a8ddSEric Joyner 	/* Save modified config */
63462984a8ddSEric Joyner 	status = i40e_aq_set_phy_config(hw, &config, NULL);
63472984a8ddSEric Joyner err:
63482984a8ddSEric Joyner 	return status;
63492984a8ddSEric Joyner }
63502984a8ddSEric Joyner 
6351be771cdaSJack F Vogel /**
635261ae650dSJack F Vogel  * i40e_read_bw_from_alt_ram
635361ae650dSJack F Vogel  * @hw: pointer to the hardware structure
635461ae650dSJack F Vogel  * @max_bw: pointer for max_bw read
635561ae650dSJack F Vogel  * @min_bw: pointer for min_bw read
635661ae650dSJack F Vogel  * @min_valid: pointer for bool that is TRUE if min_bw is a valid value
635761ae650dSJack F Vogel  * @max_valid: pointer for bool that is TRUE if max_bw is a valid value
635861ae650dSJack F Vogel  *
635961ae650dSJack F Vogel  * Read bw from the alternate ram for the given pf
636061ae650dSJack F Vogel  **/
i40e_read_bw_from_alt_ram(struct i40e_hw * hw,u32 * max_bw,u32 * min_bw,bool * min_valid,bool * max_valid)636161ae650dSJack F Vogel enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
636261ae650dSJack F Vogel 					u32 *max_bw, u32 *min_bw,
636361ae650dSJack F Vogel 					bool *min_valid, bool *max_valid)
636461ae650dSJack F Vogel {
636561ae650dSJack F Vogel 	enum i40e_status_code status;
636661ae650dSJack F Vogel 	u32 max_bw_addr, min_bw_addr;
636761ae650dSJack F Vogel 
636861ae650dSJack F Vogel 	/* Calculate the address of the min/max bw registers */
636961ae650dSJack F Vogel 	max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
637061ae650dSJack F Vogel 		      I40E_ALT_STRUCT_MAX_BW_OFFSET +
637161ae650dSJack F Vogel 		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
637261ae650dSJack F Vogel 	min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
637361ae650dSJack F Vogel 		      I40E_ALT_STRUCT_MIN_BW_OFFSET +
637461ae650dSJack F Vogel 		      (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
637561ae650dSJack F Vogel 
637661ae650dSJack F Vogel 	/* Read the bandwidths from alt ram */
637761ae650dSJack F Vogel 	status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
637861ae650dSJack F Vogel 					min_bw_addr, min_bw);
637961ae650dSJack F Vogel 
638061ae650dSJack F Vogel 	if (*min_bw & I40E_ALT_BW_VALID_MASK)
638161ae650dSJack F Vogel 		*min_valid = TRUE;
638261ae650dSJack F Vogel 	else
638361ae650dSJack F Vogel 		*min_valid = FALSE;
638461ae650dSJack F Vogel 
638561ae650dSJack F Vogel 	if (*max_bw & I40E_ALT_BW_VALID_MASK)
638661ae650dSJack F Vogel 		*max_valid = TRUE;
638761ae650dSJack F Vogel 	else
638861ae650dSJack F Vogel 		*max_valid = FALSE;
638961ae650dSJack F Vogel 
639061ae650dSJack F Vogel 	return status;
639161ae650dSJack F Vogel }
639261ae650dSJack F Vogel 
639361ae650dSJack F Vogel /**
639461ae650dSJack F Vogel  * i40e_aq_configure_partition_bw
639561ae650dSJack F Vogel  * @hw: pointer to the hardware structure
639661ae650dSJack F Vogel  * @bw_data: Buffer holding valid pfs and bw limits
639761ae650dSJack F Vogel  * @cmd_details: pointer to command details
639861ae650dSJack F Vogel  *
639961ae650dSJack F Vogel  * Configure partitions guaranteed/max bw
640061ae650dSJack F Vogel  **/
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)640161ae650dSJack F Vogel enum i40e_status_code i40e_aq_configure_partition_bw(struct i40e_hw *hw,
640261ae650dSJack F Vogel 			struct i40e_aqc_configure_partition_bw_data *bw_data,
640361ae650dSJack F Vogel 			struct i40e_asq_cmd_details *cmd_details)
640461ae650dSJack F Vogel {
640561ae650dSJack F Vogel 	enum i40e_status_code status;
640661ae650dSJack F Vogel 	struct i40e_aq_desc desc;
6407f247dc25SJack F Vogel 	u16 bwd_size = sizeof(*bw_data);
640861ae650dSJack F Vogel 
640961ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc,
641061ae650dSJack F Vogel 				i40e_aqc_opc_configure_partition_bw);
641161ae650dSJack F Vogel 
641261ae650dSJack F Vogel 	/* Indirect command */
641361ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
641461ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
641561ae650dSJack F Vogel 
641661ae650dSJack F Vogel 	desc.datalen = CPU_TO_LE16(bwd_size);
641761ae650dSJack F Vogel 
641861ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size, cmd_details);
641961ae650dSJack F Vogel 
642061ae650dSJack F Vogel 	return status;
642161ae650dSJack F Vogel }
642261ae650dSJack F Vogel 
642361ae650dSJack F Vogel /**
6424cb6b8299SEric Joyner  * i40e_read_phy_register_clause22
6425cb6b8299SEric Joyner  * @hw: pointer to the HW structure
6426cb6b8299SEric Joyner  * @reg: register address in the page
6427ceebc2f3SEric Joyner  * @phy_addr: PHY address on MDIO interface
6428cb6b8299SEric Joyner  * @value: PHY register value
6429cb6b8299SEric Joyner  *
6430cb6b8299SEric Joyner  * Reads specified PHY register value
6431cb6b8299SEric Joyner  **/
i40e_read_phy_register_clause22(struct i40e_hw * hw,u16 reg,u8 phy_addr,u16 * value)6432cb6b8299SEric Joyner enum i40e_status_code i40e_read_phy_register_clause22(struct i40e_hw *hw,
6433cb6b8299SEric Joyner 					u16 reg, u8 phy_addr, u16 *value)
6434cb6b8299SEric Joyner {
6435cb6b8299SEric Joyner 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6436cb6b8299SEric Joyner 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6437cb6b8299SEric Joyner 	u32 command = 0;
6438cb6b8299SEric Joyner 	u16 retry = 1000;
6439cb6b8299SEric Joyner 
6440cb6b8299SEric Joyner 	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6441cb6b8299SEric Joyner 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6442cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE22_OPCODE_READ_MASK) |
6443cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6444cb6b8299SEric Joyner 		  (I40E_GLGEN_MSCA_MDICMD_MASK);
6445cb6b8299SEric Joyner 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6446cb6b8299SEric Joyner 	do {
6447cb6b8299SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6448cb6b8299SEric Joyner 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6449cb6b8299SEric Joyner 			status = I40E_SUCCESS;
6450cb6b8299SEric Joyner 			break;
6451cb6b8299SEric Joyner 		}
6452cb6b8299SEric Joyner 		i40e_usec_delay(10);
6453cb6b8299SEric Joyner 		retry--;
6454cb6b8299SEric Joyner 	} while (retry);
6455cb6b8299SEric Joyner 
6456cb6b8299SEric Joyner 	if (status) {
6457cb6b8299SEric Joyner 		i40e_debug(hw, I40E_DEBUG_PHY,
6458cb6b8299SEric Joyner 			   "PHY: Can't write command to external PHY.\n");
6459cb6b8299SEric Joyner 	} else {
6460cb6b8299SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
6461cb6b8299SEric Joyner 		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
6462cb6b8299SEric Joyner 			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
6463cb6b8299SEric Joyner 	}
6464cb6b8299SEric Joyner 
6465cb6b8299SEric Joyner 	return status;
6466cb6b8299SEric Joyner }
6467cb6b8299SEric Joyner 
6468cb6b8299SEric Joyner /**
6469cb6b8299SEric Joyner  * i40e_write_phy_register_clause22
6470cb6b8299SEric Joyner  * @hw: pointer to the HW structure
6471cb6b8299SEric Joyner  * @reg: register address in the page
6472ceebc2f3SEric Joyner  * @phy_addr: PHY address on MDIO interface
6473cb6b8299SEric Joyner  * @value: PHY register value
6474cb6b8299SEric Joyner  *
6475cb6b8299SEric Joyner  * Writes specified PHY register value
6476cb6b8299SEric Joyner  **/
i40e_write_phy_register_clause22(struct i40e_hw * hw,u16 reg,u8 phy_addr,u16 value)6477cb6b8299SEric Joyner enum i40e_status_code i40e_write_phy_register_clause22(struct i40e_hw *hw,
6478cb6b8299SEric Joyner 					u16 reg, u8 phy_addr, u16 value)
6479cb6b8299SEric Joyner {
6480cb6b8299SEric Joyner 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
6481cb6b8299SEric Joyner 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
6482cb6b8299SEric Joyner 	u32 command  = 0;
6483cb6b8299SEric Joyner 	u16 retry = 1000;
6484cb6b8299SEric Joyner 
6485cb6b8299SEric Joyner 	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
6486cb6b8299SEric Joyner 	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
6487cb6b8299SEric Joyner 
6488cb6b8299SEric Joyner 	command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
6489cb6b8299SEric Joyner 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6490cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE22_OPCODE_WRITE_MASK) |
6491cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE22_STCODE_MASK) |
6492cb6b8299SEric Joyner 		  (I40E_GLGEN_MSCA_MDICMD_MASK);
6493cb6b8299SEric Joyner 
6494cb6b8299SEric Joyner 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
6495cb6b8299SEric Joyner 	do {
6496cb6b8299SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
6497cb6b8299SEric Joyner 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
6498cb6b8299SEric Joyner 			status = I40E_SUCCESS;
6499cb6b8299SEric Joyner 			break;
6500cb6b8299SEric Joyner 		}
6501cb6b8299SEric Joyner 		i40e_usec_delay(10);
6502cb6b8299SEric Joyner 		retry--;
6503cb6b8299SEric Joyner 	} while (retry);
6504cb6b8299SEric Joyner 
6505cb6b8299SEric Joyner 	return status;
6506cb6b8299SEric Joyner }
6507cb6b8299SEric Joyner 
6508cb6b8299SEric Joyner /**
6509cb6b8299SEric Joyner  * i40e_read_phy_register_clause45
65106c426059SEric Joyner  * @hw: pointer to the HW structure
65116c426059SEric Joyner  * @page: registers page number
65126c426059SEric Joyner  * @reg: register address in the page
6513ceebc2f3SEric Joyner  * @phy_addr: PHY address on MDIO interface
65146c426059SEric Joyner  * @value: PHY register value
65156c426059SEric Joyner  *
65166c426059SEric Joyner  * Reads specified PHY register value
65176c426059SEric Joyner  **/
i40e_read_phy_register_clause45(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 * value)6518cb6b8299SEric Joyner enum i40e_status_code i40e_read_phy_register_clause45(struct i40e_hw *hw,
6519cb6b8299SEric Joyner 				u8 page, u16 reg, u8 phy_addr, u16 *value)
65206c426059SEric Joyner {
65216c426059SEric Joyner 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
65226c426059SEric Joyner 	u32 command  = 0;
65236c426059SEric Joyner 	u16 retry = 1000;
65246c426059SEric Joyner 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
65256c426059SEric Joyner 
65266c426059SEric Joyner 	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
65276c426059SEric Joyner 		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
65286c426059SEric Joyner 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6529cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6530cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
65316c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
65326c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
65336c426059SEric Joyner 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
65346c426059SEric Joyner 	do {
65356c426059SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
65366c426059SEric Joyner 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
65376c426059SEric Joyner 			status = I40E_SUCCESS;
65386c426059SEric Joyner 			break;
65396c426059SEric Joyner 		}
65406c426059SEric Joyner 		i40e_usec_delay(10);
65416c426059SEric Joyner 		retry--;
65426c426059SEric Joyner 	} while (retry);
65436c426059SEric Joyner 
65446c426059SEric Joyner 	if (status) {
65456c426059SEric Joyner 		i40e_debug(hw, I40E_DEBUG_PHY,
65466c426059SEric Joyner 			   "PHY: Can't write command to external PHY.\n");
65476c426059SEric Joyner 		goto phy_read_end;
65486c426059SEric Joyner 	}
65496c426059SEric Joyner 
65506c426059SEric Joyner 	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
65516c426059SEric Joyner 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6552cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_OPCODE_READ_MASK) |
6553cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
65546c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
65556c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
65566c426059SEric Joyner 	status = I40E_ERR_TIMEOUT;
65576c426059SEric Joyner 	retry = 1000;
65586c426059SEric Joyner 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
65596c426059SEric Joyner 	do {
65606c426059SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
65616c426059SEric Joyner 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
65626c426059SEric Joyner 			status = I40E_SUCCESS;
65636c426059SEric Joyner 			break;
65646c426059SEric Joyner 		}
65656c426059SEric Joyner 		i40e_usec_delay(10);
65666c426059SEric Joyner 		retry--;
65676c426059SEric Joyner 	} while (retry);
65686c426059SEric Joyner 
65696c426059SEric Joyner 	if (!status) {
65706c426059SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
65716c426059SEric Joyner 		*value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
65726c426059SEric Joyner 			 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
65736c426059SEric Joyner 	} else {
65746c426059SEric Joyner 		i40e_debug(hw, I40E_DEBUG_PHY,
65756c426059SEric Joyner 			   "PHY: Can't read register value from external PHY.\n");
65766c426059SEric Joyner 	}
65776c426059SEric Joyner 
65786c426059SEric Joyner phy_read_end:
65796c426059SEric Joyner 	return status;
65806c426059SEric Joyner }
65816c426059SEric Joyner 
65826c426059SEric Joyner /**
6583cb6b8299SEric Joyner  * i40e_write_phy_register_clause45
65846c426059SEric Joyner  * @hw: pointer to the HW structure
65856c426059SEric Joyner  * @page: registers page number
65866c426059SEric Joyner  * @reg: register address in the page
6587ceebc2f3SEric Joyner  * @phy_addr: PHY address on MDIO interface
65886c426059SEric Joyner  * @value: PHY register value
65896c426059SEric Joyner  *
65906c426059SEric Joyner  * Writes value to specified PHY register
65916c426059SEric Joyner  **/
i40e_write_phy_register_clause45(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 value)6592cb6b8299SEric Joyner enum i40e_status_code i40e_write_phy_register_clause45(struct i40e_hw *hw,
6593cb6b8299SEric Joyner 				u8 page, u16 reg, u8 phy_addr, u16 value)
65946c426059SEric Joyner {
65956c426059SEric Joyner 	enum i40e_status_code status = I40E_ERR_TIMEOUT;
65966c426059SEric Joyner 	u32 command  = 0;
65976c426059SEric Joyner 	u16 retry = 1000;
65986c426059SEric Joyner 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
65996c426059SEric Joyner 
66006c426059SEric Joyner 	command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
66016c426059SEric Joyner 		  (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
66026c426059SEric Joyner 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6603cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
6604cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
66056c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
66066c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
66076c426059SEric Joyner 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
66086c426059SEric Joyner 	do {
66096c426059SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
66106c426059SEric Joyner 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
66116c426059SEric Joyner 			status = I40E_SUCCESS;
66126c426059SEric Joyner 			break;
66136c426059SEric Joyner 		}
66146c426059SEric Joyner 		i40e_usec_delay(10);
66156c426059SEric Joyner 		retry--;
66166c426059SEric Joyner 	} while (retry);
66176c426059SEric Joyner 	if (status) {
66186c426059SEric Joyner 		i40e_debug(hw, I40E_DEBUG_PHY,
66196c426059SEric Joyner 			   "PHY: Can't write command to external PHY.\n");
66206c426059SEric Joyner 		goto phy_write_end;
66216c426059SEric Joyner 	}
66226c426059SEric Joyner 
66236c426059SEric Joyner 	command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
66246c426059SEric Joyner 	wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
66256c426059SEric Joyner 
66266c426059SEric Joyner 	command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
66276c426059SEric Joyner 		  (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
6628cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_OPCODE_WRITE_MASK) |
6629cb6b8299SEric Joyner 		  (I40E_MDIO_CLAUSE45_STCODE_MASK) |
66306c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDICMD_MASK) |
66316c426059SEric Joyner 		  (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
66326c426059SEric Joyner 	status = I40E_ERR_TIMEOUT;
66336c426059SEric Joyner 	retry = 1000;
66346c426059SEric Joyner 	wr32(hw, I40E_GLGEN_MSCA(port_num), command);
66356c426059SEric Joyner 	do {
66366c426059SEric Joyner 		command = rd32(hw, I40E_GLGEN_MSCA(port_num));
66376c426059SEric Joyner 		if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
66386c426059SEric Joyner 			status = I40E_SUCCESS;
66396c426059SEric Joyner 			break;
66406c426059SEric Joyner 		}
66416c426059SEric Joyner 		i40e_usec_delay(10);
66426c426059SEric Joyner 		retry--;
66436c426059SEric Joyner 	} while (retry);
66446c426059SEric Joyner 
66456c426059SEric Joyner phy_write_end:
66466c426059SEric Joyner 	return status;
66476c426059SEric Joyner }
66486c426059SEric Joyner 
66496c426059SEric Joyner /**
6650cb6b8299SEric Joyner  * i40e_write_phy_register
6651cb6b8299SEric Joyner  * @hw: pointer to the HW structure
6652cb6b8299SEric Joyner  * @page: registers page number
6653cb6b8299SEric Joyner  * @reg: register address in the page
6654ceebc2f3SEric Joyner  * @phy_addr: PHY address on MDIO interface
6655cb6b8299SEric Joyner  * @value: PHY register value
6656cb6b8299SEric Joyner  *
6657cb6b8299SEric Joyner  * Writes value to specified PHY register
6658cb6b8299SEric Joyner  **/
i40e_write_phy_register(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 value)6659cb6b8299SEric Joyner enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
6660cb6b8299SEric Joyner 				u8 page, u16 reg, u8 phy_addr, u16 value)
6661cb6b8299SEric Joyner {
6662cb6b8299SEric Joyner 	enum i40e_status_code status;
6663cb6b8299SEric Joyner 
6664cb6b8299SEric Joyner 	switch (hw->device_id) {
6665cb6b8299SEric Joyner 	case I40E_DEV_ID_1G_BASE_T_X722:
6666cb6b8299SEric Joyner 		status = i40e_write_phy_register_clause22(hw,
6667cb6b8299SEric Joyner 			reg, phy_addr, value);
6668cb6b8299SEric Joyner 		break;
6669cb6b8299SEric Joyner 	case I40E_DEV_ID_10G_BASE_T:
6670cb6b8299SEric Joyner 	case I40E_DEV_ID_10G_BASE_T4:
66712984a8ddSEric Joyner 	case I40E_DEV_ID_10G_BASE_T_BC:
66722984a8ddSEric Joyner 	case I40E_DEV_ID_5G_BASE_T_BC:
6673*b7b40e4aSKrzysztof Galazka 	case I40E_DEV_ID_1G_BASE_T_BC:
6674cb6b8299SEric Joyner 	case I40E_DEV_ID_10G_BASE_T_X722:
6675cb6b8299SEric Joyner 	case I40E_DEV_ID_25G_B:
6676cb6b8299SEric Joyner 	case I40E_DEV_ID_25G_SFP28:
6677cb6b8299SEric Joyner 		status = i40e_write_phy_register_clause45(hw,
6678cb6b8299SEric Joyner 			page, reg, phy_addr, value);
6679cb6b8299SEric Joyner 		break;
6680cb6b8299SEric Joyner 	default:
6681cb6b8299SEric Joyner 		status = I40E_ERR_UNKNOWN_PHY;
6682cb6b8299SEric Joyner 		break;
6683cb6b8299SEric Joyner 	}
6684cb6b8299SEric Joyner 
6685cb6b8299SEric Joyner 	return status;
6686cb6b8299SEric Joyner }
6687cb6b8299SEric Joyner 
6688cb6b8299SEric Joyner /**
6689cb6b8299SEric Joyner  * i40e_read_phy_register
6690cb6b8299SEric Joyner  * @hw: pointer to the HW structure
6691cb6b8299SEric Joyner  * @page: registers page number
6692cb6b8299SEric Joyner  * @reg: register address in the page
6693ceebc2f3SEric Joyner  * @phy_addr: PHY address on MDIO interface
6694cb6b8299SEric Joyner  * @value: PHY register value
6695cb6b8299SEric Joyner  *
6696cb6b8299SEric Joyner  * Reads specified PHY register value
6697cb6b8299SEric Joyner  **/
i40e_read_phy_register(struct i40e_hw * hw,u8 page,u16 reg,u8 phy_addr,u16 * value)6698cb6b8299SEric Joyner enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
6699cb6b8299SEric Joyner 				u8 page, u16 reg, u8 phy_addr, u16 *value)
6700cb6b8299SEric Joyner {
6701cb6b8299SEric Joyner 	enum i40e_status_code status;
6702cb6b8299SEric Joyner 
6703cb6b8299SEric Joyner 	switch (hw->device_id) {
6704cb6b8299SEric Joyner 	case I40E_DEV_ID_1G_BASE_T_X722:
6705cb6b8299SEric Joyner 		status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
6706cb6b8299SEric Joyner 							 value);
6707cb6b8299SEric Joyner 		break;
6708cb6b8299SEric Joyner 	case I40E_DEV_ID_10G_BASE_T:
6709cb6b8299SEric Joyner 	case I40E_DEV_ID_10G_BASE_T4:
67102984a8ddSEric Joyner 	case I40E_DEV_ID_10G_BASE_T_BC:
67112984a8ddSEric Joyner 	case I40E_DEV_ID_5G_BASE_T_BC:
6712*b7b40e4aSKrzysztof Galazka 	case I40E_DEV_ID_1G_BASE_T_BC:
6713cb6b8299SEric Joyner 	case I40E_DEV_ID_10G_BASE_T_X722:
6714cb6b8299SEric Joyner 	case I40E_DEV_ID_25G_B:
6715cb6b8299SEric Joyner 	case I40E_DEV_ID_25G_SFP28:
6716cb6b8299SEric Joyner 		status = i40e_read_phy_register_clause45(hw, page, reg,
6717cb6b8299SEric Joyner 							 phy_addr, value);
6718cb6b8299SEric Joyner 		break;
6719cb6b8299SEric Joyner 	default:
6720cb6b8299SEric Joyner 		status = I40E_ERR_UNKNOWN_PHY;
6721cb6b8299SEric Joyner 		break;
6722cb6b8299SEric Joyner 	}
6723cb6b8299SEric Joyner 
6724cb6b8299SEric Joyner 	return status;
6725cb6b8299SEric Joyner }
6726cb6b8299SEric Joyner 
6727cb6b8299SEric Joyner /**
67286c426059SEric Joyner  * i40e_get_phy_address
67296c426059SEric Joyner  * @hw: pointer to the HW structure
67306c426059SEric Joyner  * @dev_num: PHY port num that address we want
67316c426059SEric Joyner  *
67326c426059SEric Joyner  * Gets PHY address for current port
67336c426059SEric Joyner  **/
i40e_get_phy_address(struct i40e_hw * hw,u8 dev_num)67346c426059SEric Joyner u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
67356c426059SEric Joyner {
67366c426059SEric Joyner 	u8 port_num = (u8)hw->func_caps.mdio_port_num;
67376c426059SEric Joyner 	u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
67386c426059SEric Joyner 
67396c426059SEric Joyner 	return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
67406c426059SEric Joyner }
67416c426059SEric Joyner 
67426c426059SEric Joyner /**
6743abf77452SKrzysztof Galazka  * i40e_blink_phy_link_led
67446c426059SEric Joyner  * @hw: pointer to the HW structure
67456c426059SEric Joyner  * @time: time how long led will blinks in secs
67466c426059SEric Joyner  * @interval: gap between LED on and off in msecs
67476c426059SEric Joyner  *
67486c426059SEric Joyner  * Blinks PHY link LED
67496c426059SEric Joyner  **/
i40e_blink_phy_link_led(struct i40e_hw * hw,u32 time,u32 interval)67506c426059SEric Joyner enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw,
67516c426059SEric Joyner 					      u32 time, u32 interval)
67526c426059SEric Joyner {
67536c426059SEric Joyner 	enum i40e_status_code status = I40E_SUCCESS;
67546c426059SEric Joyner 	u32 i;
67556c426059SEric Joyner 	u16 led_ctl = 0;
67566c426059SEric Joyner 	u16 gpio_led_port;
67576c426059SEric Joyner 	u16 led_reg;
67586c426059SEric Joyner 	u16 led_addr = I40E_PHY_LED_PROV_REG_1;
67596c426059SEric Joyner 	u8 phy_addr = 0;
67606c426059SEric Joyner 	u8 port_num;
67616c426059SEric Joyner 
67626c426059SEric Joyner 	i = rd32(hw, I40E_PFGEN_PORTNUM);
67636c426059SEric Joyner 	port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
67646c426059SEric Joyner 	phy_addr = i40e_get_phy_address(hw, port_num);
67656c426059SEric Joyner 
67666c426059SEric Joyner 	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
67676c426059SEric Joyner 	     led_addr++) {
6768cb6b8299SEric Joyner 		status = i40e_read_phy_register_clause45(hw,
6769cb6b8299SEric Joyner 							 I40E_PHY_COM_REG_PAGE,
6770cb6b8299SEric Joyner 							 led_addr, phy_addr,
6771cb6b8299SEric Joyner 							 &led_reg);
67726c426059SEric Joyner 		if (status)
67736c426059SEric Joyner 			goto phy_blinking_end;
67746c426059SEric Joyner 		led_ctl = led_reg;
67756c426059SEric Joyner 		if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
67766c426059SEric Joyner 			led_reg = 0;
6777cb6b8299SEric Joyner 			status = i40e_write_phy_register_clause45(hw,
67786c426059SEric Joyner 							 I40E_PHY_COM_REG_PAGE,
67796c426059SEric Joyner 							 led_addr, phy_addr,
67806c426059SEric Joyner 							 led_reg);
67816c426059SEric Joyner 			if (status)
67826c426059SEric Joyner 				goto phy_blinking_end;
67836c426059SEric Joyner 			break;
67846c426059SEric Joyner 		}
67856c426059SEric Joyner 	}
67866c426059SEric Joyner 
67876c426059SEric Joyner 	if (time > 0 && interval > 0) {
67886c426059SEric Joyner 		for (i = 0; i < time * 1000; i += interval) {
6789cb6b8299SEric Joyner 			status = i40e_read_phy_register_clause45(hw,
67906c426059SEric Joyner 						I40E_PHY_COM_REG_PAGE,
6791cb6b8299SEric Joyner 						led_addr, phy_addr, &led_reg);
67926c426059SEric Joyner 			if (status)
67936c426059SEric Joyner 				goto restore_config;
67946c426059SEric Joyner 			if (led_reg & I40E_PHY_LED_MANUAL_ON)
67956c426059SEric Joyner 				led_reg = 0;
67966c426059SEric Joyner 			else
67976c426059SEric Joyner 				led_reg = I40E_PHY_LED_MANUAL_ON;
6798cb6b8299SEric Joyner 			status = i40e_write_phy_register_clause45(hw,
67996c426059SEric Joyner 						I40E_PHY_COM_REG_PAGE,
6800cb6b8299SEric Joyner 						led_addr, phy_addr, led_reg);
68016c426059SEric Joyner 			if (status)
68026c426059SEric Joyner 				goto restore_config;
68036c426059SEric Joyner 			i40e_msec_delay(interval);
68046c426059SEric Joyner 		}
68056c426059SEric Joyner 	}
68066c426059SEric Joyner 
68076c426059SEric Joyner restore_config:
6808cb6b8299SEric Joyner 	status = i40e_write_phy_register_clause45(hw,
6809cb6b8299SEric Joyner 						  I40E_PHY_COM_REG_PAGE,
6810cb6b8299SEric Joyner 						  led_addr, phy_addr, led_ctl);
68116c426059SEric Joyner 
68126c426059SEric Joyner phy_blinking_end:
68136c426059SEric Joyner 	return status;
68146c426059SEric Joyner }
68156c426059SEric Joyner 
68166c426059SEric Joyner /**
6817ceebc2f3SEric Joyner  * i40e_led_get_reg - read LED register
6818ceebc2f3SEric Joyner  * @hw: pointer to the HW structure
6819ceebc2f3SEric Joyner  * @led_addr: LED register address
6820ceebc2f3SEric Joyner  * @reg_val: read register value
6821ceebc2f3SEric Joyner  **/
i40e_led_get_reg(struct i40e_hw * hw,u16 led_addr,u32 * reg_val)6822b4a7ce06SEric Joyner enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
6823ceebc2f3SEric Joyner 				       u32 *reg_val)
6824ceebc2f3SEric Joyner {
6825ceebc2f3SEric Joyner 	enum i40e_status_code status;
6826ceebc2f3SEric Joyner 	u8 phy_addr = 0;
6827ceebc2f3SEric Joyner 
6828ceebc2f3SEric Joyner 	*reg_val = 0;
6829ceebc2f3SEric Joyner 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6830ceebc2f3SEric Joyner 		status = i40e_aq_get_phy_register(hw,
6831ceebc2f3SEric Joyner 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6832b4a7ce06SEric Joyner 						I40E_PHY_COM_REG_PAGE, TRUE,
6833ceebc2f3SEric Joyner 						I40E_PHY_LED_PROV_REG_1,
6834ceebc2f3SEric Joyner 						reg_val, NULL);
6835ceebc2f3SEric Joyner 	} else {
6836ceebc2f3SEric Joyner 		phy_addr = i40e_get_phy_address(hw, hw->port);
6837ceebc2f3SEric Joyner 		status = i40e_read_phy_register_clause45(hw,
6838ceebc2f3SEric Joyner 							 I40E_PHY_COM_REG_PAGE,
6839ceebc2f3SEric Joyner 							 led_addr, phy_addr,
6840ceebc2f3SEric Joyner 							 (u16 *)reg_val);
6841ceebc2f3SEric Joyner 	}
6842ceebc2f3SEric Joyner 	return status;
6843ceebc2f3SEric Joyner }
6844ceebc2f3SEric Joyner 
6845ceebc2f3SEric Joyner /**
6846ceebc2f3SEric Joyner  * i40e_led_set_reg - write LED register
6847ceebc2f3SEric Joyner  * @hw: pointer to the HW structure
6848ceebc2f3SEric Joyner  * @led_addr: LED register address
6849ceebc2f3SEric Joyner  * @reg_val: register value to write
6850ceebc2f3SEric Joyner  **/
i40e_led_set_reg(struct i40e_hw * hw,u16 led_addr,u32 reg_val)6851b4a7ce06SEric Joyner enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
6852ceebc2f3SEric Joyner 				       u32 reg_val)
6853ceebc2f3SEric Joyner {
6854ceebc2f3SEric Joyner 	enum i40e_status_code status;
6855ceebc2f3SEric Joyner 	u8 phy_addr = 0;
6856ceebc2f3SEric Joyner 
6857ceebc2f3SEric Joyner 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6858ceebc2f3SEric Joyner 		status = i40e_aq_set_phy_register(hw,
6859ceebc2f3SEric Joyner 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6860b4a7ce06SEric Joyner 						I40E_PHY_COM_REG_PAGE, TRUE,
6861ceebc2f3SEric Joyner 						I40E_PHY_LED_PROV_REG_1,
6862ceebc2f3SEric Joyner 						reg_val, NULL);
6863ceebc2f3SEric Joyner 	} else {
6864ceebc2f3SEric Joyner 		phy_addr = i40e_get_phy_address(hw, hw->port);
6865ceebc2f3SEric Joyner 		status = i40e_write_phy_register_clause45(hw,
6866ceebc2f3SEric Joyner 							  I40E_PHY_COM_REG_PAGE,
6867ceebc2f3SEric Joyner 							  led_addr, phy_addr,
6868ceebc2f3SEric Joyner 							  (u16)reg_val);
6869ceebc2f3SEric Joyner 	}
6870ceebc2f3SEric Joyner 
6871ceebc2f3SEric Joyner 	return status;
6872ceebc2f3SEric Joyner }
6873ceebc2f3SEric Joyner 
6874ceebc2f3SEric Joyner /**
68756c426059SEric Joyner  * i40e_led_get_phy - return current on/off mode
68766c426059SEric Joyner  * @hw: pointer to the hw struct
68776c426059SEric Joyner  * @led_addr: address of led register to use
68786c426059SEric Joyner  * @val: original value of register to use
68796c426059SEric Joyner  *
68806c426059SEric Joyner  **/
i40e_led_get_phy(struct i40e_hw * hw,u16 * led_addr,u16 * val)68816c426059SEric Joyner enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
68826c426059SEric Joyner 				       u16 *val)
68836c426059SEric Joyner {
68846c426059SEric Joyner 	enum i40e_status_code status = I40E_SUCCESS;
68856c426059SEric Joyner 	u16 gpio_led_port;
6886ceebc2f3SEric Joyner 	u32 reg_val_aq;
6887ceebc2f3SEric Joyner 	u16 temp_addr;
68886c426059SEric Joyner 	u8 phy_addr = 0;
68896c426059SEric Joyner 	u16 reg_val;
68906c426059SEric Joyner 
6891ceebc2f3SEric Joyner 	if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
6892ceebc2f3SEric Joyner 		status = i40e_aq_get_phy_register(hw,
6893ceebc2f3SEric Joyner 						I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
6894b4a7ce06SEric Joyner 						I40E_PHY_COM_REG_PAGE, TRUE,
6895ceebc2f3SEric Joyner 						I40E_PHY_LED_PROV_REG_1,
6896ceebc2f3SEric Joyner 						&reg_val_aq, NULL);
6897ceebc2f3SEric Joyner 		if (status == I40E_SUCCESS)
6898ceebc2f3SEric Joyner 			*val = (u16)reg_val_aq;
6899ceebc2f3SEric Joyner 		return status;
6900ceebc2f3SEric Joyner 	}
69016c426059SEric Joyner 	temp_addr = I40E_PHY_LED_PROV_REG_1;
6902ceebc2f3SEric Joyner 	phy_addr = i40e_get_phy_address(hw, hw->port);
69036c426059SEric Joyner 	for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
69046c426059SEric Joyner 	     temp_addr++) {
6905cb6b8299SEric Joyner 		status = i40e_read_phy_register_clause45(hw,
6906cb6b8299SEric Joyner 							 I40E_PHY_COM_REG_PAGE,
6907cb6b8299SEric Joyner 							 temp_addr, phy_addr,
6908cb6b8299SEric Joyner 							 &reg_val);
69096c426059SEric Joyner 		if (status)
69106c426059SEric Joyner 			return status;
69116c426059SEric Joyner 		*val = reg_val;
69126c426059SEric Joyner 		if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
69136c426059SEric Joyner 			*led_addr = temp_addr;
69146c426059SEric Joyner 			break;
69156c426059SEric Joyner 		}
69166c426059SEric Joyner 	}
69176c426059SEric Joyner 	return status;
69186c426059SEric Joyner }
69196c426059SEric Joyner 
69206c426059SEric Joyner /**
69216c426059SEric Joyner  * i40e_led_set_phy
69226c426059SEric Joyner  * @hw: pointer to the HW structure
69236c426059SEric Joyner  * @on: TRUE or FALSE
6924ceebc2f3SEric Joyner  * @led_addr: address of led register to use
69256c426059SEric Joyner  * @mode: original val plus bit for set or ignore
6926ceebc2f3SEric Joyner  *
69276c426059SEric Joyner  * Set led's on or off when controlled by the PHY
69286c426059SEric Joyner  *
69296c426059SEric Joyner  **/
i40e_led_set_phy(struct i40e_hw * hw,bool on,u16 led_addr,u32 mode)69306c426059SEric Joyner enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on,
69316c426059SEric Joyner 				       u16 led_addr, u32 mode)
69326c426059SEric Joyner {
69336c426059SEric Joyner 	enum i40e_status_code status = I40E_SUCCESS;
6934ceebc2f3SEric Joyner 	u32 led_ctl = 0;
6935ceebc2f3SEric Joyner 	u32 led_reg = 0;
69366c426059SEric Joyner 
6937ceebc2f3SEric Joyner 	status = i40e_led_get_reg(hw, led_addr, &led_reg);
69386c426059SEric Joyner 	if (status)
69396c426059SEric Joyner 		return status;
69406c426059SEric Joyner 	led_ctl = led_reg;
69416c426059SEric Joyner 	if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
69426c426059SEric Joyner 		led_reg = 0;
6943ceebc2f3SEric Joyner 		status = i40e_led_set_reg(hw, led_addr, led_reg);
69446c426059SEric Joyner 		if (status)
69456c426059SEric Joyner 			return status;
69466c426059SEric Joyner 	}
6947ceebc2f3SEric Joyner 	status = i40e_led_get_reg(hw, led_addr, &led_reg);
69486c426059SEric Joyner 	if (status)
69496c426059SEric Joyner 		goto restore_config;
69506c426059SEric Joyner 	if (on)
69516c426059SEric Joyner 		led_reg = I40E_PHY_LED_MANUAL_ON;
69526c426059SEric Joyner 	else
69536c426059SEric Joyner 		led_reg = 0;
6954ceebc2f3SEric Joyner 	status = i40e_led_set_reg(hw, led_addr, led_reg);
69556c426059SEric Joyner 	if (status)
69566c426059SEric Joyner 		goto restore_config;
69576c426059SEric Joyner 	if (mode & I40E_PHY_LED_MODE_ORIG) {
69586c426059SEric Joyner 		led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
6959ceebc2f3SEric Joyner 		status = i40e_led_set_reg(hw, led_addr, led_ctl);
69606c426059SEric Joyner 	}
69616c426059SEric Joyner 	return status;
6962ceebc2f3SEric Joyner 
69636c426059SEric Joyner restore_config:
6964ceebc2f3SEric Joyner 	status = i40e_led_set_reg(hw, led_addr, led_ctl);
69656c426059SEric Joyner 	return status;
69666c426059SEric Joyner }
69676c426059SEric Joyner 
69686c426059SEric Joyner /**
69692984a8ddSEric Joyner  * i40e_get_phy_lpi_status - read LPI status from PHY or MAC register
69702984a8ddSEric Joyner  * @hw: pointer to the hw struct
69712984a8ddSEric Joyner  * @stat: pointer to structure with status of rx and tx lpi
69722984a8ddSEric Joyner  *
69732984a8ddSEric Joyner  * Read LPI state directly from external PHY register or from MAC
69742984a8ddSEric Joyner  * register, depending on device ID and current link speed.
69752984a8ddSEric Joyner  */
i40e_get_phy_lpi_status(struct i40e_hw * hw,struct i40e_hw_port_stats * stat)69762984a8ddSEric Joyner enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
69772984a8ddSEric Joyner 					      struct i40e_hw_port_stats *stat)
69782984a8ddSEric Joyner {
69792984a8ddSEric Joyner 	enum i40e_status_code ret = I40E_SUCCESS;
6980abf77452SKrzysztof Galazka 	bool eee_mrvl_phy;
6981abf77452SKrzysztof Galazka 	bool eee_bcm_phy;
69822984a8ddSEric Joyner 	u32 val;
69832984a8ddSEric Joyner 
69842984a8ddSEric Joyner 	stat->rx_lpi_status = 0;
69852984a8ddSEric Joyner 	stat->tx_lpi_status = 0;
69862984a8ddSEric Joyner 
6987abf77452SKrzysztof Galazka 	eee_bcm_phy =
6988abf77452SKrzysztof Galazka 		(hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
69892984a8ddSEric Joyner 		 hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
69902984a8ddSEric Joyner 		(hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB ||
6991abf77452SKrzysztof Galazka 		 hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB);
6992abf77452SKrzysztof Galazka 	eee_mrvl_phy =
6993abf77452SKrzysztof Galazka 		hw->device_id == I40E_DEV_ID_1G_BASE_T_X722;
6994abf77452SKrzysztof Galazka 
6995abf77452SKrzysztof Galazka 	if (eee_bcm_phy || eee_mrvl_phy) {
6996abf77452SKrzysztof Galazka 		// read Clause 45 PCS Status 1 register
69972984a8ddSEric Joyner 		ret = i40e_aq_get_phy_register(hw,
69982984a8ddSEric Joyner 					       I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
69992984a8ddSEric Joyner 					       I40E_BCM_PHY_PCS_STATUS1_PAGE,
70002984a8ddSEric Joyner 					       TRUE,
70012984a8ddSEric Joyner 					       I40E_BCM_PHY_PCS_STATUS1_REG,
70022984a8ddSEric Joyner 					       &val, NULL);
70032984a8ddSEric Joyner 
70042984a8ddSEric Joyner 		if (ret != I40E_SUCCESS)
70052984a8ddSEric Joyner 			return ret;
70062984a8ddSEric Joyner 
70072984a8ddSEric Joyner 		stat->rx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_RX_LPI);
70082984a8ddSEric Joyner 		stat->tx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_TX_LPI);
70092984a8ddSEric Joyner 
70102984a8ddSEric Joyner 		return ret;
70112984a8ddSEric Joyner 	}
70122984a8ddSEric Joyner 
70132984a8ddSEric Joyner 	val = rd32(hw, I40E_PRTPM_EEE_STAT);
70142984a8ddSEric Joyner 	stat->rx_lpi_status = (val & I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK) >>
70152984a8ddSEric Joyner 			       I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT;
70162984a8ddSEric Joyner 	stat->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >>
70172984a8ddSEric Joyner 			       I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT;
70182984a8ddSEric Joyner 
70192984a8ddSEric Joyner 	return ret;
70202984a8ddSEric Joyner }
70212984a8ddSEric Joyner 
70222984a8ddSEric Joyner /**
70232984a8ddSEric Joyner  * i40e_get_lpi_counters - read LPI counters from EEE statistics
70242984a8ddSEric Joyner  * @hw: pointer to the hw struct
70252984a8ddSEric Joyner  * @tx_counter: pointer to memory for TX LPI counter
70262984a8ddSEric Joyner  * @rx_counter: pointer to memory for RX LPI counter
70272984a8ddSEric Joyner  * @is_clear:   returns TRUE if counters are clear after read
70282984a8ddSEric Joyner  *
70292984a8ddSEric Joyner  * Read Low Power Idle (LPI) mode counters from Energy Efficient
70302984a8ddSEric Joyner  * Ethernet (EEE) statistics.
70312984a8ddSEric Joyner  **/
i40e_get_lpi_counters(struct i40e_hw * hw,u32 * tx_counter,u32 * rx_counter,bool * is_clear)70322984a8ddSEric Joyner enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw,
70332984a8ddSEric Joyner 					    u32 *tx_counter, u32 *rx_counter,
70342984a8ddSEric Joyner 					    bool *is_clear)
70352984a8ddSEric Joyner {
70362984a8ddSEric Joyner 	/* only X710-T*L requires special handling of counters
70372984a8ddSEric Joyner 	 * for other devices we just read the MAC registers
70382984a8ddSEric Joyner 	 */
70392984a8ddSEric Joyner 	if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
70402984a8ddSEric Joyner 	     hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
70412984a8ddSEric Joyner 	     hw->phy.link_info.link_speed != I40E_LINK_SPEED_1GB) {
70422984a8ddSEric Joyner 		enum i40e_status_code retval;
70432984a8ddSEric Joyner 		u32 cmd_status;
70442984a8ddSEric Joyner 
70452984a8ddSEric Joyner 		*is_clear = FALSE;
70462984a8ddSEric Joyner 		retval = i40e_aq_run_phy_activity(hw,
70472984a8ddSEric Joyner 				I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
70482984a8ddSEric Joyner 				I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT,
70492984a8ddSEric Joyner 				&cmd_status, tx_counter, rx_counter, NULL);
70502984a8ddSEric Joyner 
70512984a8ddSEric Joyner 		if (!retval && cmd_status != I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
70522984a8ddSEric Joyner 			retval = I40E_ERR_ADMIN_QUEUE_ERROR;
70532984a8ddSEric Joyner 
70542984a8ddSEric Joyner 		return retval;
70552984a8ddSEric Joyner 	}
70562984a8ddSEric Joyner 
70572984a8ddSEric Joyner 	*is_clear = TRUE;
70582984a8ddSEric Joyner 	*tx_counter = rd32(hw, I40E_PRTPM_TLPIC);
70592984a8ddSEric Joyner 	*rx_counter = rd32(hw, I40E_PRTPM_RLPIC);
70602984a8ddSEric Joyner 
70612984a8ddSEric Joyner 	return I40E_SUCCESS;
70622984a8ddSEric Joyner }
70632984a8ddSEric Joyner 
70642984a8ddSEric Joyner /**
70652984a8ddSEric Joyner  * i40e_get_lpi_duration - read LPI time duration from EEE statistics
70662984a8ddSEric Joyner  * @hw: pointer to the hw struct
70672984a8ddSEric Joyner  * @stat: pointer to structure with status of rx and tx lpi
70682984a8ddSEric Joyner  * @tx_duration: pointer to memory for TX LPI time duration
70692984a8ddSEric Joyner  * @rx_duration: pointer to memory for RX LPI time duration
70702984a8ddSEric Joyner  *
70712984a8ddSEric Joyner  * Read Low Power Idle (LPI) mode time duration from Energy Efficient
70722984a8ddSEric Joyner  * Ethernet (EEE) statistics.
70732984a8ddSEric Joyner  */
i40e_get_lpi_duration(struct i40e_hw * hw,struct i40e_hw_port_stats * stat,u64 * tx_duration,u64 * rx_duration)70742984a8ddSEric Joyner enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw,
70752984a8ddSEric Joyner 					    struct i40e_hw_port_stats *stat,
70762984a8ddSEric Joyner 					    u64 *tx_duration, u64 *rx_duration)
70772984a8ddSEric Joyner {
70782984a8ddSEric Joyner 	u32 tx_time_dur, rx_time_dur;
70792984a8ddSEric Joyner 	enum i40e_status_code retval;
70802984a8ddSEric Joyner 	u32 cmd_status;
70812984a8ddSEric Joyner 
70822984a8ddSEric Joyner 	if (hw->device_id != I40E_DEV_ID_10G_BASE_T_BC &&
70832984a8ddSEric Joyner 	    hw->device_id != I40E_DEV_ID_5G_BASE_T_BC)
70842984a8ddSEric Joyner 		return I40E_ERR_NOT_IMPLEMENTED;
70852984a8ddSEric Joyner 
70862984a8ddSEric Joyner 	retval = i40e_aq_run_phy_activity
70872984a8ddSEric Joyner 		(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
70882984a8ddSEric Joyner 		I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR,
70892984a8ddSEric Joyner 		&cmd_status, &tx_time_dur, &rx_time_dur, NULL);
70902984a8ddSEric Joyner 
70912984a8ddSEric Joyner 	if (retval)
70922984a8ddSEric Joyner 		return retval;
70932984a8ddSEric Joyner 	if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
70942984a8ddSEric Joyner 	    I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
70952984a8ddSEric Joyner 		return I40E_ERR_ADMIN_QUEUE_ERROR;
70962984a8ddSEric Joyner 
70972984a8ddSEric Joyner 	if (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB &&
70982984a8ddSEric Joyner 	    !tx_time_dur && !rx_time_dur &&
70992984a8ddSEric Joyner 	    stat->tx_lpi_status && stat->rx_lpi_status) {
71002984a8ddSEric Joyner 		retval = i40e_aq_run_phy_activity
71012984a8ddSEric Joyner 			(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
71022984a8ddSEric Joyner 			I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR,
71032984a8ddSEric Joyner 			&cmd_status,
71042984a8ddSEric Joyner 			&tx_time_dur, &rx_time_dur, NULL);
71052984a8ddSEric Joyner 
71062984a8ddSEric Joyner 		if (retval)
71072984a8ddSEric Joyner 			return retval;
71082984a8ddSEric Joyner 		if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
71092984a8ddSEric Joyner 		    I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
71102984a8ddSEric Joyner 			return I40E_ERR_ADMIN_QUEUE_ERROR;
71112984a8ddSEric Joyner 		tx_time_dur = 0;
71122984a8ddSEric Joyner 		rx_time_dur = 0;
71132984a8ddSEric Joyner 	}
71142984a8ddSEric Joyner 
71152984a8ddSEric Joyner 	*tx_duration = tx_time_dur;
71162984a8ddSEric Joyner 	*rx_duration = rx_time_dur;
71172984a8ddSEric Joyner 
71182984a8ddSEric Joyner 	return retval;
71192984a8ddSEric Joyner }
71202984a8ddSEric Joyner 
71212984a8ddSEric Joyner /**
71222984a8ddSEric Joyner  * i40e_lpi_stat_update - update LPI counters with values relative to offset
71232984a8ddSEric Joyner  * @hw: pointer to the hw struct
71242984a8ddSEric Joyner  * @offset_loaded: flag indicating need of writing current value to offset
71252984a8ddSEric Joyner  * @tx_offset: pointer to offset of TX LPI counter
71262984a8ddSEric Joyner  * @tx_stat: pointer to value of TX LPI counter
71272984a8ddSEric Joyner  * @rx_offset: pointer to offset of RX LPI counter
71282984a8ddSEric Joyner  * @rx_stat: pointer to value of RX LPI counter
71292984a8ddSEric Joyner  *
71302984a8ddSEric Joyner  * Update Low Power Idle (LPI) mode counters while having regard to passed
71312984a8ddSEric Joyner  * offsets.
71322984a8ddSEric Joyner  **/
i40e_lpi_stat_update(struct i40e_hw * hw,bool offset_loaded,u64 * tx_offset,u64 * tx_stat,u64 * rx_offset,u64 * rx_stat)71332984a8ddSEric Joyner enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw,
71342984a8ddSEric Joyner 					   bool offset_loaded, u64 *tx_offset,
71352984a8ddSEric Joyner 					   u64 *tx_stat, u64 *rx_offset,
71362984a8ddSEric Joyner 					   u64 *rx_stat)
71372984a8ddSEric Joyner {
71382984a8ddSEric Joyner 	enum i40e_status_code retval;
71392984a8ddSEric Joyner 	u32 tx_counter, rx_counter;
71402984a8ddSEric Joyner 	bool is_clear;
71412984a8ddSEric Joyner 
71422984a8ddSEric Joyner 	retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter, &is_clear);
71432984a8ddSEric Joyner 	if (retval)
71442984a8ddSEric Joyner 		goto err;
71452984a8ddSEric Joyner 
71462984a8ddSEric Joyner 	if (is_clear) {
71472984a8ddSEric Joyner 		*tx_stat += tx_counter;
71482984a8ddSEric Joyner 		*rx_stat += rx_counter;
71492984a8ddSEric Joyner 	} else {
71502984a8ddSEric Joyner 		if (!offset_loaded) {
71512984a8ddSEric Joyner 			*tx_offset = tx_counter;
71522984a8ddSEric Joyner 			*rx_offset = rx_counter;
71532984a8ddSEric Joyner 		}
71542984a8ddSEric Joyner 
71552984a8ddSEric Joyner 		*tx_stat = (tx_counter >= *tx_offset) ?
71562984a8ddSEric Joyner 			(u32)(tx_counter - *tx_offset) :
71572984a8ddSEric Joyner 			(u32)((tx_counter + BIT_ULL(32)) - *tx_offset);
71582984a8ddSEric Joyner 		*rx_stat = (rx_counter >= *rx_offset) ?
71592984a8ddSEric Joyner 			(u32)(rx_counter - *rx_offset) :
71602984a8ddSEric Joyner 			(u32)((rx_counter + BIT_ULL(32)) - *rx_offset);
71612984a8ddSEric Joyner 	}
71622984a8ddSEric Joyner err:
71632984a8ddSEric Joyner 	return retval;
71642984a8ddSEric Joyner }
71652984a8ddSEric Joyner 
71662984a8ddSEric Joyner /**
7167d4683565SEric Joyner  * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
7168d4683565SEric Joyner  * @hw: pointer to the hw struct
7169d4683565SEric Joyner  * @reg_addr: register address
7170d4683565SEric Joyner  * @reg_val: ptr to register value
7171d4683565SEric Joyner  * @cmd_details: pointer to command details structure or NULL
7172d4683565SEric Joyner  *
7173d4683565SEric Joyner  * Use the firmware to read the Rx control register,
7174d4683565SEric Joyner  * especially useful if the Rx unit is under heavy pressure
7175d4683565SEric Joyner  **/
i40e_aq_rx_ctl_read_register(struct i40e_hw * hw,u32 reg_addr,u32 * reg_val,struct i40e_asq_cmd_details * cmd_details)7176d4683565SEric Joyner enum i40e_status_code i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
7177d4683565SEric Joyner 				u32 reg_addr, u32 *reg_val,
7178d4683565SEric Joyner 				struct i40e_asq_cmd_details *cmd_details)
7179d4683565SEric Joyner {
7180d4683565SEric Joyner 	struct i40e_aq_desc desc;
7181d4683565SEric Joyner 	struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
7182d4683565SEric Joyner 		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7183d4683565SEric Joyner 	enum i40e_status_code status;
7184d4683565SEric Joyner 
7185d4683565SEric Joyner 	if (reg_val == NULL)
7186d4683565SEric Joyner 		return I40E_ERR_PARAM;
7187d4683565SEric Joyner 
7188d4683565SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
7189d4683565SEric Joyner 
7190d4683565SEric Joyner 	cmd_resp->address = CPU_TO_LE32(reg_addr);
7191d4683565SEric Joyner 
7192d4683565SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7193d4683565SEric Joyner 
7194d4683565SEric Joyner 	if (status == I40E_SUCCESS)
7195d4683565SEric Joyner 		*reg_val = LE32_TO_CPU(cmd_resp->value);
7196d4683565SEric Joyner 
7197d4683565SEric Joyner 	return status;
7198d4683565SEric Joyner }
7199d4683565SEric Joyner 
7200d4683565SEric Joyner /**
7201d4683565SEric Joyner  * i40e_read_rx_ctl - read from an Rx control register
7202d4683565SEric Joyner  * @hw: pointer to the hw struct
7203d4683565SEric Joyner  * @reg_addr: register address
7204d4683565SEric Joyner  **/
i40e_read_rx_ctl(struct i40e_hw * hw,u32 reg_addr)7205d4683565SEric Joyner u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
7206d4683565SEric Joyner {
7207d4683565SEric Joyner 	enum i40e_status_code status = I40E_SUCCESS;
7208d4683565SEric Joyner 	bool use_register;
7209d4683565SEric Joyner 	int retry = 5;
7210d4683565SEric Joyner 	u32 val = 0;
7211d4683565SEric Joyner 
7212ceebc2f3SEric Joyner 	use_register = (((hw->aq.api_maj_ver == 1) &&
7213ceebc2f3SEric Joyner 			(hw->aq.api_min_ver < 5)) ||
7214ceebc2f3SEric Joyner 			(hw->mac.type == I40E_MAC_X722));
7215d4683565SEric Joyner 	if (!use_register) {
7216d4683565SEric Joyner do_retry:
7217d4683565SEric Joyner 		status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
7218d4683565SEric Joyner 		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7219d4683565SEric Joyner 			i40e_msec_delay(1);
7220d4683565SEric Joyner 			retry--;
7221d4683565SEric Joyner 			goto do_retry;
7222d4683565SEric Joyner 		}
7223d4683565SEric Joyner 	}
7224d4683565SEric Joyner 
7225d4683565SEric Joyner 	/* if the AQ access failed, try the old-fashioned way */
7226d4683565SEric Joyner 	if (status || use_register)
7227d4683565SEric Joyner 		val = rd32(hw, reg_addr);
7228d4683565SEric Joyner 
7229d4683565SEric Joyner 	return val;
7230d4683565SEric Joyner }
7231d4683565SEric Joyner 
7232d4683565SEric Joyner /**
7233d4683565SEric Joyner  * i40e_aq_rx_ctl_write_register
7234d4683565SEric Joyner  * @hw: pointer to the hw struct
7235d4683565SEric Joyner  * @reg_addr: register address
7236d4683565SEric Joyner  * @reg_val: register value
7237d4683565SEric Joyner  * @cmd_details: pointer to command details structure or NULL
7238d4683565SEric Joyner  *
7239d4683565SEric Joyner  * Use the firmware to write to an Rx control register,
7240d4683565SEric Joyner  * especially useful if the Rx unit is under heavy pressure
7241d4683565SEric Joyner  **/
i40e_aq_rx_ctl_write_register(struct i40e_hw * hw,u32 reg_addr,u32 reg_val,struct i40e_asq_cmd_details * cmd_details)7242d4683565SEric Joyner enum i40e_status_code i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
7243d4683565SEric Joyner 				u32 reg_addr, u32 reg_val,
7244d4683565SEric Joyner 				struct i40e_asq_cmd_details *cmd_details)
7245d4683565SEric Joyner {
7246d4683565SEric Joyner 	struct i40e_aq_desc desc;
7247d4683565SEric Joyner 	struct i40e_aqc_rx_ctl_reg_read_write *cmd =
7248d4683565SEric Joyner 		(struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
7249d4683565SEric Joyner 	enum i40e_status_code status;
7250d4683565SEric Joyner 
7251d4683565SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
7252d4683565SEric Joyner 
7253d4683565SEric Joyner 	cmd->address = CPU_TO_LE32(reg_addr);
7254d4683565SEric Joyner 	cmd->value = CPU_TO_LE32(reg_val);
7255d4683565SEric Joyner 
7256d4683565SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7257d4683565SEric Joyner 
7258d4683565SEric Joyner 	return status;
7259d4683565SEric Joyner }
7260d4683565SEric Joyner 
7261d4683565SEric Joyner /**
7262d4683565SEric Joyner  * i40e_write_rx_ctl - write to an Rx control register
7263d4683565SEric Joyner  * @hw: pointer to the hw struct
7264d4683565SEric Joyner  * @reg_addr: register address
7265d4683565SEric Joyner  * @reg_val: register value
7266d4683565SEric Joyner  **/
i40e_write_rx_ctl(struct i40e_hw * hw,u32 reg_addr,u32 reg_val)7267d4683565SEric Joyner void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
7268d4683565SEric Joyner {
7269d4683565SEric Joyner 	enum i40e_status_code status = I40E_SUCCESS;
7270d4683565SEric Joyner 	bool use_register;
7271d4683565SEric Joyner 	int retry = 5;
7272d4683565SEric Joyner 
7273ceebc2f3SEric Joyner 	use_register = (((hw->aq.api_maj_ver == 1) &&
7274ceebc2f3SEric Joyner 			(hw->aq.api_min_ver < 5)) ||
7275ceebc2f3SEric Joyner 			(hw->mac.type == I40E_MAC_X722));
7276d4683565SEric Joyner 	if (!use_register) {
7277d4683565SEric Joyner do_retry:
7278d4683565SEric Joyner 		status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
7279d4683565SEric Joyner 						       reg_val, NULL);
7280d4683565SEric Joyner 		if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
7281d4683565SEric Joyner 			i40e_msec_delay(1);
7282d4683565SEric Joyner 			retry--;
7283d4683565SEric Joyner 			goto do_retry;
7284d4683565SEric Joyner 		}
7285d4683565SEric Joyner 	}
7286d4683565SEric Joyner 
7287d4683565SEric Joyner 	/* if the AQ access failed, try the old-fashioned way */
7288d4683565SEric Joyner 	if (status || use_register)
7289d4683565SEric Joyner 		wr32(hw, reg_addr, reg_val);
7290d4683565SEric Joyner }
7291d4683565SEric Joyner 
7292d4683565SEric Joyner /**
7293b4a7ce06SEric Joyner  * i40e_mdio_if_number_selection - MDIO I/F number selection
7294b4a7ce06SEric Joyner  * @hw: pointer to the hw struct
7295b4a7ce06SEric Joyner  * @set_mdio: use MDIO I/F number specified by mdio_num
7296b4a7ce06SEric Joyner  * @mdio_num: MDIO I/F number
7297b4a7ce06SEric Joyner  * @cmd: pointer to PHY Register command structure
7298b4a7ce06SEric Joyner  **/
7299b4a7ce06SEric Joyner static void
i40e_mdio_if_number_selection(struct i40e_hw * hw,bool set_mdio,u8 mdio_num,struct i40e_aqc_phy_register_access * cmd)7300b4a7ce06SEric Joyner i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio, u8 mdio_num,
7301b4a7ce06SEric Joyner 			      struct i40e_aqc_phy_register_access *cmd)
7302b4a7ce06SEric Joyner {
7303b4a7ce06SEric Joyner 	if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) {
7304b4a7ce06SEric Joyner 		if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED)
7305b4a7ce06SEric Joyner 			cmd->cmd_flags |=
7306b4a7ce06SEric Joyner 				I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER |
7307b4a7ce06SEric Joyner 				((mdio_num <<
7308b4a7ce06SEric Joyner 				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) &
7309b4a7ce06SEric Joyner 				I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK);
7310b4a7ce06SEric Joyner 		else
7311b4a7ce06SEric Joyner 			i40e_debug(hw, I40E_DEBUG_PHY,
7312b4a7ce06SEric Joyner 				   "MDIO I/F number selection not supported by current FW version.\n");
7313b4a7ce06SEric Joyner 	}
7314b4a7ce06SEric Joyner }
7315b4a7ce06SEric Joyner 
7316b4a7ce06SEric Joyner /**
7317b4a7ce06SEric Joyner  * i40e_aq_set_phy_register_ext
7318ceebc2f3SEric Joyner  * @hw: pointer to the hw struct
7319ceebc2f3SEric Joyner  * @phy_select: select which phy should be accessed
7320ceebc2f3SEric Joyner  * @dev_addr: PHY device address
7321b4a7ce06SEric Joyner  * @page_change: enable auto page change
7322b4a7ce06SEric Joyner  * @set_mdio: use MDIO I/F number specified by mdio_num
7323b4a7ce06SEric Joyner  * @mdio_num: MDIO I/F number
7324ceebc2f3SEric Joyner  * @reg_addr: PHY register address
7325ceebc2f3SEric Joyner  * @reg_val: new register value
7326ceebc2f3SEric Joyner  * @cmd_details: pointer to command details structure or NULL
7327ceebc2f3SEric Joyner  *
7328ceebc2f3SEric Joyner  * Write the external PHY register.
7329b4a7ce06SEric Joyner  * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7330b4a7ce06SEric Joyner  * may use simple wrapper i40e_aq_set_phy_register.
7331ceebc2f3SEric Joyner  **/
7332b4a7ce06SEric Joyner enum i40e_status_code
i40e_aq_set_phy_register_ext(struct i40e_hw * hw,u8 phy_select,u8 dev_addr,bool page_change,bool set_mdio,u8 mdio_num,u32 reg_addr,u32 reg_val,struct i40e_asq_cmd_details * cmd_details)7333b4a7ce06SEric Joyner i40e_aq_set_phy_register_ext(struct i40e_hw *hw,
7334b4a7ce06SEric Joyner 			     u8 phy_select, u8 dev_addr, bool page_change,
7335b4a7ce06SEric Joyner 			     bool set_mdio, u8 mdio_num,
7336ceebc2f3SEric Joyner 			     u32 reg_addr, u32 reg_val,
7337ceebc2f3SEric Joyner 			     struct i40e_asq_cmd_details *cmd_details)
7338ceebc2f3SEric Joyner {
7339ceebc2f3SEric Joyner 	struct i40e_aq_desc desc;
7340ceebc2f3SEric Joyner 	struct i40e_aqc_phy_register_access *cmd =
7341ceebc2f3SEric Joyner 		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
7342ceebc2f3SEric Joyner 	enum i40e_status_code status;
7343ceebc2f3SEric Joyner 
7344ceebc2f3SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
7345ceebc2f3SEric Joyner 					  i40e_aqc_opc_set_phy_register);
7346ceebc2f3SEric Joyner 
7347ceebc2f3SEric Joyner 	cmd->phy_interface = phy_select;
7348ceebc2f3SEric Joyner 	cmd->dev_addres = dev_addr;
7349ceebc2f3SEric Joyner 	cmd->reg_address = CPU_TO_LE32(reg_addr);
7350ceebc2f3SEric Joyner 	cmd->reg_value = CPU_TO_LE32(reg_val);
7351ceebc2f3SEric Joyner 
7352b4a7ce06SEric Joyner 	if (!page_change)
7353b4a7ce06SEric Joyner 		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7354b4a7ce06SEric Joyner 
7355b4a7ce06SEric Joyner 	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7356b4a7ce06SEric Joyner 
7357ceebc2f3SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7358ceebc2f3SEric Joyner 
7359ceebc2f3SEric Joyner 	return status;
7360ceebc2f3SEric Joyner }
7361ceebc2f3SEric Joyner 
7362ceebc2f3SEric Joyner /**
7363b4a7ce06SEric Joyner  * i40e_aq_get_phy_register_ext
7364ceebc2f3SEric Joyner  * @hw: pointer to the hw struct
7365ceebc2f3SEric Joyner  * @phy_select: select which phy should be accessed
7366ceebc2f3SEric Joyner  * @dev_addr: PHY device address
7367b4a7ce06SEric Joyner  * @page_change: enable auto page change
7368b4a7ce06SEric Joyner  * @set_mdio: use MDIO I/F number specified by mdio_num
7369b4a7ce06SEric Joyner  * @mdio_num: MDIO I/F number
7370ceebc2f3SEric Joyner  * @reg_addr: PHY register address
7371ceebc2f3SEric Joyner  * @reg_val: read register value
7372ceebc2f3SEric Joyner  * @cmd_details: pointer to command details structure or NULL
7373ceebc2f3SEric Joyner  *
7374ceebc2f3SEric Joyner  * Read the external PHY register.
7375b4a7ce06SEric Joyner  * NOTE: In common cases MDIO I/F number should not be changed, thats why you
7376b4a7ce06SEric Joyner  * may use simple wrapper i40e_aq_get_phy_register.
7377ceebc2f3SEric Joyner  **/
7378b4a7ce06SEric Joyner enum i40e_status_code
i40e_aq_get_phy_register_ext(struct i40e_hw * hw,u8 phy_select,u8 dev_addr,bool page_change,bool set_mdio,u8 mdio_num,u32 reg_addr,u32 * reg_val,struct i40e_asq_cmd_details * cmd_details)7379b4a7ce06SEric Joyner i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
7380b4a7ce06SEric Joyner 			     u8 phy_select, u8 dev_addr, bool page_change,
7381b4a7ce06SEric Joyner 			     bool set_mdio, u8 mdio_num,
7382ceebc2f3SEric Joyner 			     u32 reg_addr, u32 *reg_val,
7383ceebc2f3SEric Joyner 			     struct i40e_asq_cmd_details *cmd_details)
7384ceebc2f3SEric Joyner {
7385ceebc2f3SEric Joyner 	struct i40e_aq_desc desc;
7386ceebc2f3SEric Joyner 	struct i40e_aqc_phy_register_access *cmd =
7387ceebc2f3SEric Joyner 		(struct i40e_aqc_phy_register_access *)&desc.params.raw;
7388ceebc2f3SEric Joyner 	enum i40e_status_code status;
7389ceebc2f3SEric Joyner 
7390ceebc2f3SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
7391ceebc2f3SEric Joyner 					  i40e_aqc_opc_get_phy_register);
7392ceebc2f3SEric Joyner 
7393ceebc2f3SEric Joyner 	cmd->phy_interface = phy_select;
7394ceebc2f3SEric Joyner 	cmd->dev_addres = dev_addr;
7395ceebc2f3SEric Joyner 	cmd->reg_address = CPU_TO_LE32(reg_addr);
7396ceebc2f3SEric Joyner 
7397b4a7ce06SEric Joyner 	if (!page_change)
7398b4a7ce06SEric Joyner 		cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE;
7399b4a7ce06SEric Joyner 
7400b4a7ce06SEric Joyner 	i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd);
7401b4a7ce06SEric Joyner 
7402ceebc2f3SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7403ceebc2f3SEric Joyner 	if (!status)
7404ceebc2f3SEric Joyner 		*reg_val = LE32_TO_CPU(cmd->reg_value);
7405ceebc2f3SEric Joyner 
7406ceebc2f3SEric Joyner 	return status;
7407ceebc2f3SEric Joyner }
7408ceebc2f3SEric Joyner 
7409ceebc2f3SEric Joyner /**
74102984a8ddSEric Joyner  * i40e_aq_run_phy_activity
74112984a8ddSEric Joyner  * @hw: pointer to the hw struct
74122984a8ddSEric Joyner  * @activity_id: ID of DNL activity to run
74132984a8ddSEric Joyner  * @dnl_opcode: opcode passed to DNL script
74142984a8ddSEric Joyner  * @cmd_status: pointer to memory to write return value of DNL script
74152984a8ddSEric Joyner  * @data0: pointer to memory for first 4 bytes of data returned by DNL script
74162984a8ddSEric Joyner  * @data1: pointer to memory for last 4 bytes of data returned by DNL script
74172984a8ddSEric Joyner  * @cmd_details: pointer to command details structure or NULL
74182984a8ddSEric Joyner  *
74192984a8ddSEric Joyner  * Run DNL admin command.
74202984a8ddSEric Joyner  **/
74212984a8ddSEric Joyner enum i40e_status_code
i40e_aq_run_phy_activity(struct i40e_hw * hw,u16 activity_id,u32 dnl_opcode,u32 * cmd_status,u32 * data0,u32 * data1,struct i40e_asq_cmd_details * cmd_details)74222984a8ddSEric Joyner i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 dnl_opcode,
74232984a8ddSEric Joyner 			 u32 *cmd_status, u32 *data0, u32 *data1,
74242984a8ddSEric Joyner 			 struct i40e_asq_cmd_details *cmd_details)
74252984a8ddSEric Joyner {
74262984a8ddSEric Joyner 	struct i40e_aqc_run_phy_activity *cmd;
74272984a8ddSEric Joyner 	enum i40e_status_code retval;
74282984a8ddSEric Joyner 	struct i40e_aq_desc desc;
74292984a8ddSEric Joyner 
74302984a8ddSEric Joyner 	cmd = (struct i40e_aqc_run_phy_activity *)&desc.params.raw;
74312984a8ddSEric Joyner 
74322984a8ddSEric Joyner 	if (!cmd_status || !data0 || !data1) {
74332984a8ddSEric Joyner 		retval = I40E_ERR_PARAM;
74342984a8ddSEric Joyner 		goto err;
74352984a8ddSEric Joyner 	}
74362984a8ddSEric Joyner 
74372984a8ddSEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
74382984a8ddSEric Joyner 					  i40e_aqc_opc_run_phy_activity);
74392984a8ddSEric Joyner 
74402984a8ddSEric Joyner 	cmd->activity_id = CPU_TO_LE16(activity_id);
74412984a8ddSEric Joyner 	cmd->params.cmd.dnl_opcode = CPU_TO_LE32(dnl_opcode);
74422984a8ddSEric Joyner 
74432984a8ddSEric Joyner 	retval = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
74442984a8ddSEric Joyner 	if (retval)
74452984a8ddSEric Joyner 		goto err;
74462984a8ddSEric Joyner 
74472984a8ddSEric Joyner 	*cmd_status = LE32_TO_CPU(cmd->params.resp.cmd_status);
74482984a8ddSEric Joyner 	*data0 = LE32_TO_CPU(cmd->params.resp.data0);
74492984a8ddSEric Joyner 	*data1 = LE32_TO_CPU(cmd->params.resp.data1);
74502984a8ddSEric Joyner err:
74512984a8ddSEric Joyner 	return retval;
74522984a8ddSEric Joyner }
74532984a8ddSEric Joyner 
74542984a8ddSEric Joyner 
74552984a8ddSEric Joyner /**
745661ae650dSJack F Vogel  * i40e_aq_send_msg_to_pf
745761ae650dSJack F Vogel  * @hw: pointer to the hardware structure
745861ae650dSJack F Vogel  * @v_opcode: opcodes for VF-PF communication
745961ae650dSJack F Vogel  * @v_retval: return error code
746061ae650dSJack F Vogel  * @msg: pointer to the msg buffer
746161ae650dSJack F Vogel  * @msglen: msg length
746261ae650dSJack F Vogel  * @cmd_details: pointer to command details
746361ae650dSJack F Vogel  *
746461ae650dSJack F Vogel  * Send message to PF driver using admin queue. By default, this message
746561ae650dSJack F Vogel  * is sent asynchronously, i.e. i40e_asq_send_command() does not wait for
746661ae650dSJack F Vogel  * completion before returning.
746761ae650dSJack F Vogel  **/
i40e_aq_send_msg_to_pf(struct i40e_hw * hw,enum virtchnl_ops v_opcode,enum i40e_status_code v_retval,u8 * msg,u16 msglen,struct i40e_asq_cmd_details * cmd_details)746861ae650dSJack F Vogel enum i40e_status_code i40e_aq_send_msg_to_pf(struct i40e_hw *hw,
7469ceebc2f3SEric Joyner 				enum virtchnl_ops v_opcode,
747061ae650dSJack F Vogel 				enum i40e_status_code v_retval,
747161ae650dSJack F Vogel 				u8 *msg, u16 msglen,
747261ae650dSJack F Vogel 				struct i40e_asq_cmd_details *cmd_details)
747361ae650dSJack F Vogel {
747461ae650dSJack F Vogel 	struct i40e_aq_desc desc;
747561ae650dSJack F Vogel 	struct i40e_asq_cmd_details details;
747661ae650dSJack F Vogel 	enum i40e_status_code status;
747761ae650dSJack F Vogel 
747861ae650dSJack F Vogel 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf);
747961ae650dSJack F Vogel 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_SI);
748061ae650dSJack F Vogel 	desc.cookie_high = CPU_TO_LE32(v_opcode);
748161ae650dSJack F Vogel 	desc.cookie_low = CPU_TO_LE32(v_retval);
748261ae650dSJack F Vogel 	if (msglen) {
748361ae650dSJack F Vogel 		desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF
748461ae650dSJack F Vogel 						| I40E_AQ_FLAG_RD));
748561ae650dSJack F Vogel 		if (msglen > I40E_AQ_LARGE_BUF)
748661ae650dSJack F Vogel 			desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
748761ae650dSJack F Vogel 		desc.datalen = CPU_TO_LE16(msglen);
748861ae650dSJack F Vogel 	}
748961ae650dSJack F Vogel 	if (!cmd_details) {
749061ae650dSJack F Vogel 		i40e_memset(&details, 0, sizeof(details), I40E_NONDMA_MEM);
749161ae650dSJack F Vogel 		details.async = TRUE;
749261ae650dSJack F Vogel 		cmd_details = &details;
749361ae650dSJack F Vogel 	}
749461ae650dSJack F Vogel 	status = i40e_asq_send_command(hw, (struct i40e_aq_desc *)&desc, msg,
749561ae650dSJack F Vogel 				       msglen, cmd_details);
749661ae650dSJack F Vogel 	return status;
749761ae650dSJack F Vogel }
749861ae650dSJack F Vogel 
749961ae650dSJack F Vogel /**
750061ae650dSJack F Vogel  * i40e_vf_parse_hw_config
750161ae650dSJack F Vogel  * @hw: pointer to the hardware structure
750261ae650dSJack F Vogel  * @msg: pointer to the virtual channel VF resource structure
750361ae650dSJack F Vogel  *
750461ae650dSJack F Vogel  * Given a VF resource message from the PF, populate the hw struct
750561ae650dSJack F Vogel  * with appropriate information.
750661ae650dSJack F Vogel  **/
i40e_vf_parse_hw_config(struct i40e_hw * hw,struct virtchnl_vf_resource * msg)750761ae650dSJack F Vogel void i40e_vf_parse_hw_config(struct i40e_hw *hw,
7508ceebc2f3SEric Joyner 			     struct virtchnl_vf_resource *msg)
750961ae650dSJack F Vogel {
7510ceebc2f3SEric Joyner 	struct virtchnl_vsi_resource *vsi_res;
751161ae650dSJack F Vogel 	int i;
751261ae650dSJack F Vogel 
751361ae650dSJack F Vogel 	vsi_res = &msg->vsi_res[0];
751461ae650dSJack F Vogel 
751561ae650dSJack F Vogel 	hw->dev_caps.num_vsis = msg->num_vsis;
751661ae650dSJack F Vogel 	hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
751761ae650dSJack F Vogel 	hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
751861ae650dSJack F Vogel 	hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
7519ceebc2f3SEric Joyner 	hw->dev_caps.dcb = msg->vf_cap_flags &
7520ceebc2f3SEric Joyner 			   VIRTCHNL_VF_OFFLOAD_L2;
7521ceebc2f3SEric Joyner 	hw->dev_caps.iwarp = (msg->vf_cap_flags &
7522ceebc2f3SEric Joyner 			      VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
752361ae650dSJack F Vogel 	for (i = 0; i < msg->num_vsis; i++) {
7524ceebc2f3SEric Joyner 		if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
752561ae650dSJack F Vogel 			i40e_memcpy(hw->mac.perm_addr,
752661ae650dSJack F Vogel 				    vsi_res->default_mac_addr,
7527ceebc2f3SEric Joyner 				    ETH_ALEN,
752861ae650dSJack F Vogel 				    I40E_NONDMA_TO_NONDMA);
752961ae650dSJack F Vogel 			i40e_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
7530ceebc2f3SEric Joyner 				    ETH_ALEN,
753161ae650dSJack F Vogel 				    I40E_NONDMA_TO_NONDMA);
753261ae650dSJack F Vogel 		}
753361ae650dSJack F Vogel 		vsi_res++;
753461ae650dSJack F Vogel 	}
753561ae650dSJack F Vogel }
753661ae650dSJack F Vogel 
753761ae650dSJack F Vogel /**
753861ae650dSJack F Vogel  * i40e_vf_reset
753961ae650dSJack F Vogel  * @hw: pointer to the hardware structure
754061ae650dSJack F Vogel  *
754161ae650dSJack F Vogel  * Send a VF_RESET message to the PF. Does not wait for response from PF
754261ae650dSJack F Vogel  * as none will be forthcoming. Immediately after calling this function,
754361ae650dSJack F Vogel  * the admin queue should be shut down and (optionally) reinitialized.
754461ae650dSJack F Vogel  **/
i40e_vf_reset(struct i40e_hw * hw)754561ae650dSJack F Vogel enum i40e_status_code i40e_vf_reset(struct i40e_hw *hw)
754661ae650dSJack F Vogel {
7547ceebc2f3SEric Joyner 	return i40e_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
754861ae650dSJack F Vogel 				      I40E_SUCCESS, NULL, 0, NULL);
754961ae650dSJack F Vogel }
75504294f337SSean Bruno 
75514294f337SSean Bruno /**
75524294f337SSean Bruno  * i40e_aq_set_arp_proxy_config
75534294f337SSean Bruno  * @hw: pointer to the HW structure
7554ceebc2f3SEric Joyner  * @proxy_config: pointer to proxy config command table struct
75554294f337SSean Bruno  * @cmd_details: pointer to command details
75564294f337SSean Bruno  *
75574294f337SSean Bruno  * Set ARP offload parameters from pre-populated
75584294f337SSean Bruno  * i40e_aqc_arp_proxy_data struct
75594294f337SSean Bruno  **/
i40e_aq_set_arp_proxy_config(struct i40e_hw * hw,struct i40e_aqc_arp_proxy_data * proxy_config,struct i40e_asq_cmd_details * cmd_details)75604294f337SSean Bruno enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
75614294f337SSean Bruno 				struct i40e_aqc_arp_proxy_data *proxy_config,
75624294f337SSean Bruno 				struct i40e_asq_cmd_details *cmd_details)
75634294f337SSean Bruno {
75644294f337SSean Bruno 	struct i40e_aq_desc desc;
75654294f337SSean Bruno 	enum i40e_status_code status;
75664294f337SSean Bruno 
75674294f337SSean Bruno 	if (!proxy_config)
75684294f337SSean Bruno 		return I40E_ERR_PARAM;
75694294f337SSean Bruno 
75704294f337SSean Bruno 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_proxy_config);
75714294f337SSean Bruno 
7572cb6b8299SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7573cb6b8299SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
75744294f337SSean Bruno 	desc.params.external.addr_high =
75754294f337SSean Bruno 				  CPU_TO_LE32(I40E_HI_DWORD((u64)proxy_config));
75764294f337SSean Bruno 	desc.params.external.addr_low =
75774294f337SSean Bruno 				  CPU_TO_LE32(I40E_LO_DWORD((u64)proxy_config));
7578cb6b8299SEric Joyner 	desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_arp_proxy_data));
75794294f337SSean Bruno 
75804294f337SSean Bruno 	status = i40e_asq_send_command(hw, &desc, proxy_config,
75814294f337SSean Bruno 				       sizeof(struct i40e_aqc_arp_proxy_data),
75824294f337SSean Bruno 				       cmd_details);
75834294f337SSean Bruno 
75844294f337SSean Bruno 	return status;
75854294f337SSean Bruno }
75864294f337SSean Bruno 
75874294f337SSean Bruno /**
7588abf77452SKrzysztof Galazka  * i40e_aq_set_ns_proxy_table_entry
75894294f337SSean Bruno  * @hw: pointer to the HW structure
75904294f337SSean Bruno  * @ns_proxy_table_entry: pointer to NS table entry command struct
75914294f337SSean Bruno  * @cmd_details: pointer to command details
75924294f337SSean Bruno  *
75934294f337SSean Bruno  * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
75944294f337SSean Bruno  * from pre-populated i40e_aqc_ns_proxy_data struct
75954294f337SSean Bruno  **/
i40e_aq_set_ns_proxy_table_entry(struct i40e_hw * hw,struct i40e_aqc_ns_proxy_data * ns_proxy_table_entry,struct i40e_asq_cmd_details * cmd_details)75964294f337SSean Bruno enum i40e_status_code i40e_aq_set_ns_proxy_table_entry(struct i40e_hw *hw,
75974294f337SSean Bruno 			struct i40e_aqc_ns_proxy_data *ns_proxy_table_entry,
75984294f337SSean Bruno 			struct i40e_asq_cmd_details *cmd_details)
75994294f337SSean Bruno {
76004294f337SSean Bruno 	struct i40e_aq_desc desc;
76014294f337SSean Bruno 	enum i40e_status_code status;
76024294f337SSean Bruno 
76034294f337SSean Bruno 	if (!ns_proxy_table_entry)
76044294f337SSean Bruno 		return I40E_ERR_PARAM;
76054294f337SSean Bruno 
76064294f337SSean Bruno 	i40e_fill_default_direct_cmd_desc(&desc,
76074294f337SSean Bruno 				i40e_aqc_opc_set_ns_proxy_table_entry);
76084294f337SSean Bruno 
7609cb6b8299SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7610cb6b8299SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
76114294f337SSean Bruno 	desc.params.external.addr_high =
76124294f337SSean Bruno 		CPU_TO_LE32(I40E_HI_DWORD((u64)ns_proxy_table_entry));
76134294f337SSean Bruno 	desc.params.external.addr_low =
76144294f337SSean Bruno 		CPU_TO_LE32(I40E_LO_DWORD((u64)ns_proxy_table_entry));
7615cb6b8299SEric Joyner 	desc.datalen = CPU_TO_LE16(sizeof(struct i40e_aqc_ns_proxy_data));
76164294f337SSean Bruno 
76174294f337SSean Bruno 	status = i40e_asq_send_command(hw, &desc, ns_proxy_table_entry,
76184294f337SSean Bruno 				       sizeof(struct i40e_aqc_ns_proxy_data),
76194294f337SSean Bruno 				       cmd_details);
76204294f337SSean Bruno 
76214294f337SSean Bruno 	return status;
76224294f337SSean Bruno }
76234294f337SSean Bruno 
76244294f337SSean Bruno /**
76254294f337SSean Bruno  * i40e_aq_set_clear_wol_filter
76264294f337SSean Bruno  * @hw: pointer to the hw struct
76274294f337SSean Bruno  * @filter_index: index of filter to modify (0-7)
76284294f337SSean Bruno  * @filter: buffer containing filter to be set
76294294f337SSean Bruno  * @set_filter: TRUE to set filter, FALSE to clear filter
76304294f337SSean Bruno  * @no_wol_tco: if TRUE, pass through packets cannot cause wake-up
76314294f337SSean Bruno  *		if FALSE, pass through packets may cause wake-up
76324294f337SSean Bruno  * @filter_valid: TRUE if filter action is valid
76334294f337SSean Bruno  * @no_wol_tco_valid: TRUE if no WoL in TCO traffic action valid
76344294f337SSean Bruno  * @cmd_details: pointer to command details structure or NULL
76354294f337SSean Bruno  *
76364294f337SSean Bruno  * Set or clear WoL filter for port attached to the PF
76374294f337SSean Bruno  **/
i40e_aq_set_clear_wol_filter(struct i40e_hw * hw,u8 filter_index,struct i40e_aqc_set_wol_filter_data * filter,bool set_filter,bool no_wol_tco,bool filter_valid,bool no_wol_tco_valid,struct i40e_asq_cmd_details * cmd_details)76384294f337SSean Bruno enum i40e_status_code i40e_aq_set_clear_wol_filter(struct i40e_hw *hw,
76394294f337SSean Bruno 				u8 filter_index,
76404294f337SSean Bruno 				struct i40e_aqc_set_wol_filter_data *filter,
76414294f337SSean Bruno 				bool set_filter, bool no_wol_tco,
76424294f337SSean Bruno 				bool filter_valid, bool no_wol_tco_valid,
76434294f337SSean Bruno 				struct i40e_asq_cmd_details *cmd_details)
76444294f337SSean Bruno {
76454294f337SSean Bruno 	struct i40e_aq_desc desc;
76464294f337SSean Bruno 	struct i40e_aqc_set_wol_filter *cmd =
76474294f337SSean Bruno 		(struct i40e_aqc_set_wol_filter *)&desc.params.raw;
76484294f337SSean Bruno 	enum i40e_status_code status;
76494294f337SSean Bruno 	u16 cmd_flags = 0;
76504294f337SSean Bruno 	u16 valid_flags = 0;
76514294f337SSean Bruno 	u16 buff_len = 0;
76524294f337SSean Bruno 
76534294f337SSean Bruno 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_wol_filter);
76544294f337SSean Bruno 
76554294f337SSean Bruno 	if (filter_index >= I40E_AQC_MAX_NUM_WOL_FILTERS)
76564294f337SSean Bruno 		return  I40E_ERR_PARAM;
76574294f337SSean Bruno 	cmd->filter_index = CPU_TO_LE16(filter_index);
76584294f337SSean Bruno 
76594294f337SSean Bruno 	if (set_filter) {
76604294f337SSean Bruno 		if (!filter)
76614294f337SSean Bruno 			return  I40E_ERR_PARAM;
7662cb6b8299SEric Joyner 
76634294f337SSean Bruno 		cmd_flags |= I40E_AQC_SET_WOL_FILTER;
7664cb6b8299SEric Joyner 		cmd_flags |= I40E_AQC_SET_WOL_FILTER_WOL_PRESERVE_ON_PFR;
76654294f337SSean Bruno 	}
7666cb6b8299SEric Joyner 
76674294f337SSean Bruno 	if (no_wol_tco)
76684294f337SSean Bruno 		cmd_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_WOL;
76694294f337SSean Bruno 	cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
76704294f337SSean Bruno 
76714294f337SSean Bruno 	if (filter_valid)
76724294f337SSean Bruno 		valid_flags |= I40E_AQC_SET_WOL_FILTER_ACTION_VALID;
76734294f337SSean Bruno 	if (no_wol_tco_valid)
76744294f337SSean Bruno 		valid_flags |= I40E_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
76754294f337SSean Bruno 	cmd->valid_flags = CPU_TO_LE16(valid_flags);
76764294f337SSean Bruno 
7677cb6b8299SEric Joyner 	buff_len = sizeof(*filter);
7678cb6b8299SEric Joyner 	desc.datalen = CPU_TO_LE16(buff_len);
7679cb6b8299SEric Joyner 
7680cb6b8299SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
7681cb6b8299SEric Joyner 	desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
7682cb6b8299SEric Joyner 
76834294f337SSean Bruno 	cmd->address_high = CPU_TO_LE32(I40E_HI_DWORD((u64)filter));
76844294f337SSean Bruno 	cmd->address_low = CPU_TO_LE32(I40E_LO_DWORD((u64)filter));
76854294f337SSean Bruno 
76864294f337SSean Bruno 	status = i40e_asq_send_command(hw, &desc, filter,
76874294f337SSean Bruno 				       buff_len, cmd_details);
76884294f337SSean Bruno 
76894294f337SSean Bruno 	return status;
76904294f337SSean Bruno }
76914294f337SSean Bruno 
76924294f337SSean Bruno /**
76934294f337SSean Bruno  * i40e_aq_get_wake_event_reason
76944294f337SSean Bruno  * @hw: pointer to the hw struct
76954294f337SSean Bruno  * @wake_reason: return value, index of matching filter
76964294f337SSean Bruno  * @cmd_details: pointer to command details structure or NULL
76974294f337SSean Bruno  *
76984294f337SSean Bruno  * Get information for the reason of a Wake Up event
76994294f337SSean Bruno  **/
i40e_aq_get_wake_event_reason(struct i40e_hw * hw,u16 * wake_reason,struct i40e_asq_cmd_details * cmd_details)77004294f337SSean Bruno enum i40e_status_code i40e_aq_get_wake_event_reason(struct i40e_hw *hw,
77014294f337SSean Bruno 				u16 *wake_reason,
77024294f337SSean Bruno 				struct i40e_asq_cmd_details *cmd_details)
77034294f337SSean Bruno {
77044294f337SSean Bruno 	struct i40e_aq_desc desc;
77054294f337SSean Bruno 	struct i40e_aqc_get_wake_reason_completion *resp =
77064294f337SSean Bruno 		(struct i40e_aqc_get_wake_reason_completion *)&desc.params.raw;
77074294f337SSean Bruno 	enum i40e_status_code status;
77084294f337SSean Bruno 
77094294f337SSean Bruno 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_wake_reason);
77104294f337SSean Bruno 
77114294f337SSean Bruno 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
77124294f337SSean Bruno 
77134294f337SSean Bruno 	if (status == I40E_SUCCESS)
77144294f337SSean Bruno 		*wake_reason = LE16_TO_CPU(resp->wake_reason);
77154294f337SSean Bruno 
77164294f337SSean Bruno 	return status;
77174294f337SSean Bruno }
77184294f337SSean Bruno 
7719cb6b8299SEric Joyner /**
7720cb6b8299SEric Joyner * i40e_aq_clear_all_wol_filters
7721cb6b8299SEric Joyner * @hw: pointer to the hw struct
7722cb6b8299SEric Joyner * @cmd_details: pointer to command details structure or NULL
7723cb6b8299SEric Joyner *
7724cb6b8299SEric Joyner * Get information for the reason of a Wake Up event
7725cb6b8299SEric Joyner **/
i40e_aq_clear_all_wol_filters(struct i40e_hw * hw,struct i40e_asq_cmd_details * cmd_details)7726cb6b8299SEric Joyner enum i40e_status_code i40e_aq_clear_all_wol_filters(struct i40e_hw *hw,
7727cb6b8299SEric Joyner 	struct i40e_asq_cmd_details *cmd_details)
7728cb6b8299SEric Joyner {
7729cb6b8299SEric Joyner 	struct i40e_aq_desc desc;
7730cb6b8299SEric Joyner 	enum i40e_status_code status;
7731cb6b8299SEric Joyner 
7732cb6b8299SEric Joyner 	i40e_fill_default_direct_cmd_desc(&desc,
7733cb6b8299SEric Joyner 					  i40e_aqc_opc_clear_all_wol_filters);
7734cb6b8299SEric Joyner 
7735cb6b8299SEric Joyner 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
7736cb6b8299SEric Joyner 
7737cb6b8299SEric Joyner 	return status;
7738cb6b8299SEric Joyner }
7739cb6b8299SEric Joyner 
7740