41
41
#include <linux/export.h>
42
42
#include <linux/string.h>
43
43
#include <linux/slab.h>
44
+ #include <linux/in.h>
45
+ #include <linux/in6.h>
46
+ #include <net/addrconf.h>
44
47
45
48
#include <rdma/ib_verbs.h>
46
49
#include <rdma/ib_cache.h>
@@ -308,6 +311,35 @@ struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
308
311
}
309
312
EXPORT_SYMBOL (ib_create_ah );
310
313
314
+ struct find_gid_index_context {
315
+ u16 vlan_id ;
316
+ };
317
+
318
+ static bool find_gid_index (const union ib_gid * gid ,
319
+ const struct ib_gid_attr * gid_attr ,
320
+ void * context )
321
+ {
322
+ struct find_gid_index_context * ctx =
323
+ (struct find_gid_index_context * )context ;
324
+
325
+ if ((!!(ctx -> vlan_id != 0xffff ) == !is_vlan_dev (gid_attr -> ndev )) ||
326
+ (is_vlan_dev (gid_attr -> ndev ) &&
327
+ vlan_dev_vlan_id (gid_attr -> ndev ) != ctx -> vlan_id ))
328
+ return false;
329
+
330
+ return true;
331
+ }
332
+
333
+ static int get_sgid_index_from_eth (struct ib_device * device , u8 port_num ,
334
+ u16 vlan_id , const union ib_gid * sgid ,
335
+ u16 * gid_index )
336
+ {
337
+ struct find_gid_index_context context = {.vlan_id = vlan_id };
338
+
339
+ return ib_find_gid_by_filter (device , sgid , port_num , find_gid_index ,
340
+ & context , gid_index );
341
+ }
342
+
311
343
int ib_init_ah_from_wc (struct ib_device * device , u8 port_num ,
312
344
const struct ib_wc * wc , const struct ib_grh * grh ,
313
345
struct ib_ah_attr * ah_attr )
@@ -318,21 +350,30 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
318
350
319
351
memset (ah_attr , 0 , sizeof * ah_attr );
320
352
if (rdma_cap_eth_ah (device , port_num )) {
353
+ u16 vlan_id = wc -> wc_flags & IB_WC_WITH_VLAN ?
354
+ wc -> vlan_id : 0xffff ;
355
+
321
356
if (!(wc -> wc_flags & IB_WC_GRH ))
322
357
return - EPROTOTYPE ;
323
358
324
- if (wc -> wc_flags & IB_WC_WITH_SMAC &&
325
- wc -> wc_flags & IB_WC_WITH_VLAN ) {
326
- memcpy (ah_attr -> dmac , wc -> smac , ETH_ALEN );
327
- ah_attr -> vlan_id = wc -> vlan_id ;
328
- } else {
359
+ if (!(wc -> wc_flags & IB_WC_WITH_SMAC ) ||
360
+ !(wc -> wc_flags & IB_WC_WITH_VLAN )) {
329
361
ret = rdma_addr_find_dmac_by_grh (& grh -> dgid , & grh -> sgid ,
330
- ah_attr -> dmac , & ah_attr -> vlan_id );
362
+ ah_attr -> dmac ,
363
+ wc -> wc_flags & IB_WC_WITH_VLAN ?
364
+ NULL : & vlan_id ,
365
+ 0 );
331
366
if (ret )
332
367
return ret ;
333
368
}
334
- } else {
335
- ah_attr -> vlan_id = 0xffff ;
369
+
370
+ ret = get_sgid_index_from_eth (device , port_num , vlan_id ,
371
+ & grh -> dgid , & gid_index );
372
+ if (ret )
373
+ return ret ;
374
+
375
+ if (wc -> wc_flags & IB_WC_WITH_SMAC )
376
+ memcpy (ah_attr -> dmac , wc -> smac , ETH_ALEN );
336
377
}
337
378
338
379
ah_attr -> dlid = wc -> slid ;
@@ -344,10 +385,13 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
344
385
ah_attr -> ah_flags = IB_AH_GRH ;
345
386
ah_attr -> grh .dgid = grh -> sgid ;
346
387
347
- ret = ib_find_cached_gid (device , & grh -> dgid ,
348
- NULL , & port_num , & gid_index );
349
- if (ret )
350
- return ret ;
388
+ if (!rdma_cap_eth_ah (device , port_num )) {
389
+ ret = ib_find_cached_gid_by_port (device , & grh -> dgid ,
390
+ port_num , NULL ,
391
+ & gid_index );
392
+ if (ret )
393
+ return ret ;
394
+ }
351
395
352
396
ah_attr -> grh .sgid_index = (u8 ) gid_index ;
353
397
flow_class = be32_to_cpu (grh -> version_tclass_flow );
@@ -617,9 +661,7 @@ EXPORT_SYMBOL(ib_create_qp);
617
661
static const struct {
618
662
int valid ;
619
663
enum ib_qp_attr_mask req_param [IB_QPT_MAX ];
620
- enum ib_qp_attr_mask req_param_add_eth [IB_QPT_MAX ];
621
664
enum ib_qp_attr_mask opt_param [IB_QPT_MAX ];
622
- enum ib_qp_attr_mask opt_param_add_eth [IB_QPT_MAX ];
623
665
} qp_state_table [IB_QPS_ERR + 1 ][IB_QPS_ERR + 1 ] = {
624
666
[IB_QPS_RESET ] = {
625
667
[IB_QPS_RESET ] = { .valid = 1 },
@@ -700,12 +742,6 @@ static const struct {
700
742
IB_QP_MAX_DEST_RD_ATOMIC |
701
743
IB_QP_MIN_RNR_TIMER ),
702
744
},
703
- .req_param_add_eth = {
704
- [IB_QPT_RC ] = (IB_QP_SMAC ),
705
- [IB_QPT_UC ] = (IB_QP_SMAC ),
706
- [IB_QPT_XRC_INI ] = (IB_QP_SMAC ),
707
- [IB_QPT_XRC_TGT ] = (IB_QP_SMAC )
708
- },
709
745
.opt_param = {
710
746
[IB_QPT_UD ] = (IB_QP_PKEY_INDEX |
711
747
IB_QP_QKEY ),
@@ -726,21 +762,7 @@ static const struct {
726
762
[IB_QPT_GSI ] = (IB_QP_PKEY_INDEX |
727
763
IB_QP_QKEY ),
728
764
},
729
- .opt_param_add_eth = {
730
- [IB_QPT_RC ] = (IB_QP_ALT_SMAC |
731
- IB_QP_VID |
732
- IB_QP_ALT_VID ),
733
- [IB_QPT_UC ] = (IB_QP_ALT_SMAC |
734
- IB_QP_VID |
735
- IB_QP_ALT_VID ),
736
- [IB_QPT_XRC_INI ] = (IB_QP_ALT_SMAC |
737
- IB_QP_VID |
738
- IB_QP_ALT_VID ),
739
- [IB_QPT_XRC_TGT ] = (IB_QP_ALT_SMAC |
740
- IB_QP_VID |
741
- IB_QP_ALT_VID )
742
- }
743
- }
765
+ },
744
766
},
745
767
[IB_QPS_RTR ] = {
746
768
[IB_QPS_RESET ] = { .valid = 1 },
@@ -962,13 +984,6 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
962
984
req_param = qp_state_table [cur_state ][next_state ].req_param [type ];
963
985
opt_param = qp_state_table [cur_state ][next_state ].opt_param [type ];
964
986
965
- if (ll == IB_LINK_LAYER_ETHERNET ) {
966
- req_param |= qp_state_table [cur_state ][next_state ].
967
- req_param_add_eth [type ];
968
- opt_param |= qp_state_table [cur_state ][next_state ].
969
- opt_param_add_eth [type ];
970
- }
971
-
972
987
if ((mask & req_param ) != req_param )
973
988
return 0 ;
974
989
@@ -979,41 +994,52 @@ int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
979
994
}
980
995
EXPORT_SYMBOL (ib_modify_qp_is_ok );
981
996
982
- int ib_resolve_eth_l2_attrs (struct ib_qp * qp ,
983
- struct ib_qp_attr * qp_attr , int * qp_attr_mask )
997
+ int ib_resolve_eth_dmac (struct ib_qp * qp ,
998
+ struct ib_qp_attr * qp_attr , int * qp_attr_mask )
984
999
{
985
1000
int ret = 0 ;
986
- union ib_gid sgid ;
987
1001
988
- if ((* qp_attr_mask & IB_QP_AV ) &&
989
- (rdma_cap_eth_ah (qp -> device , qp_attr -> ah_attr .port_num ))) {
990
- ret = ib_query_gid (qp -> device , qp_attr -> ah_attr .port_num ,
991
- qp_attr -> ah_attr .grh .sgid_index , & sgid ,
992
- NULL );
993
- if (ret )
994
- goto out ;
1002
+ if (* qp_attr_mask & IB_QP_AV ) {
1003
+ if (qp_attr -> ah_attr .port_num < rdma_start_port (qp -> device ) ||
1004
+ qp_attr -> ah_attr .port_num > rdma_end_port (qp -> device ))
1005
+ return - EINVAL ;
1006
+
1007
+ if (!rdma_cap_eth_ah (qp -> device , qp_attr -> ah_attr .port_num ))
1008
+ return 0 ;
1009
+
995
1010
if (rdma_link_local_addr ((struct in6_addr * )qp_attr -> ah_attr .grh .dgid .raw )) {
996
- rdma_get_ll_mac ((struct in6_addr * )qp_attr -> ah_attr .grh .dgid .raw , qp_attr -> ah_attr .dmac );
997
- rdma_get_ll_mac ((struct in6_addr * )sgid .raw , qp_attr -> smac );
998
- if (!(* qp_attr_mask & IB_QP_VID ))
999
- qp_attr -> vlan_id = rdma_get_vlan_id (& sgid );
1011
+ rdma_get_ll_mac ((struct in6_addr * )qp_attr -> ah_attr .grh .dgid .raw ,
1012
+ qp_attr -> ah_attr .dmac );
1000
1013
} else {
1001
- ret = rdma_addr_find_dmac_by_grh (& sgid , & qp_attr -> ah_attr .grh .dgid ,
1002
- qp_attr -> ah_attr .dmac , & qp_attr -> vlan_id );
1003
- if (ret )
1004
- goto out ;
1005
- ret = rdma_addr_find_smac_by_sgid (& sgid , qp_attr -> smac , NULL );
1006
- if (ret )
1014
+ union ib_gid sgid ;
1015
+ struct ib_gid_attr sgid_attr ;
1016
+ int ifindex ;
1017
+
1018
+ ret = ib_query_gid (qp -> device ,
1019
+ qp_attr -> ah_attr .port_num ,
1020
+ qp_attr -> ah_attr .grh .sgid_index ,
1021
+ & sgid , & sgid_attr );
1022
+
1023
+ if (ret || !sgid_attr .ndev ) {
1024
+ if (!ret )
1025
+ ret = - ENXIO ;
1007
1026
goto out ;
1027
+ }
1028
+
1029
+ ifindex = sgid_attr .ndev -> ifindex ;
1030
+
1031
+ ret = rdma_addr_find_dmac_by_grh (& sgid ,
1032
+ & qp_attr -> ah_attr .grh .dgid ,
1033
+ qp_attr -> ah_attr .dmac ,
1034
+ NULL , ifindex );
1035
+
1036
+ dev_put (sgid_attr .ndev );
1008
1037
}
1009
- * qp_attr_mask |= IB_QP_SMAC ;
1010
- if (qp_attr -> vlan_id < 0xFFFF )
1011
- * qp_attr_mask |= IB_QP_VID ;
1012
1038
}
1013
1039
out :
1014
1040
return ret ;
1015
1041
}
1016
- EXPORT_SYMBOL (ib_resolve_eth_l2_attrs );
1042
+ EXPORT_SYMBOL (ib_resolve_eth_dmac );
1017
1043
1018
1044
1019
1045
int ib_modify_qp (struct ib_qp * qp ,
@@ -1022,7 +1048,7 @@ int ib_modify_qp(struct ib_qp *qp,
1022
1048
{
1023
1049
int ret ;
1024
1050
1025
- ret = ib_resolve_eth_l2_attrs (qp , qp_attr , & qp_attr_mask );
1051
+ ret = ib_resolve_eth_dmac (qp , qp_attr , & qp_attr_mask );
1026
1052
if (ret )
1027
1053
return ret ;
1028
1054
0 commit comments