Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 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> |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 14 | #include <linux/slab.h> |
Tomer Tayar | 5529bad | 2016-03-09 09:16:24 +0200 | [diff] [blame] | 15 | #include <linux/spinlock.h> |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 16 | #include "qed_hsi.h" |
| 17 | |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 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 | |
Manish Chopra | a64b02d | 2016-04-26 10:56:10 -0400 | [diff] [blame] | 43 | u32 min_pf_rate; |
| 44 | |
Manish Chopra | 4b01e51 | 2016-04-26 10:56:09 -0400 | [diff] [blame] | 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; |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 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) |
| 63 | #define QED_LINK_PARTNER_SPEED_40G BIT(4) |
| 64 | #define QED_LINK_PARTNER_SPEED_50G BIT(5) |
| 65 | #define QED_LINK_PARTNER_SPEED_100G BIT(6) |
| 66 | u32 partner_adv_speed; |
| 67 | |
| 68 | bool partner_tx_flow_ctrl_en; |
| 69 | bool partner_rx_flow_ctrl_en; |
| 70 | |
| 71 | #define QED_LINK_PARTNER_SYMMETRIC_PAUSE (1) |
| 72 | #define QED_LINK_PARTNER_ASYMMETRIC_PAUSE (2) |
| 73 | #define QED_LINK_PARTNER_BOTH_PAUSE (3) |
| 74 | u8 partner_adv_pause; |
| 75 | |
| 76 | bool sfp_tx_fault; |
| 77 | }; |
| 78 | |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 79 | struct qed_mcp_function_info { |
| 80 | u8 pause_on_host; |
| 81 | |
| 82 | enum qed_pci_personality protocol; |
| 83 | |
| 84 | u8 bandwidth_min; |
| 85 | u8 bandwidth_max; |
| 86 | |
| 87 | u8 mac[ETH_ALEN]; |
| 88 | |
| 89 | u64 wwn_port; |
| 90 | u64 wwn_node; |
| 91 | |
| 92 | #define QED_MCP_VLAN_UNSET (0xffff) |
| 93 | u16 ovlan; |
| 94 | }; |
| 95 | |
| 96 | struct qed_mcp_nvm_common { |
| 97 | u32 offset; |
| 98 | u32 param; |
| 99 | u32 resp; |
| 100 | u32 cmd; |
| 101 | }; |
| 102 | |
| 103 | struct qed_mcp_drv_version { |
| 104 | u32 version; |
| 105 | u8 name[MCP_DRV_VER_STR_SIZE - 4]; |
| 106 | }; |
| 107 | |
| 108 | /** |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 109 | * @brief - returns the link params of the hw function |
| 110 | * |
| 111 | * @param p_hwfn |
| 112 | * |
| 113 | * @returns pointer to link params |
| 114 | */ |
| 115 | struct qed_mcp_link_params *qed_mcp_get_link_params(struct qed_hwfn *); |
| 116 | |
| 117 | /** |
| 118 | * @brief - return the link state of the hw function |
| 119 | * |
| 120 | * @param p_hwfn |
| 121 | * |
| 122 | * @returns pointer to link state |
| 123 | */ |
| 124 | struct qed_mcp_link_state *qed_mcp_get_link_state(struct qed_hwfn *); |
| 125 | |
| 126 | /** |
| 127 | * @brief - return the link capabilities of the hw function |
| 128 | * |
| 129 | * @param p_hwfn |
| 130 | * |
| 131 | * @returns pointer to link capabilities |
| 132 | */ |
| 133 | struct qed_mcp_link_capabilities |
| 134 | *qed_mcp_get_link_capabilities(struct qed_hwfn *p_hwfn); |
| 135 | |
| 136 | /** |
| 137 | * @brief Request the MFW to set the the link according to 'link_input'. |
| 138 | * |
| 139 | * @param p_hwfn |
| 140 | * @param p_ptt |
| 141 | * @param b_up - raise link if `true'. Reset link if `false'. |
| 142 | * |
| 143 | * @return int |
| 144 | */ |
| 145 | int qed_mcp_set_link(struct qed_hwfn *p_hwfn, |
| 146 | struct qed_ptt *p_ptt, |
| 147 | bool b_up); |
| 148 | |
| 149 | /** |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 150 | * @brief Get the management firmware version value |
| 151 | * |
Yuval Mintz | 1408cc1f | 2016-05-11 16:36:14 +0300 | [diff] [blame^] | 152 | * @param p_hwfn |
| 153 | * @param p_ptt |
| 154 | * @param p_mfw_ver - mfw version value |
| 155 | * @param p_running_bundle_id - image id in nvram; Optional. |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 156 | * |
Yuval Mintz | 1408cc1f | 2016-05-11 16:36:14 +0300 | [diff] [blame^] | 157 | * @return int - 0 - operation was successful. |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 158 | */ |
Yuval Mintz | 1408cc1f | 2016-05-11 16:36:14 +0300 | [diff] [blame^] | 159 | int qed_mcp_get_mfw_ver(struct qed_hwfn *p_hwfn, |
| 160 | struct qed_ptt *p_ptt, |
| 161 | u32 *p_mfw_ver, u32 *p_running_bundle_id); |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 162 | |
| 163 | /** |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 164 | * @brief Get media type value of the port. |
| 165 | * |
| 166 | * @param cdev - qed dev pointer |
| 167 | * @param mfw_ver - media type value |
| 168 | * |
| 169 | * @return int - |
| 170 | * 0 - Operation was successul. |
| 171 | * -EBUSY - Operation failed |
| 172 | */ |
| 173 | int qed_mcp_get_media_type(struct qed_dev *cdev, |
| 174 | u32 *media_type); |
| 175 | |
| 176 | /** |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 177 | * @brief General function for sending commands to the MCP |
| 178 | * mailbox. It acquire mutex lock for the entire |
| 179 | * operation, from sending the request until the MCP |
| 180 | * response. Waiting for MCP response will be checked up |
| 181 | * to 5 seconds every 5ms. |
| 182 | * |
| 183 | * @param p_hwfn - hw function |
| 184 | * @param p_ptt - PTT required for register access |
| 185 | * @param cmd - command to be sent to the MCP. |
| 186 | * @param param - Optional param |
| 187 | * @param o_mcp_resp - The MCP response code (exclude sequence). |
| 188 | * @param o_mcp_param- Optional parameter provided by the MCP |
| 189 | * response |
| 190 | * @return int - 0 - operation |
| 191 | * was successul. |
| 192 | */ |
| 193 | int qed_mcp_cmd(struct qed_hwfn *p_hwfn, |
| 194 | struct qed_ptt *p_ptt, |
| 195 | u32 cmd, |
| 196 | u32 param, |
| 197 | u32 *o_mcp_resp, |
| 198 | u32 *o_mcp_param); |
| 199 | |
| 200 | /** |
| 201 | * @brief - drains the nig, allowing completion to pass in case of pauses. |
| 202 | * (Should be called only from sleepable context) |
| 203 | * |
| 204 | * @param p_hwfn |
| 205 | * @param p_ptt |
| 206 | */ |
| 207 | int qed_mcp_drain(struct qed_hwfn *p_hwfn, |
| 208 | struct qed_ptt *p_ptt); |
| 209 | |
| 210 | /** |
Manish Chopra | cee4d26 | 2015-10-26 11:02:28 +0200 | [diff] [blame] | 211 | * @brief Get the flash size value |
| 212 | * |
| 213 | * @param p_hwfn |
| 214 | * @param p_ptt |
| 215 | * @param p_flash_size - flash size in bytes to be filled. |
| 216 | * |
| 217 | * @return int - 0 - operation was successul. |
| 218 | */ |
| 219 | int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn, |
| 220 | struct qed_ptt *p_ptt, |
| 221 | u32 *p_flash_size); |
| 222 | |
| 223 | /** |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 224 | * @brief Send driver version to MFW |
| 225 | * |
| 226 | * @param p_hwfn |
| 227 | * @param p_ptt |
| 228 | * @param version - Version value |
| 229 | * @param name - Protocol driver name |
| 230 | * |
| 231 | * @return int - 0 - operation was successul. |
| 232 | */ |
| 233 | int |
| 234 | qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn, |
| 235 | struct qed_ptt *p_ptt, |
| 236 | struct qed_mcp_drv_version *p_ver); |
| 237 | |
Sudarsana Kalluru | 91420b8 | 2015-11-30 12:25:03 +0200 | [diff] [blame] | 238 | /** |
| 239 | * @brief Set LED status |
| 240 | * |
| 241 | * @param p_hwfn |
| 242 | * @param p_ptt |
| 243 | * @param mode - LED mode |
| 244 | * |
| 245 | * @return int - 0 - operation was successful. |
| 246 | */ |
| 247 | int qed_mcp_set_led(struct qed_hwfn *p_hwfn, |
| 248 | struct qed_ptt *p_ptt, |
| 249 | enum qed_led_mode mode); |
| 250 | |
Sudarsana Reddy Kalluru | 03dc76c | 2016-04-28 20:20:52 -0400 | [diff] [blame] | 251 | /** |
| 252 | * @brief Bist register test |
| 253 | * |
| 254 | * @param p_hwfn - hw function |
| 255 | * @param p_ptt - PTT required for register access |
| 256 | * |
| 257 | * @return int - 0 - operation was successful. |
| 258 | */ |
| 259 | int qed_mcp_bist_register_test(struct qed_hwfn *p_hwfn, |
| 260 | struct qed_ptt *p_ptt); |
| 261 | |
| 262 | /** |
| 263 | * @brief Bist clock test |
| 264 | * |
| 265 | * @param p_hwfn - hw function |
| 266 | * @param p_ptt - PTT required for register access |
| 267 | * |
| 268 | * @return int - 0 - operation was successful. |
| 269 | */ |
| 270 | int qed_mcp_bist_clock_test(struct qed_hwfn *p_hwfn, |
| 271 | struct qed_ptt *p_ptt); |
| 272 | |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 273 | /* Using hwfn number (and not pf_num) is required since in CMT mode, |
| 274 | * same pf_num may be used by two different hwfn |
| 275 | * TODO - this shouldn't really be in .h file, but until all fields |
| 276 | * required during hw-init will be placed in their correct place in shmem |
| 277 | * we need it in qed_dev.c [for readin the nvram reflection in shmem]. |
| 278 | */ |
| 279 | #define MCP_PF_ID_BY_REL(p_hwfn, rel_pfid) (QED_IS_BB((p_hwfn)->cdev) ? \ |
| 280 | ((rel_pfid) | \ |
| 281 | ((p_hwfn)->abs_pf_id & 1) << 3) : \ |
| 282 | rel_pfid) |
| 283 | #define MCP_PF_ID(p_hwfn) MCP_PF_ID_BY_REL(p_hwfn, (p_hwfn)->rel_pf_id) |
| 284 | |
| 285 | /* TODO - this is only correct as long as only BB is supported, and |
| 286 | * no port-swapping is implemented; Afterwards we'll need to fix it. |
| 287 | */ |
| 288 | #define MFW_PORT(_p_hwfn) ((_p_hwfn)->abs_pf_id % \ |
| 289 | ((_p_hwfn)->cdev->num_ports_in_engines * 2)) |
| 290 | struct qed_mcp_info { |
Tomer Tayar | 5529bad | 2016-03-09 09:16:24 +0200 | [diff] [blame] | 291 | spinlock_t lock; |
| 292 | bool block_mb_sending; |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 293 | u32 public_base; |
| 294 | u32 drv_mb_addr; |
| 295 | u32 mfw_mb_addr; |
| 296 | u32 port_addr; |
| 297 | u16 drv_mb_seq; |
| 298 | u16 drv_pulse_seq; |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 299 | struct qed_mcp_link_params link_input; |
| 300 | struct qed_mcp_link_state link_output; |
| 301 | struct qed_mcp_link_capabilities link_capabilities; |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 302 | struct qed_mcp_function_info func_info; |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 303 | u8 *mfw_mb_cur; |
| 304 | u8 *mfw_mb_shadow; |
| 305 | u16 mfw_mb_length; |
| 306 | u16 mcp_hist; |
| 307 | }; |
| 308 | |
Tomer Tayar | 5529bad | 2016-03-09 09:16:24 +0200 | [diff] [blame] | 309 | struct qed_mcp_mb_params { |
| 310 | u32 cmd; |
| 311 | u32 param; |
| 312 | union drv_union_data *p_data_src; |
| 313 | union drv_union_data *p_data_dst; |
| 314 | u32 mcp_resp; |
| 315 | u32 mcp_param; |
| 316 | }; |
| 317 | |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 318 | /** |
| 319 | * @brief Initialize the interface with the MCP |
| 320 | * |
| 321 | * @param p_hwfn - HW func |
| 322 | * @param p_ptt - PTT required for register access |
| 323 | * |
| 324 | * @return int |
| 325 | */ |
| 326 | int qed_mcp_cmd_init(struct qed_hwfn *p_hwfn, |
| 327 | struct qed_ptt *p_ptt); |
| 328 | |
| 329 | /** |
| 330 | * @brief Initialize the port interface with the MCP |
| 331 | * |
| 332 | * @param p_hwfn |
| 333 | * @param p_ptt |
| 334 | * Can only be called after `num_ports_in_engines' is set |
| 335 | */ |
| 336 | void qed_mcp_cmd_port_init(struct qed_hwfn *p_hwfn, |
| 337 | struct qed_ptt *p_ptt); |
| 338 | /** |
| 339 | * @brief Releases resources allocated during the init process. |
| 340 | * |
| 341 | * @param p_hwfn - HW func |
| 342 | * @param p_ptt - PTT required for register access |
| 343 | * |
| 344 | * @return int |
| 345 | */ |
| 346 | |
| 347 | int qed_mcp_free(struct qed_hwfn *p_hwfn); |
| 348 | |
| 349 | /** |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 350 | * @brief This function is called from the DPC context. After |
| 351 | * pointing PTT to the mfw mb, check for events sent by the MCP |
| 352 | * to the driver and ack them. In case a critical event |
| 353 | * detected, it will be handled here, otherwise the work will be |
| 354 | * queued to a sleepable work-queue. |
| 355 | * |
| 356 | * @param p_hwfn - HW function |
| 357 | * @param p_ptt - PTT required for register access |
| 358 | * @return int - 0 - operation |
| 359 | * was successul. |
| 360 | */ |
| 361 | int qed_mcp_handle_events(struct qed_hwfn *p_hwfn, |
| 362 | struct qed_ptt *p_ptt); |
| 363 | |
| 364 | /** |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 365 | * @brief Sends a LOAD_REQ to the MFW, and in case operation |
| 366 | * succeed, returns whether this PF is the first on the |
| 367 | * chip/engine/port or function. This function should be |
| 368 | * called when driver is ready to accept MFW events after |
| 369 | * Storms initializations are done. |
| 370 | * |
| 371 | * @param p_hwfn - hw function |
| 372 | * @param p_ptt - PTT required for register access |
| 373 | * @param p_load_code - The MCP response param containing one |
| 374 | * of the following: |
| 375 | * FW_MSG_CODE_DRV_LOAD_ENGINE |
| 376 | * FW_MSG_CODE_DRV_LOAD_PORT |
| 377 | * FW_MSG_CODE_DRV_LOAD_FUNCTION |
| 378 | * @return int - |
| 379 | * 0 - Operation was successul. |
| 380 | * -EBUSY - Operation failed |
| 381 | */ |
| 382 | int qed_mcp_load_req(struct qed_hwfn *p_hwfn, |
| 383 | struct qed_ptt *p_ptt, |
| 384 | u32 *p_load_code); |
| 385 | |
| 386 | /** |
| 387 | * @brief Read the MFW mailbox into Current buffer. |
| 388 | * |
| 389 | * @param p_hwfn |
| 390 | * @param p_ptt |
| 391 | */ |
| 392 | void qed_mcp_read_mb(struct qed_hwfn *p_hwfn, |
| 393 | struct qed_ptt *p_ptt); |
| 394 | |
| 395 | /** |
| 396 | * @brief - calls during init to read shmem of all function-related info. |
| 397 | * |
| 398 | * @param p_hwfn |
| 399 | * |
| 400 | * @param return 0 upon success. |
| 401 | */ |
| 402 | int qed_mcp_fill_shmem_func_info(struct qed_hwfn *p_hwfn, |
| 403 | struct qed_ptt *p_ptt); |
| 404 | |
| 405 | /** |
| 406 | * @brief - Reset the MCP using mailbox command. |
| 407 | * |
| 408 | * @param p_hwfn |
| 409 | * @param p_ptt |
| 410 | * |
| 411 | * @param return 0 upon success. |
| 412 | */ |
| 413 | int qed_mcp_reset(struct qed_hwfn *p_hwfn, |
| 414 | struct qed_ptt *p_ptt); |
| 415 | |
| 416 | /** |
| 417 | * @brief indicates whether the MFW objects [under mcp_info] are accessible |
| 418 | * |
| 419 | * @param p_hwfn |
| 420 | * |
| 421 | * @return true iff MFW is running and mcp_info is initialized |
| 422 | */ |
| 423 | bool qed_mcp_is_init(struct qed_hwfn *p_hwfn); |
Yuval Mintz | 1408cc1f | 2016-05-11 16:36:14 +0300 | [diff] [blame^] | 424 | |
| 425 | /** |
| 426 | * @brief request MFW to configure MSI-X for a VF |
| 427 | * |
| 428 | * @param p_hwfn |
| 429 | * @param p_ptt |
| 430 | * @param vf_id - absolute inside engine |
| 431 | * @param num_sbs - number of entries to request |
| 432 | * |
| 433 | * @return int |
| 434 | */ |
| 435 | int qed_mcp_config_vf_msix(struct qed_hwfn *p_hwfn, |
| 436 | struct qed_ptt *p_ptt, u8 vf_id, u8 num); |
| 437 | |
Manish Chopra | a64b02d | 2016-04-26 10:56:10 -0400 | [diff] [blame] | 438 | int qed_configure_pf_min_bandwidth(struct qed_dev *cdev, u8 min_bw); |
Manish Chopra | 4b01e51 | 2016-04-26 10:56:09 -0400 | [diff] [blame] | 439 | int qed_configure_pf_max_bandwidth(struct qed_dev *cdev, u8 max_bw); |
| 440 | int __qed_configure_pf_max_bandwidth(struct qed_hwfn *p_hwfn, |
| 441 | struct qed_ptt *p_ptt, |
| 442 | struct qed_mcp_link_state *p_link, |
| 443 | u8 max_bw); |
Manish Chopra | a64b02d | 2016-04-26 10:56:10 -0400 | [diff] [blame] | 444 | int __qed_configure_pf_min_bandwidth(struct qed_hwfn *p_hwfn, |
| 445 | struct qed_ptt *p_ptt, |
| 446 | struct qed_mcp_link_state *p_link, |
| 447 | u8 min_bw); |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 448 | #endif |