@@ -194,6 +194,22 @@ struct errcode {
194
194
int common_errno ;
195
195
};
196
196
197
+ static void hclge_cmd_copy_desc (struct hclge_hw * hw , struct hclge_desc * desc ,
198
+ int num )
199
+ {
200
+ struct hclge_desc * desc_to_use ;
201
+ int handle = 0 ;
202
+
203
+ while (handle < num ) {
204
+ desc_to_use = & hw -> cmq .csq .desc [hw -> cmq .csq .next_to_use ];
205
+ * desc_to_use = desc [handle ];
206
+ (hw -> cmq .csq .next_to_use )++ ;
207
+ if (hw -> cmq .csq .next_to_use >= hw -> cmq .csq .desc_num )
208
+ hw -> cmq .csq .next_to_use = 0 ;
209
+ handle ++ ;
210
+ }
211
+ }
212
+
197
213
static int hclge_cmd_convert_err_code (u16 desc_ret )
198
214
{
199
215
struct errcode hclge_cmd_errcode [] = {
@@ -243,6 +259,44 @@ static int hclge_cmd_check_retval(struct hclge_hw *hw, struct hclge_desc *desc,
243
259
return hclge_cmd_convert_err_code (desc_ret );
244
260
}
245
261
262
+ static int hclge_cmd_check_result (struct hclge_hw * hw , struct hclge_desc * desc ,
263
+ int num , int ntc )
264
+ {
265
+ struct hclge_dev * hdev = container_of (hw , struct hclge_dev , hw );
266
+ bool is_completed = false;
267
+ u32 timeout = 0 ;
268
+ int handle , ret ;
269
+
270
+ /**
271
+ * If the command is sync, wait for the firmware to write back,
272
+ * if multi descriptors to be sent, use the first one to check
273
+ */
274
+ if (HCLGE_SEND_SYNC (le16_to_cpu (desc -> flag ))) {
275
+ do {
276
+ if (hclge_cmd_csq_done (hw )) {
277
+ is_completed = true;
278
+ break ;
279
+ }
280
+ udelay (1 );
281
+ timeout ++ ;
282
+ } while (timeout < hw -> cmq .tx_timeout );
283
+ }
284
+
285
+ if (!is_completed )
286
+ ret = - EBADE ;
287
+ else
288
+ ret = hclge_cmd_check_retval (hw , desc , num , ntc );
289
+
290
+ /* Clean the command send queue */
291
+ handle = hclge_cmd_csq_clean (hw );
292
+ if (handle < 0 )
293
+ ret = handle ;
294
+ else if (handle != num )
295
+ dev_warn (& hdev -> pdev -> dev ,
296
+ "cleaned %d, need to clean %d\n" , handle , num );
297
+ return ret ;
298
+ }
299
+
246
300
/**
247
301
* hclge_cmd_send - send command to command queue
248
302
* @hw: pointer to the hw struct
@@ -256,11 +310,7 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
256
310
{
257
311
struct hclge_dev * hdev = container_of (hw , struct hclge_dev , hw );
258
312
struct hclge_cmq_ring * csq = & hw -> cmq .csq ;
259
- struct hclge_desc * desc_to_use ;
260
- bool complete = false;
261
- u32 timeout = 0 ;
262
- int handle = 0 ;
263
- int retval ;
313
+ int ret ;
264
314
int ntc ;
265
315
266
316
spin_lock_bh (& hw -> cmq .csq .lock );
@@ -284,49 +334,17 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num)
284
334
* which will be use for hardware to write back
285
335
*/
286
336
ntc = hw -> cmq .csq .next_to_use ;
287
- while (handle < num ) {
288
- desc_to_use = & hw -> cmq .csq .desc [hw -> cmq .csq .next_to_use ];
289
- * desc_to_use = desc [handle ];
290
- (hw -> cmq .csq .next_to_use )++ ;
291
- if (hw -> cmq .csq .next_to_use >= hw -> cmq .csq .desc_num )
292
- hw -> cmq .csq .next_to_use = 0 ;
293
- handle ++ ;
294
- }
337
+
338
+ hclge_cmd_copy_desc (hw , desc , num );
295
339
296
340
/* Write to hardware */
297
341
hclge_write_dev (hw , HCLGE_NIC_CSQ_TAIL_REG , hw -> cmq .csq .next_to_use );
298
342
299
- /**
300
- * If the command is sync, wait for the firmware to write back,
301
- * if multi descriptors to be sent, use the first one to check
302
- */
303
- if (HCLGE_SEND_SYNC (le16_to_cpu (desc -> flag ))) {
304
- do {
305
- if (hclge_cmd_csq_done (hw )) {
306
- complete = true;
307
- break ;
308
- }
309
- udelay (1 );
310
- timeout ++ ;
311
- } while (timeout < hw -> cmq .tx_timeout );
312
- }
313
-
314
- if (!complete )
315
- retval = - EBADE ;
316
- else
317
- retval = hclge_cmd_check_retval (hw , desc , num , ntc );
318
-
319
- /* Clean the command send queue */
320
- handle = hclge_cmd_csq_clean (hw );
321
- if (handle < 0 )
322
- retval = handle ;
323
- else if (handle != num )
324
- dev_warn (& hdev -> pdev -> dev ,
325
- "cleaned %d, need to clean %d\n" , handle , num );
343
+ ret = hclge_cmd_check_result (hw , desc , num , ntc );
326
344
327
345
spin_unlock_bh (& hw -> cmq .csq .lock );
328
346
329
- return retval ;
347
+ return ret ;
330
348
}
331
349
332
350
static void hclge_set_default_capability (struct hclge_dev * hdev )
0 commit comments