Lines Matching refs:fw

75 #define PRESTERA_LDR_REG_BASE(fw)	((fw)->ldr_regs)  argument
76 #define PRESTERA_LDR_REG_ADDR(fw, reg) (PRESTERA_LDR_REG_BASE(fw) + (reg)) argument
157 #define PRESTERA_FW_REG_BASE(fw) ((fw)->dev.ctl_regs) argument
158 #define PRESTERA_FW_REG_ADDR(fw, reg) PRESTERA_FW_REG_BASE((fw)) + (reg) argument
185 static int prestera_fw_load(struct prestera_fw *fw);
187 static void prestera_fw_write(struct prestera_fw *fw, u32 reg, u32 val) in prestera_fw_write() argument
189 writel(val, PRESTERA_FW_REG_ADDR(fw, reg)); in prestera_fw_write()
192 static u32 prestera_fw_read(struct prestera_fw *fw, u32 reg) in prestera_fw_read() argument
194 return readl(PRESTERA_FW_REG_ADDR(fw, reg)); in prestera_fw_read()
197 static u32 prestera_fw_evtq_len(struct prestera_fw *fw, u8 qid) in prestera_fw_evtq_len() argument
199 return fw->evt_queue[qid].len; in prestera_fw_evtq_len()
202 static u32 prestera_fw_evtq_avail(struct prestera_fw *fw, u8 qid) in prestera_fw_evtq_avail() argument
204 u32 wr_idx = prestera_fw_read(fw, PRESTERA_EVTQ_WR_IDX_REG(qid)); in prestera_fw_evtq_avail()
205 u32 rd_idx = prestera_fw_read(fw, PRESTERA_EVTQ_RD_IDX_REG(qid)); in prestera_fw_evtq_avail()
207 return CIRC_CNT(wr_idx, rd_idx, prestera_fw_evtq_len(fw, qid)); in prestera_fw_evtq_avail()
210 static void prestera_fw_evtq_rd_set(struct prestera_fw *fw, in prestera_fw_evtq_rd_set() argument
213 u32 rd_idx = idx & (prestera_fw_evtq_len(fw, qid) - 1); in prestera_fw_evtq_rd_set()
215 prestera_fw_write(fw, PRESTERA_EVTQ_RD_IDX_REG(qid), rd_idx); in prestera_fw_evtq_rd_set()
218 static u8 __iomem *prestera_fw_evtq_buf(struct prestera_fw *fw, u8 qid) in prestera_fw_evtq_buf() argument
220 return fw->evt_queue[qid].addr; in prestera_fw_evtq_buf()
223 static u32 prestera_fw_evtq_read32(struct prestera_fw *fw, u8 qid) in prestera_fw_evtq_read32() argument
225 u32 rd_idx = prestera_fw_read(fw, PRESTERA_EVTQ_RD_IDX_REG(qid)); in prestera_fw_evtq_read32()
228 val = readl(prestera_fw_evtq_buf(fw, qid) + rd_idx); in prestera_fw_evtq_read32()
229 prestera_fw_evtq_rd_set(fw, qid, rd_idx + 4); in prestera_fw_evtq_read32()
233 static ssize_t prestera_fw_evtq_read_buf(struct prestera_fw *fw, in prestera_fw_evtq_read_buf() argument
236 u32 idx = prestera_fw_read(fw, PRESTERA_EVTQ_RD_IDX_REG(qid)); in prestera_fw_evtq_read_buf()
237 u8 __iomem *evtq_addr = prestera_fw_evtq_buf(fw, qid); in prestera_fw_evtq_read_buf()
243 idx = (idx + 4) & (prestera_fw_evtq_len(fw, qid) - 1); in prestera_fw_evtq_read_buf()
246 prestera_fw_evtq_rd_set(fw, qid, idx); in prestera_fw_evtq_read_buf()
251 static u8 prestera_fw_evtq_pick(struct prestera_fw *fw) in prestera_fw_evtq_pick() argument
255 for (qid = 0; qid < fw->evt_qnum; qid++) { in prestera_fw_evtq_pick()
256 if (prestera_fw_evtq_avail(fw, qid) >= 4) in prestera_fw_evtq_pick()
265 struct prestera_fw *fw; in prestera_fw_evt_work_fn() local
269 fw = container_of(work, struct prestera_fw, evt_work); in prestera_fw_evt_work_fn()
270 msg = fw->evt_msg; in prestera_fw_evt_work_fn()
272 while ((qid = prestera_fw_evtq_pick(fw)) < PRESTERA_EVT_QNUM_MAX) { in prestera_fw_evt_work_fn()
276 len = prestera_fw_evtq_read32(fw, qid); in prestera_fw_evt_work_fn()
277 idx = prestera_fw_read(fw, PRESTERA_EVTQ_RD_IDX_REG(qid)); in prestera_fw_evt_work_fn()
279 WARN_ON(prestera_fw_evtq_avail(fw, qid) < len); in prestera_fw_evt_work_fn()
282 prestera_fw_evtq_rd_set(fw, qid, idx + len); in prestera_fw_evt_work_fn()
286 prestera_fw_evtq_read_buf(fw, qid, msg, len); in prestera_fw_evt_work_fn()
288 if (fw->dev.recv_msg) in prestera_fw_evt_work_fn()
289 fw->dev.recv_msg(&fw->dev, msg, len); in prestera_fw_evt_work_fn()
293 static int prestera_fw_wait_reg32(struct prestera_fw *fw, u32 reg, u32 cmp, in prestera_fw_wait_reg32() argument
296 u8 __iomem *addr = PRESTERA_FW_REG_ADDR(fw, reg); in prestera_fw_wait_reg32()
303 static int prestera_fw_cmd_send(struct prestera_fw *fw, in prestera_fw_cmd_send() argument
314 if (ALIGN(in_size, 4) > fw->cmd_mbox_len) in prestera_fw_cmd_send()
318 err = prestera_fw_wait_reg32(fw, PRESTERA_CMD_RCV_CTL_REG, 0, 30); in prestera_fw_cmd_send()
320 dev_err(fw->dev.dev, "finish reply from FW is timed out\n"); in prestera_fw_cmd_send()
324 prestera_fw_write(fw, PRESTERA_CMD_REQ_LEN_REG, in_size); in prestera_fw_cmd_send()
325 memcpy_toio(fw->cmd_mbox, in_msg, in_size); in prestera_fw_cmd_send()
327 prestera_fw_write(fw, PRESTERA_CMD_REQ_CTL_REG, PRESTERA_CMD_F_REQ_SENT); in prestera_fw_cmd_send()
330 err = prestera_fw_wait_reg32(fw, PRESTERA_CMD_RCV_CTL_REG, in prestera_fw_cmd_send()
333 dev_err(fw->dev.dev, "reply from FW is timed out\n"); in prestera_fw_cmd_send()
337 ret_size = prestera_fw_read(fw, PRESTERA_CMD_RCV_LEN_REG); in prestera_fw_cmd_send()
339 dev_err(fw->dev.dev, "ret_size (%u) > out_len(%zu)\n", in prestera_fw_cmd_send()
345 memcpy_fromio(out_msg, fw->cmd_mbox + in_size, ret_size); in prestera_fw_cmd_send()
348 prestera_fw_write(fw, PRESTERA_CMD_REQ_CTL_REG, PRESTERA_CMD_F_REPL_RCVD); in prestera_fw_cmd_send()
356 struct prestera_fw *fw; in prestera_fw_send_req() local
359 fw = container_of(dev, struct prestera_fw, dev); in prestera_fw_send_req()
361 mutex_lock(&fw->cmd_mtx); in prestera_fw_send_req()
362 ret = prestera_fw_cmd_send(fw, in_msg, in_size, out_msg, out_size, waitms); in prestera_fw_send_req()
363 mutex_unlock(&fw->cmd_mtx); in prestera_fw_send_req()
368 static int prestera_fw_init(struct prestera_fw *fw) in prestera_fw_init() argument
374 fw->dev.send_req = prestera_fw_send_req; in prestera_fw_init()
375 fw->ldr_regs = fw->dev.ctl_regs; in prestera_fw_init()
377 err = prestera_fw_load(fw); in prestera_fw_init()
381 err = prestera_fw_wait_reg32(fw, PRESTERA_FW_READY_REG, in prestera_fw_init()
385 dev_err(fw->dev.dev, "FW failed to start\n"); in prestera_fw_init()
389 base = fw->dev.ctl_regs; in prestera_fw_init()
391 fw->cmd_mbox = base + prestera_fw_read(fw, PRESTERA_CMD_BUF_OFFS_REG); in prestera_fw_init()
392 fw->cmd_mbox_len = prestera_fw_read(fw, PRESTERA_CMD_BUF_LEN_REG); in prestera_fw_init()
393 mutex_init(&fw->cmd_mtx); in prestera_fw_init()
395 fw->evt_buf = base + prestera_fw_read(fw, PRESTERA_EVT_BUF_OFFS_REG); in prestera_fw_init()
396 fw->evt_qnum = prestera_fw_read(fw, PRESTERA_EVT_QNUM_REG); in prestera_fw_init()
397 fw->evt_msg = kmalloc(PRESTERA_MSG_MAX_SIZE, GFP_KERNEL); in prestera_fw_init()
398 if (!fw->evt_msg) in prestera_fw_init()
401 for (qid = 0; qid < fw->evt_qnum; qid++) { in prestera_fw_init()
402 u32 offs = prestera_fw_read(fw, PRESTERA_EVTQ_OFFS_REG(qid)); in prestera_fw_init()
403 struct prestera_fw_evtq *evtq = &fw->evt_queue[qid]; in prestera_fw_init()
405 evtq->len = prestera_fw_read(fw, PRESTERA_EVTQ_LEN_REG(qid)); in prestera_fw_init()
406 evtq->addr = fw->evt_buf + offs; in prestera_fw_init()
412 static void prestera_fw_uninit(struct prestera_fw *fw) in prestera_fw_uninit() argument
414 kfree(fw->evt_msg); in prestera_fw_uninit()
419 struct prestera_fw *fw = dev_id; in prestera_pci_irq_handler() local
421 if (prestera_fw_read(fw, PRESTERA_RX_STATUS_REG)) { in prestera_pci_irq_handler()
422 prestera_fw_write(fw, PRESTERA_RX_STATUS_REG, 0); in prestera_pci_irq_handler()
424 if (fw->dev.recv_pkt) in prestera_pci_irq_handler()
425 fw->dev.recv_pkt(&fw->dev); in prestera_pci_irq_handler()
428 queue_work(fw->wq, &fw->evt_work); in prestera_pci_irq_handler()
433 static void prestera_ldr_write(struct prestera_fw *fw, u32 reg, u32 val) in prestera_ldr_write() argument
435 writel(val, PRESTERA_LDR_REG_ADDR(fw, reg)); in prestera_ldr_write()
438 static u32 prestera_ldr_read(struct prestera_fw *fw, u32 reg) in prestera_ldr_read() argument
440 return readl(PRESTERA_LDR_REG_ADDR(fw, reg)); in prestera_ldr_read()
443 static int prestera_ldr_wait_reg32(struct prestera_fw *fw, in prestera_ldr_wait_reg32() argument
446 u8 __iomem *addr = PRESTERA_LDR_REG_ADDR(fw, reg); in prestera_ldr_wait_reg32()
453 static u32 prestera_ldr_wait_buf(struct prestera_fw *fw, size_t len) in prestera_ldr_wait_buf() argument
455 u8 __iomem *addr = PRESTERA_LDR_REG_ADDR(fw, PRESTERA_LDR_BUF_RD_REG); in prestera_ldr_wait_buf()
456 u32 buf_len = fw->ldr_buf_len; in prestera_ldr_wait_buf()
457 u32 wr_idx = fw->ldr_wr_idx; in prestera_ldr_wait_buf()
465 static int prestera_ldr_wait_dl_finish(struct prestera_fw *fw) in prestera_ldr_wait_dl_finish() argument
467 u8 __iomem *addr = PRESTERA_LDR_REG_ADDR(fw, PRESTERA_LDR_STATUS_REG); in prestera_ldr_wait_dl_finish()
475 dev_err(fw->dev.dev, "Timeout to load FW img [state=%d]", in prestera_ldr_wait_dl_finish()
476 prestera_ldr_read(fw, PRESTERA_LDR_STATUS_REG)); in prestera_ldr_wait_dl_finish()
483 static void prestera_ldr_wr_idx_move(struct prestera_fw *fw, unsigned int n) in prestera_ldr_wr_idx_move() argument
485 fw->ldr_wr_idx = (fw->ldr_wr_idx + (n)) & (fw->ldr_buf_len - 1); in prestera_ldr_wr_idx_move()
488 static void prestera_ldr_wr_idx_commit(struct prestera_fw *fw) in prestera_ldr_wr_idx_commit() argument
490 prestera_ldr_write(fw, PRESTERA_LDR_BUF_WR_REG, fw->ldr_wr_idx); in prestera_ldr_wr_idx_commit()
493 static u8 __iomem *prestera_ldr_wr_ptr(struct prestera_fw *fw) in prestera_ldr_wr_ptr() argument
495 return fw->ldr_ring_buf + fw->ldr_wr_idx; in prestera_ldr_wr_ptr()
498 static int prestera_ldr_send(struct prestera_fw *fw, const u8 *buf, size_t len) in prestera_ldr_send() argument
503 err = prestera_ldr_wait_buf(fw, len); in prestera_ldr_send()
505 dev_err(fw->dev.dev, "failed wait for sending firmware\n"); in prestera_ldr_send()
510 writel_relaxed(*(u32 *)(buf + i), prestera_ldr_wr_ptr(fw)); in prestera_ldr_send()
511 prestera_ldr_wr_idx_move(fw, 4); in prestera_ldr_send()
514 prestera_ldr_wr_idx_commit(fw); in prestera_ldr_send()
518 static int prestera_ldr_fw_send(struct prestera_fw *fw, in prestera_ldr_fw_send() argument
525 err = prestera_ldr_wait_reg32(fw, PRESTERA_LDR_STATUS_REG, in prestera_ldr_fw_send()
529 dev_err(fw->dev.dev, "Loader is not ready to load image\n"); in prestera_ldr_fw_send()
537 err = prestera_ldr_send(fw, img + pos, PRESTERA_FW_BLK_SZ); in prestera_ldr_fw_send()
543 err = prestera_ldr_send(fw, img + pos, fw_size - pos); in prestera_ldr_fw_send()
548 err = prestera_ldr_wait_dl_finish(fw); in prestera_ldr_fw_send()
552 status = prestera_ldr_read(fw, PRESTERA_LDR_STATUS_REG); in prestera_ldr_fw_send()
556 dev_err(fw->dev.dev, "FW img has bad CRC\n"); in prestera_ldr_fw_send()
559 dev_err(fw->dev.dev, "Loader has no enough mem\n"); in prestera_ldr_fw_send()
576 static int prestera_fw_rev_check(struct prestera_fw *fw) in prestera_fw_rev_check() argument
578 struct prestera_fw_rev *rev = &fw->dev.fw_rev; in prestera_fw_rev_check()
585 dev_err(fw->dev.dev, "Driver supports FW version only '%u.%u.x'", in prestera_fw_rev_check()
591 static int prestera_fw_hdr_parse(struct prestera_fw *fw, in prestera_fw_hdr_parse() argument
595 struct prestera_fw_rev *rev = &fw->dev.fw_rev; in prestera_fw_hdr_parse()
600 dev_err(fw->dev.dev, "FW img hdr magic is invalid"); in prestera_fw_hdr_parse()
606 dev_info(fw->dev.dev, "FW version '%u.%u.%u'\n", in prestera_fw_hdr_parse()
609 return prestera_fw_rev_check(fw); in prestera_fw_hdr_parse()
612 static int prestera_fw_load(struct prestera_fw *fw) in prestera_fw_load() argument
619 err = prestera_ldr_wait_reg32(fw, PRESTERA_LDR_READY_REG, in prestera_fw_load()
623 dev_err(fw->dev.dev, "waiting for FW loader is timed out"); in prestera_fw_load()
627 fw->ldr_ring_buf = fw->ldr_regs + in prestera_fw_load()
628 prestera_ldr_read(fw, PRESTERA_LDR_BUF_OFFS_REG); in prestera_fw_load()
630 fw->ldr_buf_len = in prestera_fw_load()
631 prestera_ldr_read(fw, PRESTERA_LDR_BUF_SIZE_REG); in prestera_fw_load()
633 fw->ldr_wr_idx = 0; in prestera_fw_load()
638 err = request_firmware_direct(&f, fw_path, fw->dev.dev); in prestera_fw_load()
640 dev_err(fw->dev.dev, "failed to request firmware file\n"); in prestera_fw_load()
644 err = prestera_fw_hdr_parse(fw, f); in prestera_fw_load()
646 dev_err(fw->dev.dev, "FW image header is invalid\n"); in prestera_fw_load()
650 prestera_ldr_write(fw, PRESTERA_LDR_IMG_SIZE_REG, f->size - hlen); in prestera_fw_load()
651 prestera_ldr_write(fw, PRESTERA_LDR_CTL_REG, PRESTERA_LDR_CTL_DL_START); in prestera_fw_load()
653 dev_info(fw->dev.dev, "Loading %s ...", fw_path); in prestera_fw_load()
655 err = prestera_ldr_fw_send(fw, f->data + hlen, f->size - hlen); in prestera_fw_load()
666 struct prestera_fw *fw; in prestera_pci_probe() local
687 fw = devm_kzalloc(&pdev->dev, sizeof(*fw), GFP_KERNEL); in prestera_pci_probe()
688 if (!fw) { in prestera_pci_probe()
693 fw->dev.ctl_regs = pcim_iomap_table(pdev)[PRESTERA_PCI_BAR_FW]; in prestera_pci_probe()
694 fw->dev.pp_regs = pcim_iomap_table(pdev)[PRESTERA_PCI_BAR_PP]; in prestera_pci_probe()
695 fw->dev.dev = &pdev->dev; in prestera_pci_probe()
697 pci_set_drvdata(pdev, fw); in prestera_pci_probe()
699 err = prestera_fw_init(fw); in prestera_pci_probe()
703 dev_info(fw->dev.dev, "Prestera FW is ready\n"); in prestera_pci_probe()
705 fw->wq = alloc_workqueue("prestera_fw_wq", WQ_HIGHPRI, 1); in prestera_pci_probe()
706 if (!fw->wq) { in prestera_pci_probe()
711 INIT_WORK(&fw->evt_work, prestera_fw_evt_work_fn); in prestera_pci_probe()
720 0, driver_name, fw); in prestera_pci_probe()
726 err = prestera_device_register(&fw->dev); in prestera_pci_probe()
733 free_irq(pci_irq_vector(pdev, 0), fw); in prestera_pci_probe()
737 destroy_workqueue(fw->wq); in prestera_pci_probe()
739 prestera_fw_uninit(fw); in prestera_pci_probe()
748 struct prestera_fw *fw = pci_get_drvdata(pdev); in prestera_pci_remove() local
750 prestera_device_unregister(&fw->dev); in prestera_pci_remove()
751 free_irq(pci_irq_vector(pdev, 0), fw); in prestera_pci_remove()
753 destroy_workqueue(fw->wq); in prestera_pci_remove()
754 prestera_fw_uninit(fw); in prestera_pci_remove()