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