aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2013-12-12 11:03:17 -0500
committerRoland Dreier <roland@purestorage.com>2014-01-19 18:14:04 -0500
commited4c54e5b4baf55a7a67a80fa766334855c94854 (patch)
tree24ee1fc584c644b7d74956be0994f0f4abd36df9
parent37721d8501a9a1fbe87527c24d127a914b29fd7f (diff)
IB/core: Resolve Ethernet L2 addresses when modifying QP
Existing user space applications provide only IBoE L3 address attributes to the kernel when they issue a modify QP modify. To work with them and let such apps (plus kernel consumers which don't use the RDMA-CM) keep working transparently under the IBoE GID IP addressing changes, add an Eth L2 address resolution helper. Signed-off-by: Moni Shoua <monis@mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/core/core_priv.h2
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c4
-rw-r--r--drivers/infiniband/core/verbs.c43
3 files changed, 49 insertions, 0 deletions
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index a565af5c2d2e..87d1936f5c1c 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -49,4 +49,6 @@ void ib_sysfs_cleanup(void);
49int ib_cache_setup(void); 49int ib_cache_setup(void);
50void ib_cache_cleanup(void); 50void ib_cache_cleanup(void);
51 51
52int ib_resolve_eth_l2_attrs(struct ib_qp *qp,
53 struct ib_qp_attr *qp_attr, int *qp_attr_mask);
52#endif /* _CORE_PRIV_H */ 54#endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index f1cc83855af6..ea6203ee7bcc 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -40,6 +40,7 @@
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41 41
42#include "uverbs.h" 42#include "uverbs.h"
43#include "core_priv.h"
43 44
44struct uverbs_lock_class { 45struct uverbs_lock_class {
45 struct lock_class_key key; 46 struct lock_class_key key;
@@ -1961,6 +1962,9 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1961 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num; 1962 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
1962 1963
1963 if (qp->real_qp == qp) { 1964 if (qp->real_qp == qp) {
1965 ret = ib_resolve_eth_l2_attrs(qp, attr, &cmd.attr_mask);
1966 if (ret)
1967 goto out;
1964 ret = qp->device->modify_qp(qp, attr, 1968 ret = qp->device->modify_qp(qp, attr,
1965 modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata); 1969 modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
1966 } else { 1970 } else {
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 7978394738a3..b3acfc03c74d 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -46,6 +46,8 @@
46#include <rdma/ib_cache.h> 46#include <rdma/ib_cache.h>
47#include <rdma/ib_addr.h> 47#include <rdma/ib_addr.h>
48 48
49#include "core_priv.h"
50
49int ib_rate_to_mult(enum ib_rate rate) 51int ib_rate_to_mult(enum ib_rate rate)
50{ 52{
51 switch (rate) { 53 switch (rate) {
@@ -859,10 +861,51 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
859} 861}
860EXPORT_SYMBOL(ib_modify_qp_is_ok); 862EXPORT_SYMBOL(ib_modify_qp_is_ok);
861 863
864int ib_resolve_eth_l2_attrs(struct ib_qp *qp,
865 struct ib_qp_attr *qp_attr, int *qp_attr_mask)
866{
867 int ret = 0;
868 union ib_gid sgid;
869
870 if ((*qp_attr_mask & IB_QP_AV) &&
871 (rdma_port_get_link_layer(qp->device, qp_attr->ah_attr.port_num) == IB_LINK_LAYER_ETHERNET)) {
872 ret = ib_query_gid(qp->device, qp_attr->ah_attr.port_num,
873 qp_attr->ah_attr.grh.sgid_index, &sgid);
874 if (ret)
875 goto out;
876 if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
877 rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac);
878 rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac);
879 qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
880 } else {
881 ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid,
882 qp_attr->ah_attr.dmac, &qp_attr->vlan_id);
883 if (ret)
884 goto out;
885 ret = rdma_addr_find_smac_by_sgid(&sgid, qp_attr->smac, NULL);
886 if (ret)
887 goto out;
888 }
889 *qp_attr_mask |= IB_QP_SMAC;
890 if (qp_attr->vlan_id < 0xFFFF)
891 *qp_attr_mask |= IB_QP_VID;
892 }
893out:
894 return ret;
895}
896EXPORT_SYMBOL(ib_resolve_eth_l2_attrs);
897
898
862int ib_modify_qp(struct ib_qp *qp, 899int ib_modify_qp(struct ib_qp *qp,
863 struct ib_qp_attr *qp_attr, 900 struct ib_qp_attr *qp_attr,
864 int qp_attr_mask) 901 int qp_attr_mask)
865{ 902{
903 int ret;
904
905 ret = ib_resolve_eth_l2_attrs(qp, qp_attr, &qp_attr_mask);
906 if (ret)
907 return ret;
908
866 return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL); 909 return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
867} 910}
868EXPORT_SYMBOL(ib_modify_qp); 911EXPORT_SYMBOL(ib_modify_qp);