Skip to content

Commit fef3530

Browse files
committed
Merge branch 'pci/capability-search'
- Simplify __pci_find_next_cap_ttl() by replacing magic numbers with #defines, extracting fields with FIELD_GET(), etc (Hans Zhang) - Convert __pci_find_next_cap_ttl() to a PCI_FIND_NEXT_CAP() macro that takes a config space accessor function so we can also use it in cases where the usual config accessors aren't available (Hans Zhang) - Similarly convert pci_find_next_ext_capability() to a PCI_FIND_NEXT_EXT_CAP() macro (Hans Zhang) - Implement dwc, dwc endpoint, and cadence capability search interfaces on top of PCI_FIND_NEXT_CAP() and PCI_FIND_NEXT_EXT_CAP(), replacing the previous duplicated code (Hans Zhang) - Search for capabilities in the cadence core instead of hard-coding their offsets, which are subject to change (Hans Zhang) * pci/capability-search: PCI: cadence: Use cdns_pcie_find_*capability() to avoid hardcoding offsets PCI: cadence: Implement capability search using PCI core APIs PCI: dwc: ep: Implement capability search using PCI core APIs PCI: dwc: Implement capability search using PCI core APIs PCI: Refactor extended capability search into PCI_FIND_NEXT_EXT_CAP() PCI: Refactor capability search into PCI_FIND_NEXT_CAP() PCI: Clean up __pci_find_next_cap_ttl() readability
2 parents 9155399 + 907912c commit fef3530

File tree

9 files changed

+217
-188
lines changed

9 files changed

+217
-188
lines changed

drivers/pci/controller/cadence/pcie-cadence-ep.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@
2121

2222
static u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn)
2323
{
24-
u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
2524
u32 first_vf_offset, stride;
25+
u16 cap;
2626

2727
if (vfn == 0)
2828
return fn;
2929

30+
cap = cdns_pcie_find_ext_capability(pcie, PCI_EXT_CAP_ID_SRIOV);
3031
first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET);
3132
stride = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_STRIDE);
3233
fn = fn + first_vf_offset + ((vfn - 1) * stride);
@@ -38,10 +39,11 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
3839
struct pci_epf_header *hdr)
3940
{
4041
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
41-
u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
4242
struct cdns_pcie *pcie = &ep->pcie;
4343
u32 reg;
44+
u16 cap;
4445

46+
cap = cdns_pcie_find_ext_capability(pcie, PCI_EXT_CAP_ID_SRIOV);
4547
if (vfn > 1) {
4648
dev_err(&epc->dev, "Only Virtual Function #1 has deviceID\n");
4749
return -EINVAL;
@@ -227,9 +229,10 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 nr_irqs)
227229
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
228230
struct cdns_pcie *pcie = &ep->pcie;
229231
u8 mmc = order_base_2(nr_irqs);
230-
u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
231232
u16 flags;
233+
u8 cap;
232234

235+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI);
233236
fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
234237

235238
/*
@@ -249,9 +252,10 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
249252
{
250253
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
251254
struct cdns_pcie *pcie = &ep->pcie;
252-
u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
253255
u16 flags, mme;
256+
u8 cap;
254257

258+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX);
255259
fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
256260

257261
/* Validate that the MSI feature is actually enabled. */
@@ -272,9 +276,10 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
272276
{
273277
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
274278
struct cdns_pcie *pcie = &ep->pcie;
275-
u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
276279
u32 val, reg;
280+
u8 cap;
277281

282+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX);
278283
func_no = cdns_pcie_get_fn_from_vfn(pcie, func_no, vfunc_no);
279284

280285
reg = cap + PCI_MSIX_FLAGS;
@@ -292,9 +297,10 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
292297
{
293298
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
294299
struct cdns_pcie *pcie = &ep->pcie;
295-
u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
296300
u32 val, reg;
301+
u8 cap;
297302

303+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX);
298304
fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
299305

300306
reg = cap + PCI_MSIX_FLAGS;
@@ -380,11 +386,11 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
380386
u8 interrupt_num)
381387
{
382388
struct cdns_pcie *pcie = &ep->pcie;
383-
u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
384389
u16 flags, mme, data, data_mask;
385-
u8 msi_count;
386390
u64 pci_addr, pci_addr_mask = 0xff;
391+
u8 msi_count, cap;
387392

393+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI);
388394
fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
389395

390396
/* Check whether the MSI feature has been enabled by the PCI host. */
@@ -432,14 +438,14 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
432438
u32 *msi_addr_offset)
433439
{
434440
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
435-
u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
436441
struct cdns_pcie *pcie = &ep->pcie;
437442
u64 pci_addr, pci_addr_mask = 0xff;
438443
u16 flags, mme, data, data_mask;
439-
u8 msi_count;
444+
u8 msi_count, cap;
440445
int ret;
441446
int i;
442447

448+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSI);
443449
fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
444450

445451
/* Check whether the MSI feature has been enabled by the PCI host. */
@@ -482,16 +488,16 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
482488
static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
483489
u16 interrupt_num)
484490
{
485-
u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
486491
u32 tbl_offset, msg_data, reg;
487492
struct cdns_pcie *pcie = &ep->pcie;
488493
struct pci_epf_msix_tbl *msix_tbl;
489494
struct cdns_pcie_epf *epf;
490495
u64 pci_addr_mask = 0xff;
491496
u64 msg_addr;
497+
u8 bir, cap;
492498
u16 flags;
493-
u8 bir;
494499

500+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_MSIX);
495501
epf = &ep->epf[fn];
496502
if (vfn > 0)
497503
epf = &epf->epf[vfn - 1];
@@ -565,7 +571,9 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
565571
int max_epfs = sizeof(epc->function_num_map) * 8;
566572
int ret, epf, last_fn;
567573
u32 reg, value;
574+
u8 cap;
568575

576+
cap = cdns_pcie_find_capability(pcie, PCI_CAP_ID_EXP);
569577
/*
570578
* BIT(0) is hardwired to 1, hence function 0 is always enabled
571579
* and can't be disabled anyway.
@@ -589,12 +597,10 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
589597
continue;
590598

591599
value = cdns_pcie_ep_fn_readl(pcie, epf,
592-
CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET +
593-
PCI_EXP_DEVCAP);
600+
cap + PCI_EXP_DEVCAP);
594601
value &= ~PCI_EXP_DEVCAP_FLR;
595602
cdns_pcie_ep_fn_writel(pcie, epf,
596-
CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET +
597-
PCI_EXP_DEVCAP, value);
603+
cap + PCI_EXP_DEVCAP, value);
598604
}
599605
}
600606

drivers/pci/controller/cadence/pcie-cadence.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@
88
#include <linux/of.h>
99

1010
#include "pcie-cadence.h"
11+
#include "../../pci.h"
12+
13+
u8 cdns_pcie_find_capability(struct cdns_pcie *pcie, u8 cap)
14+
{
15+
return PCI_FIND_NEXT_CAP(cdns_pcie_read_cfg, PCI_CAPABILITY_LIST,
16+
cap, pcie);
17+
}
18+
EXPORT_SYMBOL_GPL(cdns_pcie_find_capability);
19+
20+
u16 cdns_pcie_find_ext_capability(struct cdns_pcie *pcie, u8 cap)
21+
{
22+
return PCI_FIND_NEXT_EXT_CAP(cdns_pcie_read_cfg, 0, cap, pcie);
23+
}
24+
EXPORT_SYMBOL_GPL(cdns_pcie_find_ext_capability);
1125

1226
void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
1327
{

drivers/pci/controller/cadence/pcie-cadence.h

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,6 @@
125125
*/
126126
#define CDNS_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12))
127127

128-
#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET 0x90
129-
#define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET 0xb0
130-
#define CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET 0xc0
131-
#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET 0x200
132-
133128
/*
134129
* Endpoint PF Registers
135130
*/
@@ -367,6 +362,37 @@ static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
367362
return readl(pcie->reg_base + reg);
368363
}
369364

365+
static inline u16 cdns_pcie_readw(struct cdns_pcie *pcie, u32 reg)
366+
{
367+
return readw(pcie->reg_base + reg);
368+
}
369+
370+
static inline u8 cdns_pcie_readb(struct cdns_pcie *pcie, u32 reg)
371+
{
372+
return readb(pcie->reg_base + reg);
373+
}
374+
375+
static inline int cdns_pcie_read_cfg_byte(struct cdns_pcie *pcie, int where,
376+
u8 *val)
377+
{
378+
*val = cdns_pcie_readb(pcie, where);
379+
return PCIBIOS_SUCCESSFUL;
380+
}
381+
382+
static inline int cdns_pcie_read_cfg_word(struct cdns_pcie *pcie, int where,
383+
u16 *val)
384+
{
385+
*val = cdns_pcie_readw(pcie, where);
386+
return PCIBIOS_SUCCESSFUL;
387+
}
388+
389+
static inline int cdns_pcie_read_cfg_dword(struct cdns_pcie *pcie, int where,
390+
u32 *val)
391+
{
392+
*val = cdns_pcie_readl(pcie, where);
393+
return PCIBIOS_SUCCESSFUL;
394+
}
395+
370396
static inline u32 cdns_pcie_read_sz(void __iomem *addr, int size)
371397
{
372398
void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4);
@@ -536,6 +562,9 @@ static inline void cdns_pcie_ep_disable(struct cdns_pcie_ep *ep)
536562
}
537563
#endif
538564

565+
u8 cdns_pcie_find_capability(struct cdns_pcie *pcie, u8 cap);
566+
u16 cdns_pcie_find_ext_capability(struct cdns_pcie *pcie, u8 cap);
567+
539568
void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
540569

541570
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -69,37 +69,10 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
6969
}
7070
EXPORT_SYMBOL_GPL(dw_pcie_ep_reset_bar);
7171

72-
static u8 __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, u8 func_no,
73-
u8 cap_ptr, u8 cap)
74-
{
75-
u8 cap_id, next_cap_ptr;
76-
u16 reg;
77-
78-
if (!cap_ptr)
79-
return 0;
80-
81-
reg = dw_pcie_ep_readw_dbi(ep, func_no, cap_ptr);
82-
cap_id = (reg & 0x00ff);
83-
84-
if (cap_id > PCI_CAP_ID_MAX)
85-
return 0;
86-
87-
if (cap_id == cap)
88-
return cap_ptr;
89-
90-
next_cap_ptr = (reg & 0xff00) >> 8;
91-
return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
92-
}
93-
9472
static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
9573
{
96-
u8 next_cap_ptr;
97-
u16 reg;
98-
99-
reg = dw_pcie_ep_readw_dbi(ep, func_no, PCI_CAPABILITY_LIST);
100-
next_cap_ptr = (reg & 0x00ff);
101-
102-
return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
74+
return PCI_FIND_NEXT_CAP(dw_pcie_ep_read_cfg, PCI_CAPABILITY_LIST,
75+
cap, ep, func_no);
10376
}
10477

10578
/**

drivers/pci/controller/dwc/pcie-designware.c

Lines changed: 5 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -213,83 +213,16 @@ void dw_pcie_version_detect(struct dw_pcie *pci)
213213
pci->type = ver;
214214
}
215215

216-
/*
217-
* These interfaces resemble the pci_find_*capability() interfaces, but these
218-
* are for configuring host controllers, which are bridges *to* PCI devices but
219-
* are not PCI devices themselves.
220-
*/
221-
static u8 __dw_pcie_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
222-
u8 cap)
223-
{
224-
u8 cap_id, next_cap_ptr;
225-
u16 reg;
226-
227-
if (!cap_ptr)
228-
return 0;
229-
230-
reg = dw_pcie_readw_dbi(pci, cap_ptr);
231-
cap_id = (reg & 0x00ff);
232-
233-
if (cap_id > PCI_CAP_ID_MAX)
234-
return 0;
235-
236-
if (cap_id == cap)
237-
return cap_ptr;
238-
239-
next_cap_ptr = (reg & 0xff00) >> 8;
240-
return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap);
241-
}
242-
243216
u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
244217
{
245-
u8 next_cap_ptr;
246-
u16 reg;
247-
248-
reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
249-
next_cap_ptr = (reg & 0x00ff);
250-
251-
return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap);
218+
return PCI_FIND_NEXT_CAP(dw_pcie_read_cfg, PCI_CAPABILITY_LIST, cap,
219+
pci);
252220
}
253221
EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
254222

255-
static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
256-
u8 cap)
257-
{
258-
u32 header;
259-
int ttl;
260-
int pos = PCI_CFG_SPACE_SIZE;
261-
262-
/* minimum 8 bytes per capability */
263-
ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
264-
265-
if (start)
266-
pos = start;
267-
268-
header = dw_pcie_readl_dbi(pci, pos);
269-
/*
270-
* If we have no capabilities, this is indicated by cap ID,
271-
* cap version and next pointer all being 0.
272-
*/
273-
if (header == 0)
274-
return 0;
275-
276-
while (ttl-- > 0) {
277-
if (PCI_EXT_CAP_ID(header) == cap && pos != start)
278-
return pos;
279-
280-
pos = PCI_EXT_CAP_NEXT(header);
281-
if (pos < PCI_CFG_SPACE_SIZE)
282-
break;
283-
284-
header = dw_pcie_readl_dbi(pci, pos);
285-
}
286-
287-
return 0;
288-
}
289-
290223
u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
291224
{
292-
return dw_pcie_find_next_ext_capability(pci, 0, cap);
225+
return PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, 0, cap, pci);
293226
}
294227
EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability);
295228

@@ -302,8 +235,8 @@ static u16 __dw_pcie_find_vsec_capability(struct dw_pcie *pci, u16 vendor_id,
302235
if (vendor_id != dw_pcie_readw_dbi(pci, PCI_VENDOR_ID))
303236
return 0;
304237

305-
while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
306-
PCI_EXT_CAP_ID_VNDR))) {
238+
while ((vsec = PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, vsec,
239+
PCI_EXT_CAP_ID_VNDR, pci))) {
307240
header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
308241
if (PCI_VNDR_HEADER_ID(header) == vsec_id)
309242
return vsec;

0 commit comments

Comments
 (0)