root/drivers/crypto/cavium/nitrox/nitrox_sriov.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. num_vfs_valid
  2. num_vfs_to_mode
  3. vf_mode_to_nr_queues
  4. nitrox_pf_cleanup
  5. nitrox_pf_reinit
  6. nitrox_sriov_cleanup
  7. nitrox_sriov_init
  8. nitrox_sriov_enable
  9. nitrox_sriov_disable
  10. nitrox_sriov_configure

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/pci.h>
   3 #include <linux/delay.h>
   4 
   5 #include "nitrox_dev.h"
   6 #include "nitrox_hal.h"
   7 #include "nitrox_common.h"
   8 #include "nitrox_isr.h"
   9 #include "nitrox_mbx.h"
  10 
  11 /**
  12  * num_vfs_valid - validate VF count
  13  * @num_vfs: number of VF(s)
  14  */
  15 static inline bool num_vfs_valid(int num_vfs)
  16 {
  17         bool valid = false;
  18 
  19         switch (num_vfs) {
  20         case 16:
  21         case 32:
  22         case 64:
  23         case 128:
  24                 valid = true;
  25                 break;
  26         }
  27 
  28         return valid;
  29 }
  30 
  31 static inline enum vf_mode num_vfs_to_mode(int num_vfs)
  32 {
  33         enum vf_mode mode = 0;
  34 
  35         switch (num_vfs) {
  36         case 0:
  37                 mode = __NDEV_MODE_PF;
  38                 break;
  39         case 16:
  40                 mode = __NDEV_MODE_VF16;
  41                 break;
  42         case 32:
  43                 mode = __NDEV_MODE_VF32;
  44                 break;
  45         case 64:
  46                 mode = __NDEV_MODE_VF64;
  47                 break;
  48         case 128:
  49                 mode = __NDEV_MODE_VF128;
  50                 break;
  51         }
  52 
  53         return mode;
  54 }
  55 
  56 static inline int vf_mode_to_nr_queues(enum vf_mode mode)
  57 {
  58         int nr_queues = 0;
  59 
  60         switch (mode) {
  61         case __NDEV_MODE_PF:
  62                 nr_queues = MAX_PF_QUEUES;
  63                 break;
  64         case __NDEV_MODE_VF16:
  65                 nr_queues = 8;
  66                 break;
  67         case __NDEV_MODE_VF32:
  68                 nr_queues = 4;
  69                 break;
  70         case __NDEV_MODE_VF64:
  71                 nr_queues = 2;
  72                 break;
  73         case __NDEV_MODE_VF128:
  74                 nr_queues = 1;
  75                 break;
  76         }
  77 
  78         return nr_queues;
  79 }
  80 
  81 static void nitrox_pf_cleanup(struct nitrox_device *ndev)
  82 {
  83          /* PF has no queues in SR-IOV mode */
  84         atomic_set(&ndev->state, __NDEV_NOT_READY);
  85         /* unregister crypto algorithms */
  86         nitrox_crypto_unregister();
  87 
  88         /* cleanup PF resources */
  89         nitrox_unregister_interrupts(ndev);
  90         nitrox_common_sw_cleanup(ndev);
  91 }
  92 
  93 /**
  94  * nitrox_pf_reinit - re-initialize PF resources once SR-IOV is disabled
  95  * @ndev: NITROX device
  96  */
  97 static int nitrox_pf_reinit(struct nitrox_device *ndev)
  98 {
  99         int err;
 100 
 101         /* allocate resources for PF */
 102         err = nitrox_common_sw_init(ndev);
 103         if (err)
 104                 return err;
 105 
 106         err = nitrox_register_interrupts(ndev);
 107         if (err) {
 108                 nitrox_common_sw_cleanup(ndev);
 109                 return err;
 110         }
 111 
 112         /* configure the AQM queues */
 113         nitrox_config_aqm_rings(ndev);
 114 
 115         /* configure the packet queues */
 116         nitrox_config_pkt_input_rings(ndev);
 117         nitrox_config_pkt_solicit_ports(ndev);
 118 
 119         /* set device to ready state */
 120         atomic_set(&ndev->state, __NDEV_READY);
 121 
 122         /* register crypto algorithms */
 123         return nitrox_crypto_register();
 124 }
 125 
 126 static void nitrox_sriov_cleanup(struct nitrox_device *ndev)
 127 {
 128         /* unregister interrupts for PF in SR-IOV */
 129         nitrox_sriov_unregister_interrupts(ndev);
 130         nitrox_mbox_cleanup(ndev);
 131 }
 132 
 133 static int nitrox_sriov_init(struct nitrox_device *ndev)
 134 {
 135         int ret;
 136 
 137         /* register interrupts for PF in SR-IOV */
 138         ret = nitrox_sriov_register_interupts(ndev);
 139         if (ret)
 140                 return ret;
 141 
 142         ret = nitrox_mbox_init(ndev);
 143         if (ret)
 144                 goto sriov_init_fail;
 145 
 146         return 0;
 147 
 148 sriov_init_fail:
 149         nitrox_sriov_cleanup(ndev);
 150         return ret;
 151 }
 152 
 153 static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs)
 154 {
 155         struct nitrox_device *ndev = pci_get_drvdata(pdev);
 156         int err;
 157 
 158         if (!num_vfs_valid(num_vfs)) {
 159                 dev_err(DEV(ndev), "Invalid num_vfs %d\n", num_vfs);
 160                 return -EINVAL;
 161         }
 162 
 163         if (pci_num_vf(pdev) == num_vfs)
 164                 return num_vfs;
 165 
 166         err = pci_enable_sriov(pdev, num_vfs);
 167         if (err) {
 168                 dev_err(DEV(ndev), "failed to enable PCI sriov %d\n", err);
 169                 return err;
 170         }
 171         dev_info(DEV(ndev), "Enabled VF(s) %d\n", num_vfs);
 172 
 173         ndev->mode = num_vfs_to_mode(num_vfs);
 174         ndev->iov.num_vfs = num_vfs;
 175         ndev->iov.max_vf_queues = vf_mode_to_nr_queues(ndev->mode);
 176         /* set bit in flags */
 177         set_bit(__NDEV_SRIOV_BIT, &ndev->flags);
 178 
 179         /* cleanup PF resources */
 180         nitrox_pf_cleanup(ndev);
 181 
 182         /* PF SR-IOV mode initialization */
 183         err = nitrox_sriov_init(ndev);
 184         if (err)
 185                 goto iov_fail;
 186 
 187         config_nps_core_vfcfg_mode(ndev, ndev->mode);
 188         return num_vfs;
 189 
 190 iov_fail:
 191         pci_disable_sriov(pdev);
 192         /* clear bit in flags */
 193         clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
 194         ndev->iov.num_vfs = 0;
 195         ndev->mode = __NDEV_MODE_PF;
 196         /* reset back to working mode in PF */
 197         nitrox_pf_reinit(ndev);
 198         return err;
 199 }
 200 
 201 static int nitrox_sriov_disable(struct pci_dev *pdev)
 202 {
 203         struct nitrox_device *ndev = pci_get_drvdata(pdev);
 204 
 205         if (!test_bit(__NDEV_SRIOV_BIT, &ndev->flags))
 206                 return 0;
 207 
 208         if (pci_vfs_assigned(pdev)) {
 209                 dev_warn(DEV(ndev), "VFs are attached to VM. Can't disable SR-IOV\n");
 210                 return -EPERM;
 211         }
 212         pci_disable_sriov(pdev);
 213         /* clear bit in flags */
 214         clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);
 215 
 216         ndev->iov.num_vfs = 0;
 217         ndev->iov.max_vf_queues = 0;
 218         ndev->mode = __NDEV_MODE_PF;
 219 
 220         /* cleanup PF SR-IOV resources */
 221         nitrox_sriov_cleanup(ndev);
 222 
 223         config_nps_core_vfcfg_mode(ndev, ndev->mode);
 224 
 225         return nitrox_pf_reinit(ndev);
 226 }
 227 
 228 int nitrox_sriov_configure(struct pci_dev *pdev, int num_vfs)
 229 {
 230         if (!num_vfs)
 231                 return nitrox_sriov_disable(pdev);
 232 
 233         return nitrox_sriov_enable(pdev, num_vfs);
 234 }

/* [<][>][^][v][top][bottom][index][help] */