0001
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
0013
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
0084 atomic_set(&ndev->state, __NDEV_NOT_READY);
0085
0086 nitrox_crypto_unregister();
0087
0088
0089 nitrox_unregister_interrupts(ndev);
0090 nitrox_common_sw_cleanup(ndev);
0091 }
0092
0093
0094
0095
0096
0097 static int nitrox_pf_reinit(struct nitrox_device *ndev)
0098 {
0099 int err;
0100
0101
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
0113 nitrox_config_aqm_rings(ndev);
0114
0115
0116 nitrox_config_pkt_input_rings(ndev);
0117 nitrox_config_pkt_solicit_ports(ndev);
0118
0119
0120 atomic_set(&ndev->state, __NDEV_READY);
0121
0122
0123 return nitrox_crypto_register();
0124 }
0125
0126 static void nitrox_sriov_cleanup(struct nitrox_device *ndev)
0127 {
0128
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
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
0177 set_bit(__NDEV_SRIOV_BIT, &ndev->flags);
0178
0179
0180 nitrox_pf_cleanup(ndev);
0181
0182
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
0193 clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
0194 ndev->iov.num_vfs = 0;
0195 ndev->mode = __NDEV_MODE_PF;
0196
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
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
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 }