@@ -54,6 +54,18 @@ static void set_data_seg_v2(struct hns_roce_v2_wqe_data_seg *dseg,
54
54
dseg -> len = cpu_to_le32 (sg -> length );
55
55
}
56
56
57
+ static void set_atomic_seg (struct hns_roce_wqe_atomic_seg * aseg ,
58
+ const struct ib_atomic_wr * wr )
59
+ {
60
+ if (wr -> wr .opcode == IB_WR_ATOMIC_CMP_AND_SWP ) {
61
+ aseg -> fetchadd_swap_data = cpu_to_le64 (wr -> swap );
62
+ aseg -> cmp_data = cpu_to_le64 (wr -> compare_add );
63
+ } else {
64
+ aseg -> fetchadd_swap_data = cpu_to_le64 (wr -> compare_add );
65
+ aseg -> cmp_data = 0 ;
66
+ }
67
+ }
68
+
57
69
static void set_extend_sge (struct hns_roce_qp * qp , const struct ib_send_wr * wr ,
58
70
unsigned int * sge_ind )
59
71
{
@@ -179,6 +191,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp,
179
191
struct hns_roce_v2_ud_send_wqe * ud_sq_wqe ;
180
192
struct hns_roce_v2_rc_send_wqe * rc_sq_wqe ;
181
193
struct hns_roce_qp * qp = to_hr_qp (ibqp );
194
+ struct hns_roce_v2_wqe_data_seg * dseg ;
182
195
struct device * dev = hr_dev -> dev ;
183
196
struct hns_roce_v2_db sq_db ;
184
197
struct ib_qp_attr attr ;
@@ -407,6 +420,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp,
407
420
roce_set_bit (rc_sq_wqe -> byte_4 ,
408
421
V2_RC_SEND_WQE_BYTE_4_OWNER_S , owner_bit );
409
422
423
+ wqe += sizeof (struct hns_roce_v2_rc_send_wqe );
410
424
switch (wr -> opcode ) {
411
425
case IB_WR_RDMA_READ :
412
426
hr_op = HNS_ROCE_V2_WQE_OP_RDMA_READ ;
@@ -443,9 +457,21 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp,
443
457
break ;
444
458
case IB_WR_ATOMIC_CMP_AND_SWP :
445
459
hr_op = HNS_ROCE_V2_WQE_OP_ATOM_CMP_AND_SWAP ;
460
+ rc_sq_wqe -> rkey =
461
+ cpu_to_le32 (atomic_wr (wr )-> rkey );
462
+ rc_sq_wqe -> va =
463
+ cpu_to_le32 (atomic_wr (wr )-> remote_addr );
464
+ wqe += sizeof (struct hns_roce_v2_wqe_data_seg );
465
+ set_atomic_seg (wqe , atomic_wr (wr ));
446
466
break ;
447
467
case IB_WR_ATOMIC_FETCH_AND_ADD :
448
468
hr_op = HNS_ROCE_V2_WQE_OP_ATOM_FETCH_AND_ADD ;
469
+ rc_sq_wqe -> rkey =
470
+ cpu_to_le32 (atomic_wr (wr )-> rkey );
471
+ rc_sq_wqe -> va =
472
+ cpu_to_le32 (atomic_wr (wr )-> remote_addr );
473
+ wqe += sizeof (struct hns_roce_v2_wqe_data_seg );
474
+ set_atomic_seg (wqe , atomic_wr (wr ));
449
475
break ;
450
476
case IB_WR_MASKED_ATOMIC_CMP_AND_SWP :
451
477
hr_op =
@@ -463,7 +489,12 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp,
463
489
roce_set_field (rc_sq_wqe -> byte_4 ,
464
490
V2_RC_SEND_WQE_BYTE_4_OPCODE_M ,
465
491
V2_RC_SEND_WQE_BYTE_4_OPCODE_S , hr_op );
466
- wqe += sizeof (struct hns_roce_v2_rc_send_wqe );
492
+ if (wr -> opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
493
+ wr -> opcode == IB_WR_ATOMIC_FETCH_AND_ADD )
494
+ dseg =
495
+ wqe - sizeof (struct hns_roce_v2_wqe_data_seg );
496
+ else
497
+ dseg = wqe ;
467
498
468
499
ret = set_rwqe_data_seg (ibqp , wr , rc_sq_wqe , wqe ,
469
500
& sge_ind , bad_wr );
@@ -1232,6 +1263,9 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
1232
1263
caps -> local_ca_ack_delay = 0 ;
1233
1264
caps -> max_mtu = IB_MTU_4096 ;
1234
1265
1266
+ if (hr_dev -> pci_dev -> revision == 0x21 )
1267
+ caps -> flags |= HNS_ROCE_CAP_FLAG_ATOMIC ;
1268
+
1235
1269
ret = hns_roce_v2_set_bt (hr_dev );
1236
1270
if (ret )
1237
1271
dev_err (hr_dev -> dev , "Configure bt attribute fail, ret = %d.\n" ,
@@ -1663,7 +1697,8 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
1663
1697
roce_set_bit (mpt_entry -> byte_8_mw_cnt_en , V2_MPT_BYTE_8_L_INV_EN_S , 0 );
1664
1698
roce_set_bit (mpt_entry -> byte_8_mw_cnt_en , V2_MPT_BYTE_8_BIND_EN_S ,
1665
1699
(mr -> access & IB_ACCESS_MW_BIND ? 1 : 0 ));
1666
- roce_set_bit (mpt_entry -> byte_8_mw_cnt_en , V2_MPT_BYTE_8_ATOMIC_EN_S , 0 );
1700
+ roce_set_bit (mpt_entry -> byte_8_mw_cnt_en , V2_MPT_BYTE_8_ATOMIC_EN_S ,
1701
+ mr -> access & IB_ACCESS_REMOTE_ATOMIC ? 1 : 0 );
1667
1702
roce_set_bit (mpt_entry -> byte_8_mw_cnt_en , V2_MPT_BYTE_8_RR_EN_S ,
1668
1703
(mr -> access & IB_ACCESS_REMOTE_READ ? 1 : 0 ));
1669
1704
roce_set_bit (mpt_entry -> byte_8_mw_cnt_en , V2_MPT_BYTE_8_RW_EN_S ,
0 commit comments