blob: 8d0ee006606b153c159d863d66a55a81c1d9ce0b [file] [log] [blame]
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001/*******************************************************************************
2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver
Shannon Nelson67be6eb2016-01-13 16:51:40 -08004 * Copyright(c) 2013 - 2016 Intel Corporation.
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00005 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
Greg Rosedc641b72013-12-18 13:45:51 +000015 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +000017 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 ******************************************************************************/
26
27#include "i40e_type.h"
28#include "i40e_adminq.h"
29#include "i40e_prototype.h"
Jesse Brandeburg55cdfd42017-05-11 11:23:10 -070030#include <linux/avf/virtchnl.h>
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +000031
32/**
33 * i40e_set_mac_type - Sets MAC type
34 * @hw: pointer to the HW structure
35 *
36 * This function sets the mac type of the adapter based on the
37 * vendor ID and device ID stored in the hw structure.
38 **/
39static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
40{
41 i40e_status status = 0;
42
43 if (hw->vendor_id == PCI_VENDOR_ID_INTEL) {
44 switch (hw->device_id) {
Shannon Nelsonab600852014-01-17 15:36:39 -080045 case I40E_DEV_ID_SFP_XL710:
Shannon Nelsonab600852014-01-17 15:36:39 -080046 case I40E_DEV_ID_QEMU:
Shannon Nelsonab600852014-01-17 15:36:39 -080047 case I40E_DEV_ID_KX_B:
48 case I40E_DEV_ID_KX_C:
Shannon Nelsonab600852014-01-17 15:36:39 -080049 case I40E_DEV_ID_QSFP_A:
50 case I40E_DEV_ID_QSFP_B:
51 case I40E_DEV_ID_QSFP_C:
Mitch Williams5960d332014-09-13 07:40:47 +000052 case I40E_DEV_ID_10G_BASE_T:
Shannon Nelsonbc5166b92015-08-26 15:14:10 -040053 case I40E_DEV_ID_10G_BASE_T4:
Jesse Brandeburgae24b402015-03-27 00:12:09 -070054 case I40E_DEV_ID_20G_KR2:
Shannon Nelson48a3b512015-07-23 16:54:39 -040055 case I40E_DEV_ID_20G_KR2_A:
Carolyn Wyborny31232372016-11-21 13:03:48 -080056 case I40E_DEV_ID_25G_B:
57 case I40E_DEV_ID_25G_SFP28:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +000058 hw->mac.type = I40E_MAC_XL710;
59 break;
Anjali Singhai Jain35dae512015-12-22 14:25:03 -080060 case I40E_DEV_ID_KX_X722:
61 case I40E_DEV_ID_QSFP_X722:
Anjali Singhai Jain87e6c1d2015-06-05 12:20:25 -040062 case I40E_DEV_ID_SFP_X722:
63 case I40E_DEV_ID_1G_BASE_T_X722:
64 case I40E_DEV_ID_10G_BASE_T_X722:
Catherine Sullivand6bf58c2016-03-18 12:18:08 -070065 case I40E_DEV_ID_SFP_I_X722:
Anjali Singhai Jain87e6c1d2015-06-05 12:20:25 -040066 hw->mac.type = I40E_MAC_X722;
67 break;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +000068 default:
69 hw->mac.type = I40E_MAC_GENERIC;
70 break;
71 }
72 } else {
73 status = I40E_ERR_DEVICE_NOT_SUPPORTED;
74 }
75
76 hw_dbg(hw, "i40e_set_mac_type found mac: %d, returns: %d\n",
77 hw->mac.type, status);
78 return status;
79}
80
81/**
Shannon Nelsonf1c7e722015-06-04 16:24:01 -040082 * i40e_aq_str - convert AQ err code to a string
83 * @hw: pointer to the HW structure
84 * @aq_err: the AQ error code to convert
85 **/
Jingjing Wu4e68adfe2015-09-28 14:12:31 -040086const char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err)
Shannon Nelsonf1c7e722015-06-04 16:24:01 -040087{
88 switch (aq_err) {
89 case I40E_AQ_RC_OK:
90 return "OK";
91 case I40E_AQ_RC_EPERM:
92 return "I40E_AQ_RC_EPERM";
93 case I40E_AQ_RC_ENOENT:
94 return "I40E_AQ_RC_ENOENT";
95 case I40E_AQ_RC_ESRCH:
96 return "I40E_AQ_RC_ESRCH";
97 case I40E_AQ_RC_EINTR:
98 return "I40E_AQ_RC_EINTR";
99 case I40E_AQ_RC_EIO:
100 return "I40E_AQ_RC_EIO";
101 case I40E_AQ_RC_ENXIO:
102 return "I40E_AQ_RC_ENXIO";
103 case I40E_AQ_RC_E2BIG:
104 return "I40E_AQ_RC_E2BIG";
105 case I40E_AQ_RC_EAGAIN:
106 return "I40E_AQ_RC_EAGAIN";
107 case I40E_AQ_RC_ENOMEM:
108 return "I40E_AQ_RC_ENOMEM";
109 case I40E_AQ_RC_EACCES:
110 return "I40E_AQ_RC_EACCES";
111 case I40E_AQ_RC_EFAULT:
112 return "I40E_AQ_RC_EFAULT";
113 case I40E_AQ_RC_EBUSY:
114 return "I40E_AQ_RC_EBUSY";
115 case I40E_AQ_RC_EEXIST:
116 return "I40E_AQ_RC_EEXIST";
117 case I40E_AQ_RC_EINVAL:
118 return "I40E_AQ_RC_EINVAL";
119 case I40E_AQ_RC_ENOTTY:
120 return "I40E_AQ_RC_ENOTTY";
121 case I40E_AQ_RC_ENOSPC:
122 return "I40E_AQ_RC_ENOSPC";
123 case I40E_AQ_RC_ENOSYS:
124 return "I40E_AQ_RC_ENOSYS";
125 case I40E_AQ_RC_ERANGE:
126 return "I40E_AQ_RC_ERANGE";
127 case I40E_AQ_RC_EFLUSHED:
128 return "I40E_AQ_RC_EFLUSHED";
129 case I40E_AQ_RC_BAD_ADDR:
130 return "I40E_AQ_RC_BAD_ADDR";
131 case I40E_AQ_RC_EMODE:
132 return "I40E_AQ_RC_EMODE";
133 case I40E_AQ_RC_EFBIG:
134 return "I40E_AQ_RC_EFBIG";
135 }
136
137 snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
138 return hw->err_str;
139}
140
141/**
142 * i40e_stat_str - convert status err code to a string
143 * @hw: pointer to the HW structure
144 * @stat_err: the status error code to convert
145 **/
Jingjing Wu4e68adfe2015-09-28 14:12:31 -0400146const char *i40e_stat_str(struct i40e_hw *hw, i40e_status stat_err)
Shannon Nelsonf1c7e722015-06-04 16:24:01 -0400147{
148 switch (stat_err) {
149 case 0:
150 return "OK";
151 case I40E_ERR_NVM:
152 return "I40E_ERR_NVM";
153 case I40E_ERR_NVM_CHECKSUM:
154 return "I40E_ERR_NVM_CHECKSUM";
155 case I40E_ERR_PHY:
156 return "I40E_ERR_PHY";
157 case I40E_ERR_CONFIG:
158 return "I40E_ERR_CONFIG";
159 case I40E_ERR_PARAM:
160 return "I40E_ERR_PARAM";
161 case I40E_ERR_MAC_TYPE:
162 return "I40E_ERR_MAC_TYPE";
163 case I40E_ERR_UNKNOWN_PHY:
164 return "I40E_ERR_UNKNOWN_PHY";
165 case I40E_ERR_LINK_SETUP:
166 return "I40E_ERR_LINK_SETUP";
167 case I40E_ERR_ADAPTER_STOPPED:
168 return "I40E_ERR_ADAPTER_STOPPED";
169 case I40E_ERR_INVALID_MAC_ADDR:
170 return "I40E_ERR_INVALID_MAC_ADDR";
171 case I40E_ERR_DEVICE_NOT_SUPPORTED:
172 return "I40E_ERR_DEVICE_NOT_SUPPORTED";
173 case I40E_ERR_MASTER_REQUESTS_PENDING:
174 return "I40E_ERR_MASTER_REQUESTS_PENDING";
175 case I40E_ERR_INVALID_LINK_SETTINGS:
176 return "I40E_ERR_INVALID_LINK_SETTINGS";
177 case I40E_ERR_AUTONEG_NOT_COMPLETE:
178 return "I40E_ERR_AUTONEG_NOT_COMPLETE";
179 case I40E_ERR_RESET_FAILED:
180 return "I40E_ERR_RESET_FAILED";
181 case I40E_ERR_SWFW_SYNC:
182 return "I40E_ERR_SWFW_SYNC";
183 case I40E_ERR_NO_AVAILABLE_VSI:
184 return "I40E_ERR_NO_AVAILABLE_VSI";
185 case I40E_ERR_NO_MEMORY:
186 return "I40E_ERR_NO_MEMORY";
187 case I40E_ERR_BAD_PTR:
188 return "I40E_ERR_BAD_PTR";
189 case I40E_ERR_RING_FULL:
190 return "I40E_ERR_RING_FULL";
191 case I40E_ERR_INVALID_PD_ID:
192 return "I40E_ERR_INVALID_PD_ID";
193 case I40E_ERR_INVALID_QP_ID:
194 return "I40E_ERR_INVALID_QP_ID";
195 case I40E_ERR_INVALID_CQ_ID:
196 return "I40E_ERR_INVALID_CQ_ID";
197 case I40E_ERR_INVALID_CEQ_ID:
198 return "I40E_ERR_INVALID_CEQ_ID";
199 case I40E_ERR_INVALID_AEQ_ID:
200 return "I40E_ERR_INVALID_AEQ_ID";
201 case I40E_ERR_INVALID_SIZE:
202 return "I40E_ERR_INVALID_SIZE";
203 case I40E_ERR_INVALID_ARP_INDEX:
204 return "I40E_ERR_INVALID_ARP_INDEX";
205 case I40E_ERR_INVALID_FPM_FUNC_ID:
206 return "I40E_ERR_INVALID_FPM_FUNC_ID";
207 case I40E_ERR_QP_INVALID_MSG_SIZE:
208 return "I40E_ERR_QP_INVALID_MSG_SIZE";
209 case I40E_ERR_QP_TOOMANY_WRS_POSTED:
210 return "I40E_ERR_QP_TOOMANY_WRS_POSTED";
211 case I40E_ERR_INVALID_FRAG_COUNT:
212 return "I40E_ERR_INVALID_FRAG_COUNT";
213 case I40E_ERR_QUEUE_EMPTY:
214 return "I40E_ERR_QUEUE_EMPTY";
215 case I40E_ERR_INVALID_ALIGNMENT:
216 return "I40E_ERR_INVALID_ALIGNMENT";
217 case I40E_ERR_FLUSHED_QUEUE:
218 return "I40E_ERR_FLUSHED_QUEUE";
219 case I40E_ERR_INVALID_PUSH_PAGE_INDEX:
220 return "I40E_ERR_INVALID_PUSH_PAGE_INDEX";
221 case I40E_ERR_INVALID_IMM_DATA_SIZE:
222 return "I40E_ERR_INVALID_IMM_DATA_SIZE";
223 case I40E_ERR_TIMEOUT:
224 return "I40E_ERR_TIMEOUT";
225 case I40E_ERR_OPCODE_MISMATCH:
226 return "I40E_ERR_OPCODE_MISMATCH";
227 case I40E_ERR_CQP_COMPL_ERROR:
228 return "I40E_ERR_CQP_COMPL_ERROR";
229 case I40E_ERR_INVALID_VF_ID:
230 return "I40E_ERR_INVALID_VF_ID";
231 case I40E_ERR_INVALID_HMCFN_ID:
232 return "I40E_ERR_INVALID_HMCFN_ID";
233 case I40E_ERR_BACKING_PAGE_ERROR:
234 return "I40E_ERR_BACKING_PAGE_ERROR";
235 case I40E_ERR_NO_PBLCHUNKS_AVAILABLE:
236 return "I40E_ERR_NO_PBLCHUNKS_AVAILABLE";
237 case I40E_ERR_INVALID_PBLE_INDEX:
238 return "I40E_ERR_INVALID_PBLE_INDEX";
239 case I40E_ERR_INVALID_SD_INDEX:
240 return "I40E_ERR_INVALID_SD_INDEX";
241 case I40E_ERR_INVALID_PAGE_DESC_INDEX:
242 return "I40E_ERR_INVALID_PAGE_DESC_INDEX";
243 case I40E_ERR_INVALID_SD_TYPE:
244 return "I40E_ERR_INVALID_SD_TYPE";
245 case I40E_ERR_MEMCPY_FAILED:
246 return "I40E_ERR_MEMCPY_FAILED";
247 case I40E_ERR_INVALID_HMC_OBJ_INDEX:
248 return "I40E_ERR_INVALID_HMC_OBJ_INDEX";
249 case I40E_ERR_INVALID_HMC_OBJ_COUNT:
250 return "I40E_ERR_INVALID_HMC_OBJ_COUNT";
251 case I40E_ERR_INVALID_SRQ_ARM_LIMIT:
252 return "I40E_ERR_INVALID_SRQ_ARM_LIMIT";
253 case I40E_ERR_SRQ_ENABLED:
254 return "I40E_ERR_SRQ_ENABLED";
255 case I40E_ERR_ADMIN_QUEUE_ERROR:
256 return "I40E_ERR_ADMIN_QUEUE_ERROR";
257 case I40E_ERR_ADMIN_QUEUE_TIMEOUT:
258 return "I40E_ERR_ADMIN_QUEUE_TIMEOUT";
259 case I40E_ERR_BUF_TOO_SHORT:
260 return "I40E_ERR_BUF_TOO_SHORT";
261 case I40E_ERR_ADMIN_QUEUE_FULL:
262 return "I40E_ERR_ADMIN_QUEUE_FULL";
263 case I40E_ERR_ADMIN_QUEUE_NO_WORK:
264 return "I40E_ERR_ADMIN_QUEUE_NO_WORK";
265 case I40E_ERR_BAD_IWARP_CQE:
266 return "I40E_ERR_BAD_IWARP_CQE";
267 case I40E_ERR_NVM_BLANK_MODE:
268 return "I40E_ERR_NVM_BLANK_MODE";
269 case I40E_ERR_NOT_IMPLEMENTED:
270 return "I40E_ERR_NOT_IMPLEMENTED";
271 case I40E_ERR_PE_DOORBELL_NOT_ENABLED:
272 return "I40E_ERR_PE_DOORBELL_NOT_ENABLED";
273 case I40E_ERR_DIAG_TEST_FAILED:
274 return "I40E_ERR_DIAG_TEST_FAILED";
275 case I40E_ERR_NOT_READY:
276 return "I40E_ERR_NOT_READY";
277 case I40E_NOT_SUPPORTED:
278 return "I40E_NOT_SUPPORTED";
279 case I40E_ERR_FIRMWARE_API_VERSION:
280 return "I40E_ERR_FIRMWARE_API_VERSION";
281 }
282
283 snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
284 return hw->err_str;
285}
286
287/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000288 * i40e_debug_aq
289 * @hw: debug mask related to admin queue
Jeff Kirsher98d44382013-12-21 05:44:42 +0000290 * @mask: debug mask
291 * @desc: pointer to admin queue descriptor
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000292 * @buffer: pointer to command buffer
Shannon Nelsonf905dd62014-07-10 07:58:20 +0000293 * @buf_len: max length of buffer
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000294 *
295 * Dumps debug log about adminq command with descriptor contents.
296 **/
297void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
Shannon Nelsonf905dd62014-07-10 07:58:20 +0000298 void *buffer, u16 buf_len)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000299{
300 struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
Heinrich Schuchardtcd956722016-05-17 22:41:33 +0200301 u16 len;
Shannon Nelson37a29732015-02-27 09:15:19 +0000302 u8 *buf = (u8 *)buffer;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000303
304 if ((!(mask & hw->debug_mask)) || (desc == NULL))
305 return;
306
Heinrich Schuchardtcd956722016-05-17 22:41:33 +0200307 len = le16_to_cpu(aq_desc->datalen);
308
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000309 i40e_debug(hw, mask,
310 "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
Paul M Stillwell Jrf1abd7d2015-02-06 08:52:07 +0000311 le16_to_cpu(aq_desc->opcode),
312 le16_to_cpu(aq_desc->flags),
313 le16_to_cpu(aq_desc->datalen),
314 le16_to_cpu(aq_desc->retval));
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000315 i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
Paul M Stillwell Jrf1abd7d2015-02-06 08:52:07 +0000316 le32_to_cpu(aq_desc->cookie_high),
317 le32_to_cpu(aq_desc->cookie_low));
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000318 i40e_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n",
Paul M Stillwell Jrf1abd7d2015-02-06 08:52:07 +0000319 le32_to_cpu(aq_desc->params.internal.param0),
320 le32_to_cpu(aq_desc->params.internal.param1));
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000321 i40e_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n",
Paul M Stillwell Jrf1abd7d2015-02-06 08:52:07 +0000322 le32_to_cpu(aq_desc->params.external.addr_high),
323 le32_to_cpu(aq_desc->params.external.addr_low));
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000324
325 if ((buffer != NULL) && (aq_desc->datalen != 0)) {
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000326 i40e_debug(hw, mask, "AQ CMD Buffer:\n");
Shannon Nelsonf905dd62014-07-10 07:58:20 +0000327 if (buf_len < len)
328 len = buf_len;
Shannon Nelson37a29732015-02-27 09:15:19 +0000329 /* write the full 16-byte chunks */
Alan Brady773d4022016-12-12 15:44:13 -0800330 if (hw->debug_mask & mask) {
Jacob Kellerb5d55042017-07-12 05:46:09 -0400331 char prefix[27];
Alan Brady773d4022016-12-12 15:44:13 -0800332
Jacob Kellerb5d55042017-07-12 05:46:09 -0400333 snprintf(prefix, sizeof(prefix),
Alan Brady773d4022016-12-12 15:44:13 -0800334 "i40e %02x:%02x.%x: \t0x",
335 hw->bus.bus_id,
336 hw->bus.device,
337 hw->bus.func);
338
339 print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET,
340 16, 1, buf, len, false);
341 }
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000342 }
343}
344
345/**
Anjali Singhai Jaine1860d82013-11-28 06:39:45 +0000346 * i40e_check_asq_alive
347 * @hw: pointer to the hw struct
348 *
349 * Returns true if Queue is enabled else false.
350 **/
351bool i40e_check_asq_alive(struct i40e_hw *hw)
352{
Kevin Scott8b833b42014-04-09 05:58:54 +0000353 if (hw->aq.asq.len)
354 return !!(rd32(hw, hw->aq.asq.len) &
355 I40E_PF_ATQLEN_ATQENABLE_MASK);
356 else
357 return false;
Anjali Singhai Jaine1860d82013-11-28 06:39:45 +0000358}
359
360/**
361 * i40e_aq_queue_shutdown
362 * @hw: pointer to the hw struct
363 * @unloading: is the driver unloading itself
364 *
365 * Tell the Firmware that we're shutting down the AdminQ and whether
366 * or not the driver is unloading as well.
367 **/
368i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
369 bool unloading)
370{
371 struct i40e_aq_desc desc;
372 struct i40e_aqc_queue_shutdown *cmd =
373 (struct i40e_aqc_queue_shutdown *)&desc.params.raw;
374 i40e_status status;
375
376 i40e_fill_default_direct_cmd_desc(&desc,
377 i40e_aqc_opc_queue_shutdown);
378
379 if (unloading)
380 cmd->driver_unloading = cpu_to_le32(I40E_AQ_DRIVER_UNLOADING);
381 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
382
383 return status;
384}
385
Anjali Singhai Jaine50c8d62015-06-05 12:20:27 -0400386/**
387 * i40e_aq_get_set_rss_lut
388 * @hw: pointer to the hardware structure
389 * @vsi_id: vsi fw index
390 * @pf_lut: for PF table set true, for VSI table set false
391 * @lut: pointer to the lut buffer provided by the caller
392 * @lut_size: size of the lut buffer
393 * @set: set true to set the table, false to get the table
394 *
395 * Internal function to get or set RSS look up table
396 **/
397static i40e_status i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
398 u16 vsi_id, bool pf_lut,
399 u8 *lut, u16 lut_size,
400 bool set)
401{
402 i40e_status status;
403 struct i40e_aq_desc desc;
404 struct i40e_aqc_get_set_rss_lut *cmd_resp =
405 (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw;
406
407 if (set)
408 i40e_fill_default_direct_cmd_desc(&desc,
409 i40e_aqc_opc_set_rss_lut);
410 else
411 i40e_fill_default_direct_cmd_desc(&desc,
412 i40e_aqc_opc_get_rss_lut);
413
414 /* Indirect command */
415 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
416 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
417
418 cmd_resp->vsi_id =
419 cpu_to_le16((u16)((vsi_id <<
420 I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
421 I40E_AQC_SET_RSS_LUT_VSI_ID_MASK));
422 cmd_resp->vsi_id |= cpu_to_le16((u16)I40E_AQC_SET_RSS_LUT_VSI_VALID);
423
424 if (pf_lut)
425 cmd_resp->flags |= cpu_to_le16((u16)
426 ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
427 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
428 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
429 else
430 cmd_resp->flags |= cpu_to_le16((u16)
431 ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
432 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
433 I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
434
Anjali Singhai Jaine50c8d62015-06-05 12:20:27 -0400435 status = i40e_asq_send_command(hw, &desc, lut, lut_size, NULL);
436
437 return status;
438}
439
440/**
441 * i40e_aq_get_rss_lut
442 * @hw: pointer to the hardware structure
443 * @vsi_id: vsi fw index
444 * @pf_lut: for PF table set true, for VSI table set false
445 * @lut: pointer to the lut buffer provided by the caller
446 * @lut_size: size of the lut buffer
447 *
448 * get the RSS lookup table, PF or VSI type
449 **/
450i40e_status i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
451 bool pf_lut, u8 *lut, u16 lut_size)
452{
453 return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
454 false);
455}
456
457/**
458 * i40e_aq_set_rss_lut
459 * @hw: pointer to the hardware structure
460 * @vsi_id: vsi fw index
461 * @pf_lut: for PF table set true, for VSI table set false
462 * @lut: pointer to the lut buffer provided by the caller
463 * @lut_size: size of the lut buffer
464 *
465 * set the RSS lookup table, PF or VSI type
466 **/
467i40e_status i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
468 bool pf_lut, u8 *lut, u16 lut_size)
469{
470 return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
471}
472
473/**
474 * i40e_aq_get_set_rss_key
475 * @hw: pointer to the hw struct
476 * @vsi_id: vsi fw index
477 * @key: pointer to key info struct
478 * @set: set true to set the key, false to get the key
479 *
480 * get the RSS key per VSI
481 **/
482static i40e_status i40e_aq_get_set_rss_key(struct i40e_hw *hw,
483 u16 vsi_id,
484 struct i40e_aqc_get_set_rss_key_data *key,
485 bool set)
486{
487 i40e_status status;
488 struct i40e_aq_desc desc;
489 struct i40e_aqc_get_set_rss_key *cmd_resp =
490 (struct i40e_aqc_get_set_rss_key *)&desc.params.raw;
491 u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data);
492
493 if (set)
494 i40e_fill_default_direct_cmd_desc(&desc,
495 i40e_aqc_opc_set_rss_key);
496 else
497 i40e_fill_default_direct_cmd_desc(&desc,
498 i40e_aqc_opc_get_rss_key);
499
500 /* Indirect command */
501 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
502 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
503
504 cmd_resp->vsi_id =
505 cpu_to_le16((u16)((vsi_id <<
506 I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
507 I40E_AQC_SET_RSS_KEY_VSI_ID_MASK));
508 cmd_resp->vsi_id |= cpu_to_le16((u16)I40E_AQC_SET_RSS_KEY_VSI_VALID);
Anjali Singhai Jaine50c8d62015-06-05 12:20:27 -0400509
510 status = i40e_asq_send_command(hw, &desc, key, key_size, NULL);
511
512 return status;
513}
514
515/**
516 * i40e_aq_get_rss_key
517 * @hw: pointer to the hw struct
518 * @vsi_id: vsi fw index
519 * @key: pointer to key info struct
520 *
521 **/
522i40e_status i40e_aq_get_rss_key(struct i40e_hw *hw,
523 u16 vsi_id,
524 struct i40e_aqc_get_set_rss_key_data *key)
525{
526 return i40e_aq_get_set_rss_key(hw, vsi_id, key, false);
527}
528
529/**
530 * i40e_aq_set_rss_key
531 * @hw: pointer to the hw struct
532 * @vsi_id: vsi fw index
533 * @key: pointer to key info struct
534 *
535 * set the RSS key per VSI
536 **/
537i40e_status i40e_aq_set_rss_key(struct i40e_hw *hw,
538 u16 vsi_id,
539 struct i40e_aqc_get_set_rss_key_data *key)
540{
541 return i40e_aq_get_set_rss_key(hw, vsi_id, key, true);
542}
543
Jesse Brandeburg206812b2014-02-12 01:45:33 +0000544/* The i40e_ptype_lookup table is used to convert from the 8-bit ptype in the
545 * hardware to a bit-field that can be used by SW to more easily determine the
546 * packet type.
547 *
548 * Macros are used to shorten the table lines and make this table human
549 * readable.
550 *
551 * We store the PTYPE in the top byte of the bit field - this is just so that
552 * we can check that the table doesn't have a row missing, as the index into
553 * the table should be the PTYPE.
554 *
555 * Typical work flow:
556 *
557 * IF NOT i40e_ptype_lookup[ptype].known
558 * THEN
559 * Packet is unknown
560 * ELSE IF i40e_ptype_lookup[ptype].outer_ip == I40E_RX_PTYPE_OUTER_IP
561 * Use the rest of the fields to look at the tunnels, inner protocols, etc
562 * ELSE
563 * Use the enum i40e_rx_l2_ptype to decode the packet type
564 * ENDIF
565 */
566
567/* macro to make the table lines short */
568#define I40E_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\
569 { PTYPE, \
570 1, \
571 I40E_RX_PTYPE_OUTER_##OUTER_IP, \
572 I40E_RX_PTYPE_OUTER_##OUTER_IP_VER, \
573 I40E_RX_PTYPE_##OUTER_FRAG, \
574 I40E_RX_PTYPE_TUNNEL_##T, \
575 I40E_RX_PTYPE_TUNNEL_END_##TE, \
576 I40E_RX_PTYPE_##TEF, \
577 I40E_RX_PTYPE_INNER_PROT_##I, \
578 I40E_RX_PTYPE_PAYLOAD_LAYER_##PL }
579
580#define I40E_PTT_UNUSED_ENTRY(PTYPE) \
581 { PTYPE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
582
583/* shorter macros makes the table fit but are terse */
584#define I40E_RX_PTYPE_NOF I40E_RX_PTYPE_NOT_FRAG
585#define I40E_RX_PTYPE_FRG I40E_RX_PTYPE_FRAG
586#define I40E_RX_PTYPE_INNER_PROT_TS I40E_RX_PTYPE_INNER_PROT_TIMESYNC
587
588/* Lookup table mapping the HW PTYPE to the bit field for decoding */
589struct i40e_rx_ptype_decoded i40e_ptype_lookup[] = {
590 /* L2 Packet types */
591 I40E_PTT_UNUSED_ENTRY(0),
592 I40E_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
593 I40E_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, TS, PAY2),
594 I40E_PTT(3, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
595 I40E_PTT_UNUSED_ENTRY(4),
596 I40E_PTT_UNUSED_ENTRY(5),
597 I40E_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
598 I40E_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
599 I40E_PTT_UNUSED_ENTRY(8),
600 I40E_PTT_UNUSED_ENTRY(9),
601 I40E_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
602 I40E_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
603 I40E_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
604 I40E_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
605 I40E_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
606 I40E_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
607 I40E_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
608 I40E_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
609 I40E_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
610 I40E_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
611 I40E_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
612 I40E_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
613
614 /* Non Tunneled IPv4 */
615 I40E_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
616 I40E_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
617 I40E_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4),
618 I40E_PTT_UNUSED_ENTRY(25),
619 I40E_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4),
620 I40E_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
621 I40E_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
622
623 /* IPv4 --> IPv4 */
624 I40E_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
625 I40E_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
626 I40E_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
627 I40E_PTT_UNUSED_ENTRY(32),
628 I40E_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
629 I40E_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
630 I40E_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
631
632 /* IPv4 --> IPv6 */
633 I40E_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
634 I40E_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
635 I40E_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
636 I40E_PTT_UNUSED_ENTRY(39),
637 I40E_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
638 I40E_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
639 I40E_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
640
641 /* IPv4 --> GRE/NAT */
642 I40E_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
643
644 /* IPv4 --> GRE/NAT --> IPv4 */
645 I40E_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
646 I40E_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
647 I40E_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
648 I40E_PTT_UNUSED_ENTRY(47),
649 I40E_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
650 I40E_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
651 I40E_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
652
653 /* IPv4 --> GRE/NAT --> IPv6 */
654 I40E_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
655 I40E_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
656 I40E_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
657 I40E_PTT_UNUSED_ENTRY(54),
658 I40E_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
659 I40E_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
660 I40E_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
661
662 /* IPv4 --> GRE/NAT --> MAC */
663 I40E_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
664
665 /* IPv4 --> GRE/NAT --> MAC --> IPv4 */
666 I40E_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
667 I40E_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
668 I40E_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
669 I40E_PTT_UNUSED_ENTRY(62),
670 I40E_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
671 I40E_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
672 I40E_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
673
674 /* IPv4 --> GRE/NAT -> MAC --> IPv6 */
675 I40E_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
676 I40E_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
677 I40E_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
678 I40E_PTT_UNUSED_ENTRY(69),
679 I40E_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
680 I40E_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
681 I40E_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
682
683 /* IPv4 --> GRE/NAT --> MAC/VLAN */
684 I40E_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
685
686 /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
687 I40E_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
688 I40E_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
689 I40E_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
690 I40E_PTT_UNUSED_ENTRY(77),
691 I40E_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
692 I40E_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
693 I40E_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
694
695 /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
696 I40E_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
697 I40E_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
698 I40E_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
699 I40E_PTT_UNUSED_ENTRY(84),
700 I40E_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
701 I40E_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
702 I40E_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
703
704 /* Non Tunneled IPv6 */
705 I40E_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
706 I40E_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
Akeem G Abodunrin73df8c92016-05-03 15:13:16 -0700707 I40E_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4),
Jesse Brandeburg206812b2014-02-12 01:45:33 +0000708 I40E_PTT_UNUSED_ENTRY(91),
709 I40E_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4),
710 I40E_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
711 I40E_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
712
713 /* IPv6 --> IPv4 */
714 I40E_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
715 I40E_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
716 I40E_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
717 I40E_PTT_UNUSED_ENTRY(98),
718 I40E_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
719 I40E_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
720 I40E_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
721
722 /* IPv6 --> IPv6 */
723 I40E_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
724 I40E_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
725 I40E_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
726 I40E_PTT_UNUSED_ENTRY(105),
727 I40E_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
728 I40E_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
729 I40E_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
730
731 /* IPv6 --> GRE/NAT */
732 I40E_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
733
734 /* IPv6 --> GRE/NAT -> IPv4 */
735 I40E_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
736 I40E_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
737 I40E_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
738 I40E_PTT_UNUSED_ENTRY(113),
739 I40E_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
740 I40E_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
741 I40E_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
742
743 /* IPv6 --> GRE/NAT -> IPv6 */
744 I40E_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
745 I40E_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
746 I40E_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
747 I40E_PTT_UNUSED_ENTRY(120),
748 I40E_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
749 I40E_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
750 I40E_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
751
752 /* IPv6 --> GRE/NAT -> MAC */
753 I40E_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
754
755 /* IPv6 --> GRE/NAT -> MAC -> IPv4 */
756 I40E_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
757 I40E_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
758 I40E_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
759 I40E_PTT_UNUSED_ENTRY(128),
760 I40E_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
761 I40E_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
762 I40E_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
763
764 /* IPv6 --> GRE/NAT -> MAC -> IPv6 */
765 I40E_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
766 I40E_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
767 I40E_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
768 I40E_PTT_UNUSED_ENTRY(135),
769 I40E_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
770 I40E_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
771 I40E_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
772
773 /* IPv6 --> GRE/NAT -> MAC/VLAN */
774 I40E_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
775
776 /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
777 I40E_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
778 I40E_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
779 I40E_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
780 I40E_PTT_UNUSED_ENTRY(143),
781 I40E_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
782 I40E_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
783 I40E_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
784
785 /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
786 I40E_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
787 I40E_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
788 I40E_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
789 I40E_PTT_UNUSED_ENTRY(150),
790 I40E_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
791 I40E_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
792 I40E_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
793
794 /* unused entries */
795 I40E_PTT_UNUSED_ENTRY(154),
796 I40E_PTT_UNUSED_ENTRY(155),
797 I40E_PTT_UNUSED_ENTRY(156),
798 I40E_PTT_UNUSED_ENTRY(157),
799 I40E_PTT_UNUSED_ENTRY(158),
800 I40E_PTT_UNUSED_ENTRY(159),
801
802 I40E_PTT_UNUSED_ENTRY(160),
803 I40E_PTT_UNUSED_ENTRY(161),
804 I40E_PTT_UNUSED_ENTRY(162),
805 I40E_PTT_UNUSED_ENTRY(163),
806 I40E_PTT_UNUSED_ENTRY(164),
807 I40E_PTT_UNUSED_ENTRY(165),
808 I40E_PTT_UNUSED_ENTRY(166),
809 I40E_PTT_UNUSED_ENTRY(167),
810 I40E_PTT_UNUSED_ENTRY(168),
811 I40E_PTT_UNUSED_ENTRY(169),
812
813 I40E_PTT_UNUSED_ENTRY(170),
814 I40E_PTT_UNUSED_ENTRY(171),
815 I40E_PTT_UNUSED_ENTRY(172),
816 I40E_PTT_UNUSED_ENTRY(173),
817 I40E_PTT_UNUSED_ENTRY(174),
818 I40E_PTT_UNUSED_ENTRY(175),
819 I40E_PTT_UNUSED_ENTRY(176),
820 I40E_PTT_UNUSED_ENTRY(177),
821 I40E_PTT_UNUSED_ENTRY(178),
822 I40E_PTT_UNUSED_ENTRY(179),
823
824 I40E_PTT_UNUSED_ENTRY(180),
825 I40E_PTT_UNUSED_ENTRY(181),
826 I40E_PTT_UNUSED_ENTRY(182),
827 I40E_PTT_UNUSED_ENTRY(183),
828 I40E_PTT_UNUSED_ENTRY(184),
829 I40E_PTT_UNUSED_ENTRY(185),
830 I40E_PTT_UNUSED_ENTRY(186),
831 I40E_PTT_UNUSED_ENTRY(187),
832 I40E_PTT_UNUSED_ENTRY(188),
833 I40E_PTT_UNUSED_ENTRY(189),
834
835 I40E_PTT_UNUSED_ENTRY(190),
836 I40E_PTT_UNUSED_ENTRY(191),
837 I40E_PTT_UNUSED_ENTRY(192),
838 I40E_PTT_UNUSED_ENTRY(193),
839 I40E_PTT_UNUSED_ENTRY(194),
840 I40E_PTT_UNUSED_ENTRY(195),
841 I40E_PTT_UNUSED_ENTRY(196),
842 I40E_PTT_UNUSED_ENTRY(197),
843 I40E_PTT_UNUSED_ENTRY(198),
844 I40E_PTT_UNUSED_ENTRY(199),
845
846 I40E_PTT_UNUSED_ENTRY(200),
847 I40E_PTT_UNUSED_ENTRY(201),
848 I40E_PTT_UNUSED_ENTRY(202),
849 I40E_PTT_UNUSED_ENTRY(203),
850 I40E_PTT_UNUSED_ENTRY(204),
851 I40E_PTT_UNUSED_ENTRY(205),
852 I40E_PTT_UNUSED_ENTRY(206),
853 I40E_PTT_UNUSED_ENTRY(207),
854 I40E_PTT_UNUSED_ENTRY(208),
855 I40E_PTT_UNUSED_ENTRY(209),
856
857 I40E_PTT_UNUSED_ENTRY(210),
858 I40E_PTT_UNUSED_ENTRY(211),
859 I40E_PTT_UNUSED_ENTRY(212),
860 I40E_PTT_UNUSED_ENTRY(213),
861 I40E_PTT_UNUSED_ENTRY(214),
862 I40E_PTT_UNUSED_ENTRY(215),
863 I40E_PTT_UNUSED_ENTRY(216),
864 I40E_PTT_UNUSED_ENTRY(217),
865 I40E_PTT_UNUSED_ENTRY(218),
866 I40E_PTT_UNUSED_ENTRY(219),
867
868 I40E_PTT_UNUSED_ENTRY(220),
869 I40E_PTT_UNUSED_ENTRY(221),
870 I40E_PTT_UNUSED_ENTRY(222),
871 I40E_PTT_UNUSED_ENTRY(223),
872 I40E_PTT_UNUSED_ENTRY(224),
873 I40E_PTT_UNUSED_ENTRY(225),
874 I40E_PTT_UNUSED_ENTRY(226),
875 I40E_PTT_UNUSED_ENTRY(227),
876 I40E_PTT_UNUSED_ENTRY(228),
877 I40E_PTT_UNUSED_ENTRY(229),
878
879 I40E_PTT_UNUSED_ENTRY(230),
880 I40E_PTT_UNUSED_ENTRY(231),
881 I40E_PTT_UNUSED_ENTRY(232),
882 I40E_PTT_UNUSED_ENTRY(233),
883 I40E_PTT_UNUSED_ENTRY(234),
884 I40E_PTT_UNUSED_ENTRY(235),
885 I40E_PTT_UNUSED_ENTRY(236),
886 I40E_PTT_UNUSED_ENTRY(237),
887 I40E_PTT_UNUSED_ENTRY(238),
888 I40E_PTT_UNUSED_ENTRY(239),
889
890 I40E_PTT_UNUSED_ENTRY(240),
891 I40E_PTT_UNUSED_ENTRY(241),
892 I40E_PTT_UNUSED_ENTRY(242),
893 I40E_PTT_UNUSED_ENTRY(243),
894 I40E_PTT_UNUSED_ENTRY(244),
895 I40E_PTT_UNUSED_ENTRY(245),
896 I40E_PTT_UNUSED_ENTRY(246),
897 I40E_PTT_UNUSED_ENTRY(247),
898 I40E_PTT_UNUSED_ENTRY(248),
899 I40E_PTT_UNUSED_ENTRY(249),
900
901 I40E_PTT_UNUSED_ENTRY(250),
902 I40E_PTT_UNUSED_ENTRY(251),
903 I40E_PTT_UNUSED_ENTRY(252),
904 I40E_PTT_UNUSED_ENTRY(253),
905 I40E_PTT_UNUSED_ENTRY(254),
906 I40E_PTT_UNUSED_ENTRY(255)
907};
908
Anjali Singhai Jaine1860d82013-11-28 06:39:45 +0000909/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000910 * i40e_init_shared_code - Initialize the shared code
911 * @hw: pointer to hardware structure
912 *
913 * This assigns the MAC type and PHY code and inits the NVM.
914 * Does not touch the hardware. This function must be called prior to any
915 * other function in the shared code. The i40e_hw structure should be
916 * memset to 0 prior to calling this function. The following fields in
917 * hw structure should be filled in prior to calling this function:
918 * hw_addr, back, device_id, vendor_id, subsystem_device_id,
919 * subsystem_vendor_id, and revision_id
920 **/
921i40e_status i40e_init_shared_code(struct i40e_hw *hw)
922{
923 i40e_status status = 0;
Shannon Nelson5fb11d72014-11-13 03:06:19 +0000924 u32 port, ari, func_rid;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000925
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000926 i40e_set_mac_type(hw);
927
928 switch (hw->mac.type) {
929 case I40E_MAC_XL710:
Anjali Singhai Jain87e6c1d2015-06-05 12:20:25 -0400930 case I40E_MAC_X722:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000931 break;
932 default:
933 return I40E_ERR_DEVICE_NOT_SUPPORTED;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000934 }
935
Shannon Nelsonaf89d26c2013-12-11 08:17:14 +0000936 hw->phy.get_link_info = true;
937
Shannon Nelson5fb11d72014-11-13 03:06:19 +0000938 /* Determine port number and PF number*/
939 port = (rd32(hw, I40E_PFGEN_PORTNUM) & I40E_PFGEN_PORTNUM_PORT_NUM_MASK)
940 >> I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT;
941 hw->port = (u8)port;
942 ari = (rd32(hw, I40E_GLPCI_CAPSUP) & I40E_GLPCI_CAPSUP_ARI_EN_MASK) >>
943 I40E_GLPCI_CAPSUP_ARI_EN_SHIFT;
944 func_rid = rd32(hw, I40E_PF_FUNC_RID);
945 if (ari)
946 hw->pf_id = (u8)(func_rid & 0xff);
Shannon Nelson5f9116a2013-12-11 08:17:13 +0000947 else
Shannon Nelson5fb11d72014-11-13 03:06:19 +0000948 hw->pf_id = (u8)(func_rid & 0x7);
Shannon Nelson5f9116a2013-12-11 08:17:13 +0000949
Anjali Singhai07f89be2015-09-24 15:26:32 -0700950 if (hw->mac.type == I40E_MAC_X722)
951 hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE;
952
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +0000953 status = i40e_init_nvm(hw);
954 return status;
955}
956
957/**
958 * i40e_aq_mac_address_read - Retrieve the MAC addresses
959 * @hw: pointer to the hw struct
960 * @flags: a return indicator of what addresses were added to the addr store
961 * @addrs: the requestor's mac addr store
962 * @cmd_details: pointer to command details structure or NULL
963 **/
964static i40e_status i40e_aq_mac_address_read(struct i40e_hw *hw,
965 u16 *flags,
966 struct i40e_aqc_mac_address_read_data *addrs,
967 struct i40e_asq_cmd_details *cmd_details)
968{
969 struct i40e_aq_desc desc;
970 struct i40e_aqc_mac_address_read *cmd_data =
971 (struct i40e_aqc_mac_address_read *)&desc.params.raw;
972 i40e_status status;
973
974 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_mac_address_read);
975 desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF);
976
977 status = i40e_asq_send_command(hw, &desc, addrs,
978 sizeof(*addrs), cmd_details);
979 *flags = le16_to_cpu(cmd_data->command_flags);
980
981 return status;
982}
983
984/**
985 * i40e_aq_mac_address_write - Change the MAC addresses
986 * @hw: pointer to the hw struct
987 * @flags: indicates which MAC to be written
988 * @mac_addr: address to write
989 * @cmd_details: pointer to command details structure or NULL
990 **/
991i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
992 u16 flags, u8 *mac_addr,
993 struct i40e_asq_cmd_details *cmd_details)
994{
995 struct i40e_aq_desc desc;
996 struct i40e_aqc_mac_address_write *cmd_data =
997 (struct i40e_aqc_mac_address_write *)&desc.params.raw;
998 i40e_status status;
999
1000 i40e_fill_default_direct_cmd_desc(&desc,
1001 i40e_aqc_opc_mac_address_write);
1002 cmd_data->command_flags = cpu_to_le16(flags);
Kamil Krawczyk55c29c32013-12-18 13:45:52 +00001003 cmd_data->mac_sah = cpu_to_le16((u16)mac_addr[0] << 8 | mac_addr[1]);
1004 cmd_data->mac_sal = cpu_to_le32(((u32)mac_addr[2] << 24) |
1005 ((u32)mac_addr[3] << 16) |
1006 ((u32)mac_addr[4] << 8) |
1007 mac_addr[5]);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001008
1009 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1010
1011 return status;
1012}
1013
1014/**
1015 * i40e_get_mac_addr - get MAC address
1016 * @hw: pointer to the HW structure
1017 * @mac_addr: pointer to MAC address
1018 *
1019 * Reads the adapter's MAC address from register
1020 **/
1021i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
1022{
1023 struct i40e_aqc_mac_address_read_data addrs;
1024 i40e_status status;
1025 u16 flags = 0;
1026
1027 status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
1028
1029 if (flags & I40E_AQC_LAN_ADDR_VALID)
Jesse Brandeburg6995b362015-08-28 17:55:54 -04001030 ether_addr_copy(mac_addr, addrs.pf_lan_mac);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001031
1032 return status;
1033}
1034
1035/**
Neerav Parikh1f224ad2014-02-12 01:45:31 +00001036 * i40e_get_port_mac_addr - get Port MAC address
1037 * @hw: pointer to the HW structure
1038 * @mac_addr: pointer to Port MAC address
1039 *
1040 * Reads the adapter's Port MAC address
1041 **/
1042i40e_status i40e_get_port_mac_addr(struct i40e_hw *hw, u8 *mac_addr)
1043{
1044 struct i40e_aqc_mac_address_read_data addrs;
1045 i40e_status status;
1046 u16 flags = 0;
1047
1048 status = i40e_aq_mac_address_read(hw, &flags, &addrs, NULL);
1049 if (status)
1050 return status;
1051
1052 if (flags & I40E_AQC_PORT_ADDR_VALID)
Jesse Brandeburg6995b362015-08-28 17:55:54 -04001053 ether_addr_copy(mac_addr, addrs.port_mac);
Neerav Parikh1f224ad2014-02-12 01:45:31 +00001054 else
1055 status = I40E_ERR_INVALID_MAC_ADDR;
1056
1057 return status;
1058}
1059
1060/**
Matt Jared351499ab2014-04-23 04:50:03 +00001061 * i40e_pre_tx_queue_cfg - pre tx queue configure
1062 * @hw: pointer to the HW structure
Jeff Kirsherb40c82e62015-02-27 09:18:34 +00001063 * @queue: target PF queue index
Matt Jared351499ab2014-04-23 04:50:03 +00001064 * @enable: state change request
1065 *
1066 * Handles hw requirement to indicate intention to enable
1067 * or disable target queue.
1068 **/
1069void i40e_pre_tx_queue_cfg(struct i40e_hw *hw, u32 queue, bool enable)
1070{
Shannon Nelsondfb699f2014-05-22 06:32:28 +00001071 u32 abs_queue_idx = hw->func_caps.base_queue + queue;
Matt Jared351499ab2014-04-23 04:50:03 +00001072 u32 reg_block = 0;
Shannon Nelsondfb699f2014-05-22 06:32:28 +00001073 u32 reg_val;
Matt Jared351499ab2014-04-23 04:50:03 +00001074
Christopher Pau24a768c2014-06-04 20:41:59 +00001075 if (abs_queue_idx >= 128) {
Matt Jared351499ab2014-04-23 04:50:03 +00001076 reg_block = abs_queue_idx / 128;
Christopher Pau24a768c2014-06-04 20:41:59 +00001077 abs_queue_idx %= 128;
1078 }
Matt Jared351499ab2014-04-23 04:50:03 +00001079
1080 reg_val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
1081 reg_val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
1082 reg_val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
1083
1084 if (enable)
1085 reg_val |= I40E_GLLAN_TXPRE_QDIS_CLEAR_QDIS_MASK;
1086 else
1087 reg_val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
1088
1089 wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), reg_val);
1090}
1091
1092/**
Kamil Krawczyk18f680c2014-12-11 07:06:31 +00001093 * i40e_read_pba_string - Reads part number string from EEPROM
1094 * @hw: pointer to hardware structure
1095 * @pba_num: stores the part number string from the EEPROM
1096 * @pba_num_size: part number string buffer length
1097 *
1098 * Reads the part number string from the EEPROM.
1099 **/
1100i40e_status i40e_read_pba_string(struct i40e_hw *hw, u8 *pba_num,
1101 u32 pba_num_size)
1102{
1103 i40e_status status = 0;
1104 u16 pba_word = 0;
1105 u16 pba_size = 0;
1106 u16 pba_ptr = 0;
1107 u16 i = 0;
1108
1109 status = i40e_read_nvm_word(hw, I40E_SR_PBA_FLAGS, &pba_word);
1110 if (status || (pba_word != 0xFAFA)) {
1111 hw_dbg(hw, "Failed to read PBA flags or flag is invalid.\n");
1112 return status;
1113 }
1114
1115 status = i40e_read_nvm_word(hw, I40E_SR_PBA_BLOCK_PTR, &pba_ptr);
1116 if (status) {
1117 hw_dbg(hw, "Failed to read PBA Block pointer.\n");
1118 return status;
1119 }
1120
1121 status = i40e_read_nvm_word(hw, pba_ptr, &pba_size);
1122 if (status) {
1123 hw_dbg(hw, "Failed to read PBA Block size.\n");
1124 return status;
1125 }
1126
1127 /* Subtract one to get PBA word count (PBA Size word is included in
1128 * total size)
1129 */
1130 pba_size--;
1131 if (pba_num_size < (((u32)pba_size * 2) + 1)) {
1132 hw_dbg(hw, "Buffer to small for PBA data.\n");
1133 return I40E_ERR_PARAM;
1134 }
1135
1136 for (i = 0; i < pba_size; i++) {
1137 status = i40e_read_nvm_word(hw, (pba_ptr + 1) + i, &pba_word);
1138 if (status) {
1139 hw_dbg(hw, "Failed to read PBA Block word %d.\n", i);
1140 return status;
1141 }
1142
1143 pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
1144 pba_num[(i * 2) + 1] = pba_word & 0xFF;
1145 }
1146 pba_num[(pba_size * 2)] = '\0';
1147
1148 return status;
1149}
1150
1151/**
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +00001152 * i40e_get_media_type - Gets media type
1153 * @hw: pointer to the hardware structure
1154 **/
1155static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
1156{
1157 enum i40e_media_type media;
1158
1159 switch (hw->phy.link_info.phy_type) {
1160 case I40E_PHY_TYPE_10GBASE_SR:
1161 case I40E_PHY_TYPE_10GBASE_LR:
Catherine Sullivan124ed152014-07-12 07:28:12 +00001162 case I40E_PHY_TYPE_1000BASE_SX:
1163 case I40E_PHY_TYPE_1000BASE_LX:
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +00001164 case I40E_PHY_TYPE_40GBASE_SR4:
1165 case I40E_PHY_TYPE_40GBASE_LR4:
Carolyn Wyborny31232372016-11-21 13:03:48 -08001166 case I40E_PHY_TYPE_25GBASE_LR:
1167 case I40E_PHY_TYPE_25GBASE_SR:
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +00001168 media = I40E_MEDIA_TYPE_FIBER;
1169 break;
1170 case I40E_PHY_TYPE_100BASE_TX:
1171 case I40E_PHY_TYPE_1000BASE_T:
1172 case I40E_PHY_TYPE_10GBASE_T:
1173 media = I40E_MEDIA_TYPE_BASET;
1174 break;
1175 case I40E_PHY_TYPE_10GBASE_CR1_CU:
1176 case I40E_PHY_TYPE_40GBASE_CR4_CU:
1177 case I40E_PHY_TYPE_10GBASE_CR1:
1178 case I40E_PHY_TYPE_40GBASE_CR4:
1179 case I40E_PHY_TYPE_10GBASE_SFPP_CU:
Catherine Sullivan180204c2015-02-26 16:14:58 +00001180 case I40E_PHY_TYPE_40GBASE_AOC:
1181 case I40E_PHY_TYPE_10GBASE_AOC:
Carolyn Wyborny31232372016-11-21 13:03:48 -08001182 case I40E_PHY_TYPE_25GBASE_CR:
Sudheer Mogilappagari211b4c12017-10-05 14:53:39 -07001183 case I40E_PHY_TYPE_25GBASE_AOC:
1184 case I40E_PHY_TYPE_25GBASE_ACC:
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +00001185 media = I40E_MEDIA_TYPE_DA;
1186 break;
1187 case I40E_PHY_TYPE_1000BASE_KX:
1188 case I40E_PHY_TYPE_10GBASE_KX4:
1189 case I40E_PHY_TYPE_10GBASE_KR:
1190 case I40E_PHY_TYPE_40GBASE_KR4:
Jesse Brandeburgae24b402015-03-27 00:12:09 -07001191 case I40E_PHY_TYPE_20GBASE_KR2:
Carolyn Wyborny31232372016-11-21 13:03:48 -08001192 case I40E_PHY_TYPE_25GBASE_KR:
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +00001193 media = I40E_MEDIA_TYPE_BACKPLANE;
1194 break;
1195 case I40E_PHY_TYPE_SGMII:
1196 case I40E_PHY_TYPE_XAUI:
1197 case I40E_PHY_TYPE_XFI:
1198 case I40E_PHY_TYPE_XLAUI:
1199 case I40E_PHY_TYPE_XLPPI:
1200 default:
1201 media = I40E_MEDIA_TYPE_UNKNOWN;
1202 break;
1203 }
1204
1205 return media;
1206}
1207
Jesse Brandeburg7134f9c2013-11-26 08:56:05 +00001208#define I40E_PF_RESET_WAIT_COUNT_A0 200
Akeem G Abodunrin8af580d2015-03-27 00:12:10 -07001209#define I40E_PF_RESET_WAIT_COUNT 200
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +00001210/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001211 * i40e_pf_reset - Reset the PF
1212 * @hw: pointer to the hardware structure
1213 *
1214 * Assuming someone else has triggered a global reset,
1215 * assure the global reset is complete and then reset the PF
1216 **/
1217i40e_status i40e_pf_reset(struct i40e_hw *hw)
1218{
Jesse Brandeburg7134f9c2013-11-26 08:56:05 +00001219 u32 cnt = 0;
Shannon Nelson42794bd2013-12-11 08:17:10 +00001220 u32 cnt1 = 0;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001221 u32 reg = 0;
1222 u32 grst_del;
1223
1224 /* Poll for Global Reset steady state in case of recent GRST.
1225 * The grst delay value is in 100ms units, and we'll wait a
1226 * couple counts longer to be sure we don't just miss the end.
1227 */
Shannon Nelsonde78fc52015-02-21 06:41:47 +00001228 grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
1229 I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
1230 I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
Kevin Scott4d7cec02016-02-17 16:12:13 -08001231
1232 /* It can take upto 15 secs for GRST steady state.
1233 * Bump it to 16 secs max to be safe.
1234 */
1235 grst_del = grst_del * 20;
1236
1237 for (cnt = 0; cnt < grst_del; cnt++) {
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001238 reg = rd32(hw, I40E_GLGEN_RSTAT);
1239 if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
1240 break;
1241 msleep(100);
1242 }
1243 if (reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
1244 hw_dbg(hw, "Global reset polling failed to complete.\n");
1245 return I40E_ERR_RESET_FAILED;
1246 }
1247
Shannon Nelson42794bd2013-12-11 08:17:10 +00001248 /* Now Wait for the FW to be ready */
1249 for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) {
1250 reg = rd32(hw, I40E_GLNVM_ULD);
1251 reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1252 I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK);
1253 if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1254 I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK)) {
1255 hw_dbg(hw, "Core and Global modules ready %d\n", cnt1);
1256 break;
1257 }
1258 usleep_range(10000, 20000);
1259 }
1260 if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
1261 I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) {
1262 hw_dbg(hw, "wait for FW Reset complete timedout\n");
1263 hw_dbg(hw, "I40E_GLNVM_ULD = 0x%x\n", reg);
1264 return I40E_ERR_RESET_FAILED;
1265 }
1266
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001267 /* If there was a Global Reset in progress when we got here,
1268 * we don't need to do the PF Reset
1269 */
Jesse Brandeburg7134f9c2013-11-26 08:56:05 +00001270 if (!cnt) {
1271 if (hw->revision_id == 0)
1272 cnt = I40E_PF_RESET_WAIT_COUNT_A0;
1273 else
1274 cnt = I40E_PF_RESET_WAIT_COUNT;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001275 reg = rd32(hw, I40E_PFGEN_CTRL);
1276 wr32(hw, I40E_PFGEN_CTRL,
1277 (reg | I40E_PFGEN_CTRL_PFSWR_MASK));
Jesse Brandeburg7134f9c2013-11-26 08:56:05 +00001278 for (; cnt; cnt--) {
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001279 reg = rd32(hw, I40E_PFGEN_CTRL);
1280 if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
1281 break;
1282 usleep_range(1000, 2000);
1283 }
1284 if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
1285 hw_dbg(hw, "PF reset polling failed to complete.\n");
1286 return I40E_ERR_RESET_FAILED;
1287 }
1288 }
1289
1290 i40e_clear_pxe_mode(hw);
Shannon Nelson922680b2013-12-18 05:29:17 +00001291
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001292 return 0;
1293}
1294
1295/**
Shannon Nelson838d41d2014-06-04 20:41:27 +00001296 * i40e_clear_hw - clear out any left over hw state
1297 * @hw: pointer to the hw struct
1298 *
1299 * Clear queues and interrupts, typically called at init time,
1300 * but after the capabilities have been found so we know how many
1301 * queues and msix vectors have been allocated.
1302 **/
1303void i40e_clear_hw(struct i40e_hw *hw)
1304{
1305 u32 num_queues, base_queue;
1306 u32 num_pf_int;
1307 u32 num_vf_int;
1308 u32 num_vfs;
1309 u32 i, j;
1310 u32 val;
1311 u32 eol = 0x7ff;
1312
Jeff Kirsherb40c82e62015-02-27 09:18:34 +00001313 /* get number of interrupts, queues, and VFs */
Shannon Nelson838d41d2014-06-04 20:41:27 +00001314 val = rd32(hw, I40E_GLPCI_CNF2);
1315 num_pf_int = (val & I40E_GLPCI_CNF2_MSI_X_PF_N_MASK) >>
1316 I40E_GLPCI_CNF2_MSI_X_PF_N_SHIFT;
1317 num_vf_int = (val & I40E_GLPCI_CNF2_MSI_X_VF_N_MASK) >>
1318 I40E_GLPCI_CNF2_MSI_X_VF_N_SHIFT;
1319
Shannon Nelson272cdaf22016-02-17 16:12:21 -08001320 val = rd32(hw, I40E_PFLAN_QALLOC);
Shannon Nelson838d41d2014-06-04 20:41:27 +00001321 base_queue = (val & I40E_PFLAN_QALLOC_FIRSTQ_MASK) >>
1322 I40E_PFLAN_QALLOC_FIRSTQ_SHIFT;
1323 j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >>
1324 I40E_PFLAN_QALLOC_LASTQ_SHIFT;
1325 if (val & I40E_PFLAN_QALLOC_VALID_MASK)
1326 num_queues = (j - base_queue) + 1;
1327 else
1328 num_queues = 0;
1329
1330 val = rd32(hw, I40E_PF_VT_PFALLOC);
1331 i = (val & I40E_PF_VT_PFALLOC_FIRSTVF_MASK) >>
1332 I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT;
1333 j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >>
1334 I40E_PF_VT_PFALLOC_LASTVF_SHIFT;
1335 if (val & I40E_PF_VT_PFALLOC_VALID_MASK)
1336 num_vfs = (j - i) + 1;
1337 else
1338 num_vfs = 0;
1339
1340 /* stop all the interrupts */
1341 wr32(hw, I40E_PFINT_ICR0_ENA, 0);
1342 val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
1343 for (i = 0; i < num_pf_int - 2; i++)
1344 wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
1345
1346 /* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
1347 val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
1348 wr32(hw, I40E_PFINT_LNKLST0, val);
1349 for (i = 0; i < num_pf_int - 2; i++)
1350 wr32(hw, I40E_PFINT_LNKLSTN(i), val);
1351 val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
1352 for (i = 0; i < num_vfs; i++)
1353 wr32(hw, I40E_VPINT_LNKLST0(i), val);
1354 for (i = 0; i < num_vf_int - 2; i++)
1355 wr32(hw, I40E_VPINT_LNKLSTN(i), val);
1356
1357 /* warn the HW of the coming Tx disables */
1358 for (i = 0; i < num_queues; i++) {
1359 u32 abs_queue_idx = base_queue + i;
1360 u32 reg_block = 0;
1361
1362 if (abs_queue_idx >= 128) {
1363 reg_block = abs_queue_idx / 128;
1364 abs_queue_idx %= 128;
1365 }
1366
1367 val = rd32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block));
1368 val &= ~I40E_GLLAN_TXPRE_QDIS_QINDX_MASK;
1369 val |= (abs_queue_idx << I40E_GLLAN_TXPRE_QDIS_QINDX_SHIFT);
1370 val |= I40E_GLLAN_TXPRE_QDIS_SET_QDIS_MASK;
1371
1372 wr32(hw, I40E_GLLAN_TXPRE_QDIS(reg_block), val);
1373 }
1374 udelay(400);
1375
1376 /* stop all the queues */
1377 for (i = 0; i < num_queues; i++) {
1378 wr32(hw, I40E_QINT_TQCTL(i), 0);
1379 wr32(hw, I40E_QTX_ENA(i), 0);
1380 wr32(hw, I40E_QINT_RQCTL(i), 0);
1381 wr32(hw, I40E_QRX_ENA(i), 0);
1382 }
1383
1384 /* short wait for all queue disables to settle */
1385 udelay(50);
1386}
1387
1388/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001389 * i40e_clear_pxe_mode - clear pxe operations mode
1390 * @hw: pointer to the hw struct
1391 *
1392 * Make sure all PXE mode settings are cleared, including things
1393 * like descriptor fetch/write-back mode.
1394 **/
1395void i40e_clear_pxe_mode(struct i40e_hw *hw)
1396{
1397 u32 reg;
1398
Shannon Nelsonc9b9b0a2014-04-09 05:59:05 +00001399 if (i40e_check_asq_alive(hw))
1400 i40e_aq_clear_pxe_mode(hw, NULL);
1401
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001402 /* Clear single descriptor fetch/write-back mode */
1403 reg = rd32(hw, I40E_GLLAN_RCTL_0);
Jesse Brandeburg7134f9c2013-11-26 08:56:05 +00001404
1405 if (hw->revision_id == 0) {
1406 /* As a work around clear PXE_MODE instead of setting it */
1407 wr32(hw, I40E_GLLAN_RCTL_0, (reg & (~I40E_GLLAN_RCTL_0_PXE_MODE_MASK)));
1408 } else {
1409 wr32(hw, I40E_GLLAN_RCTL_0, (reg | I40E_GLLAN_RCTL_0_PXE_MODE_MASK));
1410 }
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001411}
1412
1413/**
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001414 * i40e_led_is_mine - helper to find matching led
1415 * @hw: pointer to the hw struct
1416 * @idx: index into GPIO registers
1417 *
1418 * returns: 0 if no match, otherwise the value of the GPIO_CTL register
1419 */
1420static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
1421{
1422 u32 gpio_val = 0;
1423 u32 port;
1424
1425 if (!hw->func_caps.led[idx])
1426 return 0;
1427
1428 gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx));
1429 port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >>
1430 I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT;
1431
1432 /* if PRT_NUM_NA is 1 then this LED is not port specific, OR
1433 * if it is not our port then ignore
1434 */
1435 if ((gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_NA_MASK) ||
1436 (port != hw->port))
1437 return 0;
1438
1439 return gpio_val;
1440}
1441
Matt Jaredb84d5cd2015-02-26 16:11:30 +00001442#define I40E_COMBINED_ACTIVITY 0xA
1443#define I40E_FILTER_ACTIVITY 0xE
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001444#define I40E_LINK_ACTIVITY 0xC
Matt Jaredb84d5cd2015-02-26 16:11:30 +00001445#define I40E_MAC_ACTIVITY 0xD
1446#define I40E_LED0 22
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001447
1448/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001449 * i40e_led_get - return current on/off mode
1450 * @hw: pointer to the hw struct
1451 *
1452 * The value returned is the 'mode' field as defined in the
1453 * GPIO register definitions: 0x0 = off, 0xf = on, and other
1454 * values are variations of possible behaviors relating to
1455 * blink, link, and wire.
1456 **/
1457u32 i40e_led_get(struct i40e_hw *hw)
1458{
Matt Jaredb84d5cd2015-02-26 16:11:30 +00001459 u32 current_mode = 0;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001460 u32 mode = 0;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001461 int i;
1462
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001463 /* as per the documentation GPIO 22-29 are the LED
1464 * GPIO pins named LED0..LED7
1465 */
1466 for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1467 u32 gpio_val = i40e_led_is_mine(hw, i);
1468
1469 if (!gpio_val)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001470 continue;
1471
Matt Jaredb84d5cd2015-02-26 16:11:30 +00001472 /* ignore gpio LED src mode entries related to the activity
1473 * LEDs
1474 */
1475 current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
1476 >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
1477 switch (current_mode) {
1478 case I40E_COMBINED_ACTIVITY:
1479 case I40E_FILTER_ACTIVITY:
1480 case I40E_MAC_ACTIVITY:
1481 continue;
1482 default:
1483 break;
1484 }
1485
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001486 mode = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
1487 I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001488 break;
1489 }
1490
1491 return mode;
1492}
1493
1494/**
1495 * i40e_led_set - set new on/off mode
1496 * @hw: pointer to the hw struct
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001497 * @mode: 0=off, 0xf=on (else see manual for mode details)
1498 * @blink: true if the LED should blink when on, false if steady
1499 *
1500 * if this function is used to turn on the blink it should
1501 * be used to disable the blink when restoring the original state.
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001502 **/
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001503void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001504{
Matt Jaredb84d5cd2015-02-26 16:11:30 +00001505 u32 current_mode = 0;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001506 int i;
1507
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001508 if (mode & 0xfffffff0)
1509 hw_dbg(hw, "invalid mode passed in %X\n", mode);
1510
1511 /* as per the documentation GPIO 22-29 are the LED
1512 * GPIO pins named LED0..LED7
1513 */
1514 for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) {
1515 u32 gpio_val = i40e_led_is_mine(hw, i);
1516
1517 if (!gpio_val)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001518 continue;
1519
Matt Jaredb84d5cd2015-02-26 16:11:30 +00001520 /* ignore gpio LED src mode entries related to the activity
1521 * LEDs
1522 */
1523 current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
1524 >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
1525 switch (current_mode) {
1526 case I40E_COMBINED_ACTIVITY:
1527 case I40E_FILTER_ACTIVITY:
1528 case I40E_MAC_ACTIVITY:
1529 continue;
1530 default:
1531 break;
1532 }
1533
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001534 gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001535 /* this & is a bit of paranoia, but serves as a range check */
1536 gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
1537 I40E_GLGEN_GPIO_CTL_LED_MODE_MASK);
1538
1539 if (mode == I40E_LINK_ACTIVITY)
1540 blink = false;
1541
Matt Jared9be00d62015-01-24 09:58:28 +00001542 if (blink)
Jesse Brandeburg41a1d042015-06-04 16:24:02 -04001543 gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
Matt Jared9be00d62015-01-24 09:58:28 +00001544 else
Jesse Brandeburg41a1d042015-06-04 16:24:02 -04001545 gpio_val &= ~BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001546
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001547 wr32(hw, I40E_GLGEN_GPIO_CTL(i), gpio_val);
Jesse Brandeburg0556a9e2013-11-28 06:39:33 +00001548 break;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001549 }
1550}
1551
1552/* Admin command wrappers */
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001553
1554/**
Catherine Sullivan8109e122014-06-04 08:45:24 +00001555 * i40e_aq_get_phy_capabilities
1556 * @hw: pointer to the hw struct
1557 * @abilities: structure for PHY capabilities to be filled
1558 * @qualified_modules: report Qualified Modules
1559 * @report_init: report init capabilities (active are default)
1560 * @cmd_details: pointer to command details structure or NULL
1561 *
1562 * Returns the various PHY abilities supported on the Port.
1563 **/
1564i40e_status i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
1565 bool qualified_modules, bool report_init,
1566 struct i40e_aq_get_phy_abilities_resp *abilities,
1567 struct i40e_asq_cmd_details *cmd_details)
1568{
1569 struct i40e_aq_desc desc;
1570 i40e_status status;
1571 u16 abilities_size = sizeof(struct i40e_aq_get_phy_abilities_resp);
Jayaprakash Shanmugam49884102017-09-07 08:05:55 -04001572 u16 max_delay = I40E_MAX_PHY_TIMEOUT, total_delay = 0;
Catherine Sullivan8109e122014-06-04 08:45:24 +00001573
1574 if (!abilities)
1575 return I40E_ERR_PARAM;
1576
Jayaprakash Shanmugam49884102017-09-07 08:05:55 -04001577 do {
1578 i40e_fill_default_direct_cmd_desc(&desc,
1579 i40e_aqc_opc_get_phy_abilities);
Catherine Sullivan8109e122014-06-04 08:45:24 +00001580
Jayaprakash Shanmugam49884102017-09-07 08:05:55 -04001581 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
1582 if (abilities_size > I40E_AQ_LARGE_BUF)
1583 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
Catherine Sullivan8109e122014-06-04 08:45:24 +00001584
Jayaprakash Shanmugam49884102017-09-07 08:05:55 -04001585 if (qualified_modules)
1586 desc.params.external.param0 |=
Catherine Sullivan8109e122014-06-04 08:45:24 +00001587 cpu_to_le32(I40E_AQ_PHY_REPORT_QUALIFIED_MODULES);
1588
Jayaprakash Shanmugam49884102017-09-07 08:05:55 -04001589 if (report_init)
1590 desc.params.external.param0 |=
Catherine Sullivan8109e122014-06-04 08:45:24 +00001591 cpu_to_le32(I40E_AQ_PHY_REPORT_INITIAL_VALUES);
1592
Jayaprakash Shanmugam49884102017-09-07 08:05:55 -04001593 status = i40e_asq_send_command(hw, &desc, abilities,
1594 abilities_size, cmd_details);
Catherine Sullivan8109e122014-06-04 08:45:24 +00001595
Jayaprakash Shanmugam49884102017-09-07 08:05:55 -04001596 if (status)
1597 break;
1598
1599 if (hw->aq.asq_last_status == I40E_AQ_RC_EIO) {
1600 status = I40E_ERR_UNKNOWN_PHY;
1601 break;
1602 } else if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN) {
1603 usleep_range(1000, 2000);
1604 total_delay++;
1605 status = I40E_ERR_TIMEOUT;
1606 }
1607 } while ((hw->aq.asq_last_status != I40E_AQ_RC_OK) &&
1608 (total_delay < max_delay));
1609
1610 if (status)
1611 return status;
Catherine Sullivan8109e122014-06-04 08:45:24 +00001612
Carolyn Wyborny31232372016-11-21 13:03:48 -08001613 if (report_init) {
Mitch Williams22b965512017-07-14 09:27:09 -04001614 if (hw->mac.type == I40E_MAC_XL710 &&
1615 hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
Alan Brady8fdb69d2017-10-11 14:49:42 -07001616 hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) {
Mitch Williams22b965512017-07-14 09:27:09 -04001617 status = i40e_aq_get_link_info(hw, true, NULL, NULL);
Alan Brady8fdb69d2017-10-11 14:49:42 -07001618 } else {
1619 hw->phy.phy_types = le32_to_cpu(abilities->phy_type);
1620 hw->phy.phy_types |=
1621 ((u64)abilities->phy_type_ext << 32);
1622 }
Carolyn Wyborny31232372016-11-21 13:03:48 -08001623 }
Kevin Scott3ac67d72015-09-03 17:18:58 -04001624
Catherine Sullivan8109e122014-06-04 08:45:24 +00001625 return status;
1626}
1627
1628/**
Catherine Sullivanc56999f2014-06-04 08:45:26 +00001629 * i40e_aq_set_phy_config
1630 * @hw: pointer to the hw struct
1631 * @config: structure with PHY configuration to be set
1632 * @cmd_details: pointer to command details structure or NULL
1633 *
1634 * Set the various PHY configuration parameters
1635 * supported on the Port.One or more of the Set PHY config parameters may be
1636 * ignored in an MFP mode as the PF may not have the privilege to set some
1637 * of the PHY Config parameters. This status will be indicated by the
1638 * command response.
1639 **/
1640enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
1641 struct i40e_aq_set_phy_config *config,
1642 struct i40e_asq_cmd_details *cmd_details)
1643{
1644 struct i40e_aq_desc desc;
1645 struct i40e_aq_set_phy_config *cmd =
1646 (struct i40e_aq_set_phy_config *)&desc.params.raw;
1647 enum i40e_status_code status;
1648
1649 if (!config)
1650 return I40E_ERR_PARAM;
1651
1652 i40e_fill_default_direct_cmd_desc(&desc,
1653 i40e_aqc_opc_set_phy_config);
1654
1655 *cmd = *config;
1656
1657 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1658
1659 return status;
1660}
1661
1662/**
1663 * i40e_set_fc
1664 * @hw: pointer to the hw struct
1665 *
1666 * Set the requested flow control mode using set_phy_config.
1667 **/
1668enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
1669 bool atomic_restart)
1670{
1671 enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
1672 struct i40e_aq_get_phy_abilities_resp abilities;
1673 struct i40e_aq_set_phy_config config;
1674 enum i40e_status_code status;
1675 u8 pause_mask = 0x0;
1676
1677 *aq_failures = 0x0;
1678
1679 switch (fc_mode) {
1680 case I40E_FC_FULL:
1681 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1682 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1683 break;
1684 case I40E_FC_RX_PAUSE:
1685 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_RX;
1686 break;
1687 case I40E_FC_TX_PAUSE:
1688 pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
1689 break;
1690 default:
1691 break;
1692 }
1693
1694 /* Get the current phy config */
1695 status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
1696 NULL);
1697 if (status) {
1698 *aq_failures |= I40E_SET_FC_AQ_FAIL_GET;
1699 return status;
1700 }
1701
1702 memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
1703 /* clear the old pause settings */
1704 config.abilities = abilities.abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
1705 ~(I40E_AQ_PHY_FLAG_PAUSE_RX);
1706 /* set the new abilities */
1707 config.abilities |= pause_mask;
1708 /* If the abilities have changed, then set the new config */
1709 if (config.abilities != abilities.abilities) {
1710 /* Auto restart link so settings take effect */
1711 if (atomic_restart)
1712 config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
1713 /* Copy over all the old settings */
1714 config.phy_type = abilities.phy_type;
Carolyn Wyborny31232372016-11-21 13:03:48 -08001715 config.phy_type_ext = abilities.phy_type_ext;
Catherine Sullivanc56999f2014-06-04 08:45:26 +00001716 config.link_speed = abilities.link_speed;
1717 config.eee_capability = abilities.eee_capability;
1718 config.eeer = abilities.eeer_val;
1719 config.low_power_ctrl = abilities.d3_lpan;
Carolyn Wyborny60f000a2016-11-21 13:03:49 -08001720 config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
1721 I40E_AQ_PHY_FEC_CONFIG_MASK;
Catherine Sullivanc56999f2014-06-04 08:45:26 +00001722 status = i40e_aq_set_phy_config(hw, &config, NULL);
1723
1724 if (status)
1725 *aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
1726 }
1727 /* Update the link info */
Catherine Sullivan0a862b42015-08-31 19:54:53 -04001728 status = i40e_update_link_info(hw);
Catherine Sullivanc56999f2014-06-04 08:45:26 +00001729 if (status) {
1730 /* Wait a little bit (on 40G cards it sometimes takes a really
1731 * long time for link to come back from the atomic reset)
1732 * and try once more
1733 */
1734 msleep(1000);
Catherine Sullivan0a862b42015-08-31 19:54:53 -04001735 status = i40e_update_link_info(hw);
Catherine Sullivanc56999f2014-06-04 08:45:26 +00001736 }
1737 if (status)
1738 *aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
1739
1740 return status;
1741}
1742
1743/**
Shannon Nelsonc9b9b0a2014-04-09 05:59:05 +00001744 * i40e_aq_clear_pxe_mode
1745 * @hw: pointer to the hw struct
1746 * @cmd_details: pointer to command details structure or NULL
1747 *
1748 * Tell the firmware that the driver is taking over from PXE
1749 **/
1750i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
1751 struct i40e_asq_cmd_details *cmd_details)
1752{
1753 i40e_status status;
1754 struct i40e_aq_desc desc;
1755 struct i40e_aqc_clear_pxe *cmd =
1756 (struct i40e_aqc_clear_pxe *)&desc.params.raw;
1757
1758 i40e_fill_default_direct_cmd_desc(&desc,
1759 i40e_aqc_opc_clear_pxe_mode);
1760
1761 cmd->rx_cnt = 0x2;
1762
1763 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1764
1765 wr32(hw, I40E_GLLAN_RCTL_0, 0x1);
1766
1767 return status;
1768}
1769
1770/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001771 * i40e_aq_set_link_restart_an
1772 * @hw: pointer to the hw struct
Catherine Sullivan1ac978a2014-06-04 01:23:20 +00001773 * @enable_link: if true: enable link, if false: disable link
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001774 * @cmd_details: pointer to command details structure or NULL
1775 *
1776 * Sets up the link and restarts the Auto-Negotiation over the link.
1777 **/
1778i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
Catherine Sullivan1ac978a2014-06-04 01:23:20 +00001779 bool enable_link,
1780 struct i40e_asq_cmd_details *cmd_details)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001781{
1782 struct i40e_aq_desc desc;
1783 struct i40e_aqc_set_link_restart_an *cmd =
1784 (struct i40e_aqc_set_link_restart_an *)&desc.params.raw;
1785 i40e_status status;
1786
1787 i40e_fill_default_direct_cmd_desc(&desc,
1788 i40e_aqc_opc_set_link_restart_an);
1789
1790 cmd->command = I40E_AQ_PHY_RESTART_AN;
Catherine Sullivan1ac978a2014-06-04 01:23:20 +00001791 if (enable_link)
1792 cmd->command |= I40E_AQ_PHY_LINK_ENABLE;
1793 else
1794 cmd->command &= ~I40E_AQ_PHY_LINK_ENABLE;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001795
1796 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1797
1798 return status;
1799}
1800
1801/**
1802 * i40e_aq_get_link_info
1803 * @hw: pointer to the hw struct
1804 * @enable_lse: enable/disable LinkStatusEvent reporting
1805 * @link: pointer to link status structure - optional
1806 * @cmd_details: pointer to command details structure or NULL
1807 *
1808 * Returns the link status of the adapter.
1809 **/
1810i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
1811 bool enable_lse, struct i40e_link_status *link,
1812 struct i40e_asq_cmd_details *cmd_details)
1813{
1814 struct i40e_aq_desc desc;
1815 struct i40e_aqc_get_link_status *resp =
1816 (struct i40e_aqc_get_link_status *)&desc.params.raw;
1817 struct i40e_link_status *hw_link_info = &hw->phy.link_info;
1818 i40e_status status;
Catherine Sullivanc56999f2014-06-04 08:45:26 +00001819 bool tx_pause, rx_pause;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001820 u16 command_flags;
1821
1822 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
1823
1824 if (enable_lse)
1825 command_flags = I40E_AQ_LSE_ENABLE;
1826 else
1827 command_flags = I40E_AQ_LSE_DISABLE;
1828 resp->command_flags = cpu_to_le16(command_flags);
1829
1830 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1831
1832 if (status)
1833 goto aq_get_link_info_exit;
1834
1835 /* save off old link status information */
Mitch Williamsc36bd4a72013-12-18 13:46:04 +00001836 hw->phy.link_info_old = *hw_link_info;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001837
1838 /* update link status */
1839 hw_link_info->phy_type = (enum i40e_aq_phy_type)resp->phy_type;
Jesse Brandeburgbe405eb2013-11-20 10:02:50 +00001840 hw->phy.media_type = i40e_get_media_type(hw);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001841 hw_link_info->link_speed = (enum i40e_aq_link_speed)resp->link_speed;
1842 hw_link_info->link_info = resp->link_info;
1843 hw_link_info->an_info = resp->an_info;
Henry Tieman3e03d7c2016-12-02 12:32:57 -08001844 hw_link_info->fec_info = resp->config & (I40E_AQ_CONFIG_FEC_KR_ENA |
1845 I40E_AQ_CONFIG_FEC_RS_ENA);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001846 hw_link_info->ext_info = resp->ext_info;
Filip Sadowskid60bcc72017-08-22 06:57:43 -04001847 hw_link_info->loopback = resp->loopback & I40E_AQ_LOOPBACK_MASK;
Neerav Parikh6bb3f232014-04-01 07:11:56 +00001848 hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size);
1849 hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
1850
Catherine Sullivanc56999f2014-06-04 08:45:26 +00001851 /* update fc info */
1852 tx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_TX);
1853 rx_pause = !!(resp->an_info & I40E_AQ_LINK_PAUSE_RX);
1854 if (tx_pause & rx_pause)
1855 hw->fc.current_mode = I40E_FC_FULL;
1856 else if (tx_pause)
1857 hw->fc.current_mode = I40E_FC_TX_PAUSE;
1858 else if (rx_pause)
1859 hw->fc.current_mode = I40E_FC_RX_PAUSE;
1860 else
1861 hw->fc.current_mode = I40E_FC_NONE;
1862
Neerav Parikh6bb3f232014-04-01 07:11:56 +00001863 if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
1864 hw_link_info->crc_enable = true;
1865 else
1866 hw_link_info->crc_enable = false;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001867
Filip Sadowski7ed35732016-09-14 16:24:33 -07001868 if (resp->command_flags & cpu_to_le16(I40E_AQ_LSE_IS_ENABLED))
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001869 hw_link_info->lse_enable = true;
1870 else
1871 hw_link_info->lse_enable = false;
1872
Henry Tiemane586bb62016-11-08 13:05:07 -08001873 if ((hw->mac.type == I40E_MAC_XL710) &&
1874 (hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
Catherine Sullivan088c4ee2015-02-26 16:14:12 +00001875 hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
1876 hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
1877
Filip Sadowskid60bcc72017-08-22 06:57:43 -04001878 if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
1879 hw->aq.api_min_ver >= 7) {
1880 __le32 tmp;
1881
1882 memcpy(&tmp, resp->link_type, sizeof(tmp));
1883 hw->phy.phy_types = le32_to_cpu(tmp);
1884 hw->phy.phy_types |= ((u64)resp->link_type_ext << 32);
1885 }
1886
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001887 /* save link status information */
1888 if (link)
Jesse Brandeburgd7595a22013-09-13 08:23:22 +00001889 *link = *hw_link_info;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001890
1891 /* flag cleared so helper functions don't call AQ again */
1892 hw->phy.get_link_info = false;
1893
1894aq_get_link_info_exit:
1895 return status;
1896}
1897
1898/**
Jesse Brandeburg7e2453f2014-09-13 07:40:41 +00001899 * i40e_aq_set_phy_int_mask
1900 * @hw: pointer to the hw struct
1901 * @mask: interrupt mask to be set
1902 * @cmd_details: pointer to command details structure or NULL
1903 *
1904 * Set link interrupt mask.
1905 **/
1906i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
1907 u16 mask,
1908 struct i40e_asq_cmd_details *cmd_details)
1909{
1910 struct i40e_aq_desc desc;
1911 struct i40e_aqc_set_phy_int_mask *cmd =
1912 (struct i40e_aqc_set_phy_int_mask *)&desc.params.raw;
1913 i40e_status status;
1914
1915 i40e_fill_default_direct_cmd_desc(&desc,
1916 i40e_aqc_opc_set_phy_int_mask);
1917
1918 cmd->event_mask = cpu_to_le16(mask);
1919
1920 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1921
1922 return status;
1923}
1924
1925/**
Carolyn Wyborny31b606d2016-02-17 16:12:12 -08001926 * i40e_aq_set_phy_debug
1927 * @hw: pointer to the hw struct
1928 * @cmd_flags: debug command flags
1929 * @cmd_details: pointer to command details structure or NULL
1930 *
1931 * Reset the external PHY.
1932 **/
Jesse Brandeburg61829022016-03-10 14:59:42 -08001933i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
1934 struct i40e_asq_cmd_details *cmd_details)
Carolyn Wyborny31b606d2016-02-17 16:12:12 -08001935{
1936 struct i40e_aq_desc desc;
1937 struct i40e_aqc_set_phy_debug *cmd =
1938 (struct i40e_aqc_set_phy_debug *)&desc.params.raw;
Jesse Brandeburg61829022016-03-10 14:59:42 -08001939 i40e_status status;
Carolyn Wyborny31b606d2016-02-17 16:12:12 -08001940
1941 i40e_fill_default_direct_cmd_desc(&desc,
1942 i40e_aqc_opc_set_phy_debug);
1943
1944 cmd->command_flags = cmd_flags;
1945
1946 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
1947
1948 return status;
1949}
1950
1951/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001952 * i40e_aq_add_vsi
1953 * @hw: pointer to the hw struct
Jeff Kirsher98d44382013-12-21 05:44:42 +00001954 * @vsi_ctx: pointer to a vsi context struct
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001955 * @cmd_details: pointer to command details structure or NULL
1956 *
1957 * Add a VSI context to the hardware.
1958**/
1959i40e_status i40e_aq_add_vsi(struct i40e_hw *hw,
1960 struct i40e_vsi_context *vsi_ctx,
1961 struct i40e_asq_cmd_details *cmd_details)
1962{
1963 struct i40e_aq_desc desc;
1964 struct i40e_aqc_add_get_update_vsi *cmd =
1965 (struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
1966 struct i40e_aqc_add_get_update_vsi_completion *resp =
1967 (struct i40e_aqc_add_get_update_vsi_completion *)
1968 &desc.params.raw;
1969 i40e_status status;
1970
1971 i40e_fill_default_direct_cmd_desc(&desc,
1972 i40e_aqc_opc_add_vsi);
1973
1974 cmd->uplink_seid = cpu_to_le16(vsi_ctx->uplink_seid);
1975 cmd->connection_type = vsi_ctx->connection_type;
1976 cmd->vf_id = vsi_ctx->vf_num;
1977 cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
1978
1979 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00001980
1981 status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
1982 sizeof(vsi_ctx->info), cmd_details);
1983
1984 if (status)
1985 goto aq_add_vsi_exit;
1986
1987 vsi_ctx->seid = le16_to_cpu(resp->seid);
1988 vsi_ctx->vsi_number = le16_to_cpu(resp->vsi_number);
1989 vsi_ctx->vsis_allocated = le16_to_cpu(resp->vsi_used);
1990 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
1991
1992aq_add_vsi_exit:
1993 return status;
1994}
1995
1996/**
Mitch Williamsfb70fab2016-05-16 10:26:31 -07001997 * i40e_aq_set_default_vsi
1998 * @hw: pointer to the hw struct
1999 * @seid: vsi number
2000 * @cmd_details: pointer to command details structure or NULL
2001 **/
2002i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw,
2003 u16 seid,
2004 struct i40e_asq_cmd_details *cmd_details)
2005{
2006 struct i40e_aq_desc desc;
2007 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2008 (struct i40e_aqc_set_vsi_promiscuous_modes *)
2009 &desc.params.raw;
2010 i40e_status status;
2011
2012 i40e_fill_default_direct_cmd_desc(&desc,
2013 i40e_aqc_opc_set_vsi_promiscuous_modes);
2014
2015 cmd->promiscuous_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
2016 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
2017 cmd->seid = cpu_to_le16(seid);
2018
2019 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2020
2021 return status;
2022}
2023
2024/**
2025 * i40e_aq_clear_default_vsi
2026 * @hw: pointer to the hw struct
2027 * @seid: vsi number
2028 * @cmd_details: pointer to command details structure or NULL
2029 **/
2030i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw,
2031 u16 seid,
2032 struct i40e_asq_cmd_details *cmd_details)
2033{
2034 struct i40e_aq_desc desc;
2035 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2036 (struct i40e_aqc_set_vsi_promiscuous_modes *)
2037 &desc.params.raw;
2038 i40e_status status;
2039
2040 i40e_fill_default_direct_cmd_desc(&desc,
2041 i40e_aqc_opc_set_vsi_promiscuous_modes);
2042
2043 cmd->promiscuous_flags = cpu_to_le16(0);
2044 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
2045 cmd->seid = cpu_to_le16(seid);
2046
2047 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2048
2049 return status;
2050}
2051
2052/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002053 * i40e_aq_set_vsi_unicast_promiscuous
2054 * @hw: pointer to the hw struct
2055 * @seid: vsi number
2056 * @set: set unicast promiscuous enable/disable
2057 * @cmd_details: pointer to command details structure or NULL
Anjali Singhai Jainb5569892016-05-03 15:13:12 -07002058 * @rx_only_promisc: flag to decide if egress traffic gets mirrored in promisc
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002059 **/
2060i40e_status i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
Mitch Williams885552a2013-12-21 05:44:41 +00002061 u16 seid, bool set,
Anjali Singhai Jainb5569892016-05-03 15:13:12 -07002062 struct i40e_asq_cmd_details *cmd_details,
2063 bool rx_only_promisc)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002064{
2065 struct i40e_aq_desc desc;
2066 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2067 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2068 i40e_status status;
2069 u16 flags = 0;
2070
2071 i40e_fill_default_direct_cmd_desc(&desc,
2072 i40e_aqc_opc_set_vsi_promiscuous_modes);
2073
Anjali Singhai Jain3b120082016-01-15 14:33:21 -08002074 if (set) {
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002075 flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
Anjali Singhai Jainb5569892016-05-03 15:13:12 -07002076 if (rx_only_promisc &&
2077 (((hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver >= 5)) ||
2078 (hw->aq.api_maj_ver > 1)))
Anjali Singhai Jain3b120082016-01-15 14:33:21 -08002079 flags |= I40E_AQC_SET_VSI_PROMISC_TX;
2080 }
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002081
2082 cmd->promiscuous_flags = cpu_to_le16(flags);
2083
2084 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
Anjali Singhai Jain3b120082016-01-15 14:33:21 -08002085 if (((hw->aq.api_maj_ver >= 1) && (hw->aq.api_min_ver >= 5)) ||
2086 (hw->aq.api_maj_ver > 1))
2087 cmd->valid_flags |= cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_TX);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002088
2089 cmd->seid = cpu_to_le16(seid);
2090 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2091
2092 return status;
2093}
2094
2095/**
2096 * i40e_aq_set_vsi_multicast_promiscuous
2097 * @hw: pointer to the hw struct
2098 * @seid: vsi number
2099 * @set: set multicast promiscuous enable/disable
2100 * @cmd_details: pointer to command details structure or NULL
2101 **/
2102i40e_status i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
2103 u16 seid, bool set, struct i40e_asq_cmd_details *cmd_details)
2104{
2105 struct i40e_aq_desc desc;
2106 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2107 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2108 i40e_status status;
2109 u16 flags = 0;
2110
2111 i40e_fill_default_direct_cmd_desc(&desc,
2112 i40e_aqc_opc_set_vsi_promiscuous_modes);
2113
2114 if (set)
2115 flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2116
2117 cmd->promiscuous_flags = cpu_to_le16(flags);
2118
2119 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2120
2121 cmd->seid = cpu_to_le16(seid);
2122 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2123
2124 return status;
2125}
2126
2127/**
Greg Rose6c41a762016-04-12 08:30:50 -07002128 * i40e_aq_set_vsi_mc_promisc_on_vlan
2129 * @hw: pointer to the hw struct
2130 * @seid: vsi number
2131 * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2132 * @vid: The VLAN tag filter - capture any multicast packet with this VLAN tag
2133 * @cmd_details: pointer to command details structure or NULL
2134 **/
2135enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
2136 u16 seid, bool enable,
2137 u16 vid,
2138 struct i40e_asq_cmd_details *cmd_details)
2139{
2140 struct i40e_aq_desc desc;
2141 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2142 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2143 enum i40e_status_code status;
2144 u16 flags = 0;
2145
2146 i40e_fill_default_direct_cmd_desc(&desc,
2147 i40e_aqc_opc_set_vsi_promiscuous_modes);
2148
2149 if (enable)
2150 flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
2151
2152 cmd->promiscuous_flags = cpu_to_le16(flags);
2153 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
2154 cmd->seid = cpu_to_le16(seid);
2155 cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2156
2157 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2158
2159 return status;
2160}
2161
2162/**
2163 * i40e_aq_set_vsi_uc_promisc_on_vlan
2164 * @hw: pointer to the hw struct
2165 * @seid: vsi number
2166 * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2167 * @vid: The VLAN tag filter - capture any unicast packet with this VLAN tag
2168 * @cmd_details: pointer to command details structure or NULL
2169 **/
2170enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
2171 u16 seid, bool enable,
2172 u16 vid,
2173 struct i40e_asq_cmd_details *cmd_details)
2174{
2175 struct i40e_aq_desc desc;
2176 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2177 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2178 enum i40e_status_code status;
2179 u16 flags = 0;
2180
2181 i40e_fill_default_direct_cmd_desc(&desc,
2182 i40e_aqc_opc_set_vsi_promiscuous_modes);
2183
2184 if (enable)
2185 flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
2186
2187 cmd->promiscuous_flags = cpu_to_le16(flags);
2188 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
2189 cmd->seid = cpu_to_le16(seid);
2190 cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2191
2192 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2193
2194 return status;
2195}
2196
2197/**
Jacob Keller435c0842016-11-08 13:05:10 -08002198 * i40e_aq_set_vsi_bc_promisc_on_vlan
2199 * @hw: pointer to the hw struct
2200 * @seid: vsi number
2201 * @enable: set broadcast promiscuous enable/disable for a given VLAN
2202 * @vid: The VLAN tag filter - capture any broadcast packet with this VLAN tag
2203 * @cmd_details: pointer to command details structure or NULL
2204 **/
2205i40e_status i40e_aq_set_vsi_bc_promisc_on_vlan(struct i40e_hw *hw,
2206 u16 seid, bool enable, u16 vid,
2207 struct i40e_asq_cmd_details *cmd_details)
2208{
2209 struct i40e_aq_desc desc;
2210 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2211 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2212 i40e_status status;
2213 u16 flags = 0;
2214
2215 i40e_fill_default_direct_cmd_desc(&desc,
2216 i40e_aqc_opc_set_vsi_promiscuous_modes);
2217
2218 if (enable)
2219 flags |= I40E_AQC_SET_VSI_PROMISC_BROADCAST;
2220
2221 cmd->promiscuous_flags = cpu_to_le16(flags);
2222 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2223 cmd->seid = cpu_to_le16(seid);
2224 cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
2225
2226 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2227
2228 return status;
2229}
2230
2231/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002232 * i40e_aq_set_vsi_broadcast
2233 * @hw: pointer to the hw struct
2234 * @seid: vsi number
2235 * @set_filter: true to set filter, false to clear filter
2236 * @cmd_details: pointer to command details structure or NULL
2237 *
2238 * Set or clear the broadcast promiscuous flag (filter) for a given VSI.
2239 **/
2240i40e_status i40e_aq_set_vsi_broadcast(struct i40e_hw *hw,
2241 u16 seid, bool set_filter,
2242 struct i40e_asq_cmd_details *cmd_details)
2243{
2244 struct i40e_aq_desc desc;
2245 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2246 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2247 i40e_status status;
2248
2249 i40e_fill_default_direct_cmd_desc(&desc,
2250 i40e_aqc_opc_set_vsi_promiscuous_modes);
2251
2252 if (set_filter)
2253 cmd->promiscuous_flags
2254 |= cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2255 else
2256 cmd->promiscuous_flags
2257 &= cpu_to_le16(~I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2258
2259 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_BROADCAST);
2260 cmd->seid = cpu_to_le16(seid);
2261 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2262
2263 return status;
2264}
2265
2266/**
Kiran Patil7bd68752016-01-04 10:33:07 -08002267 * i40e_aq_set_vsi_vlan_promisc - control the VLAN promiscuous setting
2268 * @hw: pointer to the hw struct
2269 * @seid: vsi number
2270 * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
2271 * @cmd_details: pointer to command details structure or NULL
2272 **/
2273i40e_status i40e_aq_set_vsi_vlan_promisc(struct i40e_hw *hw,
2274 u16 seid, bool enable,
2275 struct i40e_asq_cmd_details *cmd_details)
2276{
2277 struct i40e_aq_desc desc;
2278 struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
2279 (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
2280 i40e_status status;
2281 u16 flags = 0;
2282
2283 i40e_fill_default_direct_cmd_desc(&desc,
2284 i40e_aqc_opc_set_vsi_promiscuous_modes);
2285 if (enable)
2286 flags |= I40E_AQC_SET_VSI_PROMISC_VLAN;
2287
2288 cmd->promiscuous_flags = cpu_to_le16(flags);
2289 cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_VLAN);
2290 cmd->seid = cpu_to_le16(seid);
2291
2292 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2293
2294 return status;
2295}
2296
2297/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002298 * i40e_get_vsi_params - get VSI configuration info
2299 * @hw: pointer to the hw struct
Jeff Kirsher98d44382013-12-21 05:44:42 +00002300 * @vsi_ctx: pointer to a vsi context struct
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002301 * @cmd_details: pointer to command details structure or NULL
2302 **/
2303i40e_status i40e_aq_get_vsi_params(struct i40e_hw *hw,
2304 struct i40e_vsi_context *vsi_ctx,
2305 struct i40e_asq_cmd_details *cmd_details)
2306{
2307 struct i40e_aq_desc desc;
Shannon Nelsonf5ac8572013-11-28 06:39:43 +00002308 struct i40e_aqc_add_get_update_vsi *cmd =
2309 (struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002310 struct i40e_aqc_add_get_update_vsi_completion *resp =
2311 (struct i40e_aqc_add_get_update_vsi_completion *)
2312 &desc.params.raw;
2313 i40e_status status;
2314
2315 i40e_fill_default_direct_cmd_desc(&desc,
2316 i40e_aqc_opc_get_vsi_parameters);
2317
Shannon Nelsonf5ac8572013-11-28 06:39:43 +00002318 cmd->uplink_seid = cpu_to_le16(vsi_ctx->seid);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002319
2320 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002321
2322 status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2323 sizeof(vsi_ctx->info), NULL);
2324
2325 if (status)
2326 goto aq_get_vsi_params_exit;
2327
2328 vsi_ctx->seid = le16_to_cpu(resp->seid);
2329 vsi_ctx->vsi_number = le16_to_cpu(resp->vsi_number);
2330 vsi_ctx->vsis_allocated = le16_to_cpu(resp->vsi_used);
2331 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
2332
2333aq_get_vsi_params_exit:
2334 return status;
2335}
2336
2337/**
2338 * i40e_aq_update_vsi_params
2339 * @hw: pointer to the hw struct
Jeff Kirsher98d44382013-12-21 05:44:42 +00002340 * @vsi_ctx: pointer to a vsi context struct
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002341 * @cmd_details: pointer to command details structure or NULL
2342 *
2343 * Update a VSI context.
2344 **/
2345i40e_status i40e_aq_update_vsi_params(struct i40e_hw *hw,
2346 struct i40e_vsi_context *vsi_ctx,
2347 struct i40e_asq_cmd_details *cmd_details)
2348{
2349 struct i40e_aq_desc desc;
Shannon Nelsonf5ac8572013-11-28 06:39:43 +00002350 struct i40e_aqc_add_get_update_vsi *cmd =
2351 (struct i40e_aqc_add_get_update_vsi *)&desc.params.raw;
Kevin Scottb6cacca2016-03-10 14:59:41 -08002352 struct i40e_aqc_add_get_update_vsi_completion *resp =
2353 (struct i40e_aqc_add_get_update_vsi_completion *)
2354 &desc.params.raw;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002355 i40e_status status;
2356
2357 i40e_fill_default_direct_cmd_desc(&desc,
2358 i40e_aqc_opc_update_vsi_parameters);
Shannon Nelsonf5ac8572013-11-28 06:39:43 +00002359 cmd->uplink_seid = cpu_to_le16(vsi_ctx->seid);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002360
2361 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002362
2363 status = i40e_asq_send_command(hw, &desc, &vsi_ctx->info,
2364 sizeof(vsi_ctx->info), cmd_details);
2365
Kevin Scottb6cacca2016-03-10 14:59:41 -08002366 vsi_ctx->vsis_allocated = le16_to_cpu(resp->vsi_used);
2367 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
2368
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002369 return status;
2370}
2371
2372/**
2373 * i40e_aq_get_switch_config
2374 * @hw: pointer to the hardware structure
2375 * @buf: pointer to the result buffer
2376 * @buf_size: length of input buffer
2377 * @start_seid: seid to start for the report, 0 == beginning
2378 * @cmd_details: pointer to command details structure or NULL
2379 *
2380 * Fill the buf with switch configuration returned from AdminQ command
2381 **/
2382i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
2383 struct i40e_aqc_get_switch_config_resp *buf,
2384 u16 buf_size, u16 *start_seid,
2385 struct i40e_asq_cmd_details *cmd_details)
2386{
2387 struct i40e_aq_desc desc;
2388 struct i40e_aqc_switch_seid *scfg =
2389 (struct i40e_aqc_switch_seid *)&desc.params.raw;
2390 i40e_status status;
2391
2392 i40e_fill_default_direct_cmd_desc(&desc,
2393 i40e_aqc_opc_get_switch_config);
2394 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
2395 if (buf_size > I40E_AQ_LARGE_BUF)
2396 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2397 scfg->seid = cpu_to_le16(*start_seid);
2398
2399 status = i40e_asq_send_command(hw, &desc, buf, buf_size, cmd_details);
2400 *start_seid = le16_to_cpu(scfg->seid);
2401
2402 return status;
2403}
2404
2405/**
Shannon Nelsonf3d58492016-05-03 15:13:11 -07002406 * i40e_aq_set_switch_config
2407 * @hw: pointer to the hardware structure
2408 * @flags: bit flag values to set
2409 * @valid_flags: which bit flags to set
2410 * @cmd_details: pointer to command details structure or NULL
2411 *
2412 * Set switch configuration bits
2413 **/
2414enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw,
2415 u16 flags,
2416 u16 valid_flags,
2417 struct i40e_asq_cmd_details *cmd_details)
2418{
2419 struct i40e_aq_desc desc;
2420 struct i40e_aqc_set_switch_config *scfg =
2421 (struct i40e_aqc_set_switch_config *)&desc.params.raw;
2422 enum i40e_status_code status;
2423
2424 i40e_fill_default_direct_cmd_desc(&desc,
2425 i40e_aqc_opc_set_switch_config);
2426 scfg->flags = cpu_to_le16(flags);
2427 scfg->valid_flags = cpu_to_le16(valid_flags);
Scott Petersonab243ec2017-08-22 06:57:54 -04002428 if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
2429 scfg->switch_tag = cpu_to_le16(hw->switch_tag);
2430 scfg->first_tag = cpu_to_le16(hw->first_tag);
2431 scfg->second_tag = cpu_to_le16(hw->second_tag);
2432 }
Shannon Nelsonf3d58492016-05-03 15:13:11 -07002433 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2434
2435 return status;
2436}
2437
2438/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002439 * i40e_aq_get_firmware_version
2440 * @hw: pointer to the hw struct
2441 * @fw_major_version: firmware major version
2442 * @fw_minor_version: firmware minor version
Shannon Nelson7edf8102015-02-24 06:58:41 +00002443 * @fw_build: firmware build number
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002444 * @api_major_version: major queue version
2445 * @api_minor_version: minor queue version
2446 * @cmd_details: pointer to command details structure or NULL
2447 *
2448 * Get the firmware version from the admin queue commands
2449 **/
2450i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
2451 u16 *fw_major_version, u16 *fw_minor_version,
Shannon Nelson7edf8102015-02-24 06:58:41 +00002452 u32 *fw_build,
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002453 u16 *api_major_version, u16 *api_minor_version,
2454 struct i40e_asq_cmd_details *cmd_details)
2455{
2456 struct i40e_aq_desc desc;
2457 struct i40e_aqc_get_version *resp =
2458 (struct i40e_aqc_get_version *)&desc.params.raw;
2459 i40e_status status;
2460
2461 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_version);
2462
2463 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2464
2465 if (!status) {
Shannon Nelson7edf8102015-02-24 06:58:41 +00002466 if (fw_major_version)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002467 *fw_major_version = le16_to_cpu(resp->fw_major);
Shannon Nelson7edf8102015-02-24 06:58:41 +00002468 if (fw_minor_version)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002469 *fw_minor_version = le16_to_cpu(resp->fw_minor);
Shannon Nelson7edf8102015-02-24 06:58:41 +00002470 if (fw_build)
2471 *fw_build = le32_to_cpu(resp->fw_build);
2472 if (api_major_version)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002473 *api_major_version = le16_to_cpu(resp->api_major);
Shannon Nelson7edf8102015-02-24 06:58:41 +00002474 if (api_minor_version)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002475 *api_minor_version = le16_to_cpu(resp->api_minor);
2476 }
2477
2478 return status;
2479}
2480
2481/**
2482 * i40e_aq_send_driver_version
2483 * @hw: pointer to the hw struct
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002484 * @dv: driver's major, minor version
2485 * @cmd_details: pointer to command details structure or NULL
2486 *
2487 * Send the driver version to the firmware
2488 **/
2489i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
2490 struct i40e_driver_version *dv,
2491 struct i40e_asq_cmd_details *cmd_details)
2492{
2493 struct i40e_aq_desc desc;
2494 struct i40e_aqc_driver_version *cmd =
2495 (struct i40e_aqc_driver_version *)&desc.params.raw;
2496 i40e_status status;
Kevin Scott9d2f98e2014-04-01 07:11:52 +00002497 u16 len;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002498
2499 if (dv == NULL)
2500 return I40E_ERR_PARAM;
2501
2502 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_driver_version);
2503
Kevin Scott3b38cd12015-02-06 08:52:18 +00002504 desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002505 cmd->driver_major_ver = dv->major_version;
2506 cmd->driver_minor_ver = dv->minor_version;
2507 cmd->driver_build_ver = dv->build_version;
2508 cmd->driver_subbuild_ver = dv->subbuild_version;
Shannon Nelsond2466012014-04-01 07:11:45 +00002509
2510 len = 0;
2511 while (len < sizeof(dv->driver_string) &&
2512 (dv->driver_string[len] < 0x80) &&
2513 dv->driver_string[len])
2514 len++;
2515 status = i40e_asq_send_command(hw, &desc, dv->driver_string,
2516 len, cmd_details);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002517
2518 return status;
2519}
2520
2521/**
2522 * i40e_get_link_status - get status of the HW network link
2523 * @hw: pointer to the hw struct
Jesse Brandeburga72a5abc2015-08-26 15:14:19 -04002524 * @link_up: pointer to bool (true/false = linkup/linkdown)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002525 *
Jesse Brandeburga72a5abc2015-08-26 15:14:19 -04002526 * Variable link_up true if link is up, false if link is down.
2527 * The variable link_up is invalid if returned value of status != 0
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002528 *
2529 * Side effect: LinkStatusEvent reporting becomes enabled
2530 **/
Jesse Brandeburga72a5abc2015-08-26 15:14:19 -04002531i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002532{
2533 i40e_status status = 0;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002534
2535 if (hw->phy.get_link_info) {
Catherine Sullivan0a862b42015-08-31 19:54:53 -04002536 status = i40e_update_link_info(hw);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002537
2538 if (status)
Jesse Brandeburga72a5abc2015-08-26 15:14:19 -04002539 i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
2540 status);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002541 }
2542
Jesse Brandeburga72a5abc2015-08-26 15:14:19 -04002543 *link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002544
Jesse Brandeburga72a5abc2015-08-26 15:14:19 -04002545 return status;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002546}
2547
2548/**
Catherine Sullivan0a862b42015-08-31 19:54:53 -04002549 * i40e_updatelink_status - update status of the HW network link
2550 * @hw: pointer to the hw struct
2551 **/
2552i40e_status i40e_update_link_info(struct i40e_hw *hw)
2553{
2554 struct i40e_aq_get_phy_abilities_resp abilities;
2555 i40e_status status = 0;
2556
2557 status = i40e_aq_get_link_info(hw, true, NULL, NULL);
2558 if (status)
2559 return status;
2560
Carolyn Wybornyab425cb2016-09-27 11:28:52 -07002561 /* extra checking needed to ensure link info to user is timely */
2562 if ((hw->phy.link_info.link_info & I40E_AQ_MEDIA_AVAILABLE) &&
2563 ((hw->phy.link_info.link_info & I40E_AQ_LINK_UP) ||
2564 !(hw->phy.link_info_old.link_info & I40E_AQ_LINK_UP))) {
Carolyn Wyborny8589af72015-09-28 14:16:56 -04002565 status = i40e_aq_get_phy_capabilities(hw, false, false,
2566 &abilities, NULL);
2567 if (status)
2568 return status;
Catherine Sullivan0a862b42015-08-31 19:54:53 -04002569
Mariusz Stachuraed601f62017-07-12 05:46:08 -04002570 hw->phy.link_info.req_fec_info =
2571 abilities.fec_cfg_curr_mod_ext_info &
2572 (I40E_AQ_REQUEST_FEC_KR | I40E_AQ_REQUEST_FEC_RS);
2573
Carolyn Wyborny8589af72015-09-28 14:16:56 -04002574 memcpy(hw->phy.link_info.module_type, &abilities.module_type,
2575 sizeof(hw->phy.link_info.module_type));
2576 }
Catherine Sullivan0a862b42015-08-31 19:54:53 -04002577
2578 return status;
2579}
2580
2581/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002582 * i40e_aq_add_veb - Insert a VEB between the VSI and the MAC
2583 * @hw: pointer to the hw struct
2584 * @uplink_seid: the MAC or other gizmo SEID
2585 * @downlink_seid: the VSI SEID
2586 * @enabled_tc: bitmap of TCs to be enabled
2587 * @default_port: true for default port VSI, false for control port
2588 * @veb_seid: pointer to where to put the resulting VEB SEID
Shannon Nelson8a187f42016-01-13 16:51:41 -08002589 * @enable_stats: true to turn on VEB stats
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002590 * @cmd_details: pointer to command details structure or NULL
2591 *
2592 * This asks the FW to add a VEB between the uplink and downlink
2593 * elements. If the uplink SEID is 0, this will be a floating VEB.
2594 **/
2595i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
2596 u16 downlink_seid, u8 enabled_tc,
Shannon Nelson8a187f42016-01-13 16:51:41 -08002597 bool default_port, u16 *veb_seid,
2598 bool enable_stats,
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002599 struct i40e_asq_cmd_details *cmd_details)
2600{
2601 struct i40e_aq_desc desc;
2602 struct i40e_aqc_add_veb *cmd =
2603 (struct i40e_aqc_add_veb *)&desc.params.raw;
2604 struct i40e_aqc_add_veb_completion *resp =
2605 (struct i40e_aqc_add_veb_completion *)&desc.params.raw;
2606 i40e_status status;
2607 u16 veb_flags = 0;
2608
2609 /* SEIDs need to either both be set or both be 0 for floating VEB */
2610 if (!!uplink_seid != !!downlink_seid)
2611 return I40E_ERR_PARAM;
2612
2613 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_veb);
2614
2615 cmd->uplink_seid = cpu_to_le16(uplink_seid);
2616 cmd->downlink_seid = cpu_to_le16(downlink_seid);
2617 cmd->enable_tcs = enabled_tc;
2618 if (!uplink_seid)
2619 veb_flags |= I40E_AQC_ADD_VEB_FLOATING;
2620 if (default_port)
2621 veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DEFAULT;
2622 else
2623 veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;
Kevin Scotte1c51b952013-11-20 10:02:51 +00002624
Shannon Nelson8a187f42016-01-13 16:51:41 -08002625 /* reverse logic here: set the bitflag to disable the stats */
2626 if (!enable_stats)
2627 veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;
Kevin Scotte1c51b952013-11-20 10:02:51 +00002628
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002629 cmd->veb_flags = cpu_to_le16(veb_flags);
2630
2631 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2632
2633 if (!status && veb_seid)
2634 *veb_seid = le16_to_cpu(resp->veb_seid);
2635
2636 return status;
2637}
2638
2639/**
2640 * i40e_aq_get_veb_parameters - Retrieve VEB parameters
2641 * @hw: pointer to the hw struct
2642 * @veb_seid: the SEID of the VEB to query
2643 * @switch_id: the uplink switch id
Jeff Kirsher98d44382013-12-21 05:44:42 +00002644 * @floating: set to true if the VEB is floating
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002645 * @statistic_index: index of the stats counter block for this VEB
2646 * @vebs_used: number of VEB's used by function
Jeff Kirsher98d44382013-12-21 05:44:42 +00002647 * @vebs_free: total VEB's not reserved by any function
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002648 * @cmd_details: pointer to command details structure or NULL
2649 *
2650 * This retrieves the parameters for a particular VEB, specified by
2651 * uplink_seid, and returns them to the caller.
2652 **/
2653i40e_status i40e_aq_get_veb_parameters(struct i40e_hw *hw,
2654 u16 veb_seid, u16 *switch_id,
2655 bool *floating, u16 *statistic_index,
2656 u16 *vebs_used, u16 *vebs_free,
2657 struct i40e_asq_cmd_details *cmd_details)
2658{
2659 struct i40e_aq_desc desc;
2660 struct i40e_aqc_get_veb_parameters_completion *cmd_resp =
2661 (struct i40e_aqc_get_veb_parameters_completion *)
2662 &desc.params.raw;
2663 i40e_status status;
2664
2665 if (veb_seid == 0)
2666 return I40E_ERR_PARAM;
2667
2668 i40e_fill_default_direct_cmd_desc(&desc,
2669 i40e_aqc_opc_get_veb_parameters);
2670 cmd_resp->seid = cpu_to_le16(veb_seid);
2671
2672 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2673 if (status)
2674 goto get_veb_exit;
2675
2676 if (switch_id)
2677 *switch_id = le16_to_cpu(cmd_resp->switch_id);
2678 if (statistic_index)
2679 *statistic_index = le16_to_cpu(cmd_resp->statistic_index);
2680 if (vebs_used)
2681 *vebs_used = le16_to_cpu(cmd_resp->vebs_used);
2682 if (vebs_free)
2683 *vebs_free = le16_to_cpu(cmd_resp->vebs_free);
2684 if (floating) {
2685 u16 flags = le16_to_cpu(cmd_resp->veb_flags);
Jesse Brandeburg6995b362015-08-28 17:55:54 -04002686
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002687 if (flags & I40E_AQC_ADD_VEB_FLOATING)
2688 *floating = true;
2689 else
2690 *floating = false;
2691 }
2692
2693get_veb_exit:
2694 return status;
2695}
2696
2697/**
2698 * i40e_aq_add_macvlan
2699 * @hw: pointer to the hw struct
2700 * @seid: VSI for the mac address
2701 * @mv_list: list of macvlans to be added
2702 * @count: length of the list
2703 * @cmd_details: pointer to command details structure or NULL
2704 *
2705 * Add MAC/VLAN addresses to the HW filtering
2706 **/
2707i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
2708 struct i40e_aqc_add_macvlan_element_data *mv_list,
2709 u16 count, struct i40e_asq_cmd_details *cmd_details)
2710{
2711 struct i40e_aq_desc desc;
2712 struct i40e_aqc_macvlan *cmd =
2713 (struct i40e_aqc_macvlan *)&desc.params.raw;
2714 i40e_status status;
2715 u16 buf_size;
Shannon Nelson67be6eb2016-01-13 16:51:40 -08002716 int i;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002717
2718 if (count == 0 || !mv_list || !hw)
2719 return I40E_ERR_PARAM;
2720
Shannon Nelson1efc80e2015-02-27 09:18:30 +00002721 buf_size = count * sizeof(*mv_list);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002722
2723 /* prep the rest of the request */
2724 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan);
2725 cmd->num_addresses = cpu_to_le16(count);
2726 cmd->seid[0] = cpu_to_le16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
2727 cmd->seid[1] = 0;
2728 cmd->seid[2] = 0;
2729
Shannon Nelson67be6eb2016-01-13 16:51:40 -08002730 for (i = 0; i < count; i++)
2731 if (is_multicast_ether_addr(mv_list[i].mac_addr))
2732 mv_list[i].flags |=
2733 cpu_to_le16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);
2734
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002735 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2736 if (buf_size > I40E_AQ_LARGE_BUF)
2737 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2738
2739 status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
Shannon Nelson67be6eb2016-01-13 16:51:40 -08002740 cmd_details);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002741
2742 return status;
2743}
2744
2745/**
2746 * i40e_aq_remove_macvlan
2747 * @hw: pointer to the hw struct
2748 * @seid: VSI for the mac address
2749 * @mv_list: list of macvlans to be removed
2750 * @count: length of the list
2751 * @cmd_details: pointer to command details structure or NULL
2752 *
2753 * Remove MAC/VLAN addresses from the HW filtering
2754 **/
2755i40e_status i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid,
2756 struct i40e_aqc_remove_macvlan_element_data *mv_list,
2757 u16 count, struct i40e_asq_cmd_details *cmd_details)
2758{
2759 struct i40e_aq_desc desc;
2760 struct i40e_aqc_macvlan *cmd =
2761 (struct i40e_aqc_macvlan *)&desc.params.raw;
2762 i40e_status status;
2763 u16 buf_size;
2764
2765 if (count == 0 || !mv_list || !hw)
2766 return I40E_ERR_PARAM;
2767
Shannon Nelson1efc80e2015-02-27 09:18:30 +00002768 buf_size = count * sizeof(*mv_list);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002769
2770 /* prep the rest of the request */
2771 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan);
2772 cmd->num_addresses = cpu_to_le16(count);
2773 cmd->seid[0] = cpu_to_le16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid);
2774 cmd->seid[1] = 0;
2775 cmd->seid[2] = 0;
2776
2777 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2778 if (buf_size > I40E_AQ_LARGE_BUF)
2779 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2780
2781 status = i40e_asq_send_command(hw, &desc, mv_list, buf_size,
2782 cmd_details);
2783
2784 return status;
2785}
2786
2787/**
Kiran Patil7bd68752016-01-04 10:33:07 -08002788 * i40e_mirrorrule_op - Internal helper function to add/delete mirror rule
2789 * @hw: pointer to the hw struct
2790 * @opcode: AQ opcode for add or delete mirror rule
2791 * @sw_seid: Switch SEID (to which rule refers)
2792 * @rule_type: Rule Type (ingress/egress/VLAN)
2793 * @id: Destination VSI SEID or Rule ID
2794 * @count: length of the list
2795 * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
2796 * @cmd_details: pointer to command details structure or NULL
2797 * @rule_id: Rule ID returned from FW
2798 * @rule_used: Number of rules used in internal switch
2799 * @rule_free: Number of rules free in internal switch
2800 *
2801 * Add/Delete a mirror rule to a specific switch. Mirror rules are supported for
2802 * VEBs/VEPA elements only
2803 **/
2804static i40e_status i40e_mirrorrule_op(struct i40e_hw *hw,
2805 u16 opcode, u16 sw_seid, u16 rule_type, u16 id,
2806 u16 count, __le16 *mr_list,
2807 struct i40e_asq_cmd_details *cmd_details,
2808 u16 *rule_id, u16 *rules_used, u16 *rules_free)
2809{
2810 struct i40e_aq_desc desc;
2811 struct i40e_aqc_add_delete_mirror_rule *cmd =
2812 (struct i40e_aqc_add_delete_mirror_rule *)&desc.params.raw;
2813 struct i40e_aqc_add_delete_mirror_rule_completion *resp =
2814 (struct i40e_aqc_add_delete_mirror_rule_completion *)&desc.params.raw;
2815 i40e_status status;
2816 u16 buf_size;
2817
2818 buf_size = count * sizeof(*mr_list);
2819
2820 /* prep the rest of the request */
2821 i40e_fill_default_direct_cmd_desc(&desc, opcode);
2822 cmd->seid = cpu_to_le16(sw_seid);
2823 cmd->rule_type = cpu_to_le16(rule_type &
2824 I40E_AQC_MIRROR_RULE_TYPE_MASK);
2825 cmd->num_entries = cpu_to_le16(count);
2826 /* Dest VSI for add, rule_id for delete */
2827 cmd->destination = cpu_to_le16(id);
2828 if (mr_list) {
2829 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF |
2830 I40E_AQ_FLAG_RD));
2831 if (buf_size > I40E_AQ_LARGE_BUF)
2832 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2833 }
2834
2835 status = i40e_asq_send_command(hw, &desc, mr_list, buf_size,
2836 cmd_details);
2837 if (!status ||
2838 hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) {
2839 if (rule_id)
2840 *rule_id = le16_to_cpu(resp->rule_id);
2841 if (rules_used)
2842 *rules_used = le16_to_cpu(resp->mirror_rules_used);
2843 if (rules_free)
2844 *rules_free = le16_to_cpu(resp->mirror_rules_free);
2845 }
2846 return status;
2847}
2848
2849/**
2850 * i40e_aq_add_mirrorrule - add a mirror rule
2851 * @hw: pointer to the hw struct
2852 * @sw_seid: Switch SEID (to which rule refers)
2853 * @rule_type: Rule Type (ingress/egress/VLAN)
2854 * @dest_vsi: SEID of VSI to which packets will be mirrored
2855 * @count: length of the list
2856 * @mr_list: list of mirrored VSI SEIDs or VLAN IDs
2857 * @cmd_details: pointer to command details structure or NULL
2858 * @rule_id: Rule ID returned from FW
2859 * @rule_used: Number of rules used in internal switch
2860 * @rule_free: Number of rules free in internal switch
2861 *
2862 * Add mirror rule. Mirror rules are supported for VEBs or VEPA elements only
2863 **/
2864i40e_status i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
2865 u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list,
2866 struct i40e_asq_cmd_details *cmd_details,
2867 u16 *rule_id, u16 *rules_used, u16 *rules_free)
2868{
2869 if (!(rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS ||
2870 rule_type == I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS)) {
2871 if (count == 0 || !mr_list)
2872 return I40E_ERR_PARAM;
2873 }
2874
2875 return i40e_mirrorrule_op(hw, i40e_aqc_opc_add_mirror_rule, sw_seid,
2876 rule_type, dest_vsi, count, mr_list,
2877 cmd_details, rule_id, rules_used, rules_free);
2878}
2879
2880/**
2881 * i40e_aq_delete_mirrorrule - delete a mirror rule
2882 * @hw: pointer to the hw struct
2883 * @sw_seid: Switch SEID (to which rule refers)
2884 * @rule_type: Rule Type (ingress/egress/VLAN)
2885 * @count: length of the list
2886 * @rule_id: Rule ID that is returned in the receive desc as part of
2887 * add_mirrorrule.
2888 * @mr_list: list of mirrored VLAN IDs to be removed
2889 * @cmd_details: pointer to command details structure or NULL
2890 * @rule_used: Number of rules used in internal switch
2891 * @rule_free: Number of rules free in internal switch
2892 *
2893 * Delete a mirror rule. Mirror rules are supported for VEBs/VEPA elements only
2894 **/
2895i40e_status i40e_aq_delete_mirrorrule(struct i40e_hw *hw, u16 sw_seid,
2896 u16 rule_type, u16 rule_id, u16 count, __le16 *mr_list,
2897 struct i40e_asq_cmd_details *cmd_details,
2898 u16 *rules_used, u16 *rules_free)
2899{
2900 /* Rule ID has to be valid except rule_type: INGRESS VLAN mirroring */
Greg Rosedb077272016-04-12 08:30:48 -07002901 if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
Kiran Patil7bd68752016-01-04 10:33:07 -08002902 /* count and mr_list shall be valid for rule_type INGRESS VLAN
2903 * mirroring. For other rule_type, count and rule_type should
2904 * not matter.
2905 */
2906 if (count == 0 || !mr_list)
2907 return I40E_ERR_PARAM;
2908 }
2909
2910 return i40e_mirrorrule_op(hw, i40e_aqc_opc_delete_mirror_rule, sw_seid,
2911 rule_type, rule_id, count, mr_list,
2912 cmd_details, NULL, rules_used, rules_free);
2913}
2914
2915/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002916 * i40e_aq_send_msg_to_vf
2917 * @hw: pointer to the hardware structure
Jeff Kirsherb40c82e62015-02-27 09:18:34 +00002918 * @vfid: VF id to send msg
Jeff Kirsher98d44382013-12-21 05:44:42 +00002919 * @v_opcode: opcodes for VF-PF communication
2920 * @v_retval: return error code
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00002921 * @msg: pointer to the msg buffer
2922 * @msglen: msg length
2923 * @cmd_details: pointer to command details
2924 *
2925 * send msg to vf
2926 **/
2927i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
2928 u32 v_opcode, u32 v_retval, u8 *msg, u16 msglen,
2929 struct i40e_asq_cmd_details *cmd_details)
2930{
2931 struct i40e_aq_desc desc;
2932 struct i40e_aqc_pf_vf_message *cmd =
2933 (struct i40e_aqc_pf_vf_message *)&desc.params.raw;
2934 i40e_status status;
2935
2936 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_vf);
2937 cmd->id = cpu_to_le32(vfid);
2938 desc.cookie_high = cpu_to_le32(v_opcode);
2939 desc.cookie_low = cpu_to_le32(v_retval);
2940 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_SI);
2941 if (msglen) {
2942 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF |
2943 I40E_AQ_FLAG_RD));
2944 if (msglen > I40E_AQ_LARGE_BUF)
2945 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2946 desc.datalen = cpu_to_le16(msglen);
2947 }
2948 status = i40e_asq_send_command(hw, &desc, msg, msglen, cmd_details);
2949
2950 return status;
2951}
2952
2953/**
Shannon Nelson9fee9db2014-12-11 07:06:30 +00002954 * i40e_aq_debug_read_register
2955 * @hw: pointer to the hw struct
2956 * @reg_addr: register address
2957 * @reg_val: register value
2958 * @cmd_details: pointer to command details structure or NULL
2959 *
2960 * Read the register using the admin queue commands
2961 **/
2962i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
Jesse Brandeburg7b115dd2015-02-27 09:15:23 +00002963 u32 reg_addr, u64 *reg_val,
Shannon Nelson9fee9db2014-12-11 07:06:30 +00002964 struct i40e_asq_cmd_details *cmd_details)
2965{
2966 struct i40e_aq_desc desc;
2967 struct i40e_aqc_debug_reg_read_write *cmd_resp =
2968 (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
2969 i40e_status status;
2970
2971 if (reg_val == NULL)
2972 return I40E_ERR_PARAM;
2973
Jesse Brandeburg7b115dd2015-02-27 09:15:23 +00002974 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
Shannon Nelson9fee9db2014-12-11 07:06:30 +00002975
2976 cmd_resp->address = cpu_to_le32(reg_addr);
2977
2978 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2979
2980 if (!status) {
Jesse Brandeburg7b115dd2015-02-27 09:15:23 +00002981 *reg_val = ((u64)le32_to_cpu(cmd_resp->value_high) << 32) |
2982 (u64)le32_to_cpu(cmd_resp->value_low);
Shannon Nelson9fee9db2014-12-11 07:06:30 +00002983 }
2984
2985 return status;
2986}
2987
2988/**
Shannon Nelson53db45c2014-08-01 13:27:05 -07002989 * i40e_aq_debug_write_register
2990 * @hw: pointer to the hw struct
2991 * @reg_addr: register address
2992 * @reg_val: register value
2993 * @cmd_details: pointer to command details structure or NULL
2994 *
2995 * Write to a register using the admin queue commands
2996 **/
2997i40e_status i40e_aq_debug_write_register(struct i40e_hw *hw,
2998 u32 reg_addr, u64 reg_val,
2999 struct i40e_asq_cmd_details *cmd_details)
3000{
3001 struct i40e_aq_desc desc;
3002 struct i40e_aqc_debug_reg_read_write *cmd =
3003 (struct i40e_aqc_debug_reg_read_write *)&desc.params.raw;
3004 i40e_status status;
3005
3006 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_write_reg);
3007
3008 cmd->address = cpu_to_le32(reg_addr);
3009 cmd->value_high = cpu_to_le32((u32)(reg_val >> 32));
3010 cmd->value_low = cpu_to_le32((u32)(reg_val & 0xFFFFFFFF));
3011
3012 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3013
3014 return status;
3015}
3016
3017/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003018 * i40e_aq_request_resource
3019 * @hw: pointer to the hw struct
3020 * @resource: resource id
3021 * @access: access type
3022 * @sdp_number: resource number
3023 * @timeout: the maximum time in ms that the driver may hold the resource
3024 * @cmd_details: pointer to command details structure or NULL
3025 *
3026 * requests common resource using the admin queue commands
3027 **/
3028i40e_status i40e_aq_request_resource(struct i40e_hw *hw,
3029 enum i40e_aq_resources_ids resource,
3030 enum i40e_aq_resource_access_type access,
3031 u8 sdp_number, u64 *timeout,
3032 struct i40e_asq_cmd_details *cmd_details)
3033{
3034 struct i40e_aq_desc desc;
3035 struct i40e_aqc_request_resource *cmd_resp =
3036 (struct i40e_aqc_request_resource *)&desc.params.raw;
3037 i40e_status status;
3038
3039 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_request_resource);
3040
3041 cmd_resp->resource_id = cpu_to_le16(resource);
3042 cmd_resp->access_type = cpu_to_le16(access);
3043 cmd_resp->resource_number = cpu_to_le32(sdp_number);
3044
3045 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3046 /* The completion specifies the maximum time in ms that the driver
3047 * may hold the resource in the Timeout field.
3048 * If the resource is held by someone else, the command completes with
3049 * busy return value and the timeout field indicates the maximum time
3050 * the current owner of the resource has to free it.
3051 */
3052 if (!status || hw->aq.asq_last_status == I40E_AQ_RC_EBUSY)
3053 *timeout = le32_to_cpu(cmd_resp->timeout);
3054
3055 return status;
3056}
3057
3058/**
3059 * i40e_aq_release_resource
3060 * @hw: pointer to the hw struct
3061 * @resource: resource id
3062 * @sdp_number: resource number
3063 * @cmd_details: pointer to command details structure or NULL
3064 *
3065 * release common resource using the admin queue commands
3066 **/
3067i40e_status i40e_aq_release_resource(struct i40e_hw *hw,
3068 enum i40e_aq_resources_ids resource,
3069 u8 sdp_number,
3070 struct i40e_asq_cmd_details *cmd_details)
3071{
3072 struct i40e_aq_desc desc;
3073 struct i40e_aqc_request_resource *cmd =
3074 (struct i40e_aqc_request_resource *)&desc.params.raw;
3075 i40e_status status;
3076
3077 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_release_resource);
3078
3079 cmd->resource_id = cpu_to_le16(resource);
3080 cmd->resource_number = cpu_to_le32(sdp_number);
3081
3082 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3083
3084 return status;
3085}
3086
3087/**
3088 * i40e_aq_read_nvm
3089 * @hw: pointer to the hw struct
3090 * @module_pointer: module pointer location in words from the NVM beginning
3091 * @offset: byte offset from the module beginning
3092 * @length: length of the section to be read (in bytes from the offset)
3093 * @data: command buffer (size [bytes] = length)
3094 * @last_command: tells if this is the last command in a series
3095 * @cmd_details: pointer to command details structure or NULL
3096 *
3097 * Read the NVM using the admin queue commands
3098 **/
3099i40e_status i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
3100 u32 offset, u16 length, void *data,
3101 bool last_command,
3102 struct i40e_asq_cmd_details *cmd_details)
3103{
3104 struct i40e_aq_desc desc;
3105 struct i40e_aqc_nvm_update *cmd =
3106 (struct i40e_aqc_nvm_update *)&desc.params.raw;
3107 i40e_status status;
3108
3109 /* In offset the highest byte must be zeroed. */
3110 if (offset & 0xFF000000) {
3111 status = I40E_ERR_PARAM;
3112 goto i40e_aq_read_nvm_exit;
3113 }
3114
3115 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_read);
3116
3117 /* If this is the last command in a series, set the proper flag. */
3118 if (last_command)
3119 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3120 cmd->module_pointer = module_pointer;
3121 cmd->offset = cpu_to_le32(offset);
3122 cmd->length = cpu_to_le16(length);
3123
3124 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3125 if (length > I40E_AQ_LARGE_BUF)
3126 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3127
3128 status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
3129
3130i40e_aq_read_nvm_exit:
3131 return status;
3132}
3133
Shannon Nelsoncd552cb2014-07-09 07:46:09 +00003134/**
3135 * i40e_aq_erase_nvm
3136 * @hw: pointer to the hw struct
3137 * @module_pointer: module pointer location in words from the NVM beginning
3138 * @offset: offset in the module (expressed in 4 KB from module's beginning)
3139 * @length: length of the section to be erased (expressed in 4 KB)
3140 * @last_command: tells if this is the last command in a series
3141 * @cmd_details: pointer to command details structure or NULL
3142 *
3143 * Erase the NVM sector using the admin queue commands
3144 **/
3145i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
3146 u32 offset, u16 length, bool last_command,
3147 struct i40e_asq_cmd_details *cmd_details)
3148{
3149 struct i40e_aq_desc desc;
3150 struct i40e_aqc_nvm_update *cmd =
3151 (struct i40e_aqc_nvm_update *)&desc.params.raw;
3152 i40e_status status;
3153
3154 /* In offset the highest byte must be zeroed. */
3155 if (offset & 0xFF000000) {
3156 status = I40E_ERR_PARAM;
3157 goto i40e_aq_erase_nvm_exit;
3158 }
3159
3160 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_erase);
3161
3162 /* If this is the last command in a series, set the proper flag. */
3163 if (last_command)
3164 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3165 cmd->module_pointer = module_pointer;
3166 cmd->offset = cpu_to_le32(offset);
3167 cmd->length = cpu_to_le16(length);
3168
3169 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3170
3171i40e_aq_erase_nvm_exit:
3172 return status;
3173}
3174
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003175/**
3176 * i40e_parse_discover_capabilities
3177 * @hw: pointer to the hw struct
3178 * @buff: pointer to a buffer containing device/function capability records
3179 * @cap_count: number of capability records in the list
3180 * @list_type_opc: type of capabilities list to parse
3181 *
3182 * Parse the device/function capabilities list.
3183 **/
3184static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
3185 u32 cap_count,
3186 enum i40e_admin_queue_opc list_type_opc)
3187{
3188 struct i40e_aqc_list_capabilities_element_resp *cap;
Shannon Nelson9fee9db2014-12-11 07:06:30 +00003189 u32 valid_functions, num_functions;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003190 u32 number, logical_id, phys_id;
3191 struct i40e_hw_capabilities *p;
Pawel Orlowskic78b9532015-04-22 19:34:06 -04003192 u8 major_rev;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003193 u32 i = 0;
3194 u16 id;
3195
3196 cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
3197
3198 if (list_type_opc == i40e_aqc_opc_list_dev_capabilities)
Joe Perchesb58f2f72014-03-25 04:30:32 +00003199 p = &hw->dev_caps;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003200 else if (list_type_opc == i40e_aqc_opc_list_func_capabilities)
Joe Perchesb58f2f72014-03-25 04:30:32 +00003201 p = &hw->func_caps;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003202 else
3203 return;
3204
3205 for (i = 0; i < cap_count; i++, cap++) {
3206 id = le16_to_cpu(cap->id);
3207 number = le32_to_cpu(cap->number);
3208 logical_id = le32_to_cpu(cap->logical_id);
3209 phys_id = le32_to_cpu(cap->phys_id);
Pawel Orlowskic78b9532015-04-22 19:34:06 -04003210 major_rev = cap->major_rev;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003211
3212 switch (id) {
Shannon Nelson406e7342015-12-10 11:38:49 -08003213 case I40E_AQ_CAP_ID_SWITCH_MODE:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003214 p->switch_mode = number;
3215 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003216 case I40E_AQ_CAP_ID_MNG_MODE:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003217 p->management_mode = number;
Piotr Raczynski64f5ead2016-10-25 16:08:53 -07003218 if (major_rev > 1) {
3219 p->mng_protocols_over_mctp = logical_id;
3220 i40e_debug(hw, I40E_DEBUG_INIT,
3221 "HW Capability: Protocols over MCTP = %d\n",
3222 p->mng_protocols_over_mctp);
3223 } else {
3224 p->mng_protocols_over_mctp = 0;
3225 }
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003226 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003227 case I40E_AQ_CAP_ID_NPAR_ACTIVE:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003228 p->npar_enable = number;
3229 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003230 case I40E_AQ_CAP_ID_OS2BMC_CAP:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003231 p->os2bmc = number;
3232 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003233 case I40E_AQ_CAP_ID_FUNCTIONS_VALID:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003234 p->valid_functions = number;
3235 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003236 case I40E_AQ_CAP_ID_SRIOV:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003237 if (number == 1)
3238 p->sr_iov_1_1 = true;
3239 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003240 case I40E_AQ_CAP_ID_VF:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003241 p->num_vfs = number;
3242 p->vf_base_id = logical_id;
3243 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003244 case I40E_AQ_CAP_ID_VMDQ:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003245 if (number == 1)
3246 p->vmdq = true;
3247 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003248 case I40E_AQ_CAP_ID_8021QBG:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003249 if (number == 1)
3250 p->evb_802_1_qbg = true;
3251 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003252 case I40E_AQ_CAP_ID_8021QBR:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003253 if (number == 1)
3254 p->evb_802_1_qbh = true;
3255 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003256 case I40E_AQ_CAP_ID_VSI:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003257 p->num_vsis = number;
3258 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003259 case I40E_AQ_CAP_ID_DCB:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003260 if (number == 1) {
3261 p->dcb = true;
3262 p->enabled_tcmap = logical_id;
3263 p->maxtc = phys_id;
3264 }
3265 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003266 case I40E_AQ_CAP_ID_FCOE:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003267 if (number == 1)
3268 p->fcoe = true;
3269 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003270 case I40E_AQ_CAP_ID_ISCSI:
Neerav Parikh63d7e5a2014-12-14 01:55:16 +00003271 if (number == 1)
3272 p->iscsi = true;
3273 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003274 case I40E_AQ_CAP_ID_RSS:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003275 p->rss = true;
Carolyn Wybornye157ea32014-06-03 23:50:22 +00003276 p->rss_table_size = number;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003277 p->rss_table_entry_width = logical_id;
3278 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003279 case I40E_AQ_CAP_ID_RXQ:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003280 p->num_rx_qp = number;
3281 p->base_queue = phys_id;
3282 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003283 case I40E_AQ_CAP_ID_TXQ:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003284 p->num_tx_qp = number;
3285 p->base_queue = phys_id;
3286 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003287 case I40E_AQ_CAP_ID_MSIX:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003288 p->num_msix_vectors = number;
Deepthi Kavalur453e16e2016-04-01 03:56:01 -07003289 i40e_debug(hw, I40E_DEBUG_INIT,
3290 "HW Capability: MSIX vector count = %d\n",
3291 p->num_msix_vectors);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003292 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003293 case I40E_AQ_CAP_ID_VF_MSIX:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003294 p->num_msix_vectors_vf = number;
3295 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003296 case I40E_AQ_CAP_ID_FLEX10:
Pawel Orlowskic78b9532015-04-22 19:34:06 -04003297 if (major_rev == 1) {
3298 if (number == 1) {
3299 p->flex10_enable = true;
3300 p->flex10_capable = true;
3301 }
3302 } else {
3303 /* Capability revision >= 2 */
3304 if (number & 1)
3305 p->flex10_enable = true;
3306 if (number & 2)
3307 p->flex10_capable = true;
3308 }
3309 p->flex10_mode = logical_id;
3310 p->flex10_status = phys_id;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003311 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003312 case I40E_AQ_CAP_ID_CEM:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003313 if (number == 1)
3314 p->mgmt_cem = true;
3315 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003316 case I40E_AQ_CAP_ID_IWARP:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003317 if (number == 1)
3318 p->iwarp = true;
3319 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003320 case I40E_AQ_CAP_ID_LED:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003321 if (phys_id < I40E_HW_CAP_MAX_GPIO)
3322 p->led[phys_id] = true;
3323 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003324 case I40E_AQ_CAP_ID_SDP:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003325 if (phys_id < I40E_HW_CAP_MAX_GPIO)
3326 p->sdp[phys_id] = true;
3327 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003328 case I40E_AQ_CAP_ID_MDIO:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003329 if (number == 1) {
3330 p->mdio_port_num = phys_id;
3331 p->mdio_port_mode = logical_id;
3332 }
3333 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003334 case I40E_AQ_CAP_ID_1588:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003335 if (number == 1)
3336 p->ieee_1588 = true;
3337 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003338 case I40E_AQ_CAP_ID_FLOW_DIRECTOR:
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003339 p->fd = true;
3340 p->fd_filters_guaranteed = number;
3341 p->fd_filters_best_effort = logical_id;
3342 break;
Shannon Nelson406e7342015-12-10 11:38:49 -08003343 case I40E_AQ_CAP_ID_WSR_PROT:
Kevin Scott73b23402015-04-07 19:45:38 -04003344 p->wr_csr_prot = (u64)number;
3345 p->wr_csr_prot |= (u64)logical_id << 32;
3346 break;
Michal Kosiarz68a1c5a2016-04-12 08:30:46 -07003347 case I40E_AQ_CAP_ID_NVM_MGMT:
3348 if (number & I40E_NVM_MGMT_SEC_REV_DISABLED)
3349 p->sec_rev_disabled = true;
3350 if (number & I40E_NVM_MGMT_UPDATE_DISABLED)
3351 p->update_disabled = true;
3352 break;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003353 default:
3354 break;
3355 }
3356 }
3357
Vasu Devf18ae102015-04-07 19:45:36 -04003358 if (p->fcoe)
3359 i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
3360
Vasu Dev566bb852014-04-09 05:59:06 +00003361 /* Software override ensuring FCoE is disabled if npar or mfp
3362 * mode because it is not supported in these modes.
3363 */
Pawel Orlowskic78b9532015-04-22 19:34:06 -04003364 if (p->npar_enable || p->flex10_enable)
Vasu Dev566bb852014-04-09 05:59:06 +00003365 p->fcoe = false;
3366
Shannon Nelson9fee9db2014-12-11 07:06:30 +00003367 /* count the enabled ports (aka the "not disabled" ports) */
3368 hw->num_ports = 0;
3369 for (i = 0; i < 4; i++) {
3370 u32 port_cfg_reg = I40E_PRTGEN_CNF + (4 * i);
3371 u64 port_cfg = 0;
3372
3373 /* use AQ read to get the physical register offset instead
3374 * of the port relative offset
3375 */
3376 i40e_aq_debug_read_register(hw, port_cfg_reg, &port_cfg, NULL);
3377 if (!(port_cfg & I40E_PRTGEN_CNF_PORT_DIS_MASK))
3378 hw->num_ports++;
3379 }
3380
3381 valid_functions = p->valid_functions;
3382 num_functions = 0;
3383 while (valid_functions) {
3384 if (valid_functions & 1)
3385 num_functions++;
3386 valid_functions >>= 1;
3387 }
3388
3389 /* partition id is 1-based, and functions are evenly spread
3390 * across the ports as partitions
3391 */
Michal Kosiarz999b3152016-10-11 15:26:56 -07003392 if (hw->num_ports != 0) {
3393 hw->partition_id = (hw->pf_id / hw->num_ports) + 1;
3394 hw->num_partitions = num_functions / hw->num_ports;
3395 }
Shannon Nelson9fee9db2014-12-11 07:06:30 +00003396
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003397 /* additional HW specific goodies that might
3398 * someday be HW version specific
3399 */
3400 p->rx_buf_chain_len = I40E_MAX_CHAINED_RX_BUFFERS;
3401}
3402
3403/**
3404 * i40e_aq_discover_capabilities
3405 * @hw: pointer to the hw struct
3406 * @buff: a virtual buffer to hold the capabilities
3407 * @buff_size: Size of the virtual buffer
3408 * @data_size: Size of the returned data, or buff size needed if AQ err==ENOMEM
3409 * @list_type_opc: capabilities type to discover - pass in the command opcode
3410 * @cmd_details: pointer to command details structure or NULL
3411 *
3412 * Get the device capabilities descriptions from the firmware
3413 **/
3414i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
3415 void *buff, u16 buff_size, u16 *data_size,
3416 enum i40e_admin_queue_opc list_type_opc,
3417 struct i40e_asq_cmd_details *cmd_details)
3418{
3419 struct i40e_aqc_list_capabilites *cmd;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003420 struct i40e_aq_desc desc;
Jesse Brandeburg8fb905b2014-01-17 15:36:33 -08003421 i40e_status status = 0;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003422
3423 cmd = (struct i40e_aqc_list_capabilites *)&desc.params.raw;
3424
3425 if (list_type_opc != i40e_aqc_opc_list_func_capabilities &&
3426 list_type_opc != i40e_aqc_opc_list_dev_capabilities) {
3427 status = I40E_ERR_PARAM;
3428 goto exit;
3429 }
3430
3431 i40e_fill_default_direct_cmd_desc(&desc, list_type_opc);
3432
3433 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3434 if (buff_size > I40E_AQ_LARGE_BUF)
3435 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3436
3437 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
3438 *data_size = le16_to_cpu(desc.datalen);
3439
3440 if (status)
3441 goto exit;
3442
3443 i40e_parse_discover_capabilities(hw, buff, le32_to_cpu(cmd->count),
3444 list_type_opc);
3445
3446exit:
3447 return status;
3448}
3449
3450/**
Shannon Nelsoncd552cb2014-07-09 07:46:09 +00003451 * i40e_aq_update_nvm
3452 * @hw: pointer to the hw struct
3453 * @module_pointer: module pointer location in words from the NVM beginning
3454 * @offset: byte offset from the module beginning
3455 * @length: length of the section to be written (in bytes from the offset)
3456 * @data: command buffer (size [bytes] = length)
3457 * @last_command: tells if this is the last command in a series
3458 * @cmd_details: pointer to command details structure or NULL
3459 *
3460 * Update the NVM using the admin queue commands
3461 **/
3462i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
3463 u32 offset, u16 length, void *data,
3464 bool last_command,
3465 struct i40e_asq_cmd_details *cmd_details)
3466{
3467 struct i40e_aq_desc desc;
3468 struct i40e_aqc_nvm_update *cmd =
3469 (struct i40e_aqc_nvm_update *)&desc.params.raw;
3470 i40e_status status;
3471
3472 /* In offset the highest byte must be zeroed. */
3473 if (offset & 0xFF000000) {
3474 status = I40E_ERR_PARAM;
3475 goto i40e_aq_update_nvm_exit;
3476 }
3477
3478 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
3479
3480 /* If this is the last command in a series, set the proper flag. */
3481 if (last_command)
3482 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3483 cmd->module_pointer = module_pointer;
3484 cmd->offset = cpu_to_le32(offset);
3485 cmd->length = cpu_to_le16(length);
3486
3487 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
3488 if (length > I40E_AQ_LARGE_BUF)
3489 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3490
3491 status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
3492
3493i40e_aq_update_nvm_exit:
3494 return status;
3495}
3496
3497/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003498 * i40e_aq_get_lldp_mib
3499 * @hw: pointer to the hw struct
3500 * @bridge_type: type of bridge requested
3501 * @mib_type: Local, Remote or both Local and Remote MIBs
3502 * @buff: pointer to a user supplied buffer to store the MIB block
3503 * @buff_size: size of the buffer (in bytes)
3504 * @local_len : length of the returned Local LLDP MIB
3505 * @remote_len: length of the returned Remote LLDP MIB
3506 * @cmd_details: pointer to command details structure or NULL
3507 *
3508 * Requests the complete LLDP MIB (entire packet).
3509 **/
3510i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
3511 u8 mib_type, void *buff, u16 buff_size,
3512 u16 *local_len, u16 *remote_len,
3513 struct i40e_asq_cmd_details *cmd_details)
3514{
3515 struct i40e_aq_desc desc;
3516 struct i40e_aqc_lldp_get_mib *cmd =
3517 (struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
3518 struct i40e_aqc_lldp_get_mib *resp =
3519 (struct i40e_aqc_lldp_get_mib *)&desc.params.raw;
3520 i40e_status status;
3521
3522 if (buff_size == 0 || !buff)
3523 return I40E_ERR_PARAM;
3524
3525 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_get_mib);
3526 /* Indirect Command */
3527 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3528
3529 cmd->type = mib_type & I40E_AQ_LLDP_MIB_TYPE_MASK;
3530 cmd->type |= ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) &
3531 I40E_AQ_LLDP_BRIDGE_TYPE_MASK);
3532
3533 desc.datalen = cpu_to_le16(buff_size);
3534
3535 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3536 if (buff_size > I40E_AQ_LARGE_BUF)
3537 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3538
3539 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
3540 if (!status) {
3541 if (local_len != NULL)
3542 *local_len = le16_to_cpu(resp->local_len);
3543 if (remote_len != NULL)
3544 *remote_len = le16_to_cpu(resp->remote_len);
3545 }
3546
3547 return status;
3548}
3549
3550/**
3551 * i40e_aq_cfg_lldp_mib_change_event
3552 * @hw: pointer to the hw struct
3553 * @enable_update: Enable or Disable event posting
3554 * @cmd_details: pointer to command details structure or NULL
3555 *
3556 * Enable or Disable posting of an event on ARQ when LLDP MIB
3557 * associated with the interface changes
3558 **/
3559i40e_status i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw,
3560 bool enable_update,
3561 struct i40e_asq_cmd_details *cmd_details)
3562{
3563 struct i40e_aq_desc desc;
3564 struct i40e_aqc_lldp_update_mib *cmd =
3565 (struct i40e_aqc_lldp_update_mib *)&desc.params.raw;
3566 i40e_status status;
3567
3568 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_mib);
3569
3570 if (!enable_update)
3571 cmd->command |= I40E_AQ_LLDP_MIB_UPDATE_DISABLE;
3572
3573 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3574
3575 return status;
3576}
3577
3578/**
3579 * i40e_aq_stop_lldp
3580 * @hw: pointer to the hw struct
3581 * @shutdown_agent: True if LLDP Agent needs to be Shutdown
3582 * @cmd_details: pointer to command details structure or NULL
3583 *
3584 * Stop or Shutdown the embedded LLDP Agent
3585 **/
3586i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
3587 struct i40e_asq_cmd_details *cmd_details)
3588{
3589 struct i40e_aq_desc desc;
3590 struct i40e_aqc_lldp_stop *cmd =
3591 (struct i40e_aqc_lldp_stop *)&desc.params.raw;
3592 i40e_status status;
3593
3594 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_stop);
3595
3596 if (shutdown_agent)
3597 cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN;
3598
3599 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3600
3601 return status;
3602}
3603
3604/**
3605 * i40e_aq_start_lldp
3606 * @hw: pointer to the hw struct
3607 * @cmd_details: pointer to command details structure or NULL
3608 *
3609 * Start the embedded LLDP Agent on all ports.
3610 **/
3611i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
3612 struct i40e_asq_cmd_details *cmd_details)
3613{
3614 struct i40e_aq_desc desc;
3615 struct i40e_aqc_lldp_start *cmd =
3616 (struct i40e_aqc_lldp_start *)&desc.params.raw;
3617 i40e_status status;
3618
3619 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start);
3620
3621 cmd->command = I40E_AQ_LLDP_AGENT_START;
3622
3623 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3624
3625 return status;
3626}
3627
3628/**
Neerav Parikh9fa61dd2014-11-12 00:18:25 +00003629 * i40e_aq_get_cee_dcb_config
3630 * @hw: pointer to the hw struct
3631 * @buff: response buffer that stores CEE operational configuration
3632 * @buff_size: size of the buffer passed
3633 * @cmd_details: pointer to command details structure or NULL
3634 *
3635 * Get CEE DCBX mode operational configuration from firmware
3636 **/
3637i40e_status i40e_aq_get_cee_dcb_config(struct i40e_hw *hw,
3638 void *buff, u16 buff_size,
3639 struct i40e_asq_cmd_details *cmd_details)
3640{
3641 struct i40e_aq_desc desc;
3642 i40e_status status;
3643
3644 if (buff_size == 0 || !buff)
3645 return I40E_ERR_PARAM;
3646
3647 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_cee_dcb_cfg);
3648
3649 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3650 status = i40e_asq_send_command(hw, &desc, (void *)buff, buff_size,
3651 cmd_details);
3652
3653 return status;
3654}
3655
3656/**
Jeff Kirshera1c9a9d2013-12-28 07:32:18 +00003657 * i40e_aq_add_udp_tunnel
3658 * @hw: pointer to the hw struct
Jacob Keller15d23b42017-06-07 05:43:04 -04003659 * @udp_port: the UDP port to add in Host byte order
Jeff Kirshera1c9a9d2013-12-28 07:32:18 +00003660 * @header_len: length of the tunneling header length in DWords
3661 * @protocol_index: protocol index type
Jeff Kirsher98d44382013-12-21 05:44:42 +00003662 * @filter_index: pointer to filter index
Jeff Kirshera1c9a9d2013-12-28 07:32:18 +00003663 * @cmd_details: pointer to command details structure or NULL
Jacob Keller15d23b42017-06-07 05:43:04 -04003664 *
3665 * Note: Firmware expects the udp_port value to be in Little Endian format,
3666 * and this function will call cpu_to_le16 to convert from Host byte order to
3667 * Little Endian order.
Jeff Kirshera1c9a9d2013-12-28 07:32:18 +00003668 **/
3669i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
Kevin Scottf4f94b92014-04-05 07:46:10 +00003670 u16 udp_port, u8 protocol_index,
3671 u8 *filter_index,
Jeff Kirshera1c9a9d2013-12-28 07:32:18 +00003672 struct i40e_asq_cmd_details *cmd_details)
3673{
3674 struct i40e_aq_desc desc;
3675 struct i40e_aqc_add_udp_tunnel *cmd =
3676 (struct i40e_aqc_add_udp_tunnel *)&desc.params.raw;
3677 struct i40e_aqc_del_udp_tunnel_completion *resp =
3678 (struct i40e_aqc_del_udp_tunnel_completion *)&desc.params.raw;
3679 i40e_status status;
3680
3681 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_udp_tunnel);
3682
3683 cmd->udp_port = cpu_to_le16(udp_port);
Shannon Nelson981b7542013-12-11 08:17:11 +00003684 cmd->protocol_type = protocol_index;
Jeff Kirshera1c9a9d2013-12-28 07:32:18 +00003685
3686 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3687
Shannon Nelson65d13462015-02-21 06:45:28 +00003688 if (!status && filter_index)
Jeff Kirshera1c9a9d2013-12-28 07:32:18 +00003689 *filter_index = resp->index;
3690
3691 return status;
3692}
3693
3694/**
3695 * i40e_aq_del_udp_tunnel
3696 * @hw: pointer to the hw struct
3697 * @index: filter index
3698 * @cmd_details: pointer to command details structure or NULL
3699 **/
3700i40e_status i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
3701 struct i40e_asq_cmd_details *cmd_details)
3702{
3703 struct i40e_aq_desc desc;
3704 struct i40e_aqc_remove_udp_tunnel *cmd =
3705 (struct i40e_aqc_remove_udp_tunnel *)&desc.params.raw;
3706 i40e_status status;
3707
3708 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_del_udp_tunnel);
3709
3710 cmd->index = index;
3711
3712 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3713
3714 return status;
3715}
3716
3717/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003718 * i40e_aq_delete_element - Delete switch element
3719 * @hw: pointer to the hw struct
3720 * @seid: the SEID to delete from the switch
3721 * @cmd_details: pointer to command details structure or NULL
3722 *
3723 * This deletes a switch element from the switch.
3724 **/
3725i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
3726 struct i40e_asq_cmd_details *cmd_details)
3727{
3728 struct i40e_aq_desc desc;
3729 struct i40e_aqc_switch_seid *cmd =
3730 (struct i40e_aqc_switch_seid *)&desc.params.raw;
3731 i40e_status status;
3732
3733 if (seid == 0)
3734 return I40E_ERR_PARAM;
3735
3736 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_delete_element);
3737
3738 cmd->seid = cpu_to_le16(seid);
3739
3740 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3741
3742 return status;
3743}
3744
3745/**
Neerav Parikhafb3ff02014-01-17 15:36:36 -08003746 * i40e_aq_dcb_updated - DCB Updated Command
3747 * @hw: pointer to the hw struct
3748 * @cmd_details: pointer to command details structure or NULL
3749 *
3750 * EMP will return when the shared RPB settings have been
3751 * recomputed and modified. The retval field in the descriptor
3752 * will be set to 0 when RPB is modified.
3753 **/
3754i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
3755 struct i40e_asq_cmd_details *cmd_details)
3756{
3757 struct i40e_aq_desc desc;
3758 i40e_status status;
3759
3760 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_dcb_updated);
3761
3762 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3763
3764 return status;
3765}
3766
3767/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003768 * i40e_aq_tx_sched_cmd - generic Tx scheduler AQ command handler
3769 * @hw: pointer to the hw struct
3770 * @seid: seid for the physical port/switching component/vsi
3771 * @buff: Indirect buffer to hold data parameters and response
3772 * @buff_size: Indirect buffer size
3773 * @opcode: Tx scheduler AQ command opcode
3774 * @cmd_details: pointer to command details structure or NULL
3775 *
3776 * Generic command handler for Tx scheduler AQ commands
3777 **/
3778static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
3779 void *buff, u16 buff_size,
3780 enum i40e_admin_queue_opc opcode,
3781 struct i40e_asq_cmd_details *cmd_details)
3782{
3783 struct i40e_aq_desc desc;
3784 struct i40e_aqc_tx_sched_ind *cmd =
3785 (struct i40e_aqc_tx_sched_ind *)&desc.params.raw;
3786 i40e_status status;
3787 bool cmd_param_flag = false;
3788
3789 switch (opcode) {
3790 case i40e_aqc_opc_configure_vsi_ets_sla_bw_limit:
3791 case i40e_aqc_opc_configure_vsi_tc_bw:
3792 case i40e_aqc_opc_enable_switching_comp_ets:
3793 case i40e_aqc_opc_modify_switching_comp_ets:
3794 case i40e_aqc_opc_disable_switching_comp_ets:
3795 case i40e_aqc_opc_configure_switching_comp_ets_bw_limit:
3796 case i40e_aqc_opc_configure_switching_comp_bw_config:
3797 cmd_param_flag = true;
3798 break;
3799 case i40e_aqc_opc_query_vsi_bw_config:
3800 case i40e_aqc_opc_query_vsi_ets_sla_config:
3801 case i40e_aqc_opc_query_switching_comp_ets_config:
3802 case i40e_aqc_opc_query_port_ets_config:
3803 case i40e_aqc_opc_query_switching_comp_bw_config:
3804 cmd_param_flag = false;
3805 break;
3806 default:
3807 return I40E_ERR_PARAM;
3808 }
3809
3810 i40e_fill_default_direct_cmd_desc(&desc, opcode);
3811
3812 /* Indirect command */
3813 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
3814 if (cmd_param_flag)
3815 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
3816 if (buff_size > I40E_AQ_LARGE_BUF)
3817 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
3818
3819 desc.datalen = cpu_to_le16(buff_size);
3820
3821 cmd->vsi_seid = cpu_to_le16(seid);
3822
3823 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
3824
3825 return status;
3826}
3827
3828/**
Mitch Williams6b192892014-03-06 09:02:29 +00003829 * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
3830 * @hw: pointer to the hw struct
3831 * @seid: VSI seid
3832 * @credit: BW limit credits (0 = disabled)
3833 * @max_credit: Max BW limit credits
3834 * @cmd_details: pointer to command details structure or NULL
3835 **/
3836i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
3837 u16 seid, u16 credit, u8 max_credit,
3838 struct i40e_asq_cmd_details *cmd_details)
3839{
3840 struct i40e_aq_desc desc;
3841 struct i40e_aqc_configure_vsi_bw_limit *cmd =
3842 (struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
3843 i40e_status status;
3844
3845 i40e_fill_default_direct_cmd_desc(&desc,
3846 i40e_aqc_opc_configure_vsi_bw_limit);
3847
3848 cmd->vsi_seid = cpu_to_le16(seid);
3849 cmd->credit = cpu_to_le16(credit);
3850 cmd->max_credit = max_credit;
3851
3852 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
3853
3854 return status;
3855}
3856
3857/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003858 * i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
3859 * @hw: pointer to the hw struct
3860 * @seid: VSI seid
3861 * @bw_data: Buffer holding enabled TCs, relative TC BW limit/credits
3862 * @cmd_details: pointer to command details structure or NULL
3863 **/
3864i40e_status i40e_aq_config_vsi_tc_bw(struct i40e_hw *hw,
3865 u16 seid,
3866 struct i40e_aqc_configure_vsi_tc_bw_data *bw_data,
3867 struct i40e_asq_cmd_details *cmd_details)
3868{
3869 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
3870 i40e_aqc_opc_configure_vsi_tc_bw,
3871 cmd_details);
3872}
3873
3874/**
Neerav Parikhafb3ff02014-01-17 15:36:36 -08003875 * i40e_aq_config_switch_comp_ets - Enable/Disable/Modify ETS on the port
3876 * @hw: pointer to the hw struct
3877 * @seid: seid of the switching component connected to Physical Port
3878 * @ets_data: Buffer holding ETS parameters
3879 * @cmd_details: pointer to command details structure or NULL
3880 **/
3881i40e_status i40e_aq_config_switch_comp_ets(struct i40e_hw *hw,
3882 u16 seid,
3883 struct i40e_aqc_configure_switching_comp_ets_data *ets_data,
3884 enum i40e_admin_queue_opc opcode,
3885 struct i40e_asq_cmd_details *cmd_details)
3886{
3887 return i40e_aq_tx_sched_cmd(hw, seid, (void *)ets_data,
3888 sizeof(*ets_data), opcode, cmd_details);
3889}
3890
3891/**
3892 * i40e_aq_config_switch_comp_bw_config - Config Switch comp BW Alloc per TC
3893 * @hw: pointer to the hw struct
3894 * @seid: seid of the switching component
3895 * @bw_data: Buffer holding enabled TCs, relative/absolute TC BW limit/credits
3896 * @cmd_details: pointer to command details structure or NULL
3897 **/
3898i40e_status i40e_aq_config_switch_comp_bw_config(struct i40e_hw *hw,
3899 u16 seid,
3900 struct i40e_aqc_configure_switching_comp_bw_config_data *bw_data,
3901 struct i40e_asq_cmd_details *cmd_details)
3902{
3903 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
3904 i40e_aqc_opc_configure_switching_comp_bw_config,
3905 cmd_details);
3906}
3907
3908/**
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00003909 * i40e_aq_query_vsi_bw_config - Query VSI BW configuration
3910 * @hw: pointer to the hw struct
3911 * @seid: seid of the VSI
3912 * @bw_data: Buffer to hold VSI BW configuration
3913 * @cmd_details: pointer to command details structure or NULL
3914 **/
3915i40e_status i40e_aq_query_vsi_bw_config(struct i40e_hw *hw,
3916 u16 seid,
3917 struct i40e_aqc_query_vsi_bw_config_resp *bw_data,
3918 struct i40e_asq_cmd_details *cmd_details)
3919{
3920 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
3921 i40e_aqc_opc_query_vsi_bw_config,
3922 cmd_details);
3923}
3924
3925/**
3926 * i40e_aq_query_vsi_ets_sla_config - Query VSI BW configuration per TC
3927 * @hw: pointer to the hw struct
3928 * @seid: seid of the VSI
3929 * @bw_data: Buffer to hold VSI BW configuration per TC
3930 * @cmd_details: pointer to command details structure or NULL
3931 **/
3932i40e_status i40e_aq_query_vsi_ets_sla_config(struct i40e_hw *hw,
3933 u16 seid,
3934 struct i40e_aqc_query_vsi_ets_sla_config_resp *bw_data,
3935 struct i40e_asq_cmd_details *cmd_details)
3936{
3937 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
3938 i40e_aqc_opc_query_vsi_ets_sla_config,
3939 cmd_details);
3940}
3941
3942/**
3943 * i40e_aq_query_switch_comp_ets_config - Query Switch comp BW config per TC
3944 * @hw: pointer to the hw struct
3945 * @seid: seid of the switching component
3946 * @bw_data: Buffer to hold switching component's per TC BW config
3947 * @cmd_details: pointer to command details structure or NULL
3948 **/
3949i40e_status i40e_aq_query_switch_comp_ets_config(struct i40e_hw *hw,
3950 u16 seid,
3951 struct i40e_aqc_query_switching_comp_ets_config_resp *bw_data,
3952 struct i40e_asq_cmd_details *cmd_details)
3953{
3954 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
3955 i40e_aqc_opc_query_switching_comp_ets_config,
3956 cmd_details);
3957}
3958
3959/**
3960 * i40e_aq_query_port_ets_config - Query Physical Port ETS configuration
3961 * @hw: pointer to the hw struct
3962 * @seid: seid of the VSI or switching component connected to Physical Port
3963 * @bw_data: Buffer to hold current ETS configuration for the Physical Port
3964 * @cmd_details: pointer to command details structure or NULL
3965 **/
3966i40e_status i40e_aq_query_port_ets_config(struct i40e_hw *hw,
3967 u16 seid,
3968 struct i40e_aqc_query_port_ets_config_resp *bw_data,
3969 struct i40e_asq_cmd_details *cmd_details)
3970{
3971 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
3972 i40e_aqc_opc_query_port_ets_config,
3973 cmd_details);
3974}
3975
3976/**
3977 * i40e_aq_query_switch_comp_bw_config - Query Switch comp BW configuration
3978 * @hw: pointer to the hw struct
3979 * @seid: seid of the switching component
3980 * @bw_data: Buffer to hold switching component's BW configuration
3981 * @cmd_details: pointer to command details structure or NULL
3982 **/
3983i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
3984 u16 seid,
3985 struct i40e_aqc_query_switching_comp_bw_config_resp *bw_data,
3986 struct i40e_asq_cmd_details *cmd_details)
3987{
3988 return i40e_aq_tx_sched_cmd(hw, seid, (void *)bw_data, sizeof(*bw_data),
3989 i40e_aqc_opc_query_switching_comp_bw_config,
3990 cmd_details);
3991}
3992
3993/**
3994 * i40e_validate_filter_settings
3995 * @hw: pointer to the hardware structure
3996 * @settings: Filter control settings
3997 *
3998 * Check and validate the filter control settings passed.
3999 * The function checks for the valid filter/context sizes being
4000 * passed for FCoE and PE.
4001 *
4002 * Returns 0 if the values passed are valid and within
4003 * range else returns an error.
4004 **/
4005static i40e_status i40e_validate_filter_settings(struct i40e_hw *hw,
4006 struct i40e_filter_control_settings *settings)
4007{
4008 u32 fcoe_cntx_size, fcoe_filt_size;
4009 u32 pe_cntx_size, pe_filt_size;
Anjali Singhai Jain467d7292014-05-10 04:49:02 +00004010 u32 fcoe_fmax;
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00004011 u32 val;
4012
4013 /* Validate FCoE settings passed */
4014 switch (settings->fcoe_filt_num) {
4015 case I40E_HASH_FILTER_SIZE_1K:
4016 case I40E_HASH_FILTER_SIZE_2K:
4017 case I40E_HASH_FILTER_SIZE_4K:
4018 case I40E_HASH_FILTER_SIZE_8K:
4019 case I40E_HASH_FILTER_SIZE_16K:
4020 case I40E_HASH_FILTER_SIZE_32K:
4021 fcoe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
4022 fcoe_filt_size <<= (u32)settings->fcoe_filt_num;
4023 break;
4024 default:
4025 return I40E_ERR_PARAM;
4026 }
4027
4028 switch (settings->fcoe_cntx_num) {
4029 case I40E_DMA_CNTX_SIZE_512:
4030 case I40E_DMA_CNTX_SIZE_1K:
4031 case I40E_DMA_CNTX_SIZE_2K:
4032 case I40E_DMA_CNTX_SIZE_4K:
4033 fcoe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
4034 fcoe_cntx_size <<= (u32)settings->fcoe_cntx_num;
4035 break;
4036 default:
4037 return I40E_ERR_PARAM;
4038 }
4039
4040 /* Validate PE settings passed */
4041 switch (settings->pe_filt_num) {
4042 case I40E_HASH_FILTER_SIZE_1K:
4043 case I40E_HASH_FILTER_SIZE_2K:
4044 case I40E_HASH_FILTER_SIZE_4K:
4045 case I40E_HASH_FILTER_SIZE_8K:
4046 case I40E_HASH_FILTER_SIZE_16K:
4047 case I40E_HASH_FILTER_SIZE_32K:
4048 case I40E_HASH_FILTER_SIZE_64K:
4049 case I40E_HASH_FILTER_SIZE_128K:
4050 case I40E_HASH_FILTER_SIZE_256K:
4051 case I40E_HASH_FILTER_SIZE_512K:
4052 case I40E_HASH_FILTER_SIZE_1M:
4053 pe_filt_size = I40E_HASH_FILTER_BASE_SIZE;
4054 pe_filt_size <<= (u32)settings->pe_filt_num;
4055 break;
4056 default:
4057 return I40E_ERR_PARAM;
4058 }
4059
4060 switch (settings->pe_cntx_num) {
4061 case I40E_DMA_CNTX_SIZE_512:
4062 case I40E_DMA_CNTX_SIZE_1K:
4063 case I40E_DMA_CNTX_SIZE_2K:
4064 case I40E_DMA_CNTX_SIZE_4K:
4065 case I40E_DMA_CNTX_SIZE_8K:
4066 case I40E_DMA_CNTX_SIZE_16K:
4067 case I40E_DMA_CNTX_SIZE_32K:
4068 case I40E_DMA_CNTX_SIZE_64K:
4069 case I40E_DMA_CNTX_SIZE_128K:
4070 case I40E_DMA_CNTX_SIZE_256K:
4071 pe_cntx_size = I40E_DMA_CNTX_BASE_SIZE;
4072 pe_cntx_size <<= (u32)settings->pe_cntx_num;
4073 break;
4074 default:
4075 return I40E_ERR_PARAM;
4076 }
4077
4078 /* FCHSIZE + FCDSIZE should not be greater than PMFCOEFMAX */
4079 val = rd32(hw, I40E_GLHMC_FCOEFMAX);
4080 fcoe_fmax = (val & I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_MASK)
4081 >> I40E_GLHMC_FCOEFMAX_PMFCOEFMAX_SHIFT;
4082 if (fcoe_filt_size + fcoe_cntx_size > fcoe_fmax)
4083 return I40E_ERR_INVALID_SIZE;
4084
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00004085 return 0;
4086}
4087
4088/**
4089 * i40e_set_filter_control
4090 * @hw: pointer to the hardware structure
4091 * @settings: Filter control settings
4092 *
4093 * Set the Queue Filters for PE/FCoE and enable filters required
4094 * for a single PF. It is expected that these settings are programmed
4095 * at the driver initialization time.
4096 **/
4097i40e_status i40e_set_filter_control(struct i40e_hw *hw,
4098 struct i40e_filter_control_settings *settings)
4099{
4100 i40e_status ret = 0;
4101 u32 hash_lut_size = 0;
4102 u32 val;
4103
4104 if (!settings)
4105 return I40E_ERR_PARAM;
4106
4107 /* Validate the input settings */
4108 ret = i40e_validate_filter_settings(hw, settings);
4109 if (ret)
4110 return ret;
4111
4112 /* Read the PF Queue Filter control register */
Shannon Nelsonf6581372016-02-17 16:12:20 -08004113 val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00004114
4115 /* Program required PE hash buckets for the PF */
4116 val &= ~I40E_PFQF_CTL_0_PEHSIZE_MASK;
4117 val |= ((u32)settings->pe_filt_num << I40E_PFQF_CTL_0_PEHSIZE_SHIFT) &
4118 I40E_PFQF_CTL_0_PEHSIZE_MASK;
4119 /* Program required PE contexts for the PF */
4120 val &= ~I40E_PFQF_CTL_0_PEDSIZE_MASK;
4121 val |= ((u32)settings->pe_cntx_num << I40E_PFQF_CTL_0_PEDSIZE_SHIFT) &
4122 I40E_PFQF_CTL_0_PEDSIZE_MASK;
4123
4124 /* Program required FCoE hash buckets for the PF */
4125 val &= ~I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
4126 val |= ((u32)settings->fcoe_filt_num <<
4127 I40E_PFQF_CTL_0_PFFCHSIZE_SHIFT) &
4128 I40E_PFQF_CTL_0_PFFCHSIZE_MASK;
4129 /* Program required FCoE DDP contexts for the PF */
4130 val &= ~I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
4131 val |= ((u32)settings->fcoe_cntx_num <<
4132 I40E_PFQF_CTL_0_PFFCDSIZE_SHIFT) &
4133 I40E_PFQF_CTL_0_PFFCDSIZE_MASK;
4134
4135 /* Program Hash LUT size for the PF */
4136 val &= ~I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
4137 if (settings->hash_lut_size == I40E_HASH_LUT_SIZE_512)
4138 hash_lut_size = 1;
4139 val |= (hash_lut_size << I40E_PFQF_CTL_0_HASHLUTSIZE_SHIFT) &
4140 I40E_PFQF_CTL_0_HASHLUTSIZE_MASK;
4141
4142 /* Enable FDIR, Ethertype and MACVLAN filters for PF and VFs */
4143 if (settings->enable_fdir)
4144 val |= I40E_PFQF_CTL_0_FD_ENA_MASK;
4145 if (settings->enable_ethtype)
4146 val |= I40E_PFQF_CTL_0_ETYPE_ENA_MASK;
4147 if (settings->enable_macvlan)
4148 val |= I40E_PFQF_CTL_0_MACVLAN_ENA_MASK;
4149
Shannon Nelsonf6581372016-02-17 16:12:20 -08004150 i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, val);
Jesse Brandeburg56a62fc2013-09-11 08:40:12 +00004151
4152 return 0;
4153}
Neerav Parikhafb3ff02014-01-17 15:36:36 -08004154
4155/**
4156 * i40e_aq_add_rem_control_packet_filter - Add or Remove Control Packet Filter
4157 * @hw: pointer to the hw struct
4158 * @mac_addr: MAC address to use in the filter
4159 * @ethtype: Ethertype to use in the filter
4160 * @flags: Flags that needs to be applied to the filter
4161 * @vsi_seid: seid of the control VSI
4162 * @queue: VSI queue number to send the packet to
4163 * @is_add: Add control packet filter if True else remove
4164 * @stats: Structure to hold information on control filter counts
4165 * @cmd_details: pointer to command details structure or NULL
4166 *
4167 * This command will Add or Remove control packet filter for a control VSI.
4168 * In return it will update the total number of perfect filter count in
4169 * the stats member.
4170 **/
4171i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
4172 u8 *mac_addr, u16 ethtype, u16 flags,
4173 u16 vsi_seid, u16 queue, bool is_add,
4174 struct i40e_control_filter_stats *stats,
4175 struct i40e_asq_cmd_details *cmd_details)
4176{
4177 struct i40e_aq_desc desc;
4178 struct i40e_aqc_add_remove_control_packet_filter *cmd =
4179 (struct i40e_aqc_add_remove_control_packet_filter *)
4180 &desc.params.raw;
4181 struct i40e_aqc_add_remove_control_packet_filter_completion *resp =
4182 (struct i40e_aqc_add_remove_control_packet_filter_completion *)
4183 &desc.params.raw;
4184 i40e_status status;
4185
4186 if (vsi_seid == 0)
4187 return I40E_ERR_PARAM;
4188
4189 if (is_add) {
4190 i40e_fill_default_direct_cmd_desc(&desc,
4191 i40e_aqc_opc_add_control_packet_filter);
4192 cmd->queue = cpu_to_le16(queue);
4193 } else {
4194 i40e_fill_default_direct_cmd_desc(&desc,
4195 i40e_aqc_opc_remove_control_packet_filter);
4196 }
4197
4198 if (mac_addr)
Jesse Brandeburg6995b362015-08-28 17:55:54 -04004199 ether_addr_copy(cmd->mac, mac_addr);
Neerav Parikhafb3ff02014-01-17 15:36:36 -08004200
4201 cmd->etype = cpu_to_le16(ethtype);
4202 cmd->flags = cpu_to_le16(flags);
4203 cmd->seid = cpu_to_le16(vsi_seid);
4204
4205 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4206
4207 if (!status && stats) {
4208 stats->mac_etype_used = le16_to_cpu(resp->mac_etype_used);
4209 stats->etype_used = le16_to_cpu(resp->etype_used);
4210 stats->mac_etype_free = le16_to_cpu(resp->mac_etype_free);
4211 stats->etype_free = le16_to_cpu(resp->etype_free);
4212 }
4213
4214 return status;
4215}
4216
Catherine Sullivand4dfb812013-11-28 06:39:21 +00004217/**
Anjali Singhai Jaine7358f52015-10-01 14:37:34 -04004218 * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
4219 * @hw: pointer to the hw struct
4220 * @seid: VSI seid to add ethertype filter from
4221 **/
4222#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
4223void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
4224 u16 seid)
4225{
4226 u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
4227 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
4228 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
4229 u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
4230 i40e_status status;
4231
4232 status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
4233 seid, 0, true, NULL,
4234 NULL);
4235 if (status)
4236 hw_dbg(hw, "Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
4237}
4238
4239/**
Greg Rosef4492db2015-02-06 08:52:12 +00004240 * i40e_aq_alternate_read
4241 * @hw: pointer to the hardware structure
4242 * @reg_addr0: address of first dword to be read
4243 * @reg_val0: pointer for data read from 'reg_addr0'
4244 * @reg_addr1: address of second dword to be read
4245 * @reg_val1: pointer for data read from 'reg_addr1'
4246 *
4247 * Read one or two dwords from alternate structure. Fields are indicated
4248 * by 'reg_addr0' and 'reg_addr1' register numbers. If 'reg_val1' pointer
4249 * is not passed then only register at 'reg_addr0' is read.
4250 *
4251 **/
Shannon Nelson37a29732015-02-27 09:15:19 +00004252static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
4253 u32 reg_addr0, u32 *reg_val0,
4254 u32 reg_addr1, u32 *reg_val1)
Greg Rosef4492db2015-02-06 08:52:12 +00004255{
4256 struct i40e_aq_desc desc;
4257 struct i40e_aqc_alternate_write *cmd_resp =
4258 (struct i40e_aqc_alternate_write *)&desc.params.raw;
4259 i40e_status status;
4260
4261 if (!reg_val0)
4262 return I40E_ERR_PARAM;
4263
4264 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_alternate_read);
4265 cmd_resp->address0 = cpu_to_le32(reg_addr0);
4266 cmd_resp->address1 = cpu_to_le32(reg_addr1);
4267
4268 status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
4269
4270 if (!status) {
4271 *reg_val0 = le32_to_cpu(cmd_resp->data0);
4272
4273 if (reg_val1)
4274 *reg_val1 = le32_to_cpu(cmd_resp->data1);
4275 }
4276
4277 return status;
4278}
4279
4280/**
Neerav Parikh2fd75f32014-11-12 00:18:20 +00004281 * i40e_aq_resume_port_tx
4282 * @hw: pointer to the hardware structure
4283 * @cmd_details: pointer to command details structure or NULL
4284 *
4285 * Resume port's Tx traffic
4286 **/
4287i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
4288 struct i40e_asq_cmd_details *cmd_details)
4289{
4290 struct i40e_aq_desc desc;
4291 i40e_status status;
4292
4293 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_resume_port_tx);
4294
4295 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
4296
4297 return status;
4298}
4299
4300/**
Catherine Sullivand4dfb812013-11-28 06:39:21 +00004301 * i40e_set_pci_config_data - store PCI bus info
4302 * @hw: pointer to hardware structure
4303 * @link_status: the link status word from PCI config space
4304 *
4305 * Stores the PCI bus info (speed, width, type) within the i40e_hw structure
4306 **/
4307void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
4308{
4309 hw->bus.type = i40e_bus_type_pci_express;
4310
4311 switch (link_status & PCI_EXP_LNKSTA_NLW) {
4312 case PCI_EXP_LNKSTA_NLW_X1:
4313 hw->bus.width = i40e_bus_width_pcie_x1;
4314 break;
4315 case PCI_EXP_LNKSTA_NLW_X2:
4316 hw->bus.width = i40e_bus_width_pcie_x2;
4317 break;
4318 case PCI_EXP_LNKSTA_NLW_X4:
4319 hw->bus.width = i40e_bus_width_pcie_x4;
4320 break;
4321 case PCI_EXP_LNKSTA_NLW_X8:
4322 hw->bus.width = i40e_bus_width_pcie_x8;
4323 break;
4324 default:
4325 hw->bus.width = i40e_bus_width_unknown;
4326 break;
4327 }
4328
4329 switch (link_status & PCI_EXP_LNKSTA_CLS) {
4330 case PCI_EXP_LNKSTA_CLS_2_5GB:
4331 hw->bus.speed = i40e_bus_speed_2500;
4332 break;
4333 case PCI_EXP_LNKSTA_CLS_5_0GB:
4334 hw->bus.speed = i40e_bus_speed_5000;
4335 break;
4336 case PCI_EXP_LNKSTA_CLS_8_0GB:
4337 hw->bus.speed = i40e_bus_speed_8000;
4338 break;
4339 default:
4340 hw->bus.speed = i40e_bus_speed_unknown;
4341 break;
4342 }
4343}
Greg Rosef4492db2015-02-06 08:52:12 +00004344
4345/**
Jesse Brandeburg3169c322015-04-07 19:45:37 -04004346 * i40e_aq_debug_dump
4347 * @hw: pointer to the hardware structure
4348 * @cluster_id: specific cluster to dump
4349 * @table_id: table id within cluster
4350 * @start_index: index of line in the block to read
4351 * @buff_size: dump buffer size
4352 * @buff: dump buffer
4353 * @ret_buff_size: actual buffer size returned
4354 * @ret_next_table: next block to read
4355 * @ret_next_index: next index to read
4356 *
4357 * Dump internal FW/HW data for debug purposes.
4358 *
4359 **/
4360i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
4361 u8 table_id, u32 start_index, u16 buff_size,
4362 void *buff, u16 *ret_buff_size,
4363 u8 *ret_next_table, u32 *ret_next_index,
4364 struct i40e_asq_cmd_details *cmd_details)
4365{
4366 struct i40e_aq_desc desc;
4367 struct i40e_aqc_debug_dump_internals *cmd =
4368 (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
4369 struct i40e_aqc_debug_dump_internals *resp =
4370 (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
4371 i40e_status status;
4372
4373 if (buff_size == 0 || !buff)
4374 return I40E_ERR_PARAM;
4375
4376 i40e_fill_default_direct_cmd_desc(&desc,
4377 i40e_aqc_opc_debug_dump_internals);
4378 /* Indirect Command */
4379 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
4380 if (buff_size > I40E_AQ_LARGE_BUF)
4381 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
4382
4383 cmd->cluster_id = cluster_id;
4384 cmd->table_id = table_id;
4385 cmd->idx = cpu_to_le32(start_index);
4386
4387 desc.datalen = cpu_to_le16(buff_size);
4388
4389 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
4390 if (!status) {
4391 if (ret_buff_size)
4392 *ret_buff_size = le16_to_cpu(desc.datalen);
4393 if (ret_next_table)
4394 *ret_next_table = resp->table_id;
4395 if (ret_next_index)
4396 *ret_next_index = le32_to_cpu(resp->idx);
4397 }
4398
4399 return status;
4400}
4401
4402/**
Greg Rosef4492db2015-02-06 08:52:12 +00004403 * i40e_read_bw_from_alt_ram
4404 * @hw: pointer to the hardware structure
4405 * @max_bw: pointer for max_bw read
4406 * @min_bw: pointer for min_bw read
4407 * @min_valid: pointer for bool that is true if min_bw is a valid value
4408 * @max_valid: pointer for bool that is true if max_bw is a valid value
4409 *
4410 * Read bw from the alternate ram for the given pf
4411 **/
4412i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
4413 u32 *max_bw, u32 *min_bw,
4414 bool *min_valid, bool *max_valid)
4415{
4416 i40e_status status;
4417 u32 max_bw_addr, min_bw_addr;
4418
4419 /* Calculate the address of the min/max bw registers */
4420 max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
4421 I40E_ALT_STRUCT_MAX_BW_OFFSET +
4422 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
4423 min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
4424 I40E_ALT_STRUCT_MIN_BW_OFFSET +
4425 (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
4426
4427 /* Read the bandwidths from alt ram */
4428 status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
4429 min_bw_addr, min_bw);
4430
4431 if (*min_bw & I40E_ALT_BW_VALID_MASK)
4432 *min_valid = true;
4433 else
4434 *min_valid = false;
4435
4436 if (*max_bw & I40E_ALT_BW_VALID_MASK)
4437 *max_valid = true;
4438 else
4439 *max_valid = false;
4440
4441 return status;
4442}
4443
4444/**
4445 * i40e_aq_configure_partition_bw
4446 * @hw: pointer to the hardware structure
4447 * @bw_data: Buffer holding valid pfs and bw limits
4448 * @cmd_details: pointer to command details
4449 *
4450 * Configure partitions guaranteed/max bw
4451 **/
4452i40e_status i40e_aq_configure_partition_bw(struct i40e_hw *hw,
4453 struct i40e_aqc_configure_partition_bw_data *bw_data,
4454 struct i40e_asq_cmd_details *cmd_details)
4455{
4456 i40e_status status;
4457 struct i40e_aq_desc desc;
4458 u16 bwd_size = sizeof(*bw_data);
4459
4460 i40e_fill_default_direct_cmd_desc(&desc,
4461 i40e_aqc_opc_configure_partition_bw);
4462
4463 /* Indirect command */
4464 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
4465 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD);
4466
4467 if (bwd_size > I40E_AQ_LARGE_BUF)
4468 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
4469
4470 desc.datalen = cpu_to_le16(bwd_size);
4471
4472 status = i40e_asq_send_command(hw, &desc, bw_data, bwd_size,
4473 cmd_details);
4474
4475 return status;
4476}
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004477
4478/**
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004479 * i40e_read_phy_register_clause22
4480 * @hw: pointer to the HW structure
4481 * @reg: register address in the page
4482 * @phy_adr: PHY address on MDIO interface
4483 * @value: PHY register value
4484 *
4485 * Reads specified PHY register value
4486 **/
4487i40e_status i40e_read_phy_register_clause22(struct i40e_hw *hw,
4488 u16 reg, u8 phy_addr, u16 *value)
4489{
4490 i40e_status status = I40E_ERR_TIMEOUT;
4491 u8 port_num = (u8)hw->func_caps.mdio_port_num;
4492 u32 command = 0;
4493 u16 retry = 1000;
4494
4495 command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4496 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4497 (I40E_MDIO_CLAUSE22_OPCODE_READ_MASK) |
4498 (I40E_MDIO_CLAUSE22_STCODE_MASK) |
4499 (I40E_GLGEN_MSCA_MDICMD_MASK);
4500 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4501 do {
4502 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4503 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4504 status = 0;
4505 break;
4506 }
4507 udelay(10);
4508 retry--;
4509 } while (retry);
4510
4511 if (status) {
4512 i40e_debug(hw, I40E_DEBUG_PHY,
4513 "PHY: Can't write command to external PHY.\n");
Henry Tieman27e5f252016-11-08 13:05:06 -08004514 } else {
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004515 command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
4516 *value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
4517 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004518 }
4519
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004520 return status;
4521}
4522
4523/**
4524 * i40e_write_phy_register_clause22
4525 * @hw: pointer to the HW structure
4526 * @reg: register address in the page
4527 * @phy_adr: PHY address on MDIO interface
4528 * @value: PHY register value
4529 *
4530 * Writes specified PHY register value
4531 **/
4532i40e_status i40e_write_phy_register_clause22(struct i40e_hw *hw,
4533 u16 reg, u8 phy_addr, u16 value)
4534{
4535 i40e_status status = I40E_ERR_TIMEOUT;
4536 u8 port_num = (u8)hw->func_caps.mdio_port_num;
4537 u32 command = 0;
4538 u16 retry = 1000;
4539
4540 command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
4541 wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
4542
4543 command = (reg << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4544 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
4545 (I40E_MDIO_CLAUSE22_OPCODE_WRITE_MASK) |
4546 (I40E_MDIO_CLAUSE22_STCODE_MASK) |
4547 (I40E_GLGEN_MSCA_MDICMD_MASK);
4548
4549 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4550 do {
4551 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4552 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4553 status = 0;
4554 break;
4555 }
4556 udelay(10);
4557 retry--;
4558 } while (retry);
4559
4560 return status;
4561}
4562
4563/**
4564 * i40e_read_phy_register_clause45
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004565 * @hw: pointer to the HW structure
4566 * @page: registers page number
4567 * @reg: register address in the page
4568 * @phy_adr: PHY address on MDIO interface
4569 * @value: PHY register value
4570 *
4571 * Reads specified PHY register value
4572 **/
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004573i40e_status i40e_read_phy_register_clause45(struct i40e_hw *hw,
4574 u8 page, u16 reg, u8 phy_addr, u16 *value)
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004575{
4576 i40e_status status = I40E_ERR_TIMEOUT;
4577 u32 command = 0;
4578 u16 retry = 1000;
4579 u8 port_num = hw->func_caps.mdio_port_num;
4580
4581 command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
4582 (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4583 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004584 (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
4585 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004586 (I40E_GLGEN_MSCA_MDICMD_MASK) |
4587 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4588 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4589 do {
4590 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4591 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4592 status = 0;
4593 break;
4594 }
4595 usleep_range(10, 20);
4596 retry--;
4597 } while (retry);
4598
4599 if (status) {
4600 i40e_debug(hw, I40E_DEBUG_PHY,
4601 "PHY: Can't write command to external PHY.\n");
4602 goto phy_read_end;
4603 }
4604
4605 command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4606 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004607 (I40E_MDIO_CLAUSE45_OPCODE_READ_MASK) |
4608 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004609 (I40E_GLGEN_MSCA_MDICMD_MASK) |
4610 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4611 status = I40E_ERR_TIMEOUT;
4612 retry = 1000;
4613 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4614 do {
4615 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4616 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4617 status = 0;
4618 break;
4619 }
4620 usleep_range(10, 20);
4621 retry--;
4622 } while (retry);
4623
4624 if (!status) {
4625 command = rd32(hw, I40E_GLGEN_MSRWD(port_num));
4626 *value = (command & I40E_GLGEN_MSRWD_MDIRDDATA_MASK) >>
4627 I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT;
4628 } else {
4629 i40e_debug(hw, I40E_DEBUG_PHY,
4630 "PHY: Can't read register value from external PHY.\n");
4631 }
4632
4633phy_read_end:
4634 return status;
4635}
4636
4637/**
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004638 * i40e_write_phy_register_clause45
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004639 * @hw: pointer to the HW structure
4640 * @page: registers page number
4641 * @reg: register address in the page
4642 * @phy_adr: PHY address on MDIO interface
4643 * @value: PHY register value
4644 *
4645 * Writes value to specified PHY register
4646 **/
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004647i40e_status i40e_write_phy_register_clause45(struct i40e_hw *hw,
4648 u8 page, u16 reg, u8 phy_addr, u16 value)
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004649{
4650 i40e_status status = I40E_ERR_TIMEOUT;
4651 u32 command = 0;
4652 u16 retry = 1000;
4653 u8 port_num = hw->func_caps.mdio_port_num;
4654
4655 command = (reg << I40E_GLGEN_MSCA_MDIADD_SHIFT) |
4656 (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4657 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004658 (I40E_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK) |
4659 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004660 (I40E_GLGEN_MSCA_MDICMD_MASK) |
4661 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4662 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4663 do {
4664 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4665 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4666 status = 0;
4667 break;
4668 }
4669 usleep_range(10, 20);
4670 retry--;
4671 } while (retry);
4672 if (status) {
4673 i40e_debug(hw, I40E_DEBUG_PHY,
4674 "PHY: Can't write command to external PHY.\n");
4675 goto phy_write_end;
4676 }
4677
4678 command = value << I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT;
4679 wr32(hw, I40E_GLGEN_MSRWD(port_num), command);
4680
4681 command = (page << I40E_GLGEN_MSCA_DEVADD_SHIFT) |
4682 (phy_addr << I40E_GLGEN_MSCA_PHYADD_SHIFT) |
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004683 (I40E_MDIO_CLAUSE45_OPCODE_WRITE_MASK) |
4684 (I40E_MDIO_CLAUSE45_STCODE_MASK) |
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004685 (I40E_GLGEN_MSCA_MDICMD_MASK) |
4686 (I40E_GLGEN_MSCA_MDIINPROGEN_MASK);
4687 status = I40E_ERR_TIMEOUT;
4688 retry = 1000;
4689 wr32(hw, I40E_GLGEN_MSCA(port_num), command);
4690 do {
4691 command = rd32(hw, I40E_GLGEN_MSCA(port_num));
4692 if (!(command & I40E_GLGEN_MSCA_MDICMD_MASK)) {
4693 status = 0;
4694 break;
4695 }
4696 usleep_range(10, 20);
4697 retry--;
4698 } while (retry);
4699
4700phy_write_end:
4701 return status;
4702}
4703
4704/**
Michal Kosiarzf62ba912016-11-21 13:03:50 -08004705 * i40e_write_phy_register
4706 * @hw: pointer to the HW structure
4707 * @page: registers page number
4708 * @reg: register address in the page
4709 * @phy_adr: PHY address on MDIO interface
4710 * @value: PHY register value
4711 *
4712 * Writes value to specified PHY register
4713 **/
4714i40e_status i40e_write_phy_register(struct i40e_hw *hw,
4715 u8 page, u16 reg, u8 phy_addr, u16 value)
4716{
4717 i40e_status status;
4718
4719 switch (hw->device_id) {
4720 case I40E_DEV_ID_1G_BASE_T_X722:
4721 status = i40e_write_phy_register_clause22(hw, reg, phy_addr,
4722 value);
4723 break;
4724 case I40E_DEV_ID_10G_BASE_T:
4725 case I40E_DEV_ID_10G_BASE_T4:
4726 case I40E_DEV_ID_10G_BASE_T_X722:
4727 case I40E_DEV_ID_25G_B:
4728 case I40E_DEV_ID_25G_SFP28:
4729 status = i40e_write_phy_register_clause45(hw, page, reg,
4730 phy_addr, value);
4731 break;
4732 default:
4733 status = I40E_ERR_UNKNOWN_PHY;
4734 break;
4735 }
4736
4737 return status;
4738}
4739
4740/**
4741 * i40e_read_phy_register
4742 * @hw: pointer to the HW structure
4743 * @page: registers page number
4744 * @reg: register address in the page
4745 * @phy_adr: PHY address on MDIO interface
4746 * @value: PHY register value
4747 *
4748 * Reads specified PHY register value
4749 **/
4750i40e_status i40e_read_phy_register(struct i40e_hw *hw,
4751 u8 page, u16 reg, u8 phy_addr, u16 *value)
4752{
4753 i40e_status status;
4754
4755 switch (hw->device_id) {
4756 case I40E_DEV_ID_1G_BASE_T_X722:
4757 status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
4758 value);
4759 break;
4760 case I40E_DEV_ID_10G_BASE_T:
4761 case I40E_DEV_ID_10G_BASE_T4:
4762 case I40E_DEV_ID_10G_BASE_T_X722:
4763 case I40E_DEV_ID_25G_B:
4764 case I40E_DEV_ID_25G_SFP28:
4765 status = i40e_read_phy_register_clause45(hw, page, reg,
4766 phy_addr, value);
4767 break;
4768 default:
4769 status = I40E_ERR_UNKNOWN_PHY;
4770 break;
4771 }
4772
4773 return status;
4774}
4775
4776/**
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004777 * i40e_get_phy_address
4778 * @hw: pointer to the HW structure
4779 * @dev_num: PHY port num that address we want
4780 * @phy_addr: Returned PHY address
4781 *
4782 * Gets PHY address for current port
4783 **/
4784u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num)
4785{
4786 u8 port_num = hw->func_caps.mdio_port_num;
4787 u32 reg_val = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(port_num));
4788
4789 return (u8)(reg_val >> ((dev_num + 1) * 5)) & 0x1f;
4790}
4791
4792/**
4793 * i40e_blink_phy_led
4794 * @hw: pointer to the HW structure
4795 * @time: time how long led will blinks in secs
4796 * @interval: gap between LED on and off in msecs
4797 *
4798 * Blinks PHY link LED
4799 **/
4800i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
4801 u32 time, u32 interval)
4802{
4803 i40e_status status = 0;
4804 u32 i;
4805 u16 led_ctl;
4806 u16 gpio_led_port;
4807 u16 led_reg;
4808 u16 led_addr = I40E_PHY_LED_PROV_REG_1;
4809 u8 phy_addr = 0;
4810 u8 port_num;
4811
4812 i = rd32(hw, I40E_PFGEN_PORTNUM);
4813 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
4814 phy_addr = i40e_get_phy_address(hw, port_num);
4815
4816 for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
4817 led_addr++) {
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004818 status = i40e_read_phy_register_clause45(hw,
4819 I40E_PHY_COM_REG_PAGE,
4820 led_addr, phy_addr,
4821 &led_reg);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004822 if (status)
4823 goto phy_blinking_end;
4824 led_ctl = led_reg;
4825 if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
4826 led_reg = 0;
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004827 status = i40e_write_phy_register_clause45(hw,
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004828 I40E_PHY_COM_REG_PAGE,
4829 led_addr, phy_addr,
4830 led_reg);
4831 if (status)
4832 goto phy_blinking_end;
4833 break;
4834 }
4835 }
4836
4837 if (time > 0 && interval > 0) {
4838 for (i = 0; i < time * 1000; i += interval) {
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004839 status = i40e_read_phy_register_clause45(hw,
4840 I40E_PHY_COM_REG_PAGE,
4841 led_addr, phy_addr, &led_reg);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004842 if (status)
4843 goto restore_config;
4844 if (led_reg & I40E_PHY_LED_MANUAL_ON)
4845 led_reg = 0;
4846 else
4847 led_reg = I40E_PHY_LED_MANUAL_ON;
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004848 status = i40e_write_phy_register_clause45(hw,
4849 I40E_PHY_COM_REG_PAGE,
4850 led_addr, phy_addr, led_reg);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004851 if (status)
4852 goto restore_config;
4853 msleep(interval);
4854 }
4855 }
4856
4857restore_config:
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004858 status = i40e_write_phy_register_clause45(hw,
4859 I40E_PHY_COM_REG_PAGE,
4860 led_addr, phy_addr, led_ctl);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004861
4862phy_blinking_end:
4863 return status;
4864}
4865
4866/**
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04004867 * i40e_led_get_reg - read LED register
4868 * @hw: pointer to the HW structure
4869 * @led_addr: LED register address
4870 * @reg_val: read register value
4871 **/
4872static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
4873 u32 *reg_val)
4874{
4875 enum i40e_status_code status;
4876 u8 phy_addr = 0;
4877 u8 port_num;
4878 u32 i;
4879
4880 *reg_val = 0;
4881 if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
4882 status =
4883 i40e_aq_get_phy_register(hw,
4884 I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
4885 I40E_PHY_COM_REG_PAGE,
4886 I40E_PHY_LED_PROV_REG_1,
4887 reg_val, NULL);
4888 } else {
4889 i = rd32(hw, I40E_PFGEN_PORTNUM);
4890 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
4891 phy_addr = i40e_get_phy_address(hw, port_num);
4892 status = i40e_read_phy_register_clause45(hw,
4893 I40E_PHY_COM_REG_PAGE,
4894 led_addr, phy_addr,
4895 (u16 *)reg_val);
4896 }
4897 return status;
4898}
4899
4900/**
4901 * i40e_led_set_reg - write LED register
4902 * @hw: pointer to the HW structure
4903 * @led_addr: LED register address
4904 * @reg_val: register value to write
4905 **/
4906static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
4907 u32 reg_val)
4908{
4909 enum i40e_status_code status;
4910 u8 phy_addr = 0;
4911 u8 port_num;
4912 u32 i;
4913
4914 if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
4915 status =
4916 i40e_aq_set_phy_register(hw,
4917 I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
4918 I40E_PHY_COM_REG_PAGE,
4919 I40E_PHY_LED_PROV_REG_1,
4920 reg_val, NULL);
4921 } else {
4922 i = rd32(hw, I40E_PFGEN_PORTNUM);
4923 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
4924 phy_addr = i40e_get_phy_address(hw, port_num);
4925 status = i40e_write_phy_register_clause45(hw,
4926 I40E_PHY_COM_REG_PAGE,
4927 led_addr, phy_addr,
4928 (u16)reg_val);
4929 }
4930
4931 return status;
4932}
4933
4934/**
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004935 * i40e_led_get_phy - return current on/off mode
4936 * @hw: pointer to the hw struct
4937 * @led_addr: address of led register to use
4938 * @val: original value of register to use
4939 *
4940 **/
4941i40e_status i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr,
4942 u16 *val)
4943{
4944 i40e_status status = 0;
4945 u16 gpio_led_port;
4946 u8 phy_addr = 0;
4947 u16 reg_val;
4948 u16 temp_addr;
4949 u8 port_num;
4950 u32 i;
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04004951 u32 reg_val_aq;
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004952
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04004953 if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
4954 status =
4955 i40e_aq_get_phy_register(hw,
4956 I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
4957 I40E_PHY_COM_REG_PAGE,
4958 I40E_PHY_LED_PROV_REG_1,
4959 &reg_val_aq, NULL);
4960 if (status == I40E_SUCCESS)
4961 *val = (u16)reg_val_aq;
4962 return status;
4963 }
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004964 temp_addr = I40E_PHY_LED_PROV_REG_1;
4965 i = rd32(hw, I40E_PFGEN_PORTNUM);
4966 port_num = (u8)(i & I40E_PFGEN_PORTNUM_PORT_NUM_MASK);
4967 phy_addr = i40e_get_phy_address(hw, port_num);
4968
4969 for (gpio_led_port = 0; gpio_led_port < 3; gpio_led_port++,
4970 temp_addr++) {
Michal Kosiarz91dc1e52016-10-25 16:08:51 -07004971 status = i40e_read_phy_register_clause45(hw,
4972 I40E_PHY_COM_REG_PAGE,
4973 temp_addr, phy_addr,
4974 &reg_val);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08004975 if (status)
4976 return status;
4977 *val = reg_val;
4978 if (reg_val & I40E_PHY_LED_LINK_MODE_MASK) {
4979 *led_addr = temp_addr;
4980 break;
4981 }
4982 }
4983 return status;
4984}
4985
4986/**
4987 * i40e_led_set_phy
4988 * @hw: pointer to the HW structure
4989 * @on: true or false
4990 * @mode: original val plus bit for set or ignore
4991 * Set led's on or off when controlled by the PHY
4992 *
4993 **/
4994i40e_status i40e_led_set_phy(struct i40e_hw *hw, bool on,
4995 u16 led_addr, u32 mode)
4996{
4997 i40e_status status = 0;
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04004998 u32 led_ctl = 0;
4999 u32 led_reg = 0;
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005000
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04005001 status = i40e_led_get_reg(hw, led_addr, &led_reg);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005002 if (status)
5003 return status;
5004 led_ctl = led_reg;
5005 if (led_reg & I40E_PHY_LED_LINK_MODE_MASK) {
5006 led_reg = 0;
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04005007 status = i40e_led_set_reg(hw, led_addr, led_reg);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005008 if (status)
5009 return status;
5010 }
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04005011 status = i40e_led_get_reg(hw, led_addr, &led_reg);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005012 if (status)
5013 goto restore_config;
5014 if (on)
5015 led_reg = I40E_PHY_LED_MANUAL_ON;
5016 else
5017 led_reg = 0;
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04005018
5019 status = i40e_led_set_reg(hw, led_addr, led_reg);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005020 if (status)
5021 goto restore_config;
5022 if (mode & I40E_PHY_LED_MODE_ORIG) {
5023 led_ctl = (mode & I40E_PHY_LED_MODE_MASK);
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04005024 status = i40e_led_set_reg(hw, led_addr, led_ctl);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005025 }
5026 return status;
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04005027
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005028restore_config:
Mariusz Stachura00f6c2f2017-08-22 06:57:45 -04005029 status = i40e_led_set_reg(hw, led_addr, led_ctl);
Carolyn Wybornyfd077cd2016-02-17 16:12:11 -08005030 return status;
5031}
Shannon Nelsonf6581372016-02-17 16:12:20 -08005032
5033/**
5034 * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
5035 * @hw: pointer to the hw struct
5036 * @reg_addr: register address
5037 * @reg_val: ptr to register value
5038 * @cmd_details: pointer to command details structure or NULL
5039 *
5040 * Use the firmware to read the Rx control register,
5041 * especially useful if the Rx unit is under heavy pressure
5042 **/
5043i40e_status i40e_aq_rx_ctl_read_register(struct i40e_hw *hw,
5044 u32 reg_addr, u32 *reg_val,
5045 struct i40e_asq_cmd_details *cmd_details)
5046{
5047 struct i40e_aq_desc desc;
5048 struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp =
5049 (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
5050 i40e_status status;
5051
5052 if (!reg_val)
5053 return I40E_ERR_PARAM;
5054
5055 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_read);
5056
5057 cmd_resp->address = cpu_to_le32(reg_addr);
5058
5059 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5060
5061 if (status == 0)
5062 *reg_val = le32_to_cpu(cmd_resp->value);
5063
5064 return status;
5065}
5066
5067/**
5068 * i40e_read_rx_ctl - read from an Rx control register
5069 * @hw: pointer to the hw struct
5070 * @reg_addr: register address
5071 **/
5072u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
5073{
5074 i40e_status status = 0;
5075 bool use_register;
5076 int retry = 5;
5077 u32 val = 0;
5078
Paul M Stillwell Jr60303082017-03-10 12:22:02 -08005079 use_register = (((hw->aq.api_maj_ver == 1) &&
5080 (hw->aq.api_min_ver < 5)) ||
5081 (hw->mac.type == I40E_MAC_X722));
Shannon Nelsonf6581372016-02-17 16:12:20 -08005082 if (!use_register) {
5083do_retry:
5084 status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
5085 if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
5086 usleep_range(1000, 2000);
5087 retry--;
5088 goto do_retry;
5089 }
5090 }
5091
5092 /* if the AQ access failed, try the old-fashioned way */
5093 if (status || use_register)
5094 val = rd32(hw, reg_addr);
5095
5096 return val;
5097}
5098
5099/**
5100 * i40e_aq_rx_ctl_write_register
5101 * @hw: pointer to the hw struct
5102 * @reg_addr: register address
5103 * @reg_val: register value
5104 * @cmd_details: pointer to command details structure or NULL
5105 *
5106 * Use the firmware to write to an Rx control register,
5107 * especially useful if the Rx unit is under heavy pressure
5108 **/
5109i40e_status i40e_aq_rx_ctl_write_register(struct i40e_hw *hw,
5110 u32 reg_addr, u32 reg_val,
5111 struct i40e_asq_cmd_details *cmd_details)
5112{
5113 struct i40e_aq_desc desc;
5114 struct i40e_aqc_rx_ctl_reg_read_write *cmd =
5115 (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
5116 i40e_status status;
5117
5118 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_rx_ctl_reg_write);
5119
5120 cmd->address = cpu_to_le32(reg_addr);
5121 cmd->value = cpu_to_le32(reg_val);
5122
5123 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5124
5125 return status;
5126}
5127
5128/**
5129 * i40e_write_rx_ctl - write to an Rx control register
5130 * @hw: pointer to the hw struct
5131 * @reg_addr: register address
5132 * @reg_val: register value
5133 **/
5134void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
5135{
5136 i40e_status status = 0;
5137 bool use_register;
5138 int retry = 5;
5139
Paul M Stillwell Jr60303082017-03-10 12:22:02 -08005140 use_register = (((hw->aq.api_maj_ver == 1) &&
5141 (hw->aq.api_min_ver < 5)) ||
5142 (hw->mac.type == I40E_MAC_X722));
Shannon Nelsonf6581372016-02-17 16:12:20 -08005143 if (!use_register) {
5144do_retry:
5145 status = i40e_aq_rx_ctl_write_register(hw, reg_addr,
5146 reg_val, NULL);
5147 if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) {
5148 usleep_range(1000, 2000);
5149 retry--;
5150 goto do_retry;
5151 }
5152 }
5153
5154 /* if the AQ access failed, try the old-fashioned way */
5155 if (status || use_register)
5156 wr32(hw, reg_addr, reg_val);
5157}
Jingjing Wu1d5c9602017-04-13 04:45:45 -04005158
5159/**
Filip Sadowski9c0e5ca2017-08-22 06:57:44 -04005160 * i40e_aq_set_phy_register
5161 * @hw: pointer to the hw struct
5162 * @phy_select: select which phy should be accessed
5163 * @dev_addr: PHY device address
5164 * @reg_addr: PHY register address
5165 * @reg_val: new register value
5166 * @cmd_details: pointer to command details structure or NULL
5167 *
5168 * Write the external PHY register.
5169 **/
5170i40e_status i40e_aq_set_phy_register(struct i40e_hw *hw,
5171 u8 phy_select, u8 dev_addr,
5172 u32 reg_addr, u32 reg_val,
5173 struct i40e_asq_cmd_details *cmd_details)
5174{
5175 struct i40e_aq_desc desc;
5176 struct i40e_aqc_phy_register_access *cmd =
5177 (struct i40e_aqc_phy_register_access *)&desc.params.raw;
5178 i40e_status status;
5179
5180 i40e_fill_default_direct_cmd_desc(&desc,
5181 i40e_aqc_opc_set_phy_register);
5182
5183 cmd->phy_interface = phy_select;
5184 cmd->dev_address = dev_addr;
5185 cmd->reg_address = cpu_to_le32(reg_addr);
5186 cmd->reg_value = cpu_to_le32(reg_val);
5187
5188 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5189
5190 return status;
5191}
5192
5193/**
5194 * i40e_aq_get_phy_register
5195 * @hw: pointer to the hw struct
5196 * @phy_select: select which phy should be accessed
5197 * @dev_addr: PHY device address
5198 * @reg_addr: PHY register address
5199 * @reg_val: read register value
5200 * @cmd_details: pointer to command details structure or NULL
5201 *
5202 * Read the external PHY register.
5203 **/
5204i40e_status i40e_aq_get_phy_register(struct i40e_hw *hw,
5205 u8 phy_select, u8 dev_addr,
5206 u32 reg_addr, u32 *reg_val,
5207 struct i40e_asq_cmd_details *cmd_details)
5208{
5209 struct i40e_aq_desc desc;
5210 struct i40e_aqc_phy_register_access *cmd =
5211 (struct i40e_aqc_phy_register_access *)&desc.params.raw;
5212 i40e_status status;
5213
5214 i40e_fill_default_direct_cmd_desc(&desc,
5215 i40e_aqc_opc_get_phy_register);
5216
5217 cmd->phy_interface = phy_select;
5218 cmd->dev_address = dev_addr;
5219 cmd->reg_address = cpu_to_le32(reg_addr);
5220
5221 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
5222 if (!status)
5223 *reg_val = le32_to_cpu(cmd->reg_value);
5224
5225 return status;
5226}
5227
5228/**
Jingjing Wu1d5c9602017-04-13 04:45:45 -04005229 * i40e_aq_write_ppp - Write pipeline personalization profile (ppp)
5230 * @hw: pointer to the hw struct
5231 * @buff: command buffer (size in bytes = buff_size)
5232 * @buff_size: buffer size in bytes
5233 * @track_id: package tracking id
5234 * @error_offset: returns error offset
5235 * @error_info: returns error information
5236 * @cmd_details: pointer to command details structure or NULL
5237 **/
5238enum
5239i40e_status_code i40e_aq_write_ppp(struct i40e_hw *hw, void *buff,
5240 u16 buff_size, u32 track_id,
5241 u32 *error_offset, u32 *error_info,
5242 struct i40e_asq_cmd_details *cmd_details)
5243{
5244 struct i40e_aq_desc desc;
5245 struct i40e_aqc_write_personalization_profile *cmd =
5246 (struct i40e_aqc_write_personalization_profile *)
5247 &desc.params.raw;
5248 struct i40e_aqc_write_ppp_resp *resp;
5249 i40e_status status;
5250
5251 i40e_fill_default_direct_cmd_desc(&desc,
5252 i40e_aqc_opc_write_personalization_profile);
5253
5254 desc.flags |= cpu_to_le16(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD);
5255 if (buff_size > I40E_AQ_LARGE_BUF)
5256 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
5257
5258 desc.datalen = cpu_to_le16(buff_size);
5259
5260 cmd->profile_track_id = cpu_to_le32(track_id);
5261
5262 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5263 if (!status) {
5264 resp = (struct i40e_aqc_write_ppp_resp *)&desc.params.raw;
5265 if (error_offset)
5266 *error_offset = le32_to_cpu(resp->error_offset);
5267 if (error_info)
5268 *error_info = le32_to_cpu(resp->error_info);
5269 }
5270
5271 return status;
5272}
5273
5274/**
5275 * i40e_aq_get_ppp_list - Read pipeline personalization profile (ppp)
5276 * @hw: pointer to the hw struct
5277 * @buff: command buffer (size in bytes = buff_size)
5278 * @buff_size: buffer size in bytes
5279 * @cmd_details: pointer to command details structure or NULL
5280 **/
5281enum
5282i40e_status_code i40e_aq_get_ppp_list(struct i40e_hw *hw, void *buff,
5283 u16 buff_size, u8 flags,
5284 struct i40e_asq_cmd_details *cmd_details)
5285{
5286 struct i40e_aq_desc desc;
5287 struct i40e_aqc_get_applied_profiles *cmd =
5288 (struct i40e_aqc_get_applied_profiles *)&desc.params.raw;
5289 i40e_status status;
5290
5291 i40e_fill_default_direct_cmd_desc(&desc,
5292 i40e_aqc_opc_get_personalization_profile_list);
5293
5294 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
5295 if (buff_size > I40E_AQ_LARGE_BUF)
5296 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
5297 desc.datalen = cpu_to_le16(buff_size);
5298
5299 cmd->flags = flags;
5300
5301 status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
5302
5303 return status;
5304}
5305
5306/**
5307 * i40e_find_segment_in_package
5308 * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_I40E)
5309 * @pkg_hdr: pointer to the package header to be searched
5310 *
5311 * This function searches a package file for a particular segment type. On
5312 * success it returns a pointer to the segment header, otherwise it will
5313 * return NULL.
5314 **/
5315struct i40e_generic_seg_header *
5316i40e_find_segment_in_package(u32 segment_type,
5317 struct i40e_package_header *pkg_hdr)
5318{
5319 struct i40e_generic_seg_header *segment;
5320 u32 i;
5321
5322 /* Search all package segments for the requested segment type */
5323 for (i = 0; i < pkg_hdr->segment_count; i++) {
5324 segment =
5325 (struct i40e_generic_seg_header *)((u8 *)pkg_hdr +
5326 pkg_hdr->segment_offset[i]);
5327
5328 if (segment->type == segment_type)
5329 return segment;
5330 }
5331
5332 return NULL;
5333}
5334
5335/**
5336 * i40e_write_profile
5337 * @hw: pointer to the hardware structure
5338 * @profile: pointer to the profile segment of the package to be downloaded
5339 * @track_id: package tracking id
5340 *
5341 * Handles the download of a complete package.
5342 */
5343enum i40e_status_code
5344i40e_write_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile,
5345 u32 track_id)
5346{
5347 i40e_status status = 0;
5348 struct i40e_section_table *sec_tbl;
5349 struct i40e_profile_section_header *sec = NULL;
5350 u32 dev_cnt;
5351 u32 vendor_dev_id;
5352 u32 *nvm;
5353 u32 section_size = 0;
5354 u32 offset = 0, info = 0;
5355 u32 i;
5356
5357 if (!track_id) {
5358 i40e_debug(hw, I40E_DEBUG_PACKAGE, "Track_id can't be 0.");
5359 return I40E_NOT_SUPPORTED;
5360 }
5361
5362 dev_cnt = profile->device_table_count;
5363
5364 for (i = 0; i < dev_cnt; i++) {
5365 vendor_dev_id = profile->device_table[i].vendor_dev_id;
5366 if ((vendor_dev_id >> 16) == PCI_VENDOR_ID_INTEL)
5367 if (hw->device_id == (vendor_dev_id & 0xFFFF))
5368 break;
5369 }
5370 if (i == dev_cnt) {
5371 i40e_debug(hw, I40E_DEBUG_PACKAGE, "Device doesn't support PPP");
5372 return I40E_ERR_DEVICE_NOT_SUPPORTED;
5373 }
5374
5375 nvm = (u32 *)&profile->device_table[dev_cnt];
5376 sec_tbl = (struct i40e_section_table *)&nvm[nvm[0] + 1];
5377
5378 for (i = 0; i < sec_tbl->section_count; i++) {
5379 sec = (struct i40e_profile_section_header *)((u8 *)profile +
5380 sec_tbl->section_offset[i]);
5381
5382 /* Skip 'AQ', 'note' and 'name' sections */
5383 if (sec->section.type != SECTION_TYPE_MMIO)
5384 continue;
5385
5386 section_size = sec->section.size +
5387 sizeof(struct i40e_profile_section_header);
5388
5389 /* Write profile */
5390 status = i40e_aq_write_ppp(hw, (void *)sec, (u16)section_size,
5391 track_id, &offset, &info, NULL);
5392 if (status) {
5393 i40e_debug(hw, I40E_DEBUG_PACKAGE,
5394 "Failed to write profile: offset %d, info %d",
5395 offset, info);
5396 break;
5397 }
5398 }
5399 return status;
5400}
5401
5402/**
5403 * i40e_add_pinfo_to_list
5404 * @hw: pointer to the hardware structure
5405 * @profile: pointer to the profile segment of the package
5406 * @profile_info_sec: buffer for information section
5407 * @track_id: package tracking id
5408 *
5409 * Register a profile to the list of loaded profiles.
5410 */
5411enum i40e_status_code
5412i40e_add_pinfo_to_list(struct i40e_hw *hw,
5413 struct i40e_profile_segment *profile,
5414 u8 *profile_info_sec, u32 track_id)
5415{
5416 i40e_status status = 0;
5417 struct i40e_profile_section_header *sec = NULL;
5418 struct i40e_profile_info *pinfo;
5419 u32 offset = 0, info = 0;
5420
5421 sec = (struct i40e_profile_section_header *)profile_info_sec;
5422 sec->tbl_size = 1;
5423 sec->data_end = sizeof(struct i40e_profile_section_header) +
5424 sizeof(struct i40e_profile_info);
5425 sec->section.type = SECTION_TYPE_INFO;
5426 sec->section.offset = sizeof(struct i40e_profile_section_header);
5427 sec->section.size = sizeof(struct i40e_profile_info);
5428 pinfo = (struct i40e_profile_info *)(profile_info_sec +
5429 sec->section.offset);
5430 pinfo->track_id = track_id;
5431 pinfo->version = profile->version;
5432 pinfo->op = I40E_PPP_ADD_TRACKID;
5433 memcpy(pinfo->name, profile->name, I40E_PPP_NAME_SIZE);
5434
5435 status = i40e_aq_write_ppp(hw, (void *)sec, sec->data_end,
5436 track_id, &offset, &info, NULL);
5437 return status;
5438}