|
|
1.1 ! root 1: #ifndef _HERMON_H ! 2: #define _HERMON_H ! 3: ! 4: /** @file ! 5: * ! 6: * Mellanox Hermon Infiniband HCA driver ! 7: * ! 8: */ ! 9: ! 10: FILE_LICENCE ( GPL2_OR_LATER ); ! 11: ! 12: #include <stdint.h> ! 13: #include <ipxe/uaccess.h> ! 14: #include <ipxe/ib_packet.h> ! 15: #include <ipxe/bofm.h> ! 16: #include "mlx_bitops.h" ! 17: #include "MT25408_PRM.h" ! 18: ! 19: /* ! 20: * Hardware constants ! 21: * ! 22: */ ! 23: ! 24: /* Ports in existence */ ! 25: #define HERMON_MAX_PORTS 2 ! 26: #define HERMON_PORT_BASE 1 ! 27: ! 28: /* PCI BARs */ ! 29: #define HERMON_PCI_CONFIG_BAR PCI_BASE_ADDRESS_0 ! 30: #define HERMON_PCI_CONFIG_BAR_SIZE 0x100000 ! 31: #define HERMON_PCI_UAR_BAR PCI_BASE_ADDRESS_2 ! 32: ! 33: /* Device reset */ ! 34: #define HERMON_RESET_OFFSET 0x0f0010 ! 35: #define HERMON_RESET_MAGIC 0x01000000UL ! 36: #define HERMON_RESET_WAIT_TIME_MS 1000 ! 37: ! 38: /* Work queue entry and completion queue entry opcodes */ ! 39: #define HERMON_OPCODE_NOP 0x00 ! 40: #define HERMON_OPCODE_SEND 0x0a ! 41: #define HERMON_OPCODE_RECV_ERROR 0xfe ! 42: #define HERMON_OPCODE_SEND_ERROR 0xff ! 43: ! 44: /* HCA command register opcodes */ ! 45: #define HERMON_HCR_QUERY_DEV_CAP 0x0003 ! 46: #define HERMON_HCR_QUERY_FW 0x0004 ! 47: #define HERMON_HCR_INIT_HCA 0x0007 ! 48: #define HERMON_HCR_CLOSE_HCA 0x0008 ! 49: #define HERMON_HCR_INIT_PORT 0x0009 ! 50: #define HERMON_HCR_CLOSE_PORT 0x000a ! 51: #define HERMON_HCR_SET_PORT 0x000c ! 52: #define HERMON_HCR_SW2HW_MPT 0x000d ! 53: #define HERMON_HCR_WRITE_MTT 0x0011 ! 54: #define HERMON_HCR_MAP_EQ 0x0012 ! 55: #define HERMON_HCR_SW2HW_EQ 0x0013 ! 56: #define HERMON_HCR_HW2SW_EQ 0x0014 ! 57: #define HERMON_HCR_QUERY_EQ 0x0015 ! 58: #define HERMON_HCR_SW2HW_CQ 0x0016 ! 59: #define HERMON_HCR_HW2SW_CQ 0x0017 ! 60: #define HERMON_HCR_QUERY_CQ 0x0018 ! 61: #define HERMON_HCR_RST2INIT_QP 0x0019 ! 62: #define HERMON_HCR_INIT2RTR_QP 0x001a ! 63: #define HERMON_HCR_RTR2RTS_QP 0x001b ! 64: #define HERMON_HCR_RTS2RTS_QP 0x001c ! 65: #define HERMON_HCR_2RST_QP 0x0021 ! 66: #define HERMON_HCR_QUERY_QP 0x0022 ! 67: #define HERMON_HCR_CONF_SPECIAL_QP 0x0023 ! 68: #define HERMON_HCR_MAD_IFC 0x0024 ! 69: #define HERMON_HCR_READ_MCG 0x0025 ! 70: #define HERMON_HCR_WRITE_MCG 0x0026 ! 71: #define HERMON_HCR_MGID_HASH 0x0027 ! 72: #define HERMON_HCR_MOD_STAT_CFG 0x0034 ! 73: #define HERMON_HCR_QUERY_PORT 0x0043 ! 74: #define HERMON_HCR_SENSE_PORT 0x004d ! 75: #define HERMON_HCR_RUN_FW 0x0ff6 ! 76: #define HERMON_HCR_DISABLE_LAM 0x0ff7 ! 77: #define HERMON_HCR_ENABLE_LAM 0x0ff8 ! 78: #define HERMON_HCR_UNMAP_ICM 0x0ff9 ! 79: #define HERMON_HCR_MAP_ICM 0x0ffa ! 80: #define HERMON_HCR_UNMAP_ICM_AUX 0x0ffb ! 81: #define HERMON_HCR_MAP_ICM_AUX 0x0ffc ! 82: #define HERMON_HCR_SET_ICM_SIZE 0x0ffd ! 83: #define HERMON_HCR_UNMAP_FA 0x0ffe ! 84: #define HERMON_HCR_MAP_FA 0x0fff ! 85: ! 86: /* Service types */ ! 87: #define HERMON_ST_RC 0x00 ! 88: #define HERMON_ST_UD 0x03 ! 89: #define HERMON_ST_MLX 0x07 ! 90: ! 91: /* Port types */ ! 92: #define HERMON_PORT_TYPE_UNKNOWN 0 ! 93: #define HERMON_PORT_TYPE_IB 1 ! 94: #define HERMON_PORT_TYPE_ETH 2 ! 95: ! 96: /* MTUs */ ! 97: #define HERMON_MTU_2048 0x04 ! 98: #define HERMON_MTU_ETH 0x07 ! 99: ! 100: #define HERMON_INVALID_LKEY 0x00000100UL ! 101: ! 102: #define HERMON_PAGE_SIZE ( ( size_t ) 4096 ) ! 103: ! 104: #define HERMON_DB_POST_SND_OFFSET 0x14 ! 105: #define HERMON_DB_EQ_OFFSET(_eqn) \ ! 106: ( 0x800 + HERMON_PAGE_SIZE * ( (_eqn) / 4 ) + 0x08 * ( (_eqn) % 4 ) ) ! 107: ! 108: #define HERMON_QP_OPT_PARAM_PM_STATE 0x00000400UL ! 109: #define HERMON_QP_OPT_PARAM_QKEY 0x00000020UL ! 110: #define HERMON_QP_OPT_PARAM_ALT_PATH 0x00000001UL ! 111: ! 112: #define HERMON_MAP_EQ ( 0UL << 31 ) ! 113: #define HERMON_UNMAP_EQ ( 1UL << 31 ) ! 114: ! 115: #define HERMON_SET_PORT_GENERAL_PARAM 0x0000 ! 116: #define HERMON_SET_PORT_RECEIVE_QP 0x0100 ! 117: #define HERMON_SET_PORT_MAC_TABLE 0x0200 ! 118: #define HERMON_SET_PORT_VLAN_TABLE 0x0300 ! 119: #define HERMON_SET_PORT_PRIORITY_TABLE 0x0400 ! 120: #define HERMON_SET_PORT_GID_TABLE 0x0500 ! 121: ! 122: #define HERMON_EV_PORT_STATE_CHANGE 0x09 ! 123: ! 124: #define HERMON_SCHED_QP0 0x3f ! 125: #define HERMON_SCHED_DEFAULT 0x83 ! 126: ! 127: #define HERMON_LOG_MULTICAST_HASH_SIZE 7 ! 128: ! 129: #define HERMON_PM_STATE_ARMED 0x00 ! 130: #define HERMON_PM_STATE_REARM 0x01 ! 131: #define HERMON_PM_STATE_MIGRATED 0x03 ! 132: ! 133: #define HERMON_RETRY_MAX 0x07 ! 134: ! 135: #define HERMON_MOD_STAT_CFG_SET 0x01 ! 136: #define HERMON_MOD_STAT_CFG_QUERY 0x03 ! 137: ! 138: /* ! 139: * Datatypes that seem to be missing from the autogenerated documentation ! 140: * ! 141: */ ! 142: struct hermonprm_mgm_hash_st { ! 143: pseudo_bit_t reserved0[0x00020]; ! 144: /* -------------- */ ! 145: pseudo_bit_t hash[0x00010]; ! 146: pseudo_bit_t reserved1[0x00010]; ! 147: } __attribute__ (( packed )); ! 148: ! 149: struct hermonprm_mcg_entry_st { ! 150: struct hermonprm_mcg_hdr_st hdr; ! 151: struct hermonprm_mcg_qp_dw_st qp[8]; ! 152: } __attribute__ (( packed )); ! 153: ! 154: struct hermonprm_cq_db_record_st { ! 155: pseudo_bit_t update_ci[0x00018]; ! 156: pseudo_bit_t reserved0[0x00008]; ! 157: /* -------------- */ ! 158: pseudo_bit_t arm_ci[0x00018]; ! 159: pseudo_bit_t cmd[0x00003]; ! 160: pseudo_bit_t reserved1[0x00001]; ! 161: pseudo_bit_t cmd_sn[0x00002]; ! 162: pseudo_bit_t reserved2[0x00002]; ! 163: } __attribute__ (( packed )); ! 164: ! 165: struct hermonprm_send_db_register_st { ! 166: pseudo_bit_t reserved[0x00008]; ! 167: pseudo_bit_t qn[0x00018]; ! 168: } __attribute__ (( packed )); ! 169: ! 170: struct hermonprm_event_db_register_st { ! 171: pseudo_bit_t ci[0x00018]; ! 172: pseudo_bit_t reserver[0x00007]; ! 173: pseudo_bit_t a[0x00001]; ! 174: } __attribute__ (( packed )); ! 175: ! 176: struct hermonprm_scalar_parameter_st { ! 177: pseudo_bit_t value_hi[0x00020]; ! 178: /* -------------- */ ! 179: pseudo_bit_t value[0x00020]; ! 180: } __attribute__ (( packed )); ! 181: ! 182: struct hermonprm_event_mask_st { ! 183: pseudo_bit_t reserved0[0x00020]; ! 184: /* -------------- */ ! 185: pseudo_bit_t completion[0x00001]; ! 186: pseudo_bit_t path_migration_succeeded[0x00001]; ! 187: pseudo_bit_t communication_established[0x00001]; ! 188: pseudo_bit_t send_queue_drained[0x00001]; ! 189: pseudo_bit_t cq_error[0x00001]; ! 190: pseudo_bit_t wq_catastrophe[0x00001]; ! 191: pseudo_bit_t qpc_catastrophe[0x00001]; ! 192: pseudo_bit_t path_migration_failed[0x00001]; ! 193: pseudo_bit_t internal_error[0x00001]; ! 194: pseudo_bit_t port_state_change[0x00001]; ! 195: pseudo_bit_t command_done[0x00001]; ! 196: pseudo_bit_t fexch_error[0x00001]; ! 197: pseudo_bit_t reserved1[0x00004]; ! 198: pseudo_bit_t wq_invalid_request[0x00001]; ! 199: pseudo_bit_t wq_access_violation[0x00001]; ! 200: pseudo_bit_t srq_catastrophe[0x00001]; ! 201: pseudo_bit_t srq_last_wqe[0x00001]; ! 202: pseudo_bit_t srq_rq_limit[0x00001]; ! 203: pseudo_bit_t gpio[0x00001]; ! 204: pseudo_bit_t clientreregister[0x00001]; ! 205: pseudo_bit_t reserved2[0x00009]; ! 206: } __attribute__ (( packed )); ! 207: ! 208: struct hermonprm_port_state_change_event_st { ! 209: pseudo_bit_t reserved[0x00020]; ! 210: /* -------------- */ ! 211: struct hermonprm_port_state_change_st data; ! 212: } __attribute__ (( packed )); ! 213: ! 214: struct hermonprm_sense_port_st { ! 215: pseudo_bit_t reserved0[0x00020]; ! 216: /* -------------- */ ! 217: pseudo_bit_t port_type[0x00002]; ! 218: pseudo_bit_t reserved1[0x0001e]; ! 219: } __attribute__ (( packed )); ! 220: ! 221: struct hermonprm_set_port_ib_st { ! 222: pseudo_bit_t rqk[0x00001]; ! 223: pseudo_bit_t rcm[0x00001]; ! 224: pseudo_bit_t reserved0[0x00002]; ! 225: pseudo_bit_t vl_cap[0x00004]; ! 226: pseudo_bit_t reserved1[0x00004]; ! 227: pseudo_bit_t mtu_cap[0x00004]; ! 228: pseudo_bit_t g0[0x00001]; ! 229: pseudo_bit_t ng[0x00001]; ! 230: pseudo_bit_t sig[0x00001]; ! 231: pseudo_bit_t mg[0x00001]; ! 232: pseudo_bit_t mp[0x00001]; ! 233: pseudo_bit_t mvc[0x00001]; ! 234: pseudo_bit_t mmc[0x00001]; ! 235: pseudo_bit_t reserved2[0x00004]; ! 236: pseudo_bit_t lws[0x00001]; ! 237: pseudo_bit_t lss[0x00001]; ! 238: pseudo_bit_t reserved3[0x00003]; ! 239: /* -------------- */ ! 240: pseudo_bit_t capability_mask[0x00020]; ! 241: /* -------------- */ ! 242: pseudo_bit_t system_image_guid_h[0x00020]; ! 243: /* -------------- */ ! 244: pseudo_bit_t system_image_guid_l[0x00020]; ! 245: /* -------------- */ ! 246: pseudo_bit_t guid0_h[0x00020]; ! 247: /* -------------- */ ! 248: pseudo_bit_t guid0_l[0x00020]; ! 249: /* -------------- */ ! 250: pseudo_bit_t node_guid_h[0x00020]; ! 251: /* -------------- */ ! 252: pseudo_bit_t node_guid_l[0x00020]; ! 253: /* -------------- */ ! 254: pseudo_bit_t egress_sniff_qpn[0x00018]; ! 255: pseudo_bit_t egress_sniff_mode[0x00002]; ! 256: pseudo_bit_t reserved4[0x00006]; ! 257: /* -------------- */ ! 258: pseudo_bit_t ingress_sniff_qpn[0x00018]; ! 259: pseudo_bit_t ingress_sniff_mode[0x00002]; ! 260: pseudo_bit_t reserved5[0x00006]; ! 261: /* -------------- */ ! 262: pseudo_bit_t max_gid[0x00010]; ! 263: pseudo_bit_t max_pkey[0x00010]; ! 264: /* -------------- */ ! 265: pseudo_bit_t reserved6[0x00020]; ! 266: /* -------------- */ ! 267: pseudo_bit_t reserved7[0x00020]; ! 268: /* -------------- */ ! 269: pseudo_bit_t reserved8[0x00020]; ! 270: /* -------------- */ ! 271: pseudo_bit_t reserved9[0x00020]; ! 272: /* -------------- */ ! 273: pseudo_bit_t reserved10[0x00020]; ! 274: /* -------------- */ ! 275: pseudo_bit_t reserved11[0x00020]; ! 276: /* -------------- */ ! 277: pseudo_bit_t reserved12[0x00020]; ! 278: /* -------------- */ ! 279: pseudo_bit_t reserved13[0x00020]; ! 280: /* -------------- */ ! 281: pseudo_bit_t reserved14[0x00020]; ! 282: /* -------------- */ ! 283: pseudo_bit_t reserved15[0x00020]; ! 284: /* -------------- */ ! 285: pseudo_bit_t reserved16[0x00020]; ! 286: /* -------------- */ ! 287: pseudo_bit_t reserved17[0x00020]; ! 288: /* -------------- */ ! 289: pseudo_bit_t reserved18[0x00020]; ! 290: /* -------------- */ ! 291: pseudo_bit_t reserved19[0x00020]; ! 292: /* -------------- */ ! 293: pseudo_bit_t reserved20[0x00020]; ! 294: /* -------------- */ ! 295: pseudo_bit_t reserved21[0x00020]; ! 296: /* -------------- */ ! 297: pseudo_bit_t reserved22[0x00020]; ! 298: /* -------------- */ ! 299: pseudo_bit_t link_width_supported[0x00004]; ! 300: pseudo_bit_t link_speed_supported[0x00004]; ! 301: pseudo_bit_t reserved23[0x00018]; ! 302: /* -------------- */ ! 303: } __attribute__ (( packed )); ! 304: ! 305: struct hermonprm_query_port_cap_st { ! 306: pseudo_bit_t eth_mtu[0x00010]; ! 307: pseudo_bit_t ib_mtu[0x00004]; ! 308: pseudo_bit_t reserved0[0x00004]; ! 309: pseudo_bit_t ib[0x00001]; ! 310: pseudo_bit_t eth[0x00001]; ! 311: pseudo_bit_t reserved1[0x00005]; ! 312: pseudo_bit_t link_state[0x00001]; ! 313: /* -------------- */ ! 314: pseudo_bit_t log_max_pkey[0x00004]; ! 315: pseudo_bit_t log_max_gid[0x00004]; ! 316: pseudo_bit_t ib_port_width[0x00004]; ! 317: pseudo_bit_t reserved2[0x00004]; ! 318: pseudo_bit_t eth_link_speed[0x00004]; ! 319: pseudo_bit_t reserved3[0x00004]; ! 320: pseudo_bit_t ib_link_speed[0x00004]; ! 321: pseudo_bit_t reserved4[0x00004]; ! 322: /* -------------- */ ! 323: pseudo_bit_t max_vl_ib[0x00004]; ! 324: pseudo_bit_t reserved5[0x00004]; ! 325: pseudo_bit_t log_max_mac[0x00004]; ! 326: pseudo_bit_t log_max_vlan[0x00004]; ! 327: pseudo_bit_t reserved6[0x00010]; ! 328: /* -------------- */ ! 329: pseudo_bit_t reserved7[0x00020]; ! 330: /* -------------- */ ! 331: pseudo_bit_t mac_47_32[0x00010]; ! 332: pseudo_bit_t reserved8[0x00010]; ! 333: /* -------------- */ ! 334: pseudo_bit_t mac_31_0[0x00020]; ! 335: /* -------------- */ ! 336: pseudo_bit_t vendor_oui[0x00018]; ! 337: pseudo_bit_t transceiver_type[0x00008]; ! 338: /* -------------- */ ! 339: pseudo_bit_t reserved9[0x00010]; ! 340: pseudo_bit_t wavelength[0x00010]; ! 341: /* -------------- */ ! 342: pseudo_bit_t transceiver_code_hi[0x00020]; ! 343: /* -------------- */ ! 344: pseudo_bit_t transceiver_code_lo[0x00020]; ! 345: /* -------------- */ ! 346: pseudo_bit_t reserved10[0x000c0]; ! 347: } __attribute__ (( packed )); ! 348: ! 349: struct hermonprm_set_port_general_context_st { ! 350: pseudo_bit_t v_mtu[0x00001]; ! 351: pseudo_bit_t v_pprx[0x00001]; ! 352: pseudo_bit_t v_pptx[0x00001]; ! 353: pseudo_bit_t reserved0[0x0001d]; ! 354: /* -------------- */ ! 355: pseudo_bit_t mtu[0x00010]; ! 356: pseudo_bit_t reserved1[0x00010]; ! 357: /* -------------- */ ! 358: pseudo_bit_t reserved2[0x00010]; ! 359: pseudo_bit_t pfctx[0x00008]; ! 360: pseudo_bit_t reserved3[0x00007]; ! 361: pseudo_bit_t pptx[0x00001]; ! 362: /* -------------- */ ! 363: pseudo_bit_t reserved4[0x00010]; ! 364: pseudo_bit_t pfcrx[0x00008]; ! 365: pseudo_bit_t reserved5[0x00007]; ! 366: pseudo_bit_t pprx[0x00001]; ! 367: /* -------------- */ ! 368: } __attribute__ (( packed )); ! 369: ! 370: struct hermonprm_set_port_rqp_calc_st { ! 371: pseudo_bit_t base_qpn[0x00018]; ! 372: pseudo_bit_t reserved0[0x00008]; ! 373: /* -------------- */ ! 374: pseudo_bit_t n_p[0x00002]; ! 375: pseudo_bit_t reserved1[0x00006]; ! 376: pseudo_bit_t n_v[0x00003]; ! 377: pseudo_bit_t reserved2[0x00005]; ! 378: pseudo_bit_t n_m[0x00004]; ! 379: pseudo_bit_t reserved3[0x0000c]; ! 380: /* -------------- */ ! 381: pseudo_bit_t mac_miss_index[0x00008]; ! 382: pseudo_bit_t reserved4[0x00018]; ! 383: /* -------------- */ ! 384: pseudo_bit_t vlan_miss_index[0x00007]; ! 385: pseudo_bit_t reserved5[0x00008]; ! 386: pseudo_bit_t intra_miss[0x00001]; ! 387: pseudo_bit_t no_vlan_index[0x00007]; ! 388: pseudo_bit_t reserved6[0x00008]; ! 389: pseudo_bit_t intra_no_vlan[0x00001]; ! 390: /* -------------- */ ! 391: pseudo_bit_t no_vlan_prio[0x00003]; ! 392: pseudo_bit_t reserved7[0x0001d]; ! 393: /* -------------- */ ! 394: pseudo_bit_t promisc_qpn[0x00018]; ! 395: pseudo_bit_t reserved8[0x00007]; ! 396: pseudo_bit_t en_uc_promisc[0x00001]; ! 397: /* -------------- */ ! 398: pseudo_bit_t def_mcast_qpn[0x00018]; ! 399: pseudo_bit_t reserved9[0x00005]; ! 400: pseudo_bit_t mc_by_vlan[0x00001]; ! 401: pseudo_bit_t mc_promisc_mode[0x00002]; ! 402: /* -------------- */ ! 403: pseudo_bit_t reserved10[0x00020]; ! 404: /* -------------- */ ! 405: } __attribute__ (( packed )); ! 406: ! 407: struct hermonprm_set_port_mac_table_st { ! 408: pseudo_bit_t mac_h[0x00010]; ! 409: pseudo_bit_t reserved0[0x0000f]; ! 410: pseudo_bit_t v[0x00001]; ! 411: /* -------------- */ ! 412: pseudo_bit_t mac_l[0x00020]; ! 413: /* -------------- */ ! 414: } __attribute__ (( packed )); ! 415: ! 416: struct hermonprm_set_port_vlan_st { ! 417: pseudo_bit_t vlan_id[0x0000c]; ! 418: pseudo_bit_t reserved0[0x00012]; ! 419: pseudo_bit_t intra[0x00001]; ! 420: pseudo_bit_t v[0x00001]; ! 421: /* -------------- */ ! 422: } __attribute__ (( packed )); ! 423: ! 424: struct hermonprm_mod_stat_cfg_input_mod_st { ! 425: pseudo_bit_t offset[0x00008]; ! 426: pseudo_bit_t portnum[0x00008]; ! 427: pseudo_bit_t xnum[0x00004]; ! 428: pseudo_bit_t linkspeed[0x00003]; ! 429: pseudo_bit_t autoneg[0x00001]; ! 430: pseudo_bit_t reserved[0x00004]; ! 431: pseudo_bit_t setup_mode[0x00004]; ! 432: } __attribute__ (( packed )); ! 433: ! 434: /* ! 435: * Wrapper structures for hardware datatypes ! 436: * ! 437: */ ! 438: ! 439: struct MLX_DECLARE_STRUCT ( hermonprm_completion_queue_context ); ! 440: struct MLX_DECLARE_STRUCT ( hermonprm_completion_queue_entry ); ! 441: struct MLX_DECLARE_STRUCT ( hermonprm_completion_with_error ); ! 442: struct MLX_DECLARE_STRUCT ( hermonprm_cq_db_record ); ! 443: struct MLX_DECLARE_STRUCT ( hermonprm_eqc ); ! 444: struct MLX_DECLARE_STRUCT ( hermonprm_event_db_register ); ! 445: struct MLX_DECLARE_STRUCT ( hermonprm_event_mask ); ! 446: struct MLX_DECLARE_STRUCT ( hermonprm_event_queue_entry ); ! 447: struct MLX_DECLARE_STRUCT ( hermonprm_hca_command_register ); ! 448: struct MLX_DECLARE_STRUCT ( hermonprm_init_hca ); ! 449: struct MLX_DECLARE_STRUCT ( hermonprm_mad_ifc ); ! 450: struct MLX_DECLARE_STRUCT ( hermonprm_mcg_entry ); ! 451: struct MLX_DECLARE_STRUCT ( hermonprm_mgm_hash ); ! 452: struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg ); ! 453: struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg_input_mod ); ! 454: struct MLX_DECLARE_STRUCT ( hermonprm_mpt ); ! 455: struct MLX_DECLARE_STRUCT ( hermonprm_mtt ); ! 456: struct MLX_DECLARE_STRUCT ( hermonprm_port_state_change_event ); ! 457: struct MLX_DECLARE_STRUCT ( hermonprm_qp_db_record ); ! 458: struct MLX_DECLARE_STRUCT ( hermonprm_qp_ee_state_transitions ); ! 459: struct MLX_DECLARE_STRUCT ( hermonprm_query_dev_cap ); ! 460: struct MLX_DECLARE_STRUCT ( hermonprm_query_fw ); ! 461: struct MLX_DECLARE_STRUCT ( hermonprm_query_port_cap ); ! 462: struct MLX_DECLARE_STRUCT ( hermonprm_queue_pair_ee_context_entry ); ! 463: struct MLX_DECLARE_STRUCT ( hermonprm_scalar_parameter ); ! 464: struct MLX_DECLARE_STRUCT ( hermonprm_sense_port ); ! 465: struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register ); ! 466: struct MLX_DECLARE_STRUCT ( hermonprm_set_port_ib ); ! 467: struct MLX_DECLARE_STRUCT ( hermonprm_set_port_general_context ); ! 468: struct MLX_DECLARE_STRUCT ( hermonprm_set_port_mac_table ); ! 469: struct MLX_DECLARE_STRUCT ( hermonprm_set_port_rqp_calc ); ! 470: struct MLX_DECLARE_STRUCT ( hermonprm_set_port_vlan ); ! 471: struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector ); ! 472: struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping ); ! 473: struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_mlx ); ! 474: struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_send ); ! 475: struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_data_ptr ); ! 476: struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ud ); ! 477: ! 478: /* ! 479: * Composite hardware datatypes ! 480: * ! 481: */ ! 482: ! 483: struct hermonprm_write_mtt { ! 484: struct hermonprm_scalar_parameter mtt_base_addr; ! 485: struct hermonprm_scalar_parameter reserved; ! 486: struct hermonprm_mtt mtt; ! 487: } __attribute__ (( packed )); ! 488: ! 489: #define HERMON_MAX_GATHER 2 ! 490: ! 491: struct hermonprm_ud_send_wqe { ! 492: struct hermonprm_wqe_segment_ctrl_send ctrl; ! 493: struct hermonprm_wqe_segment_ud ud; ! 494: struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER]; ! 495: } __attribute__ (( packed )); ! 496: ! 497: struct hermonprm_mlx_send_wqe { ! 498: struct hermonprm_wqe_segment_ctrl_mlx ctrl; ! 499: struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER]; ! 500: uint8_t headers[IB_MAX_HEADER_SIZE]; ! 501: } __attribute__ (( packed )); ! 502: ! 503: struct hermonprm_rc_send_wqe { ! 504: struct hermonprm_wqe_segment_ctrl_send ctrl; ! 505: struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER]; ! 506: } __attribute__ (( packed )); ! 507: ! 508: struct hermonprm_eth_send_wqe { ! 509: struct hermonprm_wqe_segment_ctrl_send ctrl; ! 510: struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_GATHER]; ! 511: } __attribute__ (( packed )); ! 512: ! 513: #define HERMON_MAX_SCATTER 1 ! 514: ! 515: struct hermonprm_recv_wqe { ! 516: struct hermonprm_wqe_segment_data_ptr data[HERMON_MAX_SCATTER]; ! 517: } __attribute__ (( packed )); ! 518: ! 519: union hermonprm_completion_entry { ! 520: struct hermonprm_completion_queue_entry normal; ! 521: struct hermonprm_completion_with_error error; ! 522: } __attribute__ (( packed )); ! 523: ! 524: union hermonprm_event_entry { ! 525: struct hermonprm_event_queue_entry generic; ! 526: struct hermonprm_port_state_change_event port_state_change; ! 527: } __attribute__ (( packed )); ! 528: ! 529: union hermonprm_doorbell_register { ! 530: struct hermonprm_send_db_register send; ! 531: struct hermonprm_event_db_register event; ! 532: uint32_t dword[1]; ! 533: } __attribute__ (( packed )); ! 534: ! 535: union hermonprm_mad { ! 536: struct hermonprm_mad_ifc ifc; ! 537: union ib_mad mad; ! 538: } __attribute__ (( packed )); ! 539: ! 540: union hermonprm_set_port { ! 541: struct hermonprm_set_port_ib ib; ! 542: struct hermonprm_set_port_general_context general; ! 543: struct hermonprm_set_port_rqp_calc rqp_calc; ! 544: struct hermonprm_set_port_mac_table mac_table[128]; ! 545: struct hermonprm_set_port_vlan vlan; ! 546: } __attribute__ (( packed )); ! 547: ! 548: /* ! 549: * iPXE-specific definitions ! 550: * ! 551: */ ! 552: ! 553: /** Hermon device capabilitiess */ ! 554: struct hermon_dev_cap { ! 555: /** CMPT entry size */ ! 556: size_t cmpt_entry_size; ! 557: /** Number of reserved QPs */ ! 558: unsigned int reserved_qps; ! 559: /** QP context entry size */ ! 560: size_t qpc_entry_size; ! 561: /** Alternate path context entry size */ ! 562: size_t altc_entry_size; ! 563: /** Auxiliary context entry size */ ! 564: size_t auxc_entry_size; ! 565: /** Number of reserved SRQs */ ! 566: unsigned int reserved_srqs; ! 567: /** SRQ context entry size */ ! 568: size_t srqc_entry_size; ! 569: /** Number of reserved CQs */ ! 570: unsigned int reserved_cqs; ! 571: /** CQ context entry size */ ! 572: size_t cqc_entry_size; ! 573: /** Number of reserved EQs */ ! 574: unsigned int reserved_eqs; ! 575: /** EQ context entry size */ ! 576: size_t eqc_entry_size; ! 577: /** Number of reserved MTTs */ ! 578: unsigned int reserved_mtts; ! 579: /** MTT entry size */ ! 580: size_t mtt_entry_size; ! 581: /** Number of reserved MRWs */ ! 582: unsigned int reserved_mrws; ! 583: /** DMPT entry size */ ! 584: size_t dmpt_entry_size; ! 585: /** Number of reserved UARs */ ! 586: unsigned int reserved_uars; ! 587: /** Number of ports */ ! 588: unsigned int num_ports; ! 589: /** Dual-port different protocol */ ! 590: int dpdp; ! 591: }; ! 592: ! 593: /** Number of cMPT entries of each type */ ! 594: #define HERMON_CMPT_MAX_ENTRIES ( 1 << 24 ) ! 595: ! 596: /** Hermon ICM memory map entry */ ! 597: struct hermon_icm_map { ! 598: /** Offset (virtual address within ICM) */ ! 599: uint64_t offset; ! 600: /** Length */ ! 601: size_t len; ! 602: }; ! 603: ! 604: /** Discontiguous regions within Hermon ICM */ ! 605: enum hermon_icm_map_regions { ! 606: HERMON_ICM_QP_CMPT = 0, ! 607: HERMON_ICM_SRQ_CMPT, ! 608: HERMON_ICM_CQ_CMPT, ! 609: HERMON_ICM_EQ_CMPT, ! 610: HERMON_ICM_OTHER, ! 611: HERMON_ICM_NUM_REGIONS ! 612: }; ! 613: ! 614: /** UAR page for doorbell accesses ! 615: * ! 616: * Pages 0-127 are reserved for event queue doorbells only, so we use ! 617: * page 128. ! 618: */ ! 619: #define HERMON_UAR_NON_EQ_PAGE 128 ! 620: ! 621: /** Maximum number of allocatable MTT entries ! 622: * ! 623: * This is a policy decision, not a device limit. ! 624: */ ! 625: #define HERMON_MAX_MTTS 64 ! 626: ! 627: /** A Hermon MTT descriptor */ ! 628: struct hermon_mtt { ! 629: /** MTT offset */ ! 630: unsigned int mtt_offset; ! 631: /** Number of pages */ ! 632: unsigned int num_pages; ! 633: /** MTT base address */ ! 634: unsigned int mtt_base_addr; ! 635: /** Offset within page */ ! 636: unsigned int page_offset; ! 637: }; ! 638: ! 639: /** Alignment of Hermon send work queue entries */ ! 640: #define HERMON_SEND_WQE_ALIGN 128 ! 641: ! 642: /** A Hermon send work queue entry */ ! 643: union hermon_send_wqe { ! 644: struct hermonprm_wqe_segment_ctrl_send ctrl; ! 645: struct hermonprm_ud_send_wqe ud; ! 646: struct hermonprm_mlx_send_wqe mlx; ! 647: struct hermonprm_rc_send_wqe rc; ! 648: struct hermonprm_eth_send_wqe eth; ! 649: uint8_t force_align[HERMON_SEND_WQE_ALIGN]; ! 650: } __attribute__ (( packed )); ! 651: ! 652: /** A Hermon send work queue */ ! 653: struct hermon_send_work_queue { ! 654: /** Number of work queue entries, including headroom ! 655: * ! 656: * Hermon requires us to leave unused space within the send ! 657: * WQ, so we create a send WQ with more entries than are ! 658: * requested in the create_qp() call. ! 659: */ ! 660: unsigned int num_wqes; ! 661: /** Work queue entries */ ! 662: union hermon_send_wqe *wqe; ! 663: /** Size of work queue */ ! 664: size_t wqe_size; ! 665: /** Doorbell register */ ! 666: void *doorbell; ! 667: }; ! 668: ! 669: /** Alignment of Hermon receive work queue entries */ ! 670: #define HERMON_RECV_WQE_ALIGN 16 ! 671: ! 672: /** A Hermon receive work queue entry */ ! 673: union hermon_recv_wqe { ! 674: struct hermonprm_recv_wqe recv; ! 675: uint8_t force_align[HERMON_RECV_WQE_ALIGN]; ! 676: } __attribute__ (( packed )); ! 677: ! 678: /** A Hermon receive work queue */ ! 679: struct hermon_recv_work_queue { ! 680: /** Work queue entries */ ! 681: union hermon_recv_wqe *wqe; ! 682: /** Size of work queue */ ! 683: size_t wqe_size; ! 684: /** Doorbell record */ ! 685: struct hermonprm_qp_db_record *doorbell; ! 686: }; ! 687: ! 688: /** Number of special queue pairs */ ! 689: #define HERMON_NUM_SPECIAL_QPS 8 ! 690: ! 691: /** Number of queue pairs reserved for the "special QP" block ! 692: * ! 693: * The special QPs must be within a contiguous block aligned on its ! 694: * own size. ! 695: */ ! 696: #define HERMON_RSVD_SPECIAL_QPS ( ( HERMON_NUM_SPECIAL_QPS << 1 ) - 1 ) ! 697: ! 698: /** Maximum number of allocatable queue pairs ! 699: * ! 700: * This is a policy decision, not a device limit. ! 701: */ ! 702: #define HERMON_MAX_QPS 8 ! 703: ! 704: /** Queue pair number randomisation mask */ ! 705: #define HERMON_QPN_RANDOM_MASK 0xfff000 ! 706: ! 707: /** Hermon queue pair state */ ! 708: enum hermon_queue_pair_state { ! 709: HERMON_QP_ST_RST = 0, ! 710: HERMON_QP_ST_INIT, ! 711: HERMON_QP_ST_RTR, ! 712: HERMON_QP_ST_RTS, ! 713: }; ! 714: ! 715: /** A Hermon queue pair */ ! 716: struct hermon_queue_pair { ! 717: /** Work queue buffer */ ! 718: void *wqe; ! 719: /** Size of work queue buffer */ ! 720: size_t wqe_size; ! 721: /** MTT descriptor */ ! 722: struct hermon_mtt mtt; ! 723: /** Send work queue */ ! 724: struct hermon_send_work_queue send; ! 725: /** Receive work queue */ ! 726: struct hermon_recv_work_queue recv; ! 727: /** Queue state */ ! 728: enum hermon_queue_pair_state state; ! 729: }; ! 730: ! 731: /** Maximum number of allocatable completion queues ! 732: * ! 733: * This is a policy decision, not a device limit. ! 734: */ ! 735: #define HERMON_MAX_CQS 8 ! 736: ! 737: /** A Hermon completion queue */ ! 738: struct hermon_completion_queue { ! 739: /** Completion queue entries */ ! 740: union hermonprm_completion_entry *cqe; ! 741: /** Size of completion queue */ ! 742: size_t cqe_size; ! 743: /** MTT descriptor */ ! 744: struct hermon_mtt mtt; ! 745: /** Doorbell record */ ! 746: struct hermonprm_cq_db_record *doorbell; ! 747: }; ! 748: ! 749: /** Maximum number of allocatable event queues ! 750: * ! 751: * This is a policy decision, not a device limit. ! 752: */ ! 753: #define HERMON_MAX_EQS 8 ! 754: ! 755: /** A Hermon event queue */ ! 756: struct hermon_event_queue { ! 757: /** Event queue entries */ ! 758: union hermonprm_event_entry *eqe; ! 759: /** Size of event queue */ ! 760: size_t eqe_size; ! 761: /** MTT descriptor */ ! 762: struct hermon_mtt mtt; ! 763: /** Event queue number */ ! 764: unsigned long eqn; ! 765: /** Next event queue entry index */ ! 766: unsigned long next_idx; ! 767: /** Doorbell register */ ! 768: void *doorbell; ! 769: }; ! 770: ! 771: /** Number of event queue entries ! 772: * ! 773: * This is a policy decision. ! 774: */ ! 775: #define HERMON_NUM_EQES 8 ! 776: ! 777: /** A Hermon resource bitmask */ ! 778: typedef uint32_t hermon_bitmask_t; ! 779: ! 780: /** Size of a hermon resource bitmask */ ! 781: #define HERMON_BITMASK_SIZE(max_entries) \ ! 782: ( ( (max_entries) + ( 8 * sizeof ( hermon_bitmask_t ) ) - 1 ) / \ ! 783: ( 8 * sizeof ( hermon_bitmask_t ) ) ) ! 784: ! 785: struct hermon; ! 786: struct hermon_port; ! 787: ! 788: /** A Hermon port type */ ! 789: struct hermon_port_type { ! 790: /** Register port ! 791: * ! 792: * @v hermon Hermon device ! 793: * @v port Hermon port ! 794: * @ret rc Return status code ! 795: */ ! 796: int ( * register_dev ) ( struct hermon *hermon, ! 797: struct hermon_port *port ); ! 798: /** Port state changed ! 799: * ! 800: * @v hermon Hermon device ! 801: * @v port Hermon port ! 802: * @v link_up Link is up ! 803: */ ! 804: void ( * state_change ) ( struct hermon *hermon, ! 805: struct hermon_port *port, ! 806: int link_up ); ! 807: /** Unregister port ! 808: * ! 809: * @v hermon Hermon device ! 810: * @v port Hermon port ! 811: */ ! 812: void ( * unregister_dev ) ( struct hermon *hermon, ! 813: struct hermon_port *port ); ! 814: }; ! 815: ! 816: /** A Hermon port */ ! 817: struct hermon_port { ! 818: /** Infiniband device */ ! 819: struct ib_device *ibdev; ! 820: /** Network device */ ! 821: struct net_device *netdev; ! 822: /** Ethernet completion queue */ ! 823: struct ib_completion_queue *eth_cq; ! 824: /** Ethernet queue pair */ ! 825: struct ib_queue_pair *eth_qp; ! 826: /** Port type */ ! 827: struct hermon_port_type *type; ! 828: }; ! 829: ! 830: /** A Hermon device */ ! 831: struct hermon { ! 832: /** PCI configuration registers */ ! 833: void *config; ! 834: /** PCI user Access Region */ ! 835: void *uar; ! 836: ! 837: /** Command toggle */ ! 838: unsigned int toggle; ! 839: /** Command input mailbox */ ! 840: void *mailbox_in; ! 841: /** Command output mailbox */ ! 842: void *mailbox_out; ! 843: ! 844: /** Firmware area in external memory */ ! 845: userptr_t firmware_area; ! 846: /** ICM map */ ! 847: struct hermon_icm_map icm_map[HERMON_ICM_NUM_REGIONS]; ! 848: /** ICM area */ ! 849: userptr_t icm; ! 850: ! 851: /** Event queue */ ! 852: struct hermon_event_queue eq; ! 853: /** Unrestricted LKey ! 854: * ! 855: * Used to get unrestricted memory access. ! 856: */ ! 857: unsigned long lkey; ! 858: ! 859: /** Completion queue in-use bitmask */ ! 860: hermon_bitmask_t cq_inuse[ HERMON_BITMASK_SIZE ( HERMON_MAX_CQS ) ]; ! 861: /** Queue pair in-use bitmask */ ! 862: hermon_bitmask_t qp_inuse[ HERMON_BITMASK_SIZE ( HERMON_MAX_QPS ) ]; ! 863: /** MTT entry in-use bitmask */ ! 864: hermon_bitmask_t mtt_inuse[ HERMON_BITMASK_SIZE ( HERMON_MAX_MTTS ) ]; ! 865: ! 866: /** Device capabilities */ ! 867: struct hermon_dev_cap cap; ! 868: /** Special QPN base */ ! 869: unsigned long special_qpn_base; ! 870: /** QPN base */ ! 871: unsigned long qpn_base; ! 872: ! 873: /** Ports */ ! 874: struct hermon_port port[HERMON_MAX_PORTS]; ! 875: ! 876: /** BOFM device */ ! 877: struct bofm_device bofm; ! 878: }; ! 879: ! 880: /** Global protection domain */ ! 881: #define HERMON_GLOBAL_PD 0x123456 ! 882: ! 883: /** Memory key prefix */ ! 884: #define HERMON_MKEY_PREFIX 0x77000000UL ! 885: ! 886: /* ! 887: * HCA commands ! 888: * ! 889: */ ! 890: ! 891: #define HERMON_HCR_BASE 0x80680 ! 892: #define HERMON_HCR_REG(x) ( HERMON_HCR_BASE + 4 * (x) ) ! 893: #define HERMON_HCR_MAX_WAIT_MS 2000 ! 894: #define HERMON_MBOX_ALIGN 4096 ! 895: #define HERMON_MBOX_SIZE 1024 ! 896: ! 897: /* HCA command is split into ! 898: * ! 899: * bits 11:0 Opcode ! 900: * bit 12 Input uses mailbox ! 901: * bit 13 Output uses mailbox ! 902: * bits 22:14 Input parameter length (in dwords) ! 903: * bits 31:23 Output parameter length (in dwords) ! 904: * ! 905: * Encoding the information in this way allows us to cut out several ! 906: * parameters to the hermon_command() call. ! 907: */ ! 908: #define HERMON_HCR_IN_MBOX 0x00001000UL ! 909: #define HERMON_HCR_OUT_MBOX 0x00002000UL ! 910: #define HERMON_HCR_OPCODE( _command ) ( (_command) & 0xfff ) ! 911: #define HERMON_HCR_IN_LEN( _command ) ( ( (_command) >> 12 ) & 0x7fc ) ! 912: #define HERMON_HCR_OUT_LEN( _command ) ( ( (_command) >> 21 ) & 0x7fc ) ! 913: ! 914: /** Build HCR command from component parts */ ! 915: #define HERMON_HCR_INOUT_CMD( _opcode, _in_mbox, _in_len, \ ! 916: _out_mbox, _out_len ) \ ! 917: ( (_opcode) | \ ! 918: ( (_in_mbox) ? HERMON_HCR_IN_MBOX : 0 ) | \ ! 919: ( ( (_in_len) / 4 ) << 14 ) | \ ! 920: ( (_out_mbox) ? HERMON_HCR_OUT_MBOX : 0 ) | \ ! 921: ( ( (_out_len) / 4 ) << 23 ) ) ! 922: ! 923: #define HERMON_HCR_IN_CMD( _opcode, _in_mbox, _in_len ) \ ! 924: HERMON_HCR_INOUT_CMD ( _opcode, _in_mbox, _in_len, 0, 0 ) ! 925: ! 926: #define HERMON_HCR_OUT_CMD( _opcode, _out_mbox, _out_len ) \ ! 927: HERMON_HCR_INOUT_CMD ( _opcode, 0, 0, _out_mbox, _out_len ) ! 928: ! 929: #define HERMON_HCR_VOID_CMD( _opcode ) \ ! 930: HERMON_HCR_INOUT_CMD ( _opcode, 0, 0, 0, 0 ) ! 931: ! 932: #endif /* _HERMON_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.