@@ -181,6 +181,22 @@ struct vf_errcode {
181
181
int common_errno ;
182
182
};
183
183
184
+ static void hclgevf_cmd_copy_desc (struct hclgevf_hw * hw ,
185
+ struct hclgevf_desc * desc , int num )
186
+ {
187
+ struct hclgevf_desc * desc_to_use ;
188
+ int handle = 0 ;
189
+
190
+ while (handle < num ) {
191
+ desc_to_use = & hw -> cmq .csq .desc [hw -> cmq .csq .next_to_use ];
192
+ * desc_to_use = desc [handle ];
193
+ (hw -> cmq .csq .next_to_use )++ ;
194
+ if (hw -> cmq .csq .next_to_use == hw -> cmq .csq .desc_num )
195
+ hw -> cmq .csq .next_to_use = 0 ;
196
+ handle ++ ;
197
+ }
198
+ }
199
+
184
200
static int hclgevf_cmd_convert_err_code (u16 desc_ret )
185
201
{
186
202
struct vf_errcode hclgevf_cmd_errcode [] = {
@@ -207,6 +223,66 @@ static int hclgevf_cmd_convert_err_code(u16 desc_ret)
207
223
return - EIO ;
208
224
}
209
225
226
+ static int hclgevf_cmd_check_retval (struct hclgevf_hw * hw ,
227
+ struct hclgevf_desc * desc , int num , int ntc )
228
+ {
229
+ u16 opcode , desc_ret ;
230
+ int handle ;
231
+
232
+ opcode = le16_to_cpu (desc [0 ].opcode );
233
+ for (handle = 0 ; handle < num ; handle ++ ) {
234
+ /* Get the result of hardware write back */
235
+ desc [handle ] = hw -> cmq .csq .desc [ntc ];
236
+ ntc ++ ;
237
+ if (ntc == hw -> cmq .csq .desc_num )
238
+ ntc = 0 ;
239
+ }
240
+ if (likely (!hclgevf_is_special_opcode (opcode )))
241
+ desc_ret = le16_to_cpu (desc [num - 1 ].retval );
242
+ else
243
+ desc_ret = le16_to_cpu (desc [0 ].retval );
244
+ hw -> cmq .last_status = desc_ret ;
245
+
246
+ return hclgevf_cmd_convert_err_code (desc_ret );
247
+ }
248
+
249
+ static int hclgevf_cmd_check_result (struct hclgevf_hw * hw ,
250
+ struct hclgevf_desc * desc , int num , int ntc )
251
+ {
252
+ struct hclgevf_dev * hdev = (struct hclgevf_dev * )hw -> hdev ;
253
+ bool is_completed = false;
254
+ u32 timeout = 0 ;
255
+ int handle , ret ;
256
+
257
+ /* If the command is sync, wait for the firmware to write back,
258
+ * if multi descriptors to be sent, use the first one to check
259
+ */
260
+ if (HCLGEVF_SEND_SYNC (le16_to_cpu (desc -> flag ))) {
261
+ do {
262
+ if (hclgevf_cmd_csq_done (hw )) {
263
+ is_completed = true;
264
+ break ;
265
+ }
266
+ udelay (1 );
267
+ timeout ++ ;
268
+ } while (timeout < hw -> cmq .tx_timeout );
269
+ }
270
+
271
+ if (!is_completed )
272
+ ret = - EBADE ;
273
+ else
274
+ ret = hclgevf_cmd_check_retval (hw , desc , num , ntc );
275
+
276
+ /* Clean the command send queue */
277
+ handle = hclgevf_cmd_csq_clean (hw );
278
+ if (handle < 0 )
279
+ ret = handle ;
280
+ else if (handle != num )
281
+ dev_warn (& hdev -> pdev -> dev ,
282
+ "cleaned %d, need to clean %d\n" , handle , num );
283
+ return ret ;
284
+ }
285
+
210
286
/* hclgevf_cmd_send - send command to command queue
211
287
* @hw: pointer to the hw struct
212
288
* @desc: prefilled descriptor for describing the command
@@ -219,13 +295,7 @@ int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclgevf_desc *desc, int num)
219
295
{
220
296
struct hclgevf_dev * hdev = (struct hclgevf_dev * )hw -> hdev ;
221
297
struct hclgevf_cmq_ring * csq = & hw -> cmq .csq ;
222
- struct hclgevf_desc * desc_to_use ;
223
- bool complete = false;
224
- u32 timeout = 0 ;
225
- int handle = 0 ;
226
- int status = 0 ;
227
- u16 retval ;
228
- u16 opcode ;
298
+ int ret ;
229
299
int ntc ;
230
300
231
301
spin_lock_bh (& hw -> cmq .csq .lock );
@@ -249,67 +319,18 @@ int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclgevf_desc *desc, int num)
249
319
* which will be use for hardware to write back
250
320
*/
251
321
ntc = hw -> cmq .csq .next_to_use ;
252
- opcode = le16_to_cpu (desc [0 ].opcode );
253
- while (handle < num ) {
254
- desc_to_use = & hw -> cmq .csq .desc [hw -> cmq .csq .next_to_use ];
255
- * desc_to_use = desc [handle ];
256
- (hw -> cmq .csq .next_to_use )++ ;
257
- if (hw -> cmq .csq .next_to_use == hw -> cmq .csq .desc_num )
258
- hw -> cmq .csq .next_to_use = 0 ;
259
- handle ++ ;
260
- }
322
+
323
+ hclgevf_cmd_copy_desc (hw , desc , num );
261
324
262
325
/* Write to hardware */
263
326
hclgevf_write_dev (hw , HCLGEVF_NIC_CSQ_TAIL_REG ,
264
327
hw -> cmq .csq .next_to_use );
265
328
266
- /* If the command is sync, wait for the firmware to write back,
267
- * if multi descriptors to be sent, use the first one to check
268
- */
269
- if (HCLGEVF_SEND_SYNC (le16_to_cpu (desc -> flag ))) {
270
- do {
271
- if (hclgevf_cmd_csq_done (hw ))
272
- break ;
273
- udelay (1 );
274
- timeout ++ ;
275
- } while (timeout < hw -> cmq .tx_timeout );
276
- }
277
-
278
- if (hclgevf_cmd_csq_done (hw )) {
279
- complete = true;
280
- handle = 0 ;
281
-
282
- while (handle < num ) {
283
- /* Get the result of hardware write back */
284
- desc_to_use = & hw -> cmq .csq .desc [ntc ];
285
- desc [handle ] = * desc_to_use ;
286
-
287
- if (likely (!hclgevf_is_special_opcode (opcode )))
288
- retval = le16_to_cpu (desc [handle ].retval );
289
- else
290
- retval = le16_to_cpu (desc [0 ].retval );
291
-
292
- status = hclgevf_cmd_convert_err_code (retval );
293
- hw -> cmq .last_status = (enum hclgevf_cmd_status )retval ;
294
- ntc ++ ;
295
- handle ++ ;
296
- if (ntc == hw -> cmq .csq .desc_num )
297
- ntc = 0 ;
298
- }
299
- }
300
-
301
- if (!complete )
302
- status = - EBADE ;
303
-
304
- /* Clean the command send queue */
305
- handle = hclgevf_cmd_csq_clean (hw );
306
- if (handle != num )
307
- dev_warn (& hdev -> pdev -> dev ,
308
- "cleaned %d, need to clean %d\n" , handle , num );
329
+ ret = hclgevf_cmd_check_result (hw , desc , num , ntc );
309
330
310
331
spin_unlock_bh (& hw -> cmq .csq .lock );
311
332
312
- return status ;
333
+ return ret ;
313
334
}
314
335
315
336
static void hclgevf_set_default_capability (struct hclgevf_dev * hdev )
0 commit comments