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 | * |
| 152 | * @param cdev - qed dev pointer |
| 153 | * @param mfw_ver - mfw version value |
| 154 | * |
| 155 | * @return int - 0 - operation was successul. |
| 156 | */ |
| 157 | int qed_mcp_get_mfw_ver(struct qed_dev *cdev, |
| 158 | u32 *mfw_ver); |
| 159 | |
| 160 | /** |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 161 | * @brief Get media type value of the port. |
| 162 | * |
| 163 | * @param cdev - qed dev pointer |
| 164 | * @param mfw_ver - media type value |
| 165 | * |
| 166 | * @return int - |
| 167 | * 0 - Operation was successul. |
| 168 | * -EBUSY - Operation failed |
| 169 | */ |
| 170 | int qed_mcp_get_media_type(struct qed_dev *cdev, |
| 171 | u32 *media_type); |
| 172 | |
| 173 | /** |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 174 | * @brief General function for sending commands to the MCP |
| 175 | * mailbox. It acquire mutex lock for the entire |
| 176 | * operation, from sending the request until the MCP |
| 177 | * response. Waiting for MCP response will be checked up |
| 178 | * to 5 seconds every 5ms. |
| 179 | * |
| 180 | * @param p_hwfn - hw function |
| 181 | * @param p_ptt - PTT required for register access |
| 182 | * @param cmd - command to be sent to the MCP. |
| 183 | * @param param - Optional param |
| 184 | * @param o_mcp_resp - The MCP response code (exclude sequence). |
| 185 | * @param o_mcp_param- Optional parameter provided by the MCP |
| 186 | * response |
| 187 | * @return int - 0 - operation |
| 188 | * was successul. |
| 189 | */ |
| 190 | int qed_mcp_cmd(struct qed_hwfn *p_hwfn, |
| 191 | struct qed_ptt *p_ptt, |
| 192 | u32 cmd, |
| 193 | u32 param, |
| 194 | u32 *o_mcp_resp, |
| 195 | u32 *o_mcp_param); |
| 196 | |
| 197 | /** |
| 198 | * @brief - drains the nig, allowing completion to pass in case of pauses. |
| 199 | * (Should be called only from sleepable context) |
| 200 | * |
| 201 | * @param p_hwfn |
| 202 | * @param p_ptt |
| 203 | */ |
| 204 | int qed_mcp_drain(struct qed_hwfn *p_hwfn, |
| 205 | struct qed_ptt *p_ptt); |
| 206 | |
| 207 | /** |
Manish Chopra | cee4d26 | 2015-10-26 11:02:28 +0200 | [diff] [blame] | 208 | * @brief Get the flash size value |
| 209 | * |
| 210 | * @param p_hwfn |
| 211 | * @param p_ptt |
| 212 | * @param p_flash_size - flash size in bytes to be filled. |
| 213 | * |
| 214 | * @return int - 0 - operation was successul. |
| 215 | */ |
| 216 | int qed_mcp_get_flash_size(struct qed_hwfn *p_hwfn, |
| 217 | struct qed_ptt *p_ptt, |
| 218 | u32 *p_flash_size); |
| 219 | |
| 220 | /** |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 221 | * @brief Send driver version to MFW |
| 222 | * |
| 223 | * @param p_hwfn |
| 224 | * @param p_ptt |
| 225 | * @param version - Version value |
| 226 | * @param name - Protocol driver name |
| 227 | * |
| 228 | * @return int - 0 - operation was successul. |
| 229 | */ |
| 230 | int |
| 231 | qed_mcp_send_drv_version(struct qed_hwfn *p_hwfn, |
| 232 | struct qed_ptt *p_ptt, |
| 233 | struct qed_mcp_drv_version *p_ver); |
| 234 | |
Sudarsana Kalluru | 91420b8 | 2015-11-30 12:25:03 +0200 | [diff] [blame] | 235 | /** |
| 236 | * @brief Set LED status |
| 237 | * |
| 238 | * @param p_hwfn |
| 239 | * @param p_ptt |
| 240 | * @param mode - LED mode |
| 241 | * |
| 242 | * @return int - 0 - operation was successful. |
| 243 | */ |
| 244 | int qed_mcp_set_led(struct qed_hwfn *p_hwfn, |
| 245 | struct qed_ptt *p_ptt, |
| 246 | enum qed_led_mode mode); |
| 247 | |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 248 | /* Using hwfn number (and not pf_num) is required since in CMT mode, |
| 249 | * same pf_num may be used by two different hwfn |
| 250 | * TODO - this shouldn't really be in .h file, but until all fields |
| 251 | * required during hw-init will be placed in their correct place in shmem |
| 252 | * we need it in qed_dev.c [for readin the nvram reflection in shmem]. |
| 253 | */ |
| 254 | #define MCP_PF_ID_BY_REL(p_hwfn, rel_pfid) (QED_IS_BB((p_hwfn)->cdev) ? \ |
| 255 | ((rel_pfid) | \ |
| 256 | ((p_hwfn)->abs_pf_id & 1) << 3) : \ |
| 257 | rel_pfid) |
| 258 | #define MCP_PF_ID(p_hwfn) MCP_PF_ID_BY_REL(p_hwfn, (p_hwfn)->rel_pf_id) |
| 259 | |
| 260 | /* TODO - this is only correct as long as only BB is supported, and |
| 261 | * no port-swapping is implemented; Afterwards we'll need to fix it. |
| 262 | */ |
| 263 | #define MFW_PORT(_p_hwfn) ((_p_hwfn)->abs_pf_id % \ |
| 264 | ((_p_hwfn)->cdev->num_ports_in_engines * 2)) |
| 265 | struct qed_mcp_info { |
Tomer Tayar | 5529bad | 2016-03-09 09:16:24 +0200 | [diff] [blame] | 266 | spinlock_t lock; |
| 267 | bool block_mb_sending; |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 268 | u32 public_base; |
| 269 | u32 drv_mb_addr; |
| 270 | u32 mfw_mb_addr; |
| 271 | u32 port_addr; |
| 272 | u16 drv_mb_seq; |
| 273 | u16 drv_pulse_seq; |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 274 | struct qed_mcp_link_params link_input; |
| 275 | struct qed_mcp_link_state link_output; |
| 276 | struct qed_mcp_link_capabilities link_capabilities; |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 277 | struct qed_mcp_function_info func_info; |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 278 | u8 *mfw_mb_cur; |
| 279 | u8 *mfw_mb_shadow; |
| 280 | u16 mfw_mb_length; |
| 281 | u16 mcp_hist; |
| 282 | }; |
| 283 | |
Tomer Tayar | 5529bad | 2016-03-09 09:16:24 +0200 | [diff] [blame] | 284 | struct qed_mcp_mb_params { |
| 285 | u32 cmd; |
| 286 | u32 param; |
| 287 | union drv_union_data *p_data_src; |
| 288 | union drv_union_data *p_data_dst; |
| 289 | u32 mcp_resp; |
| 290 | u32 mcp_param; |
| 291 | }; |
| 292 | |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 293 | /** |
| 294 | * @brief Initialize the interface with the MCP |
| 295 | * |
| 296 | * @param p_hwfn - HW func |
| 297 | * @param p_ptt - PTT required for register access |
| 298 | * |
| 299 | * @return int |
| 300 | */ |
| 301 | int qed_mcp_cmd_init(struct qed_hwfn *p_hwfn, |
| 302 | struct qed_ptt *p_ptt); |
| 303 | |
| 304 | /** |
| 305 | * @brief Initialize the port interface with the MCP |
| 306 | * |
| 307 | * @param p_hwfn |
| 308 | * @param p_ptt |
| 309 | * Can only be called after `num_ports_in_engines' is set |
| 310 | */ |
| 311 | void qed_mcp_cmd_port_init(struct qed_hwfn *p_hwfn, |
| 312 | struct qed_ptt *p_ptt); |
| 313 | /** |
| 314 | * @brief Releases resources allocated during the init process. |
| 315 | * |
| 316 | * @param p_hwfn - HW func |
| 317 | * @param p_ptt - PTT required for register access |
| 318 | * |
| 319 | * @return int |
| 320 | */ |
| 321 | |
| 322 | int qed_mcp_free(struct qed_hwfn *p_hwfn); |
| 323 | |
| 324 | /** |
Yuval Mintz | cc875c2 | 2015-10-26 11:02:31 +0200 | [diff] [blame] | 325 | * @brief This function is called from the DPC context. After |
| 326 | * pointing PTT to the mfw mb, check for events sent by the MCP |
| 327 | * to the driver and ack them. In case a critical event |
| 328 | * detected, it will be handled here, otherwise the work will be |
| 329 | * queued to a sleepable work-queue. |
| 330 | * |
| 331 | * @param p_hwfn - HW function |
| 332 | * @param p_ptt - PTT required for register access |
| 333 | * @return int - 0 - operation |
| 334 | * was successul. |
| 335 | */ |
| 336 | int qed_mcp_handle_events(struct qed_hwfn *p_hwfn, |
| 337 | struct qed_ptt *p_ptt); |
| 338 | |
| 339 | /** |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 340 | * @brief Sends a LOAD_REQ to the MFW, and in case operation |
| 341 | * succeed, returns whether this PF is the first on the |
| 342 | * chip/engine/port or function. This function should be |
| 343 | * called when driver is ready to accept MFW events after |
| 344 | * Storms initializations are done. |
| 345 | * |
| 346 | * @param p_hwfn - hw function |
| 347 | * @param p_ptt - PTT required for register access |
| 348 | * @param p_load_code - The MCP response param containing one |
| 349 | * of the following: |
| 350 | * FW_MSG_CODE_DRV_LOAD_ENGINE |
| 351 | * FW_MSG_CODE_DRV_LOAD_PORT |
| 352 | * FW_MSG_CODE_DRV_LOAD_FUNCTION |
| 353 | * @return int - |
| 354 | * 0 - Operation was successul. |
| 355 | * -EBUSY - Operation failed |
| 356 | */ |
| 357 | int qed_mcp_load_req(struct qed_hwfn *p_hwfn, |
| 358 | struct qed_ptt *p_ptt, |
| 359 | u32 *p_load_code); |
| 360 | |
| 361 | /** |
| 362 | * @brief Read the MFW mailbox into Current buffer. |
| 363 | * |
| 364 | * @param p_hwfn |
| 365 | * @param p_ptt |
| 366 | */ |
| 367 | void qed_mcp_read_mb(struct qed_hwfn *p_hwfn, |
| 368 | struct qed_ptt *p_ptt); |
| 369 | |
| 370 | /** |
| 371 | * @brief - calls during init to read shmem of all function-related info. |
| 372 | * |
| 373 | * @param p_hwfn |
| 374 | * |
| 375 | * @param return 0 upon success. |
| 376 | */ |
| 377 | int qed_mcp_fill_shmem_func_info(struct qed_hwfn *p_hwfn, |
| 378 | struct qed_ptt *p_ptt); |
| 379 | |
| 380 | /** |
| 381 | * @brief - Reset the MCP using mailbox command. |
| 382 | * |
| 383 | * @param p_hwfn |
| 384 | * @param p_ptt |
| 385 | * |
| 386 | * @param return 0 upon success. |
| 387 | */ |
| 388 | int qed_mcp_reset(struct qed_hwfn *p_hwfn, |
| 389 | struct qed_ptt *p_ptt); |
| 390 | |
| 391 | /** |
| 392 | * @brief indicates whether the MFW objects [under mcp_info] are accessible |
| 393 | * |
| 394 | * @param p_hwfn |
| 395 | * |
| 396 | * @return true iff MFW is running and mcp_info is initialized |
| 397 | */ |
| 398 | bool qed_mcp_is_init(struct qed_hwfn *p_hwfn); |
Manish Chopra | a64b02d | 2016-04-26 10:56:10 -0400 | [diff] [blame^] | 399 | 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] | 400 | int qed_configure_pf_max_bandwidth(struct qed_dev *cdev, u8 max_bw); |
| 401 | int __qed_configure_pf_max_bandwidth(struct qed_hwfn *p_hwfn, |
| 402 | struct qed_ptt *p_ptt, |
| 403 | struct qed_mcp_link_state *p_link, |
| 404 | u8 max_bw); |
Manish Chopra | a64b02d | 2016-04-26 10:56:10 -0400 | [diff] [blame^] | 405 | int __qed_configure_pf_min_bandwidth(struct qed_hwfn *p_hwfn, |
| 406 | struct qed_ptt *p_ptt, |
| 407 | struct qed_mcp_link_state *p_link, |
| 408 | u8 min_bw); |
Yuval Mintz | fe56b9e | 2015-10-26 11:02:25 +0200 | [diff] [blame] | 409 | #endif |