nitrox_main.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/delay.h>
  3. #include <linux/firmware.h>
  4. #include <linux/list.h>
  5. #include <linux/module.h>
  6. #include <linux/mutex.h>
  7. #include <linux/pci.h>
  8. #include <linux/pci_ids.h>
  9. #include "nitrox_dev.h"
  10. #include "nitrox_common.h"
  11. #include "nitrox_csr.h"
  12. #include "nitrox_hal.h"
  13. #include "nitrox_isr.h"
  14. #include "nitrox_debugfs.h"
  15. #define CNN55XX_DEV_ID 0x12
  16. #define UCODE_HLEN 48
  17. #define DEFAULT_SE_GROUP 0
  18. #define DEFAULT_AE_GROUP 0
  19. #define DRIVER_VERSION "1.2"
  20. #define CNN55XX_UCD_BLOCK_SIZE 32768
  21. #define CNN55XX_MAX_UCODE_SIZE (CNN55XX_UCD_BLOCK_SIZE * 2)
  22. #define FW_DIR "cavium/"
  23. /* SE microcode */
  24. #define SE_FW FW_DIR "cnn55xx_se.fw"
  25. /* AE microcode */
  26. #define AE_FW FW_DIR "cnn55xx_ae.fw"
  27. static const char nitrox_driver_name[] = "CNN55XX";
  28. static LIST_HEAD(ndevlist);
  29. static DEFINE_MUTEX(devlist_lock);
  30. static unsigned int num_devices;
  31. /*
  32. * nitrox_pci_tbl - PCI Device ID Table
  33. */
  34. static const struct pci_device_id nitrox_pci_tbl[] = {
  35. {PCI_VDEVICE(CAVIUM, CNN55XX_DEV_ID), 0},
  36. /* required last entry */
  37. {0, }
  38. };
  39. MODULE_DEVICE_TABLE(pci, nitrox_pci_tbl);
  40. static unsigned int qlen = DEFAULT_CMD_QLEN;
  41. module_param(qlen, uint, 0644);
  42. MODULE_PARM_DESC(qlen, "Command queue length - default 2048");
  43. /**
  44. * struct ucode - Firmware Header
  45. * @id: microcode ID
  46. * @version: firmware version
  47. * @code_size: code section size
  48. * @raz: alignment
  49. * @code: code section
  50. */
  51. struct ucode {
  52. u8 id;
  53. char version[VERSION_LEN - 1];
  54. __be32 code_size;
  55. u8 raz[12];
  56. u64 code[];
  57. };
  58. /*
  59. * write_to_ucd_unit - Write Firmware to NITROX UCD unit
  60. */
  61. static void write_to_ucd_unit(struct nitrox_device *ndev, u32 ucode_size,
  62. u64 *ucode_data, int block_num)
  63. {
  64. u32 code_size;
  65. u64 offset, data;
  66. int i = 0;
  67. /*
  68. * UCD structure
  69. *
  70. * -------------
  71. * | BLK 7 |
  72. * -------------
  73. * | BLK 6 |
  74. * -------------
  75. * | ... |
  76. * -------------
  77. * | BLK 0 |
  78. * -------------
  79. * Total of 8 blocks, each size 32KB
  80. */
  81. /* set the block number */
  82. offset = UCD_UCODE_LOAD_BLOCK_NUM;
  83. nitrox_write_csr(ndev, offset, block_num);
  84. code_size = roundup(ucode_size, 16);
  85. while (code_size) {
  86. data = ucode_data[i];
  87. /* write 8 bytes at a time */
  88. offset = UCD_UCODE_LOAD_IDX_DATAX(i);
  89. nitrox_write_csr(ndev, offset, data);
  90. code_size -= 8;
  91. i++;
  92. }
  93. usleep_range(300, 400);
  94. }
  95. static int nitrox_load_fw(struct nitrox_device *ndev)
  96. {
  97. const struct firmware *fw;
  98. const char *fw_name;
  99. struct ucode *ucode;
  100. u64 *ucode_data;
  101. u64 offset;
  102. union ucd_core_eid_ucode_block_num core_2_eid_val;
  103. union aqm_grp_execmsk_lo aqm_grp_execmask_lo;
  104. union aqm_grp_execmsk_hi aqm_grp_execmask_hi;
  105. u32 ucode_size;
  106. int ret, i = 0;
  107. fw_name = SE_FW;
  108. dev_info(DEV(ndev), "Loading firmware \"%s\"\n", fw_name);
  109. ret = request_firmware(&fw, fw_name, DEV(ndev));
  110. if (ret < 0) {
  111. dev_err(DEV(ndev), "failed to get firmware %s\n", fw_name);
  112. return ret;
  113. }
  114. ucode = (struct ucode *)fw->data;
  115. ucode_size = be32_to_cpu(ucode->code_size) * 2;
  116. if (!ucode_size || ucode_size > CNN55XX_MAX_UCODE_SIZE) {
  117. dev_err(DEV(ndev), "Invalid ucode size: %u for firmware %s\n",
  118. ucode_size, fw_name);
  119. release_firmware(fw);
  120. return -EINVAL;
  121. }
  122. ucode_data = ucode->code;
  123. /* copy the firmware version */
  124. memcpy(&ndev->hw.fw_name[0][0], ucode->version, (VERSION_LEN - 2));
  125. ndev->hw.fw_name[0][VERSION_LEN - 1] = '\0';
  126. /* Load SE Firmware on UCD Block 0 */
  127. write_to_ucd_unit(ndev, ucode_size, ucode_data, 0);
  128. release_firmware(fw);
  129. /* put all SE cores in DEFAULT_SE_GROUP */
  130. offset = POM_GRP_EXECMASKX(DEFAULT_SE_GROUP);
  131. nitrox_write_csr(ndev, offset, (~0ULL));
  132. /* write block number and firmware length
  133. * bit:<2:0> block number
  134. * bit:3 is set SE uses 32KB microcode
  135. * bit:3 is clear SE uses 64KB microcode
  136. */
  137. core_2_eid_val.value = 0ULL;
  138. core_2_eid_val.ucode_blk = 0;
  139. if (ucode_size <= CNN55XX_UCD_BLOCK_SIZE)
  140. core_2_eid_val.ucode_len = 1;
  141. else
  142. core_2_eid_val.ucode_len = 0;
  143. for (i = 0; i < ndev->hw.se_cores; i++) {
  144. offset = UCD_SE_EID_UCODE_BLOCK_NUMX(i);
  145. nitrox_write_csr(ndev, offset, core_2_eid_val.value);
  146. }
  147. fw_name = AE_FW;
  148. dev_info(DEV(ndev), "Loading firmware \"%s\"\n", fw_name);
  149. ret = request_firmware(&fw, fw_name, DEV(ndev));
  150. if (ret < 0) {
  151. dev_err(DEV(ndev), "failed to get firmware %s\n", fw_name);
  152. return ret;
  153. }
  154. ucode = (struct ucode *)fw->data;
  155. ucode_size = be32_to_cpu(ucode->code_size) * 2;
  156. if (!ucode_size || ucode_size > CNN55XX_MAX_UCODE_SIZE) {
  157. dev_err(DEV(ndev), "Invalid ucode size: %u for firmware %s\n",
  158. ucode_size, fw_name);
  159. release_firmware(fw);
  160. return -EINVAL;
  161. }
  162. ucode_data = ucode->code;
  163. /* copy the firmware version */
  164. memcpy(&ndev->hw.fw_name[1][0], ucode->version, (VERSION_LEN - 2));
  165. ndev->hw.fw_name[1][VERSION_LEN - 1] = '\0';
  166. /* Load AE Firmware on UCD Block 2 */
  167. write_to_ucd_unit(ndev, ucode_size, ucode_data, 2);
  168. release_firmware(fw);
  169. /* put all AE cores in DEFAULT_AE_GROUP */
  170. offset = AQM_GRP_EXECMSK_LOX(DEFAULT_AE_GROUP);
  171. aqm_grp_execmask_lo.exec_0_to_39 = 0xFFFFFFFFFFULL;
  172. nitrox_write_csr(ndev, offset, aqm_grp_execmask_lo.value);
  173. offset = AQM_GRP_EXECMSK_HIX(DEFAULT_AE_GROUP);
  174. aqm_grp_execmask_hi.exec_40_to_79 = 0xFFFFFFFFFFULL;
  175. nitrox_write_csr(ndev, offset, aqm_grp_execmask_hi.value);
  176. /* write block number and firmware length
  177. * bit:<2:0> block number
  178. * bit:3 is set AE uses 32KB microcode
  179. * bit:3 is clear AE uses 64KB microcode
  180. */
  181. core_2_eid_val.value = 0ULL;
  182. core_2_eid_val.ucode_blk = 2;
  183. if (ucode_size <= CNN55XX_UCD_BLOCK_SIZE)
  184. core_2_eid_val.ucode_len = 1;
  185. else
  186. core_2_eid_val.ucode_len = 0;
  187. for (i = 0; i < ndev->hw.ae_cores; i++) {
  188. offset = UCD_AE_EID_UCODE_BLOCK_NUMX(i);
  189. nitrox_write_csr(ndev, offset, core_2_eid_val.value);
  190. }
  191. return 0;
  192. }
  193. /**
  194. * nitrox_add_to_devlist - add NITROX device to global device list
  195. * @ndev: NITROX device
  196. */
  197. static int nitrox_add_to_devlist(struct nitrox_device *ndev)
  198. {
  199. struct nitrox_device *dev;
  200. int ret = 0;
  201. INIT_LIST_HEAD(&ndev->list);
  202. refcount_set(&ndev->refcnt, 1);
  203. mutex_lock(&devlist_lock);
  204. list_for_each_entry(dev, &ndevlist, list) {
  205. if (dev == ndev) {
  206. ret = -EEXIST;
  207. goto unlock;
  208. }
  209. }
  210. ndev->idx = num_devices++;
  211. list_add_tail(&ndev->list, &ndevlist);
  212. unlock:
  213. mutex_unlock(&devlist_lock);
  214. return ret;
  215. }
  216. /**
  217. * nitrox_remove_from_devlist - remove NITROX device from
  218. * global device list
  219. * @ndev: NITROX device
  220. */
  221. static void nitrox_remove_from_devlist(struct nitrox_device *ndev)
  222. {
  223. mutex_lock(&devlist_lock);
  224. list_del(&ndev->list);
  225. num_devices--;
  226. mutex_unlock(&devlist_lock);
  227. }
  228. struct nitrox_device *nitrox_get_first_device(void)
  229. {
  230. struct nitrox_device *ndev = NULL, *iter;
  231. mutex_lock(&devlist_lock);
  232. list_for_each_entry(iter, &ndevlist, list) {
  233. if (nitrox_ready(iter)) {
  234. ndev = iter;
  235. break;
  236. }
  237. }
  238. mutex_unlock(&devlist_lock);
  239. if (!ndev)
  240. return NULL;
  241. refcount_inc(&ndev->refcnt);
  242. /* barrier to sync with other cpus */
  243. smp_mb__after_atomic();
  244. return ndev;
  245. }
  246. void nitrox_put_device(struct nitrox_device *ndev)
  247. {
  248. if (!ndev)
  249. return;
  250. refcount_dec(&ndev->refcnt);
  251. /* barrier to sync with other cpus */
  252. smp_mb__after_atomic();
  253. }
  254. static int nitrox_device_flr(struct pci_dev *pdev)
  255. {
  256. int pos = 0;
  257. pos = pci_save_state(pdev);
  258. if (pos) {
  259. dev_err(&pdev->dev, "Failed to save pci state\n");
  260. return -ENOMEM;
  261. }
  262. pcie_reset_flr(pdev, PCI_RESET_DO_RESET);
  263. pci_restore_state(pdev);
  264. return 0;
  265. }
  266. static int nitrox_pf_sw_init(struct nitrox_device *ndev)
  267. {
  268. int err;
  269. err = nitrox_common_sw_init(ndev);
  270. if (err)
  271. return err;
  272. err = nitrox_register_interrupts(ndev);
  273. if (err)
  274. nitrox_common_sw_cleanup(ndev);
  275. return err;
  276. }
  277. static void nitrox_pf_sw_cleanup(struct nitrox_device *ndev)
  278. {
  279. nitrox_unregister_interrupts(ndev);
  280. nitrox_common_sw_cleanup(ndev);
  281. }
  282. /**
  283. * nitrox_bist_check - Check NITROX BIST registers status
  284. * @ndev: NITROX device
  285. */
  286. static int nitrox_bist_check(struct nitrox_device *ndev)
  287. {
  288. u64 value = 0;
  289. int i;
  290. for (i = 0; i < NR_CLUSTERS; i++) {
  291. value += nitrox_read_csr(ndev, EMU_BIST_STATUSX(i));
  292. value += nitrox_read_csr(ndev, EFL_CORE_BIST_REGX(i));
  293. }
  294. value += nitrox_read_csr(ndev, UCD_BIST_STATUS);
  295. value += nitrox_read_csr(ndev, NPS_CORE_BIST_REG);
  296. value += nitrox_read_csr(ndev, NPS_CORE_NPC_BIST_REG);
  297. value += nitrox_read_csr(ndev, NPS_PKT_SLC_BIST_REG);
  298. value += nitrox_read_csr(ndev, NPS_PKT_IN_BIST_REG);
  299. value += nitrox_read_csr(ndev, POM_BIST_REG);
  300. value += nitrox_read_csr(ndev, BMI_BIST_REG);
  301. value += nitrox_read_csr(ndev, EFL_TOP_BIST_STAT);
  302. value += nitrox_read_csr(ndev, BMO_BIST_REG);
  303. value += nitrox_read_csr(ndev, LBC_BIST_STATUS);
  304. value += nitrox_read_csr(ndev, PEM_BIST_STATUSX(0));
  305. if (value)
  306. return -EIO;
  307. return 0;
  308. }
  309. static int nitrox_pf_hw_init(struct nitrox_device *ndev)
  310. {
  311. int err;
  312. err = nitrox_bist_check(ndev);
  313. if (err) {
  314. dev_err(&ndev->pdev->dev, "BIST check failed\n");
  315. return err;
  316. }
  317. /* get cores information */
  318. nitrox_get_hwinfo(ndev);
  319. nitrox_config_nps_core_unit(ndev);
  320. nitrox_config_aqm_unit(ndev);
  321. nitrox_config_nps_pkt_unit(ndev);
  322. nitrox_config_pom_unit(ndev);
  323. nitrox_config_efl_unit(ndev);
  324. /* configure IO units */
  325. nitrox_config_bmi_unit(ndev);
  326. nitrox_config_bmo_unit(ndev);
  327. /* configure Local Buffer Cache */
  328. nitrox_config_lbc_unit(ndev);
  329. nitrox_config_rand_unit(ndev);
  330. /* load firmware on cores */
  331. err = nitrox_load_fw(ndev);
  332. if (err)
  333. return err;
  334. nitrox_config_emu_unit(ndev);
  335. return 0;
  336. }
  337. /**
  338. * nitrox_probe - NITROX Initialization function.
  339. * @pdev: PCI device information struct
  340. * @id: entry in nitrox_pci_tbl
  341. *
  342. * Return: 0, if the driver is bound to the device, or
  343. * a negative error if there is failure.
  344. */
  345. static int nitrox_probe(struct pci_dev *pdev,
  346. const struct pci_device_id *id)
  347. {
  348. struct nitrox_device *ndev;
  349. int err;
  350. dev_info_once(&pdev->dev, "%s driver version %s\n",
  351. nitrox_driver_name, DRIVER_VERSION);
  352. err = pci_enable_device_mem(pdev);
  353. if (err)
  354. return err;
  355. /* do FLR */
  356. err = nitrox_device_flr(pdev);
  357. if (err) {
  358. dev_err(&pdev->dev, "FLR failed\n");
  359. goto flr_fail;
  360. }
  361. if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
  362. dev_dbg(&pdev->dev, "DMA to 64-BIT address\n");
  363. } else {
  364. err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
  365. if (err) {
  366. dev_err(&pdev->dev, "DMA configuration failed\n");
  367. goto flr_fail;
  368. }
  369. }
  370. err = pci_request_mem_regions(pdev, nitrox_driver_name);
  371. if (err)
  372. goto flr_fail;
  373. pci_set_master(pdev);
  374. ndev = kzalloc_obj(*ndev);
  375. if (!ndev) {
  376. err = -ENOMEM;
  377. goto ndev_fail;
  378. }
  379. pci_set_drvdata(pdev, ndev);
  380. ndev->pdev = pdev;
  381. /* add to device list */
  382. nitrox_add_to_devlist(ndev);
  383. ndev->hw.vendor_id = pdev->vendor;
  384. ndev->hw.device_id = pdev->device;
  385. ndev->hw.revision_id = pdev->revision;
  386. /* command timeout in jiffies */
  387. ndev->timeout = msecs_to_jiffies(CMD_TIMEOUT);
  388. ndev->node = dev_to_node(&pdev->dev);
  389. if (ndev->node == NUMA_NO_NODE)
  390. ndev->node = 0;
  391. ndev->bar_addr = ioremap(pci_resource_start(pdev, 0),
  392. pci_resource_len(pdev, 0));
  393. if (!ndev->bar_addr) {
  394. err = -EIO;
  395. goto ioremap_err;
  396. }
  397. /* allocate command queus based on cpus, max queues are 64 */
  398. ndev->nr_queues = min_t(u32, MAX_PF_QUEUES, num_online_cpus());
  399. ndev->qlen = qlen;
  400. err = nitrox_pf_sw_init(ndev);
  401. if (err)
  402. goto pf_sw_fail;
  403. err = nitrox_pf_hw_init(ndev);
  404. if (err)
  405. goto pf_hw_fail;
  406. nitrox_debugfs_init(ndev);
  407. /* clear the statistics */
  408. atomic64_set(&ndev->stats.posted, 0);
  409. atomic64_set(&ndev->stats.completed, 0);
  410. atomic64_set(&ndev->stats.dropped, 0);
  411. atomic_set(&ndev->state, __NDEV_READY);
  412. /* barrier to sync with other cpus */
  413. smp_mb__after_atomic();
  414. err = nitrox_crypto_register();
  415. if (err)
  416. goto crypto_fail;
  417. return 0;
  418. crypto_fail:
  419. nitrox_debugfs_exit(ndev);
  420. atomic_set(&ndev->state, __NDEV_NOT_READY);
  421. /* barrier to sync with other cpus */
  422. smp_mb__after_atomic();
  423. pf_hw_fail:
  424. nitrox_pf_sw_cleanup(ndev);
  425. pf_sw_fail:
  426. iounmap(ndev->bar_addr);
  427. ioremap_err:
  428. nitrox_remove_from_devlist(ndev);
  429. kfree(ndev);
  430. pci_set_drvdata(pdev, NULL);
  431. ndev_fail:
  432. pci_release_mem_regions(pdev);
  433. flr_fail:
  434. pci_disable_device(pdev);
  435. return err;
  436. }
  437. /**
  438. * nitrox_remove - Unbind the driver from the device.
  439. * @pdev: PCI device information struct
  440. */
  441. static void nitrox_remove(struct pci_dev *pdev)
  442. {
  443. struct nitrox_device *ndev = pci_get_drvdata(pdev);
  444. if (!ndev)
  445. return;
  446. if (!refcount_dec_and_test(&ndev->refcnt)) {
  447. dev_err(DEV(ndev), "Device refcnt not zero (%d)\n",
  448. refcount_read(&ndev->refcnt));
  449. return;
  450. }
  451. dev_info(DEV(ndev), "Removing Device %x:%x\n",
  452. ndev->hw.vendor_id, ndev->hw.device_id);
  453. atomic_set(&ndev->state, __NDEV_NOT_READY);
  454. /* barrier to sync with other cpus */
  455. smp_mb__after_atomic();
  456. nitrox_remove_from_devlist(ndev);
  457. /* disable SR-IOV */
  458. nitrox_sriov_configure(pdev, 0);
  459. nitrox_crypto_unregister();
  460. nitrox_debugfs_exit(ndev);
  461. nitrox_pf_sw_cleanup(ndev);
  462. iounmap(ndev->bar_addr);
  463. kfree(ndev);
  464. pci_set_drvdata(pdev, NULL);
  465. pci_release_mem_regions(pdev);
  466. pci_disable_device(pdev);
  467. }
  468. static void nitrox_shutdown(struct pci_dev *pdev)
  469. {
  470. pci_set_drvdata(pdev, NULL);
  471. pci_release_mem_regions(pdev);
  472. pci_disable_device(pdev);
  473. }
  474. static struct pci_driver nitrox_driver = {
  475. .name = nitrox_driver_name,
  476. .id_table = nitrox_pci_tbl,
  477. .probe = nitrox_probe,
  478. .remove = nitrox_remove,
  479. .shutdown = nitrox_shutdown,
  480. .sriov_configure = nitrox_sriov_configure,
  481. };
  482. module_pci_driver(nitrox_driver);
  483. MODULE_AUTHOR("Srikanth Jampala <Jampala.Srikanth@cavium.com>");
  484. MODULE_DESCRIPTION("Cavium CNN55XX PF Driver" DRIVER_VERSION " ");
  485. MODULE_LICENSE("GPL");
  486. MODULE_VERSION(DRIVER_VERSION);
  487. MODULE_FIRMWARE(SE_FW);