Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/pci.h>
0003 #include <linux/delay.h>
0004 
0005 #include "nitrox_dev.h"
0006 #include "nitrox_hal.h"
0007 #include "nitrox_common.h"
0008 #include "nitrox_isr.h"
0009 #include "nitrox_mbx.h"
0010 
0011 /**
0012  * num_vfs_valid - validate VF count
0013  * @num_vfs: number of VF(s)
0014  */
0015 static inline bool num_vfs_valid(int num_vfs)
0016 {
0017     bool valid = false;
0018 
0019     switch (num_vfs) {
0020     case 16:
0021     case 32:
0022     case 64:
0023     case 128:
0024         valid = true;
0025         break;
0026     }
0027 
0028     return valid;
0029 }
0030 
0031 static inline enum vf_mode num_vfs_to_mode(int num_vfs)
0032 {
0033     enum vf_mode mode = 0;
0034 
0035     switch (num_vfs) {
0036     case 0:
0037         mode = __NDEV_MODE_PF;
0038         break;
0039     case 16:
0040         mode = __NDEV_MODE_VF16;
0041         break;
0042     case 32:
0043         mode = __NDEV_MODE_VF32;
0044         break;
0045     case 64:
0046         mode = __NDEV_MODE_VF64;
0047         break;
0048     case 128:
0049         mode = __NDEV_MODE_VF128;
0050         break;
0051     }
0052 
0053     return mode;
0054 }
0055 
0056 static inline int vf_mode_to_nr_queues(enum vf_mode mode)
0057 {
0058     int nr_queues = 0;
0059 
0060     switch (mode) {
0061     case __NDEV_MODE_PF:
0062         nr_queues = MAX_PF_QUEUES;
0063         break;
0064     case __NDEV_MODE_VF16:
0065         nr_queues = 8;
0066         break;
0067     case __NDEV_MODE_VF32:
0068         nr_queues = 4;
0069         break;
0070     case __NDEV_MODE_VF64:
0071         nr_queues = 2;
0072         break;
0073     case __NDEV_MODE_VF128:
0074         nr_queues = 1;
0075         break;
0076     }
0077 
0078     return nr_queues;
0079 }
0080 
0081 static void nitrox_pf_cleanup(struct nitrox_device *ndev)
0082 {
0083      /* PF has no queues in SR-IOV mode */
0084     atomic_set(&ndev->state, __NDEV_NOT_READY);
0085     /* unregister crypto algorithms */
0086     nitrox_crypto_unregister();
0087 
0088     /* cleanup PF resources */
0089     nitrox_unregister_interrupts(ndev);
0090     nitrox_common_sw_cleanup(ndev);
0091 }
0092 
0093 /**
0094  * nitrox_pf_reinit - re-initialize PF resources once SR-IOV is disabled
0095  * @ndev: NITROX device
0096  */
0097 static int nitrox_pf_reinit(struct nitrox_device *ndev)
0098 {
0099     int err;
0100 
0101     /* allocate resources for PF */
0102     err = nitrox_common_sw_init(ndev);
0103     if (err)
0104         return err;
0105 
0106     err = nitrox_register_interrupts(ndev);
0107     if (err) {
0108         nitrox_common_sw_cleanup(ndev);
0109         return err;
0110     }
0111 
0112     /* configure the AQM queues */
0113     nitrox_config_aqm_rings(ndev);
0114 
0115     /* configure the packet queues */
0116     nitrox_config_pkt_input_rings(ndev);
0117     nitrox_config_pkt_solicit_ports(ndev);
0118 
0119     /* set device to ready state */
0120     atomic_set(&ndev->state, __NDEV_READY);
0121 
0122     /* register crypto algorithms */
0123     return nitrox_crypto_register();
0124 }
0125 
0126 static void nitrox_sriov_cleanup(struct nitrox_device *ndev)
0127 {
0128     /* unregister interrupts for PF in SR-IOV */
0129     nitrox_sriov_unregister_interrupts(ndev);
0130     nitrox_mbox_cleanup(ndev);
0131 }
0132 
0133 static int nitrox_sriov_init(struct nitrox_device *ndev)
0134 {
0135     int ret;
0136 
0137     /* register interrupts for PF in SR-IOV */
0138     ret = nitrox_sriov_register_interupts(ndev);
0139     if (ret)
0140         return ret;
0141 
0142     ret = nitrox_mbox_init(ndev);
0143     if (ret)
0144         goto sriov_init_fail;
0145 
0146     return 0;
0147 
0148 sriov_init_fail:
0149     nitrox_sriov_cleanup(ndev);
0150     return ret;
0151 }
0152 
0153 static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs)
0154 {
0155     struct nitrox_device *ndev = pci_get_drvdata(pdev);
0156     int err;
0157 
0158     if (!num_vfs_valid(num_vfs)) {
0159         dev_err(DEV(ndev), "Invalid num_vfs %d\n", num_vfs);
0160         return -EINVAL;
0161     }
0162 
0163     if (pci_num_vf(pdev) == num_vfs)
0164         return num_vfs;
0165 
0166     err = pci_enable_sriov(pdev, num_vfs);
0167     if (err) {
0168         dev_err(DEV(ndev), "failed to enable PCI sriov %d\n", err);
0169         return err;
0170     }
0171     dev_info(DEV(ndev), "Enabled VF(s) %d\n", num_vfs);
0172 
0173     ndev->mode = num_vfs_to_mode(num_vfs);
0174     ndev->iov.num_vfs = num_vfs;
0175     ndev->iov.max_vf_queues = vf_mode_to_nr_queues(ndev->mode);
0176     /* set bit in flags */
0177     set_bit(__NDEV_SRIOV_BIT, &ndev->flags);
0178 
0179     /* cleanup PF resources */
0180     nitrox_pf_cleanup(ndev);
0181 
0182     /* PF SR-IOV mode initialization */
0183     err = nitrox_sriov_init(ndev);
0184     if (err)
0185         goto iov_fail;
0186 
0187     config_nps_core_vfcfg_mode(ndev, ndev->mode);
0188     return num_vfs;
0189 
0190 iov_fail:
0191     pci_disable_sriov(pdev);
0192     /* clear bit in flags */
0193     clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
0194     ndev->iov.num_vfs = 0;
0195     ndev->mode = __NDEV_MODE_PF;
0196     /* reset back to working mode in PF */
0197     nitrox_pf_reinit(ndev);
0198     return err;
0199 }
0200 
0201 static int nitrox_sriov_disable(struct pci_dev *pdev)
0202 {
0203     struct nitrox_device *ndev = pci_get_drvdata(pdev);
0204 
0205     if (!test_bit(__NDEV_SRIOV_BIT, &ndev->flags))
0206         return 0;
0207 
0208     if (pci_vfs_assigned(pdev)) {
0209         dev_warn(DEV(ndev), "VFs are attached to VM. Can't disable SR-IOV\n");
0210         return -EPERM;
0211     }
0212     pci_disable_sriov(pdev);
0213     /* clear bit in flags */
0214     clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
0215 
0216     ndev->iov.num_vfs = 0;
0217     ndev->iov.max_vf_queues = 0;
0218     ndev->mode = __NDEV_MODE_PF;
0219 
0220     /* cleanup PF SR-IOV resources */
0221     nitrox_sriov_cleanup(ndev);
0222 
0223     config_nps_core_vfcfg_mode(ndev, ndev->mode);
0224 
0225     return nitrox_pf_reinit(ndev);
0226 }
0227 
0228 int nitrox_sriov_configure(struct pci_dev *pdev, int num_vfs)
0229 {
0230     if (!num_vfs)
0231         return nitrox_sriov_disable(pdev);
0232 
0233     return nitrox_sriov_enable(pdev, num_vfs);
0234 }