@@ -16,6 +16,7 @@ man_MANS = man/umad_debug.3 man/umad_get_ca.3 \
man/umad_set_addr_net.3 man/umad_set_addr.3 man/umad_set_pkey.3 \
man/umad_get_pkey.3 \
man/umad_register.3 man/umad_register_oui.3 man/umad_unregister.3 \
+ man/umad_register2.3 \
man/umad_send.3 man/umad_recv.3 man/umad_poll.3 \
man/umad_get_issm_path.3 \
man/umad_attribute_str.3 \
@@ -90,6 +90,8 @@ typedef struct ib_user_mad {
struct ib_user_mad_reg_req)
#define IB_USER_MAD_UNREGISTER_AGENT _IOW(IB_IOCTL_MAGIC, 2, uint32_t)
#define IB_USER_MAD_ENABLE_PKEY _IO(IB_IOCTL_MAGIC, 3)
+#define IB_USER_MAD_REGISTER_AGENT2 _IOWR(IB_IOCTL_MAGIC, 4, \
+ struct ib_user_mad_reg_req2)
#define UMAD_CA_NAME_LEN 20
#define UMAD_CA_MAX_PORTS 10 /* 0 - 9 */
@@ -196,6 +198,23 @@ int umad_register_oui(int portid, int mgmt_class, uint8_t rmpp_version,
uint8_t oui[3], long method_mask[16 / sizeof(long)]);
int umad_unregister(int portid, int agentid);
+enum {
+ UMAD_USER_RMPP = (1 << 0)
+} umad_reg_flags;
+#define UMAD_REG_STRUCT_V1 0
+struct umad_reg_attr {
+ uint16_t struct_version;
+ uint8_t mgmt_class;
+ uint8_t mgmt_class_version;
+ uint32_t flags;
+ uint64_t method_mask[2];
+ uint8_t oui[3]; /* network order */
+ uint8_t rmpp_version;
+};
+int umad_register2(int port_fd, struct umad_reg_attr *attr,
+ uint32_t *agent_id);
+
+
int umad_debug(int level);
void umad_addr_dump(ib_mad_addr_t * addr);
void umad_dump(void *umad);
new file mode 100644
@@ -0,0 +1,77 @@
+.\" -*- nroff -*-
+.\"
+.TH UMAD_REGISTER2 3 "March 25, 2014" "OpenIB" "OpenIB Programmer\'s Manual"
+.SH "NAME"
+umad_register2 \- register the specified management class and version for port
+.SH "SYNOPSIS"
+.nf
+.B #include <infiniband/umad.h>
+.sp
+.BI "int umad_register2(int " "port_fd" ", struct umad_reg_attr *" "attr" ", uint32_t *" "agent_id");
+.fi
+.SH "DESCRIPTION"
+.B umad_register2()
+registers for a MAD agent using the provided registration attributes
+
+.I port_fd\fR
+the port on which to register the agent
+
+.I attr\fR
+The registration attributes as defined by the structure passed. See below for
+details of this structure. Future structures may be defined.
+
+.I agent_id\fR
+returned on success.
+
+
+.SH "REGISTRATION ATTRIBUTE STRUCTURE VERSION 0"
+.nf
+struct umad_reg_attr {
+.in +8
+uint16_t struct_version;
+uint8_t mgmt_class;
+uint8_t mgmt_class_version;
+uint32_t flags;
+uint64_t method_mask[2];
+uint8_t oui[3]; /* network order */
+uint8_t rmpp_version;
+.in -8
+};
+
+.I struct_version\fR
+Version of the attribute structure being passed. Set to '0'
+
+.I mgmt_class\fR
+Management class to register for.
+
+.I mgmt_class_version\fR
+Management class version to register for.
+
+.I flags\fR
+Registration flags. If a flag specified is not supported by the kernel, the supported flags are returned in this field.
+
+.P
+Current flags are.
+.in +8
+UMAD_USER_RMPP -- flag to indicate the kernel should not process RMPP packets. All RMPP packets will be treated like individual MAD's. The user is responsible for implementing the RMPP protocol.
+.in -8
+
+.I method_mask\fR
+A bit mask which indicates which unsolicited methods this agent should receive. Setting this array to 0 will result in the agent only receiving response MAD's for which a request was sent.
+
+.I oui\fR
+The oui to use for vendor classes 0x30 - 0x4f. Otherwise ignored.
+
+.I rmpp_version\fR
+If the class supports RMPP and kernel RMPP is enabled (the default) indicate which rmpp_version to use.
+
+
+.SH "RETURN VALUE"
+.B umad_register2()
+returns 0 on success and +ERRNO on failure.
+
+.SH "SEE ALSO"
+.BR umad_unregister (3)
+.SH "AUTHOR"
+.TP
+Ira Weiny <ira.weiny@intel.com>
@@ -23,6 +23,7 @@ IBUMAD_1.0 {
umad_poll;
umad_get_fd;
umad_register;
+ umad_register2;
umad_register_oui;
umad_unregister;
umad_status;
@@ -47,6 +47,7 @@
#include <netinet/in.h>
#include <dirent.h>
#include <ctype.h>
+#include <inttypes.h>
#include "umad.h"
@@ -76,6 +77,18 @@ typedef struct ib_user_mad_reg_req {
uint8_t rmpp_version;
} ib_user_mad_reg_req_t;
+struct ib_user_mad_reg_req2 {
+ uint32_t id;
+ uint32_t qpn;
+ uint8_t mgmt_class;
+ uint8_t mgmt_class_version;
+ uint16_t res;
+ uint32_t flags;
+ uint64_t method_mask[2];
+ uint8_t oui[3]; /* network order */
+ uint8_t rmpp_version;
+};
+
extern int sys_read_string(const char *dir_name, const char *file_name, char *str, int len);
extern int sys_read_guid(const char *dir_name, const char *file_name, uint64_t * net_guid);
extern int sys_read_gid(const char *dir_name, const char *file_name, uint8_t * gid);
@@ -973,6 +986,70 @@ int umad_register(int fd, int mgmt_class, int mgmt_version,
return -EPERM;
}
+int umad_register2(int port_fd, struct umad_reg_attr *attr, uint32_t *agent_id)
+{
+ struct ib_user_mad_reg_req2 req;
+ int rc;
+
+ if (!attr || !agent_id)
+ return EINVAL;
+
+ if (attr->struct_version != UMAD_REG_STRUCT_V1) {
+ DEBUG("struct_version %d invalid max supported %d\n",
+ attr->struct_version, UMAD_REG_STRUCT_V1);
+ return EINVAL;
+ }
+
+ TRACE("fd %d mgmt_class %u mgmt_class_version %u rmpp_version %d "
+ "oui 0x%02x%02x%02x method_mask 0x%016"PRIx64" %016"PRIx64"\n",
+ port_fd, attr->mgmt_class, attr->mgmt_class_version,
+ (int)attr->rmpp_version,
+ attr->oui[0], attr->oui[1], attr->oui[2],
+ attr->method_mask[1], attr->method_mask[0]);
+
+ if (attr->mgmt_class >= 0x30 && attr->mgmt_class <= 0x4f) {
+ if (attr->oui[0] == 0 && attr->oui[1] == 0
+ && attr->oui[2] == 0) {
+ DEBUG("mgmt class %d is in vendor range 2 but no "
+ "oui specified", attr->mgmt_class);
+ return EINVAL;
+ }
+ }
+
+ memset(&req, 0, sizeof (req));
+
+ req.mgmt_class = attr->mgmt_class;
+ req.mgmt_class_version = attr->mgmt_class_version;
+ req.qpn = (attr->mgmt_class == 0x1 || attr->mgmt_class == 0x81) ? 0 : 1;
+ req.flags = attr->flags;
+ memcpy(req.method_mask, attr->method_mask, sizeof req.method_mask);
+ memcpy(req.oui, attr->oui, sizeof req.oui);
+ req.rmpp_version = attr->rmpp_version;
+
+ VALGRIND_MAKE_MEM_DEFINED(&req, sizeof req);
+
+ if ((rc = ioctl(port_fd, IB_USER_MAD_REGISTER_AGENT2, (void *)&req))
+ == 0) {
+ DEBUG
+ ("fd %d registered to use agent %d qp %d class 0x%x "
+ "oui 0x%02x%02x%02x",
+ port_fd, req.id, req.qpn, req.mgmt_class,
+ attr->oui[0], attr->oui[1], attr->oui[2]);
+ *agent_id = req.id;
+ return 0;
+ }
+ rc = errno;
+
+ attr->flags = req.flags;
+
+ DEBUG("fd %d registering qp %d class 0x%x version %d "
+ "oui 0x%02x%02x%02x failed flags returned 0x%x : %m",
+ port_fd, req.qpn, req.mgmt_class, req.mgmt_class_version,
+ attr->oui[0], attr->oui[1], attr->oui[2],
+ req.flags);
+ return rc;
+}
+
int umad_unregister(int fd, int agentid)
{
TRACE("fd %d unregistering agent %d", fd, agentid);