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>
9 #include <linux/pci_ids.h>
11 #include "nitrox_dev.h"
12 #include "nitrox_common.h"
13 #include "nitrox_csr.h"
15 #define CNN55XX_DEV_ID 0x12
16 #define MAX_PF_QUEUES 64
20 #define DRIVER_VERSION "1.0"
22 #define SE_FW "cnn55xx_se.fw"
24 static const char nitrox_driver_name
[] = "CNN55XX";
26 static LIST_HEAD(ndevlist
);
27 static DEFINE_MUTEX(devlist_lock
);
28 static unsigned int num_devices
;
31 * nitrox_pci_tbl - PCI Device ID Table
33 static const struct pci_device_id nitrox_pci_tbl
[] = {
34 {PCI_VDEVICE(CAVIUM
, CNN55XX_DEV_ID
), 0},
35 /* required last entry */
38 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");
45 * struct ucode - Firmware Header
47 * @version: firmware version
48 * @code_size: code section size
54 char version
[VERSION_LEN
- 1];
61 * write_to_ucd_unit - Write Firmware to NITROX UCD unit
63 static void write_to_ucd_unit(struct nitrox_device
*ndev
,
66 u32 code_size
= be32_to_cpu(ucode
->code_size
) * 2;
82 * Total of 8 blocks, each size 32KB
85 /* set the block number */
86 offset
= UCD_UCODE_LOAD_BLOCK_NUM
;
87 nitrox_write_csr(ndev
, offset
, 0);
89 code_size
= roundup(code_size
, 8);
91 data
= ucode
->code
[i
];
92 /* write 8 bytes at a time */
93 offset
= UCD_UCODE_LOAD_IDX_DATAX(i
);
94 nitrox_write_csr(ndev
, offset
, data
);
99 /* put all SE cores in group 0 */
100 offset
= POM_GRP_EXECMASKX(SE_GROUP
);
101 nitrox_write_csr(ndev
, offset
, (~0ULL));
103 for (i
= 0; i
< ndev
->hw
.se_cores
; i
++) {
105 * write block number and firware length
106 * bit:<2:0> block number
107 * bit:3 is set SE uses 32KB microcode
108 * bit:3 is clear SE uses 64KB microcode
110 offset
= UCD_SE_EID_UCODE_BLOCK_NUMX(i
);
111 nitrox_write_csr(ndev
, offset
, 0x8);
113 usleep_range(300, 400);
116 static int nitrox_load_fw(struct nitrox_device
*ndev
, const char *fw_name
)
118 const struct firmware
*fw
;
122 dev_info(DEV(ndev
), "Loading firmware \"%s\"\n", fw_name
);
124 ret
= request_firmware(&fw
, fw_name
, DEV(ndev
));
126 dev_err(DEV(ndev
), "failed to get firmware %s\n", fw_name
);
130 ucode
= (struct ucode
*)fw
->data
;
131 /* copy the firmware version */
132 memcpy(ndev
->hw
.fw_name
, ucode
->version
, (VERSION_LEN
- 2));
133 ndev
->hw
.fw_name
[VERSION_LEN
- 1] = '\0';
135 write_to_ucd_unit(ndev
, ucode
);
136 release_firmware(fw
);
138 set_bit(NITROX_UCODE_LOADED
, &ndev
->status
);
139 /* barrier to sync with other cpus */
140 smp_mb__after_atomic();
145 * nitrox_add_to_devlist - add NITROX device to global device list
146 * @ndev: NITROX device
148 static int nitrox_add_to_devlist(struct nitrox_device
*ndev
)
150 struct nitrox_device
*dev
;
153 INIT_LIST_HEAD(&ndev
->list
);
154 refcount_set(&ndev
->refcnt
, 1);
156 mutex_lock(&devlist_lock
);
157 list_for_each_entry(dev
, &ndevlist
, list
) {
163 ndev
->idx
= num_devices
++;
164 list_add_tail(&ndev
->list
, &ndevlist
);
166 mutex_unlock(&devlist_lock
);
171 * nitrox_remove_from_devlist - remove NITROX device from
173 * @ndev: NITROX device
175 static void nitrox_remove_from_devlist(struct nitrox_device
*ndev
)
177 mutex_lock(&devlist_lock
);
178 list_del(&ndev
->list
);
180 mutex_unlock(&devlist_lock
);
183 struct nitrox_device
*nitrox_get_first_device(void)
185 struct nitrox_device
*ndev
= NULL
;
187 mutex_lock(&devlist_lock
);
188 list_for_each_entry(ndev
, &ndevlist
, list
) {
189 if (nitrox_ready(ndev
))
192 mutex_unlock(&devlist_lock
);
196 refcount_inc(&ndev
->refcnt
);
197 /* barrier to sync with other cpus */
198 smp_mb__after_atomic();
202 void nitrox_put_device(struct nitrox_device
*ndev
)
207 refcount_dec(&ndev
->refcnt
);
208 /* barrier to sync with other cpus */
209 smp_mb__after_atomic();
212 static int nitrox_reset_device(struct pci_dev
*pdev
)
216 pos
= pci_save_state(pdev
);
218 dev_err(&pdev
->dev
, "Failed to save pci state\n");
222 pos
= pci_pcie_cap(pdev
);
226 if (!pci_wait_for_pending_transaction(pdev
))
227 dev_err(&pdev
->dev
, "waiting for pending transaction\n");
229 pcie_capability_set_word(pdev
, PCI_EXP_DEVCTL
, PCI_EXP_DEVCTL_BCR_FLR
);
231 pci_restore_state(pdev
);
236 static int nitrox_pf_sw_init(struct nitrox_device
*ndev
)
240 err
= nitrox_common_sw_init(ndev
);
244 err
= nitrox_pf_init_isr(ndev
);
246 nitrox_common_sw_cleanup(ndev
);
251 static void nitrox_pf_sw_cleanup(struct nitrox_device
*ndev
)
253 nitrox_pf_cleanup_isr(ndev
);
254 nitrox_common_sw_cleanup(ndev
);
258 * nitrox_bist_check - Check NITORX BIST registers status
259 * @ndev: NITROX device
261 static int nitrox_bist_check(struct nitrox_device
*ndev
)
266 for (i
= 0; i
< NR_CLUSTERS
; i
++) {
267 value
+= nitrox_read_csr(ndev
, EMU_BIST_STATUSX(i
));
268 value
+= nitrox_read_csr(ndev
, EFL_CORE_BIST_REGX(i
));
270 value
+= nitrox_read_csr(ndev
, UCD_BIST_STATUS
);
271 value
+= nitrox_read_csr(ndev
, NPS_CORE_BIST_REG
);
272 value
+= nitrox_read_csr(ndev
, NPS_CORE_NPC_BIST_REG
);
273 value
+= nitrox_read_csr(ndev
, NPS_PKT_SLC_BIST_REG
);
274 value
+= nitrox_read_csr(ndev
, NPS_PKT_IN_BIST_REG
);
275 value
+= nitrox_read_csr(ndev
, POM_BIST_REG
);
276 value
+= nitrox_read_csr(ndev
, BMI_BIST_REG
);
277 value
+= nitrox_read_csr(ndev
, EFL_TOP_BIST_STAT
);
278 value
+= nitrox_read_csr(ndev
, BMO_BIST_REG
);
279 value
+= nitrox_read_csr(ndev
, LBC_BIST_STATUS
);
280 value
+= nitrox_read_csr(ndev
, PEM_BIST_STATUSX(0));
286 static void nitrox_get_hwinfo(struct nitrox_device
*ndev
)
288 union emu_fuse_map emu_fuse
;
292 for (i
= 0; i
< NR_CLUSTERS
; i
++) {
295 offset
= EMU_FUSE_MAPX(i
);
296 emu_fuse
.value
= nitrox_read_csr(ndev
, offset
);
297 if (emu_fuse
.s
.valid
) {
298 dead_cores
= hweight32(emu_fuse
.s
.ae_fuse
);
299 ndev
->hw
.ae_cores
+= AE_CORES_PER_CLUSTER
- dead_cores
;
300 dead_cores
= hweight16(emu_fuse
.s
.se_fuse
);
301 ndev
->hw
.se_cores
+= SE_CORES_PER_CLUSTER
- dead_cores
;
306 static int nitrox_pf_hw_init(struct nitrox_device
*ndev
)
310 err
= nitrox_bist_check(ndev
);
312 dev_err(&ndev
->pdev
->dev
, "BIST check failed\n");
315 /* get cores information */
316 nitrox_get_hwinfo(ndev
);
318 nitrox_config_nps_unit(ndev
);
319 nitrox_config_pom_unit(ndev
);
320 nitrox_config_efl_unit(ndev
);
321 /* configure IO units */
322 nitrox_config_bmi_unit(ndev
);
323 nitrox_config_bmo_unit(ndev
);
324 /* configure Local Buffer Cache */
325 nitrox_config_lbc_unit(ndev
);
326 nitrox_config_rand_unit(ndev
);
328 /* load firmware on SE cores */
329 err
= nitrox_load_fw(ndev
, SE_FW
);
333 nitrox_config_emu_unit(ndev
);
338 #if IS_ENABLED(CONFIG_DEBUG_FS)
339 static int registers_show(struct seq_file
*s
, void *v
)
341 struct nitrox_device
*ndev
= s
->private;
345 offset
= NPS_STATS_PKT_DMA_RD_CNT
;
346 seq_printf(s
, "NPS_STATS_PKT_DMA_RD_CNT 0x%016llx\n",
347 nitrox_read_csr(ndev
, offset
));
348 offset
= NPS_STATS_PKT_DMA_WR_CNT
;
349 seq_printf(s
, "NPS_STATS_PKT_DMA_WR_CNT 0x%016llx\n",
350 nitrox_read_csr(ndev
, offset
));
353 offset
= BMI_NPS_PKT_CNT
;
354 seq_printf(s
, "BMI_NPS_PKT_CNT 0x%016llx\n",
355 nitrox_read_csr(ndev
, offset
));
356 offset
= BMO_NPS_SLC_PKT_CNT
;
357 seq_printf(s
, "BMO_NPS_PKT_CNT 0x%016llx\n",
358 nitrox_read_csr(ndev
, offset
));
363 static int registers_open(struct inode
*inode
, struct file
*file
)
365 return single_open(file
, registers_show
, inode
->i_private
);
368 static const struct file_operations register_fops
= {
369 .owner
= THIS_MODULE
,
370 .open
= registers_open
,
373 .release
= single_release
,
376 static int firmware_show(struct seq_file
*s
, void *v
)
378 struct nitrox_device
*ndev
= s
->private;
380 seq_printf(s
, "Version: %s\n", ndev
->hw
.fw_name
);
384 static int firmware_open(struct inode
*inode
, struct file
*file
)
386 return single_open(file
, firmware_show
, inode
->i_private
);
389 static const struct file_operations firmware_fops
= {
390 .owner
= THIS_MODULE
,
391 .open
= firmware_open
,
394 .release
= single_release
,
397 static int nitrox_show(struct seq_file
*s
, void *v
)
399 struct nitrox_device
*ndev
= s
->private;
401 seq_printf(s
, "NITROX-5 [idx: %d]\n", ndev
->idx
);
402 seq_printf(s
, " Revision ID: 0x%0x\n", ndev
->hw
.revision_id
);
403 seq_printf(s
, " Cores [AE: %u SE: %u]\n",
404 ndev
->hw
.ae_cores
, ndev
->hw
.se_cores
);
405 seq_printf(s
, " Number of Queues: %u\n", ndev
->nr_queues
);
406 seq_printf(s
, " Queue length: %u\n", ndev
->qlen
);
407 seq_printf(s
, " Node: %u\n", ndev
->node
);
412 static int nitrox_open(struct inode
*inode
, struct file
*file
)
414 return single_open(file
, nitrox_show
, inode
->i_private
);
417 static const struct file_operations nitrox_fops
= {
418 .owner
= THIS_MODULE
,
422 .release
= single_release
,
425 static void nitrox_debugfs_exit(struct nitrox_device
*ndev
)
427 debugfs_remove_recursive(ndev
->debugfs_dir
);
428 ndev
->debugfs_dir
= NULL
;
431 static int nitrox_debugfs_init(struct nitrox_device
*ndev
)
433 struct dentry
*dir
, *f
;
435 dir
= debugfs_create_dir(KBUILD_MODNAME
, NULL
);
439 ndev
->debugfs_dir
= dir
;
440 f
= debugfs_create_file("counters", 0400, dir
, ndev
, ®ister_fops
);
443 f
= debugfs_create_file("firmware", 0400, dir
, ndev
, &firmware_fops
);
446 f
= debugfs_create_file("nitrox", 0400, dir
, ndev
, &nitrox_fops
);
453 nitrox_debugfs_exit(ndev
);
457 static int nitrox_debugfs_init(struct nitrox_device
*ndev
)
462 static void nitrox_debugfs_exit(struct nitrox_device
*ndev
)
468 * nitrox_probe - NITROX Initialization function.
469 * @pdev: PCI device information struct
470 * @id: entry in nitrox_pci_tbl
472 * Return: 0, if the driver is bound to the device, or
473 * a negative error if there is failure.
475 static int nitrox_probe(struct pci_dev
*pdev
,
476 const struct pci_device_id
*id
)
478 struct nitrox_device
*ndev
;
481 dev_info_once(&pdev
->dev
, "%s driver version %s\n",
482 nitrox_driver_name
, DRIVER_VERSION
);
484 err
= pci_enable_device_mem(pdev
);
489 err
= nitrox_reset_device(pdev
);
491 dev_err(&pdev
->dev
, "FLR failed\n");
492 pci_disable_device(pdev
);
496 if (!dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64))) {
497 dev_dbg(&pdev
->dev
, "DMA to 64-BIT address\n");
499 err
= dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(32));
501 dev_err(&pdev
->dev
, "DMA configuration failed\n");
502 pci_disable_device(pdev
);
507 err
= pci_request_mem_regions(pdev
, nitrox_driver_name
);
509 pci_disable_device(pdev
);
512 pci_set_master(pdev
);
514 ndev
= kzalloc(sizeof(*ndev
), GFP_KERNEL
);
518 pci_set_drvdata(pdev
, ndev
);
521 /* add to device list */
522 nitrox_add_to_devlist(ndev
);
524 ndev
->hw
.vendor_id
= pdev
->vendor
;
525 ndev
->hw
.device_id
= pdev
->device
;
526 ndev
->hw
.revision_id
= pdev
->revision
;
527 /* command timeout in jiffies */
528 ndev
->timeout
= msecs_to_jiffies(CMD_TIMEOUT
);
529 ndev
->node
= dev_to_node(&pdev
->dev
);
530 if (ndev
->node
== NUMA_NO_NODE
)
533 ndev
->bar_addr
= ioremap(pci_resource_start(pdev
, 0),
534 pci_resource_len(pdev
, 0));
535 if (!ndev
->bar_addr
) {
539 /* allocate command queus based on cpus, max queues are 64 */
540 ndev
->nr_queues
= min_t(u32
, MAX_PF_QUEUES
, num_online_cpus());
543 err
= nitrox_pf_sw_init(ndev
);
547 err
= nitrox_pf_hw_init(ndev
);
551 err
= nitrox_debugfs_init(ndev
);
555 set_bit(NITROX_READY
, &ndev
->status
);
556 /* barrier to sync with other cpus */
557 smp_mb__after_atomic();
559 err
= nitrox_crypto_register();
566 nitrox_debugfs_exit(ndev
);
567 clear_bit(NITROX_READY
, &ndev
->status
);
568 /* barrier to sync with other cpus */
569 smp_mb__after_atomic();
571 nitrox_pf_sw_cleanup(ndev
);
573 nitrox_remove_from_devlist(ndev
);
575 pci_set_drvdata(pdev
, NULL
);
577 pci_release_mem_regions(pdev
);
578 pci_disable_device(pdev
);
583 * nitrox_remove - Unbind the driver from the device.
584 * @pdev: PCI device information struct
586 static void nitrox_remove(struct pci_dev
*pdev
)
588 struct nitrox_device
*ndev
= pci_get_drvdata(pdev
);
593 if (!refcount_dec_and_test(&ndev
->refcnt
)) {
594 dev_err(DEV(ndev
), "Device refcnt not zero (%d)\n",
595 refcount_read(&ndev
->refcnt
));
599 dev_info(DEV(ndev
), "Removing Device %x:%x\n",
600 ndev
->hw
.vendor_id
, ndev
->hw
.device_id
);
602 clear_bit(NITROX_READY
, &ndev
->status
);
603 /* barrier to sync with other cpus */
604 smp_mb__after_atomic();
606 nitrox_remove_from_devlist(ndev
);
607 nitrox_crypto_unregister();
608 nitrox_debugfs_exit(ndev
);
609 nitrox_pf_sw_cleanup(ndev
);
611 iounmap(ndev
->bar_addr
);
614 pci_set_drvdata(pdev
, NULL
);
615 pci_release_mem_regions(pdev
);
616 pci_disable_device(pdev
);
619 static void nitrox_shutdown(struct pci_dev
*pdev
)
621 pci_set_drvdata(pdev
, NULL
);
622 pci_release_mem_regions(pdev
);
623 pci_disable_device(pdev
);
626 static struct pci_driver nitrox_driver
= {
627 .name
= nitrox_driver_name
,
628 .id_table
= nitrox_pci_tbl
,
629 .probe
= nitrox_probe
,
630 .remove
= nitrox_remove
,
631 .shutdown
= nitrox_shutdown
,
634 module_pci_driver(nitrox_driver
);
636 MODULE_AUTHOR("Srikanth Jampala <Jampala.Srikanth@cavium.com>");
637 MODULE_DESCRIPTION("Cavium CNN55XX PF Driver" DRIVER_VERSION
" ");
638 MODULE_LICENSE("GPL");
639 MODULE_VERSION(DRIVER_VERSION
);
640 MODULE_FIRMWARE(SE_FW
);