0001
0002 #include <linux/aer.h>
0003 #include <linux/delay.h>
0004 #include <linux/firmware.h>
0005 #include <linux/list.h>
0006 #include <linux/module.h>
0007 #include <linux/mutex.h>
0008 #include <linux/pci.h>
0009 #include <linux/pci_ids.h>
0010
0011 #include "nitrox_dev.h"
0012 #include "nitrox_common.h"
0013 #include "nitrox_csr.h"
0014 #include "nitrox_hal.h"
0015 #include "nitrox_isr.h"
0016 #include "nitrox_debugfs.h"
0017
0018 #define CNN55XX_DEV_ID 0x12
0019 #define UCODE_HLEN 48
0020 #define DEFAULT_SE_GROUP 0
0021 #define DEFAULT_AE_GROUP 0
0022
0023 #define DRIVER_VERSION "1.2"
0024 #define CNN55XX_UCD_BLOCK_SIZE 32768
0025 #define CNN55XX_MAX_UCODE_SIZE (CNN55XX_UCD_BLOCK_SIZE * 2)
0026 #define FW_DIR "cavium/"
0027
0028 #define SE_FW FW_DIR "cnn55xx_se.fw"
0029
0030 #define AE_FW FW_DIR "cnn55xx_ae.fw"
0031
0032 static const char nitrox_driver_name[] = "CNN55XX";
0033
0034 static LIST_HEAD(ndevlist);
0035 static DEFINE_MUTEX(devlist_lock);
0036 static unsigned int num_devices;
0037
0038
0039
0040
0041 static const struct pci_device_id nitrox_pci_tbl[] = {
0042 {PCI_VDEVICE(CAVIUM, CNN55XX_DEV_ID), 0},
0043
0044 {0, }
0045 };
0046 MODULE_DEVICE_TABLE(pci, nitrox_pci_tbl);
0047
0048 static unsigned int qlen = DEFAULT_CMD_QLEN;
0049 module_param(qlen, uint, 0644);
0050 MODULE_PARM_DESC(qlen, "Command queue length - default 2048");
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 struct ucode {
0061 u8 id;
0062 char version[VERSION_LEN - 1];
0063 __be32 code_size;
0064 u8 raz[12];
0065 u64 code[];
0066 };
0067
0068
0069
0070
0071 static void write_to_ucd_unit(struct nitrox_device *ndev, u32 ucode_size,
0072 u64 *ucode_data, int block_num)
0073 {
0074 u32 code_size;
0075 u64 offset, data;
0076 int i = 0;
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 offset = UCD_UCODE_LOAD_BLOCK_NUM;
0095 nitrox_write_csr(ndev, offset, block_num);
0096
0097 code_size = roundup(ucode_size, 16);
0098 while (code_size) {
0099 data = ucode_data[i];
0100
0101 offset = UCD_UCODE_LOAD_IDX_DATAX(i);
0102 nitrox_write_csr(ndev, offset, data);
0103 code_size -= 8;
0104 i++;
0105 }
0106
0107 usleep_range(300, 400);
0108 }
0109
0110 static int nitrox_load_fw(struct nitrox_device *ndev)
0111 {
0112 const struct firmware *fw;
0113 const char *fw_name;
0114 struct ucode *ucode;
0115 u64 *ucode_data;
0116 u64 offset;
0117 union ucd_core_eid_ucode_block_num core_2_eid_val;
0118 union aqm_grp_execmsk_lo aqm_grp_execmask_lo;
0119 union aqm_grp_execmsk_hi aqm_grp_execmask_hi;
0120 u32 ucode_size;
0121 int ret, i = 0;
0122
0123 fw_name = SE_FW;
0124 dev_info(DEV(ndev), "Loading firmware \"%s\"\n", fw_name);
0125
0126 ret = request_firmware(&fw, fw_name, DEV(ndev));
0127 if (ret < 0) {
0128 dev_err(DEV(ndev), "failed to get firmware %s\n", fw_name);
0129 return ret;
0130 }
0131
0132 ucode = (struct ucode *)fw->data;
0133
0134 ucode_size = be32_to_cpu(ucode->code_size) * 2;
0135 if (!ucode_size || ucode_size > CNN55XX_MAX_UCODE_SIZE) {
0136 dev_err(DEV(ndev), "Invalid ucode size: %u for firmware %s\n",
0137 ucode_size, fw_name);
0138 release_firmware(fw);
0139 return -EINVAL;
0140 }
0141 ucode_data = ucode->code;
0142
0143
0144 memcpy(&ndev->hw.fw_name[0][0], ucode->version, (VERSION_LEN - 2));
0145 ndev->hw.fw_name[0][VERSION_LEN - 1] = '\0';
0146
0147
0148 write_to_ucd_unit(ndev, ucode_size, ucode_data, 0);
0149
0150 release_firmware(fw);
0151
0152
0153 offset = POM_GRP_EXECMASKX(DEFAULT_SE_GROUP);
0154 nitrox_write_csr(ndev, offset, (~0ULL));
0155
0156
0157
0158
0159
0160
0161 core_2_eid_val.value = 0ULL;
0162 core_2_eid_val.ucode_blk = 0;
0163 if (ucode_size <= CNN55XX_UCD_BLOCK_SIZE)
0164 core_2_eid_val.ucode_len = 1;
0165 else
0166 core_2_eid_val.ucode_len = 0;
0167
0168 for (i = 0; i < ndev->hw.se_cores; i++) {
0169 offset = UCD_SE_EID_UCODE_BLOCK_NUMX(i);
0170 nitrox_write_csr(ndev, offset, core_2_eid_val.value);
0171 }
0172
0173
0174 fw_name = AE_FW;
0175 dev_info(DEV(ndev), "Loading firmware \"%s\"\n", fw_name);
0176
0177 ret = request_firmware(&fw, fw_name, DEV(ndev));
0178 if (ret < 0) {
0179 dev_err(DEV(ndev), "failed to get firmware %s\n", fw_name);
0180 return ret;
0181 }
0182
0183 ucode = (struct ucode *)fw->data;
0184
0185 ucode_size = be32_to_cpu(ucode->code_size) * 2;
0186 if (!ucode_size || ucode_size > CNN55XX_MAX_UCODE_SIZE) {
0187 dev_err(DEV(ndev), "Invalid ucode size: %u for firmware %s\n",
0188 ucode_size, fw_name);
0189 release_firmware(fw);
0190 return -EINVAL;
0191 }
0192 ucode_data = ucode->code;
0193
0194
0195 memcpy(&ndev->hw.fw_name[1][0], ucode->version, (VERSION_LEN - 2));
0196 ndev->hw.fw_name[1][VERSION_LEN - 1] = '\0';
0197
0198
0199 write_to_ucd_unit(ndev, ucode_size, ucode_data, 2);
0200
0201 release_firmware(fw);
0202
0203
0204 offset = AQM_GRP_EXECMSK_LOX(DEFAULT_AE_GROUP);
0205 aqm_grp_execmask_lo.exec_0_to_39 = 0xFFFFFFFFFFULL;
0206 nitrox_write_csr(ndev, offset, aqm_grp_execmask_lo.value);
0207 offset = AQM_GRP_EXECMSK_HIX(DEFAULT_AE_GROUP);
0208 aqm_grp_execmask_hi.exec_40_to_79 = 0xFFFFFFFFFFULL;
0209 nitrox_write_csr(ndev, offset, aqm_grp_execmask_hi.value);
0210
0211
0212
0213
0214
0215
0216 core_2_eid_val.value = 0ULL;
0217 core_2_eid_val.ucode_blk = 2;
0218 if (ucode_size <= CNN55XX_UCD_BLOCK_SIZE)
0219 core_2_eid_val.ucode_len = 1;
0220 else
0221 core_2_eid_val.ucode_len = 0;
0222
0223 for (i = 0; i < ndev->hw.ae_cores; i++) {
0224 offset = UCD_AE_EID_UCODE_BLOCK_NUMX(i);
0225 nitrox_write_csr(ndev, offset, core_2_eid_val.value);
0226 }
0227
0228 return 0;
0229 }
0230
0231
0232
0233
0234
0235 static int nitrox_add_to_devlist(struct nitrox_device *ndev)
0236 {
0237 struct nitrox_device *dev;
0238 int ret = 0;
0239
0240 INIT_LIST_HEAD(&ndev->list);
0241 refcount_set(&ndev->refcnt, 1);
0242
0243 mutex_lock(&devlist_lock);
0244 list_for_each_entry(dev, &ndevlist, list) {
0245 if (dev == ndev) {
0246 ret = -EEXIST;
0247 goto unlock;
0248 }
0249 }
0250 ndev->idx = num_devices++;
0251 list_add_tail(&ndev->list, &ndevlist);
0252 unlock:
0253 mutex_unlock(&devlist_lock);
0254 return ret;
0255 }
0256
0257
0258
0259
0260
0261
0262 static void nitrox_remove_from_devlist(struct nitrox_device *ndev)
0263 {
0264 mutex_lock(&devlist_lock);
0265 list_del(&ndev->list);
0266 num_devices--;
0267 mutex_unlock(&devlist_lock);
0268 }
0269
0270 struct nitrox_device *nitrox_get_first_device(void)
0271 {
0272 struct nitrox_device *ndev = NULL, *iter;
0273
0274 mutex_lock(&devlist_lock);
0275 list_for_each_entry(iter, &ndevlist, list) {
0276 if (nitrox_ready(iter)) {
0277 ndev = iter;
0278 break;
0279 }
0280 }
0281 mutex_unlock(&devlist_lock);
0282 if (!ndev)
0283 return NULL;
0284
0285 refcount_inc(&ndev->refcnt);
0286
0287 smp_mb__after_atomic();
0288 return ndev;
0289 }
0290
0291 void nitrox_put_device(struct nitrox_device *ndev)
0292 {
0293 if (!ndev)
0294 return;
0295
0296 refcount_dec(&ndev->refcnt);
0297
0298 smp_mb__after_atomic();
0299 }
0300
0301 static int nitrox_device_flr(struct pci_dev *pdev)
0302 {
0303 int pos = 0;
0304
0305 pos = pci_save_state(pdev);
0306 if (pos) {
0307 dev_err(&pdev->dev, "Failed to save pci state\n");
0308 return -ENOMEM;
0309 }
0310
0311 pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
0312
0313 pci_restore_state(pdev);
0314
0315 return 0;
0316 }
0317
0318 static int nitrox_pf_sw_init(struct nitrox_device *ndev)
0319 {
0320 int err;
0321
0322 err = nitrox_common_sw_init(ndev);
0323 if (err)
0324 return err;
0325
0326 err = nitrox_register_interrupts(ndev);
0327 if (err)
0328 nitrox_common_sw_cleanup(ndev);
0329
0330 return err;
0331 }
0332
0333 static void nitrox_pf_sw_cleanup(struct nitrox_device *ndev)
0334 {
0335 nitrox_unregister_interrupts(ndev);
0336 nitrox_common_sw_cleanup(ndev);
0337 }
0338
0339
0340
0341
0342
0343 static int nitrox_bist_check(struct nitrox_device *ndev)
0344 {
0345 u64 value = 0;
0346 int i;
0347
0348 for (i = 0; i < NR_CLUSTERS; i++) {
0349 value += nitrox_read_csr(ndev, EMU_BIST_STATUSX(i));
0350 value += nitrox_read_csr(ndev, EFL_CORE_BIST_REGX(i));
0351 }
0352 value += nitrox_read_csr(ndev, UCD_BIST_STATUS);
0353 value += nitrox_read_csr(ndev, NPS_CORE_BIST_REG);
0354 value += nitrox_read_csr(ndev, NPS_CORE_NPC_BIST_REG);
0355 value += nitrox_read_csr(ndev, NPS_PKT_SLC_BIST_REG);
0356 value += nitrox_read_csr(ndev, NPS_PKT_IN_BIST_REG);
0357 value += nitrox_read_csr(ndev, POM_BIST_REG);
0358 value += nitrox_read_csr(ndev, BMI_BIST_REG);
0359 value += nitrox_read_csr(ndev, EFL_TOP_BIST_STAT);
0360 value += nitrox_read_csr(ndev, BMO_BIST_REG);
0361 value += nitrox_read_csr(ndev, LBC_BIST_STATUS);
0362 value += nitrox_read_csr(ndev, PEM_BIST_STATUSX(0));
0363 if (value)
0364 return -EIO;
0365 return 0;
0366 }
0367
0368 static int nitrox_pf_hw_init(struct nitrox_device *ndev)
0369 {
0370 int err;
0371
0372 err = nitrox_bist_check(ndev);
0373 if (err) {
0374 dev_err(&ndev->pdev->dev, "BIST check failed\n");
0375 return err;
0376 }
0377
0378 nitrox_get_hwinfo(ndev);
0379
0380 nitrox_config_nps_core_unit(ndev);
0381 nitrox_config_aqm_unit(ndev);
0382 nitrox_config_nps_pkt_unit(ndev);
0383 nitrox_config_pom_unit(ndev);
0384 nitrox_config_efl_unit(ndev);
0385
0386 nitrox_config_bmi_unit(ndev);
0387 nitrox_config_bmo_unit(ndev);
0388
0389 nitrox_config_lbc_unit(ndev);
0390 nitrox_config_rand_unit(ndev);
0391
0392
0393 err = nitrox_load_fw(ndev);
0394 if (err)
0395 return err;
0396
0397 nitrox_config_emu_unit(ndev);
0398
0399 return 0;
0400 }
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410 static int nitrox_probe(struct pci_dev *pdev,
0411 const struct pci_device_id *id)
0412 {
0413 struct nitrox_device *ndev;
0414 int err;
0415
0416 dev_info_once(&pdev->dev, "%s driver version %s\n",
0417 nitrox_driver_name, DRIVER_VERSION);
0418
0419 err = pci_enable_device_mem(pdev);
0420 if (err)
0421 return err;
0422
0423
0424 err = nitrox_device_flr(pdev);
0425 if (err) {
0426 dev_err(&pdev->dev, "FLR failed\n");
0427 goto flr_fail;
0428 }
0429
0430 if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
0431 dev_dbg(&pdev->dev, "DMA to 64-BIT address\n");
0432 } else {
0433 err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
0434 if (err) {
0435 dev_err(&pdev->dev, "DMA configuration failed\n");
0436 goto flr_fail;
0437 }
0438 }
0439
0440 err = pci_request_mem_regions(pdev, nitrox_driver_name);
0441 if (err)
0442 goto flr_fail;
0443 pci_set_master(pdev);
0444
0445 ndev = kzalloc(sizeof(*ndev), GFP_KERNEL);
0446 if (!ndev) {
0447 err = -ENOMEM;
0448 goto ndev_fail;
0449 }
0450
0451 pci_set_drvdata(pdev, ndev);
0452 ndev->pdev = pdev;
0453
0454
0455 nitrox_add_to_devlist(ndev);
0456
0457 ndev->hw.vendor_id = pdev->vendor;
0458 ndev->hw.device_id = pdev->device;
0459 ndev->hw.revision_id = pdev->revision;
0460
0461 ndev->timeout = msecs_to_jiffies(CMD_TIMEOUT);
0462 ndev->node = dev_to_node(&pdev->dev);
0463 if (ndev->node == NUMA_NO_NODE)
0464 ndev->node = 0;
0465
0466 ndev->bar_addr = ioremap(pci_resource_start(pdev, 0),
0467 pci_resource_len(pdev, 0));
0468 if (!ndev->bar_addr) {
0469 err = -EIO;
0470 goto ioremap_err;
0471 }
0472
0473 ndev->nr_queues = min_t(u32, MAX_PF_QUEUES, num_online_cpus());
0474 ndev->qlen = qlen;
0475
0476 err = nitrox_pf_sw_init(ndev);
0477 if (err)
0478 goto pf_sw_fail;
0479
0480 err = nitrox_pf_hw_init(ndev);
0481 if (err)
0482 goto pf_hw_fail;
0483
0484 nitrox_debugfs_init(ndev);
0485
0486
0487 atomic64_set(&ndev->stats.posted, 0);
0488 atomic64_set(&ndev->stats.completed, 0);
0489 atomic64_set(&ndev->stats.dropped, 0);
0490
0491 atomic_set(&ndev->state, __NDEV_READY);
0492
0493 smp_mb__after_atomic();
0494
0495 err = nitrox_crypto_register();
0496 if (err)
0497 goto crypto_fail;
0498
0499 return 0;
0500
0501 crypto_fail:
0502 nitrox_debugfs_exit(ndev);
0503 atomic_set(&ndev->state, __NDEV_NOT_READY);
0504
0505 smp_mb__after_atomic();
0506 pf_hw_fail:
0507 nitrox_pf_sw_cleanup(ndev);
0508 pf_sw_fail:
0509 iounmap(ndev->bar_addr);
0510 ioremap_err:
0511 nitrox_remove_from_devlist(ndev);
0512 kfree(ndev);
0513 pci_set_drvdata(pdev, NULL);
0514 ndev_fail:
0515 pci_release_mem_regions(pdev);
0516 flr_fail:
0517 pci_disable_device(pdev);
0518 return err;
0519 }
0520
0521
0522
0523
0524
0525 static void nitrox_remove(struct pci_dev *pdev)
0526 {
0527 struct nitrox_device *ndev = pci_get_drvdata(pdev);
0528
0529 if (!ndev)
0530 return;
0531
0532 if (!refcount_dec_and_test(&ndev->refcnt)) {
0533 dev_err(DEV(ndev), "Device refcnt not zero (%d)\n",
0534 refcount_read(&ndev->refcnt));
0535 return;
0536 }
0537
0538 dev_info(DEV(ndev), "Removing Device %x:%x\n",
0539 ndev->hw.vendor_id, ndev->hw.device_id);
0540
0541 atomic_set(&ndev->state, __NDEV_NOT_READY);
0542
0543 smp_mb__after_atomic();
0544
0545 nitrox_remove_from_devlist(ndev);
0546
0547
0548 nitrox_sriov_configure(pdev, 0);
0549 nitrox_crypto_unregister();
0550 nitrox_debugfs_exit(ndev);
0551 nitrox_pf_sw_cleanup(ndev);
0552
0553 iounmap(ndev->bar_addr);
0554 kfree(ndev);
0555
0556 pci_set_drvdata(pdev, NULL);
0557 pci_release_mem_regions(pdev);
0558 pci_disable_device(pdev);
0559 }
0560
0561 static void nitrox_shutdown(struct pci_dev *pdev)
0562 {
0563 pci_set_drvdata(pdev, NULL);
0564 pci_release_mem_regions(pdev);
0565 pci_disable_device(pdev);
0566 }
0567
0568 static struct pci_driver nitrox_driver = {
0569 .name = nitrox_driver_name,
0570 .id_table = nitrox_pci_tbl,
0571 .probe = nitrox_probe,
0572 .remove = nitrox_remove,
0573 .shutdown = nitrox_shutdown,
0574 .sriov_configure = nitrox_sriov_configure,
0575 };
0576
0577 module_pci_driver(nitrox_driver);
0578
0579 MODULE_AUTHOR("Srikanth Jampala <Jampala.Srikanth@cavium.com>");
0580 MODULE_DESCRIPTION("Cavium CNN55XX PF Driver" DRIVER_VERSION " ");
0581 MODULE_LICENSE("GPL");
0582 MODULE_VERSION(DRIVER_VERSION);
0583 MODULE_FIRMWARE(SE_FW);