@@ -370,48 +370,89 @@ int hinic_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt,
370
370
MSG_NOT_RESP , timeout );
371
371
}
372
372
373
- /**
374
- * mgmt_recv_msg_handler - handler for message from mgmt cpu
375
- * @pf_to_mgmt: PF to MGMT channel
376
- * @recv_msg: received message details
377
- **/
378
- static void mgmt_recv_msg_handler (struct hinic_pf_to_mgmt * pf_to_mgmt ,
379
- struct hinic_recv_msg * recv_msg )
373
+ static void recv_mgmt_msg_work_handler (struct work_struct * work )
380
374
{
381
- struct hinic_hwif * hwif = pf_to_mgmt -> hwif ;
382
- struct pci_dev * pdev = hwif -> pdev ;
383
- u8 * buf_out = recv_msg -> buf_out ;
375
+ struct hinic_mgmt_msg_handle_work * mgmt_work =
376
+ container_of (work , struct hinic_mgmt_msg_handle_work , work );
377
+ struct hinic_pf_to_mgmt * pf_to_mgmt = mgmt_work -> pf_to_mgmt ;
378
+ struct pci_dev * pdev = pf_to_mgmt -> hwif -> pdev ;
379
+ u8 * buf_out = pf_to_mgmt -> mgmt_ack_buf ;
384
380
struct hinic_mgmt_cb * mgmt_cb ;
385
381
unsigned long cb_state ;
386
382
u16 out_size = 0 ;
387
383
388
- if (recv_msg -> mod >= HINIC_MOD_MAX ) {
384
+ memset (buf_out , 0 , MAX_PF_MGMT_BUF_SIZE );
385
+
386
+ if (mgmt_work -> mod >= HINIC_MOD_MAX ) {
389
387
dev_err (& pdev -> dev , "Unknown MGMT MSG module = %d\n" ,
390
- recv_msg -> mod );
388
+ mgmt_work -> mod );
389
+ kfree (mgmt_work -> msg );
390
+ kfree (mgmt_work );
391
391
return ;
392
392
}
393
393
394
- mgmt_cb = & pf_to_mgmt -> mgmt_cb [recv_msg -> mod ];
394
+ mgmt_cb = & pf_to_mgmt -> mgmt_cb [mgmt_work -> mod ];
395
395
396
396
cb_state = cmpxchg (& mgmt_cb -> state ,
397
397
HINIC_MGMT_CB_ENABLED ,
398
398
HINIC_MGMT_CB_ENABLED | HINIC_MGMT_CB_RUNNING );
399
399
400
400
if ((cb_state == HINIC_MGMT_CB_ENABLED ) && (mgmt_cb -> cb ))
401
- mgmt_cb -> cb (mgmt_cb -> handle , recv_msg -> cmd ,
402
- recv_msg -> msg , recv_msg -> msg_len ,
401
+ mgmt_cb -> cb (mgmt_cb -> handle , mgmt_work -> cmd ,
402
+ mgmt_work -> msg , mgmt_work -> msg_len ,
403
403
buf_out , & out_size );
404
404
else
405
405
dev_err (& pdev -> dev , "No MGMT msg handler, mod: %d, cmd: %d\n" ,
406
- recv_msg -> mod , recv_msg -> cmd );
406
+ mgmt_work -> mod , mgmt_work -> cmd );
407
407
408
408
mgmt_cb -> state &= ~HINIC_MGMT_CB_RUNNING ;
409
409
410
- if (!recv_msg -> async_mgmt_to_pf )
410
+ if (!mgmt_work -> async_mgmt_to_pf )
411
411
/* MGMT sent sync msg, send the response */
412
- msg_to_mgmt_async (pf_to_mgmt , recv_msg -> mod , recv_msg -> cmd ,
412
+ msg_to_mgmt_async (pf_to_mgmt , mgmt_work -> mod , mgmt_work -> cmd ,
413
413
buf_out , out_size , MGMT_RESP ,
414
- recv_msg -> msg_id );
414
+ mgmt_work -> msg_id );
415
+
416
+ kfree (mgmt_work -> msg );
417
+ kfree (mgmt_work );
418
+ }
419
+
420
+ /**
421
+ * mgmt_recv_msg_handler - handler for message from mgmt cpu
422
+ * @pf_to_mgmt: PF to MGMT channel
423
+ * @recv_msg: received message details
424
+ **/
425
+ static void mgmt_recv_msg_handler (struct hinic_pf_to_mgmt * pf_to_mgmt ,
426
+ struct hinic_recv_msg * recv_msg )
427
+ {
428
+ struct hinic_mgmt_msg_handle_work * mgmt_work = NULL ;
429
+ struct pci_dev * pdev = pf_to_mgmt -> hwif -> pdev ;
430
+
431
+ mgmt_work = kzalloc (sizeof (* mgmt_work ), GFP_KERNEL );
432
+ if (!mgmt_work ) {
433
+ dev_err (& pdev -> dev , "Allocate mgmt work memory failed\n" );
434
+ return ;
435
+ }
436
+
437
+ if (recv_msg -> msg_len ) {
438
+ mgmt_work -> msg = kzalloc (recv_msg -> msg_len , GFP_KERNEL );
439
+ if (!mgmt_work -> msg ) {
440
+ dev_err (& pdev -> dev , "Allocate mgmt msg memory failed\n" );
441
+ kfree (mgmt_work );
442
+ return ;
443
+ }
444
+ }
445
+
446
+ mgmt_work -> pf_to_mgmt = pf_to_mgmt ;
447
+ mgmt_work -> msg_len = recv_msg -> msg_len ;
448
+ memcpy (mgmt_work -> msg , recv_msg -> msg , recv_msg -> msg_len );
449
+ mgmt_work -> msg_id = recv_msg -> msg_id ;
450
+ mgmt_work -> mod = recv_msg -> mod ;
451
+ mgmt_work -> cmd = recv_msg -> cmd ;
452
+ mgmt_work -> async_mgmt_to_pf = recv_msg -> async_mgmt_to_pf ;
453
+
454
+ INIT_WORK (& mgmt_work -> work , recv_mgmt_msg_work_handler );
455
+ queue_work (pf_to_mgmt -> workq , & mgmt_work -> work );
415
456
}
416
457
417
458
/**
@@ -546,6 +587,12 @@ static int alloc_msg_buf(struct hinic_pf_to_mgmt *pf_to_mgmt)
546
587
if (!pf_to_mgmt -> sync_msg_buf )
547
588
return - ENOMEM ;
548
589
590
+ pf_to_mgmt -> mgmt_ack_buf = devm_kzalloc (& pdev -> dev ,
591
+ MAX_PF_MGMT_BUF_SIZE ,
592
+ GFP_KERNEL );
593
+ if (!pf_to_mgmt -> mgmt_ack_buf )
594
+ return - ENOMEM ;
595
+
549
596
return 0 ;
550
597
}
551
598
@@ -571,6 +618,11 @@ int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt,
571
618
return 0 ;
572
619
573
620
sema_init (& pf_to_mgmt -> sync_msg_lock , 1 );
621
+ pf_to_mgmt -> workq = create_singlethread_workqueue ("hinic_mgmt" );
622
+ if (!pf_to_mgmt -> workq ) {
623
+ dev_err (& pdev -> dev , "Failed to initialize MGMT workqueue\n" );
624
+ return - ENOMEM ;
625
+ }
574
626
pf_to_mgmt -> sync_msg_id = 0 ;
575
627
576
628
err = alloc_msg_buf (pf_to_mgmt );
@@ -605,4 +657,5 @@ void hinic_pf_to_mgmt_free(struct hinic_pf_to_mgmt *pf_to_mgmt)
605
657
606
658
hinic_aeq_unregister_hw_cb (& hwdev -> aeqs , HINIC_MSG_FROM_MGMT_CPU );
607
659
hinic_api_cmd_free (pf_to_mgmt -> cmd_chain );
660
+ destroy_workqueue (pf_to_mgmt -> workq );
608
661
}
0 commit comments