Message ID | 1461070287-13469-3-git-send-email-erezsh@mellanox.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On 4/19/2016 8:51 AM, Erez Shitrit wrote: > New sa query function to return the ClassPortInfo struct from the sa. > If the SM supports FullMemberSendOnly mode for MCG's, it sets a > capability bit in the capability_mask2 field of the response. > > Signed-off-by: Erez Shitrit <erezsh@mellanox.com> > Reviewed-by: Leon Romanovsky <leonro@mellanox.com> > --- > drivers/infiniband/core/sa_query.c | 174 +++++++++++++++++++++++++++++++++++++ > include/rdma/ib_sa.h | 12 +++ > 2 files changed, 186 insertions(+) > > diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c > index 8a09c0f..66535bf 100644 > --- a/drivers/infiniband/core/sa_query.c > +++ b/drivers/infiniband/core/sa_query.c > @@ -119,6 +119,12 @@ struct ib_sa_guidinfo_query { > struct ib_sa_query sa_query; > }; > > +struct ib_sa_classport_info_query { > + void (*callback)(int, struct ib_class_port_info *, void *); > + void *context; > + struct ib_sa_query sa_query; > +}; > + > struct ib_sa_mcmember_query { > void (*callback)(int, struct ib_sa_mcmember_rec *, void *); > void *context; > @@ -392,6 +398,83 @@ static const struct ib_field service_rec_table[] = { > .size_bits = 2*64 }, > }; > > +#define PORTCLASSINFO_REC_FIELD(field) \ Would CLASSPORTINFO_REC_FIELD be more consistent in terms of naming ? > + .struct_offset_bytes = offsetof(struct ib_class_port_info, field), \ > + .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \ > + .field_name = "ib_class_port_info:" #field > + > +static const struct ib_field classport_info_rec_table[] = { > + { PORTCLASSINFO_REC_FIELD(base_version), > + .offset_words = 0, > + .offset_bits = 0, > + .size_bits = 8 }, > + { PORTCLASSINFO_REC_FIELD(class_version), > + .offset_words = 0, > + .offset_bits = 8, > + .size_bits = 8 }, > + { PORTCLASSINFO_REC_FIELD(capability_mask), > + .offset_words = 0, > + .offset_bits = 16, > + .size_bits = 16 }, > + { PORTCLASSINFO_REC_FIELD(cap_mask2_resp_time), > + .offset_words = 1, > + .offset_bits = 0, > + .size_bits = 32 }, Why combine fields ? Syntax is rich enough to deal with bit fields. This is what was done for other SA attributes in this file. -- Hal > + { PORTCLASSINFO_REC_FIELD(redirect_gid), > + .offset_words = 2, > + .offset_bits = 0, > + .size_bits = 128 }, > + { PORTCLASSINFO_REC_FIELD(redirect_tcslfl), > + .offset_words = 6, > + .offset_bits = 0, > + .size_bits = 32 }, > + > + { PORTCLASSINFO_REC_FIELD(redirect_lid), > + .offset_words = 7, > + .offset_bits = 0, > + .size_bits = 16 }, > + { PORTCLASSINFO_REC_FIELD(redirect_pkey), > + .offset_words = 7, > + .offset_bits = 16, > + .size_bits = 16 }, > + > + { PORTCLASSINFO_REC_FIELD(redirect_qp), > + .offset_words = 8, > + .offset_bits = 0, > + .size_bits = 32 }, > + { PORTCLASSINFO_REC_FIELD(redirect_qkey), > + .offset_words = 9, > + .offset_bits = 0, > + .size_bits = 32 }, > + > + { PORTCLASSINFO_REC_FIELD(trap_gid), > + .offset_words = 10, > + .offset_bits = 0, > + .size_bits = 128 }, > + { PORTCLASSINFO_REC_FIELD(trap_tcslfl), > + .offset_words = 14, > + .offset_bits = 0, > + .size_bits = 32 }, > + > + { PORTCLASSINFO_REC_FIELD(trap_lid), > + .offset_words = 15, > + .offset_bits = 0, > + .size_bits = 16 }, > + { PORTCLASSINFO_REC_FIELD(trap_pkey), > + .offset_words = 15, > + .offset_bits = 16, > + .size_bits = 16 }, > + > + { PORTCLASSINFO_REC_FIELD(trap_hlqp), > + .offset_words = 16, > + .offset_bits = 0, > + .size_bits = 32 }, > + { PORTCLASSINFO_REC_FIELD(trap_qkey), > + .offset_words = 17, > + .offset_bits = 0, > + .size_bits = 32 }, > +}; > + > #define GUIDINFO_REC_FIELD(field) \ > .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \ > .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \ > @@ -1645,6 +1728,97 @@ err1: > } > EXPORT_SYMBOL(ib_sa_guid_info_rec_query); > > +/* Support get SA ClassPortInfo */ > +static void ib_sa_classport_info_rec_callback(struct ib_sa_query *sa_query, > + int status, > + struct ib_sa_mad *mad) > +{ > + struct ib_sa_classport_info_query *query = > + container_of(sa_query, struct ib_sa_classport_info_query, sa_query); > + > + if (mad) { > + struct ib_class_port_info rec; > + > + ib_unpack(classport_info_rec_table, > + ARRAY_SIZE(classport_info_rec_table), > + mad->data, &rec); > + query->callback(status, &rec, query->context); > + } else { > + query->callback(status, NULL, query->context); > + } > +} > + > +static void ib_sa_portclass_info_rec_release(struct ib_sa_query *sa_query) > +{ > + kfree(container_of(sa_query, struct ib_sa_classport_info_query, > + sa_query)); > +} > + > +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, > + struct ib_device *device, u8 port_num, > + int timeout_ms, gfp_t gfp_mask, > + void (*callback)(int status, > + struct ib_class_port_info *resp, > + void *context), > + void *context, > + struct ib_sa_query **sa_query) > +{ > + struct ib_sa_classport_info_query *query; > + struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); > + struct ib_sa_port *port; > + struct ib_mad_agent *agent; > + struct ib_sa_mad *mad; > + int ret; > + > + if (!sa_dev) > + return -ENODEV; > + > + port = &sa_dev->port[port_num - sa_dev->start_port]; > + agent = port->agent; > + > + query = kzalloc(sizeof(*query), gfp_mask); > + if (!query) > + return -ENOMEM; > + > + query->sa_query.port = port; > + ret = alloc_mad(&query->sa_query, gfp_mask); > + if (ret) > + goto err1; > + > + ib_sa_client_get(client); > + query->sa_query.client = client; > + query->callback = callback; > + query->context = context; > + > + mad = query->sa_query.mad_buf->mad; > + init_mad(mad, agent); > + > + query->sa_query.callback = callback ? ib_sa_classport_info_rec_callback : NULL; > + > + query->sa_query.release = ib_sa_portclass_info_rec_release; > + /* support GET only */ > + mad->mad_hdr.method = IB_MGMT_METHOD_GET; > + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_CLASS_PORTINFO); > + mad->sa_hdr.comp_mask = 0; > + *sa_query = &query->sa_query; > + > + ret = send_mad(&query->sa_query, timeout_ms, gfp_mask); > + if (ret < 0) > + goto err2; > + > + return ret; > + > +err2: > + *sa_query = NULL; > + ib_sa_client_put(query->sa_query.client); > + free_mad(&query->sa_query); > + > +err1: > + kfree(query); > + return ret; > +} > +EXPORT_SYMBOL(ib_sa_classport_info_rec_query); > + > static void send_handler(struct ib_mad_agent *agent, > struct ib_mad_send_wc *mad_send_wc) > { > diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h > index cdc1c81..3840416 100644 > --- a/include/rdma/ib_sa.h > +++ b/include/rdma/ib_sa.h > @@ -94,6 +94,8 @@ enum ib_sa_selector { > IB_SA_BEST = 3 > }; > > +#define IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT BIT(12) > + > /* > * Structures for SA records are named "struct ib_sa_xxx_rec." No > * attempt is made to pack structures to match the physical layout of > @@ -439,4 +441,14 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client, > void *context, > struct ib_sa_query **sa_query); > > +/* Support get SA ClassPortInfo */ > +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, > + struct ib_device *device, u8 port_num, > + int timeout_ms, gfp_t gfp_mask, > + void (*callback)(int status, > + struct ib_class_port_info *resp, > + void *context), > + void *context, > + struct ib_sa_query **sa_query); > + > #endif /* IB_SA_H */ > -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Apr 19, 2016 at 3:51 PM, Erez Shitrit <erezsh@mellanox.com> wrote: > > New sa query function to return the ClassPortInfo struct from the sa. sa --> SA in all your change-logs, please and in the subject it's the SA agent not the SA your are patching here, reflect that -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Apr 20, 2016 at 4:12 PM, Or Gerlitz <gerlitz.or@gmail.com> wrote: > On Tue, Apr 19, 2016 at 3:51 PM, Erez Shitrit <erezsh@mellanox.com> wrote: >> >> New sa query function to return the ClassPortInfo struct from the sa. > > sa --> SA in all your change-logs, please > > and in the subject it's the SA agent not the SA your are patching > here, reflect that Ack > -- > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Apr 20, 2016 at 3:09 PM, Hal Rosenstock <hal@dev.mellanox.co.il> wrote: > On 4/19/2016 8:51 AM, Erez Shitrit wrote: >> New sa query function to return the ClassPortInfo struct from the sa. >> If the SM supports FullMemberSendOnly mode for MCG's, it sets a >> capability bit in the capability_mask2 field of the response. >> >> Signed-off-by: Erez Shitrit <erezsh@mellanox.com> >> Reviewed-by: Leon Romanovsky <leonro@mellanox.com> >> --- >> drivers/infiniband/core/sa_query.c | 174 +++++++++++++++++++++++++++++++++++++ >> include/rdma/ib_sa.h | 12 +++ >> 2 files changed, 186 insertions(+) >> >> diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c >> index 8a09c0f..66535bf 100644 >> --- a/drivers/infiniband/core/sa_query.c >> +++ b/drivers/infiniband/core/sa_query.c >> @@ -119,6 +119,12 @@ struct ib_sa_guidinfo_query { >> struct ib_sa_query sa_query; >> }; >> >> +struct ib_sa_classport_info_query { >> + void (*callback)(int, struct ib_class_port_info *, void *); >> + void *context; >> + struct ib_sa_query sa_query; >> +}; >> + >> struct ib_sa_mcmember_query { >> void (*callback)(int, struct ib_sa_mcmember_rec *, void *); >> void *context; >> @@ -392,6 +398,83 @@ static const struct ib_field service_rec_table[] = { >> .size_bits = 2*64 }, >> }; >> >> +#define PORTCLASSINFO_REC_FIELD(field) \ > > Would CLASSPORTINFO_REC_FIELD be more consistent in terms of naming ? Agree. will fix that. thanks. > >> + .struct_offset_bytes = offsetof(struct ib_class_port_info, field), \ >> + .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \ >> + .field_name = "ib_class_port_info:" #field >> + >> +static const struct ib_field classport_info_rec_table[] = { >> + { PORTCLASSINFO_REC_FIELD(base_version), >> + .offset_words = 0, >> + .offset_bits = 0, >> + .size_bits = 8 }, >> + { PORTCLASSINFO_REC_FIELD(class_version), >> + .offset_words = 0, >> + .offset_bits = 8, >> + .size_bits = 8 }, >> + { PORTCLASSINFO_REC_FIELD(capability_mask), >> + .offset_words = 0, >> + .offset_bits = 16, >> + .size_bits = 16 }, >> + { PORTCLASSINFO_REC_FIELD(cap_mask2_resp_time), >> + .offset_words = 1, >> + .offset_bits = 0, >> + .size_bits = 32 }, > > Why combine fields ? Syntax is rich enough to deal with bit fields. > This is what was done for other SA attributes in this file. > > -- Hal > >> + { PORTCLASSINFO_REC_FIELD(redirect_gid), >> + .offset_words = 2, >> + .offset_bits = 0, >> + .size_bits = 128 }, >> + { PORTCLASSINFO_REC_FIELD(redirect_tcslfl), >> + .offset_words = 6, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + >> + { PORTCLASSINFO_REC_FIELD(redirect_lid), >> + .offset_words = 7, >> + .offset_bits = 0, >> + .size_bits = 16 }, >> + { PORTCLASSINFO_REC_FIELD(redirect_pkey), >> + .offset_words = 7, >> + .offset_bits = 16, >> + .size_bits = 16 }, >> + >> + { PORTCLASSINFO_REC_FIELD(redirect_qp), >> + .offset_words = 8, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + { PORTCLASSINFO_REC_FIELD(redirect_qkey), >> + .offset_words = 9, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + >> + { PORTCLASSINFO_REC_FIELD(trap_gid), >> + .offset_words = 10, >> + .offset_bits = 0, >> + .size_bits = 128 }, >> + { PORTCLASSINFO_REC_FIELD(trap_tcslfl), >> + .offset_words = 14, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + >> + { PORTCLASSINFO_REC_FIELD(trap_lid), >> + .offset_words = 15, >> + .offset_bits = 0, >> + .size_bits = 16 }, >> + { PORTCLASSINFO_REC_FIELD(trap_pkey), >> + .offset_words = 15, >> + .offset_bits = 16, >> + .size_bits = 16 }, >> + >> + { PORTCLASSINFO_REC_FIELD(trap_hlqp), >> + .offset_words = 16, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + { PORTCLASSINFO_REC_FIELD(trap_qkey), >> + .offset_words = 17, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> +}; >> + >> #define GUIDINFO_REC_FIELD(field) \ >> .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \ >> .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \ >> @@ -1645,6 +1728,97 @@ err1: >> } >> EXPORT_SYMBOL(ib_sa_guid_info_rec_query); >> >> +/* Support get SA ClassPortInfo */ >> +static void ib_sa_classport_info_rec_callback(struct ib_sa_query *sa_query, >> + int status, >> + struct ib_sa_mad *mad) >> +{ >> + struct ib_sa_classport_info_query *query = >> + container_of(sa_query, struct ib_sa_classport_info_query, sa_query); >> + >> + if (mad) { >> + struct ib_class_port_info rec; >> + >> + ib_unpack(classport_info_rec_table, >> + ARRAY_SIZE(classport_info_rec_table), >> + mad->data, &rec); >> + query->callback(status, &rec, query->context); >> + } else { >> + query->callback(status, NULL, query->context); >> + } >> +} >> + >> +static void ib_sa_portclass_info_rec_release(struct ib_sa_query *sa_query) >> +{ >> + kfree(container_of(sa_query, struct ib_sa_classport_info_query, >> + sa_query)); >> +} >> + >> +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, >> + struct ib_device *device, u8 port_num, >> + int timeout_ms, gfp_t gfp_mask, >> + void (*callback)(int status, >> + struct ib_class_port_info *resp, >> + void *context), >> + void *context, >> + struct ib_sa_query **sa_query) >> +{ >> + struct ib_sa_classport_info_query *query; >> + struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); >> + struct ib_sa_port *port; >> + struct ib_mad_agent *agent; >> + struct ib_sa_mad *mad; >> + int ret; >> + >> + if (!sa_dev) >> + return -ENODEV; >> + >> + port = &sa_dev->port[port_num - sa_dev->start_port]; >> + agent = port->agent; >> + >> + query = kzalloc(sizeof(*query), gfp_mask); >> + if (!query) >> + return -ENOMEM; >> + >> + query->sa_query.port = port; >> + ret = alloc_mad(&query->sa_query, gfp_mask); >> + if (ret) >> + goto err1; >> + >> + ib_sa_client_get(client); >> + query->sa_query.client = client; >> + query->callback = callback; >> + query->context = context; >> + >> + mad = query->sa_query.mad_buf->mad; >> + init_mad(mad, agent); >> + >> + query->sa_query.callback = callback ? ib_sa_classport_info_rec_callback : NULL; >> + >> + query->sa_query.release = ib_sa_portclass_info_rec_release; >> + /* support GET only */ >> + mad->mad_hdr.method = IB_MGMT_METHOD_GET; >> + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_CLASS_PORTINFO); >> + mad->sa_hdr.comp_mask = 0; >> + *sa_query = &query->sa_query; >> + >> + ret = send_mad(&query->sa_query, timeout_ms, gfp_mask); >> + if (ret < 0) >> + goto err2; >> + >> + return ret; >> + >> +err2: >> + *sa_query = NULL; >> + ib_sa_client_put(query->sa_query.client); >> + free_mad(&query->sa_query); >> + >> +err1: >> + kfree(query); >> + return ret; >> +} >> +EXPORT_SYMBOL(ib_sa_classport_info_rec_query); >> + >> static void send_handler(struct ib_mad_agent *agent, >> struct ib_mad_send_wc *mad_send_wc) >> { >> diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h >> index cdc1c81..3840416 100644 >> --- a/include/rdma/ib_sa.h >> +++ b/include/rdma/ib_sa.h >> @@ -94,6 +94,8 @@ enum ib_sa_selector { >> IB_SA_BEST = 3 >> }; >> >> +#define IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT BIT(12) >> + >> /* >> * Structures for SA records are named "struct ib_sa_xxx_rec." No >> * attempt is made to pack structures to match the physical layout of >> @@ -439,4 +441,14 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client, >> void *context, >> struct ib_sa_query **sa_query); >> >> +/* Support get SA ClassPortInfo */ >> +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, >> + struct ib_device *device, u8 port_num, >> + int timeout_ms, gfp_t gfp_mask, >> + void (*callback)(int status, >> + struct ib_class_port_info *resp, >> + void *context), >> + void *context, >> + struct ib_sa_query **sa_query); >> + >> #endif /* IB_SA_H */ >> > -- > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Apr 20, 2016 at 3:09 PM, Hal Rosenstock <hal@dev.mellanox.co.il> wrote: > On 4/19/2016 8:51 AM, Erez Shitrit wrote: >> New sa query function to return the ClassPortInfo struct from the sa. >> If the SM supports FullMemberSendOnly mode for MCG's, it sets a >> capability bit in the capability_mask2 field of the response. >> >> Signed-off-by: Erez Shitrit <erezsh@mellanox.com> >> Reviewed-by: Leon Romanovsky <leonro@mellanox.com> >> --- >> drivers/infiniband/core/sa_query.c | 174 +++++++++++++++++++++++++++++++++++++ >> include/rdma/ib_sa.h | 12 +++ >> 2 files changed, 186 insertions(+) >> >> diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c >> index 8a09c0f..66535bf 100644 >> --- a/drivers/infiniband/core/sa_query.c >> +++ b/drivers/infiniband/core/sa_query.c >> @@ -119,6 +119,12 @@ struct ib_sa_guidinfo_query { >> struct ib_sa_query sa_query; >> }; >> >> +struct ib_sa_classport_info_query { >> + void (*callback)(int, struct ib_class_port_info *, void *); >> + void *context; >> + struct ib_sa_query sa_query; >> +}; >> + >> struct ib_sa_mcmember_query { >> void (*callback)(int, struct ib_sa_mcmember_rec *, void *); >> void *context; >> @@ -392,6 +398,83 @@ static const struct ib_field service_rec_table[] = { >> .size_bits = 2*64 }, >> }; >> >> +#define PORTCLASSINFO_REC_FIELD(field) \ > > Would CLASSPORTINFO_REC_FIELD be more consistent in terms of naming ? > >> + .struct_offset_bytes = offsetof(struct ib_class_port_info, field), \ >> + .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \ >> + .field_name = "ib_class_port_info:" #field >> + >> +static const struct ib_field classport_info_rec_table[] = { >> + { PORTCLASSINFO_REC_FIELD(base_version), >> + .offset_words = 0, >> + .offset_bits = 0, >> + .size_bits = 8 }, >> + { PORTCLASSINFO_REC_FIELD(class_version), >> + .offset_words = 0, >> + .offset_bits = 8, >> + .size_bits = 8 }, >> + { PORTCLASSINFO_REC_FIELD(capability_mask), >> + .offset_words = 0, >> + .offset_bits = 16, >> + .size_bits = 16 }, >> + { PORTCLASSINFO_REC_FIELD(cap_mask2_resp_time), >> + .offset_words = 1, >> + .offset_bits = 0, >> + .size_bits = 32 }, > > Why combine fields ? Syntax is rich enough to deal with bit fields. > This is what was done for other SA attributes in this file. > > -- Hal Tried to follow the sm implementation. Anyway, will fix that. Thanks. > >> + { PORTCLASSINFO_REC_FIELD(redirect_gid), >> + .offset_words = 2, >> + .offset_bits = 0, >> + .size_bits = 128 }, >> + { PORTCLASSINFO_REC_FIELD(redirect_tcslfl), >> + .offset_words = 6, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + >> + { PORTCLASSINFO_REC_FIELD(redirect_lid), >> + .offset_words = 7, >> + .offset_bits = 0, >> + .size_bits = 16 }, >> + { PORTCLASSINFO_REC_FIELD(redirect_pkey), >> + .offset_words = 7, >> + .offset_bits = 16, >> + .size_bits = 16 }, >> + >> + { PORTCLASSINFO_REC_FIELD(redirect_qp), >> + .offset_words = 8, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + { PORTCLASSINFO_REC_FIELD(redirect_qkey), >> + .offset_words = 9, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + >> + { PORTCLASSINFO_REC_FIELD(trap_gid), >> + .offset_words = 10, >> + .offset_bits = 0, >> + .size_bits = 128 }, >> + { PORTCLASSINFO_REC_FIELD(trap_tcslfl), >> + .offset_words = 14, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + >> + { PORTCLASSINFO_REC_FIELD(trap_lid), >> + .offset_words = 15, >> + .offset_bits = 0, >> + .size_bits = 16 }, >> + { PORTCLASSINFO_REC_FIELD(trap_pkey), >> + .offset_words = 15, >> + .offset_bits = 16, >> + .size_bits = 16 }, >> + >> + { PORTCLASSINFO_REC_FIELD(trap_hlqp), >> + .offset_words = 16, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> + { PORTCLASSINFO_REC_FIELD(trap_qkey), >> + .offset_words = 17, >> + .offset_bits = 0, >> + .size_bits = 32 }, >> +}; >> + >> #define GUIDINFO_REC_FIELD(field) \ >> .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \ >> .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \ >> @@ -1645,6 +1728,97 @@ err1: >> } >> EXPORT_SYMBOL(ib_sa_guid_info_rec_query); >> >> +/* Support get SA ClassPortInfo */ >> +static void ib_sa_classport_info_rec_callback(struct ib_sa_query *sa_query, >> + int status, >> + struct ib_sa_mad *mad) >> +{ >> + struct ib_sa_classport_info_query *query = >> + container_of(sa_query, struct ib_sa_classport_info_query, sa_query); >> + >> + if (mad) { >> + struct ib_class_port_info rec; >> + >> + ib_unpack(classport_info_rec_table, >> + ARRAY_SIZE(classport_info_rec_table), >> + mad->data, &rec); >> + query->callback(status, &rec, query->context); >> + } else { >> + query->callback(status, NULL, query->context); >> + } >> +} >> + >> +static void ib_sa_portclass_info_rec_release(struct ib_sa_query *sa_query) >> +{ >> + kfree(container_of(sa_query, struct ib_sa_classport_info_query, >> + sa_query)); >> +} >> + >> +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, >> + struct ib_device *device, u8 port_num, >> + int timeout_ms, gfp_t gfp_mask, >> + void (*callback)(int status, >> + struct ib_class_port_info *resp, >> + void *context), >> + void *context, >> + struct ib_sa_query **sa_query) >> +{ >> + struct ib_sa_classport_info_query *query; >> + struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); >> + struct ib_sa_port *port; >> + struct ib_mad_agent *agent; >> + struct ib_sa_mad *mad; >> + int ret; >> + >> + if (!sa_dev) >> + return -ENODEV; >> + >> + port = &sa_dev->port[port_num - sa_dev->start_port]; >> + agent = port->agent; >> + >> + query = kzalloc(sizeof(*query), gfp_mask); >> + if (!query) >> + return -ENOMEM; >> + >> + query->sa_query.port = port; >> + ret = alloc_mad(&query->sa_query, gfp_mask); >> + if (ret) >> + goto err1; >> + >> + ib_sa_client_get(client); >> + query->sa_query.client = client; >> + query->callback = callback; >> + query->context = context; >> + >> + mad = query->sa_query.mad_buf->mad; >> + init_mad(mad, agent); >> + >> + query->sa_query.callback = callback ? ib_sa_classport_info_rec_callback : NULL; >> + >> + query->sa_query.release = ib_sa_portclass_info_rec_release; >> + /* support GET only */ >> + mad->mad_hdr.method = IB_MGMT_METHOD_GET; >> + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_CLASS_PORTINFO); >> + mad->sa_hdr.comp_mask = 0; >> + *sa_query = &query->sa_query; >> + >> + ret = send_mad(&query->sa_query, timeout_ms, gfp_mask); >> + if (ret < 0) >> + goto err2; >> + >> + return ret; >> + >> +err2: >> + *sa_query = NULL; >> + ib_sa_client_put(query->sa_query.client); >> + free_mad(&query->sa_query); >> + >> +err1: >> + kfree(query); >> + return ret; >> +} >> +EXPORT_SYMBOL(ib_sa_classport_info_rec_query); >> + >> static void send_handler(struct ib_mad_agent *agent, >> struct ib_mad_send_wc *mad_send_wc) >> { >> diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h >> index cdc1c81..3840416 100644 >> --- a/include/rdma/ib_sa.h >> +++ b/include/rdma/ib_sa.h >> @@ -94,6 +94,8 @@ enum ib_sa_selector { >> IB_SA_BEST = 3 >> }; >> >> +#define IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT BIT(12) >> + >> /* >> * Structures for SA records are named "struct ib_sa_xxx_rec." No >> * attempt is made to pack structures to match the physical layout of >> @@ -439,4 +441,14 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client, >> void *context, >> struct ib_sa_query **sa_query); >> >> +/* Support get SA ClassPortInfo */ >> +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, >> + struct ib_device *device, u8 port_num, >> + int timeout_ms, gfp_t gfp_mask, >> + void (*callback)(int status, >> + struct ib_class_port_info *resp, >> + void *context), >> + void *context, >> + struct ib_sa_query **sa_query); >> + >> #endif /* IB_SA_H */ >> > -- > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 8a09c0f..66535bf 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -119,6 +119,12 @@ struct ib_sa_guidinfo_query { struct ib_sa_query sa_query; }; +struct ib_sa_classport_info_query { + void (*callback)(int, struct ib_class_port_info *, void *); + void *context; + struct ib_sa_query sa_query; +}; + struct ib_sa_mcmember_query { void (*callback)(int, struct ib_sa_mcmember_rec *, void *); void *context; @@ -392,6 +398,83 @@ static const struct ib_field service_rec_table[] = { .size_bits = 2*64 }, }; +#define PORTCLASSINFO_REC_FIELD(field) \ + .struct_offset_bytes = offsetof(struct ib_class_port_info, field), \ + .struct_size_bytes = sizeof((struct ib_class_port_info *)0)->field, \ + .field_name = "ib_class_port_info:" #field + +static const struct ib_field classport_info_rec_table[] = { + { PORTCLASSINFO_REC_FIELD(base_version), + .offset_words = 0, + .offset_bits = 0, + .size_bits = 8 }, + { PORTCLASSINFO_REC_FIELD(class_version), + .offset_words = 0, + .offset_bits = 8, + .size_bits = 8 }, + { PORTCLASSINFO_REC_FIELD(capability_mask), + .offset_words = 0, + .offset_bits = 16, + .size_bits = 16 }, + { PORTCLASSINFO_REC_FIELD(cap_mask2_resp_time), + .offset_words = 1, + .offset_bits = 0, + .size_bits = 32 }, + { PORTCLASSINFO_REC_FIELD(redirect_gid), + .offset_words = 2, + .offset_bits = 0, + .size_bits = 128 }, + { PORTCLASSINFO_REC_FIELD(redirect_tcslfl), + .offset_words = 6, + .offset_bits = 0, + .size_bits = 32 }, + + { PORTCLASSINFO_REC_FIELD(redirect_lid), + .offset_words = 7, + .offset_bits = 0, + .size_bits = 16 }, + { PORTCLASSINFO_REC_FIELD(redirect_pkey), + .offset_words = 7, + .offset_bits = 16, + .size_bits = 16 }, + + { PORTCLASSINFO_REC_FIELD(redirect_qp), + .offset_words = 8, + .offset_bits = 0, + .size_bits = 32 }, + { PORTCLASSINFO_REC_FIELD(redirect_qkey), + .offset_words = 9, + .offset_bits = 0, + .size_bits = 32 }, + + { PORTCLASSINFO_REC_FIELD(trap_gid), + .offset_words = 10, + .offset_bits = 0, + .size_bits = 128 }, + { PORTCLASSINFO_REC_FIELD(trap_tcslfl), + .offset_words = 14, + .offset_bits = 0, + .size_bits = 32 }, + + { PORTCLASSINFO_REC_FIELD(trap_lid), + .offset_words = 15, + .offset_bits = 0, + .size_bits = 16 }, + { PORTCLASSINFO_REC_FIELD(trap_pkey), + .offset_words = 15, + .offset_bits = 16, + .size_bits = 16 }, + + { PORTCLASSINFO_REC_FIELD(trap_hlqp), + .offset_words = 16, + .offset_bits = 0, + .size_bits = 32 }, + { PORTCLASSINFO_REC_FIELD(trap_qkey), + .offset_words = 17, + .offset_bits = 0, + .size_bits = 32 }, +}; + #define GUIDINFO_REC_FIELD(field) \ .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \ .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \ @@ -1645,6 +1728,97 @@ err1: } EXPORT_SYMBOL(ib_sa_guid_info_rec_query); +/* Support get SA ClassPortInfo */ +static void ib_sa_classport_info_rec_callback(struct ib_sa_query *sa_query, + int status, + struct ib_sa_mad *mad) +{ + struct ib_sa_classport_info_query *query = + container_of(sa_query, struct ib_sa_classport_info_query, sa_query); + + if (mad) { + struct ib_class_port_info rec; + + ib_unpack(classport_info_rec_table, + ARRAY_SIZE(classport_info_rec_table), + mad->data, &rec); + query->callback(status, &rec, query->context); + } else { + query->callback(status, NULL, query->context); + } +} + +static void ib_sa_portclass_info_rec_release(struct ib_sa_query *sa_query) +{ + kfree(container_of(sa_query, struct ib_sa_classport_info_query, + sa_query)); +} + +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, + struct ib_device *device, u8 port_num, + int timeout_ms, gfp_t gfp_mask, + void (*callback)(int status, + struct ib_class_port_info *resp, + void *context), + void *context, + struct ib_sa_query **sa_query) +{ + struct ib_sa_classport_info_query *query; + struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); + struct ib_sa_port *port; + struct ib_mad_agent *agent; + struct ib_sa_mad *mad; + int ret; + + if (!sa_dev) + return -ENODEV; + + port = &sa_dev->port[port_num - sa_dev->start_port]; + agent = port->agent; + + query = kzalloc(sizeof(*query), gfp_mask); + if (!query) + return -ENOMEM; + + query->sa_query.port = port; + ret = alloc_mad(&query->sa_query, gfp_mask); + if (ret) + goto err1; + + ib_sa_client_get(client); + query->sa_query.client = client; + query->callback = callback; + query->context = context; + + mad = query->sa_query.mad_buf->mad; + init_mad(mad, agent); + + query->sa_query.callback = callback ? ib_sa_classport_info_rec_callback : NULL; + + query->sa_query.release = ib_sa_portclass_info_rec_release; + /* support GET only */ + mad->mad_hdr.method = IB_MGMT_METHOD_GET; + mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_CLASS_PORTINFO); + mad->sa_hdr.comp_mask = 0; + *sa_query = &query->sa_query; + + ret = send_mad(&query->sa_query, timeout_ms, gfp_mask); + if (ret < 0) + goto err2; + + return ret; + +err2: + *sa_query = NULL; + ib_sa_client_put(query->sa_query.client); + free_mad(&query->sa_query); + +err1: + kfree(query); + return ret; +} +EXPORT_SYMBOL(ib_sa_classport_info_rec_query); + static void send_handler(struct ib_mad_agent *agent, struct ib_mad_send_wc *mad_send_wc) { diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h index cdc1c81..3840416 100644 --- a/include/rdma/ib_sa.h +++ b/include/rdma/ib_sa.h @@ -94,6 +94,8 @@ enum ib_sa_selector { IB_SA_BEST = 3 }; +#define IB_SA_CAP_MASK2_SENDONLY_FULL_MEM_SUPPORT BIT(12) + /* * Structures for SA records are named "struct ib_sa_xxx_rec." No * attempt is made to pack structures to match the physical layout of @@ -439,4 +441,14 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client, void *context, struct ib_sa_query **sa_query); +/* Support get SA ClassPortInfo */ +int ib_sa_classport_info_rec_query(struct ib_sa_client *client, + struct ib_device *device, u8 port_num, + int timeout_ms, gfp_t gfp_mask, + void (*callback)(int status, + struct ib_class_port_info *resp, + void *context), + void *context, + struct ib_sa_query **sa_query); + #endif /* IB_SA_H */