| /* | |
| * Copyright (c) 2005 Topspin Communications. All rights reserved. | |
| * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. | |
| * Copyright (c) 2005 PathScale, Inc. All rights reserved. | |
| * | |
| * This software is available to you under a choice of one of two | |
| * licenses. You may choose to be licensed under the terms of the GNU | |
| * General Public License (GPL) Version 2, available from the file | |
| * COPYING in the main directory of this source tree, or the | |
| * OpenIB.org BSD license below: | |
| * | |
| * Redistribution and use in source and binary forms, with or | |
| * without modification, are permitted provided that the following | |
| * conditions are met: | |
| * | |
| * - Redistributions of source code must retain the above | |
| * copyright notice, this list of conditions and the following | |
| * disclaimer. | |
| * | |
| * - Redistributions in binary form must reproduce the above | |
| * copyright notice, this list of conditions and the following | |
| * disclaimer in the documentation and/or other materials | |
| * provided with the distribution. | |
| * | |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| * SOFTWARE. | |
| */ | |
| #ifndef KERN_ABI_H | |
| #define KERN_ABI_H | |
| #include <linux/types.h> | |
| #include <assert.h> | |
| #include <ccan/container_of.h> | |
| #include <rdma/ib_user_verbs.h> | |
| #include <kernel-abi/ib_user_verbs.h> | |
| /* | |
| * The minimum and maximum kernel ABI that we can handle. | |
| */ | |
| #define IB_USER_VERBS_MIN_ABI_VERSION 3 | |
| #define IB_USER_VERBS_MAX_ABI_VERSION 6 | |
| struct ex_hdr { | |
| struct ib_uverbs_cmd_hdr hdr; | |
| struct ib_uverbs_ex_cmd_hdr ex_hdr; | |
| }; | |
| /* | |
| * These macros expand to type names that refer to the ABI structure type | |
| * associated with the given enum string. | |
| */ | |
| #define IBV_ABI_REQ(_enum) _ABI_REQ_STRUCT_##_enum | |
| #define IBV_KABI_REQ(_enum) _KABI_REQ_STRUCT_##_enum | |
| #define IBV_KABI_RESP(_enum) _KABI_RESP_STRUCT_##_enum | |
| #define IBV_ABI_ALIGN(_enum) _ABI_ALIGN_##_enum | |
| /* | |
| * Historically the code had copied the data in the kernel headers, modified | |
| * it and placed them in structs. To avoid recoding eveything we continue to | |
| * preserve the same struct layout, with the kernel struct 'loose' inside the | |
| * modified userspace struct. | |
| * | |
| * This is automated with the make_abi_structs.py script which produces the | |
| * _STRUCT_xx macro that produces a tagless version of the kernel struct. The | |
| * tagless struct produces a layout that matches the original code. | |
| */ | |
| #define DECLARE_CMDX(_enum, _name, _kabi, _kabi_resp) \ | |
| struct _name { \ | |
| struct ib_uverbs_cmd_hdr hdr; \ | |
| union { \ | |
| _STRUCT_##_kabi; \ | |
| struct _kabi core_payload; \ | |
| }; \ | |
| }; \ | |
| typedef struct _name IBV_ABI_REQ(_enum); \ | |
| typedef struct _kabi IBV_KABI_REQ(_enum); \ | |
| typedef struct _kabi_resp IBV_KABI_RESP(_enum); \ | |
| enum { IBV_ABI_ALIGN(_enum) = 4 }; \ | |
| static_assert(sizeof(struct _kabi_resp) % 4 == 0, \ | |
| "Bad resp alignment"); \ | |
| static_assert(_enum != -1, "Bad enum"); \ | |
| static_assert(sizeof(struct _name) == \ | |
| sizeof(struct ib_uverbs_cmd_hdr) + \ | |
| sizeof(struct _kabi), \ | |
| "Bad size") | |
| #define DECLARE_CMD(_enum, _name, _kabi) \ | |
| DECLARE_CMDX(_enum, _name, _kabi, _kabi##_resp) | |
| #define DECLARE_CMD_EXX(_enum, _name, _kabi, _kabi_resp) \ | |
| struct _name { \ | |
| struct ex_hdr hdr; \ | |
| union { \ | |
| _STRUCT_##_kabi; \ | |
| struct _kabi core_payload; \ | |
| }; \ | |
| }; \ | |
| typedef struct _name IBV_ABI_REQ(_enum); \ | |
| typedef struct _kabi IBV_KABI_REQ(_enum); \ | |
| typedef struct _kabi_resp IBV_KABI_RESP(_enum); \ | |
| enum { IBV_ABI_ALIGN(_enum) = 8 }; \ | |
| static_assert(_enum != -1, "Bad enum"); \ | |
| static_assert(sizeof(struct _kabi) % 8 == 0, "Bad req alignment"); \ | |
| static_assert(sizeof(struct _kabi_resp) % 8 == 0, \ | |
| "Bad resp alignment"); \ | |
| static_assert(sizeof(struct _name) == \ | |
| sizeof(struct ex_hdr) + sizeof(struct _kabi), \ | |
| "Bad size"); \ | |
| static_assert(sizeof(struct _name) % 8 == 0, "Bad alignment") | |
| #define DECLARE_CMD_EX(_enum, _name, _kabi) \ | |
| DECLARE_CMD_EXX(_enum, _name, _kabi, _kabi##_resp) | |
| /* Drivers may use 'empty' for _kabi to signal no struct */ | |
| struct empty {}; | |
| #define _STRUCT_empty struct {} | |
| /* | |
| * Define the ABI struct for use by the driver. The internal cmd APIs require | |
| * this layout. The driver specifies the enum # they wish to define for and | |
| * the base name, and the macros figure out the rest correctly. | |
| * | |
| * The static asserts check that the layout produced by the wrapper struct has | |
| * no implicit padding in strange places, specifically between the core | |
| * structure and the driver structure and between the driver structure and the | |
| * end of the struct. | |
| * | |
| * Implicit padding can arise in various cases where the structs are not sizes | |
| * to a multiple of 8 bytes. | |
| */ | |
| #define DECLARE_DRV_CMD(_name, _enum, _kabi_req, _kabi_resp) \ | |
| struct _name { \ | |
| IBV_ABI_REQ(_enum) ibv_cmd; \ | |
| union { \ | |
| _STRUCT_##_kabi_req; \ | |
| struct _kabi_req drv_payload; \ | |
| }; \ | |
| }; \ | |
| struct _name##_resp { \ | |
| IBV_KABI_RESP(_enum) ibv_resp; \ | |
| union { \ | |
| _STRUCT_##_kabi_resp; \ | |
| struct _kabi_resp drv_payload; \ | |
| }; \ | |
| }; \ | |
| static_assert(sizeof(IBV_KABI_REQ(_enum)) % \ | |
| __alignof__(struct _kabi_req) == \ | |
| 0, \ | |
| "Bad kabi req struct length"); \ | |
| static_assert(sizeof(struct _name) == \ | |
| sizeof(IBV_ABI_REQ(_enum)) + \ | |
| sizeof(struct _kabi_req), \ | |
| "Bad req size"); \ | |
| static_assert(sizeof(struct _name) % IBV_ABI_ALIGN(_enum) == 0, \ | |
| "Bad kabi req alignment"); \ | |
| static_assert(sizeof(IBV_KABI_RESP(_enum)) % \ | |
| __alignof__(struct _kabi_resp) == \ | |
| 0, \ | |
| "Bad kabi resp struct length"); \ | |
| static_assert(sizeof(struct _name##_resp) == \ | |
| sizeof(IBV_KABI_RESP(_enum)) + \ | |
| sizeof(struct _kabi_resp), \ | |
| "Bad resp size"); \ | |
| static_assert(sizeof(struct _name##_resp) % IBV_ABI_ALIGN(_enum) == 0, \ | |
| "Bad kabi resp alignment"); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_ALLOC_MW, ibv_alloc_mw, ib_uverbs_alloc_mw); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_ALLOC_PD, ibv_alloc_pd, ib_uverbs_alloc_pd); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_ATTACH_MCAST, ibv_attach_mcast, ib_uverbs_attach_mcast, empty); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_CLOSE_XRCD, ibv_close_xrcd, ib_uverbs_close_xrcd, empty); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_AH, ibv_create_ah, ib_uverbs_create_ah); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL, ibv_create_comp_channel, ib_uverbs_create_comp_channel); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_CQ, ibv_create_cq, ib_uverbs_create_cq); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_QP, ibv_create_qp, ib_uverbs_create_qp); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_CREATE_SRQ, ibv_create_srq, ib_uverbs_create_srq); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_XSRQ, ibv_create_xsrq, ib_uverbs_create_xsrq, ib_uverbs_create_srq_resp); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_DEALLOC_MW, ibv_dealloc_mw, ib_uverbs_dealloc_mw, empty); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_DEALLOC_PD, ibv_dealloc_pd, ib_uverbs_dealloc_pd, empty); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_DEREG_MR, ibv_dereg_mr, ib_uverbs_dereg_mr, empty); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_DESTROY_AH, ibv_destroy_ah, ib_uverbs_destroy_ah, empty); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_DESTROY_CQ, ibv_destroy_cq, ib_uverbs_destroy_cq); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_DESTROY_QP, ibv_destroy_qp, ib_uverbs_destroy_qp); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_DESTROY_SRQ, ibv_destroy_srq, ib_uverbs_destroy_srq); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_DETACH_MCAST, ibv_detach_mcast, ib_uverbs_detach_mcast, empty); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_GET_CONTEXT, ibv_get_context, ib_uverbs_get_context); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_MODIFY_QP, ibv_modify_qp, ib_uverbs_modify_qp, empty); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_MODIFY_SRQ, ibv_modify_srq, ib_uverbs_modify_srq, empty); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_OPEN_QP, ibv_open_qp, ib_uverbs_open_qp, ib_uverbs_create_qp_resp); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_OPEN_XRCD, ibv_open_xrcd, ib_uverbs_open_xrcd); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_POLL_CQ, ibv_poll_cq, ib_uverbs_poll_cq); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_POST_RECV, ibv_post_recv, ib_uverbs_post_recv); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_POST_SEND, ibv_post_send, ib_uverbs_post_send); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_POST_SRQ_RECV, ibv_post_srq_recv, ib_uverbs_post_srq_recv); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_DEVICE, ibv_query_device, ib_uverbs_query_device); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_PORT, ibv_query_port, ib_uverbs_query_port); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_QP, ibv_query_qp, ib_uverbs_query_qp); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_QUERY_SRQ, ibv_query_srq, ib_uverbs_query_srq); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_REG_MR, ibv_reg_mr, ib_uverbs_reg_mr); | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_REQ_NOTIFY_CQ, ibv_req_notify_cq, ib_uverbs_req_notify_cq, empty); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_REREG_MR, ibv_rereg_mr, ib_uverbs_rereg_mr); | |
| DECLARE_CMD(IB_USER_VERBS_CMD_RESIZE_CQ, ibv_resize_cq, ib_uverbs_resize_cq); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_CQ, ibv_create_cq_ex, ib_uverbs_ex_create_cq); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_FLOW, ibv_create_flow, ib_uverbs_create_flow); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_QP, ibv_create_qp_ex, ib_uverbs_ex_create_qp); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL, ibv_create_rwq_ind_table, ib_uverbs_ex_create_rwq_ind_table); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_CREATE_WQ, ibv_create_wq, ib_uverbs_ex_create_wq); | |
| DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_DESTROY_FLOW, ibv_destroy_flow, ib_uverbs_destroy_flow, empty); | |
| DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL, ibv_destroy_rwq_ind_table, ib_uverbs_ex_destroy_rwq_ind_table, empty); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_DESTROY_WQ, ibv_destroy_wq, ib_uverbs_ex_destroy_wq); | |
| DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_MODIFY_CQ, ibv_modify_cq, ib_uverbs_ex_modify_cq, empty); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_MODIFY_QP, ibv_modify_qp_ex, ib_uverbs_ex_modify_qp); | |
| DECLARE_CMD_EXX(IB_USER_VERBS_EX_CMD_MODIFY_WQ, ibv_modify_wq, ib_uverbs_ex_modify_wq, empty); | |
| DECLARE_CMD_EX(IB_USER_VERBS_EX_CMD_QUERY_DEVICE, ibv_query_device_ex, ib_uverbs_ex_query_device); | |
| /* | |
| * Both ib_uverbs_create_qp and ib_uverbs_ex_create_qp start with the same | |
| * structure, this function converts the ex version into the normal version | |
| */ | |
| static inline struct ib_uverbs_create_qp * | |
| ibv_create_qp_ex_to_reg(struct ibv_create_qp_ex *cmd_ex) | |
| { | |
| /* | |
| * user_handle is the start in both places, note that the ex | |
| * does not have response located in the same place, so response | |
| * cannot be touched. | |
| */ | |
| return container_of(&cmd_ex->user_handle, struct ib_uverbs_create_qp, | |
| user_handle); | |
| } | |
| /* | |
| * This file contains copied data from the kernel's include/uapi/rdma/ib_user_verbs.h, | |
| * now included above. | |
| * | |
| * Whenever possible use the definition from the kernel header and avoid | |
| * copying from that header into this file. | |
| */ | |
| struct ibv_kern_ipv4_filter { | |
| __u32 src_ip; | |
| __u32 dst_ip; | |
| }; | |
| struct ibv_kern_spec_ipv4 { | |
| __u32 type; | |
| __u16 size; | |
| __u16 reserved; | |
| struct ibv_kern_ipv4_filter val; | |
| struct ibv_kern_ipv4_filter mask; | |
| }; | |
| struct ibv_kern_spec { | |
| union { | |
| struct ib_uverbs_flow_spec_hdr hdr; | |
| struct ib_uverbs_flow_spec_eth eth; | |
| struct ibv_kern_spec_ipv4 ipv4; | |
| struct ib_uverbs_flow_spec_ipv4 ipv4_ext; | |
| struct ib_uverbs_flow_spec_esp esp; | |
| struct ib_uverbs_flow_spec_tcp_udp tcp_udp; | |
| struct ib_uverbs_flow_spec_ipv6 ipv6; | |
| struct ib_uverbs_flow_spec_gre gre; | |
| struct ib_uverbs_flow_spec_tunnel tunnel; | |
| struct ib_uverbs_flow_spec_mpls mpls; | |
| struct ib_uverbs_flow_spec_action_tag flow_tag; | |
| struct ib_uverbs_flow_spec_action_drop drop; | |
| struct ib_uverbs_flow_spec_action_handle handle; | |
| struct ib_uverbs_flow_spec_action_count flow_count; | |
| }; | |
| }; | |
| struct ib_uverbs_modify_srq_v3 { | |
| __u32 srq_handle; | |
| __u32 attr_mask; | |
| __u32 max_wr; | |
| __u32 max_sge; | |
| __u32 srq_limit; | |
| __u32 reserved; | |
| }; | |
| #define _STRUCT_ib_uverbs_modify_srq_v3 | |
| enum { IB_USER_VERBS_CMD_MODIFY_SRQ_V3 = IB_USER_VERBS_CMD_MODIFY_SRQ }; | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_MODIFY_SRQ_V3, ibv_modify_srq_v3, ib_uverbs_modify_srq_v3, empty); | |
| struct ibv_create_qp_resp_v3 { | |
| __u32 qp_handle; | |
| __u32 qpn; | |
| }; | |
| struct ibv_create_qp_resp_v4 { | |
| __u32 qp_handle; | |
| __u32 qpn; | |
| __u32 max_send_wr; | |
| __u32 max_recv_wr; | |
| __u32 max_send_sge; | |
| __u32 max_recv_sge; | |
| __u32 max_inline_data; | |
| }; | |
| struct ibv_create_srq_resp_v5 { | |
| __u32 srq_handle; | |
| }; | |
| #define _STRUCT_ib_uverbs_create_srq_v5 | |
| enum { IB_USER_VERBS_CMD_CREATE_SRQ_V5 = IB_USER_VERBS_CMD_CREATE_SRQ }; | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_SRQ_V5, ibv_create_srq_v5, ib_uverbs_create_srq, ibv_create_srq_resp_v5); | |
| #define _STRUCT_ib_uverbs_create_qp_v4 | |
| enum { IB_USER_VERBS_CMD_CREATE_QP_V4 = IB_USER_VERBS_CMD_CREATE_QP }; | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_QP_V4, ibv_create_qp_v4, ib_uverbs_create_qp, ibv_create_qp_resp_v4); | |
| #define _STRUCT_ib_uverbs_create_qp_v3 | |
| enum { IB_USER_VERBS_CMD_CREATE_QP_V3 = IB_USER_VERBS_CMD_CREATE_QP }; | |
| DECLARE_CMDX(IB_USER_VERBS_CMD_CREATE_QP_V3, ibv_create_qp_v3, ib_uverbs_create_qp, ibv_create_qp_resp_v3); | |
| #endif /* KERN_ABI_H */ |