Path: blob/master/drivers/crypto/cavium/nitrox/nitrox_sriov.c
26285 views
// SPDX-License-Identifier: GPL-2.01#include <linux/pci.h>2#include <linux/delay.h>34#include "nitrox_dev.h"5#include "nitrox_hal.h"6#include "nitrox_common.h"7#include "nitrox_isr.h"8#include "nitrox_mbx.h"910/**11* num_vfs_valid - validate VF count12* @num_vfs: number of VF(s)13*/14static inline bool num_vfs_valid(int num_vfs)15{16bool valid = false;1718switch (num_vfs) {19case 16:20case 32:21case 64:22case 128:23valid = true;24break;25}2627return valid;28}2930static inline enum vf_mode num_vfs_to_mode(int num_vfs)31{32enum vf_mode mode = 0;3334switch (num_vfs) {35case 0:36mode = __NDEV_MODE_PF;37break;38case 16:39mode = __NDEV_MODE_VF16;40break;41case 32:42mode = __NDEV_MODE_VF32;43break;44case 64:45mode = __NDEV_MODE_VF64;46break;47case 128:48mode = __NDEV_MODE_VF128;49break;50}5152return mode;53}5455static inline int vf_mode_to_nr_queues(enum vf_mode mode)56{57int nr_queues = 0;5859switch (mode) {60case __NDEV_MODE_PF:61nr_queues = MAX_PF_QUEUES;62break;63case __NDEV_MODE_VF16:64nr_queues = 8;65break;66case __NDEV_MODE_VF32:67nr_queues = 4;68break;69case __NDEV_MODE_VF64:70nr_queues = 2;71break;72case __NDEV_MODE_VF128:73nr_queues = 1;74break;75}7677return nr_queues;78}7980static void nitrox_pf_cleanup(struct nitrox_device *ndev)81{82/* PF has no queues in SR-IOV mode */83atomic_set(&ndev->state, __NDEV_NOT_READY);84/* unregister crypto algorithms */85nitrox_crypto_unregister();8687/* cleanup PF resources */88nitrox_unregister_interrupts(ndev);89nitrox_common_sw_cleanup(ndev);90}9192/**93* nitrox_pf_reinit - re-initialize PF resources once SR-IOV is disabled94* @ndev: NITROX device95*/96static int nitrox_pf_reinit(struct nitrox_device *ndev)97{98int err;99100/* allocate resources for PF */101err = nitrox_common_sw_init(ndev);102if (err)103return err;104105err = nitrox_register_interrupts(ndev);106if (err) {107nitrox_common_sw_cleanup(ndev);108return err;109}110111/* configure the AQM queues */112nitrox_config_aqm_rings(ndev);113114/* configure the packet queues */115nitrox_config_pkt_input_rings(ndev);116nitrox_config_pkt_solicit_ports(ndev);117118/* set device to ready state */119atomic_set(&ndev->state, __NDEV_READY);120121/* register crypto algorithms */122return nitrox_crypto_register();123}124125static void nitrox_sriov_cleanup(struct nitrox_device *ndev)126{127/* unregister interrupts for PF in SR-IOV */128nitrox_sriov_unregister_interrupts(ndev);129nitrox_mbox_cleanup(ndev);130}131132static int nitrox_sriov_init(struct nitrox_device *ndev)133{134int ret;135136/* register interrupts for PF in SR-IOV */137ret = nitrox_sriov_register_interupts(ndev);138if (ret)139return ret;140141ret = nitrox_mbox_init(ndev);142if (ret)143goto sriov_init_fail;144145return 0;146147sriov_init_fail:148nitrox_sriov_cleanup(ndev);149return ret;150}151152static int nitrox_sriov_enable(struct pci_dev *pdev, int num_vfs)153{154struct nitrox_device *ndev = pci_get_drvdata(pdev);155int err;156157if (!num_vfs_valid(num_vfs)) {158dev_err(DEV(ndev), "Invalid num_vfs %d\n", num_vfs);159return -EINVAL;160}161162if (pci_num_vf(pdev) == num_vfs)163return num_vfs;164165err = pci_enable_sriov(pdev, num_vfs);166if (err) {167dev_err(DEV(ndev), "failed to enable PCI sriov %d\n", err);168return err;169}170dev_info(DEV(ndev), "Enabled VF(s) %d\n", num_vfs);171172ndev->mode = num_vfs_to_mode(num_vfs);173ndev->iov.num_vfs = num_vfs;174ndev->iov.max_vf_queues = vf_mode_to_nr_queues(ndev->mode);175/* set bit in flags */176set_bit(__NDEV_SRIOV_BIT, &ndev->flags);177178/* cleanup PF resources */179nitrox_pf_cleanup(ndev);180181/* PF SR-IOV mode initialization */182err = nitrox_sriov_init(ndev);183if (err)184goto iov_fail;185186config_nps_core_vfcfg_mode(ndev, ndev->mode);187return num_vfs;188189iov_fail:190pci_disable_sriov(pdev);191/* clear bit in flags */192clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);193ndev->iov.num_vfs = 0;194ndev->mode = __NDEV_MODE_PF;195/* reset back to working mode in PF */196nitrox_pf_reinit(ndev);197return err;198}199200static int nitrox_sriov_disable(struct pci_dev *pdev)201{202struct nitrox_device *ndev = pci_get_drvdata(pdev);203204if (!test_bit(__NDEV_SRIOV_BIT, &ndev->flags))205return 0;206207if (pci_vfs_assigned(pdev)) {208dev_warn(DEV(ndev), "VFs are attached to VM. Can't disable SR-IOV\n");209return -EPERM;210}211pci_disable_sriov(pdev);212/* clear bit in flags */213clear_bit(__NDEV_SRIOV_BIT, &ndev->flags);214215ndev->iov.num_vfs = 0;216ndev->iov.max_vf_queues = 0;217ndev->mode = __NDEV_MODE_PF;218219/* cleanup PF SR-IOV resources */220nitrox_sriov_cleanup(ndev);221222config_nps_core_vfcfg_mode(ndev, ndev->mode);223224return nitrox_pf_reinit(ndev);225}226227int nitrox_sriov_configure(struct pci_dev *pdev, int num_vfs)228{229if (!num_vfs)230return nitrox_sriov_disable(pdev);231232return nitrox_sriov_enable(pdev, num_vfs);233}234235236