Commit | Line | Data |
---|---|---|
d358aa9a GR |
1 | /******************************************************************************* |
2 | * | |
3 | * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver | |
b831607d | 4 | * Copyright(c) 2013 - 2014 Intel Corporation. |
d358aa9a GR |
5 | * |
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 | * | |
b831607d JB |
15 | * 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/>. | |
17 | * | |
d358aa9a GR |
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" | |
30 | #include "i40e_virtchnl.h" | |
31 | ||
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 | **/ | |
39 | 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) { | |
ab60085e | 45 | case I40E_DEV_ID_SFP_XL710: |
ab60085e | 46 | case I40E_DEV_ID_QEMU: |
ab60085e SN |
47 | case I40E_DEV_ID_KX_B: |
48 | case I40E_DEV_ID_KX_C: | |
ab60085e SN |
49 | case I40E_DEV_ID_QSFP_A: |
50 | case I40E_DEV_ID_QSFP_B: | |
51 | case I40E_DEV_ID_QSFP_C: | |
1ac1e764 | 52 | case I40E_DEV_ID_10G_BASE_T: |
bc5166b9 | 53 | case I40E_DEV_ID_10G_BASE_T4: |
ae24b409 | 54 | case I40E_DEV_ID_20G_KR2: |
48a3b512 | 55 | case I40E_DEV_ID_20G_KR2_A: |
d358aa9a GR |
56 | hw->mac.type = I40E_MAC_XL710; |
57 | break; | |
87e6c1d7 ASJ |
58 | case I40E_DEV_ID_SFP_X722: |
59 | case I40E_DEV_ID_1G_BASE_T_X722: | |
60 | case I40E_DEV_ID_10G_BASE_T_X722: | |
d6bf58c2 | 61 | case I40E_DEV_ID_SFP_I_X722: |
bccf4744 | 62 | case I40E_DEV_ID_QSFP_I_X722: |
87e6c1d7 ASJ |
63 | hw->mac.type = I40E_MAC_X722; |
64 | break; | |
65 | case I40E_DEV_ID_X722_VF: | |
66 | case I40E_DEV_ID_X722_VF_HV: | |
67 | hw->mac.type = I40E_MAC_X722_VF; | |
68 | break; | |
ab60085e SN |
69 | case I40E_DEV_ID_VF: |
70 | case I40E_DEV_ID_VF_HV: | |
d358aa9a GR |
71 | hw->mac.type = I40E_MAC_VF; |
72 | break; | |
73 | default: | |
74 | hw->mac.type = I40E_MAC_GENERIC; | |
75 | break; | |
76 | } | |
77 | } else { | |
78 | status = I40E_ERR_DEVICE_NOT_SUPPORTED; | |
79 | } | |
80 | ||
81 | hw_dbg(hw, "i40e_set_mac_type found mac: %d, returns: %d\n", | |
82 | hw->mac.type, status); | |
83 | return status; | |
84 | } | |
85 | ||
f1c7e72e SN |
86 | /** |
87 | * i40evf_aq_str - convert AQ err code to a string | |
88 | * @hw: pointer to the HW structure | |
89 | * @aq_err: the AQ error code to convert | |
90 | **/ | |
4e68adfe | 91 | const char *i40evf_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err) |
f1c7e72e SN |
92 | { |
93 | switch (aq_err) { | |
94 | case I40E_AQ_RC_OK: | |
95 | return "OK"; | |
96 | case I40E_AQ_RC_EPERM: | |
97 | return "I40E_AQ_RC_EPERM"; | |
98 | case I40E_AQ_RC_ENOENT: | |
99 | return "I40E_AQ_RC_ENOENT"; | |
100 | case I40E_AQ_RC_ESRCH: | |
101 | return "I40E_AQ_RC_ESRCH"; | |
102 | case I40E_AQ_RC_EINTR: | |
103 | return "I40E_AQ_RC_EINTR"; | |
104 | case I40E_AQ_RC_EIO: | |
105 | return "I40E_AQ_RC_EIO"; | |
106 | case I40E_AQ_RC_ENXIO: | |
107 | return "I40E_AQ_RC_ENXIO"; | |
108 | case I40E_AQ_RC_E2BIG: | |
109 | return "I40E_AQ_RC_E2BIG"; | |
110 | case I40E_AQ_RC_EAGAIN: | |
111 | return "I40E_AQ_RC_EAGAIN"; | |
112 | case I40E_AQ_RC_ENOMEM: | |
113 | return "I40E_AQ_RC_ENOMEM"; | |
114 | case I40E_AQ_RC_EACCES: | |
115 | return "I40E_AQ_RC_EACCES"; | |
116 | case I40E_AQ_RC_EFAULT: | |
117 | return "I40E_AQ_RC_EFAULT"; | |
118 | case I40E_AQ_RC_EBUSY: | |
119 | return "I40E_AQ_RC_EBUSY"; | |
120 | case I40E_AQ_RC_EEXIST: | |
121 | return "I40E_AQ_RC_EEXIST"; | |
122 | case I40E_AQ_RC_EINVAL: | |
123 | return "I40E_AQ_RC_EINVAL"; | |
124 | case I40E_AQ_RC_ENOTTY: | |
125 | return "I40E_AQ_RC_ENOTTY"; | |
126 | case I40E_AQ_RC_ENOSPC: | |
127 | return "I40E_AQ_RC_ENOSPC"; | |
128 | case I40E_AQ_RC_ENOSYS: | |
129 | return "I40E_AQ_RC_ENOSYS"; | |
130 | case I40E_AQ_RC_ERANGE: | |
131 | return "I40E_AQ_RC_ERANGE"; | |
132 | case I40E_AQ_RC_EFLUSHED: | |
133 | return "I40E_AQ_RC_EFLUSHED"; | |
134 | case I40E_AQ_RC_BAD_ADDR: | |
135 | return "I40E_AQ_RC_BAD_ADDR"; | |
136 | case I40E_AQ_RC_EMODE: | |
137 | return "I40E_AQ_RC_EMODE"; | |
138 | case I40E_AQ_RC_EFBIG: | |
139 | return "I40E_AQ_RC_EFBIG"; | |
140 | } | |
141 | ||
142 | snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err); | |
143 | return hw->err_str; | |
144 | } | |
145 | ||
146 | /** | |
147 | * i40evf_stat_str - convert status err code to a string | |
148 | * @hw: pointer to the HW structure | |
149 | * @stat_err: the status error code to convert | |
150 | **/ | |
4e68adfe | 151 | const char *i40evf_stat_str(struct i40e_hw *hw, i40e_status stat_err) |
f1c7e72e SN |
152 | { |
153 | switch (stat_err) { | |
154 | case 0: | |
155 | return "OK"; | |
156 | case I40E_ERR_NVM: | |
157 | return "I40E_ERR_NVM"; | |
158 | case I40E_ERR_NVM_CHECKSUM: | |
159 | return "I40E_ERR_NVM_CHECKSUM"; | |
160 | case I40E_ERR_PHY: | |
161 | return "I40E_ERR_PHY"; | |
162 | case I40E_ERR_CONFIG: | |
163 | return "I40E_ERR_CONFIG"; | |
164 | case I40E_ERR_PARAM: | |
165 | return "I40E_ERR_PARAM"; | |
166 | case I40E_ERR_MAC_TYPE: | |
167 | return "I40E_ERR_MAC_TYPE"; | |
168 | case I40E_ERR_UNKNOWN_PHY: | |
169 | return "I40E_ERR_UNKNOWN_PHY"; | |
170 | case I40E_ERR_LINK_SETUP: | |
171 | return "I40E_ERR_LINK_SETUP"; | |
172 | case I40E_ERR_ADAPTER_STOPPED: | |
173 | return "I40E_ERR_ADAPTER_STOPPED"; | |
174 | case I40E_ERR_INVALID_MAC_ADDR: | |
175 | return "I40E_ERR_INVALID_MAC_ADDR"; | |
176 | case I40E_ERR_DEVICE_NOT_SUPPORTED: | |
177 | return "I40E_ERR_DEVICE_NOT_SUPPORTED"; | |
178 | case I40E_ERR_MASTER_REQUESTS_PENDING: | |
179 | return "I40E_ERR_MASTER_REQUESTS_PENDING"; | |
180 | case I40E_ERR_INVALID_LINK_SETTINGS: | |
181 | return "I40E_ERR_INVALID_LINK_SETTINGS"; | |
182 | case I40E_ERR_AUTONEG_NOT_COMPLETE: | |
183 | return "I40E_ERR_AUTONEG_NOT_COMPLETE"; | |
184 | case I40E_ERR_RESET_FAILED: | |
185 | return "I40E_ERR_RESET_FAILED"; | |
186 | case I40E_ERR_SWFW_SYNC: | |
187 | return "I40E_ERR_SWFW_SYNC"; | |
188 | case I40E_ERR_NO_AVAILABLE_VSI: | |
189 | return "I40E_ERR_NO_AVAILABLE_VSI"; | |
190 | case I40E_ERR_NO_MEMORY: | |
191 | return "I40E_ERR_NO_MEMORY"; | |
192 | case I40E_ERR_BAD_PTR: | |
193 | return "I40E_ERR_BAD_PTR"; | |
194 | case I40E_ERR_RING_FULL: | |
195 | return "I40E_ERR_RING_FULL"; | |
196 | case I40E_ERR_INVALID_PD_ID: | |
197 | return "I40E_ERR_INVALID_PD_ID"; | |
198 | case I40E_ERR_INVALID_QP_ID: | |
199 | return "I40E_ERR_INVALID_QP_ID"; | |
200 | case I40E_ERR_INVALID_CQ_ID: | |
201 | return "I40E_ERR_INVALID_CQ_ID"; | |
202 | case I40E_ERR_INVALID_CEQ_ID: | |
203 | return "I40E_ERR_INVALID_CEQ_ID"; | |
204 | case I40E_ERR_INVALID_AEQ_ID: | |
205 | return "I40E_ERR_INVALID_AEQ_ID"; | |
206 | case I40E_ERR_INVALID_SIZE: | |
207 | return "I40E_ERR_INVALID_SIZE"; | |
208 | case I40E_ERR_INVALID_ARP_INDEX: | |
209 | return "I40E_ERR_INVALID_ARP_INDEX"; | |
210 | case I40E_ERR_INVALID_FPM_FUNC_ID: | |
211 | return "I40E_ERR_INVALID_FPM_FUNC_ID"; | |
212 | case I40E_ERR_QP_INVALID_MSG_SIZE: | |
213 | return "I40E_ERR_QP_INVALID_MSG_SIZE"; | |
214 | case I40E_ERR_QP_TOOMANY_WRS_POSTED: | |
215 | return "I40E_ERR_QP_TOOMANY_WRS_POSTED"; | |
216 | case I40E_ERR_INVALID_FRAG_COUNT: | |
217 | return "I40E_ERR_INVALID_FRAG_COUNT"; | |
218 | case I40E_ERR_QUEUE_EMPTY: | |
219 | return "I40E_ERR_QUEUE_EMPTY"; | |
220 | case I40E_ERR_INVALID_ALIGNMENT: | |
221 | return "I40E_ERR_INVALID_ALIGNMENT"; | |
222 | case I40E_ERR_FLUSHED_QUEUE: | |
223 | return "I40E_ERR_FLUSHED_QUEUE"; | |
224 | case I40E_ERR_INVALID_PUSH_PAGE_INDEX: | |
225 | return "I40E_ERR_INVALID_PUSH_PAGE_INDEX"; | |
226 | case I40E_ERR_INVALID_IMM_DATA_SIZE: | |
227 | return "I40E_ERR_INVALID_IMM_DATA_SIZE"; | |
228 | case I40E_ERR_TIMEOUT: | |
229 | return "I40E_ERR_TIMEOUT"; | |
230 | case I40E_ERR_OPCODE_MISMATCH: | |
231 | return "I40E_ERR_OPCODE_MISMATCH"; | |
232 | case I40E_ERR_CQP_COMPL_ERROR: | |
233 | return "I40E_ERR_CQP_COMPL_ERROR"; | |
234 | case I40E_ERR_INVALID_VF_ID: | |
235 | return "I40E_ERR_INVALID_VF_ID"; | |
236 | case I40E_ERR_INVALID_HMCFN_ID: | |
237 | return "I40E_ERR_INVALID_HMCFN_ID"; | |
238 | case I40E_ERR_BACKING_PAGE_ERROR: | |
239 | return "I40E_ERR_BACKING_PAGE_ERROR"; | |
240 | case I40E_ERR_NO_PBLCHUNKS_AVAILABLE: | |
241 | return "I40E_ERR_NO_PBLCHUNKS_AVAILABLE"; | |
242 | case I40E_ERR_INVALID_PBLE_INDEX: | |
243 | return "I40E_ERR_INVALID_PBLE_INDEX"; | |
244 | case I40E_ERR_INVALID_SD_INDEX: | |
245 | return "I40E_ERR_INVALID_SD_INDEX"; | |
246 | case I40E_ERR_INVALID_PAGE_DESC_INDEX: | |
247 | return "I40E_ERR_INVALID_PAGE_DESC_INDEX"; | |
248 | case I40E_ERR_INVALID_SD_TYPE: | |
249 | return "I40E_ERR_INVALID_SD_TYPE"; | |
250 | case I40E_ERR_MEMCPY_FAILED: | |
251 | return "I40E_ERR_MEMCPY_FAILED"; | |
252 | case I40E_ERR_INVALID_HMC_OBJ_INDEX: | |
253 | return "I40E_ERR_INVALID_HMC_OBJ_INDEX"; | |
254 | case I40E_ERR_INVALID_HMC_OBJ_COUNT: | |
255 | return "I40E_ERR_INVALID_HMC_OBJ_COUNT"; | |
256 | case I40E_ERR_INVALID_SRQ_ARM_LIMIT: | |
257 | return "I40E_ERR_INVALID_SRQ_ARM_LIMIT"; | |
258 | case I40E_ERR_SRQ_ENABLED: | |
259 | return "I40E_ERR_SRQ_ENABLED"; | |
260 | case I40E_ERR_ADMIN_QUEUE_ERROR: | |
261 | return "I40E_ERR_ADMIN_QUEUE_ERROR"; | |
262 | case I40E_ERR_ADMIN_QUEUE_TIMEOUT: | |
263 | return "I40E_ERR_ADMIN_QUEUE_TIMEOUT"; | |
264 | case I40E_ERR_BUF_TOO_SHORT: | |
265 | return "I40E_ERR_BUF_TOO_SHORT"; | |
266 | case I40E_ERR_ADMIN_QUEUE_FULL: | |
267 | return "I40E_ERR_ADMIN_QUEUE_FULL"; | |
268 | case I40E_ERR_ADMIN_QUEUE_NO_WORK: | |
269 | return "I40E_ERR_ADMIN_QUEUE_NO_WORK"; | |
270 | case I40E_ERR_BAD_IWARP_CQE: | |
271 | return "I40E_ERR_BAD_IWARP_CQE"; | |
272 | case I40E_ERR_NVM_BLANK_MODE: | |
273 | return "I40E_ERR_NVM_BLANK_MODE"; | |
274 | case I40E_ERR_NOT_IMPLEMENTED: | |
275 | return "I40E_ERR_NOT_IMPLEMENTED"; | |
276 | case I40E_ERR_PE_DOORBELL_NOT_ENABLED: | |
277 | return "I40E_ERR_PE_DOORBELL_NOT_ENABLED"; | |
278 | case I40E_ERR_DIAG_TEST_FAILED: | |
279 | return "I40E_ERR_DIAG_TEST_FAILED"; | |
280 | case I40E_ERR_NOT_READY: | |
281 | return "I40E_ERR_NOT_READY"; | |
282 | case I40E_NOT_SUPPORTED: | |
283 | return "I40E_NOT_SUPPORTED"; | |
284 | case I40E_ERR_FIRMWARE_API_VERSION: | |
285 | return "I40E_ERR_FIRMWARE_API_VERSION"; | |
286 | } | |
287 | ||
288 | snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err); | |
289 | return hw->err_str; | |
290 | } | |
291 | ||
d358aa9a GR |
292 | /** |
293 | * i40evf_debug_aq | |
294 | * @hw: debug mask related to admin queue | |
295 | * @mask: debug mask | |
296 | * @desc: pointer to admin queue descriptor | |
297 | * @buffer: pointer to command buffer | |
f905dd62 | 298 | * @buf_len: max length of buffer |
d358aa9a GR |
299 | * |
300 | * Dumps debug log about adminq command with descriptor contents. | |
301 | **/ | |
302 | void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc, | |
f905dd62 | 303 | void *buffer, u16 buf_len) |
d358aa9a GR |
304 | { |
305 | struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc; | |
f905dd62 | 306 | u16 len = le16_to_cpu(aq_desc->datalen); |
37a2973a SN |
307 | u8 *buf = (u8 *)buffer; |
308 | u16 i = 0; | |
d358aa9a GR |
309 | |
310 | if ((!(mask & hw->debug_mask)) || (desc == NULL)) | |
311 | return; | |
312 | ||
313 | i40e_debug(hw, mask, | |
314 | "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n", | |
f1abd7db PSJ |
315 | le16_to_cpu(aq_desc->opcode), |
316 | le16_to_cpu(aq_desc->flags), | |
317 | le16_to_cpu(aq_desc->datalen), | |
318 | le16_to_cpu(aq_desc->retval)); | |
d358aa9a | 319 | i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n", |
f1abd7db PSJ |
320 | le32_to_cpu(aq_desc->cookie_high), |
321 | le32_to_cpu(aq_desc->cookie_low)); | |
d358aa9a | 322 | i40e_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n", |
f1abd7db PSJ |
323 | le32_to_cpu(aq_desc->params.internal.param0), |
324 | le32_to_cpu(aq_desc->params.internal.param1)); | |
d358aa9a | 325 | i40e_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n", |
f1abd7db PSJ |
326 | le32_to_cpu(aq_desc->params.external.addr_high), |
327 | le32_to_cpu(aq_desc->params.external.addr_low)); | |
d358aa9a GR |
328 | |
329 | if ((buffer != NULL) && (aq_desc->datalen != 0)) { | |
d358aa9a | 330 | i40e_debug(hw, mask, "AQ CMD Buffer:\n"); |
f905dd62 SN |
331 | if (buf_len < len) |
332 | len = buf_len; | |
37a2973a SN |
333 | /* write the full 16-byte chunks */ |
334 | for (i = 0; i < (len - 16); i += 16) | |
a3524e95 | 335 | i40e_debug(hw, mask, "\t0x%04X %16ph\n", i, buf + i); |
37a2973a | 336 | /* write whatever's left over without overrunning the buffer */ |
a3524e95 AS |
337 | if (i < len) |
338 | i40e_debug(hw, mask, "\t0x%04X %*ph\n", | |
339 | i, len - i, buf + i); | |
d358aa9a GR |
340 | } |
341 | } | |
342 | ||
343 | /** | |
344 | * i40evf_check_asq_alive | |
345 | * @hw: pointer to the hw struct | |
346 | * | |
347 | * Returns true if Queue is enabled else false. | |
348 | **/ | |
349 | bool i40evf_check_asq_alive(struct i40e_hw *hw) | |
350 | { | |
8b833b4f KS |
351 | if (hw->aq.asq.len) |
352 | return !!(rd32(hw, hw->aq.asq.len) & | |
e02a7f83 | 353 | I40E_VF_ATQLEN1_ATQENABLE_MASK); |
8b833b4f KS |
354 | else |
355 | return false; | |
d358aa9a GR |
356 | } |
357 | ||
358 | /** | |
359 | * i40evf_aq_queue_shutdown | |
360 | * @hw: pointer to the hw struct | |
361 | * @unloading: is the driver unloading itself | |
362 | * | |
363 | * Tell the Firmware that we're shutting down the AdminQ and whether | |
364 | * or not the driver is unloading as well. | |
365 | **/ | |
366 | i40e_status i40evf_aq_queue_shutdown(struct i40e_hw *hw, | |
367 | bool unloading) | |
368 | { | |
369 | struct i40e_aq_desc desc; | |
370 | struct i40e_aqc_queue_shutdown *cmd = | |
371 | (struct i40e_aqc_queue_shutdown *)&desc.params.raw; | |
372 | i40e_status status; | |
373 | ||
374 | i40evf_fill_default_direct_cmd_desc(&desc, | |
375 | i40e_aqc_opc_queue_shutdown); | |
376 | ||
377 | if (unloading) | |
378 | cmd->driver_unloading = cpu_to_le32(I40E_AQ_DRIVER_UNLOADING); | |
379 | status = i40evf_asq_send_command(hw, &desc, NULL, 0, NULL); | |
380 | ||
381 | return status; | |
382 | } | |
383 | ||
e50c8d6d ASJ |
384 | /** |
385 | * i40e_aq_get_set_rss_lut | |
386 | * @hw: pointer to the hardware structure | |
387 | * @vsi_id: vsi fw index | |
388 | * @pf_lut: for PF table set true, for VSI table set false | |
389 | * @lut: pointer to the lut buffer provided by the caller | |
390 | * @lut_size: size of the lut buffer | |
391 | * @set: set true to set the table, false to get the table | |
392 | * | |
393 | * Internal function to get or set RSS look up table | |
394 | **/ | |
395 | static i40e_status i40e_aq_get_set_rss_lut(struct i40e_hw *hw, | |
396 | u16 vsi_id, bool pf_lut, | |
397 | u8 *lut, u16 lut_size, | |
398 | bool set) | |
399 | { | |
400 | i40e_status status; | |
401 | struct i40e_aq_desc desc; | |
402 | struct i40e_aqc_get_set_rss_lut *cmd_resp = | |
403 | (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw; | |
404 | ||
405 | if (set) | |
406 | i40evf_fill_default_direct_cmd_desc(&desc, | |
407 | i40e_aqc_opc_set_rss_lut); | |
408 | else | |
409 | i40evf_fill_default_direct_cmd_desc(&desc, | |
410 | i40e_aqc_opc_get_rss_lut); | |
411 | ||
412 | /* Indirect command */ | |
413 | desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF); | |
414 | desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD); | |
415 | ||
416 | cmd_resp->vsi_id = | |
417 | cpu_to_le16((u16)((vsi_id << | |
418 | I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) & | |
419 | I40E_AQC_SET_RSS_LUT_VSI_ID_MASK)); | |
420 | cmd_resp->vsi_id |= cpu_to_le16((u16)I40E_AQC_SET_RSS_LUT_VSI_VALID); | |
421 | ||
422 | if (pf_lut) | |
423 | cmd_resp->flags |= cpu_to_le16((u16) | |
424 | ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF << | |
425 | I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) & | |
426 | I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK)); | |
427 | else | |
428 | cmd_resp->flags |= cpu_to_le16((u16) | |
429 | ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI << | |
430 | I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) & | |
431 | I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK)); | |
432 | ||
e50c8d6d ASJ |
433 | status = i40evf_asq_send_command(hw, &desc, lut, lut_size, NULL); |
434 | ||
435 | return status; | |
436 | } | |
437 | ||
438 | /** | |
439 | * i40evf_aq_get_rss_lut | |
440 | * @hw: pointer to the hardware structure | |
441 | * @vsi_id: vsi fw index | |
442 | * @pf_lut: for PF table set true, for VSI table set false | |
443 | * @lut: pointer to the lut buffer provided by the caller | |
444 | * @lut_size: size of the lut buffer | |
445 | * | |
446 | * get the RSS lookup table, PF or VSI type | |
447 | **/ | |
448 | i40e_status i40evf_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id, | |
449 | bool pf_lut, u8 *lut, u16 lut_size) | |
450 | { | |
451 | return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, | |
452 | false); | |
453 | } | |
454 | ||
455 | /** | |
456 | * i40evf_aq_set_rss_lut | |
457 | * @hw: pointer to the hardware structure | |
458 | * @vsi_id: vsi fw index | |
459 | * @pf_lut: for PF table set true, for VSI table set false | |
460 | * @lut: pointer to the lut buffer provided by the caller | |
461 | * @lut_size: size of the lut buffer | |
462 | * | |
463 | * set the RSS lookup table, PF or VSI type | |
464 | **/ | |
465 | i40e_status i40evf_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id, | |
466 | bool pf_lut, u8 *lut, u16 lut_size) | |
467 | { | |
468 | return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true); | |
469 | } | |
470 | ||
471 | /** | |
472 | * i40e_aq_get_set_rss_key | |
473 | * @hw: pointer to the hw struct | |
474 | * @vsi_id: vsi fw index | |
475 | * @key: pointer to key info struct | |
476 | * @set: set true to set the key, false to get the key | |
477 | * | |
478 | * get the RSS key per VSI | |
479 | **/ | |
480 | static i40e_status i40e_aq_get_set_rss_key(struct i40e_hw *hw, | |
481 | u16 vsi_id, | |
482 | struct i40e_aqc_get_set_rss_key_data *key, | |
483 | bool set) | |
484 | { | |
485 | i40e_status status; | |
486 | struct i40e_aq_desc desc; | |
487 | struct i40e_aqc_get_set_rss_key *cmd_resp = | |
488 | (struct i40e_aqc_get_set_rss_key *)&desc.params.raw; | |
489 | u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data); | |
490 | ||
491 | if (set) | |
492 | i40evf_fill_default_direct_cmd_desc(&desc, | |
493 | i40e_aqc_opc_set_rss_key); | |
494 | else | |
495 | i40evf_fill_default_direct_cmd_desc(&desc, | |
496 | i40e_aqc_opc_get_rss_key); | |
497 | ||
498 | /* Indirect command */ | |
499 | desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF); | |
500 | desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_RD); | |
501 | ||
502 | cmd_resp->vsi_id = | |
503 | cpu_to_le16((u16)((vsi_id << | |
504 | I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) & | |
505 | I40E_AQC_SET_RSS_KEY_VSI_ID_MASK)); | |
506 | cmd_resp->vsi_id |= cpu_to_le16((u16)I40E_AQC_SET_RSS_KEY_VSI_VALID); | |
e50c8d6d ASJ |
507 | |
508 | status = i40evf_asq_send_command(hw, &desc, key, key_size, NULL); | |
509 | ||
510 | return status; | |
511 | } | |
512 | ||
513 | /** | |
514 | * i40evf_aq_get_rss_key | |
515 | * @hw: pointer to the hw struct | |
516 | * @vsi_id: vsi fw index | |
517 | * @key: pointer to key info struct | |
518 | * | |
519 | **/ | |
520 | i40e_status i40evf_aq_get_rss_key(struct i40e_hw *hw, | |
521 | u16 vsi_id, | |
522 | struct i40e_aqc_get_set_rss_key_data *key) | |
523 | { | |
524 | return i40e_aq_get_set_rss_key(hw, vsi_id, key, false); | |
525 | } | |
526 | ||
527 | /** | |
528 | * i40evf_aq_set_rss_key | |
529 | * @hw: pointer to the hw struct | |
530 | * @vsi_id: vsi fw index | |
531 | * @key: pointer to key info struct | |
532 | * | |
533 | * set the RSS key per VSI | |
534 | **/ | |
535 | i40e_status i40evf_aq_set_rss_key(struct i40e_hw *hw, | |
536 | u16 vsi_id, | |
537 | struct i40e_aqc_get_set_rss_key_data *key) | |
538 | { | |
539 | return i40e_aq_get_set_rss_key(hw, vsi_id, key, true); | |
540 | } | |
541 | ||
d358aa9a | 542 | |
37a622c1 | 543 | /* The i40evf_ptype_lookup table is used to convert from the 8-bit ptype in the |
206812b5 JB |
544 | * hardware to a bit-field that can be used by SW to more easily determine the |
545 | * packet type. | |
546 | * | |
547 | * Macros are used to shorten the table lines and make this table human | |
548 | * readable. | |
549 | * | |
550 | * We store the PTYPE in the top byte of the bit field - this is just so that | |
551 | * we can check that the table doesn't have a row missing, as the index into | |
552 | * the table should be the PTYPE. | |
553 | * | |
554 | * Typical work flow: | |
555 | * | |
37a622c1 | 556 | * IF NOT i40evf_ptype_lookup[ptype].known |
206812b5 JB |
557 | * THEN |
558 | * Packet is unknown | |
37a622c1 | 559 | * ELSE IF i40evf_ptype_lookup[ptype].outer_ip == I40E_RX_PTYPE_OUTER_IP |
206812b5 JB |
560 | * Use the rest of the fields to look at the tunnels, inner protocols, etc |
561 | * ELSE | |
562 | * Use the enum i40e_rx_l2_ptype to decode the packet type | |
563 | * ENDIF | |
564 | */ | |
565 | ||
566 | /* macro to make the table lines short */ | |
567 | #define I40E_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\ | |
568 | { PTYPE, \ | |
569 | 1, \ | |
570 | I40E_RX_PTYPE_OUTER_##OUTER_IP, \ | |
571 | I40E_RX_PTYPE_OUTER_##OUTER_IP_VER, \ | |
572 | I40E_RX_PTYPE_##OUTER_FRAG, \ | |
573 | I40E_RX_PTYPE_TUNNEL_##T, \ | |
574 | I40E_RX_PTYPE_TUNNEL_END_##TE, \ | |
575 | I40E_RX_PTYPE_##TEF, \ | |
576 | I40E_RX_PTYPE_INNER_PROT_##I, \ | |
577 | I40E_RX_PTYPE_PAYLOAD_LAYER_##PL } | |
578 | ||
579 | #define I40E_PTT_UNUSED_ENTRY(PTYPE) \ | |
580 | { PTYPE, 0, 0, 0, 0, 0, 0, 0, 0, 0 } | |
581 | ||
582 | /* shorter macros makes the table fit but are terse */ | |
583 | #define I40E_RX_PTYPE_NOF I40E_RX_PTYPE_NOT_FRAG | |
584 | #define I40E_RX_PTYPE_FRG I40E_RX_PTYPE_FRAG | |
585 | #define I40E_RX_PTYPE_INNER_PROT_TS I40E_RX_PTYPE_INNER_PROT_TIMESYNC | |
586 | ||
587 | /* Lookup table mapping the HW PTYPE to the bit field for decoding */ | |
37a622c1 | 588 | struct i40e_rx_ptype_decoded i40evf_ptype_lookup[] = { |
206812b5 JB |
589 | /* L2 Packet types */ |
590 | I40E_PTT_UNUSED_ENTRY(0), | |
591 | I40E_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), | |
592 | I40E_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, TS, PAY2), | |
593 | I40E_PTT(3, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), | |
594 | I40E_PTT_UNUSED_ENTRY(4), | |
595 | I40E_PTT_UNUSED_ENTRY(5), | |
596 | I40E_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), | |
597 | I40E_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), | |
598 | I40E_PTT_UNUSED_ENTRY(8), | |
599 | I40E_PTT_UNUSED_ENTRY(9), | |
600 | I40E_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), | |
601 | I40E_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), | |
602 | I40E_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
603 | I40E_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
604 | I40E_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
605 | I40E_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
606 | I40E_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
607 | I40E_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
608 | I40E_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
609 | I40E_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
610 | I40E_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
611 | I40E_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3), | |
612 | ||
613 | /* Non Tunneled IPv4 */ | |
614 | I40E_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3), | |
615 | I40E_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3), | |
616 | I40E_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4), | |
617 | I40E_PTT_UNUSED_ENTRY(25), | |
618 | I40E_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4), | |
619 | I40E_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4), | |
620 | I40E_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4), | |
621 | ||
622 | /* IPv4 --> IPv4 */ | |
623 | I40E_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3), | |
624 | I40E_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3), | |
625 | I40E_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4), | |
626 | I40E_PTT_UNUSED_ENTRY(32), | |
627 | I40E_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4), | |
628 | I40E_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4), | |
629 | I40E_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4), | |
630 | ||
631 | /* IPv4 --> IPv6 */ | |
632 | I40E_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3), | |
633 | I40E_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3), | |
634 | I40E_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4), | |
635 | I40E_PTT_UNUSED_ENTRY(39), | |
636 | I40E_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4), | |
637 | I40E_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4), | |
638 | I40E_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4), | |
639 | ||
640 | /* IPv4 --> GRE/NAT */ | |
641 | I40E_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3), | |
642 | ||
643 | /* IPv4 --> GRE/NAT --> IPv4 */ | |
644 | I40E_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3), | |
645 | I40E_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3), | |
646 | I40E_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4), | |
647 | I40E_PTT_UNUSED_ENTRY(47), | |
648 | I40E_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4), | |
649 | I40E_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4), | |
650 | I40E_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4), | |
651 | ||
652 | /* IPv4 --> GRE/NAT --> IPv6 */ | |
653 | I40E_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3), | |
654 | I40E_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3), | |
655 | I40E_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4), | |
656 | I40E_PTT_UNUSED_ENTRY(54), | |
657 | I40E_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4), | |
658 | I40E_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4), | |
659 | I40E_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4), | |
660 | ||
661 | /* IPv4 --> GRE/NAT --> MAC */ | |
662 | I40E_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3), | |
663 | ||
664 | /* IPv4 --> GRE/NAT --> MAC --> IPv4 */ | |
665 | I40E_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3), | |
666 | I40E_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3), | |
667 | I40E_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4), | |
668 | I40E_PTT_UNUSED_ENTRY(62), | |
669 | I40E_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4), | |
670 | I40E_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4), | |
671 | I40E_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4), | |
672 | ||
673 | /* IPv4 --> GRE/NAT -> MAC --> IPv6 */ | |
674 | I40E_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3), | |
675 | I40E_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3), | |
676 | I40E_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4), | |
677 | I40E_PTT_UNUSED_ENTRY(69), | |
678 | I40E_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4), | |
679 | I40E_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4), | |
680 | I40E_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4), | |
681 | ||
682 | /* IPv4 --> GRE/NAT --> MAC/VLAN */ | |
683 | I40E_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3), | |
684 | ||
685 | /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */ | |
686 | I40E_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3), | |
687 | I40E_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3), | |
688 | I40E_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4), | |
689 | I40E_PTT_UNUSED_ENTRY(77), | |
690 | I40E_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4), | |
691 | I40E_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4), | |
692 | I40E_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4), | |
693 | ||
694 | /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */ | |
695 | I40E_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3), | |
696 | I40E_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3), | |
697 | I40E_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4), | |
698 | I40E_PTT_UNUSED_ENTRY(84), | |
699 | I40E_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4), | |
700 | I40E_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4), | |
701 | I40E_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4), | |
702 | ||
703 | /* Non Tunneled IPv6 */ | |
704 | I40E_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3), | |
705 | I40E_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), | |
706 | I40E_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY3), | |
707 | I40E_PTT_UNUSED_ENTRY(91), | |
708 | I40E_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4), | |
709 | I40E_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), | |
710 | I40E_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4), | |
711 | ||
712 | /* IPv6 --> IPv4 */ | |
713 | I40E_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3), | |
714 | I40E_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3), | |
715 | I40E_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4), | |
716 | I40E_PTT_UNUSED_ENTRY(98), | |
717 | I40E_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4), | |
718 | I40E_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4), | |
719 | I40E_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4), | |
720 | ||
721 | /* IPv6 --> IPv6 */ | |
722 | I40E_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3), | |
723 | I40E_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3), | |
724 | I40E_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4), | |
725 | I40E_PTT_UNUSED_ENTRY(105), | |
726 | I40E_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4), | |
727 | I40E_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4), | |
728 | I40E_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4), | |
729 | ||
730 | /* IPv6 --> GRE/NAT */ | |
731 | I40E_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3), | |
732 | ||
733 | /* IPv6 --> GRE/NAT -> IPv4 */ | |
734 | I40E_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3), | |
735 | I40E_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3), | |
736 | I40E_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4), | |
737 | I40E_PTT_UNUSED_ENTRY(113), | |
738 | I40E_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4), | |
739 | I40E_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4), | |
740 | I40E_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4), | |
741 | ||
742 | /* IPv6 --> GRE/NAT -> IPv6 */ | |
743 | I40E_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3), | |
744 | I40E_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3), | |
745 | I40E_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4), | |
746 | I40E_PTT_UNUSED_ENTRY(120), | |
747 | I40E_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4), | |
748 | I40E_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4), | |
749 | I40E_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4), | |
750 | ||
751 | /* IPv6 --> GRE/NAT -> MAC */ | |
752 | I40E_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3), | |
753 | ||
754 | /* IPv6 --> GRE/NAT -> MAC -> IPv4 */ | |
755 | I40E_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3), | |
756 | I40E_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3), | |
757 | I40E_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4), | |
758 | I40E_PTT_UNUSED_ENTRY(128), | |
759 | I40E_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4), | |
760 | I40E_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4), | |
761 | I40E_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4), | |
762 | ||
763 | /* IPv6 --> GRE/NAT -> MAC -> IPv6 */ | |
764 | I40E_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3), | |
765 | I40E_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3), | |
766 | I40E_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4), | |
767 | I40E_PTT_UNUSED_ENTRY(135), | |
768 | I40E_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4), | |
769 | I40E_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4), | |
770 | I40E_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4), | |
771 | ||
772 | /* IPv6 --> GRE/NAT -> MAC/VLAN */ | |
773 | I40E_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3), | |
774 | ||
775 | /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */ | |
776 | I40E_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3), | |
777 | I40E_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3), | |
778 | I40E_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4), | |
779 | I40E_PTT_UNUSED_ENTRY(143), | |
780 | I40E_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4), | |
781 | I40E_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4), | |
782 | I40E_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4), | |
783 | ||
784 | /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */ | |
785 | I40E_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3), | |
786 | I40E_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3), | |
787 | I40E_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4), | |
788 | I40E_PTT_UNUSED_ENTRY(150), | |
789 | I40E_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4), | |
790 | I40E_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4), | |
791 | I40E_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4), | |
792 | ||
793 | /* unused entries */ | |
794 | I40E_PTT_UNUSED_ENTRY(154), | |
795 | I40E_PTT_UNUSED_ENTRY(155), | |
796 | I40E_PTT_UNUSED_ENTRY(156), | |
797 | I40E_PTT_UNUSED_ENTRY(157), | |
798 | I40E_PTT_UNUSED_ENTRY(158), | |
799 | I40E_PTT_UNUSED_ENTRY(159), | |
800 | ||
801 | I40E_PTT_UNUSED_ENTRY(160), | |
802 | I40E_PTT_UNUSED_ENTRY(161), | |
803 | I40E_PTT_UNUSED_ENTRY(162), | |
804 | I40E_PTT_UNUSED_ENTRY(163), | |
805 | I40E_PTT_UNUSED_ENTRY(164), | |
806 | I40E_PTT_UNUSED_ENTRY(165), | |
807 | I40E_PTT_UNUSED_ENTRY(166), | |
808 | I40E_PTT_UNUSED_ENTRY(167), | |
809 | I40E_PTT_UNUSED_ENTRY(168), | |
810 | I40E_PTT_UNUSED_ENTRY(169), | |
811 | ||
812 | I40E_PTT_UNUSED_ENTRY(170), | |
813 | I40E_PTT_UNUSED_ENTRY(171), | |
814 | I40E_PTT_UNUSED_ENTRY(172), | |
815 | I40E_PTT_UNUSED_ENTRY(173), | |
816 | I40E_PTT_UNUSED_ENTRY(174), | |
817 | I40E_PTT_UNUSED_ENTRY(175), | |
818 | I40E_PTT_UNUSED_ENTRY(176), | |
819 | I40E_PTT_UNUSED_ENTRY(177), | |
820 | I40E_PTT_UNUSED_ENTRY(178), | |
821 | I40E_PTT_UNUSED_ENTRY(179), | |
822 | ||
823 | I40E_PTT_UNUSED_ENTRY(180), | |
824 | I40E_PTT_UNUSED_ENTRY(181), | |
825 | I40E_PTT_UNUSED_ENTRY(182), | |
826 | I40E_PTT_UNUSED_ENTRY(183), | |
827 | I40E_PTT_UNUSED_ENTRY(184), | |
828 | I40E_PTT_UNUSED_ENTRY(185), | |
829 | I40E_PTT_UNUSED_ENTRY(186), | |
830 | I40E_PTT_UNUSED_ENTRY(187), | |
831 | I40E_PTT_UNUSED_ENTRY(188), | |
832 | I40E_PTT_UNUSED_ENTRY(189), | |
833 | ||
834 | I40E_PTT_UNUSED_ENTRY(190), | |
835 | I40E_PTT_UNUSED_ENTRY(191), | |
836 | I40E_PTT_UNUSED_ENTRY(192), | |
837 | I40E_PTT_UNUSED_ENTRY(193), | |
838 | I40E_PTT_UNUSED_ENTRY(194), | |
839 | I40E_PTT_UNUSED_ENTRY(195), | |
840 | I40E_PTT_UNUSED_ENTRY(196), | |
841 | I40E_PTT_UNUSED_ENTRY(197), | |
842 | I40E_PTT_UNUSED_ENTRY(198), | |
843 | I40E_PTT_UNUSED_ENTRY(199), | |
844 | ||
845 | I40E_PTT_UNUSED_ENTRY(200), | |
846 | I40E_PTT_UNUSED_ENTRY(201), | |
847 | I40E_PTT_UNUSED_ENTRY(202), | |
848 | I40E_PTT_UNUSED_ENTRY(203), | |
849 | I40E_PTT_UNUSED_ENTRY(204), | |
850 | I40E_PTT_UNUSED_ENTRY(205), | |
851 | I40E_PTT_UNUSED_ENTRY(206), | |
852 | I40E_PTT_UNUSED_ENTRY(207), | |
853 | I40E_PTT_UNUSED_ENTRY(208), | |
854 | I40E_PTT_UNUSED_ENTRY(209), | |
855 | ||
856 | I40E_PTT_UNUSED_ENTRY(210), | |
857 | I40E_PTT_UNUSED_ENTRY(211), | |
858 | I40E_PTT_UNUSED_ENTRY(212), | |
859 | I40E_PTT_UNUSED_ENTRY(213), | |
860 | I40E_PTT_UNUSED_ENTRY(214), | |
861 | I40E_PTT_UNUSED_ENTRY(215), | |
862 | I40E_PTT_UNUSED_ENTRY(216), | |
863 | I40E_PTT_UNUSED_ENTRY(217), | |
864 | I40E_PTT_UNUSED_ENTRY(218), | |
865 | I40E_PTT_UNUSED_ENTRY(219), | |
866 | ||
867 | I40E_PTT_UNUSED_ENTRY(220), | |
868 | I40E_PTT_UNUSED_ENTRY(221), | |
869 | I40E_PTT_UNUSED_ENTRY(222), | |
870 | I40E_PTT_UNUSED_ENTRY(223), | |
871 | I40E_PTT_UNUSED_ENTRY(224), | |
872 | I40E_PTT_UNUSED_ENTRY(225), | |
873 | I40E_PTT_UNUSED_ENTRY(226), | |
874 | I40E_PTT_UNUSED_ENTRY(227), | |
875 | I40E_PTT_UNUSED_ENTRY(228), | |
876 | I40E_PTT_UNUSED_ENTRY(229), | |
877 | ||
878 | I40E_PTT_UNUSED_ENTRY(230), | |
879 | I40E_PTT_UNUSED_ENTRY(231), | |
880 | I40E_PTT_UNUSED_ENTRY(232), | |
881 | I40E_PTT_UNUSED_ENTRY(233), | |
882 | I40E_PTT_UNUSED_ENTRY(234), | |
883 | I40E_PTT_UNUSED_ENTRY(235), | |
884 | I40E_PTT_UNUSED_ENTRY(236), | |
885 | I40E_PTT_UNUSED_ENTRY(237), | |
886 | I40E_PTT_UNUSED_ENTRY(238), | |
887 | I40E_PTT_UNUSED_ENTRY(239), | |
888 | ||
889 | I40E_PTT_UNUSED_ENTRY(240), | |
890 | I40E_PTT_UNUSED_ENTRY(241), | |
891 | I40E_PTT_UNUSED_ENTRY(242), | |
892 | I40E_PTT_UNUSED_ENTRY(243), | |
893 | I40E_PTT_UNUSED_ENTRY(244), | |
894 | I40E_PTT_UNUSED_ENTRY(245), | |
895 | I40E_PTT_UNUSED_ENTRY(246), | |
896 | I40E_PTT_UNUSED_ENTRY(247), | |
897 | I40E_PTT_UNUSED_ENTRY(248), | |
898 | I40E_PTT_UNUSED_ENTRY(249), | |
899 | ||
900 | I40E_PTT_UNUSED_ENTRY(250), | |
901 | I40E_PTT_UNUSED_ENTRY(251), | |
902 | I40E_PTT_UNUSED_ENTRY(252), | |
903 | I40E_PTT_UNUSED_ENTRY(253), | |
904 | I40E_PTT_UNUSED_ENTRY(254), | |
905 | I40E_PTT_UNUSED_ENTRY(255) | |
906 | }; | |
907 | ||
f658137c SN |
908 | /** |
909 | * i40evf_aq_rx_ctl_read_register - use FW to read from an Rx control register | |
910 | * @hw: pointer to the hw struct | |
911 | * @reg_addr: register address | |
912 | * @reg_val: ptr to register value | |
913 | * @cmd_details: pointer to command details structure or NULL | |
914 | * | |
915 | * Use the firmware to read the Rx control register, | |
916 | * especially useful if the Rx unit is under heavy pressure | |
917 | **/ | |
918 | i40e_status i40evf_aq_rx_ctl_read_register(struct i40e_hw *hw, | |
919 | u32 reg_addr, u32 *reg_val, | |
920 | struct i40e_asq_cmd_details *cmd_details) | |
921 | { | |
922 | struct i40e_aq_desc desc; | |
923 | struct i40e_aqc_rx_ctl_reg_read_write *cmd_resp = | |
924 | (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw; | |
925 | i40e_status status; | |
926 | ||
927 | if (!reg_val) | |
928 | return I40E_ERR_PARAM; | |
929 | ||
930 | i40evf_fill_default_direct_cmd_desc(&desc, | |
931 | i40e_aqc_opc_rx_ctl_reg_read); | |
932 | ||
933 | cmd_resp->address = cpu_to_le32(reg_addr); | |
934 | ||
935 | status = i40evf_asq_send_command(hw, &desc, NULL, 0, cmd_details); | |
936 | ||
937 | if (status == 0) | |
938 | *reg_val = le32_to_cpu(cmd_resp->value); | |
939 | ||
940 | return status; | |
941 | } | |
942 | ||
943 | /** | |
944 | * i40evf_read_rx_ctl - read from an Rx control register | |
945 | * @hw: pointer to the hw struct | |
946 | * @reg_addr: register address | |
947 | **/ | |
948 | u32 i40evf_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr) | |
949 | { | |
950 | i40e_status status = 0; | |
951 | bool use_register; | |
952 | int retry = 5; | |
953 | u32 val = 0; | |
954 | ||
955 | use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5); | |
956 | if (!use_register) { | |
957 | do_retry: | |
958 | status = i40evf_aq_rx_ctl_read_register(hw, reg_addr, | |
959 | &val, NULL); | |
960 | if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) { | |
961 | usleep_range(1000, 2000); | |
962 | retry--; | |
963 | goto do_retry; | |
964 | } | |
965 | } | |
966 | ||
967 | /* if the AQ access failed, try the old-fashioned way */ | |
968 | if (status || use_register) | |
969 | val = rd32(hw, reg_addr); | |
970 | ||
971 | return val; | |
972 | } | |
973 | ||
974 | /** | |
975 | * i40evf_aq_rx_ctl_write_register | |
976 | * @hw: pointer to the hw struct | |
977 | * @reg_addr: register address | |
978 | * @reg_val: register value | |
979 | * @cmd_details: pointer to command details structure or NULL | |
980 | * | |
981 | * Use the firmware to write to an Rx control register, | |
982 | * especially useful if the Rx unit is under heavy pressure | |
983 | **/ | |
984 | i40e_status i40evf_aq_rx_ctl_write_register(struct i40e_hw *hw, | |
985 | u32 reg_addr, u32 reg_val, | |
986 | struct i40e_asq_cmd_details *cmd_details) | |
987 | { | |
988 | struct i40e_aq_desc desc; | |
989 | struct i40e_aqc_rx_ctl_reg_read_write *cmd = | |
990 | (struct i40e_aqc_rx_ctl_reg_read_write *)&desc.params.raw; | |
991 | i40e_status status; | |
992 | ||
993 | i40evf_fill_default_direct_cmd_desc(&desc, | |
994 | i40e_aqc_opc_rx_ctl_reg_write); | |
995 | ||
996 | cmd->address = cpu_to_le32(reg_addr); | |
997 | cmd->value = cpu_to_le32(reg_val); | |
998 | ||
999 | status = i40evf_asq_send_command(hw, &desc, NULL, 0, cmd_details); | |
1000 | ||
1001 | return status; | |
1002 | } | |
1003 | ||
1004 | /** | |
1005 | * i40evf_write_rx_ctl - write to an Rx control register | |
1006 | * @hw: pointer to the hw struct | |
1007 | * @reg_addr: register address | |
1008 | * @reg_val: register value | |
1009 | **/ | |
1010 | void i40evf_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val) | |
1011 | { | |
1012 | i40e_status status = 0; | |
1013 | bool use_register; | |
1014 | int retry = 5; | |
1015 | ||
1016 | use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5); | |
1017 | if (!use_register) { | |
1018 | do_retry: | |
1019 | status = i40evf_aq_rx_ctl_write_register(hw, reg_addr, | |
1020 | reg_val, NULL); | |
1021 | if (hw->aq.asq_last_status == I40E_AQ_RC_EAGAIN && retry) { | |
1022 | usleep_range(1000, 2000); | |
1023 | retry--; | |
1024 | goto do_retry; | |
1025 | } | |
1026 | } | |
1027 | ||
1028 | /* if the AQ access failed, try the old-fashioned way */ | |
1029 | if (status || use_register) | |
1030 | wr32(hw, reg_addr, reg_val); | |
1031 | } | |
1032 | ||
d358aa9a GR |
1033 | /** |
1034 | * i40e_aq_send_msg_to_pf | |
1035 | * @hw: pointer to the hardware structure | |
1036 | * @v_opcode: opcodes for VF-PF communication | |
1037 | * @v_retval: return error code | |
1038 | * @msg: pointer to the msg buffer | |
1039 | * @msglen: msg length | |
1040 | * @cmd_details: pointer to command details | |
1041 | * | |
1042 | * Send message to PF driver using admin queue. By default, this message | |
1043 | * is sent asynchronously, i.e. i40evf_asq_send_command() does not wait for | |
1044 | * completion before returning. | |
1045 | **/ | |
1046 | i40e_status i40e_aq_send_msg_to_pf(struct i40e_hw *hw, | |
1047 | enum i40e_virtchnl_ops v_opcode, | |
1048 | i40e_status v_retval, | |
1049 | u8 *msg, u16 msglen, | |
1050 | struct i40e_asq_cmd_details *cmd_details) | |
1051 | { | |
1052 | struct i40e_aq_desc desc; | |
4334edf5 | 1053 | struct i40e_asq_cmd_details details; |
d358aa9a GR |
1054 | i40e_status status; |
1055 | ||
1056 | i40evf_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_send_msg_to_pf); | |
1057 | desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_SI); | |
1058 | desc.cookie_high = cpu_to_le32(v_opcode); | |
1059 | desc.cookie_low = cpu_to_le32(v_retval); | |
1060 | if (msglen) { | |
1061 | desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | |
1062 | | I40E_AQ_FLAG_RD)); | |
1063 | if (msglen > I40E_AQ_LARGE_BUF) | |
1064 | desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB); | |
1065 | desc.datalen = cpu_to_le16(msglen); | |
1066 | } | |
1067 | if (!cmd_details) { | |
d358aa9a GR |
1068 | memset(&details, 0, sizeof(details)); |
1069 | details.async = true; | |
1070 | cmd_details = &details; | |
1071 | } | |
b58f2f72 | 1072 | status = i40evf_asq_send_command(hw, &desc, msg, msglen, cmd_details); |
d358aa9a GR |
1073 | return status; |
1074 | } | |
1075 | ||
1076 | /** | |
1077 | * i40e_vf_parse_hw_config | |
1078 | * @hw: pointer to the hardware structure | |
1079 | * @msg: pointer to the virtual channel VF resource structure | |
1080 | * | |
1081 | * Given a VF resource message from the PF, populate the hw struct | |
1082 | * with appropriate information. | |
1083 | **/ | |
1084 | void i40e_vf_parse_hw_config(struct i40e_hw *hw, | |
1085 | struct i40e_virtchnl_vf_resource *msg) | |
1086 | { | |
1087 | struct i40e_virtchnl_vsi_resource *vsi_res; | |
1088 | int i; | |
1089 | ||
1090 | vsi_res = &msg->vsi_res[0]; | |
1091 | ||
1092 | hw->dev_caps.num_vsis = msg->num_vsis; | |
1093 | hw->dev_caps.num_rx_qp = msg->num_queue_pairs; | |
1094 | hw->dev_caps.num_tx_qp = msg->num_queue_pairs; | |
1095 | hw->dev_caps.num_msix_vectors_vf = msg->max_vectors; | |
1096 | hw->dev_caps.dcb = msg->vf_offload_flags & | |
1097 | I40E_VIRTCHNL_VF_OFFLOAD_L2; | |
1098 | hw->dev_caps.fcoe = (msg->vf_offload_flags & | |
1099 | I40E_VIRTCHNL_VF_OFFLOAD_FCOE) ? 1 : 0; | |
1100 | for (i = 0; i < msg->num_vsis; i++) { | |
1101 | if (vsi_res->vsi_type == I40E_VSI_SRIOV) { | |
6995b36c JB |
1102 | ether_addr_copy(hw->mac.perm_addr, |
1103 | vsi_res->default_mac_addr); | |
1104 | ether_addr_copy(hw->mac.addr, | |
1105 | vsi_res->default_mac_addr); | |
d358aa9a GR |
1106 | } |
1107 | vsi_res++; | |
1108 | } | |
1109 | } | |
1110 | ||
1111 | /** | |
1112 | * i40e_vf_reset | |
1113 | * @hw: pointer to the hardware structure | |
1114 | * | |
1115 | * Send a VF_RESET message to the PF. Does not wait for response from PF | |
1116 | * as none will be forthcoming. Immediately after calling this function, | |
1117 | * the admin queue should be shut down and (optionally) reinitialized. | |
1118 | **/ | |
1119 | i40e_status i40e_vf_reset(struct i40e_hw *hw) | |
1120 | { | |
1121 | return i40e_aq_send_msg_to_pf(hw, I40E_VIRTCHNL_OP_RESET_VF, | |
1122 | 0, NULL, 0, NULL); | |
1123 | } |