@@ -153,6 +153,67 @@ static void set_atomic_seg(const struct ib_send_wr *wr,
153153 V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S , valid_num_sge );
154154}
155155
156+ static int fill_ext_sge_inl_data (struct hns_roce_qp * qp ,
157+ const struct ib_send_wr * wr ,
158+ unsigned int * sge_idx , u32 msg_len )
159+ {
160+ struct ib_device * ibdev = & (to_hr_dev (qp -> ibqp .device ))-> ib_dev ;
161+ unsigned int dseg_len = sizeof (struct hns_roce_v2_wqe_data_seg );
162+ unsigned int ext_sge_sz = qp -> sq .max_gs * dseg_len ;
163+ unsigned int left_len_in_pg ;
164+ unsigned int idx = * sge_idx ;
165+ unsigned int i = 0 ;
166+ unsigned int len ;
167+ void * addr ;
168+ void * dseg ;
169+
170+ if (msg_len > ext_sge_sz ) {
171+ ibdev_err (ibdev ,
172+ "no enough extended sge space for inline data.\n" );
173+ return - EINVAL ;
174+ }
175+
176+ dseg = hns_roce_get_extend_sge (qp , idx & (qp -> sge .sge_cnt - 1 ));
177+ left_len_in_pg = hr_hw_page_align ((uintptr_t )dseg ) - (uintptr_t )dseg ;
178+ len = wr -> sg_list [0 ].length ;
179+ addr = (void * )(unsigned long )(wr -> sg_list [0 ].addr );
180+
181+ /* When copying data to extended sge space, the left length in page may
182+ * not long enough for current user's sge. So the data should be
183+ * splited into several parts, one in the first page, and the others in
184+ * the subsequent pages.
185+ */
186+ while (1 ) {
187+ if (len <= left_len_in_pg ) {
188+ memcpy (dseg , addr , len );
189+
190+ idx += len / dseg_len ;
191+
192+ i ++ ;
193+ if (i >= wr -> num_sge )
194+ break ;
195+
196+ left_len_in_pg -= len ;
197+ len = wr -> sg_list [i ].length ;
198+ addr = (void * )(unsigned long )(wr -> sg_list [i ].addr );
199+ dseg += len ;
200+ } else {
201+ memcpy (dseg , addr , left_len_in_pg );
202+
203+ len -= left_len_in_pg ;
204+ addr += left_len_in_pg ;
205+ idx += left_len_in_pg / dseg_len ;
206+ dseg = hns_roce_get_extend_sge (qp ,
207+ idx & (qp -> sge .sge_cnt - 1 ));
208+ left_len_in_pg = 1 << HNS_HW_PAGE_SHIFT ;
209+ }
210+ }
211+
212+ * sge_idx = idx ;
213+
214+ return 0 ;
215+ }
216+
156217static void set_extend_sge (struct hns_roce_qp * qp , const struct ib_send_wr * wr ,
157218 unsigned int * sge_ind , unsigned int valid_num_sge )
158219{
@@ -177,73 +238,115 @@ static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr,
177238 * sge_ind = idx ;
178239}
179240
241+ static bool check_inl_data_len (struct hns_roce_qp * qp , unsigned int len )
242+ {
243+ struct hns_roce_dev * hr_dev = to_hr_dev (qp -> ibqp .device );
244+ int mtu = ib_mtu_enum_to_int (qp -> path_mtu );
245+
246+ if (len > qp -> max_inline_data || len > mtu ) {
247+ ibdev_err (& hr_dev -> ib_dev ,
248+ "invalid length of data, data len = %u, max inline len = %u, path mtu = %d.\n" ,
249+ len , qp -> max_inline_data , mtu );
250+ return false;
251+ }
252+
253+ return true;
254+ }
255+
256+ static int set_rc_inl (struct hns_roce_qp * qp , const struct ib_send_wr * wr ,
257+ struct hns_roce_v2_rc_send_wqe * rc_sq_wqe ,
258+ unsigned int * sge_idx )
259+ {
260+ struct hns_roce_dev * hr_dev = to_hr_dev (qp -> ibqp .device );
261+ u32 msg_len = le32_to_cpu (rc_sq_wqe -> msg_len );
262+ struct ib_device * ibdev = & hr_dev -> ib_dev ;
263+ unsigned int curr_idx = * sge_idx ;
264+ void * dseg = rc_sq_wqe ;
265+ unsigned int i ;
266+ int ret ;
267+
268+ if (unlikely (wr -> opcode == IB_WR_RDMA_READ )) {
269+ ibdev_err (ibdev , "invalid inline parameters!\n" );
270+ return - EINVAL ;
271+ }
272+
273+ if (!check_inl_data_len (qp , msg_len ))
274+ return - EINVAL ;
275+
276+ dseg += sizeof (struct hns_roce_v2_rc_send_wqe );
277+
278+ roce_set_bit (rc_sq_wqe -> byte_4 , V2_RC_SEND_WQE_BYTE_4_INLINE_S , 1 );
279+
280+ if (msg_len <= HNS_ROCE_V2_MAX_RC_INL_INN_SZ ) {
281+ roce_set_bit (rc_sq_wqe -> byte_20 ,
282+ V2_RC_SEND_WQE_BYTE_20_INL_TYPE_S , 0 );
283+
284+ for (i = 0 ; i < wr -> num_sge ; i ++ ) {
285+ memcpy (dseg , ((void * )wr -> sg_list [i ].addr ),
286+ wr -> sg_list [i ].length );
287+ dseg += wr -> sg_list [i ].length ;
288+ }
289+ } else {
290+ roce_set_bit (rc_sq_wqe -> byte_20 ,
291+ V2_RC_SEND_WQE_BYTE_20_INL_TYPE_S , 1 );
292+
293+ ret = fill_ext_sge_inl_data (qp , wr , & curr_idx , msg_len );
294+ if (ret )
295+ return ret ;
296+
297+ roce_set_field (rc_sq_wqe -> byte_16 ,
298+ V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M ,
299+ V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S ,
300+ curr_idx - * sge_idx );
301+ }
302+
303+ * sge_idx = curr_idx ;
304+
305+ return 0 ;
306+ }
307+
180308static int set_rwqe_data_seg (struct ib_qp * ibqp , const struct ib_send_wr * wr ,
181309 struct hns_roce_v2_rc_send_wqe * rc_sq_wqe ,
182310 unsigned int * sge_ind ,
183311 unsigned int valid_num_sge )
184312{
185- struct hns_roce_dev * hr_dev = to_hr_dev (ibqp -> device );
186313 struct hns_roce_v2_wqe_data_seg * dseg =
187314 (void * )rc_sq_wqe + sizeof (struct hns_roce_v2_rc_send_wqe );
188- struct ib_device * ibdev = & hr_dev -> ib_dev ;
189315 struct hns_roce_qp * qp = to_hr_qp (ibqp );
190- void * wqe = dseg ;
191316 int j = 0 ;
192317 int i ;
193318
194- if (wr -> send_flags & IB_SEND_INLINE && valid_num_sge ) {
195- if (unlikely (le32_to_cpu (rc_sq_wqe -> msg_len ) >
196- hr_dev -> caps .max_sq_inline )) {
197- ibdev_err (ibdev , "inline len(1-%d)=%d, illegal" ,
198- rc_sq_wqe -> msg_len ,
199- hr_dev -> caps .max_sq_inline );
200- return - EINVAL ;
201- }
319+ roce_set_field (rc_sq_wqe -> byte_20 ,
320+ V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M ,
321+ V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S ,
322+ (* sge_ind ) & (qp -> sge .sge_cnt - 1 ));
202323
203- if (unlikely (wr -> opcode == IB_WR_RDMA_READ )) {
204- ibdev_err (ibdev , "Not support inline data!\n" );
205- return - EINVAL ;
206- }
324+ if (wr -> send_flags & IB_SEND_INLINE )
325+ return set_rc_inl (qp , wr , rc_sq_wqe , sge_ind );
207326
327+ if (valid_num_sge <= HNS_ROCE_SGE_IN_WQE ) {
208328 for (i = 0 ; i < wr -> num_sge ; i ++ ) {
209- memcpy (wqe , ((void * )wr -> sg_list [i ].addr ),
210- wr -> sg_list [i ].length );
211- wqe += wr -> sg_list [i ].length ;
329+ if (likely (wr -> sg_list [i ].length )) {
330+ set_data_seg_v2 (dseg , wr -> sg_list + i );
331+ dseg ++ ;
332+ }
212333 }
213-
214- roce_set_bit (rc_sq_wqe -> byte_4 , V2_RC_SEND_WQE_BYTE_4_INLINE_S ,
215- 1 );
216334 } else {
217- if (valid_num_sge <= HNS_ROCE_SGE_IN_WQE ) {
218- for (i = 0 ; i < wr -> num_sge ; i ++ ) {
219- if (likely (wr -> sg_list [i ].length )) {
220- set_data_seg_v2 (dseg , wr -> sg_list + i );
221- dseg ++ ;
222- }
335+ for (i = 0 ; i < wr -> num_sge && j < HNS_ROCE_SGE_IN_WQE ; i ++ ) {
336+ if (likely (wr -> sg_list [i ].length )) {
337+ set_data_seg_v2 (dseg , wr -> sg_list + i );
338+ dseg ++ ;
339+ j ++ ;
223340 }
224- } else {
225- roce_set_field (rc_sq_wqe -> byte_20 ,
226- V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M ,
227- V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S ,
228- (* sge_ind ) & (qp -> sge .sge_cnt - 1 ));
229-
230- for (i = 0 ; i < wr -> num_sge && j < HNS_ROCE_SGE_IN_WQE ;
231- i ++ ) {
232- if (likely (wr -> sg_list [i ].length )) {
233- set_data_seg_v2 (dseg , wr -> sg_list + i );
234- dseg ++ ;
235- j ++ ;
236- }
237- }
238-
239- set_extend_sge (qp , wr , sge_ind , valid_num_sge );
240341 }
241342
242- roce_set_field (rc_sq_wqe -> byte_16 ,
243- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M ,
244- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S , valid_num_sge );
343+ set_extend_sge (qp , wr , sge_ind , valid_num_sge );
245344 }
246345
346+ roce_set_field (rc_sq_wqe -> byte_16 ,
347+ V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M ,
348+ V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S , valid_num_sge );
349+
247350 return 0 ;
248351}
249352
@@ -4154,6 +4257,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
41544257 V2_QPC_BYTE_52_DMAC_S , 0 );
41554258
41564259 mtu = get_mtu (ibqp , attr );
4260+ hr_qp -> path_mtu = mtu ;
41574261
41584262 if (attr_mask & IB_QP_PATH_MTU ) {
41594263 roce_set_field (context -> byte_24_mtu_tc , V2_QPC_BYTE_24_MTU_M ,
0 commit comments