]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/infiniband/core/sa_query.c
IB/SA: Split struct sa_path_rec based on IB and ROCE specific fields
[karo-tx-linux.git] / drivers / infiniband / core / sa_query.c
index 5294bceda472b87575c1cca6572baebf2a7da75f..88361c164d7392386073a3bc0d236484cd202747 100644 (file)
@@ -129,7 +129,7 @@ struct ib_sa_service_query {
 };
 
 struct ib_sa_path_query {
-       void (*callback)(int, struct ib_sa_path_rec *, void *);
+       void (*callback)(int, struct sa_path_rec *, void *);
        void *context;
        struct ib_sa_query sa_query;
 };
@@ -188,12 +188,12 @@ static DEFINE_SPINLOCK(tid_lock);
 static u32 tid;
 
 #define PATH_REC_FIELD(field) \
-       .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field),          \
-       .struct_size_bytes   = sizeof ((struct ib_sa_path_rec *) 0)->field,     \
+       .struct_offset_bytes = offsetof(struct sa_path_rec, field),     \
+       .struct_size_bytes   = sizeof((struct sa_path_rec *)0)->field,  \
        .field_name          = "sa_path_rec:" #field
 
 static const struct ib_field path_rec_table[] = {
-       { PATH_REC_FIELD(service_id),
+       { PATH_REC_FIELD(ib.service_id),
          .offset_words = 0,
          .offset_bits  = 0,
          .size_bits    = 64 },
@@ -205,15 +205,15 @@ static const struct ib_field path_rec_table[] = {
          .offset_words = 6,
          .offset_bits  = 0,
          .size_bits    = 128 },
-       { PATH_REC_FIELD(dlid),
+       { PATH_REC_FIELD(ib.dlid),
          .offset_words = 10,
          .offset_bits  = 0,
          .size_bits    = 16 },
-       { PATH_REC_FIELD(slid),
+       { PATH_REC_FIELD(ib.slid),
          .offset_words = 10,
          .offset_bits  = 16,
          .size_bits    = 16 },
-       { PATH_REC_FIELD(raw_traffic),
+       { PATH_REC_FIELD(ib.raw_traffic),
          .offset_words = 11,
          .offset_bits  = 0,
          .size_bits    = 1 },
@@ -618,7 +618,7 @@ static inline int ib_sa_query_cancelled(struct ib_sa_query *query)
 static void ib_nl_set_path_rec_attrs(struct sk_buff *skb,
                                     struct ib_sa_query *query)
 {
-       struct ib_sa_path_rec *sa_rec = query->mad_buf->context[1];
+       struct sa_path_rec *sa_rec = query->mad_buf->context[1];
        struct ib_sa_mad *mad = query->mad_buf->mad;
        ib_sa_comp_mask comp_mask = mad->sa_hdr.comp_mask;
        u16 val16;
@@ -643,7 +643,7 @@ static void ib_nl_set_path_rec_attrs(struct sk_buff *skb,
 
        /* Now build the attributes */
        if (comp_mask & IB_SA_PATH_REC_SERVICE_ID) {
-               val64 = be64_to_cpu(sa_rec->service_id);
+               val64 = be64_to_cpu(sa_path_get_service_id(sa_rec));
                nla_put(skb, RDMA_NLA_F_MANDATORY | LS_NLA_TYPE_SERVICE_ID,
                        sizeof(val64), &val64);
        }
@@ -1099,7 +1099,7 @@ static u8 get_src_path_mask(struct ib_device *device, u8 port_num)
 }
 
 int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
-                        struct ib_sa_path_rec *rec,
+                        struct sa_path_rec *rec,
                         struct rdma_ah_attr *ah_attr)
 {
        int ret;
@@ -1108,10 +1108,11 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
        struct net_device *ndev = NULL;
 
        memset(ah_attr, 0, sizeof *ah_attr);
+       ah_attr->type = rdma_ah_find_type(device, port_num);
 
-       rdma_ah_set_dlid(ah_attr, be16_to_cpu(rec->dlid));
+       rdma_ah_set_dlid(ah_attr, be16_to_cpu(sa_path_get_dlid(rec)));
        rdma_ah_set_sl(ah_attr, rec->sl);
-       rdma_ah_set_path_bits(ah_attr, be16_to_cpu(rec->slid) &
+       rdma_ah_set_path_bits(ah_attr, be16_to_cpu(sa_path_get_slid(rec)) &
                              get_src_path_mask(device, port_num));
        rdma_ah_set_port_num(ah_attr, port_num);
        rdma_ah_set_static_rate(ah_attr, rec->rate);
@@ -1120,9 +1121,13 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
        if (use_roce) {
                struct net_device *idev;
                struct net_device *resolved_dev;
-               struct rdma_dev_addr dev_addr = {.bound_dev_if = rec->ifindex,
-                                                .net = rec->net ? rec->net :
-                                                        &init_net};
+               struct rdma_dev_addr dev_addr = {
+                       .bound_dev_if = ((sa_path_get_ifindex(rec) >= 0) ?
+                                        sa_path_get_ifindex(rec) : 0),
+                       .net = sa_path_get_ndev(rec) ?
+                               sa_path_get_ndev(rec) :
+                               &init_net
+               };
                union {
                        struct sockaddr     _sockaddr;
                        struct sockaddr_in  _sockaddr_in;
@@ -1143,7 +1148,7 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
 
                if ((dev_addr.network == RDMA_NETWORK_IPV4 ||
                     dev_addr.network == RDMA_NETWORK_IPV6) &&
-                   rec->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
+                   rec->rec_type != SA_PATH_REC_TYPE_ROCE_V2)
                        return -EINVAL;
 
                idev = device->get_netdev(device, port_num);
@@ -1174,9 +1179,10 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
        }
 
        if (rec->hop_limit > 0 || use_roce) {
-               ret = ib_find_cached_gid_by_port(device, &rec->sgid,
-                                                rec->gid_type, port_num, ndev,
-                                                &gid_index);
+               enum ib_gid_type type = sa_conv_pathrec_to_gid_type(rec);
+
+               ret = ib_find_cached_gid_by_port(device, &rec->sgid, type,
+                                                port_num, ndev, &gid_index);
                if (ret) {
                        if (ndev)
                                dev_put(ndev);
@@ -1191,8 +1197,13 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
                        dev_put(ndev);
        }
 
-       if (use_roce)
-               memcpy(ah_attr->dmac, rec->dmac, ETH_ALEN);
+       if (use_roce) {
+               u8 *dmac = sa_path_get_dmac(rec);
+
+               if (!dmac)
+                       return -EINVAL;
+               memcpy(ah_attr->roce.dmac, dmac, ETH_ALEN);
+       }
 
        return 0;
 }
@@ -1300,13 +1311,13 @@ static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
        return ret ? ret : id;
 }
 
-void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
+void ib_sa_unpack_path(void *attribute, struct sa_path_rec *rec)
 {
        ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec);
 }
 EXPORT_SYMBOL(ib_sa_unpack_path);
 
-void ib_sa_pack_path(struct ib_sa_path_rec *rec, void *attribute)
+void ib_sa_pack_path(struct sa_path_rec *rec, void *attribute)
 {
        ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, attribute);
 }
@@ -1320,14 +1331,14 @@ static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
                container_of(sa_query, struct ib_sa_path_query, sa_query);
 
        if (mad) {
-               struct ib_sa_path_rec rec;
+               struct sa_path_rec rec;
 
                ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
                          mad->data, &rec);
-               rec.net = NULL;
-               rec.ifindex = 0;
-               rec.gid_type = IB_GID_TYPE_IB;
-               eth_zero_addr(rec.dmac);
+               rec.rec_type = SA_PATH_REC_TYPE_IB;
+               sa_path_set_ndev(&rec, NULL);
+               sa_path_set_ifindex(&rec, 0);
+               sa_path_set_dmac_zero(&rec);
                query->callback(status, &rec, query->context);
        } else
                query->callback(status, NULL, query->context);
@@ -1365,11 +1376,11 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
  */
 int ib_sa_path_rec_get(struct ib_sa_client *client,
                       struct ib_device *device, u8 port_num,
-                      struct ib_sa_path_rec *rec,
+                      struct sa_path_rec *rec,
                       ib_sa_comp_mask comp_mask,
                       int timeout_ms, gfp_t gfp_mask,
                       void (*callback)(int status,
-                                       struct ib_sa_path_rec *resp,
+                                       struct sa_path_rec *resp,
                                        void *context),
                       void *context,
                       struct ib_sa_query **sa_query)
@@ -1384,6 +1395,9 @@ int ib_sa_path_rec_get(struct ib_sa_client *client,
        if (!sa_dev)
                return -ENODEV;
 
+       if (rec->rec_type != SA_PATH_REC_TYPE_IB)
+               return -EINVAL;
+
        port  = &sa_dev->port[port_num - sa_dev->start_port];
        agent = port->agent;
 
@@ -2029,6 +2043,8 @@ static void update_sm_ah(struct work_struct *work)
                pr_err("Couldn't find index for default PKey\n");
 
        memset(&ah_attr, 0, sizeof(ah_attr));
+       ah_attr.type = rdma_ah_find_type(port->agent->device,
+                                        port->port_num);
        rdma_ah_set_dlid(&ah_attr, port_attr.sm_lid);
        rdma_ah_set_sl(&ah_attr, port_attr.sm_sl);
        rdma_ah_set_port_num(&ah_attr, port->port_num);