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