Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PCI: endpoint: Add support to associate secondary EPC with EPF

In the case of standard endpoint functions, only one endpoint controller
(EPC) will be associated with an endpoint function (EPF). However for
providing NTB (non transparent bridge) functionality, two EPCs should be
associated with a single EPF. Add support to associate secondary EPC with
EPF. This is in preparation for adding NTB endpoint function driver.

Link: https://lore.kernel.org/r/20210201195809.7342-7-kishon@ti.com
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

authored by

Kishon Vijay Abraham I and committed by
Bjorn Helgaas
63840ff5 7e5a51eb

+125 -38
+7 -4
drivers/pci/endpoint/functions/pci-epf-test.c
··· 619 619 620 620 if (epf_test->reg[bar]) { 621 621 pci_epc_clear_bar(epc, epf->func_no, epf_bar); 622 - pci_epf_free_space(epf, epf_test->reg[bar], bar); 622 + pci_epf_free_space(epf, epf_test->reg[bar], bar, 623 + PRIMARY_INTERFACE); 623 624 } 624 625 } 625 626 } ··· 652 651 653 652 ret = pci_epc_set_bar(epc, epf->func_no, epf_bar); 654 653 if (ret) { 655 - pci_epf_free_space(epf, epf_test->reg[bar], bar); 654 + pci_epf_free_space(epf, epf_test->reg[bar], bar, 655 + PRIMARY_INTERFACE); 656 656 dev_err(dev, "Failed to set BAR%d\n", bar); 657 657 if (bar == test_reg_bar) 658 658 return ret; ··· 773 771 } 774 772 775 773 base = pci_epf_alloc_space(epf, test_reg_size, test_reg_bar, 776 - epc_features->align); 774 + epc_features->align, PRIMARY_INTERFACE); 777 775 if (!base) { 778 776 dev_err(dev, "Failed to allocated register space\n"); 779 777 return -ENOMEM; ··· 791 789 continue; 792 790 793 791 base = pci_epf_alloc_space(epf, bar_size[bar], bar, 794 - epc_features->align); 792 + epc_features->align, 793 + PRIMARY_INTERFACE); 795 794 if (!base) 796 795 dev_err(dev, "Failed to allocate space for BAR%d\n", 797 796 bar);
+3 -3
drivers/pci/endpoint/pci-ep-cfs.c
··· 94 94 struct pci_epc *epc = epc_group->epc; 95 95 struct pci_epf *epf = epf_group->epf; 96 96 97 - ret = pci_epc_add_epf(epc, epf); 97 + ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE); 98 98 if (ret) 99 99 return ret; 100 100 101 101 ret = pci_epf_bind(epf); 102 102 if (ret) { 103 - pci_epc_remove_epf(epc, epf); 103 + pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE); 104 104 return ret; 105 105 } 106 106 ··· 120 120 epc = epc_group->epc; 121 121 epf = epf_group->epf; 122 122 pci_epf_unbind(epf); 123 - pci_epc_remove_epf(epc, epf); 123 + pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE); 124 124 } 125 125 126 126 static struct configfs_item_operations pci_epc_item_ops = {
+36 -11
drivers/pci/endpoint/pci-epc-core.c
··· 493 493 * pci_epc_add_epf() - bind PCI endpoint function to an endpoint controller 494 494 * @epc: the EPC device to which the endpoint function should be added 495 495 * @epf: the endpoint function to be added 496 + * @type: Identifies if the EPC is connected to the primary or secondary 497 + * interface of EPF 496 498 * 497 499 * A PCI endpoint device can have one or more functions. In the case of PCIe, 498 500 * the specification allows up to 8 PCIe endpoint functions. Invoke 499 501 * pci_epc_add_epf() to add a PCI endpoint function to an endpoint controller. 500 502 */ 501 - int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf) 503 + int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf, 504 + enum pci_epc_interface_type type) 502 505 { 506 + struct list_head *list; 503 507 u32 func_no; 504 508 int ret = 0; 505 509 506 - if (epf->epc) 510 + if (IS_ERR_OR_NULL(epc)) 511 + return -EINVAL; 512 + 513 + if (type == PRIMARY_INTERFACE && epf->epc) 507 514 return -EBUSY; 508 515 509 - if (IS_ERR(epc)) 510 - return -EINVAL; 516 + if (type == SECONDARY_INTERFACE && epf->sec_epc) 517 + return -EBUSY; 511 518 512 519 mutex_lock(&epc->lock); 513 520 func_no = find_first_zero_bit(&epc->function_num_map, ··· 531 524 } 532 525 533 526 set_bit(func_no, &epc->function_num_map); 534 - epf->func_no = func_no; 535 - epf->epc = epc; 527 + if (type == PRIMARY_INTERFACE) { 528 + epf->func_no = func_no; 529 + epf->epc = epc; 530 + list = &epf->list; 531 + } else { 532 + epf->sec_epc_func_no = func_no; 533 + epf->sec_epc = epc; 534 + list = &epf->sec_epc_list; 535 + } 536 536 537 - list_add_tail(&epf->list, &epc->pci_epf); 538 - 537 + list_add_tail(list, &epc->pci_epf); 539 538 ret: 540 539 mutex_unlock(&epc->lock); 541 540 ··· 556 543 * 557 544 * Invoke to remove PCI endpoint function from the endpoint controller. 558 545 */ 559 - void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf) 546 + void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf, 547 + enum pci_epc_interface_type type) 560 548 { 549 + struct list_head *list; 550 + u32 func_no = 0; 551 + 561 552 if (!epc || IS_ERR(epc) || !epf) 562 553 return; 563 554 555 + if (type == PRIMARY_INTERFACE) { 556 + func_no = epf->func_no; 557 + list = &epf->list; 558 + } else { 559 + func_no = epf->sec_epc_func_no; 560 + list = &epf->sec_epc_list; 561 + } 562 + 564 563 mutex_lock(&epc->lock); 565 - clear_bit(epf->func_no, &epc->function_num_map); 566 - list_del(&epf->list); 564 + clear_bit(func_no, &epc->function_num_map); 565 + list_del(list); 567 566 epf->epc = NULL; 568 567 mutex_unlock(&epc->lock); 569 568 }
+41 -16
drivers/pci/endpoint/pci-epf-core.c
··· 74 74 * @epf: the EPF device from whom to free the memory 75 75 * @addr: the virtual address of the PCI EPF register space 76 76 * @bar: the BAR number corresponding to the register space 77 + * @type: Identifies if the allocated space is for primary EPC or secondary EPC 77 78 * 78 79 * Invoke to free the allocated PCI EPF register space. 79 80 */ 80 - void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar) 81 + void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar, 82 + enum pci_epc_interface_type type) 81 83 { 82 84 struct device *dev = epf->epc->dev.parent; 85 + struct pci_epf_bar *epf_bar; 86 + struct pci_epc *epc; 83 87 84 88 if (!addr) 85 89 return; 86 90 87 - dma_free_coherent(dev, epf->bar[bar].size, addr, 88 - epf->bar[bar].phys_addr); 91 + if (type == PRIMARY_INTERFACE) { 92 + epc = epf->epc; 93 + epf_bar = epf->bar; 94 + } else { 95 + epc = epf->sec_epc; 96 + epf_bar = epf->sec_epc_bar; 97 + } 89 98 90 - epf->bar[bar].phys_addr = 0; 91 - epf->bar[bar].addr = NULL; 92 - epf->bar[bar].size = 0; 93 - epf->bar[bar].barno = 0; 94 - epf->bar[bar].flags = 0; 99 + dev = epc->dev.parent; 100 + dma_free_coherent(dev, epf_bar[bar].size, addr, 101 + epf_bar[bar].phys_addr); 102 + 103 + epf_bar[bar].phys_addr = 0; 104 + epf_bar[bar].addr = NULL; 105 + epf_bar[bar].size = 0; 106 + epf_bar[bar].barno = 0; 107 + epf_bar[bar].flags = 0; 95 108 } 96 109 EXPORT_SYMBOL_GPL(pci_epf_free_space); 97 110 ··· 114 101 * @size: the size of the memory that has to be allocated 115 102 * @bar: the BAR number corresponding to the allocated register space 116 103 * @align: alignment size for the allocation region 104 + * @type: Identifies if the allocation is for primary EPC or secondary EPC 117 105 * 118 106 * Invoke to allocate memory for the PCI EPF register space. 119 107 */ 120 108 void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, 121 - size_t align) 109 + size_t align, enum pci_epc_interface_type type) 122 110 { 123 - void *space; 124 - struct device *dev = epf->epc->dev.parent; 111 + struct pci_epf_bar *epf_bar; 125 112 dma_addr_t phys_addr; 113 + struct pci_epc *epc; 114 + struct device *dev; 115 + void *space; 126 116 127 117 if (size < 128) 128 118 size = 128; ··· 135 119 else 136 120 size = roundup_pow_of_two(size); 137 121 122 + if (type == PRIMARY_INTERFACE) { 123 + epc = epf->epc; 124 + epf_bar = epf->bar; 125 + } else { 126 + epc = epf->sec_epc; 127 + epf_bar = epf->sec_epc_bar; 128 + } 129 + 130 + dev = epc->dev.parent; 138 131 space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); 139 132 if (!space) { 140 133 dev_err(dev, "failed to allocate mem space\n"); 141 134 return NULL; 142 135 } 143 136 144 - epf->bar[bar].phys_addr = phys_addr; 145 - epf->bar[bar].addr = space; 146 - epf->bar[bar].size = size; 147 - epf->bar[bar].barno = bar; 148 - epf->bar[bar].flags |= upper_32_bits(size) ? 137 + epf_bar[bar].phys_addr = phys_addr; 138 + epf_bar[bar].addr = space; 139 + epf_bar[bar].size = size; 140 + epf_bar[bar].barno = bar; 141 + epf_bar[bar].flags |= upper_32_bits(size) ? 149 142 PCI_BASE_ADDRESS_MEM_TYPE_64 : 150 143 PCI_BASE_ADDRESS_MEM_TYPE_32; 151 144
+23 -2
include/linux/pci-epc.h
··· 13 13 14 14 struct pci_epc; 15 15 16 + enum pci_epc_interface_type { 17 + UNKNOWN_INTERFACE = -1, 18 + PRIMARY_INTERFACE, 19 + SECONDARY_INTERFACE, 20 + }; 21 + 16 22 enum pci_epc_irq_type { 17 23 PCI_EPC_IRQ_UNKNOWN, 18 24 PCI_EPC_IRQ_LEGACY, 19 25 PCI_EPC_IRQ_MSI, 20 26 PCI_EPC_IRQ_MSIX, 21 27 }; 28 + 29 + static inline const char * 30 + pci_epc_interface_string(enum pci_epc_interface_type type) 31 + { 32 + switch (type) { 33 + case PRIMARY_INTERFACE: 34 + return "primary"; 35 + case SECONDARY_INTERFACE: 36 + return "secondary"; 37 + default: 38 + return "UNKNOWN interface"; 39 + } 40 + } 22 41 23 42 /** 24 43 * struct pci_epc_ops - set of function pointers for performing EPC operations ··· 194 175 struct module *owner); 195 176 void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc); 196 177 void pci_epc_destroy(struct pci_epc *epc); 197 - int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf); 178 + int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf, 179 + enum pci_epc_interface_type type); 198 180 void pci_epc_linkup(struct pci_epc *epc); 199 181 void pci_epc_init_notify(struct pci_epc *epc); 200 - void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf); 182 + void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf, 183 + enum pci_epc_interface_type type); 201 184 int pci_epc_write_header(struct pci_epc *epc, u8 func_no, 202 185 struct pci_epf_header *hdr); 203 186 int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+15 -2
include/linux/pci-epf.h
··· 14 14 #include <linux/pci.h> 15 15 16 16 struct pci_epf; 17 + enum pci_epc_interface_type; 17 18 18 19 enum pci_notify_event { 19 20 CORE_INIT, ··· 120 119 * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc 121 120 * @nb: notifier block to notify EPF of any EPC events (like linkup) 122 121 * @lock: mutex to protect pci_epf_ops 122 + * @sec_epc: the secondary EPC device to which this EPF device is bound 123 + * @sec_epc_list: to add pci_epf as list of PCI endpoint functions to secondary 124 + * EPC device 125 + * @sec_epc_bar: represents the BAR of EPF device associated with secondary EPC 126 + * @sec_epc_func_no: unique (physical) function number within the secondary EPC 123 127 */ 124 128 struct pci_epf { 125 129 struct device dev; ··· 141 135 struct notifier_block nb; 142 136 /* mutex to protect against concurrent access of pci_epf_ops */ 143 137 struct mutex lock; 138 + 139 + /* Below members are to attach secondary EPC to an endpoint function */ 140 + struct pci_epc *sec_epc; 141 + struct list_head sec_epc_list; 142 + struct pci_epf_bar sec_epc_bar[6]; 143 + u8 sec_epc_func_no; 144 144 }; 145 145 146 146 /** ··· 183 171 struct module *owner); 184 172 void pci_epf_unregister_driver(struct pci_epf_driver *driver); 185 173 void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, 186 - size_t align); 187 - void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar); 174 + size_t align, enum pci_epc_interface_type type); 175 + void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar, 176 + enum pci_epc_interface_type type); 188 177 int pci_epf_bind(struct pci_epf *epf); 189 178 void pci_epf_unbind(struct pci_epf *epf); 190 179 #endif /* __LINUX_PCI_EPF_H */