Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: mana: Add handler for hardware servicing events

To collaborate with hardware servicing events, upon receiving the special
EQE notification from the HW channel, remove the devices on this bus.
Then, after a waiting period based on the device specs, rescan the parent
bus to recover the devices.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/1749834034-18498-1-git-send-email-haiyangz@linux.microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Haiyang Zhang and committed by
Jakub Kicinski
7768c5f4 7aa3f991

+83 -2
+75
drivers/net/ethernet/microsoft/mana/gdma_main.c
··· 352 352 } 353 353 EXPORT_SYMBOL_NS(mana_gd_ring_cq, "NET_MANA"); 354 354 355 + #define MANA_SERVICE_PERIOD 10 356 + 357 + struct mana_serv_work { 358 + struct work_struct serv_work; 359 + struct pci_dev *pdev; 360 + }; 361 + 362 + static void mana_serv_func(struct work_struct *w) 363 + { 364 + struct mana_serv_work *mns_wk; 365 + struct pci_bus *bus, *parent; 366 + struct pci_dev *pdev; 367 + 368 + mns_wk = container_of(w, struct mana_serv_work, serv_work); 369 + pdev = mns_wk->pdev; 370 + 371 + pci_lock_rescan_remove(); 372 + 373 + if (!pdev) 374 + goto out; 375 + 376 + bus = pdev->bus; 377 + if (!bus) { 378 + dev_err(&pdev->dev, "MANA service: no bus\n"); 379 + goto out; 380 + } 381 + 382 + parent = bus->parent; 383 + if (!parent) { 384 + dev_err(&pdev->dev, "MANA service: no parent bus\n"); 385 + goto out; 386 + } 387 + 388 + pci_stop_and_remove_bus_device(bus->self); 389 + 390 + msleep(MANA_SERVICE_PERIOD * 1000); 391 + 392 + pci_rescan_bus(parent); 393 + 394 + out: 395 + pci_unlock_rescan_remove(); 396 + 397 + pci_dev_put(pdev); 398 + kfree(mns_wk); 399 + module_put(THIS_MODULE); 400 + } 401 + 355 402 static void mana_gd_process_eqe(struct gdma_queue *eq) 356 403 { 357 404 u32 head = eq->head % (eq->queue_size / GDMA_EQE_SIZE); 358 405 struct gdma_context *gc = eq->gdma_dev->gdma_context; 359 406 struct gdma_eqe *eq_eqe_ptr = eq->queue_mem_ptr; 407 + struct mana_serv_work *mns_wk; 360 408 union gdma_eqe_info eqe_info; 361 409 enum gdma_eqe_type type; 362 410 struct gdma_event event; ··· 447 399 event.type = type; 448 400 memcpy(&event.details, &eqe->details, GDMA_EVENT_DATA_SIZE); 449 401 eq->eq.callback(eq->eq.context, eq, &event); 402 + break; 403 + 404 + case GDMA_EQE_HWC_FPGA_RECONFIG: 405 + dev_info(gc->dev, "Recv MANA service type:%d\n", type); 406 + 407 + if (gc->in_service) { 408 + dev_info(gc->dev, "Already in service\n"); 409 + break; 410 + } 411 + 412 + if (!try_module_get(THIS_MODULE)) { 413 + dev_info(gc->dev, "Module is unloading\n"); 414 + break; 415 + } 416 + 417 + mns_wk = kzalloc(sizeof(*mns_wk), GFP_ATOMIC); 418 + if (!mns_wk) { 419 + module_put(THIS_MODULE); 420 + break; 421 + } 422 + 423 + dev_info(gc->dev, "Start MANA service type:%d\n", type); 424 + gc->in_service = true; 425 + mns_wk->pdev = to_pci_dev(gc->dev); 426 + pci_dev_get(mns_wk->pdev); 427 + INIT_WORK(&mns_wk->serv_work, mana_serv_func); 428 + schedule_work(&mns_wk->serv_work); 450 429 break; 451 430 452 431 default:
+8 -2
include/net/mana/gdma.h
··· 58 58 GDMA_EQE_HWC_INIT_EQ_ID_DB = 129, 59 59 GDMA_EQE_HWC_INIT_DATA = 130, 60 60 GDMA_EQE_HWC_INIT_DONE = 131, 61 - GDMA_EQE_HWC_SOC_RECONFIG = 132, 61 + GDMA_EQE_HWC_FPGA_RECONFIG = 132, 62 62 GDMA_EQE_HWC_SOC_RECONFIG_DATA = 133, 63 63 GDMA_EQE_HWC_SOC_SERVICE = 134, 64 64 GDMA_EQE_RNIC_QP_FATAL = 176, ··· 403 403 u32 test_event_eq_id; 404 404 405 405 bool is_pf; 406 + bool in_service; 407 + 406 408 phys_addr_t bar0_pa; 407 409 void __iomem *bar0_va; 408 410 void __iomem *shm_base; ··· 580 578 /* Driver can handle holes (zeros) in the device list */ 581 579 #define GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP BIT(11) 582 580 581 + /* Driver can self reset on FPGA Reconfig EQE notification */ 582 + #define GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE BIT(17) 583 + 583 584 #define GDMA_DRV_CAP_FLAGS1 \ 584 585 (GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \ 585 586 GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \ 586 587 GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG | \ 587 588 GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | \ 588 - GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP) 589 + GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP | \ 590 + GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE) 589 591 590 592 #define GDMA_DRV_CAP_FLAGS2 0 591 593