mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-11 21:38:01 +07:00
IB/sa: Add GuidInfoRecord query support
This query is needed for SRIOV alias GUID support. The query is implemented per the IB Spec definition in section 15.2.5.18 (GuidInfoRecord). Signed-off-by: Erez Shitrit <erezsh@mellanox.co.il> Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
parent
b1d8eb5a21
commit
aeab97ed15
@ -94,6 +94,12 @@ struct ib_sa_path_query {
|
|||||||
struct ib_sa_query sa_query;
|
struct ib_sa_query sa_query;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ib_sa_guidinfo_query {
|
||||||
|
void (*callback)(int, struct ib_sa_guidinfo_rec *, void *);
|
||||||
|
void *context;
|
||||||
|
struct ib_sa_query sa_query;
|
||||||
|
};
|
||||||
|
|
||||||
struct ib_sa_mcmember_query {
|
struct ib_sa_mcmember_query {
|
||||||
void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
|
void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
|
||||||
void *context;
|
void *context;
|
||||||
@ -347,6 +353,34 @@ static const struct ib_field service_rec_table[] = {
|
|||||||
.size_bits = 2*64 },
|
.size_bits = 2*64 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#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, \
|
||||||
|
.field_name = "sa_guidinfo_rec:" #field
|
||||||
|
|
||||||
|
static const struct ib_field guidinfo_rec_table[] = {
|
||||||
|
{ GUIDINFO_REC_FIELD(lid),
|
||||||
|
.offset_words = 0,
|
||||||
|
.offset_bits = 0,
|
||||||
|
.size_bits = 16 },
|
||||||
|
{ GUIDINFO_REC_FIELD(block_num),
|
||||||
|
.offset_words = 0,
|
||||||
|
.offset_bits = 16,
|
||||||
|
.size_bits = 8 },
|
||||||
|
{ GUIDINFO_REC_FIELD(res1),
|
||||||
|
.offset_words = 0,
|
||||||
|
.offset_bits = 24,
|
||||||
|
.size_bits = 8 },
|
||||||
|
{ GUIDINFO_REC_FIELD(res2),
|
||||||
|
.offset_words = 1,
|
||||||
|
.offset_bits = 0,
|
||||||
|
.size_bits = 32 },
|
||||||
|
{ GUIDINFO_REC_FIELD(guid_info_list),
|
||||||
|
.offset_words = 2,
|
||||||
|
.offset_bits = 0,
|
||||||
|
.size_bits = 512 },
|
||||||
|
};
|
||||||
|
|
||||||
static void free_sm_ah(struct kref *kref)
|
static void free_sm_ah(struct kref *kref)
|
||||||
{
|
{
|
||||||
struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
|
struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
|
||||||
@ -945,6 +979,105 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Support GuidInfoRecord */
|
||||||
|
static void ib_sa_guidinfo_rec_callback(struct ib_sa_query *sa_query,
|
||||||
|
int status,
|
||||||
|
struct ib_sa_mad *mad)
|
||||||
|
{
|
||||||
|
struct ib_sa_guidinfo_query *query =
|
||||||
|
container_of(sa_query, struct ib_sa_guidinfo_query, sa_query);
|
||||||
|
|
||||||
|
if (mad) {
|
||||||
|
struct ib_sa_guidinfo_rec rec;
|
||||||
|
|
||||||
|
ib_unpack(guidinfo_rec_table, ARRAY_SIZE(guidinfo_rec_table),
|
||||||
|
mad->data, &rec);
|
||||||
|
query->callback(status, &rec, query->context);
|
||||||
|
} else
|
||||||
|
query->callback(status, NULL, query->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ib_sa_guidinfo_rec_release(struct ib_sa_query *sa_query)
|
||||||
|
{
|
||||||
|
kfree(container_of(sa_query, struct ib_sa_guidinfo_query, sa_query));
|
||||||
|
}
|
||||||
|
|
||||||
|
int ib_sa_guid_info_rec_query(struct ib_sa_client *client,
|
||||||
|
struct ib_device *device, u8 port_num,
|
||||||
|
struct ib_sa_guidinfo_rec *rec,
|
||||||
|
ib_sa_comp_mask comp_mask, u8 method,
|
||||||
|
int timeout_ms, gfp_t gfp_mask,
|
||||||
|
void (*callback)(int status,
|
||||||
|
struct ib_sa_guidinfo_rec *resp,
|
||||||
|
void *context),
|
||||||
|
void *context,
|
||||||
|
struct ib_sa_query **sa_query)
|
||||||
|
{
|
||||||
|
struct ib_sa_guidinfo_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;
|
||||||
|
|
||||||
|
if (method != IB_MGMT_METHOD_GET &&
|
||||||
|
method != IB_MGMT_METHOD_SET &&
|
||||||
|
method != IB_SA_METHOD_DELETE) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
port = &sa_dev->port[port_num - sa_dev->start_port];
|
||||||
|
agent = port->agent;
|
||||||
|
|
||||||
|
query = kmalloc(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_guidinfo_rec_callback : NULL;
|
||||||
|
query->sa_query.release = ib_sa_guidinfo_rec_release;
|
||||||
|
|
||||||
|
mad->mad_hdr.method = method;
|
||||||
|
mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_GUID_INFO_REC);
|
||||||
|
mad->sa_hdr.comp_mask = comp_mask;
|
||||||
|
|
||||||
|
ib_pack(guidinfo_rec_table, ARRAY_SIZE(guidinfo_rec_table), rec,
|
||||||
|
mad->data);
|
||||||
|
|
||||||
|
*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_guid_info_rec_query);
|
||||||
|
|
||||||
static void send_handler(struct ib_mad_agent *agent,
|
static void send_handler(struct ib_mad_agent *agent,
|
||||||
struct ib_mad_send_wc *mad_send_wc)
|
struct ib_mad_send_wc *mad_send_wc)
|
||||||
{
|
{
|
||||||
|
@ -251,6 +251,28 @@ struct ib_sa_service_rec {
|
|||||||
u64 data64[2];
|
u64 data64[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define IB_SA_GUIDINFO_REC_LID IB_SA_COMP_MASK(0)
|
||||||
|
#define IB_SA_GUIDINFO_REC_BLOCK_NUM IB_SA_COMP_MASK(1)
|
||||||
|
#define IB_SA_GUIDINFO_REC_RES1 IB_SA_COMP_MASK(2)
|
||||||
|
#define IB_SA_GUIDINFO_REC_RES2 IB_SA_COMP_MASK(3)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID0 IB_SA_COMP_MASK(4)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID1 IB_SA_COMP_MASK(5)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID2 IB_SA_COMP_MASK(6)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID3 IB_SA_COMP_MASK(7)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID4 IB_SA_COMP_MASK(8)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID5 IB_SA_COMP_MASK(9)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID6 IB_SA_COMP_MASK(10)
|
||||||
|
#define IB_SA_GUIDINFO_REC_GID7 IB_SA_COMP_MASK(11)
|
||||||
|
|
||||||
|
struct ib_sa_guidinfo_rec {
|
||||||
|
__be16 lid;
|
||||||
|
u8 block_num;
|
||||||
|
/* reserved */
|
||||||
|
u8 res1;
|
||||||
|
__be32 res2;
|
||||||
|
u8 guid_info_list[64];
|
||||||
|
};
|
||||||
|
|
||||||
struct ib_sa_client {
|
struct ib_sa_client {
|
||||||
atomic_t users;
|
atomic_t users;
|
||||||
struct completion comp;
|
struct completion comp;
|
||||||
@ -385,4 +407,15 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
|
|||||||
*/
|
*/
|
||||||
void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec);
|
void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec);
|
||||||
|
|
||||||
|
/* Support GuidInfoRecord */
|
||||||
|
int ib_sa_guid_info_rec_query(struct ib_sa_client *client,
|
||||||
|
struct ib_device *device, u8 port_num,
|
||||||
|
struct ib_sa_guidinfo_rec *rec,
|
||||||
|
ib_sa_comp_mask comp_mask, u8 method,
|
||||||
|
int timeout_ms, gfp_t gfp_mask,
|
||||||
|
void (*callback)(int status,
|
||||||
|
struct ib_sa_guidinfo_rec *resp,
|
||||||
|
void *context),
|
||||||
|
void *context,
|
||||||
|
struct ib_sa_query **sa_query);
|
||||||
#endif /* IB_SA_H */
|
#endif /* IB_SA_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user