1 /* 2 * Copyright (c) 2009-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31 #ifndef _SYS_EFX_MCDI_H 32 #define _SYS_EFX_MCDI_H 33 34 #include "efx.h" 35 #include "efx_regs_mcdi.h" 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /* 42 * A reboot/assertion causes the MCDI status word to be set after the 43 * command word is set or a REBOOT event is sent. If we notice a reboot 44 * via these mechanisms then wait 10ms for the status word to be set. 45 */ 46 #define EFX_MCDI_STATUS_SLEEP_US 10000 47 48 struct efx_mcdi_req_s { 49 boolean_t emr_quiet; 50 /* Inputs: Command #, input buffer and length */ 51 unsigned int emr_cmd; 52 uint8_t *emr_in_buf; 53 size_t emr_in_length; 54 /* Outputs: retcode, buffer, length, and length used*/ 55 efx_rc_t emr_rc; 56 uint8_t *emr_out_buf; 57 size_t emr_out_length; 58 size_t emr_out_length_used; 59 /* Internals: low level transport details */ 60 unsigned int emr_err_code; 61 unsigned int emr_err_arg; 62 #if EFSYS_OPT_MCDI_PROXY_AUTH 63 uint32_t emr_proxy_handle; 64 #endif 65 }; 66 67 typedef struct efx_mcdi_iface_s { 68 unsigned int emi_port; 69 unsigned int emi_max_version; 70 unsigned int emi_seq; 71 efx_mcdi_req_t *emi_pending_req; 72 boolean_t emi_ev_cpl; 73 boolean_t emi_new_epoch; 74 int emi_aborted; 75 uint32_t emi_poll_cnt; 76 uint32_t emi_mc_reboot_status; 77 } efx_mcdi_iface_t; 78 79 extern void 80 efx_mcdi_execute( 81 __in efx_nic_t *enp, 82 __inout efx_mcdi_req_t *emrp); 83 84 extern void 85 efx_mcdi_execute_quiet( 86 __in efx_nic_t *enp, 87 __inout efx_mcdi_req_t *emrp); 88 89 extern void 90 efx_mcdi_ev_cpl( 91 __in efx_nic_t *enp, 92 __in unsigned int seq, 93 __in unsigned int outlen, 94 __in int errcode); 95 96 #if EFSYS_OPT_MCDI_PROXY_AUTH 97 extern __checkReturn efx_rc_t 98 efx_mcdi_get_proxy_handle( 99 __in efx_nic_t *enp, 100 __in efx_mcdi_req_t *emrp, 101 __out uint32_t *handlep); 102 103 extern void 104 efx_mcdi_ev_proxy_response( 105 __in efx_nic_t *enp, 106 __in unsigned int handle, 107 __in unsigned int status); 108 #endif 109 110 extern void 111 efx_mcdi_ev_death( 112 __in efx_nic_t *enp, 113 __in int rc); 114 115 extern __checkReturn efx_rc_t 116 efx_mcdi_request_errcode( 117 __in unsigned int err); 118 119 extern void 120 efx_mcdi_raise_exception( 121 __in efx_nic_t *enp, 122 __in_opt efx_mcdi_req_t *emrp, 123 __in int rc); 124 125 typedef enum efx_mcdi_boot_e { 126 EFX_MCDI_BOOT_PRIMARY, 127 EFX_MCDI_BOOT_SECONDARY, 128 EFX_MCDI_BOOT_ROM, 129 } efx_mcdi_boot_t; 130 131 extern __checkReturn efx_rc_t 132 efx_mcdi_version( 133 __in efx_nic_t *enp, 134 __out_ecount_opt(4) uint16_t versionp[4], 135 __out_opt uint32_t *buildp, 136 __out_opt efx_mcdi_boot_t *statusp); 137 138 extern __checkReturn efx_rc_t 139 efx_mcdi_read_assertion( 140 __in efx_nic_t *enp); 141 142 extern __checkReturn efx_rc_t 143 efx_mcdi_exit_assertion_handler( 144 __in efx_nic_t *enp); 145 146 extern __checkReturn efx_rc_t 147 efx_mcdi_drv_attach( 148 __in efx_nic_t *enp, 149 __in boolean_t attach); 150 151 extern __checkReturn efx_rc_t 152 efx_mcdi_get_board_cfg( 153 __in efx_nic_t *enp, 154 __out_opt uint32_t *board_typep, 155 __out_opt efx_dword_t *capabilitiesp, 156 __out_ecount_opt(6) uint8_t mac_addrp[6]); 157 158 extern __checkReturn efx_rc_t 159 efx_mcdi_get_phy_cfg( 160 __in efx_nic_t *enp); 161 162 extern __checkReturn efx_rc_t 163 efx_mcdi_firmware_update_supported( 164 __in efx_nic_t *enp, 165 __out boolean_t *supportedp); 166 167 extern __checkReturn efx_rc_t 168 efx_mcdi_macaddr_change_supported( 169 __in efx_nic_t *enp, 170 __out boolean_t *supportedp); 171 172 extern __checkReturn efx_rc_t 173 efx_mcdi_link_control_supported( 174 __in efx_nic_t *enp, 175 __out boolean_t *supportedp); 176 177 extern __checkReturn efx_rc_t 178 efx_mcdi_mac_spoofing_supported( 179 __in efx_nic_t *enp, 180 __out boolean_t *supportedp); 181 182 183 #if EFSYS_OPT_BIST 184 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 185 extern __checkReturn efx_rc_t 186 efx_mcdi_bist_enable_offline( 187 __in efx_nic_t *enp); 188 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 189 extern __checkReturn efx_rc_t 190 efx_mcdi_bist_start( 191 __in efx_nic_t *enp, 192 __in efx_bist_type_t type); 193 #endif /* EFSYS_OPT_BIST */ 194 195 extern __checkReturn efx_rc_t 196 efx_mcdi_get_resource_limits( 197 __in efx_nic_t *enp, 198 __out_opt uint32_t *nevqp, 199 __out_opt uint32_t *nrxqp, 200 __out_opt uint32_t *ntxqp); 201 202 extern __checkReturn efx_rc_t 203 efx_mcdi_log_ctrl( 204 __in efx_nic_t *enp); 205 206 extern __checkReturn efx_rc_t 207 efx_mcdi_mac_stats_clear( 208 __in efx_nic_t *enp); 209 210 extern __checkReturn efx_rc_t 211 efx_mcdi_mac_stats_upload( 212 __in efx_nic_t *enp, 213 __in efsys_mem_t *esmp); 214 215 extern __checkReturn efx_rc_t 216 efx_mcdi_mac_stats_periodic( 217 __in efx_nic_t *enp, 218 __in efsys_mem_t *esmp, 219 __in uint16_t period, 220 __in boolean_t events); 221 222 223 #if EFSYS_OPT_LOOPBACK 224 extern __checkReturn efx_rc_t 225 efx_mcdi_get_loopback_modes( 226 __in efx_nic_t *enp); 227 #endif /* EFSYS_OPT_LOOPBACK */ 228 229 extern __checkReturn efx_rc_t 230 efx_mcdi_phy_module_get_info( 231 __in efx_nic_t *enp, 232 __in uint8_t dev_addr, 233 __in uint8_t offset, 234 __in uint8_t len, 235 __out_bcount(len) uint8_t *data); 236 237 #define MCDI_IN(_emr, _type, _ofst) \ 238 ((_type *)((_emr).emr_in_buf + (_ofst))) 239 240 #define MCDI_IN2(_emr, _type, _ofst) \ 241 MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST) 242 243 #define MCDI_IN_SET_BYTE(_emr, _ofst, _value) \ 244 EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst), \ 245 EFX_BYTE_0, _value) 246 247 #define MCDI_IN_SET_WORD(_emr, _ofst, _value) \ 248 EFX_POPULATE_WORD_1(*MCDI_IN2(_emr, efx_word_t, _ofst), \ 249 EFX_WORD_0, _value) 250 251 #define MCDI_IN_SET_DWORD(_emr, _ofst, _value) \ 252 EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 253 EFX_DWORD_0, _value) 254 255 #define MCDI_IN_SET_DWORD_FIELD(_emr, _ofst, _field, _value) \ 256 EFX_SET_DWORD_FIELD(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 257 MC_CMD_ ## _field, _value) 258 259 #define MCDI_IN_POPULATE_DWORD_1(_emr, _ofst, _field1, _value1) \ 260 EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 261 MC_CMD_ ## _field1, _value1) 262 263 #define MCDI_IN_POPULATE_DWORD_2(_emr, _ofst, _field1, _value1, \ 264 _field2, _value2) \ 265 EFX_POPULATE_DWORD_2(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 266 MC_CMD_ ## _field1, _value1, \ 267 MC_CMD_ ## _field2, _value2) 268 269 #define MCDI_IN_POPULATE_DWORD_3(_emr, _ofst, _field1, _value1, \ 270 _field2, _value2, _field3, _value3) \ 271 EFX_POPULATE_DWORD_3(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 272 MC_CMD_ ## _field1, _value1, \ 273 MC_CMD_ ## _field2, _value2, \ 274 MC_CMD_ ## _field3, _value3) 275 276 #define MCDI_IN_POPULATE_DWORD_4(_emr, _ofst, _field1, _value1, \ 277 _field2, _value2, _field3, _value3, _field4, _value4) \ 278 EFX_POPULATE_DWORD_4(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 279 MC_CMD_ ## _field1, _value1, \ 280 MC_CMD_ ## _field2, _value2, \ 281 MC_CMD_ ## _field3, _value3, \ 282 MC_CMD_ ## _field4, _value4) 283 284 #define MCDI_IN_POPULATE_DWORD_5(_emr, _ofst, _field1, _value1, \ 285 _field2, _value2, _field3, _value3, _field4, _value4, \ 286 _field5, _value5) \ 287 EFX_POPULATE_DWORD_5(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 288 MC_CMD_ ## _field1, _value1, \ 289 MC_CMD_ ## _field2, _value2, \ 290 MC_CMD_ ## _field3, _value3, \ 291 MC_CMD_ ## _field4, _value4, \ 292 MC_CMD_ ## _field5, _value5) 293 294 #define MCDI_IN_POPULATE_DWORD_6(_emr, _ofst, _field1, _value1, \ 295 _field2, _value2, _field3, _value3, _field4, _value4, \ 296 _field5, _value5, _field6, _value6) \ 297 EFX_POPULATE_DWORD_6(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 298 MC_CMD_ ## _field1, _value1, \ 299 MC_CMD_ ## _field2, _value2, \ 300 MC_CMD_ ## _field3, _value3, \ 301 MC_CMD_ ## _field4, _value4, \ 302 MC_CMD_ ## _field5, _value5, \ 303 MC_CMD_ ## _field6, _value6) 304 305 #define MCDI_IN_POPULATE_DWORD_7(_emr, _ofst, _field1, _value1, \ 306 _field2, _value2, _field3, _value3, _field4, _value4, \ 307 _field5, _value5, _field6, _value6, _field7, _value7) \ 308 EFX_POPULATE_DWORD_7(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 309 MC_CMD_ ## _field1, _value1, \ 310 MC_CMD_ ## _field2, _value2, \ 311 MC_CMD_ ## _field3, _value3, \ 312 MC_CMD_ ## _field4, _value4, \ 313 MC_CMD_ ## _field5, _value5, \ 314 MC_CMD_ ## _field6, _value6, \ 315 MC_CMD_ ## _field7, _value7) 316 317 #define MCDI_IN_POPULATE_DWORD_8(_emr, _ofst, _field1, _value1, \ 318 _field2, _value2, _field3, _value3, _field4, _value4, \ 319 _field5, _value5, _field6, _value6, _field7, _value7, \ 320 _field8, _value8) \ 321 EFX_POPULATE_DWORD_8(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 322 MC_CMD_ ## _field1, _value1, \ 323 MC_CMD_ ## _field2, _value2, \ 324 MC_CMD_ ## _field3, _value3, \ 325 MC_CMD_ ## _field4, _value4, \ 326 MC_CMD_ ## _field5, _value5, \ 327 MC_CMD_ ## _field6, _value6, \ 328 MC_CMD_ ## _field7, _value7, \ 329 MC_CMD_ ## _field8, _value8) 330 331 #define MCDI_IN_POPULATE_DWORD_9(_emr, _ofst, _field1, _value1, \ 332 _field2, _value2, _field3, _value3, _field4, _value4, \ 333 _field5, _value5, _field6, _value6, _field7, _value7, \ 334 _field8, _value8, _field9, _value9) \ 335 EFX_POPULATE_DWORD_9(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 336 MC_CMD_ ## _field1, _value1, \ 337 MC_CMD_ ## _field2, _value2, \ 338 MC_CMD_ ## _field3, _value3, \ 339 MC_CMD_ ## _field4, _value4, \ 340 MC_CMD_ ## _field5, _value5, \ 341 MC_CMD_ ## _field6, _value6, \ 342 MC_CMD_ ## _field7, _value7, \ 343 MC_CMD_ ## _field8, _value8, \ 344 MC_CMD_ ## _field9, _value9) 345 346 #define MCDI_IN_POPULATE_DWORD_10(_emr, _ofst, _field1, _value1, \ 347 _field2, _value2, _field3, _value3, _field4, _value4, \ 348 _field5, _value5, _field6, _value6, _field7, _value7, \ 349 _field8, _value8, _field9, _value9, _field10, _value10) \ 350 EFX_POPULATE_DWORD_10(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ 351 MC_CMD_ ## _field1, _value1, \ 352 MC_CMD_ ## _field2, _value2, \ 353 MC_CMD_ ## _field3, _value3, \ 354 MC_CMD_ ## _field4, _value4, \ 355 MC_CMD_ ## _field5, _value5, \ 356 MC_CMD_ ## _field6, _value6, \ 357 MC_CMD_ ## _field7, _value7, \ 358 MC_CMD_ ## _field8, _value8, \ 359 MC_CMD_ ## _field9, _value9, \ 360 MC_CMD_ ## _field10, _value10) 361 362 #define MCDI_OUT(_emr, _type, _ofst) \ 363 ((_type *)((_emr).emr_out_buf + (_ofst))) 364 365 #define MCDI_OUT2(_emr, _type, _ofst) \ 366 MCDI_OUT(_emr, _type, MC_CMD_ ## _ofst ## _OFST) 367 368 #define MCDI_OUT_BYTE(_emr, _ofst) \ 369 EFX_BYTE_FIELD(*MCDI_OUT2(_emr, efx_byte_t, _ofst), \ 370 EFX_BYTE_0) 371 372 #define MCDI_OUT_WORD(_emr, _ofst) \ 373 EFX_WORD_FIELD(*MCDI_OUT2(_emr, efx_word_t, _ofst), \ 374 EFX_WORD_0) 375 376 #define MCDI_OUT_DWORD(_emr, _ofst) \ 377 EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst), \ 378 EFX_DWORD_0) 379 380 #define MCDI_OUT_DWORD_FIELD(_emr, _ofst, _field) \ 381 EFX_DWORD_FIELD(*MCDI_OUT2(_emr, efx_dword_t, _ofst), \ 382 MC_CMD_ ## _field) 383 384 #define MCDI_EV_FIELD(_eqp, _field) \ 385 EFX_QWORD_FIELD(*_eqp, MCDI_EVENT_ ## _field) 386 387 #define MCDI_CMD_DWORD_FIELD(_edp, _field) \ 388 EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field) 389 390 #define EFX_MCDI_HAVE_PRIVILEGE(mask, priv) \ 391 (((mask) & (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) == \ 392 (MC_CMD_PRIVILEGE_MASK_IN_GRP_ ## priv)) 393 394 typedef enum efx_mcdi_feature_id_e { 395 EFX_MCDI_FEATURE_FW_UPDATE = 0, 396 EFX_MCDI_FEATURE_LINK_CONTROL, 397 EFX_MCDI_FEATURE_MACADDR_CHANGE, 398 EFX_MCDI_FEATURE_MAC_SPOOFING, 399 EFX_MCDI_FEATURE_NIDS 400 } efx_mcdi_feature_id_t; 401 402 #ifdef __cplusplus 403 } 404 #endif 405 406 #endif /* _SYS_EFX_MCDI_H */ 407