aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/verbs.c
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2013-12-12 11:03:11 -0500
committerRoland Dreier <roland@purestorage.com>2014-01-14 17:20:54 -0500
commitdd5f03beb4f76ae65d76d8c22a8815e424fc607c (patch)
tree162cb1bece8602841de5cff1d37e781de8528c0f /drivers/infiniband/core/verbs.c
parent7e22e91102c6b9df7c4ae2168910e19d2bb14cd6 (diff)
IB/core: Ethernet L2 attributes in verbs/cm structures
This patch add the support for Ethernet L2 attributes in the verbs/cm/cma structures. When dealing with L2 Ethernet, we should use smac, dmac, vlan ID and priority in a similar manner that the IB L2 (and the L4 PKEY) attributes are used. Thus, those attributes were added to the following structures: * ib_ah_attr - added dmac * ib_qp_attr - added smac and vlan_id, (sl remains vlan priority) * ib_wc - added smac, vlan_id * ib_sa_path_rec - added smac, dmac, vlan_id * cm_av - added smac and vlan_id For the path record structure, extra care was taken to avoid the new fields when packing it into wire format, so we don't break the IB CM and SA wire protocol. On the active side, the CM fills. its internal structures from the path provided by the ULP. We add there taking the ETH L2 attributes and placing them into the CM Address Handle (struct cm_av). On the passive side, the CM fills its internal structures from the WC associated with the REQ message. We add there taking the ETH L2 attributes from the WC. When the HW driver provides the required ETH L2 attributes in the WC, they set the IB_WC_WITH_SMAC and IB_WC_WITH_VLAN flags. The IB core code checks for the presence of these flags, and in their absence does address resolution from the ib_init_ah_from_wc() helper function. ib_modify_qp_is_ok is also updated to consider the link layer. Some parameters are mandatory for Ethernet link layer, while they are irrelevant for IB. Vendor drivers are modified to support the new function signature. Signed-off-by: Matan Barak <matanb@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/core/verbs.c')
-rw-r--r--drivers/infiniband/core/verbs.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index d4f6ddf72ffa..7978394738a3 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -44,6 +44,7 @@
44 44
45#include <rdma/ib_verbs.h> 45#include <rdma/ib_verbs.h>
46#include <rdma/ib_cache.h> 46#include <rdma/ib_cache.h>
47#include <rdma/ib_addr.h>
47 48
48int ib_rate_to_mult(enum ib_rate rate) 49int ib_rate_to_mult(enum ib_rate rate)
49{ 50{
@@ -192,8 +193,28 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
192 u32 flow_class; 193 u32 flow_class;
193 u16 gid_index; 194 u16 gid_index;
194 int ret; 195 int ret;
196 int is_eth = (rdma_port_get_link_layer(device, port_num) ==
197 IB_LINK_LAYER_ETHERNET);
195 198
196 memset(ah_attr, 0, sizeof *ah_attr); 199 memset(ah_attr, 0, sizeof *ah_attr);
200 if (is_eth) {
201 if (!(wc->wc_flags & IB_WC_GRH))
202 return -EPROTOTYPE;
203
204 if (wc->wc_flags & IB_WC_WITH_SMAC &&
205 wc->wc_flags & IB_WC_WITH_VLAN) {
206 memcpy(ah_attr->dmac, wc->smac, ETH_ALEN);
207 ah_attr->vlan_id = wc->vlan_id;
208 } else {
209 ret = rdma_addr_find_dmac_by_grh(&grh->dgid, &grh->sgid,
210 ah_attr->dmac, &ah_attr->vlan_id);
211 if (ret)
212 return ret;
213 }
214 } else {
215 ah_attr->vlan_id = 0xffff;
216 }
217
197 ah_attr->dlid = wc->slid; 218 ah_attr->dlid = wc->slid;
198 ah_attr->sl = wc->sl; 219 ah_attr->sl = wc->sl;
199 ah_attr->src_path_bits = wc->dlid_path_bits; 220 ah_attr->src_path_bits = wc->dlid_path_bits;
@@ -476,7 +497,9 @@ EXPORT_SYMBOL(ib_create_qp);
476static const struct { 497static const struct {
477 int valid; 498 int valid;
478 enum ib_qp_attr_mask req_param[IB_QPT_MAX]; 499 enum ib_qp_attr_mask req_param[IB_QPT_MAX];
500 enum ib_qp_attr_mask req_param_add_eth[IB_QPT_MAX];
479 enum ib_qp_attr_mask opt_param[IB_QPT_MAX]; 501 enum ib_qp_attr_mask opt_param[IB_QPT_MAX];
502 enum ib_qp_attr_mask opt_param_add_eth[IB_QPT_MAX];
480} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { 503} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
481 [IB_QPS_RESET] = { 504 [IB_QPS_RESET] = {
482 [IB_QPS_RESET] = { .valid = 1 }, 505 [IB_QPS_RESET] = { .valid = 1 },
@@ -557,6 +580,12 @@ static const struct {
557 IB_QP_MAX_DEST_RD_ATOMIC | 580 IB_QP_MAX_DEST_RD_ATOMIC |
558 IB_QP_MIN_RNR_TIMER), 581 IB_QP_MIN_RNR_TIMER),
559 }, 582 },
583 .req_param_add_eth = {
584 [IB_QPT_RC] = (IB_QP_SMAC),
585 [IB_QPT_UC] = (IB_QP_SMAC),
586 [IB_QPT_XRC_INI] = (IB_QP_SMAC),
587 [IB_QPT_XRC_TGT] = (IB_QP_SMAC)
588 },
560 .opt_param = { 589 .opt_param = {
561 [IB_QPT_UD] = (IB_QP_PKEY_INDEX | 590 [IB_QPT_UD] = (IB_QP_PKEY_INDEX |
562 IB_QP_QKEY), 591 IB_QP_QKEY),
@@ -576,7 +605,21 @@ static const struct {
576 IB_QP_QKEY), 605 IB_QP_QKEY),
577 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 606 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX |
578 IB_QP_QKEY), 607 IB_QP_QKEY),
579 } 608 },
609 .opt_param_add_eth = {
610 [IB_QPT_RC] = (IB_QP_ALT_SMAC |
611 IB_QP_VID |
612 IB_QP_ALT_VID),
613 [IB_QPT_UC] = (IB_QP_ALT_SMAC |
614 IB_QP_VID |
615 IB_QP_ALT_VID),
616 [IB_QPT_XRC_INI] = (IB_QP_ALT_SMAC |
617 IB_QP_VID |
618 IB_QP_ALT_VID),
619 [IB_QPT_XRC_TGT] = (IB_QP_ALT_SMAC |
620 IB_QP_VID |
621 IB_QP_ALT_VID)
622 }
580 } 623 }
581 }, 624 },
582 [IB_QPS_RTR] = { 625 [IB_QPS_RTR] = {
@@ -779,7 +822,8 @@ static const struct {
779}; 822};
780 823
781int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state, 824int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
782 enum ib_qp_type type, enum ib_qp_attr_mask mask) 825 enum ib_qp_type type, enum ib_qp_attr_mask mask,
826 enum rdma_link_layer ll)
783{ 827{
784 enum ib_qp_attr_mask req_param, opt_param; 828 enum ib_qp_attr_mask req_param, opt_param;
785 829
@@ -798,6 +842,13 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
798 req_param = qp_state_table[cur_state][next_state].req_param[type]; 842 req_param = qp_state_table[cur_state][next_state].req_param[type];
799 opt_param = qp_state_table[cur_state][next_state].opt_param[type]; 843 opt_param = qp_state_table[cur_state][next_state].opt_param[type];
800 844
845 if (ll == IB_LINK_LAYER_ETHERNET) {
846 req_param |= qp_state_table[cur_state][next_state].
847 req_param_add_eth[type];
848 opt_param |= qp_state_table[cur_state][next_state].
849 opt_param_add_eth[type];
850 }
851
801 if ((mask & req_param) != req_param) 852 if ((mask & req_param) != req_param)
802 return 0; 853 return 0;
803 854