Skip to content

Commit e7cd58d

Browse files
jbrun3tMani-Sadhasivam
authored andcommitted
PCI: endpoint: pci-epf-vntb: Allow BAR assignment via configfs
The current BAR configuration for the PCI vNTB endpoint function allocates BARs in order, which lacks flexibility and does not account for platform-specific quirks. This is problematic on Renesas platforms, where BAR_4 is a fixed 256B region that ends up being used for MW1, despite being better suited for doorbells. Add new configfs attributes to allow users to specify arbitrary BAR assignments. If no configuration is provided, the driver retains its original behavior of sequential BAR allocation, preserving compatibility with existing userspace setups. This enables use cases such as assigning BAR_2 for MW1 and using the limited BAR_4 for doorbells on Renesas platforms. Signed-off-by: Jerome Brunet <[email protected]> [mani: adjusted the indent of EPF_NTB_BAR_W, fixed kdoc & squashed bar fix] Signed-off-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Frank Li <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent a079d83 commit e7cd58d

File tree

1 file changed

+125
-7
lines changed

1 file changed

+125
-7
lines changed

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

Lines changed: 125 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ enum epf_ntb_bar {
7373
BAR_MW1,
7474
BAR_MW2,
7575
BAR_MW3,
76+
BAR_MW4,
77+
VNTB_BAR_NUM,
7678
};
7779

7880
/*
@@ -132,7 +134,7 @@ struct epf_ntb {
132134
bool linkup;
133135
u32 spad_size;
134136

135-
enum pci_barno epf_ntb_bar[6];
137+
enum pci_barno epf_ntb_bar[VNTB_BAR_NUM];
136138

137139
struct epf_ntb_ctrl *reg;
138140

@@ -654,6 +656,63 @@ static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
654656
pci_epc_put(ntb->epf->epc);
655657
}
656658

659+
660+
/**
661+
* epf_ntb_is_bar_used() - Check if a bar is used in the ntb configuration
662+
* @ntb: NTB device that facilitates communication between HOST and VHOST
663+
* @barno: Checked bar number
664+
*
665+
* Returns: true if used, false if free.
666+
*/
667+
static bool epf_ntb_is_bar_used(struct epf_ntb *ntb,
668+
enum pci_barno barno)
669+
{
670+
int i;
671+
672+
for (i = 0; i < VNTB_BAR_NUM; i++) {
673+
if (ntb->epf_ntb_bar[i] == barno)
674+
return true;
675+
}
676+
677+
return false;
678+
}
679+
680+
/**
681+
* epf_ntb_find_bar() - Assign BAR number when no configuration is provided
682+
* @ntb: NTB device that facilitates communication between HOST and VHOST
683+
* @epc_features: The features provided by the EPC specific to this EPF
684+
* @bar: NTB BAR index
685+
* @barno: Bar start index
686+
*
687+
* When the BAR configuration was not provided through the userspace
688+
* configuration, automatically assign BAR as it has been historically
689+
* done by this endpoint function.
690+
*
691+
* Returns: the BAR number found, if any. -1 otherwise
692+
*/
693+
static int epf_ntb_find_bar(struct epf_ntb *ntb,
694+
const struct pci_epc_features *epc_features,
695+
enum epf_ntb_bar bar,
696+
enum pci_barno barno)
697+
{
698+
while (ntb->epf_ntb_bar[bar] < 0) {
699+
barno = pci_epc_get_next_free_bar(epc_features, barno);
700+
if (barno < 0)
701+
break; /* No more BAR available */
702+
703+
/*
704+
* Verify if the BAR found is not already assigned
705+
* through the provided configuration
706+
*/
707+
if (!epf_ntb_is_bar_used(ntb, barno))
708+
ntb->epf_ntb_bar[bar] = barno;
709+
710+
barno += 1;
711+
}
712+
713+
return barno;
714+
}
715+
657716
/**
658717
* epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
659718
* constructs (scratchpad region, doorbell, memorywindow)
@@ -676,23 +735,21 @@ static int epf_ntb_init_epc_bar(struct epf_ntb *ntb)
676735
epc_features = pci_epc_get_features(ntb->epf->epc, ntb->epf->func_no, ntb->epf->vfunc_no);
677736

678737
/* These are required BARs which are mandatory for NTB functionality */
679-
for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++, barno++) {
680-
barno = pci_epc_get_next_free_bar(epc_features, barno);
738+
for (bar = BAR_CONFIG; bar <= BAR_MW1; bar++) {
739+
barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
681740
if (barno < 0) {
682741
dev_err(dev, "Fail to get NTB function BAR\n");
683742
return -ENOENT;
684743
}
685-
ntb->epf_ntb_bar[bar] = barno;
686744
}
687745

688746
/* These are optional BARs which don't impact NTB functionality */
689-
for (bar = BAR_MW1, i = 1; i < num_mws; bar++, barno++, i++) {
690-
barno = pci_epc_get_next_free_bar(epc_features, barno);
747+
for (bar = BAR_MW1, i = 1; i < num_mws; bar++, i++) {
748+
barno = epf_ntb_find_bar(ntb, epc_features, bar, barno);
691749
if (barno < 0) {
692750
ntb->num_mws = i;
693751
dev_dbg(dev, "BAR not available for > MW%d\n", i + 1);
694752
}
695-
ntb->epf_ntb_bar[bar] = barno;
696753
}
697754

698755
return 0;
@@ -860,6 +917,37 @@ static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
860917
return len; \
861918
}
862919

920+
#define EPF_NTB_BAR_R(_name, _id) \
921+
static ssize_t epf_ntb_##_name##_show(struct config_item *item, \
922+
char *page) \
923+
{ \
924+
struct config_group *group = to_config_group(item); \
925+
struct epf_ntb *ntb = to_epf_ntb(group); \
926+
\
927+
return sprintf(page, "%d\n", ntb->epf_ntb_bar[_id]); \
928+
}
929+
930+
#define EPF_NTB_BAR_W(_name, _id) \
931+
static ssize_t epf_ntb_##_name##_store(struct config_item *item, \
932+
const char *page, size_t len) \
933+
{ \
934+
struct config_group *group = to_config_group(item); \
935+
struct epf_ntb *ntb = to_epf_ntb(group); \
936+
int val; \
937+
int ret; \
938+
\
939+
ret = kstrtoint(page, 0, &val); \
940+
if (ret) \
941+
return ret; \
942+
\
943+
if (val < NO_BAR || val > BAR_5) \
944+
return -EINVAL; \
945+
\
946+
ntb->epf_ntb_bar[_id] = val; \
947+
\
948+
return len; \
949+
}
950+
863951
static ssize_t epf_ntb_num_mws_store(struct config_item *item,
864952
const char *page, size_t len)
865953
{
@@ -899,6 +987,18 @@ EPF_NTB_MW_R(mw3)
899987
EPF_NTB_MW_W(mw3)
900988
EPF_NTB_MW_R(mw4)
901989
EPF_NTB_MW_W(mw4)
990+
EPF_NTB_BAR_R(ctrl_bar, BAR_CONFIG)
991+
EPF_NTB_BAR_W(ctrl_bar, BAR_CONFIG)
992+
EPF_NTB_BAR_R(db_bar, BAR_DB)
993+
EPF_NTB_BAR_W(db_bar, BAR_DB)
994+
EPF_NTB_BAR_R(mw1_bar, BAR_MW1)
995+
EPF_NTB_BAR_W(mw1_bar, BAR_MW1)
996+
EPF_NTB_BAR_R(mw2_bar, BAR_MW2)
997+
EPF_NTB_BAR_W(mw2_bar, BAR_MW2)
998+
EPF_NTB_BAR_R(mw3_bar, BAR_MW3)
999+
EPF_NTB_BAR_W(mw3_bar, BAR_MW3)
1000+
EPF_NTB_BAR_R(mw4_bar, BAR_MW4)
1001+
EPF_NTB_BAR_W(mw4_bar, BAR_MW4)
9021002

9031003
CONFIGFS_ATTR(epf_ntb_, spad_count);
9041004
CONFIGFS_ATTR(epf_ntb_, db_count);
@@ -910,6 +1010,12 @@ CONFIGFS_ATTR(epf_ntb_, mw4);
9101010
CONFIGFS_ATTR(epf_ntb_, vbus_number);
9111011
CONFIGFS_ATTR(epf_ntb_, vntb_pid);
9121012
CONFIGFS_ATTR(epf_ntb_, vntb_vid);
1013+
CONFIGFS_ATTR(epf_ntb_, ctrl_bar);
1014+
CONFIGFS_ATTR(epf_ntb_, db_bar);
1015+
CONFIGFS_ATTR(epf_ntb_, mw1_bar);
1016+
CONFIGFS_ATTR(epf_ntb_, mw2_bar);
1017+
CONFIGFS_ATTR(epf_ntb_, mw3_bar);
1018+
CONFIGFS_ATTR(epf_ntb_, mw4_bar);
9131019

9141020
static struct configfs_attribute *epf_ntb_attrs[] = {
9151021
&epf_ntb_attr_spad_count,
@@ -922,6 +1028,12 @@ static struct configfs_attribute *epf_ntb_attrs[] = {
9221028
&epf_ntb_attr_vbus_number,
9231029
&epf_ntb_attr_vntb_pid,
9241030
&epf_ntb_attr_vntb_vid,
1031+
&epf_ntb_attr_ctrl_bar,
1032+
&epf_ntb_attr_db_bar,
1033+
&epf_ntb_attr_mw1_bar,
1034+
&epf_ntb_attr_mw2_bar,
1035+
&epf_ntb_attr_mw3_bar,
1036+
&epf_ntb_attr_mw4_bar,
9251037
NULL,
9261038
};
9271039

@@ -1379,6 +1491,7 @@ static int epf_ntb_probe(struct pci_epf *epf,
13791491
{
13801492
struct epf_ntb *ntb;
13811493
struct device *dev;
1494+
int i;
13821495

13831496
dev = &epf->dev;
13841497

@@ -1389,6 +1502,11 @@ static int epf_ntb_probe(struct pci_epf *epf,
13891502
epf->header = &epf_ntb_header;
13901503
ntb->epf = epf;
13911504
ntb->vbus_number = 0xff;
1505+
1506+
/* Initially, no bar is assigned */
1507+
for (i = 0; i < VNTB_BAR_NUM; i++)
1508+
ntb->epf_ntb_bar[i] = NO_BAR;
1509+
13921510
epf_set_drvdata(epf, ntb);
13931511

13941512
dev_info(dev, "pci-ep epf driver loaded\n");

0 commit comments

Comments
 (0)