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>
8 #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 #include "nitrox_debugfs.h"
17 #define CNN55XX_DEV_ID 0x12
19 #define DEFAULT_SE_GROUP 0
20 #define DEFAULT_AE_GROUP 0
22 #define DRIVER_VERSION "1.2"
23 #define CNN55XX_UCD_BLOCK_SIZE 32768
24 #define CNN55XX_MAX_UCODE_SIZE (CNN55XX_UCD_BLOCK_SIZE * 2)
25 #define FW_DIR "cavium/"
27 #define SE_FW FW_DIR "cnn55xx_se.fw"
29 #define AE_FW FW_DIR "cnn55xx_ae.fw"
31 static const char nitrox_driver_name
[] = "CNN55XX";
33 static LIST_HEAD(ndevlist
);
34 static DEFINE_MUTEX(devlist_lock
);
35 static unsigned int num_devices
;
38 * nitrox_pci_tbl - PCI Device ID Table
40 static const struct pci_device_id nitrox_pci_tbl
[] = {
41 {PCI_VDEVICE(CAVIUM
, CNN55XX_DEV_ID
), 0},
42 /* required last entry */
45 MODULE_DEVICE_TABLE(pci
, nitrox_pci_tbl
);
47 static unsigned int qlen
= DEFAULT_CMD_QLEN
;
48 module_param(qlen
, uint
, 0644);
49 MODULE_PARM_DESC(qlen
, "Command queue length - default 2048");
52 * struct ucode - Firmware Header
54 * @version: firmware version
55 * @code_size: code section size
61 char version
[VERSION_LEN
- 1];
68 * write_to_ucd_unit - Write Firmware to NITROX UCD unit
70 static void write_to_ucd_unit(struct nitrox_device
*ndev
, u32 ucode_size
,
71 u64
*ucode_data
, int block_num
)
89 * Total of 8 blocks, each size 32KB
92 /* set the block number */
93 offset
= UCD_UCODE_LOAD_BLOCK_NUM
;
94 nitrox_write_csr(ndev
, offset
, block_num
);
96 code_size
= roundup(ucode_size
, 16);
99 /* write 8 bytes at a time */
100 offset
= UCD_UCODE_LOAD_IDX_DATAX(i
);
101 nitrox_write_csr(ndev
, offset
, data
);
106 usleep_range(300, 400);
109 static int nitrox_load_fw(struct nitrox_device
*ndev
)
111 const struct firmware
*fw
;
116 union ucd_core_eid_ucode_block_num core_2_eid_val
;
117 union aqm_grp_execmsk_lo aqm_grp_execmask_lo
;
118 union aqm_grp_execmsk_hi aqm_grp_execmask_hi
;
123 dev_info(DEV(ndev
), "Loading firmware \"%s\"\n", fw_name
);
125 ret
= request_firmware(&fw
, fw_name
, DEV(ndev
));
127 dev_err(DEV(ndev
), "failed to get firmware %s\n", fw_name
);
131 ucode
= (struct ucode
*)fw
->data
;
133 ucode_size
= be32_to_cpu(ucode
->code_size
) * 2;
134 if (!ucode_size
|| ucode_size
> CNN55XX_MAX_UCODE_SIZE
) {
135 dev_err(DEV(ndev
), "Invalid ucode size: %u for firmware %s\n",
136 ucode_size
, fw_name
);
137 release_firmware(fw
);
140 ucode_data
= ucode
->code
;
142 /* copy the firmware version */
143 memcpy(&ndev
->hw
.fw_name
[0][0], ucode
->version
, (VERSION_LEN
- 2));
144 ndev
->hw
.fw_name
[0][VERSION_LEN
- 1] = '\0';
146 /* Load SE Firmware on UCD Block 0 */
147 write_to_ucd_unit(ndev
, ucode_size
, ucode_data
, 0);
149 release_firmware(fw
);
151 /* put all SE cores in DEFAULT_SE_GROUP */
152 offset
= POM_GRP_EXECMASKX(DEFAULT_SE_GROUP
);
153 nitrox_write_csr(ndev
, offset
, (~0ULL));
155 /* write block number and firmware length
156 * bit:<2:0> block number
157 * bit:3 is set SE uses 32KB microcode
158 * bit:3 is clear SE uses 64KB microcode
160 core_2_eid_val
.value
= 0ULL;
161 core_2_eid_val
.ucode_blk
= 0;
162 if (ucode_size
<= CNN55XX_UCD_BLOCK_SIZE
)
163 core_2_eid_val
.ucode_len
= 1;
165 core_2_eid_val
.ucode_len
= 0;
167 for (i
= 0; i
< ndev
->hw
.se_cores
; i
++) {
168 offset
= UCD_SE_EID_UCODE_BLOCK_NUMX(i
);
169 nitrox_write_csr(ndev
, offset
, core_2_eid_val
.value
);
174 dev_info(DEV(ndev
), "Loading firmware \"%s\"\n", fw_name
);
176 ret
= request_firmware(&fw
, fw_name
, DEV(ndev
));
178 dev_err(DEV(ndev
), "failed to get firmware %s\n", fw_name
);
182 ucode
= (struct ucode
*)fw
->data
;
184 ucode_size
= be32_to_cpu(ucode
->code_size
) * 2;
185 if (!ucode_size
|| ucode_size
> CNN55XX_MAX_UCODE_SIZE
) {
186 dev_err(DEV(ndev
), "Invalid ucode size: %u for firmware %s\n",
187 ucode_size
, fw_name
);
188 release_firmware(fw
);
191 ucode_data
= ucode
->code
;
193 /* copy the firmware version */
194 memcpy(&ndev
->hw
.fw_name
[1][0], ucode
->version
, (VERSION_LEN
- 2));
195 ndev
->hw
.fw_name
[1][VERSION_LEN
- 1] = '\0';
197 /* Load AE Firmware on UCD Block 2 */
198 write_to_ucd_unit(ndev
, ucode_size
, ucode_data
, 2);
200 release_firmware(fw
);
202 /* put all AE cores in DEFAULT_AE_GROUP */
203 offset
= AQM_GRP_EXECMSK_LOX(DEFAULT_AE_GROUP
);
204 aqm_grp_execmask_lo
.exec_0_to_39
= 0xFFFFFFFFFFULL
;
205 nitrox_write_csr(ndev
, offset
, aqm_grp_execmask_lo
.value
);
206 offset
= AQM_GRP_EXECMSK_HIX(DEFAULT_AE_GROUP
);
207 aqm_grp_execmask_hi
.exec_40_to_79
= 0xFFFFFFFFFFULL
;
208 nitrox_write_csr(ndev
, offset
, aqm_grp_execmask_hi
.value
);
210 /* write block number and firmware length
211 * bit:<2:0> block number
212 * bit:3 is set AE uses 32KB microcode
213 * bit:3 is clear AE uses 64KB microcode
215 core_2_eid_val
.value
= 0ULL;
216 core_2_eid_val
.ucode_blk
= 2;
217 if (ucode_size
<= CNN55XX_UCD_BLOCK_SIZE
)
218 core_2_eid_val
.ucode_len
= 1;
220 core_2_eid_val
.ucode_len
= 0;
222 for (i
= 0; i
< ndev
->hw
.ae_cores
; i
++) {
223 offset
= UCD_AE_EID_UCODE_BLOCK_NUMX(i
);
224 nitrox_write_csr(ndev
, offset
, core_2_eid_val
.value
);
231 * nitrox_add_to_devlist - add NITROX device to global device list
232 * @ndev: NITROX device
234 static int nitrox_add_to_devlist(struct nitrox_device
*ndev
)
236 struct nitrox_device
*dev
;
239 INIT_LIST_HEAD(&ndev
->list
);
240 refcount_set(&ndev
->refcnt
, 1);
242 mutex_lock(&devlist_lock
);
243 list_for_each_entry(dev
, &ndevlist
, list
) {
249 ndev
->idx
= num_devices
++;
250 list_add_tail(&ndev
->list
, &ndevlist
);
252 mutex_unlock(&devlist_lock
);
257 * nitrox_remove_from_devlist - remove NITROX device from
259 * @ndev: NITROX device
261 static void nitrox_remove_from_devlist(struct nitrox_device
*ndev
)
263 mutex_lock(&devlist_lock
);
264 list_del(&ndev
->list
);
266 mutex_unlock(&devlist_lock
);
269 struct nitrox_device
*nitrox_get_first_device(void)
271 struct nitrox_device
*ndev
= NULL
, *iter
;
273 mutex_lock(&devlist_lock
);
274 list_for_each_entry(iter
, &ndevlist
, list
) {
275 if (nitrox_ready(iter
)) {
280 mutex_unlock(&devlist_lock
);
284 refcount_inc(&ndev
->refcnt
);
285 /* barrier to sync with other cpus */
286 smp_mb__after_atomic();
290 void nitrox_put_device(struct nitrox_device
*ndev
)
295 refcount_dec(&ndev
->refcnt
);
296 /* barrier to sync with other cpus */
297 smp_mb__after_atomic();
300 static int nitrox_device_flr(struct pci_dev
*pdev
)
304 pos
= pci_save_state(pdev
);
306 dev_err(&pdev
->dev
, "Failed to save pci state\n");
310 pcie_reset_flr(pdev
, PCI_RESET_DO_RESET
);
312 pci_restore_state(pdev
);
317 static int nitrox_pf_sw_init(struct nitrox_device
*ndev
)
321 err
= nitrox_common_sw_init(ndev
);
325 err
= nitrox_register_interrupts(ndev
);
327 nitrox_common_sw_cleanup(ndev
);
332 static void nitrox_pf_sw_cleanup(struct nitrox_device
*ndev
)
334 nitrox_unregister_interrupts(ndev
);
335 nitrox_common_sw_cleanup(ndev
);
339 * nitrox_bist_check - Check NITROX BIST registers status
340 * @ndev: NITROX device
342 static int nitrox_bist_check(struct nitrox_device
*ndev
)
347 for (i
= 0; i
< NR_CLUSTERS
; i
++) {
348 value
+= nitrox_read_csr(ndev
, EMU_BIST_STATUSX(i
));
349 value
+= nitrox_read_csr(ndev
, EFL_CORE_BIST_REGX(i
));
351 value
+= nitrox_read_csr(ndev
, UCD_BIST_STATUS
);
352 value
+= nitrox_read_csr(ndev
, NPS_CORE_BIST_REG
);
353 value
+= nitrox_read_csr(ndev
, NPS_CORE_NPC_BIST_REG
);
354 value
+= nitrox_read_csr(ndev
, NPS_PKT_SLC_BIST_REG
);
355 value
+= nitrox_read_csr(ndev
, NPS_PKT_IN_BIST_REG
);
356 value
+= nitrox_read_csr(ndev
, POM_BIST_REG
);
357 value
+= nitrox_read_csr(ndev
, BMI_BIST_REG
);
358 value
+= nitrox_read_csr(ndev
, EFL_TOP_BIST_STAT
);
359 value
+= nitrox_read_csr(ndev
, BMO_BIST_REG
);
360 value
+= nitrox_read_csr(ndev
, LBC_BIST_STATUS
);
361 value
+= nitrox_read_csr(ndev
, PEM_BIST_STATUSX(0));
367 static int nitrox_pf_hw_init(struct nitrox_device
*ndev
)
371 err
= nitrox_bist_check(ndev
);
373 dev_err(&ndev
->pdev
->dev
, "BIST check failed\n");
376 /* get cores information */
377 nitrox_get_hwinfo(ndev
);
379 nitrox_config_nps_core_unit(ndev
);
380 nitrox_config_aqm_unit(ndev
);
381 nitrox_config_nps_pkt_unit(ndev
);
382 nitrox_config_pom_unit(ndev
);
383 nitrox_config_efl_unit(ndev
);
384 /* configure IO units */
385 nitrox_config_bmi_unit(ndev
);
386 nitrox_config_bmo_unit(ndev
);
387 /* configure Local Buffer Cache */
388 nitrox_config_lbc_unit(ndev
);
389 nitrox_config_rand_unit(ndev
);
391 /* load firmware on cores */
392 err
= nitrox_load_fw(ndev
);
396 nitrox_config_emu_unit(ndev
);
402 * nitrox_probe - NITROX Initialization function.
403 * @pdev: PCI device information struct
404 * @id: entry in nitrox_pci_tbl
406 * Return: 0, if the driver is bound to the device, or
407 * a negative error if there is failure.
409 static int nitrox_probe(struct pci_dev
*pdev
,
410 const struct pci_device_id
*id
)
412 struct nitrox_device
*ndev
;
415 dev_info_once(&pdev
->dev
, "%s driver version %s\n",
416 nitrox_driver_name
, DRIVER_VERSION
);
418 err
= pci_enable_device_mem(pdev
);
423 err
= nitrox_device_flr(pdev
);
425 dev_err(&pdev
->dev
, "FLR failed\n");
429 if (!dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64))) {
430 dev_dbg(&pdev
->dev
, "DMA to 64-BIT address\n");
432 err
= dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(32));
434 dev_err(&pdev
->dev
, "DMA configuration failed\n");
439 err
= pci_request_mem_regions(pdev
, nitrox_driver_name
);
442 pci_set_master(pdev
);
444 ndev
= kzalloc(sizeof(*ndev
), GFP_KERNEL
);
450 pci_set_drvdata(pdev
, ndev
);
453 /* add to device list */
454 nitrox_add_to_devlist(ndev
);
456 ndev
->hw
.vendor_id
= pdev
->vendor
;
457 ndev
->hw
.device_id
= pdev
->device
;
458 ndev
->hw
.revision_id
= pdev
->revision
;
459 /* command timeout in jiffies */
460 ndev
->timeout
= msecs_to_jiffies(CMD_TIMEOUT
);
461 ndev
->node
= dev_to_node(&pdev
->dev
);
462 if (ndev
->node
== NUMA_NO_NODE
)
465 ndev
->bar_addr
= ioremap(pci_resource_start(pdev
, 0),
466 pci_resource_len(pdev
, 0));
467 if (!ndev
->bar_addr
) {
471 /* allocate command queus based on cpus, max queues are 64 */
472 ndev
->nr_queues
= min_t(u32
, MAX_PF_QUEUES
, num_online_cpus());
475 err
= nitrox_pf_sw_init(ndev
);
479 err
= nitrox_pf_hw_init(ndev
);
483 nitrox_debugfs_init(ndev
);
485 /* clear the statistics */
486 atomic64_set(&ndev
->stats
.posted
, 0);
487 atomic64_set(&ndev
->stats
.completed
, 0);
488 atomic64_set(&ndev
->stats
.dropped
, 0);
490 atomic_set(&ndev
->state
, __NDEV_READY
);
491 /* barrier to sync with other cpus */
492 smp_mb__after_atomic();
494 err
= nitrox_crypto_register();
501 nitrox_debugfs_exit(ndev
);
502 atomic_set(&ndev
->state
, __NDEV_NOT_READY
);
503 /* barrier to sync with other cpus */
504 smp_mb__after_atomic();
506 nitrox_pf_sw_cleanup(ndev
);
508 iounmap(ndev
->bar_addr
);
510 nitrox_remove_from_devlist(ndev
);
512 pci_set_drvdata(pdev
, NULL
);
514 pci_release_mem_regions(pdev
);
516 pci_disable_device(pdev
);
521 * nitrox_remove - Unbind the driver from the device.
522 * @pdev: PCI device information struct
524 static void nitrox_remove(struct pci_dev
*pdev
)
526 struct nitrox_device
*ndev
= pci_get_drvdata(pdev
);
531 if (!refcount_dec_and_test(&ndev
->refcnt
)) {
532 dev_err(DEV(ndev
), "Device refcnt not zero (%d)\n",
533 refcount_read(&ndev
->refcnt
));
537 dev_info(DEV(ndev
), "Removing Device %x:%x\n",
538 ndev
->hw
.vendor_id
, ndev
->hw
.device_id
);
540 atomic_set(&ndev
->state
, __NDEV_NOT_READY
);
541 /* barrier to sync with other cpus */
542 smp_mb__after_atomic();
544 nitrox_remove_from_devlist(ndev
);
547 nitrox_sriov_configure(pdev
, 0);
548 nitrox_crypto_unregister();
549 nitrox_debugfs_exit(ndev
);
550 nitrox_pf_sw_cleanup(ndev
);
552 iounmap(ndev
->bar_addr
);
555 pci_set_drvdata(pdev
, NULL
);
556 pci_release_mem_regions(pdev
);
557 pci_disable_device(pdev
);
560 static void nitrox_shutdown(struct pci_dev
*pdev
)
562 pci_set_drvdata(pdev
, NULL
);
563 pci_release_mem_regions(pdev
);
564 pci_disable_device(pdev
);
567 static struct pci_driver nitrox_driver
= {
568 .name
= nitrox_driver_name
,
569 .id_table
= nitrox_pci_tbl
,
570 .probe
= nitrox_probe
,
571 .remove
= nitrox_remove
,
572 .shutdown
= nitrox_shutdown
,
573 .sriov_configure
= nitrox_sriov_configure
,
576 module_pci_driver(nitrox_driver
);
578 MODULE_AUTHOR("Srikanth Jampala <Jampala.Srikanth@cavium.com>");
579 MODULE_DESCRIPTION("Cavium CNN55XX PF Driver" DRIVER_VERSION
" ");
580 MODULE_LICENSE("GPL");
581 MODULE_VERSION(DRIVER_VERSION
);
582 MODULE_FIRMWARE(SE_FW
);