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