0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "otx_cpt_common.h"
0012 #include "otx_cptpf.h"
0013
0014 #define DRV_NAME "octeontx-cpt"
0015 #define DRV_VERSION "1.0"
0016
0017 static void otx_cpt_disable_mbox_interrupts(struct otx_cpt_device *cpt)
0018 {
0019
0020 writeq(~0ull, cpt->reg_base + OTX_CPT_PF_MBOX_ENA_W1CX(0));
0021 }
0022
0023 static void otx_cpt_enable_mbox_interrupts(struct otx_cpt_device *cpt)
0024 {
0025
0026 writeq(~0ull, cpt->reg_base + OTX_CPT_PF_MBOX_ENA_W1SX(0));
0027 }
0028
0029 static irqreturn_t otx_cpt_mbx0_intr_handler(int __always_unused irq,
0030 void *cpt)
0031 {
0032 otx_cpt_mbox_intr_handler(cpt, 0);
0033
0034 return IRQ_HANDLED;
0035 }
0036
0037 static void otx_cpt_reset(struct otx_cpt_device *cpt)
0038 {
0039 writeq(1, cpt->reg_base + OTX_CPT_PF_RESET);
0040 }
0041
0042 static void otx_cpt_find_max_enabled_cores(struct otx_cpt_device *cpt)
0043 {
0044 union otx_cptx_pf_constants pf_cnsts = {0};
0045
0046 pf_cnsts.u = readq(cpt->reg_base + OTX_CPT_PF_CONSTANTS);
0047 cpt->eng_grps.avail.max_se_cnt = pf_cnsts.s.se;
0048 cpt->eng_grps.avail.max_ae_cnt = pf_cnsts.s.ae;
0049 }
0050
0051 static u32 otx_cpt_check_bist_status(struct otx_cpt_device *cpt)
0052 {
0053 union otx_cptx_pf_bist_status bist_sts = {0};
0054
0055 bist_sts.u = readq(cpt->reg_base + OTX_CPT_PF_BIST_STATUS);
0056 return bist_sts.u;
0057 }
0058
0059 static u64 otx_cpt_check_exe_bist_status(struct otx_cpt_device *cpt)
0060 {
0061 union otx_cptx_pf_exe_bist_status bist_sts = {0};
0062
0063 bist_sts.u = readq(cpt->reg_base + OTX_CPT_PF_EXE_BIST_STATUS);
0064 return bist_sts.u;
0065 }
0066
0067 static int otx_cpt_device_init(struct otx_cpt_device *cpt)
0068 {
0069 struct device *dev = &cpt->pdev->dev;
0070 u16 sdevid;
0071 u64 bist;
0072
0073
0074 otx_cpt_reset(cpt);
0075 mdelay(100);
0076
0077 pci_read_config_word(cpt->pdev, PCI_SUBSYSTEM_ID, &sdevid);
0078
0079
0080 bist = (u64)otx_cpt_check_bist_status(cpt);
0081 if (bist) {
0082 dev_err(dev, "RAM BIST failed with code 0x%llx\n", bist);
0083 return -ENODEV;
0084 }
0085
0086 bist = otx_cpt_check_exe_bist_status(cpt);
0087 if (bist) {
0088 dev_err(dev, "Engine BIST failed with code 0x%llx\n", bist);
0089 return -ENODEV;
0090 }
0091
0092
0093 otx_cpt_find_max_enabled_cores(cpt);
0094
0095 if ((sdevid == OTX_CPT_PCI_PF_SUBSYS_ID) &&
0096 (cpt->eng_grps.avail.max_se_cnt == 0)) {
0097 cpt->pf_type = OTX_CPT_AE;
0098 } else if ((sdevid == OTX_CPT_PCI_PF_SUBSYS_ID) &&
0099 (cpt->eng_grps.avail.max_ae_cnt == 0)) {
0100 cpt->pf_type = OTX_CPT_SE;
0101 }
0102
0103
0104 cpt->max_vfs = pci_sriov_get_totalvfs(cpt->pdev);
0105
0106
0107 otx_cpt_disable_all_cores(cpt);
0108
0109 return 0;
0110 }
0111
0112 static int otx_cpt_register_interrupts(struct otx_cpt_device *cpt)
0113 {
0114 struct device *dev = &cpt->pdev->dev;
0115 u32 mbox_int_idx = OTX_CPT_PF_MBOX_INT;
0116 u32 num_vec = OTX_CPT_PF_MSIX_VECTORS;
0117 int ret;
0118
0119
0120 ret = pci_alloc_irq_vectors(cpt->pdev, num_vec, num_vec, PCI_IRQ_MSIX);
0121 if (ret < 0) {
0122 dev_err(&cpt->pdev->dev,
0123 "Request for #%d msix vectors failed\n",
0124 num_vec);
0125 return ret;
0126 }
0127
0128
0129 ret = request_irq(pci_irq_vector(cpt->pdev,
0130 OTX_CPT_PF_INT_VEC_E_MBOXX(mbox_int_idx, 0)),
0131 otx_cpt_mbx0_intr_handler, 0, "CPT Mbox0", cpt);
0132 if (ret) {
0133 dev_err(dev, "Request irq failed\n");
0134 pci_free_irq_vectors(cpt->pdev);
0135 return ret;
0136 }
0137
0138 otx_cpt_enable_mbox_interrupts(cpt);
0139 return 0;
0140 }
0141
0142 static void otx_cpt_unregister_interrupts(struct otx_cpt_device *cpt)
0143 {
0144 u32 mbox_int_idx = OTX_CPT_PF_MBOX_INT;
0145
0146 otx_cpt_disable_mbox_interrupts(cpt);
0147 free_irq(pci_irq_vector(cpt->pdev,
0148 OTX_CPT_PF_INT_VEC_E_MBOXX(mbox_int_idx, 0)),
0149 cpt);
0150 pci_free_irq_vectors(cpt->pdev);
0151 }
0152
0153
0154 static int otx_cpt_sriov_configure(struct pci_dev *pdev, int numvfs)
0155 {
0156 struct otx_cpt_device *cpt = pci_get_drvdata(pdev);
0157 int ret = 0;
0158
0159 if (numvfs > cpt->max_vfs)
0160 numvfs = cpt->max_vfs;
0161
0162 if (numvfs > 0) {
0163 ret = otx_cpt_try_create_default_eng_grps(cpt->pdev,
0164 &cpt->eng_grps,
0165 cpt->pf_type);
0166 if (ret)
0167 return ret;
0168
0169 cpt->vfs_enabled = numvfs;
0170 ret = pci_enable_sriov(pdev, numvfs);
0171 if (ret) {
0172 cpt->vfs_enabled = 0;
0173 return ret;
0174 }
0175 otx_cpt_set_eng_grps_is_rdonly(&cpt->eng_grps, true);
0176 try_module_get(THIS_MODULE);
0177 ret = numvfs;
0178 } else {
0179 pci_disable_sriov(pdev);
0180 otx_cpt_set_eng_grps_is_rdonly(&cpt->eng_grps, false);
0181 module_put(THIS_MODULE);
0182 cpt->vfs_enabled = 0;
0183 }
0184 dev_notice(&cpt->pdev->dev, "VFs enabled: %d\n", ret);
0185
0186 return ret;
0187 }
0188
0189 static int otx_cpt_probe(struct pci_dev *pdev,
0190 const struct pci_device_id __always_unused *ent)
0191 {
0192 struct device *dev = &pdev->dev;
0193 struct otx_cpt_device *cpt;
0194 int err;
0195
0196 cpt = devm_kzalloc(dev, sizeof(*cpt), GFP_KERNEL);
0197 if (!cpt)
0198 return -ENOMEM;
0199
0200 pci_set_drvdata(pdev, cpt);
0201 cpt->pdev = pdev;
0202
0203 err = pci_enable_device(pdev);
0204 if (err) {
0205 dev_err(dev, "Failed to enable PCI device\n");
0206 goto err_clear_drvdata;
0207 }
0208
0209 err = pci_request_regions(pdev, DRV_NAME);
0210 if (err) {
0211 dev_err(dev, "PCI request regions failed 0x%x\n", err);
0212 goto err_disable_device;
0213 }
0214
0215 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
0216 if (err) {
0217 dev_err(dev, "Unable to get usable 48-bit DMA configuration\n");
0218 goto err_release_regions;
0219 }
0220
0221
0222 cpt->reg_base = pci_iomap(pdev, OTX_CPT_PF_PCI_CFG_BAR, 0);
0223 if (!cpt->reg_base) {
0224 dev_err(dev, "Cannot map config register space, aborting\n");
0225 err = -ENOMEM;
0226 goto err_release_regions;
0227 }
0228
0229
0230 err = otx_cpt_device_init(cpt);
0231 if (err)
0232 goto err_unmap_region;
0233
0234
0235 err = otx_cpt_register_interrupts(cpt);
0236 if (err)
0237 goto err_unmap_region;
0238
0239
0240 err = otx_cpt_init_eng_grps(pdev, &cpt->eng_grps, cpt->pf_type);
0241 if (err)
0242 goto err_unregister_interrupts;
0243
0244 return 0;
0245
0246 err_unregister_interrupts:
0247 otx_cpt_unregister_interrupts(cpt);
0248 err_unmap_region:
0249 pci_iounmap(pdev, cpt->reg_base);
0250 err_release_regions:
0251 pci_release_regions(pdev);
0252 err_disable_device:
0253 pci_disable_device(pdev);
0254 err_clear_drvdata:
0255 pci_set_drvdata(pdev, NULL);
0256
0257 return err;
0258 }
0259
0260 static void otx_cpt_remove(struct pci_dev *pdev)
0261 {
0262 struct otx_cpt_device *cpt = pci_get_drvdata(pdev);
0263
0264 if (!cpt)
0265 return;
0266
0267
0268 pci_disable_sriov(pdev);
0269
0270 otx_cpt_cleanup_eng_grps(pdev, &cpt->eng_grps);
0271
0272 otx_cpt_unregister_interrupts(cpt);
0273
0274 otx_cpt_disable_all_cores(cpt);
0275 pci_iounmap(pdev, cpt->reg_base);
0276 pci_release_regions(pdev);
0277 pci_disable_device(pdev);
0278 pci_set_drvdata(pdev, NULL);
0279 }
0280
0281
0282 static const struct pci_device_id otx_cpt_id_table[] = {
0283 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, OTX_CPT_PCI_PF_DEVICE_ID) },
0284 { 0, }
0285 };
0286
0287 static struct pci_driver otx_cpt_pci_driver = {
0288 .name = DRV_NAME,
0289 .id_table = otx_cpt_id_table,
0290 .probe = otx_cpt_probe,
0291 .remove = otx_cpt_remove,
0292 .sriov_configure = otx_cpt_sriov_configure
0293 };
0294
0295 module_pci_driver(otx_cpt_pci_driver);
0296
0297 MODULE_AUTHOR("Marvell International Ltd.");
0298 MODULE_DESCRIPTION("Marvell OcteonTX CPT Physical Function Driver");
0299 MODULE_LICENSE("GPL v2");
0300 MODULE_VERSION(DRV_VERSION);
0301 MODULE_DEVICE_TABLE(pci, otx_cpt_id_table);