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