Commit | Line | Data |
---|---|---|
fe56b9e6 YM |
1 | /* QLogic qed NIC Driver |
2 | * Copyright (c) 2015 QLogic Corporation | |
3 | * | |
4 | * This software is available under the terms of the GNU General Public License | |
5 | * (GPL) Version 2, available from the file COPYING in the main directory of | |
6 | * this source tree. | |
7 | */ | |
8 | ||
9 | #ifndef _QED_MCP_H | |
10 | #define _QED_MCP_H | |
11 | ||
12 | #include <linux/types.h> | |
13 | #include <linux/delay.h> | |
fe56b9e6 | 14 | #include <linux/slab.h> |
5529bad9 | 15 | #include <linux/spinlock.h> |
fe56b9e6 YM |
16 | #include "qed_hsi.h" |
17 | ||
cc875c2e YM |
18 | struct qed_mcp_link_speed_params { |
19 | bool autoneg; | |
20 | u32 advertised_speeds; /* bitmask of DRV_SPEED_CAPABILITY */ | |
21 | u32 forced_speed; /* In Mb/s */ | |
22 | }; | |
23 | ||
24 | struct qed_mcp_link_pause_params { | |
25 | bool autoneg; | |
26 | bool forced_rx; | |
27 | bool forced_tx; | |
28 | }; | |
29 | ||
30 | struct qed_mcp_link_params { | |
31 | struct qed_mcp_link_speed_params speed; | |
32 | struct qed_mcp_link_pause_params pause; | |
33 | u32 loopback_mode; | |
34 | }; | |
35 | ||
36 | struct qed_mcp_link_capabilities { | |
37 | u32 speed_capabilities; | |
38 | }; | |
39 | ||
40 | struct qed_mcp_link_state { | |
41 | bool link_up; | |
42 | ||
a64b02d5 MC |
43 | u32 min_pf_rate; |
44 | ||
4b01e519 MC |
45 | /* Actual link speed in Mb/s */ |
46 | u32 line_speed; | |
47 | ||
48 | /* PF max speed in Mb/s, deduced from line_speed | |
49 | * according to PF max bandwidth configuration. | |
50 | */ | |
51 | u32 speed; | |
cc875c2e YM |
52 | bool full_duplex; |
53 | ||
54 | bool an; | |
55 | bool an_complete; | |
56 | bool parallel_detection; | |
57 | bool pfc_enabled; | |
58 | ||
59 | #define QED_LINK_PARTNER_SPEED_1G_HD BIT(0) | |
60 | #define QED_LINK_PARTNER_SPEED_1G_FD BIT(1) | |
61 | #define QED_LINK_PARTNER_SPEED_10G BIT(2) | |
62 | #define QED_LINK_PARTNER_SPEED_20G BIT(3) | |
054c67d1 SRK |
63 | #define QED_LINK_PARTNER_SPEED_25G BIT(4) |
64 | #define QED_LINK_PARTNER_SPEED_40G BIT(5) | |
65 | #define QED_LINK_PARTNER_SPEED_50G BIT(6) | |
66 | #define QED_LINK_PARTNER_SPEED_100G BIT(7) | |
cc875c2e YM |
67 | u32 partner_adv_speed; |
68 | ||
69 | bool partner_tx_flow_ctrl_en; | |
70 | bool partner_rx_flow_ctrl_en; | |
71 | ||
72 | #define QED_LINK_PARTNER_SYMMETRIC_PAUSE (1) | |
73 | #define QED_LINK_PARTNER_ASYMMETRIC_PAUSE (2) | |
74 | #define QED_LINK_PARTNER_BOTH_PAUSE (3) | |
75 | u8 partner_adv_pause; | |
76 | ||
77 | bool sfp_tx_fault; | |
78 | }; | |
79 | ||
fe56b9e6 YM |
80 | struct qed_mcp_function_info { |
81 | u8 pause_on_host; | |
82 | ||
83 | enum qed_pci_personality protocol; | |
84 | ||
85 | u8 bandwidth_min; | |
86 | u8 bandwidth_max; | |
87 | ||
88 | u8 mac[ETH_ALEN]; | |
89 | ||
90 | u64 wwn_port; | |
91 | u64 wwn_node; | |
92 | ||
93 | #define QED_MCP_VLAN_UNSET (0xffff) | |
94 | u16 ovlan; | |
95 | }; | |
96 | ||
97 | struct qed_mcp_nvm_common { | |
98 | u32 offset; | |
99 | u32 param; | |
100 | u32 resp; | |
101 | u32 cmd; | |
102 | }; | |
103 | ||
104 | struct qed_mcp_drv_version { | |
105 | u32 version; | |
106 | u8 name[MCP_DRV_VER_STR_SIZE - 4]; | |
107 | }; | |
108 | ||
6c754246 SRK |
109 | struct qed_mcp_lan_stats { |
110 | u64 ucast_rx_pkts; | |
111 | u64 ucast_tx_pkts; | |
112 | u32 fcs_err; | |
113 | }; | |
114 | ||
115 | struct qed_mcp_fcoe_stats { | |
116 | u64 rx_pkts; | |
117 | u64 tx_pkts; | |
118 | u32 fcs_err; | |
119 | u32 login_failure; | |
120 | }; | |
121 | ||
122 | struct qed_mcp_iscsi_stats { | |
123 | u64 rx_pdus; | |
124 | u64 tx_pdus; | |
125 | u64 rx_bytes; | |
126 | u64 tx_bytes; | |
127 | }; | |
128 | ||
129 | struct qed_mcp_rdma_stats { | |
130 | u64 rx_pkts; | |
131 | u64 tx_pkts; | |
132 | u64 rx_bytes; | |
133 | u64 tx_byts; | |
134 | }; | |
135 | ||
136 | enum qed_mcp_protocol_type { | |
137 | QED_MCP_LAN_STATS, | |
138 | QED_MCP_FCOE_STATS, | |
139 | QED_MCP_ISCSI_STATS, | |
140 | QED_MCP_RDMA_STATS | |
141 | }; | |
142 | ||
143 | union qed_mcp_protocol_stats { | |
144 | struct qed_mcp_lan_stats lan_stats; | |
145 | struct qed_mcp_fcoe_stats fcoe_stats; | |
146 | struct qed_mcp_iscsi_stats iscsi_stats; | |
147 | struct qed_mcp_rdma_stats rdma_stats; | |
148 | }; | |
149 | ||
cc875c2e YM |
150 | /** |
151 | * @brief - returns the link params of the hw function | |
152 | * | |
153 | * @param p_hwfn | |
154 | * | |
155 | * @returns pointer to link params | |
156 | */ | |
157 | struct qed_mcp_link_params *qed_mcp_get_link_params(struct qed_hwfn *); | |
158 | ||
159 | /** | |
160 | * @brief - return the link state of the hw function | |
161 | * | |
162 | * @param p_hwfn | |
163 | * | |
164 | * @returns pointer to link state | |
165 | */ | |
166 | struct qed_mcp_link_state *qed_mcp_get_link_state(struct qed_hwfn *); | |
167 | ||
168 | /** | |
169 | * @brief - return the link capabilities of the hw function | |
170 | * | |
171 | * @param p_hwfn | |
172 | * | |
173 | * @returns pointer to link capabilities | |
174 | */ | |
175 | struct qed_mcp_link_capabilities | |
176 | *qed_mcp_get_link_capabilities(struct qed_hwfn *p_hwfn); | |
177 | ||
178 | /** | |
179 | * @brief Request the MFW to set the the link according to 'link_input'. | |
180 | * | |
181 | * @param p_hwfn | |
182 | * @param p_ptt | |
183 | * @param b_up - raise link if `true'. Reset link if `false'. | |
184 | * | |
185 | * @return int | |
186 | */ | |
187 | int qed_mcp_set_link(struct qed_hwfn *p_hwfn, | |
188 | struct qed_ptt *p_ptt, | |
189 | bool b_up); | |
190 | ||
fe56b9e6 YM |
191 | /** |
192 | * @brief Get the management firmware version value | |
193 | * | |
1408cc1f YM |
194 | * @param p_hwfn |
195 | * @param p_ptt | |
196 | * @param p_mfw_ver - mfw version value | |
197 | * @param p_running_bundle_id - image id in nvram; Optional. | |
fe56b9e6 | 198 | * |
1408cc1f | 199 | * @return int - 0 - operation was successful. |
fe56b9e6 | 200 | */ |
1408cc1f YM |
201 | int qed_mcp_get_mfw_ver(struct qed_hwfn *p_hwfn, |
202 | struct qed_ptt *p_ptt, | |
203 | u32 *p_mfw_ver, u32 *p_running_bundle_id); | |
fe56b9e6 | 204 | |
cc875c2e YM |
205 | /** |
206 | * @brief Get media type value of the port. | |
207 | * | |
208 | * @param cdev - qed dev pointer | |
209 | * @param mfw_ver - media type value | |
210 | * | |
211 | * @return int - | |
212 | * 0 - Operation was successul. | |
213 | * -EBUSY - Operation failed | |
214 | */ | |
215 | int qed_mcp_get_media_type(struct qed_dev *cdev, | |
216 | u32 *media_type); | |
217 | ||
fe56b9e6 YM |
218 | /** |
219 | * @brief General function for sending commands to the MCP | |
220 | * mailbox. It acquire mutex lock for the entire | |
221 | * operation, from sending the request until the MCP | |
222 | * response. Waiting for MCP response will be checked up | |
223 | * to 5 seconds every 5ms. | |
224 | * | |
225 | * @param p_hwfn - hw function | |
226 | * @param p_ptt - PTT required for register access | |
227 | * @param cmd - command to be sent to the MCP. | |
228 | * @param param - Optional param | |
229 | * @param o_mcp_resp - The MCP response code (exclude sequence). | |
230 | * @param o_mcp_param- Optional parameter provided by the MCP | |
231 | * response | |
232 | * @return int - 0 - operation | |
233 | * was successul. | |
234 | */ | |
235 | int qed_mcp_cmd(struct qed_hwfn *p_hwfn, | |
236 | struct qed_ptt *p_ptt, | |
237 | u32 cmd, | |
238 | u32 param, | |
239 | u32 *o_mcp_resp, | |
240 | u32 *o_mcp_param); | |
241 | ||
242 | /** | |
243 | * @brief - drains the nig, allowing completion to pass in case of pauses. | |
244 | * (Should be called only from sleepable context) | |
245 | * | |
246 | * @param p_hwfn | |
247 | * @param p_ptt | |
248 | */ | |
249 | int qed_mcp_drain(struct qed_hwfn *p_hwfn, | |
250 | struct qed_ptt *p_ptt); | |
251 | ||
cee4d264 MC |
252 | /** |
253 | * @brief Get the flash size value | |
254 | * | |
255 | * @param p_hwfn | |
256 | * @param p_ptt | |
257 | * @param p_flash_size - flash size in bytes to be filled. | |
258 | * | |
259 | * @return int - 0 - operation was successul. | |
260 | */ | |
261 | int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn, | |
262 | struct qed_ptt *p_ptt, | |
263 | u32 *p_flash_size); | |
264 | ||
fe56b9e6 YM |
265 | /** |
266 | * @brief Send driver version to MFW | |
267 | * | |
268 | * @param p_hwfn | |
269 | * @param p_ptt | |
270 | * @param version - Version value | |
271 | * @param name - Protocol driver name | |
272 | * | |
273 | * @return int - 0 - operation was successul. | |
274 | */ | |
275 | int | |
276 | qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn, | |
277 | struct qed_ptt *p_ptt, | |
278 | struct qed_mcp_drv_version *p_ver); | |
279 | ||
91420b83 SK |
280 | /** |
281 | * @brief Set LED status | |
282 | * | |
283 | * @param p_hwfn | |
284 | * @param p_ptt | |
285 | * @param mode - LED mode | |
286 | * | |
287 | * @return int - 0 - operation was successful. | |
288 | */ | |
289 | int qed_mcp_set_led(struct qed_hwfn *p_hwfn, | |
290 | struct qed_ptt *p_ptt, | |
291 | enum qed_led_mode mode); | |
292 | ||
03dc76ca SRK |
293 | /** |
294 | * @brief Bist register test | |
295 | * | |
296 | * @param p_hwfn - hw function | |
297 | * @param p_ptt - PTT required for register access | |
298 | * | |
299 | * @return int - 0 - operation was successful. | |
300 | */ | |
301 | int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, | |
302 | struct qed_ptt *p_ptt); | |
303 | ||
304 | /** | |
305 | * @brief Bist clock test | |
306 | * | |
307 | * @param p_hwfn - hw function | |
308 | * @param p_ptt - PTT required for register access | |
309 | * | |
310 | * @return int - 0 - operation was successful. | |
311 | */ | |
312 | int qed_mcp_bist_clock_test(struct qed_hwfn *p_hwfn, | |
313 | struct qed_ptt *p_ptt); | |
314 | ||
fe56b9e6 YM |
315 | /* Using hwfn number (and not pf_num) is required since in CMT mode, |
316 | * same pf_num may be used by two different hwfn | |
317 | * TODO - this shouldn't really be in .h file, but until all fields | |
318 | * required during hw-init will be placed in their correct place in shmem | |
319 | * we need it in qed_dev.c [for readin the nvram reflection in shmem]. | |
320 | */ | |
321 | #define MCP_PF_ID_BY_REL(p_hwfn, rel_pfid) (QED_IS_BB((p_hwfn)->cdev) ? \ | |
322 | ((rel_pfid) | \ | |
323 | ((p_hwfn)->abs_pf_id & 1) << 3) : \ | |
324 | rel_pfid) | |
325 | #define MCP_PF_ID(p_hwfn) MCP_PF_ID_BY_REL(p_hwfn, (p_hwfn)->rel_pf_id) | |
326 | ||
327 | /* TODO - this is only correct as long as only BB is supported, and | |
328 | * no port-swapping is implemented; Afterwards we'll need to fix it. | |
329 | */ | |
330 | #define MFW_PORT(_p_hwfn) ((_p_hwfn)->abs_pf_id % \ | |
331 | ((_p_hwfn)->cdev->num_ports_in_engines * 2)) | |
332 | struct qed_mcp_info { | |
5529bad9 TT |
333 | spinlock_t lock; |
334 | bool block_mb_sending; | |
fe56b9e6 YM |
335 | u32 public_base; |
336 | u32 drv_mb_addr; | |
337 | u32 mfw_mb_addr; | |
338 | u32 port_addr; | |
339 | u16 drv_mb_seq; | |
340 | u16 drv_pulse_seq; | |
cc875c2e YM |
341 | struct qed_mcp_link_params link_input; |
342 | struct qed_mcp_link_state link_output; | |
343 | struct qed_mcp_link_capabilities link_capabilities; | |
fe56b9e6 | 344 | struct qed_mcp_function_info func_info; |
fe56b9e6 YM |
345 | u8 *mfw_mb_cur; |
346 | u8 *mfw_mb_shadow; | |
347 | u16 mfw_mb_length; | |
348 | u16 mcp_hist; | |
349 | }; | |
350 | ||
5529bad9 TT |
351 | struct qed_mcp_mb_params { |
352 | u32 cmd; | |
353 | u32 param; | |
354 | union drv_union_data *p_data_src; | |
355 | union drv_union_data *p_data_dst; | |
356 | u32 mcp_resp; | |
357 | u32 mcp_param; | |
358 | }; | |
359 | ||
fe56b9e6 YM |
360 | /** |
361 | * @brief Initialize the interface with the MCP | |
362 | * | |
363 | * @param p_hwfn - HW func | |
364 | * @param p_ptt - PTT required for register access | |
365 | * | |
366 | * @return int | |
367 | */ | |
368 | int qed_mcp_cmd_init(struct qed_hwfn *p_hwfn, | |
369 | struct qed_ptt *p_ptt); | |
370 | ||
371 | /** | |
372 | * @brief Initialize the port interface with the MCP | |
373 | * | |
374 | * @param p_hwfn | |
375 | * @param p_ptt | |
376 | * Can only be called after `num_ports_in_engines' is set | |
377 | */ | |
378 | void qed_mcp_cmd_port_init(struct qed_hwfn *p_hwfn, | |
379 | struct qed_ptt *p_ptt); | |
380 | /** | |
381 | * @brief Releases resources allocated during the init process. | |
382 | * | |
383 | * @param p_hwfn - HW func | |
384 | * @param p_ptt - PTT required for register access | |
385 | * | |
386 | * @return int | |
387 | */ | |
388 | ||
389 | int qed_mcp_free(struct qed_hwfn *p_hwfn); | |
390 | ||
cc875c2e YM |
391 | /** |
392 | * @brief This function is called from the DPC context. After | |
393 | * pointing PTT to the mfw mb, check for events sent by the MCP | |
394 | * to the driver and ack them. In case a critical event | |
395 | * detected, it will be handled here, otherwise the work will be | |
396 | * queued to a sleepable work-queue. | |
397 | * | |
398 | * @param p_hwfn - HW function | |
399 | * @param p_ptt - PTT required for register access | |
400 | * @return int - 0 - operation | |
401 | * was successul. | |
402 | */ | |
403 | int qed_mcp_handle_events(struct qed_hwfn *p_hwfn, | |
404 | struct qed_ptt *p_ptt); | |
405 | ||
fe56b9e6 YM |
406 | /** |
407 | * @brief Sends a LOAD_REQ to the MFW, and in case operation | |
408 | * succeed, returns whether this PF is the first on the | |
409 | * chip/engine/port or function. This function should be | |
410 | * called when driver is ready to accept MFW events after | |
411 | * Storms initializations are done. | |
412 | * | |
413 | * @param p_hwfn - hw function | |
414 | * @param p_ptt - PTT required for register access | |
415 | * @param p_load_code - The MCP response param containing one | |
416 | * of the following: | |
417 | * FW_MSG_CODE_DRV_LOAD_ENGINE | |
418 | * FW_MSG_CODE_DRV_LOAD_PORT | |
419 | * FW_MSG_CODE_DRV_LOAD_FUNCTION | |
420 | * @return int - | |
421 | * 0 - Operation was successul. | |
422 | * -EBUSY - Operation failed | |
423 | */ | |
424 | int qed_mcp_load_req(struct qed_hwfn *p_hwfn, | |
425 | struct qed_ptt *p_ptt, | |
426 | u32 *p_load_code); | |
427 | ||
428 | /** | |
429 | * @brief Read the MFW mailbox into Current buffer. | |
430 | * | |
431 | * @param p_hwfn | |
432 | * @param p_ptt | |
433 | */ | |
434 | void qed_mcp_read_mb(struct qed_hwfn *p_hwfn, | |
435 | struct qed_ptt *p_ptt); | |
436 | ||
0b55e27d YM |
437 | /** |
438 | * @brief Ack to mfw that driver finished FLR process for VFs | |
439 | * | |
440 | * @param p_hwfn | |
441 | * @param p_ptt | |
442 | * @param vfs_to_ack - bit mask of all engine VFs for which the PF acks. | |
443 | * | |
444 | * @param return int - 0 upon success. | |
445 | */ | |
446 | int qed_mcp_ack_vf_flr(struct qed_hwfn *p_hwfn, | |
447 | struct qed_ptt *p_ptt, u32 *vfs_to_ack); | |
448 | ||
fe56b9e6 YM |
449 | /** |
450 | * @brief - calls during init to read shmem of all function-related info. | |
451 | * | |
452 | * @param p_hwfn | |
453 | * | |
454 | * @param return 0 upon success. | |
455 | */ | |
456 | int qed_mcp_fill_shmem_func_info(struct qed_hwfn *p_hwfn, | |
457 | struct qed_ptt *p_ptt); | |
458 | ||
459 | /** | |
460 | * @brief - Reset the MCP using mailbox command. | |
461 | * | |
462 | * @param p_hwfn | |
463 | * @param p_ptt | |
464 | * | |
465 | * @param return 0 upon success. | |
466 | */ | |
467 | int qed_mcp_reset(struct qed_hwfn *p_hwfn, | |
468 | struct qed_ptt *p_ptt); | |
469 | ||
4102426f TT |
470 | /** |
471 | * @brief - Sends an NVM read command request to the MFW to get | |
472 | * a buffer. | |
473 | * | |
474 | * @param p_hwfn | |
475 | * @param p_ptt | |
476 | * @param cmd - Command: DRV_MSG_CODE_NVM_GET_FILE_DATA or | |
477 | * DRV_MSG_CODE_NVM_READ_NVRAM commands | |
478 | * @param param - [0:23] - Offset [24:31] - Size | |
479 | * @param o_mcp_resp - MCP response | |
480 | * @param o_mcp_param - MCP response param | |
481 | * @param o_txn_size - Buffer size output | |
482 | * @param o_buf - Pointer to the buffer returned by the MFW. | |
483 | * | |
484 | * @param return 0 upon success. | |
485 | */ | |
486 | int qed_mcp_nvm_rd_cmd(struct qed_hwfn *p_hwfn, | |
487 | struct qed_ptt *p_ptt, | |
488 | u32 cmd, | |
489 | u32 param, | |
490 | u32 *o_mcp_resp, | |
491 | u32 *o_mcp_param, u32 *o_txn_size, u32 *o_buf); | |
492 | ||
fe56b9e6 YM |
493 | /** |
494 | * @brief indicates whether the MFW objects [under mcp_info] are accessible | |
495 | * | |
496 | * @param p_hwfn | |
497 | * | |
498 | * @return true iff MFW is running and mcp_info is initialized | |
499 | */ | |
500 | bool qed_mcp_is_init(struct qed_hwfn *p_hwfn); | |
1408cc1f YM |
501 | |
502 | /** | |
503 | * @brief request MFW to configure MSI-X for a VF | |
504 | * | |
505 | * @param p_hwfn | |
506 | * @param p_ptt | |
507 | * @param vf_id - absolute inside engine | |
508 | * @param num_sbs - number of entries to request | |
509 | * | |
510 | * @return int | |
511 | */ | |
512 | int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn, | |
513 | struct qed_ptt *p_ptt, u8 vf_id, u8 num); | |
514 | ||
4102426f TT |
515 | /** |
516 | * @brief - Halt the MCP. | |
517 | * | |
518 | * @param p_hwfn | |
519 | * @param p_ptt | |
520 | * | |
521 | * @param return 0 upon success. | |
522 | */ | |
523 | int qed_mcp_halt(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); | |
524 | ||
525 | /** | |
526 | * @brief - Wake up the MCP. | |
527 | * | |
528 | * @param p_hwfn | |
529 | * @param p_ptt | |
530 | * | |
531 | * @param return 0 upon success. | |
532 | */ | |
533 | int qed_mcp_resume(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); | |
534 | ||
a64b02d5 | 535 | int qed_configure_pf_min_bandwidth(struct qed_dev *cdev, u8 min_bw); |
4b01e519 MC |
536 | int qed_configure_pf_max_bandwidth(struct qed_dev *cdev, u8 max_bw); |
537 | int __qed_configure_pf_max_bandwidth(struct qed_hwfn *p_hwfn, | |
538 | struct qed_ptt *p_ptt, | |
539 | struct qed_mcp_link_state *p_link, | |
540 | u8 max_bw); | |
a64b02d5 MC |
541 | int __qed_configure_pf_min_bandwidth(struct qed_hwfn *p_hwfn, |
542 | struct qed_ptt *p_ptt, | |
543 | struct qed_mcp_link_state *p_link, | |
544 | u8 min_bw); | |
351a4ded | 545 | |
4102426f TT |
546 | int qed_mcp_mask_parities(struct qed_hwfn *p_hwfn, |
547 | struct qed_ptt *p_ptt, u32 mask_parities); | |
548 | ||
fe56b9e6 | 549 | #endif |