@@ -60,6 +60,11 @@ static int irdma_query_device(struct ib_device *ibdev,
6060 props -> max_srq = rf -> max_srq - rf -> used_srqs ;
6161 props -> max_srq_wr = IRDMA_MAX_SRQ_WRS ;
6262 props -> max_srq_sge = hw_attrs -> uk_attrs .max_hw_wq_frags ;
63+ if (hw_attrs -> uk_attrs .feature_flags & IRDMA_FEATURE_ATOMIC_OPS )
64+ props -> atomic_cap = IB_ATOMIC_HCA ;
65+ else
66+ props -> atomic_cap = IB_ATOMIC_NONE ;
67+ props -> masked_atomic_cap = props -> atomic_cap ;
6368 if (hw_attrs -> uk_attrs .hw_rev >= IRDMA_GEN_3 ) {
6469#define HCA_CORE_CLOCK_KHZ 1000000UL
6570 props -> timestamp_mask = GENMASK (31 , 0 );
@@ -1145,13 +1150,17 @@ static int irdma_get_ib_acc_flags(struct irdma_qp *iwqp)
11451150 acc_flags |= IB_ACCESS_REMOTE_READ ;
11461151 if (iwqp -> roce_info .bind_en )
11471152 acc_flags |= IB_ACCESS_MW_BIND ;
1153+ if (iwqp -> ctx_info .remote_atomics_en )
1154+ acc_flags |= IB_ACCESS_REMOTE_ATOMIC ;
11481155 } else {
11491156 if (iwqp -> iwarp_info .wr_rdresp_en ) {
11501157 acc_flags |= IB_ACCESS_LOCAL_WRITE ;
11511158 acc_flags |= IB_ACCESS_REMOTE_WRITE ;
11521159 }
11531160 if (iwqp -> iwarp_info .rd_en )
11541161 acc_flags |= IB_ACCESS_REMOTE_READ ;
1162+ if (iwqp -> ctx_info .remote_atomics_en )
1163+ acc_flags |= IB_ACCESS_REMOTE_ATOMIC ;
11551164 }
11561165 return acc_flags ;
11571166}
@@ -1448,6 +1457,9 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
14481457 roce_info -> wr_rdresp_en = true;
14491458 if (attr -> qp_access_flags & IB_ACCESS_REMOTE_READ )
14501459 roce_info -> rd_en = true;
1460+ if (dev -> hw_attrs .uk_attrs .feature_flags & IRDMA_FEATURE_ATOMIC_OPS )
1461+ if (attr -> qp_access_flags & IB_ACCESS_REMOTE_ATOMIC )
1462+ ctx_info -> remote_atomics_en = true;
14511463 }
14521464
14531465 wait_event (iwqp -> mod_qp_waitq , !atomic_read (& iwqp -> hw_mod_qp_pend ));
@@ -3250,6 +3262,8 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
32503262 stag_info -> total_len = iwmr -> len ;
32513263 stag_info -> access_rights = irdma_get_mr_access (access ,
32523264 iwdev -> rf -> sc_dev .hw_attrs .uk_attrs .hw_rev );
3265+ if (iwdev -> rf -> sc_dev .hw_attrs .uk_attrs .feature_flags & IRDMA_FEATURE_ATOMIC_OPS )
3266+ stag_info -> remote_atomics_en = (access & IB_ACCESS_REMOTE_ATOMIC ) ? 1 : 0 ;
32533267 stag_info -> pd_id = iwpd -> sc_pd .pd_id ;
32543268 stag_info -> all_memory = pd -> flags & IB_PD_UNSAFE_GLOBAL_RKEY ;
32553269 if (stag_info -> access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED )
@@ -3949,6 +3963,40 @@ static int irdma_post_send(struct ib_qp *ibqp,
39493963 if (ib_wr -> send_flags & IB_SEND_FENCE )
39503964 info .read_fence = true;
39513965 switch (ib_wr -> opcode ) {
3966+ case IB_WR_ATOMIC_CMP_AND_SWP :
3967+ if (unlikely (!(dev -> hw_attrs .uk_attrs .feature_flags &
3968+ IRDMA_FEATURE_ATOMIC_OPS ))) {
3969+ err = EINVAL ;
3970+ break ;
3971+ }
3972+ info .op_type = IRDMA_OP_TYPE_ATOMIC_COMPARE_AND_SWAP ;
3973+ info .op .atomic_compare_swap .tagged_offset = ib_wr -> sg_list [0 ].addr ;
3974+ info .op .atomic_compare_swap .remote_tagged_offset =
3975+ atomic_wr (ib_wr )-> remote_addr ;
3976+ info .op .atomic_compare_swap .swap_data_bytes = atomic_wr (ib_wr )-> swap ;
3977+ info .op .atomic_compare_swap .compare_data_bytes =
3978+ atomic_wr (ib_wr )-> compare_add ;
3979+ info .op .atomic_compare_swap .stag = ib_wr -> sg_list [0 ].lkey ;
3980+ info .op .atomic_compare_swap .remote_stag = atomic_wr (ib_wr )-> rkey ;
3981+ err = irdma_uk_atomic_compare_swap (ukqp , & info , false);
3982+ break ;
3983+ case IB_WR_ATOMIC_FETCH_AND_ADD :
3984+ if (unlikely (!(dev -> hw_attrs .uk_attrs .feature_flags &
3985+ IRDMA_FEATURE_ATOMIC_OPS ))) {
3986+ err = EINVAL ;
3987+ break ;
3988+ }
3989+ info .op_type = IRDMA_OP_TYPE_ATOMIC_FETCH_AND_ADD ;
3990+ info .op .atomic_fetch_add .tagged_offset = ib_wr -> sg_list [0 ].addr ;
3991+ info .op .atomic_fetch_add .remote_tagged_offset =
3992+ atomic_wr (ib_wr )-> remote_addr ;
3993+ info .op .atomic_fetch_add .fetch_add_data_bytes =
3994+ atomic_wr (ib_wr )-> compare_add ;
3995+ info .op .atomic_fetch_add .stag = ib_wr -> sg_list [0 ].lkey ;
3996+ info .op .atomic_fetch_add .remote_stag =
3997+ atomic_wr (ib_wr )-> rkey ;
3998+ err = irdma_uk_atomic_fetch_add (ukqp , & info , false);
3999+ break ;
39524000 case IB_WR_SEND_WITH_IMM :
39534001 if (ukqp -> qp_caps & IRDMA_SEND_WITH_IMM ) {
39544002 info .imm_data_valid = true;
0 commit comments