Skip to content

Commit 63840ff

Browse files
kishonbjorn-helgaas
authored andcommitted
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>
1 parent 7e5a51e commit 63840ff

File tree

6 files changed

+125
-38
lines changed

6 files changed

+125
-38
lines changed

drivers/pci/endpoint/functions/pci-epf-test.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,8 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
619619

620620
if (epf_test->reg[bar]) {
621621
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);
623624
}
624625
}
625626
}
@@ -651,7 +652,8 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
651652

652653
ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
653654
if (ret) {
654-
pci_epf_free_space(epf, epf_test->reg[bar], bar);
655+
pci_epf_free_space(epf, epf_test->reg[bar], bar,
656+
PRIMARY_INTERFACE);
655657
dev_err(dev, "Failed to set BAR%d\n", bar);
656658
if (bar == test_reg_bar)
657659
return ret;
@@ -771,7 +773,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
771773
}
772774

773775
base = pci_epf_alloc_space(epf, test_reg_size, test_reg_bar,
774-
epc_features->align);
776+
epc_features->align, PRIMARY_INTERFACE);
775777
if (!base) {
776778
dev_err(dev, "Failed to allocated register space\n");
777779
return -ENOMEM;
@@ -789,7 +791,8 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
789791
continue;
790792

791793
base = pci_epf_alloc_space(epf, bar_size[bar], bar,
792-
epc_features->align);
794+
epc_features->align,
795+
PRIMARY_INTERFACE);
793796
if (!base)
794797
dev_err(dev, "Failed to allocate space for BAR%d\n",
795798
bar);

drivers/pci/endpoint/pci-ep-cfs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ static int pci_epc_epf_link(struct config_item *epc_item,
9494
struct pci_epc *epc = epc_group->epc;
9595
struct pci_epf *epf = epf_group->epf;
9696

97-
ret = pci_epc_add_epf(epc, epf);
97+
ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
9898
if (ret)
9999
return ret;
100100

101101
ret = pci_epf_bind(epf);
102102
if (ret) {
103-
pci_epc_remove_epf(epc, epf);
103+
pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
104104
return ret;
105105
}
106106

@@ -120,7 +120,7 @@ static void pci_epc_epf_unlink(struct config_item *epc_item,
120120
epc = epc_group->epc;
121121
epf = epf_group->epf;
122122
pci_epf_unbind(epf);
123-
pci_epc_remove_epf(epc, epf);
123+
pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
124124
}
125125

126126
static struct configfs_item_operations pci_epc_item_ops = {

drivers/pci/endpoint/pci-epc-core.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -493,21 +493,28 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header);
493493
* pci_epc_add_epf() - bind PCI endpoint function to an endpoint controller
494494
* @epc: the EPC device to which the endpoint function should be added
495495
* @epf: the endpoint function to be added
496+
* @type: Identifies if the EPC is connected to the primary or secondary
497+
* interface of EPF
496498
*
497499
* A PCI endpoint device can have one or more functions. In the case of PCIe,
498500
* the specification allows up to 8 PCIe endpoint functions. Invoke
499501
* pci_epc_add_epf() to add a PCI endpoint function to an endpoint controller.
500502
*/
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)
502505
{
506+
struct list_head *list;
503507
u32 func_no;
504508
int ret = 0;
505509

506-
if (epf->epc)
510+
if (IS_ERR_OR_NULL(epc))
511+
return -EINVAL;
512+
513+
if (type == PRIMARY_INTERFACE && epf->epc)
507514
return -EBUSY;
508515

509-
if (IS_ERR(epc))
510-
return -EINVAL;
516+
if (type == SECONDARY_INTERFACE && epf->sec_epc)
517+
return -EBUSY;
511518

512519
mutex_lock(&epc->lock);
513520
func_no = find_first_zero_bit(&epc->function_num_map,
@@ -524,11 +531,17 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
524531
}
525532

526533
set_bit(func_no, &epc->function_num_map);
527-
epf->func_no = func_no;
528-
epf->epc = epc;
529-
530-
list_add_tail(&epf->list, &epc->pci_epf);
534+
if (type == PRIMARY_INTERFACE) {
535+
epf->func_no = func_no;
536+
epf->epc = epc;
537+
list = &epf->list;
538+
} else {
539+
epf->sec_epc_func_no = func_no;
540+
epf->sec_epc = epc;
541+
list = &epf->sec_epc_list;
542+
}
531543

544+
list_add_tail(list, &epc->pci_epf);
532545
ret:
533546
mutex_unlock(&epc->lock);
534547

@@ -543,14 +556,26 @@ EXPORT_SYMBOL_GPL(pci_epc_add_epf);
543556
*
544557
* Invoke to remove PCI endpoint function from the endpoint controller.
545558
*/
546-
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf)
559+
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
560+
enum pci_epc_interface_type type)
547561
{
562+
struct list_head *list;
563+
u32 func_no = 0;
564+
548565
if (!epc || IS_ERR(epc) || !epf)
549566
return;
550567

568+
if (type == PRIMARY_INTERFACE) {
569+
func_no = epf->func_no;
570+
list = &epf->list;
571+
} else {
572+
func_no = epf->sec_epc_func_no;
573+
list = &epf->sec_epc_list;
574+
}
575+
551576
mutex_lock(&epc->lock);
552-
clear_bit(epf->func_no, &epc->function_num_map);
553-
list_del(&epf->list);
577+
clear_bit(func_no, &epc->function_num_map);
578+
list_del(list);
554579
epf->epc = NULL;
555580
mutex_unlock(&epc->lock);
556581
}

drivers/pci/endpoint/pci-epf-core.c

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,37 @@ EXPORT_SYMBOL_GPL(pci_epf_bind);
7474
* @epf: the EPF device from whom to free the memory
7575
* @addr: the virtual address of the PCI EPF register space
7676
* @bar: the BAR number corresponding to the register space
77+
* @type: Identifies if the allocated space is for primary EPC or secondary EPC
7778
*
7879
* Invoke to free the allocated PCI EPF register space.
7980
*/
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)
8183
{
8284
struct device *dev = epf->epc->dev.parent;
85+
struct pci_epf_bar *epf_bar;
86+
struct pci_epc *epc;
8387

8488
if (!addr)
8589
return;
8690

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+
}
98+
99+
dev = epc->dev.parent;
100+
dma_free_coherent(dev, epf_bar[bar].size, addr,
101+
epf_bar[bar].phys_addr);
89102

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;
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;
95108
}
96109
EXPORT_SYMBOL_GPL(pci_epf_free_space);
97110

@@ -101,15 +114,18 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space);
101114
* @size: the size of the memory that has to be allocated
102115
* @bar: the BAR number corresponding to the allocated register space
103116
* @align: alignment size for the allocation region
117+
* @type: Identifies if the allocation is for primary EPC or secondary EPC
104118
*
105119
* Invoke to allocate memory for the PCI EPF register space.
106120
*/
107121
void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
108-
size_t align)
122+
size_t align, enum pci_epc_interface_type type)
109123
{
110-
void *space;
111-
struct device *dev = epf->epc->dev.parent;
124+
struct pci_epf_bar *epf_bar;
112125
dma_addr_t phys_addr;
126+
struct pci_epc *epc;
127+
struct device *dev;
128+
void *space;
113129

114130
if (size < 128)
115131
size = 128;
@@ -119,17 +135,26 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
119135
else
120136
size = roundup_pow_of_two(size);
121137

138+
if (type == PRIMARY_INTERFACE) {
139+
epc = epf->epc;
140+
epf_bar = epf->bar;
141+
} else {
142+
epc = epf->sec_epc;
143+
epf_bar = epf->sec_epc_bar;
144+
}
145+
146+
dev = epc->dev.parent;
122147
space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
123148
if (!space) {
124149
dev_err(dev, "failed to allocate mem space\n");
125150
return NULL;
126151
}
127152

128-
epf->bar[bar].phys_addr = phys_addr;
129-
epf->bar[bar].addr = space;
130-
epf->bar[bar].size = size;
131-
epf->bar[bar].barno = bar;
132-
epf->bar[bar].flags |= upper_32_bits(size) ?
153+
epf_bar[bar].phys_addr = phys_addr;
154+
epf_bar[bar].addr = space;
155+
epf_bar[bar].size = size;
156+
epf_bar[bar].barno = bar;
157+
epf_bar[bar].flags |= upper_32_bits(size) ?
133158
PCI_BASE_ADDRESS_MEM_TYPE_64 :
134159
PCI_BASE_ADDRESS_MEM_TYPE_32;
135160

include/linux/pci-epc.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,32 @@
1313

1414
struct pci_epc;
1515

16+
enum pci_epc_interface_type {
17+
UNKNOWN_INTERFACE = -1,
18+
PRIMARY_INTERFACE,
19+
SECONDARY_INTERFACE,
20+
};
21+
1622
enum pci_epc_irq_type {
1723
PCI_EPC_IRQ_UNKNOWN,
1824
PCI_EPC_IRQ_LEGACY,
1925
PCI_EPC_IRQ_MSI,
2026
PCI_EPC_IRQ_MSIX,
2127
};
2228

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+
}
41+
2342
/**
2443
* struct pci_epc_ops - set of function pointers for performing EPC operations
2544
* @write_header: ops to populate configuration space header
@@ -175,10 +194,12 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
175194
struct module *owner);
176195
void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc);
177196
void pci_epc_destroy(struct pci_epc *epc);
178-
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf);
197+
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf,
198+
enum pci_epc_interface_type type);
179199
void pci_epc_linkup(struct pci_epc *epc);
180200
void pci_epc_init_notify(struct pci_epc *epc);
181-
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf);
201+
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
202+
enum pci_epc_interface_type type);
182203
int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
183204
struct pci_epf_header *hdr);
184205
int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,

include/linux/pci-epf.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/pci.h>
1515

1616
struct pci_epf;
17+
enum pci_epc_interface_type;
1718

1819
enum pci_notify_event {
1920
CORE_INIT,
@@ -119,6 +120,11 @@ struct pci_epf_bar {
119120
* @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
120121
* @nb: notifier block to notify EPF of any EPC events (like linkup)
121122
* @lock: mutex to protect pci_epf_ops
123+
* @sec_epc: the secondary EPC device to which this EPF device is bound
124+
* @sec_epc_list: to add pci_epf as list of PCI endpoint functions to secondary
125+
* EPC device
126+
* @sec_epc_bar: represents the BAR of EPF device associated with secondary EPC
127+
* @sec_epc_func_no: unique (physical) function number within the secondary EPC
122128
*/
123129
struct pci_epf {
124130
struct device dev;
@@ -135,6 +141,12 @@ struct pci_epf {
135141
struct notifier_block nb;
136142
/* mutex to protect against concurrent access of pci_epf_ops */
137143
struct mutex lock;
144+
145+
/* Below members are to attach secondary EPC to an endpoint function */
146+
struct pci_epc *sec_epc;
147+
struct list_head sec_epc_list;
148+
struct pci_epf_bar sec_epc_bar[6];
149+
u8 sec_epc_func_no;
138150
};
139151

140152
/**
@@ -171,8 +183,9 @@ int __pci_epf_register_driver(struct pci_epf_driver *driver,
171183
struct module *owner);
172184
void pci_epf_unregister_driver(struct pci_epf_driver *driver);
173185
void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
174-
size_t align);
175-
void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar);
186+
size_t align, enum pci_epc_interface_type type);
187+
void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
188+
enum pci_epc_interface_type type);
176189
int pci_epf_bind(struct pci_epf *epf);
177190
void pci_epf_unbind(struct pci_epf *epf);
178191
#endif /* __LINUX_PCI_EPF_H */

0 commit comments

Comments
 (0)