134520ae5SManish Awasthi // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 234520ae5SManish Awasthi /* Copyright (c) 2025, Microsoft Corporation. */ 334520ae5SManish Awasthi 434520ae5SManish Awasthi #include <linux/bitmap.h> 534520ae5SManish Awasthi #include <linux/cpumask.h> 634520ae5SManish Awasthi #include <linux/debugfs.h> 734520ae5SManish Awasthi #include <linux/delay.h> 834520ae5SManish Awasthi #include <linux/list.h> 934520ae5SManish Awasthi #include <linux/module.h> 1034520ae5SManish Awasthi #include <linux/msi.h> 1134520ae5SManish Awasthi #include <linux/pci.h> 1234520ae5SManish Awasthi #include <linux/slab.h> 1334520ae5SManish Awasthi #include <linux/topology.h> 1434520ae5SManish Awasthi #include <linux/xarray.h> 1534520ae5SManish Awasthi 1634520ae5SManish Awasthi #include <net/mana/mana.h> 1734520ae5SManish Awasthi #include <net/mana/hw_channel.h> 1834520ae5SManish Awasthi 1934520ae5SManish Awasthi struct mana_dev_recovery { 2034520ae5SManish Awasthi struct list_head list; 2134520ae5SManish Awasthi struct pci_dev *pdev; 2234520ae5SManish Awasthi enum gdma_eqe_type type; 2334520ae5SManish Awasthi }; 2434520ae5SManish Awasthi 2534520ae5SManish Awasthi static struct mana_dev_recovery_work { 2634520ae5SManish Awasthi struct list_head dev_list; 2734520ae5SManish Awasthi struct delayed_work work; 2834520ae5SManish Awasthi 2934520ae5SManish Awasthi /* Lock for dev_list above */ 3034520ae5SManish Awasthi spinlock_t lock; 3134520ae5SManish Awasthi } mana_dev_recovery_work; 3234520ae5SManish Awasthi 3334520ae5SManish Awasthi static int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state); 3434520ae5SManish Awasthi static int mana_gd_resume(struct pci_dev *pdev); 3534520ae5SManish Awasthi 3634520ae5SManish Awasthi #define MANA_SERVICE_PERIOD 10 3734520ae5SManish Awasthi 3834520ae5SManish Awasthi static void mana_serv_rescan(struct pci_dev *pdev) 3934520ae5SManish Awasthi { 4034520ae5SManish Awasthi struct pci_bus *parent; 4134520ae5SManish Awasthi 4234520ae5SManish Awasthi pci_lock_rescan_remove(); 4334520ae5SManish Awasthi 4434520ae5SManish Awasthi parent = pdev->bus; 4534520ae5SManish Awasthi if (!parent) { 4634520ae5SManish Awasthi dev_err(&pdev->dev, "MANA service: no parent bus\n"); 4734520ae5SManish Awasthi goto out; 4834520ae5SManish Awasthi } 4934520ae5SManish Awasthi 5034520ae5SManish Awasthi pci_stop_and_remove_bus_device(pdev); 5134520ae5SManish Awasthi pci_rescan_bus(parent); 5234520ae5SManish Awasthi 5334520ae5SManish Awasthi out: 5434520ae5SManish Awasthi pci_unlock_rescan_remove(); 5534520ae5SManish Awasthi } 5634520ae5SManish Awasthi 5734520ae5SManish Awasthi static void mana_serv_fpga(struct pci_dev *pdev) 5834520ae5SManish Awasthi { 5934520ae5SManish Awasthi struct pci_bus *bus, *parent; 6034520ae5SManish Awasthi 6134520ae5SManish Awasthi pci_lock_rescan_remove(); 6234520ae5SManish Awasthi 6334520ae5SManish Awasthi bus = pdev->bus; 6434520ae5SManish Awasthi if (!bus) { 6534520ae5SManish Awasthi dev_err(&pdev->dev, "MANA service: no bus\n"); 6634520ae5SManish Awasthi goto out; 6734520ae5SManish Awasthi } 6834520ae5SManish Awasthi 6934520ae5SManish Awasthi parent = bus->parent; 7034520ae5SManish Awasthi if (!parent) { 7134520ae5SManish Awasthi dev_err(&pdev->dev, "MANA service: no parent bus\n"); 7234520ae5SManish Awasthi goto out; 7334520ae5SManish Awasthi } 7434520ae5SManish Awasthi 7534520ae5SManish Awasthi pci_stop_and_remove_bus_device(bus->self); 7634520ae5SManish Awasthi 7734520ae5SManish Awasthi msleep(MANA_SERVICE_PERIOD * 1000); 7834520ae5SManish Awasthi 7934520ae5SManish Awasthi pci_rescan_bus(parent); 8034520ae5SManish Awasthi 8134520ae5SManish Awasthi out: 8234520ae5SManish Awasthi pci_unlock_rescan_remove(); 8334520ae5SManish Awasthi } 8434520ae5SManish Awasthi 8534520ae5SManish Awasthi static void mana_serv_reset(struct pci_dev *pdev) 8634520ae5SManish Awasthi { 8734520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 8834520ae5SManish Awasthi struct hw_channel_context *hwc; 8934520ae5SManish Awasthi int ret; 9034520ae5SManish Awasthi 9134520ae5SManish Awasthi if (!gc) { 9234520ae5SManish Awasthi /* Perform PCI rescan on device if GC is not set up */ 9334520ae5SManish Awasthi dev_err(&pdev->dev, "MANA service: GC not setup, rescanning\n"); 9434520ae5SManish Awasthi mana_serv_rescan(pdev); 9534520ae5SManish Awasthi return; 9634520ae5SManish Awasthi } 9734520ae5SManish Awasthi 9834520ae5SManish Awasthi hwc = gc->hwc.driver_data; 9934520ae5SManish Awasthi if (!hwc) { 10034520ae5SManish Awasthi dev_err(&pdev->dev, "MANA service: no HWC\n"); 10134520ae5SManish Awasthi goto out; 10234520ae5SManish Awasthi } 10334520ae5SManish Awasthi 10434520ae5SManish Awasthi /* HWC is not responding in this case, so don't wait */ 10534520ae5SManish Awasthi hwc->hwc_timeout = 0; 10634520ae5SManish Awasthi 10734520ae5SManish Awasthi dev_info(&pdev->dev, "MANA reset cycle start\n"); 10834520ae5SManish Awasthi 10934520ae5SManish Awasthi mana_gd_suspend(pdev, PMSG_SUSPEND); 11034520ae5SManish Awasthi 11134520ae5SManish Awasthi msleep(MANA_SERVICE_PERIOD * 1000); 11234520ae5SManish Awasthi 11334520ae5SManish Awasthi ret = mana_gd_resume(pdev); 11434520ae5SManish Awasthi if (ret == -ETIMEDOUT || ret == -EPROTO) { 11534520ae5SManish Awasthi /* Perform PCI rescan on device if we failed on HWC */ 11634520ae5SManish Awasthi dev_err(&pdev->dev, "MANA service: resume failed, rescanning\n"); 11734520ae5SManish Awasthi mana_serv_rescan(pdev); 11834520ae5SManish Awasthi return; 11934520ae5SManish Awasthi } 12034520ae5SManish Awasthi 12134520ae5SManish Awasthi if (ret) 12234520ae5SManish Awasthi dev_info(&pdev->dev, "MANA reset cycle failed err %d\n", ret); 12334520ae5SManish Awasthi else 12434520ae5SManish Awasthi dev_info(&pdev->dev, "MANA reset cycle completed\n"); 12534520ae5SManish Awasthi 12634520ae5SManish Awasthi out: 12734520ae5SManish Awasthi clear_bit(GC_IN_SERVICE, &gc->flags); 12834520ae5SManish Awasthi } 12934520ae5SManish Awasthi 13034520ae5SManish Awasthi static void mana_do_service(enum gdma_eqe_type type, struct pci_dev *pdev) 13134520ae5SManish Awasthi { 13234520ae5SManish Awasthi switch (type) { 13334520ae5SManish Awasthi case GDMA_EQE_HWC_FPGA_RECONFIG: 13434520ae5SManish Awasthi mana_serv_fpga(pdev); 13534520ae5SManish Awasthi break; 13634520ae5SManish Awasthi 13734520ae5SManish Awasthi case GDMA_EQE_HWC_RESET_REQUEST: 13834520ae5SManish Awasthi mana_serv_reset(pdev); 13934520ae5SManish Awasthi break; 14034520ae5SManish Awasthi 14134520ae5SManish Awasthi default: 14234520ae5SManish Awasthi dev_err(&pdev->dev, "MANA service: unknown type %d\n", type); 14334520ae5SManish Awasthi break; 14434520ae5SManish Awasthi } 14534520ae5SManish Awasthi } 14634520ae5SManish Awasthi 14734520ae5SManish Awasthi static void mana_recovery_delayed_func(struct work_struct *w) 14834520ae5SManish Awasthi { 14934520ae5SManish Awasthi struct mana_dev_recovery_work *work; 15034520ae5SManish Awasthi struct mana_dev_recovery *dev; 15134520ae5SManish Awasthi unsigned long flags; 15234520ae5SManish Awasthi 15334520ae5SManish Awasthi work = container_of(w, struct mana_dev_recovery_work, work.work); 15434520ae5SManish Awasthi 15534520ae5SManish Awasthi spin_lock_irqsave(&work->lock, flags); 15634520ae5SManish Awasthi 15734520ae5SManish Awasthi while (!list_empty(&work->dev_list)) { 15834520ae5SManish Awasthi dev = list_first_entry(&work->dev_list, 15934520ae5SManish Awasthi struct mana_dev_recovery, list); 16034520ae5SManish Awasthi list_del(&dev->list); 16134520ae5SManish Awasthi spin_unlock_irqrestore(&work->lock, flags); 16234520ae5SManish Awasthi 16334520ae5SManish Awasthi mana_do_service(dev->type, dev->pdev); 16434520ae5SManish Awasthi pci_dev_put(dev->pdev); 16534520ae5SManish Awasthi kfree(dev); 16634520ae5SManish Awasthi 16734520ae5SManish Awasthi spin_lock_irqsave(&work->lock, flags); 16834520ae5SManish Awasthi } 16934520ae5SManish Awasthi 17034520ae5SManish Awasthi spin_unlock_irqrestore(&work->lock, flags); 17134520ae5SManish Awasthi } 17234520ae5SManish Awasthi 17334520ae5SManish Awasthi static void mana_serv_func(struct work_struct *w) 17434520ae5SManish Awasthi { 17534520ae5SManish Awasthi struct mana_serv_work *mns_wk; 17634520ae5SManish Awasthi struct pci_dev *pdev; 17734520ae5SManish Awasthi 17834520ae5SManish Awasthi mns_wk = container_of(w, struct mana_serv_work, serv_work); 17934520ae5SManish Awasthi pdev = mns_wk->pdev; 18034520ae5SManish Awasthi 18134520ae5SManish Awasthi if (pdev) 18234520ae5SManish Awasthi mana_do_service(mns_wk->type, pdev); 18334520ae5SManish Awasthi 18434520ae5SManish Awasthi pci_dev_put(pdev); 18534520ae5SManish Awasthi kfree(mns_wk); 18634520ae5SManish Awasthi module_put(THIS_MODULE); 18734520ae5SManish Awasthi } 18834520ae5SManish Awasthi 18934520ae5SManish Awasthi static int mana_pci_schedule_serv_work(struct gdma_context *gc, 19034520ae5SManish Awasthi enum gdma_eqe_type type) 19134520ae5SManish Awasthi { 19234520ae5SManish Awasthi struct mana_serv_work *mns_wk; 19334520ae5SManish Awasthi 19434520ae5SManish Awasthi if (test_and_set_bit(GC_IN_SERVICE, &gc->flags)) { 19534520ae5SManish Awasthi dev_info(gc->dev, "Already in service\n"); 19634520ae5SManish Awasthi return -EBUSY; 19734520ae5SManish Awasthi } 19834520ae5SManish Awasthi 19934520ae5SManish Awasthi if (!try_module_get(THIS_MODULE)) { 20034520ae5SManish Awasthi dev_info(gc->dev, "Module is unloading\n"); 20134520ae5SManish Awasthi clear_bit(GC_IN_SERVICE, &gc->flags); 20234520ae5SManish Awasthi return -ENODEV; 20334520ae5SManish Awasthi } 20434520ae5SManish Awasthi 20534520ae5SManish Awasthi mns_wk = kzalloc(sizeof(*mns_wk), GFP_ATOMIC); 20634520ae5SManish Awasthi if (!mns_wk) { 20734520ae5SManish Awasthi module_put(THIS_MODULE); 20834520ae5SManish Awasthi clear_bit(GC_IN_SERVICE, &gc->flags); 20934520ae5SManish Awasthi return -ENOMEM; 21034520ae5SManish Awasthi } 21134520ae5SManish Awasthi 21234520ae5SManish Awasthi dev_info(gc->dev, "Start MANA service type:%d\n", type); 21334520ae5SManish Awasthi mns_wk->pdev = to_pci_dev(gc->dev); 21434520ae5SManish Awasthi mns_wk->type = type; 21534520ae5SManish Awasthi pci_dev_get(mns_wk->pdev); 21634520ae5SManish Awasthi INIT_WORK(&mns_wk->serv_work, mana_serv_func); 21734520ae5SManish Awasthi schedule_work(&mns_wk->serv_work); 21834520ae5SManish Awasthi return 0; 21934520ae5SManish Awasthi } 22034520ae5SManish Awasthi 22134520ae5SManish Awasthi static bool mana_pci_msix_can_alloc_dyn(struct gdma_context *gc) 22234520ae5SManish Awasthi { 22334520ae5SManish Awasthi return pci_msix_can_alloc_dyn(to_pci_dev(gc->dev)); 22434520ae5SManish Awasthi } 22534520ae5SManish Awasthi 22634520ae5SManish Awasthi static int mana_pci_msix_virq(struct gdma_context *gc, int msi) 22734520ae5SManish Awasthi { 22834520ae5SManish Awasthi return pci_irq_vector(to_pci_dev(gc->dev), msi); 22934520ae5SManish Awasthi } 23034520ae5SManish Awasthi 23134520ae5SManish Awasthi static int mana_pci_msix_alloc_at(struct gdma_context *gc, int *msi) 23234520ae5SManish Awasthi { 23334520ae5SManish Awasthi struct msi_map irq_map; 23434520ae5SManish Awasthi 23534520ae5SManish Awasthi irq_map = pci_msix_alloc_irq_at(to_pci_dev(gc->dev), *msi, NULL); 23634520ae5SManish Awasthi if (!irq_map.virq) 23734520ae5SManish Awasthi return irq_map.index; 23834520ae5SManish Awasthi 23934520ae5SManish Awasthi *msi = irq_map.index; 24034520ae5SManish Awasthi return irq_map.virq; 24134520ae5SManish Awasthi } 24234520ae5SManish Awasthi 24334520ae5SManish Awasthi static void mana_pci_msix_free(struct gdma_context *gc, int msi, int irq) 24434520ae5SManish Awasthi { 24534520ae5SManish Awasthi struct msi_map irq_map = { .virq = irq, .index = msi }; 24634520ae5SManish Awasthi 24734520ae5SManish Awasthi pci_msix_free_irq(to_pci_dev(gc->dev), irq_map); 24834520ae5SManish Awasthi } 24934520ae5SManish Awasthi 25034520ae5SManish Awasthi static int mana_pci_msix_vec_count(struct gdma_context *gc) 25134520ae5SManish Awasthi { 25234520ae5SManish Awasthi return pci_msix_vec_count(to_pci_dev(gc->dev)); 25334520ae5SManish Awasthi } 25434520ae5SManish Awasthi 25534520ae5SManish Awasthi static int mana_pci_dev_reset(struct gdma_context *gc) 25634520ae5SManish Awasthi { 25734520ae5SManish Awasthi return pcie_flr(to_pci_dev(gc->dev)); 25834520ae5SManish Awasthi } 25934520ae5SManish Awasthi 26034520ae5SManish Awasthi /* 26134520ae5SManish Awasthi * Spread on CPUs with the following heuristics: 26234520ae5SManish Awasthi * 26334520ae5SManish Awasthi * 1. No more than one IRQ per CPU, if possible; 26434520ae5SManish Awasthi * 2. NUMA locality is the second priority; 26534520ae5SManish Awasthi * 3. Sibling dislocality is the last priority. 26634520ae5SManish Awasthi * 26734520ae5SManish Awasthi * Let's consider this topology: 26834520ae5SManish Awasthi * 26934520ae5SManish Awasthi * Node 0 1 27034520ae5SManish Awasthi * Core 0 1 2 3 27134520ae5SManish Awasthi * CPU 0 1 2 3 4 5 6 7 27234520ae5SManish Awasthi * 27334520ae5SManish Awasthi * The most performant IRQ distribution based on the above topology 27434520ae5SManish Awasthi * and heuristics may look like this: 27534520ae5SManish Awasthi * 27634520ae5SManish Awasthi * IRQ Nodes Cores CPUs 27734520ae5SManish Awasthi * 0 1 0 0-1 27834520ae5SManish Awasthi * 1 1 1 2-3 27934520ae5SManish Awasthi * 2 1 0 0-1 28034520ae5SManish Awasthi * 3 1 1 2-3 28134520ae5SManish Awasthi * 4 2 2 4-5 28234520ae5SManish Awasthi * 5 2 3 6-7 28334520ae5SManish Awasthi * 6 2 2 4-5 28434520ae5SManish Awasthi * 7 2 3 6-7 28534520ae5SManish Awasthi * 28634520ae5SManish Awasthi * The heuristics is implemented as follows. 28734520ae5SManish Awasthi * 28834520ae5SManish Awasthi * The outer for_each() loop resets the 'weight' to the actual number 28934520ae5SManish Awasthi * of CPUs in the hop. Then inner for_each() loop decrements it by the 29034520ae5SManish Awasthi * number of sibling groups (cores) while assigning first set of IRQs 29134520ae5SManish Awasthi * to each group. IRQs 0 and 1 above are distributed this way. 29234520ae5SManish Awasthi * 29334520ae5SManish Awasthi * Now, because NUMA locality is more important, we should walk the 29434520ae5SManish Awasthi * same set of siblings and assign 2nd set of IRQs (2 and 3), and it's 29534520ae5SManish Awasthi * implemented by the medium while() loop. We do like this unless the 29634520ae5SManish Awasthi * number of IRQs assigned on this hop will not become equal to number 29734520ae5SManish Awasthi * of CPUs in the hop (weight == 0). Then we switch to the next hop and 29834520ae5SManish Awasthi * do the same thing. 29934520ae5SManish Awasthi */ 30034520ae5SManish Awasthi 30134520ae5SManish Awasthi static int mana_irq_setup_numa_aware(unsigned int *irqs, unsigned int len, 30234520ae5SManish Awasthi int node, bool skip_first_cpu) 30334520ae5SManish Awasthi { 30434520ae5SManish Awasthi const struct cpumask *next, *prev = cpu_none_mask; 30534520ae5SManish Awasthi cpumask_var_t cpus __free(free_cpumask_var); 30634520ae5SManish Awasthi int cpu, weight; 30734520ae5SManish Awasthi 30834520ae5SManish Awasthi if (!alloc_cpumask_var(&cpus, GFP_KERNEL)) 30934520ae5SManish Awasthi return -ENOMEM; 31034520ae5SManish Awasthi 31134520ae5SManish Awasthi rcu_read_lock(); 31234520ae5SManish Awasthi for_each_numa_hop_mask(next, node) { 31334520ae5SManish Awasthi weight = cpumask_weight_andnot(next, prev); 31434520ae5SManish Awasthi while (weight > 0) { 31534520ae5SManish Awasthi cpumask_andnot(cpus, next, prev); 31634520ae5SManish Awasthi for_each_cpu(cpu, cpus) { 31734520ae5SManish Awasthi cpumask_andnot(cpus, cpus, topology_sibling_cpumask(cpu)); 31834520ae5SManish Awasthi --weight; 31934520ae5SManish Awasthi 32034520ae5SManish Awasthi if (unlikely(skip_first_cpu)) { 32134520ae5SManish Awasthi skip_first_cpu = false; 32234520ae5SManish Awasthi continue; 32334520ae5SManish Awasthi } 32434520ae5SManish Awasthi 32534520ae5SManish Awasthi if (len-- == 0) 32634520ae5SManish Awasthi goto done; 32734520ae5SManish Awasthi 32834520ae5SManish Awasthi irq_set_affinity_and_hint(*irqs++, topology_sibling_cpumask(cpu)); 32934520ae5SManish Awasthi } 33034520ae5SManish Awasthi } 33134520ae5SManish Awasthi prev = next; 33234520ae5SManish Awasthi } 33334520ae5SManish Awasthi done: 33434520ae5SManish Awasthi rcu_read_unlock(); 33534520ae5SManish Awasthi return 0; 33634520ae5SManish Awasthi } 33734520ae5SManish Awasthi 33834520ae5SManish Awasthi /* must be called with cpus_read_lock() held */ 33934520ae5SManish Awasthi static void mana_irq_setup_linear(unsigned int *irqs, unsigned int len) 34034520ae5SManish Awasthi { 34134520ae5SManish Awasthi int cpu; 34234520ae5SManish Awasthi 34334520ae5SManish Awasthi for_each_online_cpu(cpu) { 34434520ae5SManish Awasthi if (len == 0) 34534520ae5SManish Awasthi break; 34634520ae5SManish Awasthi 34734520ae5SManish Awasthi irq_set_affinity_and_hint(*irqs++, cpumask_of(cpu)); 34834520ae5SManish Awasthi len--; 34934520ae5SManish Awasthi } 35034520ae5SManish Awasthi } 35134520ae5SManish Awasthi 35234520ae5SManish Awasthi static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec) 35334520ae5SManish Awasthi { 35434520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 35534520ae5SManish Awasthi struct gdma_irq_context *gic; 35634520ae5SManish Awasthi int *irqs, err, i, msi; 35734520ae5SManish Awasthi 35834520ae5SManish Awasthi irqs = kmalloc_objs(int, nvec); 35934520ae5SManish Awasthi if (!irqs) 36034520ae5SManish Awasthi return -ENOMEM; 36134520ae5SManish Awasthi 36234520ae5SManish Awasthi /* 36334520ae5SManish Awasthi * In this function, num_msix_usable = HWC IRQ + Queue IRQ. 36434520ae5SManish Awasthi * nvec is only Queue IRQ (HWC already setup). 36534520ae5SManish Awasthi * While processing the next pci irq vector, we start with index 1, 36634520ae5SManish Awasthi * as IRQ vector at index 0 is already processed for HWC. 36734520ae5SManish Awasthi * However, the population of irqs array starts with index 0, to be 36834520ae5SManish Awasthi * further used in mana_irq_setup_numa_aware() 36934520ae5SManish Awasthi */ 37034520ae5SManish Awasthi for (i = 1; i <= nvec; i++) { 37134520ae5SManish Awasthi msi = i; 37234520ae5SManish Awasthi gic = mana_gd_get_gic(gc, false, &msi); 37334520ae5SManish Awasthi if (IS_ERR(gic)) { 37434520ae5SManish Awasthi err = PTR_ERR(gic); 37534520ae5SManish Awasthi goto free_irq; 37634520ae5SManish Awasthi } 37734520ae5SManish Awasthi 37834520ae5SManish Awasthi irqs[i - 1] = gic->irq; 37934520ae5SManish Awasthi } 38034520ae5SManish Awasthi 38134520ae5SManish Awasthi /* 38234520ae5SManish Awasthi * When calling mana_irq_setup_numa_aware() for dynamically added IRQs, 38334520ae5SManish Awasthi * if number of CPUs is more than or equal to allocated MSI-X, we need to 38434520ae5SManish Awasthi * skip the first CPU sibling group since they are already affinitized to 38534520ae5SManish Awasthi * HWC IRQ 38634520ae5SManish Awasthi */ 38734520ae5SManish Awasthi cpus_read_lock(); 38834520ae5SManish Awasthi if (gc->num_msix_usable <= num_online_cpus()) { 38934520ae5SManish Awasthi err = mana_irq_setup_numa_aware(irqs, nvec, gc->numa_node, 39034520ae5SManish Awasthi true); 39134520ae5SManish Awasthi if (err) { 39234520ae5SManish Awasthi cpus_read_unlock(); 39334520ae5SManish Awasthi goto free_irq; 39434520ae5SManish Awasthi } 39534520ae5SManish Awasthi } else { 39634520ae5SManish Awasthi /* 39734520ae5SManish Awasthi * When num_msix_usable are more than num_online_cpus, our 39834520ae5SManish Awasthi * queue IRQs should be equal to num of online vCPUs. 39934520ae5SManish Awasthi * We try to make sure queue IRQs spread across all vCPUs. 40034520ae5SManish Awasthi * In such a case NUMA or CPU core affinity does not matter. 40134520ae5SManish Awasthi * Note: in this case the total mana IRQ should always be 40234520ae5SManish Awasthi * num_online_cpus + 1. The first HWC IRQ is already handled 40334520ae5SManish Awasthi * in HWC setup calls 40434520ae5SManish Awasthi * However, if CPUs went offline since num_msix_usable was 40534520ae5SManish Awasthi * computed, queue IRQs will be more than num_online_cpus(). 40634520ae5SManish Awasthi * In such cases remaining extra IRQs will retain their default 40734520ae5SManish Awasthi * affinity. 40834520ae5SManish Awasthi */ 40934520ae5SManish Awasthi int first_unassigned = num_online_cpus(); 41034520ae5SManish Awasthi 41134520ae5SManish Awasthi if (nvec > first_unassigned) { 41234520ae5SManish Awasthi char buf[32]; 41334520ae5SManish Awasthi 41434520ae5SManish Awasthi if (first_unassigned == nvec - 1) 41534520ae5SManish Awasthi snprintf(buf, sizeof(buf), "%d", 41634520ae5SManish Awasthi first_unassigned); 41734520ae5SManish Awasthi else 41834520ae5SManish Awasthi snprintf(buf, sizeof(buf), "%d-%d", 41934520ae5SManish Awasthi first_unassigned, nvec - 1); 42034520ae5SManish Awasthi 42134520ae5SManish Awasthi dev_dbg(&pdev->dev, 42234520ae5SManish Awasthi "MANA IRQ indices #%s will retain the default CPU affinity\n", 42334520ae5SManish Awasthi buf); 42434520ae5SManish Awasthi } 42534520ae5SManish Awasthi 42634520ae5SManish Awasthi mana_irq_setup_linear(irqs, nvec); 42734520ae5SManish Awasthi } 42834520ae5SManish Awasthi 42934520ae5SManish Awasthi cpus_read_unlock(); 43034520ae5SManish Awasthi kfree(irqs); 43134520ae5SManish Awasthi return 0; 43234520ae5SManish Awasthi 43334520ae5SManish Awasthi free_irq: 43434520ae5SManish Awasthi for (i -= 1; i > 0; i--) 43534520ae5SManish Awasthi mana_gd_put_gic(gc, false, i); 43634520ae5SManish Awasthi kfree(irqs); 43734520ae5SManish Awasthi return err; 43834520ae5SManish Awasthi } 43934520ae5SManish Awasthi 44034520ae5SManish Awasthi static int mana_gd_setup_irqs(struct pci_dev *pdev, int nvec) 44134520ae5SManish Awasthi { 44234520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 44334520ae5SManish Awasthi struct gdma_irq_context *gic; 44434520ae5SManish Awasthi int *irqs, *start_irqs; 44534520ae5SManish Awasthi unsigned int cpu; 44634520ae5SManish Awasthi int err, i, msi; 44734520ae5SManish Awasthi 44834520ae5SManish Awasthi irqs = kmalloc_objs(int, nvec); 44934520ae5SManish Awasthi if (!irqs) 45034520ae5SManish Awasthi return -ENOMEM; 45134520ae5SManish Awasthi 45234520ae5SManish Awasthi start_irqs = irqs; 45334520ae5SManish Awasthi 45434520ae5SManish Awasthi for (i = 0; i < nvec; i++) { 45534520ae5SManish Awasthi msi = i; 45634520ae5SManish Awasthi gic = mana_gd_get_gic(gc, false, &msi); 45734520ae5SManish Awasthi if (IS_ERR(gic)) { 45834520ae5SManish Awasthi err = PTR_ERR(gic); 45934520ae5SManish Awasthi goto free_irq; 46034520ae5SManish Awasthi } 46134520ae5SManish Awasthi 46234520ae5SManish Awasthi irqs[i] = gic->irq; 46334520ae5SManish Awasthi } 46434520ae5SManish Awasthi 46534520ae5SManish Awasthi /* If number of IRQ is one extra than number of online CPUs, 46634520ae5SManish Awasthi * then we need to assign IRQ0 (hwc irq) and IRQ1 to 46734520ae5SManish Awasthi * same CPU. 46834520ae5SManish Awasthi * Else we will use different CPUs for IRQ0 and IRQ1. 46934520ae5SManish Awasthi * Also we are using cpumask_local_spread instead of 47034520ae5SManish Awasthi * cpumask_first for the node, because the node can be 47134520ae5SManish Awasthi * mem only. 47234520ae5SManish Awasthi */ 47334520ae5SManish Awasthi cpus_read_lock(); 47434520ae5SManish Awasthi if (nvec > num_online_cpus()) { 47534520ae5SManish Awasthi cpu = cpumask_local_spread(0, gc->numa_node); 47634520ae5SManish Awasthi irq_set_affinity_and_hint(irqs[0], cpumask_of(cpu)); 47734520ae5SManish Awasthi irqs++; 47834520ae5SManish Awasthi nvec -= 1; 47934520ae5SManish Awasthi } 48034520ae5SManish Awasthi 48134520ae5SManish Awasthi err = mana_irq_setup_numa_aware(irqs, nvec, gc->numa_node, false); 48234520ae5SManish Awasthi if (err) { 48334520ae5SManish Awasthi cpus_read_unlock(); 48434520ae5SManish Awasthi goto free_irq; 48534520ae5SManish Awasthi } 48634520ae5SManish Awasthi 48734520ae5SManish Awasthi cpus_read_unlock(); 48834520ae5SManish Awasthi kfree(start_irqs); 48934520ae5SManish Awasthi return 0; 49034520ae5SManish Awasthi 49134520ae5SManish Awasthi free_irq: 49234520ae5SManish Awasthi for (i -= 1; i >= 0; i--) 49334520ae5SManish Awasthi mana_gd_put_gic(gc, false, i); 49434520ae5SManish Awasthi 49534520ae5SManish Awasthi kfree(start_irqs); 49634520ae5SManish Awasthi return err; 49734520ae5SManish Awasthi } 49834520ae5SManish Awasthi 49934520ae5SManish Awasthi static int mana_gd_setup_hwc_irqs(struct pci_dev *pdev) 50034520ae5SManish Awasthi { 50134520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 50234520ae5SManish Awasthi unsigned int max_irqs, min_irqs; 50334520ae5SManish Awasthi int nvec, err; 50434520ae5SManish Awasthi 50534520ae5SManish Awasthi if (pci_msix_can_alloc_dyn(pdev)) { 50634520ae5SManish Awasthi max_irqs = 1; 50734520ae5SManish Awasthi min_irqs = 1; 50834520ae5SManish Awasthi } else { 50934520ae5SManish Awasthi /* Need 1 interrupt for HWC */ 51034520ae5SManish Awasthi max_irqs = min(num_online_cpus(), MANA_MAX_NUM_QUEUES) + 1; 51134520ae5SManish Awasthi min_irqs = 2; 51234520ae5SManish Awasthi gc->msi_sharing = true; 51334520ae5SManish Awasthi } 51434520ae5SManish Awasthi 51534520ae5SManish Awasthi nvec = pci_alloc_irq_vectors(pdev, min_irqs, max_irqs, PCI_IRQ_MSIX); 51634520ae5SManish Awasthi if (nvec < 0) 51734520ae5SManish Awasthi return nvec; 51834520ae5SManish Awasthi 51934520ae5SManish Awasthi err = mana_gd_setup_irqs(pdev, nvec); 52034520ae5SManish Awasthi if (err) { 52134520ae5SManish Awasthi pci_free_irq_vectors(pdev); 52234520ae5SManish Awasthi return err; 52334520ae5SManish Awasthi } 52434520ae5SManish Awasthi 52534520ae5SManish Awasthi gc->num_msix_usable = nvec; 52634520ae5SManish Awasthi gc->max_num_msix = nvec; 52734520ae5SManish Awasthi 52834520ae5SManish Awasthi return 0; 52934520ae5SManish Awasthi } 53034520ae5SManish Awasthi 53134520ae5SManish Awasthi static int mana_gd_setup_remaining_irqs(struct pci_dev *pdev) 53234520ae5SManish Awasthi { 53334520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 53434520ae5SManish Awasthi struct msi_map irq_map; 53534520ae5SManish Awasthi int max_irqs, i, err; 53634520ae5SManish Awasthi 53734520ae5SManish Awasthi if (!pci_msix_can_alloc_dyn(pdev)) 53834520ae5SManish Awasthi /* remain irqs are already allocated with HWC IRQ */ 53934520ae5SManish Awasthi return 0; 54034520ae5SManish Awasthi 54134520ae5SManish Awasthi /* allocate only remaining IRQs*/ 54234520ae5SManish Awasthi max_irqs = gc->num_msix_usable - 1; 54334520ae5SManish Awasthi 54434520ae5SManish Awasthi for (i = 1; i <= max_irqs; i++) { 54534520ae5SManish Awasthi irq_map = pci_msix_alloc_irq_at(pdev, i, NULL); 54634520ae5SManish Awasthi if (!irq_map.virq) { 54734520ae5SManish Awasthi err = irq_map.index; 54834520ae5SManish Awasthi /* caller will handle cleaning up all allocated 54934520ae5SManish Awasthi * irqs, after HWC is destroyed 55034520ae5SManish Awasthi */ 55134520ae5SManish Awasthi return err; 55234520ae5SManish Awasthi } 55334520ae5SManish Awasthi } 55434520ae5SManish Awasthi 55534520ae5SManish Awasthi err = mana_gd_setup_dyn_irqs(pdev, max_irqs); 55634520ae5SManish Awasthi if (err) 55734520ae5SManish Awasthi return err; 55834520ae5SManish Awasthi 55934520ae5SManish Awasthi gc->max_num_msix = gc->max_num_msix + max_irqs; 56034520ae5SManish Awasthi 56134520ae5SManish Awasthi return 0; 56234520ae5SManish Awasthi } 56334520ae5SManish Awasthi 56434520ae5SManish Awasthi static void mana_gd_remove_irqs(struct pci_dev *pdev) 56534520ae5SManish Awasthi { 56634520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 56734520ae5SManish Awasthi int i; 56834520ae5SManish Awasthi 56934520ae5SManish Awasthi if (gc->max_num_msix < 1) 57034520ae5SManish Awasthi return; 57134520ae5SManish Awasthi 57234520ae5SManish Awasthi for (i = 0; i < gc->max_num_msix; i++) { 57334520ae5SManish Awasthi if (!xa_load(&gc->irq_contexts, i)) 57434520ae5SManish Awasthi continue; 57534520ae5SManish Awasthi 57634520ae5SManish Awasthi mana_gd_put_gic(gc, false, i); 57734520ae5SManish Awasthi } 57834520ae5SManish Awasthi 57934520ae5SManish Awasthi WARN_ON(!xa_empty(&gc->irq_contexts)); 58034520ae5SManish Awasthi 58134520ae5SManish Awasthi pci_free_irq_vectors(pdev); 58234520ae5SManish Awasthi 58334520ae5SManish Awasthi bitmap_free(gc->msi_bitmap); 58434520ae5SManish Awasthi gc->msi_bitmap = NULL; 58534520ae5SManish Awasthi gc->max_num_msix = 0; 58634520ae5SManish Awasthi gc->num_msix_usable = 0; 58734520ae5SManish Awasthi } 58834520ae5SManish Awasthi 58934520ae5SManish Awasthi static int mana_pci_setup_hwc_irqs(struct gdma_context *gc) 59034520ae5SManish Awasthi { 59134520ae5SManish Awasthi return mana_gd_setup_hwc_irqs(to_pci_dev(gc->dev)); 59234520ae5SManish Awasthi } 59334520ae5SManish Awasthi 59434520ae5SManish Awasthi static int mana_pci_setup_remaining_irqs(struct gdma_context *gc) 59534520ae5SManish Awasthi { 59634520ae5SManish Awasthi int err; 59734520ae5SManish Awasthi 59834520ae5SManish Awasthi err = mana_gd_setup_remaining_irqs(to_pci_dev(gc->dev)); 59934520ae5SManish Awasthi if (err) { 60034520ae5SManish Awasthi dev_err(gc->dev, "Failed to setup remaining IRQs: %d", err); 60134520ae5SManish Awasthi return err; 60234520ae5SManish Awasthi } 60334520ae5SManish Awasthi 60434520ae5SManish Awasthi if (!gc->msi_sharing) { 60534520ae5SManish Awasthi gc->msi_bitmap = bitmap_zalloc(gc->num_msix_usable, GFP_KERNEL); 60634520ae5SManish Awasthi if (!gc->msi_bitmap) 60734520ae5SManish Awasthi return -ENOMEM; 60834520ae5SManish Awasthi /* Set bit for HWC */ 60934520ae5SManish Awasthi set_bit(0, gc->msi_bitmap); 61034520ae5SManish Awasthi } 61134520ae5SManish Awasthi 61234520ae5SManish Awasthi return 0; 61334520ae5SManish Awasthi } 61434520ae5SManish Awasthi 61534520ae5SManish Awasthi static void mana_pci_remove_irqs(struct gdma_context *gc) 61634520ae5SManish Awasthi { 61734520ae5SManish Awasthi mana_gd_remove_irqs(to_pci_dev(gc->dev)); 61834520ae5SManish Awasthi } 61934520ae5SManish Awasthi 62034520ae5SManish Awasthi static const struct gdma_bus_ops mana_pci_bus_ops = { 62134520ae5SManish Awasthi .bus_name = "pci", 622*3d6792eaSManish Awasthi .adev_prefix = "mana", 62334520ae5SManish Awasthi .msix_can_alloc_dyn = mana_pci_msix_can_alloc_dyn, 62434520ae5SManish Awasthi .msix_virq = mana_pci_msix_virq, 62534520ae5SManish Awasthi .msix_alloc_at = mana_pci_msix_alloc_at, 62634520ae5SManish Awasthi .msix_free = mana_pci_msix_free, 62734520ae5SManish Awasthi .msix_vec_count = mana_pci_msix_vec_count, 62834520ae5SManish Awasthi .setup_hwc_irqs = mana_pci_setup_hwc_irqs, 62934520ae5SManish Awasthi .setup_remaining_irqs = mana_pci_setup_remaining_irqs, 63034520ae5SManish Awasthi .remove_irqs = mana_pci_remove_irqs, 63134520ae5SManish Awasthi .dev_reset = mana_pci_dev_reset, 63234520ae5SManish Awasthi .schedule_serv_work = mana_pci_schedule_serv_work, 63334520ae5SManish Awasthi .drv_cap_flags1 = GDMA_DRV_CAP_FLAGS1_PCI, 63434520ae5SManish Awasthi }; 63534520ae5SManish Awasthi 63634520ae5SManish Awasthi static bool mana_is_pf(unsigned short dev_id) 63734520ae5SManish Awasthi { 63834520ae5SManish Awasthi return dev_id == MANA_PF_DEVICE_ID || dev_id == MANA_PF2_DEVICE_ID; 63934520ae5SManish Awasthi } 64034520ae5SManish Awasthi 64134520ae5SManish Awasthi static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 64234520ae5SManish Awasthi { 64334520ae5SManish Awasthi struct gdma_context *gc; 64434520ae5SManish Awasthi void __iomem *bar0_va; 64534520ae5SManish Awasthi int bar = 0; 64634520ae5SManish Awasthi int err; 64734520ae5SManish Awasthi 64834520ae5SManish Awasthi /* Each port has 2 CQs, each CQ has at most 1 EQE at a time */ 64934520ae5SManish Awasthi BUILD_BUG_ON(2 * MAX_PORTS_IN_MANA_DEV * GDMA_EQE_SIZE > EQ_SIZE); 65034520ae5SManish Awasthi 65134520ae5SManish Awasthi err = pci_enable_device(pdev); 65234520ae5SManish Awasthi if (err) { 65334520ae5SManish Awasthi dev_err(&pdev->dev, "Failed to enable pci device (err=%d)\n", err); 65434520ae5SManish Awasthi return -ENXIO; 65534520ae5SManish Awasthi } 65634520ae5SManish Awasthi 65734520ae5SManish Awasthi pci_set_master(pdev); 65834520ae5SManish Awasthi 65934520ae5SManish Awasthi err = pci_request_regions(pdev, "mana"); 66034520ae5SManish Awasthi if (err) 66134520ae5SManish Awasthi goto disable_dev; 66234520ae5SManish Awasthi 66334520ae5SManish Awasthi err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); 66434520ae5SManish Awasthi if (err) { 66534520ae5SManish Awasthi dev_err(&pdev->dev, "DMA set mask failed: %d\n", err); 66634520ae5SManish Awasthi goto release_region; 66734520ae5SManish Awasthi } 66834520ae5SManish Awasthi dma_set_max_seg_size(&pdev->dev, UINT_MAX); 66934520ae5SManish Awasthi 67034520ae5SManish Awasthi err = -ENOMEM; 67134520ae5SManish Awasthi gc = vzalloc(sizeof(*gc)); 67234520ae5SManish Awasthi if (!gc) 67334520ae5SManish Awasthi goto release_region; 67434520ae5SManish Awasthi 67534520ae5SManish Awasthi mutex_init(&gc->eq_test_event_mutex); 67634520ae5SManish Awasthi mutex_init(&gc->gic_mutex); 67734520ae5SManish Awasthi pci_set_drvdata(pdev, gc); 67834520ae5SManish Awasthi gc->bar0_pa = pci_resource_start(pdev, 0); 67934520ae5SManish Awasthi gc->bar0_size = pci_resource_len(pdev, 0); 68034520ae5SManish Awasthi 68134520ae5SManish Awasthi bar0_va = pci_iomap(pdev, bar, 0); 68234520ae5SManish Awasthi if (!bar0_va) 68334520ae5SManish Awasthi goto free_gc; 68434520ae5SManish Awasthi 68534520ae5SManish Awasthi gc->numa_node = dev_to_node(&pdev->dev); 68634520ae5SManish Awasthi gc->is_pf = mana_is_pf(pdev->device); 68734520ae5SManish Awasthi gc->is_pf2 = (pdev->device == MANA_PF2_DEVICE_ID); 68834520ae5SManish Awasthi 68934520ae5SManish Awasthi gc->bar0_va = bar0_va; 69034520ae5SManish Awasthi gc->dev = &pdev->dev; 69134520ae5SManish Awasthi gc->bus_ops = &mana_pci_bus_ops; 69234520ae5SManish Awasthi xa_init(&gc->irq_contexts); 69334520ae5SManish Awasthi 69434520ae5SManish Awasthi err = mana_gd_setup(gc); 69534520ae5SManish Awasthi if (err) 69634520ae5SManish Awasthi goto unmap_bar; 69734520ae5SManish Awasthi 69834520ae5SManish Awasthi err = mana_probe(&gc->mana, false); 69934520ae5SManish Awasthi if (err) 70034520ae5SManish Awasthi goto cleanup_gd; 70134520ae5SManish Awasthi 70234520ae5SManish Awasthi err = mana_rdma_probe(&gc->mana_ib); 70334520ae5SManish Awasthi if (err) 70434520ae5SManish Awasthi goto cleanup_mana; 70534520ae5SManish Awasthi 70634520ae5SManish Awasthi /* 70734520ae5SManish Awasthi * If a hardware reset event has occurred over HWC during probe, 70834520ae5SManish Awasthi * rollback and perform hardware reset procedure. 70934520ae5SManish Awasthi */ 71034520ae5SManish Awasthi if (test_and_set_bit(GC_PROBE_SUCCEEDED, &gc->flags)) { 71134520ae5SManish Awasthi err = -EPROTO; 71234520ae5SManish Awasthi goto cleanup_mana_rdma; 71334520ae5SManish Awasthi } 71434520ae5SManish Awasthi 71534520ae5SManish Awasthi return 0; 71634520ae5SManish Awasthi 71734520ae5SManish Awasthi cleanup_mana_rdma: 71834520ae5SManish Awasthi mana_rdma_remove(&gc->mana_ib); 71934520ae5SManish Awasthi cleanup_mana: 72034520ae5SManish Awasthi mana_remove(&gc->mana, false); 72134520ae5SManish Awasthi cleanup_gd: 72234520ae5SManish Awasthi mana_gd_cleanup(gc); 72334520ae5SManish Awasthi unmap_bar: 72434520ae5SManish Awasthi xa_destroy(&gc->irq_contexts); 72534520ae5SManish Awasthi pci_iounmap(pdev, bar0_va); 72634520ae5SManish Awasthi free_gc: 72734520ae5SManish Awasthi pci_set_drvdata(pdev, NULL); 72834520ae5SManish Awasthi vfree(gc); 72934520ae5SManish Awasthi release_region: 73034520ae5SManish Awasthi pci_release_regions(pdev); 73134520ae5SManish Awasthi disable_dev: 73234520ae5SManish Awasthi pci_disable_device(pdev); 73334520ae5SManish Awasthi dev_err(&pdev->dev, "gdma probe failed: err = %d\n", err); 73434520ae5SManish Awasthi 73534520ae5SManish Awasthi /* 73634520ae5SManish Awasthi * Hardware could be in recovery mode and the HWC returns TIMEDOUT or 73734520ae5SManish Awasthi * EPROTO from mana_gd_setup(), mana_probe() or mana_rdma_probe(), or 73834520ae5SManish Awasthi * we received a hardware reset event over HWC interrupt. In this case, 73934520ae5SManish Awasthi * perform the device recovery procedure after MANA_SERVICE_PERIOD 74034520ae5SManish Awasthi * seconds. 74134520ae5SManish Awasthi */ 74234520ae5SManish Awasthi if (err == -ETIMEDOUT || err == -EPROTO) { 74334520ae5SManish Awasthi struct mana_dev_recovery *dev; 74434520ae5SManish Awasthi unsigned long flags; 74534520ae5SManish Awasthi 74634520ae5SManish Awasthi dev_info(&pdev->dev, "Start MANA recovery mode\n"); 74734520ae5SManish Awasthi 74834520ae5SManish Awasthi dev = kzalloc_obj(*dev); 74934520ae5SManish Awasthi if (!dev) 75034520ae5SManish Awasthi return err; 75134520ae5SManish Awasthi 75234520ae5SManish Awasthi dev->pdev = pci_dev_get(pdev); 75334520ae5SManish Awasthi dev->type = GDMA_EQE_HWC_RESET_REQUEST; 75434520ae5SManish Awasthi 75534520ae5SManish Awasthi spin_lock_irqsave(&mana_dev_recovery_work.lock, flags); 75634520ae5SManish Awasthi list_add_tail(&dev->list, &mana_dev_recovery_work.dev_list); 75734520ae5SManish Awasthi spin_unlock_irqrestore(&mana_dev_recovery_work.lock, flags); 75834520ae5SManish Awasthi 75934520ae5SManish Awasthi schedule_delayed_work(&mana_dev_recovery_work.work, 76034520ae5SManish Awasthi secs_to_jiffies(MANA_SERVICE_PERIOD)); 76134520ae5SManish Awasthi } 76234520ae5SManish Awasthi 76334520ae5SManish Awasthi return err; 76434520ae5SManish Awasthi } 76534520ae5SManish Awasthi 76634520ae5SManish Awasthi static void mana_gd_remove(struct pci_dev *pdev) 76734520ae5SManish Awasthi { 76834520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 76934520ae5SManish Awasthi 77034520ae5SManish Awasthi pci_disable_sriov(pdev); 77134520ae5SManish Awasthi 77234520ae5SManish Awasthi mana_rdma_remove(&gc->mana_ib); 77334520ae5SManish Awasthi mana_remove(&gc->mana, false); 77434520ae5SManish Awasthi 77534520ae5SManish Awasthi mana_gd_cleanup(gc); 77634520ae5SManish Awasthi 77734520ae5SManish Awasthi xa_destroy(&gc->irq_contexts); 77834520ae5SManish Awasthi 77934520ae5SManish Awasthi pci_iounmap(pdev, gc->bar0_va); 78034520ae5SManish Awasthi 78134520ae5SManish Awasthi vfree(gc); 78234520ae5SManish Awasthi 78334520ae5SManish Awasthi pci_release_regions(pdev); 78434520ae5SManish Awasthi pci_disable_device(pdev); 78534520ae5SManish Awasthi 78634520ae5SManish Awasthi dev_dbg(&pdev->dev, "mana gdma remove successful\n"); 78734520ae5SManish Awasthi } 78834520ae5SManish Awasthi 78934520ae5SManish Awasthi /* The 'state' parameter is not used. */ 79034520ae5SManish Awasthi static int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state) 79134520ae5SManish Awasthi { 79234520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 79334520ae5SManish Awasthi 79434520ae5SManish Awasthi mana_rdma_remove(&gc->mana_ib); 79534520ae5SManish Awasthi mana_remove(&gc->mana, true); 79634520ae5SManish Awasthi 79734520ae5SManish Awasthi mana_gd_cleanup(gc); 79834520ae5SManish Awasthi 79934520ae5SManish Awasthi return 0; 80034520ae5SManish Awasthi } 80134520ae5SManish Awasthi 80234520ae5SManish Awasthi static int mana_gd_resume(struct pci_dev *pdev) 80334520ae5SManish Awasthi { 80434520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 80534520ae5SManish Awasthi int err; 80634520ae5SManish Awasthi 80734520ae5SManish Awasthi err = mana_gd_setup(gc); 80834520ae5SManish Awasthi if (err) 80934520ae5SManish Awasthi return err; 81034520ae5SManish Awasthi 81134520ae5SManish Awasthi err = mana_probe(&gc->mana, true); 81234520ae5SManish Awasthi if (err) 81334520ae5SManish Awasthi goto cleanup_gd; 81434520ae5SManish Awasthi 81534520ae5SManish Awasthi err = mana_rdma_probe(&gc->mana_ib); 81634520ae5SManish Awasthi if (err) 81734520ae5SManish Awasthi mana_rdma_remove(&gc->mana_ib); 81834520ae5SManish Awasthi 81934520ae5SManish Awasthi return err; 82034520ae5SManish Awasthi 82134520ae5SManish Awasthi cleanup_gd: 82234520ae5SManish Awasthi mana_gd_cleanup(gc); 82334520ae5SManish Awasthi return err; 82434520ae5SManish Awasthi } 82534520ae5SManish Awasthi 82634520ae5SManish Awasthi /* Quiesce the device for kexec. This is also called upon reboot/shutdown. */ 82734520ae5SManish Awasthi static void mana_gd_shutdown(struct pci_dev *pdev) 82834520ae5SManish Awasthi { 82934520ae5SManish Awasthi struct gdma_context *gc = pci_get_drvdata(pdev); 83034520ae5SManish Awasthi 83134520ae5SManish Awasthi dev_info(&pdev->dev, "Shutdown was called\n"); 83234520ae5SManish Awasthi 83334520ae5SManish Awasthi mana_rdma_remove(&gc->mana_ib); 83434520ae5SManish Awasthi mana_remove(&gc->mana, true); 83534520ae5SManish Awasthi 83634520ae5SManish Awasthi mana_gd_cleanup(gc); 83734520ae5SManish Awasthi 83834520ae5SManish Awasthi pci_disable_device(pdev); 83934520ae5SManish Awasthi } 84034520ae5SManish Awasthi 84134520ae5SManish Awasthi static int mana_sriov_configure(struct pci_dev *pdev, int numvfs) 84234520ae5SManish Awasthi { 84334520ae5SManish Awasthi int err = 0; 84434520ae5SManish Awasthi 84534520ae5SManish Awasthi dev_info(&pdev->dev, "Requested num VFs: %d\n", numvfs); 84634520ae5SManish Awasthi 84734520ae5SManish Awasthi if (numvfs > 0) { 84834520ae5SManish Awasthi err = pci_enable_sriov(pdev, numvfs); 84934520ae5SManish Awasthi } else { 85034520ae5SManish Awasthi if (pci_vfs_assigned(pdev)) { 85134520ae5SManish Awasthi dev_warn(&pdev->dev, 85234520ae5SManish Awasthi "Cannot disable SR-IOV while VFs are assigned\n"); 85334520ae5SManish Awasthi return -EPERM; 85434520ae5SManish Awasthi } 85534520ae5SManish Awasthi 85634520ae5SManish Awasthi pci_disable_sriov(pdev); 85734520ae5SManish Awasthi } 85834520ae5SManish Awasthi 85934520ae5SManish Awasthi return err ? err : numvfs; 86034520ae5SManish Awasthi } 86134520ae5SManish Awasthi 86234520ae5SManish Awasthi static const struct pci_device_id mana_id_table[] = { 86334520ae5SManish Awasthi { PCI_DEVICE(PCI_VENDOR_ID_MICROSOFT, MANA_PF_DEVICE_ID) }, 86434520ae5SManish Awasthi { PCI_DEVICE(PCI_VENDOR_ID_MICROSOFT, MANA_PF2_DEVICE_ID) }, 86534520ae5SManish Awasthi { PCI_DEVICE(PCI_VENDOR_ID_MICROSOFT, MANA_VF_DEVICE_ID) }, 86634520ae5SManish Awasthi { } 86734520ae5SManish Awasthi }; 86834520ae5SManish Awasthi 86934520ae5SManish Awasthi static struct pci_driver mana_driver = { 87034520ae5SManish Awasthi .name = "mana", 87134520ae5SManish Awasthi .id_table = mana_id_table, 87234520ae5SManish Awasthi .probe = mana_gd_probe, 87334520ae5SManish Awasthi .remove = mana_gd_remove, 87434520ae5SManish Awasthi .suspend = mana_gd_suspend, 87534520ae5SManish Awasthi .resume = mana_gd_resume, 87634520ae5SManish Awasthi .shutdown = mana_gd_shutdown, 87734520ae5SManish Awasthi .sriov_configure = mana_sriov_configure, 87834520ae5SManish Awasthi }; 87934520ae5SManish Awasthi 88034520ae5SManish Awasthi MODULE_DEVICE_TABLE(pci, mana_id_table); 88134520ae5SManish Awasthi 882445927deSManish Awasthi static int __init mana_driver_init(void) 88334520ae5SManish Awasthi { 88434520ae5SManish Awasthi INIT_LIST_HEAD(&mana_dev_recovery_work.dev_list); 88534520ae5SManish Awasthi spin_lock_init(&mana_dev_recovery_work.lock); 88634520ae5SManish Awasthi INIT_DELAYED_WORK(&mana_dev_recovery_work.work, 88734520ae5SManish Awasthi mana_recovery_delayed_func); 88834520ae5SManish Awasthi 88934520ae5SManish Awasthi return pci_register_driver(&mana_driver); 89034520ae5SManish Awasthi } 89134520ae5SManish Awasthi 892445927deSManish Awasthi static void __exit mana_driver_exit(void) 89334520ae5SManish Awasthi { 89434520ae5SManish Awasthi struct mana_dev_recovery *dev; 89534520ae5SManish Awasthi unsigned long flags; 89634520ae5SManish Awasthi 89734520ae5SManish Awasthi disable_delayed_work_sync(&mana_dev_recovery_work.work); 89834520ae5SManish Awasthi 89934520ae5SManish Awasthi spin_lock_irqsave(&mana_dev_recovery_work.lock, flags); 90034520ae5SManish Awasthi while (!list_empty(&mana_dev_recovery_work.dev_list)) { 90134520ae5SManish Awasthi dev = list_first_entry(&mana_dev_recovery_work.dev_list, 90234520ae5SManish Awasthi struct mana_dev_recovery, list); 90334520ae5SManish Awasthi list_del(&dev->list); 90434520ae5SManish Awasthi pci_dev_put(dev->pdev); 90534520ae5SManish Awasthi kfree(dev); 90634520ae5SManish Awasthi } 90734520ae5SManish Awasthi spin_unlock_irqrestore(&mana_dev_recovery_work.lock, flags); 90834520ae5SManish Awasthi 90934520ae5SManish Awasthi pci_unregister_driver(&mana_driver); 91034520ae5SManish Awasthi } 911445927deSManish Awasthi 912445927deSManish Awasthi module_init(mana_driver_init); 913445927deSManish Awasthi module_exit(mana_driver_exit); 914445927deSManish Awasthi 915445927deSManish Awasthi MODULE_LICENSE("Dual BSD/GPL"); 916445927deSManish Awasthi MODULE_DESCRIPTION("Microsoft Azure Network Adapter driver"); 917445927deSManish Awasthi MODULE_IMPORT_NS("NET_MANA"); 918