nitrox_main.c 11 KB

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