]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: mana: Expose hardware diagnostic info via debugfs
authorErni Sri Satya Vennela <ernis@linux.microsoft.com>
Tue, 19 May 2026 06:46:10 +0000 (23:46 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 22 May 2026 18:08:54 +0000 (11:08 -0700)
Add debugfs entries to expose hardware configuration and diagnostic
information that aids in debugging driver initialization and runtime
operations without adding noise to dmesg.

The debugfs directory for each PCI device is named using pci_name()
(the unique BDF address), and its creation and removal is integrated
into mana_gd_setup() and mana_gd_cleanup_device() respectively, so
that all callers (probe, remove, suspend, resume, shutdown) share a
single code path.

Device-level entries (under /sys/kernel/debug/mana/<BDF>/):
  - num_msix_usable, max_num_queues: Max resources from hardware
  - gdma_protocol_ver, pf_cap_flags1: VF version negotiation results
  - num_vports, bm_hostmode: Device configuration

Per-vPort entries (under /sys/kernel/debug/mana/<BDF>/vportN/):
  - port_handle: Hardware vPort handle
  - max_sq, max_rq: Max queues from vPort config
  - indir_table_sz: Indirection table size
  - steer_rx, steer_rss, steer_update_tab, steer_cqe_coalescing:
    Last applied steering configuration parameters

Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260519064621.772154-1-ernis@linux.microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/microsoft/mana/gdma_main.c
drivers/net/ethernet/microsoft/mana/mana_en.c
include/net/mana/gdma.h
include/net/mana/mana.h

index 3bc3fff5599912c52a0a7e27fbfc15b836773b0b..712a0881d7209088c94c3a24a1613ded61f24f3c 100644 (file)
@@ -227,6 +227,11 @@ static int mana_gd_query_max_resources(struct pci_dev *pdev)
        if (gc->max_num_queues == 0)
                return -ENOSPC;
 
+       debugfs_create_u32("num_msix_usable", 0400, gc->mana_pci_debugfs,
+                          &gc->num_msix_usable);
+       debugfs_create_u32("max_num_queues", 0400, gc->mana_pci_debugfs,
+                          &gc->max_num_queues);
+
        return 0;
 }
 
@@ -1297,6 +1302,13 @@ int mana_gd_verify_vf_version(struct pci_dev *pdev)
                return err ? err : -EPROTO;
        }
        gc->pf_cap_flags1 = resp.pf_cap_flags1;
+       gc->gdma_protocol_ver = resp.gdma_protocol_ver;
+
+       debugfs_create_x64("gdma_protocol_ver", 0400, gc->mana_pci_debugfs,
+                          &gc->gdma_protocol_ver);
+       debugfs_create_x64("pf_cap_flags1", 0400, gc->mana_pci_debugfs,
+                          &gc->pf_cap_flags1);
+
        if (resp.pf_cap_flags1 & GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG) {
                err = mana_gd_query_hwc_timeout(pdev, &hwc->hwc_timeout);
                if (err) {
@@ -1976,15 +1988,20 @@ static int mana_gd_setup(struct pci_dev *pdev)
        struct gdma_context *gc = pci_get_drvdata(pdev);
        int err;
 
+       gc->mana_pci_debugfs = debugfs_create_dir(pci_name(pdev),
+                                                 mana_debugfs_root);
+
        err = mana_gd_init_registers(pdev);
        if (err)
-               return err;
+               goto remove_debugfs;
 
        mana_smc_init(&gc->shm_channel, gc->dev, gc->shm_base);
 
        gc->service_wq = alloc_ordered_workqueue("gdma_service_wq", 0);
-       if (!gc->service_wq)
-               return -ENOMEM;
+       if (!gc->service_wq) {
+               err = -ENOMEM;
+               goto remove_debugfs;
+       }
 
        err = mana_gd_setup_hwc_irqs(pdev);
        if (err) {
@@ -2025,11 +2042,14 @@ remove_irq:
 free_workqueue:
        destroy_workqueue(gc->service_wq);
        gc->service_wq = NULL;
+remove_debugfs:
+       debugfs_remove_recursive(gc->mana_pci_debugfs);
+       gc->mana_pci_debugfs = NULL;
        dev_err(&pdev->dev, "%s failed (error %d)\n", __func__, err);
        return err;
 }
 
-static void mana_gd_cleanup(struct pci_dev *pdev)
+static void mana_gd_cleanup_device(struct pci_dev *pdev)
 {
        struct gdma_context *gc = pci_get_drvdata(pdev);
 
@@ -2041,6 +2061,10 @@ static void mana_gd_cleanup(struct pci_dev *pdev)
                destroy_workqueue(gc->service_wq);
                gc->service_wq = NULL;
        }
+
+       debugfs_remove_recursive(gc->mana_pci_debugfs);
+       gc->mana_pci_debugfs = NULL;
+
        dev_dbg(&pdev->dev, "mana gdma cleanup successful\n");
 }
 
@@ -2098,9 +2122,6 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        gc->dev = &pdev->dev;
        xa_init(&gc->irq_contexts);
 
-       gc->mana_pci_debugfs = debugfs_create_dir(pci_name(pdev),
-                                                 mana_debugfs_root);
-
        err = mana_gd_setup(pdev);
        if (err)
                goto unmap_bar;
@@ -2129,16 +2150,8 @@ cleanup_mana_rdma:
 cleanup_mana:
        mana_remove(&gc->mana, false);
 cleanup_gd:
-       mana_gd_cleanup(pdev);
+       mana_gd_cleanup_device(pdev);
 unmap_bar:
-       /*
-        * at this point we know that the other debugfs child dir/files
-        * are either not yet created or are already cleaned up.
-        * The pci debugfs folder clean-up now, will only be cleaning up
-        * adapter-MTU file and apc->mana_pci_debugfs folder.
-        */
-       debugfs_remove_recursive(gc->mana_pci_debugfs);
-       gc->mana_pci_debugfs = NULL;
        xa_destroy(&gc->irq_contexts);
        pci_iounmap(pdev, bar0_va);
 free_gc:
@@ -2188,11 +2201,7 @@ static void mana_gd_remove(struct pci_dev *pdev)
        mana_rdma_remove(&gc->mana_ib);
        mana_remove(&gc->mana, false);
 
-       mana_gd_cleanup(pdev);
-
-       debugfs_remove_recursive(gc->mana_pci_debugfs);
-
-       gc->mana_pci_debugfs = NULL;
+       mana_gd_cleanup_device(pdev);
 
        xa_destroy(&gc->irq_contexts);
 
@@ -2214,15 +2223,11 @@ int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state)
        mana_rdma_remove(&gc->mana_ib);
        mana_remove(&gc->mana, true);
 
-       mana_gd_cleanup(pdev);
+       mana_gd_cleanup_device(pdev);
 
        return 0;
 }
 
-/* In case the NIC hardware stops working, the suspend and resume callbacks will
- * fail -- if this happens, it's safer to just report an error than try to undo
- * what has been done.
- */
 int mana_gd_resume(struct pci_dev *pdev)
 {
        struct gdma_context *gc = pci_get_drvdata(pdev);
@@ -2234,13 +2239,17 @@ int mana_gd_resume(struct pci_dev *pdev)
 
        err = mana_probe(&gc->mana, true);
        if (err)
-               return err;
+               goto cleanup_gd;
 
        err = mana_rdma_probe(&gc->mana_ib);
        if (err)
-               return err;
+               mana_rdma_remove(&gc->mana_ib);
 
-       return 0;
+       return err;
+
+cleanup_gd:
+       mana_gd_cleanup_device(pdev);
+       return err;
 }
 
 /* Quiesce the device for kexec. This is also called upon reboot/shutdown. */
@@ -2253,11 +2262,7 @@ static void mana_gd_shutdown(struct pci_dev *pdev)
        mana_rdma_remove(&gc->mana_ib);
        mana_remove(&gc->mana, true);
 
-       mana_gd_cleanup(pdev);
-
-       debugfs_remove_recursive(gc->mana_pci_debugfs);
-
-       gc->mana_pci_debugfs = NULL;
+       mana_gd_cleanup_device(pdev);
 
        pci_disable_device(pdev);
 }
index b2faa7cf398f350ea5c34caa8bc006c91698700c..82f1461a48e93896e54abe91a7960d8492df4409 100644 (file)
@@ -1282,6 +1282,9 @@ static int mana_query_vport_cfg(struct mana_port_context *apc, u32 vport_index,
        apc->port_handle = resp.vport;
        ether_addr_copy(apc->mac_addr, resp.mac_addr);
 
+       apc->vport_max_sq = *max_sq;
+       apc->vport_max_rq = *max_rq;
+
        return 0;
 }
 
@@ -1436,6 +1439,11 @@ static int mana_cfg_vport_steering(struct mana_port_context *apc,
 
        netdev_info(ndev, "Configured steering vPort %llu entries %u\n",
                    apc->port_handle, apc->indir_table_sz);
+
+       apc->steer_rx = rx;
+       apc->steer_rss = apc->rss_state;
+       apc->steer_update_tab = update_tab;
+       apc->steer_cqe_coalescing = req->cqe_coalescing_enable;
 out:
        kfree(req);
        return err;
@@ -3178,6 +3186,23 @@ static int mana_init_port(struct net_device *ndev)
        eth_hw_addr_set(ndev, apc->mac_addr);
        sprintf(vport, "vport%d", port_idx);
        apc->mana_port_debugfs = debugfs_create_dir(vport, gc->mana_pci_debugfs);
+
+       debugfs_create_u64("port_handle", 0400, apc->mana_port_debugfs,
+                          &apc->port_handle);
+       debugfs_create_u32("max_sq", 0400, apc->mana_port_debugfs,
+                          &apc->vport_max_sq);
+       debugfs_create_u32("max_rq", 0400, apc->mana_port_debugfs,
+                          &apc->vport_max_rq);
+       debugfs_create_u32("indir_table_sz", 0400, apc->mana_port_debugfs,
+                          &apc->indir_table_sz);
+       debugfs_create_u32("steer_rx", 0400, apc->mana_port_debugfs,
+                          &apc->steer_rx);
+       debugfs_create_u32("steer_rss", 0400, apc->mana_port_debugfs,
+                          &apc->steer_rss);
+       debugfs_create_bool("steer_update_tab", 0400, apc->mana_port_debugfs,
+                           &apc->steer_update_tab);
+       debugfs_create_u32("steer_cqe_coalescing", 0400, apc->mana_port_debugfs,
+                          &apc->steer_cqe_coalescing);
        debugfs_create_u32("current_speed", 0400, apc->mana_port_debugfs,
                           &apc->speed);
        return 0;
@@ -3695,6 +3720,11 @@ int mana_probe(struct gdma_dev *gd, bool resuming)
        if (ac->num_ports > MAX_PORTS_IN_MANA_DEV)
                ac->num_ports = MAX_PORTS_IN_MANA_DEV;
 
+       debugfs_create_u16("num_vports", 0400, gc->mana_pci_debugfs,
+                          &ac->num_ports);
+       debugfs_create_u8("bm_hostmode", 0400, gc->mana_pci_debugfs,
+                         &ac->bm_hostmode);
+
        ac->per_port_queue_reset_wq =
                create_singlethread_workqueue("mana_per_port_queue_reset_wq");
        if (!ac->per_port_queue_reset_wq) {
@@ -3817,6 +3847,11 @@ void mana_remove(struct gdma_dev *gd, bool suspending)
 
        mana_gd_deregister_device(gd);
 
+       if (gc->mana_pci_debugfs) {
+               debugfs_lookup_and_remove("bm_hostmode", gc->mana_pci_debugfs);
+               debugfs_lookup_and_remove("num_vports", gc->mana_pci_debugfs);
+       }
+
        if (suspending)
                return;
 
index 6d836060976ad37cbe56969018b8221b0de93069..70d62bc3283702af8557042c16ea988e75660a49 100644 (file)
@@ -442,6 +442,7 @@ struct gdma_context {
        struct gdma_dev         mana_ib;
 
        u64 pf_cap_flags1;
+       u64 gdma_protocol_ver;
 
        struct workqueue_struct *service_wq;
 
index aa90a858c8e3f8b47b714b002a2e73efdbe8e0ef..d9c27310fd04dd4e753a52e70b2bb7f89b6022c3 100644 (file)
@@ -568,6 +568,14 @@ struct mana_port_context {
 
        /* Debugfs */
        struct dentry *mana_port_debugfs;
+
+       /* Cached vport/steering config for debugfs */
+       u32 vport_max_sq;
+       u32 vport_max_rq;
+       u32 steer_rx;
+       u32 steer_rss;
+       bool steer_update_tab;
+       u32 steer_cqe_coalescing;
 };
 
 netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);