Lines Matching +full:pci +full:- +full:host1
1 // SPDX-License-Identifier: GPL-2.0
3 * Endpoint Function Driver to implement Non-Transparent Bridge functionality
4 * Between PCI RC and EP
9 * Based on pci-epf-ntb.c
15 * +------------+ +---------------------------------------+
17 * +------------+ | +--------------+
20 * +------------+ | +--------------+
23 * +------------+ | +--------------+
25 * | PCI NTB | | | |
27 * | Driver | | | PCI Virtual |
28 * | | +---------------+ | NTB Driver |
29 * | | | PCI EP NTB |<------>| |
31 * +------------+ +---------------+ +--------------+
33 * | PCI Bus | <-----> | PCI EP Bus | | Virtual PCI |
34 * | | PCI | | | Bus |
35 * +------------+ +---------------+--------+--------------+
36 * PCIe Root Port PCI EP
44 #include <linux/pci-epc.h>
45 #include <linux/pci-epf.h>
79 * +--------------------------------------------------+ Base
87 * +-----------------------+--------------------------+ Base+spad_offset
92 * +-----------------------+--------------------------+ Base+spad_offset
97 * +-----------------------+--------------------------+
98 * Virtual PCI PCIe Endpoint
158 * epf_ntb_link_up() - Raise link_up interrupt to Virtual Host (VHOST)
170 ntb->reg->link_status |= LINK_STATUS_UP; in epf_ntb_link_up()
172 ntb->reg->link_status &= ~LINK_STATUS_UP; in epf_ntb_link_up()
174 ntb_link_event(&ntb->ntb); in epf_ntb_link_up()
179 * epf_ntb_configure_mw() - Configure the Outbound Address Space for VHOST
185 * +--------+ +-----------+
190 * | | +-----------+
192 * | NTB | -----------> | |
194 * | | +-----------+
197 * +--------+ +-----------+
198 * VHOST PCI EP
209 phys_addr = ntb->vpci_mw_phy[mw]; in epf_ntb_configure_mw()
210 addr = ntb->reg->addr; in epf_ntb_configure_mw()
211 size = ntb->reg->size; in epf_ntb_configure_mw()
213 func_no = ntb->epf->func_no; in epf_ntb_configure_mw()
214 vfunc_no = ntb->epf->vfunc_no; in epf_ntb_configure_mw()
216 ret = pci_epc_map_addr(ntb->epf->epc, func_no, vfunc_no, phys_addr, addr, size); in epf_ntb_configure_mw()
218 dev_err(&ntb->epf->epc->dev, in epf_ntb_configure_mw()
224 * epf_ntb_teardown_mw() - Teardown the configured OB ATU
233 pci_epc_unmap_addr(ntb->epf->epc, in epf_ntb_teardown_mw()
234 ntb->epf->func_no, in epf_ntb_teardown_mw()
235 ntb->epf->vfunc_no, in epf_ntb_teardown_mw()
236 ntb->vpci_mw_phy[mw]); in epf_ntb_teardown_mw()
240 * epf_ntb_cmd_handler() - Handle commands provided by the NTB HOST
259 for (i = 1; i < ntb->db_count; i++) { in epf_ntb_cmd_handler()
260 if (ntb->epf_db[i]) { in epf_ntb_cmd_handler()
261 ntb->db |= 1 << (i - 1); in epf_ntb_cmd_handler()
262 ntb_db_event(&ntb->ntb, i); in epf_ntb_cmd_handler()
263 ntb->epf_db[i] = 0; in epf_ntb_cmd_handler()
267 ctrl = ntb->reg; in epf_ntb_cmd_handler()
268 command = ctrl->command; in epf_ntb_cmd_handler()
271 argument = ctrl->argument; in epf_ntb_cmd_handler()
273 ctrl->command = 0; in epf_ntb_cmd_handler()
274 ctrl->argument = 0; in epf_ntb_cmd_handler()
276 ctrl = ntb->reg; in epf_ntb_cmd_handler()
277 dev = &ntb->epf->dev; in epf_ntb_cmd_handler()
281 ctrl->command_status = COMMAND_STATUS_OK; in epf_ntb_cmd_handler()
284 ctrl->command_status = COMMAND_STATUS_OK; in epf_ntb_cmd_handler()
289 ctrl->command_status = COMMAND_STATUS_ERROR; in epf_ntb_cmd_handler()
291 ctrl->command_status = COMMAND_STATUS_OK; in epf_ntb_cmd_handler()
295 ctrl->command_status = COMMAND_STATUS_OK; in epf_ntb_cmd_handler()
298 ntb->linkup = true; in epf_ntb_cmd_handler()
301 ctrl->command_status = COMMAND_STATUS_ERROR; in epf_ntb_cmd_handler()
303 ctrl->command_status = COMMAND_STATUS_OK; in epf_ntb_cmd_handler()
306 ntb->linkup = false; in epf_ntb_cmd_handler()
309 ctrl->command_status = COMMAND_STATUS_ERROR; in epf_ntb_cmd_handler()
311 ctrl->command_status = COMMAND_STATUS_OK; in epf_ntb_cmd_handler()
319 queue_delayed_work(kpcintb_workqueue, &ntb->cmd_handler, in epf_ntb_cmd_handler()
324 * epf_ntb_config_sspad_bar_clear() - Clear Config + Self scratchpad BAR
328 * Clear BAR0 of EP CONTROLLER 1 which contains the HOST1's config and
345 barno = ntb->epf_ntb_bar[BAR_CONFIG]; in epf_ntb_config_sspad_bar_clear()
346 epf_bar = &ntb->epf->bar[barno]; in epf_ntb_config_sspad_bar_clear()
348 pci_epc_clear_bar(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no, epf_bar); in epf_ntb_config_sspad_bar_clear()
352 * epf_ntb_config_sspad_bar_set() - Set Config + Self scratchpad BAR
371 dev = &ntb->epf->dev; in epf_ntb_config_sspad_bar_set()
372 func_no = ntb->epf->func_no; in epf_ntb_config_sspad_bar_set()
373 vfunc_no = ntb->epf->vfunc_no; in epf_ntb_config_sspad_bar_set()
374 barno = ntb->epf_ntb_bar[BAR_CONFIG]; in epf_ntb_config_sspad_bar_set()
375 epf_bar = &ntb->epf->bar[barno]; in epf_ntb_config_sspad_bar_set()
377 ret = pci_epc_set_bar(ntb->epf->epc, func_no, vfunc_no, epf_bar); in epf_ntb_config_sspad_bar_set()
386 * epf_ntb_config_spad_bar_free() - Free the physical memory associated with
394 barno = ntb->epf_ntb_bar[BAR_CONFIG]; in epf_ntb_config_spad_bar_free()
395 pci_epf_free_space(ntb->epf, ntb->reg, barno, 0); in epf_ntb_config_spad_bar_free()
399 * epf_ntb_config_spad_bar_alloc() - Allocate memory for config + scratchpad
405 * is obtained from "spad-count" configfs entry.
416 struct pci_epf *epf = ntb->epf; in epf_ntb_config_spad_bar_alloc()
417 struct device *dev = &epf->dev; in epf_ntb_config_spad_bar_alloc()
421 const struct pci_epc_features *epc_features = pci_epc_get_features(epf->epc, in epf_ntb_config_spad_bar_alloc()
422 epf->func_no, in epf_ntb_config_spad_bar_alloc()
423 epf->vfunc_no); in epf_ntb_config_spad_bar_alloc()
424 barno = ntb->epf_ntb_bar[BAR_CONFIG]; in epf_ntb_config_spad_bar_alloc()
425 size = epc_features->bar_fixed_size[barno]; in epf_ntb_config_spad_bar_alloc()
426 align = epc_features->align; in epf_ntb_config_spad_bar_alloc()
429 return -EINVAL; in epf_ntb_config_spad_bar_alloc()
431 spad_count = ntb->spad_count; in epf_ntb_config_spad_bar_alloc()
447 return -EINVAL; in epf_ntb_config_spad_bar_alloc()
452 return -ENOMEM; in epf_ntb_config_spad_bar_alloc()
455 ntb->reg = base; in epf_ntb_config_spad_bar_alloc()
457 ctrl = ntb->reg; in epf_ntb_config_spad_bar_alloc()
458 ctrl->spad_offset = ctrl_size; in epf_ntb_config_spad_bar_alloc()
460 ctrl->spad_count = spad_count; in epf_ntb_config_spad_bar_alloc()
461 ctrl->num_mws = ntb->num_mws; in epf_ntb_config_spad_bar_alloc()
462 ntb->spad_size = spad_size; in epf_ntb_config_spad_bar_alloc()
464 ctrl->db_entry_size = sizeof(u32); in epf_ntb_config_spad_bar_alloc()
466 for (i = 0; i < ntb->db_count; i++) { in epf_ntb_config_spad_bar_alloc()
467 ntb->reg->db_data[i] = 1 + i; in epf_ntb_config_spad_bar_alloc()
468 ntb->reg->db_offset[i] = 0; in epf_ntb_config_spad_bar_alloc()
475 * epf_ntb_configure_interrupt() - Configure MSI/MSI-X capability
478 * Configure MSI/MSI-X capability for each interface with number of
490 dev = &ntb->epf->dev; in epf_ntb_configure_interrupt()
492 epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no); in epf_ntb_configure_interrupt()
494 if (!(epc_features->msix_capable || epc_features->msi_capable)) { in epf_ntb_configure_interrupt()
495 dev_err(dev, "MSI or MSI-X is required for doorbell\n"); in epf_ntb_configure_interrupt()
496 return -EINVAL; in epf_ntb_configure_interrupt()
499 db_count = ntb->db_count; in epf_ntb_configure_interrupt()
502 return -EINVAL; in epf_ntb_configure_interrupt()
505 ntb->db_count = db_count; in epf_ntb_configure_interrupt()
507 if (epc_features->msi_capable) { in epf_ntb_configure_interrupt()
508 ret = pci_epc_set_msi(ntb->epf->epc, in epf_ntb_configure_interrupt()
509 ntb->epf->func_no, in epf_ntb_configure_interrupt()
510 ntb->epf->vfunc_no, in epf_ntb_configure_interrupt()
522 * epf_ntb_db_bar_init() - Configure Doorbell window BARs
531 struct device *dev = &ntb->epf->dev; in epf_ntb_db_bar_init()
536 size_t size = sizeof(u32) * ntb->db_count; in epf_ntb_db_bar_init()
538 epc_features = pci_epc_get_features(ntb->epf->epc, in epf_ntb_db_bar_init()
539 ntb->epf->func_no, in epf_ntb_db_bar_init()
540 ntb->epf->vfunc_no); in epf_ntb_db_bar_init()
541 align = epc_features->align; in epf_ntb_db_bar_init()
551 barno = ntb->epf_ntb_bar[BAR_DB]; in epf_ntb_db_bar_init()
553 mw_addr = pci_epf_alloc_space(ntb->epf, size, barno, align, 0); in epf_ntb_db_bar_init()
556 return -ENOMEM; in epf_ntb_db_bar_init()
559 ntb->epf_db = mw_addr; in epf_ntb_db_bar_init()
561 epf_bar = &ntb->epf->bar[barno]; in epf_ntb_db_bar_init()
563 ret = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no, epf_bar); in epf_ntb_db_bar_init()
571 pci_epf_free_space(ntb->epf, mw_addr, barno, 0); in epf_ntb_db_bar_init()
572 return -1; in epf_ntb_db_bar_init()
578 * epf_ntb_db_bar_clear() - Clear doorbell BAR and free memory
586 barno = ntb->epf_ntb_bar[BAR_DB]; in epf_ntb_db_bar_clear()
587 pci_epf_free_space(ntb->epf, ntb->epf_db, barno, 0); in epf_ntb_db_bar_clear()
588 pci_epc_clear_bar(ntb->epf->epc, in epf_ntb_db_bar_clear()
589 ntb->epf->func_no, in epf_ntb_db_bar_clear()
590 ntb->epf->vfunc_no, in epf_ntb_db_bar_clear()
591 &ntb->epf->bar[barno]); in epf_ntb_db_bar_clear()
595 * epf_ntb_mw_bar_init() - Configure Memory window BARs
606 struct device *dev = &ntb->epf->dev; in epf_ntb_mw_bar_init()
608 for (i = 0; i < ntb->num_mws; i++) { in epf_ntb_mw_bar_init()
609 size = ntb->mws_size[i]; in epf_ntb_mw_bar_init()
610 barno = ntb->epf_ntb_bar[BAR_MW0 + i]; in epf_ntb_mw_bar_init()
612 ntb->epf->bar[barno].barno = barno; in epf_ntb_mw_bar_init()
613 ntb->epf->bar[barno].size = size; in epf_ntb_mw_bar_init()
614 ntb->epf->bar[barno].addr = NULL; in epf_ntb_mw_bar_init()
615 ntb->epf->bar[barno].phys_addr = 0; in epf_ntb_mw_bar_init()
616 ntb->epf->bar[barno].flags |= upper_32_bits(size) ? in epf_ntb_mw_bar_init()
620 ret = pci_epc_set_bar(ntb->epf->epc, in epf_ntb_mw_bar_init()
621 ntb->epf->func_no, in epf_ntb_mw_bar_init()
622 ntb->epf->vfunc_no, in epf_ntb_mw_bar_init()
623 &ntb->epf->bar[barno]); in epf_ntb_mw_bar_init()
630 ntb->vpci_mw_addr[i] = pci_epc_mem_alloc_addr(ntb->epf->epc, in epf_ntb_mw_bar_init()
631 &ntb->vpci_mw_phy[i], in epf_ntb_mw_bar_init()
633 if (!ntb->vpci_mw_addr[i]) { in epf_ntb_mw_bar_init()
634 ret = -ENOMEM; in epf_ntb_mw_bar_init()
643 pci_epc_clear_bar(ntb->epf->epc, in epf_ntb_mw_bar_init()
644 ntb->epf->func_no, in epf_ntb_mw_bar_init()
645 ntb->epf->vfunc_no, in epf_ntb_mw_bar_init()
646 &ntb->epf->bar[barno]); in epf_ntb_mw_bar_init()
653 * epf_ntb_mw_bar_clear() - Clear Memory window BARs
663 barno = ntb->epf_ntb_bar[BAR_MW0 + i]; in epf_ntb_mw_bar_clear()
664 pci_epc_clear_bar(ntb->epf->epc, in epf_ntb_mw_bar_clear()
665 ntb->epf->func_no, in epf_ntb_mw_bar_clear()
666 ntb->epf->vfunc_no, in epf_ntb_mw_bar_clear()
667 &ntb->epf->bar[barno]); in epf_ntb_mw_bar_clear()
669 pci_epc_mem_free_addr(ntb->epf->epc, in epf_ntb_mw_bar_clear()
670 ntb->vpci_mw_phy[i], in epf_ntb_mw_bar_clear()
671 ntb->vpci_mw_addr[i], in epf_ntb_mw_bar_clear()
672 ntb->mws_size[i]); in epf_ntb_mw_bar_clear()
677 * epf_ntb_epc_destroy() - Cleanup NTB EPC interface
684 pci_epc_remove_epf(ntb->epf->epc, ntb->epf, 0); in epf_ntb_epc_destroy()
685 pci_epc_put(ntb->epf->epc); in epf_ntb_epc_destroy()
689 * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
705 num_mws = ntb->num_mws; in epf_ntb_init_epc_bar()
706 dev = &ntb->epf->dev; in epf_ntb_init_epc_bar()
707 epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no); in epf_ntb_init_epc_bar()
716 ntb->epf_ntb_bar[bar] = barno; in epf_ntb_init_epc_bar()
723 ntb->num_mws = i; in epf_ntb_init_epc_bar()
726 ntb->epf_ntb_bar[bar] = barno; in epf_ntb_init_epc_bar()
733 * epf_ntb_epc_init() - Initialize NTB interface
750 epf = ntb->epf; in epf_ntb_epc_init()
751 dev = &epf->dev; in epf_ntb_epc_init()
752 epc = epf->epc; in epf_ntb_epc_init()
753 func_no = ntb->epf->func_no; in epf_ntb_epc_init()
754 vfunc_no = ntb->epf->vfunc_no; in epf_ntb_epc_init()
781 ret = pci_epc_write_header(epc, func_no, vfunc_no, epf->header); in epf_ntb_epc_init()
788 INIT_DELAYED_WORK(&ntb->cmd_handler, epf_ntb_cmd_handler); in epf_ntb_epc_init()
789 queue_work(kpcintb_workqueue, &ntb->cmd_handler.work); in epf_ntb_epc_init()
794 epf_ntb_mw_bar_clear(ntb, ntb->num_mws); in epf_ntb_epc_init()
806 * epf_ntb_epc_cleanup() - Cleanup all NTB interfaces
814 epf_ntb_mw_bar_clear(ntb, ntb->num_mws); in epf_ntb_epc_cleanup()
824 return sprintf(page, "%d\n", ntb->_name); \
840 ntb->_name = val; \
851 struct device *dev = &ntb->epf->dev; \
855 return -EINVAL; \
857 if (win_no <= 0 || win_no > ntb->num_mws) { \
858 dev_err(dev, "Invalid num_nws: %d value\n", ntb->num_mws); \
859 return -EINVAL; \
862 return sprintf(page, "%lld\n", ntb->mws_size[win_no - 1]); \
871 struct device *dev = &ntb->epf->dev; \
881 return -EINVAL; \
883 if (win_no <= 0 || win_no > ntb->num_mws) { \
884 dev_err(dev, "Invalid num_nws: %d value\n", ntb->num_mws); \
885 return -EINVAL; \
888 ntb->mws_size[win_no - 1] = val; \
906 return -EINVAL; in epf_ntb_num_mws_store()
908 ntb->num_mws = val; in epf_ntb_num_mws_store()
964 * epf_ntb_add_cfs() - Add configfs directory specific to NTB
967 * config_items of a specific type that belong to a specific sub-system.
978 struct config_group *ntb_group = &ntb->group; in epf_ntb_add_cfs()
979 struct device *dev = &epf->dev; in epf_ntb_add_cfs()
986 /*==== virtual PCI bus driver, which only load virtual NTB PCI driver ====*/
1031 vpci_bus = pci_scan_bus(ndev->vbus_number, &vpci_ops, sysdata); in vpci_scan_bus()
1033 pr_err("create pci bus\n"); in vpci_scan_bus()
1046 return ndev->num_mws; in vntb_epf_mw_count()
1051 return ntb_ndev(ntb)->spad_count; in vntb_epf_spad_count()
1056 return ntb_ndev(ntb)->num_mws; in vntb_epf_peer_mw_count()
1061 return BIT_ULL(ntb_ndev(ntb)->db_count) - 1; in vntb_epf_db_valid_mask()
1078 dev = &ntb->ntb.dev; in vntb_epf_mw_set_trans()
1079 barno = ntb->epf_ntb_bar[BAR_MW0 + idx]; in vntb_epf_mw_set_trans()
1080 epf_bar = &ntb->epf->bar[barno]; in vntb_epf_mw_set_trans()
1081 epf_bar->phys_addr = addr; in vntb_epf_mw_set_trans()
1082 epf_bar->barno = barno; in vntb_epf_mw_set_trans()
1083 epf_bar->size = size; in vntb_epf_mw_set_trans()
1085 ret = pci_epc_set_bar(ntb->epf->epc, 0, 0, epf_bar); in vntb_epf_mw_set_trans()
1105 *base = ntb->vpci_mw_phy[idx]; in vntb_epf_peer_mw_get_addr()
1108 *size = ntb->mws_size[idx]; in vntb_epf_peer_mw_get_addr()
1123 int off = ntb->reg->spad_offset, ct = ntb->reg->spad_count * sizeof(u32); in vntb_epf_spad_read()
1125 void __iomem *base = (void __iomem *)ntb->reg; in vntb_epf_spad_read()
1134 struct epf_ntb_ctrl *ctrl = ntb->reg; in vntb_epf_spad_write()
1135 int off = ctrl->spad_offset, ct = ctrl->spad_count * sizeof(u32); in vntb_epf_spad_write()
1136 void __iomem *base = (void __iomem *)ntb->reg; in vntb_epf_spad_write()
1145 struct epf_ntb_ctrl *ctrl = ntb->reg; in vntb_epf_peer_spad_read()
1146 int off = ctrl->spad_offset; in vntb_epf_peer_spad_read()
1147 void __iomem *base = (void __iomem *)ntb->reg; in vntb_epf_peer_spad_read()
1157 struct epf_ntb_ctrl *ctrl = ntb->reg; in vntb_epf_peer_spad_write()
1158 int off = ctrl->spad_offset; in vntb_epf_peer_spad_write()
1159 void __iomem *base = (void __iomem *)ntb->reg; in vntb_epf_peer_spad_write()
1172 func_no = ntb->epf->func_no; in vntb_epf_peer_db_set()
1173 vfunc_no = ntb->epf->vfunc_no; in vntb_epf_peer_db_set()
1175 ret = pci_epc_raise_irq(ntb->epf->epc, in vntb_epf_peer_db_set()
1181 dev_err(&ntb->ntb.dev, "Failed to raise IRQ\n"); in vntb_epf_peer_db_set()
1190 return ntb->db; in vntb_epf_db_read()
1207 *size_max = ntb->mws_size[idx]; in vntb_epf_mw_get_align()
1218 return ntb->reg->link_status; in vntb_epf_link_is_up()
1230 ntb->db &= ~db_bits; in vntb_epf_db_clear()
1265 struct epf_ntb *ndev = (struct epf_ntb *)pdev->sysdata; in pci_vntb_probe()
1266 struct device *dev = &pdev->dev; in pci_vntb_probe()
1268 ndev->ntb.pdev = pdev; in pci_vntb_probe()
1269 ndev->ntb.topo = NTB_TOPO_NONE; in pci_vntb_probe()
1270 ndev->ntb.ops = &vntb_epf_ops; in pci_vntb_probe()
1275 return -EINVAL; in pci_vntb_probe()
1278 ret = ntb_register_device(&ndev->ntb); in pci_vntb_probe()
1284 dev_dbg(dev, "PCI Virtual NTB driver loaded\n"); in pci_vntb_probe()
1288 put_device(&ndev->ntb.dev); in pci_vntb_probe()
1289 return -EINVAL; in pci_vntb_probe()
1300 .name = "pci-vntb",
1308 * epf_ntb_bind() - Initialize endpoint controller to provide NTB functionality
1321 struct device *dev = &epf->dev; in epf_ntb_bind()
1324 if (!epf->epc) { in epf_ntb_bind()
1349 pci_space[0] = (ntb->vntb_pid << 16) | ntb->vntb_vid; in epf_ntb_bind()
1350 pci_vntb_table[0].vendor = ntb->vntb_vid; in epf_ntb_bind()
1351 pci_vntb_table[0].device = ntb->vntb_pid; in epf_ntb_bind()
1355 dev_err(dev, "failure register vntb pci driver\n"); in epf_ntb_bind()
1373 * epf_ntb_unbind() - Cleanup the initialization from epf_ntb_bind()
1397 * epf_ntb_probe() - Probe NTB function driver
1412 dev = &epf->dev; in epf_ntb_probe()
1416 return -ENOMEM; in epf_ntb_probe()
1418 epf->header = &epf_ntb_header; in epf_ntb_probe()
1419 ntb->epf = epf; in epf_ntb_probe()
1420 ntb->vbus_number = 0xff; in epf_ntb_probe()
1423 dev_info(dev, "pci-ep epf driver loaded\n"); in epf_ntb_probe()
1451 pr_err("Failed to register pci epf ntb driver --> %d\n", ret); in epf_ntb_init()
1466 MODULE_DESCRIPTION("PCI EPF NTB DRIVER");