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

net: mana: Handle Reset Request from MANA NIC

Upon receiving the Reset Request, pause the connection and clean up
queues, wait for the specified period, then resume the NIC.
In the cleanup phase, the HWC is no longer responding, so set hwc_timeout
to zero to skip waiting on the response.

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Link: https://patch.msgid.link/1751055983-29760-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
fbe346ce f461c7a8

+143 -35
+103 -24
drivers/net/ethernet/microsoft/mana/gdma_main.c
··· 10 10 #include <linux/irqdomain.h> 11 11 12 12 #include <net/mana/mana.h> 13 + #include <net/mana/hw_channel.h> 13 14 14 15 struct dentry *mana_debugfs_root; 15 16 ··· 67 66 mana_gd_init_pf_regs(pdev); 68 67 else 69 68 mana_gd_init_vf_regs(pdev); 69 + } 70 + 71 + /* Suppress logging when we set timeout to zero */ 72 + bool mana_need_log(struct gdma_context *gc, int err) 73 + { 74 + struct hw_channel_context *hwc; 75 + 76 + if (err != -ETIMEDOUT) 77 + return true; 78 + 79 + if (!gc) 80 + return true; 81 + 82 + hwc = gc->hwc.driver_data; 83 + if (hwc && hwc->hwc_timeout == 0) 84 + return false; 85 + 86 + return true; 70 87 } 71 88 72 89 static int mana_gd_query_max_resources(struct pci_dev *pdev) ··· 297 278 298 279 err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); 299 280 if (err || resp.hdr.status) { 300 - dev_err(gc->dev, "Failed to disable queue: %d, 0x%x\n", err, 301 - resp.hdr.status); 281 + if (mana_need_log(gc, err)) 282 + dev_err(gc->dev, "Failed to disable queue: %d, 0x%x\n", err, 283 + resp.hdr.status); 302 284 return err ? err : -EPROTO; 303 285 } 304 286 ··· 386 366 387 367 #define MANA_SERVICE_PERIOD 10 388 368 389 - struct mana_serv_work { 390 - struct work_struct serv_work; 391 - struct pci_dev *pdev; 392 - }; 393 - 394 - static void mana_serv_func(struct work_struct *w) 369 + static void mana_serv_fpga(struct pci_dev *pdev) 395 370 { 396 - struct mana_serv_work *mns_wk; 397 371 struct pci_bus *bus, *parent; 398 - struct pci_dev *pdev; 399 - 400 - mns_wk = container_of(w, struct mana_serv_work, serv_work); 401 - pdev = mns_wk->pdev; 402 372 403 373 pci_lock_rescan_remove(); 404 - 405 - if (!pdev) 406 - goto out; 407 374 408 375 bus = pdev->bus; 409 376 if (!bus) { ··· 412 405 413 406 out: 414 407 pci_unlock_rescan_remove(); 408 + } 415 409 410 + static void mana_serv_reset(struct pci_dev *pdev) 411 + { 412 + struct gdma_context *gc = pci_get_drvdata(pdev); 413 + struct hw_channel_context *hwc; 414 + 415 + if (!gc) { 416 + dev_err(&pdev->dev, "MANA service: no GC\n"); 417 + return; 418 + } 419 + 420 + hwc = gc->hwc.driver_data; 421 + if (!hwc) { 422 + dev_err(&pdev->dev, "MANA service: no HWC\n"); 423 + goto out; 424 + } 425 + 426 + /* HWC is not responding in this case, so don't wait */ 427 + hwc->hwc_timeout = 0; 428 + 429 + dev_info(&pdev->dev, "MANA reset cycle start\n"); 430 + 431 + mana_gd_suspend(pdev, PMSG_SUSPEND); 432 + 433 + msleep(MANA_SERVICE_PERIOD * 1000); 434 + 435 + mana_gd_resume(pdev); 436 + 437 + dev_info(&pdev->dev, "MANA reset cycle completed\n"); 438 + 439 + out: 440 + gc->in_service = false; 441 + } 442 + 443 + struct mana_serv_work { 444 + struct work_struct serv_work; 445 + struct pci_dev *pdev; 446 + enum gdma_eqe_type type; 447 + }; 448 + 449 + static void mana_serv_func(struct work_struct *w) 450 + { 451 + struct mana_serv_work *mns_wk; 452 + struct pci_dev *pdev; 453 + 454 + mns_wk = container_of(w, struct mana_serv_work, serv_work); 455 + pdev = mns_wk->pdev; 456 + 457 + if (!pdev) 458 + goto out; 459 + 460 + switch (mns_wk->type) { 461 + case GDMA_EQE_HWC_FPGA_RECONFIG: 462 + mana_serv_fpga(pdev); 463 + break; 464 + 465 + case GDMA_EQE_HWC_RESET_REQUEST: 466 + mana_serv_reset(pdev); 467 + break; 468 + 469 + default: 470 + dev_err(&pdev->dev, "MANA service: unknown type %d\n", 471 + mns_wk->type); 472 + break; 473 + } 474 + 475 + out: 416 476 pci_dev_put(pdev); 417 477 kfree(mns_wk); 418 478 module_put(THIS_MODULE); ··· 536 462 break; 537 463 538 464 case GDMA_EQE_HWC_FPGA_RECONFIG: 465 + case GDMA_EQE_HWC_RESET_REQUEST: 539 466 dev_info(gc->dev, "Recv MANA service type:%d\n", type); 540 467 541 468 if (gc->in_service) { ··· 558 483 dev_info(gc->dev, "Start MANA service type:%d\n", type); 559 484 gc->in_service = true; 560 485 mns_wk->pdev = to_pci_dev(gc->dev); 486 + mns_wk->type = type; 561 487 pci_dev_get(mns_wk->pdev); 562 488 INIT_WORK(&mns_wk->serv_work, mana_serv_func); 563 489 schedule_work(&mns_wk->serv_work); ··· 710 634 711 635 err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); 712 636 if (err) { 713 - dev_err(dev, "test_eq failed: %d\n", err); 637 + if (mana_need_log(gc, err)) 638 + dev_err(dev, "test_eq failed: %d\n", err); 714 639 goto out; 715 640 } 716 641 ··· 746 669 747 670 if (flush_evenets) { 748 671 err = mana_gd_test_eq(gc, queue); 749 - if (err) 672 + if (err && mana_need_log(gc, err)) 750 673 dev_warn(gc->dev, "Failed to flush EQ: %d\n", err); 751 674 } 752 675 ··· 892 815 893 816 err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); 894 817 if (err || resp.hdr.status) { 895 - dev_err(gc->dev, "Failed to destroy DMA region: %d, 0x%x\n", 896 - err, resp.hdr.status); 818 + if (mana_need_log(gc, err)) 819 + dev_err(gc->dev, "Failed to destroy DMA region: %d, 0x%x\n", 820 + err, resp.hdr.status); 897 821 return -EPROTO; 898 822 } 899 823 ··· 1194 1116 1195 1117 err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp); 1196 1118 if (err || resp.hdr.status) { 1197 - dev_err(gc->dev, "Failed to deregister device: %d, 0x%x\n", 1198 - err, resp.hdr.status); 1119 + if (mana_need_log(gc, err)) 1120 + dev_err(gc->dev, "Failed to deregister device: %d, 0x%x\n", 1121 + err, resp.hdr.status); 1199 1122 if (!err) 1200 1123 err = -EPROTO; 1201 1124 } ··· 1994 1915 } 1995 1916 1996 1917 /* The 'state' parameter is not used. */ 1997 - static int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state) 1918 + int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state) 1998 1919 { 1999 1920 struct gdma_context *gc = pci_get_drvdata(pdev); 2000 1921 ··· 2010 1931 * fail -- if this happens, it's safer to just report an error than try to undo 2011 1932 * what has been done. 2012 1933 */ 2013 - static int mana_gd_resume(struct pci_dev *pdev) 1934 + int mana_gd_resume(struct pci_dev *pdev) 2014 1935 { 2015 1936 struct gdma_context *gc = pci_get_drvdata(pdev); 2016 1937 int err;
+3 -1
drivers/net/ethernet/microsoft/mana/hw_channel.c
··· 880 880 881 881 if (!wait_for_completion_timeout(&ctx->comp_event, 882 882 (msecs_to_jiffies(hwc->hwc_timeout)))) { 883 - dev_err(hwc->dev, "HWC: Request timed out!\n"); 883 + if (hwc->hwc_timeout != 0) 884 + dev_err(hwc->dev, "HWC: Request timed out!\n"); 885 + 884 886 err = -ETIMEDOUT; 885 887 goto out; 886 888 }
+27 -10
drivers/net/ethernet/microsoft/mana/mana_en.c
··· 47 47 .read = mana_dbg_q_read, 48 48 }; 49 49 50 + static bool mana_en_need_log(struct mana_port_context *apc, int err) 51 + { 52 + if (apc && apc->ac && apc->ac->gdma_dev && 53 + apc->ac->gdma_dev->gdma_context) 54 + return mana_need_log(apc->ac->gdma_dev->gdma_context, err); 55 + else 56 + return true; 57 + } 58 + 50 59 /* Microsoft Azure Network Adapter (MANA) functions */ 51 60 52 61 static int mana_open(struct net_device *ndev) ··· 863 854 if (err == -EOPNOTSUPP) 864 855 return err; 865 856 866 - if (req->req.msg_type != MANA_QUERY_PHY_STAT) 857 + if (req->req.msg_type != MANA_QUERY_PHY_STAT && 858 + mana_need_log(gc, err)) 867 859 dev_err(dev, "Failed to send mana message: %d, 0x%x\n", 868 860 err, resp->status); 869 861 return err ? err : -EPROTO; ··· 941 931 err = mana_send_request(apc->ac, &req, sizeof(req), &resp, 942 932 sizeof(resp)); 943 933 if (err) { 944 - netdev_err(apc->ndev, "Failed to unregister hw vPort: %d\n", 945 - err); 934 + if (mana_en_need_log(apc, err)) 935 + netdev_err(apc->ndev, "Failed to unregister hw vPort: %d\n", 936 + err); 937 + 946 938 return; 947 939 } 948 940 ··· 999 987 err = mana_send_request(apc->ac, &req, sizeof(req), &resp, 1000 988 sizeof(resp)); 1001 989 if (err) { 1002 - netdev_err(apc->ndev, "Failed to unregister filter: %d\n", 1003 - err); 990 + if (mana_en_need_log(apc, err)) 991 + netdev_err(apc->ndev, "Failed to unregister filter: %d\n", 992 + err); 993 + 1004 994 return; 1005 995 } 1006 996 ··· 1232 1218 err = mana_send_request(apc->ac, req, req_buf_size, &resp, 1233 1219 sizeof(resp)); 1234 1220 if (err) { 1235 - netdev_err(ndev, "Failed to configure vPort RX: %d\n", err); 1221 + if (mana_en_need_log(apc, err)) 1222 + netdev_err(ndev, "Failed to configure vPort RX: %d\n", err); 1223 + 1236 1224 goto out; 1237 1225 } 1238 1226 ··· 1418 1402 err = mana_send_request(apc->ac, &req, sizeof(req), &resp, 1419 1403 sizeof(resp)); 1420 1404 if (err) { 1421 - netdev_err(ndev, "Failed to destroy WQ object: %d\n", err); 1405 + if (mana_en_need_log(apc, err)) 1406 + netdev_err(ndev, "Failed to destroy WQ object: %d\n", err); 1407 + 1422 1408 return; 1423 1409 } 1424 1410 ··· 3085 3067 3086 3068 apc->rss_state = TRI_STATE_FALSE; 3087 3069 err = mana_config_rss(apc, TRI_STATE_FALSE, false, false); 3088 - if (err) { 3070 + if (err && mana_en_need_log(apc, err)) 3089 3071 netdev_err(ndev, "Failed to disable vPort: %d\n", err); 3090 - return err; 3091 - } 3092 3072 3073 + /* Even in err case, still need to cleanup the vPort */ 3093 3074 mana_destroy_vport(apc); 3094 3075 3095 3076 return 0;
+10
include/net/mana/gdma.h
··· 62 62 GDMA_EQE_HWC_FPGA_RECONFIG = 132, 63 63 GDMA_EQE_HWC_SOC_RECONFIG_DATA = 133, 64 64 GDMA_EQE_HWC_SOC_SERVICE = 134, 65 + GDMA_EQE_HWC_RESET_REQUEST = 135, 65 66 GDMA_EQE_RNIC_QP_FATAL = 176, 66 67 }; 67 68 ··· 585 584 /* Driver supports dynamic MSI-X vector allocation */ 586 585 #define GDMA_DRV_CAP_FLAG_1_DYNAMIC_IRQ_ALLOC_SUPPORT BIT(13) 587 586 587 + /* Driver can self reset on EQE notification */ 588 + #define GDMA_DRV_CAP_FLAG_1_SELF_RESET_ON_EQE BIT(14) 589 + 588 590 /* Driver can self reset on FPGA Reconfig EQE notification */ 589 591 #define GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE BIT(17) 590 592 ··· 598 594 GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | \ 599 595 GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP | \ 600 596 GDMA_DRV_CAP_FLAG_1_DYNAMIC_IRQ_ALLOC_SUPPORT | \ 597 + GDMA_DRV_CAP_FLAG_1_SELF_RESET_ON_EQE | \ 601 598 GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE) 602 599 603 600 #define GDMA_DRV_CAP_FLAGS2 0 ··· 925 920 void mana_unregister_debugfs(void); 926 921 927 922 int mana_rdma_service_event(struct gdma_context *gc, enum gdma_service_type event); 923 + 924 + int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state); 925 + int mana_gd_resume(struct pci_dev *pdev); 926 + 927 + bool mana_need_log(struct gdma_context *gc, int err); 928 928 929 929 #endif /* _GDMA_H */