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